diff options
-rw-r--r-- | libretro.c | 156 | ||||
-rw-r--r-- | libretro.h | 337 | ||||
-rw-r--r-- | libretro_core_options.h | 813 | ||||
-rw-r--r-- | libretro_core_options_intl.h | 88 |
4 files changed, 605 insertions, 789 deletions
@@ -54,6 +54,15 @@ int one_c, slow_one_c, two_c; static int32_t samples_per_frame = 0; static int32_t samplerate = (((SNES_CLOCK_SPEED * 6) / (32 * ONE_APU_CYCLE))); +static unsigned frameskip_type = 0; +static uint16_t frameskip_counter = 0; +static bool retro_audio_buff_active = false; +static unsigned retro_audio_buff_occupancy = 0; +static bool retro_audio_buff_underrun = false; +/* Maximum number of consecutive frames that + * can be skipped */ +#define FRAMESKIP_MAX 30 + #ifdef PERF_TEST #define RETRO_PERFORMANCE_INIT(name) \ retro_perf_tick_t current_ticks; \ @@ -124,6 +133,37 @@ unsigned retro_api_version() return RETRO_API_VERSION; } +static void retro_audio_buff_status_cb( + bool active, unsigned occupancy, bool underrun_likely) +{ + retro_audio_buff_active = active; + retro_audio_buff_occupancy = occupancy; + retro_audio_buff_underrun = underrun_likely; +} + +static void retro_set_audio_buff_status_cb(void) +{ + if (frameskip_type > 0) + { + struct retro_audio_buffer_status_callback buf_status_cb; + + buf_status_cb.callback = retro_audio_buff_status_cb; + if (!environ_cb(RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK, + &buf_status_cb)) + { + if (log_cb) + log_cb(RETRO_LOG_WARN, "Frameskip disabled - frontend does not support audio buffer status monitoring.\n"); + + retro_audio_buff_active = false; + retro_audio_buff_occupancy = 0; + retro_audio_buff_underrun = false; + } + } + else + environ_cb(RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK, + NULL); +} + void S9xDeinitDisplay(void) { #ifdef DS2_DMA @@ -386,54 +426,71 @@ uint32_t S9xReadJoypad(int32_t port) static void check_variables(void) { struct retro_variable var; + bool prev_frameskip_type; var.key = "catsfc_VideoMode"; var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { Settings.ForceNTSC = !strcmp(var.value, "NTSC"); Settings.ForcePAL = !strcmp(var.value, "PAL"); } + var.key = "catsfc_frameskip"; + var.value = NULL; + + prev_frameskip_type = frameskip_type; + frameskip_type = 0; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "auto") == 0) + frameskip_type = 1; + else if (strcmp(var.value, "aggressive") == 0) + frameskip_type = 2; + else if (strcmp(var.value, "max") == 0) + frameskip_type = 3; + } + + if (frameskip_type != prev_frameskip_type) + retro_set_audio_buff_status_cb(); + var.key = "catsfc_overclock_cycles"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "compatible") == 0) + { + overclock_cycles = true; + one_c = 4; + slow_one_c = 5; + two_c = 6; + } + else if (strcmp(var.value, "max") == 0) { - if (strcmp(var.value, "compatible") == 0) - { - overclock_cycles = true; - one_c = 4; - slow_one_c = 5; - two_c = 6; - } - else if (strcmp(var.value, "max") == 0) - { - overclock_cycles = true; - one_c = 3; - slow_one_c = 3; - two_c = 3; - } - else - overclock_cycles = false; + overclock_cycles = true; + one_c = 3; + slow_one_c = 3; + two_c = 3; } + else + overclock_cycles = false; + } var.key = "catsfc_reduce_sprite_flicker"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "enabled") == 0) - reduce_sprite_flicker = true; - else - reduce_sprite_flicker = false; - } + { + if (strcmp(var.value, "enabled") == 0) + reduce_sprite_flicker = true; + else + reduce_sprite_flicker = false; + } } -#ifdef PSP -#define FRAMESKIP -#endif - static int32_t samples_to_play = 0; void retro_run(void) { @@ -474,6 +531,42 @@ void retro_run(void) Settings.HardDisableAudio = false; } + /* Check whether current frame should + * be skipped */ + if ((frameskip_type > 0) && + retro_audio_buff_active && + IPPU.RenderThisFrame) + { + bool skip_frame; + + switch (frameskip_type) + { + case 1: /* auto */ + skip_frame = retro_audio_buff_underrun; + break; + case 2: /* aggressive */ + skip_frame = (retro_audio_buff_occupancy < 33); + break; + case 3: /* max */ + skip_frame = (retro_audio_buff_occupancy < 50); + break; + default: + skip_frame = false; + break; + } + + if (skip_frame) + { + if(frameskip_counter < FRAMESKIP_MAX) + { + IPPU.RenderThisFrame = false; + frameskip_counter++; + } + else + frameskip_counter = 0; + } + } + poll_cb(); RETRO_PERFORMANCE_INIT(S9xMainLoop_func); @@ -498,11 +591,8 @@ void retro_run(void) return; #endif -#ifdef FRAMESKIP if (IPPU.RenderThisFrame) { -#endif - #ifdef PSP static unsigned int __attribute__((aligned(16))) d_list[32]; void* const texture_vram_p = (void*)(0x44200000 - (512 * 512)); /* max VRAM address - frame size */ @@ -519,16 +609,9 @@ void retro_run(void) #else video_cb(GFX.Screen, IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight, GFX.Pitch); #endif - -#ifdef FRAMESKIP - IPPU.RenderThisFrame = false; } else - { video_cb(NULL, IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight, GFX.Pitch); - IPPU.RenderThisFrame = true; - } -#endif } bool S9xReadMousePosition(int32_t which1, int32_t* x, int32_t* y, uint32_t* buttons) @@ -868,6 +951,7 @@ bool retro_load_game(const struct retro_game_info* game) Settings.FrameTime = (Settings.PAL ? Settings.FrameTimePAL : Settings.FrameTimeNTSC); + retro_set_audio_buff_status_cb(); retro_get_system_av_info(&av_info); #ifdef USE_BLARGG_APU @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro API header (libretro.h). @@ -278,6 +278,10 @@ enum retro_language RETRO_LANGUAGE_ARABIC = 16, RETRO_LANGUAGE_GREEK = 17, RETRO_LANGUAGE_TURKISH = 18, + RETRO_LANGUAGE_SLOVAK = 19, + RETRO_LANGUAGE_PERSIAN = 20, + RETRO_LANGUAGE_HEBREW = 21, + RETRO_LANGUAGE_ASTURIAN = 22, RETRO_LANGUAGE_LAST, /* Ensure sizeof(enum) == sizeof(int) */ @@ -1087,10 +1091,10 @@ enum retro_mod #define RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE (50 | RETRO_ENVIRONMENT_EXPERIMENTAL) /* float * -- - * Float value that lets us know what target refresh rate + * Float value that lets us know what target refresh rate * is curently in use by the frontend. * - * The core can use the returned value to set an ideal + * The core can use the returned value to set an ideal * refresh rate/framerate. */ @@ -1098,7 +1102,7 @@ enum retro_mod /* bool * -- * Boolean value that indicates whether or not the frontend supports * input bitmasks being returned by retro_input_state_t. The advantage - * of this is that retro_input_state_t has to be only called once to + * of this is that retro_input_state_t has to be only called once to * grab all button states instead of multiple times. * * If it returns true, you can pass RETRO_DEVICE_ID_JOYPAD_MASK as 'id' @@ -1117,7 +1121,7 @@ enum retro_mod * This may be still be done regardless of the core options * interface version. * - * If version is 1 however, core options may instead be set by + * If version is >= 1 however, core options may instead be set by * passing an array of retro_core_option_definition structs to * RETRO_ENVIRONMENT_SET_CORE_OPTIONS, or a 2D array of * retro_core_option_definition structs to RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL. @@ -1132,8 +1136,8 @@ enum retro_mod * GET_VARIABLE. * This allows the frontend to present these variables to * a user dynamically. - * This should only be called if RETRO_ENVIRONMENT_GET_ENHANCED_CORE_OPTIONS - * returns an API version of 1. + * This should only be called if RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION + * returns an API version of >= 1. * This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES. * This should be called the first time as early as * possible (ideally in retro_set_environment). @@ -1169,8 +1173,6 @@ enum retro_mod * 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", @@ -1196,8 +1198,8 @@ enum retro_mod * GET_VARIABLE. * This allows the frontend to present these variables to * a user dynamically. - * This should only be called if RETRO_ENVIRONMENT_GET_ENHANCED_CORE_OPTIONS - * returns an API version of 1. + * This should only be called if RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION + * returns an API version of >= 1. * This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES. * This should be called the first time as early as * possible (ideally in retro_set_environment). @@ -1248,6 +1250,100 @@ enum retro_mod * default when calling SET_VARIABLES/SET_CORE_OPTIONS. */ +#define RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER 56 + /* unsigned * -- + * + * Allows an implementation to ask frontend preferred hardware + * context to use. Core should use this information to deal + * with what specific context to request with SET_HW_RENDER. + * + * 'data' points to an unsigned variable + */ + +#define RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION 57 + /* unsigned * -- + * Unsigned value is the API version number of the disk control + * interface supported by the frontend. If callback return false, + * API version is assumed to be 0. + * + * In legacy code, the disk control interface is defined by passing + * a struct of type retro_disk_control_callback to + * RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE. + * This may be still be done regardless of the disk control + * interface version. + * + * If version is >= 1 however, the disk control interface may + * instead be defined by passing a struct of type + * retro_disk_control_ext_callback to + * RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE. + * This allows the core to provide additional information about + * disk images to the frontend and/or enables extra + * disk control functionality by the frontend. + */ + +#define RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE 58 + /* const struct retro_disk_control_ext_callback * -- + * Sets an interface which frontend can use to eject and insert + * disk images, and also obtain information about individual + * disk image files registered by the core. + * This is used for games which consist of multiple images and + * must be manually swapped out by the user (e.g. PSX, floppy disk + * based systems). + */ + +#define RETRO_ENVIRONMENT_GET_MESSAGE_INTERFACE_VERSION 59 + /* unsigned * -- + * Unsigned value is the API version number of the message + * interface supported by the frontend. If callback returns + * false, API version is assumed to be 0. + * + * In legacy code, messages may be displayed in an + * implementation-specific manner by passing a struct + * of type retro_message to RETRO_ENVIRONMENT_SET_MESSAGE. + * This may be still be done regardless of the message + * interface version. + * + * If version is >= 1 however, messages may instead be + * displayed by passing a struct of type retro_message_ext + * to RETRO_ENVIRONMENT_SET_MESSAGE_EXT. This allows the + * core to specify message logging level, priority and + * destination (OSD, logging interface or both). + */ + +#define RETRO_ENVIRONMENT_SET_MESSAGE_EXT 60 + /* const struct retro_message_ext * -- + * Sets a message to be displayed in an implementation-specific + * manner for a certain amount of 'frames'. Additionally allows + * the core to specify message logging level, priority and + * destination (OSD, logging interface or both). + * Should not be used for trivial messages, which should simply be + * logged via RETRO_ENVIRONMENT_GET_LOG_INTERFACE (or as a + * fallback, stderr). + */ + +#define RETRO_ENVIRONMENT_GET_INPUT_MAX_USERS 61 + /* unsigned * -- + * Unsigned value is the number of active input devices + * provided by the frontend. This may change between + * frames, but will remain constant for the duration + * of each frame. + * If callback returns true, a core need not poll any + * input device with an index greater than or equal to + * the number of active devices. + * If callback returns false, the number of active input + * devices is unknown. In this case, all input devices + * should be considered active. + */ + +#define RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK 62 + /* const struct retro_audio_buffer_status_callback * -- + * Lets the core know the occupancy level of the frontend + * audio buffer. Can be used by a core to attempt frame + * skipping in order to avoid buffer under-runs. + * A core may pass NULL to disable buffer status reporting + * in the frontend. + */ + /* VFS functionality */ /* File paths: @@ -1924,6 +2020,10 @@ enum retro_sensor_action { RETRO_SENSOR_ACCELEROMETER_ENABLE = 0, RETRO_SENSOR_ACCELEROMETER_DISABLE, + RETRO_SENSOR_GYROSCOPE_ENABLE, + RETRO_SENSOR_GYROSCOPE_DISABLE, + RETRO_SENSOR_ILLUMINANCE_ENABLE, + RETRO_SENSOR_ILLUMINANCE_DISABLE, RETRO_SENSOR_DUMMY = INT_MAX }; @@ -1932,6 +2032,10 @@ enum retro_sensor_action #define RETRO_SENSOR_ACCELEROMETER_X 0 #define RETRO_SENSOR_ACCELEROMETER_Y 1 #define RETRO_SENSOR_ACCELEROMETER_Z 2 +#define RETRO_SENSOR_GYROSCOPE_X 3 +#define RETRO_SENSOR_GYROSCOPE_Y 4 +#define RETRO_SENSOR_GYROSCOPE_Z 5 +#define RETRO_SENSOR_ILLUMINANCE 6 typedef bool (RETRO_CALLCONV *retro_set_sensor_state_t)(unsigned port, enum retro_sensor_action action, unsigned rate); @@ -2129,6 +2233,30 @@ struct retro_frame_time_callback retro_usec_t reference; }; +/* Notifies a libretro core of the current occupancy + * level of the frontend audio buffer. + * + * - active: 'true' if audio buffer is currently + * in use. Will be 'false' if audio is + * disabled in the frontend + * + * - occupancy: Given as a value in the range [0,100], + * corresponding to the occupancy percentage + * of the audio buffer + * + * - underrun_likely: 'true' if the frontend expects an + * audio buffer underrun during the + * next frame (indicates that a core + * should attempt frame skipping) + * + * It will be called right before retro_run() every frame. */ +typedef void (RETRO_CALLCONV *retro_audio_buffer_status_callback_t)( + bool active, unsigned occupancy, bool underrun_likely); +struct retro_audio_buffer_status_callback +{ + retro_audio_buffer_status_callback_t callback; +}; + /* Pass this to retro_video_refresh_t if rendering to hardware. * Passing NULL to retro_video_refresh_t is still a frame dupe as normal. * */ @@ -2289,7 +2417,8 @@ struct retro_keyboard_callback retro_keyboard_event_t callback; }; -/* Callbacks for RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE. +/* Callbacks for RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE & + * RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE. * Should be set for implementations which can swap out multiple disk * images in runtime. * @@ -2347,6 +2476,53 @@ typedef bool (RETRO_CALLCONV *retro_replace_image_index_t)(unsigned index, * with replace_image_index. */ typedef bool (RETRO_CALLCONV *retro_add_image_index_t)(void); +/* Sets initial image to insert in drive when calling + * core_load_game(). + * Since we cannot pass the initial index when loading + * content (this would require a major API change), this + * is set by the frontend *before* calling the core's + * retro_load_game()/retro_load_game_special() implementation. + * A core should therefore cache the index/path values and handle + * them inside retro_load_game()/retro_load_game_special(). + * - If 'index' is invalid (index >= get_num_images()), the + * core should ignore the set value and instead use 0 + * - 'path' is used purely for error checking - i.e. when + * content is loaded, the core should verify that the + * disk specified by 'index' has the specified file path. + * This is to guard against auto selecting the wrong image + * if (for example) the user should modify an existing M3U + * playlist. We have to let the core handle this because + * set_initial_image() must be called before loading content, + * i.e. the frontend cannot access image paths in advance + * and thus cannot perform the error check itself. + * If set path and content path do not match, the core should + * ignore the set 'index' value and instead use 0 + * Returns 'false' if index or 'path' are invalid, or core + * does not support this functionality + */ +typedef bool (RETRO_CALLCONV *retro_set_initial_image_t)(unsigned index, const char *path); + +/* Fetches the path of the specified disk image file. + * Returns 'false' if index is invalid (index >= get_num_images()) + * or path is otherwise unavailable. + */ +typedef bool (RETRO_CALLCONV *retro_get_image_path_t)(unsigned index, char *path, size_t len); + +/* Fetches a core-provided 'label' for the specified disk + * image file. In the simplest case this may be a file name + * (without extension), but for cores with more complex + * content requirements information may be provided to + * facilitate user disk swapping - for example, a core + * running floppy-disk-based content may uniquely label + * save disks, data disks, level disks, etc. with names + * corresponding to in-game disk change prompts (so the + * frontend can provide better user guidance than a 'dumb' + * disk index value). + * Returns 'false' if index is invalid (index >= get_num_images()) + * or label is otherwise unavailable. + */ +typedef bool (RETRO_CALLCONV *retro_get_image_label_t)(unsigned index, char *label, size_t len); + struct retro_disk_control_callback { retro_set_eject_state_t set_eject_state; @@ -2360,6 +2536,27 @@ struct retro_disk_control_callback retro_add_image_index_t add_image_index; }; +struct retro_disk_control_ext_callback +{ + retro_set_eject_state_t set_eject_state; + retro_get_eject_state_t get_eject_state; + + retro_get_image_index_t get_image_index; + retro_set_image_index_t set_image_index; + retro_get_num_images_t get_num_images; + + retro_replace_image_index_t replace_image_index; + retro_add_image_index_t add_image_index; + + /* NOTE: Frontend will only attempt to record/restore + * last used disk index if both set_initial_image() + * and get_image_path() are implemented */ + retro_set_initial_image_t set_initial_image; /* Optional - may be NULL */ + + retro_get_image_path_t get_image_path; /* Optional - may be NULL */ + retro_get_image_label_t get_image_label; /* Optional - may be NULL */ +}; + enum retro_pixel_format { /* 0RGB1555, native endian. @@ -2390,6 +2587,104 @@ struct retro_message unsigned frames; /* Duration in frames of message. */ }; +enum retro_message_target +{ + RETRO_MESSAGE_TARGET_ALL = 0, + RETRO_MESSAGE_TARGET_OSD, + RETRO_MESSAGE_TARGET_LOG +}; + +enum retro_message_type +{ + RETRO_MESSAGE_TYPE_NOTIFICATION = 0, + RETRO_MESSAGE_TYPE_NOTIFICATION_ALT, + RETRO_MESSAGE_TYPE_STATUS, + RETRO_MESSAGE_TYPE_PROGRESS +}; + +struct retro_message_ext +{ + /* Message string to be displayed/logged */ + const char *msg; + /* Duration (in ms) of message when targeting the OSD */ + unsigned duration; + /* Message priority when targeting the OSD + * > When multiple concurrent messages are sent to + * the frontend and the frontend does not have the + * capacity to display them all, messages with the + * *highest* priority value should be shown + * > There is no upper limit to a message priority + * value (within the bounds of the unsigned data type) + * > In the reference frontend (RetroArch), the same + * priority values are used for frontend-generated + * notifications, which are typically assigned values + * between 0 and 3 depending upon importance */ + unsigned priority; + /* Message logging level (info, warn, error, etc.) */ + enum retro_log_level level; + /* Message destination: OSD, logging interface or both */ + enum retro_message_target target; + /* Message 'type' when targeting the OSD + * > RETRO_MESSAGE_TYPE_NOTIFICATION: Specifies that a + * message should be handled in identical fashion to + * a standard frontend-generated notification + * > RETRO_MESSAGE_TYPE_NOTIFICATION_ALT: Specifies that + * message is a notification that requires user attention + * or action, but that it should be displayed in a manner + * that differs from standard frontend-generated notifications. + * This would typically correspond to messages that should be + * displayed immediately (independently from any internal + * frontend message queue), and/or which should be visually + * distinguishable from frontend-generated notifications. + * For example, a core may wish to inform the user of + * information related to a disk-change event. It is + * expected that the frontend itself may provide a + * notification in this case; if the core sends a + * message of type RETRO_MESSAGE_TYPE_NOTIFICATION, an + * uncomfortable 'double-notification' may occur. A message + * of RETRO_MESSAGE_TYPE_NOTIFICATION_ALT should therefore + * be presented such that visual conflict with regular + * notifications does not occur + * > RETRO_MESSAGE_TYPE_STATUS: Indicates that message + * is not a standard notification. This typically + * corresponds to 'status' indicators, such as a core's + * internal FPS, which are intended to be displayed + * either permanently while a core is running, or in + * a manner that does not suggest user attention or action + * is required. 'Status' type messages should therefore be + * displayed in a different on-screen location and in a manner + * easily distinguishable from both standard frontend-generated + * notifications and messages of type RETRO_MESSAGE_TYPE_NOTIFICATION_ALT + * > RETRO_MESSAGE_TYPE_PROGRESS: Indicates that message reports + * the progress of an internal core task. For example, in cases + * where a core itself handles the loading of content from a file, + * this may correspond to the percentage of the file that has been + * read. Alternatively, an audio/video playback core may use a + * message of type RETRO_MESSAGE_TYPE_PROGRESS to display the current + * playback position as a percentage of the runtime. 'Progress' type + * messages should therefore be displayed as a literal progress bar, + * where: + * - 'retro_message_ext.msg' is the progress bar title/label + * - 'retro_message_ext.progress' determines the length of + * the progress bar + * NOTE: Message type is a *hint*, and may be ignored + * by the frontend. If a frontend lacks support for + * displaying messages via alternate means than standard + * frontend-generated notifications, it will treat *all* + * messages as having the type RETRO_MESSAGE_TYPE_NOTIFICATION */ + enum retro_message_type type; + /* Task progress when targeting the OSD and message is + * of type RETRO_MESSAGE_TYPE_PROGRESS + * > -1: Unmetered/indeterminate + * > 0-100: Current progress percentage + * NOTE: Since message type is a hint, a frontend may ignore + * progress values. Where relevant, a core should therefore + * include progress percentage within the message string, + * such that the message intent remains clear when displayed + * as a standard frontend-generated notification */ + int8_t progress; +}; + /* Describes how the libretro implementation maps a libretro input bind * to its internal input system through a human readable string. * This string can be used to better let a user configure input. */ @@ -2410,7 +2705,7 @@ struct retro_input_descriptor struct retro_system_info { /* All pointers are owned by libretro implementation, and pointers must - * remain valid until retro_deinit() is called. */ + * remain valid until it is unloaded. */ const char *library_name; /* Descriptive name of library. Should not * contain any version numbers, etc. */ @@ -2504,8 +2799,20 @@ struct retro_core_option_display }; /* Maximum number of values permitted for a core option - * NOTE: This may be increased on a core-by-core basis - * if required (doing so has no effect on the frontend) */ + * > Note: We have to set a maximum value due the limitations + * of the C language - i.e. it is not possible to create an + * array of structs each containing a variable sized array, + * so the retro_core_option_definition values array must + * have a fixed size. The size limit of 128 is a balancing + * act - it needs to be large enough to support all 'sane' + * core options, but setting it too large may impact low memory + * platforms. In practise, if a core option has more than + * 128 values then the implementation is likely flawed. + * To quote the above API reference: + * "The number of possible options should be very limited + * i.e. it should be feasible to cycle through options + * without a keyboard." + */ #define RETRO_NUM_CORE_OPTION_VALUES_MAX 128 struct retro_core_option_value diff --git a/libretro_core_options.h b/libretro_core_options.h index c1f2490..3f92b3b 100644 --- a/libretro_core_options.h +++ b/libretro_core_options.h @@ -7,6 +7,28 @@ #include <libretro.h> #include <retro_inline.h> +#ifndef HAVE_NO_LANGEXTRA +#include "libretro_core_options_intl.h" +#endif + +/* + ******************************** + * VERSION: 1.3 + ******************************** + * + * - 1.3: Move translations to libretro_core_options_intl.h + * - libretro_core_options_intl.h includes BOM and utf-8 + * fix for MSVC 2010-2013 + * - Added HAVE_NO_LANGEXTRA flag to disable translations + * on platforms/compilers without BOM support + * - 1.2: Use core options v1 interface when + * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1 + * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1) + * - 1.1: Support generation of core options v0 retro_core_option_value + * arrays containing options with a single value + * - 1.0: First commit +*/ + #ifdef __cplusplus extern "C" { #endif @@ -34,733 +56,52 @@ struct retro_core_option_definition option_defs_us[] = { { "catsfc_VideoMode", - "Video Mode", - "Awaiting description.", + "Console Region", + "Specify which region the system is from. 'PAL' is 50hz, 'NTSC' is 60hz. Games will run faster or slower than normal if the incorrect region is selected.", { - { "auto", NULL }, + { "auto", "Auto" }, { "NTSC", NULL }, { "PAL", NULL }, - { NULL, NULL}, - }, - "auto" - }, - { - "catsfc_overclock_cycles", - "Reduce Slowdown (Hack, Unsafe, Restart)", - "Many games for the SNES suffered from slowdown due to the weak main CPU. This option helps allievate that at the cost of possible bugs. COMPATIBLE: Reduce slowdown but keep as much game compatibility as much as possible. MAX: Reduce slowdown as much as possible but will break more games.", - { - { "disabled", NULL }, - { "compatible", NULL }, - { "max", NULL }, - { NULL, NULL}, - }, - "disabled" - }, - { - "catsfc_next_reduce_sprite_flicker", - "Reduce Flickering (Hack, Unsafe)", - "Raises sprite limit to reduce flickering in games.", - { - { "disabled", NULL }, - { "enabled", NULL }, - { NULL, NULL}, - }, - "disabled" - }, - { NULL, NULL, NULL, {{0}}, NULL }, -}; - -/* RETRO_LANGUAGE_JAPANESE */ - -/* RETRO_LANGUAGE_FRENCH */ - -/* RETRO_LANGUAGE_SPANISH */ - -/* RETRO_LANGUAGE_GERMAN */ - -/* RETRO_LANGUAGE_ITALIAN */ - -/* RETRO_LANGUAGE_DUTCH */ - -/* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */ - -/* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */ - -/* RETRO_LANGUAGE_RUSSIAN */ - -/* RETRO_LANGUAGE_KOREAN */ - -/* RETRO_LANGUAGE_CHINESE_TRADITIONAL */ - -/* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */ - -/* RETRO_LANGUAGE_ESPERANTO */ - -/* RETRO_LANGUAGE_POLISH */ - -/* RETRO_LANGUAGE_VIETNAMESE */ - -/* RETRO_LANGUAGE_ARABIC */ - -/* RETRO_LANGUAGE_GREEK */ - -/* RETRO_LANGUAGE_TURKISH */ - -struct retro_core_option_definition option_defs_tr[] = { - - /* These variable names and possible values constitute an ABI with ZMZ (ZSNES Libretro player). - * Changing "Show layer 1" is fine, but don't change "layer_1"/etc or the possible values ("Yes|No"). - * Adding more variables and rearranging them is safe. */ - { - "snes9x_region", - "Konsol Bölgesi (Core Yenilenir)", - "Sistemin hangi bölgeden olduğunu belirtir.. 'PAL' 50hz'dir, 'NTSC' ise 60hz. Yanlış bölge seçiliyse, oyunlar normalden daha hızlı veya daha yavaş çalışacaktır.", - { - { "auto", "Otomatik" }, - { "ntsc", "NTSC" }, - { "pal", "PAL" }, - { NULL, NULL}, + { NULL, NULL }, }, "auto" }, { - "snes9x_aspect", - "Tercih Edilen En Boy Oranı", - "Tercih edilen içerik en boy oranını seçin. Bu, yalnızca RetroArch’ın en boy oranı Video ayarlarında 'Core tarafından' olarak ayarlandığında uygulanacaktır.", - { - { "4:3", NULL }, - { "uncorrected", "Düzeltilmemiş" }, - { "auto", "Otomatik" }, - { "ntsc", "NTSC" }, - { "pal", "PAL" }, - { NULL, NULL}, - }, - "4:3" - }, - { - "snes9x_overscan", - "Aşırı Taramayı Kırp", - "Ekranın üst ve alt kısmındaki ~8 piksel sınırlarını, tipik olarak standart çözünürlüklü bir televizyondakini kaldırır. 'Otomatik' ise geçerli içeriğe bağlı olarak aşırı taramayı algılamaya ve kırpmaya çalışacaktır.", - { - { "enabled", NULL }, - { "disabled", NULL }, - { "auto", "Otomatik" }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_gfx_hires", - "Hi-Res Modunu Etkinleştir", - "Oyunların hi-res moduna (512x448) geçmesine izin verir veya tüm içeriği 256x224'te (ezilmiş piksellerle) çıkmaya zorlar.", - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_hires_blend", - "Hi-Res Karışımı", - "Oyun hi-res moduna geçtiğinde pikselleri karıştırır (512x448). Şeffaflık efektleri üretmek için hi-res modunu kullanan bazı oyunlar için gereklidir (Kirby's Dream Land, Jurassic Park ...).", - { - { "disabled", NULL }, - { "merge", "Birlşetir" }, - { "blur", "Bulanıklaştır" }, - { NULL, NULL}, - }, - "disabled" - }, - { - "snes9x_blargg", - "Blargg NTSC Filtresi", - "Çeşitli NTSC TV sinyallerini taklit etmek için bir video filtresi uygular.", + "catsfc_frameskip", + "Frameskip", + "Automatically skip frames to avoid audio buffer under-run (crackling). 'Aggressive' and 'Max' increase the buffer threshold at which frames are skipped. Improves performance at the expense of visual smoothness. NOTE: For best results, frontend 'Audio Latency' should be set to at least 128 ms.", { { "disabled", NULL }, - { "monochrome", "Monochrome" }, - { "rf", "RF" }, - { "composite", "Composite" }, - { "s-video", "S-Video" }, - { "rgb", "RGB" }, - { NULL, NULL}, - }, - "disabled" - }, - { - "snes9x_audio_interpolation", - "Ses Enterpolasyonu", - "Belirtilen ses filtresini uygular. 'Gaussian', orijinal donanımın bas ağırlıklı sesini üretir. 'Cubic' ve 'Sinc' daha az doğrudur ve daha fazla aralığı korur.", - { - { "gaussian", "Gaussian" }, - { "cubic", "Cubic" }, - { "sinc", "Sinc" }, - { "none", "Hiçbiri" }, - { "linear", "Linear" }, - { NULL, NULL}, - }, - "gaussian" - }, - { - "snes9x_up_down_allowed", - "Karşı Yönlere İzin Ver", - "Bunu etkinleştirmek aynı anda hem sola hem de sağa (veya yukarı ve aşağı) yönlere basma / hızlı değiştirme / tutma imkanı sağlar. Bu harekete dayalı hatalara neden olabilir.", - { - { "disabled", NULL }, - { "enabled", NULL }, + { "auto", "Auto" }, + { "aggressive", "Aggressive" }, + { "max", "Max" }, { NULL, NULL }, }, "disabled" }, { - "snes9x_overclock_superfx", - "SuperFX Hız Aşırtma", - "SuperFX işlemcisi frekans çarpanıdır. Kare hızını artırabilir veya zamanlama hatalarına neden olabilir. % 100'ün altındaki değerler yavaş cihazlarda oyun performansını artırabilir.", - { - { "50%", NULL }, - { "60%", NULL }, - { "70%", NULL }, - { "80%", NULL }, - { "90%", NULL }, - { "100%", NULL }, - { "150%", NULL }, - { "200%", NULL }, - { "250%", NULL }, - { "300%", NULL }, - { "350%", NULL }, - { "400%", NULL }, - { "450%", NULL }, - { "500%", NULL }, - { NULL, NULL}, - }, - "100%" - }, - { - "snes9x_overclock_cycles", - "Yavaşlamayı Azalt (Hack, Güvensiz)", - "SNES İşlemcisi için hız aşırtmadır. Oyunların çökmesine neden olabilir! Daha kısa yükleme süreleri için 'Hafif'i, yavaşlama gösteren oyunların çoğunda' Uyumlu 've yalnızca kesinlikle gerekliyse' Maks 'kullanın (Gradius 3, Süper R tipi ...).", + "catsfc_overclock_cycles", + "Reduce Slowdown (Hack, Unsafe, Restart)", + "Many games for the SNES suffered from slowdown due to the weak main CPU. This option helps allievate that at the cost of possible bugs. COMPATIBLE: Reduce slowdown but keep as much game compatibility as much as possible. MAX: Reduce slowdown as much as possible but will break more games.", { { "disabled", NULL }, - { "light", "Hafif" }, - { "compatible", "Uyumlu" }, - { "max", "Maks" }, - { NULL, NULL}, - }, - "disabled" - }, - { - "snes9x_reduce_sprite_flicker", - "Kırılmayı Azalt (Hack, Güvensiz)", - "Ekranda aynı anda çizilebilen sprite sayısını arttırır.", - { - { "disabled", NULL }, - { "enabled", NULL }, - { NULL, NULL}, - }, - "disabled" - }, - { - "snes9x_randomize_memory", - "Belleği Rastgele Kıl (Güvensiz)", - "Başlatıldığında sistem RAM'ını rastgele ayarlar. 'Super Off Road' gibi bazı oyunlar, oyunu daha öngörülemeyen hale getirmek için öğe yerleştirme ve AI davranışı için rastgele sayı üreticisi olarak sistem RAM'ini kullanır.", - { - { "disabled", NULL }, - { "enabled", NULL }, - { NULL, NULL}, - }, - "disabled" - }, - { - "snes9x_block_invalid_vram_access", - "Geçersiz VRAM Erişimini Engelle", - "Bazı Homebrew/ROM'lar, doğru işlem için bu seçeneğin devre dışı bırakılmasını gerektirir.", - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_echo_buffer_hack", - "Eko Tampon Hack (Güvenli değil, yalnızca eski addmusic için etkinleştirin)", - "Bazı Homebrew/ROM'lar, doğru işlem için bu seçeneğin devre dışı bırakılmasını gerektirir.", - { - { "disabled", NULL }, - { "enabled", NULL }, - { NULL, NULL}, - }, - "disabled" - }, - { - "snes9x_show_lightgun_settings", - "Light Gun Ayarlarını Göster", - "Super Scope / Justifier / M.A.C.S. için tüfek girişi yapılandırmasını etkinleştir. NOT: Bu ayarın etkili olabilmesi için Hızlı Menü’nün açılması gerekir.", - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, + { "compatible", "Compatible" }, + { "max", "Max" }, + { NULL, NULL }, }, "disabled" }, { - "snes9x_lightgun_mode", - "Light Gun Modu", - "Fare kontrollü 'Light Gun' veya 'Dokunmatik Ekran' girişini kullanın.", - { - { "Lightgun", "Light Gun" }, - { "Touchscreen", "Dokunmatik Ekran" }, - { NULL, NULL}, - }, - "Lightgun" - }, - { - "snes9x_superscope_reverse_buttons", - "Super Scope Ters Tetik Düğmeleri", - "Süper Scope için 'Ateş' ve 'İmleç' butonlarının pozisyonlarını değiştir.", + "catsfc_reduce_sprite_flicker", + "Reduce Flickering (Hack, Unsafe)", + "Raises sprite limit to reduce flickering in games.", { { "disabled", NULL }, { "enabled", NULL }, - { NULL, NULL}, - }, - "disabled" - }, - { - "snes9x_superscope_crosshair", - "Super Scope İmkeç", - "Ekrandaki imleç işaretini değiştirin.", - { - { "0", NULL }, - { "1", NULL }, - { "2", NULL }, - { "3", NULL }, - { "4", NULL }, - { "5", NULL }, - { "6", NULL }, - { "7", NULL }, - { "8", NULL }, - { "9", NULL }, - { "10", NULL }, - { "11", NULL }, - { "12", NULL }, - { "13", NULL }, - { "14", NULL }, - { "15", NULL }, - { "16", NULL }, - { NULL, NULL}, - }, - "2" - }, - { - "snes9x_superscope_color", - "Super Scope Rengi", - "Ekrandaki imleç işaretinin rengini değiştirin.", - { - { "White", NULL }, - { "White (blend)", NULL }, - { "Red", NULL }, - { "Red (blend)", NULL }, - { "Orange", NULL }, - { "Orange (blend)", NULL }, - { "Yellow", NULL }, - { "Yellow (blend)", NULL }, - { "Green", NULL }, - { "Green (blend)", NULL }, - { "Cyan", NULL }, - { "Cyan (blend)", NULL }, - { "Sky", NULL }, - { "Sky (blend)", NULL }, - { "Blue", NULL }, - { "Blue (blend)", NULL }, - { "Violet", NULL }, - { "Violet (blend)", NULL }, - { "Pink", NULL }, - { "Pink (blend)", NULL }, - { "Purple", NULL }, - { "Purple (blend)", NULL }, - { "Black", NULL }, - { "Black (blend)", NULL }, - { "25% Grey", NULL }, - { "25% Grey (blend)", NULL }, - { "50% Grey", NULL }, - { "50% Grey (blend)", NULL }, - { "75% Grey", NULL }, - { "75% Grey (blend)", NULL }, - { NULL, NULL}, - }, - "White" - }, - { - "snes9x_justifier1_crosshair", - "Justifier 1 İmleci", - "Ekrandaki imleç işaretinin boyutunu değiştirin.", - { - { "0", NULL }, - { "1", NULL }, - { "2", NULL }, - { "3", NULL }, - { "4", NULL }, - { "5", NULL }, - { "6", NULL }, - { "7", NULL }, - { "8", NULL }, - { "9", NULL }, - { "10", NULL }, - { "11", NULL }, - { "12", NULL }, - { "13", NULL }, - { "14", NULL }, - { "15", NULL }, - { "16", NULL }, - { NULL, NULL}, - }, - "4" - }, - { - "snes9x_justifier1_color", - "Justifier 1 Rengi", - "Ekrandaki imleç işaretinin rengini değiştirin.", - { - { "Blue", NULL }, - { "Blue (blend)", NULL }, - { "Violet", NULL }, - { "Violet (blend)", NULL }, - { "Pink", NULL }, - { "Pink (blend)", NULL }, - { "Purple", NULL }, - { "Purple (blend)", NULL }, - { "Black", NULL }, - { "Black (blend)", NULL }, - { "25% Grey", NULL }, - { "25% Grey (blend)", NULL }, - { "50% Grey", NULL }, - { "50% Grey (blend)", NULL }, - { "75% Grey", NULL }, - { "75% Grey (blend)", NULL }, - { "White", NULL }, - { "White (blend)", NULL }, - { "Red", NULL }, - { "Red (blend)", NULL }, - { "Orange", NULL }, - { "Orange (blend)", NULL }, - { "Yellow", NULL }, - { "Yellow (blend)", NULL }, - { "Green", NULL }, - { "Green (blend)", NULL }, - { "Cyan", NULL }, - { "Cyan (blend)", NULL }, - { "Sky", NULL }, - { "Sky (blend)", NULL }, - { NULL, NULL}, - }, - "Blue" - }, - { - "snes9x_justifier2_crosshair", - "Justifier 2 İmleci", - "Ekrandaki imleç işaretinin boyutunu değiştirin.", - { - { "0", NULL }, - { "1", NULL }, - { "2", NULL }, - { "3", NULL }, - { "4", NULL }, - { "5", NULL }, - { "6", NULL }, - { "7", NULL }, - { "8", NULL }, - { "9", NULL }, - { "10", NULL }, - { "11", NULL }, - { "12", NULL }, - { "13", NULL }, - { "14", NULL }, - { "15", NULL }, - { "16", NULL }, - { NULL, NULL}, - }, - "4" - }, - { - "snes9x_justifier2_color", - "Justifier 2 REngi", - "Ekrandaki imleç işaretinin rengini değiştirin.", - { - { "Pink", NULL }, - { "Pink (blend)", NULL }, - { "Purple", NULL }, - { "Purple (blend)", NULL }, - { "Black", NULL }, - { "Black (blend)", NULL }, - { "25% Grey", NULL }, - { "25% Grey (blend)", NULL }, - { "50% Grey", NULL }, - { "50% Grey (blend)", NULL }, - { "75% Grey", NULL }, - { "75% Grey (blend)", NULL }, - { "White", NULL }, - { "White (blend)", NULL }, - { "Red", NULL }, - { "Red (blend)", NULL }, - { "Orange", NULL }, - { "Orange (blend)", NULL }, - { "Yellow", NULL }, - { "Yellow (blend)", NULL }, - { "Green", NULL }, - { "Green (blend)", NULL }, - { "Cyan", NULL }, - { "Cyan (blend)", NULL }, - { "Sky", NULL }, - { "Sky (blend)", NULL }, - { "Blue", NULL }, - { "Blue (blend)", NULL }, - { "Violet", NULL }, - { "Violet (blend)", NULL }, - { NULL, NULL}, - }, - "Pink" - }, - { - "snes9x_rifle_crosshair", - "M.A.C.S. Tüfek ", - "Ekrandaki imleç işaretinin rengini değiştirin..", - { - { "0", NULL }, - { "1", NULL }, - { "2", NULL }, - { "3", NULL }, - { "4", NULL }, - { "5", NULL }, - { "6", NULL }, - { "7", NULL }, - { "8", NULL }, - { "9", NULL }, - { "10", NULL }, - { "11", NULL }, - { "12", NULL }, - { "13", NULL }, - { "14", NULL }, - { "15", NULL }, - { "16", NULL }, - { NULL, NULL}, - }, - "2" - }, - { - "snes9x_rifle_color", - "M.A.C.S. Tüfek Rengi", - "Ekrandaki imleç işaretinin rengini değiştirin.", - { - { "White", NULL }, - { "White (blend)", NULL }, - { "Red", NULL }, - { "Red (blend)", NULL }, - { "Orange", NULL }, - { "Orange (blend)", NULL }, - { "Yellow", NULL }, - { "Yellow (blend)", NULL }, - { "Green", NULL }, - { "Green (blend)", NULL }, - { "Cyan", NULL }, - { "Cyan (blend)", NULL }, - { "Sky", NULL }, - { "Sky (blend)", NULL }, - { "Blue", NULL }, - { "Blue (blend)", NULL }, - { "Violet", NULL }, - { "Violet (blend)", NULL }, - { "Pink", NULL }, - { "Pink (blend)", NULL }, - { "Purple", NULL }, - { "Purple (blend)", NULL }, - { "Black", NULL }, - { "Black (blend)", NULL }, - { "25% Grey", NULL }, - { "25% Grey (blend)", NULL }, - { "50% Grey", NULL }, - { "50% Grey (blend)", NULL }, - { "75% Grey", NULL }, - { "75% Grey (blend)", NULL }, - { NULL, NULL}, - }, - "White" - }, - { - "snes9x_show_advanced_av_settings", - "Gelişmiş Ses/Video Ayarlarını Göster", - "Düşük seviye video katmanı / GFX etkisi / ses kanalı parametrelerinin yapılandırılmasını etkinleştirir. NOT: Bu ayarın etkili olabilmesi için Hızlı Menü’nün açılması gerekir.", - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, + { NULL, NULL }, }, "disabled" }, - { - "snes9x_layer_1", - "1. Katmanı Göster", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_layer_2", - "2. Katmanı Göster", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_layer_3", - "3. Katmanı Göster", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_layer_4", - "4. Katmanı Göster", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_layer_5", - "Sprite Katmanını Göster", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_gfx_clip", - "Grafik Klibi Pencerelerini Etkinleştir", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_gfx_transp", - "Saydamlık Efektlerini Etkinleştir", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_sndchan_1", - "Ses Kanalı 1'i etkinleştir", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_sndchan_2", - "Ses Kanalı 2'yi etkinleştir", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_sndchan_3", - "Ses Kanalı 3'ü etkinleştir", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_sndchan_4", - "Ses Kanalı 4'ü etkinleştir", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_sndchan_5", - "Ses Kanalı 5'i etkinleştir", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_sndchan_6", - "Ses Kanalı 6'yı etkinleştir", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_sndchan_7", - "Ses Kanalı 7'yi etkinleştir", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, - { - "snes9x_sndchan_8", - "Ses Kanalı 8'i etkinleştir", - NULL, - { - { "enabled", NULL }, - { "disabled", NULL }, - { NULL, NULL}, - }, - "enabled" - }, { NULL, NULL, NULL, {{0}}, NULL }, }; @@ -770,6 +111,7 @@ struct retro_core_option_definition option_defs_tr[] = { ******************************** */ +#ifndef HAVE_NO_LANGEXTRA struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = { option_defs_us, /* RETRO_LANGUAGE_ENGLISH */ NULL, /* RETRO_LANGUAGE_JAPANESE */ @@ -789,8 +131,14 @@ struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = { NULL, /* RETRO_LANGUAGE_VIETNAMESE */ NULL, /* RETRO_LANGUAGE_ARABIC */ NULL, /* RETRO_LANGUAGE_GREEK */ - option_defs_tr, /* RETRO_LANGUAGE_TURKISH */ + NULL, /* RETRO_LANGUAGE_TURKISH */ + NULL, /* RETRO_LANGUAGE_SLOVAK */ + NULL, /* RETRO_LANGUAGE_PERSIAN */ + NULL, /* RETRO_LANGUAGE_HEBREW */ + NULL, /* RETRO_LANGUAGE_ASTURIAN */ + }; +#endif /* ******************************** @@ -799,7 +147,8 @@ struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = { */ /* Handles configuration/setting of core options. - * Should only be called inside retro_set_environment(). + * Should be called as early as possible - ideally inside + * retro_set_environment(), and no later than retro_load_game() * > We place the function body in the header to avoid the * necessity of adding more .c files (i.e. want this to * be as painless as possible for core devs) @@ -812,8 +161,9 @@ static INLINE void libretro_set_core_options(retro_environment_t environ_cb) if (!environ_cb) return; - if (environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version) && (version == 1)) + if (environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version) && (version >= 1)) { +#ifndef HAVE_NO_LANGEXTRA struct retro_core_options_intl core_options_intl; unsigned language = 0; @@ -825,27 +175,23 @@ static INLINE void libretro_set_core_options(retro_environment_t environ_cb) core_options_intl.local = option_defs_intl[language]; environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_intl); +#else + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS, &option_defs_us); +#endif } else { size_t i; - size_t option_index = 0; size_t num_options = 0; struct retro_variable *variables = NULL; char **values_buf = NULL; - /* Determine number of options - * > Note: We are going to skip a number of irrelevant - * core options when building the retro_variable array, - * but we'll allocate space for all of them. The difference - * in resource usage is negligible, and this allows us to - * keep the code 'cleaner' */ - while (true) + /* Determine number of options */ + for (;;) { - if (option_defs_us[num_options].key) - num_options++; - else + if (!option_defs_us[num_options].key) break; + num_options++; } /* Allocate arrays */ @@ -867,35 +213,27 @@ static INLINE void libretro_set_core_options(retro_environment_t environ_cb) values_buf[i] = NULL; - /* Skip options that are irrelevant when using the - * old style core options interface */ - if ((strcmp(key, "snes9x_show_lightgun_settings") == 0) || - (strcmp(key, "snes9x_show_advanced_av_settings") == 0)) - continue; - if (desc) { size_t num_values = 0; /* Determine number of values */ - while (true) + for (;;) { - if (values[num_values].value) - { - /* Check if this is the default value */ - if (default_value) - if (strcmp(values[num_values].value, default_value) == 0) - default_index = num_values; - - buf_len += strlen(values[num_values].value); - num_values++; - } - else + if (!values[num_values].value) break; + + /* Check if this is the default value */ + if (default_value) + if (strcmp(values[num_values].value, default_value) == 0) + default_index = num_values; + + buf_len += strlen(values[num_values].value); + num_values++; } /* Build values string */ - if (num_values > 1) + if (num_values > 0) { size_t j; @@ -924,11 +262,10 @@ static INLINE void libretro_set_core_options(retro_environment_t environ_cb) } } - variables[option_index].key = key; - variables[option_index].value = values_buf[i]; - option_index++; + variables[i].key = key; + variables[i].value = values_buf[i]; } - + /* Set variables */ environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables); diff --git a/libretro_core_options_intl.h b/libretro_core_options_intl.h new file mode 100644 index 0000000..abf5d9a --- /dev/null +++ b/libretro_core_options_intl.h @@ -0,0 +1,88 @@ +#ifndef LIBRETRO_CORE_OPTIONS_INTL_H__ +#define LIBRETRO_CORE_OPTIONS_INTL_H__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1500 && _MSC_VER < 1900) +/* https://support.microsoft.com/en-us/kb/980263 */ +#pragma execution_character_set("utf-8") +#pragma warning(disable:4566) +#endif + +#include <libretro.h> + +/* + ******************************** + * VERSION: 1.3 + ******************************** + * + * - 1.3: Move translations to libretro_core_options_intl.h + * - libretro_core_options_intl.h includes BOM and utf-8 + * fix for MSVC 2010-2013 + * - Added HAVE_NO_LANGEXTRA flag to disable translations + * on platforms/compilers without BOM support + * - 1.2: Use core options v1 interface when + * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1 + * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1) + * - 1.1: Support generation of core options v0 retro_core_option_value + * arrays containing options with a single value + * - 1.0: First commit +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + ******************************** + * Core Option Definitions + ******************************** +*/ + +/* RETRO_LANGUAGE_JAPANESE */ + +/* RETRO_LANGUAGE_FRENCH */ + +/* RETRO_LANGUAGE_SPANISH */ + +/* RETRO_LANGUAGE_GERMAN */ + +/* RETRO_LANGUAGE_ITALIAN */ + +/* RETRO_LANGUAGE_DUTCH */ + +/* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */ + +/* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */ + +/* RETRO_LANGUAGE_RUSSIAN */ + +/* RETRO_LANGUAGE_KOREAN */ + +/* RETRO_LANGUAGE_CHINESE_TRADITIONAL */ + +/* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */ + +/* RETRO_LANGUAGE_ESPERANTO */ + +/* RETRO_LANGUAGE_POLISH */ + +/* RETRO_LANGUAGE_VIETNAMESE */ + +/* RETRO_LANGUAGE_ARABIC */ + +/* RETRO_LANGUAGE_GREEK */ + +/* RETRO_LANGUAGE_TURKISH */ + +/* RETRO_LANGUAGE_SLOVAK */ + +/* RETRO_LANGUAGE_PERSIAN */ + +/* RETRO_LANGUAGE_HEBREW */ + +/* RETRO_LANGUAGE_ASTURIAN */ + +#ifdef __cplusplus +} +#endif + +#endif |