From 6b983991fed8243f7e82241f7be8b126026b3cc1 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Tue, 17 Aug 2021 17:33:02 +0100 Subject: [PATCH] Add support for RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK environment callback --- .../libretro-common/include/libretro.h | 49 ++++--- libgambatte/libretro/libretro.cpp | 120 +++++++++++------- libgambatte/libretro/libretro_core_options.h | 89 +++++-------- 3 files changed, 135 insertions(+), 123 deletions(-) diff --git a/libgambatte/libretro-common/include/libretro.h b/libgambatte/libretro-common/include/libretro.h index 2c30120..d9e28bf 100644 --- a/libgambatte/libretro-common/include/libretro.h +++ b/libgambatte/libretro-common/include/libretro.h @@ -1712,6 +1712,16 @@ enum retro_mod * the retro_core_options_v2_intl::local struct will be ignored. */ +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK 69 + /* const struct retro_core_options_update_display_callback * -- + * Allows a frontend to signal that a core must update + * the visibility of any dynamically hidden core options, + * and enables the frontend to detect visibility changes. + * Used by the frontend to update the menu display status + * of core options without requiring a call of retro_run(). + * Must be called in retro_set_environment(). + */ + /* VFS functionality */ /* File paths: @@ -3519,26 +3529,6 @@ struct retro_core_option_v2_definition * in the retro_core_option_value array, otherwise will be * ignored */ const char *default_value; - - /* Specify the type this option represents so the frontend - * can present the user an alternative input method besides - * a limited list of possible values. - * > If set to "int", all values need to be integers - * and a frontend with support for numerical input will - * allow input of any number betwen the lowest and - * highest defined value. - * > If set to "float", all values need to be numbers - * and a frontend with support for numerical input will - * allow input of any number betwen the lowest and - * highest defined value. - * > If set to "bool", there should be only two values - * "true" and "false" (label can be anything) - * The frontend can choose to show a checkbox for it. - * > If NULL or set to "enum", the frontend will show - * the list of values and input will be limited to them. - * Future versions of the specs could allow this for more - * types or to be "TYPE:MORE:OPTIONS" */ - const char *type_info; }; struct retro_core_options_v2 @@ -3571,6 +3561,25 @@ struct retro_core_options_v2_intl struct retro_core_options_v2 *local; }; +/* Used by the frontend to monitor changes in core option + * visibility. May be called each time any core option + * value is set via the frontend. + * - On each invocation, the core must update the visibility + * of any dynamically hidden options using the + * RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY environment + * callback. + * - On the first invocation, returns 'true' if the visibility + * of any core option has changed since the last call of + * retro_load_game() or retro_load_game_special(). + * - On each subsequent invocation, returns 'true' if the + * visibility of any core option has changed since the last + * time the function was called. */ +typedef bool (RETRO_CALLCONV *retro_core_options_update_display_callback_t)(void); +struct retro_core_options_update_display_callback +{ + retro_core_options_update_display_callback_t callback; +}; + struct retro_game_info { const char *path; /* Path to game, UTF-8 encoded. diff --git a/libgambatte/libretro/libretro.cpp b/libgambatte/libretro/libretro.cpp index 81fe6b4..61a2949 100644 --- a/libgambatte/libretro/libretro.cpp +++ b/libgambatte/libretro/libretro.cpp @@ -649,6 +649,65 @@ static void deactivate_rumble(void) /* Rumble support END */ /**********************/ +#ifdef HAVE_NETWORK +/* Core options 'update display' callback */ +static bool update_option_visibility(void) +{ + struct retro_variable var = {0}; + bool updated = false; + unsigned i; + + /* If frontend supports core option categories, + * then gambatte_show_gb_link_settings is ignored + * and no options should be hidden */ + if (libretro_supports_option_categories) + return false; + + var.key = "gambatte_show_gb_link_settings"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + bool show_gb_link_settings_prev = show_gb_link_settings; + + show_gb_link_settings = true; + if (strcmp(var.value, "disabled") == 0) + show_gb_link_settings = false; + + if (show_gb_link_settings != show_gb_link_settings_prev) + { + struct retro_core_option_display option_display; + + option_display.visible = show_gb_link_settings; + + option_display.key = "gambatte_gb_link_mode"; + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display); + + option_display.key = "gambatte_gb_link_network_port"; + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display); + + for (i = 0; i < 12; i++) + { + char key[64] = {0}; + + /* Should be using std::to_string() here, but some + * compilers don't support it... */ + sprintf(key, "%s%u", + "gambatte_gb_link_network_server_ip_", i + 1); + + option_display.key = key; + + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display); + } + + updated = true; + } + } + + return updated; +} +#endif + /* Fast forward override */ void set_fastforward_override(bool fastforward) { @@ -1028,6 +1087,7 @@ void retro_set_environment(retro_environment_t cb) libretro_set_core_options(environ_cb, &libretro_supports_option_categories); +#ifdef HAVE_NETWORK /* If frontend supports core option categories, * gambatte_show_gb_link_settings is unused and * should be hidden */ @@ -1041,6 +1101,20 @@ void retro_set_environment(retro_environment_t cb) environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display); } + /* If frontend does not support core option + * categories, core options may be shown/hidden + * at runtime. In this case, register 'update + * display' callback, so frontend can update + * core options menu without calling retro_run() */ + else + { + struct retro_core_options_update_display_callback update_display_cb; + update_display_cb.callback = update_option_visibility; + + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK, + &update_display_cb); + } +#endif vfs_iface_info.required_interface_version = 1; vfs_iface_info.iface = NULL; @@ -1503,50 +1577,8 @@ static void check_variables(void) break; } - /* Show/hide core options - * > If frontend supports core option categories, - * then gambatte_show_gb_link_settings is ignored - * and no options should be hidden */ - - var.key = "gambatte_show_gb_link_settings"; - var.value = NULL; - - if (!libretro_supports_option_categories && - environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - bool show_gb_link_settings_prev = show_gb_link_settings; - - show_gb_link_settings = true; - if (strcmp(var.value, "disabled") == 0) - show_gb_link_settings = false; - - if (show_gb_link_settings != show_gb_link_settings_prev) - { - struct retro_core_option_display option_display; - - option_display.visible = show_gb_link_settings; - - option_display.key = "gambatte_gb_link_mode"; - environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display); - - option_display.key = "gambatte_gb_link_network_port"; - environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display); - - for (i = 0; i < 12; i++) - { - char key[64] = {0}; - - /* Should be using std::to_string() here, but some - * compilers don't support it... */ - sprintf(key, "%s%u", - "gambatte_gb_link_network_server_ip_", i + 1); - - option_display.key = key; - - environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display); - } - } - } + /* Show/hide core options */ + update_option_visibility(); #endif diff --git a/libgambatte/libretro/libretro_core_options.h b/libgambatte/libretro/libretro_core_options.h index 498fbcb..ca5d896 100644 --- a/libgambatte/libretro/libretro_core_options.h +++ b/libgambatte/libretro/libretro_core_options.h @@ -75,8 +75,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "custom", "Custom" }, { NULL, NULL }, }, - "disabled", - NULL + "disabled" }, { "gambatte_gb_internal_palette", @@ -141,8 +140,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "TWB64 - Pack 2", NULL }, { NULL, NULL }, }, - "GB - DMG", - NULL + "GB - DMG" }, { "gambatte_gb_palette_twb64_1", @@ -254,8 +252,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "TWB64 100 - Stone Orange", NULL }, { NULL, NULL }, }, - "TWB64 001 - Aqours Blue", - NULL + "TWB64 001 - Aqours Blue" }, { "gambatte_gb_palette_twb64_2", @@ -367,8 +364,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "TWB64 200 - TOKYO SKYTREE CLOUDY BLUE", NULL }, { NULL, NULL }, }, - "TWB64 101 - 765PRO Pink", - NULL + "TWB64 101 - 765PRO Pink" }, { "gambatte_gbc_color_correction", @@ -383,8 +379,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "disabled", NULL }, { NULL, NULL }, }, - "GBC only", - NULL + "GBC only" }, { "gambatte_gbc_color_correction_mode", @@ -398,8 +393,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "fast", "Fast" }, { NULL, NULL }, }, - "accurate", - NULL + "accurate" }, { "gambatte_gbc_frontlight_position", @@ -414,8 +408,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "below screen", "Below Screen" }, { NULL, NULL }, }, - "central", - NULL + "central" }, { "gambatte_dark_filter_level", @@ -438,8 +431,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "50", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, { "gambatte_gb_hwmode", @@ -455,8 +447,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "GBA", NULL }, { NULL, NULL }, }, - "Auto", - NULL + "Auto" }, { "gambatte_gb_bootloader", @@ -470,8 +461,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "disabled", NULL }, { NULL, NULL }, }, - "enabled", - "bool" + "enabled" }, { "gambatte_mix_frames", @@ -487,8 +477,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "lcd_ghosting_fast", "LCD Ghosting (Fast)" }, { NULL, NULL }, }, - "disabled", - NULL + "disabled" }, { "gambatte_up_down_allowed", @@ -502,8 +491,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "enabled", NULL }, { NULL, NULL }, }, - "disabled", - "bool" + "disabled" }, { "gambatte_turbo_period", @@ -632,8 +620,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "120", NULL }, { NULL, NULL }, }, - "4", - "int" + "4" }, { "gambatte_rumble_level", @@ -656,15 +643,14 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "10", NULL }, { NULL, NULL }, }, - "10", - "int" + "10" }, #ifdef HAVE_NETWORK { "gambatte_show_gb_link_settings", "Show Game Boy Link Settings", NULL, - "Enable configuration of networked 'Game Boy Link' (multiplayer) options. NOTE: Quick Menu must be toggled for this setting to take effect.", + "Enable configuration of networked 'Game Boy Link' (multiplayer) options. NOTE: Quick Menu may need to be toggled for this setting to take effect.", NULL, NULL, { @@ -672,8 +658,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "disabled", NULL }, { NULL, NULL }, }, - "disabled", - "bool" + "disabled" }, { "gambatte_gb_link_mode", @@ -688,8 +673,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "Network Client", NULL }, { NULL, NULL }, }, - "Not Connected", - NULL + "Not Connected" }, { "gambatte_gb_link_network_port", @@ -722,8 +706,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "56420", NULL }, { NULL, NULL }, }, - "56400", - "int" + "56400" }, { "gambatte_gb_link_network_server_ip_1", @@ -745,8 +728,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "9", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, { "gambatte_gb_link_network_server_ip_2", @@ -768,8 +750,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "9", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, { "gambatte_gb_link_network_server_ip_3", @@ -791,8 +772,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "9", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, { "gambatte_gb_link_network_server_ip_4", @@ -814,8 +794,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "9", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, { "gambatte_gb_link_network_server_ip_5", @@ -837,8 +816,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "9", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, { "gambatte_gb_link_network_server_ip_6", @@ -860,8 +838,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "9", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, { "gambatte_gb_link_network_server_ip_7", @@ -883,8 +860,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "9", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, { "gambatte_gb_link_network_server_ip_8", @@ -906,8 +882,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "9", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, { "gambatte_gb_link_network_server_ip_9", @@ -929,8 +904,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "9", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, { "gambatte_gb_link_network_server_ip_10", @@ -952,8 +926,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "9", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, { "gambatte_gb_link_network_server_ip_11", @@ -975,8 +948,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "9", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, { "gambatte_gb_link_network_server_ip_12", @@ -998,8 +970,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { { "9", NULL }, { NULL, NULL }, }, - "0", - "int" + "0" }, #endif { NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL },