From 79be7b6913857000275376e69bfffb867e881be9 Mon Sep 17 00:00:00 2001 From: markwkidd Date: Fri, 15 Feb 2019 08:25:17 -0500 Subject: [PATCH 001/237] use "playlist" rather than "collection" in UI --- intl/msg_hash_us.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index a2340b3fd8..de3e17145b 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -591,7 +591,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Collections" + "Playlists" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, @@ -2078,7 +2078,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Playlist" + "Playlists" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, @@ -5101,7 +5101,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Select From Collection" + "Select from a playlist" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_FILTER, @@ -5685,11 +5685,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Scans a directory for compatible files and add them to the collection." + "Scans a directory for compatible content. If found, content is added to playlists." ) MSG_HASH( MENU_ENUM_SUBLABEL_SCAN_FILE, - "Scans a compatible file and add it to the collection." + "Scans a file for compatible content. If found, content is added to playlists." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, @@ -5725,7 +5725,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Remove this entry from the collection." + "Remove this entry from the playlist." ) MSG_HASH( MENU_ENUM_SUBLABEL_INFORMATION, @@ -5869,7 +5869,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Allow the user to remove entries from collections." + "Allow the user to remove entries from playlists." ) MSG_HASH( MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, @@ -6039,7 +6039,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Save all collections to this directory." + "Save all playlists to this directory." ) MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, @@ -6363,7 +6363,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Allow the user to rename entries in collections." + "Allow the user to rename entries in playlists." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, @@ -6674,11 +6674,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, - "Automatically add content to playlist" + "Automatically add content to playlists" ) MSG_HASH( MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, - "Automatically scans loaded content so they appear inside playlists." + "Automatically scans loaded content with the playlist scanner." ) MSG_HASH( MSG_SCANNING_OF_FILE_FINISHED, From 28bb7c67afbc251069cd9a87f5d22da3afc1d1d5 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 14 Mar 2019 11:47:00 +0000 Subject: [PATCH 002/237] (RGUI/XMB) Enable thumbnail display on mixed content playlists (history, favourites, etc.) Move thumbnail path handling code to reusable menu_thumbnail_path.h/.c file (XMB) Bug fixes: - Show thumbnails correctly when 'Show associated cores in playlists' is enabled - Prevent each thumbnail from being loaded twice (!) when changing current selection --- Makefile.common | 3 +- griffin/griffin.c | 1 + menu/drivers/rgui.c | 213 +++----------- menu/drivers/xmb.c | 531 +++++++++++++---------------------- menu/menu_displaylist.c | 49 ++-- menu/menu_thumbnail_path.c | 560 +++++++++++++++++++++++++++++++++++++ menu/menu_thumbnail_path.h | 129 +++++++++ 7 files changed, 948 insertions(+), 538 deletions(-) create mode 100644 menu/menu_thumbnail_path.c create mode 100644 menu/menu_thumbnail_path.h diff --git a/Makefile.common b/Makefile.common index 88e4439225..f6adc1ae13 100644 --- a/Makefile.common +++ b/Makefile.common @@ -792,7 +792,8 @@ ifeq ($(HAVE_MENU_COMMON), 1) menu/menu_displaylist.o \ menu/menu_animation.o \ menu/drivers/menu_generic.o \ - menu/drivers/null.o + menu/drivers/null.o \ + menu/menu_thumbnail_path.o ifeq ($(HAVE_MENU_COMMON),1) OBJ += menu/drivers_display/menu_display_null.o diff --git a/griffin/griffin.c b/griffin/griffin.c index 4c7deb0202..c05b7a2dba 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -1238,6 +1238,7 @@ MENU #include "../menu/menu_shader.c" #include "../menu/menu_displaylist.c" #include "../menu/menu_animation.c" +#include "../menu/menu_thumbnail_path.c" #include "../menu/drivers/null.c" #include "../menu/drivers/menu_generic.c" diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index b25dfc9bd8..032e3aab5f 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -53,6 +53,7 @@ #include /* Thumbnail additions */ +#include "../menu_thumbnail_path.h" #include #include "../../tasks/tasks_internal.h" #include @@ -424,9 +425,7 @@ typedef struct bool is_playlist; bool entry_has_thumbnail; bool show_thumbnail; - char *thumbnail_system; - char *thumbnail_content; - char *thumbnail_path; + menu_thumbnail_path_data_t *thumbnail_path_data; uint32_t thumbnail_queue_size; bool show_wallpaper; char theme_preset_path[PATH_MAX_LENGTH]; /* Must be a fixed length array... */ @@ -1608,6 +1607,7 @@ static void rgui_render(void *data, bool is_idle) * through a list...) */ if (rgui->show_thumbnail && rgui->entry_has_thumbnail && (thumbnail.is_valid || (rgui->thumbnail_queue_size > 0))) { + const char *thumbnail_title = NULL; char thumbnail_title_buf[255]; unsigned title_x, title_width; thumbnail_title_buf[0] = '\0'; @@ -1615,24 +1615,28 @@ static void rgui_render(void *data, bool is_idle) /* Draw thumbnail */ rgui_render_thumbnail(); - /* Format thumbnail title */ - ticker.s = thumbnail_title_buf; - ticker.len = RGUI_TERM_WIDTH(fb_width) - 10; - ticker.str = rgui->thumbnail_content; - ticker.selected = true; - menu_animation_ticker(&ticker); - - title_width = utf8len(thumbnail_title_buf) * FONT_WIDTH_STRIDE; - title_x = RGUI_TERM_START_X(fb_width) + ((RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE) - title_width) / 2; - - if (rgui_framebuf_data) + /* Get thumbnail title */ + if (menu_thumbnail_get_label(rgui->thumbnail_path_data, &thumbnail_title)) { - /* Draw thumbnail title background */ - rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, - title_x - 5, 0, title_width + 10, FONT_HEIGHT_STRIDE, rgui_bg_filler); + /* Format thumbnail title */ + ticker.s = thumbnail_title_buf; + ticker.len = RGUI_TERM_WIDTH(fb_width) - 10; + ticker.str = thumbnail_title; + ticker.selected = true; + menu_animation_ticker(&ticker); - /* Draw thumbnail title */ - blit_line((int)title_x, 0, thumbnail_title_buf, rgui->colors.hover_color); + title_width = utf8len(thumbnail_title_buf) * FONT_WIDTH_STRIDE; + title_x = RGUI_TERM_START_X(fb_width) + ((RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE) - title_width) / 2; + + if (rgui_framebuf_data) + { + /* Draw thumbnail title background */ + rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, + title_x - 5, 0, title_width + 10, FONT_HEIGHT_STRIDE, rgui_bg_filler); + + /* Draw thumbnail title */ + blit_line((int)title_x, 0, thumbnail_title_buf, rgui->colors.hover_color); + } } } else @@ -1927,6 +1931,10 @@ static void *rgui_init(void **userdata, bool video_is_threaded) rgui->last_width = fb_width; rgui->last_height = fb_height; + rgui->thumbnail_path_data = menu_thumbnail_path_init(); + if (!rgui->thumbnail_path_data) + goto error; + rgui->thumbnail_queue_size = 0; /* Ensure that we start with thumbnails disabled */ rgui->show_thumbnail = false; @@ -1948,12 +1956,8 @@ static void rgui_free(void *data) if (rgui) { - if (!string_is_empty(rgui->thumbnail_system)) - free(rgui->thumbnail_system); - if (!string_is_empty(rgui->thumbnail_content)) - free(rgui->thumbnail_content); - if (!string_is_empty(rgui->thumbnail_path)) - free(rgui->thumbnail_path); + if (rgui->thumbnail_path_data) + free(rgui->thumbnail_path_data); } fb_font_inited = menu_display_get_font_data_init(); @@ -2092,151 +2096,12 @@ static void rgui_navigation_clear(void *data, bool pending_push) rgui->scroll_y = 0; } -static const char *rgui_thumbnail_ident(void) -{ - char folder = 0; - settings_t *settings = config_get_ptr(); - - folder = settings->uints.menu_thumbnails; - - switch (folder) - { - case 1: - return "Named_Snaps"; - case 2: - return "Named_Titles"; - case 3: - return "Named_Boxarts"; - case 0: - default: - break; - } - - return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF); -} - -static bool rgui_update_thumbnail_path(void *userdata) -{ - rgui_t *rgui = (rgui_t*)userdata; - settings_t *settings = config_get_ptr(); - char new_path[PATH_MAX_LENGTH] = {0}; - const char *thumbnail_base_dir = settings->paths.directory_thumbnails; - const char *thumb_ident = rgui_thumbnail_ident(); - - if (!string_is_empty(rgui->thumbnail_path)) - { - free(rgui->thumbnail_path); - rgui->thumbnail_path = NULL; - } - - /* NB: The following is copied directly from xmb.c (xmb_update_thumbnail_path()) */ - if (!string_is_equal(thumb_ident, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) && - !string_is_empty(thumbnail_base_dir) && - !string_is_empty(rgui->thumbnail_system) && - !string_is_empty(rgui->thumbnail_content)) - { - /* Append thumbnail system directory */ - fill_pathname_join(new_path, thumbnail_base_dir, rgui->thumbnail_system, sizeof(new_path)); - - if (!string_is_empty(new_path)) - { - char *tmp_new2 = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); - tmp_new2[0] = '\0'; - - /* Append Named_Snaps/Named_Boxarts/Named_Titles */ - fill_pathname_join(tmp_new2, new_path, thumb_ident, PATH_MAX_LENGTH * sizeof(char)); - - strlcpy(new_path, tmp_new2, PATH_MAX_LENGTH * sizeof(char)); - free(tmp_new2); - tmp_new2 = NULL; - - if (!string_is_empty(new_path)) - { - /* Scrub characters that are not cross-platform and/or violate the - * No-Intro filename standard: - * http://datomatic.no-intro.org/stuff/The%20Official%20No-Intro%20Convention%20(20071030).zip - * Replace these characters in the entry name with underscores. - */ - char *scrub_char_pointer = NULL; - char *tmp_new = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); - char *tmp = strdup(rgui->thumbnail_content); - - tmp_new[0] = '\0'; - - while((scrub_char_pointer = strpbrk(tmp, "&*/:`\"<>?\\|"))) - *scrub_char_pointer = '_'; - - fill_pathname_join(tmp_new, new_path, tmp, PATH_MAX_LENGTH * sizeof(char)); - - if (!string_is_empty(tmp_new)) - strlcpy(new_path, tmp_new, sizeof(new_path)); - - free(tmp_new); - tmp_new = NULL; - free(tmp); - tmp = NULL; - - /* Append png extension */ - if (!string_is_empty(new_path)) - { - strlcat(new_path, file_path_str(FILE_PATH_PNG_EXTENSION), sizeof(new_path)); - - if (!string_is_empty(new_path)) - { - rgui->thumbnail_path = strdup(new_path); - return true; - } - } - } - } - } - - return false; -} - static void rgui_set_thumbnail_system(void *userdata, char *s, size_t len) { rgui_t *rgui = (rgui_t*)userdata; if (!rgui) return; - if (!string_is_empty(rgui->thumbnail_system)) - free(rgui->thumbnail_system); - rgui->thumbnail_system = strdup(s); -} - -static bool rgui_update_thumbnail_content(void *userdata) -{ - rgui_t *rgui = (rgui_t*)userdata; - playlist_t *playlist = NULL; - size_t selection = menu_navigation_get_selection(); - - if (!rgui) - return false; - - /* Get label of currently selected playlist entry */ - playlist = playlist_get_cached(); - if (playlist) - { - if (selection < playlist_get_size(playlist)) - { - const char *label = NULL; - playlist_get_index(playlist, selection, NULL, &label, NULL, NULL, NULL, NULL); - - if (!string_is_empty(rgui->thumbnail_content)) - { - free(rgui->thumbnail_content); - rgui->thumbnail_content = NULL; - } - - if (!string_is_empty(label)) - { - rgui->thumbnail_content = strdup(label); - return true; - } - } - } - - return false; + menu_thumbnail_set_system(rgui->thumbnail_path_data, s); } static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui) @@ -2245,11 +2110,18 @@ static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui) if (rgui->show_thumbnail && rgui->is_playlist) { - if (rgui_update_thumbnail_content(rgui)) + if (menu_thumbnail_set_content_playlist(rgui->thumbnail_path_data, + playlist_get_cached(), menu_navigation_get_selection())) { - if (rgui_update_thumbnail_path(rgui)) + if (menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_RIGHT)) { - rgui->entry_has_thumbnail = request_thumbnail(rgui, rgui->thumbnail_path); + const char *thumbnail_path = NULL; + + if (menu_thumbnail_get_path(rgui->thumbnail_path_data, + MENU_THUMBNAIL_RIGHT, &thumbnail_path)) + { + rgui->entry_has_thumbnail = request_thumbnail(rgui, thumbnail_path); + } } } } @@ -2379,7 +2251,10 @@ static void rgui_populate_entries(void *data, return; /* Check whether we are currently viewing a playlist */ - rgui->is_playlist = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST)); + rgui->is_playlist = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_IMAGES_LIST)); /* Set menu title */ menu_entries_get_title(rgui->menu_title, sizeof(rgui->menu_title)); diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 362dbcead8..efd5f76741 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -45,6 +45,7 @@ #include "../menu_animation.h" #include "../menu_entries.h" #include "../menu_input.h" +#include "../menu_thumbnail_path.h" #include "../../core_info.h" #include "../../core.h" @@ -245,6 +246,8 @@ typedef struct xmb_handle bool mouse_show; bool use_ps3_layout; bool assets_missing; + bool is_playlist; + bool is_db_manager_list; uint8_t system_tab_end; uint8_t tabs[XMB_SYSTEM_TAB_MAX_LENGTH]; @@ -306,11 +309,7 @@ typedef struct xmb_handle char title_name[255]; char *box_message; - char *thumbnail_system; - char *thumbnail_content; char *savestate_thumbnail_file_path; - char *thumbnail_file_path; - char *left_thumbnail_file_path; char *bg_file_path; file_list_t *selection_buf_old; @@ -340,6 +339,8 @@ typedef struct xmb_handle font_data_t *font2; video_font_raster_block_t raster_block; video_font_raster_block_t raster_block2; + + menu_thumbnail_path_data_t *thumbnail_path_data; } xmb_handle_t; float scale_mod[8] = { @@ -559,32 +560,6 @@ static xmb_node_t *xmb_copy_node(const xmb_node_t *old_node) return new_node; } -static const char *xmb_thumbnails_ident(char pos) -{ - char folder = 0; - settings_t *settings = config_get_ptr(); - - if (pos == 'R') - folder = settings->uints.menu_thumbnails; - if (pos == 'L') - folder = settings->uints.menu_left_thumbnails; - - switch (folder) - { - case 1: - return "Named_Snaps"; - case 2: - return "Named_Titles"; - case 3: - return "Named_Boxarts"; - case 0: - default: - break; - } - - return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF); -} - static float *xmb_gradient_ident(video_frame_info_t *video_info) { switch (video_info->xmb_color_theme) @@ -952,153 +927,21 @@ end: static void xmb_update_thumbnail_path(void *data, unsigned i, char pos) { - menu_entry_t entry; - unsigned entry_type = 0; - char new_path[PATH_MAX_LENGTH] = {0}; - settings_t *settings = config_get_ptr(); - xmb_handle_t *xmb = (xmb_handle_t*)data; - playlist_t *playlist = NULL; - const char *dir_thumbnails = settings->paths.directory_thumbnails; + xmb_handle_t *xmb = (xmb_handle_t*)data; + const char *core_name = NULL; - menu_entry_init(&entry); + if (!xmb) + return; - if (!xmb || string_is_empty(dir_thumbnails)) - goto end; - - menu_entry_get(&entry, 0, i, NULL, true); - - entry_type = menu_entry_get_type_new(&entry); - - if (entry_type == FILE_TYPE_IMAGEVIEWER || entry_type == FILE_TYPE_IMAGE) + /* imageviewer content requires special treatment... */ + menu_thumbnail_get_core_name(xmb->thumbnail_path_data, &core_name); + if (string_is_equal(core_name, "imageviewer")) { - file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); - xmb_node_t *node = (xmb_node_t*) - file_list_get_userdata_at_offset(selection_buf, i); - - if (node && !string_is_empty(node->fullpath) && - (pos == 'R' || (pos == 'L' && string_is_equal(xmb_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))))) - { - if (!string_is_empty(entry.path)) - fill_pathname_join( - new_path, - node->fullpath, - entry.path, - sizeof(new_path)); - - goto end; - } + if ((pos == 'R') || (pos == 'L' && !menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT))) + menu_thumbnail_update_path(xmb->thumbnail_path_data, pos == 'R' ? MENU_THUMBNAIL_RIGHT : MENU_THUMBNAIL_LEFT); } - else if (filebrowser_get_type() != FILEBROWSER_NONE) - { - video_driver_texture_unload(&xmb->thumbnail); - goto end; - } - - playlist = playlist_get_cached(); - - if (playlist) - { - const char *core_name = NULL; - playlist_get_index(playlist, i, - NULL, NULL, NULL, &core_name, NULL, NULL); - - if (string_is_equal(core_name, "imageviewer")) - { - if ( - (pos == 'R') || - ( - pos == 'L' && - string_is_equal(xmb_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) - ) - ) - { - if (!string_is_empty(entry.label)) - strlcpy(new_path, entry.label, - sizeof(new_path)); - } - else - video_driver_texture_unload(&xmb->left_thumbnail); - goto end; - } - } - - /* Append thumbnail system directory */ - if (!string_is_empty(xmb->thumbnail_system)) - fill_pathname_join( - new_path, - dir_thumbnails, - xmb->thumbnail_system, - sizeof(new_path)); - - if (!string_is_empty(new_path)) - { - char *tmp_new2 = (char*) - malloc(PATH_MAX_LENGTH * sizeof(char)); - - tmp_new2[0] = '\0'; - - /* Append Named_Snaps/Named_Boxarts/Named_Titles */ - if (pos == 'R') - fill_pathname_join(tmp_new2, new_path, - xmb_thumbnails_ident('R'), PATH_MAX_LENGTH * sizeof(char)); - if (pos == 'L') - fill_pathname_join(tmp_new2, new_path, - xmb_thumbnails_ident('L'), PATH_MAX_LENGTH * sizeof(char)); - - strlcpy(new_path, tmp_new2, - PATH_MAX_LENGTH * sizeof(char)); - free(tmp_new2); - } - - /* Scrub characters that are not cross-platform and/or violate the - * No-Intro filename standard: - * http://datomatic.no-intro.org/stuff/The%20Official%20No-Intro%20Convention%20(20071030).zip - * Replace these characters in the entry name with underscores. - */ - if (!string_is_empty(xmb->thumbnail_content)) - { - char *scrub_char_pointer = NULL; - char *tmp_new = (char*) - malloc(PATH_MAX_LENGTH * sizeof(char)); - char *tmp = strdup(xmb->thumbnail_content); - - tmp_new[0] = '\0'; - - while((scrub_char_pointer = strpbrk(tmp, "&*/:`\"<>?\\|"))) - *scrub_char_pointer = '_'; - - /* Look for thumbnail file with this scrubbed filename */ - - fill_pathname_join(tmp_new, - new_path, - tmp, PATH_MAX_LENGTH * sizeof(char)); - - if (!string_is_empty(tmp_new)) - strlcpy(new_path, - tmp_new, sizeof(new_path)); - - free(tmp_new); - free(tmp); - } - - /* Append png extension */ - if (!string_is_empty(new_path)) - strlcat(new_path, - file_path_str(FILE_PATH_PNG_EXTENSION), - sizeof(new_path)); - -end: - if (xmb && !string_is_empty(new_path)) - { - if (pos == 'R') - xmb->thumbnail_file_path = strdup(new_path); - if (pos == 'L') - xmb->left_thumbnail_file_path = strdup(new_path); - } - - menu_entry_free(&entry); + else + menu_thumbnail_update_path(xmb->thumbnail_path_data, pos == 'R' ? MENU_THUMBNAIL_RIGHT : MENU_THUMBNAIL_LEFT); } static void xmb_update_savestate_thumbnail_path(void *data, unsigned i) @@ -1162,32 +1005,29 @@ static void xmb_update_savestate_thumbnail_path(void *data, unsigned i) static void xmb_update_thumbnail_image(void *data) { - xmb_handle_t *xmb = (xmb_handle_t*)data; + xmb_handle_t *xmb = (xmb_handle_t*)data; + const char *right_thumbnail_path = NULL; + const char *left_thumbnail_path = NULL; + if (!xmb) return; - if (!(string_is_empty(xmb->thumbnail_file_path))) + if (menu_thumbnail_get_path(xmb->thumbnail_path_data, MENU_THUMBNAIL_RIGHT, &right_thumbnail_path)) { - if (filestream_exists(xmb->thumbnail_file_path)) - task_push_image_load(xmb->thumbnail_file_path, + if (filestream_exists(right_thumbnail_path)) + task_push_image_load(right_thumbnail_path, menu_display_handle_thumbnail_upload, NULL); else video_driver_texture_unload(&xmb->thumbnail); - - free(xmb->thumbnail_file_path); - xmb->thumbnail_file_path = NULL; } - if (!(string_is_empty(xmb->left_thumbnail_file_path))) + if (menu_thumbnail_get_path(xmb->thumbnail_path_data, MENU_THUMBNAIL_LEFT, &left_thumbnail_path)) { - if (filestream_exists(xmb->left_thumbnail_file_path)) - task_push_image_load(xmb->left_thumbnail_file_path, + if (filestream_exists(left_thumbnail_path)) + task_push_image_load(left_thumbnail_path, menu_display_handle_left_thumbnail_upload, NULL); else video_driver_texture_unload(&xmb->left_thumbnail); - - free(xmb->left_thumbnail_file_path); - xmb->left_thumbnail_file_path = NULL; } } @@ -1197,32 +1037,77 @@ static void xmb_set_thumbnail_system(void *data, char*s, size_t len) if (!xmb) return; - if (!string_is_empty(xmb->thumbnail_system)) - free(xmb->thumbnail_system); - /* There is only one mame thumbnail repo */ - if (strncmp("MAME", s, 4) == 0) - strcpy(s, "MAME"); - xmb->thumbnail_system = strdup(s); + menu_thumbnail_set_system(xmb->thumbnail_path_data, s); } -static void xmb_reset_thumbnail_content(void *data) +static void xmb_unload_thumbnail_textures(void *data) { xmb_handle_t *xmb = (xmb_handle_t*)data; if (!xmb) return; - if (!string_is_empty(xmb->thumbnail_content)) - free(xmb->thumbnail_content); - xmb->thumbnail_content = NULL; + + if (xmb->thumbnail) + video_driver_texture_unload(&xmb->thumbnail); + if (xmb->left_thumbnail) + video_driver_texture_unload(&xmb->left_thumbnail); } static void xmb_set_thumbnail_content(void *data, char *s, size_t len) { + size_t selection = menu_navigation_get_selection(); xmb_handle_t *xmb = (xmb_handle_t*)data; if (!xmb) return; - if (!string_is_empty(xmb->thumbnail_content)) - free(xmb->thumbnail_content); - xmb->thumbnail_content = strdup(s); + + if (xmb->is_playlist) + { + /* Playlist content */ + if (string_is_empty(s)) + menu_thumbnail_set_content_playlist(xmb->thumbnail_path_data, + playlist_get_cached(), selection); + } + else if (xmb->is_db_manager_list) + { + /* Database list content */ + if (string_is_empty(s)) + { + menu_entry_t entry; + + menu_entry_init(&entry); + menu_entry_get(&entry, 0, selection, NULL, true); + + if (!string_is_empty(entry.path)) + menu_thumbnail_set_content(xmb->thumbnail_path_data, entry.path); + + menu_entry_free(&entry); + } + } + else if (string_is_equal(s, "imageviewer")) + { + /* Filebrowser image updates */ + menu_entry_t entry; + file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); + xmb_node_t *node = (xmb_node_t*)file_list_get_userdata_at_offset(selection_buf, selection); + + menu_entry_init(&entry); + menu_entry_get(&entry, 0, selection, NULL, true); + + if (node) + if (!string_is_empty(entry.path) && !string_is_empty(node->fullpath)) + menu_thumbnail_set_content_image(xmb->thumbnail_path_data, node->fullpath, entry.path); + + menu_entry_free(&entry); + } + else if (!string_is_empty(s)) + { + /* Annoying leftovers... + * This is required to ensure that thumbnails are + * updated correctly when navigating deeply through + * the sublevels of database manager lists. + * Showing thumbnails on database entries is a + * pointless nuisance and a waste of CPU cycles, IMHO... */ + menu_thumbnail_set_content(xmb->thumbnail_path_data, s); + } } static void xmb_update_savestate_thumbnail_image(void *data) @@ -1259,8 +1144,6 @@ static void xmb_selection_pointer_changed( menu_list_t *menu_list = NULL; file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); size_t selection = menu_navigation_get_selection(); - const char *thumb_ident = xmb_thumbnails_ident('R'); - const char *lft_thumb_ident= xmb_thumbnails_ident('L'); menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); menu_entry_init(&entry); @@ -1302,64 +1185,44 @@ static void xmb_selection_pointer_changed( ia = xmb->items_active_alpha; iz = xmb->items_active_zoom; - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) || !string_is_equal(lft_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) || menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) { - if ((xmb_system_tab > XMB_SYSTEM_TAB_SETTINGS && depth == 1) || - (xmb_system_tab < XMB_SYSTEM_TAB_SETTINGS && depth == 4)) + bool update_thumbnails = false; + + /* Playlist updates */ + if (((xmb_system_tab > XMB_SYSTEM_TAB_SETTINGS && depth == 1) || + (xmb_system_tab < XMB_SYSTEM_TAB_SETTINGS && depth == 4)) && + xmb->is_playlist) { - if (!string_is_empty(entry.path)) - xmb_set_thumbnail_content(xmb, entry.path, 0 /* will be ignored */); - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - xmb_update_thumbnail_path(xmb, i, 'R'); - xmb_update_thumbnail_image(xmb); - } - if (!string_is_equal(lft_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - xmb_update_thumbnail_path(xmb, i, 'L'); - xmb_update_thumbnail_image(xmb); - } + xmb_set_thumbnail_content(xmb, "", 0 /* will be ignored */); + update_thumbnails = true; } - else if (((entry_type == FILE_TYPE_IMAGE || entry_type == FILE_TYPE_IMAGEVIEWER || - entry_type == FILE_TYPE_RDB || entry_type == FILE_TYPE_RDB_ENTRY) - && xmb_system_tab <= XMB_SYSTEM_TAB_SETTINGS)) + /* Database list updates + * (pointless nuisance...) */ + else if (depth == 4 && xmb->is_db_manager_list) { - if (!string_is_empty(entry.path)) - xmb_set_thumbnail_content(xmb, entry.path, 0 /* will be ignored */); - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - xmb_update_thumbnail_path(xmb, i, 'R'); - xmb_update_thumbnail_image(xmb); - } - else if (!string_is_equal(lft_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - xmb_update_thumbnail_path(xmb, i, 'L'); - xmb_update_thumbnail_image(xmb); - } + xmb_set_thumbnail_content(xmb, "", 0 /* will be ignored */); + update_thumbnails = true; } - else if (filebrowser_get_type() != FILEBROWSER_NONE) + /* Filebrowser image updates */ + else if (entry_type == FILE_TYPE_IMAGEVIEWER || entry_type == FILE_TYPE_IMAGE) { - xmb_reset_thumbnail_content(xmb); - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - xmb_update_thumbnail_path(xmb, i, 'R'); - xmb_update_thumbnail_image(xmb); - } - else if (!string_is_equal(lft_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - xmb_update_thumbnail_path(xmb, i, 'L'); - xmb_update_thumbnail_image(xmb); - } + xmb_set_thumbnail_content(xmb, "imageviewer", 0 /* will be ignored */); + update_thumbnails = true; + } + + if (update_thumbnails) + { + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) + xmb_update_thumbnail_path(xmb, i /* will be ignored */, 'R'); + + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) + xmb_update_thumbnail_path(xmb, i /* will be ignored */, 'L'); + + xmb_update_thumbnail_image(xmb); } } + xmb_update_savestate_thumbnail_path(xmb, i); xmb_update_savestate_thumbnail_image(xmb); } @@ -1542,12 +1405,28 @@ static void xmb_list_open_new(xmb_handle_t *xmb, if (xmb_system_tab <= XMB_SYSTEM_TAB_SETTINGS) { - if (xmb->depth < 4) - xmb_reset_thumbnail_content(xmb); - xmb_update_thumbnail_path(xmb, 0, 'R'); - xmb_update_thumbnail_image(xmb); - xmb_update_thumbnail_path(xmb, 0, 'L'); - xmb_update_thumbnail_image(xmb); + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) || menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) + { + /* This code is horrible, full of hacks... + * This hack ensures that thumbnails are not cleared + * when selecting an entry from a collection via + * 'load content'... */ + if (xmb->depth != 5) + xmb_unload_thumbnail_textures(xmb); + + if (xmb->is_playlist || xmb->is_db_manager_list) + { + xmb_set_thumbnail_content(xmb, "", 0 /* will be ignored */); + + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) + xmb_update_thumbnail_path(xmb, 0 /* will be ignored */, 'R'); + + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) + xmb_update_thumbnail_path(xmb, 0 /* will be ignored */, 'L'); + + xmb_update_thumbnail_image(xmb); + } + } } } @@ -1861,37 +1740,22 @@ static void xmb_list_switch(xmb_handle_t *xmb) xmb_list_switch_new(xmb, selection_buf, dir, selection); xmb->categories_active_idx_old = (unsigned)xmb->categories_selection_ptr; - if (!string_is_equal(xmb_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) || menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) { - menu_entry_t entry; + xmb_unload_thumbnail_textures(xmb); - menu_entry_init(&entry); - menu_entry_get(&entry, 0, selection, NULL, true); + if (xmb->is_playlist) + { + xmb_set_thumbnail_content(xmb, "", 0 /* will be ignored */); - if (!string_is_empty(entry.path)) - xmb_set_thumbnail_content(xmb, entry.path, 0 /* will be ignored */); + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) + xmb_update_thumbnail_path(xmb, 0 /* will be ignored */, 'R'); - menu_entry_free(&entry); + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) + xmb_update_thumbnail_path(xmb, 0 /* will be ignored */, 'L'); - xmb_update_thumbnail_path(xmb, 0, 'R'); - xmb_update_thumbnail_image(xmb); - } - if (!string_is_equal(xmb_thumbnails_ident('L'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - menu_entry_t entry; - - menu_entry_init(&entry); - menu_entry_get(&entry, 0, selection, NULL, true); - - if (!string_is_empty(entry.path)) - xmb_set_thumbnail_content(xmb, entry.path, 0 /* will be ignored */); - - menu_entry_free(&entry); - - xmb_update_thumbnail_path(xmb, 0, 'L'); - xmb_update_thumbnail_image(xmb); + xmb_update_thumbnail_image(xmb); + } } } @@ -2241,27 +2105,29 @@ static void xmb_populate_entries(void *data, const char *label, unsigned k) { xmb_handle_t *xmb = (xmb_handle_t*)data; + unsigned xmb_system_tab; if (!xmb) return; + /* Determine whether this is a playlist */ + xmb_system_tab = xmb_get_system_tab(xmb, (unsigned)xmb->categories_selection_ptr); + xmb->is_playlist = (xmb_system_tab == XMB_SYSTEM_TAB_FAVORITES) || + (xmb_system_tab == XMB_SYSTEM_TAB_HISTORY) || + (xmb_system_tab == XMB_SYSTEM_TAB_IMAGES) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HORIZONTAL_MENU)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_IMAGES_LIST)); + xmb->is_playlist = xmb->is_playlist && !string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RDB_ENTRY_DETAIL)); + + /* 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)); + if (menu_driver_ctl(RARCH_MENU_CTL_IS_PREVENT_POPULATE, NULL)) { xmb_selection_pointer_changed(xmb, false); menu_driver_ctl(RARCH_MENU_CTL_UNSET_PREVENT_POPULATE, NULL); - if (!string_is_equal(xmb_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - xmb_update_thumbnail_path(xmb, 0, 'R'); - xmb_update_thumbnail_image(xmb); - } - xmb_update_savestate_thumbnail_image(xmb); - if (!string_is_equal(xmb_thumbnails_ident('L'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - xmb_update_thumbnail_path(xmb, 0, 'L'); - xmb_update_thumbnail_image(xmb); - } return; } @@ -2793,8 +2659,6 @@ static int xmb_draw_item( xmb_node_t *core_node, file_list_t *list, float *color, - const char *thumb_ident, - const char *left_thumb_ident, size_t i, size_t current, unsigned width, @@ -2908,13 +2772,9 @@ static int xmb_draw_item( { if (xmb->savestate_thumbnail || !xmb->use_ps3_layout || - (!string_is_equal - (thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) + (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) && xmb->thumbnail) || - (!string_is_equal - (left_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) + (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT) && xmb->left_thumbnail && settings->bools.menu_xmb_vertical_thumbnails) ) @@ -3075,8 +2935,6 @@ static void xmb_draw_items( menu_display_ctx_rotate_draw_t rotate_draw; xmb_node_t *core_node = NULL; size_t end = 0; - const char *thumb_ident = xmb_thumbnails_ident('R'); - const char *left_thumb_ident= xmb_thumbnails_ident('L'); if (!list || !list->size || !xmb) return; @@ -3126,7 +2984,7 @@ static void xmb_draw_items( &entry, &mymat, xmb, core_node, - list, color, thumb_ident, left_thumb_ident, + list, color, i, current, width, height); menu_entry_free(&entry); @@ -3493,9 +3351,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) xmb->icon_spacing_horizontal + pseudo_font_length + min_thumb_size) <= width)) { - if (xmb->thumbnail - && !string_is_equal(xmb_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + if (xmb->thumbnail && menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) { /* Limit thumbnail width */ @@ -3560,9 +3416,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) { /* Left Thumbnail in the left margin */ - if (xmb->left_thumbnail - && !string_is_equal(xmb_thumbnails_ident('L'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + if (xmb->left_thumbnail && menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) { /* Limit left thumbnail width */ @@ -3631,9 +3485,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) xmb->icon_spacing_horizontal + pseudo_font_length + min_thumb_size) <= width)) { - if (xmb->left_thumbnail - && !string_is_equal(xmb_thumbnails_ident('L'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + if (xmb->left_thumbnail && menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) { /* Limit left thumbnail width */ @@ -3696,9 +3548,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) { /* Left Thumbnail in the left margin */ - if (xmb->left_thumbnail - && !string_is_equal(xmb_thumbnails_ident('L'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + if (xmb->left_thumbnail && menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) { /* Limit left thumbnail width */ @@ -3943,9 +3793,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) xmb->icon_spacing_horizontal + pseudo_font_length + min_thumb_size) <= width)) { - if (xmb->thumbnail && - !string_is_equal(xmb_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + if (xmb->thumbnail && menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) { /* Limit right thumbnail width */ @@ -4007,9 +3855,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) xmb->icon_spacing_horizontal + pseudo_font_length + min_thumb_size) <= width)) { - if (xmb->left_thumbnail && - !string_is_equal(xmb_thumbnails_ident('L'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + if (xmb->left_thumbnail && menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) { /* Limit left thumbnail width */ @@ -4520,6 +4366,10 @@ static void *xmb_init(void **userdata, bool video_is_threaded) xmb_init_ribbon(xmb); + xmb->thumbnail_path_data = menu_thumbnail_path_init(); + if (!xmb->thumbnail_path_data) + goto error; + return menu; error: @@ -4567,18 +4417,13 @@ static void xmb_free(void *data) if (!string_is_empty(xmb->box_message)) free(xmb->box_message); - if (!string_is_empty(xmb->thumbnail_system)) - free(xmb->thumbnail_system); - if (!string_is_empty(xmb->thumbnail_content)) - free(xmb->thumbnail_content); if (!string_is_empty(xmb->savestate_thumbnail_file_path)) free(xmb->savestate_thumbnail_file_path); - if (!string_is_empty(xmb->thumbnail_file_path)) - free(xmb->thumbnail_file_path); - if (!string_is_empty(xmb->left_thumbnail_file_path)) - free(xmb->left_thumbnail_file_path); if (!string_is_empty(xmb->bg_file_path)) free(xmb->bg_file_path); + + if (xmb->thumbnail_path_data) + free(xmb->thumbnail_path_data); } font_driver_bind_block(NULL, NULL); @@ -5087,16 +4932,14 @@ static void xmb_context_reset_internal(xmb_handle_t *xmb, xmb_context_reset_horizontal_list(xmb); - if (!string_is_equal(xmb_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) || menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) { - xmb_update_thumbnail_path(xmb, 0, 'R'); - xmb_update_thumbnail_image(xmb); - } - if (!string_is_equal(xmb_thumbnails_ident('L'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - xmb_update_thumbnail_path(xmb, 0, 'L'); + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) + xmb_update_thumbnail_path(xmb, 0, 'R'); + + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) + xmb_update_thumbnail_path(xmb, 0, 'L'); + xmb_update_thumbnail_image(xmb); } xmb_update_savestate_thumbnail_image(xmb); @@ -5801,8 +5644,8 @@ menu_ctx_driver_t menu_ctx_xmb = { xmb_populate_entries, xmb_toggle, xmb_navigation_clear, - xmb_navigation_pointer_changed, - xmb_navigation_pointer_changed, + NULL, /*xmb_navigation_pointer_changed,*/ /* Note: navigation_set() is called each time navigation_increment/decrement() */ + NULL, /*xmb_navigation_pointer_changed,*/ /* is called, so linking these just duplicates work... */ xmb_navigation_set, xmb_navigation_pointer_changed, xmb_navigation_alphabet, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 7d3f2b7652..abd882be63 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -1323,8 +1323,24 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, strlcpy(label_spacer, PL_LABEL_SPACER_DEFAULT, sizeof(label_spacer)); } - /* Inform menu driver of current system name */ - if (!string_is_empty(info->path)) + /* Inform menu driver of current system name + * > Note: history, favorites and images_history + * require special treatment here, since info->path + * is nonsensical in these cases (and we *do* need + * to call set_thumbnail_system() in these cases, + * since all three playlist types have thumbnail + * support) */ + if (string_is_equal(path_playlist, "history") || + string_is_equal(path_playlist, "favorites") || + string_is_equal(path_playlist, "images_history")) + { + char system_name[15]; + system_name[0] = '\0'; + + strlcpy(system_name, path_playlist, sizeof(system_name)); + menu_driver_set_thumbnail_system(system_name, sizeof(system_name)); + } + else if (!string_is_empty(info->path)) { char lpl_basename[PATH_MAX_LENGTH]; lpl_basename[0] = '\0'; @@ -1394,24 +1410,6 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, } } - /* If this is a standard collection (not a history list or - * favourites), trigger thumbnail update for current selection. - * Note: Thumbnail updates must be omitted when using RGUI, - * since this functionality is handled elsewhere... */ - if (i == selection) - { - if (is_collection && !string_is_empty(label) && !is_rgui) - { - char *content_basename = strdup(label); - /* Note: If menu_driver_set_thumbnail_content() accepted a const pointer, - * we could save a string duplication here... */ - menu_driver_set_thumbnail_content(content_basename, strlen(content_basename) + 1); - menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_PATH, NULL); - menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_IMAGE, NULL); - free(content_basename); - } - } - if (!string_is_empty(path)) { /* Standard playlist entry @@ -1721,12 +1719,15 @@ static int menu_displaylist_parse_database_entry(menu_handle_t *menu, snprintf(crc_str, sizeof(crc_str), "%08X", db_info_entry->crc32); - /* It is unclear why parsing a database should trigger a - * thumbnail update, but I guess this is here for a reason... - * Regardless, thumbnail updates must be disabled when using + /* This allows thumbnails to be shown while viewing database + * entries... + * It only makes sense to do this for the first info entry, + * since menu drivers cannot handle multiple successive + * calls of menu_driver_set_thumbnail_content()... + * Note that thumbnail updates must be disabled when using * RGUI, since this functionality is handled elsewhere * (and doing it here creates harmful conflicts) */ - if (!string_is_equal(settings->arrays.menu_driver, "rgui")) + if ((i == 0) && !string_is_equal(settings->arrays.menu_driver, "rgui")) { if (!string_is_empty(db_info_entry->name)) strlcpy(thumbnail_content, db_info_entry->name, diff --git a/menu/menu_thumbnail_path.c b/menu/menu_thumbnail_path.c new file mode 100644 index 0000000000..6f554e3100 --- /dev/null +++ b/menu/menu_thumbnail_path.c @@ -0,0 +1,560 @@ +/* Copyright (C) 2010-2019 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (runtime_file.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "../configuration.h" +#include "../msg_hash.h" +#include "../paths.h" +#include "../file_path_special.h" + +#include "menu_driver.h" +#include "widgets/menu_entry.h" + +#include "menu_thumbnail_path.h" + +/* Used fixed size char arrays here, just to avoid + * the inconvenience of having to calloc()/free() + * each individual entry by hand... */ +struct menu_thumbnail_path_data +{ + char system[PATH_MAX_LENGTH]; + char content_path[PATH_MAX_LENGTH]; + char content_label[PATH_MAX_LENGTH]; + char content_core_name[PATH_MAX_LENGTH]; + char content_db_name[PATH_MAX_LENGTH]; + char content_img[PATH_MAX_LENGTH]; + char right_path[PATH_MAX_LENGTH]; + char left_path[PATH_MAX_LENGTH]; +}; + +/* Initialisation */ + +/* Creates new thumbnail path data container. + * Returns handle to new menu_thumbnail_path_data_t object. + * on success, otherwise NULL. + * Note: Returned object must be free()d */ +menu_thumbnail_path_data_t *menu_thumbnail_path_init() +{ + menu_thumbnail_path_data_t *path_data = NULL; + path_data = (menu_thumbnail_path_data_t*)calloc(1, sizeof(*path_data)); + if (!path_data) + return NULL; + return path_data; +} + +/* Resets thumbnail path data + * (blanks all internal string containers) */ +void menu_thumbnail_path_reset(menu_thumbnail_path_data_t *path_data) +{ + if (!path_data) + return; + + path_data->system[0] = '\0'; + path_data->content_path[0] = '\0'; + path_data->content_label[0] = '\0'; + path_data->content_core_name[0] = '\0'; + path_data->content_db_name[0] = '\0'; + path_data->content_img[0] = '\0'; + path_data->right_path[0] = '\0'; + path_data->left_path[0] = '\0'; +} + +/* Utility Functions */ + +/* Returns currently set thumbnail 'type' (Named_Snaps, + * Named_Titles, Named_Boxarts) for specified thumbnail + * identifier (right, left) */ +const char *menu_thumbnail_get_type(enum menu_thumbnail_id thumbnail_id) +{ + settings_t *settings = config_get_ptr(); + unsigned type = 0; + + if (!settings) + return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF); + + switch (thumbnail_id) + { + case MENU_THUMBNAIL_RIGHT: + type = settings->uints.menu_thumbnails; + break; + case MENU_THUMBNAIL_LEFT: + type = settings->uints.menu_left_thumbnails; + break; + default: + return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF); + } + + switch (type) + { + case 1: + return "Named_Snaps"; + case 2: + return "Named_Titles"; + case 3: + return "Named_Boxarts"; + case 0: + default: + break; + } + + return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF); +} + +/* Returns true if specified thumbnail is enabled + * (i.e. if 'type' is not equal to MENU_ENUM_LABEL_VALUE_OFF) */ +bool menu_thumbnail_is_enabled(enum menu_thumbnail_id thumbnail_id) +{ + settings_t *settings = config_get_ptr(); + + if (!settings) + return false; + + switch (thumbnail_id) + { + case MENU_THUMBNAIL_RIGHT: + return settings->uints.menu_thumbnails != 0; + case MENU_THUMBNAIL_LEFT: + return settings->uints.menu_left_thumbnails != 0; + break; + default: + break; + } + + return false; +} + +/* Setters */ + +/* Fills content_img field of path_data using existing + * content_label field (for internal use only) */ +static void fill_content_img(menu_thumbnail_path_data_t *path_data) +{ + char *scrub_char_pointer = NULL; + + /* Copy source label string */ + strlcpy(path_data->content_img, + path_data->content_label, sizeof(path_data->content_img)); + + /* Scrub characters that are not cross-platform and/or violate the + * No-Intro filename standard: + * http://datomatic.no-intro.org/stuff/The%20Official%20No-Intro%20Convention%20(20071030).zip + * Replace these characters in the entry name with underscores */ + while((scrub_char_pointer = strpbrk(path_data->content_img, "&*/:`\"<>?\\|"))) + *scrub_char_pointer = '_'; + + /* Add PNG extension */ + strlcat(path_data->content_img, + file_path_str(FILE_PATH_PNG_EXTENSION), sizeof(path_data->content_img)); +} + +/* Sets current 'system' (default database name). + * Returns true if 'system' is valid. + * > Used as a fallback when individual content lacks an + * associated database name */ +bool menu_thumbnail_set_system(menu_thumbnail_path_data_t *path_data, const char *system) +{ + if (!path_data) + return false; + + /* When system is updated, must regenerate right/left + * thumbnail paths */ + path_data->right_path[0] = '\0'; + path_data->left_path[0] = '\0'; + + /* 'Reset' path_data system string */ + path_data->system[0] = '\0'; + + if (string_is_empty(system)) + return false; + + /* Hack: There is only one MAME thumbnail repo, + * so filter any input starting with 'MAME...' */ + if (strncmp(system, "MAME", 4) == 0) + strlcpy(path_data->system, "MAME", sizeof(path_data->system)); + else + strlcpy(path_data->system, system, sizeof(path_data->system)); + + return true; +} + +/* Sets current thumbnail content according to the specified label. + * Returns true if content is valid */ +bool menu_thumbnail_set_content(menu_thumbnail_path_data_t *path_data, const char *label) +{ + if (!path_data) + return false; + + /* When content is updated, must regenerate right/left + * thumbnail paths */ + path_data->right_path[0] = '\0'; + path_data->left_path[0] = '\0'; + + /* 'Reset' path_data content strings */ + path_data->content_path[0] = '\0'; + path_data->content_label[0] = '\0'; + path_data->content_core_name[0] = '\0'; + path_data->content_db_name[0] = '\0'; + path_data->content_img[0] = '\0'; + + if (string_is_empty(label)) + return false; + + /* Cache content label */ + strlcpy(path_data->content_label, label, sizeof(path_data->content_label)); + + /* Determine content image name */ + fill_content_img(path_data); + + /* Redundant error check... */ + if (string_is_empty(path_data->content_img)) + return false; + + return true; +} + +/* Sets current thumbnail content to the specified image. + * Returns true if content is valid */ +bool menu_thumbnail_set_content_image(menu_thumbnail_path_data_t *path_data, const char *img_dir, const char *img_name) +{ + if (!path_data) + return false; + + /* When content is updated, must regenerate right/left + * thumbnail paths */ + path_data->right_path[0] = '\0'; + path_data->left_path[0] = '\0'; + + /* 'Reset' path_data content strings */ + path_data->content_path[0] = '\0'; + path_data->content_label[0] = '\0'; + path_data->content_core_name[0] = '\0'; + path_data->content_db_name[0] = '\0'; + path_data->content_img[0] = '\0'; + + if (string_is_empty(img_dir)) + return false; + + if (string_is_empty(img_name)) + return false; + + if (path_is_media_type(img_name) != RARCH_CONTENT_IMAGE) + return false; + + /* Cache content image name */ + strlcpy(path_data->content_img, + img_name, sizeof(path_data->content_img)); + + /* Get image label */ + strlcpy(path_data->content_label, + path_remove_extension(path_data->content_img), sizeof(path_data->content_label)); + + /* Set file path */ + fill_pathname_join(path_data->content_path, + img_dir, img_name, sizeof(path_data->content_path)); + + /* Set core name to "imageviewer" */ + strlcpy(path_data->content_core_name, + "imageviewer", sizeof(path_data->content_core_name)); + + /* Set database name (arbitrarily) to "_images_" + * (required for compatibility with menu_thumbnail_update_path(), + * but not actually used...) */ + strlcpy(path_data->content_db_name, + "_images_", sizeof(path_data->content_db_name)); + + /* Redundant error check */ + if (string_is_empty(path_data->content_path)) + return false; + + return true; +} + +/* Sets current thumbnail content to the specified playlist entry. + * Returns true if content is valid. + * > Note: It is always best to use playlists when setting + * thumbnail content, since there is no guarantee that the + * corresponding menu entry label will contain a useful + * identifier (it may be 'tainted', e.g. with the current + * core name). 'Real' labels should be extracted from source */ +bool menu_thumbnail_set_content_playlist(menu_thumbnail_path_data_t *path_data, playlist_t *playlist, size_t idx) +{ + const char *content_path = NULL; + const char *content_label = NULL; + const char *core_name = NULL; + const char *db_name = NULL; + + if (!path_data) + return false; + + /* When content is updated, must regenerate right/left + * thumbnail paths */ + path_data->right_path[0] = '\0'; + path_data->left_path[0] = '\0'; + + /* 'Reset' path_data content strings */ + path_data->content_path[0] = '\0'; + path_data->content_label[0] = '\0'; + path_data->content_core_name[0] = '\0'; + path_data->content_db_name[0] = '\0'; + path_data->content_img[0] = '\0'; + + if (!playlist) + return false; + + if (idx >= playlist_get_size(playlist)) + return false; + + /* Read playlist values */ + playlist_get_index(playlist, idx, + &content_path, &content_label, NULL, &core_name, NULL, &db_name); + + /* Content without a path is invalid by definition */ + if (string_is_empty(content_path)) + return false; + + /* Cache content path + * (This is required for imageviewer content) */ + strlcpy(path_data->content_path, + content_path, sizeof(path_data->content_path)); + + /* Cache core name + * (This is required for imageviewer content) */ + if (!string_is_empty(core_name)) + strlcpy(path_data->content_core_name, + core_name, sizeof(path_data->content_core_name)); + + /* Get content label */ + if (!string_is_empty(content_label)) + strlcpy(path_data->content_label, + content_label, sizeof(path_data->content_label)); + else + fill_short_pathname_representation(path_data->content_label, + content_path, sizeof(path_data->content_label)); + + /* Determine content image name */ + fill_content_img(path_data); + + /* Redundant error check... */ + if (string_is_empty(path_data->content_img)) + return false; + + /* Thumbnail image name is done -> now check if + * per-content database name is defined */ + if (!string_is_empty(db_name)) + { + /* Hack: There is only one MAME thumbnail repo, + * so filter any input starting with 'MAME...' */ + if (strncmp(db_name, "MAME", 4) == 0) + strlcpy(path_data->content_db_name, + "MAME", sizeof(path_data->content_db_name)); + else + { + char tmp_buf[PATH_MAX_LENGTH]; + tmp_buf[0] = '\0'; + + strlcpy(tmp_buf, db_name, sizeof(tmp_buf)); + + /* Remove .lpl extension + * > path_remove_extension() requires a char * (not const) + * so have to use a temporary buffer... */ + strlcpy(path_data->content_db_name, + path_remove_extension(tmp_buf), sizeof(path_data->content_db_name)); + } + } + + return true; +} + +/* Updaters */ + +/* Updates path for specified thumbnail identifier (right, left). + * Must be called after: + * - menu_thumbnail_set_system() + * - menu_thumbnail_set_content*() + * ...and before: + * - menu_thumbnail_get_path() + * Returns true if generated path is valid */ +bool menu_thumbnail_update_path(menu_thumbnail_path_data_t *path_data, enum menu_thumbnail_id thumbnail_id) +{ + settings_t *settings = config_get_ptr(); + const char *type = menu_thumbnail_get_type(thumbnail_id); + const char *system_name = NULL; + char *thumbnail_path = NULL; + + if (!path_data) + return false; + + /* Determine which path we are updating... */ + switch (thumbnail_id) + { + case MENU_THUMBNAIL_RIGHT: + thumbnail_path = path_data->right_path; + break; + case MENU_THUMBNAIL_LEFT: + thumbnail_path = path_data->left_path; + break; + default: + return false; + } + + thumbnail_path[0] = '\0'; + + /* Sundry error checking */ + if (!settings) + return false; + + if (string_is_empty(settings->paths.directory_thumbnails)) + return false; + + if (!menu_thumbnail_is_enabled(thumbnail_id)) + return false; + + /* Generate new path */ + + /* > Check path_data for empty strings */ + if (string_is_empty(path_data->content_img) || + (string_is_empty(path_data->system) && + string_is_empty(path_data->content_db_name))) + return false; + + /* > Get current system */ + system_name = string_is_empty(path_data->content_db_name) ? + path_data->system : path_data->content_db_name; + + /* > Special case: thumbnail for imageviewer content + * is the image file itself */ + if (string_is_equal(system_name, "images_history") || + string_is_equal(path_data->content_core_name, "imageviewer")) + { + if (string_is_empty(path_data->content_path)) + return false; + + /* imageviewer content is identical for left and right thumbnails */ + if (path_is_media_type(path_data->content_path) == RARCH_CONTENT_IMAGE) + strlcpy(thumbnail_path, + path_data->content_path, PATH_MAX_LENGTH * sizeof(char)); + } + else + { + char tmp_buf[PATH_MAX_LENGTH]; + tmp_buf[0] = '\0'; + + /* > Normal content: assemble path */ + + /* >> Base + system name */ + fill_pathname_join(thumbnail_path, settings->paths.directory_thumbnails, + system_name, PATH_MAX_LENGTH * sizeof(char)); + + /* >> Add type */ + fill_pathname_join(tmp_buf, thumbnail_path, type, sizeof(tmp_buf)); + + /* >> Add content image */ + thumbnail_path[0] = '\0'; + fill_pathname_join(thumbnail_path, tmp_buf, + path_data->content_img, PATH_MAX_LENGTH * sizeof(char)); + } + + /* Final error check - is cached path empty? */ + if (string_is_empty(thumbnail_path)) + return false; + + return true; +} + +/* Getters */ + +/* Fetches the current thumbnail file path of the + * specified thumbnail 'type'. + * Returns true if path is valid. */ +bool menu_thumbnail_get_path(menu_thumbnail_path_data_t *path_data, enum menu_thumbnail_id thumbnail_id, const char **path) +{ + char *thumbnail_path = NULL; + + if (!path_data) + return false; + + if (!path) + return false; + + switch (thumbnail_id) + { + case MENU_THUMBNAIL_RIGHT: + thumbnail_path = path_data->right_path; + break; + case MENU_THUMBNAIL_LEFT: + thumbnail_path = path_data->left_path; + break; + default: + return false; + } + + if (string_is_empty(thumbnail_path)) + return false; + + *path = thumbnail_path; + + return true; +} + +/* Fetches current thumbnail label. + * Returns true if label is valid. */ +bool menu_thumbnail_get_label(menu_thumbnail_path_data_t *path_data, const char **label) +{ + if (!path_data) + return false; + + if (!label) + return false; + + if (string_is_empty(path_data->content_label)) + return false; + + *label = path_data->content_label; + + return true; +} + +/* Fetches current thumbnail core name. + * Returns true if core name is valid. */ +bool menu_thumbnail_get_core_name(menu_thumbnail_path_data_t *path_data, const char **core_name) +{ + if (!path_data) + return false; + + if (!core_name) + return false; + + if (string_is_empty(path_data->content_core_name)) + return false; + + *core_name = path_data->content_core_name; + + return true; +} diff --git a/menu/menu_thumbnail_path.h b/menu/menu_thumbnail_path.h new file mode 100644 index 0000000000..bc98cbcb02 --- /dev/null +++ b/menu/menu_thumbnail_path.h @@ -0,0 +1,129 @@ +/* Copyright (C) 2010-2019 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (runtime_file.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __MENU_THUMBNAIL_PATH_H +#define __MENU_THUMBNAIL_PATH_H + +#include +#include + +#include + +#include "../playlist.h" + +RETRO_BEGIN_DECLS + +/* Note: This implementation reflects the current + * setup of: + * - menu_driver_set_thumbnail_system() + * - menu_driver_set_thumbnail_content() + * - menu_driver_update_thumbnail_path() + * This is absolutely not the best way to handle things, + * but I have no interest in rewriting the existing + * menu code... */ + +enum menu_thumbnail_id +{ + MENU_THUMBNAIL_RIGHT = 0, + MENU_THUMBNAIL_LEFT +}; + +/* Prevent direct access to menu_thumbnail_path_data_t members */ +typedef struct menu_thumbnail_path_data menu_thumbnail_path_data_t; + +/* Initialisation */ + +/* Creates new thumbnail path data container. + * Returns handle to new menu_thumbnail_path_data_t object. + * on success, otherwise NULL. + * Note: Returned object must be free()d */ +menu_thumbnail_path_data_t *menu_thumbnail_path_init(); + +/* Resets thumbnail path data + * (blanks all internal string containers) */ +void menu_thumbnail_path_reset(menu_thumbnail_path_data_t *path_data); + +/* Utility Functions */ + +/* Returns currently set thumbnail 'type' (Named_Snaps, + * Named_Titles, Named_Boxarts) for specified thumbnail + * identifier (right, left) */ +const char *menu_thumbnail_get_type(enum menu_thumbnail_id thumbnail_id); + +/* Returns true if specified thumbnail is enabled + * (i.e. if 'type' is not equal to MENU_ENUM_LABEL_VALUE_OFF) */ +bool menu_thumbnail_is_enabled(enum menu_thumbnail_id thumbnail_id); + +/* Setters */ + +/* Sets current 'system' (default database name). + * Returns true if 'system' is valid. + * > Used as a fallback when individual content lacks an + * associated database name */ +bool menu_thumbnail_set_system(menu_thumbnail_path_data_t *path_data, const char *system); + +/* Sets current thumbnail content according to the specified label. + * Returns true if content is valid */ +bool menu_thumbnail_set_content(menu_thumbnail_path_data_t *path_data, const char *label); + +/* Sets current thumbnail content to the specified image. + * Returns true if content is valid */ +bool menu_thumbnail_set_content_image(menu_thumbnail_path_data_t *path_data, const char *img_dir, const char *img_name); + +/* Sets current thumbnail content to the specified playlist entry. + * Returns true if content is valid. + * > Note: It is always best to use playlists when setting + * thumbnail content, since there is no guarantee that the + * corresponding menu entry label will contain a useful + * identifier (it may be 'tainted', e.g. with the current + * core name). 'Real' labels should be extracted from source */ +bool menu_thumbnail_set_content_playlist(menu_thumbnail_path_data_t *path_data, playlist_t *playlist, size_t idx); + +/* Updaters */ + +/* Updates path for specified thumbnail identifier (right, left). + * Must be called after: + * - menu_thumbnail_set_system() + * - menu_thumbnail_set_content*() + * ...and before: + * - menu_thumbnail_get_path() + * Returns true if generated path is valid */ +bool menu_thumbnail_update_path(menu_thumbnail_path_data_t *path_data, enum menu_thumbnail_id thumbnail_id); + +/* Getters */ + +/* Fetches the current thumbnail file path of the + * specified thumbnail 'type'. + * Returns true if path is valid. */ +bool menu_thumbnail_get_path(menu_thumbnail_path_data_t *path_data, enum menu_thumbnail_id thumbnail_id, const char **path); + +/* Fetches current thumbnail label. + * Returns true if label is valid. */ +bool menu_thumbnail_get_label(menu_thumbnail_path_data_t *path_data, const char **label); + +/* Fetches current thumbnail core name. + * Returns true if core name is valid. */ +bool menu_thumbnail_get_core_name(menu_thumbnail_path_data_t *path_data, const char **core_name); + +RETRO_END_DECLS + +#endif From 970404dc28635f659afa5c7bf603cbb11e33b9ea Mon Sep 17 00:00:00 2001 From: bparker06 Date: Thu, 14 Mar 2019 08:37:52 -0400 Subject: [PATCH 003/237] ios buildfix --- frontend/drivers/platform_darwin.m | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/drivers/platform_darwin.m b/frontend/drivers/platform_darwin.m index 5bf829b316..00125d96cd 100644 --- a/frontend/drivers/platform_darwin.m +++ b/frontend/drivers/platform_darwin.m @@ -53,6 +53,7 @@ #include #include #include +#include #ifdef HAVE_MENU #include "../../menu/menu_driver.h" From 643cd1923e40be9320b457fcf678d9c0a7f44958 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 14 Mar 2019 14:14:44 +0100 Subject: [PATCH 004/237] CXX_BUILD / C89_BUILD buildfixes --- gfx/drivers/d3d10.c | 3 ++- gfx/drivers/d3d11.c | 3 ++- gfx/video_shader_parse.c | 2 +- menu/drivers/ozone/ozone.c | 18 +++++++++-------- menu/drivers/xmb.c | 14 ++++++------- menu/drivers_display/menu_display_gl_core.c | 22 ++++++++++++--------- menu/menu_driver.c | 2 +- menu/menu_driver.h | 2 +- 8 files changed, 37 insertions(+), 29 deletions(-) diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index e518204464..812986a717 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -997,7 +997,8 @@ d3d10_gfx_init(const video_info_t* video, IDXGIAdapter_GetDesc(d3d10->adapter, &desc); - utf16_to_char_string(desc.Description, str, sizeof(str)); + utf16_to_char_string((const uint16_t*) + desc.Description, str, sizeof(str)); RARCH_LOG("[D3D10]: Using GPU: %s\n", str); diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 1b92a226d5..8921fd44eb 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -1069,7 +1069,8 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i IDXGIAdapter_GetDesc(d3d11->adapter, &desc); - utf16_to_char_string(desc.Description, str, sizeof(str)); + utf16_to_char_string((const uint16_t*) + desc.Description, str, sizeof(str)); RARCH_LOG("[D3D11]: Using GPU: %s\n", str); diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index f91402a272..961a5695aa 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -1122,7 +1122,7 @@ void video_shader_write_conf_cgp(config_file_t *conf, bool video_shader_is_supported(enum rarch_shader_type type) { gfx_ctx_flags_t flags; - unsigned flag; + enum display_flags flag = GFX_CTX_FLAGS_NONE; switch (type) { diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index 7cb6f53659..c0ad56b8ea 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1353,7 +1353,7 @@ static void ozone_draw_footer(ozone_handle_t *ozone, video_frame_info_t *video_i } -static void ozone_set_thumbnail_content(void *data, char *s, size_t len) +static void ozone_set_thumbnail_content(void *data, const char *s) { ozone_handle_t *ozone = (ozone_handle_t*)data; if (!ozone) @@ -1403,8 +1403,10 @@ static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) if (ozone->selection != new_selection) { - ozone->selection_old = ozone->selection; - ozone->selection = new_selection; + ozone_node_t *node = NULL; + + ozone->selection_old = ozone->selection; + ozone->selection = new_selection; ozone->cursor_in_sidebar_old = ozone->cursor_in_sidebar; @@ -1412,7 +1414,7 @@ static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) ozone_update_scroll(ozone, allow_animation, node); /* Update thumbnail */ - ozone_node_t *node = (ozone_node_t*) + node = (ozone_node_t*) file_list_get_userdata_at_offset(selection_buf, ozone->selection); if (node) @@ -1432,7 +1434,7 @@ static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) if (ozone->is_playlist && ozone->depth == 1) { if (!string_is_empty(entry.path)) - ozone_set_thumbnail_content(ozone, entry.path, 0 /* will be ignored */); + ozone_set_thumbnail_content(ozone, entry.path); if (!string_is_equal(thumb_ident, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) { @@ -1451,7 +1453,7 @@ static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) && ozone->tabs[ozone->categories_selection_ptr] <= OZONE_SYSTEM_TAB_SETTINGS)) { if (!string_is_empty(entry.path)) - ozone_set_thumbnail_content(ozone, entry.path, 0 /* will be ignored */); + ozone_set_thumbnail_content(ozone, entry.path); if (!string_is_equal(thumb_ident, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) { @@ -1860,7 +1862,7 @@ static void ozone_populate_entries(void *data, const char *path, const char *lab menu_entry_get(&entry, 0, ozone->selection, NULL, true); if (!string_is_empty(entry.path)) - ozone_set_thumbnail_content(ozone, entry.path, 0 /* will be ignored */); + ozone_set_thumbnail_content(ozone, entry.path); menu_entry_free(&entry); @@ -1876,7 +1878,7 @@ static void ozone_populate_entries(void *data, const char *path, const char *lab menu_entry_get(&entry, 0, ozone->selection, NULL, true); if (!string_is_empty(entry.path)) - ozone_set_thumbnail_content(ozone, entry.path, 0 /* will be ignored */); + ozone_set_thumbnail_content(ozone, entry.path); menu_entry_free(&entry); diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index efd5f76741..5a865c853e 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -1052,9 +1052,9 @@ static void xmb_unload_thumbnail_textures(void *data) video_driver_texture_unload(&xmb->left_thumbnail); } -static void xmb_set_thumbnail_content(void *data, char *s, size_t len) +static void xmb_set_thumbnail_content(void *data, const char *s) { - size_t selection = menu_navigation_get_selection(); + size_t selection = menu_navigation_get_selection(); xmb_handle_t *xmb = (xmb_handle_t*)data; if (!xmb) return; @@ -1194,20 +1194,20 @@ static void xmb_selection_pointer_changed( (xmb_system_tab < XMB_SYSTEM_TAB_SETTINGS && depth == 4)) && xmb->is_playlist) { - xmb_set_thumbnail_content(xmb, "", 0 /* will be ignored */); + xmb_set_thumbnail_content(xmb, NULL); update_thumbnails = true; } /* Database list updates * (pointless nuisance...) */ else if (depth == 4 && xmb->is_db_manager_list) { - xmb_set_thumbnail_content(xmb, "", 0 /* will be ignored */); + xmb_set_thumbnail_content(xmb, NULL); update_thumbnails = true; } /* Filebrowser image updates */ else if (entry_type == FILE_TYPE_IMAGEVIEWER || entry_type == FILE_TYPE_IMAGE) { - xmb_set_thumbnail_content(xmb, "imageviewer", 0 /* will be ignored */); + xmb_set_thumbnail_content(xmb, "imageviewer"); update_thumbnails = true; } @@ -1416,7 +1416,7 @@ static void xmb_list_open_new(xmb_handle_t *xmb, if (xmb->is_playlist || xmb->is_db_manager_list) { - xmb_set_thumbnail_content(xmb, "", 0 /* will be ignored */); + xmb_set_thumbnail_content(xmb, NULL); if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) xmb_update_thumbnail_path(xmb, 0 /* will be ignored */, 'R'); @@ -1746,7 +1746,7 @@ static void xmb_list_switch(xmb_handle_t *xmb) if (xmb->is_playlist) { - xmb_set_thumbnail_content(xmb, "", 0 /* will be ignored */); + xmb_set_thumbnail_content(xmb, NULL); if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) xmb_update_thumbnail_path(xmb, 0 /* will be ignored */, 'R'); diff --git a/menu/drivers_display/menu_display_gl_core.c b/menu/drivers_display/menu_display_gl_core.c index 22d9b26672..c2f9df52d1 100644 --- a/menu/drivers_display/menu_display_gl_core.c +++ b/menu/drivers_display/menu_display_gl_core.c @@ -244,24 +244,28 @@ static void menu_display_gl_core_draw(menu_display_ctx_draw_t *draw, if (!loc) { const math_matrix_4x4 *mat = draw->matrix_data - ? (const math_matrix_4x4*)draw->matrix_data : menu_display_gl_core_get_default_mvp(video_info); + ? (const math_matrix_4x4*)draw->matrix_data : (const math_matrix_4x4*)menu_display_gl_core_get_default_mvp(video_info); if (gl->pipelines.alpha_blend_loc.flat_ubo_vertex >= 0) - { glUniform4fv(gl->pipelines.alpha_blend_loc.flat_ubo_vertex, 4, mat->data); - } } glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); - gl_core_bind_scratch_vbo(gl, vertex, 2 * sizeof(float) * draw->coords->vertices); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *)(uintptr_t)0); - gl_core_bind_scratch_vbo(gl, tex_coord, 2 * sizeof(float) * draw->coords->vertices); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *)(uintptr_t)0); - gl_core_bind_scratch_vbo(gl, color, 4 * sizeof(float) * draw->coords->vertices); - glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)(uintptr_t)0); + gl_core_bind_scratch_vbo(gl, vertex, + 2 * sizeof(float) * draw->coords->vertices); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), (void *)(uintptr_t)0); + gl_core_bind_scratch_vbo(gl, tex_coord, + 2 * sizeof(float) * draw->coords->vertices); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), (void *)(uintptr_t)0); + gl_core_bind_scratch_vbo(gl, color, + 4 * sizeof(float) * draw->coords->vertices); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, + 4 * sizeof(float), (void *)(uintptr_t)0); if (draw->prim_type == MENU_DISPLAY_PRIM_TRIANGLESTRIP) glDrawArrays(GL_TRIANGLE_STRIP, 0, draw->coords->vertices); diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 0f6250367f..cddec7f9da 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -2184,7 +2184,7 @@ void menu_driver_set_thumbnail_system(char *s, size_t len) void menu_driver_set_thumbnail_content(char *s, size_t len) { if (menu_driver_ctx && menu_driver_ctx->set_thumbnail_content) - menu_driver_ctx->set_thumbnail_content(menu_userdata, s, len); + menu_driver_ctx->set_thumbnail_content(menu_userdata, s); } /* Teardown function for the menu driver. */ diff --git a/menu/menu_driver.h b/menu/menu_driver.h index 5bb7ce8ca2..5136230194 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -378,7 +378,7 @@ typedef struct menu_ctx_driver void (*update_thumbnail_path)(void *data, unsigned i, char pos); void (*update_thumbnail_image)(void *data); void (*set_thumbnail_system)(void *data, char* s, size_t len); - void (*set_thumbnail_content)(void *data, char* s, size_t len); + void (*set_thumbnail_content)(void *data, const char *s); int (*osk_ptr_at_pos)(void *data, int x, int y, unsigned width, unsigned height); void (*update_savestate_thumbnail_path)(void *data, unsigned i); void (*update_savestate_thumbnail_image)(void *data); From 53268540f8cb5716bd80e530c6e9ff63f9eb0634 Mon Sep 17 00:00:00 2001 From: natinusala Date: Thu, 14 Mar 2019 15:03:53 +0100 Subject: [PATCH 005/237] ozone: fix crash --- menu/drivers/ozone/ozone.c | 126 +++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 67 deletions(-) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index c0ad56b8ea..cf53e0b78e 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1403,8 +1403,6 @@ static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) if (ozone->selection != new_selection) { - ozone_node_t *node = NULL; - ozone->selection_old = ozone->selection; ozone->selection = new_selection; @@ -1414,79 +1412,73 @@ static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) ozone_update_scroll(ozone, allow_animation, node); /* Update thumbnail */ - node = (ozone_node_t*) - file_list_get_userdata_at_offset(selection_buf, ozone->selection); - - if (node) + if (!string_is_equal(thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) || !string_is_equal(left_thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) { - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) || !string_is_equal(left_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + menu_entry_t entry; + unsigned entry_type; + unsigned i = ozone->selection; + + menu_entry_init(&entry); + menu_entry_get(&entry, 0, (unsigned)i, NULL, true); + entry_type = menu_entry_get_type_new(&entry); + + if (ozone->is_playlist && ozone->depth == 1) { - menu_entry_t entry; - unsigned entry_type; - unsigned i = ozone->selection; - - menu_entry_init(&entry); - menu_entry_get(&entry, 0, (unsigned)i, NULL, true); - entry_type = menu_entry_get_type_new(&entry); - - if (ozone->is_playlist && ozone->depth == 1) + if (!string_is_empty(entry.path)) + ozone_set_thumbnail_content(ozone, entry.path); + if (!string_is_equal(thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) { - if (!string_is_empty(entry.path)) - ozone_set_thumbnail_content(ozone, entry.path); - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, i, 'R'); - ozone_update_thumbnail_image(ozone); - } - if (!string_is_equal(left_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, i, 'L'); - ozone_update_thumbnail_image(ozone); - } + ozone_update_thumbnail_path(ozone, i, 'R'); + ozone_update_thumbnail_image(ozone); } - else if (((entry_type == FILE_TYPE_IMAGE || entry_type == FILE_TYPE_IMAGEVIEWER || - entry_type == FILE_TYPE_RDB || entry_type == FILE_TYPE_RDB_ENTRY) - && ozone->tabs[ozone->categories_selection_ptr] <= OZONE_SYSTEM_TAB_SETTINGS)) + if (!string_is_equal(left_thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) { - if (!string_is_empty(entry.path)) - ozone_set_thumbnail_content(ozone, entry.path); - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, i, 'R'); - ozone_update_thumbnail_image(ozone); - } - else if (!string_is_equal(left_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, i, 'L'); - ozone_update_thumbnail_image(ozone); - } + ozone_update_thumbnail_path(ozone, i, 'L'); + ozone_update_thumbnail_image(ozone); } - else if (filebrowser_get_type() != FILEBROWSER_NONE) - { - ozone_reset_thumbnail_content(ozone); - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, i, 'R'); - ozone_update_thumbnail_image(ozone); - } - else if (!string_is_equal(left_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, i, 'L'); - ozone_update_thumbnail_image(ozone); - } - } - menu_entry_free(&entry); } - /* TODO: Update savestate thumbnail */ + else if (((entry_type == FILE_TYPE_IMAGE || entry_type == FILE_TYPE_IMAGEVIEWER || + entry_type == FILE_TYPE_RDB || entry_type == FILE_TYPE_RDB_ENTRY) + && ozone->tabs[ozone->categories_selection_ptr] <= OZONE_SYSTEM_TAB_SETTINGS)) + { + if (!string_is_empty(entry.path)) + ozone_set_thumbnail_content(ozone, entry.path); + if (!string_is_equal(thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + ozone_update_thumbnail_path(ozone, i, 'R'); + ozone_update_thumbnail_image(ozone); + } + else if (!string_is_equal(left_thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + ozone_update_thumbnail_path(ozone, i, 'L'); + ozone_update_thumbnail_image(ozone); + } + } + else if (filebrowser_get_type() != FILEBROWSER_NONE) + { + ozone_reset_thumbnail_content(ozone); + if (!string_is_equal(thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + ozone_update_thumbnail_path(ozone, i, 'R'); + ozone_update_thumbnail_image(ozone); + } + else if (!string_is_equal(left_thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + ozone_update_thumbnail_path(ozone, i, 'L'); + ozone_update_thumbnail_image(ozone); + } + } + menu_entry_free(&entry); } + /* TODO: Update savestate thumbnail */ } } From d65068cf15bf58d54e848dc185458601fda1c6b5 Mon Sep 17 00:00:00 2001 From: natinusala Date: Thu, 14 Mar 2019 15:07:13 +0100 Subject: [PATCH 006/237] ozone: new content metadata layout --- menu/drivers/ozone/ozone.c | 14 ++++++---- menu/drivers/ozone/ozone.h | 4 +-- menu/drivers/ozone/ozone_entries.c | 44 +++++++++++------------------- 3 files changed, 26 insertions(+), 36 deletions(-) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index cf53e0b78e..1ab7215f5a 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -461,9 +461,9 @@ static void ozone_update_thumbnail_path(void *data, unsigned i, char pos) core_label = core_name; snprintf(ozone->selection_core_name, sizeof(ozone->selection_core_name), - "%s", core_label); + "%s %s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_CORE), core_label); - word_wrap(ozone->selection_core_name, ozone->selection_core_name, (unsigned)((float)ozone->dimensions.thumbnail_bar_width * (float)0.66) / ozone->footer_font_glyph_width, false); + word_wrap(ozone->selection_core_name, ozone->selection_core_name, (unsigned)((float)ozone->dimensions.thumbnail_bar_width * (float)0.85) / ozone->footer_font_glyph_width, false); ozone->selection_core_name_lines = ozone_count_lines(ozone->selection_core_name); /* Fill play time if applicable */ @@ -485,18 +485,20 @@ static void ozone_update_thumbnail_path(void *data, unsigned i, char pos) &last_played_year, &last_played_month, &last_played_day, &last_played_hour, &last_played_minute, &last_played_second); - snprintf(ozone->selection_playtime, sizeof(ozone->selection_playtime), "%02u:%02u:%02u", - runtime_hours, runtime_minutes, runtime_seconds); + snprintf(ozone->selection_playtime, sizeof(ozone->selection_playtime), "%s %02u:%02u:%02u", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME), runtime_hours, runtime_minutes, runtime_seconds); if (last_played_year == 0 && last_played_month == 0 && last_played_day == 0 && last_played_hour == 0 && last_played_minute == 0 && last_played_second == 0) { - snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s", + snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s %s", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_NEVER)); } else { - snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%04u/%02u/%02u - %02u:%02u:%02u", + snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s %04u/%02u/%02u -\n%02u:%02u:%02u", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), last_played_year, last_played_month, last_played_day, last_played_hour, last_played_minute, last_played_second); } diff --git a/menu/drivers/ozone/ozone.h b/menu/drivers/ozone/ozone.h index 0f931e9857..929468b058 100644 --- a/menu/drivers/ozone/ozone.h +++ b/menu/drivers/ozone/ozone.h @@ -238,8 +238,8 @@ struct ozone_handle uintptr_t left_thumbnail; char selection_core_name[255]; - char selection_playtime[64]; - char selection_lastplayed[64]; + char selection_playtime[255]; + char selection_lastplayed[255]; unsigned selection_core_name_lines; }; diff --git a/menu/drivers/ozone/ozone_entries.c b/menu/drivers/ozone/ozone_entries.c index c4a79eb4c8..c836c92c9c 100644 --- a/menu/drivers/ozone/ozone_entries.c +++ b/menu/drivers/ozone/ozone_entries.c @@ -138,7 +138,13 @@ void ozone_update_scroll(ozone_handle_t *ozone, bool allow_animation, ozone_node video_driver_get_size(NULL, &video_info_height); - current_selection_middle_onscreen = ozone->dimensions.header_height + ozone->dimensions.entry_padding_vertical + ozone->animations.scroll_y + node->position_y + node->height / 2; + current_selection_middle_onscreen = + ozone->dimensions.header_height + + ozone->dimensions.entry_padding_vertical + + ozone->animations.scroll_y + + node->position_y + + node->height / 2; + bottom_boundary = video_info_height - ozone->dimensions.header_height - 1 - ozone->dimensions.footer_height; entries_middle = video_info_height/2; @@ -639,12 +645,12 @@ static void ozone_draw_no_thumbnail_available(ozone_handle_t *ozone, } static void ozone_content_metadata_line(video_frame_info_t *video_info, ozone_handle_t *ozone, - unsigned *y, unsigned title_column_x, unsigned data_column_x, - const char *title, const char *data, unsigned lines_count) + unsigned *y, unsigned column_x, + const char *text, unsigned lines_count) { ozone_draw_text(video_info, ozone, - title, - title_column_x, + text, + column_x, *y + FONT_SIZE_FOOTER, TEXT_ALIGN_LEFT, video_info->width, video_info->height, @@ -653,20 +659,6 @@ static void ozone_content_metadata_line(video_frame_info_t *video_info, ozone_ha true ); - if (font_driver_get_message_width(ozone->fonts.footer, data, strlen(data), 1) > ozone->dimensions.thumbnail_bar_width / 2) - *y += font_driver_get_line_height(ozone->fonts.footer, 1); - - ozone_draw_text(video_info, ozone, - data, - data_column_x, - *y + FONT_SIZE_FOOTER, - TEXT_ALIGN_RIGHT, - video_info->width, video_info->height, - ozone->fonts.footer, - ozone->theme->text_rgba, - true - ); - *y += (font_driver_get_line_height(ozone->fonts.footer, 1) * 1.5) * lines_count; } @@ -758,8 +750,7 @@ void ozone_draw_thumbnail_bar(ozone_handle_t *ozone, video_frame_info_t *video_i unsigned y = video_info->height / 2 + ozone->dimensions.sidebar_entry_icon_padding / 2; unsigned content_metadata_padding = ozone->dimensions.sidebar_entry_icon_padding*3; unsigned separator_padding = ozone->dimensions.sidebar_entry_icon_padding*2; - unsigned title_column_x = x_position + content_metadata_padding; - unsigned data_column_x = x_position + sidebar_width - content_metadata_padding; + unsigned column_x = x_position + content_metadata_padding; /* Content metadata */ y += 10; @@ -775,26 +766,23 @@ void ozone_draw_thumbnail_bar(ozone_handle_t *ozone, video_frame_info_t *video_i /* Core association */ ozone_content_metadata_line(video_info, ozone, - &y, title_column_x, data_column_x, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_CORE), + &y, column_x, ozone->selection_core_name, ozone->selection_core_name_lines ); /* Playtime */ ozone_content_metadata_line(video_info, ozone, - &y, title_column_x, data_column_x, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME), + &y, column_x, ozone->selection_playtime, 1 ); /* Last played */ ozone_content_metadata_line(video_info, ozone, - &y, title_column_x, data_column_x, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), + &y, column_x, ozone->selection_lastplayed, - 1 + 2 ); } } From f50567d3400b55231c93f2f66424f99a5e82c059 Mon Sep 17 00:00:00 2001 From: natinusala Date: Thu, 14 Mar 2019 15:40:43 +0100 Subject: [PATCH 007/237] ozone: fix thumbnails position and size --- menu/drivers/ozone/ozone.c | 15 ++++++++++++--- menu/drivers/ozone/ozone_entries.c | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index 1ab7215f5a..e0e9c1df10 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -2333,7 +2333,7 @@ static bool ozone_load_image(void *userdata, void *data, enum menu_image_type ty ozone_handle_t *ozone = (ozone_handle_t*) userdata; unsigned sidebar_height; unsigned height; - unsigned maximum_height; + unsigned maximum_height, maximum_width; if (!ozone || !data) return false; @@ -2342,18 +2342,27 @@ static bool ozone_load_image(void *userdata, void *data, enum menu_image_type ty sidebar_height = height - ozone->dimensions.header_height - 55 - ozone->dimensions.footer_height; maximum_height = sidebar_height / 2; + maximum_width = ozone->dimensions.thumbnail_bar_width - ozone->dimensions.sidebar_entry_icon_padding * 2; switch (type) { case MENU_IMAGE_THUMBNAIL: { struct texture_image *img = (struct texture_image*)data; + float scale_down; + ozone->dimensions.thumbnail_height = ozone->dimensions.thumbnail_width * (float)img->height / (float)img->width; - if (ozone->dimensions.thumbnail_height > maximum_height) + scale_down = (float) maximum_height / ozone->dimensions.thumbnail_height; + + ozone->dimensions.thumbnail_height *= scale_down; + ozone->dimensions.thumbnail_width *= scale_down; + + if (ozone->dimensions.thumbnail_width > (float)maximum_width) { - float scale_down = (float) maximum_height / (float) ozone->dimensions.thumbnail_height; + scale_down = (float) maximum_width / ozone->dimensions.thumbnail_width; + ozone->dimensions.thumbnail_height *= scale_down; ozone->dimensions.thumbnail_width *= scale_down; } diff --git a/menu/drivers/ozone/ozone_entries.c b/menu/drivers/ozone/ozone_entries.c index c836c92c9c..12f4b1ecdc 100644 --- a/menu/drivers/ozone/ozone_entries.c +++ b/menu/drivers/ozone/ozone_entries.c @@ -700,7 +700,7 @@ void ozone_draw_thumbnail_bar(ozone_handle_t *ozone, video_frame_info_t *video_i /* Top row : thumbnail or no thumbnail available message */ if (thumbnail) { - unsigned thumb_x_position = x_position + sidebar_width/2 - (ozone->dimensions.thumbnail_width + ozone->dimensions.sidebar_entry_icon_padding) / 2; + unsigned thumb_x_position = x_position + sidebar_width/2 - ozone->dimensions.thumbnail_width / 2; unsigned thumb_y_position = video_info->height / 2 - ozone->dimensions.thumbnail_height / 2; if (!string_is_equal(ozone->selection_core_name, "imageviewer")) @@ -731,7 +731,7 @@ void ozone_draw_thumbnail_bar(ozone_handle_t *ozone, video_frame_info_t *video_i /* Bottom row : "left" thumbnail or content metadata */ if (thumbnail && left_thumbnail) { - unsigned thumb_x_position = x_position + sidebar_width/2 - (ozone->dimensions.left_thumbnail_width + ozone->dimensions.sidebar_entry_icon_padding) / 2; + unsigned thumb_x_position = x_position + sidebar_width/2 - ozone->dimensions.left_thumbnail_width / 2; unsigned thumb_y_position = video_info->height / 2 + ozone->dimensions.sidebar_entry_icon_padding / 2; ozone_draw_icon(video_info, From 43b1768ee7d094ae824b12f302a05bbc962c136a Mon Sep 17 00:00:00 2001 From: natinusala Date: Thu, 14 Mar 2019 16:56:07 +0100 Subject: [PATCH 008/237] ozone: use menu_thumbnail for thumbnails --- .vscode/settings.json | 3 +- menu/drivers/ozone/ozone.c | 463 +++++++++-------------------- menu/drivers/ozone/ozone.h | 13 +- menu/drivers/ozone/ozone_entries.c | 6 +- 4 files changed, 157 insertions(+), 328 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index e6425ac914..7f80c61030 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -66,7 +66,8 @@ "xutility": "c", "menu_input_dialog.h": "c", "menu_filebrowser.h": "c", - "ozone_sidebar.h": "c" + "ozone_sidebar.h": "c", + "menu_thumbnail_path.h": "c" }, "C_Cpp.dimInactiveRegions": false, } \ No newline at end of file diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index e0e9c1df10..aa3f572d29 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -56,32 +56,6 @@ #include "../../../tasks/tasks_internal.h" #include "../../../dynamic.h" -const char *ozone_thumbnails_ident(char pos) -{ - char folder = 0; - settings_t *settings = config_get_ptr(); - - if (pos == 'R') - folder = settings->uints.menu_thumbnails; - if (pos == 'L') - folder = settings->uints.menu_left_thumbnails; - - switch (folder) - { - case 1: - return "Named_Snaps"; - case 2: - return "Named_Titles"; - case 3: - return "Named_Boxarts"; - case 0: - default: - break; - } - - return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF); -} - ozone_node_t *ozone_alloc_node(void) { ozone_node_t *node = (ozone_node_t*)malloc(sizeof(*node)); @@ -199,6 +173,10 @@ static void *ozone_init(void **userdata, bool video_is_threaded) ozone->show_thumbnail_bar = false; ozone->dimensions.sidebar_width = 0.0f; + ozone->thumbnail_path_data = menu_thumbnail_path_init(); + if (!ozone->thumbnail_path_data) + goto error; + ozone_sidebar_update_collapse(ozone, false); ozone->system_tab_end = 0; @@ -376,17 +354,8 @@ static void ozone_free(void *data) if (!string_is_empty(ozone->pending_message)) free(ozone->pending_message); - if (!string_is_empty(ozone->thumbnail_content)) - free(ozone->thumbnail_content); - - if (!string_is_empty(ozone->thumbnail_system)) - free(ozone->thumbnail_system); - - if (!string_is_empty(ozone->thumbnail_file_path)) - free(ozone->thumbnail_file_path); - - if (!string_is_empty(ozone->left_thumbnail_file_path)) - free(ozone->left_thumbnail_file_path); + if (ozone->thumbnail_path_data) + free(ozone->thumbnail_path_data); } } @@ -402,54 +371,28 @@ unsigned ozone_count_lines(const char *str) static void ozone_update_thumbnail_path(void *data, unsigned i, char pos) { - menu_entry_t entry; - unsigned entry_type = 0; - char new_path[PATH_MAX_LENGTH] = {0}; settings_t *settings = config_get_ptr(); ozone_handle_t *ozone = (ozone_handle_t*)data; playlist_t *playlist = NULL; - const char *dir_thumbnails = settings->paths.directory_thumbnails; + const char *core_name = NULL; - menu_entry_init(&entry); - - if (!ozone || string_is_empty(dir_thumbnails)) - goto end; - - menu_entry_get(&entry, 0, i, NULL, true); - - entry_type = menu_entry_get_type_new(&entry); - - if (entry_type == FILE_TYPE_IMAGEVIEWER || entry_type == FILE_TYPE_IMAGE) - { - file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); - ozone_node_t *node = (ozone_node_t*) - file_list_get_userdata_at_offset(selection_buf, i); - - if (node && !string_is_empty(node->fullpath) && - (pos == 'R' || (pos == 'L' && string_is_equal(ozone_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))))) - { - if (!string_is_empty(entry.path)) - fill_pathname_join( - new_path, - node->fullpath, - entry.path, - sizeof(new_path)); - - goto end; - } - } - else if (filebrowser_get_type() != FILEBROWSER_NONE) - { - video_driver_texture_unload(&ozone->thumbnail); - goto end; - } + if (!ozone) + return; playlist = playlist_get_cached(); + /* imageviewer content requires special treatment... */ + menu_thumbnail_get_core_name(ozone->thumbnail_path_data, &core_name); + if (string_is_equal(core_name, "imageviewer")) + { + if ((pos == 'R') || (pos == 'L' && !menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT))) + menu_thumbnail_update_path(ozone->thumbnail_path_data, pos == 'R' ? MENU_THUMBNAIL_RIGHT : MENU_THUMBNAIL_LEFT); + } + else + menu_thumbnail_update_path(ozone->thumbnail_path_data, pos == 'R' ? MENU_THUMBNAIL_RIGHT : MENU_THUMBNAIL_LEFT); + if (playlist) { - const char *core_name = NULL; const char *core_label = NULL; playlist_get_index(playlist, i, NULL, NULL, NULL, &core_name, NULL, NULL); @@ -511,133 +454,34 @@ static void ozone_update_thumbnail_path(void *data, unsigned i, char pos) snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED)); } - - if (string_is_equal(core_name, "imageviewer")) - { - if ( - (pos == 'R') || - ( - pos == 'L' && - string_is_equal(ozone_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) - ) - ) - { - if (!string_is_empty(entry.label)) - strlcpy(new_path, entry.label, - sizeof(new_path)); - } - else - video_driver_texture_unload(&ozone->left_thumbnail); - goto end; - } } - - /* Append thumbnail system directory */ - if (!string_is_empty(ozone->thumbnail_system)) - fill_pathname_join( - new_path, - dir_thumbnails, - ozone->thumbnail_system, - sizeof(new_path)); - - if (!string_is_empty(new_path)) - { - char *tmp_new2 = (char*) - malloc(PATH_MAX_LENGTH * sizeof(char)); - - tmp_new2[0] = '\0'; - - /* Append Named_Snaps/Named_Boxarts/Named_Titles */ - if (pos == 'R') - fill_pathname_join(tmp_new2, new_path, - ozone_thumbnails_ident('R'), PATH_MAX_LENGTH * sizeof(char)); - if (pos == 'L') - fill_pathname_join(tmp_new2, new_path, - ozone_thumbnails_ident('L'), PATH_MAX_LENGTH * sizeof(char)); - - strlcpy(new_path, tmp_new2, - PATH_MAX_LENGTH * sizeof(char)); - free(tmp_new2); - } - - /* Scrub characters that are not cross-platform and/or violate the - * No-Intro filename standard: - * http://datomatic.no-intro.org/stuff/The%20Official%20No-Intro%20Convention%20(20071030).zip - * Replace these characters in the entry name with underscores. - */ - if (!string_is_empty(ozone->thumbnail_content)) - { - char *scrub_char_pointer = NULL; - char *tmp_new = (char*) - malloc(PATH_MAX_LENGTH * sizeof(char)); - char *tmp = strdup(ozone->thumbnail_content); - - tmp_new[0] = '\0'; - - while((scrub_char_pointer = strpbrk(tmp, "&*/:`\"<>?\\|"))) - *scrub_char_pointer = '_'; - - /* Look for thumbnail file with this scrubbed filename */ - - fill_pathname_join(tmp_new, - new_path, - tmp, PATH_MAX_LENGTH * sizeof(char)); - - if (!string_is_empty(tmp_new)) - strlcpy(new_path, - tmp_new, sizeof(new_path)); - - free(tmp_new); - free(tmp); - } - - /* Append png extension */ - if (!string_is_empty(new_path)) - strlcat(new_path, - file_path_str(FILE_PATH_PNG_EXTENSION), - sizeof(new_path)); - -end: - if (ozone && !string_is_empty(new_path)) - { - if (pos == 'R') - ozone->thumbnail_file_path = strdup(new_path); - if (pos == 'L') - ozone->left_thumbnail_file_path = strdup(new_path); - } - - menu_entry_free(&entry); } static void ozone_update_thumbnail_image(void *data) { - ozone_handle_t *ozone = (ozone_handle_t*)data; + ozone_handle_t *ozone = (ozone_handle_t*)data; + const char *right_thumbnail_path = NULL; + const char *left_thumbnail_path = NULL; + if (!ozone) return; - if (!(string_is_empty(ozone->thumbnail_file_path))) + if (menu_thumbnail_get_path(ozone->thumbnail_path_data, MENU_THUMBNAIL_RIGHT, &right_thumbnail_path)) { - if (filestream_exists(ozone->thumbnail_file_path)) - task_push_image_load(ozone->thumbnail_file_path, + if (filestream_exists(right_thumbnail_path)) + task_push_image_load(right_thumbnail_path, menu_display_handle_thumbnail_upload, NULL); else video_driver_texture_unload(&ozone->thumbnail); - - free(ozone->thumbnail_file_path); - ozone->thumbnail_file_path = NULL; } - if (!(string_is_empty(ozone->left_thumbnail_file_path))) + if (menu_thumbnail_get_path(ozone->thumbnail_path_data, MENU_THUMBNAIL_LEFT, &left_thumbnail_path)) { - if (filestream_exists(ozone->left_thumbnail_file_path)) - task_push_image_load(ozone->left_thumbnail_file_path, + if (filestream_exists(left_thumbnail_path)) + task_push_image_load(left_thumbnail_path, menu_display_handle_left_thumbnail_upload, NULL); else video_driver_texture_unload(&ozone->left_thumbnail); - - free(ozone->left_thumbnail_file_path); - ozone->left_thumbnail_file_path = NULL; } } @@ -829,18 +673,13 @@ static void ozone_context_reset(void *data, bool is_threaded) } /* Thumbnails */ - if (!string_is_equal(ozone_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) ozone_update_thumbnail_path(ozone, 0, 'R'); - ozone_update_thumbnail_image(ozone); - } - if (!string_is_equal(ozone_thumbnails_ident('L'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { + + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) ozone_update_thumbnail_path(ozone, 0, 'L'); - ozone_update_thumbnail_image(ozone); - } + + ozone_update_thumbnail_image(ozone); /* TODO: update savestate thumbnail image */ @@ -1354,25 +1193,74 @@ static void ozone_draw_footer(ozone_handle_t *ozone, video_frame_info_t *video_i menu_display_blend_end(video_info); } - static void ozone_set_thumbnail_content(void *data, const char *s) { + size_t selection = menu_navigation_get_selection(); ozone_handle_t *ozone = (ozone_handle_t*)data; if (!ozone) return; - if (!string_is_empty(ozone->thumbnail_content)) - free(ozone->thumbnail_content); - ozone->thumbnail_content = strdup(s); + + if (ozone->is_playlist) + { + /* Playlist content */ + if (string_is_empty(s)) + menu_thumbnail_set_content_playlist(ozone->thumbnail_path_data, + playlist_get_cached(), selection); + } + else if (ozone->is_db_manager_list) + { + /* Database list content */ + if (string_is_empty(s)) + { + menu_entry_t entry; + + menu_entry_init(&entry); + menu_entry_get(&entry, 0, selection, NULL, true); + + if (!string_is_empty(entry.path)) + menu_thumbnail_set_content(ozone->thumbnail_path_data, entry.path); + + menu_entry_free(&entry); + } + } + else if (string_is_equal(s, "imageviewer")) + { + /* Filebrowser image updates */ + menu_entry_t entry; + file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); + ozone_node_t *node = (ozone_node_t*)file_list_get_userdata_at_offset(selection_buf, selection); + + menu_entry_init(&entry); + menu_entry_get(&entry, 0, selection, NULL, true); + + if (node) + if (!string_is_empty(entry.path) && !string_is_empty(node->fullpath)) + menu_thumbnail_set_content_image(ozone->thumbnail_path_data, node->fullpath, entry.path); + + menu_entry_free(&entry); + } + else if (!string_is_empty(s)) + { + /* Annoying leftovers... + * This is required to ensure that thumbnails are + * updated correctly when navigating deeply through + * the sublevels of database manager lists. + * Showing thumbnails on database entries is a + * pointless nuisance and a waste of CPU cycles, IMHO... */ + menu_thumbnail_set_content(ozone->thumbnail_path_data, s); + } } -static void ozone_reset_thumbnail_content(void *data) +static void ozone_unload_thumbnail_textures(void *data) { ozone_handle_t *ozone = (ozone_handle_t*)data; if (!ozone) return; - if (!string_is_empty(ozone->thumbnail_content)) - free(ozone->thumbnail_content); - ozone->thumbnail_content = NULL; + + if (ozone->thumbnail) + video_driver_texture_unload(&ozone->thumbnail); + if (ozone->left_thumbnail) + video_driver_texture_unload(&ozone->left_thumbnail); } static void ozone_set_thumbnail_system(void *data, char*s, size_t len) @@ -1381,30 +1269,31 @@ static void ozone_set_thumbnail_system(void *data, char*s, size_t len) if (!ozone) return; - if (!string_is_empty(ozone->thumbnail_system)) - free(ozone->thumbnail_system); - /* There is only one mame thumbnail repo */ - if (strncmp("MAME", s, 4) == 0) - strcpy(s, "MAME"); - ozone->thumbnail_system = strdup(s); + menu_thumbnail_set_system(ozone->thumbnail_path_data, s); } static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) { + menu_entry_t entry; + file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); menu_animation_ctx_tag tag = (uintptr_t) selection_buf; + size_t selection = menu_navigation_get_selection(); size_t new_selection = menu_navigation_get_selection(); - ozone_node_t *node = (ozone_node_t*) file_list_get_userdata_at_offset(selection_buf, new_selection); + ozone_node_t *node = (ozone_node_t*) file_list_get_userdata_at_offset(selection_buf, new_selection); - const char *thumb_ident = ozone_thumbnails_ident('R'); - const char *left_thumb_ident = ozone_thumbnails_ident('L'); + menu_entry_init(&entry); if (!node) return; + menu_entry_get(&entry, 0, selection, NULL, true); + if (ozone->selection != new_selection) { + unsigned entry_type = menu_entry_get_type_new(&entry); + ozone->selection_old = ozone->selection; ozone->selection = new_selection; @@ -1414,74 +1303,46 @@ static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) ozone_update_scroll(ozone, allow_animation, node); /* Update thumbnail */ - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) || !string_is_equal(left_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) || menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) { - menu_entry_t entry; - unsigned entry_type; - unsigned i = ozone->selection; - - menu_entry_init(&entry); - menu_entry_get(&entry, 0, (unsigned)i, NULL, true); - entry_type = menu_entry_get_type_new(&entry); + bool update_thumbnails = false; + /* Playlist updates */ if (ozone->is_playlist && ozone->depth == 1) { - if (!string_is_empty(entry.path)) - ozone_set_thumbnail_content(ozone, entry.path); - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, i, 'R'); - ozone_update_thumbnail_image(ozone); - } - if (!string_is_equal(left_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, i, 'L'); - ozone_update_thumbnail_image(ozone); - } + ozone_set_thumbnail_content( ozone, ""); + update_thumbnails = true; } - else if (((entry_type == FILE_TYPE_IMAGE || entry_type == FILE_TYPE_IMAGEVIEWER || - entry_type == FILE_TYPE_RDB || entry_type == FILE_TYPE_RDB_ENTRY) - && ozone->tabs[ozone->categories_selection_ptr] <= OZONE_SYSTEM_TAB_SETTINGS)) + /* Database list updates + * (pointless nuisance...) */ + else if (ozone->depth == 4 && ozone->is_db_manager_list) { - if (!string_is_empty(entry.path)) - ozone_set_thumbnail_content(ozone, entry.path); - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, i, 'R'); - ozone_update_thumbnail_image(ozone); - } - else if (!string_is_equal(left_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, i, 'L'); - ozone_update_thumbnail_image(ozone); - } + ozone_set_thumbnail_content(ozone, ""); + update_thumbnails = true; } - else if (filebrowser_get_type() != FILEBROWSER_NONE) + /* Filebrowser image updates */ + else if (entry_type == FILE_TYPE_IMAGEVIEWER || entry_type == FILE_TYPE_IMAGE) { - ozone_reset_thumbnail_content(ozone); - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, i, 'R'); - ozone_update_thumbnail_image(ozone); - } - else if (!string_is_equal(left_thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, i, 'L'); - ozone_update_thumbnail_image(ozone); - } + ozone_set_thumbnail_content(ozone, "imageviewer"); + update_thumbnails = true; + } + + if (update_thumbnails) + { + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) + ozone_update_thumbnail_path(ozone, 0 /* will be ignored */, 'R'); + + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) + ozone_update_thumbnail_path(ozone, 0 /* will be ignored */, 'L'); + + ozone_update_thumbnail_image(ozone); } - menu_entry_free(&entry); } - /* TODO: Update savestate thumbnail */ + + //TODO: update savestate thumbnail and path } + + menu_entry_free(&entry); } static void ozone_navigation_clear(void *data, bool pending_push) @@ -1812,22 +1673,6 @@ static void ozone_populate_entries(void *data, const char *path, const char *lab if (menu_driver_ctl(RARCH_MENU_CTL_IS_PREVENT_POPULATE, NULL)) { menu_driver_ctl(RARCH_MENU_CTL_UNSET_PREVENT_POPULATE, NULL); - - /* Thumbnails */ - if (!string_is_equal(ozone_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, 0, 'R'); - ozone_update_thumbnail_image(ozone); - } - /* TODO: update savestate thumbnail image */ - if (!string_is_equal(ozone_thumbnails_ident('L'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - ozone_update_thumbnail_path(ozone, 0, 'L'); - ozone_update_thumbnail_image(ozone); - } - ozone_selection_changed(ozone, false); return; } @@ -1836,9 +1681,10 @@ static void ozone_populate_entries(void *data, const char *path, const char *lab new_depth = (int)ozone_list_get_size(ozone, MENU_LIST_PLAIN); - ozone->fade_direction = new_depth <= ozone->depth; - ozone->depth = new_depth; - ozone->is_playlist = ozone_is_playlist(ozone, true); + 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)); if (ozone->categories_selection_ptr == ozone->categories_active_idx_old) { @@ -1847,37 +1693,22 @@ static void ozone_populate_entries(void *data, const char *path, const char *lab else { /* Thumbnails */ - if (!string_is_equal(ozone_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) || menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) { - menu_entry_t entry; + ozone_unload_thumbnail_textures(ozone); - menu_entry_init(&entry); - menu_entry_get(&entry, 0, ozone->selection, NULL, true); + if (ozone->is_playlist) + { + ozone_set_thumbnail_content(ozone, ""); - if (!string_is_empty(entry.path)) - ozone_set_thumbnail_content(ozone, entry.path); + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) + ozone_update_thumbnail_path(ozone, 0 /* will be ignored */, 'R'); - menu_entry_free(&entry); + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) + ozone_update_thumbnail_path(ozone, 0 /* will be ignored */, 'L'); - ozone_update_thumbnail_path(ozone, 0, 'R'); - ozone_update_thumbnail_image(ozone); - } - if (!string_is_equal(ozone_thumbnails_ident('L'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) - { - menu_entry_t entry; - - menu_entry_init(&entry); - menu_entry_get(&entry, 0, ozone->selection, NULL, true); - - if (!string_is_empty(entry.path)) - ozone_set_thumbnail_content(ozone, entry.path); - - menu_entry_free(&entry); - - ozone_update_thumbnail_path(ozone, 0, 'L'); - ozone_update_thumbnail_image(ozone); + ozone_update_thumbnail_image(ozone); + } } } } @@ -2409,8 +2240,8 @@ menu_ctx_driver_t menu_ctx_ozone = { ozone_populate_entries, ozone_toggle, ozone_navigation_clear, - ozone_navigation_pointer_changed, - ozone_navigation_pointer_changed, + NULL, + NULL, ozone_navigation_set, ozone_navigation_pointer_changed, ozone_navigation_alphabet, diff --git a/menu/drivers/ozone/ozone.h b/menu/drivers/ozone/ozone.h index 929468b058..aae40c736c 100644 --- a/menu/drivers/ozone/ozone.h +++ b/menu/drivers/ozone/ozone.h @@ -24,7 +24,9 @@ typedef struct ozone_handle ozone_handle_t; #include +#include "../../menu_thumbnail_path.h" #include "../../menu_driver.h" + #include "../../../retroarch.h" #define ANIMATION_PUSH_ENTRY_DURATION 166 @@ -229,18 +231,17 @@ struct ozone_handle /* Thumbnails data */ bool show_thumbnail_bar; - char *thumbnail_content; - char *thumbnail_system; - char *thumbnail_file_path; - char *left_thumbnail_file_path; /* name taken from xmb for consistency but not actually on the left */ - uintptr_t thumbnail; uintptr_t left_thumbnail; + menu_thumbnail_path_data_t *thumbnail_path_data; + char selection_core_name[255]; char selection_playtime[255]; char selection_lastplayed[255]; unsigned selection_core_name_lines; + + bool is_db_manager_list; }; /* If you change this struct, also @@ -307,8 +308,6 @@ void ozone_entries_update_thumbnail_bar(ozone_handle_t *ozone, bool is_playlist, void ozone_draw_thumbnail_bar(ozone_handle_t *ozone, video_frame_info_t *video_info); -const char *ozone_thumbnails_ident(char pos); - unsigned ozone_count_lines(const char *str); #endif diff --git a/menu/drivers/ozone/ozone_entries.c b/menu/drivers/ozone/ozone_entries.c index 12f4b1ecdc..fa4647e3ff 100644 --- a/menu/drivers/ozone/ozone_entries.c +++ b/menu/drivers/ozone/ozone_entries.c @@ -682,11 +682,9 @@ void ozone_draw_thumbnail_bar(ozone_handle_t *ozone, video_frame_info_t *video_i /* Thumbnails */ thumbnail = ozone->thumbnail && - !string_is_equal(ozone_thumbnails_ident('R'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)); + menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT); left_thumbnail = ozone->left_thumbnail && - !string_is_equal(ozone_thumbnails_ident('L'), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)); + menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT); /* If user requested "left" thumbnail instead of content metadata * and no thumbnails are available, show a centered message and From 136c08a4bbdc511c976656561f3f256a9593641e Mon Sep 17 00:00:00 2001 From: Hugo Hromic Date: Thu, 14 Mar 2019 16:09:05 +0000 Subject: [PATCH 009/237] (x11_common.c) Fix C89 build --- gfx/common/x11_common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gfx/common/x11_common.c b/gfx/common/x11_common.c index cba21c6ded..f0e7d28249 100644 --- a/gfx/common/x11_common.c +++ b/gfx/common/x11_common.c @@ -572,17 +572,17 @@ bool x11_alive(void *data) case KeyRelease: /* When you receive a key release and the next event is a key press - of the same key combination, then it's auto-repeat and the + of the same key combination, then it's auto-repeat and the key wasn't actually released. */ if(XEventsQueued(g_x11_dpy, QueuedAfterReading)) { XEvent next_event; XPeekEvent(g_x11_dpy, &next_event); - if (next_event.type == KeyPress && + if (next_event.type == KeyPress && next_event.xkey.time == event.xkey.time && next_event.xkey.keycode == event.xkey.keycode) { - break; // Key wasn't actually released + break; /* Key wasn't actually released */ } } case KeyPress: From 1233c9d0dcd952cb813f9b9f3d4543e07369f2e0 Mon Sep 17 00:00:00 2001 From: Hugo Hromic Date: Thu, 14 Mar 2019 16:09:51 +0000 Subject: [PATCH 010/237] (command.c) Silence warning in C89 build --- command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command.c b/command.c index aefc2fe531..be515931d2 100755 --- a/command.c +++ b/command.c @@ -287,7 +287,7 @@ static bool command_read_ram(const char *arg) unsigned int alloc_size = 0; unsigned int addr = -1; - if (sscanf(arg, "%x %d", &addr, &nbytes) != 2) + if (sscanf(arg, "%x %u", &addr, &nbytes) != 2) return true; alloc_size = 40 + nbytes * 3; /* We alloc more than needed, saving 20 bytes is not really relevant */ reply = (char*) malloc(alloc_size); From b10a318f16dc762ae9c7834732142d34688bc6b3 Mon Sep 17 00:00:00 2001 From: Hugo Hromic Date: Thu, 14 Mar 2019 16:10:53 +0000 Subject: [PATCH 011/237] (dispserv_x11.c) Silence warning --- gfx/display_servers/dispserv_x11.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gfx/display_servers/dispserv_x11.c b/gfx/display_servers/dispserv_x11.c index 0c1abd3a38..8727ac5a94 100644 --- a/gfx/display_servers/dispserv_x11.c +++ b/gfx/display_servers/dispserv_x11.c @@ -57,6 +57,7 @@ typedef struct bool decorations; } dispserv_x11_t; +#ifdef HAVE_XRANDR static Display* x11_display_server_open_display(void) { Display *dpy = g_x11_dpy; @@ -72,7 +73,9 @@ static Display* x11_display_server_open_display(void) return dpy; } +#endif +#ifdef HAVE_XRANDR static void x11_display_server_close_display(Display *dpy) { if (!dpy || x11_display_server_using_global_dpy || dpy == g_x11_dpy) @@ -80,6 +83,7 @@ static void x11_display_server_close_display(Display *dpy) XCloseDisplay(dpy); } +#endif static void* x11_display_server_init(void) { From 794f4a6b3436693baa67dd6055d8c2dc65f537dd Mon Sep 17 00:00:00 2001 From: Hugo Hromic Date: Thu, 14 Mar 2019 16:22:22 +0000 Subject: [PATCH 012/237] (libretro-common/libchdr) Silence warnings in C89 build --- libretro-common/include/libchdr/chd.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libretro-common/include/libchdr/chd.h b/libretro-common/include/libchdr/chd.h index 454de38774..3c68f9c907 100644 --- a/libretro-common/include/libchdr/chd.h +++ b/libretro-common/include/libchdr/chd.h @@ -226,11 +226,11 @@ extern "C" { /* standard CD-ROM metadata */ #define CDROM_OLD_METADATA_TAG 0x43484344 /* 'CHCD' */ #define CDROM_TRACK_METADATA_TAG 0x43485452 /* 'CHTR' */ -#define CDROM_TRACK_METADATA_FORMAT "TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d" +#define CDROM_TRACK_METADATA_FORMAT "TRACK:%u TYPE:%s SUBTYPE:%s FRAMES:%u" #define CDROM_TRACK_METADATA2_TAG 0x43485432 /* 'CHT2' */ -#define CDROM_TRACK_METADATA2_FORMAT "TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d PREGAP:%d PGTYPE:%s PGSUB:%s POSTGAP:%d" +#define CDROM_TRACK_METADATA2_FORMAT "TRACK:%u TYPE:%s SUBTYPE:%s FRAMES:%u PREGAP:%u PGTYPE:%s PGSUB:%s POSTGAP:%u" #define GDROM_TRACK_METADATA_TAG 0x43484744 /* 'CHTD' */ -#define GDROM_TRACK_METADATA_FORMAT "TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d PAD:%d PREGAP:%d PGTYPE:%s PGSUB:%s POSTGAP:%d" +#define GDROM_TRACK_METADATA_FORMAT "TRACK:%u TYPE:%s SUBTYPE:%s FRAMES:%u PAD:%u PREGAP:%u PGTYPE:%s PGSUB:%s POSTGAP:%u" /* standard A/V metadata */ #define AV_METADATA_TAG 0x41564156 /* 'AVAV' */ From 44db578691694cdd54adcb2403c1fbf9b4b6e689 Mon Sep 17 00:00:00 2001 From: natinusala Date: Thu, 14 Mar 2019 17:31:48 +0100 Subject: [PATCH 013/237] ozone: fix content metadata update --- menu/drivers/ozone/ozone.c | 150 +++++++++++++++-------------- menu/drivers/ozone/ozone.h | 2 + menu/drivers/ozone/ozone_sidebar.c | 2 + 3 files changed, 84 insertions(+), 70 deletions(-) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index aa3f572d29..26c328ceb7 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -373,14 +373,11 @@ static void ozone_update_thumbnail_path(void *data, unsigned i, char pos) { settings_t *settings = config_get_ptr(); ozone_handle_t *ozone = (ozone_handle_t*)data; - playlist_t *playlist = NULL; const char *core_name = NULL; if (!ozone) return; - playlist = playlist_get_cached(); - /* imageviewer content requires special treatment... */ menu_thumbnail_get_core_name(ozone->thumbnail_path_data, &core_name); if (string_is_equal(core_name, "imageviewer")) @@ -390,71 +387,6 @@ static void ozone_update_thumbnail_path(void *data, unsigned i, char pos) } else menu_thumbnail_update_path(ozone->thumbnail_path_data, pos == 'R' ? MENU_THUMBNAIL_RIGHT : MENU_THUMBNAIL_LEFT); - - if (playlist) - { - const char *core_label = NULL; - playlist_get_index(playlist, i, - NULL, NULL, NULL, &core_name, NULL, NULL); - - /* Fill core name */ - if (!core_name || string_is_equal(core_name, "DETECT")) - core_label = msg_hash_to_str(MSG_AUTODETECT); - else - core_label = core_name; - - snprintf(ozone->selection_core_name, sizeof(ozone->selection_core_name), - "%s %s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_CORE), core_label); - - word_wrap(ozone->selection_core_name, ozone->selection_core_name, (unsigned)((float)ozone->dimensions.thumbnail_bar_width * (float)0.85) / ozone->footer_font_glyph_width, false); - ozone->selection_core_name_lines = ozone_count_lines(ozone->selection_core_name); - - /* Fill play time if applicable */ - if (settings->bools.content_runtime_log || settings->bools.content_runtime_log_aggregate) - { - unsigned runtime_hours = 0; - unsigned runtime_minutes = 0; - unsigned runtime_seconds = 0; - - unsigned last_played_year = 0; - unsigned last_played_month = 0; - unsigned last_played_day = 0; - unsigned last_played_hour = 0; - unsigned last_played_minute = 0; - unsigned last_played_second = 0; - - playlist_get_runtime_index(playlist, i, NULL, NULL, - &runtime_hours, &runtime_minutes, &runtime_seconds, - &last_played_year, &last_played_month, &last_played_day, - &last_played_hour, &last_played_minute, &last_played_second); - - snprintf(ozone->selection_playtime, sizeof(ozone->selection_playtime), "%s %02u:%02u:%02u", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME), runtime_hours, runtime_minutes, runtime_seconds); - - if (last_played_year == 0 && last_played_month == 0 && last_played_day == 0 - && last_played_hour == 0 && last_played_minute == 0 && last_played_second == 0) - { - snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s %s", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_NEVER)); - } - else - { - snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s %04u/%02u/%02u -\n%02u:%02u:%02u", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), - last_played_year, last_played_month, last_played_day, - last_played_hour, last_played_minute, last_played_second); - } - } - else - { - snprintf(ozone->selection_playtime, sizeof(ozone->selection_playtime), "%s", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED)); - - snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED)); - } - } } static void ozone_update_thumbnail_image(void *data) @@ -1193,10 +1125,86 @@ static void ozone_draw_footer(ozone_handle_t *ozone, video_frame_info_t *video_i menu_display_blend_end(video_info); } +void ozone_update_content_metadata(ozone_handle_t *ozone) +{ + playlist_t *playlist = playlist_get_cached(); + const char *core_name = NULL; + settings_t *settings = config_get_ptr(); + + menu_thumbnail_get_core_name(ozone->thumbnail_path_data, &core_name); + + if (ozone->is_playlist && playlist) + { + const char *core_label = NULL; + playlist_get_index(playlist, ozone->selection, + NULL, NULL, NULL, &core_name, NULL, NULL); + + /* Fill core name */ + if (!core_name || string_is_equal(core_name, "DETECT")) + core_label = msg_hash_to_str(MSG_AUTODETECT); + else + core_label = core_name; + + snprintf(ozone->selection_core_name, sizeof(ozone->selection_core_name), + "%s %s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_CORE), core_label); + + word_wrap(ozone->selection_core_name, ozone->selection_core_name, (unsigned)((float)ozone->dimensions.thumbnail_bar_width * (float)0.85) / ozone->footer_font_glyph_width, false); + ozone->selection_core_name_lines = ozone_count_lines(ozone->selection_core_name); + + /* Fill play time if applicable */ + if (settings->bools.content_runtime_log || settings->bools.content_runtime_log_aggregate) + { + unsigned runtime_hours = 0; + unsigned runtime_minutes = 0; + unsigned runtime_seconds = 0; + + unsigned last_played_year = 0; + unsigned last_played_month = 0; + unsigned last_played_day = 0; + unsigned last_played_hour = 0; + unsigned last_played_minute = 0; + unsigned last_played_second = 0; + + playlist_get_runtime_index(playlist, ozone->selection, NULL, NULL, + &runtime_hours, &runtime_minutes, &runtime_seconds, + &last_played_year, &last_played_month, &last_played_day, + &last_played_hour, &last_played_minute, &last_played_second); + + snprintf(ozone->selection_playtime, sizeof(ozone->selection_playtime), "%s %02u:%02u:%02u", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME), runtime_hours, runtime_minutes, runtime_seconds); + + if (last_played_year == 0 && last_played_month == 0 && last_played_day == 0 + && last_played_hour == 0 && last_played_minute == 0 && last_played_second == 0) + { + snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s %s", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_NEVER)); + } + else + { + snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s %04u/%02u/%02u -\n%02u:%02u:%02u", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), + last_played_year, last_played_month, last_played_day, + last_played_hour, last_played_minute, last_played_second); + } + } + else + { + snprintf(ozone->selection_playtime, sizeof(ozone->selection_playtime), "%s", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED)); + + snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED)); + } + } + +} + static void ozone_set_thumbnail_content(void *data, const char *s) { - size_t selection = menu_navigation_get_selection(); - ozone_handle_t *ozone = (ozone_handle_t*)data; + size_t selection = menu_navigation_get_selection(); + ozone_handle_t *ozone = (ozone_handle_t*)data; + if (!ozone) return; @@ -1283,6 +1291,8 @@ static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) size_t new_selection = menu_navigation_get_selection(); ozone_node_t *node = (ozone_node_t*) file_list_get_userdata_at_offset(selection_buf, new_selection); + ozone_update_content_metadata(ozone); + menu_entry_init(&entry); if (!node) diff --git a/menu/drivers/ozone/ozone.h b/menu/drivers/ozone/ozone.h index aae40c736c..16f2d44b00 100644 --- a/menu/drivers/ozone/ozone.h +++ b/menu/drivers/ozone/ozone.h @@ -310,4 +310,6 @@ void ozone_draw_thumbnail_bar(ozone_handle_t *ozone, video_frame_info_t *video_i unsigned ozone_count_lines(const char *str); +void ozone_update_content_metadata(ozone_handle_t *ozone); + #endif diff --git a/menu/drivers/ozone/ozone_sidebar.c b/menu/drivers/ozone/ozone_sidebar.c index b3309681c9..bafe6f5cd7 100644 --- a/menu/drivers/ozone/ozone_sidebar.c +++ b/menu/drivers/ozone/ozone_sidebar.c @@ -292,6 +292,8 @@ void ozone_leave_sidebar(ozone_handle_t *ozone, uintptr_t tag) if (ozone->empty_playlist) return; + ozone_update_content_metadata(ozone); + ozone->categories_active_idx_old = ozone->categories_selection_ptr; ozone->cursor_in_sidebar_old = ozone->cursor_in_sidebar; ozone->cursor_in_sidebar = false; From a68072e293ef07dfbd1f80145dff64ced9bcde8e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 14 Mar 2019 18:14:32 +0100 Subject: [PATCH 014/237] Buildfix for C89_BUILD --- menu/drivers/ozone/ozone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index 26c328ceb7..81d83ac7ad 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1349,7 +1349,7 @@ static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) } } - //TODO: update savestate thumbnail and path + /* TODO: update savestate thumbnail and path */ } menu_entry_free(&entry); From 0cfefdd2a8038cc102b68bccf75703a3b3c07a9f Mon Sep 17 00:00:00 2001 From: Hugo Hromic Date: Thu, 14 Mar 2019 18:12:10 +0000 Subject: [PATCH 015/237] (libretro-common/libchdr) Use int types and format aligned to the `chd_header` typedef --- libretro-common/formats/libchdr/libchdr_chd.c | 2 +- libretro-common/include/libchdr/chd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libretro-common/formats/libchdr/libchdr_chd.c b/libretro-common/formats/libchdr/libchdr_chd.c index 7ac16a5e4b..4713dd6fc5 100644 --- a/libretro-common/formats/libchdr/libchdr_chd.c +++ b/libretro-common/formats/libchdr/libchdr_chd.c @@ -1335,7 +1335,7 @@ static UINT32 header_guess_unitbytes(chd_file *chd) { /* look for hard disk metadata; if found, then the unit size == sector size */ char metadata[512]; - int i0, i1, i2, i3; + unsigned int i0, i1, i2, i3; if (chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE && sscanf(metadata, HARD_DISK_METADATA_FORMAT, &i0, &i1, &i2, &i3) == 4) return i3; diff --git a/libretro-common/include/libchdr/chd.h b/libretro-common/include/libchdr/chd.h index 3c68f9c907..a21ee9dd52 100644 --- a/libretro-common/include/libchdr/chd.h +++ b/libretro-common/include/libchdr/chd.h @@ -212,7 +212,7 @@ extern "C" { /* standard hard disk metadata */ #define HARD_DISK_METADATA_TAG 0x47444444 /* 'GDDD' */ -#define HARD_DISK_METADATA_FORMAT "CYLS:%d,HEADS:%d,SECS:%d,BPS:%d" +#define HARD_DISK_METADATA_FORMAT "CYLS:%u,HEADS:%u,SECS:%u,BPS:%u" /* hard disk identify information */ #define HARD_DISK_IDENT_METADATA_TAG 0x49444e54 /* 'IDNT' */ From c8eb85ec2eeea88d2f9ff019f25cf664bfbc3b65 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 14 Mar 2019 20:03:41 +0100 Subject: [PATCH 016/237] Implement gl_core_wrap_type_to_enum --- gfx/drivers/gl_core.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/gfx/drivers/gl_core.c b/gfx/drivers/gl_core.c index 2a7e3d8a63..cdf4c3fb13 100644 --- a/gfx/drivers/gl_core.c +++ b/gfx/drivers/gl_core.c @@ -1998,6 +1998,25 @@ static bool gl_core_menu_widgets_enabled(void *data) } #endif +static unsigned gl_core_wrap_type_to_enum(enum gfx_wrap_type type) +{ + switch (type) + { + case RARCH_WRAP_BORDER: + return GL_CLAMP_TO_BORDER; + case RARCH_WRAP_EDGE: + return GL_CLAMP_TO_EDGE; + case RARCH_WRAP_REPEAT: + return GL_REPEAT; + case RARCH_WRAP_MIRRORED_REPEAT: + return GL_MIRRORED_REPEAT; + default: + break; + } + + return 0; +} + video_driver_t video_gl_core = { gl_core_init, gl_core_frame, @@ -2028,7 +2047,7 @@ video_driver_t video_gl_core = { gl_core_get_overlay_interface, #endif gl_core_get_poke_interface, - /*gl_core_wrap_type_to_enum,*/NULL, + gl_core_wrap_type_to_enum, #if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) gl_core_menu_widgets_enabled #endif From 2f659e3e17f565d912709f195a1d13a78fd422ee Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 14 Mar 2019 19:33:02 -0400 Subject: [PATCH 017/237] style nits --- input/drivers/android_input.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/input/drivers/android_input.c b/input/drivers/android_input.c index 31be4be737..0e3e1667ed 100644 --- a/input/drivers/android_input.c +++ b/input/drivers/android_input.c @@ -561,7 +561,7 @@ static int android_check_quick_tap(android_input_t *android) * and then not touched again for 200ms * If so then return true and deactivate quick tap timer */ retro_time_t now = cpu_features_get_time_usec(); - if(android->quick_tap_time && (now/1000 - android->quick_tap_time/1000000) >= 200) + if (android->quick_tap_time && (now/1000 - android->quick_tap_time/1000000) >= 200) { android->quick_tap_time = 0; return 1; @@ -648,7 +648,7 @@ static INLINE void android_mouse_calculate_deltas(android_input_t *android, float y_scale = 1; struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); - if(av_info) + if (av_info) { video_viewport_t *custom_vp = video_viewport_get_custom(); const struct retro_game_geometry *geom = (const struct retro_game_geometry*)&av_info->geometry; @@ -737,11 +737,11 @@ static INLINE int android_input_poll_event_type_motion( if (keyup && motion_ptr < MAX_TOUCH) { - if(action == AMOTION_EVENT_ACTION_UP && ENABLE_TOUCH_SCREEN_MOUSE) + if (action == AMOTION_EVENT_ACTION_UP && ENABLE_TOUCH_SCREEN_MOUSE) { /* If touchscreen was pressed for less than 200ms * then register time stamp of a quick tap */ - if((AMotionEvent_getEventTime(event)-AMotionEvent_getDownTime(event))/1000000 < 200) + if ((AMotionEvent_getEventTime(event)-AMotionEvent_getDownTime(event))/1000000 < 200) android->quick_tap_time = AMotionEvent_getEventTime(event); android->mouse_l = 0; } @@ -760,7 +760,7 @@ static INLINE int android_input_poll_event_type_motion( if (settings && settings->bools.vibrate_on_keypress && action != AMOTION_EVENT_ACTION_MOVE) android_app_write_cmd(g_android, APP_CMD_VIBRATE_KEYPRESS); - if(action == AMOTION_EVENT_ACTION_DOWN && ENABLE_TOUCH_SCREEN_MOUSE) + if (action == AMOTION_EVENT_ACTION_DOWN && ENABLE_TOUCH_SCREEN_MOUSE) { /* When touch screen is pressed, set mouse * previous position to current position @@ -771,14 +771,14 @@ static INLINE int android_input_poll_event_type_motion( /* If another touch happened within 200ms after a quick tap * then cancel the quick tap and register left mouse button * as being held down */ - if((AMotionEvent_getEventTime(event) - android->quick_tap_time)/1000000 < 200) + if ((AMotionEvent_getEventTime(event) - android->quick_tap_time)/1000000 < 200) { android->quick_tap_time = 0; android->mouse_l = 1; } } - if(action == AMOTION_EVENT_ACTION_MOVE && ENABLE_TOUCH_SCREEN_MOUSE) + if (action == AMOTION_EVENT_ACTION_MOVE && ENABLE_TOUCH_SCREEN_MOUSE) android_mouse_calculate_deltas(android,event,motion_ptr); for (motion_ptr = 0; motion_ptr < pointer_max; motion_ptr++) @@ -964,7 +964,7 @@ static void handle_hotplug(android_input_t *android, * and be grouped with the NVIDIA button of the virtual device. * */ - if(strstr(device_model, "SHIELD Android TV") && ( + if (strstr(device_model, "SHIELD Android TV") && ( strstr(device_name, "Virtual") || strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.0"))) { @@ -1007,7 +1007,7 @@ static void handle_hotplug(android_input_t *android, } } - else if(strstr(device_model, "SHIELD") && ( + else if (strstr(device_model, "SHIELD") && ( strstr(device_name, "Virtual") || strstr(device_name, "gpio") || strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.01") || strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.02"))) @@ -1026,7 +1026,7 @@ static void handle_hotplug(android_input_t *android, } } - else if(strstr(device_model, "SHIELD") && ( + else if (strstr(device_model, "SHIELD") && ( strstr(device_name, "Virtual") || strstr(device_name, "gpio") || strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.03"))) { @@ -1057,7 +1057,7 @@ static void handle_hotplug(android_input_t *android, * This is a simple hack, basically groups the "back" * button with the rest of the gamepad */ - else if(strstr(device_model, "XD") && ( + else if (strstr(device_model, "XD") && ( strstr(device_name, "Virtual") || strstr(device_name, "rk29-keypad") || strstr(device_name,"Playstation3") || strstr(device_name,"XBOX"))) { @@ -1118,7 +1118,7 @@ static void handle_hotplug(android_input_t *android, * This device is composed of two hid devices * We make it look like one device */ - else if(strstr(device_model, "ARCHOS GAMEPAD") && ( + else if (strstr(device_model, "ARCHOS GAMEPAD") && ( strstr(device_name, "joy_key") || strstr(device_name, "joystick"))) { /* only use the hack if the device is one of the built-in devices */ @@ -1138,7 +1138,7 @@ static void handle_hotplug(android_input_t *android, } /* Amazon Fire TV & Fire stick */ - else if(strstr(device_model, "AFTB") || strstr(device_model, "AFTT") || + else if (strstr(device_model, "AFTB") || strstr(device_model, "AFTT") || strstr(device_model, "AFTS") || strstr(device_model, "AFTM") || strstr(device_model, "AFTRS")) { @@ -1152,7 +1152,7 @@ static void handle_hotplug(android_input_t *android, strlcpy(name_buf, device_name, sizeof(name_buf)); } /* remove the remote when a gamepad enters */ - else if(strstr(android->pad_states[0].name,"Amazon Fire TV Remote")) + else if (strstr(android->pad_states[0].name,"Amazon Fire TV Remote")) { android->pads_connected = 0; *port = 0; @@ -1192,7 +1192,7 @@ static void handle_hotplug(android_input_t *android, /* If device is keyboard only and didn't match any of the devices above * then assume it is a keyboard, register the id, and return unless the * maximum number of keyboards are already registered. */ - else if(source == AINPUT_SOURCE_KEYBOARD && kbd_num < MAX_NUM_KEYBOARDS) + else if (source == AINPUT_SOURCE_KEYBOARD && kbd_num < MAX_NUM_KEYBOARDS) { kbd_id[kbd_num] = id; kbd_num++; From 15e489fd0a356eb874af37672fbf5311be9a7f97 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 14 Mar 2019 19:33:51 -0400 Subject: [PATCH 018/237] android: allow stylus/pen to move mouse without pressing down --- input/drivers/android_input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/input/drivers/android_input.c b/input/drivers/android_input.c index 0e3e1667ed..f79921e012 100644 --- a/input/drivers/android_input.c +++ b/input/drivers/android_input.c @@ -687,7 +687,7 @@ static INLINE int android_input_poll_event_type_motion( int btn; /* Only handle events from a touchscreen or mouse */ - if (!(source & (AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_MOUSE))) + if (!(source & (AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_MOUSE))) return 1; getaction = AMotionEvent_getAction(event); @@ -778,7 +778,7 @@ static INLINE int android_input_poll_event_type_motion( } } - if (action == AMOTION_EVENT_ACTION_MOVE && ENABLE_TOUCH_SCREEN_MOUSE) + if ((action == AMOTION_EVENT_ACTION_MOVE || action == AMOTION_EVENT_ACTION_HOVER_MOVE) && ENABLE_TOUCH_SCREEN_MOUSE) android_mouse_calculate_deltas(android,event,motion_ptr); for (motion_ptr = 0; motion_ptr < pointer_max; motion_ptr++) From c9dca9cdf1f3ea7170e6e0351b42366d1923faa5 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 14 Mar 2019 19:34:51 -0400 Subject: [PATCH 019/237] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index d1f2177601..cfc54b0139 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ - ANDROID: Add option to vibrate on touch (works in menu or overlay). - ANDROID: Add device vibration option for cores that support rumble. - ANDROID: Add gamepad vibration support for cores that support rumble. +- ANDROID: Allow stylus/pen to move mouse without pressing down. - AUDIO: Avoid deadlocks in certain audio drivers when toggling menu sounds on. - BLISS-BOX: Support PSX Jogcon (requires firmware 3.0). - CRT: Dynamic super resolution support. From 6f284a1d437a1056bcf2207e9d6cf49c7ace9521 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 15 Mar 2019 01:08:09 +0100 Subject: [PATCH 020/237] Build fix --- menu/drivers/xmb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 5a865c853e..3fe263dc20 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2114,7 +2114,9 @@ static void xmb_populate_entries(void *data, xmb_system_tab = xmb_get_system_tab(xmb, (unsigned)xmb->categories_selection_ptr); xmb->is_playlist = (xmb_system_tab == XMB_SYSTEM_TAB_FAVORITES) || (xmb_system_tab == XMB_SYSTEM_TAB_HISTORY) || +#ifdef HAVE_IMAGEVIEWER (xmb_system_tab == XMB_SYSTEM_TAB_IMAGES) || +#endif string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HORIZONTAL_MENU)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST)) || From 145013074e428f1a5fb874f5d6991140c3eb7af9 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 14 Mar 2019 21:26:33 -0400 Subject: [PATCH 021/237] android buildfix --- input/drivers/android_input.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/input/drivers/android_input.c b/input/drivers/android_input.c index f79921e012..599a11e7ef 100644 --- a/input/drivers/android_input.c +++ b/input/drivers/android_input.c @@ -56,6 +56,8 @@ enum { AMOTION_EVENT_BUTTON_BACK = 1 << 3, AMOTION_EVENT_BUTTON_FORWARD = 1 << 4, AMOTION_EVENT_AXIS_VSCROLL = 9, + AMOTION_EVENT_ACTION_HOVER_MOVE = 7, + AINPUT_SOURCE_STYLUS = 0x00004000 }; #endif From 1a4786a7f1039e8f265dae59e70fc018e90a39c8 Mon Sep 17 00:00:00 2001 From: natinusala Date: Fri, 15 Mar 2019 11:16:29 +0100 Subject: [PATCH 022/237] ozone: show metadata name if content logging is disabled --- menu/drivers/ozone/ozone.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index 81d83ac7ad..e180c34297 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1190,10 +1190,12 @@ void ozone_update_content_metadata(ozone_handle_t *ozone) } else { - snprintf(ozone->selection_playtime, sizeof(ozone->selection_playtime), "%s", + snprintf(ozone->selection_playtime, sizeof(ozone->selection_playtime), "%s %s", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED)); - snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s", + snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s %s", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED)); } } From 26f750395971c45b8acf8b583713deb56a8e04c4 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Fri, 15 Mar 2019 11:26:04 +0000 Subject: [PATCH 023/237] (XMB) Fix display glitches when refreshing current menu --- menu/drivers/xmb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 3fe263dc20..a5ac46e7f2 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2061,6 +2061,8 @@ static void xmb_list_open(xmb_handle_t *xmb) dir = 1; else if (xmb->depth < xmb->old_depth) dir = -1; + else + return; /* If menu hasn't changed, do nothing */ xmb_list_open_horizontal_list(xmb); From 27c1dd4b7b351e3fc1bc30aa01d2560b683438cb Mon Sep 17 00:00:00 2001 From: natinusala Date: Fri, 15 Mar 2019 14:21:20 +0100 Subject: [PATCH 024/237] ozone: fix horizontal animation when refreshing the menu --- menu/drivers/ozone/ozone.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index e180c34297..00482acb4d 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1676,6 +1676,7 @@ static void ozone_populate_entries(void *data, const char *path, const char *lab ozone_handle_t *ozone = (ozone_handle_t*) data; int new_depth; + bool animate; if (!ozone) return; @@ -1693,6 +1694,7 @@ static void ozone_populate_entries(void *data, const char *path, const char *lab 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); @@ -1700,7 +1702,8 @@ static void ozone_populate_entries(void *data, const char *path, const char *lab if (ozone->categories_selection_ptr == ozone->categories_active_idx_old) { - ozone_list_open(ozone); + if (animate) + ozone_list_open(ozone); } else { From 6807f1b9bb4859218f5081179010ebdbc15588ff Mon Sep 17 00:00:00 2001 From: natinusala Date: Fri, 15 Mar 2019 14:41:41 +0100 Subject: [PATCH 025/237] ozone: prevent content metadata from lagging --- menu/drivers/ozone/ozone.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index 00482acb4d..45dbdd67be 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1293,8 +1293,6 @@ static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) size_t new_selection = menu_navigation_get_selection(); ozone_node_t *node = (ozone_node_t*) file_list_get_userdata_at_offset(selection_buf, new_selection); - ozone_update_content_metadata(ozone); - menu_entry_init(&entry); if (!node) @@ -1311,6 +1309,8 @@ static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) ozone->cursor_in_sidebar_old = ozone->cursor_in_sidebar; + ozone_update_content_metadata(ozone); + menu_animation_kill_by_tag(&tag); ozone_update_scroll(ozone, allow_animation, node); From 48341199634491cb4bc2c9b24bfd5d5727779cb1 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Fri, 15 Mar 2019 14:12:25 +0000 Subject: [PATCH 026/237] strlcpy() safety checks --- menu/menu_thumbnail_path.c | 25 +++++++++++++++++++------ runtime_file.c | 19 ++++++++++++++++--- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/menu/menu_thumbnail_path.c b/menu/menu_thumbnail_path.c index 6f554e3100..9bf097d9c3 100644 --- a/menu/menu_thumbnail_path.c +++ b/menu/menu_thumbnail_path.c @@ -243,6 +243,8 @@ bool menu_thumbnail_set_content(menu_thumbnail_path_data_t *path_data, const cha * Returns true if content is valid */ bool menu_thumbnail_set_content_image(menu_thumbnail_path_data_t *path_data, const char *img_dir, const char *img_name) { + char *content_img_no_ext = NULL; + if (!path_data) return false; @@ -272,8 +274,13 @@ bool menu_thumbnail_set_content_image(menu_thumbnail_path_data_t *path_data, con img_name, sizeof(path_data->content_img)); /* Get image label */ - strlcpy(path_data->content_label, - path_remove_extension(path_data->content_img), sizeof(path_data->content_label)); + content_img_no_ext = path_remove_extension(path_data->content_img); + if (!string_is_empty(content_img_no_ext)) + strlcpy(path_data->content_label, + content_img_no_ext, sizeof(path_data->content_label)); + else + strlcpy(path_data->content_label, + path_data->content_img, sizeof(path_data->content_label)); /* Set file path */ fill_pathname_join(path_data->content_path, @@ -376,16 +383,22 @@ bool menu_thumbnail_set_content_playlist(menu_thumbnail_path_data_t *path_data, "MAME", sizeof(path_data->content_db_name)); else { + char *db_name_no_ext = NULL; char tmp_buf[PATH_MAX_LENGTH]; tmp_buf[0] = '\0'; - strlcpy(tmp_buf, db_name, sizeof(tmp_buf)); - /* Remove .lpl extension * > path_remove_extension() requires a char * (not const) * so have to use a temporary buffer... */ - strlcpy(path_data->content_db_name, - path_remove_extension(tmp_buf), sizeof(path_data->content_db_name)); + strlcpy(tmp_buf, db_name, sizeof(tmp_buf)); + db_name_no_ext = path_remove_extension(tmp_buf); + + if (!string_is_empty(db_name_no_ext)) + strlcpy(path_data->content_db_name, + db_name_no_ext, sizeof(path_data->content_db_name)); + else + strlcpy(path_data->content_db_name, + tmp_buf, sizeof(path_data->content_db_name)); } } diff --git a/runtime_file.c b/runtime_file.c index faea97d5a9..7139b56c38 100644 --- a/runtime_file.c +++ b/runtime_file.c @@ -319,8 +319,13 @@ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, { if (string_is_equal(path_basename(core_info->list[i].path), core_path_basename)) { - strlcpy(core_name, core_info->list[i].core_name, sizeof(core_name)); - break; + if (!string_is_empty(core_info->list[i].core_name)) + { + strlcpy(core_name, core_info->list[i].core_name, sizeof(core_name)); + break; + } + else + return NULL; } } @@ -341,6 +346,9 @@ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, else strlcpy(tmp_buf, settings->paths.directory_runtime_log, sizeof(tmp_buf)); + if (string_is_empty(tmp_buf)) + return NULL; + if (log_per_core) { fill_pathname_join( @@ -388,9 +396,14 @@ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, { /* path_remove_extension() requires a char * (not const) * so have to use a temporary buffer... */ + char *tmp_buf_no_ext = NULL; tmp_buf[0] = '\0'; strlcpy(tmp_buf, path_basename(content_path), sizeof(tmp_buf)); - strlcpy(content_name, path_remove_extension(tmp_buf), sizeof(content_name)); + tmp_buf_no_ext = path_remove_extension(tmp_buf); + if (!string_is_empty(tmp_buf_no_ext)) + strlcpy(content_name, tmp_buf_no_ext, sizeof(content_name)); + else + return NULL; } if (string_is_empty(content_name)) From e3a88e88064a917ff9a3062f397738110ec11285 Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 15 Mar 2019 15:36:18 +0100 Subject: [PATCH 027/237] glcore: Set frame count in shader interface. --- gfx/drivers/gl_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gfx/drivers/gl_core.c b/gfx/drivers/gl_core.c index cdf4c3fb13..1210f3d6c6 100644 --- a/gfx/drivers/gl_core.c +++ b/gfx/drivers/gl_core.c @@ -1624,6 +1624,7 @@ static bool gl_core_frame(void *data, const void *frame, texture.padded_width = streamed->width; texture.padded_height = streamed->height; } + gl_core_filter_chain_set_frame_count(gl->filter_chain, frame_count); gl_core_filter_chain_set_input_texture(gl->filter_chain, &texture); gl_core_filter_chain_build_offscreen_passes(gl->filter_chain, &gl->filter_chain_vp); From d1e457115c5465ee98584dafef60ebaf06e9ae06 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Fri, 15 Mar 2019 16:59:50 +0000 Subject: [PATCH 028/237] (Ozone) Fix thumbnail display issues --- menu/drivers/ozone/ozone.c | 115 ++++++++++++++++++++++--------------- 1 file changed, 70 insertions(+), 45 deletions(-) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index 45dbdd67be..097cba513c 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1127,6 +1127,7 @@ static void ozone_draw_footer(ozone_handle_t *ozone, video_frame_info_t *video_i void ozone_update_content_metadata(ozone_handle_t *ozone) { + size_t selection = menu_navigation_get_selection(); playlist_t *playlist = playlist_get_cached(); const char *core_name = NULL; settings_t *settings = config_get_ptr(); @@ -1136,7 +1137,7 @@ void ozone_update_content_metadata(ozone_handle_t *ozone) if (ozone->is_playlist && playlist) { const char *core_label = NULL; - playlist_get_index(playlist, ozone->selection, + playlist_get_index(playlist, selection, NULL, NULL, NULL, &core_name, NULL, NULL); /* Fill core name */ @@ -1165,7 +1166,7 @@ void ozone_update_content_metadata(ozone_handle_t *ozone) unsigned last_played_minute = 0; unsigned last_played_second = 0; - playlist_get_runtime_index(playlist, ozone->selection, NULL, NULL, + playlist_get_runtime_index(playlist, selection, NULL, NULL, &runtime_hours, &runtime_minutes, &runtime_seconds, &last_played_year, &last_played_month, &last_played_day, &last_played_hour, &last_played_minute, &last_played_second); @@ -1259,6 +1260,8 @@ static void ozone_set_thumbnail_content(void *data, const char *s) * pointless nuisance and a waste of CPU cycles, IMHO... */ menu_thumbnail_set_content(ozone->thumbnail_path_data, s); } + + ozone_update_content_metadata(ozone); } static void ozone_unload_thumbnail_textures(void *data) @@ -1309,8 +1312,6 @@ static void ozone_selection_changed(ozone_handle_t *ozone, bool allow_animation) ozone->cursor_in_sidebar_old = ozone->cursor_in_sidebar; - ozone_update_content_metadata(ozone); - menu_animation_kill_by_tag(&tag); ozone_update_scroll(ozone, allow_animation, node); @@ -1705,25 +1706,23 @@ static void ozone_populate_entries(void *data, const char *path, const char *lab if (animate) ozone_list_open(ozone); } - else + + /* Thumbnails */ + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) || menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) { - /* Thumbnails */ - if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) || menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) + ozone_unload_thumbnail_textures(ozone); + + if (ozone->is_playlist) { - ozone_unload_thumbnail_textures(ozone); + ozone_set_thumbnail_content(ozone, ""); - if (ozone->is_playlist) - { - ozone_set_thumbnail_content(ozone, ""); + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) + ozone_update_thumbnail_path(ozone, 0 /* will be ignored */, 'R'); - if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) - ozone_update_thumbnail_path(ozone, 0 /* will be ignored */, 'R'); + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) + ozone_update_thumbnail_path(ozone, 0 /* will be ignored */, 'L'); - if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) - ozone_update_thumbnail_path(ozone, 0 /* will be ignored */, 'L'); - - ozone_update_thumbnail_image(ozone); - } + ozone_update_thumbnail_image(ozone); } } } @@ -2180,6 +2179,7 @@ static bool ozone_load_image(void *userdata, void *data, enum menu_image_type ty unsigned sidebar_height; unsigned height; unsigned maximum_height, maximum_width; + float display_aspect_ratio; if (!ozone || !data) return false; @@ -2189,50 +2189,75 @@ static bool ozone_load_image(void *userdata, void *data, enum menu_image_type ty sidebar_height = height - ozone->dimensions.header_height - 55 - ozone->dimensions.footer_height; maximum_height = sidebar_height / 2; maximum_width = ozone->dimensions.thumbnail_bar_width - ozone->dimensions.sidebar_entry_icon_padding * 2; + if (maximum_height > 0) + display_aspect_ratio = (float)maximum_width / (float)maximum_height; + else + display_aspect_ratio = 0.0f; switch (type) { case MENU_IMAGE_THUMBNAIL: { - struct texture_image *img = (struct texture_image*)data; - float scale_down; + struct texture_image *img = (struct texture_image*)data; - ozone->dimensions.thumbnail_height = ozone->dimensions.thumbnail_width - * (float)img->height / (float)img->width; - - scale_down = (float) maximum_height / ozone->dimensions.thumbnail_height; - - ozone->dimensions.thumbnail_height *= scale_down; - ozone->dimensions.thumbnail_width *= scale_down; - - if (ozone->dimensions.thumbnail_width > (float)maximum_width) + if (img->width > 0 && img->height > 0 && display_aspect_ratio > 0.0001f) { - scale_down = (float) maximum_width / ozone->dimensions.thumbnail_width; + float thumb_aspect_ratio = (float)img->width / (float)img->height; - ozone->dimensions.thumbnail_height *= scale_down; - ozone->dimensions.thumbnail_width *= scale_down; + if (thumb_aspect_ratio > display_aspect_ratio) + { + ozone->dimensions.thumbnail_width = (float)maximum_width; + ozone->dimensions.thumbnail_height = (float)img->height * (float)maximum_width / (float)img->width; + } + else + { + ozone->dimensions.thumbnail_height = (float)maximum_height; + ozone->dimensions.thumbnail_width = (float)img->width * (float)maximum_height / (float)img->height; + } + + video_driver_texture_unload(&ozone->thumbnail); + video_driver_texture_load(data, + TEXTURE_FILTER_MIPMAP_LINEAR, &ozone->thumbnail); + } + else + { + ozone->dimensions.thumbnail_width = 0.0f; + ozone->dimensions.thumbnail_height = 0.0f; + video_driver_texture_unload(&ozone->thumbnail); } - video_driver_texture_unload(&ozone->thumbnail); - video_driver_texture_load(data, - TEXTURE_FILTER_MIPMAP_LINEAR, &ozone->thumbnail); break; } case MENU_IMAGE_LEFT_THUMBNAIL: { - struct texture_image *img = (struct texture_image*)data; - ozone->dimensions.left_thumbnail_height = ozone->dimensions.left_thumbnail_width - * (float)img->height / (float)img->width; + struct texture_image *img = (struct texture_image*)data; - if (ozone->dimensions.left_thumbnail_height > maximum_height) + if (img->width > 0 && img->height > 0 && display_aspect_ratio > 0.0001f) { - float scale_down = (float) maximum_height / (float) ozone->dimensions.left_thumbnail_height; - ozone->dimensions.left_thumbnail_height *= scale_down; - ozone->dimensions.left_thumbnail_width *= scale_down; + float thumb_aspect_ratio = (float)img->width / (float)img->height; + + if (thumb_aspect_ratio > display_aspect_ratio) + { + ozone->dimensions.left_thumbnail_width = (float)maximum_width; + ozone->dimensions.left_thumbnail_height = (float)img->height * (float)maximum_width / (float)img->width; + } + else + { + ozone->dimensions.left_thumbnail_height = (float)maximum_height; + ozone->dimensions.left_thumbnail_width = (float)img->width * (float)maximum_height / (float)img->height; + } + + video_driver_texture_unload(&ozone->left_thumbnail); + video_driver_texture_load(data, + TEXTURE_FILTER_MIPMAP_LINEAR, &ozone->left_thumbnail); } - video_driver_texture_unload(&ozone->left_thumbnail); - video_driver_texture_load(data, - TEXTURE_FILTER_MIPMAP_LINEAR, &ozone->left_thumbnail); + else + { + ozone->dimensions.left_thumbnail_width = 0.0f; + ozone->dimensions.left_thumbnail_height = 0.0f; + video_driver_texture_unload(&ozone->left_thumbnail); + } + break; } default: From f75f8482f8a000859a1c6f708138f4bebdc45807 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Mon, 25 Feb 2019 19:29:56 +0100 Subject: [PATCH 029/237] Use bin2c for compiling IRX --- Makefile.ps2 | 26 +++---- frontend/drivers/platform_ps2.c | 122 +++++++++++++++++++------------- 2 files changed, 88 insertions(+), 60 deletions(-) diff --git a/Makefile.ps2 b/Makefile.ps2 index 313163abd6..9c7079d9ab 100644 --- a/Makefile.ps2 +++ b/Makefile.ps2 @@ -1,5 +1,5 @@ BUILD_PRX = 0 -DEBUG = 0 +DEBUG = 1 HAVE_KERNEL_PRX = 0 HAVE_LOGGER = 0 HAVE_FILE_LOGGER = 0 @@ -9,7 +9,7 @@ MUTE_WARNINGS = 0 PS2_IP = 192.168.1.150 #Configuration for IRX -EE_BIN2O = bin2o +EE_BIN2C = bin2c IRX_DIR = $(PS2SDK)/iop/irx TARGET = retroarchps2.elf @@ -39,12 +39,14 @@ RARCH_DEFINES += -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU - LIBDIR = LDFLAGS += -L$(PS2SDK)/ports/lib -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ee/lib -L. -LIBS += -lretro_ps2 -lgskit -ldmakit -lgskit_toolkit -laudsrv -lmf -lpad -lmc -lhdd -lsdl -lfileXio -lpatches -lpoweroff +LIBS += -lretro_ps2 -lgskit -ldmakit -lgskit_toolkit -laudsrv -lmf -lpadx -lmtap -lmc -lhdd -lsdl -lfileXio -lpatches -lpoweroff #IRX modules # IRX modules - modules have to be in IRX_DIR -IRX = iomanX.irx fileXio.irx mcman.irx mcserv.irx usbd.irx usbhdfsd.irx freesd.irx audsrv.irx poweroff.irx ps2dev9.irx ps2atad.irx ps2hdd.irx ps2fs.irx -IRX_OBJ = $(IRX:.irx=.o) +IRX_FILES = freemtap.irx freepad.irx freesio2.irx iomanX.irx fileXio.irx mcman.irx mcserv.irx usbd.irx usbhdfsd.irx freesd.irx audsrv.irx poweroff.irx ps2dev9.irx ps2atad.irx ps2hdd.irx ps2fs.irx +IRX_C_FILES = $(IRX_FILES:.irx=_irx.c) +IRX_OBJ = $(IRX_FILES:.irx=_irx.o) +# Add into the EE_OBJS the irx.c files EE_OBJS += $(IRX_OBJ) ifeq ($(HAVE_THREADS), 1) @@ -77,14 +79,18 @@ EE_LDFLAGS = $(LDFLAGS) EE_LIBS = $(LIBS) EE_ASFLAGS = $(ASFLAGS) EE_INCS = $(INCDIR) -EE_IRX_OBJ = $(IRX_OBJ) EE_BIN = $(TARGET) EE_GPVAL = $(GPVAL) -all: $(EE_IRX_OBJ) $(EE_BIN) +# Specific file name and output per IRX Module +%.irx: + $(EE_BIN2C) $(IRX_DIR)/$@ $(@:.irx=_irx.c) $(@:.irx=_irx) + + +all: $(IRX_FILES) $(EE_BIN) clean: - rm -f $(EE_BIN) $(EE_OBJS) + rm -f $(EE_BIN) $(EE_OBJS) $(IRX_C_FILES) prepare: ps2client -h $(PS2_IP) reset @@ -100,10 +106,6 @@ package: release: clean all package -#Specific file name and output per IRX Module -$(EE_IRX_OBJ): - $(EE_BIN2O) $(EE_GPVAL) $(IRX_DIR)/$(@:.o=.irx) $@ $(@:.o=_irx) - #Include preferences include $(PS2SDK)/samples/Makefile.pref include $(PS2SDK)/samples/Makefile.eeglobal diff --git a/frontend/drivers/platform_ps2.c b/frontend/drivers/platform_ps2.c index 08e449cdf1..594257974e 100644 --- a/frontend/drivers/platform_ps2.c +++ b/frontend/drivers/platform_ps2.c @@ -23,49 +23,59 @@ #include #include #include +#include +#include #include #include #include -extern unsigned char poweroff_irx_start[]; -extern unsigned int poweroff_irx_size; +// #ifdef SOUND_ON + #include + extern unsigned char audsrv_irx; + extern unsigned int size_audsrv_irx; + extern unsigned char freesd_irx; + extern unsigned int size_freesd_irx; +// #endif -extern unsigned char ps2dev9_irx_start[]; -extern unsigned int ps2dev9_irx_size; -extern unsigned char ps2atad_irx_start[]; -extern unsigned int ps2atad_irx_size; +// Input +// #define NEW_PADMAN +#include +#include +extern unsigned char freesio2_irx; +extern unsigned int size_freesio2_irx; +extern unsigned char mcman_irx; +extern unsigned int size_mcman_irx; +extern unsigned char mcserv_irx; +extern unsigned int size_mcserv_irx; +extern unsigned char freemtap_irx; +extern unsigned int size_freemtap_irx; +extern unsigned char freepad_irx; +extern unsigned int size_freepad_irx; -extern unsigned char ps2hdd_irx_start[]; -extern unsigned int ps2hdd_irx_size; - -extern unsigned char ps2fs_irx_start[]; -extern unsigned int ps2fs_irx_size; - -extern unsigned char iomanX_irx_start[]; -extern unsigned int iomanX_irx_size; - -extern unsigned char fileXio_irx_start[]; -extern unsigned int fileXio_irx_size; - -extern unsigned char freesd_irx_start[]; -extern unsigned int freesd_irx_size; - -extern unsigned char audsrv_irx_start[]; -extern unsigned int audsrv_irx_size; - -extern unsigned char usbd_irx_start[]; -extern unsigned int usbd_irx_size; - -extern unsigned char usbhdfsd_irx_start[]; -extern unsigned int usbhdfsd_irx_size; - -extern unsigned char mcman_irx_start[]; -extern unsigned int mcman_irx_size; - -extern unsigned char mcserv_irx_start[]; -extern unsigned int mcserv_irx_size; +extern unsigned char poweroff_irx; +extern unsigned int size_poweroff_irx; +extern unsigned char iomanX_irx; +extern unsigned int size_iomanX_irx; +extern unsigned char fileXio_irx; +extern unsigned int size_fileXio_irx; +extern unsigned char ps2dev9_irx; +extern unsigned int size_ps2dev9_irx; +extern unsigned char ps2atad_irx; +extern unsigned int size_ps2atad_irx; +extern unsigned char ps2hdd_irx; +extern unsigned int size_ps2hdd_irx; +extern unsigned char ps2fs_irx; +extern unsigned int size_ps2fs_irx; +extern unsigned char usbd_irx; +extern unsigned int size_usbd_irx; +extern unsigned char usbhdfsd_irx; +extern unsigned int size_usbhdfsd_irx; +// #ifdef CDSUPPORT +extern unsigned char cdvd_irx; +extern unsigned int size_cdvd_irx; +// #endif char eboot_path[512]; char user_path[512]; @@ -196,36 +206,52 @@ static void frontend_ps2_init(void *data) SifInitRpc(0); sbv_patch_enable_lmb(); - /* Controllers */ - SifLoadModule("rom0:SIO2MAN", 0, NULL); - SifLoadModule("rom0:PADMAN", 0, NULL); - /* I/O Files */ - SifExecModuleBuffer(iomanX_irx_start, iomanX_irx_size, 0, NULL, NULL); - SifExecModuleBuffer(fileXio_irx_start, fileXio_irx_size, 0, NULL, NULL); + SifExecModuleBuffer(&iomanX_irx, size_iomanX_irx, 0, NULL, NULL); + SifExecModuleBuffer(&fileXio_irx, size_fileXio_irx, 0, NULL, NULL); + SifExecModuleBuffer(&freesio2_irx, size_freesio2_irx, 0, NULL, NULL); /* Memory Card */ - SifExecModuleBuffer(mcman_irx_start, mcman_irx_size, 0, NULL, NULL); - SifExecModuleBuffer(mcserv_irx_start, mcserv_irx_size, 0, NULL, NULL); + SifExecModuleBuffer(&mcman_irx, size_mcman_irx, 0, NULL, NULL); + SifExecModuleBuffer(&mcserv_irx, size_mcserv_irx, 0, NULL, NULL); + + /* Controllers */ + SifExecModuleBuffer(&freemtap_irx, size_freemtap_irx, 0, NULL, NULL); + SifExecModuleBuffer(&freepad_irx, size_freepad_irx, 0, NULL, NULL); /* USB */ - SifExecModuleBuffer(usbd_irx_start, usbd_irx_size, 0, NULL, NULL); - SifExecModuleBuffer(usbhdfsd_irx_start, usbhdfsd_irx_size, 0, NULL, NULL); + SifExecModuleBuffer(&usbd_irx, size_usbd_irx, 0, NULL, NULL); + SifExecModuleBuffer(&usbhdfsd_irx, size_usbhdfsd_irx, 0, NULL, NULL); /* Audio */ - SifExecModuleBuffer(freesd_irx_start, freesd_irx_size, 0, NULL, NULL); - SifExecModuleBuffer(audsrv_irx_start, audsrv_irx_size, 0, NULL, NULL); + SifExecModuleBuffer(&freesd_irx, size_freesd_irx, 0, NULL, NULL); + SifExecModuleBuffer(&audsrv_irx, size_audsrv_irx, 0, NULL, NULL); + + for (i = 0; i < 3; i++) { // Taken from ulaunchelf + sometime = 0x01000000; + while (sometime--) asm("nop\nnop\nnop\nnop"); + } + + if (mcInit(MC_TYPE_XMC)) { + RARCH_ERR("mcInit library not initalizated\n"); + } /* Initializes audsrv library */ if (audsrv_init()) { RARCH_ERR("audsrv library not initalizated\n"); } - /* Initializes pad library + /* Initializes pad libraries Must be init with 0 as parameter*/ + if (mtapInit() != 1) { + RARCH_ERR("mtapInit library not initalizated\n"); + } if (padInit(0) != 1) { RARCH_ERR("padInit library not initalizated\n"); } + if (mtapPortOpen(0) != 1) { + RARCH_ERR("mtapPortOpen library not initalizated\n"); + } /* Prepare device */ getcwd(cwd, sizeof(cwd)); From 4c24a171193982aef88007774e2d7a3cdc6f4b7d Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Mon, 25 Feb 2019 23:43:34 +0100 Subject: [PATCH 030/237] Extract IRX variables --- .gitignore | 3 ++ Makefile.ps2 | 32 +++++++-------- frontend/drivers/platform_ps2.c | 54 +------------------------ libretro-common/file/file_path.c | 2 +- ps2/include/inttypes.h | 2 +- ps2/include/ps2_irx_variables.h | 69 ++++++++++++++++++++++++++++++++ ps2/irx/Makefile | 22 ++++++++++ 7 files changed, 112 insertions(+), 72 deletions(-) create mode 100644 ps2/include/ps2_irx_variables.h create mode 100644 ps2/irx/Makefile diff --git a/.gitignore b/.gitignore index 4e752c40c4..6d6bad97d8 100644 --- a/.gitignore +++ b/.gitignore @@ -165,6 +165,9 @@ retroarch_switch.nacp retroarch_switch.nro retroarch_switch.nso +# PS2 +ps2/irx/*.c + # Wayland gfx/common/wayland/idle-inhibit-unstable-v1.c gfx/common/wayland/idle-inhibit-unstable-v1.h diff --git a/Makefile.ps2 b/Makefile.ps2 index 9c7079d9ab..f4061c70bb 100644 --- a/Makefile.ps2 +++ b/Makefile.ps2 @@ -1,5 +1,5 @@ BUILD_PRX = 0 -DEBUG = 1 +DEBUG = 0 HAVE_KERNEL_PRX = 0 HAVE_LOGGER = 0 HAVE_FILE_LOGGER = 0 @@ -8,13 +8,13 @@ BIG_STACK = 0 MUTE_WARNINGS = 0 PS2_IP = 192.168.1.150 -#Configuration for IRX -EE_BIN2C = bin2c -IRX_DIR = $(PS2SDK)/iop/irx - TARGET = retroarchps2.elf TARGET_RELEASE = retroarchps2-release.elf +# Compile the IRXs first +IRX_DIR = ps2/irx +IRX_FILES = $(wildcard ps2/irx/*.c) + ifeq ($(DEBUG), 1) OPTIMIZE_LV := -O0 -g RARCH_DEFINES += -DDEBUG @@ -41,13 +41,6 @@ LIBDIR = LDFLAGS += -L$(PS2SDK)/ports/lib -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ee/lib -L. LIBS += -lretro_ps2 -lgskit -ldmakit -lgskit_toolkit -laudsrv -lmf -lpadx -lmtap -lmc -lhdd -lsdl -lfileXio -lpatches -lpoweroff -#IRX modules -# IRX modules - modules have to be in IRX_DIR -IRX_FILES = freemtap.irx freepad.irx freesio2.irx iomanX.irx fileXio.irx mcman.irx mcserv.irx usbd.irx usbhdfsd.irx freesd.irx audsrv.irx poweroff.irx ps2dev9.irx ps2atad.irx ps2hdd.irx ps2fs.irx -IRX_C_FILES = $(IRX_FILES:.irx=_irx.c) -IRX_OBJ = $(IRX_FILES:.irx=_irx.o) -# Add into the EE_OBJS the irx.c files -EE_OBJS += $(IRX_OBJ) ifeq ($(HAVE_THREADS), 1) RARCH_DEFINES += -DHAVE_THREADS @@ -67,6 +60,11 @@ endif CFLAGS += $(RARCH_DEFINES) +# All the IRX objects +EE_OBJS += $(IRX_DIR)/freemtap_irx.o $(IRX_DIR)/freepad_irx.o $(IRX_DIR)/freesio2_irx.o $(IRX_DIR)/iomanX_irx.o +EE_OBJS += $(IRX_DIR)/fileXio_irx.o $(IRX_DIR)/mcman_irx.o $(IRX_DIR)/mcserv_irx.o $(IRX_DIR)/usbd_irx.o +EE_OBJS += $(IRX_DIR)/usbhdfsd_irx.o $(IRX_DIR)/freesd_irx.o $(IRX_DIR)/audsrv_irx.o $(IRX_DIR)/poweroff_irx.o + # Missing objecst on the PS2SDK EE_OBJS += ps2/compat_files/compat_ctype.o ps2/compat_files/time.o ps2/compat_files/ps2_devices.o @@ -82,15 +80,15 @@ EE_INCS = $(INCDIR) EE_BIN = $(TARGET) EE_GPVAL = $(GPVAL) -# Specific file name and output per IRX Module -%.irx: - $(EE_BIN2C) $(IRX_DIR)/$@ $(@:.irx=_irx.c) $(@:.irx=_irx) +all: irxdir $(EE_BIN) -all: $(IRX_FILES) $(EE_BIN) +irxdir: + $(MAKE) -C $(IRX_DIR) clean: - rm -f $(EE_BIN) $(EE_OBJS) $(IRX_C_FILES) + rm -f $(EE_BIN) $(EE_OBJS) + $(MAKE) -C $(IRX_DIR) clean prepare: ps2client -h $(PS2_IP) reset diff --git a/frontend/drivers/platform_ps2.c b/frontend/drivers/platform_ps2.c index 594257974e..34b5d3a755 100644 --- a/frontend/drivers/platform_ps2.c +++ b/frontend/drivers/platform_ps2.c @@ -28,54 +28,7 @@ #include #include #include - - -// #ifdef SOUND_ON - #include - extern unsigned char audsrv_irx; - extern unsigned int size_audsrv_irx; - extern unsigned char freesd_irx; - extern unsigned int size_freesd_irx; -// #endif - - -// Input -// #define NEW_PADMAN -#include -#include -extern unsigned char freesio2_irx; -extern unsigned int size_freesio2_irx; -extern unsigned char mcman_irx; -extern unsigned int size_mcman_irx; -extern unsigned char mcserv_irx; -extern unsigned int size_mcserv_irx; -extern unsigned char freemtap_irx; -extern unsigned int size_freemtap_irx; -extern unsigned char freepad_irx; -extern unsigned int size_freepad_irx; - -extern unsigned char poweroff_irx; -extern unsigned int size_poweroff_irx; -extern unsigned char iomanX_irx; -extern unsigned int size_iomanX_irx; -extern unsigned char fileXio_irx; -extern unsigned int size_fileXio_irx; -extern unsigned char ps2dev9_irx; -extern unsigned int size_ps2dev9_irx; -extern unsigned char ps2atad_irx; -extern unsigned int size_ps2atad_irx; -extern unsigned char ps2hdd_irx; -extern unsigned int size_ps2hdd_irx; -extern unsigned char ps2fs_irx; -extern unsigned int size_ps2fs_irx; -extern unsigned char usbd_irx; -extern unsigned int size_usbd_irx; -extern unsigned char usbhdfsd_irx; -extern unsigned int size_usbhdfsd_irx; -// #ifdef CDSUPPORT -extern unsigned char cdvd_irx; -extern unsigned int size_cdvd_irx; -// #endif +#include char eboot_path[512]; char user_path[512]; @@ -227,11 +180,6 @@ static void frontend_ps2_init(void *data) SifExecModuleBuffer(&freesd_irx, size_freesd_irx, 0, NULL, NULL); SifExecModuleBuffer(&audsrv_irx, size_audsrv_irx, 0, NULL, NULL); - for (i = 0; i < 3; i++) { // Taken from ulaunchelf - sometime = 0x01000000; - while (sometime--) asm("nop\nnop\nnop\nnop"); - } - if (mcInit(MC_TYPE_XMC)) { RARCH_ERR("mcInit library not initalizated\n"); } diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index bfe5c902bd..0a72fdc13e 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -100,7 +100,7 @@ #define FIO_S_ISDIR SCE_S_ISDIR #endif -#if (defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)) || defined(__QNX__) || defined(PSP) +#if (defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)) || defined(__QNX__) || defined(PSP) || defined(PS2) #include /* stat() is defined here */ #endif diff --git a/ps2/include/inttypes.h b/ps2/include/inttypes.h index 8b37fcc33e..3234974612 100644 --- a/ps2/include/inttypes.h +++ b/ps2/include/inttypes.h @@ -19,4 +19,4 @@ #define PRIu64 "lu" #define PRIuPTR "lu" -#endif //INTTYPES_H +#endif /* INTTYPES_H */ diff --git a/ps2/include/ps2_irx_variables.h b/ps2/include/ps2_irx_variables.h new file mode 100644 index 0000000000..856d82e209 --- /dev/null +++ b/ps2/include/ps2_irx_variables.h @@ -0,0 +1,69 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2018 - Francisco Javier Trujillo Mata - fjtrujy + * + * 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 . + */ + +#ifndef PS2_IRX_VARIABLES_H +#define PS2_IRX_VARIABLES_H + +extern unsigned char freesio2_irx; +extern unsigned int size_freesio2_irx; + +extern unsigned char mcman_irx; +extern unsigned int size_mcman_irx; + +extern unsigned char mcserv_irx; +extern unsigned int size_mcserv_irx; + +extern unsigned char freemtap_irx; +extern unsigned int size_freemtap_irx; + +extern unsigned char freepad_irx; +extern unsigned int size_freepad_irx; + +extern unsigned char poweroff_irx; +extern unsigned int size_poweroff_irx; + +extern unsigned char iomanX_irx; +extern unsigned int size_iomanX_irx; + +extern unsigned char fileXio_irx; +extern unsigned int size_fileXio_irx; + +extern unsigned char ps2dev9_irx; +extern unsigned int size_ps2dev9_irx; + +extern unsigned char ps2atad_irx; +extern unsigned int size_ps2atad_irx; + +extern unsigned char ps2hdd_irx; +extern unsigned int size_ps2hdd_irx; + +extern unsigned char ps2fs_irx; +extern unsigned int size_ps2fs_irx; + +extern unsigned char usbd_irx; +extern unsigned int size_usbd_irx; + +extern unsigned char usbhdfsd_irx; +extern unsigned int size_usbhdfsd_irx; + +extern unsigned char cdvd_irx; +extern unsigned int size_cdvd_irx; + +extern unsigned char audsrv_irx; +extern unsigned int size_audsrv_irx; + +extern unsigned char freesd_irx; +extern unsigned int size_freesd_irx; + +#endif /* PS2_IRX_VARIABLES_H */ diff --git a/ps2/irx/Makefile b/ps2/irx/Makefile new file mode 100644 index 0000000000..49cb342c2b --- /dev/null +++ b/ps2/irx/Makefile @@ -0,0 +1,22 @@ +#Configuration for IRX +EE_BIN2C = bin2c +IRX_DIR = $(PS2SDK)/iop/irx + +#IRX modules +# IRX modules - modules have to be in IRX_DIR +IRX_FILES += freemtap.irx freepad.irx freesio2.irx iomanX.irx fileXio.irx mcman.irx mcserv.irx usbd.irx usbhdfsd.irx +IRX_FILES += freesd.irx audsrv.irx poweroff.irx +IRX_C_FILES = $(IRX_FILES:.irx=_irx.c) + +# Specific file name and output per IRX Module +%.irx: + $(EE_BIN2C) $(IRX_DIR)/$@ $(@:.irx=_irx.c) $(@:.irx=_irx) + +all: $(IRX_FILES) + +clean: + rm -f $(IRX_C_FILES) + +#Include preferences +include $(PS2SDK)/samples/Makefile.pref +include $(PS2SDK)/samples/Makefile.eeglobal From da86549b8e1ac923ba4b01d7deacac71c996eac5 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Sat, 9 Mar 2019 13:16:12 +0100 Subject: [PATCH 031/237] Add libcdvd library --- ps2/libcdvd/Makefile | 19 + ps2/libcdvd/common/cdvd.h | 45 + ps2/libcdvd/docs/libcdvd_ref.pdf | Bin 0 -> 113259 bytes ps2/libcdvd/ee/Makefile | 10 + ps2/libcdvd/ee/cdvd_rpc.c | 135 +++ ps2/libcdvd/ee/cdvd_rpc.h | 28 + ps2/libcdvd/example/Makefile | 17 + ps2/libcdvd/example/example.cpp | 425 +++++++ ps2/libcdvd/example/font.fnt | Bin 0 -> 262432 bytes ps2/libcdvd/iop/Makefile | 12 + ps2/libcdvd/iop/Rules.make | 54 + ps2/libcdvd/iop/cdvd_iop.c | 1852 ++++++++++++++++++++++++++++++ ps2/libcdvd/iop/cdvd_iop.h | 84 ++ ps2/libcdvd/iop/imports.lst | 62 + ps2/libcdvd/iop/irx_imports.h | 9 + ps2/libcdvd/license.txt | 45 + 16 files changed, 2797 insertions(+) create mode 100644 ps2/libcdvd/Makefile create mode 100644 ps2/libcdvd/common/cdvd.h create mode 100644 ps2/libcdvd/docs/libcdvd_ref.pdf create mode 100644 ps2/libcdvd/ee/Makefile create mode 100644 ps2/libcdvd/ee/cdvd_rpc.c create mode 100644 ps2/libcdvd/ee/cdvd_rpc.h create mode 100644 ps2/libcdvd/example/Makefile create mode 100644 ps2/libcdvd/example/example.cpp create mode 100644 ps2/libcdvd/example/font.fnt create mode 100644 ps2/libcdvd/iop/Makefile create mode 100644 ps2/libcdvd/iop/Rules.make create mode 100644 ps2/libcdvd/iop/cdvd_iop.c create mode 100644 ps2/libcdvd/iop/cdvd_iop.h create mode 100644 ps2/libcdvd/iop/imports.lst create mode 100644 ps2/libcdvd/iop/irx_imports.h create mode 100644 ps2/libcdvd/license.txt diff --git a/ps2/libcdvd/Makefile b/ps2/libcdvd/Makefile new file mode 100644 index 0000000000..765a8e05e4 --- /dev/null +++ b/ps2/libcdvd/Makefile @@ -0,0 +1,19 @@ +# Remove the line below, if you want to disable silent mode +#.SILENT: + +all: lib/libcdvdfs.a lib/cdvd.irx + +lib: + mkdir -p $@ + +clean: + $(MAKE) -C ee clean + $(MAKE) -C iop clean + +lib/cdvd.irx: iop | lib + @echo Building IRX + $(MAKE) -C $< + +lib/libcdvdfs.a: ee | lib + @echo Building EE client + $(MAKE) -C $< diff --git a/ps2/libcdvd/common/cdvd.h b/ps2/libcdvd/common/cdvd.h new file mode 100644 index 0000000000..516e0fc9dd --- /dev/null +++ b/ps2/libcdvd/common/cdvd.h @@ -0,0 +1,45 @@ +#ifndef _CDVD_H +#define _CDVD_H + +// This header contains the common definitions for libcdvd +// that are used by both IOP and EE sides + +#define CDVD_IRX 0xB001337 +#define CDVD_FINDFILE 0x01 +#define CDVD_GETDIR 0x02 +#define CDVD_STOP 0x04 +#define CDVD_TRAYREQ 0x05 +#define CDVD_DISKREADY 0x06 +#define CDVD_FLUSHCACHE 0x07 +#define CDVD_GETSIZE 0x08 + + +struct TocEntry +{ + u32 fileLBA; + u32 fileSize; + u8 fileProperties; + u8 padding1[3]; + char filename[128 + 1]; + u8 padding2[3]; +} __attribute__((packed)); + + +enum CDVD_getMode { + CDVD_GET_FILES_ONLY = 1, + CDVD_GET_DIRS_ONLY = 2, + CDVD_GET_FILES_AND_DIRS = 3 +}; + +// Macros for TrayReq +#define CdTrayOpen 0 +#define CdTrayClose 1 +#define CdTrayCheck 2 + +// Macros for DiskReady +#define CdComplete 0x02 +#define CdNotReady 0x06 +#define CdBlock 0x00 +#define CdNonBlock 0x01 + +#endif // _CDVD_H diff --git a/ps2/libcdvd/docs/libcdvd_ref.pdf b/ps2/libcdvd/docs/libcdvd_ref.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b8a99aa09d455bd9315dcb3edd3be17b7fce46ee GIT binary patch literal 113259 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 aq1*v$h{1lpo8jsO6on$?;JBeIMfyMHL#5yV literal 0 HcmV?d00001 diff --git a/ps2/libcdvd/ee/Makefile b/ps2/libcdvd/ee/Makefile new file mode 100644 index 0000000000..9a079c88eb --- /dev/null +++ b/ps2/libcdvd/ee/Makefile @@ -0,0 +1,10 @@ +EE_LIB = ../lib/libcdvdfs.a +EE_OBJS = cdvd_rpc.o + +all: $(EE_LIB) + +clean: + rm -f $(EE_LIB) $(EE_OBJS) + +include $(PS2SDK)/samples/Makefile.pref +include $(PS2SDK)/samples/Makefile.eeglobal diff --git a/ps2/libcdvd/ee/cdvd_rpc.c b/ps2/libcdvd/ee/cdvd_rpc.c new file mode 100644 index 0000000000..14227a5bb8 --- /dev/null +++ b/ps2/libcdvd/ee/cdvd_rpc.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include + +#include "cdvd_rpc.h" + +int k_sceSifDmaStat(unsigned int id); +static unsigned sbuff[0x1300] __attribute__((aligned(64))); +static SifRpcClientData_t cd0; + +int cdvd_inited = 0; + +int CDVD_Init() +{ + int i; + + while (1) { + if (SifBindRpc(&cd0, CDVD_IRX, 0) < 0) + return -1; // bind error + if (cd0.server != 0) + break; + i = 0x10000; + while (i--) + ; + } + + cdvd_inited = 1; + + return 0; +} + +int CDVD_DiskReady(int mode) +{ + if (!cdvd_inited) + return -1; + + sbuff[0] = mode; + + SifCallRpc(&cd0, CDVD_DISKREADY, 0, (void *)(&sbuff[0]), 4, (void *)(&sbuff[0]), 4, 0, 0); + + return sbuff[0]; +} + +int CDVD_FindFile(const char *fname, struct TocEntry *tocEntry) +{ + if (!cdvd_inited) + return -1; + + strncpy((char *)&sbuff, fname, 1024); + + SifCallRpc(&cd0, CDVD_FINDFILE, 0, (void *)(&sbuff[0]), 1024, (void *)(&sbuff[0]), sizeof(struct TocEntry) + 1024, 0, 0); + + memcpy(tocEntry, &sbuff[256], sizeof(struct TocEntry)); + + return sbuff[0]; +} + +void CDVD_Stop() +{ + if (!cdvd_inited) + return; + + SifCallRpc(&cd0, CDVD_STOP, 0, (void *)(&sbuff[0]), 0, (void *)(&sbuff[0]), 0, 0, 0); + + return; +} + +int CDVD_TrayReq(int mode) +{ + if (!cdvd_inited) + return -1; + + SifCallRpc(&cd0, CDVD_TRAYREQ, 0, (void *)(&sbuff[0]), 4, (void *)(&sbuff[0]), 4, 0, 0); + + return sbuff[0]; +} + +int CDVD_GetDir(const char *pathname, const char *extensions, enum CDVD_getMode getMode, struct TocEntry tocEntry[], unsigned int req_entries, char *new_pathname) +{ + unsigned int num_entries; + + if (!cdvd_inited) + return -1; + + // copy the requested pathname to the rpc buffer + strncpy((char *)sbuff, pathname, 1023); + + // copy in the extension list to the rpc buffer + if (extensions == NULL) { + // Can't copy in the extension list since there isnt one, so just null the string in the rpc buffer + sbuff[1024 / 4] = 0; + } else { + strncpy((char *)&sbuff[1024 / 4], extensions, 127); + } + + sbuff[1152 / 4] = getMode; + + sbuff[1156 / 4] = (int)tocEntry; + + sbuff[1160 / 4] = req_entries; + + SifWriteBackDCache(tocEntry, req_entries * sizeof(struct TocEntry)); + + // This will get the directory contents, and fill tocEntry via DMA + SifCallRpc(&cd0, CDVD_GETDIR, 0, (void *)(&sbuff[0]), 1024 + 128 + 4 + 4 + 4, (void *)(&sbuff[0]), 4 + 1024, 0, 0); + + num_entries = sbuff[0]; + + if (new_pathname != NULL) + strncpy(new_pathname, (char *)&sbuff[1], 1023); + + return (num_entries); +} + +void CDVD_FlushCache() +{ + if (!cdvd_inited) + return; + + SifCallRpc(&cd0, CDVD_FLUSHCACHE, 0, (void *)(&sbuff[0]), 0, (void *)(&sbuff[0]), 0, 0, 0); + + return; +} + +unsigned int CDVD_GetSize() +{ + if (!cdvd_inited) + return -1; + + SifCallRpc(&cd0, CDVD_GETSIZE, 0, (void *)(&sbuff[0]), 0, (void *)(&sbuff[0]), 4, 0, 0); + + return sbuff[0]; +} diff --git a/ps2/libcdvd/ee/cdvd_rpc.h b/ps2/libcdvd/ee/cdvd_rpc.h new file mode 100644 index 0000000000..394adb73e7 --- /dev/null +++ b/ps2/libcdvd/ee/cdvd_rpc.h @@ -0,0 +1,28 @@ +#ifndef _CDVD_RPC_H +#define _CDVD_RPC_H + +// include the common definitions +#include "../common/cdvd.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +int CDVD_Init(); +int CDVD_DiskReady(int mode); +int CDVD_FindFile(const char *fname, struct TocEntry *tocEntry); +void CDVD_Stop(); +int CDVD_TrayReq(int mode); +int CDVD_DiskReady(int mode); +int CDVD_GetDir(const char *pathname, const char *extensions, enum CDVD_getMode getMode, struct TocEntry tocEntry[], unsigned int req_entries, char *new_pathname); +void CDVD_FlushCache(); +unsigned int CDVD_GetSize(); + + +#ifdef __cplusplus +} +#endif + + +#endif // _CDVD_H diff --git a/ps2/libcdvd/example/Makefile b/ps2/libcdvd/example/Makefile new file mode 100644 index 0000000000..bc02ebc7ac --- /dev/null +++ b/ps2/libcdvd/example/Makefile @@ -0,0 +1,17 @@ +#update this to point to the location of gslib +GSLIB = /ps2dev/gslib + +EE_BIN = example.elf +EE_OBJS = example.o + +EE_LDFLAGS += -L../lib -L$(GSLIB)/lib +EE_LIBS += -lkernel -lcdvdfs -lgs -lgcc -lsupc++ -lpad +EE_INCS += -I $(GSLIB)/source -I ../ee + +all: $(EE_BIN) + +clean: + rm -f *.elf *.o *.a + +include $(PS2LIB)/Makefile.pref +include $(PS2LIB)/Makefile.eeglobal diff --git a/ps2/libcdvd/example/example.cpp b/ps2/libcdvd/example/example.cpp new file mode 100644 index 0000000000..8f42e44db6 --- /dev/null +++ b/ps2/libcdvd/example/example.cpp @@ -0,0 +1,425 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +#include "cdvd_rpc.h" + +#define scr_w 640 +#define scr_h 480 + + +#define TEXT_COL_BRIGHT GS_SET_RGBA(0xFF, 0xFF, 0xFF, 0x80) +#define TEXT_COL_DIM GS_SET_RGBA(0x40, 0x40, 0xFF, 0x80) + +#define TRUE 1 +#define FALSE 0 + +gsDriver *pDisplay; + +extern int screen; +int filelisty = 60; + +static float selected = 1; // The currently selected file/dir + + +int button_released = TRUE; + +//A pointer to an array of TocEntries to be alloc'd later +static struct TocEntry *TocEntryList; + + + +gsFontTex *fontTex; + + + +// pathname on CD +char pathname[1024 + 1] __attribute__((aligned(64))); + +gsFont myFont; + +int WaitPadReady(int port, int slot); +void SetPadMode(int port, int slot); + + +void ClearScreen(void) +{ + pDisplay->drawPipe.setAlphaEnable(GS_DISABLE); + pDisplay->drawPipe.RectFlat(0, 0, scr_w, scr_h, 0, GS_SET_RGBA(0, 0, 0, 0x80)); + pDisplay->drawPipe.setAlphaEnable(GS_ENABLE); + pDisplay->drawPipe.Flush(); +} + + +int main(void) +{ + SifInitRpc(0); + + SifLoadModule("rom0:SIO2MAN", 0, NULL); /* load sio2 manager irx */ + SifLoadModule("rom0:PADMAN", 0, NULL); /* load pad manager irx */ + + SifLoadModule("host:cdvd.irx", 0, NULL); + + CDVD_Init(); + + padInit(0); + + char *padBuf = (char *)memalign(64, 256); + + padPortOpen(0, 0, padBuf); + + SetPadMode(0, 0); + + // allocate the memory for a large file list + TocEntryList = (TocEntry *)memalign(64, 4000 * sizeof(struct TocEntry)); + + + // open the font file, find the size of the file, allocate memory for it, and load it + int fontfile = fioOpen("host:font.fnt", O_RDONLY); + int fontsize = fioLseek(fontfile, 0, SEEK_END); + fioLseek(fontfile, 0, SEEK_SET); + fontTex = (gsFontTex *)memalign(64, fontsize); + fioRead(fontfile, fontTex, fontsize); + fioClose(fontfile); + + // Upload the background to the texture buffer + pDisplay = new gsDriver; + + pDisplay->setDisplayMode(scr_w, scr_h, + 170, 80, + GS_PSMCT32, 2, + GS_TV_AUTO, GS_TV_INTERLACE, + GS_DISABLE, GS_DISABLE); + + // Enable Alpha Blending + pDisplay->drawPipe.setAlphaEnable(GS_ENABLE); + + myFont.assignPipe(&(pDisplay->drawPipe)); + + // Upload the font into the texture memory past the screen buffers + myFont.uploadFont(fontTex, pDisplay->getTextureBufferBase(), + fontTex->TexWidth, // Use the fontTex width as texbuffer width (can use diff width) + 0, 0); + + +#define list_max 21 + int list_size = 21; // Number of files to display in list + int first_file = 1; // The first file to display in the on-screen list + int num_files = 0; // The total number of files in the list + int offset; // Offset of the selected file into the displayed list + + struct padButtonStatus padButtons; + int ps2_buttons; + + button_released = TRUE; + + while (1) { + + while (1) // until we've selected a file + { + // Get entries from specified path, don't filter by file extension, + // get files and directories, get a maximum of 4000 entries, and update path if dir changed + num_files = CDVD_GetDir(pathname, NULL, CDVD_GET_FILES_AND_DIRS, TocEntryList, 4000, pathname); + + if (num_files < list_max) + list_size = num_files; + else + list_size = list_max; + + // Don't leave the drive spinning, it's annoying ! + CDVD_Stop(); + + while (1) // Until we've selected something (dir or file) + { + + // Get button presses + // If X then select the previously highlighted file + // If up/down then increase/decrease the selected file + int padState; + + // only listen to pad input if it's plugged in, and stable + padState = padGetState(0, 0); + if (padState == PAD_STATE_STABLE) { + padRead(0, 0, &padButtons); + ps2_buttons = (padButtons.btns[0] << 8) | padButtons.btns[1]; + ps2_buttons = ~ps2_buttons; + + if (num_files > 0) { + // file Selected + if (ps2_buttons & PAD_CROSS) { + if (button_released == TRUE) { + button_released = FALSE; + break; + } + } else + button_released = TRUE; + + // DPAD + Shoulder file Selection + if (ps2_buttons & PAD_UP) + selected -= 0.15; + else if (ps2_buttons & PAD_DOWN) + selected += 0.15; + else if (ps2_buttons & PAD_R1) + selected -= 1; + else if (ps2_buttons & PAD_R2) + selected += 1; + else if (ps2_buttons & PAD_L1) + selected = 1; + else if (ps2_buttons & PAD_L2) + selected = num_files; + } + + if (ps2_buttons & PAD_SELECT) { + strcpy(pathname, "/"); + + ClearScreen(); + + myFont.Print(0, 640, 220, 4, + TEXT_COL_BRIGHT, + GSFONT_ALIGN_CENTRE, "Please Change CD\nThen Press 'X'"); + + pDisplay->drawPipe.Flush(); + + // Wait for VSync and then swap buffers + pDisplay->WaitForVSync(); + + pDisplay->swapBuffers(); + + + CDVD_FlushCache(); + strcpy(pathname, "/"); + + while (1) { + int padState; + + // only listen to pad input if it's plugged in, and stable + padState = padGetState(0, 0); + if (padState == PAD_STATE_STABLE) { + padRead(0, 0, &padButtons); + ps2_buttons = (padButtons.btns[0] << 8) | padButtons.btns[1]; + ps2_buttons = ~ps2_buttons; + + // ROM Selected + if (ps2_buttons & PAD_CROSS) { + break; + } + } + + pDisplay->WaitForVSync(); + } + + num_files = CDVD_GetDir(pathname, NULL, CDVD_GET_FILES_AND_DIRS, TocEntryList, 4000, pathname); + + if (num_files < list_max) + list_size = num_files; + else + list_size = list_max; + + selected = 1; + + CDVD_Stop(); + } + + if ((padButtons.mode >> 4) == 0x07) { + // Analogue file selection + float pad_v; + + pad_v = (float)(padButtons.ljoy_v - 128); // Range = +127 to -128 + + + if (pad_v > 32) { + // scrolling down, so incrementing selected tom + pad_v -= 32; + selected += (pad_v / 96); + } + + if (pad_v < -32) { + // scrolling down, so incrementing selected tom + pad_v += 32; + selected += (pad_v / 96); + } + } + + + + if (selected < 1) + selected = 1; + + if ((int)selected > num_files) + selected = (float)num_files; + } + + // calculate which file to display first in the list + if ((int)selected <= list_size / 2) + first_file = 1; + else { + if ((int)selected >= (num_files - (list_size / 2) + 1)) + first_file = num_files - list_size + 1; + else + first_file = (int)selected - ((list_size / 2)); + } + + // calculate the offset of the selected file into the displayed list + offset = (int)selected - first_file; + + + ClearScreen(); + + if (num_files > 0) { + // pDisplay->drawPipe.setScissorRect(list_xpos,list_ypos,list_xpos+list_width,list_ypos+list_height); + + for (int file = 0; file < list_size; file++) { + // if the entry is a dir, then display the directory symbol before the name + if (TocEntryList[first_file + file - 1].fileProperties & 0x02) { + // display a dir symbol (character 001 in the bitmap font) + myFont.Print(128, 640, filelisty + (file * 18), 4, GS_SET_RGBA(0x80, 0x80, 0x80, 0x80), GSFONT_ALIGN_LEFT, "\001"); + + if (file == ((int)selected - first_file)) { + myFont.Print(148, 640, filelisty + (file * 18), 4, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, + TocEntryList[first_file + file - 1].filename); + } else { + myFont.Print(148, 640, filelisty + (file * 18), 4, TEXT_COL_DIM, GSFONT_ALIGN_LEFT, + TocEntryList[first_file + file - 1].filename); + } + } else { + if (file == ((int)selected - first_file)) { + myFont.Print(128, 640, filelisty + (file * 18), 4, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, + TocEntryList[first_file + file - 1].filename); + } else { + myFont.Print(128, 640, filelisty + (file * 18), 4, TEXT_COL_DIM, GSFONT_ALIGN_LEFT, + TocEntryList[first_file + file - 1].filename); + } + } + } + + myFont.Print(420, 640, 440, 0, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, + "Press X to Select"); + + myFont.Print(420, 640, 458, 0, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, + "Press SELECT to Change CD"); + } + + + pDisplay->drawPipe.Flush(); + + // Wait for VSync and then swap buffers + pDisplay->WaitForVSync(); + + pDisplay->swapBuffers(); + } + + // We've selected something, but is it a file or a dir ? + if (TocEntryList[((int)selected) - 1].fileProperties & 0x02) { + // Append name onto current path + //gui_getfile_dispname((int)selected, tempname); + strcat(pathname, "/"); + strcat(pathname, TocEntryList[((int)selected) - 1].filename); + + // file list will be got next time round the while loop + + // Start from top of list + selected = 1; + } else { + // It's not a dir, so it must be a file + break; + } + } + + char size_string[64]; + + if (TocEntryList[((int)selected) - 1].fileSize < (2 * 1024)) + sprintf(size_string, "%d bytes", TocEntryList[((int)selected) - 1].fileSize); + else { + if (TocEntryList[((int)selected) - 1].fileSize < (2 * 1024 * 1024)) + sprintf(size_string, "%d Kb", TocEntryList[((int)selected) - 1].fileSize / 1024); + else + sprintf(size_string, "%d Mb", TocEntryList[((int)selected) - 1].fileSize / (1024 * 1024)); + } + + + for (int frame = 0; frame < 200; frame++) { + + // Selected a file, so display file properties for a couple of seconds + ClearScreen(); + + myFont.Print(100, 200, 220, 1, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, + "File name:"); + + myFont.Print(200, 640, 220, 1, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, + TocEntryList[((int)selected) - 1].filename); + + myFont.Print(100, 200, 240, 1, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, + "File path:"); + + myFont.Print(200, 640, 240, 1, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, + pathname); + + + myFont.Print(100, 200, 260, 1, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, + "File size:"); + + myFont.Print(200, 640, 260, 1, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, + size_string); + + pDisplay->drawPipe.Flush(); + + // Wait for VSync and then swap buffers + pDisplay->WaitForVSync(); + + pDisplay->swapBuffers(); + } + } + + free(fontTex); + + free(TocEntryList); + + delete pDisplay; + + return 0; +} + + +int WaitPadReady(int port, int slot) +{ + int state = 0; + + while ((state != PAD_STATE_STABLE) && + (state != PAD_STATE_FINDCTP1)) { + state = padGetState(port, slot); + + if (state == PAD_STATE_DISCONN) + break; // If no pad connected then dont wait for it to be plugged in + + //pEmuDisplay->WaitForVSync(); + } + + return state; +} + + +void SetPadMode(int port, int slot) +{ + // If the controller is already plugged in then + // put the controller into Analogue mode (and lock it) + // so that analogue stick can be used + + if (WaitPadReady(port, slot) == PAD_STATE_STABLE) // if pad is connected then initialise it + { + padSetMainMode(port, slot, PAD_MMODE_DUALSHOCK, PAD_MMODE_LOCK); + + WaitPadReady(port, slot); + } +} diff --git a/ps2/libcdvd/example/font.fnt b/ps2/libcdvd/example/font.fnt new file mode 100644 index 0000000000000000000000000000000000000000..8d747f8826b8bbd53abce54e6b20440158b5ad19 GIT binary patch literal 262432 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 aoK@`JN9?qAdG_Jm$IQG+#|n1J{{I0UHI(K6 literal 0 HcmV?d00001 diff --git a/ps2/libcdvd/iop/Makefile b/ps2/libcdvd/iop/Makefile new file mode 100644 index 0000000000..c1dfd7c6c3 --- /dev/null +++ b/ps2/libcdvd/iop/Makefile @@ -0,0 +1,12 @@ +IOP_BIN = ../lib/cdvd.irx + +IOP_OBJS = cdvd_iop.o imports.o + + +all: $(IOP_BIN) + +clean: + rm -f $(IOP_BIN) $(IOP_OBJS) + +include $(PS2SDK)/Defs.make +include Rules.make diff --git a/ps2/libcdvd/iop/Rules.make b/ps2/libcdvd/iop/Rules.make new file mode 100644 index 0000000000..3a53febbe3 --- /dev/null +++ b/ps2/libcdvd/iop/Rules.make @@ -0,0 +1,54 @@ +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright 2001-2004. +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. + + +IOP_CC_VERSION := $(shell $(IOP_CC) -v 2>&1 | sed -n 's/^.*version //p') + +ASFLAGS_TARGET = -mcpu=r3000 + +ifeq ($(IOP_CC_VERSION),3.2.2) +CFLAGS_TARGET = -miop +ASFLAGS_TARGET = -march=r3000 +LDFLAGS_TARGET = -miop +endif + +IOP_INCS := $(IOP_INCS) -I$(PS2SDK)/iop/include -I$(PS2SDK)/common/include + +IOP_CFLAGS := $(CFLAGS_TARGET) -O2 -G0 -D_IOP -c $(IOP_INCS) $(IOP_CFLAGS) +IOP_ASFLAGS := $(ASFLAGS_TARGET) -EL -G0 $(IOP_ASFLAGS) +IOP_LDFLAGS := $(LDFLAGS_TARGET) -nostdlib $(IOP_LDFLAGS) + +# Externally defined variables: IOP_BIN, IOP_OBJS, IOP_LIB + +%.o : %.c + $(IOP_CC) $(IOP_CFLAGS) $< -o $@ + +%.o : %.s + $(IOP_AS) $(IOP_ASFLAGS) $< -o $@ + +# A rule to build imports.lst. +%.o : %.lst + echo "#include \"irx_imports.h\"" > build-imports.c + cat $< >> build-imports.c + $(IOP_CC) $(IOP_CFLAGS) build-imports.c -o $@ + -rm -f build-imports.c + +# A rule to build exports.tab. +%.o : %.tab + echo "#include \"irx.h\"" > build-exports.c + cat $< >> build-exports.c + $(IOP_CC) $(IOP_CFLAGS) build-exports.c -o $@ + -rm -f build-exports.c + + +$(IOP_BIN) : $(IOP_OBJS) + $(IOP_CC) $(IOP_LDFLAGS) -o $(IOP_BIN) $(IOP_OBJS) $(IOP_LIBS) + +$(IOP_LIB) : $(IOP_OBJS) + $(IOP_AR) cru $(IOP_LIB) $(IOP_OBJS) + diff --git a/ps2/libcdvd/iop/cdvd_iop.c b/ps2/libcdvd/iop/cdvd_iop.c new file mode 100644 index 0000000000..3e82b57267 --- /dev/null +++ b/ps2/libcdvd/iop/cdvd_iop.c @@ -0,0 +1,1852 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cdvd_iop.h" + +#define TRUE 1 +#define FALSE 0 + +enum PathMatch { + NOT_MATCH = 0, + MATCH, + SUBDIR +}; + +//#define DEBUG + +// 16 sectors worth of toc entry +#define MAX_DIR_CACHE_SECTORS 32 + + +//static u8 cdVolDescriptor[2048]; +static sceCdRMode cdReadMode; + +int lastsector; +int last_bk = 0; + + +struct rootDirTocHeader +{ + u16 length; + u32 tocLBA; + u32 tocLBA_bigend; + u32 tocSize; + u32 tocSize_bigend; + u8 dateStamp[8]; + u8 reserved[6]; + u8 reserved2; + u8 reserved3; +} __attribute__((packed)); + +struct asciiDate +{ + char year[4]; + char month[2]; + char day[2]; + char hours[2]; + char minutes[2]; + char seconds[2]; + char hundreths[2]; + char terminator[1]; +} __attribute__((packed)); + +struct cdVolDesc +{ + u8 filesystemType; // 0x01 = ISO9660, 0x02 = Joliet, 0xFF = NULL + u8 volID[5]; // "CD001" + u8 reserved2; + u8 reserved3; + u8 sysIdName[32]; + u8 volName[32]; // The ISO9660 Volume Name + u8 reserved5[8]; + u32 volSize; // Volume Size + u32 volSizeBig; // Volume Size Big-Endian + u8 reserved6[32]; + u32 unknown1; + u32 unknown1_bigend; + u16 volDescSize; + u16 volDescSize_bigend; + u32 unknown3; + u32 unknown3_bigend; + u32 priDirTableLBA; // LBA of Primary Dir Table + u32 reserved7; + u32 secDirTableLBA; // LBA of Secondary Dir Table + u32 reserved8; + struct rootDirTocHeader rootToc; + u8 volSetName[128]; + u8 publisherName[128]; + u8 preparerName[128]; + u8 applicationName[128]; + u8 copyrightFileName[37]; + u8 abstractFileName[37]; + u8 bibliographyFileName[37]; + struct asciiDate creationDate; + struct asciiDate modificationDate; + struct asciiDate effectiveDate; + struct asciiDate expirationDate; + u8 reserved10; + u8 reserved11[1166]; +} __attribute__((packed)); + +struct dirTableEntry +{ + u8 dirNameLength; + u8 reserved; + u32 dirTOCLBA; + u16 dirDepth; + u8 dirName[32]; +} __attribute__((packed)); + +struct dirTocEntry +{ + short length; + unsigned int fileLBA; + unsigned int fileLBA_bigend; + unsigned int fileSize; + unsigned int fileSize_bigend; + unsigned char dateStamp[6]; + unsigned char reserved1; + unsigned char fileProperties; + unsigned char reserved2[6]; + unsigned char filenameLength; + unsigned char filename[128]; +} __attribute__((packed)); // This is the internal format on the CD +// a file with a single character filename will have a 34byte toc entry +// (max 60 entries per sector)6 + +// TocEntry structure contains only the important stuff needed for export +// + +struct fdtable +{ + iop_file_t *fd; + int fileSize; + int LBA; + int filePos; +}; + + +struct dir_cache_info +{ + char pathname[1024]; // The pathname of the cached directory + unsigned int valid; // TRUE if cache data is valid, FALSE if not + + unsigned int path_depth; // The path depth of the cached directory (0 = root) + + unsigned int sector_start; // The start sector (LBA) of the cached directory + unsigned int sector_num; // The total size of the directory (in sectors) + unsigned int cache_offset; // The offset from sector_start of the cached area + unsigned int cache_size; // The size of the cached directory area (in sectors) + + char *cache; // The actual cached data +}; + + +static struct dir_cache_info CachedDirInfo; + +enum Cache_getMode { + CACHE_START = 0, + CACHE_NEXT = 1 +}; + +static struct cdVolDesc CDVolDesc; + +static unsigned int *buffer; // RPC send/receive buffer +struct t_SifRpcDataQueue qd; +struct t_SifRpcServerData sd0; + + +static struct fdtable fd_table[16]; +static int fd_used[16]; +static int files_open; + +static iop_device_t file_driver; + +/* Filing-system exported functions */ +int CDVD_init(iop_device_t *driver); +int CDVD_open(iop_file_t *f, const char *name, int mode); +int CDVD_lseek(iop_file_t *f, int offset, int whence); +int CDVD_read(iop_file_t *f, void *buffer, int size); +int CDVD_write(iop_file_t *f, void *buffer, int size); +int CDVD_close(iop_file_t *f); + +/* RPC exported functions */ +int CDVD_findfile(const char *fname, struct TocEntry *tocEntry); +int CDVD_stop(void); +int CDVD_trayreq(int mode); +int CDVD_diskready(void); +int CDVD_GetDir_RPC(const char *pathname, const char *extensions, enum CDVD_getMode getMode, struct TocEntry tocEntry[], unsigned int req_entries); + +int CDVD_getdir_IOP(const char *pathname, const char *extensions, enum CDVD_getMode getMode, struct TocEntry tocEntry[], unsigned int req_entries); + + +// Functions called by the RPC server +void *CDVDRpc_Stop(); +void *CDVDRpc_FlushCache(); +void *CDVDRpc_TrayReq(unsigned int *sbuff); +void *CDVDRpc_DiskReady(unsigned int *sbuff); +void *CDVDRpc_FindFile(unsigned int *sbuff); +void *CDVDRpc_Getdir(unsigned int *sbuff); +void *CDVDRpc_GetSize(unsigned int *sbuff); + + +/* Internal use functions */ +int isValidDisc(void); +int strcasecmp(const char *s1, const char *s2); +int strncasecmp(const char *s1, const char *s2, int limit); +int CDVD_GetVolumeDescriptor(void); +void _splitpath(const char *constpath, char *dir, char *fname); +void TocEntryCopy(struct TocEntry *tocEntry, struct dirTocEntry *internalTocEntry); +int TocEntryCompare(char *filename, const char *extensions); + +enum PathMatch ComparePath(const char *path); + +int CDVD_Cache_Dir(const char *pathname, enum Cache_getMode getMode); +int FindPath(char *pathname); + + +void *CDVD_rpc_server(int fno, void *data, int size); +void CDVD_Thread(void *param); + + + +/******************** +* Optimised CD Read * +********************/ + +int ReadSect(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode) +{ + int retry; + int result = 0; + cdReadMode.trycount = 32; + + for (retry = 0; retry < 32; retry++) // 32 retries + { + if (retry <= 8) + cdReadMode.spindlctrl = 1; // Try fast reads for first 8 tries + else + cdReadMode.spindlctrl = 0; // Then try slow reads + + if (!isValidDisc()) + return FALSE; + + sceCdDiskReady(0); + + if (sceCdRead(lsn, sectors, buf, mode) != TRUE) { + // Failed to read + if (retry == 31) { + // Still failed after last retry + memset(buf, 0, (sectors << 11)); + // printf("Couldn't Read from file for some reason\n"); + return FALSE; // error + } + } else { + // Read okay + sceCdSync(0); + break; + } + + result = sceCdGetError(); + if (result == 0) + break; + } + + cdReadMode.trycount = 32; + cdReadMode.spindlctrl = 1; + + if (result == 0) + return TRUE; + + memset(buf, 0, (sectors << 11)); + + return FALSE; // error +} + +/*********************************************** +* Determines if there is a valid disc inserted * +***********************************************/ +int isValidDisc(void) +{ + int result; + + switch (sceCdGetDiskType()) { + case SCECdPSCD: + case SCECdPSCDDA: + case SCECdPS2CD: + case SCECdPS2CDDA: + case SCECdPS2DVD: + result = 1; + break; + default: + result = 0; + } + + return result; +} + +/************************************************************* +* The functions below are the normal file-system operations, * +* used to provide a standard filesystem interface. There is * +* no need to export these functions for calling via RPC * +*************************************************************/ +int dummy() +{ +#ifdef DEBUG + printf("CDVD: dummy function called\n"); +#endif + + return -5; +} + +int CDVD_init(iop_device_t *driver) +{ + printf("CDVD: CDVD Filesystem v1.15\n"); + printf("by A.Lee (aka Hiryu) & Nicholas Van Veen (aka Sjeep)\n"); + printf("CDVD: Initializing '%s' file driver.\n", driver->name); + + sceCdInit(SCECdINoD); + + memset(fd_table, 0, sizeof(fd_table)); + memset(fd_used, 0, 16 * 4); + + return 0; +} + +int CDVD_deinit(iop_device_t *driver) +{ + return 0; +} + +int CDVD_open(iop_file_t *f, const char *name, int mode) +{ + int j; + static struct TocEntry tocEntry; + +#ifdef DEBUG + printf("CDVD: fd_open called.\n"); + printf(" kernel_fd.. %p\n", f); + printf(" name....... %s %x\n", name, (int)name); + printf(" mode....... %d\n\n", mode); +#endif + + // check if the file exists + if (CDVD_findfile(name, &tocEntry) != TRUE) { + return -1; + } + + if (mode != O_RDONLY) + return -2; + + // set up a new file descriptor + for (j = 0; j < 16; j++) { + if (fd_used[j] == 0) + break; + } + + if (j >= 16) + return -3; + + + fd_used[j] = 1; + files_open++; + +#ifdef DEBUG + printf("CDVD: internal fd %d\n", j); +#endif + + fd_table[j].fd = f; + fd_table[j].fileSize = tocEntry.fileSize; + fd_table[j].LBA = tocEntry.fileLBA; + fd_table[j].filePos = 0; + +#ifdef DEBUG + printf("tocEntry.fileSize = %d\n", tocEntry.fileSize); + + printf("Opened file: %s\n", name); +#endif + + return j; +} + + + +int CDVD_lseek(iop_file_t *f, int offset, int whence) +{ + int i; + +#ifdef DEBUG + printf("CDVD: fd_seek called.\n"); + printf(" kernel_fd... %p\n", f); + printf(" offset...... %d\n", offset); + printf(" whence...... %d\n\n", whence); +#endif + + for (i = 0; i < 16; i++) { + if (fd_table[i].fd == f) + break; + } + + if (i >= 16) { +#ifdef DEBUG + printf("CDVD_lseek: ERROR: File does not appear to be open!\n"); +#endif + + return -1; + } + + switch (whence) { + case SEEK_SET: + fd_table[i].filePos = offset; + break; + + case SEEK_CUR: + fd_table[i].filePos += offset; + break; + + case SEEK_END: + fd_table[i].filePos = fd_table[i].fileSize + offset; + break; + + default: + return -1; + } + + if (fd_table[i].filePos < 0) + fd_table[i].filePos = 0; + + if (fd_table[i].filePos > fd_table[i].fileSize) + fd_table[i].filePos = fd_table[i].fileSize; + + return fd_table[i].filePos; +} + + +int CDVD_read(iop_file_t *f, void *buffer, int size) +{ + int i; + + int start_sector; + int off_sector; + int num_sectors; + + int read = 0; + // int sector; + + // int size_left; + // int copy_size; + + static char local_buffer[9 * 2048]; + + +#ifdef DEBUG + printf("CDVD: read called\n"); + printf(" kernel_fd... %p\n", f); + printf(" buffer...... 0x%X\n", (int)buffer); + printf(" size........ %d\n\n", size); +#endif + + for (i = 0; i < 16; i++) { + if (fd_table[i].fd == f) + break; + } + + if (i >= 16) { +#ifdef DEBUG + printf("CDVD_read: ERROR: File does not appear to be open!\n"); +#endif + + return -1; + } + + + // A few sanity checks + if (fd_table[i].filePos > fd_table[i].fileSize) { + // We cant start reading from past the beginning of the file + return 0; // File exists but we couldnt read anything from it + } + + if ((fd_table[i].filePos + size) > fd_table[i].fileSize) + size = fd_table[i].fileSize - fd_table[i].filePos; + + if (size <= 0) + return 0; + + if (size > 16384) + size = 16384; + + // Now work out where we want to start reading from + start_sector = fd_table[i].LBA + (fd_table[i].filePos >> 11); + off_sector = (fd_table[i].filePos & 0x7FF); + + num_sectors = (off_sector + size); + num_sectors = (num_sectors >> 11) + ((num_sectors & 2047) != 0); + +#ifdef DEBUG + printf("CDVD_read: read sectors %d to %d\n", start_sector, start_sector + num_sectors); +#endif + + // Skip a Sector for equal (use the last sector in buffer) + if (start_sector == lastsector) { + read = 1; + if (last_bk > 0) + memcpy(local_buffer, local_buffer + 2048 * (last_bk), 2048); + last_bk = 0; + } + + lastsector = start_sector + num_sectors - 1; + // Read the data (we only ever get 16KB max request at once) + + if (read == 0 || (read == 1 && num_sectors > 1)) { + if (ReadSect(start_sector + read, num_sectors - read, local_buffer + ((read) << 11), &cdReadMode) != TRUE) { +#ifdef DEBUG + printf("Couldn't Read from file for some reason\n"); +#endif + } + + last_bk = num_sectors - 1; + } + + memcpy(buffer, local_buffer + off_sector, size); + + fd_table[i].filePos += size; + + return (size); +} + + +int CDVD_write(iop_file_t *f, void *buffer, int size) +{ + if (size == 0) + return 0; + else + return -1; +} + + + +int CDVD_close(iop_file_t *f) +{ + int i; + +#ifdef DEBUG + printf("CDVD: fd_close called.\n"); + printf(" kernel fd.. %p\n\n", f); +#endif + + for (i = 0; i < 16; i++) { + if (fd_table[i].fd == f) + break; + } + + if (i >= 16) { +#ifdef DEBUG + printf("CDVD_close: ERROR: File does not appear to be open!\n"); +#endif + + return -1; + } + +#ifdef DEBUG + printf("CDVD: internal fd %d\n", i); +#endif + + fd_used[i] = 0; + files_open--; + + return 0; +} + + +static iop_device_ops_t filedriver_ops = { + &CDVD_init, + &CDVD_deinit, + (void *)&dummy, + &CDVD_open, + &CDVD_close, + &CDVD_read, + &CDVD_write, + &CDVD_lseek, + (void *)&dummy, + (void *)&dummy, + (void *)&dummy, + (void *)&dummy, + (void *)&dummy, + (void *)&dummy, + (void *)&dummy, + (void *)&dummy, + (void *)&dummy}; + +int _start(int argc, char **argv) +{ + int i; + struct _iop_thread param; + int th; + + // Initialise the directory cache + strcpy(CachedDirInfo.pathname, ""); // The pathname of the cached directory + CachedDirInfo.valid = FALSE; // Cache is not valid + CachedDirInfo.path_depth = 0; // 0 = root) + CachedDirInfo.sector_start = 0; // The start sector (LBA) of the cached directory + CachedDirInfo.sector_num = 0; // The total size of the directory (in sectors) + CachedDirInfo.cache_offset = 0; // The offset from sector_start of the cached area + CachedDirInfo.cache_size = 0; // The size of the cached directory area (in sectors) + + if (CachedDirInfo.cache == NULL) + CachedDirInfo.cache = (char *)AllocSysMemory(0, MAX_DIR_CACHE_SECTORS * 2048, NULL); + + + // setup the cdReadMode structure + cdReadMode.trycount = 0; + cdReadMode.spindlctrl = SCECdSpinStm; + cdReadMode.datapattern = SCECdSecS2048; + + // setup the file_driver structure + file_driver.name = "cdfs"; + file_driver.type = IOP_DT_FS; + file_driver.version = 1; + file_driver.desc = "CDVD Filedriver"; + file_driver.ops = &filedriver_ops; + + DelDrv("cdfs"); + AddDrv(&file_driver); + + param.attr = TH_C; + param.thread = (void *)CDVD_Thread; + param.priority = 40; + param.stacksize = 0x8000; + param.option = 0; + + th = CreateThread(¶m); + + if (th > 0) { + StartThread(th, NULL); + return MODULE_RESIDENT_END; + } else + return MODULE_NO_RESIDENT_END; +} + +/************************************************************** +* The functions below are not exported for normal file-system * +* operations, but are used by the file-system operations, and * +* may also be exported for use via RPC * +**************************************************************/ + + +int CDVD_GetVolumeDescriptor(void) +{ + // Read until we find the last valid Volume Descriptor + int volDescSector; + + static struct cdVolDesc localVolDesc; + +#ifdef DEBUG + printf("CDVD_GetVolumeDescriptor called\n"); +#endif + + for (volDescSector = 16; volDescSector < 20; volDescSector++) { + ReadSect(volDescSector, 1, &localVolDesc, &cdReadMode); + + // If this is still a volume Descriptor + if (strncmp(localVolDesc.volID, "CD001", 5) == 0) { + if ((localVolDesc.filesystemType == 1) || + (localVolDesc.filesystemType == 2)) { + memcpy(&CDVolDesc, &localVolDesc, sizeof(struct cdVolDesc)); + } + } else + break; + } + +#ifdef DEBUG + switch (CDVolDesc.filesystemType) { + case 1: + printf("CD FileSystem is ISO9660\n"); + break; + + case 2: + printf("CD FileSystem is Joliet\n"); + break; + + default: + printf("CD FileSystem is unknown type\n"); + break; + } +#endif + // sceCdStop(); + + return TRUE; +} + + +int CDVD_findfile(const char *fname, struct TocEntry *tocEntry) +{ + static char filename[128 + 1]; + static char pathname[1024 + 1]; + + struct dirTocEntry *tocEntryPointer; + +#ifdef DEBUG + printf("CDVD_findfile called\n"); +#endif + + _splitpath(fname, pathname, filename); + +#ifdef DEBUG + printf("Trying to find file: %s in directory: %s\n", filename, pathname); +#endif + + // if ((CachedDirInfo.valid==TRUE) + // && (strcasecmp(pathname, CachedDirInfo.pathname)==0)) + + if ((CachedDirInfo.valid == TRUE) && (ComparePath(pathname) == MATCH)) { + // the directory is already cached, so check through the currently + // cached chunk of the directory first + + tocEntryPointer = (struct dirTocEntry *)CachedDirInfo.cache; + + for (; tocEntryPointer < (struct dirTocEntry *)(CachedDirInfo.cache + (CachedDirInfo.cache_size * 2048)); tocEntryPointer = (struct dirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length)) { + if (tocEntryPointer->length == 0) { +#ifdef DEBUG + printf("Got a null pointer entry, so either reached end of dir, or end of sector\n"); +#endif + + tocEntryPointer = (struct dirTocEntry *)(CachedDirInfo.cache + (((((char *)tocEntryPointer - CachedDirInfo.cache) / 2048) + 1) * 2048)); + } + + if (tocEntryPointer >= (struct dirTocEntry *)(CachedDirInfo.cache + (CachedDirInfo.cache_size * 2048))) { + // reached the end of the cache block + break; + } + + if ((tocEntryPointer->fileProperties & 0x02) == 0) { + // It's a file + TocEntryCopy(tocEntry, tocEntryPointer); + + if (strcasecmp(tocEntry->filename, filename) == 0) { + // and it matches !! + return TRUE; + } + } + } // end of for loop + + + + // If that was the only dir block, and we havent found it, then fail + if (CachedDirInfo.cache_size == CachedDirInfo.sector_num) + return FALSE; + + // Otherwise there is more dir to check + if (CachedDirInfo.cache_offset == 0) { + // If that was the first block then continue with the next block + if (CDVD_Cache_Dir(pathname, CACHE_NEXT) != TRUE) + return FALSE; + } else { + // otherwise (if that wasnt the first block) then start checking from the start + if (CDVD_Cache_Dir(pathname, CACHE_START) != TRUE) + return FALSE; + } + } else { +#ifdef DEBUG + printf("Trying to cache directory\n"); +#endif + // The wanted directory wasnt already cached, so cache it now + if (CDVD_Cache_Dir(pathname, CACHE_START) != TRUE) { +#ifdef DEBUG + printf("Failed to cache directory\n"); +#endif + + return FALSE; + } + } + +// If we've got here, then we have a block of the directory cached, and want to check +// from this point, to the end of the dir +#ifdef DEBUG + printf("cache_size = %d\n", CachedDirInfo.cache_size); +#endif + + while (CachedDirInfo.cache_size > 0) { + tocEntryPointer = (struct dirTocEntry *)CachedDirInfo.cache; + + if (CachedDirInfo.cache_offset == 0) + tocEntryPointer = (struct dirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length); + + for (; tocEntryPointer < (struct dirTocEntry *)(CachedDirInfo.cache + (CachedDirInfo.cache_size * 2048)); tocEntryPointer = (struct dirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length)) { + if (tocEntryPointer->length == 0) { +#ifdef DEBUG + printf("Got a null pointer entry, so either reached end of dir, or end of sector\n"); + printf("Offset into cache = %d bytes\n", (char *)tocEntryPointer - CachedDirInfo.cache); +#endif + + tocEntryPointer = (struct dirTocEntry *)(CachedDirInfo.cache + (((((char *)tocEntryPointer - CachedDirInfo.cache) / 2048) + 1) * 2048)); + } + + if (tocEntryPointer >= (struct dirTocEntry *)(CachedDirInfo.cache + (CachedDirInfo.cache_size * 2048))) { + // reached the end of the cache block + break; + } + + TocEntryCopy(tocEntry, tocEntryPointer); + + if (strcasecmp(tocEntry->filename, filename) == 0) { +#ifdef DEBUG + printf("Found a matching file\n"); +#endif + // and it matches !! + return TRUE; + } + +#ifdef DEBUG + printf("Non-matching file - looking for %s , found %s\n", filename, tocEntry->filename); +#endif + } // end of for loop + +#ifdef DEBUG + printf("Reached end of cache block\n"); +#endif + // cache the next block + CDVD_Cache_Dir(pathname, CACHE_NEXT); + } + +// we've run out of dir blocks to cache, and still not found it, so fail + +#ifdef DEBUG + printf("CDVD_findfile: could not find file\n"); +#endif + + return FALSE; +} + + + +// Find, and cache, the requested directory, for use by GetDir or (and thus open) +// provide an optional offset variable, for use when caching dirs of greater than 500 files + +// returns TRUE if all TOC entries have been retrieved, or +// returns FALSE if there are more TOC entries to be retrieved +int CDVD_Cache_Dir(const char *pathname, enum Cache_getMode getMode) +{ + + // macke sure that the requested pathname is not directly modified + static char dirname[1024]; + + int path_len; + +#ifdef DEBUG + printf("Attempting to find, and cache, directory: %s\n", pathname); +#endif + + // only take any notice of the existing cache, if it's valid + if (CachedDirInfo.valid == TRUE) { + // Check if the requested path is already cached + // if (strcasecmp(pathname,CachedDirInfo.pathname)==0) + if (ComparePath(pathname) == MATCH) { +#ifdef DEBUG + printf("CacheDir: The requested path is already cached\n"); +#endif + + // If so, is the request ot cache the start of the directory, or to resume the next block ? + if (getMode == CACHE_START) { +#ifdef DEBUG + printf(" and requested cache from start of dir\n"); +#endif + + if (CachedDirInfo.cache_offset == 0) { +// requested cache of start of the directory, and thats what's already cached +// so sit back and do nothing +#ifdef DEBUG + printf(" and start of dir is already cached so nothing to do :o)\n"); +#endif + + CachedDirInfo.valid = TRUE; + return TRUE; + } else { +// Requested cache of start of the directory, but thats not what's cached +// so re-cache the start of the directory + +#ifdef DEBUG + printf(" but dir isn't cached from start, so re-cache existing dir from start\n"); +#endif + + // reset cache data to start of existing directory + CachedDirInfo.cache_offset = 0; + CachedDirInfo.cache_size = CachedDirInfo.sector_num; + + if (CachedDirInfo.cache_size > MAX_DIR_CACHE_SECTORS) + CachedDirInfo.cache_size = MAX_DIR_CACHE_SECTORS; + + // Now fill the cache with the specified sectors + if (ReadSect(CachedDirInfo.sector_start + CachedDirInfo.cache_offset, CachedDirInfo.cache_size, CachedDirInfo.cache, &cdReadMode) != TRUE) { +#ifdef DEBUG + printf("Couldn't Read from CD !\n"); +#endif + + CachedDirInfo.valid = FALSE; // should we completely invalidate just because we couldnt read first time? + return FALSE; + } + + CachedDirInfo.valid = TRUE; + return TRUE; + } + } else // getMode == CACHE_NEXT + { + // So get the next block of the existing directory + + CachedDirInfo.cache_offset += CachedDirInfo.cache_size; + + CachedDirInfo.cache_size = CachedDirInfo.sector_num - CachedDirInfo.cache_offset; + + if (CachedDirInfo.cache_size > MAX_DIR_CACHE_SECTORS) + CachedDirInfo.cache_size = MAX_DIR_CACHE_SECTORS; + + // Now fill the cache with the specified sectors + if (ReadSect(CachedDirInfo.sector_start + CachedDirInfo.cache_offset, CachedDirInfo.cache_size, CachedDirInfo.cache, &cdReadMode) != TRUE) { +#ifdef DEBUG + printf("Couldn't Read from CD !\n"); +#endif + + CachedDirInfo.valid = FALSE; // should we completely invalidate just because we couldnt read first time? + return FALSE; + } + + CachedDirInfo.valid = TRUE; + return TRUE; + } + } else // requested directory is not the cached directory (but cache is still valid) + { +#ifdef DEBUG + printf("Cache is valid, but cached directory, is not the requested one\n" + "so check if the requested directory is a sub-dir of the cached one\n"); + + printf("Requested Path = %s , Cached Path = %s\n", pathname, CachedDirInfo.pathname); +#endif + + + // Is the requested pathname a sub-directory of the current-directory ? + + // if the requested pathname is longer than the pathname of the cached dir + // and the pathname of the cached dir matches the beginning of the requested pathname + // and the next character in the requested pathname is a dir seperator + // printf("Length of Cached pathname = %d, length of req'd pathname = %d\n",path_len, strlen(pathname)); + // printf("Result of strncasecmp = %d\n",strncasecmp(pathname, CachedDirInfo.pathname, path_len)); + // printf("next character after length of cached name = %c\n",pathname[path_len]); + + // if ((strlen(pathname) > path_len) + // && (strncasecmp(pathname, CachedDirInfo.pathname, path_len)==0) + // && ((pathname[path_len]=='/') || (pathname[path_len]=='\\'))) + + if (ComparePath(pathname) == SUBDIR) { +// If so then we can start our search for the path, from the currently cached directory +#ifdef DEBUG + printf("Requested dir is a sub-dir of the cached directory,\n" + "so start search from current cached dir\n"); +#endif + // if the cached chunk, is not the start of the dir, + // then we will need to re-load it before starting search + if (CachedDirInfo.cache_offset != 0) { + CachedDirInfo.cache_offset = 0; + CachedDirInfo.cache_size = CachedDirInfo.sector_num; + if (CachedDirInfo.cache_size > MAX_DIR_CACHE_SECTORS) + CachedDirInfo.cache_size = MAX_DIR_CACHE_SECTORS; + + // Now fill the cache with the specified sectors + if (ReadSect(CachedDirInfo.sector_start + CachedDirInfo.cache_offset, CachedDirInfo.cache_size, CachedDirInfo.cache, &cdReadMode) != TRUE) { +#ifdef DEBUG + printf("Couldn't Read from CD !\n"); +#endif + + CachedDirInfo.valid = FALSE; // should we completely invalidate just because we couldnt read time? + return FALSE; + } + } + + // start the search, with the path after the current directory + path_len = strlen(CachedDirInfo.pathname); + strcpy(dirname, pathname + path_len); + + // FindPath should use the current directory cache to start it's search + // and should change CachedDirInfo.pathname, to the path of the dir it finds + // it should also cache the first chunk of directory sectors, + // and fill the contents of the other elements of CachedDirInfo appropriately + + return (FindPath(dirname)); + } + } + } + +// If we've got here, then either the cache was not valid to start with +// or the requested path is not a subdirectory of the currently cached directory +// so lets start again +#ifdef DEBUG + printf("The cache is not valid, or the requested directory is not a sub-dir of the cached one\n"); +#endif + + if (!isValidDisc()) { +#ifdef DEBUG + printf("No supported disc inserted.\n"); +#endif + + return -1; + } + + sceCdDiskReady(0); + + // Read the main volume descriptor + if (CDVD_GetVolumeDescriptor() != TRUE) { +#ifdef DEBUG + printf("Could not read the CD/DVD Volume Descriptor\n"); +#endif + + return -1; + } + +#ifdef DEBUG + printf("Read the CD Volume Descriptor\n"); +#endif + + CachedDirInfo.path_depth = 0; + + strcpy(CachedDirInfo.pathname, ""); + + // Setup the lba and sector size, for retrieving the root toc + CachedDirInfo.cache_offset = 0; + CachedDirInfo.sector_start = CDVolDesc.rootToc.tocLBA; + CachedDirInfo.sector_num = (CDVolDesc.rootToc.tocSize >> 11) + ((CDVolDesc.rootToc.tocSize & 2047) != 0); + + CachedDirInfo.cache_size = CachedDirInfo.sector_num; + + if (CachedDirInfo.cache_size > MAX_DIR_CACHE_SECTORS) + CachedDirInfo.cache_size = MAX_DIR_CACHE_SECTORS; + + + // Now fill the cache with the specified sectors + if (ReadSect(CachedDirInfo.sector_start + CachedDirInfo.cache_offset, CachedDirInfo.cache_size, CachedDirInfo.cache, &cdReadMode) != TRUE) { +#ifdef DEBUG + printf("Couldn't Read from CD !\n"); +#endif + + CachedDirInfo.valid = FALSE; // should we completely invalidate just because we couldnt read time? + return FALSE; + } + +#ifdef DEBUG + printf("Read the first block from the root directory\n"); +#endif + +// FindPath should use the current directory cache to start it's search (in this case the root) +// and should change CachedDirInfo.pathname, to the path of the dir it finds +// it should also cache the first chunk of directory sectors, +// and fill the contents of the other elements of CachedDirInfo appropriately +#ifdef DEBUG + printf("Calling FindPath\n"); +#endif + strcpy(dirname, pathname); + + return (FindPath(dirname)); +} + +int FindPath(char *pathname) +{ + char *dirname; + char *seperator; + + int dir_entry; + int found_dir; + + struct dirTocEntry *tocEntryPointer; + struct TocEntry localTocEntry; + + dirname = strtok(pathname, "\\/"); + +#ifdef DEBUG + printf("FindPath: trying to find directory %s\n", pathname); +#endif + + if (!isValidDisc()) + return FALSE; + + sceCdDiskReady(0); + + while (dirname != NULL) { + found_dir = FALSE; + + tocEntryPointer = (struct dirTocEntry *)CachedDirInfo.cache; + + // Always skip the first entry (self-refencing entry) + tocEntryPointer = (struct dirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length); + + dir_entry = 0; + + for (; tocEntryPointer < (struct dirTocEntry *)(CachedDirInfo.cache + (CachedDirInfo.cache_size * 2048)); tocEntryPointer = (struct dirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length)) { + // If we have a null toc entry, then we've either reached the end of the dir, or have reached a sector boundary + if (tocEntryPointer->length == 0) { +#ifdef DEBUG + printf("Got a null pointer entry, so either reached end of dir, or end of sector\n"); +#endif + + tocEntryPointer = (struct dirTocEntry *)(CachedDirInfo.cache + (((((char *)tocEntryPointer - CachedDirInfo.cache) / 2048) + 1) * 2048)); + } + + if (tocEntryPointer >= (struct dirTocEntry *)(CachedDirInfo.cache + (CachedDirInfo.cache_size * 2048))) { + // If we've gone past the end of the cache + // then check if there are more sectors to load into the cache + + if ((CachedDirInfo.cache_offset + CachedDirInfo.cache_size) < CachedDirInfo.sector_num) { + // If there are more sectors to load, then load them + CachedDirInfo.cache_offset += CachedDirInfo.cache_size; + CachedDirInfo.cache_size = CachedDirInfo.sector_num - CachedDirInfo.cache_offset; + + if (CachedDirInfo.cache_size > MAX_DIR_CACHE_SECTORS) + CachedDirInfo.cache_size = MAX_DIR_CACHE_SECTORS; + + if (ReadSect(CachedDirInfo.sector_start + CachedDirInfo.cache_offset, CachedDirInfo.cache_size, CachedDirInfo.cache, &cdReadMode) != TRUE) { +#ifdef DEBUG + printf("Couldn't Read from CD !\n"); +#endif + + CachedDirInfo.valid = FALSE; // should we completely invalidate just because we couldnt read time? + return FALSE; + } + + tocEntryPointer = (struct dirTocEntry *)CachedDirInfo.cache; + } else { + CachedDirInfo.valid = FALSE; + return FALSE; + } + } + + // If the toc Entry is a directory ... + if (tocEntryPointer->fileProperties & 0x02) { + // Convert to our format (inc ascii name), for the check + TocEntryCopy(&localTocEntry, tocEntryPointer); + + // If it's the link to the parent directory, then give it the name ".." + if (dir_entry == 0) { + if (CachedDirInfo.path_depth != 0) { +#ifdef DEBUG + printf("First directory entry in dir, so name it '..'\n"); +#endif + + strcpy(localTocEntry.filename, ".."); + } + } + + // Check if this is the directory that we are looking for + if (strcasecmp(dirname, localTocEntry.filename) == 0) { +#ifdef DEBUG + printf("Found the matching sub-directory\n"); +#endif + + found_dir = TRUE; + + if (dir_entry == 0) { + // We've matched with the parent directory + // so truncate the pathname by one level + + if (CachedDirInfo.path_depth > 0) + CachedDirInfo.path_depth--; + + if (CachedDirInfo.path_depth == 0) { + // If at root then just clear the path to root + // (simpler than finding the colon seperator etc) + CachedDirInfo.pathname[0] = 0; + } else { + seperator = strrchr(CachedDirInfo.pathname, '/'); + + if (seperator != NULL) + *seperator = 0; + } + } else { + // otherwise append a seperator, and the matched directory + // to the pathname + strcat(CachedDirInfo.pathname, "/"); + +#ifdef DEBUG + printf("Adding '%s' to cached pathname - path depth = %d\n", dirname, CachedDirInfo.path_depth); +#endif + + strcat(CachedDirInfo.pathname, dirname); + + CachedDirInfo.path_depth++; + } + + // Exit out of the search loop + // (and find the next sub-directory, if there is one) + break; + } else { +#ifdef DEBUG + printf("Found a directory, but it doesn't match\n"); +#endif + } + } + + dir_entry++; + + } // end of cache block search loop + + + // if we've reached here, without finding the directory, then it's not there + if (found_dir != TRUE) { + CachedDirInfo.valid = FALSE; + return FALSE; + } + + // find name of next dir + dirname = strtok(NULL, "\\/"); + + CachedDirInfo.sector_start = localTocEntry.fileLBA; + CachedDirInfo.sector_num = (localTocEntry.fileSize >> 11) + ((CDVolDesc.rootToc.tocSize & 2047) != 0); + + // Cache the start of the found directory + // (used in searching if this isn't the last dir, + // or used by whatever requested the cache in the first place if it is the last dir) + CachedDirInfo.cache_offset = 0; + CachedDirInfo.cache_size = CachedDirInfo.sector_num; + + if (CachedDirInfo.cache_size > MAX_DIR_CACHE_SECTORS) + CachedDirInfo.cache_size = MAX_DIR_CACHE_SECTORS; + + if (ReadSect(CachedDirInfo.sector_start + CachedDirInfo.cache_offset, CachedDirInfo.cache_size, CachedDirInfo.cache, &cdReadMode) != TRUE) { +#ifdef DEBUG + printf("Couldn't Read from CD, trying to read %d sectors, starting at sector %d !\n", + CachedDirInfo.cache_size, CachedDirInfo.sector_start + CachedDirInfo.cache_offset); +#endif + + CachedDirInfo.valid = FALSE; // should we completely invalidate just because we couldnt read time? + return FALSE; + } + } + +// If we've got here then we found the requested directory +#ifdef DEBUG + printf("FindPath found the path\n"); +#endif + + CachedDirInfo.valid = TRUE; + return TRUE; +} + + + +// This is the getdir for use by IOP clients +// fills an array of TocEntry stucts in IOP memory +int CDVD_getdir_IOP(const char *pathname, const char *extensions, enum CDVD_getMode getMode, struct TocEntry tocEntry[], unsigned int req_entries) +{ + // TO DO + return FALSE; +} + + +// This is the getdir for use by the EE RPC client +// It DMA's entries to the specified buffer in EE memory +int CDVD_GetDir_RPC(const char *pathname, const char *extensions, enum CDVD_getMode getMode, struct TocEntry tocEntry[], unsigned int req_entries) +{ + int matched_entries; + int dir_entry; + + struct TocEntry localTocEntry; + + struct dirTocEntry *tocEntryPointer; + + int intStatus; // interrupt status - for dis/en-abling interrupts + + struct t_SifDmaTransfer dmaStruct; + int dmaID; + + dmaID = 0; + +#ifdef DEBUG + printf("RPC GetDir Request\n"); +#endif + + matched_entries = 0; + + // pre-cache the dir (and get the new pathname - in-case selected "..") + if (CDVD_Cache_Dir(pathname, CACHE_START) != TRUE) { +#ifdef DEBUG + printf("CDVD_GetDir_RPC - Call of CDVD_Cache_Dir failed\n"); +#endif + + return -1; + } + +#ifdef DEBUG + printf("requested directory is %d sectors\n", CachedDirInfo.sector_num); +#endif + + if ((getMode == CDVD_GET_DIRS_ONLY) || (getMode == CDVD_GET_FILES_AND_DIRS)) { + // Cache the start of the requested directory + if (CDVD_Cache_Dir(CachedDirInfo.pathname, CACHE_START) != TRUE) { +#ifdef DEBUG + printf("CDVD_GetDir_RPC - Call of CDVD_Cache_Dir failed\n"); +#endif + + return -1; + } + + tocEntryPointer = (struct dirTocEntry *)CachedDirInfo.cache; + + // skip the first self-referencing entry + tocEntryPointer = (struct dirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length); + + // skip the parent entry if this is the root + if (CachedDirInfo.path_depth == 0) + tocEntryPointer = (struct dirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length); + + dir_entry = 0; + + while (1) { +#ifdef DEBUG + printf("CDVD_GetDir_RPC - inside while-loop\n"); +#endif + + // parse the current cache block + for (; tocEntryPointer < (struct dirTocEntry *)(CachedDirInfo.cache + (CachedDirInfo.cache_size * 2048)); tocEntryPointer = (struct dirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length)) { + if (tocEntryPointer->length == 0) { + // if we have a toc entry length of zero, + // then we've either reached the end of the sector, or the end of the dir + // so point to next sector (if there is one - will be checked by next condition) + + tocEntryPointer = (struct dirTocEntry *)(CachedDirInfo.cache + (((((char *)tocEntryPointer - CachedDirInfo.cache) / 2048) + 1) * 2048)); + } + + if (tocEntryPointer >= (struct dirTocEntry *)(CachedDirInfo.cache + (CachedDirInfo.cache_size * 2048))) { + // we've reached the end of the current cache block (which may be end of entire dir + // so just break the loop + break; + } + + // Check if the current entry is a dir or a file + if (tocEntryPointer->fileProperties & 0x02) { +#ifdef DEBUG + printf("We found a dir, and we want all dirs\n"); +#endif + + // wait for any previous DMA to complete + // before over-writing localTocEntry + while (sceSifDmaStat(dmaID) >= 0) + ; + + TocEntryCopy(&localTocEntry, tocEntryPointer); + + if (dir_entry == 0) { + if (CachedDirInfo.path_depth != 0) { +#ifdef DEBUG + printf("It's the first directory entry, so name it '..'\n"); +#endif + + strcpy(localTocEntry.filename, ".."); + } + } + + // DMA localTocEntry to the address specified by tocEntry[matched_entries] + + // setup the dma struct + dmaStruct.src = &localTocEntry; + dmaStruct.dest = &tocEntry[matched_entries]; + dmaStruct.size = sizeof(struct TocEntry); + dmaStruct.attr = 0; + + // Do the DMA transfer + CpuSuspendIntr(&intStatus); + + dmaID = sceSifSetDma(&dmaStruct, 1); + + CpuResumeIntr(intStatus); + + matched_entries++; + } else // it must be a file + { +#ifdef DEBUG + printf("We found a file, but we dont want files (at least not yet)\n"); +#endif + } + + dir_entry++; + + if (matched_entries >= req_entries) // if we've filled the requested buffer + return (matched_entries); // then just return + + } // end of the current cache block + + // if there is more dir to load, then load next chunk, else finish + if ((CachedDirInfo.cache_offset + CachedDirInfo.cache_size) < CachedDirInfo.sector_num) { + if (CDVD_Cache_Dir(CachedDirInfo.pathname, CACHE_NEXT) != TRUE) { + // failed to cache next block (should return TRUE even if + // there is no more directory, as long as a CD read didnt fail + return -1; + } + } else + break; + + tocEntryPointer = (struct dirTocEntry *)CachedDirInfo.cache; + } + } + + // Next do files + if ((getMode == CDVD_GET_FILES_ONLY) || (getMode == CDVD_GET_FILES_AND_DIRS)) { + // Cache the start of the requested directory + if (CDVD_Cache_Dir(CachedDirInfo.pathname, CACHE_START) != TRUE) { +#ifdef DEBUG + printf("CDVD_GetDir_RPC - Call of CDVD_Cache_Dir failed\n"); +#endif + + return -1; + } + + tocEntryPointer = (struct dirTocEntry *)CachedDirInfo.cache; + + // skip the first self-referencing entry + tocEntryPointer = (struct dirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length); + + // skip the parent entry if this is the root + if (CachedDirInfo.path_depth == 0) + tocEntryPointer = (struct dirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length); + + dir_entry = 0; + + while (1) { +#ifdef DEBUG + printf("CDVD_GetDir_RPC - inside while-loop\n"); +#endif + + // parse the current cache block + for (; tocEntryPointer < (struct dirTocEntry *)(CachedDirInfo.cache + (CachedDirInfo.cache_size * 2048)); tocEntryPointer = (struct dirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length)) { + if (tocEntryPointer->length == 0) { + // if we have a toc entry length of zero, + // then we've either reached the end of the sector, or the end of the dir + // so point to next sector (if there is one - will be checked by next condition) + + tocEntryPointer = (struct dirTocEntry *)(CachedDirInfo.cache + (((((char *)tocEntryPointer - CachedDirInfo.cache) / 2048) + 1) * 2048)); + } + + if (tocEntryPointer >= (struct dirTocEntry *)(CachedDirInfo.cache + (CachedDirInfo.cache_size * 2048))) { + // we've reached the end of the current cache block (which may be end of entire dir + // so just break the loop + break; + } + + // Check if the current entry is a dir or a file + if (tocEntryPointer->fileProperties & 0x02) { +#ifdef DEBUG + printf("We don't want files now\n"); +#endif + } else // it must be a file + { + // wait for any previous DMA to complete + // before over-writing localTocEntry + while (sceSifDmaStat(dmaID) >= 0) + ; + + TocEntryCopy(&localTocEntry, tocEntryPointer); + + if (strlen(extensions) > 0) { + // check if the file matches the extension list + if (TocEntryCompare(localTocEntry.filename, extensions) == TRUE) { +#ifdef DEBUG + printf("We found a file that matches the requested extension list\n"); +#endif + + // DMA localTocEntry to the address specified by tocEntry[matched_entries] + + // setup the dma struct + dmaStruct.src = &localTocEntry; + dmaStruct.dest = &tocEntry[matched_entries]; + dmaStruct.size = sizeof(struct TocEntry); + dmaStruct.attr = 0; + + // Do the DMA transfer + CpuSuspendIntr(&intStatus); + + dmaID = sceSifSetDma(&dmaStruct, 1); + + CpuResumeIntr(intStatus); + + matched_entries++; + } else { +#ifdef DEBUG + printf("We found a file, but it didnt match the requested extension list\n"); +#endif + } + } else // no extension list to match against + { +#ifdef DEBUG + printf("We found a file, and there is not extension list to match against\n"); +#endif + + // DMA localTocEntry to the address specified by tocEntry[matched_entries] + + // setup the dma struct + dmaStruct.src = &localTocEntry; + dmaStruct.dest = &tocEntry[matched_entries]; + dmaStruct.size = sizeof(struct TocEntry); + dmaStruct.attr = 0; + + // Do the DMA transfer + CpuSuspendIntr(&intStatus); + + dmaID = sceSifSetDma(&dmaStruct, 1); + + CpuResumeIntr(intStatus); + + matched_entries++; + } + } + + dir_entry++; + + if (matched_entries >= req_entries) // if we've filled the requested buffer + return (matched_entries); // then just return + + } // end of the current cache block + + + // if there is more dir to load, then load next chunk, else finish + if ((CachedDirInfo.cache_offset + CachedDirInfo.cache_size) < CachedDirInfo.sector_num) { + if (CDVD_Cache_Dir(CachedDirInfo.pathname, CACHE_NEXT) != TRUE) { + // failed to cache next block (should return TRUE even if + // there is no more directory, as long as a CD read didnt fail + return -1; + } + } else + break; + + tocEntryPointer = (struct dirTocEntry *)CachedDirInfo.cache; + } + } + // reached the end of the dir, before filling up the requested entries + + return (matched_entries); +} + +int CdFlushCache(void) +{ + strcpy(CachedDirInfo.pathname, ""); // The pathname of the cached directory + CachedDirInfo.valid = FALSE; // Cache is not valid + CachedDirInfo.path_depth = 0; // 0 = root) + CachedDirInfo.sector_start = 0; // The start sector (LBA) of the cached directory + CachedDirInfo.sector_num = 0; // The total size of the directory (in sectors) + CachedDirInfo.cache_offset = 0; // The offset from sector_start of the cached area + CachedDirInfo.cache_size = 0; // The size of the cached directory area (in sectors) + + return TRUE; +} + +unsigned int CdGetSize(void) +{ + if (CDVD_GetVolumeDescriptor() != TRUE) + return TRUE; + + return CDVolDesc.volSize; +} + +void *CDVDRpc_FlushCache() +{ + CdFlushCache(); + + return NULL; +} + + +void *CDVDRpc_Stop() +{ + if (isValidDisc()) { + sceCdStop(); + sceCdSync(0); + } + + return NULL; +} + +// Send: Offset 0 = mode. Size = int +// Return: Offset 0 = traycnt. Size = int +void *CDVDRpc_TrayReq(unsigned int *sbuff) +{ + int ret; + + sceCdTrayReq(sbuff[0], (s32 *)&ret); + + sbuff[0] = ret; + return sbuff; +} + +// Send: Offset 0 = mode +// Return: Offset 0 = ret val (cd status) +void *CDVDRpc_DiskReady(unsigned int *sbuff) +{ + int ret; + + if (isValidDisc()) + ret = sceCdDiskReady(sbuff[0]); + else + ret = -1; + + sbuff[0] = ret; + return sbuff; +} + +// Send: Offset 0 = filename string (1024 bytes) +// Return: Offset 0 = ret val (true/false). Size = int +// Offset 1024 = start of TocEntry structure +void *CDVDRpc_FindFile(unsigned int *sbuff) +{ + int ret; + + ret = CDVD_findfile((char *)&sbuff[0], (struct TocEntry *)&sbuff[1024 / 4]); + + sbuff[0] = ret; + + return sbuff; +} + +// Send: Offset 0 = filename string (1024 bytes) +// Send: Offset 1024 = extension string (128 bytes) +// Send: Offset 1152 = CDVD_getMode +// Send: Offset 1156 = pointer to array of TocEntry structures in EE mem +// Send: Offset 1160 = requested number of entries + +// Return: Offset 0 = ret val (number of matched entries). Size = int +// Return: Offset 4 = updated pathname (for if path selected = ".." +void *CDVDRpc_Getdir(unsigned int *sbuff) +{ + int ret; + + ret = CDVD_GetDir_RPC( + (char *)&sbuff[0 / 4], // pathname string + (char *)&sbuff[1024 / 4], // extension string + sbuff[1152 / 4], // CDVD_getMode + (struct TocEntry *)sbuff[1156 / 4], // pointer to array of TocEntry structures in EE mem + sbuff[1160 / 4] // requested number of entries + ); + + sbuff[0] = ret; + strcpy((char *)&sbuff[1], CachedDirInfo.pathname); + return sbuff; +} + +void *CDVDRpc_GetSize(unsigned int *sbuff) +{ + sbuff[0] = CdGetSize(); + return sbuff; +} + +/************************************************* +* The functions below are for internal use only, * +* and are not to be exported * +*************************************************/ + +void CDVD_Thread(void *param) +{ +#ifdef DEBUG + printf("CDVD: RPC Initialize\n"); +#endif + + sceSifInitRpc(0); + + // 0x4800 bytes for TocEntry structures (can fit 128 of them) + // 0x400 bytes for the filename string + buffer = AllocSysMemory(0, 0x4C00, NULL); + if (buffer == NULL) { +#ifdef DEBUG + printf("Failed to allocate memory for RPC buffer!\n"); +#endif + + SleepThread(); + } + + sceSifSetRpcQueue(&qd, GetThreadId()); + sceSifRegisterRpc(&sd0, CDVD_IRX, CDVD_rpc_server, (void *)buffer, 0, 0, &qd); + sceSifRpcLoop(&qd); +} + +void *CDVD_rpc_server(int fno, void *data, int size) +{ + + switch (fno) { + case CDVD_FINDFILE: + return CDVDRpc_FindFile((unsigned *)data); + case CDVD_GETDIR: + return CDVDRpc_Getdir((unsigned *)data); + case CDVD_STOP: + return CDVDRpc_Stop(); + case CDVD_TRAYREQ: + return CDVDRpc_TrayReq((unsigned *)data); + case CDVD_DISKREADY: + return CDVDRpc_DiskReady((unsigned *)data); + case CDVD_FLUSHCACHE: + return CDVDRpc_FlushCache(); + } + + return NULL; +} + +void _splitpath(const char *constpath, char *dir, char *fname) +{ + // 255 char max path-length is an ISO9660 restriction + // we must change this for Joliet or relaxed iso restriction support + static char pathcopy[1024 + 1]; + + char *slash; + + strncpy(pathcopy, constpath, 1024); + + slash = strrchr(pathcopy, '/'); + + // if the path doesn't contain a '/' then look for a '\' + if (!slash) + slash = strrchr(pathcopy, (int)'\\'); + + // if a slash was found + if (slash != NULL) { + // null terminate the path + slash[0] = 0; + // and copy the path into 'dir' + strncpy(dir, pathcopy, 1024); + dir[255] = 0; + + // copy the filename into 'fname' + strncpy(fname, slash + 1, 128); + fname[128] = 0; + } else { + dir[0] = 0; + + strncpy(fname, pathcopy, 128); + fname[128] = 0; + } +} + +// Copy a TOC Entry from the CD native format to our tidier format +void TocEntryCopy(struct TocEntry *tocEntry, struct dirTocEntry *internalTocEntry) +{ + int i; + int filenamelen; + + tocEntry->fileSize = internalTocEntry->fileSize; + tocEntry->fileLBA = internalTocEntry->fileLBA; + tocEntry->fileProperties = internalTocEntry->fileProperties; + + if (CDVolDesc.filesystemType == 2) { + // This is a Joliet Filesystem, so use Unicode to ISO string copy + filenamelen = internalTocEntry->filenameLength / 2; + + for (i = 0; i < filenamelen; i++) + tocEntry->filename[i] = internalTocEntry->filename[(i << 1) + 1]; + } else { + filenamelen = internalTocEntry->filenameLength; + + // use normal string copy + strncpy(tocEntry->filename, internalTocEntry->filename, 128); + } + + tocEntry->filename[filenamelen] = 0; + + if (!(tocEntry->fileProperties & 0x02)) { + // strip the ;1 from the filename (if it's there) + strtok(tocEntry->filename, ";"); + } +} + +// Check if a TOC Entry matches our extension list +int TocEntryCompare(char *filename, const char *extensions) +{ + static char ext_list[129]; + + char *token; + + char *ext_point; + + strncpy(ext_list, extensions, 128); + ext_list[128] = 0; + + token = strtok(ext_list, " ,"); + while (token != NULL) { + // if 'token' matches extension of 'filename' + // then return a match + ext_point = strrchr(filename, '.'); + + if (strcasecmp(ext_point, token) == 0) + return (TRUE); + + /* Get next token: */ + token = strtok(NULL, " ,"); + } + + // If not match found then return FALSE + return (FALSE); +} + +// Used in findfile +//int tolower(int c); +int strcasecmp(const char *s1, const char *s2) +{ + while (*s1 != '\0' && tolower(*s1) == tolower(*s2)) { + s1++; + s2++; + } + + return tolower(*(unsigned char *)s1) - tolower(*(unsigned char *)s2); +} + +int strncasecmp(const char *s1, const char *s2, int limit) +{ + int i; + + for (i = 0; i < limit; i++) { + if (*s1 == '\0') + return tolower(*(unsigned char *)s1) - tolower(*(unsigned char *)s2); + + if (tolower(*s1) != tolower(*s2)) + return tolower(*(unsigned char *)s1) - tolower(*(unsigned char *)s2); + + s1++; + s2++; + } + + return 0; +} + +enum PathMatch ComparePath(const char *path) +{ + int length; + int i; + + length = strlen(CachedDirInfo.pathname); + + for (i = 0; i < length; i++) { + // check if character matches + if (path[i] != CachedDirInfo.pathname[i]) { + // if not, then is it just because of different path seperator ? + if ((path[i] == '/') || (path[i] == '\\')) { + if ((CachedDirInfo.pathname[i] == '/') || (CachedDirInfo.pathname[i] == '\\')) { + continue; + } + } + + // if the characters don't match for any other reason then report a failure + return NOT_MATCH; + } + } + + // Reached the end of the Cached pathname + + // if requested path is same length, then report exact match + if (path[length] == 0) + return MATCH; + + // if requested path is longer, and next char is a dir seperator + // then report sub-dir match + if ((path[length] == '/') || (path[length] == '\\')) + return SUBDIR; + else + return NOT_MATCH; +} diff --git a/ps2/libcdvd/iop/cdvd_iop.h b/ps2/libcdvd/iop/cdvd_iop.h new file mode 100644 index 0000000000..989ed12cef --- /dev/null +++ b/ps2/libcdvd/iop/cdvd_iop.h @@ -0,0 +1,84 @@ +#ifndef _CDVD_IOP_H +#define _CDVD_IOP_H + +#include "../common/cdvd.h" + +// Macros for READ Data pattan +#define CdSecS2048 0 // sector size 2048 +#define CdSecS2328 1 // sector size 2328 +#define CdSecS2340 2 // sector size 2340 + +// Macros for Spindle control +#define CdSpinMax 0 +#define CdSpinNom 1 // Starts reading data at maximum rotational velocity and if a read error occurs, the rotational velocity is reduced. +#define CdSpinStm 0 // Recommended stream rotation speed. + +typedef struct +{ + u8 stat; // 0: normal. Any other: error + u8 second; // second (BCD value) + u8 minute; // minute (BCD value) + u8 hour; // hour (BCD value) + u8 week; // week (BCD value) + u8 day; // day (BCD value) + u8 month; // month (BCD value) + u8 year; // year (BCD value) +} CdCLOCK; + +typedef struct +{ + u32 lsn; // Logical sector number of file + u32 size; // File size (in bytes) + char name[16]; // Filename + u8 date[8]; // 1th: Seconds + // 2th: Minutes + // 3th: Hours + // 4th: Date + // 5th: Month + // 6th 7th: Year (4 digits) +} CdlFILE; + +typedef struct +{ + u8 minute; // Minutes + u8 second; // Seconds + u8 sector; // Sector + u8 track; // Track number +} CdlLOCCD; + +typedef struct +{ + u8 trycount; // Read try count (No. of error retries + 1) (0 - 255) + u8 spindlctrl; // SCECdSpinStm: Recommended stream rotation speed. + // SCECdSpinNom: Starts reading data at maximum rotational velocity and if a read error occurs, the rotational velocity is reduced. + u8 datapattern; // SCECdSecS2048: Data size 2048 bytes + // SCECdSecS2328: 2328 bytes + // SCECdSecS2340: 2340 bytes + u8 pad; // Padding data produced by alignment. +} CdRMode; + + +int CdBreak(void); +int CdCallback(void (*func)()); +int CdDiskReady(int mode); +int CdGetDiskType(void); +int CdGetError(void); +u32 CdGetReadPos(void); +int CdGetToc(u8 *toc); +int CdInit(int init_mode); +CdlLOCCD *CdIntToPos(int i, CdlLOCCD *p); +int CdPause(void); +int CdPosToInt(CdlLOCCD *p); +int CdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode); +int CdReadClock(CdCLOCK *rtc); +int CdSearchFile(CdlFILE *fp, const char *name); +int CdSeek(u32 lsn); +int CdStandby(void); +int CdStatus(void); +int CdStop(void); +int CdSync(int mode); +int CdTrayReq(int mode, u32 *traycnt); +int CdFlushCache(void); +unsigned int CdGetSize(void); + +#endif // _CDVD_H diff --git a/ps2/libcdvd/iop/imports.lst b/ps2/libcdvd/iop/imports.lst new file mode 100644 index 0000000000..f47423c148 --- /dev/null +++ b/ps2/libcdvd/iop/imports.lst @@ -0,0 +1,62 @@ +cdvdman_IMPORTS_start +I_sceCdInit +I_sceCdGetError +I_sceCdRead +I_sceCdStop +I_sceCdSync +I_sceCdDiskReady +I_sceCdGetDiskType +I_sceCdTrayReq +cdvdman_IMPORTS_end + +intrman_IMPORTS_start +I_CpuSuspendIntr +I_CpuResumeIntr +intrman_IMPORTS_end + +ioman_IMPORTS_start +I_AddDrv +I_DelDrv +ioman_IMPORTS_end + +sifcmd_IMPORTS_start +I_sceSifInitRpc +I_sceSifSetRpcQueue +I_sceSifRegisterRpc +I_sceSifRpcLoop +sifcmd_IMPORTS_end + +sifman_IMPORTS_start +I_sceSifSetDma +I_sceSifDmaStat +sifman_IMPORTS_end + +stdio_IMPORTS_start +I_printf +I_puts +stdio_IMPORTS_end + +sysclib_IMPORTS_start +I_tolower +I_strcpy +I_strncpy +I_strncmp +I_strtok +I_strrchr +I_strcat +I_strlen +I_memset +I_memcpy +I_memcmp +sysclib_IMPORTS_end + +sysmem_IMPORTS_start +I_AllocSysMemory +sysmem_IMPORTS_end + +thbase_IMPORTS_start +I_GetThreadId +I_CreateThread +I_StartThread +I_SleepThread +thbase_IMPORTS_end diff --git a/ps2/libcdvd/iop/irx_imports.h b/ps2/libcdvd/iop/irx_imports.h new file mode 100644 index 0000000000..4048b3d831 --- /dev/null +++ b/ps2/libcdvd/iop/irx_imports.h @@ -0,0 +1,9 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/ps2/libcdvd/license.txt b/ps2/libcdvd/license.txt new file mode 100644 index 0000000000..bd0a0cb71d --- /dev/null +++ b/ps2/libcdvd/license.txt @@ -0,0 +1,45 @@ +Copyright (c) 2002, A.Lee & Nicholas Van Veen +All rights reserved. + +Redistribution and use of this software, in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. You are granted a license to use this software for academic, research and + non-commercial purposes only. + +4. The copyright holder imposes no restrictions on any code developed using + this software. However, the copyright holder retains a non-exclusive + royalty-free license to any modifications to the distribution made by the + licensee. + +5. Any licensee wishing to make commercial use of this software should contact + the copyright holder to execute the appropriate license for such commercial + use. Commercial use includes: + + - Integration of all or part of the source code into a product for sale + or commercial license by or on behalf of Licensee to third parties, or + + - Distribution of the binary code or source code to third parties that + need it to utilize a commercial product sold or licensed by or on + behalf of Licensee. + + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + From adf2743464161adc74130822e82285fac4b1e075 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Sat, 9 Mar 2019 14:11:04 +0100 Subject: [PATCH 032/237] Implement CDFS and custom file descriptor support --- Makefile.ps2 | 16 +- frontend/drivers/platform_ps2.c | 24 ++ gfx/drivers/ps2_gfx.c | 2 +- libretro-common/features/features_cpu.c | 1 + libretro-common/include/retro_miscellaneous.h | 2 +- libretro-common/vfs/vfs_implementation.c | 7 +- ps2/compat_files/cd.c | 323 ++++++++++++++++++ ps2/compat_files/murmur3.c | 317 +++++++++++++++++ ps2/compat_files/ps2_descriptor.c | 189 ++++++++++ ps2/compat_files/ps2_devices.c | 8 + ps2/compat_files/ps2_hashtable.c | 159 +++++++++ ps2/include/cd.h | 40 +++ ps2/include/murmur3.h | 29 ++ ps2/include/ps2_descriptor.h | 59 ++++ ps2/include/ps2_devices.h | 1 + ps2/include/ps2_hashtable.h | 45 +++ ps2/irx/Makefile | 14 +- 17 files changed, 1224 insertions(+), 12 deletions(-) create mode 100644 ps2/compat_files/cd.c create mode 100755 ps2/compat_files/murmur3.c create mode 100644 ps2/compat_files/ps2_descriptor.c create mode 100644 ps2/compat_files/ps2_hashtable.c create mode 100644 ps2/include/cd.h create mode 100755 ps2/include/murmur3.h create mode 100644 ps2/include/ps2_descriptor.h create mode 100644 ps2/include/ps2_hashtable.h diff --git a/Makefile.ps2 b/Makefile.ps2 index f4061c70bb..881f950860 100644 --- a/Makefile.ps2 +++ b/Makefile.ps2 @@ -5,12 +5,15 @@ HAVE_LOGGER = 0 HAVE_FILE_LOGGER = 0 HAVE_THREADS = 0 BIG_STACK = 0 -MUTE_WARNINGS = 0 +MUTE_WARNINGS = 1 PS2_IP = 192.168.1.150 TARGET = retroarchps2.elf TARGET_RELEASE = retroarchps2-release.elf +# Lib CDVD +CDVD_DIR = ps2/libcdvd + # Compile the IRXs first IRX_DIR = ps2/irx IRX_FILES = $(wildcard ps2/irx/*.c) @@ -27,7 +30,7 @@ ifeq ($(MUTE_WARNINGS), 1) DISABLE_WARNINGS := -Wno-sign-compare -Wno-unused -Wno-parentheses endif -INCDIR = -I$(PS2DEV)/gsKit/include -I$(PS2SDK)/ports/include +INCDIR = -I$(PS2DEV)/gsKit/include -I$(PS2SDK)/ports/include -I$(CDVD_DIR)/ee INCDIR += -Ips2 -Ips2/include -Ilibretro-common/include INCDIR += -Ideps -Ideps/stb -Ideps/libz -Ideps/7zip -Ideps/pthreads -Ideps/pthreads/platform/ps2 -Ideps/pthreads/platform/helper GPVAL = -G0 @@ -38,8 +41,9 @@ RARCH_DEFINES += -DPS2 -DUSE_IOP_CTYPE_MACRO -D_MIPS_ARCH_R5900 -DHAVE_ZLIB -DHA RARCH_DEFINES += -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -DHAVE_CC_RESAMPLER LIBDIR = -LDFLAGS += -L$(PS2SDK)/ports/lib -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ee/lib -L. -LIBS += -lretro_ps2 -lgskit -ldmakit -lgskit_toolkit -laudsrv -lmf -lpadx -lmtap -lmc -lhdd -lsdl -lfileXio -lpatches -lpoweroff +LDFLAGS += -L$(PS2SDK)/ports/lib -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ee/lib -L$(CDVD_DIR)/lib -L. +LIBS += -lretro_ps2 -lgskit -ldmakit -lgskit_toolkit -laudsrv -lmf -lpadx -lmtap -lmc -lhdd -lsdl -lfileXio +LIBS += -lcdvdfs -lpatches -lpoweroff ifeq ($(HAVE_THREADS), 1) @@ -64,9 +68,11 @@ CFLAGS += $(RARCH_DEFINES) EE_OBJS += $(IRX_DIR)/freemtap_irx.o $(IRX_DIR)/freepad_irx.o $(IRX_DIR)/freesio2_irx.o $(IRX_DIR)/iomanX_irx.o EE_OBJS += $(IRX_DIR)/fileXio_irx.o $(IRX_DIR)/mcman_irx.o $(IRX_DIR)/mcserv_irx.o $(IRX_DIR)/usbd_irx.o EE_OBJS += $(IRX_DIR)/usbhdfsd_irx.o $(IRX_DIR)/freesd_irx.o $(IRX_DIR)/audsrv_irx.o $(IRX_DIR)/poweroff_irx.o +EE_OBJS += $(IRX_DIR)/cdvd_irx.o # Missing objecst on the PS2SDK -EE_OBJS += ps2/compat_files/compat_ctype.o ps2/compat_files/time.o ps2/compat_files/ps2_devices.o +EE_OBJS += ps2/compat_files/compat_ctype.o ps2/compat_files/time.o ps2/compat_files/ps2_devices.o +EE_OBJS += ps2/compat_files/cd.o ps2/compat_files/ps2_hashtable.o ps2/compat_files/murmur3.o ps2/compat_files/ps2_descriptor.o #EE_OBJS = griffin/griffin.o bootstrap/ps2/kernel_functions.o EE_OBJS += griffin/griffin.o diff --git a/frontend/drivers/platform_ps2.c b/frontend/drivers/platform_ps2.c index 34b5d3a755..8cc839c79a 100644 --- a/frontend/drivers/platform_ps2.c +++ b/frontend/drivers/platform_ps2.c @@ -27,8 +27,11 @@ #include #include #include +#include +#include #include #include +#include char eboot_path[512]; char user_path[512]; @@ -180,6 +183,9 @@ static void frontend_ps2_init(void *data) SifExecModuleBuffer(&freesd_irx, size_freesd_irx, 0, NULL, NULL); SifExecModuleBuffer(&audsrv_irx, size_audsrv_irx, 0, NULL, NULL); + /* CDVD */ + SifExecModuleBuffer(&cdvd_irx, size_cdvd_irx, 0, NULL, NULL); + if (mcInit(MC_TYPE_XMC)) { RARCH_ERR("mcInit library not initalizated\n"); } @@ -201,6 +207,16 @@ static void frontend_ps2_init(void *data) RARCH_ERR("mtapPortOpen library not initalizated\n"); } + /* Initializes CDVD library */ + if (CDVD_Init() != 1) { + RARCH_ERR("CDVD_Init library not initalizated\n"); + } + if (cdInit(CDVD_INIT_INIT) != 1) { + RARCH_ERR("cdInit library not initalizated\n"); + } + + _init_ps2_io(); + /* Prepare device */ getcwd(cwd, sizeof(cwd)); bootDeviceID=getBootDeviceID(cwd); @@ -219,6 +235,9 @@ static void frontend_ps2_deinit(void *data) verbosity_disable(); command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL); #endif + _free_ps2_io(); + cdInit(CDVD_INIT_EXIT); + CDVD_Stop(); padEnd(); audsrv_quit(); fileXioExit(); @@ -333,6 +352,11 @@ static int frontend_ps2_parse_drive_list(void *data, bool load_content) msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR), enum_idx, FILE_TYPE_DIRECTORY, 0, 0); + menu_entries_append_enum(list, + rootDevicePath(BOOT_DEVICE_CDFS), + msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR), + enum_idx, + FILE_TYPE_DIRECTORY, 0, 0); menu_entries_append_enum(list, rootDevicePath(BOOT_DEVICE_MASS), msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR), diff --git a/gfx/drivers/ps2_gfx.c b/gfx/drivers/ps2_gfx.c index 40a197ec3f..381848be92 100644 --- a/gfx/drivers/ps2_gfx.c +++ b/gfx/drivers/ps2_gfx.c @@ -172,7 +172,7 @@ static void prim_texture(GSGLOBAL *gsGlobal, GSTEXTURE *texture, int zPosition, GS_TEXT); } -static void clearVRAMIfNeeded(ps2_video_t *ps2, void *frame, int width, int height) +static void clearVRAMIfNeeded(ps2_video_t *ps2, const void *frame, int width, int height) { if (!ps2->clearVRAM) { if(frame && frame != RETRO_HW_FRAME_BUFFER_VALID) { diff --git a/libretro-common/features/features_cpu.c b/libretro-common/features/features_cpu.c index e247e46a02..7b3283f124 100644 --- a/libretro-common/features/features_cpu.c +++ b/libretro-common/features/features_cpu.c @@ -68,6 +68,7 @@ #if defined(PS2) #include #include +#include #endif #if defined(__PSL1GHT__) diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index 814bdef923..3893416ee4 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -166,7 +166,7 @@ typedef struct # endif # endif #elif PS2 -# define PRI_SIZET "lu" +# define PRI_SIZET "u" #else # if (SIZE_MAX == 0xFFFF) # define PRI_SIZET "hu" diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c index b791fa0d6f..09bdca60d5 100644 --- a/libretro-common/vfs/vfs_implementation.c +++ b/libretro-common/vfs/vfs_implementation.c @@ -52,6 +52,7 @@ # endif # if defined(PS2) # include +# include # endif # include # include @@ -1045,7 +1046,7 @@ libretro_vfs_implementation_dir *retro_vfs_opendir_impl(const char *name, bool i #elif defined(VITA) || defined(PSP) rdir->directory = sceIoDopen(name); #elif defined(PS2) - rdir->directory = fileXioDopen(name); + rdir->directory = newfileXioDopen(name); #elif defined(_3DS) rdir->directory = !string_is_empty(name) ? opendir(name) : NULL; rdir->entry = NULL; @@ -1088,7 +1089,7 @@ bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir *rdir) return (sceIoDread(rdir->directory, &rdir->entry) > 0); #elif defined(PS2) iox_dirent_t record; - int ret = fileXioDread(rdir->directory, &record); + int ret = newfileXioDread(rdir->directory, &record); rdir->entry = record; return ( ret > 0); #elif defined(__CELLOS_LV2__) @@ -1186,7 +1187,7 @@ int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *rdir) #elif defined(VITA) || defined(PSP) sceIoDclose(rdir->directory); #elif defined(PS2) - fileXioDclose(rdir->directory); + newfileXioDclose(rdir->directory); #elif defined(__CELLOS_LV2__) rdir->error = cellFsClosedir(rdir->directory); #elif defined(ORBIS) diff --git a/ps2/compat_files/cd.c b/ps2/compat_files/cd.c new file mode 100644 index 0000000000..4369139720 --- /dev/null +++ b/ps2/compat_files/cd.c @@ -0,0 +1,323 @@ +#include +#include +#include +#include +#include +#include +#include +//#include +#include "cd.h" + +#include "ps2_devices.h" +#include "ps2_descriptor.h" + +#define CD_SERVER_INIT 0x80000592 +#define CD_SERVER_SCMD 0x80000593 +#define CD_SCMD_GETDISCTYPE 0x03 + +static SifRpcClientData_t clientInit __attribute__ ((aligned(64))); +static u32 initMode __attribute__ ((aligned(64))); +static s32 cdThreadId = 0; +static s32 bindSearchFile = -1; +static s32 bindDiskReady = -1; +static s32 bindInit = -1; +static s32 bindNCmd = -1; +static s32 bindSCmd = -1; +static s32 nCmdSemaId = -1; // n-cmd semaphore id +static s32 sCmdSemaId = -1; // s-cmd semaphore id +static s32 callbackSemaId = -1; // callback semaphore id +static s32 cdDebug = 0; +static s32 sCmdNum = 0; +static SifRpcClientData_t clientSCmd __attribute__ ((aligned(64))); +static u8 sCmdRecvBuff[48] __attribute__ ((aligned(64))); +static volatile s32 cbSema = 0; +static ee_thread_status_t cdThreadParam; +static s32 callbackThreadId = 0; +volatile s32 cdCallbackNum __attribute__ ((aligned(64))); + +static void cdSemaInit(void); +static s32 cdCheckSCmd(s32 cur_cmd); +static s32 cdSyncS(s32 mode); +static void cdSemaExit(void); + +s32 cdInit(s32 mode) +{ + s32 i; + + if (cdSyncS(1)) + return 0; + SifInitRpc(0); + cdThreadId = GetThreadId(); + bindSearchFile = -1; + bindNCmd = -1; + bindSCmd = -1; + bindDiskReady = -1; + bindInit = -1; + + while (1) { + if (SifBindRpc(&clientInit, CD_SERVER_INIT, 0) >= 0) + if (clientInit.server != 0) break; + i = 0x10000; + while (i--); + } + + bindInit = 0; + initMode = mode; + SifWriteBackDCache(&initMode, 4); + if (SifCallRpc(&clientInit, 0, 0, &initMode, 4, 0, 0, 0, 0) < 0) + return 0; + if (mode == CDVD_INIT_EXIT) { + cdSemaExit(); + nCmdSemaId = -1; + sCmdSemaId = -1; + callbackSemaId = -1; + } else { + cdSemaInit(); + } + return 1; +} + +static void cdSemaExit(void) +{ + if (callbackThreadId) { + cdCallbackNum = -1; + SignalSema(callbackSemaId); + } + DeleteSema(nCmdSemaId); + DeleteSema(sCmdSemaId); + DeleteSema(callbackSemaId); +} + +static void cdSemaInit(void) +{ + struct t_ee_sema semaParam; + + // return if both semaphores are already inited + if (nCmdSemaId != -1 && sCmdSemaId != -1) + return; + + semaParam.init_count = 1; + semaParam.max_count = 1; + semaParam.option = 0; + nCmdSemaId = CreateSema(&semaParam); + sCmdSemaId = CreateSema(&semaParam); + + semaParam.init_count = 0; + callbackSemaId = CreateSema(&semaParam); + + cbSema = 0; +} + +static s32 cdCheckSCmd(s32 cur_cmd) +{ + s32 i; + cdSemaInit(); + if (PollSema(sCmdSemaId) != sCmdSemaId) { + if (cdDebug > 0) + printf("Scmd fail sema cur_cmd:%d keep_cmd:%d\n", cur_cmd, sCmdNum); + return 0; + } + sCmdNum = cur_cmd; + ReferThreadStatus(cdThreadId, &cdThreadParam); + if (cdSyncS(1)) { + SignalSema(sCmdSemaId); + return 0; + } + + SifInitRpc(0); + if (bindSCmd >= 0) + return 1; + while (1) { + if (SifBindRpc(&clientSCmd, CD_SERVER_SCMD, 0) < 0) { + if (cdDebug > 0) + printf("Libcdvd bind err S cmd\n"); + } + if (clientSCmd.server != 0) + break; + + i = 0x10000; + while (i--) + ; + } + + bindSCmd = 0; + return 1; +} + +static s32 cdSyncS(s32 mode) +{ + if (mode == 0) { + if (cdDebug > 0) + printf("S cmd wait\n"); + while (SifCheckStatRpc(&clientSCmd)) + ; + return 0; + } + return SifCheckStatRpc(&clientSCmd); +} + +CdvdDiscType_t cdGetDiscType(void) +{ + if (cdCheckSCmd(CD_SCMD_GETDISCTYPE) == 0) + return 0; + + if (SifCallRpc(&clientSCmd, CD_SCMD_GETDISCTYPE, 0, 0, 0, sCmdRecvBuff, 4, 0, 0) < 0) { + SignalSema(sCmdSemaId); + return 0; + } + + SignalSema(sCmdSemaId); + return *(s32 *) UNCACHED_SEG(sCmdRecvBuff); +} + + + + + + + + + + + + +static int first_file_index; + +static int comp_entries_by_filename(const void *elem1, const void *elem2) +{ + return strcmp(((entries*)elem1)->filename, ((entries*)elem2)->filename); +} + +static inline char* strzncpy(char *d, const char *s, size_t l) +{ + d[0] = 0; return strncat(d, s, l); +} + + + + + +int listcdvd(const char *path, entries *FileEntry) +{ + static struct TocEntry TocEntryList[FILEENTRY_SIZE]; + char dir[1025]; + int i, n, t; + + strcpy(dir, &path[5]); + // Directories first... + + CDVD_FlushCache(); + n = CDVD_GetDir(dir, NULL, CDVD_GET_DIRS_ONLY, TocEntryList, FILEENTRY_SIZE, dir); + + for (i = 0; i < n; i++) { + if (TocEntryList[i].fileProperties & 0x02 && (!strcmp( + TocEntryList[i].filename, ".") || !strcmp( + TocEntryList[i].filename, ".."))) + continue; // Skip pseudopaths "." and ".." + + FileEntry[t].dircheck = 1; + strcpy(FileEntry[t].filename, TocEntryList[i].filename); + strzncpy(FileEntry[t].displayname, FileEntry[t].filename, 63); + t++; + + if (t >= FILEENTRY_SIZE - 2) { + break; + } + } + + qsort(FileEntry, t, sizeof(entries), comp_entries_by_filename); + first_file_index = t; + + // Now files only + + CDVD_FlushCache(); + n = CDVD_GetDir(dir, NULL, CDVD_GET_FILES_ONLY, TocEntryList, FILEENTRY_SIZE, dir); + + for (i = 0; i < n; i++) { + if (TocEntryList[i].fileProperties & 0x02 && (!strcmp( + TocEntryList[i].filename, ".") || !strcmp( + TocEntryList[i].filename, ".."))) + continue; // Skip pseudopaths "." and ".." + + FileEntry[t].dircheck = 0; + strcpy(FileEntry[t].filename, TocEntryList[i].filename); + strzncpy(FileEntry[t].displayname, FileEntry[t].filename, 63); + t++; + + if (t >= FILEENTRY_SIZE - 2) { + break; + } + } + + qsort(FileEntry + first_file_index, t - first_file_index, sizeof(entries), comp_entries_by_filename); + + return t; +} + + + + + + + +int fileXioCDDread(int fd, iox_dirent_t *dirent) +{ + DescriptorTranslation *descriptor = __ps2_fd_grab(fd); + if (descriptor->current_folder_position == -1) { + descriptor->current_folder_position = 0; + descriptor->items = listcdvd(descriptor->path, descriptor->FileEntry); + printf("Items in cdfs %i\n", descriptor->items); + } + + if (descriptor->current_folder_position < descriptor->items) { + strcpy(dirent->name, descriptor->FileEntry[descriptor->current_folder_position].filename); + if (descriptor->FileEntry[descriptor->current_folder_position].dircheck) { + dirent->stat.mode = FIO_S_IFDIR; + } + printf("Reading files from CDVD %s\n", dirent->name); + descriptor->current_folder_position++; + } else { + descriptor->current_folder_position = 0; + return 0; + } + + return 1; +} + + +int newfileXioDopen(const char *name) +{ + enum BootDeviceIDs deviceID = getBootDeviceID(name); + int fd; + if (deviceID == BOOT_DEVICE_CDFS) { + fd = __ps2_acquire_descriptor(); + DescriptorTranslation *descriptor = __ps2_fd_grab(fd); + strcpy(descriptor->path, name); + } else { + fd = fileXioDopen(name); + } + + return fd; +} + +int newfileXioDclose(int fd) +{ + // if (is_fd_valid(fd)) { + // int res = __ps2_release_descriptor(fd); + // printf("Releassssinggggg %i\n", res); + // return res; + // } else { + return fileXioDclose(fd); + // } +} + +int newfileXioDread(int fd, iox_dirent_t *dirent) +{ + if (is_fd_valid(fd)) { + return fileXioCDDread(fd, dirent); + } else { + return fileXioDread(fd, dirent); + } +} + + diff --git a/ps2/compat_files/murmur3.c b/ps2/compat_files/murmur3.c new file mode 100755 index 0000000000..8abd92bca7 --- /dev/null +++ b/ps2/compat_files/murmur3.c @@ -0,0 +1,317 @@ +//----------------------------------------------------------------------------- +// MurmurHash3 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. + +// Note - The x86 and x64 versions do _not_ produce the same results, as the +// algorithms are optimized for their respective platforms. You can still +// compile and run any of them on any platform, but your performance with the +// non-native version will be less than optimal. + +#include "murmur3.h" + +/*----------------------------------------------------------------------------- + Platform-specific functions and macros +*/ + +#ifdef __GNUC__ +#define FORCE_INLINE __attribute__((always_inline)) inline +#else +#define FORCE_INLINE inline +#endif + +static FORCE_INLINE uint32_t rotl32 ( uint32_t x, int8_t r ) +{ + return (x << r) | (x >> (32 - r)); +} + +static FORCE_INLINE uint64_t rotl64 ( uint64_t x, int8_t r ) +{ + return (x << r) | (x >> (64 - r)); +} + +#define ROTL32(x,y) rotl32(x,y) +#define ROTL64(x,y) rotl64(x,y) + +#define BIG_CONSTANT(x) (x##LLU) + +/*----------------------------------------------------------------------------- + Block read - if your platform needs to do endian-swapping or can only + handle aligned reads, do the conversion here +*/ + +#define getblock(p, i) (p[i]) + +/*-----------------------------------------------------------------------------*/ +/* Finalization mix - force all bits of a hash block to avalanche */ + +static FORCE_INLINE uint32_t fmix32 ( uint32_t h ) +{ + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return h; +} + +/*----------*/ + +static FORCE_INLINE uint64_t fmix64 ( uint64_t k ) +{ + k ^= k >> 33; + k *= BIG_CONSTANT(0xff51afd7ed558ccd); + k ^= k >> 33; + k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); + k ^= k >> 33; + + return k; +} + +/*-----------------------------------------------------------------------------*/ + +void MurmurHash3_x86_32( const void * key, int len, + uint32_t seed, void * out ) +{ + const uint8_t * data = (const uint8_t*)key; + const int nblocks = len / 4; + int i; + + uint32_t h1 = seed; + + uint32_t c1 = 0xcc9e2d51; + uint32_t c2 = 0x1b873593; + + /*----------*/ + /* body */ + + const uint32_t * blocks = (const uint32_t *)(data + nblocks*4); + + for(i = -nblocks; i; i++) + { + uint32_t k1 = getblock(blocks,i); + + k1 *= c1; + k1 = ROTL32(k1,15); + k1 *= c2; + + h1 ^= k1; + h1 = ROTL32(h1,13); + h1 = h1*5+0xe6546b64; + } + + /*----------*/ + /* tail */ + + const uint8_t * tail = (const uint8_t*)(data + nblocks*4); + + uint32_t k1 = 0; + + switch(len & 3) + { + case 3: k1 ^= tail[2] << 16; + case 2: k1 ^= tail[1] << 8; + case 1: k1 ^= tail[0]; + k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; + }; + + /*----------*/ + /* finalization */ + + h1 ^= len; + + h1 = fmix32(h1); + + *(uint32_t*)out = h1; +} + +/*-----------------------------------------------------------------------------*/ + +void MurmurHash3_x86_128 ( const void * key, const int len, + uint32_t seed, void * out ) +{ + const uint8_t * data = (const uint8_t*)key; + const int nblocks = len / 16; + int i; + + uint32_t h1 = seed; + uint32_t h2 = seed; + uint32_t h3 = seed; + uint32_t h4 = seed; + + uint32_t c1 = 0x239b961b; + uint32_t c2 = 0xab0e9789; + uint32_t c3 = 0x38b34ae5; + uint32_t c4 = 0xa1e38b93; + + /*----------*/ + /* body */ + + const uint32_t * blocks = (const uint32_t *)(data + nblocks*16); + + for(i = -nblocks; i; i++) + { + uint32_t k1 = getblock(blocks,i*4+0); + uint32_t k2 = getblock(blocks,i*4+1); + uint32_t k3 = getblock(blocks,i*4+2); + uint32_t k4 = getblock(blocks,i*4+3); + + k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; + + h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b; + + k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; + + h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747; + + k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; + + h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35; + + k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; + + h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17; + } + + /*----------*/ + /* tail */ + + const uint8_t * tail = (const uint8_t*)(data + nblocks*16); + + uint32_t k1 = 0; + uint32_t k2 = 0; + uint32_t k3 = 0; + uint32_t k4 = 0; + + switch(len & 15) + { + case 15: k4 ^= tail[14] << 16; + case 14: k4 ^= tail[13] << 8; + case 13: k4 ^= tail[12] << 0; + k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; + + case 12: k3 ^= tail[11] << 24; + case 11: k3 ^= tail[10] << 16; + case 10: k3 ^= tail[ 9] << 8; + case 9: k3 ^= tail[ 8] << 0; + k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; + + case 8: k2 ^= tail[ 7] << 24; + case 7: k2 ^= tail[ 6] << 16; + case 6: k2 ^= tail[ 5] << 8; + case 5: k2 ^= tail[ 4] << 0; + k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; + + case 4: k1 ^= tail[ 3] << 24; + case 3: k1 ^= tail[ 2] << 16; + case 2: k1 ^= tail[ 1] << 8; + case 1: k1 ^= tail[ 0] << 0; + k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; + }; + + /*----------*/ + /* finalization */ + + h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len; + + h1 += h2; h1 += h3; h1 += h4; + h2 += h1; h3 += h1; h4 += h1; + + h1 = fmix32(h1); + h2 = fmix32(h2); + h3 = fmix32(h3); + h4 = fmix32(h4); + + h1 += h2; h1 += h3; h1 += h4; + h2 += h1; h3 += h1; h4 += h1; + + ((uint32_t*)out)[0] = h1; + ((uint32_t*)out)[1] = h2; + ((uint32_t*)out)[2] = h3; + ((uint32_t*)out)[3] = h4; +} + +/*-----------------------------------------------------------------------------*/ + +void MurmurHash3_x64_128( const void * key, const int len, + const uint32_t seed, void * out ) +{ + const uint8_t * data = (const uint8_t*)key; + const int nblocks = len / 16; + int i; + + uint64_t h1 = seed; + uint64_t h2 = seed; + + uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5); + uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f); + + /*----------*/ + /* body */ + + const uint64_t * blocks = (const uint64_t *)(data); + + for(i = 0; i < nblocks; i++) + { + uint64_t k1 = getblock(blocks,i*2+0); + uint64_t k2 = getblock(blocks,i*2+1); + + k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; + + h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729; + + k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; + + h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5; + } + + /*----------*/ + /* tail */ + + const uint8_t * tail = (const uint8_t*)(data + nblocks*16); + + uint64_t k1 = 0; + uint64_t k2 = 0; + + switch(len & 15) + { + case 15: k2 ^= (uint64_t)(tail[14]) << 48; + case 14: k2 ^= (uint64_t)(tail[13]) << 40; + case 13: k2 ^= (uint64_t)(tail[12]) << 32; + case 12: k2 ^= (uint64_t)(tail[11]) << 24; + case 11: k2 ^= (uint64_t)(tail[10]) << 16; + case 10: k2 ^= (uint64_t)(tail[ 9]) << 8; + case 9: k2 ^= (uint64_t)(tail[ 8]) << 0; + k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; + + case 8: k1 ^= (uint64_t)(tail[ 7]) << 56; + case 7: k1 ^= (uint64_t)(tail[ 6]) << 48; + case 6: k1 ^= (uint64_t)(tail[ 5]) << 40; + case 5: k1 ^= (uint64_t)(tail[ 4]) << 32; + case 4: k1 ^= (uint64_t)(tail[ 3]) << 24; + case 3: k1 ^= (uint64_t)(tail[ 2]) << 16; + case 2: k1 ^= (uint64_t)(tail[ 1]) << 8; + case 1: k1 ^= (uint64_t)(tail[ 0]) << 0; + k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; + }; + + /*----------*/ + /* finalization */ + + h1 ^= len; h2 ^= len; + + h1 += h2; + h2 += h1; + + h1 = fmix64(h1); + h2 = fmix64(h2); + + h1 += h2; + h2 += h1; + + ((uint64_t*)out)[0] = h1; + ((uint64_t*)out)[1] = h2; +} + +/*-----------------------------------------------------------------------------*/ + diff --git a/ps2/compat_files/ps2_descriptor.c b/ps2/compat_files/ps2_descriptor.c new file mode 100644 index 0000000000..3c95c16905 --- /dev/null +++ b/ps2/compat_files/ps2_descriptor.c @@ -0,0 +1,189 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2018 - Francisco Javier Trujillo Mata - fjtrujy + * + * 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 . + */ + +#include + +#include +#include +#include +#include + +#define SCE_ERRNO_MASK 0xFF + +DescriptorTranslation *__ps2_fdmap[MAX_OPEN_FILES]; +DescriptorTranslation __ps2_fdmap_pool[MAX_OPEN_FILES]; + +static int _lock_sema_id = -1; +static inline int _lock(void) +{ + return(WaitSema(_lock_sema_id)); +} + +static inline int _unlock(void) +{ + return(SignalSema(_lock_sema_id)); +} + +void _init_ps2_io(void) { + int ret; + ee_sema_t sp; + + memset(__ps2_fdmap, 0, sizeof(__ps2_fdmap)); + memset(__ps2_fdmap_pool, 0, sizeof(__ps2_fdmap_pool)); + + sp.init_count = 1; + sp.max_count = 1; + sp.option = 0; + _lock_sema_id = CreateSema(&sp); + +} + +void _free_ps2_io(void) { + _lock(); + _unlock(); + if(_lock_sema_id >= 0) DeleteSema(_lock_sema_id); +} + +int __ps2_acquire_descriptor(void) +{ + int fd = -1; + int i = 0; + _lock(); + + // get free descriptor + // only allocate descriptors after stdin/stdout/stderr -> aka 0/1/2 + for (fd = 1; fd < MAX_OPEN_FILES; ++fd) + { + if (__ps2_fdmap[fd] == NULL) + { + // get free pool + for (i = 0; i < MAX_OPEN_FILES; ++i) + { + if (__ps2_fdmap_pool[i].ref_count == 0) + { + __ps2_fdmap[fd] = &__ps2_fdmap_pool[i]; + __ps2_fdmap[fd]->ref_count = 1; + __ps2_fdmap[fd]->current_folder_position = -1; + __ps2_fdmap[fd]->FileEntry = calloc(sizeof(entries), FILEENTRY_SIZE); + _unlock(); + return MAX_OPEN_FILES - fd; + } + } + } + } + + // // no mores descriptors available... + _unlock(); + return -1; +} + +int __ps2_release_descriptor(int fd) +{ + DescriptorTranslation *map = NULL; + int res = -1; + + _lock(); + + if (is_fd_valid(fd) && __ps2_fd_drop(__ps2_fdmap[MAX_OPEN_FILES - fd]) >= 0) + { + /* Correct fd value */ + fd = MAX_OPEN_FILES - fd; + free(__ps2_fdmap[fd]->FileEntry); + __ps2_fdmap[fd] = NULL; + res = 0; + } + + _unlock(); + return res; +} + +int __ps2_duplicate_descriptor(int fd) +{ + int fd2 = -1; + + _lock(); + + if (is_fd_valid(fd)) + { + /* Correct fd value */ + fd = MAX_OPEN_FILES - fd; + // get free descriptor + // only allocate descriptors after stdin/stdout/stderr -> aka 0/1/2 + for (fd2 = 0; fd2 < MAX_OPEN_FILES; ++fd2) + { + if (__ps2_fdmap[fd2] == NULL) + { + __ps2_fdmap[fd2] = __ps2_fdmap[fd]; + __ps2_fdmap[fd2]->ref_count++; + _unlock(); + return fd2; + } + } + } + + _unlock(); + return -1; +} + +int __ps2_descriptor_ref_count(int fd) +{ + int res = 0; + /* Correct fd value */ + fd = MAX_OPEN_FILES - fd; + + _lock(); + res = __ps2_fdmap[fd]->ref_count; + _unlock(); + return res; +} + +DescriptorTranslation *__ps2_fd_grab(int fd) +{ + DescriptorTranslation *map = NULL; + + _lock(); + + if (is_fd_valid(fd)) + { + /* Correct fd value */ + fd = MAX_OPEN_FILES - fd; + map = __ps2_fdmap[fd]; + + if (map) + map->ref_count++; + } + + _unlock(); + return map; +} + +int __ps2_fd_drop(DescriptorTranslation *map) +{ + _lock(); + + if (map->ref_count == 1) + { + int ret = 0; + + map->ref_count--; + memset(map, 0, sizeof(DescriptorTranslation)); + } + else + { + map->ref_count--; + } + + _unlock(); + return 0; +} diff --git a/ps2/compat_files/ps2_devices.c b/ps2/compat_files/ps2_devices.c index 08a071bd96..63a6eeadd6 100644 --- a/ps2/compat_files/ps2_devices.c +++ b/ps2/compat_files/ps2_devices.c @@ -16,12 +16,15 @@ #include #include +#include +#include #define DEVICE_SLASH "/" #define DEVICE_MC0 "mc0:" #define DEVICE_MC1 "mc1:" #define DEVICE_CDROM "cdrom0:" +#define DEVICE_CDFS "cdfs:" #define DEVICE_MASS "mass:" #define DEVICE_MASS0 "mass0:" #define DEVICE_HDD "hdd:" @@ -40,6 +43,7 @@ #define DEVICE_MC0_PATH DEVICE_MC0 DEVICE_SLASH #define DEVICE_MC1_PATH DEVICE_MC1 DEVICE_SLASH +#define DEVICE_CDFS_PATH DEVICE_CDFS DEVICE_SLASH #define DEVICE_CDROM_PATH DEVICE_CDROM DEVICE_SLASH #define DEVICE_MASS_PATH DEVICE_MASS DEVICE_SLASH #define DEVICE_MASS0_PATH DEVICE_MASS0 DEVICE_SLASH @@ -67,6 +71,8 @@ char *rootDevicePath(enum BootDeviceIDs device_id) return DEVICE_MC1_PATH; case BOOT_DEVICE_CDROM: return DEVICE_CDROM_PATH; + case BOOT_DEVICE_CDFS: + return DEVICE_CDFS_PATH; case BOOT_DEVICE_MASS: return DEVICE_MASS_PATH; case BOOT_DEVICE_MASS0: @@ -110,6 +116,8 @@ enum BootDeviceIDs getBootDeviceID(char *path) return BOOT_DEVICE_MC1; else if (!strncmp(path, DEVICE_CDROM, 7)) return BOOT_DEVICE_CDROM; + else if (!strncmp(path, DEVICE_CDFS, 5)) + return BOOT_DEVICE_CDFS; else if (!strncmp(path, DEVICE_MASS, 5)) return BOOT_DEVICE_MASS; else if (!strncmp(path, DEVICE_MASS0, 6)) diff --git a/ps2/compat_files/ps2_hashtable.c b/ps2/compat_files/ps2_hashtable.c new file mode 100644 index 0000000000..abeaa86d3c --- /dev/null +++ b/ps2/compat_files/ps2_hashtable.c @@ -0,0 +1,159 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2018 - Francisco Javier Trujillo Mata - fjtrujy + * + * 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 . + */ + +#include + +#include +#include +#include + +HashTable *crb_hashtable_create(uint32_t _size) { + HashTable *tbl = malloc(sizeof(HashTable)); + tbl->size = 0; + tbl->capacity = 0; + tbl->table = NULL; + return tbl; +} + +void crb_hashtable_destroy(HashTable **_tbl) { + if (_tbl == NULL || *_tbl == NULL) return; + + if ((*_tbl)->table != NULL) { + free((*_tbl)->table); + (*_tbl)->table = NULL; + } + + free(*_tbl); + + *_tbl = NULL; +} + +void crb_hashtable_grow(HashTable *_tbl) { + unsigned int oldCapacity; + struct table_entry **oldTable; + unsigned int i; + + if (_tbl == NULL) return; + + oldCapacity = _tbl->capacity; + if (_tbl->capacity > 0) { + _tbl->capacity *= 2; + } else { + _tbl->capacity = 32; + } + oldTable = _tbl->table; + _tbl->table = calloc(_tbl->capacity, sizeof(struct table_entry*)); + for (i = 0; i < oldCapacity; i++) { + if (oldTable[i] != NULL) { + crb_hashtable_insert(_tbl, oldTable[i]->key, oldTable[i]->value); + free(oldTable[i]); + } + } + free(oldTable); +} + +void crb_hashtable_hash(const char *_key, uint32_t *hash) { + MurmurHash3_x86_32(_key, strlen(_key), 0, hash); +} + +bool crb_hashtable_insert(HashTable *_tbl, const char *_key, void *_data) { + struct table_entry *entry, *next_entry; + uint32_t index; + + if (_tbl == NULL || _key == NULL || _data == NULL) return false; + + if (_tbl->size == _tbl->capacity) { + crb_hashtable_grow(_tbl); + } + + entry = malloc(sizeof(struct table_entry)); + if (entry == NULL) return false; + crb_hashtable_hash(_key, &entry->hash); + index = entry->hash % _tbl->capacity; + entry->key = strdup(_key); + entry->value = _data; + entry->next = NULL; + + if (_tbl->table[index] == NULL) { + _tbl->table[index] = entry; + } else { + next_entry = _tbl->table[index]; + while (next_entry != NULL) { + if (next_entry->next == NULL) { + next_entry->next = entry; + break; + } + next_entry = next_entry->next; + } + } + _tbl->size++; + return true; +} + +void *crb_hashtable_find(HashTable *_tbl, const char *_key) { + uint32_t hash; + struct table_entry *entry; + + if (_tbl == NULL || _key == NULL) return NULL; + + crb_hashtable_hash(_key, &hash); + + for (entry = _tbl->table[hash % _tbl->capacity]; entry != NULL; entry = entry->next) { + if (strcmp(_key, entry->key) == 0) return entry->value; + } + + return NULL; +} + +void *crb_hashtable_remove(HashTable *_tbl, const char *_key) { + uint32_t hash; + struct table_entry *entry, *sibling; + bool top = true; + void *data; + + if (_tbl == NULL || _key == NULL) return NULL; + + crb_hashtable_hash(_key, &hash); + + for (entry = _tbl->table[hash % _tbl->capacity]; entry != NULL; sibling = entry, entry = entry->next) { + if (strcmp(_key, entry->key) == 0) { + break; + } else { + top = false; + } + } + if (entry != NULL) { + data = entry->value; + if (top) { + if (entry->next != NULL) { + _tbl->table[hash % _tbl->capacity] = entry->next; + } else { + _tbl->table[hash % _tbl->capacity] = NULL; + } + } else { + if (entry->next != NULL) { + sibling->next = entry->next; + } else { + sibling->next = NULL; + } + } + free(entry->key); + free(entry); + entry = NULL; + _tbl->size--; + return data; + } + + return NULL; +} diff --git a/ps2/include/cd.h b/ps2/include/cd.h new file mode 100644 index 0000000000..31a050063d --- /dev/null +++ b/ps2/include/cd.h @@ -0,0 +1,40 @@ +#ifndef CD_H +#define CD_H + +#include +#include +#include + +#define CDVD_INIT_INIT 0x00 +#define CDVD_INIT_NOCHECK 0x01 +#define CDVD_INIT_EXIT 0x05 + +typedef enum { + CDVD_TYPE_NODISK = 0x00, // No Disc inserted + CDVD_TYPE_DETECT, // Detecting disc type + CDVD_TYPE_DETECT_CD, + CDVD_TYPE_DETECT_DVDSINGLE, + CDVD_TYPE_DETECT_DVDDUAL, + CDVD_TYPE_UNKNOWN, // Unknown disc type + + CDVD_TYPE_PS1CD = 0x10, // PS1 CD with no CDDA tracks + CDVD_TYPE_PS1CDDA, // PS1 CD with CDDA tracks + CDVD_TYPE_PS2CD, // PS2 CD with no CDDA tracks + CDVD_TYPE_PS2CDDA, // PS2 CD with CDDA tracks + CDVD_TYPE_PS2DVD, // PS2 DVD + + CDVD_TYPE_CDDA = 0xFD, // CDDA + CDVD_TYPE_DVDVIDEO, // DVD Video + CDVD_TYPE_ILLEGAL, // Illegal disk type +} CdvdDiscType_t; + +s32 cdInit(s32); +CdvdDiscType_t cdGetDiscType(void); + + + + +int newfileXioDopen(const char *name); +int newfileXioDread(int fd, iox_dirent_t *dirent); + +#endif diff --git a/ps2/include/murmur3.h b/ps2/include/murmur3.h new file mode 100755 index 0000000000..555659f620 --- /dev/null +++ b/ps2/include/murmur3.h @@ -0,0 +1,29 @@ +//----------------------------------------------------------------------------- +// MurmurHash3 was written by Austin Appleby, and is placed in the +// public domain. The author hereby disclaims copyright to this source +// code. + +#ifndef _MURMURHASH3_H_ +#define _MURMURHASH3_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*-----------------------------------------------------------------------------*/ + +void MurmurHash3_x86_32(const void *key, int len, uint32_t seed, void *out); + +void MurmurHash3_x86_128(const void *key, int len, uint32_t seed, void *out); + +void MurmurHash3_x64_128(const void *key, int len, uint32_t seed, void *out); + +/*-----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _MURMURHASH3_H_ */ diff --git a/ps2/include/ps2_descriptor.h b/ps2/include/ps2_descriptor.h new file mode 100644 index 0000000000..5a4f0fcbd3 --- /dev/null +++ b/ps2/include/ps2_descriptor.h @@ -0,0 +1,59 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2018 - Francisco Javier Trujillo Mata - fjtrujy + * + * 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 . + */ + +#ifndef PS2_DESCRIPTOR_H +#define PS2_DESCRIPTOR_H + +#include +#include + +#define MAX_OPEN_FILES 256 +#define FILEENTRY_SIZE 2048 + +typedef struct { + char displayname[64]; + int dircheck; + char filename[256]; +} entries; + +typedef struct +{ + char path[256]; + int ref_count; + int items; + int current_folder_position; + entries *FileEntry; +} DescriptorTranslation; + +extern DescriptorTranslation *__ps2_fdmap[]; + +void _init_ps2_io(void); +void _free_ps2_io(void); + +int __ps2_acquire_descriptor(void); +int __ps2_release_descriptor(int fd); +int __ps2_duplicate_descriptor(int fd); +int __ps2_descriptor_ref_count(int fd); +DescriptorTranslation *__ps2_fd_grab(int fd); +int __ps2_fd_drop(DescriptorTranslation *fdmap); + +static inline int is_fd_valid(int fd) +{ + /* Correct fd value */ + fd = MAX_OPEN_FILES - fd; + + return (fd > 0) && (fd < MAX_OPEN_FILES) && (__ps2_fdmap[fd] != NULL); +} + +#endif /* PS2_DESCRIPTOR_H */ diff --git a/ps2/include/ps2_devices.h b/ps2/include/ps2_devices.h index deab4ec0d2..a2bc283572 100644 --- a/ps2/include/ps2_devices.h +++ b/ps2/include/ps2_devices.h @@ -22,6 +22,7 @@ enum BootDeviceIDs{ BOOT_DEVICE_MC0 = 0, BOOT_DEVICE_MC1, BOOT_DEVICE_CDROM, + BOOT_DEVICE_CDFS, BOOT_DEVICE_MASS, BOOT_DEVICE_MASS0, BOOT_DEVICE_HDD, diff --git a/ps2/include/ps2_hashtable.h b/ps2/include/ps2_hashtable.h new file mode 100644 index 0000000000..2b3d86a50f --- /dev/null +++ b/ps2/include/ps2_hashtable.h @@ -0,0 +1,45 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2018 - Francisco Javier Trujillo Mata - fjtrujy + * + * 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 . + */ + +#ifndef PS2_HASHTABLE_H +#define PS2_HASHTABLE_H + +#include +#include + +struct table_entry { + char *key; + void *value; + uint32_t hash; + struct table_entry *next; +}; + +struct hash_table { + uint32_t capacity; + uint32_t size; + struct table_entry **table; +}; + +typedef struct hash_table HashTable; + +HashTable *crb_hashtable_create(uint32_t _size); +void crb_hashtable_destroy(HashTable **_tbl); + +void crb_hashtable_grow(HashTable *_tbl); +void crb_hashtable_hash(const char *_key, uint32_t *hash); +bool crb_hashtable_insert(HashTable *_tbl, const char *_key, void *_data); +void *crb_hashtable_find(HashTable *_tbl, const char *_key); +void *crb_hashtable_remove(HashTable *_tbl, const char *_key); + +#endif diff --git a/ps2/irx/Makefile b/ps2/irx/Makefile index 49cb342c2b..0328ccc8c1 100644 --- a/ps2/irx/Makefile +++ b/ps2/irx/Makefile @@ -2,20 +2,30 @@ EE_BIN2C = bin2c IRX_DIR = $(PS2SDK)/iop/irx +#Specific folder for cdvd.irx +LIBCDVD_DIR = ../libcdvd +LIBCDVD_IRX_DIR = $(LIBCDVD_DIR)/lib + #IRX modules # IRX modules - modules have to be in IRX_DIR IRX_FILES += freemtap.irx freepad.irx freesio2.irx iomanX.irx fileXio.irx mcman.irx mcserv.irx usbd.irx usbhdfsd.irx -IRX_FILES += freesd.irx audsrv.irx poweroff.irx +IRX_FILES += freesd.irx audsrv.irx poweroff.irx cdvd.irx IRX_C_FILES = $(IRX_FILES:.irx=_irx.c) # Specific file name and output per IRX Module %.irx: - $(EE_BIN2C) $(IRX_DIR)/$@ $(@:.irx=_irx.c) $(@:.irx=_irx) + if [[ "$(@)" == "cdvd.irx" ]]; then \ + $(MAKE) -C $(LIBCDVD_DIR); \ + $(EE_BIN2C) $(LIBCDVD_IRX_DIR)/$@ $(@:.irx=_irx.c) $(@:.irx=_irx); \ + else \ + $(EE_BIN2C) $(IRX_DIR)/$@ $(@:.irx=_irx.c) $(@:.irx=_irx); \ + fi all: $(IRX_FILES) clean: rm -f $(IRX_C_FILES) + $(MAKE) -C $(LIBCDVD_DIR) clean #Include preferences include $(PS2SDK)/samples/Makefile.pref From 8d1adbc6eeb6cb0a6c4ec5474d44febd5e7e078c Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Fri, 15 Mar 2019 01:14:53 +0100 Subject: [PATCH 033/237] Cleaning no needed functions and library --- .gitignore | 1 + Makefile.ps2 | 2 +- frontend/drivers/platform_ps2.c | 2 +- libretro-common/vfs/vfs_implementation.c | 8 +- ps2/compat_files/{cd.c => fileXio_cdvd.c} | 121 ++---- ps2/compat_files/murmur3.c | 317 ---------------- ps2/compat_files/ps2_descriptor.c | 169 ++++----- ps2/compat_files/ps2_hashtable.c | 159 -------- ps2/include/cd.h | 40 -- ps2/include/fileXio_cdvd.h | 37 ++ ps2/include/murmur3.h | 29 -- ps2/include/ps2_descriptor.h | 15 +- ps2/include/ps2_hashtable.h | 45 --- ps2/libcdvd/docs/libcdvd_ref.pdf | Bin 113259 -> 0 bytes ps2/libcdvd/example/Makefile | 17 - ps2/libcdvd/example/example.cpp | 425 ---------------------- ps2/libcdvd/example/font.fnt | Bin 262432 -> 0 bytes ps2/libcdvd/iop/cdvd_iop.c | 2 +- 18 files changed, 151 insertions(+), 1238 deletions(-) rename ps2/compat_files/{cd.c => fileXio_cdvd.c} (77%) delete mode 100755 ps2/compat_files/murmur3.c delete mode 100644 ps2/compat_files/ps2_hashtable.c delete mode 100644 ps2/include/cd.h create mode 100644 ps2/include/fileXio_cdvd.h delete mode 100755 ps2/include/murmur3.h delete mode 100644 ps2/include/ps2_hashtable.h delete mode 100644 ps2/libcdvd/docs/libcdvd_ref.pdf delete mode 100644 ps2/libcdvd/example/Makefile delete mode 100644 ps2/libcdvd/example/example.cpp delete mode 100644 ps2/libcdvd/example/font.fnt diff --git a/.gitignore b/.gitignore index 6d6bad97d8..caa622d541 100644 --- a/.gitignore +++ b/.gitignore @@ -167,6 +167,7 @@ retroarch_switch.nso # PS2 ps2/irx/*.c +ps2/libcdvd/lib/ # Wayland gfx/common/wayland/idle-inhibit-unstable-v1.c diff --git a/Makefile.ps2 b/Makefile.ps2 index 881f950860..9638fd087c 100644 --- a/Makefile.ps2 +++ b/Makefile.ps2 @@ -72,7 +72,7 @@ EE_OBJS += $(IRX_DIR)/cdvd_irx.o # Missing objecst on the PS2SDK EE_OBJS += ps2/compat_files/compat_ctype.o ps2/compat_files/time.o ps2/compat_files/ps2_devices.o -EE_OBJS += ps2/compat_files/cd.o ps2/compat_files/ps2_hashtable.o ps2/compat_files/murmur3.o ps2/compat_files/ps2_descriptor.o +EE_OBJS += ps2/compat_files/fileXio_cdvd.o ps2/compat_files/ps2_descriptor.o #EE_OBJS = griffin/griffin.o bootstrap/ps2/kernel_functions.o EE_OBJS += griffin/griffin.o diff --git a/frontend/drivers/platform_ps2.c b/frontend/drivers/platform_ps2.c index 8cc839c79a..d28986d4d8 100644 --- a/frontend/drivers/platform_ps2.c +++ b/frontend/drivers/platform_ps2.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c index 09bdca60d5..6dfb9b83b5 100644 --- a/libretro-common/vfs/vfs_implementation.c +++ b/libretro-common/vfs/vfs_implementation.c @@ -52,7 +52,7 @@ # endif # if defined(PS2) # include -# include +# include # endif # include # include @@ -1046,7 +1046,7 @@ libretro_vfs_implementation_dir *retro_vfs_opendir_impl(const char *name, bool i #elif defined(VITA) || defined(PSP) rdir->directory = sceIoDopen(name); #elif defined(PS2) - rdir->directory = newfileXioDopen(name); + rdir->directory = ps2fileXioDopen(name); #elif defined(_3DS) rdir->directory = !string_is_empty(name) ? opendir(name) : NULL; rdir->entry = NULL; @@ -1089,7 +1089,7 @@ bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir *rdir) return (sceIoDread(rdir->directory, &rdir->entry) > 0); #elif defined(PS2) iox_dirent_t record; - int ret = newfileXioDread(rdir->directory, &record); + int ret = ps2fileXioDread(rdir->directory, &record); rdir->entry = record; return ( ret > 0); #elif defined(__CELLOS_LV2__) @@ -1187,7 +1187,7 @@ int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *rdir) #elif defined(VITA) || defined(PSP) sceIoDclose(rdir->directory); #elif defined(PS2) - newfileXioDclose(rdir->directory); + ps2fileXioDclose(rdir->directory); #elif defined(__CELLOS_LV2__) rdir->error = cellFsClosedir(rdir->directory); #elif defined(ORBIS) diff --git a/ps2/compat_files/cd.c b/ps2/compat_files/fileXio_cdvd.c similarity index 77% rename from ps2/compat_files/cd.c rename to ps2/compat_files/fileXio_cdvd.c index 4369139720..09074c7094 100644 --- a/ps2/compat_files/cd.c +++ b/ps2/compat_files/fileXio_cdvd.c @@ -5,9 +5,7 @@ #include #include #include -//#include -#include "cd.h" - +#include #include "ps2_devices.h" #include "ps2_descriptor.h" @@ -17,32 +15,34 @@ static SifRpcClientData_t clientInit __attribute__ ((aligned(64))); static u32 initMode __attribute__ ((aligned(64))); -static s32 cdThreadId = 0; -static s32 bindSearchFile = -1; -static s32 bindDiskReady = -1; -static s32 bindInit = -1; -static s32 bindNCmd = -1; -static s32 bindSCmd = -1; -static s32 nCmdSemaId = -1; // n-cmd semaphore id -static s32 sCmdSemaId = -1; // s-cmd semaphore id -static s32 callbackSemaId = -1; // callback semaphore id -static s32 cdDebug = 0; -static s32 sCmdNum = 0; +static int cdThreadId = 0; +static int bindSearchFile = -1; +static int bindDiskReady = -1; +static int bindInit = -1; +static int bindNCmd = -1; +static int bindSCmd = -1; +static int nCmdSemaId = -1; // n-cmd semaphore id +static int sCmdSemaId = -1; // s-cmd semaphore id +static int callbackSemaId = -1; // callback semaphore id +static int cdDebug = 0; +static int sCmdNum = 0; static SifRpcClientData_t clientSCmd __attribute__ ((aligned(64))); static u8 sCmdRecvBuff[48] __attribute__ ((aligned(64))); -static volatile s32 cbSema = 0; +static volatile int cbSema = 0; static ee_thread_status_t cdThreadParam; -static s32 callbackThreadId = 0; -volatile s32 cdCallbackNum __attribute__ ((aligned(64))); +static int callbackThreadId = 0; +volatile int cdCallbackNum __attribute__ ((aligned(64))); static void cdSemaInit(void); -static s32 cdCheckSCmd(s32 cur_cmd); -static s32 cdSyncS(s32 mode); +static int cdCheckSCmd(int cur_cmd); +static int cdSyncS(int mode); static void cdSemaExit(void); -s32 cdInit(s32 mode) +static int first_file_index; + +int cdInit(int mode) { - s32 i; + int i; if (cdSyncS(1)) return 0; @@ -108,9 +108,9 @@ static void cdSemaInit(void) cbSema = 0; } -static s32 cdCheckSCmd(s32 cur_cmd) +static int cdCheckSCmd(int cur_cmd) { - s32 i; + int i; cdSemaInit(); if (PollSema(sCmdSemaId) != sCmdSemaId) { if (cdDebug > 0) @@ -144,7 +144,7 @@ static s32 cdCheckSCmd(s32 cur_cmd) return 1; } -static s32 cdSyncS(s32 mode) +static int cdSyncS(int mode) { if (mode == 0) { if (cdDebug > 0) @@ -156,33 +156,6 @@ static s32 cdSyncS(s32 mode) return SifCheckStatRpc(&clientSCmd); } -CdvdDiscType_t cdGetDiscType(void) -{ - if (cdCheckSCmd(CD_SCMD_GETDISCTYPE) == 0) - return 0; - - if (SifCallRpc(&clientSCmd, CD_SCMD_GETDISCTYPE, 0, 0, 0, sCmdRecvBuff, 4, 0, 0) < 0) { - SignalSema(sCmdSemaId); - return 0; - } - - SignalSema(sCmdSemaId); - return *(s32 *) UNCACHED_SEG(sCmdRecvBuff); -} - - - - - - - - - - - - -static int first_file_index; - static int comp_entries_by_filename(const void *elem1, const void *elem2) { return strcmp(((entries*)elem1)->filename, ((entries*)elem2)->filename); @@ -193,15 +166,12 @@ static inline char* strzncpy(char *d, const char *s, size_t l) d[0] = 0; return strncat(d, s, l); } - - - - -int listcdvd(const char *path, entries *FileEntry) +static int listcdvd(const char *path, entries *FileEntry) { static struct TocEntry TocEntryList[FILEENTRY_SIZE]; char dir[1025]; - int i, n, t; + int i, n; + int t = 0; strcpy(dir, &path[5]); // Directories first... @@ -254,19 +224,12 @@ int listcdvd(const char *path, entries *FileEntry) return t; } - - - - - - -int fileXioCDDread(int fd, iox_dirent_t *dirent) +static int fileXioCDDread(int fd, iox_dirent_t *dirent) { DescriptorTranslation *descriptor = __ps2_fd_grab(fd); if (descriptor->current_folder_position == -1) { descriptor->current_folder_position = 0; descriptor->items = listcdvd(descriptor->path, descriptor->FileEntry); - printf("Items in cdfs %i\n", descriptor->items); } if (descriptor->current_folder_position < descriptor->items) { @@ -274,7 +237,6 @@ int fileXioCDDread(int fd, iox_dirent_t *dirent) if (descriptor->FileEntry[descriptor->current_folder_position].dircheck) { dirent->stat.mode = FIO_S_IFDIR; } - printf("Reading files from CDVD %s\n", dirent->name); descriptor->current_folder_position++; } else { descriptor->current_folder_position = 0; @@ -284,10 +246,9 @@ int fileXioCDDread(int fd, iox_dirent_t *dirent) return 1; } - -int newfileXioDopen(const char *name) +int ps2fileXioDopen(const char *name) { - enum BootDeviceIDs deviceID = getBootDeviceID(name); + enum BootDeviceIDs deviceID = getBootDeviceID((char *)name); int fd; if (deviceID == BOOT_DEVICE_CDFS) { fd = __ps2_acquire_descriptor(); @@ -300,18 +261,7 @@ int newfileXioDopen(const char *name) return fd; } -int newfileXioDclose(int fd) -{ - // if (is_fd_valid(fd)) { - // int res = __ps2_release_descriptor(fd); - // printf("Releassssinggggg %i\n", res); - // return res; - // } else { - return fileXioDclose(fd); - // } -} - -int newfileXioDread(int fd, iox_dirent_t *dirent) +int ps2fileXioDread(int fd, iox_dirent_t *dirent) { if (is_fd_valid(fd)) { return fileXioCDDread(fd, dirent); @@ -320,4 +270,11 @@ int newfileXioDread(int fd, iox_dirent_t *dirent) } } - +int ps2fileXioDclose(int fd) +{ + if (is_fd_valid(fd)) { + return __ps2_release_descriptor(fd); + } else { + return fileXioDclose(fd); + } +} diff --git a/ps2/compat_files/murmur3.c b/ps2/compat_files/murmur3.c deleted file mode 100755 index 8abd92bca7..0000000000 --- a/ps2/compat_files/murmur3.c +++ /dev/null @@ -1,317 +0,0 @@ -//----------------------------------------------------------------------------- -// MurmurHash3 was written by Austin Appleby, and is placed in the public -// domain. The author hereby disclaims copyright to this source code. - -// Note - The x86 and x64 versions do _not_ produce the same results, as the -// algorithms are optimized for their respective platforms. You can still -// compile and run any of them on any platform, but your performance with the -// non-native version will be less than optimal. - -#include "murmur3.h" - -/*----------------------------------------------------------------------------- - Platform-specific functions and macros -*/ - -#ifdef __GNUC__ -#define FORCE_INLINE __attribute__((always_inline)) inline -#else -#define FORCE_INLINE inline -#endif - -static FORCE_INLINE uint32_t rotl32 ( uint32_t x, int8_t r ) -{ - return (x << r) | (x >> (32 - r)); -} - -static FORCE_INLINE uint64_t rotl64 ( uint64_t x, int8_t r ) -{ - return (x << r) | (x >> (64 - r)); -} - -#define ROTL32(x,y) rotl32(x,y) -#define ROTL64(x,y) rotl64(x,y) - -#define BIG_CONSTANT(x) (x##LLU) - -/*----------------------------------------------------------------------------- - Block read - if your platform needs to do endian-swapping or can only - handle aligned reads, do the conversion here -*/ - -#define getblock(p, i) (p[i]) - -/*-----------------------------------------------------------------------------*/ -/* Finalization mix - force all bits of a hash block to avalanche */ - -static FORCE_INLINE uint32_t fmix32 ( uint32_t h ) -{ - h ^= h >> 16; - h *= 0x85ebca6b; - h ^= h >> 13; - h *= 0xc2b2ae35; - h ^= h >> 16; - - return h; -} - -/*----------*/ - -static FORCE_INLINE uint64_t fmix64 ( uint64_t k ) -{ - k ^= k >> 33; - k *= BIG_CONSTANT(0xff51afd7ed558ccd); - k ^= k >> 33; - k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); - k ^= k >> 33; - - return k; -} - -/*-----------------------------------------------------------------------------*/ - -void MurmurHash3_x86_32( const void * key, int len, - uint32_t seed, void * out ) -{ - const uint8_t * data = (const uint8_t*)key; - const int nblocks = len / 4; - int i; - - uint32_t h1 = seed; - - uint32_t c1 = 0xcc9e2d51; - uint32_t c2 = 0x1b873593; - - /*----------*/ - /* body */ - - const uint32_t * blocks = (const uint32_t *)(data + nblocks*4); - - for(i = -nblocks; i; i++) - { - uint32_t k1 = getblock(blocks,i); - - k1 *= c1; - k1 = ROTL32(k1,15); - k1 *= c2; - - h1 ^= k1; - h1 = ROTL32(h1,13); - h1 = h1*5+0xe6546b64; - } - - /*----------*/ - /* tail */ - - const uint8_t * tail = (const uint8_t*)(data + nblocks*4); - - uint32_t k1 = 0; - - switch(len & 3) - { - case 3: k1 ^= tail[2] << 16; - case 2: k1 ^= tail[1] << 8; - case 1: k1 ^= tail[0]; - k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; - }; - - /*----------*/ - /* finalization */ - - h1 ^= len; - - h1 = fmix32(h1); - - *(uint32_t*)out = h1; -} - -/*-----------------------------------------------------------------------------*/ - -void MurmurHash3_x86_128 ( const void * key, const int len, - uint32_t seed, void * out ) -{ - const uint8_t * data = (const uint8_t*)key; - const int nblocks = len / 16; - int i; - - uint32_t h1 = seed; - uint32_t h2 = seed; - uint32_t h3 = seed; - uint32_t h4 = seed; - - uint32_t c1 = 0x239b961b; - uint32_t c2 = 0xab0e9789; - uint32_t c3 = 0x38b34ae5; - uint32_t c4 = 0xa1e38b93; - - /*----------*/ - /* body */ - - const uint32_t * blocks = (const uint32_t *)(data + nblocks*16); - - for(i = -nblocks; i; i++) - { - uint32_t k1 = getblock(blocks,i*4+0); - uint32_t k2 = getblock(blocks,i*4+1); - uint32_t k3 = getblock(blocks,i*4+2); - uint32_t k4 = getblock(blocks,i*4+3); - - k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; - - h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b; - - k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; - - h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747; - - k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; - - h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35; - - k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; - - h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17; - } - - /*----------*/ - /* tail */ - - const uint8_t * tail = (const uint8_t*)(data + nblocks*16); - - uint32_t k1 = 0; - uint32_t k2 = 0; - uint32_t k3 = 0; - uint32_t k4 = 0; - - switch(len & 15) - { - case 15: k4 ^= tail[14] << 16; - case 14: k4 ^= tail[13] << 8; - case 13: k4 ^= tail[12] << 0; - k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; - - case 12: k3 ^= tail[11] << 24; - case 11: k3 ^= tail[10] << 16; - case 10: k3 ^= tail[ 9] << 8; - case 9: k3 ^= tail[ 8] << 0; - k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; - - case 8: k2 ^= tail[ 7] << 24; - case 7: k2 ^= tail[ 6] << 16; - case 6: k2 ^= tail[ 5] << 8; - case 5: k2 ^= tail[ 4] << 0; - k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; - - case 4: k1 ^= tail[ 3] << 24; - case 3: k1 ^= tail[ 2] << 16; - case 2: k1 ^= tail[ 1] << 8; - case 1: k1 ^= tail[ 0] << 0; - k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; - }; - - /*----------*/ - /* finalization */ - - h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len; - - h1 += h2; h1 += h3; h1 += h4; - h2 += h1; h3 += h1; h4 += h1; - - h1 = fmix32(h1); - h2 = fmix32(h2); - h3 = fmix32(h3); - h4 = fmix32(h4); - - h1 += h2; h1 += h3; h1 += h4; - h2 += h1; h3 += h1; h4 += h1; - - ((uint32_t*)out)[0] = h1; - ((uint32_t*)out)[1] = h2; - ((uint32_t*)out)[2] = h3; - ((uint32_t*)out)[3] = h4; -} - -/*-----------------------------------------------------------------------------*/ - -void MurmurHash3_x64_128( const void * key, const int len, - const uint32_t seed, void * out ) -{ - const uint8_t * data = (const uint8_t*)key; - const int nblocks = len / 16; - int i; - - uint64_t h1 = seed; - uint64_t h2 = seed; - - uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5); - uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f); - - /*----------*/ - /* body */ - - const uint64_t * blocks = (const uint64_t *)(data); - - for(i = 0; i < nblocks; i++) - { - uint64_t k1 = getblock(blocks,i*2+0); - uint64_t k2 = getblock(blocks,i*2+1); - - k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; - - h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729; - - k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; - - h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5; - } - - /*----------*/ - /* tail */ - - const uint8_t * tail = (const uint8_t*)(data + nblocks*16); - - uint64_t k1 = 0; - uint64_t k2 = 0; - - switch(len & 15) - { - case 15: k2 ^= (uint64_t)(tail[14]) << 48; - case 14: k2 ^= (uint64_t)(tail[13]) << 40; - case 13: k2 ^= (uint64_t)(tail[12]) << 32; - case 12: k2 ^= (uint64_t)(tail[11]) << 24; - case 11: k2 ^= (uint64_t)(tail[10]) << 16; - case 10: k2 ^= (uint64_t)(tail[ 9]) << 8; - case 9: k2 ^= (uint64_t)(tail[ 8]) << 0; - k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; - - case 8: k1 ^= (uint64_t)(tail[ 7]) << 56; - case 7: k1 ^= (uint64_t)(tail[ 6]) << 48; - case 6: k1 ^= (uint64_t)(tail[ 5]) << 40; - case 5: k1 ^= (uint64_t)(tail[ 4]) << 32; - case 4: k1 ^= (uint64_t)(tail[ 3]) << 24; - case 3: k1 ^= (uint64_t)(tail[ 2]) << 16; - case 2: k1 ^= (uint64_t)(tail[ 1]) << 8; - case 1: k1 ^= (uint64_t)(tail[ 0]) << 0; - k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; - }; - - /*----------*/ - /* finalization */ - - h1 ^= len; h2 ^= len; - - h1 += h2; - h2 += h1; - - h1 = fmix64(h1); - h2 = fmix64(h2); - - h1 += h2; - h2 += h1; - - ((uint64_t*)out)[0] = h1; - ((uint64_t*)out)[1] = h2; -} - -/*-----------------------------------------------------------------------------*/ - diff --git a/ps2/compat_files/ps2_descriptor.c b/ps2/compat_files/ps2_descriptor.c index 3c95c16905..6af1106aac 100644 --- a/ps2/compat_files/ps2_descriptor.c +++ b/ps2/compat_files/ps2_descriptor.c @@ -19,40 +19,65 @@ #include #include -#define SCE_ERRNO_MASK 0xFF - -DescriptorTranslation *__ps2_fdmap[MAX_OPEN_FILES]; -DescriptorTranslation __ps2_fdmap_pool[MAX_OPEN_FILES]; - +static DescriptorTranslation *__ps2_fdmap[MAX_OPEN_FILES]; +static DescriptorTranslation __ps2_fdmap_pool[MAX_OPEN_FILES]; static int _lock_sema_id = -1; + static inline int _lock(void) { - return(WaitSema(_lock_sema_id)); + return(WaitSema(_lock_sema_id)); } static inline int _unlock(void) { - return(SignalSema(_lock_sema_id)); + return(SignalSema(_lock_sema_id)); +} + +static int __ps2_fd_drop(DescriptorTranslation *map) +{ + _lock(); + + if (map->ref_count == 1) + { + map->ref_count--; + free(map->FileEntry); + memset(map, 0, sizeof(DescriptorTranslation)); + } + else + { + map->ref_count--; + } + + _unlock(); + return 0; +} + +int is_fd_valid(int fd) +{ + /* Correct fd value */ + fd = MAX_OPEN_FILES - fd; + + return (fd > 0) && (fd < MAX_OPEN_FILES) && (__ps2_fdmap[fd] != NULL); } void _init_ps2_io(void) { - int ret; + int ret; ee_sema_t sp; - memset(__ps2_fdmap, 0, sizeof(__ps2_fdmap)); - memset(__ps2_fdmap_pool, 0, sizeof(__ps2_fdmap_pool)); + memset(__ps2_fdmap, 0, sizeof(__ps2_fdmap)); + memset(__ps2_fdmap_pool, 0, sizeof(__ps2_fdmap_pool)); sp.init_count = 1; - sp.max_count = 1; - sp.option = 0; - _lock_sema_id = CreateSema(&sp); + sp.max_count = 1; + sp.option = 0; + _lock_sema_id = CreateSema(&sp); } void _free_ps2_io(void) { - _lock(); - _unlock(); - if(_lock_sema_id >= 0) DeleteSema(_lock_sema_id); + _lock(); + _unlock(); + if(_lock_sema_id >= 0) DeleteSema(_lock_sema_id); } int __ps2_acquire_descriptor(void) @@ -61,13 +86,12 @@ int __ps2_acquire_descriptor(void) int i = 0; _lock(); - // get free descriptor - // only allocate descriptors after stdin/stdout/stderr -> aka 0/1/2 - for (fd = 1; fd < MAX_OPEN_FILES; ++fd) + /* get free descriptor */ + for (fd = 0; fd < MAX_OPEN_FILES; ++fd) { if (__ps2_fdmap[fd] == NULL) { - // get free pool + /* get free pool */ for (i = 0; i < MAX_OPEN_FILES; ++i) { if (__ps2_fdmap_pool[i].ref_count == 0) @@ -83,107 +107,44 @@ int __ps2_acquire_descriptor(void) } } - // // no mores descriptors available... + /* no mores descriptors available... */ _unlock(); return -1; } int __ps2_release_descriptor(int fd) { - DescriptorTranslation *map = NULL; - int res = -1; + int res = -1; - _lock(); - - if (is_fd_valid(fd) && __ps2_fd_drop(__ps2_fdmap[MAX_OPEN_FILES - fd]) >= 0) - { + if (is_fd_valid(fd) && __ps2_fd_drop(__ps2_fdmap[MAX_OPEN_FILES - fd]) >= 0) + { + _lock(); /* Correct fd value */ fd = MAX_OPEN_FILES - fd; - free(__ps2_fdmap[fd]->FileEntry); - __ps2_fdmap[fd] = NULL; - res = 0; - } + __ps2_fdmap[fd] = NULL; + res = 0; + _unlock(); + } - _unlock(); - return res; -} - -int __ps2_duplicate_descriptor(int fd) -{ - int fd2 = -1; - - _lock(); - - if (is_fd_valid(fd)) - { - /* Correct fd value */ - fd = MAX_OPEN_FILES - fd; - // get free descriptor - // only allocate descriptors after stdin/stdout/stderr -> aka 0/1/2 - for (fd2 = 0; fd2 < MAX_OPEN_FILES; ++fd2) - { - if (__ps2_fdmap[fd2] == NULL) - { - __ps2_fdmap[fd2] = __ps2_fdmap[fd]; - __ps2_fdmap[fd2]->ref_count++; - _unlock(); - return fd2; - } - } - } - - _unlock(); - return -1; -} - -int __ps2_descriptor_ref_count(int fd) -{ - int res = 0; - /* Correct fd value */ - fd = MAX_OPEN_FILES - fd; - - _lock(); - res = __ps2_fdmap[fd]->ref_count; - _unlock(); - return res; + return res; } DescriptorTranslation *__ps2_fd_grab(int fd) { - DescriptorTranslation *map = NULL; - - _lock(); + DescriptorTranslation *map = NULL; - if (is_fd_valid(fd)) - { + _lock(); + + if (is_fd_valid(fd)) + { /* Correct fd value */ fd = MAX_OPEN_FILES - fd; - map = __ps2_fdmap[fd]; + map = __ps2_fdmap[fd]; - if (map) - map->ref_count++; - } + if (map) + map->ref_count++; + } - _unlock(); - return map; -} - -int __ps2_fd_drop(DescriptorTranslation *map) -{ - _lock(); - - if (map->ref_count == 1) - { - int ret = 0; - - map->ref_count--; - memset(map, 0, sizeof(DescriptorTranslation)); - } - else - { - map->ref_count--; - } - - _unlock(); - return 0; + _unlock(); + return map; } diff --git a/ps2/compat_files/ps2_hashtable.c b/ps2/compat_files/ps2_hashtable.c deleted file mode 100644 index abeaa86d3c..0000000000 --- a/ps2/compat_files/ps2_hashtable.c +++ /dev/null @@ -1,159 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2018 - Francisco Javier Trujillo Mata - fjtrujy - * - * 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 . - */ - -#include - -#include -#include -#include - -HashTable *crb_hashtable_create(uint32_t _size) { - HashTable *tbl = malloc(sizeof(HashTable)); - tbl->size = 0; - tbl->capacity = 0; - tbl->table = NULL; - return tbl; -} - -void crb_hashtable_destroy(HashTable **_tbl) { - if (_tbl == NULL || *_tbl == NULL) return; - - if ((*_tbl)->table != NULL) { - free((*_tbl)->table); - (*_tbl)->table = NULL; - } - - free(*_tbl); - - *_tbl = NULL; -} - -void crb_hashtable_grow(HashTable *_tbl) { - unsigned int oldCapacity; - struct table_entry **oldTable; - unsigned int i; - - if (_tbl == NULL) return; - - oldCapacity = _tbl->capacity; - if (_tbl->capacity > 0) { - _tbl->capacity *= 2; - } else { - _tbl->capacity = 32; - } - oldTable = _tbl->table; - _tbl->table = calloc(_tbl->capacity, sizeof(struct table_entry*)); - for (i = 0; i < oldCapacity; i++) { - if (oldTable[i] != NULL) { - crb_hashtable_insert(_tbl, oldTable[i]->key, oldTable[i]->value); - free(oldTable[i]); - } - } - free(oldTable); -} - -void crb_hashtable_hash(const char *_key, uint32_t *hash) { - MurmurHash3_x86_32(_key, strlen(_key), 0, hash); -} - -bool crb_hashtable_insert(HashTable *_tbl, const char *_key, void *_data) { - struct table_entry *entry, *next_entry; - uint32_t index; - - if (_tbl == NULL || _key == NULL || _data == NULL) return false; - - if (_tbl->size == _tbl->capacity) { - crb_hashtable_grow(_tbl); - } - - entry = malloc(sizeof(struct table_entry)); - if (entry == NULL) return false; - crb_hashtable_hash(_key, &entry->hash); - index = entry->hash % _tbl->capacity; - entry->key = strdup(_key); - entry->value = _data; - entry->next = NULL; - - if (_tbl->table[index] == NULL) { - _tbl->table[index] = entry; - } else { - next_entry = _tbl->table[index]; - while (next_entry != NULL) { - if (next_entry->next == NULL) { - next_entry->next = entry; - break; - } - next_entry = next_entry->next; - } - } - _tbl->size++; - return true; -} - -void *crb_hashtable_find(HashTable *_tbl, const char *_key) { - uint32_t hash; - struct table_entry *entry; - - if (_tbl == NULL || _key == NULL) return NULL; - - crb_hashtable_hash(_key, &hash); - - for (entry = _tbl->table[hash % _tbl->capacity]; entry != NULL; entry = entry->next) { - if (strcmp(_key, entry->key) == 0) return entry->value; - } - - return NULL; -} - -void *crb_hashtable_remove(HashTable *_tbl, const char *_key) { - uint32_t hash; - struct table_entry *entry, *sibling; - bool top = true; - void *data; - - if (_tbl == NULL || _key == NULL) return NULL; - - crb_hashtable_hash(_key, &hash); - - for (entry = _tbl->table[hash % _tbl->capacity]; entry != NULL; sibling = entry, entry = entry->next) { - if (strcmp(_key, entry->key) == 0) { - break; - } else { - top = false; - } - } - if (entry != NULL) { - data = entry->value; - if (top) { - if (entry->next != NULL) { - _tbl->table[hash % _tbl->capacity] = entry->next; - } else { - _tbl->table[hash % _tbl->capacity] = NULL; - } - } else { - if (entry->next != NULL) { - sibling->next = entry->next; - } else { - sibling->next = NULL; - } - } - free(entry->key); - free(entry); - entry = NULL; - _tbl->size--; - return data; - } - - return NULL; -} diff --git a/ps2/include/cd.h b/ps2/include/cd.h deleted file mode 100644 index 31a050063d..0000000000 --- a/ps2/include/cd.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef CD_H -#define CD_H - -#include -#include -#include - -#define CDVD_INIT_INIT 0x00 -#define CDVD_INIT_NOCHECK 0x01 -#define CDVD_INIT_EXIT 0x05 - -typedef enum { - CDVD_TYPE_NODISK = 0x00, // No Disc inserted - CDVD_TYPE_DETECT, // Detecting disc type - CDVD_TYPE_DETECT_CD, - CDVD_TYPE_DETECT_DVDSINGLE, - CDVD_TYPE_DETECT_DVDDUAL, - CDVD_TYPE_UNKNOWN, // Unknown disc type - - CDVD_TYPE_PS1CD = 0x10, // PS1 CD with no CDDA tracks - CDVD_TYPE_PS1CDDA, // PS1 CD with CDDA tracks - CDVD_TYPE_PS2CD, // PS2 CD with no CDDA tracks - CDVD_TYPE_PS2CDDA, // PS2 CD with CDDA tracks - CDVD_TYPE_PS2DVD, // PS2 DVD - - CDVD_TYPE_CDDA = 0xFD, // CDDA - CDVD_TYPE_DVDVIDEO, // DVD Video - CDVD_TYPE_ILLEGAL, // Illegal disk type -} CdvdDiscType_t; - -s32 cdInit(s32); -CdvdDiscType_t cdGetDiscType(void); - - - - -int newfileXioDopen(const char *name); -int newfileXioDread(int fd, iox_dirent_t *dirent); - -#endif diff --git a/ps2/include/fileXio_cdvd.h b/ps2/include/fileXio_cdvd.h new file mode 100644 index 0000000000..ada31a1006 --- /dev/null +++ b/ps2/include/fileXio_cdvd.h @@ -0,0 +1,37 @@ +#ifndef PS2_CD_H +#define PS2_CD_H + +#include +#include +#include + +#define CDVD_INIT_INIT 0x00 +#define CDVD_INIT_NOCHECK 0x01 +#define CDVD_INIT_EXIT 0x05 + +typedef enum { + CDVD_TYPE_NODISK = 0x00, /* No Disc inserted */ + CDVD_TYPE_DETECT, /* Detecting disc type */ + CDVD_TYPE_DETECT_CD, + CDVD_TYPE_DETECT_DVDSINGLE, + CDVD_TYPE_DETECT_DVDDUAL, + CDVD_TYPE_UNKNOWN, /* Unknown disc type */ + + CDVD_TYPE_PS1CD = 0x10, /* PS1 CD with no CDDA tracks */ + CDVD_TYPE_PS1CDDA, /* PS1 CD with CDDA tracks */ + CDVD_TYPE_PS2CD, /* PS2 CD with no CDDA tracks */ + CDVD_TYPE_PS2CDDA, /* PS2 CD with CDDA tracks */ + CDVD_TYPE_PS2DVD, /* PS2 DVD */ + + CDVD_TYPE_CDDA = 0xFD, /* CDDA */ + CDVD_TYPE_DVDVIDEO, /* DVD Video */ + CDVD_TYPE_ILLEGAL, /* Illegal disk type */ +} CdvdDiscType_t; + +int cdInit(int); + +int ps2fileXioDopen(const char *name); +int ps2fileXioDread(int fd, iox_dirent_t *dirent); +int ps2fileXioDclose(int fd); + +#endif /* PS2_CD_H */ diff --git a/ps2/include/murmur3.h b/ps2/include/murmur3.h deleted file mode 100755 index 555659f620..0000000000 --- a/ps2/include/murmur3.h +++ /dev/null @@ -1,29 +0,0 @@ -//----------------------------------------------------------------------------- -// MurmurHash3 was written by Austin Appleby, and is placed in the -// public domain. The author hereby disclaims copyright to this source -// code. - -#ifndef _MURMURHASH3_H_ -#define _MURMURHASH3_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*-----------------------------------------------------------------------------*/ - -void MurmurHash3_x86_32(const void *key, int len, uint32_t seed, void *out); - -void MurmurHash3_x86_128(const void *key, int len, uint32_t seed, void *out); - -void MurmurHash3_x64_128(const void *key, int len, uint32_t seed, void *out); - -/*-----------------------------------------------------------------------------*/ - -#ifdef __cplusplus -} -#endif - -#endif /* _MURMURHASH3_H_ */ diff --git a/ps2/include/ps2_descriptor.h b/ps2/include/ps2_descriptor.h index 5a4f0fcbd3..1d9e84c3a8 100644 --- a/ps2/include/ps2_descriptor.h +++ b/ps2/include/ps2_descriptor.h @@ -16,7 +16,7 @@ #define PS2_DESCRIPTOR_H #include -#include +#include #define MAX_OPEN_FILES 256 #define FILEENTRY_SIZE 2048 @@ -40,20 +40,9 @@ extern DescriptorTranslation *__ps2_fdmap[]; void _init_ps2_io(void); void _free_ps2_io(void); - +int is_fd_valid(int fd); int __ps2_acquire_descriptor(void); int __ps2_release_descriptor(int fd); -int __ps2_duplicate_descriptor(int fd); -int __ps2_descriptor_ref_count(int fd); DescriptorTranslation *__ps2_fd_grab(int fd); -int __ps2_fd_drop(DescriptorTranslation *fdmap); - -static inline int is_fd_valid(int fd) -{ - /* Correct fd value */ - fd = MAX_OPEN_FILES - fd; - - return (fd > 0) && (fd < MAX_OPEN_FILES) && (__ps2_fdmap[fd] != NULL); -} #endif /* PS2_DESCRIPTOR_H */ diff --git a/ps2/include/ps2_hashtable.h b/ps2/include/ps2_hashtable.h deleted file mode 100644 index 2b3d86a50f..0000000000 --- a/ps2/include/ps2_hashtable.h +++ /dev/null @@ -1,45 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2018 - Francisco Javier Trujillo Mata - fjtrujy - * - * 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 . - */ - -#ifndef PS2_HASHTABLE_H -#define PS2_HASHTABLE_H - -#include -#include - -struct table_entry { - char *key; - void *value; - uint32_t hash; - struct table_entry *next; -}; - -struct hash_table { - uint32_t capacity; - uint32_t size; - struct table_entry **table; -}; - -typedef struct hash_table HashTable; - -HashTable *crb_hashtable_create(uint32_t _size); -void crb_hashtable_destroy(HashTable **_tbl); - -void crb_hashtable_grow(HashTable *_tbl); -void crb_hashtable_hash(const char *_key, uint32_t *hash); -bool crb_hashtable_insert(HashTable *_tbl, const char *_key, void *_data); -void *crb_hashtable_find(HashTable *_tbl, const char *_key); -void *crb_hashtable_remove(HashTable *_tbl, const char *_key); - -#endif diff --git a/ps2/libcdvd/docs/libcdvd_ref.pdf b/ps2/libcdvd/docs/libcdvd_ref.pdf deleted file mode 100644 index b8a99aa09d455bd9315dcb3edd3be17b7fce46ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113259 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 aq1*v$h{1lpo8jsO6on$?;JBeIMfyMHL#5yV diff --git a/ps2/libcdvd/example/Makefile b/ps2/libcdvd/example/Makefile deleted file mode 100644 index bc02ebc7ac..0000000000 --- a/ps2/libcdvd/example/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -#update this to point to the location of gslib -GSLIB = /ps2dev/gslib - -EE_BIN = example.elf -EE_OBJS = example.o - -EE_LDFLAGS += -L../lib -L$(GSLIB)/lib -EE_LIBS += -lkernel -lcdvdfs -lgs -lgcc -lsupc++ -lpad -EE_INCS += -I $(GSLIB)/source -I ../ee - -all: $(EE_BIN) - -clean: - rm -f *.elf *.o *.a - -include $(PS2LIB)/Makefile.pref -include $(PS2LIB)/Makefile.eeglobal diff --git a/ps2/libcdvd/example/example.cpp b/ps2/libcdvd/example/example.cpp deleted file mode 100644 index 8f42e44db6..0000000000 --- a/ps2/libcdvd/example/example.cpp +++ /dev/null @@ -1,425 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include - -#include "cdvd_rpc.h" - -#define scr_w 640 -#define scr_h 480 - - -#define TEXT_COL_BRIGHT GS_SET_RGBA(0xFF, 0xFF, 0xFF, 0x80) -#define TEXT_COL_DIM GS_SET_RGBA(0x40, 0x40, 0xFF, 0x80) - -#define TRUE 1 -#define FALSE 0 - -gsDriver *pDisplay; - -extern int screen; -int filelisty = 60; - -static float selected = 1; // The currently selected file/dir - - -int button_released = TRUE; - -//A pointer to an array of TocEntries to be alloc'd later -static struct TocEntry *TocEntryList; - - - -gsFontTex *fontTex; - - - -// pathname on CD -char pathname[1024 + 1] __attribute__((aligned(64))); - -gsFont myFont; - -int WaitPadReady(int port, int slot); -void SetPadMode(int port, int slot); - - -void ClearScreen(void) -{ - pDisplay->drawPipe.setAlphaEnable(GS_DISABLE); - pDisplay->drawPipe.RectFlat(0, 0, scr_w, scr_h, 0, GS_SET_RGBA(0, 0, 0, 0x80)); - pDisplay->drawPipe.setAlphaEnable(GS_ENABLE); - pDisplay->drawPipe.Flush(); -} - - -int main(void) -{ - SifInitRpc(0); - - SifLoadModule("rom0:SIO2MAN", 0, NULL); /* load sio2 manager irx */ - SifLoadModule("rom0:PADMAN", 0, NULL); /* load pad manager irx */ - - SifLoadModule("host:cdvd.irx", 0, NULL); - - CDVD_Init(); - - padInit(0); - - char *padBuf = (char *)memalign(64, 256); - - padPortOpen(0, 0, padBuf); - - SetPadMode(0, 0); - - // allocate the memory for a large file list - TocEntryList = (TocEntry *)memalign(64, 4000 * sizeof(struct TocEntry)); - - - // open the font file, find the size of the file, allocate memory for it, and load it - int fontfile = fioOpen("host:font.fnt", O_RDONLY); - int fontsize = fioLseek(fontfile, 0, SEEK_END); - fioLseek(fontfile, 0, SEEK_SET); - fontTex = (gsFontTex *)memalign(64, fontsize); - fioRead(fontfile, fontTex, fontsize); - fioClose(fontfile); - - // Upload the background to the texture buffer - pDisplay = new gsDriver; - - pDisplay->setDisplayMode(scr_w, scr_h, - 170, 80, - GS_PSMCT32, 2, - GS_TV_AUTO, GS_TV_INTERLACE, - GS_DISABLE, GS_DISABLE); - - // Enable Alpha Blending - pDisplay->drawPipe.setAlphaEnable(GS_ENABLE); - - myFont.assignPipe(&(pDisplay->drawPipe)); - - // Upload the font into the texture memory past the screen buffers - myFont.uploadFont(fontTex, pDisplay->getTextureBufferBase(), - fontTex->TexWidth, // Use the fontTex width as texbuffer width (can use diff width) - 0, 0); - - -#define list_max 21 - int list_size = 21; // Number of files to display in list - int first_file = 1; // The first file to display in the on-screen list - int num_files = 0; // The total number of files in the list - int offset; // Offset of the selected file into the displayed list - - struct padButtonStatus padButtons; - int ps2_buttons; - - button_released = TRUE; - - while (1) { - - while (1) // until we've selected a file - { - // Get entries from specified path, don't filter by file extension, - // get files and directories, get a maximum of 4000 entries, and update path if dir changed - num_files = CDVD_GetDir(pathname, NULL, CDVD_GET_FILES_AND_DIRS, TocEntryList, 4000, pathname); - - if (num_files < list_max) - list_size = num_files; - else - list_size = list_max; - - // Don't leave the drive spinning, it's annoying ! - CDVD_Stop(); - - while (1) // Until we've selected something (dir or file) - { - - // Get button presses - // If X then select the previously highlighted file - // If up/down then increase/decrease the selected file - int padState; - - // only listen to pad input if it's plugged in, and stable - padState = padGetState(0, 0); - if (padState == PAD_STATE_STABLE) { - padRead(0, 0, &padButtons); - ps2_buttons = (padButtons.btns[0] << 8) | padButtons.btns[1]; - ps2_buttons = ~ps2_buttons; - - if (num_files > 0) { - // file Selected - if (ps2_buttons & PAD_CROSS) { - if (button_released == TRUE) { - button_released = FALSE; - break; - } - } else - button_released = TRUE; - - // DPAD + Shoulder file Selection - if (ps2_buttons & PAD_UP) - selected -= 0.15; - else if (ps2_buttons & PAD_DOWN) - selected += 0.15; - else if (ps2_buttons & PAD_R1) - selected -= 1; - else if (ps2_buttons & PAD_R2) - selected += 1; - else if (ps2_buttons & PAD_L1) - selected = 1; - else if (ps2_buttons & PAD_L2) - selected = num_files; - } - - if (ps2_buttons & PAD_SELECT) { - strcpy(pathname, "/"); - - ClearScreen(); - - myFont.Print(0, 640, 220, 4, - TEXT_COL_BRIGHT, - GSFONT_ALIGN_CENTRE, "Please Change CD\nThen Press 'X'"); - - pDisplay->drawPipe.Flush(); - - // Wait for VSync and then swap buffers - pDisplay->WaitForVSync(); - - pDisplay->swapBuffers(); - - - CDVD_FlushCache(); - strcpy(pathname, "/"); - - while (1) { - int padState; - - // only listen to pad input if it's plugged in, and stable - padState = padGetState(0, 0); - if (padState == PAD_STATE_STABLE) { - padRead(0, 0, &padButtons); - ps2_buttons = (padButtons.btns[0] << 8) | padButtons.btns[1]; - ps2_buttons = ~ps2_buttons; - - // ROM Selected - if (ps2_buttons & PAD_CROSS) { - break; - } - } - - pDisplay->WaitForVSync(); - } - - num_files = CDVD_GetDir(pathname, NULL, CDVD_GET_FILES_AND_DIRS, TocEntryList, 4000, pathname); - - if (num_files < list_max) - list_size = num_files; - else - list_size = list_max; - - selected = 1; - - CDVD_Stop(); - } - - if ((padButtons.mode >> 4) == 0x07) { - // Analogue file selection - float pad_v; - - pad_v = (float)(padButtons.ljoy_v - 128); // Range = +127 to -128 - - - if (pad_v > 32) { - // scrolling down, so incrementing selected tom - pad_v -= 32; - selected += (pad_v / 96); - } - - if (pad_v < -32) { - // scrolling down, so incrementing selected tom - pad_v += 32; - selected += (pad_v / 96); - } - } - - - - if (selected < 1) - selected = 1; - - if ((int)selected > num_files) - selected = (float)num_files; - } - - // calculate which file to display first in the list - if ((int)selected <= list_size / 2) - first_file = 1; - else { - if ((int)selected >= (num_files - (list_size / 2) + 1)) - first_file = num_files - list_size + 1; - else - first_file = (int)selected - ((list_size / 2)); - } - - // calculate the offset of the selected file into the displayed list - offset = (int)selected - first_file; - - - ClearScreen(); - - if (num_files > 0) { - // pDisplay->drawPipe.setScissorRect(list_xpos,list_ypos,list_xpos+list_width,list_ypos+list_height); - - for (int file = 0; file < list_size; file++) { - // if the entry is a dir, then display the directory symbol before the name - if (TocEntryList[first_file + file - 1].fileProperties & 0x02) { - // display a dir symbol (character 001 in the bitmap font) - myFont.Print(128, 640, filelisty + (file * 18), 4, GS_SET_RGBA(0x80, 0x80, 0x80, 0x80), GSFONT_ALIGN_LEFT, "\001"); - - if (file == ((int)selected - first_file)) { - myFont.Print(148, 640, filelisty + (file * 18), 4, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, - TocEntryList[first_file + file - 1].filename); - } else { - myFont.Print(148, 640, filelisty + (file * 18), 4, TEXT_COL_DIM, GSFONT_ALIGN_LEFT, - TocEntryList[first_file + file - 1].filename); - } - } else { - if (file == ((int)selected - first_file)) { - myFont.Print(128, 640, filelisty + (file * 18), 4, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, - TocEntryList[first_file + file - 1].filename); - } else { - myFont.Print(128, 640, filelisty + (file * 18), 4, TEXT_COL_DIM, GSFONT_ALIGN_LEFT, - TocEntryList[first_file + file - 1].filename); - } - } - } - - myFont.Print(420, 640, 440, 0, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, - "Press X to Select"); - - myFont.Print(420, 640, 458, 0, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, - "Press SELECT to Change CD"); - } - - - pDisplay->drawPipe.Flush(); - - // Wait for VSync and then swap buffers - pDisplay->WaitForVSync(); - - pDisplay->swapBuffers(); - } - - // We've selected something, but is it a file or a dir ? - if (TocEntryList[((int)selected) - 1].fileProperties & 0x02) { - // Append name onto current path - //gui_getfile_dispname((int)selected, tempname); - strcat(pathname, "/"); - strcat(pathname, TocEntryList[((int)selected) - 1].filename); - - // file list will be got next time round the while loop - - // Start from top of list - selected = 1; - } else { - // It's not a dir, so it must be a file - break; - } - } - - char size_string[64]; - - if (TocEntryList[((int)selected) - 1].fileSize < (2 * 1024)) - sprintf(size_string, "%d bytes", TocEntryList[((int)selected) - 1].fileSize); - else { - if (TocEntryList[((int)selected) - 1].fileSize < (2 * 1024 * 1024)) - sprintf(size_string, "%d Kb", TocEntryList[((int)selected) - 1].fileSize / 1024); - else - sprintf(size_string, "%d Mb", TocEntryList[((int)selected) - 1].fileSize / (1024 * 1024)); - } - - - for (int frame = 0; frame < 200; frame++) { - - // Selected a file, so display file properties for a couple of seconds - ClearScreen(); - - myFont.Print(100, 200, 220, 1, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, - "File name:"); - - myFont.Print(200, 640, 220, 1, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, - TocEntryList[((int)selected) - 1].filename); - - myFont.Print(100, 200, 240, 1, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, - "File path:"); - - myFont.Print(200, 640, 240, 1, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, - pathname); - - - myFont.Print(100, 200, 260, 1, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, - "File size:"); - - myFont.Print(200, 640, 260, 1, TEXT_COL_BRIGHT, GSFONT_ALIGN_LEFT, - size_string); - - pDisplay->drawPipe.Flush(); - - // Wait for VSync and then swap buffers - pDisplay->WaitForVSync(); - - pDisplay->swapBuffers(); - } - } - - free(fontTex); - - free(TocEntryList); - - delete pDisplay; - - return 0; -} - - -int WaitPadReady(int port, int slot) -{ - int state = 0; - - while ((state != PAD_STATE_STABLE) && - (state != PAD_STATE_FINDCTP1)) { - state = padGetState(port, slot); - - if (state == PAD_STATE_DISCONN) - break; // If no pad connected then dont wait for it to be plugged in - - //pEmuDisplay->WaitForVSync(); - } - - return state; -} - - -void SetPadMode(int port, int slot) -{ - // If the controller is already plugged in then - // put the controller into Analogue mode (and lock it) - // so that analogue stick can be used - - if (WaitPadReady(port, slot) == PAD_STATE_STABLE) // if pad is connected then initialise it - { - padSetMainMode(port, slot, PAD_MMODE_DUALSHOCK, PAD_MMODE_LOCK); - - WaitPadReady(port, slot); - } -} diff --git a/ps2/libcdvd/example/font.fnt b/ps2/libcdvd/example/font.fnt deleted file mode 100644 index 8d747f8826b8bbd53abce54e6b20440158b5ad19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 262432 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 aoK@`JN9?qAdG_Jm$IQG+#|n1J{{I0UHI(K6 diff --git a/ps2/libcdvd/iop/cdvd_iop.c b/ps2/libcdvd/iop/cdvd_iop.c index 3e82b57267..6fd3b8dd6c 100644 --- a/ps2/libcdvd/iop/cdvd_iop.c +++ b/ps2/libcdvd/iop/cdvd_iop.c @@ -1574,7 +1574,7 @@ void *CDVDRpc_TrayReq(unsigned int *sbuff) { int ret; - sceCdTrayReq(sbuff[0], (s32 *)&ret); + sceCdTrayReq(sbuff[0], (int *)&ret); sbuff[0] = ret; return sbuff; From 88ea33bbd20a9cf546bb4c6a2c2a62df9ec735d1 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 16 Mar 2019 03:48:48 +0100 Subject: [PATCH 034/237] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index cfc54b0139..299cad7b2d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -66,6 +66,7 @@ - OSX: Prevent crash on exit. - OSX: Metal is now the default video driver. - OSX: Enable CoreAudio v3 driver for Metal. +- PS2: CDFS support. - PS2: Implemented analog support for ps2 controllers. - PS2: Fix audio freeze after restarting core. - PS2: Fix issues with load state and the font driver. From b1846ee44936de073d2b87faa6685fcf125aa277 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Sat, 16 Mar 2019 15:32:11 +0100 Subject: [PATCH 035/237] [PS2] CDFS Improvements --- frontend/drivers/platform_ps2.c | 7 +- ps2/compat_files/fileXio_cdvd.c | 239 ++++++++++-------------------- ps2/compat_files/ps2_descriptor.c | 3 +- ps2/include/ps2_descriptor.h | 6 +- 4 files changed, 86 insertions(+), 169 deletions(-) diff --git a/frontend/drivers/platform_ps2.c b/frontend/drivers/platform_ps2.c index d28986d4d8..fc07094e28 100644 --- a/frontend/drivers/platform_ps2.c +++ b/frontend/drivers/platform_ps2.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -208,12 +209,11 @@ static void frontend_ps2_init(void *data) } /* Initializes CDVD library */ + /* SCECdINoD init without check for a disc. Reduces risk of a lockup if the drive is in a erroneous state. */ + sceCdInit(SCECdINoD); if (CDVD_Init() != 1) { RARCH_ERR("CDVD_Init library not initalizated\n"); } - if (cdInit(CDVD_INIT_INIT) != 1) { - RARCH_ERR("cdInit library not initalizated\n"); - } _init_ps2_io(); @@ -236,7 +236,6 @@ static void frontend_ps2_deinit(void *data) command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL); #endif _free_ps2_io(); - cdInit(CDVD_INIT_EXIT); CDVD_Stop(); padEnd(); audsrv_quit(); diff --git a/ps2/compat_files/fileXio_cdvd.c b/ps2/compat_files/fileXio_cdvd.c index 09074c7094..5c61840568 100644 --- a/ps2/compat_files/fileXio_cdvd.c +++ b/ps2/compat_files/fileXio_cdvd.c @@ -2,168 +2,79 @@ #include #include #include +#include #include #include #include #include +#include #include "ps2_devices.h" #include "ps2_descriptor.h" -#define CD_SERVER_INIT 0x80000592 -#define CD_SERVER_SCMD 0x80000593 -#define CD_SCMD_GETDISCTYPE 0x03 - +/* I dont know why but this line is totally needed */ static SifRpcClientData_t clientInit __attribute__ ((aligned(64))); -static u32 initMode __attribute__ ((aligned(64))); -static int cdThreadId = 0; -static int bindSearchFile = -1; -static int bindDiskReady = -1; -static int bindInit = -1; -static int bindNCmd = -1; -static int bindSCmd = -1; -static int nCmdSemaId = -1; // n-cmd semaphore id -static int sCmdSemaId = -1; // s-cmd semaphore id -static int callbackSemaId = -1; // callback semaphore id -static int cdDebug = 0; -static int sCmdNum = 0; -static SifRpcClientData_t clientSCmd __attribute__ ((aligned(64))); -static u8 sCmdRecvBuff[48] __attribute__ ((aligned(64))); -static volatile int cbSema = 0; -static ee_thread_status_t cdThreadParam; -static int callbackThreadId = 0; -volatile int cdCallbackNum __attribute__ ((aligned(64))); - -static void cdSemaInit(void); -static int cdCheckSCmd(int cur_cmd); -static int cdSyncS(int mode); -static void cdSemaExit(void); - -static int first_file_index; - -int cdInit(int mode) -{ - int i; - - if (cdSyncS(1)) - return 0; - SifInitRpc(0); - cdThreadId = GetThreadId(); - bindSearchFile = -1; - bindNCmd = -1; - bindSCmd = -1; - bindDiskReady = -1; - bindInit = -1; - - while (1) { - if (SifBindRpc(&clientInit, CD_SERVER_INIT, 0) >= 0) - if (clientInit.server != 0) break; - i = 0x10000; - while (i--); - } - - bindInit = 0; - initMode = mode; - SifWriteBackDCache(&initMode, 4); - if (SifCallRpc(&clientInit, 0, 0, &initMode, 4, 0, 0, 0, 0) < 0) - return 0; - if (mode == CDVD_INIT_EXIT) { - cdSemaExit(); - nCmdSemaId = -1; - sCmdSemaId = -1; - callbackSemaId = -1; - } else { - cdSemaInit(); - } - return 1; -} - -static void cdSemaExit(void) -{ - if (callbackThreadId) { - cdCallbackNum = -1; - SignalSema(callbackSemaId); - } - DeleteSema(nCmdSemaId); - DeleteSema(sCmdSemaId); - DeleteSema(callbackSemaId); -} - -static void cdSemaInit(void) -{ - struct t_ee_sema semaParam; - - // return if both semaphores are already inited - if (nCmdSemaId != -1 && sCmdSemaId != -1) - return; - - semaParam.init_count = 1; - semaParam.max_count = 1; - semaParam.option = 0; - nCmdSemaId = CreateSema(&semaParam); - sCmdSemaId = CreateSema(&semaParam); - - semaParam.init_count = 0; - callbackSemaId = CreateSema(&semaParam); - - cbSema = 0; -} - -static int cdCheckSCmd(int cur_cmd) -{ - int i; - cdSemaInit(); - if (PollSema(sCmdSemaId) != sCmdSemaId) { - if (cdDebug > 0) - printf("Scmd fail sema cur_cmd:%d keep_cmd:%d\n", cur_cmd, sCmdNum); - return 0; - } - sCmdNum = cur_cmd; - ReferThreadStatus(cdThreadId, &cdThreadParam); - if (cdSyncS(1)) { - SignalSema(sCmdSemaId); - return 0; - } - - SifInitRpc(0); - if (bindSCmd >= 0) - return 1; - while (1) { - if (SifBindRpc(&clientSCmd, CD_SERVER_SCMD, 0) < 0) { - if (cdDebug > 0) - printf("Libcdvd bind err S cmd\n"); - } - if (clientSCmd.server != 0) - break; - - i = 0x10000; - while (i--) - ; - } - - bindSCmd = 0; - return 1; -} - -static int cdSyncS(int mode) -{ - if (mode == 0) { - if (cdDebug > 0) - printf("S cmd wait\n"); - while (SifCheckStatRpc(&clientSCmd)) - ; - return 0; - } - return SifCheckStatRpc(&clientSCmd); -} static int comp_entries_by_filename(const void *elem1, const void *elem2) { - return strcmp(((entries*)elem1)->filename, ((entries*)elem2)->filename); + return strcmp(((entries*)elem1)->filename, ((entries*)elem2)->filename); } -static inline char* strzncpy(char *d, const char *s, size_t l) -{ - d[0] = 0; return strncat(d, s, l); +static int ps2_cdDiscValid(void) //returns 1 if disc valid, else returns 0 +{ + int cdmode = sceCdGetDiskType(); + + switch (cdmode) { + case SCECdPSCD: + case SCECdPSCDDA: + case SCECdPS2CD: + case SCECdPS2CDDA: + case SCECdPS2DVD: + case SCECdCDDA: + case SCECdDVDV: + return 1; + case SCECdNODISC: + case SCECdDETCT: + case SCECdDETCTCD: + case SCECdDETCTDVDS: + case SCECdDETCTDVDD: + case SCECdUNKNOWN: + case SCECdIllegalMedia: + default: + return 0; + } +} + +static u64 cd_Timer(void) +{ + return (clock() / (CLOCKS_PER_SEC / 1000)); +} + +static void ps2_cdStop(void) +{ + CDVD_Stop(); + sceCdSync(0); +} + +static int prepareCDVD(void) +{ + u64 wait_start; + int cdmode = sceCdGetDiskType(); + + if (sceCdGetDiskType() <= SCECdUNKNOWN) { + wait_start = cd_Timer(); + while ((cd_Timer() < wait_start + 500) && !ps2_cdDiscValid()) { + if (cdmode == SCECdNODISC) + return 0; + } + if (cdmode == SCECdNODISC) + return 0; + if ((cdmode < SCECdPSCD) || (cdmode > SCECdPS2DVD)) { + ps2_cdStop(); + return 0; + } + } + + return 1; } static int listcdvd(const char *path, entries *FileEntry) @@ -172,6 +83,7 @@ static int listcdvd(const char *path, entries *FileEntry) char dir[1025]; int i, n; int t = 0; + int first_file_index; strcpy(dir, &path[5]); // Directories first... @@ -187,7 +99,6 @@ static int listcdvd(const char *path, entries *FileEntry) FileEntry[t].dircheck = 1; strcpy(FileEntry[t].filename, TocEntryList[i].filename); - strzncpy(FileEntry[t].displayname, FileEntry[t].filename, 63); t++; if (t >= FILEENTRY_SIZE - 2) { @@ -211,7 +122,6 @@ static int listcdvd(const char *path, entries *FileEntry) FileEntry[t].dircheck = 0; strcpy(FileEntry[t].filename, TocEntryList[i].filename); - strzncpy(FileEntry[t].displayname, FileEntry[t].filename, 63); t++; if (t >= FILEENTRY_SIZE - 2) { @@ -227,15 +137,13 @@ static int listcdvd(const char *path, entries *FileEntry) static int fileXioCDDread(int fd, iox_dirent_t *dirent) { DescriptorTranslation *descriptor = __ps2_fd_grab(fd); - if (descriptor->current_folder_position == -1) { - descriptor->current_folder_position = 0; - descriptor->items = listcdvd(descriptor->path, descriptor->FileEntry); - } - if (descriptor->current_folder_position < descriptor->items) { + if (descriptor && descriptor->current_folder_position < descriptor->items) { strcpy(dirent->name, descriptor->FileEntry[descriptor->current_folder_position].filename); if (descriptor->FileEntry[descriptor->current_folder_position].dircheck) { dirent->stat.mode = FIO_S_IFDIR; + } else { + dirent->stat.mode = FIO_S_IFREG; } descriptor->current_folder_position++; } else { @@ -246,14 +154,25 @@ static int fileXioCDDread(int fd, iox_dirent_t *dirent) return 1; } +static int fileXioCDDopen(const char *name) +{ + int fd = -1; + if (prepareCDVD()){ + fd = __ps2_acquire_descriptor(); + DescriptorTranslation *descriptor = __ps2_fd_grab(fd); + descriptor->current_folder_position = 0; + descriptor->items = listcdvd(name, descriptor->FileEntry); + } + return fd; +} + + int ps2fileXioDopen(const char *name) { enum BootDeviceIDs deviceID = getBootDeviceID((char *)name); - int fd; + int fd = -1; if (deviceID == BOOT_DEVICE_CDFS) { - fd = __ps2_acquire_descriptor(); - DescriptorTranslation *descriptor = __ps2_fd_grab(fd); - strcpy(descriptor->path, name); + fd = fileXioCDDopen(name); } else { fd = fileXioDopen(name); } diff --git a/ps2/compat_files/ps2_descriptor.c b/ps2/compat_files/ps2_descriptor.c index 6af1106aac..c46be16c9b 100644 --- a/ps2/compat_files/ps2_descriptor.c +++ b/ps2/compat_files/ps2_descriptor.c @@ -40,6 +40,7 @@ static int __ps2_fd_drop(DescriptorTranslation *map) if (map->ref_count == 1) { map->ref_count--; + map->current_folder_position = -1; free(map->FileEntry); memset(map, 0, sizeof(DescriptorTranslation)); } @@ -57,7 +58,7 @@ int is_fd_valid(int fd) /* Correct fd value */ fd = MAX_OPEN_FILES - fd; - return (fd > 0) && (fd < MAX_OPEN_FILES) && (__ps2_fdmap[fd] != NULL); + return (fd >= 0) && (fd < MAX_OPEN_FILES) && (__ps2_fdmap[fd] != NULL); } void _init_ps2_io(void) { diff --git a/ps2/include/ps2_descriptor.h b/ps2/include/ps2_descriptor.h index 1d9e84c3a8..f0e17cc53f 100644 --- a/ps2/include/ps2_descriptor.h +++ b/ps2/include/ps2_descriptor.h @@ -22,14 +22,12 @@ #define FILEENTRY_SIZE 2048 typedef struct { - char displayname[64]; - int dircheck; - char filename[256]; + int dircheck; + char filename[256]; } entries; typedef struct { - char path[256]; int ref_count; int items; int current_folder_position; From 45069537fba01a8da6bdd86a7b0766d4ee1024ee Mon Sep 17 00:00:00 2001 From: Huw Pascoe Date: Sun, 17 Mar 2019 03:04:35 +0000 Subject: [PATCH 036/237] Re-enable RXML and purge libxml Fixed rxml to work with griffin.c --- .gitignore | 1 - Makefile.common | 8 +------ Makefile.win | 6 ----- README-mali_fbdev_r4p0.md | 2 +- README.md | 1 - config.features.h | 6 ----- griffin/griffin.c | 5 ---- intl/msg_hash_ar.h | 2 -- intl/msg_hash_chs.h | 2 -- intl/msg_hash_cht.h | 2 -- intl/msg_hash_de.h | 2 -- intl/msg_hash_el.h | 4 ---- intl/msg_hash_eo.h | 2 -- intl/msg_hash_es.h | 4 ---- intl/msg_hash_fr.h | 2 -- intl/msg_hash_it.h | 2 -- intl/msg_hash_ja.h | 2 -- intl/msg_hash_ko.h | 2 -- intl/msg_hash_nl.h | 2 -- intl/msg_hash_pl.h | 2 -- intl/msg_hash_pt_br.h | 4 ---- intl/msg_hash_pt_pt.h | 2 -- intl/msg_hash_ru.h | 2 -- intl/msg_hash_us.h | 4 ---- intl/msg_hash_vn.h | 2 -- libretro-common/formats/xml/rxml.c | 8 +++---- libretro-common/include/formats/rxml.h | 30 +----------------------- menu/menu_displaylist.c | 9 ------- msg_hash.h | 1 - pkg/debian/control | 1 - pkg/sailfishos/retroarch-sailfishos.spec | 1 - qb/config.libs.sh | 2 -- qb/config.params.sh | 1 - retroarch.c | 2 -- 34 files changed, 7 insertions(+), 121 deletions(-) diff --git a/.gitignore b/.gitignore index caa622d541..89245c82ea 100644 --- a/.gitignore +++ b/.gitignore @@ -62,7 +62,6 @@ apple/RetroArch_iOS.xcodeproj/project.xcworkspace/* /freetype2/ /ft2build.h /iconv.h -/libxml2/ /phoenix/ /python/ /rsound.h diff --git a/Makefile.common b/Makefile.common index f6adc1ae13..1923f238a9 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1474,13 +1474,6 @@ ifeq ($(WANT_WGL), 1) LIBS += -lcomctl32 endif -#ifeq ($(HAVE_LIBXML2), 1) - #LIBS += $(LIBXML2_LIBS) - #DEFINES += $(LIBXML2_CFLAGS) -#else - #OBJ += $(LIBRETRO_COMM_DIR)/formats/xml/rxml.o -#endif - # Compression/Archive OBJ += $(LIBRETRO_COMM_DIR)/file/archive_file.o \ @@ -1617,6 +1610,7 @@ endif OBJ += $(LIBRETRO_COMM_DIR)/formats/bmp/rbmp_encode.o \ $(LIBRETRO_COMM_DIR)/formats/json/jsonsax.o \ $(LIBRETRO_COMM_DIR)/formats/json/jsonsax_full.o \ + $(LIBRETRO_COMM_DIR)/formats/xml/rxml.o \ $(LIBRETRO_COMM_DIR)/formats/image_transfer.o ifdef HAVE_COMPRESSION diff --git a/Makefile.win b/Makefile.win index bdab1a775b..7614b080fa 100644 --- a/Makefile.win +++ b/Makefile.win @@ -32,7 +32,6 @@ HAVE_FREETYPE := 1 HAVE_FFMPEG := 0 HAVE_CG := 1 -HAVE_LIBXML2 := 0 HAVE_ZLIB := 1 WANT_ZLIB := 1 HAVE_CC_RESAMPLER := 1 @@ -46,11 +45,6 @@ FREETYPE_CFLAGS := -DHAVE_FREETYPE -Ifreetype2 FREETYPE_LIBS := -lfreetype endif -ifeq ($(HAVE_LIBXML2), 1) -LIBXML2_CFLAGS := -Ilibxml2 -DHAVE_LIBXML2 -DHAVE_GLSL -LIBXML2_LIBS := -lxml2 -liconv -endif - ifeq ($(HAVE_SDL), 1) SDL_LIBS := -lSDL SDL_CFLAGS := -ISDL -DHAVE_SDL diff --git a/README-mali_fbdev_r4p0.md b/README-mali_fbdev_r4p0.md index 4449795d49..c004efdbaa 100644 --- a/README-mali_fbdev_r4p0.md +++ b/README-mali_fbdev_r4p0.md @@ -80,7 +80,7 @@ To enable mali_fbdev you must configure RetroArch with --enable-gles and --enabl This is an example of what you would use on a CubieBoard2 for a lightweight RetroArch: -./configure --enable-gles --enable-mali_fbdev --disable-x11 --disable-sdl2 --enable-floathard --disable-ffmpeg --disable-netplay --enable-udev --disable-sdl --disable-pulse --disable-oss --disable-freetype --disable-7zip --disable-libxml2 +./configure --enable-gles --enable-mali_fbdev --disable-x11 --disable-sdl2 --enable-floathard --disable-ffmpeg --disable-netplay --enable-udev --disable-sdl --disable-pulse --disable-oss --disable-freetype --disable-7zip NOTE: A TTY hack is used to auto-clean the console on exit, and the fbdev ioctls are used to retrieve current video mode. Both things work good, but they are not exactly ideal solutions. diff --git a/README.md b/README.md index c9f7b7b4b8..ff828e3d93 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,6 @@ OSX port of RetroArch requires latest versions of XCode to build. RetroArch can utilize these libraries if enabled: - nvidia-cg-toolkit - - libxml2 (GLSL XML shaders) - libfreetype2 (TTF font rendering on screen) RetroArch needs at least one of these audio driver libraries: diff --git a/config.features.h b/config.features.h index cc50979ef0..0dcba0dfcf 100644 --- a/config.features.h +++ b/config.features.h @@ -260,12 +260,6 @@ static const bool _hlsl_supp = true; static const bool _hlsl_supp = false; #endif -#ifdef HAVE_LIBXML2 -static const bool _libxml2_supp = true; -#else -static const bool _libxml2_supp = false; -#endif - #ifdef HAVE_SDL_IMAGE static const bool _sdl_image_supp = true; #else diff --git a/griffin/griffin.c b/griffin/griffin.c index c05b7a2dba..271878cdd6 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -1439,12 +1439,7 @@ DEPENDENCIES /*============================================================ XML ============================================================ */ -#if 0 -#ifndef HAVE_LIBXML2 -#define RXML_LIBXML2_COMPAT 1 #include "../libretro-common/formats/xml/rxml.c" -#endif -#endif /*============================================================ AUDIO UTILS diff --git a/intl/msg_hash_ar.h b/intl/msg_hash_ar.h index 4261ff67ba..52cf18f812 100644 --- a/intl/msg_hash_ar.h +++ b/intl/msg_hash_ar.h @@ -1553,8 +1553,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "LibretroDB support") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Libusb support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "libxml2 XML parsing support") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Netplay (peer-to-peer) support") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index 18cdfc12db..1a68a5158d 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -1579,8 +1579,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "LibretroDB 支持") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Libusb 支持") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "libxml2 XML解析支持") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Netplay (点对点) 支持") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index 7661b5aa54..d263c9b501 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -1431,8 +1431,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "LibretroDB 支持") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Libusb 支持") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "libxml2 XML解析支持") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Netplay (點對點) 支持") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 1be3956bfc..17db8d4b06 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -1500,8 +1500,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "LibretroDB-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Libusb-Unterstützung") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "Libxml2-XML-Parsing-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Netplay-Unterstützung (Peer-to-Peer)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_el.h b/intl/msg_hash_el.h index 9fd13ec7a7..8ee4f4409b 100644 --- a/intl/msg_hash_el.h +++ b/intl/msg_hash_el.h @@ -2670,10 +2670,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Υποστήριξη Libusb" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "Υποστήριξη ανάλυσης libxml2 XML" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Υποστήριξη Netplay (peer-to-peer)" diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index b67e4a6245..26f889c6be 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -1341,8 +1341,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "LibretroDB support") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Libusb support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "libxml2 XML parsing support") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Netplay (peer-to-peer) support") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index bbfe18ff73..dc0a7fd555 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -2738,10 +2738,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Soporte de Libusb" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "Soporte de parseo XML libxml2" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Soporte de juego en red (peer-to-peer)" diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 1fe39d6a1f..5d2b7a0ada 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -1456,8 +1456,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "Support de LibretroDB") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Support de Libusb") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "Support du parser XML libxml2") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Support du jeu en réseau (peer-to-peer)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index 99fa7614cc..c6a068d046 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -1474,8 +1474,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "Supporto LibretroDB ") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Supporto Libusb ") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "Supporto libxml2 XML parsing ") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Supporto Netplay (peer-to-peer) ") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index 5df46be382..71797b13ee 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -1640,8 +1640,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "LibretroDB対応") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Libusb対応") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "libxml2 XMLパース対応") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "ネットプレイ(ピアツーピア)対応") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index bfec9bae41..57a12537ff 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -1428,8 +1428,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "LibretroDB 지원") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Libusb 지원") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "libxml2 XML 파싱 지원") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "넷플레이 (P2P) 지원") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index b7eb9ad1c8..04882dbf40 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -1343,8 +1343,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "LibretroDB ondersteuning") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Libusb ondersteuning") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "libxml2 XML parsing ondersteuning") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Netplay (peer-to-peer) ondersteuning") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index 510ba2a690..a6c7d7405e 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -1568,8 +1568,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "Obsługa LibretroDB") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Wsparcie Libusb") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "Libxml2 obsługa parowania XML") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Wsparcie Gry online (peer-to-peer)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index 19f22420c0..e7ff535699 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -2742,10 +2742,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Suporte a Libusb" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "Suporte a libxml2 XML parsing" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Suporte de jogo em rede (ponto-a-ponto)" diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h index 4101c40ea8..fe3270ce50 100644 --- a/intl/msg_hash_pt_pt.h +++ b/intl/msg_hash_pt_pt.h @@ -1420,8 +1420,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "Suporte de LibretroDB") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Suporte de Libusb") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "Suporte de análise de libxml2 XML") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Suporte de Netplay (ponto-a-ponto)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index 2d7cef985b..589c08e3bb 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -1455,8 +1455,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "Поддержка LibretroDB") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Поддержка Libusb") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "Поддержка синтаксического анализа libxml2 XML") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Поддержка Netplay (peer-to-peer)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 7bb269143e..1d1d541390 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -2778,10 +2778,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Libusb support" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "libxml2 XML parsing support" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Netplay (peer-to-peer) support" diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h index 6c802afa81..1b43b88163 100644 --- a/intl/msg_hash_vn.h +++ b/intl/msg_hash_vn.h @@ -1449,8 +1449,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, "LibretroDB support") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, "Libusb support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "libxml2 XML parsing support") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Netplay (peer-to-peer) support") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, diff --git a/libretro-common/formats/xml/rxml.c b/libretro-common/formats/xml/rxml.c index 482b75b004..7701d7c98b 100644 --- a/libretro-common/formats/xml/rxml.c +++ b/libretro-common/formats/xml/rxml.c @@ -116,7 +116,7 @@ static bool range_is_space(const char *begin, const char *end) return true; } -static void skip_spaces(const char **ptr_) +static void rxml_skip_spaces(const char **ptr_) { const char *ptr = *ptr_; while (isspace(*ptr)) @@ -218,7 +218,7 @@ static char *find_first_space(const char *str) static bool rxml_parse_tag(struct rxml_node *node, const char *str) { const char *str_ptr = str; - skip_spaces(&str_ptr); + rxml_skip_spaces(&str_ptr); const char *name_end = find_first_space(str_ptr); if (name_end) @@ -248,7 +248,7 @@ static struct rxml_node *rxml_parse_node(const char **ptr_) if (!node) return NULL; - skip_spaces(ptr_); + rxml_skip_spaces(ptr_); ptr = *ptr_; if (*ptr != '<') @@ -474,7 +474,7 @@ void rxml_free_document(rxml_document_t *doc) free(doc); } -char *rxml_node_attrib(struct rxml_node *node, const char *attrib) +const char *rxml_node_attrib(struct rxml_node *node, const char *attrib) { struct rxml_attrib_node *attribs = NULL; for (attribs = node->attrib; attribs; attribs = attribs->next) diff --git a/libretro-common/include/formats/rxml.h b/libretro-common/include/formats/rxml.h index 21adc347e0..200a27917b 100644 --- a/libretro-common/include/formats/rxml.h +++ b/libretro-common/include/formats/rxml.h @@ -54,10 +54,6 @@ struct rxml_node struct rxml_node *children; struct rxml_node *next; - - /* Dummy. Used by libxml2 compat. - * Is always set to 0, so XML_ELEMENT_NODE check goes through. */ - int type; }; rxml_document_t *rxml_load_document(const char *path); @@ -65,30 +61,6 @@ void rxml_free_document(rxml_document_t *doc); struct rxml_node *rxml_root_node(rxml_document_t *doc); -/* Drop const-correctness here to avoid warnings - * when used as libxml2 compat. - * xmlGetProp() returns xmlChar*, which is supposed - * to be passed to xmlFree(). */ -char *rxml_node_attrib(struct rxml_node *node, const char *attrib); - -#ifdef RXML_LIBXML2_COMPAT -/* Compat for part of libxml2 that RetroArch uses. */ -#define LIBXML_TEST_VERSION ((void)0) -typedef char xmlChar; /* It's really unsigned char, but it doesn't matter. */ -typedef struct rxml_node *xmlNodePtr; -typedef void *xmlParserCtxtPtr; -typedef rxml_document_t *xmlDocPtr; -#define XML_ELEMENT_NODE (0) -#define xmlNewParserCtxt() ((void*)-1) -#define xmlCtxtReadFile(ctx, path, a, b) rxml_load_document(path) -#define xmlGetProp(node, prop) rxml_node_attrib(node, prop) -#define xmlFree(p) ((void)0) -#define xmlNodeGetContent(node) (node->data) -#define xmlDocGetRootElement(doc) rxml_root_node(doc) -#define xmlFreeDoc(doc) rxml_free_document(doc) -#define xmlFreeParserCtxt(ctx) ((void)0) -#endif - -RETRO_END_DECLS +const char *rxml_node_attrib(struct rxml_node *node, const char *attrib); #endif diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index abd882be63..ceed148af6 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -1172,15 +1172,6 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info) menu_entries_append_enum(info->list, feat_str, "", MENU_ENUM_LABEL_SYSTEM_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0); - snprintf(feat_str, sizeof(feat_str), - "%s: %s", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT), - _libxml2_supp ? - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_YES) : - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO)); - menu_entries_append_enum(info->list, feat_str, "", - MENU_ENUM_LABEL_SYSTEM_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0); - snprintf(feat_str, sizeof(feat_str), "%s: %s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_IMAGE_SUPPORT), diff --git a/msg_hash.h b/msg_hash.h index 25e7b53a64..ada9feaf93 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1876,7 +1876,6 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GLSL_SUPPORT, MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SLANG_SUPPORT, MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_HLSL_SUPPORT, - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_IMAGE_SUPPORT, MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FBO_SUPPORT, MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FFMPEG_SUPPORT, diff --git a/pkg/debian/control b/pkg/debian/control index 184f262979..775036e6eb 100644 --- a/pkg/debian/control +++ b/pkg/debian/control @@ -8,7 +8,6 @@ Build-Depends: debhelper (>= 9), libc6-dev (>= 2.13), libpulse-dev, libsdl2-dev, - libxml2-dev, libavcodec-dev, libavdevice-dev, libavformat-dev, diff --git a/pkg/sailfishos/retroarch-sailfishos.spec b/pkg/sailfishos/retroarch-sailfishos.spec index 29de5dfc93..5ca85a1571 100644 --- a/pkg/sailfishos/retroarch-sailfishos.spec +++ b/pkg/sailfishos/retroarch-sailfishos.spec @@ -7,7 +7,6 @@ Group: Applications/Emulators License: GPLv3+ URL: http://www.libretro.com/ -BuildRequires: libxml2-devel BuildRequires: mesa-llvmpipe-libwayland-egl-devel BuildRequires: pulseaudio-devel BuildRequires: OpenAL-devel diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 56090cb6b7..7b189c1e15 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -405,8 +405,6 @@ if [ "$HAVE_KMS" != "no" ]; then fi fi -check_val '' LIBXML2 -lxml2 libxml2 libxml-2.0 '' '' false - if [ "$HAVE_EGL" = "yes" ]; then if [ "$HAVE_OPENGLES" != "no" ]; then if [ "$OPENGLES_LIBS" ] || [ "$OPENGLES_CFLAGS" ]; then diff --git a/qb/config.params.sh b/qb/config.params.sh index 69e3bc1faa..8bb4d964f1 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -80,7 +80,6 @@ HAVE_EGL=auto # EGL context support HAVE_VG=auto # OpenVG support HAVE_CG=auto # Cg shader support HAVE_HLSL=no # HLSL9 shader support (for Direct3D9) -HAVE_LIBXML2=auto # libxml2 support HAVE_BUILTINZLIB=no # Bake in zlib HAVE_ZLIB=auto # zlib support (ZIP extract, PNG decoding/encoding) HAVE_ALSA=auto # ALSA support diff --git a/retroarch.c b/retroarch.c index e7afc9bfff..f964a18d82 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1024,8 +1024,6 @@ static void retroarch_print_features(void) _PSUPP(glsl, "GLSL", "Fragment/vertex shader driver"); _PSUPP(glsl, "HLSL", "Fragment/vertex shader driver"); - _PSUPP(libxml2, "libxml2", "libxml2 XML parsing"); - _PSUPP(sdl_image, "SDL_image", "SDL_image image loading"); _PSUPP(rpng, "rpng", "PNG image loading/encoding"); _PSUPP(rpng, "rjpeg", "JPEG image loading"); From 69087727e9e2b513f915096520c895e036f36262 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Sun, 17 Mar 2019 13:31:56 +0100 Subject: [PATCH 037/237] fix issues executing makefile in a bash script --- ps2/irx/Makefile | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/ps2/irx/Makefile b/ps2/irx/Makefile index 0328ccc8c1..ce28efa15b 100644 --- a/ps2/irx/Makefile +++ b/ps2/irx/Makefile @@ -9,19 +9,20 @@ LIBCDVD_IRX_DIR = $(LIBCDVD_DIR)/lib #IRX modules # IRX modules - modules have to be in IRX_DIR IRX_FILES += freemtap.irx freepad.irx freesio2.irx iomanX.irx fileXio.irx mcman.irx mcserv.irx usbd.irx usbhdfsd.irx -IRX_FILES += freesd.irx audsrv.irx poweroff.irx cdvd.irx -IRX_C_FILES = $(IRX_FILES:.irx=_irx.c) +IRX_FILES += freesd.irx audsrv.irx poweroff.irx +IRX_C_FILES = $(IRX_FILES:.irx=_irx.c) cdvd_irx.c + +all: cdvd irxs # Specific file name and output per IRX Module %.irx: - if [[ "$(@)" == "cdvd.irx" ]]; then \ - $(MAKE) -C $(LIBCDVD_DIR); \ - $(EE_BIN2C) $(LIBCDVD_IRX_DIR)/$@ $(@:.irx=_irx.c) $(@:.irx=_irx); \ - else \ - $(EE_BIN2C) $(IRX_DIR)/$@ $(@:.irx=_irx.c) $(@:.irx=_irx); \ - fi + $(EE_BIN2C) $(IRX_DIR)/$@ $(@:.irx=_irx.c) $(@:.irx=_irx) -all: $(IRX_FILES) +irxs: $(IRX_FILES) + +cdvd: + $(MAKE) -C $(LIBCDVD_DIR) + $(EE_BIN2C) $(LIBCDVD_IRX_DIR)/$@.irx $@_irx.c $@_irx clean: rm -f $(IRX_C_FILES) From a8a06d498c40a271999effdfbab397fdad942a8b Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sun, 17 Mar 2019 12:45:54 -0400 Subject: [PATCH 038/237] gl1: fix matrix not loading when threaded video is on --- gfx/drivers/gl1.c | 20 +++----------------- gfx/video_driver.c | 20 ++++++++++++++++++++ menu/drivers_display/menu_display_gl1.c | 3 +-- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/gfx/drivers/gl1.c b/gfx/drivers/gl1.c index 309afab44b..2798479e7a 100644 --- a/gfx/drivers/gl1.c +++ b/gfx/drivers/gl1.c @@ -468,7 +468,6 @@ static void draw_tex(gl1_t *gl1, int pot_width, int pot_height, int width, int h glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - /*glLoadMatrixf(gl1->mvp.data);*/ glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -1135,7 +1134,7 @@ static int video_texture_load_wrap_gl1_mipmap(void *data) if (!data) return 0; video_texture_load_gl1((struct texture_image*)data, - TEXTURE_FILTER_MIPMAP_LINEAR, &id); + TEXTURE_FILTER_MIPMAP_NEAREST, &id); return (int)id; } @@ -1146,7 +1145,7 @@ static int video_texture_load_wrap_gl1(void *data) if (!data) return 0; video_texture_load_gl1((struct texture_image*)data, - TEXTURE_FILTER_LINEAR, &id); + TEXTURE_FILTER_NEAREST, &id); return (int)id; } #endif @@ -1249,19 +1248,6 @@ static uint32_t gl1_get_flags(void *data) return flags; } -static void gl1_set_mvp(void *data, void *shader_data, const void *mat_data) -{ - const math_matrix_4x4 *mat = (const math_matrix_4x4*)mat_data; - - (void)data; - (void)shader_data; - - if (!mat) - return; - - glLoadMatrixf(mat->data); -} - static void gl1_set_coords(void *handle_data, void *shader_data, const struct video_coords *coords) { @@ -1279,7 +1265,7 @@ static void gl1_set_coords(void *handle_data, void *shader_data, static const video_poke_interface_t gl1_poke_interface = { gl1_get_flags, gl1_set_coords, - gl1_set_mvp, + NULL, gl1_load_texture, gl1_unload_texture, gl1_set_video_mode, diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 6150b329af..d0fed6987e 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -2703,9 +2703,17 @@ bool video_driver_texture_load(void *data, enum texture_filter_type filter_type, uintptr_t *id) { +#ifdef HAVE_THREADS + bool is_threaded = video_driver_is_threaded_internal(); +#endif if (!id || !video_driver_poke || !video_driver_poke->load_texture) return false; +#ifdef HAVE_THREADS + if (is_threaded) + video_context_driver_make_current(false); +#endif + *id = video_driver_poke->load_texture(video_driver_data, data, video_driver_is_threaded_internal(), filter_type); @@ -2715,9 +2723,17 @@ bool video_driver_texture_load(void *data, bool video_driver_texture_unload(uintptr_t *id) { +#ifdef HAVE_THREADS + bool is_threaded = video_driver_is_threaded_internal(); +#endif if (!video_driver_poke || !video_driver_poke->unload_texture) return false; +#ifdef HAVE_THREADS + if (is_threaded) + video_context_driver_make_current(false); +#endif + video_driver_poke->unload_texture(video_driver_data, *id); *id = 0; return true; @@ -3363,6 +3379,10 @@ enum gfx_ctx_api video_context_driver_get_api(void) return GFX_CTX_GX_API; else if (string_is_equal(video_driver, "gl")) return GFX_CTX_OPENGL_API; + else if (string_is_equal(video_driver, "gl1")) + return GFX_CTX_OPENGL_API; + else if (string_is_equal(video_driver, "glcore")) + return GFX_CTX_OPENGL_API; else if (string_is_equal(video_driver, "vulkan")) return GFX_CTX_VULKAN_API; else if (string_is_equal(video_driver, "metal")) diff --git a/menu/drivers_display/menu_display_gl1.c b/menu/drivers_display/menu_display_gl1.c index 7780ebd0ee..5124931c05 100644 --- a/menu/drivers_display/menu_display_gl1.c +++ b/menu/drivers_display/menu_display_gl1.c @@ -131,8 +131,7 @@ static void menu_display_gl1_draw(menu_display_ctx_draw_t *draw, glMatrixMode(GL_PROJECTION); glPushMatrix(); - - video_driver_set_mvp(&mvp); + glLoadMatrixf(mvp.matrix); glMatrixMode(GL_MODELVIEW); glPushMatrix(); From 8fd0aedc56d1a93d4e9e542f220a70ec8f6c3a61 Mon Sep 17 00:00:00 2001 From: radius Date: Tue, 5 Mar 2019 17:34:05 -0500 Subject: [PATCH 039/237] add log to file settings --- config.def.h | 8 ++++++++ configuration.c | 21 ++++++++++++++++++++- configuration.h | 8 ++++++++ defaults.h | 1 + frontend/drivers/platform_unix.c | 12 ++++++++++++ frontend/drivers/platform_win32.c | 3 ++- intl/msg_hash_us.h | 2 +- pkg/android/phoenix/jni/Android.mk | 1 + retroarch.c | 14 ++++++++++++++ runtime_file.c | 4 ++-- verbosity.c | 17 +++++++++++++---- verbosity.h | 2 ++ 12 files changed, 84 insertions(+), 9 deletions(-) diff --git a/config.def.h b/config.def.h index 563ed9555d..5164432321 100644 --- a/config.def.h +++ b/config.def.h @@ -438,6 +438,12 @@ static bool menu_swap_ok_cancel_buttons = false; static bool quit_press_twice = false; +#if defined(ANDROID) +static bool default_log_to_file = true; +#else +static bool default_log_to_file = false; +#endif + /* Crop overscanned frames. */ static const bool crop_overscan = true; @@ -915,4 +921,6 @@ static char buildbot_assets_server_url[] = "http://buildbot.libretro.com/assets/ static char default_discord_app_id[] = "475456035851599874"; +static char default_log_file[] = "retroarch.log"; + #endif diff --git a/configuration.c b/configuration.c index 8aecd689c3..9c6c0483d5 100644 --- a/configuration.c +++ b/configuration.c @@ -1310,6 +1310,9 @@ static struct config_path_setting *populate_settings_path(settings_t *settings, global->record.config_dir, false, NULL, true); } + SETTING_ARRAY("log_file", settings->paths.log_file, true, default_log_file, true); + SETTING_ARRAY("log_dir", settings->paths.log_dir, true, "", true); + *size = count; return tmp; @@ -1586,12 +1589,16 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("playlist_sort_alphabetical", &settings->bools.playlist_sort_alphabetical, true, playlist_sort_alphabetical, false); SETTING_BOOL("quit_press_twice", &settings->bools.quit_press_twice, true, quit_press_twice, false); +<<<<<<< HEAD SETTING_BOOL("vibrate_on_keypress", &settings->bools.vibrate_on_keypress, true, vibrate_on_keypress, false); SETTING_BOOL("enable_device_vibration", &settings->bools.enable_device_vibration, true, enable_device_vibration, false); #ifdef HAVE_OZONE SETTING_BOOL("ozone_collapse_sidebar", &settings->bools.ozone_collapse_sidebar, true, ozone_collapse_sidebar, false); #endif +======= + SETTING_BOOL("log_to_file", &settings->bools.log_to_file, true, default_log_to_file, false); +>>>>>>> add log to file settings *size = count; @@ -1956,6 +1963,12 @@ void config_set_defaults(void) strlcpy(settings->arrays.discord_app_id, default_discord_app_id, sizeof(settings->arrays.discord_app_id)); + strlcpy(settings->paths.log_file, + default_log_file, sizeof(settings->paths.log_file)); + + strlcpy(settings->paths.log_dir, + g_defaults.dirs[DEFAULT_DIR_LOGS], sizeof(settings->paths.log_dir)); + #ifdef HAVE_MATERIALUI if (g_defaults.menu.materialui.menu_color_theme_enable) settings->uints.menu_materialui_color_theme = g_defaults.menu.materialui.menu_color_theme; @@ -2253,6 +2266,11 @@ void config_set_defaults(void) g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY], sizeof(settings->paths.directory_content_history)); + if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_LOGS])) + strlcpy(settings->paths.log_dir, + g_defaults.dirs[DEFAULT_DIR_LOGS], + sizeof(settings->paths.log_dir)); + if (!string_is_empty(g_defaults.path.config)) { char *temp_str = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); @@ -2832,7 +2850,9 @@ static bool config_load_file(const char *path, bool set_defaults, if (config_get_bool(conf, "log_verbosity", &tmp_bool)) { if (tmp_bool) + { verbosity_enable(); + } else verbosity_disable(); } @@ -3244,7 +3264,6 @@ static bool config_load_file(const char *path, bool set_defaults, recording_driver_update_streaming_url(); ret = true; - end: if (conf) config_file_free(conf); diff --git a/configuration.h b/configuration.h index f1ea2f6b3b..94c757f536 100644 --- a/configuration.h +++ b/configuration.h @@ -315,11 +315,16 @@ typedef struct settings bool playlist_show_sublabels; bool quit_press_twice; +<<<<<<< HEAD bool vibrate_on_keypress; bool enable_device_vibration; #ifdef HAVE_OZONE bool ozone_collapse_sidebar; #endif +======= + + bool log_to_file; +>>>>>>> add log to file settings } bools; struct @@ -589,6 +594,9 @@ typedef struct settings char directory_menu_config[PATH_MAX_LENGTH]; char directory_menu_content[PATH_MAX_LENGTH]; char streaming_title[PATH_MAX_LENGTH]; + + char log_dir[PATH_MAX_LENGTH]; + char log_file[PATH_MAX_LENGTH]; } paths; bool modified; diff --git a/defaults.h b/defaults.h index 117e14a39a..6ffd885498 100644 --- a/defaults.h +++ b/defaults.h @@ -54,6 +54,7 @@ enum default_dirs DEFAULT_DIR_CHEATS, DEFAULT_DIR_RECORD_CONFIG, DEFAULT_DIR_RECORD_OUTPUT, + DEFAULT_DIR_LOGS, DEFAULT_DIR_LAST }; diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index 2f9e41e6b2..2fd9914449 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -1660,6 +1660,10 @@ static void frontend_unix_get_env(int *argc, sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS])); } + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], + internal_storage_app_path, "logs", + sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); + break; /* only the internal app dir is writable, this should never happen*/ @@ -1722,6 +1726,10 @@ static void frontend_unix_get_env(int *argc, sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS])); } + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], + app_dir, "logs", + sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); + break; /* sdcard is writable, this should be the case most of the time*/ case INTERNAL_STORAGE_WRITABLE: @@ -1742,6 +1750,10 @@ static void frontend_unix_get_env(int *argc, internal_storage_path, "RetroArch/downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], + internal_storage_path, "RetroArch/logs", + sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG], internal_storage_path, "RetroArch/config", sizeof(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG])); diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index da5142956d..35bd1f0a2e 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -465,7 +465,8 @@ static void frontend_win32_environment_get(int *argc, char *argv[], ":\\states", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE])); fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_SYSTEM], ":\\system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); - + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_LOGS], + ":\\logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); #ifdef HAVE_MENU #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) snprintf(g_defaults.settings.menu, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 7bb269143e..ec89eef333 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3976,7 +3976,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_LOG_VERBOSITY, - "Log events to the terminal." + "Log events to a terminal or file." ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY, diff --git a/pkg/android/phoenix/jni/Android.mk b/pkg/android/phoenix/jni/Android.mk index 0c63486e0e..542acad1a6 100644 --- a/pkg/android/phoenix/jni/Android.mk +++ b/pkg/android/phoenix/jni/Android.mk @@ -8,6 +8,7 @@ HAVE_NEON := 1 HAVE_LOGGER := 0 HAVE_VULKAN := 1 HAVE_CHEEVOS := 1 +HAVE_FILE_LOGGER := 1 INCFLAGS := DEFINES := diff --git a/retroarch.c b/retroarch.c index e7afc9bfff..5b882e08d3 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1759,6 +1759,20 @@ static void retroarch_parse_input_and_config(int argc, char *argv[]) } } + + if (verbosity_is_enabled()) + { + settings_t *settings = config_get_ptr(); + if (settings->bools.log_to_file && + !string_is_empty(settings->paths.log_dir) && !string_is_empty(settings->paths.log_file)) + { + char buf[PATH_MAX_LENGTH]; + fill_pathname_join(buf, settings->paths.log_dir, settings->paths.log_file, sizeof(buf)); + RARCH_LOG("Logging to file: %s\n", buf); + retro_main_log_file_init(buf); + } + } + #ifdef HAVE_GIT_VERSION RARCH_LOG("RetroArch %s (Git %s)\n", PACKAGE_VERSION, retroarch_git_version); diff --git a/runtime_file.c b/runtime_file.c index 7139b56c38..b2125a1bbb 100644 --- a/runtime_file.c +++ b/runtime_file.c @@ -370,7 +370,7 @@ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, if(!path_is_directory(log_file_dir)) { - RARCH_ERR("Failed to create directory for runtime log: %s.\n", log_file_dir); + RARCH_ERR("[runtime] failed to create directory for runtime log: %s.\n", log_file_dir); return NULL; } } @@ -415,7 +415,7 @@ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, if (string_is_empty(log_file_path)) return NULL; - + /* Phew... If we get this far then all is well. * > Create 'runtime_log' object */ runtime_log = (runtime_log_t*)calloc(1, sizeof(*runtime_log)); diff --git a/verbosity.c b/verbosity.c index 55a155a34c..662198dee0 100644 --- a/verbosity.c +++ b/verbosity.c @@ -96,6 +96,11 @@ bool verbosity_is_enabled(void) return main_verbosity; } +bool is_logging_to_file(void) +{ + return log_file_initialized; +} + bool *verbosity_get_ptr(void) { return &main_verbosity; @@ -190,10 +195,14 @@ void RARCH_LOG_V(const char *tag, const char *fmt, va_list ap) else if (string_is_equal(file_path_str(FILE_PATH_LOG_ERROR), tag)) prio = ANDROID_LOG_ERROR; } - __android_log_vprint(prio, - file_path_str(FILE_PATH_PROGRAM_NAME), - fmt, - ap); + + if (log_file_initialized) + vfprintf(log_file_fp, fmt, ap); + else + __android_log_vprint(prio, + file_path_str(FILE_PATH_PROGRAM_NAME), + fmt, + ap); } #else diff --git a/verbosity.h b/verbosity.h index 42ae964f58..546066af61 100644 --- a/verbosity.h +++ b/verbosity.h @@ -41,6 +41,8 @@ void retro_main_log_file_deinit(void); void retro_main_log_file_init(const char *path); +bool is_logging_to_file(void); + #if defined(HAVE_LOGGER) void logger_init (void); From 0c2f5093b26d431952e5418432884f6e189ecf5a Mon Sep 17 00:00:00 2001 From: radius Date: Thu, 7 Mar 2019 08:26:27 -0500 Subject: [PATCH 040/237] disable forced logging on android --- dirs.c | 2 ++ .../com/retroarch/browser/preferences/util/UserPreferences.java | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dirs.c b/dirs.c index aa253ceb8e..ee2c980861 100644 --- a/dirs.c +++ b/dirs.c @@ -314,6 +314,8 @@ void dir_check_defaults(void) */ #ifdef ORBIS if (filestream_exists("host0:app/custom.ini")) +#elif defined(ANDROID) + if (filestream_exists("host0:app/custom.ini")) #else if (filestream_exists("custom.ini")) #endif diff --git a/pkg/android/phoenix/src/com/retroarch/browser/preferences/util/UserPreferences.java b/pkg/android/phoenix/src/com/retroarch/browser/preferences/util/UserPreferences.java index 2e1ec9ed61..d19cef2643 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/preferences/util/UserPreferences.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/preferences/util/UserPreferences.java @@ -140,7 +140,6 @@ public final class UserPreferences Log.i(TAG, "dst dir is: " + dst_path); Log.i(TAG, "dst subdir is: " + dst_path_subdir); - config.setBoolean("log_verbosity", true); config.setString("bundle_assets_src_path", ctx.getApplicationInfo().sourceDir); config.setString("bundle_assets_dst_path", dst_path); config.setString("bundle_assets_dst_path_subdir", dst_path_subdir); From 2acfe9cb6af8327732f7dd49718fd912c0a8435f Mon Sep 17 00:00:00 2001 From: radius Date: Wed, 13 Mar 2019 12:39:27 -0500 Subject: [PATCH 041/237] fix --- configuration.c | 3 --- configuration.h | 3 --- 2 files changed, 6 deletions(-) diff --git a/configuration.c b/configuration.c index 9c6c0483d5..e779600a69 100644 --- a/configuration.c +++ b/configuration.c @@ -1589,16 +1589,13 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("playlist_sort_alphabetical", &settings->bools.playlist_sort_alphabetical, true, playlist_sort_alphabetical, false); SETTING_BOOL("quit_press_twice", &settings->bools.quit_press_twice, true, quit_press_twice, false); -<<<<<<< HEAD SETTING_BOOL("vibrate_on_keypress", &settings->bools.vibrate_on_keypress, true, vibrate_on_keypress, false); SETTING_BOOL("enable_device_vibration", &settings->bools.enable_device_vibration, true, enable_device_vibration, false); #ifdef HAVE_OZONE SETTING_BOOL("ozone_collapse_sidebar", &settings->bools.ozone_collapse_sidebar, true, ozone_collapse_sidebar, false); #endif -======= SETTING_BOOL("log_to_file", &settings->bools.log_to_file, true, default_log_to_file, false); ->>>>>>> add log to file settings *size = count; diff --git a/configuration.h b/configuration.h index 94c757f536..6e8cd1ad2c 100644 --- a/configuration.h +++ b/configuration.h @@ -315,16 +315,13 @@ typedef struct settings bool playlist_show_sublabels; bool quit_press_twice; -<<<<<<< HEAD bool vibrate_on_keypress; bool enable_device_vibration; #ifdef HAVE_OZONE bool ozone_collapse_sidebar; #endif -======= bool log_to_file; ->>>>>>> add log to file settings } bools; struct From 8361253b52ba3b67f3dcef9f08caae5d0e1628d5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 18 Mar 2019 04:39:54 +0100 Subject: [PATCH 042/237] (GL menu display driver) Don't go through video_driver_set_coords/video_driver_set_mvp --- menu/drivers_display/menu_display_gl.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/menu/drivers_display/menu_display_gl.c b/menu/drivers_display/menu_display_gl.c index bbfde4a0e0..15158d84b2 100644 --- a/menu/drivers_display/menu_display_gl.c +++ b/menu/drivers_display/menu_display_gl.c @@ -103,8 +103,6 @@ static void menu_display_gl_viewport(menu_display_ctx_draw_t *draw, static void menu_display_gl_draw(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { - video_shader_ctx_mvp_t mvp; - video_shader_ctx_coords_t coords; gl_t *gl = (gl_t*)video_info->userdata; if (!gl || !draw) @@ -121,16 +119,13 @@ static void menu_display_gl_draw(menu_display_ctx_draw_t *draw, if (draw) glBindTexture(GL_TEXTURE_2D, (GLuint)draw->texture); - coords.handle_data = gl; - coords.data = draw->coords; + gl->shader->set_coords(gl, + gl->shader_data, draw->coords); - video_driver_set_coords(&coords); + gl->shader->set_mvp(gl, gl->shader_data, + draw->matrix_data ? (math_matrix_4x4*)draw->matrix_data + : (math_matrix_4x4*)menu_display_gl_get_default_mvp(video_info)); - mvp.data = gl; - mvp.matrix = draw->matrix_data ? (math_matrix_4x4*)draw->matrix_data - : (math_matrix_4x4*)menu_display_gl_get_default_mvp(video_info); - - video_driver_set_mvp(&mvp); glDrawArrays(menu_display_prim_to_gl_enum( draw->prim_type), 0, draw->coords->vertices); From ab814efc6269b5eb913848648da1b76f1c8b3a58 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 18 Mar 2019 04:46:27 +0100 Subject: [PATCH 043/237] (GL raster font) Don't have to call video_driver_set_coords/ video_driver_set_mvp anymore --- gfx/drivers_font/gl_raster_font.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/gfx/drivers_font/gl_raster_font.c b/gfx/drivers_font/gl_raster_font.c index c1150ec86b..5eaf611df1 100644 --- a/gfx/drivers_font/gl_raster_font.c +++ b/gfx/drivers_font/gl_raster_font.c @@ -249,21 +249,17 @@ static void gl_raster_font_draw_vertices(gl_raster_t *font, const video_coords_t *coords, video_frame_info_t *video_info) { - video_shader_ctx_coords_t coords_data; - if (font->atlas->dirty) { gl_raster_font_upload_atlas(font); font->atlas->dirty = false; } - coords_data.handle_data = NULL; - coords_data.data = coords; + font->gl->shader->set_coords(font->gl, + font->gl->shader_data, coords); - video_driver_set_coords(&coords_data); - - video_info->cb_set_mvp(font->gl, - video_info->shader_data, &font->gl->mvp_no_rot); + font->gl->shader->set_mvp(font->gl, font->gl->shader_data, + &font->gl->mvp_no_rot); glDrawArrays(GL_TRIANGLES, 0, coords->vertices); } From 03641f237899480554ad0eae874d9f1314e88a1d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 18 Mar 2019 04:50:50 +0100 Subject: [PATCH 044/237] (GL1) Cleanups --- gfx/drivers_font/gl1_raster_font.c | 10 ---------- menu/drivers_display/menu_display_gl1.c | 9 +-------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/gfx/drivers_font/gl1_raster_font.c b/gfx/drivers_font/gl1_raster_font.c index fcd14c8476..974bb1d90b 100644 --- a/gfx/drivers_font/gl1_raster_font.c +++ b/gfx/drivers_font/gl1_raster_font.c @@ -237,22 +237,12 @@ static void gl1_raster_font_draw_vertices(gl1_raster_t *font, const video_coords_t *coords, video_frame_info_t *video_info) { - video_shader_ctx_coords_t coords_data; - if (font->atlas->dirty) { gl1_raster_font_upload_atlas(font); font->atlas->dirty = false; } - coords_data.handle_data = NULL; - coords_data.data = coords; - - video_driver_set_coords(&coords_data); - - /*video_info->cb_set_mvp(font->gl, - video_info->shader_data, &font->gl->mvp_no_rot);*/ - glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadMatrixf(font->gl->mvp.data); diff --git a/menu/drivers_display/menu_display_gl1.c b/menu/drivers_display/menu_display_gl1.c index 5124931c05..cb4840d49e 100644 --- a/menu/drivers_display/menu_display_gl1.c +++ b/menu/drivers_display/menu_display_gl1.c @@ -100,9 +100,7 @@ static void menu_display_gl1_draw(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { video_shader_ctx_mvp_t mvp; - video_shader_ctx_coords_t coords; - gl1_t *gl1 = video_info ? - (gl1_t*)video_info->userdata : NULL; + gl1_t *gl1 = (gl1_t*)video_info->userdata; if (!gl1 || !draw) return; @@ -120,11 +118,6 @@ static void menu_display_gl1_draw(menu_display_ctx_draw_t *draw, glBindTexture(GL_TEXTURE_2D, (GLuint)draw->texture); - coords.handle_data = gl1; - coords.data = draw->coords; - - video_driver_set_coords(&coords); - mvp.data = gl1; mvp.matrix = draw->matrix_data ? (math_matrix_4x4*)draw->matrix_data : (math_matrix_4x4*)menu_display_gl1_get_default_mvp(video_info); From fe1255094fcd2c517ac417cf36cccaef5b4e0954 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 18 Mar 2019 05:04:23 +0100 Subject: [PATCH 045/237] Get rid of now unused set_coords in video_driver_poke_interface --- gfx/drivers/caca_gfx.c | 1 - gfx/drivers/ctr_gfx.c | 1 - gfx/drivers/d3d10.c | 1 - gfx/drivers/d3d11.c | 1 - gfx/drivers/d3d12.c | 1 - gfx/drivers/d3d8.c | 1 - gfx/drivers/d3d9.c | 1 - gfx/drivers/dispmanx_gfx.c | 1 - gfx/drivers/drm_gfx.c | 1 - gfx/drivers/exynos_gfx.c | 1 - gfx/drivers/gdi_gfx.c | 1 - gfx/drivers/gl.c | 1 - gfx/drivers/gl1.c | 15 --------------- gfx/drivers/gl_core.c | 1 - gfx/drivers/gx2_gfx.c | 1 - gfx/drivers/gx_gfx.c | 1 - gfx/drivers/omap_gfx.c | 1 - gfx/drivers/ps2_gfx.c | 1 - gfx/drivers/psp1_gfx.c | 1 - gfx/drivers/sdl2_gfx.c | 1 - gfx/drivers/sdl_gfx.c | 1 - gfx/drivers/sixel_gfx.c | 1 - gfx/drivers/sunxi_gfx.c | 1 - gfx/drivers/switch_gfx.c | 1 - gfx/drivers/switch_nx_gfx.c | 1 - gfx/drivers/vga_gfx.c | 1 - gfx/drivers/vita2d_gfx.c | 1 - gfx/drivers/vulkan.c | 1 - gfx/drivers/xshm_gfx.c | 1 - gfx/drivers/xvideo.c | 1 - gfx/video_driver.c | 15 --------------- gfx/video_driver.h | 4 ---- gfx/video_thread_wrapper.c | 1 - 33 files changed, 64 deletions(-) diff --git a/gfx/drivers/caca_gfx.c b/gfx/drivers/caca_gfx.c index 05f5d17205..6a2abac951 100644 --- a/gfx/drivers/caca_gfx.c +++ b/gfx/drivers/caca_gfx.c @@ -306,7 +306,6 @@ static void caca_set_osd_msg(void *data, static const video_poke_interface_t caca_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index ee59e53baf..a87a659f90 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -1144,7 +1144,6 @@ static void ctr_set_osd_msg(void *data, static const video_poke_interface_t ctr_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ ctr_load_texture, ctr_unload_texture, diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index 812986a717..c20116ca6f 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -1684,7 +1684,6 @@ static uint32_t d3d10_get_flags(void *data) static const video_poke_interface_t d3d10_poke_interface = { d3d10_get_flags, - NULL, /* set_coords */ NULL, /* set_mvp */ d3d10_gfx_load_texture, d3d10_gfx_unload_texture, diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 8921fd44eb..a27864e1d1 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -1751,7 +1751,6 @@ static uint32_t d3d11_get_flags(void *data) static const video_poke_interface_t d3d11_poke_interface = { d3d11_get_flags, - NULL, /* set_coords */ NULL, /* set_mvp */ d3d11_gfx_load_texture, d3d11_gfx_unload_texture, diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index 354007c7a9..733803ea19 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -1797,7 +1797,6 @@ static uint32_t d3d12_get_flags(void *data) static const video_poke_interface_t d3d12_poke_interface = { d3d12_get_flags, - NULL, /* set_coords */ NULL, /* set_mvp */ d3d12_gfx_load_texture, d3d12_gfx_unload_texture, diff --git a/gfx/drivers/d3d8.c b/gfx/drivers/d3d8.c index b6f58d3c10..9ffe225e2d 100644 --- a/gfx/drivers/d3d8.c +++ b/gfx/drivers/d3d8.c @@ -1854,7 +1854,6 @@ static uint32_t d3d8_get_flags(void *data) static const video_poke_interface_t d3d_poke_interface = { d3d8_get_flags, - NULL, /* set_coords */ d3d8_set_mvp, d3d8_load_texture, d3d8_unload_texture, diff --git a/gfx/drivers/d3d9.c b/gfx/drivers/d3d9.c index 9a3ea1703f..e79b527297 100644 --- a/gfx/drivers/d3d9.c +++ b/gfx/drivers/d3d9.c @@ -2053,7 +2053,6 @@ static uint32_t d3d9_get_flags(void *data) static const video_poke_interface_t d3d9_poke_interface = { d3d9_get_flags, - NULL, /* set_coords */ d3d9_set_mvp, d3d9_load_texture, d3d9_unload_texture, diff --git a/gfx/drivers/dispmanx_gfx.c b/gfx/drivers/dispmanx_gfx.c index 386d2bcc38..e0262894d7 100644 --- a/gfx/drivers/dispmanx_gfx.c +++ b/gfx/drivers/dispmanx_gfx.c @@ -632,7 +632,6 @@ static void dispmanx_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) static const video_poke_interface_t dispmanx_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/drm_gfx.c b/gfx/drivers/drm_gfx.c index 4f071167c2..d2cf0b1dc2 100644 --- a/gfx/drivers/drm_gfx.c +++ b/gfx/drivers/drm_gfx.c @@ -966,7 +966,6 @@ static void drm_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) static const video_poke_interface_t drm_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/exynos_gfx.c b/gfx/drivers/exynos_gfx.c index ce2256a84e..a166bc9a8e 100644 --- a/gfx/drivers/exynos_gfx.c +++ b/gfx/drivers/exynos_gfx.c @@ -1489,7 +1489,6 @@ static void exynos_show_mouse(void *data, bool state) static const video_poke_interface_t exynos_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/gdi_gfx.c b/gfx/drivers/gdi_gfx.c index c30cefd736..667c8724f6 100644 --- a/gfx/drivers/gdi_gfx.c +++ b/gfx/drivers/gdi_gfx.c @@ -631,7 +631,6 @@ static void gdi_unload_texture(void *data, uintptr_t handle) static const video_poke_interface_t gdi_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ gdi_load_texture, gdi_unload_texture, diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 8ee8560010..81b040f391 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -4142,7 +4142,6 @@ static uint32_t gl2_get_flags(void *data) static const video_poke_interface_t gl2_poke_interface = { gl2_get_flags, - NULL, /* set_coords */ NULL, /* set_mvp */ gl2_load_texture, gl2_unload_texture, diff --git a/gfx/drivers/gl1.c b/gfx/drivers/gl1.c index 2798479e7a..4bbd0ea7ea 100644 --- a/gfx/drivers/gl1.c +++ b/gfx/drivers/gl1.c @@ -1248,23 +1248,8 @@ static uint32_t gl1_get_flags(void *data) return flags; } -static void gl1_set_coords(void *handle_data, void *shader_data, - const struct video_coords *coords) -{ - gl1_t *gl1 = (gl1_t*)handle_data; - - if (!gl1) - return; - - gl1->coords.vertex = coords->vertex; - gl1->coords.color = coords->color; - gl1->coords.tex_coord = coords->tex_coord; - gl1->coords.lut_tex_coord = coords->lut_tex_coord; -} - static const video_poke_interface_t gl1_poke_interface = { gl1_get_flags, - gl1_set_coords, NULL, gl1_load_texture, gl1_unload_texture, diff --git a/gfx/drivers/gl_core.c b/gfx/drivers/gl_core.c index 1210f3d6c6..5ef082ddbb 100644 --- a/gfx/drivers/gl_core.c +++ b/gfx/drivers/gl_core.c @@ -1960,7 +1960,6 @@ static retro_proc_address_t gl_core_get_proc_address(void *data, const char *sym static const video_poke_interface_t gl_core_poke_interface = { gl_core_get_flags, - NULL, /* set_coords */ NULL, /* set_mvp */ gl_core_load_texture, gl_core_unload_texture, diff --git a/gfx/drivers/gx2_gfx.c b/gfx/drivers/gx2_gfx.c index eb90ff3aa0..9c0e8354bc 100644 --- a/gfx/drivers/gx2_gfx.c +++ b/gfx/drivers/gx2_gfx.c @@ -1717,7 +1717,6 @@ static uint32_t wiiu_gfx_get_flags(void *data) static const video_poke_interface_t wiiu_poke_interface = { wiiu_gfx_get_flags, - NULL, /* set_coords */ NULL, /* set_mvp */ wiiu_gfx_load_texture, wiiu_gfx_unload_texture, diff --git a/gfx/drivers/gx_gfx.c b/gfx/drivers/gx_gfx.c index 25c615e246..14438aa9c8 100644 --- a/gfx/drivers/gx_gfx.c +++ b/gfx/drivers/gx_gfx.c @@ -1265,7 +1265,6 @@ static void gx_get_video_output_next(void *data) static const video_poke_interface_t gx_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/omap_gfx.c b/gfx/drivers/omap_gfx.c index 992472eaa2..783a9a838e 100644 --- a/gfx/drivers/omap_gfx.c +++ b/gfx/drivers/omap_gfx.c @@ -1138,7 +1138,6 @@ static float omap_get_refresh_rate(void *data) static const video_poke_interface_t omap_gfx_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/ps2_gfx.c b/gfx/drivers/ps2_gfx.c index 381848be92..4ef83f763a 100644 --- a/gfx/drivers/ps2_gfx.c +++ b/gfx/drivers/ps2_gfx.c @@ -470,7 +470,6 @@ static bool ps2_get_hw_render_interface(void* data, static const video_poke_interface_t ps2_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/psp1_gfx.c b/gfx/drivers/psp1_gfx.c index 773fe26b7c..c05397797a 100644 --- a/gfx/drivers/psp1_gfx.c +++ b/gfx/drivers/psp1_gfx.c @@ -832,7 +832,6 @@ static void psp_viewport_info(void *data, struct video_viewport *vp) static const video_poke_interface_t psp_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/sdl2_gfx.c b/gfx/drivers/sdl2_gfx.c index eb13938958..c7f73fe24f 100644 --- a/gfx/drivers/sdl2_gfx.c +++ b/gfx/drivers/sdl2_gfx.c @@ -726,7 +726,6 @@ static void sdl2_grab_mouse_toggle(void *data) static video_poke_interface_t sdl2_video_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/sdl_gfx.c b/gfx/drivers/sdl_gfx.c index 18a54cdac5..914fa3d5dc 100644 --- a/gfx/drivers/sdl_gfx.c +++ b/gfx/drivers/sdl_gfx.c @@ -518,7 +518,6 @@ static void sdl_grab_mouse_toggle(void *data) static const video_poke_interface_t sdl_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/sixel_gfx.c b/gfx/drivers/sixel_gfx.c index bf288c7f80..10feb2d56f 100644 --- a/gfx/drivers/sixel_gfx.c +++ b/gfx/drivers/sixel_gfx.c @@ -603,7 +603,6 @@ static const video_poke_interface_t sixel_poke_interface = { NULL, NULL, NULL, - NULL, sixel_set_video_mode, NULL, NULL, diff --git a/gfx/drivers/sunxi_gfx.c b/gfx/drivers/sunxi_gfx.c index baf909520a..b4d8390d01 100644 --- a/gfx/drivers/sunxi_gfx.c +++ b/gfx/drivers/sunxi_gfx.c @@ -944,7 +944,6 @@ static float sunxi_get_refresh_rate (void *data) static const video_poke_interface_t sunxi_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/switch_gfx.c b/gfx/drivers/switch_gfx.c index 954938ef3f..04c442654c 100644 --- a/gfx/drivers/switch_gfx.c +++ b/gfx/drivers/switch_gfx.c @@ -406,7 +406,6 @@ static void switch_set_texture_enable(void *data, bool enable, bool full_screen) static const video_poke_interface_t switch_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, /* load_texture */ NULL, /* unload_texture */ diff --git a/gfx/drivers/switch_nx_gfx.c b/gfx/drivers/switch_nx_gfx.c index b54701e720..8c7c603aa0 100644 --- a/gfx/drivers/switch_nx_gfx.c +++ b/gfx/drivers/switch_nx_gfx.c @@ -755,7 +755,6 @@ void switch_overlay_interface(void *data, const video_overlay_interface_t **ifac static const video_poke_interface_t switch_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, /* load_texture */ NULL, /* unload_texture */ diff --git a/gfx/drivers/vga_gfx.c b/gfx/drivers/vga_gfx.c index 22182a6229..02db6a474f 100644 --- a/gfx/drivers/vga_gfx.c +++ b/gfx/drivers/vga_gfx.c @@ -391,7 +391,6 @@ static void vga_set_osd_msg(void *data, static const video_poke_interface_t vga_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/vita2d_gfx.c b/gfx/drivers/vita2d_gfx.c index 3e253ee8d4..4a3cbb33ae 100644 --- a/gfx/drivers/vita2d_gfx.c +++ b/gfx/drivers/vita2d_gfx.c @@ -790,7 +790,6 @@ static bool vita_get_current_sw_framebuffer(void *data, static const video_poke_interface_t vita_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ vita_load_texture, vita_unload_texture, diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index 297170de5e..e35a875b77 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -2407,7 +2407,6 @@ static uint32_t vulkan_get_flags(void *data) static const video_poke_interface_t vulkan_poke_interface = { vulkan_get_flags, - NULL, /* set_coords */ NULL, /* set_mvp */ vulkan_load_texture, vulkan_unload_texture, diff --git a/gfx/drivers/xshm_gfx.c b/gfx/drivers/xshm_gfx.c index ea728793cc..cfeda3481b 100644 --- a/gfx/drivers/xshm_gfx.c +++ b/gfx/drivers/xshm_gfx.c @@ -205,7 +205,6 @@ static void xshm_grab_mouse_toggle(void *data) static video_poke_interface_t xshm_video_poke_interface = { NULL, /* get_flags */ - NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, diff --git a/gfx/drivers/xvideo.c b/gfx/drivers/xvideo.c index 619cbaa712..70fc2b5d27 100644 --- a/gfx/drivers/xvideo.c +++ b/gfx/drivers/xvideo.c @@ -940,7 +940,6 @@ static video_poke_interface_t xv_video_poke_interface = { NULL, NULL, NULL, - NULL, x11_get_refresh_rate, NULL, NULL, diff --git a/gfx/video_driver.c b/gfx/video_driver.c index d0fed6987e..db87f6183f 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -3544,21 +3544,6 @@ bool video_shader_driver_init(video_shader_ctx_init_t *init) return true; } -void video_driver_set_coords(video_shader_ctx_coords_t *coords) -{ - if (current_shader && current_shader->set_coords) - current_shader->set_coords(coords->handle_data, - current_shader_data, - (const struct video_coords*)coords->data); - else - { - if (video_driver_poke && video_driver_poke->set_coords) - video_driver_poke->set_coords(coords->handle_data, - current_shader_data, - (const struct video_coords*)coords->data); - } -} - void video_driver_set_mvp(video_shader_ctx_mvp_t *mvp) { if (!mvp || !mvp->matrix) diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 4d2d8597dc..de35ab60b2 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -691,8 +691,6 @@ struct aspect_ratio_elem typedef struct video_poke_interface { uint32_t (*get_flags)(void *data); - void (*set_coords)(void *handle_data, void *shader_data, - const struct video_coords *coords); void (*set_mvp)(void *data, void *shader_data, const void *mat_data); uintptr_t (*load_texture)(void *video_data, void *data, @@ -1198,8 +1196,6 @@ bool video_shader_driver_init_first(const void *data); bool video_shader_driver_init(video_shader_ctx_init_t *init); -void video_driver_set_coords(video_shader_ctx_coords_t *coords); - void video_driver_set_mvp(video_shader_ctx_mvp_t *mvp); float video_driver_get_refresh_rate(void); diff --git a/gfx/video_thread_wrapper.c b/gfx/video_thread_wrapper.c index c04a8b7d57..94f4b9f727 100644 --- a/gfx/video_thread_wrapper.c +++ b/gfx/video_thread_wrapper.c @@ -1241,7 +1241,6 @@ static uint32_t thread_get_flags(void *data) static const video_poke_interface_t thread_poke = { thread_get_flags, - NULL, /* set_coords */ NULL, /* set_mvp */ thread_load_texture, thread_unload_texture, From e94c8a762da06d5229f2284e7d3dbbd7fdfa79e0 Mon Sep 17 00:00:00 2001 From: natinusala Date: Mon, 18 Mar 2019 12:59:23 +0100 Subject: [PATCH 046/237] ozone: use new button icons in footer --- menu/drivers/ozone/ozone.c | 18 +++++++++++------- menu/drivers/ozone/ozone_texture.h | 10 +--------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index 097cba513c..c19c2d3618 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1072,7 +1072,9 @@ static void ozone_draw_footer(ozone_handle_t *ozone, video_frame_info_t *video_i unsigned ok_width = 96; unsigned search_width = 343; unsigned thumb_width = 343 + 188 + 80; - bool do_swap = video_info->input_menu_swap_ok_cancel_buttons; + unsigned icon_size = 35; + unsigned icon_offset = icon_size / 2; + bool do_swap = video_info->input_menu_swap_ok_cancel_buttons; if (do_swap) { @@ -1082,21 +1084,23 @@ static void ozone_draw_footer(ozone_handle_t *ozone, video_frame_info_t *video_i menu_display_blend_begin(video_info); + menu_display_set_alpha(ozone->theme_dynamic.entries_icon, 1.0f); + if (do_swap) { - ozone_draw_icon(video_info, 25, 25, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_B], video_info->width - 133, video_info->height - ozone->dimensions.footer_height / 2 - 12, video_info->width,video_info->height, 0, 1, NULL); - ozone_draw_icon(video_info, 25, 25, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_A], video_info->width - 251, video_info->height - ozone->dimensions.footer_height / 2 - 12, video_info->width,video_info->height, 0, 1, NULL); + ozone_draw_icon(video_info, icon_size, icon_size, ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_BTN_R], video_info->width - 138, video_info->height - ozone->dimensions.footer_height / 2 - icon_offset, video_info->width,video_info->height, 0, 1, ozone->theme_dynamic.entries_icon); + ozone_draw_icon(video_info, icon_size, icon_size, ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_BTN_D], video_info->width - 256, video_info->height - ozone->dimensions.footer_height / 2 - icon_offset, video_info->width,video_info->height, 0, 1, ozone->theme_dynamic.entries_icon); } else { - ozone_draw_icon(video_info, 25, 25, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_B], video_info->width - 251, video_info->height - ozone->dimensions.footer_height / 2 - 12, video_info->width,video_info->height, 0, 1, NULL); - ozone_draw_icon(video_info, 25, 25, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_A], video_info->width - 133, video_info->height - ozone->dimensions.footer_height / 2 - 12, video_info->width,video_info->height, 0, 1, NULL); + ozone_draw_icon(video_info, icon_size, icon_size, ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_BTN_D], video_info->width - 256, video_info->height - ozone->dimensions.footer_height / 2 - icon_offset, video_info->width,video_info->height, 0, 1, ozone->theme_dynamic.entries_icon); + ozone_draw_icon(video_info, icon_size, icon_size, ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_BTN_R], video_info->width - 138, video_info->height - ozone->dimensions.footer_height / 2 - icon_offset, video_info->width,video_info->height, 0, 1, ozone->theme_dynamic.entries_icon); } - ozone_draw_icon(video_info, 26, 26, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_X], video_info->width - 379, video_info->height - ozone->dimensions.footer_height / 2 - 12, video_info->width,video_info->height, 0, 1, NULL); + ozone_draw_icon(video_info, icon_size, icon_size, ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_BTN_U], video_info->width - 384, video_info->height - ozone->dimensions.footer_height / 2 - icon_offset, video_info->width,video_info->height, 0, 1, ozone->theme_dynamic.entries_icon); if (ozone->is_playlist && !ozone->cursor_in_sidebar) - ozone_draw_icon(video_info, 26, 26, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_Y], video_info->width - 379 - 118 - 100 - 50, video_info->height - ozone->dimensions.footer_height / 2 - 12, video_info->width,video_info->height, 0, 1, NULL); + ozone_draw_icon(video_info, icon_size, icon_size, ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_BTN_L], video_info->width - 384 - 118 - 100 - 50, video_info->height - ozone->dimensions.footer_height / 2 - icon_offset, video_info->width,video_info->height, 0, 1, ozone->theme_dynamic.entries_icon); menu_display_blend_end(video_info); diff --git a/menu/drivers/ozone/ozone_texture.h b/menu/drivers/ozone/ozone_texture.h index 237c8e25a9..1c5e832c76 100644 --- a/menu/drivers/ozone/ozone_texture.h +++ b/menu/drivers/ozone/ozone_texture.h @@ -40,11 +40,7 @@ static const char *OZONE_TEXTURES_FILES[OZONE_TEXTURE_LAST] = { }; enum OZONE_THEME_TEXTURES { - OZONE_THEME_TEXTURE_BUTTON_A = 0, - OZONE_THEME_TEXTURE_BUTTON_B, - OZONE_THEME_TEXTURE_BUTTON_X, - OZONE_THEME_TEXTURE_BUTTON_Y, - OZONE_THEME_TEXTURE_SWITCH, + OZONE_THEME_TEXTURE_SWITCH = 0, OZONE_THEME_TEXTURE_CHECK, OZONE_THEME_TEXTURE_CURSOR_NO_BORDER, @@ -54,10 +50,6 @@ enum OZONE_THEME_TEXTURES { }; static const char *OZONE_THEME_TEXTURES_FILES[OZONE_THEME_TEXTURE_LAST] = { - "button_a", - "button_b", - "button_x", - "button_y", "switch", "check", From f67bfa24efed294dec4410d04c970c53cca793f0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 18 Mar 2019 15:19:11 +0100 Subject: [PATCH 047/237] Get rid of video_poke_interface set_mvp --- gfx/common/d3d8_common.h | 2 + gfx/common/d3d9_common.h | 2 + gfx/drivers/caca_gfx.c | 2 - gfx/drivers/ctr_gfx.c | 1 - gfx/drivers/d3d10.c | 1 - gfx/drivers/d3d11.c | 1 - gfx/drivers/d3d12.c | 1 - gfx/drivers/d3d8.c | 29 ++++----------- gfx/drivers/d3d9.c | 13 +++---- gfx/drivers/dispmanx_gfx.c | 1 - gfx/drivers/drm_gfx.c | 1 - gfx/drivers/exynos_gfx.c | 1 - gfx/drivers/gdi_gfx.c | 1 - gfx/drivers/gl.c | 1 - gfx/drivers/gl1.c | 1 - gfx/drivers/gl_core.c | 1 - gfx/drivers/gx2_gfx.c | 1 - gfx/drivers/gx_gfx.c | 1 - gfx/drivers/omap_gfx.c | 1 - gfx/drivers/ps2_gfx.c | 1 - gfx/drivers/psp1_gfx.c | 1 - gfx/drivers/sdl2_gfx.c | 1 - gfx/drivers/sdl_gfx.c | 1 - gfx/drivers/sixel_gfx.c | 1 - gfx/drivers/sunxi_gfx.c | 1 - gfx/drivers/switch_gfx.c | 1 - gfx/drivers/switch_nx_gfx.c | 1 - gfx/drivers/vga_gfx.c | 1 - gfx/drivers/vita2d_gfx.c | 1 - gfx/drivers/vulkan.c | 1 - gfx/drivers/xshm_gfx.c | 1 - gfx/drivers/xvideo.c | 1 - gfx/video_driver.c | 47 ------------------------ gfx/video_driver.h | 7 ---- gfx/video_thread_wrapper.c | 1 - menu/drivers_display/menu_display_d3d8.c | 6 +-- menu/drivers_display/menu_display_d3d9.c | 5 +-- 37 files changed, 20 insertions(+), 121 deletions(-) diff --git a/gfx/common/d3d8_common.h b/gfx/common/d3d8_common.h index 556086440b..84125e2d21 100644 --- a/gfx/common/d3d8_common.h +++ b/gfx/common/d3d8_common.h @@ -515,6 +515,8 @@ static INLINE INT32 d3d8_get_xrgb8888_format(void) #endif } +void d3d8_set_mvp(void *data, const void *userdata); + RETRO_END_DECLS #endif diff --git a/gfx/common/d3d9_common.h b/gfx/common/d3d9_common.h index 992447dcf6..56128981a0 100644 --- a/gfx/common/d3d9_common.h +++ b/gfx/common/d3d9_common.h @@ -812,6 +812,8 @@ static INLINE void d3d9_convert_geometry( } } +void d3d9_set_mvp(void *data, const void *userdata); + RETRO_END_DECLS #endif diff --git a/gfx/drivers/caca_gfx.c b/gfx/drivers/caca_gfx.c index 6a2abac951..5c88affec5 100644 --- a/gfx/drivers/caca_gfx.c +++ b/gfx/drivers/caca_gfx.c @@ -306,8 +306,6 @@ static void caca_set_osd_msg(void *data, static const video_poke_interface_t caca_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ - NULL, NULL, NULL, NULL, diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index a87a659f90..525d9491ff 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -1144,7 +1144,6 @@ static void ctr_set_osd_msg(void *data, static const video_poke_interface_t ctr_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ ctr_load_texture, ctr_unload_texture, NULL, diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index c20116ca6f..89b483b2bc 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -1684,7 +1684,6 @@ static uint32_t d3d10_get_flags(void *data) static const video_poke_interface_t d3d10_poke_interface = { d3d10_get_flags, - NULL, /* set_mvp */ d3d10_gfx_load_texture, d3d10_gfx_unload_texture, NULL, /* set_video_mode */ diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index a27864e1d1..027e3d5ad5 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -1751,7 +1751,6 @@ static uint32_t d3d11_get_flags(void *data) static const video_poke_interface_t d3d11_poke_interface = { d3d11_get_flags, - NULL, /* set_mvp */ d3d11_gfx_load_texture, d3d11_gfx_unload_texture, NULL, /* set_video_mode */ diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index 733803ea19..d778a1730d 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -1797,7 +1797,6 @@ static uint32_t d3d12_get_flags(void *data) static const video_poke_interface_t d3d12_poke_interface = { d3d12_get_flags, - NULL, /* set_mvp */ d3d12_gfx_load_texture, d3d12_gfx_unload_texture, NULL, /* set_video_mode */ diff --git a/gfx/drivers/d3d8.c b/gfx/drivers/d3d8.c index 9ffe225e2d..f5aa6bf2c0 100644 --- a/gfx/drivers/d3d8.c +++ b/gfx/drivers/d3d8.c @@ -86,23 +86,20 @@ typedef struct d3d8_renderchain uint64_t frame_count; } d3d8_renderchain_t; -static void d3d8_renderchain_set_mvp( - d3d8_video_t *d3d, - void *chain_data, - void *shader_data, - const void *mat_data) +void d3d8_set_mvp(void *data, const void *mat_data) { struct d3d_matrix matrix; + LPDIRECT3DDEVICE8 d3dr = (LPDIRECT3DDEVICE8)data; d3d_matrix_identity(&matrix); - d3d8_set_transform(d3d->dev, D3DTS_PROJECTION, (D3DMATRIX*)&matrix); - d3d8_set_transform(d3d->dev, D3DTS_VIEW, (D3DMATRIX*)&matrix); + d3d8_set_transform(d3dr, D3DTS_PROJECTION, (D3DMATRIX*)&matrix); + d3d8_set_transform(d3dr, D3DTS_VIEW, (D3DMATRIX*)&matrix); if (mat_data) d3d_matrix_transpose(&matrix, mat_data); - d3d8_set_transform(d3d->dev, D3DTS_WORLD, (D3DMATRIX*)&matrix); + d3d8_set_transform(d3dr, D3DTS_WORLD, (D3DMATRIX*)&matrix); } static bool d3d8_renderchain_create_first_pass( @@ -288,7 +285,7 @@ static void d3d8_renderchain_render_pass( D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_DIFFUSE, NULL); d3d8_set_stream_source(d3dr, 0, chain->vertex_buf, 0, sizeof(Vertex)); - d3d8_renderchain_set_mvp(d3d, chain, NULL, &d3d->mvp_rotate); + d3d8_set_mvp(d3d->dev, &d3d->mvp_rotate); d3d8_draw_primitive(d3dr, D3DPT_TRIANGLESTRIP, 0, 2); } @@ -427,15 +424,6 @@ static void d3d8_viewport_info(void *data, struct video_viewport *vp) d3d8_renderchain_viewport_info(d3d, vp); } -static void d3d8_set_mvp(void *data, - void *shader_data, - const void *mat_data) -{ - d3d8_video_t *d3d = (d3d8_video_t*)data; - if (d3d) - d3d8_renderchain_set_mvp(d3d, d3d->renderchain_data, shader_data, mat_data); -} - static void d3d8_overlay_render(d3d8_video_t *d3d, video_frame_info_t *video_info, overlay_t *overlay, bool force_linear) @@ -1598,7 +1586,7 @@ static bool d3d8_frame(void *data, const void *frame, #ifdef HAVE_MENU if (d3d->menu && d3d->menu->enabled) { - d3d8_set_mvp(d3d, NULL, &d3d->mvp); + d3d8_set_mvp(d3d->dev, &d3d->mvp); d3d8_overlay_render(d3d, video_info, d3d->menu, false); d3d->menu_display.offset = 0; @@ -1623,7 +1611,7 @@ static bool d3d8_frame(void *data, const void *frame, #ifdef HAVE_OVERLAY if (d3d->overlays_enabled) { - d3d8_set_mvp(d3d, NULL, &d3d->mvp); + d3d8_set_mvp(d3d->dev, &d3d->mvp); for (i = 0; i < d3d->overlays_size; i++) d3d8_overlay_render(d3d, video_info, &d3d->overlays[i], true); } @@ -1854,7 +1842,6 @@ static uint32_t d3d8_get_flags(void *data) static const video_poke_interface_t d3d_poke_interface = { d3d8_get_flags, - d3d8_set_mvp, d3d8_load_texture, d3d8_unload_texture, d3d8_set_video_mode, diff --git a/gfx/drivers/d3d9.c b/gfx/drivers/d3d9.c index e79b527297..e8797b092f 100644 --- a/gfx/drivers/d3d9.c +++ b/gfx/drivers/d3d9.c @@ -456,12 +456,10 @@ static void d3d9_viewport_info(void *data, struct video_viewport *vp) vp->full_height = height; } -static void d3d9_set_mvp(void *data, - void *shader_data, - const void *mat_data) +void d3d9_set_mvp(void *data, const void *mat_data) { - d3d9_video_t *d3d = (d3d9_video_t*)data; - d3d9_set_vertex_shader_constantf(d3d->dev, 0, (const float*)mat_data, 4); + LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)data; + d3d9_set_vertex_shader_constantf(dev, 0, (const float*)mat_data, 4); } static void d3d9_overlay_render(d3d9_video_t *d3d, @@ -1696,7 +1694,7 @@ static bool d3d9_frame(void *data, const void *frame, #ifdef HAVE_MENU if (d3d->menu && d3d->menu->enabled) { - d3d9_set_mvp(d3d, NULL, &d3d->mvp); + d3d9_set_mvp(d3d->dev, &d3d->mvp); d3d9_overlay_render(d3d, video_info, d3d->menu, false); d3d->menu_display.offset = 0; @@ -1725,7 +1723,7 @@ static bool d3d9_frame(void *data, const void *frame, #ifdef HAVE_OVERLAY if (d3d->overlays_enabled) { - d3d9_set_mvp(d3d, NULL, &d3d->mvp); + d3d9_set_mvp(d3d->dev, &d3d->mvp); for (i = 0; i < d3d->overlays_size; i++) d3d9_overlay_render(d3d, video_info, &d3d->overlays[i], true); } @@ -2053,7 +2051,6 @@ static uint32_t d3d9_get_flags(void *data) static const video_poke_interface_t d3d9_poke_interface = { d3d9_get_flags, - d3d9_set_mvp, d3d9_load_texture, d3d9_unload_texture, d3d9_set_video_mode, diff --git a/gfx/drivers/dispmanx_gfx.c b/gfx/drivers/dispmanx_gfx.c index e0262894d7..74b6504c13 100644 --- a/gfx/drivers/dispmanx_gfx.c +++ b/gfx/drivers/dispmanx_gfx.c @@ -632,7 +632,6 @@ static void dispmanx_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) static const video_poke_interface_t dispmanx_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, NULL, NULL, /* set_video_mode */ diff --git a/gfx/drivers/drm_gfx.c b/gfx/drivers/drm_gfx.c index d2cf0b1dc2..41a99df738 100644 --- a/gfx/drivers/drm_gfx.c +++ b/gfx/drivers/drm_gfx.c @@ -966,7 +966,6 @@ static void drm_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) static const video_poke_interface_t drm_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, NULL, NULL, /* set_video_mode */ diff --git a/gfx/drivers/exynos_gfx.c b/gfx/drivers/exynos_gfx.c index a166bc9a8e..6e919ccf98 100644 --- a/gfx/drivers/exynos_gfx.c +++ b/gfx/drivers/exynos_gfx.c @@ -1489,7 +1489,6 @@ static void exynos_show_mouse(void *data, bool state) static const video_poke_interface_t exynos_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, NULL, NULL, /* set_video_mode */ diff --git a/gfx/drivers/gdi_gfx.c b/gfx/drivers/gdi_gfx.c index 667c8724f6..68d5cdca55 100644 --- a/gfx/drivers/gdi_gfx.c +++ b/gfx/drivers/gdi_gfx.c @@ -631,7 +631,6 @@ static void gdi_unload_texture(void *data, uintptr_t handle) static const video_poke_interface_t gdi_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ gdi_load_texture, gdi_unload_texture, gdi_set_video_mode, diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 81b040f391..a1294b496f 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -4142,7 +4142,6 @@ static uint32_t gl2_get_flags(void *data) static const video_poke_interface_t gl2_poke_interface = { gl2_get_flags, - NULL, /* set_mvp */ gl2_load_texture, gl2_unload_texture, gl2_set_video_mode, diff --git a/gfx/drivers/gl1.c b/gfx/drivers/gl1.c index 4bbd0ea7ea..77550ca204 100644 --- a/gfx/drivers/gl1.c +++ b/gfx/drivers/gl1.c @@ -1250,7 +1250,6 @@ static uint32_t gl1_get_flags(void *data) static const video_poke_interface_t gl1_poke_interface = { gl1_get_flags, - NULL, gl1_load_texture, gl1_unload_texture, gl1_set_video_mode, diff --git a/gfx/drivers/gl_core.c b/gfx/drivers/gl_core.c index 5ef082ddbb..ef3025e01e 100644 --- a/gfx/drivers/gl_core.c +++ b/gfx/drivers/gl_core.c @@ -1960,7 +1960,6 @@ static retro_proc_address_t gl_core_get_proc_address(void *data, const char *sym static const video_poke_interface_t gl_core_poke_interface = { gl_core_get_flags, - NULL, /* set_mvp */ gl_core_load_texture, gl_core_unload_texture, gl_core_set_video_mode, diff --git a/gfx/drivers/gx2_gfx.c b/gfx/drivers/gx2_gfx.c index 9c0e8354bc..544354f105 100644 --- a/gfx/drivers/gx2_gfx.c +++ b/gfx/drivers/gx2_gfx.c @@ -1717,7 +1717,6 @@ static uint32_t wiiu_gfx_get_flags(void *data) static const video_poke_interface_t wiiu_poke_interface = { wiiu_gfx_get_flags, - NULL, /* set_mvp */ wiiu_gfx_load_texture, wiiu_gfx_unload_texture, NULL, /* set_video_mode */ diff --git a/gfx/drivers/gx_gfx.c b/gfx/drivers/gx_gfx.c index 14438aa9c8..723f481419 100644 --- a/gfx/drivers/gx_gfx.c +++ b/gfx/drivers/gx_gfx.c @@ -1265,7 +1265,6 @@ static void gx_get_video_output_next(void *data) static const video_poke_interface_t gx_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, NULL, gx_set_video_mode, diff --git a/gfx/drivers/omap_gfx.c b/gfx/drivers/omap_gfx.c index 783a9a838e..c202f16ae3 100644 --- a/gfx/drivers/omap_gfx.c +++ b/gfx/drivers/omap_gfx.c @@ -1138,7 +1138,6 @@ static float omap_get_refresh_rate(void *data) static const video_poke_interface_t omap_gfx_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, NULL, NULL, diff --git a/gfx/drivers/ps2_gfx.c b/gfx/drivers/ps2_gfx.c index 4ef83f763a..ff6db846e0 100644 --- a/gfx/drivers/ps2_gfx.c +++ b/gfx/drivers/ps2_gfx.c @@ -470,7 +470,6 @@ static bool ps2_get_hw_render_interface(void* data, static const video_poke_interface_t ps2_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, NULL, NULL, diff --git a/gfx/drivers/psp1_gfx.c b/gfx/drivers/psp1_gfx.c index c05397797a..497b866319 100644 --- a/gfx/drivers/psp1_gfx.c +++ b/gfx/drivers/psp1_gfx.c @@ -832,7 +832,6 @@ static void psp_viewport_info(void *data, struct video_viewport *vp) static const video_poke_interface_t psp_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, NULL, NULL, diff --git a/gfx/drivers/sdl2_gfx.c b/gfx/drivers/sdl2_gfx.c index c7f73fe24f..dbd7a2467a 100644 --- a/gfx/drivers/sdl2_gfx.c +++ b/gfx/drivers/sdl2_gfx.c @@ -726,7 +726,6 @@ static void sdl2_grab_mouse_toggle(void *data) static video_poke_interface_t sdl2_video_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, NULL, NULL, diff --git a/gfx/drivers/sdl_gfx.c b/gfx/drivers/sdl_gfx.c index 914fa3d5dc..d2d7cbe932 100644 --- a/gfx/drivers/sdl_gfx.c +++ b/gfx/drivers/sdl_gfx.c @@ -518,7 +518,6 @@ static void sdl_grab_mouse_toggle(void *data) static const video_poke_interface_t sdl_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, NULL, NULL, diff --git a/gfx/drivers/sixel_gfx.c b/gfx/drivers/sixel_gfx.c index 10feb2d56f..e2c6724e4e 100644 --- a/gfx/drivers/sixel_gfx.c +++ b/gfx/drivers/sixel_gfx.c @@ -602,7 +602,6 @@ static const video_poke_interface_t sixel_poke_interface = { NULL, NULL, NULL, - NULL, sixel_set_video_mode, NULL, NULL, diff --git a/gfx/drivers/sunxi_gfx.c b/gfx/drivers/sunxi_gfx.c index b4d8390d01..3f72e4158c 100644 --- a/gfx/drivers/sunxi_gfx.c +++ b/gfx/drivers/sunxi_gfx.c @@ -944,7 +944,6 @@ static float sunxi_get_refresh_rate (void *data) static const video_poke_interface_t sunxi_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, NULL, NULL, /* set_video_mode */ diff --git a/gfx/drivers/switch_gfx.c b/gfx/drivers/switch_gfx.c index 04c442654c..cedad20ed9 100644 --- a/gfx/drivers/switch_gfx.c +++ b/gfx/drivers/switch_gfx.c @@ -406,7 +406,6 @@ static void switch_set_texture_enable(void *data, bool enable, bool full_screen) static const video_poke_interface_t switch_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, /* load_texture */ NULL, /* unload_texture */ NULL, /* set_video_mode */ diff --git a/gfx/drivers/switch_nx_gfx.c b/gfx/drivers/switch_nx_gfx.c index 8c7c603aa0..44cc61cfa8 100644 --- a/gfx/drivers/switch_nx_gfx.c +++ b/gfx/drivers/switch_nx_gfx.c @@ -755,7 +755,6 @@ void switch_overlay_interface(void *data, const video_overlay_interface_t **ifac static const video_poke_interface_t switch_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, /* load_texture */ NULL, /* unload_texture */ NULL, /* set_video_mode */ diff --git a/gfx/drivers/vga_gfx.c b/gfx/drivers/vga_gfx.c index 02db6a474f..4c1a96bb06 100644 --- a/gfx/drivers/vga_gfx.c +++ b/gfx/drivers/vga_gfx.c @@ -391,7 +391,6 @@ static void vga_set_osd_msg(void *data, static const video_poke_interface_t vga_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, NULL, NULL, diff --git a/gfx/drivers/vita2d_gfx.c b/gfx/drivers/vita2d_gfx.c index 4a3cbb33ae..b0436bc31a 100644 --- a/gfx/drivers/vita2d_gfx.c +++ b/gfx/drivers/vita2d_gfx.c @@ -790,7 +790,6 @@ static bool vita_get_current_sw_framebuffer(void *data, static const video_poke_interface_t vita_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ vita_load_texture, vita_unload_texture, NULL, diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index e35a875b77..b0a1b50191 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -2407,7 +2407,6 @@ static uint32_t vulkan_get_flags(void *data) static const video_poke_interface_t vulkan_poke_interface = { vulkan_get_flags, - NULL, /* set_mvp */ vulkan_load_texture, vulkan_unload_texture, vulkan_set_video_mode, diff --git a/gfx/drivers/xshm_gfx.c b/gfx/drivers/xshm_gfx.c index cfeda3481b..ed6033fae7 100644 --- a/gfx/drivers/xshm_gfx.c +++ b/gfx/drivers/xshm_gfx.c @@ -205,7 +205,6 @@ static void xshm_grab_mouse_toggle(void *data) static video_poke_interface_t xshm_video_poke_interface = { NULL, /* get_flags */ - NULL, /* set_mvp */ NULL, NULL, NULL, diff --git a/gfx/drivers/xvideo.c b/gfx/drivers/xvideo.c index 70fc2b5d27..e1016129fc 100644 --- a/gfx/drivers/xvideo.c +++ b/gfx/drivers/xvideo.c @@ -939,7 +939,6 @@ static video_poke_interface_t xv_video_poke_interface = { NULL, NULL, NULL, - NULL, x11_get_refresh_rate, NULL, NULL, diff --git a/gfx/video_driver.c b/gfx/video_driver.c index db87f6183f..84ddb15ac3 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -125,8 +125,6 @@ typedef struct video_pixel_scaler void *scaler_out; } video_pixel_scaler_t; -static bool (*video_driver_cb_shader_set_mvp)(void *data, - void *shader_data, const void *mat_data); bool (*video_driver_cb_has_focus)(void); /* Opaque handles to currently running window. @@ -2852,8 +2850,6 @@ void video_driver_build_info(video_frame_info_t *video_info) video_info->cb_get_metrics = current_video_context.get_metrics; video_info->cb_set_resize = current_video_context.set_resize; - video_info->cb_set_mvp = video_driver_cb_shader_set_mvp; - video_info->userdata = video_driver_get_ptr(false); #ifdef HAVE_THREADS @@ -3472,31 +3468,6 @@ bool video_shader_driver_deinit(void) return true; } -static bool video_driver_cb_set_mvp(void *data, - void *shader_data, const void *mat_data) -{ - video_shader_ctx_mvp_t mvp; - mvp.data = data; - mvp.matrix = mat_data; - - video_driver_set_mvp(&mvp); - return true; -} - -static void video_shader_driver_reset_to_defaults(void) -{ - if (!current_shader) - return; - - if (current_shader->set_mvp) - video_driver_cb_shader_set_mvp = current_shader->set_mvp; - else - { - current_shader->set_mvp = video_driver_cb_set_mvp; - video_driver_cb_shader_set_mvp = video_driver_cb_set_mvp; - } -} - /* Finds first suitable shader context driver. */ bool video_shader_driver_init_first(const void *data) { @@ -3504,7 +3475,6 @@ bool video_shader_driver_init_first(const void *data) if (!ptr) return false; current_shader = ptr; - video_shader_driver_reset_to_defaults(); return true; } @@ -3539,27 +3509,10 @@ bool video_shader_driver_init(video_shader_ctx_init_t *init) RARCH_LOG("Resetting shader to defaults ... \n"); current_shader = (shader_backend_t*)init->shader; - video_shader_driver_reset_to_defaults(); return true; } -void video_driver_set_mvp(video_shader_ctx_mvp_t *mvp) -{ - if (!mvp || !mvp->matrix) - return; - - if (current_shader && current_shader->set_mvp) - current_shader->set_mvp(mvp->data, - current_shader_data, mvp->matrix); - else - { - if (video_driver_poke && video_driver_poke->set_mvp) - video_driver_poke->set_mvp(mvp->data, - current_shader_data, mvp->matrix); - } -} - float video_driver_get_refresh_rate(void) { if (video_driver_poke && video_driver_poke->get_refresh_rate) diff --git a/gfx/video_driver.h b/gfx/video_driver.h index de35ab60b2..9affce35fa 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -492,9 +492,6 @@ typedef struct video_frame_info float *value); bool (*cb_set_resize)(void*, unsigned, unsigned); - bool (*cb_set_mvp)(void *data, void *shader_data, - const void *mat_data); - void *context_data; void *shader_data; void *userdata; @@ -691,8 +688,6 @@ struct aspect_ratio_elem typedef struct video_poke_interface { uint32_t (*get_flags)(void *data); - void (*set_mvp)(void *data, void *shader_data, - const void *mat_data); uintptr_t (*load_texture)(void *video_data, void *data, bool threaded, enum texture_filter_type filter_type); void (*unload_texture)(void *data, uintptr_t id); @@ -1196,8 +1191,6 @@ bool video_shader_driver_init_first(const void *data); bool video_shader_driver_init(video_shader_ctx_init_t *init); -void video_driver_set_mvp(video_shader_ctx_mvp_t *mvp); - float video_driver_get_refresh_rate(void); extern bool (*video_driver_cb_has_focus)(void); diff --git a/gfx/video_thread_wrapper.c b/gfx/video_thread_wrapper.c index 94f4b9f727..a7cf29b2d6 100644 --- a/gfx/video_thread_wrapper.c +++ b/gfx/video_thread_wrapper.c @@ -1241,7 +1241,6 @@ static uint32_t thread_get_flags(void *data) static const video_poke_interface_t thread_poke = { thread_get_flags, - NULL, /* set_mvp */ thread_load_texture, thread_unload_texture, thread_set_video_mode, diff --git a/menu/drivers_display/menu_display_d3d8.c b/menu/drivers_display/menu_display_d3d8.c index c4b0279553..f5189bed91 100644 --- a/menu/drivers_display/menu_display_d3d8.c +++ b/menu/drivers_display/menu_display_d3d8.c @@ -121,7 +121,6 @@ static void menu_display_d3d8_draw(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { unsigned i; - video_shader_ctx_mvp_t mvp; math_matrix_4x4 mop, m1, m2; unsigned width, height; d3d8_video_t *d3d = video_info ? @@ -212,9 +211,8 @@ static void menu_display_d3d8_draw(menu_display_ctx_draw_t *draw, matrix_4x4_multiply(m2, d3d->mvp_transposed, m1); d3d_matrix_transpose(&m1, &m2); - mvp.data = d3d; - mvp.matrix = &m1; - video_driver_set_mvp(&mvp); + d3d8_set_mvp(d3d->dev, &m1); + if (draw && draw->texture) menu_display_d3d8_bind_texture(draw, d3d); diff --git a/menu/drivers_display/menu_display_d3d9.c b/menu/drivers_display/menu_display_d3d9.c index 72a3ba8e65..003afb7062 100644 --- a/menu/drivers_display/menu_display_d3d9.c +++ b/menu/drivers_display/menu_display_d3d9.c @@ -122,7 +122,6 @@ static void menu_display_d3d9_draw(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { unsigned i; - video_shader_ctx_mvp_t mvp; math_matrix_4x4 mop, m1, m2; unsigned width, height; LPDIRECT3DDEVICE9 dev; @@ -205,9 +204,7 @@ static void menu_display_d3d9_draw(menu_display_ctx_draw_t *draw, matrix_4x4_multiply(m2, d3d->mvp_transposed, m1); d3d_matrix_transpose(&m1, &m2); - mvp.data = d3d; - mvp.matrix = &m1; - video_driver_set_mvp(&mvp); + d3d9_set_mvp(d3d->dev, &m1); if (draw && draw->texture) menu_display_d3d9_bind_texture(draw, d3d); From 27928081cff027327236c7e2d6864167980dedf5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 18 Mar 2019 15:27:37 +0100 Subject: [PATCH 048/237] Cleanups --- gfx/drivers/gl.c | 41 ++++++++------------------ gfx/drivers_font/gl_raster_font.c | 6 ++-- gfx/drivers_shader/shader_gl_cg.c | 5 ++-- gfx/drivers_shader/shader_glsl.c | 6 ++-- gfx/video_driver.h | 6 ++-- menu/drivers_display/menu_display_gl.c | 9 ++---- 6 files changed, 24 insertions(+), 49 deletions(-) diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index a1294b496f..e4d413b641 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -658,11 +658,8 @@ static void gl2_renderchain_render( gl->coords.vertices = 4; - gl->shader->set_coords(gl, - gl->shader_data, &gl->coords); - - gl->shader->set_mvp(gl, gl->shader_data, - &gl->mvp); + gl->shader->set_coords(gl->shader_data, &gl->coords); + gl->shader->set_mvp(gl->shader_data, &gl->mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -729,11 +726,8 @@ static void gl2_renderchain_render( gl->coords.vertices = 4; - gl->shader->set_coords(gl, - gl->shader_data, &gl->coords); - - gl->shader->set_mvp(gl, gl->shader_data, - &gl->mvp); + gl->shader->set_coords(gl->shader_data, &gl->coords); + gl->shader->set_mvp(gl->shader_data, &gl->mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -1986,11 +1980,8 @@ static void gl2_render_overlay(gl_t *gl, video_frame_info_t *video_info) gl->coords.color = gl->overlay_color_coord; gl->coords.vertices = 4 * gl->overlays; - gl->shader->set_coords(gl, - gl->shader_data, &gl->coords); - - gl->shader->set_mvp(gl, gl->shader_data, - &gl->mvp_no_rot); + gl->shader->set_coords(gl->shader_data, &gl->coords); + gl->shader->set_mvp(gl->shader_data, &gl->mvp_no_rot); for (i = 0; i < gl->overlays; i++) { @@ -2364,15 +2355,13 @@ static void gl2_render_osd_background( video_info->shader_driver->use(gl, video_info->shader_data, VIDEO_SHADER_STOCK_BLEND, true); - gl->shader->set_coords(gl, gl->shader_data, - &coords); + gl->shader->set_coords(gl->shader_data, &coords); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); - gl->shader->set_mvp(gl, gl->shader_data, - &gl->mvp_no_rot); + gl->shader->set_mvp(gl->shader_data, &gl->mvp_no_rot); uniform_param.type = UNIFORM_4F; uniform_param.enabled = true; @@ -2470,11 +2459,8 @@ static INLINE void gl2_draw_texture(gl_t *gl, video_frame_info_t *video_info) gl->coords.vertices = 4; - gl->shader->set_coords(gl, - gl->shader_data, &gl->coords); - - gl->shader->set_mvp(gl, gl->shader_data, - &gl->mvp_no_rot); + gl->shader->set_coords(gl->shader_data, &gl->coords); + gl->shader->set_mvp(gl->shader_data, &gl->mvp_no_rot); glEnable(GL_BLEND); @@ -2669,11 +2655,8 @@ static bool gl2_frame(void *data, const void *frame, gl->coords.vertices = 4; - gl->shader->set_coords(gl, - gl->shader_data, &gl->coords); - - gl->shader->set_mvp(gl, gl->shader_data, - &gl->mvp); + gl->shader->set_coords(gl->shader_data, &gl->coords); + gl->shader->set_mvp(gl->shader_data, &gl->mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); diff --git a/gfx/drivers_font/gl_raster_font.c b/gfx/drivers_font/gl_raster_font.c index 5eaf611df1..3f1fb18b51 100644 --- a/gfx/drivers_font/gl_raster_font.c +++ b/gfx/drivers_font/gl_raster_font.c @@ -255,10 +255,8 @@ static void gl_raster_font_draw_vertices(gl_raster_t *font, font->atlas->dirty = false; } - font->gl->shader->set_coords(font->gl, - font->gl->shader_data, coords); - - font->gl->shader->set_mvp(font->gl, font->gl->shader_data, + font->gl->shader->set_coords(font->gl->shader_data, coords); + font->gl->shader->set_mvp(font->gl->shader_data, &font->gl->mvp_no_rot); glDrawArrays(GL_TRIANGLES, 0, coords->vertices); diff --git a/gfx/drivers_shader/shader_gl_cg.c b/gfx/drivers_shader/shader_gl_cg.c index 250d2a6716..71e805b76e 100644 --- a/gfx/drivers_shader/shader_gl_cg.c +++ b/gfx/drivers_shader/shader_gl_cg.c @@ -244,7 +244,7 @@ static void gl_cg_reset_attrib(void *data) cg->attribs_index = 0; } -static bool gl_cg_set_mvp(void *data, void *shader_data, +static bool gl_cg_set_mvp(void *shader_data, const void *mat_data) { cg_shader_data_t *cg = (cg_shader_data_t*)shader_data; @@ -258,7 +258,8 @@ static bool gl_cg_set_mvp(void *data, void *shader_data, return false; } -static bool gl_cg_set_coords(void *handle_data, void *shader_data, const struct video_coords *coords) +static bool gl_cg_set_coords(void *shader_data, + const struct video_coords *coords) { cg_shader_data_t *cg = (cg_shader_data_t*)shader_data; diff --git a/gfx/drivers_shader/shader_glsl.c b/gfx/drivers_shader/shader_glsl.c index 7ea03027ac..3550074eae 100644 --- a/gfx/drivers_shader/shader_glsl.c +++ b/gfx/drivers_shader/shader_glsl.c @@ -1410,13 +1410,11 @@ static void gl_glsl_set_params(void *dat, void *shader_data) } } -static bool gl_glsl_set_mvp(void *data, void *shader_data, const void *mat_data) +static bool gl_glsl_set_mvp(void *shader_data, const void *mat_data) { int loc; glsl_shader_data_t *glsl = (glsl_shader_data_t*)shader_data; - (void)data; - if (!glsl || !glsl->shader->modern) return false; @@ -1448,7 +1446,7 @@ static bool gl_glsl_set_mvp(void *data, void *shader_data, const void *mat_data) buffer[y + size] = coord2[y]; \ size += multiplier * coords->vertices; \ -static bool gl_glsl_set_coords(void *handle_data, void *shader_data, +static bool gl_glsl_set_coords(void *shader_data, const struct video_coords *coords) { GLfloat short_buffer[4 * (2 + 2 + 4 + 2)]; diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 9affce35fa..1554ba559f 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -234,10 +234,8 @@ typedef struct shader_backend enum gfx_wrap_type (*wrap_type)(void *data, unsigned index); void (*shader_scale)(void *data, unsigned index, struct gfx_fbo_scale *scale); - bool (*set_coords)(void *handle_data, - void *shader_data, const struct video_coords *coords); - bool (*set_mvp)(void *data, void *shader_data, - const void *mat_data); + bool (*set_coords)(void *shader_data, const struct video_coords *coords); + bool (*set_mvp)(void *shader_data, const void *mat_data); unsigned (*get_prev_textures)(void *data); bool (*get_feedback_pass)(void *data, unsigned *pass); bool (*mipmap_input)(void *data, unsigned index); diff --git a/menu/drivers_display/menu_display_gl.c b/menu/drivers_display/menu_display_gl.c index 15158d84b2..2baa181da4 100644 --- a/menu/drivers_display/menu_display_gl.c +++ b/menu/drivers_display/menu_display_gl.c @@ -116,13 +116,10 @@ static void menu_display_gl_draw(menu_display_ctx_draw_t *draw, draw->coords->lut_tex_coord = menu_display_gl_get_default_tex_coords(); menu_display_gl_viewport(draw, video_info); - if (draw) - glBindTexture(GL_TEXTURE_2D, (GLuint)draw->texture); + glBindTexture(GL_TEXTURE_2D, (GLuint)draw->texture); - gl->shader->set_coords(gl, - gl->shader_data, draw->coords); - - gl->shader->set_mvp(gl, gl->shader_data, + gl->shader->set_coords(gl->shader_data, draw->coords); + gl->shader->set_mvp(gl->shader_data, draw->matrix_data ? (math_matrix_4x4*)draw->matrix_data : (math_matrix_4x4*)menu_display_gl_get_default_mvp(video_info)); From 819016b00ca648ebb84ac61ce7084e0bff006bf3 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 18 Mar 2019 15:52:21 +0100 Subject: [PATCH 049/237] Move video_shader_driver_init to gl.c --- gfx/drivers/gl.c | 112 +++++++++++++++++++++++++++++++++------------ gfx/video_driver.c | 97 --------------------------------------- gfx/video_driver.h | 8 ---- 3 files changed, 84 insertions(+), 133 deletions(-) diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index e4d413b641..a9958e909b 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -1971,9 +1971,8 @@ static void gl2_render_overlay(gl_t *gl, video_frame_info_t *video_info) glViewport(0, 0, width, height); /* Ensure that we reset the attrib array. */ - if (video_info->shader_driver && video_info->shader_driver->use) - video_info->shader_driver->use(gl, - video_info->shader_data, VIDEO_SHADER_STOCK_BLEND, true); + gl->shader->use(gl, gl->shader_data, + VIDEO_SHADER_STOCK_BLEND, true); gl->coords.vertex = gl->overlay_vertex_coord; gl->coords.tex_coord = gl->overlay_tex_coord; @@ -2012,6 +2011,76 @@ static void gl2_set_viewport_wrapper(void *data, unsigned viewport_width, } /* Shaders */ +static const shader_backend_t *gl_shader_driver_set_backend( + enum rarch_shader_type type) +{ + switch (type) + { + case RARCH_SHADER_CG: + { +#ifdef HAVE_CG + gfx_ctx_flags_t flags; + flags.flags = 0; + video_context_driver_get_flags(&flags); + + if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT)) + { + RARCH_ERR("[Shader driver]: Cg cannot be used with core" + " GL context. Trying to fall back to GLSL...\n"); + return gl_shader_driver_set_backend(RARCH_SHADER_GLSL); + } + + RARCH_LOG("[Shader driver]: Using Cg shader backend.\n"); + return &gl_cg_backend; +#else + break; +#endif + } + case RARCH_SHADER_GLSL: +#ifdef HAVE_GLSL + RARCH_LOG("[Shader driver]: Using GLSL shader backend.\n"); + return &gl_glsl_backend; +#else + break; +#endif + case RARCH_SHADER_HLSL: + case RARCH_SHADER_NONE: + default: + break; + } + + return NULL; +} + +static bool gl_shader_driver_init(video_shader_ctx_init_t *init) +{ + void *tmp = NULL; + settings_t *settings = config_get_ptr(); + + if (!init->shader || !init->shader->init) + { + init->shader = gl_shader_driver_set_backend(init->shader_type); + + if (!init->shader) + return false; + } + + tmp = init->shader->init(init->data, init->path); + + if (!tmp) + return false; + + if (string_is_equal(settings->arrays.menu_driver, "xmb") + && init->shader->init_menu_shaders) + { + RARCH_LOG("Setting up menu pipeline shaders for XMB ... \n"); + init->shader->init_menu_shaders(tmp); + } + + init->shader_data = tmp; + + return true; +} static bool gl2_shader_init(gl_t *gl, const gfx_ctx_driver_t *ctx_driver, struct retro_hw_render_callback *hwr @@ -2057,7 +2126,7 @@ static bool gl2_shader_init(gl_t *gl, const gfx_ctx_driver_t *ctx_driver, init_data.data = gl; init_data.path = shader_path; - if (video_shader_driver_init(&init_data)) + if (gl_shader_driver_init(&init_data)) { gl->shader = init_data.shader; gl->shader_data = init_data.shader_data; @@ -2069,7 +2138,7 @@ static bool gl2_shader_init(gl_t *gl, const gfx_ctx_driver_t *ctx_driver, init_data.shader = NULL; init_data.path = NULL; - ret = video_shader_driver_init(&init_data); + ret = gl_shader_driver_init(&init_data); gl->shader = init_data.shader; gl->shader_data = init_data.shader_data; @@ -2237,10 +2306,7 @@ static INLINE void gl2_set_shader_viewports(gl_t *gl) for (i = 0; i < 2; i++) { - if (video_info.shader_driver && video_info.shader_driver->use) - video_info.shader_driver->use(gl, - video_info.shader_data, i, true); - + gl->shader->use(gl, gl->shader_data, i, true); gl2_set_viewport(gl, &video_info, width, height, false, true); } @@ -2351,9 +2417,8 @@ static void gl2_render_osd_background( video_driver_set_viewport(video_info->width, video_info->height, true, false); - if (video_info->shader_driver && video_info->shader_driver->use) - video_info->shader_driver->use(gl, - video_info->shader_data, VIDEO_SHADER_STOCK_BLEND, true); + gl->shader->use(gl, gl->shader_data, + VIDEO_SHADER_STOCK_BLEND, true); gl->shader->set_coords(gl->shader_data, &coords); @@ -2453,9 +2518,8 @@ static INLINE void gl2_draw_texture(gl_t *gl, video_frame_info_t *video_info) glBindTexture(GL_TEXTURE_2D, gl->menu_texture); - if (video_info->shader_driver && video_info->shader_driver->use) - video_info->shader_driver->use(gl, - video_info->shader_data, VIDEO_SHADER_STOCK_BLEND, true); + gl->shader->use(gl, + gl->shader_data, VIDEO_SHADER_STOCK_BLEND, true); gl->coords.vertices = 4; @@ -2525,9 +2589,7 @@ static bool gl2_frame(void *data, const void *frame, if (gl->core_context_in_use) gl2_renderchain_bind_vao(chain); - if (video_info->shader_driver && video_info->shader_driver->use) - video_info->shader_driver->use(gl, - video_info->shader_data, 1, true); + gl->shader->use(gl, gl->shader_data, 1, true); #ifdef IOS /* Apparently the viewport is lost each frame, thanks Apple. */ @@ -2720,10 +2782,7 @@ static bool gl2_frame(void *data, const void *frame, /* Reset state which could easily mess up libretro core. */ if (gl->hw_render_fbo_init) { - if (video_info->shader_driver && video_info->shader_driver->use) - video_info->shader_driver->use(gl, - video_info->shader_data, 0, true); - + gl->shader->use(gl, gl->shader_data, 0, true); glBindTexture(GL_TEXTURE_2D, 0); } @@ -2821,7 +2880,6 @@ static void gl2_free(void *data) font_driver_free_osd(); gl->shader->deinit(gl->shader_data); - video_shader_driver_deinit(); glDeleteTextures(gl->textures, gl->texture); @@ -3430,7 +3488,7 @@ static void *gl2_init(const video_info_t *video, gl->shader = (shader_backend_t*)gl2_shader_ctx_drivers[0]; - if (!video_shader_driver_init_first(gl->shader)) + if (!gl->shader) { RARCH_ERR("[GL:]: Shader driver initialization failed.\n"); goto error; @@ -3665,8 +3723,6 @@ static bool gl2_set_shader(void *data, gl->shader->deinit(gl->shader_data); gl->shader_data = NULL; - video_shader_driver_deinit(); - switch (type) { #ifdef HAVE_GLSL @@ -3697,11 +3753,11 @@ static bool gl2_set_shader(void *data, init_data.data = gl; init_data.path = path; - if (!video_shader_driver_init(&init_data)) + if (!gl_shader_driver_init(&init_data)) { init_data.path = NULL; - video_shader_driver_init(&init_data); + gl_shader_driver_init(&init_data); gl->shader = init_data.shader; gl->shader_data = init_data.shader_data; diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 84ddb15ac3..378bdf493f 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -225,9 +225,6 @@ static gfx_ctx_flags_t deferred_flag_data = {0}; static bool video_started_fullscreen = false; -static shader_backend_t *current_shader = NULL; -static void *current_shader_data = NULL; - static char video_driver_gpu_device_string[128] = {0}; static char video_driver_gpu_api_version_string[128] = {0}; @@ -2842,8 +2839,6 @@ void video_driver_build_info(video_frame_info_t *video_info) video_info->input_driver_nonblock_state = input_driver_is_nonblock_state(); video_info->context_data = video_context_data; - video_info->shader_driver = current_shader; - video_info->shader_data = current_shader_data; video_info->cb_update_window_title = current_video_context.update_window_title; video_info->cb_swap_buffers = current_video_context.swap_buffers; @@ -3408,46 +3403,6 @@ bool video_driver_cached_frame_has_valid_framebuffer(void) return false; } -static const shader_backend_t *video_shader_set_backend( - enum rarch_shader_type type) -{ - switch (type) - { - case RARCH_SHADER_CG: - { -#ifdef HAVE_CG - gfx_ctx_flags_t flags; - flags.flags = 0; - video_context_driver_get_flags(&flags); - - if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT)) - { - RARCH_ERR("[Shader driver]: Cg cannot be used with core" - " GL context. Trying to fall back to GLSL...\n"); - return video_shader_set_backend(RARCH_SHADER_GLSL); - } - - RARCH_LOG("[Shader driver]: Using Cg shader backend.\n"); - return &gl_cg_backend; -#else - break; -#endif - } - case RARCH_SHADER_GLSL: -#ifdef HAVE_GLSL - RARCH_LOG("[Shader driver]: Using GLSL shader backend.\n"); - return &gl_glsl_backend; -#else - break; -#endif - case RARCH_SHADER_HLSL: - case RARCH_SHADER_NONE: - default: - break; - } - - return NULL; -} bool video_shader_driver_get_current_shader(video_shader_ctx_t *shader) { @@ -3461,58 +3416,6 @@ bool video_shader_driver_get_current_shader(video_shader_ctx_t *shader) return true; } -bool video_shader_driver_deinit(void) -{ - current_shader_data = NULL; - current_shader = NULL; - return true; -} - -/* Finds first suitable shader context driver. */ -bool video_shader_driver_init_first(const void *data) -{ - shader_backend_t *ptr = (shader_backend_t*)data; - if (!ptr) - return false; - current_shader = ptr; - return true; -} - -bool video_shader_driver_init(video_shader_ctx_init_t *init) -{ - void *tmp = NULL; - settings_t *settings = config_get_ptr(); - - if (!init->shader || !init->shader->init) - { - init->shader = video_shader_set_backend(init->shader_type); - - if (!init->shader) - return false; - } - - tmp = init->shader->init(init->data, init->path); - - if (!tmp) - return false; - - if (string_is_equal(settings->arrays.menu_driver, "xmb") - && init->shader->init_menu_shaders) - { - RARCH_LOG("Setting up menu pipeline shaders for XMB ... \n"); - init->shader->init_menu_shaders(tmp); - } - - init->shader_data = tmp; - current_shader_data = tmp; - - RARCH_LOG("Resetting shader to defaults ... \n"); - - current_shader = (shader_backend_t*)init->shader; - - return true; -} - float video_driver_get_refresh_rate(void) { if (video_driver_poke && video_driver_poke->get_refresh_rate) diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 1554ba559f..60d52dee69 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -491,9 +491,7 @@ typedef struct video_frame_info bool (*cb_set_resize)(void*, unsigned, unsigned); void *context_data; - void *shader_data; void *userdata; - const shader_backend_t *shader_driver; } video_frame_info_t; typedef void (*update_window_title_cb)(void*, void*); @@ -1183,12 +1181,6 @@ void video_context_driver_free(void); bool video_shader_driver_get_current_shader(video_shader_ctx_t *shader); -bool video_shader_driver_deinit(void); - -bool video_shader_driver_init_first(const void *data); - -bool video_shader_driver_init(video_shader_ctx_init_t *init); - float video_driver_get_refresh_rate(void); extern bool (*video_driver_cb_has_focus)(void); From 7c93da136062f672eecdffe9b466f6a1353e9d99 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 18 Mar 2019 15:57:43 +0100 Subject: [PATCH 050/237] (GL2) Simplifications --- gfx/drivers/gl.c | 38 ++++++++------------------------------ 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index a9958e909b..f3cb78aec5 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -267,13 +267,6 @@ static bool gl2_shader_scale(gl_t *gl, return true; } -static const char *gl2_shader_get_ident(gl_t *gl) -{ - if (!gl || !gl->shader) - return "N/A"; - return gl->shader->ident; -} - static void gl2_renderchain_convert_geometry( struct video_fbo_rect *fbo_rect, struct gfx_fbo_scale *fbo_scale, @@ -1610,28 +1603,15 @@ static void gl2_renderchain_copy_frame( #endif } -static void gl2_renderchain_bind_pbo(unsigned idx) -{ #if !defined(HAVE_OPENGLES2) && !defined(HAVE_PSGL) - glBindBuffer(GL_PIXEL_PACK_BUFFER, (GLuint)idx); +#define gl2_renderchain_bind_pbo(idx) glBindBuffer(GL_PIXEL_PACK_BUFFER, (GLuint)idx) +#define gl2_renderchain_unbind_pbo() glBindBuffer(GL_PIXEL_PACK_BUFFER, 0) +#define gl2_renderchain_init_pbo(size, data) glBufferData(GL_PIXEL_PACK_BUFFER, size, (const GLvoid*)data, GL_STREAM_READ) +#else +#define gl2_renderchain_bind_pbo(idx) +#define gl2_renderchain_unbind_pbo() +#define gl2_renderchain_init_pbo(size, data) #endif -} - -static void gl2_renderchain_unbind_pbo(void) -{ -#if !defined(HAVE_OPENGLES2) && !defined(HAVE_PSGL) - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); -#endif -} - -static void gl2_renderchain_init_pbo(unsigned size, - const void *data) -{ -#if !defined(HAVE_OPENGLES2) && !defined(HAVE_PSGL) - glBufferData(GL_PIXEL_PACK_BUFFER, size, - (const GLvoid*)data, GL_STREAM_READ); -#endif -} static void gl2_renderchain_readback( gl_t *gl, @@ -3494,9 +3474,7 @@ static void *gl2_init(const video_info_t *video, goto error; } - gl2_shader_get_ident(gl); - - RARCH_LOG("[GL]: Default shader backend found: %s.\n", gl2_shader_get_ident(gl)); + RARCH_LOG("[GL]: Default shader backend found: %s.\n", gl->shader->ident); if (!gl2_shader_init(gl, ctx_driver, hwr)) { From 794f9c89686dfbccc2597382d8c3ec6f0811b0b0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 18 Mar 2019 16:02:28 +0100 Subject: [PATCH 051/237] (GL) Add comments --- gfx/drivers/gl.c | 6 ++++++ gfx/drivers/gl1.c | 4 +++- gfx/drivers/gl_core.c | 6 ++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index f3cb78aec5..2b8c725ebe 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -15,6 +15,12 @@ * If not, see . */ +/* Middle of the road OpenGL driver. + * + * Minimum version (desktop): OpenGL 2.0+ + * Minimum version (mobile) : OpenGLES 2.0+ + */ + #ifdef _MSC_VER #pragma comment(lib, "opengl32") #endif diff --git a/gfx/drivers/gl1.c b/gfx/drivers/gl1.c index 77550ca204..5da24e03b5 100644 --- a/gfx/drivers/gl1.c +++ b/gfx/drivers/gl1.c @@ -15,7 +15,9 @@ * If not, see . */ -/* We are targeting a minimum of OpenGL 1.1 and the Microsoft "GDI Generic" software GL implementation. +/* OpenGL driver. + * + * We are targeting a minimum of OpenGL 1.1 and the Microsoft "GDI Generic" software GL implementation. * Any additional features added for later 1.x versions should only be enabled if they are detected at runtime. */ #include diff --git a/gfx/drivers/gl_core.c b/gfx/drivers/gl_core.c index ef3025e01e..63528444a3 100644 --- a/gfx/drivers/gl_core.c +++ b/gfx/drivers/gl_core.c @@ -13,6 +13,12 @@ * If not, see . */ +/* Modern OpenGL driver. + * + * Minimum version (desktop): OpenGL 3.2+ + * Minimum version (mobile) : OpenGLES 3.0+ + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif From 46dc4508f48ebb8c354c94855a75f0d969f7ef6f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 18 Mar 2019 16:32:46 +0100 Subject: [PATCH 052/237] Buildfix for Cg --- gfx/video_driver.c | 2 +- gfx/video_driver.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 378bdf493f..6cc2821ea4 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -3291,7 +3291,7 @@ bool video_context_driver_show_mouse(bool *bool_data) return true; } -static bool video_context_driver_get_flags(gfx_ctx_flags_t *flags) +bool video_context_driver_get_flags(gfx_ctx_flags_t *flags) { if (!current_video_context.get_flags) return false; diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 60d52dee69..a005e3dc87 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -1189,6 +1189,8 @@ bool video_driver_started_fullscreen(void); bool video_driver_is_threaded(void); +bool video_context_driver_get_flags(gfx_ctx_flags_t *flags); + bool video_driver_get_all_flags(gfx_ctx_flags_t *flags, enum display_flags flag); From 4fb95db80b9e8b37eaed21c70787157ede416be9 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 19 Mar 2019 04:32:36 +0100 Subject: [PATCH 053/237] Simplify video_driver_frame --- gfx/video_driver.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 6cc2821ea4..2a5b7fc190 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -2419,32 +2419,27 @@ void video_driver_frame(const void *data, unsigned width, if ((video_driver_frame_count % FPS_UPDATE_INTERVAL) == 0) { - char frames_text[64]; last_fps = TIME_TO_FPS(curr_time, new_time, FPS_UPDATE_INTERVAL); - if (video_info.fps_show || video_info.framecount_show) + strlcpy(video_driver_window_title, title, sizeof(video_driver_window_title)); + + if (video_info.fps_show) { - if (video_info.fps_show) - { - snprintf(video_info.fps_text, sizeof(video_info.fps_text), - " || FPS: %6.1f ", last_fps); - } - if (video_info.framecount_show) - { - snprintf(frames_text, - sizeof(frames_text), - " || Frames: %" PRIu64, - (uint64_t)video_driver_frame_count); - } - snprintf(video_driver_window_title, sizeof(video_driver_window_title), - "%s%s%s", title, - video_info.fps_show ? video_info.fps_text : "", - video_info.framecount_show ? frames_text : ""); + snprintf(video_info.fps_text, sizeof(video_info.fps_text), + " || FPS: %6.1f ", last_fps); + strlcat(video_driver_window_title, + video_info.fps_text, sizeof(video_driver_window_title)); } - else + + if (video_info.framecount_show) { - if (!string_is_equal(video_driver_window_title, title)) - strlcpy(video_driver_window_title, title, sizeof(video_driver_window_title)); + char frames_text[64]; + snprintf(frames_text, + sizeof(frames_text), + " || Frames: %" PRIu64, + (uint64_t)video_driver_frame_count); + strlcat(video_driver_window_title, + frames_text, sizeof(video_driver_window_title)); } curr_time = new_time; From e72c67bf8745ae8da79381629264b9e19078e739 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Tue, 19 Mar 2019 11:48:22 +0000 Subject: [PATCH 054/237] (RGUI) Add widescreen support --- config.def.h | 1 + configuration.c | 1 + configuration.h | 1 + cores/dynamic_dummy.c | 51 +++- intl/msg_hash_lbl.h | 2 + intl/msg_hash_us.h | 20 ++ menu/cbs/menu_cbs_sublabel.c | 4 + menu/drivers/rgui.c | 494 +++++++++++++++++++++++------------ menu/menu_defines.h | 8 + menu/menu_displaylist.c | 4 + menu/menu_setting.c | 48 ++++ msg_hash.h | 5 + 12 files changed, 466 insertions(+), 173 deletions(-) diff --git a/config.def.h b/config.def.h index 5164432321..451964cb52 100644 --- a/config.def.h +++ b/config.def.h @@ -388,6 +388,7 @@ static unsigned rgui_thumbnail_downscaler = RGUI_THUMB_SCALE_POINT; static bool rgui_lock_aspect = false; static unsigned rgui_internal_upscale_level = RGUI_UPSCALE_NONE; static bool rgui_full_width_layout = true; +static unsigned rgui_aspect = RGUI_ASPECT_RATIO_4_3; #else static bool default_block_config_read = false; diff --git a/configuration.c b/configuration.c index e779600a69..5ff9b1b3f2 100644 --- a/configuration.c +++ b/configuration.c @@ -1694,6 +1694,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("rgui_menu_color_theme", &settings->uints.menu_rgui_color_theme, true, rgui_color_theme, false); SETTING_UINT("rgui_thumbnail_downscaler", &settings->uints.menu_rgui_thumbnail_downscaler, true, rgui_thumbnail_downscaler, false); SETTING_UINT("rgui_internal_upscale_level", &settings->uints.menu_rgui_internal_upscale_level, true, rgui_internal_upscale_level, false); + SETTING_UINT("rgui_aspect_ratio", &settings->uints.menu_rgui_aspect_ratio, true, rgui_aspect, false); #endif #ifdef HAVE_LIBNX SETTING_UINT("split_joycon_p1", &settings->uints.input_split_joycon[0], true, 0, false); diff --git a/configuration.h b/configuration.h index 6e8cd1ad2c..82e3729aa4 100644 --- a/configuration.h +++ b/configuration.h @@ -443,6 +443,7 @@ typedef struct settings unsigned menu_font_color_green; unsigned menu_font_color_blue; unsigned menu_rgui_internal_upscale_level; + unsigned menu_rgui_aspect_ratio; unsigned menu_ticker_type; unsigned playlist_show_inline_core_name; diff --git a/cores/dynamic_dummy.c b/cores/dynamic_dummy.c index d456c4ed01..6b5db0bff1 100644 --- a/cores/dynamic_dummy.c +++ b/cores/dynamic_dummy.c @@ -21,10 +21,19 @@ #include +#if defined(HAVE_MENU) && defined(HAVE_RGUI) +#include +#include "../configuration.h" +#include "../menu/menu_defines.h" +#endif + #include "internal_cores.h" static uint16_t *dummy_frame_buf; +static uint16_t frame_buf_width; +static uint16_t frame_buf_height; + #if defined(HAVE_LIBNX) && defined(HAVE_STATIC_DUMMY) void retro_init(void) { libretro_dummy_retro_init(); } void retro_deinit(void) { libretro_dummy_retro_deinit(); } @@ -55,10 +64,36 @@ void retro_cheat_set(unsigned idx, bool enabled, const char *code) { libretro_du void libretro_dummy_retro_init(void) { +#if defined(HAVE_MENU) && defined(HAVE_RGUI) + settings_t *settings = config_get_ptr(); +#endif unsigned i; - dummy_frame_buf = (uint16_t*)calloc(320 * 240, sizeof(uint16_t)); - for (i = 0; i < 320 * 240; i++) + /* Sensible defaults */ + frame_buf_width = 320; + frame_buf_height = 240; + +#if defined(HAVE_MENU) && defined(HAVE_RGUI) + if (string_is_equal(settings->arrays.menu_driver, "rgui")) + { + switch (settings->uints.menu_rgui_aspect_ratio) + { + case RGUI_ASPECT_RATIO_16_9: + frame_buf_width = 426; + break; + case RGUI_ASPECT_RATIO_16_10: + frame_buf_width = 384; + break; + default: + /* 4:3 */ + frame_buf_width = 320; + break; + } + } +#endif + + dummy_frame_buf = (uint16_t*)calloc(frame_buf_width * frame_buf_height, sizeof(uint16_t)); + for (i = 0; i < frame_buf_width * frame_buf_height; i++) dummy_frame_buf[i] = 4 << 5; } @@ -109,11 +144,11 @@ void libretro_dummy_retro_get_system_av_info( info->timing.fps = refresh_rate; info->timing.sample_rate = 30000.0; - info->geometry.base_width = 320; - info->geometry.base_height = 240; - info->geometry.max_width = 320; - info->geometry.max_height = 240; - info->geometry.aspect_ratio = 4.0 / 3.0; + info->geometry.base_width = frame_buf_width; + info->geometry.base_height = frame_buf_height; + info->geometry.max_width = frame_buf_width; + info->geometry.max_height = frame_buf_height; + info->geometry.aspect_ratio = (float)frame_buf_width / (float)frame_buf_height; } void libretro_dummy_retro_set_environment(retro_environment_t cb) @@ -158,7 +193,7 @@ void libretro_dummy_retro_reset(void) void libretro_dummy_retro_run(void) { dummy_input_poll_cb(); - dummy_video_cb(dummy_frame_buf, 320, 240, 640); + dummy_video_cb(dummy_frame_buf, frame_buf_width, frame_buf_height, 2 * frame_buf_width); } /* This should never be called, it's only used as a placeholder. */ diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 4ff5531de8..aa62858979 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1609,6 +1609,8 @@ MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_LOCK_ASPECT, "menu_rgui_lock_aspect") MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL, "rgui_internal_upscale_level") +MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO, + "rgui_aspect_ratio") MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT, "menu_rgui_full_width_layout") MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_REWIND, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index ec89eef333..461965bb9e 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3022,6 +3022,18 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_RGUI_UPSCALE_X9, "x9" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_4_3, + "4:3" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_9, + "16:9" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_10, + "16:10" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, "Thumbnails" @@ -6808,6 +6820,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL, "Upscale menu interface before drawing to screen. When used with 'Menu Linear Filter' enabled, removes scaling artefacts (uneven pixels) while maintaining a sharp image. Has a significant performance impact that increases with upscaling level." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_RGUI_ASPECT_RATIO, + "Menu Aspect Ratio" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_RGUI_ASPECT_RATIO, + "Select menu aspect ratio. Widescreen ratios increase the horizontal resolution of the menu interface. (May require a restart if 'Lock Menu Aspect Ratio' is disabled)" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MENU_RGUI_FULL_WIDTH_LAYOUT, "Use Full-Width Layout" diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 108446b63c..48d73cc31c 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -528,6 +528,7 @@ default_sublabel_macro(action_bind_sublabel_content_runtime_log, default_sublabel_macro(action_bind_sublabel_content_runtime_log_aggregate, MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG_AGGREGATE) default_sublabel_macro(action_bind_sublabel_playlist_sublabel_runtime_type, MENU_ENUM_SUBLABEL_PLAYLIST_SUBLABEL_RUNTIME_TYPE) default_sublabel_macro(action_bind_sublabel_menu_rgui_internal_upscale_level, MENU_ENUM_SUBLABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL) +default_sublabel_macro(action_bind_sublabel_menu_rgui_aspect_ratio, MENU_ENUM_SUBLABEL_MENU_RGUI_ASPECT_RATIO) default_sublabel_macro(action_bind_sublabel_menu_ticker_type, MENU_ENUM_SUBLABEL_MENU_TICKER_TYPE) default_sublabel_macro(action_bind_sublabel_menu_ticker_speed, MENU_ENUM_SUBLABEL_MENU_TICKER_SPEED) default_sublabel_macro(action_bind_sublabel_playlist_show_inline_core_name, MENU_ENUM_SUBLABEL_PLAYLIST_SHOW_INLINE_CORE_NAME) @@ -2410,6 +2411,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_internal_upscale_level); break; + case MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_aspect_ratio); + break; case MENU_ENUM_LABEL_MENU_TICKER_TYPE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_ticker_type); break; diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 032e3aab5f..7ab929ed11 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -58,15 +58,33 @@ #include "../../tasks/tasks_internal.h" #include -#define RGUI_TERM_START_X(width) (width / 21) -#define RGUI_TERM_START_Y(height) (height / 9) -#define RGUI_TERM_WIDTH(width) (((width - RGUI_TERM_START_X(width) - RGUI_TERM_START_X(width)) / (FONT_WIDTH_STRIDE))) -#define RGUI_TERM_HEIGHT(width, height) (((height - RGUI_TERM_START_Y(height) - RGUI_TERM_START_X(width)) / (FONT_HEIGHT_STRIDE)) - 1) +#if defined(GEKKO) +#define RGUI_TERM_START_X(fb_width) (width / 21) +#define RGUI_TERM_START_Y(fb_height) (height / 9) +#define RGUI_TERM_WIDTH(fb_width) (((width - RGUI_TERM_START_X(width) - RGUI_TERM_START_X(width)) / (FONT_WIDTH_STRIDE))) +#define RGUI_TERM_HEIGHT(fb_height) (((height - RGUI_TERM_START_Y(height) - RGUI_TERM_START_Y(height)) / (FONT_HEIGHT_STRIDE))) +#else +#define RGUI_TERM_START_X(fb_width) rgui_term_layout.start_x +#define RGUI_TERM_START_Y(fb_height) rgui_term_layout.start_y +#define RGUI_TERM_WIDTH(fb_width) rgui_term_layout.width +#define RGUI_TERM_HEIGHT(fb_height) rgui_term_layout.height +#endif #define RGUI_ENTRY_VALUE_MAXLEN 19 #define RGUI_TICKER_SPACER " | " +typedef struct +{ + unsigned start_x; + unsigned start_y; + unsigned width; + unsigned height; + unsigned value_maxlen; +} rgui_term_layout_t; + +static rgui_term_layout_t rgui_term_layout = {0}; + typedef struct { uint32_t hover_color; @@ -431,20 +449,19 @@ typedef struct char theme_preset_path[PATH_MAX_LENGTH]; /* Must be a fixed length array... */ char menu_title[255]; /* Must be a fixed length array... */ char menu_sublabel[255]; /* Must be a fixed length array... */ - unsigned content_aspect_ratio; + unsigned menu_aspect_ratio; + unsigned menu_aspect_ratio_idx; + unsigned content_aspect_ratio_idx; struct scaler_ctx image_scaler; } rgui_t; -#define THUMB_MAX_WIDTH 320 -#define THUMB_MAX_HEIGHT 240 - typedef struct { unsigned width; unsigned height; bool is_valid; char *path; - uint16_t data[THUMB_MAX_WIDTH * THUMB_MAX_HEIGHT]; + uint16_t *data; } thumbnail_t; static thumbnail_t thumbnail = { @@ -452,25 +469,20 @@ static thumbnail_t thumbnail = { 0, false, NULL, - {0} + NULL }; -/* Identical to thumbnail max width/height, but cannot - * assume this will always be the case... */ -#define WALLPAPER_WIDTH 320 -#define WALLPAPER_HEIGHT 240 - typedef struct { bool is_valid; char *path; - uint16_t data[WALLPAPER_WIDTH * WALLPAPER_HEIGHT]; + uint16_t *data; } wallpaper_t; static wallpaper_t wallpaper = { false, NULL, - {0} + NULL }; typedef struct @@ -478,15 +490,19 @@ typedef struct unsigned width; unsigned height; uint16_t *data; -} upscale_buf_t; +} frame_buf_t; -static upscale_buf_t upscale_buf = { +static frame_buf_t rgui_frame_buf = { 0, 0, NULL }; -static uint16_t *rgui_framebuf_data = NULL; +static frame_buf_t rgui_upscale_buf = { + 0, + 0, + NULL +}; #if defined(PS2) @@ -635,16 +651,16 @@ static void process_wallpaper(rgui_t *rgui, struct texture_image *image) unsigned x, y; /* Sanity check */ - if (!image->pixels || (image->width != WALLPAPER_WIDTH) || (image->height != WALLPAPER_HEIGHT)) + if (!image->pixels || (image->width != rgui_frame_buf.width) || (image->height != rgui_frame_buf.height) || !wallpaper.data) return; /* Copy image to wallpaper buffer, performing pixel format conversion */ - for (x = 0; x < WALLPAPER_WIDTH; x++) + for (x = 0; x < rgui_frame_buf.width; x++) { - for (y = 0; y < WALLPAPER_HEIGHT; y++) + for (y = 0; y < rgui_frame_buf.height; y++) { - wallpaper.data[x + (y * WALLPAPER_WIDTH)] = - argb32_to_pixel_platform_format(image->pixels[x + (y * WALLPAPER_WIDTH)]); + wallpaper.data[x + (y * rgui_frame_buf.width)] = + argb32_to_pixel_platform_format(image->pixels[x + (y * rgui_frame_buf.width)]); } } @@ -694,23 +710,23 @@ static bool downscale_thumbnail(rgui_t *rgui, struct texture_image *image_src, s settings_t *settings = config_get_ptr(); /* Determine output dimensions */ - static const float display_aspect_ratio = (float)THUMB_MAX_WIDTH / (float)THUMB_MAX_HEIGHT; + float display_aspect_ratio = (float)rgui_frame_buf.width / (float)rgui_frame_buf.height; float aspect_ratio = (float)image_src->width / (float)image_src->height; if (aspect_ratio > display_aspect_ratio) { - image_dst->width = THUMB_MAX_WIDTH; - image_dst->height = image_src->height * THUMB_MAX_WIDTH / image_src->width; + image_dst->width = rgui_frame_buf.width; + image_dst->height = image_src->height * rgui_frame_buf.width / image_src->width; /* Account for any possible rounding errors... */ image_dst->height = (image_dst->height < 1) ? 1 : image_dst->height; - image_dst->height = (image_dst->height > THUMB_MAX_HEIGHT) ? THUMB_MAX_HEIGHT : image_dst->height; + image_dst->height = (image_dst->height > rgui_frame_buf.height) ? rgui_frame_buf.height : image_dst->height; } else { - image_dst->height = THUMB_MAX_HEIGHT; - image_dst->width = image_src->width * THUMB_MAX_HEIGHT / image_src->height; + image_dst->height = rgui_frame_buf.height; + image_dst->width = image_src->width * rgui_frame_buf.height / image_src->height; /* Account for any possible rounding errors... */ image_dst->width = (image_dst->width < 1) ? 1 : image_dst->width; - image_dst->width = (image_dst->width > THUMB_MAX_WIDTH) ? THUMB_MAX_WIDTH : image_dst->width; + image_dst->width = (image_dst->width > rgui_frame_buf.width) ? rgui_frame_buf.width : image_dst->width; } /* Allocate pixel buffer */ @@ -806,11 +822,11 @@ static void process_thumbnail(rgui_t *rgui, struct texture_image *image_src) return; /* Sanity check */ - if (!image_src->pixels || (image_src->width < 1) || (image_src->height < 1)) + if (!image_src->pixels || (image_src->width < 1) || (image_src->height < 1) || !thumbnail.data) return; /* Downscale thumbnail if it exceeds maximum size limits */ - if ((image_src->width > THUMB_MAX_WIDTH) || (image_src->height > THUMB_MAX_HEIGHT)) + if ((image_src->width > rgui_frame_buf.width) || (image_src->height > rgui_frame_buf.height)) { if (!downscale_thumbnail(rgui, image_src, &image_resampled)) return; @@ -879,16 +895,16 @@ static bool rgui_render_wallpaper(void) size_t fb_pitch; unsigned fb_width, fb_height; - if (wallpaper.is_valid && rgui_framebuf_data) + if (wallpaper.is_valid && rgui_frame_buf.data && wallpaper.data) { menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch); /* Sanity check */ - if ((fb_width != WALLPAPER_WIDTH) || (fb_height != WALLPAPER_HEIGHT) || (fb_pitch != WALLPAPER_WIDTH << 1)) + if ((fb_width != rgui_frame_buf.width) || (fb_height != rgui_frame_buf.height) || (fb_pitch != rgui_frame_buf.width << 1)) return false; /* Copy wallpaper to framebuffer */ - memcpy(rgui_framebuf_data, wallpaper.data, WALLPAPER_WIDTH * WALLPAPER_HEIGHT * sizeof(uint16_t)); + memcpy(rgui_frame_buf.data, wallpaper.data, rgui_frame_buf.width * rgui_frame_buf.height * sizeof(uint16_t)); return true; } @@ -905,7 +921,7 @@ static void rgui_render_thumbnail(void) unsigned thumb_x_offset, thumb_y_offset; unsigned width, height; - if (thumbnail.is_valid && rgui_framebuf_data) + if (thumbnail.is_valid && rgui_frame_buf.data && thumbnail.data) { menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch); @@ -944,7 +960,7 @@ static void rgui_render_thumbnail(void) { for (x = 0; x < width; x++) { - rgui_framebuf_data[(y + fb_y_offset) * (fb_pitch >> 1) + (x + fb_x_offset)] = + rgui_frame_buf.data[(y + fb_y_offset) * (fb_pitch >> 1) + (x + fb_x_offset)] = thumbnail.data[(x + thumb_x_offset) + ((y + thumb_y_offset) * thumbnail.width)]; } } @@ -1028,13 +1044,30 @@ static const rgui_theme_t *get_theme(rgui_t *rgui) static void load_custom_theme(rgui_t *rgui, rgui_theme_t *theme_colors, const char *theme_path) { + settings_t *settings = config_get_ptr(); config_file_t *conf = NULL; + char *wallpaper_key = NULL; unsigned normal_color, hover_color, title_color, bg_dark_color, bg_light_color, border_dark_color, border_light_color; char wallpaper_file[PATH_MAX_LENGTH]; bool success = false; + /* Determine which type of wallpaper to load */ + switch (settings->uints.menu_rgui_aspect_ratio) + { + case RGUI_ASPECT_RATIO_16_9: + wallpaper_key = "rgui_wallpaper_16_9"; + break; + case RGUI_ASPECT_RATIO_16_10: + wallpaper_key = "rgui_wallpaper_16_10"; + break; + default: + /* 4:3 */ + wallpaper_key = "rgui_wallpaper"; + break; + } + wallpaper_file[0] = '\0'; /* Sanity check */ @@ -1070,7 +1103,7 @@ static void load_custom_theme(rgui_t *rgui, rgui_theme_t *theme_colors, const ch if(!config_get_hex(conf, "rgui_border_light_color", &border_light_color)) goto end; - config_get_array(conf, "rgui_wallpaper", wallpaper_file, sizeof(wallpaper_file)); + config_get_array(conf, wallpaper_key, wallpaper_file, sizeof(wallpaper_file)); success = true; @@ -1214,7 +1247,7 @@ static void blit_line(int x, int y, bool col = (font_fb[FONT_OFFSET(symbol) + offset] & rem); if (col) - rgui_framebuf_data[(y + j) * (pitch >> 1) + (x + i)] = color; + rgui_frame_buf.data[(y + j) * (pitch >> 1) + (x + i)] = color; } } @@ -1307,8 +1340,8 @@ static void rgui_render_background(rgui_t *rgui) pitch_in_pixels = fb_pitch >> 1; size = fb_pitch * 4; - src = rgui_framebuf_data + pitch_in_pixels * fb_height; - dst = rgui_framebuf_data; + src = rgui_frame_buf.data + pitch_in_pixels * fb_height; + dst = rgui_frame_buf.data; while (dst < src) { @@ -1319,16 +1352,16 @@ static void rgui_render_background(rgui_t *rgui) /* Skip drawing border if we are currently showing a thumbnail */ if (!(rgui->show_thumbnail && rgui->entry_has_thumbnail && (thumbnail.is_valid || (rgui->thumbnail_queue_size > 0)))) { - if (rgui_framebuf_data) + if (rgui_frame_buf.data) { settings_t *settings = config_get_ptr(); if (settings->bools.menu_rgui_border_filler_enable) { - rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, 5, 5, fb_width - 10, 5, rgui_border_filler); - rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, 5, fb_height - 10, fb_width - 10, 5, rgui_border_filler); - rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, 5, 5, 5, fb_height - 10, rgui_border_filler); - rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, fb_width - 10, 5, 5, fb_height - 10, rgui_border_filler); + rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, 5, 5, fb_width - 10, 5, rgui_border_filler); + rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, 5, fb_height - 10, fb_width - 10, 5, rgui_border_filler); + rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, 5, 5, 5, fb_height - 10, rgui_border_filler); + rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, fb_width - 10, 5, 5, fb_height - 10, rgui_border_filler); } } } @@ -1397,16 +1430,16 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) x = (fb_width - width) / 2; y = (fb_height - height) / 2; - if (rgui_framebuf_data) + if (rgui_frame_buf.data) { - rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, x + 5, y + 5, width - 10, height - 10, rgui_bg_filler); + rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x + 5, y + 5, width - 10, height - 10, rgui_bg_filler); if (settings->bools.menu_rgui_border_filler_enable) { - rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, x, y, width - 5, 5, rgui_border_filler); - rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, x + width - 5, y, 5, height - 5, rgui_border_filler); - rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, x + 5, y + height - 5, width - 5, 5, rgui_border_filler); - rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, x, y + 5, 5, height - 5, rgui_border_filler); + rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x, y, width - 5, 5, rgui_border_filler); + rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x + width - 5, y, 5, height - 5, rgui_border_filler); + rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x + 5, y + height - 5, width - 5, 5, rgui_border_filler); + rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x, y + 5, 5, height - 5, rgui_border_filler); } } @@ -1416,7 +1449,7 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) int offset_x = (int)(FONT_WIDTH_STRIDE * (glyphs_width - utf8len(msg)) / 2); int offset_y = (int)(FONT_HEIGHT_STRIDE * i); - if (rgui_framebuf_data) + if (rgui_frame_buf.data) blit_line(x + 8 + offset_x, y + 8 + offset_y, msg, rgui->colors.normal_color); } @@ -1434,36 +1467,10 @@ static void rgui_blit_cursor(void) menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch); - if (rgui_framebuf_data) + if (rgui_frame_buf.data) { - rgui_color_rect(rgui_framebuf_data, fb_pitch, fb_width, fb_height, x, y - 5, 1, 11, 0xFFFF); - rgui_color_rect(rgui_framebuf_data, fb_pitch, fb_width, fb_height, x - 5, y, 11, 1, 0xFFFF); - } -} - -static void rgui_frame(void *data, video_frame_info_t *video_info) -{ - rgui_t *rgui = (rgui_t*)data; - settings_t *settings = config_get_ptr(); - - if ((settings->bools.menu_rgui_background_filler_thickness_enable != rgui->bg_thickness) || - (settings->bools.menu_rgui_border_filler_thickness_enable != rgui->border_thickness) - ) - rgui->bg_modified = true; - - rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable; - rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; - - if (settings->uints.menu_rgui_color_theme != rgui->color_theme) - { - prepare_rgui_colors(rgui, settings); - } - else if (settings->uints.menu_rgui_color_theme == RGUI_THEME_CUSTOM) - { - if (string_is_not_equal_fast(settings->paths.path_rgui_theme_preset, rgui->theme_preset_path, sizeof(rgui->theme_preset_path))) - { - prepare_rgui_colors(rgui, settings); - } + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, x, y - 5, 1, 11, 0xFFFF); + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, x - 5, y, 11, 1, 0xFFFF); } } @@ -1505,9 +1512,9 @@ static void rgui_render(void *data, bool is_idle) /* if the framebuffer changed size, recache the background */ if (rgui->bg_modified || rgui->last_width != fb_width || rgui->last_height != fb_height) { - if (rgui_framebuf_data) + if (rgui_frame_buf.data) { - rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, 0, fb_height, fb_width, 4, rgui_bg_filler); + rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, 0, fb_height, fb_width, 4, rgui_bg_filler); } rgui->last_width = fb_width; rgui->last_height = fb_height; @@ -1560,13 +1567,13 @@ static void rgui_render(void *data, bool is_idle) } /* Do not scroll if all items are visible. */ - if (menu_entries_get_size() <= RGUI_TERM_HEIGHT(fb_width, fb_height)) + if (menu_entries_get_size() <= RGUI_TERM_HEIGHT(fb_height)) { size_t start = 0; menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &start); } - bottom = (int)(menu_entries_get_size() - RGUI_TERM_HEIGHT(fb_width, fb_height)); + bottom = (int)(menu_entries_get_size() - RGUI_TERM_HEIGHT(fb_height)); menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &old_start); if (old_start > (unsigned)bottom) @@ -1576,8 +1583,8 @@ static void rgui_render(void *data, bool is_idle) entries_end = menu_entries_get_size(); - end = ((old_start + RGUI_TERM_HEIGHT(fb_width, fb_height)) <= (entries_end)) ? - old_start + RGUI_TERM_HEIGHT(fb_width, fb_height) : entries_end; + end = ((old_start + RGUI_TERM_HEIGHT(fb_height)) <= (entries_end)) ? + old_start + RGUI_TERM_HEIGHT(fb_height) : entries_end; /* Render wallpaper or 'normal' background */ if (rgui->show_wallpaper && wallpaper.is_valid) @@ -1628,10 +1635,10 @@ static void rgui_render(void *data, bool is_idle) title_width = utf8len(thumbnail_title_buf) * FONT_WIDTH_STRIDE; title_x = RGUI_TERM_START_X(fb_width) + ((RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE) - title_width) / 2; - if (rgui_framebuf_data) + if (rgui_frame_buf.data) { /* Draw thumbnail title background */ - rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, + rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, title_x - 5, 0, title_width + 10, FONT_HEIGHT_STRIDE, rgui_bg_filler); /* Draw thumbnail title */ @@ -1643,7 +1650,8 @@ static void rgui_render(void *data, bool is_idle) { /* No thumbnail - render usual text */ char title_buf[255]; - unsigned timedate_x = RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE - RGUI_TERM_START_X(fb_width); + unsigned timedate_x = (RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE)) - + (5 * FONT_WIDTH_STRIDE); unsigned core_name_len = ((timedate_x - RGUI_TERM_START_X(fb_width)) / FONT_WIDTH_STRIDE) - 3; /* Print title */ @@ -1658,11 +1666,11 @@ static void rgui_render(void *data, bool is_idle) string_to_upper(title_buf); - if (rgui_framebuf_data) + if (rgui_frame_buf.data) blit_line( (int)(RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) - utf8len(title_buf)) * FONT_WIDTH_STRIDE / 2), - RGUI_TERM_START_X(fb_width), + RGUI_TERM_START_Y(fb_height) - FONT_HEIGHT_STRIDE, title_buf, rgui->colors.title_color); /* Print menu entries */ @@ -1712,7 +1720,8 @@ static void rgui_render(void *data, bool is_idle) { /* Resize fields according to actual length of value string */ entry_value_len = strlen(entry_value); - entry_value_len = entry_value_len > RGUI_ENTRY_VALUE_MAXLEN ? RGUI_ENTRY_VALUE_MAXLEN : entry_value_len; + entry_value_len = entry_value_len > rgui_term_layout.value_maxlen ? + rgui_term_layout.value_maxlen : entry_value_len; } else { @@ -1765,7 +1774,7 @@ static void rgui_render(void *data, bool is_idle) entry_title_buf); } - if (rgui_framebuf_data) + if (rgui_frame_buf.data) blit_line(x, y, message, entry_selected ? rgui->colors.hover_color : rgui->colors.normal_color); @@ -1786,10 +1795,10 @@ static void rgui_render(void *data, bool is_idle) menu_animation_ticker(&ticker); - if (rgui_framebuf_data) + if (rgui_frame_buf.data) blit_line( RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, - (RGUI_TERM_HEIGHT(fb_width, fb_height) * FONT_HEIGHT_STRIDE) + + (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, sublabel_buf, rgui->colors.hover_color); } else if (settings->bools.menu_core_enable) @@ -1807,10 +1816,10 @@ static void rgui_render(void *data, bool is_idle) menu_animation_ticker(&ticker); - if (rgui_framebuf_data) + if (rgui_frame_buf.data) blit_line( RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, - (RGUI_TERM_HEIGHT(fb_width, fb_height) * FONT_HEIGHT_STRIDE) + + (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, core_title_buf, rgui->colors.hover_color); } } @@ -1829,10 +1838,10 @@ static void rgui_render(void *data, bool is_idle) menu_display_timedate(&datetime); - if (rgui_framebuf_data) + if (rgui_frame_buf.data) blit_line( timedate_x, - (RGUI_TERM_HEIGHT(fb_width, fb_height) * FONT_HEIGHT_STRIDE) + + (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, timedate, rgui->colors.hover_color); } } @@ -1868,9 +1877,144 @@ static void rgui_render(void *data, bool is_idle) static void rgui_framebuffer_free(void) { - if (rgui_framebuf_data) - free(rgui_framebuf_data); - rgui_framebuf_data = NULL; + if (rgui_frame_buf.data) + free(rgui_frame_buf.data); + rgui_frame_buf.data = NULL; +} + +static void rgui_thumbnail_free(void) +{ + thumbnail.width = 0; + thumbnail.height = 0; + thumbnail.is_valid = false; + + if (!string_is_empty(thumbnail.path)) + free(thumbnail.path); + thumbnail.path = NULL; + + if (thumbnail.data) + free(thumbnail.data); + thumbnail.data = NULL; +} + +static void rgui_wallpaper_free(void) +{ + wallpaper.is_valid = false; + + if (!string_is_empty(wallpaper.path)) + free(wallpaper.path); + wallpaper.path = NULL; + + if (wallpaper.data) + free(wallpaper.data); + wallpaper.data = NULL; +} + +static bool rgui_set_aspect_ratio(rgui_t *rgui) +{ +#if !defined(GEKKO) + settings_t *settings = config_get_ptr(); +#endif + + rgui_framebuffer_free(); + rgui_thumbnail_free(); + rgui_wallpaper_free(); + + /* Cache new aspect ratio */ + rgui->menu_aspect_ratio = settings->uints.menu_rgui_aspect_ratio; + +#if defined(GEKKO) + + /* Set frame buffer dimensions + * and update menu aspect index */ + rgui_frame_buf.height = 240; + rgui_frame_buf.width = 320; + rgui->menu_aspect_ratio_idx = ASPECT_RATIO_4_3; + + /* Allocate frame buffer + * (4 extra lines to cache the chequered background) */ + rgui_frame_buf.data = (uint16_t*)calloc( + 400 * (rgui_frame_buf.height + 4), sizeof(uint16_t)); + +#else + + /* Set frame buffer dimensions + * and update menu aspect index */ + rgui_frame_buf.height = 240; + switch (settings->uints.menu_rgui_aspect_ratio) + { + case RGUI_ASPECT_RATIO_16_9: + rgui_frame_buf.width = 426; + rgui->menu_aspect_ratio_idx = ASPECT_RATIO_16_9; + break; + case RGUI_ASPECT_RATIO_16_10: + rgui_frame_buf.width = 384; + rgui->menu_aspect_ratio_idx = ASPECT_RATIO_16_10; + break; + default: + /* 4:3 */ + rgui_frame_buf.width = 320; + rgui->menu_aspect_ratio_idx = ASPECT_RATIO_4_3; + break; + } + + /* Allocate frame buffer + * (4 extra lines to cache the chequered background) */ + rgui_frame_buf.data = (uint16_t*)calloc( + rgui_frame_buf.width * (rgui_frame_buf.height + 4), sizeof(uint16_t)); + +#endif + + if (!rgui_frame_buf.data) + return false; + + /* Configure 'menu display' settings */ + menu_display_set_width(rgui_frame_buf.width); + menu_display_set_height(rgui_frame_buf.height); + menu_display_set_framebuffer_pitch(rgui_frame_buf.width * sizeof(uint16_t)); + + /* Determine terminal layout */ + rgui_term_layout.start_x = (3 * 5) + 1; + rgui_term_layout.start_y = (3 * 5) + FONT_HEIGHT_STRIDE; + rgui_term_layout.width = (rgui_frame_buf.width - (2 * rgui_term_layout.start_x)) / FONT_WIDTH_STRIDE; + rgui_term_layout.height = (rgui_frame_buf.height - (2 * rgui_term_layout.start_y)) / FONT_HEIGHT_STRIDE; + rgui_term_layout.value_maxlen = (unsigned)(((float)RGUI_ENTRY_VALUE_MAXLEN * (float)rgui_frame_buf.width / 320.0f) + 0.5); + + /* > 'Start X/Y' adjustments */ + rgui_term_layout.start_x = (rgui_frame_buf.width - (rgui_term_layout.width * FONT_WIDTH_STRIDE)) / 2; + rgui_term_layout.start_y = (rgui_frame_buf.height - (rgui_term_layout.height * FONT_HEIGHT_STRIDE)) / 2; + + /* Allocate thumbnail buffer */ + thumbnail.data = (uint16_t*)calloc( + rgui_frame_buf.width * rgui_frame_buf.height, sizeof(uint16_t)); + if (!thumbnail.data) + return false; + + /* Allocate wallpaper buffer */ + wallpaper.data = (uint16_t*)calloc( + rgui_frame_buf.width * rgui_frame_buf.height, sizeof(uint16_t)); + if (!wallpaper.data) + return false; + + /* Trigger background/display update */ + rgui->theme_preset_path[0] = '\0'; + rgui->bg_modified = true; + rgui->force_redraw = true; + + /* If aspect ratio lock is enabled, notify + * video driver of change */ + if (settings->bools.menu_rgui_lock_aspect) + { + unsigned aspect_ratio_idx = settings->uints.video_aspect_ratio_idx; + if (aspect_ratio_idx != rgui->menu_aspect_ratio_idx) + { + settings->uints.video_aspect_ratio_idx = rgui->menu_aspect_ratio_idx; + video_driver_set_aspect_ratio(); + settings->uints.video_aspect_ratio_idx = aspect_ratio_idx; + } + } + + return true; } static void *rgui_init(void **userdata, bool video_is_threaded) @@ -1895,27 +2039,20 @@ static void *rgui_init(void **userdata, bool video_is_threaded) rgui->menu_title[0] = '\0'; rgui->menu_sublabel[0] = '\0'; + /* Set aspect ratio + * - Allocates frame buffer + * - Configures variable 'menu display' settings */ + if (!rgui_set_aspect_ratio(rgui)) + goto error; + + /* Fixed 'menu display' settings */ + new_font_height = FONT_HEIGHT_STRIDE * 2; + menu_display_set_header_height(new_font_height); + /* Prepare RGUI colors, to improve performance */ rgui->theme_preset_path[0] = '\0'; prepare_rgui_colors(rgui, settings); - /* 4 extra lines to cache the checked background */ - rgui_framebuf_data = (uint16_t*) - calloc(400 * (240 + 4), sizeof(uint16_t)); - - if (!rgui_framebuf_data) - goto error; - - fb_width = 320; - fb_height = 240; - fb_pitch = fb_width * sizeof(uint16_t); - new_font_height = FONT_HEIGHT_STRIDE * 2; - - menu_display_set_width(fb_width); - menu_display_set_height(fb_height); - menu_display_set_header_height(new_font_height); - menu_display_set_framebuffer_pitch(fb_pitch); - start = 0; menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &start); @@ -1928,8 +2065,8 @@ static void *rgui_init(void **userdata, bool video_is_threaded) rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; rgui->bg_modified = true; - rgui->last_width = fb_width; - rgui->last_height = fb_height; + rgui->last_width = rgui_frame_buf.width; + rgui->last_height = rgui_frame_buf.height; rgui->thumbnail_path_data = menu_thumbnail_path_init(); if (!rgui->thumbnail_path_data) @@ -1943,6 +2080,8 @@ static void *rgui_init(void **userdata, bool video_is_threaded) error: rgui_framebuffer_free(); + rgui_thumbnail_free(); + rgui_wallpaper_free(); if (menu) free(menu); return NULL; @@ -1970,20 +2109,45 @@ static void rgui_free(void *data) menu_display_set_font_data_init(fb_font_inited); rgui_framebuffer_free(); + rgui_thumbnail_free(); + rgui_wallpaper_free(); - if (!string_is_empty(thumbnail.path)) - free(thumbnail.path); - - if (!string_is_empty(wallpaper.path)) - free(wallpaper.path); - - if (upscale_buf.data) + if (rgui_upscale_buf.data) { - free(upscale_buf.data); - upscale_buf.data = NULL; + free(rgui_upscale_buf.data); + rgui_upscale_buf.data = NULL; } } +static void rgui_frame(void *data, video_frame_info_t *video_info) +{ + rgui_t *rgui = (rgui_t*)data; + settings_t *settings = config_get_ptr(); + + if ((settings->bools.menu_rgui_background_filler_thickness_enable != rgui->bg_thickness) || + (settings->bools.menu_rgui_border_filler_thickness_enable != rgui->border_thickness) + ) + rgui->bg_modified = true; + + rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable; + rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; + + if (settings->uints.menu_rgui_color_theme != rgui->color_theme) + { + prepare_rgui_colors(rgui, settings); + } + else if (settings->uints.menu_rgui_color_theme == RGUI_THEME_CUSTOM) + { + if (string_is_not_equal_fast(settings->paths.path_rgui_theme_preset, rgui->theme_preset_path, sizeof(rgui->theme_preset_path))) + { + prepare_rgui_colors(rgui, settings); + } + } + + if (settings->uints.menu_rgui_aspect_ratio != rgui->menu_aspect_ratio) + rgui_set_aspect_ratio(rgui); +} + static void rgui_set_texture(void) { size_t fb_pitch; @@ -2000,7 +2164,7 @@ static void rgui_set_texture(void) if (settings->uints.menu_rgui_internal_upscale_level == RGUI_UPSCALE_NONE) { - video_driver_set_texture_frame(rgui_framebuf_data, + video_driver_set_texture_frame(rgui_frame_buf.data, false, fb_width, fb_height, 1.0f); } else @@ -2013,7 +2177,7 @@ static void rgui_set_texture(void) * than the menu framebuffer, no scaling is required */ if ((vp.width <= fb_width) && (vp.height <= fb_height)) { - video_driver_set_texture_frame(rgui_framebuf_data, + video_driver_set_texture_frame(rgui_frame_buf.data, false, fb_width, fb_height, 1.0f); } else @@ -2037,25 +2201,25 @@ static void rgui_set_texture(void) } /* Allocate upscaling buffer, if required */ - if ((upscale_buf.width != out_width) || (upscale_buf.height != out_height) || !upscale_buf.data) + if ((rgui_upscale_buf.width != out_width) || (rgui_upscale_buf.height != out_height) || !rgui_upscale_buf.data) { - upscale_buf.width = out_width; - upscale_buf.height = out_height; + rgui_upscale_buf.width = out_width; + rgui_upscale_buf.height = out_height; - if (upscale_buf.data) + if (rgui_upscale_buf.data) { - free(upscale_buf.data); - upscale_buf.data = NULL; + free(rgui_upscale_buf.data); + rgui_upscale_buf.data = NULL; } - upscale_buf.data = (uint16_t*)calloc(out_width * out_height, sizeof(uint16_t)); - if (!upscale_buf.data) + rgui_upscale_buf.data = (uint16_t*)calloc(out_width * out_height, sizeof(uint16_t)); + if (!rgui_upscale_buf.data) { /* Uh oh... This could mean we don't have enough * memory, so disable upscaling and draw the usual * framebuffer... */ settings->uints.menu_rgui_internal_upscale_level = RGUI_UPSCALE_NONE; - video_driver_set_texture_frame(rgui_framebuf_data, + video_driver_set_texture_frame(rgui_frame_buf.data, false, fb_width, fb_height, 1.0f); return; } @@ -2073,12 +2237,12 @@ static void rgui_set_texture(void) for (x_dst = 0; x_dst < out_width; x_dst++) { x_src = (x_dst * x_ratio) >> 16; - upscale_buf.data[(y_dst * out_width) + x_dst] = rgui_framebuf_data[(y_src * fb_width) + x_src]; + rgui_upscale_buf.data[(y_dst * out_width) + x_dst] = rgui_frame_buf.data[(y_src * fb_width) + x_src]; } } /* Draw upscaled texture */ - video_driver_set_texture_frame(upscale_buf.data, + video_driver_set_texture_frame(rgui_upscale_buf.data, false, out_width, out_height, 1.0f); } } @@ -2205,20 +2369,20 @@ static void rgui_navigation_set(void *data, bool scroll) menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch); - if (selection < RGUI_TERM_HEIGHT(fb_width, fb_height) /2) + if (selection < RGUI_TERM_HEIGHT(fb_height) /2) { start = 0; do_set_start = true; } - else if (selection >= (RGUI_TERM_HEIGHT(fb_width, fb_height) /2) - && selection < (end - RGUI_TERM_HEIGHT(fb_width, fb_height) /2)) + else if (selection >= (RGUI_TERM_HEIGHT(fb_height) /2) + && selection < (end - RGUI_TERM_HEIGHT(fb_height) /2)) { - start = selection - RGUI_TERM_HEIGHT(fb_width, fb_height) /2; + start = selection - RGUI_TERM_HEIGHT(fb_height) /2; do_set_start = true; } - else if (selection >= (end - RGUI_TERM_HEIGHT(fb_width, fb_height) /2)) + else if (selection >= (end - RGUI_TERM_HEIGHT(fb_height) /2)) { - start = end - RGUI_TERM_HEIGHT(fb_width, fb_height); + start = end - RGUI_TERM_HEIGHT(fb_height); do_set_start = true; } @@ -2332,30 +2496,30 @@ static void rgui_toggle(void *userdata, bool menu_on) if (menu_on) { /* Cache last used content aspect ratio */ - rgui->content_aspect_ratio = settings->uints.video_aspect_ratio_idx; + rgui->content_aspect_ratio_idx = settings->uints.video_aspect_ratio_idx; /* Check if aspect ratio needs to change */ - if (rgui->content_aspect_ratio != ASPECT_RATIO_4_3) + if (rgui->content_aspect_ratio_idx != rgui->menu_aspect_ratio_idx) { - settings->uints.video_aspect_ratio_idx = ASPECT_RATIO_4_3; + settings->uints.video_aspect_ratio_idx = rgui->menu_aspect_ratio_idx; video_driver_set_aspect_ratio(); /* If content is using a custom aspect ratio, we * have to stop here - otherwise, restore content * aspect ratio setting */ - if (rgui->content_aspect_ratio != ASPECT_RATIO_CUSTOM) - settings->uints.video_aspect_ratio_idx = rgui->content_aspect_ratio; + if (rgui->content_aspect_ratio_idx != ASPECT_RATIO_CUSTOM) + settings->uints.video_aspect_ratio_idx = rgui->content_aspect_ratio_idx; } } else { /* If content is using a custom aspect ratio, this * must be restored */ - if (rgui->content_aspect_ratio == ASPECT_RATIO_CUSTOM - && settings->uints.video_aspect_ratio_idx == ASPECT_RATIO_4_3) - settings->uints.video_aspect_ratio_idx = rgui->content_aspect_ratio; + if (rgui->content_aspect_ratio_idx == ASPECT_RATIO_CUSTOM + && settings->uints.video_aspect_ratio_idx == rgui->menu_aspect_ratio_idx) + settings->uints.video_aspect_ratio_idx = rgui->content_aspect_ratio_idx; - if (settings->uints.video_aspect_ratio_idx != ASPECT_RATIO_4_3) + if (settings->uints.video_aspect_ratio_idx != rgui->menu_aspect_ratio_idx) video_driver_set_aspect_ratio(); } } @@ -2363,10 +2527,10 @@ static void rgui_toggle(void *userdata, bool menu_on) /* Upscaling buffer is only required while menu is on. Save * memory by freeing it whenever we switch back to the current * content */ - if (!menu_on && upscale_buf.data) + if (!menu_on && rgui_upscale_buf.data) { - free(upscale_buf.data); - upscale_buf.data = NULL; + free(rgui_upscale_buf.data); + rgui_upscale_buf.data = NULL; } } diff --git a/menu/menu_defines.h b/menu/menu_defines.h index 91a0ad3f16..5d0d26e8ed 100644 --- a/menu/menu_defines.h +++ b/menu/menu_defines.h @@ -249,6 +249,14 @@ enum rgui_upscale_level RGUI_UPSCALE_LAST }; +enum rgui_aspect_ratio +{ + RGUI_ASPECT_RATIO_4_3 = 0, + RGUI_ASPECT_RATIO_16_9, + RGUI_ASPECT_RATIO_16_10, + RGUI_ASPECT_RATIO_LAST +}; + enum menu_action { MENU_ACTION_NOOP = 0, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index abd882be63..7fde7b8ec1 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6114,6 +6114,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL, PARSE_ONLY_UINT, false) == 0) count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO, + PARSE_ONLY_UINT, false) == 0) + count++; if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_RGUI_LOCK_ASPECT, PARSE_ONLY_BOOL, false) == 0) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 2bad35bb7d..0d5980c118 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -891,6 +891,36 @@ static void setting_get_string_representation_uint_rgui_internal_upscale_level( } } +static void setting_get_string_representation_uint_rgui_aspect_ratio( + rarch_setting_t *setting, + char *s, size_t len) +{ + if (!setting) + return; + + switch (*setting->value.target.unsigned_integer) + { + case RGUI_ASPECT_RATIO_4_3: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_4_3), + len); + break; + case RGUI_ASPECT_RATIO_16_9: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_9), + len); + break; + case RGUI_ASPECT_RATIO_16_10: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_10), + len); + break; + } +} + static void setting_get_string_representation_uint_menu_ticker_type( rarch_setting_t *setting, char *s, size_t len) @@ -8293,6 +8323,24 @@ static bool setting_append_list( settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); } +#if !defined(GEKKO) + CONFIG_UINT( + list, list_info, + &settings->uints.menu_rgui_aspect_ratio, + MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO, + MENU_ENUM_LABEL_VALUE_MENU_RGUI_ASPECT_RATIO, + rgui_aspect, + &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_rgui_aspect_ratio; + menu_settings_list_current_add_range(list, list_info, 0, RGUI_ASPECT_RATIO_LAST-1, 1, true, true); +#endif + CONFIG_BOOL( list, list_info, &settings->bools.menu_rgui_lock_aspect, diff --git a/msg_hash.h b/msg_hash.h index 25e7b53a64..2600d05f47 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -867,6 +867,7 @@ enum msg_hash_enums MENU_LABEL(MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE), MENU_LABEL(MENU_RGUI_LOCK_ASPECT), MENU_LABEL(MENU_RGUI_INTERNAL_UPSCALE_LEVEL), + MENU_LABEL(MENU_RGUI_ASPECT_RATIO), MENU_LABEL(MENU_RGUI_FULL_WIDTH_LAYOUT), MENU_LABEL(MENU_LINEAR_FILTER), MENU_LABEL(MENU_HORIZONTAL_ANIMATION), @@ -1985,6 +1986,10 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_RGUI_UPSCALE_X8, MENU_ENUM_LABEL_VALUE_RGUI_UPSCALE_X9, + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_4_3, + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_9, + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_10, + /* Callback strings */ MENU_ENUM_LABEL_CB_CORE_CONTENT_DIRS_LIST, MENU_ENUM_LABEL_CB_CORE_CONTENT_DOWNLOAD, From a17f0e2136f4b30faa8d66dde91a8bac9eac387e Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Tue, 19 Mar 2019 13:11:00 +0000 Subject: [PATCH 055/237] (RGUI) Allow text to be centred when selecting widescreen layouts --- cores/dynamic_dummy.c | 2 ++ intl/msg_hash_us.h | 8 ++++++++ menu/drivers/rgui.c | 21 +++++++++++++++++++-- menu/menu_defines.h | 2 ++ menu/menu_setting.c | 12 ++++++++++++ msg_hash.h | 2 ++ 6 files changed, 45 insertions(+), 2 deletions(-) diff --git a/cores/dynamic_dummy.c b/cores/dynamic_dummy.c index 6b5db0bff1..d02b2846b7 100644 --- a/cores/dynamic_dummy.c +++ b/cores/dynamic_dummy.c @@ -79,9 +79,11 @@ void libretro_dummy_retro_init(void) switch (settings->uints.menu_rgui_aspect_ratio) { case RGUI_ASPECT_RATIO_16_9: + case RGUI_ASPECT_RATIO_16_9_CENTRE: frame_buf_width = 426; break; case RGUI_ASPECT_RATIO_16_10: + case RGUI_ASPECT_RATIO_16_10_CENTRE: frame_buf_width = 384; break; default: diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 461965bb9e..8564c7aa7e 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3030,10 +3030,18 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_9, "16:9" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_9_CENTRE, + "16:9 (Centered)" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_10, "16:10" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_10_CENTRE, + "16:10 (Centered)" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, "Thumbnails" diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 7ab929ed11..0f62f75a4d 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -1057,9 +1057,11 @@ static void load_custom_theme(rgui_t *rgui, rgui_theme_t *theme_colors, const ch switch (settings->uints.menu_rgui_aspect_ratio) { case RGUI_ASPECT_RATIO_16_9: + case RGUI_ASPECT_RATIO_16_9_CENTRE: wallpaper_key = "rgui_wallpaper_16_9"; break; case RGUI_ASPECT_RATIO_16_10: + case RGUI_ASPECT_RATIO_16_10_CENTRE: wallpaper_key = "rgui_wallpaper_16_10"; break; default: @@ -1915,6 +1917,7 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui) #if !defined(GEKKO) settings_t *settings = config_get_ptr(); #endif + unsigned base_term_width; rgui_framebuffer_free(); rgui_thumbnail_free(); @@ -1929,6 +1932,7 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui) * and update menu aspect index */ rgui_frame_buf.height = 240; rgui_frame_buf.width = 320; + base_term_width = rgui_frame_buf.width; rgui->menu_aspect_ratio_idx = ASPECT_RATIO_4_3; /* Allocate frame buffer @@ -1945,15 +1949,28 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui) { case RGUI_ASPECT_RATIO_16_9: rgui_frame_buf.width = 426; + base_term_width = rgui_frame_buf.width; + rgui->menu_aspect_ratio_idx = ASPECT_RATIO_16_9; + break; + case RGUI_ASPECT_RATIO_16_9_CENTRE: + rgui_frame_buf.width = 426; + base_term_width = 320; rgui->menu_aspect_ratio_idx = ASPECT_RATIO_16_9; break; case RGUI_ASPECT_RATIO_16_10: rgui_frame_buf.width = 384; + base_term_width = rgui_frame_buf.width; + rgui->menu_aspect_ratio_idx = ASPECT_RATIO_16_10; + break; + case RGUI_ASPECT_RATIO_16_10_CENTRE: + rgui_frame_buf.width = 384; + base_term_width = 320; rgui->menu_aspect_ratio_idx = ASPECT_RATIO_16_10; break; default: /* 4:3 */ rgui_frame_buf.width = 320; + base_term_width = rgui_frame_buf.width; rgui->menu_aspect_ratio_idx = ASPECT_RATIO_4_3; break; } @@ -1976,9 +1993,9 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui) /* Determine terminal layout */ rgui_term_layout.start_x = (3 * 5) + 1; rgui_term_layout.start_y = (3 * 5) + FONT_HEIGHT_STRIDE; - rgui_term_layout.width = (rgui_frame_buf.width - (2 * rgui_term_layout.start_x)) / FONT_WIDTH_STRIDE; + rgui_term_layout.width = (base_term_width - (2 * rgui_term_layout.start_x)) / FONT_WIDTH_STRIDE; rgui_term_layout.height = (rgui_frame_buf.height - (2 * rgui_term_layout.start_y)) / FONT_HEIGHT_STRIDE; - rgui_term_layout.value_maxlen = (unsigned)(((float)RGUI_ENTRY_VALUE_MAXLEN * (float)rgui_frame_buf.width / 320.0f) + 0.5); + rgui_term_layout.value_maxlen = (unsigned)(((float)RGUI_ENTRY_VALUE_MAXLEN * (float)base_term_width / 320.0f) + 0.5); /* > 'Start X/Y' adjustments */ rgui_term_layout.start_x = (rgui_frame_buf.width - (rgui_term_layout.width * FONT_WIDTH_STRIDE)) / 2; diff --git a/menu/menu_defines.h b/menu/menu_defines.h index 5d0d26e8ed..95d3ff04b3 100644 --- a/menu/menu_defines.h +++ b/menu/menu_defines.h @@ -253,7 +253,9 @@ enum rgui_aspect_ratio { RGUI_ASPECT_RATIO_4_3 = 0, RGUI_ASPECT_RATIO_16_9, + RGUI_ASPECT_RATIO_16_9_CENTRE, RGUI_ASPECT_RATIO_16_10, + RGUI_ASPECT_RATIO_16_10_CENTRE, RGUI_ASPECT_RATIO_LAST }; diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 0d5980c118..984712fdbd 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -912,12 +912,24 @@ static void setting_get_string_representation_uint_rgui_aspect_ratio( MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_9), len); break; + case RGUI_ASPECT_RATIO_16_9_CENTRE: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_9_CENTRE), + len); + break; case RGUI_ASPECT_RATIO_16_10: strlcpy(s, msg_hash_to_str( MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_10), len); break; + case RGUI_ASPECT_RATIO_16_10_CENTRE: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_10_CENTRE), + len); + break; } } diff --git a/msg_hash.h b/msg_hash.h index 2600d05f47..2bf42c3415 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1988,7 +1988,9 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_4_3, MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_9, + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_9_CENTRE, MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_10, + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_10_CENTRE, /* Callback strings */ MENU_ENUM_LABEL_CB_CORE_CONTENT_DIRS_LIST, From f943688dff76924a87ec9206a3ae85c577823f85 Mon Sep 17 00:00:00 2001 From: rsn8887 Date: Mon, 18 Mar 2019 17:51:56 -0500 Subject: [PATCH 056/237] [LIBNX] USB keyboard support --- input/drivers/switch_input.c | 45 ++++++++++++- input/input_keymaps.c | 119 +++++++++++++++++++++++++++++++++++ input/input_keymaps.h | 3 + 3 files changed, 165 insertions(+), 2 deletions(-) diff --git a/input/drivers/switch_input.c b/input/drivers/switch_input.c index 699bbf6e15..1a60958041 100644 --- a/input/drivers/switch_input.c +++ b/input/drivers/switch_input.c @@ -14,9 +14,11 @@ #define MULTITOUCH_LIMIT 4 /* supports up to this many fingers at once */ #define TOUCH_AXIS_MAX 0x7fff /* abstraction of pointer coords */ +#define SWITCH_NUM_SCANCODES 114 #endif #include "../input_driver.h" +#include "../input_keymaps.h" #define MAX_PADS 10 @@ -38,6 +40,7 @@ typedef struct switch_input bool touch_state[MULTITOUCH_LIMIT]; uint32_t touch_x[MULTITOUCH_LIMIT]; uint32_t touch_y[MULTITOUCH_LIMIT]; + bool keyboard_state[SWITCH_NUM_SCANCODES]; #endif } switch_input_t; @@ -50,8 +53,12 @@ static void switch_input_poll(void *data) #ifdef HAVE_LIBNX uint32_t touch_count = hidTouchCount(); + int i = 0; + int keySym = 0; + unsigned keyCode = 0; + uint16_t mod = 0; - for (int i = 0; i < MULTITOUCH_LIMIT; i++) + for (i = 0; i < MULTITOUCH_LIMIT; i++) { sw->touch_state[i] = touch_count > i; @@ -64,6 +71,31 @@ static void switch_input_poll(void *data) sw->touch_y[i] = touch_position.py; } } + + mod = 0; + if (hidKeyboardHeld(KBD_LEFTALT) || hidKeyboardHeld(KBD_RIGHTALT)) + mod |= RETROKMOD_ALT; + if (hidKeyboardHeld(KBD_LEFTCTRL) || hidKeyboardHeld(KBD_RIGHTCTRL)) + mod |= RETROKMOD_CTRL; + if (hidKeyboardHeld(KBD_LEFTSHIFT) || hidKeyboardHeld(KBD_RIGHTSHIFT)) + mod |= RETROKMOD_SHIFT; + + for (i = 0; i < SWITCH_NUM_SCANCODES; i++) + { + keySym = rarch_key_map_switch[i].sym; + keyCode = input_keymaps_translate_keysym_to_rk(keySym); + + if (hidKeyboardHeld(keySym) && !(sw->keyboard_state[i])) + { + sw->keyboard_state[i] = true; + input_keyboard_event(true, keyCode, keyCode, mod, RETRO_DEVICE_KEYBOARD); + } + else if (!hidKeyboardHeld(keySym) && sw->keyboard_state[i]) + { + sw->keyboard_state[i] = false; + input_keyboard_event(false, keyCode, keyCode, mod, RETRO_DEVICE_KEYBOARD); + } + } #endif } @@ -120,6 +152,9 @@ static int16_t switch_input_state(void *data, joypad_info, port, idx, id, binds[port]); break; #ifdef HAVE_LIBNX + case RETRO_DEVICE_KEYBOARD: + return ((id < RETROK_LAST) && sw->keyboard_state[rarch_keysym_lut[(enum retro_key)id]]); + break; case RETRO_DEVICE_POINTER: case RARCH_DEVICE_POINTER_SCREEN: return switch_pointer_device_state(sw, id, idx); @@ -162,6 +197,12 @@ static void* switch_input_init(const char *joypad_driver) */ calc_touch_scaling(sw, 1280, 720, TOUCH_AXIS_MAX); + + input_keymaps_init_keyboard_lut(rarch_key_map_switch); + int i; + for (i = 0; i < SWITCH_NUM_SCANCODES; i++) { + sw->keyboard_state[i] = false; + } #endif return sw; @@ -174,7 +215,7 @@ static uint64_t switch_input_get_capabilities(void *data) uint64_t caps = (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG); #ifdef HAVE_LIBNX - caps |= (1 << RETRO_DEVICE_POINTER); + caps |= (1 << RETRO_DEVICE_POINTER) | (1 << RETRO_DEVICE_KEYBOARD); #endif return caps; diff --git a/input/input_keymaps.c b/input/input_keymaps.c index 0d28f24cbe..a92bf60256 100644 --- a/input/input_keymaps.c +++ b/input/input_keymaps.c @@ -292,6 +292,125 @@ const struct input_key_map input_config_key_map[] = { { NULL, RETROK_UNKNOWN }, }; +#ifdef HAVE_LIBNX +const struct rarch_key_map rarch_key_map_switch[] = { + { KBD_A, RETROK_a }, + { KBD_B, RETROK_b }, + { KBD_C, RETROK_c }, + { KBD_D, RETROK_d }, + { KBD_E, RETROK_e }, + { KBD_F, RETROK_f }, + { KBD_G, RETROK_g }, + { KBD_H, RETROK_h }, + { KBD_I, RETROK_i }, + { KBD_J, RETROK_j }, + { KBD_K, RETROK_k }, + { KBD_L, RETROK_l }, + { KBD_M, RETROK_m }, + { KBD_N, RETROK_n }, + { KBD_O, RETROK_o }, + { KBD_P, RETROK_p }, + { KBD_Q, RETROK_q }, + { KBD_R, RETROK_r }, + { KBD_S, RETROK_s }, + { KBD_T, RETROK_t }, + { KBD_U, RETROK_u }, + { KBD_V, RETROK_v }, + { KBD_W, RETROK_w }, + { KBD_X, RETROK_x }, + { KBD_Y, RETROK_y }, + { KBD_Z, RETROK_z }, + { KBD_BACKSPACE, RETROK_BACKSPACE }, + { KBD_TAB, RETROK_TAB }, + { KBD_ENTER, RETROK_RETURN }, + { KBD_PAUSE, RETROK_PAUSE }, + { KBD_ESC, RETROK_ESCAPE }, + { KBD_SPACE, RETROK_SPACE }, + { KBD_HASHTILDE, RETROK_HASH }, + { KBD_APOSTROPHE, RETROK_QUOTE }, + { KBD_KPLEFTPAREN, RETROK_LEFTPAREN }, + { KBD_KPRIGHTPAREN, RETROK_RIGHTPAREN }, + { KBD_COMMA, RETROK_COMMA }, + { KBD_MINUS, RETROK_MINUS }, + { KBD_DOT, RETROK_PERIOD }, + { KBD_SLASH, RETROK_SLASH }, + { KBD_0, RETROK_0 }, + { KBD_1, RETROK_1 }, + { KBD_2, RETROK_2 }, + { KBD_3, RETROK_3 }, + { KBD_4, RETROK_4 }, + { KBD_5, RETROK_5 }, + { KBD_6, RETROK_6 }, + { KBD_7, RETROK_7 }, + { KBD_8, RETROK_8 }, + { KBD_9, RETROK_9 }, + { KBD_SEMICOLON, RETROK_SEMICOLON }, + { KBD_EQUAL, RETROK_EQUALS }, + { KBD_LEFTBRACE, RETROK_LEFTBRACKET }, + { KBD_BACKSLASH, RETROK_BACKSLASH }, + { KBD_RIGHTBRACE, RETROK_RIGHTBRACKET }, + { KBD_DELETE, RETROK_DELETE }, + { KBD_KP0, RETROK_KP0 }, + { KBD_KP1, RETROK_KP1 }, + { KBD_KP2, RETROK_KP2 }, + { KBD_KP3, RETROK_KP3 }, + { KBD_KP4, RETROK_KP4 }, + { KBD_KP5, RETROK_KP5 }, + { KBD_KP6, RETROK_KP6 }, + { KBD_KP7, RETROK_KP7 }, + { KBD_KP8, RETROK_KP8 }, + { KBD_KP9, RETROK_KP9 }, + { KBD_KPDOT, RETROK_KP_PERIOD }, + { KBD_KPSLASH, RETROK_KP_DIVIDE }, + { KBD_KPASTERISK, RETROK_KP_MULTIPLY }, + { KBD_KPMINUS, RETROK_KP_MINUS }, + { KBD_KPPLUS, RETROK_KP_PLUS }, + { KBD_KPENTER, RETROK_KP_ENTER }, + { KBD_KPEQUAL, RETROK_KP_EQUALS }, + { KBD_UP, RETROK_UP }, + { KBD_DOWN, RETROK_DOWN }, + { KBD_RIGHT, RETROK_RIGHT }, + { KBD_LEFT, RETROK_LEFT }, + { KBD_INSERT, RETROK_INSERT }, + { KBD_HOME, RETROK_HOME }, + { KBD_END, RETROK_END }, + { KBD_PAGEUP, RETROK_PAGEUP }, + { KBD_PAGEDOWN, RETROK_PAGEDOWN }, + { KBD_F1, RETROK_F1 }, + { KBD_F2, RETROK_F2 }, + { KBD_F3, RETROK_F3 }, + { KBD_F4, RETROK_F4 }, + { KBD_F5, RETROK_F5 }, + { KBD_F6, RETROK_F6 }, + { KBD_F7, RETROK_F7 }, + { KBD_F8, RETROK_F8 }, + { KBD_F9, RETROK_F9 }, + { KBD_F10, RETROK_F10 }, + { KBD_F11, RETROK_F11 }, + { KBD_F12, RETROK_F12 }, + { KBD_F13, RETROK_F13 }, + { KBD_F14, RETROK_F14 }, + { KBD_F15, RETROK_F15 }, + { KBD_NUMLOCK, RETROK_NUMLOCK }, + { KBD_CAPSLOCK, RETROK_CAPSLOCK }, + { KBD_SCROLLLOCK, RETROK_SCROLLOCK }, + { KBD_RIGHTSHIFT, RETROK_RSHIFT }, + { KBD_LEFTSHIFT, RETROK_LSHIFT }, + { KBD_RIGHTCTRL, RETROK_RCTRL }, + { KBD_LEFTCTRL, RETROK_LCTRL }, + { KBD_RIGHTALT, RETROK_RALT }, + { KBD_LEFTALT, RETROK_LALT }, + { KBD_LEFTMETA, RETROK_LMETA }, + { KBD_RIGHTMETA, RETROK_RMETA }, + { KBD_COMPOSE, RETROK_COMPOSE }, + { KBD_HELP, RETROK_HELP }, + { KBD_PAUSE, RETROK_BREAK }, + { KBD_POWER, RETROK_POWER }, + { KBD_UNDO, RETROK_UNDO }, + { 0, RETROK_UNKNOWN } +}; +#endif + #if defined(HAVE_SDL) || defined(HAVE_SDL2) const struct rarch_key_map rarch_key_map_sdl[] = { { SDLK_BACKSPACE, RETROK_BACKSPACE }, diff --git a/input/input_keymaps.h b/input/input_keymaps.h index d682af4e0e..69fe66d6fc 100644 --- a/input/input_keymaps.h +++ b/input/input_keymaps.h @@ -65,6 +65,9 @@ extern const struct rarch_key_map rarch_key_map_qnx[]; extern const struct rarch_key_map rarch_key_map_dos[]; extern const struct rarch_key_map rarch_key_map_wiiu[]; extern const struct rarch_key_map rarch_key_map_winraw[]; +#ifdef HAVE_LIBNX +extern const struct rarch_key_map rarch_key_map_switch[]; +#endif /** * input_keymaps_init_keyboard_lut: From b10901e6b9f0d537c6895da4294ffbe46b6d9385 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Tue, 19 Mar 2019 14:42:52 +0000 Subject: [PATCH 057/237] Fix 'Multiplication result converted to larger type' alert --- cores/dynamic_dummy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/dynamic_dummy.c b/cores/dynamic_dummy.c index d02b2846b7..65d76a4c7b 100644 --- a/cores/dynamic_dummy.c +++ b/cores/dynamic_dummy.c @@ -67,7 +67,7 @@ void libretro_dummy_retro_init(void) #if defined(HAVE_MENU) && defined(HAVE_RGUI) settings_t *settings = config_get_ptr(); #endif - unsigned i; + uint32_t i; /* Sensible defaults */ frame_buf_width = 320; From cd750457925941ff7dba092c05d9af407d4cb98f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 19 Mar 2019 16:03:19 +0100 Subject: [PATCH 058/237] Simplify video_driver_frame - simplify FPS reporting printout --- gfx/video_driver.c | 93 ++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 62 deletions(-) diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 2a5b7fc190..16fe7def54 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -2367,14 +2367,10 @@ void video_driver_frame(const void *data, unsigned width, unsigned height, size_t pitch) { static char video_driver_msg[256]; - static char title[256]; video_frame_info_t video_info; static retro_time_t curr_time; static retro_time_t fps_time; static float last_fps, frame_time; - unsigned output_width = 0; - unsigned output_height = 0; - unsigned output_pitch = 0; const char *msg = NULL; retro_time_t new_time = cpu_features_get_time_usec(); @@ -2407,6 +2403,7 @@ void video_driver_frame(const void *data, unsigned width, /* Get the amount of frames per seconds. */ if (video_driver_frame_count) { + static char title[256]; unsigned write_index = video_driver_frame_time_count++ & (MEASURE_FRAME_TIME_SAMPLES_COUNT - 1); @@ -2417,78 +2414,46 @@ void video_driver_frame(const void *data, unsigned width, if (video_driver_frame_count == 1) strlcpy(title, video_driver_window_title, sizeof(title)); + if (video_info.fps_show) + { + snprintf(video_info.fps_text, sizeof(video_info.fps_text), + "FPS: %6.1f", last_fps); + if (video_info.framecount_show) + strlcat(video_info.fps_text, + " || ", sizeof(video_info.fps_text)); + } + + if (video_info.framecount_show) + { + char frames_text[64]; + snprintf(frames_text, + sizeof(frames_text), + "%s: %" PRIu64, msg_hash_to_str(MSG_FRAMES), + (uint64_t)video_driver_frame_count); + strlcat(video_info.fps_text, + frames_text, sizeof(video_info.fps_text)); + } + if ((video_driver_frame_count % FPS_UPDATE_INTERVAL) == 0) { last_fps = TIME_TO_FPS(curr_time, new_time, FPS_UPDATE_INTERVAL); strlcpy(video_driver_window_title, title, sizeof(video_driver_window_title)); - if (video_info.fps_show) + if (!string_is_empty(video_info.fps_text)) { - snprintf(video_info.fps_text, sizeof(video_info.fps_text), - " || FPS: %6.1f ", last_fps); + strlcat(video_driver_window_title, + "|| ", sizeof(video_driver_window_title)); strlcat(video_driver_window_title, video_info.fps_text, sizeof(video_driver_window_title)); } - if (video_info.framecount_show) - { - char frames_text[64]; - snprintf(frames_text, - sizeof(frames_text), - " || Frames: %" PRIu64, - (uint64_t)video_driver_frame_count); - strlcat(video_driver_window_title, - frames_text, sizeof(video_driver_window_title)); - } - - curr_time = new_time; + curr_time = new_time; video_driver_window_title_update = true; } - - if (video_info.fps_show) - { - if (video_info.framecount_show) - snprintf( - video_info.fps_text, - sizeof(video_info.fps_text), - "FPS: %6.1f || %s: %" PRIu64, - last_fps, - msg_hash_to_str(MSG_FRAMES), - (uint64_t)video_driver_frame_count); - else - snprintf( - video_info.fps_text, - sizeof(video_info.fps_text), - "FPS: %6.1f", - last_fps); - } - - if (video_info.fps_show && video_info.framecount_show) - snprintf( - video_info.fps_text, - sizeof(video_info.fps_text), - "FPS: %6.1f || %s: %" PRIu64, - last_fps, - msg_hash_to_str(MSG_FRAMES), - (uint64_t)video_driver_frame_count); - else if (video_info.framecount_show) - snprintf( - video_info.fps_text, - sizeof(video_info.fps_text), - "%s: %" PRIu64, - msg_hash_to_str(MSG_FRAMES), - (uint64_t)video_driver_frame_count); - else if (video_info.fps_show) - snprintf( - video_info.fps_text, - sizeof(video_info.fps_text), - "FPS: %6.1f", - last_fps); } else { - curr_time = fps_time = new_time; strlcpy(video_driver_window_title, @@ -2503,8 +2468,8 @@ void video_driver_frame(const void *data, unsigned width, video_driver_window_title_update = true; } - video_info.frame_rate = last_fps; - video_info.frame_time = frame_time / 1000.0f; + video_info.frame_rate = last_fps; + video_info.frame_time = frame_time / 1000.0f; video_info.frame_count = (uint64_t) video_driver_frame_count; /* Slightly messy code, @@ -2524,6 +2489,10 @@ void video_driver_frame(const void *data, unsigned width, if (data && video_driver_state_filter) { + unsigned output_width = 0; + unsigned output_height = 0; + unsigned output_pitch = 0; + rarch_softfilter_get_output_size(video_driver_state_filter, &output_width, &output_height, width, height); From 8336163112efcc5005799284eec1474d608dc3e3 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Tue, 19 Mar 2019 15:10:14 +0000 Subject: [PATCH 059/237] (RGUI) Ensure update is immediate when changing 'Menu Aspect Ratio' --- menu/drivers/rgui.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 0f62f75a4d..418bb10e9a 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -2023,12 +2023,9 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui) if (settings->bools.menu_rgui_lock_aspect) { unsigned aspect_ratio_idx = settings->uints.video_aspect_ratio_idx; - if (aspect_ratio_idx != rgui->menu_aspect_ratio_idx) - { - settings->uints.video_aspect_ratio_idx = rgui->menu_aspect_ratio_idx; - video_driver_set_aspect_ratio(); - settings->uints.video_aspect_ratio_idx = aspect_ratio_idx; - } + settings->uints.video_aspect_ratio_idx = rgui->menu_aspect_ratio_idx; + video_driver_set_aspect_ratio(); + settings->uints.video_aspect_ratio_idx = aspect_ratio_idx; } return true; From 208a68b528814523a1d64fce92e59675b3cf678a Mon Sep 17 00:00:00 2001 From: rsn8887 Date: Tue, 19 Mar 2019 09:22:16 -0500 Subject: [PATCH 060/237] [LIBNX] USB mouse support --- input/drivers/switch_input.c | 135 ++++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 3 deletions(-) diff --git a/input/drivers/switch_input.c b/input/drivers/switch_input.c index 1a60958041..a163af7573 100644 --- a/input/drivers/switch_input.c +++ b/input/drivers/switch_input.c @@ -15,6 +15,8 @@ #define MULTITOUCH_LIMIT 4 /* supports up to this many fingers at once */ #define TOUCH_AXIS_MAX 0x7fff /* abstraction of pointer coords */ #define SWITCH_NUM_SCANCODES 114 +#define MOUSE_MAX_X 1920 +#define MOUSE_MAX_Y 1080 #endif #include "../input_driver.h" @@ -41,6 +43,15 @@ typedef struct switch_input uint32_t touch_x[MULTITOUCH_LIMIT]; uint32_t touch_y[MULTITOUCH_LIMIT]; bool keyboard_state[SWITCH_NUM_SCANCODES]; + + int32_t mouse_x; + int32_t mouse_y; + int32_t mouse_x_delta; + int32_t mouse_y_delta; + int32_t mouse_wheel; + bool mouse_button_left; + bool mouse_button_right; + bool mouse_button_middle; #endif } switch_input_t; @@ -53,10 +64,11 @@ static void switch_input_poll(void *data) #ifdef HAVE_LIBNX uint32_t touch_count = hidTouchCount(); - int i = 0; + unsigned int i = 0; int keySym = 0; unsigned keyCode = 0; uint16_t mod = 0; + MousePosition mouse_pos; for (i = 0; i < MULTITOUCH_LIMIT; i++) { @@ -96,6 +108,60 @@ static void switch_input_poll(void *data) input_keyboard_event(false, keyCode, keyCode, mod, RETRO_DEVICE_KEYBOARD); } } + + if (hidMouseButtonsHeld() & MOUSE_LEFT) + { + sw->mouse_button_left = true; + } + else + { + sw->mouse_button_left = false; + } + + if (hidMouseButtonsHeld() & MOUSE_RIGHT) + { + sw->mouse_button_right = true; + } + else + { + sw->mouse_button_right = false; + } + + if (hidMouseButtonsHeld() & MOUSE_MIDDLE) + { + sw->mouse_button_middle = true; + } + else + { + sw->mouse_button_middle = false; + } + + hidMouseRead(&mouse_pos); + + sw->mouse_x_delta = mouse_pos.velocityX; + sw->mouse_y_delta = mouse_pos.velocityY; + + sw->mouse_x += mouse_pos.velocityX; + sw->mouse_y += mouse_pos.velocityY; + if (sw->mouse_x < 0) + { + sw->mouse_x = 0; + } + else if (sw->mouse_x > MOUSE_MAX_X) + { + sw->mouse_x = MOUSE_MAX_X; + } + + if (sw->mouse_y < 0) + { + sw->mouse_y = 0; + } + else if (sw->mouse_y > MOUSE_MAX_Y) + { + sw->mouse_y = MOUSE_MAX_Y; + } + + sw->mouse_wheel = mouse_pos.scrollVelocityY; #endif } @@ -127,6 +193,61 @@ static int16_t switch_pointer_device_state(switch_input_t *sw, return 0; } + +static int16_t switch_input_mouse_state(switch_input_t *sw, unsigned id, bool screen) +{ + int val = 0; + switch (id) + { + case RETRO_DEVICE_ID_MOUSE_LEFT: + val = sw->mouse_button_left; + break; + case RETRO_DEVICE_ID_MOUSE_RIGHT: + val = sw->mouse_button_right; + break; + case RETRO_DEVICE_ID_MOUSE_MIDDLE: + val = sw->mouse_button_middle; + break; + case RETRO_DEVICE_ID_MOUSE_X: + if (screen) + { + val = sw->mouse_x; + } + else + { + val = sw->mouse_x_delta; + sw->mouse_x_delta = 0; /* flush delta after it has been read */ + } + break; + case RETRO_DEVICE_ID_MOUSE_Y: + if (screen) + { + val = sw->mouse_y; + } + else + { + val = sw->mouse_y_delta; + sw->mouse_y_delta = 0; /* flush delta after it has been read */ + } + break; + case RETRO_DEVICE_ID_MOUSE_WHEELUP: + if (sw->mouse_wheel > 0) + { + val = sw->mouse_wheel; + sw->mouse_wheel = 0; + } + break; + case RETRO_DEVICE_ID_MOUSE_WHEELDOWN: + if (sw->mouse_wheel < 0) + { + val = sw->mouse_wheel; + sw->mouse_wheel = 0; + } + break; + } + + return val; +} #endif static int16_t switch_input_state(void *data, @@ -155,6 +276,12 @@ static int16_t switch_input_state(void *data, case RETRO_DEVICE_KEYBOARD: return ((id < RETROK_LAST) && sw->keyboard_state[rarch_keysym_lut[(enum retro_key)id]]); break; + case RETRO_DEVICE_MOUSE: + return switch_input_mouse_state(sw, id, false); + break; + case RARCH_DEVICE_MOUSE_SCREEN: + return switch_input_mouse_state(sw, id, true); + break; case RETRO_DEVICE_POINTER: case RARCH_DEVICE_POINTER_SCREEN: return switch_pointer_device_state(sw, id, idx); @@ -199,10 +326,12 @@ static void* switch_input_init(const char *joypad_driver) calc_touch_scaling(sw, 1280, 720, TOUCH_AXIS_MAX); input_keymaps_init_keyboard_lut(rarch_key_map_switch); - int i; + unsigned int i; for (i = 0; i < SWITCH_NUM_SCANCODES; i++) { sw->keyboard_state[i] = false; } + sw->mouse_x = 0; + sw->mouse_y = 0; #endif return sw; @@ -215,7 +344,7 @@ static uint64_t switch_input_get_capabilities(void *data) uint64_t caps = (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG); #ifdef HAVE_LIBNX - caps |= (1 << RETRO_DEVICE_POINTER) | (1 << RETRO_DEVICE_KEYBOARD); + caps |= (1 << RETRO_DEVICE_POINTER) | (1 << RETRO_DEVICE_KEYBOARD) | (1 << RETRO_DEVICE_MOUSE); #endif return caps; From 5aa0d176592ed9dbc77dc9504558219d85ade5f7 Mon Sep 17 00:00:00 2001 From: rsn8887 Date: Tue, 19 Mar 2019 19:42:52 -0500 Subject: [PATCH 061/237] [LIBNX] Fix USB keyboard support for controlling Vice core and Menu --- input/drivers/switch_input.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/input/drivers/switch_input.c b/input/drivers/switch_input.c index a163af7573..a21ed5d74e 100644 --- a/input/drivers/switch_input.c +++ b/input/drivers/switch_input.c @@ -14,7 +14,8 @@ #define MULTITOUCH_LIMIT 4 /* supports up to this many fingers at once */ #define TOUCH_AXIS_MAX 0x7fff /* abstraction of pointer coords */ -#define SWITCH_NUM_SCANCODES 114 +#define SWITCH_NUM_SCANCODES 114 /* size of rarch_key_map_switch */ +#define SWITCH_MAX_SCANCODE 0xfb /* see https://switchbrew.github.io/libnx/hid_8h.html */ #define MOUSE_MAX_X 1920 #define MOUSE_MAX_Y 1080 #endif @@ -42,7 +43,7 @@ typedef struct switch_input bool touch_state[MULTITOUCH_LIMIT]; uint32_t touch_x[MULTITOUCH_LIMIT]; uint32_t touch_y[MULTITOUCH_LIMIT]; - bool keyboard_state[SWITCH_NUM_SCANCODES]; + bool keyboard_state[SWITCH_MAX_SCANCODE + 1]; int32_t mouse_x; int32_t mouse_y; @@ -97,15 +98,15 @@ static void switch_input_poll(void *data) keySym = rarch_key_map_switch[i].sym; keyCode = input_keymaps_translate_keysym_to_rk(keySym); - if (hidKeyboardHeld(keySym) && !(sw->keyboard_state[i])) + if (hidKeyboardHeld(keySym) && !(sw->keyboard_state[keySym])) { - sw->keyboard_state[i] = true; - input_keyboard_event(true, keyCode, keyCode, mod, RETRO_DEVICE_KEYBOARD); + sw->keyboard_state[keySym] = true; + input_keyboard_event(true, keyCode, 0, mod, RETRO_DEVICE_KEYBOARD); } - else if (!hidKeyboardHeld(keySym) && sw->keyboard_state[i]) + else if (!hidKeyboardHeld(keySym) && sw->keyboard_state[keySym]) { - sw->keyboard_state[i] = false; - input_keyboard_event(false, keyCode, keyCode, mod, RETRO_DEVICE_KEYBOARD); + sw->keyboard_state[keySym] = false; + input_keyboard_event(false, keyCode, 0, mod, RETRO_DEVICE_KEYBOARD); } } @@ -327,7 +328,7 @@ static void* switch_input_init(const char *joypad_driver) input_keymaps_init_keyboard_lut(rarch_key_map_switch); unsigned int i; - for (i = 0; i < SWITCH_NUM_SCANCODES; i++) { + for (i = 0; i <= SWITCH_MAX_SCANCODE; i++) { sw->keyboard_state[i] = false; } sw->mouse_x = 0; From 3fb4ed753dbc82df4f38b32f1eb78a36da2d08dc Mon Sep 17 00:00:00 2001 From: orbea Date: Tue, 19 Mar 2019 21:54:06 -0700 Subject: [PATCH 062/237] Fix caca warning. One too many lines were removed in commit f67bfa24efed294dec4410d04c970c53cca793f0. --- gfx/drivers/caca_gfx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gfx/drivers/caca_gfx.c b/gfx/drivers/caca_gfx.c index 5c88affec5..a7028cac17 100644 --- a/gfx/drivers/caca_gfx.c +++ b/gfx/drivers/caca_gfx.c @@ -317,6 +317,7 @@ static const video_poke_interface_t caca_poke_interface = { NULL, NULL, NULL, + NULL, caca_set_texture_frame, NULL, caca_set_osd_msg, From 513273e3f2b58a34d3b71deb3e043e13b6e4b0a3 Mon Sep 17 00:00:00 2001 From: bubuleur Date: Wed, 20 Mar 2019 09:44:28 +0100 Subject: [PATCH 063/237] Update french translation --- intl/msg_hash_fr.h | 458 ++++++++++++++++++++++----------------------- 1 file changed, 229 insertions(+), 229 deletions(-) diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 1fe39d6a1f..1e022a8fc1 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -993,7 +993,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_HORIZONTAL_ANIMATION, "Horizontal Animation") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, - "Appearance") + "Apparence") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER, "Fond d'écran") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY, @@ -1667,7 +1667,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "Fréquence estimée de l'écran") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, - "Set Display-Reported Refresh Rate") + "Définir le taux de rafraîchissement signalé par l'affichage") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "Rotation") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, @@ -1733,11 +1733,11 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "Transparence du fond") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_RED, - "Menu Font Red Color") + "Police de menu couleur rouge") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_GREEN, - "Menu Font Green Color") + "Police de menu couleur verte") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_BLUE, - "Menu Font Blue Color") + "Police de menu couleur bleue") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "Police du menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, @@ -1901,7 +1901,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "Taux de rafraîchissement estimé de l'écran en Hz.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED, - "The refresh rate as reported by the display driver.") + "Le taux de rafraîchissement indiqué par le pilote d'affichage.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, "Ajuster les paramètres de sortie vidéo.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2561,11 +2561,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, - "Only scales video in integer steps. The base size depends on system-reported geometry and aspect ratio. If 'Force Aspect' is not set, X/Y will be integer scaled independently." + "Uniquement les échelles vidéo dans les étapes entières. La taille de base dépend de la géométrie et du rapport d'aspect signalés par le système. Si 'Force Aspect' n'est pas défini, X/Y sera entier et mis à l'échelle indépendamment." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT, - "Screenshots output of GPU shaded material if available." + "Sortie des captures d'écran du matériel ombré par le GPU, si disponible." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_ROTATION, @@ -2573,7 +2573,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_FORCE_SRGB_DISABLE, - "Forcibly disable sRGB FBO support. Some Intel OpenGL drivers on Windows have video problems with sRGB FBO support if this is enabled. Enabling this can work around it." + "Désactivez de force le support sRGB FBO. Certains pilotes Intel OpenGL sous Windows rencontrent des problèmes vidéo avec la prise en charge de sRGB FBO, le cas échéant. Activer cela peut fonctionner autour de cela." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN, @@ -2585,23 +2585,23 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_GPU_RECORD, - "Records output of GPU shaded material if available." + "Enregistre la sortie du matériel ombré GPU si disponible." ) MSG_HASH( MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX, - "When making a savestate, save state index is automatically increased before it is saved. When loading content, the index will be set to the highest existing index." + "Lors de la création d'un état de sauvegarde, l'index d'état de sauvegarde est automatiquement augmenté avant d'être enregistré. Lors du chargement du contenu, l'index sera défini sur le plus haut index existant." ) MSG_HASH( MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE, - "Block Save RAM from being overwritten when loading save states. Might potentially lead to buggy games." + "Bloquer la sauvegarde de la RAM afin qu'elle ne soit pas écrasée lors du chargement des états de sauvegarde." ) MSG_HASH( MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO, - "The maximum rate at which content will be run when using fast forward (e.g., 5.0x for 60 fps content = 300 fps cap). If set to 0.0x, fastforward ratio is unlimited (no FPS cap)." + "Taux maximal auquel le contenu sera exécuté lors de l’utilisation de l’avance rapide (par exemple, 5,0x pour un contenu de 60 ips = limite de 300 ips). Si défini à 0,0x, le rapport de rapidité est illimité (pas de limite de FPS)." ) MSG_HASH( MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, - "When in slow motion, content will slow down by the factor specified/set." + "Au ralenti, le contenu sera ralenti du facteur spécifié/défini." ) MSG_HASH( MENU_ENUM_SUBLABEL_REWIND_ENABLE, @@ -2609,15 +2609,15 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_REWIND_GRANULARITY, - "When rewinding a defined number of frames, you can rewind several frames at a time, increasing the rewind speed." + "Lors du rembobinage d’un nombre défini d’images, vous pouvez rembobiner plusieurs images à la fois, ce qui augmente la vitesse de rembobinage." ) MSG_HASH( MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL, - "Sets log level for cores. If a log level issued by a core is below this value, it is ignored." + "Définit le niveau de journalisation des cœurs. Si un niveau de journalisation émis par un core est inférieur à cette valeur, il est ignoré." ) MSG_HASH( MENU_ENUM_SUBLABEL_PERFCNT_ENABLE, - "Enable performance counters for RetroArch (and cores)." + "Activer les compteurs de performance pour RetroArch (et les coeurs)." ) MSG_HASH( MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_SAVE, @@ -2633,7 +2633,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL, - "Autosaves the non-volatile Save RAM at a regular interval. This is disabled by default unless set otherwise. The interval is measured in seconds. A value of 0 disables autosave." + "Sauvegarde automatique la mémoire RAM non volatile à un intervalle régulier. Ceci est désactivé par défaut sauf indication contraire. L'intervalle est mesuré en secondes. Une valeur de 0 désactive la sauvegarde automatique." ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE, @@ -2705,11 +2705,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_DEVICE, - "Override the default audio device the audio driver uses. This is driver dependent." + "Remplacez le périphérique audio par défaut utilisé par le pilote audio. Ceci dépend du pilote." ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_DSP_PLUGIN, - "Audio DSP plugin that processes audio before it's sent to the driver." + "Plugin audio DSP qui traite l'audio avant qu'il ne soit envoyé au pilote." ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_OUTPUT_RATE, @@ -2757,23 +2757,23 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_ALLOW_SLAVES, - "Whether to allow connections in slave mode. Slave-mode clients require very little processing power on either side, but will suffer significantly from network latency." + "Autoriser ou non les connexions en mode esclave. Les clients en mode esclave nécessitent très peu de puissance de traitement de part et d’autre, mais souffrent considérablement de la latence du réseau." ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_REQUIRE_SLAVES, - "Whether to disallow connections not in slave mode. Not recommended except for very fast networks with very weak machines." + "Interdire les connexions non en mode esclave. Non recommandé sauf pour les réseaux très rapides avec des machines très faibles." ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_STATELESS_MODE, - "Whether to run netplay in a mode not requiring save states. If set to true, a very fast network is required, but no rewinding is performed, so there will be no netplay jitter." + "Exécuter ou non netplay dans un mode ne nécessitant pas d’état de sauvegarde. Si défini sur true, un réseau très rapide est requis, mais aucun rembobinage n'est effectué. Il n'y aura donc pas de jitter sur Netplay." ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_CHECK_FRAMES, - "The frequency in frames with which netplay will verify that the host and client are in sync." + "La fréquence dans les cadres avec laquelle netplay vérifiera que l'hôte et le client sont synchronisés." ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_NAT_TRAVERSAL, - "When hosting, attempt to listen for connections from the public Internet, using UPnP or similar technologies to escape LANs." + "Lors de l'hébergement, essayez d'écouter les connexions à partir d'Internet public, en utilisant UPnP ou des technologies similaires pour échapper aux réseaux locaux." ) MSG_HASH( MENU_ENUM_SUBLABEL_STDIN_CMD_ENABLE, @@ -2816,20 +2816,20 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, "Analyse un fichier pour vérifier s'il est compatible et l'ajouter à une playlist.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, - "Uses a custom swap interval for Vsync. Set this to effectively halve monitor refresh rate." + "Utilise un intervalle d'échange personnalisé pour Vsync. Définissez cette option pour réduire de moitié le taux de rafraîchissement du moniteur." ) MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE, - "Sort save files in folders named after the core used." + "Tri des fichiers de sauvegarde dans des dossiers nommés d'après le coeur utilisé." ) MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE, - "Sort save states in folders named after the core used." + "Tri des états de sauvegarde dans des dossiers nommés d'après le coeur utilisé." ) MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL, - "URL to core updater directory on the Libretro buildbot.") + "URL du répertoire principal du programme de mise à jour sur le buildbot Libretro.") MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL, - "URL to assets updater directory on the Libretro buildbot.") + "URL du répertoire de mise à jour des actifs sur le buildbot Libretro.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, - "After downloading, automatically extract files contained in the downloaded archives." + "Après le téléchargement, extrayez automatiquement les fichiers contenus dans les archives téléchargées." ) MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Rafraîchir la liste des salons.") @@ -2874,12 +2874,12 @@ MSG_HASH(MENU_ENUM_SUBLABEL_RESUME_CONTENT, MSG_HASH(MENU_ENUM_SUBLABEL_STATE_SLOT, "Changer l'emplacement de destination de la sauvegarde instantanée.") MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_LOAD_STATE, - "If a state was loaded, content will go back to the state prior to loading.") + "Si un état a été chargé, le contenu reviendra à l'état avant le chargement.") MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_SAVE_STATE, - "If a state was overwritten, it will roll back to the previous save state.") + "Si un état a été écrasé, il reviendra à l'état de sauvegarde précédent.") MSG_HASH( MENU_ENUM_SUBLABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, - "Retro Achievements service. For more information, visit http://retroachievements.org" + "Service de réalisations Retro. Pour plus d'informations, visitez http://retroachievements.org" ) MSG_HASH( MENU_ENUM_SUBLABEL_ACCOUNTS_LIST, @@ -2904,7 +2904,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_OPTIONS, MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, "Afficher les options avancées pour les utilisateurs expérimentés (invisible par défaut).") MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, - "Perform tasks on a separate thread.") + "Effectuer des tâches sur un fil séparé.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, "Autoriser l'utilisateur à supprimer des entrées des collections") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, @@ -2913,35 +2913,35 @@ MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, "Définir le répertoire de début pour l'exporateur de fichiers.") MSG_HASH( MENU_ENUM_SUBLABEL_CONTENT_DIR, - "Usually set by developers who bundle libretro/RetroArch apps to point to assets." + "Généralement définie par les développeurs qui regroupent les applications Libretro/RetroArch pour pointer sur des éléments." ) MSG_HASH(MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPERS_DIRECTORY, - "Directory to store wallpapers dynamically loaded by the menu depending on context.") + "Répertoire pour stocker les fonds d'écran chargés dynamiquement par le menu en fonction du contexte.") MSG_HASH(MENU_ENUM_SUBLABEL_THUMBNAILS_DIRECTORY, - "Supplementary thumbnails (boxarts/misc. images, etc.) are stored here." + "Des vignettes supplémentaires (Boxarts/images diverses, etc.) sont stockées ici." ) MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_CONFIG_DIRECTORY, - "Sets start directory for menu configuration browser.") + "Définit le répertoire de départ pour le navigateur de configuration de menu.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, - "The number of frames of input latency for netplay to use to hide network latency. Reduces jitter and makes netplay less CPU-intensive, at the expense of noticeable input lag.") + "Nombre d'images de latence d'entrée que netplay doit utiliser pour masquer la latence du réseau. Réduit la gigue et rend netplay moins gourmand en ressources processeur, aux dépens d'un décalage d'entrée notable.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, - "The range of frames of input latency that may be used to hide network latency. Reduces jitter and makes netplay less CPU-intensive, at the expense of unpredictable input lag.") + "Plage de trames de latence d'entrée pouvant être utilisée pour masquer la latence du réseau. Réduit la gigue et rend netplay moins gourmand en ressources processeur, aux dépens d'un retard d'entrée imprévisible.") MSG_HASH(MENU_ENUM_SUBLABEL_DISK_CYCLE_TRAY_STATUS, - "Cycle the current disk. If the disk is inserted, it will eject the disk. If the disk has not been inserted, it will be inserted. ") + "Faire un cycle du disque actuel. Si le disque est inséré, il sera éjecté. Si le disque n'a pas été inséré, il sera inséré.") MSG_HASH(MENU_ENUM_SUBLABEL_DISK_INDEX, - "Change the disk index.") + "Changer l'index du disque.") MSG_HASH(MENU_ENUM_SUBLABEL_DISK_OPTIONS, - "Disk image management.") + "Gestion des images disque.") MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, - "Select a disk image to insert.") + "Sélectionnez une image disque à insérer.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, - "Makes sure the framerate is capped while inside the menu.") + "Assurez-vous que le nombre d'images par seconde est limité lorsque vous vous trouvez dans le menu.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_LAYOUT, - "Select a different layout for the XMB interface.") + "Sélectionnez une mise en page différente pour l'interface XMB.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_THEME, - "Select a different theme for the icon. Changes will take effect after you restart the program.") + "Sélectionnez un thème différent pour l'icône. Les modifications entreront en vigueur après le redémarrage du programme.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, - "Enable drop shadows for all icons. This will have a minor performance hit.") + "Activer les ombres portées pour toutes les icônes. Cela aura un coup mineur sur la performance.") MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_COLOR_THEME, "Choisir un thème de dégradé de couleur différent pour l'arrière plan.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_WALLPAPER_OPACITY, @@ -2949,7 +2949,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_MENU_WALLPAPER_OPACITY, MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MENU_COLOR_THEME, "Choisir un thème de dégradé de couleur différent pour l'arrière plan.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_RIBBON_ENABLE, - "Select an animated background effect. Can be GPU-intensive depending on the effect. If performance is unsatisfactory, either turn this off or revert to a simpler effect.") + "Sélectionnez un effet de fond animé. Peut être gourmand en GPU selon l'effet. Si les performances ne sont pas satisfaisantes, désactivez-le ou revenez à un effet plus simple.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_FONT, "Choisir une police principale différente pour le menu.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_IMAGES, @@ -2965,133 +2965,133 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_HISTORY, "Affiche l'onglet de l'historique dans le menu principal.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_ADD, - "Show the import content tab inside the main menu.") + "Affiche l'onglet du contenu d'importation dans le menu principal.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_PLAYLISTS, - "Show playlist tabs inside the main menu.") + "Affiche les onglets de la liste de lecture dans le menu principal.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN, - "Show startup screen in menu. This is automatically set to false after the program starts for the first time.") + "Affiche l'écran de démarrage dans le menu. Ceci est automatiquement défini sur factice après le premier démarrage du programme.") MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY, - "Modify the opacity of the header graphic.") + "Modifier l'opacité du graphique d'en-tête.") MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_FOOTER_OPACITY, - "Modify the opacity of the footer graphic.") + "Modifier l'opacité du graphique de pied de page.") MSG_HASH(MENU_ENUM_SUBLABEL_DPI_OVERRIDE_ENABLE, - "The menu normally scales itself dynamically. If you want to set a specific scaling size instead, enable this.") + "Le menu se redimensionne normalement de manière dynamique. Si vous souhaitez plutôt définir une taille de mise à l'échelle spécifique, activez cette option.") MSG_HASH(MENU_ENUM_SUBLABEL_DPI_OVERRIDE_VALUE, - "Set the custom scaling size here. NOTE: You have to enable 'DPI Override' for this scaling size to take effect.") + "Définissez la taille de mise à l'échelle personnalisée ici. REMARQUE: vous devez activer 'DPI Override' pour que cette taille de mise à l'échelle prenne effet.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_ASSETS_DIRECTORY, - "Save all downloaded files to this directory.") + "Enregistrer tous les fichiers téléchargés dans ce répertoire.") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_REMAPPING_DIRECTORY, - "Save all remapped controls to this directory.") + "Enregistrer tous les contrôles remappés dans ce répertoire.") MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_DIR_PATH, - "Directory where the program searches for content/cores.") + "Répertoire où le programme recherche le contenu/les cœurs.") MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, - "Application/core information files are stored here.") + "Les fichiers d’application/principaux sont stockés ici.") MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, - "If a joypad is plugged in, that joypad will be autoconfigured if a config file corresponding to it is present inside this directory.") + "Si une manette est branché, cette manette sera autoconfiguré si un fichier de configuration correspondant est présent dans ce répertoire.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, "Sauvegarder toutes les collections dans ce dossier.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, - "If set to a directory, content which is temporarily extracted (e.g. from archives) will be extracted to this directory." + "Si défini dans un répertoire, le contenu qui est temporairement extrait (par exemple à partir d’archives) sera extrait dans ce répertoire." ) MSG_HASH(MENU_ENUM_SUBLABEL_CURSOR_DIRECTORY, - "Saved queries are stored to this directory.") + "Les requêtes enregistrées sont stockées dans ce répertoire.") MSG_HASH( MENU_ENUM_SUBLABEL_CONTENT_DATABASE_DIRECTORY, "Les bases de données sont stockées dans ce répertoire." ) MSG_HASH( MENU_ENUM_SUBLABEL_ASSETS_DIRECTORY, - "This location is queried by default when menu interfaces try to look for loadable assets, etc." + "Cet emplacement est interrogé par défaut lorsque les interfaces de menu tentent de rechercher des actifs chargeables, etc." ) MSG_HASH(MENU_ENUM_SUBLABEL_SAVEFILE_DIRECTORY, - "Save all save files to this directory. If not set, will try to save inside the content file's working directory.") + "Enregistrez tous les fichiers de sauvegarde dans ce répertoire. S'il n'est pas défini, essaiera de sauvegarder dans le répertoire de travail du fichier de contenu.") MSG_HASH(MENU_ENUM_SUBLABEL_SAVESTATE_DIRECTORY, - "Save all save states to this directory. If not set, will try to save inside the content file's working directory.") + "Enregistrez tous les états de sauvegarde dans ce répertoire. S'il n'est pas défini, essaiera de sauvegarder dans le répertoire de travail du fichier de contenu.") MSG_HASH(MENU_ENUM_SUBLABEL_SCREENSHOT_DIRECTORY, "Dossier d'emplacement des captures d'écran.") MSG_HASH(MENU_ENUM_SUBLABEL_OVERLAY_DIRECTORY, - "Defines a directory where overlays are kept for easy access.") + "Définit un répertoire où les superpositions sont conservées pour un accès facile.") MSG_HASH( MENU_ENUM_SUBLABEL_CHEAT_DATABASE_PATH, "Les fichiers de triche sont stockés ici." ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_FILTER_DIR, - "Directory where audio DSP filter files are kept." + "Répertoire dans lequel les fichiers de filtres audio DSP sont conservés." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_FILTER_DIR, - "Directory where CPU-based video filter files are kept." + "Répertoire dans lequel les fichiers de filtres vidéo basés sur l'UC sont conservés." ) MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_DIR, - "Defines a directory where GPU-based video shader files are kept for easy access.") + "Définit un répertoire dans lequel les fichiers de shader vidéo basés sur un GPU sont conservés pour un accès facile.") MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_OUTPUT_DIRECTORY, - "Recordings will be dumped to this directory.") + "Les enregistrements seront sauvegardés dans ce répertoire.") MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_CONFIG_DIRECTORY, - "Recording configurations will be kept here.") + "Les configurations d'enregistrement seront conservées ici.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_PATH, "Choisir une police différente pour les notifications.") MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_APPLY_CHANGES, - "Changes to the shader configuration will take effect immediately. Use this if you changed the amount of shader passes, filtering, FBO scale, etc.") + "Les modifications apportées à la configuration du shader prendront effet immédiatement. Utilisez cette option si vous avez modifié le nombre de passes de shaders, de filtrage, d’échelle FBO, etc.") MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SHADER_NUM_PASSES, - "Increase or decrease the amount of shader pipeline passes. You can bind a separate shader to each pipeline pass and configure its scale and filtering." + "Augmentez ou diminuez le nombre de passes de pipeline de shaders. Vous pouvez lier un shader distincte à chaque pipeline et configurer son échelle et son filtrage." ) MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET, - "Load a shader preset. The shader pipeline will be automatically set-up.") + "Charger un préréglage de shader. Le pipeline de shader sera automatiquement configuré.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_AS, - "Save the current shader settings as a new shader preset.") + "Enregistrer les paramètres actuels du shader en tant que nouveau préréglage de shader.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_CORE, - "Save the current shader settings as the default settings for this application/core.") + "Enregistrer les paramètres de shader actuels en tant que paramètres par défaut pour cette application/coeur.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_GAME, - "Save the current shader settings as the default settings for the content.") + "Enregistrer les paramètres de shader actuels en tant que paramètres par défaut pour le contenu.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PARAMETERS, - "Modifies the current shader directly. Changes will not be saved to the preset file.") + "Modifie le shader actuel directement. Les modifications ne seront pas enregistrées dans le fichier prédéfini.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_PARAMETERS, - "Modifies the shader preset itself currently used in the menu.") + "Modifie le préréglage du shader lui-même actuellement utilisé dans le menu.") MSG_HASH( MENU_ENUM_SUBLABEL_CHEAT_NUM_PASSES, "Augmenter ou réduire le nombre de codes de triche." ) MSG_HASH(MENU_ENUM_SUBLABEL_CHEAT_APPLY_CHANGES, - "Cheat changes will take effect immediately.") + "Les changements de triche prendront effet immédiatement.") MSG_HASH( MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD, "Charger un fichier de triche." ) MSG_HASH( MENU_ENUM_SUBLABEL_CHEAT_FILE_SAVE_AS, - "Save current cheats as a save file." + "Enregistrer les astuces actuelles en tant que fichier de sauvegarde." ) MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SETTINGS, "Accéder rapidement aux options utiles en jeu.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_INFORMATION, - "View information pertaining to the application/core.") + "Afficher les informations relatives à l'application/au coeur.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_ASPECT_RATIO, - "Floating point value for video aspect ratio (width / height), used if the Aspect Ratio is set to 'Config'.") + "Valeur de virgule flottante pour le rapport d'aspect vidéo (largeur/hauteur), utilisée si le rapport d'aspect est défini sur 'Config'.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT, - "Custom viewport height that is used if the Aspect Ratio is set to 'Custom'.") + "Hauteur de fenêtre d'affichage personnalisée utilisée si le rapport d'aspect est défini sur 'Personnalisé'.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH, - "Custom viewport width that is used if the Aspect Ratio is set to 'Custom'.") + "Largeur de la fenêtre d'affichage utilisée si le rapport d'aspect est défini sur 'Personnalisé'.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_X, - "Custom viewport offset used for defining the X-axis position of the viewport. These are ignored if 'Integer Scale' is enabled. It will be automatically centered then.") + "Décalage de fenêtre personnalisé utilisé pour définir la position de l'axe X de la fenêtre. Celles-ci sont ignorées si «Échelle entière» est activé. Il sera automatiquement centré ensuite.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_Y, - "Custom viewport offset used for defining the Y-axis position of the viewport. These are ignored if 'Integer Scale' is enabled. It will be automatically centered then.") + "Décalage de la fenêtre d'affichage personnalisé utilisé pour définir la position de l'axe Y de la fenêtre d'affichage. Celles-ci sont ignorées si «Échelle entière» est activé. Il sera automatiquement centré ensuite.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_USE_MITM_SERVER, - "Use Relay Server") + "Utiliser le serveur relais") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, - "Forward netplay connections through a man-in-the-middle server. Useful if the host is behind a firewall or has NAT/UPnP problems.") + "Transférez les connexions netplay via un serveur intermédiaire. Utile si l'hôte est derrière un pare-feu ou a des problèmes de NAT/UPnP.") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, "Ajouter au mixeur") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_PLAY, - "Add to mixer and play") + "Ajouter au mixeur et joueur") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION, "Ajouter au mixeur") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY, - "Add to mixer and play") + "Ajouter au mixeur et joueur") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER_BY_CURRENT_CORE, - "Filter by current core") + "Filtrer par coeurs actuel") MSG_HASH( MSG_AUDIO_MIXER_VOLUME, "Volume global du mixeur audio" @@ -3165,27 +3165,27 @@ MSG_HASH(MSG_INPUT_ENABLE_SETTINGS_PASSWORD_NOK, MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, "Active l'onglet des réglages. Un redémarrage est requis pour que l'onglet s'affiche.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, - "Supplying a password when hiding the settings tab makes it possible to later restore it from the menu, by going to the Main Menu tab, selecting Enable Settings Tab and entering the password.") + "La saisie d'un mot de passe en masquant l'onglet des paramètres permet de le restaurer ultérieurement à partir du menu en accédant à l'onglet Menu principal, en sélectionnant Activer l'onglet Paramètres et en entrant le mot de passe.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, "Autoriser l'utilisateur à renommer les entrées des collections.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, - "Autoriser le renommage des entrées") + "Autoriser le renommage des entrées.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, - "Show Load Core") + "Afficher le coeur en charge.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CORE, - "Show/hide the 'Load Core' option.") + "Afficher/masquer l'option 'Charger coeur'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CONTENT, - "Show Load Content") + "Afficher le contenu du chargement.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CONTENT, - "Show/hide the 'Load Content' option.") + "Afficher/masquer l'option 'Charger le contenu'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_INFORMATION, - "Show Information") + "Montrer l'information.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_INFORMATION, - "Show/hide the 'Information' option.") + "Afficher/masquer l'option 'Information'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_CONFIGURATIONS, - "Show Configurations") + "Afficher les configurations") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_CONFIGURATIONS, - "Show/hide the 'Configurations' option.") + "Afficher/masquer l'option 'Configurations'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_HELP, "Afficher l'aide") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_HELP, @@ -3220,73 +3220,73 @@ MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT, MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_LOAD_STATE, "Afficher Sauver/Charger une sauvegarde instantanée") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE, - "Show/hide the options for saving/loading state.") + "Afficher/masquer les options pour enregistrer/charger l’état.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, - "Show Undo Save/Load State") + "Afficher annuler enregistrer/charger l'état") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, - "Show/hide the options for undoing save/load state.") + "Afficher/masquer les options pour annuler l'état d'enregistrement/de chargement.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_ADD_TO_FAVORITES, - "Show Add to Favorites") + "Afficher Ajouter aux favoris") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, - "Show/hide the 'Add to Favorites' option.") + "Afficher/masquer l'option'ajouter aux favoris'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_START_RECORDING, - "Show Start Recording") + "Afficher le début de l'enregistrement") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_START_RECORDING, - "Show/hide the 'Start Recording' option.") + "Afficher/masquer l'option 'Démarrer l'enregistrement'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_START_STREAMING, - "Show Start Streaming") + "Afficher démarrer le streaming") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_START_STREAMING, - "Show/hide the 'Start Streaming' option.") + "Afficher/masquer l'option 'Démarrer le streaming'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION, - "Show Reset Core Association") + "Afficher réinitialiser le coeur") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION, - "Show/hide the 'Reset Core Association' option.") + "Afficher/masquer l'option 'Réinitialiser l'association de base'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_OPTIONS, - "Show Options") + "Afficher les options") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_OPTIONS, - "Show/hide the 'Options' option.") + "Afficher/masquer l'option 'Options'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CONTROLS, - "Show Controls") + "Afficher les contrôles") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CONTROLS, - "Show/hide the 'Controls' option.") + "Afficher/masquer l'option 'Contrôles'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CHEATS, - "Show Cheats") + "Afficher les astuces") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CHEATS, - "Show/hide the 'Cheats' option.") + "Afficher / masquer l'option 'Astuces'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SHADERS, - "Show Shaders") + "Afficher Shaders") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SHADERS, - "Show/hide the 'Shaders' option.") + "Afficher/masquer l'option 'Shaders'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, - "Show Save Core Overrides") + "Afficher les remplacements de base") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, - "Show/hide the 'Save Core Overrides' option.") + "Afficher/masquer l'option «Remplacements de base».") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, - "Show Save Game Overrides") + "Afficher les remplacements de jeu") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, - "Show/hide the 'Save Game Overrides' option.") + "Afficher/masquer l'option «Remplacements de jeu».") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_INFORMATION, - "Show Information") + "Afficher les informations") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_INFORMATION, - "Show/hide the 'Information' option.") + "Afficher/masquer l'option 'Informations'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DISABLE_KIOSK_MODE, - "Disable Kiosk Mode") + "Désactiver le mode kiosque") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_DISABLE_KIOSK_MODE, - "Disables kiosk mode. A restart is required for the change to take full effect.") + "Désactive le mode kiosque. Un redémarrage est nécessaire pour que la modification prenne effet.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_ENABLE_KIOSK_MODE, - "Enable Kiosk Mode") + "Activer le mode kiosque") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENABLE_KIOSK_MODE, - "Protects the setup by hiding all configuration related settings.") + "Protège la configuration en cachant tous les paramètres liés à la configuration.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_KIOSK_MODE_PASSWORD, - "Set Password For Disabling Kiosk Mode") + "Définir le mot de passe pour désactiver le mode kiosque") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_KIOSK_MODE_PASSWORD, - "Supplying a password when enabling kiosk mode makes it possible to later disable it from the menu, by going to the Main Menu, selecting Disable Kiosk Mode and entering the password.") + "La fourniture d'un mot de passe lors de l'activation du mode kiosque permet de la désactiver ultérieurement dans le menu, en accédant au menu principal, en sélectionnant désactiver le mode kiosque et en saisissant le mot de passe.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD, - "Enter Password") + "Entrer le mot de passe") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, - "Password correct.") + "Mot de passe correct.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, - "Password incorrect.") + "Mot de passe incorrect.") MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, "Ajouter automatiquement le contenu à la playlist") MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, @@ -3296,113 +3296,113 @@ MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY, "Qualité du ré-échantilloneur audio") MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, - "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") + "Réduisez cette valeur pour favoriser la performance/latence inférieure sur la qualité audio, augmenter si vous voulez une meilleure qualité audio au détriment des performances/latence inférieure.") MSG_HASH(MENU_ENUM_LABEL_VALUE_STATISTICS_SHOW, - "Display Statistics") + "Afficher les statistiques") MSG_HASH(MENU_ENUM_SUBLABEL_STATISTICS_SHOW, - "Show onscreen technical statistics.") + "Afficher les statistiques techniques à l'écran.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_ENABLE, - "Enable border filler") + "Activer le remplissage de bordure") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, - "Enable border filler thickness") + "Activer l'épaisseur du remplissage de bordure") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, - "Enable background filler thickness") -MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For CRT displays only. Attempts to use exact core/game resolution and refresh rate.") + "Activer l'épaisseur de remplissage en arrière-plan") +MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "Pour les écrans CRT uniquement. Tentative d'utilisation de la résolution exacte du coeur/du jeu et du taux de rafraîchissement.") MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH( MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, - "Switch among native and ultrawide super resolutions." + "Basculez entre les super résolutions natives et ultrawides." ) MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, - "Show Rewind Settings") + "Afficher les paramètres de rembobinage") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, - "Show/hide the Rewind options.") + "Afficher/masquer les options de rembobinage.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_LATENCY, - "Show/hide the Latency options.") + "Afficher/masquer les options de latence.") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_LATENCY, - "Show Latency Settings") + "Afficher les paramètres de latence") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_OVERLAYS, - "Show/hide the Overlay options.") + "Afficher/masquer les options de superposition.") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_OVERLAYS, - "Show Overlay Settings") + "Afficher les paramètres overlay") MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE_MENU, - "Enable menu audio") + "Activer le menu audio") MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_ENABLE_MENU, - "Enable or disable menu sound.") + "Activer ou désactiver le son du menu.") MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_SETTINGS, - "Mixer Settings") + "Paramètres du mixeur") MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MIXER_SETTINGS, - "View and/or modify audio mixer settings.") + "Afficher et/ou modifier les paramètres du mélangeur audio.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS, - "Overrides") + "Dérogations") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_OVERRIDE_OPTIONS, - "Options for overriding the global configuration.") + "Options pour remplacer la configuration globale.") MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY, - "Will start playback of the audio stream. Once finished, it will remove the current audio stream from memory.") + "Va commencer la lecture du flux audio. Une fois terminé, il supprimera le flux audio actuel de la mémoire.") MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_LOOPED, - "Will start playback of the audio stream. Once finished, it will loop and play the track again from the beginning.") + "Va commencer la lecture du flux audio. Une fois terminé, il boucle et lit la piste à nouveau depuis le début.") MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_SEQUENTIAL, - "Will start playback of the audio stream. Once finished, it will jump to the next audio stream in sequential order and repeat this behavior. Useful as an album playback mode.") + "Va commencer la lecture du flux audio. Une fois terminé, il passera au prochain flux audio dans un ordre séquentiel et répétera ce comportement. Utile comme mode de lecture d'album.") MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_STOP, - "This will stop playback of the audio stream, but not remove it from memory. You can start playing it again by selecting 'Play'.") + "Cela arrêtera la lecture du flux audio, mais ne le supprimera pas de la mémoire. Vous pouvez recommencer à jouer en sélectionnant 'Jouer'.") MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_REMOVE, - "This will stop playback of the audio stream and remove it entirely from memory.") + "Cela arrêtera la lecture du flux audio et le supprimera entièrement de la mémoire.") MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_VOLUME, - "Adjust the volume of the audio stream.") + "Ajuster le volume du flux audio.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_MIXER, - "Add this audio track to an available audio stream slot. If no slots are currently available, it will be ignored.") + "Ajoutez cette piste audio à un emplacement de flux audio disponible. Si aucun créneau n'est disponible, il sera ignoré.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_MIXER_AND_PLAY, - "Add this audio track to an available audio stream slot and play it. If no slots are currently available, it will be ignored.") + "Ajoutez cette piste audio à un emplacement de flux audio disponible et lisez-la. Si aucun créneau n'est disponible, il sera ignoré.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY, - "Play") + "Jouer") MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_LOOPED, - "Play (Looped)") + "Jouer (en boucle)") MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_SEQUENTIAL, - "Play (Sequential)") + "Jouer (séquentiel)") MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_STOP, - "Stop") + "Stopper") MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_REMOVE, - "Remove") + "Effacer") MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_VOLUME, "Volume") MSG_HASH(MENU_ENUM_LABEL_VALUE_DETECT_CORE_LIST_OK_CURRENT_CORE, - "Current core") + "Coeur actuel") MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, - "Clear") + "Effacer") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, - "In-Menu") + "Dans le menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, - "In-Game") + "En jeu") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, - "In-Game (Paused)") + "En jeu (en pause)") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, - "Playing") + "Jouer") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, - "Paused") + "En pause") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, - "Enable Discord" + "Activer Discord" ) MSG_HASH( MENU_ENUM_SUBLABEL_DISCORD_ALLOW, - "Enable or disable Discord support. Will not work with the browser version, only native desktop client." + "Activer ou désactiver le support Discord. Ne fonctionnera pas avec la version du navigateur, uniquement avec le client de bureau natif." ) MSG_HASH(MENU_ENUM_LABEL_VALUE_POWER_MANAGEMENT_SETTINGS, - "Power Management") + "Gestion de l'alimentation") MSG_HASH(MENU_ENUM_SUBLABEL_POWER_MANAGEMENT_SETTINGS, - "Change power management settings.") + "Modifier les paramètres de gestion de l'alimentation.") MSG_HASH(MENU_ENUM_LABEL_VALUE_SUSTAINED_PERFORMANCE_MODE, - "Sustained Performance Mode") + "Mode de performance soutenue") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_MPV_SUPPORT, - "mpv support") + "support mpv") MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ADAPTIVE_VSYNC, - "Adaptive Vsync" + "V-Sync adaptatif" ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_ADAPTIVE_VSYNC, - "V-Sync is enabled until performance falls below the target refresh rate. Can minimize stuttering when performance falls below realtime, and can be more energy efficient." + "V-Sync est activé jusqu'à ce que les performances deviennent inférieures au taux de rafraîchissement cible. Peut minimiser le bégaiement lorsque les performances sont inférieures au temps réel et être plus économe en énergie." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CRT_SWITCHRES_SETTINGS, @@ -3410,83 +3410,83 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_CRT_SWITCHRES_SETTINGS, - "Output native, low-resolution signals for use with CRT displays." + "Produisez des signaux natifs à basse résolution pour une utilisation avec les écrans CRT." ) MSG_HASH( MENU_ENUM_SUBLABEL_CRT_SWITCH_X_AXIS_CENTERING, - "Cycle through these options if the image is not centered properly on the display." + "Parcourez ces options si l'image n'est pas centrée correctement sur l'écran." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CRT_SWITCH_X_AXIS_CENTERING, - "X-Axis Centering" + "Centrage sur l'axe X" ) MSG_HASH( MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_USE_CUSTOM_REFRESH_RATE, - "Use a custom refresh rate specified in the config file if needed.") + "Utilisez un taux de rafraîchissement personnalisé spécifié dans le fichier de configuration si nécessaire.") MSG_HASH( MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_USE_CUSTOM_REFRESH_RATE, - "Use Custom Refresh Rate") + "Utiliser le taux de rafraîchissement personnalisé") MSG_HASH( MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_OUTPUT_DISPLAY_ID, - "Select the output port connected to the CRT display.") + "Sélectionnez le port de sortie connecté à l'écran CRT.") MSG_HASH( MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_OUTPUT_DISPLAY_ID, - "Output Display ID") + "ID d'affichage de sortie") MSG_HASH( MENU_ENUM_LABEL_VALUE_QUICK_MENU_START_RECORDING, - "Start Recording" + "Commencer l'enregistrement" ) MSG_HASH( MENU_ENUM_SUBLABEL_QUICK_MENU_START_RECORDING, - "Starts recording." + "Commence l'enregistrement." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QUICK_MENU_STOP_RECORDING, - "Stop Recording" + "Arrête d'enregistrer" ) MSG_HASH( MENU_ENUM_SUBLABEL_QUICK_MENU_STOP_RECORDING, - "Stops recording." + "Arrête l'enregistrement." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QUICK_MENU_START_STREAMING, - "Start Streaming" + "Démarrer le streaming" ) MSG_HASH( MENU_ENUM_SUBLABEL_QUICK_MENU_START_STREAMING, - "Starts streaming." + "Démarre le streaming." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QUICK_MENU_STOP_STREAMING, - "Stop Streaming" + "Arrêter le streaming" ) MSG_HASH( MENU_ENUM_SUBLABEL_QUICK_MENU_STOP_STREAMING, - "Stops streaming." + "Arrête le streaming." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE, - "Recording toggle" + "Basculer en enregistrement" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE, - "Streaming toggle" + "Basculer en streaming" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_RECORD_QUALITY, - "Record Quality" + "Qualité d'enregistrement" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_STREAM_QUALITY, - "Stream Quality" + "Qualité du flux" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_STREAMING_URL, - "Streaming URL" + "URL Streaming" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_UDP_STREAM_PORT, - "UDP Stream Port" + "Port de flux UDP" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACCOUNTS_TWITCH, @@ -3497,24 +3497,24 @@ MSG_HASH( "YouTube" ) MSG_HASH(MENU_ENUM_LABEL_VALUE_TWITCH_STREAM_KEY, - "Twitch Stream Key") + "Clé Twitch Stream") MSG_HASH(MENU_ENUM_LABEL_VALUE_YOUTUBE_STREAM_KEY, - "YouTube Stream Key") + "Clé YouTube Stream") MSG_HASH(MENU_ENUM_LABEL_VALUE_STREAMING_MODE, - "Streaming Mode") + "Mode Streaming") MSG_HASH(MENU_ENUM_LABEL_VALUE_STREAMING_TITLE, - "Title of Stream") + "Titre du flux") MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_SPLIT_JOYCON, "Split Joy-Con" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_RESET_TO_DEFAULT_CONFIG, - "Reset To Defaults" + "Réinitialiser les paramètres par défaut" ) MSG_HASH( MENU_ENUM_SUBLABEL_RESET_TO_DEFAULT_CONFIG, - "Reset the current configuration to default values." + "Réinitialiser la configuration actuelle aux valeurs par défaut." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_OK, @@ -3524,53 +3524,53 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_OZONE_MENU_COLOR_THEME, "Couleur du thème du menu") MSG_HASH( MENU_ENUM_LABEL_VALUE_OZONE_COLOR_THEME_BASIC_WHITE, - "Basic White" + "Blanc de base" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_OZONE_COLOR_THEME_BASIC_BLACK, - "Basic Black" + "Noir de base" ) MSG_HASH( MENU_ENUM_SUBLABEL_OZONE_MENU_COLOR_THEME, - "Select a different color theme." + "Sélectionnez un thème de couleur différent." ) MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, - "Use preferred system color theme") + "Utiliser le thème de couleur système préféré") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, - "Use your operating system's color theme (if any) - overrides theme settings.") + "Utilisez le thème de couleur de votre système d'exploitation (le cas échéant) - remplace les paramètres du thème.") MSG_HASH(MSG_RESAMPLER_QUALITY_LOWEST, - "Lowest") + "Plus bas") MSG_HASH(MSG_RESAMPLER_QUALITY_LOWER, - "Lower") + "Inférieur") MSG_HASH(MSG_RESAMPLER_QUALITY_NORMAL, "Normal") MSG_HASH(MSG_RESAMPLER_QUALITY_HIGHER, - "Higher") + "Superieur") MSG_HASH(MSG_RESAMPLER_QUALITY_HIGHEST, - "Highest") + "Plus haut") MSG_HASH( MENU_ENUM_LABEL_VALUE_NO_MUSIC_AVAILABLE, - "No music available." + "Aucune musique disponible." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_NO_VIDEOS_AVAILABLE, - "No videos available." + "Aucune vidéo disponible." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_NO_IMAGES_AVAILABLE, - "No images available." + "Aucune image disponible." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_NO_FAVORITES_AVAILABLE, - "No favorites available." + "Pas de favoris disponibles." ) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_SAVE_POSITION, - "Remember Window Position and Size") + "Rappelez-vous la position et la taille de la fenêtre") MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT, - "CoreAudio support" + "Support CoreAudio" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT, - "CoreAudio V3 support" + "Support CoreAudio V3" ) From c168835c5fce6d7e85295327dcfe4482b057a9cc Mon Sep 17 00:00:00 2001 From: bubuleur Date: Wed, 20 Mar 2019 09:56:16 +0100 Subject: [PATCH 064/237] Update msg_hash_fr.h --- intl/msg_hash_fr.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 1e022a8fc1..bc0ca5c676 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -108,7 +108,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_MENU_HORIZONTAL_ANIMATION, - "Enable horizontal animation for the menu. This will have a performance hit." + "Activer l'animation horizontale pour le menu. Cela aura un succès sur la performance." ) MSG_HASH( MENU_ENUM_SUBLABEL_MENU_SETTINGS, @@ -208,11 +208,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, - "Assets" + "Actifs" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, - "Block Frames" + "Bloque cadres" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, @@ -1713,7 +1713,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_Y, "Position verticale personnalisée") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, - "Set VI Screen Width") + "Définir la largeur de l'écran VI") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, "Synchronisation verticale") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, @@ -1799,7 +1799,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "Afficher l'onglet Vidéo") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, - "Menu Layout") + "Menu mise en page") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, "Thème XMB") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, From 9f93ec107717a5519baeeb5f50b2193435b6af40 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Wed, 20 Mar 2019 09:46:18 +0000 Subject: [PATCH 065/237] (RGUI) Wii build fix --- menu/drivers/rgui.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 418bb10e9a..3a67f2d2f6 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -59,10 +59,10 @@ #include #if defined(GEKKO) -#define RGUI_TERM_START_X(fb_width) (width / 21) -#define RGUI_TERM_START_Y(fb_height) (height / 9) -#define RGUI_TERM_WIDTH(fb_width) (((width - RGUI_TERM_START_X(width) - RGUI_TERM_START_X(width)) / (FONT_WIDTH_STRIDE))) -#define RGUI_TERM_HEIGHT(fb_height) (((height - RGUI_TERM_START_Y(height) - RGUI_TERM_START_Y(height)) / (FONT_HEIGHT_STRIDE))) +#define RGUI_TERM_START_X(fb_width) (fb_width / 21) +#define RGUI_TERM_START_Y(fb_height) (fb_height / 9) +#define RGUI_TERM_WIDTH(fb_width) (((fb_width - RGUI_TERM_START_X(fb_width) - RGUI_TERM_START_X(fb_width)) / (FONT_WIDTH_STRIDE))) +#define RGUI_TERM_HEIGHT(fb_height) (((fb_height - RGUI_TERM_START_Y(fb_height) - RGUI_TERM_START_Y(fb_height)) / (FONT_HEIGHT_STRIDE))) #else #define RGUI_TERM_START_X(fb_width) rgui_term_layout.start_x #define RGUI_TERM_START_Y(fb_height) rgui_term_layout.start_y From f114e14d4857d8533ddc1c62e0d57979659b3c8f Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Wed, 20 Mar 2019 13:40:04 +0000 Subject: [PATCH 066/237] (RGUI) Overhaul 'Lock Menu Aspect Ratio' option --- config.def.h | 2 +- configuration.c | 2 +- configuration.h | 2 +- intl/msg_hash_lbl.h | 4 +- intl/msg_hash_us.h | 16 ++- menu/cbs/menu_cbs_sublabel.c | 6 +- menu/drivers/rgui.c | 223 +++++++++++++++++++++++++++++------ menu/menu_defines.h | 8 ++ menu/menu_displaylist.c | 4 +- menu/menu_setting.c | 50 ++++++-- msg_hash.h | 6 +- 11 files changed, 263 insertions(+), 60 deletions(-) diff --git a/config.def.h b/config.def.h index 451964cb52..a907065740 100644 --- a/config.def.h +++ b/config.def.h @@ -385,10 +385,10 @@ static bool show_advanced_settings = false; static unsigned rgui_color_theme = RGUI_THEME_CLASSIC_GREEN; static unsigned rgui_thumbnail_downscaler = RGUI_THUMB_SCALE_POINT; -static bool rgui_lock_aspect = false; static unsigned rgui_internal_upscale_level = RGUI_UPSCALE_NONE; static bool rgui_full_width_layout = true; static unsigned rgui_aspect = RGUI_ASPECT_RATIO_4_3; +static unsigned rgui_aspect_lock = RGUI_ASPECT_RATIO_LOCK_NONE; #else static bool default_block_config_read = false; diff --git a/configuration.c b/configuration.c index 5ff9b1b3f2..d0dab08378 100644 --- a/configuration.c +++ b/configuration.c @@ -1509,7 +1509,6 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("rgui_background_filler_thickness_enable", &settings->bools.menu_rgui_background_filler_thickness_enable, true, true, false); SETTING_BOOL("rgui_border_filler_thickness_enable", &settings->bools.menu_rgui_border_filler_thickness_enable, true, true, false); SETTING_BOOL("rgui_border_filler_enable", &settings->bools.menu_rgui_border_filler_enable, true, true, false); - SETTING_BOOL("menu_rgui_lock_aspect", &settings->bools.menu_rgui_lock_aspect, true, rgui_lock_aspect, false); SETTING_BOOL("menu_rgui_full_width_layout", &settings->bools.menu_rgui_full_width_layout, true, rgui_full_width_layout, false); #endif #ifdef HAVE_XMB @@ -1695,6 +1694,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("rgui_thumbnail_downscaler", &settings->uints.menu_rgui_thumbnail_downscaler, true, rgui_thumbnail_downscaler, false); SETTING_UINT("rgui_internal_upscale_level", &settings->uints.menu_rgui_internal_upscale_level, true, rgui_internal_upscale_level, false); SETTING_UINT("rgui_aspect_ratio", &settings->uints.menu_rgui_aspect_ratio, true, rgui_aspect, false); + SETTING_UINT("rgui_aspect_ratio_lock", &settings->uints.menu_rgui_aspect_ratio_lock, true, rgui_aspect_lock, false); #endif #ifdef HAVE_LIBNX SETTING_UINT("split_joycon_p1", &settings->uints.input_split_joycon[0], true, 0, false); diff --git a/configuration.h b/configuration.h index 82e3729aa4..d2057a8093 100644 --- a/configuration.h +++ b/configuration.h @@ -171,7 +171,6 @@ typedef struct settings bool menu_rgui_background_filler_thickness_enable; bool menu_rgui_border_filler_thickness_enable; bool menu_rgui_border_filler_enable; - bool menu_rgui_lock_aspect; bool menu_rgui_full_width_layout; bool menu_xmb_shadows_enable; bool menu_xmb_vertical_thumbnails; @@ -444,6 +443,7 @@ typedef struct settings unsigned menu_font_color_blue; unsigned menu_rgui_internal_upscale_level; unsigned menu_rgui_aspect_ratio; + unsigned menu_rgui_aspect_ratio_lock; unsigned menu_ticker_type; unsigned playlist_show_inline_core_name; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index aa62858979..50ee9ca329 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1605,12 +1605,12 @@ MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, "menu_rgui_border_filler_thickness_enable") MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "menu_rgui_background_filler_thickness_enable") -MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_LOCK_ASPECT, - "menu_rgui_lock_aspect") MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL, "rgui_internal_upscale_level") MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO, "rgui_aspect_ratio") +MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK, + "rgui_aspect_ratio_lock") MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT, "menu_rgui_full_width_layout") MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_REWIND, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 8564c7aa7e..daa8ca33aa 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3042,6 +3042,18 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_10_CENTRE, "16:10 (Centered)" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_NONE, + "OFF" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_FIT_SCREEN, + "Fit Screen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_INTEGER, + "Integer Scale" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, "Thumbnails" @@ -6813,11 +6825,11 @@ MSG_HASH( "Increase coarseness of menu background chequerboard pattern." ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_RGUI_LOCK_ASPECT, + MENU_ENUM_LABEL_VALUE_MENU_RGUI_ASPECT_RATIO_LOCK, "Lock Menu Aspect Ratio" ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_RGUI_LOCK_ASPECT, + MENU_ENUM_SUBLABEL_MENU_RGUI_ASPECT_RATIO_LOCK, "Ensures that the menu is always displayed with the correct aspect ratio. If disabled, the quick menu will be stretched to match the currently loaded content." ) MSG_HASH( diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 48d73cc31c..b55f1ae374 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -520,7 +520,7 @@ default_sublabel_macro(action_bind_sublabel_menu_rgui_border_filler_enable, default_sublabel_macro(action_bind_sublabel_menu_rgui_border_filler_thickness_enable, MENU_ENUM_SUBLABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE) default_sublabel_macro(action_bind_sublabel_menu_rgui_background_filler_thickness_enable, MENU_ENUM_SUBLABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE) default_sublabel_macro(action_bind_sublabel_menu_linear_filter, MENU_ENUM_SUBLABEL_MENU_LINEAR_FILTER) -default_sublabel_macro(action_bind_sublabel_menu_rgui_lock_aspect, MENU_ENUM_SUBLABEL_MENU_RGUI_LOCK_ASPECT) +default_sublabel_macro(action_bind_sublabel_menu_rgui_aspect_ratio_lock, MENU_ENUM_SUBLABEL_MENU_RGUI_ASPECT_RATIO_LOCK) default_sublabel_macro(action_bind_sublabel_rgui_menu_color_theme, MENU_ENUM_SUBLABEL_RGUI_MENU_COLOR_THEME) default_sublabel_macro(action_bind_sublabel_rgui_menu_theme_preset, MENU_ENUM_SUBLABEL_RGUI_MENU_THEME_PRESET) default_sublabel_macro(action_bind_sublabel_menu_rgui_thumbnail_downscaler, MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER) @@ -2387,8 +2387,8 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_MENU_LINEAR_FILTER: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_linear_filter); break; - case MENU_ENUM_LABEL_MENU_RGUI_LOCK_ASPECT: - BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_lock_aspect); + case MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_aspect_ratio_lock); break; case MENU_ENUM_LABEL_RGUI_MENU_COLOR_THEME: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_rgui_menu_color_theme); diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 418bb10e9a..06f30233db 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -427,6 +427,12 @@ typedef struct uint16_t border_light_color; } rgui_colors_t; +typedef struct +{ + unsigned aspect_ratio_idx; + video_viewport_t viewport; +} rgui_video_settings_t; + typedef struct { bool bg_modified; @@ -450,8 +456,9 @@ typedef struct char menu_title[255]; /* Must be a fixed length array... */ char menu_sublabel[255]; /* Must be a fixed length array... */ unsigned menu_aspect_ratio; - unsigned menu_aspect_ratio_idx; - unsigned content_aspect_ratio_idx; + unsigned menu_aspect_ratio_lock; + rgui_video_settings_t menu_video_settings; + rgui_video_settings_t content_video_settings; struct scaler_ctx image_scaler; } rgui_t; @@ -1912,6 +1919,127 @@ static void rgui_wallpaper_free(void) wallpaper.data = NULL; } +bool rgui_is_video_config_equal(rgui_video_settings_t *config_a, rgui_video_settings_t *config_b) +{ + return (config_a->aspect_ratio_idx == config_b->aspect_ratio_idx) && + (config_a->viewport.width == config_b->viewport.width) && + (config_a->viewport.height == config_b->viewport.height) && + (config_a->viewport.x == config_b->viewport.x) && + (config_a->viewport.y == config_b->viewport.y); +} + +static void rgui_get_video_config(rgui_video_settings_t *video_settings) +{ + settings_t *settings = config_get_ptr(); + /* Could use settings->video_viewport_custom directly, + * but this seems to be the standard way of doing it... */ + video_viewport_t *custom_vp = video_viewport_get_custom(); + + if (!settings) + return; + + video_settings->aspect_ratio_idx = settings->uints.video_aspect_ratio_idx; + video_settings->viewport.width = custom_vp->width; + video_settings->viewport.height = custom_vp->height; + video_settings->viewport.x = custom_vp->x; + video_settings->viewport.y = custom_vp->y; +} + +static void rgui_set_video_config(rgui_video_settings_t *video_settings) +{ + settings_t *settings = config_get_ptr(); + /* Could use settings->video_viewport_custom directly, + * but this seems to be the standard way of doing it... */ + video_viewport_t *custom_vp = video_viewport_get_custom(); + + if (!settings) + return; + + settings->uints.video_aspect_ratio_idx = video_settings->aspect_ratio_idx; + custom_vp->width = video_settings->viewport.width; + custom_vp->height = video_settings->viewport.height; + custom_vp->x = video_settings->viewport.x; + custom_vp->y = video_settings->viewport.y; + + aspectratio_lut[ASPECT_RATIO_CUSTOM].value = + (float)custom_vp->width / custom_vp->height; + + video_driver_set_aspect_ratio(); +} + +/* Note: This function is only called when aspect ratio + * lock is enabled */ +static void rgui_update_menu_viewport(rgui_t *rgui) +{ + settings_t *settings = config_get_ptr(); + size_t fb_pitch; + unsigned fb_width, fb_height; + struct video_viewport vp; + + if (!settings) + return; + + menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch); + video_driver_get_viewport_info(&vp); + + /* Could do this once in rgui_init(), but seems cleaner to + * handle all video config in one place... */ + rgui->menu_video_settings.aspect_ratio_idx = ASPECT_RATIO_CUSTOM; + + /* Determine custom viewport layout */ + if (fb_width > 0 && fb_height > 0 && vp.full_width > 0 && vp.full_height > 0) + { + /* Check whether we need to perform integer scaling */ + bool do_integer_scaling = (settings->uints.menu_rgui_aspect_ratio_lock == RGUI_ASPECT_RATIO_LOCK_INTEGER); + + if (do_integer_scaling) + { + unsigned width_scale = (vp.full_width / fb_width); + unsigned height_scale = (vp.full_height / fb_height); + unsigned scale = (width_scale <= height_scale) ? width_scale : height_scale; + + if (scale > 0) + { + rgui->menu_video_settings.viewport.width = scale * fb_width; + rgui->menu_video_settings.viewport.height = scale * fb_height; + } + else + do_integer_scaling = false; + } + + if (!do_integer_scaling) + { + float display_aspect_ratio = (float)vp.full_width / (float)vp.full_height; + float aspect_ratio = (float)fb_width / (float)fb_height; + + if (aspect_ratio > display_aspect_ratio) + { + rgui->menu_video_settings.viewport.width = vp.full_width; + rgui->menu_video_settings.viewport.height = fb_height * vp.full_width / fb_width; + } + else + { + rgui->menu_video_settings.viewport.height = vp.full_height; + rgui->menu_video_settings.viewport.width = fb_width * vp.full_height / fb_height; + } + } + + /* Sanity check */ + rgui->menu_video_settings.viewport.width = (rgui->menu_video_settings.viewport.width < 1) ? + 1 : rgui->menu_video_settings.viewport.width; + rgui->menu_video_settings.viewport.height = (rgui->menu_video_settings.viewport.height < 1) ? + 1 : rgui->menu_video_settings.viewport.height; + } + else + { + rgui->menu_video_settings.viewport.width = 1; + rgui->menu_video_settings.viewport.height = 1; + } + + rgui->menu_video_settings.viewport.x = (vp.full_width - rgui->menu_video_settings.viewport.width) / 2; + rgui->menu_video_settings.viewport.y = (vp.full_height - rgui->menu_video_settings.viewport.height) / 2; +} + static bool rgui_set_aspect_ratio(rgui_t *rgui) { #if !defined(GEKKO) @@ -1933,7 +2061,6 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui) rgui_frame_buf.height = 240; rgui_frame_buf.width = 320; base_term_width = rgui_frame_buf.width; - rgui->menu_aspect_ratio_idx = ASPECT_RATIO_4_3; /* Allocate frame buffer * (4 extra lines to cache the chequered background) */ @@ -1950,28 +2077,23 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui) case RGUI_ASPECT_RATIO_16_9: rgui_frame_buf.width = 426; base_term_width = rgui_frame_buf.width; - rgui->menu_aspect_ratio_idx = ASPECT_RATIO_16_9; break; case RGUI_ASPECT_RATIO_16_9_CENTRE: rgui_frame_buf.width = 426; base_term_width = 320; - rgui->menu_aspect_ratio_idx = ASPECT_RATIO_16_9; break; case RGUI_ASPECT_RATIO_16_10: rgui_frame_buf.width = 384; base_term_width = rgui_frame_buf.width; - rgui->menu_aspect_ratio_idx = ASPECT_RATIO_16_10; break; case RGUI_ASPECT_RATIO_16_10_CENTRE: rgui_frame_buf.width = 384; base_term_width = 320; - rgui->menu_aspect_ratio_idx = ASPECT_RATIO_16_10; break; default: /* 4:3 */ rgui_frame_buf.width = 320; base_term_width = rgui_frame_buf.width; - rgui->menu_aspect_ratio_idx = ASPECT_RATIO_4_3; break; } @@ -2020,12 +2142,10 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui) /* If aspect ratio lock is enabled, notify * video driver of change */ - if (settings->bools.menu_rgui_lock_aspect) + if (settings->uints.menu_rgui_aspect_ratio_lock != RGUI_ASPECT_RATIO_LOCK_NONE) { - unsigned aspect_ratio_idx = settings->uints.video_aspect_ratio_idx; - settings->uints.video_aspect_ratio_idx = rgui->menu_aspect_ratio_idx; - video_driver_set_aspect_ratio(); - settings->uints.video_aspect_ratio_idx = aspect_ratio_idx; + rgui_update_menu_viewport(rgui); + rgui_set_video_config(&rgui->menu_video_settings); } return true; @@ -2053,9 +2173,13 @@ static void *rgui_init(void **userdata, bool video_is_threaded) rgui->menu_title[0] = '\0'; rgui->menu_sublabel[0] = '\0'; + /* Cache initial video settings */ + rgui_get_video_config(&rgui->content_video_settings); + /* Set aspect ratio * - Allocates frame buffer * - Configures variable 'menu display' settings */ + rgui->menu_aspect_ratio_lock = settings->uints.menu_rgui_aspect_ratio_lock; if (!rgui_set_aspect_ratio(rgui)) goto error; @@ -2160,6 +2284,21 @@ static void rgui_frame(void *data, video_frame_info_t *video_info) if (settings->uints.menu_rgui_aspect_ratio != rgui->menu_aspect_ratio) rgui_set_aspect_ratio(rgui); + + if (settings->uints.menu_rgui_aspect_ratio_lock != rgui->menu_aspect_ratio_lock) + { + rgui->menu_aspect_ratio_lock = settings->uints.menu_rgui_aspect_ratio_lock; + + if (settings->uints.menu_rgui_aspect_ratio_lock == RGUI_ASPECT_RATIO_LOCK_NONE) + { + rgui_set_video_config(&rgui->content_video_settings); + } + else + { + rgui_update_menu_viewport(rgui); + rgui_set_video_config(&rgui->menu_video_settings); + } + } } static void rgui_set_texture(void) @@ -2423,9 +2562,10 @@ static void rgui_populate_entries(void *data, const char *path, const char *label, unsigned k) { - rgui_t *rgui = (rgui_t*)data; + rgui_t *rgui = (rgui_t*)data; + settings_t *settings = config_get_ptr(); - if (!rgui) + if (!rgui || !settings) return; /* Check whether we are currently viewing a playlist */ @@ -2438,6 +2578,22 @@ static void rgui_populate_entries(void *data, menu_entries_get_title(rgui->menu_title, sizeof(rgui->menu_title)); rgui_navigation_set(data, true); + + /* If aspect ratio lock is enabled, must restore + * content video settings when accessing the video + * settings menu... */ + if (settings->uints.menu_rgui_aspect_ratio_lock != RGUI_ASPECT_RATIO_LOCK_NONE) + { + if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_VIDEO_SETTINGS_LIST))) + { + /* Make sure that any changes made while accessing + * the video settings menu are preserved */ + rgui_video_settings_t current_video_settings = {0}; + rgui_get_video_config(¤t_video_settings); + if (rgui_is_video_config_equal(¤t_video_settings, &rgui->menu_video_settings)) + rgui_set_video_config(&rgui->content_video_settings); + } + } } static int rgui_environ(enum menu_environ_cb type, @@ -2505,36 +2661,29 @@ static void rgui_toggle(void *userdata, bool menu_on) if (!rgui || !settings) return; - if (settings->bools.menu_rgui_lock_aspect) + if (settings->uints.menu_rgui_aspect_ratio_lock != RGUI_ASPECT_RATIO_LOCK_NONE) { if (menu_on) { - /* Cache last used content aspect ratio */ - rgui->content_aspect_ratio_idx = settings->uints.video_aspect_ratio_idx; + /* Cache content video settings */ + rgui_get_video_config(&rgui->content_video_settings); - /* Check if aspect ratio needs to change */ - if (rgui->content_aspect_ratio_idx != rgui->menu_aspect_ratio_idx) - { - settings->uints.video_aspect_ratio_idx = rgui->menu_aspect_ratio_idx; - video_driver_set_aspect_ratio(); - - /* If content is using a custom aspect ratio, we - * have to stop here - otherwise, restore content - * aspect ratio setting */ - if (rgui->content_aspect_ratio_idx != ASPECT_RATIO_CUSTOM) - settings->uints.video_aspect_ratio_idx = rgui->content_aspect_ratio_idx; - } + /* Update menu viewport */ + rgui_update_menu_viewport(rgui); + + /* Apply menu video settings */ + rgui_set_video_config(&rgui->menu_video_settings); } else { - /* If content is using a custom aspect ratio, this - * must be restored */ - if (rgui->content_aspect_ratio_idx == ASPECT_RATIO_CUSTOM - && settings->uints.video_aspect_ratio_idx == rgui->menu_aspect_ratio_idx) - settings->uints.video_aspect_ratio_idx = rgui->content_aspect_ratio_idx; + /* Restore content video settings *if* user + * has not changed video settings since menu was + * last toggled on */ + rgui_video_settings_t current_video_settings = {0}; + rgui_get_video_config(¤t_video_settings); - if (settings->uints.video_aspect_ratio_idx != rgui->menu_aspect_ratio_idx) - video_driver_set_aspect_ratio(); + if (rgui_is_video_config_equal(¤t_video_settings, &rgui->menu_video_settings)) + rgui_set_video_config(&rgui->content_video_settings); } } diff --git a/menu/menu_defines.h b/menu/menu_defines.h index 95d3ff04b3..8ea24d035d 100644 --- a/menu/menu_defines.h +++ b/menu/menu_defines.h @@ -259,6 +259,14 @@ enum rgui_aspect_ratio RGUI_ASPECT_RATIO_LAST }; +enum rgui_aspect_ratio_lock +{ + RGUI_ASPECT_RATIO_LOCK_NONE = 0, + RGUI_ASPECT_RATIO_LOCK_FIT_SCREEN, + RGUI_ASPECT_RATIO_LOCK_INTEGER, + RGUI_ASPECT_RATIO_LOCK_LAST +}; + enum menu_action { MENU_ACTION_NOOP = 0, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 7fde7b8ec1..dc34e08f16 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6119,8 +6119,8 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist PARSE_ONLY_UINT, false) == 0) count++; if (menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MENU_RGUI_LOCK_ASPECT, - PARSE_ONLY_BOOL, false) == 0) + MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK, + PARSE_ONLY_UINT, false) == 0) count++; if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 984712fdbd..9217f2be3f 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -933,6 +933,36 @@ static void setting_get_string_representation_uint_rgui_aspect_ratio( } } +static void setting_get_string_representation_uint_rgui_aspect_ratio_lock( + rarch_setting_t *setting, + char *s, size_t len) +{ + if (!setting) + return; + + switch (*setting->value.target.unsigned_integer) + { + case RGUI_ASPECT_RATIO_LOCK_NONE: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_NONE), + len); + break; + case RGUI_ASPECT_RATIO_LOCK_FIT_SCREEN: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_FIT_SCREEN), + len); + break; + case RGUI_ASPECT_RATIO_LOCK_INTEGER: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_INTEGER), + len); + break; + } +} + static void setting_get_string_representation_uint_menu_ticker_type( rarch_setting_t *setting, char *s, size_t len) @@ -8353,21 +8383,21 @@ static bool setting_append_list( menu_settings_list_current_add_range(list, list_info, 0, RGUI_ASPECT_RATIO_LAST-1, 1, true, true); #endif - CONFIG_BOOL( + CONFIG_UINT( list, list_info, - &settings->bools.menu_rgui_lock_aspect, - MENU_ENUM_LABEL_MENU_RGUI_LOCK_ASPECT, - MENU_ENUM_LABEL_VALUE_MENU_RGUI_LOCK_ASPECT, - true, - MENU_ENUM_LABEL_VALUE_OFF, - MENU_ENUM_LABEL_VALUE_ON, + &settings->uints.menu_rgui_aspect_ratio_lock, + MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK, + MENU_ENUM_LABEL_VALUE_MENU_RGUI_ASPECT_RATIO_LOCK, + rgui_aspect_lock, &group_info, &subgroup_info, parent_group, general_write_handler, - general_read_handler, - SD_FLAG_NONE - ); + 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_rgui_aspect_ratio_lock; + menu_settings_list_current_add_range(list, list_info, 0, RGUI_ASPECT_RATIO_LOCK_LAST-1, 1, true, true); CONFIG_UINT( list, list_info, diff --git a/msg_hash.h b/msg_hash.h index 2bf42c3415..c3b8b033bf 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -865,9 +865,9 @@ enum msg_hash_enums MENU_LABEL(MENU_RGUI_BORDER_FILLER_ENABLE), MENU_LABEL(MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE), MENU_LABEL(MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE), - MENU_LABEL(MENU_RGUI_LOCK_ASPECT), MENU_LABEL(MENU_RGUI_INTERNAL_UPSCALE_LEVEL), MENU_LABEL(MENU_RGUI_ASPECT_RATIO), + MENU_LABEL(MENU_RGUI_ASPECT_RATIO_LOCK), MENU_LABEL(MENU_RGUI_FULL_WIDTH_LAYOUT), MENU_LABEL(MENU_LINEAR_FILTER), MENU_LABEL(MENU_HORIZONTAL_ANIMATION), @@ -1992,6 +1992,10 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_10, MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_16_10_CENTRE, + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_NONE, + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_FIT_SCREEN, + MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_INTEGER, + /* Callback strings */ MENU_ENUM_LABEL_CB_CORE_CONTENT_DIRS_LIST, MENU_ENUM_LABEL_CB_CORE_CONTENT_DOWNLOAD, From be9a8c0e18a256158927ff097606a32030d05d36 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 20 Mar 2019 18:00:14 +0100 Subject: [PATCH 067/237] Buildfix --- menu/drivers/rgui.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index a5faadc812..09af66b711 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -2042,10 +2042,8 @@ static void rgui_update_menu_viewport(rgui_t *rgui) static bool rgui_set_aspect_ratio(rgui_t *rgui) { -#if !defined(GEKKO) - settings_t *settings = config_get_ptr(); -#endif unsigned base_term_width; + settings_t *settings = config_get_ptr(); rgui_framebuffer_free(); rgui_thumbnail_free(); @@ -2055,12 +2053,11 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui) rgui->menu_aspect_ratio = settings->uints.menu_rgui_aspect_ratio; #if defined(GEKKO) - /* Set frame buffer dimensions * and update menu aspect index */ rgui_frame_buf.height = 240; - rgui_frame_buf.width = 320; - base_term_width = rgui_frame_buf.width; + rgui_frame_buf.width = 320; + base_term_width = rgui_frame_buf.width; /* Allocate frame buffer * (4 extra lines to cache the chequered background) */ From 1f9928c677813ab93e72c96de49b548fa34d61c0 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 20 Mar 2019 22:30:39 +0100 Subject: [PATCH 068/237] Revert "Update french translation" --- intl/msg_hash_fr.h | 468 ++++++++++++++++++++++----------------------- 1 file changed, 234 insertions(+), 234 deletions(-) diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index bc0ca5c676..1fe39d6a1f 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -108,7 +108,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_MENU_HORIZONTAL_ANIMATION, - "Activer l'animation horizontale pour le menu. Cela aura un succès sur la performance." + "Enable horizontal animation for the menu. This will have a performance hit." ) MSG_HASH( MENU_ENUM_SUBLABEL_MENU_SETTINGS, @@ -208,11 +208,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, - "Actifs" + "Assets" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, - "Bloque cadres" + "Block Frames" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, @@ -993,7 +993,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_HORIZONTAL_ANIMATION, "Horizontal Animation") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, - "Apparence") + "Appearance") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER, "Fond d'écran") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY, @@ -1667,7 +1667,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "Fréquence estimée de l'écran") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, - "Définir le taux de rafraîchissement signalé par l'affichage") + "Set Display-Reported Refresh Rate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "Rotation") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, @@ -1713,7 +1713,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_Y, "Position verticale personnalisée") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, - "Définir la largeur de l'écran VI") + "Set VI Screen Width") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, "Synchronisation verticale") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, @@ -1733,11 +1733,11 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "Transparence du fond") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_RED, - "Police de menu couleur rouge") + "Menu Font Red Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_GREEN, - "Police de menu couleur verte") + "Menu Font Green Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_BLUE, - "Police de menu couleur bleue") + "Menu Font Blue Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "Police du menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, @@ -1799,7 +1799,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "Afficher l'onglet Vidéo") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, - "Menu mise en page") + "Menu Layout") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, "Thème XMB") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, @@ -1901,7 +1901,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "Taux de rafraîchissement estimé de l'écran en Hz.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED, - "Le taux de rafraîchissement indiqué par le pilote d'affichage.") + "The refresh rate as reported by the display driver.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, "Ajuster les paramètres de sortie vidéo.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2561,11 +2561,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, - "Uniquement les échelles vidéo dans les étapes entières. La taille de base dépend de la géométrie et du rapport d'aspect signalés par le système. Si 'Force Aspect' n'est pas défini, X/Y sera entier et mis à l'échelle indépendamment." + "Only scales video in integer steps. The base size depends on system-reported geometry and aspect ratio. If 'Force Aspect' is not set, X/Y will be integer scaled independently." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT, - "Sortie des captures d'écran du matériel ombré par le GPU, si disponible." + "Screenshots output of GPU shaded material if available." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_ROTATION, @@ -2573,7 +2573,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_FORCE_SRGB_DISABLE, - "Désactivez de force le support sRGB FBO. Certains pilotes Intel OpenGL sous Windows rencontrent des problèmes vidéo avec la prise en charge de sRGB FBO, le cas échéant. Activer cela peut fonctionner autour de cela." + "Forcibly disable sRGB FBO support. Some Intel OpenGL drivers on Windows have video problems with sRGB FBO support if this is enabled. Enabling this can work around it." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN, @@ -2585,23 +2585,23 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_GPU_RECORD, - "Enregistre la sortie du matériel ombré GPU si disponible." + "Records output of GPU shaded material if available." ) MSG_HASH( MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX, - "Lors de la création d'un état de sauvegarde, l'index d'état de sauvegarde est automatiquement augmenté avant d'être enregistré. Lors du chargement du contenu, l'index sera défini sur le plus haut index existant." + "When making a savestate, save state index is automatically increased before it is saved. When loading content, the index will be set to the highest existing index." ) MSG_HASH( MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE, - "Bloquer la sauvegarde de la RAM afin qu'elle ne soit pas écrasée lors du chargement des états de sauvegarde." + "Block Save RAM from being overwritten when loading save states. Might potentially lead to buggy games." ) MSG_HASH( MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO, - "Taux maximal auquel le contenu sera exécuté lors de l’utilisation de l’avance rapide (par exemple, 5,0x pour un contenu de 60 ips = limite de 300 ips). Si défini à 0,0x, le rapport de rapidité est illimité (pas de limite de FPS)." + "The maximum rate at which content will be run when using fast forward (e.g., 5.0x for 60 fps content = 300 fps cap). If set to 0.0x, fastforward ratio is unlimited (no FPS cap)." ) MSG_HASH( MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, - "Au ralenti, le contenu sera ralenti du facteur spécifié/défini." + "When in slow motion, content will slow down by the factor specified/set." ) MSG_HASH( MENU_ENUM_SUBLABEL_REWIND_ENABLE, @@ -2609,15 +2609,15 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_REWIND_GRANULARITY, - "Lors du rembobinage d’un nombre défini d’images, vous pouvez rembobiner plusieurs images à la fois, ce qui augmente la vitesse de rembobinage." + "When rewinding a defined number of frames, you can rewind several frames at a time, increasing the rewind speed." ) MSG_HASH( MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL, - "Définit le niveau de journalisation des cœurs. Si un niveau de journalisation émis par un core est inférieur à cette valeur, il est ignoré." + "Sets log level for cores. If a log level issued by a core is below this value, it is ignored." ) MSG_HASH( MENU_ENUM_SUBLABEL_PERFCNT_ENABLE, - "Activer les compteurs de performance pour RetroArch (et les coeurs)." + "Enable performance counters for RetroArch (and cores)." ) MSG_HASH( MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_SAVE, @@ -2633,7 +2633,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL, - "Sauvegarde automatique la mémoire RAM non volatile à un intervalle régulier. Ceci est désactivé par défaut sauf indication contraire. L'intervalle est mesuré en secondes. Une valeur de 0 désactive la sauvegarde automatique." + "Autosaves the non-volatile Save RAM at a regular interval. This is disabled by default unless set otherwise. The interval is measured in seconds. A value of 0 disables autosave." ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE, @@ -2705,11 +2705,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_DEVICE, - "Remplacez le périphérique audio par défaut utilisé par le pilote audio. Ceci dépend du pilote." + "Override the default audio device the audio driver uses. This is driver dependent." ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_DSP_PLUGIN, - "Plugin audio DSP qui traite l'audio avant qu'il ne soit envoyé au pilote." + "Audio DSP plugin that processes audio before it's sent to the driver." ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_OUTPUT_RATE, @@ -2757,23 +2757,23 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_ALLOW_SLAVES, - "Autoriser ou non les connexions en mode esclave. Les clients en mode esclave nécessitent très peu de puissance de traitement de part et d’autre, mais souffrent considérablement de la latence du réseau." + "Whether to allow connections in slave mode. Slave-mode clients require very little processing power on either side, but will suffer significantly from network latency." ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_REQUIRE_SLAVES, - "Interdire les connexions non en mode esclave. Non recommandé sauf pour les réseaux très rapides avec des machines très faibles." + "Whether to disallow connections not in slave mode. Not recommended except for very fast networks with very weak machines." ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_STATELESS_MODE, - "Exécuter ou non netplay dans un mode ne nécessitant pas d’état de sauvegarde. Si défini sur true, un réseau très rapide est requis, mais aucun rembobinage n'est effectué. Il n'y aura donc pas de jitter sur Netplay." + "Whether to run netplay in a mode not requiring save states. If set to true, a very fast network is required, but no rewinding is performed, so there will be no netplay jitter." ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_CHECK_FRAMES, - "La fréquence dans les cadres avec laquelle netplay vérifiera que l'hôte et le client sont synchronisés." + "The frequency in frames with which netplay will verify that the host and client are in sync." ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_NAT_TRAVERSAL, - "Lors de l'hébergement, essayez d'écouter les connexions à partir d'Internet public, en utilisant UPnP ou des technologies similaires pour échapper aux réseaux locaux." + "When hosting, attempt to listen for connections from the public Internet, using UPnP or similar technologies to escape LANs." ) MSG_HASH( MENU_ENUM_SUBLABEL_STDIN_CMD_ENABLE, @@ -2816,20 +2816,20 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, "Analyse un fichier pour vérifier s'il est compatible et l'ajouter à une playlist.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, - "Utilise un intervalle d'échange personnalisé pour Vsync. Définissez cette option pour réduire de moitié le taux de rafraîchissement du moniteur." + "Uses a custom swap interval for Vsync. Set this to effectively halve monitor refresh rate." ) MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE, - "Tri des fichiers de sauvegarde dans des dossiers nommés d'après le coeur utilisé." + "Sort save files in folders named after the core used." ) MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE, - "Tri des états de sauvegarde dans des dossiers nommés d'après le coeur utilisé." + "Sort save states in folders named after the core used." ) MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL, - "URL du répertoire principal du programme de mise à jour sur le buildbot Libretro.") + "URL to core updater directory on the Libretro buildbot.") MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL, - "URL du répertoire de mise à jour des actifs sur le buildbot Libretro.") + "URL to assets updater directory on the Libretro buildbot.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, - "Après le téléchargement, extrayez automatiquement les fichiers contenus dans les archives téléchargées." + "After downloading, automatically extract files contained in the downloaded archives." ) MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Rafraîchir la liste des salons.") @@ -2874,12 +2874,12 @@ MSG_HASH(MENU_ENUM_SUBLABEL_RESUME_CONTENT, MSG_HASH(MENU_ENUM_SUBLABEL_STATE_SLOT, "Changer l'emplacement de destination de la sauvegarde instantanée.") MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_LOAD_STATE, - "Si un état a été chargé, le contenu reviendra à l'état avant le chargement.") + "If a state was loaded, content will go back to the state prior to loading.") MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_SAVE_STATE, - "Si un état a été écrasé, il reviendra à l'état de sauvegarde précédent.") + "If a state was overwritten, it will roll back to the previous save state.") MSG_HASH( MENU_ENUM_SUBLABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, - "Service de réalisations Retro. Pour plus d'informations, visitez http://retroachievements.org" + "Retro Achievements service. For more information, visit http://retroachievements.org" ) MSG_HASH( MENU_ENUM_SUBLABEL_ACCOUNTS_LIST, @@ -2904,7 +2904,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_OPTIONS, MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, "Afficher les options avancées pour les utilisateurs expérimentés (invisible par défaut).") MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, - "Effectuer des tâches sur un fil séparé.") + "Perform tasks on a separate thread.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, "Autoriser l'utilisateur à supprimer des entrées des collections") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, @@ -2913,35 +2913,35 @@ MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, "Définir le répertoire de début pour l'exporateur de fichiers.") MSG_HASH( MENU_ENUM_SUBLABEL_CONTENT_DIR, - "Généralement définie par les développeurs qui regroupent les applications Libretro/RetroArch pour pointer sur des éléments." + "Usually set by developers who bundle libretro/RetroArch apps to point to assets." ) MSG_HASH(MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPERS_DIRECTORY, - "Répertoire pour stocker les fonds d'écran chargés dynamiquement par le menu en fonction du contexte.") + "Directory to store wallpapers dynamically loaded by the menu depending on context.") MSG_HASH(MENU_ENUM_SUBLABEL_THUMBNAILS_DIRECTORY, - "Des vignettes supplémentaires (Boxarts/images diverses, etc.) sont stockées ici." + "Supplementary thumbnails (boxarts/misc. images, etc.) are stored here." ) MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_CONFIG_DIRECTORY, - "Définit le répertoire de départ pour le navigateur de configuration de menu.") + "Sets start directory for menu configuration browser.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, - "Nombre d'images de latence d'entrée que netplay doit utiliser pour masquer la latence du réseau. Réduit la gigue et rend netplay moins gourmand en ressources processeur, aux dépens d'un décalage d'entrée notable.") + "The number of frames of input latency for netplay to use to hide network latency. Reduces jitter and makes netplay less CPU-intensive, at the expense of noticeable input lag.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, - "Plage de trames de latence d'entrée pouvant être utilisée pour masquer la latence du réseau. Réduit la gigue et rend netplay moins gourmand en ressources processeur, aux dépens d'un retard d'entrée imprévisible.") + "The range of frames of input latency that may be used to hide network latency. Reduces jitter and makes netplay less CPU-intensive, at the expense of unpredictable input lag.") MSG_HASH(MENU_ENUM_SUBLABEL_DISK_CYCLE_TRAY_STATUS, - "Faire un cycle du disque actuel. Si le disque est inséré, il sera éjecté. Si le disque n'a pas été inséré, il sera inséré.") + "Cycle the current disk. If the disk is inserted, it will eject the disk. If the disk has not been inserted, it will be inserted. ") MSG_HASH(MENU_ENUM_SUBLABEL_DISK_INDEX, - "Changer l'index du disque.") + "Change the disk index.") MSG_HASH(MENU_ENUM_SUBLABEL_DISK_OPTIONS, - "Gestion des images disque.") + "Disk image management.") MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, - "Sélectionnez une image disque à insérer.") + "Select a disk image to insert.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, - "Assurez-vous que le nombre d'images par seconde est limité lorsque vous vous trouvez dans le menu.") + "Makes sure the framerate is capped while inside the menu.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_LAYOUT, - "Sélectionnez une mise en page différente pour l'interface XMB.") + "Select a different layout for the XMB interface.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_THEME, - "Sélectionnez un thème différent pour l'icône. Les modifications entreront en vigueur après le redémarrage du programme.") + "Select a different theme for the icon. Changes will take effect after you restart the program.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, - "Activer les ombres portées pour toutes les icônes. Cela aura un coup mineur sur la performance.") + "Enable drop shadows for all icons. This will have a minor performance hit.") MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_COLOR_THEME, "Choisir un thème de dégradé de couleur différent pour l'arrière plan.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_WALLPAPER_OPACITY, @@ -2949,7 +2949,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_MENU_WALLPAPER_OPACITY, MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MENU_COLOR_THEME, "Choisir un thème de dégradé de couleur différent pour l'arrière plan.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_RIBBON_ENABLE, - "Sélectionnez un effet de fond animé. Peut être gourmand en GPU selon l'effet. Si les performances ne sont pas satisfaisantes, désactivez-le ou revenez à un effet plus simple.") + "Select an animated background effect. Can be GPU-intensive depending on the effect. If performance is unsatisfactory, either turn this off or revert to a simpler effect.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_FONT, "Choisir une police principale différente pour le menu.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_IMAGES, @@ -2965,133 +2965,133 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_HISTORY, "Affiche l'onglet de l'historique dans le menu principal.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_ADD, - "Affiche l'onglet du contenu d'importation dans le menu principal.") + "Show the import content tab inside the main menu.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_PLAYLISTS, - "Affiche les onglets de la liste de lecture dans le menu principal.") + "Show playlist tabs inside the main menu.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN, - "Affiche l'écran de démarrage dans le menu. Ceci est automatiquement défini sur factice après le premier démarrage du programme.") + "Show startup screen in menu. This is automatically set to false after the program starts for the first time.") MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY, - "Modifier l'opacité du graphique d'en-tête.") + "Modify the opacity of the header graphic.") MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_FOOTER_OPACITY, - "Modifier l'opacité du graphique de pied de page.") + "Modify the opacity of the footer graphic.") MSG_HASH(MENU_ENUM_SUBLABEL_DPI_OVERRIDE_ENABLE, - "Le menu se redimensionne normalement de manière dynamique. Si vous souhaitez plutôt définir une taille de mise à l'échelle spécifique, activez cette option.") + "The menu normally scales itself dynamically. If you want to set a specific scaling size instead, enable this.") MSG_HASH(MENU_ENUM_SUBLABEL_DPI_OVERRIDE_VALUE, - "Définissez la taille de mise à l'échelle personnalisée ici. REMARQUE: vous devez activer 'DPI Override' pour que cette taille de mise à l'échelle prenne effet.") + "Set the custom scaling size here. NOTE: You have to enable 'DPI Override' for this scaling size to take effect.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_ASSETS_DIRECTORY, - "Enregistrer tous les fichiers téléchargés dans ce répertoire.") + "Save all downloaded files to this directory.") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_REMAPPING_DIRECTORY, - "Enregistrer tous les contrôles remappés dans ce répertoire.") + "Save all remapped controls to this directory.") MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_DIR_PATH, - "Répertoire où le programme recherche le contenu/les cœurs.") + "Directory where the program searches for content/cores.") MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, - "Les fichiers d’application/principaux sont stockés ici.") + "Application/core information files are stored here.") MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, - "Si une manette est branché, cette manette sera autoconfiguré si un fichier de configuration correspondant est présent dans ce répertoire.") + "If a joypad is plugged in, that joypad will be autoconfigured if a config file corresponding to it is present inside this directory.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, "Sauvegarder toutes les collections dans ce dossier.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, - "Si défini dans un répertoire, le contenu qui est temporairement extrait (par exemple à partir d’archives) sera extrait dans ce répertoire." + "If set to a directory, content which is temporarily extracted (e.g. from archives) will be extracted to this directory." ) MSG_HASH(MENU_ENUM_SUBLABEL_CURSOR_DIRECTORY, - "Les requêtes enregistrées sont stockées dans ce répertoire.") + "Saved queries are stored to this directory.") MSG_HASH( MENU_ENUM_SUBLABEL_CONTENT_DATABASE_DIRECTORY, "Les bases de données sont stockées dans ce répertoire." ) MSG_HASH( MENU_ENUM_SUBLABEL_ASSETS_DIRECTORY, - "Cet emplacement est interrogé par défaut lorsque les interfaces de menu tentent de rechercher des actifs chargeables, etc." + "This location is queried by default when menu interfaces try to look for loadable assets, etc." ) MSG_HASH(MENU_ENUM_SUBLABEL_SAVEFILE_DIRECTORY, - "Enregistrez tous les fichiers de sauvegarde dans ce répertoire. S'il n'est pas défini, essaiera de sauvegarder dans le répertoire de travail du fichier de contenu.") + "Save all save files to this directory. If not set, will try to save inside the content file's working directory.") MSG_HASH(MENU_ENUM_SUBLABEL_SAVESTATE_DIRECTORY, - "Enregistrez tous les états de sauvegarde dans ce répertoire. S'il n'est pas défini, essaiera de sauvegarder dans le répertoire de travail du fichier de contenu.") + "Save all save states to this directory. If not set, will try to save inside the content file's working directory.") MSG_HASH(MENU_ENUM_SUBLABEL_SCREENSHOT_DIRECTORY, "Dossier d'emplacement des captures d'écran.") MSG_HASH(MENU_ENUM_SUBLABEL_OVERLAY_DIRECTORY, - "Définit un répertoire où les superpositions sont conservées pour un accès facile.") + "Defines a directory where overlays are kept for easy access.") MSG_HASH( MENU_ENUM_SUBLABEL_CHEAT_DATABASE_PATH, "Les fichiers de triche sont stockés ici." ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_FILTER_DIR, - "Répertoire dans lequel les fichiers de filtres audio DSP sont conservés." + "Directory where audio DSP filter files are kept." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_FILTER_DIR, - "Répertoire dans lequel les fichiers de filtres vidéo basés sur l'UC sont conservés." + "Directory where CPU-based video filter files are kept." ) MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_DIR, - "Définit un répertoire dans lequel les fichiers de shader vidéo basés sur un GPU sont conservés pour un accès facile.") + "Defines a directory where GPU-based video shader files are kept for easy access.") MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_OUTPUT_DIRECTORY, - "Les enregistrements seront sauvegardés dans ce répertoire.") + "Recordings will be dumped to this directory.") MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_CONFIG_DIRECTORY, - "Les configurations d'enregistrement seront conservées ici.") + "Recording configurations will be kept here.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_PATH, "Choisir une police différente pour les notifications.") MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_APPLY_CHANGES, - "Les modifications apportées à la configuration du shader prendront effet immédiatement. Utilisez cette option si vous avez modifié le nombre de passes de shaders, de filtrage, d’échelle FBO, etc.") + "Changes to the shader configuration will take effect immediately. Use this if you changed the amount of shader passes, filtering, FBO scale, etc.") MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SHADER_NUM_PASSES, - "Augmentez ou diminuez le nombre de passes de pipeline de shaders. Vous pouvez lier un shader distincte à chaque pipeline et configurer son échelle et son filtrage." + "Increase or decrease the amount of shader pipeline passes. You can bind a separate shader to each pipeline pass and configure its scale and filtering." ) MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET, - "Charger un préréglage de shader. Le pipeline de shader sera automatiquement configuré.") + "Load a shader preset. The shader pipeline will be automatically set-up.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_AS, - "Enregistrer les paramètres actuels du shader en tant que nouveau préréglage de shader.") + "Save the current shader settings as a new shader preset.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_CORE, - "Enregistrer les paramètres de shader actuels en tant que paramètres par défaut pour cette application/coeur.") + "Save the current shader settings as the default settings for this application/core.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_GAME, - "Enregistrer les paramètres de shader actuels en tant que paramètres par défaut pour le contenu.") + "Save the current shader settings as the default settings for the content.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PARAMETERS, - "Modifie le shader actuel directement. Les modifications ne seront pas enregistrées dans le fichier prédéfini.") + "Modifies the current shader directly. Changes will not be saved to the preset file.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_PARAMETERS, - "Modifie le préréglage du shader lui-même actuellement utilisé dans le menu.") + "Modifies the shader preset itself currently used in the menu.") MSG_HASH( MENU_ENUM_SUBLABEL_CHEAT_NUM_PASSES, "Augmenter ou réduire le nombre de codes de triche." ) MSG_HASH(MENU_ENUM_SUBLABEL_CHEAT_APPLY_CHANGES, - "Les changements de triche prendront effet immédiatement.") + "Cheat changes will take effect immediately.") MSG_HASH( MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD, "Charger un fichier de triche." ) MSG_HASH( MENU_ENUM_SUBLABEL_CHEAT_FILE_SAVE_AS, - "Enregistrer les astuces actuelles en tant que fichier de sauvegarde." + "Save current cheats as a save file." ) MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SETTINGS, "Accéder rapidement aux options utiles en jeu.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_INFORMATION, - "Afficher les informations relatives à l'application/au coeur.") + "View information pertaining to the application/core.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_ASPECT_RATIO, - "Valeur de virgule flottante pour le rapport d'aspect vidéo (largeur/hauteur), utilisée si le rapport d'aspect est défini sur 'Config'.") + "Floating point value for video aspect ratio (width / height), used if the Aspect Ratio is set to 'Config'.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT, - "Hauteur de fenêtre d'affichage personnalisée utilisée si le rapport d'aspect est défini sur 'Personnalisé'.") + "Custom viewport height that is used if the Aspect Ratio is set to 'Custom'.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH, - "Largeur de la fenêtre d'affichage utilisée si le rapport d'aspect est défini sur 'Personnalisé'.") + "Custom viewport width that is used if the Aspect Ratio is set to 'Custom'.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_X, - "Décalage de fenêtre personnalisé utilisé pour définir la position de l'axe X de la fenêtre. Celles-ci sont ignorées si «Échelle entière» est activé. Il sera automatiquement centré ensuite.") + "Custom viewport offset used for defining the X-axis position of the viewport. These are ignored if 'Integer Scale' is enabled. It will be automatically centered then.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_Y, - "Décalage de la fenêtre d'affichage personnalisé utilisé pour définir la position de l'axe Y de la fenêtre d'affichage. Celles-ci sont ignorées si «Échelle entière» est activé. Il sera automatiquement centré ensuite.") + "Custom viewport offset used for defining the Y-axis position of the viewport. These are ignored if 'Integer Scale' is enabled. It will be automatically centered then.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_USE_MITM_SERVER, - "Utiliser le serveur relais") + "Use Relay Server") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, - "Transférez les connexions netplay via un serveur intermédiaire. Utile si l'hôte est derrière un pare-feu ou a des problèmes de NAT/UPnP.") + "Forward netplay connections through a man-in-the-middle server. Useful if the host is behind a firewall or has NAT/UPnP problems.") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, "Ajouter au mixeur") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_PLAY, - "Ajouter au mixeur et joueur") + "Add to mixer and play") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION, "Ajouter au mixeur") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY, - "Ajouter au mixeur et joueur") + "Add to mixer and play") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER_BY_CURRENT_CORE, - "Filtrer par coeurs actuel") + "Filter by current core") MSG_HASH( MSG_AUDIO_MIXER_VOLUME, "Volume global du mixeur audio" @@ -3165,27 +3165,27 @@ MSG_HASH(MSG_INPUT_ENABLE_SETTINGS_PASSWORD_NOK, MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, "Active l'onglet des réglages. Un redémarrage est requis pour que l'onglet s'affiche.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, - "La saisie d'un mot de passe en masquant l'onglet des paramètres permet de le restaurer ultérieurement à partir du menu en accédant à l'onglet Menu principal, en sélectionnant Activer l'onglet Paramètres et en entrant le mot de passe.") + "Supplying a password when hiding the settings tab makes it possible to later restore it from the menu, by going to the Main Menu tab, selecting Enable Settings Tab and entering the password.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, "Autoriser l'utilisateur à renommer les entrées des collections.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, - "Autoriser le renommage des entrées.") + "Autoriser le renommage des entrées") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, - "Afficher le coeur en charge.") + "Show Load Core") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CORE, - "Afficher/masquer l'option 'Charger coeur'.") + "Show/hide the 'Load Core' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CONTENT, - "Afficher le contenu du chargement.") + "Show Load Content") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CONTENT, - "Afficher/masquer l'option 'Charger le contenu'.") + "Show/hide the 'Load Content' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_INFORMATION, - "Montrer l'information.") + "Show Information") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_INFORMATION, - "Afficher/masquer l'option 'Information'.") + "Show/hide the 'Information' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_CONFIGURATIONS, - "Afficher les configurations") + "Show Configurations") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_CONFIGURATIONS, - "Afficher/masquer l'option 'Configurations'.") + "Show/hide the 'Configurations' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_HELP, "Afficher l'aide") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_HELP, @@ -3220,73 +3220,73 @@ MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT, MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_LOAD_STATE, "Afficher Sauver/Charger une sauvegarde instantanée") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE, - "Afficher/masquer les options pour enregistrer/charger l’état.") + "Show/hide the options for saving/loading state.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, - "Afficher annuler enregistrer/charger l'état") + "Show Undo Save/Load State") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, - "Afficher/masquer les options pour annuler l'état d'enregistrement/de chargement.") + "Show/hide the options for undoing save/load state.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_ADD_TO_FAVORITES, - "Afficher Ajouter aux favoris") + "Show Add to Favorites") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, - "Afficher/masquer l'option'ajouter aux favoris'.") + "Show/hide the 'Add to Favorites' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_START_RECORDING, - "Afficher le début de l'enregistrement") + "Show Start Recording") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_START_RECORDING, - "Afficher/masquer l'option 'Démarrer l'enregistrement'.") + "Show/hide the 'Start Recording' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_START_STREAMING, - "Afficher démarrer le streaming") + "Show Start Streaming") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_START_STREAMING, - "Afficher/masquer l'option 'Démarrer le streaming'.") + "Show/hide the 'Start Streaming' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION, - "Afficher réinitialiser le coeur") + "Show Reset Core Association") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION, - "Afficher/masquer l'option 'Réinitialiser l'association de base'.") + "Show/hide the 'Reset Core Association' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_OPTIONS, - "Afficher les options") + "Show Options") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_OPTIONS, - "Afficher/masquer l'option 'Options'.") + "Show/hide the 'Options' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CONTROLS, - "Afficher les contrôles") + "Show Controls") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CONTROLS, - "Afficher/masquer l'option 'Contrôles'.") + "Show/hide the 'Controls' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CHEATS, - "Afficher les astuces") + "Show Cheats") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CHEATS, - "Afficher / masquer l'option 'Astuces'.") + "Show/hide the 'Cheats' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SHADERS, - "Afficher Shaders") + "Show Shaders") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SHADERS, - "Afficher/masquer l'option 'Shaders'.") + "Show/hide the 'Shaders' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, - "Afficher les remplacements de base") + "Show Save Core Overrides") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, - "Afficher/masquer l'option «Remplacements de base».") + "Show/hide the 'Save Core Overrides' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, - "Afficher les remplacements de jeu") + "Show Save Game Overrides") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, - "Afficher/masquer l'option «Remplacements de jeu».") + "Show/hide the 'Save Game Overrides' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_INFORMATION, - "Afficher les informations") + "Show Information") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_INFORMATION, - "Afficher/masquer l'option 'Informations'.") + "Show/hide the 'Information' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DISABLE_KIOSK_MODE, - "Désactiver le mode kiosque") + "Disable Kiosk Mode") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_DISABLE_KIOSK_MODE, - "Désactive le mode kiosque. Un redémarrage est nécessaire pour que la modification prenne effet.") + "Disables kiosk mode. A restart is required for the change to take full effect.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_ENABLE_KIOSK_MODE, - "Activer le mode kiosque") + "Enable Kiosk Mode") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENABLE_KIOSK_MODE, - "Protège la configuration en cachant tous les paramètres liés à la configuration.") + "Protects the setup by hiding all configuration related settings.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_KIOSK_MODE_PASSWORD, - "Définir le mot de passe pour désactiver le mode kiosque") + "Set Password For Disabling Kiosk Mode") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_KIOSK_MODE_PASSWORD, - "La fourniture d'un mot de passe lors de l'activation du mode kiosque permet de la désactiver ultérieurement dans le menu, en accédant au menu principal, en sélectionnant désactiver le mode kiosque et en saisissant le mot de passe.") + "Supplying a password when enabling kiosk mode makes it possible to later disable it from the menu, by going to the Main Menu, selecting Disable Kiosk Mode and entering the password.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD, - "Entrer le mot de passe") + "Enter Password") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, - "Mot de passe correct.") + "Password correct.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, - "Mot de passe incorrect.") + "Password incorrect.") MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, "Ajouter automatiquement le contenu à la playlist") MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, @@ -3296,113 +3296,113 @@ MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY, "Qualité du ré-échantilloneur audio") MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, - "Réduisez cette valeur pour favoriser la performance/latence inférieure sur la qualité audio, augmenter si vous voulez une meilleure qualité audio au détriment des performances/latence inférieure.") + "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") MSG_HASH(MENU_ENUM_LABEL_VALUE_STATISTICS_SHOW, - "Afficher les statistiques") + "Display Statistics") MSG_HASH(MENU_ENUM_SUBLABEL_STATISTICS_SHOW, - "Afficher les statistiques techniques à l'écran.") + "Show onscreen technical statistics.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_ENABLE, - "Activer le remplissage de bordure") + "Enable border filler") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, - "Activer l'épaisseur du remplissage de bordure") + "Enable border filler thickness") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, - "Activer l'épaisseur de remplissage en arrière-plan") -MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "Pour les écrans CRT uniquement. Tentative d'utilisation de la résolution exacte du coeur/du jeu et du taux de rafraîchissement.") + "Enable background filler thickness") +MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For CRT displays only. Attempts to use exact core/game resolution and refresh rate.") MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH( MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, - "Basculez entre les super résolutions natives et ultrawides." + "Switch among native and ultrawide super resolutions." ) MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, - "Afficher les paramètres de rembobinage") + "Show Rewind Settings") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, - "Afficher/masquer les options de rembobinage.") + "Show/hide the Rewind options.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_LATENCY, - "Afficher/masquer les options de latence.") + "Show/hide the Latency options.") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_LATENCY, - "Afficher les paramètres de latence") + "Show Latency Settings") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_OVERLAYS, - "Afficher/masquer les options de superposition.") + "Show/hide the Overlay options.") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_OVERLAYS, - "Afficher les paramètres overlay") + "Show Overlay Settings") MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE_MENU, - "Activer le menu audio") + "Enable menu audio") MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_ENABLE_MENU, - "Activer ou désactiver le son du menu.") + "Enable or disable menu sound.") MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_SETTINGS, - "Paramètres du mixeur") + "Mixer Settings") MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MIXER_SETTINGS, - "Afficher et/ou modifier les paramètres du mélangeur audio.") + "View and/or modify audio mixer settings.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS, - "Dérogations") + "Overrides") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_OVERRIDE_OPTIONS, - "Options pour remplacer la configuration globale.") + "Options for overriding the global configuration.") MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY, - "Va commencer la lecture du flux audio. Une fois terminé, il supprimera le flux audio actuel de la mémoire.") + "Will start playback of the audio stream. Once finished, it will remove the current audio stream from memory.") MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_LOOPED, - "Va commencer la lecture du flux audio. Une fois terminé, il boucle et lit la piste à nouveau depuis le début.") + "Will start playback of the audio stream. Once finished, it will loop and play the track again from the beginning.") MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_SEQUENTIAL, - "Va commencer la lecture du flux audio. Une fois terminé, il passera au prochain flux audio dans un ordre séquentiel et répétera ce comportement. Utile comme mode de lecture d'album.") + "Will start playback of the audio stream. Once finished, it will jump to the next audio stream in sequential order and repeat this behavior. Useful as an album playback mode.") MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_STOP, - "Cela arrêtera la lecture du flux audio, mais ne le supprimera pas de la mémoire. Vous pouvez recommencer à jouer en sélectionnant 'Jouer'.") + "This will stop playback of the audio stream, but not remove it from memory. You can start playing it again by selecting 'Play'.") MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_REMOVE, - "Cela arrêtera la lecture du flux audio et le supprimera entièrement de la mémoire.") + "This will stop playback of the audio stream and remove it entirely from memory.") MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_VOLUME, - "Ajuster le volume du flux audio.") + "Adjust the volume of the audio stream.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_MIXER, - "Ajoutez cette piste audio à un emplacement de flux audio disponible. Si aucun créneau n'est disponible, il sera ignoré.") + "Add this audio track to an available audio stream slot. If no slots are currently available, it will be ignored.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_MIXER_AND_PLAY, - "Ajoutez cette piste audio à un emplacement de flux audio disponible et lisez-la. Si aucun créneau n'est disponible, il sera ignoré.") + "Add this audio track to an available audio stream slot and play it. If no slots are currently available, it will be ignored.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY, - "Jouer") + "Play") MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_LOOPED, - "Jouer (en boucle)") + "Play (Looped)") MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_SEQUENTIAL, - "Jouer (séquentiel)") + "Play (Sequential)") MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_STOP, - "Stopper") + "Stop") MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_REMOVE, - "Effacer") + "Remove") MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_VOLUME, "Volume") MSG_HASH(MENU_ENUM_LABEL_VALUE_DETECT_CORE_LIST_OK_CURRENT_CORE, - "Coeur actuel") + "Current core") MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, - "Effacer") + "Clear") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, - "Dans le menu") + "In-Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, - "En jeu") + "In-Game") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, - "En jeu (en pause)") + "In-Game (Paused)") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, - "Jouer") + "Playing") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, - "En pause") + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, - "Activer Discord" + "Enable Discord" ) MSG_HASH( MENU_ENUM_SUBLABEL_DISCORD_ALLOW, - "Activer ou désactiver le support Discord. Ne fonctionnera pas avec la version du navigateur, uniquement avec le client de bureau natif." + "Enable or disable Discord support. Will not work with the browser version, only native desktop client." ) MSG_HASH(MENU_ENUM_LABEL_VALUE_POWER_MANAGEMENT_SETTINGS, - "Gestion de l'alimentation") + "Power Management") MSG_HASH(MENU_ENUM_SUBLABEL_POWER_MANAGEMENT_SETTINGS, - "Modifier les paramètres de gestion de l'alimentation.") + "Change power management settings.") MSG_HASH(MENU_ENUM_LABEL_VALUE_SUSTAINED_PERFORMANCE_MODE, - "Mode de performance soutenue") + "Sustained Performance Mode") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_MPV_SUPPORT, - "support mpv") + "mpv support") MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ADAPTIVE_VSYNC, - "V-Sync adaptatif" + "Adaptive Vsync" ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_ADAPTIVE_VSYNC, - "V-Sync est activé jusqu'à ce que les performances deviennent inférieures au taux de rafraîchissement cible. Peut minimiser le bégaiement lorsque les performances sont inférieures au temps réel et être plus économe en énergie." + "V-Sync is enabled until performance falls below the target refresh rate. Can minimize stuttering when performance falls below realtime, and can be more energy efficient." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CRT_SWITCHRES_SETTINGS, @@ -3410,83 +3410,83 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_CRT_SWITCHRES_SETTINGS, - "Produisez des signaux natifs à basse résolution pour une utilisation avec les écrans CRT." + "Output native, low-resolution signals for use with CRT displays." ) MSG_HASH( MENU_ENUM_SUBLABEL_CRT_SWITCH_X_AXIS_CENTERING, - "Parcourez ces options si l'image n'est pas centrée correctement sur l'écran." + "Cycle through these options if the image is not centered properly on the display." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CRT_SWITCH_X_AXIS_CENTERING, - "Centrage sur l'axe X" + "X-Axis Centering" ) MSG_HASH( MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_USE_CUSTOM_REFRESH_RATE, - "Utilisez un taux de rafraîchissement personnalisé spécifié dans le fichier de configuration si nécessaire.") + "Use a custom refresh rate specified in the config file if needed.") MSG_HASH( MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_USE_CUSTOM_REFRESH_RATE, - "Utiliser le taux de rafraîchissement personnalisé") + "Use Custom Refresh Rate") MSG_HASH( MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_OUTPUT_DISPLAY_ID, - "Sélectionnez le port de sortie connecté à l'écran CRT.") + "Select the output port connected to the CRT display.") MSG_HASH( MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_OUTPUT_DISPLAY_ID, - "ID d'affichage de sortie") + "Output Display ID") MSG_HASH( MENU_ENUM_LABEL_VALUE_QUICK_MENU_START_RECORDING, - "Commencer l'enregistrement" + "Start Recording" ) MSG_HASH( MENU_ENUM_SUBLABEL_QUICK_MENU_START_RECORDING, - "Commence l'enregistrement." + "Starts recording." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QUICK_MENU_STOP_RECORDING, - "Arrête d'enregistrer" + "Stop Recording" ) MSG_HASH( MENU_ENUM_SUBLABEL_QUICK_MENU_STOP_RECORDING, - "Arrête l'enregistrement." + "Stops recording." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QUICK_MENU_START_STREAMING, - "Démarrer le streaming" + "Start Streaming" ) MSG_HASH( MENU_ENUM_SUBLABEL_QUICK_MENU_START_STREAMING, - "Démarre le streaming." + "Starts streaming." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QUICK_MENU_STOP_STREAMING, - "Arrêter le streaming" + "Stop Streaming" ) MSG_HASH( MENU_ENUM_SUBLABEL_QUICK_MENU_STOP_STREAMING, - "Arrête le streaming." + "Stops streaming." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE, - "Basculer en enregistrement" + "Recording toggle" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE, - "Basculer en streaming" + "Streaming toggle" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_RECORD_QUALITY, - "Qualité d'enregistrement" + "Record Quality" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_STREAM_QUALITY, - "Qualité du flux" + "Stream Quality" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_STREAMING_URL, - "URL Streaming" + "Streaming URL" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_UDP_STREAM_PORT, - "Port de flux UDP" + "UDP Stream Port" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACCOUNTS_TWITCH, @@ -3497,24 +3497,24 @@ MSG_HASH( "YouTube" ) MSG_HASH(MENU_ENUM_LABEL_VALUE_TWITCH_STREAM_KEY, - "Clé Twitch Stream") + "Twitch Stream Key") MSG_HASH(MENU_ENUM_LABEL_VALUE_YOUTUBE_STREAM_KEY, - "Clé YouTube Stream") + "YouTube Stream Key") MSG_HASH(MENU_ENUM_LABEL_VALUE_STREAMING_MODE, - "Mode Streaming") + "Streaming Mode") MSG_HASH(MENU_ENUM_LABEL_VALUE_STREAMING_TITLE, - "Titre du flux") + "Title of Stream") MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_SPLIT_JOYCON, "Split Joy-Con" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_RESET_TO_DEFAULT_CONFIG, - "Réinitialiser les paramètres par défaut" + "Reset To Defaults" ) MSG_HASH( MENU_ENUM_SUBLABEL_RESET_TO_DEFAULT_CONFIG, - "Réinitialiser la configuration actuelle aux valeurs par défaut." + "Reset the current configuration to default values." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_OK, @@ -3524,53 +3524,53 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_OZONE_MENU_COLOR_THEME, "Couleur du thème du menu") MSG_HASH( MENU_ENUM_LABEL_VALUE_OZONE_COLOR_THEME_BASIC_WHITE, - "Blanc de base" + "Basic White" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_OZONE_COLOR_THEME_BASIC_BLACK, - "Noir de base" + "Basic Black" ) MSG_HASH( MENU_ENUM_SUBLABEL_OZONE_MENU_COLOR_THEME, - "Sélectionnez un thème de couleur différent." + "Select a different color theme." ) MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, - "Utiliser le thème de couleur système préféré") + "Use preferred system color theme") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, - "Utilisez le thème de couleur de votre système d'exploitation (le cas échéant) - remplace les paramètres du thème.") + "Use your operating system's color theme (if any) - overrides theme settings.") MSG_HASH(MSG_RESAMPLER_QUALITY_LOWEST, - "Plus bas") + "Lowest") MSG_HASH(MSG_RESAMPLER_QUALITY_LOWER, - "Inférieur") + "Lower") MSG_HASH(MSG_RESAMPLER_QUALITY_NORMAL, "Normal") MSG_HASH(MSG_RESAMPLER_QUALITY_HIGHER, - "Superieur") + "Higher") MSG_HASH(MSG_RESAMPLER_QUALITY_HIGHEST, - "Plus haut") + "Highest") MSG_HASH( MENU_ENUM_LABEL_VALUE_NO_MUSIC_AVAILABLE, - "Aucune musique disponible." + "No music available." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_NO_VIDEOS_AVAILABLE, - "Aucune vidéo disponible." + "No videos available." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_NO_IMAGES_AVAILABLE, - "Aucune image disponible." + "No images available." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_NO_FAVORITES_AVAILABLE, - "Pas de favoris disponibles." + "No favorites available." ) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_SAVE_POSITION, - "Rappelez-vous la position et la taille de la fenêtre") + "Remember Window Position and Size") MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT, - "Support CoreAudio" + "CoreAudio support" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT, - "Support CoreAudio V3" + "CoreAudio V3 support" ) From 677d65bf8dcda90b82b8a43b8b4295a811c0d579 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Wed, 20 Mar 2019 22:32:12 +0100 Subject: [PATCH 069/237] Remove the parallel compilation for PS2 in the dist-scripts --- dist-scripts/dist-cores.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dist-scripts/dist-cores.sh b/dist-scripts/dist-cores.sh index c2fd89ba4c..8f2b3365f5 100755 --- a/dist-scripts/dist-cores.sh +++ b/dist-scripts/dist-cores.sh @@ -231,6 +231,9 @@ for f in `ls -v *_${platform}.${EXT}`; do make -C ../ -f Makefile.${platform} $OPTS LIBRETRO=$name $whole_archive $big_stack -j3 || exit 1 elif [ $PLATFORM = "libnx" ]; then make -C ../ -f Makefile.${platform} $OPTS APP_TITLE="$name" LIBRETRO=$name $whole_archive $big_stack -j3 || exit 1 + elif [ $PLATFORM = "ps2" ]; then + # TODO PS2 should be able to compile in parallel + make -C ../ -f Makefile.${platform} $OPTS $whole_archive $big_stack || exit 1 else make -C ../ -f Makefile.${platform} $OPTS $whole_archive $big_stack -j3 || exit 1 fi From 538576e6f9a59d5f7eb2b8ba4f7961872507dec1 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Wed, 20 Mar 2019 21:20:48 -0400 Subject: [PATCH 070/237] update JP translation --- CHANGES.md | 1 + intl/msg_hash_ja.h | 160 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 155 insertions(+), 6 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 299cad7b2d..95202231a1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -28,6 +28,7 @@ - GONG: Add savestate support. - GONG: Add video refresh rate core options. - GONG: Two player support via core option. +- LOCALIZATION: Update Japanese translation. - LOCALIZATION: Update Polish translation. - MIDI: Fix startup crash in midi driver. - MENU: Add memory statistics support to more context drivers. diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index 5df46be382..e14fc8b465 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -3397,15 +3397,15 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_ADD_TO_FAVORITES, MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, "「お気に入りに追加」オプションを表示/非表示にする。") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_START_RECORDING, - "Show Start Recording") + "「録画を開始」を表示") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_START_RECORDING, "Show/hide the 'Start Recording' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_START_STREAMING, - "Show Start Streaming") + "「ストリーミングを開始」を表示") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_START_STREAMING, "Show/hide the 'Start Streaming' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION, - "Show Reset Core Association") + "「コアの関連付けをリセット」を表示") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION, "Show/hide the 'Reset Core Association' option.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_OPTIONS, @@ -4025,7 +4025,7 @@ MSG_HASH( "色テーマを選択します。" ) MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, - "Use preferred system color theme") + "システムの優先色テーマを使用") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, "Use your operating system's color theme (if any) - overrides theme settings.") MSG_HASH(MSG_RESAMPLER_QUALITY_LOWEST, @@ -4058,9 +4058,157 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_SAVE_POSITION, "ウィンドウの位置とサイズを記憶") MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT, - "CoreAudio support" + "CoreAudio対応" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT, - "CoreAudio V3 support" + "CoreAudio V3対応" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SIDELOAD_CORE_LIST, + "コアをインストールや復元" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SOUNDS, + "メニュー音" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, + "デバッグ情報を送信" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO, + "デバッグ情報を送信" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCREEN_ORIENTATION, + "画面の向き" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SOUND_OK, + "OKの音を有効" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SOUND_CANCEL, + "キュンセルの音を有効" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SOUND_NOTICE, + "通知の音を有効" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SOUND_BGM, + "BGMの音を有効" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUIT_PRESS_TWICE, + "終了キーを2回続けて押す" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIBRATE_ON_KEYPRESS, + "キー操作で振動" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ENABLE_DEVICE_VIBRATION, + "対応されたコアにデバイス振動を使用" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HOLD_START, + "スタートをホールド(2秒)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, + "FPS表示の切り替え" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_HOST_TOGGLE, + "ネットプレイホストの切り替え" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_RUNTIME_LOG, + "実行時ログを保存(コアごと)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_RUNTIME_LOG_AGGREGATE, + "実行時ログを保存(総計)" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RUNTIME_LOG_DIRECTORY, + "実行時ログの保存フォルダ" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_PER_CORE, + "コアごと" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_AGGREGATE, + "総計" + ) +MSG_HASH( + MSG_FAILED_TO_SAVE_DEBUG_INFO, + "デバッグ情報を保存に失敗しました。" + ) +MSG_HASH( + MSG_FAILED_TO_SEND_DEBUG_INFO, + "デバッグ情報を送信に失敗しました。" + ) +MSG_HASH( + MSG_SENDING_DEBUG_INFO, + "デバッグ情報をサーバーに送信中..." + ) +MSG_HASH( + MSG_SENT_DEBUG_INFO, + "デバッグ情報を送信に成功しました。ID番号は%u。" + ) +MSG_HASH( + MSG_PRESS_TWO_MORE_TIMES_TO_SEND_DEBUG_INFO, + "後2回押すとデバッグ情報をRetroArchチームに送信します。" + ) +MSG_HASH( + MSG_PRESS_ONE_MORE_TIME_TO_SEND_DEBUG_INFO, + "後1回押すとデバッグ情報をRetroArchチームに送信します。" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VRR_RUNLOOP_ENABLE, + "正確なコンテンツフレームレートに同期 (G-Sync, FreeSync)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MEMORY_SHOW, + "メモリ詳細を含む" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_TICKER_TYPE, + "ティッカーのテキストアニメーション" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_TICKER_SPEED, + "ティッカーのテキスト速度" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TIMEDATE_STYLE, + "日付/時刻の形式" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SORT_ALPHABETICAL, + "ABC順にプレイリストを分類" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_USE_OLD_FORMAT, + "古い形式でプレイリストを保存" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SHOW_INLINE_CORE_NAME, + "関連付けたコアをプレイリストに表示" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SHOW_SUBLABELS, + "プレイリストのサブレーベルを表示" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME_TYPE, + "プレイリストサブレーベルの実行時ログ形式" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUNTIME_LOG_DIRECTORY, + "実行時ログ" ) From 93506a0d189c4c5098cea6a42f32d31989da9bca Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 21 Mar 2019 16:56:24 +0000 Subject: [PATCH 071/237] Log to file improvements --- config.def.h | 6 -- configuration.c | 26 +++++--- configuration.h | 1 - file_path_special.h | 4 +- file_path_str.c | 6 ++ frontend/drivers/platform_unix.c | 2 + intl/msg_hash_lbl.h | 4 ++ intl/msg_hash_us.h | 16 +++++ menu/cbs/menu_cbs_sublabel.c | 8 +++ menu/cbs/menu_cbs_title.c | 7 +++ menu/menu_displaylist.c | 6 ++ menu/menu_setting.c | 52 ++++++++++++++++ msg_hash.h | 3 + retroarch.c | 104 +++++++++++++++++++++++-------- retroarch.h | 4 ++ verbosity.c | 10 ++- verbosity.h | 2 +- 17 files changed, 212 insertions(+), 49 deletions(-) diff --git a/config.def.h b/config.def.h index a907065740..97a95dacb1 100644 --- a/config.def.h +++ b/config.def.h @@ -439,11 +439,7 @@ static bool menu_swap_ok_cancel_buttons = false; static bool quit_press_twice = false; -#if defined(ANDROID) -static bool default_log_to_file = true; -#else static bool default_log_to_file = false; -#endif /* Crop overscanned frames. */ static const bool crop_overscan = true; @@ -922,6 +918,4 @@ static char buildbot_assets_server_url[] = "http://buildbot.libretro.com/assets/ static char default_discord_app_id[] = "475456035851599874"; -static char default_log_file[] = "retroarch.log"; - #endif diff --git a/configuration.c b/configuration.c index d0dab08378..07af9cdc0a 100644 --- a/configuration.c +++ b/configuration.c @@ -1310,8 +1310,7 @@ static struct config_path_setting *populate_settings_path(settings_t *settings, global->record.config_dir, false, NULL, true); } - SETTING_ARRAY("log_file", settings->paths.log_file, true, default_log_file, true); - SETTING_ARRAY("log_dir", settings->paths.log_dir, true, "", true); + SETTING_ARRAY("log_dir", settings->paths.log_dir, true, NULL, true); *size = count; @@ -1594,6 +1593,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, #ifdef HAVE_OZONE SETTING_BOOL("ozone_collapse_sidebar", &settings->bools.ozone_collapse_sidebar, true, ozone_collapse_sidebar, false); #endif + SETTING_BOOL("log_to_file", &settings->bools.log_to_file, true, default_log_to_file, false); *size = count; @@ -1961,12 +1961,6 @@ void config_set_defaults(void) strlcpy(settings->arrays.discord_app_id, default_discord_app_id, sizeof(settings->arrays.discord_app_id)); - strlcpy(settings->paths.log_file, - default_log_file, sizeof(settings->paths.log_file)); - - strlcpy(settings->paths.log_dir, - g_defaults.dirs[DEFAULT_DIR_LOGS], sizeof(settings->paths.log_dir)); - #ifdef HAVE_MATERIALUI if (g_defaults.menu.materialui.menu_color_theme_enable) settings->uints.menu_materialui_color_theme = g_defaults.menu.materialui.menu_color_theme; @@ -2128,6 +2122,8 @@ void config_set_defaults(void) *settings->paths.directory_content_history = '\0'; *settings->paths.path_audio_dsp_plugin = '\0'; + *settings->paths.log_dir = '\0'; + video_driver_default_settings(); if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_WALLPAPERS])) @@ -3160,6 +3156,20 @@ static bool config_load_file(const char *path, bool set_defaults, if (string_is_equal(settings->paths.directory_system, "default")) *settings->paths.directory_system = '\0'; + /* Log directory is a special case, since it must contain + * a valid path as soon as possible - if config file + * value is 'default' must copy g_defaults.dirs[DEFAULT_DIR_LOGS] + * directly... */ + if (string_is_equal(settings->paths.log_dir, "default")) + { + if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_LOGS])) + strlcpy(settings->paths.log_dir, + g_defaults.dirs[DEFAULT_DIR_LOGS], + sizeof(settings->paths.log_dir)); + else + *settings->paths.log_dir = '\0'; + } + if (settings->floats.slowmotion_ratio < 1.0f) configuration_set_float(settings, settings->floats.slowmotion_ratio, 1.0f); diff --git a/configuration.h b/configuration.h index d2057a8093..4919a22c14 100644 --- a/configuration.h +++ b/configuration.h @@ -594,7 +594,6 @@ typedef struct settings char streaming_title[PATH_MAX_LENGTH]; char log_dir[PATH_MAX_LENGTH]; - char log_file[PATH_MAX_LENGTH]; } paths; bool modified; diff --git a/file_path_special.h b/file_path_special.h index 8b7cc3e3ef..481528dd47 100644 --- a/file_path_special.h +++ b/file_path_special.h @@ -94,7 +94,9 @@ enum file_path_enum FILE_PATH_XM_EXTENSION, FILE_PATH_CONFIG_EXTENSION, FILE_PATH_CORE_INFO_EXTENSION, - FILE_PATH_RUNTIME_EXTENSION + FILE_PATH_RUNTIME_EXTENSION, + FILE_PATH_DEFAULT_EVENT_LOG, + FILE_PATH_EVENT_LOG_EXTENSION }; enum application_special_type diff --git a/file_path_str.c b/file_path_str.c index 46aad7605f..43515babc9 100644 --- a/file_path_str.c +++ b/file_path_str.c @@ -227,6 +227,12 @@ const char *file_path_str(enum file_path_enum enum_idx) case FILE_PATH_RUNTIME_EXTENSION: str = ".lrtl"; break; + case FILE_PATH_DEFAULT_EVENT_LOG: + str = "retroarch.log"; + break; + case FILE_PATH_EVENT_LOG_EXTENSION: + str = ".log"; + break; case FILE_PATH_UNKNOWN: default: break; diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index 2fd9914449..f823dfb698 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -1920,6 +1920,8 @@ static void frontend_unix_get_env(int *argc, "screenshots", sizeof(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS], base_path, "thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], base_path, + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); #endif for (i = 0; i < DEFAULT_DIR_LAST; i++) diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 50ee9ca329..a0f0b92e35 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -647,6 +647,8 @@ MSG_HASH(MENU_ENUM_LABEL_LOGGING_SETTINGS, "logging_settings") MSG_HASH(MENU_ENUM_LABEL_LOG_VERBOSITY, "log_verbosity") +MSG_HASH(MENU_ENUM_LABEL_LOG_TO_FILE, + "log_to_file") MSG_HASH(MENU_ENUM_LABEL_MAIN_MENU, "main_menu") MSG_HASH(MENU_ENUM_LABEL_MANAGEMENT, @@ -1811,3 +1813,5 @@ MSG_HASH(MENU_ENUM_LABEL_VIBRATE_ON_KEYPRESS, "vibrate_on_keypress") MSG_HASH(MENU_ENUM_LABEL_ENABLE_DEVICE_VIBRATION, "enable_device_vibration") +MSG_HASH(MENU_ENUM_LABEL_LOG_DIR, + "log_dir") diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index daa8ca33aa..fe06a6aad5 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1616,6 +1616,14 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_LOG_VERBOSITY, "Logging Verbosity" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOG_TO_FILE, + "Log To File" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOG_TO_FILE, + "Redirects system event log messages to file. Requires 'Logging Verbosity' to be enabled." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MAIN_MENU, "Main Menu" @@ -8494,3 +8502,11 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_ENABLE_DEVICE_VIBRATION, "Enable device vibration (for supported cores)" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOG_DIR, + "System Event Logs" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOG_DIR, + "Save system event log files to this directory." + ) diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index b55f1ae374..de341c3a1e 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -143,6 +143,8 @@ default_sublabel_macro(action_bind_sublabel_systeminfo_cpu_cores, MENU_ default_sublabel_macro(action_bind_sublabel_toggle_gamepad_combo, MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO) default_sublabel_macro(action_bind_sublabel_show_hidden_files, MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES) default_sublabel_macro(action_bind_sublabel_log_verbosity, MENU_ENUM_SUBLABEL_LOG_VERBOSITY) +default_sublabel_macro(action_bind_sublabel_log_to_file, MENU_ENUM_SUBLABEL_LOG_TO_FILE) +default_sublabel_macro(action_bind_sublabel_log_dir, MENU_ENUM_SUBLABEL_LOG_DIR) default_sublabel_macro(action_bind_sublabel_video_monitor_index, MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX) default_sublabel_macro(action_bind_sublabel_video_refresh_rate_auto, MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO) default_sublabel_macro(action_bind_sublabel_video_hard_sync, MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC) @@ -2129,6 +2131,12 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_LOG_VERBOSITY: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_log_verbosity); break; + case MENU_ENUM_LABEL_LOG_TO_FILE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_log_to_file); + break; + case MENU_ENUM_LABEL_LOG_DIR: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_log_dir); + break; case MENU_ENUM_LABEL_SHOW_HIDDEN_FILES: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_show_hidden_files); break; diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index 0274020a6c..4da8251556 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -213,6 +213,7 @@ default_fill_title_macro(action_get_title_assets_directory, MENU_ENUM_LABE default_fill_title_macro(action_get_title_extraction_directory, MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY) default_fill_title_macro(action_get_title_menu, MENU_ENUM_LABEL_VALUE_MENU_SETTINGS) default_fill_title_macro(action_get_title_font_path, MENU_ENUM_LABEL_VALUE_XMB_FONT) +default_fill_title_macro(action_get_title_log_dir, MENU_ENUM_LABEL_VALUE_LOG_DIR) default_title_copy_macro(action_get_title_help, MENU_ENUM_LABEL_VALUE_HELP_LIST) default_title_copy_macro(action_get_title_input_settings, MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS) @@ -715,6 +716,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_RGUI_CONFIG_DIRECTORY: BIND_ACTION_GET_TITLE(cbs, action_get_title_config_directory); break; + case MENU_ENUM_LABEL_LOG_DIR: + BIND_ACTION_GET_TITLE(cbs, action_get_title_log_dir); + break; case MENU_ENUM_LABEL_INFORMATION_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_title_information_list); break; @@ -1047,6 +1051,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_LABEL_RGUI_CONFIG_DIRECTORY: BIND_ACTION_GET_TITLE(cbs, action_get_title_config_directory); break; + case MENU_LABEL_LOG_DIR: + BIND_ACTION_GET_TITLE(cbs, action_get_title_log_dir); + break; case MENU_LABEL_INFORMATION_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_title_information_list); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index dc34e08f16..c9cccbd4f5 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -5498,6 +5498,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL, PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_LOG_TO_FILE, + PARSE_ONLY_BOOL, false); { settings_t *settings = config_get_ptr(); @@ -6735,6 +6738,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CACHE_DIRECTORY, PARSE_ONLY_DIR, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_LOG_DIR, + PARSE_ONLY_DIR, false); info->need_refresh = true; info->need_push = true; diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 9217f2be3f..3b03386ba5 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -3321,11 +3321,33 @@ void general_write_handler(rarch_setting_t *setting) break; case MENU_ENUM_LABEL_LOG_VERBOSITY: if (!verbosity_is_enabled()) + { + rarch_log_file_init(); verbosity_enable(); + } else + { verbosity_disable(); + rarch_log_file_deinit(); + } retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_VERBOSITY, NULL); break; + case MENU_ENUM_LABEL_LOG_TO_FILE: + if (verbosity_is_enabled()) + { + if (settings->bools.log_to_file && !is_logging_to_file()) + rarch_log_file_init(); + else if (!settings->bools.log_to_file && is_logging_to_file()) + rarch_log_file_deinit(); + } + break; + case MENU_ENUM_LABEL_LOG_DIR: + if (verbosity_is_enabled() && is_logging_to_file()) + { + rarch_log_file_deinit(); + rarch_log_file_init(); + } + break; case MENU_ENUM_LABEL_VIDEO_SMOOTH: video_driver_set_filtering(1, settings->bools.video_smooth); break; @@ -4938,6 +4960,21 @@ static bool setting_append_list( &setting_get_string_representation_uint_libretro_log_level; settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); + CONFIG_BOOL( + list, list_info, + &settings->bools.log_to_file, + MENU_ENUM_LABEL_LOG_TO_FILE, + MENU_ENUM_LABEL_VALUE_LOG_TO_FILE, + default_log_to_file, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_ADVANCED); + END_SUB_GROUP(list, list_info, parent_group); START_SUB_GROUP(list, list_info, "Performance Counters", &group_info, &subgroup_info, @@ -11414,6 +11451,21 @@ static bool setting_append_list( general_read_handler); (*list)[list_info->index - 1].action_start = directory_action_start_generic; + CONFIG_DIR( + list, list_info, + settings->paths.log_dir, + sizeof(settings->paths.log_dir), + MENU_ENUM_LABEL_LOG_DIR, + MENU_ENUM_LABEL_VALUE_LOG_DIR, + g_defaults.dirs[DEFAULT_DIR_LOGS], + MENU_ENUM_LABEL_VALUE_DIRECTORY_DEFAULT, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].action_start = directory_action_start_generic; + END_SUB_GROUP(list, list_info, parent_group); END_GROUP(list, list_info, parent_group); break; diff --git a/msg_hash.h b/msg_hash.h index c3b8b033bf..6e9d9443ec 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1393,6 +1393,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VOLUME_DOWN, MENU_LABEL(LOG_VERBOSITY), + MENU_LABEL(LOG_TO_FILE), MENU_ENUM_LABEL_OVERLAY_NEXT, @@ -1703,6 +1704,7 @@ enum msg_hash_enums MENU_LABEL(VIDEO_SHADER_DIR), MENU_LABEL(VIDEO_FILTER_DIR), MENU_LABEL(AUDIO_FILTER_DIR), + MENU_LABEL(LOG_DIR), MENU_LABEL(TURBO_DEADZONE_LIST), MENU_LABEL(LIBRETRO_DIR_PATH), @@ -2477,6 +2479,7 @@ enum msg_hash_enums #define MENU_LABEL_RGUI_CONFIG_DIRECTORY 0x0cb3e005U #define MENU_LABEL_ASSETS_DIRECTORY 0xde1ae8ecU #define MENU_LABEL_CACHE_DIRECTORY 0x851dfb8dU +#define MENU_LABEL_LOG_DIR 0x87BB87E5U /* RDB settings */ diff --git a/retroarch.c b/retroarch.c index 5b882e08d3..f98616fd73 100644 --- a/retroarch.c +++ b/retroarch.c @@ -187,7 +187,6 @@ enum RA_OPT_FEATURES, RA_OPT_VERSION, RA_OPT_EOF_EXIT, - RA_OPT_LOG_FILE, RA_OPT_MAX_FRAMES, RA_OPT_MAX_FRAMES_SCREENSHOT, RA_OPT_MAX_FRAMES_SCREENSHOT_PATH @@ -292,6 +291,8 @@ static retro_time_t libretro_core_runtime_usec = 0; static char runtime_content_path[PATH_MAX_LENGTH] = {0}; static char runtime_core_path[PATH_MAX_LENGTH] = {0}; +static bool log_file_created = false; + extern bool input_driver_flushing_input; static char launch_arguments[4096]; @@ -1084,7 +1085,6 @@ static void retroarch_print_help(const char *arg0) puts(" -h, --help Show this help message."); puts(" -v, --verbose Verbose logging."); - puts(" --log-file FILE Log messages to FILE."); puts(" --version Show version."); puts(" --features Prints available features compiled into " "program."); @@ -1277,9 +1277,6 @@ static void retroarch_parse_input_and_config(int argc, char *argv[]) { "max-frames-ss-path", 1, NULL, RA_OPT_MAX_FRAMES_SCREENSHOT_PATH }, { "eof-exit", 0, NULL, RA_OPT_EOF_EXIT }, { "version", 0, NULL, RA_OPT_VERSION }, -#ifdef HAVE_FILE_LOGGER - { "log-file", 1, NULL, RA_OPT_LOG_FILE }, -#endif { NULL, 0, NULL, 0 } }; @@ -1735,12 +1732,6 @@ static void retroarch_parse_input_and_config(int argc, char *argv[]) retroarch_print_version(); exit(0); - #ifdef HAVE_FILE_LOGGER - case RA_OPT_LOG_FILE: - retro_main_log_file_init(optarg); - break; - #endif - case 'c': case 'h': case RA_OPT_APPENDCONFIG: @@ -1759,19 +1750,8 @@ static void retroarch_parse_input_and_config(int argc, char *argv[]) } } - if (verbosity_is_enabled()) - { - settings_t *settings = config_get_ptr(); - if (settings->bools.log_to_file && - !string_is_empty(settings->paths.log_dir) && !string_is_empty(settings->paths.log_file)) - { - char buf[PATH_MAX_LENGTH]; - fill_pathname_join(buf, settings->paths.log_dir, settings->paths.log_file, sizeof(buf)); - RARCH_LOG("Logging to file: %s\n", buf); - retro_main_log_file_init(buf); - } - } + rarch_log_file_init(); #ifdef HAVE_GIT_VERSION RARCH_LOG("RetroArch %s (Git %s)\n", @@ -1975,7 +1955,8 @@ bool retroarch_main_init(int argc, char *argv[]) rarch_error_on_init = true; - retro_main_log_file_init(NULL); + /* Have to initialise non-file logging once at the start... */ + retro_main_log_file_init(NULL, false); retroarch_parse_input_and_config(argc, argv); @@ -1993,8 +1974,8 @@ bool retroarch_main_init(int argc, char *argv[]) RARCH_LOG_OUTPUT("CPU Model Name: %s\n", cpu_model); retroarch_get_capabilities(RARCH_CAPABILITIES_CPU, str, sizeof(str)); - fprintf(stderr, "%s: %s\n", msg_hash_to_str(MSG_CAPABILITIES), str); - fprintf(stderr, "Built: %s\n", __DATE__); + RARCH_LOG_OUTPUT("%s: %s\n", msg_hash_to_str(MSG_CAPABILITIES), str); + RARCH_LOG_OUTPUT("Built: %s\n", __DATE__); RARCH_LOG_OUTPUT("Version: %s\n", PACKAGE_VERSION); #ifdef HAVE_GIT_VERSION RARCH_LOG_OUTPUT("Git: %s\n", retroarch_git_version); @@ -5296,3 +5277,74 @@ finish: free(info_buf); #endif } + +void rarch_log_file_init(void) +{ + settings_t *settings = config_get_ptr(); + FILE *fp = NULL; + bool success = false; + + /* If nothing has changed, do nothing */ + if ((!settings->bools.log_to_file && !is_logging_to_file()) || + (settings->bools.log_to_file && is_logging_to_file())) + return; + + /* If we are currently logging to file and wish to stop, + * de-initialise existing logger... */ + if (!settings->bools.log_to_file && is_logging_to_file()) + { + retro_main_log_file_deinit(); + /* ...and revert to console */ + retro_main_log_file_init(NULL, false); + return; + } + + /* If we reach this point, then we are not currently + * logging to file, and wish to do so */ + + /* > Check whether we are already logging to console */ + fp = retro_main_log_file(); + if (fp) + { + /* De-initialise existing logger */ + retro_main_log_file_deinit(); + } + + /* > Attempt to initialise log file */ + if (!string_is_empty(settings->paths.log_dir)) + { + char buf[PATH_MAX_LENGTH]; + fill_pathname_join(buf, settings->paths.log_dir, file_path_str(FILE_PATH_DEFAULT_EVENT_LOG), sizeof(buf)); + if (!string_is_empty(buf)) + { + /* When RetroArch is launched, log file is overwritten. + * On subsequent calls within the same session, it is appended to. */ + retro_main_log_file_init(buf, log_file_created); + log_file_created = true; + success = true; + } + } + + /* > Fall back to console logging if something went wrong */ + if (!success) + retro_main_log_file_init(NULL, false); +} + +void rarch_log_file_deinit(void) +{ + FILE *fp = NULL; + + /* De-initialise existing logger, if currently logging to file */ + if (is_logging_to_file()) + { + retro_main_log_file_deinit(); + } + + /* If logging is currently disabled... */ + fp = retro_main_log_file(); + if (!fp) + { + /* ...initialise logging to console */ + retro_main_log_file_init(NULL, false); + } +} diff --git a/retroarch.h b/retroarch.h index 721938f379..8063848ae9 100644 --- a/retroarch.h +++ b/retroarch.h @@ -428,6 +428,10 @@ bool rarch_write_debug_info(void); void rarch_get_cpu_architecture_string(char *cpu_arch_str, size_t len); +void rarch_log_file_init(void); + +void rarch_log_file_deinit(void); + RETRO_END_DECLS #endif diff --git a/verbosity.c b/verbosity.c index 662198dee0..8c05d20055 100644 --- a/verbosity.c +++ b/verbosity.c @@ -111,7 +111,7 @@ void *retro_main_log_file(void) return log_file_fp; } -void retro_main_log_file_init(const char *path) +void retro_main_log_file_init(const char *path, bool append) { if (log_file_initialized) return; @@ -125,7 +125,7 @@ void retro_main_log_file_init(const char *path) if (path == NULL) return; - log_file_fp = (FILE*)fopen_utf8(path, "wb"); + log_file_fp = (FILE*)fopen_utf8(path, append ? "ab" : "wb"); log_file_initialized = true; #if !defined(PS2) /* TODO: PS2 IMPROVEMENT */ @@ -145,6 +145,8 @@ void retro_main_log_file_deinit(void) if (log_file_buf) free(log_file_buf); log_file_buf = NULL; + + log_file_initialized = false; } #if !defined(HAVE_LOGGER) @@ -210,11 +212,7 @@ void RARCH_LOG_V(const char *tag, const char *fmt, va_list ap) #if defined(HAVE_QT) || defined(__WINRT__) char buffer[1024]; #endif -#ifdef HAVE_FILE_LOGGER FILE *fp = (FILE*)retro_main_log_file(); -#else - FILE *fp = stderr; -#endif #if defined(HAVE_QT) || defined(__WINRT__) buffer[0] = '\0'; diff --git a/verbosity.h b/verbosity.h index 546066af61..e6d11dbbd8 100644 --- a/verbosity.h +++ b/verbosity.h @@ -39,7 +39,7 @@ void *retro_main_log_file(void); void retro_main_log_file_deinit(void); -void retro_main_log_file_init(const char *path); +void retro_main_log_file_init(const char *path, bool append); bool is_logging_to_file(void); From 8771e5b95825d0c905b642225a11f030be610855 Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Sun, 17 Mar 2019 12:35:30 -0400 Subject: [PATCH 072/237] use PLAYLISTS_TAB enum instead of COLLECTION_LIST --- intl/msg_hash_ar.c | 12 ++++---- intl/msg_hash_ar.h | 8 ++--- intl/msg_hash_chs.c | 16 +++++----- intl/msg_hash_chs.h | 6 +--- intl/msg_hash_cht.c | 18 ++++++------ intl/msg_hash_cht.h | 18 +++++------- intl/msg_hash_de.c | 10 +++---- intl/msg_hash_de.h | 6 +--- intl/msg_hash_el.c | 12 ++++---- intl/msg_hash_el.h | 6 +--- intl/msg_hash_eo.h | 8 ++--- intl/msg_hash_es.c | 18 ++++++------ intl/msg_hash_es.h | 6 +--- intl/msg_hash_fr.h | 6 +--- intl/msg_hash_it.c | 4 +-- intl/msg_hash_it.h | 6 +--- intl/msg_hash_ja.c | 39 ++++++++++++------------- intl/msg_hash_ja.h | 6 +--- intl/msg_hash_ko.c | 12 ++++---- intl/msg_hash_ko.h | 6 +--- intl/msg_hash_lbl.h | 2 -- intl/msg_hash_nl.h | 6 +--- intl/msg_hash_pl.h | 6 +--- intl/msg_hash_pt_br.c | 26 ++++++++--------- intl/msg_hash_pt_br.h | 6 +--- intl/msg_hash_pt_pt.h | 6 +--- intl/msg_hash_ru.h | 6 +--- intl/msg_hash_us.c | 12 ++++---- intl/msg_hash_us.h | 8 ++--- intl/msg_hash_vn.c | 47 +++++++++++++++--------------- intl/msg_hash_vn.h | 6 +--- menu/cbs/menu_cbs_cancel.c | 2 +- menu/cbs/menu_cbs_deferred_push.c | 4 +-- menu/cbs/menu_cbs_get_value.c | 2 +- menu/cbs/menu_cbs_ok.c | 4 +-- menu/cbs/menu_cbs_sublabel.c | 4 +-- menu/cbs/menu_cbs_title.c | 6 ++-- menu/drivers/ozone/ozone.c | 6 ++-- menu/drivers/ozone/ozone_sidebar.c | 4 +-- menu/drivers/ozone/ozone_texture.c | 2 +- menu/drivers/xmb.c | 12 ++++---- menu/menu_displaylist.c | 22 +++++++------- msg_hash.h | 4 +-- 43 files changed, 174 insertions(+), 252 deletions(-) diff --git a/intl/msg_hash_ar.c b/intl/msg_hash_ar.c index d4ad60564b..0bb6cfcb47 100644 --- a/intl/msg_hash_ar.c +++ b/intl/msg_hash_ar.c @@ -696,24 +696,24 @@ int menu_hash_get_help_ar_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "To scan for content, go to '%s' and\n" "select either '%s' or %s'.\n" - " \n" + "\n" "Files will be compared to database entries.\n" "If there is a match, it will add an entry\n" - "to a collection.\n" - " \n" + "to a playlist.\n" + "\n" "You can then easily access this content by\n" "going to '%s' ->\n" "'%s'\n" "instead of having to go through the\n" - "filebrowser everytime.\n" - " \n" + "file browser everytime.\n" + "\n" "NOTE: Content for some cores might still not be\n" "scannable.", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) ); break; case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: diff --git a/intl/msg_hash_ar.h b/intl/msg_hash_ar.h index 4261ff67ba..3b1e600e73 100644 --- a/intl/msg_hash_ar.h +++ b/intl/msg_hash_ar.h @@ -530,10 +530,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Save Configuration on Exit" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Collections" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Database" @@ -2694,8 +2690,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, "Select the port for the overlay to listen to if Show Inputs On Overlay is enabled.") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, - "Scanned content will appear here." + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, + "Scanned content matching the database will appear here." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, diff --git a/intl/msg_hash_chs.c b/intl/msg_hash_chs.c index 498c4e4e4c..6e182511d7 100644 --- a/intl/msg_hash_chs.c +++ b/intl/msg_hash_chs.c @@ -632,15 +632,15 @@ int menu_hash_get_help_chs_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC: snprintf(s, len, - "若要扫描游戏内容,请访问菜单「%s」 \n" + "若要扫描游戏内容,请访问菜单「%s」\n" "并选择「%s」或者「%s」。\n" - " \n" - "文件将会同数据库中的条目进行对比。 \n" - "若文件匹配某个条目,则它会被加入收藏中。 \n" - " \n" - "你可以无需每次都打开文件浏览器,而可以直接 \n" + "\n" + "文件将会同数据库中的条目进行对比。\n" + "若文件匹配某个条目,则它会被加入戏列表中。\n" + "\n" + "你可以无需每次都打开文件浏览器,而可以直接\n" "通过菜单项「%s」->「%s」 来访\n" - "问这些游戏内容。 \n" + "问这些游戏内容。\n" " \n" "注意:不是所有核心的游戏内容都支持扫描录入。" , @@ -648,7 +648,7 @@ int menu_hash_get_help_chs_enum(enum msg_hash_enums msg, char *s, size_t len) msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) ); break; case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index 18cdfc12db..d51c9ff98d 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -523,10 +523,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIRM_ON_EXIT, "退出时进行询问" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "收藏" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "游戏内容数据库文件夹" @@ -2751,7 +2747,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, "如果开启「在图层上显示控制器」,\n" "请选择相应屏幕图层的端口来侦听。") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "扫描到的游戏内容将在此处显示。" ) MSG_HASH( diff --git a/intl/msg_hash_cht.c b/intl/msg_hash_cht.c index b273803849..0748c607c0 100644 --- a/intl/msg_hash_cht.c +++ b/intl/msg_hash_cht.c @@ -646,23 +646,23 @@ int menu_hash_get_help_cht_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC: snprintf(s, len, - "若要掃瞄遊戲內容,請訪問菜單「%s」 \n" + "若要掃瞄遊戲內容,請訪問菜單「%s」\n" "並選擇「%s」或者「%s」。\n" - " \n" - "文件將會同數據庫中的條目進行對比。 \n" - "若文件匹配某個條目,則它會被加入收藏中。 \n" - " \n" - "你可以無需每次都打開文件瀏覽器,而可以直接 \n" + "\n" + "文件將會同數據庫中的條目進行對比。\n" + "若文件匹配某個條目,則它會被加入戲列表中。\n" + "\n" + "你可以無需每次都打開文件瀏覽器,而可以直接\n" "通過菜單項「%s」->「%s」 來訪\n" - "問這些遊戲內容。 \n" - " \n" + "問這些遊戲內容。\n" + "\n" "注意:不是所有核心的遊戲內容都支持掃瞄錄入。" , msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) ); break; case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index 7661b5aa54..b9839dc9d7 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -473,10 +473,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIRM_ON_EXIT, "退出時進行詢問" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "收藏" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "遊戲內容數據庫目錄" @@ -1091,9 +1087,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, "沒有性能計數器。") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, - "沒有遊戲列表。") + "沒有戲列表。") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLIST_ENTRIES_AVAILABLE, - "沒有可用的遊戲列表項目。") + "沒有可用的戲列表項目。") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, "沒有找到設定。") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, @@ -1141,11 +1137,11 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, "性能計數器") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, - "遊戲列表") + "戲列表") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "遊戲列表目錄") + "戲列表目錄") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, - "遊戲列表") + "戲列表") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, "觸控支援") MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, @@ -1802,7 +1798,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, "修改此系統的默認目錄。") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, - "修改遊戲列表設定。") + "修改戲列表設定。") MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, "修改網路設定。") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, @@ -2512,7 +2508,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, "Hide the overlay while inside the menu, and show it again when exiting the menu.") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "Scanned content will appear here." ) MSG_HASH( diff --git a/intl/msg_hash_de.c b/intl/msg_hash_de.c index 35d288c79d..ec10701f9a 100644 --- a/intl/msg_hash_de.c +++ b/intl/msg_hash_de.c @@ -676,17 +676,17 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Um nach Inhalten zu suchen, gehe zu '%s' und\n" "wähle '%s' oder %s'.\n" - " \n" + "\n" "Die Dateien werden werden mit einer Datenbank abgeglichen.\n" - "Bei einem Treffer wird die Datei zu einer Sammlung\n" + "Bei einem Treffer wird die Datei zu eine Wiedergabeliste\n" "hinzugefügt.\n" - " \n" + "\n" "du kannst diese Inhalte einfach aufrufen, indem du\n" "zu'%s' ->\n" "'%s'\n gehst," "anstatt jedes Mal den Dateibrowser\n" "verwenden zu müssen.\n" - " \n" + "\n" "HINWEIS: Inhalte für einige Cores können möglicherweise\n" "noch nicht durchsucht werden." , @@ -694,7 +694,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) ); break; case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 1be3956bfc..54fc68624a 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -506,10 +506,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Einstellungen beim Beenden speichern" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Sammlungen" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Inhaltsdatenbank" @@ -2620,7 +2616,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, "Wähle den Port des Controllers aus, dessen Eingaben im Overlay angezeigt werden sollen.") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "Während der Suche gefundener Inhalt wird hier erscheinen." ) MSG_HASH( diff --git a/intl/msg_hash_el.c b/intl/msg_hash_el.c index 8ca0867487..9e59d2cf04 100644 --- a/intl/msg_hash_el.c +++ b/intl/msg_hash_el.c @@ -706,24 +706,24 @@ int menu_hash_get_help_el_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "To scan for content, go to '%s' and\n" "select either '%s' or %s'.\n" - " \n" + "\n" "Files will be compared to database entries.\n" "If there is a match, it will add an entry\n" - "to a collection.\n" - " \n" + "to a playlist.\n" + "\n" "You can then easily access this content by\n" "going to '%s' ->\n" "'%s'\n" "instead of having to go through the\n" - "filebrowser everytime.\n" - " \n" + "file browser every time.\n" + "\n" "NOTE: Content for some cores might still not be\n" "scannable.", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) ); break; case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: diff --git a/intl/msg_hash_el.h b/intl/msg_hash_el.h index 9fd13ec7a7..0466838c00 100644 --- a/intl/msg_hash_el.h +++ b/intl/msg_hash_el.h @@ -554,10 +554,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Απόθηκευση Διαμόρφωσης στην Έξοδο" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Συλλογές" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Βάσεις Δεδομένων" @@ -4885,7 +4881,7 @@ MSG_HASH( "Επιλογή της θύρας για όταν είναι ενεργοποιημένη η επιλογή 'Εμφάνιση Εισαγωγών Στην Οθόνη'" ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "Το σαρωμένο περιεχόμενο θα εμφανίζεται εδώ." ) MSG_HASH( diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index b67e4a6245..8bcaede75d 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -399,10 +399,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Save Configuration on Exit" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Collections" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Content Database" @@ -2398,8 +2394,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, "Hide the overlay while inside the menu, and show it again when exiting the menu.") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, - "Scanned content will appear here." + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, + "Scanned content matching the database will appear here." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, diff --git a/intl/msg_hash_es.c b/intl/msg_hash_es.c index 1b0842119f..6576e00b6b 100644 --- a/intl/msg_hash_es.c +++ b/intl/msg_hash_es.c @@ -102,18 +102,18 @@ int menu_hash_get_help_es_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC: snprintf(s, len, - "Para escanear contenidos ve a '%s' \n" + "Para escanear contenidos ve a '%s'\n" "y selecciona '%s' o '%s'.\n" - " \n" - "Esto comparará los archivos con las entradas en \n" - "la base de datos. Si hay una coincidencia, \n" - "añadirá una entrada en una colección.\n" - " \n" + "\n" + "Esto comparará los archivos con las entradas en\n" + "la base de datos. Si hay una coincidencia,\n" + "añadirá una entrada en una lista de reproducción.\n" + "\n" "Entonces podrás acceder fácilmente al contenido\n" "si vas a '%s' -> '%s'\n" - "en vez de tener que pasar por el navegador \n" + "en vez de tener que pasar por el navegador\n" "de archivos constantemente.\n" - " \n" + "\n" "NOTA: El contenido de algunos núcleos podría\n" "no ser localizable. Entre los ejemplos están\n" "PlayStation, MAME, FBA, y puede que otros.", @@ -121,7 +121,7 @@ int menu_hash_get_help_es_enum(enum msg_hash_enums msg, char *s, size_t len) msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) ); break; case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index bbfe18ff73..d7b8e02e70 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -581,10 +581,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Guardar configuración al salir" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Colecciones" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Base de datos" @@ -4985,7 +4981,7 @@ MSG_HASH( "Seleccionar el puerto en que los controles en pantalla escucharán las pulsaciones" ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "El contenido escaneado aparecerá aquí" ) MSG_HASH( diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 1fe39d6a1f..e4efe28a30 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -474,10 +474,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Sauvegarder la configuration en quittant" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Collections" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Base de données" @@ -2556,7 +2552,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, "Cacher l'overlay quand vous êtes dans le menu. Il sera actif uniquement dans les jeux.") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "Les contenus scannés apparaitront ici." ) MSG_HASH( diff --git a/intl/msg_hash_it.c b/intl/msg_hash_it.c index c81047efa0..2915a5f792 100644 --- a/intl/msg_hash_it.c +++ b/intl/msg_hash_it.c @@ -98,7 +98,7 @@ int menu_hash_get_help_it_enum(enum msg_hash_enums msg, char *s, size_t len) " \n" "I files saranno comparati alle entrate del database.\n" "Se c'è un riscontro, sarà aggiunta un'entrata\n" - "alla collezione.\n" + "alla playlist.\n" " \n" "Puoi accedere facilmente a questo contenuto\n" "andando su '%s' ->\n" @@ -114,7 +114,7 @@ int menu_hash_get_help_it_enum(enum msg_hash_enums msg, char *s, size_t len) msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) ); break; case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index 99fa7614cc..f74c666895 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -478,10 +478,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Salva la configurazione all' uscita" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Collezioni" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Database" @@ -2592,7 +2588,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, "Select the port for the overlay to listen to if Show Inputs On Overlay is enabled.") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "Qui vengono visualizzati i contenuti scansionati." ) MSG_HASH( diff --git a/intl/msg_hash_ja.c b/intl/msg_hash_ja.c index e4d823c82e..c3df9e2019 100644 --- a/intl/msg_hash_ja.c +++ b/intl/msg_hash_ja.c @@ -665,31 +665,30 @@ int menu_hash_get_help_jp_enum(enum msg_hash_enums msg, char *s, size_t len) strlcat(s, u, len); } break; - case MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC: - snprintf(s, len, + case MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC: + snprintf(s, len, "To scan for content, go to '%s' and\n" - "select either '%s' or %s'.\n" - " \n" - "Files will be compared to database entries.\n" - "If there is a match, it will add an entry\n" - "to a collection.\n" - " \n" - "You can then easily access this content by\n" - "going to '%s' ->\n" - "'%s'\n" - "instead of having to go through the\n" - "filebrowser everytime.\n" - " \n" - "NOTE: Content for some cores might still not be\n" - "scannable." - , + "select either '%s' or %s'.\n" + "\n" + "Files will be compared to database entries.\n" + "If there is a match, it will add an entry\n" + "to a playlist.\n" + "\n" + "You can then easily access this content by\n" + "going to '%s' ->\n" + "'%s'\n" + "instead of having to go through the\n" + "file browser every time.\n" + "\n" + "NOTE: Content for some cores might still not be\n" + "scannable.", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) - ); - break; + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) + ); + break; case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: snprintf(s, len, "Welcome to RetroArch\n" diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index e14fc8b465..5bb3526a4e 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -565,10 +565,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "終了前に設定を自動保存" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "コレクション" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "コンテンツデータベース" @@ -2770,7 +2766,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, "メニュー表示中はオーバーレイを隠し、メニューを閉じたときに再表示する。") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "スキャンしたコンテンツを表示します。" ) MSG_HASH( diff --git a/intl/msg_hash_ko.c b/intl/msg_hash_ko.c index 87c0c0adfb..f607bceb33 100644 --- a/intl/msg_hash_ko.c +++ b/intl/msg_hash_ko.c @@ -680,24 +680,24 @@ int menu_hash_get_help_ko_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "To scan for content, go to '%s' and\n" "select either '%s' or %s'.\n" - " \n" + "\n" "Files will be compared to database entries.\n" "If there is a match, it will add an entry\n" - "to a collection.\n" - " \n" + "to a playlist.\n" + "\n" "You can then easily access this content by\n" "going to '%s' ->\n" "'%s'\n" "instead of having to go through the\n" - "filebrowser everytime.\n" - " \n" + "file browser every time.\n" + "\n" "NOTE: Content for some cores might still not be\n" "scannable.", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) ); break; case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index bfec9bae41..4df173d6fd 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -462,10 +462,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "종료시 환경설정 저장하기" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "컬렉션" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "데이터베이스" @@ -2510,7 +2506,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, "메뉴 화면에서 오버레이를 숨기고 메뉴 종료 시에 다시 표시.") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "검색된 컨텐츠가 이곳에 표시됨." ) MSG_HASH( diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index a0f0b92e35..6d53ee49f6 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -193,8 +193,6 @@ MSG_HASH(MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM, "connect_room") MSG_HASH(MENU_ENUM_LABEL_CONTENT_ACTIONS, "content_actions") -MSG_HASH(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST, - "select_from_collection") MSG_HASH(MENU_ENUM_LABEL_BROWSE_URL_LIST, "browse_url_list") MSG_HASH(MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY, diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index b7eb9ad1c8..830c4cb00d 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -399,10 +399,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Configuratie Opslaan Tijdens Afsluiten" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Collecties" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Inhoud Database" @@ -2401,7 +2397,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, "Hide the overlay while inside the menu, and show it again when exiting the menu.") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "Gescande inhoud zal hier getoond worden." ) MSG_HASH( diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index 510ba2a690..8405ea8915 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -534,10 +534,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Zapisz konfigurację przy wyjściu" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Kolekcje" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Baza danych" @@ -2724,7 +2720,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, "Wybierz port dla nakładki, aby usłyszeć, czy opcja Pokaż nakładki na nakładkę jest włączona.") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "Tutaj pojawi się skanowana zawartość." ) MSG_HASH( diff --git a/intl/msg_hash_pt_br.c b/intl/msg_hash_pt_br.c index dff66b5f81..3aac1693e1 100644 --- a/intl/msg_hash_pt_br.c +++ b/intl/msg_hash_pt_br.c @@ -704,28 +704,28 @@ int menu_hash_get_help_pt_br_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC: snprintf(s, len, - "Para analisar por conteúdo, vá para \n" + "Para analisar por conteúdo, vá para\n" "'%s' e selecione \n" - "'%s' ou '%s'. \n" - " \n" - "Os arquivos serão comparados com registros \n" - "da base de dados. \n" - "Se houver uma correspondência, um registro \n" - "será adicionado a uma coleção. \n" - " \n" + "'%s' ou '%s'.\n" + "\n" + "Os arquivos serão comparados com registros\n" + "da base de dados.\n" + "Se houver uma correspondência, um registro\n" + "será adicionado à uma lista de reprodução.\n" + "\n" "Você poderá então acessar facilmente este \n" - "conteúdo indo até \n" + "conteúdo indo até\n" "'%s' -> '%s'\n" - "em vez de ter que utilizar o \n" + "em vez de ter que utilizar o\n" "navegador de arquivos todas as vezes.\n" - " \n" - "OBS: Conteúdo para alguns núcleos pode ainda \n" + "\n" + "OBS: Conteúdo para alguns núcleos pode ainda\n" "não ser reconhecido.", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) ); break; case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index 19f22420c0..c489b56bb5 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -589,10 +589,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Salvar Configuração ao Sair" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Coleções" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Base de Dados" @@ -5129,7 +5125,7 @@ MSG_HASH( "Selecione a porta para a transparência escutar se Exibir Comandos na Transparência estiver habilitado." ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "O conteúdo analisado aparecerá aqui." ) MSG_HASH( diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h index 4101c40ea8..1296366ffd 100644 --- a/intl/msg_hash_pt_pt.h +++ b/intl/msg_hash_pt_pt.h @@ -462,10 +462,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Guardar configuração ao sair" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Coleções" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Base de dados" @@ -2499,7 +2495,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, "Ocultar a sobreposição quando o menu estiver aberto e mostrar novamente ao encerrar o mesmo.") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "O conteúdo verificado aparecerá aqui." ) MSG_HASH( diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index 2d7cef985b..e77b1dfe5a 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -483,10 +483,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Сохранить конфигурацию и выйти" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Коллекции" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "База данных контента" @@ -2561,7 +2557,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, "Спрятать наложения в меню интерфейса, и показывать снова после выхода из него.") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "Сканированный контент появится здесь." ) MSG_HASH( diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index 384ab23163..b317e23e89 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -719,24 +719,24 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "To scan for content, go to '%s' and\n" "select either '%s' or %s'.\n" - " \n" + "\n" "Files will be compared to database entries.\n" "If there is a match, it will add an entry\n" - "to a collection.\n" - " \n" + "to a playlist.\n" + "\n" "You can then easily access this content by\n" "going to '%s' ->\n" "'%s'\n" "instead of having to go through the\n" - "filebrowser everytime.\n" - " \n" + "file browser every time.\n" + "\n" "NOTE: Content for some cores might still not be\n" "scannable.", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) ); break; case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index fe06a6aad5..74a68774d7 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -589,10 +589,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Save Configuration on Exit" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Playlists" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Database" @@ -5352,8 +5348,8 @@ MSG_HASH( "Select the port for the overlay to listen to if Show Inputs On Overlay is enabled." ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, - "Scanned content will appear here." + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, + "Scanned content matching the database will appear here." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, diff --git a/intl/msg_hash_vn.c b/intl/msg_hash_vn.c index 371a7d2e40..cf35698852 100644 --- a/intl/msg_hash_vn.c +++ b/intl/msg_hash_vn.c @@ -666,30 +666,29 @@ int menu_hash_get_help_vn_enum(enum msg_hash_enums msg, char *s, size_t len) } break; case MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC: - snprintf(s, len, - "To scan for content, go to '%s' and\n" - "select either '%s' or %s'.\n" - " \n" - "Files will be compared to database entries.\n" - "If there is a match, it will add an entry\n" - "to a collection.\n" - " \n" - "You can then easily access this content by\n" - "going to '%s' ->\n" - "'%s'\n" - "instead of having to go through the\n" - "filebrowser everytime.\n" - " \n" - "NOTE: Content for some cores might still not be\n" - "scannable." - , - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) - ); - break; + snprintf(s, len, + "To scan for content, go to '%s' and\n" + "select either '%s' or %s'.\n" + "\n" + "Files will be compared to database entries.\n" + "If there is a match, it will add an entry\n" + "to a playlist.\n" + "\n" + "You can then easily access this content by\n" + "going to '%s' ->\n" + "'%s'\n" + "instead of having to go through the\n" + "file browser every time.\n" + "\n" + "NOTE: Content for some cores might still not be\n" + "scannable.", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) + ); + break; case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: snprintf(s, len, "Welcome to RetroArch\n" diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h index 6c802afa81..2b6f716913 100644 --- a/intl/msg_hash_vn.h +++ b/intl/msg_hash_vn.h @@ -474,10 +474,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Lưu cấu hình khi thoát" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Bộ sưu tập" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Mục cơ sở dữ liệu nội dung" @@ -2560,7 +2556,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, "Hide the overlay while inside the menu, and show it again when exiting the menu.") MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + MENU_ENUM_SUBLABEL_PLAYLISTS_TAB, "Scanned content will appear here." ) MSG_HASH( diff --git a/menu/cbs/menu_cbs_cancel.c b/menu/cbs/menu_cbs_cancel.c index c06aefaf47..0f4076b4fb 100644 --- a/menu/cbs/menu_cbs_cancel.c +++ b/menu/cbs/menu_cbs_cancel.c @@ -53,7 +53,7 @@ int action_cancel_pop_default(const char *path, { if ( string_is_equal(menu_label, - msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST) + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB) ) || string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_MENU_WALLPAPER) diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 8029d8c254..7b444cbb29 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -1238,7 +1238,7 @@ static int menu_cbs_init_bind_deferred_push_compare_label( case MENU_ENUM_LABEL_CORE_LIST: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_core_list); break; - case MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST: + case MENU_ENUM_LABEL_PLAYLISTS_TAB: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_content_collection_list); break; case MENU_ENUM_LABEL_CONFIGURATIONS: @@ -1476,7 +1476,7 @@ static int menu_cbs_init_bind_deferred_push_compare_label( case MENU_LABEL_CORE_INPUT_REMAPPING_OPTIONS: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_core_input_remapping_options); break; - case MENU_LABEL_CONTENT_COLLECTION_LIST: + case MENU_LABEL_PLAYLISTS_TAB: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_content_collection_list); break; case MENU_LABEL_CONFIGURATIONS: diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index 624aedf633..c826845d29 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -1362,7 +1362,7 @@ static int menu_cbs_init_bind_get_string_representation_compare_label( BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label_menu_video_resolution); break; - case MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST: + case MENU_ENUM_LABEL_PLAYLISTS_TAB: case MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY: case MENU_ENUM_LABEL_DOWNLOADED_FILE_DETECT_CORE_LIST: case MENU_ENUM_LABEL_FAVORITES: diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 6e83490a12..550f32149a 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -5732,7 +5732,7 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_REMAP_FILE_REMOVE_GAME: BIND_ACTION_OK(cbs, action_ok_remap_file_remove_game); break; - case MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST: + case MENU_ENUM_LABEL_PLAYLISTS_TAB: BIND_ACTION_OK(cbs, action_ok_content_collection_list); break; case MENU_ENUM_LABEL_BROWSE_URL_LIST: @@ -6103,7 +6103,7 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, BIND_ACTION_OK(cbs, action_ok_push_default); break; case FILE_TYPE_PLAYLIST_ENTRY: - if (label_hash == MENU_LABEL_COLLECTION) + if (label_hash == MENU_LABEL_PLAYLISTS_TAB) { BIND_ACTION_OK(cbs, action_ok_playlist_entry_collection); } diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index de341c3a1e..cf8332f430 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -213,7 +213,7 @@ default_sublabel_macro(action_bind_sublabel_video_message_pos_x, MENU_ default_sublabel_macro(action_bind_sublabel_video_message_pos_y, MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_Y) default_sublabel_macro(action_bind_sublabel_video_font_size, MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE) default_sublabel_macro(action_bind_sublabel_input_overlay_hide_in_menu, MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU) -default_sublabel_macro(action_bind_sublabel_content_collection_list, MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST) +default_sublabel_macro(action_bind_sublabel_content_collection_list, MENU_ENUM_SUBLABEL_PLAYLISTS_TAB) default_sublabel_macro(action_bind_sublabel_video_scale_integer, MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER) default_sublabel_macro(action_bind_sublabel_video_gpu_screenshot, MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT) default_sublabel_macro(action_bind_sublabel_video_rotation, MENU_ENUM_SUBLABEL_VIDEO_ROTATION) @@ -1896,7 +1896,7 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_scale_integer); break; - case MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST: + case MENU_ENUM_LABEL_PLAYLISTS_TAB: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_collection_list); break; case MENU_ENUM_LABEL_INPUT_OVERLAY_HIDE_IN_MENU: diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index 4da8251556..57cbd97320 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -172,7 +172,7 @@ default_title_macro(action_get_title_goto_favorites, MENU_ENUM_LABEL_ default_title_macro(action_get_title_goto_image, MENU_ENUM_LABEL_VALUE_GOTO_IMAGES) default_title_macro(action_get_title_goto_music, MENU_ENUM_LABEL_VALUE_GOTO_MUSIC) default_title_macro(action_get_title_goto_video, MENU_ENUM_LABEL_VALUE_GOTO_VIDEO) -default_title_macro(action_get_title_collection, MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) +default_title_macro(action_get_title_collection, MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) default_fill_title_macro(action_get_title_disk_image_append, MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND) default_fill_title_macro(action_get_title_cheat_file_load, MENU_ENUM_LABEL_VALUE_CHEAT_FILE) @@ -844,7 +844,7 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_ACHIEVEMENT_LIST_HARDCORE: case MENU_ENUM_LABEL_VIDEO_SHADER_PARAMETERS: case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_PARAMETERS: - case MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST: + case MENU_ENUM_LABEL_PLAYLISTS_TAB: BIND_ACTION_GET_TITLE(cbs, action_get_title_action_generic); break; case MENU_ENUM_LABEL_DISK_IMAGE_APPEND: @@ -1144,7 +1144,7 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_LABEL_DEFERRED_PLAYLIST_SETTINGS_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_playlist_settings_list); break; - case MENU_LABEL_CONTENT_COLLECTION_LIST: + case MENU_LABEL_PLAYLISTS_TAB: BIND_ACTION_GET_TITLE(cbs, action_get_title_collection); break; case MENU_LABEL_ACHIEVEMENT_LIST: diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index c19c2d3618..ad5b25eddb 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -740,9 +740,9 @@ static int ozone_list_push(void *data, void *userdata, #ifdef HAVE_LIBRETRODB menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST), - MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB), + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB), + MENU_ENUM_LABEL_PLAYLISTS_TAB, MENU_SETTING_ACTION, 0, 0); #endif diff --git a/menu/drivers/ozone/ozone_sidebar.c b/menu/drivers/ozone/ozone_sidebar.c index bafe6f5cd7..89431e58cb 100644 --- a/menu/drivers/ozone/ozone_sidebar.c +++ b/menu/drivers/ozone/ozone_sidebar.c @@ -532,11 +532,11 @@ void ozone_init_horizontal_list(ozone_handle_t *ozone) info.path = strdup( settings->paths.directory_playlist); info.label = strdup( - msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST)); + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)); info.exts = strdup( file_path_str(FILE_PATH_LPL_EXTENSION_NO_DOT)); info.type_default = FILE_TYPE_PLAIN; - info.enum_idx = MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST; + info.enum_idx = MENU_ENUM_LABEL_PLAYLISTS_TAB; if (settings->bools.menu_content_show_playlists && !string_is_empty(info.path)) { diff --git a/menu/drivers/ozone/ozone_texture.c b/menu/drivers/ozone/ozone_texture.c index 529ae51301..1aa3d39533 100644 --- a/menu/drivers/ozone/ozone_texture.c +++ b/menu/drivers/ozone/ozone_texture.c @@ -81,7 +81,7 @@ menu_texture_item ozone_entries_icon_get_texture(ozone_handle_t *ozone, return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_RDB]; /* Menu collection submenus*/ - case MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST: + case MENU_ENUM_LABEL_PLAYLISTS_TAB: return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_ZIP]; case MENU_ENUM_LABEL_GOTO_FAVORITES: return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_FAVORITE]; diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index a5ac46e7f2..152425ed84 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -1827,11 +1827,11 @@ static void xmb_init_horizontal_list(xmb_handle_t *xmb) info.path = strdup( settings->paths.directory_playlist); info.label = strdup( - msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST)); + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)); info.exts = strdup( file_path_str(FILE_PATH_LPL_EXTENSION_NO_DOT)); info.type_default = FILE_TYPE_PLAIN; - info.enum_idx = MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST; + info.enum_idx = MENU_ENUM_LABEL_PLAYLISTS_TAB; if (settings->bools.menu_content_show_playlists && !string_is_empty(info.path)) { @@ -2216,7 +2216,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, return xmb->textures.list[XMB_TEXTURE_RDB]; /* Menu collection submenus */ - case MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST: + case MENU_ENUM_LABEL_PLAYLISTS_TAB: return xmb->textures.list[XMB_TEXTURE_ZIP]; case MENU_ENUM_LABEL_GOTO_FAVORITES: return xmb->textures.list[XMB_TEXTURE_FAVORITE]; @@ -5380,9 +5380,9 @@ static int xmb_list_push(void *data, void *userdata, #ifdef HAVE_LIBRETRODB menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST), - MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB), + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB), + MENU_ENUM_LABEL_PLAYLISTS_TAB, MENU_SETTING_ACTION, 0, 0); #endif diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index c9cccbd4f5..874cd6a6ff 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4002,7 +4002,7 @@ static bool menu_displaylist_push_internal( info->exts = strdup( file_path_str(FILE_PATH_LPL_EXTENSION_NO_DOT)); info->label = strdup( - msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST)); + 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); @@ -4021,7 +4021,7 @@ static bool menu_displaylist_push_internal( info->exts = strdup( file_path_str(FILE_PATH_LPL_EXTENSION_NO_DOT)); info->label = strdup( - msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST)); + 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); @@ -4040,7 +4040,7 @@ static bool menu_displaylist_push_internal( info->exts = strdup( file_path_str(FILE_PATH_LPL_EXTENSION_NO_DOT)); info->label = strdup( - msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST)); + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)); menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); @@ -4072,7 +4072,7 @@ static bool menu_displaylist_push_internal( info->exts = strdup( file_path_str(FILE_PATH_LPL_EXTENSION_NO_DOT)); info->label = strdup( - msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST)); + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)); if (string_is_empty(settings->paths.directory_playlist)) { @@ -7448,9 +7448,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist #ifdef HAVE_LIBRETRODB menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST), - MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB), + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB), + MENU_ENUM_LABEL_PLAYLISTS_TAB, MENU_SETTING_ACTION, 0, 0); #endif @@ -7717,9 +7717,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist if (string_is_equal(settings->arrays.menu_driver, "rgui") && settings->bools.menu_content_show_playlists) { menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST), - MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB), + msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB), + MENU_ENUM_LABEL_PLAYLISTS_TAB, MENU_SETTING_ACTION, 0, 0); } #endif @@ -8023,7 +8023,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist free(info->exts); info->exts = strdup( file_path_str(FILE_PATH_RDB_EXTENSION)); - info->enum_idx = MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST; + info->enum_idx = MENU_ENUM_LABEL_PLAYLISTS_TAB; load_content = false; use_filebrowser = true; if (info->path) diff --git a/msg_hash.h b/msg_hash.h index 6e9d9443ec..1abaa0cf4f 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1751,7 +1751,6 @@ enum msg_hash_enums MENU_ENUM_LABEL_COLLECTION, MENU_LABEL(CONFIGURATIONS), - MENU_LABEL(CONTENT_COLLECTION_LIST), MENU_LABEL(BROWSE_URL_LIST), MENU_ENUM_LABEL_CUSTOM_BIND, @@ -2532,8 +2531,7 @@ enum msg_hash_enums #define MENU_LABEL_REMAP_FILE_SAVE_CORE 0x7c9d4c8fU #define MENU_LABEL_REMAP_FILE_SAVE_CONTENT_DIR 0x7b99c1ffU #define MENU_LABEL_REMAP_FILE_SAVE_GAME 0x7c9f41e0U -#define MENU_LABEL_CONTENT_COLLECTION_LIST 0x32d1df83U -#define MENU_LABEL_COLLECTION 0x5fea5991U +#define MENU_LABEL_PLAYLISTS_TAB 0x5fea5991U #define MENU_LABEL_OPEN_ARCHIVE 0x78c0ca58U #define MENU_LABEL_OPEN_ARCHIVE_DETECT_CORE 0x92442638U From dcd9860e8002f80481e64747c66de82a1bf4580a Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Sun, 17 Mar 2019 17:47:18 -0400 Subject: [PATCH 073/237] update MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY --- intl/msg_hash_ar.h | 4 ++-- intl/msg_hash_chs.h | 8 ++++---- intl/msg_hash_cht.h | 4 ++-- intl/msg_hash_de.h | 4 ++-- intl/msg_hash_el.h | 4 ++-- intl/msg_hash_eo.h | 2 +- intl/msg_hash_es.h | 4 ++-- intl/msg_hash_fr.h | 4 ++-- intl/msg_hash_it.h | 6 +++--- intl/msg_hash_ja.h | 4 ++-- intl/msg_hash_ko.h | 4 ++-- intl/msg_hash_nl.h | 4 ++-- intl/msg_hash_pl.h | 6 +++--- intl/msg_hash_pt_br.h | 4 ++-- intl/msg_hash_pt_pt.h | 6 +++--- intl/msg_hash_ru.h | 6 +++--- intl/msg_hash_us.h | 2 +- intl/msg_hash_vn.h | 6 +++--- msg_hash.h | 2 +- retroarch.cfg | 2 +- 20 files changed, 43 insertions(+), 43 deletions(-) diff --git a/intl/msg_hash_ar.h b/intl/msg_hash_ar.h index 3b1e600e73..195a68c07e 100644 --- a/intl/msg_hash_ar.h +++ b/intl/msg_hash_ar.h @@ -2606,8 +2606,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "Show battery level") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Select File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Select From Collection") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "Select from Playlist") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "Filter") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index d51c9ff98d..b75d26954a 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -1251,11 +1251,11 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, "性能计数器") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, - "游戏列表") + "戏列表") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "游戏列表文件夹") + "戏列表文件夹") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, - "游戏列表") + "戏列表") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, "触摸支持") MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, @@ -2664,7 +2664,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "显示电池电量") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "选择文件") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, "从收藏中选择") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "过滤器") diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index b9839dc9d7..cbb4791073 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -2435,8 +2435,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "顯示電池電量") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "選擇文件") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "從收藏中選擇") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "從播放列表中選擇") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "過濾器") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 54fc68624a..37dc9501f9 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -2539,8 +2539,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "Akkustand anzeigen") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Wähle Datei") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Wähle aus Sammlung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "Wähle aus Wiedergabeliste") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "Filter") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, diff --git a/intl/msg_hash_el.h b/intl/msg_hash_el.h index 0466838c00..7ea57d58f9 100644 --- a/intl/msg_hash_el.h +++ b/intl/msg_hash_el.h @@ -4736,8 +4736,8 @@ MSG_HASH( "Επιλογή Αρχείου" ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Επιλογή Από Συλλογή" + MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "Επιλογή Από λίστα αναπαραγωγής" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_FILTER, diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index 8bcaede75d..2fb8d1a49c 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -1046,7 +1046,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, "Playlists") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Playlist") + "Playlists") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, "Playlists") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index d7b8e02e70..e8c34f713b 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -4817,8 +4817,8 @@ MSG_HASH( "Seleccionar archivo" ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Seleccionar de la colección" + MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "Seleccionar de la lista de reproducción" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_FILTER, diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index e4efe28a30..f8228b317a 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -2479,8 +2479,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "Afficher le niveau de la batterie") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Sélectionner un fichier") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Sélectionner depuis la collection") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "Sélectionner depuis la playlist") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "Filtre") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index f74c666895..2b3e89714f 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -1162,7 +1162,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, "Playlists") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Playlist") + "Playlists") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, "Playlists") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, @@ -2511,8 +2511,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "Visualizza il livello della batteria") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Seleziona File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Seleziona da collezione") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "Seleziona da Playlist") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "Filtra") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index 5bb3526a4e..6407db9604 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -2685,8 +2685,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "バッテリー残量を表示") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "ファイル選択") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "コレクションから選択") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "プレイリストから選択") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "フィルター") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index 4df173d6fd..36c9f0de9e 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -2437,8 +2437,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "배터리 수준 표시") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "파일 선택") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "컬렉션에서 선택") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "재생목록에서 선택") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "필터") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index 830c4cb00d..e8255fe5c5 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -1045,9 +1045,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, "Afspeellijsten") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Afspeellijst") + "Afspeellijsten") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, - "Playlists") + "Afspeellijsten") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, "Touch Ondersteuning") MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index 8405ea8915..a35dd5165a 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -1242,7 +1242,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, "Listy odtwarzania") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Playlista") + "Listy odtwarzania") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, "Listy odtwarzania") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, @@ -2641,8 +2641,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "Pokaż poziom naładowania baterii") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Wybierz plik") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Wybierz z kolekcji") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "Wybierz z listy odtwarzania") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "Filtr") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index c489b56bb5..d58c9b5c81 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -4957,8 +4957,8 @@ MSG_HASH( "Selecionar Arquivo" ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Selecionar de Coleção" + MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "Selecionar da Lista de Reprodução" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_FILTER, diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h index 1296366ffd..42c13a3ad8 100644 --- a/intl/msg_hash_pt_pt.h +++ b/intl/msg_hash_pt_pt.h @@ -1128,7 +1128,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, "Contadores de desempenhp") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, - "Listas de reprodução") + "Selecionar de Listas de Reprodução") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, "Pasta de listas de reprodução") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, @@ -2426,8 +2426,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "Mostrado estado da bateria") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Selecionar ficheiro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Selecionar de coleção") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "Selecionar da Lista de Reprodução") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "Filtro") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index e77b1dfe5a..dfb17365e7 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -1159,7 +1159,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, "Плейлисты") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Плейлист") + "Плейлисты") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, "Плейлисты") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, @@ -2484,8 +2484,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "Показать заряд батареи") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Выбрать файл") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Выбрать файл с коллекции") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "Выбрать из списка воспроизведения.") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "Фильтр") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 74a68774d7..4e8858589e 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -5180,7 +5180,7 @@ MSG_HASH( "Select File" ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, + MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, "Select from a playlist" ) MSG_HASH( diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h index 2b6f716913..f6d7c3a238 100644 --- a/intl/msg_hash_vn.h +++ b/intl/msg_hash_vn.h @@ -1157,7 +1157,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, "Playlists") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Playlist Danh mục") + "Playlists Danh mục") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, "Playlists") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, @@ -2478,8 +2478,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "Display battery level") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Select File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Select From Collection") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, + "Select from Playlst") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "Filter") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, diff --git a/msg_hash.h b/msg_hash.h index 1abaa0cf4f..741bc56551 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -2035,7 +2035,7 @@ enum msg_hash_enums MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, MENU_LABEL(SELECT_FILE), - MENU_LABEL(SELECT_FROM_COLLECTION), + MENU_LABEL(SELECT_FROM_PLAYLIST), MENU_ENUM_LABEL_VALUE_FILTER, MENU_ENUM_LABEL_VALUE_SCALE, diff --git a/retroarch.cfg b/retroarch.cfg index a996f1c8bd..bf0319399d 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -908,4 +908,4 @@ # vibrate_on_keypress = false # Enable device vibration for supported cores -# enable_device_vibration = false +# enable_device_vibration = false \ No newline at end of file From 961e435317c4b7a08b9701df627b78b4acba10f1 Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Sun, 17 Mar 2019 20:19:28 -0400 Subject: [PATCH 074/237] update MENU_ENUM_SUBLABEL_SCAN_XX strings --- intl/msg_hash_ar.h | 4 ++-- intl/msg_hash_chs.h | 4 ++-- intl/msg_hash_cht.h | 4 ++-- intl/msg_hash_de.h | 4 ++-- intl/msg_hash_el.h | 4 ++-- intl/msg_hash_eo.h | 4 ++-- intl/msg_hash_es.h | 4 ++-- intl/msg_hash_fr.h | 4 ++-- intl/msg_hash_it.h | 4 ++-- intl/msg_hash_ja.h | 4 ++-- intl/msg_hash_ko.h | 4 ++-- intl/msg_hash_nl.h | 4 ++-- intl/msg_hash_pl.h | 4 ++-- intl/msg_hash_pt_br.h | 4 ++-- intl/msg_hash_pt_pt.h | 4 ++-- intl/msg_hash_ru.h | 4 ++-- intl/msg_hash_us.h | 4 ++-- intl/msg_hash_vn.h | 4 ++-- 18 files changed, 36 insertions(+), 36 deletions(-) diff --git a/intl/msg_hash_ar.h b/intl/msg_hash_ar.h index 195a68c07e..37ec1977eb 100644 --- a/intl/msg_hash_ar.h +++ b/intl/msg_hash_ar.h @@ -2946,9 +2946,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "Disconnects an active Netplay connection.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Scans a directory for compatible files and add them to the collection.") + "Scans a directory for content that matches the database.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Scans a compatible file and add it to the collection.") + "Scans a file for content that matches the database.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "Uses a custom swap interval for Vsync. Set this to effectively halve monitor refresh rate." ) diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index b75d26954a..6d1207d911 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -3166,9 +3166,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "断开当前网络连接。") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "扫描目录并将兼容的文件添加到合集中。") + "扫描目录并将兼容的文件添加到播放列表。") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "扫描一个兼容的文件并将其添加到合集中") + "扫描一个兼容的文件并将其添加到播放列表") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "为垂直同步使用自定义的交换间隔。该设置可以\n" "有效地降低显示器刷新率。" diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index cbb4791073..2d01248423 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -2764,9 +2764,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "Disconnects an active Netplay connection.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Scans a directory for compatible files and add them to the collection.") + "Scans a directory for content that matches the database.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Scans a compatible file and add it to the collection.") + "Scans a file for content that matches the database.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "Uses a custom swap interval for Vsync. Set this to effectively halve monitor refresh rate." ) diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 37dc9501f9..86b61cfa8f 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -2872,9 +2872,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "Beendet eine aktive Netplay-Verbindung.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Durchsuche ein Verzeichnis nach kompatiblen Dateien und füge diese zur Sammlung hinzu.") + "Durchsuche ein Verzeichnis nach kompatiblen Dateien.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Untersuche eine kompatible Datei und fügt diese zur Sammlung hinzu.") + "Untersuche eine kompatible Datei.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "Verwende ein eigenes Intervall für Vsync. Aktivieren, um die Bildschirm-Wiederholrate zu halbieren." ) diff --git a/intl/msg_hash_el.h b/intl/msg_hash_el.h index 7ea57d58f9..0f9dc8fc03 100644 --- a/intl/msg_hash_el.h +++ b/intl/msg_hash_el.h @@ -5291,11 +5291,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Σαρώνει ένα ευρετήριο για συμβατά αρχεία και τα προσθέτει στην συλλογή." + "Σαρώνει ένα ευρετήριο για συμβατά αρχεία." ) MSG_HASH( MENU_ENUM_SUBLABEL_SCAN_FILE, - "Σαρώνει ένα συμβατό αρχείο και το προσθέτει στην συλλογή." + "Σαρώνει ένα συμβατό αρχείο" ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index 2fb8d1a49c..c23584af9a 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -2650,9 +2650,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "Disconnects an active Netplay connection.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Scans a directory for compatible files and add them to the collection.") + "Scans a directory for content that matches the database.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Scans a compatible file and add it to the collection.") + "Scans a file for content that matches the database.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "Uses a custom swap interval for Vsync. Set this to effectively halve monitor refresh rate." ) diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index e8c34f713b..e788d60183 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -5392,11 +5392,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Escanea una carpeta en busca de archivos compatibles y los añade a la colección" + "Escanea una carpeta en busca de archivos compatibles." ) MSG_HASH( MENU_ENUM_SUBLABEL_SCAN_FILE, - "Escanea un archivo compatible y lo añade a la colección" + "Escanea un archivo compatible." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index f8228b317a..e17e5c49fd 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -2808,9 +2808,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "Se déconnecter de la session de jeu en réseau active.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Analyse récursivement un dossier pour y trouver des contenus compatibles qui seront ajoutés dans des playlists.") + "Analyse récursivement un dossier pour y trouver des contenus compatibles.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Analyse un fichier pour vérifier s'il est compatible et l'ajouter à une playlist.") + "Analyse un fichier pour vérifier s'il est compatible.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "Uses a custom swap interval for Vsync. Set this to effectively halve monitor refresh rate." ) diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index 2b3e89714f..fe58db0988 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -2844,9 +2844,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "Disconnette da una connessione Netplay attiva") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Effettua la scansione di una directory per i file compatibili e li aggiunge alla raccolta.") + "Effettua la scansione di una directory per i file compatibili.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Esegue la scansione di un file compatibile e li aggiunge alla raccolta.") + "Esegue la scansione di un file compatibile.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "Utilizza un intervallo di scambio personalizzato per Vsync. Impostando un valore corretto dimezza la frequenza di aggiornamento del monitor." ) diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index 6407db9604..3e0f46fe63 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -3014,9 +3014,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "アクティブなネットプレイ接続を切断する。") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "フォルダ内のすべての対応ファイルをスキャンして\nコレクションに追加します。") + "フォルダ内のすべての対応ファイルをスキャン") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "対応ファイルをスキャンしてコレクションに追加\nします。") + "対応ファイルをスキャンし。") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "Uses a custom swap interval for Vsync. Set this to effectively halve monitor refresh rate." ) diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index 36c9f0de9e..d4e2c6f7a1 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -2762,9 +2762,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "활성 중인 모든 넷플레이 연결 해제.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "디렉토리에서 실행 가능한 파일을 검색하고 컬렉션에 추가.") + "디렉토리에서 실행 파일 검색.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "실행 가능한 파일을 검색하고 컬렉션에 추가.") + "실행 파일 검색.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "수직 동기에 사용자 스왑 간격을 사용. 모니터 재생 빈도를 효과적으로 줄이는데 사용." ) diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index e8255fe5c5..9a00f46fee 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -2653,9 +2653,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "Disconnects an active Netplay connection.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Scans a directory for compatible files and add them to the collection.") + "Scans a directory for content that matches the database.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Scans a compatible file and add it to the collection.") + "Scans a file for content that matches the database.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "Uses a custom swap interval for Vsync. Set this to effectively halve monitor refresh rate." ) diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index a35dd5165a..57e4296684 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -3003,9 +3003,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "Odłącz aktywne połączenie gry online.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Skanuje katalog w poszukiwaniu kompatybilnych plików i dodaje je do kolekcji.") + "Skanuje katalog w poszukiwaniu kompatybilnych plików.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Skanuje zgodny plik i dodaje go do kolekcji.") + "Skanuje zgodny plik.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "Używa niestandardowego interwału wymiany dla Vsync. Ustaw, aby efektywnie zmniejszyć o połowę częstotliwość odświeżania monitora." ) diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index d58c9b5c81..38c00d5c1d 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -5536,11 +5536,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Analisa um diretório por arquivos compatíveis e os adiciona à coleção." + "Analisa um diretório por arquivos compatíveis." ) MSG_HASH( MENU_ENUM_SUBLABEL_SCAN_FILE, - "Analisa um arquivo compatível e o adiciona à coleção." + "Analisa um arquivo compatível." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h index 42c13a3ad8..39add92bc7 100644 --- a/intl/msg_hash_pt_pt.h +++ b/intl/msg_hash_pt_pt.h @@ -2739,9 +2739,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "Terminar uma ligação de Netplay ativa.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Verificar uma pasta por ficheiros compatíveis e adicionar os mesmos à coleção.") + "Verificar uma pasta por ficheiros compatíveis.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Verificar um ficheiro compatível e adicioná-lo à coleção.") + "Verificar um ficheiro compatível.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "Usa um intervalo de troca personalizado para Vsync. Utilize isto para reduzir efetivamente a taxa de atualização do monitor." ) diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index dfb17365e7..f483278b9c 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -2813,9 +2813,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "Отключить активное соединение Netplay.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Сканирует каталог для поиска совместимых файлов и добавляет их в коллекцию.") + "Сканирует каталог для поиска совместимых файлов.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Сканирует совместимый файл и добавляет его в коллекцию.") + "Сканирует совместимый файл.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "Использует заданный интервал обновления для вертикальной синхронизации. Установите для эффективной частоты обновления монитора." ) diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 4e8858589e..8feac9824f 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -5773,11 +5773,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Scans a directory for compatible content. If found, content is added to playlists." + "Scans a directory for content that matches the database." ) MSG_HASH( MENU_ENUM_SUBLABEL_SCAN_FILE, - "Scans a file for compatible content. If found, content is added to playlists." + "Scans a file for content that matches the database." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h index f6d7c3a238..b70c09b1d0 100644 --- a/intl/msg_hash_vn.h +++ b/intl/msg_hash_vn.h @@ -2812,9 +2812,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "Disconnects an active Netplay connection.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Scans a directory for compatible files and add them to the collection.") + "Scans a directory for content that matches the database.") MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Scans a compatible file and add it to the collection.") + "Scans a file for content that matches the database.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "Uses a custom swap interval for Vsync. Set this to effectively halve monitor refresh rate." ) From 9b9b1e6b9ccbcc990b0a2760b22d094e168799c7 Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Fri, 22 Mar 2019 10:24:09 -0400 Subject: [PATCH 075/237] update MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE --- intl/msg_hash_ar.h | 4 ++-- intl/msg_hash_chs.h | 2 +- intl/msg_hash_cht.h | 4 ++-- intl/msg_hash_de.h | 4 ++-- intl/msg_hash_el.h | 4 ++-- intl/msg_hash_eo.h | 4 ++-- intl/msg_hash_es.h | 4 ++-- intl/msg_hash_fr.h | 2 +- intl/msg_hash_it.h | 4 ++-- intl/msg_hash_ja.h | 6 +++--- intl/msg_hash_ko.h | 4 ++-- intl/msg_hash_nl.h | 4 ++-- intl/msg_hash_pl.h | 4 ++-- intl/msg_hash_pt_br.h | 4 ++-- intl/msg_hash_pt_pt.h | 4 ++-- intl/msg_hash_ru.h | 6 +++--- intl/msg_hash_vn.h | 4 ++-- 17 files changed, 34 insertions(+), 34 deletions(-) diff --git a/intl/msg_hash_ar.h b/intl/msg_hash_ar.h index 37ec1977eb..e3dbf93ed5 100644 --- a/intl/msg_hash_ar.h +++ b/intl/msg_hash_ar.h @@ -2970,7 +2970,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Scan for new rooms.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Remove this entry from the collection.") + "Remove this entry from the playlist.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "View more information about the content.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, @@ -3046,7 +3046,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Perform tasks on a separate thread.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Allow the user to remove entries from collections.") + "Allow the user to remove entries from playlists.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Sets the System directory. Cores can query for this directory to load BIOSes, system-specific configs, etc.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index 6d1207d911..9d63e3e061 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -3279,7 +3279,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "在单独的线程上执行任务。") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "允许用户从收藏夹中删除游戏。") + "允许用户从播放列表中删除条目。") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "设置系统文件夹。固件和 BIOS 存放在这里。") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index 2d01248423..9d3d6ab058 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -2786,7 +2786,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Scan for new rooms.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Remove this entry from the collection.") + "Remove this entry from the playlist.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "View more information about the content.") MSG_HASH(MENU_ENUM_SUBLABEL_RUN, @@ -2858,7 +2858,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Perform tasks on a separate thread.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Allow the user to remove entries from collections.") + "Allow the user to remove entries from playlists.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Sets the System directory. Cores can query for this directory to load BIOSes, system-specific configs, etc.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 86b61cfa8f..3223a0a225 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -2894,7 +2894,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Suche nach neuen Räumen.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Entferne diesen Eintrag aus der Sammlung.") + "Entferne diesen Eintrag aus der Wiedergabeliste.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "Zeige weiterführende Informationen über diesen Inhalt an.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, @@ -2970,7 +2970,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Führe Aufgaben im Hintergrund aus.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Erlaube dem Benutzer, Einträge aus der Sammlung zu entfernen.") + "Erlaube dem Benutzer, Einträge aus Wiedergabelisten zu entfernen.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Lege das Systemverzeichnis fest. Cores können dieses Verzeichnis verwenden, um ein BIOS, system-spezifische Konfigurationen usw. zu laden.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_el.h b/intl/msg_hash_el.h index 0f9dc8fc03..14a2f4ff55 100644 --- a/intl/msg_hash_el.h +++ b/intl/msg_hash_el.h @@ -5331,7 +5331,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Κατάργηση αυτής της καταχώρησης από την συλλογή." + "Κατάργηση αυτής της καταχώρισης από λίστα αναπαραγωγής." ) MSG_HASH( MENU_ENUM_SUBLABEL_INFORMATION, @@ -5475,7 +5475,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Επιτρέψτε στον χρήστη να καταργεί τις καταχωρήσεις από την συλλογή." + "Επιτρέψτε στον χρήστη να καταργεί τις καταχωρήσεις από τις λίστες αναπαραγωγής." ) MSG_HASH( MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index c23584af9a..522b3dc853 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -2672,7 +2672,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Scan for new rooms.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Remove this entry from the collection.") + "Remove this entry from the playlist.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "View more information about the content.") MSG_HASH(MENU_ENUM_SUBLABEL_RUN, @@ -2744,7 +2744,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Perform tasks on a separate thread.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Allow the user to remove entries from collections.") + "Allow the user to remove entries from playlists.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Sets the System directory. Cores can query for this directory to load BIOSes, system-specific configs, etc.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index e788d60183..b6b1d49faf 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -5432,7 +5432,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Eliminar esta entrada de la colección" + "Eliminar esta entrada de la lista de reproducción" ) MSG_HASH( MENU_ENUM_SUBLABEL_INFORMATION, @@ -5576,7 +5576,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Permitir al usuario eliminar entradas de las colecciones" + "Permitir al usuario eliminar entradas de las listas de reprodução" ) MSG_HASH( MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index e17e5c49fd..0041e55603 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -2902,7 +2902,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Perform tasks on a separate thread.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Autoriser l'utilisateur à supprimer des entrées des collections") + "Autoriser l'utilisateur à supprimer des entrées des playlists") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Définir le répertoire système. Les cœur peuvent utiliser ce répertoire pour charger des BIOS, configurations, etc.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index fe58db0988..37566bf250 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -2866,7 +2866,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Scansiona nuove camere.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Rimuovi questo titolo dalla collezione") + "Rimuovi questo titolo dalla playlist") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "Visualizza ulteriori informazioni sul contenuto.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, @@ -2942,7 +2942,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Esegue le attività su un thread separato.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Consente all'utente di rimuovere le voci dalla collezione.") + "Consente all'utente di rimuovere le voci dalla playlists.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Imposta la directory di sistema. I core possono richiedere questa directory per caricare BIOS, configurazioni specifiche del sistema, ecc.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index 3e0f46fe63..d10884d72c 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -3036,7 +3036,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "新しいネットプレイルームをスキャンします。") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "このエントリーをコレクションから削除する。") + "このエントリーをプレイリストから削除する。") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "このコンテンツについての詳細を表示する。") MSG_HASH(MENU_ENUM_SUBLABEL_RUN, @@ -3108,7 +3108,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "タスクを別のスレッドで実行する。") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "ユーザーがコレクションからエントリーを削除できるようにする。") + "ユーザーがプレイリストからエントリーを削除できるようにする。") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "システムフォルダを指定します。コアはBIOSや特定システムの設定などをロードするため、このフォルダを探索することができます。") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, @@ -3337,7 +3337,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "設定タブを隠す際にあらかじめパスワードを設定しておくことで、そのパスワードを使用してメニューから設定タブを復元することができます。") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "コレクションのエントリーの名前変更をユーザーに許可する。") + "プレイリストのエントリーの名前変更をユーザーに許可する。") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "エントリーの名前変更を許可") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index d4e2c6f7a1..191aa8aee5 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -2784,7 +2784,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "새 호스트 검색.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "컬렉션에서 현재 항목 삭제.") + "재생목록에서 현재 항목 삭제.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "컨텐츠에 대한 자세한 정보 확인.") MSG_HASH(MENU_ENUM_SUBLABEL_RUN, @@ -2856,7 +2856,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "분할된 스레드에서 작업을 수행.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "사용자가 컬렉션에서 항목을 제거할 수 있게 허용.") + "사용자가 재생목록에서 항목을 제거할 수 있게 허용.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "시스템 디렉토리를 설정. 코어는 이 디렉토리에서 BIOS, 시스템 특정 구성 등을 불러들일 수 있습니다.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index 9a00f46fee..a65513d1f7 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -2675,7 +2675,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Scan for new rooms.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Remove this entry from the collection.") + "Remove this entry from the playlist.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "View more information about the content.") MSG_HASH(MENU_ENUM_SUBLABEL_RUN, @@ -2747,7 +2747,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Perform tasks on a separate thread.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Allow the user to remove entries from collections.") + "Allow the user to remove entries from playlists.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Sets the System directory. Cores can query for this directory to load BIOSes, system-specific configs, etc.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index 57e4296684..528c96ba94 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -3027,7 +3027,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Zeskanuj nowe pokoje.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Usuń ten wpis z kolekcji.") + "Usuń ten wpis z listy odtwarzania.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "Zobacz więcej informacji o zawartości.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, @@ -3103,7 +3103,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Wykonuj zadania w oddzielnym wątku.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Pozwól użytkownikowi usuwać wpisy ze zbiorów.") + "Pozwól użytkownikowi usuwać wpisy z list odtwarzania.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Ustawia katalog systemowy. Rdzenie mogą wysyłać zapytania do tego katalogu, aby załadować BIOS, konfiguracje specyficzne dla systemu itp.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index 38c00d5c1d..4bfde6b393 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -5576,7 +5576,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Remove esta entrada da coleção." + "Remove esta entrada da lista de reprodução." ) MSG_HASH( MENU_ENUM_SUBLABEL_INFORMATION, @@ -5720,7 +5720,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Permite que o usuário possa remover itens das coleções." + "Permite que o usuário possa remover itens das listas de reprodução." ) MSG_HASH( MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h index 39add92bc7..af96a3aaf4 100644 --- a/intl/msg_hash_pt_pt.h +++ b/intl/msg_hash_pt_pt.h @@ -2761,7 +2761,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Verificar por novas ROMs.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Remover esta entrada da coleção.") + "Remover esta entrada da lista de reprodução.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "Ver mais informações sobre o conteúdo.") MSG_HASH(MENU_ENUM_SUBLABEL_RUN, @@ -2833,7 +2833,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Executar tarefas numa thread independente.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Permitir que o utilizador remova entradas das coleções.") + "Permitir que o utilizador remova entradas das listas de reprodução.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Define a pasta de sistema. Os núcleos podem verificar esta pasta para o carregamento de ficheiros BIOS, configurações específicas de sistema, etc.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index f483278b9c..f061b4e85e 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -2485,7 +2485,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Выбрать файл") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, - "Выбрать из списка воспроизведения.") + "Выбрать из Плейлист.") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "Фильтр") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, @@ -2835,7 +2835,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Сканировать для поиска новых комнат.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Удалить эту запись из коллекции.") + "Удалить эту запись из Плейлист.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "Просмотреть больше информации о содержимом.") MSG_HASH(MENU_ENUM_SUBLABEL_RUN, @@ -2907,7 +2907,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Выполнять задачи в отдельном потоке.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Разрешить пользователю удалять отдельные записи из коллекции.") + "Разрешить пользователю удалять отдельные записи из Плейлисты.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Устанавливает каталог System. Ядра могут запрашивать его для загрузки BIOS, прошивок, системных настроек и т.д.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h index b70c09b1d0..d04de0354d 100644 --- a/intl/msg_hash_vn.h +++ b/intl/msg_hash_vn.h @@ -2834,7 +2834,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Scan for new rooms.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Remove this entry from the collection.") + "Remove this entry from the playlist.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "View more information about the content.") MSG_HASH(MENU_ENUM_SUBLABEL_RUN, @@ -2906,7 +2906,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Perform tasks on a separate thread.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Allow the user to remove entries from collections.") + "Allow the user to remove entries from playlists.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Sets the System directory. Cores can query for this directory to load BIOSes, system-specific configs, etc.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, From 04e87a00db163aadbc1247b6bd948ddd48c2d56b Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Fri, 22 Mar 2019 11:33:16 -0400 Subject: [PATCH 076/237] update PLAYLIST_DIRECTORY & PLAYLIST_ENTRY_RENAME --- intl/msg_hash_ar.h | 4 ++-- intl/msg_hash_chs.h | 4 ++-- intl/msg_hash_cht.h | 4 ++-- intl/msg_hash_de.h | 4 ++-- intl/msg_hash_el.h | 4 ++-- intl/msg_hash_eo.h | 4 ++-- intl/msg_hash_es.h | 4 ++-- intl/msg_hash_fr.h | 4 ++-- intl/msg_hash_it.h | 4 ++-- intl/msg_hash_ko.h | 4 ++-- intl/msg_hash_nl.h | 4 ++-- intl/msg_hash_pl.h | 4 ++-- intl/msg_hash_pt_br.h | 4 ++-- intl/msg_hash_pt_pt.h | 4 ++-- intl/msg_hash_ru.h | 4 ++-- intl/msg_hash_vn.h | 4 ++-- 16 files changed, 32 insertions(+), 32 deletions(-) diff --git a/intl/msg_hash_ar.h b/intl/msg_hash_ar.h index e3dbf93ed5..a3b539662f 100644 --- a/intl/msg_hash_ar.h +++ b/intl/msg_hash_ar.h @@ -3131,7 +3131,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "If a joypad is plugged in, that joypad will be autoconfigured if a config file corresponding to it is present inside this directory.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Save all collections to this directory.") + "Save all playlists to this directory.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "If set to a directory, content which is temporarily extracted (e.g. from archives) will be extracted to this directory." @@ -3315,7 +3315,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Supplying a password when hiding the settings tab makes it possible to later restore it from the menu, by going to the Main Menu tab, selecting Enable Settings Tab and entering the password.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Allow the user to rename entries in collections.") + "Allow the user to rename entries in playlists.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Allow to rename entries") MSG_HASH(MENU_ENUM_SUBLABEL_RENAME_ENTRY, diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index 9d63e3e061..def741c539 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -3373,7 +3373,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "如果插入的游戏手柄与该目录中的配置文件匹配,\n" "这个游戏手柄将自动完成配置。") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "保存游戏列表文件的文件夹。") + "保存播放列表文件的文件夹。") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "如果设置为目录,临时提取的内容(例如从档案中)\n" @@ -3582,7 +3582,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "启用方法:在主菜单中选择「启用设置页」\n" "并输入密码来重新启用设置页。") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "允许在集合中重命名条目。") + "允许重命名播放列表中的条目。") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "允许重命名条目") MSG_HASH( diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index 9d3d6ab058..ebe65858a7 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -2941,7 +2941,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "If a joypad is plugged in, that joypad will be autoconfigured if a config file corresponding to it is present inside this directory.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Save all collections to this directory.") + "Save all playlists to this directory.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "If set to a directory, content which is temporarily extracted (e.g. from archives) will be extracted to this directory." @@ -3119,7 +3119,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "請輸入隱藏 settings tab 的密碼。事後可在選項中取消") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Allow the user to rename entries in collections.") + "Allow the user to rename entries in playlists.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Allow to rename entries") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 3223a0a225..8a3e538c2d 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -3053,7 +3053,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "Wenn ein Controller eingesteckt wird, wird er automatisch konfiguriert, sofern eine passende Konfigurationsdatei in diesem Verzeichnis vorhanden ist.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Speichere alle Sammlungen in diesem Verzeichnis.") + "Speichere alle Wiedergabelisten in diesem Verzeichnis.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "Wenn ein Verzeichnis gewählt wird, wird Inhalt, der temporär entpackt wird (z.B. aus Archiven) in dieses Verzeichnis entpackt." @@ -3233,7 +3233,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Wird vor dem Verstecken der Einstellungen ein Passwort vergeben, wird es später möglich sein, den Reiter wiederherzustellen, in dem die Funktion 'Aktiviere den Reiter 'Einstellungen' ausgewählt und das Passwort dort eingegeben wird.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Erlaube dem Benutzer, Einträge in der Sammlung umzubenennen.") + "Erlaube dem Benutzer, Einträge in Wiedergabelisten umzubenennen.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Umbenennen von Einträgen erlauben") MSG_HASH(MENU_ENUM_LABEL_VALUE_RENAME_ENTRY, diff --git a/intl/msg_hash_el.h b/intl/msg_hash_el.h index 14a2f4ff55..317949e1ee 100644 --- a/intl/msg_hash_el.h +++ b/intl/msg_hash_el.h @@ -5644,7 +5644,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Save all collections to this directory." + "Save all playlists to this directory." ) MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, @@ -5968,7 +5968,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Επιτρέψτε στον χρήστη να μετονομάζει τις καταχωρήσεις στην συλλογή." + "Επιτρέψτε στον χρήστη να μετονομάζει τις καταχωρήσεις λίστας αναπαραγωγής" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index 522b3dc853..80656f084a 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -2829,7 +2829,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "If a joypad is plugged in, that joypad will be autoconfigured if a config file corresponding to it is present inside this directory.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Save all collections to this directory.") + "Save all playlists to this directory.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "If set to a directory, content which is temporarily extracted (e.g. from archives) will be extracted to this directory." @@ -3007,7 +3007,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Supplying a password when hiding the settings tab makes it possible to later restore it from the menu, by going to the Main Menu tab, selecting Enable Settings Tab and entering the password.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Allow the user to rename entries in collections.") + "Allow the user to rename entries in playlists.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Allow to rename entries") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index b6b1d49faf..a2591aff94 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -5745,7 +5745,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Guardar colecciones en esta carpeta" + "Guardar listas de reprodução en esta carpeta" ) MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, @@ -6069,7 +6069,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Permitir al usuario renombrar entradas en colecciones" + "Permitir al usuario renombrar entradas en listas de reprodução" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 0041e55603..6d16765bec 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -2985,7 +2985,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "If a joypad is plugged in, that joypad will be autoconfigured if a config file corresponding to it is present inside this directory.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Sauvegarder toutes les collections dans ce dossier.") + "Sauvegarder toutes les playlists dans ce dossier.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "If set to a directory, content which is temporarily extracted (e.g. from archives) will be extracted to this directory." @@ -3163,7 +3163,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Supplying a password when hiding the settings tab makes it possible to later restore it from the menu, by going to the Main Menu tab, selecting Enable Settings Tab and entering the password.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Autoriser l'utilisateur à renommer les entrées des collections.") + "Autoriser l'utilisateur à renommer les entrées des playlists.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Autoriser le renommage des entrées") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index 37566bf250..05f5750902 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -3027,7 +3027,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "Se un joypad viene collegato, verrà automaticamente configurato se all'interno di questa directory è presente un file di configurazione corrispondente.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Salva tutte le collezioni in questa directory.") + "Salva tutte le playlists in questa directory.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "Se non viene impostata una directory, il contenuto estratto temporaneamente (ad esempio dagli archivi) si troverà in questa directory." @@ -3211,7 +3211,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Fornisce una password quando si nasconde la colonna Impostazioni per poi ripristinarli dal menu, andando alla colonna Menù Principale, selezionando abilita la colonna Impostazioni e immettere la password") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Consente all'utente di rinominare le voci nelle collezioni.") + "Consente all'utente di rinominare le voci nelle playlists.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Permette di rinominare le voci") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index 191aa8aee5..49944b8b29 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -2937,7 +2937,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "조이패드가 연결되면 해당 디렉토리에 설정 파일이 있는 경우 자동으로 구성해줍니다.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "모든 컬렉션이 이 디렉토리에 저장됩니다.") + "모든 재생 목록은이 디렉토리에 저장됩니다.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "디렉토리를 설정하면 설정하면 임시로 압축해제된 컨첸츠가 이 디렉토리에 추출됩니다." @@ -3114,7 +3114,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "설정 탭을 숨길때 비밀번호를 설정해 나중에 되돌릴수 있게 끔 합니다. 메인 메뉴에서 '설정 탭 표시'를 선택 후 비밀번호를 입력해 되돌릴수 있습니다.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "콜렉션에 있는 엔트리들을 편집할 수 있게 허용합니다.") + "재생목록에 있는 엔트리들을 편집할 수 있게 허용합니다.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "엔트리 편집 허용") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index a65513d1f7..9ea4d01b43 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -2830,7 +2830,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "If a joypad is plugged in, that joypad will be autoconfigured if a config file corresponding to it is present inside this directory.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Save all collections to this directory.") + "Save all playlists to this directory.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "If set to a directory, content which is temporarily extracted (e.g. from archives) will be extracted to this directory." @@ -3008,7 +3008,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Supplying a password when hiding the settings tab makes it possible to later restore it from the menu, by going to the Main Menu tab, selecting Enable Settings Tab and entering the password.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Allow the user to rename entries in collections.") + "Allow the user to rename entries in playlists.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Allow to rename entries") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index 528c96ba94..5e8f909ed5 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -3188,7 +3188,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "Jeśli joypad jest podłączony, to zostanie automatycznie skonfigurowany, jeśli plik konfiguracyjny odpowiadający mu jest obecny w tym katalogu.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Zapisz wszystkie kolekcje w tym katalogu.") + "Zapisz wszystkie listy odtwarzania w tym katalogu.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "Jeśli ustawione na katalog, zawartość, która jest czasowo wyodrębniana (np. Z archiwów), zostanie wyodrębniona do tego katalogu." @@ -3374,7 +3374,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Podanie hasła podczas ukrywania karty ustawień pozwala później przywrócić ją z menu, przechodząc do karty Menu główne, wybierając opcję Włącz kartę Ustawienia i wprowadzając hasło.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Zezwalaj użytkownikowi na zmianę nazw wpisów w kolekcjach.") + "Zezwalaj użytkownikowi na zmianę nazw wpisów na listach odtwarzania.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Zezwalaj na zmianę nazw wpisów") MSG_HASH(MENU_ENUM_SUBLABEL_RENAME_ENTRY, diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index 4bfde6b393..2ba6bcda55 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -5889,7 +5889,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Salva todas as coleções neste diretório." + "Salva todas as listas de reprodução neste diretório." ) MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, @@ -6213,7 +6213,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Permite que o usuário renomeie os itens nas coleções." + "Permite que o usuário renomeie os itens nas listas de reprodução." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h index af96a3aaf4..0393fd6592 100644 --- a/intl/msg_hash_pt_pt.h +++ b/intl/msg_hash_pt_pt.h @@ -2912,7 +2912,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "Se um comando estiver conectado, o mesmo será configurado automaticamente se o ficheiro de configuração correspondente estiver presente nesta pasta.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Guardar todas as coleções nesta pasta.") + "Guardar todas as listas de reprodução nesta pasta.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "Se for definido, o conteúdo que for extraído, de forma temporária, será extraído para esta pasta." @@ -3088,7 +3088,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Fornecer uma palavra-passe durante a ocultação do separador das definições faz com que seja possível restaurá-lo mais tarde a partir do menu, através do separador Menu principal, selecionando o separador Ativar definições e introduzindo a palavra-passe.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Permitir que o utilizador renomeie entradas nas coleções.") + "Permitir que o utilizador renomeie entradas nas listas de reprodução.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Permitir renomeação de entradas") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index f061b4e85e..8b3d7ab7b5 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -2988,7 +2988,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "Если игровой джойстик подключен, то джойстик будет автомотически подстроен, если существует подходящий файл автоматической настройки.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Сохранять все коллекции в выбранной папке.") + "Сохранять все плейлисты в выбранной папке.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "Контент извлеченный из архивов будет временно размещен в этой папке." @@ -3162,7 +3162,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Применение пароля при скрытии вкладки Настройки может позже восстановить ее из меню. Для этого нужно перейти на вкладку Главное меню, выбрать Включить вкладку Настройки и ввести пароль.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Разрешить пользователю переименовывать записи в коллекции.") + "Разрешить пользователю переименовывать записи в плейлистах.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Разрешить переименовывать записи") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h index d04de0354d..1d9e6481d6 100644 --- a/intl/msg_hash_vn.h +++ b/intl/msg_hash_vn.h @@ -2989,7 +2989,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "If a joypad is plugged in, that joypad will be autoconfigured if a config file corresponding to it is present inside this directory.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Save all collections to this directory.") + "Save all playlists to this directory.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "If set to a directory, content which is temporarily extracted (e.g. from archives) will be extracted to this directory." @@ -3161,7 +3161,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Supplying a password when hiding the settings tab makes it possible to later restore it from the menu, by going to the Main Menu tab, selecting Enable Settings Tab and entering the password.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Allow the user to rename entries in collections.") + "Allow the user to rename entries in playlists.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Allow to rename entries") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, From b9b946465203df4f5a3e96d51f6a8e338d27f7ff Mon Sep 17 00:00:00 2001 From: barbudreadmon Date: Fri, 22 Mar 2019 17:04:17 +0100 Subject: [PATCH 077/237] Add glsym private Allows core developpers to add their own definitions when working with glsm. 2 things needed : - enable the `HAVE_GLSYM_PRIVATE` define - create a glsym_private.h with your logic You can find an example of usage at https://github.com/libretro/yabause/tree/yabasanshiro/yabause/src/libretro --- libretro-common/include/glsym/glsym.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libretro-common/include/glsym/glsym.h b/libretro-common/include/glsym/glsym.h index a64fe573fb..4e06a4a07a 100644 --- a/libretro-common/include/glsym/glsym.h +++ b/libretro-common/include/glsym/glsym.h @@ -38,4 +38,8 @@ #endif #endif +#ifdef HAVE_GLSYM_PRIVATE +#include "glsym_private.h" +#endif + #endif From e8dc6b8c3e518e2c5cd2f5aecf2bca49a201e9e1 Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Fri, 22 Mar 2019 12:07:39 -0400 Subject: [PATCH 078/237] german translation fixes per m4xw --- intl/msg_hash_de.c | 2 +- intl/msg_hash_de.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/intl/msg_hash_de.c b/intl/msg_hash_de.c index ec10701f9a..394e82ffd3 100644 --- a/intl/msg_hash_de.c +++ b/intl/msg_hash_de.c @@ -678,7 +678,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "wähle '%s' oder %s'.\n" "\n" "Die Dateien werden werden mit einer Datenbank abgeglichen.\n" - "Bei einem Treffer wird die Datei zu eine Wiedergabeliste\n" + "Bei einem Treffer wird die Datei zu einer Wiedergabeliste\n" "hinzugefügt.\n" "\n" "du kannst diese Inhalte einfach aufrufen, indem du\n" diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 8a3e538c2d..1a8d434689 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -2970,7 +2970,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Führe Aufgaben im Hintergrund aus.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Erlaube dem Benutzer, Einträge aus Wiedergabelisten zu entfernen.") + "Erlaube dem Benutzer, Einträge aus den Wiedergabelisten zu entfernen.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Lege das Systemverzeichnis fest. Cores können dieses Verzeichnis verwenden, um ein BIOS, system-spezifische Konfigurationen usw. zu laden.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, @@ -3233,7 +3233,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Wird vor dem Verstecken der Einstellungen ein Passwort vergeben, wird es später möglich sein, den Reiter wiederherzustellen, in dem die Funktion 'Aktiviere den Reiter 'Einstellungen' ausgewählt und das Passwort dort eingegeben wird.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Erlaube dem Benutzer, Einträge in Wiedergabelisten umzubenennen.") + "Erlaube dem Benutzer, Einträge in den Wiedergabelisten umzubenennen.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Umbenennen von Einträgen erlauben") MSG_HASH(MENU_ENUM_LABEL_VALUE_RENAME_ENTRY, From 28ef222886e075b072f120387c429feac6399df0 Mon Sep 17 00:00:00 2001 From: rsn8887 Date: Fri, 22 Mar 2019 19:30:43 -0500 Subject: [PATCH 079/237] [VITA] Bluetooth mouse and keyboard support --- Makefile.griffin | 2 +- Makefile.vita | 2 +- Makefile.vita.salamander | 2 +- input/drivers/psp_input.c | 270 +++++++++++++++++++++++++++++++++++++- input/input_keymaps.c | 141 ++++++++++++++++++++ input/input_keymaps.h | 3 + 6 files changed, 416 insertions(+), 4 deletions(-) diff --git a/Makefile.griffin b/Makefile.griffin index a5ab7229d9..945b9ad5e9 100644 --- a/Makefile.griffin +++ b/Makefile.griffin @@ -271,7 +271,7 @@ else ifeq ($(platform), vita) PLATCFLAGS := -mfloat-abi=hard -fsingle-precision-constant \ -mword-relocations -fno-unwind-tables -fno-asynchronous-unwind-tables -ftree-vectorize -fno-optimize-sibling-calls LIBS += -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub\ - -lSceSysmodule_stub -lSceCtrl_stub -lSceTouch_stub -lSceAudio_stub -lSceFiber_stub\ + -lSceSysmodule_stub -lSceCtrl_stub -lSceHid_stub -lSceTouch_stub -lSceAudio_stub -lSceFiber_stub\ -lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub \ -lSceMotion_stub -lSceAppMgr_stub -lpng -lm -lc diff --git a/Makefile.vita b/Makefile.vita index abc953ccec..ae79600c32 100644 --- a/Makefile.vita +++ b/Makefile.vita @@ -116,7 +116,7 @@ endif CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions VITA_LIBS := -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub \ - -lSceSysmodule_stub -lSceCtrl_stub -lSceTouch_stub -lSceAudio_stub \ + -lSceSysmodule_stub -lSceCtrl_stub -lSceHid_stub -lSceTouch_stub -lSceAudio_stub \ -lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub \ -lSceFiber_stub -lSceMotion_stub -lSceAppMgr_stub -lpthread -lpng -lz diff --git a/Makefile.vita.salamander b/Makefile.vita.salamander index 20160de36e..f479726e6d 100644 --- a/Makefile.vita.salamander +++ b/Makefile.vita.salamander @@ -22,7 +22,7 @@ RARCH_DEFINES = -DVITA -DIS_SALAMANDER -DRARCH_CONSOLE LIBDIR = LDFLAGS = LIBS = -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub\ - -lSceSysmodule_stub -lSceCtrl_stub -lSceAudio_stub -lSceFiber_stub\ + -lSceSysmodule_stub -lSceCtrl_stub -lSceHid_stub -lSceAudio_stub -lSceFiber_stub\ -lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub \ -lSceMotion_stub -lSceAppMgr_stub -lfreetype -lpng -lm -lc diff --git a/input/drivers/psp_input.c b/input/drivers/psp_input.c index 6ee849ec17..0116718805 100644 --- a/input/drivers/psp_input.c +++ b/input/drivers/psp_input.c @@ -27,6 +27,13 @@ #include #elif defined(VITA) #include +#include +#include +#define VITA_NUM_SCANCODES 115 /* size of rarch_key_map_vita */ +#define VITA_MAX_SCANCODE 0xE7 +#define VITA_NUM_MODIFIERS 11 /* number of modifiers reported */ +#define MOUSE_MAX_X 960 +#define MOUSE_MAX_Y 544 #elif defined(PSP) #include #endif @@ -42,6 +49,23 @@ #include "../../defines/psp_defines.h" #include "../input_driver.h" +#ifdef VITA +#include "../input_keymaps.h" +uint8_t modifier_lut[VITA_NUM_MODIFIERS][2] = +{ + { 0xE0, 0x01 }, /* LCTRL */ + { 0xE4, 0x10 }, /* RCTRL */ + { 0xE1, 0x02 }, /* LSHIFT */ + { 0xE5, 0x20 }, /* RSHIFT */ + { 0xE2, 0x04 }, /* LALT */ + { 0xE6, 0x40 }, /* RALT */ + { 0xE3, 0x08 }, /* LGUI */ + { 0xE7, 0x80 }, /* RGUI */ + { 0x53, 0x01 }, /* NUMLOCK */ + { 0x39, 0x02 }, /* CAPSLOCK */ + { 0x47, 0x04 } /* SCROLLOCK */ +}; +#endif /* TODO/FIXME - * fix game focus toggle */ @@ -50,6 +74,20 @@ typedef struct psp_input { bool blocked; const input_device_driver_t *joypad; +#ifdef VITA + int keyboard_hid_handle; + uint8_t prev_keys[6]; + bool keyboard_state[VITA_MAX_SCANCODE + 1]; + + int mouse_hid_handle; + int32_t mouse_x; + int32_t mouse_y; + int32_t mouse_x_delta; + int32_t mouse_y_delta; + bool mouse_button_left; + bool mouse_button_right; + bool mouse_button_middle; +#endif } psp_input_t; static void psp_input_poll(void *data) @@ -58,8 +96,206 @@ static void psp_input_poll(void *data) if (psp && psp->joypad) psp->joypad->poll(); + +#ifdef VITA + unsigned int i = 0; + int key_sym = 0; + unsigned key_code = 0; + uint8_t mod_code = 0; + uint16_t mod = 0; + uint8_t modifiers[2] = { 0, 0 }; + bool key_held = false; + int numReports = 0; + int mouse_velocity_x = 0; + int mouse_velocity_y = 0; + SceHidKeyboardReport k_reports[SCE_HID_MAX_REPORT]; + SceHidMouseReport m_reports[SCE_HID_MAX_REPORT]; + + if (psp->keyboard_hid_handle > 0) + { + numReports = sceHidKeyboardRead(psp->keyboard_hid_handle, (SceHidKeyboardReport**)&k_reports, SCE_HID_MAX_REPORT); + + if (numReports < 0) { + psp->keyboard_hid_handle = 0; + } + else if (numReports) { + modifiers[0] = k_reports[numReports - 1].modifiers[0]; + modifiers[1] = k_reports[numReports - 1].modifiers[1]; + mod = 0; + if (modifiers[0] & 0x11) + mod |= RETROKMOD_CTRL; + if (modifiers[0] & 0x22) + mod |= RETROKMOD_SHIFT; + if (modifiers[0] & 0x44) + mod |= RETROKMOD_ALT; + if (modifiers[0] & 0x88) + mod |= RETROKMOD_META; + if (modifiers[1] & 0x01) + mod |= RETROKMOD_NUMLOCK; + if (modifiers[1] & 0x02) + mod |= RETROKMOD_CAPSLOCK; + if (modifiers[1] & 0x04) + mod |= RETROKMOD_SCROLLOCK; + + for (i = 0; i < VITA_NUM_MODIFIERS; i++) + { + key_sym = (int) modifier_lut[i][0]; + mod_code = modifier_lut[i][1]; + key_code = input_keymaps_translate_keysym_to_rk(key_sym); + if (i < 8) + { + key_held = (modifiers[0] & mod_code); + } + else + { + key_held = (modifiers[1] & mod_code); + } + + if (key_held && !(psp->keyboard_state[key_sym])) + { + psp->keyboard_state[key_sym] = true; + input_keyboard_event(true, key_code, 0, mod, RETRO_DEVICE_KEYBOARD); + } + else if (!key_held && (psp->keyboard_state[key_sym])) + { + psp->keyboard_state[key_sym] = false; + input_keyboard_event(false, key_code, 0, mod, RETRO_DEVICE_KEYBOARD); + } + } + + for (i = 0; i < 6; i++) + { + key_sym = k_reports[numReports - 1].keycodes[i]; + + if (key_sym != psp->prev_keys[i]) + { + if (psp->prev_keys[i]) + { + psp->keyboard_state[psp->prev_keys[i]] = false; + key_code = input_keymaps_translate_keysym_to_rk(psp->prev_keys[i]); + input_keyboard_event(false, key_code, 0, mod, RETRO_DEVICE_KEYBOARD); + } + if (key_sym) + { + psp->keyboard_state[key_sym] = true; + key_code = input_keymaps_translate_keysym_to_rk(key_sym); + input_keyboard_event(true, key_code, 0, mod, RETRO_DEVICE_KEYBOARD); + } + psp->prev_keys[i] = key_sym; + } + } + } + } + + if (psp->mouse_hid_handle > 0) + { + numReports = sceHidMouseRead(psp->mouse_hid_handle, (SceHidMouseReport**)&m_reports, SCE_HID_MAX_REPORT); + if (numReports > 0) + { + for (i = 0; i <= numReports - 1; i++) + { + uint8_t buttons = m_reports[i].buttons; + + if (buttons & 0x1) + { + psp->mouse_button_left = true; + } + else + { + psp->mouse_button_left = false; + } + + if (buttons & 0x2) + { + psp->mouse_button_right = true; + } + else + { + psp->mouse_button_right = false; + } + + if (buttons & 0x4) + { + psp->mouse_button_middle = true; + } + else + { + psp->mouse_button_middle = false; + } + + mouse_velocity_x += m_reports[i].rel_x; + mouse_velocity_y += m_reports[i].rel_y; + } + } + } + psp->mouse_x_delta = mouse_velocity_x; + psp->mouse_y_delta = mouse_velocity_y; + psp->mouse_x += mouse_velocity_x; + psp->mouse_y += mouse_velocity_y; + if (psp->mouse_x < 0) + { + psp->mouse_x = 0; + } + else if (psp->mouse_x > MOUSE_MAX_X) + { + psp->mouse_x = MOUSE_MAX_X; + } + + if (psp->mouse_y < 0) + { + psp->mouse_y = 0; + } + else if (psp->mouse_y > MOUSE_MAX_Y) + { + psp->mouse_y = MOUSE_MAX_Y; + } +#endif } +#ifdef VITA +static int16_t psp_input_mouse_state(psp_input_t *psp, unsigned id, bool screen) +{ + int val = 0; + switch (id) + { + case RETRO_DEVICE_ID_MOUSE_LEFT: + val = psp->mouse_button_left; + break; + case RETRO_DEVICE_ID_MOUSE_RIGHT: + val = psp->mouse_button_right; + break; + case RETRO_DEVICE_ID_MOUSE_MIDDLE: + val = psp->mouse_button_middle; + break; + case RETRO_DEVICE_ID_MOUSE_X: + if (screen) + { + val = psp->mouse_x; + } + else + { + val = psp->mouse_x_delta; + psp->mouse_x_delta = 0; /* flush delta after it has been read */ + } + break; + case RETRO_DEVICE_ID_MOUSE_Y: + if (screen) + { + val = psp->mouse_y; + } + else + { + val = psp->mouse_y_delta; + psp->mouse_y_delta = 0; /* flush delta after it has been read */ + } + break; + } + + return val; +} +#endif + + static int16_t psp_input_state(void *data, rarch_joypad_info_t joypad_info, const struct retro_keybind **binds, @@ -81,6 +317,17 @@ static int16_t psp_input_state(void *data, if (binds[port]) return input_joypad_analog(psp->joypad, joypad_info, port, idx, id, binds[port]); break; +#ifdef VITA + case RETRO_DEVICE_KEYBOARD: + return ((id < RETROK_LAST) && psp->keyboard_state[rarch_keysym_lut[(enum retro_key)id]]); + break; + case RETRO_DEVICE_MOUSE: + return psp_input_mouse_state(psp, id, false); + break; + case RARCH_DEVICE_MOUSE_SCREEN: + return psp_input_mouse_state(psp, id, true); + break; +#endif } return 0; @@ -104,6 +351,21 @@ static void* psp_input_initialize(const char *joypad_driver) psp->joypad = input_joypad_init_driver(joypad_driver, psp); +#ifdef VITA + sceHidKeyboardEnumerate(&(psp->keyboard_hid_handle), 1); + sceHidMouseEnumerate(&(psp->mouse_hid_handle), 1); + + input_keymaps_init_keyboard_lut(rarch_key_map_vita); + unsigned int i; + for (i = 0; i <= VITA_MAX_SCANCODE; i++) { + psp->keyboard_state[i] = false; + } + for (i = 0; i < 6; i++) { + psp->prev_keys[i] = 0; + } + psp->mouse_x = 0; + psp->mouse_y = 0; +#endif return psp; } @@ -111,7 +373,13 @@ static uint64_t psp_input_get_capabilities(void *data) { (void)data; - return (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG); + uint64_t caps = (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG); + +#ifdef VITA + caps |= (1 << RETRO_DEVICE_KEYBOARD) | (1 << RETRO_DEVICE_MOUSE); +#endif + + return caps; } static const input_device_driver_t *psp_input_get_joypad_driver(void *data) diff --git a/input/input_keymaps.c b/input/input_keymaps.c index a92bf60256..b0ec268640 100644 --- a/input/input_keymaps.c +++ b/input/input_keymaps.c @@ -411,6 +411,147 @@ const struct rarch_key_map rarch_key_map_switch[] = { }; #endif +#ifdef VITA +// Vita scancodes are identical to USB 2.0 standard, e.g. SDL2 +const struct rarch_key_map rarch_key_map_vita[] = { + { 0x02A, RETROK_BACKSPACE }, + { 0x02B, RETROK_TAB }, + { 0x09C, RETROK_CLEAR }, + { 0x028, RETROK_RETURN }, + { 0x048, RETROK_PAUSE }, + { 0x029, RETROK_ESCAPE }, + { 0x02C, RETROK_SPACE }, + /*{ ?, RETROK_EXCLAIM },*/ + /*{ ?, RETROK_QUOTEDBL },*/ + /*{ ?, RETROK_HASH },*/ + /*{ ?, RETROK_DOLLAR },*/ + /*{ ?, RETROK_AMPERSAND },*/ + { 0x034, RETROK_QUOTE }, + /*{ ?, RETROK_LEFTPAREN },*/ + /*{ ?, RETROK_RIGHTPAREN },*/ + /*{ ?, RETROK_ASTERISK },*/ + /*{ ?, RETROK_PLUS },*/ + { 0x036, RETROK_COMMA }, + { 0x02D, RETROK_MINUS }, + { 0x037, RETROK_PERIOD }, + { 0x038, RETROK_SLASH }, + { 0x027, RETROK_0 }, + { 0x01E, RETROK_1 }, + { 0x01F, RETROK_2 }, + { 0x020, RETROK_3 }, + { 0x021, RETROK_4 }, + { 0x022, RETROK_5 }, + { 0x023, RETROK_6 }, + { 0x024, RETROK_7 }, + { 0x025, RETROK_8 }, + { 0x026, RETROK_9 }, + /*{ ?, RETROK_COLON },*/ + { 0x033, RETROK_SEMICOLON }, + /*{ ?, RETROK_OEM_102 },*/ + { 0x02E, RETROK_EQUALS }, + /*{ ?, RETROK_GREATER },*/ + /*{ ?, RETROK_QUESTION },*/ + /*{ ?, RETROK_AT },*/ + { 0x02F, RETROK_LEFTBRACKET }, + { 0x031, RETROK_BACKSLASH }, + { 0x030, RETROK_RIGHTBRACKET }, + /*{ ?, RETROK_CARET },*/ + /*{ ?, RETROK_UNDERSCORE },*/ + { 0x035, RETROK_BACKQUOTE }, + { 0x004, RETROK_a }, + { 0x005, RETROK_b }, + { 0x006, RETROK_c }, + { 0x007, RETROK_d }, + { 0x008, RETROK_e }, + { 0x009, RETROK_f }, + { 0x00A, RETROK_g }, + { 0x00B, RETROK_h }, + { 0x00C, RETROK_i }, + { 0x00D, RETROK_j }, + { 0x00E, RETROK_k }, + { 0x00F, RETROK_l }, + { 0x010, RETROK_m }, + { 0x011, RETROK_n }, + { 0x012, RETROK_o }, + { 0x013, RETROK_p }, + { 0x014, RETROK_q }, + { 0x015, RETROK_r }, + { 0x016, RETROK_s }, + { 0x017, RETROK_t }, + { 0x018, RETROK_u }, + { 0x019, RETROK_v }, + { 0x01A, RETROK_w }, + { 0x01B, RETROK_x }, + { 0x01C, RETROK_y }, + { 0x01D, RETROK_z }, + { 0x04C, RETROK_DELETE }, + { 0x062, RETROK_KP0 }, + { 0x059, RETROK_KP1 }, + { 0x05A, RETROK_KP2 }, + { 0x05B, RETROK_KP3 }, + { 0x05C, RETROK_KP4 }, + { 0x05D, RETROK_KP5 }, + { 0x05E, RETROK_KP6 }, + { 0x05F, RETROK_KP7 }, + { 0x060, RETROK_KP8 }, + { 0x061, RETROK_KP9 }, + { 0x063, RETROK_KP_PERIOD }, + { 0x054, RETROK_KP_DIVIDE }, + { 0x055, RETROK_KP_MULTIPLY }, + { 0x056, RETROK_KP_MINUS }, + { 0x057, RETROK_KP_PLUS }, + { 0x058, RETROK_KP_ENTER }, + { 0x067, RETROK_KP_EQUALS }, + { 0x052, RETROK_UP }, + { 0x051, RETROK_DOWN }, + { 0x04F, RETROK_RIGHT }, + { 0x050, RETROK_LEFT }, + { 0x049, RETROK_INSERT }, + { 0x04A, RETROK_HOME }, + { 0x04D, RETROK_END }, + { 0x04B, RETROK_PAGEUP }, + { 0x04E, RETROK_PAGEDOWN }, + { 0x03A, RETROK_F1 }, + { 0x03B, RETROK_F2 }, + { 0x03C, RETROK_F3 }, + { 0x03D, RETROK_F4 }, + { 0x03E, RETROK_F5 }, + { 0x03F, RETROK_F6 }, + { 0x040, RETROK_F7 }, + { 0x041, RETROK_F8 }, + { 0x042, RETROK_F9 }, + { 0x043, RETROK_F10 }, + { 0x044, RETROK_F11 }, + { 0x045, RETROK_F12 }, + { 0x068, RETROK_F13 }, + { 0x069, RETROK_F14 }, + { 0x06A, RETROK_F15 }, + { 0x053, RETROK_NUMLOCK }, + { 0x039, RETROK_CAPSLOCK }, + { 0x047, RETROK_SCROLLOCK }, + { 0x0E5, RETROK_RSHIFT }, + { 0x0E1, RETROK_LSHIFT }, + { 0x0E4, RETROK_RCTRL }, + { 0x0E0, RETROK_LCTRL }, + { 0x0E6, RETROK_RALT }, + { 0x0E2, RETROK_LALT }, + /* { ?, RETROK_RMETA }, */ + /* { ?, RETROK_LMETA }, */ + { 0x0E3, RETROK_LSUPER }, + { 0x0E7, RETROK_RSUPER }, + /* { ?, RETROK_MODE },*/ + { 0x075, RETROK_HELP }, + { 0x046, RETROK_PRINT }, + { 0x09A, RETROK_SYSREQ }, + { 0x048, RETROK_BREAK }, + { 0x076, RETROK_MENU }, + { 0x066, RETROK_POWER }, + /*{ ?, RETROK_EURO },*/ + { 0x07A, RETROK_UNDO }, + { 0, RETROK_UNKNOWN }, +}; +#endif + #if defined(HAVE_SDL) || defined(HAVE_SDL2) const struct rarch_key_map rarch_key_map_sdl[] = { { SDLK_BACKSPACE, RETROK_BACKSPACE }, diff --git a/input/input_keymaps.h b/input/input_keymaps.h index 69fe66d6fc..fa8394ef00 100644 --- a/input/input_keymaps.h +++ b/input/input_keymaps.h @@ -68,6 +68,9 @@ extern const struct rarch_key_map rarch_key_map_winraw[]; #ifdef HAVE_LIBNX extern const struct rarch_key_map rarch_key_map_switch[]; #endif +#ifdef VITA +extern const struct rarch_key_map rarch_key_map_vita[]; +#endif /** * input_keymaps_init_keyboard_lut: From 6abaded3735b67ed41e61668d193040971fb8b4b Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Sat, 23 Mar 2019 12:34:37 -0400 Subject: [PATCH 080/237] spanish fixes per alfrix --- intl/msg_hash_es.h | 6 +++--- retroarch.cfg | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index a2591aff94..e7e231c506 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -5576,7 +5576,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Permitir al usuario eliminar entradas de las listas de reprodução" + "Permitir al usuario eliminar entradas de las listas de reproducción" ) MSG_HASH( MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, @@ -5745,7 +5745,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Guardar listas de reprodução en esta carpeta" + "Guardar listas de reproducción en esta carpeta" ) MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, @@ -6069,7 +6069,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Permitir al usuario renombrar entradas en listas de reprodução" + "Permitir al usuario renombrar entradas en listas de reproducción" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, diff --git a/retroarch.cfg b/retroarch.cfg index bf0319399d..a996f1c8bd 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -908,4 +908,4 @@ # vibrate_on_keypress = false # Enable device vibration for supported cores -# enable_device_vibration = false \ No newline at end of file +# enable_device_vibration = false From 5ba97fbcb28495910a00715889e5641243a4b70a Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Sat, 23 Mar 2019 12:44:37 -0400 Subject: [PATCH 081/237] use more natural Playlist term in German --- intl/msg_hash_de.c | 6 +++--- intl/msg_hash_de.h | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/intl/msg_hash_de.c b/intl/msg_hash_de.c index 394e82ffd3..4d1801468e 100644 --- a/intl/msg_hash_de.c +++ b/intl/msg_hash_de.c @@ -339,9 +339,9 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_PLAYLIST_DIRECTORY: snprintf(s, len, - "Wiedergabelisten-Verzeichnis. \n" + "Playlists-Verzeichnis. \n" " \n" - "Speichere alle Wiedergabelisten in diesem \n" + "Speichere alle Playlists in diesem \n" "Verzeichnis."); break; case MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN: @@ -678,7 +678,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "wähle '%s' oder %s'.\n" "\n" "Die Dateien werden werden mit einer Datenbank abgeglichen.\n" - "Bei einem Treffer wird die Datei zu einer Wiedergabeliste\n" + "Bei einem Treffer wird die Datei zu einer Playlist\n" "hinzugefügt.\n" "\n" "du kannst diese Inhalte einfach aufrufen, indem du\n" diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 1a8d434689..4114373ef4 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -1136,9 +1136,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, "Keine Leistungszähler.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, - "Keine Wiedergabelisten.") + "Keine Playlists.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLIST_ENTRIES_AVAILABLE, - "Keine Wiedergabelisten-Einträge verfügbar.") + "Keine Playlist-Einträge verfügbar.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, "Keine Einstellungen gefunden.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, @@ -1186,11 +1186,11 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, "Leistungsindikatoren") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, - "Wiedergabelisten") + "Playlists") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Wiedergabelisten") + "Playlists") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, - "Wiedergabelisten") + "Playlists") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, "Touch-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, @@ -1887,7 +1887,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, "Ändere die Standard-Verzeichnisse für dieses System") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, - "Ändere die Einstellungen für die Wiedergabelisten.") + "Ändere die Einstellungen für die Playlists.") MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, "Ändere die Einstellungen für das Netzwerk.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, @@ -2524,7 +2524,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, "Aktiviere oder deaktiviere Desktop-Gestaltung (nur Windows).") MSG_HASH(MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, - "Aktiviere Wiedergabeliste für kürzlich geöffnete Inhalte.") + "Aktiviere Playlist für kürzlich geöffnete Inhalte.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, "Begrenzt die Anzahl der Einträge in der Verlaufsliste.") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_UNIFIED_MENU_CONTROLS, @@ -2540,7 +2540,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Wähle Datei") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, - "Wähle aus Wiedergabeliste") + "Wähle aus Playlist") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "Filter") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, @@ -2894,7 +2894,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Suche nach neuen Räumen.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Entferne diesen Eintrag aus der Wiedergabeliste.") + "Entferne diesen Eintrag aus der Playlist.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "Zeige weiterführende Informationen über diesen Inhalt an.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, @@ -2970,7 +2970,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Führe Aufgaben im Hintergrund aus.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Erlaube dem Benutzer, Einträge aus den Wiedergabelisten zu entfernen.") + "Erlaube dem Benutzer, Einträge aus den Playlists zu entfernen.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Lege das Systemverzeichnis fest. Cores können dieses Verzeichnis verwenden, um ein BIOS, system-spezifische Konfigurationen usw. zu laden.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, @@ -3053,7 +3053,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "Wenn ein Controller eingesteckt wird, wird er automatisch konfiguriert, sofern eine passende Konfigurationsdatei in diesem Verzeichnis vorhanden ist.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Speichere alle Wiedergabelisten in diesem Verzeichnis.") + "Speichere alle Playlists in diesem Verzeichnis.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "Wenn ein Verzeichnis gewählt wird, wird Inhalt, der temporär entpackt wird (z.B. aus Archiven) in dieses Verzeichnis entpackt." @@ -3233,7 +3233,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Wird vor dem Verstecken der Einstellungen ein Passwort vergeben, wird es später möglich sein, den Reiter wiederherzustellen, in dem die Funktion 'Aktiviere den Reiter 'Einstellungen' ausgewählt und das Passwort dort eingegeben wird.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Erlaube dem Benutzer, Einträge in den Wiedergabelisten umzubenennen.") + "Erlaube dem Benutzer, Einträge in den Playlists umzubenennen.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Umbenennen von Einträgen erlauben") MSG_HASH(MENU_ENUM_LABEL_VALUE_RENAME_ENTRY, From 11e4b0b6ef02d78ba520c75c5d87d28d0cb4264a Mon Sep 17 00:00:00 2001 From: stellarporter <48503008+stellarporter@users.noreply.github.com> Date: Sat, 23 Mar 2019 20:22:21 -0500 Subject: [PATCH 082/237] gfx video filters: blargg ntsc snes conflicts emscipten: avoid global symbol multiply defined error (core compiling its own snes_ntsc.c library) --- gfx/video_filters/blargg_ntsc_snes.c | 16 ++++++++-------- gfx/video_filters/snes_ntsc/snes_ntsc.c | 18 +++++++++--------- gfx/video_filters/snes_ntsc/snes_ntsc.h | 14 +++++++------- gfx/video_filters/snes_ntsc/snes_ntsc_impl.h | 4 ++-- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/gfx/video_filters/blargg_ntsc_snes.c b/gfx/video_filters/blargg_ntsc_snes.c index 131ea3161d..a75a7986da 100644 --- a/gfx/video_filters/blargg_ntsc_snes.c +++ b/gfx/video_filters/blargg_ntsc_snes.c @@ -84,35 +84,35 @@ static void blargg_ntsc_snes_initialize(void *data, { if (memcmp(tvtype, "composite", 9) == 0) { - setup = snes_ntsc_composite; + setup = retroarch_snes_ntsc_composite; setup.merge_fields = 1; } else if (memcmp(tvtype, "rf", 2) == 0) { - setup = snes_ntsc_composite; + setup = retroarch_snes_ntsc_composite; setup.merge_fields = 0; } else if (memcmp(tvtype, "rgb", 3) == 0) { - setup = snes_ntsc_rgb; + setup = retroarch_snes_ntsc_rgb; setup.merge_fields = 1; } else if (memcmp(tvtype, "svideo", 6) == 0) { - setup = snes_ntsc_svideo; + setup = retroarch_snes_ntsc_svideo; setup.merge_fields = 1; } } else { - setup = snes_ntsc_composite; + setup = retroarch_snes_ntsc_composite; setup.merge_fields = 1; } config->free(tvtype); tvtype = NULL; - snes_ntsc_init(filt->ntsc, &setup); + retroarch_snes_ntsc_init(filt->ntsc, &setup); filt->burst = 0; filt->burst_toggle = (setup.merge_fields ? 0 : 1); @@ -170,10 +170,10 @@ static void blargg_ntsc_snes_render_rgb565(void *data, int width, int height, { struct filter_data *filt = (struct filter_data*)data; if(width <= 256) - snes_ntsc_blit(filt->ntsc, input, pitch, filt->burst, + retroarch_snes_ntsc_blit(filt->ntsc, input, pitch, filt->burst, width, height, output, outpitch * 2, first, last); else - snes_ntsc_blit_hires(filt->ntsc, input, pitch, filt->burst, + retroarch_snes_ntsc_blit_hires(filt->ntsc, input, pitch, filt->burst, width, height, output, outpitch * 2, first, last); filt->burst ^= filt->burst_toggle; diff --git a/gfx/video_filters/snes_ntsc/snes_ntsc.c b/gfx/video_filters/snes_ntsc/snes_ntsc.c index bb33031389..97cbc7d6d9 100644 --- a/gfx/video_filters/snes_ntsc/snes_ntsc.c +++ b/gfx/video_filters/snes_ntsc/snes_ntsc.c @@ -15,10 +15,10 @@ details. You should have received a copy of the GNU Lesser General Public License along with this module; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -snes_ntsc_setup_t const snes_ntsc_monochrome = { 0,-1, 0, 0,.2, 0,.2,-.2,-.2,-1, 1, 0, 0 }; -snes_ntsc_setup_t const snes_ntsc_composite = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }; -snes_ntsc_setup_t const snes_ntsc_svideo = { 0, 0, 0, 0,.2, 0,.2, -1, -1, 0, 1, 0, 0 }; -snes_ntsc_setup_t const snes_ntsc_rgb = { 0, 0, 0, 0,.2, 0,.7, -1, -1,-1, 1, 0, 0 }; +snes_ntsc_setup_t const retroarch_snes_ntsc_monochrome = { 0,-1, 0, 0,.2, 0,.2,-.2,-.2,-1, 1, 0, 0 }; +snes_ntsc_setup_t const retroarch_snes_ntsc_composite = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }; +snes_ntsc_setup_t const retroarch_snes_ntsc_svideo = { 0, 0, 0, 0,.2, 0,.2, -1, -1, 0, 1, 0, 0 }; +snes_ntsc_setup_t const retroarch_snes_ntsc_rgb = { 0, 0, 0, 0,.2, 0,.7, -1, -1,-1, 1, 0, 0 }; #define alignment_count 3 #define burst_count 3 @@ -35,7 +35,7 @@ snes_ntsc_setup_t const snes_ntsc_rgb = { 0, 0, 0, 0,.2, 0,.7, -1, -1,-1 #include "snes_ntsc_impl.h" /* 3 input pixels -> 8 composite samples */ -pixel_info_t const snes_ntsc_pixels [alignment_count] = { +pixel_info_t const retroarch_snes_ntsc_pixels [alignment_count] = { { PIXEL_OFFSET( -4, -9 ), { 1, 1, .6667f, 0 } }, { PIXEL_OFFSET( -2, -7 ), { .3333f, 1, 1, .3333f } }, { PIXEL_OFFSET( 0, -5 ), { 0, .6667f, 1, 1 } }, @@ -77,13 +77,13 @@ static void correct_errors( snes_ntsc_rgb_t color, snes_ntsc_rgb_t* out ) } } -void snes_ntsc_init( snes_ntsc_t* ntsc, snes_ntsc_setup_t const* setup ) +void retroarch_snes_ntsc_init( snes_ntsc_t* ntsc, snes_ntsc_setup_t const* setup ) { int merge_fields; int entry; init_t impl; if ( !setup ) - setup = &snes_ntsc_composite; + setup = &retroarch_snes_ntsc_composite; init( &impl, setup ); merge_fields = setup->merge_fields; @@ -118,7 +118,7 @@ void snes_ntsc_init( snes_ntsc_t* ntsc, snes_ntsc_setup_t const* setup ) #ifndef SNES_NTSC_NO_BLITTERS -void snes_ntsc_blit( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, long in_row_width, +void retroarch_snes_ntsc_blit( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, long in_row_width, int burst_phase, int in_width, int in_height, void* rgb_out, long out_pitch, int first, int last ) { int chunk_count = (in_width - 1) / snes_ntsc_in_chunk; @@ -171,7 +171,7 @@ void snes_ntsc_blit( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, long } } -void snes_ntsc_blit_hires( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, long in_row_width, +void retroarch_snes_ntsc_blit_hires( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, long in_row_width, int burst_phase, int in_width, int in_height, void* rgb_out, long out_pitch, int first, int last ) { int chunk_count = (in_width - 2) / (snes_ntsc_in_chunk * 2); diff --git a/gfx/video_filters/snes_ntsc/snes_ntsc.h b/gfx/video_filters/snes_ntsc/snes_ntsc.h index a8e728a237..df8d1c4c5d 100644 --- a/gfx/video_filters/snes_ntsc/snes_ntsc.h +++ b/gfx/video_filters/snes_ntsc/snes_ntsc.h @@ -34,25 +34,25 @@ typedef struct snes_ntsc_setup_t } snes_ntsc_setup_t; /* Video format presets */ -extern snes_ntsc_setup_t const snes_ntsc_composite; /* color bleeding + artifacts */ -extern snes_ntsc_setup_t const snes_ntsc_svideo; /* color bleeding only */ -extern snes_ntsc_setup_t const snes_ntsc_rgb; /* crisp image */ -extern snes_ntsc_setup_t const snes_ntsc_monochrome;/* desaturated + artifacts */ +extern snes_ntsc_setup_t const retroarch_snes_ntsc_composite; /* color bleeding + artifacts */ +extern snes_ntsc_setup_t const retroarch_snes_ntsc_svideo; /* color bleeding only */ +extern snes_ntsc_setup_t const retroarch_snes_ntsc_rgb; /* crisp image */ +extern snes_ntsc_setup_t const retroarch_snes_ntsc_monochrome;/* desaturated + artifacts */ /* Initializes and adjusts parameters. Can be called multiple times on the same snes_ntsc_t object. Can pass NULL for either parameter. */ typedef struct snes_ntsc_t snes_ntsc_t; -void snes_ntsc_init( snes_ntsc_t* ntsc, snes_ntsc_setup_t const* setup ); +void retroarch_snes_ntsc_init( snes_ntsc_t* ntsc, snes_ntsc_setup_t const* setup ); /* Filters one or more rows of pixels. Input pixel format is set by SNES_NTSC_IN_FORMAT and output RGB depth is set by SNES_NTSC_OUT_DEPTH. Both default to 16-bit RGB. In_row_width is the number of pixels to get to the next input row. Out_pitch is the number of *bytes* to get to the next output row. */ -void snes_ntsc_blit( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, +void retroarch_snes_ntsc_blit( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, long in_row_width, int burst_phase, int in_width, int in_height, void* rgb_out, long out_pitch, int first, int last); -void snes_ntsc_blit_hires( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, +void retroarch_snes_ntsc_blit_hires( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, long in_row_width, int burst_phase, int in_width, int in_height, void* rgb_out, long out_pitch, int first, int last); diff --git a/gfx/video_filters/snes_ntsc/snes_ntsc_impl.h b/gfx/video_filters/snes_ntsc/snes_ntsc_impl.h index 36d767d697..6507ae63b1 100644 --- a/gfx/video_filters/snes_ntsc/snes_ntsc_impl.h +++ b/gfx/video_filters/snes_ntsc/snes_ntsc_impl.h @@ -311,7 +311,7 @@ typedef struct pixel_info_t (1.0f - (((ntsc) + 100) & 2)) #endif -extern pixel_info_t const snes_ntsc_pixels [alignment_count]; +extern pixel_info_t const retroarch_snes_ntsc_pixels [alignment_count]; /* Generate pixel at all burst phases and column alignments */ static void gen_kernel( init_t* impl, float y, float i, float q, snes_ntsc_rgb_t* out ) @@ -326,7 +326,7 @@ static void gen_kernel( init_t* impl, float y, float i, float q, snes_ntsc_rgb_t Convolve these with kernels which: filter respective components, apply sharpening, and rescale horizontally. Convert resulting yiq to rgb and pack into integer. Based on algorithm by NewRisingSun. */ - pixel_info_t const* pixel = snes_ntsc_pixels; + pixel_info_t const* pixel = retroarch_snes_ntsc_pixels; int alignment_remain = alignment_count; do { From 4d2c35f6fe3ab99d7ef5e11432ed8292dd31715f Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Sun, 24 Mar 2019 12:38:45 +0000 Subject: [PATCH 083/237] (RGUI) Fix deadlock when changing menu aspect with threaded video enabled --- menu/drivers/rgui.c | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 09af66b711..eb1ba1056f 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -457,6 +457,7 @@ typedef struct char menu_sublabel[255]; /* Must be a fixed length array... */ unsigned menu_aspect_ratio; unsigned menu_aspect_ratio_lock; + bool aspect_update_pending; rgui_video_settings_t menu_video_settings; rgui_video_settings_t content_video_settings; struct scaler_ctx image_scaler; @@ -1499,6 +1500,13 @@ static void rgui_render(void *data, bool is_idle) static bool display_kb = false; bool current_display_cb = false; + /* Apply pending aspect ratio update */ + if (rgui->aspect_update_pending) + { + command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL); + rgui->aspect_update_pending = false; + } + current_display_cb = menu_input_dialog_get_display_kb(); if (!rgui->force_redraw) @@ -1945,7 +1953,7 @@ static void rgui_get_video_config(rgui_video_settings_t *video_settings) video_settings->viewport.y = custom_vp->y; } -static void rgui_set_video_config(rgui_video_settings_t *video_settings) +static void rgui_set_video_config(rgui_t *rgui, rgui_video_settings_t *video_settings, bool delay_update) { settings_t *settings = config_get_ptr(); /* Could use settings->video_viewport_custom directly, @@ -1964,7 +1972,13 @@ static void rgui_set_video_config(rgui_video_settings_t *video_settings) aspectratio_lut[ASPECT_RATIO_CUSTOM].value = (float)custom_vp->width / custom_vp->height; - video_driver_set_aspect_ratio(); + if (delay_update) + rgui->aspect_update_pending = true; + else + { + command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL); + rgui->aspect_update_pending = false; + } } /* Note: This function is only called when aspect ratio @@ -2040,7 +2054,7 @@ static void rgui_update_menu_viewport(rgui_t *rgui) rgui->menu_video_settings.viewport.y = (vp.full_height - rgui->menu_video_settings.viewport.height) / 2; } -static bool rgui_set_aspect_ratio(rgui_t *rgui) +static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update) { unsigned base_term_width; settings_t *settings = config_get_ptr(); @@ -2142,7 +2156,7 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui) if (settings->uints.menu_rgui_aspect_ratio_lock != RGUI_ASPECT_RATIO_LOCK_NONE) { rgui_update_menu_viewport(rgui); - rgui_set_video_config(&rgui->menu_video_settings); + rgui_set_video_config(rgui, &rgui->menu_video_settings, delay_update); } return true; @@ -2177,7 +2191,8 @@ static void *rgui_init(void **userdata, bool video_is_threaded) * - Allocates frame buffer * - Configures variable 'menu display' settings */ rgui->menu_aspect_ratio_lock = settings->uints.menu_rgui_aspect_ratio_lock; - if (!rgui_set_aspect_ratio(rgui)) + rgui->aspect_update_pending = false; + if (!rgui_set_aspect_ratio(rgui, false)) goto error; /* Fixed 'menu display' settings */ @@ -2279,8 +2294,15 @@ static void rgui_frame(void *data, video_frame_info_t *video_info) } } + /* Note: both rgui_set_aspect_ratio() and rgui_set_video_config() + * normally call command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL) + * ## THIS CANNOT BE DONE INSIDE rgui_frame() IF THREADED VIDEO IS ENABLED ## + * Attempting to do so creates a deadlock, and causes RetroArch to hang. + * We therefore have to set the 'delay_update' argument, which causes + * command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL) to be called at + * the next instance of rgui_render() */ if (settings->uints.menu_rgui_aspect_ratio != rgui->menu_aspect_ratio) - rgui_set_aspect_ratio(rgui); + rgui_set_aspect_ratio(rgui, true); if (settings->uints.menu_rgui_aspect_ratio_lock != rgui->menu_aspect_ratio_lock) { @@ -2288,12 +2310,12 @@ static void rgui_frame(void *data, video_frame_info_t *video_info) if (settings->uints.menu_rgui_aspect_ratio_lock == RGUI_ASPECT_RATIO_LOCK_NONE) { - rgui_set_video_config(&rgui->content_video_settings); + rgui_set_video_config(rgui, &rgui->content_video_settings, true); } else { rgui_update_menu_viewport(rgui); - rgui_set_video_config(&rgui->menu_video_settings); + rgui_set_video_config(rgui, &rgui->menu_video_settings, true); } } } @@ -2588,7 +2610,7 @@ static void rgui_populate_entries(void *data, rgui_video_settings_t current_video_settings = {0}; rgui_get_video_config(¤t_video_settings); if (rgui_is_video_config_equal(¤t_video_settings, &rgui->menu_video_settings)) - rgui_set_video_config(&rgui->content_video_settings); + rgui_set_video_config(rgui, &rgui->content_video_settings, false); } } } @@ -2669,7 +2691,7 @@ static void rgui_toggle(void *userdata, bool menu_on) rgui_update_menu_viewport(rgui); /* Apply menu video settings */ - rgui_set_video_config(&rgui->menu_video_settings); + rgui_set_video_config(rgui, &rgui->menu_video_settings, false); } else { @@ -2680,7 +2702,7 @@ static void rgui_toggle(void *userdata, bool menu_on) rgui_get_video_config(¤t_video_settings); if (rgui_is_video_config_equal(¤t_video_settings, &rgui->menu_video_settings)) - rgui_set_video_config(&rgui->content_video_settings); + rgui_set_video_config(rgui, &rgui->content_video_settings, false); } } From cec06a08592c7987be275e18ffb19756f889af19 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 24 Mar 2019 18:15:26 +0100 Subject: [PATCH 084/237] C89 buildfixes --- cores/dynamic_dummy.c | 4 +-- libretro-common/formats/xml/rxml.c | 46 ++++++++++++++++++------------ menu/drivers/rgui.c | 2 +- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/cores/dynamic_dummy.c b/cores/dynamic_dummy.c index 65d76a4c7b..9edc06d74d 100644 --- a/cores/dynamic_dummy.c +++ b/cores/dynamic_dummy.c @@ -67,7 +67,7 @@ void libretro_dummy_retro_init(void) #if defined(HAVE_MENU) && defined(HAVE_RGUI) settings_t *settings = config_get_ptr(); #endif - uint32_t i; + unsigned i; /* Sensible defaults */ frame_buf_width = 320; @@ -95,7 +95,7 @@ void libretro_dummy_retro_init(void) #endif dummy_frame_buf = (uint16_t*)calloc(frame_buf_width * frame_buf_height, sizeof(uint16_t)); - for (i = 0; i < frame_buf_width * frame_buf_height; i++) + for (i = 0; i < (unsigned)(frame_buf_width * frame_buf_height); i++) dummy_frame_buf[i] = 4 << 5; } diff --git a/libretro-common/formats/xml/rxml.c b/libretro-common/formats/xml/rxml.c index 7701d7c98b..430d51ceb1 100644 --- a/libretro-common/formats/xml/rxml.c +++ b/libretro-common/formats/xml/rxml.c @@ -146,28 +146,31 @@ static char *strdup_range_escape(const char *begin, const char *end) static struct rxml_attrib_node *rxml_parse_attrs(const char *str) { - char *copy = strdup(str); + const char *elem; + struct rxml_attrib_node *list = NULL; + struct rxml_attrib_node *tail = NULL; + char *attrib = NULL; + char *value = NULL; + char *last_char = NULL; + char *save = NULL; + char *copy = strdup(str); if (!copy) return NULL; - char *last_char = copy + strlen(copy) - 1; + last_char = copy + strlen(copy) - 1; if (*last_char == '/') *last_char = '\0'; - struct rxml_attrib_node *list = NULL; - struct rxml_attrib_node *tail = NULL; - - char *attrib = NULL; - char *value = NULL; - char *save; - const char *elem = strtok_r(copy, " \n\t\f\v\r", &save); + elem = strtok_r(copy, " \n\t\f\v\r", &save); while (elem) { + const char *end; + struct rxml_attrib_node *new_node; const char *eq = strstr(elem, "=\""); if (!eq) goto end; - const char *end = strrchr(eq + 2, '\"'); + end = strrchr(eq + 2, '\"'); if (!end || end != (elem + strlen(elem) - 1)) goto end; @@ -176,15 +179,15 @@ static struct rxml_attrib_node *rxml_parse_attrs(const char *str) if (!attrib || !value) goto end; - struct rxml_attrib_node *new_node = + new_node = (struct rxml_attrib_node*)calloc(1, sizeof(*new_node)); if (!new_node) goto end; new_node->attrib = attrib; new_node->value = value; - attrib = NULL; - value = NULL; + attrib = NULL; + value = NULL; if (tail) { @@ -217,10 +220,11 @@ static char *find_first_space(const char *str) static bool rxml_parse_tag(struct rxml_node *node, const char *str) { + const char *name_end; const char *str_ptr = str; rxml_skip_spaces(&str_ptr); - const char *name_end = find_first_space(str_ptr); + name_end = find_first_space(str_ptr); if (name_end) { node->name = strdup_range(str_ptr, name_end); @@ -375,15 +379,18 @@ error: static char *purge_xml_comments(const char *str) { - size_t len = strlen(str); + char *copy_dest; + const char *copy_src; + size_t len = strlen(str); char *new_str = (char*)malloc(len + 1); if (!new_str) return NULL; - new_str[len] = '\0'; + new_str[len] = '\0'; + + copy_dest = new_str; + copy_src = str; - char *copy_dest = new_str; - const char *copy_src = str; for (;;) { ptrdiff_t copy_len; @@ -411,6 +418,7 @@ static char *purge_xml_comments(const char *str) rxml_document_t *rxml_load_document(const char *path) { + rxml_document_t *doc; char *memory_buffer = NULL; char *new_memory_buffer = NULL; const char *mem_ptr = NULL; @@ -421,7 +429,7 @@ rxml_document_t *rxml_load_document(const char *path) if (!file) return NULL; - rxml_document_t *doc = (rxml_document_t*)calloc(1, sizeof(*doc)); + doc = (rxml_document_t*)calloc(1, sizeof(*doc)); if (!doc) goto error; diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index eb1ba1056f..c748d96a67 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -2164,8 +2164,8 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update) static void *rgui_init(void **userdata, bool video_is_threaded) { + unsigned new_font_height; size_t fb_pitch, start; - unsigned fb_width, fb_height, new_font_height; rgui_t *rgui = NULL; bool ret = false; settings_t *settings = config_get_ptr(); From d017163612083c57e09ead029851af7f2d5babf9 Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Sun, 24 Mar 2019 14:23:38 -0400 Subject: [PATCH 085/237] update Russian translation per ofry --- intl/msg_hash_ru.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index 8b3d7ab7b5..662114b765 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -2485,7 +2485,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Выбрать файл") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, - "Выбрать из Плейлист.") + "Выбрать из плейлиста.") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "Фильтр") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, @@ -2835,7 +2835,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Сканировать для поиска новых комнат.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Удалить эту запись из Плейлист.") + "Удалить эту запись из плейлиста.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "Просмотреть больше информации о содержимом.") MSG_HASH(MENU_ENUM_SUBLABEL_RUN, @@ -2907,7 +2907,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Выполнять задачи в отдельном потоке.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Разрешить пользователю удалять отдельные записи из Плейлисты.") + "Разрешить пользователю удалять отдельные записи из плейлистов.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Устанавливает каталог System. Ядра могут запрашивать его для загрузки BIOS, прошивок, системных настроек и т.д.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, From f61cacd24cd450c4e3651d6fcb8768905fe36b43 Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Mon, 25 Mar 2019 09:48:25 -0400 Subject: [PATCH 086/237] update Chinese (Traditional) per asakkous --- intl/msg_hash_cht.c | 2 +- intl/msg_hash_cht.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/intl/msg_hash_cht.c b/intl/msg_hash_cht.c index 0748c607c0..a87d3d658d 100644 --- a/intl/msg_hash_cht.c +++ b/intl/msg_hash_cht.c @@ -650,7 +650,7 @@ int menu_hash_get_help_cht_enum(enum msg_hash_enums msg, char *s, size_t len) "並選擇「%s」或者「%s」。\n" "\n" "文件將會同數據庫中的條目進行對比。\n" - "若文件匹配某個條目,則它會被加入戲列表中。\n" + "若文件匹配某個條目,則它會被加入遊戲列表中。\n" "\n" "你可以無需每次都打開文件瀏覽器,而可以直接\n" "通過菜單項「%s」->「%s」 來訪\n" diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index ebe65858a7..2d5b4bd44d 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -1087,9 +1087,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, "沒有性能計數器。") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, - "沒有戲列表。") + "沒有遊戲列表。") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLIST_ENTRIES_AVAILABLE, - "沒有可用的戲列表項目。") + "沒有可用的遊戲列表項目。") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, "沒有找到設定。") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, @@ -1137,11 +1137,11 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, "性能計數器") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, - "戲列表") + "遊戲列表") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "戲列表目錄") + "遊戲列表目錄") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, - "戲列表") + "遊戲列表") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, "觸控支援") MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, @@ -1798,7 +1798,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, "修改此系統的默認目錄。") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, - "修改戲列表設定。") + "修改遊戲列表設定。") MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, "修改網路設定。") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, From 2c65068be09458e0935a892850df21bf3ce48df9 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 25 Mar 2019 17:22:59 +0000 Subject: [PATCH 087/237] More 'Log to File' Additions: - Add optional timestamped log files - Handle errors if log file cannot be opened - Android: flush log file immediately - 3DS: log to file tested and fully working - Default log paths added for all platforms --- config.def.h | 1 + configuration.c | 1 + configuration.h | 1 + frontend/drivers/platform_ctr.c | 33 ++++++++-------- frontend/drivers/platform_darwin.m | 1 + frontend/drivers/platform_emscripten.c | 2 + frontend/drivers/platform_gx.c | 53 +++++++------------------- frontend/drivers/platform_orbis.c | 2 + frontend/drivers/platform_ps2.c | 2 + frontend/drivers/platform_ps3.c | 3 ++ frontend/drivers/platform_psp.c | 4 ++ frontend/drivers/platform_qnx.c | 2 + frontend/drivers/platform_switch.c | 3 ++ frontend/drivers/platform_uwp.c | 2 + frontend/drivers/platform_wiiu.c | 2 + frontend/drivers/platform_xdk.c | 6 +++ intl/msg_hash_lbl.h | 2 + intl/msg_hash_us.h | 8 ++++ menu/cbs/menu_cbs_sublabel.c | 4 ++ menu/menu_displaylist.c | 3 ++ menu/menu_setting.c | 16 ++++++++ msg_hash.h | 1 + retroarch.c | 21 +++++++++- tasks/task_content.c | 4 -- verbosity.c | 13 ++++++- 25 files changed, 128 insertions(+), 62 deletions(-) diff --git a/config.def.h b/config.def.h index 97a95dacb1..efdb68a691 100644 --- a/config.def.h +++ b/config.def.h @@ -440,6 +440,7 @@ static bool menu_swap_ok_cancel_buttons = false; static bool quit_press_twice = false; static bool default_log_to_file = false; +static bool log_to_file_timestamp = false; /* Crop overscanned frames. */ static const bool crop_overscan = true; diff --git a/configuration.c b/configuration.c index 07af9cdc0a..fb82023d53 100644 --- a/configuration.c +++ b/configuration.c @@ -1595,6 +1595,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, #endif SETTING_BOOL("log_to_file", &settings->bools.log_to_file, true, default_log_to_file, false); + SETTING_BOOL("log_to_file_timestamp", &settings->bools.log_to_file_timestamp, true, log_to_file_timestamp, false); *size = count; diff --git a/configuration.h b/configuration.h index 4919a22c14..a6099c2198 100644 --- a/configuration.h +++ b/configuration.h @@ -321,6 +321,7 @@ typedef struct settings #endif bool log_to_file; + bool log_to_file_timestamp; } bools; struct diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c index 6db1865dbb..41254ef7ea 100644 --- a/frontend/drivers/platform_ctr.c +++ b/frontend/drivers/platform_ctr.c @@ -93,14 +93,6 @@ static void frontend_ctr_get_environment_settings(int* argc, char* argv[], { (void)args; -#ifndef IS_SALAMANDER -#if defined(HAVE_LOGGER) - logger_init(); -#elif defined(HAVE_FILE_LOGGER) - retro_main_log_file_init("sdmc:/retroarch/retroarch-log.txt"); -#endif -#endif - fill_pathname_basedir(g_defaults.dirs[DEFAULT_DIR_PORT], elf_path_cst, sizeof(g_defaults.dirs[DEFAULT_DIR_PORT])); RARCH_LOG("port dir: [%s]\n", g_defaults.dirs[DEFAULT_DIR_PORT]); @@ -125,11 +117,13 @@ static void frontend_ctr_get_environment_settings(int* argc, char* argv[], fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_REMAP], g_defaults.dirs[DEFAULT_DIR_PORT], "config/remaps", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], g_defaults.dirs[DEFAULT_DIR_PORT], - "filters", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP])); + "filters", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_DATABASE], g_defaults.dirs[DEFAULT_DIR_PORT], "database/rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CURSOR], g_defaults.dirs[DEFAULT_DIR_PORT], "database/cursors", sizeof(g_defaults.dirs[DEFAULT_DIR_CURSOR])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], g_defaults.dirs[DEFAULT_DIR_PORT], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); fill_pathname_join(g_defaults.path.config, g_defaults.dirs[DEFAULT_DIR_PORT], file_path_str(FILE_PATH_MAIN_CONFIG), sizeof(g_defaults.path.config)); } @@ -145,11 +139,18 @@ static void frontend_ctr_deinit(void* data) (void)data; #ifndef IS_SALAMANDER + /* Note: frontend_ctr_deinit() is normally called when + * forking to load new content. When this happens, the + * log messages generated in frontend_ctr_exec() *must* + * be printed to screen (provided bottom screen is not + * turned off...), since the 'first core launch' warning + * can prevent sdcard corruption. We therefore close any + * existing log file, enable verbose logging and revert + * to console output. (Normal logging will be resumed + * once retroarch.cfg has been re-read) */ + retro_main_log_file_deinit(); verbosity_enable(); - -#ifdef HAVE_FILE_LOGGER - command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL); -#endif + retro_main_log_file_init(NULL, false); if ((gfxBottomFramebuffers[0] == (u8*)currentConsole->frameBuffer) && (ctr_fork_mode == FRONTEND_FORK_NONE)) @@ -203,9 +204,9 @@ static void frontend_ctr_exec(const char* path, bool should_load_game) if (should_load_game && !path_is_empty(RARCH_PATH_CONTENT)) { strcpy(game_path, path_get(RARCH_PATH_CONTENT)); - arg_data[args] = game_path; - arg_data[args + 1] = NULL; - args++; + arg_data[args] = game_path; + arg_data[args + 1] = NULL; + args++; RARCH_LOG("content path: [%s].\n", path_get(RARCH_PATH_CONTENT)); } #endif diff --git a/frontend/drivers/platform_darwin.m b/frontend/drivers/platform_darwin.m index 00125d96cd..ab3cbdb6b2 100644 --- a/frontend/drivers/platform_darwin.m +++ b/frontend/drivers/platform_darwin.m @@ -401,6 +401,7 @@ static void frontend_darwin_get_environment_settings(int *argc, char *argv[], fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SAVESTATE], home_dir_buf, "states", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_RECORD_CONFIG], home_dir_buf, "records_config", sizeof(g_defaults.dirs[DEFAULT_DIR_RECORD_CONFIG])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_RECORD_OUTPUT], home_dir_buf, "records", sizeof(g_defaults.dirs[DEFAULT_DIR_RECORD_OUTPUT])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], home_dir_buf, "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); #if defined(IOS) fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], home_dir_buf, "playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST])); #endif diff --git a/frontend/drivers/platform_emscripten.c b/frontend/drivers/platform_emscripten.c index 4aaf6a7d13..df4dad555c 100644 --- a/frontend/drivers/platform_emscripten.c +++ b/frontend/drivers/platform_emscripten.c @@ -198,6 +198,8 @@ static void frontend_emscripten_get_env(int *argc, char *argv[], "system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS], user_path, "thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); /* cache dir */ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CACHE], "/tmp/", diff --git a/frontend/drivers/platform_gx.c b/frontend/drivers/platform_gx.c index 47e983cf6d..5fb04661e9 100644 --- a/frontend/drivers/platform_gx.c +++ b/frontend/drivers/platform_gx.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -65,17 +66,6 @@ extern void system_exec_wii(const char *path, bool should_load_game); static enum frontend_fork gx_fork_mode = FRONTEND_FORK_NONE; #endif -#ifndef IS_SALAMANDER -#include "../../paths.h" - -enum -{ - GX_DEVICE_SD = 0, - GX_DEVICE_USB, - GX_DEVICE_END -}; - -#if defined(HAVE_LOGGER) || defined(HAVE_FILE_LOGGER) static devoptab_t dotab_stdout = { "stdout", /* device name */ 0, /* size of file structure */ @@ -101,7 +91,16 @@ static devoptab_t dotab_stdout = { NULL, /* device fsync_r */ NULL, /* deviceData; */ }; -#endif + +#ifndef IS_SALAMANDER +#include "../../paths.h" + +enum +{ + GX_DEVICE_SD = 0, + GX_DEVICE_USB, + GX_DEVICE_END +}; #ifdef HW_RVL static struct @@ -151,22 +150,6 @@ static void gx_devthread(void *a) } #endif -#ifdef HAVE_LOGGER -static int gx_logger_net(struct _reent *r, int fd, const char *ptr, size_t len) -{ -#ifdef HAVE_LOGGER - static char temp[4000]; - size_t l = (len >= 4000) ? 3999 : len - 1; - memcpy(temp, ptr, l); - temp[l] = 0; - logger_send("%s", temp); -#elif defined(HAVE_FILE_LOGGER) - fwrite(ptr, 1, len, retro_main_log_file()); -#endif - return len; -} -#endif - #endif #ifdef IS_SALAMANDER @@ -180,11 +163,6 @@ static void frontend_gx_get_environment_settings( char *last_slash = NULL; char *device_end = NULL; #ifndef IS_SALAMANDER -#if defined(HAVE_LOGGER) - logger_init(); -#elif defined(HAVE_FILE_LOGGER) - retro_main_log_file_init("/retroarch-log.txt"); -#endif /* This situation can happen on some loaders so we really need some fake args or else retroarch will just crash on parsing NULL pointers */ @@ -253,6 +231,8 @@ static void frontend_gx_get_environment_settings( "savefiles", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], g_defaults.dirs[DEFAULT_DIR_PORT], "playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], g_defaults.dirs[DEFAULT_DIR_PORT], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); #ifdef IS_SALAMANDER if (*argc > 2 && argv[1] != NULL && argv[2] != NULL) @@ -326,15 +306,8 @@ static void frontend_gx_init(void *data) fatInitDefault(); -#ifdef HAVE_LOGGER devoptab_list[STD_OUT] = &dotab_stdout; devoptab_list[STD_ERR] = &dotab_stdout; - dotab_stdout.write_r = gx_logger_net; -#elif defined(HAVE_FILE_LOGGER) && !defined(IS_SALAMANDER) - devoptab_list[STD_OUT] = &dotab_stdout; - devoptab_list[STD_ERR] = &dotab_stdout; - dotab_stdout.write_r = gx_logger_file; -#endif #if defined(HW_RVL) && !defined(IS_SALAMANDER) gx_devices[GX_DEVICE_SD].interface = &__io_wiisd; diff --git a/frontend/drivers/platform_orbis.c b/frontend/drivers/platform_orbis.c index b46d11f4e9..f284dbf898 100644 --- a/frontend/drivers/platform_orbis.c +++ b/frontend/drivers/platform_orbis.c @@ -169,6 +169,8 @@ static void frontend_orbis_get_environment_settings(int *argc, char *argv[], "overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS], user_path, "thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); strlcpy(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY], user_path, sizeof(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY])); fill_pathname_join(g_defaults.path.config, user_path, diff --git a/frontend/drivers/platform_ps2.c b/frontend/drivers/platform_ps2.c index fc07094e28..1ac58934d2 100644 --- a/frontend/drivers/platform_ps2.c +++ b/frontend/drivers/platform_ps2.c @@ -77,6 +77,8 @@ static void create_path_names(void) "SCREENSHOTS", sizeof(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM], user_path, "SYSTEM", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, + "LOGS", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); /* cache dir */ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CACHE], user_path, diff --git a/frontend/drivers/platform_ps3.c b/frontend/drivers/platform_ps3.c index 656d1e604b..c796b6f07f 100644 --- a/frontend/drivers/platform_ps3.c +++ b/frontend/drivers/platform_ps3.c @@ -263,6 +263,9 @@ static void frontend_ps3_get_environment_settings(int *argc, char *argv[], fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG], g_defaults.dirs[DEFAULT_DIR_CORE], "autoconfig", sizeof(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], + g_defaults.dirs[DEFAULT_DIR_CORE], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); } #ifndef IS_SALAMANDER diff --git a/frontend/drivers/platform_psp.c b/frontend/drivers/platform_psp.c index fa8e86e472..25045be15c 100644 --- a/frontend/drivers/platform_psp.c +++ b/frontend/drivers/platform_psp.c @@ -147,6 +147,8 @@ static void frontend_psp_get_environment_settings(int *argc, char *argv[], "overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS], user_path, "thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); strlcpy(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY], user_path, sizeof(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY])); fill_pathname_join(g_defaults.path.config, user_path, @@ -177,6 +179,8 @@ static void frontend_psp_get_environment_settings(int *argc, char *argv[], "SCREENSHOTS", sizeof(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM], user_path, "SYSTEM", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, + "LOGS", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); /* cache dir */ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CACHE], user_path, diff --git a/frontend/drivers/platform_qnx.c b/frontend/drivers/platform_qnx.c index 168a7462ca..eb2bd40857 100644 --- a/frontend/drivers/platform_qnx.c +++ b/frontend/drivers/platform_qnx.c @@ -130,6 +130,8 @@ static void frontend_qnx_get_environment_settings(int *argc, char *argv[], "thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAIL])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_WALLPAPERS], user_path, "wallpapers", sizeof(g_defaults.dirs[DEFAULT_DIR_WALLPAPERS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], user_path, + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); /* tmp */ strlcpy(g_defaults.dirs[DEFAULT_DIR_CACHE], diff --git a/frontend/drivers/platform_switch.c b/frontend/drivers/platform_switch.c index d3927eff84..98cb62d335 100644 --- a/frontend/drivers/platform_switch.c +++ b/frontend/drivers/platform_switch.c @@ -223,6 +223,9 @@ static void frontend_switch_get_environment_settings(int *argc, char *argv[], vo fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS], g_defaults.dirs[DEFAULT_DIR_PORT], "thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], g_defaults.dirs[DEFAULT_DIR_PORT], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); + int i = 0; for (i; i < DEFAULT_DIR_LAST; i++) { diff --git a/frontend/drivers/platform_uwp.c b/frontend/drivers/platform_uwp.c index 7859f8ac5b..ce33bfcd7e 100644 --- a/frontend/drivers/platform_uwp.c +++ b/frontend/drivers/platform_uwp.c @@ -374,6 +374,8 @@ static void frontend_uwp_environment_get(int *argc, char *argv[], "~\\states", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE])); fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_SYSTEM], "~\\system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_LOGS], + "~\\logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); #ifdef HAVE_MENU #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) diff --git a/frontend/drivers/platform_wiiu.c b/frontend/drivers/platform_wiiu.c index f3a6831019..5559deca3b 100644 --- a/frontend/drivers/platform_wiiu.c +++ b/frontend/drivers/platform_wiiu.c @@ -104,6 +104,8 @@ static void frontend_wiiu_get_environment_settings(int *argc, char *argv[], "database/rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CURSOR], g_defaults.dirs[DEFAULT_DIR_PORT], "database/cursors", sizeof(g_defaults.dirs[DEFAULT_DIR_CURSOR])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], g_defaults.dirs[DEFAULT_DIR_CORE], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); fill_pathname_join(g_defaults.path.config, g_defaults.dirs[DEFAULT_DIR_PORT], file_path_str(FILE_PATH_MAIN_CONFIG), sizeof(g_defaults.path.config)); diff --git a/frontend/drivers/platform_xdk.c b/frontend/drivers/platform_xdk.c index 73b1e978eb..8fb2e5ebc7 100644 --- a/frontend/drivers/platform_xdk.c +++ b/frontend/drivers/platform_xdk.c @@ -132,6 +132,9 @@ static void frontend_xdk_get_environment_settings(int *argc, char *argv[], fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], g_defaults.dirs[DEFAULT_DIR_CORE], "playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], + g_defaults.dirs[DEFAULT_DIR_CORE], + "logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); #elif defined(_XBOX360) strlcpy(g_defaults.dirs[DEFAULT_DIR_CORE], "game:", @@ -152,6 +155,9 @@ static void frontend_xdk_get_environment_settings(int *argc, char *argv[], sizeof(g_defaults.dirs[DEFAULT_DIR_SRAM])); strlcpy(g_defaults.dirs[DEFAULT_DIR_SYSTEM], "game:\\system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); + strlcpy(g_defaults.dirs[DEFAULT_DIR_LOGS], + "game:\\logs", + sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS])); #endif fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], g_defaults.dirs[DEFAULT_DIR_CORE], diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index a0f0b92e35..939158c0c7 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -649,6 +649,8 @@ MSG_HASH(MENU_ENUM_LABEL_LOG_VERBOSITY, "log_verbosity") MSG_HASH(MENU_ENUM_LABEL_LOG_TO_FILE, "log_to_file") +MSG_HASH(MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP, + "log_to_file_timestamp") MSG_HASH(MENU_ENUM_LABEL_MAIN_MENU, "main_menu") MSG_HASH(MENU_ENUM_LABEL_MANAGEMENT, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 85f8d5e911..38c0fc9d83 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1624,6 +1624,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_LOG_TO_FILE, "Redirects system event log messages to file. Requires 'Logging Verbosity' to be enabled." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOG_TO_FILE_TIMESTAMP, + "Timestamped Log Files" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOG_TO_FILE_TIMESTAMP, + "When logging to file, redirects the output from each RetroArch session to a new timestamped file. If disabled, log is overwritten each time RetroArch is restarted." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MAIN_MENU, "Main Menu" diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index de341c3a1e..a5b70b6583 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -144,6 +144,7 @@ default_sublabel_macro(action_bind_sublabel_toggle_gamepad_combo, MENU_ default_sublabel_macro(action_bind_sublabel_show_hidden_files, MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES) default_sublabel_macro(action_bind_sublabel_log_verbosity, MENU_ENUM_SUBLABEL_LOG_VERBOSITY) default_sublabel_macro(action_bind_sublabel_log_to_file, MENU_ENUM_SUBLABEL_LOG_TO_FILE) +default_sublabel_macro(action_bind_sublabel_log_to_file_timestamp, MENU_ENUM_SUBLABEL_LOG_TO_FILE_TIMESTAMP) default_sublabel_macro(action_bind_sublabel_log_dir, MENU_ENUM_SUBLABEL_LOG_DIR) default_sublabel_macro(action_bind_sublabel_video_monitor_index, MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX) default_sublabel_macro(action_bind_sublabel_video_refresh_rate_auto, MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO) @@ -2134,6 +2135,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_LOG_TO_FILE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_log_to_file); break; + case MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_log_to_file_timestamp); + break; case MENU_ENUM_LABEL_LOG_DIR: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_log_dir); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index c2038ea153..4c827c366f 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -5492,6 +5492,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_LOG_TO_FILE, PARSE_ONLY_BOOL, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP, + PARSE_ONLY_BOOL, false); { settings_t *settings = config_get_ptr(); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 3b03386ba5..ad3de63362 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -3342,6 +3342,7 @@ void general_write_handler(rarch_setting_t *setting) } break; case MENU_ENUM_LABEL_LOG_DIR: + case MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP: if (verbosity_is_enabled() && is_logging_to_file()) { rarch_log_file_deinit(); @@ -4975,6 +4976,21 @@ static bool setting_append_list( general_read_handler, SD_FLAG_ADVANCED); + CONFIG_BOOL( + list, list_info, + &settings->bools.log_to_file_timestamp, + MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP, + MENU_ENUM_LABEL_VALUE_LOG_TO_FILE_TIMESTAMP, + log_to_file_timestamp, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_ADVANCED); + END_SUB_GROUP(list, list_info, parent_group); START_SUB_GROUP(list, list_info, "Performance Counters", &group_info, &subgroup_info, diff --git a/msg_hash.h b/msg_hash.h index 89c58939c1..0973f9946a 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1394,6 +1394,7 @@ enum msg_hash_enums MENU_LABEL(LOG_VERBOSITY), MENU_LABEL(LOG_TO_FILE), + MENU_LABEL(LOG_TO_FILE_TIMESTAMP), MENU_ENUM_LABEL_OVERLAY_NEXT, diff --git a/retroarch.c b/retroarch.c index 50252741e7..a1308602a7 100644 --- a/retroarch.c +++ b/retroarch.c @@ -292,6 +292,7 @@ static char runtime_content_path[PATH_MAX_LENGTH] = {0}; static char runtime_core_path[PATH_MAX_LENGTH] = {0}; static bool log_file_created = false; +static char timestamped_log_file_name[64] = {0}; extern bool input_driver_flushing_input; @@ -5282,6 +5283,22 @@ void rarch_log_file_init(void) FILE *fp = NULL; bool success = false; + /* If this is the first run, generate a timestamped log + * file name (do this even when not outputting timestamped + * log files, since user may decide to switch at any moment...) */ + if (string_is_empty(timestamped_log_file_name)) + { + char format[256]; + time_t cur_time = time(NULL); + + format[0] = '\0'; + + strftime(format, sizeof(format), "retroarch__%Y_%m_%d__%H_%M_%S", localtime(&cur_time)); + + fill_pathname_noext(timestamped_log_file_name, format, + file_path_str(FILE_PATH_EVENT_LOG_EXTENSION), sizeof(timestamped_log_file_name)); + } + /* If nothing has changed, do nothing */ if ((!settings->bools.log_to_file && !is_logging_to_file()) || (settings->bools.log_to_file && is_logging_to_file())) @@ -5312,7 +5329,9 @@ void rarch_log_file_init(void) if (!string_is_empty(settings->paths.log_dir)) { char buf[PATH_MAX_LENGTH]; - fill_pathname_join(buf, settings->paths.log_dir, file_path_str(FILE_PATH_DEFAULT_EVENT_LOG), sizeof(buf)); + fill_pathname_join(buf, settings->paths.log_dir, + settings->bools.log_to_file_timestamp ? timestamped_log_file_name : file_path_str(FILE_PATH_DEFAULT_EVENT_LOG), + sizeof(buf)); if (!string_is_empty(buf)) { /* When RetroArch is launched, log file is overwritten. diff --git a/tasks/task_content.c b/tasks/task_content.c index ec809fa14f..d1c9c03fd0 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -188,9 +188,7 @@ static void content_load_init_wrap( const struct rarch_main_wrap *args, int *argc, char **argv) { -#ifdef HAVE_FILE_LOGGER int i; -#endif *argc = 0; argv[(*argc)++] = strdup("retroarch"); @@ -238,10 +236,8 @@ static void content_load_init_wrap( if (args->verbose) argv[(*argc)++] = strdup("-v"); -#ifdef HAVE_FILE_LOGGER for (i = 0; i < *argc; i++) RARCH_LOG("arg #%d: %s\n", i, argv[i]); -#endif } /** diff --git a/verbosity.c b/verbosity.c index 8c05d20055..267f6193f6 100644 --- a/verbosity.c +++ b/verbosity.c @@ -126,6 +126,14 @@ void retro_main_log_file_init(const char *path, bool append) return; log_file_fp = (FILE*)fopen_utf8(path, append ? "ab" : "wb"); + + if (!log_file_fp) + { + log_file_fp = stderr; + RARCH_ERR("Failed to open system event log file: %s\n", path); + return; + } + log_file_initialized = true; #if !defined(PS2) /* TODO: PS2 IMPROVEMENT */ @@ -137,7 +145,7 @@ void retro_main_log_file_init(const char *path, bool append) void retro_main_log_file_deinit(void) { - if (log_file_fp && log_file_fp != stderr) + if (log_file_fp && log_file_initialized) { fclose(log_file_fp); log_file_fp = NULL; @@ -199,7 +207,10 @@ void RARCH_LOG_V(const char *tag, const char *fmt, va_list ap) } if (log_file_initialized) + { vfprintf(log_file_fp, fmt, ap); + fflush(log_file_fp); + } else __android_log_vprint(prio, file_path_str(FILE_PATH_PROGRAM_NAME), From e7891b8c1aa90c620fb2ade47a74c834a0de6cfd Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 25 Mar 2019 23:22:19 -0400 Subject: [PATCH 088/237] add analog deadzone and sensitivity options, rename axis threshold --- config.def.h | 6 ++- configuration.c | 2 + configuration.h | 2 + input/input_driver.c | 71 +++++++++++++++++++++++++++++------- intl/msg_hash_ar.c | 8 ---- intl/msg_hash_ar.h | 6 --- intl/msg_hash_chs.c | 7 ---- intl/msg_hash_chs.h | 6 --- intl/msg_hash_cht.c | 8 ---- intl/msg_hash_cht.h | 6 --- intl/msg_hash_de.c | 8 ---- intl/msg_hash_de.h | 6 --- intl/msg_hash_el.c | 8 ---- intl/msg_hash_el.h | 8 ---- intl/msg_hash_eo.h | 6 --- intl/msg_hash_es.c | 9 ----- intl/msg_hash_es.h | 8 ---- intl/msg_hash_fr.h | 6 --- intl/msg_hash_it.c | 8 ---- intl/msg_hash_it.h | 6 --- intl/msg_hash_ja.c | 8 ---- intl/msg_hash_ja.h | 6 --- intl/msg_hash_ko.c | 8 ---- intl/msg_hash_ko.h | 6 --- intl/msg_hash_lbl.h | 6 ++- intl/msg_hash_nl.h | 6 --- intl/msg_hash_pl.h | 6 --- intl/msg_hash_pt_br.c | 8 ---- intl/msg_hash_pt_br.h | 8 ---- intl/msg_hash_pt_pt.c | 8 ---- intl/msg_hash_pt_pt.h | 6 --- intl/msg_hash_ru.h | 6 --- intl/msg_hash_us.c | 4 +- intl/msg_hash_us.h | 14 +++++-- intl/msg_hash_vn.c | 8 ---- intl/msg_hash_vn.h | 6 --- menu/cbs/menu_cbs_sublabel.c | 4 +- menu/menu_displaylist.c | 6 ++- menu/menu_setting.c | 36 ++++++++++++++++-- msg_hash.h | 4 +- retroarch.cfg | 4 ++ 41 files changed, 132 insertions(+), 231 deletions(-) diff --git a/config.def.h b/config.def.h index 97a95dacb1..61d29d3458 100644 --- a/config.def.h +++ b/config.def.h @@ -755,7 +755,11 @@ static const unsigned libretro_log_level = 1; /* Axis threshold (between 0.0 and 1.0) * How far an axis must be tilted to result in a button press. */ -static const float axis_threshold = 0.5; +static const float axis_threshold = 0.5f; + +static const float analog_deadzone = 0.0f; + +static const float analog_sensitivity = 1.0f; /* Describes speed of which turbo-enabled buttons toggle. */ static const unsigned turbo_period = 6; diff --git a/configuration.c b/configuration.c index 07af9cdc0a..a087f6a661 100644 --- a/configuration.c +++ b/configuration.c @@ -1634,6 +1634,8 @@ static struct config_float_setting *populate_settings_float(settings_t *settings SETTING_FLOAT("fastforward_ratio", &settings->floats.fastforward_ratio, true, fastforward_ratio, false); SETTING_FLOAT("slowmotion_ratio", &settings->floats.slowmotion_ratio, true, slowmotion_ratio, false); SETTING_FLOAT("input_axis_threshold", input_driver_get_float(INPUT_ACTION_AXIS_THRESHOLD), true, axis_threshold, false); + SETTING_FLOAT("input_analog_deadzone", &settings->floats.input_analog_deadzone, true, analog_deadzone, false); + SETTING_FLOAT("input_analog_sensitivity", &settings->floats.input_analog_sensitivity, true, analog_sensitivity, false); SETTING_FLOAT("video_msg_bgcolor_opacity", &settings->floats.video_msg_bgcolor_opacity, true, message_bgcolor_opacity, false); *size = count; diff --git a/configuration.h b/configuration.h index 4919a22c14..bd2c414b08 100644 --- a/configuration.h +++ b/configuration.h @@ -353,6 +353,8 @@ typedef struct settings float slowmotion_ratio; float fastforward_ratio; + float input_analog_deadzone; + float input_analog_sensitivity; } floats; struct diff --git a/input/input_driver.c b/input/input_driver.c index 9e8e1b913e..7d2b71f30a 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -1,6 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2019 - Brad Parker * * 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- @@ -876,6 +877,48 @@ static INLINE bool input_keys_pressed_iterate(unsigned i, return false; } +static int16_t input_joypad_axis(const input_device_driver_t *drv, unsigned port, uint32_t joyaxis) +{ + int16_t val = 0; + settings_t *settings = config_get_ptr(); + + if (!drv || !drv->axis) + return 0; + + val = drv->axis(port, joyaxis); + + if (settings->floats.input_analog_deadzone) + { + float normalized; + + /* if analog value is below the deadzone, ignore it */ + val = ((float)abs(val) / 0x7fff) < settings->floats.input_analog_deadzone ? 0 : val; + + if (val == 0) + return 0; + + normalized = (1.0f / 0x7fff) * val; + + /* now scale the "good" analog range appropriately, so we don't start out way above 0 */ + val = 0x7fff * ((normalized - settings->floats.input_analog_deadzone) / (1.0f - settings->floats.input_analog_deadzone)); + } + + if (settings->floats.input_analog_sensitivity != 1.0f) + { + float normalized = (1.0f / 0x7fff) * val; + int new_val = 0x7fff * normalized * settings->floats.input_analog_sensitivity; + + if (new_val > 0x7fff) + new_val = 0x7fff; + else if (new_val < -0x7fff) + new_val = -0x7fff; + + val = new_val; + } + + return val; +} + #ifdef HAVE_MENU /** @@ -979,7 +1022,7 @@ void input_menu_keys_pressed(void *data, input_bits_t *p_new_state) { if (joykey == NO_BTN || !sec->button(joypad_info.joy_idx, joykey)) { - int16_t axis = sec->axis(joypad_info.joy_idx, joyaxis); + int16_t axis = input_joypad_axis(sec, joypad_info.joy_idx, joyaxis); float scaled_axis = (float)abs(axis) / 0x8000; bit_pressed = scaled_axis > joypad_info.axis_threshold; } @@ -991,7 +1034,7 @@ void input_menu_keys_pressed(void *data, input_bits_t *p_new_state) { if (joykey == NO_BTN || !first->button(joypad_info.joy_idx, joykey)) { - int16_t axis = first->axis(joypad_info.joy_idx, joyaxis); + int16_t axis = input_joypad_axis(first, joypad_info.joy_idx, joyaxis); float scaled_axis = (float)abs(axis) / 0x8000; bit_pressed = scaled_axis > joypad_info.axis_threshold; } @@ -1682,34 +1725,36 @@ int16_t input_joypad_analog(const input_device_driver_t *drv, { int16_t res; - if ( idx == RETRO_DEVICE_INDEX_ANALOG_BUTTON ) + if (idx == RETRO_DEVICE_INDEX_ANALOG_BUTTON) { /* A RETRO_DEVICE_JOYPAD button? */ - if ( ident < RARCH_FIRST_CUSTOM_BIND ) + if (ident < RARCH_FIRST_CUSTOM_BIND) { uint32_t axis = 0; const struct retro_keybind *bind = NULL; bind = &binds[ ident ]; + if (!bind->valid) return 0; axis = bind->joyaxis; - if ( axis == AXIS_NONE ) - axis = joypad_info.auto_binds[ ident ].joyaxis; + + if (axis == AXIS_NONE) + axis = joypad_info.auto_binds[ident].joyaxis; /* Analog button. */ - res = abs( drv->axis( joypad_info.joy_idx, axis ) ); + res = abs(input_joypad_axis(drv, joypad_info.joy_idx, axis)); /* If the result is zero, it's got a digital button attached to it */ - if ( res == 0 ) + if (res == 0) { uint16_t key = bind->joykey; - if ( key == NO_BTN ) - key = joypad_info.auto_binds[ ident ].joykey; + if (key == NO_BTN) + key = joypad_info.auto_binds[ident].joykey; - if ( drv->button(joypad_info.joy_idx, key)) + if (drv->button(joypad_info.joy_idx, key)) res = 0x7fff; } } @@ -1747,8 +1792,8 @@ int16_t input_joypad_analog(const input_device_driver_t *drv, if (axis_plus == AXIS_NONE) axis_plus = joypad_info.auto_binds[ident_plus].joyaxis; - pressed_minus = abs(drv->axis(joypad_info.joy_idx, axis_minus)); - pressed_plus = abs(drv->axis(joypad_info.joy_idx, axis_plus)); + pressed_minus = abs(input_joypad_axis(drv, joypad_info.joy_idx, axis_minus)); + pressed_plus = abs(input_joypad_axis(drv, joypad_info.joy_idx, axis_plus)); res = pressed_plus - pressed_minus; if (res == 0) diff --git a/intl/msg_hash_ar.c b/intl/msg_hash_ar.c index d4ad60564b..6c7b3d87c4 100644 --- a/intl/msg_hash_ar.c +++ b/intl/msg_hash_ar.c @@ -1499,14 +1499,6 @@ int menu_hash_get_help_ar_enum(enum msg_hash_enums msg, char *s, size_t len) "When slowmotion, content will slow\n" "down by factor."); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "Defines axis threshold.\n" - " \n" - "How far an axis must be tilted to result\n" - "in a button press.\n" - " Possible values are [0.0, 1.0]."); - break; case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: snprintf(s, len, "Turbo period.\n" diff --git a/intl/msg_hash_ar.h b/intl/msg_hash_ar.h index 52cf18f812..c72799a4b5 100644 --- a/intl/msg_hash_ar.h +++ b/intl/msg_hash_ar.h @@ -759,8 +759,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "Gun D-pad Right") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Autoconfig Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Analog Stick Deadzone") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Menu Swap OK & Cancel Buttons") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2465,10 +2463,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Synchronize audio. Recommended." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "How far an axis must be tilted to result in a button press." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Amount of seconds to wait until proceeding to the next bind." diff --git a/intl/msg_hash_chs.c b/intl/msg_hash_chs.c index 498c4e4e4c..ccdfae50ae 100644 --- a/intl/msg_hash_chs.c +++ b/intl/msg_hash_chs.c @@ -1399,13 +1399,6 @@ int menu_hash_get_help_chs_enum(enum msg_hash_enums msg, char *s, size_t len) " \n" "减速游戏时,速度将被降低的倍数。"); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "摇杆灵敏度\n" - " \n" - "必须把摇杆推到多大幅度才算按下按键。\n" - "数值范围为0.0至1.0。"); - break; case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: snprintf(s, len, "Turbo period.\n" diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index 1a68a5158d..709b8ec3c3 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -754,8 +754,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "Gun D-pad Right") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "启用自动配置") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "摇杆灵敏度") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "互换确定键和取消键") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2518,10 +2516,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "同步音频。推荐。" ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "必须把摇杆推到多大幅度才算按下按键。" - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Amount of seconds to wait until proceeding to the next bind." diff --git a/intl/msg_hash_cht.c b/intl/msg_hash_cht.c index b273803849..bfbf481b04 100644 --- a/intl/msg_hash_cht.c +++ b/intl/msg_hash_cht.c @@ -1443,14 +1443,6 @@ int menu_hash_get_help_cht_enum(enum msg_hash_enums msg, char *s, size_t len) "When slowmotion, content will slow\n" "down by factor."); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "Defines axis threshold.\n" - " \n" - "How far an axis must be tilted to result\n" - "in a button press.\n" - " Possible values are [0.0, 1.0]."); - break; case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: snprintf(s, len, "Turbo period.\n" diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index d263c9b501..b421cb1e8a 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -702,8 +702,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "Gun D-pad Right") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "啟用自動設定") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "輸入軸閾值") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "選單切換 確定/取消 按鈕") /*FIXME:"Menu Swap OK & Cancel Buttons"*/ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2294,10 +2292,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "同步聲音。推薦。" ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "How far an axis must be tilted to result in a button press." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Amount of seconds to wait until proceeding to the next bind." diff --git a/intl/msg_hash_de.c b/intl/msg_hash_de.c index 35d288c79d..838498c66b 100644 --- a/intl/msg_hash_de.c +++ b/intl/msg_hash_de.c @@ -1492,14 +1492,6 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "Ist die Zeitlupe eingeschaltet, wird das Spiel \n" "um diesen Faktor verlangsamt."); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "Definiert Achsen-Grenzwert.\n" - " \n" - "Wie weit eine Achse bewegt werden muss, um einen \n" - "Tastendruck auszulösen .\n" - "Mögliche Werte liegen im Bereich [0.0, 1.0]."); - break; case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: snprintf(s, len, "Turbo-Frequenz.\n" diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 17db8d4b06..8515281b0c 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -735,8 +735,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "Gun D-pad Right") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Automatische Konfiguration aktivieren") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Schwellenwert der Analogsticks") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Vertausche OK- und Zurück-Tasten im Menü") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2402,10 +2400,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Synchronisiere Audio. Empfohlen." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "Legt fest, wie weit ein Analog-Stick bewegt werden muss, bis er reagiert." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Zeitdauer in Sekunden, nach der die nächste Tastenbelegung abgefragt wird." diff --git a/intl/msg_hash_el.c b/intl/msg_hash_el.c index 8ca0867487..35a647c84e 100644 --- a/intl/msg_hash_el.c +++ b/intl/msg_hash_el.c @@ -1559,14 +1559,6 @@ int menu_hash_get_help_el_enum(enum msg_hash_enums msg, char *s, size_t len) "When slowmotion, content will slow\n" "down by factor."); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "Defines axis threshold.\n" - " \n" - "How far an axis must be tilted to result\n" - "in a button press.\n" - " Possible values are [0.0, 1.0]."); - break; case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: snprintf(s, len, "Turbo period.\n" diff --git a/intl/msg_hash_el.h b/intl/msg_hash_el.h index 8ee4f4409b..9b2099fa97 100644 --- a/intl/msg_hash_el.h +++ b/intl/msg_hash_el.h @@ -1002,10 +1002,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Ενεργοποίηση Αυτόματης Διαμόρφωσης" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Νεκρή Ζώνη Αναλογικού" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Εναλλαγή Κουμπιών Επιβεβαίωσης & Ακύρωσης Στο Μενού" @@ -4538,10 +4534,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Συγχρονισμός ήχου. Προτείνεται." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "Πόσο μακριά ένας άξωνας πρέπει να γείρει ώστε να οδηγήσει σε πάτημα κουμπιού." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Χρόνος αναμονής σε δευτερόλεπτα μέχρι την συνέχιση στην επόμενη σύνδεση πλήκτρων." diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index 26f889c6be..6d95430e96 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -622,8 +622,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "Gun D-pad Right") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Autoconfig Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Analog Stick Deadzone") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Menu Swap OK & Cancel Buttons") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2203,10 +2201,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Synchronize audio. Recommended." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "How far an axis must be tilted to result in a button press." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Amount of seconds to wait until proceeding to the next bind." diff --git a/intl/msg_hash_es.c b/intl/msg_hash_es.c index 1b0842119f..3d94c02128 100644 --- a/intl/msg_hash_es.c +++ b/intl/msg_hash_es.c @@ -987,15 +987,6 @@ int menu_hash_get_help_es_enum(enum msg_hash_enums msg, char *s, size_t len) "Al reducir la velocidad, el contenido \n" "se ralentizará según este factor."); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "Define el margen de los ejes.\n" - " \n" - "Indica la distancia mínima que debe \n" - "recorrer un eje para que provoque \n" - "una pulsación del botón.\n" - "Los valores posibles son [0.0, 1.0]."); - break; case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: snprintf(s, len, "Período de turbo.\n" diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index dc0a7fd555..1e56d885e5 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -1045,10 +1045,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Activar Auto-configuración" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Zona muerta analógica" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Menú: cambiar OK y Cancelar" @@ -4619,10 +4615,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Sincronizar audio. Recomendado" ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "Cuanto debe mover la palanca para ser detectada. Evita movimientos indeseados en los mandos que no vuelven perfectamente al centro" - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Cantidad de segundos a esperar hasta la siguiente asignación" diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 5d2b7a0ada..7e32f21d23 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -701,8 +701,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "Gun D-pad Right") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Activer l'autoconfiguration") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Seuil des axes analogiques") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Inverser les boutons OK et Annuler dans le menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2342,10 +2340,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Synchroniser le son avec le jeu. Recommandé." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "Indique à quel point un axe doit être poussé avant d'obtenir une pression sur un bouton." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Nombre de secondes à attendre avant de passer à l'assignation suivante." diff --git a/intl/msg_hash_it.c b/intl/msg_hash_it.c index c81047efa0..1b39241eae 100644 --- a/intl/msg_hash_it.c +++ b/intl/msg_hash_it.c @@ -879,14 +879,6 @@ int menu_hash_get_help_it_enum(enum msg_hash_enums msg, char *s, size_t len) "When slowmotion, content will slow\n" "down by factor."); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "Defines axis threshold.\n" - " \n" - "How far an axis must be tilted to result\n" - "in a button press.\n" - " Possible values are [0.0, 1.0]."); - break; case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: snprintf(s, len, "Turbo period.\n" diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index c6a068d046..ad4252e318 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -707,8 +707,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "Pistola D-pad Destro") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Abilita Autoconfigurazione") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Deadzone dello stick analogico") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Scambia i pulsanti OK & Annulla ") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2374,10 +2372,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Sincronizza l'audio. Consigliato." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "Quanto deve essere inclinato un asse durante la pressione di un pulsante." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Quantità di secondi da attendere fino al prossimo bind." diff --git a/intl/msg_hash_ja.c b/intl/msg_hash_ja.c index e4d823c82e..0846ffac28 100644 --- a/intl/msg_hash_ja.c +++ b/intl/msg_hash_ja.c @@ -1475,14 +1475,6 @@ int menu_hash_get_help_jp_enum(enum msg_hash_enums msg, char *s, size_t len) "When slowmotion, content will slow\n" "down by factor."); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "Defines axis threshold.\n" - " \n" - "How far an axis must be tilted to result\n" - "in a button press.\n" - " Possible values are [0.0, 1.0]."); - break; case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: snprintf(s, len, "Turbo period.\n" diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index daf231cebc..6367ad6abb 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -807,8 +807,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "ライトガンの十字キーの右") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "自動設定を有効") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "入力軸のしきい値") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "メニューのOKとキャンセルボタンをスワップ") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2544,10 +2542,6 @@ MSG_HASH( ) MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_SYNC, "オーディオを同期する。推奨。") -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "入力を確定するために要するスティックの傾き量です。" - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "次のバインドに移るまでの待機秒数です。" diff --git a/intl/msg_hash_ko.c b/intl/msg_hash_ko.c index 87c0c0adfb..14849fdf3e 100644 --- a/intl/msg_hash_ko.c +++ b/intl/msg_hash_ko.c @@ -1473,14 +1473,6 @@ int menu_hash_get_help_ko_enum(enum msg_hash_enums msg, char *s, size_t len) "When slowmotion, content will slow\n" "down by factor."); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "Defines axis threshold.\n" - " \n" - "How far an axis must be tilted to result\n" - "in a button press.\n" - " Possible values are [0.0, 1.0]."); - break; case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: snprintf(s, len, "Turbo period.\n" diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index 57a12537ff..7449d7ab27 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -689,8 +689,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "무기 D-패드 오른쪽") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "자동설정 사용") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "아날로그 스틱 데드존") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "확인/취소 버튼 반전") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2300,10 +2298,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "오디오 동기화. 사용 권장." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "축의 기울기가 인식되는 범위를 설정." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "다음 입력 설정으로 넘어가기 전까지 대기하는 시간(초)." diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index a0f0b92e35..d26290e446 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -521,8 +521,12 @@ MSG_HASH(MENU_ENUM_LABEL_MENU_INPUT_SWAP_OK_CANCEL, "menu_swap_ok_cancel") MSG_HASH(MENU_ENUM_LABEL_INPUT_AUTODETECT_ENABLE, "input_autodetect_enable") -MSG_HASH(MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD, +MSG_HASH(MENU_ENUM_LABEL_INPUT_BUTTON_AXIS_THRESHOLD, "input_axis_threshold") +MSG_HASH(MENU_ENUM_LABEL_INPUT_ANALOG_DEADZONE, + "input_analog_deadzone") +MSG_HASH(MENU_ENUM_LABEL_INPUT_ANALOG_SENSITIVITY, + "input_analog_sensitivity") MSG_HASH(MENU_ENUM_LABEL_INPUT_BIND_MODE, "input_bind_mode") MSG_HASH(MENU_ENUM_LABEL_INPUT_BIND_TIMEOUT, diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index 04882dbf40..75a1c84608 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -626,8 +626,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "Gun D-pad Right") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Autoconfiguratie Activeren") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Analoge As Deadzone") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Menu Swap OK & Cancel Buttons") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2205,10 +2203,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Synchroniseer audio. Aangeraden." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "How far an axis must be tilted to result in a button press." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Amount of seconds to wait until proceeding to the next bind." diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index a6c7d7405e..df5f811da6 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -763,8 +763,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "D-pad prawo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Włącz autoconfig") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Martwa strefa gałki analogowej") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Zamień przyciski menu ok i anuluj") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2500,10 +2498,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Synchronizuj dźwięk. Zalecane." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "Jak daleko oś musi być przechylona, aby spowodować naciśnięcie przycisku." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Ilość sekund oczekiwania na przejście do następnej więzi." diff --git a/intl/msg_hash_pt_br.c b/intl/msg_hash_pt_br.c index dff66b5f81..a6a5ef24e5 100644 --- a/intl/msg_hash_pt_br.c +++ b/intl/msg_hash_pt_br.c @@ -1533,14 +1533,6 @@ int menu_hash_get_help_pt_br_enum(enum msg_hash_enums msg, char *s, size_t len) "Quando está em Câmera Lenta, o conteúdo será \n" "diminuído pelo fator especificado/definido."); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "Define a zona morta do controle analógico. \n" - " \n" - "Até que ponto um eixo deve ser \n" - "movido para resultar em um botão pressionado. \n" - "Os valores aceitos são entre [0.0, 1.0]."); - break; case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: snprintf(s, len, "Período do turbo.\n" diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index e7ff535699..01c28608ff 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -1053,10 +1053,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Habilitar Auto Configuração" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Zona Morta do Controle Analógico" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Inverter Botões OK e Cancelar do Menu" @@ -4759,10 +4755,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Sincroniza o áudio. Recomendado." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "Até que ponto um eixo deve ser movido para resultar em um botão pressionado." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Quantidade de segundos para aguardar até proceder para o próximo vínculo." diff --git a/intl/msg_hash_pt_pt.c b/intl/msg_hash_pt_pt.c index bfb24b202f..416f592a56 100644 --- a/intl/msg_hash_pt_pt.c +++ b/intl/msg_hash_pt_pt.c @@ -781,14 +781,6 @@ int menu_hash_get_help_pt_pt_enum(enum msg_hash_enums msg, char *s, size_t len) "Quando ativo, o conteúdo será executado numa velocidade\n" "reduzida por esse fator."); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "Define o limite de eixo.\n" - " \n" - "Representa o valor que deve ser atingido para\n" - "significar o pressionamento de um botão.\n" - " Valores possíveis são [0.0, 1.0]."); - break; case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: snprintf(s, len, "Período de turbo.\n" diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h index fe3270ce50..5126656377 100644 --- a/intl/msg_hash_pt_pt.h +++ b/intl/msg_hash_pt_pt.h @@ -689,8 +689,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "Botão direcional (direita) da pistola") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Ativar auto-configuração de teclas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Zona morta do eixo analógico") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Menu trocar botões OK e Cancelar") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2289,10 +2287,6 @@ MSG_HASH( MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Sincronizar o som. Recomendado.") -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "Até que ponto um eixo deve estar inclinado para causar o pressionamento de um botão." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Quantidade de segundos a aguardar até que seja feita uma nova associação." diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index 589c08e3bb..2a6a556462 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -710,8 +710,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "Gun D-pad Right") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Автоматическая настройка включена") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Мертвая зона у стиков") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Поменять кнопки OK и Отмена") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2347,10 +2345,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Синхронизировать звук. Рекомендуется." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "Как далеко ось должна быть наклонена, чтобы вызвать нажатие кнопки." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Количество секунд ожидания до перехода к следующей привязке." diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index 384ab23163..49a52aea3f 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -1572,9 +1572,9 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) "When slowmotion, content will slow\n" "down by factor."); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: + case MENU_ENUM_LABEL_INPUT_BUTTON_AXIS_THRESHOLD: snprintf(s, len, - "Defines axis threshold.\n" + "Defines the axis threshold.\n" " \n" "How far an axis must be tilted to result\n" "in a button press.\n" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 85f8d5e911..c92239d3c0 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1054,8 +1054,16 @@ MSG_HASH( "Autoconfig" ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Analog Stick Deadzone" + MENU_ENUM_LABEL_VALUE_INPUT_BUTTON_AXIS_THRESHOLD, + "Input Button Axis Threshold" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_DEADZONE, + "Analog Deadzone" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_SENSITIVITY, + "Analog Sensitivity" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, @@ -4967,7 +4975,7 @@ MSG_HASH( "Synchronize audio. Recommended." ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, + MENU_ENUM_SUBLABEL_INPUT_BUTTON_AXIS_THRESHOLD, "How far an axis must be tilted to result in a button press." ) MSG_HASH( diff --git a/intl/msg_hash_vn.c b/intl/msg_hash_vn.c index 371a7d2e40..c32c016710 100644 --- a/intl/msg_hash_vn.c +++ b/intl/msg_hash_vn.c @@ -1476,14 +1476,6 @@ int menu_hash_get_help_vn_enum(enum msg_hash_enums msg, char *s, size_t len) "When slowmotion, content will slow\n" "down by factor."); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "Defines axis threshold.\n" - " \n" - "How far an axis must be tilted to result\n" - "in a button press.\n" - " Possible values are [0.0, 1.0]."); - break; case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: snprintf(s, len, "Turbo period.\n" diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h index 1b43b88163..ef5597c2d8 100644 --- a/intl/msg_hash_vn.h +++ b/intl/msg_hash_vn.h @@ -701,8 +701,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, "Gun D-pad Right") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Kích hoạt Autoconfig") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Analog Stick Deadzone") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, "Menu Swap OK & Cancel Buttons") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, @@ -2337,10 +2335,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, "Synchronize audio. Recommended." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "How far an axis must be tilted to result in a button press." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, "Amount of seconds to wait until proceeding to the next bind." diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index de341c3a1e..e576a1748e 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -168,7 +168,7 @@ default_sublabel_macro(action_bind_sublabel_input_bind_hold, MENU_ default_sublabel_macro(action_bind_sublabel_audio_volume, MENU_ENUM_SUBLABEL_AUDIO_VOLUME) default_sublabel_macro(action_bind_sublabel_audio_mixer_volume, MENU_ENUM_SUBLABEL_AUDIO_MIXER_VOLUME) default_sublabel_macro(action_bind_sublabel_audio_sync, MENU_ENUM_SUBLABEL_AUDIO_SYNC) -default_sublabel_macro(action_bind_sublabel_axis_threshold, MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD) +default_sublabel_macro(action_bind_sublabel_axis_threshold, MENU_ENUM_SUBLABEL_INPUT_BUTTON_AXIS_THRESHOLD) default_sublabel_macro(action_bind_sublabel_input_turbo_period, MENU_ENUM_SUBLABEL_INPUT_TURBO_PERIOD) default_sublabel_macro(action_bind_sublabel_input_duty_cycle, MENU_ENUM_SUBLABEL_INPUT_DUTY_CYCLE) default_sublabel_macro(action_bind_sublabel_video_vertical_sync, MENU_ENUM_SUBLABEL_VIDEO_VSYNC) @@ -2028,7 +2028,7 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_INPUT_BIND_HOLD: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_bind_hold); break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: + case MENU_ENUM_LABEL_INPUT_BUTTON_AXIS_THRESHOLD: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_axis_threshold); break; case MENU_ENUM_LABEL_AUDIO_SYNC: diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index c2038ea153..b676b05a67 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -7130,7 +7130,11 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_DESCRIPTOR_HIDE_UNBOUND, PARSE_ONLY_BOOL, false); ret = menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD, PARSE_ONLY_FLOAT, false); + MENU_ENUM_LABEL_INPUT_BUTTON_AXIS_THRESHOLD, PARSE_ONLY_FLOAT, false); + ret = menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_INPUT_ANALOG_DEADZONE, PARSE_ONLY_FLOAT, false); + ret = menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_INPUT_ANALOG_SENSITIVITY, PARSE_ONLY_FLOAT, false); ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_BIND_TIMEOUT, PARSE_ONLY_UINT, false); ret = menu_displaylist_parse_settings_enum(menu, info, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 3b03386ba5..de1a0aaaae 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -7313,8 +7313,8 @@ static bool setting_append_list( CONFIG_FLOAT( list, list_info, input_driver_get_float(INPUT_ACTION_AXIS_THRESHOLD), - MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD, - MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, + MENU_ENUM_LABEL_INPUT_BUTTON_AXIS_THRESHOLD, + MENU_ENUM_LABEL_VALUE_INPUT_BUTTON_AXIS_THRESHOLD, axis_threshold, "%.3f", &group_info, @@ -7323,9 +7323,39 @@ static bool setting_append_list( general_write_handler, general_read_handler); (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; - menu_settings_list_current_add_range(list, list_info, 0, 1.00, 0.001, true, true); + menu_settings_list_current_add_range(list, list_info, 0, 1.0, 0.01, true, true); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + CONFIG_FLOAT( + list, list_info, + &settings->floats.input_analog_deadzone, + MENU_ENUM_LABEL_INPUT_ANALOG_DEADZONE, + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_DEADZONE, + analog_deadzone, + "%.1f", + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; + menu_settings_list_current_add_range(list, list_info, 0, 1.0, 0.1, true, true); + + CONFIG_FLOAT( + list, list_info, + &settings->floats.input_analog_sensitivity, + MENU_ENUM_LABEL_INPUT_ANALOG_SENSITIVITY, + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_SENSITIVITY, + analog_sensitivity, + "%.1f", + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; + menu_settings_list_current_add_range(list, list_info, -5.0, 5.0, 0.1, true, true); + CONFIG_UINT( list, list_info, &settings->uints.input_bind_timeout, diff --git a/msg_hash.h b/msg_hash.h index 89c58939c1..789f216e03 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -750,7 +750,9 @@ enum msg_hash_enums MENU_LABEL(INPUT_AUTODETECT_ENABLE), MENU_LABEL(INPUT_DESCRIPTOR_LABEL_SHOW), MENU_LABEL(INPUT_DESCRIPTOR_HIDE_UNBOUND), - MENU_LABEL(INPUT_AXIS_THRESHOLD), + MENU_LABEL(INPUT_BUTTON_AXIS_THRESHOLD), + MENU_LABEL(INPUT_ANALOG_DEADZONE), + MENU_LABEL(INPUT_ANALOG_SENSITIVITY), MENU_LABEL(INPUT_BIND_TIMEOUT), MENU_LABEL(INPUT_BIND_HOLD), MENU_LABEL(INPUT_REMAP_BINDS_ENABLE), diff --git a/retroarch.cfg b/retroarch.cfg index a996f1c8bd..9d7c109bfe 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -375,6 +375,10 @@ # Defines axis threshold. Possible values are [0.0, 1.0] # input_axis_threshold = 0.5 +# input_analog_deadzone = 0.0 + +# input_analog_sensitivity = 1.0 + # Enable input auto-detection. Will attempt to autoconfigure # joypads, Plug-and-Play style. # input_autodetect_enable = true From 2e125cd608a0c3afde1524685afa4e8cb8f5b757 Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Tue, 26 Mar 2019 08:01:01 -0400 Subject: [PATCH 089/237] update Chinese (Simplified) per asakous --- intl/msg_hash_chs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index def741c539..e5a12a2515 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -1251,11 +1251,11 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, "性能计数器") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, - "戏列表") + "游戏列表") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "戏列表文件夹") + "游戏列表文件夹") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, - "戏列表") + "游戏列表") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, "触摸支持") MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, From bd6fedc0f29d616e5fae44bd69370eb50910a04e Mon Sep 17 00:00:00 2001 From: CozmoP <25121396+CozmoP@users.noreply.github.com> Date: Wed, 27 Mar 2019 02:37:34 +0100 Subject: [PATCH 090/237] Qt: WIP settings dialog --- Makefile.common | 69 +- config.def.h | 6 +- configuration.c | 2 + griffin/griffin.c | 3 +- griffin/griffin_cpp.cpp | 23 + pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj | 102 +- retroarch.c | 6 +- ui/drivers/qt/options/achievements.cpp | 48 + ui/drivers/qt/options/audio.cpp | 94 ++ ui/drivers/qt/options/configuration.cpp | 38 + ui/drivers/qt/options/core.cpp | 38 + ui/drivers/qt/options/directory.cpp | 58 + ui/drivers/qt/options/drivers.cpp | 45 + ui/drivers/qt/options/input.cpp | 162 +++ ui/drivers/qt/options/latency.cpp | 57 + ui/drivers/qt/options/logging.cpp | 37 + ui/drivers/qt/options/network.cpp | 171 +++ ui/drivers/qt/options/options.h | 537 ++++++++ ui/drivers/qt/options/osd.cpp | 95 ++ ui/drivers/qt/options/playlists.cpp | 43 + ui/drivers/qt/options/recording.cpp | 57 + ui/drivers/qt/options/saving.cpp | 65 + ui/drivers/qt/options/throttle.cpp | 62 + ui/drivers/qt/options/ui.cpp | 288 ++++ ui/drivers/qt/options/user.cpp | 76 ++ ui/drivers/qt/options/video.cpp | 337 +++++ ui/drivers/qt/settingswidgets.cpp | 1187 +++++++++++++++++ ui/drivers/qt/settingswidgets.h | 421 ++++++ ui/drivers/qt/ui_qt_themes.h | 9 +- ui/drivers/qt/ui_qt_window.cpp | 3 + ui/drivers/qt/viewoptionsdialog.cpp | 243 +++- ui/drivers/qt/viewoptionsdialog.h | 44 +- 32 files changed, 4349 insertions(+), 77 deletions(-) create mode 100644 ui/drivers/qt/options/achievements.cpp create mode 100644 ui/drivers/qt/options/audio.cpp create mode 100644 ui/drivers/qt/options/configuration.cpp create mode 100644 ui/drivers/qt/options/core.cpp create mode 100644 ui/drivers/qt/options/directory.cpp create mode 100644 ui/drivers/qt/options/drivers.cpp create mode 100644 ui/drivers/qt/options/input.cpp create mode 100644 ui/drivers/qt/options/latency.cpp create mode 100644 ui/drivers/qt/options/logging.cpp create mode 100644 ui/drivers/qt/options/network.cpp create mode 100644 ui/drivers/qt/options/options.h create mode 100644 ui/drivers/qt/options/osd.cpp create mode 100644 ui/drivers/qt/options/playlists.cpp create mode 100644 ui/drivers/qt/options/recording.cpp create mode 100644 ui/drivers/qt/options/saving.cpp create mode 100644 ui/drivers/qt/options/throttle.cpp create mode 100644 ui/drivers/qt/options/ui.cpp create mode 100644 ui/drivers/qt/options/user.cpp create mode 100644 ui/drivers/qt/options/video.cpp create mode 100644 ui/drivers/qt/settingswidgets.cpp create mode 100644 ui/drivers/qt/settingswidgets.h diff --git a/Makefile.common b/Makefile.common index 1923f238a9..3d51f1591e 100644 --- a/Makefile.common +++ b/Makefile.common @@ -102,9 +102,9 @@ ifeq ($(HAVE_NETPLAYDISCOVERY), 1) endif ifeq ($(HAVE_NETLOGGER), 1) - DEF_FLAGS += -DHAVE_LOGGER - DEFINES += -DHAVE_LOGGER - OBJ += network/net_logger.o + DEF_FLAGS += -DHAVE_LOGGER + DEFINES += -DHAVE_LOGGER + OBJ += network/net_logger.o endif # System @@ -357,6 +357,27 @@ ifeq ($(HAVE_QT), 1) ui/drivers/qt/thumbnaildownload.o \ ui/drivers/qt/thumbnailpackdownload.o \ ui/drivers/qt/playlistthumbnaildownload.o + ifeq ($(HAVE_MENU), 1) + OBJ += ui/drivers/qt/settingswidgets.o \ + ui/drivers/qt/options/achievements.o \ + ui/drivers/qt/options/audio.o \ + ui/drivers/qt/options/configuration.o \ + ui/drivers/qt/options/core.o \ + ui/drivers/qt/options/directory.o \ + ui/drivers/qt/options/drivers.o \ + ui/drivers/qt/options/input.o \ + ui/drivers/qt/options/latency.o \ + ui/drivers/qt/options/logging.o \ + ui/drivers/qt/options/network.o \ + ui/drivers/qt/options/osd.o \ + ui/drivers/qt/options/playlists.o \ + ui/drivers/qt/options/recording.o \ + ui/drivers/qt/options/saving.o \ + ui/drivers/qt/options/throttle.o \ + ui/drivers/qt/options/ui.o \ + ui/drivers/qt/options/user.o \ + ui/drivers/qt/options/video.o + endif MOC_HEADERS += ui/drivers/ui_qt.h \ ui/drivers/qt/ui_qt_load_core_window.h \ @@ -367,6 +388,10 @@ ifeq ($(HAVE_QT), 1) ui/drivers/qt/coreinfodialog.h \ ui/drivers/qt/playlistentrydialog.h \ ui/drivers/qt/viewoptionsdialog.h + ifeq ($(HAVE_MENU), 1) + MOC_HEADERS += ui/drivers/qt/settingswidgets.h \ + ui/drivers/qt/options/options.h + endif DEFINES += $(QT5CORE_CFLAGS) $(QT5GUI_CFLAGS) $(QT5WIDGETS_CFLAGS) $(QT5CONCURRENT_CFLAGS) $(QT5NETWORK_CFLAGS) -DHAVE_MAIN #DEFINES += $(QT5WEBENGINE_CFLAGS) @@ -519,16 +544,16 @@ endif ifeq ($(HAVE_COREAUDIO), 1) OBJ += audio/drivers/coreaudio.o - HAVE_COREAUDIO_LIBS = 1 + HAVE_COREAUDIO_LIBS = 1 endif ifeq ($(HAVE_COREAUDIO3), 1) OBJ += audio/drivers/coreaudio3.o - HAVE_COREAUDIO_LIBS = 1 + HAVE_COREAUDIO_LIBS = 1 endif ifeq ($(HAVE_COREAUDIO_LIBS), 1) - LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit + LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit endif ifeq ($(HAVE_CORETEXT), 1) @@ -796,8 +821,8 @@ ifeq ($(HAVE_MENU_COMMON), 1) menu/menu_thumbnail_path.o ifeq ($(HAVE_MENU_COMMON),1) - OBJ += menu/drivers_display/menu_display_null.o - endif + OBJ += menu/drivers_display/menu_display_null.o + endif ifeq ($(HAVE_MENU_WIDGETS), 1) OBJ += menu/widgets/menu_widgets.o @@ -807,8 +832,8 @@ endif ifeq ($(HAVE_OVERLAY), 1) DEFINES += -DHAVE_OVERLAY OBJ += tasks/task_overlay.o \ - input/input_overlay.o \ - led/drivers/led_overlay.o + input/input_overlay.o \ + led/drivers/led_overlay.o endif ifeq ($(HAVE_STB_FONT), 1) @@ -895,11 +920,11 @@ endif ifeq ($(HAVE_WAYLAND), 1) OBJ += gfx/drivers_context/wayland_ctx.o \ - input/drivers/wayland_input.o \ - gfx/common/wayland/xdg-shell.o \ - gfx/common/wayland/xdg-shell-unstable-v6.o \ - gfx/common/wayland/idle-inhibit-unstable-v1.o \ - gfx/common/wayland/xdg-decoration-unstable-v1.o + input/drivers/wayland_input.o \ + gfx/common/wayland/xdg-shell.o \ + gfx/common/wayland/xdg-shell-unstable-v6.o \ + gfx/common/wayland/idle-inhibit-unstable-v1.o \ + gfx/common/wayland/xdg-decoration-unstable-v1.o ifeq ($(HAVE_EGL), 1) LIBS += $(EGL_LIBS) endif @@ -1174,7 +1199,7 @@ ifeq ($(HAVE_GL_CONTEXT), 1) OBJ += gfx/drivers_context/cgl_ctx.o else ifneq ($(findstring Win32,$(OS)),) GL_LIBS := -lopengl32 -lgdi32 -lcomdlg32 - WANT_WGL=1 + WANT_WGL=1 endif LIBS += $(GL_LIBS) endif @@ -1347,8 +1372,8 @@ ifeq ($(HAVE_D3D11), 1) gfx/common/d3d11_common.o \ gfx/drivers_font/d3d11_font.o ifeq ($(HAVE_MENU_COMMON), 1) - OBJ += menu/drivers_display/menu_display_d3d11.o - endif + OBJ += menu/drivers_display/menu_display_d3d11.o + endif DEFINES += -DHAVE_D3D11 HAVE_SLANG = 1 HAVE_GLSLANG = 1 @@ -1669,8 +1694,8 @@ ifeq ($(HAVE_NETWORKING), 1) endif # Netplay - DEFINES += -DHAVE_NETWORK_CMD - OBJ += network/netplay/netplay_delta.o \ + DEFINES += -DHAVE_NETWORK_CMD + OBJ += network/netplay/netplay_delta.o \ network/netplay/netplay_frontend.o \ network/netplay/netplay_handshake.o \ network/netplay/netplay_init.o \ @@ -1822,8 +1847,8 @@ ifneq ($(findstring Win32,$(OS)),) gfx/display_servers/dispserv_win32.o ifeq ($(HAVE_MENU_COMMON), 1) - OBJ += menu/drivers_display/menu_display_gdi.o - endif + OBJ += menu/drivers_display/menu_display_gdi.o + endif LIBS += -lmsimg32 -lhid -lsetupapi endif diff --git a/config.def.h b/config.def.h index 3ceef8ad7e..bea3214896 100644 --- a/config.def.h +++ b/config.def.h @@ -720,13 +720,15 @@ static const bool playlist_sort_alphabetical = true; /* File format to use when writing playlists to disk */ static const bool playlist_use_old_format = false; +#ifdef HAVE_MENU /* Specify when to display 'core name' inline on playlist entries */ static const unsigned playlist_show_inline_core_name = PLAYLIST_INLINE_CORE_DISPLAY_HIST_FAV; -static const bool playlist_show_sublabels = false; - /* Specifies which runtime record to use on playlist sublabels */ static const unsigned playlist_sublabel_runtime_type = PLAYLIST_RUNTIME_PER_CORE; +#endif + +static const bool playlist_show_sublabels = false; /* Show Menu start-up screen on boot. */ static const bool default_menu_show_start_screen = true; diff --git a/configuration.c b/configuration.c index 02a7ed77d2..0757d735a0 100644 --- a/configuration.c +++ b/configuration.c @@ -1778,8 +1778,10 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("libnx_overclock", &settings->uints.libnx_overclock, true, SWITCH_DEFAULT_CPU_PROFILE, false); #endif +#ifdef HAVE_MENU SETTING_UINT("playlist_show_inline_core_name", &settings->uints.playlist_show_inline_core_name, true, playlist_show_inline_core_name, false); SETTING_UINT("playlist_sublabel_runtime_type", &settings->uints.playlist_sublabel_runtime_type, true, playlist_sublabel_runtime_type, false); +#endif *size = count; diff --git a/griffin/griffin.c b/griffin/griffin.c index 271878cdd6..49a36d7dde 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -1199,6 +1199,8 @@ PLAYLISTS /*============================================================ MENU ============================================================ */ +#include "../menu/menu_shader.c" + #ifdef HAVE_MENU #include "../menu/menu_driver.c" #include "../menu/menu_input.c" @@ -1235,7 +1237,6 @@ MENU #include "../menu/cbs/menu_cbs_up.c" #include "../menu/cbs/menu_cbs_down.c" #include "../menu/cbs/menu_cbs_contentlist_switch.c" -#include "../menu/menu_shader.c" #include "../menu/menu_displaylist.c" #include "../menu/menu_animation.c" #include "../menu/menu_thumbnail_path.c" diff --git a/griffin/griffin_cpp.cpp b/griffin/griffin_cpp.cpp index 6b90c1b80f..06fb0f002d 100644 --- a/griffin/griffin_cpp.cpp +++ b/griffin/griffin_cpp.cpp @@ -58,6 +58,29 @@ UI #include "../ui/drivers/qt/thumbnaildownload.cpp" #include "../ui/drivers/qt/thumbnailpackdownload.cpp" #include "../ui/drivers/qt/playlistthumbnaildownload.cpp" +#ifdef HAVE_MENU +#include "../ui/drivers/qt/settingswidgets.cpp" +#include "../ui/drivers/qt/options/drivers.cpp" +#include "../ui/drivers/qt/options/video.cpp" +#include "../ui/drivers/qt/options/audio.cpp" +#include "../ui/drivers/qt/options/saving.cpp" +#include "../ui/drivers/qt/options/throttle.cpp" +#include "../ui/drivers/qt/options/osd.cpp" +#include "../ui/drivers/qt/options/input.cpp" +#include "../ui/drivers/qt/options/directory.cpp" +#include "../ui/drivers/qt/options/logging.cpp" +#include "../ui/drivers/qt/options/core.cpp" +#include "../ui/drivers/qt/options/configuration.cpp" +#include "../ui/drivers/qt/options/latency.cpp" +#include "../ui/drivers/qt/options/playlists.cpp" +#include "../ui/drivers/qt/options/user.cpp" +#include "../ui/drivers/qt/options/recording.cpp" +#include "../ui/drivers/qt/options/ui.cpp" +#include "../ui/drivers/qt/options/achievements.cpp" +#include "../ui/drivers/qt/options/network.cpp" +#include "../ui/drivers/qt/moc_settingswidgets.cpp" +#include "../ui/drivers/qt/options/moc_options.cpp" +#endif #include "../ui/drivers/moc_ui_qt.cpp" #include "../ui/drivers/qt/moc_coreinfodialog.cpp" #include "../ui/drivers/qt/moc_coreoptionsdialog.cpp" diff --git a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj index 16c6f3169e..bc1950ce50 100644 --- a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj +++ b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj @@ -1814,7 +1814,107 @@ true true true - + + + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + false + false + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + false + false + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + true + true + true + true + true + true + true + true + + + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + false + false + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + false + false + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "%(RootDir)%(Directory)moc_%(Filename).cpp" + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + QT: Generate %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + %(RootDir)%(Directory)moc_%(Filename).cpp + false + false + true + true + true + true + true + true + true + true + diff --git a/retroarch.c b/retroarch.c index a1308602a7..3b8df25823 100644 --- a/retroarch.c +++ b/retroarch.c @@ -4897,13 +4897,15 @@ bool rarch_write_debug_info(void) gfx_ctx_ident_t ident_info = {0}; const input_driver_t *input_driver; const input_device_driver_t *joypad_driver; - const char *driver = menu_driver_ident(); + const char *driver; +#ifdef HAVE_MENU + driver = menu_driver_ident(); if (string_is_equal(driver, settings->arrays.menu_driver)) filestream_printf(file, " - Menu: %s\n", !string_is_empty(driver) ? driver : "n/a"); else filestream_printf(file, " - Menu: %s (configured for %s)\n", !string_is_empty(driver) ? driver : "n/a", !string_is_empty(settings->arrays.menu_driver) ? settings->arrays.menu_driver : "n/a"); - +#endif driver = #ifdef HAVE_THREADS (video_driver_is_threaded()) ? diff --git a/ui/drivers/qt/options/achievements.cpp b/ui/drivers/qt/options/achievements.cpp new file mode 100644 index 0000000000..76d0acf81f --- /dev/null +++ b/ui/drivers/qt/options/achievements.cpp @@ -0,0 +1,48 @@ +#include "options.h" + +AchievementsCategory::AchievementsCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS); + setCategoryIcon("menu_achievements"); +} + +QVector AchievementsCategory::pages() +{ + QVector pages; + + pages << new AchievementsPage(this); + + return pages; +} + +AchievementsPage::AchievementsPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *AchievementsPage::widget() +{ + QWidget *widget = new QWidget; + + QVBoxLayout *layout = new QVBoxLayout; + + CheckableSettingsGroup *group = new CheckableSettingsGroup(MENU_ENUM_LABEL_CHEEVOS_ENABLE); + + group->addStringLineEdit(MENU_ENUM_LABEL_CHEEVOS_USERNAME); + group->addPasswordLineEdit(MENU_ENUM_LABEL_CHEEVOS_PASSWORD); + group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE); + group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE); + group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE); + group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_TEST_UNOFFICIAL); + group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_VERBOSE_ENABLE); + group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_AUTO_SCREENSHOT); + + layout->addWidget(group); + + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/audio.cpp b/ui/drivers/qt/options/audio.cpp new file mode 100644 index 0000000000..0ba87ed664 --- /dev/null +++ b/ui/drivers/qt/options/audio.cpp @@ -0,0 +1,94 @@ +#include + +#include "options.h" + +AudioCategory::AudioCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS); + setCategoryIcon("menu_audio"); +} + +QVector AudioCategory::pages() +{ + QVector pages; + + pages << new AudioPage(this); + pages << new MenuSoundsPage(this); + + return pages; +} + +AudioPage::AudioPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *AudioPage::widget() +{ + QWidget *widget = new QWidget; + + QVBoxLayout *layout = new QVBoxLayout; + + SettingsGroup *outputGroup = new SettingsGroup("Output"); + SettingsGroup *resamplerGroup = new SettingsGroup("Resampler"); + SettingsGroup *syncGroup = new SettingsGroup("Synchronization"); + SettingsGroup *dspGroup = new SettingsGroup("DSP plugin"); + SettingsGroup *volumeGroup = new SettingsGroup("Volume"); + + QHBoxLayout *volumeLayout = new QHBoxLayout(); + + outputGroup->addCheckBox(MENU_ENUM_LABEL_AUDIO_ENABLE); + outputGroup->addStringComboBox(MENU_ENUM_LABEL_AUDIO_DRIVER); + outputGroup->addStringLineEdit(MENU_ENUM_LABEL_AUDIO_DEVICE); + outputGroup->addUIntSpinBox(MENU_ENUM_LABEL_AUDIO_LATENCY); + + resamplerGroup->addStringComboBox(MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER); + resamplerGroup->addUIntComboBox(MENU_ENUM_LABEL_AUDIO_RESAMPLER_QUALITY); + resamplerGroup->addUIntSpinBox(MENU_ENUM_LABEL_AUDIO_OUTPUT_RATE); + + syncGroup->addCheckBox(MENU_ENUM_LABEL_AUDIO_SYNC); + syncGroup->addFloatSpinBox(MENU_ENUM_LABEL_AUDIO_MAX_TIMING_SKEW); + syncGroup->addFloatSpinBox(MENU_ENUM_LABEL_AUDIO_RATE_CONTROL_DELTA); + + dspGroup->addFileSelector(MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN); + + volumeLayout->addWidget(new CheckableIcon(MENU_ENUM_LABEL_AUDIO_MUTE, qApp->style()->standardIcon(QStyle::SP_MediaVolumeMuted))); + volumeLayout->addLayout(new FloatSliderAndSpinBox(MENU_ENUM_LABEL_AUDIO_VOLUME)); + volumeGroup->addRow(volumeLayout); + + layout->addWidget(outputGroup); + layout->addWidget(resamplerGroup); + layout->addWidget(syncGroup); + layout->addWidget(dspGroup); + layout->addWidget(volumeGroup); + + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} + +MenuSoundsPage::MenuSoundsPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_MENU_SOUNDS); +} + +QWidget *MenuSoundsPage::widget() +{ + QWidget *widget = new QWidget(); + + FormLayout *layout = new FormLayout; + + layout->addCheckBox(MENU_ENUM_LABEL_AUDIO_ENABLE_MENU); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_SOUND_OK); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_SOUND_CANCEL); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_SOUND_NOTICE); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_SOUND_BGM); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/configuration.cpp b/ui/drivers/qt/options/configuration.cpp new file mode 100644 index 0000000000..017bb97cb5 --- /dev/null +++ b/ui/drivers/qt/options/configuration.cpp @@ -0,0 +1,38 @@ +#include "options.h" + +ConfigurationCategory::ConfigurationCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS); + setCategoryIcon("setting"); +} + +QVector ConfigurationCategory::pages() +{ + QVector pages; + + pages << new ConfigurationPage(this); + + return pages; +} + +ConfigurationPage::ConfigurationPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *ConfigurationPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addCheckBox(MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT); + layout->addCheckBox(MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS); + layout->addCheckBox(MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE); + layout->addCheckBox(MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/core.cpp b/ui/drivers/qt/options/core.cpp new file mode 100644 index 0000000000..755ffced3a --- /dev/null +++ b/ui/drivers/qt/options/core.cpp @@ -0,0 +1,38 @@ +#include "options.h" + +CoreCategory::CoreCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_CORE_SETTINGS); + setCategoryIcon("core-options"); +} + +QVector CoreCategory::pages() +{ + QVector pages; + + pages << new CorePage(this); + + return pages; +} + +CorePage::CorePage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *CorePage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addCheckBox(MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT); + layout->addCheckBox(MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN); + layout->addCheckBox(MENU_ENUM_LABEL_CHECK_FOR_MISSING_FIRMWARE); + layout->addCheckBox(MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/directory.cpp b/ui/drivers/qt/options/directory.cpp new file mode 100644 index 0000000000..c665096393 --- /dev/null +++ b/ui/drivers/qt/options/directory.cpp @@ -0,0 +1,58 @@ +#include "options.h" + +DirectoryCategory::DirectoryCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS); + setCategoryIcon("folder"); +} + +QVector DirectoryCategory::pages() +{ + QVector pages; + + pages << new DirectoryPage(this); + + return pages; +} + +DirectoryPage::DirectoryPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *DirectoryPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addDirectorySelector(MENU_ENUM_LABEL_CORE_ASSETS_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_ASSETS_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_DYNAMIC_WALLPAPERS_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_RGUI_CONFIG_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_LIBRETRO_DIR_PATH); + layout->addDirectorySelector(MENU_ENUM_LABEL_LIBRETRO_INFO_PATH); + layout->addDirectorySelector(MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_CURSOR_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_CHEAT_DATABASE_PATH); + layout->addDirectorySelector(MENU_ENUM_LABEL_VIDEO_FILTER_DIR); + layout->addDirectorySelector(MENU_ENUM_LABEL_AUDIO_FILTER_DIR); + layout->addDirectorySelector(MENU_ENUM_LABEL_VIDEO_SHADER_DIR); + layout->addDirectorySelector(MENU_ENUM_LABEL_RECORDING_OUTPUT_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_RECORDING_CONFIG_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_OVERLAY_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_SCREENSHOT_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_JOYPAD_AUTOCONFIG_DIR); + layout->addDirectorySelector(MENU_ENUM_LABEL_INPUT_REMAPPING_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_PLAYLIST_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_SAVEFILE_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_SAVESTATE_DIRECTORY); + layout->addDirectorySelector(MENU_ENUM_LABEL_CACHE_DIRECTORY); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/drivers.cpp b/ui/drivers/qt/options/drivers.cpp new file mode 100644 index 0000000000..64db8534ab --- /dev/null +++ b/ui/drivers/qt/options/drivers.cpp @@ -0,0 +1,45 @@ +#include "options.h" + +DriversCategory::DriversCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS); + setCategoryIcon("menu_drivers"); +} + +QVector DriversCategory::pages() +{ + QVector pages; + + pages << new DriversPage(this); + + return pages; +} + +DriversPage::DriversPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS); +} + +QWidget *DriversPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addStringComboBox(MENU_ENUM_LABEL_INPUT_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_JOYPAD_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_VIDEO_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_AUDIO_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_CAMERA_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_LOCATION_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_MENU_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_RECORD_DRIVER); + layout->addStringComboBox(MENU_ENUM_LABEL_MIDI_DRIVER); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/input.cpp b/ui/drivers/qt/options/input.cpp new file mode 100644 index 0000000000..54fa5ccca3 --- /dev/null +++ b/ui/drivers/qt/options/input.cpp @@ -0,0 +1,162 @@ +#include + +#include "options.h" + +#ifndef CXX_BUILD +extern "C" { +#endif + +#include "../../input/input_driver.h" + +#ifndef CXX_BUILD +} +#endif + +InputCategory::InputCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS); + setCategoryIcon("core-input-remapping-options"); +} + +QVector InputCategory::pages() +{ + QVector pages; + + pages << new InputPage(this); + pages << new HotkeyBindsPage(this); + + return pages; +} + +InputPage::InputPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *InputPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_MAX_USERS); + layout->addCheckBox(MENU_ENUM_LABEL_INPUT_UNIFIED_MENU_CONTROLS); + layout->addUIntComboBox(MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR); + layout->addUIntComboBox(MENU_ENUM_LABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_INPUT_SWAP_OK_CANCEL); + layout->addCheckBox(MENU_ENUM_LABEL_INPUT_ALL_USERS_CONTROL_MENU); + layout->addCheckBox(MENU_ENUM_LABEL_INPUT_REMAP_BINDS_ENABLE); + layout->addCheckBox(MENU_ENUM_LABEL_INPUT_AUTODETECT_ENABLE); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_INPUT_BUTTON_AXIS_THRESHOLD); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_INPUT_ANALOG_DEADZONE); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_INPUT_ANALOG_SENSITIVITY); + layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_BIND_TIMEOUT); + layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_BIND_HOLD); + layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_TURBO_PERIOD); + layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_DUTY_CYCLE); + + widget->setLayout(layout); + + return widget; +} + +HotkeyBindsPage::HotkeyBindsPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS); +} + +QWidget *HotkeyBindsPage::widget() +{ + QWidget *widget = new QWidget; + + QHBoxLayout *layout = new QHBoxLayout; + FormLayout *leftLayout = new FormLayout; + FormLayout *rightLayout = new FormLayout; + + unsigned i; + unsigned count = 0; + unsigned half = 40 / 2; /* TODO unhardcode */ + + for (i = 0; i < RARCH_BIND_LIST_END; i++) + { + if (count < half) + { + if (leftLayout->addBindButton((enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i))) + count++; + } + else + rightLayout->addBindButton((enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i)); + } + + layout->addLayout(leftLayout); + layout->addSpacing(50); + layout->addLayout(rightLayout); + + widget->setLayout(layout); + + return widget; +} + +UserBindsPage::UserBindsPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName("User Binds"); +} + +QWidget *UserBindsPage::widget() +{ + QWidget *widget = new QWidget; + + QGridLayout *layout = new QGridLayout; + + unsigned count = 0; + unsigned p, retro_id; + unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); + + QComboBox *userCombo = new QComboBox; + QStackedWidget *stack = new QStackedWidget; + + for (p = 0; p < max_users; p++) + { + userCombo->addItem(QString::number(p)); + + QWidget *uWidget = new QWidget(); + FormLayout *form = new FormLayout(); + + for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND + 20; retro_id++) + { + char descriptor[300]; + const struct retro_keybind *auto_bind = NULL; + const struct retro_keybind *keybind = NULL; + + keybind = &input_config_binds[p][retro_id]; + + auto_bind = (const struct retro_keybind*) + input_config_get_bind_auto(p, retro_id); + + input_config_get_bind_string(descriptor, + keybind, auto_bind, sizeof(descriptor)); + + const struct retro_keybind *keyptr = + &input_config_binds[p][retro_id]; + + QString label = msg_hash_to_str(keyptr->enum_idx); + + form->addRow(QString(msg_hash_to_str(keyptr->enum_idx)), new QPushButton(QString(descriptor))); + } + uWidget->setLayout(form); + + stack->addWidget(uWidget); + } + + connect(userCombo, SIGNAL(activated(int)), stack, SLOT(setCurrentIndex(int))); + + layout->addWidget(userCombo, 0, 0); + layout->addWidget(stack, 1, 0); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/latency.cpp b/ui/drivers/qt/options/latency.cpp new file mode 100644 index 0000000000..664e0785a2 --- /dev/null +++ b/ui/drivers/qt/options/latency.cpp @@ -0,0 +1,57 @@ +#include "options.h" + +LatencyCategory::LatencyCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_LATENCY_SETTINGS); + setCategoryIcon("menu_latency"); +} + +QVector LatencyCategory::pages() +{ + QVector pages; + + pages << new LatencyPage(this); + + return pages; +} + +LatencyPage::LatencyPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *LatencyPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + CheckableSettingsGroup *runAheadGpuSync = new CheckableSettingsGroup(MENU_ENUM_LABEL_RUN_AHEAD_ENABLED); + + { + rarch_setting_t *hardSyncSetting = menu_setting_find_enum(MENU_ENUM_LABEL_VIDEO_HARD_SYNC); + + if (hardSyncSetting) + { + CheckableSettingsGroup *hardSyncGroup = new CheckableSettingsGroup(hardSyncSetting); + + hardSyncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES); + + layout->addRow(hardSyncGroup); + } + } + + layout->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_FRAME_DELAY); + layout->addUIntSpinBox(MENU_ENUM_LABEL_AUDIO_LATENCY); + layout->addUIntComboBox(MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR); + + runAheadGpuSync->addUIntComboBox(MENU_ENUM_LABEL_RUN_AHEAD_FRAMES); + runAheadGpuSync->addCheckBox(MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE); + runAheadGpuSync->addCheckBox(MENU_ENUM_LABEL_RUN_AHEAD_HIDE_WARNINGS); + layout->addRow(runAheadGpuSync); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/logging.cpp b/ui/drivers/qt/options/logging.cpp new file mode 100644 index 0000000000..734bb480b6 --- /dev/null +++ b/ui/drivers/qt/options/logging.cpp @@ -0,0 +1,37 @@ +#include "options.h" + +LoggingCategory::LoggingCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS); + setCategoryIcon("menu_log"); +} + +QVector LoggingCategory::pages() +{ + QVector pages; + + pages << new LoggingPage(this); + + return pages; +} + +LoggingPage::LoggingPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *LoggingPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addCheckBox(MENU_ENUM_LABEL_LOG_VERBOSITY); + layout->addUIntRadioButtons(MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL); + layout->addCheckBox(MENU_ENUM_LABEL_PERFCNT_ENABLE); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/network.cpp b/ui/drivers/qt/options/network.cpp new file mode 100644 index 0000000000..4d60da0790 --- /dev/null +++ b/ui/drivers/qt/options/network.cpp @@ -0,0 +1,171 @@ +#include + +#include "options.h" + +#ifndef CXX_BUILD +extern "C" { +#endif + +#include + +#include "../../network/netplay/netplay.h" + +#ifndef CXX_BUILD +} +#endif + +NetworkCategory::NetworkCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_NETWORK_SETTINGS); + setCategoryIcon("menu_network"); +} + +QVector NetworkCategory::pages() +{ + QVector pages; + + pages << new NetplayPage(this); + pages << new UpdaterPage(this); + + return pages; +} + +NetplayPage::NetplayPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_NETPLAY); +} + +QWidget *NetplayPage::widget() +{ + QWidget *widget = new QWidget; + QGridLayout *layout = new QGridLayout; + FormLayout *checksLayout = new FormLayout; + QGroupBox *serverGroup = new QGroupBox("Server"); + SettingsGroup *syncGroup = new SettingsGroup("Synchronization"); + SettingsGroup *slaveGroup = new SettingsGroup("Slave-Mode"); + SettingsGroup *inputGroup = new SettingsGroup("Input Sharing"); + SettingsGroup *deviceGroup = new SettingsGroup("Device Request"); + FormLayout *serverForm = new FormLayout; + QHBoxLayout *serverLayout = new QHBoxLayout; + QVBoxLayout *mainLayout = new QVBoxLayout; + QGridLayout *requestGrid = new QGridLayout; + unsigned i = 0; + unsigned row = 0; + unsigned column = 0; + + checksLayout->addCheckBox(MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE); + checksLayout->addCheckBox(MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR); + + serverForm->addStringLineEdit(MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS); + serverForm->addUIntSpinBox(MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT); + serverForm->addPasswordLineEdit(MENU_ENUM_LABEL_NETPLAY_PASSWORD); + serverForm->addPasswordLineEdit(MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD); + serverForm->addCheckBox(MENU_ENUM_LABEL_NETPLAY_NAT_TRAVERSAL); + + serverLayout->addWidget(createMitmServerGroup()); + serverLayout->addSpacing(30); + serverLayout->addLayout(serverForm); + + serverGroup->setLayout(serverLayout); + + slaveGroup->addCheckBox(MENU_ENUM_LABEL_NETPLAY_ALLOW_SLAVES); + slaveGroup->addCheckBox(MENU_ENUM_LABEL_NETPLAY_REQUIRE_SLAVES); + + syncGroup->addCheckBox(MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE); + syncGroup->addUIntSpinBox(MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES); + syncGroup->addUIntSpinBox(MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN); + syncGroup->addUIntSpinBox(MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE); + + inputGroup->addUIntComboBox(MENU_ENUM_LABEL_NETPLAY_SHARE_DIGITAL); + inputGroup->addUIntComboBox(MENU_ENUM_LABEL_NETPLAY_SHARE_ANALOG); + + for (i = 0; i < MAX_USERS; i++) + { + if (column % 4 == 0) + { + column = 0; + row++; + } + requestGrid->addWidget(new CheckBox((enum msg_hash_enums)(MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1 + i)), row, column); + column++; + } + + deviceGroup->addRow(requestGrid); + + layout->addLayout(checksLayout, 0, 0, 1, 2); + layout->addWidget(serverGroup, 1, 0, 1, 2); + layout->addWidget(slaveGroup, 2, 0, 1, 1); + layout->addWidget(syncGroup, 2, 1, 2, 1); + layout->addWidget(inputGroup, 3, 0, 1, 1); + layout->addWidget(deviceGroup, 4, 0, 1, 2); + + mainLayout->addLayout(layout); + + mainLayout->addStretch(); + + widget->setLayout(mainLayout); + + return widget; +} + +QGroupBox *NetplayPage::createMitmServerGroup() +{ + CheckableSettingsGroup *groupBox = new CheckableSettingsGroup(MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER); + QButtonGroup *buttonGroup = new QButtonGroup(this); + + rarch_setting_t *setting = menu_setting_find_enum(MENU_ENUM_LABEL_NETPLAY_MITM_SERVER); + + unsigned i; + unsigned list_len = ARRAY_SIZE(netplay_mitm_server_list); + + if (!setting) + return nullptr; + + for (i = 0; i < list_len; i++) + { + QRadioButton *radioButton = new QRadioButton(netplay_mitm_server_list[i].description); + + /* find the currently selected server in the list */ + if (string_is_equal(setting->value.target.string, netplay_mitm_server_list[i].name)) + { + radioButton->setChecked(true); + } + + buttonGroup->addButton(radioButton, i); + + groupBox->addRow(radioButton); + } + + connect(buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(onRadioButtonClicked(int))); + + return groupBox; +} + +void NetplayPage::onRadioButtonClicked(int id) +{ + rarch_setting_t *setting = menu_setting_find_enum(MENU_ENUM_LABEL_NETPLAY_MITM_SERVER); + + strlcpy(setting->value.target.string, netplay_mitm_server_list[id].name, setting->size); +} + +UpdaterPage::UpdaterPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS); +} + +QWidget *UpdaterPage::widget() +{ + QWidget *widget = new QWidget; + FormLayout *layout = new FormLayout; + + layout->addStringLineEdit(MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL); + layout->addStringLineEdit(MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL); + layout->addCheckBox(MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/options.h b/ui/drivers/qt/options/options.h new file mode 100644 index 0000000000..b2549f1964 --- /dev/null +++ b/ui/drivers/qt/options/options.h @@ -0,0 +1,537 @@ +#ifndef OPTIONS_H +#define OPTIONS_H + +#include +#include +#include +#include + +#include "../settingswidgets.h" + +class MainWindow; +class ViewOptionsWidget; + +class OptionsPage : public QObject +{ + Q_OBJECT + +public: + OptionsPage(QObject *parent = nullptr) + : QObject(parent) + { + } + + QString displayName() const + { + return m_displayName; + } + + virtual QWidget *widget() = 0; + virtual void load() {} + virtual void apply() {} + +protected: + void setDisplayName(msg_hash_enums name) + { + m_displayName = msg_hash_to_str(name); + } + + void setDisplayName(const QString& name) + { + m_displayName = name; + } + + QString m_displayName = "General"; +}; + +class OptionsCategory : public QObject +{ + Q_OBJECT +public: + OptionsCategory(QObject *parent = nullptr) : QObject(parent) {} + OptionsCategory(MainWindow *mainwindow, QObject *parent = nullptr) : QObject(parent) {} + virtual QVector pages() = 0; + QString displayName() const { return m_displayName; } + QString categoryIconName() const { return m_categoryIconName; } + virtual void load() + { + for (int i = 0; i < m_pages.size(); i++) + m_pages.at(i)->load(); + } + virtual void apply() + { + for (int i = 0; i < m_pages.size(); i++) + m_pages.at(i)->apply(); + } +protected: + void setDisplayName(msg_hash_enums name) { m_displayName = msg_hash_to_str(name); } + void setCategoryIcon(const QString &categoryIconName) { m_categoryIconName = categoryIconName; } + QString m_displayName; + QString m_categoryIconName = "setting"; + QVector m_pages; +}; + +/*********************************************************** + Drivers +************************************************************/ +class DriversCategory : public OptionsCategory +{ +public: + DriversCategory(QWidget *parent); + QVector pages(); +}; + +class DriversPage : public OptionsPage +{ + Q_OBJECT +public: + DriversPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Video +************************************************************/ +class VideoCategory : public OptionsCategory +{ +public: + VideoCategory(QWidget *parent); + QVector pages(); +}; + +class AspectRatioRadioButton : public QRadioButton +{ + Q_OBJECT +public: + AspectRatioRadioButton(unsigned min, unsigned max, QWidget *parent = 0); +private: + unsigned m_min; + unsigned m_max; +}; + +class AspectRatioGroup : public SettingsGroup +{ + Q_OBJECT +public: + AspectRatioGroup(const QString &title, QWidget *parent = 0); +private slots: + void paintEvent(QPaintEvent *event); + void onAspectRadioToggled(bool checked); + void onAspectRadioClicked(bool checked); +private: + AspectRatioRadioButton *m_radioButton; + UIntComboBox *m_comboBox; +}; + +class VideoPage : public OptionsPage +{ + Q_OBJECT +public: + VideoPage(QObject *parent = nullptr); + QWidget *widget(); +private slots: + void onResolutionComboIndexChanged(const QString& value); +private: + QComboBox *m_resolutionCombo; +}; + +class CrtSwitchresPage : public OptionsPage +{ + Q_OBJECT +public: + CrtSwitchresPage(QObject *parent = nullptr); + QWidget *widget(); +private slots: + void onCrtSuperResolutionComboIndexChanged(int index); +private: + QComboBox *m_crtSuperResolutionCombo; +}; + +/************************************************************ + Audio +************************************************************/ +class AudioCategory : public OptionsCategory +{ +public: + AudioCategory(QWidget *parent); + QVector pages(); +}; + +class AudioPage : public OptionsPage +{ + Q_OBJECT +public: + AudioPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class MenuSoundsPage : public OptionsPage +{ + Q_OBJECT +public: + MenuSoundsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Input +************************************************************/ +class InputCategory : public OptionsCategory +{ +public: + InputCategory(QWidget *parent); + QVector pages(); +}; + +class InputPage : public OptionsPage +{ + Q_OBJECT +public: + InputPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class HotkeyBindsPage : public OptionsPage +{ + Q_OBJECT +public: + HotkeyBindsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class UserBindsPage : public OptionsPage +{ + Q_OBJECT +public: + UserBindsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Latency +************************************************************/ +class LatencyCategory : public OptionsCategory +{ +public: + LatencyCategory(QWidget *parent); + QVector pages(); +}; + +class LatencyPage : public OptionsPage +{ + Q_OBJECT +public: + LatencyPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Core +************************************************************/ +class CoreCategory : public OptionsCategory +{ +public: + CoreCategory(QWidget *parent); + QVector pages(); +}; + +class CorePage : public OptionsPage +{ + Q_OBJECT +public: + CorePage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Configuration +************************************************************/ +class ConfigurationCategory : public OptionsCategory +{ +public: + ConfigurationCategory(QWidget *parent); + QVector pages(); +}; + +class ConfigurationPage : public OptionsPage +{ + Q_OBJECT +public: + ConfigurationPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Saving +************************************************************/ +class SavingCategory : public OptionsCategory +{ +public: + SavingCategory(QWidget *parent); + QVector pages(); +}; + +class SavingPage : public OptionsPage +{ + Q_OBJECT +public: + SavingPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Logging +************************************************************/ +class LoggingCategory : public OptionsCategory +{ +public: + LoggingCategory(QWidget *parent); + QVector pages(); +}; + +class LoggingPage : public OptionsPage +{ + Q_OBJECT +public: + LoggingPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Frame Throttle +************************************************************/ +class FrameThrottleCategory : public OptionsCategory +{ +public: + FrameThrottleCategory(QWidget *parent); + QVector pages(); +}; + +class FrameThrottlePage : public OptionsPage +{ + Q_OBJECT +public: + FrameThrottlePage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class RewindPage : public OptionsPage +{ + Q_OBJECT +public: + RewindPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Recording +************************************************************/ +class RecordingCategory : public OptionsCategory +{ +public: + RecordingCategory(QWidget *parent); + QVector pages(); +}; + +class RecordingPage : public OptionsPage +{ + Q_OBJECT +public: + RecordingPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + User Interface +************************************************************/ +class UserInterfaceCategory : public OptionsCategory +{ +public: + UserInterfaceCategory(QWidget *parent); + UserInterfaceCategory(MainWindow *mainwindow, QWidget *parent); + QVector pages(); +private: + MainWindow *m_mainwindow; +}; + +class UserInterfacePage : public OptionsPage +{ + Q_OBJECT +public: + UserInterfacePage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class ViewsPage : public OptionsPage +{ + Q_OBJECT +public: + ViewsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class QuickMenuPage : public OptionsPage +{ + Q_OBJECT +public: + QuickMenuPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class AppearancePage : public OptionsPage +{ + Q_OBJECT +public: + AppearancePage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class DesktopMenuPage : public OptionsPage +{ + Q_OBJECT +public: + DesktopMenuPage(MainWindow *mainwindow, QObject *parent = nullptr); + QWidget *widget(); + void load(); + void apply(); +private: + ViewOptionsWidget *m_widget; +}; + +/************************************************************ + Onscreen Display +************************************************************/ +class OnscreenDisplayCategory : public OptionsCategory +{ +public: + OnscreenDisplayCategory(QWidget *parent); + QVector pages(); +}; + +class OverlayPage : public OptionsPage +{ + Q_OBJECT +public: + OverlayPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class NotificationsPage : public OptionsPage +{ + Q_OBJECT +public: + NotificationsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Achievements +************************************************************/ +class AchievementsCategory : public OptionsCategory +{ +public: + AchievementsCategory(QWidget *parent); + QVector pages(); +}; + +class AchievementsPage : public OptionsPage +{ + Q_OBJECT +public: + AchievementsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Network +************************************************************/ +class NetworkCategory : public OptionsCategory +{ +public: + NetworkCategory(QWidget *parent); + QVector pages(); +}; + +class NetplayPage : public OptionsPage +{ + Q_OBJECT +public: + NetplayPage(QObject *parent = nullptr); + QWidget *widget(); +private slots: + void onRadioButtonClicked(int); +private: + QGroupBox* createMitmServerGroup(); +}; + +class UpdaterPage : public OptionsPage +{ + Q_OBJECT +public: + UpdaterPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Playlists +************************************************************/ +class PlaylistsCategory : public OptionsCategory +{ +public: + PlaylistsCategory(QWidget *parent); + QVector pages(); +}; + +class PlaylistsPage : public OptionsPage +{ + Q_OBJECT +public: + PlaylistsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +class AccountsPage : public OptionsPage +{ + Q_OBJECT +public: + AccountsPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + User +************************************************************/ +class UserCategory : public OptionsCategory +{ +public: + UserCategory(QWidget *parent); + QVector pages(); +}; + +class UserPage : public OptionsPage +{ + Q_OBJECT +public: + UserPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +/************************************************************ + Directory +************************************************************/ +class DirectoryCategory : public OptionsCategory +{ +public: + DirectoryCategory(QWidget *parent); + QVector pages(); +}; + +class DirectoryPage : public OptionsPage +{ + Q_OBJECT +public: + DirectoryPage(QObject *parent = nullptr); + QWidget *widget(); +}; + +#endif diff --git a/ui/drivers/qt/options/osd.cpp b/ui/drivers/qt/options/osd.cpp new file mode 100644 index 0000000000..311f07c894 --- /dev/null +++ b/ui/drivers/qt/options/osd.cpp @@ -0,0 +1,95 @@ +#include "options.h" + +OnscreenDisplayCategory::OnscreenDisplayCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS); + setCategoryIcon("menu_osd"); +} + +QVector OnscreenDisplayCategory::pages() +{ + QVector pages; + + pages << new OverlayPage(this); + pages << new NotificationsPage(this); + + return pages; +} + +NotificationsPage::NotificationsPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS); +} + +QWidget *NotificationsPage::widget() +{ + QWidget *widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; + + CheckableSettingsGroup *notificationsGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_FONT_ENABLE); + CheckableSettingsGroup *bgGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_ENABLE); + + notificationsGroup->addCheckBox(MENU_ENUM_LABEL_FPS_SHOW); + notificationsGroup->addCheckBox(MENU_ENUM_LABEL_FRAMECOUNT_SHOW); + notificationsGroup->addCheckBox(MENU_ENUM_LABEL_MEMORY_SHOW); + notificationsGroup->addFontSelector(MENU_ENUM_LABEL_VIDEO_FONT_PATH); + notificationsGroup->addFloatSpinBox(MENU_ENUM_LABEL_VIDEO_FONT_SIZE); + notificationsGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_X); + notificationsGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_Y); + notificationsGroup->addRow("Notification Color: ", new FloatColorButton( + MENU_ENUM_LABEL_VIDEO_MESSAGE_COLOR_RED, + MENU_ENUM_LABEL_VIDEO_MESSAGE_COLOR_GREEN, + MENU_ENUM_LABEL_VIDEO_MESSAGE_COLOR_BLUE)); + + bgGroup->addRow("Notification Background Color: ", new UIntColorButton( + MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_RED, + MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_GREEN, + MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_BLUE)); + bgGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_OPACITY); + + notificationsGroup->addRow(bgGroup); + + layout->addWidget(notificationsGroup); + + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} + +OverlayPage::OverlayPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS); +} + +QWidget *OverlayPage::widget() +{ + QWidget *widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; + + CheckableSettingsGroup *overlayGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_INPUT_OVERLAY_ENABLE); + CheckableSettingsGroup *inputsGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS); + + overlayGroup->addCheckBox(MENU_ENUM_LABEL_OVERLAY_AUTOLOAD_PREFERRED); + overlayGroup->addCheckBox(MENU_ENUM_LABEL_INPUT_OVERLAY_HIDE_IN_MENU); + + inputsGroup->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT); + + overlayGroup->addRow(inputsGroup); + + overlayGroup->addFileSelector(MENU_ENUM_LABEL_OVERLAY_PRESET); + overlayGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_OVERLAY_OPACITY); + overlayGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_OVERLAY_SCALE); + + layout->addWidget(overlayGroup); + + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/playlists.cpp b/ui/drivers/qt/options/playlists.cpp new file mode 100644 index 0000000000..3670684b5b --- /dev/null +++ b/ui/drivers/qt/options/playlists.cpp @@ -0,0 +1,43 @@ +#include "options.h" + +PlaylistsCategory::PlaylistsCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS); + setCategoryIcon("menu_playlist"); +} + +QVector PlaylistsCategory::pages() +{ + QVector pages; + + pages << new PlaylistsPage(this); + + return pages; +} + +PlaylistsPage::PlaylistsPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *PlaylistsPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + CheckableSettingsGroup *history = new CheckableSettingsGroup(MENU_ENUM_LABEL_HISTORY_LIST_ENABLE); + + history->addUIntSpinBox(MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE); + + layout->addRow(history); + + layout->addCheckBox(MENU_ENUM_LABEL_PLAYLIST_ENTRY_RENAME); + layout->addCheckBox(MENU_ENUM_LABEL_PLAYLIST_ENTRY_REMOVE); + layout->addCheckBox(MENU_ENUM_LABEL_PLAYLIST_USE_OLD_FORMAT); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/recording.cpp b/ui/drivers/qt/options/recording.cpp new file mode 100644 index 0000000000..cf8e354ff1 --- /dev/null +++ b/ui/drivers/qt/options/recording.cpp @@ -0,0 +1,57 @@ +#include "options.h" + +RecordingCategory::RecordingCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS); + setCategoryIcon("menu_record"); +} + +QVector RecordingCategory::pages() +{ + QVector pages; + + pages << new RecordingPage(this); + + return pages; +} + +RecordingPage::RecordingPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *RecordingPage::widget() +{ + QWidget * widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; + SettingsGroup *recordingGroup = new SettingsGroup("Recording"); + SettingsGroup *streamingGroup = new SettingsGroup("Streaming"); + QHBoxLayout *hl = new QHBoxLayout; + + recordingGroup->addUIntComboBox(MENU_ENUM_LABEL_VIDEO_RECORD_QUALITY); + recordingGroup->addFileSelector(MENU_ENUM_LABEL_RECORD_CONFIG); + recordingGroup->addUIntComboBox(MENU_ENUM_LABEL_VIDEO_RECORD_THREADS); + recordingGroup->addDirectorySelector(MENU_ENUM_LABEL_RECORDING_OUTPUT_DIRECTORY); + recordingGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_POST_FILTER_RECORD); + recordingGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_GPU_RECORD); + + hl->addWidget(new UIntRadioButtons(MENU_ENUM_LABEL_STREAMING_MODE)); + hl->addWidget(new UIntRadioButtons(MENU_ENUM_LABEL_VIDEO_STREAM_QUALITY)); + + streamingGroup->addRow(hl); + + streamingGroup->addFileSelector(MENU_ENUM_LABEL_STREAM_CONFIG); + streamingGroup->addStringLineEdit(MENU_ENUM_LABEL_STREAMING_TITLE); + streamingGroup->addStringLineEdit(MENU_ENUM_LABEL_STREAMING_URL); + streamingGroup->addUIntSpinBox(MENU_ENUM_LABEL_UDP_STREAM_PORT); + + layout->addWidget(recordingGroup); + layout->addWidget(streamingGroup); + + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/saving.cpp b/ui/drivers/qt/options/saving.cpp new file mode 100644 index 0000000000..c91a5378b1 --- /dev/null +++ b/ui/drivers/qt/options/saving.cpp @@ -0,0 +1,65 @@ +#include "options.h" + +SavingCategory::SavingCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS); + setCategoryIcon("menu_saving"); +} + +QVector SavingCategory::pages() +{ + QVector pages; + + pages << new SavingPage(this); + + return pages; +} + +SavingPage::SavingPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *SavingPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + SettingsGroup *savesGroup = new SettingsGroup("Saves"); + SettingsGroup *savestatesGroup = new SettingsGroup("Savestates"); + CheckableSettingsGroup *autoSavestatesGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE); + SettingsGroup *saveRamGroup = new SettingsGroup("SaveRAM"); + SettingsGroup *systemFilesDirGroup = new SettingsGroup("System Files"); + SettingsGroup *screenshotsDirGroup = new SettingsGroup("Screenshots"); + + savesGroup->addCheckBox(MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE); + savesGroup->addCheckBox(MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE); + + savestatesGroup->addCheckBox(MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX); + + autoSavestatesGroup->addCheckBox(MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD); + + savestatesGroup->addRow(autoSavestatesGroup); + savestatesGroup->addCheckBox(MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE); + savestatesGroup->addCheckBox(MENU_ENUM_LABEL_SORT_SAVESTATES_ENABLE); + savestatesGroup->addCheckBox(MENU_ENUM_LABEL_SAVESTATES_IN_CONTENT_DIR_ENABLE); + + saveRamGroup->addCheckBox(MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE); + saveRamGroup->addUIntSpinBox(MENU_ENUM_LABEL_AUTOSAVE_INTERVAL); + + systemFilesDirGroup->addCheckBox(MENU_ENUM_LABEL_SYSTEMFILES_IN_CONTENT_DIR_ENABLE); + + screenshotsDirGroup->addCheckBox(MENU_ENUM_LABEL_SCREENSHOTS_IN_CONTENT_DIR_ENABLE); + + layout->addRow(savesGroup); + layout->addRow(savestatesGroup); + layout->addRow(saveRamGroup); + layout->addRow(systemFilesDirGroup); + layout->addRow(screenshotsDirGroup); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/throttle.cpp b/ui/drivers/qt/options/throttle.cpp new file mode 100644 index 0000000000..a59260c30d --- /dev/null +++ b/ui/drivers/qt/options/throttle.cpp @@ -0,0 +1,62 @@ +#include "options.h" + +FrameThrottleCategory::FrameThrottleCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS); + setCategoryIcon("menu_frameskip"); +} + +QVector FrameThrottleCategory::pages() +{ + QVector pages; + + pages << new FrameThrottlePage(this); + pages << new RewindPage(this); + + return pages; +} + +FrameThrottlePage::FrameThrottlePage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS); +} + +QWidget *FrameThrottlePage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addFloatSpinBox(MENU_ENUM_LABEL_FASTFORWARD_RATIO); + layout->addFloatSpinBox(MENU_ENUM_LABEL_SLOWMOTION_RATIO); + layout->addCheckBox(MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE); + + widget->setLayout(layout); + + return widget; +} + +RewindPage::RewindPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS); +} + +QWidget *RewindPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addCheckBox(MENU_ENUM_LABEL_REWIND_ENABLE); + layout->addUIntSpinBox(MENU_ENUM_LABEL_REWIND_GRANULARITY); + layout->addSizeSpinBox(MENU_ENUM_LABEL_REWIND_BUFFER_SIZE); + layout->addUIntSpinBox(MENU_ENUM_LABEL_REWIND_BUFFER_SIZE_STEP); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/ui.cpp b/ui/drivers/qt/options/ui.cpp new file mode 100644 index 0000000000..9f8d659d59 --- /dev/null +++ b/ui/drivers/qt/options/ui.cpp @@ -0,0 +1,288 @@ +#include "options.h" +#include "../viewoptionsdialog.h" + +UserInterfaceCategory::UserInterfaceCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS); + setCategoryIcon("menu_ui"); +} + +UserInterfaceCategory::UserInterfaceCategory(MainWindow *mainwindow, QWidget *parent) : + OptionsCategory(parent) + ,m_mainwindow(mainwindow) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS); + setCategoryIcon("menu_ui"); + + m_pages << new UserInterfacePage(this); + m_pages << new ViewsPage(this); + /* pages << new QuickMenuPage(parent); */ + m_pages << new AppearancePage(this); + m_pages << new DesktopMenuPage(m_mainwindow, this); +} + +QVector UserInterfaceCategory::pages() +{ + return m_pages; +} + +UserInterfacePage::UserInterfacePage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *UserInterfacePage::widget() +{ + QWidget * widget = new QWidget; + + QVBoxLayout *layout = new QVBoxLayout; + + SettingsGroup *menuGroup = new SettingsGroup("Menu"); + SettingsGroup *inputGroup = new SettingsGroup("Input"); + SettingsGroup *miscGroup = new SettingsGroup("Miscelaneous"); + CheckableSettingsGroup *desktopGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_DESKTOP_MENU_ENABLE); + + menuGroup->addCheckBox(MENU_ENUM_LABEL_SHOW_ADVANCED_SETTINGS); + + { + rarch_setting_t *kioskMode = menu_setting_find_enum(MENU_ENUM_LABEL_MENU_ENABLE_KIOSK_MODE); + + /* only on xmb and ozone*/ + if (kioskMode) + { + CheckableSettingsGroup *kioskGroup = new CheckableSettingsGroup(kioskMode, widget); + + kioskGroup->addPasswordLineEdit(MENU_ENUM_LABEL_MENU_KIOSK_MODE_PASSWORD); + + menuGroup->addRow(kioskGroup); + } + + } + + menuGroup->addCheckBox(MENU_ENUM_LABEL_NAVIGATION_WRAPAROUND); + menuGroup->addCheckBox(MENU_ENUM_LABEL_PAUSE_LIBRETRO); + + inputGroup->addCheckBox(MENU_ENUM_LABEL_MOUSE_ENABLE); + inputGroup->addCheckBox(MENU_ENUM_LABEL_POINTER_ENABLE); + + menuGroup->addRow(inputGroup); + menuGroup->addCheckBox(MENU_ENUM_LABEL_THREADED_DATA_RUNLOOP_ENABLE); + + miscGroup->addCheckBox(MENU_ENUM_LABEL_PAUSE_NONACTIVE); + miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_DISABLE_COMPOSITION); + + menuGroup->addCheckBox(MENU_ENUM_LABEL_UI_COMPANION_ENABLE); + menuGroup->addCheckBox(MENU_ENUM_LABEL_UI_COMPANION_START_ON_BOOT); + menuGroup->addCheckBox(MENU_ENUM_LABEL_UI_MENUBAR_ENABLE); + + /* layout->addCheckBox(MENU_ENUM_LABEL_DESKTOP_MENU_ENABLE); */ + desktopGroup->addCheckBox(MENU_ENUM_LABEL_UI_COMPANION_TOGGLE); + + layout->addWidget(menuGroup); + layout->addWidget(miscGroup); + layout->addWidget(desktopGroup); + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} + +ViewsPage::ViewsPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_MENU_VIEWS_SETTINGS); +} + +QWidget *ViewsPage::widget() +{ + QWidget * widget = new QWidget(); + QHBoxLayout *mainLayout = new QHBoxLayout; + FormLayout *leftLayout = new FormLayout; + QVBoxLayout *rightLayout = new QVBoxLayout; + SettingsGroup *quickMenu = new SettingsGroup("Quick Menu"); + QuickMenuPage *quickPage = new QuickMenuPage(this); + SettingsGroup *mainMenu = new SettingsGroup("Main Menu"); + SettingsGroup *tabs = new SettingsGroup("Tabs"); + SettingsGroup *status = new SettingsGroup("Status"); + SettingsGroup *startScreen = new SettingsGroup("StartScreen"); + + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_LOAD_CORE); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_LOAD_CONTENT); + /* mainMenu->addCheckBox(MENU_ENUM_LABEL_SHOW_WIMP); */ + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_ONLINE_UPDATER); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_CORE_UPDATER); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_INFORMATION); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_CONFIGURATIONS); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_HELP); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_QUIT_RETROARCH); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_REBOOT); + mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_SHUTDOWN); + + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS); + tabs->addPasswordLineEdit(MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS_PASSWORD); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_FAVORITES); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_HISTORY); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_IMAGES); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_MUSIC); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_VIDEO); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_NETPLAY); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_ADD); + tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_PLAYLISTS); + + status->addCheckBox(MENU_ENUM_LABEL_TIMEDATE_ENABLE); + status->addUIntComboBox(MENU_ENUM_LABEL_TIMEDATE_STYLE); + status->addCheckBox(MENU_ENUM_LABEL_BATTERY_LEVEL_ENABLE); + status->addCheckBox(MENU_ENUM_LABEL_CORE_ENABLE); + + startScreen->addCheckBox(MENU_ENUM_LABEL_RGUI_SHOW_START_SCREEN); + + quickMenu->layout()->setContentsMargins(0, 0, 0, 0); + quickMenu->addRow(quickPage->widget()); + + leftLayout->addRow(mainMenu); + leftLayout->addRow(tabs); + leftLayout->addRow(startScreen); + + rightLayout->addWidget(quickMenu); + rightLayout->addWidget(status); + rightLayout->addStretch(); + + mainLayout->addLayout(leftLayout); + mainLayout->addLayout(rightLayout); + + widget->setLayout(mainLayout); + + return widget; +} + +QuickMenuPage::QuickMenuPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_QUICK_MENU_VIEWS_SETTINGS); +} + +QWidget *QuickMenuPage::widget() +{ + QWidget * widget = new QWidget; + FormLayout *layout = new FormLayout; + + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_RECORDING); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_STREAMING); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_OPTIONS); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_CONTROLS); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_CHEATS); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SHADERS); + layout->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_REWIND); + layout->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY); + layout->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_OVERLAYS); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES); + layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_INFORMATION); + + widget->setLayout(layout); + + return widget; +} + +AppearancePage::AppearancePage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_MENU_SETTINGS); +} + +QWidget *AppearancePage::widget() +{ + QWidget * widget = new QWidget; + FormLayout *layout = new FormLayout; + + layout->addFileSelector(MENU_ENUM_LABEL_MENU_WALLPAPER); + layout->addCheckBox(MENU_ENUM_LABEL_DYNAMIC_WALLPAPER); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MENU_FRAMEBUFFER_OPACITY); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_LINEAR_FILTER); + layout->addUIntComboBox(MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL); + layout->addUIntComboBox(MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK); + layout->addUIntComboBox(MENU_ENUM_LABEL_RGUI_MENU_COLOR_THEME); + layout->addFileSelector(MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET); + layout->addCheckBox(MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE); + layout->addUIntSpinBox(MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE); + layout->addUIntSpinBox(MENU_ENUM_LABEL_XMB_ALPHA_FACTOR); + layout->addUIntSpinBox(MENU_ENUM_LABEL_XMB_SCALE_FACTOR); + layout->addFontSelector(MENU_ENUM_LABEL_XMB_FONT); + layout->addUIntColorButton("Menu Font Color: ", + MENU_ENUM_LABEL_MENU_FONT_COLOR_RED, + MENU_ENUM_LABEL_MENU_FONT_COLOR_GREEN, + MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE); + layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_LAYOUT); + layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_THEME); + layout->addCheckBox(MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE); + layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_RIBBON_ENABLE); + layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME); + layout->addUIntComboBox(MENU_ENUM_LABEL_OZONE_MENU_COLOR_THEME); + layout->addCheckBox(MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE); + layout->addUIntComboBox(MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY); + layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY); + layout->addCheckBox(MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME); + + { + rarch_setting_t *thumbnails = menu_setting_find_enum(MENU_ENUM_LABEL_THUMBNAILS); + + if (thumbnails) + { + QHBoxLayout *thumbsLayout = new QHBoxLayout; + + rarch_setting_t *leftThumbnails = menu_setting_find_enum(MENU_ENUM_LABEL_LEFT_THUMBNAILS); + + thumbsLayout->addWidget(new UIntRadioButtons(thumbnails)); + + if (leftThumbnails) + thumbsLayout->addWidget(new UIntRadioButtons(leftThumbnails)); + + layout->addRow(thumbsLayout); + } + } + + layout->addCheckBox(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS); + layout->addUIntRadioButtons(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER); + layout->addUIntRadioButtons(MENU_ENUM_LABEL_MENU_TICKER_TYPE); + layout->addFloatSpinBox(MENU_ENUM_LABEL_MENU_TICKER_SPEED); + + widget->setLayout(layout); + + return widget; +} + +DesktopMenuPage::DesktopMenuPage(MainWindow *mainwindow, QObject *parent) : + OptionsPage(parent) + ,m_widget(new ViewOptionsWidget(mainwindow)) +{ + setDisplayName("Desktop Menu"); +} + +void DesktopMenuPage::apply() +{ + m_widget->saveViewOptions(); +} + +void DesktopMenuPage::load() +{ + m_widget->loadViewOptions(); +} + +QWidget *DesktopMenuPage::widget() +{ + return m_widget; +} diff --git a/ui/drivers/qt/options/user.cpp b/ui/drivers/qt/options/user.cpp new file mode 100644 index 0000000000..a004785702 --- /dev/null +++ b/ui/drivers/qt/options/user.cpp @@ -0,0 +1,76 @@ +#include "options.h" + +UserCategory::UserCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_USER_SETTINGS); + setCategoryIcon("menu_user"); +} + +QVector UserCategory::pages() +{ + QVector pages; + + pages << new UserPage(this); + pages << new AccountsPage(this); + + return pages; +} + +UserPage::UserPage(QObject *parent) : + OptionsPage(parent) +{ +} + +QWidget *UserPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + layout->addStringLineEdit(MENU_ENUM_LABEL_NETPLAY_NICKNAME); + layout->addUIntComboBox(MENU_ENUM_LABEL_USER_LANGUAGE); + + widget->setLayout(layout); + + return widget; +} + +AccountsPage::AccountsPage(QObject *parent) : + OptionsPage(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST); +} + +QWidget *AccountsPage::widget() +{ + QWidget *widget = new QWidget; + + QVBoxLayout *layout = new QVBoxLayout; + + SettingsGroup *youtubeGroup = new SettingsGroup(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ACCOUNTS_YOUTUBE)); + SettingsGroup *twitchGroup = new SettingsGroup(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ACCOUNTS_TWITCH)); + +#ifdef HAVE_CHEEVOS + SettingsGroup *cheevosGroup = new SettingsGroup(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS)); + + cheevosGroup->addStringLineEdit(MENU_ENUM_LABEL_CHEEVOS_USERNAME); + cheevosGroup->addPasswordLineEdit(MENU_ENUM_LABEL_CHEEVOS_PASSWORD); + + layout->addWidget(cheevosGroup); +#endif + + youtubeGroup->addStringLineEdit(MENU_ENUM_LABEL_YOUTUBE_STREAM_KEY); + + layout->addWidget(youtubeGroup); + + twitchGroup->addStringLineEdit(MENU_ENUM_LABEL_TWITCH_STREAM_KEY); + + layout->addWidget(twitchGroup); + + layout->addStretch(); + + widget->setLayout(layout); + + return widget; +} diff --git a/ui/drivers/qt/options/video.cpp b/ui/drivers/qt/options/video.cpp new file mode 100644 index 0000000000..c564241c93 --- /dev/null +++ b/ui/drivers/qt/options/video.cpp @@ -0,0 +1,337 @@ +#include "options.h" + +#ifndef CXX_BUILD +extern "C" { +#endif + +#include "../../../../gfx/video_display_server.h" +#include "../../../../gfx/video_driver.h" + +#ifndef CXX_BUILD +} +#endif + +VideoCategory::VideoCategory(QWidget *parent) : + OptionsCategory(parent) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS); + setCategoryIcon("menu_video"); +} + +QVector VideoCategory::pages() +{ + QVector pages; + + pages << new VideoPage(this); + pages << new CrtSwitchresPage(this); + + return pages; +} + +VideoPage::VideoPage(QObject *parent) : + OptionsPage(parent) + ,m_resolutionCombo(new QComboBox()) +{ +} + +QWidget *VideoPage::widget() +{ + QWidget *widget = new QWidget; + + QVBoxLayout *layout = new QVBoxLayout; + + SettingsGroup *outputGroup = new SettingsGroup("Output"); + SettingsGroup *aspectGroup = new SettingsGroup("Scaling"); + + SettingsGroup *fullscreenGroup = new SettingsGroup("Fullscreen Mode"); + SettingsGroup *windowedGroup = new SettingsGroup("Windowed Mode"); + + QHBoxLayout *fullcreenSizeLayout = new QHBoxLayout; + FormLayout *leftFullscreenSizeForm = new FormLayout; + FormLayout *rightFullscreenSizeForm = new FormLayout; + + QHBoxLayout *windowedSizeLayout = new QHBoxLayout; + FormLayout *leftWindowedSizeForm = new FormLayout; + FormLayout *rightWindowedSizeForm = new FormLayout; + + SettingsGroup *syncGroup = new SettingsGroup("Synchronization"); + CheckableSettingsGroup *vSyncGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_VSYNC); + + QHBoxLayout *outputScalingLayout = new QHBoxLayout; + QHBoxLayout *modeLayout = new QHBoxLayout; + QHBoxLayout *syncMiscLayout = new QHBoxLayout; + + SettingsGroup *miscGroup = new SettingsGroup("Miscellaneous"); + SettingsGroup *filterGroup = new SettingsGroup("Video Filter"); + + unsigned i, size = 0; + struct video_display_config *list = (struct video_display_config*) video_display_server_get_resolution_list(&size); + + if (list) + { + for (i = 0; i < size; i++) + { + char val_d[256], str[256]; + snprintf(str, sizeof(str), "%dx%d (%d Hz)", list[i].width, list[i].height, list[i].refreshrate); + snprintf(val_d, sizeof(val_d), "%d", i); + + m_resolutionCombo->addItem(str); + + if (list[i].current) + m_resolutionCombo->setCurrentIndex(i); + } + + free(list); + } + + outputGroup->addStringComboBox(MENU_ENUM_LABEL_VIDEO_DRIVER); + outputGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_MONITOR_INDEX); + outputGroup->addUIntComboBox(MENU_ENUM_LABEL_VIDEO_ROTATION); + outputGroup->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION), m_resolutionCombo); + outputGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_FORCE_SRGB_DISABLE); + + fullscreenGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_FULLSCREEN); + fullscreenGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_WINDOWED_FULLSCREEN); + + leftFullscreenSizeForm->addRow("Width:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_FULLSCREEN_X)); + rightFullscreenSizeForm->addRow("Height:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_FULLSCREEN_Y)); + + fullcreenSizeLayout->addLayout(leftFullscreenSizeForm); + fullcreenSizeLayout->addLayout(rightFullscreenSizeForm); + + fullscreenGroup->addRow(fullcreenSizeLayout); + + aspectGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER); + aspectGroup->addRow(new AspectRatioGroup("Aspect Ratio")); + + leftWindowedSizeForm->addRow("Scale:", new FloatSpinBox(MENU_ENUM_LABEL_VIDEO_SCALE)); + leftWindowedSizeForm->addRow("Width:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_WINDOW_WIDTH)); + + rightWindowedSizeForm->addRow("Opacity:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY)); + rightWindowedSizeForm->addRow("Height:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_WINDOW_HEIGHT)); + + windowedSizeLayout->addLayout(leftWindowedSizeForm); + windowedSizeLayout->addLayout(rightWindowedSizeForm); + + windowedGroup->addRow(windowedSizeLayout); + + windowedGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_WINDOW_SHOW_DECORATIONS); + windowedGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_WINDOW_SAVE_POSITION); + + vSyncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL); + vSyncGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_ADAPTIVE_VSYNC); + vSyncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_FRAME_DELAY); + syncGroup->addRow(vSyncGroup); + + { + rarch_setting_t *hardSyncSetting = menu_setting_find_enum(MENU_ENUM_LABEL_VIDEO_HARD_SYNC); + + if (hardSyncSetting) + { + CheckableSettingsGroup *hardSyncGroup = new CheckableSettingsGroup(hardSyncSetting); + + hardSyncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES); + + syncGroup->addRow(hardSyncGroup); + } + } + + syncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES); + + miscGroup->addCheckBox(MENU_ENUM_LABEL_SUSPEND_SCREENSAVER_ENABLE); + miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_THREADED); + miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION); + miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT); + miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_CROP_OVERSCAN); + miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_SMOOTH); + + syncMiscLayout->addWidget(syncGroup); + syncMiscLayout->addWidget(miscGroup); + + filterGroup->addFileSelector(MENU_ENUM_LABEL_VIDEO_FILTER); + + modeLayout->addWidget(fullscreenGroup); + modeLayout->addWidget(windowedGroup); + + outputScalingLayout->addWidget(outputGroup); + outputScalingLayout->addWidget(aspectGroup); + + layout->addLayout(outputScalingLayout); + layout->addLayout(modeLayout); + layout->addLayout(syncMiscLayout); + layout->addWidget(filterGroup); + + layout->addStretch(); + + connect(m_resolutionCombo, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(onResolutionComboIndexChanged(const QString&))); + + widget->setLayout(layout); + + return widget; +} + +AspectRatioGroup::AspectRatioGroup(const QString &title, QWidget *parent) : + SettingsGroup(title, parent) + ,m_radioButton(new AspectRatioRadioButton(ASPECT_RATIO_4_3, ASPECT_RATIO_32_9)) + ,m_comboBox(new UIntComboBox(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_4_3, ASPECT_RATIO_32_9)) +{ + QHBoxLayout *aspectLayout = new QHBoxLayout; + FormLayout *leftAspectForm = new FormLayout; + FormLayout *rightAspectForm = new FormLayout; + QHBoxLayout *preset = new QHBoxLayout; + //AspectRatioRadioButton *aspectRadioButton = new AspectRatioRadioButton(ASPECT_RATIO_4_3, ASPECT_RATIO_32_9); + QHBoxLayout *custom = new QHBoxLayout; + QVBoxLayout *customRadio = new QVBoxLayout; + QHBoxLayout *config = new QHBoxLayout; + QHBoxLayout *aspectL = new QHBoxLayout; + FormLayout *leftAspect = new FormLayout; + FormLayout *rightAspect = new FormLayout; + + leftAspectForm->addRow("X Pos.:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_X)); + leftAspectForm->addRow("Width:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH)); + rightAspectForm->addRow("Y Pos.:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_Y)); + rightAspectForm->addRow("Height:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT)); + + aspectLayout->addLayout(leftAspectForm); + aspectLayout->addLayout(rightAspectForm); + + preset->addWidget(m_radioButton); + preset->addWidget(m_comboBox); + preset->setStretch(1, 1); + + customRadio->addWidget(new UIntRadioButton(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_CUSTOM), Qt::AlignTop); + customRadio->addStretch(); + + custom->addLayout(customRadio); + custom->addLayout(aspectLayout); + custom->addStretch(); + + config->addWidget(new UIntRadioButton(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_CONFIG)); + config->addWidget(new FloatSpinBox(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO)); + config->setStretch(1, 1); + config->setSizeConstraint(QLayout::SetMinimumSize); + + leftAspect->addRow(new UIntRadioButton(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_CORE)); + leftAspect->addRow(preset); + + rightAspect->addRow(config); + rightAspect->addRow(new UIntRadioButton(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_SQUARE)); + + aspectL->addLayout(leftAspect); + aspectL->addStretch(); + aspectL->addSpacing(30); + aspectL->addLayout(rightAspect); + + addRow(aspectL); + addRow(custom); + + connect(m_radioButton, SIGNAL(clicked(bool)), this, SLOT(onAspectRadioClicked(bool))); +} + +void AspectRatioGroup::paintEvent(QPaintEvent *event) +{ + unsigned value = config_get_ptr()->uints.video_aspect_ratio_idx; + + if (ASPECT_RATIO_4_3 >= value || value <= ASPECT_RATIO_32_9) + { + m_comboBox->blockSignals(false); + m_radioButton->setChecked(true); + } + else + { + m_comboBox->blockSignals(true); + } + + SettingsGroup::paintEvent(event); +} + +void AspectRatioGroup::onAspectRadioToggled(bool checked) +{ + if (checked) + m_comboBox->currentIndexChanged(m_comboBox->currentIndex()); + else + m_comboBox->blockSignals(true); +} + +void AspectRatioGroup::onAspectRadioClicked(bool checked) +{ + m_comboBox->blockSignals(false); + m_comboBox->currentIndexChanged(m_comboBox->currentIndex()); + setChecked(true); +} + +CrtSwitchresPage::CrtSwitchresPage(QObject *parent) : + OptionsPage(parent) + ,m_crtSuperResolutionCombo(new QComboBox()) +{ + setDisplayName(MENU_ENUM_LABEL_VALUE_CRT_SWITCHRES_SETTINGS); +} + +QWidget *CrtSwitchresPage::widget() +{ + QWidget *widget = new QWidget; + + FormLayout *layout = new FormLayout; + + m_crtSuperResolutionCombo->addItem(msg_hash_to_str(MSG_NATIVE), 0); + m_crtSuperResolutionCombo->addItem("1920", 1920); + m_crtSuperResolutionCombo->addItem("2560", 2560); + m_crtSuperResolutionCombo->addItem("3840", 3840); + + layout->addUIntComboBox(MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION); + layout->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER), m_crtSuperResolutionCombo); + layout->addUIntSpinBox(MENU_ENUM_LABEL_CRT_SWITCH_X_AXIS_CENTERING); + layout->addCheckBox(MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_USE_CUSTOM_REFRESH_RATE); + + connect(m_crtSuperResolutionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onCrtSuperResolutionComboIndexChanged(int))); + + widget->setLayout(layout); + + return widget; +} + +void VideoPage::onResolutionComboIndexChanged(const QString &text) +{ + char str[100]; + char *pch = NULL; + const char *path = text.toUtf8().constData(); + unsigned width = 0; + unsigned height = 0; + unsigned refreshrate = 0; + + snprintf(str, sizeof(str), "%s", path); + + pch = strtok(str, "x"); + if (pch) + width = strtoul(pch, NULL, 0); + pch = strtok(NULL, " "); + if (pch) + height = strtoul(pch, NULL, 0); + pch = strtok(NULL, "("); + if (pch) + refreshrate = strtoul(pch, NULL, 0); + + if (video_display_server_set_resolution(width, height, + refreshrate, (float)refreshrate, 0, 0, 0)) + { + settings_t *settings = config_get_ptr(); + + video_monitor_set_refresh_rate((float)refreshrate); + + settings->uints.video_fullscreen_x = width; + settings->uints.video_fullscreen_y = height; + } +} + +void CrtSwitchresPage::onCrtSuperResolutionComboIndexChanged(int index) +{ + Q_UNUSED(index) + config_get_ptr()->uints.crt_switch_resolution_super = m_crtSuperResolutionCombo->currentData().value(); +} + +AspectRatioRadioButton::AspectRatioRadioButton(unsigned min, unsigned max, QWidget *parent) : + QRadioButton(parent) + ,m_min(min) + ,m_max(max) +{ +} diff --git a/ui/drivers/qt/settingswidgets.cpp b/ui/drivers/qt/settingswidgets.cpp new file mode 100644 index 0000000000..6454c4fe7d --- /dev/null +++ b/ui/drivers/qt/settingswidgets.cpp @@ -0,0 +1,1187 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "settingswidgets.h" + +#include + +#ifndef CXX_BUILD +extern "C" { +#endif + +#include + +#ifndef CXX_BUILD +} +#endif + +static const QRegularExpression decimalsRegex("%.(\\d)f"); + +inline void handleChange(rarch_setting_t *setting) +{ + + config_get_ptr()->modified = true; + + if (setting->change_handler) + setting->change_handler(setting); + + if (setting->cmd_trigger.idx && !setting->cmd_trigger.triggered) + command_event(setting->cmd_trigger.idx, NULL); +} + +inline void addSublabelAndWhatsThis(QWidget *widget, rarch_setting_t *setting) +{ + struct menu_file_list_cbs cbs = {}; + char tmp[512]; + tmp[0] = '\0'; + + cbs.enum_idx = setting->enum_idx; + + menu_cbs_init_bind_sublabel(&cbs, 0, 0, setting->type, setting->size); + + cbs.action_sublabel(0, 0, 0, 0, 0, tmp, sizeof(tmp)); + + widget->setToolTip(tmp); + + menu_hash_get_help_enum(setting->enum_idx, tmp, sizeof(tmp)); + + if (!string_is_equal(tmp, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE))) + widget->setWhatsThis(tmp); +} + +inline QString formLabel(rarch_setting_t *setting) +{ + return QString(setting->short_description) + ":"; +} + +FormLayout::FormLayout(QWidget *parent) : + QFormLayout(parent) +{ +} + +void FormLayout::addCheckBox(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(new CheckBox(setting)); +} + +void FormLayout::addUIntRadioButtons(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(new UIntRadioButtons(setting)); +} + +void FormLayout::addUIntComboBox(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new UIntComboBox(setting)); +} + +void FormLayout::addStringComboBox(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new StringComboBox(setting)); +} + +void FormLayout::addStringLineEdit(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new StringLineEdit(setting)); +} + +void FormLayout::addPasswordLineEdit(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new PasswordLineEdit(setting)); +} + +void FormLayout::addUIntSpinBox(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new UIntSpinBox(setting)); +} + +void FormLayout::addSizeSpinBox(msg_hash_enums enum_idx, unsigned scale) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new SizeSpinBox(setting, scale)); +} + +void FormLayout::addFloatSpinBox(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new FloatSpinBox(setting)); +} + +void FormLayout::addDirectorySelector(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new DirectorySelector(setting)); +} + +void FormLayout::addFileSelector(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new FileSelector(setting)); +} + +void FormLayout::addFontSelector(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new FontSelector(setting)); +} + +void FormLayout::addFloatSliderAndSpinBox(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting && setting->short_description) + addRow(formLabel(setting), new FloatSliderAndSpinBox(setting)); +} + +void FormLayout::addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b) +{ + rarch_setting_t *red = menu_setting_find_enum(r); + rarch_setting_t *green = menu_setting_find_enum(g); + rarch_setting_t *blue = menu_setting_find_enum(b); + + if (red && green && blue) + addRow(title, new UIntColorButton(red, green, blue)); +} + +bool FormLayout::addBindButton(msg_hash_enums enum_idx) +{ + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (!setting || !setting->short_description) + return false; + + addRow(QString(setting->short_description), new BindButton(setting)); + + return true; +} + +SettingsGroup::SettingsGroup(const QString &title, QWidget *parent) : + QGroupBox(title, parent) + ,m_layout(new FormLayout(this)) +{ +} + +SettingsGroup::SettingsGroup(QWidget *parent) : + QGroupBox(parent) + ,m_layout(new FormLayout(this)) +{ +} + +void SettingsGroup::addWidget(QWidget *widget) +{ + m_layout->addWidget(widget); +} + +void SettingsGroup::addRow(QString label, QWidget *widget) +{ + m_layout->addRow(label, widget); +} + +void SettingsGroup::addRow(QWidget *widget) +{ + m_layout->addRow(widget); +} + +void SettingsGroup::addRow(QLayout *layout) +{ + m_layout->addRow(layout); +} + +void SettingsGroup::addRow(QString label, QLayout *layout) +{ + m_layout->addRow(label, layout); +} + +void SettingsGroup::addCheckBox(msg_hash_enums enum_idx) +{ + m_layout->addCheckBox(enum_idx); +} + +void SettingsGroup::addDirectorySelector(msg_hash_enums enum_idx) +{ + m_layout->addDirectorySelector(enum_idx); +} + +void SettingsGroup::addFileSelector(msg_hash_enums enum_idx) +{ + m_layout->addFileSelector(enum_idx); +} + +void SettingsGroup::addFontSelector(msg_hash_enums enum_idx) +{ + m_layout->addFontSelector(enum_idx); +} + +void SettingsGroup::addStringLineEdit(msg_hash_enums enum_idx) +{ + m_layout->addStringLineEdit(enum_idx); +} + +void SettingsGroup::addPasswordLineEdit(msg_hash_enums enum_idx) +{ + m_layout->addPasswordLineEdit(enum_idx); +} + +void SettingsGroup::addStringComboBox(msg_hash_enums enum_idx) +{ + m_layout->addStringComboBox(enum_idx); +} + +void SettingsGroup::addUIntComboBox(msg_hash_enums enum_idx) +{ + m_layout->addUIntComboBox(enum_idx); +} + +void SettingsGroup::addUIntRadioButtons(msg_hash_enums enum_idx) +{ + m_layout->addUIntRadioButtons(enum_idx); +} + +void SettingsGroup::addUIntSpinBox(msg_hash_enums enum_idx) +{ + m_layout->addUIntSpinBox(enum_idx); +} + +void SettingsGroup::addFloatSpinBox(msg_hash_enums enum_idx) +{ + m_layout->addFloatSpinBox(enum_idx); +} + +void SettingsGroup::addFloatSliderAndSpinBox(msg_hash_enums enum_idx) +{ + m_layout->addFloatSliderAndSpinBox(enum_idx); +} + +void SettingsGroup::addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b) +{ + m_layout->addUIntColorButton(title, r, g, b); +} + +void SettingsGroup::addBindButton(msg_hash_enums enum_idx) +{ + m_layout->addBindButton(enum_idx); +} + +CheckBox::CheckBox(rarch_setting_t *setting, QWidget *parent) : + QCheckBox(setting->short_description, parent) + ,m_setting(setting) + ,m_value(setting->value.target.boolean) +{ + QAbstractButton::setChecked(*m_value); + + /* TODO/FIXME only one of these should be necessary */ + connect(this, SIGNAL(toggled(bool)), this, SLOT(onClicked(bool))); + connect(this, SIGNAL(clicked(bool)), this, SLOT(onClicked(bool))); + + addSublabelAndWhatsThis(this, m_setting); +} + +CheckBox::CheckBox(const char *setting, QWidget *parent) : + CheckBox(menu_setting_find(setting), parent) +{ +} + +CheckBox::CheckBox(msg_hash_enums enum_idx, QWidget *parent) : + CheckBox(menu_setting_find_enum(enum_idx), parent) +{ +} + +void CheckBox::onClicked(bool checked) +{ + *m_value = checked; + + handleChange(m_setting); +} + +void CheckBox::paintEvent(QPaintEvent *event) +{ + if (*m_value != QAbstractButton::isChecked()) + { + blockSignals(true); + + QAbstractButton::setChecked(*m_value); + + blockSignals(false); + } + + QCheckBox::paintEvent(event); +} + +CheckableSettingsGroup::CheckableSettingsGroup(rarch_setting_t *setting, QWidget *parent) : + SettingsGroup(parent) +{ + if (setting && setting->short_description) + { + m_setting = setting; + m_value = setting->value.target.boolean; + + setTitle(setting->short_description); + + setCheckable(true); + setChecked(*m_value); + + connect(this, SIGNAL(clicked(bool)), this, SLOT(onClicked(bool))); + + addSublabelAndWhatsThis(this, m_setting); + } +} + +CheckableSettingsGroup::CheckableSettingsGroup(const char *setting, QWidget *parent) : + CheckableSettingsGroup(menu_setting_find(setting), parent) +{ +} + +CheckableSettingsGroup::CheckableSettingsGroup(msg_hash_enums enum_idx, QWidget *parent) : + CheckableSettingsGroup(menu_setting_find_enum(enum_idx), parent) +{ +} + +void CheckableSettingsGroup::onClicked(bool checked) +{ + *m_value = checked; + + handleChange(m_setting); +} + +void CheckableSettingsGroup::paintEvent(QPaintEvent *event) +{ + if (*m_value != isChecked()) + { + blockSignals(true); + + setChecked(*m_value); + + blockSignals(false); + } + + QGroupBox::paintEvent(event); +} + +CheckableIcon::CheckableIcon(const char *setting, const QIcon &icon, QWidget *parent) : + CheckableIcon(menu_setting_find(setting), icon, parent) +{ +} + +CheckableIcon::CheckableIcon(msg_hash_enums enum_idx, const QIcon &icon, QWidget *parent) : + CheckableIcon(menu_setting_find_enum(enum_idx), icon, parent) +{ +} + +CheckableIcon::CheckableIcon(rarch_setting_t *setting, const QIcon &icon, QWidget *parent) : + QToolButton(parent) + ,m_setting(setting) + ,m_value(setting->value.target.boolean) +{ + setIcon(icon); + + setCheckable(true); + + QAbstractButton::setChecked(*m_value); + + connect(this, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool))); + + addSublabelAndWhatsThis(this, m_setting); +} + +void CheckableIcon::onToggled(bool checked) +{ + *m_value = QAbstractButton::isChecked(); + + handleChange(m_setting); + + QAbstractButton::setChecked(checked); +} + +void CheckableIcon::paintEvent(QPaintEvent *event) +{ + if (QAbstractButton::isChecked() != *m_value) + { + blockSignals(true); + + QAbstractButton::setChecked(*m_value); + + blockSignals(false); + } + QToolButton::paintEvent(event); +} + +StringLineEdit::StringLineEdit(rarch_setting_t *setting, QWidget *parent) : + QLineEdit(setting->value.target.string) + ,m_setting(setting) + ,m_value(setting->value.target.string) +{ + connect(this, SIGNAL(editingFinished()), this, SLOT(onEditingFinished())); + + addSublabelAndWhatsThis(this, m_setting); +} + +StringLineEdit::StringLineEdit(const char *setting, QWidget *parent) : + StringLineEdit(menu_setting_find(setting), parent) +{ +} + +void StringLineEdit::onEditingFinished() +{ + strlcpy(m_value, text().toUtf8().data(), m_setting->size); + + handleChange(m_setting); + + setModified(false); +} + +void StringLineEdit::paintEvent(QPaintEvent *event) +{ + if (!isModified() && m_value != text()) + { + setText(m_value); + setModified(false); + } + + QLineEdit::paintEvent(event); +} + +PasswordLineEdit::PasswordLineEdit(rarch_setting_t *setting, QWidget *parent) : + StringLineEdit(setting) +{ + setEchoMode(QLineEdit::Password); +} + +StringComboBox::StringComboBox(rarch_setting_t *setting, QWidget *parent) : + QComboBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.string) +{ + addItems(QString(setting->values).split("|")); + + connect(this, SIGNAL(currentTextChanged(const QString&)), this, SLOT(onCurrentTextChanged(const QString&))); + + addSublabelAndWhatsThis(this, m_setting); +} + +StringComboBox::StringComboBox(const char *setting, QWidget *parent) : + StringComboBox(menu_setting_find(setting), parent) +{ +} + +void StringComboBox::onCurrentTextChanged(const QString &text) +{ + strlcpy(m_value, text.toUtf8().data(), sizeof(m_value)); + + handleChange(m_setting); +} + +void StringComboBox::paintEvent(QPaintEvent *event) +{ + setCurrentText(m_value); + QComboBox::paintEvent(event); +} + +UIntComboBox::UIntComboBox(rarch_setting_t *setting, QWidget *parent) : + QComboBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.unsigned_integer) +{ + double min = setting->enforce_minrange ? setting->min : 0.00; + double max = setting->enforce_maxrange ? setting->max : 999.00; + + populate(min, max); + + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int))); + + addSublabelAndWhatsThis(this, m_setting); +} + +UIntComboBox::UIntComboBox(rarch_setting_t *setting, double min, double max, QWidget *parent) : + QComboBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.unsigned_integer) +{ + populate(min, max); + + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int))); + + addSublabelAndWhatsThis(this, m_setting); +} + +void UIntComboBox::populate(double min, double max) +{ + float i; + unsigned orig_value = *m_setting->value.target.unsigned_integer; + float step = m_setting->step; + bool checked_found = false; + unsigned count = 0; + + if (m_setting->get_string_representation) + { + for (i = min; i <= max; i += step) + { + char val_s[256]; + unsigned val = (unsigned)i; + + *m_setting->value.target.unsigned_integer = val; + + m_setting->get_string_representation(m_setting, val_s, sizeof(val_s)); + + m_hash[i] = QString(val_s); + + addItem(m_hash[i], i); + + if (!checked_found && val == orig_value) + { + setCurrentIndex(count); + checked_found = true; + } + count++; + } + + *m_setting->value.target.unsigned_integer = orig_value; + } +} + +UIntComboBox::UIntComboBox(msg_hash_enums enum_idx, QWidget *parent) : + UIntComboBox(menu_setting_find_enum(enum_idx), parent) +{ +} + +UIntComboBox::UIntComboBox(msg_hash_enums enum_idx, double min, double max, QWidget *parent) : + UIntComboBox(menu_setting_find_enum(enum_idx), min, max, parent) +{ +} + +UIntComboBox::UIntComboBox(const char *setting, QWidget *parent) : + UIntComboBox(menu_setting_find(setting), parent) +{ +} + +void UIntComboBox::onCurrentIndexChanged(int index) +{ + Q_UNUSED(index); + + *m_value = currentData().toUInt(); + + handleChange(m_setting); +} + +void UIntComboBox::paintEvent(QPaintEvent *event) +{ + setCurrentText(m_hash.value(*m_value)); + QComboBox::paintEvent(event); +} + +UIntSpinBox::UIntSpinBox(rarch_setting_t *setting, QWidget *parent) : + QSpinBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.unsigned_integer) +{ + setMinimum(setting->enforce_minrange ? setting->min : 0.00); + setMaximum(setting->enforce_maxrange ? setting->max : INT_MAX); + + setSingleStep(setting->step); + + connect(this, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int))); + + addSublabelAndWhatsThis(this, m_setting); +} + +UIntSpinBox::UIntSpinBox(msg_hash_enums enum_idx, QWidget *parent) : + UIntSpinBox(menu_setting_find_enum(enum_idx), parent) +{ +} + +void UIntSpinBox::onValueChanged(int value) +{ + *m_value = value; + handleChange(m_setting); +} + +void UIntSpinBox::paintEvent(QPaintEvent *event) +{ + if ((unsigned)value() != *m_value) + { + blockSignals(true); + + setValue(*m_value); + + blockSignals(false); + } + + QSpinBox::paintEvent(event); +} + +SizeSpinBox::SizeSpinBox(rarch_setting_t *setting, unsigned scale, QWidget *parent) : + QSpinBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.sizet) + ,m_scale(scale) +{ + setMinimum(setting->enforce_minrange ? setting->min / m_scale : 0.00); + setMaximum(setting->enforce_maxrange ? setting->max / m_scale : INT_MAX); + + setSingleStep(setting->step / m_scale); + + setValue(*m_value / m_scale); + + connect(this, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int))); + + addSublabelAndWhatsThis(this, m_setting); +} + +SizeSpinBox::SizeSpinBox(msg_hash_enums enum_idx, unsigned scale, QWidget *parent) : + SizeSpinBox(menu_setting_find_enum(enum_idx), scale, parent) +{ +} + +void SizeSpinBox::onValueChanged(int value) +{ + *m_value = value * m_scale; + handleChange(m_setting); +} + +void SizeSpinBox::paintEvent(QPaintEvent *event) +{ + if ((value() * m_scale) != *m_value) + { + blockSignals(true); + + setValue(*m_value / m_scale); + + blockSignals(false); + } + + QSpinBox::paintEvent(event); +} + +UIntRadioButton::UIntRadioButton(msg_hash_enums enum_idx, unsigned value, QWidget *parent) : + QRadioButton(parent) + ,m_setting(menu_setting_find_enum(enum_idx)) + ,m_target(m_setting->value.target.unsigned_integer) + ,m_value(value) +{ + char val_s[256]; + unsigned orig_value = *m_setting->value.target.unsigned_integer; + + *m_setting->value.target.unsigned_integer = value; + + m_setting->get_string_representation(m_setting, val_s, sizeof(val_s)); + + *m_setting->value.target.unsigned_integer = orig_value; + + setText(val_s); + + if (m_value == orig_value) + setChecked(true); + + connect(this, SIGNAL(clicked(bool)), this, SLOT(onClicked(bool))); +} + +UIntRadioButton::UIntRadioButton(const QString &text, rarch_setting_t *setting, unsigned value, QWidget *parent) : + QRadioButton(text, parent) + ,m_setting(setting) + ,m_target(setting->value.target.unsigned_integer) + ,m_value(value) +{ + connect(this, SIGNAL(clicked(bool)), this, SLOT(onClicked(bool))); +} + +void UIntRadioButton::onClicked(bool) +{ + *m_target = m_value; + handleChange(m_setting); +} + +void UIntRadioButton::paintEvent(QPaintEvent *event) +{ + if (*m_target == m_value) + setChecked(true); + else + setChecked(false); + + QRadioButton::paintEvent(event); +} + +UIntRadioButtons::UIntRadioButtons(rarch_setting_t *setting, QWidget *parent) : + QGroupBox(setting->short_description, parent) + ,m_setting(setting) + ,m_value(setting->value.target.unsigned_integer) + ,m_buttonGroup(new QButtonGroup(this)) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + /* from menu_displaylist */ + float i; + unsigned orig_value = *setting->value.target.unsigned_integer; + float step = setting->step; + double min = setting->enforce_minrange ? setting->min : 0.00; + double max = setting->enforce_maxrange ? setting->max : UINT_MAX; + + bool checked_found = false; + + if (setting->get_string_representation) + { + for (i = min; i <= max; i += step) + { + char val_s[256]; + //int val = (int)i; + + *setting->value.target.unsigned_integer = i; + + setting->get_string_representation(setting, val_s, sizeof(val_s)); + + //m_hash[i] = QString(val_s); + + QRadioButton *button = new QRadioButton(QString(val_s), this); + + m_buttonGroup->addButton(button, i); + + layout->addWidget(button); + //addItem(m_hash[i], i); + + if (!checked_found && i == orig_value) + { + button->setChecked(true); + checked_found = true; + } + } + + *setting->value.target.unsigned_integer = orig_value; + } + addSublabelAndWhatsThis(this, m_setting); + connect(m_buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(onButtonClicked(int))); +} + +UIntRadioButtons::UIntRadioButtons(const char *setting, QWidget *parent) : + UIntRadioButtons(menu_setting_find(setting), parent) +{ +} + +UIntRadioButtons::UIntRadioButtons(msg_hash_enums enum_idx, QWidget *parent) : + UIntRadioButtons(menu_setting_find_enum(enum_idx), parent) +{ +} + +void UIntRadioButtons::onButtonClicked(int id) +{ + *m_value = id; + + handleChange(m_setting); +} + +IntSpinBox::IntSpinBox(rarch_setting_t *setting, QWidget *parent) : + QSpinBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.integer) +{ + setMinimum(setting->enforce_minrange ? setting->min : INT_MIN); + setMaximum(setting->enforce_maxrange ? setting->max : INT_MAX); + + setSingleStep(setting->step); + + connect(this, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int))); + + addSublabelAndWhatsThis(this, m_setting); +} + +void IntSpinBox::onValueChanged(int value) +{ + *m_value = value; + handleChange(m_setting); +} + +void IntSpinBox::paintEvent(QPaintEvent *event) +{ + if (value() != *m_value) + { + blockSignals(true); + setValue(*m_value); + blockSignals(false); + } + + QSpinBox::paintEvent(event); +} + +FloatSpinBox::FloatSpinBox(const char *setting, QWidget *parent) : + FloatSpinBox(menu_setting_find(setting), parent) +{ +} + +FloatSpinBox::FloatSpinBox(msg_hash_enums enum_idx, QWidget *parent) : + FloatSpinBox(menu_setting_find_enum(enum_idx), parent) +{ +} + +const QRegularExpression FloatSpinBox::DECIMALS_REGEX = QRegularExpression("%.(\\d)f"); + +FloatSpinBox::FloatSpinBox(rarch_setting_t *setting, QWidget *parent) : + QDoubleSpinBox(parent) + ,m_setting(setting) + ,m_value(setting->value.target.fraction) +{ + QRegularExpressionMatch match = DECIMALS_REGEX.match(setting->rounding_fraction); + + if (match.hasMatch()) + setDecimals(match.captured(1).toInt()); + + setMinimum(setting->enforce_minrange ? setting->min : 0.00); + setMaximum(setting->enforce_maxrange ? setting->max : 999.00); + + setValue(*m_value); + setSingleStep(setting->step); + + connect(this, SIGNAL(valueChanged(double)), this, SLOT(onValueChanged(double))); + addSublabelAndWhatsThis(this, m_setting); +} + +void FloatSpinBox::onValueChanged(double value) +{ + *m_value = (float)value; + + handleChange(m_setting); +} + +void FloatSpinBox::paintEvent(QPaintEvent *event) +{ + if ((float)value() != *m_value) + { + blockSignals(true); + + if (*m_value < minimum() || *m_value > maximum()) + *m_value = m_setting->default_value.fraction; + + setValue(*m_value); + + blockSignals(false); + } + + QDoubleSpinBox::paintEvent(event); +} + +PathButton::PathButton(rarch_setting_t *setting, QWidget *parent) : + QPushButton("Browse...", parent) + ,m_setting(setting) + ,m_value(setting->value.target.string) + ,m_dir(setting->default_value.string) +{ + connect(this, SIGNAL(clicked(bool)), this, SLOT(onClicked(bool))); + + addSublabelAndWhatsThis(this, m_setting); +} + +PathButton::PathButton(const char *setting, QWidget *parent) : + PathButton(menu_setting_find(setting), parent) +{ +} + +void DirectoryButton::onClicked(bool) +{ + QString dir = QFileDialog::getExistingDirectory( + this, + "Choose " + QString(m_setting->short_description) + " Directory", + QString(m_setting->default_value.string)); + + if (!dir.isNull()) + { + strlcpy(m_setting->value.target.string, QDir::toNativeSeparators(dir).toUtf8().data(), m_setting->size); + + handleChange(m_setting); + } +} + +void FileButton::onClicked(bool) +{ + QString file = QFileDialog::getOpenFileName( + this, + "Choose File", + QString(m_setting->default_value.string), + QString(m_setting->short_description) + " (*." + QString(m_setting->values) + ")"); + + if (!file.isNull()) + { + strlcpy(m_setting->value.target.string, QDir::toNativeSeparators(file).toUtf8().data(), m_setting->size); + + handleChange(m_setting); + } +} + +void FontButton::onClicked(bool) +{ + QString file = QFileDialog::getOpenFileName( + this, + "Choose Font", + QString(m_setting->default_value.string), + "TrueType font (*.ttf)"); + + if (!file.isNull()) + { + strlcpy(m_setting->value.target.string, QDir::toNativeSeparators(file).toUtf8().data(), m_setting->size); + + handleChange(m_setting); + } +} + +DirectorySelector::DirectorySelector(rarch_setting_t *setting, QWidget *parent) : + QHBoxLayout(parent) +{ + addWidget(new StringLineEdit(setting)); + addWidget(new DirectoryButton(setting)); +} + +FileSelector::FileSelector(const char *setting, QWidget *parent) : + FileSelector(menu_setting_find(setting), parent) +{ +} + +FileSelector::FileSelector(rarch_setting_t *setting, QWidget *parent) : + QHBoxLayout(parent) +{ + addWidget(new StringLineEdit(setting)); + addWidget(new FileButton(setting)); +} + +FontSelector::FontSelector(rarch_setting_t *setting, QWidget *parent) : + QHBoxLayout(parent) +{ + addWidget(new StringLineEdit(setting)); + addWidget(new FontButton(setting)); +} + +FloatSlider::FloatSlider(const char *setting, QWidget *parent) : + FloatSlider(menu_setting_find(setting), parent) +{ +} + +FloatSlider::FloatSlider(rarch_setting_t *setting, QWidget *parent) : + QSlider(Qt::Horizontal, parent) + ,m_setting(setting) + ,m_value(setting->value.target.fraction) + ,m_decimalsRegEx("%.(\\d)f") +{ + QRegularExpressionMatch match = m_decimalsRegEx.match(setting->rounding_fraction); + + if (match.hasMatch()) + m_precision = pow(10, match.captured(1).toInt()); + else + m_precision = pow(10, 3); + + setMinimum(setting->enforce_minrange ? setting->min * m_precision : 0.00 * m_precision); + setMaximum(setting->enforce_maxrange ? setting->max * m_precision : 999.00 * m_precision); + + setSingleStep(setting->step * m_precision); + + setValue(*m_value * m_precision); + + connect(this, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int))); + + addSublabelAndWhatsThis(this, m_setting); +} + +void FloatSlider::onValueChanged(int value) +{ + *m_value = (float)value / m_precision; + + handleChange(m_setting); +} + +void FloatSlider::paintEvent(QPaintEvent *event) +{ + if (value() / m_precision != *m_value) + { + blockSignals(true); + + setValue(*m_value * m_precision); + + blockSignals(false); + } + + QSlider::paintEvent(event); +} + +FloatSliderAndSpinBox::FloatSliderAndSpinBox(const char *setting, QWidget *parent) : + FloatSliderAndSpinBox(menu_setting_find(setting), parent) +{ +} + +FloatSliderAndSpinBox::FloatSliderAndSpinBox(msg_hash_enums enum_idx, QWidget *parent) : + FloatSliderAndSpinBox(menu_setting_find_enum(enum_idx), parent) +{ +} + +FloatSliderAndSpinBox::FloatSliderAndSpinBox(rarch_setting_t *setting, QWidget *parent) : + QHBoxLayout(parent) + ,m_slider(new FloatSlider(setting)) + ,m_spinBox(new FloatSpinBox(setting)) +{ + addWidget(m_slider); + addWidget(m_spinBox); + + connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(onSliderValueChanged(int))); + connect(m_spinBox, SIGNAL(valueChanged(double)), this, SLOT(onSpinBoxValueChanged(double))); +} + +void FloatSliderAndSpinBox::onSliderValueChanged(int value) +{ + Q_UNUSED(value); + + m_spinBox->update(); +} + +void FloatSliderAndSpinBox::onSpinBoxValueChanged(double value) +{ + Q_UNUSED(value); + + m_slider->update(); +} + +BindButton::BindButton(rarch_setting_t *setting, QWidget *parent) : + QPushButton(parent) + ,m_setting(setting) +{ + char val_s[256]; + + setting->get_string_representation(setting, val_s, sizeof(val_s)); + + setText(val_s); + + connect(this, SIGNAL(clicked(bool)), this, SLOT(onClicked(bool))); +} + +BindButton::BindButton(msg_hash_enums enum_idx, QWidget *parent) : + BindButton(menu_setting_find_enum(enum_idx), parent) +{ +} + +void BindButton::onClicked(bool checked) +{ + Q_UNUSED(checked); + + m_setting->action_ok(m_setting, false); +} + +ColorButton::ColorButton(rarch_setting_t *red, rarch_setting_t *green, rarch_setting_t *blue, QWidget *parent) : + QToolButton(parent) + ,m_red(red) + ,m_green(green) + ,m_blue(blue) + ,m_dialog(new QColorDialog(this)) +{ + setMinimumSize(64, 0); + + m_dialog->setOptions(QColorDialog::NoButtons); + + connect(this, SIGNAL(clicked()), m_dialog, SLOT(open())); + connect(m_dialog, SIGNAL(currentColorChanged(const QColor&)), this, SLOT(onColorChanged(const QColor&))); +} + +ColorButton::ColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent) : + ColorButton(menu_setting_find_enum(red), menu_setting_find_enum(green), menu_setting_find_enum(blue), parent) +{ +} + +/* Stolen from Qt Creator's QtColorButton */ +void ColorButton::paintEvent(QPaintEvent *event) +{ + QToolButton::paintEvent(event); + if (!isEnabled()) + return; + + const int pixSize = 10; + QBrush br(color()); + + QPainter p(this); + const int corr = 5; + QRect r = rect().adjusted(corr, corr, -corr, -corr); + p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr); + p.fillRect(r, br); + + const QColor frameColor1(0, 0, 0, 26); + p.setPen(frameColor1); + p.drawRect(r.adjusted(1, 1, -2, -2)); + const QColor frameColor2(0, 0, 0, 51); + p.setPen(frameColor2); + p.drawRect(r.adjusted(0, 0, -1, -1)); +} + +UIntColorButton::UIntColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent) : + ColorButton(red, green, blue, parent) +{ +} + +UIntColorButton::UIntColorButton(rarch_setting_t *red, rarch_setting_t *green, rarch_setting_t *blue, QWidget *parent) : + ColorButton(red, green, blue, parent) +{ +} + +void UIntColorButton::onColorChanged(const QColor &color) +{ + if (color.isValid()) + { + *m_red->value.target.unsigned_integer = color.red(); + *m_green->value.target.unsigned_integer = color.green(); + *m_blue->value.target.unsigned_integer = color.blue(); + } +} + +QColor UIntColorButton::color() +{ + return QColor( + *m_red->value.target.unsigned_integer, + *m_green->value.target.unsigned_integer, + *m_blue->value.target.unsigned_integer); +} + +FloatColorButton::FloatColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent) : + ColorButton(red, green, blue, parent) +{ +} + +void FloatColorButton::onColorChanged(const QColor &color) +{ + if (color.isValid()) + { + *m_red->value.target.fraction = color.red() / 255.0f; + *m_green->value.target.fraction = color.green() / 255.0f; + *m_blue->value.target.fraction = color.blue() / 255.0f; + } +} + +QColor FloatColorButton::color() +{ + return QColor( + *m_red->value.target.fraction * 255, + *m_green->value.target.fraction * 255, + *m_blue->value.target.fraction * 255); +} diff --git a/ui/drivers/qt/settingswidgets.h b/ui/drivers/qt/settingswidgets.h new file mode 100644 index 0000000000..cf2adaaced --- /dev/null +++ b/ui/drivers/qt/settingswidgets.h @@ -0,0 +1,421 @@ +#ifndef SETTINGSWIDGETS_H +#define SETTINGSWIDGETS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CXX_BUILD +extern "C" { +#endif + +#include "../../../configuration.h" +#include "../../../setting_list.h" +#include "../../../menu/menu_setting.h" +#include "../../../menu/menu_cbs.h" + +#ifndef CXX_BUILD +} +#endif + +static const QString FONT_FILTER = QStringLiteral("TrueType font (*.ttf)"); + +class FormLayout : public QFormLayout +{ +public: + FormLayout(QWidget *parent = 0); + void addUIntSpinBox(msg_hash_enums enum_idx); + void addSizeSpinBox(msg_hash_enums enum_idx, unsigned scale = 1024 * 1024); + void addFloatSpinBox(msg_hash_enums enum_idx); + void addDirectorySelector(msg_hash_enums enum_idx); + void addFileSelector(msg_hash_enums enum_idx); + void addFontSelector(msg_hash_enums enum_idx); + void addCheckBox(msg_hash_enums enum_idx); + void addUIntComboBox(msg_hash_enums enum_idx); + void addUIntRadioButtons(msg_hash_enums enum_idx); + void addStringComboBox(msg_hash_enums enum_idx); + void addStringLineEdit(msg_hash_enums enum_idx); + void addPasswordLineEdit(msg_hash_enums enum_idx); + void addFloatSliderAndSpinBox(msg_hash_enums enum_idx); + void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b); + bool addBindButton(msg_hash_enums enum_idx); +}; + +class SettingsGroup : public QGroupBox +{ + Q_OBJECT +public: + SettingsGroup(const QString &title, QWidget *parent = 0); + SettingsGroup(QWidget *parent = 0); + void addWidget(QWidget *widget); + void addRow(QString label, QWidget *widget); + void addRow(QWidget *widget); + void addRow(QLayout *layout); + void addRow(QString label, QLayout *layout); + void addCheckBox(msg_hash_enums enum_idx); + void addFileSelector(msg_hash_enums enum_idx); + void addDirectorySelector(msg_hash_enums enum_idx); + void addFontSelector(msg_hash_enums enum_idx); + void addStringLineEdit(msg_hash_enums enum_idx); + void addPasswordLineEdit(msg_hash_enums enum_idx); + void addStringComboBox(msg_hash_enums enum_idx); + void addUIntSpinBox(msg_hash_enums enum_idx); + void addUIntComboBox(msg_hash_enums enum_idx); + void addUIntRadioButtons(msg_hash_enums enum_idx); + void addFloatSpinBox(msg_hash_enums enum_idx); + void addFloatSliderAndSpinBox(msg_hash_enums enum_idx); + void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b); + void addBindButton(msg_hash_enums enum_idx); +private: + FormLayout *m_layout; +}; + +class CheckableSettingsGroup : public SettingsGroup +{ + Q_OBJECT +public: + CheckableSettingsGroup(rarch_setting_t *setting, QWidget *parent = 0); + CheckableSettingsGroup(const char *setting, QWidget *parent = 0); + CheckableSettingsGroup(msg_hash_enums enum_idx, QWidget *parent = 0); +private slots: + void onClicked(bool clicked); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + bool *m_value; +}; + +class CheckBox : public QCheckBox +{ + Q_OBJECT +public: + CheckBox(rarch_setting_t *setting, QWidget *parent = 0); + CheckBox(const char *setting, QWidget *parent = 0); + CheckBox(msg_hash_enums enum_idx, QWidget *parent = 0); +private slots: + void onClicked(bool checked); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + bool *m_value; +}; + +class CheckableIcon : public QToolButton +{ + Q_OBJECT +public: + CheckableIcon(rarch_setting_t *setting, const QIcon &icon, QWidget *parent = 0); + CheckableIcon(const char *setting, const QIcon &icon, QWidget *parent = 0); + CheckableIcon(msg_hash_enums enum_idx, const QIcon &icon, QWidget *parent = 0); +private slots: + void onToggled(bool checked); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + bool *m_value; +}; + +class StringLineEdit : public QLineEdit +{ + Q_OBJECT +public: + StringLineEdit(rarch_setting_t *setting, QWidget *parent = 0); + StringLineEdit(const char *setting, QWidget *parent = 0); +private slots: + void onEditingFinished(); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + char *m_value; +}; + +class PasswordLineEdit : public StringLineEdit +{ + Q_OBJECT +public: + PasswordLineEdit(rarch_setting_t *setting, QWidget *parent = 0); +}; + +class StringComboBox : public QComboBox +{ + Q_OBJECT +public: + StringComboBox(rarch_setting_t *setting, QWidget *parent = 0); + StringComboBox(const char *setting, QWidget *parent = 0); +private slots: + void onCurrentTextChanged(const QString &text); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + char *m_value; +}; + +class UIntComboBox : public QComboBox +{ + Q_OBJECT +public: + UIntComboBox(rarch_setting_t *setting, QWidget *parent = 0); + UIntComboBox(rarch_setting_t *setting, double min, double max, QWidget *parent = 0); + UIntComboBox(msg_hash_enums enum_idx, QWidget *parent = 0); + UIntComboBox(msg_hash_enums enum_idx, double min, double max, QWidget *parent = 0); + UIntComboBox(const char *setting, QWidget *parent = 0); +private slots: + void onCurrentIndexChanged(int index); + void paintEvent(QPaintEvent *event); +private: + void populate(double min, double max); + rarch_setting_t *m_setting; + unsigned *m_value; + QHash m_hash; +}; + +class UIntRadioButton : public QRadioButton +{ + Q_OBJECT +public: + UIntRadioButton(const QString &text, rarch_setting_t *setting, unsigned value, QWidget *parent = 0); + UIntRadioButton(msg_hash_enums enum_idx, unsigned value, QWidget *parent = 0); +private slots: + void onClicked(bool); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + unsigned *m_target; + unsigned m_value; +}; + +class UIntRadioButtons : public QGroupBox +{ + Q_OBJECT +public: + UIntRadioButtons(rarch_setting_t *setting, QWidget *parent = 0); + UIntRadioButtons(const char *setting, QWidget *parent = 0); + UIntRadioButtons(msg_hash_enums enum_idx, QWidget *parent = 0); +signals: + void currentUIntChanged(unsigned value); +private slots: + void onButtonClicked(int id); +private: + rarch_setting_t *m_setting; + unsigned *m_value; + QButtonGroup *m_buttonGroup; +}; + +class UIntSpinBox : public QSpinBox +{ + Q_OBJECT +public: + UIntSpinBox(rarch_setting_t *setting, QWidget *parent = 0); + UIntSpinBox(msg_hash_enums enum_idx, QWidget *parent = 0); +private slots: + void onValueChanged(int value); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + unsigned *m_value; +}; + +class SizeSpinBox : public QSpinBox +{ + Q_OBJECT +public: + SizeSpinBox(rarch_setting_t *setting, unsigned scale = 1024*1024, QWidget *parent = 0); + SizeSpinBox(msg_hash_enums enum_idx, unsigned scale = 1024 * 1024, QWidget *parent = 0); +private slots: + void onValueChanged(int value); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + size_t *m_value; + unsigned m_scale; +}; + +class IntSpinBox : public QSpinBox +{ + Q_OBJECT +public: + IntSpinBox(rarch_setting_t *setting, QWidget *parent = 0); +private slots: + void onValueChanged(int value); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + int *m_value; +}; + +class FloatSpinBox : public QDoubleSpinBox +{ + Q_OBJECT +public: + FloatSpinBox(rarch_setting_t *setting, QWidget *parent = 0); + FloatSpinBox(const char *setting, QWidget *parent = 0); + FloatSpinBox(msg_hash_enums enum_idx, QWidget *parent = 0); +private slots: + void onValueChanged(double value); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + float *m_value; + static const QRegularExpression DECIMALS_REGEX; +}; + +class PathButton : public QPushButton +{ + Q_OBJECT +public: + PathButton(rarch_setting_t *setting, QWidget *parent = 0); + PathButton(const char *setting, QWidget *parent = 0); +protected slots: + virtual void onClicked(bool checked = false) { Q_UNUSED( checked); } +protected: + QString m_filter; + rarch_setting_t *m_setting; + char *m_value; + const char *m_dir; +}; + +class DirectoryButton : public PathButton +{ + Q_OBJECT +public: + DirectoryButton(rarch_setting_t *setting, QWidget *parent = 0) : + PathButton(setting, parent) {} +private: + void onClicked(bool checked = false); +}; + +class FileButton : public PathButton +{ + Q_OBJECT +public: + FileButton(rarch_setting_t *setting, QWidget *parent = 0) : + PathButton(setting, parent) {} +private: + void onClicked(bool checked = false); +}; + +class FontButton : public PathButton +{ + Q_OBJECT +public: + FontButton(rarch_setting_t *setting, QWidget *parent = 0) : + PathButton(setting, parent) {} +private: + void onClicked(bool checked = false); +}; + +class DirectorySelector : public QHBoxLayout +{ + Q_OBJECT +public: + DirectorySelector(rarch_setting_t *setting, QWidget *parent = 0); +}; + +class FileSelector : public QHBoxLayout +{ + Q_OBJECT +public: + FileSelector(rarch_setting_t *setting, QWidget *parent = 0); + FileSelector(const char *setting, QWidget *parent = 0); +}; + +class FontSelector : public QHBoxLayout +{ + Q_OBJECT +public: + FontSelector(rarch_setting_t *setting, QWidget *parent = 0); +}; + +class FloatSlider : public QSlider +{ + Q_OBJECT +public: + FloatSlider(rarch_setting_t *setting, QWidget *parent = 0); + FloatSlider(const char *setting, QWidget *parent = 0); +private slots: + void onValueChanged(int value); + void paintEvent(QPaintEvent *event); +private: + rarch_setting_t *m_setting; + float *m_value; + QRegularExpression m_decimalsRegEx; + unsigned int m_precision; +}; + +class FloatSliderAndSpinBox : public QHBoxLayout +{ + Q_OBJECT +public: + FloatSliderAndSpinBox(rarch_setting_t *setting, QWidget *parent = 0); + FloatSliderAndSpinBox(const char *setting, QWidget *parent = 0); + FloatSliderAndSpinBox(msg_hash_enums enum_idx, QWidget *parent = 0); +private slots: + void onSliderValueChanged(int value); + void onSpinBoxValueChanged(double value); +private: + FloatSlider *m_slider; + FloatSpinBox *m_spinBox; +}; + +class BindButton : public QPushButton +{ + Q_OBJECT +public: + BindButton(rarch_setting_t *setting, QWidget *parent = 0); + BindButton(msg_hash_enums enum_idx, QWidget *parent = 0); +private slots: + void onClicked(bool checked); +private: + rarch_setting_t *m_setting; +}; + +class ColorButton : public QToolButton +{ + Q_OBJECT +public: + ColorButton(rarch_setting_t *red, rarch_setting_t *green, rarch_setting_t *blue, QWidget *parent = 0); + ColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent = 0); +protected slots: + virtual void onColorChanged(const QColor& color) { Q_UNUSED(color); } +protected: + virtual QColor color() { return QColor(); } + void paintEvent(QPaintEvent *event); + + rarch_setting_t *m_red, *m_green, *m_blue; + QColorDialog *m_dialog; +}; + +class UIntColorButton : public ColorButton +{ + Q_OBJECT +public: + UIntColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent = 0); + UIntColorButton(rarch_setting_t *red, rarch_setting_t *green, rarch_setting_t *blue, QWidget *parent = 0); +protected slots: + void onColorChanged(const QColor& color); +protected: + QColor color(); +}; + +class FloatColorButton : public ColorButton +{ + Q_OBJECT +public: + explicit FloatColorButton(msg_hash_enums red, msg_hash_enums green, msg_hash_enums blue, QWidget *parent = 0); +protected slots: + void onColorChanged(const QColor& color); +protected: + QColor color(); +}; + +#endif diff --git a/ui/drivers/qt/ui_qt_themes.h b/ui/drivers/qt/ui_qt_themes.h index e7e43db132..31ff876387 100644 --- a/ui/drivers/qt/ui_qt_themes.h +++ b/ui/drivers/qt/ui_qt_themes.h @@ -12,7 +12,6 @@ static const QString qt_theme_default_stylesheet = QStringLiteral(R"( ThumbnailWidget#thumbnailWidget, ThumbnailLabel#thumbnailGridLabel, QLabel#thumbnailQLabel { background-color:#d4d4d4; } - QLabel#dropIndicator { font-size: 9pt; color: darkgrey; @@ -27,9 +26,13 @@ static const QString qt_theme_default_stylesheet = QStringLiteral(R"( QFrame#playlistWidget, QFrame#browserWidget, QFrame#logWidget { padding: 8px; } - ListWidget { + QListWidget { icon-size: 32px; } + /* color of the icons on the settings dialog */ + /* QLabel#iconColor { + color: black; + } */ )"); static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( @@ -46,7 +49,7 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( border-right:1px solid rgba(125,125,125,50%); border-bottom:1px solid rgba(25,25,25,75%); } - ListWidget { + QListWidget { icon-size: 32px; } QLabel#dropIndicator { diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index 1bc4e164f7..f79df2c354 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -1249,6 +1249,9 @@ void MainWindow::setTheme(Theme theme) default: break; } +#ifdef HAVE_MENU + m_viewOptionsDialog->repaintIcons(); +#endif } void MainWindow::setDefaultCustomProperties() diff --git a/ui/drivers/qt/viewoptionsdialog.cpp b/ui/drivers/qt/viewoptionsdialog.cpp index 2b5e3a3ba5..52404998c7 100644 --- a/ui/drivers/qt/viewoptionsdialog.cpp +++ b/ui/drivers/qt/viewoptionsdialog.cpp @@ -12,6 +12,15 @@ #include #include "viewoptionsdialog.h" + +#ifdef HAVE_MENU +#include +#include +#include + +#include "options/options.h" +#endif + #include "../ui_qt.h" #ifndef CXX_BUILD @@ -24,8 +33,187 @@ extern "C" { } #endif +#ifdef HAVE_MENU + +QPixmap getColorizedPixmap(const QPixmap& oldPixmap, const QColor& color) +{ + QPixmap pixmap = oldPixmap; + QBitmap mask = pixmap.createMaskFromColor(Qt::transparent, Qt::MaskInColor); + pixmap.fill(color); + pixmap.setMask(mask); + return pixmap; +} + +QColor getLabelColor(const QString& objectName) +{ + QLabel dummyColor; + dummyColor.setObjectName(objectName); + dummyColor.ensurePolished(); + return dummyColor.palette().color(QPalette::Foreground); +} + ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : QDialog(mainwindow) + , m_optionsList(new QListWidget(this)) + , m_optionsStack(new QStackedWidget(this)) +{ + QGridLayout *layout = new QGridLayout(this); + QLabel *m_headerLabel = new QLabel(this); + // Header label with large font and a bit of spacing (align with group boxes) + QFont headerLabelFont = m_headerLabel->font(); + const int pointSize = headerLabelFont.pointSize(); + QHBoxLayout *headerHLayout = new QHBoxLayout; + const int leftMargin = QApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin); + int width; + + headerLabelFont.setBold(true); + + // Paranoia: Should a font be set in pixels... + if (pointSize > 0) + headerLabelFont.setPointSize(pointSize + 2); + + m_headerLabel->setFont(headerLabelFont); + + headerHLayout->addSpacerItem(new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); + headerHLayout->addWidget(m_headerLabel); + + addCategory(new DriversCategory(this)); + addCategory(new VideoCategory(this)); + addCategory(new AudioCategory(this)); + addCategory(new InputCategory(this)); + addCategory(new LatencyCategory(this)); + addCategory(new CoreCategory(this)); + addCategory(new ConfigurationCategory(this)); + addCategory(new SavingCategory(this)); + addCategory(new LoggingCategory(this)); + addCategory(new FrameThrottleCategory(this)); + addCategory(new RecordingCategory(this)); + addCategory(new OnscreenDisplayCategory(this)); + addCategory(new UserInterfaceCategory(mainwindow, this)); + addCategory(new AchievementsCategory(this)); + addCategory(new NetworkCategory(this)); + addCategory(new PlaylistsCategory(this)); + addCategory(new UserCategory(this)); + addCategory(new DirectoryCategory(this)); + + width = m_optionsList->sizeHintForColumn(0) + m_optionsList->frameWidth() * 2 + 5; + width += m_optionsList->verticalScrollBar()->sizeHint().width(); + + m_optionsList->setMaximumWidth(width); + m_optionsList->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); + + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE)); + + layout->addWidget(m_optionsList, 0, 0, 2, 1); + layout->addLayout(headerHLayout, 0, 1); + layout->addWidget(m_optionsStack, 1, 1); + + connect(m_optionsList, SIGNAL(currentRowChanged(int)), m_optionsStack, SLOT(setCurrentIndex(int))); + connect(m_optionsList, SIGNAL(currentTextChanged(const QString&)), m_headerLabel, SLOT(setText(const QString&))); + + connect(this, SIGNAL(rejected()), this, SLOT(onRejected())); +} + +QIcon getIcon(OptionsCategory *category) { + QPixmap pixmap = QPixmap(QString(config_get_ptr()->paths.directory_assets) + "/xmb/monochrome/png/" + category->categoryIconName() + ".png"); + return QIcon(getColorizedPixmap(pixmap, getLabelColor("iconColor"))); +} + +void ViewOptionsDialog::addCategory(OptionsCategory *category) +{ + QTabWidget *tabWidget = new QTabWidget(); + + m_categoryList.append(category); + + for (OptionsPage* page : category->pages()) + { + QWidget *widget = page->widget(); + widget->setAutoFillBackground(false); + tabWidget->addTab(widget, page->displayName()); + } + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) + tabWidget->setTabBarAutoHide(true); +#else + /* TODO remove the tabBar's space */ + if (tabWidget->count() < 2) + tabWidget->tabBar()->hide(); +#endif + m_optionsList->addItem(new QListWidgetItem(getIcon(category), category->displayName())); + m_optionsStack->addWidget(tabWidget); +} + +void ViewOptionsDialog::repaintIcons() +{ + int i; + + for (i = 0; i < m_categoryList.size(); i++) + { + m_optionsList->item(i)->setIcon(getIcon(m_categoryList.at(i))); + } +} + +#else + +ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : + QDialog(mainwindow) + , m_viewOptionsWidget(new ViewOptionsWidget(mainwindow)) +{ + QVBoxLayout *layout = new QVBoxLayout; + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + connect(this, SIGNAL(accepted()), m_viewOptionsWidget, SLOT(onAccepted())); + connect(this, SIGNAL(rejected()), m_viewOptionsWidget, SLOT(onRejected())); + + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE)); + + layout->setContentsMargins(0, 0, 0, 0); + + layout->addWidget(m_viewOptionsWidget); + layout->addWidget(buttonBox); + + setLayout(layout); +} + +#endif + +void ViewOptionsDialog::showDialog() +{ +#ifndef HAVE_MENU + m_viewOptionsWidget->loadViewOptions(); +#else + int i; + for (i = 0; i < m_categoryList.size(); i++) + { + m_categoryList.at(i)->load(); + } +#endif + show(); + activateWindow(); +} + +void ViewOptionsDialog::hideDialog() +{ + reject(); +} + +void ViewOptionsDialog::onRejected() +{ +#ifdef HAVE_MENU + int i; + + for (i = 0; i < m_categoryList.size(); i++) + { + m_categoryList.at(i)->apply(); + } +#endif +} + +ViewOptionsWidget::ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent) : + QWidget(parent) ,m_mainwindow(mainwindow) ,m_settings(mainwindow->settings()) ,m_saveGeometryCheckBox(new QCheckBox(this)) @@ -44,10 +232,8 @@ ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : /* ,m_allPlaylistsListMaxCountSpinBox(new QSpinBox(this)) */ /* ,m_allPlaylistsGridMaxCountSpinBox(new QSpinBox(this)) */ { - QFormLayout *form = new QFormLayout(); - QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - - setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE)); + QVBoxLayout *layout = new QVBoxLayout; + QFormLayout *form = new QFormLayout; m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_SYSTEM_DEFAULT), MainWindow::THEME_SYSTEM_DEFAULT); m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK), MainWindow::THEME_DARK); @@ -66,14 +252,6 @@ ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : form->setFormAlignment(Qt::AlignCenter); form->setLabelAlignment(Qt::AlignCenter); - setLayout(new QVBoxLayout(this)); - - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - connect(this, SIGNAL(accepted()), this, SLOT(onAccepted())); - connect(this, SIGNAL(rejected()), this, SLOT(onRejected())); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY), m_saveGeometryCheckBox); form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS), m_saveDockPositionsCheckBox); form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB), m_saveLastTabCheckBox); @@ -87,9 +265,11 @@ ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME), m_themeComboBox); form->addRow(m_highlightColorLabel, m_highlightColorPushButton); - qobject_cast(layout())->addLayout(form); - layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); - layout()->addWidget(buttonBox); + layout->addLayout(form); + + layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + setLayout(layout); loadViewOptions(); @@ -98,13 +278,13 @@ ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : connect(m_highlightColorPushButton, SIGNAL(clicked()), this, SLOT(onHighlightColorChoose())); } -void ViewOptionsDialog::onThumbnailComboBoxIndexChanged(int index) +void ViewOptionsWidget::onThumbnailComboBoxIndexChanged(int index) { ThumbnailType type = static_cast(m_thumbnailComboBox->currentData().value()); m_mainwindow->setCurrentThumbnailType(type); } -void ViewOptionsDialog::onThemeComboBoxIndexChanged(int) +void ViewOptionsWidget::onThemeComboBoxIndexChanged(int) { MainWindow::Theme theme = static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()); @@ -137,7 +317,7 @@ void ViewOptionsDialog::onThemeComboBoxIndexChanged(int) showOrHideHighlightColor(); } -void ViewOptionsDialog::onHighlightColorChoose() +void ViewOptionsWidget::onHighlightColorChoose() { QPixmap highlightPixmap(m_highlightColorPushButton->iconSize()); QColor currentHighlightColor = m_settings->value("highlight_color", QApplication::palette().highlight().color()).value(); @@ -155,7 +335,7 @@ void ViewOptionsDialog::onHighlightColorChoose() } } -void ViewOptionsDialog::loadViewOptions() +void ViewOptionsWidget::loadViewOptions() { QColor highlightColor = m_settings->value("highlight_color", QApplication::palette().highlight().color()).value(); QPixmap highlightPixmap(m_highlightColorPushButton->iconSize()); @@ -209,7 +389,7 @@ void ViewOptionsDialog::loadViewOptions() m_startupPlaylistComboBox->setCurrentIndex(playlistIndex); } -void ViewOptionsDialog::showOrHideHighlightColor() +void ViewOptionsWidget::showOrHideHighlightColor() { if (m_mainwindow->theme() == MainWindow::THEME_DARK) { @@ -223,7 +403,7 @@ void ViewOptionsDialog::showOrHideHighlightColor() } } -void ViewOptionsDialog::saveViewOptions() +void ViewOptionsWidget::saveViewOptions() { m_settings->setValue("save_geometry", m_saveGeometryCheckBox->isChecked()); m_settings->setValue("save_dock_positions", m_saveDockPositionsCheckBox->isChecked()); @@ -246,29 +426,12 @@ void ViewOptionsDialog::saveViewOptions() m_mainwindow->setThumbnailCacheLimit(m_thumbnailCacheSpinBox->value()); } -void ViewOptionsDialog::onAccepted() +void ViewOptionsWidget::onAccepted() { - MainWindow::Theme newTheme = static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()); - - m_mainwindow->setTheme(newTheme); - saveViewOptions(); } -void ViewOptionsDialog::onRejected() +void ViewOptionsWidget::onRejected() { loadViewOptions(); } - -void ViewOptionsDialog::showDialog() -{ - loadViewOptions(); - setWindowFlags(windowFlags() | Qt::Tool); - show(); - activateWindow(); -} - -void ViewOptionsDialog::hideDialog() -{ - reject(); -} diff --git a/ui/drivers/qt/viewoptionsdialog.h b/ui/drivers/qt/viewoptionsdialog.h index 4e9ff4c76a..7116a50f25 100644 --- a/ui/drivers/qt/viewoptionsdialog.h +++ b/ui/drivers/qt/viewoptionsdialog.h @@ -12,23 +12,28 @@ class QColor; class QLabel; class QSpinBox; -class ViewOptionsDialog : public QDialog +#ifdef HAVE_MENU +class QWidget; +class OptionsCategory; +class QListWidget; +class QStackedWidget; +#endif + +class ViewOptionsWidget : public QWidget { Q_OBJECT public: - ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent = 0); + ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent = 0); public slots: - void showDialog(); - void hideDialog(); void onAccepted(); void onRejected(); + void loadViewOptions(); + void saveViewOptions(); private slots: void onThemeComboBoxIndexChanged(int index); void onThumbnailComboBoxIndexChanged(int index); void onHighlightColorChoose(); private: - void loadViewOptions(); - void saveViewOptions(); void showOrHideHighlightColor(); MainWindow *m_mainwindow; @@ -50,4 +55,31 @@ private: QSpinBox *m_allPlaylistsGridMaxCountSpinBox; }; +class ViewOptionsDialog : public QDialog +{ + Q_OBJECT +public: + ViewOptionsDialog(MainWindow *window, QWidget *parent = 0); + // Make sure the settings dialog starts up as small as possible. + QSize sizeHint() const final { return minimumSize(); } +#ifdef HAVE_MENU + void repaintIcons(); +#endif +public slots: + void showDialog(); + void hideDialog(); +private slots: + void onRejected(); +private: +#ifdef HAVE_MENU + void addCategory(QWidget *widget, QString name, QString icon); + void addCategory(OptionsCategory *category); + QVector m_categoryList; + QListWidget *m_optionsList; + QStackedWidget *m_optionsStack; +#else + ViewOptionsWidget *m_viewOptionsWidget; +#endif +}; + #endif From c2122ed1d8944f8d194f887833ad5e41a4c8d714 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Wed, 27 Mar 2019 16:29:23 +0000 Subject: [PATCH 091/237] (RGUI) Add inline playlist thumbnail support --- config.def.h | 2 + configuration.c | 2 + configuration.h | 2 + intl/msg_hash_lbl.h | 4 + intl/msg_hash_us.h | 34 ++- menu/cbs/menu_cbs_scan.c | 16 +- menu/cbs/menu_cbs_sublabel.c | 26 +- menu/drivers/rgui.c | 460 +++++++++++++++++++++++++++-------- menu/menu_displaylist.c | 8 + menu/menu_setting.c | 127 +++++++--- msg_hash.h | 4 + 11 files changed, 540 insertions(+), 145 deletions(-) diff --git a/config.def.h b/config.def.h index 3ceef8ad7e..5a5cabcf4d 100644 --- a/config.def.h +++ b/config.def.h @@ -384,6 +384,8 @@ static unsigned menu_shader_pipeline = 2; static bool show_advanced_settings = false; static unsigned rgui_color_theme = RGUI_THEME_CLASSIC_GREEN; +static bool rgui_inline_thumbnails = false; +static bool rgui_swap_thumbnails = false; static unsigned rgui_thumbnail_downscaler = RGUI_THUMB_SCALE_POINT; static unsigned rgui_internal_upscale_level = RGUI_UPSCALE_NONE; static bool rgui_full_width_layout = true; diff --git a/configuration.c b/configuration.c index 02a7ed77d2..ad007934d0 100644 --- a/configuration.c +++ b/configuration.c @@ -1509,6 +1509,8 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("rgui_border_filler_thickness_enable", &settings->bools.menu_rgui_border_filler_thickness_enable, true, true, false); SETTING_BOOL("rgui_border_filler_enable", &settings->bools.menu_rgui_border_filler_enable, true, true, false); SETTING_BOOL("menu_rgui_full_width_layout", &settings->bools.menu_rgui_full_width_layout, true, rgui_full_width_layout, false); + SETTING_BOOL("rgui_inline_thumbnails", &settings->bools.menu_rgui_inline_thumbnails, true, rgui_inline_thumbnails, false); + SETTING_BOOL("rgui_swap_thumbnails", &settings->bools.menu_rgui_swap_thumbnails, true, rgui_swap_thumbnails, false); #endif #ifdef HAVE_XMB SETTING_BOOL("xmb_shadows_enable", &settings->bools.menu_xmb_shadows_enable, true, xmb_shadows_enable, false); diff --git a/configuration.h b/configuration.h index 75badb90cd..7d4728b9eb 100644 --- a/configuration.h +++ b/configuration.h @@ -172,6 +172,8 @@ typedef struct settings bool menu_rgui_border_filler_thickness_enable; bool menu_rgui_border_filler_enable; bool menu_rgui_full_width_layout; + bool menu_rgui_inline_thumbnails; + bool menu_rgui_swap_thumbnails; bool menu_xmb_shadows_enable; bool menu_xmb_vertical_thumbnails; bool menu_content_show_settings; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index e86bd83c77..4faa07bd24 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1133,6 +1133,10 @@ MSG_HASH(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, "xmb_vertical_thumbnails") MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER, "rgui_thumbnail_downscaler") +MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS, + "rgui_inline_thumbnails") +MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS, + "rgui_swap_thumbnails") MSG_HASH(MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY, "thumbnails_directory") MSG_HASH(MENU_ENUM_LABEL_THUMBNAILS_UPDATER_LIST, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 750eafe636..15b88d24ea 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -2970,10 +2970,18 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_THUMBNAILS, "Thumbnails" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAILS_RGUI, + "Top Thumbnail" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS, "Left Thumbnails" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_RGUI, + "Bottom Thumbnail" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_OZONE, "Second Thumbnail" @@ -2982,13 +2990,29 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS, "Thumbnails Vertical Disposition" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_RGUI_INLINE_THUMBNAILS, + "Show Playlist Thumbnails" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_RGUI_INLINE_THUMBNAILS, + "Enable display of inline downscaled thumbnails while viewing playlists. When disabled, 'Top Thumbnail' may still be toggled fullscreen by pressing RetroPad Y." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_RGUI_SWAP_THUMBNAILS, + "Swap Thumbnails" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_RGUI_SWAP_THUMBNAILS, + "Swaps the display positions of 'Top Thumbnail' and 'Bottom Thumbnail'." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MENU_RGUI_THUMBNAIL_DOWNSCALER, "Thumbnail Downscaling Method" ) MSG_HASH( MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER, - "Resampling method used when shrinking large thumbnails to fit the screen." + "Resampling method used when shrinking large thumbnails to fit the display." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_RGUI_THUMB_SCALE_POINT, @@ -5751,10 +5775,18 @@ MSG_HASH( MENU_ENUM_SUBLABEL_THUMBNAILS, "Type of thumbnail to display." ) +MSG_HASH( + MENU_ENUM_SUBLABEL_THUMBNAILS_RGUI, + "Type of thumbnail to display at the top right of playlists. This thumbnail may be toggled fullscreen by pressing RetroPad Y." + ) MSG_HASH( MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS, "Type of thumbnail to display at the left." ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS_RGUI, + "Type of thumbnail to display at the bottom right of playlists." + ) MSG_HASH( MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS_OZONE, "Replace the content metadata panel by another thumbnail." diff --git a/menu/cbs/menu_cbs_scan.c b/menu/cbs/menu_cbs_scan.c index 9376a99a00..ae6ce51091 100644 --- a/menu/cbs/menu_cbs_scan.c +++ b/menu/cbs/menu_cbs_scan.c @@ -111,11 +111,17 @@ int action_switch_thumbnail(const char *path, if (settings->uints.menu_thumbnails == 0) { - settings->uints.menu_left_thumbnails++; - if (settings->uints.menu_left_thumbnails > 3) - settings->uints.menu_left_thumbnails = 1; - menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_PATH, NULL); - menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_IMAGE, NULL); + /* RGUI is a special case where thumbnail 'switch' corresponds to + * toggling thumbnail view on/off. For other menu drivers, we + * cycle through available thumbnail types. */ + if(!string_is_equal(settings->arrays.menu_driver, "rgui")) + { + settings->uints.menu_left_thumbnails++; + if (settings->uints.menu_left_thumbnails > 3) + settings->uints.menu_left_thumbnails = 1; + menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_PATH, NULL); + menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_IMAGE, NULL); + } } else { diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 522d316ac2..f60a588484 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -312,7 +312,9 @@ default_sublabel_macro(action_bind_sublabel_stdin_cmd_enable, MENU_ default_sublabel_macro(action_bind_sublabel_mouse_enable, MENU_ENUM_SUBLABEL_MOUSE_ENABLE) default_sublabel_macro(action_bind_sublabel_pointer_enable, MENU_ENUM_SUBLABEL_POINTER_ENABLE) default_sublabel_macro(action_bind_sublabel_thumbnails, MENU_ENUM_SUBLABEL_THUMBNAILS) +default_sublabel_macro(action_bind_sublabel_thumbnails_rgui, MENU_ENUM_SUBLABEL_THUMBNAILS_RGUI) default_sublabel_macro(action_bind_sublabel_left_thumbnails, MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS) +default_sublabel_macro(action_bind_sublabel_left_thumbnails_rgui, MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS_RGUI) default_sublabel_macro(action_bind_sublabel_left_thumbnails_ozone, MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS_OZONE) default_sublabel_macro(action_bind_sublabel_timedate_enable, MENU_ENUM_SUBLABEL_TIMEDATE_ENABLE) default_sublabel_macro(action_bind_sublabel_timedate_style, MENU_ENUM_SUBLABEL_TIMEDATE_STYLE) @@ -526,6 +528,8 @@ default_sublabel_macro(action_bind_sublabel_menu_linear_filter, default_sublabel_macro(action_bind_sublabel_menu_rgui_aspect_ratio_lock, MENU_ENUM_SUBLABEL_MENU_RGUI_ASPECT_RATIO_LOCK) default_sublabel_macro(action_bind_sublabel_rgui_menu_color_theme, MENU_ENUM_SUBLABEL_RGUI_MENU_COLOR_THEME) default_sublabel_macro(action_bind_sublabel_rgui_menu_theme_preset, MENU_ENUM_SUBLABEL_RGUI_MENU_THEME_PRESET) +default_sublabel_macro(action_bind_sublabel_menu_rgui_inline_thumbnails, MENU_ENUM_SUBLABEL_MENU_RGUI_INLINE_THUMBNAILS) +default_sublabel_macro(action_bind_sublabel_menu_rgui_swap_thumbnails, MENU_ENUM_SUBLABEL_MENU_RGUI_SWAP_THUMBNAILS) default_sublabel_macro(action_bind_sublabel_menu_rgui_thumbnail_downscaler, MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER) default_sublabel_macro(action_bind_sublabel_content_runtime_log, MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG) default_sublabel_macro(action_bind_sublabel_content_runtime_log_aggregate, MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG_AGGREGATE) @@ -1599,11 +1603,23 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_timedate_style); break; case MENU_ENUM_LABEL_THUMBNAILS: - BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_thumbnails); + settings = config_get_ptr(); + if (string_is_equal(settings->arrays.menu_driver, "rgui")) + { + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_thumbnails_rgui); + } + else + { + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_thumbnails); + } break; case MENU_ENUM_LABEL_LEFT_THUMBNAILS: settings = config_get_ptr(); - if (string_is_equal(settings->arrays.menu_driver, "ozone")) + if (string_is_equal(settings->arrays.menu_driver, "rgui")) + { + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_left_thumbnails_rgui); + } + else if (string_is_equal(settings->arrays.menu_driver, "ozone")) { BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_left_thumbnails_ozone); } @@ -2408,6 +2424,12 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_rgui_menu_theme_preset); break; + case MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_inline_thumbnails); + break; + case MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_swap_thumbnails); + break; case MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_thumbnail_downscaler); break; diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index c748d96a67..06e861cbf0 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -448,9 +448,11 @@ typedef struct rgui_colors_t colors; bool is_playlist; bool entry_has_thumbnail; - bool show_thumbnail; + bool entry_has_left_thumbnail; + bool show_fs_thumbnail; menu_thumbnail_path_data_t *thumbnail_path_data; uint32_t thumbnail_queue_size; + uint32_t left_thumbnail_queue_size; bool show_wallpaper; char theme_preset_path[PATH_MAX_LENGTH]; /* Must be a fixed length array... */ char menu_title[255]; /* Must be a fixed length array... */ @@ -463,8 +465,13 @@ typedef struct struct scaler_ctx image_scaler; } rgui_t; +static unsigned mini_thumbnail_max_width = 0; +static unsigned mini_thumbnail_max_height = 0; + typedef struct { + unsigned max_width; + unsigned max_height; unsigned width; unsigned height; bool is_valid; @@ -472,7 +479,29 @@ typedef struct uint16_t *data; } thumbnail_t; -static thumbnail_t thumbnail = { +static thumbnail_t fs_thumbnail = { + 0, + 0, + 0, + 0, + false, + NULL, + NULL +}; + +static thumbnail_t mini_thumbnail = { + 0, + 0, + 0, + 0, + false, + NULL, + NULL +}; + +static thumbnail_t mini_left_thumbnail = { + 0, + 0, 0, 0, false, @@ -678,33 +707,34 @@ static void process_wallpaper(rgui_t *rgui, struct texture_image *image) rgui->force_redraw = true; } -static bool request_thumbnail(rgui_t *rgui, const char *path) +static bool request_thumbnail(thumbnail_t *thumbnail, enum menu_thumbnail_id thumbnail_id, uint32_t *queue_size, const char *path) { /* Do nothing if current thumbnail path hasn't changed */ - if (!string_is_empty(path) && !string_is_empty(thumbnail.path)) + if (!string_is_empty(path) && !string_is_empty(thumbnail->path)) { - if (string_is_equal(thumbnail.path, path)) + if (string_is_equal(thumbnail->path, path)) return true; } /* 'Reset' current thumbnail */ - thumbnail.width = 0; - thumbnail.height = 0; - thumbnail.is_valid = false; - free(thumbnail.path); - thumbnail.path = NULL; + thumbnail->width = 0; + thumbnail->height = 0; + thumbnail->is_valid = false; + free(thumbnail->path); + thumbnail->path = NULL; /* Ensure that new path is valid... */ if (!string_is_empty(path)) { - thumbnail.path = strdup(path); + thumbnail->path = strdup(path); if (filestream_exists(path)) { /* Would like to cancel any existing image load tasks * here, but can't see how to do it... */ - if(task_push_image_load(thumbnail.path, menu_display_handle_thumbnail_upload, NULL)) + if(task_push_image_load(thumbnail->path, (thumbnail_id == MENU_THUMBNAIL_LEFT) ? + menu_display_handle_left_thumbnail_upload : menu_display_handle_thumbnail_upload, NULL)) { - rgui->thumbnail_queue_size++; + *queue_size = *queue_size + 1; return true; } } @@ -713,28 +743,29 @@ static bool request_thumbnail(rgui_t *rgui, const char *path) return false; } -static bool downscale_thumbnail(rgui_t *rgui, struct texture_image *image_src, struct texture_image *image_dst) +static bool downscale_thumbnail(rgui_t *rgui, unsigned max_width, unsigned max_height, + struct texture_image *image_src, struct texture_image *image_dst) { settings_t *settings = config_get_ptr(); /* Determine output dimensions */ - float display_aspect_ratio = (float)rgui_frame_buf.width / (float)rgui_frame_buf.height; + float display_aspect_ratio = (float)max_width / (float)max_height; float aspect_ratio = (float)image_src->width / (float)image_src->height; if (aspect_ratio > display_aspect_ratio) { - image_dst->width = rgui_frame_buf.width; - image_dst->height = image_src->height * rgui_frame_buf.width / image_src->width; + image_dst->width = max_width; + image_dst->height = image_src->height * max_width / image_src->width; /* Account for any possible rounding errors... */ image_dst->height = (image_dst->height < 1) ? 1 : image_dst->height; - image_dst->height = (image_dst->height > rgui_frame_buf.height) ? rgui_frame_buf.height : image_dst->height; + image_dst->height = (image_dst->height > max_height) ? max_height : image_dst->height; } else { - image_dst->height = rgui_frame_buf.height; - image_dst->width = image_src->width * rgui_frame_buf.height / image_src->height; + image_dst->height = max_height; + image_dst->width = image_src->width * max_height / image_src->height; /* Account for any possible rounding errors... */ image_dst->width = (image_dst->width < 1) ? 1 : image_dst->width; - image_dst->width = (image_dst->width > rgui_frame_buf.width) ? rgui_frame_buf.width : image_dst->width; + image_dst->width = (image_dst->width > max_width) ? max_width : image_dst->width; } /* Allocate pixel buffer */ @@ -805,7 +836,7 @@ static bool downscale_thumbnail(rgui_t *rgui, struct texture_image *image_src, s return true; } -static void process_thumbnail(rgui_t *rgui, struct texture_image *image_src) +static void process_thumbnail(rgui_t *rgui, thumbnail_t *thumbnail, uint32_t *queue_size, struct texture_image *image_src) { unsigned x, y; struct texture_image *image = NULL; @@ -818,25 +849,20 @@ static void process_thumbnail(rgui_t *rgui, struct texture_image *image_src) /* Ensure that we only process the most recently loaded * thumbnail image (i.e. don't waste CPU cycles processing - * old images if we have a backlog) - * > NB: After some testing, cannot seem to ever trigger a - * situation where rgui->thumbnail_queue_size is greater - * than 1, so perhaps image loading is synchronous after all. - * This probably makes the check redundant, but we'll leave - * it here for now... */ - if (rgui->thumbnail_queue_size > 0) - rgui->thumbnail_queue_size--; - if (rgui->thumbnail_queue_size > 0) + * old images if we have a backlog) */ + if (*queue_size > 0) + *queue_size = *queue_size - 1; + if (*queue_size > 0) return; /* Sanity check */ - if (!image_src->pixels || (image_src->width < 1) || (image_src->height < 1) || !thumbnail.data) + if (!image_src->pixels || (image_src->width < 1) || (image_src->height < 1) || !thumbnail->data) return; /* Downscale thumbnail if it exceeds maximum size limits */ - if ((image_src->width > rgui_frame_buf.width) || (image_src->height > rgui_frame_buf.height)) + if ((image_src->width > thumbnail->max_width) || (image_src->height > thumbnail->max_height)) { - if (!downscale_thumbnail(rgui, image_src, &image_resampled)) + if (!downscale_thumbnail(rgui, thumbnail->max_width, thumbnail->max_height, image_src, &image_resampled)) return; image = &image_resampled; } @@ -845,20 +871,20 @@ static void process_thumbnail(rgui_t *rgui, struct texture_image *image_src) image = image_src; } - thumbnail.width = image->width; - thumbnail.height = image->height; + thumbnail->width = image->width; + thumbnail->height = image->height; /* Copy image to thumbnail buffer, performing pixel format conversion */ - for (x = 0; x < thumbnail.width; x++) + for (x = 0; x < thumbnail->width; x++) { - for (y = 0; y < thumbnail.height; y++) + for (y = 0; y < thumbnail->height; y++) { - thumbnail.data[x + (y * thumbnail.width)] = - argb32_to_pixel_platform_format(image->pixels[x + (y * thumbnail.width)]); + thumbnail->data[x + (y * thumbnail->width)] = + argb32_to_pixel_platform_format(image->pixels[x + (y * thumbnail->width)]); } } - thumbnail.is_valid = true; + thumbnail->is_valid = true; /* Tell menu that a display update is required */ rgui->force_redraw = true; @@ -872,9 +898,10 @@ static void process_thumbnail(rgui_t *rgui, struct texture_image *image_src) static bool rgui_load_image(void *userdata, void *data, enum menu_image_type type) { - rgui_t *rgui = (rgui_t*)userdata; + rgui_t *rgui = (rgui_t*)userdata; + settings_t *settings = config_get_ptr(); - if (!rgui || !data) + if (!rgui || !data || !settings) return false; switch (type) @@ -888,7 +915,27 @@ static bool rgui_load_image(void *userdata, void *data, enum menu_image_type typ case MENU_IMAGE_THUMBNAIL: { struct texture_image *image = (struct texture_image*)data; - process_thumbnail(rgui, image); + + if (rgui->show_fs_thumbnail) + process_thumbnail(rgui, &fs_thumbnail, &rgui->thumbnail_queue_size, image); + else if (settings->bools.menu_rgui_inline_thumbnails) + process_thumbnail(rgui, &mini_thumbnail, &rgui->thumbnail_queue_size, image); + else + { + /* If user toggles settings rapidly on very slow systems, + * it is possible for a thumbnail to be requested without + * it ever being processed. In this case, we still have to + * decrement the thumbnail queue (otherwise image updates + * will get 'stuck') */ + if (rgui->thumbnail_queue_size > 0) + rgui->thumbnail_queue_size--; + } + } + break; + case MENU_IMAGE_LEFT_THUMBNAIL: + { + struct texture_image *image = (struct texture_image*)data; + process_thumbnail(rgui, &mini_left_thumbnail, &rgui->left_thumbnail_queue_size, image); } break; default: @@ -920,7 +967,7 @@ static bool rgui_render_wallpaper(void) return false; } -static void rgui_render_thumbnail(void) +static void rgui_render_fs_thumbnail(void) { size_t fb_pitch; unsigned fb_width, fb_height; @@ -929,7 +976,7 @@ static void rgui_render_thumbnail(void) unsigned thumb_x_offset, thumb_y_offset; unsigned width, height; - if (thumbnail.is_valid && rgui_frame_buf.data && thumbnail.data) + if (fs_thumbnail.is_valid && rgui_frame_buf.data && fs_thumbnail.data) { menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch); @@ -938,27 +985,27 @@ static void rgui_render_thumbnail(void) * cannot assume fb_width and fb_height are constant and * >= thumbnail.width and thumbnail.height (even though * they are...) */ - if (thumbnail.width <= fb_width) + if (fs_thumbnail.width <= fb_width) { thumb_x_offset = 0; - fb_x_offset = (fb_width - thumbnail.width) >> 1; - width = thumbnail.width; + fb_x_offset = (fb_width - fs_thumbnail.width) >> 1; + width = fs_thumbnail.width; } else { - thumb_x_offset = (thumbnail.width - fb_width) >> 1; + thumb_x_offset = (fs_thumbnail.width - fb_width) >> 1; fb_x_offset = 0; width = fb_width; } - if (thumbnail.height <= fb_height) + if (fs_thumbnail.height <= fb_height) { thumb_y_offset = 0; - fb_y_offset = (fb_height - thumbnail.height) >> 1; - height = thumbnail.height; + fb_y_offset = (fb_height - fs_thumbnail.height) >> 1; + height = fs_thumbnail.height; } else { - thumb_y_offset = (thumbnail.height - fb_height) >> 1; + thumb_y_offset = (fs_thumbnail.height - fb_height) >> 1; fb_y_offset = 0; height = fb_height; } @@ -969,7 +1016,65 @@ static void rgui_render_thumbnail(void) for (x = 0; x < width; x++) { rgui_frame_buf.data[(y + fb_y_offset) * (fb_pitch >> 1) + (x + fb_x_offset)] = - thumbnail.data[(x + thumb_x_offset) + ((y + thumb_y_offset) * thumbnail.width)]; + fs_thumbnail.data[(x + thumb_x_offset) + ((y + thumb_y_offset) * fs_thumbnail.width)]; + } + } + } +} + +static unsigned inline rgui_get_mini_thumbnail_fullwidth(void) +{ + unsigned width = mini_thumbnail.is_valid ? mini_thumbnail.width : 0; + unsigned left_width = mini_left_thumbnail.is_valid ? mini_left_thumbnail.width : 0; + return width >= left_width ? width : left_width; +} + +static void rgui_render_mini_thumbnail(thumbnail_t *thumbnail, enum menu_thumbnail_id thumbnail_id) +{ + settings_t *settings = config_get_ptr(); + size_t fb_pitch; + unsigned fb_width, fb_height; + unsigned term_width, term_height; + unsigned x, y; + unsigned fb_x_offset, fb_y_offset; + unsigned thumbnail_fullwidth = rgui_get_mini_thumbnail_fullwidth(); + + if (!thumbnail || !settings) + return; + + if (thumbnail->is_valid && rgui_frame_buf.data && thumbnail->data) + { + menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch); + + term_width = RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE; + term_height = RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE; + + /* Sanity check (this can never, ever happen, so just return + * instead of trying to crop the thumbnail image...) */ + if ((thumbnail_fullwidth > term_width) || (thumbnail->height > term_height)) + return; + + fb_x_offset = (RGUI_TERM_START_X(fb_width) + term_width) - + (thumbnail->width + ((thumbnail_fullwidth - thumbnail->width) >> 1)); + + if (((thumbnail_id == MENU_THUMBNAIL_RIGHT) && !settings->bools.menu_rgui_swap_thumbnails) || + ((thumbnail_id == MENU_THUMBNAIL_LEFT) && settings->bools.menu_rgui_swap_thumbnails)) + { + fb_y_offset = RGUI_TERM_START_Y(fb_height) + ((thumbnail->max_height - thumbnail->height) >> 1); + } + else + { + fb_y_offset = (RGUI_TERM_START_Y(fb_height) + term_height) - + (thumbnail->height + ((thumbnail->max_height - thumbnail->height) >> 1)); + } + + /* Copy thumbnail to framebuffer */ + for (y = 0; y < thumbnail->height; y++) + { + for (x = 0; x < thumbnail->width; x++) + { + rgui_frame_buf.data[(y + fb_y_offset) * (fb_pitch >> 1) + (x + fb_x_offset)] = + thumbnail->data[x + (y * thumbnail->width)]; } } } @@ -1359,8 +1464,8 @@ static void rgui_render_background(rgui_t *rgui) dst += pitch_in_pixels * 4; } - /* Skip drawing border if we are currently showing a thumbnail */ - if (!(rgui->show_thumbnail && rgui->entry_has_thumbnail && (thumbnail.is_valid || (rgui->thumbnail_queue_size > 0)))) + /* Skip drawing border if we are currently showing a fullscreen thumbnail */ + if (!(rgui->show_fs_thumbnail && rgui->entry_has_thumbnail && (fs_thumbnail.is_valid || (rgui->thumbnail_queue_size > 0)))) { if (rgui_frame_buf.data) { @@ -1489,7 +1594,7 @@ static void rgui_render(void *data, bool is_idle) menu_animation_ctx_ticker_t ticker; static const char* const ticker_spacer = RGUI_TICKER_SPACER; unsigned x, y; - size_t i, end, fb_pitch, old_start; + size_t i, end, fb_pitch, old_start, new_start; unsigned fb_width, fb_height; int bottom; size_t entries_end = 0; @@ -1622,14 +1727,14 @@ static void rgui_render(void *data, bool is_idle) ticker.type_enum = (enum menu_animation_ticker_type)settings->uints.menu_ticker_type; ticker.spacer = ticker_spacer; - /* If thumbnails are enabled and we are viewing a playlist, - * switch to thumbnail view mode if either current thumbnail + /* If fullscreen thumbnails are enabled and we are viewing a playlist, + * switch to fullscreen thumbnail view mode if either current thumbnail * is valid or we are waiting for current thumbnail to load * (if load is pending we'll get a blank screen + title, but * this is better than switching back to the text playlist * view, which causes ugly flickering when scrolling quickly * through a list...) */ - if (rgui->show_thumbnail && rgui->entry_has_thumbnail && (thumbnail.is_valid || (rgui->thumbnail_queue_size > 0))) + if (rgui->show_fs_thumbnail && rgui->entry_has_thumbnail && (fs_thumbnail.is_valid || (rgui->thumbnail_queue_size > 0))) { const char *thumbnail_title = NULL; char thumbnail_title_buf[255]; @@ -1637,7 +1742,7 @@ static void rgui_render(void *data, bool is_idle) thumbnail_title_buf[0] = '\0'; /* Draw thumbnail */ - rgui_render_thumbnail(); + rgui_render_fs_thumbnail(); /* Get thumbnail title */ if (menu_thumbnail_get_label(rgui->thumbnail_path_data, &thumbnail_title)) @@ -1665,11 +1770,40 @@ static void rgui_render(void *data, bool is_idle) } else { - /* No thumbnail - render usual text */ + /* Render usual text */ char title_buf[255]; unsigned timedate_x = (RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE)) - (5 * FONT_WIDTH_STRIDE); unsigned core_name_len = ((timedate_x - RGUI_TERM_START_X(fb_width)) / FONT_WIDTH_STRIDE) - 3; + bool show_mini_thumbnails = rgui->is_playlist && settings->bools.menu_rgui_inline_thumbnails; + bool show_thumbnail = false; + bool show_left_thumbnail = false; + unsigned thumbnail_panel_width = 0; + unsigned term_mid_point = 0; + + /* Cache mini thumbnail related parameters, if required */ + if (show_mini_thumbnails) + { + /* Get whether each thumbnail type is enabled */ + show_thumbnail = rgui->entry_has_thumbnail && + (mini_thumbnail.is_valid || (rgui->thumbnail_queue_size > 0)); + show_left_thumbnail = rgui->entry_has_left_thumbnail && + (mini_left_thumbnail.is_valid || (rgui->left_thumbnail_queue_size > 0)); + + /* Get maximum width of thumbnail 'panel' on right side + * of screen */ + thumbnail_panel_width = rgui_get_mini_thumbnail_fullwidth(); + + if ((rgui->entry_has_thumbnail && rgui->thumbnail_queue_size > 0) || + (rgui->entry_has_left_thumbnail && rgui->left_thumbnail_queue_size > 0)) + thumbnail_panel_width = mini_thumbnail_max_width; + + /* Index (relative to first displayed menu entry) of + * the vertical centre of RGUI's 'terminal' + * (required to determine whether a particular entry + * is adjacent to the 'right' or 'left' thumbnail) */ + term_mid_point = (unsigned)((RGUI_TERM_HEIGHT(fb_height) * 0.5f) + 0.5f) - 1; + } /* Print title */ title_buf[0] = '\0'; @@ -1694,9 +1828,9 @@ static void rgui_render(void *data, bool is_idle) x = RGUI_TERM_START_X(fb_width); y = RGUI_TERM_START_Y(fb_height); - menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &i); + menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &new_start); - for (; i < end; i++, y += FONT_HEIGHT_STRIDE) + for (i = new_start; i < end; i++, y += FONT_HEIGHT_STRIDE) { char entry_value[255]; char message[255]; @@ -1727,9 +1861,45 @@ static void rgui_render(void *data, bool is_idle) entry_path = menu_entry_get_rich_label(&entry); menu_entry_get_value(&entry, entry_value, sizeof(entry_value)); - /* Get base width of entry title field */ + /* Get base length of entry title field */ entry_title_max_len = RGUI_TERM_WIDTH(fb_width) - (1 + 2); + /* If showing mini thumbnails, reduce title field length accordingly */ + if (show_mini_thumbnails) + { + unsigned term_offset = settings->bools.menu_rgui_swap_thumbnails ? + (RGUI_TERM_HEIGHT(fb_height) - (i - new_start) - 1) : (i - new_start); + unsigned thumbnail_width = 0; + + /* Note: + * - 'Right' thumbnail is drawn at the top + * - 'Left' thumbnail is drawn at the bottom + * ...unless thumbnail postions are swapped. + * (legacy naming, unfortunately...) */ + + /* An annoyance - cannot assume terminal will have a + * standard layout (even though it always will...), + * so have to check whether there are an odd or even + * number of entries... */ + if((RGUI_TERM_HEIGHT(fb_height) & 1) == 0) + { + /* Even number of entries */ + if ((show_thumbnail && (term_offset <= term_mid_point)) || + (show_left_thumbnail && (term_offset > term_mid_point))) + thumbnail_width = thumbnail_panel_width; + } + else + { + /* Odd number of entries (will always be the case) */ + if ((show_thumbnail && (term_offset < term_mid_point)) || + (show_left_thumbnail && (term_offset > term_mid_point)) || + ((show_thumbnail || show_left_thumbnail) && (term_offset == term_mid_point))) + thumbnail_width = thumbnail_panel_width; + } + + entry_title_max_len -= (thumbnail_width / FONT_WIDTH_STRIDE) + 1; + } + /* Determine whether entry has a value component */ if (!string_is_empty(entry_value)) { @@ -1799,6 +1969,16 @@ static void rgui_render(void *data, bool is_idle) free(entry_path); } + /* Draw mini thumbnails, if required */ + if (show_mini_thumbnails) + { + if (show_thumbnail) + rgui_render_mini_thumbnail(&mini_thumbnail, MENU_THUMBNAIL_RIGHT); + + if (show_left_thumbnail) + rgui_render_mini_thumbnail(&mini_left_thumbnail, MENU_THUMBNAIL_LEFT); + } + /* Print menu sublabel/core name (if required) */ if (settings->bools.menu_show_sublabels && !string_is_empty(rgui->menu_sublabel)) { @@ -1899,19 +2079,24 @@ static void rgui_framebuffer_free(void) rgui_frame_buf.data = NULL; } -static void rgui_thumbnail_free(void) +static void rgui_thumbnail_free(thumbnail_t *thumbnail) { - thumbnail.width = 0; - thumbnail.height = 0; - thumbnail.is_valid = false; + if (!thumbnail) + return; - if (!string_is_empty(thumbnail.path)) - free(thumbnail.path); - thumbnail.path = NULL; + thumbnail->max_width = 0; + thumbnail->max_height = 0; + thumbnail->width = 0; + thumbnail->height = 0; + thumbnail->is_valid = false; - if (thumbnail.data) - free(thumbnail.data); - thumbnail.data = NULL; + if (!string_is_empty(thumbnail->path)) + free(thumbnail->path); + thumbnail->path = NULL; + + if (thumbnail->data) + free(thumbnail->data); + thumbnail->data = NULL; } static void rgui_wallpaper_free(void) @@ -2060,7 +2245,9 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update) settings_t *settings = config_get_ptr(); rgui_framebuffer_free(); - rgui_thumbnail_free(); + rgui_thumbnail_free(&fs_thumbnail); + rgui_thumbnail_free(&mini_thumbnail); + rgui_thumbnail_free(&mini_left_thumbnail); rgui_wallpaper_free(); /* Cache new aspect ratio */ @@ -2135,9 +2322,29 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update) rgui_term_layout.start_y = (rgui_frame_buf.height - (rgui_term_layout.height * FONT_HEIGHT_STRIDE)) / 2; /* Allocate thumbnail buffer */ - thumbnail.data = (uint16_t*)calloc( - rgui_frame_buf.width * rgui_frame_buf.height, sizeof(uint16_t)); - if (!thumbnail.data) + fs_thumbnail.max_width = rgui_frame_buf.width; + fs_thumbnail.max_height = rgui_frame_buf.height; + fs_thumbnail.data = (uint16_t*)calloc( + fs_thumbnail.max_width * fs_thumbnail.max_height, sizeof(uint16_t)); + if (!fs_thumbnail.data) + return false; + + /* Allocate mini thumbnail buffers */ + mini_thumbnail_max_width = ((rgui_term_layout.width - 4) > 19 ? 19 : (rgui_term_layout.width - 4)) * FONT_WIDTH_STRIDE; + mini_thumbnail_max_height = (unsigned)((rgui_term_layout.height * FONT_HEIGHT_STRIDE) * 0.5f) - 2; + + mini_thumbnail.max_width = mini_thumbnail_max_width; + mini_thumbnail.max_height = mini_thumbnail_max_height; + mini_thumbnail.data = (uint16_t*)calloc( + mini_thumbnail.max_width * mini_thumbnail.max_height, sizeof(uint16_t)); + if (!mini_thumbnail.data) + return false; + + mini_left_thumbnail.max_width = mini_thumbnail_max_width; + mini_left_thumbnail.max_height = mini_thumbnail_max_height; + mini_left_thumbnail.data = (uint16_t*)calloc( + mini_left_thumbnail.max_width * mini_left_thumbnail.max_height, sizeof(uint16_t)); + if (!mini_left_thumbnail.data) return false; /* Allocate wallpaper buffer */ @@ -2223,14 +2430,17 @@ static void *rgui_init(void **userdata, bool video_is_threaded) goto error; rgui->thumbnail_queue_size = 0; - /* Ensure that we start with thumbnails disabled */ - rgui->show_thumbnail = false; + rgui->left_thumbnail_queue_size = 0; + /* Ensure that we start with fullscreen thumbnails disabled */ + rgui->show_fs_thumbnail = false; return menu; error: rgui_framebuffer_free(); - rgui_thumbnail_free(); + rgui_thumbnail_free(&fs_thumbnail); + rgui_thumbnail_free(&mini_thumbnail); + rgui_thumbnail_free(&mini_left_thumbnail); rgui_wallpaper_free(); if (menu) free(menu); @@ -2259,7 +2469,9 @@ static void rgui_free(void *data) menu_display_set_font_data_init(fb_font_inited); rgui_framebuffer_free(); - rgui_thumbnail_free(); + rgui_thumbnail_free(&fs_thumbnail); + rgui_thumbnail_free(&mini_thumbnail); + rgui_thumbnail_free(&mini_left_thumbnail); rgui_wallpaper_free(); if (rgui_upscale_buf.data) @@ -2442,21 +2654,50 @@ static void rgui_set_thumbnail_system(void *userdata, char *s, size_t len) static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui) { - rgui->entry_has_thumbnail = false; + settings_t *settings = config_get_ptr(); - if (rgui->show_thumbnail && rgui->is_playlist) + if (!settings) + return; + + rgui->entry_has_thumbnail = false; + rgui->entry_has_left_thumbnail = false; + + if ((rgui->show_fs_thumbnail || settings->bools.menu_rgui_inline_thumbnails) && rgui->is_playlist) { if (menu_thumbnail_set_content_playlist(rgui->thumbnail_path_data, playlist_get_cached(), menu_navigation_get_selection())) { - if (menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_RIGHT)) + if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) { - const char *thumbnail_path = NULL; - - if (menu_thumbnail_get_path(rgui->thumbnail_path_data, - MENU_THUMBNAIL_RIGHT, &thumbnail_path)) + if (menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_RIGHT)) { - rgui->entry_has_thumbnail = request_thumbnail(rgui, thumbnail_path); + const char *thumbnail_path = NULL; + + if (menu_thumbnail_get_path(rgui->thumbnail_path_data, + MENU_THUMBNAIL_RIGHT, &thumbnail_path)) + { + if (rgui->show_fs_thumbnail) + rgui->entry_has_thumbnail = request_thumbnail( + &fs_thumbnail, MENU_THUMBNAIL_RIGHT, &rgui->thumbnail_queue_size, thumbnail_path); + else + rgui->entry_has_thumbnail = request_thumbnail( + &mini_thumbnail, MENU_THUMBNAIL_RIGHT, &rgui->thumbnail_queue_size, thumbnail_path); + } + } + } + + if (settings->bools.menu_rgui_inline_thumbnails && menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) + { + if (menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_LEFT)) + { + const char *left_thumbnail_path = NULL; + + if (menu_thumbnail_get_path(rgui->thumbnail_path_data, + MENU_THUMBNAIL_LEFT, &left_thumbnail_path)) + { + rgui->entry_has_left_thumbnail = request_thumbnail( + &mini_left_thumbnail, MENU_THUMBNAIL_LEFT, &rgui->left_thumbnail_queue_size, left_thumbnail_path); + } } } } @@ -2465,11 +2706,37 @@ static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui) static void rgui_update_thumbnail_image(void *userdata) { - rgui_t *rgui = (rgui_t*)userdata; - if (!rgui) + rgui_t *rgui = (rgui_t*)userdata; + settings_t *settings = config_get_ptr(); + if (!rgui || !settings) return; - rgui->show_thumbnail = !rgui->show_thumbnail; + rgui->show_fs_thumbnail = !rgui->show_fs_thumbnail; + + /* It is possible that we are waiting for a 'right' thumbnail + * image to load at this point. If so, and we are displaying + * inline thumbnails, then 'fs_thumbnail' and 'mini_thumbnail' + * can get mixed up. To avoid this, we simply 'reset' the + * currently inactive right thumbnail. */ + if (settings->bools.menu_rgui_inline_thumbnails) + { + if (rgui->show_fs_thumbnail) + { + mini_thumbnail.width = 0; + mini_thumbnail.height = 0; + mini_thumbnail.is_valid = false; + free(mini_thumbnail.path); + mini_thumbnail.path = NULL; + } + else + { + fs_thumbnail.width = 0; + fs_thumbnail.height = 0; + fs_thumbnail.is_valid = false; + free(fs_thumbnail.path); + fs_thumbnail.path = NULL; + } + } rgui_scan_selected_entry_thumbnail(rgui); } @@ -2590,8 +2857,7 @@ static void rgui_populate_entries(void *data, /* Check whether we are currently viewing a playlist */ rgui->is_playlist = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY)) || - string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST)) || - string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_IMAGES_LIST)); + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST)); /* Set menu title */ menu_entries_get_title(rgui->menu_title, sizeof(rgui->menu_title)); diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index d4bd92dfe8..9437e5d562 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6211,6 +6211,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, PARSE_ONLY_BOOL, false) == 0) count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS, + PARSE_ONLY_BOOL, false) == 0) + count++; if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_THUMBNAILS, PARSE_ONLY_UINT, false) == 0) @@ -6223,6 +6227,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, PARSE_ONLY_BOOL, false) == 0) count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS, + PARSE_ONLY_BOOL, false) == 0) + count++; if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER, PARSE_ONLY_UINT, false) == 0) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index c0bbabde1e..e574986ef2 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -9345,13 +9345,65 @@ static bool setting_append_list( general_read_handler, SD_FLAG_ADVANCED); + if (string_is_equal(settings->arrays.menu_driver, "rgui")) + { + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_rgui_inline_thumbnails, + MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS, + MENU_ENUM_LABEL_VALUE_MENU_RGUI_INLINE_THUMBNAILS, + rgui_inline_thumbnails, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); + + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_rgui_swap_thumbnails, + MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS, + MENU_ENUM_LABEL_VALUE_MENU_RGUI_SWAP_THUMBNAILS, + rgui_swap_thumbnails, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); + } + if (string_is_equal(settings->arrays.menu_driver, "xmb") || string_is_equal(settings->arrays.menu_driver, "ozone") || string_is_equal(settings->arrays.menu_driver, "rgui")) { + enum msg_hash_enums thumbnails_label_value; + enum msg_hash_enums left_thumbnails_label_value; + + if (string_is_equal(settings->arrays.menu_driver, "rgui")) + { + thumbnails_label_value = MENU_ENUM_LABEL_VALUE_THUMBNAILS_RGUI; + left_thumbnails_label_value = MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_RGUI; + } + else if (string_is_equal(settings->arrays.menu_driver, "ozone")) + { + thumbnails_label_value = MENU_ENUM_LABEL_VALUE_THUMBNAILS; + left_thumbnails_label_value = MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_OZONE; + } + else + { + thumbnails_label_value = MENU_ENUM_LABEL_VALUE_THUMBNAILS; + left_thumbnails_label_value = MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS; + } + CONFIG_UINT( list, list_info, &settings->uints.menu_thumbnails, MENU_ENUM_LABEL_THUMBNAILS, - MENU_ENUM_LABEL_VALUE_THUMBNAILS, + thumbnails_label_value, menu_thumbnails_default, &group_info, &subgroup_info, @@ -9362,6 +9414,40 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_menu_thumbnails; menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true); + + CONFIG_UINT( + list, list_info, + &settings->uints.menu_left_thumbnails, + MENU_ENUM_LABEL_LEFT_THUMBNAILS, + left_thumbnails_label_value, + menu_left_thumbnails_default, + &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_left_thumbnails; + menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true); + } + + if (string_is_equal(settings->arrays.menu_driver, "xmb")) + { + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_xmb_vertical_thumbnails, + MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, + MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS, + xmb_vertical_thumbnails, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); } if (string_is_equal(settings->arrays.menu_driver, "rgui")) @@ -9383,45 +9469,6 @@ static bool setting_append_list( menu_settings_list_current_add_range(list, list_info, 0, RGUI_THUMB_SCALE_LAST-1, 1, true, true); } - if (string_is_equal(settings->arrays.menu_driver, "xmb") || string_is_equal(settings->arrays.menu_driver, "ozone")) - { - bool is_ozone = string_is_equal(settings->arrays.menu_driver, "ozone"); - enum msg_hash_enums label = is_ozone ? - MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_OZONE : MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS; - - CONFIG_UINT( - list, list_info, - &settings->uints.menu_left_thumbnails, - MENU_ENUM_LABEL_LEFT_THUMBNAILS, - label, - menu_left_thumbnails_default, - &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_left_thumbnails; - menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true); - - if (!is_ozone) - CONFIG_BOOL( - list, list_info, - &settings->bools.menu_xmb_vertical_thumbnails, - MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, - MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS, - xmb_vertical_thumbnails, - MENU_ENUM_LABEL_VALUE_OFF, - MENU_ENUM_LABEL_VALUE_ON, - &group_info, - &subgroup_info, - parent_group, - general_write_handler, - general_read_handler, - SD_FLAG_NONE); - } - CONFIG_BOOL( list, list_info, &settings->bools.menu_timedate_enable, diff --git a/msg_hash.h b/msg_hash.h index 8562efeaa0..e4bc2b0ccf 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -901,9 +901,13 @@ enum msg_hash_enums MENU_LABEL(CONTENT_SHOW_PLAYLISTS), MENU_LABEL(XMB_RIBBON_ENABLE), MENU_LABEL(THUMBNAILS), + MENU_LABEL(THUMBNAILS_RGUI), MENU_LABEL(LEFT_THUMBNAILS), + MENU_LABEL(LEFT_THUMBNAILS_RGUI), MENU_LABEL(LEFT_THUMBNAILS_OZONE), MENU_LABEL(XMB_VERTICAL_THUMBNAILS), + MENU_LABEL(MENU_RGUI_INLINE_THUMBNAILS), + MENU_LABEL(MENU_RGUI_SWAP_THUMBNAILS), MENU_LABEL(MENU_RGUI_THUMBNAIL_DOWNSCALER), MENU_LABEL(TIMEDATE_ENABLE), MENU_LABEL(TIMEDATE_STYLE), From 8bbdf39cbfb65d9c7e5682bf0228489d863250e5 Mon Sep 17 00:00:00 2001 From: "Mark W. Kidd" Date: Wed, 27 Mar 2019 16:31:37 -0400 Subject: [PATCH 092/237] remove un-reviewed translation updates --- intl/msg_hash_el.h | 16 ---------------- intl/msg_hash_ko.h | 14 -------------- intl/msg_hash_pl.h | 10 ---------- 3 files changed, 40 deletions(-) diff --git a/intl/msg_hash_el.h b/intl/msg_hash_el.h index 317949e1ee..225f9113f3 100644 --- a/intl/msg_hash_el.h +++ b/intl/msg_hash_el.h @@ -4735,10 +4735,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Επιλογή Αρχείου" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, - "Επιλογή Από λίστα αναπαραγωγής" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_FILTER, "Φίλτρα" @@ -5329,10 +5325,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Σάρωση για νέα δωμάτια." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Κατάργηση αυτής της καταχώρισης από λίστα αναπαραγωγής." - ) MSG_HASH( MENU_ENUM_SUBLABEL_INFORMATION, "View more information about the content." @@ -5473,10 +5465,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Perform tasks on a separate thread." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Επιτρέψτε στον χρήστη να καταργεί τις καταχωρήσεις από τις λίστες αναπαραγωγής." - ) MSG_HASH( MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Sets the System directory. Cores can query for this directory to load BIOSes, system-specific configs, etc." @@ -5966,10 +5954,6 @@ MSG_HASH( MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Supplying a password when hiding the settings tab makes it possible to later restore it from the menu, by going to the Main Menu tab, selecting Enable Settings Tab and entering the password." ) -MSG_HASH( - MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Επιτρέψτε στον χρήστη να μετονομάζει τις καταχωρήσεις λίστας αναπαραγωγής" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Επίτρεψη μετονομασίας καταχωρήσεων" diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index 49944b8b29..62dc1d3cce 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -2437,8 +2437,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "배터리 수준 표시") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "파일 선택") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, - "재생목록에서 선택") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "필터") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, @@ -2761,10 +2759,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, "클라이언트 모드로 넷플레이 사용.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, "활성 중인 모든 넷플레이 연결 해제.") -MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "디렉토리에서 실행 파일 검색.") -MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "실행 파일 검색.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, "수직 동기에 사용자 스왑 간격을 사용. 모니터 재생 빈도를 효과적으로 줄이는데 사용." ) @@ -2783,8 +2777,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, ) MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "새 호스트 검색.") -MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "재생목록에서 현재 항목 삭제.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "컨텐츠에 대한 자세한 정보 확인.") MSG_HASH(MENU_ENUM_SUBLABEL_RUN, @@ -2855,8 +2847,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, "파워 유저를 위한 고급 설정 보이기(기본값은 숨김).") MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "분할된 스레드에서 작업을 수행.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "사용자가 재생목록에서 항목을 제거할 수 있게 허용.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "시스템 디렉토리를 설정. 코어는 이 디렉토리에서 BIOS, 시스템 특정 구성 등을 불러들일 수 있습니다.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, @@ -2936,8 +2926,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, "앱/코어 정보 파일이 저장될 공간.") MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "조이패드가 연결되면 해당 디렉토리에 설정 파일이 있는 경우 자동으로 구성해줍니다.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "모든 재생 목록은이 디렉토리에 저장됩니다.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "디렉토리를 설정하면 설정하면 임시로 압축해제된 컨첸츠가 이 디렉토리에 추출됩니다." @@ -3113,8 +3101,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, "설정 탭을 표시/해제 합니다. 다시 표시하기 위해 재시작이 필요합니다.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "설정 탭을 숨길때 비밀번호를 설정해 나중에 되돌릴수 있게 끔 합니다. 메인 메뉴에서 '설정 탭 표시'를 선택 후 비밀번호를 입력해 되돌릴수 있습니다.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "재생목록에 있는 엔트리들을 편집할 수 있게 허용합니다.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "엔트리 편집 허용") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index 5e8f909ed5..276d7063c3 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -2641,8 +2641,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, "Pokaż poziom naładowania baterii") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, "Wybierz plik") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_PLAYLIST, - "Wybierz z listy odtwarzania") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, "Filtr") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, @@ -3026,8 +3024,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, ) MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Zeskanuj nowe pokoje.") -MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Usuń ten wpis z listy odtwarzania.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, "Zobacz więcej informacji o zawartości.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, @@ -3102,8 +3098,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, "Pokaż zaawansowane ustawienia dla zaawansowanych użytkowników (domyślnie ukryty).") MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, "Wykonuj zadania w oddzielnym wątku.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Pozwól użytkownikowi usuwać wpisy z list odtwarzania.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Ustawia katalog systemowy. Rdzenie mogą wysyłać zapytania do tego katalogu, aby załadować BIOS, konfiguracje specyficzne dla systemu itp.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, @@ -3187,8 +3181,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, "Pliki informacji o aplikacji/rdzeniu przechowywane są tutaj .") MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, "Jeśli joypad jest podłączony, to zostanie automatycznie skonfigurowany, jeśli plik konfiguracyjny odpowiadający mu jest obecny w tym katalogu.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Zapisz wszystkie listy odtwarzania w tym katalogu.") MSG_HASH( MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, "Jeśli ustawione na katalog, zawartość, która jest czasowo wyodrębniana (np. Z archiwów), zostanie wyodrębniona do tego katalogu." @@ -3373,8 +3365,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, "Włącza kartę Ustawienia. Wymagane jest ponowne uruchomienie karty.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, "Podanie hasła podczas ukrywania karty ustawień pozwala później przywrócić ją z menu, przechodząc do karty Menu główne, wybierając opcję Włącz kartę Ustawienia i wprowadzając hasło.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Zezwalaj użytkownikowi na zmianę nazw wpisów na listach odtwarzania.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, "Zezwalaj na zmianę nazw wpisów") MSG_HASH(MENU_ENUM_SUBLABEL_RENAME_ENTRY, From 2148f8ca0a4c3660621efd57ecc6703679068312 Mon Sep 17 00:00:00 2001 From: natinusala Date: Thu, 28 Mar 2019 10:39:11 +0100 Subject: [PATCH 093/237] ozone: fix content metadata for images playlist --- menu/drivers/ozone/ozone.c | 2 ++ menu/drivers/ozone/ozone.h | 1 + menu/drivers/ozone/ozone_entries.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index c19c2d3618..62b1589c9a 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1153,6 +1153,8 @@ void ozone_update_content_metadata(ozone_handle_t *ozone) snprintf(ozone->selection_core_name, sizeof(ozone->selection_core_name), "%s %s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_CORE), core_label); + ozone->selection_core_is_imageviewer = string_is_equal(core_label, "imageviewer"); + word_wrap(ozone->selection_core_name, ozone->selection_core_name, (unsigned)((float)ozone->dimensions.thumbnail_bar_width * (float)0.85) / ozone->footer_font_glyph_width, false); ozone->selection_core_name_lines = ozone_count_lines(ozone->selection_core_name); diff --git a/menu/drivers/ozone/ozone.h b/menu/drivers/ozone/ozone.h index 16f2d44b00..a6772505f7 100644 --- a/menu/drivers/ozone/ozone.h +++ b/menu/drivers/ozone/ozone.h @@ -240,6 +240,7 @@ struct ozone_handle char selection_playtime[255]; char selection_lastplayed[255]; unsigned selection_core_name_lines; + bool selection_core_is_imageviewer; bool is_db_manager_list; }; diff --git a/menu/drivers/ozone/ozone_entries.c b/menu/drivers/ozone/ozone_entries.c index fa4647e3ff..7266823ae5 100644 --- a/menu/drivers/ozone/ozone_entries.c +++ b/menu/drivers/ozone/ozone_entries.c @@ -743,7 +743,7 @@ void ozone_draw_thumbnail_bar(ozone_handle_t *ozone, video_frame_info_t *video_i ozone_pure_white ); } - else if (!string_is_equal(ozone->selection_core_name, "imageviewer")) + else if (!ozone->selection_core_is_imageviewer) { unsigned y = video_info->height / 2 + ozone->dimensions.sidebar_entry_icon_padding / 2; unsigned content_metadata_padding = ozone->dimensions.sidebar_entry_icon_padding*3; From 4086826e9227302e010536b6ac1b699c6f14a0e6 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 28 Mar 2019 11:27:26 +0000 Subject: [PATCH 094/237] Log to file: ensure log directory is always created --- retroarch.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/retroarch.c b/retroarch.c index a1308602a7..308783897d 100644 --- a/retroarch.c +++ b/retroarch.c @@ -5281,7 +5281,6 @@ void rarch_log_file_init(void) { settings_t *settings = config_get_ptr(); FILE *fp = NULL; - bool success = false; /* If this is the first run, generate a timestamped log * file name (do this even when not outputting timestamped @@ -5328,6 +5327,20 @@ void rarch_log_file_init(void) /* > Attempt to initialise log file */ if (!string_is_empty(settings->paths.log_dir)) { + /* Create log directory, if required */ + if (!path_is_directory(settings->paths.log_dir)) + { + path_mkdir(settings->paths.log_dir); + if(!path_is_directory(settings->paths.log_dir)) + { + /* Re-enable console logging and output error message */ + retro_main_log_file_init(NULL, false); + RARCH_ERR("Failed to create system event log directory: %s\n", settings->paths.log_dir); + return; + } + } + + /* Format log file name */ char buf[PATH_MAX_LENGTH]; fill_pathname_join(buf, settings->paths.log_dir, settings->bools.log_to_file_timestamp ? timestamped_log_file_name : file_path_str(FILE_PATH_DEFAULT_EVENT_LOG), @@ -5337,14 +5350,16 @@ void rarch_log_file_init(void) /* When RetroArch is launched, log file is overwritten. * On subsequent calls within the same session, it is appended to. */ retro_main_log_file_init(buf, log_file_created); - log_file_created = true; - success = true; + if (is_logging_to_file()) + log_file_created = true; + return; } } - /* > Fall back to console logging if something went wrong */ - if (!success) - retro_main_log_file_init(NULL, false); + /* If we reach this point, then something went wrong... + * Just fall back to console logging */ + retro_main_log_file_init(NULL, false); + RARCH_ERR("Failed to initialise system event file logging...\n"); } void rarch_log_file_deinit(void) From 022f25df0ca4bc66b41e71cb8369e4605c4fa8b0 Mon Sep 17 00:00:00 2001 From: Tatsuya79 Date: Thu, 28 Mar 2019 18:21:55 +0100 Subject: [PATCH 095/237] dark theme settings update --- ui/drivers/qt/ui_qt_themes.h | 63 ++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/ui/drivers/qt/ui_qt_themes.h b/ui/drivers/qt/ui_qt_themes.h index 31ff876387..95b8ad0da7 100644 --- a/ui/drivers/qt/ui_qt_themes.h +++ b/ui/drivers/qt/ui_qt_themes.h @@ -41,6 +41,9 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( background-color:rgb(53,53,53); selection-background-color:%1; } + QWidget:disabled { + color:rgb(127,127,127); + } QFrame#playlistWidget, QFrame#browserWidget, QStackedWidget#centralWidget, QFrame#logWidget { padding: 8px; background-color:rgb(66,66,66); @@ -62,11 +65,42 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( QTextEdit, LogTextEdit { background-color:rgb(25,25,25); } - QSpinBox, QDoubleSpinBox, QCheckBox { + QSpinBox, QDoubleSpinBox, QCheckBox, QRadioButton { background-color:rgb(25,25,25); } - QCheckBox:checked, QCheckBox:unchecked { - background-color:rgb(53,53,53); + QCheckBox:checked, QCheckBox:unchecked, QRadioButton:checked, QRadioButton:unchecked { + background-color:transparent; + } + /* Groupboxes for the settings window, can be restricted later with ViewOptionsDialog QGroupBox */ + QGroupBox { + background-color:rgba(80,80,80,50%); + margin-top:27px; + border:1px solid rgba(25,25,25,127); + border-top-left-radius:0px; + border-top-right-radius:4px; + } + QGroupBox::title { + min-height:28px; + subcontrol-origin:margin; + subcontrol-position:left top; + padding:4px 6px 5px 6px; + margin-left:0px; + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgb(65,65,65),stop: 0.4 rgb(70,70,70),stop:1 rgb(90,90,90)); + border:1px solid rgba(25,25,25,127); + border-bottom:1px solid rgb(65,65,65); + border-top-left-radius:4px; + border-top-right-radius:4px; + } + QGroupBox::indicator:checked { + background-color:%1; + border:4px solid rgb(45,45,45); + } + QGroupBox::indicator:unchecked { + background-color:rgba(25,25,25,50%); + } + QGroupBox::indicator { + width:16px; + height:16px; } QWidget#shaderParamsWidget { background-color:rgb(25,25,25); @@ -207,23 +241,6 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( QDockWidget::float-button { right:25px; } - QGroupBox { - background-color:rgba(66,66,66,50%); - margin-top:27px; - border:1px solid rgba(25,25,25,127); - border-top-left-radius:4px; - border-top-right-radius:4px; - } - QGroupBox::title { - subcontrol-origin:margin; - subcontrol-position:left top; - padding:4px 6px; - margin-left:3px; - background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); - border:1px solid rgba(25,25,25,75); - border-top-left-radius:4px; - border-top-right-radius:4px; - } QTabWidget::pane { background-color:rgba(66,66,66,50%); } @@ -401,6 +418,9 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( subcontrol-position:top; subcontrol-origin:margin; } + QSlider { + background:transparent; + } QSlider::sub-page { background:%1; } @@ -447,6 +467,9 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( QStatusBar QLabel { background-color:transparent; } + QLabel { + background-color:transparent; + } QSizeGrip { background-color:solid; } From a924ac15c9a1fcfd8961b5a8c74f6f7f4e6ee0fb Mon Sep 17 00:00:00 2001 From: natinusala Date: Fri, 29 Mar 2019 10:08:12 +0100 Subject: [PATCH 096/237] ozone: fix content metadata for music and movie playlists --- menu/drivers/ozone/ozone.c | 4 +++- menu/drivers/ozone/ozone.h | 2 +- menu/drivers/ozone/ozone_entries.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index 62b1589c9a..3ac69a399c 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1153,7 +1153,9 @@ void ozone_update_content_metadata(ozone_handle_t *ozone) snprintf(ozone->selection_core_name, sizeof(ozone->selection_core_name), "%s %s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_CORE), core_label); - ozone->selection_core_is_imageviewer = string_is_equal(core_label, "imageviewer"); + ozone->selection_core_is_viewer = string_is_equal(core_label, "imageviewer") + || string_is_equal(core_label, "musicplayer") + || string_is_equal(core_label, "movieplayer"); word_wrap(ozone->selection_core_name, ozone->selection_core_name, (unsigned)((float)ozone->dimensions.thumbnail_bar_width * (float)0.85) / ozone->footer_font_glyph_width, false); ozone->selection_core_name_lines = ozone_count_lines(ozone->selection_core_name); diff --git a/menu/drivers/ozone/ozone.h b/menu/drivers/ozone/ozone.h index a6772505f7..3448669d9b 100644 --- a/menu/drivers/ozone/ozone.h +++ b/menu/drivers/ozone/ozone.h @@ -240,7 +240,7 @@ struct ozone_handle char selection_playtime[255]; char selection_lastplayed[255]; unsigned selection_core_name_lines; - bool selection_core_is_imageviewer; + bool selection_core_is_viewer; bool is_db_manager_list; }; diff --git a/menu/drivers/ozone/ozone_entries.c b/menu/drivers/ozone/ozone_entries.c index 7266823ae5..b81b56aed0 100644 --- a/menu/drivers/ozone/ozone_entries.c +++ b/menu/drivers/ozone/ozone_entries.c @@ -743,7 +743,7 @@ void ozone_draw_thumbnail_bar(ozone_handle_t *ozone, video_frame_info_t *video_i ozone_pure_white ); } - else if (!ozone->selection_core_is_imageviewer) + else if (!ozone->selection_core_is_viewer) { unsigned y = video_info->height / 2 + ozone->dimensions.sidebar_entry_icon_padding / 2; unsigned content_metadata_padding = ozone->dimensions.sidebar_entry_icon_padding*3; From 41eab46111177711dc57a5083db8421701be3710 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 29 Mar 2019 12:39:03 +0100 Subject: [PATCH 097/237] (C89) Buildfixes --- menu/drivers/rgui.c | 4 ++-- retroarch.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 06e861cbf0..7928646637 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -1022,7 +1022,7 @@ static void rgui_render_fs_thumbnail(void) } } -static unsigned inline rgui_get_mini_thumbnail_fullwidth(void) +static unsigned INLINE rgui_get_mini_thumbnail_fullwidth(void) { unsigned width = mini_thumbnail.is_valid ? mini_thumbnail.width : 0; unsigned left_width = mini_left_thumbnail.is_valid ? mini_left_thumbnail.width : 0; @@ -2372,7 +2372,7 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update) static void *rgui_init(void **userdata, bool video_is_threaded) { unsigned new_font_height; - size_t fb_pitch, start; + size_t start; rgui_t *rgui = NULL; bool ret = false; settings_t *settings = config_get_ptr(); diff --git a/retroarch.c b/retroarch.c index 308783897d..154e6bad69 100644 --- a/retroarch.c +++ b/retroarch.c @@ -5327,6 +5327,7 @@ void rarch_log_file_init(void) /* > Attempt to initialise log file */ if (!string_is_empty(settings->paths.log_dir)) { + char buf[PATH_MAX_LENGTH]; /* Create log directory, if required */ if (!path_is_directory(settings->paths.log_dir)) { @@ -5341,7 +5342,6 @@ void rarch_log_file_init(void) } /* Format log file name */ - char buf[PATH_MAX_LENGTH]; fill_pathname_join(buf, settings->paths.log_dir, settings->bools.log_to_file_timestamp ? timestamped_log_file_name : file_path_str(FILE_PATH_DEFAULT_EVENT_LOG), sizeof(buf)); From 8639018976384ae7c816b7cf86616ef64643a393 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Fri, 29 Mar 2019 14:07:35 -0400 Subject: [PATCH 098/237] use proper scaled radial deadzone calculation --- input/input_driver.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/input/input_driver.c b/input/input_driver.c index 7d2b71f30a..edb2e4fa02 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -18,12 +18,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include @@ -881,18 +883,48 @@ static int16_t input_joypad_axis(const input_device_driver_t *drv, unsigned port { int16_t val = 0; settings_t *settings = config_get_ptr(); + bool left = true; if (!drv || !drv->axis) return 0; val = drv->axis(port, joyaxis); + if (AXIS_POS_GET(joyaxis) == AXIS_DIR_NONE) + { + /* current axis is negative */ + if (AXIS_NEG_GET(joyaxis) < 2) + { + /* current stick is the left */ + left = true; + } + else + left = false; + } + else + { + /* current axis is positive */ + if (AXIS_POS_GET(joyaxis) < 2) + { + /* current stick is the left */ + left = true; + } + else + left = false; + } + + if (settings->floats.input_analog_deadzone) { + /* 0/1 are the left analog X/Y axes, 2/3 are the right analog X/Y axes */ + int16_t x = input_joypad_axis_raw(drv, port, left ? 0 : 2); + int16_t y = input_joypad_axis_raw(drv, port, left ? 1 : 3); + int mag = sqrt(x * x + y * y); float normalized; + float normal_mag = (1.0f / 0x7fff) * mag; /* if analog value is below the deadzone, ignore it */ - val = ((float)abs(val) / 0x7fff) < settings->floats.input_analog_deadzone ? 0 : val; + val = normal_mag <= settings->floats.input_analog_deadzone ? 0 : val; if (val == 0) return 0; @@ -900,7 +932,7 @@ static int16_t input_joypad_axis(const input_device_driver_t *drv, unsigned port normalized = (1.0f / 0x7fff) * val; /* now scale the "good" analog range appropriately, so we don't start out way above 0 */ - val = 0x7fff * ((normalized - settings->floats.input_analog_deadzone) / (1.0f - settings->floats.input_analog_deadzone)); + val = 0x7fff * normalized * MIN(1.0f, ((normal_mag - settings->floats.input_analog_deadzone) / (1.0f - settings->floats.input_analog_deadzone))); } if (settings->floats.input_analog_sensitivity != 1.0f) From 255dc9d932bfbc36b0d89a77ef1b76c9c39e0f62 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Sun, 31 Mar 2019 08:53:36 -0500 Subject: [PATCH 099/237] don't alphabetize shader presets It makes it harder to edit them later. --- menu/menu_shader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/menu/menu_shader.c b/menu/menu_shader.c index c547bfc26c..4be5d9924a 100644 --- a/menu/menu_shader.c +++ b/menu/menu_shader.c @@ -343,7 +343,7 @@ bool menu_shader_manager_save_preset( if (!string_is_empty(basename)) strlcpy(preset_path, buffer, sizeof(preset_path)); - if (config_file_write(conf, preset_path, true)) + if (config_file_write(conf, preset_path, false)) { RARCH_LOG("Saved shader preset to %s.\n", preset_path); if (apply) @@ -363,7 +363,7 @@ bool menu_shader_manager_save_preset( fill_pathname_join(preset_path, dirs[d], buffer, sizeof(preset_path)); - if (config_file_write(conf, preset_path, true)) + if (config_file_write(conf, preset_path, false)) { RARCH_LOG("Saved shader preset to %s.\n", preset_path); if (apply) From 224f925b3ba0fd00245952b5256a1fb7447ec1e6 Mon Sep 17 00:00:00 2001 From: CozmoP <25121396+CozmoP@users.noreply.github.com> Date: Mon, 1 Apr 2019 02:07:08 +0200 Subject: [PATCH 100/237] fix camera and location dropdown lists --- list_special.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/list_special.c b/list_special.c index 4df9ed804d..2be08e3303 100644 --- a/list_special.c +++ b/list_special.c @@ -31,17 +31,13 @@ #include "menu/menu_driver.h" #endif -#ifdef HAVE_CAMERA #include "camera/camera_driver.h" -#endif #ifdef HAVE_WIFI #include "wifi/wifi_driver.h" #endif -#ifdef HAVE_LOCATION #include "location/location_driver.h" -#endif #include "list_special.h" #include "frontend/frontend_driver.h" @@ -187,7 +183,6 @@ struct string_list *string_list_new_special(enum string_list_type type, break; #endif case STRING_LIST_CAMERA_DRIVERS: -#ifdef HAVE_CAMERA for (i = 0; camera_driver_find_handle(i); i++) { const char *opt = camera_driver_find_ident(i); @@ -196,7 +191,6 @@ struct string_list *string_list_new_special(enum string_list_type type, string_list_append(s, opt, attr); } break; -#endif case STRING_LIST_WIFI_DRIVERS: #ifdef HAVE_WIFI for (i = 0; wifi_driver_find_handle(i); i++) @@ -209,15 +203,13 @@ struct string_list *string_list_new_special(enum string_list_type type, break; #endif case STRING_LIST_LOCATION_DRIVERS: -#ifdef HAVE_LOCATION for (i = 0; location_driver_find_handle(i); i++) { const char *opt = location_driver_find_ident(i); *len += strlen(opt) + 1; - string_list_append(options_l, opt, attr); + string_list_append(s, opt, attr); } break; -#endif case STRING_LIST_AUDIO_DRIVERS: for (i = 0; audio_driver_find_handle(i); i++) { From 3c10731fbd1523977d02881570580c687e28334e Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 1 Apr 2019 13:52:10 +0100 Subject: [PATCH 101/237] (RGUI) Add optional shadow effects --- config.def.h | 1 + configuration.c | 1 + configuration.h | 1 + intl/msg_hash_lbl.h | 2 + intl/msg_hash_us.h | 8 + menu/cbs/menu_cbs_sublabel.c | 4 + menu/drivers/rgui.c | 400 ++++++++++++++++++++++++++--------- menu/menu_displaylist.c | 4 + menu/menu_setting.c | 15 ++ msg_hash.h | 1 + 10 files changed, 333 insertions(+), 104 deletions(-) diff --git a/config.def.h b/config.def.h index 5a5cabcf4d..fda9c97c41 100644 --- a/config.def.h +++ b/config.def.h @@ -391,6 +391,7 @@ static unsigned rgui_internal_upscale_level = RGUI_UPSCALE_NONE; static bool rgui_full_width_layout = true; static unsigned rgui_aspect = RGUI_ASPECT_RATIO_4_3; static unsigned rgui_aspect_lock = RGUI_ASPECT_RATIO_LOCK_NONE; +static bool rgui_shadows = false; #else static bool default_block_config_read = false; diff --git a/configuration.c b/configuration.c index ad007934d0..491e3bfb65 100644 --- a/configuration.c +++ b/configuration.c @@ -1508,6 +1508,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("rgui_background_filler_thickness_enable", &settings->bools.menu_rgui_background_filler_thickness_enable, true, true, false); SETTING_BOOL("rgui_border_filler_thickness_enable", &settings->bools.menu_rgui_border_filler_thickness_enable, true, true, false); SETTING_BOOL("rgui_border_filler_enable", &settings->bools.menu_rgui_border_filler_enable, true, true, false); + SETTING_BOOL("menu_rgui_shadows", &settings->bools.menu_rgui_shadows, true, rgui_shadows, false); SETTING_BOOL("menu_rgui_full_width_layout", &settings->bools.menu_rgui_full_width_layout, true, rgui_full_width_layout, false); SETTING_BOOL("rgui_inline_thumbnails", &settings->bools.menu_rgui_inline_thumbnails, true, rgui_inline_thumbnails, false); SETTING_BOOL("rgui_swap_thumbnails", &settings->bools.menu_rgui_swap_thumbnails, true, rgui_swap_thumbnails, false); diff --git a/configuration.h b/configuration.h index 7d4728b9eb..b53db75971 100644 --- a/configuration.h +++ b/configuration.h @@ -172,6 +172,7 @@ typedef struct settings bool menu_rgui_border_filler_thickness_enable; bool menu_rgui_border_filler_enable; bool menu_rgui_full_width_layout; + bool menu_rgui_shadows; bool menu_rgui_inline_thumbnails; bool menu_rgui_swap_thumbnails; bool menu_xmb_shadows_enable; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 4faa07bd24..b70d3fb6fa 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1625,6 +1625,8 @@ MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK, "rgui_aspect_ratio_lock") MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT, "menu_rgui_full_width_layout") +MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_SHADOWS, + "menu_rgui_shadows") MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_REWIND, "menu_show_rewind_settings") MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 15b88d24ea..252f8bcc99 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -6908,6 +6908,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_MENU_RGUI_FULL_WIDTH_LAYOUT, "Resize and position menu entries to make best use of available screen space. Disable this to use classic fixed-width two column layout." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_RGUI_SHADOWS, + "Shadow Effects" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_RGUI_SHADOWS, + "Enable drop shadows for menu text, borders and thumbnails. Has a modest performance impact." + ) MSG_HASH( MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For CRT displays only. Attempts to use exact core/game resolution and refresh rate." diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index f60a588484..f2cb33e60b 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -528,6 +528,7 @@ default_sublabel_macro(action_bind_sublabel_menu_linear_filter, default_sublabel_macro(action_bind_sublabel_menu_rgui_aspect_ratio_lock, MENU_ENUM_SUBLABEL_MENU_RGUI_ASPECT_RATIO_LOCK) default_sublabel_macro(action_bind_sublabel_rgui_menu_color_theme, MENU_ENUM_SUBLABEL_RGUI_MENU_COLOR_THEME) default_sublabel_macro(action_bind_sublabel_rgui_menu_theme_preset, MENU_ENUM_SUBLABEL_RGUI_MENU_THEME_PRESET) +default_sublabel_macro(action_bind_sublabel_menu_rgui_shadows, MENU_ENUM_SUBLABEL_MENU_RGUI_SHADOWS) default_sublabel_macro(action_bind_sublabel_menu_rgui_inline_thumbnails, MENU_ENUM_SUBLABEL_MENU_RGUI_INLINE_THUMBNAILS) default_sublabel_macro(action_bind_sublabel_menu_rgui_swap_thumbnails, MENU_ENUM_SUBLABEL_MENU_RGUI_SWAP_THUMBNAILS) default_sublabel_macro(action_bind_sublabel_menu_rgui_thumbnail_downscaler, MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER) @@ -2424,6 +2425,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_rgui_menu_theme_preset); break; + case MENU_ENUM_LABEL_MENU_RGUI_SHADOWS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_shadows); + break; case MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_inline_thumbnails); break; diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 7928646637..44a8649508 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -94,6 +94,7 @@ typedef struct uint32_t bg_light_color; uint32_t border_dark_color; uint32_t border_light_color; + uint32_t shadow_color; } rgui_theme_t; static const rgui_theme_t rgui_theme_classic_red = { @@ -103,7 +104,8 @@ static const rgui_theme_t rgui_theme_classic_red = { 0xC0202020, /* bg_dark_color */ 0xC0404040, /* bg_light_color */ 0xC08C0000, /* border_dark_color */ - 0xC0CC0E03 /* border_light_color */ + 0xC0CC0E03, /* border_light_color */ + 0xC0000000 /* shadow_color */ }; static const rgui_theme_t rgui_theme_classic_orange = { @@ -113,7 +115,8 @@ static const rgui_theme_t rgui_theme_classic_orange = { 0xC0202020, /* bg_dark_color */ 0xC0404040, /* bg_light_color */ 0xC0962800, /* border_dark_color */ - 0xC0E46C03 /* border_light_color */ + 0xC0E46C03, /* border_light_color */ + 0xC0000000 /* shadow_color */ }; static const rgui_theme_t rgui_theme_classic_yellow = { @@ -123,7 +126,8 @@ static const rgui_theme_t rgui_theme_classic_yellow = { 0xC0202020, /* bg_dark_color */ 0xC0404040, /* bg_light_color */ 0xC0AC7800, /* border_dark_color */ - 0xC0F3C60D /* border_light_color */ + 0xC0F3C60D, /* border_light_color */ + 0xC0000000 /* shadow_color */ }; static const rgui_theme_t rgui_theme_classic_green = { @@ -133,7 +137,8 @@ static const rgui_theme_t rgui_theme_classic_green = { 0xC0202020, /* bg_dark_color */ 0xC0404040, /* bg_light_color */ 0xC0204020, /* border_dark_color */ - 0xC0408040 /* border_light_color */ + 0xC0408040, /* border_light_color */ + 0xC0000000 /* shadow_color */ }; static const rgui_theme_t rgui_theme_classic_blue = { @@ -143,7 +148,8 @@ static const rgui_theme_t rgui_theme_classic_blue = { 0xC0202020, /* bg_dark_color */ 0xC0404040, /* bg_light_color */ 0xC0005BA6, /* border_dark_color */ - 0xC02E94E2 /* border_light_color */ + 0xC02E94E2, /* border_light_color */ + 0xC0000000 /* shadow_color */ }; static const rgui_theme_t rgui_theme_classic_violet = { @@ -153,7 +159,8 @@ static const rgui_theme_t rgui_theme_classic_violet = { 0xC0202020, /* bg_dark_color */ 0xC0404040, /* bg_light_color */ 0xC04C0A60, /* border_dark_color */ - 0xC0842DCE /* border_light_color */ + 0xC0842DCE, /* border_light_color */ + 0xC0000000 /* shadow_color */ }; static const rgui_theme_t rgui_theme_classic_grey = { @@ -163,7 +170,8 @@ static const rgui_theme_t rgui_theme_classic_grey = { 0xC0202020, /* bg_dark_color */ 0xC0404040, /* bg_light_color */ 0xC0505050, /* border_dark_color */ - 0xC0798A99 /* border_light_color */ + 0xC0798A99, /* border_light_color */ + 0xC0000000 /* shadow_color */ }; static const rgui_theme_t rgui_theme_legacy_red = { @@ -173,7 +181,8 @@ static const rgui_theme_t rgui_theme_legacy_red = { 0xC09E4137, /* bg_dark_color */ 0xC0B34B41, /* bg_light_color */ 0xC0BF5E58, /* border_dark_color */ - 0xC0F27A6F /* border_light_color */ + 0xC0F27A6F, /* border_light_color */ + 0xC01F0C0A /* shadow_color */ }; static const rgui_theme_t rgui_theme_dark_purple = { @@ -183,7 +192,8 @@ static const rgui_theme_t rgui_theme_dark_purple = { 0xC0562D56, /* bg_dark_color */ 0xC0663A66, /* bg_light_color */ 0xC0885783, /* border_dark_color */ - 0xC0A675A1 /* border_light_color */ + 0xC0A675A1, /* border_light_color */ + 0xC0140A14 /* shadow_color */ }; static const rgui_theme_t rgui_theme_midnight_blue = { @@ -193,7 +203,8 @@ static const rgui_theme_t rgui_theme_midnight_blue = { 0xC024374A, /* bg_dark_color */ 0xC03C4D5E, /* bg_light_color */ 0xC046586A, /* border_dark_color */ - 0xC06D7F91 /* border_light_color */ + 0xC06D7F91, /* border_light_color */ + 0xC00A0F14 /* shadow_color */ }; static const rgui_theme_t rgui_theme_golden = { @@ -203,7 +214,8 @@ static const rgui_theme_t rgui_theme_golden = { 0xC0B88D0B, /* bg_dark_color */ 0xC0BF962B, /* bg_light_color */ 0xC0e1ad21, /* border_dark_color */ - 0xC0FCC717 /* border_light_color */ + 0xC0FCC717, /* border_light_color */ + 0xC0382B03 /* shadow_color */ }; static const rgui_theme_t rgui_theme_electric_blue = { @@ -213,7 +225,8 @@ static const rgui_theme_t rgui_theme_electric_blue = { 0xC02E69C6, /* bg_dark_color */ 0xC0007FFF, /* bg_light_color */ 0xC034A5D8, /* border_dark_color */ - 0xC070C9FF /* border_light_color */ + 0xC070C9FF, /* border_light_color */ + 0xC012294D /* shadow_color */ }; static const rgui_theme_t rgui_theme_apple_green = { @@ -223,7 +236,8 @@ static const rgui_theme_t rgui_theme_apple_green = { 0xC04F7942, /* bg_dark_color */ 0xC0688539, /* bg_light_color */ 0xC0608E3A, /* border_dark_color */ - 0xC09AB973 /* border_light_color */ + 0xC09AB973, /* border_light_color */ + 0xC01F2E19 /* shadow_color */ }; static const rgui_theme_t rgui_theme_volcanic_red = { @@ -233,7 +247,8 @@ static const rgui_theme_t rgui_theme_volcanic_red = { 0xC0922724, /* bg_dark_color */ 0xC0BD0F1E, /* bg_light_color */ 0xC0CE2029, /* border_dark_color */ - 0xC0FF0000 /* border_light_color */ + 0xC0FF0000, /* border_light_color */ + 0xC0330D0D /* shadow_color */ }; static const rgui_theme_t rgui_theme_lagoon = { @@ -243,7 +258,8 @@ static const rgui_theme_t rgui_theme_lagoon = { 0xC0495C6B, /* bg_dark_color */ 0xC0526778, /* bg_light_color */ 0xC058848F, /* border_dark_color */ - 0xC060909C /* border_light_color */ + 0xC060909C, /* border_light_color */ + 0xC01C2329 /* shadow_color */ }; static const rgui_theme_t rgui_theme_brogrammer = { @@ -253,7 +269,8 @@ static const rgui_theme_t rgui_theme_brogrammer = { 0xC0242424, /* bg_dark_color */ 0xC0242424, /* bg_light_color */ 0xC0E74C3C, /* border_dark_color */ - 0xC0E74C3C /* border_light_color */ + 0xC0E74C3C, /* border_light_color */ + 0xC0000000 /* shadow_color */ }; static const rgui_theme_t rgui_theme_dracula = { @@ -263,7 +280,8 @@ static const rgui_theme_t rgui_theme_dracula = { 0xC02F3240, /* bg_dark_color */ 0xC02F3240, /* bg_light_color */ 0xC06272A4, /* border_dark_color */ - 0xC06272A4 /* border_light_color */ + 0xC06272A4, /* border_light_color */ + 0xC00F0F0F /* shadow_color */ }; static const rgui_theme_t rgui_theme_fairyfloss = { @@ -273,7 +291,8 @@ static const rgui_theme_t rgui_theme_fairyfloss = { 0xC0675F87, /* bg_dark_color */ 0xC0675F87, /* bg_light_color */ 0xC08077A8, /* border_dark_color */ - 0xC08077A8 /* border_light_color */ + 0xC08077A8, /* border_light_color */ + 0xC0262433 /* shadow_color */ }; static const rgui_theme_t rgui_theme_flatui = { @@ -283,7 +302,8 @@ static const rgui_theme_t rgui_theme_flatui = { 0xE0ECF0F1, /* bg_dark_color */ 0xE0ECF0F1, /* bg_light_color */ 0xE095A5A6, /* border_dark_color */ - 0xE095A5A6 /* border_light_color */ + 0xE095A5A6, /* border_light_color */ + 0xE0C3DBDE /* shadow_color */ }; static const rgui_theme_t rgui_theme_gruvbox_dark = { @@ -293,7 +313,8 @@ static const rgui_theme_t rgui_theme_gruvbox_dark = { 0xC03D3D3D, /* bg_dark_color */ 0xC03D3D3D, /* bg_light_color */ 0xC099897A, /* border_dark_color */ - 0xC099897A /* border_light_color */ + 0xC099897A, /* border_light_color */ + 0xC0000000 /* shadow_color */ }; static const rgui_theme_t rgui_theme_gruvbox_light = { @@ -303,7 +324,8 @@ static const rgui_theme_t rgui_theme_gruvbox_light = { 0xE0FBEBC7, /* bg_dark_color */ 0xE0FBEBC7, /* bg_light_color */ 0xE0928374, /* border_dark_color */ - 0xE0928374 /* border_light_color */ + 0xE0928374, /* border_light_color */ + 0xE0D5C4A1 /* shadow_color */ }; static const rgui_theme_t rgui_theme_hacking_the_kernel = { @@ -313,7 +335,8 @@ static const rgui_theme_t rgui_theme_hacking_the_kernel = { 0xC0000000, /* bg_dark_color */ 0xC0000000, /* bg_light_color */ 0xC0036303, /* border_dark_color */ - 0xC0036303 /* border_light_color */ + 0xC0036303, /* border_light_color */ + 0xC0154D2B /* shadow_color */ }; static const rgui_theme_t rgui_theme_nord = { @@ -323,7 +346,8 @@ static const rgui_theme_t rgui_theme_nord = { 0xC0363C4F, /* bg_dark_color */ 0xC0363C4F, /* bg_light_color */ 0xC04E596E, /* border_dark_color */ - 0xC04E596E /* border_light_color */ + 0xC04E596E, /* border_light_color */ + 0xC0040505 /* shadow_color */ }; static const rgui_theme_t rgui_theme_nova = { @@ -333,7 +357,8 @@ static const rgui_theme_t rgui_theme_nova = { 0xC0485B66, /* bg_dark_color */ 0xC0485B66, /* bg_light_color */ 0xC0627985, /* border_dark_color */ - 0xC0627985 /* border_light_color */ + 0xC0627985, /* border_light_color */ + 0xC01E272C /* shadow_color */ }; static const rgui_theme_t rgui_theme_one_dark = { @@ -343,7 +368,8 @@ static const rgui_theme_t rgui_theme_one_dark = { 0xC02D323B, /* bg_dark_color */ 0xC02D323B, /* bg_light_color */ 0xC0495162, /* border_dark_color */ - 0xC0495162 /* border_light_color */ + 0xC0495162, /* border_light_color */ + 0xC007080A /* shadow_color */ }; static const rgui_theme_t rgui_theme_palenight = { @@ -353,7 +379,8 @@ static const rgui_theme_t rgui_theme_palenight = { 0xC02F3347, /* bg_dark_color */ 0xC02F3347, /* bg_light_color */ 0xC0697098, /* border_dark_color */ - 0xC0697098 /* border_light_color */ + 0xC0697098, /* border_light_color */ + 0xC00D0E14 /* shadow_color */ }; static const rgui_theme_t rgui_theme_solarized_dark = { @@ -363,7 +390,8 @@ static const rgui_theme_t rgui_theme_solarized_dark = { 0xC0003542, /* bg_dark_color */ 0xC0003542, /* bg_light_color */ 0xC093A1A1, /* border_dark_color */ - 0xC093A1A1 /* border_light_color */ + 0xC093A1A1, /* border_light_color */ + 0xC000141A /* shadow_color */ }; static const rgui_theme_t rgui_theme_solarized_light = { @@ -373,7 +401,8 @@ static const rgui_theme_t rgui_theme_solarized_light = { 0xE0FDEDDF, /* bg_dark_color */ 0xE0FDEDDF, /* bg_light_color */ 0xE093A1A1, /* border_dark_color */ - 0xE093A1A1 /* border_light_color */ + 0xE093A1A1, /* border_light_color */ + 0xE0E0DBC9 /* shadow_color */ }; static const rgui_theme_t rgui_theme_tango_dark = { @@ -383,7 +412,8 @@ static const rgui_theme_t rgui_theme_tango_dark = { 0xC0384042, /* bg_dark_color */ 0xC0384042, /* bg_light_color */ 0xC06A767A, /* border_dark_color */ - 0xC06A767A /* border_light_color */ + 0xC06A767A, /* border_light_color */ + 0xC01A1A1A /* shadow_color */ }; static const rgui_theme_t rgui_theme_tango_light = { @@ -393,7 +423,8 @@ static const rgui_theme_t rgui_theme_tango_light = { 0xE0EEEEEC, /* bg_dark_color */ 0xE0EEEEEC, /* bg_light_color */ 0xE0C7C7C7, /* border_dark_color */ - 0xE0C7C7C7 /* border_light_color */ + 0xE0C7C7C7, /* border_light_color */ + 0xE0D3D7CF /* shadow_color */ }; static const rgui_theme_t rgui_theme_zenburn = { @@ -403,7 +434,8 @@ static const rgui_theme_t rgui_theme_zenburn = { 0xC04F4F4F, /* bg_dark_color */ 0xC04F4F4F, /* bg_light_color */ 0xC0636363, /* border_dark_color */ - 0xC0636363 /* border_light_color */ + 0xC0636363, /* border_light_color */ + 0xC01F1F1F /* shadow_color */ }; static const rgui_theme_t rgui_theme_anti_zenburn = { @@ -413,7 +445,8 @@ static const rgui_theme_t rgui_theme_anti_zenburn = { 0xE0C0C0C0, /* bg_dark_color */ 0xE0C0C0C0, /* bg_light_color */ 0xE0A0A0A0, /* border_dark_color */ - 0xE0A0A0A0 /* border_light_color */ + 0xE0A0A0A0, /* border_light_color */ + 0xE0B0B0B0 /* shadow_color */ }; typedef struct @@ -425,6 +458,7 @@ typedef struct uint16_t bg_light_color; uint16_t border_dark_color; uint16_t border_light_color; + uint16_t shadow_color; } rgui_colors_t; typedef struct @@ -652,6 +686,51 @@ static uint16_t argb32_to_rgba4444(uint32_t col) #endif +static uint16_t rgui_bg_filler(rgui_t *rgui, unsigned x, unsigned y) +{ + unsigned shift = (rgui->bg_thickness ? 1 : 0); + unsigned select = ((x >> shift) + (y >> shift)) & 1; + return (select == 0) ? rgui->colors.bg_dark_color : rgui->colors.bg_light_color; +} + +static uint16_t rgui_border_filler(rgui_t *rgui, unsigned x, unsigned y) +{ + unsigned shift = (rgui->border_thickness ? 1 : 0); + unsigned select = ((x >> shift) + (y >> shift)) & 1; + return (select == 0) ? rgui->colors.border_dark_color : rgui->colors.border_light_color; +} + +static void rgui_fill_rect( + rgui_t *rgui, + uint16_t *data, + size_t pitch, + unsigned x, unsigned y, + unsigned width, unsigned height, + uint16_t (*col)(rgui_t *rgui, unsigned x, unsigned y)) +{ + unsigned i, j; + + for (j = y; j < y + height; j++) + for (i = x; i < x + width; i++) + data[j * (pitch >> 1) + i] = col(rgui, i, j); +} + +static void rgui_color_rect( + uint16_t *data, + size_t pitch, + unsigned fb_width, unsigned fb_height, + unsigned x, unsigned y, + unsigned width, unsigned height, + uint16_t color) +{ + unsigned i, j; + + for (j = y; j < y + height; j++) + for (i = x; i < x + width; i++) + if (i < fb_width && j < fb_height) + data[j * (pitch >> 1) + i] = color; +} + static bool request_wallpaper(const char *path) { /* Do nothing if current wallpaper path hasn't changed */ @@ -967,8 +1046,9 @@ static bool rgui_render_wallpaper(void) return false; } -static void rgui_render_fs_thumbnail(void) +static void rgui_render_fs_thumbnail(rgui_t *rgui) { + settings_t *settings = config_get_ptr(); size_t fb_pitch; unsigned fb_width, fb_height; unsigned x, y; @@ -976,6 +1056,9 @@ static void rgui_render_fs_thumbnail(void) unsigned thumb_x_offset, thumb_y_offset; unsigned width, height; + if (!settings) + return; + if (fs_thumbnail.is_valid && rgui_frame_buf.data && fs_thumbnail.data) { menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch); @@ -1019,6 +1102,53 @@ static void rgui_render_fs_thumbnail(void) fs_thumbnail.data[(x + thumb_x_offset) + ((y + thumb_y_offset) * fs_thumbnail.width)]; } } + + /* Draw drop shadow, if required */ + if (settings->bools.menu_rgui_shadows) + { + unsigned shadow_x; + unsigned shadow_y; + unsigned shadow_width; + unsigned shadow_height; + + /* Vertical component */ + if (fs_thumbnail.width < fb_width) + { + shadow_width = fb_width - fs_thumbnail.width; + shadow_width = shadow_width > 2 ? 2 : shadow_width; + shadow_height = fs_thumbnail.height + 2 < fb_height ? fs_thumbnail.height : fb_height - 2; + + shadow_x = fb_x_offset + fs_thumbnail.width; + shadow_y = fb_y_offset + 2; + + /* Super paranoid safety check... + * (This is not required at all, but terrible things + * will happen if we ever go out of bounds...) */ + if (((shadow_x + shadow_width) <= fb_width) && + ((shadow_y + shadow_height) <= fb_height)) + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + shadow_x, shadow_y, shadow_width, shadow_height, rgui->colors.shadow_color); + } + + /* Horizontal component */ + if (fs_thumbnail.height < fb_height) + { + shadow_height = fb_height - fs_thumbnail.height; + shadow_height = shadow_height > 2 ? 2 : shadow_height; + shadow_width = fs_thumbnail.width + 2 < fb_width ? fs_thumbnail.width : fb_width - 2; + + shadow_x = fb_x_offset + 2; + shadow_y = fb_y_offset + fs_thumbnail.height; + + /* Super paranoid safety check... + * (This is not required at all, but terrible things + * will happen if we ever go out of bounds...) */ + if (((shadow_x + shadow_width) <= fb_width) && + ((shadow_y + shadow_height) <= fb_height)) + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + shadow_x, shadow_y, shadow_width, shadow_height, rgui->colors.shadow_color); + } + } } } @@ -1029,7 +1159,7 @@ static unsigned INLINE rgui_get_mini_thumbnail_fullwidth(void) return width >= left_width ? width : left_width; } -static void rgui_render_mini_thumbnail(thumbnail_t *thumbnail, enum menu_thumbnail_id thumbnail_id) +static void rgui_render_mini_thumbnail(rgui_t *rgui, thumbnail_t *thumbnail, enum menu_thumbnail_id thumbnail_id) { settings_t *settings = config_get_ptr(); size_t fb_pitch; @@ -1077,6 +1207,15 @@ static void rgui_render_mini_thumbnail(thumbnail_t *thumbnail, enum menu_thumbna thumbnail->data[x + (y * thumbnail->width)]; } } + + /* Draw drop shadow, if required */ + if (settings->bools.menu_rgui_shadows) + { + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + fb_x_offset + thumbnail->width, fb_y_offset + 1, 1, thumbnail->height, rgui->colors.shadow_color); + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + fb_x_offset + 1, fb_y_offset + thumbnail->height, thumbnail->width, 1, rgui->colors.shadow_color); + } } } @@ -1162,7 +1301,8 @@ static void load_custom_theme(rgui_t *rgui, rgui_theme_t *theme_colors, const ch char *wallpaper_key = NULL; unsigned normal_color, hover_color, title_color, bg_dark_color, bg_light_color, - border_dark_color, border_light_color; + border_dark_color, border_light_color, + shadow_color; char wallpaper_file[PATH_MAX_LENGTH]; bool success = false; @@ -1218,6 +1358,12 @@ static void load_custom_theme(rgui_t *rgui, rgui_theme_t *theme_colors, const ch if(!config_get_hex(conf, "rgui_border_light_color", &border_light_color)) goto end; + /* Make shadow colour optional (fallback to fully opaque black) + * - i.e. if user has no intention of enabling shadows, they + * should not have to include this entry */ + if(!config_get_hex(conf, "rgui_shadow_color", &shadow_color)) + shadow_color = 0xFF000000; + config_get_array(conf, wallpaper_key, wallpaper_file, sizeof(wallpaper_file)); success = true; @@ -1233,6 +1379,7 @@ end: theme_colors->bg_light_color = (uint32_t)bg_light_color; theme_colors->border_dark_color = (uint32_t)border_dark_color; theme_colors->border_light_color = (uint32_t)border_light_color; + theme_colors->shadow_color = (uint32_t)shadow_color; /* Load wallpaper, if required */ if (!string_is_empty(wallpaper_file)) @@ -1254,6 +1401,7 @@ end: theme_colors->bg_light_color = rgui_theme_classic_green.bg_light_color; theme_colors->border_dark_color = rgui_theme_classic_green.border_dark_color; theme_colors->border_light_color = rgui_theme_classic_green.border_light_color; + theme_colors->shadow_color = rgui_theme_classic_green.shadow_color; } if (conf) @@ -1282,6 +1430,7 @@ static void prepare_rgui_colors(rgui_t *rgui, settings_t *settings) theme_colors.bg_light_color = current_theme->bg_light_color; theme_colors.border_dark_color = current_theme->border_dark_color; theme_colors.border_light_color = current_theme->border_light_color; + theme_colors.shadow_color = current_theme->shadow_color; } rgui->colors.hover_color = argb32_to_pixel_platform_format(theme_colors.hover_color); rgui->colors.normal_color = argb32_to_pixel_platform_format(theme_colors.normal_color); @@ -1290,83 +1439,79 @@ static void prepare_rgui_colors(rgui_t *rgui, settings_t *settings) rgui->colors.bg_light_color = argb32_to_pixel_platform_format(theme_colors.bg_light_color); rgui->colors.border_dark_color = argb32_to_pixel_platform_format(theme_colors.border_dark_color); rgui->colors.border_light_color = argb32_to_pixel_platform_format(theme_colors.border_light_color); + rgui->colors.shadow_color = argb32_to_pixel_platform_format(theme_colors.shadow_color); rgui->bg_modified = true; rgui->force_redraw = true; } -static uint16_t rgui_bg_filler(rgui_t *rgui, unsigned x, unsigned y) -{ - unsigned shift = (rgui->bg_thickness ? 1 : 0); - unsigned select = ((x >> shift) + (y >> shift)) & 1; - return (select == 0) ? rgui->colors.bg_dark_color : rgui->colors.bg_light_color; -} - -static uint16_t rgui_border_filler(rgui_t *rgui, unsigned x, unsigned y) -{ - unsigned shift = (rgui->border_thickness ? 1 : 0); - unsigned select = ((x >> shift) + (y >> shift)) & 1; - return (select == 0) ? rgui->colors.border_dark_color : rgui->colors.border_light_color; -} - -static void rgui_fill_rect( - rgui_t *rgui, - uint16_t *data, - size_t pitch, - unsigned x, unsigned y, - unsigned width, unsigned height, - uint16_t (*col)(rgui_t *rgui, unsigned x, unsigned y)) -{ - unsigned i, j; - - for (j = y; j < y + height; j++) - for (i = x; i < x + width; i++) - data[j * (pitch >> 1) + i] = col(rgui, i, j); -} - -static void rgui_color_rect( - uint16_t *data, - size_t pitch, - unsigned fb_width, unsigned fb_height, - unsigned x, unsigned y, - unsigned width, unsigned height, - uint16_t color) -{ - unsigned i, j; - - for (j = y; j < y + height; j++) - for (i = x; i < x + width; i++) - if (i < fb_width && j < fb_height) - data[j * (pitch >> 1) + i] = color; -} - static void blit_line(int x, int y, - const char *message, uint16_t color) + const char *message, uint16_t color, uint16_t shadow_color, bool draw_shadow) { size_t pitch = menu_display_get_framebuffer_pitch(); const uint8_t *font_fb = menu_display_get_font_framebuffer(); if (font_fb) { - while (!string_is_empty(message)) + /* We're going to do some ugly loop unswitching here + * because rendering text is *very* expensive and I don't + * want to rely on the compiler to optimise this properly... */ + if (draw_shadow) { - unsigned i, j; - char symbol = *message++; - - for (j = 0; j < FONT_HEIGHT; j++) + /* Drop shadow version */ + while (!string_is_empty(message)) { - for (i = 0; i < FONT_WIDTH; i++) + unsigned i, j; + char symbol = *message++; + + for (j = 0; j < FONT_HEIGHT; j++) { - uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); - int offset = (i + j * FONT_WIDTH) >> 3; - bool col = (font_fb[FONT_OFFSET(symbol) + offset] & rem); + for (i = 0; i < FONT_WIDTH; i++) + { + uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); + int offset = (i + j * FONT_WIDTH) >> 3; - if (col) - rgui_frame_buf.data[(y + j) * (pitch >> 1) + (x + i)] = color; + if ((font_fb[FONT_OFFSET(symbol) + offset] & rem) > 0) + { + unsigned pixel_x = x + i; + unsigned pixel_y = y + j; + + /* Text pixel */ + rgui_frame_buf.data[pixel_y * (pitch >> 1) + pixel_x] = color; + + /* Shadow pixels */ + rgui_frame_buf.data[(pixel_y + 1) * (pitch >> 1) + pixel_x ] = shadow_color; + rgui_frame_buf.data[ pixel_y * (pitch >> 1) + (pixel_x + 1)] = shadow_color; + rgui_frame_buf.data[(pixel_y + 1) * (pitch >> 1) + (pixel_x + 1)] = shadow_color; + } + } } - } - x += FONT_WIDTH_STRIDE; + x += FONT_WIDTH_STRIDE; + } + } + else + { + /* Normal version */ + while (!string_is_empty(message)) + { + unsigned i, j; + char symbol = *message++; + + for (j = 0; j < FONT_HEIGHT; j++) + { + for (i = 0; i < FONT_WIDTH; i++) + { + uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); + int offset = (i + j * FONT_WIDTH) >> 3; + + if ((font_fb[FONT_OFFSET(symbol) + offset] & rem) > 0) + rgui_frame_buf.data[(y + j) * (pitch >> 1) + (x + i)] = color; + } + } + + x += FONT_WIDTH_STRIDE; + } } } } @@ -1473,10 +1618,24 @@ static void rgui_render_background(rgui_t *rgui) if (settings->bools.menu_rgui_border_filler_enable) { + /* Draw border */ rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, 5, 5, fb_width - 10, 5, rgui_border_filler); rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, 5, fb_height - 10, fb_width - 10, 5, rgui_border_filler); rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, 5, 5, 5, fb_height - 10, rgui_border_filler); rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, fb_width - 10, 5, 5, fb_height - 10, rgui_border_filler); + + /* Draw drop shadow, if required */ + if (settings->bools.menu_rgui_shadows) + { + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + 10, 10, 1, fb_height - 20, rgui->colors.shadow_color); + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + 10, 10, fb_width - 20, 1, rgui->colors.shadow_color); + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + fb_width - 5, 6, 1, fb_height - 10, rgui->colors.shadow_color); + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + 6, fb_height - 5, fb_width - 10, 1, rgui->colors.shadow_color); + } } } } @@ -1551,11 +1710,38 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) if (settings->bools.menu_rgui_border_filler_enable) { + /* Draw drop shadow, if required */ + if (settings->bools.menu_rgui_shadows) + { + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + x + 5, y + 5, 1, height - 5, rgui->colors.shadow_color); + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + x + 5, y + 5, width - 5, 1, rgui->colors.shadow_color); + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + x + width, y + 1, 1, height, rgui->colors.shadow_color); + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + x + 1, y + height, width, 1, rgui->colors.shadow_color); + } + + /* Draw border */ rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x, y, width - 5, 5, rgui_border_filler); rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x + width - 5, y, 5, height - 5, rgui_border_filler); rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x + 5, y + height - 5, width - 5, 5, rgui_border_filler); rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x, y + 5, 5, height - 5, rgui_border_filler); } + else if (settings->bools.menu_rgui_shadows) + { + /* Without a border, this is a bit silly... + * All we can do is draw a sort of frame... */ + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + x + 4, y + 4, 1, height - 8, rgui->colors.shadow_color); + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + x + 5, y + 4, width - 10, 1, rgui->colors.shadow_color); + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + x + width - 5, y + 4, 1, height - 8, rgui->colors.shadow_color); + rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, + x + 5, y + height - 5, width - 10, 1, rgui->colors.shadow_color); + } } for (i = 0; i < list->size; i++) @@ -1565,7 +1751,8 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) int offset_y = (int)(FONT_HEIGHT_STRIDE * i); if (rgui_frame_buf.data) - blit_line(x + 8 + offset_x, y + 8 + offset_y, msg, rgui->colors.normal_color); + blit_line(x + 8 + offset_x, y + 8 + offset_y, msg, + rgui->colors.normal_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); } end: @@ -1742,7 +1929,7 @@ static void rgui_render(void *data, bool is_idle) thumbnail_title_buf[0] = '\0'; /* Draw thumbnail */ - rgui_render_fs_thumbnail(); + rgui_render_fs_thumbnail(rgui); /* Get thumbnail title */ if (menu_thumbnail_get_label(rgui->thumbnail_path_data, &thumbnail_title)) @@ -1764,7 +1951,8 @@ static void rgui_render(void *data, bool is_idle) title_x - 5, 0, title_width + 10, FONT_HEIGHT_STRIDE, rgui_bg_filler); /* Draw thumbnail title */ - blit_line((int)title_x, 0, thumbnail_title_buf, rgui->colors.hover_color); + blit_line((int)title_x, 0, thumbnail_title_buf, + rgui->colors.hover_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); } } } @@ -1822,7 +2010,7 @@ static void rgui_render(void *data, bool is_idle) (int)(RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) - utf8len(title_buf)) * FONT_WIDTH_STRIDE / 2), RGUI_TERM_START_Y(fb_height) - FONT_HEIGHT_STRIDE, - title_buf, rgui->colors.title_color); + title_buf, rgui->colors.title_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); /* Print menu entries */ x = RGUI_TERM_START_X(fb_width); @@ -1963,7 +2151,8 @@ static void rgui_render(void *data, bool is_idle) if (rgui_frame_buf.data) blit_line(x, y, message, - entry_selected ? rgui->colors.hover_color : rgui->colors.normal_color); + entry_selected ? rgui->colors.hover_color : rgui->colors.normal_color, + rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); if (!string_is_empty(entry_path)) free(entry_path); @@ -1973,10 +2162,10 @@ static void rgui_render(void *data, bool is_idle) if (show_mini_thumbnails) { if (show_thumbnail) - rgui_render_mini_thumbnail(&mini_thumbnail, MENU_THUMBNAIL_RIGHT); + rgui_render_mini_thumbnail(rgui, &mini_thumbnail, MENU_THUMBNAIL_RIGHT); if (show_left_thumbnail) - rgui_render_mini_thumbnail(&mini_left_thumbnail, MENU_THUMBNAIL_LEFT); + rgui_render_mini_thumbnail(rgui, &mini_left_thumbnail, MENU_THUMBNAIL_LEFT); } /* Print menu sublabel/core name (if required) */ @@ -1996,7 +2185,8 @@ static void rgui_render(void *data, bool is_idle) blit_line( RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + - RGUI_TERM_START_Y(fb_height) + 2, sublabel_buf, rgui->colors.hover_color); + RGUI_TERM_START_Y(fb_height) + 2, sublabel_buf, + rgui->colors.hover_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); } else if (settings->bools.menu_core_enable) { @@ -2017,7 +2207,8 @@ static void rgui_render(void *data, bool is_idle) blit_line( RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + - RGUI_TERM_START_Y(fb_height) + 2, core_title_buf, rgui->colors.hover_color); + RGUI_TERM_START_Y(fb_height) + 2, core_title_buf, + rgui->colors.hover_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); } } @@ -2039,7 +2230,8 @@ static void rgui_render(void *data, bool is_idle) blit_line( timedate_x, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + - RGUI_TERM_START_Y(fb_height) + 2, timedate, rgui->colors.hover_color); + RGUI_TERM_START_Y(fb_height) + 2, timedate, + rgui->colors.hover_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); } } diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 9437e5d562..9ecf6a0bd4 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6131,6 +6131,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET, PARSE_ONLY_PATH, false) == 0) count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_RGUI_SHADOWS, + PARSE_ONLY_BOOL, false) == 0) + count++; if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE, PARSE_ONLY_BOOL, false) == 0) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index e574986ef2..d374ff1873 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -8511,6 +8511,21 @@ static bool setting_append_list( general_write_handler, general_read_handler); menu_settings_list_current_add_values(list, list_info, "cfg"); + + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_rgui_shadows, + MENU_ENUM_LABEL_MENU_RGUI_SHADOWS, + MENU_ENUM_LABEL_VALUE_MENU_RGUI_SHADOWS, + rgui_shadows, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); } if (string_is_equal(settings->arrays.menu_driver, "xmb")) diff --git a/msg_hash.h b/msg_hash.h index e4bc2b0ccf..6b840ec10c 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -871,6 +871,7 @@ enum msg_hash_enums MENU_LABEL(MENU_RGUI_ASPECT_RATIO), MENU_LABEL(MENU_RGUI_ASPECT_RATIO_LOCK), MENU_LABEL(MENU_RGUI_FULL_WIDTH_LAYOUT), + MENU_LABEL(MENU_RGUI_SHADOWS), MENU_LABEL(MENU_LINEAR_FILTER), MENU_LABEL(MENU_HORIZONTAL_ANIMATION), MENU_LABEL(NAVIGATION_WRAPAROUND), From 61fa0a0807f02c7b331dcec4d56dfb05fd328be9 Mon Sep 17 00:00:00 2001 From: Tatsuya79 Date: Mon, 1 Apr 2019 21:31:46 +0200 Subject: [PATCH 102/237] Move thumbnail type selection to grid footer. --- intl/msg_hash_pt_br.h | 2 +- intl/msg_hash_us.h | 2 +- ui/drivers/qt/ui_qt_window.cpp | 34 +++++++++++++++++++++++++++++ ui/drivers/qt/viewoptionsdialog.cpp | 20 ----------------- ui/drivers/qt/viewoptionsdialog.h | 2 -- ui/drivers/ui_qt.h | 3 +++ 6 files changed, 39 insertions(+), 24 deletions(-) diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index 01c28608ff..887df7ba7b 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -7773,7 +7773,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_TYPE, - "Tipo de visualização de miniatura de ícones:" + "Miniatura" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_CACHE_LIMIT, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 750eafe636..154d5ca8c6 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -8087,7 +8087,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_TYPE, - "Icon view thumbnail type:" + "Thumbnail" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_CACHE_LIMIT, diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index f79df2c354..74a617d864 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -366,6 +366,11 @@ MainWindow::MainWindow(QWidget *parent) : QToolButton *searchResetButton = NULL; QHBoxLayout *zoomLayout = new QHBoxLayout(); QLabel *zoomLabel = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ZOOM), m_zoomWidget); + QPushButton *thumbnailTypePushButton = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_TYPE), m_zoomWidget); + QMenu *thumbnailTypeMenu = new QMenu(thumbnailTypePushButton); + QAction *thumbnailTypeBoxartAction = NULL; + QAction *thumbnailTypeScreenshotAction = NULL; + QAction *thumbnailTypeTitleAction = NULL; QPushButton *viewTypePushButton = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_VIEW), m_zoomWidget); QMenu *viewTypeMenu = new QMenu(viewTypePushButton); QAction *viewTypeIconsAction = NULL; @@ -386,6 +391,15 @@ MainWindow::MainWindow(QWidget *parent) : m_gridProgressWidget = new QWidget(); gridProgressLabel = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PROGRESS), m_gridProgressWidget); + thumbnailTypePushButton->setObjectName("thumbnailTypePushButton"); + thumbnailTypePushButton->setFlat(true); + + thumbnailTypeBoxartAction = thumbnailTypeMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_BOXART)); + thumbnailTypeScreenshotAction = thumbnailTypeMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_SCREENSHOT)); + thumbnailTypeTitleAction = thumbnailTypeMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_TITLE_SCREEN)); + + thumbnailTypePushButton->setMenu(thumbnailTypeMenu); + viewTypePushButton->setObjectName("viewTypePushButton"); viewTypePushButton->setFlat(true); @@ -444,6 +458,7 @@ MainWindow::MainWindow(QWidget *parent) : gridFooterLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred)); gridFooterLayout->addWidget(m_gridProgressWidget); gridFooterLayout->addWidget(m_zoomWidget); + gridFooterLayout->addWidget(thumbnailTypePushButton); gridFooterLayout->addWidget(viewTypePushButton); static_cast(m_playlistViewsAndFooter->layout())->addLayout(gridFooterLayout); @@ -613,6 +628,9 @@ MainWindow::MainWindow(QWidget *parent) : connect(m_listWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(onPlaylistWidgetContextMenuRequested(const QPoint&))); connect(m_launchWithComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onLaunchWithComboBoxIndexChanged(int))); connect(m_zoomSlider, SIGNAL(valueChanged(int)), this, SLOT(onZoomValueChanged(int))); + connect(thumbnailTypeBoxartAction, SIGNAL(triggered()), this, SLOT(onBoxartThumbnailClicked())); + connect(thumbnailTypeScreenshotAction, SIGNAL(triggered()), this, SLOT(onScreenshotThumbnailClicked())); + connect(thumbnailTypeTitleAction, SIGNAL(triggered()), this, SLOT(onTitleThumbnailClicked())); connect(viewTypeIconsAction, SIGNAL(triggered()), this, SLOT(onIconViewClicked())); connect(viewTypeListAction, SIGNAL(triggered()), this, SLOT(onListViewClicked())); connect(m_dirModel, SIGNAL(directoryLoaded(const QString&)), this, SLOT(onFileSystemDirLoaded(const QString&))); @@ -830,6 +848,21 @@ void MainWindow::onListViewClicked() setCurrentViewType(VIEW_TYPE_LIST); } +void MainWindow::onBoxartThumbnailClicked() +{ + setCurrentThumbnailType(THUMBNAIL_TYPE_BOXART); +} + +void MainWindow::onScreenshotThumbnailClicked() +{ + setCurrentThumbnailType(THUMBNAIL_TYPE_SCREENSHOT); +} + +void MainWindow::onTitleThumbnailClicked() +{ + setCurrentThumbnailType(THUMBNAIL_TYPE_TITLE_SCREEN); +} + void MainWindow::setIconViewZoom(int zoomValue) { m_zoomSlider->setValue(zoomValue); @@ -2986,6 +3019,7 @@ void MainWindow::closeEvent(QCloseEvent *event) m_settings->setValue("view_type", getCurrentViewTypeString()); m_settings->setValue("file_browser_table_headers", m_fileTableView->horizontalHeader()->saveState()); m_settings->setValue("icon_view_zoom", m_lastZoomSliderValue); + m_settings->setValue("icon_view_thumbnail_type", getCurrentThumbnailTypeString()); QMainWindow::closeEvent(event); } diff --git a/ui/drivers/qt/viewoptionsdialog.cpp b/ui/drivers/qt/viewoptionsdialog.cpp index 52404998c7..2bb2cc7731 100644 --- a/ui/drivers/qt/viewoptionsdialog.cpp +++ b/ui/drivers/qt/viewoptionsdialog.cpp @@ -221,7 +221,6 @@ ViewOptionsWidget::ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent) : ,m_saveLastTabCheckBox(new QCheckBox(this)) ,m_showHiddenFilesCheckBox(new QCheckBox(this)) ,m_themeComboBox(new QComboBox(this)) - ,m_thumbnailComboBox(new QComboBox(this)) ,m_thumbnailCacheSpinBox(new QSpinBox(this)) ,m_startupPlaylistComboBox(new QComboBox(this)) ,m_highlightColorPushButton(new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CHOOSE), this)) @@ -239,10 +238,6 @@ ViewOptionsWidget::ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent) : m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK), MainWindow::THEME_DARK); m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM), MainWindow::THEME_CUSTOM); - m_thumbnailComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_BOXART), THUMBNAIL_TYPE_BOXART); - m_thumbnailComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_SCREENSHOT), THUMBNAIL_TYPE_SCREENSHOT); - m_thumbnailComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_TITLE_SCREEN), THUMBNAIL_TYPE_TITLE_SCREEN); - m_thumbnailCacheSpinBox->setSuffix(" MB"); m_thumbnailCacheSpinBox->setRange(0, 99999); @@ -260,7 +255,6 @@ ViewOptionsWidget::ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent) : /* form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_LIST_MAX_COUNT), m_allPlaylistsListMaxCountSpinBox); */ /* form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_GRID_MAX_COUNT), m_allPlaylistsGridMaxCountSpinBox); */ form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_STARTUP_PLAYLIST), m_startupPlaylistComboBox); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_TYPE), m_thumbnailComboBox); form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_CACHE_LIMIT), m_thumbnailCacheSpinBox); form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME), m_themeComboBox); form->addRow(m_highlightColorLabel, m_highlightColorPushButton); @@ -274,16 +268,9 @@ ViewOptionsWidget::ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent) : loadViewOptions(); connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThemeComboBoxIndexChanged(int))); - connect(m_thumbnailComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThumbnailComboBoxIndexChanged(int))); connect(m_highlightColorPushButton, SIGNAL(clicked()), this, SLOT(onHighlightColorChoose())); } -void ViewOptionsWidget::onThumbnailComboBoxIndexChanged(int index) -{ - ThumbnailType type = static_cast(m_thumbnailComboBox->currentData().value()); - m_mainwindow->setCurrentThumbnailType(type); -} - void ViewOptionsWidget::onThemeComboBoxIndexChanged(int) { MainWindow::Theme theme = static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()); @@ -342,7 +329,6 @@ void ViewOptionsWidget::loadViewOptions() QVector > playlists = m_mainwindow->getPlaylists(); QString initialPlaylist = m_settings->value("initial_playlist", m_mainwindow->getSpecialPlaylistPath(SPECIAL_PLAYLIST_HISTORY)).toString(); int themeIndex = 0; - int thumbnailIndex = 0; int playlistIndex = 0; int i; @@ -360,11 +346,6 @@ void ViewOptionsWidget::loadViewOptions() if (m_themeComboBox->count() > themeIndex) m_themeComboBox->setCurrentIndex(themeIndex); - thumbnailIndex = m_thumbnailComboBox->findData(m_mainwindow->getThumbnailTypeFromString(m_settings->value("icon_view_thumbnail_type", "boxart").toString())); - - if (m_thumbnailComboBox->count() > thumbnailIndex) - m_thumbnailComboBox->setCurrentIndex(thumbnailIndex); - if (highlightColor.isValid()) { m_highlightColor = highlightColor; @@ -415,7 +396,6 @@ void ViewOptionsWidget::saveViewOptions() /* m_settings->setValue("all_playlists_list_max_count", m_allPlaylistsListMaxCountSpinBox->value()); */ /* m_settings->setValue("all_playlists_grid_max_count", m_allPlaylistsGridMaxCountSpinBox->value()); */ m_settings->setValue("initial_playlist", m_startupPlaylistComboBox->currentData(Qt::UserRole).toString()); - m_settings->setValue("icon_view_thumbnail_type", m_mainwindow->getCurrentThumbnailTypeString()); m_settings->setValue("thumbnail_cache_limit", m_thumbnailCacheSpinBox->value()); if (!m_mainwindow->customThemeString().isEmpty()) diff --git a/ui/drivers/qt/viewoptionsdialog.h b/ui/drivers/qt/viewoptionsdialog.h index 7116a50f25..6f7afd6b2f 100644 --- a/ui/drivers/qt/viewoptionsdialog.h +++ b/ui/drivers/qt/viewoptionsdialog.h @@ -31,7 +31,6 @@ public slots: void saveViewOptions(); private slots: void onThemeComboBoxIndexChanged(int index); - void onThumbnailComboBoxIndexChanged(int index); void onHighlightColorChoose(); private: void showOrHideHighlightColor(); @@ -43,7 +42,6 @@ private: QCheckBox *m_saveLastTabCheckBox; QCheckBox *m_showHiddenFilesCheckBox; QComboBox *m_themeComboBox; - QComboBox *m_thumbnailComboBox; QSpinBox *m_thumbnailCacheSpinBox; QComboBox *m_startupPlaylistComboBox; QPushButton *m_highlightColorPushButton; diff --git a/ui/drivers/ui_qt.h b/ui/drivers/ui_qt.h index c7183c3397..d0f1e8e919 100644 --- a/ui/drivers/ui_qt.h +++ b/ui/drivers/ui_qt.h @@ -447,6 +447,9 @@ public slots: void showWelcomeScreen(); void onIconViewClicked(); void onListViewClicked(); + void onBoxartThumbnailClicked(); + void onScreenshotThumbnailClicked(); + void onTitleThumbnailClicked(); void onTabWidgetIndexChanged(int index); void deleteCurrentPlaylistItem(); void onFileDropWidgetContextMenuRequested(const QPoint &pos); From e7373a9cc2b593c2e68d7d5af56ea11e0985d2c0 Mon Sep 17 00:00:00 2001 From: Tatsuya79 Date: Tue, 2 Apr 2019 01:49:30 +0200 Subject: [PATCH 103/237] dark theme pushbutton indicator fix --- ui/drivers/qt/ui_qt_themes.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ui/drivers/qt/ui_qt_themes.h b/ui/drivers/qt/ui_qt_themes.h index 95b8ad0da7..c72531e39a 100644 --- a/ui/drivers/qt/ui_qt_themes.h +++ b/ui/drivers/qt/ui_qt_themes.h @@ -326,6 +326,11 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( QPushButton[flat="true"] { background-color:transparent; } + QPushButton[flat="true"]::menu-indicator { + position:relative; + bottom:4px; + right:4px; + } QRadioButton::indicator { width:18px; height:18px; From 9739b181bfc380cc797b0d06ca856a8f4e9a67ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Tue, 2 Apr 2019 08:47:35 -0500 Subject: [PATCH 104/237] Update record_ffmpeg.c small fix in recording presets --- record/drivers/record_ffmpeg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/record/drivers/record_ffmpeg.c b/record/drivers/record_ffmpeg.c index 851c0975fb..56a8a6bfa2 100644 --- a/record/drivers/record_ffmpeg.c +++ b/record/drivers/record_ffmpeg.c @@ -703,7 +703,7 @@ static bool ffmpeg_init_config_common(struct ff_config_param *params, unsigned p params->scale_factor = 1; strlcpy(params->format, "webm", sizeof(params->format)); } - else if (preset <= RECORD_CONFIG_TYPE_STREAMING_LOW_QUALITY) + else if (preset < RECORD_CONFIG_TYPE_STREAMING_LOW_QUALITY) { params->scale_factor = 1; strlcpy(params->format, "gif", sizeof(params->format)); From 052137b027e47fd20739f1653dae52141c1e73de Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 3 Apr 2019 13:31:45 +0200 Subject: [PATCH 105/237] (OSX) Silence warnings --- libretro-common/features/features_cpu.c | 5 ++++- menu/drivers/ozone/ozone.c | 3 --- menu/menu_displaylist.c | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libretro-common/features/features_cpu.c b/libretro-common/features/features_cpu.c index 7b3283f124..443f4187c2 100644 --- a/libretro-common/features/features_cpu.c +++ b/libretro-common/features/features_cpu.c @@ -877,7 +877,10 @@ end: #elif defined(__MACH__) if (!name) return; - sysctlbyname("machdep.cpu.brand_string", name, &len, NULL, 0); + { + size_t len_size = len; + sysctlbyname("machdep.cpu.brand_string", name, &len_size, NULL, 0); + } #else if (!name) return; diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index 3ac69a399c..e1b68f5a18 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -371,7 +371,6 @@ unsigned ozone_count_lines(const char *str) static void ozone_update_thumbnail_path(void *data, unsigned i, char pos) { - settings_t *settings = config_get_ptr(); ozone_handle_t *ozone = (ozone_handle_t*)data; const char *core_name = NULL; @@ -2169,8 +2168,6 @@ static int ozone_pointer_tap(void *userdata, menu_file_list_cbs_t *cbs, menu_entry_t *entry, unsigned action) { - ozone_handle_t *ozone = (ozone_handle_t*) userdata; - size_t selection = menu_navigation_get_selection(); if (ptr == selection && cbs && cbs->action_select) return (unsigned)menu_entry_action(entry, (unsigned)selection, MENU_ACTION_SELECT); diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 9ecf6a0bd4..092474c02e 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -1272,7 +1272,6 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, playlist_t *playlist, const char *path_playlist, bool is_collection) { unsigned i; - size_t selection = menu_navigation_get_selection(); size_t list_size = playlist_size(playlist); settings_t *settings = config_get_ptr(); bool is_rgui = string_is_equal(settings->arrays.menu_driver, "rgui"); From 637414c13865f134ea07403ae9b747c9620099ac Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 3 Apr 2019 14:37:06 +0200 Subject: [PATCH 106/237] (CoreAudio3) Fix issues --- audio/drivers/coreaudio3.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/audio/drivers/coreaudio3.m b/audio/drivers/coreaudio3.m index 298dd3cb19..8802fe425d 100644 --- a/audio/drivers/coreaudio3.m +++ b/audio/drivers/coreaudio3.m @@ -377,6 +377,8 @@ audio_driver_t audio_coreaudio3 = { coreaudio3_free, coreaudio3_use_float, "coreaudio3", + NULL, /* device_list_new */ + NULL, /* device_list_free */ coreaudio3_write_avail, coreaudio3_buffer_size, }; From e0aa224575fe166272e23996167ba05f142c8f97 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 3 Apr 2019 14:48:18 +0200 Subject: [PATCH 107/237] (CoreAudio3) some cleanups --- audio/drivers/coreaudio3.m | 54 ++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/audio/drivers/coreaudio3.m b/audio/drivers/coreaudio3.m index 8802fe425d..408d080385 100644 --- a/audio/drivers/coreaudio3.m +++ b/audio/drivers/coreaudio3.m @@ -115,9 +115,10 @@ static void rb_write_data(ringbuffer_h r, const float *data, size_t len) rb_len_add(r, (int)n); } -static void rb_read_data(ringbuffer_h r, float *d0, float *d1, size_t len) +static void rb_read_data(ringbuffer_h r, + float *d0, float *d1, size_t len) { - size_t need = len*2; + size_t need = len * 2; do { size_t have = rb_len(r); @@ -136,13 +137,15 @@ static void rb_read_data(ringbuffer_h r, float *d0, float *d1, size_t len) if (UNLIKELY(need > 0)) { + const float quiet = 0.0f; + size_t fill; + /* we got more data */ if (rb_len(r) > 0) continue; - // underflow - const float quiet = 0.0f; - size_t fill = (need/2)*sizeof(float); + /* underflow */ + fill = (need/2)*sizeof(float); memset_pattern4(&d0[i], &quiet, fill); memset_pattern4(&d1[i], &quiet, fill); } @@ -180,35 +183,38 @@ static bool g_interrupted; latency:(NSUInteger)latency { if (self = [super init]) { - _sema = dispatch_semaphore_create(0); + NSError *err; + AUAudioUnit *au; + AudioComponentDescription desc; + AVAudioFormat *format, *renderFormat; - _bufferSize = (latency * rate) / 1000; - _bufferSize *= 2; // stereo + _sema = dispatch_semaphore_create(0); + + _bufferSize = (latency * rate) / 1000; + _bufferSize *= 2; /* stereo */ rb_init(&_rb, _bufferSize); - AudioComponentDescription desc = { - .componentType = kAudioUnitType_Output, - .componentSubType = kAudioUnitSubType_DefaultOutput, - .componentManufacturer = kAudioUnitManufacturer_Apple, - }; + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_DefaultOutput; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; - NSError *err; - AUAudioUnit *au = [[AUAudioUnit alloc] initWithComponentDescription:desc error:&err]; + au = [[AUAudioUnit alloc] initWithComponentDescription:desc error:&err]; if (err != nil) return nil; - AVAudioFormat *format = au.outputBusses[0].format; + format = au.outputBusses[0].format; if (format.channelCount != 2) return nil; - AVAudioFormat *renderFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:rate channels:2]; + renderFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:rate channels:2]; [au.inputBusses[0] setFormat:renderFormat error:&err]; if (err != nil) return nil; ringbuffer_h rb = &_rb; __block dispatch_semaphore_t sema = _sema; - au.outputProvider = ^AUAudioUnitStatus(AudioUnitRenderActionFlags * actionFlags, const AudioTimeStamp * timestamp, AUAudioFrameCount frameCount, NSInteger inputBusNumber, AudioBufferList * inputData) { + au.outputProvider = ^AUAudioUnitStatus(AudioUnitRenderActionFlags * actionFlags, const AudioTimeStamp * timestamp, AUAudioFrameCount frameCount, NSInteger inputBusNumber, AudioBufferList * inputData) + { rb_read_data(rb, inputData->mBuffers[0].mData, inputData->mBuffers[1].mData, frameCount); dispatch_semaphore_signal(sema); return 0; @@ -288,9 +294,9 @@ static void coreaudio3_free(void *data) } static void *coreaudio3_init(const char *device, - unsigned rate, unsigned latency, - unsigned block_frames, - unsigned *new_rate) + unsigned rate, unsigned latency, + unsigned block_frames, + unsigned *new_rate) { CoreAudio3 *dev = [[CoreAudio3 alloc] initWithRate:rate latency:latency]; @@ -300,10 +306,12 @@ static void *coreaudio3_init(const char *device, return (__bridge_retained void *)dev; } -static ssize_t coreaudio3_write(void *data, const void *buf_, size_t size) +static ssize_t coreaudio3_write(void *data, + const void *buf_, size_t size) { CoreAudio3 *dev = (__bridge CoreAudio3 *)data; - return [dev writeFloat:(const float *)buf_ samples:size/sizeof(float)] * sizeof(float); + return [dev writeFloat:(const float *) + buf_ samples:size/sizeof(float)] * sizeof(float); } static void coreaudio3_set_nonblock_state(void *data, bool state) From be7b845b6ce5325ced63eb50d6f259d737644418 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 3 Apr 2019 14:52:20 +0200 Subject: [PATCH 108/237] Silence warning --- menu/menu_thumbnail_path.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menu/menu_thumbnail_path.h b/menu/menu_thumbnail_path.h index bc98cbcb02..8ff215d382 100644 --- a/menu/menu_thumbnail_path.h +++ b/menu/menu_thumbnail_path.h @@ -56,7 +56,7 @@ typedef struct menu_thumbnail_path_data menu_thumbnail_path_data_t; * Returns handle to new menu_thumbnail_path_data_t object. * on success, otherwise NULL. * Note: Returned object must be free()d */ -menu_thumbnail_path_data_t *menu_thumbnail_path_init(); +menu_thumbnail_path_data_t *menu_thumbnail_path_init(void); /* Resets thumbnail path data * (blanks all internal string containers) */ From 25ba8f4ab08001ef7bd475d74ab008411bf23765 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 3 Apr 2019 16:13:01 +0200 Subject: [PATCH 109/237] (GL1) GL1.x won't have mipmapping support --- gfx/drivers/gl1.c | 49 ++--------------------------------------------- 1 file changed, 2 insertions(+), 47 deletions(-) diff --git a/gfx/drivers/gl1.c b/gfx/drivers/gl1.c index 5da24e03b5..7f2cf6ac50 100644 --- a/gfx/drivers/gl1.c +++ b/gfx/drivers/gl1.c @@ -115,10 +115,6 @@ static unsigned get_pot(unsigned x) return (is_pot(x) ? x : next_pow2(x)); } -static void gl1_gfx_create(void) -{ -} - static void *gl1_gfx_init(const video_info_t *video, const input_driver_t **input, void **input_data) { @@ -155,8 +151,6 @@ static void *gl1_gfx_init(const video_info_t *video, else gl1_video_pitch = video->width * 2; - gl1_gfx_create(); - ctx_driver = video_context_driver_init_first(gl1, settings->arrays.video_context_driver, GFX_CTX_OPENGL_API, 1, 1, false, &ctx_data); @@ -1068,33 +1062,15 @@ static void gl1_load_texture_data( bool rgb32 = (base_size == (sizeof(uint32_t))); GLenum wrap = gl1_wrap_type_to_enum(wrap_type); - /* Assume no mipmapping support. */ + /* GL1.x does not have mipmapping support. */ switch (filter_type) { - case TEXTURE_FILTER_MIPMAP_LINEAR: - filter_type = TEXTURE_FILTER_LINEAR; - break; case TEXTURE_FILTER_MIPMAP_NEAREST: - filter_type = TEXTURE_FILTER_NEAREST; - break; - default: - break; - } - - switch (filter_type) - { - case TEXTURE_FILTER_MIPMAP_LINEAR: - min_filter = GL_LINEAR_MIPMAP_NEAREST; - mag_filter = GL_LINEAR; - break; - case TEXTURE_FILTER_MIPMAP_NEAREST: - min_filter = GL_NEAREST_MIPMAP_NEAREST; - mag_filter = GL_NEAREST; - break; case TEXTURE_FILTER_NEAREST: min_filter = GL_NEAREST; mag_filter = GL_NEAREST; break; + case TEXTURE_FILTER_MIPMAP_LINEAR: case TEXTURE_FILTER_LINEAR: default: min_filter = GL_LINEAR; @@ -1129,17 +1105,6 @@ static void video_texture_load_gl1( } #ifdef HAVE_THREADS -static int video_texture_load_wrap_gl1_mipmap(void *data) -{ - uintptr_t id = 0; - - if (!data) - return 0; - video_texture_load_gl1((struct texture_image*)data, - TEXTURE_FILTER_MIPMAP_NEAREST, &id); - return (int)id; -} - static int video_texture_load_wrap_gl1(void *data) { uintptr_t id = 0; @@ -1161,16 +1126,6 @@ static uintptr_t gl1_load_texture(void *video_data, void *data, if (threaded) { custom_command_method_t func = video_texture_load_wrap_gl1; - - switch (filter_type) - { - case TEXTURE_FILTER_MIPMAP_LINEAR: - case TEXTURE_FILTER_MIPMAP_NEAREST: - func = video_texture_load_wrap_gl1_mipmap; - break; - default: - break; - } return video_thread_texture_load(data, func); } #endif From ab33d16da148d1817e5936011c43f90853e5da58 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 3 Apr 2019 16:33:16 +0200 Subject: [PATCH 110/237] Small cleanup --- gfx/drivers/gl.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 2b8c725ebe..e1484a7e0e 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -351,18 +351,20 @@ static void gl2_load_texture_image(GLenum target, { #if !defined(HAVE_PSGL) && !defined(ORBIS) #ifdef HAVE_OPENGLES2 - if (gl_check_capability(GL_CAPS_TEX_STORAGE_EXT) && internalFormat != GL_BGRA_EXT) - { - gl2_size_format(&internalFormat); - glTexStorage2DEXT(target, 1, internalFormat, width, height); - } + unsigned cap = GL_CAPS_TEX_STORAGE_EXT; #else - if (gl_check_capability(GL_CAPS_TEX_STORAGE) && internalFormat != GL_BGRA_EXT) + unsigned cap = GL_CAPS_TEX_STORAGE; +#endif + + if (gl_check_capability(cap) && internalFormat != GL_BGRA_EXT) { gl2_size_format(&internalFormat); - glTexStorage2D(target, 1, internalFormat, width, height); - } +#ifdef HAVE_OPENGLES2 + glTexStorage2DEXT(target, 1, internalFormat, width, height); +#else + glTexStorage2D (target, 1, internalFormat, width, height); #endif + } else #endif { From ae12c30285af44bc89900fcdd0cbe9e341417e91 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Wed, 3 Apr 2019 10:40:38 -0400 Subject: [PATCH 111/237] strcmp will always be faster --- libretro-common/include/string/stdstring.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libretro-common/include/string/stdstring.h b/libretro-common/include/string/stdstring.h index 3d278d7cf2..3cf5e7c298 100644 --- a/libretro-common/include/string/stdstring.h +++ b/libretro-common/include/string/stdstring.h @@ -44,12 +44,7 @@ static INLINE bool string_is_equal(const char *a, const char *b) { if (!a || !b) return false; - while(*a && (*a == *b)) - { - a++; - b++; - } - return (*(const unsigned char*)a - *(const unsigned char*)b) == 0; + return strcmp(a, b) == 0; } static INLINE bool string_is_not_equal(const char *a, const char *b) From a5aa4d731b9080269eeef035f8c4ef7a9538b2e4 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 3 Apr 2019 16:56:50 +0200 Subject: [PATCH 112/237] Use memset instead of bzero --- audio/drivers/coreaudio3.m | 2 +- gfx/common/metal/Context.m | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/audio/drivers/coreaudio3.m b/audio/drivers/coreaudio3.m index 408d080385..176024411b 100644 --- a/audio/drivers/coreaudio3.m +++ b/audio/drivers/coreaudio3.m @@ -89,7 +89,7 @@ static void rb_init(ringbuffer_h r, size_t cap) static void rb_free(ringbuffer_h r) { free(r->buffer); - bzero(r, sizeof(*r)); + memset(r, 0, sizeof(*r)); } #define UNLIKELY(x) __builtin_expect((x), 0) diff --git a/gfx/common/metal/Context.m b/gfx/common/metal/Context.m index a16d486860..1cef6ec0a7 100644 --- a/gfx/common/metal/Context.m +++ b/gfx/common/metal/Context.m @@ -744,12 +744,14 @@ static const NSUInteger kConstantAlignment = 4; - (bool)allocRange:(BufferRange *)range length:(NSUInteger)length { - bzero(range, sizeof(*range)); + MTLResourceOptions opts; + + memset(range, 0, sizeof(*range)); #if TARGET_OS_OSX - MTLResourceOptions opts = MTLResourceStorageModeManaged; + opts = MTLResourceStorageModeManaged; #else - MTLResourceOptions opts = MTLResourceStorageModeShared; + opts = MTLResourceStorageModeShared; #endif if (!_head) From c8b9b4ef2586c6669d4ef872bb9fc5055060beae Mon Sep 17 00:00:00 2001 From: bparker06 Date: Wed, 3 Apr 2019 12:06:31 -0400 Subject: [PATCH 113/237] Update stdstring.h --- libretro-common/include/string/stdstring.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretro-common/include/string/stdstring.h b/libretro-common/include/string/stdstring.h index 3cf5e7c298..af07b01121 100644 --- a/libretro-common/include/string/stdstring.h +++ b/libretro-common/include/string/stdstring.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2019 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (stdstring.h). @@ -44,7 +44,7 @@ static INLINE bool string_is_equal(const char *a, const char *b) { if (!a || !b) return false; - return strcmp(a, b) == 0; + return !strcmp(a, b); } static INLINE bool string_is_not_equal(const char *a, const char *b) From ca56e0e91df9eb022488a174d84581cb1e97558c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 3 Apr 2019 22:48:08 +0200 Subject: [PATCH 114/237] Don't grab these two variables for every blit_line call --- menu/drivers/rgui.c | 133 +++++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 63 deletions(-) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 44a8649508..a543fa7867 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -1445,73 +1445,71 @@ static void prepare_rgui_colors(rgui_t *rgui, settings_t *settings) rgui->force_redraw = true; } -static void blit_line(int x, int y, - const char *message, uint16_t color, uint16_t shadow_color, bool draw_shadow) +static void rgui_blit_line( + size_t pitch, + const uint8_t *font_fb, + int x, int y, + const char *message, uint16_t color, + uint16_t shadow_color, bool draw_shadow) { - size_t pitch = menu_display_get_framebuffer_pitch(); - const uint8_t *font_fb = menu_display_get_font_framebuffer(); - - if (font_fb) + /* We're going to do some ugly loop unswitching here + * because rendering text is *very* expensive and I don't + * want to rely on the compiler to optimise this properly... */ + if (draw_shadow) { - /* We're going to do some ugly loop unswitching here - * because rendering text is *very* expensive and I don't - * want to rely on the compiler to optimise this properly... */ - if (draw_shadow) + /* Drop shadow version */ + while (!string_is_empty(message)) { - /* Drop shadow version */ - while (!string_is_empty(message)) + unsigned i, j; + char symbol = *message++; + + for (j = 0; j < FONT_HEIGHT; j++) { - unsigned i, j; - char symbol = *message++; - - for (j = 0; j < FONT_HEIGHT; j++) + for (i = 0; i < FONT_WIDTH; i++) { - for (i = 0; i < FONT_WIDTH; i++) + uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); + int offset = (i + j * FONT_WIDTH) >> 3; + + if ((font_fb[FONT_OFFSET(symbol) + offset] & rem) > 0) { - uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); - int offset = (i + j * FONT_WIDTH) >> 3; + unsigned pixel_x = x + i; + unsigned pixel_y = y + j; - if ((font_fb[FONT_OFFSET(symbol) + offset] & rem) > 0) - { - unsigned pixel_x = x + i; - unsigned pixel_y = y + j; + /* Text pixel */ + rgui_frame_buf.data[pixel_y * (pitch >> 1) + pixel_x] = color; - /* Text pixel */ - rgui_frame_buf.data[pixel_y * (pitch >> 1) + pixel_x] = color; - - /* Shadow pixels */ - rgui_frame_buf.data[(pixel_y + 1) * (pitch >> 1) + pixel_x ] = shadow_color; - rgui_frame_buf.data[ pixel_y * (pitch >> 1) + (pixel_x + 1)] = shadow_color; - rgui_frame_buf.data[(pixel_y + 1) * (pitch >> 1) + (pixel_x + 1)] = shadow_color; - } + /* Shadow pixels */ + rgui_frame_buf.data[(pixel_y + 1) * (pitch >> 1) + pixel_x ] = shadow_color; + rgui_frame_buf.data[ pixel_y * (pitch >> 1) + (pixel_x + 1)] = shadow_color; + rgui_frame_buf.data[(pixel_y + 1) * (pitch >> 1) + (pixel_x + 1)] = shadow_color; } } - - x += FONT_WIDTH_STRIDE; } + + x += FONT_WIDTH_STRIDE; } - else + } + else + { + /* Normal version */ + while (!string_is_empty(message)) { - /* Normal version */ - while (!string_is_empty(message)) + unsigned i, j; + char symbol = *message++; + + for (j = 0; j < FONT_HEIGHT; j++) { - unsigned i, j; - char symbol = *message++; - - for (j = 0; j < FONT_HEIGHT; j++) + for (i = 0; i < FONT_WIDTH; i++) { - for (i = 0; i < FONT_WIDTH; i++) - { - uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); - int offset = (i + j * FONT_WIDTH) >> 3; + uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); + int offset = (i + j * FONT_WIDTH) >> 3; - if ((font_fb[FONT_OFFSET(symbol) + offset] & rem) > 0) - rgui_frame_buf.data[(y + j) * (pitch >> 1) + (x + i)] = color; - } + if ((font_fb[FONT_OFFSET(symbol) + offset] & rem) > 0) + rgui_frame_buf.data[(y + j) * (pitch >> 1) + (x + i)] = color; } - - x += FONT_WIDTH_STRIDE; } + + x += FONT_WIDTH_STRIDE; } } } @@ -1662,7 +1660,8 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) unsigned width, glyphs_width, height; struct string_list *list = NULL; settings_t *settings = config_get_ptr(); - + size_t pitch = menu_display_get_framebuffer_pitch(); + const uint8_t *font_fb = menu_display_get_font_framebuffer(); (void)settings; if (!message || !*message) @@ -1744,15 +1743,18 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) } } - for (i = 0; i < list->size; i++) + if (rgui_frame_buf.data) { - const char *msg = list->elems[i].data; - int offset_x = (int)(FONT_WIDTH_STRIDE * (glyphs_width - utf8len(msg)) / 2); - int offset_y = (int)(FONT_HEIGHT_STRIDE * i); + for (i = 0; i < list->size; i++) + { + const char *msg = list->elems[i].data; + int offset_x = (int)(FONT_WIDTH_STRIDE * (glyphs_width - utf8len(msg)) / 2); + int offset_y = (int)(FONT_HEIGHT_STRIDE * i); - if (rgui_frame_buf.data) - blit_line(x + 8 + offset_x, y + 8 + offset_y, msg, + rgui_blit_line(pitch, font_fb, + x + 8 + offset_x, y + 8 + offset_y, msg, rgui->colors.normal_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); + } } end: @@ -1788,6 +1790,8 @@ static void rgui_render(void *data, bool is_idle) bool msg_force = false; settings_t *settings = config_get_ptr(); rgui_t *rgui = (rgui_t*)data; + size_t pitch = menu_display_get_framebuffer_pitch(); + const uint8_t *font_fb = menu_display_get_font_framebuffer(); static bool display_kb = false; bool current_display_cb = false; @@ -1951,8 +1955,10 @@ static void rgui_render(void *data, bool is_idle) title_x - 5, 0, title_width + 10, FONT_HEIGHT_STRIDE, rgui_bg_filler); /* Draw thumbnail title */ - blit_line((int)title_x, 0, thumbnail_title_buf, - rgui->colors.hover_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); + if (font_fb) + rgui_blit_line(pitch, font_fb, + (int)title_x, 0, thumbnail_title_buf, + rgui->colors.hover_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); } } } @@ -2006,7 +2012,7 @@ static void rgui_render(void *data, bool is_idle) string_to_upper(title_buf); if (rgui_frame_buf.data) - blit_line( + rgui_blit_line(pitch, font_fb, (int)(RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) - utf8len(title_buf)) * FONT_WIDTH_STRIDE / 2), RGUI_TERM_START_Y(fb_height) - FONT_HEIGHT_STRIDE, @@ -2150,7 +2156,8 @@ static void rgui_render(void *data, bool is_idle) } if (rgui_frame_buf.data) - blit_line(x, y, message, + rgui_blit_line(pitch, font_fb, + x, y, message, entry_selected ? rgui->colors.hover_color : rgui->colors.normal_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); @@ -2182,7 +2189,7 @@ static void rgui_render(void *data, bool is_idle) menu_animation_ticker(&ticker); if (rgui_frame_buf.data) - blit_line( + rgui_blit_line(pitch, font_fb, RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, sublabel_buf, @@ -2204,7 +2211,7 @@ static void rgui_render(void *data, bool is_idle) menu_animation_ticker(&ticker); if (rgui_frame_buf.data) - blit_line( + rgui_blit_line(pitch, font_fb, RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, core_title_buf, @@ -2227,7 +2234,7 @@ static void rgui_render(void *data, bool is_idle) menu_display_timedate(&datetime); if (rgui_frame_buf.data) - blit_line( + rgui_blit_line(pitch, font_fb, timedate_x, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, timedate, From 1a3ec1c3be85df8262a2aa9b4460c0545491ca5c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 3 Apr 2019 23:06:56 +0200 Subject: [PATCH 115/237] (RGUI) Move menu_display_font_framebuffer to rgui.c --- menu/drivers/rgui.c | 14 ++++++++------ menu/menu_driver.c | 11 ----------- menu/menu_driver.h | 2 -- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index a543fa7867..f2b7a36b0c 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -499,9 +499,11 @@ typedef struct struct scaler_ctx image_scaler; } rgui_t; -static unsigned mini_thumbnail_max_width = 0; +static unsigned mini_thumbnail_max_width = 0; static unsigned mini_thumbnail_max_height = 0; +static const uint8_t *rgui_font_framebuf = NULL; + typedef struct { unsigned max_width; @@ -1559,7 +1561,7 @@ static bool init_font(menu_handle_t *menu, const uint8_t *font_bmp_buf) font_bmp_buf + 54 + 3 * (256 * (255 - 16 * y) + 16 * x)); } - menu_display_set_font_framebuffer(font); + rgui_font_framebuf = font; return true; } @@ -1580,7 +1582,7 @@ static bool rguidisp_init_font(menu_handle_t *menu) return init_font(menu, font_bmp_buf); #endif - menu_display_set_font_framebuffer(font_bin_buf); + rgui_font_framebuf = font_bin_buf; return true; } @@ -1661,7 +1663,7 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) struct string_list *list = NULL; settings_t *settings = config_get_ptr(); size_t pitch = menu_display_get_framebuffer_pitch(); - const uint8_t *font_fb = menu_display_get_font_framebuffer(); + const uint8_t *font_fb = rgui_font_framebuf; (void)settings; if (!message || !*message) @@ -1791,7 +1793,7 @@ static void rgui_render(void *data, bool is_idle) settings_t *settings = config_get_ptr(); rgui_t *rgui = (rgui_t*)data; size_t pitch = menu_display_get_framebuffer_pitch(); - const uint8_t *font_fb = menu_display_get_font_framebuffer(); + const uint8_t *font_fb = rgui_font_framebuf; static bool display_kb = false; bool current_display_cb = false; @@ -2659,7 +2661,7 @@ static void rgui_free(void *data) } fb_font_inited = menu_display_get_font_data_init(); - font_fb = menu_display_get_font_framebuffer(); + font_fb = rgui_font_framebuf; if (fb_font_inited) free((void*)font_fb); diff --git a/menu/menu_driver.c b/menu/menu_driver.c index cddec7f9da..576941ce01 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -183,7 +183,6 @@ static bool menu_display_has_windowed = false; static bool menu_display_msg_force = false; static bool menu_display_font_alloc_framebuf = false; static bool menu_display_framebuf_dirty = false; -static const uint8_t *menu_display_font_framebuf = NULL; static menu_display_ctx_driver_t *menu_disp = NULL; /* when enabled, on next iteration the 'Quick Menu' list will @@ -502,16 +501,6 @@ video_coord_array_t *menu_display_get_coords_array(void) return &menu_disp_ca; } -const uint8_t *menu_display_get_font_framebuffer(void) -{ - return menu_display_font_framebuf; -} - -void menu_display_set_font_framebuffer(const uint8_t *buffer) -{ - menu_display_font_framebuf = buffer; -} - bool menu_display_libretro_running( bool rarch_is_inited, bool rarch_is_dummy_core) diff --git a/menu/menu_driver.h b/menu/menu_driver.h index 5136230194..4ce4624bf0 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -549,8 +549,6 @@ void menu_display_font_free(font_data_t *font); void menu_display_coords_array_reset(void); video_coord_array_t *menu_display_get_coords_array(void); -const uint8_t *menu_display_get_font_framebuffer(void); -void menu_display_set_font_framebuffer(const uint8_t *buffer); bool menu_display_libretro(bool is_idle, bool is_inited, bool is_dummy); bool menu_display_libretro_running(bool rarch_is_inited, bool rarch_is_dummy_core); From d7d260556b76d67106886e7012b8e33147cd7b6c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 4 Apr 2019 17:51:58 +0200 Subject: [PATCH 116/237] Revert "(RGUI) Move menu_display_font_framebuffer to rgui.c" This reverts commit 1a3ec1c3be85df8262a2aa9b4460c0545491ca5c. --- menu/drivers/rgui.c | 14 ++++++-------- menu/menu_driver.c | 11 +++++++++++ menu/menu_driver.h | 2 ++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index f2b7a36b0c..a543fa7867 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -499,11 +499,9 @@ typedef struct struct scaler_ctx image_scaler; } rgui_t; -static unsigned mini_thumbnail_max_width = 0; +static unsigned mini_thumbnail_max_width = 0; static unsigned mini_thumbnail_max_height = 0; -static const uint8_t *rgui_font_framebuf = NULL; - typedef struct { unsigned max_width; @@ -1561,7 +1559,7 @@ static bool init_font(menu_handle_t *menu, const uint8_t *font_bmp_buf) font_bmp_buf + 54 + 3 * (256 * (255 - 16 * y) + 16 * x)); } - rgui_font_framebuf = font; + menu_display_set_font_framebuffer(font); return true; } @@ -1582,7 +1580,7 @@ static bool rguidisp_init_font(menu_handle_t *menu) return init_font(menu, font_bmp_buf); #endif - rgui_font_framebuf = font_bin_buf; + menu_display_set_font_framebuffer(font_bin_buf); return true; } @@ -1663,7 +1661,7 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) struct string_list *list = NULL; settings_t *settings = config_get_ptr(); size_t pitch = menu_display_get_framebuffer_pitch(); - const uint8_t *font_fb = rgui_font_framebuf; + const uint8_t *font_fb = menu_display_get_font_framebuffer(); (void)settings; if (!message || !*message) @@ -1793,7 +1791,7 @@ static void rgui_render(void *data, bool is_idle) settings_t *settings = config_get_ptr(); rgui_t *rgui = (rgui_t*)data; size_t pitch = menu_display_get_framebuffer_pitch(); - const uint8_t *font_fb = rgui_font_framebuf; + const uint8_t *font_fb = menu_display_get_font_framebuffer(); static bool display_kb = false; bool current_display_cb = false; @@ -2661,7 +2659,7 @@ static void rgui_free(void *data) } fb_font_inited = menu_display_get_font_data_init(); - font_fb = rgui_font_framebuf; + font_fb = menu_display_get_font_framebuffer(); if (fb_font_inited) free((void*)font_fb); diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 576941ce01..cddec7f9da 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -183,6 +183,7 @@ static bool menu_display_has_windowed = false; static bool menu_display_msg_force = false; static bool menu_display_font_alloc_framebuf = false; static bool menu_display_framebuf_dirty = false; +static const uint8_t *menu_display_font_framebuf = NULL; static menu_display_ctx_driver_t *menu_disp = NULL; /* when enabled, on next iteration the 'Quick Menu' list will @@ -501,6 +502,16 @@ video_coord_array_t *menu_display_get_coords_array(void) return &menu_disp_ca; } +const uint8_t *menu_display_get_font_framebuffer(void) +{ + return menu_display_font_framebuf; +} + +void menu_display_set_font_framebuffer(const uint8_t *buffer) +{ + menu_display_font_framebuf = buffer; +} + bool menu_display_libretro_running( bool rarch_is_inited, bool rarch_is_dummy_core) diff --git a/menu/menu_driver.h b/menu/menu_driver.h index 4ce4624bf0..5136230194 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -549,6 +549,8 @@ void menu_display_font_free(font_data_t *font); void menu_display_coords_array_reset(void); video_coord_array_t *menu_display_get_coords_array(void); +const uint8_t *menu_display_get_font_framebuffer(void); +void menu_display_set_font_framebuffer(const uint8_t *buffer); bool menu_display_libretro(bool is_idle, bool is_inited, bool is_dummy); bool menu_display_libretro_running(bool rarch_is_inited, bool rarch_is_dummy_core); From 827802d883856cc5d5373578259e3d8ce8b8056c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 4 Apr 2019 18:32:08 +0200 Subject: [PATCH 117/237] Revert "Don't grab these two variables for every blit_line call" This reverts commit ca56e0e91df9eb022488a174d84581cb1e97558c. --- menu/drivers/rgui.c | 133 +++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 70 deletions(-) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index a543fa7867..44a8649508 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -1445,71 +1445,73 @@ static void prepare_rgui_colors(rgui_t *rgui, settings_t *settings) rgui->force_redraw = true; } -static void rgui_blit_line( - size_t pitch, - const uint8_t *font_fb, - int x, int y, - const char *message, uint16_t color, - uint16_t shadow_color, bool draw_shadow) +static void blit_line(int x, int y, + const char *message, uint16_t color, uint16_t shadow_color, bool draw_shadow) { - /* We're going to do some ugly loop unswitching here - * because rendering text is *very* expensive and I don't - * want to rely on the compiler to optimise this properly... */ - if (draw_shadow) + size_t pitch = menu_display_get_framebuffer_pitch(); + const uint8_t *font_fb = menu_display_get_font_framebuffer(); + + if (font_fb) { - /* Drop shadow version */ - while (!string_is_empty(message)) + /* We're going to do some ugly loop unswitching here + * because rendering text is *very* expensive and I don't + * want to rely on the compiler to optimise this properly... */ + if (draw_shadow) { - unsigned i, j; - char symbol = *message++; - - for (j = 0; j < FONT_HEIGHT; j++) + /* Drop shadow version */ + while (!string_is_empty(message)) { - for (i = 0; i < FONT_WIDTH; i++) + unsigned i, j; + char symbol = *message++; + + for (j = 0; j < FONT_HEIGHT; j++) { - uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); - int offset = (i + j * FONT_WIDTH) >> 3; - - if ((font_fb[FONT_OFFSET(symbol) + offset] & rem) > 0) + for (i = 0; i < FONT_WIDTH; i++) { - unsigned pixel_x = x + i; - unsigned pixel_y = y + j; + uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); + int offset = (i + j * FONT_WIDTH) >> 3; - /* Text pixel */ - rgui_frame_buf.data[pixel_y * (pitch >> 1) + pixel_x] = color; + if ((font_fb[FONT_OFFSET(symbol) + offset] & rem) > 0) + { + unsigned pixel_x = x + i; + unsigned pixel_y = y + j; - /* Shadow pixels */ - rgui_frame_buf.data[(pixel_y + 1) * (pitch >> 1) + pixel_x ] = shadow_color; - rgui_frame_buf.data[ pixel_y * (pitch >> 1) + (pixel_x + 1)] = shadow_color; - rgui_frame_buf.data[(pixel_y + 1) * (pitch >> 1) + (pixel_x + 1)] = shadow_color; + /* Text pixel */ + rgui_frame_buf.data[pixel_y * (pitch >> 1) + pixel_x] = color; + + /* Shadow pixels */ + rgui_frame_buf.data[(pixel_y + 1) * (pitch >> 1) + pixel_x ] = shadow_color; + rgui_frame_buf.data[ pixel_y * (pitch >> 1) + (pixel_x + 1)] = shadow_color; + rgui_frame_buf.data[(pixel_y + 1) * (pitch >> 1) + (pixel_x + 1)] = shadow_color; + } } } - } - x += FONT_WIDTH_STRIDE; + x += FONT_WIDTH_STRIDE; + } } - } - else - { - /* Normal version */ - while (!string_is_empty(message)) + else { - unsigned i, j; - char symbol = *message++; - - for (j = 0; j < FONT_HEIGHT; j++) + /* Normal version */ + while (!string_is_empty(message)) { - for (i = 0; i < FONT_WIDTH; i++) + unsigned i, j; + char symbol = *message++; + + for (j = 0; j < FONT_HEIGHT; j++) { - uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); - int offset = (i + j * FONT_WIDTH) >> 3; + for (i = 0; i < FONT_WIDTH; i++) + { + uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); + int offset = (i + j * FONT_WIDTH) >> 3; - if ((font_fb[FONT_OFFSET(symbol) + offset] & rem) > 0) - rgui_frame_buf.data[(y + j) * (pitch >> 1) + (x + i)] = color; + if ((font_fb[FONT_OFFSET(symbol) + offset] & rem) > 0) + rgui_frame_buf.data[(y + j) * (pitch >> 1) + (x + i)] = color; + } } - } - x += FONT_WIDTH_STRIDE; + x += FONT_WIDTH_STRIDE; + } } } } @@ -1660,8 +1662,7 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) unsigned width, glyphs_width, height; struct string_list *list = NULL; settings_t *settings = config_get_ptr(); - size_t pitch = menu_display_get_framebuffer_pitch(); - const uint8_t *font_fb = menu_display_get_font_framebuffer(); + (void)settings; if (!message || !*message) @@ -1743,18 +1744,15 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) } } - if (rgui_frame_buf.data) + for (i = 0; i < list->size; i++) { - for (i = 0; i < list->size; i++) - { - const char *msg = list->elems[i].data; - int offset_x = (int)(FONT_WIDTH_STRIDE * (glyphs_width - utf8len(msg)) / 2); - int offset_y = (int)(FONT_HEIGHT_STRIDE * i); + const char *msg = list->elems[i].data; + int offset_x = (int)(FONT_WIDTH_STRIDE * (glyphs_width - utf8len(msg)) / 2); + int offset_y = (int)(FONT_HEIGHT_STRIDE * i); - rgui_blit_line(pitch, font_fb, - x + 8 + offset_x, y + 8 + offset_y, msg, + if (rgui_frame_buf.data) + blit_line(x + 8 + offset_x, y + 8 + offset_y, msg, rgui->colors.normal_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); - } } end: @@ -1790,8 +1788,6 @@ static void rgui_render(void *data, bool is_idle) bool msg_force = false; settings_t *settings = config_get_ptr(); rgui_t *rgui = (rgui_t*)data; - size_t pitch = menu_display_get_framebuffer_pitch(); - const uint8_t *font_fb = menu_display_get_font_framebuffer(); static bool display_kb = false; bool current_display_cb = false; @@ -1955,10 +1951,8 @@ static void rgui_render(void *data, bool is_idle) title_x - 5, 0, title_width + 10, FONT_HEIGHT_STRIDE, rgui_bg_filler); /* Draw thumbnail title */ - if (font_fb) - rgui_blit_line(pitch, font_fb, - (int)title_x, 0, thumbnail_title_buf, - rgui->colors.hover_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); + blit_line((int)title_x, 0, thumbnail_title_buf, + rgui->colors.hover_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); } } } @@ -2012,7 +2006,7 @@ static void rgui_render(void *data, bool is_idle) string_to_upper(title_buf); if (rgui_frame_buf.data) - rgui_blit_line(pitch, font_fb, + blit_line( (int)(RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) - utf8len(title_buf)) * FONT_WIDTH_STRIDE / 2), RGUI_TERM_START_Y(fb_height) - FONT_HEIGHT_STRIDE, @@ -2156,8 +2150,7 @@ static void rgui_render(void *data, bool is_idle) } if (rgui_frame_buf.data) - rgui_blit_line(pitch, font_fb, - x, y, message, + blit_line(x, y, message, entry_selected ? rgui->colors.hover_color : rgui->colors.normal_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); @@ -2189,7 +2182,7 @@ static void rgui_render(void *data, bool is_idle) menu_animation_ticker(&ticker); if (rgui_frame_buf.data) - rgui_blit_line(pitch, font_fb, + blit_line( RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, sublabel_buf, @@ -2211,7 +2204,7 @@ static void rgui_render(void *data, bool is_idle) menu_animation_ticker(&ticker); if (rgui_frame_buf.data) - rgui_blit_line(pitch, font_fb, + blit_line( RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, core_title_buf, @@ -2234,7 +2227,7 @@ static void rgui_render(void *data, bool is_idle) menu_display_timedate(&datetime); if (rgui_frame_buf.data) - rgui_blit_line(pitch, font_fb, + blit_line( timedate_x, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, timedate, From b301e4d4443470ec9dc4a4838da5c8fb60a548a6 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 4 Apr 2019 16:17:35 +0100 Subject: [PATCH 118/237] (RGUI) Performance optimisations --- menu/drivers/rgui.c | 682 +++++++++++++++++++++----------------------- menu/menu_driver.c | 22 -- menu/menu_driver.h | 4 - 3 files changed, 321 insertions(+), 387 deletions(-) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 44a8649508..6a3b549030 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -476,6 +477,8 @@ typedef struct unsigned last_height; bool bg_thickness; bool border_thickness; + bool border_enable; + bool shadow_enable; float scroll_y; char *msgbox; unsigned color_theme; @@ -502,6 +505,8 @@ typedef struct static unsigned mini_thumbnail_max_width = 0; static unsigned mini_thumbnail_max_height = 0; +static bool font_lut[128][FONT_WIDTH * FONT_HEIGHT]; + typedef struct { unsigned max_width; @@ -543,19 +548,6 @@ static thumbnail_t mini_left_thumbnail = { NULL }; -typedef struct -{ - bool is_valid; - char *path; - uint16_t *data; -} wallpaper_t; - -static wallpaper_t wallpaper = { - false, - NULL, - NULL -}; - typedef struct { unsigned width; @@ -569,6 +561,12 @@ static frame_buf_t rgui_frame_buf = { NULL }; +static frame_buf_t rgui_background_buf = { + 0, + 0, + NULL +}; + static frame_buf_t rgui_upscale_buf = { 0, 0, @@ -686,14 +684,14 @@ static uint16_t argb32_to_rgba4444(uint32_t col) #endif -static uint16_t rgui_bg_filler(rgui_t *rgui, unsigned x, unsigned y) +static uint16_t INLINE rgui_bg_filler(rgui_t *rgui, unsigned x, unsigned y) { unsigned shift = (rgui->bg_thickness ? 1 : 0); unsigned select = ((x >> shift) + (y >> shift)) & 1; return (select == 0) ? rgui->colors.bg_dark_color : rgui->colors.bg_light_color; } -static uint16_t rgui_border_filler(rgui_t *rgui, unsigned x, unsigned y) +static uint16_t INLINE rgui_border_filler(rgui_t *rgui, unsigned x, unsigned y) { unsigned shift = (rgui->border_thickness ? 1 : 0); unsigned select = ((x >> shift) + (y >> shift)) & 1; @@ -731,35 +729,19 @@ static void rgui_color_rect( data[j * (pitch >> 1) + i] = color; } -static bool request_wallpaper(const char *path) +static void request_wallpaper(const char *path) { - /* Do nothing if current wallpaper path hasn't changed */ - if (!string_is_empty(path) && !string_is_empty(wallpaper.path)) - { - if (string_is_equal(wallpaper.path, path)) - return true; - } - - /* 'Reset' current wallpaper */ - wallpaper.is_valid = false; - free(wallpaper.path); - wallpaper.path = NULL; - - /* Ensure that new path is valid... */ + /* Ensure that path is valid... */ if (!string_is_empty(path)) { - wallpaper.path = strdup(path); if (filestream_exists(path)) { /* Unlike thumbnails, we don't worry about queued images * here - in general, wallpaper is loaded once per session * and then forgotten, so performance issues are not a concern */ - task_push_image_load(wallpaper.path, menu_display_handle_wallpaper_upload, NULL); - return true; + task_push_image_load(path, menu_display_handle_wallpaper_upload, NULL); } } - - return false; } static void process_wallpaper(rgui_t *rgui, struct texture_image *image) @@ -767,20 +749,23 @@ static void process_wallpaper(rgui_t *rgui, struct texture_image *image) unsigned x, y; /* Sanity check */ - if (!image->pixels || (image->width != rgui_frame_buf.width) || (image->height != rgui_frame_buf.height) || !wallpaper.data) + if (!image->pixels || + (image->width != rgui_background_buf.width) || + (image->height != rgui_background_buf.height) || + !rgui_background_buf.data) return; /* Copy image to wallpaper buffer, performing pixel format conversion */ - for (x = 0; x < rgui_frame_buf.width; x++) + for (x = 0; x < rgui_background_buf.width; x++) { - for (y = 0; y < rgui_frame_buf.height; y++) + for (y = 0; y < rgui_background_buf.height; y++) { - wallpaper.data[x + (y * rgui_frame_buf.width)] = - argb32_to_pixel_platform_format(image->pixels[x + (y * rgui_frame_buf.width)]); + rgui_background_buf.data[x + (y * rgui_background_buf.width)] = + argb32_to_pixel_platform_format(image->pixels[x + (y * rgui_background_buf.width)]); } } - wallpaper.is_valid = true; + rgui->show_wallpaper = true; /* Tell menu that a display update is required */ rgui->force_redraw = true; @@ -1024,43 +1009,37 @@ static bool rgui_load_image(void *userdata, void *data, enum menu_image_type typ return true; } -static bool rgui_render_wallpaper(void) +static void rgui_render_background(void) { size_t fb_pitch; unsigned fb_width, fb_height; - if (wallpaper.is_valid && rgui_frame_buf.data && wallpaper.data) + if (rgui_frame_buf.data && rgui_background_buf.data) { menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch); /* Sanity check */ if ((fb_width != rgui_frame_buf.width) || (fb_height != rgui_frame_buf.height) || (fb_pitch != rgui_frame_buf.width << 1)) - return false; + return; - /* Copy wallpaper to framebuffer */ - memcpy(rgui_frame_buf.data, wallpaper.data, rgui_frame_buf.width * rgui_frame_buf.height * sizeof(uint16_t)); - - return true; + /* Copy background to framebuffer */ + memcpy(rgui_frame_buf.data, rgui_background_buf.data, rgui_frame_buf.width * rgui_frame_buf.height * sizeof(uint16_t)); } - - return false; } static void rgui_render_fs_thumbnail(rgui_t *rgui) { - settings_t *settings = config_get_ptr(); - size_t fb_pitch; - unsigned fb_width, fb_height; - unsigned x, y; - unsigned fb_x_offset, fb_y_offset; - unsigned thumb_x_offset, thumb_y_offset; - unsigned width, height; - - if (!settings) - return; - if (fs_thumbnail.is_valid && rgui_frame_buf.data && fs_thumbnail.data) { + size_t fb_pitch; + unsigned fb_width, fb_height; + unsigned y; + unsigned fb_x_offset, fb_y_offset; + unsigned thumb_x_offset, thumb_y_offset; + unsigned width, height; + uint16_t *src = NULL; + uint16_t *dst = NULL; + menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch); /* Ensure that thumbnail is centred @@ -1096,15 +1075,14 @@ static void rgui_render_fs_thumbnail(rgui_t *rgui) /* Copy thumbnail to framebuffer */ for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) - { - rgui_frame_buf.data[(y + fb_y_offset) * (fb_pitch >> 1) + (x + fb_x_offset)] = - fs_thumbnail.data[(x + thumb_x_offset) + ((y + thumb_y_offset) * fs_thumbnail.width)]; - } + src = fs_thumbnail.data + thumb_x_offset + ((y + thumb_y_offset) * fs_thumbnail.width); + dst = rgui_frame_buf.data + (y + fb_y_offset) * (fb_pitch >> 1) + fb_x_offset; + + memcpy(dst, src, width * sizeof(uint16_t)); } /* Draw drop shadow, if required */ - if (settings->bools.menu_rgui_shadows) + if (rgui->shadow_enable) { unsigned shadow_x; unsigned shadow_y; @@ -1162,18 +1140,21 @@ static unsigned INLINE rgui_get_mini_thumbnail_fullwidth(void) static void rgui_render_mini_thumbnail(rgui_t *rgui, thumbnail_t *thumbnail, enum menu_thumbnail_id thumbnail_id) { settings_t *settings = config_get_ptr(); - size_t fb_pitch; - unsigned fb_width, fb_height; - unsigned term_width, term_height; - unsigned x, y; - unsigned fb_x_offset, fb_y_offset; - unsigned thumbnail_fullwidth = rgui_get_mini_thumbnail_fullwidth(); if (!thumbnail || !settings) return; if (thumbnail->is_valid && rgui_frame_buf.data && thumbnail->data) { + size_t fb_pitch; + unsigned fb_width, fb_height; + unsigned term_width, term_height; + unsigned y; + unsigned fb_x_offset, fb_y_offset; + unsigned thumbnail_fullwidth = rgui_get_mini_thumbnail_fullwidth(); + uint16_t *src = NULL; + uint16_t *dst = NULL; + menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch); term_width = RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE; @@ -1201,15 +1182,14 @@ static void rgui_render_mini_thumbnail(rgui_t *rgui, thumbnail_t *thumbnail, enu /* Copy thumbnail to framebuffer */ for (y = 0; y < thumbnail->height; y++) { - for (x = 0; x < thumbnail->width; x++) - { - rgui_frame_buf.data[(y + fb_y_offset) * (fb_pitch >> 1) + (x + fb_x_offset)] = - thumbnail->data[x + (y * thumbnail->width)]; - } + src = thumbnail->data + (y * thumbnail->width); + dst = rgui_frame_buf.data + (y + fb_y_offset) * (fb_pitch >> 1) + fb_x_offset; + + memcpy(dst, src, thumbnail->width * sizeof(uint16_t)); } /* Draw drop shadow, if required */ - if (settings->bools.menu_rgui_shadows) + if (rgui->shadow_enable) { rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, fb_x_offset + thumbnail->width, fb_y_offset + 1, 1, thumbnail->height, rgui->colors.shadow_color); @@ -1388,7 +1368,7 @@ end: wallpaper_path[0] = '\0'; fill_pathname_resolve_relative(wallpaper_path, theme_path, wallpaper_file, sizeof(wallpaper_path)); - rgui->show_wallpaper = request_wallpaper(wallpaper_path); + request_wallpaper(wallpaper_path); } } else @@ -1409,6 +1389,68 @@ end: conf = NULL; } +static void rgui_cache_background(rgui_t *rgui) +{ + size_t pitch_in_pixels, size; + size_t fb_pitch; + unsigned fb_width, fb_height; + uint16_t *src = NULL; + uint16_t *dst = NULL; + + /* Only regenerate the background if we are *not* + * currently showing a wallpaper image */ + if (rgui->show_wallpaper) + return; + + menu_display_get_fb_size(&fb_width, &fb_height, + &fb_pitch); + + /* Sanity check */ + if ((fb_width != rgui_background_buf.width) || + (fb_height != rgui_background_buf.height) || + (fb_pitch != rgui_background_buf.width << 1) || + !rgui_background_buf.data) + return; + + /* Fill last 4 lines of background buffer with standard + * chequer pattern */ + rgui_fill_rect(rgui, rgui_background_buf.data, fb_pitch, 0, fb_height, fb_width, 4, rgui_bg_filler); + + /* Copy chequer pattern to rest of background buffer */ + pitch_in_pixels = fb_pitch >> 1; + size = fb_pitch * 4; + src = rgui_background_buf.data + pitch_in_pixels * fb_height; + dst = rgui_background_buf.data; + + while (dst < src) + { + memcpy(dst, src, size); + dst += pitch_in_pixels * 4; + } + + if (rgui->border_enable) + { + /* Draw border */ + rgui_fill_rect(rgui, rgui_background_buf.data, fb_pitch, 5, 5, fb_width - 10, 5, rgui_border_filler); + rgui_fill_rect(rgui, rgui_background_buf.data, fb_pitch, 5, fb_height - 10, fb_width - 10, 5, rgui_border_filler); + rgui_fill_rect(rgui, rgui_background_buf.data, fb_pitch, 5, 5, 5, fb_height - 10, rgui_border_filler); + rgui_fill_rect(rgui, rgui_background_buf.data, fb_pitch, fb_width - 10, 5, 5, fb_height - 10, rgui_border_filler); + + /* Draw drop shadow, if required */ + if (rgui->shadow_enable) + { + rgui_color_rect(rgui_background_buf.data, fb_pitch, fb_width, fb_height, + 10, 10, 1, fb_height - 20, rgui->colors.shadow_color); + rgui_color_rect(rgui_background_buf.data, fb_pitch, fb_width, fb_height, + 10, 10, fb_width - 20, 1, rgui->colors.shadow_color); + rgui_color_rect(rgui_background_buf.data, fb_pitch, fb_width, fb_height, + fb_width - 5, 6, 1, fb_height - 10, rgui->colors.shadow_color); + rgui_color_rect(rgui_background_buf.data, fb_pitch, fb_width, fb_height, + 6, fb_height - 5, fb_width - 10, 1, rgui->colors.shadow_color); + } + } +} + static void prepare_rgui_colors(rgui_t *rgui, settings_t *settings) { rgui_theme_t theme_colors; @@ -1448,194 +1490,114 @@ static void prepare_rgui_colors(rgui_t *rgui, settings_t *settings) static void blit_line(int x, int y, const char *message, uint16_t color, uint16_t shadow_color, bool draw_shadow) { - size_t pitch = menu_display_get_framebuffer_pitch(); - const uint8_t *font_fb = menu_display_get_font_framebuffer(); + unsigned fb_width = rgui_frame_buf.width; + uint16_t *frame_buf_data = rgui_frame_buf.data; - if (font_fb) + /* Note: We can only display ASCII characters from 0-127. + * Everything else is rendered as garbage (incorrect glyphs + * from extended ASCII set). This is due to the fact that + * char arrays use a signed 8 bit data type [-128 to 127], + * so values greater than 127 are 'written' across multiple bytes. + * This is a UTF-8 encoding issue, and it's too difficult and + * too performance intensive to deal with here. + * Since drawing these multi-byte characters is a huge problem + * (we could end up with a string that exceeds the dimensions + * of the framebuffer, and get a segfault...) we shall + * skip drawing any character greater than 127 */ + + /* We're going to do some ugly loop unswitching here + * because rendering text is *very* expensive and I don't + * want to rely on the compiler to optimise this properly... */ + if (draw_shadow) { - /* We're going to do some ugly loop unswitching here - * because rendering text is *very* expensive and I don't - * want to rely on the compiler to optimise this properly... */ - if (draw_shadow) - { - /* Drop shadow version */ - while (!string_is_empty(message)) - { - unsigned i, j; - char symbol = *message++; + /* Small performance hack... */ + uint32_t shadow_colour_32 = shadow_color; + shadow_colour_32 |= shadow_colour_32 << 16; + /* Drop shadow version */ + while (!string_is_empty(message)) + { + unsigned i, j; + uint8_t symbol = (uint8_t)*message++; + + if (symbol > 127) + continue; + + if (symbol != ' ') + { for (j = 0; j < FONT_HEIGHT; j++) { + unsigned buff_offset = ((y + j) * fb_width) + x; + for (i = 0; i < FONT_WIDTH; i++) { - uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); - int offset = (i + j * FONT_WIDTH) >> 3; - - if ((font_fb[FONT_OFFSET(symbol) + offset] & rem) > 0) + if (font_lut[symbol][i + (j * FONT_WIDTH)]) { - unsigned pixel_x = x + i; - unsigned pixel_y = y + j; + uint16_t *frame_buf_ptr = frame_buf_data + buff_offset + i; /* Text pixel */ - rgui_frame_buf.data[pixel_y * (pitch >> 1) + pixel_x] = color; + *frame_buf_ptr = color; /* Shadow pixels */ - rgui_frame_buf.data[(pixel_y + 1) * (pitch >> 1) + pixel_x ] = shadow_color; - rgui_frame_buf.data[ pixel_y * (pitch >> 1) + (pixel_x + 1)] = shadow_color; - rgui_frame_buf.data[(pixel_y + 1) * (pitch >> 1) + (pixel_x + 1)] = shadow_color; + frame_buf_ptr++; + *frame_buf_ptr = shadow_color; + frame_buf_ptr += fb_width - 1; + /* Small performance hack... */ + *(uint32_t *)frame_buf_ptr = shadow_colour_32; } } } - - x += FONT_WIDTH_STRIDE; } - } - else - { - /* Normal version */ - while (!string_is_empty(message)) - { - unsigned i, j; - char symbol = *message++; + x += FONT_WIDTH_STRIDE; + } + } + else + { + /* Normal version */ + while (!string_is_empty(message)) + { + unsigned i, j; + uint8_t symbol = (uint8_t)*message++; + + if (symbol > 127) + continue; + + if (symbol != ' ') + { for (j = 0; j < FONT_HEIGHT; j++) { + unsigned buff_offset = ((y + j) * fb_width) + x; + for (i = 0; i < FONT_WIDTH; i++) { - uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); - int offset = (i + j * FONT_WIDTH) >> 3; - - if ((font_fb[FONT_OFFSET(symbol) + offset] & rem) > 0) - rgui_frame_buf.data[(y + j) * (pitch >> 1) + (x + i)] = color; + if (font_lut[symbol][i + (j * FONT_WIDTH)]) + *(frame_buf_data + buff_offset + i) = color; } } - - x += FONT_WIDTH_STRIDE; } + + x += FONT_WIDTH_STRIDE; } } } -#if 0 -static void rgui_copy_glyph(uint8_t *glyph, const uint8_t *buf) +static void rgui_init_font_lut(void) { - int x, y; - - if (!glyph) - return; - - for (y = 0; y < FONT_HEIGHT; y++) + unsigned symbol_index, i, j; + + /* Loop over all possible characters */ + for (symbol_index = 0; symbol_index < 128; symbol_index++) { - for (x = 0; x < FONT_WIDTH; x++) + for (j = 0; j < FONT_HEIGHT; j++) { - uint32_t col = - ((uint32_t)buf[3 * (-y * 256 + x) + 0] << 0) | - ((uint32_t)buf[3 * (-y * 256 + x) + 1] << 8) | - ((uint32_t)buf[3 * (-y * 256 + x) + 2] << 16); - - uint8_t rem = 1 << ((x + y * FONT_WIDTH) & 7); - unsigned offset = (x + y * FONT_WIDTH) >> 3; - - if (col != 0xff) - glyph[offset] |= rem; - } - } -} - -static bool init_font(menu_handle_t *menu, const uint8_t *font_bmp_buf) -{ - unsigned i; - bool fb_font_inited = true; - uint8_t *font = (uint8_t *)calloc(1, FONT_OFFSET(256)); - - if (!font) - return false; - - menu_display_set_font_data_init(fb_font_inited); - - for (i = 0; i < 256; i++) - { - unsigned y = i / 16; - unsigned x = i % 16; - rgui_copy_glyph(&font[FONT_OFFSET(i)], - font_bmp_buf + 54 + 3 * (256 * (255 - 16 * y) + 16 * x)); - } - - menu_display_set_font_framebuffer(font); - - return true; -} -#endif - -static bool rguidisp_init_font(menu_handle_t *menu) -{ -#if 0 - const uint8_t *font_bmp_buf = NULL; -#endif - const uint8_t *font_bin_buf = bitmap_bin; - - if (!menu) - return false; - -#if 0 - if (font_bmp_buf) - return init_font(menu, font_bmp_buf); -#endif - - menu_display_set_font_framebuffer(font_bin_buf); - - return true; -} - -static void rgui_render_background(rgui_t *rgui) -{ - size_t pitch_in_pixels, size; - size_t fb_pitch; - unsigned fb_width, fb_height; - uint16_t *src = NULL; - uint16_t *dst = NULL; - - menu_display_get_fb_size(&fb_width, &fb_height, - &fb_pitch); - - pitch_in_pixels = fb_pitch >> 1; - size = fb_pitch * 4; - src = rgui_frame_buf.data + pitch_in_pixels * fb_height; - dst = rgui_frame_buf.data; - - while (dst < src) - { - memcpy(dst, src, size); - dst += pitch_in_pixels * 4; - } - - /* Skip drawing border if we are currently showing a fullscreen thumbnail */ - if (!(rgui->show_fs_thumbnail && rgui->entry_has_thumbnail && (fs_thumbnail.is_valid || (rgui->thumbnail_queue_size > 0)))) - { - if (rgui_frame_buf.data) - { - settings_t *settings = config_get_ptr(); - - if (settings->bools.menu_rgui_border_filler_enable) + for (i = 0; i < FONT_WIDTH; i++) { - /* Draw border */ - rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, 5, 5, fb_width - 10, 5, rgui_border_filler); - rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, 5, fb_height - 10, fb_width - 10, 5, rgui_border_filler); - rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, 5, 5, 5, fb_height - 10, rgui_border_filler); - rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, fb_width - 10, 5, 5, fb_height - 10, rgui_border_filler); - - /* Draw drop shadow, if required */ - if (settings->bools.menu_rgui_shadows) - { - rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, - 10, 10, 1, fb_height - 20, rgui->colors.shadow_color); - rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, - 10, 10, fb_width - 20, 1, rgui->colors.shadow_color); - rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, - fb_width - 5, 6, 1, fb_height - 10, rgui->colors.shadow_color); - rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, - 6, fb_height - 5, fb_width - 10, 1, rgui->colors.shadow_color); - } + uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); + unsigned offset = (i + j * FONT_WIDTH) >> 3; + + /* LUT value is 'true' if specified glyph position contains a pixel */ + font_lut[symbol_index][i + (j * FONT_WIDTH)] = (bitmap_bin[FONT_OFFSET(symbol_index) + offset] & rem) > 0; } } } @@ -1661,9 +1623,6 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) unsigned fb_width, fb_height; unsigned width, glyphs_width, height; struct string_list *list = NULL; - settings_t *settings = config_get_ptr(); - - (void)settings; if (!message || !*message) return; @@ -1708,10 +1667,10 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) { rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x + 5, y + 5, width - 10, height - 10, rgui_bg_filler); - if (settings->bools.menu_rgui_border_filler_enable) + if (rgui->border_enable) { /* Draw drop shadow, if required */ - if (settings->bools.menu_rgui_shadows) + if (rgui->shadow_enable) { rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, x + 5, y + 5, 1, height - 5, rgui->colors.shadow_color); @@ -1729,7 +1688,7 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x + 5, y + height - 5, width - 5, 5, rgui_border_filler); rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x, y + 5, 5, height - 5, rgui_border_filler); } - else if (settings->bools.menu_rgui_shadows) + else if (rgui->shadow_enable) { /* Without a border, this is a bit silly... * All we can do is draw a sort of frame... */ @@ -1752,7 +1711,7 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) if (rgui_frame_buf.data) blit_line(x + 8 + offset_x, y + 8 + offset_y, msg, - rgui->colors.normal_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); + rgui->colors.normal_color, rgui->colors.shadow_color, rgui->shadow_enable); } end: @@ -1792,6 +1751,10 @@ static void rgui_render(void *data, bool is_idle) static bool display_kb = false; bool current_display_cb = false; + /* Sanity check */ + if (!rgui || !rgui_frame_buf.data || !settings) + return; + /* Apply pending aspect ratio update */ if (rgui->aspect_update_pending) { @@ -1821,10 +1784,7 @@ static void rgui_render(void *data, bool is_idle) /* if the framebuffer changed size, recache the background */ if (rgui->bg_modified || rgui->last_width != fb_width || rgui->last_height != fb_height) { - if (rgui_frame_buf.data) - { - rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, 0, fb_height, fb_width, 4, rgui_bg_filler); - } + rgui_cache_background(rgui); rgui->last_width = fb_width; rgui->last_height = fb_height; } @@ -1895,18 +1855,8 @@ static void rgui_render(void *data, bool is_idle) end = ((old_start + RGUI_TERM_HEIGHT(fb_height)) <= (entries_end)) ? old_start + RGUI_TERM_HEIGHT(fb_height) : entries_end; - /* Render wallpaper or 'normal' background */ - if (rgui->show_wallpaper && wallpaper.is_valid) - { - /* If rgui_render_wallpaper() fails (can't actually happen...) - * then use 'normal' background fallback */ - if (!rgui_render_wallpaper()) - rgui_render_background(rgui); - } - else - { - rgui_render_background(rgui); - } + /* Render background */ + rgui_render_background(); /* We use a single ticker for all text animations, * with the following configuration: */ @@ -1944,21 +1894,19 @@ static void rgui_render(void *data, bool is_idle) title_width = utf8len(thumbnail_title_buf) * FONT_WIDTH_STRIDE; title_x = RGUI_TERM_START_X(fb_width) + ((RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE) - title_width) / 2; - if (rgui_frame_buf.data) - { - /* Draw thumbnail title background */ - rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, - title_x - 5, 0, title_width + 10, FONT_HEIGHT_STRIDE, rgui_bg_filler); + /* Draw thumbnail title background */ + rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, + title_x - 5, 0, title_width + 10, FONT_HEIGHT_STRIDE, rgui_bg_filler); - /* Draw thumbnail title */ - blit_line((int)title_x, 0, thumbnail_title_buf, - rgui->colors.hover_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); - } + /* Draw thumbnail title */ + blit_line((int)title_x, 0, thumbnail_title_buf, + rgui->colors.hover_color, rgui->colors.shadow_color, rgui->shadow_enable); } } else { /* Render usual text */ + size_t selection = menu_navigation_get_selection(); char title_buf[255]; unsigned timedate_x = (RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE)) - (5 * FONT_WIDTH_STRIDE); @@ -2005,12 +1953,11 @@ static void rgui_render(void *data, bool is_idle) string_to_upper(title_buf); - if (rgui_frame_buf.data) - blit_line( - (int)(RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) - - utf8len(title_buf)) * FONT_WIDTH_STRIDE / 2), - RGUI_TERM_START_Y(fb_height) - FONT_HEIGHT_STRIDE, - title_buf, rgui->colors.title_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); + blit_line( + (int)(RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) + - utf8len(title_buf)) * FONT_WIDTH_STRIDE / 2), + RGUI_TERM_START_Y(fb_height) - FONT_HEIGHT_STRIDE, + title_buf, rgui->colors.title_color, rgui->colors.shadow_color, rgui->shadow_enable); /* Print menu entries */ x = RGUI_TERM_START_X(fb_width); @@ -2025,13 +1972,11 @@ static void rgui_render(void *data, bool is_idle) char entry_title_buf[255]; char type_str_buf[255]; menu_entry_t entry; - char *entry_path = NULL; size_t entry_title_max_len = 0; size_t entry_title_buf_utf8len = 0; size_t entry_title_buf_len = 0; unsigned entry_value_len = 0; - bool entry_selected = menu_entry_is_currently_selected((unsigned)i); - size_t selection = menu_navigation_get_selection(); + bool entry_selected = (i == selection); if (i > (selection + 100)) continue; @@ -2045,8 +1990,10 @@ static void rgui_render(void *data, bool is_idle) menu_entry_init(&entry); menu_entry_get(&entry, 0, (unsigned)i, NULL, true); - /* Read entry parameters */ - entry_path = menu_entry_get_rich_label(&entry); + /* Read entry parameters + * Note: can use entry.path/entry.rich_label directly, + * but have to use menu_entry_get_value() for the value + * since this function handles password entries... */ menu_entry_get_value(&entry, entry_value, sizeof(entry_value)); /* Get base length of entry title field */ @@ -2108,12 +2055,10 @@ static void rgui_render(void *data, bool is_idle) entry_title_max_len -= entry_value_len + 2; } - menu_entry_free(&entry); - /* Format entry title string */ ticker.s = entry_title_buf; ticker.len = entry_title_max_len; - ticker.str = entry_path; + ticker.str = string_is_empty(entry.rich_label) ? entry.path : entry.rich_label; ticker.selected = entry_selected; menu_animation_ticker(&ticker); @@ -2149,13 +2094,11 @@ static void rgui_render(void *data, bool is_idle) entry_title_buf); } - if (rgui_frame_buf.data) - blit_line(x, y, message, - entry_selected ? rgui->colors.hover_color : rgui->colors.normal_color, - rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); + blit_line(x, y, message, + entry_selected ? rgui->colors.hover_color : rgui->colors.normal_color, + rgui->colors.shadow_color, rgui->shadow_enable); - if (!string_is_empty(entry_path)) - free(entry_path); + menu_entry_free(&entry); } /* Draw mini thumbnails, if required */ @@ -2181,12 +2124,11 @@ static void rgui_render(void *data, bool is_idle) menu_animation_ticker(&ticker); - if (rgui_frame_buf.data) - blit_line( - RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, - (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + - RGUI_TERM_START_Y(fb_height) + 2, sublabel_buf, - rgui->colors.hover_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); + blit_line( + RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, + (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + + RGUI_TERM_START_Y(fb_height) + 2, sublabel_buf, + rgui->colors.hover_color, rgui->colors.shadow_color, rgui->shadow_enable); } else if (settings->bools.menu_core_enable) { @@ -2203,35 +2145,45 @@ static void rgui_render(void *data, bool is_idle) menu_animation_ticker(&ticker); - if (rgui_frame_buf.data) - blit_line( - RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, - (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + - RGUI_TERM_START_Y(fb_height) + 2, core_title_buf, - rgui->colors.hover_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); + blit_line( + RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, + (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + + RGUI_TERM_START_Y(fb_height) + 2, core_title_buf, + rgui->colors.hover_color, rgui->colors.shadow_color, rgui->shadow_enable); } } /* Print clock (if required) */ if (settings->bools.menu_timedate_enable) { - menu_display_ctx_datetime_t datetime; - char timedate[255]; + time_t current_time; + struct tm * time_info; + char timedate[16]; + int n; - timedate[0] = '\0'; + timedate[0] = '\0'; - datetime.s = timedate; - datetime.len = sizeof(timedate); - datetime.time_mode = 4; + /* menu_display_timedate() is incredibly slow + * -> do this the old fashioned way... */ - menu_display_timedate(&datetime); + /* Get current time */ + time(¤t_time); + time_info = localtime(¤t_time); + + if (time_info) + { + n = snprintf(timedate, sizeof(timedate), "%02u:%02u", + (unsigned)time_info->tm_hour, (unsigned)time_info->tm_min); + + if ((n < 0) || (n >= 16)) + n = 0; /* Silence GCC warnings... */ - if (rgui_frame_buf.data) blit_line( timedate_x, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, timedate, - rgui->colors.hover_color, rgui->colors.shadow_color, settings->bools.menu_rgui_shadows); + rgui->colors.hover_color, rgui->colors.shadow_color, rgui->shadow_enable); + } } } @@ -2266,11 +2218,24 @@ static void rgui_render(void *data, bool is_idle) static void rgui_framebuffer_free(void) { + rgui_frame_buf.width = 0; + rgui_frame_buf.height = 0; + if (rgui_frame_buf.data) free(rgui_frame_buf.data); rgui_frame_buf.data = NULL; } +static void rgui_background_free(void) +{ + rgui_background_buf.width = 0; + rgui_background_buf.height = 0; + + if (rgui_background_buf.data) + free(rgui_background_buf.data); + rgui_background_buf.data = NULL; +} + static void rgui_thumbnail_free(thumbnail_t *thumbnail) { if (!thumbnail) @@ -2291,19 +2256,6 @@ static void rgui_thumbnail_free(thumbnail_t *thumbnail) thumbnail->data = NULL; } -static void rgui_wallpaper_free(void) -{ - wallpaper.is_valid = false; - - if (!string_is_empty(wallpaper.path)) - free(wallpaper.path); - wallpaper.path = NULL; - - if (wallpaper.data) - free(wallpaper.data); - wallpaper.data = NULL; -} - bool rgui_is_video_config_equal(rgui_video_settings_t *config_a, rgui_video_settings_t *config_b) { return (config_a->aspect_ratio_idx == config_b->aspect_ratio_idx) && @@ -2437,10 +2389,10 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update) settings_t *settings = config_get_ptr(); rgui_framebuffer_free(); + rgui_background_free(); rgui_thumbnail_free(&fs_thumbnail); rgui_thumbnail_free(&mini_thumbnail); rgui_thumbnail_free(&mini_left_thumbnail); - rgui_wallpaper_free(); /* Cache new aspect ratio */ rgui->menu_aspect_ratio = settings->uints.menu_rgui_aspect_ratio; @@ -2452,10 +2404,9 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update) rgui_frame_buf.width = 320; base_term_width = rgui_frame_buf.width; - /* Allocate frame buffer - * (4 extra lines to cache the chequered background) */ + /* Allocate frame buffer */ rgui_frame_buf.data = (uint16_t*)calloc( - 400 * (rgui_frame_buf.height + 4), sizeof(uint16_t)); + 400 * rgui_frame_buf.height, sizeof(uint16_t)); #else @@ -2487,10 +2438,9 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update) break; } - /* Allocate frame buffer - * (4 extra lines to cache the chequered background) */ + /* Allocate frame buffer */ rgui_frame_buf.data = (uint16_t*)calloc( - rgui_frame_buf.width * (rgui_frame_buf.height + 4), sizeof(uint16_t)); + rgui_frame_buf.width * rgui_frame_buf.height, sizeof(uint16_t)); #endif @@ -2513,6 +2463,16 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update) rgui_term_layout.start_x = (rgui_frame_buf.width - (rgui_term_layout.width * FONT_WIDTH_STRIDE)) / 2; rgui_term_layout.start_y = (rgui_frame_buf.height - (rgui_term_layout.height * FONT_HEIGHT_STRIDE)) / 2; + /* Allocate background buffer + * (4 extra lines to store a copy of the chequered background) */ + rgui_background_buf.width = rgui_frame_buf.width; + rgui_background_buf.height = rgui_frame_buf.height; + rgui_background_buf.data = (uint16_t*)calloc( + rgui_background_buf.width * (rgui_background_buf.height + 4), sizeof(uint16_t)); + + if (!rgui_background_buf.data) + return false; + /* Allocate thumbnail buffer */ fs_thumbnail.max_width = rgui_frame_buf.width; fs_thumbnail.max_height = rgui_frame_buf.height; @@ -2539,12 +2499,6 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update) if (!mini_left_thumbnail.data) return false; - /* Allocate wallpaper buffer */ - wallpaper.data = (uint16_t*)calloc( - rgui_frame_buf.width * rgui_frame_buf.height, sizeof(uint16_t)); - if (!wallpaper.data) - return false; - /* Trigger background/display update */ rgui->theme_preset_path[0] = '\0'; rgui->bg_modified = true; @@ -2566,7 +2520,6 @@ static void *rgui_init(void **userdata, bool video_is_threaded) unsigned new_font_height; size_t start; rgui_t *rgui = NULL; - bool ret = false; settings_t *settings = config_get_ptr(); menu_handle_t *menu = (menu_handle_t*)calloc(1, sizeof(*menu)); @@ -2605,14 +2558,12 @@ static void *rgui_init(void **userdata, bool video_is_threaded) start = 0; menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &start); - ret = rguidisp_init_font(menu); + rgui_init_font_lut(); - if (!ret) - goto error; - - rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable; - rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; - rgui->bg_modified = true; + rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable; + rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; + rgui->border_enable = settings->bools.menu_rgui_border_filler_enable; + rgui->shadow_enable = settings->bools.menu_rgui_shadows; rgui->last_width = rgui_frame_buf.width; rgui->last_height = rgui_frame_buf.height; @@ -2630,10 +2581,10 @@ static void *rgui_init(void **userdata, bool video_is_threaded) error: rgui_framebuffer_free(); + rgui_background_free(); rgui_thumbnail_free(&fs_thumbnail); rgui_thumbnail_free(&mini_thumbnail); rgui_thumbnail_free(&mini_left_thumbnail); - rgui_wallpaper_free(); if (menu) free(menu); return NULL; @@ -2641,8 +2592,6 @@ error: static void rgui_free(void *data) { - const uint8_t *font_fb; - bool fb_font_inited = false; rgui_t *rgui = (rgui_t*)data; if (rgui) @@ -2651,20 +2600,11 @@ static void rgui_free(void *data) free(rgui->thumbnail_path_data); } - fb_font_inited = menu_display_get_font_data_init(); - font_fb = menu_display_get_font_framebuffer(); - - if (fb_font_inited) - free((void*)font_fb); - - fb_font_inited = false; - menu_display_set_font_data_init(fb_font_inited); - rgui_framebuffer_free(); + rgui_background_free(); rgui_thumbnail_free(&fs_thumbnail); rgui_thumbnail_free(&mini_thumbnail); rgui_thumbnail_free(&mini_left_thumbnail); - rgui_wallpaper_free(); if (rgui_upscale_buf.data) { @@ -2678,13 +2618,33 @@ static void rgui_frame(void *data, video_frame_info_t *video_info) rgui_t *rgui = (rgui_t*)data; settings_t *settings = config_get_ptr(); - if ((settings->bools.menu_rgui_background_filler_thickness_enable != rgui->bg_thickness) || - (settings->bools.menu_rgui_border_filler_thickness_enable != rgui->border_thickness) - ) - rgui->bg_modified = true; + if (settings->bools.menu_rgui_background_filler_thickness_enable != rgui->bg_thickness) + { + rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable; + rgui->bg_modified = true; + rgui->force_redraw = true; + } - rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable; - rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; + if (settings->bools.menu_rgui_border_filler_thickness_enable != rgui->border_thickness) + { + rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; + rgui->bg_modified = true; + rgui->force_redraw = true; + } + + if (settings->bools.menu_rgui_border_filler_enable != rgui->border_enable) + { + rgui->border_enable = settings->bools.menu_rgui_border_filler_enable; + rgui->bg_modified = true; + rgui->force_redraw = true; + } + + if (settings->bools.menu_rgui_shadows != rgui->shadow_enable) + { + rgui->shadow_enable = settings->bools.menu_rgui_shadows; + rgui->bg_modified = true; + rgui->force_redraw = true; + } if (settings->uints.menu_rgui_color_theme != rgui->color_theme) { diff --git a/menu/menu_driver.c b/menu/menu_driver.c index cddec7f9da..32f803a60e 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -181,9 +181,7 @@ static unsigned menu_display_header_height = 0; static bool menu_display_has_windowed = false; static bool menu_display_msg_force = false; -static bool menu_display_font_alloc_framebuf = false; static bool menu_display_framebuf_dirty = false; -static const uint8_t *menu_display_font_framebuf = NULL; static menu_display_ctx_driver_t *menu_disp = NULL; /* when enabled, on next iteration the 'Quick Menu' list will @@ -502,16 +500,6 @@ video_coord_array_t *menu_display_get_coords_array(void) return &menu_disp_ca; } -const uint8_t *menu_display_get_font_framebuffer(void) -{ - return menu_display_font_framebuf; -} - -void menu_display_set_font_framebuffer(const uint8_t *buffer) -{ - menu_display_font_framebuf = buffer; -} - bool menu_display_libretro_running( bool rarch_is_inited, bool rarch_is_dummy_core) @@ -608,16 +596,6 @@ void menu_display_set_msg_force(bool state) menu_display_msg_force = state; } -bool menu_display_get_font_data_init(void) -{ - return menu_display_font_alloc_framebuf; -} - -void menu_display_set_font_data_init(bool state) -{ - menu_display_font_alloc_framebuf = state; -} - /* Returns true if an animation is still active or * when the menu framebuffer still is dirty and * therefore it still needs to be rendered onscreen. diff --git a/menu/menu_driver.h b/menu/menu_driver.h index 5136230194..376ee2d29e 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -549,8 +549,6 @@ void menu_display_font_free(font_data_t *font); void menu_display_coords_array_reset(void); video_coord_array_t *menu_display_get_coords_array(void); -const uint8_t *menu_display_get_font_framebuffer(void); -void menu_display_set_font_framebuffer(const uint8_t *buffer); bool menu_display_libretro(bool is_idle, bool is_inited, bool is_dummy); bool menu_display_libretro_running(bool rarch_is_inited, bool rarch_is_dummy_core); @@ -566,8 +564,6 @@ void menu_display_set_framebuffer_pitch(size_t pitch); bool menu_display_get_msg_force(void); void menu_display_set_msg_force(bool state); -bool menu_display_get_font_data_init(void); -void menu_display_set_font_data_init(bool state); bool menu_display_get_update_pending(void); void menu_display_set_viewport(unsigned width, unsigned height); void menu_display_unset_viewport(unsigned width, unsigned height); From 48dc25130317b1266abf032f8e68e8c3b13b3d0e Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Fri, 5 Apr 2019 18:17:11 -0400 Subject: [PATCH 119/237] gl1: add scissor reset from gl --- gfx/drivers_font/gl1_raster_font.c | 1 - menu/drivers_display/menu_display_gl1.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/drivers_font/gl1_raster_font.c b/gfx/drivers_font/gl1_raster_font.c index 974bb1d90b..658c4f9b49 100644 --- a/gfx/drivers_font/gl1_raster_font.c +++ b/gfx/drivers_font/gl1_raster_font.c @@ -550,7 +550,6 @@ static void gl1_raster_font_bind_block(void *data, void *userdata) font->block = block; } - static int gl1_get_line_height(void *data) { gl1_raster_t *font = (gl1_raster_t*)data; diff --git a/menu/drivers_display/menu_display_gl1.c b/menu/drivers_display/menu_display_gl1.c index cb4840d49e..b0099d76f4 100644 --- a/menu/drivers_display/menu_display_gl1.c +++ b/menu/drivers_display/menu_display_gl1.c @@ -193,6 +193,7 @@ static void menu_display_gl1_scissor_begin(video_frame_info_t *video_info, int x static void menu_display_gl1_scissor_end(video_frame_info_t *video_info) { + glScissor(0, 0, video_info->width, video_info->height); glDisable(GL_SCISSOR_TEST); } From 9579804c7213e367a66747cdfd13d62c5d54def5 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Fri, 5 Apr 2019 23:07:59 -0400 Subject: [PATCH 120/237] gl1: add overlay support --- gfx/common/gl1_common.h | 8 ++ gfx/drivers/gl1.c | 248 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 255 insertions(+), 1 deletion(-) diff --git a/gfx/common/gl1_common.h b/gfx/common/gl1_common.h index 7c8f4ffaca..c855dca3cb 100644 --- a/gfx/common/gl1_common.h +++ b/gfx/common/gl1_common.h @@ -75,6 +75,14 @@ typedef struct gl1 bool smooth; bool menu_smooth; void *readback_buffer_screenshot; + bool overlay_enable; + bool overlay_full_screen; + GLuint *overlay_tex; + unsigned overlays; + float *overlay_vertex_coord; + float *overlay_tex_coord; + float *overlay_color_coord; + bool fullscreen; } gl1_t; static INLINE void gl1_bind_texture(GLuint id, GLint wrap_mode, GLint mag_filter, diff --git a/gfx/drivers/gl1.c b/gfx/drivers/gl1.c index 7f2cf6ac50..900bd418e8 100644 --- a/gfx/drivers/gl1.c +++ b/gfx/drivers/gl1.c @@ -105,6 +105,17 @@ static const GLfloat gl1_white_color[] = { if (gl1_shared_context_use) \ gl1->ctx_driver->bind_hw_render(gl1->ctx_data, enable) +static void gl1_render_overlay(gl1_t *gl, video_frame_info_t *video_info); +static void gl1_free_overlay(gl1_t *gl); +static void gl1_overlay_vertex_geom(void *data, + unsigned image, + float x, float y, + float w, float h); +static void gl1_overlay_tex_geom(void *data, + unsigned image, + GLfloat x, GLfloat y, + GLfloat w, GLfloat h); + static bool is_pot(unsigned x) { return (x & (x - 1)) == 0; @@ -202,6 +213,8 @@ static void *gl1_gfx_init(const video_info_t *video, if (!video_context_driver_set_video_mode(&mode)) goto error; + gl1->fullscreen = video->fullscreen; + mode.width = 0; mode.height = 0; @@ -705,6 +718,11 @@ static bool gl1_gfx_frame(void *data, const void *frame, menu_driver_frame(video_info); #endif +#ifdef HAVE_OVERLAY + if (gl1->overlay_enable) + gl1_render_overlay(gl1, video_info); +#endif + if (msg) font_driver_render_msg(video_info, NULL, msg, NULL); @@ -854,6 +872,10 @@ static void gl1_gfx_free(void *data) gl1->menu_tex = 0; } +#ifdef HAVE_OVERLAY + gl1_free_overlay(gl1); +#endif + if (gl1->extensions) { string_list_free(gl1->extensions); @@ -1253,6 +1275,230 @@ bool gl1_has_menu_frame(void) return (gl1_menu_frame != NULL); } +#ifdef HAVE_OVERLAY +static bool gl1_overlay_load(void *data, + const void *image_data, unsigned num_images) +{ + unsigned i, j; + gl1_t *gl = (gl1_t*)data; + const struct texture_image *images = + (const struct texture_image*)image_data; + + if (!gl) + return false; + + gl1_context_bind_hw_render(gl, false); + + gl1_free_overlay(gl); + gl->overlay_tex = (GLuint*) + calloc(num_images, sizeof(*gl->overlay_tex)); + + if (!gl->overlay_tex) + { + gl1_context_bind_hw_render(gl, true); + return false; + } + + gl->overlay_vertex_coord = (GLfloat*) + calloc(2 * 4 * num_images, sizeof(GLfloat)); + gl->overlay_tex_coord = (GLfloat*) + calloc(2 * 4 * num_images, sizeof(GLfloat)); + gl->overlay_color_coord = (GLfloat*) + calloc(4 * 4 * num_images, sizeof(GLfloat)); + + if ( !gl->overlay_vertex_coord + || !gl->overlay_tex_coord + || !gl->overlay_color_coord) + return false; + + gl->overlays = num_images; + glGenTextures(num_images, gl->overlay_tex); + + for (i = 0; i < num_images; i++) + { + unsigned alignment = video_pixel_get_alignment(images[i].width + * sizeof(uint32_t)); + + gl1_load_texture_data(gl->overlay_tex[i], + RARCH_WRAP_EDGE, TEXTURE_FILTER_LINEAR, + alignment, + images[i].width, images[i].height, images[i].pixels, + sizeof(uint32_t)); + + /* Default. Stretch to whole screen. */ + gl1_overlay_tex_geom(gl, i, 0, 0, 1, 1); + gl1_overlay_vertex_geom(gl, i, 0, 0, 1, 1); + + for (j = 0; j < 16; j++) + gl->overlay_color_coord[16 * i + j] = 1.0f; + } + + gl1_context_bind_hw_render(gl, true); + return true; +} + +static void gl1_overlay_enable(void *data, bool state) +{ + gl1_t *gl = (gl1_t*)data; + + if (!gl) + return; + + gl->overlay_enable = state; + + if (gl->fullscreen) + video_context_driver_show_mouse(&state); +} + +static void gl1_overlay_full_screen(void *data, bool enable) +{ + gl1_t *gl = (gl1_t*)data; + + if (gl) + gl->overlay_full_screen = enable; +} + +static void gl1_overlay_set_alpha(void *data, unsigned image, float mod) +{ + GLfloat *color = NULL; + gl1_t *gl = (gl1_t*)data; + if (!gl) + return; + + color = (GLfloat*)&gl->overlay_color_coord[image * 16]; + + color[ 0 + 3] = mod; + color[ 4 + 3] = mod; + color[ 8 + 3] = mod; + color[12 + 3] = mod; +} + +static const video_overlay_interface_t gl1_overlay_interface = { + gl1_overlay_enable, + gl1_overlay_load, + gl1_overlay_tex_geom, + gl1_overlay_vertex_geom, + gl1_overlay_full_screen, + gl1_overlay_set_alpha, +}; + +static void gl1_get_overlay_interface(void *data, + const video_overlay_interface_t **iface) +{ + (void)data; + *iface = &gl1_overlay_interface; +} + +static void gl1_free_overlay(gl1_t *gl) +{ + glDeleteTextures(gl->overlays, gl->overlay_tex); + + free(gl->overlay_tex); + free(gl->overlay_vertex_coord); + free(gl->overlay_tex_coord); + free(gl->overlay_color_coord); + gl->overlay_tex = NULL; + gl->overlay_vertex_coord = NULL; + gl->overlay_tex_coord = NULL; + gl->overlay_color_coord = NULL; + gl->overlays = 0; +} + +static void gl1_overlay_vertex_geom(void *data, + unsigned image, + float x, float y, + float w, float h) +{ + GLfloat *vertex = NULL; + gl1_t *gl = (gl1_t*)data; + + if (!gl) + return; + + if (image > gl->overlays) + { + RARCH_ERR("[GL]: Invalid overlay id: %u\n", image); + return; + } + + vertex = (GLfloat*)&gl->overlay_vertex_coord[image * 8]; + + /* Flipped, so we preserve top-down semantics. */ + y = 1.0f - y; + h = -h; + + vertex[0] = x; + vertex[1] = y; + vertex[2] = x + w; + vertex[3] = y; + vertex[4] = x; + vertex[5] = y + h; + vertex[6] = x + w; + vertex[7] = y + h; +} + +static void gl1_overlay_tex_geom(void *data, + unsigned image, + GLfloat x, GLfloat y, + GLfloat w, GLfloat h) +{ + GLfloat *tex = NULL; + gl1_t *gl = (gl1_t*)data; + + if (!gl) + return; + + tex = (GLfloat*)&gl->overlay_tex_coord[image * 8]; + + tex[0] = x; + tex[1] = y; + tex[2] = x + w; + tex[3] = y; + tex[4] = x; + tex[5] = y + h; + tex[6] = x + w; + tex[7] = y + h; +} + +static void gl1_render_overlay(gl1_t *gl, video_frame_info_t *video_info) +{ + unsigned i; + unsigned width = video_info->width; + unsigned height = video_info->height; + + glEnable(GL_BLEND); + + if (gl->overlay_full_screen) + glViewport(0, 0, width, height); + + gl->coords.vertex = gl->overlay_vertex_coord; + gl->coords.tex_coord = gl->overlay_tex_coord; + gl->coords.color = gl->overlay_color_coord; + gl->coords.vertices = 4 * gl->overlays; + + /*gl->shader->set_coords(gl->shader_data, &gl->coords); + gl->shader->set_mvp(gl->shader_data, &gl->mvp_no_rot);*/ + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + for (i = 0; i < gl->overlays; i++) + { + glBindTexture(GL_TEXTURE_2D, gl->overlay_tex[i]); + glDrawArrays(GL_TRIANGLE_STRIP, 4 * i, 4); + } + + glDisable(GL_BLEND); + gl->coords.vertex = gl->vertex_ptr; + gl->coords.tex_coord = gl->tex_info.coord; + gl->coords.color = gl->white_color_ptr; + gl->coords.vertices = 4; + if (gl->overlay_full_screen) + glViewport(gl->vp.x, gl->vp.y, gl->vp.width, gl->vp.height); +} +#endif + video_driver_t video_gl1 = { gl1_gfx_init, gl1_gfx_frame, @@ -1271,7 +1517,7 @@ video_driver_t video_gl1 = { NULL, /* read_frame_raw */ #ifdef HAVE_OVERLAY - NULL, /* overlay_interface */ + gl1_get_overlay_interface, #endif gl1_gfx_get_poke_interface, gl1_wrap_type_to_enum, From e181bc6d3971faf31b6c2f4f50aa0f3a8103095b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Zumer?= Date: Sat, 6 Apr 2019 13:48:18 -0400 Subject: [PATCH 121/237] Fix cheevos crash when peeking out of range This would occur if the address being peeked at was not part of a memory region defined in the core. --- cheevos-new/cheevos.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cheevos-new/cheevos.c b/cheevos-new/cheevos.c index 435a154f08..5276d006d4 100644 --- a/cheevos-new/cheevos.c +++ b/cheevos-new/cheevos.c @@ -527,11 +527,14 @@ static unsigned cheevos_peek(unsigned address, unsigned num_bytes, void* ud) address, cheevos_locals.patchdata.console_id); unsigned value = 0; - switch (num_bytes) + if (data) { - case 4: value |= data[2] << 16 | data[3] << 24; - case 2: value |= data[1] << 8; - case 1: value |= data[0]; + switch (num_bytes) + { + case 4: value |= data[2] << 16 | data[3] << 24; + case 2: value |= data[1] << 8; + case 1: value |= data[0]; + } } return value; From e0cb900abe61a630fd5b099a64b88442e851d796 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 7 Apr 2019 21:22:20 +0200 Subject: [PATCH 122/237] (UWP VFS) Cleanups --- .../vfs/vfs_implementation_uwp.cpp | 121 +++++++++--------- 1 file changed, 64 insertions(+), 57 deletions(-) diff --git a/libretro-common/vfs/vfs_implementation_uwp.cpp b/libretro-common/vfs/vfs_implementation_uwp.cpp index 9487840659..2febfba933 100644 --- a/libretro-common/vfs/vfs_implementation_uwp.cpp +++ b/libretro-common/vfs/vfs_implementation_uwp.cpp @@ -55,69 +55,63 @@ using namespace Windows::Storage::FileProperties; namespace { - /* Dear Microsoft - * I really appreciate all the effort you took to not provide any - * synchronous file APIs and block all attempts to synchronously - * wait for the results of async tasks for "smooth user experience", - * but I'm not going to run and rewrite all RetroArch cores for - * async I/O. I hope you like this hack I made instead. - */ template - T RunAsync(std::function()> func) - { - volatile bool finished = false; - volatile Platform::Exception^ exception = nullptr; - volatile T result; - func().then([&finished, &exception, &result](concurrency::task t) { - try - { - result = t.get(); - } - catch (Platform::Exception^ exception_) - { - exception = exception_; - } - finished = true; - }); - - /* Don't stall the UI thread - prevents a deadlock */ - Windows::UI::Core::CoreWindow^ corewindow = Windows::UI::Core::CoreWindow::GetForCurrentThread(); - while (!finished) - { - if (corewindow) - corewindow->Dispatcher->ProcessEvents(Windows::UI::Core::CoreProcessEventsOption::ProcessAllIfPresent); - } - - if (exception != nullptr) - throw exception; - return result; - } - - template - T RunAsyncAndCatchErrors(std::function()> func, T valueOnError) + static T RunAsyncAndCatchErrors(std::function()> func, T valueOnError) { try { - return RunAsync(func); + /* Dear Microsoft + * I really appreciate all the effort you took to not provide any + * synchronous file APIs and block all attempts to synchronously + * wait for the results of async tasks for "smooth user experience", + * but I'm not going to run and rewrite all RetroArch cores for + * async I/O. I hope you like this hack I made instead. + */ + volatile bool finished = false; + volatile Platform::Exception^ exception = nullptr; + volatile T result; + func().then([&finished, &exception, &result](concurrency::task t) { + try + { + result = t.get(); + } + catch (Platform::Exception^ exception_) + { + exception = exception_; + } + finished = true; + }); + + /* Don't stall the UI thread - prevents a deadlock */ + Windows::UI::Core::CoreWindow^ corewindow = Windows::UI::Core::CoreWindow::GetForCurrentThread(); + while (!finished) + { + if (corewindow) + corewindow->Dispatcher->ProcessEvents(Windows::UI::Core::CoreProcessEventsOption::ProcessAllIfPresent); + } + + if (exception != nullptr) + throw exception; + return result; } catch (Platform::Exception^ e) { return valueOnError; } } +} - void windowsize_path(wchar_t* path) +static void windowsize_path(wchar_t* path) +{ + /* UWP deals with paths containing / instead of \ way worse than normal Windows */ + /* and RetroArch may sometimes mix them (e.g. on archive extraction) */ + if (!path) + return; + while (*path) { - /* UWP deals with paths containing / instead of \ way worse than normal Windows */ - /* and RetroArch may sometimes mix them (e.g. on archive extraction) */ - if (!path) - return; - while (*path) - { - if (*path == '/') - *path = '\\'; - ++path; - } + if (*path == '/') + *path = '\\'; + ++path; } } @@ -166,7 +160,7 @@ namespace /* A list of all StorageFolder objects returned using from the file picker */ Platform::Collections::Vector accessible_directories; - concurrency::task TriggerPickerAddDialog() + static concurrency::task TriggerPickerAddDialog() { auto folderPicker = ref new Windows::Storage::Pickers::FolderPicker(); folderPicker->SuggestedStartLocation = Windows::Storage::Pickers::PickerLocationId::Desktop; @@ -183,7 +177,7 @@ namespace } template - concurrency::task LocateStorageItem(Platform::String^ path) + static concurrency::task LocateStorageItem(Platform::String^ path) { /* Look for a matching directory we can use */ for each (StorageFolder^ folder in accessible_directories) @@ -231,7 +225,7 @@ namespace }); } - IStorageItem^ LocateStorageFileOrFolder(Platform::String^ path) + static IStorageItem^ LocateStorageFileOrFolder(Platform::String^ path) { if (!path || path->IsEmpty()) return nullptr; @@ -273,6 +267,8 @@ struct libretro_vfs_implementation_file libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, unsigned mode, unsigned hints) { + char *dirpath = NULL; + wchar_t *dirpath_wide = NULL; if (!path || !*path) return NULL; @@ -288,9 +284,14 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, uns return NULL; } - char* dirpath = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + dirpath = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + + if (!dirpath) + return NULL; + fill_pathname_basedir(dirpath, path, PATH_MAX_LENGTH); - wchar_t *dirpath_wide = utf8_to_utf16_string_alloc(dirpath); + + dirpath_wide = utf8_to_utf16_string_alloc(dirpath); windowsize_path(dirpath_wide); Platform::String^ dirpath_str = ref new Platform::String(dirpath_wide); free(dirpath_wide); @@ -570,11 +571,17 @@ const char *retro_vfs_file_get_path_impl(libretro_vfs_implementation_file *strea int retro_vfs_stat_impl(const char *path, int32_t *size) { + wchar_t *path_wide = NULL; if (!path || !*path) return 0; - wchar_t *path_wide = utf8_to_utf16_string_alloc(path); + path_wide = utf8_to_utf16_string_alloc(path); + + if (!path_wide) + return 0; + windowsize_path(path_wide); + Platform::String^ path_str = ref new Platform::String(path_wide); free(path_wide); From 79ffb53ef221f5ef09a451a326b377b7c073b5da Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 7 Apr 2019 21:35:45 +0200 Subject: [PATCH 123/237] (UWP VFS) Try to rewrite this - baby steps --- .../vfs/vfs_implementation_uwp.cpp | 105 +++++++++++------- 1 file changed, 65 insertions(+), 40 deletions(-) diff --git a/libretro-common/vfs/vfs_implementation_uwp.cpp b/libretro-common/vfs/vfs_implementation_uwp.cpp index 2febfba933..a072f971e2 100644 --- a/libretro-common/vfs/vfs_implementation_uwp.cpp +++ b/libretro-common/vfs/vfs_implementation_uwp.cpp @@ -182,11 +182,13 @@ namespace /* Look for a matching directory we can use */ for each (StorageFolder^ folder in accessible_directories) { + std::wstring file_path; std::wstring folder_path = folder->Path->Data(); /* Could be C:\ or C:\Users\somebody - remove the trailing slash to unify them */ if (folder_path[folder_path.size() - 1] == '\\') folder_path.erase(folder_path.size() - 1); - std::wstring file_path = path->Data(); + file_path = path->Data(); + if (file_path.find(folder_path) == 0) { /* Found a match */ @@ -267,8 +269,11 @@ struct libretro_vfs_implementation_file libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, unsigned mode, unsigned hints) { - char *dirpath = NULL; - wchar_t *dirpath_wide = NULL; + char *filename = NULL; + char *dirpath = NULL; + wchar_t *dirpath_wide = NULL; + wchar_t *filename_wide = NULL; + if (!path || !*path) return NULL; @@ -297,9 +302,9 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, uns free(dirpath_wide); free(dirpath); - char* filename = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + filename = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); fill_pathname_base(filename, path, PATH_MAX_LENGTH); - wchar_t *filename_wide = utf8_to_utf16_string_alloc(filename); + filename_wide = utf8_to_utf16_string_alloc(filename); Platform::String^ filename_str = ref new Platform::String(filename_wide); free(filename_wide); free(filename); @@ -307,26 +312,32 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, uns retro_assert(!dirpath_str->IsEmpty() && !filename_str->IsEmpty()); return RunAsyncAndCatchErrors([=]() { - return concurrency::create_task(LocateStorageItem(dirpath_str)).then([=](StorageFolder^ dir) { - if (mode == RETRO_VFS_FILE_ACCESS_READ) - return dir->GetFileAsync(filename_str); - else + return concurrency::create_task(LocateStorageItem(dirpath_str)). + then([=](StorageFolder^ dir) + { + if (mode == RETRO_VFS_FILE_ACCESS_READ) + return dir->GetFileAsync(filename_str); return dir->CreateFileAsync(filename_str, (mode & RETRO_VFS_FILE_ACCESS_UPDATE_EXISTING) != 0 ? CreationCollisionOption::OpenIfExists : CreationCollisionOption::ReplaceExisting); - }).then([=](StorageFile^ file) { - FileAccessMode accessMode = mode == RETRO_VFS_FILE_ACCESS_READ ? + } + ).then([=](StorageFile^ file) + { + FileAccessMode accessMode = mode == RETRO_VFS_FILE_ACCESS_READ ? FileAccessMode::Read : FileAccessMode::ReadWrite; - return file->OpenAsync(accessMode); - }).then([=](IRandomAccessStream^ fpstream) { - libretro_vfs_implementation_file *stream = (libretro_vfs_implementation_file*)calloc(1, sizeof(*stream)); - if (!stream) - return (libretro_vfs_implementation_file*)NULL; + return file->OpenAsync(accessMode); + } + ).then([=](IRandomAccessStream^ fpstream) + { + libretro_vfs_implementation_file *stream = (libretro_vfs_implementation_file*)calloc(1, sizeof(*stream)); + if (!stream) + return (libretro_vfs_implementation_file*)NULL; - stream->orig_path = strdup(path); - stream->fp = fpstream; - stream->fp->Seek(0); - return stream; - }); + stream->orig_path = strdup(path); + stream->fp = fpstream; + stream->fp->Seek(0); + return stream; + } + ); }, NULL); } @@ -499,10 +510,11 @@ int retro_vfs_file_flush_impl(libretro_vfs_implementation_file *stream) int retro_vfs_file_remove_impl(const char *path) { + wchar_t *path_wide = NULL; if (!path || !*path) return -1; - wchar_t *path_wide = utf8_to_utf16_string_alloc(path); + path_wide = utf8_to_utf16_string_alloc(path); windowsize_path(path_wide); Platform::String^ path_str = ref new Platform::String(path_wide); free(path_wide); @@ -519,22 +531,27 @@ int retro_vfs_file_remove_impl(const char *path) /* TODO: this may not work if trying to move a directory */ int retro_vfs_file_rename_impl(const char *old_path, const char *new_path) { + wchar_t *old_path_wide = NULL; + wchar_t *new_dir_path_wide = NULL; + char *new_dir_path = NULL; + char *new_file_name = NULL; + if (!old_path || !*old_path || !new_path || !*new_path) return -1; - wchar_t* old_path_wide = utf8_to_utf16_string_alloc(old_path); + old_path_wide = utf8_to_utf16_string_alloc(old_path); Platform::String^ old_path_str = ref new Platform::String(old_path_wide); free(old_path_wide); - char* new_dir_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + new_dir_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); fill_pathname_basedir(new_dir_path, new_path, PATH_MAX_LENGTH); - wchar_t *new_dir_path_wide = utf8_to_utf16_string_alloc(new_dir_path); + new_dir_path_wide = utf8_to_utf16_string_alloc(new_dir_path); windowsize_path(new_dir_path_wide); Platform::String^ new_dir_path_str = ref new Platform::String(new_dir_path_wide); free(new_dir_path_wide); free(new_dir_path); - char* new_file_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + new_file_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); fill_pathname_base(new_file_name, new_path, PATH_MAX_LENGTH); wchar_t *new_file_name_wide = utf8_to_utf16_string_alloc(new_file_name); Platform::String^ new_file_name_str = ref new Platform::String(new_file_name_wide); @@ -600,25 +617,31 @@ int retro_vfs_stat_impl(const char *path, int32_t *size) int retro_vfs_mkdir_impl(const char *dir) { + char *dir_local = NULL; + char *tmp = NULL; + char *dir_name = NULL; + char *parent_path = NULL; + wchar_t *dir_name_wide = NULL; + wchar_t *parent_path_wide = NULL; if (!dir || !*dir) return -1; - char* dir_local = strdup(dir); + dir_local = strdup(dir); /* If the path ends with a slash, we have to remove it for basename to work */ - char* tmp = dir_local + strlen(dir_local) - 1; + tmp = dir_local + strlen(dir_local) - 1; if (path_char_is_slash(*tmp)) *tmp = 0; - char* dir_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + dir_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); fill_pathname_base(dir_name, dir_local, PATH_MAX_LENGTH); - wchar_t *dir_name_wide = utf8_to_utf16_string_alloc(dir_name); + dir_name_wide = utf8_to_utf16_string_alloc(dir_name); Platform::String^ dir_name_str = ref new Platform::String(dir_name_wide); free(dir_name_wide); free(dir_name); - char* parent_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + parent_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); fill_pathname_parent_dir(parent_path, dir_local, PATH_MAX_LENGTH); - wchar_t *parent_path_wide = utf8_to_utf16_string_alloc(parent_path); + parent_path_wide = utf8_to_utf16_string_alloc(parent_path); windowsize_path(parent_path_wide); Platform::String^ parent_path_str = ref new Platform::String(parent_path_wide); free(parent_path_wide); @@ -660,7 +683,8 @@ struct libretro_vfs_implementation_dir libretro_vfs_implementation_dir *retro_vfs_opendir_impl(const char *name, bool include_hidden) { - libretro_vfs_implementation_dir *rdir; + libretro_vfs_implementation_dir *rdir = NULL; + wchar_t *name_wide = NULL; if (!name || !*name) return NULL; @@ -669,7 +693,7 @@ libretro_vfs_implementation_dir *retro_vfs_opendir_impl(const char *name, bool i if (!rdir) return NULL; - wchar_t *name_wide = utf8_to_utf16_string_alloc(name); + name_wide = utf8_to_utf16_string_alloc(name); windowsize_path(name_wide); Platform::String^ name_str = ref new Platform::String(name_wide); free(name_wide); @@ -694,10 +718,8 @@ bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir *rdir) rdir->entry = rdir->directory->First(); return rdir->entry->HasCurrent; } - else - { - return rdir->entry->MoveNext(); - } + + return rdir->entry->MoveNext(); } const char *retro_vfs_dirent_get_name_impl(libretro_vfs_implementation_dir *rdir) @@ -729,10 +751,12 @@ int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *rdir) bool uwp_is_path_accessible_using_standard_io(const char *path) { + bool result = false; char *relative_path_abbrev = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + fill_pathname_abbreviate_special(relative_path_abbrev, path, PATH_MAX_LENGTH * sizeof(char)); - bool result = strlen(relative_path_abbrev) >= 2 && (relative_path_abbrev[0] == ':' || relative_path_abbrev[0] == '~') && path_char_is_slash(relative_path_abbrev[1]); + result = strlen(relative_path_abbrev) >= 2 && (relative_path_abbrev[0] == ':' || relative_path_abbrev[0] == '~') && path_char_is_slash(relative_path_abbrev[1]); free(relative_path_abbrev); return result; @@ -740,10 +764,11 @@ bool uwp_is_path_accessible_using_standard_io(const char *path) bool uwp_drive_exists(const char *path) { + wchar_t *path_wide = NULL; if (!path || !*path) return 0; - wchar_t *path_wide = utf8_to_utf16_string_alloc(path); + path_wide = utf8_to_utf16_string_alloc(path); Platform::String^ path_str = ref new Platform::String(path_wide); free(path_wide); From dd016c44c9aff10a50b0385428ac4148dc09ae81 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 7 Apr 2019 21:58:10 +0200 Subject: [PATCH 124/237] (UWP VFS) Code formatting cleanups --- .../vfs/vfs_implementation_uwp.cpp | 77 ++++++++++--------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/libretro-common/vfs/vfs_implementation_uwp.cpp b/libretro-common/vfs/vfs_implementation_uwp.cpp index a072f971e2..b78d4b96ed 100644 --- a/libretro-common/vfs/vfs_implementation_uwp.cpp +++ b/libretro-common/vfs/vfs_implementation_uwp.cpp @@ -267,7 +267,8 @@ struct libretro_vfs_implementation_file char* orig_path; }; -libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, unsigned mode, unsigned hints) +libretro_vfs_implementation_file *retro_vfs_file_open_impl( + const char *path, unsigned mode, unsigned hints) { char *filename = NULL; char *dirpath = NULL; @@ -289,25 +290,26 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, uns return NULL; } - dirpath = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + dirpath = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); if (!dirpath) return NULL; fill_pathname_basedir(dirpath, path, PATH_MAX_LENGTH); - dirpath_wide = utf8_to_utf16_string_alloc(dirpath); + dirpath_wide = utf8_to_utf16_string_alloc(dirpath); windowsize_path(dirpath_wide); - Platform::String^ dirpath_str = ref new Platform::String(dirpath_wide); - free(dirpath_wide); - free(dirpath); + Platform::String^ dirpath_str = ref new Platform::String(dirpath_wide); - filename = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + filename = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); fill_pathname_base(filename, path, PATH_MAX_LENGTH); - filename_wide = utf8_to_utf16_string_alloc(filename); + filename_wide = utf8_to_utf16_string_alloc(filename); Platform::String^ filename_str = ref new Platform::String(filename_wide); + free(filename_wide); free(filename); + free(dirpath_wide); + free(dirpath); retro_assert(!dirpath_str->IsEmpty() && !filename_str->IsEmpty()); @@ -510,13 +512,13 @@ int retro_vfs_file_flush_impl(libretro_vfs_implementation_file *stream) int retro_vfs_file_remove_impl(const char *path) { - wchar_t *path_wide = NULL; + wchar_t *path_wide = NULL; if (!path || !*path) return -1; - path_wide = utf8_to_utf16_string_alloc(path); + path_wide = utf8_to_utf16_string_alloc(path); windowsize_path(path_wide); - Platform::String^ path_str = ref new Platform::String(path_wide); + Platform::String^ path_str = ref new Platform::String(path_wide); free(path_wide); return RunAsyncAndCatchErrors([=]() { @@ -531,34 +533,37 @@ int retro_vfs_file_remove_impl(const char *path) /* TODO: this may not work if trying to move a directory */ int retro_vfs_file_rename_impl(const char *old_path, const char *new_path) { - wchar_t *old_path_wide = NULL; - wchar_t *new_dir_path_wide = NULL; - char *new_dir_path = NULL; - char *new_file_name = NULL; + wchar_t *old_path_wide = NULL; + wchar_t *new_dir_path_wide = NULL; + char *new_dir_path = NULL; + char *new_file_name = NULL; if (!old_path || !*old_path || !new_path || !*new_path) return -1; - old_path_wide = utf8_to_utf16_string_alloc(old_path); - Platform::String^ old_path_str = ref new Platform::String(old_path_wide); + old_path_wide = utf8_to_utf16_string_alloc(old_path); + Platform::String^ old_path_str = ref new Platform::String(old_path_wide); free(old_path_wide); - new_dir_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + new_dir_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); fill_pathname_basedir(new_dir_path, new_path, PATH_MAX_LENGTH); - new_dir_path_wide = utf8_to_utf16_string_alloc(new_dir_path); + new_dir_path_wide = utf8_to_utf16_string_alloc(new_dir_path); windowsize_path(new_dir_path_wide); Platform::String^ new_dir_path_str = ref new Platform::String(new_dir_path_wide); free(new_dir_path_wide); free(new_dir_path); - new_file_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + new_file_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); fill_pathname_base(new_file_name, new_path, PATH_MAX_LENGTH); - wchar_t *new_file_name_wide = utf8_to_utf16_string_alloc(new_file_name); + wchar_t *new_file_name_wide = utf8_to_utf16_string_alloc(new_file_name); Platform::String^ new_file_name_str = ref new Platform::String(new_file_name_wide); free(new_file_name_wide); free(new_file_name); - retro_assert(!old_path_str->IsEmpty() && !new_dir_path_str->IsEmpty() && !new_file_name_str->IsEmpty()); + retro_assert( + !old_path_str->IsEmpty() + && !new_dir_path_str->IsEmpty() + && !new_file_name_str->IsEmpty()); return RunAsyncAndCatchErrors([=]() { concurrency::task old_file_task = concurrency::create_task(LocateStorageItem(old_path_str)); @@ -617,31 +622,31 @@ int retro_vfs_stat_impl(const char *path, int32_t *size) int retro_vfs_mkdir_impl(const char *dir) { - char *dir_local = NULL; - char *tmp = NULL; - char *dir_name = NULL; - char *parent_path = NULL; - wchar_t *dir_name_wide = NULL; - wchar_t *parent_path_wide = NULL; + char *dir_local = NULL; + char *tmp = NULL; + char *dir_name = NULL; + char *parent_path = NULL; + wchar_t *dir_name_wide = NULL; + wchar_t *parent_path_wide = NULL; if (!dir || !*dir) return -1; - dir_local = strdup(dir); + dir_local = strdup(dir); /* If the path ends with a slash, we have to remove it for basename to work */ - tmp = dir_local + strlen(dir_local) - 1; + tmp = dir_local + strlen(dir_local) - 1; if (path_char_is_slash(*tmp)) *tmp = 0; - dir_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + dir_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); fill_pathname_base(dir_name, dir_local, PATH_MAX_LENGTH); - dir_name_wide = utf8_to_utf16_string_alloc(dir_name); - Platform::String^ dir_name_str = ref new Platform::String(dir_name_wide); + dir_name_wide = utf8_to_utf16_string_alloc(dir_name); + Platform::String^ dir_name_str = ref new Platform::String(dir_name_wide); free(dir_name_wide); free(dir_name); - parent_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + parent_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); fill_pathname_parent_dir(parent_path, dir_local, PATH_MAX_LENGTH); - parent_path_wide = utf8_to_utf16_string_alloc(parent_path); + parent_path_wide = utf8_to_utf16_string_alloc(parent_path); windowsize_path(parent_path_wide); Platform::String^ parent_path_str = ref new Platform::String(parent_path_wide); free(parent_path_wide); @@ -742,7 +747,7 @@ int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *rdir) if (rdir->entry_name) free(rdir->entry_name); - rdir->entry = nullptr; + rdir->entry = nullptr; rdir->directory = nullptr; free(rdir); From b49577b65f347be4d8df0683d1609eae66cf624e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 7 Apr 2019 22:45:35 +0200 Subject: [PATCH 125/237] (UWP VFS) Code formatting cleanups --- .../vfs/vfs_implementation_uwp.cpp | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/libretro-common/vfs/vfs_implementation_uwp.cpp b/libretro-common/vfs/vfs_implementation_uwp.cpp index b78d4b96ed..86435ee14c 100644 --- a/libretro-common/vfs/vfs_implementation_uwp.cpp +++ b/libretro-common/vfs/vfs_implementation_uwp.cpp @@ -119,35 +119,38 @@ namespace { /* Damn you, UWP, why no functions for that either */ template - concurrency::task GetItemFromPathAsync(Platform::String^ path) + static concurrency::task GetItemFromPathAsync(Platform::String^ path) { static_assert(false, "StorageFile and StorageFolder only"); } + template<> - concurrency::task GetItemFromPathAsync(Platform::String^ path) + static concurrency::task GetItemFromPathAsync(Platform::String^ path) { return concurrency::create_task(StorageFile::GetFileFromPathAsync(path)); } template<> - concurrency::task GetItemFromPathAsync(Platform::String^ path) + static concurrency::task GetItemFromPathAsync(Platform::String^ path) { return concurrency::create_task(StorageFolder::GetFolderFromPathAsync(path)); } template - concurrency::task GetItemInFolderFromPathAsync(StorageFolder^ folder, Platform::String^ path) + static concurrency::task GetItemInFolderFromPathAsync(StorageFolder^ folder, Platform::String^ path) { static_assert(false, "StorageFile and StorageFolder only"); } + template<> - concurrency::task GetItemInFolderFromPathAsync(StorageFolder^ folder, Platform::String^ path) + static concurrency::task GetItemInFolderFromPathAsync(StorageFolder^ folder, Platform::String^ path) { if (path->IsEmpty()) retro_assert(false); /* Attempt to read a folder as a file - this really should have been caught earlier */ return concurrency::create_task(folder->GetFileAsync(path)); } + template<> - concurrency::task GetItemInFolderFromPathAsync(StorageFolder^ folder, Platform::String^ path) + static concurrency::task GetItemInFolderFromPathAsync(StorageFolder^ folder, Platform::String^ path) { if (path->IsEmpty()) return concurrency::create_task(concurrency::create_async([folder]() { return folder; })); @@ -242,8 +245,7 @@ namespace else { /* No final slash - probably a file (since RetroArch usually slash-terminates dirs), but there is still a chance it's a directory */ - IStorageItem^ item; - item = RunAsyncAndCatchErrors([=]() { + IStorageItem ^item = RunAsyncAndCatchErrors([=]() { return concurrency::create_task(LocateStorageItem(path)); }, nullptr); if (!item) @@ -420,9 +422,10 @@ public: HRESULT __stdcall RuntimeClassInitialize(byte *buffer, uint32_t capacity, uint32_t length) { - m_buffer = buffer; + m_buffer = buffer; m_capacity = capacity; - m_length = length; + m_length = length; + return S_OK; } @@ -465,7 +468,7 @@ IBuffer^ CreateNativeBuffer(void* buf, uint32_t capacity, uint32_t length) Microsoft::WRL::ComPtr nativeBuffer; Microsoft::WRL::Details::MakeAndInitialize(&nativeBuffer, (byte *)buf, capacity, length); auto iinspectable = (IInspectable *)reinterpret_cast(nativeBuffer.Get()); - IBuffer ^buffer = reinterpret_cast(iinspectable); + IBuffer ^buffer = reinterpret_cast(iinspectable); return buffer; } @@ -535,6 +538,7 @@ int retro_vfs_file_rename_impl(const char *old_path, const char *new_path) { wchar_t *old_path_wide = NULL; wchar_t *new_dir_path_wide = NULL; + wchar_t *new_file_name_wide = NULL; char *new_dir_path = NULL; char *new_file_name = NULL; @@ -555,7 +559,7 @@ int retro_vfs_file_rename_impl(const char *old_path, const char *new_path) new_file_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); fill_pathname_base(new_file_name, new_path, PATH_MAX_LENGTH); - wchar_t *new_file_name_wide = utf8_to_utf16_string_alloc(new_file_name); + new_file_name_wide = utf8_to_utf16_string_alloc(new_file_name); Platform::String^ new_file_name_str = ref new Platform::String(new_file_name_wide); free(new_file_name_wide); free(new_file_name); From d03ff44d53d61ceed0c4f67cdf595976f26a7412 Mon Sep 17 00:00:00 2001 From: markwkidd Date: Sun, 7 Apr 2019 22:34:01 -0400 Subject: [PATCH 126/237] allow non-accelerated video to rotate the display --- libretro-common/include/libretro.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index 1482ea4104..9fa1e3ad37 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -485,7 +485,6 @@ enum retro_mod /* Environment commands. */ #define RETRO_ENVIRONMENT_SET_ROTATION 1 /* const unsigned * -- * Sets screen rotation of graphics. - * Is only implemented if rotation can be accelerated by hardware. * Valid values are 0, 1, 2, 3, which rotates screen by 0, 90, 180, * 270 degrees counter-clockwise respectively. */ From 9fff07e589496c799e66f2767f48f754b8432e68 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 8 Apr 2019 13:35:35 +0100 Subject: [PATCH 127/237] (Menu Widgets) Fix text alignment issues with Vulkan and D3D video drivers --- gfx/drivers/vulkan.c | 2 +- gfx/drivers_font/d3d10_font.c | 4 ++-- gfx/drivers_font/d3d11_font.c | 4 ++-- gfx/drivers_font/d3d12_font.c | 4 ++-- gfx/drivers_font/vulkan_raster_font.c | 4 ++-- menu/widgets/menu_widgets.c | 7 +++++-- retroarch.c | 7 +++++++ 7 files changed, 21 insertions(+), 11 deletions(-) diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index b0a1b50191..dd151870a7 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -2366,7 +2366,7 @@ static void vulkan_unload_texture(void *data, uintptr_t handle) { vk_t *vk = (vk_t*)data; struct vk_texture *texture = (struct vk_texture*)handle; - if (!texture) + if (!texture || !vk) return; /* TODO: We really want to defer this deletion instead, diff --git a/gfx/drivers_font/d3d10_font.c b/gfx/drivers_font/d3d10_font.c index 363008c6c3..0efe989ab9 100644 --- a/gfx/drivers_font/d3d10_font.c +++ b/gfx/drivers_font/d3d10_font.c @@ -178,8 +178,8 @@ static void d3d10_font_render_line( if (!glyph) continue; - v->pos.x = (x + glyph->draw_offset_x) * scale / (float)d3d10->viewport.Width; - v->pos.y = (y + glyph->draw_offset_y) * scale / (float)d3d10->viewport.Height; + v->pos.x = (x + (glyph->draw_offset_x * scale)) / (float)d3d10->viewport.Width; + v->pos.y = (y + (glyph->draw_offset_y * scale)) / (float)d3d10->viewport.Height; v->pos.w = glyph->width * scale / (float)d3d10->viewport.Width; v->pos.h = glyph->height * scale / (float)d3d10->viewport.Height; diff --git a/gfx/drivers_font/d3d11_font.c b/gfx/drivers_font/d3d11_font.c index 5ef55b956f..15f370e772 100644 --- a/gfx/drivers_font/d3d11_font.c +++ b/gfx/drivers_font/d3d11_font.c @@ -176,8 +176,8 @@ static void d3d11_font_render_line( if (!glyph) continue; - v->pos.x = (x + glyph->draw_offset_x) * scale / (float)d3d11->viewport.Width; - v->pos.y = (y + glyph->draw_offset_y) * scale / (float)d3d11->viewport.Height; + v->pos.x = (x + (glyph->draw_offset_x * scale)) / (float)d3d11->viewport.Width; + v->pos.y = (y + (glyph->draw_offset_y * scale)) / (float)d3d11->viewport.Height; v->pos.w = glyph->width * scale / (float)d3d11->viewport.Width; v->pos.h = glyph->height * scale / (float)d3d11->viewport.Height; diff --git a/gfx/drivers_font/d3d12_font.c b/gfx/drivers_font/d3d12_font.c index c37b56b374..741ea953b0 100644 --- a/gfx/drivers_font/d3d12_font.c +++ b/gfx/drivers_font/d3d12_font.c @@ -184,8 +184,8 @@ static void d3d12_font_render_line( if (!glyph) continue; - v->pos.x = (x + glyph->draw_offset_x) * scale / (float)d3d12->chain.viewport.Width; - v->pos.y = (y + glyph->draw_offset_y) * scale / (float)d3d12->chain.viewport.Height; + v->pos.x = (x + (glyph->draw_offset_x * scale)) / (float)d3d12->chain.viewport.Width; + v->pos.y = (y + (glyph->draw_offset_y * scale)) / (float)d3d12->chain.viewport.Height; v->pos.w = glyph->width * scale / (float)d3d12->chain.viewport.Width; v->pos.h = glyph->height * scale / (float)d3d12->chain.viewport.Height; diff --git a/gfx/drivers_font/vulkan_raster_font.c b/gfx/drivers_font/vulkan_raster_font.c index aae54e604a..553499aecf 100644 --- a/gfx/drivers_font/vulkan_raster_font.c +++ b/gfx/drivers_font/vulkan_raster_font.c @@ -203,8 +203,8 @@ static void vulkan_raster_font_render_line( height = glyph->height; vulkan_write_quad_vbo(font->pv + font->vertices, - (x + off_x + delta_x * scale) * inv_win_width, - (y + off_y + delta_y * scale) * inv_win_height, + (x + (off_x + delta_x) * scale) * inv_win_width, + (y + (off_y + delta_y) * scale) * inv_win_height, width * scale * inv_win_width, height * scale * inv_win_height, tex_x * inv_tex_size_x, diff --git a/menu/widgets/menu_widgets.c b/menu/widgets/menu_widgets.c index b37d532d1c..4b83e7bd11 100644 --- a/menu/widgets/menu_widgets.c +++ b/menu/widgets/menu_widgets.c @@ -208,7 +208,7 @@ static char *menu_widgets_icons_names[MENU_WIDGETS_ICON_LAST] = { "menu_info.png" }; -static menu_texture_item menu_widgets_icons_textures[MENU_WIDGETS_ICON_LAST]; +static menu_texture_item menu_widgets_icons_textures[MENU_WIDGETS_ICON_LAST] = {0}; /* Volume */ static float volume_db = 0.0f; @@ -1776,6 +1776,9 @@ void menu_widgets_free(void) { int i; + if (!menu_widgets_inited) + return; + menu_widgets_inited = false; /* Kill any pending animation */ @@ -2078,4 +2081,4 @@ void menu_widgets_start_load_content_animation(const char *content_name, bool re bool menu_widgets_ready(void) { return menu_widgets_inited; -} \ No newline at end of file +} diff --git a/retroarch.c b/retroarch.c index 154e6bad69..cc9389e266 100644 --- a/retroarch.c +++ b/retroarch.c @@ -700,6 +700,13 @@ void driver_uninit(int flags) #ifdef HAVE_MENU if (flags & DRIVER_MENU_MASK) { +#if defined(HAVE_MENU_WIDGETS) + /* This absolutely has to be done before video_driver_free() + * is called/completes, otherwise certain menu drivers + * (e.g. Vulkan) will segfault */ + menu_widgets_context_destroy(); + menu_widgets_free(); +#endif menu_driver_ctl(RARCH_MENU_CTL_DEINIT, NULL); menu_driver_free(); } From 45fa047b07d07013d0a9f47100876d03d6ff90f8 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 8 Apr 2019 15:22:21 +0200 Subject: [PATCH 128/237] (Menu display) Pointer cleanups --- menu/drivers_display/menu_display_d3d10.c | 46 ++++++++--------- menu/drivers_display/menu_display_d3d11.c | 38 +++++++------- menu/drivers_display/menu_display_d3d12.c | 38 +++++++------- menu/drivers_display/menu_display_d3d8.c | 14 ++---- menu/drivers_display/menu_display_d3d9.c | 55 ++++++++++----------- menu/drivers_display/menu_display_gl.c | 2 +- menu/drivers_display/menu_display_gl1.c | 2 +- menu/drivers_display/menu_display_gl_core.c | 39 +++++++-------- menu/drivers_display/menu_display_vulkan.c | 36 +++++++------- 9 files changed, 127 insertions(+), 143 deletions(-) diff --git a/menu/drivers_display/menu_display_d3d10.c b/menu/drivers_display/menu_display_d3d10.c index f04452b069..914a40b879 100644 --- a/menu/drivers_display/menu_display_d3d10.c +++ b/menu/drivers_display/menu_display_d3d10.c @@ -46,14 +46,14 @@ static void* menu_display_d3d10_get_default_mvp(video_frame_info_t *video_info) static void menu_display_d3d10_blend_begin(video_frame_info_t *video_info) { - d3d10_video_t* d3d10 = video_info ? (d3d10_video_t*)video_info->userdata : NULL; + d3d10_video_t* d3d10 = (d3d10_video_t*)video_info->userdata; D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK); } static void menu_display_d3d10_blend_end(video_frame_info_t *video_info) { - d3d10_video_t* d3d10 = video_info ? (d3d10_video_t*)video_info->userdata : NULL; + d3d10_video_t* d3d10 = (d3d10_video_t*)video_info->userdata; D3D10SetBlendState(d3d10->device, d3d10->blend_disable, NULL, D3D10_DEFAULT_SAMPLE_MASK); } @@ -66,9 +66,8 @@ static void menu_display_d3d10_viewport(menu_display_ctx_draw_t *draw, static void menu_display_d3d10_draw(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { - int vertex_count; - d3d10_video_t* d3d10 = video_info ? - (d3d10_video_t*)video_info->userdata : NULL; + int vertex_count; + d3d10_video_t* d3d10 = (d3d10_video_t*)video_info->userdata; if (!d3d10 || !draw || !draw->texture) return; @@ -114,7 +113,8 @@ static void menu_display_d3d10_draw(menu_display_ctx_draw_t *draw, { sprite->pos.x = draw->x / (float)d3d10->viewport.Width; sprite->pos.y = - (d3d10->viewport.Height - draw->y - draw->height) / (float)d3d10->viewport.Height; + (d3d10->viewport.Height - draw->y - draw->height) + / (float)d3d10->viewport.Height; sprite->pos.w = draw->width / (float)d3d10->viewport.Width; sprite->pos.h = draw->height / (float)d3d10->viewport.Height; @@ -188,8 +188,7 @@ static void menu_display_d3d10_draw(menu_display_ctx_draw_t *draw, static void menu_display_d3d10_draw_pipeline(menu_display_ctx_draw_t* draw, video_frame_info_t *video_info) { - d3d10_video_t* d3d10 = video_info ? - (d3d10_video_t*)video_info->userdata : NULL; + d3d10_video_t* d3d10 = (d3d10_video_t*)video_info->userdata; if (!d3d10 || !draw) return; @@ -248,8 +247,7 @@ static void menu_display_d3d10_clear_color( menu_display_ctx_clearcolor_t* clearcolor, video_frame_info_t *video_info) { - d3d10_video_t *d3d10 = video_info ? - (d3d10_video_t*)video_info->userdata : NULL; + d3d10_video_t* d3d10 = (d3d10_video_t*)video_info->userdata; if (!d3d10 || !clearcolor) return; @@ -277,34 +275,32 @@ static bool menu_display_d3d10_font_init_first( void menu_display_d3d10_scissor_begin(video_frame_info_t *video_info, int x, int y, unsigned width, unsigned height) { - D3D10_RECT rect = {0}; - d3d10_video_t *d3d10 = video_info ? - (d3d10_video_t*)video_info->userdata : NULL; - - rect.left = x; - rect.top = y; - rect.right = width + x; - rect.bottom = height + y; + D3D10_RECT rect; + d3d10_video_t *d3d10 = (d3d10_video_t*)video_info->userdata; if (!d3d10 || !width || !height) return; + rect.left = x; + rect.top = y; + rect.right = width + x; + rect.bottom = height + y; + D3D10SetScissorRects(d3d10->device, 1, &rect); } void menu_display_d3d10_scissor_end(video_frame_info_t *video_info) { - D3D10_RECT rect = {0}; - d3d10_video_t *d3d10 = video_info ? - (d3d10_video_t*)video_info->userdata : NULL; + D3D10_RECT rect; + d3d10_video_t *d3d10 = (d3d10_video_t*)video_info->userdata; if (!d3d10) return; - rect.left = d3d10->vp.x; - rect.top = d3d10->vp.y; - rect.right = d3d10->vp.width; - rect.bottom = d3d10->vp.height; + rect.left = d3d10->vp.x; + rect.top = d3d10->vp.y; + rect.right = d3d10->vp.width; + rect.bottom = d3d10->vp.height; D3D10SetScissorRects(d3d10->device, 1, &rect); } diff --git a/menu/drivers_display/menu_display_d3d11.c b/menu/drivers_display/menu_display_d3d11.c index 55ac4fc9fe..043a392392 100644 --- a/menu/drivers_display/menu_display_d3d11.c +++ b/menu/drivers_display/menu_display_d3d11.c @@ -65,8 +65,8 @@ static void menu_display_d3d11_viewport(menu_display_ctx_draw_t *draw, static void menu_display_d3d11_draw(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { - int vertex_count; - d3d11_video_t* d3d11 = video_info ? (d3d11_video_t*)video_info->userdata : NULL; + int vertex_count; + d3d11_video_t *d3d11 = (d3d11_video_t*)video_info->userdata; if (!d3d11 || !draw || !draw->texture) return; @@ -187,8 +187,7 @@ static void menu_display_d3d11_draw(menu_display_ctx_draw_t *draw, static void menu_display_d3d11_draw_pipeline(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { - d3d11_video_t* d3d11 = video_info ? - (d3d11_video_t*)video_info->userdata : NULL; + d3d11_video_t *d3d11 = (d3d11_video_t*)video_info->userdata; if (!d3d11 || !draw) return; @@ -247,8 +246,7 @@ static void menu_display_d3d11_clear_color( menu_display_ctx_clearcolor_t* clearcolor, video_frame_info_t *video_info) { - d3d11_video_t *d3d11 = video_info ? - (d3d11_video_t*)video_info->userdata : NULL; + d3d11_video_t *d3d11 = (d3d11_video_t*)video_info->userdata; if (!d3d11 || !clearcolor) return; @@ -276,34 +274,32 @@ static bool menu_display_d3d11_font_init_first( void menu_display_d3d11_scissor_begin(video_frame_info_t *video_info, int x, int y, unsigned width, unsigned height) { - D3D11_RECT rect = {0}; - d3d11_video_t *d3d11 = video_info ? - (d3d11_video_t*)video_info->userdata : NULL; - - rect.left = x; - rect.top = y; - rect.right = width + x; - rect.bottom = height + y; + D3D11_RECT rect; + d3d11_video_t *d3d11 = (d3d11_video_t*)video_info->userdata; if (!d3d11 || !width || !height) return; + rect.left = x; + rect.top = y; + rect.right = width + x; + rect.bottom = height + y; + D3D11SetScissorRects(d3d11->context, 1, &rect); } void menu_display_d3d11_scissor_end(video_frame_info_t *video_info) { - D3D11_RECT rect = {0}; - d3d11_video_t *d3d11 = video_info ? - (d3d11_video_t*)video_info->userdata : NULL; + D3D11_RECT rect; + d3d11_video_t *d3d11 = (d3d11_video_t*)video_info->userdata; if (!d3d11) return; - rect.left = d3d11->vp.x; - rect.top = d3d11->vp.y; - rect.right = d3d11->vp.width; - rect.bottom = d3d11->vp.height; + rect.left = d3d11->vp.x; + rect.top = d3d11->vp.y; + rect.right = d3d11->vp.width; + rect.bottom = d3d11->vp.height; D3D11SetScissorRects(d3d11->context, 1, &rect); } diff --git a/menu/drivers_display/menu_display_d3d12.c b/menu/drivers_display/menu_display_d3d12.c index e845770724..3a96c215d6 100644 --- a/menu/drivers_display/menu_display_d3d12.c +++ b/menu/drivers_display/menu_display_d3d12.c @@ -67,9 +67,8 @@ static void menu_display_d3d12_viewport(menu_display_ctx_draw_t *draw, static void menu_display_d3d12_draw(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { - int vertex_count; - d3d12_video_t* d3d12 = video_info ? - (d3d12_video_t*)video_info->userdata : NULL; + int vertex_count; + d3d12_video_t *d3d12 = (d3d12_video_t*)video_info->userdata; if (!d3d12 || !draw || !draw->texture) return; @@ -205,8 +204,7 @@ static void menu_display_d3d12_draw(menu_display_ctx_draw_t *draw, static void menu_display_d3d12_draw_pipeline(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { - d3d12_video_t *d3d12 = video_info ? - (d3d12_video_t*)video_info->userdata : NULL; + d3d12_video_t *d3d12 = (d3d12_video_t*)video_info->userdata; if (!d3d12 || !draw) return; @@ -269,7 +267,7 @@ static void menu_display_d3d12_restore_clear_color(void) {} static void menu_display_d3d12_clear_color( menu_display_ctx_clearcolor_t* clearcolor, video_frame_info_t *video_info) { - d3d12_video_t* d3d12 = video_info ? (d3d12_video_t*)video_info->userdata : NULL; + d3d12_video_t *d3d12 = (d3d12_video_t*)video_info->userdata; if (!d3d12 || !clearcolor) return; @@ -297,34 +295,32 @@ static bool menu_display_d3d12_font_init_first( void menu_display_d3d12_scissor_begin(video_frame_info_t *video_info, int x, int y, unsigned width, unsigned height) { - D3D12_RECT rect = {0}; - d3d12_video_t *d3d12 = video_info ? - (d3d12_video_t*)video_info->userdata : NULL; - - rect.left = x; - rect.top = y; - rect.right = width + x; - rect.bottom = height + y; + D3D12_RECT rect; + d3d12_video_t *d3d12 = (d3d12_video_t*)video_info->userdata; if (!d3d12 || !width || !height) return; + rect.left = x; + rect.top = y; + rect.right = width + x; + rect.bottom = height + y; + D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &rect); } void menu_display_d3d12_scissor_end(video_frame_info_t *video_info) { - D3D12_RECT rect = {0}; - d3d12_video_t *d3d12 = video_info ? - (d3d12_video_t*)video_info->userdata : NULL; + D3D12_RECT rect; + d3d12_video_t *d3d12 = (d3d12_video_t*)video_info->userdata; if (!d3d12) return; - rect.left = d3d12->vp.x; - rect.top = d3d12->vp.y; - rect.right = d3d12->vp.width; - rect.bottom = d3d12->vp.height; + rect.left = d3d12->vp.x; + rect.top = d3d12->vp.y; + rect.right = d3d12->vp.width; + rect.bottom = d3d12->vp.height; D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &rect); } diff --git a/menu/drivers_display/menu_display_d3d8.c b/menu/drivers_display/menu_display_d3d8.c index f5189bed91..4e10a5c8a6 100644 --- a/menu/drivers_display/menu_display_d3d8.c +++ b/menu/drivers_display/menu_display_d3d8.c @@ -80,8 +80,7 @@ static INT32 menu_display_prim_to_d3d8_enum( static void menu_display_d3d8_blend_begin(video_frame_info_t *video_info) { - d3d8_video_t *d3d = video_info ? - (d3d8_video_t*)video_info->userdata : NULL; + d3d8_video_t *d3d = (d3d8_video_t*)video_info->userdata; if (!d3d) return; @@ -91,8 +90,7 @@ static void menu_display_d3d8_blend_begin(video_frame_info_t *video_info) static void menu_display_d3d8_blend_end(video_frame_info_t *video_info) { - d3d8_video_t *d3d = video_info ? - (d3d8_video_t*)video_info->userdata : NULL; + d3d8_video_t *d3d = (d3d8_video_t*)video_info->userdata; if (!d3d) return; @@ -123,8 +121,7 @@ static void menu_display_d3d8_draw(menu_display_ctx_draw_t *draw, unsigned i; math_matrix_4x4 mop, m1, m2; unsigned width, height; - d3d8_video_t *d3d = video_info ? - (d3d8_video_t*)video_info->userdata : NULL; + d3d8_video_t *d3d = (d3d8_video_t*)video_info->userdata; Vertex * pv = NULL; const float *vertex = NULL; const float *tex_coord = NULL; @@ -239,9 +236,8 @@ static void menu_display_d3d8_restore_clear_color(void) static void menu_display_d3d8_clear_color( menu_display_ctx_clearcolor_t *clearcolor, video_frame_info_t *video_info) { - DWORD clear_color = 0; - d3d8_video_t *d3d = video_info ? - (d3d8_video_t*)video_info->userdata : NULL; + DWORD clear_color = 0; + d3d8_video_t *d3d = (d3d8_video_t*)video_info->userdata; if (!d3d || !clearcolor) return; diff --git a/menu/drivers_display/menu_display_d3d9.c b/menu/drivers_display/menu_display_d3d9.c index 003afb7062..fc5af5479e 100644 --- a/menu/drivers_display/menu_display_d3d9.c +++ b/menu/drivers_display/menu_display_d3d9.c @@ -80,8 +80,7 @@ static INT32 menu_display_prim_to_d3d9_enum( static void menu_display_d3d9_blend_begin(video_frame_info_t *video_info) { - d3d9_video_t *d3d = video_info ? - (d3d9_video_t*)video_info->userdata : NULL; + d3d9_video_t *d3d = (d3d9_video_t*)video_info->userdata; if (!d3d) return; @@ -91,8 +90,7 @@ static void menu_display_d3d9_blend_begin(video_frame_info_t *video_info) static void menu_display_d3d9_blend_end(video_frame_info_t *video_info) { - d3d9_video_t *d3d = video_info ? - (d3d9_video_t*)video_info->userdata : NULL; + d3d9_video_t *d3d = (d3d9_video_t*)video_info->userdata; if (!d3d) return; @@ -125,8 +123,7 @@ static void menu_display_d3d9_draw(menu_display_ctx_draw_t *draw, math_matrix_4x4 mop, m1, m2; unsigned width, height; LPDIRECT3DDEVICE9 dev; - d3d9_video_t *d3d = video_info ? - (d3d9_video_t*)video_info->userdata : NULL; + d3d9_video_t *d3d = (d3d9_video_t*)video_info->userdata; Vertex * pv = NULL; const float *vertex = NULL; const float *tex_coord = NULL; @@ -142,7 +139,8 @@ static void menu_display_d3d9_draw(menu_display_ctx_draw_t *draw, return; pv = (Vertex*) - d3d9_vertex_buffer_lock((LPDIRECT3DVERTEXBUFFER9)d3d->menu_display.buffer); + d3d9_vertex_buffer_lock((LPDIRECT3DVERTEXBUFFER9) + d3d->menu_display.buffer); if (!pv) return; @@ -180,7 +178,8 @@ static void menu_display_d3d9_draw(menu_display_ctx_draw_t *draw, colors[2] /* B */ ); } - d3d9_vertex_buffer_unlock((LPDIRECT3DVERTEXBUFFER9)d3d->menu_display.buffer); + d3d9_vertex_buffer_unlock((LPDIRECT3DVERTEXBUFFER9) + d3d->menu_display.buffer); if(!draw->matrix_data) draw->matrix_data = menu_display_d3d9_get_default_mvp(video_info); @@ -270,12 +269,12 @@ static void menu_display_d3d9_restore_clear_color(void) } static void menu_display_d3d9_clear_color( - menu_display_ctx_clearcolor_t *clearcolor, video_frame_info_t *video_info) + menu_display_ctx_clearcolor_t *clearcolor, + video_frame_info_t *video_info) { LPDIRECT3DDEVICE9 dev; - DWORD clear_color = 0; - d3d9_video_t *d3d = video_info ? - (d3d9_video_t*)video_info->userdata : NULL; + DWORD clear_color = 0; + d3d9_video_t *d3d = (d3d9_video_t*)video_info->userdata; if (!d3d || !clearcolor) return; @@ -306,36 +305,36 @@ static bool menu_display_d3d9_font_init_first( return true; } -void menu_display_d3d9_scissor_begin(video_frame_info_t *video_info, int x, int y, unsigned width, unsigned height) +void menu_display_d3d9_scissor_begin( + video_frame_info_t *video_info, + int x, int y, unsigned width, unsigned height) { - RECT rect = {0}; - d3d9_video_t *d3d9 = video_info ? - (d3d9_video_t*)video_info->userdata : NULL; - - rect.left = x; - rect.top = y; - rect.right = width + x; - rect.bottom = height + y; + RECT rect; + d3d9_video_t *d3d9 = (d3d9_video_t*)video_info->userdata; if (!d3d9 || !width || !height) return; + rect.left = x; + rect.top = y; + rect.right = width + x; + rect.bottom = height + y; + d3d9_set_scissor_rect(d3d9->dev, &rect); } void menu_display_d3d9_scissor_end(video_frame_info_t *video_info) { - RECT rect = {0}; - d3d9_video_t *d3d9 = video_info ? - (d3d9_video_t*)video_info->userdata : NULL; + RECT rect; + d3d9_video_t *d3d9 = (d3d9_video_t*)video_info->userdata; if (!d3d9) return; - rect.left = d3d9->vp.x; - rect.top = d3d9->vp.y; - rect.right = d3d9->vp.width; - rect.bottom = d3d9->vp.height; + rect.left = d3d9->vp.x; + rect.top = d3d9->vp.y; + rect.right = d3d9->vp.width; + rect.bottom = d3d9->vp.height; d3d9_set_scissor_rect(d3d9->dev, &rect); } diff --git a/menu/drivers_display/menu_display_gl.c b/menu/drivers_display/menu_display_gl.c index 2baa181da4..7e02fe4a09 100644 --- a/menu/drivers_display/menu_display_gl.c +++ b/menu/drivers_display/menu_display_gl.c @@ -52,7 +52,7 @@ static const float *menu_display_gl_get_default_tex_coords(void) static void *menu_display_gl_get_default_mvp(video_frame_info_t *video_info) { - gl_t *gl = video_info ? (gl_t*)video_info->userdata : NULL; + gl_t *gl = (gl_t*)video_info->userdata; if (!gl) return NULL; diff --git a/menu/drivers_display/menu_display_gl1.c b/menu/drivers_display/menu_display_gl1.c index b0099d76f4..7e308015bd 100644 --- a/menu/drivers_display/menu_display_gl1.c +++ b/menu/drivers_display/menu_display_gl1.c @@ -53,7 +53,7 @@ static const float *menu_display_gl1_get_default_tex_coords(void) static void *menu_display_gl1_get_default_mvp(video_frame_info_t *video_info) { - gl1_t *gl1 = video_info ? (gl1_t*)video_info->userdata : NULL; + gl1_t *gl1 = (gl1_t*)video_info->userdata; if (!gl1) return NULL; diff --git a/menu/drivers_display/menu_display_gl_core.c b/menu/drivers_display/menu_display_gl_core.c index c2f9df52d1..8930f76aeb 100644 --- a/menu/drivers_display/menu_display_gl_core.c +++ b/menu/drivers_display/menu_display_gl_core.c @@ -51,7 +51,7 @@ static const float gl_core_colors[] = { static void *menu_display_gl_core_get_default_mvp(video_frame_info_t *video_info) { - gl_core_t *gl_core = video_info ? (gl_core_t*)video_info->userdata : NULL; + gl_core_t *gl_core = (gl_core_t*)video_info->userdata; if (!gl_core) return NULL; return &gl_core->mvp_no_rot; @@ -83,23 +83,23 @@ static void menu_display_gl_core_draw_pipeline(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { #ifdef HAVE_SHADERPIPELINE + float output_size[2]; + static struct video_coords blank_coords; static uint8_t ubo_scratch_data[768]; static float t = 0.0f; float yflip = 0.0f; - static struct video_coords blank_coords; - float output_size[2]; - video_coord_array_t *ca = NULL; - gl_core_t *gl = video_info ? (gl_core_t*)video_info->userdata : NULL; + video_coord_array_t *ca = NULL; + gl_core_t *gl_core = (gl_core_t*)video_info->userdata; - if (!gl || !draw) + if (!gl_core || !draw) return; - draw->x = 0; - draw->y = 0; - draw->matrix_data = NULL; + draw->x = 0; + draw->y = 0; + draw->matrix_data = NULL; - output_size[0] = (float)video_info->width; - output_size[1] = (float)video_info->height; + output_size[0] = (float)video_info->width; + output_size[1] = (float)video_info->height; switch (draw->pipeline.id) { @@ -123,7 +123,8 @@ static void menu_display_gl_core_draw_pipeline(menu_display_ctx_draw_t *draw, case VIDEO_SHADER_MENU_4: case VIDEO_SHADER_MENU_5: draw->pipeline.backend_data = ubo_scratch_data; - draw->pipeline.backend_data_size = sizeof(math_matrix_4x4) + 4 * sizeof(float); + draw->pipeline.backend_data_size = sizeof(math_matrix_4x4) + + 4 * sizeof(float); /* Match UBO layout in shader. */ memcpy(ubo_scratch_data, @@ -138,8 +139,10 @@ static void menu_display_gl_core_draw_pipeline(menu_display_ctx_draw_t *draw, else yflip = 0.0f; - memcpy(ubo_scratch_data + sizeof(math_matrix_4x4) + 2 * sizeof(float), &t, sizeof(t)); - memcpy(ubo_scratch_data + sizeof(math_matrix_4x4) + 3 * sizeof(float), &yflip, sizeof(yflip)); + memcpy(ubo_scratch_data + sizeof(math_matrix_4x4) + + 2 * sizeof(float), &t, sizeof(t)); + memcpy(ubo_scratch_data + sizeof(math_matrix_4x4) + + 3 * sizeof(float), &yflip, sizeof(yflip)); draw->coords = &blank_coords; blank_coords.vertices = 4; draw->prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; @@ -158,7 +161,7 @@ static void menu_display_gl_core_draw(menu_display_ctx_draw_t *draw, const float *color = NULL; struct gl_core_vertex *pv = NULL; GLuint texture = 0; - gl_core_t *gl = video_info ? (gl_core_t*)video_info->userdata : NULL; + gl_core_t *gl = (gl_core_t*)video_info->userdata; const struct gl_core_buffer_locations *loc = NULL; if (!gl || !draw) @@ -228,18 +231,14 @@ static void menu_display_gl_core_draw(menu_display_ctx_draw_t *draw, } if (loc && loc->flat_ubo_vertex >= 0) - { glUniform4fv(loc->flat_ubo_vertex, (GLsizei)((draw->pipeline.backend_data_size + 15) / 16), (const GLfloat*)draw->pipeline.backend_data); - } if (loc && loc->flat_ubo_fragment >= 0) - { glUniform4fv(loc->flat_ubo_fragment, (GLsizei)((draw->pipeline.backend_data_size + 15) / 16), (const GLfloat*)draw->pipeline.backend_data); - } if (!loc) { @@ -298,7 +297,7 @@ static void menu_display_gl_core_clear_color( static void menu_display_gl_core_blend_begin(video_frame_info_t *video_info) { - gl_core_t *gl = video_info ? (gl_core_t*)video_info->userdata : NULL; + gl_core_t *gl = (gl_core_t*)video_info->userdata; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); diff --git a/menu/drivers_display/menu_display_vulkan.c b/menu/drivers_display/menu_display_vulkan.c index b4b6af2f30..081e3291e4 100644 --- a/menu/drivers_display/menu_display_vulkan.c +++ b/menu/drivers_display/menu_display_vulkan.c @@ -121,13 +121,12 @@ static void menu_display_vk_draw_pipeline(menu_display_ctx_draw_t *draw, { #ifdef HAVE_SHADERPIPELINE static uint8_t ubo_scratch_data[768]; - static float t = 0.0f; - float yflip = 0.0f; + static float t = 0.0f; + float yflip = 0.0f; static struct video_coords blank_coords; float output_size[2]; - video_coord_array_t *ca = NULL; - vk_t *vk = video_info ? - (vk_t*)video_info->userdata : NULL; + video_coord_array_t *ca = NULL; + vk_t *vk = (vk_t*)video_info->userdata; if (!vk || !draw) return; @@ -161,7 +160,8 @@ static void menu_display_vk_draw_pipeline(menu_display_ctx_draw_t *draw, case VIDEO_SHADER_MENU_4: case VIDEO_SHADER_MENU_5: draw->pipeline.backend_data = ubo_scratch_data; - draw->pipeline.backend_data_size = sizeof(math_matrix_4x4) + 4 * sizeof(float); + draw->pipeline.backend_data_size = sizeof(math_matrix_4x4) + + 4 * sizeof(float); /* Match UBO layout in shader. */ memcpy(ubo_scratch_data, @@ -177,11 +177,13 @@ static void menu_display_vk_draw_pipeline(menu_display_ctx_draw_t *draw, else yflip = 1.0f; - memcpy(ubo_scratch_data + sizeof(math_matrix_4x4) + 2 * sizeof(float), &t, sizeof(t)); - memcpy(ubo_scratch_data + sizeof(math_matrix_4x4) + 3 * sizeof(float), &yflip, sizeof(yflip)); - draw->coords = &blank_coords; + memcpy(ubo_scratch_data + sizeof(math_matrix_4x4) + + 2 * sizeof(float), &t, sizeof(t)); + memcpy(ubo_scratch_data + sizeof(math_matrix_4x4) + + 3 * sizeof(float), &yflip, sizeof(yflip)); + draw->coords = &blank_coords; blank_coords.vertices = 4; - draw->prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; + draw->prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; break; } @@ -199,8 +201,7 @@ static void menu_display_vk_draw(menu_display_ctx_draw_t *draw, const float *tex_coord = NULL; const float *color = NULL; struct vk_vertex *pv = NULL; - vk_t *vk = video_info ? - (vk_t*)video_info->userdata : NULL; + vk_t *vk = (vk_t*)video_info->userdata; if (!vk || !draw) return; @@ -305,7 +306,7 @@ static void menu_display_vk_clear_color( { VkClearRect rect; VkClearAttachment attachment; - vk_t *vk = video_info ? (vk_t*)video_info->userdata : NULL; + vk_t *vk = (vk_t*)video_info->userdata; if (!vk || !clearcolor) return; @@ -327,7 +328,7 @@ static void menu_display_vk_clear_color( static void menu_display_vk_blend_begin(video_frame_info_t *video_info) { - vk_t *vk = video_info ? (vk_t*)video_info->userdata : NULL; + vk_t *vk = (vk_t*)video_info->userdata; if (vk) vk->display.blend = true; @@ -335,7 +336,7 @@ static void menu_display_vk_blend_begin(video_frame_info_t *video_info) static void menu_display_vk_blend_end(video_frame_info_t *video_info) { - vk_t *vk = video_info ? (vk_t*)video_info->userdata : NULL; + vk_t *vk = (vk_t*)video_info->userdata; if (vk) vk->display.blend = false; @@ -360,7 +361,7 @@ static bool menu_display_vk_font_init_first( static void menu_display_vk_scissor_begin(video_frame_info_t *video_info, int x, int y, unsigned width, unsigned height) { - vk_t *vk = (vk_t*)video_info->userdata; + vk_t *vk = (vk_t*)video_info->userdata; vk->tracker.use_scissor = true; vk->tracker.scissor.offset.x = x; @@ -372,7 +373,8 @@ static void menu_display_vk_scissor_begin(video_frame_info_t *video_info, static void menu_display_vk_scissor_end(video_frame_info_t *video_info) { - vk_t *vk = (vk_t*)video_info->userdata; + vk_t *vk = (vk_t*)video_info->userdata; + vk->tracker.use_scissor = false; vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT; } From 4065dbf18e96b7566160c2270ba8f29f033cec71 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 8 Apr 2019 15:13:19 +0100 Subject: [PATCH 129/237] (Menu Widgets) Fix text alignment issues for ctr, metal and vita2d drivers --- gfx/drivers_font/ctr_font.c | 4 ++-- gfx/drivers_font/metal_raster_font.m | 4 ++-- gfx/drivers_font/vita2d_font.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gfx/drivers_font/ctr_font.c b/gfx/drivers_font/ctr_font.c index 0443204ac5..e3ed3fe89e 100644 --- a/gfx/drivers_font/ctr_font.c +++ b/gfx/drivers_font/ctr_font.c @@ -215,8 +215,8 @@ static void ctr_font_render_line( width = glyph->width; height = glyph->height; - v->x0 = x + off_x + delta_x * scale; - v->y0 = y + off_y + delta_y * scale; + v->x0 = x + (off_x + delta_x) * scale; + v->y0 = y + (off_y + delta_y) * scale; v->u0 = tex_x; v->v0 = tex_y; v->x1 = v->x0 + width * scale; diff --git a/gfx/drivers_font/metal_raster_font.m b/gfx/drivers_font/metal_raster_font.m index 734034c643..49641d9b91 100644 --- a/gfx/drivers_font/metal_raster_font.m +++ b/gfx/drivers_font/metal_raster_font.m @@ -298,8 +298,8 @@ static INLINE void write_quad6(SpriteVertex *pv, height = glyph->height; write_quad6(v, - (x + off_x + delta_x * scale) * inv_win_width, - (y + off_y + delta_y * scale) * inv_win_height, + (x + (off_x + delta_x) * scale) * inv_win_width, + (y + (off_y + delta_y) * scale) * inv_win_height, width * scale * inv_win_width, height * scale * inv_win_height, tex_x * inv_tex_size_x, diff --git a/gfx/drivers_font/vita2d_font.c b/gfx/drivers_font/vita2d_font.c index b333c6ff51..7f5ef08485 100644 --- a/gfx/drivers_font/vita2d_font.c +++ b/gfx/drivers_font/vita2d_font.c @@ -209,8 +209,8 @@ static void vita2d_font_render_line( } vita2d_draw_texture_tint_part_scale(font->texture, - x + off_x + delta_x * scale, - y + off_y + delta_y * scale, + x + (off_x + delta_x) * scale, + y + (off_y + delta_y) * scale, tex_x, tex_y, width, height, scale, scale, From 7a3caf82d0fb1d838cfd456d45767786c292a8fa Mon Sep 17 00:00:00 2001 From: natinusala Date: Mon, 8 Apr 2019 16:33:18 +0200 Subject: [PATCH 130/237] menu widgets: reimplement FPS counter --- gfx/video_driver.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 16fe7def54..5e0c098a09 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -47,6 +47,9 @@ #ifdef HAVE_MENU #include "../menu/menu_driver.h" #include "../menu/menu_setting.h" +#ifdef HAVE_MENU_WIDGETS +#include "../menu/widgets/menu_widgets.h" +#endif #endif #include "video_thread_wrapper.h" @@ -2596,7 +2599,10 @@ void video_driver_frame(const void *data, unsigned width, /* Display the FPS, with a higher priority. */ if (video_info.fps_show || video_info.framecount_show) - runloop_msg_queue_push(video_info.fps_text, 2, 1, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (!video_driver_has_widgets() || !menu_widgets_set_fps_text(video_info.fps_text)) +#endif + runloop_msg_queue_push(video_info.fps_text, 2, 1, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); /* trigger set resolution*/ if (video_info.crt_switch_resolution) From e1838b490882d38abad61bb1866b83a3de928115 Mon Sep 17 00:00:00 2001 From: natinusala Date: Mon, 8 Apr 2019 16:39:30 +0200 Subject: [PATCH 131/237] Add more Windows MINGW working directory stuff to gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 89245c82ea..f5b1883eb7 100644 --- a/.gitignore +++ b/.gitignore @@ -76,6 +76,10 @@ convert_rumble.awk *~ assets info +content_image_history.lpl +saves +screenshots + # Wii U *.depend From 3d52f2bf8f9f489cd99a49d1d2e773e5d9b23f6c Mon Sep 17 00:00:00 2001 From: natinusala Date: Mon, 8 Apr 2019 16:39:50 +0200 Subject: [PATCH 132/237] menu widgets: reimplement screenshot widget --- tasks/task_screenshot.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tasks/task_screenshot.c b/tasks/task_screenshot.c index ebf172be46..e2a229db23 100644 --- a/tasks/task_screenshot.c +++ b/tasks/task_screenshot.c @@ -43,6 +43,10 @@ #define IMG_EXT "bmp" #endif +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) +#include "../../menu/widgets/menu_widgets.h" +#endif + #include "../defaults.h" #include "../command.h" #include "../configuration.h" @@ -126,6 +130,11 @@ static bool screenshot_dump_direct(screenshot_task_state_t *state) bmp_type); #endif +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (!state->silence) + menu_widgets_screenshot_taken(state->shotname, state->filename); +#endif + return ret; } @@ -290,6 +299,11 @@ static bool screenshot_dump( if (use_thread) { +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (video_driver_has_widgets()) + task_free_title(task); + else +#endif if (!savestate) task->title = strdup(msg_hash_to_str(MSG_TAKING_SCREENSHOT)); @@ -444,6 +458,11 @@ bool take_screenshot(const char *name_base, bool silence, bool has_valid_framebu bool is_perfcnt_enable = false; bool ret = false; +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (!silence) + menu_widgets_take_screenshot(); +#endif + runloop_get_status(&is_paused, &is_idle, &is_slowmotion, &is_perfcnt_enable); ret = take_screenshot_choice(name_base, silence, is_paused, is_idle, From b750199db4f0f17a0569a23a1d1201806f398f57 Mon Sep 17 00:00:00 2001 From: natinusala Date: Mon, 8 Apr 2019 16:44:21 +0200 Subject: [PATCH 133/237] menu widgets: reimplement pause widget --- command.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/command.c b/command.c index be515931d2..f9b2095aa3 100755 --- a/command.c +++ b/command.c @@ -59,6 +59,9 @@ #include "menu/menu_content.h" #include "menu/menu_shader.h" #include "menu/widgets/menu_dialog.h" +#ifdef HAVE_MENU_WIDGETS +#include "menu/widgets/menu_widgets.h" +#endif #endif #ifdef HAVE_NETWORKING @@ -2488,6 +2491,9 @@ TODO: Add a setting for these tweaks */ RARCH_LOG("%s\n", msg_hash_to_str(MSG_PAUSED)); command_event(CMD_EVENT_AUDIO_STOP, NULL); +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (!video_driver_has_widgets() || !menu_widgets_set_paused(is_paused)) +#endif runloop_msg_queue_push(msg_hash_to_str(MSG_PAUSED), 1, 1, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); @@ -2502,6 +2508,10 @@ TODO: Add a setting for these tweaks */ } else { +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (video_driver_has_widgets()) + menu_widgets_set_paused(is_paused); +#endif RARCH_LOG("%s\n", msg_hash_to_str(MSG_UNPAUSED)); command_event(CMD_EVENT_AUDIO_START, NULL); } From 5667c73ebfafd044ec7066ef040507c1baac4a0b Mon Sep 17 00:00:00 2001 From: natinusala Date: Mon, 8 Apr 2019 16:47:06 +0200 Subject: [PATCH 134/237] menu widgets: reimplement rewind widget --- retroarch.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/retroarch.c b/retroarch.c index cc9389e266..9fe5611a4b 100644 --- a/retroarch.c +++ b/retroarch.c @@ -4137,10 +4137,20 @@ static enum runloop_state runloop_check_state( s[0] = '\0'; - if (state_manager_check_rewind(BIT256_GET(current_input, RARCH_REWIND), - settings->uints.rewind_granularity, runloop_is_paused, s, sizeof(s), &t)) - runloop_msg_queue_push(s, 0, t, true, NULL, - MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + bool rewinding = state_manager_check_rewind(BIT256_GET(current_input, RARCH_REWIND), + settings->uints.rewind_granularity, runloop_paused, s, sizeof(s), &t); + +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (!video_driver_has_widgets()) +#endif + if (state_manager_check_rewind(BIT256_GET(current_input, RARCH_REWIND), + settings->uints.rewind_granularity, runloop_is_paused, s, sizeof(s), &t)) + runloop_msg_queue_push(s, 0, t, true, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + menu_widgets_set_rewind(rewinding); +#endif } /* Checks if slowmotion toggle/hold was being pressed and/or held. */ From 7a7f444e55a0501746ff6892781819731ca61020 Mon Sep 17 00:00:00 2001 From: natinusala Date: Mon, 8 Apr 2019 16:49:15 +0200 Subject: [PATCH 135/237] menu widgets: reimplement fast forward widget --- retroarch.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/retroarch.c b/retroarch.c index 9fe5611a4b..a67947d0f6 100644 --- a/retroarch.c +++ b/retroarch.c @@ -4048,8 +4048,17 @@ static enum runloop_state runloop_check_state( /* Display the fast forward state to the user, if needed. */ if (runloop_fastmotion) - runloop_msg_queue_push( - msg_hash_to_str(MSG_FAST_FORWARD), 1, 1, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + { +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (!video_driver_has_widgets() || !menu_widgets_set_fast_forward(true)) +#endif + runloop_msg_queue_push( + msg_hash_to_str(MSG_FAST_FORWARD), 1, 1, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + } +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + else + menu_widgets_set_fast_forward(false); +#endif old_button_state = new_button_state; old_hold_button_state = new_hold_button_state; From f036ce442ef562899d10c6e85ff0c58e14a47d91 Mon Sep 17 00:00:00 2001 From: natinusala Date: Mon, 8 Apr 2019 16:55:03 +0200 Subject: [PATCH 136/237] menu widgets: reimplement slowmotion --- retroarch.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/retroarch.c b/retroarch.c index a67947d0f6..b1e111f810 100644 --- a/retroarch.c +++ b/retroarch.c @@ -4195,15 +4195,22 @@ static enum runloop_state runloop_check_state( if (!runloop_idle) video_driver_cached_frame(); - if (state_manager_frame_is_reversed()) - runloop_msg_queue_push( - msg_hash_to_str(MSG_SLOW_MOTION_REWIND), 1, 1, false, NULL, - MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - else - runloop_msg_queue_push( - msg_hash_to_str(MSG_SLOW_MOTION), 1, 1, false, - NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (!video_driver_has_widgets()) + { +#endif + if (state_manager_frame_is_reversed()) + runloop_msg_queue_push( + msg_hash_to_str(MSG_SLOW_MOTION_REWIND), 1, 1, false, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + else + runloop_msg_queue_push( + msg_hash_to_str(MSG_SLOW_MOTION), 1, 1, false, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + } +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) } +#endif old_slowmotion_button_state = new_slowmotion_button_state; old_slowmotion_hold_button_state = new_slowmotion_hold_button_state; From fba6f69d7489020f12977330e39d48bd79c8d08a Mon Sep 17 00:00:00 2001 From: natinusala Date: Mon, 8 Apr 2019 17:01:02 +0200 Subject: [PATCH 137/237] menu widgets: reimplement volume widget --- command.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/command.c b/command.c index f9b2095aa3..31879c9adb 100755 --- a/command.c +++ b/command.c @@ -974,7 +974,10 @@ static void command_event_set_volume(float gain) msg_hash_to_str(MSG_AUDIO_VOLUME), new_volume); - runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (!video_driver_has_widgets() || !menu_widgets_volume_update_and_show()) +#endif + runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); RARCH_LOG("%s\n", msg); @@ -2107,9 +2110,11 @@ TODO: Add a setting for these tweaks */ return false; } - runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (!video_driver_has_widgets() || !menu_widgets_volume_update_and_show()) +#endif + runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - RARCH_LOG("%s\n", msg); } break; case CMD_EVENT_SEND_DEBUG_INFO: From 55d0701ac1e784d77ffca42b37c1549042415cf1 Mon Sep 17 00:00:00 2001 From: natinusala Date: Mon, 8 Apr 2019 17:04:47 +0200 Subject: [PATCH 138/237] menu widgets: remove qb notice --- qb/config.libs.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 7b189c1e15..80297d8d6d 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -507,11 +507,6 @@ if [ "$HAVE_MENU" != 'no' ]; then fi fi -if [ "$HAVE_MENU_WIDGETS" != 'no' ]; then - die : 'Notice: Menu widgets are not fully implemented and should not be enabled' \ - 'Please do not report any bug concerning widgets until this message is removed' -fi - check_macro NEON __ARM_NEON__ add_define MAKEFILE OS "$OS" From 38d2febba50c129c4453c6448b70210ea60a69b5 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 8 Apr 2019 17:36:02 +0100 Subject: [PATCH 139/237] Fix text alignment when using stb_unicode --- gfx/drivers_font_renderer/stb_unicode.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/gfx/drivers_font_renderer/stb_unicode.c b/gfx/drivers_font_renderer/stb_unicode.c index 72c925b14a..aa74e1b8f5 100644 --- a/gfx/drivers_font_renderer/stb_unicode.c +++ b/gfx/drivers_font_renderer/stb_unicode.c @@ -66,6 +66,13 @@ typedef struct unsigned usage_counter; } stb_unicode_font_renderer_t; +/* Ugly little thing... */ +static int INLINE round_away_from_zero(float f) +{ + double round = (f < 0.0) ? floor((double)f) : ceil((double)f); + return (int)round; +} + static struct font_atlas *font_renderer_stb_unicode_get_atlas(void *data) { stb_unicode_font_renderer_t *self = (stb_unicode_font_renderer_t*)data; @@ -153,10 +160,10 @@ static const struct font_glyph *font_renderer_stb_unicode_get_glyph( atlas_slot->glyph.width = self->max_glyph_width; atlas_slot->glyph.height = self->max_glyph_height; - atlas_slot->glyph.advance_x = advance_width * self->scale_factor; - /* atlas_slot->glyph.advance_y = 0 ; */ - atlas_slot->glyph.draw_offset_x = x0 * self->scale_factor; - atlas_slot->glyph.draw_offset_y = -y1 * self->scale_factor; + atlas_slot->glyph.advance_x = round_away_from_zero((float)advance_width * self->scale_factor); + atlas_slot->glyph.advance_y = 0; + atlas_slot->glyph.draw_offset_x = round_away_from_zero((float)x0 * self->scale_factor); + atlas_slot->glyph.draw_offset_y = round_away_from_zero((float)(-y1) * self->scale_factor); self->atlas.dirty = true; atlas_slot->last_used = self->usage_counter++; @@ -177,7 +184,7 @@ static bool font_renderer_stb_unicode_create_atlas( self->atlas.height = self->max_glyph_height * STB_UNICODE_ATLAS_ROWS; self->atlas.buffer = (uint8_t*) - calloc(self->atlas.width * self->atlas.height, 1); + calloc(self->atlas.width * self->atlas.height, sizeof(uint8_t)); if (!self->atlas.buffer) return false; From c12e8dea07f5c60d6101e6c9ed5ab0a1f47ffbb8 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 8 Apr 2019 18:42:52 +0200 Subject: [PATCH 140/237] (D3D10/11) All struct members are already being set --- gfx/drivers/d3d10.c | 8 ++++---- gfx/drivers/d3d11.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index 89b483b2bc..abf0d1e2c3 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -76,11 +76,11 @@ d3d10_overlay_vertex_geom(void* data, unsigned index, float x, float y, float w, static void d3d10_clear_scissor(d3d10_video_t *d3d10, video_frame_info_t *video_info) { - D3D10_RECT scissor_rect = {0}; + D3D10_RECT scissor_rect; - scissor_rect.left = 0; - scissor_rect.top = 0; - scissor_rect.right = video_info->width; + scissor_rect.left = 0; + scissor_rect.top = 0; + scissor_rect.right = video_info->width; scissor_rect.bottom = video_info->height; D3D10SetScissorRects(d3d10->device, 1, &scissor_rect); diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 027e3d5ad5..63c197ba07 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -93,11 +93,11 @@ d3d11_overlay_vertex_geom(void* data, unsigned index, float x, float y, float w, static void d3d11_clear_scissor(d3d11_video_t *d3d11, video_frame_info_t *video_info) { - D3D11_RECT scissor_rect = {0}; + D3D11_RECT scissor_rect; - scissor_rect.left = 0; - scissor_rect.top = 0; - scissor_rect.right = video_info->width; + scissor_rect.left = 0; + scissor_rect.top = 0; + scissor_rect.right = video_info->width; scissor_rect.bottom = video_info->height; D3D11SetScissorRects(d3d11->context, 1, &scissor_rect); From 0af7167586576a7c3bfedaae0f37f7bdb595befb Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 8 Apr 2019 18:58:04 +0200 Subject: [PATCH 141/237] (GL1) Add menu widgets support --- gfx/drivers/gl1.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/gfx/drivers/gl1.c b/gfx/drivers/gl1.c index 900bd418e8..245cb54e65 100644 --- a/gfx/drivers/gl1.c +++ b/gfx/drivers/gl1.c @@ -34,6 +34,9 @@ #ifdef HAVE_MENU #include "../../menu/menu_driver.h" +#ifdef HAVE_MENU_WIDGETS +#include "../../menu/widgets/menu_widgets.h" +#endif #endif #include "../font_driver.h" @@ -716,6 +719,10 @@ static bool gl1_gfx_frame(void *data, const void *frame, #ifdef HAVE_MENU if (gl1->menu_texture_enable) menu_driver_frame(video_info); + +#ifdef HAVE_MENU_WIDGETS + menu_widgets_frame(video_info); +#endif #endif #ifdef HAVE_OVERLAY @@ -1258,6 +1265,14 @@ static void gl1_gfx_get_poke_interface(void *data, *iface = &gl1_poke_interface; } +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) +static bool gl1_menu_widgets_enabled(void *data) +{ + (void)data; + return true; +} +#endif + static void gl1_gfx_set_viewport_wrapper(void *data, unsigned viewport_width, unsigned viewport_height, bool force_full, bool allow_rotate) { @@ -1522,6 +1537,6 @@ video_driver_t video_gl1 = { gl1_gfx_get_poke_interface, gl1_wrap_type_to_enum, #if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) - NULL + gl1_menu_widgets_enabled #endif }; From 8d7a0117bc129cdc53b800ce63457fa0df82171b Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 8 Apr 2019 19:17:51 +0200 Subject: [PATCH 142/237] (Metal RA) Exclude OpenGL from Metal build --- .../RetroArch_Metal.xcodeproj/project.pbxproj | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj index 589f6f1295..275803dad1 100644 --- a/pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj @@ -1703,6 +1703,17 @@ "@executable_path/../Frameworks", ); MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + OTHER_CFLAGS = ( + "$(inherited)", + "$(QT_CFLAGS)", + "-UHAVE_GLSL", + "-UHAVE_OPENGL", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-UHAVE_GLSL", + "-UHAVE_OPENGL", + ); PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; PRODUCT_BUNDLE_IDENTIFIER = libretro.RetroArch; PRODUCT_NAME = RetroArch; @@ -1723,6 +1734,17 @@ "$(inherited)", "@executable_path/../Frameworks", ); + OTHER_CFLAGS = ( + "$(inherited)", + "$(QT_CFLAGS)", + "-UHAVE_GLSL", + "-UHAVE_OPENGL", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-UHAVE_GLSL", + "-UHAVE_OPENGL", + ); PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; PRODUCT_BUNDLE_IDENTIFIER = libretro.RetroArch; PRODUCT_NAME = RetroArch; @@ -1742,6 +1764,18 @@ GCC_OPTIMIZATION_LEVEL = 0; INSTALL_PATH = "$(HOME)/Applications"; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + OTHER_CFLAGS = ( + "$(inherited)", + "-DHAVE_MAIN", + "-DHAVE_COCOA_METAL", + "-UHAVE_GLSL", + "-UHAVE_OPENGL", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-UHAVE_OPENGL", + "-UHAVE_GLSL", + ); PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; PRODUCT_BUNDLE_IDENTIFIER = "libretro.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = RetroArch; @@ -1758,6 +1792,18 @@ GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; INSTALL_PATH = "$(HOME)/Applications"; + OTHER_CFLAGS = ( + "$(inherited)", + "-DHAVE_MAIN", + "-DHAVE_COCOA_METAL", + "-UHAVE_GLSL", + "-UHAVE_OPENGL", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-UHAVE_OPENGL", + "-UHAVE_GLSL", + ); PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; PRODUCT_BUNDLE_IDENTIFIER = "libretro.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = RetroArch; From d6dfa240c83c62ce4c914cb98bf3ae81b0aa78f8 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 8 Apr 2019 19:36:44 +0200 Subject: [PATCH 143/237] Some cleanups --- cores/libretro-gong/gong.c | 6 +++--- libretro-common/encodings/encoding_crc32.c | 4 ++-- retroarch.c | 3 +-- runtime_file.c | 6 +++--- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/cores/libretro-gong/gong.c b/cores/libretro-gong/gong.c index 58dbfd3f16..61833075fc 100644 --- a/cores/libretro-gong/gong.c +++ b/cores/libretro-gong/gong.c @@ -393,11 +393,11 @@ void GONG_CORE_PREFIX(retro_init)(void) else GONG_CORE_PREFIX(log_cb) = NULL; - video_buf = (unsigned char*)calloc(1, WIDTH * HEIGHT * sizeof(unsigned)); + video_buf = (unsigned char*)calloc(1, WIDTH * HEIGHT * sizeof(unsigned char)); - game_buffer.width = WIDTH; + game_buffer.width = WIDTH; game_buffer.height = HEIGHT; - game_buffer.pitch = WIDTH * sizeof(unsigned); + game_buffer.pitch = WIDTH * sizeof(unsigned); game_buffer.memory = video_buf; } diff --git a/libretro-common/encodings/encoding_crc32.c b/libretro-common/encodings/encoding_crc32.c index 9724f3eff7..38b3de2545 100644 --- a/libretro-common/encodings/encoding_crc32.c +++ b/libretro-common/encodings/encoding_crc32.c @@ -119,8 +119,8 @@ uint32_t file_crc32(uint32_t crc, const char *path) for(i = 0; i < CRC32_MAX_MB; i++) { - int nread = filestream_read(file, buf, CRC32_BUFFER_SIZE); - if (nread < 0) + int64_t nread = filestream_read(file, buf, CRC32_BUFFER_SIZE); + if (nread < 0) goto error; crc = encoding_crc32(crc, buf, nread); diff --git a/retroarch.c b/retroarch.c index b1e111f810..deecbe8159 100644 --- a/retroarch.c +++ b/retroarch.c @@ -4152,8 +4152,7 @@ static enum runloop_state runloop_check_state( #if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) if (!video_driver_has_widgets()) #endif - if (state_manager_check_rewind(BIT256_GET(current_input, RARCH_REWIND), - settings->uints.rewind_granularity, runloop_is_paused, s, sizeof(s), &t)) + if (rewinding) runloop_msg_queue_push(s, 0, t, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); diff --git a/runtime_file.c b/runtime_file.c index b2125a1bbb..ffeb9cd9df 100644 --- a/runtime_file.c +++ b/runtime_file.c @@ -775,9 +775,9 @@ void runtime_log_convert_hms2usec(unsigned hours, unsigned minutes, unsigned sec /* Convert from microseconds to hours, minutes, seconds */ void runtime_log_convert_usec2hms(retro_time_t usec, unsigned *hours, unsigned *minutes, unsigned *seconds) { - *seconds = usec / 1000000; - *minutes = *seconds / 60; - *hours = *minutes / 60; + *seconds = usec / 1000000; + *minutes = *seconds / 60; + *hours = *minutes / 60; *seconds -= *minutes * 60; *minutes -= *hours * 60; From e206230a8930749238ffff29388e492229b25e24 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 8 Apr 2019 20:12:22 +0200 Subject: [PATCH 144/237] (Linux) Use STB unicode font renderer for Linux --- gfx/font_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/font_driver.c b/gfx/font_driver.c index 3f433e2a4e..0c84999394 100644 --- a/gfx/font_driver.c +++ b/gfx/font_driver.c @@ -34,7 +34,7 @@ static const font_renderer_driver_t *font_backends[] = { &coretext_font_renderer, #endif #ifdef HAVE_STB_FONT -#if defined(VITA) || defined(WIIU) || defined(ANDROID) || defined(_WIN32) && !defined(_XBOX) && !defined(_MSC_VER) || (defined(_WIN32) && !defined(_XBOX) && defined(_MSC_VER) && _MSC_VER > 1400) || defined(__CELLOS_LV2__) || defined(HAVE_LIBNX) || defined (HAVE_EMSCRIPTEN) +#if defined(VITA) || defined(WIIU) || defined(ANDROID) || defined(_WIN32) && !defined(_XBOX) && !defined(_MSC_VER) || (defined(_WIN32) && !defined(_XBOX) && defined(_MSC_VER) && _MSC_VER > 1400) || defined(__CELLOS_LV2__) || defined(HAVE_LIBNX) || defined(__linux__) || defined (HAVE_EMSCRIPTEN) &stb_unicode_font_renderer, #else &stb_font_renderer, From 3199edcde20450484c6da7db76cbd8edd08a6637 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 8 Apr 2019 20:48:47 +0200 Subject: [PATCH 145/237] (MSVC 2005) Buildfix --- retroarch.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/retroarch.c b/retroarch.c index deecbe8159..a60d7efcd7 100644 --- a/retroarch.c +++ b/retroarch.c @@ -4142,11 +4142,12 @@ static enum runloop_state runloop_check_state( #endif { char s[128]; - unsigned t = 0; + bool rewinding = false; + unsigned t = 0; - s[0] = '\0'; + s[0] = '\0'; - bool rewinding = state_manager_check_rewind(BIT256_GET(current_input, RARCH_REWIND), + rewinding = state_manager_check_rewind(BIT256_GET(current_input, RARCH_REWIND), settings->uints.rewind_granularity, runloop_paused, s, sizeof(s), &t); #if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) From f82601c4a8bab91d99d086c9dc158b84cd9423e4 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 8 Apr 2019 21:17:13 +0200 Subject: [PATCH 146/237] glcore: Fix GLES build. --- gfx/drivers/gl_core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gfx/drivers/gl_core.c b/gfx/drivers/gl_core.c index 63528444a3..06bab7604e 100644 --- a/gfx/drivers/gl_core.c +++ b/gfx/drivers/gl_core.c @@ -2008,7 +2008,13 @@ static unsigned gl_core_wrap_type_to_enum(enum gfx_wrap_type type) switch (type) { case RARCH_WRAP_BORDER: +#ifdef HAVE_OPENGLES3 + /* GLES does not support CLAMP_TO_BORDER until GLES 3.2. + * It is a deprecated feature in general. */ + return GL_CLAMP_TO_EDGE; +#else return GL_CLAMP_TO_BORDER; +#endif case RARCH_WRAP_EDGE: return GL_CLAMP_TO_EDGE; case RARCH_WRAP_REPEAT: @@ -2016,7 +2022,7 @@ static unsigned gl_core_wrap_type_to_enum(enum gfx_wrap_type type) case RARCH_WRAP_MIRRORED_REPEAT: return GL_MIRRORED_REPEAT; default: - break; + break; } return 0; From b25c571b23d270eaf1ea4bc0c4f487aae7189db1 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 8 Apr 2019 22:25:35 +0200 Subject: [PATCH 147/237] Comment out asserts that can be triggered when launching MaterialUI in fullscreen mode --- deps/stb/stb_truetype.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/deps/stb/stb_truetype.h b/deps/stb/stb_truetype.h index 7c67a1fc28..5798c45658 100644 --- a/deps/stb/stb_truetype.h +++ b/deps/stb/stb_truetype.h @@ -1876,6 +1876,7 @@ static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edg y1 = e->ey; } +#if 0 if (x0 == x) assert(x1 <= x+1); else if (x0 == x+1) @@ -1886,13 +1887,16 @@ static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edg assert(x1 >= x+1); else assert(x1 >= x && x1 <= x+1); +#endif if (x0 <= x && x1 <= x) scanline[x] += e->direction * (y1-y0); else if (x0 >= x+1 && x1 >= x+1) ; else { +#if 0 assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1); +#endif scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); /* coverage = 1 - average x position */ } } From 076a0d2f566ddaf2537a088f2fb8a30ef6e37d8c Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 8 Apr 2019 23:13:39 +0200 Subject: [PATCH 148/237] (OSX) Code analysis cleanups --- libretro-common/lists/file_list.c | 2 +- menu/cbs/menu_cbs_ok.c | 17 ++++++++--------- menu/drivers/ozone/ozone_sidebar.c | 10 ++++------ menu/drivers/rgui.c | 10 +++------- menu/menu_animation.c | 6 +++--- menu/menu_displaylist.c | 2 +- playlist.c | 16 ++-------------- runtime_file.c | 2 +- 8 files changed, 23 insertions(+), 42 deletions(-) diff --git a/libretro-common/lists/file_list.c b/libretro-common/lists/file_list.c index 2d7780cab6..a4bd5a9b78 100644 --- a/libretro-common/lists/file_list.c +++ b/libretro-common/lists/file_list.c @@ -116,7 +116,7 @@ bool file_list_insert(file_list_t *list, free(copy); } - file_list_add(list, idx, path, label, type, + file_list_add(list, (unsigned)idx, path, label, type, directory_ptr, entry_idx); return true; diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 6e83490a12..fc15653320 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -1279,11 +1279,9 @@ static int generic_action_ok_command(enum event_command cmd) /* TO-DO: Localization for errors */ static bool file_copy(const char *src_path, const char *dst_path, char *msg, size_t size) { - RFILE *src, *dst; - int numr, numw; - bool ret = true; - - src = filestream_open(src_path, + RFILE *dst = NULL; + bool ret = true; + RFILE *src = filestream_open(src_path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); @@ -1305,8 +1303,9 @@ static bool file_copy(const char *src_path, const char *dst_path, char *msg, siz while (!filestream_eof(src)) { + int64_t numw; char buffer[100] = {0}; - numr = filestream_read(src, buffer, sizeof(buffer)); + int64_t numr = filestream_read(src, buffer, sizeof(buffer)); if (filestream_error(dst) != 0) { @@ -4954,13 +4953,13 @@ static int action_ok_push_dropdown_item_resolution(const char *path, pch = strtok(str, "x"); if (pch) - width = strtoul(pch, NULL, 0); + width = (unsigned)strtoul(pch, NULL, 0); pch = strtok(NULL, " "); if (pch) - height = strtoul(pch, NULL, 0); + height = (unsigned)strtoul(pch, NULL, 0); pch = strtok(NULL, "("); if (pch) - refreshrate = strtoul(pch, NULL, 0); + refreshrate = (unsigned)strtoul(pch, NULL, 0); if (video_display_server_set_resolution(width, height, refreshrate, (float)refreshrate, 0, 0, 0)) diff --git a/menu/drivers/ozone/ozone_sidebar.c b/menu/drivers/ozone/ozone_sidebar.c index bafe6f5cd7..aa0d6d08d8 100644 --- a/menu/drivers/ozone/ozone_sidebar.c +++ b/menu/drivers/ozone/ozone_sidebar.c @@ -116,15 +116,13 @@ void ozone_draw_sidebar(ozone_handle_t *ozone, video_frame_info_t *video_info) uint32_t text_alpha = ozone->animations.sidebar_text_alpha * 255.0f; /* Initial ticker configuration */ - ticker.type_enum = (enum menu_animation_ticker_type)settings->uints.menu_ticker_type; - ticker.spacer = ticker_spacer; + ticker.type_enum = (enum menu_animation_ticker_type)settings->uints.menu_ticker_type; + ticker.spacer = ticker_spacer; selection_y = 0; selection_old_y = 0; horizontal_list_size = 0; - entry_width = 0; - if (!ozone->draw_sidebar) return; @@ -150,14 +148,14 @@ void ozone_draw_sidebar(ozone_handle_t *ozone, video_frame_info_t *video_info) { if (i == ozone->categories_selection_ptr) { - selection_y = y; + selection_y = (unsigned)y; if (ozone->categories_selection_ptr > ozone->system_tab_end) selection_y += ozone->dimensions.sidebar_entry_padding_vertical + 1; } if (i == ozone->categories_active_idx_old) { - selection_old_y = y; + selection_old_y = (unsigned)y; if (ozone->categories_active_idx_old > ozone->system_tab_end) selection_old_y += ozone->dimensions.sidebar_entry_padding_vertical + 1; } diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 6a3b549030..f46fe877a4 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -1891,8 +1891,8 @@ static void rgui_render(void *data, bool is_idle) ticker.selected = true; menu_animation_ticker(&ticker); - title_width = utf8len(thumbnail_title_buf) * FONT_WIDTH_STRIDE; - title_x = RGUI_TERM_START_X(fb_width) + ((RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE) - title_width) / 2; + title_width = (unsigned)(utf8len(thumbnail_title_buf) * FONT_WIDTH_STRIDE); + title_x = RGUI_TERM_START_X(fb_width) + ((RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE) - title_width) / 2; /* Draw thumbnail title background */ rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, @@ -2159,7 +2159,6 @@ static void rgui_render(void *data, bool is_idle) time_t current_time; struct tm * time_info; char timedate[16]; - int n; timedate[0] = '\0'; @@ -2172,12 +2171,9 @@ static void rgui_render(void *data, bool is_idle) if (time_info) { - n = snprintf(timedate, sizeof(timedate), "%02u:%02u", + snprintf(timedate, sizeof(timedate), "%02u:%02u", (unsigned)time_info->tm_hour, (unsigned)time_info->tm_min); - if ((n < 0) || (n >= 16)) - n = 0; /* Silence GCC warnings... */ - blit_line( timedate_x, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + diff --git a/menu/menu_animation.c b/menu/menu_animation.c index 3a1bbb5598..6d8728bbc5 100644 --- a/menu/menu_animation.c +++ b/menu/menu_animation.c @@ -356,7 +356,7 @@ static void menu_animation_ticker_loop(uint64_t idx, /* String 1 */ offset = (phase < (int)str_width) ? phase : 0; - width = str_width - phase; + width = (int)(str_width - phase); width = (width < 0) ? 0 : width; width = (width > (int)max_width) ? max_width : width; @@ -364,9 +364,9 @@ static void menu_animation_ticker_loop(uint64_t idx, *width1 = width; /* String 2 */ - offset = phase - str_width; + offset = (int)(phase - str_width); offset = offset < 0 ? 0 : offset; - width = max_width - *width1; + width = (int)(max_width - *width1); width = (width > (int)spacer_width) ? spacer_width : width; width = width - offset; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 092474c02e..0aa0b97034 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -2302,7 +2302,7 @@ static int menu_displaylist_parse_settings_internal(void *data, (entry_type >= MENU_SETTINGS_INPUT_BEGIN) && (entry_type < MENU_SETTINGS_INPUT_END) ) - entry_type = MENU_SETTINGS_INPUT_BEGIN + count; + entry_type = (unsigned)(MENU_SETTINGS_INPUT_BEGIN + count); if (entry_type == 0) entry_type = menu_setting_set_flags(setting); diff --git a/playlist.c b/playlist.c index 9410fcfb36..459f27586f 100644 --- a/playlist.c +++ b/playlist.c @@ -1104,9 +1104,7 @@ static JSON_Parser_HandlerResult JSONStartArrayHandler(JSON_Parser parser) if (pCtx->object_depth == 1) { if (string_is_equal(pCtx->current_meta_string, "items") && pCtx->array_depth == 1) - { pCtx->in_items = true; - } } return JSON_Parser_Continue; @@ -1144,14 +1142,10 @@ static JSON_Parser_HandlerResult JSONStartObjectHandler(JSON_Parser parser) if (pCtx->array_depth == 1) { if (pCtx->playlist->size < pCtx->playlist->cap) - { pCtx->current_entry = &pCtx->playlist->entries[pCtx->playlist->size]; - } else - { /* hit max item limit */ return JSON_Parser_Abort; - } } } @@ -1165,9 +1159,7 @@ static JSON_Parser_HandlerResult JSONEndObjectHandler(JSON_Parser parser) if (pCtx->in_items && pCtx->object_depth == 2) { if (pCtx->array_depth == 1) - { pCtx->playlist->size++; - } } retro_assert(pCtx->object_depth > 0); @@ -1229,13 +1221,9 @@ static JSON_Parser_HandlerResult JSONNumberHandler(JSON_Parser parser, char *pVa if (pCtx->array_depth == 1) { if (pCtx->current_entry_int_val && length && !string_is_empty(pValue)) - { - *pCtx->current_entry_int_val = strtoul(pValue, NULL, 10); - } + *pCtx->current_entry_int_val = (int)strtoul(pValue, NULL, 10); else if (pCtx->current_entry_uint_val && length && !string_is_empty(pValue)) - { - *pCtx->current_entry_uint_val = strtoul(pValue, NULL, 10); - } + *pCtx->current_entry_uint_val = (unsigned)strtoul(pValue, NULL, 10); else { /* must be a value for an unknown member we aren't tracking, skip it */ diff --git a/runtime_file.c b/runtime_file.c index ffeb9cd9df..ea524c4d3a 100644 --- a/runtime_file.c +++ b/runtime_file.c @@ -775,7 +775,7 @@ void runtime_log_convert_hms2usec(unsigned hours, unsigned minutes, unsigned sec /* Convert from microseconds to hours, minutes, seconds */ void runtime_log_convert_usec2hms(retro_time_t usec, unsigned *hours, unsigned *minutes, unsigned *seconds) { - *seconds = usec / 1000000; + *seconds = (unsigned)(usec / 1000000); *minutes = *seconds / 60; *hours = *minutes / 60; From 136762f6a2829161bf9218c4bac0b37cbd5d338e Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Tue, 9 Apr 2019 15:51:33 +0100 Subject: [PATCH 149/237] Fix text display issues when using Japanese (and other unicode-dependent language) text with stb_unicode --- gfx/drivers_font_renderer/stb_unicode.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/gfx/drivers_font_renderer/stb_unicode.c b/gfx/drivers_font_renderer/stb_unicode.c index aa74e1b8f5..075490f577 100644 --- a/gfx/drivers_font_renderer/stb_unicode.c +++ b/gfx/drivers_font_renderer/stb_unicode.c @@ -152,11 +152,22 @@ static const struct font_glyph *font_renderer_stb_unicode_get_glyph( dst = (uint8_t*)self->atlas.buffer + atlas_slot->glyph.atlas_offset_x + atlas_slot->glyph.atlas_offset_y * self->atlas.width; - stbtt_MakeGlyphBitmap(&self->info, dst, self->max_glyph_width, self->max_glyph_height, - self->atlas.width, self->scale_factor, self->scale_factor, glyph_index); - stbtt_GetGlyphHMetrics(&self->info, glyph_index, &advance_width, &left_side_bearing); - stbtt_GetGlyphBox(&self->info, glyph_index, &x0, NULL, NULL, &y1); + if (stbtt_GetGlyphBox(&self->info, glyph_index, &x0, NULL, NULL, &y1)) + { + stbtt_MakeGlyphBitmap(&self->info, dst, self->max_glyph_width, self->max_glyph_height, + self->atlas.width, self->scale_factor, self->scale_factor, glyph_index); + } + else + { + /* This means the glyph is empty. In this case, stbtt_MakeGlyphBitmap() + * fills the corresponding region of the atlas buffer with garbage, + * so just zero it */ + unsigned x, y; + for (x = 0; x < self->max_glyph_width; x++) + for (y = 0; y < self->max_glyph_height; y++) + dst[x + (y * self->atlas.width)] = 0; + } atlas_slot->glyph.width = self->max_glyph_width; atlas_slot->glyph.height = self->max_glyph_height; From 002ac5a3449d356ac8a15db27aa836b3efe1c031 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 10 Apr 2019 01:46:25 +0200 Subject: [PATCH 150/237] (menu display) pointer cleanups --- menu/drivers_display/menu_display_ctr.c | 3 +-- menu/drivers_display/menu_display_metal.m | 20 +++++++++----------- menu/drivers_display/menu_display_vita2d.c | 6 ++---- menu/drivers_display/menu_display_vulkan.c | 5 ++--- menu/drivers_display/menu_display_wiiu.c | 6 ++---- 5 files changed, 16 insertions(+), 24 deletions(-) diff --git a/menu/drivers_display/menu_display_ctr.c b/menu/drivers_display/menu_display_ctr.c index 1c6dc9ddb8..e131bc0e93 100644 --- a/menu/drivers_display/menu_display_ctr.c +++ b/menu/drivers_display/menu_display_ctr.c @@ -64,8 +64,7 @@ static void menu_display_ctr_draw(menu_display_ctx_draw_t *draw, { struct ctr_texture *texture = NULL; const float *color = NULL; - ctr_video_t *ctr = video_info ? - (ctr_video_t*)video_info->userdata : NULL; + ctr_video_t *ctr = (ctr_video_t*)video_info->userdata; if (!ctr || !draw) return; diff --git a/menu/drivers_display/menu_display_metal.m b/menu/drivers_display/menu_display_metal.m index 97103bacad..ac9a9f76d8 100644 --- a/menu/drivers_display/menu_display_metal.m +++ b/menu/drivers_display/menu_display_metal.m @@ -25,8 +25,6 @@ #include "../../gfx/video_driver.h" #import "../../gfx/common/metal_common.h" -#define GET_DRIVER(video_info) (video_info ? (__bridge MetalDriver *)video_info->userdata : NULL); - static const float *menu_display_metal_get_default_vertices(void) { return [MenuDisplay defaultVertices]; @@ -39,7 +37,7 @@ static const float *menu_display_metal_get_default_tex_coords(void) static void *menu_display_metal_get_default_mvp(video_frame_info_t *video_info) { - MetalDriver *md = GET_DRIVER(video_info); + MetalDriver *md = (__bridge MetalDriver *)video_info->userdata; if (!md) return NULL; @@ -48,7 +46,7 @@ static void *menu_display_metal_get_default_mvp(video_frame_info_t *video_info) static void menu_display_metal_blend_begin(video_frame_info_t *video_info) { - MetalDriver *md = GET_DRIVER(video_info); + MetalDriver *md = (__bridge MetalDriver *)video_info->userdata; if (!md) return; @@ -57,7 +55,7 @@ static void menu_display_metal_blend_begin(video_frame_info_t *video_info) static void menu_display_metal_blend_end(video_frame_info_t *video_info) { - MetalDriver *md = GET_DRIVER(video_info); + MetalDriver *md = (__bridge MetalDriver *)video_info->userdata; if (!md) return; @@ -67,7 +65,7 @@ static void menu_display_metal_blend_end(video_frame_info_t *video_info) static void menu_display_metal_draw(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { - MetalDriver *md = GET_DRIVER(video_info); + MetalDriver *md = (__bridge MetalDriver *)video_info->userdata; if (!md || !draw) return; @@ -76,7 +74,7 @@ static void menu_display_metal_draw(menu_display_ctx_draw_t *draw, static void menu_display_metal_draw_pipeline(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { - MetalDriver *md = GET_DRIVER(video_info); + MetalDriver *md = (__bridge MetalDriver *)video_info->userdata; if (!md || !draw) return; @@ -90,7 +88,7 @@ static void menu_display_metal_viewport(menu_display_ctx_draw_t *draw, static void menu_display_metal_scissor_begin(video_frame_info_t *video_info, int x, int y, unsigned width, unsigned height) { - MetalDriver *md = GET_DRIVER(video_info); + MetalDriver *md = (__bridge MetalDriver *)video_info->userdata; if (!md) return; @@ -100,7 +98,7 @@ static void menu_display_metal_scissor_begin(video_frame_info_t *video_info, int static void menu_display_metal_scissor_end(video_frame_info_t *video_info) { - MetalDriver *md = GET_DRIVER(video_info); + MetalDriver *md = (__bridge MetalDriver *)video_info->userdata; if (!md) return; @@ -109,13 +107,13 @@ static void menu_display_metal_scissor_end(video_frame_info_t *video_info) static void menu_display_metal_restore_clear_color(void) { - // nothing to do + /* nothing to do */ } static void menu_display_metal_clear_color(menu_display_ctx_clearcolor_t *clearcolor, video_frame_info_t *video_info) { - MetalDriver *md = GET_DRIVER(video_info); + MetalDriver *md = (__bridge MetalDriver *)video_info->userdata; if (!md) return; diff --git a/menu/drivers_display/menu_display_vita2d.c b/menu/drivers_display/menu_display_vita2d.c index 701825ea50..8a9b620db4 100644 --- a/menu/drivers_display/menu_display_vita2d.c +++ b/menu/drivers_display/menu_display_vita2d.c @@ -56,8 +56,7 @@ static const float *menu_display_vita2d_get_default_tex_coords(void) static void *menu_display_vita2d_get_default_mvp( video_frame_info_t *video_info) { - vita_video_t *vita2d = video_info ? - (vita_video_t*)video_info->userdata : NULL; + vita_video_t *vita2d = (vita_video_t*)video_info->userdata; if (!vita2d) return NULL; @@ -113,8 +112,7 @@ static void menu_display_vita2d_draw(menu_display_ctx_draw_t *draw, const float *vertex = NULL; const float *tex_coord = NULL; const float *color = NULL; - vita_video_t *vita2d = video_info ? - (vita_video_t*)video_info->userdata : NULL; + vita_video_t *vita2d = (vita_video_t*)video_info->userdata; if (!vita2d || !draw) return; diff --git a/menu/drivers_display/menu_display_vulkan.c b/menu/drivers_display/menu_display_vulkan.c index 081e3291e4..0beef42eaf 100644 --- a/menu/drivers_display/menu_display_vulkan.c +++ b/menu/drivers_display/menu_display_vulkan.c @@ -50,7 +50,7 @@ static const float vk_colors[] = { static void *menu_display_vk_get_default_mvp(video_frame_info_t *video_info) { - vk_t *vk = video_info ? (vk_t*)video_info->userdata : NULL; + vk_t *vk = (vk_t*)video_info->userdata; if (!vk) return NULL; return &vk->mvp_no_rot; @@ -102,8 +102,7 @@ static unsigned to_menu_pipeline( static void menu_display_vk_viewport(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { - vk_t *vk = video_info ? (vk_t*)video_info->userdata - : NULL; + vk_t *vk = (vk_t*)video_info->userdata; if (!vk || !draw) return; diff --git a/menu/drivers_display/menu_display_wiiu.c b/menu/drivers_display/menu_display_wiiu.c index 95471205a1..fdc6729fd1 100644 --- a/menu/drivers_display/menu_display_wiiu.c +++ b/menu/drivers_display/menu_display_wiiu.c @@ -63,8 +63,7 @@ static void menu_display_wiiu_viewport(menu_display_ctx_draw_t *draw, static void menu_display_wiiu_draw(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { - wiiu_video_t *wiiu = video_info ? - (wiiu_video_t*)video_info->userdata : NULL; + wiiu_video_t *wiiu = (wiiu_video_t*)video_info->userdata; if (!wiiu || !draw) return; @@ -234,8 +233,7 @@ static void menu_display_wiiu_draw_pipeline(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { video_coord_array_t *ca = NULL; - wiiu_video_t *wiiu = video_info ? - (wiiu_video_t*)video_info->userdata : NULL; + wiiu_video_t *wiiu = (wiiu_video_t*)video_info->userdata; if (!wiiu || !draw) return; From dc80e495092f65c4d5825927bc96632c69d30322 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 10 Apr 2019 01:50:55 +0200 Subject: [PATCH 151/237] (menu_display_gl) Small cleanup --- menu/drivers_display/menu_display_gl.c | 3 ++- menu/drivers_display/menu_display_gl_core.c | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/menu/drivers_display/menu_display_gl.c b/menu/drivers_display/menu_display_gl.c index 7e02fe4a09..310f629a0a 100644 --- a/menu/drivers_display/menu_display_gl.c +++ b/menu/drivers_display/menu_display_gl.c @@ -237,7 +237,8 @@ static bool menu_display_gl_font_init_first( return true; } -static void menu_display_gl_scissor_begin(video_frame_info_t *video_info, int x, int y, +static void menu_display_gl_scissor_begin( + video_frame_info_t *video_info, int x, int y, unsigned width, unsigned height) { glScissor(x, video_info->height - y - height, width, height); diff --git a/menu/drivers_display/menu_display_gl_core.c b/menu/drivers_display/menu_display_gl_core.c index 8930f76aeb..1e3ee8bc5f 100644 --- a/menu/drivers_display/menu_display_gl_core.c +++ b/menu/drivers_display/menu_display_gl_core.c @@ -136,8 +136,6 @@ static void menu_display_gl_core_draw_pipeline(menu_display_ctx_draw_t *draw, if (draw->pipeline.id == VIDEO_SHADER_MENU_5) yflip = 1.0f; - else - yflip = 0.0f; memcpy(ubo_scratch_data + sizeof(math_matrix_4x4) + 2 * sizeof(float), &t, sizeof(t)); From e0b59f13e20d8b293463635f0cb01e12b01ea38e Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Tue, 9 Apr 2019 23:17:11 -0400 Subject: [PATCH 152/237] no analog/sensitivity correction for analog buttons --- input/input_driver.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/input/input_driver.c b/input/input_driver.c index edb2e4fa02..0b47f9f850 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -879,7 +879,7 @@ static INLINE bool input_keys_pressed_iterate(unsigned i, return false; } -static int16_t input_joypad_axis(const input_device_driver_t *drv, unsigned port, uint32_t joyaxis) +static int16_t input_joypad_axis(const input_device_driver_t *drv, unsigned port, uint32_t joyaxis, bool button) { int16_t val = 0; settings_t *settings = config_get_ptr(); @@ -890,6 +890,10 @@ static int16_t input_joypad_axis(const input_device_driver_t *drv, unsigned port val = drv->axis(port, joyaxis); + /* no deadzone/sensitivity correction for analog buttons currently */ + if (button) + return val; + if (AXIS_POS_GET(joyaxis) == AXIS_DIR_NONE) { /* current axis is negative */ @@ -913,7 +917,6 @@ static int16_t input_joypad_axis(const input_device_driver_t *drv, unsigned port left = false; } - if (settings->floats.input_analog_deadzone) { /* 0/1 are the left analog X/Y axes, 2/3 are the right analog X/Y axes */ @@ -1054,7 +1057,7 @@ void input_menu_keys_pressed(void *data, input_bits_t *p_new_state) { if (joykey == NO_BTN || !sec->button(joypad_info.joy_idx, joykey)) { - int16_t axis = input_joypad_axis(sec, joypad_info.joy_idx, joyaxis); + int16_t axis = input_joypad_axis(sec, joypad_info.joy_idx, joyaxis, false); float scaled_axis = (float)abs(axis) / 0x8000; bit_pressed = scaled_axis > joypad_info.axis_threshold; } @@ -1066,7 +1069,7 @@ void input_menu_keys_pressed(void *data, input_bits_t *p_new_state) { if (joykey == NO_BTN || !first->button(joypad_info.joy_idx, joykey)) { - int16_t axis = input_joypad_axis(first, joypad_info.joy_idx, joyaxis); + int16_t axis = input_joypad_axis(first, joypad_info.joy_idx, joyaxis, false); float scaled_axis = (float)abs(axis) / 0x8000; bit_pressed = scaled_axis > joypad_info.axis_threshold; } @@ -1776,7 +1779,7 @@ int16_t input_joypad_analog(const input_device_driver_t *drv, axis = joypad_info.auto_binds[ident].joyaxis; /* Analog button. */ - res = abs(input_joypad_axis(drv, joypad_info.joy_idx, axis)); + res = abs(input_joypad_axis(drv, joypad_info.joy_idx, axis, true)); /* If the result is zero, it's got a digital button attached to it */ if (res == 0) @@ -1824,8 +1827,8 @@ int16_t input_joypad_analog(const input_device_driver_t *drv, if (axis_plus == AXIS_NONE) axis_plus = joypad_info.auto_binds[ident_plus].joyaxis; - pressed_minus = abs(input_joypad_axis(drv, joypad_info.joy_idx, axis_minus)); - pressed_plus = abs(input_joypad_axis(drv, joypad_info.joy_idx, axis_plus)); + pressed_minus = abs(input_joypad_axis(drv, joypad_info.joy_idx, axis_minus, false)); + pressed_plus = abs(input_joypad_axis(drv, joypad_info.joy_idx, axis_plus, false)); res = pressed_plus - pressed_minus; if (res == 0) From 7648da1413d8718ca29bb7eecff61c5ab677ef5a Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Wed, 10 Apr 2019 00:22:36 -0400 Subject: [PATCH 153/237] d3d9/10/11/12: fix scissor parameters --- menu/drivers_display/menu_display_d3d10.c | 8 ++++---- menu/drivers_display/menu_display_d3d11.c | 8 ++++---- menu/drivers_display/menu_display_d3d12.c | 8 ++++---- menu/drivers_display/menu_display_d3d9.c | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/menu/drivers_display/menu_display_d3d10.c b/menu/drivers_display/menu_display_d3d10.c index 914a40b879..712dfec833 100644 --- a/menu/drivers_display/menu_display_d3d10.c +++ b/menu/drivers_display/menu_display_d3d10.c @@ -297,10 +297,10 @@ void menu_display_d3d10_scissor_end(video_frame_info_t *video_info) if (!d3d10) return; - rect.left = d3d10->vp.x; - rect.top = d3d10->vp.y; - rect.right = d3d10->vp.width; - rect.bottom = d3d10->vp.height; + rect.left = 0; + rect.top = 0; + rect.right = video_info->width; + rect.bottom = video_info->height; D3D10SetScissorRects(d3d10->device, 1, &rect); } diff --git a/menu/drivers_display/menu_display_d3d11.c b/menu/drivers_display/menu_display_d3d11.c index 043a392392..0a83fd64c4 100644 --- a/menu/drivers_display/menu_display_d3d11.c +++ b/menu/drivers_display/menu_display_d3d11.c @@ -296,10 +296,10 @@ void menu_display_d3d11_scissor_end(video_frame_info_t *video_info) if (!d3d11) return; - rect.left = d3d11->vp.x; - rect.top = d3d11->vp.y; - rect.right = d3d11->vp.width; - rect.bottom = d3d11->vp.height; + rect.left = 0; + rect.top = 0; + rect.right = video_info->width; + rect.bottom = video_info->height; D3D11SetScissorRects(d3d11->context, 1, &rect); } diff --git a/menu/drivers_display/menu_display_d3d12.c b/menu/drivers_display/menu_display_d3d12.c index 3a96c215d6..9d3d14fb8f 100644 --- a/menu/drivers_display/menu_display_d3d12.c +++ b/menu/drivers_display/menu_display_d3d12.c @@ -317,10 +317,10 @@ void menu_display_d3d12_scissor_end(video_frame_info_t *video_info) if (!d3d12) return; - rect.left = d3d12->vp.x; - rect.top = d3d12->vp.y; - rect.right = d3d12->vp.width; - rect.bottom = d3d12->vp.height; + rect.left = 0; + rect.top = 0; + rect.right = video_info->width; + rect.bottom = video_info->height; D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &rect); } diff --git a/menu/drivers_display/menu_display_d3d9.c b/menu/drivers_display/menu_display_d3d9.c index fc5af5479e..f4316aa9d9 100644 --- a/menu/drivers_display/menu_display_d3d9.c +++ b/menu/drivers_display/menu_display_d3d9.c @@ -331,10 +331,10 @@ void menu_display_d3d9_scissor_end(video_frame_info_t *video_info) if (!d3d9) return; - rect.left = d3d9->vp.x; - rect.top = d3d9->vp.y; - rect.right = d3d9->vp.width; - rect.bottom = d3d9->vp.height; + rect.left = 0; + rect.top = 0; + rect.right = video_info->width; + rect.bottom = video_info->height; d3d9_set_scissor_rect(d3d9->dev, &rect); } From 7e80f5520aa9a351e4090d4f39db79fea206402b Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Wed, 10 Apr 2019 13:19:34 +0100 Subject: [PATCH 154/237] (RGUI) Fix menu widget display issues --- menu/drivers/rgui.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index f46fe877a4..8e77f7d889 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -499,6 +499,9 @@ typedef struct bool aspect_update_pending; rgui_video_settings_t menu_video_settings; rgui_video_settings_t content_video_settings; +#if defined(HAVE_MENU_WIDGETS) + bool widgets_supported; +#endif struct scaler_ctx image_scaler; } rgui_t; @@ -2529,6 +2532,25 @@ static void *rgui_init(void **userdata, bool video_is_threaded) *userdata = rgui; +#if defined(HAVE_MENU_WIDGETS) + /* We have to be somewhat careful here, since some + * platforms do not like video_driver_texture-related + * operations (e.g. 3DS). We would hope that these + * platforms will always have HAVE_MENU_WIDGETS disabled, + * but for extra safety we will only permit menu widget + * additions when the current gfx driver reports that it + * has widget support */ + rgui->widgets_supported = video_driver_has_widgets(); + + if (rgui->widgets_supported) + { + if (!menu_display_init_first_driver(video_is_threaded)) + goto error; + + menu_display_allocate_white_texture(); + } +#endif + rgui->menu_title[0] = '\0'; rgui->menu_sublabel[0] = '\0'; @@ -3130,6 +3152,30 @@ static void rgui_toggle(void *userdata, bool menu_on) } } +#if defined(HAVE_MENU_WIDGETS) +static void rgui_context_reset(void *data, bool is_threaded) +{ + rgui_t *rgui = (rgui_t*)data; + + if (!rgui) + return; + + if (rgui->widgets_supported) + menu_display_allocate_white_texture(); +} + +static void rgui_context_destroy(void *data) +{ + rgui_t *rgui = (rgui_t*)data; + + if (!rgui) + return; + + if (rgui->widgets_supported) + video_driver_texture_unload(&menu_display_white_texture); +} +#endif + menu_ctx_driver_t menu_ctx_rgui = { rgui_set_texture, rgui_set_message, @@ -3138,8 +3184,13 @@ menu_ctx_driver_t menu_ctx_rgui = { rgui_frame, rgui_init, rgui_free, +#if defined(HAVE_MENU_WIDGETS) + rgui_context_reset, + rgui_context_destroy, +#else NULL, NULL, +#endif rgui_populate_entries, rgui_toggle, rgui_navigation_clear, From 2bfb073b3e95376a8175e84c328fdc8e1a5b03ea Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Wed, 10 Apr 2019 18:58:53 -0400 Subject: [PATCH 155/237] fix stack-use-after-scope and a memory leak with subsystems --- menu/cbs/menu_cbs_ok.c | 20 +++++++++----------- paths.c | 8 +++++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index fc15653320..9908a2aabe 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -278,7 +278,7 @@ int generic_action_ok_displaylist_push(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx, unsigned action_type) { - menu_displaylist_info_t info; + menu_displaylist_info_t info = {0}; char tmp[PATH_MAX_LENGTH]; char parent_dir[PATH_MAX_LENGTH]; enum menu_displaylist_ctl_state dl_type = DISPLAYLIST_NONE; @@ -304,7 +304,7 @@ int generic_action_ok_displaylist_push(const char *path, string_is_equal(menu_driver, "null")) goto end; - tmp[0] = '\0'; + tmp[0] = parent_dir[0] = '\0'; menu_entries_get_last_stack(&menu_path, &menu_label, NULL, &enum_idx, NULL); @@ -542,27 +542,25 @@ int generic_action_ok_displaylist_push(const char *path, break; case ACTION_OK_DL_DISK_IMAGE_APPEND_LIST: { - char game_dir[PATH_MAX_LENGTH]; filebrowser_clear_type(); - strlcpy(game_dir, path_get(RARCH_PATH_CONTENT), sizeof(game_dir)); - path_basedir(game_dir); + strlcpy(tmp, path_get(RARCH_PATH_CONTENT), sizeof(tmp)); + path_basedir(tmp); info.type = type; info.directory_ptr = idx; - info_path = !string_is_empty(game_dir) ? game_dir : settings->paths.directory_menu_content; + info_path = !string_is_empty(tmp) ? tmp : settings->paths.directory_menu_content; info_label = label; dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE; } break; case ACTION_OK_DL_SUBSYSTEM_ADD_LIST: { - char game_dir[PATH_MAX_LENGTH]; filebrowser_clear_type(); if (content_get_subsystem_rom_id() > 0) - strlcpy(game_dir, content_get_subsystem_rom(content_get_subsystem_rom_id() - 1), sizeof(game_dir)); + strlcpy(tmp, content_get_subsystem_rom(content_get_subsystem_rom_id() - 1), sizeof(tmp)); else - strlcpy(game_dir, path_get(RARCH_PATH_CONTENT), sizeof(game_dir)); - path_basedir(game_dir); + strlcpy(tmp, path_get(RARCH_PATH_CONTENT), sizeof(tmp)); + path_basedir(tmp); if (content_get_subsystem() != type - MENU_SETTINGS_SUBSYSTEM_ADD) content_clear_subsystem(); @@ -570,7 +568,7 @@ int generic_action_ok_displaylist_push(const char *path, filebrowser_set_type(FILEBROWSER_SELECT_FILE_SUBSYSTEM); info.type = type; info.directory_ptr = idx; - info_path = !string_is_empty(game_dir) ? game_dir : settings->paths.directory_menu_content; + info_path = !string_is_empty(tmp) ? tmp : settings->paths.directory_menu_content; info_label = label; dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE; } diff --git a/paths.c b/paths.c index 8758020347..22ba194d61 100644 --- a/paths.c +++ b/paths.c @@ -256,9 +256,9 @@ void path_set_special(char **argv, unsigned num_content) { unsigned i; union string_list_elem_attr attr; - struct string_list* subsystem_paths = NULL; + struct string_list *subsystem_paths = NULL; char str[PATH_MAX_LENGTH]; - global_t *global = global_get_ptr(); + global_t *global = global_get_ptr(); /* First content file is the significant one. */ path_set_basename(argv[0]); @@ -297,7 +297,9 @@ void path_set_special(char **argv, unsigned num_content) global->name.savestate); } } - free(subsystem_paths); + + if (subsystem_paths) + string_list_free(subsystem_paths); } static bool path_init_subsystem(void) From 702c889cd19121a4e244339559fb16cb592bd704 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 11 Apr 2019 02:21:45 +0200 Subject: [PATCH 156/237] (D3D10/11/12) Menu widgets can now appear ingame --- gfx/drivers/d3d10.c | 8 +++++++- gfx/drivers/d3d11.c | 13 +++++++++---- gfx/drivers/d3d12.c | 8 +++++++- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index abf0d1e2c3..065d0be67c 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -1403,12 +1403,18 @@ static bool d3d10_gfx_frame( d3d10->sprites.enabled = true; #ifdef HAVE_MENU +#ifndef HAVE_MENU_WIDGETS if (d3d10->menu.enabled) +#endif { D3D10SetViewports(context, 1, &d3d10->viewport); D3D10SetVertexBuffer(context, 0, d3d10->sprites.vbo, sizeof(d3d10_sprite_t), 0); - menu_driver_frame(video_info); } +#endif + +#ifdef HAVE_MENU + if (d3d10->menu.enabled) + menu_driver_frame(video_info); else #endif if (video_info->statistics_show) diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 63c197ba07..924e80b011 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -1468,12 +1468,19 @@ static bool d3d11_gfx_frame( d3d11->sprites.enabled = true; #ifdef HAVE_MENU +#ifndef HAVE_MENU_WIDGETS if (d3d11->menu.enabled) +#endif { D3D11SetViewports(context, 1, &d3d11->viewport); - D3D11SetVertexBuffer(context, 0, d3d11->sprites.vbo, sizeof(d3d11_sprite_t), 0); - menu_driver_frame(video_info); + D3D11SetVertexBuffer(context, 0, + d3d11->sprites.vbo, sizeof(d3d11_sprite_t), 0); } +#endif + +#ifdef HAVE_MENU + if (d3d11->menu.enabled) + menu_driver_frame(video_info); else #endif if (video_info->statistics_show) @@ -1528,8 +1535,6 @@ static bool d3d11_gfx_frame( } d3d11->sprites.enabled = false; - - #if 0 PERF_STOP(); #endif diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index d778a1730d..257abcf389 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -1477,13 +1477,19 @@ static bool d3d12_gfx_frame( d3d12->sprites.enabled = true; #ifdef HAVE_MENU +#ifndef HAVE_MENU_WIDGETS if (d3d12->menu.enabled) +#endif { D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->chain.viewport); D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->chain.scissorRect); D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->sprites.vbo_view); - menu_driver_frame(video_info); } +#endif + +#ifdef HAVE_MENU + if (d3d12->menu.enabled) + menu_driver_frame(video_info); else #endif if (video_info->statistics_show) From 230c64ba4b1e3dee151c531bc476f02c10da2f70 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 11 Apr 2019 00:09:13 -0400 Subject: [PATCH 157/237] add subsystem support for playlists, only missing the content load portion --- command.c | 3 +- discord/discord.c | 2 +- menu/cbs/menu_cbs_ok.c | 30 ++--- menu/cbs/menu_cbs_sublabel.c | 2 +- menu/drivers/ozone/ozone.c | 2 +- menu/drivers/stripes.c | 2 +- menu/menu_displaylist.c | 6 +- menu/menu_thumbnail_path.c | 2 +- playlist.c | 182 ++++++++++++++++++++++++++++-- playlist.h | 17 ++- tasks/task_content.c | 4 +- tasks/task_database.c | 10 +- tasks/task_netplay_find_content.c | 4 +- tasks/task_screenshot.c | 4 +- ui/drivers/qt/qt_playlist.cpp | 4 +- 15 files changed, 227 insertions(+), 47 deletions(-) diff --git a/command.c b/command.c index 31879c9adb..a00ef3e435 100755 --- a/command.c +++ b/command.c @@ -2415,7 +2415,8 @@ TODO: Add a setting for these tweaks */ str_list->elems[2].data, /* core_path */ str_list->elems[3].data, /* core_name */ str_list->elems[4].data, /* crc32 */ - str_list->elems[5].data /* db_name */ + str_list->elems[5].data, /* db_name */ + NULL, NULL ); runloop_msg_queue_push(msg_hash_to_str(MSG_ADDED_TO_FAVORITES), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); } diff --git a/discord/discord.c b/discord/discord.c index 8e8f339709..f6c2108d76 100644 --- a/discord/discord.c +++ b/discord/discord.c @@ -349,7 +349,7 @@ void discord_update(enum discord_presence presence) if (current_playlist) playlist_get_index_by_path( - current_playlist, path_get(RARCH_PATH_CONTENT), NULL, &label, NULL, NULL, NULL, NULL); + current_playlist, path_get(RARCH_PATH_CONTENT), NULL, &label, NULL, NULL, NULL, NULL, NULL, NULL); if (!label) label = (char *)path_basename(path_get(RARCH_PATH_BASENAME)); diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 9908a2aabe..730aeaa375 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -967,7 +967,7 @@ static bool menu_content_playlist_load(playlist_t *playlist, size_t idx) const char *path = NULL; playlist_get_index(playlist, - idx, &path, NULL, NULL, NULL, NULL, NULL); + idx, &path, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (!string_is_empty(path)) { @@ -1735,7 +1735,7 @@ static int action_ok_playlist_entry_collection(const char *path, selection_ptr = entry_idx; playlist_get_index(playlist, selection_ptr, - &entry_path, &entry_label, &core_path, &core_name, NULL, NULL); + &entry_path, &entry_label, &core_path, &core_name, NULL, NULL, NULL, NULL); /* Is the core path / name of the playlist entry not yet filled in? */ if ( string_is_equal(core_path, file_path_str(FILE_PATH_DETECT)) @@ -1794,7 +1794,7 @@ static int action_ok_playlist_entry_collection(const char *path, } playlist_get_index(playlist, - selection_ptr, &path, NULL, NULL, NULL, NULL, NULL); + selection_ptr, &path, NULL, NULL, NULL, NULL, NULL, NULL, NULL); return default_action_ok_load_content_from_playlist_from_menu( new_core_path, path, entry_label); @@ -1820,7 +1820,7 @@ static int action_ok_playlist_entry(const char *path, selection_ptr = entry_idx; playlist_get_index(playlist, selection_ptr, - &entry_path, &entry_label, &core_path, &core_name, NULL, NULL); + &entry_path, &entry_label, &core_path, &core_name, NULL, NULL, NULL, NULL); if ( string_is_equal(core_path, file_path_str(FILE_PATH_DETECT)) && string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) @@ -1869,7 +1869,7 @@ static int action_ok_playlist_entry(const char *path, playlist_get_index(playlist, selection_ptr, &path, NULL, NULL, NULL, - NULL, NULL); + NULL, NULL, NULL, NULL); return default_action_ok_load_content_from_playlist_from_menu( new_core_path, path, entry_label); @@ -1893,7 +1893,7 @@ static int action_ok_playlist_entry_start_content(const char *path, selection_ptr = menu->scratchpad.unsigned_var; playlist_get_index(playlist, selection_ptr, - &entry_path, &entry_label, &core_path, &core_name, NULL, NULL); + &entry_path, &entry_label, &core_path, &core_name, NULL, NULL, NULL, NULL); if ( string_is_equal(core_path, file_path_str(FILE_PATH_DETECT)) && string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) @@ -1943,7 +1943,7 @@ static int action_ok_playlist_entry_start_content(const char *path, } playlist_get_index(playlist, - selection_ptr, &path, NULL, NULL, NULL, NULL, NULL); + selection_ptr, &path, NULL, NULL, NULL, NULL, NULL, NULL, NULL); return default_action_ok_load_content_from_playlist_from_menu(core_path, path, entry_label); @@ -2067,7 +2067,7 @@ static int action_ok_audio_add_to_mixer(const char *path, return -1; playlist_get_index(tmp_playlist, entry_idx, - &entry_path, NULL, NULL, NULL, NULL, NULL); + &entry_path, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (filestream_exists(entry_path)) task_push_audio_mixer_load(entry_path, @@ -2089,7 +2089,7 @@ static int action_ok_audio_add_to_mixer_and_play(const char *path, return -1; playlist_get_index(tmp_playlist, entry_idx, - &entry_path, NULL, NULL, NULL, NULL, NULL); + &entry_path, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (filestream_exists(entry_path)) task_push_audio_mixer_load_and_play(entry_path, @@ -2120,8 +2120,8 @@ static int action_ok_audio_add_to_mixer_and_collection(const char *path, NULL, "builtin", "musicplayer", - NULL, - NULL); + NULL, NULL, + NULL, NULL); if (filestream_exists(combined_path)) task_push_audio_mixer_load(combined_path, @@ -2152,8 +2152,8 @@ static int action_ok_audio_add_to_mixer_and_collection_and_play(const char *path NULL, "builtin", "musicplayer", - NULL, - NULL); + NULL, NULL, + NULL, NULL); if (filestream_exists(combined_path)) task_push_audio_mixer_load_and_play(combined_path, @@ -3803,7 +3803,7 @@ static int action_ok_reset_core_association(const char *path, playlist_get_index(tmp_playlist, menu->rpl_entry_selection_ptr, - &tmp_path, NULL, NULL, NULL, NULL, NULL); + &tmp_path, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (!command_event(CMD_EVENT_RESET_CORE_ASSOCIATION, (void *)&menu->rpl_entry_selection_ptr)) @@ -3947,7 +3947,7 @@ static int action_ok_add_to_favorites_playlist(const char *path, /* Read current playlist parameters */ playlist_get_index(playlist_curr, menu->rpl_entry_selection_ptr, &content_path, &content_label, &core_path, &core_name, - &crc32, NULL); + &crc32, NULL, NULL, NULL); /* Error checking * > If content path is empty, cannot do anything... */ diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index f2cb33e60b..acf1f2bb45 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -859,7 +859,7 @@ static int action_bind_sublabel_playlist_entry( return 0; /* Read playlist entry */ - playlist_get_index(playlist, i, NULL, NULL, NULL, &core_name, NULL, NULL); + playlist_get_index(playlist, i, NULL, NULL, NULL, &core_name, NULL, NULL, NULL, NULL); /* Only add sublabel if a core is currently assigned */ if (string_is_empty(core_name) || string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index e1b68f5a18..54ad392ef8 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1141,7 +1141,7 @@ void ozone_update_content_metadata(ozone_handle_t *ozone) { const char *core_label = NULL; playlist_get_index(playlist, selection, - NULL, NULL, NULL, &core_name, NULL, NULL); + NULL, NULL, NULL, &core_name, NULL, NULL, NULL, NULL); /* Fill core name */ if (!core_name || string_is_equal(core_name, "DETECT")) diff --git a/menu/drivers/stripes.c b/menu/drivers/stripes.c index 7d6338c9f2..d77f4295a1 100644 --- a/menu/drivers/stripes.c +++ b/menu/drivers/stripes.c @@ -905,7 +905,7 @@ static void stripes_update_thumbnail_path(void *data, unsigned i, char pos) { const char *core_name = NULL; playlist_get_index(playlist, i, - NULL, NULL, NULL, &core_name, NULL, NULL); + NULL, NULL, NULL, &core_name, NULL, NULL, NULL, NULL); if (string_is_equal(core_name, "imageviewer")) { diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 0aa0b97034..9e1799089e 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -1354,7 +1354,7 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, /* Read playlist entry */ playlist_get_index(playlist, i, - &path, &label, &core_path, &core_name, NULL, NULL); + &path, &label, &core_path, &core_name, NULL, NULL, NULL, NULL); /* Extract any available runtime values, if required */ if (get_runtime) @@ -1741,7 +1741,7 @@ static int menu_displaylist_parse_database_entry(menu_handle_t *menu, playlist_get_index(playlist, j, NULL, NULL, NULL, NULL, - &crc32, NULL); + &crc32, NULL, NULL, NULL); if (crc32) tmp_str_list = string_split(crc32, "|"); @@ -2890,7 +2890,7 @@ static int menu_displaylist_parse_horizontal_content_actions( if (playlist) playlist_get_index(playlist, idx, - &entry_path, &label, &core_path, &core_name, NULL, &db_name); + &entry_path, &label, &core_path, &core_name, NULL, &db_name, NULL, NULL); content_loaded = !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL) && string_is_equal(menu->deferred_path, fullpath); diff --git a/menu/menu_thumbnail_path.c b/menu/menu_thumbnail_path.c index 9bf097d9c3..7a085d5f74 100644 --- a/menu/menu_thumbnail_path.c +++ b/menu/menu_thumbnail_path.c @@ -340,7 +340,7 @@ bool menu_thumbnail_set_content_playlist(menu_thumbnail_path_data_t *path_data, /* Read playlist values */ playlist_get_index(playlist, idx, - &content_path, &content_label, NULL, &core_name, NULL, &db_name); + &content_path, &content_label, NULL, &core_name, NULL, &db_name, NULL, NULL); /* Content without a path is invalid by definition */ if (string_is_empty(content_path)) diff --git a/playlist.c b/playlist.c index 459f27586f..db281914ce 100644 --- a/playlist.c +++ b/playlist.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "playlist.h" @@ -46,6 +47,8 @@ struct playlist_entry char *core_name; char *db_name; char *crc32; + char *subsystem_ident; + struct string_list *subsystem_roms; unsigned runtime_hours; unsigned runtime_minutes; unsigned runtime_seconds; @@ -82,8 +85,11 @@ typedef struct char **current_entry_val; int *current_entry_int_val; unsigned *current_entry_uint_val; + struct string_list **current_entry_string_list_val; char *current_meta_string; + char *current_items_string; bool in_items; + bool in_subsystem_roms; } JSONContext; static playlist_t *playlist_cached = NULL; @@ -121,7 +127,9 @@ void playlist_get_index(playlist_t *playlist, const char **path, const char **label, const char **core_path, const char **core_name, const char **crc32, - const char **db_name) + const char **db_name, + const char **subsystem_ident, + const struct string_list **subsystem_roms) { if (!playlist) return; @@ -138,6 +146,10 @@ void playlist_get_index(playlist_t *playlist, *db_name = playlist->entries[idx].db_name; if (crc32) *crc32 = playlist->entries[idx].crc32; + if (subsystem_ident) + *subsystem_ident = playlist->entries[idx].subsystem_ident; + if (subsystem_roms) + *subsystem_roms = playlist->entries[idx].subsystem_roms; } void playlist_get_runtime_index(playlist_t *playlist, @@ -200,7 +212,9 @@ void playlist_get_index_by_path(playlist_t *playlist, char **path, char **label, char **core_path, char **core_name, char **crc32, - char **db_name) + char **db_name, + char **subsystem_ident, + struct string_list **subsystem_roms) { size_t i; if (!playlist) @@ -223,6 +237,10 @@ void playlist_get_index_by_path(playlist_t *playlist, *db_name = playlist->entries[i].db_name; if (crc32) *crc32 = playlist->entries[i].crc32; + if (subsystem_ident) + *subsystem_ident = playlist->entries[i].subsystem_ident; + if (subsystem_roms) + *subsystem_roms = playlist->entries[i].subsystem_roms; break; } } @@ -265,6 +283,10 @@ static void playlist_free_entry(struct playlist_entry *entry) free(entry->db_name); if (entry->crc32 != NULL) free(entry->crc32); + if (entry->subsystem_ident != NULL) + free(entry->subsystem_ident); + if (entry->subsystem_roms != NULL) + string_list_free(entry->subsystem_roms); entry->path = NULL; entry->label = NULL; @@ -272,6 +294,8 @@ static void playlist_free_entry(struct playlist_entry *entry) entry->core_name = NULL; entry->db_name = NULL; entry->crc32 = NULL; + entry->subsystem_ident = NULL; + entry->subsystem_roms = NULL; entry->runtime_hours = 0; entry->runtime_minutes = 0; entry->runtime_seconds = 0; @@ -544,7 +568,9 @@ bool playlist_push(playlist_t *playlist, const char *path, const char *label, const char *core_path, const char *core_name, const char *crc32, - const char *db_name) + const char *db_name, + const char *subsystem_ident, + const struct string_list *subsystem_roms) { size_t i; bool core_path_empty = string_is_empty(core_path); @@ -595,6 +621,37 @@ bool playlist_push(playlist_t *playlist, if (!string_is_equal(playlist->entries[i].core_path, core_path)) continue; + if (!string_is_empty(subsystem_ident) && !string_is_empty(playlist->entries[i].subsystem_ident) && !string_is_equal(playlist->entries[i].subsystem_ident, subsystem_ident)) + continue; + + if (string_is_empty(subsystem_ident) && !string_is_empty(playlist->entries[i].subsystem_ident)) + continue; + + if (!string_is_empty(subsystem_ident) && string_is_empty(playlist->entries[i].subsystem_ident)) + continue; + + if (subsystem_roms) + { + int j; + const struct string_list *roms = playlist->entries[i].subsystem_roms; + bool unequal = false; + + if (subsystem_roms->size != roms->size) + continue; + + for (j = 0; j < subsystem_roms->size; j++) + { + if (!string_is_equal(subsystem_roms->elems[j].data, roms->elems[j].data)) + { + unequal = true; + break; + } + } + + if (unequal) + continue; + } + /* If top entry, we don't want to push a new entry since * the top and the entry to be pushed are the same. */ if (i == 0) @@ -629,6 +686,8 @@ bool playlist_push(playlist_t *playlist, playlist->entries[0].core_name = NULL; playlist->entries[0].db_name = NULL; playlist->entries[0].crc32 = NULL; + playlist->entries[0].subsystem_ident = NULL; + playlist->entries[0].subsystem_roms = NULL; playlist->entries[0].runtime_hours = 0; playlist->entries[0].runtime_minutes = 0; playlist->entries[0].runtime_seconds = 0; @@ -650,6 +709,19 @@ bool playlist_push(playlist_t *playlist, playlist->entries[0].db_name = strdup(db_name); if (!string_is_empty(crc32)) playlist->entries[0].crc32 = strdup(crc32); + if (!string_is_empty(subsystem_ident)) + playlist->entries[0].subsystem_ident = strdup(subsystem_ident); + if (subsystem_roms) + { + union string_list_elem_attr attributes = {0}; + + playlist->entries[0].subsystem_roms = string_list_new(); + + for (i = 0; i < subsystem_roms->size; i++) + { + string_list_append(playlist->entries[0].subsystem_roms, subsystem_roms->elems[i].data, attributes); + } + } } playlist->size++; @@ -1001,6 +1073,49 @@ void playlist_write_file(playlist_t *playlist) JSON_Writer_WriteColon(context.writer); JSON_Writer_WriteSpace(context.writer, 1); JSON_Writer_WriteString(context.writer, playlist->entries[i].db_name ? playlist->entries[i].db_name : "", playlist->entries[i].db_name ? strlen(playlist->entries[i].db_name) : 0, JSON_UTF8); + + if (!string_is_empty(playlist->entries[i].subsystem_ident)) + { + JSON_Writer_WriteComma(context.writer); + JSON_Writer_WriteNewLine(context.writer); + JSON_Writer_WriteSpace(context.writer, 6); + JSON_Writer_WriteString(context.writer, "subsystem_ident", strlen("subsystem_ident"), JSON_UTF8); + JSON_Writer_WriteColon(context.writer); + JSON_Writer_WriteSpace(context.writer, 1); + JSON_Writer_WriteString(context.writer, playlist->entries[i].subsystem_ident ? playlist->entries[i].subsystem_ident : "", playlist->entries[i].subsystem_ident ? strlen(playlist->entries[i].subsystem_ident) : 0, JSON_UTF8); + } + + if (playlist->entries[i].subsystem_roms && playlist->entries[i].subsystem_roms->size > 0) + { + int j; + + JSON_Writer_WriteComma(context.writer); + JSON_Writer_WriteNewLine(context.writer); + JSON_Writer_WriteSpace(context.writer, 6); + JSON_Writer_WriteString(context.writer, "subsystem_roms", strlen("subsystem_roms"), JSON_UTF8); + JSON_Writer_WriteColon(context.writer); + JSON_Writer_WriteSpace(context.writer, 1); + JSON_Writer_WriteStartArray(context.writer); + JSON_Writer_WriteNewLine(context.writer); + + for (j = 0; j < playlist->entries[i].subsystem_roms->size; j++) + { + const struct string_list *roms = playlist->entries[i].subsystem_roms; + JSON_Writer_WriteSpace(context.writer, 8); + JSON_Writer_WriteString(context.writer, !string_is_empty(roms->elems[j].data) ? roms->elems[j].data : "", !string_is_empty(roms->elems[j].data) ? strlen(roms->elems[j].data) : 0, JSON_UTF8); + + if (j < playlist->entries[i].subsystem_roms->size - 1) + { + JSON_Writer_WriteComma(context.writer); + JSON_Writer_WriteNewLine(context.writer); + } + } + + JSON_Writer_WriteNewLine(context.writer); + JSON_Writer_WriteSpace(context.writer, 6); + JSON_Writer_WriteEndArray(context.writer); + } + JSON_Writer_WriteNewLine(context.writer); JSON_Writer_WriteSpace(context.writer, 4); @@ -1106,6 +1221,12 @@ static JSON_Parser_HandlerResult JSONStartArrayHandler(JSON_Parser parser) if (string_is_equal(pCtx->current_meta_string, "items") && pCtx->array_depth == 1) pCtx->in_items = true; } + else if (pCtx->object_depth == 2) + { + if (pCtx->array_depth == 2) + if (string_is_equal(pCtx->current_items_string, "subsystem_roms")) + pCtx->in_subsystem_roms = true; + } return JSON_Parser_Continue; } @@ -1125,6 +1246,19 @@ static JSON_Parser_HandlerResult JSONEndArrayHandler(JSON_Parser parser) free(pCtx->current_meta_string); pCtx->current_meta_string = NULL; pCtx->in_items = false; + + if (pCtx->current_items_string) + { + free(pCtx->current_items_string); + pCtx->current_items_string = NULL; + } + } + } + else if (pCtx->object_depth == 2) + { + if (pCtx->in_subsystem_roms && string_is_equal(pCtx->current_items_string, "subsystem_roms") && pCtx->array_depth == 1) + { + pCtx->in_subsystem_roms = false; } } @@ -1174,7 +1308,19 @@ static JSON_Parser_HandlerResult JSONStringHandler(JSON_Parser parser, char *pVa JSONContext *pCtx = (JSONContext*)JSON_Parser_GetUserData(parser); (void)attributes; /* unused */ - if (pCtx->in_items && pCtx->object_depth == 2) + if (pCtx->in_items && pCtx->in_subsystem_roms && pCtx->object_depth == 2 && pCtx->array_depth == 2) + { + if (pCtx->current_entry_string_list_val && length && !string_is_empty(pValue)) + { + union string_list_elem_attr attr = {0}; + + if (!*pCtx->current_entry_string_list_val) + *pCtx->current_entry_string_list_val = string_list_new(); + + string_list_append(*pCtx->current_entry_string_list_val, pValue, attr); + } + } + else if (pCtx->in_items && pCtx->object_depth == 2) { if (pCtx->array_depth == 1) { @@ -1269,6 +1415,13 @@ static JSON_Parser_HandlerResult JSONObjectMemberHandler(JSON_Parser parser, cha if (length) { + if (!string_is_empty(pValue)) + { + if (!string_is_empty(pCtx->current_items_string)) + free(pCtx->current_items_string); + pCtx->current_items_string = strdup(pValue); + } + if (string_is_equal(pValue, "path")) pCtx->current_entry_val = &pCtx->current_entry->path; else if (string_is_equal(pValue, "label")) @@ -1281,6 +1434,10 @@ static JSON_Parser_HandlerResult JSONObjectMemberHandler(JSON_Parser parser, cha pCtx->current_entry_val = &pCtx->current_entry->crc32; else if (string_is_equal(pValue, "db_name")) pCtx->current_entry_val = &pCtx->current_entry->db_name; + else if (string_is_equal(pValue, "subsystem_ident")) + pCtx->current_entry_val = &pCtx->current_entry->subsystem_ident; + else if (string_is_equal(pValue, "subsystem_roms")) + pCtx->current_entry_string_list_val = &pCtx->current_entry->subsystem_roms; else if (string_is_equal(pValue, "runtime_hours")) pCtx->current_entry_uint_val = &pCtx->current_entry->runtime_hours; else if (string_is_equal(pValue, "runtime_minutes")) @@ -1441,6 +1598,9 @@ static bool playlist_read_file( if (context.current_meta_string) free(context.current_meta_string); + + if (context.current_items_string) + free(context.current_items_string); } else { @@ -1464,9 +1624,9 @@ static bool playlist_read_file( /* Read playlist entry and terminate string with NUL character * regardless of Windows or Unix line endings */ - if((last = strrchr(buf[i], '\r'))) + if ((last = strrchr(buf[i], '\r'))) *last = '\0'; - else if((last = strrchr(buf[i], '\n'))) + else if ((last = strrchr(buf[i], '\n'))) *last = '\0'; } @@ -1577,6 +1737,7 @@ static int playlist_qsort_func(const struct playlist_entry *a, goto end; a_fallback_label = (char*)calloc(PATH_MAX_LENGTH, sizeof(char)); + if (!a_fallback_label) goto end; @@ -1594,6 +1755,7 @@ static int playlist_qsort_func(const struct playlist_entry *a, goto end; b_fallback_label = (char*)calloc(PATH_MAX_LENGTH, sizeof(char)); + if (!b_fallback_label) goto end; @@ -1641,7 +1803,9 @@ void command_playlist_push_write( const char *core_path, const char *core_name, const char *crc32, - const char *db_name) + const char *db_name, + const char *subsystem_ident, + const struct string_list *subsystem_roms) { if (!playlist) return; @@ -1653,7 +1817,9 @@ void command_playlist_push_write( core_path, core_name, crc32, - db_name + db_name, + subsystem_ident, + subsystem_roms )) playlist_write_file(playlist); } diff --git a/playlist.h b/playlist.h index 9de8b2a19a..7265ebfb8e 100644 --- a/playlist.h +++ b/playlist.h @@ -21,6 +21,7 @@ #include #include +#include RETRO_BEGIN_DECLS @@ -77,7 +78,9 @@ void playlist_get_index(playlist_t *playlist, const char **path, const char **label, const char **core_path, const char **core_name, const char **crc32, - const char **db_name); + const char **db_name, + const char **subsystem_ident, + const struct string_list **subsystem_roms); void playlist_get_runtime_index(playlist_t *playlist, size_t idx, @@ -109,7 +112,9 @@ bool playlist_push(playlist_t *playlist, const char *path, const char *label, const char *core_path, const char *core_name, const char *crc32, - const char *db_name); + const char *db_name, + const char *subsystem_ident, + const struct string_list *subsystem_roms); bool playlist_push_runtime(playlist_t *playlist, const char *path, const char *core_path, @@ -140,7 +145,9 @@ void playlist_get_index_by_path(playlist_t *playlist, char **path, char **label, char **core_path, char **core_name, char **crc32, - char **db_name); + char **db_name, + char **subsystem_ident, + struct string_list **subsystem_roms); bool playlist_entry_exists(playlist_t *playlist, const char *path, @@ -169,7 +176,9 @@ void command_playlist_push_write( const char *core_path, const char *core_name, const char *crc32, - const char *db_name); + const char *db_name, + const char *subsystem_ident, + const struct string_list *subsystem_roms); void command_playlist_update_write( playlist_t *playlist, diff --git a/tasks/task_content.c b/tasks/task_content.c index d1c9c03fd0..348cf524e2 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -1094,7 +1094,9 @@ static bool task_load_content(content_ctx_info_t *content_info, core_path, core_name, crc32, - db_name); + db_name, + path_get(RARCH_PATH_SUBSYSTEM), + path_get_subsystem_list()); } free(tmp); diff --git a/tasks/task_database.c b/tasks/task_database.c index 4d701c0bee..29700f1413 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -843,13 +843,14 @@ static int database_info_list_iterate_found_match( fprintf(stderr, "entry path str: %s\n", entry_path_str); #endif - if(!playlist_entry_exists(playlist, entry_path_str, db_crc)) + if (!playlist_entry_exists(playlist, entry_path_str, db_crc)) { playlist_push(playlist, entry_path_str, db_info_entry->name, file_path_str(FILE_PATH_DETECT), file_path_str(FILE_PATH_DETECT), - db_crc, db_playlist_base_str); + db_crc, db_playlist_base_str, + NULL, NULL); } playlist_write_file(playlist); @@ -1010,7 +1011,7 @@ static int task_database_iterate_playlist_lutro( free(db_playlist_path); - if(!playlist_entry_exists(playlist, + if (!playlist_entry_exists(playlist, path, file_path_str(FILE_PATH_DETECT))) { char *game_title = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); @@ -1025,7 +1026,8 @@ static int task_database_iterate_playlist_lutro( file_path_str(FILE_PATH_DETECT), file_path_str(FILE_PATH_DETECT), file_path_str(FILE_PATH_DETECT), - file_path_str(FILE_PATH_LUTRO_PLAYLIST)); + file_path_str(FILE_PATH_LUTRO_PLAYLIST), + NULL, NULL); free(game_title); } diff --git a/tasks/task_netplay_find_content.c b/tasks/task_netplay_find_content.c index 8cce2eb286..205606d2bb 100644 --- a/tasks/task_netplay_find_content.c +++ b/tasks/task_netplay_find_content.c @@ -277,7 +277,7 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) const char *playlist_crc32 = NULL; const char *playlist_path = NULL; - playlist_get_index(playlist, j, &playlist_path, NULL, NULL, NULL, &playlist_crc32, NULL); + playlist_get_index(playlist, j, &playlist_path, NULL, NULL, NULL, &playlist_crc32, NULL, NULL, NULL); if(have_crc && string_is_equal(playlist_crc32, state->content_crc)) { @@ -345,7 +345,7 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) const char *playlist_crc32 = NULL; const char *playlist_path = NULL; - playlist_get_index(playlist, k, &playlist_path, NULL, NULL, NULL, &playlist_crc32, NULL); + playlist_get_index(playlist, k, &playlist_path, NULL, NULL, NULL, &playlist_crc32, NULL, NULL, NULL); get_entry(entry, sizeof(entry), playlist_path); if(!string_is_empty(entry) && diff --git a/tasks/task_screenshot.c b/tasks/task_screenshot.c index e2a229db23..eb1f8beedb 100644 --- a/tasks/task_screenshot.c +++ b/tasks/task_screenshot.c @@ -176,8 +176,8 @@ static void task_screenshot_handler(retro_task_t *task) NULL, "builtin", "imageviewer", - NULL, - NULL); + NULL, NULL, + NULL, NULL); #endif task_set_progress(task, 100); diff --git a/ui/drivers/qt/qt_playlist.cpp b/ui/drivers/qt/qt_playlist.cpp index 2ebcc684a0..8e2aab5325 100644 --- a/ui/drivers/qt/qt_playlist.cpp +++ b/ui/drivers/qt/qt_playlist.cpp @@ -602,7 +602,7 @@ void MainWindow::addFilesToPlaylist(QStringList files) } playlist_push(playlist, pathData, fileNameNoExten, - corePathData, coreNameData, "00000000|crc", databaseData); + corePathData, coreNameData, "00000000|crc", databaseData, NULL, NULL); } playlist_write_file(playlist); @@ -1368,7 +1368,7 @@ void PlaylistModel::getPlaylistItems(QString path) playlist_get_index(playlist, i, &path, &label, &core_path, - &core_name, &crc32, &db_name); + &core_name, &crc32, &db_name, NULL, NULL); if (string_is_empty(path)) continue; From a870526dc96106e48e20177c3240bf94eff11afa Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 11 Apr 2019 14:29:31 +0100 Subject: [PATCH 158/237] (RGUI) Add optional extended ASCII support --- config.def.h | 1 + configuration.c | 1 + configuration.h | 1 + intl/msg_hash_lbl.h | 2 + intl/msg_hash_us.h | 8 + menu/cbs/menu_cbs_sublabel.c | 4 + menu/drivers/rgui.c | 325 +++++++++++++++++++++++++---------- menu/menu_displaylist.c | 4 + menu/menu_setting.c | 15 ++ msg_hash.h | 1 + 10 files changed, 273 insertions(+), 89 deletions(-) diff --git a/config.def.h b/config.def.h index fda9c97c41..3b779d0b4d 100644 --- a/config.def.h +++ b/config.def.h @@ -392,6 +392,7 @@ static bool rgui_full_width_layout = true; static unsigned rgui_aspect = RGUI_ASPECT_RATIO_4_3; static unsigned rgui_aspect_lock = RGUI_ASPECT_RATIO_LOCK_NONE; static bool rgui_shadows = false; +static bool rgui_extended_ascii = false; #else static bool default_block_config_read = false; diff --git a/configuration.c b/configuration.c index 491e3bfb65..d4bdb2f3ba 100644 --- a/configuration.c +++ b/configuration.c @@ -1512,6 +1512,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("menu_rgui_full_width_layout", &settings->bools.menu_rgui_full_width_layout, true, rgui_full_width_layout, false); SETTING_BOOL("rgui_inline_thumbnails", &settings->bools.menu_rgui_inline_thumbnails, true, rgui_inline_thumbnails, false); SETTING_BOOL("rgui_swap_thumbnails", &settings->bools.menu_rgui_swap_thumbnails, true, rgui_swap_thumbnails, false); + SETTING_BOOL("rgui_extended_ascii", &settings->bools.menu_rgui_extended_ascii, true, rgui_extended_ascii, false); #endif #ifdef HAVE_XMB SETTING_BOOL("xmb_shadows_enable", &settings->bools.menu_xmb_shadows_enable, true, xmb_shadows_enable, false); diff --git a/configuration.h b/configuration.h index b53db75971..25852cac04 100644 --- a/configuration.h +++ b/configuration.h @@ -175,6 +175,7 @@ typedef struct settings bool menu_rgui_shadows; bool menu_rgui_inline_thumbnails; bool menu_rgui_swap_thumbnails; + bool menu_rgui_extended_ascii; bool menu_xmb_shadows_enable; bool menu_xmb_vertical_thumbnails; bool menu_content_show_settings; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index b70d3fb6fa..832ce5fa61 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1627,6 +1627,8 @@ MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT, "menu_rgui_full_width_layout") MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_SHADOWS, "menu_rgui_shadows") +MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_EXTENDED_ASCII, + "rgui_extended_ascii") MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_REWIND, "menu_show_rewind_settings") MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 252f8bcc99..7e4e9f057c 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -6916,6 +6916,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_MENU_RGUI_SHADOWS, "Enable drop shadows for menu text, borders and thumbnails. Has a modest performance impact." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_RGUI_EXTENDED_ASCII, + "Extended ASCII Support" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_RGUI_EXTENDED_ASCII, + "Enable display of non-standard ASCII characters. Required for compatibility with certain non-English Western languages. Has a moderate performance impact." + ) MSG_HASH( MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For CRT displays only. Attempts to use exact core/game resolution and refresh rate." diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index f2cb33e60b..f05409021d 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -542,6 +542,7 @@ default_sublabel_macro(action_bind_sublabel_menu_ticker_speed, default_sublabel_macro(action_bind_sublabel_playlist_show_inline_core_name, MENU_ENUM_SUBLABEL_PLAYLIST_SHOW_INLINE_CORE_NAME) default_sublabel_macro(action_bind_sublabel_playlist_sort_alphabetical, MENU_ENUM_SUBLABEL_PLAYLIST_SORT_ALPHABETICAL) default_sublabel_macro(action_bind_sublabel_menu_rgui_full_width_layout, MENU_ENUM_SUBLABEL_MENU_RGUI_FULL_WIDTH_LAYOUT) +default_sublabel_macro(action_bind_sublabel_menu_rgui_extended_ascii, MENU_ENUM_SUBLABEL_MENU_RGUI_EXTENDED_ASCII) default_sublabel_macro(action_bind_sublabel_help_send_debug_info, MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO) static int action_bind_sublabel_systeminfo_controller_entry( @@ -2467,6 +2468,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_full_width_layout); break; + case MENU_ENUM_LABEL_MENU_RGUI_EXTENDED_ASCII: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_extended_ascii); + break; case MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_help_send_debug_info); break; diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 8e77f7d889..23ac36b82b 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -75,6 +75,9 @@ #define RGUI_TICKER_SPACER " | " +#define NUM_FONT_GLYPHS_REGULAR 128 +#define NUM_FONT_GLYPHS_EXTENDED 256 + typedef struct { unsigned start_x; @@ -479,6 +482,7 @@ typedef struct bool border_thickness; bool border_enable; bool shadow_enable; + bool extended_ascii_enable; float scroll_y; char *msgbox; unsigned color_theme; @@ -508,7 +512,7 @@ typedef struct static unsigned mini_thumbnail_max_width = 0; static unsigned mini_thumbnail_max_height = 0; -static bool font_lut[128][FONT_WIDTH * FONT_HEIGHT]; +static bool font_lut[NUM_FONT_GLYPHS_EXTENDED][FONT_WIDTH * FONT_HEIGHT]; typedef struct { @@ -1490,107 +1494,233 @@ static void prepare_rgui_colors(rgui_t *rgui, settings_t *settings) rgui->force_redraw = true; } -static void blit_line(int x, int y, - const char *message, uint16_t color, uint16_t shadow_color, bool draw_shadow) +/* ============================== + * blit_line() START + * ============================== */ + +/* NOTE: These functions are WET (Write Everything Twice). + * This is bad design and difficult to maintain, but we have + * no other choice here. blit_line() is so performance + * critical that we simply cannot afford to check user + * settings internally. */ + +static void blit_line_regular(int x, int y, + const char *message, uint16_t color, uint16_t shadow_color) { - unsigned fb_width = rgui_frame_buf.width; + unsigned fb_width = rgui_frame_buf.width; uint16_t *frame_buf_data = rgui_frame_buf.data; - /* Note: We can only display ASCII characters from 0-127. - * Everything else is rendered as garbage (incorrect glyphs - * from extended ASCII set). This is due to the fact that - * char arrays use a signed 8 bit data type [-128 to 127], - * so values greater than 127 are 'written' across multiple bytes. - * This is a UTF-8 encoding issue, and it's too difficult and - * too performance intensive to deal with here. - * Since drawing these multi-byte characters is a huge problem - * (we could end up with a string that exceeds the dimensions - * of the framebuffer, and get a segfault...) we shall - * skip drawing any character greater than 127 */ - - /* We're going to do some ugly loop unswitching here - * because rendering text is *very* expensive and I don't - * want to rely on the compiler to optimise this properly... */ - if (draw_shadow) + while (!string_is_empty(message)) { - /* Small performance hack... */ - uint32_t shadow_colour_32 = shadow_color; - shadow_colour_32 |= shadow_colour_32 << 16; + unsigned i, j; + uint8_t symbol = (uint8_t)*message++; - /* Drop shadow version */ - while (!string_is_empty(message)) + if (symbol >= NUM_FONT_GLYPHS_REGULAR) + continue; + + if (symbol != ' ') { - unsigned i, j; - uint8_t symbol = (uint8_t)*message++; - - if (symbol > 127) - continue; - - if (symbol != ' ') + for (j = 0; j < FONT_HEIGHT; j++) { - for (j = 0; j < FONT_HEIGHT; j++) + unsigned buff_offset = ((y + j) * fb_width) + x; + + for (i = 0; i < FONT_WIDTH; i++) { - unsigned buff_offset = ((y + j) * fb_width) + x; + if (font_lut[symbol][i + (j * FONT_WIDTH)]) + *(frame_buf_data + buff_offset + i) = color; + } + } + } - for (i = 0; i < FONT_WIDTH; i++) + x += FONT_WIDTH_STRIDE; + } +} + +static void blit_line_regular_shadow(int x, int y, + const char *message, uint16_t color, uint16_t shadow_color) +{ + unsigned fb_width = rgui_frame_buf.width; + uint16_t *frame_buf_data = rgui_frame_buf.data; + uint32_t shadow_colour_32 = shadow_color; + + /* Small performance hack... */ + shadow_colour_32 |= shadow_colour_32 << 16; + + while (!string_is_empty(message)) + { + unsigned i, j; + uint8_t symbol = (uint8_t)*message++; + + if (symbol >= NUM_FONT_GLYPHS_REGULAR) + continue; + + if (symbol != ' ') + { + for (j = 0; j < FONT_HEIGHT; j++) + { + unsigned buff_offset = ((y + j) * fb_width) + x; + + for (i = 0; i < FONT_WIDTH; i++) + { + if (font_lut[symbol][i + (j * FONT_WIDTH)]) { - if (font_lut[symbol][i + (j * FONT_WIDTH)]) - { - uint16_t *frame_buf_ptr = frame_buf_data + buff_offset + i; + uint16_t *frame_buf_ptr = frame_buf_data + buff_offset + i; - /* Text pixel */ - *frame_buf_ptr = color; + /* Text pixel */ + *frame_buf_ptr = color; - /* Shadow pixels */ - frame_buf_ptr++; - *frame_buf_ptr = shadow_color; - frame_buf_ptr += fb_width - 1; - /* Small performance hack... */ - *(uint32_t *)frame_buf_ptr = shadow_colour_32; - } + /* Shadow pixels */ + frame_buf_ptr++; + *frame_buf_ptr = shadow_color; + frame_buf_ptr += fb_width - 1; + /* Small performance hack... */ + *(uint32_t *)frame_buf_ptr = shadow_colour_32; } } } - - x += FONT_WIDTH_STRIDE; } + + x += FONT_WIDTH_STRIDE; + } +} + +static void blit_line_extended(int x, int y, + const char *message, uint16_t color, uint16_t shadow_color) +{ + unsigned fb_width = rgui_frame_buf.width; + uint16_t *frame_buf_data = rgui_frame_buf.data; + + while (!string_is_empty(message)) + { + /* Deal with spaces first, for efficiency */ + if (*message == ' ') + message++; + else + { + unsigned i, j; + uint32_t symbol = utf8_walk(&message); + + /* Stupid cretinous hack: 'oe' ligatures are not + * really standard extended ASCII, so we have to + * waste CPU cycles performing a conversion from + * the unicode values... + * (Note: This is only really required for msg_hash_fr.h) */ + if (symbol == 339) /* Latin small ligature oe */ + symbol = 156; + if (symbol == 338) /* Latin capital ligature oe */ + symbol = 140; + + if (symbol >= NUM_FONT_GLYPHS_EXTENDED) + continue; + + for (j = 0; j < FONT_HEIGHT; j++) + { + unsigned buff_offset = ((y + j) * fb_width) + x; + + for (i = 0; i < FONT_WIDTH; i++) + { + if (font_lut[symbol][i + (j * FONT_WIDTH)]) + *(frame_buf_data + buff_offset + i) = color; + } + } + } + + x += FONT_WIDTH_STRIDE; + } +} + +static void blit_line_extended_shadow(int x, int y, + const char *message, uint16_t color, uint16_t shadow_color) +{ + unsigned fb_width = rgui_frame_buf.width; + uint16_t *frame_buf_data = rgui_frame_buf.data; + uint32_t shadow_colour_32 = shadow_color; + + /* Small performance hack... */ + shadow_colour_32 |= shadow_colour_32 << 16; + + while (!string_is_empty(message)) + { + /* Deal with spaces first, for efficiency */ + if (*message == ' ') + message++; + else + { + unsigned i, j; + uint32_t symbol = utf8_walk(&message); + + /* Stupid cretinous hack: 'oe' ligatures are not + * really standard extended ASCII, so we have to + * waste CPU cycles performing a conversion from + * the unicode values... + * (Note: This is only really required for msg_hash_fr.h) */ + if (symbol == 339) /* Latin small ligature oe */ + symbol = 156; + if (symbol == 338) /* Latin capital ligature oe */ + symbol = 140; + + if (symbol >= NUM_FONT_GLYPHS_EXTENDED) + continue; + + for (j = 0; j < FONT_HEIGHT; j++) + { + unsigned buff_offset = ((y + j) * fb_width) + x; + + for (i = 0; i < FONT_WIDTH; i++) + { + if (font_lut[symbol][i + (j * FONT_WIDTH)]) + { + uint16_t *frame_buf_ptr = frame_buf_data + buff_offset + i; + + /* Text pixel */ + *frame_buf_ptr = color; + + /* Shadow pixels */ + frame_buf_ptr++; + *frame_buf_ptr = shadow_color; + frame_buf_ptr += fb_width - 1; + /* Small performance hack... */ + *(uint32_t *)frame_buf_ptr = shadow_colour_32; + } + } + } + } + + x += FONT_WIDTH_STRIDE; + } +} + +static void (*blit_line)(int x, int y, + const char *message, uint16_t color, uint16_t shadow_color) = blit_line_regular; + +static void rgui_set_blit_line_function(bool draw_shadow, bool extended_ascii) +{ + if (draw_shadow) + { + if (extended_ascii) + blit_line = blit_line_extended_shadow; + else + blit_line = blit_line_regular_shadow; } else { - /* Normal version */ - while (!string_is_empty(message)) - { - unsigned i, j; - uint8_t symbol = (uint8_t)*message++; - - if (symbol > 127) - continue; - - if (symbol != ' ') - { - for (j = 0; j < FONT_HEIGHT; j++) - { - unsigned buff_offset = ((y + j) * fb_width) + x; - - for (i = 0; i < FONT_WIDTH; i++) - { - if (font_lut[symbol][i + (j * FONT_WIDTH)]) - *(frame_buf_data + buff_offset + i) = color; - } - } - } - - x += FONT_WIDTH_STRIDE; - } + if (extended_ascii) + blit_line = blit_line_extended; + else + blit_line = blit_line_regular; } } +/* ============================== + * blit_line() END + * ============================== */ + static void rgui_init_font_lut(void) { unsigned symbol_index, i, j; /* Loop over all possible characters */ - for (symbol_index = 0; symbol_index < 128; symbol_index++) + for (symbol_index = 0; symbol_index < NUM_FONT_GLYPHS_EXTENDED; symbol_index++) { for (j = 0; j < FONT_HEIGHT; j++) { @@ -1714,7 +1844,7 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message) if (rgui_frame_buf.data) blit_line(x + 8 + offset_x, y + 8 + offset_y, msg, - rgui->colors.normal_color, rgui->colors.shadow_color, rgui->shadow_enable); + rgui->colors.normal_color, rgui->colors.shadow_color); } end: @@ -1903,7 +2033,7 @@ static void rgui_render(void *data, bool is_idle) /* Draw thumbnail title */ blit_line((int)title_x, 0, thumbnail_title_buf, - rgui->colors.hover_color, rgui->colors.shadow_color, rgui->shadow_enable); + rgui->colors.hover_color, rgui->colors.shadow_color); } } else @@ -1960,7 +2090,7 @@ static void rgui_render(void *data, bool is_idle) (int)(RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) - utf8len(title_buf)) * FONT_WIDTH_STRIDE / 2), RGUI_TERM_START_Y(fb_height) - FONT_HEIGHT_STRIDE, - title_buf, rgui->colors.title_color, rgui->colors.shadow_color, rgui->shadow_enable); + title_buf, rgui->colors.title_color, rgui->colors.shadow_color); /* Print menu entries */ x = RGUI_TERM_START_X(fb_width); @@ -2099,7 +2229,7 @@ static void rgui_render(void *data, bool is_idle) blit_line(x, y, message, entry_selected ? rgui->colors.hover_color : rgui->colors.normal_color, - rgui->colors.shadow_color, rgui->shadow_enable); + rgui->colors.shadow_color); menu_entry_free(&entry); } @@ -2131,7 +2261,7 @@ static void rgui_render(void *data, bool is_idle) RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, sublabel_buf, - rgui->colors.hover_color, rgui->colors.shadow_color, rgui->shadow_enable); + rgui->colors.hover_color, rgui->colors.shadow_color); } else if (settings->bools.menu_core_enable) { @@ -2152,7 +2282,7 @@ static void rgui_render(void *data, bool is_idle) RGUI_TERM_START_X(fb_width) + FONT_WIDTH_STRIDE, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, core_title_buf, - rgui->colors.hover_color, rgui->colors.shadow_color, rgui->shadow_enable); + rgui->colors.hover_color, rgui->colors.shadow_color); } } @@ -2181,7 +2311,7 @@ static void rgui_render(void *data, bool is_idle) timedate_x, (RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y(fb_height) + 2, timedate, - rgui->colors.hover_color, rgui->colors.shadow_color, rgui->shadow_enable); + rgui->colors.hover_color, rgui->colors.shadow_color); } } } @@ -2578,14 +2708,19 @@ static void *rgui_init(void **userdata, bool video_is_threaded) rgui_init_font_lut(); - rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable; - rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; - rgui->border_enable = settings->bools.menu_rgui_border_filler_enable; - rgui->shadow_enable = settings->bools.menu_rgui_shadows; + rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable; + rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; + rgui->border_enable = settings->bools.menu_rgui_border_filler_enable; + rgui->shadow_enable = settings->bools.menu_rgui_shadows; + rgui->extended_ascii_enable = settings->bools.menu_rgui_extended_ascii; rgui->last_width = rgui_frame_buf.width; rgui->last_height = rgui_frame_buf.height; + /* Set initial 'blit_line' function */ + rgui_set_blit_line_function( + settings->bools.menu_rgui_shadows, settings->bools.menu_rgui_extended_ascii); + rgui->thumbnail_path_data = menu_thumbnail_path_init(); if (!rgui->thumbnail_path_data) goto error; @@ -2647,21 +2782,33 @@ static void rgui_frame(void *data, video_frame_info_t *video_info) { rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; rgui->bg_modified = true; - rgui->force_redraw = true; + rgui->force_redraw = true; } if (settings->bools.menu_rgui_border_filler_enable != rgui->border_enable) { rgui->border_enable = settings->bools.menu_rgui_border_filler_enable; rgui->bg_modified = true; - rgui->force_redraw = true; + rgui->force_redraw = true; } if (settings->bools.menu_rgui_shadows != rgui->shadow_enable) { + rgui_set_blit_line_function( + settings->bools.menu_rgui_shadows, settings->bools.menu_rgui_extended_ascii); + rgui->shadow_enable = settings->bools.menu_rgui_shadows; rgui->bg_modified = true; - rgui->force_redraw = true; + rgui->force_redraw = true; + } + + if (settings->bools.menu_rgui_extended_ascii != rgui->extended_ascii_enable) + { + rgui_set_blit_line_function( + settings->bools.menu_rgui_shadows, settings->bools.menu_rgui_extended_ascii); + + rgui->extended_ascii_enable = settings->bools.menu_rgui_extended_ascii; + rgui->force_redraw = true; } if (settings->uints.menu_rgui_color_theme != rgui->color_theme) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 0aa0b97034..6edd0d548a 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6246,6 +6246,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist MENU_ENUM_LABEL_MENU_TICKER_SPEED, PARSE_ONLY_FLOAT, false) == 0) count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_RGUI_EXTENDED_ASCII, + PARSE_ONLY_BOOL, false) == 0) + count++; if (count == 0) menu_entries_append_enum(info->list, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index d374ff1873..4971b40221 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -8526,6 +8526,21 @@ static bool setting_append_list( general_write_handler, general_read_handler, SD_FLAG_NONE); + + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_rgui_extended_ascii, + MENU_ENUM_LABEL_MENU_RGUI_EXTENDED_ASCII, + MENU_ENUM_LABEL_VALUE_MENU_RGUI_EXTENDED_ASCII, + rgui_extended_ascii, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); } if (string_is_equal(settings->arrays.menu_driver, "xmb")) diff --git a/msg_hash.h b/msg_hash.h index 6b840ec10c..2b5d897b7d 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -872,6 +872,7 @@ enum msg_hash_enums MENU_LABEL(MENU_RGUI_ASPECT_RATIO_LOCK), MENU_LABEL(MENU_RGUI_FULL_WIDTH_LAYOUT), MENU_LABEL(MENU_RGUI_SHADOWS), + MENU_LABEL(MENU_RGUI_EXTENDED_ASCII), MENU_LABEL(MENU_LINEAR_FILTER), MENU_LABEL(MENU_HORIZONTAL_ANIMATION), MENU_LABEL(NAVIGATION_WRAPAROUND), From 942d228e3a2578505a94dd1b0838bc74c98e17ed Mon Sep 17 00:00:00 2001 From: natinusala Date: Wed, 10 Apr 2019 16:55:34 +0200 Subject: [PATCH 159/237] menu widgets: fix screenshot flash tainting the image --- menu/widgets/menu_widgets.c | 16 +++++++++------- menu/widgets/menu_widgets.h | 2 -- tasks/task_screenshot.c | 5 ----- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/menu/widgets/menu_widgets.c b/menu/widgets/menu_widgets.c index 4b83e7bd11..ef76fa5f0b 100644 --- a/menu/widgets/menu_widgets.c +++ b/menu/widgets/menu_widgets.c @@ -1926,13 +1926,7 @@ static void menu_widgets_screenshot_fadeout(void *userdata) menu_animation_push(&entry); } -void menu_widgets_screenshot_taken(const char *shotname, const char *filename) -{ - strlcpy(screenshot_filename, filename, sizeof(screenshot_filename)); - strlcpy(screenshot_shotname, shotname, sizeof(screenshot_shotname)); -} - -void menu_widgets_take_screenshot(void) +static void menu_widgets_play_screenshot_flash(void) { menu_animation_ctx_entry_t entry; @@ -1950,6 +1944,14 @@ void menu_widgets_take_screenshot(void) menu_animation_push(&entry); } +void menu_widgets_screenshot_taken(const char *shotname, const char *filename) +{ + menu_widgets_play_screenshot_flash(); + strlcpy(screenshot_filename, filename, sizeof(screenshot_filename)); + strlcpy(screenshot_shotname, shotname, sizeof(screenshot_shotname)); +} + + bool menu_widgets_task_msg_queue_push(retro_task_t *task, const char *msg, unsigned prio, unsigned duration, diff --git a/menu/widgets/menu_widgets.h b/menu/widgets/menu_widgets.h index bf370fc9c6..a2dacaa72d 100644 --- a/menu/widgets/menu_widgets.h +++ b/menu/widgets/menu_widgets.h @@ -60,8 +60,6 @@ bool menu_widgets_task_msg_queue_push(retro_task_t *task, unsigned prio, unsigned duration, bool flush); -void menu_widgets_take_screenshot(void); - void menu_widgets_screenshot_taken(const char *shotname, const char *filename); void menu_widgets_start_load_content_animation(const char *content_name, bool remove_extension); diff --git a/tasks/task_screenshot.c b/tasks/task_screenshot.c index e2a229db23..3138326129 100644 --- a/tasks/task_screenshot.c +++ b/tasks/task_screenshot.c @@ -458,11 +458,6 @@ bool take_screenshot(const char *name_base, bool silence, bool has_valid_framebu bool is_perfcnt_enable = false; bool ret = false; -#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) - if (!silence) - menu_widgets_take_screenshot(); -#endif - runloop_get_status(&is_paused, &is_idle, &is_slowmotion, &is_perfcnt_enable); ret = take_screenshot_choice(name_base, silence, is_paused, is_idle, From f941d4e625988d4b753cb93bbd04b763ac218e5d Mon Sep 17 00:00:00 2001 From: natinusala Date: Thu, 11 Apr 2019 16:46:29 +0200 Subject: [PATCH 160/237] menu widgets: add first achievement notification widget --- .vscode/settings.json | 3 +- cheevos-new/cheevos.c | 17 ++- cheevos/cheevos.c | 26 +++- gfx/font_driver.c | 2 + intl/msg_hash_us.h | 4 + menu/widgets/menu_widgets.c | 258 ++++++++++++++++++++++++++++++++---- menu/widgets/menu_widgets.h | 5 +- msg_hash.h | 1 + 8 files changed, 278 insertions(+), 38 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7f80c61030..c2e6cabd58 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -67,7 +67,8 @@ "menu_input_dialog.h": "c", "menu_filebrowser.h": "c", "ozone_sidebar.h": "c", - "menu_thumbnail_path.h": "c" + "menu_thumbnail_path.h": "c", + "badges.h": "c" }, "C_Cpp.dimInactiveRegions": false, } \ No newline at end of file diff --git a/cheevos-new/cheevos.c b/cheevos-new/cheevos.c index 5276d006d4..0524cf7338 100644 --- a/cheevos-new/cheevos.c +++ b/cheevos-new/cheevos.c @@ -35,6 +35,9 @@ #ifdef HAVE_MENU #include "../menu/menu_driver.h" #include "../menu/menu_entries.h" +#ifdef HAVE_MENU_WIDGETS +#include "../menu/widgets/menu_widgets.h" +#endif #endif #ifdef HAVE_THREADS @@ -492,9 +495,14 @@ static void cheevos_award(cheevos_cheevo_t* cheevo, int mode) cheevo->active &= ~CHEEVOS_ACTIVE_SOFTCORE; /* Show the OSD message. */ - snprintf(buffer, sizeof(buffer), "Achievement Unlocked: %s", cheevo->info->title); - runloop_msg_queue_push(buffer, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - runloop_msg_queue_push(cheevo->info->description, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (!video_driver_has_widgets() || !menu_widgets_push_achievement(cheevo->title, cheevo->badge)) +#endif + { + snprintf(buffer, sizeof(buffer), "Achievement Unlocked: %s", cheevo->info->title); + runloop_msg_queue_push(buffer, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + runloop_msg_queue_push(cheevo->info->description, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + } /* Start the award task. */ if ((mode & CHEEVOS_ACTIVE_HARDCORE) != 0) @@ -1676,6 +1684,9 @@ found: badges_ctx = new_badges_ctx; +#ifdef HAVE_MENU_WIDGETS + if (false) /* we always want badges if menu widgets are enabled */ +#endif { settings_t *settings = config_get_ptr(); if (!( diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index d56afeaab5..8dd2b2c995 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -36,6 +36,9 @@ #ifdef HAVE_MENU #include "../menu/menu_driver.h" #include "../menu/menu_entries.h" +#ifdef HAVE_MENU_WIDGETS +#include "../menu/widgets/menu_widgets.h" +#endif #endif #ifdef HAVE_THREADS @@ -1643,9 +1646,8 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) } else if (valid) { - char msg[256]; char url[256]; - msg[0] = url[0] = '\0'; + url[0] = '\0'; cheevo->active &= ~mode; @@ -1655,11 +1657,18 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) CHEEVOS_LOG("[CHEEVOS]: awarding cheevo %u: %s (%s).\n", cheevo->id, cheevo->title, cheevo->description); - snprintf(msg, sizeof(msg), "Achievement Unlocked: %s", - cheevo->title); - msg[sizeof(msg) - 1] = 0; - runloop_msg_queue_push(msg, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - runloop_msg_queue_push(cheevo->description, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); +#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) + if (!video_driver_has_widgets() || !menu_widgets_push_achievement(cheevo->title, cheevo->badge)) +#endif + { + char msg[256]; + msg[0] = '\0'; + snprintf(msg, sizeof(msg), "Achievement Unlocked: %s", + cheevo->title); + msg[sizeof(msg) - 1] = 0; + runloop_msg_queue_push(msg, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + runloop_msg_queue_push(cheevo->description, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + } cheevos_make_unlock_url(cheevo, url, sizeof(url)); task_push_http_transfer(url, true, NULL, @@ -3195,6 +3204,9 @@ found: badges_ctx = new_badges_ctx; +#ifdef HAVE_MENU_WIDGETS + if (false) /* we always want badges if menu widgets are enabled */ +#endif { settings_t *settings = config_get_ptr(); if (!( diff --git a/gfx/font_driver.c b/gfx/font_driver.c index 0c84999394..936872675a 100644 --- a/gfx/font_driver.c +++ b/gfx/font_driver.c @@ -1074,6 +1074,8 @@ int font_driver_get_message_width(void *font_data, const char *msg, unsigned len, float scale) { font_data_t *font = (font_data_t*)(font_data ? font_data : video_font_driver); + if (len == 0 && msg) + len = (unsigned)strlen(msg); if (font && font->renderer && font->renderer->get_message_width) return font->renderer->get_message_width(font->renderer_data, msg, len, scale); return -1; diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 252f8bcc99..18203be721 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -4882,6 +4882,10 @@ MSG_HASH( MSG_SCREENSHOT_SAVED, "Screenshot saved" ) +MSG_HASH( + MSG_ACHIEVEMENT_UNLOCKED, + "Achievement Unlocked" + ) MSG_HASH( MSG_CHANGE_THUMBNAIL_TYPE, "Change thumbnail type" diff --git a/menu/widgets/menu_widgets.c b/menu/widgets/menu_widgets.c index ef76fa5f0b..999890b8e8 100644 --- a/menu/widgets/menu_widgets.c +++ b/menu/widgets/menu_widgets.c @@ -38,8 +38,9 @@ #define PI 3.14159265359f -/* TODO: Fix context reset freezing everything in place (probably kills animations when it shouldn't anymore) */ +#define max(x, y) x >= y ? x : y +/* TODO: Fix context reset freezing everything in place (probably kills animations when it shouldn't anymore) */ static float msg_queue_background[16] = COLOR_HEX_TO_FLOAT(0x3A3A3A, 1.0f); static float msg_queue_info[16] = COLOR_HEX_TO_FLOAT(0x12ACF8, 1.0f); @@ -79,6 +80,17 @@ static float menu_widgets_pure_white[16] = { 1.00, 1.00, 1.00, 1.00, }; +/* Achievement notification */ +static char *cheevo_title = NULL; +static char *cheevo_badge = NULL; +static float cheevo_unfold = 0.0f; + +static menu_timer_t cheevo_timer; + +static float cheevo_y = 0.0f; +static unsigned cheevo_width = 0; +static unsigned cheevo_height = 0; + /* Load content animation */ #define ANIMATION_LOAD_CONTENT_DURATION 333 @@ -98,7 +110,7 @@ static float load_content_animation_final_fade_alpha; static menu_timer_t load_content_animation_end_timer; -static float menu_widgets_backdrop_orig[16] = { +static float menu_widgets_backdrop_orig[16] = { 0.00, 0.00, 0.00, 0.75, 0.00, 0.00, 0.00, 0.75, 0.00, 0.00, 0.00, 0.75, @@ -188,7 +200,9 @@ enum menu_widgets_icon MENU_WIDGETS_ICON_INFO, - MENU_WIDGETS_ICON_LAST + MENU_WIDGETS_ICON_ACHIEVEMENT, + + MENU_WIDGETS_ICON_LAST, }; static char *menu_widgets_icons_names[MENU_WIDGETS_ICON_LAST] = { @@ -205,7 +219,9 @@ static char *menu_widgets_icons_names[MENU_WIDGETS_ICON_LAST] = { "menu_hourglass.png", "menu_check.png", - "menu_info.png" + "menu_info.png", + + "menu_achievements.png" }; static menu_texture_item menu_widgets_icons_textures[MENU_WIDGETS_ICON_LAST] = {0}; @@ -1211,7 +1227,7 @@ static void menu_widgets_draw_regular_msg(menu_widget_msg_t *msg, video_frame_in icon, msg_queue_spacing + msg_queue_internal_icon_offset, video_info->height - msg->offset_y - msg_queue_icon_offset_y + msg_queue_internal_icon_offset, video_info->width, video_info->height, 0, 1, menu_widgets_pure_white); - + menu_display_blend_end(video_info); } } @@ -1305,21 +1321,21 @@ void menu_widgets_frame(video_frame_info_t *video_info) menu_display_set_alpha(menu_widgets_backdrop_orig, DEFAULT_BACKDROP); menu_display_draw_quad(video_info, - 0, screenshot_y, + 0, screenshot_y, screenshot_width, screenshot_height, video_info->width, video_info->height, menu_widgets_backdrop_orig ); menu_display_set_alpha(menu_widgets_pure_white, 1.0f); - menu_widgets_draw_icon(video_info, - screenshot_thumbnail_width, screenshot_thumbnail_height, - screenshot_texture, - 0, screenshot_y, - video_info->width, video_info->height, + menu_widgets_draw_icon(video_info, + screenshot_thumbnail_width, screenshot_thumbnail_height, + screenshot_texture, + 0, screenshot_y, + video_info->width, video_info->height, 0, 1, menu_widgets_pure_white ); - + menu_display_draw_text(font_regular, msg_hash_to_str(MSG_SCREENSHOT_SAVED), screenshot_thumbnail_width + simple_widget_padding, settings->floats.video_font_size * 1.9f + screenshot_y, @@ -1347,6 +1363,86 @@ void menu_widgets_frame(video_frame_info_t *video_info) ); } + /* Achievement notification */ + if (cheevo_title) + { + unsigned unfold_offet = ((1.0f-cheevo_unfold) * cheevo_width/2); + + menu_display_set_alpha(menu_widgets_backdrop_orig, DEFAULT_BACKDROP); + + /* Default icon */ + if (!cheevo_badge) + { + /* Backdrop */ + menu_display_draw_quad(video_info, + 0, (int)cheevo_y, + cheevo_height, cheevo_height, + video_info->width, video_info->height, + menu_widgets_backdrop_orig); + + /* Icon */ + if (menu_widgets_icons_textures[MENU_WIDGETS_ICON_ACHIEVEMENT]) + { + menu_display_blend_begin(video_info); + menu_display_set_alpha(menu_widgets_pure_white, 1.0f); + menu_widgets_draw_icon(video_info, + cheevo_height, cheevo_height, + menu_widgets_icons_textures[MENU_WIDGETS_ICON_ACHIEVEMENT], 0, cheevo_y, + video_info->width, video_info->height, 0, 1, menu_widgets_pure_white); + menu_display_blend_end(video_info); + } + } + /* Badge */ + else + { + /* TODO: Display the badge */ + } + + if (cheevo_unfold != 1.0f) + { + menu_display_scissor_begin(video_info, + cheevo_height, 0, + (unsigned)((float)(cheevo_width) * cheevo_unfold), cheevo_height); + } + + /* Backdrop */ + menu_display_draw_quad(video_info, + cheevo_height, (int)cheevo_y, + cheevo_width, cheevo_height, + video_info->width, video_info->height, + menu_widgets_backdrop_orig); + + /* Title */ + menu_display_draw_text(font_regular, + msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED), + cheevo_height + simple_widget_padding - unfold_offet, settings->floats.video_font_size * 1.9f + cheevo_y, + video_info->width, video_info->height, + text_color_faint, + TEXT_ALIGN_LEFT, + 1, false, 0, true + ); + + /* Title */ + + /* TODO: is a ticker necessary ? */ + + menu_display_draw_text(font_regular, + cheevo_title, + cheevo_height + simple_widget_padding - unfold_offet, settings->floats.video_font_size * 2.9f + cheevo_y, + video_info->width, video_info->height, + text_color_info, + TEXT_ALIGN_LEFT, + 1, false, 0, true + ); + + if (cheevo_unfold != 1.0f) + { + font_driver_flush(video_info->width, video_info->height, font_regular, video_info); + font_raster_regular.carr.coords.vertices = 0; + menu_display_scissor_end(video_info); + } + } + /* Volume */ if (volume_alpha > 0.0f) { @@ -1700,9 +1796,9 @@ void menu_widgets_context_reset(bool is_threaded) } /* Metrics */ - simple_widget_padding = settings->floats.video_font_size * 2/3; - simple_widget_height = settings->floats.video_font_size + simple_widget_padding; - glyph_width = font_driver_get_message_width(font_regular, "a", 1, 1); + simple_widget_padding = settings->floats.video_font_size * 2/3; + simple_widget_height = settings->floats.video_font_size + simple_widget_padding; + glyph_width = font_driver_get_message_width(font_regular, "a", 1, 1); msg_queue_height = settings->floats.video_font_size * 2.5f; @@ -1772,6 +1868,21 @@ void menu_widgets_context_destroy(void) font_bold = NULL; } +static void menu_widgets_achievement_free(void *userdata) +{ + if (cheevo_title) + { + free(cheevo_title); + cheevo_title = NULL; + } + + if (cheevo_badge) + { + free(cheevo_badge); + cheevo_badge = NULL; + } +} + void menu_widgets_free(void) { int i; @@ -1802,7 +1913,7 @@ void menu_widgets_free(void) } /* Purge everything from the list */ - if (current_msgs) + if (current_msgs) { for (i = 0; i < current_msgs->size; i++) { @@ -1813,6 +1924,10 @@ void menu_widgets_free(void) file_list_free(current_msgs); } + /* Achievement notification */ + menu_widgets_achievement_free(NULL); + + /* Screenshot texture */ video_driver_texture_unload(&screenshot_texture); /* Font */ @@ -1859,15 +1974,6 @@ bool menu_widgets_volume_update_and_show(void) volume_text_alpha = 1.0f; volume_mute = mute; - /* TODO/FIXME - natinusula - - * -menu/widgets/menu_widgets.c: In function 'menu_widgets_volume_update_and_show': -menu/widgets/menu_widgets.c:1859:19: warning: assignment to 'tween_cb' {aka 'void (*)(void *)'} from incompatible pointer type 'void (*)(void)' [-Wincompatible-pointer-types] - entry.cb = menu_widgets_volume_timer_end; - ^ - * - * - */ entry.cb = menu_widgets_volume_timer_end; entry.duration = VOLUME_DURATION; entry.userdata = NULL; @@ -1951,7 +2057,6 @@ void menu_widgets_screenshot_taken(const char *shotname, const char *filename) strlcpy(screenshot_shotname, shotname, sizeof(screenshot_shotname)); } - bool menu_widgets_task_msg_queue_push(retro_task_t *task, const char *msg, unsigned prio, unsigned duration, @@ -2080,6 +2185,107 @@ void menu_widgets_start_load_content_animation(const char *content_name, bool re load_content_animation_running = true; } +static void menu_widgets_achievement_dismiss(void *userdata) +{ + menu_animation_ctx_entry_t entry; + + /* Slide up animation */ + entry.cb = menu_widgets_achievement_free; + entry.duration = MSG_QUEUE_ANIMATION_DURATION; + entry.easing_enum = EASING_OUT_QUAD; + entry.subject = &cheevo_y; + entry.tag = generic_tag; + entry.target_value = (float)(-(int)(cheevo_height)); + entry.userdata = NULL; + + menu_animation_push(&entry); +} + +static void menu_widgets_achievement_fold(void *userdata) +{ + menu_animation_ctx_entry_t entry; + + /* Fold */ + entry.cb = menu_widgets_achievement_dismiss; + entry.duration = MSG_QUEUE_ANIMATION_DURATION; + entry.easing_enum = EASING_OUT_QUAD; + entry.subject = &cheevo_unfold; + entry.tag = generic_tag; + entry.target_value = 0.0f; + entry.userdata = NULL; + + menu_animation_push(&entry); +} + +static void menu_widgets_achievement_unfold(void *userdata) +{ + menu_animation_ctx_entry_t entry; + menu_timer_ctx_entry_t timer; + + /* Unfold */ + entry.cb = NULL; + entry.duration = MSG_QUEUE_ANIMATION_DURATION; + entry.easing_enum = EASING_OUT_QUAD; + entry.subject = &cheevo_unfold; + entry.tag = generic_tag; + entry.target_value = 1.0f; + entry.userdata = NULL; + + menu_animation_push(&entry); + + /* Wait before dismissing */ + timer.cb = menu_widgets_achievement_fold; + timer.duration = MSG_QUEUE_ANIMATION_DURATION + CHEEVO_NOTIFICATION_DURATION; + timer.userdata = NULL; + + menu_timer_start(&cheevo_timer, &timer); +} + +static void menu_widgets_start_achievement_notification() +{ + settings_t *settings = config_get_ptr(); + menu_animation_ctx_entry_t entry; + cheevo_height = settings->floats.video_font_size * 4; + cheevo_width = max( + font_driver_get_message_width(font_regular, msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED), 0, 1), + font_driver_get_message_width(font_regular, cheevo_title, 0, 1) + ); + cheevo_width += simple_widget_padding * 2; + cheevo_y = (float)(-(int)cheevo_height); + cheevo_unfold = 0.0f; + + /* Slide down animation */ + entry.cb = menu_widgets_achievement_unfold; + entry.duration = MSG_QUEUE_ANIMATION_DURATION; + entry.easing_enum = EASING_OUT_QUAD; + entry.subject = &cheevo_y; + entry.tag = generic_tag; + entry.target_value = 0.0f; + entry.userdata = NULL; + + menu_animation_push(&entry); +} + +bool menu_widgets_push_achievement(const char *title, const char *badge) +{ + if (!menu_widgets_inited) + return false; + + menu_widgets_achievement_free(NULL); + + /* TODO: Make a queue of notifications to display */ + + cheevo_title = strdup(title); + + /* TODO: Check if badge exists before copying it */ + /* cheevo_badge = strdup(badge); */ + cheevo_badge = NULL; + + menu_widgets_start_achievement_notification(); + + return true; +} + bool menu_widgets_ready(void) { return menu_widgets_inited; diff --git a/menu/widgets/menu_widgets.h b/menu/widgets/menu_widgets.h index a2dacaa72d..aef16bd19e 100644 --- a/menu/widgets/menu_widgets.h +++ b/menu/widgets/menu_widgets.h @@ -31,6 +31,7 @@ #define SCREENSHOT_DURATION_IN 66 #define SCREENSHOT_DURATION_OUT SCREENSHOT_DURATION_IN*10 #define SCREENSHOT_NOTIFICATION_DURATION 4000 +#define CHEEVO_NOTIFICATION_DURATION 4000 #define TASK_FINISHED_DURATION 3000 #define HOURGLASS_INTERVAL 5000 #define HOURGLASS_DURATION 1000 @@ -69,8 +70,10 @@ void menu_widgets_context_reset(bool is_threaded); void menu_widgets_context_destroy(void); +bool menu_widgets_push_achievement(const char *title, const char *badge); + /* All the functions below should be called in - * the video driver - once they are all added, set + * the video driver - once they are all added, set * enable_menu_widgets to true for that driver */ void menu_widgets_frame(video_frame_info_t *video_info); diff --git a/msg_hash.h b/msg_hash.h index 6b840ec10c..b87ace9ae6 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -347,6 +347,7 @@ enum msg_hash_enums MSG_MOVIE_PLAYBACK_ENDED, MSG_TAKING_SCREENSHOT, MSG_SCREENSHOT_SAVED, + MSG_ACHIEVEMENT_UNLOCKED, MSG_CHANGE_THUMBNAIL_TYPE, MSG_NO_THUMBNAIL_AVAILABLE, MSG_PRESS_AGAIN_TO_QUIT, From 8287049a13362b35966675c54c25998e92396045 Mon Sep 17 00:00:00 2001 From: natinusala Date: Thu, 11 Apr 2019 17:35:13 +0200 Subject: [PATCH 161/237] menu widgets: add badges to achievement notification --- cheevos-new/cheevos.c | 2 +- cheevos/badges.c | 2 +- menu/widgets/menu_widgets.c | 47 +++++++++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/cheevos-new/cheevos.c b/cheevos-new/cheevos.c index 0524cf7338..0a0d7ba6ac 100644 --- a/cheevos-new/cheevos.c +++ b/cheevos-new/cheevos.c @@ -496,7 +496,7 @@ static void cheevos_award(cheevos_cheevo_t* cheevo, int mode) /* Show the OSD message. */ #if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) - if (!video_driver_has_widgets() || !menu_widgets_push_achievement(cheevo->title, cheevo->badge)) + if (!video_driver_has_widgets() || !menu_widgets_push_achievement(cheevo->info->title, cheevo->info->badge)) #endif { snprintf(buffer, sizeof(buffer), "Achievement Unlocked: %s", cheevo->info->title); diff --git a/cheevos/badges.c b/cheevos/badges.c index 3232a9d449..6dec002aa6 100644 --- a/cheevos/badges.c +++ b/cheevos/badges.c @@ -47,7 +47,7 @@ void set_badge_menu_texture(badges_ctx_t * badges, int i) PATH_MAX_LENGTH * sizeof(char), APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES); -#ifdef HAVE_MENU +#if defined(HAVE_MENU) || defined(HAVE_MENU_WIDGETS) menu_display_reset_textures_list(badge_file, fullpath, &badges->menu_texture_list[i],TEXTURE_FILTER_MIPMAP_LINEAR, NULL, NULL); #endif diff --git a/menu/widgets/menu_widgets.c b/menu/widgets/menu_widgets.c index 999890b8e8..bbf738527e 100644 --- a/menu/widgets/menu_widgets.c +++ b/menu/widgets/menu_widgets.c @@ -1,6 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2014-2017 - Jean-André Santoni - * Copyright (C) 2018 - natinusala + * Copyright (C) 2015-2018 - Andre Leiradella + * Copyright (C) 2018-2019 - natinusala * * 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- @@ -81,9 +82,9 @@ static float menu_widgets_pure_white[16] = { }; /* Achievement notification */ -static char *cheevo_title = NULL; -static char *cheevo_badge = NULL; -static float cheevo_unfold = 0.0f; +static char *cheevo_title = NULL; +static menu_texture_item cheevo_badge = 0; +static float cheevo_unfold = 0.0f; static menu_timer_t cheevo_timer; @@ -1369,6 +1370,7 @@ void menu_widgets_frame(video_frame_info_t *video_info) unsigned unfold_offet = ((1.0f-cheevo_unfold) * cheevo_width/2); menu_display_set_alpha(menu_widgets_backdrop_orig, DEFAULT_BACKDROP); + menu_display_set_alpha(menu_widgets_pure_white, 1.0f); /* Default icon */ if (!cheevo_badge) @@ -1384,7 +1386,6 @@ void menu_widgets_frame(video_frame_info_t *video_info) if (menu_widgets_icons_textures[MENU_WIDGETS_ICON_ACHIEVEMENT]) { menu_display_blend_begin(video_info); - menu_display_set_alpha(menu_widgets_pure_white, 1.0f); menu_widgets_draw_icon(video_info, cheevo_height, cheevo_height, menu_widgets_icons_textures[MENU_WIDGETS_ICON_ACHIEVEMENT], 0, cheevo_y, @@ -1395,7 +1396,10 @@ void menu_widgets_frame(video_frame_info_t *video_info) /* Badge */ else { - /* TODO: Display the badge */ + menu_widgets_draw_icon(video_info, + cheevo_height, cheevo_height, + cheevo_badge, 0, cheevo_y, + video_info->width, video_info->height, 0, 1, menu_widgets_pure_white); } if (cheevo_unfold != 1.0f) @@ -1878,8 +1882,8 @@ static void menu_widgets_achievement_free(void *userdata) if (cheevo_badge) { - free(cheevo_badge); - cheevo_badge = NULL; + video_driver_texture_unload(&cheevo_badge); + cheevo_badge = 0; } } @@ -2266,6 +2270,28 @@ static void menu_widgets_start_achievement_notification() menu_animation_push(&entry); } +static void menu_widgets_get_badge_texture(menu_texture_item *tex, const char *badge) +{ + char badge_file[16]; + char fullpath[PATH_MAX_LENGTH]; + settings_t *settings = config_get_ptr(); + + if (!badge || !settings || !settings->bools.cheevos_badges_enable) + { + *tex = 0; + return; + } + + snprintf(badge_file, sizeof(badge_file), "%s.png", badge); + + fill_pathname_application_special(fullpath, + PATH_MAX_LENGTH * sizeof(char), + APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES); + + menu_display_reset_textures_list(badge_file, fullpath, + tex, TEXTURE_FILTER_MIPMAP_LINEAR, NULL, NULL); +} + bool menu_widgets_push_achievement(const char *title, const char *badge) { if (!menu_widgets_inited) @@ -2276,10 +2302,7 @@ bool menu_widgets_push_achievement(const char *title, const char *badge) /* TODO: Make a queue of notifications to display */ cheevo_title = strdup(title); - - /* TODO: Check if badge exists before copying it */ - /* cheevo_badge = strdup(badge); */ - cheevo_badge = NULL; + menu_widgets_get_badge_texture(&cheevo_badge, badge); menu_widgets_start_achievement_notification(); From 71bfd98012983e5bdc09088bde368a0673a8ec93 Mon Sep 17 00:00:00 2001 From: radius Date: Thu, 11 Apr 2019 18:18:37 -0500 Subject: [PATCH 162/237] [subsystem] allow loading from history --- menu/cbs/menu_cbs_ok.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 730aeaa375..7ae36ebea9 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -1715,9 +1715,17 @@ static int action_ok_playlist_entry_collection(const char *path, playlist_t *tmp_playlist = NULL; menu_handle_t *menu = NULL; + const char *subsystem_ident = NULL; + const struct string_list + *subsystem_rom_list = NULL; + unsigned i = 0; + + if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); + + new_core_path[0] = '\0'; tmp_playlist = playlist_get_cached(); @@ -1735,7 +1743,32 @@ static int action_ok_playlist_entry_collection(const char *path, selection_ptr = entry_idx; playlist_get_index(playlist, selection_ptr, - &entry_path, &entry_label, &core_path, &core_name, NULL, NULL, NULL, NULL); + &entry_path, &entry_label, &core_path, &core_name, NULL, NULL, &subsystem_ident, &subsystem_rom_list); + + + /* Subsystem codepath */ + if (!string_is_empty(subsystem_ident) && subsystem_rom_list) + { + content_ctx_info_t content_info = {0}; + task_push_load_new_core(core_path, NULL, + &content_info, CORE_TYPE_PLAIN, NULL, NULL); + content_clear_subsystem(); + if (!content_set_subsystem_by_name(subsystem_ident)) + { + RARCH_LOG("[playlist] subsystem not found in implementation\n"); + /* TODO: Add OSD message telling users that content can't be loaded */ + return 0; + } + + for (i = 0; i < subsystem_rom_list->size; i++) + content_add_subsystem(subsystem_rom_list->elems[i].data); + task_push_load_subsystem_with_core_from_menu( + NULL, &content_info, + CORE_TYPE_PLAIN, NULL, NULL); + /* TODO: update playlist entry? move to first position I guess? */ + return 1; + } + /* Is the core path / name of the playlist entry not yet filled in? */ if ( string_is_equal(core_path, file_path_str(FILE_PATH_DETECT)) From 729f13cad4af202d8498a11ed21f3852ead3ac8a Mon Sep 17 00:00:00 2001 From: bparker06 Date: Thu, 11 Apr 2019 19:45:28 -0400 Subject: [PATCH 163/237] Update menu_cbs_ok.c --- menu/cbs/menu_cbs_ok.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 7ae36ebea9..8999fe2c30 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -1720,12 +1720,9 @@ static int action_ok_playlist_entry_collection(const char *path, *subsystem_rom_list = NULL; unsigned i = 0; - if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); - - new_core_path[0] = '\0'; tmp_playlist = playlist_get_cached(); @@ -1736,6 +1733,7 @@ static int action_ok_playlist_entry_collection(const char *path, if (!tmp_playlist) return menu_cbs_exit(); + playlist_initialized = true; } @@ -1745,14 +1743,16 @@ static int action_ok_playlist_entry_collection(const char *path, playlist_get_index(playlist, selection_ptr, &entry_path, &entry_label, &core_path, &core_name, NULL, NULL, &subsystem_ident, &subsystem_rom_list); - /* Subsystem codepath */ - if (!string_is_empty(subsystem_ident) && subsystem_rom_list) + if (!string_is_empty(subsystem_ident)) { - content_ctx_info_t content_info = {0}; + content_ctx_info_t content_info = {0}; + task_push_load_new_core(core_path, NULL, &content_info, CORE_TYPE_PLAIN, NULL, NULL); + content_clear_subsystem(); + if (!content_set_subsystem_by_name(subsystem_ident)) { RARCH_LOG("[playlist] subsystem not found in implementation\n"); @@ -1762,6 +1762,7 @@ static int action_ok_playlist_entry_collection(const char *path, for (i = 0; i < subsystem_rom_list->size; i++) content_add_subsystem(subsystem_rom_list->elems[i].data); + task_push_load_subsystem_with_core_from_menu( NULL, &content_info, CORE_TYPE_PLAIN, NULL, NULL); @@ -1769,7 +1770,6 @@ static int action_ok_playlist_entry_collection(const char *path, return 1; } - /* Is the core path / name of the playlist entry not yet filled in? */ if ( string_is_equal(core_path, file_path_str(FILE_PATH_DETECT)) && string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) From d08779adf039d16f94a1e80aa08207c23af827b8 Mon Sep 17 00:00:00 2001 From: radius Date: Thu, 11 Apr 2019 18:51:27 -0500 Subject: [PATCH 164/237] [subsystem] add a function to get the friendly name --- content.h | 3 +++ tasks/task_content.c | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/content.h b/content.h index 20ff9cd9aa..fb44c05e21 100644 --- a/content.h +++ b/content.h @@ -112,6 +112,9 @@ char* content_get_subsystem_rom(unsigned index); /* Sets the subsystem by name */ bool content_set_subsystem_by_name(const char* subsystem_name); +/* Get the current subsystem "friendly name" */ +void content_get_subsystem_friendly_name(const char* subsystem_name, char* subsystem_friendly_name, size_t len); + RETRO_END_DECLS #endif diff --git a/tasks/task_content.c b/tasks/task_content.c index 348cf524e2..ccbdb42a3d 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -1982,6 +1982,28 @@ bool content_set_subsystem_by_name(const char* subsystem_name) return false; } +void content_get_subsystem_friendly_name(const char* subsystem_name, char* subsystem_friendly_name, size_t len) +{ + rarch_system_info_t *system = runloop_get_system_info(); + const struct retro_subsystem_info *subsystem; + unsigned i = 0; + + /* Core fully loaded, use the subsystem data */ + if (system->subsystem.data) + subsystem = system->subsystem.data; + /* Core not loaded completely, use the data we peeked on load core */ + else + subsystem = subsystem_data; + + for (i = 0; i < subsystem_current_count; i++, subsystem++) + { + if (string_is_equal(subsystem_name, subsystem->ident)) + strlcpy(subsystem_friendly_name, subsystem->desc, len); + } + + return; +} + /* Add a rom to the subsystem rom buffer */ void content_add_subsystem(const char* path) { From e85167072e3d0aae2982892717073bcb79cf8cd7 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Thu, 11 Apr 2019 20:46:12 -0500 Subject: [PATCH 165/237] silence redefinition warning go ahead and protect against PI redefinition, too, since that seems very likely to crop up at some point. --- menu/widgets/menu_widgets.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/menu/widgets/menu_widgets.c b/menu/widgets/menu_widgets.c index bbf738527e..9e0335d3a4 100644 --- a/menu/widgets/menu_widgets.c +++ b/menu/widgets/menu_widgets.c @@ -37,9 +37,13 @@ #include #include +#ifndef PI #define PI 3.14159265359f +#endif +#ifndef max(x, y) #define max(x, y) x >= y ? x : y +#endif /* TODO: Fix context reset freezing everything in place (probably kills animations when it shouldn't anymore) */ From 4f004ebebcc093416f5df50497d4c9ba80c2697c Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Thu, 11 Apr 2019 20:51:50 -0500 Subject: [PATCH 166/237] whoops, syntax error --- menu/widgets/menu_widgets.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menu/widgets/menu_widgets.c b/menu/widgets/menu_widgets.c index 9e0335d3a4..406ed728e4 100644 --- a/menu/widgets/menu_widgets.c +++ b/menu/widgets/menu_widgets.c @@ -41,7 +41,7 @@ #define PI 3.14159265359f #endif -#ifndef max(x, y) +#ifndef max #define max(x, y) x >= y ? x : y #endif From a446f8ad515877d4e10becdf4dd4e248c15db852 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Fri, 12 Apr 2019 15:50:27 +0100 Subject: [PATCH 167/237] (RGUI) Add optional delay when loading thumbnails --- config.def.h | 1 + configuration.c | 1 + configuration.h | 1 + intl/msg_hash_lbl.h | 2 + intl/msg_hash_us.h | 8 + menu/cbs/menu_cbs_sublabel.c | 4 + menu/drivers/rgui.c | 283 ++++++++++++++++++++--------------- menu/menu_displaylist.c | 4 + menu/menu_setting.c | 13 ++ msg_hash.h | 1 + 10 files changed, 201 insertions(+), 117 deletions(-) diff --git a/config.def.h b/config.def.h index 3b779d0b4d..9c41045d8b 100644 --- a/config.def.h +++ b/config.def.h @@ -387,6 +387,7 @@ static unsigned rgui_color_theme = RGUI_THEME_CLASSIC_GREEN; static bool rgui_inline_thumbnails = false; static bool rgui_swap_thumbnails = false; static unsigned rgui_thumbnail_downscaler = RGUI_THUMB_SCALE_POINT; +static unsigned rgui_thumbnail_delay = 0; static unsigned rgui_internal_upscale_level = RGUI_UPSCALE_NONE; static bool rgui_full_width_layout = true; static unsigned rgui_aspect = RGUI_ASPECT_RATIO_4_3; diff --git a/configuration.c b/configuration.c index d4bdb2f3ba..fa2043859d 100644 --- a/configuration.c +++ b/configuration.c @@ -1699,6 +1699,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, #ifdef HAVE_RGUI SETTING_UINT("rgui_menu_color_theme", &settings->uints.menu_rgui_color_theme, true, rgui_color_theme, false); SETTING_UINT("rgui_thumbnail_downscaler", &settings->uints.menu_rgui_thumbnail_downscaler, true, rgui_thumbnail_downscaler, false); + SETTING_UINT("rgui_thumbnail_delay", &settings->uints.menu_rgui_thumbnail_delay, true, rgui_thumbnail_delay, false); SETTING_UINT("rgui_internal_upscale_level", &settings->uints.menu_rgui_internal_upscale_level, true, rgui_internal_upscale_level, false); SETTING_UINT("rgui_aspect_ratio", &settings->uints.menu_rgui_aspect_ratio, true, rgui_aspect, false); SETTING_UINT("rgui_aspect_ratio_lock", &settings->uints.menu_rgui_aspect_ratio_lock, true, rgui_aspect_lock, false); diff --git a/configuration.h b/configuration.h index 25852cac04..291f4c879a 100644 --- a/configuration.h +++ b/configuration.h @@ -435,6 +435,7 @@ typedef struct settings unsigned menu_thumbnails; unsigned menu_left_thumbnails; unsigned menu_rgui_thumbnail_downscaler; + unsigned menu_rgui_thumbnail_delay; unsigned menu_dpi_override_value; unsigned menu_rgui_color_theme; unsigned menu_xmb_layout; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 9955b7a197..f03d5d9131 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1131,6 +1131,8 @@ MSG_HASH(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, "xmb_vertical_thumbnails") MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER, "rgui_thumbnail_downscaler") +MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY, + "rgui_thumbnail_delay") MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS, "rgui_inline_thumbnails") MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 07b0f84885..15e1e7295d 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3002,6 +3002,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_MENU_RGUI_SWAP_THUMBNAILS, "Swaps the display positions of 'Top Thumbnail' and 'Bottom Thumbnail'." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_RGUI_THUMBNAIL_DELAY, + "Thumbnail Delay (ms)" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DELAY, + "Applies a time delay between selecting a playlist entry and loading its associated thumbnails. Setting this to a value of at least 256 ms enables fast lag-free scrolling on even the slowest devices." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MENU_RGUI_THUMBNAIL_DOWNSCALER, "Thumbnail Downscaling Method" diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index f79dadc8d0..fb69ad4c2b 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -532,6 +532,7 @@ default_sublabel_macro(action_bind_sublabel_menu_rgui_shadows, default_sublabel_macro(action_bind_sublabel_menu_rgui_inline_thumbnails, MENU_ENUM_SUBLABEL_MENU_RGUI_INLINE_THUMBNAILS) default_sublabel_macro(action_bind_sublabel_menu_rgui_swap_thumbnails, MENU_ENUM_SUBLABEL_MENU_RGUI_SWAP_THUMBNAILS) default_sublabel_macro(action_bind_sublabel_menu_rgui_thumbnail_downscaler, MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER) +default_sublabel_macro(action_bind_sublabel_menu_rgui_thumbnail_delay, MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DELAY) default_sublabel_macro(action_bind_sublabel_content_runtime_log, MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG) default_sublabel_macro(action_bind_sublabel_content_runtime_log_aggregate, MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG_AGGREGATE) default_sublabel_macro(action_bind_sublabel_playlist_sublabel_runtime_type, MENU_ENUM_SUBLABEL_PLAYLIST_SUBLABEL_RUNTIME_TYPE) @@ -2438,6 +2439,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_thumbnail_downscaler); break; + case MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_thumbnail_delay); + break; case MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_runtime_log); break; diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 23ac36b82b..03e9a6f334 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -58,6 +58,7 @@ #include #include "../../tasks/tasks_internal.h" #include +#include #if defined(GEKKO) #define RGUI_TERM_START_X(fb_width) (fb_width / 21) @@ -494,6 +495,8 @@ typedef struct menu_thumbnail_path_data_t *thumbnail_path_data; uint32_t thumbnail_queue_size; uint32_t left_thumbnail_queue_size; + bool thumbnail_load_pending; + retro_time_t thumbnail_load_trigger_time; bool show_wallpaper; char theme_preset_path[PATH_MAX_LENGTH]; /* Must be a fixed length array... */ char menu_title[255]; /* Must be a fixed length array... */ @@ -2727,6 +2730,8 @@ static void *rgui_init(void **userdata, bool video_is_threaded) rgui->thumbnail_queue_size = 0; rgui->left_thumbnail_queue_size = 0; + rgui->thumbnail_load_pending = false; + rgui->thumbnail_load_trigger_time = 0; /* Ensure that we start with fullscreen thumbnails disabled */ rgui->show_fs_thumbnail = false; @@ -2766,89 +2771,6 @@ static void rgui_free(void *data) } } -static void rgui_frame(void *data, video_frame_info_t *video_info) -{ - rgui_t *rgui = (rgui_t*)data; - settings_t *settings = config_get_ptr(); - - if (settings->bools.menu_rgui_background_filler_thickness_enable != rgui->bg_thickness) - { - rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable; - rgui->bg_modified = true; - rgui->force_redraw = true; - } - - if (settings->bools.menu_rgui_border_filler_thickness_enable != rgui->border_thickness) - { - rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; - rgui->bg_modified = true; - rgui->force_redraw = true; - } - - if (settings->bools.menu_rgui_border_filler_enable != rgui->border_enable) - { - rgui->border_enable = settings->bools.menu_rgui_border_filler_enable; - rgui->bg_modified = true; - rgui->force_redraw = true; - } - - if (settings->bools.menu_rgui_shadows != rgui->shadow_enable) - { - rgui_set_blit_line_function( - settings->bools.menu_rgui_shadows, settings->bools.menu_rgui_extended_ascii); - - rgui->shadow_enable = settings->bools.menu_rgui_shadows; - rgui->bg_modified = true; - rgui->force_redraw = true; - } - - if (settings->bools.menu_rgui_extended_ascii != rgui->extended_ascii_enable) - { - rgui_set_blit_line_function( - settings->bools.menu_rgui_shadows, settings->bools.menu_rgui_extended_ascii); - - rgui->extended_ascii_enable = settings->bools.menu_rgui_extended_ascii; - rgui->force_redraw = true; - } - - if (settings->uints.menu_rgui_color_theme != rgui->color_theme) - { - prepare_rgui_colors(rgui, settings); - } - else if (settings->uints.menu_rgui_color_theme == RGUI_THEME_CUSTOM) - { - if (string_is_not_equal_fast(settings->paths.path_rgui_theme_preset, rgui->theme_preset_path, sizeof(rgui->theme_preset_path))) - { - prepare_rgui_colors(rgui, settings); - } - } - - /* Note: both rgui_set_aspect_ratio() and rgui_set_video_config() - * normally call command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL) - * ## THIS CANNOT BE DONE INSIDE rgui_frame() IF THREADED VIDEO IS ENABLED ## - * Attempting to do so creates a deadlock, and causes RetroArch to hang. - * We therefore have to set the 'delay_update' argument, which causes - * command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL) to be called at - * the next instance of rgui_render() */ - if (settings->uints.menu_rgui_aspect_ratio != rgui->menu_aspect_ratio) - rgui_set_aspect_ratio(rgui, true); - - if (settings->uints.menu_rgui_aspect_ratio_lock != rgui->menu_aspect_ratio_lock) - { - rgui->menu_aspect_ratio_lock = settings->uints.menu_rgui_aspect_ratio_lock; - - if (settings->uints.menu_rgui_aspect_ratio_lock == RGUI_ASPECT_RATIO_LOCK_NONE) - { - rgui_set_video_config(rgui, &rgui->content_video_settings, true); - } - else - { - rgui_update_menu_viewport(rgui); - rgui_set_video_config(rgui, &rgui->menu_video_settings, true); - } - } -} - static void rgui_set_texture(void) { size_t fb_pitch; @@ -2969,54 +2891,79 @@ static void rgui_set_thumbnail_system(void *userdata, char *s, size_t len) menu_thumbnail_set_system(rgui->thumbnail_path_data, s); } -static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui) +static void rgui_load_current_thumbnails(rgui_t *rgui) { + const char *thumbnail_path = NULL; + const char *left_thumbnail_path = NULL; + + /* Right (or fullscreen) thumbnail */ + if (menu_thumbnail_get_path(rgui->thumbnail_path_data, + MENU_THUMBNAIL_RIGHT, &thumbnail_path)) + { + rgui->entry_has_thumbnail = request_thumbnail( + rgui->show_fs_thumbnail ? &fs_thumbnail : &mini_thumbnail, + MENU_THUMBNAIL_RIGHT, &rgui->thumbnail_queue_size, thumbnail_path); + } + + /* Left thumbnail + * (Note: there is no need to load this when viewing + * fullscreen thumbnails) */ + if (!rgui->show_fs_thumbnail) + { + if (menu_thumbnail_get_path(rgui->thumbnail_path_data, + MENU_THUMBNAIL_LEFT, &left_thumbnail_path)) + { + rgui->entry_has_left_thumbnail = request_thumbnail( + &mini_left_thumbnail, MENU_THUMBNAIL_LEFT, &rgui->left_thumbnail_queue_size, left_thumbnail_path); + } + } + + /* Reset 'load pending' state */ + rgui->thumbnail_load_pending = false; + + /* Force a redraw (so 'entry_has_thumbnail' values are + * applied immediately) */ + rgui->force_redraw = true; +} + +static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui, bool force_load) +{ + bool has_thumbnail = false; settings_t *settings = config_get_ptr(); if (!settings) return; - rgui->entry_has_thumbnail = false; + rgui->entry_has_thumbnail = false; rgui->entry_has_left_thumbnail = false; + rgui->thumbnail_load_pending = false; + /* Update thumbnail content/path */ if ((rgui->show_fs_thumbnail || settings->bools.menu_rgui_inline_thumbnails) && rgui->is_playlist) { if (menu_thumbnail_set_content_playlist(rgui->thumbnail_path_data, playlist_get_cached(), menu_navigation_get_selection())) { if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)) - { - if (menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_RIGHT)) - { - const char *thumbnail_path = NULL; - - if (menu_thumbnail_get_path(rgui->thumbnail_path_data, - MENU_THUMBNAIL_RIGHT, &thumbnail_path)) - { - if (rgui->show_fs_thumbnail) - rgui->entry_has_thumbnail = request_thumbnail( - &fs_thumbnail, MENU_THUMBNAIL_RIGHT, &rgui->thumbnail_queue_size, thumbnail_path); - else - rgui->entry_has_thumbnail = request_thumbnail( - &mini_thumbnail, MENU_THUMBNAIL_RIGHT, &rgui->thumbnail_queue_size, thumbnail_path); - } - } - } + has_thumbnail = menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_RIGHT); if (settings->bools.menu_rgui_inline_thumbnails && menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)) - { - if (menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_LEFT)) - { - const char *left_thumbnail_path = NULL; - - if (menu_thumbnail_get_path(rgui->thumbnail_path_data, - MENU_THUMBNAIL_LEFT, &left_thumbnail_path)) - { - rgui->entry_has_left_thumbnail = request_thumbnail( - &mini_left_thumbnail, MENU_THUMBNAIL_LEFT, &rgui->left_thumbnail_queue_size, left_thumbnail_path); - } - } - } + has_thumbnail = menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_LEFT) || + has_thumbnail; + } + } + + /* Check whether thumbnails should be loaded */ + if (has_thumbnail) + { + /* Check whether thumbnails should be loaded immediately */ + if ((settings->uints.menu_rgui_thumbnail_delay == 0) || force_load) + rgui_load_current_thumbnails(rgui); + else + { + /* Schedule a delayed load */ + rgui->thumbnail_load_pending = true; + rgui->thumbnail_load_trigger_time = cpu_features_get_time_usec(); } } } @@ -3055,7 +3002,11 @@ static void rgui_update_thumbnail_image(void *userdata) } } - rgui_scan_selected_entry_thumbnail(rgui); + /* Note that we always load thumbnails immediately + * when toggling via the 'scan' button (scheduling a + * delayed load here would make for a poor user + * experience...) */ + rgui_scan_selected_entry_thumbnail(rgui, true); } static void rgui_update_menu_sublabel(rgui_t *rgui) @@ -3116,7 +3067,7 @@ static void rgui_navigation_set(void *data, bool scroll) if (!rgui) return; - rgui_scan_selected_entry_thumbnail(rgui); + rgui_scan_selected_entry_thumbnail(rgui, false); rgui_update_menu_sublabel(rgui); if (!scroll) @@ -3179,6 +3130,9 @@ static void rgui_populate_entries(void *data, /* Set menu title */ menu_entries_get_title(rgui->menu_title, sizeof(rgui->menu_title)); + /* Cancel any pending thumbnail load operations */ + rgui->thumbnail_load_pending = false; + rgui_navigation_set(data, true); /* If aspect ratio lock is enabled, must restore @@ -3251,6 +3205,101 @@ static int rgui_pointer_tap(void *data, return 0; } +static void rgui_frame(void *data, video_frame_info_t *video_info) +{ + rgui_t *rgui = (rgui_t*)data; + settings_t *settings = config_get_ptr(); + + if (settings->bools.menu_rgui_background_filler_thickness_enable != rgui->bg_thickness) + { + rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable; + rgui->bg_modified = true; + rgui->force_redraw = true; + } + + if (settings->bools.menu_rgui_border_filler_thickness_enable != rgui->border_thickness) + { + rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; + rgui->bg_modified = true; + rgui->force_redraw = true; + } + + if (settings->bools.menu_rgui_border_filler_enable != rgui->border_enable) + { + rgui->border_enable = settings->bools.menu_rgui_border_filler_enable; + rgui->bg_modified = true; + rgui->force_redraw = true; + } + + if (settings->bools.menu_rgui_shadows != rgui->shadow_enable) + { + rgui_set_blit_line_function( + settings->bools.menu_rgui_shadows, settings->bools.menu_rgui_extended_ascii); + + rgui->shadow_enable = settings->bools.menu_rgui_shadows; + rgui->bg_modified = true; + rgui->force_redraw = true; + } + + if (settings->bools.menu_rgui_extended_ascii != rgui->extended_ascii_enable) + { + rgui_set_blit_line_function( + settings->bools.menu_rgui_shadows, settings->bools.menu_rgui_extended_ascii); + + rgui->extended_ascii_enable = settings->bools.menu_rgui_extended_ascii; + rgui->force_redraw = true; + } + + if (settings->uints.menu_rgui_color_theme != rgui->color_theme) + { + prepare_rgui_colors(rgui, settings); + } + else if (settings->uints.menu_rgui_color_theme == RGUI_THEME_CUSTOM) + { + if (string_is_not_equal_fast(settings->paths.path_rgui_theme_preset, rgui->theme_preset_path, sizeof(rgui->theme_preset_path))) + { + prepare_rgui_colors(rgui, settings); + } + } + + /* Note: both rgui_set_aspect_ratio() and rgui_set_video_config() + * normally call command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL) + * ## THIS CANNOT BE DONE INSIDE rgui_frame() IF THREADED VIDEO IS ENABLED ## + * Attempting to do so creates a deadlock, and causes RetroArch to hang. + * We therefore have to set the 'delay_update' argument, which causes + * command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL) to be called at + * the next instance of rgui_render() */ + if (settings->uints.menu_rgui_aspect_ratio != rgui->menu_aspect_ratio) + rgui_set_aspect_ratio(rgui, true); + + if (settings->uints.menu_rgui_aspect_ratio_lock != rgui->menu_aspect_ratio_lock) + { + rgui->menu_aspect_ratio_lock = settings->uints.menu_rgui_aspect_ratio_lock; + + if (settings->uints.menu_rgui_aspect_ratio_lock == RGUI_ASPECT_RATIO_LOCK_NONE) + { + rgui_set_video_config(rgui, &rgui->content_video_settings, true); + } + else + { + rgui_update_menu_viewport(rgui); + rgui_set_video_config(rgui, &rgui->menu_video_settings, true); + } + } + + /* Handle pending thumbnail load operations */ + if (rgui->thumbnail_load_pending) + { + /* Check whether current 'load delay' duration has elapsed + * Note: Delay is increased when viewing fullscreen thumbnails, + * since the flicker when switching between playlist view and + * fullscreen thumbnail view is incredibly jarring...) */ + if ((cpu_features_get_time_usec() - rgui->thumbnail_load_trigger_time) >= + (settings->uints.menu_rgui_thumbnail_delay * 1000 * (rgui->show_fs_thumbnail ? 1.5f : 1.0f))) + rgui_load_current_thumbnails(rgui); + } +} + static void rgui_toggle(void *userdata, bool menu_on) { rgui_t *rgui = (rgui_t*)userdata; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index be5ca2b0dd..b621326a67 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6238,6 +6238,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER, PARSE_ONLY_UINT, false) == 0) count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY, + PARSE_ONLY_UINT, false) == 0) + count++; if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_TICKER_TYPE, PARSE_ONLY_UINT, false) == 0) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 4971b40221..f4c1fc7c8b 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -9497,6 +9497,19 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_rgui_thumbnail_scaler; menu_settings_list_current_add_range(list, list_info, 0, RGUI_THUMB_SCALE_LAST-1, 1, true, true); + + CONFIG_UINT( + list, list_info, + &settings->uints.menu_rgui_thumbnail_delay, + MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY, + MENU_ENUM_LABEL_VALUE_MENU_RGUI_THUMBNAIL_DELAY, + rgui_thumbnail_delay, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0.0f, 1024.0f, 64.0f, true, true); } CONFIG_BOOL( diff --git a/msg_hash.h b/msg_hash.h index 55b0d68a1b..2b54064111 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -912,6 +912,7 @@ enum msg_hash_enums MENU_LABEL(MENU_RGUI_INLINE_THUMBNAILS), MENU_LABEL(MENU_RGUI_SWAP_THUMBNAILS), MENU_LABEL(MENU_RGUI_THUMBNAIL_DOWNSCALER), + MENU_LABEL(MENU_RGUI_THUMBNAIL_DELAY), MENU_LABEL(TIMEDATE_ENABLE), MENU_LABEL(TIMEDATE_STYLE), MENU_LABEL(BATTERY_LEVEL_ENABLE), From fed06044c44412eb27bb493c547711d98f89c12f Mon Sep 17 00:00:00 2001 From: Huw Pascoe Date: Fri, 12 Apr 2019 17:28:53 +0100 Subject: [PATCH 168/237] silence warnings --- audio/drivers/xaudio.c | 2 +- dynamic.c | 2 +- gfx/common/vulkan_common.c | 6 +++--- gfx/drivers/gl_core.c | 8 ++++---- gfx/drivers_font_renderer/stb_unicode.c | 2 +- libretro-common/features/features_cpu.c | 2 +- libretro-common/glsym/glsym_gl.c | 2 +- libretro-common/include/compat/msvc.h | 2 ++ pkg/msvc/msvc-2010/RetroArch-msvc2010.vcxproj | 4 ---- pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj | 4 ---- pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj | 8 -------- 11 files changed, 14 insertions(+), 28 deletions(-) diff --git a/audio/drivers/xaudio.c b/audio/drivers/xaudio.c index 4549a5f8d4..7c05c3cc39 100644 --- a/audio/drivers/xaudio.c +++ b/audio/drivers/xaudio.c @@ -219,7 +219,7 @@ static xaudio2_t *xaudio2_new(unsigned samplerate, unsigned channels, goto error; #if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) - if (FAILED(IXAudio2_CreateMasteringVoice(handle->pXAudio2, &handle->pMasterVoice, channels, samplerate, 0, device, NULL, AudioCategory_GameEffects))) + if (FAILED(IXAudio2_CreateMasteringVoice(handle->pXAudio2, &handle->pMasterVoice, channels, samplerate, 0, (LPCWSTR)(uintptr_t)device, NULL, AudioCategory_GameEffects))) goto error; #else if (FAILED(IXAudio2_CreateMasteringVoice(handle->pXAudio2, &handle->pMasterVoice, channels, samplerate, 0, device, NULL))) diff --git a/dynamic.c b/dynamic.c index 0cf7bd830c..a8ca1bd2cd 100644 --- a/dynamic.c +++ b/dynamic.c @@ -1394,7 +1394,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) { unsigned retro_id; const struct retro_input_descriptor *desc = NULL; - memset(&system->input_desc_btn, 0, + memset((void*)&system->input_desc_btn, 0, sizeof(system->input_desc_btn)); desc = (const struct retro_input_descriptor*)data; diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index 95faa57fa8..bf0cdcab1a 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2016-2017 - Hans-Kristian Arntzen * * RetroArch is free software: you can redistribute it and/or modify it under the terms @@ -618,7 +618,7 @@ struct vk_texture vulkan_create_texture(vk_t *vk, RARCH_LOG("[Vulkan]: GPU supports linear images as textures, but not DEVICE_LOCAL. Falling back to copy path.\n"); type = VULKAN_TEXTURE_STAGING; vkDestroyImage(device, tex.image, NULL); - tex.image = NULL; + tex.image = (VkImage)NULL; info.initialLayout = VK_IMAGE_LAYOUT_GENERAL; buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; @@ -1580,7 +1580,7 @@ static bool vulkan_find_device_extensions(VkPhysicalDevice gpu, goto end; } - memcpy(enabled, exts, num_exts * sizeof(*exts)); + memcpy((void*)enabled, exts, num_exts * sizeof(*exts)); *enabled_count = num_exts; for (i = 0; i < num_optional_exts; i++) diff --git a/gfx/drivers/gl_core.c b/gfx/drivers/gl_core.c index 06bab7604e..83c34e8fae 100644 --- a/gfx/drivers/gl_core.c +++ b/gfx/drivers/gl_core.c @@ -400,13 +400,13 @@ static bool gl_core_init_hw_render(gl_core_t *gl, unsigned width, unsigned heigh RARCH_LOG("[GLCore]: Max texture size: %d px, renderbuffer size: %d px.\n", max_fbo_size, max_rb_size); - if (width > max_fbo_size) + if (width > (unsigned)max_fbo_size) width = max_fbo_size; - if (width > max_rb_size) + if (width > (unsigned)max_rb_size) width = max_rb_size; - if (height > max_fbo_size) + if (height > (unsigned)max_fbo_size) height = max_fbo_size; - if (height > max_rb_size) + if (height > (unsigned)max_rb_size) height = max_rb_size; glGenFramebuffers(1, &gl->hw_render_fbo); diff --git a/gfx/drivers_font_renderer/stb_unicode.c b/gfx/drivers_font_renderer/stb_unicode.c index 075490f577..7f31afc6bb 100644 --- a/gfx/drivers_font_renderer/stb_unicode.c +++ b/gfx/drivers_font_renderer/stb_unicode.c @@ -163,7 +163,7 @@ static const struct font_glyph *font_renderer_stb_unicode_get_glyph( /* This means the glyph is empty. In this case, stbtt_MakeGlyphBitmap() * fills the corresponding region of the atlas buffer with garbage, * so just zero it */ - unsigned x, y; + int x, y; for (x = 0; x < self->max_glyph_width; x++) for (y = 0; y < self->max_glyph_height; y++) dst[x + (y * self->atlas.width)] = 0; diff --git a/libretro-common/features/features_cpu.c b/libretro-common/features/features_cpu.c index 443f4187c2..5b4595b055 100644 --- a/libretro-common/features/features_cpu.c +++ b/libretro-common/features/features_cpu.c @@ -872,7 +872,7 @@ void cpu_features_get_model_name(char *name, int len) } end: /* terminate our string */ - if (pos < len) + if (pos < (size_t)len) name[pos] = '\0'; #elif defined(__MACH__) if (!name) diff --git a/libretro-common/glsym/glsym_gl.c b/libretro-common/glsym/glsym_gl.c index 4f0c8280f7..51d3bf0f31 100644 --- a/libretro-common/glsym/glsym_gl.c +++ b/libretro-common/glsym/glsym_gl.c @@ -24,7 +24,7 @@ #include -#define SYM(x) { "gl" #x, &(gl##x) } +#define SYM(x) { "gl" #x, (void*)&(gl##x) } const struct rglgen_sym_map rglgen_symbol_map[] = { #ifdef HAVE_LIBNX diff --git a/libretro-common/include/compat/msvc.h b/libretro-common/include/compat/msvc.h index ad55bd8874..4681b12cf2 100644 --- a/libretro-common/include/compat/msvc.h +++ b/libretro-common/include/compat/msvc.h @@ -56,6 +56,8 @@ extern "C" { #undef UNICODE /* Do not bother with UNICODE at this time. */ #include #include + +#define _USE_MATH_DEFINES #include /* Python headers defines ssize_t and sets HAVE_SSIZE_T. diff --git a/pkg/msvc/msvc-2010/RetroArch-msvc2010.vcxproj b/pkg/msvc/msvc-2010/RetroArch-msvc2010.vcxproj index 70775fbb7a..75e61da9a3 100644 --- a/pkg/msvc/msvc-2010/RetroArch-msvc2010.vcxproj +++ b/pkg/msvc/msvc-2010/RetroArch-msvc2010.vcxproj @@ -228,7 +228,6 @@ MultiThreadedDebug CompileAsCpp Fast - StreamingSIMDExtensions2 OldStyle @@ -248,7 +247,6 @@ MultiThreadedDebug CompileAsCpp Fast - StreamingSIMDExtensions2 OldStyle @@ -324,7 +322,6 @@ MultiThreaded CompileAsCpp Fast - StreamingSIMDExtensions2 true OldStyle @@ -350,7 +347,6 @@ MultiThreaded CompileAsCpp Fast - StreamingSIMDExtensions2 true OldStyle diff --git a/pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj b/pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj index 7be9b56ada..21522d9fc8 100644 --- a/pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj +++ b/pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj @@ -237,7 +237,6 @@ CompileAsCpp /bigobj Fast - StreamingSIMDExtensions2 OldStyle @@ -257,7 +256,6 @@ MultiThreadedDebug CompileAsCpp Fast - StreamingSIMDExtensions2 OldStyle @@ -331,7 +329,6 @@ MultiThreaded CompileAsCpp Fast - StreamingSIMDExtensions2 true OldStyle @@ -356,7 +353,6 @@ MultiThreaded CompileAsCpp Fast - StreamingSIMDExtensions2 true OldStyle diff --git a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj index 16c6f3169e..4c40326883 100644 --- a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj +++ b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj @@ -722,7 +722,6 @@ MultiThreadedDebug CompileAsCpp Fast - StreamingSIMDExtensions2 OldStyle @@ -742,7 +741,6 @@ MultiThreadedDebug CompileAsCpp Fast - StreamingSIMDExtensions2 OldStyle @@ -763,7 +761,6 @@ MultiThreadedDebug CompileAsCpp Fast - StreamingSIMDExtensions2 OldStyle @@ -784,7 +781,6 @@ MultiThreadedDebug CompileAsCpp Fast - StreamingSIMDExtensions2 OldStyle @@ -1014,7 +1010,6 @@ MultiThreaded CompileAsCpp Fast - StreamingSIMDExtensions2 true OldStyle @@ -1040,7 +1035,6 @@ MultiThreaded CompileAsCpp Fast - StreamingSIMDExtensions2 true OldStyle @@ -1066,7 +1060,6 @@ MultiThreaded CompileAsCpp Fast - StreamingSIMDExtensions2 true OldStyle @@ -1092,7 +1085,6 @@ MultiThreaded CompileAsCpp Fast - StreamingSIMDExtensions2 true OldStyle From f7b0c0947c261727f4b31673fecc111f6b864d06 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Fri, 12 Apr 2019 12:50:27 -0400 Subject: [PATCH 169/237] add subsystem_name (friendly name) to history playlist, make playlist_entry struct public to simplify function parameters --- command.c | 29 ++-- discord/discord.c | 10 +- menu/cbs/menu_cbs_ok.c | 257 ++++++++++++++---------------- menu/cbs/menu_cbs_sublabel.c | 7 +- menu/drivers/ozone/ozone.c | 7 +- menu/drivers/stripes.c | 7 +- menu/menu_displaylist.c | 58 +++---- menu/menu_thumbnail_path.c | 13 +- playlist.c | 237 ++++++++++----------------- playlist.h | 73 ++++----- tasks/task_content.c | 33 ++-- tasks/task_database.c | 34 ++-- tasks/task_netplay_find_content.c | 54 ++++--- tasks/task_screenshot.c | 18 ++- ui/drivers/qt/qt_playlist.cpp | 72 +++++---- 15 files changed, 438 insertions(+), 471 deletions(-) diff --git a/command.c b/command.c index a00ef3e435..85a07db7e9 100755 --- a/command.c +++ b/command.c @@ -2407,16 +2407,19 @@ TODO: Add a setting for these tweaks */ { if (str_list->size >= 6) { + struct playlist_entry entry = {0}; + + entry.path = str_list->elems[0].data; /* content_path */ + entry.label = str_list->elems[1].data; /* content_label */ + entry.core_path = str_list->elems[2].data; /* core_path */ + entry.core_name = str_list->elems[3].data; /* core_name */ + entry.crc32 = str_list->elems[4].data; /* crc32 */ + entry.db_name = str_list->elems[5].data; /* db_name */ + /* Write playlist entry */ command_playlist_push_write( g_defaults.content_favorites, - str_list->elems[0].data, /* content_path */ - str_list->elems[1].data, /* content_label */ - str_list->elems[2].data, /* core_path */ - str_list->elems[3].data, /* core_name */ - str_list->elems[4].data, /* crc32 */ - str_list->elems[5].data, /* db_name */ - NULL, NULL + &entry ); runloop_msg_queue_push(msg_hash_to_str(MSG_ADDED_TO_FAVORITES), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); } @@ -2429,16 +2432,16 @@ TODO: Add a setting for these tweaks */ const char *core_name = "DETECT"; const char *core_path = "DETECT"; size_t *playlist_index = (size_t*)data; + struct playlist_entry entry = {0}; + + /* the update function reads our entry as const, so these casts are safe */ + entry.core_path = (char*)core_path; + entry.core_name = (char*)core_name; command_playlist_update_write( NULL, *playlist_index, - NULL, - NULL, - core_path, - core_name, - NULL, - NULL); + &entry); runloop_msg_queue_push(msg_hash_to_str(MSG_RESET_CORE_ASSOCIATION), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); break; diff --git a/discord/discord.c b/discord/discord.c index f6c2108d76..ba7c3fdc95 100644 --- a/discord/discord.c +++ b/discord/discord.c @@ -344,15 +344,19 @@ void discord_update(enum discord_presence presence) { const char *system_id = core_info->system_id ? core_info->system_id : "core"; - char *label = NULL; + const char *label = NULL; + const struct playlist_entry *entry = NULL; playlist_t *current_playlist = playlist_get_cached(); if (current_playlist) + { playlist_get_index_by_path( - current_playlist, path_get(RARCH_PATH_CONTENT), NULL, &label, NULL, NULL, NULL, NULL, NULL, NULL); + current_playlist, path_get(RARCH_PATH_CONTENT), &entry); + label = entry->label; + } if (!label) - label = (char *)path_basename(path_get(RARCH_PATH_BASENAME)); + label = path_basename(path_get(RARCH_PATH_BASENAME)); #if 0 RARCH_LOG("[discord] current core: %s\n", system_id); RARCH_LOG("[discord] current content: %s\n", label); diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 8999fe2c30..98e6d14335 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -965,9 +965,11 @@ end: static bool menu_content_playlist_load(playlist_t *playlist, size_t idx) { const char *path = NULL; + const struct playlist_entry *entry = NULL; - playlist_get_index(playlist, - idx, &path, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + playlist_get_index(playlist, idx, &entry); + + path = entry->path; if (!string_is_empty(path)) { @@ -1708,16 +1710,9 @@ static int action_ok_playlist_entry_collection(const char *path, size_t selection_ptr = 0; bool playlist_initialized = false; playlist_t *playlist = NULL; - const char *entry_path = NULL; - const char *entry_label = NULL; - const char *core_path = NULL; - const char *core_name = NULL; playlist_t *tmp_playlist = NULL; menu_handle_t *menu = NULL; - - const char *subsystem_ident = NULL; - const struct string_list - *subsystem_rom_list = NULL; + const struct playlist_entry *entry = NULL; unsigned i = 0; if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) @@ -1740,28 +1735,27 @@ static int action_ok_playlist_entry_collection(const char *path, playlist = tmp_playlist; selection_ptr = entry_idx; - playlist_get_index(playlist, selection_ptr, - &entry_path, &entry_label, &core_path, &core_name, NULL, NULL, &subsystem_ident, &subsystem_rom_list); + playlist_get_index(playlist, selection_ptr, &entry); /* Subsystem codepath */ - if (!string_is_empty(subsystem_ident)) + if (!string_is_empty(entry->subsystem_ident)) { content_ctx_info_t content_info = {0}; - task_push_load_new_core(core_path, NULL, + task_push_load_new_core(entry->core_path, NULL, &content_info, CORE_TYPE_PLAIN, NULL, NULL); content_clear_subsystem(); - if (!content_set_subsystem_by_name(subsystem_ident)) + if (!content_set_subsystem_by_name(entry->subsystem_ident)) { RARCH_LOG("[playlist] subsystem not found in implementation\n"); /* TODO: Add OSD message telling users that content can't be loaded */ return 0; } - for (i = 0; i < subsystem_rom_list->size; i++) - content_add_subsystem(subsystem_rom_list->elems[i].data); + for (i = 0; i < entry->subsystem_roms->size; i++) + content_add_subsystem(entry->subsystem_roms->elems[i].data); task_push_load_subsystem_with_core_from_menu( NULL, &content_info, @@ -1771,8 +1765,8 @@ static int action_ok_playlist_entry_collection(const char *path, } /* Is the core path / name of the playlist entry not yet filled in? */ - if ( string_is_equal(core_path, file_path_str(FILE_PATH_DETECT)) - && string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) + if ( string_is_equal(entry->core_path, file_path_str(FILE_PATH_DETECT)) + && string_is_equal(entry->core_name, file_path_str(FILE_PATH_DETECT))) { core_info_ctx_find_t core_info; const char *entry_path = NULL; @@ -1802,18 +1796,20 @@ static int action_ok_playlist_entry_collection(const char *path, tmp_playlist = playlist_get_cached(); if (tmp_playlist) + { + struct playlist_entry entry = {0}; + + entry.core_path = new_core_path; + entry.core_name = core_info.inf->display_name; + command_playlist_update_write( tmp_playlist, selection_ptr, - NULL, - NULL, - new_core_path, - core_info.inf->display_name, - NULL, - NULL); + &entry); + } } else - strlcpy(new_core_path, core_path, sizeof(new_core_path)); + strlcpy(new_core_path, entry->core_path, sizeof(new_core_path)); if (!playlist || !menu_content_playlist_load(playlist, selection_ptr)) { @@ -1826,11 +1822,10 @@ static int action_ok_playlist_entry_collection(const char *path, return menu_cbs_exit(); } - playlist_get_index(playlist, - selection_ptr, &path, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + playlist_get_index(playlist, selection_ptr, &entry); return default_action_ok_load_content_from_playlist_from_menu( - new_core_path, path, entry_label); + new_core_path, entry->path, entry->label); } static int action_ok_playlist_entry(const char *path, @@ -1839,11 +1834,9 @@ static int action_ok_playlist_entry(const char *path, char new_core_path[PATH_MAX_LENGTH]; size_t selection_ptr = 0; playlist_t *playlist = g_defaults.content_history; - const char *entry_path = NULL; - const char *entry_label = NULL; - const char *core_path = NULL; - const char *core_name = NULL; menu_handle_t *menu = NULL; + const struct playlist_entry *entry = NULL; + const char *entry_label = NULL; new_core_path[0] = '\0'; @@ -1852,11 +1845,12 @@ static int action_ok_playlist_entry(const char *path, selection_ptr = entry_idx; - playlist_get_index(playlist, selection_ptr, - &entry_path, &entry_label, &core_path, &core_name, NULL, NULL, NULL, NULL); + playlist_get_index(playlist, selection_ptr, &entry); - if ( string_is_equal(core_path, file_path_str(FILE_PATH_DETECT)) - && string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) + entry_label = entry->label; + + if ( string_is_equal(entry->core_path, file_path_str(FILE_PATH_DETECT)) + && string_is_equal(entry->core_name, file_path_str(FILE_PATH_DETECT))) { core_info_ctx_find_t core_info; const char *entry_path = NULL; @@ -1875,21 +1869,23 @@ static int action_ok_playlist_entry(const char *path, if (!found_associated_core) /* TODO: figure out if this should refer to the inner or outer entry_path */ /* TODO: make sure there's only one entry_path in this function */ - return action_ok_file_load_with_detect_core(entry_path, + return action_ok_file_load_with_detect_core(entry->path, label, type, selection_ptr, entry_idx); - command_playlist_update_write(NULL, - selection_ptr, - NULL, - NULL, - new_core_path, - core_info.inf->display_name, - NULL, - NULL); + { + struct playlist_entry entry = {0}; + + entry.core_path = new_core_path; + entry.core_name = core_info.inf->display_name; + + command_playlist_update_write(NULL, + selection_ptr, + &entry); + } } - else if (!string_is_empty(core_path)) - strlcpy(new_core_path, core_path, sizeof(new_core_path)); + else if (!string_is_empty(entry->core_path)) + strlcpy(new_core_path, entry->core_path, sizeof(new_core_path)); if (!playlist || !menu_content_playlist_load(playlist, selection_ptr)) { @@ -1901,23 +1897,19 @@ static int action_ok_playlist_entry(const char *path, } playlist_get_index(playlist, - selection_ptr, &path, NULL, NULL, NULL, - NULL, NULL, NULL, NULL); + selection_ptr, &entry); return default_action_ok_load_content_from_playlist_from_menu( - new_core_path, path, entry_label); + new_core_path, entry->path, entry_label); } static int action_ok_playlist_entry_start_content(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { size_t selection_ptr = 0; - const char *entry_path = NULL; - const char *entry_label = NULL; - const char *core_path = NULL; - const char *core_name = NULL; menu_handle_t *menu = NULL; playlist_t *playlist = playlist_get_cached(); + const struct playlist_entry *entry = NULL; if ( !playlist || !menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) @@ -1925,11 +1917,10 @@ static int action_ok_playlist_entry_start_content(const char *path, selection_ptr = menu->scratchpad.unsigned_var; - playlist_get_index(playlist, selection_ptr, - &entry_path, &entry_label, &core_path, &core_name, NULL, NULL, NULL, NULL); + playlist_get_index(playlist, selection_ptr, &entry); - if ( string_is_equal(core_path, file_path_str(FILE_PATH_DETECT)) - && string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) + if ( string_is_equal(entry->core_path, file_path_str(FILE_PATH_DETECT)) + && string_is_equal(entry->core_name, file_path_str(FILE_PATH_DETECT))) { core_info_ctx_find_t core_info; char new_core_path[PATH_MAX_LENGTH]; @@ -1958,15 +1949,17 @@ static int action_ok_playlist_entry_start_content(const char *path, return action_ok_file_load_with_detect_core(entry_path, label, type, selection_ptr, entry_idx); - command_playlist_update_write( - playlist, - selection_ptr, - NULL, - NULL, - new_core_path, - core_info.inf->display_name, - NULL, - NULL); + { + struct playlist_entry entry = {0}; + + entry.core_path = new_core_path; + entry.core_name = core_info.inf->display_name; + + command_playlist_update_write( + playlist, + selection_ptr, + &entry); + } } if (!menu_content_playlist_load(playlist, selection_ptr)) @@ -1975,10 +1968,9 @@ static int action_ok_playlist_entry_start_content(const char *path, goto error; } - playlist_get_index(playlist, - selection_ptr, &path, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + playlist_get_index(playlist, selection_ptr, &entry); - return default_action_ok_load_content_from_playlist_from_menu(core_path, path, entry_label); + return default_action_ok_load_content_from_playlist_from_menu(entry->core_path, entry->path, entry->label); error: return menu_cbs_exit(); @@ -2095,15 +2087,15 @@ static int action_ok_audio_add_to_mixer(const char *path, { const char *entry_path = NULL; playlist_t *tmp_playlist = playlist_get_cached(); + const struct playlist_entry *entry = NULL; if (!tmp_playlist) return -1; - playlist_get_index(tmp_playlist, entry_idx, - &entry_path, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + playlist_get_index(tmp_playlist, entry_idx, &entry); - if (filestream_exists(entry_path)) - task_push_audio_mixer_load(entry_path, + if (filestream_exists(entry->path)) + task_push_audio_mixer_load(entry->path, NULL, NULL, false, AUDIO_MIXER_SLOT_SELECTION_AUTOMATIC, 0 @@ -2117,15 +2109,15 @@ static int action_ok_audio_add_to_mixer_and_play(const char *path, { const char *entry_path = NULL; playlist_t *tmp_playlist = playlist_get_cached(); + const struct playlist_entry *entry = NULL; if (!tmp_playlist) return -1; - playlist_get_index(tmp_playlist, entry_idx, - &entry_path, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + playlist_get_index(tmp_playlist, entry_idx, &entry); - if (filestream_exists(entry_path)) - task_push_audio_mixer_load_and_play(entry_path, + if (filestream_exists(entry->path)) + task_push_audio_mixer_load_and_play(entry->path, NULL, NULL, false, AUDIO_MIXER_SLOT_SELECTION_AUTOMATIC, 0); @@ -2138,6 +2130,7 @@ static int action_ok_audio_add_to_mixer_and_collection(const char *path, { char combined_path[PATH_MAX_LENGTH]; menu_handle_t *menu = NULL; + struct playlist_entry entry = {0}; combined_path[0] = '\0'; @@ -2147,14 +2140,12 @@ static int action_ok_audio_add_to_mixer_and_collection(const char *path, fill_pathname_join(combined_path, menu->scratch2_buf, menu->scratch_buf, sizeof(combined_path)); - command_playlist_push_write( - g_defaults.music_history, - combined_path, - NULL, - "builtin", - "musicplayer", - NULL, NULL, - NULL, NULL); + /* the push function reads our entry as const, so these casts are safe */ + entry.path = combined_path; + entry.core_path = (char*)"builtin"; + entry.core_name = (char*)"musicplayer"; + + command_playlist_push_write(g_defaults.music_history, &entry); if (filestream_exists(combined_path)) task_push_audio_mixer_load(combined_path, @@ -2170,6 +2161,7 @@ static int action_ok_audio_add_to_mixer_and_collection_and_play(const char *path { char combined_path[PATH_MAX_LENGTH]; menu_handle_t *menu = NULL; + struct playlist_entry entry = {0}; combined_path[0] = '\0'; @@ -2179,14 +2171,12 @@ static int action_ok_audio_add_to_mixer_and_collection_and_play(const char *path fill_pathname_join(combined_path, menu->scratch2_buf, menu->scratch_buf, sizeof(combined_path)); - command_playlist_push_write( - g_defaults.music_history, - combined_path, - NULL, - "builtin", - "musicplayer", - NULL, NULL, - NULL, NULL); + /* the push function reads our entry as const, so these casts are safe */ + entry.path = combined_path; + entry.core_path = (char*)"builtin"; + entry.core_name = (char*)"musicplayer"; + + command_playlist_push_write(g_defaults.music_history, &entry); if (filestream_exists(combined_path)) task_push_audio_mixer_load_and_play(combined_path, @@ -2250,14 +2240,16 @@ static void menu_input_st_string_cb_rename_entry(void *userdata, const char *label = menu_input_dialog_get_buffer(); if (!string_is_empty(label)) + { + struct playlist_entry entry = {0}; + + /* the update function reads our entry as const, so these casts are safe */ + entry.label = (char*)label; + command_playlist_update_write(NULL, menu_input_dialog_get_kb_idx(), - NULL, - label, - NULL, - NULL, - NULL, - NULL); + &entry); + } } menu_input_dialog_end(); @@ -2708,15 +2700,20 @@ static int action_ok_core_deferred_set(const char *new_core_path, ext_name, settings->bools.show_hidden_files, true); - command_playlist_update_write( - NULL, - menu->scratchpad.unsigned_var, - NULL, - content_label, - new_core_path, - core_display_name, - NULL, - NULL); + + { + struct playlist_entry entry = {0}; + + /* the update function reads our entry as const, so these casts are safe */ + entry.label = (char*)content_label; + entry.core_path = (char*)new_core_path; + entry.core_name = core_display_name; + + command_playlist_update_write( + NULL, + menu->scratchpad.unsigned_var, + &entry); + } menu_entries_pop_stack(&selection, 0, 1); menu_navigation_set_selection(selection); @@ -3834,10 +3831,6 @@ static int action_ok_reset_core_association(const char *path, if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); - playlist_get_index(tmp_playlist, - menu->rpl_entry_selection_ptr, - &tmp_path, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if (!command_event(CMD_EVENT_RESET_CORE_ASSOCIATION, (void *)&menu->rpl_entry_selection_ptr)) return menu_cbs_exit(); @@ -3962,14 +3955,9 @@ static int action_ok_add_to_favorites(const char *path, static int action_ok_add_to_favorites_playlist(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - const char *content_path = NULL; - const char *content_label = NULL; - const char *core_path = NULL; - const char *core_name = NULL; - const char *crc32 = NULL; - const char *db_name = NULL; menu_handle_t *menu = NULL; playlist_t *playlist_curr = playlist_get_cached(); + const struct playlist_entry *entry = NULL; int ret = 0; if (!playlist_curr) @@ -3978,13 +3966,11 @@ static int action_ok_add_to_favorites_playlist(const char *path, return menu_cbs_exit(); /* Read current playlist parameters */ - playlist_get_index(playlist_curr, menu->rpl_entry_selection_ptr, - &content_path, &content_label, &core_path, &core_name, - &crc32, NULL, NULL, NULL); + playlist_get_index(playlist_curr, menu->rpl_entry_selection_ptr, &entry); /* Error checking * > If content path is empty, cannot do anything... */ - if (!string_is_empty(content_path)) + if (!string_is_empty(entry->path)) { struct string_list *str_list = NULL; union string_list_elem_attr attr; @@ -4007,43 +3993,43 @@ static int action_ok_add_to_favorites_playlist(const char *path, * [5]: db_name */ /* > content_path */ - string_list_append(str_list, content_path, attr); + string_list_append(str_list, entry->path, attr); /* > content_label */ - if (!string_is_empty(content_label)) + if (!string_is_empty(entry->label)) { - string_list_append(str_list, content_label, attr); + string_list_append(str_list, entry->label, attr); } else { /* Label is empty - use file name instead */ char fallback_content_label[PATH_MAX_LENGTH]; fallback_content_label[0] = '\0'; - fill_short_pathname_representation(fallback_content_label, content_path, sizeof(fallback_content_label)); + fill_short_pathname_representation(fallback_content_label, entry->path, sizeof(fallback_content_label)); string_list_append(str_list, fallback_content_label, attr); } /* > core_path + core_name */ - if (!string_is_empty(core_path) && !string_is_empty(core_name)) + if (!string_is_empty(entry->core_path) && !string_is_empty(entry->core_name)) { core_info_ctx_find_t core_info; /* >> core_path */ - string_list_append(str_list, core_path, attr); + string_list_append(str_list, entry->core_path, attr); /* >> core_name * (always use display name, if available) */ core_info.inf = NULL; - core_info.path = core_path; + core_info.path = entry->core_path; - if (core_info_find(&core_info, core_path)) + if (core_info_find(&core_info, entry->core_path)) if (!string_is_empty(core_info.inf->display_name)) strlcpy(core_display_name, core_info.inf->display_name, sizeof(core_display_name)); if (!string_is_empty(core_display_name)) string_list_append(str_list, core_display_name, attr); else - string_list_append(str_list, core_name, attr); + string_list_append(str_list, entry->core_name, attr); } else { @@ -4052,11 +4038,10 @@ static int action_ok_add_to_favorites_playlist(const char *path, } /* crc32 */ - string_list_append(str_list, !string_is_empty(crc32) ? crc32 : "", attr); + string_list_append(str_list, !string_is_empty(entry->crc32) ? entry->crc32 : "", attr); /* db_name */ - playlist_get_db_name(playlist_curr, menu->rpl_entry_selection_ptr, &db_name); - string_list_append(str_list, !string_is_empty(db_name) ? db_name : "", attr); + string_list_append(str_list, !string_is_empty(entry->db_name) ? entry->db_name : "", attr); /* Trigger 'ADD_TO_FAVORITES' event */ if (!command_event(CMD_EVENT_ADD_TO_FAVORITES, (void*)str_list)) diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index acf1f2bb45..854f01a5fc 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -837,6 +837,7 @@ static int action_bind_sublabel_playlist_entry( { settings_t *settings = config_get_ptr(); playlist_t *playlist = NULL; + const struct playlist_entry *entry = NULL; const char *core_name = NULL; unsigned runtime_hours = 0; unsigned runtime_minutes = 0; @@ -853,13 +854,17 @@ static int action_bind_sublabel_playlist_entry( /* Get current playlist */ playlist = playlist_get_cached(); + if (!playlist) return 0; + if (i >= playlist_get_size(playlist)) return 0; /* Read playlist entry */ - playlist_get_index(playlist, i, NULL, NULL, NULL, &core_name, NULL, NULL, NULL, NULL); + playlist_get_index(playlist, i, &entry); + + core_name = entry->core_name; /* Only add sublabel if a core is currently assigned */ if (string_is_empty(core_name) || string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index 54ad392ef8..c08b616d41 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1132,6 +1132,7 @@ void ozone_update_content_metadata(ozone_handle_t *ozone) { size_t selection = menu_navigation_get_selection(); playlist_t *playlist = playlist_get_cached(); + const struct playlist_entry *entry = NULL; const char *core_name = NULL; settings_t *settings = config_get_ptr(); @@ -1140,8 +1141,9 @@ void ozone_update_content_metadata(ozone_handle_t *ozone) if (ozone->is_playlist && playlist) { const char *core_label = NULL; - playlist_get_index(playlist, selection, - NULL, NULL, NULL, &core_name, NULL, NULL, NULL, NULL); + playlist_get_index(playlist, selection, &entry); + + core_name = entry->core_name; /* Fill core name */ if (!core_name || string_is_equal(core_name, "DETECT")) @@ -1207,7 +1209,6 @@ void ozone_update_content_metadata(ozone_handle_t *ozone) msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED)); } } - } static void ozone_set_thumbnail_content(void *data, const char *s) diff --git a/menu/drivers/stripes.c b/menu/drivers/stripes.c index d77f4295a1..9515008558 100644 --- a/menu/drivers/stripes.c +++ b/menu/drivers/stripes.c @@ -903,11 +903,10 @@ static void stripes_update_thumbnail_path(void *data, unsigned i, char pos) if (playlist) { - const char *core_name = NULL; - playlist_get_index(playlist, i, - NULL, NULL, NULL, &core_name, NULL, NULL, NULL, NULL); + const struct playlist_entry *entry = NULL; + playlist_get_index(playlist, i, &entry); - if (string_is_equal(core_name, "imageviewer")) + if (string_is_equal(entry->core_name, "imageviewer")) { if (pos == 'R' || (pos == 'L' && string_is_equal(stripes_thumbnails_ident('R'), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 9e1799089e..68571c7f52 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -1345,22 +1345,18 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, for (i = 0; i < list_size; i++) { char menu_entry_label[PATH_MAX_LENGTH]; - const char *path = NULL; - const char *label = NULL; - const char *core_path = NULL; - const char *core_name = NULL; + const struct playlist_entry *entry = NULL; menu_entry_label[0] = '\0'; /* Read playlist entry */ - playlist_get_index(playlist, i, - &path, &label, &core_path, &core_name, NULL, NULL, NULL, NULL); + playlist_get_index(playlist, i, &entry); /* Extract any available runtime values, if required */ if (get_runtime) { runtime_log_t *runtime_log = NULL; - runtime_log = runtime_log_init(path, core_path, + runtime_log = runtime_log_init(entry->path, entry->core_path, settings->uints.playlist_sublabel_runtime_type == PLAYLIST_RUNTIME_PER_CORE); if (runtime_log) @@ -1400,7 +1396,7 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, } } - if (!string_is_empty(path)) + if (!string_is_empty(entry->path)) { /* Standard playlist entry * > Base menu entry label is always playlist label @@ -1408,27 +1404,27 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, * > If required, add currently associated core (if any), otherwise * no further action is necessary */ - if (string_is_empty(label)) - fill_short_pathname_representation(menu_entry_label, path, sizeof(menu_entry_label)); + if (string_is_empty(entry->label)) + fill_short_pathname_representation(menu_entry_label, entry->path, sizeof(menu_entry_label)); else - strlcpy(menu_entry_label, label, sizeof(menu_entry_label)); + strlcpy(menu_entry_label, entry->label, sizeof(menu_entry_label)); if (show_inline_core_name) { - if (!string_is_empty(core_name) && !string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) + if (!string_is_empty(entry->core_name) && !string_is_equal(entry->core_name, file_path_str(FILE_PATH_DETECT))) { strlcat(menu_entry_label, label_spacer, sizeof(menu_entry_label)); - strlcat(menu_entry_label, core_name, sizeof(menu_entry_label)); + strlcat(menu_entry_label, entry->core_name, sizeof(menu_entry_label)); } } - menu_entries_append_enum(info->list, menu_entry_label, path, + menu_entries_append_enum(info->list, menu_entry_label, entry->path, MENU_ENUM_LABEL_PLAYLIST_ENTRY, FILE_TYPE_RPL_ENTRY, 0, i); } else { - if (core_name) - strlcpy(menu_entry_label, core_name, sizeof(menu_entry_label)); + if (entry->core_name) + strlcpy(menu_entry_label, entry->core_name, sizeof(menu_entry_label)); menu_entries_append_enum(info->list, menu_entry_label, path_playlist, MENU_ENUM_LABEL_PLAYLIST_ENTRY, FILE_TYPE_PLAYLIST_ENTRY, 0, i); @@ -1735,16 +1731,14 @@ static int menu_displaylist_parse_database_entry(menu_handle_t *menu, { for (j = 0; j < playlist_size(playlist); j++) { - const char *crc32 = NULL; + const struct playlist_entry *entry = NULL; bool match_found = false; struct string_list *tmp_str_list = NULL; - playlist_get_index(playlist, j, - NULL, NULL, NULL, NULL, - &crc32, NULL, NULL, NULL); + playlist_get_index(playlist, j, &entry); - if (crc32) - tmp_str_list = string_split(crc32, "|"); + if (entry->crc32) + tmp_str_list = string_split(entry->crc32, "|"); if (!tmp_str_list) continue; @@ -2878,19 +2872,14 @@ static int menu_displaylist_parse_horizontal_content_actions( menu_displaylist_info_t *info) { bool content_loaded = false; - const char *label = NULL; - const char *entry_path = NULL; - const char *core_path = NULL; - const char *core_name = NULL; - const char *db_name = NULL; playlist_t *playlist = playlist_get_cached(); settings_t *settings = config_get_ptr(); const char *fullpath = path_get(RARCH_PATH_CONTENT); unsigned idx = menu->rpl_entry_selection_ptr; + const struct playlist_entry *entry = NULL; if (playlist) - playlist_get_index(playlist, idx, - &entry_path, &label, &core_path, &core_name, NULL, &db_name, NULL, NULL); + playlist_get_index(playlist, idx, &entry); content_loaded = !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL) && string_is_equal(menu->deferred_path, fullpath); @@ -2901,8 +2890,8 @@ static int menu_displaylist_parse_horizontal_content_actions( { const char *ext = NULL; - if (!string_is_empty(entry_path)) - ext = path_get_extension(entry_path); + if (!string_is_empty(entry->path)) + ext = path_get_extension(entry->path); if (!string_is_empty(ext) && audio_driver_mixer_extension_supported(ext)) @@ -2956,10 +2945,9 @@ static int menu_displaylist_parse_horizontal_content_actions( msg_hash_to_str(MENU_ENUM_LABEL_RESET_CORE_ASSOCIATION), MENU_ENUM_LABEL_RESET_CORE_ASSOCIATION, FILE_TYPE_PLAYLIST_ENTRY, 0, 0); } - } - if (!string_is_empty(db_name) && (!content_loaded || + if (!string_is_empty(entry->db_name) && (!content_loaded || (content_loaded && settings->bools.quick_menu_show_information))) { char *db_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); @@ -2968,7 +2956,7 @@ static int menu_displaylist_parse_horizontal_content_actions( fill_pathname_join_noext(db_path, settings->paths.path_content_database, - db_name, + entry->db_name, PATH_MAX_LENGTH * sizeof(char)); strlcat(db_path, file_path_str(FILE_PATH_RDB_EXTENSION), @@ -2977,7 +2965,7 @@ static int menu_displaylist_parse_horizontal_content_actions( if (filestream_exists(db_path)) menu_entries_append_enum( info->list, - label, + entry->label, db_path, MENU_ENUM_LABEL_INFORMATION, FILE_TYPE_RDB_ENTRY, 0, idx); diff --git a/menu/menu_thumbnail_path.c b/menu/menu_thumbnail_path.c index 7a085d5f74..f5eb0a141c 100644 --- a/menu/menu_thumbnail_path.c +++ b/menu/menu_thumbnail_path.c @@ -316,7 +316,8 @@ bool menu_thumbnail_set_content_playlist(menu_thumbnail_path_data_t *path_data, const char *content_label = NULL; const char *core_name = NULL; const char *db_name = NULL; - + const struct playlist_entry *entry = NULL; + if (!path_data) return false; @@ -339,9 +340,13 @@ bool menu_thumbnail_set_content_playlist(menu_thumbnail_path_data_t *path_data, return false; /* Read playlist values */ - playlist_get_index(playlist, idx, - &content_path, &content_label, NULL, &core_name, NULL, &db_name, NULL, NULL); - + playlist_get_index(playlist, idx, &entry); + + content_path = entry->path; + content_label = entry->label; + core_name = entry->core_name; + db_name = entry->db_name; + /* Content without a path is invalid by definition */ if (string_is_empty(content_path)) return false; diff --git a/playlist.c b/playlist.c index db281914ce..24a3e305d7 100644 --- a/playlist.c +++ b/playlist.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis - * Copyright (C) 2018-2019 - Brad Parker + * Copyright (C) 2016-2019 - Brad Parker * * 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- @@ -39,30 +39,6 @@ #define PLAYLIST_ENTRIES 6 #endif -struct playlist_entry -{ - char *path; - char *label; - char *core_path; - char *core_name; - char *db_name; - char *crc32; - char *subsystem_ident; - struct string_list *subsystem_roms; - unsigned runtime_hours; - unsigned runtime_minutes; - unsigned runtime_seconds; - /* Note: due to platform dependence, have to record - * timestamp as either a string or independent integer - * values. The latter is more verbose, but more efficient. */ - unsigned last_played_year; - unsigned last_played_month; - unsigned last_played_day; - unsigned last_played_hour; - unsigned last_played_minute; - unsigned last_played_second; -}; - struct content_playlist { bool modified; @@ -124,32 +100,12 @@ char *playlist_get_conf_path(playlist_t *playlist) **/ void playlist_get_index(playlist_t *playlist, size_t idx, - const char **path, const char **label, - const char **core_path, const char **core_name, - const char **crc32, - const char **db_name, - const char **subsystem_ident, - const struct string_list **subsystem_roms) + const struct playlist_entry **entry) { - if (!playlist) + if (!playlist || !entry) return; - if (path) - *path = playlist->entries[idx].path; - if (label) - *label = playlist->entries[idx].label; - if (core_path) - *core_path = playlist->entries[idx].core_path; - if (core_name) - *core_name = playlist->entries[idx].core_name; - if (db_name) - *db_name = playlist->entries[idx].db_name; - if (crc32) - *crc32 = playlist->entries[idx].crc32; - if (subsystem_ident) - *subsystem_ident = playlist->entries[idx].subsystem_ident; - if (subsystem_roms) - *subsystem_roms = playlist->entries[idx].subsystem_roms; + *entry = &playlist->entries[idx]; } void playlist_get_runtime_index(playlist_t *playlist, @@ -209,15 +165,11 @@ void playlist_delete_index(playlist_t *playlist, void playlist_get_index_by_path(playlist_t *playlist, const char *search_path, - char **path, char **label, - char **core_path, char **core_name, - char **crc32, - char **db_name, - char **subsystem_ident, - struct string_list **subsystem_roms) + const struct playlist_entry **entry) { size_t i; - if (!playlist) + + if (!playlist || !entry) return; for (i = 0; i < playlist->size; i++) @@ -225,22 +177,8 @@ void playlist_get_index_by_path(playlist_t *playlist, if (!string_is_equal(playlist->entries[i].path, search_path)) continue; - if (path) - *path = playlist->entries[i].path; - if (label) - *label = playlist->entries[i].label; - if (core_path) - *core_path = playlist->entries[i].core_path; - if (core_name) - *core_name = playlist->entries[i].core_name; - if (db_name) - *db_name = playlist->entries[i].db_name; - if (crc32) - *crc32 = playlist->entries[i].crc32; - if (subsystem_ident) - *subsystem_ident = playlist->entries[i].subsystem_ident; - if (subsystem_roms) - *subsystem_roms = playlist->entries[i].subsystem_roms; + *entry = &playlist->entries[i]; + break; } } @@ -285,6 +223,8 @@ static void playlist_free_entry(struct playlist_entry *entry) free(entry->crc32); if (entry->subsystem_ident != NULL) free(entry->subsystem_ident); + if (entry->subsystem_name != NULL) + free(entry->subsystem_name); if (entry->subsystem_roms != NULL) string_list_free(entry->subsystem_roms); @@ -295,6 +235,7 @@ static void playlist_free_entry(struct playlist_entry *entry) entry->db_name = NULL; entry->crc32 = NULL; entry->subsystem_ident = NULL; + entry->subsystem_name = NULL; entry->subsystem_roms = NULL; entry->runtime_hours = 0; entry->runtime_minutes = 0; @@ -308,10 +249,7 @@ static void playlist_free_entry(struct playlist_entry *entry) } void playlist_update(playlist_t *playlist, size_t idx, - const char *path, const char *label, - const char *core_path, const char *core_name, - const char *crc32, - const char *db_name) + const struct playlist_entry *update_entry) { struct playlist_entry *entry = NULL; @@ -320,52 +258,52 @@ void playlist_update(playlist_t *playlist, size_t idx, entry = &playlist->entries[idx]; - if (path && (path != entry->path)) + if (update_entry->path && (update_entry->path != entry->path)) { if (entry->path != NULL) free(entry->path); - entry->path = strdup(path); + entry->path = strdup(update_entry->path); playlist->modified = true; } - if (label && (label != entry->label)) + if (update_entry->label && (update_entry->label != entry->label)) { if (entry->label != NULL) free(entry->label); - entry->label = strdup(label); + entry->label = strdup(update_entry->label); playlist->modified = true; } - if (core_path && (core_path != entry->core_path)) + if (update_entry->core_path && (update_entry->core_path != entry->core_path)) { if (entry->core_path != NULL) free(entry->core_path); entry->core_path = NULL; - entry->core_path = strdup(core_path); + entry->core_path = strdup(update_entry->core_path); playlist->modified = true; } - if (core_name && (core_name != entry->core_name)) + if (update_entry->core_name && (update_entry->core_name != entry->core_name)) { if (entry->core_name != NULL) free(entry->core_name); - entry->core_name = strdup(core_name); + entry->core_name = strdup(update_entry->core_name); playlist->modified = true; } - if (db_name && (db_name != entry->db_name)) + if (update_entry->db_name && (update_entry->db_name != entry->db_name)) { if (entry->db_name != NULL) free(entry->db_name); - entry->db_name = strdup(db_name); + entry->db_name = strdup(update_entry->db_name); playlist->modified = true; } - if (crc32 && (crc32 != entry->crc32)) + if (update_entry->crc32 && (update_entry->crc32 != entry->crc32)) { if (entry->crc32 != NULL) free(entry->crc32); - entry->crc32 = strdup(crc32); + entry->crc32 = strdup(update_entry->crc32); playlist->modified = true; } } @@ -558,30 +496,24 @@ success: /** * playlist_push: * @playlist : Playlist handle. - * @path : Path of new playlist entry. - * @core_path : Core path of new playlist entry. - * @core_name : Core name of new playlist entry. * * Push entry to top of playlist. **/ bool playlist_push(playlist_t *playlist, - const char *path, const char *label, - const char *core_path, const char *core_name, - const char *crc32, - const char *db_name, - const char *subsystem_ident, - const struct string_list *subsystem_roms) + const struct playlist_entry *entry) { size_t i; - bool core_path_empty = string_is_empty(core_path); - bool core_name_empty = string_is_empty(core_name); + bool core_path_empty = string_is_empty(entry->core_path); + bool core_name_empty = string_is_empty(entry->core_name); + const char *core_name = entry->core_name; + const char *path = entry->path; if (core_path_empty || core_name_empty) { if (core_name_empty && !core_path_empty) { static char base_path[255] = {0}; - fill_pathname_base_noext(base_path, core_path, sizeof(base_path)); + fill_pathname_base_noext(base_path, entry->core_path, sizeof(base_path)); core_name = base_path; } @@ -607,9 +539,9 @@ bool playlist_push(playlist_t *playlist, (path && playlist->entries[i].path && #ifdef _WIN32 /*prevent duplicates on case-insensitive operating systems*/ - string_is_equal_noncase(path,playlist->entries[i].path) + string_is_equal_noncase(path, playlist->entries[i].path) #else - string_is_equal(path,playlist->entries[i].path) + string_is_equal(path, playlist->entries[i].path) #endif ); @@ -618,30 +550,39 @@ bool playlist_push(playlist_t *playlist, if (!equal_path) continue; - if (!string_is_equal(playlist->entries[i].core_path, core_path)) + if (!string_is_equal(playlist->entries[i].core_path, entry->core_path)) continue; - if (!string_is_empty(subsystem_ident) && !string_is_empty(playlist->entries[i].subsystem_ident) && !string_is_equal(playlist->entries[i].subsystem_ident, subsystem_ident)) + if (!string_is_empty(entry->subsystem_ident) && !string_is_empty(playlist->entries[i].subsystem_ident) && !string_is_equal(playlist->entries[i].subsystem_ident, entry->subsystem_ident)) continue; - if (string_is_empty(subsystem_ident) && !string_is_empty(playlist->entries[i].subsystem_ident)) + if (string_is_empty(entry->subsystem_ident) && !string_is_empty(playlist->entries[i].subsystem_ident)) continue; - if (!string_is_empty(subsystem_ident) && string_is_empty(playlist->entries[i].subsystem_ident)) + if (!string_is_empty(entry->subsystem_ident) && string_is_empty(playlist->entries[i].subsystem_ident)) continue; - if (subsystem_roms) + if (!string_is_empty(entry->subsystem_name) && !string_is_empty(playlist->entries[i].subsystem_name) && !string_is_equal(playlist->entries[i].subsystem_name, entry->subsystem_name)) + continue; + + if (string_is_empty(entry->subsystem_name) && !string_is_empty(playlist->entries[i].subsystem_name)) + continue; + + if (!string_is_empty(entry->subsystem_name) && string_is_empty(playlist->entries[i].subsystem_name)) + continue; + + if (entry->subsystem_roms) { int j; const struct string_list *roms = playlist->entries[i].subsystem_roms; bool unequal = false; - if (subsystem_roms->size != roms->size) + if (entry->subsystem_roms->size != roms->size) continue; - for (j = 0; j < subsystem_roms->size; j++) + for (j = 0; j < entry->subsystem_roms->size; j++) { - if (!string_is_equal(subsystem_roms->elems[j].data, roms->elems[j].data)) + if (!string_is_equal(entry->subsystem_roms->elems[j].data, roms->elems[j].data)) { unequal = true; break; @@ -687,6 +628,7 @@ bool playlist_push(playlist_t *playlist, playlist->entries[0].db_name = NULL; playlist->entries[0].crc32 = NULL; playlist->entries[0].subsystem_ident = NULL; + playlist->entries[0].subsystem_name = NULL; playlist->entries[0].subsystem_roms = NULL; playlist->entries[0].runtime_hours = 0; playlist->entries[0].runtime_minutes = 0; @@ -697,29 +639,31 @@ bool playlist_push(playlist_t *playlist, playlist->entries[0].last_played_hour = 0; playlist->entries[0].last_played_minute = 0; playlist->entries[0].last_played_second = 0; - if (!string_is_empty(path)) - playlist->entries[0].path = strdup(path); - if (!string_is_empty(label)) - playlist->entries[0].label = strdup(label); - if (!string_is_empty(core_path)) - playlist->entries[0].core_path = strdup(core_path); + if (!string_is_empty(entry->path)) + playlist->entries[0].path = strdup(entry->path); + if (!string_is_empty(entry->label)) + playlist->entries[0].label = strdup(entry->label); + if (!string_is_empty(entry->core_path)) + playlist->entries[0].core_path = strdup(entry->core_path); if (!string_is_empty(core_name)) playlist->entries[0].core_name = strdup(core_name); - if (!string_is_empty(db_name)) - playlist->entries[0].db_name = strdup(db_name); - if (!string_is_empty(crc32)) - playlist->entries[0].crc32 = strdup(crc32); - if (!string_is_empty(subsystem_ident)) - playlist->entries[0].subsystem_ident = strdup(subsystem_ident); - if (subsystem_roms) + if (!string_is_empty(entry->db_name)) + playlist->entries[0].db_name = strdup(entry->db_name); + if (!string_is_empty(entry->crc32)) + playlist->entries[0].crc32 = strdup(entry->crc32); + if (!string_is_empty(entry->subsystem_ident)) + playlist->entries[0].subsystem_ident = strdup(entry->subsystem_ident); + if (!string_is_empty(entry->subsystem_name)) + playlist->entries[0].subsystem_name = strdup(entry->subsystem_name); + if (entry->subsystem_roms) { union string_list_elem_attr attributes = {0}; playlist->entries[0].subsystem_roms = string_list_new(); - for (i = 0; i < subsystem_roms->size; i++) + for (i = 0; i < entry->subsystem_roms->size; i++) { - string_list_append(playlist->entries[0].subsystem_roms, subsystem_roms->elems[i].data, attributes); + string_list_append(playlist->entries[0].subsystem_roms, entry->subsystem_roms->elems[i].data, attributes); } } } @@ -1085,6 +1029,17 @@ void playlist_write_file(playlist_t *playlist) JSON_Writer_WriteString(context.writer, playlist->entries[i].subsystem_ident ? playlist->entries[i].subsystem_ident : "", playlist->entries[i].subsystem_ident ? strlen(playlist->entries[i].subsystem_ident) : 0, JSON_UTF8); } + if (!string_is_empty(playlist->entries[i].subsystem_name)) + { + JSON_Writer_WriteComma(context.writer); + JSON_Writer_WriteNewLine(context.writer); + JSON_Writer_WriteSpace(context.writer, 6); + JSON_Writer_WriteString(context.writer, "subsystem_name", strlen("subsystem_name"), JSON_UTF8); + JSON_Writer_WriteColon(context.writer); + JSON_Writer_WriteSpace(context.writer, 1); + JSON_Writer_WriteString(context.writer, playlist->entries[i].subsystem_name ? playlist->entries[i].subsystem_name : "", playlist->entries[i].subsystem_name ? strlen(playlist->entries[i].subsystem_name) : 0, JSON_UTF8); + } + if (playlist->entries[i].subsystem_roms && playlist->entries[i].subsystem_roms->size > 0) { int j; @@ -1436,6 +1391,8 @@ static JSON_Parser_HandlerResult JSONObjectMemberHandler(JSON_Parser parser, cha pCtx->current_entry_val = &pCtx->current_entry->db_name; else if (string_is_equal(pValue, "subsystem_ident")) pCtx->current_entry_val = &pCtx->current_entry->subsystem_ident; + else if (string_is_equal(pValue, "subsystem_name")) + pCtx->current_entry_val = &pCtx->current_entry->subsystem_name; else if (string_is_equal(pValue, "subsystem_roms")) pCtx->current_entry_string_list_val = &pCtx->current_entry->subsystem_roms; else if (string_is_equal(pValue, "runtime_hours")) @@ -1798,28 +1755,14 @@ void playlist_qsort(playlist_t *playlist) void command_playlist_push_write( playlist_t *playlist, - const char *path, - const char *label, - const char *core_path, - const char *core_name, - const char *crc32, - const char *db_name, - const char *subsystem_ident, - const struct string_list *subsystem_roms) + const struct playlist_entry *entry) { if (!playlist) return; if (playlist_push( playlist, - path, - label, - core_path, - core_name, - crc32, - db_name, - subsystem_ident, - subsystem_roms + entry )) playlist_write_file(playlist); } @@ -1827,12 +1770,7 @@ void command_playlist_push_write( void command_playlist_update_write( playlist_t *plist, size_t idx, - const char *path, - const char *label, - const char *core_path, - const char *core_display_name, - const char *crc32, - const char *db_name) + const struct playlist_entry *entry) { playlist_t *playlist = plist ? plist : playlist_get_cached(); @@ -1842,12 +1780,7 @@ void command_playlist_update_write( playlist_update( playlist, idx, - path, - label, - core_path, - core_display_name, - crc32, - db_name); + entry); playlist_write_file(playlist); } diff --git a/playlist.h b/playlist.h index 7265ebfb8e..5532d1e40d 100644 --- a/playlist.h +++ b/playlist.h @@ -1,6 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2019 - Brad Parker * * 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- @@ -25,7 +26,32 @@ RETRO_BEGIN_DECLS -typedef struct content_playlist playlist_t; +typedef struct content_playlist playlist_t; + +struct playlist_entry +{ + char *path; + char *label; + char *core_path; + char *core_name; + char *db_name; + char *crc32; + char *subsystem_ident; + char *subsystem_name; + struct string_list *subsystem_roms; + unsigned runtime_hours; + unsigned runtime_minutes; + unsigned runtime_seconds; + /* Note: due to platform dependence, have to record + * timestamp as either a string or independent integer + * values. The latter is more verbose, but more efficient. */ + unsigned last_played_year; + unsigned last_played_month; + unsigned last_played_day; + unsigned last_played_hour; + unsigned last_played_minute; + unsigned last_played_second; +}; /** * playlist_init: @@ -67,20 +93,12 @@ size_t playlist_size(playlist_t *playlist); * playlist_get_index: * @playlist : Playlist handle. * @idx : Index of playlist entry. - * @path : Path of playlist entry. - * @core_path : Core path of playlist entry. - * @core_name : Core name of playlist entry. * * Gets values of playlist index: **/ void playlist_get_index(playlist_t *playlist, size_t idx, - const char **path, const char **label, - const char **core_path, const char **core_name, - const char **crc32, - const char **db_name, - const char **subsystem_ident, - const struct string_list **subsystem_roms); + const struct playlist_entry **entry); void playlist_get_runtime_index(playlist_t *playlist, size_t idx, @@ -109,12 +127,7 @@ void playlist_delete_index(playlist_t *playlist, * Push entry to top of playlist. **/ bool playlist_push(playlist_t *playlist, - const char *path, const char *label, - const char *core_path, const char *core_name, - const char *crc32, - const char *db_name, - const char *subsystem_ident, - const struct string_list *subsystem_roms); + const struct playlist_entry *entry); bool playlist_push_runtime(playlist_t *playlist, const char *path, const char *core_path, @@ -123,10 +136,7 @@ bool playlist_push_runtime(playlist_t *playlist, unsigned last_played_hour, unsigned last_played_minute, unsigned last_played_second); void playlist_update(playlist_t *playlist, size_t idx, - const char *path, const char *label, - const char *core_path, const char *core_name, - const char *crc32, - const char *db_name); + const struct playlist_entry *update_entry); /* Note: register_update determines whether the internal * 'playlist->modified' flag is set when updating runtime @@ -142,12 +152,7 @@ void playlist_update_runtime(playlist_t *playlist, size_t idx, void playlist_get_index_by_path(playlist_t *playlist, const char *search_path, - char **path, char **label, - char **core_path, char **core_name, - char **crc32, - char **db_name, - char **subsystem_ident, - struct string_list **subsystem_roms); + const struct playlist_entry **entry); bool playlist_entry_exists(playlist_t *playlist, const char *path, @@ -171,24 +176,12 @@ bool playlist_init_cached(const char *path, size_t size); void command_playlist_push_write( playlist_t *playlist, - const char *path, - const char *label, - const char *core_path, - const char *core_name, - const char *crc32, - const char *db_name, - const char *subsystem_ident, - const struct string_list *subsystem_roms); + const struct playlist_entry *entry); void command_playlist_update_write( playlist_t *playlist, size_t idx, - const char *path, - const char *label, - const char *core_path, - const char *core_display_name, - const char *crc32, - const char *db_name); + const struct playlist_entry *entry); /* Returns true if specified playlist index matches * specified content/core paths */ diff --git a/tasks/task_content.c b/tasks/task_content.c index ccbdb42a3d..aecf58c0f9 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -439,7 +439,7 @@ static bool load_content_from_compressed_archive( string_list_append(additional_path_allocs, new_path, attributes); info[i].path = - additional_path_allocs->elems[additional_path_allocs->size -1 ].data; + additional_path_allocs->elems[additional_path_allocs->size - 1].data; if (!string_list_append(content_ctx->temporary_content, new_path, attributes)) @@ -1052,6 +1052,7 @@ static bool task_load_content(content_ctx_info_t *content_info, * (As far as I can tell, core_info_get_current_core() * should always provide a valid pointer here...) */ core_info_get_current_core(&core_info); + if (core_info) core_name = core_info->display_name; @@ -1087,16 +1088,28 @@ static bool task_load_content(content_ctx_info_t *content_info, if ( content_ctx->history_list_enable && playlist_hist) + { + char subsystem_name[PATH_MAX_LENGTH]; + struct playlist_entry entry = {0}; + + subsystem_name[0] = '\0'; + + content_get_subsystem_friendly_name(path_get(RARCH_PATH_SUBSYSTEM), subsystem_name, sizeof(subsystem_name)); + + /* the push function reads our entry as const, so these casts are safe */ + entry.path = (char*)tmp; + entry.label = (char*)label; + entry.core_path = (char*)core_path; + entry.core_name = (char*)core_name; + entry.crc32 = (char*)crc32; + entry.db_name = (char*)db_name; + entry.subsystem_ident = (char*)path_get(RARCH_PATH_SUBSYSTEM), + entry.subsystem_name = (char*)subsystem_name; + entry.subsystem_roms = (struct string_list*)path_get_subsystem_list(); + command_playlist_push_write( - playlist_hist, - tmp, - label, - core_path, - core_name, - crc32, - db_name, - path_get(RARCH_PATH_SUBSYSTEM), - path_get_subsystem_list()); + playlist_hist, &entry); + } } free(tmp); diff --git a/tasks/task_database.c b/tasks/task_database.c index 29700f1413..e68f3306bb 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -845,12 +845,17 @@ static int database_info_list_iterate_found_match( if (!playlist_entry_exists(playlist, entry_path_str, db_crc)) { - playlist_push(playlist, entry_path_str, - db_info_entry->name, - file_path_str(FILE_PATH_DETECT), - file_path_str(FILE_PATH_DETECT), - db_crc, db_playlist_base_str, - NULL, NULL); + struct playlist_entry entry = {0}; + + /* the push function reads our entry as const, so these casts are safe */ + entry.path = entry_path_str; + entry.label = db_info_entry->name; + entry.core_path = (char*)file_path_str(FILE_PATH_DETECT); + entry.core_name = (char*)file_path_str(FILE_PATH_DETECT); + entry.crc32 = db_crc; + entry.db_name = db_playlist_base_str; + + playlist_push(playlist, &entry); } playlist_write_file(playlist); @@ -1015,19 +1020,22 @@ static int task_database_iterate_playlist_lutro( path, file_path_str(FILE_PATH_DETECT))) { char *game_title = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + struct playlist_entry entry = {0}; game_title[0] = '\0'; fill_short_pathname_representation_noext(game_title, path, PATH_MAX_LENGTH * sizeof(char)); - playlist_push(playlist, path, - game_title, - file_path_str(FILE_PATH_DETECT), - file_path_str(FILE_PATH_DETECT), - file_path_str(FILE_PATH_DETECT), - file_path_str(FILE_PATH_LUTRO_PLAYLIST), - NULL, NULL); + /* the push function reads our entry as const, so these casts are safe */ + entry.path = (char*)path; + entry.label = game_title; + entry.core_path = (char*)file_path_str(FILE_PATH_DETECT); + entry.core_name = (char*)file_path_str(FILE_PATH_DETECT); + entry.crc32 = (char*)file_path_str(FILE_PATH_DETECT); + entry.db_name = (char*)file_path_str(FILE_PATH_LUTRO_PLAYLIST); + + playlist_push(playlist, &entry); free(game_title); } diff --git a/tasks/task_netplay_find_content.c b/tasks/task_netplay_find_content.c index 205606d2bb..842629b588 100644 --- a/tasks/task_netplay_find_content.c +++ b/tasks/task_netplay_find_content.c @@ -205,7 +205,8 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) /* start by checking cases that don't require a search */ /* the core doesn't have any content to match, so fast-succeed */ - if(!core_requires_content(state)) { + if (!core_requires_content(state)) + { state->found = true; state->contentless = true; task_set_data(task, state); @@ -222,7 +223,8 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) } /* We opened the playlist directory, but there's nothing there. Nothing to do. */ - if(state->lpl_list->size == 0 && core_requires_content(state)) { + if (state->lpl_list->size == 0 && core_requires_content(state)) + { string_list_free(state->lpl_list); finish_task(task, "There are no playlists available; cannot execute search"); command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED, state->hostname); @@ -233,7 +235,7 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) have_crc = !string_is_equal(state->content_crc, "00000000|crc"); /* if content is already loaded and the lobby gave us a CRC, check the loaded content first */ - if(have_crc && content_get_crc() > 0) + if (have_crc && content_get_crc() > 0) { char current[PATH_MAX_LENGTH]; @@ -258,7 +260,7 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) /* now let's do the search */ if (string_is_empty(state->subsystem_name) || string_is_equal(state->subsystem_name, "N/A")) { - for(i = 0; i < state->lpl_list->size; i++) + for (i = 0; i < state->lpl_list->size; i++) { playlist_t *playlist = NULL; unsigned playlist_size = 0; @@ -272,14 +274,18 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) playlist = playlist_init(lpl_path, 99999); playlist_size = playlist_get_size(playlist); - for(j = 0; j < playlist_size; j++) + for (j = 0; j < playlist_size; j++) { - const char *playlist_crc32 = NULL; const char *playlist_path = NULL; + const char *playlist_crc32 = NULL; + const struct playlist_entry *playlist_entry = NULL; - playlist_get_index(playlist, j, &playlist_path, NULL, NULL, NULL, &playlist_crc32, NULL, NULL, NULL); + playlist_get_index(playlist, j, &playlist_entry); - if(have_crc && string_is_equal(playlist_crc32, state->content_crc)) + playlist_path = playlist_entry->path; + playlist_crc32 = playlist_entry->crc32; + + if (have_crc && string_is_equal(playlist_crc32, state->content_crc)) { RARCH_LOG("[lobby] CRC match %s\n", playlist_crc32); strlcpy(state->content_path, playlist_path, sizeof(state->content_path)); @@ -298,7 +304,7 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) * Otherwise, on match we complete the task and mark it as successful immediately. */ - if(!string_is_empty(entry) && + if (!string_is_empty(entry) && string_is_equal(entry, state->content_path) && strstr(state->core_extensions, path_get_extension(playlist_path))) { @@ -312,8 +318,10 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) playlist_free(playlist); return; } + task_set_progress(task, (int)(j / playlist_size * 100.0)); } + playlist_free(playlist); } } @@ -326,7 +334,7 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) { found[i] = false; - for(j = 0; j < state->lpl_list->size && !found[i]; j++) + for (j = 0; j < state->lpl_list->size && !found[i]; j++) { playlist_t *playlist = NULL; unsigned playlist_size = 0; @@ -340,34 +348,37 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) playlist = playlist_init(lpl_path, 99999); playlist_size = playlist_get_size(playlist); - for(k = 0; k < playlist_size && !found[i]; k++) + for (k = 0; k < playlist_size && !found[i]; k++) { - const char *playlist_crc32 = NULL; - const char *playlist_path = NULL; + const struct playlist_entry *playlist_entry = NULL; - playlist_get_index(playlist, k, &playlist_path, NULL, NULL, NULL, &playlist_crc32, NULL, NULL, NULL); - get_entry(entry, sizeof(entry), playlist_path); + playlist_get_index(playlist, k, &playlist_entry); - if(!string_is_empty(entry) && + get_entry(entry, sizeof(entry), playlist_entry->path); + + if (!string_is_empty(entry) && strstr(game_list->elems[i].data, entry) && - strstr(state->core_extensions, path_get_extension(playlist_path))) + strstr(state->core_extensions, path_get_extension(playlist_entry->path))) { - RARCH_LOG("[lobby] filename match %s\n", playlist_path); + RARCH_LOG("[lobby] filename match %s\n", playlist_entry->path); if (i == 0) { state->content_path[0] = '\0'; - strlcpy(state->content_path, playlist_path, sizeof(state->content_path)); + strlcpy(state->content_path, playlist_entry->path, sizeof(state->content_path)); } else { strlcat(state->content_path, "|", sizeof(state->content_path)); - strlcat(state->content_path, playlist_path, sizeof(state->content_path)); + strlcat(state->content_path, playlist_entry->path, sizeof(state->content_path)); } + found[i] = true; } + task_set_progress(task, (int)(j / playlist_size * 100.0)); } + playlist_free(playlist); } } @@ -388,6 +399,7 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) task_set_data(task, state); finish_task(task, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND)); } + string_list_free(state->lpl_list); string_list_free(game_list); return; @@ -457,7 +469,7 @@ bool task_push_netplay_crc_scan(uint32_t crc, char* name, #if 0 printf("Info: %s State: %s", info->list[i].core_name, state->core_name); #endif - if(string_is_equal(info->list[i].core_name, state->core_name)) + if (string_is_equal(info->list[i].core_name, state->core_name)) { strlcpy(state->core_path, info->list[i].path, sizeof(state->core_path)); diff --git a/tasks/task_screenshot.c b/tasks/task_screenshot.c index eb1f8beedb..c00ff8ebc4 100644 --- a/tasks/task_screenshot.c +++ b/tasks/task_screenshot.c @@ -170,14 +170,16 @@ static void task_screenshot_handler(retro_task_t *task) !state->silence && state->history_list_enable ) - command_playlist_push_write( - g_defaults.image_history, - state->filename, - NULL, - "builtin", - "imageviewer", - NULL, NULL, - NULL, NULL); + { + struct playlist_entry entry = {0}; + + /* the push function reads our entry as const, so these casts are safe */ + entry.path = state->filename; + entry.core_path = (char*)"builtin"; + entry.core_name = (char*)"imageviewer"; + + command_playlist_push_write(g_defaults.image_history, &entry); + } #endif task_set_progress(task, 100); diff --git a/ui/drivers/qt/qt_playlist.cpp b/ui/drivers/qt/qt_playlist.cpp index 8e2aab5325..ea8166d772 100644 --- a/ui/drivers/qt/qt_playlist.cpp +++ b/ui/drivers/qt/qt_playlist.cpp @@ -601,8 +601,19 @@ void MainWindow::addFilesToPlaylist(QStringList files) } } - playlist_push(playlist, pathData, fileNameNoExten, - corePathData, coreNameData, "00000000|crc", databaseData, NULL, NULL); + { + struct playlist_entry entry = {0}; + + /* the push function reads our entry as const, so these casts are safe */ + entry.path = const_cast(pathData); + entry.label = const_cast(fileNameNoExten); + entry.core_path = const_cast(corePathData); + entry.core_name = const_cast(coreNameData); + entry.crc32 = const_cast("00000000|crc"); + entry.db_name = const_cast(databaseData); + + playlist_push(playlist, &entry); + } } playlist_write_file(playlist); @@ -703,8 +714,20 @@ bool MainWindow::updateCurrentPlaylistEntry(const QHash &conte playlist = playlist_init(playlistPathData, COLLECTION_SIZE); - playlist_update(playlist, index, pathData, labelData, - corePathData, coreNameData, crc32Data, dbNameData); + { + struct playlist_entry entry = {0}; + + /* the update function reads our entry as const, so these casts are safe */ + entry.path = const_cast(pathData); + entry.label = const_cast(labelData); + entry.core_path = const_cast(corePathData); + entry.core_name = const_cast(coreNameData); + entry.crc32 = const_cast(crc32Data); + entry.db_name = const_cast(dbNameData); + + playlist_update(playlist, index, &entry); + } + playlist_write_file(playlist); playlist_free(playlist); @@ -1358,48 +1381,41 @@ void PlaylistModel::getPlaylistItems(QString path) for (i = 0; i < playlistSize; i++) { - const char *path = NULL; - const char *label = NULL; - const char *core_path = NULL; - const char *core_name = NULL; - const char *crc32 = NULL; - const char *db_name = NULL; + const struct playlist_entry *entry = NULL; QHash hash; - playlist_get_index(playlist, i, - &path, &label, &core_path, - &core_name, &crc32, &db_name, NULL, NULL); + playlist_get_index(playlist, i, &entry); - if (string_is_empty(path)) + if (string_is_empty(entry->path)) continue; else - hash["path"] = path; + hash["path"] = entry->path; hash["index"] = QString::number(i); - if (string_is_empty(label)) + if (string_is_empty(entry->label)) { - hash["label"] = path; - hash["label_noext"] = path; + hash["label"] = entry->path; + hash["label_noext"] = entry->path; } else { - hash["label"] = label; - hash["label_noext"] = label; + hash["label"] = entry->label; + hash["label_noext"] = entry->label; } - if (!string_is_empty(core_path)) - hash["core_path"] = core_path; + if (!string_is_empty(entry->core_path)) + hash["core_path"] = entry->core_path; - if (!string_is_empty(core_name)) - hash["core_name"] = core_name; + if (!string_is_empty(entry->core_name)) + hash["core_name"] = entry->core_name; - if (!string_is_empty(crc32)) - hash["crc32"] = crc32; + if (!string_is_empty(entry->crc32)) + hash["crc32"] = entry->crc32; - if (!string_is_empty(db_name)) + if (!string_is_empty(entry->db_name)) { - hash["db_name"] = db_name; + hash["db_name"] = entry->db_name; hash["db_name"].remove(file_path_str(FILE_PATH_LPL_EXTENSION)); } From 15c0191f08b09990ee0f6d192ed8220d47cfa1c1 Mon Sep 17 00:00:00 2001 From: bparker06 Date: Fri, 12 Apr 2019 13:04:59 -0400 Subject: [PATCH 170/237] Update task_content.c --- tasks/task_content.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tasks/task_content.c b/tasks/task_content.c index aecf58c0f9..8c02546939 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -2011,7 +2011,10 @@ void content_get_subsystem_friendly_name(const char* subsystem_name, char* subsy for (i = 0; i < subsystem_current_count; i++, subsystem++) { if (string_is_equal(subsystem_name, subsystem->ident)) + { strlcpy(subsystem_friendly_name, subsystem->desc, len); + break; + } } return; From b8471aa3dcefe2cdf892f6672a132fc07c9f76f2 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Fri, 12 Apr 2019 19:28:34 -0400 Subject: [PATCH 171/237] gl1: add gpu hard sync support and print osd statistics --- gfx/drivers/gl1.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/gfx/drivers/gl1.c b/gfx/drivers/gl1.c index 245cb54e65..0f2bf526bf 100644 --- a/gfx/drivers/gl1.c +++ b/gfx/drivers/gl1.c @@ -719,6 +719,25 @@ static bool gl1_gfx_frame(void *data, const void *frame, #ifdef HAVE_MENU if (gl1->menu_texture_enable) menu_driver_frame(video_info); + else if (video_info->statistics_show) + { + struct font_params *osd_params = (struct font_params*) + &video_info->osd_stat_params; + + if (osd_params) + { + font_driver_render_msg(video_info, NULL, video_info->stat_text, + (const struct font_params*)&video_info->osd_stat_params); + if (frame_count % 60 == 0) + RARCH_LOG("%s\n", video_info->stat_text); +#if 0 + osd_params->y = 0.350f; + osd_params->scale = 0.75f; + font_driver_render_msg(video_info, NULL, video_info->chat_text, + (const struct font_params*)&video_info->osd_stat_params); +#endif + } + } #ifdef HAVE_MENU_WIDGETS menu_widgets_frame(video_info); @@ -760,13 +779,12 @@ static bool gl1_gfx_frame(void *data, const void *frame, video_info->cb_swap_buffers(video_info->context_data, video_info); /* check if we are fast forwarding or in menu, if we are ignore hard sync */ - if (gl1->have_sync - && video_info->hard_sync + if (video_info->hard_sync && !video_info->input_driver_nonblock_state && !gl1->menu_texture_enable) { glClear(GL_COLOR_BUFFER_BIT); - /* hard sync would go here if possible */ + glFinish(); } gl1_context_bind_hw_render(gl1, true); @@ -1228,6 +1246,7 @@ static uint32_t gl1_get_flags(void *data) { uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_HARD_SYNC); BIT32_SET(flags, GFX_CTX_FLAGS_BLACK_FRAME_INSERTION); BIT32_SET(flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING); From 3619fae2d9d0a7cb3850f59ed3b99047914dde84 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 13 Apr 2019 02:14:43 +0200 Subject: [PATCH 172/237] (LGTM) Silence some warnings --- gfx/drivers_shader/shader_vulkan.cpp | 2 +- gfx/drivers_shader/slang_reflection.cpp | 4 ++-- pkg/emscripten/libretro/libretro.js | 2 +- tasks/task_autodetect.c | 2 +- verbosity.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp index 0578522351..ec3be3d1bd 100644 --- a/gfx/drivers_shader/shader_vulkan.cpp +++ b/gfx/drivers_shader/shader_vulkan.cpp @@ -1369,7 +1369,7 @@ bool Pass::init_pipeline_layout() if (reflection.push_constant_stage_mask & SLANG_STAGE_FRAGMENT_MASK) push_range.stageFlags |= VK_SHADER_STAGE_FRAGMENT_BIT; - RARCH_LOG("[Vulkan]: Push Constant Block: %u bytes.\n", reflection.push_constant_size); + RARCH_LOG("[Vulkan]: Push Constant Block: %u bytes.\n", (unsigned int)reflection.push_constant_size); layout_info.pushConstantRangeCount = 1; layout_info.pPushConstantRanges = &push_range; diff --git a/gfx/drivers_shader/slang_reflection.cpp b/gfx/drivers_shader/slang_reflection.cpp index e9ef89ce23..1726840da6 100644 --- a/gfx/drivers_shader/slang_reflection.cpp +++ b/gfx/drivers_shader/slang_reflection.cpp @@ -643,9 +643,9 @@ bool slang_reflect(const Compiler &vertex_compiler, const Compiler &fragment_com for (auto ¶m : reflection->semantic_float_parameters) { if (param.uniform) - RARCH_LOG("[slang]: #%u (Offset: %u)\n", i, param.ubo_offset); + RARCH_LOG("[slang]: #%u (Offset: %u)\n", i, (unsigned int)param.ubo_offset); if (param.push_constant) - RARCH_LOG("[slang]: #%u (PushOffset: %u)\n", i, param.push_constant_offset); + RARCH_LOG("[slang]: #%u (PushOffset: %u)\n", i, (unsigned int)param.push_constant_offset); i++; } diff --git a/pkg/emscripten/libretro/libretro.js b/pkg/emscripten/libretro/libretro.js index 2dca489768..1654d74e7d 100644 --- a/pkg/emscripten/libretro/libretro.js +++ b/pkg/emscripten/libretro/libretro.js @@ -149,7 +149,7 @@ function selectFiles(files) $('#icnAdd').addClass('fa-spinner spinning'); var count = files.length; - for (var i = 0; i < files.length; i++) + for (var i = 0; i < count; i++) { filereader = new FileReader(); filereader.file_name = files[i].name; diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index ae4a3d7685..f11ebc8d11 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -368,7 +368,7 @@ static bool input_autoconfigure_joypad_from_conf_dir( if (list) { - RARCH_LOG("[Autoconf]: %d profiles found.\n", list->size); + RARCH_LOG("[Autoconf]: %d profiles found.\n", (int)list->size); } for (i = 0; i < list->size; i++) diff --git a/verbosity.c b/verbosity.c index 267f6193f6..b6372c6d9e 100644 --- a/verbosity.c +++ b/verbosity.c @@ -270,7 +270,7 @@ void RARCH_LOG_BUFFER(uint8_t *data, size_t size) int padding = size % 16; uint8_t buf[16] = {0}; - RARCH_LOG("== %d-byte buffer ==================\n", size); + RARCH_LOG("== %d-byte buffer ==================\n", (int)size); for(i = 0, offset = 0; i < size; i++) { From 95145ec0d43a6d142c200e290f8062e6128f43f4 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Fri, 12 Apr 2019 21:16:58 -0400 Subject: [PATCH 173/237] remove debug code --- gfx/drivers/gl1.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gfx/drivers/gl1.c b/gfx/drivers/gl1.c index 0f2bf526bf..2f754bd180 100644 --- a/gfx/drivers/gl1.c +++ b/gfx/drivers/gl1.c @@ -728,8 +728,6 @@ static bool gl1_gfx_frame(void *data, const void *frame, { font_driver_render_msg(video_info, NULL, video_info->stat_text, (const struct font_params*)&video_info->osd_stat_params); - if (frame_count % 60 == 0) - RARCH_LOG("%s\n", video_info->stat_text); #if 0 osd_params->y = 0.350f; osd_params->scale = 0.75f; From 70373dba9ab8729ad1687e3db17de904b31e7a78 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 13 Apr 2019 04:56:11 +0200 Subject: [PATCH 174/237] (task_screenshot.c) Cleanups --- tasks/task_screenshot.c | 114 +++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 60 deletions(-) diff --git a/tasks/task_screenshot.c b/tasks/task_screenshot.c index 9facd37a57..4647ccf6c9 100644 --- a/tasks/task_screenshot.c +++ b/tasks/task_screenshot.c @@ -82,20 +82,16 @@ struct screenshot_task_state static bool screenshot_dump_direct(screenshot_task_state_t *state) { - struct scaler_ctx *scaler = (struct scaler_ctx*)&state->scaler; - bool ret = false; -#ifdef HAVE_RBMP - enum rbmp_source_type bmp_type = RBMP_SOURCE_TYPE_DONT_CARE; - (void)bmp_type; -#endif + struct scaler_ctx *scaler = (struct scaler_ctx*)&state->scaler; + bool ret = false; #if defined(HAVE_RPNG) if (state->bgr24) - scaler->in_fmt = SCALER_FMT_BGR24; + scaler->in_fmt = SCALER_FMT_BGR24; else if (state->pixel_format_type == RETRO_PIXEL_FORMAT_XRGB8888) - scaler->in_fmt = SCALER_FMT_ARGB8888; + scaler->in_fmt = SCALER_FMT_ARGB8888; else - scaler->in_fmt = SCALER_FMT_RGB565; + scaler->in_fmt = SCALER_FMT_RGB565; video_frame_convert_to_bgr24( scaler, @@ -117,17 +113,20 @@ static bool screenshot_dump_direct(screenshot_task_state_t *state) free(state->out_buffer); #elif defined(HAVE_RBMP) - if (state->bgr24) - bmp_type = RBMP_SOURCE_TYPE_BGR24; - else if (state->pixel_format_type == RETRO_PIXEL_FORMAT_XRGB8888) - bmp_type = RBMP_SOURCE_TYPE_XRGB888; + { + enum rbmp_source_type bmp_type = RBMP_SOURCE_TYPE_DONT_CARE; + if (state->bgr24) + bmp_type = RBMP_SOURCE_TYPE_BGR24; + else if (state->pixel_format_type == RETRO_PIXEL_FORMAT_XRGB8888) + bmp_type = RBMP_SOURCE_TYPE_XRGB888; - ret = rbmp_save_image(state->filename, - state->frame, - state->width, - state->height, - state->pitch, - bmp_type); + ret = rbmp_save_image(state->filename, + state->frame, + state->width, + state->height, + state->pitch, + bmp_type); + } #endif #if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) @@ -174,9 +173,9 @@ static void task_screenshot_handler(retro_task_t *task) struct playlist_entry entry = {0}; /* the push function reads our entry as const, so these casts are safe */ - entry.path = state->filename; - entry.core_path = (char*)"builtin"; - entry.core_name = (char*)"imageviewer"; + entry.path = state->filename; + entry.core_path = (char*)"builtin"; + entry.core_name = (char*)"imageviewer"; command_playlist_push_write(g_defaults.image_history, &entry); } @@ -208,24 +207,19 @@ static bool screenshot_dump( bool fullpath, bool use_thread) { + struct retro_system_info system_info; char screenshot_path[PATH_MAX_LENGTH]; uint8_t *buf = NULL; settings_t *settings = config_get_ptr(); - retro_task_t *task; - screenshot_task_state_t *state; const char *screenshot_dir = settings->paths.directory_screenshot; - struct retro_system_info system_info; + retro_task_t *task = task_init(); + screenshot_task_state_t *state = (screenshot_task_state_t*)calloc(1, sizeof(*state)); + state->shotname[0] = '\0'; screenshot_path[0] = '\0'; - if (!core_get_system_info(&system_info)) - return false; - - task = task_init(); - state = (screenshot_task_state_t*)calloc(1, sizeof(*state)); - state->shotname[0] = '\0'; - - /* If fullpath is true, name_base already contains a static path + filename to save the screenshot to. */ + /* If fullpath is true, name_base already contains a + * static path + filename to save the screenshot to. */ if (fullpath) strlcpy(state->filename, name_base, sizeof(state->filename)); else @@ -263,6 +257,9 @@ static bool screenshot_dump( if (path_is_empty(RARCH_PATH_CONTENT)) { + if (!core_get_system_info(&system_info)) + return false; + if (string_is_empty(system_info.library_name)) screenshot_name = "RetroArch"; else @@ -306,33 +303,29 @@ static bool screenshot_dump( task_free_title(task); else #endif - if (!savestate) - task->title = strdup(msg_hash_to_str(MSG_TAKING_SCREENSHOT)); + if (!savestate) + task->title = strdup(msg_hash_to_str(MSG_TAKING_SCREENSHOT)); - if (!task_queue_push(task)) - { - /* There is already a blocking task going on */ - if (task->title) - task_free_title(task); + if (task_queue_push(task)) + return true; - free(task); + /* There is already a blocking task going on */ + if (task->title) + task_free_title(task); - if (state->out_buffer) - free(state->out_buffer); + free(task); - free(state); + if (state->out_buffer) + free(state->out_buffer); - return false; - } - } - else - { - if (task) - free(task); - return screenshot_dump_direct(state); + free(state); + + return false; } - return true; + if (task) + free(task); + return screenshot_dump_direct(state); } #if !defined(VITA) @@ -341,7 +334,6 @@ static bool take_screenshot_viewport(const char *name_base, bool savestate, { struct video_viewport vp; uint8_t *buffer = NULL; - bool retval = false; vp.x = 0; vp.y = 0; @@ -374,7 +366,7 @@ static bool take_screenshot_viewport(const char *name_base, bool savestate, error: if (buffer) free(buffer); - return retval; + return false; } #endif @@ -392,7 +384,8 @@ static bool take_screenshot_raw(const char *name_base, void *userbuf, */ if (!screenshot_dump(name_base, (const uint8_t*)data + (height - 1) * pitch, - width, height, (int)(-pitch), false, userbuf, savestate, is_idle, is_paused, fullpath, use_thread)) + width, height, (int)(-pitch), false, userbuf, savestate, + is_idle, is_paused, fullpath, use_thread)) return false; return true; @@ -403,7 +396,6 @@ static bool take_screenshot_choice(const char *name_base, bool savestate, { size_t old_pitch; unsigned old_width, old_height; - bool ret = false; void *frame_data = NULL; const void* old_data = NULL; settings_t *settings = config_get_ptr(); @@ -446,13 +438,15 @@ static bool take_screenshot_choice(const char *name_base, bool savestate, { video_driver_set_cached_frame_ptr(frame_data); if (take_screenshot_raw(name_base, frame_data, savestate, is_idle, is_paused, fullpath, use_thread)) - ret = true; + return true; } - return ret; + return false; } -bool take_screenshot(const char *name_base, bool silence, bool has_valid_framebuffer, bool fullpath, bool use_thread) +bool take_screenshot(const char *name_base, + bool silence, bool has_valid_framebuffer, + bool fullpath, bool use_thread) { bool is_paused = false; bool is_idle = false; From a7abd77141e492422a099d4add409a6a04ad4913 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 13 Apr 2019 06:40:21 +0200 Subject: [PATCH 175/237] (menu_shader) Remove some unnecessary functions --- menu/cbs/menu_cbs_left.c | 2 +- menu/cbs/menu_cbs_right.c | 2 +- menu/menu_shader.c | 20 ---------- menu/menu_shader.h | 4 -- ui/drivers/qt/shaderparamsdialog.cpp | 56 +++++----------------------- 5 files changed, 11 insertions(+), 73 deletions(-) diff --git a/menu/cbs/menu_cbs_left.c b/menu/cbs/menu_cbs_left.c index 19704f5320..69955af267 100644 --- a/menu/cbs/menu_cbs_left.c +++ b/menu/cbs/menu_cbs_left.c @@ -341,7 +341,7 @@ static int action_left_shader_num_passes(unsigned type, const char *label, return menu_cbs_exit(); if (pass_count > 0) - menu_shader_manager_decrement_amount_passes(); + shader->passes--; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); diff --git a/menu/cbs/menu_cbs_right.c b/menu/cbs/menu_cbs_right.c index 40a258c712..82850b9058 100644 --- a/menu/cbs/menu_cbs_right.c +++ b/menu/cbs/menu_cbs_right.c @@ -362,7 +362,7 @@ static int action_right_shader_num_passes(unsigned type, const char *label, return menu_cbs_exit(); if (pass_count < GFX_MAX_SHADERS) - menu_shader_manager_increment_amount_passes(); + shader->passes++; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); diff --git a/menu/menu_shader.c b/menu/menu_shader.c index 4be5d9924a..a27a042235 100644 --- a/menu/menu_shader.c +++ b/menu/menu_shader.c @@ -44,26 +44,6 @@ struct video_shader *menu_shader_get(void) return NULL; } -void menu_shader_manager_decrement_amount_passes(void) -{ - struct video_shader *shader = menu_shader_get(); - - if (!shader) - return; - - shader->passes--; -} - -void menu_shader_manager_increment_amount_passes(void) -{ - struct video_shader *shader = menu_shader_get(); - - if (!shader) - return; - - shader->passes++; -} - void menu_shader_manager_free(void) { if (menu_driver_shader) diff --git a/menu/menu_shader.h b/menu/menu_shader.h index 9609449680..a3da011651 100644 --- a/menu/menu_shader.h +++ b/menu/menu_shader.h @@ -82,10 +82,6 @@ void menu_shader_manager_clear_pass_scale(unsigned i); void menu_shader_manager_clear_pass_path(unsigned i); -void menu_shader_manager_decrement_amount_passes(void); - -void menu_shader_manager_increment_amount_passes(void); - RETRO_END_DECLS #endif diff --git a/ui/drivers/qt/shaderparamsdialog.cpp b/ui/drivers/qt/shaderparamsdialog.cpp index 8b70451531..397076920c 100644 --- a/ui/drivers/qt/shaderparamsdialog.cpp +++ b/ui/drivers/qt/shaderparamsdialog.cpp @@ -150,9 +150,7 @@ void ShaderParamsDialog::clearLayout() if (m_scrollArea) { foreach (QObject *obj, children()) - { obj->deleteLater(); - } } m_layout = new QVBoxLayout(); @@ -179,25 +177,17 @@ void ShaderParamsDialog::getShaders(struct video_shader **menu_shader, struct vi if (menu_shader) { if (shader) - { *menu_shader = shader; - } else - { *menu_shader = NULL; - } } if (video_shader) { if (shader) - { *video_shader = shader_info.data; - } else - { *video_shader = NULL; - } } if (video_shader) @@ -215,13 +205,9 @@ void ShaderParamsDialog::getShaders(struct video_shader **menu_shader, struct vi } if (shader_info.data) - { *video_shader = shader_info.data; - } else - { *video_shader = NULL; - } } } @@ -272,11 +258,11 @@ void ShaderParamsDialog::onFilterComboBoxIndexChanged(int) void ShaderParamsDialog::onScaleComboBoxIndexChanged(int) { - QComboBox *comboBox = qobject_cast(sender()); QVariant passVariant; - int pass = 0; - bool ok = false; - struct video_shader *menu_shader = NULL; + QComboBox *comboBox = qobject_cast(sender()); + int pass = 0; + bool ok = false; + struct video_shader *menu_shader = NULL; struct video_shader *video_shader = NULL; getShaders(&menu_shader, &video_shader); @@ -345,10 +331,7 @@ void ShaderParamsDialog::onShaderPassMoveDownClicked() pass = passVariant.toInt(&ok); - if (!ok) - return; - - if (pass < 0) + if (!ok || pass < 0) return; if (video_shader) @@ -364,13 +347,9 @@ void ShaderParamsDialog::onShaderPassMoveDownClicked() struct video_shader_parameter *param = &video_shader->parameters[i]; if (param->pass == pass) - { param->pass += 1; - } else if (param->pass == pass + 1) - { param->pass -= 1; - } } tempPass = ShaderPass(&video_shader->pass[pass]); @@ -391,13 +370,9 @@ void ShaderParamsDialog::onShaderPassMoveDownClicked() struct video_shader_parameter *param = &menu_shader->parameters[i]; if (param->pass == pass) - { param->pass += 1; - } else if (param->pass == pass + 1) - { param->pass -= 1; - } } tempPass = ShaderPass(&menu_shader->pass[pass]); @@ -429,10 +404,7 @@ void ShaderParamsDialog::onShaderPassMoveUpClicked() pass = passVariant.toInt(&ok); - if (!ok) - return; - - if (pass <= 0) + if (!ok || pass <= 0) return; if (video_shader) @@ -448,13 +420,9 @@ void ShaderParamsDialog::onShaderPassMoveUpClicked() struct video_shader_parameter *param = &video_shader->parameters[i]; if (param->pass == pass) - { param->pass -= 1; - } else if (param->pass == pass - 1) - { param->pass += 1; - } } tempPass = ShaderPass(&video_shader->pass[pass - 1]); @@ -475,13 +443,9 @@ void ShaderParamsDialog::onShaderPassMoveUpClicked() struct video_shader_parameter *param = &menu_shader->parameters[i]; if (param->pass == pass) - { param->pass -= 1; - } else if (param->pass == pass - 1) - { param->pass += 1; - } } tempPass = ShaderPass(&menu_shader->pass[pass - 1]); @@ -684,7 +648,7 @@ void ShaderParamsDialog::onShaderAddPassClicked() pathData = pathArray.constData(); if (menu_shader->passes < GFX_MAX_SHADERS) - menu_shader_manager_increment_amount_passes(); + menu_shader->passes++; else return; @@ -811,7 +775,7 @@ void ShaderParamsDialog::onShaderClearAllPassesClicked() return; while (menu_shader->passes > 0) - menu_shader_manager_decrement_amount_passes(); + menu_shader->passes--; onShaderApplyClicked(); } @@ -846,11 +810,9 @@ void ShaderParamsDialog::onShaderRemovePassClicked() /* move selected pass to the bottom */ for (i = pass; i < static_cast(menu_shader->passes) - 1; i++) - { std::swap(menu_shader->pass[i], menu_shader->pass[i + 1]); - } - menu_shader_manager_decrement_amount_passes(); + menu_shader->passes--; onShaderApplyClicked(); } From 10d66d28c0a1b271804eb049729e11ea8872d672 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 13 Apr 2019 18:47:11 +0200 Subject: [PATCH 176/237] (runtime_file.c) Code style cleanups(runtime_file.c) Code style cleanups(runtime_file.c) Code style cleanups(runtime_file.c) Code style cleanups(runtime_file.c) Code style cleanups(runtime_file.c) Code style cleanups(runtime_file.c) Code style cleanups(runtime_file.c) Code style cleanups(runtime_file.c) Code style cleanups --- runtime_file.c | 239 +++++++++++++++++++++++-------------------------- 1 file changed, 112 insertions(+), 127 deletions(-) diff --git a/runtime_file.c b/runtime_file.c index ea524c4d3a..5ed29d6f95 100644 --- a/runtime_file.c +++ b/runtime_file.c @@ -109,8 +109,9 @@ static void RtlJSONLogError(RtlJSONContext *pCtx) { if (pCtx->parser && JSON_Parser_GetError(pCtx->parser) != JSON_Error_AbortedByHandler) { - JSON_Error error = JSON_Parser_GetError(pCtx->parser); + JSON_Error error = JSON_Parser_GetError(pCtx->parser); JSON_Location errorLocation = { 0, 0, 0 }; + (void)JSON_Parser_GetErrorLocation(pCtx->parser, &errorLocation); RARCH_ERR("Error: Invalid JSON at line %d, column %d (input byte %d) - %s.\n", (int)errorLocation.line + 1, @@ -130,27 +131,21 @@ static void RtlJSONLogError(RtlJSONContext *pCtx) * Does nothing if log file does not exist. */ static void runtime_log_read_file(runtime_log_t *runtime_log) { - unsigned runtime_hours = 0; - unsigned runtime_minutes = 0; - unsigned runtime_seconds = 0; + unsigned runtime_hours = 0; + unsigned runtime_minutes = 0; + unsigned runtime_seconds = 0; - unsigned last_played_year = 0; - unsigned last_played_month = 0; - unsigned last_played_day = 0; - unsigned last_played_hour = 0; + unsigned last_played_year = 0; + unsigned last_played_month = 0; + unsigned last_played_day = 0; + unsigned last_played_hour = 0; unsigned last_played_minute = 0; unsigned last_played_second = 0; - RtlJSONContext context = {0}; - RFILE *file = NULL; - int ret = 0; - - /* Check if log file exists */ - if (!filestream_exists(runtime_log->path)) - return; - + RtlJSONContext context = {0}; /* Attempt to open log file */ - file = filestream_open(runtime_log->path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); + RFILE *file = filestream_open(runtime_log->path, + RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!file) { @@ -159,10 +154,10 @@ static void runtime_log_read_file(runtime_log_t *runtime_log) } /* Initialise JSON parser */ - context.runtime_string = NULL; + context.runtime_string = NULL; context.last_played_string = NULL; - context.parser = JSON_Parser_Create(NULL); - context.file = file; + context.parser = JSON_Parser_Create(NULL); + context.file = file; if (!context.parser) { @@ -181,7 +176,7 @@ static void runtime_log_read_file(runtime_log_t *runtime_log) { /* Runtime log files are tiny - use small chunk size */ char chunk[128] = {0}; - int64_t length = filestream_read(file, chunk, sizeof(chunk)); + int64_t length = filestream_read(file, chunk, sizeof(chunk)); /* Error checking... */ if (!length && !filestream_eof(file)) @@ -216,40 +211,38 @@ static void runtime_log_read_file(runtime_log_t *runtime_log) /* Process string values read from JSON file */ /* Runtime */ - ret = 0; if (!string_is_empty(context.runtime_string)) - ret = sscanf(context.runtime_string, LOG_FILE_RUNTIME_FORMAT_STR, - &runtime_hours, &runtime_minutes, &runtime_seconds); - - if (ret != 3) { - RARCH_ERR("Runtime log file - invalid 'runtime' entry detected: %s\n", runtime_log->path); - goto end; + if (sscanf(context.runtime_string, LOG_FILE_RUNTIME_FORMAT_STR, + &runtime_hours, &runtime_minutes, &runtime_seconds) != 3) + { + RARCH_ERR("Runtime log file - invalid 'runtime' entry detected: %s\n", runtime_log->path); + goto end; + } } /* Last played */ - ret = 0; if (!string_is_empty(context.last_played_string)) - ret = sscanf(context.last_played_string, LOG_FILE_LAST_PLAYED_FORMAT_STR, - &last_played_year, &last_played_month, &last_played_day, - &last_played_hour, &last_played_minute, &last_played_second); - - if (ret != 6) { - RARCH_ERR("Runtime log file - invalid 'last played' entry detected: %s\n", runtime_log->path); - goto end; + if (sscanf(context.last_played_string, LOG_FILE_LAST_PLAYED_FORMAT_STR, + &last_played_year, &last_played_month, &last_played_day, + &last_played_hour, &last_played_minute, &last_played_second) != 6) + { + RARCH_ERR("Runtime log file - invalid 'last played' entry detected: %s\n", runtime_log->path); + goto end; + } } /* If we reach this point then all is well * > Assign values to runtime_log object */ - runtime_log->runtime.hours = runtime_hours; - runtime_log->runtime.minutes = runtime_minutes; - runtime_log->runtime.seconds = runtime_seconds; + runtime_log->runtime.hours = runtime_hours; + runtime_log->runtime.minutes = runtime_minutes; + runtime_log->runtime.seconds = runtime_seconds; - runtime_log->last_played.year = last_played_year; - runtime_log->last_played.month = last_played_month; - runtime_log->last_played.day = last_played_day; - runtime_log->last_played.hour = last_played_hour; + runtime_log->last_played.year = last_played_year; + runtime_log->last_played.month = last_played_month; + runtime_log->last_played.day = last_played_day; + runtime_log->last_played.hour = last_played_hour; runtime_log->last_played.minute = last_played_minute; runtime_log->last_played.second = last_played_second; @@ -270,24 +263,22 @@ end: * Returns NULL if content_path and/or core_path are invalid */ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, bool log_per_core) { - settings_t *settings = config_get_ptr(); - core_info_list_t *core_info = NULL; - runtime_log_t *runtime_log = NULL; - const char *core_path_basename = path_basename(core_path); - + unsigned i; char content_name[PATH_MAX_LENGTH]; char core_name[PATH_MAX_LENGTH]; char log_file_dir[PATH_MAX_LENGTH]; char log_file_path[PATH_MAX_LENGTH]; char tmp_buf[PATH_MAX_LENGTH]; + settings_t *settings = config_get_ptr(); + core_info_list_t *core_info = NULL; + runtime_log_t *runtime_log = NULL; + const char *core_path_basename = path_basename(core_path); - unsigned i; - - content_name[0] = '\0'; - core_name[0] = '\0'; - log_file_dir[0] = '\0'; - log_file_path[0] = '\0'; - tmp_buf[0] = '\0'; + content_name[0] = '\0'; + core_name[0] = '\0'; + log_file_dir[0] = '\0'; + log_file_path[0] = '\0'; + tmp_buf[0] = '\0'; /* Error checking */ if (!settings) @@ -317,16 +308,14 @@ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, for (i = 0; i < core_info->count; i++) { - if (string_is_equal(path_basename(core_info->list[i].path), core_path_basename)) - { - if (!string_is_empty(core_info->list[i].core_name)) - { - strlcpy(core_name, core_info->list[i].core_name, sizeof(core_name)); - break; - } - else - return NULL; - } + if (!string_is_equal(path_basename(core_info->list[i].path), core_path_basename)) + continue; + + if (string_is_empty(core_info->list[i].core_name)) + return NULL; + + strlcpy(core_name, core_info->list[i].core_name, sizeof(core_name)); + break; } if (string_is_empty(core_name)) @@ -350,13 +339,11 @@ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, return NULL; if (log_per_core) - { fill_pathname_join( log_file_dir, tmp_buf, core_name, sizeof(log_file_dir)); - } else strlcpy(log_file_dir, tmp_buf, sizeof(log_file_dir)); @@ -397,13 +384,14 @@ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, /* path_remove_extension() requires a char * (not const) * so have to use a temporary buffer... */ char *tmp_buf_no_ext = NULL; - tmp_buf[0] = '\0'; + tmp_buf[0] = '\0'; strlcpy(tmp_buf, path_basename(content_path), sizeof(tmp_buf)); - tmp_buf_no_ext = path_remove_extension(tmp_buf); - if (!string_is_empty(tmp_buf_no_ext)) - strlcpy(content_name, tmp_buf_no_ext, sizeof(content_name)); - else + tmp_buf_no_ext = path_remove_extension(tmp_buf); + + if (string_is_empty(tmp_buf_no_ext)) return NULL; + + strlcpy(content_name, tmp_buf_no_ext, sizeof(content_name)); } if (string_is_empty(content_name)) @@ -418,26 +406,27 @@ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, /* Phew... If we get this far then all is well. * > Create 'runtime_log' object */ - runtime_log = (runtime_log_t*)calloc(1, sizeof(*runtime_log)); + runtime_log = (runtime_log_t*)calloc(1, sizeof(*runtime_log)); if (!runtime_log) return NULL; /* > Populate default values */ - runtime_log->runtime.hours = 0; - runtime_log->runtime.minutes = 0; - runtime_log->runtime.seconds = 0; + runtime_log->runtime.hours = 0; + runtime_log->runtime.minutes = 0; + runtime_log->runtime.seconds = 0; - runtime_log->last_played.year = 0; - runtime_log->last_played.month = 0; - runtime_log->last_played.day = 0; - runtime_log->last_played.hour = 0; + runtime_log->last_played.year = 0; + runtime_log->last_played.month = 0; + runtime_log->last_played.day = 0; + runtime_log->last_played.hour = 0; runtime_log->last_played.minute = 0; runtime_log->last_played.second = 0; strlcpy(runtime_log->path, log_file_path, sizeof(runtime_log->path)); /* Load existing log file, if it exists */ - runtime_log_read_file(runtime_log); + if (filestream_exists(runtime_log->path)) + runtime_log_read_file(runtime_log); return runtime_log; } @@ -519,10 +508,10 @@ void runtime_log_set_last_played(runtime_log_t *runtime_log, /* This function should never be needed, so just * perform dumb value assignment (i.e. no validation * using mktime()) */ - runtime_log->last_played.year = year; - runtime_log->last_played.month = month; - runtime_log->last_played.day = day; - runtime_log->last_played.hour = hour; + runtime_log->last_played.year = year; + runtime_log->last_played.month = month; + runtime_log->last_played.day = day; + runtime_log->last_played.hour = hour; runtime_log->last_played.minute = minute; runtime_log->last_played.second = second; } @@ -549,10 +538,10 @@ void runtime_log_set_last_played_now(runtime_log_t *runtime_log) } /* Extract values */ - runtime_log->last_played.year = (unsigned)time_info->tm_year + 1900; - runtime_log->last_played.month = (unsigned)time_info->tm_mon + 1; - runtime_log->last_played.day = (unsigned)time_info->tm_mday; - runtime_log->last_played.hour = (unsigned)time_info->tm_hour; + runtime_log->last_played.year = (unsigned)time_info->tm_year + 1900; + runtime_log->last_played.month = (unsigned)time_info->tm_mon + 1; + runtime_log->last_played.day = (unsigned)time_info->tm_mday; + runtime_log->last_played.hour = (unsigned)time_info->tm_hour; runtime_log->last_played.minute = (unsigned)time_info->tm_min; runtime_log->last_played.second = (unsigned)time_info->tm_sec; } @@ -563,14 +552,14 @@ void runtime_log_reset(runtime_log_t *runtime_log) if (!runtime_log) return; - runtime_log->runtime.hours = 0; - runtime_log->runtime.minutes = 0; - runtime_log->runtime.seconds = 0; + runtime_log->runtime.hours = 0; + runtime_log->runtime.minutes = 0; + runtime_log->runtime.seconds = 0; - runtime_log->last_played.year = 0; - runtime_log->last_played.month = 0; - runtime_log->last_played.day = 0; - runtime_log->last_played.hour = 0; + runtime_log->last_played.year = 0; + runtime_log->last_played.month = 0; + runtime_log->last_played.day = 0; + runtime_log->last_played.hour = 0; runtime_log->last_played.minute = 0; runtime_log->last_played.second = 0; } @@ -583,7 +572,7 @@ void runtime_log_get_runtime_hms(runtime_log_t *runtime_log, unsigned *hours, un if (!runtime_log) return; - *hours = runtime_log->runtime.hours; + *hours = runtime_log->runtime.hours; *minutes = runtime_log->runtime.minutes; *seconds = runtime_log->runtime.seconds; } @@ -607,10 +596,10 @@ void runtime_log_get_last_played(runtime_log_t *runtime_log, if (!runtime_log) return; - *year = runtime_log->last_played.year; - *month = runtime_log->last_played.month; - *day = runtime_log->last_played.day; - *hour = runtime_log->last_played.hour; + *year = runtime_log->last_played.year; + *month = runtime_log->last_played.month; + *day = runtime_log->last_played.day; + *hour = runtime_log->last_played.hour; *minute = runtime_log->last_played.minute; *second = runtime_log->last_played.second; } @@ -621,23 +610,20 @@ void runtime_log_get_last_played_time(runtime_log_t *runtime_log, time_t *time) { struct tm time_info; - if (!runtime_log) - return; - - if (!time) + if (!runtime_log || !time) return; /* Set tm values */ - time_info.tm_year = (int)runtime_log->last_played.year - 1900; - time_info.tm_mon = (int)runtime_log->last_played.month - 1; - time_info.tm_mday = (int)runtime_log->last_played.day; - time_info.tm_hour = (int)runtime_log->last_played.hour; - time_info.tm_min = (int)runtime_log->last_played.minute; - time_info.tm_sec = (int)runtime_log->last_played.second; + time_info.tm_year = (int)runtime_log->last_played.year - 1900; + time_info.tm_mon = (int)runtime_log->last_played.month - 1; + time_info.tm_mday = (int)runtime_log->last_played.day; + time_info.tm_hour = (int)runtime_log->last_played.hour; + time_info.tm_min = (int)runtime_log->last_played.minute; + time_info.tm_sec = (int)runtime_log->last_played.second; time_info.tm_isdst = -1; /* Get time */ - *time = mktime(&time_info); + *time = mktime(&time_info); } /* Status */ @@ -648,7 +634,7 @@ bool runtime_log_has_runtime(runtime_log_t *runtime_log) if (!runtime_log) return false; - return !((runtime_log->runtime.hours == 0) && + return !((runtime_log->runtime.hours == 0) && (runtime_log->runtime.minutes == 0) && (runtime_log->runtime.seconds == 0)); } @@ -659,10 +645,10 @@ bool runtime_log_has_last_played(runtime_log_t *runtime_log) if (!runtime_log) return false; - return !((runtime_log->last_played.year == 0) && - (runtime_log->last_played.month == 0) && - (runtime_log->last_played.day == 0) && - (runtime_log->last_played.hour == 0) && + return !((runtime_log->last_played.year == 0) && + (runtime_log->last_played.month == 0) && + (runtime_log->last_played.day == 0) && + (runtime_log->last_played.hour == 0) && (runtime_log->last_played.minute == 0) && (runtime_log->last_played.second == 0)); } @@ -672,10 +658,10 @@ bool runtime_log_has_last_played(runtime_log_t *runtime_log) /* Saves specified runtime log to disk */ void runtime_log_save(runtime_log_t *runtime_log) { - RtlJSONContext context = {0}; - RFILE *file = NULL; - char value_string[64]; /* 64 characters should be enough for a very long runtime... :) */ int n; + char value_string[64]; /* 64 characters should be enough for a very long runtime... :) */ + RtlJSONContext context = {0}; + RFILE *file = NULL; if (!runtime_log) return; @@ -693,7 +679,7 @@ void runtime_log_save(runtime_log_t *runtime_log) /* Initialise JSON writer */ context.writer = JSON_Writer_Create(NULL); - context.file = file; + context.file = file; if (!context.writer) { @@ -721,7 +707,7 @@ void runtime_log_save(runtime_log_t *runtime_log) /* > Runtime entry */ value_string[0] = '\0'; - n = snprintf(value_string, sizeof(value_string), LOG_FILE_RUNTIME_FORMAT_STR, + n = snprintf(value_string, sizeof(value_string), LOG_FILE_RUNTIME_FORMAT_STR, runtime_log->runtime.hours, runtime_log->runtime.minutes, runtime_log->runtime.seconds); if ((n < 0) || (n >= 64)) n = 0; /* Silence GCC warnings... */ @@ -736,7 +722,7 @@ void runtime_log_save(runtime_log_t *runtime_log) /* > Last played entry */ value_string[0] = '\0'; - n = snprintf(value_string, sizeof(value_string), LOG_FILE_LAST_PLAYED_FORMAT_STR, + n = snprintf(value_string, sizeof(value_string), LOG_FILE_LAST_PLAYED_FORMAT_STR, runtime_log->last_played.year, runtime_log->last_played.month, runtime_log->last_played.day, runtime_log->last_played.hour, runtime_log->last_played.minute, runtime_log->last_played.second); if ((n < 0) || (n >= 64)) @@ -757,7 +743,6 @@ void runtime_log_save(runtime_log_t *runtime_log) JSON_Writer_Free(context.writer); end: - /* Close log file */ filestream_close(file); } @@ -767,9 +752,9 @@ end: /* Convert from hours, minutes, seconds to microseconds */ void runtime_log_convert_hms2usec(unsigned hours, unsigned minutes, unsigned seconds, retro_time_t *usec) { - *usec = ((retro_time_t)hours * 60 * 60 * 1000000) + - ((retro_time_t)minutes * 60 * 1000000) + - ((retro_time_t)seconds * 1000000); + *usec = ((retro_time_t)hours * 60 * 60 * 1000000) + + ((retro_time_t)minutes * 60 * 1000000) + + ((retro_time_t)seconds * 1000000); } /* Convert from microseconds to hours, minutes, seconds */ From fb306a9358c7754a731f9f680dd2a2f2dd99c6a0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 13 Apr 2019 18:49:05 +0200 Subject: [PATCH 177/237] (verbosity.c) Code formatting cleanups --- verbosity.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/verbosity.c b/verbosity.c index b6372c6d9e..6abff5463b 100644 --- a/verbosity.c +++ b/verbosity.c @@ -272,7 +272,7 @@ void RARCH_LOG_BUFFER(uint8_t *data, size_t size) RARCH_LOG("== %d-byte buffer ==================\n", (int)size); - for(i = 0, offset = 0; i < size; i++) + for (i = 0, offset = 0; i < size; i++) { buf[offset] = data[i]; offset++; @@ -285,9 +285,10 @@ void RARCH_LOG_BUFFER(uint8_t *data, size_t size) buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]); } } - if(padding) + + if (padding) { - for(i = padding; i < 16; i++) + for (i = padding; i < 16; i++) buf[i] = 0xff; RARCH_LOG("%02x%02x%02x%02x%02x%02x%02x%02x %02x%02x%02x%02x%02x%02x%02x%02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], From cee285bcd579404524092c5a743582cde9bdf42e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 13 Apr 2019 18:57:02 +0200 Subject: [PATCH 178/237] (playlist.c) Code style cleanups --- playlist.c | 93 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 40 deletions(-) diff --git a/playlist.c b/playlist.c index 24a3e305d7..663cb632a4 100644 --- a/playlist.c +++ b/playlist.c @@ -420,8 +420,9 @@ bool playlist_push_runtime(playlist_t *playlist, struct playlist_entry tmp; bool equal_path; - equal_path = (!path && !playlist->entries[i].path) || - (path && playlist->entries[i].path && + equal_path = + (!path && !playlist->entries[i].path) || + (path && playlist->entries[i].path && #ifdef _WIN32 /*prevent duplicates on case-insensitive operating systems*/ string_is_equal_noncase(path,playlist->entries[i].path) @@ -503,10 +504,10 @@ bool playlist_push(playlist_t *playlist, const struct playlist_entry *entry) { size_t i; - bool core_path_empty = string_is_empty(entry->core_path); - bool core_name_empty = string_is_empty(entry->core_name); + bool core_path_empty = string_is_empty(entry->core_path); + bool core_name_empty = string_is_empty(entry->core_name); const char *core_name = entry->core_name; - const char *path = entry->path; + const char *path = entry->path; if (core_path_empty || core_name_empty) { @@ -553,29 +554,37 @@ bool playlist_push(playlist_t *playlist, if (!string_is_equal(playlist->entries[i].core_path, entry->core_path)) continue; - if (!string_is_empty(entry->subsystem_ident) && !string_is_empty(playlist->entries[i].subsystem_ident) && !string_is_equal(playlist->entries[i].subsystem_ident, entry->subsystem_ident)) + if ( !string_is_empty(entry->subsystem_ident) + && !string_is_empty(playlist->entries[i].subsystem_ident) + && !string_is_equal(playlist->entries[i].subsystem_ident, entry->subsystem_ident)) continue; - if (string_is_empty(entry->subsystem_ident) && !string_is_empty(playlist->entries[i].subsystem_ident)) + if ( string_is_empty(entry->subsystem_ident) + && !string_is_empty(playlist->entries[i].subsystem_ident)) continue; - if (!string_is_empty(entry->subsystem_ident) && string_is_empty(playlist->entries[i].subsystem_ident)) + if ( !string_is_empty(entry->subsystem_ident) + && string_is_empty(playlist->entries[i].subsystem_ident)) continue; - if (!string_is_empty(entry->subsystem_name) && !string_is_empty(playlist->entries[i].subsystem_name) && !string_is_equal(playlist->entries[i].subsystem_name, entry->subsystem_name)) + if ( !string_is_empty(entry->subsystem_name) + && !string_is_empty(playlist->entries[i].subsystem_name) + && !string_is_equal(playlist->entries[i].subsystem_name, entry->subsystem_name)) continue; - if (string_is_empty(entry->subsystem_name) && !string_is_empty(playlist->entries[i].subsystem_name)) + if ( string_is_empty(entry->subsystem_name) + && !string_is_empty(playlist->entries[i].subsystem_name)) continue; - if (!string_is_empty(entry->subsystem_name) && string_is_empty(playlist->entries[i].subsystem_name)) + if ( !string_is_empty(entry->subsystem_name) + && string_is_empty(playlist->entries[i].subsystem_name)) continue; if (entry->subsystem_roms) { int j; const struct string_list *roms = playlist->entries[i].subsystem_roms; - bool unequal = false; + bool unequal = false; if (entry->subsystem_roms->size != roms->size) continue; @@ -640,31 +649,30 @@ bool playlist_push(playlist_t *playlist, playlist->entries[0].last_played_minute = 0; playlist->entries[0].last_played_second = 0; if (!string_is_empty(entry->path)) - playlist->entries[0].path = strdup(entry->path); + playlist->entries[0].path = strdup(entry->path); if (!string_is_empty(entry->label)) - playlist->entries[0].label = strdup(entry->label); + playlist->entries[0].label = strdup(entry->label); if (!string_is_empty(entry->core_path)) - playlist->entries[0].core_path = strdup(entry->core_path); + playlist->entries[0].core_path = strdup(entry->core_path); if (!string_is_empty(core_name)) - playlist->entries[0].core_name = strdup(core_name); + playlist->entries[0].core_name = strdup(core_name); if (!string_is_empty(entry->db_name)) - playlist->entries[0].db_name = strdup(entry->db_name); + playlist->entries[0].db_name = strdup(entry->db_name); if (!string_is_empty(entry->crc32)) - playlist->entries[0].crc32 = strdup(entry->crc32); + playlist->entries[0].crc32 = strdup(entry->crc32); if (!string_is_empty(entry->subsystem_ident)) playlist->entries[0].subsystem_ident = strdup(entry->subsystem_ident); if (!string_is_empty(entry->subsystem_name)) - playlist->entries[0].subsystem_name = strdup(entry->subsystem_name); + playlist->entries[0].subsystem_name = strdup(entry->subsystem_name); + if (entry->subsystem_roms) { union string_list_elem_attr attributes = {0}; - playlist->entries[0].subsystem_roms = string_list_new(); + playlist->entries[0].subsystem_roms = string_list_new(); for (i = 0; i < entry->subsystem_roms->size; i++) - { string_list_append(playlist->entries[0].subsystem_roms, entry->subsystem_roms->elems[i].data, attributes); - } } } @@ -688,8 +696,9 @@ static void JSONLogError(JSONContext *pCtx) { if (pCtx->parser && JSON_Parser_GetError(pCtx->parser) != JSON_Error_AbortedByHandler) { - JSON_Error error = JSON_Parser_GetError(pCtx->parser); + JSON_Error error = JSON_Parser_GetError(pCtx->parser); JSON_Location errorLocation = { 0, 0, 0 }; + (void)JSON_Parser_GetErrorLocation(pCtx->parser, &errorLocation); RARCH_WARN("Error: Invalid JSON at line %d, column %d (input byte %d) - %s.\n", (int)errorLocation.line + 1, @@ -907,7 +916,7 @@ end: void playlist_write_file(playlist_t *playlist) { size_t i; - RFILE *file = NULL; + RFILE *file = NULL; settings_t *settings = config_get_ptr(); if (!playlist || !playlist->modified) @@ -1500,7 +1509,9 @@ static bool playlist_read_file( goto end; } - /*JSON_Parser_SetTrackObjectMembers(context.parser, JSON_True);*/ +#if 0 + JSON_Parser_SetTrackObjectMembers(context.parser, JSON_True); +#endif JSON_Parser_SetAllowBOM(context.parser, JSON_True); JSON_Parser_SetAllowComments(context.parser, JSON_True); JSON_Parser_SetAllowSpecialNumbers(context.parser, JSON_True); @@ -1508,18 +1519,20 @@ static bool playlist_read_file( JSON_Parser_SetAllowUnescapedControlCharacters(context.parser, JSON_True); JSON_Parser_SetReplaceInvalidEncodingSequences(context.parser, JSON_True); - /*JSON_Parser_SetNullHandler(context.parser, &JSONNullHandler); - JSON_Parser_SetBooleanHandler(context.parser, &JSONBooleanHandler); +#if 0 + JSON_Parser_SetNullHandler(context.parser, &JSONNullHandler); + JSON_Parser_SetBooleanHandler(context.parser, &JSONBooleanHandler); JSON_Parser_SetSpecialNumberHandler(context.parser, &JSONSpecialNumberHandler); - JSON_Parser_SetArrayItemHandler(context.parser, &JSONArrayItemHandler);*/ + JSON_Parser_SetArrayItemHandler(context.parser, &JSONArrayItemHandler); +#endif - JSON_Parser_SetNumberHandler(context.parser, &JSONNumberHandler); - JSON_Parser_SetStringHandler(context.parser, &JSONStringHandler); - JSON_Parser_SetStartObjectHandler(context.parser, &JSONStartObjectHandler); - JSON_Parser_SetEndObjectHandler(context.parser, &JSONEndObjectHandler); - JSON_Parser_SetObjectMemberHandler(context.parser, &JSONObjectMemberHandler); - JSON_Parser_SetStartArrayHandler(context.parser, &JSONStartArrayHandler); - JSON_Parser_SetEndArrayHandler(context.parser, &JSONEndArrayHandler); + JSON_Parser_SetNumberHandler(context.parser, &JSONNumberHandler); + JSON_Parser_SetStringHandler(context.parser, &JSONStringHandler); + JSON_Parser_SetStartObjectHandler(context.parser, &JSONStartObjectHandler); + JSON_Parser_SetEndObjectHandler(context.parser, &JSONEndObjectHandler); + JSON_Parser_SetObjectMemberHandler(context.parser, &JSONObjectMemberHandler); + JSON_Parser_SetStartArrayHandler(context.parser, &JSONStartArrayHandler); + JSON_Parser_SetEndArrayHandler(context.parser, &JSONEndArrayHandler); JSON_Parser_SetUserData(context.parser, &context); while (!filestream_eof(file)) @@ -1681,8 +1694,8 @@ static int playlist_qsort_func(const struct playlist_entry *a, if (!a || !b) goto end; - a_str = a->label; - b_str = b->label; + a_str = a->label; + b_str = b->label; /* It is quite possible for playlist labels * to be blank. If that is the case, have to use @@ -1824,9 +1837,9 @@ void playlist_get_db_name(playlist_t *playlist, size_t idx, /* Only use file basename if this is a 'collection' playlist * (i.e. ignore history/favourites) */ - if (!string_is_empty(conf_path_basename) && - !string_is_equal(conf_path_basename, file_path_str(FILE_PATH_CONTENT_FAVORITES)) && - !string_is_equal(conf_path_basename, file_path_str(FILE_PATH_CONTENT_HISTORY)) && + if (!string_is_empty(conf_path_basename) && + !string_is_equal(conf_path_basename, file_path_str(FILE_PATH_CONTENT_FAVORITES)) && + !string_is_equal(conf_path_basename, file_path_str(FILE_PATH_CONTENT_HISTORY)) && !string_is_equal(conf_path_basename, file_path_str(FILE_PATH_CONTENT_IMAGE_HISTORY)) && !string_is_equal(conf_path_basename, file_path_str(FILE_PATH_CONTENT_MUSIC_HISTORY)) && !string_is_equal(conf_path_basename, file_path_str(FILE_PATH_CONTENT_VIDEO_HISTORY))) From 9c8c88947728a359dc9512ff42c5b2bcb6a7ccd2 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 07:01:01 +0200 Subject: [PATCH 179/237] rarch_setting - start implementing ui_type --- menu/menu_setting.c | 5 +++-- setting_list.c | 7 ++++++- setting_list.h | 23 +++++++++++++++++++++++ ui/drivers/qt/options/audio.cpp | 2 +- ui/drivers/qt/options/video.cpp | 12 +++++------- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index f4c1fc7c8b..1a9ca9bfbe 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -6241,6 +6241,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_video_rotation; @@ -6267,7 +6268,7 @@ static bool setting_append_list( START_SUB_GROUP( list, list_info, - "Synchronization", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_AUDIO_SYNC), &group_info, &subgroup_info, parent_group); @@ -6775,7 +6776,7 @@ static bool setting_append_list( START_SUB_GROUP( list, list_info, - "Synchronization", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_AUDIO_SYNC), &group_info, &subgroup_info, parent_group); diff --git a/setting_list.c b/setting_list.c index f32319db18..78f5bcc421 100644 --- a/setting_list.c +++ b/setting_list.c @@ -1798,7 +1798,8 @@ bool CONFIG_BOOL( if (!settings_list_append(list, list_info)) return false; - (*list)[list_info->index++] = value; + (*list)[list_info->index++] = value; + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_CHECKBOX; if (flags != SD_FLAG_NONE) settings_data_list_current_add_flags(list, list_info, flags); @@ -1859,6 +1860,7 @@ bool CONFIG_UINT_ALT( if (!(settings_list_append(list, list_info))) return false; (*list)[list_info->index++] = value; + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_SPINBOX; return true; } @@ -1885,6 +1887,7 @@ bool CONFIG_UINT( if (!(settings_list_append(list, list_info))) return false; (*list)[list_info->index++] = value; + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_SPINBOX; #ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); @@ -1977,6 +1980,7 @@ bool CONFIG_PATH( if (!(settings_list_append(list, list_info))) return false; (*list)[list_info->index++] = value; + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_FILE_SELECTOR; settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_EMPTY); #ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); @@ -2071,6 +2075,7 @@ bool CONFIG_STRING_OPTIONS( return false; (*list)[list_info->index++] = value; + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_COMBOBOX; #ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); diff --git a/setting_list.h b/setting_list.h index 0045f88881..334312c361 100644 --- a/setting_list.h +++ b/setting_list.h @@ -46,6 +46,28 @@ enum setting_type ST_END_SUB_GROUP }; +enum ui_setting_type +{ + ST_UI_TYPE_NONE = 0, + ST_UI_TYPE_CHECKBOX, + ST_UI_TYPE_UINT_COLOR_BUTTON, + ST_UI_TYPE_UINT_SPINBOX, + ST_UI_TYPE_UINT_COMBOBOX, + ST_UI_TYPE_UINT_RADIO_BUTTONS, + ST_UI_TYPE_FLOAT_COLOR_BUTTON, + ST_UI_TYPE_FLOAT_SPINBOX, + ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX, + ST_UI_TYPE_SIZE_SPINBOX, + ST_UI_TYPE_BIND_BUTTON, + ST_UI_TYPE_DIRECTORY_SELECTOR, + ST_UI_TYPE_FILE_SELECTOR, + ST_UI_TYPE_FONT_SELECTOR, + ST_UI_TYPE_STRING_COMBOBOX, + ST_UI_TYPE_STRING_LINE_EDIT, + ST_UI_TYPE_PASSWORD_LINE_EDIT, + ST_UI_TYPE_LAST +}; + enum setting_flags { SD_FLAG_NONE = 0, @@ -91,6 +113,7 @@ struct rarch_setting_group_info struct rarch_setting { + enum ui_setting_type ui_type; enum setting_type browser_selection_type; enum msg_hash_enums enum_idx; enum msg_hash_enums enum_value_idx; diff --git a/ui/drivers/qt/options/audio.cpp b/ui/drivers/qt/options/audio.cpp index 0ba87ed664..1be8a37f0c 100644 --- a/ui/drivers/qt/options/audio.cpp +++ b/ui/drivers/qt/options/audio.cpp @@ -32,7 +32,7 @@ QWidget *AudioPage::widget() SettingsGroup *outputGroup = new SettingsGroup("Output"); SettingsGroup *resamplerGroup = new SettingsGroup("Resampler"); - SettingsGroup *syncGroup = new SettingsGroup("Synchronization"); + SettingsGroup *syncGroup = new SettingsGroup(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_AUDIO_SYNC)); SettingsGroup *dspGroup = new SettingsGroup("DSP plugin"); SettingsGroup *volumeGroup = new SettingsGroup("Volume"); diff --git a/ui/drivers/qt/options/video.cpp b/ui/drivers/qt/options/video.cpp index c564241c93..68f03ff702 100644 --- a/ui/drivers/qt/options/video.cpp +++ b/ui/drivers/qt/options/video.cpp @@ -130,7 +130,7 @@ QWidget *VideoPage::widget() { CheckableSettingsGroup *hardSyncGroup = new CheckableSettingsGroup(hardSyncSetting); - hardSyncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES); + hardSyncGroup->addUIntSpinBox(hardSyncSetting->enum_idx); syncGroup->addRow(hardSyncGroup); } @@ -238,9 +238,7 @@ void AspectRatioGroup::paintEvent(QPaintEvent *event) m_radioButton->setChecked(true); } else - { m_comboBox->blockSignals(true); - } SettingsGroup::paintEvent(event); } @@ -293,10 +291,10 @@ QWidget *CrtSwitchresPage::widget() void VideoPage::onResolutionComboIndexChanged(const QString &text) { char str[100]; - char *pch = NULL; - const char *path = text.toUtf8().constData(); - unsigned width = 0; - unsigned height = 0; + char *pch = NULL; + const char *path = text.toUtf8().constData(); + unsigned width = 0; + unsigned height = 0; unsigned refreshrate = 0; snprintf(str, sizeof(str), "%s", path); From e840a6c95a50564711d52a006309b6973970030c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 07:08:35 +0200 Subject: [PATCH 180/237] Cut down on some code duplication --- menu/cbs/menu_cbs_ok.c | 20 ++++++++++++++++++-- menu/menu_cbs.h | 2 ++ ui/drivers/qt/options/video.cpp | 30 ++---------------------------- 3 files changed, 22 insertions(+), 30 deletions(-) diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index e64767d82d..90fa4e0214 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -4956,7 +4956,7 @@ static int action_ok_push_dropdown_item(const char *path, return 0; } -static int action_ok_push_dropdown_item_resolution(const char *path, +int action_cb_push_dropdown_item_resolution(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { char str[100]; @@ -4965,6 +4965,11 @@ static int action_ok_push_dropdown_item_resolution(const char *path, unsigned height = 0; unsigned refreshrate = 0; + (void)label; + (void)type; + (void)idx; + (void)entry_idx; + snprintf(str, sizeof(str), "%s", path); pch = strtok(str, "x"); @@ -4987,11 +4992,22 @@ static int action_ok_push_dropdown_item_resolution(const char *path, settings->uints.video_fullscreen_x = width; settings->uints.video_fullscreen_y = height; + return 1; + } + + return 0; +} + +static int action_ok_push_dropdown_item_resolution(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + if (action_cb_push_dropdown_item_resolution(path, + label, type, idx, entry_idx) == 1) + { /* TODO/FIXME - menu drivers like XMB don't rescale * automatically */ return menu_cbs_exit(); } - return 0; } diff --git a/menu/menu_cbs.h b/menu/menu_cbs.h index e1f61c5e2b..5845b8b157 100644 --- a/menu/menu_cbs.h +++ b/menu/menu_cbs.h @@ -149,6 +149,8 @@ enum }; /* Function callbacks */ +int action_cb_push_dropdown_item_resolution(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx); int action_cancel_pop_default(const char *path, const char *label, unsigned type, size_t idx); diff --git a/ui/drivers/qt/options/video.cpp b/ui/drivers/qt/options/video.cpp index 68f03ff702..77752d00cc 100644 --- a/ui/drivers/qt/options/video.cpp +++ b/ui/drivers/qt/options/video.cpp @@ -290,35 +290,9 @@ QWidget *CrtSwitchresPage::widget() void VideoPage::onResolutionComboIndexChanged(const QString &text) { - char str[100]; - char *pch = NULL; const char *path = text.toUtf8().constData(); - unsigned width = 0; - unsigned height = 0; - unsigned refreshrate = 0; - - snprintf(str, sizeof(str), "%s", path); - - pch = strtok(str, "x"); - if (pch) - width = strtoul(pch, NULL, 0); - pch = strtok(NULL, " "); - if (pch) - height = strtoul(pch, NULL, 0); - pch = strtok(NULL, "("); - if (pch) - refreshrate = strtoul(pch, NULL, 0); - - if (video_display_server_set_resolution(width, height, - refreshrate, (float)refreshrate, 0, 0, 0)) - { - settings_t *settings = config_get_ptr(); - - video_monitor_set_refresh_rate((float)refreshrate); - - settings->uints.video_fullscreen_x = width; - settings->uints.video_fullscreen_y = height; - } + action_cb_push_dropdown_item_resolution(path, + NULL, 0, 0, 0); } void CrtSwitchresPage::onCrtSuperResolutionComboIndexChanged(int index) From 0cb94aef85a7b2e1299e0c9aebee3277a7675065 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 08:13:54 +0200 Subject: [PATCH 181/237] (Qt) Slight code formatting cleanups --- ui/drivers/qt/options/network.cpp | 62 +++++++++++++++++-------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/ui/drivers/qt/options/network.cpp b/ui/drivers/qt/options/network.cpp index 4d60da0790..ccad6be695 100644 --- a/ui/drivers/qt/options/network.cpp +++ b/ui/drivers/qt/options/network.cpp @@ -39,21 +39,21 @@ NetplayPage::NetplayPage(QObject *parent) : QWidget *NetplayPage::widget() { - QWidget *widget = new QWidget; - QGridLayout *layout = new QGridLayout; - FormLayout *checksLayout = new FormLayout; - QGroupBox *serverGroup = new QGroupBox("Server"); - SettingsGroup *syncGroup = new SettingsGroup("Synchronization"); - SettingsGroup *slaveGroup = new SettingsGroup("Slave-Mode"); - SettingsGroup *inputGroup = new SettingsGroup("Input Sharing"); + QWidget *widget = new QWidget; + QGridLayout *layout = new QGridLayout; + FormLayout *checksLayout = new FormLayout; + QGroupBox *serverGroup = new QGroupBox("Server"); + SettingsGroup *syncGroup = new SettingsGroup("Synchronization"); + SettingsGroup *slaveGroup = new SettingsGroup("Slave-Mode"); + SettingsGroup *inputGroup = new SettingsGroup("Input Sharing"); SettingsGroup *deviceGroup = new SettingsGroup("Device Request"); - FormLayout *serverForm = new FormLayout; - QHBoxLayout *serverLayout = new QHBoxLayout; - QVBoxLayout *mainLayout = new QVBoxLayout; - QGridLayout *requestGrid = new QGridLayout; - unsigned i = 0; - unsigned row = 0; - unsigned column = 0; + FormLayout *serverForm = new FormLayout; + QHBoxLayout *serverLayout = new QHBoxLayout; + QVBoxLayout *mainLayout = new QVBoxLayout; + QGridLayout *requestGrid = new QGridLayout; + unsigned i = 0; + unsigned row = 0; + unsigned column = 0; checksLayout->addCheckBox(MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE); checksLayout->addCheckBox(MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR); @@ -112,42 +112,48 @@ QWidget *NetplayPage::widget() QGroupBox *NetplayPage::createMitmServerGroup() { - CheckableSettingsGroup *groupBox = new CheckableSettingsGroup(MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER); - QButtonGroup *buttonGroup = new QButtonGroup(this); - - rarch_setting_t *setting = menu_setting_find_enum(MENU_ENUM_LABEL_NETPLAY_MITM_SERVER); - unsigned i; - unsigned list_len = ARRAY_SIZE(netplay_mitm_server_list); + CheckableSettingsGroup *groupBox = new CheckableSettingsGroup( + MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER); + QButtonGroup *buttonGroup = new QButtonGroup(this); + unsigned list_len = ARRAY_SIZE(netplay_mitm_server_list); + rarch_setting_t *setting = menu_setting_find_enum( + MENU_ENUM_LABEL_NETPLAY_MITM_SERVER); if (!setting) return nullptr; for (i = 0; i < list_len; i++) { - QRadioButton *radioButton = new QRadioButton(netplay_mitm_server_list[i].description); + QRadioButton *radioButton = new QRadioButton( + netplay_mitm_server_list[i].description); /* find the currently selected server in the list */ - if (string_is_equal(setting->value.target.string, netplay_mitm_server_list[i].name)) - { + if (string_is_equal(setting->value.target.string, + netplay_mitm_server_list[i].name)) radioButton->setChecked(true); - } buttonGroup->addButton(radioButton, i); groupBox->addRow(radioButton); } - connect(buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(onRadioButtonClicked(int))); + connect(buttonGroup, SIGNAL(buttonClicked(int)), + this, SLOT(onRadioButtonClicked(int))); return groupBox; } void NetplayPage::onRadioButtonClicked(int id) { - rarch_setting_t *setting = menu_setting_find_enum(MENU_ENUM_LABEL_NETPLAY_MITM_SERVER); + rarch_setting_t *setting = + menu_setting_find_enum(MENU_ENUM_LABEL_NETPLAY_MITM_SERVER); - strlcpy(setting->value.target.string, netplay_mitm_server_list[id].name, setting->size); + if (!setting) + return; + + strlcpy(setting->value.target.string, + netplay_mitm_server_list[id].name, setting->size); } UpdaterPage::UpdaterPage(QObject *parent) : @@ -158,7 +164,7 @@ UpdaterPage::UpdaterPage(QObject *parent) : QWidget *UpdaterPage::widget() { - QWidget *widget = new QWidget; + QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; layout->addStringLineEdit(MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL); From 95f77a228818ebf8c575f8e2d4ca2b06d398b983 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 17:10:13 +0200 Subject: [PATCH 182/237] (UI/QT) Create 'add' function for SettingsGroup and LayoutForm --- menu/menu_setting.c | 11 ++- setting_list.c | 1 + ui/drivers/qt/options/audio.cpp | 44 +++++----- ui/drivers/qt/options/input.cpp | 83 +++++++++--------- ui/drivers/qt/options/logging.cpp | 9 +- ui/drivers/qt/options/video.cpp | 28 +++--- ui/drivers/qt/settingswidgets.h | 137 ++++++++++++++++++++++++++++++ 7 files changed, 226 insertions(+), 87 deletions(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 1a9ca9bfbe..15757e38b7 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -4955,6 +4955,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_RADIO_BUTTONS; (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; menu_settings_list_current_add_range(list, list_info, 0, 3, 1.0, true, true); (*list)[list_info->index - 1].get_string_representation = @@ -6532,6 +6533,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_crt_switch_resolutions; @@ -6566,6 +6568,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_SPINBOX; (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; (*list)[list_info->index - 1].offset_by = -3; settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); @@ -6825,6 +6828,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_audio_resampler_quality; @@ -6916,6 +6920,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; (*list)[list_info->index - 1].action_left = &setting_string_action_left_audio_device; (*list)[list_info->index - 1].action_right = &setting_string_action_right_audio_device; #endif @@ -7112,6 +7117,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_poll_type_behavior; @@ -7213,6 +7219,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_toggle_gamepad_combo; @@ -7457,6 +7464,7 @@ static bool setting_append_list( &group_info, &subgroup_info, parent_group); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_BIND_BUTTON; (*list)[list_info->index - 1].index = user_value; (*list)[list_info->index - 1].index_offset = user; @@ -7693,7 +7701,8 @@ static bool setting_append_list( strdup(input_config_bind_map_get_desc(i)), &retro_keybinds_1[i], &group_info, &subgroup_info, parent_group); - (*list)[list_info->index - 1].bind_type = i + MENU_SETTINGS_BIND_BEGIN; + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_BIND_BUTTON; + (*list)[list_info->index - 1].bind_type = i + MENU_SETTINGS_BIND_BEGIN; menu_settings_list_current_add_enum_idx(list, list_info, (enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i)); } diff --git a/setting_list.c b/setting_list.c index 78f5bcc421..6bb523e166 100644 --- a/setting_list.c +++ b/setting_list.c @@ -1949,6 +1949,7 @@ bool CONFIG_FLOAT( if (!(settings_list_append(list, list_info))) return false; (*list)[list_info->index++] = value; + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX; #ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); diff --git a/ui/drivers/qt/options/audio.cpp b/ui/drivers/qt/options/audio.cpp index 1be8a37f0c..8f673a31d9 100644 --- a/ui/drivers/qt/options/audio.cpp +++ b/ui/drivers/qt/options/audio.cpp @@ -26,28 +26,26 @@ AudioPage::AudioPage(QObject *parent) : QWidget *AudioPage::widget() { - QWidget *widget = new QWidget; - - QVBoxLayout *layout = new QVBoxLayout; - - SettingsGroup *outputGroup = new SettingsGroup("Output"); + QWidget *widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; + SettingsGroup *outputGroup = new SettingsGroup("Output"); SettingsGroup *resamplerGroup = new SettingsGroup("Resampler"); - SettingsGroup *syncGroup = new SettingsGroup(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_AUDIO_SYNC)); - SettingsGroup *dspGroup = new SettingsGroup("DSP plugin"); - SettingsGroup *volumeGroup = new SettingsGroup("Volume"); + SettingsGroup *syncGroup = new SettingsGroup(msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_AUDIO_SYNC)); + SettingsGroup *dspGroup = new SettingsGroup("DSP plugin"); + SettingsGroup *volumeGroup = new SettingsGroup("Volume"); + QHBoxLayout *volumeLayout = new QHBoxLayout(); - QHBoxLayout *volumeLayout = new QHBoxLayout(); + outputGroup->add(MENU_ENUM_LABEL_AUDIO_ENABLE); + outputGroup->add(MENU_ENUM_LABEL_AUDIO_DRIVER); + outputGroup->add(MENU_ENUM_LABEL_AUDIO_DEVICE); + outputGroup->add(MENU_ENUM_LABEL_AUDIO_LATENCY); - outputGroup->addCheckBox(MENU_ENUM_LABEL_AUDIO_ENABLE); - outputGroup->addStringComboBox(MENU_ENUM_LABEL_AUDIO_DRIVER); - outputGroup->addStringLineEdit(MENU_ENUM_LABEL_AUDIO_DEVICE); - outputGroup->addUIntSpinBox(MENU_ENUM_LABEL_AUDIO_LATENCY); + resamplerGroup->add(MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER); + resamplerGroup->add(MENU_ENUM_LABEL_AUDIO_RESAMPLER_QUALITY); + resamplerGroup->add(MENU_ENUM_LABEL_AUDIO_OUTPUT_RATE); - resamplerGroup->addStringComboBox(MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER); - resamplerGroup->addUIntComboBox(MENU_ENUM_LABEL_AUDIO_RESAMPLER_QUALITY); - resamplerGroup->addUIntSpinBox(MENU_ENUM_LABEL_AUDIO_OUTPUT_RATE); - - syncGroup->addCheckBox(MENU_ENUM_LABEL_AUDIO_SYNC); + syncGroup->add(MENU_ENUM_LABEL_AUDIO_SYNC); syncGroup->addFloatSpinBox(MENU_ENUM_LABEL_AUDIO_MAX_TIMING_SKEW); syncGroup->addFloatSpinBox(MENU_ENUM_LABEL_AUDIO_RATE_CONTROL_DELTA); @@ -82,11 +80,11 @@ QWidget *MenuSoundsPage::widget() FormLayout *layout = new FormLayout; - layout->addCheckBox(MENU_ENUM_LABEL_AUDIO_ENABLE_MENU); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_SOUND_OK); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_SOUND_CANCEL); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_SOUND_NOTICE); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_SOUND_BGM); + layout->add(MENU_ENUM_LABEL_AUDIO_ENABLE_MENU); + layout->add(MENU_ENUM_LABEL_MENU_SOUND_OK); + layout->add(MENU_ENUM_LABEL_MENU_SOUND_CANCEL); + layout->add(MENU_ENUM_LABEL_MENU_SOUND_NOTICE); + layout->add(MENU_ENUM_LABEL_MENU_SOUND_BGM); widget->setLayout(layout); diff --git a/ui/drivers/qt/options/input.cpp b/ui/drivers/qt/options/input.cpp index 54fa5ccca3..43bc71ddc8 100644 --- a/ui/drivers/qt/options/input.cpp +++ b/ui/drivers/qt/options/input.cpp @@ -36,25 +36,24 @@ InputPage::InputPage(QObject *parent) : QWidget *InputPage::widget() { - QWidget *widget = new QWidget; - + QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; - layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_MAX_USERS); - layout->addCheckBox(MENU_ENUM_LABEL_INPUT_UNIFIED_MENU_CONTROLS); - layout->addUIntComboBox(MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR); - layout->addUIntComboBox(MENU_ENUM_LABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_INPUT_SWAP_OK_CANCEL); - layout->addCheckBox(MENU_ENUM_LABEL_INPUT_ALL_USERS_CONTROL_MENU); - layout->addCheckBox(MENU_ENUM_LABEL_INPUT_REMAP_BINDS_ENABLE); - layout->addCheckBox(MENU_ENUM_LABEL_INPUT_AUTODETECT_ENABLE); - layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_INPUT_BUTTON_AXIS_THRESHOLD); - layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_INPUT_ANALOG_DEADZONE); - layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_INPUT_ANALOG_SENSITIVITY); - layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_BIND_TIMEOUT); - layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_BIND_HOLD); - layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_TURBO_PERIOD); - layout->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_DUTY_CYCLE); + layout->add(MENU_ENUM_LABEL_INPUT_MAX_USERS); + layout->add(MENU_ENUM_LABEL_INPUT_UNIFIED_MENU_CONTROLS); + layout->add(MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR); + layout->add(MENU_ENUM_LABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO); + layout->add(MENU_ENUM_LABEL_MENU_INPUT_SWAP_OK_CANCEL); + layout->add(MENU_ENUM_LABEL_INPUT_ALL_USERS_CONTROL_MENU); + layout->add(MENU_ENUM_LABEL_INPUT_REMAP_BINDS_ENABLE); + layout->add(MENU_ENUM_LABEL_INPUT_AUTODETECT_ENABLE); + layout->add(MENU_ENUM_LABEL_INPUT_BUTTON_AXIS_THRESHOLD); + layout->add(MENU_ENUM_LABEL_INPUT_ANALOG_DEADZONE); + layout->add(MENU_ENUM_LABEL_INPUT_ANALOG_SENSITIVITY); + layout->add(MENU_ENUM_LABEL_INPUT_BIND_TIMEOUT); + layout->add(MENU_ENUM_LABEL_INPUT_BIND_HOLD); + layout->add(MENU_ENUM_LABEL_INPUT_TURBO_PERIOD); + layout->add(MENU_ENUM_LABEL_INPUT_DUTY_CYCLE); widget->setLayout(layout); @@ -69,25 +68,25 @@ HotkeyBindsPage::HotkeyBindsPage(QObject *parent) : QWidget *HotkeyBindsPage::widget() { - QWidget *widget = new QWidget; - - QHBoxLayout *layout = new QHBoxLayout; - FormLayout *leftLayout = new FormLayout; - FormLayout *rightLayout = new FormLayout; - unsigned i; - unsigned count = 0; - unsigned half = 40 / 2; /* TODO unhardcode */ + unsigned count = 0; + unsigned half = 40 / 2; /* TODO unhardcode */ + QWidget *widget = new QWidget; + QHBoxLayout *layout = new QHBoxLayout; + FormLayout *leftLayout = new FormLayout; + FormLayout *rightLayout = new FormLayout; for (i = 0; i < RARCH_BIND_LIST_END; i++) { + enum msg_hash_enums lbl = (enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i); + if (count < half) { - if (leftLayout->addBindButton((enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i))) + if (leftLayout->add(lbl)) count++; } else - rightLayout->addBindButton((enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i)); + rightLayout->add(lbl); } layout->addLayout(leftLayout); @@ -107,15 +106,12 @@ UserBindsPage::UserBindsPage(QObject *parent) : QWidget *UserBindsPage::widget() { - QWidget *widget = new QWidget; - - QGridLayout *layout = new QGridLayout; - - unsigned count = 0; unsigned p, retro_id; - unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); - - QComboBox *userCombo = new QComboBox; + unsigned count = 0; + unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); + QWidget *widget = new QWidget; + QGridLayout *layout = new QGridLayout; + QComboBox *userCombo = new QComboBox; QStackedWidget *stack = new QStackedWidget; for (p = 0; p < max_users; p++) @@ -128,12 +124,10 @@ QWidget *UserBindsPage::widget() for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND + 20; retro_id++) { char descriptor[300]; - const struct retro_keybind *auto_bind = NULL; - const struct retro_keybind *keybind = NULL; - - keybind = &input_config_binds[p][retro_id]; - - auto_bind = (const struct retro_keybind*) + const struct retro_keybind *keybind = + &input_config_binds[p][retro_id]; + const struct retro_keybind *auto_bind = + (const struct retro_keybind*) input_config_get_bind_auto(p, retro_id); input_config_get_bind_string(descriptor, @@ -144,14 +138,17 @@ QWidget *UserBindsPage::widget() QString label = msg_hash_to_str(keyptr->enum_idx); - form->addRow(QString(msg_hash_to_str(keyptr->enum_idx)), new QPushButton(QString(descriptor))); + form->addRow(QString(msg_hash_to_str(keyptr->enum_idx)), + new QPushButton(QString(descriptor))); } + uWidget->setLayout(form); stack->addWidget(uWidget); } - connect(userCombo, SIGNAL(activated(int)), stack, SLOT(setCurrentIndex(int))); + connect(userCombo, SIGNAL(activated(int)), + stack, SLOT(setCurrentIndex(int))); layout->addWidget(userCombo, 0, 0); layout->addWidget(stack, 1, 0); diff --git a/ui/drivers/qt/options/logging.cpp b/ui/drivers/qt/options/logging.cpp index 734bb480b6..b122ecd4f6 100644 --- a/ui/drivers/qt/options/logging.cpp +++ b/ui/drivers/qt/options/logging.cpp @@ -23,13 +23,12 @@ LoggingPage::LoggingPage(QObject *parent) : QWidget *LoggingPage::widget() { - QWidget *widget = new QWidget; - + QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; - layout->addCheckBox(MENU_ENUM_LABEL_LOG_VERBOSITY); - layout->addUIntRadioButtons(MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL); - layout->addCheckBox(MENU_ENUM_LABEL_PERFCNT_ENABLE); + layout->add(MENU_ENUM_LABEL_LOG_VERBOSITY); + layout->add(MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL); + layout->add(MENU_ENUM_LABEL_PERFCNT_ENABLE); widget->setLayout(layout); diff --git a/ui/drivers/qt/options/video.cpp b/ui/drivers/qt/options/video.cpp index 77752d00cc..b962a8e97c 100644 --- a/ui/drivers/qt/options/video.cpp +++ b/ui/drivers/qt/options/video.cpp @@ -175,17 +175,16 @@ AspectRatioGroup::AspectRatioGroup(const QString &title, QWidget *parent) : ,m_radioButton(new AspectRatioRadioButton(ASPECT_RATIO_4_3, ASPECT_RATIO_32_9)) ,m_comboBox(new UIntComboBox(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, ASPECT_RATIO_4_3, ASPECT_RATIO_32_9)) { - QHBoxLayout *aspectLayout = new QHBoxLayout; - FormLayout *leftAspectForm = new FormLayout; + QHBoxLayout *aspectLayout = new QHBoxLayout; + QHBoxLayout *preset = new QHBoxLayout; + QHBoxLayout *custom = new QHBoxLayout; + QVBoxLayout *customRadio = new QVBoxLayout; + QHBoxLayout *config = new QHBoxLayout; + QHBoxLayout *aspectL = new QHBoxLayout; + FormLayout *leftAspectForm = new FormLayout; FormLayout *rightAspectForm = new FormLayout; - QHBoxLayout *preset = new QHBoxLayout; - //AspectRatioRadioButton *aspectRadioButton = new AspectRatioRadioButton(ASPECT_RATIO_4_3, ASPECT_RATIO_32_9); - QHBoxLayout *custom = new QHBoxLayout; - QVBoxLayout *customRadio = new QVBoxLayout; - QHBoxLayout *config = new QHBoxLayout; - QHBoxLayout *aspectL = new QHBoxLayout; - FormLayout *leftAspect = new FormLayout; - FormLayout *rightAspect = new FormLayout; + FormLayout *leftAspect = new FormLayout; + FormLayout *rightAspect = new FormLayout; leftAspectForm->addRow("X Pos.:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_X)); leftAspectForm->addRow("Width:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH)); @@ -267,8 +266,7 @@ CrtSwitchresPage::CrtSwitchresPage(QObject *parent) : QWidget *CrtSwitchresPage::widget() { - QWidget *widget = new QWidget; - + QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; m_crtSuperResolutionCombo->addItem(msg_hash_to_str(MSG_NATIVE), 0); @@ -276,10 +274,10 @@ QWidget *CrtSwitchresPage::widget() m_crtSuperResolutionCombo->addItem("2560", 2560); m_crtSuperResolutionCombo->addItem("3840", 3840); - layout->addUIntComboBox(MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION); + layout->add(MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION); layout->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER), m_crtSuperResolutionCombo); - layout->addUIntSpinBox(MENU_ENUM_LABEL_CRT_SWITCH_X_AXIS_CENTERING); - layout->addCheckBox(MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_USE_CUSTOM_REFRESH_RATE); + layout->add(MENU_ENUM_LABEL_CRT_SWITCH_X_AXIS_CENTERING); + layout->add(MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_USE_CUSTOM_REFRESH_RATE); connect(m_crtSuperResolutionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onCrtSuperResolutionComboIndexChanged(int))); diff --git a/ui/drivers/qt/settingswidgets.h b/ui/drivers/qt/settingswidgets.h index cf2adaaced..563e113ee5 100644 --- a/ui/drivers/qt/settingswidgets.h +++ b/ui/drivers/qt/settingswidgets.h @@ -49,6 +49,73 @@ public: void addFloatSliderAndSpinBox(msg_hash_enums enum_idx); void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b); bool addBindButton(msg_hash_enums enum_idx); + + bool add(msg_hash_enums enum_idx) + { + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + enum ui_setting_type ui_type = ST_UI_TYPE_NONE; + + if (!setting) + return false; + + ui_type = setting->ui_type; + + switch (ui_type) + { + case ST_UI_TYPE_CHECKBOX: + this->addCheckBox(enum_idx); + break; + case ST_UI_TYPE_UINT_COLOR_BUTTON: + /* TODO/FIXME */ + break; + case ST_UI_TYPE_UINT_SPINBOX: + this->addUIntSpinBox(enum_idx); + break; + case ST_UI_TYPE_UINT_COMBOBOX: + this->addUIntComboBox(enum_idx); + break; + case ST_UI_TYPE_UINT_RADIO_BUTTONS: + this->addUIntRadioButtons(enum_idx); + break; + case ST_UI_TYPE_FLOAT_COLOR_BUTTON: + /* TODO/FIXME */ + break; + case ST_UI_TYPE_FLOAT_SPINBOX: + this->addFloatSpinBox(enum_idx); + break; + case ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX: + this->addFloatSliderAndSpinBox(enum_idx); + break; + case ST_UI_TYPE_SIZE_SPINBOX: + /* TODO/FIXME */ + break; + case ST_UI_TYPE_BIND_BUTTON: + return this->addBindButton(enum_idx); + case ST_UI_TYPE_DIRECTORY_SELECTOR: + this->addDirectorySelector(enum_idx); + break; + case ST_UI_TYPE_FILE_SELECTOR: + this->addFileSelector(enum_idx); + break; + case ST_UI_TYPE_FONT_SELECTOR: + this->addFontSelector(enum_idx); + break; + case ST_UI_TYPE_STRING_COMBOBOX: + this->addStringComboBox(enum_idx); + break; + case ST_UI_TYPE_STRING_LINE_EDIT: + this->addStringLineEdit(enum_idx); + break; + case ST_UI_TYPE_PASSWORD_LINE_EDIT: + this->addPasswordLineEdit(enum_idx); + break; + case ST_UI_TYPE_NONE: + default: + break; + } + + return true; + } }; class SettingsGroup : public QGroupBox @@ -76,6 +143,76 @@ public: void addFloatSliderAndSpinBox(msg_hash_enums enum_idx); void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b); void addBindButton(msg_hash_enums enum_idx); + + bool add(msg_hash_enums enum_idx) + { + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + enum ui_setting_type ui_type = ST_UI_TYPE_NONE; + + if (!setting) + return false; + + ui_type = setting->ui_type; + + switch (ui_type) + { + case ST_UI_TYPE_CHECKBOX: + this->addCheckBox(enum_idx); + break; + case ST_UI_TYPE_UINT_COLOR_BUTTON: + /* TODO/FIXME */ + break; + case ST_UI_TYPE_UINT_SPINBOX: + this->addUIntSpinBox(enum_idx); + break; + case ST_UI_TYPE_UINT_COMBOBOX: + this->addUIntComboBox(enum_idx); + break; + case ST_UI_TYPE_UINT_RADIO_BUTTONS: + this->addUIntRadioButtons(enum_idx); + break; + case ST_UI_TYPE_FLOAT_COLOR_BUTTON: + /* TODO/FIXME */ + break; + case ST_UI_TYPE_FLOAT_SPINBOX: + this->addFloatSpinBox(enum_idx); + break; + case ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX: + this->addFloatSliderAndSpinBox(enum_idx); + break; + case ST_UI_TYPE_SIZE_SPINBOX: + /* TODO/FIXME */ + break; + case ST_UI_TYPE_BIND_BUTTON: + /* TODO/FIXME - Why is the returntype void here and bool + * for Layout? */ + this->addBindButton(enum_idx); + break; + case ST_UI_TYPE_DIRECTORY_SELECTOR: + this->addDirectorySelector(enum_idx); + break; + case ST_UI_TYPE_FILE_SELECTOR: + this->addFileSelector(enum_idx); + break; + case ST_UI_TYPE_FONT_SELECTOR: + this->addFontSelector(enum_idx); + break; + case ST_UI_TYPE_STRING_COMBOBOX: + this->addStringComboBox(enum_idx); + break; + case ST_UI_TYPE_STRING_LINE_EDIT: + this->addStringLineEdit(enum_idx); + break; + case ST_UI_TYPE_PASSWORD_LINE_EDIT: + this->addPasswordLineEdit(enum_idx); + break; + case ST_UI_TYPE_NONE: + default: + break; + } + + return true; + } private: FormLayout *m_layout; }; From 82e38ca2ee1aa8db675f5672bec37a4bb80cdeda Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 17:13:04 +0200 Subject: [PATCH 183/237] (UI/QT) Dehardcode some more settings --- ui/drivers/qt/options/audio.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/drivers/qt/options/audio.cpp b/ui/drivers/qt/options/audio.cpp index 8f673a31d9..766855fa7b 100644 --- a/ui/drivers/qt/options/audio.cpp +++ b/ui/drivers/qt/options/audio.cpp @@ -46,10 +46,10 @@ QWidget *AudioPage::widget() resamplerGroup->add(MENU_ENUM_LABEL_AUDIO_OUTPUT_RATE); syncGroup->add(MENU_ENUM_LABEL_AUDIO_SYNC); - syncGroup->addFloatSpinBox(MENU_ENUM_LABEL_AUDIO_MAX_TIMING_SKEW); - syncGroup->addFloatSpinBox(MENU_ENUM_LABEL_AUDIO_RATE_CONTROL_DELTA); + syncGroup->add(MENU_ENUM_LABEL_AUDIO_MAX_TIMING_SKEW); + syncGroup->add(MENU_ENUM_LABEL_AUDIO_RATE_CONTROL_DELTA); - dspGroup->addFileSelector(MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN); + dspGroup->add(MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN); volumeLayout->addWidget(new CheckableIcon(MENU_ENUM_LABEL_AUDIO_MUTE, qApp->style()->standardIcon(QStyle::SP_MediaVolumeMuted))); volumeLayout->addLayout(new FloatSliderAndSpinBox(MENU_ENUM_LABEL_AUDIO_VOLUME)); From 338ce7e678fa8420db07cf93065808c2053aa6e9 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 17:26:14 +0200 Subject: [PATCH 184/237] (UI/QT) Dehardcode some more additions --- setting_list.c | 1 + ui/drivers/qt/options/configuration.cpp | 11 +++--- ui/drivers/qt/options/core.cpp | 11 +++--- ui/drivers/qt/options/directory.cpp | 51 ++++++++++++------------- ui/drivers/qt/options/drivers.cpp | 23 ++++++----- 5 files changed, 47 insertions(+), 50 deletions(-) diff --git a/setting_list.c b/setting_list.c index 6bb523e166..49c57e1847 100644 --- a/setting_list.c +++ b/setting_list.c @@ -2014,6 +2014,7 @@ bool CONFIG_DIR( if (!(settings_list_append(list, list_info))) return false; (*list)[list_info->index++] = value; + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_DIRECTORY_SELECTOR; settings_data_list_current_add_flags( list, list_info, diff --git a/ui/drivers/qt/options/configuration.cpp b/ui/drivers/qt/options/configuration.cpp index 017bb97cb5..30f9548879 100644 --- a/ui/drivers/qt/options/configuration.cpp +++ b/ui/drivers/qt/options/configuration.cpp @@ -23,14 +23,13 @@ ConfigurationPage::ConfigurationPage(QObject *parent) : QWidget *ConfigurationPage::widget() { - QWidget *widget = new QWidget; - + QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; - layout->addCheckBox(MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT); - layout->addCheckBox(MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS); - layout->addCheckBox(MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE); - layout->addCheckBox(MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE); + layout->add(MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT); + layout->add(MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS); + layout->add(MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE); + layout->add(MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE); widget->setLayout(layout); diff --git a/ui/drivers/qt/options/core.cpp b/ui/drivers/qt/options/core.cpp index 755ffced3a..90a6996c23 100644 --- a/ui/drivers/qt/options/core.cpp +++ b/ui/drivers/qt/options/core.cpp @@ -23,14 +23,13 @@ CorePage::CorePage(QObject *parent) : QWidget *CorePage::widget() { - QWidget *widget = new QWidget; - + QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; - layout->addCheckBox(MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT); - layout->addCheckBox(MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN); - layout->addCheckBox(MENU_ENUM_LABEL_CHECK_FOR_MISSING_FIRMWARE); - layout->addCheckBox(MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE); + layout->add(MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT); + layout->add(MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN); + layout->add(MENU_ENUM_LABEL_CHECK_FOR_MISSING_FIRMWARE); + layout->add(MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE); widget->setLayout(layout); diff --git a/ui/drivers/qt/options/directory.cpp b/ui/drivers/qt/options/directory.cpp index c665096393..51a062e341 100644 --- a/ui/drivers/qt/options/directory.cpp +++ b/ui/drivers/qt/options/directory.cpp @@ -23,34 +23,33 @@ DirectoryPage::DirectoryPage(QObject *parent) : QWidget *DirectoryPage::widget() { - QWidget *widget = new QWidget; - + QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; - layout->addDirectorySelector(MENU_ENUM_LABEL_CORE_ASSETS_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_ASSETS_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_DYNAMIC_WALLPAPERS_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_RGUI_CONFIG_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_LIBRETRO_DIR_PATH); - layout->addDirectorySelector(MENU_ENUM_LABEL_LIBRETRO_INFO_PATH); - layout->addDirectorySelector(MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_CURSOR_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_CHEAT_DATABASE_PATH); - layout->addDirectorySelector(MENU_ENUM_LABEL_VIDEO_FILTER_DIR); - layout->addDirectorySelector(MENU_ENUM_LABEL_AUDIO_FILTER_DIR); - layout->addDirectorySelector(MENU_ENUM_LABEL_VIDEO_SHADER_DIR); - layout->addDirectorySelector(MENU_ENUM_LABEL_RECORDING_OUTPUT_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_RECORDING_CONFIG_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_OVERLAY_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_SCREENSHOT_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_JOYPAD_AUTOCONFIG_DIR); - layout->addDirectorySelector(MENU_ENUM_LABEL_INPUT_REMAPPING_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_PLAYLIST_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_SAVEFILE_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_SAVESTATE_DIRECTORY); - layout->addDirectorySelector(MENU_ENUM_LABEL_CACHE_DIRECTORY); + layout->add(MENU_ENUM_LABEL_CORE_ASSETS_DIRECTORY); + layout->add(MENU_ENUM_LABEL_ASSETS_DIRECTORY); + layout->add(MENU_ENUM_LABEL_DYNAMIC_WALLPAPERS_DIRECTORY); + layout->add(MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY); + layout->add(MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY); + layout->add(MENU_ENUM_LABEL_RGUI_CONFIG_DIRECTORY); + layout->add(MENU_ENUM_LABEL_LIBRETRO_DIR_PATH); + layout->add(MENU_ENUM_LABEL_LIBRETRO_INFO_PATH); + layout->add(MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY); + layout->add(MENU_ENUM_LABEL_CURSOR_DIRECTORY); + layout->add(MENU_ENUM_LABEL_CHEAT_DATABASE_PATH); + layout->add(MENU_ENUM_LABEL_VIDEO_FILTER_DIR); + layout->add(MENU_ENUM_LABEL_AUDIO_FILTER_DIR); + layout->add(MENU_ENUM_LABEL_VIDEO_SHADER_DIR); + layout->add(MENU_ENUM_LABEL_RECORDING_OUTPUT_DIRECTORY); + layout->add(MENU_ENUM_LABEL_RECORDING_CONFIG_DIRECTORY); + layout->add(MENU_ENUM_LABEL_OVERLAY_DIRECTORY); + layout->add(MENU_ENUM_LABEL_SCREENSHOT_DIRECTORY); + layout->add(MENU_ENUM_LABEL_JOYPAD_AUTOCONFIG_DIR); + layout->add(MENU_ENUM_LABEL_INPUT_REMAPPING_DIRECTORY); + layout->add(MENU_ENUM_LABEL_PLAYLIST_DIRECTORY); + layout->add(MENU_ENUM_LABEL_SAVEFILE_DIRECTORY); + layout->add(MENU_ENUM_LABEL_SAVESTATE_DIRECTORY); + layout->add(MENU_ENUM_LABEL_CACHE_DIRECTORY); widget->setLayout(layout); diff --git a/ui/drivers/qt/options/drivers.cpp b/ui/drivers/qt/options/drivers.cpp index 64db8534ab..10a724c58d 100644 --- a/ui/drivers/qt/options/drivers.cpp +++ b/ui/drivers/qt/options/drivers.cpp @@ -24,20 +24,19 @@ DriversPage::DriversPage(QObject *parent) : QWidget *DriversPage::widget() { - QWidget *widget = new QWidget; - + QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; - layout->addStringComboBox(MENU_ENUM_LABEL_INPUT_DRIVER); - layout->addStringComboBox(MENU_ENUM_LABEL_JOYPAD_DRIVER); - layout->addStringComboBox(MENU_ENUM_LABEL_VIDEO_DRIVER); - layout->addStringComboBox(MENU_ENUM_LABEL_AUDIO_DRIVER); - layout->addStringComboBox(MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER); - layout->addStringComboBox(MENU_ENUM_LABEL_CAMERA_DRIVER); - layout->addStringComboBox(MENU_ENUM_LABEL_LOCATION_DRIVER); - layout->addStringComboBox(MENU_ENUM_LABEL_MENU_DRIVER); - layout->addStringComboBox(MENU_ENUM_LABEL_RECORD_DRIVER); - layout->addStringComboBox(MENU_ENUM_LABEL_MIDI_DRIVER); + layout->add(MENU_ENUM_LABEL_INPUT_DRIVER); + layout->add(MENU_ENUM_LABEL_JOYPAD_DRIVER); + layout->add(MENU_ENUM_LABEL_VIDEO_DRIVER); + layout->add(MENU_ENUM_LABEL_AUDIO_DRIVER); + layout->add(MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER); + layout->add(MENU_ENUM_LABEL_CAMERA_DRIVER); + layout->add(MENU_ENUM_LABEL_LOCATION_DRIVER); + layout->add(MENU_ENUM_LABEL_MENU_DRIVER); + layout->add(MENU_ENUM_LABEL_RECORD_DRIVER); + layout->add(MENU_ENUM_LABEL_MIDI_DRIVER); widget->setLayout(layout); From 9f09efe5c9e6714b509e6bfb2f30b2212a661157 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 17:45:12 +0200 Subject: [PATCH 185/237] (UI/QT) Dehardcode some more additions --- menu/menu_setting.c | 1 + ui/drivers/qt/options/latency.cpp | 31 +++++------ ui/drivers/qt/options/playlists.cpp | 14 +++-- ui/drivers/qt/options/video.cpp | 82 ++++++++++++++--------------- 4 files changed, 61 insertions(+), 67 deletions(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 15757e38b7..c0f3e9b34c 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -7794,6 +7794,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; (*list)[list_info->index - 1].offset_by = 1; menu_settings_list_current_add_range(list, list_info, 1, 6, 1, true, true); diff --git a/ui/drivers/qt/options/latency.cpp b/ui/drivers/qt/options/latency.cpp index 664e0785a2..ffecde9f21 100644 --- a/ui/drivers/qt/options/latency.cpp +++ b/ui/drivers/qt/options/latency.cpp @@ -23,32 +23,27 @@ LatencyPage::LatencyPage(QObject *parent) : QWidget *LatencyPage::widget() { - QWidget *widget = new QWidget; - - FormLayout *layout = new FormLayout; - + QWidget *widget = new QWidget; + FormLayout *layout = new FormLayout; CheckableSettingsGroup *runAheadGpuSync = new CheckableSettingsGroup(MENU_ENUM_LABEL_RUN_AHEAD_ENABLED); + rarch_setting_t *hardSyncSetting = menu_setting_find_enum(MENU_ENUM_LABEL_VIDEO_HARD_SYNC); + if (hardSyncSetting) { - rarch_setting_t *hardSyncSetting = menu_setting_find_enum(MENU_ENUM_LABEL_VIDEO_HARD_SYNC); + CheckableSettingsGroup *hardSyncGroup = new CheckableSettingsGroup(hardSyncSetting); - if (hardSyncSetting) - { - CheckableSettingsGroup *hardSyncGroup = new CheckableSettingsGroup(hardSyncSetting); + hardSyncGroup->add(MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES); - hardSyncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES); - - layout->addRow(hardSyncGroup); - } + layout->addRow(hardSyncGroup); } - layout->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_FRAME_DELAY); - layout->addUIntSpinBox(MENU_ENUM_LABEL_AUDIO_LATENCY); - layout->addUIntComboBox(MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR); + layout->add(MENU_ENUM_LABEL_VIDEO_FRAME_DELAY); + layout->add(MENU_ENUM_LABEL_AUDIO_LATENCY); + layout->add(MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR); - runAheadGpuSync->addUIntComboBox(MENU_ENUM_LABEL_RUN_AHEAD_FRAMES); - runAheadGpuSync->addCheckBox(MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE); - runAheadGpuSync->addCheckBox(MENU_ENUM_LABEL_RUN_AHEAD_HIDE_WARNINGS); + runAheadGpuSync->add(MENU_ENUM_LABEL_RUN_AHEAD_FRAMES); + runAheadGpuSync->add(MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE); + runAheadGpuSync->add(MENU_ENUM_LABEL_RUN_AHEAD_HIDE_WARNINGS); layout->addRow(runAheadGpuSync); widget->setLayout(layout); diff --git a/ui/drivers/qt/options/playlists.cpp b/ui/drivers/qt/options/playlists.cpp index 3670684b5b..63c74368b5 100644 --- a/ui/drivers/qt/options/playlists.cpp +++ b/ui/drivers/qt/options/playlists.cpp @@ -23,19 +23,17 @@ PlaylistsPage::PlaylistsPage(QObject *parent) : QWidget *PlaylistsPage::widget() { - QWidget *widget = new QWidget; - - FormLayout *layout = new FormLayout; - + QWidget *widget = new QWidget; + FormLayout *layout = new FormLayout; CheckableSettingsGroup *history = new CheckableSettingsGroup(MENU_ENUM_LABEL_HISTORY_LIST_ENABLE); - history->addUIntSpinBox(MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE); + history->add(MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE); layout->addRow(history); - layout->addCheckBox(MENU_ENUM_LABEL_PLAYLIST_ENTRY_RENAME); - layout->addCheckBox(MENU_ENUM_LABEL_PLAYLIST_ENTRY_REMOVE); - layout->addCheckBox(MENU_ENUM_LABEL_PLAYLIST_USE_OLD_FORMAT); + layout->add(MENU_ENUM_LABEL_PLAYLIST_ENTRY_RENAME); + layout->add(MENU_ENUM_LABEL_PLAYLIST_ENTRY_REMOVE); + layout->add(MENU_ENUM_LABEL_PLAYLIST_USE_OLD_FORMAT); widget->setLayout(layout); diff --git a/ui/drivers/qt/options/video.cpp b/ui/drivers/qt/options/video.cpp index b962a8e97c..a948277118 100644 --- a/ui/drivers/qt/options/video.cpp +++ b/ui/drivers/qt/options/video.cpp @@ -36,36 +36,36 @@ VideoPage::VideoPage(QObject *parent) : QWidget *VideoPage::widget() { - QWidget *widget = new QWidget; + QWidget *widget = new QWidget; - QVBoxLayout *layout = new QVBoxLayout; + QVBoxLayout *layout = new QVBoxLayout; - SettingsGroup *outputGroup = new SettingsGroup("Output"); - SettingsGroup *aspectGroup = new SettingsGroup("Scaling"); + SettingsGroup *outputGroup = new SettingsGroup("Output"); + SettingsGroup *aspectGroup = new SettingsGroup("Scaling"); - SettingsGroup *fullscreenGroup = new SettingsGroup("Fullscreen Mode"); - SettingsGroup *windowedGroup = new SettingsGroup("Windowed Mode"); + SettingsGroup *fullscreenGroup = new SettingsGroup("Fullscreen Mode"); + SettingsGroup *windowedGroup = new SettingsGroup("Windowed Mode"); - QHBoxLayout *fullcreenSizeLayout = new QHBoxLayout; - FormLayout *leftFullscreenSizeForm = new FormLayout; + QHBoxLayout *fullcreenSizeLayout = new QHBoxLayout; + FormLayout *leftFullscreenSizeForm = new FormLayout; FormLayout *rightFullscreenSizeForm = new FormLayout; - QHBoxLayout *windowedSizeLayout = new QHBoxLayout; - FormLayout *leftWindowedSizeForm = new FormLayout; - FormLayout *rightWindowedSizeForm = new FormLayout; + QHBoxLayout *windowedSizeLayout = new QHBoxLayout; + FormLayout *leftWindowedSizeForm = new FormLayout; + FormLayout *rightWindowedSizeForm = new FormLayout; - SettingsGroup *syncGroup = new SettingsGroup("Synchronization"); - CheckableSettingsGroup *vSyncGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_VSYNC); + SettingsGroup *syncGroup = new SettingsGroup("Synchronization"); + CheckableSettingsGroup *vSyncGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_VSYNC); - QHBoxLayout *outputScalingLayout = new QHBoxLayout; - QHBoxLayout *modeLayout = new QHBoxLayout; - QHBoxLayout *syncMiscLayout = new QHBoxLayout; + QHBoxLayout *outputScalingLayout = new QHBoxLayout; + QHBoxLayout *modeLayout = new QHBoxLayout; + QHBoxLayout *syncMiscLayout = new QHBoxLayout; - SettingsGroup *miscGroup = new SettingsGroup("Miscellaneous"); - SettingsGroup *filterGroup = new SettingsGroup("Video Filter"); + SettingsGroup *miscGroup = new SettingsGroup("Miscellaneous"); + SettingsGroup *filterGroup = new SettingsGroup("Video Filter"); - unsigned i, size = 0; - struct video_display_config *list = (struct video_display_config*) video_display_server_get_resolution_list(&size); + unsigned i, size = 0; + struct video_display_config *list = (struct video_display_config*) video_display_server_get_resolution_list(&size); if (list) { @@ -84,14 +84,14 @@ QWidget *VideoPage::widget() free(list); } - outputGroup->addStringComboBox(MENU_ENUM_LABEL_VIDEO_DRIVER); - outputGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_MONITOR_INDEX); - outputGroup->addUIntComboBox(MENU_ENUM_LABEL_VIDEO_ROTATION); + outputGroup->add(MENU_ENUM_LABEL_VIDEO_DRIVER); + outputGroup->add(MENU_ENUM_LABEL_VIDEO_MONITOR_INDEX); + outputGroup->add(MENU_ENUM_LABEL_VIDEO_ROTATION); outputGroup->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION), m_resolutionCombo); - outputGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_FORCE_SRGB_DISABLE); + outputGroup->add(MENU_ENUM_LABEL_VIDEO_FORCE_SRGB_DISABLE); - fullscreenGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_FULLSCREEN); - fullscreenGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_WINDOWED_FULLSCREEN); + fullscreenGroup->add(MENU_ENUM_LABEL_VIDEO_FULLSCREEN); + fullscreenGroup->add(MENU_ENUM_LABEL_VIDEO_WINDOWED_FULLSCREEN); leftFullscreenSizeForm->addRow("Width:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_FULLSCREEN_X)); rightFullscreenSizeForm->addRow("Height:", new UIntSpinBox(MENU_ENUM_LABEL_VIDEO_FULLSCREEN_Y)); @@ -101,7 +101,7 @@ QWidget *VideoPage::widget() fullscreenGroup->addRow(fullcreenSizeLayout); - aspectGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER); + aspectGroup->add(MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER); aspectGroup->addRow(new AspectRatioGroup("Aspect Ratio")); leftWindowedSizeForm->addRow("Scale:", new FloatSpinBox(MENU_ENUM_LABEL_VIDEO_SCALE)); @@ -115,12 +115,12 @@ QWidget *VideoPage::widget() windowedGroup->addRow(windowedSizeLayout); - windowedGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_WINDOW_SHOW_DECORATIONS); - windowedGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_WINDOW_SAVE_POSITION); + windowedGroup->add(MENU_ENUM_LABEL_VIDEO_WINDOW_SHOW_DECORATIONS); + windowedGroup->add(MENU_ENUM_LABEL_VIDEO_WINDOW_SAVE_POSITION); - vSyncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL); - vSyncGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_ADAPTIVE_VSYNC); - vSyncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_FRAME_DELAY); + vSyncGroup->add(MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL); + vSyncGroup->add(MENU_ENUM_LABEL_VIDEO_ADAPTIVE_VSYNC); + vSyncGroup->add(MENU_ENUM_LABEL_VIDEO_FRAME_DELAY); syncGroup->addRow(vSyncGroup); { @@ -130,25 +130,25 @@ QWidget *VideoPage::widget() { CheckableSettingsGroup *hardSyncGroup = new CheckableSettingsGroup(hardSyncSetting); - hardSyncGroup->addUIntSpinBox(hardSyncSetting->enum_idx); + hardSyncGroup->add(MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES); syncGroup->addRow(hardSyncGroup); } } - syncGroup->addUIntSpinBox(MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES); + syncGroup->add(MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES); - miscGroup->addCheckBox(MENU_ENUM_LABEL_SUSPEND_SCREENSAVER_ENABLE); - miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_THREADED); - miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION); - miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT); - miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_CROP_OVERSCAN); - miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_SMOOTH); + miscGroup->add(MENU_ENUM_LABEL_SUSPEND_SCREENSAVER_ENABLE); + miscGroup->add(MENU_ENUM_LABEL_VIDEO_THREADED); + miscGroup->add(MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION); + miscGroup->add(MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT); + miscGroup->add(MENU_ENUM_LABEL_VIDEO_CROP_OVERSCAN); + miscGroup->add(MENU_ENUM_LABEL_VIDEO_SMOOTH); syncMiscLayout->addWidget(syncGroup); syncMiscLayout->addWidget(miscGroup); - filterGroup->addFileSelector(MENU_ENUM_LABEL_VIDEO_FILTER); + filterGroup->add(MENU_ENUM_LABEL_VIDEO_FILTER); modeLayout->addWidget(fullscreenGroup); modeLayout->addWidget(windowedGroup); From 0feb657e293c5a4fe8ec8f8900fe6e8068614d1b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 17:54:00 +0200 Subject: [PATCH 186/237] (UI/QT) More dehardcoding --- setting_list.c | 1 + ui/drivers/qt/options/throttle.cpp | 22 ++++++++++------------ ui/drivers/qt/settingswidgets.h | 4 ++-- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/setting_list.c b/setting_list.c index 49c57e1847..2154558ab0 100644 --- a/setting_list.c +++ b/setting_list.c @@ -1921,6 +1921,7 @@ bool CONFIG_SIZE( if (!(settings_list_append(list, list_info))) return false; (*list)[list_info->index++] = value; + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_SIZE_SPINBOX; #ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); diff --git a/ui/drivers/qt/options/throttle.cpp b/ui/drivers/qt/options/throttle.cpp index a59260c30d..a9cf82c72e 100644 --- a/ui/drivers/qt/options/throttle.cpp +++ b/ui/drivers/qt/options/throttle.cpp @@ -25,14 +25,13 @@ FrameThrottlePage::FrameThrottlePage(QObject *parent) : QWidget *FrameThrottlePage::widget() { - QWidget *widget = new QWidget; - + QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; - layout->addFloatSpinBox(MENU_ENUM_LABEL_FASTFORWARD_RATIO); - layout->addFloatSpinBox(MENU_ENUM_LABEL_SLOWMOTION_RATIO); - layout->addCheckBox(MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE); + layout->add(MENU_ENUM_LABEL_FASTFORWARD_RATIO); + layout->add(MENU_ENUM_LABEL_SLOWMOTION_RATIO); + layout->add(MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE); + layout->add(MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE); widget->setLayout(layout); @@ -47,14 +46,13 @@ RewindPage::RewindPage(QObject *parent) : QWidget *RewindPage::widget() { - QWidget *widget = new QWidget; - + QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; - layout->addCheckBox(MENU_ENUM_LABEL_REWIND_ENABLE); - layout->addUIntSpinBox(MENU_ENUM_LABEL_REWIND_GRANULARITY); - layout->addSizeSpinBox(MENU_ENUM_LABEL_REWIND_BUFFER_SIZE); - layout->addUIntSpinBox(MENU_ENUM_LABEL_REWIND_BUFFER_SIZE_STEP); + layout->add(MENU_ENUM_LABEL_REWIND_ENABLE); + layout->add(MENU_ENUM_LABEL_REWIND_GRANULARITY); + layout->add(MENU_ENUM_LABEL_REWIND_BUFFER_SIZE); + layout->add(MENU_ENUM_LABEL_REWIND_BUFFER_SIZE_STEP); widget->setLayout(layout); diff --git a/ui/drivers/qt/settingswidgets.h b/ui/drivers/qt/settingswidgets.h index 563e113ee5..7f24203389 100644 --- a/ui/drivers/qt/settingswidgets.h +++ b/ui/drivers/qt/settingswidgets.h @@ -87,7 +87,7 @@ public: this->addFloatSliderAndSpinBox(enum_idx); break; case ST_UI_TYPE_SIZE_SPINBOX: - /* TODO/FIXME */ + this->addSizeSpinBox(enum_idx); break; case ST_UI_TYPE_BIND_BUTTON: return this->addBindButton(enum_idx); @@ -181,7 +181,7 @@ public: this->addFloatSliderAndSpinBox(enum_idx); break; case ST_UI_TYPE_SIZE_SPINBOX: - /* TODO/FIXME */ + this->addSizeSpinBox(enum_idx); break; case ST_UI_TYPE_BIND_BUTTON: /* TODO/FIXME - Why is the returntype void here and bool From 051c877c6233186cea68329d4af20eca6ebf949e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 18:24:27 +0200 Subject: [PATCH 187/237] (QT/UI) By default, a CONFIG_FLOAT setting becomes a 'spinbox' UI type. If a range is specified, it becomes a 'slider and spinbox' UI type. --- menu/menu_setting.c | 4 ++++ setting_list.c | 2 +- ui/drivers/qt/options/osd.cpp | 37 ++++++++++++++++----------------- ui/drivers/qt/settingswidgets.h | 2 +- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index c0f3e9b34c..944173d69c 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -2474,6 +2474,10 @@ void menu_settings_list_current_add_range( { unsigned idx = list_info->index - 1; + if ((*list)[idx].type == ST_FLOAT) + (*list)[list_info->index - 1].ui_type + = ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX; + (*list)[idx].min = min; (*list)[idx].step = step; (*list)[idx].max = max; diff --git a/setting_list.c b/setting_list.c index 2154558ab0..4ec80bc339 100644 --- a/setting_list.c +++ b/setting_list.c @@ -1950,7 +1950,7 @@ bool CONFIG_FLOAT( if (!(settings_list_append(list, list_info))) return false; (*list)[list_info->index++] = value; - (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX; + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_FLOAT_SPINBOX; #ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); diff --git a/ui/drivers/qt/options/osd.cpp b/ui/drivers/qt/options/osd.cpp index 311f07c894..1c77393c47 100644 --- a/ui/drivers/qt/options/osd.cpp +++ b/ui/drivers/qt/options/osd.cpp @@ -25,19 +25,18 @@ NotificationsPage::NotificationsPage(QObject *parent) : QWidget *NotificationsPage::widget() { - QWidget *widget = new QWidget; - QVBoxLayout *layout = new QVBoxLayout; - + QWidget *widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; CheckableSettingsGroup *notificationsGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_FONT_ENABLE); - CheckableSettingsGroup *bgGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_ENABLE); + CheckableSettingsGroup *bgGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_ENABLE); - notificationsGroup->addCheckBox(MENU_ENUM_LABEL_FPS_SHOW); - notificationsGroup->addCheckBox(MENU_ENUM_LABEL_FRAMECOUNT_SHOW); - notificationsGroup->addCheckBox(MENU_ENUM_LABEL_MEMORY_SHOW); - notificationsGroup->addFontSelector(MENU_ENUM_LABEL_VIDEO_FONT_PATH); - notificationsGroup->addFloatSpinBox(MENU_ENUM_LABEL_VIDEO_FONT_SIZE); - notificationsGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_X); - notificationsGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_Y); + notificationsGroup->add(MENU_ENUM_LABEL_FPS_SHOW); + notificationsGroup->add(MENU_ENUM_LABEL_FRAMECOUNT_SHOW); + notificationsGroup->add(MENU_ENUM_LABEL_MEMORY_SHOW); + notificationsGroup->add(MENU_ENUM_LABEL_VIDEO_FONT_PATH); + notificationsGroup->add(MENU_ENUM_LABEL_VIDEO_FONT_SIZE); + notificationsGroup->add(MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_X); + notificationsGroup->add(MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_Y); notificationsGroup->addRow("Notification Color: ", new FloatColorButton( MENU_ENUM_LABEL_VIDEO_MESSAGE_COLOR_RED, MENU_ENUM_LABEL_VIDEO_MESSAGE_COLOR_GREEN, @@ -68,22 +67,22 @@ OverlayPage::OverlayPage(QObject *parent) : QWidget *OverlayPage::widget() { - QWidget *widget = new QWidget; - QVBoxLayout *layout = new QVBoxLayout; + QWidget *widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; CheckableSettingsGroup *overlayGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_INPUT_OVERLAY_ENABLE); - CheckableSettingsGroup *inputsGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS); + CheckableSettingsGroup *inputsGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS); - overlayGroup->addCheckBox(MENU_ENUM_LABEL_OVERLAY_AUTOLOAD_PREFERRED); - overlayGroup->addCheckBox(MENU_ENUM_LABEL_INPUT_OVERLAY_HIDE_IN_MENU); + overlayGroup->add(MENU_ENUM_LABEL_OVERLAY_AUTOLOAD_PREFERRED); + overlayGroup->add(MENU_ENUM_LABEL_INPUT_OVERLAY_HIDE_IN_MENU); inputsGroup->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT); overlayGroup->addRow(inputsGroup); - overlayGroup->addFileSelector(MENU_ENUM_LABEL_OVERLAY_PRESET); - overlayGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_OVERLAY_OPACITY); - overlayGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_OVERLAY_SCALE); + overlayGroup->add(MENU_ENUM_LABEL_OVERLAY_PRESET); + overlayGroup->add(MENU_ENUM_LABEL_OVERLAY_OPACITY); + overlayGroup->add(MENU_ENUM_LABEL_OVERLAY_SCALE); layout->addWidget(overlayGroup); diff --git a/ui/drivers/qt/settingswidgets.h b/ui/drivers/qt/settingswidgets.h index 7f24203389..201233d97e 100644 --- a/ui/drivers/qt/settingswidgets.h +++ b/ui/drivers/qt/settingswidgets.h @@ -181,7 +181,7 @@ public: this->addFloatSliderAndSpinBox(enum_idx); break; case ST_UI_TYPE_SIZE_SPINBOX: - this->addSizeSpinBox(enum_idx); + /* TODO/FIXME */ break; case ST_UI_TYPE_BIND_BUTTON: /* TODO/FIXME - Why is the returntype void here and bool From e0849df59f5b0a526a1dce401a2dcd2c7c0287cc Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 18:33:15 +0200 Subject: [PATCH 188/237] (UI/QT) Dehardcode two more additions --- ui/drivers/qt/options/osd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/drivers/qt/options/osd.cpp b/ui/drivers/qt/options/osd.cpp index 1c77393c47..9bdf9533d1 100644 --- a/ui/drivers/qt/options/osd.cpp +++ b/ui/drivers/qt/options/osd.cpp @@ -46,7 +46,7 @@ QWidget *NotificationsPage::widget() MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_RED, MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_GREEN, MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_BLUE)); - bgGroup->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_OPACITY); + bgGroup->add(MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_OPACITY); notificationsGroup->addRow(bgGroup); @@ -76,7 +76,7 @@ QWidget *OverlayPage::widget() overlayGroup->add(MENU_ENUM_LABEL_OVERLAY_AUTOLOAD_PREFERRED); overlayGroup->add(MENU_ENUM_LABEL_INPUT_OVERLAY_HIDE_IN_MENU); - inputsGroup->addUIntSpinBox(MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT); + inputsGroup->add(MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT); overlayGroup->addRow(inputsGroup); From f3a7f6971b628a3cdc9801cf6836bb3fcefb712f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 18:37:20 +0200 Subject: [PATCH 189/237] (QT/UI) Dehardcode more additions --- menu/menu_setting.c | 2 ++ ui/drivers/qt/options/achievements.cpp | 22 ++++++++++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 944173d69c..56e1e01dd5 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -11173,6 +11173,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; CONFIG_STRING( list, list_info, @@ -11189,6 +11190,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_cheevos_password; settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_PASSWORD_LINE_EDIT; #endif END_SUB_GROUP(list, list_info, parent_group); diff --git a/ui/drivers/qt/options/achievements.cpp b/ui/drivers/qt/options/achievements.cpp index 76d0acf81f..0b7dce7651 100644 --- a/ui/drivers/qt/options/achievements.cpp +++ b/ui/drivers/qt/options/achievements.cpp @@ -23,20 +23,18 @@ AchievementsPage::AchievementsPage(QObject *parent) : QWidget *AchievementsPage::widget() { - QWidget *widget = new QWidget; - - QVBoxLayout *layout = new QVBoxLayout; - + QWidget *widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; CheckableSettingsGroup *group = new CheckableSettingsGroup(MENU_ENUM_LABEL_CHEEVOS_ENABLE); - group->addStringLineEdit(MENU_ENUM_LABEL_CHEEVOS_USERNAME); - group->addPasswordLineEdit(MENU_ENUM_LABEL_CHEEVOS_PASSWORD); - group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE); - group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE); - group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE); - group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_TEST_UNOFFICIAL); - group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_VERBOSE_ENABLE); - group->addCheckBox(MENU_ENUM_LABEL_CHEEVOS_AUTO_SCREENSHOT); + group->add(MENU_ENUM_LABEL_CHEEVOS_USERNAME); + group->add(MENU_ENUM_LABEL_CHEEVOS_PASSWORD); + group->add(MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE); + group->add(MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE); + group->add(MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE); + group->add(MENU_ENUM_LABEL_CHEEVOS_TEST_UNOFFICIAL); + group->add(MENU_ENUM_LABEL_CHEEVOS_VERBOSE_ENABLE); + group->add(MENU_ENUM_LABEL_CHEEVOS_AUTO_SCREENSHOT); layout->addWidget(group); From 181cff34d8dc459be52d35ef6d3711d9ebab6808 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 18:55:30 +0200 Subject: [PATCH 190/237] (UI/QT) network.cpp - dehardcode more additions --- menu/menu_setting.c | 10 +++++++++ ui/drivers/qt/options/network.cpp | 36 +++++++++++++++---------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 56e1e01dd5..15f4ff2572 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -10465,6 +10465,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; CONFIG_STRING( list, list_info, @@ -10479,6 +10480,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; CONFIG_BOOL( list, list_info, @@ -10575,6 +10577,7 @@ static bool setting_append_list( general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; CONFIG_UINT( list, list_info, @@ -10605,6 +10608,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_PASSWORD_LINE_EDIT; CONFIG_STRING( list, list_info, @@ -10619,6 +10623,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_PASSWORD_LINE_EDIT; CONFIG_BOOL( list, list_info, @@ -10694,6 +10699,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_SPINBOX; menu_settings_list_current_add_range(list, list_info, -600, 600, 1, false, false); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); @@ -10708,6 +10714,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_SPINBOX; (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; menu_settings_list_current_add_range(list, list_info, 0, 15, 1, true, true); @@ -10722,6 +10729,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_SPINBOX; (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; menu_settings_list_current_add_range(list, list_info, 0, 15, 1, true, true); @@ -10756,6 +10764,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_netplay_share_digital; menu_settings_list_current_add_range(list, list_info, 0, RARCH_NETPLAY_SHARE_DIGITAL_LAST-1, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; CONFIG_UINT( list, list_info, @@ -10772,6 +10781,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_netplay_share_analog; menu_settings_list_current_add_range(list, list_info, 0, RARCH_NETPLAY_SHARE_ANALOG_LAST-1, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; for (user = 0; user < MAX_USERS; user++) { diff --git a/ui/drivers/qt/options/network.cpp b/ui/drivers/qt/options/network.cpp index ccad6be695..d8034a6e9e 100644 --- a/ui/drivers/qt/options/network.cpp +++ b/ui/drivers/qt/options/network.cpp @@ -55,14 +55,14 @@ QWidget *NetplayPage::widget() unsigned row = 0; unsigned column = 0; - checksLayout->addCheckBox(MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE); - checksLayout->addCheckBox(MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR); + checksLayout->add(MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE); + checksLayout->add(MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR); - serverForm->addStringLineEdit(MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS); - serverForm->addUIntSpinBox(MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT); - serverForm->addPasswordLineEdit(MENU_ENUM_LABEL_NETPLAY_PASSWORD); - serverForm->addPasswordLineEdit(MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD); - serverForm->addCheckBox(MENU_ENUM_LABEL_NETPLAY_NAT_TRAVERSAL); + serverForm->add(MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS); + serverForm->add(MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT); + serverForm->add(MENU_ENUM_LABEL_NETPLAY_PASSWORD); + serverForm->add(MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD); + serverForm->add(MENU_ENUM_LABEL_NETPLAY_NAT_TRAVERSAL); serverLayout->addWidget(createMitmServerGroup()); serverLayout->addSpacing(30); @@ -70,16 +70,16 @@ QWidget *NetplayPage::widget() serverGroup->setLayout(serverLayout); - slaveGroup->addCheckBox(MENU_ENUM_LABEL_NETPLAY_ALLOW_SLAVES); - slaveGroup->addCheckBox(MENU_ENUM_LABEL_NETPLAY_REQUIRE_SLAVES); + slaveGroup->add(MENU_ENUM_LABEL_NETPLAY_ALLOW_SLAVES); + slaveGroup->add(MENU_ENUM_LABEL_NETPLAY_REQUIRE_SLAVES); - syncGroup->addCheckBox(MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE); - syncGroup->addUIntSpinBox(MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES); - syncGroup->addUIntSpinBox(MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN); - syncGroup->addUIntSpinBox(MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE); + syncGroup->add(MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE); + syncGroup->add(MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES); + syncGroup->add(MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN); + syncGroup->add(MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE); - inputGroup->addUIntComboBox(MENU_ENUM_LABEL_NETPLAY_SHARE_DIGITAL); - inputGroup->addUIntComboBox(MENU_ENUM_LABEL_NETPLAY_SHARE_ANALOG); + inputGroup->add(MENU_ENUM_LABEL_NETPLAY_SHARE_DIGITAL); + inputGroup->add(MENU_ENUM_LABEL_NETPLAY_SHARE_ANALOG); for (i = 0; i < MAX_USERS; i++) { @@ -167,9 +167,9 @@ QWidget *UpdaterPage::widget() QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; - layout->addStringLineEdit(MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL); - layout->addStringLineEdit(MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL); - layout->addCheckBox(MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE); + layout->add(MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL); + layout->add(MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL); + layout->add(MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE); widget->setLayout(layout); From 4b3ca341c2f83d0b116e6431b54fb5d9f7cf2127 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 18:58:51 +0200 Subject: [PATCH 191/237] (UI/QT) saving - dehardcode more additions --- ui/drivers/qt/options/saving.cpp | 38 +++++++++++++++----------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/ui/drivers/qt/options/saving.cpp b/ui/drivers/qt/options/saving.cpp index c91a5378b1..29389eb729 100644 --- a/ui/drivers/qt/options/saving.cpp +++ b/ui/drivers/qt/options/saving.cpp @@ -23,35 +23,33 @@ SavingPage::SavingPage(QObject *parent) : QWidget *SavingPage::widget() { - QWidget *widget = new QWidget; - - FormLayout *layout = new FormLayout; - - SettingsGroup *savesGroup = new SettingsGroup("Saves"); - SettingsGroup *savestatesGroup = new SettingsGroup("Savestates"); + QWidget *widget = new QWidget; + FormLayout *layout = new FormLayout; + SettingsGroup *savesGroup = new SettingsGroup("Saves"); + SettingsGroup *savestatesGroup = new SettingsGroup("Savestates"); CheckableSettingsGroup *autoSavestatesGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE); - SettingsGroup *saveRamGroup = new SettingsGroup("SaveRAM"); - SettingsGroup *systemFilesDirGroup = new SettingsGroup("System Files"); - SettingsGroup *screenshotsDirGroup = new SettingsGroup("Screenshots"); + SettingsGroup *saveRamGroup = new SettingsGroup("SaveRAM"); + SettingsGroup *systemFilesDirGroup = new SettingsGroup("System Files"); + SettingsGroup *screenshotsDirGroup = new SettingsGroup("Screenshots"); - savesGroup->addCheckBox(MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE); - savesGroup->addCheckBox(MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE); + savesGroup->add(MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE); + savesGroup->add(MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE); - savestatesGroup->addCheckBox(MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX); + savestatesGroup->add(MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX); - autoSavestatesGroup->addCheckBox(MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD); + autoSavestatesGroup->add(MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD); savestatesGroup->addRow(autoSavestatesGroup); - savestatesGroup->addCheckBox(MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE); - savestatesGroup->addCheckBox(MENU_ENUM_LABEL_SORT_SAVESTATES_ENABLE); - savestatesGroup->addCheckBox(MENU_ENUM_LABEL_SAVESTATES_IN_CONTENT_DIR_ENABLE); + savestatesGroup->add(MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE); + savestatesGroup->add(MENU_ENUM_LABEL_SORT_SAVESTATES_ENABLE); + savestatesGroup->add(MENU_ENUM_LABEL_SAVESTATES_IN_CONTENT_DIR_ENABLE); - saveRamGroup->addCheckBox(MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE); - saveRamGroup->addUIntSpinBox(MENU_ENUM_LABEL_AUTOSAVE_INTERVAL); + saveRamGroup->add(MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE); + saveRamGroup->add(MENU_ENUM_LABEL_AUTOSAVE_INTERVAL); - systemFilesDirGroup->addCheckBox(MENU_ENUM_LABEL_SYSTEMFILES_IN_CONTENT_DIR_ENABLE); + systemFilesDirGroup->add(MENU_ENUM_LABEL_SYSTEMFILES_IN_CONTENT_DIR_ENABLE); - screenshotsDirGroup->addCheckBox(MENU_ENUM_LABEL_SCREENSHOTS_IN_CONTENT_DIR_ENABLE); + screenshotsDirGroup->add(MENU_ENUM_LABEL_SCREENSHOTS_IN_CONTENT_DIR_ENABLE); layout->addRow(savesGroup); layout->addRow(savestatesGroup); From 534cfb60cfb38c0e2ca18ce21e5e5da0fb13d2a1 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 19:04:46 +0200 Subject: [PATCH 192/237] (UI/QT) ui - start dehardcoding additions --- ui/drivers/qt/options/ui.cpp | 204 +++++++++++++++++------------------ 1 file changed, 97 insertions(+), 107 deletions(-) diff --git a/ui/drivers/qt/options/ui.cpp b/ui/drivers/qt/options/ui.cpp index 9f8d659d59..bffd5bc19f 100644 --- a/ui/drivers/qt/options/ui.cpp +++ b/ui/drivers/qt/options/ui.cpp @@ -34,50 +34,44 @@ UserInterfacePage::UserInterfacePage(QObject *parent) : QWidget *UserInterfacePage::widget() { - QWidget * widget = new QWidget; - - QVBoxLayout *layout = new QVBoxLayout; - - SettingsGroup *menuGroup = new SettingsGroup("Menu"); - SettingsGroup *inputGroup = new SettingsGroup("Input"); - SettingsGroup *miscGroup = new SettingsGroup("Miscelaneous"); + QWidget * widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; + SettingsGroup *menuGroup = new SettingsGroup("Menu"); + SettingsGroup *inputGroup = new SettingsGroup("Input"); + SettingsGroup *miscGroup = new SettingsGroup("Miscellaneous"); CheckableSettingsGroup *desktopGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_DESKTOP_MENU_ENABLE); + rarch_setting_t *kioskMode = menu_setting_find_enum(MENU_ENUM_LABEL_MENU_ENABLE_KIOSK_MODE); - menuGroup->addCheckBox(MENU_ENUM_LABEL_SHOW_ADVANCED_SETTINGS); + menuGroup->add(MENU_ENUM_LABEL_SHOW_ADVANCED_SETTINGS); + /* only on XMB and Ozone*/ + if (kioskMode) { - rarch_setting_t *kioskMode = menu_setting_find_enum(MENU_ENUM_LABEL_MENU_ENABLE_KIOSK_MODE); + CheckableSettingsGroup *kioskGroup = new CheckableSettingsGroup(kioskMode, widget); - /* only on xmb and ozone*/ - if (kioskMode) - { - CheckableSettingsGroup *kioskGroup = new CheckableSettingsGroup(kioskMode, widget); - - kioskGroup->addPasswordLineEdit(MENU_ENUM_LABEL_MENU_KIOSK_MODE_PASSWORD); - - menuGroup->addRow(kioskGroup); - } + kioskGroup->addPasswordLineEdit(MENU_ENUM_LABEL_MENU_KIOSK_MODE_PASSWORD); + menuGroup->addRow(kioskGroup); } - menuGroup->addCheckBox(MENU_ENUM_LABEL_NAVIGATION_WRAPAROUND); - menuGroup->addCheckBox(MENU_ENUM_LABEL_PAUSE_LIBRETRO); + menuGroup->add(MENU_ENUM_LABEL_NAVIGATION_WRAPAROUND); + menuGroup->add(MENU_ENUM_LABEL_PAUSE_LIBRETRO); - inputGroup->addCheckBox(MENU_ENUM_LABEL_MOUSE_ENABLE); - inputGroup->addCheckBox(MENU_ENUM_LABEL_POINTER_ENABLE); + inputGroup->add(MENU_ENUM_LABEL_MOUSE_ENABLE); + inputGroup->add(MENU_ENUM_LABEL_POINTER_ENABLE); menuGroup->addRow(inputGroup); - menuGroup->addCheckBox(MENU_ENUM_LABEL_THREADED_DATA_RUNLOOP_ENABLE); + menuGroup->add(MENU_ENUM_LABEL_THREADED_DATA_RUNLOOP_ENABLE); - miscGroup->addCheckBox(MENU_ENUM_LABEL_PAUSE_NONACTIVE); - miscGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_DISABLE_COMPOSITION); + miscGroup->add(MENU_ENUM_LABEL_PAUSE_NONACTIVE); + miscGroup->add(MENU_ENUM_LABEL_VIDEO_DISABLE_COMPOSITION); - menuGroup->addCheckBox(MENU_ENUM_LABEL_UI_COMPANION_ENABLE); - menuGroup->addCheckBox(MENU_ENUM_LABEL_UI_COMPANION_START_ON_BOOT); - menuGroup->addCheckBox(MENU_ENUM_LABEL_UI_MENUBAR_ENABLE); + menuGroup->add(MENU_ENUM_LABEL_UI_COMPANION_ENABLE); + menuGroup->add(MENU_ENUM_LABEL_UI_COMPANION_START_ON_BOOT); + menuGroup->add(MENU_ENUM_LABEL_UI_MENUBAR_ENABLE); - /* layout->addCheckBox(MENU_ENUM_LABEL_DESKTOP_MENU_ENABLE); */ - desktopGroup->addCheckBox(MENU_ENUM_LABEL_UI_COMPANION_TOGGLE); + /* layout->add(MENU_ENUM_LABEL_DESKTOP_MENU_ENABLE); */ + desktopGroup->add(MENU_ENUM_LABEL_UI_COMPANION_TOGGLE); layout->addWidget(menuGroup); layout->addWidget(miscGroup); @@ -97,46 +91,46 @@ ViewsPage::ViewsPage(QObject *parent) : QWidget *ViewsPage::widget() { - QWidget * widget = new QWidget(); - QHBoxLayout *mainLayout = new QHBoxLayout; - FormLayout *leftLayout = new FormLayout; - QVBoxLayout *rightLayout = new QVBoxLayout; - SettingsGroup *quickMenu = new SettingsGroup("Quick Menu"); - QuickMenuPage *quickPage = new QuickMenuPage(this); - SettingsGroup *mainMenu = new SettingsGroup("Main Menu"); - SettingsGroup *tabs = new SettingsGroup("Tabs"); - SettingsGroup *status = new SettingsGroup("Status"); + QWidget * widget = new QWidget(); + QHBoxLayout *mainLayout = new QHBoxLayout; + FormLayout *leftLayout = new FormLayout; + QVBoxLayout *rightLayout = new QVBoxLayout; + SettingsGroup *quickMenu = new SettingsGroup("Quick Menu"); + QuickMenuPage *quickPage = new QuickMenuPage(this); + SettingsGroup *mainMenu = new SettingsGroup("Main Menu"); + SettingsGroup *tabs = new SettingsGroup("Tabs"); + SettingsGroup *status = new SettingsGroup("Status"); SettingsGroup *startScreen = new SettingsGroup("StartScreen"); - mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_LOAD_CORE); - mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_LOAD_CONTENT); - /* mainMenu->addCheckBox(MENU_ENUM_LABEL_SHOW_WIMP); */ - mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_ONLINE_UPDATER); - mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_CORE_UPDATER); - mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_INFORMATION); - mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_CONFIGURATIONS); - mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_HELP); - mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_QUIT_RETROARCH); - mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_REBOOT); - mainMenu->addCheckBox(MENU_ENUM_LABEL_MENU_SHOW_SHUTDOWN); + mainMenu->add(MENU_ENUM_LABEL_MENU_SHOW_LOAD_CORE); + mainMenu->add(MENU_ENUM_LABEL_MENU_SHOW_LOAD_CONTENT); + /* mainMenu->add(MENU_ENUM_LABEL_SHOW_WIMP); */ + mainMenu->add(MENU_ENUM_LABEL_MENU_SHOW_ONLINE_UPDATER); + mainMenu->add(MENU_ENUM_LABEL_MENU_SHOW_CORE_UPDATER); + mainMenu->add(MENU_ENUM_LABEL_MENU_SHOW_INFORMATION); + mainMenu->add(MENU_ENUM_LABEL_MENU_SHOW_CONFIGURATIONS); + mainMenu->add(MENU_ENUM_LABEL_MENU_SHOW_HELP); + mainMenu->add(MENU_ENUM_LABEL_MENU_SHOW_QUIT_RETROARCH); + mainMenu->add(MENU_ENUM_LABEL_MENU_SHOW_REBOOT); + mainMenu->add(MENU_ENUM_LABEL_MENU_SHOW_SHUTDOWN); - tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS); + tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS); tabs->addPasswordLineEdit(MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS_PASSWORD); - tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_FAVORITES); - tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_HISTORY); - tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_IMAGES); - tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_MUSIC); - tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_VIDEO); - tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_NETPLAY); - tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_ADD); - tabs->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_PLAYLISTS); + tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_FAVORITES); + tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_HISTORY); + tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_IMAGES); + tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_MUSIC); + tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_VIDEO); + tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_NETPLAY); + tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_ADD); + tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_PLAYLISTS); - status->addCheckBox(MENU_ENUM_LABEL_TIMEDATE_ENABLE); + status->add(MENU_ENUM_LABEL_TIMEDATE_ENABLE); status->addUIntComboBox(MENU_ENUM_LABEL_TIMEDATE_STYLE); - status->addCheckBox(MENU_ENUM_LABEL_BATTERY_LEVEL_ENABLE); - status->addCheckBox(MENU_ENUM_LABEL_CORE_ENABLE); + status->add(MENU_ENUM_LABEL_BATTERY_LEVEL_ENABLE); + status->add(MENU_ENUM_LABEL_CORE_ENABLE); - startScreen->addCheckBox(MENU_ENUM_LABEL_RGUI_SHOW_START_SCREEN); + startScreen->add(MENU_ENUM_LABEL_RGUI_SHOW_START_SCREEN); quickMenu->layout()->setContentsMargins(0, 0, 0, 0); quickMenu->addRow(quickPage->widget()); @@ -165,26 +159,26 @@ QuickMenuPage::QuickMenuPage(QObject *parent) : QWidget *QuickMenuPage::widget() { - QWidget * widget = new QWidget; + QWidget * widget = new QWidget; FormLayout *layout = new FormLayout; - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_RECORDING); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_STREAMING); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_OPTIONS); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_CONTROLS); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_CHEATS); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SHADERS); - layout->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_REWIND); - layout->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY); - layout->addCheckBox(MENU_ENUM_LABEL_CONTENT_SHOW_OVERLAYS); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES); - layout->addCheckBox(MENU_ENUM_LABEL_QUICK_MENU_SHOW_INFORMATION); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_RECORDING); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_STREAMING); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_OPTIONS); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_CONTROLS); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_CHEATS); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SHADERS); + layout->add(MENU_ENUM_LABEL_CONTENT_SHOW_REWIND); + layout->add(MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY); + layout->add(MENU_ENUM_LABEL_CONTENT_SHOW_OVERLAYS); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES); + layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_INFORMATION); widget->setLayout(layout); @@ -199,24 +193,25 @@ AppearancePage::AppearancePage(QObject *parent) : QWidget *AppearancePage::widget() { - QWidget * widget = new QWidget; - FormLayout *layout = new FormLayout; + QWidget * widget = new QWidget; + FormLayout *layout = new FormLayout; + rarch_setting_t *thumbnails = menu_setting_find_enum(MENU_ENUM_LABEL_THUMBNAILS); layout->addFileSelector(MENU_ENUM_LABEL_MENU_WALLPAPER); - layout->addCheckBox(MENU_ENUM_LABEL_DYNAMIC_WALLPAPER); + layout->add(MENU_ENUM_LABEL_DYNAMIC_WALLPAPER); layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY); layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MENU_FRAMEBUFFER_OPACITY); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_LINEAR_FILTER); + layout->add(MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT); + layout->add(MENU_ENUM_LABEL_MENU_LINEAR_FILTER); layout->addUIntComboBox(MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL); layout->addUIntComboBox(MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK); layout->addUIntComboBox(MENU_ENUM_LABEL_RGUI_MENU_COLOR_THEME); layout->addFileSelector(MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET); - layout->addCheckBox(MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE); + layout->add(MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE); layout->addUIntSpinBox(MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE); layout->addUIntSpinBox(MENU_ENUM_LABEL_XMB_ALPHA_FACTOR); layout->addUIntSpinBox(MENU_ENUM_LABEL_XMB_SCALE_FACTOR); @@ -227,35 +222,30 @@ QWidget *AppearancePage::widget() MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE); layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_LAYOUT); layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_THEME); - layout->addCheckBox(MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE); + layout->add(MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE); layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_RIBBON_ENABLE); layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME); layout->addUIntComboBox(MENU_ENUM_LABEL_OZONE_MENU_COLOR_THEME); - layout->addCheckBox(MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE); + layout->add(MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE); layout->addUIntComboBox(MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME); layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY); layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY); - layout->addCheckBox(MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME); + layout->add(MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME); + if (thumbnails) { - rarch_setting_t *thumbnails = menu_setting_find_enum(MENU_ENUM_LABEL_THUMBNAILS); + QHBoxLayout *thumbsLayout = new QHBoxLayout; + rarch_setting_t *leftThumbnails = menu_setting_find_enum(MENU_ENUM_LABEL_LEFT_THUMBNAILS); - if (thumbnails) - { - QHBoxLayout *thumbsLayout = new QHBoxLayout; + thumbsLayout->addWidget(new UIntRadioButtons(thumbnails)); - rarch_setting_t *leftThumbnails = menu_setting_find_enum(MENU_ENUM_LABEL_LEFT_THUMBNAILS); + if (leftThumbnails) + thumbsLayout->addWidget(new UIntRadioButtons(leftThumbnails)); - thumbsLayout->addWidget(new UIntRadioButtons(thumbnails)); - - if (leftThumbnails) - thumbsLayout->addWidget(new UIntRadioButtons(leftThumbnails)); - - layout->addRow(thumbsLayout); - } + layout->addRow(thumbsLayout); } - layout->addCheckBox(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS); + layout->add(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS); layout->addUIntRadioButtons(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER); layout->addUIntRadioButtons(MENU_ENUM_LABEL_MENU_TICKER_TYPE); layout->addFloatSpinBox(MENU_ENUM_LABEL_MENU_TICKER_SPEED); From 756e49d2afe224935ba297f399189b2c2d228fd2 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 23:07:34 +0200 Subject: [PATCH 193/237] (UI/QT) Dehardcode settings --- menu/menu_setting.c | 18 +++++++++++ ui/drivers/qt/options/recording.cpp | 18 +++++------ ui/drivers/qt/options/ui.cpp | 48 ++++++++++++++--------------- 3 files changed, 51 insertions(+), 33 deletions(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 15f4ff2572..777f800130 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -7504,6 +7504,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_video_record_quality; menu_settings_list_current_add_range(list, list_info, RECORD_CONFIG_TYPE_RECORDING_CUSTOM, RECORD_CONFIG_TYPE_RECORDING_GIF, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; CONFIG_PATH( list, list_info, @@ -7622,6 +7623,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint_special; menu_settings_list_current_add_range(list, list_info, 1, 8, 1, true, true); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; CONFIG_DIR( list, list_info, @@ -8461,6 +8463,7 @@ static bool setting_append_list( &setting_get_string_representation_uint_rgui_internal_upscale_level; menu_settings_list_current_add_range(list, list_info, 0, RGUI_UPSCALE_LAST-1, 1, true, true); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; } #if !defined(GEKKO) @@ -8496,6 +8499,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_rgui_aspect_ratio_lock; menu_settings_list_current_add_range(list, list_info, 0, RGUI_ASPECT_RATIO_LOCK_LAST-1, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; CONFIG_UINT( list, list_info, @@ -8512,6 +8516,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_rgui_menu_color_theme; menu_settings_list_current_add_range(list, list_info, 0, RGUI_THEME_LAST-1, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; CONFIG_PATH( list, list_info, @@ -8598,6 +8603,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_menu_ticker_type; menu_settings_list_current_add_range(list, list_info, 0, TICKER_TYPE_LAST-1, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_RADIO_BUTTONS; CONFIG_FLOAT( list, list_info, @@ -8791,6 +8797,7 @@ static bool setting_append_list( general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REINIT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_FONT_SELECTOR; CONFIG_UINT( list, list_info, @@ -8852,6 +8859,7 @@ static bool setting_append_list( &setting_get_string_representation_uint_xmb_layout; menu_settings_list_current_add_range(list, list_info, 0, 2, 1, true, true); menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REINIT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; CONFIG_UINT( list, list_info, @@ -8868,6 +8876,7 @@ static bool setting_append_list( &setting_get_string_representation_uint_xmb_icon_theme; menu_settings_list_current_add_range(list, list_info, 0, XMB_ICON_THEME_LAST - 1, 1, true, true); menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REINIT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; CONFIG_BOOL( list, list_info, @@ -8902,6 +8911,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_xmb_shader_pipeline; menu_settings_list_current_add_range(list, list_info, 0, XMB_SHADER_PIPELINE_LAST-1, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; } #endif @@ -8920,6 +8930,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_xmb_menu_color_theme; menu_settings_list_current_add_range(list, list_info, 0, XMB_THEME_LAST-1, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; } #endif if (string_is_equal(settings->arrays.menu_driver, "ozone")) @@ -9139,6 +9150,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT | SD_FLAG_LAKKA_ADVANCED); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_PASSWORD_LINE_EDIT; } #endif @@ -9306,6 +9318,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_materialui_menu_color_theme; menu_settings_list_current_add_range(list, list_info, 0, MATERIALUI_THEME_LAST-1, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; CONFIG_FLOAT( list, list_info, @@ -9336,6 +9349,8 @@ static bool setting_append_list( general_read_handler); (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; menu_settings_list_current_add_range(list, list_info, 0.0, 1.0, 0.010, true, true); + (*list)[list_info->index - 1].ui_type + = ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX; } #endif @@ -9357,6 +9372,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_ozone_menu_color_theme; menu_settings_list_current_add_range(list, list_info, 0, 1, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; CONFIG_BOOL( list, list_info, @@ -9512,6 +9528,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_rgui_thumbnail_scaler; menu_settings_list_current_add_range(list, list_info, 0, RGUI_THUMB_SCALE_LAST-1, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_RADIO_BUTTONS; CONFIG_UINT( list, list_info, @@ -9556,6 +9573,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_menu_timedate_style; menu_settings_list_current_add_range(list, list_info, 0, 7, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; CONFIG_BOOL( list, list_info, diff --git a/ui/drivers/qt/options/recording.cpp b/ui/drivers/qt/options/recording.cpp index cf8e354ff1..d78dce1b2c 100644 --- a/ui/drivers/qt/options/recording.cpp +++ b/ui/drivers/qt/options/recording.cpp @@ -23,18 +23,18 @@ RecordingPage::RecordingPage(QObject *parent) : QWidget *RecordingPage::widget() { - QWidget * widget = new QWidget; - QVBoxLayout *layout = new QVBoxLayout; + QWidget * widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; SettingsGroup *recordingGroup = new SettingsGroup("Recording"); SettingsGroup *streamingGroup = new SettingsGroup("Streaming"); - QHBoxLayout *hl = new QHBoxLayout; + QHBoxLayout *hl = new QHBoxLayout; - recordingGroup->addUIntComboBox(MENU_ENUM_LABEL_VIDEO_RECORD_QUALITY); - recordingGroup->addFileSelector(MENU_ENUM_LABEL_RECORD_CONFIG); - recordingGroup->addUIntComboBox(MENU_ENUM_LABEL_VIDEO_RECORD_THREADS); - recordingGroup->addDirectorySelector(MENU_ENUM_LABEL_RECORDING_OUTPUT_DIRECTORY); - recordingGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_POST_FILTER_RECORD); - recordingGroup->addCheckBox(MENU_ENUM_LABEL_VIDEO_GPU_RECORD); + recordingGroup->add(MENU_ENUM_LABEL_VIDEO_RECORD_QUALITY); + recordingGroup->add(MENU_ENUM_LABEL_RECORD_CONFIG); + recordingGroup->add(MENU_ENUM_LABEL_VIDEO_RECORD_THREADS); + recordingGroup->add(MENU_ENUM_LABEL_RECORDING_OUTPUT_DIRECTORY); + recordingGroup->add(MENU_ENUM_LABEL_VIDEO_POST_FILTER_RECORD); + recordingGroup->add(MENU_ENUM_LABEL_VIDEO_GPU_RECORD); hl->addWidget(new UIntRadioButtons(MENU_ENUM_LABEL_STREAMING_MODE)); hl->addWidget(new UIntRadioButtons(MENU_ENUM_LABEL_VIDEO_STREAM_QUALITY)); diff --git a/ui/drivers/qt/options/ui.cpp b/ui/drivers/qt/options/ui.cpp index bffd5bc19f..4d557e796c 100644 --- a/ui/drivers/qt/options/ui.cpp +++ b/ui/drivers/qt/options/ui.cpp @@ -115,7 +115,7 @@ QWidget *ViewsPage::widget() mainMenu->add(MENU_ENUM_LABEL_MENU_SHOW_SHUTDOWN); tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS); - tabs->addPasswordLineEdit(MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS_PASSWORD); + tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS_PASSWORD); tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_FAVORITES); tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_HISTORY); tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_IMAGES); @@ -126,7 +126,7 @@ QWidget *ViewsPage::widget() tabs->add(MENU_ENUM_LABEL_CONTENT_SHOW_PLAYLISTS); status->add(MENU_ENUM_LABEL_TIMEDATE_ENABLE); - status->addUIntComboBox(MENU_ENUM_LABEL_TIMEDATE_STYLE); + status->add(MENU_ENUM_LABEL_TIMEDATE_STYLE); status->add(MENU_ENUM_LABEL_BATTERY_LEVEL_ENABLE); status->add(MENU_ENUM_LABEL_CORE_ENABLE); @@ -197,39 +197,39 @@ QWidget *AppearancePage::widget() FormLayout *layout = new FormLayout; rarch_setting_t *thumbnails = menu_setting_find_enum(MENU_ENUM_LABEL_THUMBNAILS); - layout->addFileSelector(MENU_ENUM_LABEL_MENU_WALLPAPER); + layout->add(MENU_ENUM_LABEL_MENU_WALLPAPER); layout->add(MENU_ENUM_LABEL_DYNAMIC_WALLPAPER); - layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY); - layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MENU_FRAMEBUFFER_OPACITY); + layout->add(MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY); + layout->add(MENU_ENUM_LABEL_MENU_FRAMEBUFFER_OPACITY); layout->add(MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION); layout->add(MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE); layout->add(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE); layout->add(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE); layout->add(MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT); layout->add(MENU_ENUM_LABEL_MENU_LINEAR_FILTER); - layout->addUIntComboBox(MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL); - layout->addUIntComboBox(MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK); - layout->addUIntComboBox(MENU_ENUM_LABEL_RGUI_MENU_COLOR_THEME); - layout->addFileSelector(MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK); + layout->add(MENU_ENUM_LABEL_RGUI_MENU_COLOR_THEME); + layout->add(MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET); layout->add(MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE); - layout->addUIntSpinBox(MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE); - layout->addUIntSpinBox(MENU_ENUM_LABEL_XMB_ALPHA_FACTOR); - layout->addUIntSpinBox(MENU_ENUM_LABEL_XMB_SCALE_FACTOR); - layout->addFontSelector(MENU_ENUM_LABEL_XMB_FONT); + layout->add(MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE); + layout->add(MENU_ENUM_LABEL_XMB_ALPHA_FACTOR); + layout->add(MENU_ENUM_LABEL_XMB_SCALE_FACTOR); + layout->add(MENU_ENUM_LABEL_XMB_FONT); layout->addUIntColorButton("Menu Font Color: ", MENU_ENUM_LABEL_MENU_FONT_COLOR_RED, MENU_ENUM_LABEL_MENU_FONT_COLOR_GREEN, MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE); - layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_LAYOUT); - layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_THEME); + layout->add(MENU_ENUM_LABEL_XMB_LAYOUT); + layout->add(MENU_ENUM_LABEL_XMB_THEME); layout->add(MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE); - layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_RIBBON_ENABLE); - layout->addUIntComboBox(MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME); - layout->addUIntComboBox(MENU_ENUM_LABEL_OZONE_MENU_COLOR_THEME); + layout->add(MENU_ENUM_LABEL_XMB_RIBBON_ENABLE); + layout->add(MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME); + layout->add(MENU_ENUM_LABEL_OZONE_MENU_COLOR_THEME); layout->add(MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE); - layout->addUIntComboBox(MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME); - layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY); - layout->addFloatSliderAndSpinBox(MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY); + layout->add(MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME); + layout->add(MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY); + layout->add(MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY); layout->add(MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME); if (thumbnails) @@ -246,9 +246,9 @@ QWidget *AppearancePage::widget() } layout->add(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS); - layout->addUIntRadioButtons(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER); - layout->addUIntRadioButtons(MENU_ENUM_LABEL_MENU_TICKER_TYPE); - layout->addFloatSpinBox(MENU_ENUM_LABEL_MENU_TICKER_SPEED); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER); + layout->add(MENU_ENUM_LABEL_MENU_TICKER_TYPE); + layout->add(MENU_ENUM_LABEL_MENU_TICKER_SPEED); widget->setLayout(layout); From 060396e726320b61a01b0887a2d1618ac08cedf3 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 23:30:34 +0200 Subject: [PATCH 194/237] (UI/QT) Dehardcode more settings --- menu/menu_setting.c | 4 ++++ ui/drivers/qt/options/user.cpp | 24 ++++++++++-------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 777f800130..91ed293158 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -11045,6 +11045,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; CONFIG_STRING( list, list_info, @@ -11083,6 +11084,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_user_language; + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; #endif END_SUB_GROUP(list, list_info, parent_group); @@ -11148,6 +11150,7 @@ static bool setting_append_list( update_streaming_url_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; END_SUB_GROUP(list, list_info, parent_group); END_GROUP(list, list_info, parent_group); @@ -11174,6 +11177,7 @@ static bool setting_append_list( update_streaming_url_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; END_SUB_GROUP(list, list_info, parent_group); END_GROUP(list, list_info, parent_group); diff --git a/ui/drivers/qt/options/user.cpp b/ui/drivers/qt/options/user.cpp index a004785702..4178d4deda 100644 --- a/ui/drivers/qt/options/user.cpp +++ b/ui/drivers/qt/options/user.cpp @@ -24,12 +24,11 @@ UserPage::UserPage(QObject *parent) : QWidget *UserPage::widget() { - QWidget *widget = new QWidget; - + QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; - layout->addStringLineEdit(MENU_ENUM_LABEL_NETPLAY_NICKNAME); - layout->addUIntComboBox(MENU_ENUM_LABEL_USER_LANGUAGE); + layout->add(MENU_ENUM_LABEL_NETPLAY_NICKNAME); + layout->add(MENU_ENUM_LABEL_USER_LANGUAGE); widget->setLayout(layout); @@ -44,27 +43,24 @@ AccountsPage::AccountsPage(QObject *parent) : QWidget *AccountsPage::widget() { - QWidget *widget = new QWidget; - - QVBoxLayout *layout = new QVBoxLayout; - + QWidget *widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; SettingsGroup *youtubeGroup = new SettingsGroup(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ACCOUNTS_YOUTUBE)); - SettingsGroup *twitchGroup = new SettingsGroup(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ACCOUNTS_TWITCH)); - + SettingsGroup *twitchGroup = new SettingsGroup(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ACCOUNTS_TWITCH)); #ifdef HAVE_CHEEVOS SettingsGroup *cheevosGroup = new SettingsGroup(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS)); - cheevosGroup->addStringLineEdit(MENU_ENUM_LABEL_CHEEVOS_USERNAME); - cheevosGroup->addPasswordLineEdit(MENU_ENUM_LABEL_CHEEVOS_PASSWORD); + cheevosGroup->add(MENU_ENUM_LABEL_CHEEVOS_USERNAME); + cheevosGroup->add(MENU_ENUM_LABEL_CHEEVOS_PASSWORD); layout->addWidget(cheevosGroup); #endif - youtubeGroup->addStringLineEdit(MENU_ENUM_LABEL_YOUTUBE_STREAM_KEY); + youtubeGroup->add(MENU_ENUM_LABEL_YOUTUBE_STREAM_KEY); layout->addWidget(youtubeGroup); - twitchGroup->addStringLineEdit(MENU_ENUM_LABEL_TWITCH_STREAM_KEY); + twitchGroup->add(MENU_ENUM_LABEL_TWITCH_STREAM_KEY); layout->addWidget(twitchGroup); From 52d2b6ae94e933e1e6698d0dbc086de7fac378f9 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Apr 2019 23:34:28 +0200 Subject: [PATCH 195/237] (UI/QT) Cleanups --- menu/menu_setting.c | 3 +++ ui/drivers/qt/options/recording.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 91ed293158..448b18afc5 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -7533,6 +7533,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; CONFIG_UINT( list, list_info, @@ -7594,6 +7595,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); menu_settings_list_current_add_values(list, list_info, "cfg"); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_FILE_SELECTOR; CONFIG_STRING( list, list_info, @@ -7608,6 +7610,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; CONFIG_UINT( list, list_info, diff --git a/ui/drivers/qt/options/recording.cpp b/ui/drivers/qt/options/recording.cpp index d78dce1b2c..e829d5f20a 100644 --- a/ui/drivers/qt/options/recording.cpp +++ b/ui/drivers/qt/options/recording.cpp @@ -41,10 +41,10 @@ QWidget *RecordingPage::widget() streamingGroup->addRow(hl); - streamingGroup->addFileSelector(MENU_ENUM_LABEL_STREAM_CONFIG); - streamingGroup->addStringLineEdit(MENU_ENUM_LABEL_STREAMING_TITLE); - streamingGroup->addStringLineEdit(MENU_ENUM_LABEL_STREAMING_URL); - streamingGroup->addUIntSpinBox(MENU_ENUM_LABEL_UDP_STREAM_PORT); + streamingGroup->add(MENU_ENUM_LABEL_STREAM_CONFIG); + streamingGroup->add(MENU_ENUM_LABEL_STREAMING_TITLE); + streamingGroup->add(MENU_ENUM_LABEL_STREAMING_URL); + streamingGroup->add(MENU_ENUM_LABEL_UDP_STREAM_PORT); layout->addWidget(recordingGroup); layout->addWidget(streamingGroup); From d9723d2282059cc4fb1151a2fd56b30bf55343f0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 03:55:00 +0200 Subject: [PATCH 196/237] Make parse_settings_internal_enum a public function --- menu/menu_displaylist.c | 1006 +++++++++++++++++++-------------------- menu/menu_displaylist.h | 13 + 2 files changed, 514 insertions(+), 505 deletions(-) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 03d97d73a8..f1c880963d 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -2136,8 +2136,8 @@ static unsigned deferred_push_video_shader_parameters_common( return count; } -static int menu_displaylist_parse_settings_internal(void *data, - menu_displaylist_info_t *info, +static int menu_displaylist_parse_settings_internal( + file_list_t *info_list, enum menu_displaylist_parse_type parse_type, bool add_empty_entry, unsigned entry_type, @@ -2300,7 +2300,7 @@ static int menu_displaylist_parse_settings_internal(void *data, if (entry_type == 0) entry_type = menu_setting_set_flags(setting); - menu_entries_append(info->list, short_description, + menu_entries_append(info_list, short_description, name, entry_type, 0, 0); count++; @@ -2336,7 +2336,7 @@ loop: } if (count == 0 && add_empty_entry) - menu_entries_append_enum(info->list, + menu_entries_append_enum(info_list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), MENU_ENUM_LABEL_NO_SETTINGS_FOUND, @@ -2345,8 +2345,8 @@ loop: return 0; } -static int menu_displaylist_parse_settings_internal_enum(void *data, - menu_displaylist_info_t *info, +int menu_displaylist_parse_settings_internal_enum( + file_list_t *info_list, enum menu_displaylist_parse_type parse_type, bool add_empty_entry, rarch_setting_t *setting, @@ -2500,7 +2500,7 @@ static int menu_displaylist_parse_settings_internal_enum(void *data, goto loop; #endif - menu_entries_append_enum(info->list, short_description, + menu_entries_append_enum(info_list, short_description, name, enum_idx, menu_setting_set_flags(setting), 0, 0); count++; @@ -2538,7 +2538,7 @@ loop: if (count == 0) { if (add_empty_entry) - menu_entries_append_enum(info->list, + menu_entries_append_enum(info_list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), MENU_ENUM_LABEL_NO_SETTINGS_FOUND, @@ -2549,10 +2549,6 @@ loop: return 0; } -#define menu_displaylist_parse_settings(data, info, info_label, parse_type, add_empty_entry, entry_type) menu_displaylist_parse_settings_internal(data, info, parse_type, add_empty_entry, entry_type, menu_setting_find(info_label)) - -#define menu_displaylist_parse_settings_enum(data, info, label, parse_type, add_empty_entry) menu_displaylist_parse_settings_internal_enum(data, info, parse_type, add_empty_entry, menu_setting_find_enum(label), label) - static void menu_displaylist_set_new_playlist( menu_handle_t *menu, const char *path) { @@ -2675,7 +2671,7 @@ static int menu_displaylist_parse_load_content_settings( #endif ) { - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_STATE_SLOT, PARSE_ONLY_INT, true); menu_entries_append_enum(info->list, @@ -3317,10 +3313,10 @@ static int menu_displaylist_parse_options_cheats( msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_DELETE_ALL), MENU_ENUM_LABEL_CHEAT_DELETE_ALL, MENU_SETTING_ACTION, 0, 0); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_APPLY_AFTER_LOAD, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_APPLY_AFTER_TOGGLE, PARSE_ONLY_BOOL, false); menu_entries_append_enum(info->list, @@ -3369,9 +3365,9 @@ static int menu_displaylist_parse_options_remappings( snprintf(key_analog, sizeof(key_analog), msg_hash_to_str(MENU_ENUM_LABEL_INPUT_PLAYER_ANALOG_DPAD_MODE), val); - menu_displaylist_parse_settings(menu, info, + menu_displaylist_parse_settings(info->list, key_type, PARSE_ONLY_UINT, true, 0); - menu_displaylist_parse_settings(menu, info, + menu_displaylist_parse_settings(info->list, key_analog, PARSE_ONLY_UINT, true, 0); } @@ -4371,8 +4367,8 @@ void menu_displaylist_info_init(menu_displaylist_info_t *info) bool menu_displaylist_setting(menu_displaylist_ctx_parse_entry_t *entry) { - if (menu_displaylist_parse_settings_enum(entry->data, - entry->info, + if (menu_displaylist_parse_settings_enum( + entry->info->list, entry->enum_idx, entry->parse_type, entry->add_empty_entry) == -1) @@ -5313,31 +5309,31 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_PLAYLIST_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_HISTORY_LIST_ENABLE, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE, PARSE_ONLY_UINT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PLAYLIST_ENTRY_RENAME, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PLAYLIST_ENTRY_REMOVE, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PLAYLIST_SORT_ALPHABETICAL, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PLAYLIST_USE_OLD_FORMAT, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PLAYLIST_SHOW_INLINE_CORE_NAME, PARSE_ONLY_UINT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PLAYLIST_SHOW_SUBLABELS, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_RUNTIME_TYPE, PARSE_ONLY_UINT, false); @@ -5352,7 +5348,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist for (i = 0; i < RARCH_BIND_LIST_END; i++) { - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, (enum msg_hash_enums)( MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i), PARSE_ONLY_BIND, false); @@ -5363,38 +5359,38 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_DRIVER_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_DRIVER, PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_JOYPAD_DRIVER, PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_DRIVER, PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_DRIVER, PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER, PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CAMERA_DRIVER, PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LOCATION_DRIVER, PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_DRIVER, PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RECORD_DRIVER, PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MIDI_DRIVER, PARSE_ONLY_STRING_OPTIONS, false); #ifdef HAVE_LAKKA - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_WIFI_DRIVER, PARSE_ONLY_STRING_OPTIONS, false); #endif @@ -5404,16 +5400,16 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_CONFIGURATION_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE, PARSE_ONLY_BOOL, false); @@ -5422,46 +5418,46 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_SAVING_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SORT_SAVESTATES_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUTOSAVE_INTERVAL, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SAVESTATES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SYSTEMFILES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SCREENSHOTS_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG_AGGREGATE, PARSE_ONLY_BOOL, false); @@ -5470,23 +5466,23 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_LOGGING_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LOG_VERBOSITY, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LOG_TO_FILE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP, PARSE_ONLY_BOOL, false); { settings_t *settings = config_get_ptr(); if (settings->bools.menu_show_advanced_settings) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PERFCNT_ENABLE, PARSE_ONLY_BOOL, false); } @@ -5496,22 +5492,22 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_REWIND_SETTINGS, PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_FASTFORWARD_RATIO, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SLOWMOTION_RATIO, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE, PARSE_ONLY_BOOL, false); { settings_t *settings = config_get_ptr(); if (settings->bools.menu_show_advanced_settings) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE, PARSE_ONLY_BOOL, false); } @@ -5521,16 +5517,16 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_REWIND_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_REWIND_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_REWIND_GRANULARITY, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_REWIND_BUFFER_SIZE, PARSE_ONLY_SIZE, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_REWIND_BUFFER_SIZE_STEP, PARSE_ONLY_UINT, false); @@ -5557,71 +5553,71 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist if ( setting ) setting->max = cheat_manager_state.total_memory_size>0?cheat_manager_state.total_memory_size-1:0 ; - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_IDX, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_STATE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_DESC, PARSE_ONLY_STRING, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_HANDLER, PARSE_ONLY_UINT, false); if ( cheat_manager_state.working_cheat.handler == CHEAT_HANDLER_TYPE_EMU) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_CODE, PARSE_ONLY_STRING, false); else { - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_MEMORY_SEARCH_SIZE, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_TYPE, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_VALUE, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_ADDRESS, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_BROWSE_MEMORY, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_ADDRESS_BIT_POSITION, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_REPEAT_COUNT, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_REPEAT_ADD_TO_ADDRESS, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_REPEAT_ADD_TO_VALUE, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_RUMBLE_TYPE, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_RUMBLE_VALUE, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_RUMBLE_PORT, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_RUMBLE_PRIMARY_STRENGTH, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_RUMBLE_PRIMARY_DURATION, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_RUMBLE_SECONDARY_STRENGTH, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_RUMBLE_SECONDARY_DURATION, PARSE_ONLY_UINT, false); } @@ -5669,47 +5665,47 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_START_OR_RESTART, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_BIG_ENDIAN, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_SEARCH_LT, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_SEARCH_LTE, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_SEARCH_GT, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_SEARCH_GTE, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_SEARCH_EQ, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS, PARSE_ONLY_UINT, false); @@ -5723,11 +5719,11 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist MENU_ENUM_LABEL_CHEAT_ADD_MATCHES, MENU_SETTING_ACTION, 0, 0); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_DELETE_MATCH, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_COPY_MATCH, PARSE_ONLY_UINT, false); @@ -5743,7 +5739,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist MSG_UNKNOWN, MENU_SETTINGS_CHEAT_MATCH, 0, 0); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_BROWSE_MEMORY, PARSE_ONLY_UINT, false); @@ -5763,9 +5759,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist } case DISPLAYLIST_ONSCREEN_DISPLAY_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_ONSCREEN_OVERLAY_SETTINGS, PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_ONSCREEN_NOTIFICATIONS_SETTINGS, PARSE_ACTION, false); info->need_refresh = true; @@ -5773,55 +5769,55 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_FONT_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_FPS_SHOW, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_FRAMECOUNT_SHOW, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_STATISTICS_SHOW, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MEMORY_SHOW, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_FONT_PATH, PARSE_ONLY_PATH, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_FONT_SIZE, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_X, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_Y, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MESSAGE_COLOR_RED, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MESSAGE_COLOR_GREEN, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MESSAGE_COLOR_BLUE, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_RED, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_GREEN, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_BLUE, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MESSAGE_BGCOLOR_OPACITY, PARSE_ONLY_FLOAT, false); @@ -5830,30 +5826,30 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_ONSCREEN_OVERLAY_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_OVERLAY_ENABLE, PARSE_ONLY_BOOL, false); #if 0 - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_OVERLAY_AUTOLOAD_PREFERRED, PARSE_ONLY_BOOL, false); #endif - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_OVERLAY_HIDE_IN_MENU, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_OVERLAY_PRESET, PARSE_ONLY_PATH, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_OVERLAY_OPACITY, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_OVERLAY_SCALE, PARSE_ONLY_FLOAT, false); @@ -5862,19 +5858,19 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_MENU_FILE_BROWSER_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SHOW_HIDDEN_FILES, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_USE_BUILTIN_PLAYER, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_FILTER_BY_CURRENT_CORE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, PARSE_ONLY_BOOL, false); info->need_refresh = true; @@ -5883,102 +5879,102 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_MENU_VIEWS_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_VIEWS_SETTINGS, PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SHOW_LOAD_CORE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SHOW_LOAD_CONTENT, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SHOW_ONLINE_UPDATER, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SHOW_CORE_UPDATER, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SHOW_INFORMATION, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SHOW_CONFIGURATIONS, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SHOW_HELP, PARSE_ONLY_BOOL, false); #ifdef HAVE_QT - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SHOW_WIMP, PARSE_ONLY_UINT, false); #endif - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SHOW_QUIT_RETROARCH, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SHOW_REBOOT, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SHOW_SHUTDOWN, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS_PASSWORD, PARSE_ONLY_STRING, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_FAVORITES, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_IMAGES, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_MUSIC, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_VIDEO, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_NETPLAY, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_HISTORY, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_ADD, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_PLAYLISTS, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_TIMEDATE_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_TIMEDATE_STYLE, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_BATTERY_LEVEL_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CORE_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SHOW_SUBLABELS, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RGUI_SHOW_START_SCREEN, PARSE_ONLY_BOOL, false); @@ -5988,67 +5984,67 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_QUICK_MENU_VIEWS_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_RECORDING, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_STREAMING, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_OPTIONS, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_CONTROLS, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_CHEATS, PARSE_ONLY_BOOL, false); if (video_shader_any_supported()) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_SHADERS, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_REWIND, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SHOW_OVERLAYS, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUICK_MENU_SHOW_INFORMATION, PARSE_ONLY_BOOL, false); @@ -6058,187 +6054,187 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_MENU_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_WALLPAPER, PARSE_ONLY_PATH, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_DYNAMIC_WALLPAPER, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY, PARSE_ONLY_FLOAT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_FRAMEBUFFER_OPACITY, PARSE_ONLY_FLOAT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_LINEAR_FILTER, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RGUI_MENU_COLOR_THEME, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET, PARSE_ONLY_PATH, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_SHADOWS, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_XMB_ALPHA_FACTOR, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_XMB_SCALE_FACTOR, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_XMB_FONT, PARSE_ONLY_PATH, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_FONT_COLOR_RED, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_FONT_COLOR_GREEN, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_XMB_LAYOUT, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_XMB_THEME, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_XMB_RIBBON_ENABLE, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_OZONE_MENU_COLOR_THEME, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_OZONE_COLLAPSE_SIDEBAR, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY, PARSE_ONLY_FLOAT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY, PARSE_ONLY_FLOAT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_THUMBNAILS, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LEFT_THUMBNAILS, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_TICKER_TYPE, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_TICKER_SPEED, PARSE_ONLY_FLOAT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_RGUI_EXTENDED_ASCII, PARSE_ONLY_BOOL, false) == 0) count++; @@ -6256,7 +6252,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_POWER_MANAGEMENT_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SUSTAINED_PERFORMANCE_MODE, PARSE_ONLY_BOOL, false) == 0) count++; @@ -6274,27 +6270,27 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_MENU_SOUNDS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_ENABLE_MENU, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SOUND_OK, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SOUND_CANCEL, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SOUND_NOTICE, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SOUND_BGM, PARSE_ONLY_BOOL, false) == 0) count++; @@ -6311,60 +6307,60 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_USER_INTERFACE_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_VIEWS_SETTINGS, PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SETTINGS, PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SHOW_ADVANCED_SETTINGS, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_ENABLE_KIOSK_MODE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_KIOSK_MODE_PASSWORD, PARSE_ONLY_STRING, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NAVIGATION_WRAPAROUND, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PAUSE_LIBRETRO, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MOUSE_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_POINTER_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_THREADED_DATA_RUNLOOP_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PAUSE_NONACTIVE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_DISABLE_COMPOSITION, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_UI_COMPANION_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_UI_COMPANION_START_ON_BOOT, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_UI_MENUBAR_ENABLE, PARSE_ONLY_BOOL, false); #ifdef HAVE_QT - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_DESKTOP_MENU_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_UI_COMPANION_TOGGLE, PARSE_ONLY_BOOL, false); #endif #ifdef _3DS - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_3DS_LCD_BOTTOM, PARSE_ONLY_BOOL, false); #endif @@ -6373,31 +6369,31 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_RETRO_ACHIEVEMENTS_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEEVOS_ENABLE, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEEVOS_USERNAME, PARSE_ONLY_STRING, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEEVOS_PASSWORD, PARSE_ONLY_STRING, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEEVOS_TEST_UNOFFICIAL, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEEVOS_VERBOSE_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEEVOS_AUTO_SCREENSHOT, PARSE_ONLY_BOOL, false); @@ -6406,15 +6402,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_UPDATER_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL, PARSE_ONLY_STRING, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL, PARSE_ONLY_STRING, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, PARSE_ONLY_BOOL, false) != -1) count++; @@ -6473,71 +6469,71 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_NETWORK_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE, PARSE_ONLY_BOOL, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER, PARSE_ONLY_BOOL, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_MITM_SERVER, PARSE_ONLY_STRING, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS, PARSE_ONLY_STRING, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT, PARSE_ONLY_UINT, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_PASSWORD, PARSE_ONLY_STRING, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD, PARSE_ONLY_STRING, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR, PARSE_ONLY_BOOL, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_ALLOW_SLAVES, PARSE_ONLY_BOOL, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_REQUIRE_SLAVES, PARSE_ONLY_BOOL, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE, PARSE_ONLY_BOOL, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES, PARSE_ONLY_INT, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, PARSE_ONLY_INT, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, PARSE_ONLY_INT, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_NAT_TRAVERSAL, PARSE_ONLY_BOOL, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_SHARE_DIGITAL, PARSE_ONLY_UINT, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_SHARE_ANALOG, PARSE_ONLY_UINT, false) != -1) count++; @@ -6546,26 +6542,26 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist unsigned user; for (user = 0; user < MAX_USERS; user++) { - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, (enum msg_hash_enums)(MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1 + user), PARSE_ONLY_BOOL, false) != -1) count++; } } - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETWORK_CMD_ENABLE, PARSE_ONLY_BOOL, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETWORK_CMD_PORT, PARSE_ONLY_UINT, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETWORK_REMOTE_ENABLE, PARSE_ONLY_BOOL, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETWORK_REMOTE_PORT, PARSE_ONLY_UINT, false) != -1) count++; @@ -6575,7 +6571,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); for(user = 0; user < max_users; user++) { - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, (enum msg_hash_enums)( MENU_ENUM_LABEL_NETWORK_REMOTE_USER_1_ENABLE + user), PARSE_ONLY_BOOL, false) != -1) @@ -6583,12 +6579,12 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist } } - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_STDIN_CMD_ENABLE, PARSE_ONLY_BOOL, false) != -1) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_UPDATER_SETTINGS, PARSE_ACTION, false) != -1) count++; @@ -6605,17 +6601,17 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_LAKKA_SERVICES_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SSH_ENABLE, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SAMBA_ENABLE, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_BLUETOOTH_ENABLE, PARSE_ONLY_BOOL, false) == 0) count++; @@ -6632,19 +6628,19 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_USER_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PRIVACY_SETTINGS, PARSE_ACTION, false); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_ACCOUNTS_LIST, PARSE_ACTION, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_NICKNAME, PARSE_ONLY_STRING, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_USER_LANGUAGE, PARSE_ONLY_UINT, false) == 0) count++; @@ -6661,85 +6657,85 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_DIRECTORY_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SYSTEM_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CORE_ASSETS_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_ASSETS_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_DYNAMIC_WALLPAPERS_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RGUI_CONFIG_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LIBRETRO_DIR_PATH, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LIBRETRO_INFO_PATH, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CURSOR_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEAT_DATABASE_PATH, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_FILTER_DIR, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_FILTER_DIR, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_SHADER_DIR, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RECORDING_OUTPUT_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RECORDING_CONFIG_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_OVERLAY_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SCREENSHOT_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_JOYPAD_AUTOCONFIG_DIR, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_REMAPPING_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PLAYLIST_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RUNTIME_LOG_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SAVEFILE_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SAVESTATE_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CACHE_DIRECTORY, PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LOG_DIR, PARSE_ONLY_DIR, false); @@ -6749,15 +6745,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_PRIVACY_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CAMERA_ALLOW, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_DISCORD_ALLOW, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LOCATION_ALLOW, PARSE_ONLY_BOOL, true) == 0) count++; @@ -6775,13 +6771,13 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_MIDI_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MIDI_INPUT, PARSE_ONLY_STRING, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MIDI_OUTPUT, PARSE_ONLY_STRING, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MIDI_VOLUME, PARSE_ONLY_UINT, false); @@ -6791,16 +6787,16 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_CRT_SWITCHRES_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CRT_SWITCH_X_AXIS_CENTERING, PARSE_ONLY_INT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_USE_CUSTOM_REFRESH_RATE, PARSE_ONLY_BOOL, false); @@ -6810,10 +6806,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_VIDEO_SETTINGS_LIST: { menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CRT_SWITCHRES_SETTINGS, PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SUSPEND_SCREENSAVER_ENABLE, PARSE_ONLY_BOOL, false); #if defined(GEKKO) || defined(__CELLOS_LV2__) @@ -6822,142 +6818,142 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist if (!string_is_equal(video_display_server_get_ident(), "null")) #endif { - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SCREEN_RESOLUTION, PARSE_ACTION, false); } - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PAL60_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_GAMMA, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_SOFT_FILTER, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_FILTER_FLICKER, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MONITOR_INDEX, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_FULLSCREEN, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_WINDOWED_FULLSCREEN, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_FULLSCREEN_X, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_FULLSCREEN_Y, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_REFRESH_RATE, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_AUTO, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_FORCE_SRGB_DISABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_INDEX, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_X, PARSE_ONLY_INT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_Y, PARSE_ONLY_INT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_SCALE, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_WINDOW_SHOW_DECORATIONS, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_WINDOW_SAVE_POSITION, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_WINDOW_WIDTH, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_WINDOW_HEIGHT, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_VI_WIDTH, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_VFILTER, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_ROTATION, PARSE_ONLY_UINT, false); if (video_display_server_can_set_screen_orientation()) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SCREEN_ORIENTATION, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_THREADED, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_VSYNC, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_ADAPTIVE_VSYNC, PARSE_ONLY_BOOL, false); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_HARD_SYNC, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_FRAME_DELAY, PARSE_ONLY_UINT, false) == 0) count++; - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_CROP_OVERSCAN, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_SMOOTH, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_FILTER, PARSE_ONLY_PATH, false); @@ -6967,16 +6963,16 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist } case DISPLAYLIST_CORE_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHECK_FOR_MISSING_FIRMWARE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE, PARSE_ONLY_BOOL, false); @@ -7014,37 +7010,37 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_AUDIO_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MIDI_SETTINGS, PARSE_ACTION, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_MIXER_SETTINGS, PARSE_ACTION, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_SOUNDS, PARSE_ACTION, false) == 0) count++; - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_MUTE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_MIXER_MUTE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_VOLUME, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_MIXER_VOLUME, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SYSTEM_BGM_ENABLE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_SYNC, PARSE_ONLY_BOOL, false); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_LATENCY, PARSE_ONLY_UINT, false) == 0) count++; @@ -7052,37 +7048,37 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist settings_t *settings = config_get_ptr(); if (string_is_not_equal(settings->arrays.audio_resampler, "null")) { - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_RESAMPLER_QUALITY, PARSE_ONLY_UINT, false); count++; } } - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_RATE_CONTROL_DELTA, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_MAX_TIMING_SKEW, PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_BLOCK_FRAMES, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_DEVICE, PARSE_ONLY_STRING, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_OUTPUT_RATE, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN, PARSE_ONLY_PATH, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_WASAPI_EXCLUSIVE_MODE, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_WASAPI_FLOAT_FORMAT, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_WASAPI_SH_BUFFER_LENGTH, PARSE_ONLY_INT, false); @@ -7091,71 +7087,71 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_INPUT_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_MAX_USERS, PARSE_ONLY_UINT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_SMALL_KEYBOARD_ENABLE, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_UNIFIED_MENU_CONTROLS, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUIT_PRESS_TWICE, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIBRATE_ON_KEYPRESS, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_ENABLE_DEVICE_VIBRATION, PARSE_ONLY_BOOL, false); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR, PARSE_ONLY_UINT, false) == 0) count++; - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_ICADE_ENABLE, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, PARSE_ONLY_UINT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_TOUCH_ENABLE, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_PREFER_FRONT_TOUCH, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, PARSE_ONLY_UINT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_MENU_INPUT_SWAP_OK_CANCEL, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_ALL_USERS_CONTROL_MENU, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_REMAP_BINDS_ENABLE, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_AUTODETECT_ENABLE, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_DESCRIPTOR_LABEL_SHOW, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_DESCRIPTOR_HIDE_UNBOUND, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_BUTTON_AXIS_THRESHOLD, PARSE_ONLY_FLOAT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_ANALOG_DEADZONE, PARSE_ONLY_FLOAT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_ANALOG_SENSITIVITY, PARSE_ONLY_FLOAT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_BIND_TIMEOUT, PARSE_ONLY_UINT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_BIND_HOLD, PARSE_ONLY_UINT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_TURBO_PERIOD, PARSE_ONLY_UINT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_DUTY_CYCLE, PARSE_ONLY_UINT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_BIND_MODE, PARSE_ONLY_UINT, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_HOTKEY_BINDS, PARSE_ACTION, false); #ifdef HAVE_LIBNX @@ -7173,7 +7169,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist "%s_%u", msg_hash_to_str(MENU_ENUM_LABEL_INPUT_SPLIT_JOYCON), val); - menu_displaylist_parse_settings(menu, info, + menu_displaylist_parse_settings(info->list, key_split_joycon, PARSE_ONLY_UINT, true, 0); } } @@ -7184,7 +7180,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); for (user = 0; user < max_users; user++) { - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, (enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_USER_1_BINDS + user), PARSE_ACTION, false); } @@ -7197,48 +7193,48 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_LATENCY_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_HARD_SYNC, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_FRAME_DELAY, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_LATENCY, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RUN_AHEAD_ENABLED, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RUN_AHEAD_FRAMES, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RUN_AHEAD_HIDE_WARNINGS, PARSE_ONLY_BOOL, false) == 0) count++; #ifdef ANDROID - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_BLOCK_TIMEOUT, PARSE_ONLY_UINT, false) == 0) count++; @@ -7255,53 +7251,53 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_SETTINGS_ALL: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_DRIVER_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_AUDIO_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INPUT_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LATENCY_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CORE_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONFIGURATION_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SAVING_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LOGGING_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_FRAME_THROTTLE_SETTINGS, PARSE_ACTION, false); { settings_t *settings = config_get_ptr(); if (string_is_not_equal(settings->arrays.record_driver, "null")) - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RECORDING_SETTINGS, PARSE_ACTION, false); } - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_ONSCREEN_DISPLAY_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_USER_INTERFACE_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_POWER_MANAGEMENT_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RETRO_ACHIEVEMENTS_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_WIFI_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETWORK_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY_LAN_SCAN_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LAKKA_SERVICES, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_PLAYLIST_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_USER_SETTINGS, PARSE_ACTION, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + ret = menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_DIRECTORY_SETTINGS, PARSE_ACTION, false); info->need_push = true; break; @@ -7604,51 +7600,51 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist { settings_t *settings = config_get_ptr(); menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_RECORD_QUALITY, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RECORD_CONFIG, PARSE_ONLY_PATH, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_STREAM_QUALITY, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_STREAM_CONFIG, PARSE_ONLY_PATH, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_STREAMING_MODE, PARSE_ONLY_UINT, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_RECORD_THREADS, PARSE_ONLY_UINT, true) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_STREAMING_TITLE, PARSE_ONLY_STRING, false) == 0) count++; if (settings->uints.streaming_mode == STREAMING_MODE_LOCAL) { /* To-Do: Refresh on settings->uints.streaming_mode change to show this parameter */ - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_UDP_STREAM_PORT, PARSE_ONLY_UINT, false) == 0) count++; } - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_STREAMING_URL, PARSE_ONLY_STRING, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_GPU_RECORD, PARSE_ONLY_BOOL, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_POST_FILTER_RECORD, PARSE_ONLY_BOOL, false) == 0) count++; @@ -7678,12 +7674,12 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist !string_is_equal(system->library_name, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_CORE))) if (!rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL)) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONTENT_SETTINGS, PARSE_ACTION, false); if (sys_info->load_no_content) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_START_CORE, PARSE_ACTION, false); } @@ -7693,14 +7689,14 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist { if (settings->bools.menu_show_load_core) { - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CORE_LIST, PARSE_ACTION, false); } } if (settings->bools.menu_show_load_content) { - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LOAD_CONTENT_LIST, PARSE_ACTION, false); @@ -7715,7 +7711,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist } if (settings->bools.menu_content_show_history) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY, PARSE_ACTION, false); #ifdef HAVE_LIBRETRODB @@ -7729,53 +7725,53 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist } #endif if (settings->bools.menu_content_show_add) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_ADD_CONTENT_LIST, PARSE_ACTION, false); if (settings->bools.menu_content_show_netplay) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_NETPLAY, PARSE_ACTION, false); if (settings->bools.menu_show_online_updater) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_ONLINE_UPDATER, PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SETTINGS, PARSE_ACTION, false); if (settings->bools.menu_show_information) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_INFORMATION_LIST, PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_RESTART_RETROARCH, PARSE_ACTION, false); if (settings->bools.menu_show_configurations) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CONFIGURATIONS_LIST, PARSE_ACTION, false); if (settings->bools.menu_show_help) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_HELP_LIST, PARSE_ACTION, false); if (settings->bools.menu_show_quit_retroarch) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_QUIT_RETROARCH, PARSE_ACTION, false); #ifdef HAVE_LAKKA_SWITCH - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SWITCH_GPU_PROFILE, PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SWITCH_BACKLIGHT_CONTROL, PARSE_ACTION, false); #endif if (settings->bools.menu_show_reboot) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_REBOOT, PARSE_ACTION, false); if (settings->bools.menu_show_shutdown) - menu_displaylist_parse_settings_enum(menu, info, + menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_SHUTDOWN, PARSE_ACTION, false); info->need_push = true; @@ -7872,18 +7868,18 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_ACCOUNTS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, PARSE_ACTION, false) == 0) count++; #ifdef HAVE_NETWORKING - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_ACCOUNTS_YOUTUBE, PARSE_ACTION, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_ACCOUNTS_TWITCH, PARSE_ACTION, false) == 0) count++; @@ -7903,11 +7899,11 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_ACCOUNTS_CHEEVOS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEEVOS_USERNAME, PARSE_ONLY_STRING, false) == 0) count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_CHEEVOS_PASSWORD, PARSE_ONLY_STRING, false) == 0) count++; @@ -7926,7 +7922,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_ACCOUNTS_YOUTUBE_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_YOUTUBE_STREAM_KEY, PARSE_ONLY_STRING, false) == 0) count++; @@ -7945,7 +7941,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_ACCOUNTS_TWITCH_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_TWITCH_STREAM_KEY, PARSE_ONLY_STRING, false) == 0) count++; @@ -8012,7 +8008,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist lbl[0] = '\0'; strlcpy(lbl, temp_val, sizeof(lbl)); - ret = menu_displaylist_parse_settings(menu, info, + ret = menu_displaylist_parse_settings(info->list, lbl, PARSE_NONE, true, MENU_SETTINGS_INPUT_BEGIN); info->need_refresh = true; info->need_push = true; diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index 1be1b853be..0c42a8d72c 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -23,6 +23,7 @@ #include #include +#include "../msg_hash.h" #include "../setting_list.h" #ifndef COLLECTION_SIZE @@ -261,6 +262,18 @@ bool menu_displaylist_setting(menu_displaylist_ctx_parse_entry_t *entry); void netplay_refresh_rooms_menu(file_list_t *list); #endif +int menu_displaylist_parse_settings_internal_enum( + file_list_t *list, + enum menu_displaylist_parse_type parse_type, + bool add_empty_entry, + rarch_setting_t *setting, + enum msg_hash_enums enum_idx + ); + +#define menu_displaylist_parse_settings_enum(list, label, parse_type, add_empty_entry) menu_displaylist_parse_settings_internal_enum(list, parse_type, add_empty_entry, menu_setting_find_enum(label), label) + +#define menu_displaylist_parse_settings(info_list, info_label, parse_type, add_empty_entry, entry_type) menu_displaylist_parse_settings_internal(info_list, parse_type, add_empty_entry, entry_type, menu_setting_find(info_label)) + RETRO_END_DECLS #endif From b38a4dcb08ccecbab5cb78834c418a27388b3468 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 04:26:19 +0200 Subject: [PATCH 197/237] (UI/QT) Make some of the add functions private --- menu/menu_setting.c | 1 + ui/drivers/qt/options/ui.cpp | 2 +- ui/drivers/qt/settingswidgets.cpp | 16 +++++-------- ui/drivers/qt/settingswidgets.h | 40 +++++++++++++++---------------- 4 files changed, 28 insertions(+), 31 deletions(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 448b18afc5..ad1cfb6a64 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -8691,6 +8691,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_PASSWORD_LINE_EDIT; } #ifdef HAVE_THREADS diff --git a/ui/drivers/qt/options/ui.cpp b/ui/drivers/qt/options/ui.cpp index 4d557e796c..87ab40bbfa 100644 --- a/ui/drivers/qt/options/ui.cpp +++ b/ui/drivers/qt/options/ui.cpp @@ -49,7 +49,7 @@ QWidget *UserInterfacePage::widget() { CheckableSettingsGroup *kioskGroup = new CheckableSettingsGroup(kioskMode, widget); - kioskGroup->addPasswordLineEdit(MENU_ENUM_LABEL_MENU_KIOSK_MODE_PASSWORD); + kioskGroup->add(MENU_ENUM_LABEL_MENU_KIOSK_MODE_PASSWORD); menuGroup->addRow(kioskGroup); } diff --git a/ui/drivers/qt/settingswidgets.cpp b/ui/drivers/qt/settingswidgets.cpp index 6454c4fe7d..91d8ada10f 100644 --- a/ui/drivers/qt/settingswidgets.cpp +++ b/ui/drivers/qt/settingswidgets.cpp @@ -65,10 +65,8 @@ FormLayout::FormLayout(QWidget *parent) : { } -void FormLayout::addCheckBox(msg_hash_enums enum_idx) +void FormLayout::addCheckBox(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(new CheckBox(setting)); } @@ -129,10 +127,8 @@ void FormLayout::addSizeSpinBox(msg_hash_enums enum_idx, unsigned scale) addRow(formLabel(setting), new SizeSpinBox(setting, scale)); } -void FormLayout::addFloatSpinBox(msg_hash_enums enum_idx) +void FormLayout::addFloatSpinBox(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(formLabel(setting), new FloatSpinBox(setting)); } @@ -228,9 +224,9 @@ void SettingsGroup::addRow(QString label, QLayout *layout) m_layout->addRow(label, layout); } -void SettingsGroup::addCheckBox(msg_hash_enums enum_idx) +void SettingsGroup::addCheckBox(rarch_setting_t *setting) { - m_layout->addCheckBox(enum_idx); + m_layout->addCheckBox(setting); } void SettingsGroup::addDirectorySelector(msg_hash_enums enum_idx) @@ -278,9 +274,9 @@ void SettingsGroup::addUIntSpinBox(msg_hash_enums enum_idx) m_layout->addUIntSpinBox(enum_idx); } -void SettingsGroup::addFloatSpinBox(msg_hash_enums enum_idx) +void SettingsGroup::addFloatSpinBox(rarch_setting_t *setting) { - m_layout->addFloatSpinBox(enum_idx); + m_layout->addFloatSpinBox(setting); } void SettingsGroup::addFloatSliderAndSpinBox(msg_hash_enums enum_idx) diff --git a/ui/drivers/qt/settingswidgets.h b/ui/drivers/qt/settingswidgets.h index 201233d97e..e417b03cf7 100644 --- a/ui/drivers/qt/settingswidgets.h +++ b/ui/drivers/qt/settingswidgets.h @@ -34,20 +34,20 @@ class FormLayout : public QFormLayout { public: FormLayout(QWidget *parent = 0); - void addUIntSpinBox(msg_hash_enums enum_idx); void addSizeSpinBox(msg_hash_enums enum_idx, unsigned scale = 1024 * 1024); - void addFloatSpinBox(msg_hash_enums enum_idx); + void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b); + void addUIntSpinBox(msg_hash_enums enum_idx); + void addFloatSpinBox(rarch_setting_t *setting); void addDirectorySelector(msg_hash_enums enum_idx); void addFileSelector(msg_hash_enums enum_idx); void addFontSelector(msg_hash_enums enum_idx); - void addCheckBox(msg_hash_enums enum_idx); + void addCheckBox(rarch_setting_t *setting); void addUIntComboBox(msg_hash_enums enum_idx); void addUIntRadioButtons(msg_hash_enums enum_idx); void addStringComboBox(msg_hash_enums enum_idx); void addStringLineEdit(msg_hash_enums enum_idx); void addPasswordLineEdit(msg_hash_enums enum_idx); void addFloatSliderAndSpinBox(msg_hash_enums enum_idx); - void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b); bool addBindButton(msg_hash_enums enum_idx); bool add(msg_hash_enums enum_idx) @@ -63,7 +63,7 @@ public: switch (ui_type) { case ST_UI_TYPE_CHECKBOX: - this->addCheckBox(enum_idx); + this->addCheckBox(setting); break; case ST_UI_TYPE_UINT_COLOR_BUTTON: /* TODO/FIXME */ @@ -81,7 +81,7 @@ public: /* TODO/FIXME */ break; case ST_UI_TYPE_FLOAT_SPINBOX: - this->addFloatSpinBox(enum_idx); + this->addFloatSpinBox(setting); break; case ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX: this->addFloatSliderAndSpinBox(enum_idx); @@ -129,18 +129,6 @@ public: void addRow(QWidget *widget); void addRow(QLayout *layout); void addRow(QString label, QLayout *layout); - void addCheckBox(msg_hash_enums enum_idx); - void addFileSelector(msg_hash_enums enum_idx); - void addDirectorySelector(msg_hash_enums enum_idx); - void addFontSelector(msg_hash_enums enum_idx); - void addStringLineEdit(msg_hash_enums enum_idx); - void addPasswordLineEdit(msg_hash_enums enum_idx); - void addStringComboBox(msg_hash_enums enum_idx); - void addUIntSpinBox(msg_hash_enums enum_idx); - void addUIntComboBox(msg_hash_enums enum_idx); - void addUIntRadioButtons(msg_hash_enums enum_idx); - void addFloatSpinBox(msg_hash_enums enum_idx); - void addFloatSliderAndSpinBox(msg_hash_enums enum_idx); void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b); void addBindButton(msg_hash_enums enum_idx); @@ -157,7 +145,7 @@ public: switch (ui_type) { case ST_UI_TYPE_CHECKBOX: - this->addCheckBox(enum_idx); + this->addCheckBox(setting); break; case ST_UI_TYPE_UINT_COLOR_BUTTON: /* TODO/FIXME */ @@ -175,7 +163,7 @@ public: /* TODO/FIXME */ break; case ST_UI_TYPE_FLOAT_SPINBOX: - this->addFloatSpinBox(enum_idx); + this->addFloatSpinBox(setting); break; case ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX: this->addFloatSliderAndSpinBox(enum_idx); @@ -214,6 +202,18 @@ public: return true; } private: + void addCheckBox(rarch_setting_t *setting); + void addFileSelector(msg_hash_enums enum_idx); + void addDirectorySelector(msg_hash_enums enum_idx); + void addFontSelector(msg_hash_enums enum_idx); + void addStringLineEdit(msg_hash_enums enum_idx); + void addPasswordLineEdit(msg_hash_enums enum_idx); + void addStringComboBox(msg_hash_enums enum_idx); + void addUIntSpinBox(msg_hash_enums enum_idx); + void addUIntComboBox(msg_hash_enums enum_idx); + void addUIntRadioButtons(msg_hash_enums enum_idx); + void addFloatSpinBox(rarch_setting_t *setting); + void addFloatSliderAndSpinBox(msg_hash_enums enum_idx); FormLayout *m_layout; }; From 29ca98c10c044497a60a45e56062f7670d0bf704 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 05:13:40 +0200 Subject: [PATCH 198/237] (UI/QT) Prevent unnecessary costly functions --- ui/drivers/qt/settingswidgets.cpp | 92 ++++++++++++------------------- ui/drivers/qt/settingswidgets.h | 92 +++++++++++++++---------------- 2 files changed, 80 insertions(+), 104 deletions(-) diff --git a/ui/drivers/qt/settingswidgets.cpp b/ui/drivers/qt/settingswidgets.cpp index 91d8ada10f..40b0b1e3ec 100644 --- a/ui/drivers/qt/settingswidgets.cpp +++ b/ui/drivers/qt/settingswidgets.cpp @@ -71,58 +71,44 @@ void FormLayout::addCheckBox(rarch_setting_t *setting) addRow(new CheckBox(setting)); } -void FormLayout::addUIntRadioButtons(msg_hash_enums enum_idx) +void FormLayout::addUIntRadioButtons(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(new UIntRadioButtons(setting)); } -void FormLayout::addUIntComboBox(msg_hash_enums enum_idx) +void FormLayout::addUIntComboBox(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(formLabel(setting), new UIntComboBox(setting)); } -void FormLayout::addStringComboBox(msg_hash_enums enum_idx) +void FormLayout::addStringComboBox(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(formLabel(setting), new StringComboBox(setting)); } -void FormLayout::addStringLineEdit(msg_hash_enums enum_idx) +void FormLayout::addStringLineEdit(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(formLabel(setting), new StringLineEdit(setting)); } -void FormLayout::addPasswordLineEdit(msg_hash_enums enum_idx) +void FormLayout::addPasswordLineEdit(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(formLabel(setting), new PasswordLineEdit(setting)); } -void FormLayout::addUIntSpinBox(msg_hash_enums enum_idx) +void FormLayout::addUIntSpinBox(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(formLabel(setting), new UIntSpinBox(setting)); } -void FormLayout::addSizeSpinBox(msg_hash_enums enum_idx, unsigned scale) +void FormLayout::addSizeSpinBox(rarch_setting_t *setting, unsigned scale) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(formLabel(setting), new SizeSpinBox(setting, scale)); } @@ -133,34 +119,26 @@ void FormLayout::addFloatSpinBox(rarch_setting_t *setting) addRow(formLabel(setting), new FloatSpinBox(setting)); } -void FormLayout::addDirectorySelector(msg_hash_enums enum_idx) +void FormLayout::addDirectorySelector(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(formLabel(setting), new DirectorySelector(setting)); } -void FormLayout::addFileSelector(msg_hash_enums enum_idx) +void FormLayout::addFileSelector(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(formLabel(setting), new FileSelector(setting)); } -void FormLayout::addFontSelector(msg_hash_enums enum_idx) +void FormLayout::addFontSelector(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(formLabel(setting), new FontSelector(setting)); } -void FormLayout::addFloatSliderAndSpinBox(msg_hash_enums enum_idx) +void FormLayout::addFloatSliderAndSpinBox(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (setting && setting->short_description) addRow(formLabel(setting), new FloatSliderAndSpinBox(setting)); } @@ -175,10 +153,8 @@ void FormLayout::addUIntColorButton(const QString &title, msg_hash_enums r, msg_ addRow(title, new UIntColorButton(red, green, blue)); } -bool FormLayout::addBindButton(msg_hash_enums enum_idx) +bool FormLayout::addBindButton(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); - if (!setting || !setting->short_description) return false; @@ -229,49 +205,49 @@ void SettingsGroup::addCheckBox(rarch_setting_t *setting) m_layout->addCheckBox(setting); } -void SettingsGroup::addDirectorySelector(msg_hash_enums enum_idx) +void SettingsGroup::addDirectorySelector(rarch_setting_t *setting) { - m_layout->addDirectorySelector(enum_idx); + m_layout->addDirectorySelector(setting); } -void SettingsGroup::addFileSelector(msg_hash_enums enum_idx) +void SettingsGroup::addFileSelector(rarch_setting_t *setting) { - m_layout->addFileSelector(enum_idx); + m_layout->addFileSelector(setting); } -void SettingsGroup::addFontSelector(msg_hash_enums enum_idx) +void SettingsGroup::addFontSelector(rarch_setting_t *setting) { - m_layout->addFontSelector(enum_idx); + m_layout->addFontSelector(setting); } -void SettingsGroup::addStringLineEdit(msg_hash_enums enum_idx) +void SettingsGroup::addStringLineEdit(rarch_setting_t *setting) { - m_layout->addStringLineEdit(enum_idx); + m_layout->addStringLineEdit(setting); } -void SettingsGroup::addPasswordLineEdit(msg_hash_enums enum_idx) +void SettingsGroup::addPasswordLineEdit(rarch_setting_t *setting) { - m_layout->addPasswordLineEdit(enum_idx); + m_layout->addPasswordLineEdit(setting); } -void SettingsGroup::addStringComboBox(msg_hash_enums enum_idx) +void SettingsGroup::addStringComboBox(rarch_setting_t *setting) { - m_layout->addStringComboBox(enum_idx); + m_layout->addStringComboBox(setting); } -void SettingsGroup::addUIntComboBox(msg_hash_enums enum_idx) +void SettingsGroup::addUIntComboBox(rarch_setting_t *setting) { - m_layout->addUIntComboBox(enum_idx); + m_layout->addUIntComboBox(setting); } -void SettingsGroup::addUIntRadioButtons(msg_hash_enums enum_idx) +void SettingsGroup::addUIntRadioButtons(rarch_setting_t *setting) { - m_layout->addUIntRadioButtons(enum_idx); + m_layout->addUIntRadioButtons(setting); } -void SettingsGroup::addUIntSpinBox(msg_hash_enums enum_idx) +void SettingsGroup::addUIntSpinBox(rarch_setting_t *setting) { - m_layout->addUIntSpinBox(enum_idx); + m_layout->addUIntSpinBox(setting); } void SettingsGroup::addFloatSpinBox(rarch_setting_t *setting) @@ -279,9 +255,9 @@ void SettingsGroup::addFloatSpinBox(rarch_setting_t *setting) m_layout->addFloatSpinBox(setting); } -void SettingsGroup::addFloatSliderAndSpinBox(msg_hash_enums enum_idx) +void SettingsGroup::addFloatSliderAndSpinBox(rarch_setting_t *setting) { - m_layout->addFloatSliderAndSpinBox(enum_idx); + m_layout->addFloatSliderAndSpinBox(setting); } void SettingsGroup::addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b) @@ -289,9 +265,9 @@ void SettingsGroup::addUIntColorButton(const QString &title, msg_hash_enums r, m m_layout->addUIntColorButton(title, r, g, b); } -void SettingsGroup::addBindButton(msg_hash_enums enum_idx) +void SettingsGroup::addBindButton(rarch_setting_t *setting) { - m_layout->addBindButton(enum_idx); + m_layout->addBindButton(setting); } CheckBox::CheckBox(rarch_setting_t *setting, QWidget *parent) : diff --git a/ui/drivers/qt/settingswidgets.h b/ui/drivers/qt/settingswidgets.h index e417b03cf7..efddef7f68 100644 --- a/ui/drivers/qt/settingswidgets.h +++ b/ui/drivers/qt/settingswidgets.h @@ -34,21 +34,21 @@ class FormLayout : public QFormLayout { public: FormLayout(QWidget *parent = 0); - void addSizeSpinBox(msg_hash_enums enum_idx, unsigned scale = 1024 * 1024); + void addSizeSpinBox(rarch_setting_t *setting, unsigned scale = 1024 * 1024); void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b); - void addUIntSpinBox(msg_hash_enums enum_idx); + void addUIntSpinBox(rarch_setting_t *setting); void addFloatSpinBox(rarch_setting_t *setting); - void addDirectorySelector(msg_hash_enums enum_idx); - void addFileSelector(msg_hash_enums enum_idx); - void addFontSelector(msg_hash_enums enum_idx); void addCheckBox(rarch_setting_t *setting); - void addUIntComboBox(msg_hash_enums enum_idx); - void addUIntRadioButtons(msg_hash_enums enum_idx); - void addStringComboBox(msg_hash_enums enum_idx); - void addStringLineEdit(msg_hash_enums enum_idx); - void addPasswordLineEdit(msg_hash_enums enum_idx); - void addFloatSliderAndSpinBox(msg_hash_enums enum_idx); - bool addBindButton(msg_hash_enums enum_idx); + void addUIntComboBox(rarch_setting_t *setting); + bool addBindButton(rarch_setting_t *setting); + void addFileSelector(rarch_setting_t *setting); + void addDirectorySelector(rarch_setting_t *setting); + void addFloatSliderAndSpinBox(rarch_setting_t *setting); + void addFontSelector(rarch_setting_t *setting); + void addUIntRadioButtons(rarch_setting_t *setting); + void addStringComboBox(rarch_setting_t *setting); + void addStringLineEdit(rarch_setting_t *setting); + void addPasswordLineEdit(rarch_setting_t *setting); bool add(msg_hash_enums enum_idx) { @@ -69,13 +69,13 @@ public: /* TODO/FIXME */ break; case ST_UI_TYPE_UINT_SPINBOX: - this->addUIntSpinBox(enum_idx); + this->addUIntSpinBox(setting); break; case ST_UI_TYPE_UINT_COMBOBOX: - this->addUIntComboBox(enum_idx); + this->addUIntComboBox(setting); break; case ST_UI_TYPE_UINT_RADIO_BUTTONS: - this->addUIntRadioButtons(enum_idx); + this->addUIntRadioButtons(setting); break; case ST_UI_TYPE_FLOAT_COLOR_BUTTON: /* TODO/FIXME */ @@ -84,30 +84,30 @@ public: this->addFloatSpinBox(setting); break; case ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX: - this->addFloatSliderAndSpinBox(enum_idx); + this->addFloatSliderAndSpinBox(setting); break; case ST_UI_TYPE_SIZE_SPINBOX: - this->addSizeSpinBox(enum_idx); + this->addSizeSpinBox(setting); break; case ST_UI_TYPE_BIND_BUTTON: - return this->addBindButton(enum_idx); + return this->addBindButton(setting); case ST_UI_TYPE_DIRECTORY_SELECTOR: - this->addDirectorySelector(enum_idx); + this->addDirectorySelector(setting); break; case ST_UI_TYPE_FILE_SELECTOR: - this->addFileSelector(enum_idx); + this->addFileSelector(setting); break; case ST_UI_TYPE_FONT_SELECTOR: - this->addFontSelector(enum_idx); + this->addFontSelector(setting); break; case ST_UI_TYPE_STRING_COMBOBOX: - this->addStringComboBox(enum_idx); + this->addStringComboBox(setting); break; case ST_UI_TYPE_STRING_LINE_EDIT: - this->addStringLineEdit(enum_idx); + this->addStringLineEdit(setting); break; case ST_UI_TYPE_PASSWORD_LINE_EDIT: - this->addPasswordLineEdit(enum_idx); + this->addPasswordLineEdit(setting); break; case ST_UI_TYPE_NONE: default: @@ -130,7 +130,6 @@ public: void addRow(QLayout *layout); void addRow(QString label, QLayout *layout); void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b); - void addBindButton(msg_hash_enums enum_idx); bool add(msg_hash_enums enum_idx) { @@ -151,13 +150,13 @@ public: /* TODO/FIXME */ break; case ST_UI_TYPE_UINT_SPINBOX: - this->addUIntSpinBox(enum_idx); + this->addUIntSpinBox(setting); break; case ST_UI_TYPE_UINT_COMBOBOX: - this->addUIntComboBox(enum_idx); + this->addUIntComboBox(setting); break; case ST_UI_TYPE_UINT_RADIO_BUTTONS: - this->addUIntRadioButtons(enum_idx); + this->addUIntRadioButtons(setting); break; case ST_UI_TYPE_FLOAT_COLOR_BUTTON: /* TODO/FIXME */ @@ -166,7 +165,7 @@ public: this->addFloatSpinBox(setting); break; case ST_UI_TYPE_FLOAT_SLIDER_AND_SPINBOX: - this->addFloatSliderAndSpinBox(enum_idx); + this->addFloatSliderAndSpinBox(setting); break; case ST_UI_TYPE_SIZE_SPINBOX: /* TODO/FIXME */ @@ -174,25 +173,25 @@ public: case ST_UI_TYPE_BIND_BUTTON: /* TODO/FIXME - Why is the returntype void here and bool * for Layout? */ - this->addBindButton(enum_idx); + this->addBindButton(setting); break; case ST_UI_TYPE_DIRECTORY_SELECTOR: - this->addDirectorySelector(enum_idx); + this->addDirectorySelector(setting); break; case ST_UI_TYPE_FILE_SELECTOR: - this->addFileSelector(enum_idx); + this->addFileSelector(setting); break; case ST_UI_TYPE_FONT_SELECTOR: - this->addFontSelector(enum_idx); + this->addFontSelector(setting); break; case ST_UI_TYPE_STRING_COMBOBOX: - this->addStringComboBox(enum_idx); + this->addStringComboBox(setting); break; case ST_UI_TYPE_STRING_LINE_EDIT: - this->addStringLineEdit(enum_idx); + this->addStringLineEdit(setting); break; case ST_UI_TYPE_PASSWORD_LINE_EDIT: - this->addPasswordLineEdit(enum_idx); + this->addPasswordLineEdit(setting); break; case ST_UI_TYPE_NONE: default: @@ -202,18 +201,19 @@ public: return true; } private: + void addBindButton(rarch_setting_t *setting); void addCheckBox(rarch_setting_t *setting); - void addFileSelector(msg_hash_enums enum_idx); - void addDirectorySelector(msg_hash_enums enum_idx); - void addFontSelector(msg_hash_enums enum_idx); - void addStringLineEdit(msg_hash_enums enum_idx); - void addPasswordLineEdit(msg_hash_enums enum_idx); - void addStringComboBox(msg_hash_enums enum_idx); - void addUIntSpinBox(msg_hash_enums enum_idx); - void addUIntComboBox(msg_hash_enums enum_idx); - void addUIntRadioButtons(msg_hash_enums enum_idx); + void addUIntSpinBox(rarch_setting_t *setting); + void addUIntComboBox(rarch_setting_t *setting); void addFloatSpinBox(rarch_setting_t *setting); - void addFloatSliderAndSpinBox(msg_hash_enums enum_idx); + void addFileSelector(rarch_setting_t *setting); + void addDirectorySelector(rarch_setting_t *setting); + void addFloatSliderAndSpinBox(rarch_setting_t *setting); + void addFontSelector(rarch_setting_t *setting); + void addUIntRadioButtons(rarch_setting_t *setting); + void addStringComboBox(rarch_setting_t *setting); + void addStringLineEdit(rarch_setting_t *setting); + void addPasswordLineEdit(rarch_setting_t *setting); FormLayout *m_layout; }; From 1599f1f5d3a85c71c8dbfb189a95eb714b7e2f8b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 05:18:30 +0200 Subject: [PATCH 199/237] (UI/QT) Create overloaded 'add' function --- ui/drivers/qt/settingswidgets.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/ui/drivers/qt/settingswidgets.h b/ui/drivers/qt/settingswidgets.h index efddef7f68..70ea3d8ee9 100644 --- a/ui/drivers/qt/settingswidgets.h +++ b/ui/drivers/qt/settingswidgets.h @@ -50,9 +50,8 @@ public: void addStringLineEdit(rarch_setting_t *setting); void addPasswordLineEdit(rarch_setting_t *setting); - bool add(msg_hash_enums enum_idx) + bool add(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); enum ui_setting_type ui_type = ST_UI_TYPE_NONE; if (!setting) @@ -116,6 +115,12 @@ public: return true; } + + bool add(msg_hash_enums enum_idx) + { + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + return add(setting); + } }; class SettingsGroup : public QGroupBox @@ -131,9 +136,8 @@ public: void addRow(QString label, QLayout *layout); void addUIntColorButton(const QString &title, msg_hash_enums r, msg_hash_enums g, msg_hash_enums b); - bool add(msg_hash_enums enum_idx) + bool add(rarch_setting_t *setting) { - rarch_setting_t *setting = menu_setting_find_enum(enum_idx); enum ui_setting_type ui_type = ST_UI_TYPE_NONE; if (!setting) @@ -200,6 +204,12 @@ public: return true; } + + bool add(msg_hash_enums enum_idx) + { + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + return add(setting); + } private: void addBindButton(rarch_setting_t *setting); void addCheckBox(rarch_setting_t *setting); From 085f25e81f2c3eea8a4b8f2215cbeba3c5144f54 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 06:16:55 +0200 Subject: [PATCH 200/237] (UI/QT) First attempt at dynamically generating settings instead of manually specifying settings --- menu/menu_displaylist.c | 384 ++++++++++++++++++----------------- menu/menu_displaylist.h | 2 + menu/menu_setting.c | 2 + ui/drivers/qt/options/ui.cpp | 45 +++- 4 files changed, 248 insertions(+), 185 deletions(-) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index f1c880963d..127ab7e50d 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4376,6 +4376,205 @@ bool menu_displaylist_setting(menu_displaylist_ctx_parse_entry_t *entry) return true; } +unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ctl_state type) +{ + unsigned count = 0; + + switch (type) + { + case DISPLAYLIST_MENU_SETTINGS_LIST: + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_WALLPAPER, + PARSE_ONLY_PATH, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_DYNAMIC_WALLPAPER, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY, + PARSE_ONLY_FLOAT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_FRAMEBUFFER_OPACITY, + PARSE_ONLY_FLOAT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_LINEAR_FILTER, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_RGUI_MENU_COLOR_THEME, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET, + PARSE_ONLY_PATH, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_SHADOWS, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_XMB_ALPHA_FACTOR, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_XMB_SCALE_FACTOR, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_XMB_FONT, + PARSE_ONLY_PATH, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_FONT_COLOR_RED, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_FONT_COLOR_GREEN, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_XMB_LAYOUT, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_XMB_THEME, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_XMB_RIBBON_ENABLE, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_OZONE_MENU_COLOR_THEME, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_OZONE_COLLAPSE_SIDEBAR, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY, + PARSE_ONLY_FLOAT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY, + PARSE_ONLY_FLOAT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_THUMBNAILS, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_LEFT_THUMBNAILS, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_TICKER_TYPE, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_TICKER_SPEED, + PARSE_ONLY_FLOAT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_RGUI_EXTENDED_ASCII, + PARSE_ONLY_BOOL, false) == 0) + count++; + break; + default: + break; + } + + return count; +} + bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist_info_t *info) { size_t i; @@ -6054,190 +6253,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_MENU_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_WALLPAPER, - PARSE_ONLY_PATH, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_DYNAMIC_WALLPAPER, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY, - PARSE_ONLY_FLOAT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_FRAMEBUFFER_OPACITY, - PARSE_ONLY_FLOAT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_LINEAR_FILTER, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_RGUI_MENU_COLOR_THEME, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET, - PARSE_ONLY_PATH, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_SHADOWS, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_XMB_ALPHA_FACTOR, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_XMB_SCALE_FACTOR, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_XMB_FONT, - PARSE_ONLY_PATH, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_FONT_COLOR_RED, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_FONT_COLOR_GREEN, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_XMB_LAYOUT, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_XMB_THEME, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_XMB_RIBBON_ENABLE, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_OZONE_MENU_COLOR_THEME, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_OZONE_COLLAPSE_SIDEBAR, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY, - PARSE_ONLY_FLOAT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY, - PARSE_ONLY_FLOAT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_THUMBNAILS, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_LEFT_THUMBNAILS, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS, - PARSE_ONLY_BOOL, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_TICKER_TYPE, - PARSE_ONLY_UINT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_TICKER_SPEED, - PARSE_ONLY_FLOAT, false) == 0) - count++; - if (menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_RGUI_EXTENDED_ASCII, - PARSE_ONLY_BOOL, false) == 0) - count++; + count = menu_displaylist_build_list(info->list, DISPLAYLIST_MENU_SETTINGS_LIST); if (count == 0) menu_entries_append_enum(info->list, diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index 0c42a8d72c..8d55fae715 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -252,6 +252,8 @@ bool menu_displaylist_push(menu_displaylist_ctx_entry_t *entry); void menu_displaylist_info_free(menu_displaylist_info_t *info); +unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ctl_state type); + void menu_displaylist_info_init(menu_displaylist_info_t *info); bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist_info_t *info); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index ad1cfb6a64..f08242eb0d 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -9479,6 +9479,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_menu_thumbnails; menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_RADIO_BUTTONS; CONFIG_UINT( list, list_info, @@ -9495,6 +9496,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_menu_left_thumbnails; menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_RADIO_BUTTONS; } if (string_is_equal(settings->arrays.menu_driver, "xmb")) diff --git a/ui/drivers/qt/options/ui.cpp b/ui/drivers/qt/options/ui.cpp index 87ab40bbfa..a992589f5a 100644 --- a/ui/drivers/qt/options/ui.cpp +++ b/ui/drivers/qt/options/ui.cpp @@ -1,5 +1,6 @@ #include "options.h" #include "../viewoptionsdialog.h" +#include "../../verbosity.h" UserInterfaceCategory::UserInterfaceCategory(QWidget *parent) : OptionsCategory(parent) @@ -193,10 +194,51 @@ AppearancePage::AppearancePage(QObject *parent) : QWidget *AppearancePage::widget() { + unsigned i; QWidget * widget = new QWidget; FormLayout *layout = new FormLayout; - rarch_setting_t *thumbnails = menu_setting_find_enum(MENU_ENUM_LABEL_THUMBNAILS); + rarch_setting_t *thumbnails = menu_setting_find_enum( + MENU_ENUM_LABEL_THUMBNAILS); + file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); + unsigned count = menu_displaylist_build_list( + list, DISPLAYLIST_MENU_SETTINGS_LIST); + /* TODO/FIXME - we haven't yet figured out how to + * put a radio button setting next to another radio + * button on the same row */ + + for (i = 0; i < list->size; i++) + { + menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) + file_list_get_actiondata_at_offset(list, i); + + switch (cbs->enum_idx) + { + /* TODO/FIXME - this is a dirty hack - if we + * detect this setting, we instead replace it with a + * color button and ignore the other two font color + * settings since they are already covered by this one + * color button */ + case MENU_ENUM_LABEL_MENU_FONT_COLOR_RED: + layout->addUIntColorButton("Menu Font Color: ", + MENU_ENUM_LABEL_MENU_FONT_COLOR_RED, + MENU_ENUM_LABEL_MENU_FONT_COLOR_GREEN, + MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE); + break; + case MENU_ENUM_LABEL_MENU_FONT_COLOR_GREEN: + case MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE: + break; + default: + layout->add(cbs->enum_idx); + break; + } + + file_list_free_actiondata(list, i); + } + + file_list_free(list); + +#if 0 layout->add(MENU_ENUM_LABEL_MENU_WALLPAPER); layout->add(MENU_ENUM_LABEL_DYNAMIC_WALLPAPER); layout->add(MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY); @@ -249,6 +291,7 @@ QWidget *AppearancePage::widget() layout->add(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER); layout->add(MENU_ENUM_LABEL_MENU_TICKER_TYPE); layout->add(MENU_ENUM_LABEL_MENU_TICKER_SPEED); +#endif widget->setLayout(layout); From f33e04c747596b240f1db6f5df715910c85bcfc6 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 06:29:02 +0200 Subject: [PATCH 201/237] (UI/QT) Dynamically generate settings for 'throttle' --- menu/menu_displaylist.c | 80 ++++++++++++++++++------------ ui/drivers/qt/options/throttle.cpp | 42 +++++++++++----- ui/drivers/qt/options/ui.cpp | 2 - 3 files changed, 78 insertions(+), 46 deletions(-) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 127ab7e50d..ad50a5fb5e 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4382,6 +4382,50 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct switch (type) { + case DISPLAYLIST_REWIND_SETTINGS_LIST: + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_REWIND_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_REWIND_GRANULARITY, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_REWIND_BUFFER_SIZE, + PARSE_ONLY_SIZE, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_REWIND_BUFFER_SIZE_STEP, + PARSE_ONLY_UINT, false) == 0) + count++; + break; + case DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST: + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_REWIND_SETTINGS, PARSE_ACTION, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_FASTFORWARD_RATIO, + PARSE_ONLY_FLOAT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_SLOWMOTION_RATIO, + PARSE_ONLY_FLOAT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + + { + settings_t *settings = config_get_ptr(); + if (settings->bools.menu_show_advanced_settings) + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE, + PARSE_ONLY_BOOL, false) == 0) + count++; + } + break; case DISPLAYLIST_MENU_SETTINGS_LIST: if (menu_displaylist_parse_settings_enum(list, MENU_ENUM_LABEL_MENU_WALLPAPER, @@ -5691,43 +5735,14 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_REWIND_SETTINGS, PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_FASTFORWARD_RATIO, - PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_SLOWMOTION_RATIO, - PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE, - PARSE_ONLY_BOOL, false); - - { - settings_t *settings = config_get_ptr(); - if (settings->bools.menu_show_advanced_settings) - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE, - PARSE_ONLY_BOOL, false); - } + count = menu_displaylist_build_list(info->list, type); info->need_refresh = true; info->need_push = true; break; case DISPLAYLIST_REWIND_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_REWIND_ENABLE, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_REWIND_GRANULARITY, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_REWIND_BUFFER_SIZE, - PARSE_ONLY_SIZE, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_REWIND_BUFFER_SIZE_STEP, - PARSE_ONLY_UINT, false); + count = menu_displaylist_build_list(info->list, type); info->need_refresh = true; info->need_push = true; @@ -6253,7 +6268,8 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_MENU_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - count = menu_displaylist_build_list(info->list, DISPLAYLIST_MENU_SETTINGS_LIST); + count = menu_displaylist_build_list(info->list, + type); if (count == 0) menu_entries_append_enum(info->list, diff --git a/ui/drivers/qt/options/throttle.cpp b/ui/drivers/qt/options/throttle.cpp index a9cf82c72e..ea46a36562 100644 --- a/ui/drivers/qt/options/throttle.cpp +++ b/ui/drivers/qt/options/throttle.cpp @@ -25,13 +25,22 @@ FrameThrottlePage::FrameThrottlePage(QObject *parent) : QWidget *FrameThrottlePage::widget() { - QWidget *widget = new QWidget; - FormLayout *layout = new FormLayout; + unsigned i; + QWidget *widget = new QWidget; + FormLayout *layout = new FormLayout; + file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); + unsigned count = menu_displaylist_build_list( + list, DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST); - layout->add(MENU_ENUM_LABEL_FASTFORWARD_RATIO); - layout->add(MENU_ENUM_LABEL_SLOWMOTION_RATIO); - layout->add(MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE); - layout->add(MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE); + for (i = 0; i < list->size; i++) + { + menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) + file_list_get_actiondata_at_offset(list, i); + + layout->add(cbs->enum_idx); + } + + file_list_free(list); widget->setLayout(layout); @@ -46,13 +55,22 @@ RewindPage::RewindPage(QObject *parent) : QWidget *RewindPage::widget() { - QWidget *widget = new QWidget; - FormLayout *layout = new FormLayout; + unsigned i; + QWidget *widget = new QWidget; + FormLayout *layout = new FormLayout; + file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); + unsigned count = menu_displaylist_build_list( + list, DISPLAYLIST_REWIND_SETTINGS_LIST); - layout->add(MENU_ENUM_LABEL_REWIND_ENABLE); - layout->add(MENU_ENUM_LABEL_REWIND_GRANULARITY); - layout->add(MENU_ENUM_LABEL_REWIND_BUFFER_SIZE); - layout->add(MENU_ENUM_LABEL_REWIND_BUFFER_SIZE_STEP); + for (i = 0; i < list->size; i++) + { + menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) + file_list_get_actiondata_at_offset(list, i); + + layout->add(cbs->enum_idx); + } + + file_list_free(list); widget->setLayout(layout); diff --git a/ui/drivers/qt/options/ui.cpp b/ui/drivers/qt/options/ui.cpp index a992589f5a..5b8745c47e 100644 --- a/ui/drivers/qt/options/ui.cpp +++ b/ui/drivers/qt/options/ui.cpp @@ -232,8 +232,6 @@ QWidget *AppearancePage::widget() layout->add(cbs->enum_idx); break; } - - file_list_free_actiondata(list, i); } file_list_free(list); From 1f7d7d64419c2e57c6340b31eb10e8d4ac049d37 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 06:54:36 +0200 Subject: [PATCH 202/237] (UI/QT) Dehardcode logging --- menu/menu_displaylist.c | 48 ++++++++++++++++++------------- ui/drivers/qt/options/logging.cpp | 20 +++++++++---- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index ad50a5fb5e..f2b6c69a8a 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4382,6 +4382,33 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct switch (type) { + case DISPLAYLIST_LOGGING_SETTINGS_LIST: + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_LOG_VERBOSITY, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_LOG_TO_FILE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP, + PARSE_ONLY_BOOL, false) == 0) + count++; + + { + settings_t *settings = config_get_ptr(); + if (settings->bools.menu_show_advanced_settings) + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_PERFCNT_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + } + break; case DISPLAYLIST_REWIND_SETTINGS_LIST: if (menu_displaylist_parse_settings_enum(list, MENU_ENUM_LABEL_REWIND_ENABLE, @@ -5709,26 +5736,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist break; case DISPLAYLIST_LOGGING_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_LOG_VERBOSITY, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_LOG_TO_FILE, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_LOG_TO_FILE_TIMESTAMP, - PARSE_ONLY_BOOL, false); - - { - settings_t *settings = config_get_ptr(); - if (settings->bools.menu_show_advanced_settings) - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_PERFCNT_ENABLE, - PARSE_ONLY_BOOL, false); - } + count = menu_displaylist_build_list(info->list, type); info->need_refresh = true; info->need_push = true; diff --git a/ui/drivers/qt/options/logging.cpp b/ui/drivers/qt/options/logging.cpp index b122ecd4f6..5246b8bec9 100644 --- a/ui/drivers/qt/options/logging.cpp +++ b/ui/drivers/qt/options/logging.cpp @@ -23,12 +23,22 @@ LoggingPage::LoggingPage(QObject *parent) : QWidget *LoggingPage::widget() { - QWidget *widget = new QWidget; - FormLayout *layout = new FormLayout; + unsigned i; + QWidget *widget = new QWidget; + FormLayout *layout = new FormLayout; + file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); + unsigned count = menu_displaylist_build_list( + list, DISPLAYLIST_LOGGING_SETTINGS_LIST); - layout->add(MENU_ENUM_LABEL_LOG_VERBOSITY); - layout->add(MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL); - layout->add(MENU_ENUM_LABEL_PERFCNT_ENABLE); + for (i = 0; i < list->size; i++) + { + menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) + file_list_get_actiondata_at_offset(list, i); + + layout->add(cbs->enum_idx); + } + + file_list_free(list); widget->setLayout(layout); From df1fe1f1ae04f5383ac87de6fe7e5ea870af3524 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 06:55:44 +0200 Subject: [PATCH 203/237] (menu_displaylist) slim down switch list --- menu/menu_displaylist.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index f2b6c69a8a..14f9dc85cf 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -5735,19 +5735,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist info->need_push = true; break; case DISPLAYLIST_LOGGING_SETTINGS_LIST: - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - count = menu_displaylist_build_list(info->list, type); - - info->need_refresh = true; - info->need_push = true; - break; case DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST: - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - count = menu_displaylist_build_list(info->list, type); - - info->need_refresh = true; - info->need_push = true; - break; case DISPLAYLIST_REWIND_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); count = menu_displaylist_build_list(info->list, type); From a680133a3807e9eeeea58422568935c71bc318c9 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 07:01:51 +0200 Subject: [PATCH 204/237] (UI/QT) Dehardcode driver settings --- menu/menu_displaylist.c | 90 +++++++++++++++++-------------- ui/drivers/qt/options/drivers.cpp | 27 +++++----- 2 files changed, 64 insertions(+), 53 deletions(-) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 14f9dc85cf..052f74e2db 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4382,6 +4382,54 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct switch (type) { + case DISPLAYLIST_DRIVER_SETTINGS_LIST: + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_INPUT_DRIVER, + PARSE_ONLY_STRING_OPTIONS, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_JOYPAD_DRIVER, + PARSE_ONLY_STRING_OPTIONS, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_VIDEO_DRIVER, + PARSE_ONLY_STRING_OPTIONS, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_AUDIO_DRIVER, + PARSE_ONLY_STRING_OPTIONS, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER, + PARSE_ONLY_STRING_OPTIONS, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_CAMERA_DRIVER, + PARSE_ONLY_STRING_OPTIONS, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_LOCATION_DRIVER, + PARSE_ONLY_STRING_OPTIONS, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MENU_DRIVER, + PARSE_ONLY_STRING_OPTIONS, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_RECORD_DRIVER, + PARSE_ONLY_STRING_OPTIONS, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_MIDI_DRIVER, + PARSE_ONLY_STRING_OPTIONS, false) == 0) + count++; +#ifdef HAVE_LAKKA + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_WIFI_DRIVER, + PARSE_ONLY_STRING_OPTIONS, false) == 0) + count++; +#endif + break; case DISPLAYLIST_LOGGING_SETTINGS_LIST: if (menu_displaylist_parse_settings_enum(list, MENU_ENUM_LABEL_LOG_VERBOSITY, @@ -5627,47 +5675,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist } info->need_push = true; break; - case DISPLAYLIST_DRIVER_SETTINGS_LIST: - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - ret = menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_INPUT_DRIVER, - PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_JOYPAD_DRIVER, - PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_VIDEO_DRIVER, - PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_AUDIO_DRIVER, - PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER, - PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_CAMERA_DRIVER, - PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_LOCATION_DRIVER, - PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MENU_DRIVER, - PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_RECORD_DRIVER, - PARSE_ONLY_STRING_OPTIONS, false); - ret = menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_MIDI_DRIVER, - PARSE_ONLY_STRING_OPTIONS, false); -#ifdef HAVE_LAKKA - ret = menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_WIFI_DRIVER, - PARSE_ONLY_STRING_OPTIONS, false); -#endif - - info->need_refresh = true; - info->need_push = true; - break; case DISPLAYLIST_CONFIGURATION_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); menu_displaylist_parse_settings_enum(info->list, @@ -5734,6 +5741,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist info->need_refresh = true; info->need_push = true; break; + case DISPLAYLIST_DRIVER_SETTINGS_LIST: case DISPLAYLIST_LOGGING_SETTINGS_LIST: case DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST: case DISPLAYLIST_REWIND_SETTINGS_LIST: diff --git a/ui/drivers/qt/options/drivers.cpp b/ui/drivers/qt/options/drivers.cpp index 10a724c58d..cca6c2b623 100644 --- a/ui/drivers/qt/options/drivers.cpp +++ b/ui/drivers/qt/options/drivers.cpp @@ -24,19 +24,22 @@ DriversPage::DriversPage(QObject *parent) : QWidget *DriversPage::widget() { - QWidget *widget = new QWidget; - FormLayout *layout = new FormLayout; + unsigned i; + QWidget *widget = new QWidget; + FormLayout *layout = new FormLayout; + file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); + unsigned count = menu_displaylist_build_list( + list, DISPLAYLIST_DRIVER_SETTINGS_LIST); - layout->add(MENU_ENUM_LABEL_INPUT_DRIVER); - layout->add(MENU_ENUM_LABEL_JOYPAD_DRIVER); - layout->add(MENU_ENUM_LABEL_VIDEO_DRIVER); - layout->add(MENU_ENUM_LABEL_AUDIO_DRIVER); - layout->add(MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER); - layout->add(MENU_ENUM_LABEL_CAMERA_DRIVER); - layout->add(MENU_ENUM_LABEL_LOCATION_DRIVER); - layout->add(MENU_ENUM_LABEL_MENU_DRIVER); - layout->add(MENU_ENUM_LABEL_RECORD_DRIVER); - layout->add(MENU_ENUM_LABEL_MIDI_DRIVER); + for (i = 0; i < list->size; i++) + { + menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) + file_list_get_actiondata_at_offset(list, i); + + layout->add(cbs->enum_idx); + } + + file_list_free(list); widget->setLayout(layout); From 39c111bb925a124edd12aef5a54bf69795367a07 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 07:15:53 +0200 Subject: [PATCH 205/237] (UI/QT) Dehardcode directory settings --- menu/menu_displaylist.c | 198 ++++++++++++++++------------ ui/drivers/qt/options/directory.cpp | 41 +++--- 2 files changed, 126 insertions(+), 113 deletions(-) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 052f74e2db..a6128388d4 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4382,6 +4382,116 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct switch (type) { + case DISPLAYLIST_DIRECTORY_SETTINGS_LIST: + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_SYSTEM_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_CORE_ASSETS_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_ASSETS_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_DYNAMIC_WALLPAPERS_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_RGUI_CONFIG_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_LIBRETRO_DIR_PATH, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_LIBRETRO_INFO_PATH, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_CURSOR_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_CHEAT_DATABASE_PATH, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_VIDEO_FILTER_DIR, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_AUDIO_FILTER_DIR, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_VIDEO_SHADER_DIR, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_RECORDING_OUTPUT_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_RECORDING_CONFIG_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_OVERLAY_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_SCREENSHOT_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_JOYPAD_AUTOCONFIG_DIR, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_INPUT_REMAPPING_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_PLAYLIST_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_RUNTIME_LOG_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_SAVEFILE_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_SAVESTATE_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_CACHE_DIRECTORY, + PARSE_ONLY_DIR, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_LOG_DIR, + PARSE_ONLY_DIR, false) == 0) + count++; + break; case DISPLAYLIST_DRIVER_SETTINGS_LIST: if (menu_displaylist_parse_settings_enum(list, MENU_ENUM_LABEL_INPUT_DRIVER, @@ -5745,6 +5855,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_LOGGING_SETTINGS_LIST: case DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST: case DISPLAYLIST_REWIND_SETTINGS_LIST: + case DISPLAYLIST_DIRECTORY_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); count = menu_displaylist_build_list(info->list, type); @@ -6688,93 +6799,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist MENU_ENUM_LABEL_NO_SETTINGS_FOUND, 0, 0, 0); - info->need_refresh = true; - info->need_push = true; - break; - case DISPLAYLIST_DIRECTORY_SETTINGS_LIST: - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_SYSTEM_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_CORE_ASSETS_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_ASSETS_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_DYNAMIC_WALLPAPERS_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_RGUI_CONFIG_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_LIBRETRO_DIR_PATH, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_LIBRETRO_INFO_PATH, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_CURSOR_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_CHEAT_DATABASE_PATH, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_VIDEO_FILTER_DIR, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_AUDIO_FILTER_DIR, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_VIDEO_SHADER_DIR, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_RECORDING_OUTPUT_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_RECORDING_CONFIG_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_OVERLAY_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_SCREENSHOT_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_JOYPAD_AUTOCONFIG_DIR, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_INPUT_REMAPPING_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_PLAYLIST_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_RUNTIME_LOG_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_SAVEFILE_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_SAVESTATE_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_CACHE_DIRECTORY, - PARSE_ONLY_DIR, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_LOG_DIR, - PARSE_ONLY_DIR, false); - info->need_refresh = true; info->need_push = true; break; diff --git a/ui/drivers/qt/options/directory.cpp b/ui/drivers/qt/options/directory.cpp index 51a062e341..2fb303df5f 100644 --- a/ui/drivers/qt/options/directory.cpp +++ b/ui/drivers/qt/options/directory.cpp @@ -23,33 +23,22 @@ DirectoryPage::DirectoryPage(QObject *parent) : QWidget *DirectoryPage::widget() { - QWidget *widget = new QWidget; - FormLayout *layout = new FormLayout; + unsigned i; + QWidget *widget = new QWidget; + FormLayout *layout = new FormLayout; + file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); + unsigned count = menu_displaylist_build_list( + list, DISPLAYLIST_DIRECTORY_SETTINGS_LIST); - layout->add(MENU_ENUM_LABEL_CORE_ASSETS_DIRECTORY); - layout->add(MENU_ENUM_LABEL_ASSETS_DIRECTORY); - layout->add(MENU_ENUM_LABEL_DYNAMIC_WALLPAPERS_DIRECTORY); - layout->add(MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY); - layout->add(MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY); - layout->add(MENU_ENUM_LABEL_RGUI_CONFIG_DIRECTORY); - layout->add(MENU_ENUM_LABEL_LIBRETRO_DIR_PATH); - layout->add(MENU_ENUM_LABEL_LIBRETRO_INFO_PATH); - layout->add(MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY); - layout->add(MENU_ENUM_LABEL_CURSOR_DIRECTORY); - layout->add(MENU_ENUM_LABEL_CHEAT_DATABASE_PATH); - layout->add(MENU_ENUM_LABEL_VIDEO_FILTER_DIR); - layout->add(MENU_ENUM_LABEL_AUDIO_FILTER_DIR); - layout->add(MENU_ENUM_LABEL_VIDEO_SHADER_DIR); - layout->add(MENU_ENUM_LABEL_RECORDING_OUTPUT_DIRECTORY); - layout->add(MENU_ENUM_LABEL_RECORDING_CONFIG_DIRECTORY); - layout->add(MENU_ENUM_LABEL_OVERLAY_DIRECTORY); - layout->add(MENU_ENUM_LABEL_SCREENSHOT_DIRECTORY); - layout->add(MENU_ENUM_LABEL_JOYPAD_AUTOCONFIG_DIR); - layout->add(MENU_ENUM_LABEL_INPUT_REMAPPING_DIRECTORY); - layout->add(MENU_ENUM_LABEL_PLAYLIST_DIRECTORY); - layout->add(MENU_ENUM_LABEL_SAVEFILE_DIRECTORY); - layout->add(MENU_ENUM_LABEL_SAVESTATE_DIRECTORY); - layout->add(MENU_ENUM_LABEL_CACHE_DIRECTORY); + for (i = 0; i < list->size; i++) + { + menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) + file_list_get_actiondata_at_offset(list, i); + + layout->add(cbs->enum_idx); + } + + file_list_free(list); widget->setLayout(layout); From 2e21a35261d7b2053b2b4810340292727ba0c471 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 07:40:51 +0200 Subject: [PATCH 206/237] (UI/QT) Dehardcode configuration settings --- menu/menu_displaylist.c | 37 +++++++++++++------------ ui/drivers/qt/options/configuration.cpp | 21 ++++++++++---- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index a6128388d4..df73f30172 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4382,6 +4382,24 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct switch (type) { + case DISPLAYLIST_CONFIGURATION_SETTINGS_LIST: + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + break; case DISPLAYLIST_DIRECTORY_SETTINGS_LIST: if (menu_displaylist_parse_settings_enum(list, MENU_ENUM_LABEL_SYSTEM_DIRECTORY, @@ -5785,24 +5803,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist } info->need_push = true; break; - case DISPLAYLIST_CONFIGURATION_SETTINGS_LIST: - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE, - PARSE_ONLY_BOOL, false); - - info->need_refresh = true; - info->need_push = true; - break; case DISPLAYLIST_SAVING_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); menu_displaylist_parse_settings_enum(info->list, @@ -5856,6 +5856,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST: case DISPLAYLIST_REWIND_SETTINGS_LIST: case DISPLAYLIST_DIRECTORY_SETTINGS_LIST: + case DISPLAYLIST_CONFIGURATION_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); count = menu_displaylist_build_list(info->list, type); diff --git a/ui/drivers/qt/options/configuration.cpp b/ui/drivers/qt/options/configuration.cpp index 30f9548879..d3ca48f1b9 100644 --- a/ui/drivers/qt/options/configuration.cpp +++ b/ui/drivers/qt/options/configuration.cpp @@ -23,13 +23,22 @@ ConfigurationPage::ConfigurationPage(QObject *parent) : QWidget *ConfigurationPage::widget() { - QWidget *widget = new QWidget; - FormLayout *layout = new FormLayout; + unsigned i; + QWidget *widget = new QWidget; + FormLayout *layout = new FormLayout; + file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); + unsigned count = menu_displaylist_build_list( + list, DISPLAYLIST_CONFIGURATION_SETTINGS_LIST); - layout->add(MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT); - layout->add(MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS); - layout->add(MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE); - layout->add(MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE); + for (i = 0; i < list->size; i++) + { + menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) + file_list_get_actiondata_at_offset(list, i); + + layout->add(cbs->enum_idx); + } + + file_list_free(list); widget->setLayout(layout); From d620e9ce1d83738f29a80e4272202068edc452ba Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 07:48:34 +0200 Subject: [PATCH 207/237] (UI/QT) Dehardcode core settings --- menu/menu_displaylist.c | 37 +++++++++++++++++----------------- ui/drivers/qt/options/core.cpp | 21 +++++++++++++------ 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index df73f30172..e1aa65a9f0 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4382,6 +4382,24 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct switch (type) { + case DISPLAYLIST_CORE_SETTINGS_LIST: + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_CHECK_FOR_MISSING_FIRMWARE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE, + PARSE_ONLY_BOOL, false) == 0) + count++; + break; case DISPLAYLIST_CONFIGURATION_SETTINGS_LIST: if (menu_displaylist_parse_settings_enum(list, MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT, @@ -5857,6 +5875,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_REWIND_SETTINGS_LIST: case DISPLAYLIST_DIRECTORY_SETTINGS_LIST: case DISPLAYLIST_CONFIGURATION_SETTINGS_LIST: + case DISPLAYLIST_CORE_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); count = menu_displaylist_build_list(info->list, type); @@ -7022,24 +7041,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist info->need_push = true; break; } - case DISPLAYLIST_CORE_SETTINGS_LIST: - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_CHECK_FOR_MISSING_FIRMWARE, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE, - PARSE_ONLY_BOOL, false); - - info->need_refresh = true; - info->need_push = true; - break; case DISPLAYLIST_AUDIO_MIXER_SETTINGS_LIST: { unsigned i; diff --git a/ui/drivers/qt/options/core.cpp b/ui/drivers/qt/options/core.cpp index 90a6996c23..1decf55c01 100644 --- a/ui/drivers/qt/options/core.cpp +++ b/ui/drivers/qt/options/core.cpp @@ -23,13 +23,22 @@ CorePage::CorePage(QObject *parent) : QWidget *CorePage::widget() { - QWidget *widget = new QWidget; - FormLayout *layout = new FormLayout; + unsigned i; + QWidget *widget = new QWidget; + FormLayout *layout = new FormLayout; + file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); + unsigned count = menu_displaylist_build_list( + list, DISPLAYLIST_CORE_SETTINGS_LIST); - layout->add(MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT); - layout->add(MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN); - layout->add(MENU_ENUM_LABEL_CHECK_FOR_MISSING_FIRMWARE); - layout->add(MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE); + for (i = 0; i < list->size; i++) + { + menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) + file_list_get_actiondata_at_offset(list, i); + + layout->add(cbs->enum_idx); + } + + file_list_free(list); widget->setLayout(layout); From 3d7eb19abdf49c26d9ac06883041007220741277 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 15 Apr 2019 08:00:24 +0200 Subject: [PATCH 208/237] (UI/QT) Dehardcode User Interface -> Views -> Quick Menu --- menu/menu_displaylist.c | 156 +++++++++++++++++++---------------- ui/drivers/qt/options/ui.cpp | 34 ++++---- 2 files changed, 101 insertions(+), 89 deletions(-) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index e1aa65a9f0..2868252d34 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4382,6 +4382,91 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct switch (type) { + case DISPLAYLIST_QUICK_MENU_VIEWS_SETTINGS_LIST: + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_RECORDING, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_STREAMING, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_OPTIONS, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_CONTROLS, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_CHEATS, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (video_shader_any_supported()) + { + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_SHADERS, + PARSE_ONLY_BOOL, false) == 0) + count++; + } + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_CONTENT_SHOW_REWIND, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_CONTENT_SHOW_OVERLAYS, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (menu_displaylist_parse_settings_enum(list, + MENU_ENUM_LABEL_QUICK_MENU_SHOW_INFORMATION, + PARSE_ONLY_BOOL, false) == 0) + count++; + break; case DISPLAYLIST_CORE_SETTINGS_LIST: if (menu_displaylist_parse_settings_enum(list, MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT, @@ -5876,6 +5961,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_DIRECTORY_SETTINGS_LIST: case DISPLAYLIST_CONFIGURATION_SETTINGS_LIST: case DISPLAYLIST_CORE_SETTINGS_LIST: + case DISPLAYLIST_QUICK_MENU_VIEWS_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); count = menu_displaylist_build_list(info->list, type); @@ -6327,76 +6413,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist MENU_ENUM_LABEL_RGUI_SHOW_START_SCREEN, PARSE_ONLY_BOOL, false); - info->need_refresh = true; - info->need_push = true; - break; - case DISPLAYLIST_QUICK_MENU_VIEWS_SETTINGS_LIST: - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT, - PARSE_ONLY_BOOL, false); - - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE, - PARSE_ONLY_BOOL, false); - - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, - PARSE_ONLY_BOOL, false); - - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, - PARSE_ONLY_BOOL, false); - - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_RECORDING, - PARSE_ONLY_BOOL, false); - - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_STREAMING, - PARSE_ONLY_BOOL, false); - - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION, - PARSE_ONLY_BOOL, false); - - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_OPTIONS, - PARSE_ONLY_BOOL, false); - - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_CONTROLS, - PARSE_ONLY_BOOL, false); - - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_CHEATS, - PARSE_ONLY_BOOL, false); - if (video_shader_any_supported()) - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_SHADERS, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_CONTENT_SHOW_REWIND, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_CONTENT_SHOW_OVERLAYS, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, - PARSE_ONLY_BOOL, false); - - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, - PARSE_ONLY_BOOL, false); - - menu_displaylist_parse_settings_enum(info->list, - MENU_ENUM_LABEL_QUICK_MENU_SHOW_INFORMATION, - PARSE_ONLY_BOOL, false); - info->need_refresh = true; info->need_push = true; break; diff --git a/ui/drivers/qt/options/ui.cpp b/ui/drivers/qt/options/ui.cpp index 5b8745c47e..ce11e9d8de 100644 --- a/ui/drivers/qt/options/ui.cpp +++ b/ui/drivers/qt/options/ui.cpp @@ -160,26 +160,22 @@ QuickMenuPage::QuickMenuPage(QObject *parent) : QWidget *QuickMenuPage::widget() { - QWidget * widget = new QWidget; - FormLayout *layout = new FormLayout; + unsigned i; + QWidget * widget = new QWidget; + FormLayout *layout = new FormLayout; + file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); + unsigned count = menu_displaylist_build_list( + list, DISPLAYLIST_QUICK_MENU_VIEWS_SETTINGS_LIST); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_RECORDING); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_STREAMING); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_RESET_CORE_ASSOCIATION); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_OPTIONS); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_CONTROLS); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_CHEATS); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SHADERS); - layout->add(MENU_ENUM_LABEL_CONTENT_SHOW_REWIND); - layout->add(MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY); - layout->add(MENU_ENUM_LABEL_CONTENT_SHOW_OVERLAYS); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES); - layout->add(MENU_ENUM_LABEL_QUICK_MENU_SHOW_INFORMATION); + for (i = 0; i < list->size; i++) + { + menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) + file_list_get_actiondata_at_offset(list, i); + + layout->add(cbs->enum_idx); + } + + file_list_free(list); widget->setLayout(layout); From 54e1711f9a8bed372c2373caeedd603333724167 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 15 Apr 2019 17:05:55 +0100 Subject: [PATCH 209/237] (3DS) Sanitise/Improve display mode selection --- config.def.h | 9 +- configuration.c | 4 + configuration.h | 1 + frontend/drivers/platform_ctr.c | 13 +- gfx/common/ctr_common.h | 14 +- gfx/drivers/ctr_gfx.c | 235 ++++++++++++++---------- gfx/drivers_font/ctr_font.c | 2 +- intl/msg_hash_chs.h | 2 + intl/msg_hash_cht.h | 2 + intl/msg_hash_de.h | 2 + intl/msg_hash_el.h | 2 + intl/msg_hash_eo.h | 2 + intl/msg_hash_es.h | 2 + intl/msg_hash_fr.h | 2 + intl/msg_hash_it.h | 2 + intl/msg_hash_ja.h | 2 + intl/msg_hash_ko.h | 2 + intl/msg_hash_lbl.h | 4 + intl/msg_hash_nl.h | 2 + intl/msg_hash_pl.h | 2 + intl/msg_hash_pt_br.h | 2 + intl/msg_hash_pt_pt.h | 2 + intl/msg_hash_ru.h | 2 + intl/msg_hash_us.h | 30 +++ intl/msg_hash_vn.h | 2 + menu/cbs/menu_cbs_sublabel.c | 13 ++ menu/drivers_display/menu_display_ctr.c | 2 +- menu/menu_displaylist.c | 5 +- menu/menu_setting.c | 74 +++++++- msg_hash.h | 9 + 30 files changed, 332 insertions(+), 115 deletions(-) diff --git a/config.def.h b/config.def.h index 6f17b654de..da181acbd0 100644 --- a/config.def.h +++ b/config.def.h @@ -32,6 +32,11 @@ #include "network/netplay/netplay.h" #endif +/* Required for 3DS display mode setting */ +#if defined(_3DS) +#include "gfx/common/ctr_common.h" +#endif + #if defined(HW_RVL) #define MAX_GAMMA_SETTING 30 #elif defined(GEKKO) @@ -518,9 +523,11 @@ static const float crt_refresh_rate = 60/1.001; * Used for setups where one manually rotates the monitor. */ static const bool allow_rotate = true; -#ifdef _3DS +#if defined(_3DS) /* Enable bottom LCD screen */ static const bool video_3ds_lcd_bottom = true; +/* Sets video display mode (3D, 2D, etc.) */ +static const unsigned video_3ds_display_mode = CTR_VIDEO_MODE_3D; #endif /* AUDIO */ diff --git a/configuration.c b/configuration.c index 9dfd351488..f19821b680 100644 --- a/configuration.c +++ b/configuration.c @@ -1783,6 +1783,10 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("libnx_overclock", &settings->uints.libnx_overclock, true, SWITCH_DEFAULT_CPU_PROFILE, false); #endif +#ifdef _3DS + SETTING_UINT("video_3ds_display_mode", &settings->uints.video_3ds_display_mode, true, video_3ds_display_mode, false); +#endif + #ifdef HAVE_MENU SETTING_UINT("playlist_show_inline_core_name", &settings->uints.playlist_show_inline_core_name, true, playlist_show_inline_core_name, false); SETTING_UINT("playlist_sublabel_runtime_type", &settings->uints.playlist_sublabel_runtime_type, true, playlist_sublabel_runtime_type, false); diff --git a/configuration.h b/configuration.h index 291f4c879a..eb1a185b0e 100644 --- a/configuration.h +++ b/configuration.h @@ -430,6 +430,7 @@ typedef struct settings unsigned video_stream_quality; unsigned video_record_scale_factor; unsigned video_stream_scale_factor; + unsigned video_3ds_display_mode; unsigned menu_timedate_style; unsigned menu_thumbnails; diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c index 41254ef7ea..759eb37d47 100644 --- a/frontend/drivers/platform_ctr.c +++ b/frontend/drivers/platform_ctr.c @@ -133,6 +133,7 @@ static void frontend_ctr_deinit(void* data) Handle lcd_handle; u32 parallax_layer_reg_state; u8 not_2DS; + u8 device_model = 0xFF; extern PrintConsole* currentConsole; @@ -167,8 +168,16 @@ static void frontend_ctr_deinit(void* data) svcCloseHandle(lcd_handle); } - parallax_layer_reg_state = (*(float*)0x1FF81080 == 0.0) ? 0x0 : 0x00010001; - GSPGPU_WriteHWRegs(0x202000, ¶llax_layer_reg_state, 4); + /* Only O3DS and O3DSXL support running in 'dual-framebuffer' + * mode with the parallax barrier disabled + * (i.e. these are the only platforms that can use + * CTR_VIDEO_MODE_2D_400x240 and CTR_VIDEO_MODE_2D_800x240) */ + CFGU_GetSystemModel(&device_model); /* (0 = O3DS, 1 = O3DSXL, 2 = N3DS, 3 = 2DS, 4 = N3DSXL, 5 = N2DSXL) */ + if ((device_model == 0) || (device_model == 1)) + { + parallax_layer_reg_state = (*(float*)0x1FF81080 == 0.0) ? 0x0 : 0x00010001; + GSPGPU_WriteHWRegs(0x202000, ¶llax_layer_reg_state, 4); + } mcuHwcExit(); ptmuExit(); diff --git a/gfx/common/ctr_common.h b/gfx/common/ctr_common.h index ff8e2236b5..6f12e2bf0d 100644 --- a/gfx/common/ctr_common.h +++ b/gfx/common/ctr_common.h @@ -42,11 +42,12 @@ typedef struct typedef enum { - CTR_VIDEO_MODE_NORMAL, - CTR_VIDEO_MODE_800x240, - CTR_VIDEO_MODE_400x240, - CTR_VIDEO_MODE_3D -}ctr_video_mode_enum; + CTR_VIDEO_MODE_3D = 0, + CTR_VIDEO_MODE_2D, + CTR_VIDEO_MODE_2D_400x240, + CTR_VIDEO_MODE_2D_800x240, + CTR_VIDEO_MODE_LAST +} ctr_video_mode_enum; typedef struct ctr_video { @@ -95,8 +96,9 @@ typedef struct ctr_video unsigned rotation; bool keep_aspect; bool should_resize; - bool lcd_buttom_on; bool msg_rendering_enabled; + bool supports_parallax_disable; + bool enable_3d; void* empty_framebuffer; diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index 525d9491ff..c9086fb5db 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -53,46 +53,59 @@ * when reinitialising... */ static bool ctr_bottom_screen_enabled = true; -static INLINE void ctr_check_3D_slider(ctr_video_t* ctr) +static INLINE void ctr_check_3D_slider(ctr_video_t* ctr, ctr_video_mode_enum video_mode) { float slider_val = *(float*)0x1FF81080; - ctr_video_mode_enum old_mode = ctr->video_mode; - if (slider_val == 0.0) - ctr->video_mode = CTR_VIDEO_MODE_NORMAL; - else if (slider_val < 0.2) - ctr->video_mode = CTR_VIDEO_MODE_800x240; - else if (slider_val < 0.5) - ctr->video_mode = CTR_VIDEO_MODE_400x240; - else - ctr->video_mode = CTR_VIDEO_MODE_3D; - - if (ctr->video_mode) + if (slider_val == 0.0f) { - switch (ctr->video_mode) - { - case CTR_VIDEO_MODE_800x240: - case CTR_VIDEO_MODE_400x240: - ctr_set_parallax_layer(false); - break; - case CTR_VIDEO_MODE_3D: - { - s16 offset = (slider_val - 0.6) * 10.0; - ctr->frame_coords[1] = ctr->frame_coords[0]; - ctr->frame_coords[2] = ctr->frame_coords[0]; + ctr->video_mode = CTR_VIDEO_MODE_2D; + ctr->enable_3d = false; + return; + } - ctr->frame_coords[1].x0 -= offset; - ctr->frame_coords[1].x1 -= offset; - ctr->frame_coords[2].x0 += offset; - ctr->frame_coords[2].x1 += offset; + switch (video_mode) + { + case CTR_VIDEO_MODE_3D: + { + s16 offset = slider_val * 10.0f; - GSPGPU_FlushDataCache(ctr->frame_coords, 3 * sizeof(ctr_vertex_t)); + ctr->video_mode = CTR_VIDEO_MODE_3D; + + ctr->frame_coords[1] = ctr->frame_coords[0]; + ctr->frame_coords[2] = ctr->frame_coords[0]; + + ctr->frame_coords[1].x0 -= offset; + ctr->frame_coords[1].x1 -= offset; + ctr->frame_coords[2].x0 += offset; + ctr->frame_coords[2].x1 += offset; + + GSPGPU_FlushDataCache(ctr->frame_coords, 3 * sizeof(ctr_vertex_t)); + + if (ctr->supports_parallax_disable) ctr_set_parallax_layer(true); - break; - } - default: - break; - } + ctr->enable_3d = true; + } + break; + case CTR_VIDEO_MODE_2D_400x240: + case CTR_VIDEO_MODE_2D_800x240: + if (ctr->supports_parallax_disable) + { + ctr->video_mode = video_mode; + ctr_set_parallax_layer(false); + ctr->enable_3d = true; + } + else + { + ctr->video_mode = CTR_VIDEO_MODE_2D; + ctr->enable_3d = false; + } + break; + case CTR_VIDEO_MODE_2D: + default: + ctr->video_mode = CTR_VIDEO_MODE_2D; + ctr->enable_3d = false; + break; } } @@ -128,13 +141,12 @@ static INLINE void ctr_set_screen_coords(ctr_video_t * ctr) } } -static void ctr_update_viewport(ctr_video_t* ctr, video_frame_info_t *video_info) +static void ctr_update_viewport(ctr_video_t* ctr, settings_t *settings, video_frame_info_t *video_info) { int x = 0; int y = 0; float width = ctr->vp.full_width; float height = ctr->vp.full_height; - settings_t *settings = config_get_ptr(); float desired_aspect = video_driver_get_aspect_ratio(); if(ctr->rotation & 0x1) @@ -248,7 +260,7 @@ static void ctr_lcd_aptHook(APT_HookType hook, void* param) ctr->p3d_event_pending = false; } - if((hook == APTHOOK_ONSUSPEND) && (ctr->video_mode == CTR_VIDEO_MODE_400x240)) + if((hook == APTHOOK_ONSUSPEND) && (ctr->video_mode == CTR_VIDEO_MODE_2D_400x240)) { memcpy(gfxTopRightFramebuffers[ctr->current_buffer_top], gfxTopLeftFramebuffers[ctr->current_buffer_top], @@ -256,7 +268,7 @@ static void ctr_lcd_aptHook(APT_HookType hook, void* param) GSPGPU_FlushDataCache(gfxTopRightFramebuffers[ctr->current_buffer_top], 400 * 240 * 3); } - if ((hook == APTHOOK_ONSUSPEND)) + if ((hook == APTHOOK_ONSUSPEND) && ctr->supports_parallax_disable) ctr_set_parallax_layer(*(float*)0x1FF81080 != 0.0); if((hook == APTHOOK_ONSUSPEND) || (hook == APTHOOK_ONRESTORE)) @@ -317,9 +329,10 @@ static void* ctr_init(const video_info_t* video, const input_driver_t** input, void** input_data) { float refresh_rate; - void* ctrinput = NULL; + u8 device_model = 0xFF; + void* ctrinput = NULL; settings_t *settings = config_get_ptr(); - ctr_video_t* ctr = (ctr_video_t*)linearAlloc(sizeof(ctr_video_t)); + ctr_video_t* ctr = (ctr_video_t*)linearAlloc(sizeof(ctr_video_t)); if (!ctr) return NULL; @@ -455,9 +468,15 @@ static void* ctr_init(const video_info_t* video, ctr->should_resize = true; ctr->smooth = video->smooth; ctr->vsync = video->vsync; - ctr->lcd_buttom_on = true; /* Unused */ ctr->current_buffer_top = 0; + /* Only O3DS and O3DSXL support running in 'dual-framebuffer' + * mode with the parallax barrier disabled + * (i.e. these are the only platforms that can use + * CTR_VIDEO_MODE_2D_400x240 and CTR_VIDEO_MODE_2D_800x240) */ + CFGU_GetSystemModel(&device_model); /* (0 = O3DS, 1 = O3DSXL, 2 = N3DS, 3 = 2DS, 4 = N3DSXL, 5 = N2DSXL) */ + ctr->supports_parallax_disable = (device_model == 0) || (device_model == 1); + ctr->empty_framebuffer = linearAlloc(320 * 240 * 2); memset(ctr->empty_framebuffer, 0, 320 * 240 * 2); @@ -500,6 +519,7 @@ static bool ctr_frame(void* data, const void* frame, extern u8* gfxSharedMemory; extern u8 gfxThreadID; uint32_t state_tmp = 0; + settings_t *settings = config_get_ptr(); ctr_video_t *ctr = (ctr_video_t*)data; static float fps = 0.0; static int total_frames = 0; @@ -507,7 +527,7 @@ static bool ctr_frame(void* data, const void* frame, extern bool select_pressed; - if (!width || !height) + if (!width || !height || !settings) { gspWaitForEvent(GSPGPU_EVENT_VBlank0, true); return true; @@ -542,7 +562,6 @@ static bool ctr_frame(void* data, const void* frame, gspWaitForEvent(GSPGPU_EVENT_PPF, false); ctr->ppf_event_pending = false; } - frames++; #ifndef HAVE_THREADS if(task_queue_find(&ctr_tasks_finder_data)) { @@ -564,68 +583,74 @@ static bool ctr_frame(void* data, const void* frame, ctr->vsync_event_pending = true; - currentTick = svcGetSystemTick(); - diff = currentTick - lastTick; - if(diff > CTR_CPU_TICKS_PER_SECOND) + /* Internal counters/statistics + * > This is only required if the bottom screen is enabled */ + if (ctr_bottom_screen_enabled) { - fps = (float)frames * ((float) CTR_CPU_TICKS_PER_SECOND / (float) diff); - lastTick = currentTick; - frames = 0; - } + frames++; + currentTick = svcGetSystemTick(); + diff = currentTick - lastTick; + if(diff > CTR_CPU_TICKS_PER_SECOND) + { + fps = (float)frames * ((float) CTR_CPU_TICKS_PER_SECOND / (float) diff); + lastTick = currentTick; + frames = 0; + } #ifdef CTR_INSPECT_MEMORY_USAGE - uint32_t ctr_get_stack_usage(void); - void ctr_linear_get_stats(void); - extern u32 __linear_heap_size; - extern u32 __heap_size; + uint32_t ctr_get_stack_usage(void); + void ctr_linear_get_stats(void); + extern u32 __linear_heap_size; + extern u32 __heap_size; - MemInfo mem_info; - PageInfo page_info; - u32 query_addr = 0x08000000; - printf(PRINTFPOS(0,0)); - while (query_addr < 0x40000000) - { - svcQueryMemory(&mem_info, &page_info, query_addr); - printf("0x%08X --> 0x%08X (0x%08X) \n", mem_info.base_addr, mem_info.base_addr + mem_info.size, mem_info.size); - query_addr = mem_info.base_addr + mem_info.size; - if(query_addr == 0x1F000000) - query_addr = 0x30000000; - } + MemInfo mem_info; + PageInfo page_info; + u32 query_addr = 0x08000000; + printf(PRINTFPOS(0,0)); + while (query_addr < 0x40000000) + { + svcQueryMemory(&mem_info, &page_info, query_addr); + printf("0x%08X --> 0x%08X (0x%08X) \n", mem_info.base_addr, mem_info.base_addr + mem_info.size, mem_info.size); + query_addr = mem_info.base_addr + mem_info.size; + if(query_addr == 0x1F000000) + query_addr = 0x30000000; + } #if 0 - static u32* dummy_pointer; - if(total_frames == 500) - dummy_pointer = malloc(0x2000000); - if(total_frames == 1000) - free(dummy_pointer); + static u32* dummy_pointer; + if(total_frames == 500) + dummy_pointer = malloc(0x2000000); + if(total_frames == 1000) + free(dummy_pointer); #endif - printf("========================================"); - printf("0x%08X 0x%08X 0x%08X\n", __heap_size, gpuCmdBufOffset, (__linear_heap_size - linearSpaceFree())); - printf("fps: %8.4f frames: %i (%X)\n", fps, total_frames++, (__linear_heap_size - linearSpaceFree())); - printf("========================================"); - u32 app_memory = *((u32*)0x1FF80040); - u64 mem_used; - svcGetSystemInfo(&mem_used, 0, 1); - printf("total mem : 0x%08X \n", app_memory); - printf("used: 0x%08X free: 0x%08X \n", (u32)mem_used, app_memory - (u32)mem_used); - static u32 stack_usage = 0; - extern u32 __stack_bottom; - if(!(total_frames & 0x3F)) - stack_usage = ctr_get_stack_usage(); - printf("stack total:0x%08X used: 0x%08X\n", 0x10000000 - __stack_bottom, stack_usage); + printf("========================================"); + printf("0x%08X 0x%08X 0x%08X\n", __heap_size, gpuCmdBufOffset, (__linear_heap_size - linearSpaceFree())); + printf("fps: %8.4f frames: %i (%X)\n", fps, total_frames++, (__linear_heap_size - linearSpaceFree())); + printf("========================================"); + u32 app_memory = *((u32*)0x1FF80040); + u64 mem_used; + svcGetSystemInfo(&mem_used, 0, 1); + printf("total mem : 0x%08X \n", app_memory); + printf("used: 0x%08X free: 0x%08X \n", (u32)mem_used, app_memory - (u32)mem_used); + static u32 stack_usage = 0; + extern u32 __stack_bottom; + if(!(total_frames & 0x3F)) + stack_usage = ctr_get_stack_usage(); + printf("stack total:0x%08X used: 0x%08X\n", 0x10000000 - __stack_bottom, stack_usage); - printf("========================================"); - ctr_linear_get_stats(); - printf("========================================"); + printf("========================================"); + ctr_linear_get_stats(); + printf("========================================"); #else - printf(PRINTFPOS(29,0)"fps: %8.4f frames: %i\r", fps, total_frames++); + printf(PRINTFPOS(29,0)"fps: %8.4f frames: %i\r", fps, total_frames++); #endif - fflush(stdout); + fflush(stdout); + } if (ctr->should_resize) - ctr_update_viewport(ctr, video_info); + ctr_update_viewport(ctr, settings, video_info); ctrGuSetMemoryFill(true, (u32*)ctr->drawbuffers.top.left, 0x00000000, (u32*)ctr->drawbuffers.top.left + 2 * CTR_TOP_FRAMEBUFFER_WIDTH * CTR_TOP_FRAMEBUFFER_HEIGHT, @@ -658,7 +683,7 @@ static bool ctr_frame(void* data, const void* frame, else { int i; - uint8_t *dst = (uint8_t*)ctr->texture_linear; + uint8_t *dst = (uint8_t*)ctr->texture_linear; const uint8_t *src = frame; for (i = 0; i < height; i++) @@ -689,7 +714,7 @@ static bool ctr_frame(void* data, const void* frame, GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE), ctr->rgb32 ? GPU_RGBA8: GPU_RGB565); - ctr_check_3D_slider(ctr); + ctr_check_3D_slider(ctr, (ctr_video_mode_enum)settings->uints.video_3ds_display_mode); /* ARGB --> RGBA */ if (ctr->rgb32) @@ -720,7 +745,7 @@ static bool ctr_frame(void* data, const void* frame, GPU_SetViewport(NULL, VIRT_TO_PHYS(ctr->drawbuffers.top.left), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, - ctr->video_mode == CTR_VIDEO_MODE_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH); + ctr->video_mode == CTR_VIDEO_MODE_2D_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH); if (ctr->video_mode == CTR_VIDEO_MODE_3D) { @@ -769,7 +794,7 @@ static bool ctr_frame(void* data, const void* frame, GPU_SetViewport(NULL, VIRT_TO_PHYS(ctr->drawbuffers.top.left), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, - ctr->video_mode == CTR_VIDEO_MODE_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH); + ctr->video_mode == CTR_VIDEO_MODE_2D_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH); GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); if (ctr->video_mode == CTR_VIDEO_MODE_3D) @@ -813,16 +838,16 @@ static bool ctr_frame(void* data, const void* frame, ctrGuDisplayTransfer(true, ctr->drawbuffers.top.left, 240, - ctr->video_mode == CTR_VIDEO_MODE_800x240 ? 800 : 400, + ctr->video_mode == CTR_VIDEO_MODE_2D_800x240 ? 800 : 400, CTRGU_RGBA8, - gfxTopLeftFramebuffers[ctr->current_buffer_top], 240,CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE); + gfxTopLeftFramebuffers[ctr->current_buffer_top], 240, CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE); - if ((ctr->video_mode == CTR_VIDEO_MODE_400x240) || (ctr->video_mode == CTR_VIDEO_MODE_3D)) + if ((ctr->video_mode == CTR_VIDEO_MODE_2D_400x240) || (ctr->video_mode == CTR_VIDEO_MODE_3D)) ctrGuDisplayTransfer(true, ctr->drawbuffers.top.right, 240, 400, CTRGU_RGBA8, - gfxTopRightFramebuffers[ctr->current_buffer_top], 240,CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE); + gfxTopRightFramebuffers[ctr->current_buffer_top], 240, CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE); /* Swap buffers : */ @@ -831,7 +856,7 @@ static bool ctr_frame(void* data, const void* frame, topFramebufferInfo. framebuf0_vaddr = (u32*)gfxTopLeftFramebuffers[ctr->current_buffer_top]; - if(ctr->video_mode == CTR_VIDEO_MODE_800x240) + if(ctr->video_mode == CTR_VIDEO_MODE_2D_800x240) { topFramebufferInfo. framebuf1_vaddr = (u32*)(gfxTopLeftFramebuffers[ctr->current_buffer_top] + 240 * 3); @@ -840,13 +865,19 @@ static bool ctr_frame(void* data, const void* frame, } else { - topFramebufferInfo. - framebuf1_vaddr = (u32*)gfxTopRightFramebuffers[ctr->current_buffer_top]; + if (ctr->enable_3d) + topFramebufferInfo. + framebuf1_vaddr = (u32*)gfxTopRightFramebuffers[ctr->current_buffer_top]; + else + topFramebufferInfo. + framebuf1_vaddr = topFramebufferInfo.framebuf0_vaddr; + topFramebufferInfo. framebuf_widthbytesize = 240 * 3; } - topFramebufferInfo.format = (1<<8)|(1<<5)|GSP_BGR8_OES; + u8 bit5 = (ctr->enable_3d != 0); + topFramebufferInfo.format = (1<<8)|((1^bit5)<<6)|((bit5)<<5)|GSP_BGR8_OES; topFramebufferInfo. framebuf_dispselect = ctr->current_buffer_top; topFramebufferInfo.unk = 0x00000000; diff --git a/gfx/drivers_font/ctr_font.c b/gfx/drivers_font/ctr_font.c index e3ed3fe89e..fda8f70d21 100644 --- a/gfx/drivers_font/ctr_font.c +++ b/gfx/drivers_font/ctr_font.c @@ -265,7 +265,7 @@ static void ctr_font_render_line( GPU_SetViewport(NULL, VIRT_TO_PHYS(ctr->drawbuffers.top.left), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, - ctr->video_mode == CTR_VIDEO_MODE_800x240 + ctr->video_mode == CTR_VIDEO_MODE_2D_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH); GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, v - ctr->vertex_cache.current); diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index 6d4a30bf89..cbfbb3dcad 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -1767,8 +1767,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "裁剪过扫描部分(需重启)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "禁用桌面元素") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "3DS底部屏幕") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "视频驱动") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index 8517d14d06..51fcd9bec1 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -1583,8 +1583,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Crop Overscan (Reload)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "禁用桌面元素") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "3DS底部屏幕") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "視訊驅動") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index edf1dc1be8..aa8d12dc5c 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -1656,8 +1656,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Bildränder (Overscan) zuschneiden (Neustart erforderlich)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Deaktiviere Desktop-Gestaltung") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "3DS-Bildschirm unten") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Videotreiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_el.h b/intl/msg_hash_el.h index 10b71d9942..277010eeb8 100644 --- a/intl/msg_hash_el.h +++ b/intl/msg_hash_el.h @@ -3046,10 +3046,12 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Disable Desktop Composition" ) +#if defined(_3DS) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "Κάτω οθόνη 3DS" ) +#endif MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Οδηγός Βίντεο" diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index 2b5e8ba288..8bd0a1bf94 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -1493,8 +1493,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Crop Overscan (Reload)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Disable Desktop Composition") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "3DS Fundo Ekrano") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Video Driver") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index 20db79a533..d28468f27a 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -3114,10 +3114,12 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Desactivar composición de escritorio" ) +#if defined(_3DS) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "Pantalla inferior 3DS" ) +#endif MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Controlador de video" diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 137e12ff85..f19fba3360 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -1610,8 +1610,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Tronquer l'overscan (Reload)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Désactiver le compositeur de bureau") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "Écran inférieur 3DS") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Pilote vidéo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index 6b013562e8..cc85ed1948 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -1628,8 +1628,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Crop Overscan (Ricarica)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Disattiva composizione del Desktop") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "3DS Bottom Screen") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Driver Video") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index 504c771f69..4e1d965c27 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -1802,8 +1802,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "オーバースキャンをクロップ(再起動が必要)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "デスクトップコンポジションを無効") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "3DSボトム画面") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "ビデオのドライバ") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index bbd97c71cb..9925ca5c83 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -1580,8 +1580,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "오버스캔 잘라내기(재시작)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "데스크탑 구성요소 사용안함") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "3DS 하단 화면") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "비디오 드라이버") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index f03d5d9131..f270b20e18 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1797,8 +1797,12 @@ MSG_HASH(MENU_ENUM_LABEL_NO_IMAGES_AVAILABLE, "no_images") MSG_HASH(MENU_ENUM_LABEL_NO_FAVORITES_AVAILABLE, "no_favorites") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VIDEO_3DS_LCD_BOTTOM, "video_3ds_lcd_bottom") +MSG_HASH(MENU_ENUM_LABEL_VIDEO_3DS_DISPLAY_MODE, + "video_3ds_display_mode") +#endif MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_USE_OLD_FORMAT, "playlist_use_old_format") MSG_HASH(MENU_ENUM_LABEL_MENU_SOUND_OK, diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index 5d44e7e3bb..ca9e1e1d2e 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -1495,8 +1495,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Overscan Afsnijden (Herladen Vereist)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Desktop Compositie Deactiveren") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "3DS onderste scherm") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Video Driver") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index 4c9d646346..3b1f838276 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -1732,8 +1732,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Przytnij Overscan (Przeładuj)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Wyłącz kompozycję pulpitu") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "Dolny ekran 3DS") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Sterownik wideo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index bfd58a9546..fd005cd987 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -3254,10 +3254,12 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Desativar Composição da Área de Trabalho" ) +#if defined(_3DS) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "Tela Inferior 3DS" ) +#endif MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Driver de Vídeo" diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h index 9ddc1406a2..86a2be8e07 100644 --- a/intl/msg_hash_pt_pt.h +++ b/intl/msg_hash_pt_pt.h @@ -1572,8 +1572,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Cortar sobreexploração (recarregar)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Desativar composição do ambiente de trabalho") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "Tela Inferior 3DS") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Controlador de vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index 8263f22e0a..7924355c65 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -1609,8 +1609,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Обрезка обрезки (перезагрузка)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Отключить компоновку рабочего стола") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "Нижний экран 3DS") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Видеодрайвер") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index afdad73e80..b9c4fa90dd 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3482,10 +3482,40 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Disable Desktop Composition" ) +#if defined(_3DS) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "3DS Bottom Screen" ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_3DS_LCD_BOTTOM, + "Enable display of status information on bottom screen. Disable to increase battery life and improve performance." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_3DS_DISPLAY_MODE, + "3DS Display Mode" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_3DS_DISPLAY_MODE, + "Selects between 3D and 2D display modes. In '3D' mode, pixels are square and a depth effect is applied when viewing the Quick Menu. '2D' mode provides the best performance." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_3D, + "3D" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D, + "2D" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D_400x240, + "2D (Pixel Grid Effect)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D_800x240, + "2D (High Resolution)" + ) +#endif MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Video" diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h index ec18729199..99dc15aa15 100644 --- a/intl/msg_hash_vn.h +++ b/intl/msg_hash_vn.h @@ -1603,8 +1603,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Crop Overscan (Reload)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Disable Desktop Composition") +#if defined(_3DS) MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, "Màn hình dưới 3DS") +#endif MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Video Driver") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index caac4519d4..35f59907aa 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -520,6 +520,11 @@ default_sublabel_macro(action_bind_sublabel_switch_gpu_profile, MENU default_sublabel_macro(action_bind_sublabel_switch_backlight_control, MENU_ENUM_SUBLABEL_SWITCH_BACKLIGHT_CONTROL) #endif +#if defined(_3DS) +default_sublabel_macro(action_bind_sublabel_video_3ds_lcd_bottom, MENU_ENUM_SUBLABEL_VIDEO_3DS_LCD_BOTTOM) +default_sublabel_macro(action_bind_sublabel_video_3ds_display_mode, MENU_ENUM_SUBLABEL_VIDEO_3DS_DISPLAY_MODE) +#endif + default_sublabel_macro(action_bind_sublabel_playlist_show_sublabels, MENU_ENUM_SUBLABEL_PLAYLIST_SHOW_SUBLABELS) default_sublabel_macro(action_bind_sublabel_menu_rgui_border_filler_enable, MENU_ENUM_SUBLABEL_MENU_RGUI_BORDER_FILLER_ENABLE) default_sublabel_macro(action_bind_sublabel_menu_rgui_border_filler_thickness_enable, MENU_ENUM_SUBLABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE) @@ -2398,6 +2403,14 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_SWITCH_BACKLIGHT_CONTROL: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_switch_backlight_control); break; +#endif +#if defined(_3DS) + case MENU_ENUM_LABEL_VIDEO_3DS_LCD_BOTTOM: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_3ds_lcd_bottom); + break; + case MENU_ENUM_LABEL_VIDEO_3DS_DISPLAY_MODE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_3ds_display_mode); + break; #endif case MENU_ENUM_LABEL_CHEAT_APPLY_AFTER_LOAD: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_apply_after_load); diff --git a/menu/drivers_display/menu_display_ctr.c b/menu/drivers_display/menu_display_ctr.c index e131bc0e93..a29cc7f531 100644 --- a/menu/drivers_display/menu_display_ctr.c +++ b/menu/drivers_display/menu_display_ctr.c @@ -134,7 +134,7 @@ static void menu_display_ctr_draw(menu_display_ctx_draw_t *draw, GPU_SetViewport(NULL, VIRT_TO_PHYS(ctr->drawbuffers.top.left), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, - ctr->video_mode == CTR_VIDEO_MODE_800x240 ? + ctr->video_mode == CTR_VIDEO_MODE_2D_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH); GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 2868252d34..49c2edc18d 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6542,7 +6542,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist MENU_ENUM_LABEL_UI_COMPANION_TOGGLE, PARSE_ONLY_BOOL, false); #endif -#ifdef _3DS +#if defined(_3DS) + menu_displaylist_parse_settings_enum(info->list, + MENU_ENUM_LABEL_VIDEO_3DS_DISPLAY_MODE, + PARSE_ONLY_UINT, false); menu_displaylist_parse_settings_enum(info->list, MENU_ENUM_LABEL_VIDEO_3DS_LCD_BOTTOM, PARSE_ONLY_BOOL, false); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index f08242eb0d..f084a29ef9 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -95,6 +95,12 @@ #include "../network/netplay/netplay.h" #endif +/* Required for 3DS display mode setting */ +#if defined(_3DS) +#include "gfx/common/ctr_common.h" +#include <3ds/services/cfgu.h> +#endif + enum settings_list_type { SETTINGS_LIST_NONE = 0, @@ -1424,6 +1430,44 @@ static void setting_get_string_representation_uint_playlist_inline_core_display_ } } +#if defined(_3DS) +static void setting_get_string_representation_uint_video_3ds_display_mode( + rarch_setting_t *setting, + char *s, size_t len) +{ + if (!setting) + return; + + switch (*setting->value.target.unsigned_integer) + { + case CTR_VIDEO_MODE_3D: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_3D), + len); + break; + case CTR_VIDEO_MODE_2D: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D), + len); + break; + case CTR_VIDEO_MODE_2D_400x240: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D_400x240), + len); + break; + case CTR_VIDEO_MODE_2D_800x240: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D_800x240), + len); + break; + } +} +#endif + static int setting_action_left_analog_dpad_mode(rarch_setting_t *setting, bool wraparound) { unsigned port = 0; @@ -9807,7 +9851,35 @@ static bool setting_append_list( settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); #endif -#ifdef _3DS +#if defined(_3DS) + { + u8 device_model = 0xFF; + + /* Only O3DS and O3DSXL support running in 'dual-framebuffer' + * mode with the parallax barrier disabled + * (i.e. these are the only platforms that can use + * CTR_VIDEO_MODE_2D_400x240 and CTR_VIDEO_MODE_2D_800x240) */ + CFGU_GetSystemModel(&device_model); /* (0 = O3DS, 1 = O3DSXL, 2 = N3DS, 3 = 2DS, 4 = N3DSXL, 5 = N2DSXL) */ + + CONFIG_UINT( + list, list_info, + &settings->uints.video_3ds_display_mode, + MENU_ENUM_LABEL_VIDEO_3DS_DISPLAY_MODE, + MENU_ENUM_LABEL_VALUE_VIDEO_3DS_DISPLAY_MODE, + video_3ds_display_mode, + &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_video_3ds_display_mode; + menu_settings_list_current_add_range(list, list_info, 0, + CTR_VIDEO_MODE_LAST - (((device_model == 0) || (device_model == 1)) ? 1 : 3), + 1, true, true); + } + CONFIG_BOOL( list, list_info, &settings->bools.video_3ds_lcd_bottom, diff --git a/msg_hash.h b/msg_hash.h index 2b54064111..401fc44639 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -955,7 +955,16 @@ enum msg_hash_enums MENU_LABEL(UI_COMPANION_TOGGLE), MENU_LABEL(DESKTOP_MENU_ENABLE), MENU_LABEL(UI_MENUBAR_ENABLE), + +#if defined(_3DS) MENU_LABEL(VIDEO_3DS_LCD_BOTTOM), + MENU_LABEL(VIDEO_3DS_DISPLAY_MODE), + + MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_3D, + MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D, + MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D_400x240, + MENU_ENUM_LABEL_VALUE_CTR_VIDEO_MODE_2D_800x240, +#endif MENU_ENUM_LABEL_FILE_CONFIG, MENU_ENUM_LABEL_FILE_BROWSER_COMPRESSED_ARCHIVE, From dc37d56ac8e7f93a98068be69a763bef3cc17519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Zumer?= Date: Mon, 15 Apr 2019 13:11:49 -0400 Subject: [PATCH 210/237] Check bounds of peeked memory for achievements --- cheevos/var.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cheevos/var.c b/cheevos/var.c index 18c8955dac..683ae6918e 100644 --- a/cheevos/var.c +++ b/cheevos/var.c @@ -295,8 +295,13 @@ uint8_t* cheevos_var_get_memory(const cheevos_var_t* var) { rarch_system_info_t* system = runloop_get_system_info(); - if (system->mmaps.num_descriptors != 0) + if (system->mmaps.num_descriptors > var->bank_id) + { + if (var->value >= system->mmaps.descriptors[var->bank_id].core.len) + return NULL; + memory = (uint8_t*)system->mmaps.descriptors[var->bank_id].core.ptr; + } else { retro_ctx_memory_info_t meminfo = {NULL, 0, 0}; @@ -321,6 +326,10 @@ uint8_t* cheevos_var_get_memory(const cheevos_var_t* var) } core_get_memory(&meminfo); + + if (var->value >= meminfo.size) + return NULL; + memory = (uint8_t*)meminfo.data; } From ac6e4732f10bef76d56fc23284b7b721cab563b6 Mon Sep 17 00:00:00 2001 From: CozmoP <25121396+CozmoP@users.noreply.github.com> Date: Mon, 15 Apr 2019 22:29:16 +0200 Subject: [PATCH 211/237] Qt: add scrollbar to settings dialog --- ui/drivers/qt/ui_qt_window.cpp | 1 + ui/drivers/qt/viewoptionsdialog.cpp | 79 +++++++++++++++++++++++++++-- ui/drivers/qt/viewoptionsdialog.h | 6 +-- ui/drivers/ui_qt.cpp | 3 ++ 4 files changed, 81 insertions(+), 8 deletions(-) diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index 74a617d864..fcf8af80a6 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -3020,6 +3020,7 @@ void MainWindow::closeEvent(QCloseEvent *event) m_settings->setValue("file_browser_table_headers", m_fileTableView->horizontalHeader()->saveState()); m_settings->setValue("icon_view_zoom", m_lastZoomSliderValue); m_settings->setValue("icon_view_thumbnail_type", getCurrentThumbnailTypeString()); + m_settings->setValue("options_dialog_geometry", m_viewOptionsDialog->saveGeometry()); QMainWindow::closeEvent(event); } diff --git a/ui/drivers/qt/viewoptionsdialog.cpp b/ui/drivers/qt/viewoptionsdialog.cpp index 2bb2cc7731..ccbac145b5 100644 --- a/ui/drivers/qt/viewoptionsdialog.cpp +++ b/ui/drivers/qt/viewoptionsdialog.cpp @@ -35,6 +35,9 @@ extern "C" { #ifdef HAVE_MENU +static const int MAX_MIN_WIDTH = 250; +static const int MAX_MIN_HEIGHT = 250; + QPixmap getColorizedPixmap(const QPixmap& oldPixmap, const QColor& color) { QPixmap pixmap = oldPixmap; @@ -52,10 +55,74 @@ QColor getLabelColor(const QString& objectName) return dummyColor.palette().color(QPalette::Foreground); } +/* stolen from Qt Creator */ +class SmartScrollArea : public QScrollArea +{ +public: + explicit SmartScrollArea(QWidget *parent) : + QScrollArea(parent) + { + setFrameStyle(QFrame::NoFrame | QFrame::Plain); + viewport()->setAutoFillBackground(false); + setWidgetResizable(true); + } +private: + void resizeEvent(QResizeEvent *event) final + { + QWidget *inner = widget(); + if (inner) + { + int fw = frameWidth() * 2; + QSize innerSize = event->size() - QSize(fw, fw); + QSize innerSizeHint = inner->minimumSizeHint(); + + if (innerSizeHint.height() > innerSize.height()) + { /* Widget wants to be bigger than available space */ + innerSize.setWidth(innerSize.width() - scrollBarWidth()); + innerSize.setHeight(innerSizeHint.height()); + } + inner->resize(innerSize); + } + QScrollArea::resizeEvent(event); + } + + QSize minimumSizeHint() const final + { + QWidget *inner = widget(); + if (inner) { + int fw = frameWidth() * 2; + + QSize minSize = inner->minimumSizeHint(); + minSize += QSize(fw, fw); + minSize += QSize(scrollBarWidth(), 0); + minSize.setWidth(qMin(minSize.width(), MAX_MIN_WIDTH)); + minSize.setHeight(qMin(minSize.height(), MAX_MIN_HEIGHT)); + return minSize; + } + return QSize(0, 0); + } + + bool event(QEvent *event) final + { + if (event->type() == QEvent::LayoutRequest) + updateGeometry(); + return QScrollArea::event(event); + } + + int scrollBarWidth() const + { + SmartScrollArea *that = const_cast(this); + QWidgetList list = that->scrollBarWidgets(Qt::AlignRight); + if (list.isEmpty()) + return 0; + return list.first()->sizeHint().width(); + } +}; + ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : QDialog(mainwindow) - , m_optionsList(new QListWidget(this)) - , m_optionsStack(new QStackedWidget(this)) + ,m_optionsList(new QListWidget(this)) + ,m_optionsStack(new QStackedLayout) { QGridLayout *layout = new QGridLayout(this); QLabel *m_headerLabel = new QLabel(this); @@ -66,6 +133,8 @@ ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : const int leftMargin = QApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin); int width; + m_optionsStack->setMargin(0); + headerLabelFont.setBold(true); // Paranoia: Should a font be set in pixels... @@ -106,7 +175,7 @@ ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : layout->addWidget(m_optionsList, 0, 0, 2, 1); layout->addLayout(headerHLayout, 0, 1); - layout->addWidget(m_optionsStack, 1, 1); + layout->addLayout(m_optionsStack, 1, 1); connect(m_optionsList, SIGNAL(currentRowChanged(int)), m_optionsStack, SLOT(setCurrentIndex(int))); connect(m_optionsList, SIGNAL(currentTextChanged(const QString&)), m_headerLabel, SLOT(setText(const QString&))); @@ -127,9 +196,11 @@ void ViewOptionsDialog::addCategory(OptionsCategory *category) for (OptionsPage* page : category->pages()) { + SmartScrollArea *scrollArea = new SmartScrollArea(this); QWidget *widget = page->widget(); + scrollArea->setWidget(widget); widget->setAutoFillBackground(false); - tabWidget->addTab(widget, page->displayName()); + tabWidget->addTab(scrollArea, page->displayName()); } #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) diff --git a/ui/drivers/qt/viewoptionsdialog.h b/ui/drivers/qt/viewoptionsdialog.h index 6f7afd6b2f..3a47ac44a5 100644 --- a/ui/drivers/qt/viewoptionsdialog.h +++ b/ui/drivers/qt/viewoptionsdialog.h @@ -16,7 +16,7 @@ class QSpinBox; class QWidget; class OptionsCategory; class QListWidget; -class QStackedWidget; +class QStackedLayout; #endif class ViewOptionsWidget : public QWidget @@ -58,8 +58,6 @@ class ViewOptionsDialog : public QDialog Q_OBJECT public: ViewOptionsDialog(MainWindow *window, QWidget *parent = 0); - // Make sure the settings dialog starts up as small as possible. - QSize sizeHint() const final { return minimumSize(); } #ifdef HAVE_MENU void repaintIcons(); #endif @@ -74,7 +72,7 @@ private: void addCategory(OptionsCategory *category); QVector m_categoryList; QListWidget *m_optionsList; - QStackedWidget *m_optionsStack; + QStackedLayout *m_optionsStack; #else ViewOptionsWidget *m_viewOptionsWidget; #endif diff --git a/ui/drivers/ui_qt.cpp b/ui/drivers/ui_qt.cpp index cb72fa1182..5bee2a3798 100644 --- a/ui/drivers/ui_qt.cpp +++ b/ui/drivers/ui_qt.cpp @@ -522,6 +522,9 @@ static void* ui_companion_qt_init(void) if (qsettings->contains("save_geometry")) mainwindow->restoreGeometry(qsettings->value("geometry").toByteArray()); + if (qsettings->contains("options_dialog_geometry")) + mainwindow->viewOptionsDialog()->restoreGeometry(qsettings->value("options_dialog_geometry").toByteArray()); + if (qsettings->contains("save_dock_positions")) if (qsettings->contains("dock_positions")) mainwindow->restoreState(qsettings->value("dock_positions").toByteArray()); From aa98a80fa68b4da1f84cc608848dfa67367efd12 Mon Sep 17 00:00:00 2001 From: CozmoP <25121396+CozmoP@users.noreply.github.com> Date: Mon, 15 Apr 2019 22:45:03 +0200 Subject: [PATCH 212/237] Qt: sanitize ampersands --- ui/drivers/qt/settingswidgets.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ui/drivers/qt/settingswidgets.cpp b/ui/drivers/qt/settingswidgets.cpp index 40b0b1e3ec..ace540f703 100644 --- a/ui/drivers/qt/settingswidgets.cpp +++ b/ui/drivers/qt/settingswidgets.cpp @@ -55,9 +55,14 @@ inline void addSublabelAndWhatsThis(QWidget *widget, rarch_setting_t *setting) widget->setWhatsThis(tmp); } +static QString sanitizeAmpersand(QString input) +{ + return input.replace("&", "&&"); +} + inline QString formLabel(rarch_setting_t *setting) { - return QString(setting->short_description) + ":"; + return QString(sanitizeAmpersand(setting->short_description)) + ":"; } FormLayout::FormLayout(QWidget *parent) : @@ -271,7 +276,7 @@ void SettingsGroup::addBindButton(rarch_setting_t *setting) } CheckBox::CheckBox(rarch_setting_t *setting, QWidget *parent) : - QCheckBox(setting->short_description, parent) + QCheckBox(sanitizeAmpersand(setting->short_description), parent) ,m_setting(setting) ,m_value(setting->value.target.boolean) { From 1baebdbd47c3492045a6fd8c745d4985344f2482 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 16 Apr 2019 00:46:27 +0200 Subject: [PATCH 213/237] (UI/QT) Fix Travis OSX build hopefully --- griffin/griffin_cpp.cpp | 1 - ui/drivers/qt/options/configuration.cpp | 3 +- ui/drivers/qt/options/core.cpp | 3 +- ui/drivers/qt/options/directory.cpp | 3 +- ui/drivers/qt/options/drivers.cpp | 3 +- ui/drivers/qt/options/input.cpp | 1 - ui/drivers/qt/options/logging.cpp | 3 +- ui/drivers/qt/options/throttle.cpp | 6 +- ui/drivers/qt/options/ui.cpp | 107 ++++++++++---------- ui/drivers/qt/ui_qt_window.cpp | 20 ++-- ui/drivers/ui_qt.cpp | 124 ++++++++++++------------ 11 files changed, 142 insertions(+), 132 deletions(-) diff --git a/griffin/griffin_cpp.cpp b/griffin/griffin_cpp.cpp index 06fb0f002d..229a1adee0 100644 --- a/griffin/griffin_cpp.cpp +++ b/griffin/griffin_cpp.cpp @@ -78,7 +78,6 @@ UI #include "../ui/drivers/qt/options/ui.cpp" #include "../ui/drivers/qt/options/achievements.cpp" #include "../ui/drivers/qt/options/network.cpp" -#include "../ui/drivers/qt/moc_settingswidgets.cpp" #include "../ui/drivers/qt/options/moc_options.cpp" #endif #include "../ui/drivers/moc_ui_qt.cpp" diff --git a/ui/drivers/qt/options/configuration.cpp b/ui/drivers/qt/options/configuration.cpp index d3ca48f1b9..54c94726ed 100644 --- a/ui/drivers/qt/options/configuration.cpp +++ b/ui/drivers/qt/options/configuration.cpp @@ -27,7 +27,8 @@ QWidget *ConfigurationPage::widget() QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); - unsigned count = menu_displaylist_build_list( + + menu_displaylist_build_list( list, DISPLAYLIST_CONFIGURATION_SETTINGS_LIST); for (i = 0; i < list->size; i++) diff --git a/ui/drivers/qt/options/core.cpp b/ui/drivers/qt/options/core.cpp index 1decf55c01..18f56e5d55 100644 --- a/ui/drivers/qt/options/core.cpp +++ b/ui/drivers/qt/options/core.cpp @@ -27,7 +27,8 @@ QWidget *CorePage::widget() QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); - unsigned count = menu_displaylist_build_list( + + menu_displaylist_build_list( list, DISPLAYLIST_CORE_SETTINGS_LIST); for (i = 0; i < list->size; i++) diff --git a/ui/drivers/qt/options/directory.cpp b/ui/drivers/qt/options/directory.cpp index 2fb303df5f..ffd16851cc 100644 --- a/ui/drivers/qt/options/directory.cpp +++ b/ui/drivers/qt/options/directory.cpp @@ -27,7 +27,8 @@ QWidget *DirectoryPage::widget() QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); - unsigned count = menu_displaylist_build_list( + + menu_displaylist_build_list( list, DISPLAYLIST_DIRECTORY_SETTINGS_LIST); for (i = 0; i < list->size; i++) diff --git a/ui/drivers/qt/options/drivers.cpp b/ui/drivers/qt/options/drivers.cpp index cca6c2b623..d88dc21a3b 100644 --- a/ui/drivers/qt/options/drivers.cpp +++ b/ui/drivers/qt/options/drivers.cpp @@ -28,7 +28,8 @@ QWidget *DriversPage::widget() QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); - unsigned count = menu_displaylist_build_list( + + menu_displaylist_build_list( list, DISPLAYLIST_DRIVER_SETTINGS_LIST); for (i = 0; i < list->size; i++) diff --git a/ui/drivers/qt/options/input.cpp b/ui/drivers/qt/options/input.cpp index 43bc71ddc8..579113bbbc 100644 --- a/ui/drivers/qt/options/input.cpp +++ b/ui/drivers/qt/options/input.cpp @@ -107,7 +107,6 @@ UserBindsPage::UserBindsPage(QObject *parent) : QWidget *UserBindsPage::widget() { unsigned p, retro_id; - unsigned count = 0; unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); QWidget *widget = new QWidget; QGridLayout *layout = new QGridLayout; diff --git a/ui/drivers/qt/options/logging.cpp b/ui/drivers/qt/options/logging.cpp index 5246b8bec9..a71577fc01 100644 --- a/ui/drivers/qt/options/logging.cpp +++ b/ui/drivers/qt/options/logging.cpp @@ -27,7 +27,8 @@ QWidget *LoggingPage::widget() QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); - unsigned count = menu_displaylist_build_list( + + menu_displaylist_build_list( list, DISPLAYLIST_LOGGING_SETTINGS_LIST); for (i = 0; i < list->size; i++) diff --git a/ui/drivers/qt/options/throttle.cpp b/ui/drivers/qt/options/throttle.cpp index ea46a36562..b389dfc3e7 100644 --- a/ui/drivers/qt/options/throttle.cpp +++ b/ui/drivers/qt/options/throttle.cpp @@ -29,7 +29,8 @@ QWidget *FrameThrottlePage::widget() QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); - unsigned count = menu_displaylist_build_list( + + menu_displaylist_build_list( list, DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST); for (i = 0; i < list->size; i++) @@ -59,7 +60,8 @@ QWidget *RewindPage::widget() QWidget *widget = new QWidget; FormLayout *layout = new FormLayout; file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); - unsigned count = menu_displaylist_build_list( + + menu_displaylist_build_list( list, DISPLAYLIST_REWIND_SETTINGS_LIST); for (i = 0; i < list->size; i++) diff --git a/ui/drivers/qt/options/ui.cpp b/ui/drivers/qt/options/ui.cpp index ce11e9d8de..4ba7811281 100644 --- a/ui/drivers/qt/options/ui.cpp +++ b/ui/drivers/qt/options/ui.cpp @@ -164,7 +164,8 @@ QWidget *QuickMenuPage::widget() QWidget * widget = new QWidget; FormLayout *layout = new FormLayout; file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); - unsigned count = menu_displaylist_build_list( + + menu_displaylist_build_list( list, DISPLAYLIST_QUICK_MENU_VIEWS_SETTINGS_LIST); for (i = 0; i < list->size; i++) @@ -193,10 +194,9 @@ QWidget *AppearancePage::widget() unsigned i; QWidget * widget = new QWidget; FormLayout *layout = new FormLayout; - rarch_setting_t *thumbnails = menu_setting_find_enum( - MENU_ENUM_LABEL_THUMBNAILS); file_list_t *list = (file_list_t*)calloc(1, sizeof(*list)); - unsigned count = menu_displaylist_build_list( + + menu_displaylist_build_list( list, DISPLAYLIST_MENU_SETTINGS_LIST); /* TODO/FIXME - we haven't yet figured out how to @@ -233,58 +233,63 @@ QWidget *AppearancePage::widget() file_list_free(list); #if 0 - layout->add(MENU_ENUM_LABEL_MENU_WALLPAPER); - layout->add(MENU_ENUM_LABEL_DYNAMIC_WALLPAPER); - layout->add(MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY); - layout->add(MENU_ENUM_LABEL_MENU_FRAMEBUFFER_OPACITY); - layout->add(MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION); - layout->add(MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE); - layout->add(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE); - layout->add(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE); - layout->add(MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT); - layout->add(MENU_ENUM_LABEL_MENU_LINEAR_FILTER); - layout->add(MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL); - layout->add(MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK); - layout->add(MENU_ENUM_LABEL_RGUI_MENU_COLOR_THEME); - layout->add(MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET); - layout->add(MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE); - layout->add(MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE); - layout->add(MENU_ENUM_LABEL_XMB_ALPHA_FACTOR); - layout->add(MENU_ENUM_LABEL_XMB_SCALE_FACTOR); - layout->add(MENU_ENUM_LABEL_XMB_FONT); - layout->addUIntColorButton("Menu Font Color: ", - MENU_ENUM_LABEL_MENU_FONT_COLOR_RED, - MENU_ENUM_LABEL_MENU_FONT_COLOR_GREEN, - MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE); - layout->add(MENU_ENUM_LABEL_XMB_LAYOUT); - layout->add(MENU_ENUM_LABEL_XMB_THEME); - layout->add(MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE); - layout->add(MENU_ENUM_LABEL_XMB_RIBBON_ENABLE); - layout->add(MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME); - layout->add(MENU_ENUM_LABEL_OZONE_MENU_COLOR_THEME); - layout->add(MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE); - layout->add(MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME); - layout->add(MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY); - layout->add(MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY); - layout->add(MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME); - - if (thumbnails) { - QHBoxLayout *thumbsLayout = new QHBoxLayout; - rarch_setting_t *leftThumbnails = menu_setting_find_enum(MENU_ENUM_LABEL_LEFT_THUMBNAILS); + rarch_setting_t *thumbnails = menu_setting_find_enum( + MENU_ENUM_LABEL_THUMBNAILS); - thumbsLayout->addWidget(new UIntRadioButtons(thumbnails)); + layout->add(MENU_ENUM_LABEL_MENU_WALLPAPER); + layout->add(MENU_ENUM_LABEL_DYNAMIC_WALLPAPER); + layout->add(MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY); + layout->add(MENU_ENUM_LABEL_MENU_FRAMEBUFFER_OPACITY); + layout->add(MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT); + layout->add(MENU_ENUM_LABEL_MENU_LINEAR_FILTER); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_ASPECT_RATIO_LOCK); + layout->add(MENU_ENUM_LABEL_RGUI_MENU_COLOR_THEME); + layout->add(MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET); + layout->add(MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE); + layout->add(MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE); + layout->add(MENU_ENUM_LABEL_XMB_ALPHA_FACTOR); + layout->add(MENU_ENUM_LABEL_XMB_SCALE_FACTOR); + layout->add(MENU_ENUM_LABEL_XMB_FONT); + layout->addUIntColorButton("Menu Font Color: ", + MENU_ENUM_LABEL_MENU_FONT_COLOR_RED, + MENU_ENUM_LABEL_MENU_FONT_COLOR_GREEN, + MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE); + layout->add(MENU_ENUM_LABEL_XMB_LAYOUT); + layout->add(MENU_ENUM_LABEL_XMB_THEME); + layout->add(MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE); + layout->add(MENU_ENUM_LABEL_XMB_RIBBON_ENABLE); + layout->add(MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME); + layout->add(MENU_ENUM_LABEL_OZONE_MENU_COLOR_THEME); + layout->add(MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE); + layout->add(MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME); + layout->add(MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY); + layout->add(MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY); + layout->add(MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME); - if (leftThumbnails) - thumbsLayout->addWidget(new UIntRadioButtons(leftThumbnails)); + if (thumbnails) + { + QHBoxLayout *thumbsLayout = new QHBoxLayout; + rarch_setting_t *leftThumbnails = menu_setting_find_enum(MENU_ENUM_LABEL_LEFT_THUMBNAILS); - layout->addRow(thumbsLayout); + thumbsLayout->addWidget(new UIntRadioButtons(thumbnails)); + + if (leftThumbnails) + thumbsLayout->addWidget(new UIntRadioButtons(leftThumbnails)); + + layout->addRow(thumbsLayout); + } + + layout->add(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS); + layout->add(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER); + layout->add(MENU_ENUM_LABEL_MENU_TICKER_TYPE); + layout->add(MENU_ENUM_LABEL_MENU_TICKER_SPEED); } - - layout->add(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS); - layout->add(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER); - layout->add(MENU_ENUM_LABEL_MENU_TICKER_TYPE); - layout->add(MENU_ENUM_LABEL_MENU_TICKER_SPEED); #endif widget->setLayout(layout); diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index fcf8af80a6..dbbe16591a 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -2070,9 +2070,9 @@ ViewOptionsDialog* MainWindow::viewOptionsDialog() void MainWindow::setCoreActions() { QListWidgetItem *currentPlaylistItem = m_listWidget->currentItem(); - ViewType viewType = getCurrentViewType(); - QHash hash = getCurrentContentHash(); - QString currentPlaylistFileName = QString(); + ViewType viewType = getCurrentViewType(); + QHash hash = getCurrentContentHash(); + QString currentPlaylistFileName = QString(); m_launchWithComboBox->clear(); @@ -2097,9 +2097,7 @@ void MainWindow::setCoreActions() QString coreName = hash["core_name"]; if (coreName.isEmpty()) - { coreName = ""; - } else { const char *detect_str = file_path_str(FILE_PATH_DETECT); @@ -2882,9 +2880,8 @@ void MainWindow::onLoadCoreClicked(const QStringList &extensionFilters) void MainWindow::initContentTableWidget() { - QListWidgetItem *item = m_listWidget->currentItem(); QString path; - int i = 0; + QListWidgetItem *item = m_listWidget->currentItem(); if (!item) return; @@ -2904,10 +2901,10 @@ void MainWindow::initContentTableWidget() if (path == ALL_PLAYLISTS_TOKEN) { + unsigned i; settings_t *settings = config_get_ptr(); QDir playlistDir(settings->paths.directory_playlist); QStringList playlists; - int i = 0; for (i = 0; i < m_playlistFiles.count(); i++) { @@ -2933,12 +2930,13 @@ void MainWindow::initContentTableWidget() void MainWindow::updateItemsCount() { - m_itemsCountLabel->setText(m_itemsCountLiteral.arg(m_proxyModel->rowCount())); + m_itemsCountLabel->setText( + m_itemsCountLiteral.arg(m_proxyModel->rowCount())); } void MainWindow::keyPressEvent(QKeyEvent *event) { -/* +#if 0 if (event->key() == Qt::Key_F5) { event->accept(); @@ -2946,7 +2944,7 @@ void MainWindow::keyPressEvent(QKeyEvent *event) return; } -*/ +#endif QMainWindow::keyPressEvent(event); } diff --git a/ui/drivers/ui_qt.cpp b/ui/drivers/ui_qt.cpp index 5bee2a3798..61f9f3c314 100644 --- a/ui/drivers/ui_qt.cpp +++ b/ui/drivers/ui_qt.cpp @@ -97,7 +97,9 @@ void ThumbnailWidget::dragEnterEvent(QDragEnterEvent *event) event->acceptProposedAction(); } -/* Workaround for QTBUG-72844. Without it, you can't drop on this if you first drag over another widget that doesn't accept drops. */ +/* Workaround for QTBUG-72844. Without it, you can't + * drop on this if you first drag over another + * widget that doesn't accept drops. */ void ThumbnailWidget::dragMoveEvent(QDragMoveEvent *event) { event->acceptProposedAction(); @@ -155,10 +157,10 @@ QSize ThumbnailLabel::sizeHint() const void ThumbnailLabel::paintEvent(QPaintEvent *event) { - int w = width(); - int h = height(); QStyleOption o; QPainter p; + int w = width(); + int h = height(); event->accept(); @@ -234,70 +236,70 @@ static void ui_companion_qt_deinit(void *data) static void* ui_companion_qt_init(void) { - ui_companion_qt_t *handle = (ui_companion_qt_t*)calloc(1, sizeof(*handle)); - MainWindow *mainwindow = NULL; - QHBoxLayout *browserButtonsHBoxLayout = NULL; - QVBoxLayout *layout = NULL; - QVBoxLayout *playlistViewsLayout = NULL; - QVBoxLayout *launchWithWidgetLayout = NULL; - QHBoxLayout *coreComboBoxLayout = NULL; - QMenuBar *menu = NULL; - QDesktopWidget *desktop = NULL; - QMenu *fileMenu = NULL; - QMenu *editMenu = NULL; - QMenu *viewMenu = NULL; - QMenu *viewClosedDocksMenu = NULL; -#ifdef Q_OS_WIN - QMenu *toolsMenu = NULL; - QMenu *updaterMenu = NULL; -#endif - QMenu *helpMenu = NULL; - QRect desktopRect; - QDockWidget *thumbnailDock = NULL; - QDockWidget *thumbnail2Dock = NULL; - QDockWidget *thumbnail3Dock = NULL; - QDockWidget *browserAndPlaylistTabDock = NULL; - QDockWidget *coreSelectionDock = NULL; - QTabWidget *browserAndPlaylistTabWidget = NULL; - QStackedWidget *centralWidget = NULL; - QStackedWidget *widget = NULL; - QFrame *browserWidget = NULL; - QFrame *playlistWidget = NULL; - QWidget *coreSelectionWidget = NULL; - QWidget *launchWithWidget = NULL; - ThumbnailWidget *thumbnailWidget = NULL; - ThumbnailWidget *thumbnail2Widget = NULL; - ThumbnailWidget *thumbnail3Widget = NULL; - QPushButton *browserDownloadsButton = NULL; - QPushButton *browserUpButton = NULL; - QPushButton *browserStartButton = NULL; - ThumbnailLabel *thumbnail = NULL; - ThumbnailLabel *thumbnail2 = NULL; - ThumbnailLabel *thumbnail3 = NULL; - QAction *editSearchAction = NULL; - QAction *loadCoreAction = NULL; - QAction *unloadCoreAction = NULL; - QAction *exitAction = NULL; - QComboBox *launchWithComboBox = NULL; - QSettings *qsettings = NULL; - QListWidget *listWidget = NULL; - QString initialPlaylist; - bool foundPlaylist = false; - int i = 0; + QString initialPlaylist; + QRect desktopRect; + ui_companion_qt_t *handle = (ui_companion_qt_t*) + calloc(1, sizeof(*handle)); + MainWindow *mainwindow = NULL; + QHBoxLayout *browserButtonsHBoxLayout = NULL; + QVBoxLayout *layout = NULL; + QVBoxLayout *launchWithWidgetLayout = NULL; + QHBoxLayout *coreComboBoxLayout = NULL; + QMenuBar *menu = NULL; + QDesktopWidget *desktop = NULL; + QMenu *fileMenu = NULL; + QMenu *editMenu = NULL; + QMenu *viewMenu = NULL; + QMenu *viewClosedDocksMenu = NULL; +#ifdef Q_OS_WIN + QMenu *toolsMenu = NULL; + QMenu *updaterMenu = NULL; +#endif + QMenu *helpMenu = NULL; + QDockWidget *thumbnailDock = NULL; + QDockWidget *thumbnail2Dock = NULL; + QDockWidget *thumbnail3Dock = NULL; + QDockWidget *browserAndPlaylistTabDock = NULL; + QDockWidget *coreSelectionDock = NULL; + QTabWidget *browserAndPlaylistTabWidget = NULL; + QStackedWidget *centralWidget = NULL; + QStackedWidget *widget = NULL; + QFrame *browserWidget = NULL; + QFrame *playlistWidget = NULL; + QWidget *coreSelectionWidget = NULL; + QWidget *launchWithWidget = NULL; + ThumbnailWidget *thumbnailWidget = NULL; + ThumbnailWidget *thumbnail2Widget = NULL; + ThumbnailWidget *thumbnail3Widget = NULL; + QPushButton *browserDownloadsButton = NULL; + QPushButton *browserUpButton = NULL; + QPushButton *browserStartButton = NULL; + ThumbnailLabel *thumbnail = NULL; + ThumbnailLabel *thumbnail2 = NULL; + ThumbnailLabel *thumbnail3 = NULL; + QAction *editSearchAction = NULL; + QAction *loadCoreAction = NULL; + QAction *unloadCoreAction = NULL; + QAction *exitAction = NULL; + QComboBox *launchWithComboBox = NULL; + QSettings *qsettings = NULL; + QListWidget *listWidget = NULL; + bool foundPlaylist = false; if (!handle) return NULL; - handle->app = static_cast(ui_application_qt.initialize()); - handle->window = static_cast(ui_window_qt.init()); + handle->app = static_cast + (ui_application_qt.initialize()); + handle->window = static_cast(ui_window_qt.init()); - desktop = qApp->desktop(); - desktopRect = desktop->availableGeometry(); + desktop = qApp->desktop(); + desktopRect = desktop->availableGeometry(); - mainwindow = handle->window->qtWindow; + mainwindow = handle->window->qtWindow; - qsettings = mainwindow->settings(); + qsettings = mainwindow->settings(); initialPlaylist = qsettings->value("initial_playlist", mainwindow->getSpecialPlaylistPath(SPECIAL_PLAYLIST_HISTORY)).toString(); @@ -307,9 +309,9 @@ static void* ui_companion_qt_init(void) mainwindow->setWindowTitle("RetroArch"); mainwindow->setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks | GROUPED_DRAGGING); - listWidget = mainwindow->playlistListWidget(); + listWidget = mainwindow->playlistListWidget(); - widget = mainwindow->playlistViews(); + widget = mainwindow->playlistViews(); widget->setContextMenuPolicy(Qt::CustomContextMenu); QObject::connect(widget, SIGNAL(filesDropped(QStringList)), mainwindow, SLOT(onPlaylistFilesDropped(QStringList))); From aa588dec35f60a3932235296d386a6a517b388b5 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 15 Apr 2019 23:14:49 -0400 Subject: [PATCH 214/237] set default language on first startup according to OS setting (initial *nix implementation) --- configuration.c | 5 ++- frontend/drivers/platform_ctr.c | 1 + frontend/drivers/platform_darwin.m | 7 ++-- frontend/drivers/platform_dos.c | 1 + frontend/drivers/platform_emscripten.c | 1 + frontend/drivers/platform_gx.c | 1 + frontend/drivers/platform_null.c | 1 + frontend/drivers/platform_orbis.c | 1 + frontend/drivers/platform_ps2.c | 1 + frontend/drivers/platform_ps3.c | 1 + frontend/drivers/platform_psp.c | 1 + frontend/drivers/platform_qnx.c | 1 + frontend/drivers/platform_switch.c | 1 + frontend/drivers/platform_unix.c | 10 ++++++ frontend/drivers/platform_uwp.c | 1 + frontend/drivers/platform_wiiu.c | 1 + frontend/drivers/platform_win32.c | 1 + frontend/drivers/platform_xdk.c | 1 + frontend/drivers/platform_xenon.c | 1 + frontend/frontend_driver.c | 9 +++++ frontend/frontend_driver.h | 3 ++ retroarch.c | 49 ++++++++++++++++++++++++++ retroarch.h | 2 ++ 23 files changed, 97 insertions(+), 4 deletions(-) diff --git a/configuration.c b/configuration.c index 9dfd351488..5fff82057d 100644 --- a/configuration.c +++ b/configuration.c @@ -1754,7 +1754,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("netplay_share_analog", &settings->uints.netplay_share_analog, true, netplay_share_analog, false); #endif #ifdef HAVE_LANGEXTRA - SETTING_UINT("user_language", msg_hash_get_uint(MSG_HASH_USER_LANGUAGE), true, RETRO_LANGUAGE_ENGLISH, false); + SETTING_UINT("user_language", msg_hash_get_uint(MSG_HASH_USER_LANGUAGE), true, def_user_language, false); #endif SETTING_UINT("bundle_assets_extract_version_current", &settings->uints.bundle_assets_extract_version_current, true, 0, false); SETTING_UINT("bundle_assets_extract_last_version", &settings->uints.bundle_assets_extract_last_version, true, 0, false); @@ -3281,6 +3281,9 @@ static bool config_load_file(const char *path, bool set_defaults, frontend_driver_set_sustained_performance_mode(settings->bools.sustained_performance_mode); recording_driver_update_streaming_url(); + if (!config_entry_exists(conf, "user_language")) + msg_hash_set_uint(MSG_HASH_USER_LANGUAGE, frontend_driver_get_user_language()); + ret = true; end: if (conf) diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c index 41254ef7ea..9375e8fcad 100644 --- a/frontend/drivers/platform_ctr.c +++ b/frontend/drivers/platform_ctr.c @@ -604,5 +604,6 @@ frontend_ctx_driver_t frontend_ctx_ctr = NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "ctr", }; diff --git a/frontend/drivers/platform_darwin.m b/frontend/drivers/platform_darwin.m index ab3cbdb6b2..5fbe53ca9d 100644 --- a/frontend/drivers/platform_darwin.m +++ b/frontend/drivers/platform_darwin.m @@ -773,10 +773,11 @@ frontend_ctx_driver_t frontend_ctx_darwin = { NULL, /* watch_path_for_changes */ NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ - #if (defined(OSX) && !(defined(__ppc__) || defined(__ppc64__))) +#if (defined(OSX) && !(defined(__ppc__) || defined(__ppc64__))) frontend_darwin_get_cpu_model_name, - #else +#else NULL, - #endif +#endif + NULL, /* get_user_language */ "darwin", }; diff --git a/frontend/drivers/platform_dos.c b/frontend/drivers/platform_dos.c index daac64064f..dfce99e2d1 100644 --- a/frontend/drivers/platform_dos.c +++ b/frontend/drivers/platform_dos.c @@ -72,5 +72,6 @@ frontend_ctx_driver_t frontend_ctx_dos = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "dos", }; diff --git a/frontend/drivers/platform_emscripten.c b/frontend/drivers/platform_emscripten.c index df4dad555c..8cfcce53dd 100644 --- a/frontend/drivers/platform_emscripten.c +++ b/frontend/drivers/platform_emscripten.c @@ -267,5 +267,6 @@ frontend_ctx_driver_t frontend_ctx_emscripten = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "emscripten" }; diff --git a/frontend/drivers/platform_gx.c b/frontend/drivers/platform_gx.c index 5fb04661e9..0e47dd0d5d 100644 --- a/frontend/drivers/platform_gx.c +++ b/frontend/drivers/platform_gx.c @@ -548,5 +548,6 @@ frontend_ctx_driver_t frontend_ctx_gx = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "gx", }; diff --git a/frontend/drivers/platform_null.c b/frontend/drivers/platform_null.c index 7d4ec37558..1954dd0a34 100644 --- a/frontend/drivers/platform_null.c +++ b/frontend/drivers/platform_null.c @@ -48,5 +48,6 @@ frontend_ctx_driver_t frontend_ctx_null = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "null", }; diff --git a/frontend/drivers/platform_orbis.c b/frontend/drivers/platform_orbis.c index f284dbf898..cb2e64fe8f 100644 --- a/frontend/drivers/platform_orbis.c +++ b/frontend/drivers/platform_orbis.c @@ -369,5 +369,6 @@ frontend_ctx_driver_t frontend_ctx_orbis = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "orbis", }; diff --git a/frontend/drivers/platform_ps2.c b/frontend/drivers/platform_ps2.c index 1ac58934d2..09ac87c187 100644 --- a/frontend/drivers/platform_ps2.c +++ b/frontend/drivers/platform_ps2.c @@ -415,5 +415,6 @@ frontend_ctx_driver_t frontend_ctx_ps2 = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "null", }; diff --git a/frontend/drivers/platform_ps3.c b/frontend/drivers/platform_ps3.c index c796b6f07f..94299c5760 100644 --- a/frontend/drivers/platform_ps3.c +++ b/frontend/drivers/platform_ps3.c @@ -639,5 +639,6 @@ frontend_ctx_driver_t frontend_ctx_ps3 = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "ps3", }; diff --git a/frontend/drivers/platform_psp.c b/frontend/drivers/platform_psp.c index 25045be15c..3832f7fcf3 100644 --- a/frontend/drivers/platform_psp.c +++ b/frontend/drivers/platform_psp.c @@ -534,6 +534,7 @@ frontend_ctx_driver_t frontend_ctx_psp = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ #ifdef VITA "vita", #else diff --git a/frontend/drivers/platform_qnx.c b/frontend/drivers/platform_qnx.c index eb2bd40857..30cb376523 100644 --- a/frontend/drivers/platform_qnx.c +++ b/frontend/drivers/platform_qnx.c @@ -208,5 +208,6 @@ frontend_ctx_driver_t frontend_ctx_qnx = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "qnx", }; diff --git a/frontend/drivers/platform_switch.c b/frontend/drivers/platform_switch.c index 98cb62d335..8ee91405a1 100644 --- a/frontend/drivers/platform_switch.c +++ b/frontend/drivers/platform_switch.c @@ -945,5 +945,6 @@ frontend_ctx_driver_t frontend_ctx_switch = NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "switch", }; diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index f823dfb698..7ae46447ca 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -2494,6 +2494,15 @@ static const char* frontend_unix_get_cpu_model_name(void) #endif } +enum retro_language frontend_unix_get_user_language(void) +{ +#ifdef ANDROID + return RETRO_LANGUAGE_ENGLISH; +#else + return rarch_get_language_from_iso(getenv("LANG")); +#endif +} + frontend_ctx_driver_t frontend_ctx_unix = { frontend_unix_get_env, /* environment_get */ frontend_unix_init, /* init */ @@ -2539,6 +2548,7 @@ frontend_ctx_driver_t frontend_ctx_unix = { frontend_unix_check_for_path_changes, frontend_unix_set_sustained_performance_mode, frontend_unix_get_cpu_model_name, + frontend_unix_get_user_language, #ifdef ANDROID "android" #else diff --git a/frontend/drivers/platform_uwp.c b/frontend/drivers/platform_uwp.c index ce33bfcd7e..fecced3b6d 100644 --- a/frontend/drivers/platform_uwp.c +++ b/frontend/drivers/platform_uwp.c @@ -447,5 +447,6 @@ frontend_ctx_driver_t frontend_ctx_uwp = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "uwp" }; diff --git a/frontend/drivers/platform_wiiu.c b/frontend/drivers/platform_wiiu.c index 5559deca3b..cf4bc15edc 100644 --- a/frontend/drivers/platform_wiiu.c +++ b/frontend/drivers/platform_wiiu.c @@ -302,6 +302,7 @@ frontend_ctx_driver_t frontend_ctx_wiiu = NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "wiiu", NULL, /* get_video_driver */ }; diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index 35bd1f0a2e..c6fb1157f3 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -603,5 +603,6 @@ frontend_ctx_driver_t frontend_ctx_win32 = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ frontend_win32_get_cpu_model_name, + NULL, /* get_user_language */ "win32" }; diff --git a/frontend/drivers/platform_xdk.c b/frontend/drivers/platform_xdk.c index 8fb2e5ebc7..a638ebe1f5 100644 --- a/frontend/drivers/platform_xdk.c +++ b/frontend/drivers/platform_xdk.c @@ -434,5 +434,6 @@ frontend_ctx_driver_t frontend_ctx_xdk = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "xdk", }; diff --git a/frontend/drivers/platform_xenon.c b/frontend/drivers/platform_xenon.c index 0e9988f0a4..654b76d92e 100644 --- a/frontend/drivers/platform_xenon.c +++ b/frontend/drivers/platform_xenon.c @@ -95,5 +95,6 @@ frontend_ctx_driver_t frontend_ctx_qnx = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ NULL, /* get_cpu_model_name */ + NULL, /* get_user_language */ "xenon", }; diff --git a/frontend/frontend_driver.c b/frontend/frontend_driver.c index cfb0ce8955..9c6c6e3ce6 100644 --- a/frontend/frontend_driver.c +++ b/frontend/frontend_driver.c @@ -18,6 +18,7 @@ #include #include +#include #if defined(_3DS) #include <3ds.h> @@ -464,4 +465,12 @@ const char* frontend_driver_get_cpu_model_name(void) return NULL; return frontend->get_cpu_model_name(); } + +enum retro_language frontend_driver_get_user_language(void) +{ + frontend_ctx_driver_t *frontend = frontend_get_ptr(); + if (!frontend || !frontend->get_user_language) + return RETRO_LANGUAGE_ENGLISH; + return frontend->get_user_language(); +} #endif diff --git a/frontend/frontend_driver.h b/frontend/frontend_driver.h index 76119f660e..af141d23df 100644 --- a/frontend/frontend_driver.h +++ b/frontend/frontend_driver.h @@ -107,6 +107,7 @@ typedef struct frontend_ctx_driver bool (*check_for_path_changes)(path_change_data_t *change_data); void (*set_sustained_performance_mode)(bool on); const char* (*get_cpu_model_name)(void); + enum retro_language (*get_user_language)(void); const char *ident; @@ -214,6 +215,8 @@ void frontend_driver_set_sustained_performance_mode(bool on); const char* frontend_driver_get_cpu_model_name(void); +enum retro_language frontend_driver_get_user_language(void); + RETRO_END_DECLS #endif diff --git a/retroarch.c b/retroarch.c index 429017fc69..7d2a108e6e 100644 --- a/retroarch.c +++ b/retroarch.c @@ -5415,3 +5415,52 @@ void rarch_log_file_deinit(void) retro_main_log_file_init(NULL, false); } } + +enum retro_language rarch_get_language_from_iso(const char *iso639) +{ + unsigned i; + enum retro_language lang = RETRO_LANGUAGE_ENGLISH; + + struct lang_pair + { + const char *iso639; + enum retro_language lang; + }; + + const struct lang_pair pairs[] = + { + {"en", RETRO_LANGUAGE_ENGLISH}, + {"ja", RETRO_LANGUAGE_JAPANESE}, + {"fr", RETRO_LANGUAGE_FRENCH}, + {"es", RETRO_LANGUAGE_SPANISH}, + {"de", RETRO_LANGUAGE_GERMAN}, + {"it", RETRO_LANGUAGE_ITALIAN}, + {"nl", RETRO_LANGUAGE_DUTCH}, + {"pt_BR", RETRO_LANGUAGE_PORTUGUESE_BRAZIL}, + {"pt_PT", RETRO_LANGUAGE_PORTUGUESE_PORTUGAL}, + {"pt", RETRO_LANGUAGE_PORTUGUESE_PORTUGAL}, + {"ru", RETRO_LANGUAGE_RUSSIAN}, + {"ko", RETRO_LANGUAGE_KOREAN}, + {"zh_CN", RETRO_LANGUAGE_CHINESE_SIMPLIFIED}, + {"zh_SG", RETRO_LANGUAGE_CHINESE_SIMPLIFIED}, + {"zh_HK", RETRO_LANGUAGE_CHINESE_TRADITIONAL}, + {"zh_TW", RETRO_LANGUAGE_CHINESE_TRADITIONAL}, + {"zh", RETRO_LANGUAGE_CHINESE_SIMPLIFIED}, + {"eo", RETRO_LANGUAGE_ESPERANTO}, + {"pl", RETRO_LANGUAGE_POLISH}, + {"vi", RETRO_LANGUAGE_VIETNAMESE}, + {"ar", RETRO_LANGUAGE_ARABIC}, + {"el", RETRO_LANGUAGE_GREEK}, + }; + + for (i = 0; i < sizeof(pairs) / sizeof(pairs[0]); i++) + { + if (strcasestr(iso639, pairs[i].iso639)) + { + lang = pairs[i].lang; + break; + } + } + + return lang; +} diff --git a/retroarch.h b/retroarch.h index 8063848ae9..b4b41fd7ec 100644 --- a/retroarch.h +++ b/retroarch.h @@ -432,6 +432,8 @@ void rarch_log_file_init(void); void rarch_log_file_deinit(void); +enum retro_language rarch_get_language_from_iso(const char *lang); + RETRO_END_DECLS #endif From 1ecc5fd9d148a6e650d8f657b0b6fc91f96a8ff9 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Tue, 16 Apr 2019 00:41:59 -0400 Subject: [PATCH 215/237] unix: only set default language if support for multiple languages is compiled in --- frontend/drivers/platform_unix.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index 7ae46447ca..4051a9873e 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -2496,11 +2496,15 @@ static const char* frontend_unix_get_cpu_model_name(void) enum retro_language frontend_unix_get_user_language(void) { + enum retro_language lang = RETRO_LANGUAGE_ENGLISH; +#ifdef HAVE_LANGEXTRA #ifdef ANDROID return RETRO_LANGUAGE_ENGLISH; #else - return rarch_get_language_from_iso(getenv("LANG")); + lang = rarch_get_language_from_iso(getenv("LANG")); #endif +#endif + return lang; } frontend_ctx_driver_t frontend_ctx_unix = { From ffb07f3076afa1ead6f8493f6159f58f98d286b4 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Tue, 16 Apr 2019 00:42:29 -0400 Subject: [PATCH 216/237] win32: set default language to OS preferred language on first start --- frontend/drivers/platform_win32.c | 57 ++++++++++++++++++++++++++++++- retroarch.c | 1 + 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index c6fb1157f3..032d27a656 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -575,6 +575,61 @@ static const char* frontend_win32_get_cpu_model_name(void) #endif } +enum retro_language frontend_win32_get_user_language(void) +{ + enum retro_language lang = RETRO_LANGUAGE_ENGLISH; +#if defined(HAVE_LANGEXTRA) && !defined(_XBOX) +#if (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500) || !defined(_MSC_VER) + LANGID langid = GetUserDefaultUILanguage(); + unsigned i; + + struct lang_pair + { + unsigned short lang_ident; + enum retro_language lang; + }; + + /* https://docs.microsoft.com/en-us/windows/desktop/Intl/language-identifier-constants-and-strings */ + const struct lang_pair pairs[] = + { + {0x9, RETRO_LANGUAGE_ENGLISH}, + {0x11, RETRO_LANGUAGE_JAPANESE}, + {0xc, RETRO_LANGUAGE_FRENCH}, + {0xa, RETRO_LANGUAGE_SPANISH}, + {0x7, RETRO_LANGUAGE_GERMAN}, + {0x10, RETRO_LANGUAGE_ITALIAN}, + {0x13, RETRO_LANGUAGE_DUTCH}, + {0x416, RETRO_LANGUAGE_PORTUGUESE_BRAZIL}, + {0x816, RETRO_LANGUAGE_PORTUGUESE_PORTUGAL}, + {0x16, RETRO_LANGUAGE_PORTUGUESE_PORTUGAL}, + {0x19, RETRO_LANGUAGE_RUSSIAN}, + {0x12, RETRO_LANGUAGE_KOREAN}, + {0xC04, RETRO_LANGUAGE_CHINESE_TRADITIONAL}, /* HK/PRC */ + {0x1404, RETRO_LANGUAGE_CHINESE_TRADITIONAL}, /* MO */ + {0x1004, RETRO_LANGUAGE_CHINESE_SIMPLIFIED}, /* SG */ + {0x7c04, RETRO_LANGUAGE_CHINESE_TRADITIONAL}, /* neutral */ + {0x4, RETRO_LANGUAGE_CHINESE_SIMPLIFIED}, /* neutral */ + /* MS does not support Esperanto */ + /*{0x0, RETRO_LANGUAGE_ESPERANTO},*/ + {0x15, RETRO_LANGUAGE_POLISH}, + {0x2a, RETRO_LANGUAGE_VIETNAMESE}, + {0x1, RETRO_LANGUAGE_ARABIC}, + {0x8, RETRO_LANGUAGE_GREEK}, + }; + + for (i = 0; i < sizeof(pairs) / sizeof(pairs[0]); i++) + { + if ((langid & pairs[i].lang_ident) == pairs[i].lang_ident) + { + lang = pairs[i].lang; + break; + } + } +#endif +#endif + return lang; +} + frontend_ctx_driver_t frontend_ctx_win32 = { frontend_win32_environment_get, frontend_win32_init, @@ -603,6 +658,6 @@ frontend_ctx_driver_t frontend_ctx_win32 = { NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ frontend_win32_get_cpu_model_name, - NULL, /* get_user_language */ + frontend_win32_get_user_language, "win32" }; diff --git a/retroarch.c b/retroarch.c index 7d2a108e6e..1a7bd7a246 100644 --- a/retroarch.c +++ b/retroarch.c @@ -44,6 +44,7 @@ #include #include +#include #include #include

\n" + "In order for content to be correctly scanned, you must:\n" + "
  • have a compatible core already downloaded
  • \n" + "
  • have \"Core Info Files\" updated via Online Updater
  • \n" + "
  • have \"Databases\" updated via Online Updater
  • \n" + "
  • restart RetroArch if any of the above was just done
\n" + "Finally, the content must match existing databases from
here. If it is still not working, consider submitting a bug report." + ) +#endif +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHOW_WIMP, + "Masaüstü Menüsünü Göster" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHOW_WIMP, + "Kapalıysa, masaüstü menüsünü açar." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, + "Bunu bir daha gösterme" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_STOP, + "Durdur" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE, + "Bağdaştırılmış Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS, + "Hidden Playlists" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_HIDE, + "Sakla" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_HIGHLIGHT_COLOR, + "Highlight color:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CHOOSE, + "&Seç..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_COLOR, + "Select Color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_THEME, + "Select Theme" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CUSTOM_THEME, + "Custom Theme" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_PATH_IS_BLANK, + "Dosya yolu boş." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_IS_EMPTY, + "Dosya boş." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_READ_OPEN_FAILED, + "Dosya okumak için açılamadı." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_WRITE_OPEN_FAILED, + "Dosya yazmak için açılamadı." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST, + "Dosya bulunmuyor." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SUGGEST_LOADED_CORE_FIRST, + "Suggest loaded core first:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ZOOM, + "Zoom" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_VIEW, + "View" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_ICONS, + "İkonlar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_LIST, + "Liste" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS, + "Overrides" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_OVERRIDE_OPTIONS, + "Options for overriding the global configuration." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY, + "Ses akışının oynatılmasını başlatır. Tamamlandığında, mevcut ses akışını bellekten kaldıracak." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_LOOPED, + "Ses akışının oynatılmasını başlatır. Tamamlandığında, tekrar baştan başlayıp tekrar çalmaya başlayacaktır." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_SEQUENTIAL, + "Ses akışının oynatılmasını başlatır. Tamamlandığında, sıralı sırayla bir sonraki ses akışına atlar ve bu davranışı tekrarlar. Albüm çalma modu olarak kullanışlıdır." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_STOP, + "Ses akışının çalınmasını durdurur, ancak bellekten çıkarmaz. 'Oynat' seçeneğini seçerek tekrar oynamaya başlayabilirsiniz." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_REMOVE, + "Ses akışının çalınmasını durdurur ve tamamen bellekten kaldırır." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_VOLUME, + "Ses akışının sesini ayarlayın." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ADD_TO_MIXER, + "Ses parçasını kullanılabilir bir ses akışı yuvasına ekleyin. Şu anda mevcut slot bulunmuyorsa, dikkate alınmaz." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ADD_TO_MIXER_AND_PLAY, + "Ses parçasını kullanılabilir bir ses akışı yuvasına ekleyin ve oynatın. Şu anda mevcut slot bulunmuyorsa, dikkate alınmaz." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY, + "Oynat" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_LOOPED, + "Oynat (Döngüsel)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_SEQUENTIAL, + "Oynat (Ardışık)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_STOP, + "Durdur" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_REMOVE, + "Kaldır" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_VOLUME, + "Ses" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DETECT_CORE_LIST_OK_CURRENT_CORE, + "Geçerli Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, + "Temizle" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ACHIEVEMENT_PAUSE, + "Mevcut oturum için başarıları duraklatın (Bu işlem konum kaydetmeleri, hileleri, geri sarma, duraklatma ve slow-motion etkinleştirir)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ACHIEVEMENT_RESUME, + "Mevcut oturum için başarıları sürdürün (Bu işlem konum kaydetmeleri, hileleri, geri sarma, duraklatma ve slow-motion'ı devre dışı bırakır ve mevcut oyunu sıfırlar)." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, + "Menü-İçinde" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "Oyun-İçinde" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "Oyun-İçinde (Durdurulduğunda)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Oynatılıyor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Durduruldu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, + "Discord Rich Presence" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DISCORD_ALLOW, + "Discord uygulamasının, oynatılan içerik hakkında daha fazla veri göstermesine izin verir.\n" + "NOT: Tarayıcı sürümüyle çalışmaz, yalnızca masaüstü istemcisiyle çalışır." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_INPUT, + "Input" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIDI_INPUT, + "Select input device." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_OUTPUT, + "Output" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIDI_OUTPUT, + "Select output device." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_VOLUME, + "Ses" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIDI_VOLUME, + "Set output volume (%)." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_POWER_MANAGEMENT_SETTINGS, + "Güç yönetimi" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_POWER_MANAGEMENT_SETTINGS, + "Güç yönetimi ayarlarını değiştirin." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SUSTAINED_PERFORMANCE_MODE, + "Sürdürülebilir Performans Modu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_MPV_SUPPORT, + "mpv desteği" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_IDX, + "Indeks" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_MATCH_IDX, + "View Match #" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_MATCH, + "Match Address: %08X Mask: %02X" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_MATCH, + "Create Code Match #" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_MATCH, + "Delete Match #" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_BROWSE_MEMORY, + "Browse Address: %08X" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DESC, + "Açıklama" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_STATE, + "Etkinleştirildi" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_CODE, + "Code" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_HANDLER, + "Handler" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_MEMORY_SEARCH_SIZE, + "Memory Search Size" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_TYPE, + "Tip" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_VALUE, + "Değer" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS, + "Memory Address" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS_BIT_POSITION, + "Memory Address Mask" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_TYPE, + "Rumble When Memory" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_VALUE, + "Rumble Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PORT, + "Rumble Port" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_STRENGTH, + "Rumble Primary Strength" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_DURATION, + "Rumble Primary Duration (ms)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_STRENGTH, + "Rumble Secondary Strength" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_DURATION, + "Rumble Secondary Duration (ms)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_REPEAT_COUNT, + "Number of Iterations" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_REPEAT_ADD_TO_VALUE, + "Value Increase Each Iteration" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_REPEAT_ADD_TO_ADDRESS, + "Address Increase Each Iteration" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_AFTER, + "Add New Cheat After This One" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BEFORE, + "Add New Cheat Before This One" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_AFTER, + "Copy This Cheat After" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_BEFORE, + "Copy This Cheat Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE, + "Delete This Cheat" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_EMU, + "Emulator" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_RETRO, + "RetroArch" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_DISABLED, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_SET_TO_VALUE, + "Set To Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_INCREASE_VALUE, + "Increase By Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_DECREASE_VALUE, + "Decrease By Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_EQ, + "Run next cheat if value = memory" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_NEQ, + "Run next cheat if value != memory" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_LT, + "Run next cheat if value < memory" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_GT, + "Run next cheat if value > memory" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_DISABLED, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_CHANGES, + "Değişiklikler" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_DOES_NOT_CHANGE, + "Does Not Change" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_INCREASE, + "Increases" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_DECREASE, + "Decreases" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_EQ_VALUE, + "= Rumble Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_NEQ_VALUE, + "!= Rumble Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_LT_VALUE, + "< Rumble Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_GT_VALUE, + "> Rumble Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_INCREASE_BY_VALUE, + "Increases by Rumble Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_DECREASE_BY_VALUE, + "Decreases by Rumble Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_1, + "1-bit, maksimum değer = 0x01" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_2, + "2-bit, maksimum değer = 0x03" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_4, + "4-bit, maksimum değer = 0x0F" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_8, + "8-bit, maksimum değer = 0xFF" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_16, + "16-bit, maksimum değer = 0xFFFF" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_32, + "32-bit, maksimum değer = 0xFFFFFFFF" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_0, + "1" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_1, + "2" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_2, + "3" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_3, + "4" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_4, + "5" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_5, + "6" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_6, + "7" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_7, + "8" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_8, + "9" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_9, + "10" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_10, + "11" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_11, + "12" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_12, + "13" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_13, + "14" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_14, + "15" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_15, + "16" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_16, + "All" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_CONT, + "Hile Aramaya Başla veya Devam Et" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_RESTART, + "Hile Aramasını Başlat veya Yeniden Başlat" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EXACT, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LT, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GT, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQ, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GTE, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LTE, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_NEQ, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQPLUS, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQMINUS, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_MATCHES, + "Add the %u Matches to Your List" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_VIEW_MATCHES, + "View the List of %u Matches" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_CREATE_OPTION, + "Create Code From This Match" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_OPTION, + "Delete This Match" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_TOP, + "Add New Code to Top" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BOTTOM, + "Add New Code to Bottom" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_ALL, + "Delete All Codes" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RELOAD_CHEATS, + "Reload Game-Specific Cheats" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT_VAL, + "Equal to %u (%X)" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_LT_VAL, + "Less Than Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_GT_VAL, + "Greater Than Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_LTE_VAL, + "Less Than or Equal To Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_GTE_VAL, + "Greater Than or Equal To Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_EQ_VAL, + "Equal to Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ_VAL, + "Not Equal to Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS_VAL, + "Equal to Before+%u (%X)" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS_VAL, + "Equal to Before-%u (%X)" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS, + "Start or Continue Cheat Search" + ) +MSG_HASH( + MSG_CHEAT_INIT_SUCCESS, + "Successfully started cheat search" + ) +MSG_HASH( + MSG_CHEAT_INIT_FAIL, + "Failed to start cheat search" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_NOT_INITIALIZED, + "Searching has not been initialized/started" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_FOUND_MATCHES, + "New match count = %u" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_BIG_ENDIAN, + "Big Endian" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADDED_MATCHES_SUCCESS, + "Added %u matches" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADDED_MATCHES_FAIL, + "Failed to add matches" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS, + "Created code from match" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADD_MATCH_FAIL, + "Failed to create code" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS, + "Deleted match" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADDED_MATCHES_TOO_MANY, + "Not enough room. The total number of cheats you can have is 100." + ) +MSG_HASH( + MSG_CHEAT_ADD_TOP_SUCCESS, + "New cheat added to top of list." + ) +MSG_HASH( + MSG_CHEAT_ADD_BOTTOM_SUCCESS, + "New cheat added to bottom of list." + ) +MSG_HASH( + MSG_CHEAT_DELETE_ALL_INSTRUCTIONS, + "Press right five times to delete all cheats." + ) +MSG_HASH( + MSG_CHEAT_DELETE_ALL_SUCCESS, + "All cheats deleted." + ) +MSG_HASH( + MSG_CHEAT_ADD_BEFORE_SUCCESS, + "New cheat added before this one." + ) +MSG_HASH( + MSG_CHEAT_ADD_AFTER_SUCCESS, + "New cheat added after this one." + ) +MSG_HASH( + MSG_CHEAT_COPY_BEFORE_SUCCESS, + "Cheat copied before this one." + ) +MSG_HASH( + MSG_CHEAT_COPY_AFTER_SUCCESS, + "Cheat copied after this one." + ) +MSG_HASH( + MSG_CHEAT_DELETE_SUCCESS, + "Cheat deleted." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PROGRESS, + "Progress:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_LIST_MAX_COUNT, + "\"All Playlists\" max list entries:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_GRID_MAX_COUNT, + "\"All Playlists\" max grid entries:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SHOW_HIDDEN_FILES, + "Show hidden files and folders:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST, + "Yeni Oynatma Listesi" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ENTER_NEW_PLAYLIST_NAME, + "Lütfen yeni oynatma listesi adını girin:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DELETE_PLAYLIST, + "Oynatma Listesini Sil" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RENAME_PLAYLIST, + "Oynatma Listesini Yeniden Adlandır" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST, + "\"%1\" oynatma listesini silmek istediğine emin misin?" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_QUESTION, + "Question" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_DELETE_FILE, + "Dosya silinemedi." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_RENAME_FILE, + "Dosya yeniden adlandırılamadı." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_GATHERING_LIST_OF_FILES, + "Dosyaların toplanıyor ..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADDING_FILES_TO_PLAYLIST, + "Çalma listesine dosyalar ekleniyor ..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY, + "Playlist Entry" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_NAME, + "Ad:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_PATH, + "Dizin:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_CORE, + "Core:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_DATABASE, + "Veritabanı:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_EXTENSIONS, + "Uzantılar:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_EXTENSIONS_PLACEHOLDER, + "(space-separated; includes all by default)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_FILTER_INSIDE_ARCHIVES, + "Filter inside archives" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FOR_THUMBNAILS, + "(used to find thumbnails)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST_ITEM, + "Are you sure you want to delete the item \"%1\"?" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CANNOT_ADD_TO_ALL_PLAYLISTS, + "Lütfen önce tek bir oynatma listesi seçin." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DELETE, + "Kaldır" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADD_ENTRY, + "Giriş Ekle..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADD_FILES, + "Dosya(lar) ekle..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADD_FOLDER, + "Klasör Ekle..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_EDIT, + "Düzenle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_FILES, + "Dosyaları Seç" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_FOLDER, + "Klasörleri Seç" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FIELD_MULTIPLE, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_UPDATE_PLAYLIST_ENTRY, + "Oyatma listesi girişi güncellenirken hata oluştu." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLEASE_FILL_OUT_REQUIRED_FIELDS, + "Lütfen tüm gerekli alanları doldurunuz." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_NIGHTLY, + "RetroArch'ı güncelle (nightly)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FINISHED, + "RetroArch başarıyla güncellendi. Değişikliklerin etkili olması için lütfen uygulamayı yeniden başlatın." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FAILED, + "Güncelleme başarısız oldu." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_ABOUT_CONTRIBUTORS, + "Katkıda bulunanlar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CURRENT_SHADER, + "Geçerli gölgelendirici" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MOVE_DOWN, + "Move Down" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MOVE_UP, + "Move Up" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOAD, + "Yükle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SAVE, + "Kaydet" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_REMOVE, + "Kaldır" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_APPLY, + "Uygula" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SHADER_ADD_PASS, + "Add Pass" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SHADER_CLEAR_ALL_PASSES, + "Clear All Passes" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SHADER_NO_PASSES, + "No shader passes." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESET_PASS, + "Reset Pass" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESET_ALL_PASSES, + "Reset All Passes" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESET_PARAMETER, + "Reset Parameter" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_THUMBNAIL, + "Download thumbnail" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALREADY_IN_PROGRESS, + "Bir indirme işlemi zaten devam ediyor." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_STARTUP_PLAYLIST, + "Oynatma listesinde başla:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_TYPE, + "Simge görünümü küçük resmi türü:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_CACHE_LIMIT, + "Küçük resim önbellek sınırı:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS, + "Tüm Küçük Resimleri İndir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_ENTIRE_SYSTEM, + "Tüm sistemin" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_THIS_PLAYLIST, + "Bu Oynatma Listesinin" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_PACK_DOWNLOADED_SUCCESSFULLY, + "Küçük resimler başarıyla indirildi." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_PLAYLIST_THUMBNAIL_PROGRESS, + "Başarılı: %1 Başarısız: %2" + ) +MSG_HASH( + MSG_DEVICE_CONFIGURED_IN_PORT, + "Configured in port:" + ) +MSG_HASH( + MSG_FAILED_TO_SET_DISK, + "Failed to set disk" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE_OPTIONS, + "Core Seçenekleri" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_ADAPTIVE_VSYNC, + "Adaptive Vsync" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_ADAPTIVE_VSYNC, + "V-Sync is enabled until performance falls below the target refresh rate.\n" + "This can minimize stuttering when performance falls below realtime, and can be more energy efficient." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CRT_SWITCHRES_SETTINGS, + "CRT SwitchRes" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CRT_SWITCHRES_SETTINGS, + "Output native, low-resolution signals for use with CRT displays." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CRT_SWITCH_X_AXIS_CENTERING, + "Görüntü ekranda doğru şekilde ortalanmamışsa bu seçenekler arasında gezinin." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CRT_SWITCH_X_AXIS_CENTERING, + "X-Axis Centering" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_USE_CUSTOM_REFRESH_RATE, + "Gerekirse, yapılandırma dosyasında belirtilen özel bir yenileme hızı kullanın." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_USE_CUSTOM_REFRESH_RATE, + "Özel Yenileme Hızını Kullan" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_OUTPUT_DISPLAY_ID, + "Select the output port connected to the CRT display." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_OUTPUT_DISPLAY_ID, + "Output Display ID" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_START_RECORDING, + "Kayda başla" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_START_RECORDING, + "Kaydı başlatır." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_STOP_RECORDING, + "Kaydetmeyi durdur" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_STOP_RECORDING, + "Kaydı durdurur." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_START_STREAMING, + "Yayın Yapmayı Başlat" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_START_STREAMING, + "Yayın yapmayı başlatır." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_STOP_STREAMING, + "Yayın yapmayı durdur" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_STOP_STREAMING, + "Yayın yapmayı durdurur." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE, + "Recording toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE, + "Streaming toggle" + ) +MSG_HASH( + MSG_CHEEVOS_HARDCORE_MODE_DISABLED, + "A savestate was loaded, Achievements Hardcore Mode disabled for the current session. Restart to enable hardcore mode." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_RECORD_QUALITY, + "Kayıt Kalitesi" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_STREAM_QUALITY, + "Yayın Kalitesi" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_STREAMING_URL, + "Akış URL’si" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UDP_STREAM_PORT, + "UDP Stream Port" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_TWITCH, + "Twitch" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_YOUTUBE, + "YouTube" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TWITCH_STREAM_KEY, + "Twitch Stream Key" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_YOUTUBE_STREAM_KEY, + "YouTube Stream Key" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_STREAMING_MODE, + "Yayıncı Modu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_STREAMING_TITLE, + "Yayın Başlığı" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_SPLIT_JOYCON, + "Split Joy-Con" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RESET_TO_DEFAULT_CONFIG, + "Varsayılanlara dön" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RESET_TO_DEFAULT_CONFIG, + "Geçerli yapılandırmayı varsayılan değerlere sıfırlayın." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_OK, + "Tamam" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OZONE_MENU_COLOR_THEME, + "Menü Renk Teması" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OZONE_COLOR_THEME_BASIC_WHITE, + "Temel Beyaz" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OZONE_COLOR_THEME_BASIC_BLACK, + "Temel Siyah" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_OZONE_MENU_COLOR_THEME, + "Farklı bir renk teması seçin." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OZONE_COLLAPSE_SIDEBAR, + "Kenar çubuğunu daralt" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_OZONE_COLLAPSE_SIDEBAR, + "Sol kenar çubuğunu daima daraltın." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, + "Tercih edilen sistem renk temasını kullan" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, + "İşletim sisteminizin renk temasını kullanın (varsa) - tema ayarlarını geçersiz kılar." + ) +MSG_HASH( + MSG_RESAMPLER_QUALITY_LOWEST, + "En düşük" + ) +MSG_HASH( + MSG_RESAMPLER_QUALITY_LOWER, + "Düşük" + ) +MSG_HASH( + MSG_RESAMPLER_QUALITY_NORMAL, + "Normal" + ) +MSG_HASH( + MSG_RESAMPLER_QUALITY_HIGHER, + "Yüksek" + ) +MSG_HASH( + MSG_RESAMPLER_QUALITY_HIGHEST, + "En Yüksek" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_MUSIC_AVAILABLE, + "Kullanılabilir bir müzik yok." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_VIDEOS_AVAILABLE, + "Kullanılabilir bir video yok." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_IMAGES_AVAILABLE, + "Kullanılabilir bir resim yok." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_FAVORITES_AVAILABLE, + "Favoriler yok." + ) +MSG_HASH( + MSG_MISSING_ASSETS, + "Uyarı: Kayıp içerikler, varsa Çevrimiçi Güncelleyiciyi kullanın" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_SAVE_POSITION, + "Pencere Konumunu ve Boyutunu hatırla" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HOLD_START, + "Start'a Basılı Tutun (2 saniye)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_USE_OLD_FORMAT, + "Eski formatı kullanarak oynatma listelerini kaydet" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SHOW_INLINE_CORE_NAME, + "Oynatma listelerinde ilişkili Core'ları göster" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_SHOW_INLINE_CORE_NAME, + "Oynatma listesi girişlerinin o anda ilişkilendirilmiş olan Corela (varsa) ne zaman etiketleneceğini belirleyin. NOT: Oynatma listesi alt etiketleri etkinleştirildiğinde bu ayar dikkate alınmaz." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_HIST_FAV, + "Geçmiş & Favoriler" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_ALWAYS, + "Her zaman" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_NEVER, + "Asla" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SORT_ALPHABETICAL, + "Oynatma listelerini alfabetik olarak sırala" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_SORT_ALPHABETICAL, + "İçerik çalma listelerini alfabetik sıraya göre sıralar. Son kullanılan oyunların, resimlerin, müziklerin ve videoların 'geçmiş' oynatma listelerinin hariç tutulduğunu unutmayın." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SOUNDS, + "Menü Sesleri" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SOUND_OK, + "Tamam sesini etkinleştir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SOUND_CANCEL, + "İptal sesini etkinleştir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SOUND_NOTICE, + "Bildirim sesini etkinleştir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SOUND_BGM, + "Enable BGM sound" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DOWN_SELECT, + "Down + Select" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER_FALLBACK, + "Grafik sürücünüz RetroArch'taki mevcut video sürücüsü ile uyumlu değil ve %s sürücüsüne geri dönülüyor. Lütfen değişikliklerin geçerli olması için RetroArch'ı yeniden başlatın." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT, + "CoreAudio support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT, + "CoreAudio V3 support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_RUNTIME_LOG, + "Save runtime log (per core)" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG, + "Her bir içerik öğesinin ne kadar süre çalıştığını, kayıtlar Core'a ayrılmış olarak izler." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_RUNTIME_LOG_AGGREGATE, + "Çalışma günlüğünü kaydet (toplam)" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG_AGGREGATE, + "Tüm içeriğin toplamının toplam olarak kaydedildiği her bir içerik öğesinin ne kadar süre çalıştığını takip eder." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUNTIME_LOG_DIRECTORY, + "Çalışma Zamanı Günlükleri" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RUNTIME_LOG_DIRECTORY, + "Oynatma zamanı günlük dosyalarını bu dizine kaydedin." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SHOW_SUBLABELS, + "Oynatma listesi alt etiketlerini göster" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_SHOW_SUBLABELS, + "Geçerli Core ilişkilendirme ve çalışma zamanı (varsa) gibi her oynatma listesi girişi için ek bilgi gösterir. Performansı etkiler(değişken)." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_CORE, + "Core:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME, + "Oyun süresi:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED, + "Son oynatma:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME_TYPE, + "Playlist sublabel runtime" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_SUBLABEL_RUNTIME_TYPE, + "Oynatma listesinin alt etiketlerinde hangi çalışma zamanı günlüğü kaydının görüntüleneceğini seçer. (İlgili çalışma zamanı günlüğünün 'Kaydetme' seçenekler menüsünden etkinleştirilmesi gerektiğini unutmayın))" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_PER_CORE, + "Core başına" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_AGGREGATE, + "Toplam" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO, + "Hata Ayıklama Bilgisi Gönder" + ) +MSG_HASH( + MSG_FAILED_TO_SAVE_DEBUG_INFO, + "Hata ayıklama bilgisi kaydedilemedi." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_DEBUG_INFO, + "Sunucuya hata ayıklama bilgisi gönderilemedi." + ) +MSG_HASH( + MSG_SENDING_DEBUG_INFO, + "Hata ayıklama bilgisi gönderiliyor ..." + ) +MSG_HASH( + MSG_SENT_DEBUG_INFO, + "Sunucuya hata ayıklama bilgisi başarıyla gönderildi. Kimlik numaranız %u." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO, + "Analiz için cihazların ve RetroArch yapılandırmasına ilişkin teşhis bilgilerini gönderir." + ) +MSG_HASH( + MSG_PRESS_TWO_MORE_TIMES_TO_SEND_DEBUG_INFO, + "RetroArch ekibine tanılama bilgileri göndermek için iki kez daha basın." + ) +MSG_HASH( + MSG_PRESS_ONE_MORE_TIME_TO_SEND_DEBUG_INFO, + "RetroArch ekibine tanılama bilgileri göndermek için bir kez daha basın." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIBRATE_ON_KEYPRESS, + "Vibrate on key press" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ENABLE_DEVICE_VIBRATION, + "Cihaz titreşimini etkinleştir (desteklenen Corelar için)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOG_DIR, + "Sistem Olayı Günlükleri" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOG_DIR, + "Sistem olay günlüğü dosyalarını bu dizine kaydedin." + ) diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index b9c4fa90dd..4718895150 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1568,6 +1568,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_LANG_GREEK, "Greek" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_TURKISH, + "Turkish" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_LEFT_ANALOG, "Left Analog" diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index 9fa1e3ad37..b089316718 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -274,6 +274,7 @@ enum retro_language RETRO_LANGUAGE_VIETNAMESE = 15, RETRO_LANGUAGE_ARABIC = 16, RETRO_LANGUAGE_GREEK = 17, + RETRO_LANGUAGE_TURKISH = 18, RETRO_LANGUAGE_LAST, /* Ensure sizeof(enum) == sizeof(int) */ diff --git a/menu/menu_setting.c b/menu/menu_setting.c index f084a29ef9..d9ce82a19b 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -2475,7 +2475,8 @@ static void setting_get_string_representation_uint_user_language( modes[RETRO_LANGUAGE_POLISH] = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LANG_POLISH); modes[RETRO_LANGUAGE_VIETNAMESE] = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LANG_VIETNAMESE); modes[RETRO_LANGUAGE_ARABIC] = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LANG_ARABIC); - modes[RETRO_LANGUAGE_GREEK] = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LANG_GREEK); + modes[RETRO_LANGUAGE_GREEK] = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LANG_GREEK); + modes[RETRO_LANGUAGE_TURKISH] = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LANG_TURKISH); strlcpy(s, modes[*msg_hash_get_uint(MSG_HASH_USER_LANGUAGE)], len); } #endif diff --git a/msg_hash.c b/msg_hash.c index 7890befeda..d45725cfa5 100644 --- a/msg_hash.c +++ b/msg_hash.c @@ -85,6 +85,9 @@ int menu_hash_get_help_enum(enum msg_hash_enums msg, char *s, size_t len) case RETRO_LANGUAGE_GREEK: ret = menu_hash_get_help_el_enum(msg, s, len); break; + case RETRO_LANGUAGE_TURKISH: + ret = menu_hash_get_help_tr_enum(msg, s, len); + break; default: break; } @@ -157,6 +160,9 @@ const char *msg_hash_to_str(enum msg_hash_enums msg) case RETRO_LANGUAGE_GREEK: ret = msg_hash_to_str_el(msg); break; + case RETRO_LANGUAGE_TURKISH: + ret = msg_hash_to_str_tr(msg); + break; default: break; } diff --git a/msg_hash.h b/msg_hash.h index 401fc44639..df4111a5c1 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1957,6 +1957,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_LANG_VIETNAMESE, MENU_ENUM_LABEL_VALUE_LANG_ARABIC, MENU_ENUM_LABEL_VALUE_LANG_GREEK, + MENU_ENUM_LABEL_VALUE_LANG_TURKISH, MENU_ENUM_LABEL_VALUE_NONE, MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE, @@ -2642,6 +2643,9 @@ int menu_hash_get_help_ar_enum(enum msg_hash_enums msg, char *s, size_t len); const char *msg_hash_to_str_el(enum msg_hash_enums msg); int menu_hash_get_help_el_enum(enum msg_hash_enums msg, char *s, size_t len); +const char *msg_hash_to_str_tr(enum msg_hash_enums msg); +int menu_hash_get_help_tr_enum(enum msg_hash_enums msg, char *s, size_t len); + int menu_hash_get_help_enum(enum msg_hash_enums msg, char *s, size_t len); enum msg_file_type msg_hash_to_file_type(uint32_t hash); From ed1480bc879f561c829a2e5299c54e105a2e53e3 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 18 Apr 2019 10:02:05 +0100 Subject: [PATCH 222/237] RGUI OSK - HAVE_LANGEXTRA=0 build fix --- menu/menu_input.c | 4 ++-- menu/widgets/menu_osk.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/menu/menu_input.c b/menu/menu_input.c index e7b526c72c..b9b123151b 100644 --- a/menu/menu_input.c +++ b/menu/menu_input.c @@ -273,12 +273,12 @@ unsigned menu_event(input_bits_t *p_input, input_bits_t *p_trigger_input) menu_event_set_osk_idx((enum osk_type)( menu_event_get_osk_idx() - 1)); else - menu_event_set_osk_idx((enum osk_type)(is_rgui ? OSK_HIRAGANA_PAGE1 - 1 : OSK_TYPE_LAST - 1)); + menu_event_set_osk_idx((enum osk_type)(is_rgui ? OSK_SYMBOLS_PAGE1 : OSK_TYPE_LAST - 1)); } if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R)) { - if (menu_event_get_osk_idx() < (is_rgui ? OSK_HIRAGANA_PAGE1 - 1 : OSK_TYPE_LAST - 1)) + if (menu_event_get_osk_idx() < (is_rgui ? OSK_SYMBOLS_PAGE1 : OSK_TYPE_LAST - 1)) menu_event_set_osk_idx((enum osk_type)( menu_event_get_osk_idx() + 1)); else diff --git a/menu/widgets/menu_osk.c b/menu/widgets/menu_osk.c index 4782163633..3a32e0955f 100644 --- a/menu/widgets/menu_osk.c +++ b/menu/widgets/menu_osk.c @@ -115,7 +115,7 @@ void menu_event_osk_append(int ptr) menu_event_set_osk_idx(OSK_LOWERCASE_LATIN); else if (string_is_equal(osk_grid[ptr], "Next")) #endif - if (menu_event_get_osk_idx() < (is_rgui ? OSK_HIRAGANA_PAGE1 - 1 : OSK_TYPE_LAST - 1)) + if (menu_event_get_osk_idx() < (is_rgui ? OSK_SYMBOLS_PAGE1 : OSK_TYPE_LAST - 1)) menu_event_set_osk_idx((enum osk_type)(menu_event_get_osk_idx() + 1)); else menu_event_set_osk_idx((enum osk_type)(OSK_TYPE_UNKNOWN + 1)); From fa128f950dd714cbd5c05bf831a33691ac221fdc Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 18 Apr 2019 10:35:51 -0400 Subject: [PATCH 223/237] remove unused functions --- cores/libretro-gong/gong.c | 6 ------ ui/drivers/qt/qt_playlist.cpp | 5 ----- 2 files changed, 11 deletions(-) diff --git a/cores/libretro-gong/gong.c b/cores/libretro-gong/gong.c index 61833075fc..9d2b3c91b4 100644 --- a/cores/libretro-gong/gong.c +++ b/cores/libretro-gong/gong.c @@ -351,12 +351,6 @@ static void load_state(const void *data, size_t size) check_variables(); } -static INLINE bool pressed(Game_Button_State state) -{ - return state.half_transition_count > 1 || - (state.half_transition_count == 1 && state.ended_down); -} - static INLINE bool is_down(Game_Button_State state) { return state.ended_down; diff --git a/ui/drivers/qt/qt_playlist.cpp b/ui/drivers/qt/qt_playlist.cpp index ea8166d772..516aa985f7 100644 --- a/ui/drivers/qt/qt_playlist.cpp +++ b/ui/drivers/qt/qt_playlist.cpp @@ -265,11 +265,6 @@ inline static bool comp_hash_name_key_lower(const QHash &lhs, return lhs.value("name").toLower() < rhs.value("name").toLower(); } -inline static bool comp_hash_label_key_lower(const QHash &lhs, const QHash &rhs) -{ - return lhs.value("label").toLower() < rhs.value("label").toLower(); -} - bool MainWindow::addDirectoryFilesToList(QProgressDialog *dialog, QStringList &list, QDir &dir, QStringList &extensions) { PlaylistEntryDialog *playlistDialog = playlistEntryDialog(); From e7dbac7eb0f8bfaf850b95158af75c68210afa5a Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 18 Apr 2019 11:46:53 -0400 Subject: [PATCH 224/237] prevent null derefs found by scan-build --- gfx/drivers/gl_core.c | 3 ++- libretro-common/net/net_http.c | 19 +++++++++++-------- menu/cbs/menu_cbs_deferred_push.c | 12 +++++++++--- menu/cbs/menu_cbs_ok.c | 2 +- menu/drivers/ozone/ozone.c | 24 ++++++++++++++---------- menu/drivers/ozone/ozone_entries.c | 3 ++- menu/menu_displaylist.c | 6 +++--- 7 files changed, 42 insertions(+), 27 deletions(-) diff --git a/gfx/drivers/gl_core.c b/gfx/drivers/gl_core.c index 83c34e8fae..5efe7b3b22 100644 --- a/gfx/drivers/gl_core.c +++ b/gfx/drivers/gl_core.c @@ -503,7 +503,8 @@ static const gfx_ctx_driver_t *gl_core_get_context(gl_core_t *gl) #endif /* Force shared context. */ - gl->use_shared_context = hwr->context_type != RETRO_HW_CONTEXT_NONE; + if (hwr) + gl->use_shared_context = hwr->context_type != RETRO_HW_CONTEXT_NONE; gfx_ctx = video_context_driver_init_first(gl, settings->arrays.video_context_driver, diff --git a/libretro-common/net/net_http.c b/libretro-common/net/net_http.c index 4f2ad2635e..fef8400012 100644 --- a/libretro-common/net/net_http.c +++ b/libretro-common/net/net_http.c @@ -483,15 +483,18 @@ struct http_t *net_http_new(struct http_connection_t *conn) return state; error: - if (conn->methodcopy) - free(conn->methodcopy); - if (conn->contenttypecopy) - free(conn->contenttypecopy); - conn->methodcopy = NULL; - conn->contenttypecopy = NULL; - conn->postdatacopy = NULL; + if (conn) + { + if (conn->methodcopy) + free(conn->methodcopy); + if (conn->contenttypecopy) + free(conn->contenttypecopy); + conn->methodcopy = NULL; + conn->contenttypecopy = NULL; + conn->postdatacopy = NULL; + } #ifdef HAVE_SSL - if (conn->sock_state.ssl && conn->sock_state.ssl_ctx && fd >= 0) + if (conn && conn->sock_state.ssl && conn->sock_state.ssl_ctx && fd >= 0) { ssl_socket_close(conn->sock_state.ssl_ctx); ssl_socket_free(conn->sock_state.ssl_ctx); diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 7b444cbb29..76434fcce2 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -418,8 +418,9 @@ static int general_push(menu_displaylist_info_t *info, } else { - strlcpy(newstring2, system->valid_extensions, - PATH_MAX_LENGTH * sizeof(char)); + if (system) + strlcpy(newstring2, system->valid_extensions, + PATH_MAX_LENGTH * sizeof(char)); } } break; @@ -442,7 +443,7 @@ static int general_push(menu_displaylist_info_t *info, } else { - if (!string_is_empty(system->valid_extensions)) + if (system && !string_is_empty(system->valid_extensions)) { new_exts = strdup(system->valid_extensions); new_exts_allocated = true; @@ -473,7 +474,12 @@ static int general_push(menu_displaylist_info_t *info, } if (new_exts_allocated) + { free(new_exts); + + if (new_exts == info->exts) + info->exts = NULL; + } } break; case PUSH_ARCHIVE_OPEN_DETECT_CORE: diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 90fa4e0214..a9e2cb6436 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -3611,7 +3611,7 @@ finish: (transf ? transf->path: "unknown"), err); } #ifdef HAVE_DISCORD - else if (transf->enum_idx == MENU_ENUM_LABEL_CB_DISCORD_AVATAR) + else if (transf && transf->enum_idx == MENU_ENUM_LABEL_CB_DISCORD_AVATAR) discord_avatar_set_ready(true); #endif diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index 1f1edebf65..906d1d76ad 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -301,19 +301,23 @@ static void *ozone_init(void **userdata, bool video_is_threaded) return menu; error: - if (ozone->horizontal_list) + if (ozone) { - ozone_free_list_nodes(ozone->horizontal_list, false); - file_list_free(ozone->horizontal_list); - } + if (ozone->horizontal_list) + { + ozone_free_list_nodes(ozone->horizontal_list, false); + file_list_free(ozone->horizontal_list); + } - if (ozone->selection_buf_old) - { - ozone_free_list_nodes(ozone->selection_buf_old, false); - file_list_free(ozone->selection_buf_old); + if (ozone->selection_buf_old) + { + ozone_free_list_nodes(ozone->selection_buf_old, false); + file_list_free(ozone->selection_buf_old); + } + + ozone->selection_buf_old = NULL; + ozone->horizontal_list = NULL; } - ozone->selection_buf_old = NULL; - ozone->horizontal_list = NULL; if (menu) free(menu); diff --git a/menu/drivers/ozone/ozone_entries.c b/menu/drivers/ozone/ozone_entries.c index b81b56aed0..d908ffa48b 100644 --- a/menu/drivers/ozone/ozone_entries.c +++ b/menu/drivers/ozone/ozone_entries.c @@ -441,7 +441,8 @@ void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_info, } border_iterate: - y += node->height; + if (node) + y += node->height; } /* Cursor(s) layer - current */ diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 49c2edc18d..792e54ee3f 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -2886,7 +2886,7 @@ static int menu_displaylist_parse_horizontal_content_actions( { const char *ext = NULL; - if (!string_is_empty(entry->path)) + if (entry && !string_is_empty(entry->path)) ext = path_get_extension(entry->path); if (!string_is_empty(ext) && @@ -2943,7 +2943,7 @@ static int menu_displaylist_parse_horizontal_content_actions( } } - if (!string_is_empty(entry->db_name) && (!content_loaded || + if ((entry && !string_is_empty(entry->db_name)) && (!content_loaded || (content_loaded && settings->bools.quick_menu_show_information))) { char *db_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); @@ -7782,7 +7782,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist PARSE_ACTION, false); /* Core fully loaded, use the subsystem data */ - if (sys_info->subsystem.data) + if (sys_info && sys_info->subsystem.data) subsystem = sys_info->subsystem.data; /* Core not loaded completely, use the data we peeked on load core */ else From 572c16cb2a48f1b01d7aa609bc7d81439a3052c1 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 18 Apr 2019 11:47:13 -0400 Subject: [PATCH 225/237] style cleanup with uncrustify --- managers/cheat_manager.c | 960 ++++++++++++++++++++------------------- 1 file changed, 486 insertions(+), 474 deletions(-) diff --git a/managers/cheat_manager.c b/managers/cheat_manager.c index 9dec2d8ac0..1acc87912e 100644 --- a/managers/cheat_manager.c +++ b/managers/cheat_manager.c @@ -68,7 +68,7 @@ unsigned cheat_manager_get_size(void) void cheat_manager_apply_cheats(void) { #ifdef HAVE_CHEEVOS - bool data_bool = false; + bool data_bool = false; #endif unsigned i, idx = 0; @@ -83,9 +83,9 @@ void cheat_manager_apply_cheats(void) { retro_ctx_cheat_info_t cheat_info; - cheat_info.index = idx++; + cheat_info.index = idx++; cheat_info.enabled = true; - cheat_info.code = cheat_manager_state.cheats[i].code; + cheat_info.code = cheat_manager_state.cheats[i].code; if (!string_is_empty(cheat_info.code)) core_set_cheat(&cheat_info); @@ -110,9 +110,9 @@ void cheat_manager_set_code(unsigned i, const char *str) return; if (!string_is_empty(str)) - strcpy(cheat_manager_state.cheats[i].code,str); + strcpy(cheat_manager_state.cheats[i].code, str); - cheat_manager_state.cheats[i].state = true; + cheat_manager_state.cheats[i].state = true; } /** @@ -129,30 +129,30 @@ bool cheat_manager_save(const char *path, const char *cheat_database, bool overw unsigned i; char buf[PATH_MAX_LENGTH]; char cheats_file[PATH_MAX_LENGTH]; - config_file_t *conf = NULL; + config_file_t *conf = NULL; unsigned int* data_ptrs[16] = { NULL}; - char* keys[16] = { - (char*)"cheat%u_handler", - (char*)"cheat%u_memory_search_size", - (char*)"cheat%u_cheat_type", - (char*)"cheat%u_value", - (char*)"cheat%u_address", - (char*)"cheat%u_address_bit_position", - (char*)"cheat%u_rumble_type", - (char*)"cheat%u_rumble_value", - (char*)"cheat%u_rumble_port", - (char*)"cheat%u_rumble_primary_strength", - (char*)"cheat%u_rumble_primary_duration", - (char*)"cheat%u_rumble_secondary_strength", - (char*)"cheat%u_rumble_secondary_duration", - (char*)"cheat%u_repeat_count", - (char*)"cheat%u_repeat_add_to_value", - (char*)"cheat%u_repeat_add_to_address" + char* keys[16] = { + (char*)"cheat%u_handler", + (char*)"cheat%u_memory_search_size", + (char*)"cheat%u_cheat_type", + (char*)"cheat%u_value", + (char*)"cheat%u_address", + (char*)"cheat%u_address_bit_position", + (char*)"cheat%u_rumble_type", + (char*)"cheat%u_rumble_value", + (char*)"cheat%u_rumble_port", + (char*)"cheat%u_rumble_primary_strength", + (char*)"cheat%u_rumble_primary_duration", + (char*)"cheat%u_rumble_secondary_strength", + (char*)"cheat%u_rumble_secondary_duration", + (char*)"cheat%u_repeat_count", + (char*)"cheat%u_repeat_add_to_value", + (char*)"cheat%u_repeat_add_to_address" }; buf[0] = cheats_file[0] = '\0'; - if ((!cheat_manager_state.cheats) || cheat_manager_state.size==0) + if ((!cheat_manager_state.cheats) || cheat_manager_state.size == 0) return false; if (!cheat_database) @@ -163,6 +163,7 @@ bool cheat_manager_save(const char *path, const char *cheat_database, bool overw fill_pathname_noext(cheats_file, buf, ".cht", sizeof(cheats_file)); } + if (!overwrite) conf = config_file_new(cheats_file); else @@ -189,19 +190,19 @@ bool cheat_manager_save(const char *path, const char *cheat_database, bool overw key[0] = endian_key[0] = desc_key[0] = code_key[0] = enable_key[0] = '\0'; - snprintf(endian_key, sizeof(endian_key), "cheat%u_big_endian", i); - snprintf(desc_key, sizeof(desc_key), "cheat%u_desc", i); - snprintf(code_key, sizeof(code_key), "cheat%u_code", i); + snprintf(endian_key, sizeof(endian_key), "cheat%u_big_endian", i); + snprintf(desc_key, sizeof(desc_key), "cheat%u_desc", i); + snprintf(code_key, sizeof(code_key), "cheat%u_code", i); snprintf(enable_key, sizeof(enable_key), "cheat%u_enable", i); if (!string_is_empty(cheat_manager_state.cheats[i].desc)) - config_set_string(conf, desc_key, cheat_manager_state.cheats[i].desc); + config_set_string(conf, desc_key, cheat_manager_state.cheats[i].desc); else - config_set_string(conf, desc_key, cheat_manager_state.cheats[i].code); + config_set_string(conf, desc_key, cheat_manager_state.cheats[i].code); - config_set_string(conf, code_key, cheat_manager_state.cheats[i].code); - config_set_bool(conf, enable_key, cheat_manager_state.cheats[i].state); - config_set_bool(conf, endian_key, cheat_manager_state.cheats[i].big_endian); + config_set_string(conf, code_key, cheat_manager_state.cheats[i].code); + config_set_bool(conf, enable_key, cheat_manager_state.cheats[i].state); + config_set_bool(conf, endian_key, cheat_manager_state.cheats[i].big_endian); data_ptrs[0] = &cheat_manager_state.cheats[i].handler; data_ptrs[1] = &cheat_manager_state.cheats[i].memory_search_size; @@ -237,10 +238,11 @@ bool cheat_manager_save(const char *path, const char *cheat_database, bool overw bool cheat_manager_copy_idx_to_working(unsigned idx) { - if ((!cheat_manager_state.cheats) || (cheat_manager_state.size < idx+1)) + if ((!cheat_manager_state.cheats) || (cheat_manager_state.size < idx + 1)) return false; memcpy(&(cheat_manager_state.working_cheat), &(cheat_manager_state.cheats[idx]), sizeof(struct item_cheat)); + if (cheat_manager_state.cheats[idx].desc) strlcpy(cheat_manager_state.working_desc, cheat_manager_state.cheats[idx].desc, CHEAT_DESC_SCRATCH_SIZE); else @@ -253,12 +255,14 @@ bool cheat_manager_copy_idx_to_working(unsigned idx) return true; } + bool cheat_manager_copy_working_to_idx(unsigned idx) { - if ((!cheat_manager_state.cheats) || (cheat_manager_state.size < idx+1)) + if ((!cheat_manager_state.cheats) || (cheat_manager_state.size < idx + 1)) return false; memcpy(&(cheat_manager_state.cheats[idx]), &(cheat_manager_state.working_cheat), sizeof(struct item_cheat)); + if (cheat_manager_state.cheats[idx].desc) free(cheat_manager_state.cheats[idx].desc); @@ -268,8 +272,10 @@ bool cheat_manager_copy_working_to_idx(unsigned idx) free(cheat_manager_state.cheats[idx].code); cheat_manager_state.cheats[idx].code = strdup(cheat_manager_state.working_code); + return true; } + static void cheat_manager_new(unsigned size) { unsigned i; @@ -277,10 +283,10 @@ static void cheat_manager_new(unsigned size) cheat_manager_free(); cheat_manager_state.buf_size = size; - cheat_manager_state.size = size; - cheat_manager_state.search_bit_size = 3; - cheat_manager_state.cheats = (struct item_cheat*) - calloc(cheat_manager_state.buf_size, sizeof(struct item_cheat)); + cheat_manager_state.size = size; + cheat_manager_state.search_bit_size = 3; + cheat_manager_state.cheats = (struct item_cheat*) + calloc(cheat_manager_state.buf_size, sizeof(struct item_cheat)); if (!cheat_manager_state.cheats) { @@ -294,7 +300,7 @@ static void cheat_manager_new(unsigned size) { cheat_manager_state.cheats[i].desc = NULL; cheat_manager_state.cheats[i].code = NULL; - cheat_manager_state.cheats[i].state = false; + cheat_manager_state.cheats[i].state = false; cheat_manager_state.cheats[i].repeat_count = 1; cheat_manager_state.cheats[i].repeat_add_to_value = 0; cheat_manager_state.cheats[i].repeat_add_to_address = 1; @@ -321,7 +327,7 @@ void cheat_manager_load_cb_second_pass(char *key, char *value) char cheat_num_str[20]; unsigned cheat_num; unsigned cheat_idx; - unsigned idx = 5; + unsigned idx = 5; size_t key_length = 0; errno = 0; @@ -330,29 +336,29 @@ void cheat_manager_load_cb_second_pass(char *key, char *value) key_length = strlen((const char*)key); - while (idx < key_length && key[idx] >= '0' && key[idx] <= '9' && idx < 24) + while (idx < key_length && key[idx] >= '0' && key[idx] <= '9' && idx < 24) { - cheat_num_str[idx-5] = key[idx]; + cheat_num_str[idx - 5] = key[idx]; idx++; } - cheat_num_str[idx-5] = '\0'; + cheat_num_str[idx - 5] = '\0'; cheat_num = (unsigned)strtoul(cheat_num_str, NULL, 0); - if (cheat_num+cheat_manager_state.loading_cheat_offset >= cheat_manager_state.size) + if (cheat_num + cheat_manager_state.loading_cheat_offset >= cheat_manager_state.size) return; - key = key+idx+1; + key = key + idx + 1; - cheat_idx = cheat_num+cheat_manager_state.loading_cheat_offset; + cheat_idx = cheat_num + cheat_manager_state.loading_cheat_offset; if (string_is_equal(key, "address")) cheat_manager_state.cheats[cheat_idx].address = (unsigned)strtoul(value, NULL, 0); else if (string_is_equal(key, "address_bit_position")) cheat_manager_state.cheats[cheat_idx].address_mask = (unsigned)strtoul(value, NULL, 0); else if (string_is_equal(key, "big_endian")) - cheat_manager_state.cheats[cheat_idx].big_endian = (string_is_equal(value,"true") || string_is_equal(value,"1")); + cheat_manager_state.cheats[cheat_idx].big_endian = (string_is_equal(value, "true") || string_is_equal(value, "1")); else if (string_is_equal(key, "cheat_type")) cheat_manager_state.cheats[cheat_idx].cheat_type = (unsigned)strtoul(value, NULL, 0); else if (string_is_equal(key, "code")) @@ -360,7 +366,7 @@ void cheat_manager_load_cb_second_pass(char *key, char *value) else if (string_is_equal(key, "desc")) cheat_manager_state.cheats[cheat_idx].desc = strdup(value); else if (string_is_equal(key, "enable")) - cheat_manager_state.cheats[cheat_idx].state = (string_is_equal(value,"true") || string_is_equal(value,"1")); + cheat_manager_state.cheats[cheat_idx].state = (string_is_equal(value, "true") || string_is_equal(value, "1")); else if (string_is_equal(key, "handler")) cheat_manager_state.cheats[cheat_idx].handler = (unsigned)strtoul(value, NULL, 0); else if (string_is_equal(key, "memory_search_size")) @@ -424,7 +430,9 @@ bool cheat_manager_load(const char *path, bool append) else { cheats = cheats + orig_size; - if (cheat_manager_realloc(cheats, CHEAT_HANDLER_TYPE_EMU)) { } + if (cheat_manager_realloc(cheats, CHEAT_HANDLER_TYPE_EMU)) + { + } } } else @@ -433,14 +441,14 @@ bool cheat_manager_load(const char *path, bool append) cheat_manager_new(cheats); } - for (i = orig_size; i < cheats; i++) + for (i = orig_size; cheat_manager_state.cheats && i < cheats; i++) { - cheat_manager_state.cheats[i].idx = i; - cheat_manager_state.cheats[i].desc = NULL; - cheat_manager_state.cheats[i].code = NULL; - cheat_manager_state.cheats[i].state = false; - cheat_manager_state.cheats[i].big_endian = false; - cheat_manager_state.cheats[i].cheat_type = CHEAT_TYPE_SET_TO_VALUE; + cheat_manager_state.cheats[i].idx = i; + cheat_manager_state.cheats[i].desc = NULL; + cheat_manager_state.cheats[i].code = NULL; + cheat_manager_state.cheats[i].state = false; + cheat_manager_state.cheats[i].big_endian = false; + cheat_manager_state.cheats[i].cheat_type = CHEAT_TYPE_SET_TO_VALUE; cheat_manager_state.cheats[i].memory_search_size = 3; } @@ -468,7 +476,7 @@ bool cheat_manager_realloc(unsigned new_size, unsigned default_handler) if (!cheat_manager_state.cheats) { cheat_manager_state.cheats = (struct item_cheat*) - calloc(new_size, sizeof(struct item_cheat)); + calloc(new_size, sizeof(struct item_cheat)); orig_size = 0; } else @@ -486,8 +494,8 @@ bool cheat_manager_realloc(unsigned new_size, unsigned default_handler) } val = (struct item_cheat*) - realloc(cheat_manager_state.cheats, - new_size * sizeof(struct item_cheat)); + realloc(cheat_manager_state.cheats, + new_size * sizeof(struct item_cheat)); cheat_manager_state.cheats = val ? val : NULL; } @@ -500,18 +508,18 @@ bool cheat_manager_realloc(unsigned new_size, unsigned default_handler) } cheat_manager_state.buf_size = new_size; - cheat_manager_state.size = new_size; + cheat_manager_state.size = new_size; for (i = orig_size; i < cheat_manager_state.size; i++) { memset(&(cheat_manager_state.cheats[i]), 0, sizeof(cheat_manager_state.cheats[i])); - cheat_manager_state.cheats[i].state = false; - cheat_manager_state.cheats[i].handler = default_handler; - cheat_manager_state.cheats[i].cheat_type = CHEAT_TYPE_SET_TO_VALUE; - cheat_manager_state.cheats[i].memory_search_size = 3; - cheat_manager_state.cheats[i].idx = i; - cheat_manager_state.cheats[i].repeat_count = 1; - cheat_manager_state.cheats[i].repeat_add_to_value = 0; + cheat_manager_state.cheats[i].state = false; + cheat_manager_state.cheats[i].handler = default_handler; + cheat_manager_state.cheats[i].cheat_type = CHEAT_TYPE_SET_TO_VALUE; + cheat_manager_state.cheats[i].memory_search_size = 3; + cheat_manager_state.cheats[i].idx = i; + cheat_manager_state.cheats[i].repeat_count = 1; + cheat_manager_state.cheats[i].repeat_add_to_value = 0; cheat_manager_state.cheats[i].repeat_add_to_address = 1; } @@ -547,17 +555,17 @@ void cheat_manager_free(void) if (cheat_manager_state.memory_size_list) free(cheat_manager_state.memory_size_list); - cheat_manager_state.cheats = NULL; - cheat_manager_state.size = 0; - cheat_manager_state.buf_size = 0; - cheat_manager_state.prev_memory_buf = NULL; - cheat_manager_state.curr_memory_buf = NULL; - cheat_manager_state.memory_buf_list = NULL; - cheat_manager_state.memory_size_list = NULL; - cheat_manager_state.matches = NULL; - cheat_manager_state.num_memory_buffers = 0; - cheat_manager_state.total_memory_size = 0; - cheat_manager_state.memory_initialized = false; + cheat_manager_state.cheats = NULL; + cheat_manager_state.size = 0; + cheat_manager_state.buf_size = 0; + cheat_manager_state.prev_memory_buf = NULL; + cheat_manager_state.curr_memory_buf = NULL; + cheat_manager_state.memory_buf_list = NULL; + cheat_manager_state.memory_size_list = NULL; + cheat_manager_state.matches = NULL; + cheat_manager_state.num_memory_buffers = 0; + cheat_manager_state.total_memory_size = 0; + cheat_manager_state.memory_initialized = false; cheat_manager_state.memory_search_initialized = false; } @@ -571,16 +579,16 @@ void cheat_manager_update(cheat_manager_t *handle, unsigned handle_idx) snprintf(msg, sizeof(msg), "Cheat: #%u [%s]: %s", handle_idx, handle->cheats[handle_idx].state ? "ON" : "OFF", - (handle->cheats[handle_idx].desc!=NULL) ? + (handle->cheats[handle_idx].desc != NULL) ? (handle->cheats[handle_idx].desc) : (handle->cheats[handle_idx].code) - ); + ); runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); RARCH_LOG("%s\n", msg); } void cheat_manager_toggle_index(unsigned i) { - settings_t *settings = config_get_ptr(); + settings_t *settings = config_get_ptr(); if (!cheat_manager_state.cheats || cheat_manager_state.size == 0) return; @@ -650,10 +658,10 @@ bool cheat_manager_get_code_state(unsigned i) bool cheat_manager_get_game_specific_filename(char * cheat_filename, size_t max_length) { - settings_t *settings = config_get_ptr(); - global_t *global = global_get_ptr(); - const char *core_name = NULL; - const char *game_name = NULL; + settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); + const char *core_name = NULL; + const char *game_name = NULL; struct retro_system_info system_info; if (!settings || !global || !cheat_filename) @@ -662,22 +670,22 @@ bool cheat_manager_get_game_specific_filename(char * cheat_filename, size_t max_ if (!core_get_system_info(&system_info)) return false; - core_name = system_info.library_name; - game_name = path_basename(global->name.cheatfile); + core_name = system_info.library_name; + game_name = path_basename(global->name.cheatfile); - if (string_is_empty(settings->paths.path_cheat_database) || - string_is_empty(core_name) || - string_is_empty(game_name)) + if (string_is_empty(settings->paths.path_cheat_database) || + string_is_empty(core_name) || + string_is_empty(game_name)) return false; cheat_filename[0] = '\0'; strlcat(cheat_filename, settings->paths.path_cheat_database, max_length); fill_pathname_slash(cheat_filename, max_length); - strlcat(cheat_filename, core_name, max_length); + strlcat(cheat_filename, core_name, max_length); fill_pathname_slash(cheat_filename, max_length); if (!filestream_exists(cheat_filename)) - path_mkdir(cheat_filename); + path_mkdir(cheat_filename); strlcat(cheat_filename, game_name, max_length); @@ -689,7 +697,7 @@ void cheat_manager_load_game_specific_cheats() char cheat_file[PATH_MAX_LENGTH]; if (cheat_manager_get_game_specific_filename(cheat_file, PATH_MAX_LENGTH)) - cheat_manager_load(cheat_file,true); + cheat_manager_load(cheat_file, true); } void cheat_manager_save_game_specific_cheats() @@ -718,14 +726,14 @@ int cheat_manager_initialize_memory(rarch_setting_t *setting, bool wraparound) { unsigned i; retro_ctx_memory_info_t meminfo; - bool refresh = false; - bool is_search_initialization = (setting != NULL); - rarch_system_info_t *system = runloop_get_system_info(); - unsigned offset = 0; + bool refresh = false; + bool is_search_initialization = (setting != NULL); + rarch_system_info_t *system = runloop_get_system_info(); + unsigned offset = 0; cheat_manager_state.num_memory_buffers = 0; - cheat_manager_state.total_memory_size = 0; - cheat_manager_state.curr_memory_buf = NULL; + cheat_manager_state.total_memory_size = 0; + cheat_manager_state.curr_memory_buf = NULL; if (cheat_manager_state.memory_buf_list) { @@ -767,8 +775,8 @@ int cheat_manager_initialize_memory(rarch_setting_t *setting, bool wraparound) cheat_manager_state.memory_size_list = val; } - cheat_manager_state.memory_buf_list[cheat_manager_state.num_memory_buffers-1] = (uint8_t*)system->mmaps.descriptors[i].core.ptr; - cheat_manager_state.memory_size_list[cheat_manager_state.num_memory_buffers-1] = system->mmaps.descriptors[i].core.len; + cheat_manager_state.memory_buf_list[cheat_manager_state.num_memory_buffers - 1] = (uint8_t*)system->mmaps.descriptors[i].core.ptr; + cheat_manager_state.memory_size_list[cheat_manager_state.num_memory_buffers - 1] = system->mmaps.descriptors[i].core.len; cheat_manager_state.total_memory_size += system->mmaps.descriptors[i].core.len; if (!cheat_manager_state.curr_memory_buf) @@ -789,24 +797,24 @@ int cheat_manager_initialize_memory(rarch_setting_t *setting, bool wraparound) if (meminfo.size == 0) return 0; - cheat_manager_state.memory_buf_list = (uint8_t**) - calloc(1, sizeof(uint8_t *)); - cheat_manager_state.memory_size_list = (unsigned*) - calloc(1, sizeof(unsigned)); - cheat_manager_state.num_memory_buffers = 1; - cheat_manager_state.memory_buf_list[0] = (uint8_t*)meminfo.data; + cheat_manager_state.memory_buf_list = (uint8_t**) + calloc(1, sizeof(uint8_t *)); + cheat_manager_state.memory_size_list = (unsigned*) + calloc(1, sizeof(unsigned)); + cheat_manager_state.num_memory_buffers = 1; + cheat_manager_state.memory_buf_list[0] = (uint8_t*)meminfo.data; cheat_manager_state.memory_size_list[0] = (unsigned)meminfo.size; - cheat_manager_state.total_memory_size = (unsigned)meminfo.size; - cheat_manager_state.curr_memory_buf = (uint8_t*)meminfo.data; + cheat_manager_state.total_memory_size = (unsigned)meminfo.size; + cheat_manager_state.curr_memory_buf = (uint8_t*)meminfo.data; } - cheat_manager_state.num_matches = (cheat_manager_state.total_memory_size*8)/((int)pow(2,cheat_manager_state.search_bit_size)); + cheat_manager_state.num_matches = (cheat_manager_state.total_memory_size * 8) / ((int)pow(2, cheat_manager_state.search_bit_size)); /* Ensure we're aligned on 4-byte boundary */ #if 0 if (meminfo.size % 4 > 0) - cheat_manager_state.total_memory_size = cheat_manager_state.total_memory_size + (4 - (meminfo.size%4)); + cheat_manager_state.total_memory_size = cheat_manager_state.total_memory_size + (4 - (meminfo.size % 4)); #endif if (is_search_initialization) @@ -814,10 +822,10 @@ int cheat_manager_initialize_memory(rarch_setting_t *setting, bool wraparound) if (cheat_manager_state.prev_memory_buf) { free(cheat_manager_state.prev_memory_buf); - cheat_manager_state.prev_memory_buf = NULL; + cheat_manager_state.prev_memory_buf = NULL; } - cheat_manager_state.prev_memory_buf = (uint8_t*) calloc(cheat_manager_state.total_memory_size, sizeof(uint8_t)); + cheat_manager_state.prev_memory_buf = (uint8_t*)calloc(cheat_manager_state.total_memory_size, sizeof(uint8_t)); if (!cheat_manager_state.prev_memory_buf) { runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_INIT_FAIL), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); @@ -827,10 +835,10 @@ int cheat_manager_initialize_memory(rarch_setting_t *setting, bool wraparound) if (cheat_manager_state.matches) { free(cheat_manager_state.matches); - cheat_manager_state.matches = NULL; + cheat_manager_state.matches = NULL; } - cheat_manager_state.matches = (uint8_t*) calloc(cheat_manager_state.total_memory_size, sizeof(uint8_t)); + cheat_manager_state.matches = (uint8_t*)calloc(cheat_manager_state.total_memory_size, sizeof(uint8_t)); if (!cheat_manager_state.matches) { free(cheat_manager_state.prev_memory_buf); @@ -845,7 +853,7 @@ int cheat_manager_initialize_memory(rarch_setting_t *setting, bool wraparound) for (i = 0; i < cheat_manager_state.num_memory_buffers; i++) { - memcpy(cheat_manager_state.prev_memory_buf+offset, cheat_manager_state.memory_buf_list[i], cheat_manager_state.memory_size_list[i]); + memcpy(cheat_manager_state.prev_memory_buf + offset, cheat_manager_state.memory_buf_list[i], cheat_manager_state.memory_size_list[i]); offset += cheat_manager_state.memory_size_list[i]; } @@ -874,7 +882,7 @@ static unsigned translate_address(unsigned address, unsigned char **curr) for (i = 0; i < cheat_manager_state.num_memory_buffers; i++) { - if ((address >= offset) && (address < offset+cheat_manager_state.memory_size_list[i])) + if ((address >= offset) && (address < offset + cheat_manager_state.memory_size_list[i])) { *curr = cheat_manager_state.memory_buf_list[i]; break; @@ -888,38 +896,38 @@ static unsigned translate_address(unsigned address, unsigned char **curr) static void cheat_manager_setup_search_meta(unsigned int bitsize, unsigned int *bytes_per_item, unsigned int *mask, unsigned int *bits) { - switch( bitsize) + switch (bitsize) { - case 0 : - *bytes_per_item = 1; - *bits = 1; - *mask = 0x01; - break; - case 1 : - *bytes_per_item = 1; - *bits = 2; - *mask = 0x03; - break; - case 2 : - *bytes_per_item = 1; - *bits = 4; - *mask = 0x0F; - break; - case 3 : - *bytes_per_item = 1; - *bits = 8; - *mask = 0xFF; - break; - case 4 : - *bytes_per_item = 2; - *bits = 8; - *mask = 0xFFFF; - break; - case 5 : - *bytes_per_item = 4; - *bits = 8; - *mask = 0xFFFFFFFF; - break; + case 0: + *bytes_per_item = 1; + *bits = 1; + *mask = 0x01; + break; + case 1: + *bytes_per_item = 1; + *bits = 2; + *mask = 0x03; + break; + case 2: + *bytes_per_item = 1; + *bits = 4; + *mask = 0x0F; + break; + case 3: + *bytes_per_item = 1; + *bits = 8; + *mask = 0xFF; + break; + case 4: + *bytes_per_item = 2; + *bits = 8; + *mask = 0xFFFF; + break; + case 5: + *bytes_per_item = 4; + *bits = 8; + *mask = 0xFFFFFFFF; + break; } } @@ -963,17 +971,17 @@ int cheat_manager_search_eqminus(rarch_setting_t *setting, bool wraparound) int cheat_manager_search(enum cheat_search_type search_type) { char msg[100]; - unsigned char *curr = cheat_manager_state.curr_memory_buf; - unsigned char *prev = cheat_manager_state.prev_memory_buf; - unsigned int idx = 0; - unsigned int curr_val = 0; - unsigned int prev_val = 0; - unsigned int mask = 0; + unsigned char *curr = cheat_manager_state.curr_memory_buf; + unsigned char *prev = cheat_manager_state.prev_memory_buf; + unsigned int idx = 0; + unsigned int curr_val = 0; + unsigned int prev_val = 0; + unsigned int mask = 0; unsigned int bytes_per_item = 1; - unsigned int bits = 8; - unsigned int offset = 0; - unsigned int i = 0; - bool refresh = false; + unsigned int bits = 8; + unsigned int offset = 0; + unsigned int i = 0; + bool refresh = false; if (cheat_manager_state.num_memory_buffers == 0) { @@ -992,80 +1000,80 @@ int cheat_manager_search(enum cheat_search_type search_type) switch (bytes_per_item) { - case 2 : - curr_val = cheat_manager_state.big_endian ? - (*(curr+idx-offset)*256) + *(curr+idx+1-offset) : - *(curr+idx-offset) + (*(curr+idx+1-offset)*256); - prev_val = cheat_manager_state.big_endian ? - (*(prev+idx)*256) + *(prev+idx+1) : - *(prev+idx) + (*(prev+idx+1)*256); - break; - case 4 : - curr_val = cheat_manager_state.big_endian ? - (*(curr+idx-offset)*256*256*256) + (*(curr+idx+1-offset)*256*256) + (*(curr+idx+2-offset)*256) + *(curr+idx+3-offset) : - *(curr+idx-offset) + (*(curr+idx+1-offset)*256) + (*(curr+idx+2-offset)*256*256) + (*(curr+idx+3-offset)*256*256*256); - prev_val = cheat_manager_state.big_endian ? - (*(prev+idx)*256*256*256) + (*(prev+idx+1)*256*256) + (*(prev+idx+2)*256) + *(prev+idx+3) : - *(prev+idx) + (*(prev+idx+1)*256) + (*(prev+idx+2)*256*256) + (*(prev+idx+3)*256*256*256); - break; - case 1 : - default : - curr_val = *(curr-offset+idx); - prev_val = *(prev+idx); - break; + case 2: + curr_val = cheat_manager_state.big_endian ? + (*(curr + idx - offset) * 256) + *(curr + idx + 1 - offset) : + *(curr + idx - offset) + (*(curr + idx + 1 - offset) * 256); + prev_val = cheat_manager_state.big_endian ? + (*(prev + idx) * 256) + *(prev + idx + 1) : + *(prev + idx) + (*(prev + idx + 1) * 256); + break; + case 4: + curr_val = cheat_manager_state.big_endian ? + (*(curr + idx - offset) * 256 * 256 * 256) + (*(curr + idx + 1 - offset) * 256 * 256) + (*(curr + idx + 2 - offset) * 256) + *(curr + idx + 3 - offset) : + *(curr + idx - offset) + (*(curr + idx + 1 - offset) * 256) + (*(curr + idx + 2 - offset) * 256 * 256) + (*(curr + idx + 3 - offset) * 256 * 256 * 256); + prev_val = cheat_manager_state.big_endian ? + (*(prev + idx) * 256 * 256 * 256) + (*(prev + idx + 1) * 256 * 256) + (*(prev + idx + 2) * 256) + *(prev + idx + 3) : + *(prev + idx) + (*(prev + idx + 1) * 256) + (*(prev + idx + 2) * 256 * 256) + (*(prev + idx + 3) * 256 * 256 * 256); + break; + case 1: + default: + curr_val = *(curr - offset + idx); + prev_val = *(prev + idx); + break; } - for (byte_part = 0; byte_part < 8/bits; byte_part++) + for (byte_part = 0; byte_part < 8 / bits; byte_part++) { - unsigned int curr_subval = (curr_val >> (byte_part*bits)) & mask; - unsigned int prev_subval = (prev_val >> (byte_part*bits)) & mask; + unsigned int curr_subval = (curr_val >> (byte_part * bits)) & mask; + unsigned int prev_subval = (prev_val >> (byte_part * bits)) & mask; unsigned int prev_match; if (bits < 8) - prev_match = *(cheat_manager_state.matches+idx) & (mask << (byte_part*bits)); + prev_match = *(cheat_manager_state.matches + idx) & (mask << (byte_part * bits)); else - prev_match = *(cheat_manager_state.matches+idx); + prev_match = *(cheat_manager_state.matches + idx); if (prev_match > 0) { bool match = false; switch (search_type) { - case CHEAT_SEARCH_TYPE_EXACT : - match = (curr_subval == cheat_manager_state.search_exact_value); - break; - case CHEAT_SEARCH_TYPE_LT : - match = (curr_subval < prev_subval); - break; - case CHEAT_SEARCH_TYPE_GT : - match = (curr_subval > prev_subval); - break; - case CHEAT_SEARCH_TYPE_LTE : - match = (curr_subval <= prev_subval); - break; - case CHEAT_SEARCH_TYPE_GTE : - match = (curr_subval >= prev_subval); - break; - case CHEAT_SEARCH_TYPE_EQ : - match = (curr_subval == prev_subval); - break; - case CHEAT_SEARCH_TYPE_NEQ : - match = (curr_subval != prev_subval); - break; - case CHEAT_SEARCH_TYPE_EQPLUS : - match = (curr_subval == prev_subval+cheat_manager_state.search_eqplus_value); - break; - case CHEAT_SEARCH_TYPE_EQMINUS : - match = (curr_subval == prev_subval-cheat_manager_state.search_eqminus_value); - break; + case CHEAT_SEARCH_TYPE_EXACT: + match = (curr_subval == cheat_manager_state.search_exact_value); + break; + case CHEAT_SEARCH_TYPE_LT: + match = (curr_subval < prev_subval); + break; + case CHEAT_SEARCH_TYPE_GT: + match = (curr_subval > prev_subval); + break; + case CHEAT_SEARCH_TYPE_LTE: + match = (curr_subval <= prev_subval); + break; + case CHEAT_SEARCH_TYPE_GTE: + match = (curr_subval >= prev_subval); + break; + case CHEAT_SEARCH_TYPE_EQ: + match = (curr_subval == prev_subval); + break; + case CHEAT_SEARCH_TYPE_NEQ: + match = (curr_subval != prev_subval); + break; + case CHEAT_SEARCH_TYPE_EQPLUS: + match = (curr_subval == prev_subval + cheat_manager_state.search_eqplus_value); + break; + case CHEAT_SEARCH_TYPE_EQMINUS: + match = (curr_subval == prev_subval - cheat_manager_state.search_eqminus_value); + break; } if (!match) { if (bits < 8) - *(cheat_manager_state.matches+idx) = *(cheat_manager_state.matches+idx) & - (( ~(mask << (byte_part*bits))) & 0xFF); + *(cheat_manager_state.matches + idx) = *(cheat_manager_state.matches + idx) & + ((~(mask << (byte_part * bits))) & 0xFF); else - memset(cheat_manager_state.matches+idx,0,bytes_per_item); + memset(cheat_manager_state.matches + idx, 0, bytes_per_item); if (cheat_manager_state.num_matches > 0) cheat_manager_state.num_matches--; } @@ -1077,7 +1085,7 @@ int cheat_manager_search(enum cheat_search_type search_type) for (i = 0; i < cheat_manager_state.num_memory_buffers; i++) { - memcpy(cheat_manager_state.prev_memory_buf+offset, cheat_manager_state.memory_buf_list[i], cheat_manager_state.memory_size_list[i]); + memcpy(cheat_manager_state.prev_memory_buf + offset, cheat_manager_state.memory_buf_list[i], cheat_manager_state.memory_size_list[i]); offset += cheat_manager_state.memory_size_list[i]; } @@ -1101,11 +1109,11 @@ bool cheat_manager_add_new_code(unsigned int memory_search_size, unsigned int ad if (!cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO)) return false; - cheat_manager_state.cheats[cheat_manager_state.size-1].address = address; - cheat_manager_state.cheats[cheat_manager_state.size-1].address_mask = address_mask; - cheat_manager_state.cheats[cheat_manager_state.size-1].memory_search_size = memory_search_size; - cheat_manager_state.cheats[cheat_manager_state.size-1].value = value; - cheat_manager_state.cheats[cheat_manager_state.size-1].big_endian = big_endian; + cheat_manager_state.cheats[cheat_manager_state.size - 1].address = address; + cheat_manager_state.cheats[cheat_manager_state.size - 1].address_mask = address_mask; + cheat_manager_state.cheats[cheat_manager_state.size - 1].memory_search_size = memory_search_size; + cheat_manager_state.cheats[cheat_manager_state.size - 1].value = value; + cheat_manager_state.cheats[cheat_manager_state.size - 1].big_endian = big_endian; return true; } @@ -1113,16 +1121,16 @@ int cheat_manager_add_matches(const char *path, const char *label, unsigned type, size_t menuidx, size_t entry_idx) { char msg[100]; - bool refresh = false; - unsigned byte_part = 0; - unsigned int idx = 0; - unsigned int mask = 0; + bool refresh = false; + unsigned byte_part = 0; + unsigned int idx = 0; + unsigned int mask = 0; unsigned int bytes_per_item = 1; - unsigned int bits = 8; - unsigned int curr_val = 0; - unsigned int num_added = 0; - unsigned int offset = 0; - unsigned char *curr = cheat_manager_state.curr_memory_buf; + unsigned int bits = 8; + unsigned int curr_val = 0; + unsigned int num_added = 0; + unsigned int offset = 0; + unsigned char *curr = cheat_manager_state.curr_memory_buf; if (cheat_manager_state.num_matches + cheat_manager_state.size > 100) { @@ -1137,31 +1145,31 @@ int cheat_manager_add_matches(const char *path, switch (bytes_per_item) { - case 2 : - curr_val = cheat_manager_state.big_endian ? - (*(curr+idx-offset)*256) + *(curr+idx+1-offset) : - *(curr+idx-offset) + (*(curr+idx+1-offset)*256); - break; - case 4 : - curr_val = cheat_manager_state.big_endian ? - (*(curr+idx-offset)*256*256*256) + (*(curr+idx+1-offset)*256*256) + (*(curr+idx+2-offset)*256) + *(curr+idx+3-offset) : - *(curr+idx-offset) + (*(curr+idx+1-offset)*256) + (*(curr+idx+2-offset)*256*256) + (*(curr+idx+3-offset)*256*256*256); - break; - case 1 : - default : - curr_val = *(curr-offset+idx); - break; + case 2: + curr_val = cheat_manager_state.big_endian ? + (*(curr + idx - offset) * 256) + *(curr + idx + 1 - offset) : + *(curr + idx - offset) + (*(curr + idx + 1 - offset) * 256); + break; + case 4: + curr_val = cheat_manager_state.big_endian ? + (*(curr + idx - offset) * 256 * 256 * 256) + (*(curr + idx + 1 - offset) * 256 * 256) + (*(curr + idx + 2 - offset) * 256) + *(curr + idx + 3 - offset) : + *(curr + idx - offset) + (*(curr + idx + 1 - offset) * 256) + (*(curr + idx + 2 - offset) * 256 * 256) + (*(curr + idx + 3 - offset) * 256 * 256 * 256); + break; + case 1: + default: + curr_val = *(curr - offset + idx); + break; } - for (byte_part = 0; byte_part < 8/bits; byte_part++) + for (byte_part = 0; byte_part < 8 / bits; byte_part++) { unsigned int prev_match; if (bits < 8) { - prev_match = *(cheat_manager_state.matches+idx) & (mask << (byte_part*bits)); + prev_match = *(cheat_manager_state.matches + idx) & (mask << (byte_part * bits)); if (prev_match) { - if (!cheat_manager_add_new_code(cheat_manager_state.search_bit_size, idx, (mask << (byte_part*bits)), + if (!cheat_manager_add_new_code(cheat_manager_state.search_bit_size, idx, (mask << (byte_part * bits)), cheat_manager_state.big_endian, curr_val)) { runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADDED_MATCHES_FAIL), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); @@ -1172,7 +1180,7 @@ int cheat_manager_add_matches(const char *path, } else { - prev_match = *(cheat_manager_state.matches+idx); + prev_match = *(cheat_manager_state.matches + idx); if (prev_match) { if (!cheat_manager_add_new_code(cheat_manager_state.search_bit_size, idx, 0xFF, @@ -1207,38 +1215,38 @@ void cheat_manager_apply_rumble(struct item_cheat *cheat, unsigned int curr_valu switch (cheat->rumble_type) { - case RUMBLE_TYPE_DISABLED: - return; - case RUMBLE_TYPE_CHANGES: - rumble = (curr_value != cheat->rumble_prev_value); - break; - case RUMBLE_TYPE_DOES_NOT_CHANGE: - rumble = (curr_value == cheat->rumble_prev_value); - break; - case RUMBLE_TYPE_INCREASE: - rumble = (curr_value > cheat->rumble_prev_value); - break; - case RUMBLE_TYPE_DECREASE: - rumble = (curr_value < cheat->rumble_prev_value); - break; - case RUMBLE_TYPE_EQ_VALUE: - rumble = (curr_value == cheat->rumble_value); - break; - case RUMBLE_TYPE_NEQ_VALUE: - rumble = (curr_value != cheat->rumble_value); - break; - case RUMBLE_TYPE_LT_VALUE: - rumble = (curr_value < cheat->rumble_value); - break; - case RUMBLE_TYPE_GT_VALUE: - rumble = (curr_value > cheat->rumble_value); - break; - case RUMBLE_TYPE_INCREASE_BY_VALUE: - rumble = (curr_value == cheat->rumble_prev_value + cheat->rumble_value); - break; - case RUMBLE_TYPE_DECREASE_BY_VALUE: - rumble = (curr_value == cheat->rumble_prev_value - cheat->rumble_value); - break; + case RUMBLE_TYPE_DISABLED: + return; + case RUMBLE_TYPE_CHANGES: + rumble = (curr_value != cheat->rumble_prev_value); + break; + case RUMBLE_TYPE_DOES_NOT_CHANGE: + rumble = (curr_value == cheat->rumble_prev_value); + break; + case RUMBLE_TYPE_INCREASE: + rumble = (curr_value > cheat->rumble_prev_value); + break; + case RUMBLE_TYPE_DECREASE: + rumble = (curr_value < cheat->rumble_prev_value); + break; + case RUMBLE_TYPE_EQ_VALUE: + rumble = (curr_value == cheat->rumble_value); + break; + case RUMBLE_TYPE_NEQ_VALUE: + rumble = (curr_value != cheat->rumble_value); + break; + case RUMBLE_TYPE_LT_VALUE: + rumble = (curr_value < cheat->rumble_value); + break; + case RUMBLE_TYPE_GT_VALUE: + rumble = (curr_value > cheat->rumble_value); + break; + case RUMBLE_TYPE_INCREASE_BY_VALUE: + rumble = (curr_value == cheat->rumble_prev_value + cheat->rumble_value); + break; + case RUMBLE_TYPE_DECREASE_BY_VALUE: + rumble = (curr_value == cheat->rumble_prev_value - cheat->rumble_value); + break; } cheat->rumble_prev_value = curr_value; @@ -1249,8 +1257,8 @@ void cheat_manager_apply_rumble(struct item_cheat *cheat, unsigned int curr_valu { if (rumble) { - cheat->rumble_primary_end_time = cpu_features_get_time_usec() + (cheat->rumble_primary_duration*1000); - cheat->rumble_secondary_end_time = cpu_features_get_time_usec() + (cheat->rumble_secondary_duration*1000); + cheat->rumble_primary_end_time = cpu_features_get_time_usec() + (cheat->rumble_primary_duration * 1000); + cheat->rumble_secondary_end_time = cpu_features_get_time_usec() + (cheat->rumble_secondary_duration * 1000); input_driver_set_rumble_state(cheat->rumble_port, RETRO_RUMBLE_STRONG, cheat->rumble_primary_strength); input_driver_set_rumble_state(cheat->rumble_port, RETRO_RUMBLE_WEAK, cheat->rumble_secondary_strength); } @@ -1286,11 +1294,11 @@ void cheat_manager_apply_retro_cheats(void) { unsigned i; unsigned int offset; - unsigned int mask = 0; + unsigned int mask = 0; unsigned int bytes_per_item = 1; - unsigned int bits = 8; - unsigned int curr_val = 0; - bool run_cheat = true; + unsigned int bits = 8; + unsigned int curr_val = 0; + bool run_cheat = true; if ((!cheat_manager_state.cheats)) return; @@ -1298,10 +1306,10 @@ void cheat_manager_apply_retro_cheats(void) for (i = 0; i < cheat_manager_state.size; i++) { unsigned char *curr; - unsigned int idx; - bool set_value = false; + unsigned int idx; + bool set_value = false; unsigned int value_to_set = 0; - unsigned int repeat_iter = 0; + unsigned int repeat_iter = 0; unsigned int address_mask = cheat_manager_state.cheats[i].address_mask; if (cheat_manager_state.cheats[i].handler != CHEAT_HANDLER_TYPE_RETRO || !cheat_manager_state.cheats[i].state) @@ -1322,133 +1330,136 @@ void cheat_manager_apply_retro_cheats(void) cheat_manager_setup_search_meta(cheat_manager_state.cheats[i].memory_search_size, &bytes_per_item, &mask, &bits); curr = cheat_manager_state.curr_memory_buf; - idx = cheat_manager_state.cheats[i].address; + idx = cheat_manager_state.cheats[i].address; offset = translate_address(idx, &curr); switch (bytes_per_item) { - case 2 : - curr_val = cheat_manager_state.big_endian ? - (*(curr+idx-offset)*256) + *(curr+idx+1-offset) : - *(curr+idx-offset) + (*(curr+idx+1-offset)*256); - break; - case 4 : - curr_val = cheat_manager_state.big_endian ? - (*(curr+idx-offset)*256*256*256) + (*(curr+idx+1-offset)*256*256) + (*(curr+idx+2-offset)*256) + *(curr+idx+3-offset) : - *(curr+idx-offset) + (*(curr+idx+1-offset)*256) + (*(curr+idx+2-offset)*256*256) + (*(curr+idx+3-offset)*256*256*256); - break; - case 1 : - default : - curr_val = *(curr+idx-offset); - break; + case 2: + curr_val = cheat_manager_state.big_endian ? + (*(curr + idx - offset) * 256) + *(curr + idx + 1 - offset) : + *(curr + idx - offset) + (*(curr + idx + 1 - offset) * 256); + break; + case 4: + curr_val = cheat_manager_state.big_endian ? + (*(curr + idx - offset) * 256 * 256 * 256) + (*(curr + idx + 1 - offset) * 256 * 256) + (*(curr + idx + 2 - offset) * 256) + *(curr + idx + 3 - offset) : + *(curr + idx - offset) + (*(curr + idx + 1 - offset) * 256) + (*(curr + idx + 2 - offset) * 256 * 256) + (*(curr + idx + 3 - offset) * 256 * 256 * 256); + break; + case 1: + default: + curr_val = *(curr + idx - offset); + break; } cheat_manager_apply_rumble(&cheat_manager_state.cheats[i], curr_val); switch (cheat_manager_state.cheats[i].cheat_type) { - case CHEAT_TYPE_SET_TO_VALUE : - set_value = true; - value_to_set = cheat_manager_state.cheats[i].value; - break; - case CHEAT_TYPE_INCREASE_VALUE: - set_value = true; - value_to_set = curr_val + cheat_manager_state.cheats[i].value; - break; - case CHEAT_TYPE_DECREASE_VALUE: - set_value = true; - value_to_set = curr_val - cheat_manager_state.cheats[i].value; - break; - case CHEAT_TYPE_RUN_NEXT_IF_EQ: - if (!(curr_val == cheat_manager_state.cheats[i].value)) - run_cheat = false; - break; - case CHEAT_TYPE_RUN_NEXT_IF_NEQ: - if (!(curr_val != cheat_manager_state.cheats[i].value)) - run_cheat = false; - break; - case CHEAT_TYPE_RUN_NEXT_IF_LT: - if (!(cheat_manager_state.cheats[i].value < curr_val)) - run_cheat = false; - break; - case CHEAT_TYPE_RUN_NEXT_IF_GT: - if (!(cheat_manager_state.cheats[i].value > curr_val)) - run_cheat = false; - break; - + case CHEAT_TYPE_SET_TO_VALUE: + set_value = true; + value_to_set = cheat_manager_state.cheats[i].value; + break; + case CHEAT_TYPE_INCREASE_VALUE: + set_value = true; + value_to_set = curr_val + cheat_manager_state.cheats[i].value; + break; + case CHEAT_TYPE_DECREASE_VALUE: + set_value = true; + value_to_set = curr_val - cheat_manager_state.cheats[i].value; + break; + case CHEAT_TYPE_RUN_NEXT_IF_EQ: + if (!(curr_val == cheat_manager_state.cheats[i].value)) + run_cheat = false; + break; + case CHEAT_TYPE_RUN_NEXT_IF_NEQ: + if (!(curr_val != cheat_manager_state.cheats[i].value)) + run_cheat = false; + break; + case CHEAT_TYPE_RUN_NEXT_IF_LT: + if (!(cheat_manager_state.cheats[i].value < curr_val)) + run_cheat = false; + break; + case CHEAT_TYPE_RUN_NEXT_IF_GT: + if (!(cheat_manager_state.cheats[i].value > curr_val)) + run_cheat = false; + break; } + if (set_value) { for (repeat_iter = 1; repeat_iter <= cheat_manager_state.cheats[i].repeat_count; repeat_iter++) { switch (bytes_per_item) { - case 2 : - if (cheat_manager_state.cheats[i].big_endian) - { - *(curr+idx-offset) = (value_to_set >> 8) & 0xFF; - *(curr+idx+1-offset) = value_to_set & 0xFF; - } - else - { - *(curr+idx-offset) = value_to_set & 0xFF; - *(curr+idx+1-offset) = (value_to_set >> 8) & 0xFF; + case 2: + if (cheat_manager_state.cheats[i].big_endian) + { + *(curr + idx - offset) = (value_to_set >> 8) & 0xFF; + *(curr + idx + 1 - offset) = value_to_set & 0xFF; + } + else + { + *(curr + idx - offset) = value_to_set & 0xFF; + *(curr + idx + 1 - offset) = (value_to_set >> 8) & 0xFF; + } + break; + case 4: + if (cheat_manager_state.cheats[i].big_endian) + { + *(curr + idx - offset) = (value_to_set >> 24) & 0xFF; + *(curr + idx + 1 - offset) = (value_to_set >> 16) & 0xFF; + *(curr + idx + 2 - offset) = (value_to_set >> 8) & 0xFF; + *(curr + idx + 3 - offset) = value_to_set & 0xFF; + } + else + { + *(curr + idx - offset) = value_to_set & 0xFF; + *(curr + idx + 1 - offset) = (value_to_set >> 8) & 0xFF; + *(curr + idx + 2 - offset) = (value_to_set >> 16) & 0xFF; + *(curr + idx + 3 - offset) = (value_to_set >> 24) & 0xFF; + } + break; + case 1: + if (bits < 8) + { + unsigned bitpos; + unsigned char val = *(curr + idx - offset); - } - break; - case 4 : - if (cheat_manager_state.cheats[i].big_endian) + for (bitpos = 0; bitpos < 8; bitpos++) { - *(curr+idx-offset) = (value_to_set >> 24) & 0xFF; - *(curr+idx+1-offset) = (value_to_set >> 16) & 0xFF; - *(curr+idx+2-offset) = (value_to_set >> 8) & 0xFF; - *(curr+idx+3-offset) = value_to_set & 0xFF; - } - else - { - *(curr+idx-offset) = value_to_set & 0xFF; - *(curr+idx+1-offset) = (value_to_set >> 8) & 0xFF; - *(curr+idx+2-offset) = (value_to_set >> 16) & 0xFF; - *(curr+idx+3-offset) = (value_to_set >> 24) & 0xFF; - - } - break; - case 1 : - if (bits < 8) - { - unsigned bitpos; - unsigned char val = *(curr+idx-offset); - - for (bitpos = 0; bitpos < 8; bitpos++) + if ((address_mask >> bitpos) & 0x01) { - if ((address_mask>>bitpos)&0x01) - { - mask = (~(1<>bitpos)&0x01)<> bitpos) & 0x01) << bitpos); } - *(curr+idx-offset) = val; } - else - *(curr+idx-offset) = value_to_set & 0xFF; - break; - default : - *(curr+idx-offset) = value_to_set & 0xFF; - break; + + *(curr + idx - offset) = val; + } + else + *(curr + idx - offset) = value_to_set & 0xFF; + break; + default: + *(curr + idx - offset) = value_to_set & 0xFF; + break; } + value_to_set += cheat_manager_state.cheats[i].repeat_add_to_value; - value_to_set = value_to_set%mask; + + if (mask != 0) + value_to_set = value_to_set % mask; if (bits < 8) { unsigned int bit_iter; for (bit_iter = 0; bit_iter < cheat_manager_state.cheats[i].repeat_add_to_address; bit_iter++) { - address_mask = (address_mask< cheat_manager_state.num_matches-1) + if (target_match_idx > cheat_manager_state.num_matches - 1) return; if (cheat_manager_state.num_memory_buffers == 0) @@ -1501,30 +1512,30 @@ void cheat_manager_match_action(enum cheat_match_action_type match_action, unsig switch (bytes_per_item) { - case 2 : - curr_val = cheat_manager_state.big_endian ? - (*(curr+idx-offset)*256) + *(curr+idx+1-offset) : - *(curr+idx-offset) + (*(curr+idx+1-offset)*256); - if (prev) - prev_val = cheat_manager_state.big_endian ? - (*(prev+idx)*256) + *(prev+idx+1) : - *(prev+idx) + (*(prev+idx+1)*256); - break; - case 4 : - curr_val = cheat_manager_state.big_endian ? - (*(curr+idx-offset)*256*256*256) + (*(curr+idx+1-offset)*256*256) + (*(curr+idx+2-offset)*256) + *(curr+idx+3-offset) : - *(curr+idx-offset) + (*(curr+idx+1-offset)*256) + (*(curr+idx+2-offset)*256*256) + (*(curr+idx+3-offset)*256*256*256); - if (prev) - prev_val = cheat_manager_state.big_endian ? - (*(prev+idx)*256*256*256) + (*(prev+idx+1)*256*256) + (*(prev+idx+2)*256) + *(prev+idx+3) : - *(prev+idx) + (*(prev+idx+1)*256) + (*(prev+idx+2)*256*256) + (*(prev+idx+3)*256*256*256); - break; - case 1 : - default : - curr_val = *(curr+idx-offset); - if (prev) - prev_val = *(prev+idx); - break; + case 2: + curr_val = cheat_manager_state.big_endian ? + (*(curr + idx - offset) * 256) + *(curr + idx + 1 - offset) : + *(curr + idx - offset) + (*(curr + idx + 1 - offset) * 256); + if (prev) + prev_val = cheat_manager_state.big_endian ? + (*(prev + idx) * 256) + *(prev + idx + 1) : + *(prev + idx) + (*(prev + idx + 1) * 256); + break; + case 4: + curr_val = cheat_manager_state.big_endian ? + (*(curr + idx - offset) * 256 * 256 * 256) + (*(curr + idx + 1 - offset) * 256 * 256) + (*(curr + idx + 2 - offset) * 256) + *(curr + idx + 3 - offset) : + *(curr + idx - offset) + (*(curr + idx + 1 - offset) * 256) + (*(curr + idx + 2 - offset) * 256 * 256) + (*(curr + idx + 3 - offset) * 256 * 256 * 256); + if (prev) + prev_val = cheat_manager_state.big_endian ? + (*(prev + idx) * 256 * 256 * 256) + (*(prev + idx + 1) * 256 * 256) + (*(prev + idx + 2) * 256) + *(prev + idx + 3) : + *(prev + idx) + (*(prev + idx + 1) * 256) + (*(prev + idx + 2) * 256 * 256) + (*(prev + idx + 3) * 256 * 256 * 256); + break; + case 1: + default: + curr_val = *(curr + idx - offset); + if (prev) + prev_val = *(prev + idx); + break; } if (match_action == CHEAT_MATCH_ACTION_TYPE_BROWSE) @@ -1537,44 +1548,44 @@ void cheat_manager_match_action(enum cheat_match_action_type match_action, unsig if (!prev) return; - for (byte_part = 0; byte_part < 8/bits; byte_part++) + for (byte_part = 0; byte_part < 8 / bits; byte_part++) { unsigned int prev_match; if (bits < 8) { - prev_match = *(cheat_manager_state.matches+idx) & (mask << (byte_part*bits)); + prev_match = *(cheat_manager_state.matches + idx) & (mask << (byte_part * bits)); if (prev_match) { if (target_match_idx == curr_match_idx) { switch (match_action) { - case CHEAT_MATCH_ACTION_TYPE_BROWSE : - return; - case CHEAT_MATCH_ACTION_TYPE_VIEW : - *address = idx; - *address_mask = (mask << (byte_part*bits)); - *curr_value = curr_val; - *prev_value = prev_val; - return; - case CHEAT_MATCH_ACTION_TYPE_COPY : - if (!cheat_manager_add_new_code(cheat_manager_state.search_bit_size, idx, (mask << (byte_part*bits)), - cheat_manager_state.big_endian, curr_val)) - runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADD_MATCH_FAIL), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - else - runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - return; - case CHEAT_MATCH_ACTION_TYPE_DELETE : - if (bits < 8) - *(cheat_manager_state.matches+idx) = *(cheat_manager_state.matches+idx) & - (( ~(mask << (byte_part*bits))) & 0xFF); - else - memset(cheat_manager_state.matches+idx,0,bytes_per_item); - if (cheat_manager_state.num_matches > 0) - cheat_manager_state.num_matches--; - runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - return; + case CHEAT_MATCH_ACTION_TYPE_BROWSE: + return; + case CHEAT_MATCH_ACTION_TYPE_VIEW: + *address = idx; + *address_mask = (mask << (byte_part * bits)); + *curr_value = curr_val; + *prev_value = prev_val; + return; + case CHEAT_MATCH_ACTION_TYPE_COPY: + if (!cheat_manager_add_new_code(cheat_manager_state.search_bit_size, idx, (mask << (byte_part * bits)), + cheat_manager_state.big_endian, curr_val)) + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADD_MATCH_FAIL), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + else + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + return; + case CHEAT_MATCH_ACTION_TYPE_DELETE: + if (bits < 8) + *(cheat_manager_state.matches + idx) = *(cheat_manager_state.matches + idx) & + ((~(mask << (byte_part * bits))) & 0xFF); + else + memset(cheat_manager_state.matches + idx, 0, bytes_per_item); + if (cheat_manager_state.num_matches > 0) + cheat_manager_state.num_matches--; + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + return; } return; } @@ -1583,51 +1594,52 @@ void cheat_manager_match_action(enum cheat_match_action_type match_action, unsig } else { - prev_match = *(cheat_manager_state.matches+idx); + prev_match = *(cheat_manager_state.matches + idx); if (prev_match) { if (target_match_idx == curr_match_idx) { switch (match_action) { - case CHEAT_MATCH_ACTION_TYPE_BROWSE : - return; - case CHEAT_MATCH_ACTION_TYPE_VIEW : - *address = idx; - *address_mask = 0xFF; - *curr_value = curr_val; - *prev_value = prev_val; - return; - case CHEAT_MATCH_ACTION_TYPE_COPY : - if (!cheat_manager_add_new_code(cheat_manager_state.search_bit_size, idx, 0xFF, - cheat_manager_state.big_endian, curr_val)) - runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADD_MATCH_FAIL), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - else - runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - return; - case CHEAT_MATCH_ACTION_TYPE_DELETE : - if (bits < 8) - *(cheat_manager_state.matches+idx) = *(cheat_manager_state.matches+idx) & - (( ~(mask << (byte_part*bits))) & 0xFF); - else - memset(cheat_manager_state.matches+idx,0,bytes_per_item); - if (cheat_manager_state.num_matches > 0) - cheat_manager_state.num_matches--; - runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - return; + case CHEAT_MATCH_ACTION_TYPE_BROWSE: + return; + case CHEAT_MATCH_ACTION_TYPE_VIEW: + *address = idx; + *address_mask = 0xFF; + *curr_value = curr_val; + *prev_value = prev_val; + return; + case CHEAT_MATCH_ACTION_TYPE_COPY: + if (!cheat_manager_add_new_code(cheat_manager_state.search_bit_size, idx, 0xFF, + cheat_manager_state.big_endian, curr_val)) + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADD_MATCH_FAIL), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + else + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + return; + case CHEAT_MATCH_ACTION_TYPE_DELETE: + if (bits < 8) + *(cheat_manager_state.matches + idx) = *(cheat_manager_state.matches + idx) & + ((~(mask << (byte_part * bits))) & 0xFF); + else + memset(cheat_manager_state.matches + idx, 0, bytes_per_item); + if (cheat_manager_state.num_matches > 0) + cheat_manager_state.num_matches--; + runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS), 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + return; } } + curr_match_idx++; } } - } } + } int cheat_manager_copy_match(rarch_setting_t *setting, bool wraparound) { cheat_manager_match_action(CHEAT_MATCH_ACTION_TYPE_COPY, - cheat_manager_state.match_idx, NULL, NULL, NULL, NULL); + cheat_manager_state.match_idx, NULL, NULL, NULL, NULL); return 0; } @@ -1635,7 +1647,7 @@ int cheat_manager_delete_match(rarch_setting_t *setting, bool wraparound) { bool refresh = false; cheat_manager_match_action(CHEAT_MATCH_ACTION_TYPE_DELETE, - cheat_manager_state.match_idx, NULL, NULL, NULL, NULL); + cheat_manager_state.match_idx, NULL, NULL, NULL, NULL); #ifdef HAVE_MENU menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); From dd9bde218445474e93309070b9e4646f4f776930 Mon Sep 17 00:00:00 2001 From: orbea Date: Thu, 18 Apr 2019 11:15:05 -0700 Subject: [PATCH 226/237] Fix font selection. Fixes https://github.com/libretro/RetroArch/issues/8593 --- menu/cbs/menu_cbs_ok.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index a9e2cb6436..1be7a77ada 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -6220,7 +6220,9 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, case FILE_TYPE_DIRECTORY: if (cbs->enum_idx != MSG_UNKNOWN || menu_label_hash == MENU_LABEL_DISK_IMAGE_APPEND - || menu_label_hash == MENU_LABEL_SUBSYSTEM_ADD) + || menu_label_hash == MENU_LABEL_SUBSYSTEM_ADD + || menu_label_hash == MENU_LABEL_VIDEO_FONT_PATH + || menu_label_hash == MENU_LABEL_XMB_FONT) BIND_ACTION_OK(cbs, action_ok_directory_push); else BIND_ACTION_OK(cbs, action_ok_push_random_dir); From d7a7260909fc7e172292fd8513f376846791cec9 Mon Sep 17 00:00:00 2001 From: bparker06 Date: Thu, 18 Apr 2019 15:12:06 -0400 Subject: [PATCH 227/237] also fix audio DSP plugin --- menu/cbs/menu_cbs_ok.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 1be7a77ada..b0923cd039 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -6222,7 +6222,8 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, || menu_label_hash == MENU_LABEL_DISK_IMAGE_APPEND || menu_label_hash == MENU_LABEL_SUBSYSTEM_ADD || menu_label_hash == MENU_LABEL_VIDEO_FONT_PATH - || menu_label_hash == MENU_LABEL_XMB_FONT) + || menu_label_hash == MENU_LABEL_XMB_FONT + || menu_label_hash == MENU_LABEL_AUDIO_DSP_PLUGIN) BIND_ACTION_OK(cbs, action_ok_directory_push); else BIND_ACTION_OK(cbs, action_ok_push_random_dir); From b7b17ee7e55e8e8c71d043cfe6994b517599fc65 Mon Sep 17 00:00:00 2001 From: orbea Date: Thu, 18 Apr 2019 12:49:48 -0700 Subject: [PATCH 228/237] Also fix the video filter selection. --- menu/cbs/menu_cbs_ok.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index b0923cd039..5144b7bae4 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -6223,7 +6223,8 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, || menu_label_hash == MENU_LABEL_SUBSYSTEM_ADD || menu_label_hash == MENU_LABEL_VIDEO_FONT_PATH || menu_label_hash == MENU_LABEL_XMB_FONT - || menu_label_hash == MENU_LABEL_AUDIO_DSP_PLUGIN) + || menu_label_hash == MENU_LABEL_AUDIO_DSP_PLUGIN + || menu_label_hash == MENU_LABEL_VIDEO_FILTER) BIND_ACTION_OK(cbs, action_ok_directory_push); else BIND_ACTION_OK(cbs, action_ok_push_random_dir); From a86848d822a64bdde85370af1a2e1e51a1c9070a Mon Sep 17 00:00:00 2001 From: orbea Date: Thu, 18 Apr 2019 13:49:54 -0700 Subject: [PATCH 229/237] qb: Check for libroar 1.0.12. This hides a now fixed upstream libroar build error which breaks LGTM. Unfortunately this only allows the most recent roaraudio version to be used. --- qb/config.libs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 80297d8d6d..997081a894 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -222,7 +222,7 @@ else fi check_pkgconf RSOUND rsound 1.1 -check_pkgconf ROAR libroar +check_pkgconf ROAR libroar 1.0.12 check_val '' JACK -ljack '' jack 0.120.1 '' false check_val '' PULSE -lpulse '' libpulse '' '' false check_val '' SDL -lSDL SDL sdl 1.2.10 '' false From 51d3376f07c54a350fbb0e2209834b332d9544b5 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Fri, 19 Apr 2019 09:15:47 -0400 Subject: [PATCH 230/237] Update CHANGES.md --- CHANGES.md | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 95202231a1..d9145377a0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,6 @@ # 1.7.7 (future) - 3DS: Add unique IDs to prevent cores overwriting each other. +- 3DS: Fix screen tearing when running 50Hz content. - ANDROID: We now target API level 26 (minimum is still API level 9). - ANDROID: Add option to vibrate on touch (works in menu or overlay). - ANDROID: Add device vibration option for cores that support rumble. @@ -7,6 +8,7 @@ - ANDROID: Allow stylus/pen to move mouse without pressing down. - AUDIO: Avoid deadlocks in certain audio drivers when toggling menu sounds on. - BLISS-BOX: Support PSX Jogcon (requires firmware 3.0). +- CHEEVOS: Fix crash when reading memory that is out of range. - CRT: Dynamic super resolution support. - DISCORD: Fix potential crash when username is empty and discord is disabled. - DISCORD: Ask to join support for Linux. @@ -22,14 +24,30 @@ - COMMON: Show CPU model name in log. - COMMON: Add "Help -> Send Debug Info" option (and F10 hotkey) to send diagnostic info to the RetroArch team for help with problems. - COMMON: Show GPU device name/version in log. +- COMMON: Add menu option to write log info to a file. +- COMMON: Add subsystem support for playlists. Subsystem info is automatically saved to the history playlist for easy relaunching. - GL: Add new "gl1" OpenGL 1.1 compliant video driver for legacy GPUs and software renderers - GL: Draw OSD on top of overlay. - GL: Add a new "glcore" driver with slang support (requires GL 3.2+ or GLES3). - GONG: Add savestate support. - GONG: Add video refresh rate core options. - GONG: Two player support via core option. +- GUI: Fix text alignment when using stb_unicode. +- GUI: Fix text display issues when using Japanese (and other unicode-dependent language) text with stb_unicode. +- GUI: Set language on first startup to the user's preferred OS language (Windows, *nix and Android). +- INPUT: Add (scaled radial) analog deadzone and sensitivity options. +- LIBRETRO: Add Turkish language support. +- LIBRETRO: Allow non-accelerated video to rotate the display. +- LOCALIZATION: Update Chinese (Simplified) translation. +- LOCALIZATION: Update Chinese (Traditional) translation. +- LOCALIZATION: Update Dutch translation. +- LOCALIZATION: Update French translation. +- LOCALIZATION: Update German translation. - LOCALIZATION: Update Japanese translation. - LOCALIZATION: Update Polish translation. +- LOCALIZATION: Update Russian translation. +- LOCALIZATION: Update Spanish translation. +- LOCALIZATION: Add new Turkish translation. - MIDI: Fix startup crash in midi driver. - MENU: Add memory statistics support to more context drivers. - MENU: Enable ozone driver for UWP builds. @@ -42,12 +60,15 @@ - MENU: Enable "Add to Favorites" without loading a core. - MENU: Allow core name to be hidden on history/favorites playlists. - MENU: Populate crc32 and db_name fields when adding history/favourites playlist entries. +- MENU: Fix TTF files not showing in OSD/menu font selection screen. +- MENU: Fix audio/video filters not showing in file browser. - MENU/GLUI: Add subsystem support. - MENU/OZONE: Add mouse support on entries (no sidebar yet). - MENU/OZONE: Allow collapsing the sidebar. - MENU/OZONE: Add thumbnail support. -- MENU/QT: Add git version and build date to Help->About window. -- MENU/QT: Fix content loading via the file browser. +- MENU/QT/WIMP: Add git version and build date to Help->About window. +- MENU/QT/WIMP: Fix content loading via the file browser. +- MENU/QT/WIMP: Add new settings window to control all RetroArch settings. - MENU/RGUI: Improve playlist titles. - MENU/RGUI: Add option to hide associated cores in playlists. - MENU/RGUI: Add internal upscaling option. @@ -59,6 +80,14 @@ - MENU/RGUI: Add "full width" layout option. - MENU/RGUI: Ensure menu color theme is applied immediately. - MENU/RGUI: Fix "Lock Menu Aspect Ratio" option when using custom viewports. +- MENU/RGUI: Add widescreen support. +- MENU/RGUI: Allow text to be centred when selecting widescreen layouts. +- MENU/RGUI: Add inline playlist thumbnail support. +- MENU/RGUI: Add optional shadow effects. +- MENU/RGUI: Performance optimizations. +- MENU/RGUI: Add optional extended ASCII support. +- MENU/RGUI: Add optional delay when loading thumbnails. +- MENU/RGUI: Add on-screen keyboard. - MENU/XMB: Prevent crashes when resizing to a tiny window. - NETPLAY: Fix stall-out causing total disconnection with >2 players. - NETPLAY: Different (more intuitive?) default netplay share policy. @@ -73,7 +102,10 @@ - PS2: Fix issues with load state and the font driver. - PS2: File I/O now works for USB and network host. - PS2: Support cores with extra padding in their frame buffers. +- SHADERS: Don't alphabetize shader presets. - SWITCH: Add rumble support. +- SWITCH: Add USB keyboard support. +- VITA: Add bluetooth mouse and keyboard support. - VULKAN: Fix color issues with RGBA8888 swapchains in readback (screenshots). - WII: Don't init overlay when RAM is beyond 72MB. - WII: Skip CRC calculation on content load, can improve load times of larger games by several seconds. From 8aa16caef5fcd7ca510b738f959e2483ce825cfd Mon Sep 17 00:00:00 2001 From: leiradel Date: Fri, 19 Apr 2019 15:01:02 +0100 Subject: [PATCH 231/237] Fix format string in log message --- cheevos/var.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheevos/var.c b/cheevos/var.c index 683ae6918e..d4ae654499 100644 --- a/cheevos/var.c +++ b/cheevos/var.c @@ -321,7 +321,7 @@ uint8_t* cheevos_var_get_memory(const cheevos_var_t* var) meminfo.id = RETRO_MEMORY_RTC; break; default: - CHEEVOS_ERR(CHEEVOS_TAG "invalid bank id: %s\n", var->bank_id); + CHEEVOS_ERR(CHEEVOS_TAG "invalid bank id: %d\n", var->bank_id); break; } From c0bb91150105ae8853b2301d26b403e9e173e36e Mon Sep 17 00:00:00 2001 From: leiradel Date: Fri, 19 Apr 2019 15:12:04 +0100 Subject: [PATCH 232/237] Fix check to chose between mmaps and meminfo --- cheevos/var.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheevos/var.c b/cheevos/var.c index d4ae654499..b595a22753 100644 --- a/cheevos/var.c +++ b/cheevos/var.c @@ -295,7 +295,7 @@ uint8_t* cheevos_var_get_memory(const cheevos_var_t* var) { rarch_system_info_t* system = runloop_get_system_info(); - if (system->mmaps.num_descriptors > var->bank_id) + if (system->mmaps.num_descriptors != 0) { if (var->value >= system->mmaps.descriptors[var->bank_id].core.len) return NULL; From dab941e53dcc611368d35ed8ddec565d0bef21d6 Mon Sep 17 00:00:00 2001 From: leiradel Date: Fri, 19 Apr 2019 17:33:24 +0100 Subject: [PATCH 233/237] Simpler code paths --- cheevos/var.c | 77 +++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/cheevos/var.c b/cheevos/var.c index b595a22753..d0d53cecb6 100644 --- a/cheevos/var.c +++ b/cheevos/var.c @@ -290,54 +290,51 @@ Testing uint8_t* cheevos_var_get_memory(const cheevos_var_t* var) { uint8_t* memory = NULL; + size_t length = 0; - if (var->bank_id >= 0) + if (var->bank_id < 0) + return NULL; + + rarch_system_info_t* system = runloop_get_system_info(); + + if (system->mmaps.num_descriptors != 0) { - rarch_system_info_t* system = runloop_get_system_info(); + memory = (uint8_t*)system->mmaps.descriptors[var->bank_id].core.ptr; + length = system->mmaps.descriptors[var->bank_id].core.len; + } + else + { + retro_ctx_memory_info_t meminfo = {NULL, 0, 0}; - if (system->mmaps.num_descriptors != 0) + switch (var->bank_id) { - if (var->value >= system->mmaps.descriptors[var->bank_id].core.len) - return NULL; - - memory = (uint8_t*)system->mmaps.descriptors[var->bank_id].core.ptr; - } - else - { - retro_ctx_memory_info_t meminfo = {NULL, 0, 0}; - - switch (var->bank_id) - { - case 0: - meminfo.id = RETRO_MEMORY_SYSTEM_RAM; - break; - case 1: - meminfo.id = RETRO_MEMORY_SAVE_RAM; - break; - case 2: - meminfo.id = RETRO_MEMORY_VIDEO_RAM; - break; - case 3: - meminfo.id = RETRO_MEMORY_RTC; - break; - default: - CHEEVOS_ERR(CHEEVOS_TAG "invalid bank id: %d\n", var->bank_id); - break; - } - - core_get_memory(&meminfo); - - if (var->value >= meminfo.size) - return NULL; - - memory = (uint8_t*)meminfo.data; + case 0: + meminfo.id = RETRO_MEMORY_SYSTEM_RAM; + break; + case 1: + meminfo.id = RETRO_MEMORY_SAVE_RAM; + break; + case 2: + meminfo.id = RETRO_MEMORY_VIDEO_RAM; + break; + case 3: + meminfo.id = RETRO_MEMORY_RTC; + break; + default: + CHEEVOS_ERR(CHEEVOS_TAG "invalid bank id: %d\n", var->bank_id); + break; } - if (memory) - memory += var->value; + core_get_memory(&meminfo); + + memory = (uint8_t*)meminfo.data; + length = meminfo.size; } - return memory; + if (memory == NULL || var->value >= length) + return NULL; + + return memory + var->value; } unsigned cheevos_var_get_value(cheevos_var_t* var) From d7d201cb634133f9941fe7aa0c48cc6586d7804a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 19 Apr 2019 19:26:57 +0200 Subject: [PATCH 234/237] (Apple Metal) Add HAVE_MENU to moc generation --- pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj index 275803dad1..660c78d3aa 100644 --- a/pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj @@ -1633,7 +1633,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "make -C ${SRCBASE} -f Makefile.apple HAVE_QT=1 MOC=${QT_INSTALL}/bin/moc generate\n"; + shellScript = "make -C ${SRCBASE} -f Makefile.apple HAVE_MENU=1 HAVE_QT=1 MOC=${QT_INSTALL}/bin/moc generate\n"; }; /* End PBXShellScriptBuildPhase section */ From 1fb1b1bdb7855d86672b8e0f8673ee84fac0b12d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 19 Apr 2019 19:28:25 +0200 Subject: [PATCH 235/237] Add this back --- griffin/griffin_cpp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/griffin/griffin_cpp.cpp b/griffin/griffin_cpp.cpp index 229a1adee0..06fb0f002d 100644 --- a/griffin/griffin_cpp.cpp +++ b/griffin/griffin_cpp.cpp @@ -78,6 +78,7 @@ UI #include "../ui/drivers/qt/options/ui.cpp" #include "../ui/drivers/qt/options/achievements.cpp" #include "../ui/drivers/qt/options/network.cpp" +#include "../ui/drivers/qt/moc_settingswidgets.cpp" #include "../ui/drivers/qt/options/moc_options.cpp" #endif #include "../ui/drivers/moc_ui_qt.cpp" From 1d3533d847f73137aacc402d9457d6a54a2ae352 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 20 Apr 2019 01:14:38 +0200 Subject: [PATCH 236/237] Add rsemaphore.c --- griffin/griffin.c | 1 + libretro-common/rthreads/rsemaphore.c | 116 ++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 libretro-common/rthreads/rsemaphore.c diff --git a/griffin/griffin.c b/griffin/griffin.c index 890913ca63..cecab2d10d 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -1136,6 +1136,7 @@ THREAD #endif #include "../libretro-common/rthreads/rthreads.c" +#include "../libretro-common/rthreads/rsemaphore.c" #include "../gfx/video_thread_wrapper.c" #include "../audio/audio_thread_wrapper.c" #endif diff --git a/libretro-common/rthreads/rsemaphore.c b/libretro-common/rthreads/rsemaphore.c new file mode 100644 index 0000000000..aa2a285d50 --- /dev/null +++ b/libretro-common/rthreads/rsemaphore.c @@ -0,0 +1,116 @@ +/* + Copyright 2005 Allen B. Downey + + This file contains an example program from The Little Book of + Semaphores, available from Green Tea Press, greenteapress.com + + This program 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 Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, see http://www.gnu.org/licenses/gpl.html + or write to the Free Software Foundation, Inc., 51 Franklin St, + Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* Code taken from http://greenteapress.com/semaphores/semaphore.c + * and changed to use libretro-common's mutexes and conditions. + */ + +#include + +#include +#include + +struct ssem +{ + int value; + int wakeups; + slock_t *mutex; + scond_t *cond; +}; + +ssem_t *ssem_new(int value) +{ + ssem_t *semaphore = (ssem_t*)calloc(1, sizeof(*semaphore)); + + if (!semaphore) + goto error; + + semaphore->value = value; + semaphore->wakeups = 0; + semaphore->mutex = slock_new(); + + if (!semaphore->mutex) + goto error; + + semaphore->cond = scond_new(); + + if (!semaphore->cond) + goto error; + + return semaphore; + +error: + if (semaphore->mutex) + slock_free(semaphore->mutex); + semaphore->mutex = NULL; + if (semaphore) + free((void*)semaphore); + return NULL; +} + +void ssem_free(ssem_t *semaphore) +{ + if (!semaphore) + return; + + scond_free(semaphore->cond); + slock_free(semaphore->mutex); + free((void*)semaphore); +} + +void ssem_wait(ssem_t *semaphore) +{ + if (!semaphore) + return; + + slock_lock(semaphore->mutex); + semaphore->value--; + + if (semaphore->value < 0) + { + do + { + scond_wait(semaphore->cond, semaphore->mutex); + }while (semaphore->wakeups < 1); + + semaphore->wakeups--; + } + + slock_unlock(semaphore->mutex); +} + +void ssem_signal(ssem_t *semaphore) +{ + if (!semaphore) + return; + + slock_lock(semaphore->mutex); + semaphore->value++; + + if (semaphore->value <= 0) + { + semaphore->wakeups++; + scond_signal(semaphore->cond); + } + + slock_unlock(semaphore->mutex); +} From b1376167460a3ad167180a6cced689b9124845c1 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 20 Apr 2019 01:15:09 +0200 Subject: [PATCH 237/237] Update Makefile.common --- Makefile.common | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.common b/Makefile.common index e236a8cddd..35a68e98c9 100644 --- a/Makefile.common +++ b/Makefile.common @@ -851,6 +851,7 @@ endif ifeq ($(HAVE_THREADS), 1) OBJ += $(LIBRETRO_COMM_DIR)/rthreads/rthreads.o \ + $(LIBRETRO_COMM_DIR)/rthreads/rsemaphore.o \ gfx/video_thread_wrapper.o \ audio/audio_thread_wrapper.o DEFINES += -DHAVE_THREADS