+#define RETRO_ENVIRONMENT_SET_HW_RENDER 14
+ // struct retro_hw_render_callback * --
+ // Sets an interface to let a libretro core render with hardware acceleration.
+ // Should be called in retro_load_game().
+ // If successful, libretro cores will be able to render to a frontend-provided framebuffer.
+ // The size of this framebuffer will be at least as large as max_width/max_height provided in get_av_info().
+ // If HW rendering is used, pass only RETRO_HW_FRAME_BUFFER_VALID or NULL to retro_video_refresh_t.
+#define RETRO_ENVIRONMENT_GET_VARIABLE 15
+ // struct retro_variable * --
+ // Interface to acquire user-defined information from environment
+ // that cannot feasibly be supported in a multi-system way.
+ // 'key' should be set to a key which has already been set by SET_VARIABLES.
+ // 'data' will be set to a value or NULL.
+ //
+#define RETRO_ENVIRONMENT_SET_VARIABLES 16
+ // const struct retro_variable * --
+ // Allows an implementation to signal the environment
+ // which variables it might want to check for later using GET_VARIABLE.
+ // This allows the frontend to present these variables to a user dynamically.
+ // This should be called as early as possible (ideally in retro_set_environment).
+ //
+ // 'data' points to an array of retro_variable structs terminated by a { NULL, NULL } element.
+ // retro_variable::key should be namespaced to not collide with other implementations' keys. E.g. A core called 'foo' should use keys named as 'foo_option'.
+ // retro_variable::value should contain a human readable description of the key as well as a '|' delimited list of expected values.
+ // The number of possible options should be very limited, i.e. it should be feasible to cycle through options without a keyboard.
+ // First entry should be treated as a default.
+ //
+ // Example entry:
+ // { "foo_option", "Speed hack coprocessor X; false|true" }
+ //
+ // Text before first ';' is description. This ';' must be followed by a space, and followed by a list of possible values split up with '|'.
+ // Only strings are operated on. The possible values will generally be displayed and stored as-is by the frontend.
+ //
+#define RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE 17
+ // bool * --
+ // Result is set to true if some variables are updated by
+ // frontend since last call to RETRO_ENVIRONMENT_GET_VARIABLE.
+ // Variables should be queried with GET_VARIABLE.
+ //
+#define RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME 18
+ // const bool * --
+ // If true, the libretro implementation supports calls to retro_load_game() with NULL as argument.
+ // Used by cores which can run without particular game data.
+ // This should be called within retro_set_environment() only.
+ //
+#define RETRO_ENVIRONMENT_GET_LIBRETRO_PATH 19
+ // const char ** --
+ // Retrieves the absolute path from where this libretro implementation was loaded.
+ // NULL is returned if the libretro was loaded statically (i.e. linked statically to frontend), or if the path cannot be determined.
+ // Mostly useful in cooperation with SET_SUPPORT_NO_GAME as assets can be loaded without ugly hacks.
+ //
+ //
+// Environment 20 was an obsolete version of SET_AUDIO_CALLBACK. It was not used by any known core at the time,
+// and was removed from the API.
+#define RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK 22
+ // const struct retro_audio_callback * --
+ // Sets an interface which is used to notify a libretro core about audio being available for writing.
+ // The callback can be called from any thread, so a core using this must have a thread safe audio implementation.
+ // It is intended for games where audio and video are completely asynchronous and audio can be generated on the fly.
+ // This interface is not recommended for use with emulators which have highly synchronous audio.
+ //
+ // The callback only notifies about writability; the libretro core still has to call the normal audio callbacks
+ // to write audio. The audio callbacks must be called from within the notification callback.
+ // The amount of audio data to write is up to the implementation.
+ // Generally, the audio callback will be called continously in a loop.
+ //
+ // Due to thread safety guarantees and lack of sync between audio and video, a frontend
+ // can selectively disallow this interface based on internal configuration. A core using
+ // this interface must also implement the "normal" audio interface.
+ //
+ // A libretro core using SET_AUDIO_CALLBACK should also make use of SET_FRAME_TIME_CALLBACK.
+#define RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK 21
+ // const struct retro_frame_time_callback * --
+ // Lets the core know how much time has passed since last invocation of retro_run().
+ // The frontend can tamper with the timing to fake fast-forward, slow-motion, frame stepping, etc.
+ // In this case the delta time will use the reference value in frame_time_callback..
+ //
+#define RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE 23
+ // struct retro_rumble_interface * --
+ // Gets an interface which is used by a libretro core to set state of rumble motors in controllers.
+ // A strong and weak motor is supported, and they can be controlled indepedently.
+ //
+#define RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES 24
+ // uint64_t * --
+ // Gets a bitmask telling which device type are expected to be handled properly in a call to retro_input_state_t.
+ // Devices which are not handled or recognized always return 0 in retro_input_state_t.
+ // Example bitmask: caps = (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG).
+ // Should only be called in retro_run().
+ //
+#define RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE (25 | RETRO_ENVIRONMENT_EXPERIMENTAL)
+ // struct retro_sensor_interface * --
+ // Gets access to the sensor interface.
+ // The purpose of this interface is to allow
+ // setting state related to sensors such as polling rate, enabling/disable it entirely, etc.
+ // Reading sensor state is done via the normal input_state_callback API.
+ //
+#define RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE (26 | RETRO_ENVIRONMENT_EXPERIMENTAL)
+ // struct retro_camera_callback * --
+ // Gets an interface to a video camera driver.
+ // A libretro core can use this interface to get access to a video camera.
+ // New video frames are delivered in a callback in same thread as retro_run().
+ //
+ // GET_CAMERA_INTERFACE should be called in retro_load_game().
+ //
+ // Depending on the camera implementation used, camera frames will be delivered as a raw framebuffer,
+ // or as an OpenGL texture directly.
+ //
+ // The core has to tell the frontend here which types of buffers can be handled properly.
+ // An OpenGL texture can only be handled when using a libretro GL core (SET_HW_RENDER).
+ // It is recommended to use a libretro GL core when using camera interface.
+ //
+ // The camera is not started automatically. The retrieved start/stop functions must be used to explicitly
+ // start and stop the camera driver.
+ //
+#define RETRO_ENVIRONMENT_GET_LOG_INTERFACE 27
+ // struct retro_log_callback * --
+ // Gets an interface for logging. This is useful for logging in a cross-platform way
+ // as certain platforms cannot use use stderr for logging. It also allows the frontend to
+ // show logging information in a more suitable way.
+ // If this interface is not used, libretro cores should log to stderr as desired.
+#define RETRO_ENVIRONMENT_GET_PERF_INTERFACE 28
+ // struct retro_perf_callback * --
+ // Gets an interface for performance counters. This is useful for performance logging in a
+ // cross-platform way and for detecting architecture-specific features, such as SIMD support.
+
+enum retro_log_level
+{
+ RETRO_LOG_DEBUG = 0,
+ RETRO_LOG_INFO,
+ RETRO_LOG_WARN,
+ RETRO_LOG_ERROR,
+
+ RETRO_LOG_DUMMY = INT_MAX
+};
+
+// Logging function. Takes log level argument as well.
+typedef void (*retro_log_printf_t)(enum retro_log_level level, const char *fmt, ...);
+
+struct retro_log_callback
+{
+ retro_log_printf_t log;
+};
+
+// Performance related functions
+//
+// ID values for SIMD CPU features
+#define RETRO_SIMD_SSE (1 << 0)
+#define RETRO_SIMD_SSE2 (1 << 1)
+#define RETRO_SIMD_VMX (1 << 2)
+#define RETRO_SIMD_VMX128 (1 << 3)
+#define RETRO_SIMD_AVX (1 << 4)
+#define RETRO_SIMD_NEON (1 << 5)
+#define RETRO_SIMD_SSE3 (1 << 6)
+#define RETRO_SIMD_SSSE3 (1 << 7)
+
+typedef uint64_t retro_perf_tick_t;
+typedef int64_t retro_time_t;
+
+struct retro_perf_counter
+{
+ const char *ident;
+ retro_perf_tick_t start;
+ retro_perf_tick_t total;
+ retro_perf_tick_t call_cnt;
+
+ bool registered;
+};
+
+// Returns current time in microseconds. Tries to use the most accurate timer available.
+typedef retro_time_t (*retro_perf_get_time_usec_t)(void);
+// A simple counter. Usually nanoseconds, but can also be CPU cycles.
+// Can be used directly if desired (when creating a more sophisticated performance counter system).
+typedef retro_perf_tick_t (*retro_perf_get_counter_t)(void);
+// Returns a bit-mask of detected CPU features (RETRO_SIMD_*).
+typedef uint64_t (*retro_get_cpu_features_t)(void);
+// Asks frontend to log and/or display the state of performance counters.
+// Performance counters can always be poked into manually as well.
+typedef void (*retro_perf_log_t)(void);
+// Register a performance counter.
+// ident field must be set with a discrete value and other values in retro_perf_counter must be 0.
+// Registering can be called multiple times. To avoid calling to frontend redundantly, you can check registered field first.
+typedef void (*retro_perf_register_t)(struct retro_perf_counter *counter);
+// Starts and stops a registered counter.
+typedef void (*retro_perf_start_t)(struct retro_perf_counter *counter);
+typedef void (*retro_perf_stop_t)(struct retro_perf_counter *counter);
+
+// For convenience it can be useful to wrap register, start and stop in macros.
+// E.g.:
+// #ifdef LOG_PERFORMANCE
+// #define RETRO_PERFORMANCE_INIT(perf_cb, name) static struct retro_perf_counter name = {#name}; if (!name.registered) perf_cb.perf_register(&(name))
+// #define RETRO_PERFORMANCE_START(perf_cb, name) perf_cb.perf_start(&(name))
+// #define RETRO_PERFORMANCE_STOP(perf_cb, name) perf_cb.perf_stop(&(name))
+// #else
+// ... Blank macros ...
+// #endif
+// These can then be used mid-functions around code snippets.
+//
+// extern struct retro_perf_callback perf_cb; // Somewhere in the core.
+//
+// void do_some_heavy_work(void)
+// {
+// RETRO_PERFORMANCE_INIT(cb, work_1);
+// RETRO_PERFORMANCE_START(cb, work_1);
+// heavy_work_1();
+// RETRO_PERFORMANCE_STOP(cb, work_1);
+//
+// RETRO_PERFORMANCE_INIT(cb, work_2);
+// RETRO_PERFORMANCE_START(cb, work_2);
+// heavy_work_2();
+// RETRO_PERFORMANCE_STOP(cb, work_2);
+// }
+//
+// void retro_deinit(void)
+// {
+// perf_cb.perf_log(); // Log all perf counters here for example.
+// }