From 5677799faf95888950742b3518477d6eafa7d379 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 31 Aug 2021 01:27:36 +0200 Subject: [PATCH] Move more code over --- menu/menu_driver.c | 484 +++++++++++++++++++++++++++++++++++++++++++ menu/menu_driver.h | 25 +++ retroarch.c | 496 +-------------------------------------------- 3 files changed, 519 insertions(+), 486 deletions(-) diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 496d7dc44a..f1fa718a2a 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -22,6 +22,7 @@ #include #include "menu_driver.h" +#include "menu_cbs.h" #ifdef HAVE_LANGEXTRA /* This file has a UTF8 BOM, we assume HAVE_LANGEXTRA @@ -1147,6 +1148,489 @@ void menu_entries_settings_deinit(struct menu_state *menu_st) menu_st->entries.list_settings = NULL; } +static bool menu_driver_displaylist_push_internal( + const char *label, + menu_displaylist_info_t *info, + settings_t *settings) +{ + if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HISTORY_TAB))) + { + if (menu_displaylist_ctl(DISPLAYLIST_HISTORY, info, settings)) + return true; + } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_FAVORITES_TAB))) + { + if (menu_displaylist_ctl(DISPLAYLIST_FAVORITES, info, settings)) + return true; + } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_SETTINGS_TAB))) + { + if (menu_displaylist_ctl(DISPLAYLIST_SETTINGS_ALL, info, settings)) + return true; + } +#ifdef HAVE_CHEATS + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS))) + { + if (menu_displaylist_ctl(DISPLAYLIST_CHEAT_SEARCH_SETTINGS_LIST, info, settings)) + return true; + } +#endif + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_MUSIC_TAB))) + { + filebrowser_clear_type(); + info->type = 42; + + if (!string_is_empty(info->exts)) + free(info->exts); + if (!string_is_empty(info->label)) + free(info->label); + + info->exts = strdup("lpl"); + info->label = strdup( + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)); + + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + menu_displaylist_ctl(DISPLAYLIST_MUSIC_HISTORY, info, settings); + return true; + } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_TAB))) + { + filebrowser_clear_type(); + info->type = 42; + + if (!string_is_empty(info->exts)) + free(info->exts); + if (!string_is_empty(info->label)) + free(info->label); + + info->exts = strdup("lpl"); + info->label = strdup( + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)); + + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + menu_displaylist_ctl(DISPLAYLIST_VIDEO_HISTORY, info, settings); + return true; + } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_IMAGES_TAB))) + { + filebrowser_clear_type(); + info->type = 42; + + if (!string_is_empty(info->exts)) + free(info->exts); + if (!string_is_empty(info->label)) + free(info->label); + + info->exts = strdup("lpl"); + info->label = strdup( + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)); + + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + +#if 0 +#ifdef HAVE_SCREENSHOTS + if (!rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL)) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT), + msg_hash_to_str(MENU_ENUM_LABEL_TAKE_SCREENSHOT), + MENU_ENUM_LABEL_TAKE_SCREENSHOT, + MENU_SETTING_ACTION_SCREENSHOT, 0, 0); + else + info->need_push_no_playlist_entries = true; +#endif +#endif + menu_displaylist_ctl(DISPLAYLIST_IMAGES_HISTORY, info, settings); + return true; + } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB))) + { + const char *dir_playlist = settings->paths.directory_playlist; + + filebrowser_clear_type(); + info->type = 42; + + if (!string_is_empty(info->exts)) + free(info->exts); + if (!string_is_empty(info->label)) + free(info->label); + + info->exts = strdup("lpl"); + info->label = strdup( + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)); + + if (string_is_empty(dir_playlist)) + { + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + info->need_refresh = true; + info->need_push_no_playlist_entries = true; + info->need_push = true; + + return true; + } + + if (!string_is_empty(info->path)) + free(info->path); + + info->path = strdup(dir_playlist); + + if (menu_displaylist_ctl( + DISPLAYLIST_DATABASE_PLAYLISTS, info, settings)) + return true; + } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TAB))) + { + if (menu_displaylist_ctl(DISPLAYLIST_SCAN_DIRECTORY_LIST, info, settings)) + return true; + } +#if defined(HAVE_LIBRETRODB) + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_EXPLORE_TAB))) + { + if (menu_displaylist_ctl(DISPLAYLIST_EXPLORE, info, settings)) + return true; + } +#endif + 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)) + return true; + } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HORIZONTAL_MENU))) + { + if (menu_displaylist_ctl(DISPLAYLIST_HORIZONTAL, info, settings)) + return true; + } + + return false; +} + +bool menu_driver_displaylist_push( + struct menu_state *menu_st, + settings_t *settings, + file_list_t *entry_list, + file_list_t *entry_stack) +{ + menu_displaylist_info_t info; + const char *path = NULL; + const char *label = NULL; + unsigned type = 0; + bool ret = false; + enum msg_hash_enums enum_idx = MSG_UNKNOWN; + file_list_t *list = MENU_LIST_GET(menu_st->entries.list, 0); + menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) + list->list[list->size - 1].actiondata; + + menu_displaylist_info_init(&info); + + if (list && list->size) + file_list_get_at_offset(list, list->size - 1, &path, &label, &type, NULL); + + if (cbs) + enum_idx = cbs->enum_idx; + + info.list = entry_list; + info.menu_list = entry_stack; + info.type = type; + info.enum_idx = enum_idx; + + if (!string_is_empty(path)) + info.path = strdup(path); + + if (!string_is_empty(label)) + info.label = strdup(label); + + if (!info.list) + goto error; + + if (menu_driver_displaylist_push_internal(label, &info, settings)) + { + ret = menu_displaylist_process(&info); + goto end; + } + + cbs = (menu_file_list_cbs_t*)list->list[list->size - 1].actiondata; + + if (cbs && cbs->action_deferred_push) + if (cbs->action_deferred_push(&info) != 0) + goto error; + + ret = true; + +end: + menu_displaylist_info_free(&info); + + return ret; + +error: + menu_displaylist_info_free(&info); + return false; +} + +static void menu_input_key_bind_poll_bind_state_internal( + const input_device_driver_t *joypad, + struct menu_bind_state *state, + unsigned port, + bool timed_out) +{ + unsigned i; + + /* poll only the relevant port */ + for (i = 0; i < MENU_MAX_BUTTONS; i++) + state->state[port].buttons[i] = joypad->button(port, i); + + for (i = 0; i < MENU_MAX_AXES; i++) + { + if (AXIS_POS(i) != AXIS_NONE) + state->state[port].axes[i] = joypad->axis(port, AXIS_POS(i)); + + if (AXIS_NEG(i) != AXIS_NONE) + state->state[port].axes[i] += joypad->axis(port, AXIS_NEG(i)); + } + + for (i = 0; i < MENU_MAX_HATS; i++) + { + if (joypad->button(port, HAT_MAP(i, HAT_UP_MASK))) + state->state[port].hats[i] |= HAT_UP_MASK; + if (joypad->button(port, HAT_MAP(i, HAT_DOWN_MASK))) + state->state[port].hats[i] |= HAT_DOWN_MASK; + if (joypad->button(port, HAT_MAP(i, HAT_LEFT_MASK))) + state->state[port].hats[i] |= HAT_LEFT_MASK; + if (joypad->button(port, HAT_MAP(i, HAT_RIGHT_MASK))) + state->state[port].hats[i] |= HAT_RIGHT_MASK; + } +} + +/* This sets up all the callback functions for a menu entry. + * + * OK : When we press the 'OK' button on an entry. + * Cancel : When we press the 'Cancel' button on an entry. + * Scan : When we press the 'Scan' button on an entry. + * Start : When we press the 'Start' button on an entry. + * Select : When we press the 'Select' button on an entry. + * Info : When we press the 'Info' button on an entry. + * Left : when we press 'Left' on the D-pad while this entry is selected. + * Right : when we press 'Right' on the D-pad while this entry is selected. + * Deferred push : When pressing an entry results in spawning a new list, it waits until the next + * frame to push this onto the stack. This function callback will then be invoked. + * Get value: Each entry has associated 'text', which we call the value. This function callback + * lets us render that text. + * Title: Each entry can have a custom 'title'. + * Label: Each entry has a label name. This function callback lets us render that label text. + * Sublabel: each entry has a sublabel, which consists of one or more lines of additional information. + * This function callback lets us render that text. + */ +void menu_cbs_init( + struct menu_state *menu_st, + const menu_ctx_driver_t *menu_driver_ctx, + file_list_t *list, + menu_file_list_cbs_t *cbs, + const char *path, const char *label, + unsigned type, size_t idx) +{ + const char *menu_label = NULL; + file_list_t *menu_list = MENU_LIST_GET(menu_st->entries.list, 0); +#ifdef DEBUG_LOG + menu_file_list_cbs_t *menu_cbs = (menu_file_list_cbs_t*) + menu_list->list[list->size - 1].actiondata; + enum msg_hash_enums enum_idx = menu_cbs ? menu_cbs->enum_idx : MSG_UNKNOWN; +#endif + + if (menu_list && menu_list->size) + file_list_get_at_offset(menu_list, menu_list->size - 1, NULL, &menu_label, NULL, NULL); + + if (!label || !menu_label) + return; + +#ifdef DEBUG_LOG + RARCH_LOG("\n"); + + if (cbs && cbs->enum_idx != MSG_UNKNOWN) + RARCH_LOG("\t\t\tenum_idx %d [%s]\n", cbs->enum_idx, msg_hash_to_str(cbs->enum_idx)); +#endif + + /* It will try to find a corresponding callback function inside + * menu_cbs_ok.c, then map this callback to the entry. */ + menu_cbs_init_bind_ok(cbs, path, label, type, idx, menu_label); + + /* It will try to find a corresponding callback function inside + * menu_cbs_cancel.c, then map this callback to the entry. */ + menu_cbs_init_bind_cancel(cbs, path, label, type, idx); + + /* It will try to find a corresponding callback function inside + * menu_cbs_scan.c, then map this callback to the entry. */ + menu_cbs_init_bind_scan(cbs, path, label, type, idx); + + /* It will try to find a corresponding callback function inside + * menu_cbs_start.c, then map this callback to the entry. */ + menu_cbs_init_bind_start(cbs, path, label, type, idx); + + /* It will try to find a corresponding callback function inside + * menu_cbs_select.c, then map this callback to the entry. */ + menu_cbs_init_bind_select(cbs, path, label, type, idx); + + /* It will try to find a corresponding callback function inside + * menu_cbs_info.c, then map this callback to the entry. */ + menu_cbs_init_bind_info(cbs, path, label, type, idx); + + /* It will try to find a corresponding callback function inside + * menu_cbs_left.c, then map this callback to the entry. */ + menu_cbs_init_bind_left(cbs, path, label, type, idx, menu_label); + + /* It will try to find a corresponding callback function inside + * menu_cbs_right.c, then map this callback to the entry. */ + menu_cbs_init_bind_right(cbs, path, label, type, idx, menu_label); + + /* It will try to find a corresponding callback function inside + * menu_cbs_deferred_push.c, then map this callback to the entry. */ + menu_cbs_init_bind_deferred_push(cbs, path, label, type, idx); + + /* It will try to find a corresponding callback function inside + * menu_cbs_get_string_representation.c, then map this callback to the entry. */ + menu_cbs_init_bind_get_string_representation(cbs, path, label, type, idx); + + /* It will try to find a corresponding callback function inside + * menu_cbs_title.c, then map this callback to the entry. */ + menu_cbs_init_bind_title(cbs, path, label, type, idx); + + /* It will try to find a corresponding callback function inside + * menu_cbs_label.c, then map this callback to the entry. */ + menu_cbs_init_bind_label(cbs, path, label, type, idx); + + /* It will try to find a corresponding callback function inside + * menu_cbs_sublabel.c, then map this callback to the entry. */ + menu_cbs_init_bind_sublabel(cbs, path, label, type, idx); + + if (menu_driver_ctx && menu_driver_ctx->bind_init) + menu_driver_ctx->bind_init( + cbs, + path, + label, + type, + idx); +} + +/* Pretty much a stub function. TODO/FIXME - Might as well remove this. */ +int menu_cbs_exit(void) +{ + return -1; +} + +enum action_iterate_type action_iterate_type(const char *label) +{ + if (string_is_equal(label, "info_screen")) + return ITERATE_TYPE_INFO; + if (string_starts_with_size(label, "help", STRLEN_CONST("help"))) + if ( + string_is_equal(label, "help") || + string_is_equal(label, "help_controls") || + string_is_equal(label, "help_what_is_a_core") || + string_is_equal(label, "help_loading_content") || + string_is_equal(label, "help_scanning_content") || + string_is_equal(label, "help_change_virtual_gamepad") || + string_is_equal(label, "help_audio_video_troubleshooting") || + string_is_equal(label, "help_send_debug_info") + ) + return ITERATE_TYPE_HELP; + if (string_is_equal(label, "cheevos_description")) + return ITERATE_TYPE_HELP; + if (string_starts_with_size(label, "custom_bind", STRLEN_CONST("custom_bind"))) + if ( + string_is_equal(label, "custom_bind") || + string_is_equal(label, "custom_bind_all") || + string_is_equal(label, "custom_bind_defaults") + ) + return ITERATE_TYPE_BIND; + + return ITERATE_TYPE_DEFAULT; +} + +void menu_input_key_bind_poll_bind_state( + input_driver_state_t *input_driver_st, + const struct retro_keybind **binds, + float input_axis_threshold, + unsigned joy_idx, + struct menu_bind_state *state, + bool timed_out, + bool keyboard_mapping_blocked) +{ + unsigned b; + rarch_joypad_info_t joypad_info; + input_driver_t *current_input = input_driver_st->current_driver; + void *input_data = input_driver_st->current_data; + unsigned port = state->port; + const input_device_driver_t *joypad = input_driver_st->primary_joypad; +#ifdef HAVE_MFI + const input_device_driver_t *sec_joypad = input_driver_st->secondary_joypad; +#else + const input_device_driver_t *sec_joypad = NULL; +#endif + + memset(state->state, 0, sizeof(state->state)); + + joypad_info.axis_threshold = input_axis_threshold; + joypad_info.joy_idx = joy_idx; + joypad_info.auto_binds = input_autoconf_binds[joy_idx]; + + if (current_input->input_state) + { + /* Poll mouse (on the relevant port) + * + * Check if key was being pressed by + * user with mouse number 'port' + * + * NOTE: We start iterating on 2 (RETRO_DEVICE_ID_MOUSE_LEFT), + * because we want to skip the axes + */ + for (b = 2; b < MENU_MAX_MBUTTONS; b++) + { + state->state[port].mouse_buttons[b] = + current_input->input_state( + input_driver_st->current_data, + joypad, + sec_joypad, + &joypad_info, + binds, + keyboard_mapping_blocked, + port, + RETRO_DEVICE_MOUSE, 0, b); + } + } + + joypad_info.joy_idx = 0; + joypad_info.auto_binds = NULL; + joypad_info.axis_threshold = 0.0f; + + state->skip = timed_out; + if (current_input->input_state) + state->skip |= + current_input->input_state( + input_data, + joypad, + sec_joypad, + &joypad_info, + NULL, + keyboard_mapping_blocked, + 0, + RETRO_DEVICE_KEYBOARD, + 0, + RETROK_RETURN); + + if (joypad) + { + if (joypad->poll) + joypad->poll(); + menu_input_key_bind_poll_bind_state_internal( + joypad, state, port, timed_out); + } + + if (sec_joypad) + { + if (sec_joypad->poll) + sec_joypad->poll(); + menu_input_key_bind_poll_bind_state_internal( + sec_joypad, state, port, timed_out); + } +} + int menu_dialog_iterate( menu_dialog_t *p_dialog, settings_t *settings, diff --git a/menu/menu_driver.h b/menu/menu_driver.h index 0ef6ca69db..47274bca27 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -769,6 +769,31 @@ float menu_input_get_dpi( void menu_input_pointer_close_messagebox(struct menu_state *menu_st); +void menu_input_key_bind_poll_bind_state( + input_driver_state_t *input_driver_st, + const struct retro_keybind **binds, + float input_axis_threshold, + unsigned joy_idx, + struct menu_bind_state *state, + bool timed_out, + bool keyboard_mapping_blocked); + +enum action_iterate_type action_iterate_type(const char *label); + +void menu_cbs_init( + struct menu_state *menu_st, + const menu_ctx_driver_t *menu_driver_ctx, + file_list_t *list, + menu_file_list_cbs_t *cbs, + const char *path, const char *label, + unsigned type, size_t idx); + +bool menu_driver_displaylist_push( + struct menu_state *menu_st, + settings_t *settings, + file_list_t *entry_list, + file_list_t *entry_stack); + int generic_menu_entry_action(void *userdata, menu_entry_t *entry, size_t i, enum menu_action action); extern menu_ctx_driver_t menu_ctx_ozone; diff --git a/retroarch.c b/retroarch.c index 0d59a165b5..51441fccf1 100644 --- a/retroarch.c +++ b/retroarch.c @@ -719,127 +719,6 @@ static bool menu_input_key_bind_custom_bind_keyboard_cb( return (binds->begin <= binds->last); } -static void menu_input_key_bind_poll_bind_state_internal( - const input_device_driver_t *joypad, - struct menu_bind_state *state, - unsigned port, - bool timed_out) -{ - unsigned i; - - /* poll only the relevant port */ - for (i = 0; i < MENU_MAX_BUTTONS; i++) - state->state[port].buttons[i] = joypad->button(port, i); - - for (i = 0; i < MENU_MAX_AXES; i++) - { - if (AXIS_POS(i) != AXIS_NONE) - state->state[port].axes[i] = joypad->axis(port, AXIS_POS(i)); - - if (AXIS_NEG(i) != AXIS_NONE) - state->state[port].axes[i] += joypad->axis(port, AXIS_NEG(i)); - } - - for (i = 0; i < MENU_MAX_HATS; i++) - { - if (joypad->button(port, HAT_MAP(i, HAT_UP_MASK))) - state->state[port].hats[i] |= HAT_UP_MASK; - if (joypad->button(port, HAT_MAP(i, HAT_DOWN_MASK))) - state->state[port].hats[i] |= HAT_DOWN_MASK; - if (joypad->button(port, HAT_MAP(i, HAT_LEFT_MASK))) - state->state[port].hats[i] |= HAT_LEFT_MASK; - if (joypad->button(port, HAT_MAP(i, HAT_RIGHT_MASK))) - state->state[port].hats[i] |= HAT_RIGHT_MASK; - } -} - -static void menu_input_key_bind_poll_bind_state( - struct rarch_state *p_rarch, - float input_axis_threshold, - unsigned joy_idx, - struct menu_bind_state *state, - bool timed_out) -{ - unsigned b; - rarch_joypad_info_t joypad_info; - input_driver_state_t *input_driver_st = &p_rarch->input_driver_state; - input_driver_t *current_input = input_driver_st->current_driver; - void *input_data = input_driver_st->current_data; - unsigned port = state->port; - const input_device_driver_t *joypad = input_driver_st->primary_joypad; -#ifdef HAVE_MFI - const input_device_driver_t *sec_joypad = input_driver_st->secondary_joypad; -#else - const input_device_driver_t *sec_joypad = NULL; -#endif - - memset(state->state, 0, sizeof(state->state)); - - joypad_info.axis_threshold = input_axis_threshold; - joypad_info.joy_idx = joy_idx; - joypad_info.auto_binds = input_autoconf_binds[joy_idx]; - - if (current_input->input_state) - { - /* Poll mouse (on the relevant port) - * - * Check if key was being pressed by - * user with mouse number 'port' - * - * NOTE: We start iterating on 2 (RETRO_DEVICE_ID_MOUSE_LEFT), - * because we want to skip the axes - */ - for (b = 2; b < MENU_MAX_MBUTTONS; b++) - { - state->state[port].mouse_buttons[b] = - current_input->input_state( - input_driver_st->current_data, - joypad, - sec_joypad, - &joypad_info, - p_rarch->libretro_input_binds, - p_rarch->keyboard_mapping_blocked, - port, - RETRO_DEVICE_MOUSE, 0, b); - } - } - - joypad_info.joy_idx = 0; - joypad_info.auto_binds = NULL; - joypad_info.axis_threshold = 0.0f; - - state->skip = timed_out; - if (current_input->input_state) - state->skip |= - current_input->input_state( - input_data, - joypad, - sec_joypad, - &joypad_info, - NULL, - p_rarch->keyboard_mapping_blocked, - 0, - RETRO_DEVICE_KEYBOARD, - 0, - RETROK_RETURN); - - if (joypad) - { - if (joypad->poll) - joypad->poll(); - menu_input_key_bind_poll_bind_state_internal( - joypad, state, port, timed_out); - } - - if (sec_joypad) - { - if (sec_joypad->poll) - sec_joypad->poll(); - menu_input_key_bind_poll_bind_state_internal( - sec_joypad, state, port, timed_out); - } -} - bool menu_input_key_bind_set_mode( enum menu_input_binds_ctl_state state, void *data) { @@ -881,10 +760,13 @@ bool menu_input_key_bind_set_mode( joypad, sec_joypad, binds); - menu_input_key_bind_poll_bind_state(p_rarch, + menu_input_key_bind_poll_bind_state( + &p_rarch->input_driver_state, + p_rarch->libretro_input_binds, settings->floats.input_axis_threshold, settings->uints.input_joypad_index[binds->port], - binds, false); + binds, false, + p_rarch->keyboard_mapping_blocked); current_usec = cpu_features_get_time_usec(); @@ -995,10 +877,13 @@ static bool menu_input_key_bind_iterate( p_rarch->keyboard_mapping_blocked = false; - menu_input_key_bind_poll_bind_state(p_rarch, + menu_input_key_bind_poll_bind_state( + &p_rarch->input_driver_state, + p_rarch->libretro_input_binds, settings->floats.input_axis_threshold, settings->uints.input_joypad_index[new_binds.port], - &new_binds, timed_out); + &new_binds, timed_out, + p_rarch->keyboard_mapping_blocked); #ifdef ANDROID /* Keep resetting bind during the hold period, @@ -1095,150 +980,6 @@ static bool menu_input_key_bind_iterate( return false; } -/* This sets up all the callback functions for a menu entry. - * - * OK : When we press the 'OK' button on an entry. - * Cancel : When we press the 'Cancel' button on an entry. - * Scan : When we press the 'Scan' button on an entry. - * Start : When we press the 'Start' button on an entry. - * Select : When we press the 'Select' button on an entry. - * Info : When we press the 'Info' button on an entry. - * Left : when we press 'Left' on the D-pad while this entry is selected. - * Right : when we press 'Right' on the D-pad while this entry is selected. - * Deferred push : When pressing an entry results in spawning a new list, it waits until the next - * frame to push this onto the stack. This function callback will then be invoked. - * Get value: Each entry has associated 'text', which we call the value. This function callback - * lets us render that text. - * Title: Each entry can have a custom 'title'. - * Label: Each entry has a label name. This function callback lets us render that label text. - * Sublabel: each entry has a sublabel, which consists of one or more lines of additional information. - * This function callback lets us render that text. - */ -static void menu_cbs_init( - struct menu_state *menu_st, - const menu_ctx_driver_t *menu_driver_ctx, - file_list_t *list, - menu_file_list_cbs_t *cbs, - const char *path, const char *label, - unsigned type, size_t idx) -{ - const char *menu_label = NULL; - file_list_t *menu_list = MENU_LIST_GET(menu_st->entries.list, 0); -#ifdef DEBUG_LOG - menu_file_list_cbs_t *menu_cbs = (menu_file_list_cbs_t*) - menu_list->list[list->size - 1].actiondata; - enum msg_hash_enums enum_idx = menu_cbs ? menu_cbs->enum_idx : MSG_UNKNOWN; -#endif - - if (menu_list && menu_list->size) - file_list_get_at_offset(menu_list, menu_list->size - 1, NULL, &menu_label, NULL, NULL); - - if (!label || !menu_label) - return; - -#ifdef DEBUG_LOG - RARCH_LOG("\n"); - - if (cbs && cbs->enum_idx != MSG_UNKNOWN) - RARCH_LOG("\t\t\tenum_idx %d [%s]\n", cbs->enum_idx, msg_hash_to_str(cbs->enum_idx)); -#endif - - /* It will try to find a corresponding callback function inside - * menu_cbs_ok.c, then map this callback to the entry. */ - menu_cbs_init_bind_ok(cbs, path, label, type, idx, menu_label); - - /* It will try to find a corresponding callback function inside - * menu_cbs_cancel.c, then map this callback to the entry. */ - menu_cbs_init_bind_cancel(cbs, path, label, type, idx); - - /* It will try to find a corresponding callback function inside - * menu_cbs_scan.c, then map this callback to the entry. */ - menu_cbs_init_bind_scan(cbs, path, label, type, idx); - - /* It will try to find a corresponding callback function inside - * menu_cbs_start.c, then map this callback to the entry. */ - menu_cbs_init_bind_start(cbs, path, label, type, idx); - - /* It will try to find a corresponding callback function inside - * menu_cbs_select.c, then map this callback to the entry. */ - menu_cbs_init_bind_select(cbs, path, label, type, idx); - - /* It will try to find a corresponding callback function inside - * menu_cbs_info.c, then map this callback to the entry. */ - menu_cbs_init_bind_info(cbs, path, label, type, idx); - - /* It will try to find a corresponding callback function inside - * menu_cbs_left.c, then map this callback to the entry. */ - menu_cbs_init_bind_left(cbs, path, label, type, idx, menu_label); - - /* It will try to find a corresponding callback function inside - * menu_cbs_right.c, then map this callback to the entry. */ - menu_cbs_init_bind_right(cbs, path, label, type, idx, menu_label); - - /* It will try to find a corresponding callback function inside - * menu_cbs_deferred_push.c, then map this callback to the entry. */ - menu_cbs_init_bind_deferred_push(cbs, path, label, type, idx); - - /* It will try to find a corresponding callback function inside - * menu_cbs_get_string_representation.c, then map this callback to the entry. */ - menu_cbs_init_bind_get_string_representation(cbs, path, label, type, idx); - - /* It will try to find a corresponding callback function inside - * menu_cbs_title.c, then map this callback to the entry. */ - menu_cbs_init_bind_title(cbs, path, label, type, idx); - - /* It will try to find a corresponding callback function inside - * menu_cbs_label.c, then map this callback to the entry. */ - menu_cbs_init_bind_label(cbs, path, label, type, idx); - - /* It will try to find a corresponding callback function inside - * menu_cbs_sublabel.c, then map this callback to the entry. */ - menu_cbs_init_bind_sublabel(cbs, path, label, type, idx); - - if (menu_driver_ctx && menu_driver_ctx->bind_init) - menu_driver_ctx->bind_init( - cbs, - path, - label, - type, - idx); -} - -/* Pretty much a stub function. TODO/FIXME - Might as well remove this. */ -int menu_cbs_exit(void) -{ - return -1; -} - -static enum action_iterate_type action_iterate_type(const char *label) -{ - if (string_is_equal(label, "info_screen")) - return ITERATE_TYPE_INFO; - if (string_starts_with_size(label, "help", STRLEN_CONST("help"))) - if ( - string_is_equal(label, "help") || - string_is_equal(label, "help_controls") || - string_is_equal(label, "help_what_is_a_core") || - string_is_equal(label, "help_loading_content") || - string_is_equal(label, "help_scanning_content") || - string_is_equal(label, "help_change_virtual_gamepad") || - string_is_equal(label, "help_audio_video_troubleshooting") || - string_is_equal(label, "help_send_debug_info") - ) - return ITERATE_TYPE_HELP; - if (string_is_equal(label, "cheevos_description")) - return ITERATE_TYPE_HELP; - if (string_starts_with_size(label, "custom_bind", STRLEN_CONST("custom_bind"))) - if ( - string_is_equal(label, "custom_bind") || - string_is_equal(label, "custom_bind_all") || - string_is_equal(label, "custom_bind_defaults") - ) - return ITERATE_TYPE_BIND; - - return ITERATE_TYPE_DEFAULT; -} - #ifdef HAVE_ACCESSIBILITY static void get_current_menu_value(struct menu_state *menu_st, char *s, size_t len) @@ -1722,223 +1463,6 @@ static int generic_menu_iterate( return 0; } -static bool menu_driver_displaylist_push_internal( - const char *label, - menu_displaylist_info_t *info, - settings_t *settings) -{ - if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HISTORY_TAB))) - { - if (menu_displaylist_ctl(DISPLAYLIST_HISTORY, info, settings)) - return true; - } - else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_FAVORITES_TAB))) - { - if (menu_displaylist_ctl(DISPLAYLIST_FAVORITES, info, settings)) - return true; - } - else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_SETTINGS_TAB))) - { - if (menu_displaylist_ctl(DISPLAYLIST_SETTINGS_ALL, info, settings)) - return true; - } -#ifdef HAVE_CHEATS - else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS))) - { - if (menu_displaylist_ctl(DISPLAYLIST_CHEAT_SEARCH_SETTINGS_LIST, info, settings)) - return true; - } -#endif - else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_MUSIC_TAB))) - { - filebrowser_clear_type(); - info->type = 42; - - if (!string_is_empty(info->exts)) - free(info->exts); - if (!string_is_empty(info->label)) - free(info->label); - - info->exts = strdup("lpl"); - info->label = strdup( - msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)); - - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_ctl(DISPLAYLIST_MUSIC_HISTORY, info, settings); - return true; - } - else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_TAB))) - { - filebrowser_clear_type(); - info->type = 42; - - if (!string_is_empty(info->exts)) - free(info->exts); - if (!string_is_empty(info->label)) - free(info->label); - - info->exts = strdup("lpl"); - info->label = strdup( - msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)); - - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_ctl(DISPLAYLIST_VIDEO_HISTORY, info, settings); - return true; - } - else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_IMAGES_TAB))) - { - filebrowser_clear_type(); - info->type = 42; - - if (!string_is_empty(info->exts)) - free(info->exts); - if (!string_is_empty(info->label)) - free(info->label); - - info->exts = strdup("lpl"); - info->label = strdup( - msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)); - - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - -#if 0 -#ifdef HAVE_SCREENSHOTS - if (!rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL)) - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT), - msg_hash_to_str(MENU_ENUM_LABEL_TAKE_SCREENSHOT), - MENU_ENUM_LABEL_TAKE_SCREENSHOT, - MENU_SETTING_ACTION_SCREENSHOT, 0, 0); - else - info->need_push_no_playlist_entries = true; -#endif -#endif - menu_displaylist_ctl(DISPLAYLIST_IMAGES_HISTORY, info, settings); - return true; - } - else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB))) - { - const char *dir_playlist = settings->paths.directory_playlist; - - filebrowser_clear_type(); - info->type = 42; - - if (!string_is_empty(info->exts)) - free(info->exts); - if (!string_is_empty(info->label)) - free(info->label); - - info->exts = strdup("lpl"); - info->label = strdup( - msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)); - - if (string_is_empty(dir_playlist)) - { - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - info->need_refresh = true; - info->need_push_no_playlist_entries = true; - info->need_push = true; - - return true; - } - - if (!string_is_empty(info->path)) - free(info->path); - - info->path = strdup(dir_playlist); - - if (menu_displaylist_ctl( - DISPLAYLIST_DATABASE_PLAYLISTS, info, settings)) - return true; - } - else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TAB))) - { - if (menu_displaylist_ctl(DISPLAYLIST_SCAN_DIRECTORY_LIST, info, settings)) - return true; - } -#if defined(HAVE_LIBRETRODB) - else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_EXPLORE_TAB))) - { - if (menu_displaylist_ctl(DISPLAYLIST_EXPLORE, info, settings)) - return true; - } -#endif - 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)) - return true; - } - else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HORIZONTAL_MENU))) - { - if (menu_displaylist_ctl(DISPLAYLIST_HORIZONTAL, info, settings)) - return true; - } - - return false; -} - -static bool menu_driver_displaylist_push( - struct menu_state *menu_st, - settings_t *settings, - file_list_t *entry_list, - file_list_t *entry_stack) -{ - menu_displaylist_info_t info; - const char *path = NULL; - const char *label = NULL; - unsigned type = 0; - bool ret = false; - enum msg_hash_enums enum_idx = MSG_UNKNOWN; - file_list_t *list = MENU_LIST_GET(menu_st->entries.list, 0); - menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) - list->list[list->size - 1].actiondata; - - menu_displaylist_info_init(&info); - - if (list && list->size) - file_list_get_at_offset(list, list->size - 1, &path, &label, &type, NULL); - - if (cbs) - enum_idx = cbs->enum_idx; - - info.list = entry_list; - info.menu_list = entry_stack; - info.type = type; - info.enum_idx = enum_idx; - - if (!string_is_empty(path)) - info.path = strdup(path); - - if (!string_is_empty(label)) - info.label = strdup(label); - - if (!info.list) - goto error; - - if (menu_driver_displaylist_push_internal(label, &info, settings)) - { - ret = menu_displaylist_process(&info); - goto end; - } - - cbs = (menu_file_list_cbs_t*)list->list[list->size - 1].actiondata; - - if (cbs && cbs->action_deferred_push) - if (cbs->action_deferred_push(&info) != 0) - goto error; - - ret = true; - -end: - menu_displaylist_info_free(&info); - - return ret; - -error: - menu_displaylist_info_free(&info); - return false; -} - int generic_menu_entry_action( void *userdata, menu_entry_t *entry, size_t i, enum menu_action action) {