diff --git a/dynamic.h b/dynamic.h index 79ed70ab16d..0f1d238ee75 100644 --- a/dynamic.h +++ b/dynamic.h @@ -68,6 +68,13 @@ struct retro_core_t unsigned 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 1d7e765a55d..6c5d4ce374c 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -2574,6 +2574,32 @@ enum retro_mod */ #define RETRO_ENVIRONMENT_GET_FILE_BROWSER_START_DIRECTORY 80 +/** + * 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 (81 | 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 (82 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /**@}*/ /** diff --git a/runloop.c b/runloop.c index 80c8891cce7..507c02f5dac 100644 --- a/runloop.c +++ b/runloop.c @@ -3556,6 +3556,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;