diff --git a/dynamic.h b/dynamic.h index af4a0cdd15f..f8c530a73e7 100644 --- a/dynamic.h +++ b/dynamic.h @@ -68,6 +68,13 @@ struct retro_core_t enum poll_type poll_type; uint8_t flags; + + /** + * Arbitrary core data. + * + * @see RETRO_ENVIRONMENT_GET_CORE_DATA + */ + void *core_data; }; diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index 73ff390c508..b00b77d3f24 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -2944,6 +2944,32 @@ enum retro_mod | RETRO_AUDIO_SPEAKER_SIDE_LEFT | RETRO_AUDIO_SPEAKER_SIDE_RIGHT) #define RETRO_AUDIO_LAYOUT_7_1 (RETRO_AUDIO_LAYOUT_5_1 | RETRO_AUDIO_SPEAKER_SIDE_LEFT | RETRO_AUDIO_SPEAKER_SIDE_RIGHT) +/** + * Sets a pointer to arbitrary data for the actively running core. + * + * Intended for use as a substitute for global state, which is a common + * source of bugs. Can be set in either \c retro_init() or \c retro_load_game(). + * + * @param[in] data void *. Pointer to the data to set. + * @return \c true if the environment call is available. + * + * @see RETRO_ENVIRONMENT_GET_CORE_DATA + */ +#define RETRO_ENVIRONMENT_SET_CORE_DATA (95 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Gets a pointer to arbitrary data for the actively running core. + * + * This is persistent for the lifetime of the core until \c retro_deinit() is called. + * + * @param[out] data void **. Pointer to the data that was set. + * May be \c NULL if the data was not set yet. + * @return \c true if the environment call is available. + * + * @see RETRO_ENVIRONMENT_SET_CORE_DATA + */ +#define RETRO_ENVIRONMENT_GET_CORE_DATA (96 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /** * Result of \c RETRO_ENVIRONMENT_GET_MEMORY_STATUS. * diff --git a/runloop.c b/runloop.c index c21a32682e1..c282686fc08 100644 --- a/runloop.c +++ b/runloop.c @@ -4119,6 +4119,18 @@ bool runloop_environment_cb(unsigned cmd, void *data) } } break; + + case RETRO_ENVIRONMENT_SET_CORE_DATA: + runloop_st->current_core.core_data = data; + break; + + case RETRO_ENVIRONMENT_GET_CORE_DATA: + if (data != NULL) { + void **core_data = (void **)data; + *core_data = runloop_st->current_core.core_data; + } + break; + default: RARCH_LOG("[Environ] UNSUPPORTED (#%u).\n", cmd); return false;