mirror of
https://github.com/libretro/RetroArch
synced 2025-03-03 13:14:04 +00:00
Merge pull request #10716 from jdgleaver/core-updater-improvements
Core updater improvements
This commit is contained in:
commit
2b10350edc
@ -957,10 +957,13 @@ static const bool stdin_cmd_enable = false;
|
||||
|
||||
static const uint16_t network_remote_base_port = 55400;
|
||||
|
||||
#define DEFAULT_NETWORK_BUILDBOT_AUTO_EXTRACT_ARCHIVE true
|
||||
#define DEFAULT_NETWORK_BUILDBOT_SHOW_EXPERIMENTAL_CORES false
|
||||
|
||||
#if defined(ANDROID) || defined(IOS)
|
||||
static const bool network_on_demand_thumbnails = true;
|
||||
#define DEFAULT_NETWORK_ON_DEMAND_THUMBNAILS true
|
||||
#else
|
||||
static const bool network_on_demand_thumbnails = false;
|
||||
#define DEFAULT_NETWORK_ON_DEMAND_THUMBNAILS false
|
||||
#endif
|
||||
|
||||
/* Number of entries that will be kept in content history playlist file. */
|
||||
|
@ -1369,7 +1369,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
|
||||
SETTING_BOOL("netplay_request_device_p14", &settings->bools.netplay_request_devices[13], true, false, false);
|
||||
SETTING_BOOL("netplay_request_device_p15", &settings->bools.netplay_request_devices[14], true, false, false);
|
||||
SETTING_BOOL("netplay_request_device_p16", &settings->bools.netplay_request_devices[15], true, false, false);
|
||||
SETTING_BOOL("network_on_demand_thumbnails", &settings->bools.network_on_demand_thumbnails, true, network_on_demand_thumbnails, false);
|
||||
SETTING_BOOL("network_on_demand_thumbnails", &settings->bools.network_on_demand_thumbnails, true, DEFAULT_NETWORK_ON_DEMAND_THUMBNAILS, false);
|
||||
#endif
|
||||
SETTING_BOOL("input_descriptor_label_show", &settings->bools.input_descriptor_label_show, true, input_descriptor_label_show, false);
|
||||
SETTING_BOOL("input_descriptor_hide_unbound", &settings->bools.input_descriptor_hide_unbound, true, input_descriptor_hide_unbound, false);
|
||||
@ -1435,7 +1435,8 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
|
||||
SETTING_BOOL("audio_fastforward_mute", &settings->bools.audio_fastforward_mute, true, DEFAULT_AUDIO_FASTFORWARD_MUTE, false);
|
||||
SETTING_BOOL("location_allow", &settings->bools.location_allow, true, false, false);
|
||||
SETTING_BOOL("video_font_enable", &settings->bools.video_font_enable, true, DEFAULT_FONT_ENABLE, false);
|
||||
SETTING_BOOL("core_updater_auto_extract_archive", &settings->bools.network_buildbot_auto_extract_archive, true, true, false);
|
||||
SETTING_BOOL("core_updater_auto_extract_archive", &settings->bools.network_buildbot_auto_extract_archive, true, DEFAULT_NETWORK_BUILDBOT_AUTO_EXTRACT_ARCHIVE, false);
|
||||
SETTING_BOOL("core_updater_show_experimental_cores", &settings->bools.network_buildbot_show_experimental_cores, true, DEFAULT_NETWORK_BUILDBOT_SHOW_EXPERIMENTAL_CORES, false);
|
||||
SETTING_BOOL("camera_allow", &settings->bools.camera_allow, true, false, false);
|
||||
SETTING_BOOL("discord_allow", &settings->bools.discord_enable, true, false, false);
|
||||
#if defined(VITA)
|
||||
|
@ -285,6 +285,7 @@ typedef struct settings
|
||||
|
||||
/* Network */
|
||||
bool network_buildbot_auto_extract_archive;
|
||||
bool network_buildbot_show_experimental_cores;
|
||||
bool network_on_demand_thumbnails;
|
||||
|
||||
/* UI */
|
||||
|
107
core_info.c
107
core_info.c
@ -189,6 +189,7 @@ static void core_info_list_free(core_info_list_t *core_info_list)
|
||||
free(info->databases);
|
||||
free(info->notes);
|
||||
free(info->required_hw_api);
|
||||
free(info->description);
|
||||
string_list_free(info->supported_extensions_list);
|
||||
string_list_free(info->authors_list);
|
||||
string_list_free(info->note_list);
|
||||
@ -471,6 +472,14 @@ static core_info_list_t *core_info_list_new(const char *path,
|
||||
tmp = NULL;
|
||||
}
|
||||
|
||||
if (config_get_string(conf, "description", &tmp))
|
||||
{
|
||||
if (!string_is_empty(tmp))
|
||||
core_info[i].description = strdup(tmp);
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
|
||||
if (tmp)
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
@ -484,6 +493,10 @@ static core_info_list_t *core_info_list_new(const char *path,
|
||||
if (config_get_bool(conf, "database_match_archive_member",
|
||||
&tmp_bool))
|
||||
core_info[i].database_match_archive_member = tmp_bool;
|
||||
|
||||
if (config_get_bool(conf, "is_experimental",
|
||||
&tmp_bool))
|
||||
core_info[i].is_experimental = tmp_bool;
|
||||
}
|
||||
|
||||
core_info[i].config_data = conf;
|
||||
@ -1003,6 +1016,100 @@ bool core_info_get_display_name(const char *path, char *s, size_t len)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns core_info parameters required for
|
||||
* core updater tasks, read from specified file.
|
||||
* Returned core_updater_info_t object must be
|
||||
* freed using core_info_free_core_updater_info().
|
||||
* Returns NULL if 'path' is invalid. */
|
||||
core_updater_info_t *core_info_get_core_updater_info(const char *path)
|
||||
{
|
||||
char *tmp_str = NULL;
|
||||
bool tmp_bool = false;
|
||||
core_updater_info_t *info = NULL;
|
||||
config_file_t *conf = NULL;
|
||||
|
||||
if (string_is_empty(path))
|
||||
return NULL;
|
||||
|
||||
/* Read config file */
|
||||
conf = config_file_new_from_path_to_string(path);
|
||||
|
||||
if (!conf)
|
||||
return NULL;
|
||||
|
||||
/* Create info struct */
|
||||
info = (core_updater_info_t*)calloc(1, sizeof(*info));
|
||||
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
/* Fetch required parameters */
|
||||
|
||||
/* > is_experimental */
|
||||
info->is_experimental = false;
|
||||
if (config_get_bool(conf, "is_experimental", &tmp_bool))
|
||||
info->is_experimental = tmp_bool;
|
||||
|
||||
/* > display_name */
|
||||
info->display_name = NULL;
|
||||
if (config_get_string(conf, "display_name", &tmp_str))
|
||||
{
|
||||
if (!string_is_empty(tmp_str))
|
||||
info->display_name = tmp_str;
|
||||
else
|
||||
free(tmp_str);
|
||||
|
||||
tmp_str = NULL;
|
||||
}
|
||||
|
||||
/* > description */
|
||||
info->description = NULL;
|
||||
if (config_get_string(conf, "description", &tmp_str))
|
||||
{
|
||||
if (!string_is_empty(tmp_str))
|
||||
info->description = tmp_str;
|
||||
else
|
||||
free(tmp_str);
|
||||
|
||||
tmp_str = NULL;
|
||||
}
|
||||
|
||||
/* > licenses */
|
||||
info->licenses = NULL;
|
||||
if (config_get_string(conf, "license", &tmp_str))
|
||||
{
|
||||
if (!string_is_empty(tmp_str))
|
||||
info->licenses = tmp_str;
|
||||
else
|
||||
free(tmp_str);
|
||||
|
||||
tmp_str = NULL;
|
||||
}
|
||||
|
||||
/* Clean up */
|
||||
config_file_free(conf);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void core_info_free_core_updater_info(core_updater_info_t *info)
|
||||
{
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
if (info->display_name)
|
||||
free(info->display_name);
|
||||
|
||||
if (info->description)
|
||||
free(info->description);
|
||||
|
||||
if (info->licenses)
|
||||
free(info->licenses);
|
||||
|
||||
free(info);
|
||||
info = NULL;
|
||||
}
|
||||
|
||||
static int core_info_qsort_func_path(const core_info_t *a,
|
||||
const core_info_t *b)
|
||||
{
|
||||
|
20
core_info.h
20
core_info.h
@ -39,6 +39,7 @@ typedef struct
|
||||
{
|
||||
bool supports_no_game;
|
||||
bool database_match_archive_member;
|
||||
bool is_experimental;
|
||||
size_t firmware_count;
|
||||
char *path;
|
||||
void *config_data;
|
||||
@ -56,6 +57,7 @@ typedef struct
|
||||
char *databases;
|
||||
char *notes;
|
||||
char *required_hw_api;
|
||||
char *description;
|
||||
struct string_list *categories_list;
|
||||
struct string_list *databases_list;
|
||||
struct string_list *note_list;
|
||||
@ -68,6 +70,16 @@ typedef struct
|
||||
void *userdata;
|
||||
} core_info_t;
|
||||
|
||||
/* A subset of core_info parameters required for
|
||||
* core updater tasks */
|
||||
typedef struct
|
||||
{
|
||||
bool is_experimental;
|
||||
char *display_name;
|
||||
char *description;
|
||||
char *licenses;
|
||||
} core_updater_info_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
core_info_t *list;
|
||||
@ -109,6 +121,14 @@ bool core_info_list_get_display_name(core_info_list_t *list,
|
||||
|
||||
bool core_info_get_display_name(const char *path, char *s, size_t len);
|
||||
|
||||
/* Returns core_info parameters required for
|
||||
* core updater tasks, read from specified file.
|
||||
* Returned core_updater_info_t object must be
|
||||
* freed using core_info_free_core_updater_info().
|
||||
* Returns NULL if 'path' is invalid. */
|
||||
core_updater_info_t *core_info_get_core_updater_info(const char *path);
|
||||
void core_info_free_core_updater_info(core_updater_info_t *info);
|
||||
|
||||
void core_info_get_name(const char *path, char *s, size_t len,
|
||||
const char *path_info, const char *dir_cores,
|
||||
const char *exts, bool show_hidden_files,
|
||||
|
@ -82,6 +82,18 @@ static void core_updater_list_free_entry(core_updater_list_entry_t *entry)
|
||||
free(entry->display_name);
|
||||
entry->display_name = NULL;
|
||||
}
|
||||
|
||||
if (entry->description)
|
||||
{
|
||||
free(entry->description);
|
||||
entry->description = NULL;
|
||||
}
|
||||
|
||||
if (entry->licenses_list)
|
||||
{
|
||||
string_list_free(entry->licenses_list);
|
||||
entry->licenses_list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Creates a new, empty core updater list.
|
||||
@ -410,13 +422,11 @@ static bool core_updater_list_set_paths(
|
||||
char remote_core_path[PATH_MAX_LENGTH];
|
||||
char local_core_path[PATH_MAX_LENGTH];
|
||||
char local_info_path[PATH_MAX_LENGTH];
|
||||
char display_name[255];
|
||||
bool is_archive;
|
||||
|
||||
remote_core_path[0] = '\0';
|
||||
local_core_path[0] = '\0';
|
||||
local_info_path[0] = '\0';
|
||||
display_name[0] = '\0';
|
||||
|
||||
if (!entry || string_is_empty(filename_str))
|
||||
return false;
|
||||
@ -518,29 +528,94 @@ static bool core_updater_list_set_paths(
|
||||
|
||||
entry->local_info_path = strdup(local_info_path);
|
||||
|
||||
/* display_name
|
||||
* > Note: It's a bit rubbish that we have to
|
||||
* read the actual core info files here...
|
||||
* Would be better to cache this globally
|
||||
* (at present, we only cache info for
|
||||
* *installed* cores...) */
|
||||
if (path_is_valid(local_info_path))
|
||||
if (!core_info_get_display_name(
|
||||
local_info_path, display_name, sizeof(display_name)))
|
||||
display_name[0] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
/* > If info file does not exist, just use
|
||||
* core filename */
|
||||
if (string_is_empty(display_name))
|
||||
strlcpy(display_name, filename_str, sizeof(display_name));
|
||||
/* Reads info file associated with core and
|
||||
* adds relevant information to updater list
|
||||
* entry */
|
||||
static bool core_updater_list_set_core_info(
|
||||
core_updater_list_entry_t *entry,
|
||||
const char *local_info_path,
|
||||
const char *filename_str)
|
||||
{
|
||||
core_updater_info_t *core_info = NULL;
|
||||
|
||||
if (!entry ||
|
||||
string_is_empty(local_info_path) ||
|
||||
string_is_empty(filename_str))
|
||||
return false;
|
||||
|
||||
/* Clear any existing core info */
|
||||
if (entry->display_name)
|
||||
{
|
||||
free(entry->display_name);
|
||||
entry->display_name = NULL;
|
||||
}
|
||||
|
||||
entry->display_name = strdup(display_name);
|
||||
if (entry->description)
|
||||
{
|
||||
free(entry->description);
|
||||
entry->description = NULL;
|
||||
}
|
||||
|
||||
if (entry->licenses_list)
|
||||
{
|
||||
/* Note: We can safely leave this as NULL if
|
||||
* the core info file is invalid */
|
||||
string_list_free(entry->licenses_list);
|
||||
entry->licenses_list = NULL;
|
||||
}
|
||||
|
||||
entry->is_experimental = false;
|
||||
|
||||
/* Read core info file
|
||||
* > Note: It's a bit rubbish that we have to
|
||||
* read the actual core info files here...
|
||||
* Would be better to cache this globally
|
||||
* (at present, we only cache info for
|
||||
* *installed* cores...) */
|
||||
core_info = core_info_get_core_updater_info(local_info_path);
|
||||
|
||||
if (core_info)
|
||||
{
|
||||
/* display_name + is_experimental */
|
||||
if (!string_is_empty(core_info->display_name))
|
||||
{
|
||||
entry->display_name = strdup(core_info->display_name);
|
||||
entry->is_experimental = core_info->is_experimental;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If display name is blank, use core filename and
|
||||
* assume core is experimental (i.e. all 'fit for consumption'
|
||||
* cores must have a valid/complete core info file) */
|
||||
entry->display_name = strdup(filename_str);
|
||||
entry->is_experimental = true;
|
||||
}
|
||||
|
||||
/* description */
|
||||
if (!string_is_empty(core_info->description))
|
||||
entry->description = strdup(core_info->description);
|
||||
else
|
||||
entry->description = strdup("");
|
||||
|
||||
/* licenses_list */
|
||||
if (!string_is_empty(core_info->licenses))
|
||||
entry->licenses_list = string_split(core_info->licenses, "|");
|
||||
|
||||
/* Clean up */
|
||||
core_info_free_core_updater_info(core_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If info file is missing, use core filename and
|
||||
* assume core is experimental (i.e. all 'fit for consumption'
|
||||
* cores must have a valid/complete core info file) */
|
||||
entry->display_name = strdup(filename_str);
|
||||
entry->is_experimental = true;
|
||||
entry->description = strdup("");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -576,10 +651,15 @@ static bool core_updater_list_push_entry(
|
||||
list_entry->remote_core_path = entry->remote_core_path;
|
||||
list_entry->local_core_path = entry->local_core_path;
|
||||
list_entry->local_info_path = entry->local_info_path;
|
||||
|
||||
/* Assign core info */
|
||||
list_entry->display_name = entry->display_name;
|
||||
list_entry->description = entry->description;
|
||||
list_entry->licenses_list = entry->licenses_list;
|
||||
list_entry->is_experimental = entry->is_experimental;
|
||||
|
||||
/* Copy crc */
|
||||
list_entry->crc = entry->crc;
|
||||
list_entry->crc = entry->crc;
|
||||
|
||||
/* Copy date */
|
||||
memcpy(&list_entry->date, &entry->date, sizeof(core_updater_list_date_t));
|
||||
@ -644,6 +724,12 @@ static void core_updater_list_add_entry(
|
||||
filename_str))
|
||||
goto error;
|
||||
|
||||
if (!core_updater_list_set_core_info(
|
||||
&entry,
|
||||
entry.local_info_path,
|
||||
filename_str))
|
||||
goto error;
|
||||
|
||||
/* Add entry to list */
|
||||
if (!core_updater_list_push_entry(core_list, &entry))
|
||||
goto error;
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include <retro_common_api.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include <lists/string_list.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
@ -52,6 +54,9 @@ typedef struct
|
||||
char *local_core_path;
|
||||
char *local_info_path;
|
||||
char *display_name;
|
||||
char *description;
|
||||
struct string_list *licenses_list;
|
||||
bool is_experimental;
|
||||
uint32_t crc;
|
||||
core_updater_list_date_t date;
|
||||
} core_updater_list_entry_t;
|
||||
|
@ -492,6 +492,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE,
|
||||
"core_updater_auto_extract_archive"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_CORE_UPDATER_SHOW_EXPERIMENTAL_CORES,
|
||||
"core_updater_show_experimental_cores"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL,
|
||||
"core_updater_buildbot_url"
|
||||
|
@ -4373,6 +4373,14 @@ MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE,
|
||||
"After downloading, automatically extract files contained in the downloaded archives."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SHOW_EXPERIMENTAL_CORES,
|
||||
"Show Experimental Cores"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_CORE_UPDATER_SHOW_EXPERIMENTAL_CORES,
|
||||
"Include 'experimental' cores in the Core Updater download list. These are typically for development/testing purposes only, and are not recommended for general use."
|
||||
)
|
||||
|
||||
/* Settings > Playlists */
|
||||
|
||||
|
@ -60,35 +60,31 @@
|
||||
|
||||
static int menu_action_sublabel_file_browser_core(file_list_t *list, unsigned type, unsigned i, const char *label, const char *path, char *s, size_t len)
|
||||
{
|
||||
core_info_list_t *core_list = NULL;
|
||||
core_info_ctx_find_t core_info;
|
||||
|
||||
core_info_get_list(&core_list);
|
||||
/* Set sublabel prefix */
|
||||
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES), len);
|
||||
strlcat(s, ": ", len);
|
||||
|
||||
strlcpy(s, "License: ", len);
|
||||
/* Search for specified core */
|
||||
core_info.inf = NULL;
|
||||
core_info.path = path;
|
||||
|
||||
if (core_list)
|
||||
if (core_info_find(&core_info, path) &&
|
||||
core_info.inf->licenses_list)
|
||||
{
|
||||
unsigned j;
|
||||
for (j = 0; j < core_list->count; j++)
|
||||
{
|
||||
if (string_is_equal(path_basename(core_list->list[j].path),
|
||||
path))
|
||||
{
|
||||
if (core_list->list[j].licenses_list)
|
||||
{
|
||||
char tmp[PATH_MAX_LENGTH];
|
||||
tmp[0] = '\0';
|
||||
char tmp[MENU_SUBLABEL_MAX_LENGTH];
|
||||
tmp[0] = '\0';
|
||||
|
||||
string_list_join_concat(tmp, sizeof(tmp),
|
||||
core_list->list[j].licenses_list, ", ");
|
||||
strlcat(s, tmp, len);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Add license text */
|
||||
string_list_join_concat(tmp, sizeof(tmp),
|
||||
core_info.inf->licenses_list, ", ");
|
||||
strlcat(s, tmp, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
strlcat(s, "N/A", len);
|
||||
/* No license found - set to N/A */
|
||||
strlcat(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE), len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -473,6 +469,7 @@ default_sublabel_macro(action_bind_sublabel_input_overlay_show_physical_inputs,
|
||||
default_sublabel_macro(action_bind_sublabel_input_overlay_show_physical_inputs_port, MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT)
|
||||
default_sublabel_macro(action_bind_sublabel_core_updater_buildbot_assets_url, MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL)
|
||||
default_sublabel_macro(action_bind_sublabel_core_updater_auto_extract_archive, MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE)
|
||||
default_sublabel_macro(action_bind_sublabel_core_updater_show_experimental_cores, MENU_ENUM_SUBLABEL_CORE_UPDATER_SHOW_EXPERIMENTAL_CORES)
|
||||
default_sublabel_macro(action_bind_sublabel_netplay_refresh_rooms, MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS)
|
||||
default_sublabel_macro(action_bind_sublabel_rename_entry, MENU_ENUM_SUBLABEL_RENAME_ENTRY)
|
||||
default_sublabel_macro(action_bind_sublabel_delete_entry, MENU_ENUM_SUBLABEL_DELETE_ENTRY)
|
||||
@ -1208,6 +1205,39 @@ static int action_bind_sublabel_core_option(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_bind_sublabel_core_updater_entry(
|
||||
file_list_t *list,
|
||||
unsigned type, unsigned i,
|
||||
const char *label, const char *path,
|
||||
char *s, size_t len)
|
||||
{
|
||||
core_updater_list_t *core_list = core_updater_list_get_cached();
|
||||
const core_updater_list_entry_t *entry = NULL;
|
||||
|
||||
/* Set sublabel prefix */
|
||||
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES), len);
|
||||
strlcat(s, ": ", len);
|
||||
|
||||
/* Search for specified core */
|
||||
if (core_list &&
|
||||
core_updater_list_get_filename(core_list, path, &entry) &&
|
||||
entry->licenses_list)
|
||||
{
|
||||
char tmp[MENU_SUBLABEL_MAX_LENGTH];
|
||||
tmp[0] = '\0';
|
||||
|
||||
/* Add license text */
|
||||
string_list_join_concat(tmp, sizeof(tmp),
|
||||
entry->licenses_list, ", ");
|
||||
strlcat(s, tmp, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* No license found - set to N/A */
|
||||
strlcat(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE), len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int action_bind_sublabel_generic(
|
||||
file_list_t *list,
|
||||
unsigned type, unsigned i,
|
||||
@ -1307,6 +1337,12 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (type == FILE_TYPE_DOWNLOAD_CORE)
|
||||
{
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_updater_entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cbs->enum_idx != MSG_UNKNOWN)
|
||||
{
|
||||
switch (cbs->enum_idx)
|
||||
@ -2102,6 +2138,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_updater_auto_extract_archive);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_CORE_UPDATER_SHOW_EXPERIMENTAL_CORES:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_updater_show_experimental_cores);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_updater_buildbot_url);
|
||||
break;
|
||||
|
@ -1425,6 +1425,7 @@ typedef struct materialui_handle
|
||||
bool is_playlist;
|
||||
bool is_file_list;
|
||||
bool is_dropdown_list;
|
||||
bool is_core_updater_list;
|
||||
bool last_show_nav_bar;
|
||||
bool last_auto_rotate_nav_bar;
|
||||
bool menu_stack_flushed;
|
||||
@ -2149,16 +2150,32 @@ static void materialui_render_messagebox(materialui_handle_t *mui,
|
||||
unsigned i;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int usable_width = 0;
|
||||
int longest_width = 0;
|
||||
size_t longest_len = 0;
|
||||
struct string_list *list = NULL;
|
||||
char wrapped_message[MENU_SUBLABEL_MAX_LENGTH];
|
||||
|
||||
wrapped_message[0] = '\0';
|
||||
|
||||
/* Sanity check */
|
||||
if (!mui || !mui->font_data.list.font)
|
||||
if (string_is_empty(message) ||
|
||||
!mui ||
|
||||
!mui->font_data.list.font)
|
||||
goto end;
|
||||
|
||||
usable_width = (int)video_width - (mui->margin * 4.0);
|
||||
|
||||
if (usable_width < 1)
|
||||
goto end;
|
||||
|
||||
/* Split message into lines */
|
||||
list = string_split(message, "\n");
|
||||
word_wrap(
|
||||
wrapped_message, message,
|
||||
usable_width / (int)mui->font_data.list.glyph_width,
|
||||
true, 0);
|
||||
|
||||
list = string_split(wrapped_message, "\n");
|
||||
|
||||
if (!list || list->elems == 0)
|
||||
goto end;
|
||||
@ -2177,14 +2194,11 @@ static void materialui_render_messagebox(materialui_handle_t *mui,
|
||||
|
||||
if (!string_is_empty(line))
|
||||
{
|
||||
size_t len = utf8len(line);
|
||||
int width = font_driver_get_message_width(
|
||||
mui->font_data.list.font, line, (unsigned)strlen(line), 1);
|
||||
|
||||
if (len > longest_len)
|
||||
{
|
||||
longest_len = len;
|
||||
longest_width = font_driver_get_message_width(
|
||||
mui->font_data.list.font, line, (unsigned)strlen(line), 1);
|
||||
}
|
||||
longest_width = (width > longest_width) ?
|
||||
width : longest_width;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2321,7 +2335,7 @@ static unsigned materialui_count_sublabel_lines(
|
||||
word_wrap(
|
||||
wrapped_sublabel_str, sublabel_str,
|
||||
sublabel_width_max / (int)mui->font_data.hint.glyph_width,
|
||||
false, 0);
|
||||
true, 0);
|
||||
|
||||
/* Return number of lines in wrapped string */
|
||||
return materialui_count_lines(wrapped_sublabel_str);
|
||||
@ -7121,6 +7135,7 @@ static void *materialui_init(void **userdata, bool video_is_threaded)
|
||||
mui->is_playlist = false;
|
||||
mui->is_file_list = false;
|
||||
mui->is_dropdown_list = false;
|
||||
mui->is_core_updater_list = false;
|
||||
mui->menu_stack_flushed = false;
|
||||
|
||||
mui->first_onscreen_entry = 0;
|
||||
@ -7575,6 +7590,11 @@ static void materialui_populate_entries(
|
||||
* scrolling via an alphabet search) */
|
||||
mui->is_playlist_tab = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB));
|
||||
|
||||
/* Check whether this is the core updater menu
|
||||
* (this requires special handling when long
|
||||
* pressing an entry) */
|
||||
mui->is_core_updater_list = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CORE_UPDATER_LIST));
|
||||
|
||||
/* Check whether we are currently viewing a playlist,
|
||||
* file-browser-type list or dropdown list
|
||||
* (each of these is regarded as a 'plain' list,
|
||||
@ -7594,7 +7614,7 @@ static void materialui_populate_entries(
|
||||
* Note: MENU_ENUM_LABEL_FAVORITES is always set
|
||||
* as the 'label' when navigating directories after
|
||||
* selecting load content */
|
||||
mui->is_file_list = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CORE_UPDATER_LIST)) ||
|
||||
mui->is_file_list = mui->is_core_updater_list ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_SCAN_DIRECTORY)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_SCAN_FILE)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_IMAGES_LIST)) ||
|
||||
@ -8942,9 +8962,17 @@ static int materialui_pointer_up(void *userdata,
|
||||
}
|
||||
break;
|
||||
case MENU_INPUT_GESTURE_LONG_PRESS:
|
||||
/* 'Reset to default' action */
|
||||
if ((ptr < entries_end) && (ptr == selection))
|
||||
return materialui_menu_entry_action(mui, entry, selection, MENU_ACTION_START);
|
||||
{
|
||||
/* If this is the core updater list, show info
|
||||
* message box for current entry.
|
||||
* In all other cases, perform 'reset to default'
|
||||
* action */
|
||||
if (mui->is_core_updater_list)
|
||||
return materialui_menu_entry_action(mui, entry, selection, MENU_ACTION_INFO);
|
||||
else
|
||||
return materialui_menu_entry_action(mui, entry, selection, MENU_ACTION_START);
|
||||
}
|
||||
break;
|
||||
case MENU_INPUT_GESTURE_SWIPE_LEFT:
|
||||
{
|
||||
|
@ -516,21 +516,37 @@ void ozone_draw_messagebox(
|
||||
const char *message)
|
||||
{
|
||||
unsigned i, y_position;
|
||||
int x, y, longest = 0, longest_width = 0;
|
||||
struct string_list *list = !string_is_empty(message)
|
||||
? string_split(message, "\n") : NULL;
|
||||
float scale_factor = ozone->last_scale_factor;
|
||||
int x, y, longest_width = 0;
|
||||
int usable_width = 0;
|
||||
struct string_list *list = NULL;
|
||||
float scale_factor = 0.0f;
|
||||
unsigned width = video_width;
|
||||
unsigned height = video_height;
|
||||
char wrapped_message[MENU_SUBLABEL_MAX_LENGTH];
|
||||
|
||||
if (!list || !ozone || !ozone->fonts.footer.font)
|
||||
{
|
||||
if (list)
|
||||
string_list_free(list);
|
||||
return;
|
||||
}
|
||||
wrapped_message[0] = '\0';
|
||||
|
||||
if (list->elems == 0)
|
||||
/* Sanity check */
|
||||
if (string_is_empty(message) ||
|
||||
!ozone ||
|
||||
!ozone->fonts.footer.font)
|
||||
goto end;
|
||||
|
||||
scale_factor = ozone->last_scale_factor;
|
||||
usable_width = (int)width - (48 * 8 * scale_factor);
|
||||
|
||||
if (usable_width < 1)
|
||||
goto end;
|
||||
|
||||
/* Split message into lines */
|
||||
word_wrap(
|
||||
wrapped_message, message,
|
||||
usable_width / (int)ozone->fonts.footer.glyph_width,
|
||||
true, 0);
|
||||
|
||||
list = string_split(wrapped_message, "\n");
|
||||
|
||||
if (!list || list->elems == 0)
|
||||
goto end;
|
||||
|
||||
y_position = height / 2;
|
||||
@ -544,13 +560,14 @@ void ozone_draw_messagebox(
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
const char *msg = list->elems[i].data;
|
||||
int len = (int)utf8len(msg);
|
||||
|
||||
if (len > longest)
|
||||
if (!string_is_empty(msg))
|
||||
{
|
||||
longest = len;
|
||||
longest_width = font_driver_get_message_width(
|
||||
int width = font_driver_get_message_width(
|
||||
ozone->fonts.footer.font, msg, (unsigned)strlen(msg), 1);
|
||||
|
||||
longest_width = (width > longest_width) ?
|
||||
width : longest_width;
|
||||
}
|
||||
}
|
||||
|
||||
@ -606,7 +623,8 @@ void ozone_draw_messagebox(
|
||||
}
|
||||
|
||||
end:
|
||||
string_list_free(list);
|
||||
if (list)
|
||||
string_list_free(list);
|
||||
}
|
||||
|
||||
void ozone_draw_fullscreen_thumbnails(
|
||||
|
@ -2768,21 +2768,28 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message)
|
||||
int x, y;
|
||||
size_t i, fb_pitch;
|
||||
unsigned fb_width, fb_height;
|
||||
unsigned width, glyphs_width, height;
|
||||
struct string_list *list = NULL;
|
||||
unsigned width = 0;
|
||||
unsigned glyphs_width = 0;
|
||||
unsigned height = 0;
|
||||
struct string_list *list = NULL;
|
||||
char wrapped_message[MENU_SUBLABEL_MAX_LENGTH];
|
||||
|
||||
if (!message || !*message)
|
||||
wrapped_message[0] = '\0';
|
||||
|
||||
if (string_is_empty(message))
|
||||
return;
|
||||
|
||||
list = string_split(message, "\n");
|
||||
if (!list)
|
||||
return;
|
||||
if (list->elems == 0)
|
||||
/* Split message into lines */
|
||||
word_wrap(
|
||||
wrapped_message, message,
|
||||
rgui_term_layout.width,
|
||||
false, 0);
|
||||
|
||||
list = string_split(wrapped_message, "\n");
|
||||
|
||||
if (!list || list->elems == 0)
|
||||
goto end;
|
||||
|
||||
width = 0;
|
||||
glyphs_width = 0;
|
||||
|
||||
gfx_display_get_fb_size(&fb_width, &fb_height,
|
||||
&fb_pitch);
|
||||
|
||||
@ -2792,23 +2799,18 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message)
|
||||
char *msg = list->elems[i].data;
|
||||
unsigned msglen = (unsigned)utf8len(msg);
|
||||
|
||||
if (msglen > rgui_term_layout.width)
|
||||
{
|
||||
msg[rgui_term_layout.width - 2] = '.';
|
||||
msg[rgui_term_layout.width - 1] = '.';
|
||||
msg[rgui_term_layout.width - 0] = '.';
|
||||
msg[rgui_term_layout.width + 1] = '\0';
|
||||
msglen = rgui_term_layout.width;
|
||||
}
|
||||
|
||||
line_width = msglen * FONT_WIDTH_STRIDE - 1 + 6 + 10;
|
||||
width = MAX(width, line_width);
|
||||
glyphs_width = MAX(glyphs_width, msglen);
|
||||
}
|
||||
|
||||
height = (unsigned)(FONT_HEIGHT_STRIDE * list->size + 6 + 10);
|
||||
x = (fb_width - width) / 2;
|
||||
y = (fb_height - height) / 2;
|
||||
x = ((int)fb_width - (int)width) / 2;
|
||||
y = ((int)fb_height - (int)height) / 2;
|
||||
|
||||
height = (height > fb_height) ? fb_height : height;
|
||||
x = (x < 0) ? 0 : x;
|
||||
y = (y < 0) ? 0 : y;
|
||||
|
||||
if (rgui_frame_buf.data)
|
||||
{
|
||||
@ -2854,19 +2856,30 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message)
|
||||
border_dark_color, border_light_color, border_thickness);
|
||||
}
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
/* Draw text */
|
||||
if (rgui_frame_buf.data)
|
||||
{
|
||||
const char *msg = list->elems[i].data;
|
||||
int offset_x = (int)(FONT_WIDTH_STRIDE * (glyphs_width - utf8len(msg)) / 2);
|
||||
int offset_y = (int)(FONT_HEIGHT_STRIDE * i);
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
const char *msg = list->elems[i].data;
|
||||
int offset_x = (int)(FONT_WIDTH_STRIDE * (glyphs_width - utf8len(msg)) / 2);
|
||||
int offset_y = (int)(FONT_HEIGHT_STRIDE * i);
|
||||
int text_x = x + 8 + offset_x;
|
||||
int text_y = y + 8 + offset_y;
|
||||
|
||||
if (rgui_frame_buf.data)
|
||||
blit_line(fb_width, x + 8 + offset_x, y + 8 + offset_y, msg,
|
||||
/* Ensure we remain within the bounds of the
|
||||
* framebuffer */
|
||||
if (text_y > (int)fb_height - 10 - (int)FONT_HEIGHT_STRIDE)
|
||||
break;
|
||||
|
||||
blit_line(fb_width, text_x, text_y, msg,
|
||||
rgui->colors.normal_color, rgui->colors.shadow_color);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
string_list_free(list);
|
||||
if (list)
|
||||
string_list_free(list);
|
||||
}
|
||||
|
||||
static void rgui_blit_cursor(rgui_t *rgui)
|
||||
|
@ -902,17 +902,32 @@ static void xmb_render_messagebox_internal(
|
||||
unsigned i, y_position;
|
||||
int x, y, longest = 0, longest_width = 0;
|
||||
float line_height = 0;
|
||||
struct string_list *list = !string_is_empty(message)
|
||||
? string_split(message, "\n") : NULL;
|
||||
int usable_width = 0;
|
||||
struct string_list *list = NULL;
|
||||
char wrapped_message[MENU_SUBLABEL_MAX_LENGTH];
|
||||
|
||||
if (!list || !xmb || !xmb->font)
|
||||
{
|
||||
if (list)
|
||||
string_list_free(list);
|
||||
return;
|
||||
}
|
||||
wrapped_message[0] = '\0';
|
||||
|
||||
if (list->elems == 0)
|
||||
/* Sanity check */
|
||||
if (string_is_empty(message) ||
|
||||
!xmb ||
|
||||
!xmb->font)
|
||||
goto end;
|
||||
|
||||
usable_width = (int)video_width - (xmb->margins_dialog * 8);
|
||||
|
||||
if (usable_width < 1)
|
||||
goto end;
|
||||
|
||||
/* Split message into lines */
|
||||
word_wrap(
|
||||
wrapped_message, message,
|
||||
usable_width / (xmb->font_size * 0.6f),
|
||||
true, 0);
|
||||
|
||||
list = string_split(wrapped_message, "\n");
|
||||
|
||||
if (!list || list->elems == 0)
|
||||
goto end;
|
||||
|
||||
line_height = xmb->font->size * 1.2;
|
||||
@ -927,14 +942,15 @@ static void xmb_render_messagebox_internal(
|
||||
/* find the longest line width */
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
const char *msg = list->elems[i].data;
|
||||
int len = (int)utf8len(msg);
|
||||
const char *msg = list->elems[i].data;
|
||||
|
||||
if (len > longest)
|
||||
if (!string_is_empty(msg))
|
||||
{
|
||||
longest = len;
|
||||
longest_width = font_driver_get_message_width(
|
||||
int width = font_driver_get_message_width(
|
||||
xmb->font, msg, (unsigned)strlen(msg), 1);
|
||||
|
||||
longest_width = (width > longest_width) ?
|
||||
width : longest_width;
|
||||
}
|
||||
}
|
||||
|
||||
@ -978,7 +994,8 @@ static void xmb_render_messagebox_internal(
|
||||
0xffffffff);
|
||||
|
||||
end:
|
||||
string_list_free(list);
|
||||
if (list)
|
||||
string_list_free(list);
|
||||
}
|
||||
|
||||
static void xmb_update_savestate_thumbnail_path(void *data, unsigned i)
|
||||
|
@ -7070,6 +7070,7 @@ unsigned menu_displaylist_build_list(
|
||||
{MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL, PARSE_ONLY_STRING},
|
||||
{MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL, PARSE_ONLY_STRING},
|
||||
{MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_CORE_UPDATER_SHOW_EXPERIMENTAL_CORES, PARSE_ONLY_BOOL},
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(build_list); i++)
|
||||
@ -8828,9 +8829,12 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
||||
#ifdef HAVE_NETWORKING
|
||||
{
|
||||
core_updater_list_t *core_list = core_updater_list_get_cached();
|
||||
settings_t *settings = config_get_ptr();
|
||||
bool show_experimental_cores = settings->bools.network_buildbot_show_experimental_cores;
|
||||
|
||||
if (core_list)
|
||||
{
|
||||
size_t menu_index = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < core_updater_list_size(core_list); i++)
|
||||
@ -8839,15 +8843,25 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
||||
|
||||
if (core_updater_list_get_index(core_list, i, &entry))
|
||||
{
|
||||
/* Skip 'experimental' cores, if required
|
||||
* > Note: We always show cores that are already
|
||||
* installed, regardless of status (a user should
|
||||
* always have the option to update existing cores) */
|
||||
if (!show_experimental_cores &&
|
||||
(entry->is_experimental &&
|
||||
!path_is_valid(entry->local_core_path)))
|
||||
continue;
|
||||
|
||||
if (menu_entries_append_enum(info->list,
|
||||
entry->remote_filename,
|
||||
"",
|
||||
MENU_ENUM_LABEL_URL_ENTRY,
|
||||
MENU_ENUM_LABEL_CORE_UPDATER_ENTRY,
|
||||
FILE_TYPE_DOWNLOAD_CORE, 0, 0))
|
||||
{
|
||||
file_list_set_alt_at_offset(
|
||||
info->list, i, entry->display_name);
|
||||
info->list, menu_index, entry->display_name);
|
||||
|
||||
menu_index++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
@ -298,8 +298,35 @@ static int generic_menu_iterate(void *data,
|
||||
|
||||
if (cbs && cbs->enum_idx != MSG_UNKNOWN)
|
||||
{
|
||||
ret = menu_hash_get_help_enum(cbs->enum_idx,
|
||||
menu->menu_state_msg, sizeof(menu->menu_state_msg));
|
||||
#ifdef HAVE_NETWORKING
|
||||
/* Core updater entries require special treatment */
|
||||
if (cbs->enum_idx == MENU_ENUM_LABEL_CORE_UPDATER_ENTRY)
|
||||
{
|
||||
core_updater_list_t *core_list = core_updater_list_get_cached();
|
||||
const core_updater_list_entry_t *entry = NULL;
|
||||
const char *path = NULL;
|
||||
|
||||
/* Get core path */
|
||||
menu_entries_get_at_offset(selection_buf, selection,
|
||||
&path, NULL, NULL, NULL, NULL);
|
||||
|
||||
/* Search for specified core */
|
||||
if (core_list && path &&
|
||||
core_updater_list_get_filename(core_list, path, &entry) &&
|
||||
!string_is_empty(entry->description))
|
||||
strlcpy(menu->menu_state_msg, entry->description,
|
||||
sizeof(menu->menu_state_msg));
|
||||
else
|
||||
strlcpy(menu->menu_state_msg,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE),
|
||||
sizeof(menu->menu_state_msg));
|
||||
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
ret = menu_hash_get_help_enum(cbs->enum_idx,
|
||||
menu->menu_state_msg, sizeof(menu->menu_state_msg));
|
||||
|
||||
#ifdef HAVE_ACCESSIBILITY
|
||||
if (iterate_type != last_iterate_type && is_accessibility_enabled())
|
||||
|
@ -16100,7 +16100,23 @@ static bool setting_append_list(
|
||||
&settings->bools.network_buildbot_auto_extract_archive,
|
||||
MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE,
|
||||
MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE,
|
||||
true,
|
||||
DEFAULT_NETWORK_BUILDBOT_AUTO_EXTRACT_ARCHIVE,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE
|
||||
);
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.network_buildbot_show_experimental_cores,
|
||||
MENU_ENUM_LABEL_CORE_UPDATER_SHOW_EXPERIMENTAL_CORES,
|
||||
MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SHOW_EXPERIMENTAL_CORES,
|
||||
DEFAULT_NETWORK_BUILDBOT_SHOW_EXPERIMENTAL_CORES,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
&group_info,
|
||||
@ -16552,7 +16568,7 @@ static bool setting_append_list(
|
||||
&settings->bools.network_on_demand_thumbnails,
|
||||
MENU_ENUM_LABEL_NETWORK_ON_DEMAND_THUMBNAILS,
|
||||
MENU_ENUM_LABEL_VALUE_NETWORK_ON_DEMAND_THUMBNAILS,
|
||||
network_on_demand_thumbnails,
|
||||
DEFAULT_NETWORK_ON_DEMAND_THUMBNAILS,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
&group_info,
|
||||
|
@ -681,6 +681,7 @@ enum msg_hash_enums
|
||||
MENU_ENUM_LABEL_SHADER_PARAMETERS_ENTRY,
|
||||
MENU_ENUM_LABEL_RDB_ENTRY,
|
||||
MENU_ENUM_LABEL_URL_ENTRY,
|
||||
MENU_ENUM_LABEL_CORE_UPDATER_ENTRY,
|
||||
MENU_ENUM_LABEL_CORE_OPTION_ENTRY,
|
||||
MENU_ENUM_LABEL_NETWORK_INFO_ENTRY,
|
||||
MENU_ENUM_LABEL_SYSTEM_INFO_ENTRY,
|
||||
@ -1881,6 +1882,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(START_CORE),
|
||||
MENU_LABEL(CORE_UPDATER_LIST),
|
||||
MENU_LABEL(CORE_UPDATER_AUTO_EXTRACT_ARCHIVE),
|
||||
MENU_LABEL(CORE_UPDATER_SHOW_EXPERIMENTAL_CORES),
|
||||
MENU_LABEL(CORE_UPDATER_BUILDBOT_URL),
|
||||
MENU_LABEL(BUILDBOT_ASSETS_URL),
|
||||
MENU_LABEL(CORE_SET_SUPPORTS_NO_CONTENT_ENABLE),
|
||||
|
Loading…
x
Reference in New Issue
Block a user