mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-26 17:50:56 +00:00
Add 'Standalone Cores' menu (#13655)
This commit is contained in:
parent
6dec52fda7
commit
9b0cb0fc92
@ -1088,7 +1088,8 @@ ifeq ($(HAVE_MENU_COMMON), 1)
|
||||
menu/cbs/menu_cbs_label.o \
|
||||
menu/cbs/menu_cbs_sublabel.o \
|
||||
menu/cbs/menu_cbs_title.o \
|
||||
menu/menu_displaylist.o
|
||||
menu/menu_displaylist.o \
|
||||
menu/menu_contentless_cores.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_GFX_WIDGETS), 1)
|
||||
|
@ -730,6 +730,7 @@ static const bool content_show_playlists = true;
|
||||
#if defined(HAVE_LIBRETRODB)
|
||||
#define DEFAULT_MENU_CONTENT_SHOW_EXPLORE true
|
||||
#endif
|
||||
#define DEFAULT_MENU_CONTENT_SHOW_CONTENTLESS_CORES MENU_CONTENTLESS_CORES_DISPLAY_SINGLE_PURPOSE
|
||||
|
||||
#ifdef HAVE_XMB
|
||||
#define DEFAULT_XMB_ANIMATION 0
|
||||
|
@ -2162,6 +2162,7 @@ static struct config_uint_setting *populate_settings_uint(
|
||||
SETTING_UINT("menu_ticker_type", &settings->uints.menu_ticker_type, true, DEFAULT_MENU_TICKER_TYPE, false);
|
||||
SETTING_UINT("menu_scroll_delay", &settings->uints.menu_scroll_delay, true, DEFAULT_MENU_SCROLL_DELAY, false);
|
||||
SETTING_UINT("content_show_add_entry", &settings->uints.menu_content_show_add_entry, true, DEFAULT_MENU_CONTENT_SHOW_ADD_ENTRY, false);
|
||||
SETTING_UINT("content_show_contentless_cores", &settings->uints.menu_content_show_contentless_cores, true, DEFAULT_MENU_CONTENT_SHOW_CONTENTLESS_CORES, false);
|
||||
SETTING_UINT("menu_screensaver_timeout", &settings->uints.menu_screensaver_timeout, true, DEFAULT_MENU_SCREENSAVER_TIMEOUT, false);
|
||||
#if defined(HAVE_MATERIALUI) || defined(HAVE_XMB) || defined(HAVE_OZONE)
|
||||
SETTING_UINT("menu_screensaver_animation", &settings->uints.menu_screensaver_animation, true, DEFAULT_MENU_SCREENSAVER_ANIMATION, false);
|
||||
|
@ -295,6 +295,7 @@ typedef struct settings
|
||||
unsigned menu_ticker_type;
|
||||
unsigned menu_scroll_delay;
|
||||
unsigned menu_content_show_add_entry;
|
||||
unsigned menu_content_show_contentless_cores;
|
||||
unsigned menu_screensaver_timeout;
|
||||
unsigned menu_screensaver_animation;
|
||||
|
||||
|
19
core_info.c
19
core_info.c
@ -48,7 +48,7 @@
|
||||
/* Core Info Cache START */
|
||||
/*************************/
|
||||
|
||||
#define CORE_INFO_CACHE_VERSION "1.1"
|
||||
#define CORE_INFO_CACHE_VERSION "1.2"
|
||||
#define CORE_INFO_CACHE_DEFAULT_CAPACITY 8
|
||||
|
||||
/* TODO/FIXME: Apparently rzip compression is an issue on UWP */
|
||||
@ -203,6 +203,8 @@ static bool CCJSONObjectMemberHandler(void *context,
|
||||
}
|
||||
else if (string_is_equal(pValue, "supports_no_game"))
|
||||
pCtx->current_entry_bool_val = &pCtx->core_info->supports_no_game;
|
||||
else if (string_is_equal(pValue, "single_purpose"))
|
||||
pCtx->current_entry_bool_val = &pCtx->core_info->single_purpose;
|
||||
else if (string_is_equal(pValue, "savestate_support_level"))
|
||||
pCtx->current_entry_uint_val = &pCtx->core_info->savestate_support_level;
|
||||
break;
|
||||
@ -472,6 +474,7 @@ static void core_info_copy(core_info_t *src, core_info_t *dst)
|
||||
dst->savestate_support_level = src->savestate_support_level;
|
||||
dst->has_info = src->has_info;
|
||||
dst->supports_no_game = src->supports_no_game;
|
||||
dst->single_purpose = src->single_purpose;
|
||||
dst->database_match_archive_member = src->database_match_archive_member;
|
||||
dst->is_experimental = src->is_experimental;
|
||||
dst->is_locked = src->is_locked;
|
||||
@ -567,6 +570,7 @@ static void core_info_transfer(core_info_t *src, core_info_t *dst)
|
||||
dst->savestate_support_level = src->savestate_support_level;
|
||||
dst->has_info = src->has_info;
|
||||
dst->supports_no_game = src->supports_no_game;
|
||||
dst->single_purpose = src->single_purpose;
|
||||
dst->database_match_archive_member = src->database_match_archive_member;
|
||||
dst->is_experimental = src->is_experimental;
|
||||
dst->is_locked = src->is_locked;
|
||||
@ -1118,6 +1122,14 @@ static bool core_info_cache_write(core_info_cache_list_t *list, const char *info
|
||||
rjsonwriter_add_comma(writer);
|
||||
rjsonwriter_add_newline(writer);
|
||||
|
||||
rjsonwriter_add_spaces(writer, 6);
|
||||
rjsonwriter_add_string(writer, "single_purpose");
|
||||
rjsonwriter_add_colon(writer);
|
||||
rjsonwriter_add_space(writer);
|
||||
rjsonwriter_add_bool(writer, info->single_purpose);
|
||||
rjsonwriter_add_comma(writer);
|
||||
rjsonwriter_add_newline(writer);
|
||||
|
||||
rjsonwriter_add_spaces(writer, 6);
|
||||
rjsonwriter_add_string(writer, "database_match_archive_member");
|
||||
rjsonwriter_add_colon(writer);
|
||||
@ -1746,6 +1758,10 @@ static void core_info_parse_config_file(
|
||||
&tmp_bool))
|
||||
info->supports_no_game = tmp_bool;
|
||||
|
||||
if (config_get_bool(conf, "single_purpose",
|
||||
&tmp_bool))
|
||||
info->single_purpose = tmp_bool;
|
||||
|
||||
if (config_get_bool(conf, "database_match_archive_member",
|
||||
&tmp_bool))
|
||||
info->database_match_archive_member = tmp_bool;
|
||||
@ -2178,6 +2194,7 @@ bool core_info_init_current_core(void)
|
||||
return false;
|
||||
current->has_info = false;
|
||||
current->supports_no_game = false;
|
||||
current->single_purpose = false;
|
||||
current->database_match_archive_member = false;
|
||||
current->is_experimental = false;
|
||||
current->is_locked = false;
|
||||
|
@ -104,6 +104,7 @@ typedef struct
|
||||
uint32_t savestate_support_level;
|
||||
bool has_info;
|
||||
bool supports_no_game;
|
||||
bool single_purpose;
|
||||
bool database_match_archive_member;
|
||||
bool is_experimental;
|
||||
bool is_locked;
|
||||
|
2
driver.c
2
driver.c
@ -627,6 +627,7 @@ void drivers_init(
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
menu_explore_context_init();
|
||||
#endif
|
||||
menu_contentless_cores_context_init();
|
||||
}
|
||||
}
|
||||
|
||||
@ -694,6 +695,7 @@ void driver_uninit(int flags)
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
menu_explore_context_deinit();
|
||||
#endif
|
||||
menu_contentless_cores_context_deinit();
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_DEINIT, NULL);
|
||||
}
|
||||
|
@ -1416,6 +1416,7 @@ MENU
|
||||
#include "../menu/cbs/menu_cbs_label.c"
|
||||
#include "../menu/cbs/menu_cbs_sublabel.c"
|
||||
#include "../menu/menu_displaylist.c"
|
||||
#include "../menu/menu_contentless_cores.c"
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
#include "../menu/menu_explore.c"
|
||||
#include "../tasks/task_menu_explore.c"
|
||||
|
@ -82,6 +82,14 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_EXPLORE_INITIALISING_LIST,
|
||||
"explore_initialising_list"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB,
|
||||
"contentless_cores_tab"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_CONTENTLESS_CORE,
|
||||
"contentless_core"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_ADD_TAB,
|
||||
"add_tab"
|
||||
@ -768,6 +776,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_DEFERRED_EXPLORE_LIST,
|
||||
"deferred_explore_list"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_DEFERRED_CONTENTLESS_CORES_LIST,
|
||||
"deferred_contentless_cores_list"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_DEFERRED_NETPLAY,
|
||||
"deferred_netplay"
|
||||
@ -3752,6 +3764,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_CONTENT_SHOW_EXPLORE,
|
||||
"content_show_explore"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_CONTENT_SHOW_CONTENTLESS_CORES,
|
||||
"content_show_contentless_cores"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_CONTENT_SHOW_FAVORITES,
|
||||
"content_show_favorites"
|
||||
@ -4070,6 +4086,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_GOTO_EXPLORE,
|
||||
"goto_explore"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_GOTO_CONTENTLESS_CORES,
|
||||
"goto_contentless_cores"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE,
|
||||
"materialui_icons_enable"
|
||||
|
@ -44,6 +44,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_EXPLORE_TAB,
|
||||
"Explore"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CONTENTLESS_CORES_TAB,
|
||||
"Standalone Cores"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_ADD_TAB,
|
||||
"Import Content"
|
||||
@ -286,6 +290,14 @@ MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_GOTO_EXPLORE,
|
||||
"Browse all content matching the database via a categorized search interface."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_GOTO_CONTENTLESS_CORES,
|
||||
"Standalone Cores"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_GOTO_CONTENTLESS_CORES,
|
||||
"Installed cores which can operate without loading content will appear here."
|
||||
)
|
||||
|
||||
/* Main Menu > Online Updater */
|
||||
|
||||
@ -4620,6 +4632,22 @@ MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_CONTENT_SHOW_EXPLORE,
|
||||
"Show the content explorer option. (Restart Required on Ozone/XMB)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_CONTENTLESS_CORES,
|
||||
"Show 'Standalone Cores'"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_CONTENT_SHOW_CONTENTLESS_CORES,
|
||||
"Specify the type of core (if any) to show in the 'Standalone Cores' menu. (Restart Required on Ozone/XMB)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_SHOW_CONTENTLESS_CORES_ALL,
|
||||
"All"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_SHOW_CONTENTLESS_CORES_SINGLE_PURPOSE,
|
||||
"Single-Use"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_TIMEDATE_ENABLE,
|
||||
"Show Date and Time"
|
||||
|
@ -92,6 +92,13 @@ int action_cancel_pop_default(const char *path,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_cancel_contentless_core(const char *path,
|
||||
const char *label, unsigned type, size_t idx)
|
||||
{
|
||||
menu_state_get_ptr()->contentless_core_ptr = 0;
|
||||
return action_cancel_pop_default(path, label, type, idx) ;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CHEATS
|
||||
static int action_cancel_cheat_details(const char *path,
|
||||
const char *label, unsigned type, size_t idx)
|
||||
@ -164,6 +171,11 @@ static int menu_cbs_init_bind_cancel_compare_type(
|
||||
case FILE_TYPE_DOWNLOAD_CORE:
|
||||
BIND_ACTION_CANCEL(cbs, action_cancel_core_content);
|
||||
return 0;
|
||||
case MENU_SETTING_ACTION_CONTENTLESS_CORE_RUN:
|
||||
BIND_ACTION_CANCEL(cbs, action_cancel_contentless_core);
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CHEATS
|
||||
|
@ -648,6 +648,7 @@ GENERIC_DEFERRED_PUSH_GENERAL(deferred_music_history_list, PUSH_DEFAULT, DISPLAY
|
||||
GENERIC_DEFERRED_PUSH_GENERAL(deferred_image_history_list, PUSH_DEFAULT, DISPLAYLIST_IMAGES_HISTORY)
|
||||
GENERIC_DEFERRED_PUSH_GENERAL(deferred_video_history_list, PUSH_DEFAULT, DISPLAYLIST_VIDEO_HISTORY)
|
||||
GENERIC_DEFERRED_PUSH_GENERAL(deferred_explore_list, PUSH_DEFAULT, DISPLAYLIST_EXPLORE)
|
||||
GENERIC_DEFERRED_PUSH_GENERAL(deferred_contentless_cores_list, PUSH_DEFAULT, DISPLAYLIST_CONTENTLESS_CORES)
|
||||
GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST)
|
||||
GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list_special, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_SPECIAL)
|
||||
GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list_resolution, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_RESOLUTION)
|
||||
@ -759,6 +760,7 @@ static int menu_cbs_init_bind_deferred_push_compare_label(
|
||||
{MENU_ENUM_LABEL_DEFERRED_IMAGES_LIST, deferred_image_history_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_VIDEO_LIST, deferred_video_history_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_EXPLORE_LIST, deferred_explore_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_CONTENTLESS_CORES_LIST, deferred_contentless_cores_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_INPUT_SETTINGS_LIST, deferred_push_input_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_INPUT_MENU_SETTINGS_LIST, deferred_push_input_menu_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_INPUT_TURBO_FIRE_SETTINGS_LIST, deferred_push_input_turbo_fire_settings_list},
|
||||
|
@ -519,6 +519,25 @@ static void menu_action_setting_disp_set_label_core_manager_entry(
|
||||
}
|
||||
}
|
||||
|
||||
static void menu_action_setting_disp_set_label_contentless_core(
|
||||
file_list_t* list,
|
||||
unsigned *w, unsigned type, unsigned i,
|
||||
const char *label,
|
||||
char *s, size_t len,
|
||||
const char *path,
|
||||
char *s2, size_t len2)
|
||||
{
|
||||
const char *alt = list->list[i].alt
|
||||
? list->list[i].alt
|
||||
: list->list[i].path;
|
||||
|
||||
*s = '\0';
|
||||
*w = 0;
|
||||
|
||||
if (alt)
|
||||
strlcpy(s2, alt, len2);
|
||||
}
|
||||
|
||||
#ifndef HAVE_LAKKA_SWITCH
|
||||
#ifdef HAVE_LAKKA
|
||||
static void menu_action_setting_disp_cpu_gov_mode(
|
||||
@ -1912,6 +1931,10 @@ static int menu_cbs_init_bind_get_string_representation_compare_label(
|
||||
BIND_ACTION_GET_VALUE(cbs,
|
||||
menu_action_setting_disp_set_label_core_manager_entry);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_CONTENTLESS_CORE:
|
||||
BIND_ACTION_GET_VALUE(cbs,
|
||||
menu_action_setting_disp_set_label_contentless_core);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_CORE_OPTION_OVERRIDE_INFO:
|
||||
BIND_ACTION_GET_VALUE(cbs,
|
||||
menu_action_setting_disp_set_label_core_option_override_info);
|
||||
@ -2120,6 +2143,7 @@ static int menu_cbs_init_bind_get_string_representation_compare_type(
|
||||
case MENU_SETTING_ACTION_DELETE_ENTRY:
|
||||
case MENU_SETTING_ACTION_CORE_DISK_OPTIONS:
|
||||
case MENU_EXPLORE_TAB:
|
||||
case MENU_CONTENTLESS_CORES_TAB:
|
||||
BIND_ACTION_GET_VALUE(cbs,
|
||||
menu_action_setting_disp_set_label_menu_more);
|
||||
break;
|
||||
|
@ -1006,6 +1006,7 @@ static int menu_cbs_init_bind_left_compare_label(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_SUBSYSTEM_LOAD:
|
||||
case MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM:
|
||||
case MENU_ENUM_LABEL_EXPLORE_ITEM:
|
||||
case MENU_ENUM_LABEL_CONTENTLESS_CORE:
|
||||
case MENU_ENUM_LABEL_NO_SETTINGS_FOUND:
|
||||
BIND_ACTION_LEFT(cbs, action_left_mainmenu);
|
||||
break;
|
||||
@ -1043,6 +1044,7 @@ static int menu_cbs_init_bind_left_compare_label(menu_file_list_cbs_t *cbs,
|
||||
break;
|
||||
case MENU_ENUM_LABEL_NO_ITEMS:
|
||||
case MENU_ENUM_LABEL_NO_PLAYLIST_ENTRIES_AVAILABLE:
|
||||
case MENU_ENUM_LABEL_NO_CORES_AVAILABLE:
|
||||
case MENU_ENUM_LABEL_EXPLORE_INITIALISING_LIST:
|
||||
if (
|
||||
string_ends_with_size(menu_label, "_tab",
|
||||
|
@ -612,6 +612,15 @@ int generic_action_ok_displaylist_push(const char *path,
|
||||
info.enum_idx = MENU_ENUM_LABEL_DEFERRED_EXPLORE_LIST;
|
||||
dl_type = DISPLAYLIST_GENERIC;
|
||||
break;
|
||||
case ACTION_OK_DL_CONTENTLESS_CORES_LIST:
|
||||
info.type = type;
|
||||
info.directory_ptr = idx;
|
||||
info_path = label;
|
||||
info_label = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_DEFERRED_CONTENTLESS_CORES_LIST);
|
||||
info.enum_idx = MENU_ENUM_LABEL_DEFERRED_CONTENTLESS_CORES_LIST;
|
||||
dl_type = DISPLAYLIST_GENERIC;
|
||||
break;
|
||||
case ACTION_OK_DL_REMAPPINGS_PORT_LIST:
|
||||
info.type = type;
|
||||
info.directory_ptr = idx;
|
||||
@ -5172,14 +5181,30 @@ int action_ok_close_content(const char *path, const char *label, unsigned type,
|
||||
/* Unload core */
|
||||
ret = generic_action_ok_command(CMD_EVENT_UNLOAD_CORE);
|
||||
|
||||
/* If close content was selected via 'Main Menu > Quick Menu',
|
||||
* have to flush the menu stack back to 'Main Menu'
|
||||
/* If close content was selected via any means other than
|
||||
* 'Playlist > Quick Menu', have to flush the menu stack
|
||||
* (otherwise users will be presented with an empty
|
||||
* 'No items' quick menu, requiring needless backwards
|
||||
* navigation) */
|
||||
if (type == MENU_SETTING_ACTION_CLOSE)
|
||||
{
|
||||
menu_entries_flush_stack(msg_hash_to_str(MENU_ENUM_LABEL_MAIN_MENU), 0);
|
||||
const char *flush_target = msg_hash_to_str(MENU_ENUM_LABEL_MAIN_MENU);
|
||||
const char *parent_label = NULL;
|
||||
struct menu_state *menu_st = menu_state_get_ptr();
|
||||
file_list_t *list = NULL;
|
||||
|
||||
if (menu_st->entries.list)
|
||||
list = MENU_LIST_GET(menu_st->entries.list, 0);
|
||||
if (list && (list->size > 1))
|
||||
{
|
||||
file_list_get_at_offset(list, list->size - 2, NULL, &parent_label, NULL, NULL);
|
||||
|
||||
if (string_is_equal(parent_label, msg_hash_to_str(MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB)) ||
|
||||
string_is_equal(parent_label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CONTENTLESS_CORES_LIST)))
|
||||
flush_target = parent_label;
|
||||
}
|
||||
|
||||
menu_entries_flush_stack(flush_target, 0);
|
||||
/* An annoyance - some menu drivers (Ozone...) call
|
||||
* RARCH_MENU_CTL_SET_PREVENT_POPULATE in awkward
|
||||
* places, which can cause breakage here when flushing
|
||||
@ -5611,6 +5636,7 @@ DEFAULT_ACTION_OK_FUNC(action_ok_cdrom_info_list, ACTION_OK_DL_CDROM_INFO_DETAIL
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_goto_video, ACTION_OK_DL_VIDEO_LIST)
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_goto_music, ACTION_OK_DL_MUSIC_LIST)
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_goto_explore, ACTION_OK_DL_EXPLORE_LIST)
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_goto_contentless_cores, ACTION_OK_DL_CONTENTLESS_CORES_LIST)
|
||||
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_shader_preset_save, ACTION_OK_DL_SHADER_PRESET_SAVE)
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_shader_preset_remove, ACTION_OK_DL_SHADER_PRESET_REMOVE)
|
||||
@ -6670,12 +6696,20 @@ static int action_ok_start_core(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
content_ctx_info_t content_info;
|
||||
menu_ctx_list_t list_info;
|
||||
|
||||
content_info.argc = 0;
|
||||
content_info.argv = NULL;
|
||||
content_info.args = NULL;
|
||||
content_info.environ_get = NULL;
|
||||
|
||||
/* We are going to push a new menu; ensure
|
||||
* that the current one is cached for animation
|
||||
* purposes */
|
||||
list_info.type = MENU_LIST_PLAIN;
|
||||
list_info.action = 0;
|
||||
menu_driver_list_cache(&list_info);
|
||||
|
||||
path_clear(RARCH_PATH_BASENAME);
|
||||
if (!task_push_start_current_core(&content_info))
|
||||
return -1;
|
||||
@ -6683,6 +6717,54 @@ static int action_ok_start_core(const char *path,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_ok_contentless_core_run(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
const char *core_path = path;
|
||||
/* TODO/FIXME: If this function succeeds, the
|
||||
* quick menu will be pushed on the subsequent
|
||||
* frame via the RARCH_MENU_CTL_SET_PENDING_QUICK_MENU
|
||||
* command. The way this is implemented 'breaks' the
|
||||
* menu stack record, so when leaving the quick
|
||||
* menu via a 'cancel' operation, the last selected
|
||||
* menu index is lost. We therefore have to cache
|
||||
* the current selection here, and reapply it manually
|
||||
* when building the contentless cores list... */
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
|
||||
if (string_is_empty(core_path))
|
||||
return menu_cbs_exit();
|
||||
|
||||
/* If core is already running, open quick menu */
|
||||
if (retroarch_ctl(RARCH_CTL_IS_CORE_LOADED, (void*)core_path) &&
|
||||
retroarch_ctl(RARCH_CTL_CORE_IS_RUNNING, NULL))
|
||||
{
|
||||
bool flush_menu = false;
|
||||
menu_driver_ctl(RARCH_MENU_CTL_SET_PENDING_QUICK_MENU, &flush_menu);
|
||||
menu_state_get_ptr()->contentless_core_ptr = selection;
|
||||
menu_navigation_set_selection(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Cache current menu selection *before* attempting
|
||||
* to start the core, to ensure consistent menu
|
||||
* navigation (i.e. running a core will in general
|
||||
* cause a redraw of the menu, so must record current
|
||||
* position even if the operation fails) */
|
||||
menu_state_get_ptr()->contentless_core_ptr = selection;
|
||||
|
||||
/* Load and start core */
|
||||
path_clear(RARCH_PATH_BASENAME);
|
||||
if (!task_push_load_contentless_core_from_menu(core_path))
|
||||
{
|
||||
if (retroarch_ctl(RARCH_CTL_IS_CORE_LOADED, (void*)core_path))
|
||||
generic_action_ok_command(CMD_EVENT_UNLOAD_CORE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_ok_load_archive(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
@ -7384,6 +7466,9 @@ static int action_ok_core_delete(const char *path,
|
||||
/* Reload core info files */
|
||||
command_event(CMD_EVENT_CORE_INFO_INIT, NULL);
|
||||
|
||||
/* Force reload of contentless cores icons */
|
||||
menu_contentless_cores_free();
|
||||
|
||||
/* Return to higher level menu */
|
||||
return action_cancel_pop_default(NULL, NULL, 0, 0);
|
||||
}
|
||||
@ -7787,6 +7872,7 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
|
||||
{MENU_ENUM_LABEL_GOTO_IMAGES, action_ok_goto_images},
|
||||
{MENU_ENUM_LABEL_GOTO_VIDEO, action_ok_goto_video},
|
||||
{MENU_ENUM_LABEL_GOTO_EXPLORE, action_ok_goto_explore},
|
||||
{MENU_ENUM_LABEL_GOTO_CONTENTLESS_CORES, action_ok_goto_contentless_cores},
|
||||
{MENU_ENUM_LABEL_BROWSE_START, action_ok_browse_url_start},
|
||||
{MENU_ENUM_LABEL_FILE_BROWSER_CORE, action_ok_load_core},
|
||||
{MENU_ENUM_LABEL_FILE_BROWSER_CORE_SELECT_FROM_COLLECTION, action_ok_core_deferred_set},
|
||||
@ -8020,6 +8106,7 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
|
||||
{MENU_ENUM_LABEL_PLAYLIST_MANAGER_DEFAULT_CORE, action_ok_playlist_default_core},
|
||||
{MENU_ENUM_LABEL_CORE_MANAGER_LIST, action_ok_push_core_manager_list},
|
||||
{MENU_ENUM_LABEL_EXPLORE_TAB, action_ok_push_default},
|
||||
{MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB, action_ok_push_default},
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ok_list); i++)
|
||||
@ -8652,6 +8739,9 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs,
|
||||
case MENU_SETTING_ACTION_AUDIO_DSP_PLUGIN_REMOVE:
|
||||
BIND_ACTION_OK(cbs, action_ok_audio_dsp_plugin_remove);
|
||||
break;
|
||||
case MENU_SETTING_ACTION_CONTENTLESS_CORE_RUN:
|
||||
BIND_ACTION_OK(cbs, action_ok_contentless_core_run);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -1126,6 +1126,7 @@ static int menu_cbs_init_bind_right_compare_label(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_SUBSYSTEM_LOAD:
|
||||
case MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM:
|
||||
case MENU_ENUM_LABEL_EXPLORE_ITEM:
|
||||
case MENU_ENUM_LABEL_CONTENTLESS_CORE:
|
||||
case MENU_ENUM_LABEL_NO_SETTINGS_FOUND:
|
||||
BIND_ACTION_RIGHT(cbs, action_right_mainmenu);
|
||||
break;
|
||||
@ -1163,6 +1164,7 @@ static int menu_cbs_init_bind_right_compare_label(menu_file_list_cbs_t *cbs,
|
||||
break;
|
||||
case MENU_ENUM_LABEL_NO_ITEMS:
|
||||
case MENU_ENUM_LABEL_NO_PLAYLIST_ENTRIES_AVAILABLE:
|
||||
case MENU_ENUM_LABEL_NO_CORES_AVAILABLE:
|
||||
case MENU_ENUM_LABEL_EXPLORE_INITIALISING_LIST:
|
||||
if (
|
||||
string_ends_with_size(menu_label, "_tab",
|
||||
|
@ -693,6 +693,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_goto_images,
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_goto_music, MENU_ENUM_SUBLABEL_GOTO_MUSIC)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_goto_video, MENU_ENUM_SUBLABEL_GOTO_VIDEO)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_goto_explore, MENU_ENUM_SUBLABEL_GOTO_EXPLORE)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_goto_contentless_cores, MENU_ENUM_SUBLABEL_GOTO_CONTENTLESS_CORES)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_filebrowser_settings, MENU_ENUM_SUBLABEL_MENU_FILE_BROWSER_SETTINGS)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_filebrowser_open_uwp_permissions, MENU_ENUM_SUBLABEL_FILE_BROWSER_OPEN_UWP_PERMISSIONS)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_filebrowser_open_picker, MENU_ENUM_SUBLABEL_FILE_BROWSER_OPEN_PICKER)
|
||||
@ -855,6 +856,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_import_content_tab,
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_import_content_entry, MENU_ENUM_SUBLABEL_CONTENT_SHOW_ADD_ENTRY)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_playlist_tabs, MENU_ENUM_SUBLABEL_CONTENT_SHOW_PLAYLISTS)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_explore_tab, MENU_ENUM_SUBLABEL_CONTENT_SHOW_EXPLORE)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_contentless_cores_tab, MENU_ENUM_SUBLABEL_CONTENT_SHOW_CONTENTLESS_CORES)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_main_menu_enable_settings, MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_rgui_show_start_screen, MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_header_opacity, MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY)
|
||||
@ -1968,6 +1970,7 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
{
|
||||
case MENU_ENUM_LABEL_FILE_BROWSER_CORE:
|
||||
case MENU_ENUM_LABEL_CORE_MANAGER_ENTRY:
|
||||
case MENU_ENUM_LABEL_CONTENTLESS_CORE:
|
||||
BIND_ACTION_SUBLABEL(cbs, menu_action_sublabel_file_browser_core);
|
||||
break;
|
||||
#ifdef HAVE_NETWORKING
|
||||
@ -2297,6 +2300,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_CONTENT_SHOW_EXPLORE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_explore_tab);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_CONTENT_SHOW_CONTENTLESS_CORES:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_contentless_cores_tab);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_XMB_MAIN_MENU_ENABLE_SETTINGS:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_main_menu_enable_settings);
|
||||
break;
|
||||
@ -2321,6 +2327,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_GOTO_EXPLORE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_goto_explore);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_GOTO_CONTENTLESS_CORES:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_goto_contentless_cores);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_GOTO_FAVORITES:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_goto_favorites);
|
||||
break;
|
||||
|
@ -754,6 +754,8 @@ DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_title_deferred_favorites_list, MENU
|
||||
DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_title_deferred_images_list, MENU_ENUM_LABEL_VALUE_GOTO_IMAGES)
|
||||
DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_title_deferred_music_list, MENU_ENUM_LABEL_VALUE_GOTO_MUSIC)
|
||||
DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_title_deferred_video_list, MENU_ENUM_LABEL_VALUE_GOTO_VIDEO)
|
||||
DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_title_deferred_contentless_cores_list, MENU_ENUM_LABEL_VALUE_GOTO_CONTENTLESS_CORES)
|
||||
|
||||
DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_core_updater_list, MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST)
|
||||
DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_core_manager_list, MENU_ENUM_LABEL_VALUE_CORE_MANAGER_LIST)
|
||||
DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_core_cheat_options_list, MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS)
|
||||
@ -853,18 +855,19 @@ static int action_get_title_group_settings(const char *path, const char *label,
|
||||
* tab, but its actual title is set elsewhere - so treat
|
||||
* it as a generic top-level item */
|
||||
title_info_list_t info_list[] = {
|
||||
{MENU_ENUM_LABEL_MAIN_MENU, MENU_ENUM_LABEL_VALUE_MAIN_MENU, false },
|
||||
{MENU_ENUM_LABEL_HISTORY_TAB, MENU_ENUM_LABEL_VALUE_HISTORY_TAB, true },
|
||||
{MENU_ENUM_LABEL_FAVORITES_TAB, MENU_ENUM_LABEL_VALUE_FAVORITES_TAB, true },
|
||||
{MENU_ENUM_LABEL_IMAGES_TAB, MENU_ENUM_LABEL_VALUE_IMAGES_TAB, true },
|
||||
{MENU_ENUM_LABEL_MUSIC_TAB, MENU_ENUM_LABEL_VALUE_MUSIC_TAB, true },
|
||||
{MENU_ENUM_LABEL_VIDEO_TAB, MENU_ENUM_LABEL_VALUE_VIDEO_TAB, true },
|
||||
{MENU_ENUM_LABEL_SETTINGS_TAB, MENU_ENUM_LABEL_VALUE_SETTINGS_TAB, false },
|
||||
{MENU_ENUM_LABEL_PLAYLISTS_TAB, MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, false },
|
||||
{MENU_ENUM_LABEL_ADD_TAB, MENU_ENUM_LABEL_VALUE_ADD_TAB, false },
|
||||
{MENU_ENUM_LABEL_EXPLORE_TAB, MENU_ENUM_LABEL_VALUE_EXPLORE_TAB, false },
|
||||
{MENU_ENUM_LABEL_NETPLAY_TAB, MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, false },
|
||||
{MENU_ENUM_LABEL_HORIZONTAL_MENU, MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, false },
|
||||
{MENU_ENUM_LABEL_MAIN_MENU, MENU_ENUM_LABEL_VALUE_MAIN_MENU, false },
|
||||
{MENU_ENUM_LABEL_HISTORY_TAB, MENU_ENUM_LABEL_VALUE_HISTORY_TAB, true },
|
||||
{MENU_ENUM_LABEL_FAVORITES_TAB, MENU_ENUM_LABEL_VALUE_FAVORITES_TAB, true },
|
||||
{MENU_ENUM_LABEL_IMAGES_TAB, MENU_ENUM_LABEL_VALUE_IMAGES_TAB, true },
|
||||
{MENU_ENUM_LABEL_MUSIC_TAB, MENU_ENUM_LABEL_VALUE_MUSIC_TAB, true },
|
||||
{MENU_ENUM_LABEL_VIDEO_TAB, MENU_ENUM_LABEL_VALUE_VIDEO_TAB, true },
|
||||
{MENU_ENUM_LABEL_SETTINGS_TAB, MENU_ENUM_LABEL_VALUE_SETTINGS_TAB, false },
|
||||
{MENU_ENUM_LABEL_PLAYLISTS_TAB, MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, false },
|
||||
{MENU_ENUM_LABEL_ADD_TAB, MENU_ENUM_LABEL_VALUE_ADD_TAB, false },
|
||||
{MENU_ENUM_LABEL_EXPLORE_TAB, MENU_ENUM_LABEL_VALUE_EXPLORE_TAB, false },
|
||||
{MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB, MENU_ENUM_LABEL_VALUE_CONTENTLESS_CORES_TAB, false },
|
||||
{MENU_ENUM_LABEL_NETPLAY_TAB, MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, false },
|
||||
{MENU_ENUM_LABEL_HORIZONTAL_MENU, MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, false },
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(info_list); i++)
|
||||
@ -989,6 +992,7 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs,
|
||||
{MENU_ENUM_LABEL_DEFERRED_IMAGES_LIST, action_get_title_deferred_images_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_MUSIC_LIST, action_get_title_deferred_music_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_VIDEO_LIST, action_get_title_deferred_video_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_CONTENTLESS_CORES_LIST, action_get_title_deferred_contentless_cores_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_DRIVER_SETTINGS_LIST, action_get_driver_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_AUDIO_SETTINGS_LIST, action_get_audio_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_AUDIO_RESAMPLER_SETTINGS_LIST, action_get_audio_resampler_settings_list},
|
||||
|
@ -1303,7 +1303,8 @@ enum materialui_node_icon_type
|
||||
MUI_ICON_TYPE_NONE = 0,
|
||||
MUI_ICON_TYPE_INTERNAL,
|
||||
MUI_ICON_TYPE_MENU_EXPLORE,
|
||||
MUI_ICON_TYPE_PLAYLIST
|
||||
MUI_ICON_TYPE_PLAYLIST,
|
||||
MUI_ICON_TYPE_MENU_CONTENTLESS_CORE
|
||||
};
|
||||
|
||||
/* This structure holds auxiliary information for
|
||||
@ -2797,6 +2798,7 @@ static void materialui_compute_entries_box_default(
|
||||
has_icon = mui->textures.list[node->icon_texture_index] != 0;
|
||||
break;
|
||||
case MUI_ICON_TYPE_MENU_EXPLORE:
|
||||
case MUI_ICON_TYPE_MENU_CONTENTLESS_CORE:
|
||||
has_icon = true;
|
||||
break;
|
||||
case MUI_ICON_TYPE_PLAYLIST:
|
||||
@ -3996,6 +3998,9 @@ static void materialui_render_menu_entry_default(
|
||||
case MUI_ICON_TYPE_MENU_EXPLORE:
|
||||
icon_texture = menu_explore_get_entry_icon(entry_type);
|
||||
break;
|
||||
case MUI_ICON_TYPE_MENU_CONTENTLESS_CORE:
|
||||
icon_texture = menu_contentless_cores_get_entry_icon(entry->label);
|
||||
break;
|
||||
case MUI_ICON_TYPE_PLAYLIST:
|
||||
icon_texture = materialui_get_playlist_icon(
|
||||
mui, node->icon_texture_index);
|
||||
@ -10105,6 +10110,7 @@ static void materialui_list_insert(
|
||||
case MENU_SETTING_ACTION_CORE_MANAGER_OPTIONS:
|
||||
case MENU_SETTING_ACTION_CORE_LOCK:
|
||||
case MENU_EXPLORE_TAB:
|
||||
case MENU_CONTENTLESS_CORES_TAB:
|
||||
node->icon_texture_index = MUI_TEXTURE_CORES;
|
||||
node->icon_type = MUI_ICON_TYPE_INTERNAL;
|
||||
break;
|
||||
@ -10189,6 +10195,9 @@ static void materialui_list_insert(
|
||||
node->icon_texture_index = MUI_TEXTURE_FILE;
|
||||
node->icon_type = MUI_ICON_TYPE_INTERNAL;
|
||||
break;
|
||||
case MENU_SETTING_ACTION_CONTENTLESS_CORE_RUN:
|
||||
node->icon_type = MUI_ICON_TYPE_MENU_CONTENTLESS_CORE;
|
||||
break;
|
||||
case FILE_TYPE_RPL_ENTRY:
|
||||
case MENU_SETTING_DROPDOWN_ITEM:
|
||||
case MENU_SETTING_DROPDOWN_ITEM_RESOLUTION:
|
||||
|
@ -144,6 +144,7 @@ enum
|
||||
#if defined(HAVE_LIBRETRODB)
|
||||
OZONE_SYSTEM_TAB_EXPLORE,
|
||||
#endif
|
||||
OZONE_SYSTEM_TAB_CONTENTLESS_CORES,
|
||||
|
||||
/* End of this enum - use the last one to determine num of possible tabs */
|
||||
OZONE_SYSTEM_TAB_LAST
|
||||
@ -181,6 +182,8 @@ enum OZONE_TAB_TEXTURES
|
||||
OZONE_TAB_TEXTURE_IMAGE,
|
||||
OZONE_TAB_TEXTURE_NETWORK,
|
||||
OZONE_TAB_TEXTURE_SCAN_CONTENT,
|
||||
OZONE_TAB_TEXTURE_EXPLORE,
|
||||
OZONE_TAB_TEXTURE_CONTENTLESS_CORES,
|
||||
|
||||
OZONE_TAB_TEXTURE_LAST
|
||||
};
|
||||
@ -570,6 +573,7 @@ struct ozone_handle
|
||||
bool is_db_manager_list;
|
||||
bool is_file_list;
|
||||
bool is_quick_menu;
|
||||
bool is_contentless_cores;
|
||||
bool first_frame;
|
||||
|
||||
struct
|
||||
@ -604,15 +608,17 @@ static const char *OZONE_TEXTURES_FILES[OZONE_TEXTURE_LAST] = {
|
||||
};
|
||||
|
||||
static const char *OZONE_TAB_TEXTURES_FILES[OZONE_TAB_TEXTURE_LAST] = {
|
||||
"retroarch",
|
||||
"settings",
|
||||
"history",
|
||||
"favorites",
|
||||
"music",
|
||||
"video",
|
||||
"image",
|
||||
"netplay",
|
||||
"add"
|
||||
"retroarch", /* MAIN_MENU */
|
||||
"settings", /* SETTINGS_TAB */
|
||||
"history", /* HISTORY_TAB */
|
||||
"favorites", /* FAVORITES_TAB */
|
||||
"music", /* MUSIC_TAB */
|
||||
"video", /* VIDEO_TAB */
|
||||
"image", /* IMAGES_TAB */
|
||||
"netplay", /* NETPLAY_TAB */
|
||||
"add", /* ADD_TAB */
|
||||
"retroarch", /* EXPLORE_TAB */
|
||||
"retroarch" /* CONTENTLESS_CORES_TAB */
|
||||
};
|
||||
|
||||
static const enum msg_hash_enums ozone_system_tabs_value[OZONE_SYSTEM_TAB_LAST] = {
|
||||
@ -630,12 +636,11 @@ static const enum msg_hash_enums ozone_system_tabs_value[OZONE_SYSTEM_TAB_LAST]
|
||||
#ifdef HAVE_NETWORKING
|
||||
MENU_ENUM_LABEL_VALUE_NETPLAY_TAB,
|
||||
#endif
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
MENU_ENUM_LABEL_VALUE_ADD_TAB,
|
||||
MENU_ENUM_LABEL_VALUE_EXPLORE_TAB
|
||||
#else
|
||||
MENU_ENUM_LABEL_VALUE_ADD_TAB
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
MENU_ENUM_LABEL_VALUE_EXPLORE_TAB,
|
||||
#endif
|
||||
MENU_ENUM_LABEL_VALUE_CONTENTLESS_CORES_TAB
|
||||
};
|
||||
|
||||
static const enum menu_settings_type ozone_system_tabs_type[OZONE_SYSTEM_TAB_LAST] = {
|
||||
@ -653,12 +658,11 @@ static const enum menu_settings_type ozone_system_tabs_type[OZONE_SYSTEM_TAB_LAS
|
||||
#ifdef HAVE_NETWORKING
|
||||
MENU_NETPLAY_TAB,
|
||||
#endif
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
MENU_ADD_TAB,
|
||||
MENU_EXPLORE_TAB
|
||||
#else
|
||||
MENU_ADD_TAB
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
MENU_EXPLORE_TAB,
|
||||
#endif
|
||||
MENU_CONTENTLESS_CORES_TAB
|
||||
};
|
||||
|
||||
static const enum msg_hash_enums ozone_system_tabs_idx[OZONE_SYSTEM_TAB_LAST] = {
|
||||
@ -676,12 +680,11 @@ static const enum msg_hash_enums ozone_system_tabs_idx[OZONE_SYSTEM_TAB_LAST] =
|
||||
#ifdef HAVE_NETWORKING
|
||||
MENU_ENUM_LABEL_NETPLAY_TAB,
|
||||
#endif
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
MENU_ENUM_LABEL_ADD_TAB,
|
||||
MENU_ENUM_LABEL_EXPLORE_TAB
|
||||
#else
|
||||
MENU_ENUM_LABEL_ADD_TAB
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
MENU_ENUM_LABEL_EXPLORE_TAB,
|
||||
#endif
|
||||
MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB
|
||||
};
|
||||
|
||||
static const unsigned ozone_system_tabs_icons[OZONE_SYSTEM_TAB_LAST] = {
|
||||
@ -699,7 +702,11 @@ static const unsigned ozone_system_tabs_icons[OZONE_SYSTEM_TAB_LAST] = {
|
||||
#ifdef HAVE_NETWORKING
|
||||
OZONE_TAB_TEXTURE_NETWORK,
|
||||
#endif
|
||||
OZONE_TAB_TEXTURE_SCAN_CONTENT
|
||||
OZONE_TAB_TEXTURE_SCAN_CONTENT,
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
OZONE_TAB_TEXTURE_EXPLORE,
|
||||
#endif
|
||||
OZONE_TAB_TEXTURE_CONTENTLESS_CORES
|
||||
};
|
||||
|
||||
static const char *OZONE_THEME_TEXTURES_FILES[OZONE_THEME_TEXTURE_LAST] = {
|
||||
@ -1597,7 +1604,7 @@ static void ozone_set_background_running_opacity(
|
||||
|
||||
static uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone,
|
||||
enum msg_hash_enums enum_idx, const char *enum_path,
|
||||
unsigned type, bool active)
|
||||
const char *enum_label, unsigned type, bool active)
|
||||
{
|
||||
switch (enum_idx)
|
||||
{
|
||||
@ -1675,6 +1682,8 @@ static uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone,
|
||||
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_MUSIC];
|
||||
case MENU_ENUM_LABEL_GOTO_EXPLORE:
|
||||
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_RDB];
|
||||
case MENU_ENUM_LABEL_GOTO_CONTENTLESS_CORES:
|
||||
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_CORE];
|
||||
|
||||
/* Menu icons */
|
||||
case MENU_ENUM_LABEL_CONTENT_SETTINGS:
|
||||
@ -1735,6 +1744,8 @@ static uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone,
|
||||
case MENU_ENUM_LABEL_UPDATE_DATABASES:
|
||||
case MENU_ENUM_LABEL_DATABASE_MANAGER_LIST:
|
||||
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_RDB];
|
||||
case MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB:
|
||||
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_CORE];
|
||||
case MENU_ENUM_LABEL_CURSOR_MANAGER_LIST:
|
||||
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_CURSOR];
|
||||
case MENU_ENUM_LABEL_HELP_LIST:
|
||||
@ -1930,6 +1941,12 @@ static uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone,
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case MENU_ENUM_LABEL_CONTENTLESS_CORE:
|
||||
{
|
||||
uintptr_t icon = menu_contentless_cores_get_entry_icon(enum_label);
|
||||
if (icon) return icon;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -3288,6 +3305,7 @@ static bool ozone_is_playlist(ozone_handle_t *ozone, bool depth)
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
case OZONE_SYSTEM_TAB_EXPLORE:
|
||||
#endif
|
||||
case OZONE_SYSTEM_TAB_CONTENTLESS_CORES:
|
||||
is_playlist = false;
|
||||
break;
|
||||
case OZONE_SYSTEM_TAB_HISTORY:
|
||||
@ -4490,7 +4508,7 @@ static void ozone_compute_entries_position(
|
||||
if (ozone->is_playlist && entries_end == 1)
|
||||
{
|
||||
uintptr_t tex = ozone_entries_icon_get_texture(ozone,
|
||||
entry.enum_idx, entry.path, entry.type, false);
|
||||
entry.enum_idx, entry.path, entry.label, entry.type, false);
|
||||
ozone->empty_playlist = tex == ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_CORE_INFO];
|
||||
}
|
||||
else
|
||||
@ -4783,7 +4801,7 @@ border_iterate:
|
||||
|
||||
MENU_ENTRY_INIT(entry);
|
||||
entry.path_enabled = false;
|
||||
entry.label_enabled = false;
|
||||
entry.label_enabled = ozone->is_contentless_cores;
|
||||
menu_entry_get(&entry, 0, (unsigned)i, selection_buf, true);
|
||||
|
||||
if (entry.enum_idx == MENU_ENUM_LABEL_CHEEVOS_PASSWORD)
|
||||
@ -4856,7 +4874,7 @@ border_iterate:
|
||||
|
||||
/* Icon */
|
||||
tex = ozone_entries_icon_get_texture(ozone,
|
||||
entry.enum_idx, entry.path, entry.type, entry_selected);
|
||||
entry.enum_idx, entry.path, entry.label, entry.type, entry_selected);
|
||||
if (tex != ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_SUBSETTING])
|
||||
{
|
||||
uintptr_t texture = tex;
|
||||
@ -7150,6 +7168,12 @@ static void *ozone_init(void **userdata, bool video_is_threaded)
|
||||
ozone->tabs[++ozone->system_tab_end] = OZONE_SYSTEM_TAB_EXPLORE;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DYNAMIC)
|
||||
if (settings->uints.menu_content_show_contentless_cores !=
|
||||
MENU_CONTENTLESS_CORES_DISPLAY_NONE)
|
||||
ozone->tabs[++ozone->system_tab_end] = OZONE_SYSTEM_TAB_CONTENTLESS_CORES;
|
||||
#endif
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_UNSET_PREVENT_POPULATE, NULL);
|
||||
|
||||
gfx_display_set_width(width);
|
||||
@ -9844,14 +9868,16 @@ static void ozone_populate_entries(void *data,
|
||||
|
||||
new_depth = (int)ozone_list_get_size(ozone, MENU_LIST_PLAIN);
|
||||
|
||||
animate = new_depth != ozone->depth;
|
||||
ozone->fade_direction = new_depth <= ozone->depth;
|
||||
ozone->depth = new_depth;
|
||||
ozone->is_playlist = ozone_is_playlist(ozone, true);
|
||||
ozone->is_db_manager_list = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DATABASE_MANAGER_LIST));
|
||||
ozone->is_file_list = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_FAVORITES));
|
||||
ozone->is_quick_menu = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_SETTINGS));
|
||||
animate = new_depth != ozone->depth;
|
||||
ozone->fade_direction = new_depth <= ozone->depth;
|
||||
ozone->depth = new_depth;
|
||||
ozone->is_playlist = ozone_is_playlist(ozone, true);
|
||||
ozone->is_db_manager_list = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DATABASE_MANAGER_LIST));
|
||||
ozone->is_file_list = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_FAVORITES));
|
||||
ozone->is_quick_menu = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_SETTINGS));
|
||||
ozone->is_contentless_cores = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CONTENTLESS_CORES_LIST));
|
||||
|
||||
if (animate)
|
||||
if (ozone->categories_selection_ptr == ozone->categories_active_idx_old)
|
||||
|
@ -248,6 +248,7 @@ enum
|
||||
#if defined(HAVE_LIBRETRODB)
|
||||
XMB_SYSTEM_TAB_EXPLORE,
|
||||
#endif
|
||||
XMB_SYSTEM_TAB_CONTENTLESS_CORES,
|
||||
|
||||
/* End of this enum - use the last one to determine num of possible tabs */
|
||||
XMB_SYSTEM_TAB_MAX_LENGTH
|
||||
@ -294,6 +295,7 @@ typedef struct xmb_handle
|
||||
#if defined(HAVE_LIBRETRODB)
|
||||
xmb_node_t explore_tab_node;
|
||||
#endif
|
||||
xmb_node_t contentless_cores_tab_node;
|
||||
xmb_node_t netplay_tab_node;
|
||||
menu_input_pointer_t pointer;
|
||||
|
||||
@ -399,6 +401,7 @@ typedef struct xmb_handle
|
||||
/* Favorites, History, Images, Music, Videos, user generated */
|
||||
bool is_playlist;
|
||||
bool is_db_manager_list;
|
||||
bool is_contentless_cores;
|
||||
|
||||
/* Load Content file browser */
|
||||
bool is_file_list;
|
||||
@ -1978,6 +1981,8 @@ static xmb_node_t* xmb_get_node(xmb_handle_t *xmb, unsigned i)
|
||||
case XMB_SYSTEM_TAB_EXPLORE:
|
||||
return &xmb->explore_tab_node;
|
||||
#endif
|
||||
case XMB_SYSTEM_TAB_CONTENTLESS_CORES:
|
||||
return &xmb->contentless_cores_tab_node;
|
||||
default:
|
||||
if (i > xmb->system_tab_end)
|
||||
return xmb_get_userdata_from_horizontal_list(
|
||||
@ -2472,6 +2477,10 @@ static void xmb_populate_entries(void *data,
|
||||
/* Determine whether this is a database manager list */
|
||||
xmb->is_db_manager_list = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DATABASE_MANAGER_LIST));
|
||||
|
||||
/* Determine whether this is the contentless cores menu */
|
||||
xmb->is_contentless_cores = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CONTENTLESS_CORES_LIST));
|
||||
|
||||
/* Determine whether this is a 'file list'
|
||||
* (needed for handling thumbnails when viewing images
|
||||
* via 'load content')
|
||||
@ -2539,7 +2548,8 @@ static void xmb_populate_entries(void *data,
|
||||
static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
|
||||
xmb_node_t *core_node, xmb_node_t *node,
|
||||
enum msg_hash_enums enum_idx, const char *enum_path,
|
||||
unsigned type, bool active, bool checked)
|
||||
const char *enum_label, unsigned type, bool active,
|
||||
bool checked)
|
||||
{
|
||||
switch (enum_idx)
|
||||
{
|
||||
@ -2635,7 +2645,8 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
|
||||
return xmb->textures.list[XMB_TEXTURE_MUSIC];
|
||||
case MENU_ENUM_LABEL_GOTO_EXPLORE:
|
||||
return xmb->textures.list[XMB_TEXTURE_MAIN_MENU];
|
||||
|
||||
case MENU_ENUM_LABEL_GOTO_CONTENTLESS_CORES:
|
||||
return xmb->textures.list[XMB_TEXTURE_MAIN_MENU];
|
||||
case MENU_ENUM_LABEL_LOAD_DISC:
|
||||
case MENU_ENUM_LABEL_DUMP_DISC:
|
||||
#ifdef HAVE_LAKKA
|
||||
@ -2865,6 +2876,13 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case MENU_ENUM_LABEL_CONTENTLESS_CORE:
|
||||
{
|
||||
uintptr_t icon = menu_contentless_cores_get_entry_icon(enum_label);
|
||||
if (icon)
|
||||
return icon;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -3224,7 +3242,7 @@ static int xmb_draw_item(
|
||||
return 0;
|
||||
|
||||
MENU_ENTRY_INIT(entry);
|
||||
entry.label_enabled = false;
|
||||
entry.label_enabled = xmb->is_contentless_cores;
|
||||
entry.sublabel_enabled = (i == current);
|
||||
menu_entry_get(&entry, 0, i, list, true);
|
||||
entry_type = entry.type;
|
||||
@ -3582,7 +3600,8 @@ static int xmb_draw_item(
|
||||
math_matrix_4x4 mymat_tmp;
|
||||
gfx_display_ctx_rotate_draw_t rotate_draw;
|
||||
uintptr_t texture = xmb_icon_get_id(xmb, core_node, node,
|
||||
entry.enum_idx, entry.path, entry_type, (i == current), entry.checked);
|
||||
entry.enum_idx, entry.path, entry.label,
|
||||
entry_type, (i == current), entry.checked);
|
||||
float x = icon_x;
|
||||
float y = icon_y;
|
||||
float scale_factor = node->zoom;
|
||||
@ -5933,6 +5952,12 @@ static void *xmb_init(void **userdata, bool video_is_threaded)
|
||||
xmb->tabs[++xmb->system_tab_end] = XMB_SYSTEM_TAB_EXPLORE;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DYNAMIC)
|
||||
if (settings->uints.menu_content_show_contentless_cores !=
|
||||
MENU_CONTENTLESS_CORES_DISPLAY_NONE)
|
||||
xmb->tabs[++xmb->system_tab_end] = XMB_SYSTEM_TAB_CONTENTLESS_CORES;
|
||||
#endif
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_UNSET_PREVENT_POPULATE, NULL);
|
||||
|
||||
/* TODO/FIXME - we don't use framebuffer at all
|
||||
@ -6410,6 +6435,10 @@ static void xmb_context_reset_textures(
|
||||
xmb->explore_tab_node.zoom = xmb->categories_active_zoom;
|
||||
#endif
|
||||
|
||||
xmb->contentless_cores_tab_node.icon = xmb->textures.list[XMB_TEXTURE_MAIN_MENU];
|
||||
xmb->contentless_cores_tab_node.alpha = xmb->categories_active_alpha;
|
||||
xmb->contentless_cores_tab_node.zoom = xmb->categories_active_zoom;
|
||||
|
||||
#ifdef HAVE_NETWORKING
|
||||
xmb->netplay_tab_node.icon = xmb->textures.list[XMB_TEXTURE_NETPLAY];
|
||||
xmb->netplay_tab_node.alpha = xmb->categories_active_alpha;
|
||||
@ -6871,6 +6900,12 @@ static void xmb_list_cache(void *data, enum menu_list_type type, unsigned action
|
||||
MENU_EXPLORE_TAB;
|
||||
break;
|
||||
#endif
|
||||
case XMB_SYSTEM_TAB_CONTENTLESS_CORES:
|
||||
menu_stack->list[stack_size - 1].label =
|
||||
strdup(msg_hash_to_str(MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB));
|
||||
menu_stack->list[stack_size - 1].type =
|
||||
MENU_CONTENTLESS_CORES_TAB;
|
||||
break;
|
||||
default:
|
||||
menu_stack->list[stack_size - 1].label =
|
||||
strdup(msg_hash_to_str(MENU_ENUM_LABEL_HORIZONTAL_MENU));
|
||||
|
@ -77,6 +77,7 @@ enum
|
||||
ACTION_OK_DL_IMAGES_LIST,
|
||||
ACTION_OK_DL_VIDEO_LIST,
|
||||
ACTION_OK_DL_EXPLORE_LIST,
|
||||
ACTION_OK_DL_CONTENTLESS_CORES_LIST,
|
||||
ACTION_OK_DL_MUSIC_LIST,
|
||||
ACTION_OK_DL_SHADER_PARAMETERS,
|
||||
ACTION_OK_DL_SHADER_PRESET,
|
||||
|
302
menu/menu_contentless_cores.c
Normal file
302
menu/menu_contentless_cores.c
Normal file
@ -0,0 +1,302 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2020 - Daniel De Matteis
|
||||
* Copyright (C) 2019-2022 - James Leaver
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <compat/strcasestr.h>
|
||||
#include <compat/strl.h>
|
||||
#include <array/rhmap.h>
|
||||
#include <file/file_path.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include "menu_driver.h"
|
||||
#include "menu_displaylist.h"
|
||||
#include "../retroarch.h"
|
||||
#include "../core_info.h"
|
||||
#include "../configuration.h"
|
||||
|
||||
#define CONTENTLESS_CORE_ICON_DEFAULT "default.png"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uintptr_t **system;
|
||||
uintptr_t fallback;
|
||||
} contentless_core_icons_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
contentless_core_icons_t *icons;
|
||||
bool icons_enabled;
|
||||
} contentless_cores_state_t;
|
||||
|
||||
static contentless_cores_state_t *contentless_cores_state = NULL;
|
||||
|
||||
static void contentless_cores_unload_icons(contentless_cores_state_t *state)
|
||||
{
|
||||
size_t i, cap;
|
||||
|
||||
if (!state || !state->icons)
|
||||
return;
|
||||
|
||||
if (state->icons->fallback)
|
||||
video_driver_texture_unload(&state->icons->fallback);
|
||||
|
||||
for (i = 0, cap = RHMAP_CAP(state->icons->system); i != cap; i++)
|
||||
{
|
||||
if (RHMAP_KEY(state->icons->system, i))
|
||||
{
|
||||
uintptr_t *icon = state->icons->system[i];
|
||||
|
||||
if (!icon)
|
||||
continue;
|
||||
|
||||
video_driver_texture_unload(icon);
|
||||
free(icon);
|
||||
}
|
||||
}
|
||||
|
||||
RHMAP_FREE(state->icons->system);
|
||||
free(state->icons);
|
||||
state->icons = NULL;
|
||||
}
|
||||
|
||||
static void contentless_cores_load_icons(contentless_cores_state_t *state)
|
||||
{
|
||||
bool rgba_supported = video_driver_supports_rgba();
|
||||
core_info_list_t *core_info_list = NULL;
|
||||
char icon_directory[PATH_MAX_LENGTH];
|
||||
char icon_path[PATH_MAX_LENGTH];
|
||||
size_t i;
|
||||
|
||||
icon_directory[0] = '\0';
|
||||
icon_path[0] = '\0';
|
||||
|
||||
if (!state)
|
||||
return;
|
||||
|
||||
/* Unload any existing icons */
|
||||
contentless_cores_unload_icons(state);
|
||||
|
||||
if (!state->icons_enabled)
|
||||
return;
|
||||
|
||||
/* Create new icon container */
|
||||
state->icons = (contentless_core_icons_t*)calloc(
|
||||
1, sizeof(*state->icons));
|
||||
|
||||
/* Get icon directory */
|
||||
fill_pathname_application_special(icon_directory,
|
||||
sizeof(icon_directory),
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_SYSICONS);
|
||||
|
||||
if (string_is_empty(icon_directory))
|
||||
return;
|
||||
|
||||
/* Load fallback icon */
|
||||
fill_pathname_join(icon_path, icon_directory,
|
||||
CONTENTLESS_CORE_ICON_DEFAULT, sizeof(icon_path));
|
||||
|
||||
if (path_is_valid(icon_path))
|
||||
{
|
||||
struct texture_image ti = {0};
|
||||
ti.supports_rgba = rgba_supported;
|
||||
|
||||
if (image_texture_load(&ti, icon_path))
|
||||
{
|
||||
if (ti.pixels)
|
||||
video_driver_texture_load(&ti,
|
||||
TEXTURE_FILTER_MIPMAP_LINEAR,
|
||||
&state->icons->fallback);
|
||||
|
||||
image_texture_free(&ti);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get icons for all contentless cores */
|
||||
core_info_get_list(&core_info_list);
|
||||
|
||||
if (!core_info_list)
|
||||
return;
|
||||
|
||||
for (i = 0; i < core_info_list->count; i++)
|
||||
{
|
||||
core_info_t *core_info = core_info_get(core_info_list, i);
|
||||
|
||||
/* Icon name is the first entry in the core
|
||||
* info database list */
|
||||
if (core_info &&
|
||||
core_info->supports_no_game &&
|
||||
core_info->databases_list &&
|
||||
(core_info->databases_list->size > 0))
|
||||
{
|
||||
const char *icon_name =
|
||||
core_info->databases_list->elems[0].data;
|
||||
struct texture_image ti = {0};
|
||||
ti.supports_rgba = rgba_supported;
|
||||
|
||||
fill_pathname_join(icon_path, icon_directory,
|
||||
icon_name, sizeof(icon_path));
|
||||
strlcat(icon_path, ".png", sizeof(icon_path));
|
||||
|
||||
if (!path_is_valid(icon_path))
|
||||
continue;
|
||||
|
||||
if (image_texture_load(&ti, icon_path))
|
||||
{
|
||||
if (ti.pixels)
|
||||
{
|
||||
uintptr_t *icon = (uintptr_t*)calloc(1, sizeof(*icon));
|
||||
|
||||
video_driver_texture_load(&ti,
|
||||
TEXTURE_FILTER_MIPMAP_LINEAR,
|
||||
icon);
|
||||
|
||||
/* Add icon to hash map */
|
||||
RHMAP_SET_STR(state->icons->system, core_info->core_file_id.str, icon);
|
||||
}
|
||||
|
||||
image_texture_free(&ti);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t menu_contentless_cores_get_entry_icon(const char *core_id)
|
||||
{
|
||||
contentless_cores_state_t *state = contentless_cores_state;
|
||||
uintptr_t *icon = NULL;
|
||||
|
||||
if (!state ||
|
||||
!state->icons_enabled ||
|
||||
!state->icons ||
|
||||
string_is_empty(core_id))
|
||||
return 0;
|
||||
|
||||
icon = RHMAP_GET_STR(state->icons->system, core_id);
|
||||
|
||||
if (icon)
|
||||
return *icon;
|
||||
|
||||
return state->icons->fallback;
|
||||
}
|
||||
|
||||
void menu_contentless_cores_context_init(void)
|
||||
{
|
||||
if (!contentless_cores_state)
|
||||
return;
|
||||
|
||||
contentless_cores_load_icons(contentless_cores_state);
|
||||
}
|
||||
|
||||
void menu_contentless_cores_context_deinit(void)
|
||||
{
|
||||
if (!contentless_cores_state)
|
||||
return;
|
||||
|
||||
contentless_cores_unload_icons(contentless_cores_state);
|
||||
}
|
||||
|
||||
void menu_contentless_cores_free(void)
|
||||
{
|
||||
if (!contentless_cores_state)
|
||||
return;
|
||||
|
||||
contentless_cores_unload_icons(contentless_cores_state);
|
||||
free(contentless_cores_state);
|
||||
contentless_cores_state = NULL;
|
||||
}
|
||||
|
||||
unsigned menu_displaylist_contentless_cores(file_list_t *list, settings_t *settings)
|
||||
{
|
||||
unsigned count = 0;
|
||||
enum menu_contentless_cores_display_type
|
||||
core_display_type = (enum menu_contentless_cores_display_type)
|
||||
settings->uints.menu_content_show_contentless_cores;
|
||||
core_info_list_t *core_info_list = NULL;
|
||||
|
||||
/* Get core list */
|
||||
core_info_get_list(&core_info_list);
|
||||
|
||||
if (core_info_list)
|
||||
{
|
||||
size_t menu_index = 0;
|
||||
size_t i;
|
||||
|
||||
/* Sort cores alphabetically */
|
||||
core_info_qsort(core_info_list, CORE_INFO_LIST_SORT_DISPLAY_NAME);
|
||||
|
||||
/* Loop through cores */
|
||||
for (i = 0; i < core_info_list->count; i++)
|
||||
{
|
||||
core_info_t *core_info = core_info_get(core_info_list, i);
|
||||
bool core_valid = false;
|
||||
|
||||
if (core_info)
|
||||
{
|
||||
switch (core_display_type)
|
||||
{
|
||||
case MENU_CONTENTLESS_CORES_DISPLAY_ALL:
|
||||
core_valid = core_info->supports_no_game;
|
||||
break;
|
||||
case MENU_CONTENTLESS_CORES_DISPLAY_SINGLE_PURPOSE:
|
||||
core_valid = core_info->supports_no_game &&
|
||||
core_info->single_purpose;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (core_valid &&
|
||||
menu_entries_append_enum(list,
|
||||
core_info->path,
|
||||
core_info->core_file_id.str,
|
||||
MENU_ENUM_LABEL_CONTENTLESS_CORE,
|
||||
MENU_SETTING_ACTION_CONTENTLESS_CORE_RUN,
|
||||
0, 0))
|
||||
{
|
||||
file_list_set_alt_at_offset(
|
||||
list, menu_index, core_info->display_name);
|
||||
|
||||
menu_index++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialise icons, if required */
|
||||
if (!contentless_cores_state && (count > 0))
|
||||
{
|
||||
contentless_cores_state = (contentless_cores_state_t*)calloc(1,
|
||||
sizeof(*contentless_cores_state));
|
||||
|
||||
/* Disable icons when using menu drivers without
|
||||
* icon support */
|
||||
contentless_cores_state->icons_enabled =
|
||||
!string_is_equal(menu_driver_ident(), "rgui");
|
||||
|
||||
contentless_cores_load_icons(contentless_cores_state);
|
||||
}
|
||||
|
||||
if ((count == 0) &&
|
||||
menu_entries_append_enum(list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_CORES_AVAILABLE),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_NO_CORES_AVAILABLE),
|
||||
MENU_ENUM_LABEL_NO_CORES_AVAILABLE,
|
||||
0, 0, 0))
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
@ -130,6 +130,16 @@ enum menu_add_content_entry_display_type
|
||||
MENU_ADD_CONTENT_ENTRY_DISPLAY_LAST
|
||||
};
|
||||
|
||||
/* Specifies which type of core will be displayed
|
||||
* in the 'contentless cores' menu */
|
||||
enum menu_contentless_cores_display_type
|
||||
{
|
||||
MENU_CONTENTLESS_CORES_DISPLAY_NONE = 0,
|
||||
MENU_CONTENTLESS_CORES_DISPLAY_ALL,
|
||||
MENU_CONTENTLESS_CORES_DISPLAY_SINGLE_PURPOSE,
|
||||
MENU_CONTENTLESS_CORES_DISPLAY_LAST
|
||||
};
|
||||
|
||||
enum rgui_color_theme
|
||||
{
|
||||
RGUI_THEME_CUSTOM = 0,
|
||||
|
@ -3586,6 +3586,17 @@ static unsigned menu_displaylist_parse_playlists(
|
||||
MENU_EXPLORE_TAB, 0, 0))
|
||||
count++;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DYNAMIC)
|
||||
if (settings->uints.menu_content_show_contentless_cores !=
|
||||
MENU_CONTENTLESS_CORES_DISPLAY_NONE)
|
||||
if (menu_entries_append_enum(info->list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_CONTENTLESS_CORES),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_GOTO_CONTENTLESS_CORES),
|
||||
MENU_ENUM_LABEL_GOTO_CONTENTLESS_CORES,
|
||||
MENU_CONTENTLESS_CORES_TAB, 0, 0))
|
||||
count++;
|
||||
#endif
|
||||
if (settings->bools.menu_content_show_favorites)
|
||||
if (menu_entries_append_enum(info->list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES),
|
||||
@ -6321,6 +6332,17 @@ unsigned menu_displaylist_build_list(
|
||||
MENU_EXPLORE_TAB, 0, 0))
|
||||
count++;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DYNAMIC)
|
||||
if (settings->uints.menu_content_show_contentless_cores !=
|
||||
MENU_CONTENTLESS_CORES_DISPLAY_NONE)
|
||||
if (menu_entries_append_enum(list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_CONTENTLESS_CORES),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_GOTO_CONTENTLESS_CORES),
|
||||
MENU_ENUM_LABEL_GOTO_CONTENTLESS_CORES,
|
||||
MENU_CONTENTLESS_CORES_TAB, 0, 0))
|
||||
count++;
|
||||
#endif
|
||||
if (menu_content_show_favorites)
|
||||
if (menu_entries_append_enum(list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES),
|
||||
@ -8268,6 +8290,9 @@ unsigned menu_displaylist_build_list(
|
||||
{MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS, PARSE_ONLY_BOOL, true },
|
||||
{MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS_PASSWORD, PARSE_ONLY_STRING, true},
|
||||
{MENU_ENUM_LABEL_CONTENT_SHOW_EXPLORE, PARSE_ONLY_BOOL, true },
|
||||
#if defined(HAVE_DYNAMIC)
|
||||
{MENU_ENUM_LABEL_CONTENT_SHOW_CONTENTLESS_CORES, PARSE_ONLY_UINT, true },
|
||||
#endif
|
||||
{MENU_ENUM_LABEL_CONTENT_SHOW_FAVORITES, PARSE_ONLY_BOOL, true },
|
||||
{MENU_ENUM_LABEL_CONTENT_SHOW_IMAGES, PARSE_ONLY_BOOL, true },
|
||||
{MENU_ENUM_LABEL_CONTENT_SHOW_MUSIC, PARSE_ONLY_BOOL, true },
|
||||
@ -8288,6 +8313,9 @@ unsigned menu_displaylist_build_list(
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(build_list); i++)
|
||||
{
|
||||
if (!build_list[i].checked && !include_everything)
|
||||
continue;
|
||||
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
|
||||
build_list[i].enum_idx, build_list[i].parse_type,
|
||||
false) == 0)
|
||||
@ -11687,6 +11715,30 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
||||
info->need_push = true;
|
||||
}
|
||||
break;
|
||||
case DISPLAYLIST_CONTENTLESS_CORES:
|
||||
{
|
||||
size_t contentless_core_ptr =
|
||||
menu_state_get_ptr()->contentless_core_ptr;
|
||||
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
|
||||
count = menu_displaylist_contentless_cores(info->list, settings);
|
||||
|
||||
/* TODO/FIXME: Selecting an entry in the
|
||||
* contentless cores list will cause the
|
||||
* quick menu to be pushed on the subsequent
|
||||
* frame via the RARCH_MENU_CTL_SET_PENDING_QUICK_MENU
|
||||
* command. The way this is implemented 'breaks' the
|
||||
* menu stack record, so when leaving the quick
|
||||
* menu via a 'cancel' operation, the last selected
|
||||
* menu index is lost. We therefore have to apply
|
||||
* a cached index value after rebuilding the list... */
|
||||
if (contentless_core_ptr < count)
|
||||
menu_navigation_set_selection(contentless_core_ptr);
|
||||
|
||||
info->need_sort = false;
|
||||
info->need_push = true;
|
||||
}
|
||||
break;
|
||||
case DISPLAYLIST_CORE_OPTIONS:
|
||||
{
|
||||
/* Number of displayed options is dynamic. If user opens
|
||||
|
@ -83,6 +83,7 @@ enum menu_displaylist_ctl_state
|
||||
DISPLAYLIST_HORIZONTAL_CONTENT_ACTIONS,
|
||||
DISPLAYLIST_HISTORY,
|
||||
DISPLAYLIST_EXPLORE,
|
||||
DISPLAYLIST_CONTENTLESS_CORES,
|
||||
DISPLAYLIST_FAVORITES,
|
||||
DISPLAYLIST_PLAYLIST,
|
||||
DISPLAYLIST_VIDEO_HISTORY,
|
||||
@ -344,6 +345,7 @@ bool menu_displaylist_has_subsystems(void);
|
||||
#if defined(HAVE_LIBRETRODB)
|
||||
unsigned menu_displaylist_explore(file_list_t *list, settings_t *settings);
|
||||
#endif
|
||||
unsigned menu_displaylist_contentless_cores(file_list_t *list, settings_t *settings);
|
||||
|
||||
enum filebrowser_enums filebrowser_get_type(void);
|
||||
|
||||
|
@ -2334,6 +2334,11 @@ static bool menu_driver_displaylist_push_internal(
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB)))
|
||||
{
|
||||
if (menu_displaylist_ctl(DISPLAYLIST_CONTENTLESS_CORES, info, settings))
|
||||
return true;
|
||||
}
|
||||
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)))
|
||||
{
|
||||
if (menu_displaylist_ctl(DISPLAYLIST_NETPLAY_ROOM_LIST, info, settings))
|
||||
@ -4155,6 +4160,7 @@ int menu_driver_deferred_push_content_list(file_list_t *list)
|
||||
file_list_t *selection_buf = MENU_LIST_GET_SELECTION(menu_list, (unsigned)0);
|
||||
|
||||
menu_st->selection_ptr = 0;
|
||||
menu_st->contentless_core_ptr = 0;
|
||||
|
||||
if (!menu_driver_displaylist_push(
|
||||
menu_st,
|
||||
@ -4518,6 +4524,7 @@ bool menu_entries_append_enum(
|
||||
if ( enum_idx != MENU_ENUM_LABEL_PLAYLIST_ENTRY
|
||||
&& enum_idx != MENU_ENUM_LABEL_PLAYLIST_COLLECTION_ENTRY
|
||||
&& enum_idx != MENU_ENUM_LABEL_EXPLORE_ITEM
|
||||
&& enum_idx != MENU_ENUM_LABEL_CONTENTLESS_CORE
|
||||
&& enum_idx != MENU_ENUM_LABEL_RDB_ENTRY)
|
||||
cbs->setting = menu_setting_find_enum(enum_idx);
|
||||
|
||||
@ -6974,8 +6981,12 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data)
|
||||
switch (state)
|
||||
{
|
||||
case RARCH_MENU_CTL_SET_PENDING_QUICK_MENU:
|
||||
menu_entries_flush_stack(NULL, MENU_SETTINGS);
|
||||
menu_st->pending_quick_menu = true;
|
||||
{
|
||||
bool flush_stack = !data ? true : *((bool *)data);
|
||||
if (flush_stack)
|
||||
menu_entries_flush_stack(NULL, MENU_SETTINGS);
|
||||
menu_st->pending_quick_menu = true;
|
||||
}
|
||||
break;
|
||||
case RARCH_MENU_CTL_SET_PREVENT_POPULATE:
|
||||
menu_st->prevent_populate = true;
|
||||
@ -7000,21 +7011,25 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data)
|
||||
#ifdef HAVE_NETWORKING
|
||||
core_updater_list_free_cached();
|
||||
#endif
|
||||
#if defined(HAVE_MENU) && defined(HAVE_LIBRETRODB)
|
||||
#if defined(HAVE_MENU)
|
||||
#if defined(HAVE_LIBRETRODB)
|
||||
/* Before freeing the explore menu, we
|
||||
* must wait for any explore menu initialisation
|
||||
* tasks to complete */
|
||||
menu_explore_wait_for_init_task();
|
||||
menu_explore_free();
|
||||
#endif
|
||||
menu_contentless_cores_free();
|
||||
#endif
|
||||
|
||||
if (menu_st->driver_data)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
menu_st->scroll.acceleration = 0;
|
||||
menu_st->selection_ptr = 0;
|
||||
menu_st->scroll.index_size = 0;
|
||||
menu_st->scroll.acceleration = 0;
|
||||
menu_st->selection_ptr = 0;
|
||||
menu_st->contentless_core_ptr = 0;
|
||||
menu_st->scroll.index_size = 0;
|
||||
|
||||
for (i = 0; i < SCROLL_INDEX_SIZE; i++)
|
||||
menu_st->scroll.index_list[i] = 0;
|
||||
@ -7517,6 +7532,7 @@ static int generic_menu_iterate(
|
||||
break;
|
||||
#endif
|
||||
case MENU_ENUM_LABEL_CORE_MANAGER_ENTRY:
|
||||
case MENU_ENUM_LABEL_CONTENTLESS_CORE:
|
||||
{
|
||||
core_info_t *core_info = NULL;
|
||||
const char *path = selection_buf->list[selection].path;
|
||||
|
@ -90,6 +90,7 @@ enum menu_settings_type
|
||||
MENU_IMAGES_TAB,
|
||||
MENU_NETPLAY_TAB,
|
||||
MENU_EXPLORE_TAB,
|
||||
MENU_CONTENTLESS_CORES_TAB,
|
||||
MENU_ADD_TAB,
|
||||
MENU_PLAYLISTS_TAB,
|
||||
MENU_SETTING_DROPDOWN_ITEM,
|
||||
@ -268,6 +269,8 @@ enum menu_settings_type
|
||||
MENU_SETTING_ACTION_CORE_OPTIONS_RESET,
|
||||
MENU_SETTING_ACTION_CORE_OPTIONS_FLUSH,
|
||||
|
||||
MENU_SETTING_ACTION_CONTENTLESS_CORE_RUN,
|
||||
|
||||
MENU_SETTINGS_LAST
|
||||
};
|
||||
|
||||
@ -454,6 +457,7 @@ struct menu_state
|
||||
size_t begin;
|
||||
} entries;
|
||||
size_t selection_ptr;
|
||||
size_t contentless_core_ptr;
|
||||
|
||||
/* Quick jumping indices with L/R.
|
||||
* Rebuilt when parsing directory. */
|
||||
@ -635,6 +639,11 @@ void menu_explore_free(void);
|
||||
void menu_explore_set_state(explore_state_t *state);
|
||||
#endif
|
||||
|
||||
uintptr_t menu_contentless_cores_get_entry_icon(const char *core_id);
|
||||
void menu_contentless_cores_context_init(void);
|
||||
void menu_contentless_cores_context_deinit(void);
|
||||
void menu_contentless_cores_free(void);
|
||||
|
||||
/* Returns true if search filter is enabled
|
||||
* for the specified menu list */
|
||||
bool menu_driver_search_filter_enabled(const char *label, unsigned type);
|
||||
|
@ -3674,6 +3674,36 @@ static void setting_get_string_representation_uint_menu_add_content_entry_displa
|
||||
}
|
||||
}
|
||||
|
||||
static void setting_get_string_representation_uint_menu_contentless_cores_display_type(
|
||||
rarch_setting_t *setting,
|
||||
char *s, size_t len)
|
||||
{
|
||||
if (!setting)
|
||||
return;
|
||||
|
||||
switch (*setting->value.target.unsigned_integer)
|
||||
{
|
||||
case MENU_CONTENTLESS_CORES_DISPLAY_NONE:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_OFF),
|
||||
len);
|
||||
break;
|
||||
case MENU_CONTENTLESS_CORES_DISPLAY_ALL:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SHOW_CONTENTLESS_CORES_ALL),
|
||||
len);
|
||||
break;
|
||||
case MENU_CONTENTLESS_CORES_DISPLAY_SINGLE_PURPOSE:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SHOW_CONTENTLESS_CORES_SINGLE_PURPOSE),
|
||||
len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void setting_get_string_representation_uint_rgui_menu_color_theme(
|
||||
rarch_setting_t *setting,
|
||||
char *s, size_t len)
|
||||
@ -16711,6 +16741,23 @@ static bool setting_append_list(
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE);
|
||||
#endif
|
||||
CONFIG_UINT(
|
||||
list, list_info,
|
||||
&settings->uints.menu_content_show_contentless_cores,
|
||||
MENU_ENUM_LABEL_CONTENT_SHOW_CONTENTLESS_CORES,
|
||||
MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_CONTENTLESS_CORES,
|
||||
DEFAULT_MENU_CONTENT_SHOW_CONTENTLESS_CORES,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler);
|
||||
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
|
||||
(*list)[list_info->index - 1].get_string_representation =
|
||||
&setting_get_string_representation_uint_menu_contentless_cores_display_type;
|
||||
menu_settings_list_current_add_range(list, list_info, 0, MENU_CONTENTLESS_CORES_DISPLAY_LAST-1, 1, true, true);
|
||||
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX;
|
||||
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_LAKKA_ADVANCED);
|
||||
|
||||
#ifdef HAVE_MATERIALUI
|
||||
if (string_is_equal(settings->arrays.menu_driver, "glui"))
|
||||
|
@ -1224,6 +1224,9 @@ enum msg_hash_enums
|
||||
MENU_LABEL(CONTENT_SHOW_ADD_ENTRY),
|
||||
MENU_LABEL(CONTENT_SHOW_PLAYLISTS),
|
||||
MENU_LABEL(CONTENT_SHOW_EXPLORE),
|
||||
MENU_LABEL(CONTENT_SHOW_CONTENTLESS_CORES),
|
||||
MENU_ENUM_LABEL_VALUE_SHOW_CONTENTLESS_CORES_ALL,
|
||||
MENU_ENUM_LABEL_VALUE_SHOW_CONTENTLESS_CORES_SINGLE_PURPOSE,
|
||||
MENU_LABEL(XMB_RIBBON_ENABLE),
|
||||
MENU_LABEL(THUMBNAILS),
|
||||
MENU_LABEL(THUMBNAILS_RGUI),
|
||||
@ -1368,6 +1371,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(GOTO_IMAGES),
|
||||
MENU_LABEL(GOTO_VIDEO),
|
||||
MENU_LABEL(GOTO_EXPLORE),
|
||||
MENU_LABEL(GOTO_CONTENTLESS_CORES),
|
||||
MENU_LABEL(ADD_TO_FAVORITES),
|
||||
MENU_LABEL(ADD_TO_FAVORITES_PLAYLIST),
|
||||
MENU_LABEL(SET_CORE_ASSOCIATION),
|
||||
@ -1524,6 +1528,7 @@ enum msg_hash_enums
|
||||
MENU_ENUM_LABEL_DEFERRED_MUSIC_LIST,
|
||||
MENU_ENUM_LABEL_DEFERRED_VIDEO_LIST,
|
||||
MENU_ENUM_LABEL_DEFERRED_EXPLORE_LIST,
|
||||
MENU_ENUM_LABEL_DEFERRED_CONTENTLESS_CORES_LIST,
|
||||
MENU_ENUM_LABEL_DEFERRED_NETPLAY,
|
||||
MENU_ENUM_LABEL_DEFERRED_MUSIC,
|
||||
MENU_ENUM_LABEL_DEFERRED_BROWSE_URL_START,
|
||||
@ -2159,6 +2164,8 @@ enum msg_hash_enums
|
||||
MENU_ENUM_LABEL_EXPLORE_TAB,
|
||||
MENU_ENUM_LABEL_EXPLORE_ITEM,
|
||||
MENU_ENUM_LABEL_VALUE_EXPLORE_TAB,
|
||||
MENU_LABEL(CONTENTLESS_CORES_TAB),
|
||||
MENU_LABEL(CONTENTLESS_CORE),
|
||||
MENU_LABEL(ADD_TAB),
|
||||
MENU_LABEL(NETPLAY_TAB),
|
||||
MENU_LABEL(PLAYLISTS_TAB),
|
||||
|
17
runloop.c
17
runloop.c
@ -6678,13 +6678,20 @@ static enum runloop_state_enum runloop_check_state(
|
||||
|
||||
/* Iterate the menu driver for one frame. */
|
||||
|
||||
/* If the user had requested that the Quick Menu
|
||||
* be spawned during the previous frame, do this now
|
||||
* and exit the function to go to the next frame. */
|
||||
if (menu_st->pending_quick_menu)
|
||||
{
|
||||
/* If the user had requested that the Quick Menu
|
||||
* be spawned during the previous frame, do this now
|
||||
* and exit the function to go to the next frame.
|
||||
*/
|
||||
menu_entries_flush_stack(NULL, MENU_SETTINGS);
|
||||
menu_ctx_list_t list_info;
|
||||
|
||||
/* We are going to push a new menu; ensure
|
||||
* that the current one is cached for animation
|
||||
* purposes */
|
||||
list_info.type = MENU_LIST_PLAIN;
|
||||
list_info.action = 0;
|
||||
menu_driver_list_cache(&list_info);
|
||||
|
||||
p_disp->msg_force = true;
|
||||
|
||||
generic_action_ok_displaylist_push("", NULL,
|
||||
|
@ -2096,8 +2096,14 @@ bool task_push_start_current_core(content_ctx_info_t *content_info)
|
||||
if (firmware_update_status(&content_ctx))
|
||||
goto end;
|
||||
|
||||
/* Loads content into currently selected core. */
|
||||
if (!(ret = content_load(content_info, p_content)))
|
||||
/* Loads content into currently selected core.
|
||||
* Note that 'content_load()' can fail and yet still
|
||||
* return 'true'... In this case, the dummy core
|
||||
* will be loaded; the 'start core' operation can
|
||||
* therefore only be considered successful if the
|
||||
* dummy core is not running following 'content_load()' */
|
||||
if (!(ret = content_load(content_info, p_content)) ||
|
||||
!(ret = (runloop_st->current_core_type != CORE_TYPE_DUMMY)))
|
||||
{
|
||||
if (error_string)
|
||||
{
|
||||
@ -2159,6 +2165,101 @@ bool task_push_load_new_core(
|
||||
}
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
bool task_push_load_contentless_core_from_menu(
|
||||
const char *core_path)
|
||||
{
|
||||
content_ctx_info_t content_info = {0};
|
||||
content_information_ctx_t content_ctx = {0};
|
||||
content_state_t *p_content = content_state_get_ptr();
|
||||
bool ret = true;
|
||||
char *error_string = NULL;
|
||||
runloop_state_t *runloop_st = runloop_state_get_ptr();
|
||||
settings_t *settings = config_get_ptr();
|
||||
const char *path_dir_system = settings->paths.directory_system;
|
||||
bool check_firmware_before_loading = settings->bools.check_firmware_before_loading;
|
||||
bool flush_menu = true;
|
||||
const char *menu_label = NULL;
|
||||
|
||||
if (string_is_empty(core_path))
|
||||
return false;
|
||||
|
||||
content_info.environ_get = menu_content_environment_get;
|
||||
|
||||
content_ctx.check_firmware_before_loading = check_firmware_before_loading;
|
||||
content_ctx.bios_is_missing = retroarch_ctl(RARCH_CTL_IS_MISSING_BIOS, NULL);
|
||||
if (!string_is_empty(path_dir_system))
|
||||
content_ctx.directory_system = strdup(path_dir_system);
|
||||
|
||||
/* Set core path */
|
||||
path_set(RARCH_PATH_CORE, core_path);
|
||||
|
||||
/* Clear content path */
|
||||
path_clear(RARCH_PATH_CONTENT);
|
||||
|
||||
#if defined(HAVE_DYNAMIC)
|
||||
/* Load core */
|
||||
command_event(CMD_EVENT_LOAD_CORE, NULL);
|
||||
|
||||
runloop_set_current_core_type(CORE_TYPE_PLAIN, true);
|
||||
|
||||
if (firmware_update_status(&content_ctx))
|
||||
goto end;
|
||||
|
||||
/* Loads content into currently selected core.
|
||||
* Note that 'content_load()' can fail and yet still
|
||||
* return 'true'... In this case, the dummy core
|
||||
* will be loaded; the 'start core' operation can
|
||||
* therefore only be considered successful if the
|
||||
* dummy core is not running following 'content_load()' */
|
||||
if (!(ret = content_load(&content_info, p_content)) ||
|
||||
!(ret = (runloop_st->current_core_type != CORE_TYPE_DUMMY)))
|
||||
{
|
||||
if (error_string)
|
||||
{
|
||||
runloop_msg_queue_push(error_string, 2, 90,
|
||||
true, NULL, MESSAGE_QUEUE_ICON_DEFAULT,
|
||||
MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
RARCH_ERR("[Content]: %s\n", error_string);
|
||||
free(error_string);
|
||||
}
|
||||
|
||||
retroarch_menu_running();
|
||||
goto end;
|
||||
}
|
||||
#else
|
||||
/* TODO/FIXME: Static builds do not support running
|
||||
* a core directly from the 'command line' without
|
||||
* supplying a content path, so this *will not work*.
|
||||
* In order to support this functionality, the '-L'
|
||||
* command line argument must be enabled for static
|
||||
* builds to inform the frontend that the core should
|
||||
* run automatically on launch. We will leave this
|
||||
* non-functional code here as a place-marker for
|
||||
* future devs who may wish to implement this... */
|
||||
command_event_cmd_exec(p_content,
|
||||
path_get(RARCH_PATH_CONTENT), &content_ctx,
|
||||
false, &error_string);
|
||||
command_event(CMD_EVENT_QUIT, NULL);
|
||||
#endif
|
||||
|
||||
/* Push quick menu onto menu stack */
|
||||
menu_entries_get_last_stack(NULL, &menu_label, NULL, NULL, NULL);
|
||||
|
||||
if (string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB)) ||
|
||||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CONTENTLESS_CORES_LIST)))
|
||||
flush_menu = false;
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_SET_PENDING_QUICK_MENU, &flush_menu);
|
||||
|
||||
#ifdef HAVE_DYNAMIC
|
||||
end:
|
||||
#endif
|
||||
if (content_ctx.directory_system)
|
||||
free(content_ctx.directory_system);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool task_push_load_content_with_new_core_from_menu(
|
||||
const char *core_path,
|
||||
const char *fullpath,
|
||||
|
@ -99,6 +99,9 @@ bool task_push_load_content_from_playlist_from_menu(
|
||||
content_ctx_info_t *content_info,
|
||||
retro_task_callback_t cb,
|
||||
void *user_data);
|
||||
|
||||
bool task_push_load_contentless_core_from_menu(
|
||||
const char *core_path);
|
||||
#endif
|
||||
|
||||
bool task_push_load_content_with_core(
|
||||
|
@ -36,6 +36,10 @@
|
||||
#include "../core_info.h"
|
||||
#include "../core_backup.h"
|
||||
|
||||
#if defined(RARCH_INTERNAL) && defined(HAVE_MENU)
|
||||
#include "../menu/menu_driver.h"
|
||||
#endif
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include "../play_feature_delivery/play_feature_delivery.h"
|
||||
#endif
|
||||
@ -649,6 +653,11 @@ static void cb_task_core_restore(
|
||||
/* Reload core info files
|
||||
* > This must be done on the main thread */
|
||||
command_event(CMD_EVENT_CORE_INFO_INIT, NULL);
|
||||
|
||||
#if defined(RARCH_INTERNAL) && defined(HAVE_MENU)
|
||||
/* Force reload of contentless cores icons */
|
||||
menu_contentless_cores_free();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void task_core_restore_handler(retro_task_t *task)
|
||||
|
@ -45,6 +45,7 @@
|
||||
|
||||
#if defined(RARCH_INTERNAL) && defined(HAVE_MENU)
|
||||
#include "../menu/menu_entries.h"
|
||||
#include "../menu/menu_driver.h"
|
||||
#endif
|
||||
|
||||
/* Get core updater list */
|
||||
@ -521,6 +522,11 @@ static void cb_task_core_updater_download(
|
||||
/* Reload core info files
|
||||
* > This must be done on the main thread */
|
||||
command_event(CMD_EVENT_CORE_INFO_INIT, NULL);
|
||||
|
||||
#if defined(RARCH_INTERNAL) && defined(HAVE_MENU)
|
||||
/* Force reload of contentless cores icons */
|
||||
menu_contentless_cores_free();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void cb_decompress_task_core_updater_download(
|
||||
|
Loading…
Reference in New Issue
Block a user