+ /* const struct retro_input_descriptor * --
+ * Sets an array of retro_input_descriptors.
+ * It is up to the frontend to present this in a usable way.
+ * The array is terminated by retro_input_descriptor::description
+ * being set to NULL.
+ * This function can be called at any time, but it is recommended
+ * to call it as early as possible.
+ */
+#define RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK 12
+ /* const struct retro_keyboard_callback * --
+ * Sets a callback function used to notify core about keyboard events.
+ */
+#define RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE 13
+ /* const struct retro_disk_control_callback * --
+ * Sets an interface which frontend can use to eject and insert
+ * disk images.
+ * This is used for games which consist of multiple images and
+ * must be manually swapped out by the user (e.g. PSX).
+ */
+#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.
+ */
+#define RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE 29
+ /* struct retro_location_callback * --
+ * Gets access to the location interface.
+ * The purpose of this interface is to be able to retrieve
+ * location-based information from the host device,
+ * such as current latitude / longitude.
+ */
+#define RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY 30
+ /* const char ** --
+ * Returns the "content" directory of the frontend.
+ * This directory can be used to store specific assets that the
+ * core relies upon, such as art assets,
+ * input data, etc etc.
+ * The returned value can be NULL.
+ * If so, no such directory is defined,
+ * and it's up to the implementation to find a suitable directory.
+ */
+#define RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY 31
+ /* const char ** --
+ * Returns the "save" directory of the frontend.
+ * This directory can be used to store SRAM, memory cards,
+ * high scores, etc, if the libretro core
+ * cannot use the regular memory interface (retro_get_memory_data()).
+ *
+ * NOTE: libretro cores used to check GET_SYSTEM_DIRECTORY for
+ * similar things before.
+ * They should still check GET_SYSTEM_DIRECTORY if they want to
+ * be backwards compatible.
+ * The path here can be NULL. It should only be non-NULL if the
+ * frontend user has set a specific save path.
+ */
+#define RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO 32
+ /* const struct retro_system_av_info * --
+ * Sets a new av_info structure. This can only be called from
+ * within retro_run().
+ * This should *only* be used if the core is completely altering the
+ * internal resolutions, aspect ratios, timings, sampling rate, etc.
+ * Calling this can require a full reinitialization of video/audio
+ * drivers in the frontend,
+ *
+ * so it is important to call it very sparingly, and usually only with
+ * the users explicit consent.
+ * An eventual driver reinitialize will happen so that video and
+ * audio callbacks
+ * happening after this call within the same retro_run() call will
+ * target the newly initialized driver.
+ *
+ * This callback makes it possible to support configurable resolutions
+ * in games, which can be useful to
+ * avoid setting the "worst case" in max_width/max_height.
+ *
+ * ***HIGHLY RECOMMENDED*** Do not call this callback every time
+ * resolution changes in an emulator core if it's
+ * expected to be a temporary change, for the reasons of possible
+ * driver reinitialization.
+ * This call is not a free pass for not trying to provide
+ * correct values in retro_get_system_av_info(). If you need to change
+ * things like aspect ratio or nominal width/height,
+ * use RETRO_ENVIRONMENT_SET_GEOMETRY, which is a softer variant
+ * of SET_SYSTEM_AV_INFO.
+ *
+ * If this returns false, the frontend does not acknowledge a
+ * changed av_info struct.
+ */
+#define RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK 33
+ /* const struct retro_get_proc_address_interface * --
+ * Allows a libretro core to announce support for the
+ * get_proc_address() interface.
+ * This interface allows for a standard way to extend libretro where
+ * use of environment calls are too indirect,
+ * e.g. for cases where the frontend wants to call directly into the core.
+ *
+ * If a core wants to expose this interface, SET_PROC_ADDRESS_CALLBACK
+ * **MUST** be called from within retro_set_environment().
+ */
+#define RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO 34
+ /* const struct retro_subsystem_info * --
+ * This environment call introduces the concept of libretro "subsystems".
+ * A subsystem is a variant of a libretro core which supports
+ * different kinds of games.
+ * The purpose of this is to support e.g. emulators which might
+ * have special needs, e.g. Super Nintendo's Super GameBoy, Sufami Turbo.
+ * It can also be used to pick among subsystems in an explicit way
+ * if the libretro implementation is a multi-system emulator itself.
+ *
+ * Loading a game via a subsystem is done with retro_load_game_special(),
+ * and this environment call allows a libretro core to expose which
+ * subsystems are supported for use with retro_load_game_special().
+ * A core passes an array of retro_game_special_info which is terminated
+ * with a zeroed out retro_game_special_info struct.
+ *
+ * If a core wants to use this functionality, SET_SUBSYSTEM_INFO
+ * **MUST** be called from within retro_set_environment().
+ */
+#define RETRO_ENVIRONMENT_SET_CONTROLLER_INFO 35
+ /* const struct retro_controller_info * --
+ * This environment call lets a libretro core tell the frontend
+ * which controller types are recognized in calls to
+ * retro_set_controller_port_device().
+ *
+ * Some emulators such as Super Nintendo
+ * support multiple lightgun types which must be specifically
+ * selected from.
+ * It is therefore sometimes necessary for a frontend to be able
+ * to tell the core about a special kind of input device which is
+ * not covered by the libretro input API.
+ *
+ * In order for a frontend to understand the workings of an input device,
+ * it must be a specialized type
+ * of the generic device types already defined in the libretro API.
+ *
+ * Which devices are supported can vary per input port.
+ * The core must pass an array of const struct retro_controller_info which
+ * is terminated with a blanked out struct. Each element of the struct
+ * corresponds to an ascending port index to
+ * retro_set_controller_port_device().
+ * Even if special device types are set in the libretro core,
+ * libretro should only poll input based on the base input device types.
+ */
+#define RETRO_ENVIRONMENT_SET_MEMORY_MAPS (36 | RETRO_ENVIRONMENT_EXPERIMENTAL)
+ /* const struct retro_memory_map * --
+ * This environment call lets a libretro core tell the frontend
+ * about the memory maps this core emulates.
+ * This can be used to implement, for example, cheats in a core-agnostic way.
+ *
+ * Should only be used by emulators; it doesn't make much sense for
+ * anything else.
+ * It is recommended to expose all relevant pointers through
+ * retro_get_memory_* as well.
+ *
+ * Can be called from retro_init and retro_load_game.
+ */
+#define RETRO_ENVIRONMENT_SET_GEOMETRY 37
+ /* const struct retro_game_geometry * --
+ * This environment call is similar to SET_SYSTEM_AV_INFO for changing
+ * video parameters, but provides a guarantee that drivers will not be
+ * reinitialized.
+ * This can only be called from within retro_run().
+ *
+ * The purpose of this call is to allow a core to alter nominal
+ * width/heights as well as aspect ratios on-the-fly, which can be
+ * useful for some emulators to change in run-time.
+ *
+ * max_width/max_height arguments are ignored and cannot be changed
+ * with this call as this could potentially require a reinitialization or a
+ * non-constant time operation.
+ * If max_width/max_height are to be changed, SET_SYSTEM_AV_INFO is required.
+ *
+ * A frontend must guarantee that this environment call completes in
+ * constant time.
+ */
+#define RETRO_ENVIRONMENT_GET_USERNAME 38
+ /* const char **
+ * Returns the specified username of the frontend, if specified by the user.
+ * This username can be used as a nickname for a core that has online facilities
+ * or any other mode where personalization of the user is desirable.
+ * The returned value can be NULL.
+ * If this environ callback is used by a core that requires a valid username,
+ * a default username should be specified by the core.
+ */
+#define RETRO_ENVIRONMENT_GET_LANGUAGE 39
+ /* unsigned * --
+ * Returns the specified language of the frontend, if specified by the user.
+ * It can be used by the core for localization purposes.
+ */
+
+#define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */
+#define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */
+#define RETRO_MEMDESC_ALIGN_2 (1 << 16) /* All memory access in this area is aligned to their own size, or 2, whichever is smaller. */
+#define RETRO_MEMDESC_ALIGN_4 (2 << 16)
+#define RETRO_MEMDESC_ALIGN_8 (3 << 16)
+#define RETRO_MEMDESC_MINSIZE_2 (1 << 24) /* All memory in this region is accessed at least 2 bytes at the time. */
+#define RETRO_MEMDESC_MINSIZE_4 (2 << 24)
+#define RETRO_MEMDESC_MINSIZE_8 (3 << 24)
+struct retro_memory_descriptor
+{
+ uint64_t flags;
+
+ /* Pointer to the start of the relevant ROM or RAM chip.
+ * It's strongly recommended to use 'offset' if possible, rather than
+ * doing math on the pointer.
+ *
+ * If the same byte is mapped my multiple descriptors, their descriptors
+ * must have the same pointer.
+ * If 'start' does not point to the first byte in the pointer, put the
+ * difference in 'offset' instead.
+ *
+ * May be NULL if there's nothing usable here (e.g. hardware registers and
+ * open bus). No flags should be set if the pointer is NULL.
+ * It's recommended to minimize the number of descriptors if possible,
+ * but not mandatory. */
+ void *ptr;
+ size_t offset;
+
+ /* This is the location in the emulated address space
+ * where the mapping starts. */
+ size_t start;
+
+ /* Which bits must be same as in 'start' for this mapping to apply.
+ * The first memory descriptor to claim a certain byte is the one
+ * that applies.
+ * A bit which is set in 'start' must also be set in this.
+ * Can be zero, in which case each byte is assumed mapped exactly once.
+ * In this case, 'len' must be a power of two. */
+ size_t select;
+
+ /* If this is nonzero, the set bits are assumed not connected to the
+ * memory chip's address pins. */
+ size_t disconnect;
+
+ /* This one tells the size of the current memory area.
+ * If, after start+disconnect are applied, the address is higher than
+ * this, the highest bit of the address is cleared.
+ *
+ * If the address is still too high, the next highest bit is cleared.
+ * Can be zero, in which case it's assumed to be infinite (as limited
+ * by 'select' and 'disconnect'). */
+ size_t len;
+
+ /* To go from emulated address to physical address, the following
+ * order applies:
+ * Subtract 'start', pick off 'disconnect', apply 'len', add 'offset'.
+ *
+ * The address space name must consist of only a-zA-Z0-9_-,
+ * should be as short as feasible (maximum length is 8 plus the NUL),
+ * and may not be any other address space plus one or more 0-9A-F
+ * at the end.
+ * However, multiple memory descriptors for the same address space is
+ * allowed, and the address space name can be empty. NULL is treated
+ * as empty.
+ *
+ * Address space names are case sensitive, but avoid lowercase if possible.
+ * The same pointer may exist in multiple address spaces.
+ *
+ * Examples:
+ * blank+blank - valid (multiple things may be mapped in the same namespace)
+ * 'Sp'+'Sp' - valid (multiple things may be mapped in the same namespace)
+ * 'A'+'B' - valid (neither is a prefix of each other)
+ * 'S'+blank - valid ('S' is not in 0-9A-F)
+ * 'a'+blank - valid ('a' is not in 0-9A-F)
+ * 'a'+'A' - valid (neither is a prefix of each other)
+ * 'AR'+blank - valid ('R' is not in 0-9A-F)
+ * 'ARB'+blank - valid (the B can't be part of the address either, because
+ * there is no namespace 'AR')
+ * blank+'B' - not valid, because it's ambigous which address space B1234
+ * would refer to.
+ * The length can't be used for that purpose; the frontend may want
+ * to append arbitrary data to an address, without a separator. */
+ const char *addrspace;
+};
+
+/* The frontend may use the largest value of 'start'+'select' in a
+ * certain namespace to infer the size of the address space.
+ *
+ * If the address space is larger than that, a mapping with .ptr=NULL
+ * should be at the end of the array, with .select set to all ones for
+ * as long as the address space is big.
+ *
+ * Sample descriptors (minus .ptr, and RETRO_MEMFLAG_ on the flags):
+ * SNES WRAM:
+ * .start=0x7E0000, .len=0x20000
+ * (Note that this must be mapped before the ROM in most cases; some of the
+ * ROM mappers
+ * try to claim $7E0000, or at least $7E8000.)
+ * SNES SPC700 RAM:
+ * .addrspace="S", .len=0x10000
+ * SNES WRAM mirrors:
+ * .flags=MIRROR, .start=0x000000, .select=0xC0E000, .len=0x2000
+ * .flags=MIRROR, .start=0x800000, .select=0xC0E000, .len=0x2000
+ * SNES WRAM mirrors, alternate equivalent descriptor:
+ * .flags=MIRROR, .select=0x40E000, .disconnect=~0x1FFF
+ * (Various similar constructions can be created by combining parts of
+ * the above two.)
+ * SNES LoROM (512KB, mirrored a couple of times):
+ * .flags=CONST, .start=0x008000, .select=0x408000, .disconnect=0x8000, .len=512*1024
+ * .flags=CONST, .start=0x400000, .select=0x400000, .disconnect=0x8000, .len=512*1024
+ * SNES HiROM (4MB):
+ * .flags=CONST, .start=0x400000, .select=0x400000, .len=4*1024*1024
+ * .flags=CONST, .offset=0x8000, .start=0x008000, .select=0x408000, .len=4*1024*1024
+ * SNES ExHiROM (8MB):
+ * .flags=CONST, .offset=0, .start=0xC00000, .select=0xC00000, .len=4*1024*1024
+ * .flags=CONST, .offset=4*1024*1024, .start=0x400000, .select=0xC00000, .len=4*1024*1024
+ * .flags=CONST, .offset=0x8000, .start=0x808000, .select=0xC08000, .len=4*1024*1024
+ * .flags=CONST, .offset=4*1024*1024+0x8000, .start=0x008000, .select=0xC08000, .len=4*1024*1024
+ * Clarify the size of the address space:
+ * .ptr=NULL, .select=0xFFFFFF
+ * .len can be implied by .select in many of them, but was included for clarity.
+ */
+
+struct retro_memory_map
+{
+ const struct retro_memory_descriptor *descriptors;
+ unsigned num_descriptors;
+};
+
+struct retro_controller_description
+{
+ /* Human-readable description of the controller. Even if using a generic
+ * input device type, this can be set to the particular device type the
+ * core uses. */
+ const char *desc;
+
+ /* Device type passed to retro_set_controller_port_device(). If the device
+ * type is a sub-class of a generic input device type, use the
+ * RETRO_DEVICE_SUBCLASS macro to create an ID.
+ *
+ * E.g. RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1). */
+ unsigned id;
+};
+
+struct retro_controller_info
+{
+ const struct retro_controller_description *types;
+ unsigned num_types;
+};
+
+struct retro_subsystem_memory_info
+{
+ /* The extension associated with a memory type, e.g. "psram". */
+ const char *extension;
+
+ /* The memory type for retro_get_memory(). This should be at
+ * least 0x100 to avoid conflict with standardized
+ * libretro memory types. */
+ unsigned type;
+};
+
+struct retro_subsystem_rom_info
+{
+ /* Describes what the content is (SGB BIOS, GB ROM, etc). */
+ const char *desc;
+
+ /* Same definition as retro_get_system_info(). */
+ const char *valid_extensions;
+
+ /* Same definition as retro_get_system_info(). */
+ bool need_fullpath;
+
+ /* Same definition as retro_get_system_info(). */
+ bool block_extract;
+
+ /* This is set if the content is required to load a game.
+ * If this is set to false, a zeroed-out retro_game_info can be passed. */
+ bool required;
+
+ /* Content can have multiple associated persistent
+ * memory types (retro_get_memory()). */
+ const struct retro_subsystem_memory_info *memory;
+ unsigned num_memory;
+};
+
+struct retro_subsystem_info
+{
+ /* Human-readable string of the subsystem type, e.g. "Super GameBoy" */
+ const char *desc;
+
+ /* A computer friendly short string identifier for the subsystem type.
+ * This name must be [a-z].
+ * E.g. if desc is "Super GameBoy", this can be "sgb".
+ * This identifier can be used for command-line interfaces, etc.
+ */
+ const char *ident;
+
+ /* Infos for each content file. The first entry is assumed to be the
+ * "most significant" content for frontend purposes.
+ * E.g. with Super GameBoy, the first content should be the GameBoy ROM,
+ * as it is the most "significant" content to a user.
+ * If a frontend creates new file paths based on the content used
+ * (e.g. savestates), it should use the path for the first ROM to do so. */
+ const struct retro_subsystem_rom_info *roms;
+
+ /* Number of content files associated with a subsystem. */
+ unsigned num_roms;
+
+ /* The type passed to retro_load_game_special(). */
+ unsigned id;
+};
+
+typedef void (*retro_proc_address_t)(void);
+
+/* libretro API extension functions:
+ * (None here so far).
+ *
+ * Get a symbol from a libretro core.
+ * Cores should only return symbols which are actual
+ * extensions to the libretro API.
+ *
+ * Frontends should not use this to obtain symbols to standard
+ * libretro entry points (static linking or dlsym).
+ *
+ * The symbol name must be equal to the function name,
+ * e.g. if void retro_foo(void); exists, the symbol must be called "retro_foo".
+ * The returned function pointer must be cast to the corresponding type.
+ */
+typedef retro_proc_address_t (*retro_get_proc_address_t)(const char *sym);
+
+struct retro_get_proc_address_interface
+{
+ retro_get_proc_address_t get_proc_address;
+};
+
+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)
+#define RETRO_SIMD_MMX (1 << 8)
+#define RETRO_SIMD_MMXEXT (1 << 9)
+#define RETRO_SIMD_SSE4 (1 << 10)
+#define RETRO_SIMD_SSE42 (1 << 11)
+#define RETRO_SIMD_AVX2 (1 << 12)
+#define RETRO_SIMD_VFPU (1 << 13)
+#define RETRO_SIMD_PS (1 << 14)
+#define RETRO_SIMD_AES (1 << 15)
+
+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;
+};