diff --git a/Makefile.common b/Makefile.common index 28692d589c..03b37bac07 100644 --- a/Makefile.common +++ b/Makefile.common @@ -307,6 +307,7 @@ ifeq ($(HAVE_MENU_COMMON), 1) menu/menu_action.o \ menu/menu_database.o \ menu/menu_shader.o \ + menu/menu_texture.o \ menu/menu_entries.o \ menu/menu_entries_cbs.o \ menu/menu_list.o \ @@ -534,7 +535,7 @@ endif #LIBS += $(LIBXML2_LIBS) #DEFINES += $(LIBXML2_CFLAGS) #else - #OBJ += compat/rxml/rxml.o + #OBJ += libretro-sdk/formats/xml/rxml.o #endif # Compression/Archive @@ -564,7 +565,7 @@ endif ifeq ($(HAVE_ZLIB), 1) ZLIB_OBJS = decompress/zip_support.o - OBJ += gfx/rpng/rpng.o file_extract.o + OBJ += libretro-sdk/formats/png/rpng.o file_extract.o OBJ += $(ZLIB_OBJS) DEFINES += -DHAVE_ZLIB HAVE_COMPRESSION = 1 diff --git a/apple/common/utility.m b/apple/common/utility.m index c187f6135e..8610da2846 100644 --- a/apple/common/utility.m +++ b/apple/common/utility.m @@ -18,8 +18,6 @@ #include "RetroArch_Apple.h" #include "../../settings_data.h" -#import - void apple_display_alert(const char *message, const char *title) { #ifdef IOS diff --git a/apple/iOS/RetroArch_iOS.xcodeproj/project.pbxproj b/apple/iOS/RetroArch_iOS.xcodeproj/project.pbxproj index e954f4d9ec..f233fa8af7 100644 --- a/apple/iOS/RetroArch_iOS.xcodeproj/project.pbxproj +++ b/apple/iOS/RetroArch_iOS.xcodeproj/project.pbxproj @@ -496,6 +496,7 @@ HEADER_SEARCH_PATHS = ( ../, "../../libretro-sdk/include", + ../../, ); INFOPLIST_FILE = "$(SRCROOT)/iOS/RetroArch-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 5.0; @@ -558,6 +559,7 @@ HEADER_SEARCH_PATHS = ( ../, "../../libretro-sdk/include", + ../../, ); INFOPLIST_FILE = "$(SRCROOT)/iOS/RetroArch-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 5.0; diff --git a/apple/iOS/menu.m b/apple/iOS/menu.m index cf56bc5fb3..c5031fe698 100644 --- a/apple/iOS/menu.m +++ b/apple/iOS/menu.m @@ -610,8 +610,12 @@ static void RunActionSheet(const char* title, const struct string_list* items, U const char *dir = NULL; const char *label = NULL; unsigned menu_type = 0; + menu_handle_t *menu = menu_driver_resolve(); - menu_list_get_last_stack(driver.menu->menu_list, + if (!menu) + return; + + menu_list_get_last_stack(menu->menu_list, &dir, &label, &menu_type); get_title(label, dir, menu_type, title, sizeof(title)); @@ -636,9 +640,9 @@ static void RunActionSheet(const char* title, const struct string_list* items, U everything = [NSMutableArray array]; [everything addObject:BOXSTRING(title)]; - end = menu_list_get_size(driver.menu->menu_list); + end = menu_list_get_size(menu->menu_list); - for (i = driver.menu->begin; i < end; i++) + for (i = menu->begin; i < end; i++) { rarch_setting_t *setting; char type_str[PATH_MAX_LENGTH], path_buf[PATH_MAX_LENGTH]; @@ -646,19 +650,19 @@ static void RunActionSheet(const char* title, const struct string_list* items, U const char *path = NULL, *entry_label = NULL; unsigned type = 0, w = 0; - menu_list_get_at_offset(driver.menu->menu_list->selection_buf, i, &path, + menu_list_get_at_offset(menu->menu_list->selection_buf, i, &path, &entry_label, &type); setting = (rarch_setting_t*)setting_data_find_setting - (driver.menu->list_settings, - driver.menu->menu_list->selection_buf->list[i].label); + (menu->list_settings, + menu->menu_list->selection_buf->list[i].label); cbs = (menu_file_list_cbs_t*)menu_list_get_actiondata_at_offset( - driver.menu->menu_list->selection_buf, i); + menu->menu_list->selection_buf, i); if (cbs && cbs->action_get_representation) { cbs->action_get_representation - (driver.menu->menu_list->selection_buf, + (menu->menu_list->selection_buf, &w, type, i, label, type_str, sizeof(type_str), entry_label, path, @@ -683,7 +687,7 @@ static void RunActionSheet(const char* title, const struct string_list* items, U [RAMenuItemGeneralSetting itemForSetting:setting action:^{ - driver.menu->selection_ptr = i; + menu->selection_ptr = i; if (cbs && cbs->action_ok) cbs->action_ok(path, entry_label, type, i); }]]; @@ -695,7 +699,7 @@ static void RunActionSheet(const char* title, const struct string_list* items, U [RAMenuItemBasic itemWithDescription:BOXSTRING(path_buf) action:^{ - driver.menu->selection_ptr = i; + menu->selection_ptr = i; if (cbs && cbs->action_ok) cbs->action_ok(path, entry_label, type, i); else @@ -704,7 +708,7 @@ static void RunActionSheet(const char* title, const struct string_list* items, U cbs->action_start(type, entry_label, MENU_ACTION_START); if (cbs && cbs->action_toggle) cbs->action_toggle(type, entry_label, MENU_ACTION_RIGHT); - menu_list_push_stack(driver.menu->menu_list, "", + menu_list_push_stack(menu->menu_list, "", "info_screen", 0, i); } @@ -716,29 +720,36 @@ static void RunActionSheet(const char* title, const struct string_list* items, U [self.sections addObject:everything]; - if (menu_list_get_stack_size(driver.menu->menu_list) > 1) + if (menu_list_get_stack_size(menu->menu_list) > 1) self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:BOXSTRING("Back") style:UIBarButtonItemStyleBordered target:weakSelf action:@selector(menuBack)]; else self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:BOXSTRING("Resume") style:UIBarButtonItemStyleBordered target:[RetroArch_iOS get] action:@selector(showGameView)]; - if ( driver.menu->message_contents[0] != '\0' ) - apple_display_alert(driver.menu->message_contents, NULL); + if ( menu->message_contents[0] != '\0' ) + apple_display_alert(menu->message_contents, NULL); } - (void)menuRefresh { - if (!driver.menu->need_refresh) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; + if (!menu->need_refresh) return; - menu_entries_deferred_push(driver.menu->menu_list->selection_buf, - driver.menu->menu_list->menu_stack); - driver.menu->need_refresh = false; + menu_entries_deferred_push(menu->menu_list->selection_buf, + menu->menu_list->menu_stack); + menu->need_refresh = false; } - (void)menuBack { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; + menu_apply_deferred_settings(); - menu_list_pop_stack(driver.menu->menu_list); + menu_list_pop_stack(menu->menu_list); [self menuRefresh]; [self reloadData]; } diff --git a/audio/audio_driver.c b/audio/audio_driver.c index 3384e9ac05..81fc90a977 100644 --- a/audio/audio_driver.c +++ b/audio/audio_driver.c @@ -409,3 +409,37 @@ bool audio_driver_mute_toggle(void) return true; } + +/* + * audio_driver_readjust_input_rate: + * + * Readjust the audio input rate. + */ +void audio_driver_readjust_input_rate(void) +{ + double direction, adjust; + int half_size, delta_mid, avail; + unsigned write_idx; + + avail = driver.audio->write_avail(driver.audio_data); + +#if 0 + RARCH_LOG_OUTPUT("Audio buffer is %u%% full\n", + (unsigned)(100 - (avail * 100) / g_extern.audio_data.driver_buffer_size)); +#endif + + write_idx = g_extern.measure_data.buffer_free_samples_count++ & + (AUDIO_BUFFER_FREE_SAMPLES_COUNT - 1); + half_size = g_extern.audio_data.driver_buffer_size / 2; + delta_mid = avail - half_size; + direction = (double)delta_mid / half_size; + adjust = 1.0 + g_settings.audio.rate_control_delta * direction; + + g_extern.measure_data.buffer_free_samples[write_idx] = avail; + g_extern.audio_data.src_ratio = g_extern.audio_data.orig_src_ratio * adjust; + +#if 0 + RARCH_LOG_OUTPUT("New rate: %lf, Orig rate: %lf\n", + g_extern.audio_data.src_ratio, g_extern.audio_data.orig_src_ratio); +#endif +} diff --git a/audio/audio_driver.h b/audio/audio_driver.h index ad789483bb..206b552d20 100644 --- a/audio/audio_driver.h +++ b/audio/audio_driver.h @@ -112,6 +112,13 @@ const char *audio_driver_find_ident(int index); bool audio_driver_mute_toggle(void); +/* + * audio_driver_readjust_input_rate: + * + * Readjust the audio input rate. + */ +void audio_driver_readjust_input_rate(void); + /** * config_get_audio_driver_options: * diff --git a/audio/audio_resampler_driver.c b/audio/audio_resampler_driver.c index 1af57e4dc0..06042ab12f 100644 --- a/audio/audio_resampler_driver.c +++ b/audio/audio_resampler_driver.c @@ -177,7 +177,7 @@ retro_get_cpu_features_t perf_get_cpu_features_cb; #endif -resampler_simd_mask_t resampler_get_cpu_features(void) +static resampler_simd_mask_t resampler_get_cpu_features(void) { #ifdef RARCH_INTERNAL return rarch_get_cpu_features(); diff --git a/audio/audio_utils.c b/audio/audio_utils.c index 2c50fe0197..99bcd48638 100644 --- a/audio/audio_utils.c +++ b/audio/audio_utils.c @@ -25,9 +25,6 @@ #ifdef RARCH_INTERNAL #include "../performance.h" -#include "../libretro.h" -#else -#include "../libretro/libretro.h" #endif /** diff --git a/audio/test/Makefile b/audio/test/Makefile index 4d772d0cc2..935e75abd7 100644 --- a/audio/test/Makefile +++ b/audio/test/Makefile @@ -13,15 +13,16 @@ TESTS := test-sinc-lowest \ CFLAGS += -O3 -ffast-math -g -Wall -pedantic -march=native -std=gnu99 CFLAGS += -DRESAMPLER_TEST -DRARCH_DUMMY_LOG +CFLAGS += -I../../libretro-sdk/include -I../../ LDFLAGS += -lm all: $(TESTS) -resampler-sinc.o: ../resamplers/resampler.c +resampler-sinc.o: ../audio_resampler_driver.c $(CC) -c -o $@ $< $(CFLAGS) -resampler-cc.o: ../resamplers/resampler.c +resampler-cc.o: ../audio_resampler_driver.c $(CC) -c -o $@ $< $(CFLAGS) -DRESAMPLER_IDENT='"CC"' main-cc.o: main.c @@ -33,58 +34,58 @@ snr-cc.o: snr.c cc-resampler.o: ../resamplers/cc_resampler.c $(CC) -c -o $@ $< $(CFLAGS) -sinc-lowest.o: ../resamplers/sinc.c +sinc-lowest.o: ../drivers_resampler/sinc.c $(CC) -c -o $@ $< $(CFLAGS) -DSINC_LOWEST_QUALITY -sinc-lower.o: ../resamplers/sinc.c +sinc-lower.o: ../drivers_resampler/sinc.c $(CC) -c -o $@ $< $(CFLAGS) -DSINC_LOWER_QUALITY -sinc.o: ../resamplers/sinc.c +sinc.o: ../drivers_resampler/sinc.c $(CC) -c -o $@ $< $(CFLAGS) -nearest.o: ../resamplers/nearest.c +nearest.o: ../drivers_resampler/nearest.c $(CC) -c -o $@ $< $(CFLAGS) -sinc-higher.o: ../resamplers/sinc.c +sinc-higher.o: ../drivers_resampler/sinc.c $(CC) -c -o $@ $< $(CFLAGS) -DSINC_HIGHER_QUALITY -sinc-highest.o: ../resamplers/sinc.c +sinc-highest.o: ../drivers_resampler/sinc.c $(CC) -c -o $@ $< $(CFLAGS) -DSINC_HIGHEST_QUALITY -test-sinc-lowest: sinc-lowest.o ../utils.o main.o resampler-sinc.o nearest.o +test-sinc-lowest: sinc-lowest.o ../audio_utils.o main.o resampler-sinc.o nearest.o $(CC) -o $@ $^ $(LDFLAGS) -test-snr-sinc-lowest: sinc-lowest.o ../utils.o snr.o resampler-sinc.o nearest.o +test-snr-sinc-lowest: sinc-lowest.o ../audio_utils.o snr.o resampler-sinc.o nearest.o $(CC) -o $@ $^ $(LDFLAGS) -test-sinc-lower: sinc-lower.o ../utils.o main.o resampler-sinc.o nearest.o +test-sinc-lower: sinc-lower.o ../audio_utils.o main.o resampler-sinc.o nearest.o $(CC) -o $@ $^ $(LDFLAGS) -test-snr-sinc-lower: sinc-lower.o ../utils.o snr.o resampler-sinc.o nearest.o +test-snr-sinc-lower: sinc-lower.o ../audio_utils.o snr.o resampler-sinc.o nearest.o $(CC) -o $@ $^ $(LDFLAGS) -test-sinc: sinc.o ../utils.o main.o resampler-sinc.o nearest.o +test-sinc: sinc.o ../audio_utils.o main.o resampler-sinc.o nearest.o $(CC) -o $@ $^ $(LDFLAGS) -test-snr-sinc: sinc.o ../utils.o snr.o resampler-sinc.o nearest.o +test-snr-sinc: sinc.o ../audio_utils.o snr.o resampler-sinc.o nearest.o $(CC) -o $@ $^ $(LDFLAGS) -test-sinc-higher: sinc-higher.o ../utils.o main.o resampler-sinc.o nearest.o +test-sinc-higher: sinc-higher.o ../audio_utils.o main.o resampler-sinc.o nearest.o $(CC) -o $@ $^ $(LDFLAGS) -test-snr-sinc-higher: sinc-higher.o ../utils.o snr.o resampler-sinc.o nearest.o +test-snr-sinc-higher: sinc-higher.o ../audio_utils.o snr.o resampler-sinc.o nearest.o $(CC) -o $@ $^ $(LDFLAGS) -test-sinc-highest: sinc-highest.o ../utils.o main.o resampler-sinc.o nearest.o +test-sinc-highest: sinc-highest.o ../audio_utils.o main.o resampler-sinc.o nearest.o $(CC) -o $@ $^ $(LDFLAGS) -test-snr-sinc-highest: sinc-highest.o ../utils.o snr.o resampler-sinc.o nearest.o +test-snr-sinc-highest: sinc-highest.o ../audio_utils.o snr.o resampler-sinc.o nearest.o $(CC) -o $@ $^ $(LDFLAGS) -test-cc: cc-resampler.o ../utils.o main-cc.o resampler-cc.o sinc.o nearest.o +test-cc: cc-resampler.o ../audio_utils.o main-cc.o resampler-cc.o sinc.o nearest.o $(CC) -o $@ $^ $(LDFLAGS) -test-snr-cc: cc-resampler.o ../utils.o snr-cc.o resampler-cc.o sinc.o nearest.o +test-snr-cc: cc-resampler.o ../audio_utils.o snr-cc.o resampler-cc.o sinc.o nearest.o $(CC) -o $@ $^ $(LDFLAGS) %.o: %.c diff --git a/audio/test/main.c b/audio/test/main.c index 15e5bfc4e3..abecdba194 100644 --- a/audio/test/main.c +++ b/audio/test/main.c @@ -16,7 +16,7 @@ // Resampler that reads raw S16NE/stereo from stdin and outputs to stdout in S16NE/stereo. // Used for testing and performance benchmarking. -#include "../resamplers/resampler.h" +#include "../audio_resampler_driver.h" #include "../audio_utils.h" #include #include diff --git a/compat/rxml/rxml_test.c b/compat/rxml/rxml_test.c deleted file mode 100644 index 375a443249..0000000000 --- a/compat/rxml/rxml_test.c +++ /dev/null @@ -1,60 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * - * 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 "rxml.h" -#include - -static void print_siblings(struct rxml_node *node, unsigned level) -{ - fprintf(stderr, "\n%*sName: %s\n", level * 4, "", node->name); - if (node->data) - fprintf(stderr, "%*sData: %s\n", level * 4, "", node->data); - - for (const struct rxml_attrib_node *attrib = - node->attrib; attrib; attrib = attrib->next) - fprintf(stderr, "%*s Attrib: %s = %s\n", level * 4, "", - attrib->attrib, attrib->value); - - if (node->children) - print_siblings(node->children, level + 1); - - if (node->next) - print_siblings(node->next, level); -} - -static void rxml_log_document(const char *path) -{ - rxml_document_t *doc = rxml_load_document(path); - if (!doc) - { - fprintf(stderr, "rxml: Failed to load document: %s\n", path); - return; - } - - print_siblings(rxml_root_node(doc), 0); - rxml_free_document(doc); -} - -int main(int argc, char *argv[]) -{ - if (argc != 2) - { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - - rxml_log_document(argv[1]); -} - diff --git a/database_info.c b/database_info.c index 1ad464873b..825220469b 100644 --- a/database_info.c +++ b/database_info.c @@ -35,7 +35,7 @@ int database_open_cursor(libretrodb_t *db, libretrodb_query_t *q = NULL; if (query) - q = libretrodb_query_compile(db, query, + q = (libretrodb_query_t*)libretrodb_query_compile(db, query, strlen(query), &error); if (error) @@ -118,12 +118,25 @@ int database_info_write_rdl(const char *dir) return 0; } +static char *bin_to_hex_alloc(const uint8_t *data, size_t len) +{ + size_t i; + char *ret=malloc(len*2+1); + + for (i = 0; i < len; i++) + { + snprintf(ret+i*2, 3, "%02X", data[i]); + } + return ret; +} + database_info_list_t *database_info_list_new(const char *rdb_path, const char *query) { libretrodb_t db; libretrodb_cursor_t cur; struct rmsgpack_dom_value item; - size_t i = 0, j; + size_t j; + unsigned k = 0; database_info_t *database_info = NULL; database_info_list_t *database_info_list = NULL; @@ -142,12 +155,15 @@ database_info_list_t *database_info_list_new(const char *rdb_path, const char *q if (item.type != RDT_MAP) continue; - database_info = (database_info_t*)realloc(database_info, (i+1) * sizeof(database_info_t)); + database_info = (database_info_t*)realloc(database_info, (k+1) * sizeof(database_info_t)); if (!database_info) goto error; - db_info = &database_info[i]; + db_info = &database_info[k]; + + if (!db_info) + continue; db_info->name = NULL; db_info->description = NULL; @@ -243,52 +259,17 @@ database_info_list_t *database_info_list_new(const char *rdb_path, const char *q db_info->analog_supported = val->uint_; if (!strcmp(key->string.buff, "crc")) - { - size_t i; - char crc32[PATH_MAX_LENGTH]; - - for (i = 0; i < val->binary.len; i++) - { - char crc32_cat[PATH_MAX_LENGTH]; - snprintf(crc32_cat, sizeof(crc32_cat), "%02X", (unsigned char)val->binary.buff[i]); - strlcat(crc32, crc32_cat, sizeof(crc32)); - } - db_info->crc32 = strdup(crc32); - } - + db_info->crc32 = bin_to_hex_alloc((uint8_t*)val->binary.buff, val->binary.len); if (!strcmp(key->string.buff, "sha1")) - { - size_t i; - char sha1[PATH_MAX_LENGTH]; - - for (i = 0; i < val->binary.len; i++) - { - char sha1_cat[PATH_MAX_LENGTH]; - snprintf(sha1_cat, sizeof(sha1_cat), "%02X", (unsigned char)val->binary.buff[i]); - strlcat(sha1, sha1_cat, sizeof(sha1)); - } - db_info->sha1 = strdup(sha1); - } - + db_info->sha1 = bin_to_hex_alloc((uint8_t*)val->binary.buff, val->binary.len); if (!strcmp(key->string.buff, "md5")) - { - size_t i; - char md5[PATH_MAX_LENGTH]; - - for (i = 0; i < val->binary.len; i++) - { - char md5_cat[PATH_MAX_LENGTH]; - snprintf(md5_cat, sizeof(md5_cat), "%02X", (unsigned char)val->binary.buff[i]); - strlcat(md5, md5_cat, sizeof(md5)); - } - db_info->md5 = strdup(md5); - } + db_info->md5 = bin_to_hex_alloc((uint8_t*)val->binary.buff, val->binary.len); } - i++; + k++; } database_info_list->list = database_info; - database_info_list->count = i; + database_info_list->count = k; return database_info_list; diff --git a/driver.c b/driver.c index 77ca46144e..6e978c4a9f 100644 --- a/driver.c +++ b/driver.c @@ -335,8 +335,8 @@ void init_drivers(int flags) { init_menu(); - if (driver.menu && driver.menu_ctx && driver.menu_ctx->context_reset) - driver.menu_ctx->context_reset(driver.menu); + if (driver.menu_ctx && driver.menu_ctx->context_reset) + driver.menu_ctx->context_reset(); } #endif @@ -371,8 +371,8 @@ void uninit_drivers(int flags) #ifdef HAVE_MENU if (flags & DRIVER_MENU) { - if (driver.menu && driver.menu_ctx && driver.menu_ctx->context_destroy) - driver.menu_ctx->context_destroy(driver.menu); + if (driver.menu_ctx && driver.menu_ctx->context_destroy) + driver.menu_ctx->context_destroy(); if (!driver.menu_data_own) { diff --git a/general.h b/general.h index 8e27757c67..8ccc5937c7 100644 --- a/general.h +++ b/general.h @@ -205,6 +205,7 @@ struct settings bool pause_libretro; bool mouse_enable; bool timedate_enable; + bool core_enable; bool throttle; char wallpaper[PATH_MAX_LENGTH]; diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 23d9665e47..2796957536 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -38,6 +38,7 @@ #include "../gl_common.h" #include "../video_viewport.h" +#include "../video_pixel_converter.h" #include "../video_context_driver.h" #include @@ -87,17 +88,6 @@ static const GLfloat white_color[] = { 1, 1, 1, 1, }; -static inline unsigned get_alignment(unsigned pitch) -{ - if (pitch & 1) - return 1; - if (pitch & 2) - return 2; - if (pitch & 4) - return 4; - return 8; -} - static inline bool gl_query_extension(gl_t *gl, const char *ext) { bool ret = false; @@ -329,27 +319,6 @@ static inline GLenum min_filter_to_mag(GLenum type) } } -static unsigned gl_wrap_type_to_enum(enum gfx_wrap_type type) -{ - switch (type) - { -#ifndef HAVE_OPENGLES - case RARCH_WRAP_BORDER: - return GL_CLAMP_TO_BORDER; -#else - case RARCH_WRAP_BORDER: -#endif - 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; - } - - return 0; -} - #ifdef HAVE_FBO static void gl_shader_scale(gl_t *gl, unsigned idx, struct gfx_fbo_scale *scale) @@ -378,69 +347,72 @@ static void gl_compute_fbo_geometry(gl_t *gl, unsigned width, unsigned height, /* Calculate viewports for FBOs. */ for (i = 0; i < gl->fbo_pass; i++) { + struct gl_fbo_rect *fbo_rect = &gl->fbo_rect[i]; + struct gfx_fbo_scale *fbo_scale = &gl->fbo_scale[i]; + switch (gl->fbo_scale[i].type_x) { case RARCH_SCALE_INPUT: - gl->fbo_rect[i].img_width = last_width * gl->fbo_scale[i].scale_x; - gl->fbo_rect[i].max_img_width = last_max_width * gl->fbo_scale[i].scale_x; + fbo_rect->img_width = last_width * fbo_scale->scale_x; + fbo_rect->max_img_width = last_max_width * fbo_scale->scale_x; break; case RARCH_SCALE_ABSOLUTE: - gl->fbo_rect[i].img_width = gl->fbo_rect[i].max_img_width = gl->fbo_scale[i].abs_x; + fbo_rect->img_width = fbo_rect->max_img_width = fbo_scale->abs_x; break; case RARCH_SCALE_VIEWPORT: - gl->fbo_rect[i].img_width = gl->fbo_rect[i].max_img_width = gl->fbo_scale[i].scale_x * vp_width; + fbo_rect->img_width = fbo_rect->max_img_width = fbo_scale->scale_x * vp_width; break; } - switch (gl->fbo_scale[i].type_y) + switch (fbo_scale->type_y) { case RARCH_SCALE_INPUT: - gl->fbo_rect[i].img_height = last_height * gl->fbo_scale[i].scale_y; - gl->fbo_rect[i].max_img_height = last_max_height * gl->fbo_scale[i].scale_y; + fbo_rect->img_height = last_height * fbo_scale->scale_y; + fbo_rect->max_img_height = last_max_height * fbo_scale->scale_y; break; case RARCH_SCALE_ABSOLUTE: - gl->fbo_rect[i].img_height = gl->fbo_rect[i].max_img_height = gl->fbo_scale[i].abs_y; + fbo_rect->img_height = fbo_rect->max_img_height = fbo_scale->abs_y; break; case RARCH_SCALE_VIEWPORT: - gl->fbo_rect[i].img_height = gl->fbo_rect[i].max_img_height = gl->fbo_scale[i].scale_y * vp_height; + fbo_rect->img_height = fbo_rect->max_img_height = fbo_scale->scale_y * vp_height; break; } - if (gl->fbo_rect[i].img_width > (unsigned)max_size) + if (fbo_rect->img_width > (unsigned)max_size) { size_modified = true; - gl->fbo_rect[i].img_width = max_size; + fbo_rect->img_width = max_size; } - if (gl->fbo_rect[i].img_height > (unsigned)max_size) + if (fbo_rect->img_height > (unsigned)max_size) { size_modified = true; - gl->fbo_rect[i].img_height = max_size; + fbo_rect->img_height = max_size; } - if (gl->fbo_rect[i].max_img_width > (unsigned)max_size) + if (fbo_rect->max_img_width > (unsigned)max_size) { size_modified = true; - gl->fbo_rect[i].max_img_width = max_size; + fbo_rect->max_img_width = max_size; } - if (gl->fbo_rect[i].max_img_height > (unsigned)max_size) + if (fbo_rect->max_img_height > (unsigned)max_size) { size_modified = true; - gl->fbo_rect[i].max_img_height = max_size; + fbo_rect->max_img_height = max_size; } if (size_modified) RARCH_WARN("FBO textures exceeded maximum size of GPU (%ux%u). Resizing to fit.\n", max_size, max_size); - last_width = gl->fbo_rect[i].img_width; - last_height = gl->fbo_rect[i].img_height; - last_max_width = gl->fbo_rect[i].max_img_width; - last_max_height = gl->fbo_rect[i].max_img_height; + last_width = fbo_rect->img_width; + last_height = fbo_rect->img_height; + last_max_width = fbo_rect->max_img_width; + last_max_height = fbo_rect->max_img_height; } } @@ -477,7 +449,7 @@ static void gl_create_fbo_textures(gl_t *gl) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_enum); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_enum); - bool fp_fbo = gl->fbo_scale[i].fp_fbo; + bool fp_fbo = gl->fbo_scale[i].fp_fbo; bool srgb_fbo = gl->fbo_scale[i].srgb_fbo; if (fp_fbo) @@ -922,39 +894,50 @@ static void gl_check_fbo_dimensions(gl_t *gl) /* Check if we have to recreate our FBO textures. */ for (i = 0; i < gl->fbo_pass; i++) { - if (gl->fbo_rect[i].max_img_width > gl->fbo_rect[i].width || - gl->fbo_rect[i].max_img_height > gl->fbo_rect[i].height) - { - /* Check proactively since we might suddently - * get sizes of tex_w width or tex_h height. */ - unsigned img_width = gl->fbo_rect[i].max_img_width; - unsigned img_height = gl->fbo_rect[i].max_img_height; - unsigned max = img_width > img_height ? img_width : img_height; - unsigned pow2_size = next_pow2(max); + GLenum status; + unsigned img_width, img_height, max, pow2_size; + bool check_dimensions = false; + struct gl_fbo_rect *fbo_rect = &gl->fbo_rect[i]; - gl->fbo_rect[i].width = gl->fbo_rect[i].height = pow2_size; + if (!fbo_rect) + continue; - glBindFramebuffer(RARCH_GL_FRAMEBUFFER, gl->fbo[i]); - glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i]); + check_dimensions = + (fbo_rect->max_img_width > fbo_rect->width) || + (fbo_rect->max_img_height > fbo_rect->height); - glTexImage2D(GL_TEXTURE_2D, - 0, RARCH_GL_INTERNAL_FORMAT32, - gl->fbo_rect[i].width, - gl->fbo_rect[i].height, - 0, RARCH_GL_TEXTURE_TYPE32, - RARCH_GL_FORMAT32, NULL); + if (!check_dimensions) + continue; - glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER, - RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - gl->fbo_texture[i], 0); + /* Check proactively since we might suddently + * get sizes of tex_w width or tex_h height. */ + img_width = fbo_rect->max_img_width; + img_height = fbo_rect->max_img_height; + max = img_width > img_height ? img_width : img_height; + pow2_size = next_pow2(max); - GLenum status = glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER); - if (status != RARCH_GL_FRAMEBUFFER_COMPLETE) - RARCH_WARN("Failed to reinitialize FBO texture.\n"); + fbo_rect->width = fbo_rect->height = pow2_size; - RARCH_LOG("[GL]: Recreating FBO texture #%d: %ux%u\n", - i, gl->fbo_rect[i].width, gl->fbo_rect[i].height); - } + glBindFramebuffer(RARCH_GL_FRAMEBUFFER, gl->fbo[i]); + glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i]); + + glTexImage2D(GL_TEXTURE_2D, + 0, RARCH_GL_INTERNAL_FORMAT32, + fbo_rect->width, + fbo_rect->height, + 0, RARCH_GL_TEXTURE_TYPE32, + RARCH_GL_FORMAT32, NULL); + + glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER, + RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + gl->fbo_texture[i], 0); + + status = glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER); + if (status != RARCH_GL_FRAMEBUFFER_COMPLETE) + RARCH_WARN("Failed to reinitialize FBO texture.\n"); + + RARCH_LOG("[GL]: Recreating FBO texture #%d: %ux%u\n", + i, fbo_rect->width, fbo_rect->height); } } @@ -986,11 +969,11 @@ static void gl_frame_fbo(gl_t *gl, set_texture_coords(fbo_tex_coords, xamt, yamt); - fbo_info->tex = gl->fbo_texture[i - 1]; + fbo_info->tex = gl->fbo_texture[i - 1]; fbo_info->input_size[0] = prev_rect->img_width; fbo_info->input_size[1] = prev_rect->img_height; - fbo_info->tex_size[0] = prev_rect->width; - fbo_info->tex_size[1] = prev_rect->height; + fbo_info->tex_size[0] = prev_rect->width; + fbo_info->tex_size[1] = prev_rect->height; memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords)); fbo_tex_info_cnt++; @@ -1024,18 +1007,19 @@ static void gl_frame_fbo(gl_t *gl, /* Render our last FBO texture directly to screen. */ prev_rect = &gl->fbo_rect[gl->fbo_pass - 1]; - xamt = (GLfloat)prev_rect->img_width / prev_rect->width; - yamt = (GLfloat)prev_rect->img_height / prev_rect->height; + xamt = (GLfloat)prev_rect->img_width / prev_rect->width; + yamt = (GLfloat)prev_rect->img_height / prev_rect->height; set_texture_coords(fbo_tex_coords, xamt, yamt); /* Push final FBO to list. */ fbo_info = &fbo_tex_info[gl->fbo_pass - 1]; - fbo_info->tex = gl->fbo_texture[gl->fbo_pass - 1]; + + fbo_info->tex = gl->fbo_texture[gl->fbo_pass - 1]; fbo_info->input_size[0] = prev_rect->img_width; fbo_info->input_size[1] = prev_rect->img_height; - fbo_info->tex_size[0] = prev_rect->width; - fbo_info->tex_size[1] = prev_rect->height; + fbo_info->tex_size[0] = prev_rect->width; + fbo_info->tex_size[1] = prev_rect->height; memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords)); fbo_tex_info_cnt++; @@ -1051,7 +1035,8 @@ static void gl_frame_fbo(gl_t *gl, glClear(GL_COLOR_BUFFER_BIT); gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); - gl->shader->set_params(gl, prev_rect->img_width, prev_rect->img_height, + gl->shader->set_params(gl, + prev_rect->img_width, prev_rect->img_height, prev_rect->width, prev_rect->height, gl->vp.width, gl->vp.height, g_extern.frame_count, tex_info, gl->prev_info, fbo_tex_info, fbo_tex_info_cnt); @@ -1070,6 +1055,7 @@ static void gl_frame_fbo(gl_t *gl, static void gl_update_input_size(gl_t *gl, unsigned width, unsigned height, unsigned pitch, bool clear) { + GLfloat xamt, yamt; bool set_coords = false; @@ -1084,7 +1070,7 @@ static void gl_update_input_size(gl_t *gl, unsigned width, if (clear) { glPixelStorei(GL_UNPACK_ALIGNMENT, - get_alignment(width * sizeof(uint32_t))); + video_pixel_get_alignment(width * sizeof(uint32_t))); #if defined(HAVE_PSGL) glBufferSubData(GL_TEXTURE_REFERENCE_BUFFER_SCE, gl->tex_w * gl->tex_h * gl->tex_index * gl->base_size, @@ -1100,21 +1086,21 @@ static void gl_update_input_size(gl_t *gl, unsigned width, set_coords = true; } else if ((width != - gl->last_width[(gl->tex_index + gl->textures - 1) % gl->textures]) || + gl->last_width[(gl->tex_index + gl->textures - 1) % gl->textures]) || (height != - gl->last_height[(gl->tex_index + gl->textures - 1) % gl->textures])) + gl->last_height[(gl->tex_index + gl->textures - 1) % gl->textures])) { /* We might have used different texture coordinates * last frame. Edge case if resolution changes very rapidly. */ set_coords = true; } - if (set_coords) - { - GLfloat xamt = (GLfloat)width / gl->tex_w; - GLfloat yamt = (GLfloat)height / gl->tex_h; - set_texture_coords(gl->tex_info.coord, xamt, yamt); - } + if (!set_coords) + return; + + xamt = (GLfloat)width / gl->tex_w; + yamt = (GLfloat)height / gl->tex_h; + set_texture_coords(gl->tex_info.coord, xamt, yamt); } /* It is *much* faster (order of magnitude on my setup) @@ -1276,7 +1262,7 @@ static inline void gl_copy_frame(gl_t *gl, const void *frame, if (gl->egl_images) { EGLImageKHR img = 0; - bool new_egl = gl->ctx_driver->write_egl_image(gl, + bool new_egl = gl->ctx_driver->write_egl_image(gl, frame, width, height, pitch, (gl->base_size == 4), gl->tex_index, &img); @@ -1292,7 +1278,7 @@ static inline void gl_copy_frame(gl_t *gl, const void *frame, else #endif { - glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(width * gl->base_size)); + glPixelStorei(GL_UNPACK_ALIGNMENT, video_pixel_get_alignment(width * gl->base_size)); /* Fallback for GLES devices without GL_BGRA_EXT. */ if (gl->base_size == 4 && driver.gfx_use_rgba) @@ -1317,7 +1303,7 @@ static inline void gl_copy_frame(gl_t *gl, const void *frame, /* No GL_UNPACK_ROW_LENGTH. */ const GLvoid *data_buf = frame; - unsigned pitch_width = pitch / gl->base_size; + unsigned pitch_width = pitch / gl->base_size; if (width != pitch_width) { @@ -1326,13 +1312,13 @@ static inline void gl_copy_frame(gl_t *gl, const void *frame, unsigned h; const unsigned line_bytes = width * gl->base_size; - uint8_t *dst = (uint8_t*)gl->conv_buffer; - const uint8_t *src = (const uint8_t*)frame; + uint8_t *dst = (uint8_t*)gl->conv_buffer; + const uint8_t *src = (const uint8_t*)frame; for (h = 0; h < height; h++, src += pitch, dst += line_bytes) memcpy(dst, src, line_bytes); - data_buf = gl->conv_buffer; + data_buf = gl->conv_buffer; } glTexSubImage2D(GL_TEXTURE_2D, @@ -1355,7 +1341,7 @@ static inline void gl_copy_frame(gl_t *gl, const void *frame, glUnmapBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE); #else const GLvoid *data_buf = frame; - glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(pitch)); + glPixelStorei(GL_UNPACK_ALIGNMENT, video_pixel_get_alignment(pitch)); if (gl->base_size == 2 && !gl->have_es2_compat) { @@ -1403,7 +1389,7 @@ static void gl_pbo_async_readback(gl_t *gl) glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_ALIGNMENT, - get_alignment(gl->vp.width * sizeof(uint32_t))); + video_pixel_get_alignment(gl->vp.width * sizeof(uint32_t))); /* Read asynchronously into PBO buffer. */ RARCH_PERFORMANCE_INIT(async_readback); @@ -1436,13 +1422,13 @@ static inline void gl_draw_texture(gl_t *gl) if (!gl->menu_texture) return; - gl->coords.vertex = vertexes_flipped; + gl->coords.vertex = vertexes_flipped; gl->coords.tex_coord = tex_coords; - gl->coords.color = color; + gl->coords.color = color; glBindTexture(GL_TEXTURE_2D, gl->menu_texture); gl->shader->use(gl, GL_SHADER_STOCK_BLEND); - gl->coords.vertices = 4; + gl->coords.vertices = 4; gl->shader->set_coords(&gl->coords); gl->shader->set_mvp(gl, &gl->mvp_no_rot); @@ -1459,9 +1445,9 @@ static inline void gl_draw_texture(gl_t *gl) glDisable(GL_BLEND); - gl->coords.vertex = gl->vertex_ptr; + gl->coords.vertex = gl->vertex_ptr; gl->coords.tex_coord = gl->tex_info.coord; - gl->coords.color = gl->white_color_ptr; + gl->coords.color = gl->white_color_ptr; } #endif @@ -1727,6 +1713,7 @@ static void gl_free(void *data) if (gl->have_sync) { unsigned i; + for (i = 0; i < gl->fence_count; i++) { glClientWaitSync(gl->fences[i], @@ -1811,9 +1798,12 @@ static void gl_set_nonblock_state(void *data, bool state) static bool resolve_extensions(gl_t *gl) { #ifndef HAVE_OPENGLES - gl->core_context = + const char *vendor = NULL; + const char *renderer = NULL; + gl->core_context = (g_extern.system.hw_render_callback.context_type == RETRO_HW_CONTEXT_OPENGL_CORE); + if (gl->core_context) { RARCH_LOG("[GL]: Using Core GL context.\n"); @@ -1831,8 +1821,9 @@ static bool resolve_extensions(gl_t *gl) * The speed gain from using GL_RGB565 is worth * adding some workarounds for. */ - const char *vendor = (const char*)glGetString(GL_VENDOR); - const char *renderer = (const char*)glGetString(GL_RENDERER); + vendor = (const char*)glGetString(GL_VENDOR); + renderer = (const char*)glGetString(GL_RENDERER); + if (vendor && renderer && (strstr(vendor, "ATI") || strstr(renderer, "ATI"))) RARCH_LOG("[GL]: ATI card detected, skipping check for GL_RGB565 support.\n"); else @@ -1847,6 +1838,10 @@ static bool resolve_extensions(gl_t *gl) driver.gfx_use_rgba = false; #ifdef HAVE_OPENGLES2 + const char *version = NULL; + bool gles3 = false; + unsigned gles_major = 0, gles_minor = 0; + /* There are both APPLE and EXT variants. */ if (gl_query_extension(gl, "BGRA8888")) RARCH_LOG("[GL]: BGRA8888 extension found for GLES.\n"); @@ -1857,9 +1852,9 @@ static bool resolve_extensions(gl_t *gl) "32-bit path will require conversion.\n"); } - bool gles3 = false; - const char *version = (const char*)glGetString(GL_VERSION); - unsigned gles_major = 0, gles_minor = 0; + + version = (const char*)glGetString(GL_VERSION); + /* This format is mandated by GLES. */ if (version && sscanf(version, "OpenGL ES %u.%u", &gles_major, &gles_minor) == 2 && gles_major >= 3) @@ -1918,6 +1913,7 @@ static bool resolve_extensions(gl_t *gl) else { const char *ext = (const char*)glGetString(GL_EXTENSIONS); + if (ext) { size_t i; @@ -1935,19 +1931,26 @@ static bool resolve_extensions(gl_t *gl) static inline void gl_set_texture_fmts(gl_t *gl, bool rgb32) { - gl->internal_fmt = rgb32 ? RARCH_GL_INTERNAL_FORMAT32 : RARCH_GL_INTERNAL_FORMAT16; - gl->texture_type = rgb32 ? RARCH_GL_TEXTURE_TYPE32 : RARCH_GL_TEXTURE_TYPE16; - gl->texture_fmt = rgb32 ? RARCH_GL_FORMAT32 : RARCH_GL_FORMAT16; - gl->base_size = rgb32 ? sizeof(uint32_t) : sizeof(uint16_t); + gl->internal_fmt = RARCH_GL_INTERNAL_FORMAT16; + gl->texture_type = RARCH_GL_TEXTURE_TYPE16; + gl->texture_fmt = RARCH_GL_FORMAT16; + gl->base_size = sizeof(uint16_t); - if (driver.gfx_use_rgba && rgb32) + if (rgb32) { - gl->internal_fmt = GL_RGBA; - gl->texture_type = GL_RGBA; - } + gl->internal_fmt = RARCH_GL_INTERNAL_FORMAT32; + gl->texture_type = RARCH_GL_TEXTURE_TYPE32; + gl->texture_fmt = RARCH_GL_FORMAT32; + gl->base_size = sizeof(uint32_t); + if (driver.gfx_use_rgba) + { + gl->internal_fmt = GL_RGBA; + gl->texture_type = GL_RGBA; + } + } #ifndef HAVE_OPENGLES - if (!rgb32 && gl->have_es2_compat) + else if (gl->have_es2_compat) { RARCH_LOG("[GL]: Using GL_RGB565 for texture uploads.\n"); gl->internal_fmt = RARCH_GL_INTERNAL_FORMAT16_565; @@ -2271,15 +2274,14 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo gl->full_y = gl->win_height; } - hw_render = &g_extern.system.hw_render_callback; - - gl->vertex_ptr = hw_render->bottom_left_origin ? vertexes : vertexes_flipped; + hw_render = &g_extern.system.hw_render_callback; + gl->vertex_ptr = hw_render->bottom_left_origin ? vertexes : vertexes_flipped; /* Better pipelining with GPU due to synchronous glSubTexImage. * Multiple async PBOs would be an alternative, * but still need multiple textures with PREV. */ - gl->textures = 4; + gl->textures = 4; #ifdef HAVE_FBO gl->hw_render_use = hw_render->context_type != RETRO_HW_CONTEXT_NONE; @@ -2303,7 +2305,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo hw_render->version_major, hw_render->version_minor); #endif - gl->shader = (const shader_backend_t*)shader_ctx_init_first(); + gl->shader = (const shader_backend_t*)shader_ctx_init_first(); if (gl->shader) { @@ -2322,23 +2324,21 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo if (gl->shader) { unsigned minimum = gl->shader->get_prev_textures(); - gl->textures = max(minimum + 1, gl->textures); + gl->textures = max(minimum + 1, gl->textures); } RARCH_LOG("[GL]: Using %u textures.\n", gl->textures); RARCH_LOG("[GL]: Loaded %u program(s).\n", gl->shader->num_shaders()); - gl->tex_w = RARCH_SCALE_BASE * video->input_scale; - gl->tex_h = RARCH_SCALE_BASE * video->input_scale; - - gl->keep_aspect = video->force_aspect; + gl->tex_w = gl->tex_h = (RARCH_SCALE_BASE * video->input_scale); + gl->keep_aspect = video->force_aspect; /* Apparently need to set viewport for passes * when we aren't using FBOs. */ gl_set_shader_viewport(gl, 0); gl_set_shader_viewport(gl, 1); - gl->tex_mipmap = gl->shader->mipmap_input(1); + gl->tex_mipmap = gl->shader->mipmap_input(1); if (gl->shader->filter_type(1, &force_smooth)) gl->tex_min_filter = gl->tex_mipmap ? (force_smooth ? @@ -2350,7 +2350,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo : (video->smooth ? GL_LINEAR : GL_NEAREST); gl->tex_mag_filter = min_filter_to_mag(gl->tex_min_filter); - gl->wrap_mode = gl_wrap_type_to_enum(gl->shader->wrap_type(1)); + gl->wrap_mode = gl_wrap_type_to_enum(gl->shader->wrap_type(1)); gl_set_texture_fmts(gl, video->rgb32); @@ -2372,10 +2372,10 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo /* Empty buffer that we use to clear out * the texture with on res change. */ - gl->empty_buf = calloc(sizeof(uint32_t), gl->tex_w * gl->tex_h); + gl->empty_buf = calloc(sizeof(uint32_t), gl->tex_w * gl->tex_h); #if !defined(HAVE_PSGL) - gl->conv_buffer = calloc(sizeof(uint32_t), gl->tex_w * gl->tex_h); + gl->conv_buffer = calloc(sizeof(uint32_t), gl->tex_w * gl->tex_h); if (!gl->conv_buffer) { @@ -2486,23 +2486,25 @@ static void gl_update_tex_filter_frame(gl_t *gl) return; context_bind_hw_render(gl, false); + if (!gl->shader->filter_type(1, &smooth)) smooth = g_settings.video.smooth; - wrap_mode = gl_wrap_type_to_enum(gl->shader->wrap_type(1)); - gl->tex_mipmap = gl->shader->mipmap_input(1); + wrap_mode = gl_wrap_type_to_enum(gl->shader->wrap_type(1)); + gl->tex_mipmap = gl->shader->mipmap_input(1); gl->video_info.smooth = smooth; new_filt = gl->tex_mipmap ? (smooth ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST) : (smooth ? GL_LINEAR : GL_NEAREST); + if (new_filt == gl->tex_min_filter && wrap_mode == gl->wrap_mode) return; - gl->tex_min_filter = new_filt; - gl->tex_mag_filter = min_filter_to_mag(gl->tex_min_filter); + gl->tex_min_filter = new_filt; + gl->tex_mag_filter = min_filter_to_mag(gl->tex_min_filter); + gl->wrap_mode = wrap_mode; - gl->wrap_mode = wrap_mode; for (i = 0; i < gl->textures; i++) { if (!gl->texture[i]) @@ -2567,8 +2569,11 @@ static bool gl_set_shader(void *data, if (!gl->shader->init(gl, path)) { + bool ret = false; + RARCH_WARN("[GL]: Failed to set multipass shader. Falling back to stock.\n"); - bool ret = gl->shader->init(gl, NULL); + ret = gl->shader->init(gl, NULL); + if (!ret) gl->shader = NULL; context_bind_hw_render(gl, true); @@ -2622,16 +2627,15 @@ static bool gl_set_shader(void *data, static void gl_viewport_info(void *data, struct rarch_viewport *vp) { unsigned top_y, top_dist; - gl_t *gl = (gl_t*)data; - - *vp = gl->vp; + gl_t *gl = (gl_t*)data; + *vp = gl->vp; vp->full_width = gl->win_width; vp->full_height = gl->win_height; /* Adjust as GL viewport is bottom-up. */ - top_y = vp->y + vp->height; - top_dist = gl->win_height - top_y; - vp->y = top_dist; + top_y = vp->y + vp->height; + top_dist = gl->win_height - top_y; + vp->y = top_dist; } #ifdef NO_GL_READ_PIXELS @@ -2772,6 +2776,7 @@ static bool gl_overlay_load(void *data, gl_free_overlay(gl); gl->overlay_tex = (GLuint*)calloc(num_images, sizeof(*gl->overlay_tex)); + if (!gl->overlay_tex) { context_bind_hw_render(gl, true); @@ -2781,28 +2786,23 @@ static bool gl_overlay_load(void *data, 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; + gl->overlays = num_images; glGenTextures(num_images, gl->overlay_tex); for (i = 0; i < num_images; i++) { - glBindTexture(GL_TEXTURE_2D, gl->overlay_tex[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + unsigned alignment = video_pixel_get_alignment(images[i].width + * sizeof(uint32_t)); - glPixelStorei(GL_UNPACK_ALIGNMENT, - get_alignment(images[i].width * sizeof(uint32_t))); - - glTexImage2D(GL_TEXTURE_2D, 0, driver.gfx_use_rgba ? - GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, - images[i].width, images[i].height, 0, - driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, - RARCH_GL_FORMAT32, images[i].pixels); + gl_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. */ gl_overlay_tex_geom(gl, i, 0, 0, 1, 1); @@ -2822,20 +2822,24 @@ static void gl_overlay_tex_geom(void *data, GLfloat w, GLfloat h) { GLfloat *tex = NULL; - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; if (!gl) return; - tex = (GLfloat*)&gl->overlay_tex_coord[image * 8]; + tex = (GLfloat*)&gl->overlay_tex_coord[image * 8]; if (!tex) return; - 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; + 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 gl_overlay_vertex_geom(void *data, @@ -2844,34 +2848,39 @@ static void gl_overlay_vertex_geom(void *data, float w, float h) { GLfloat *vertex = NULL; - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; if (!gl) return; - vertex = (GLfloat*)&gl->overlay_vertex_coord[image * 8]; + vertex = (GLfloat*)&gl->overlay_vertex_coord[image * 8]; /* Flipped, so we preserve top-down semantics. */ - y = 1.0f - y; - h = -h; + y = 1.0f - y; + h = -h; if (!vertex) return; - 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; + 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 gl_overlay_enable(void *data, bool state) { - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; if (!gl) return; gl->overlay_enable = state; + if (gl->ctx_driver->show_mouse && gl->fullscreen) gl->ctx_driver->show_mouse(gl, state); } @@ -2887,19 +2896,19 @@ static void gl_overlay_full_screen(void *data, bool enable) static void gl_overlay_set_alpha(void *data, unsigned image, float mod) { GLfloat *color = NULL; - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; if (!gl) return; - color = (GLfloat*)&gl->overlay_color_coord[image * 16]; + color = (GLfloat*)&gl->overlay_color_coord[image * 16]; if (!color) return; - color[ 0 + 3] = mod; - color[ 4 + 3] = mod; - color[ 8 + 3] = mod; - color[12 + 3] = mod; + color[ 0 + 3] = mod; + color[ 4 + 3] = mod; + color[ 8 + 3] = mod; + color[12 + 3] = mod; } static void gl_render_overlay(void *data) @@ -3008,7 +3017,7 @@ static void gl_set_texture_frame(void *data, const void *frame, bool rgb32, unsigned width, unsigned height, float alpha) { - unsigned base_size; + unsigned base_size = rgb32 ? sizeof(uint32_t) : sizeof(uint16_t); gl_t *gl = (gl_t*)data; if (!gl) return; @@ -3016,49 +3025,29 @@ static void gl_set_texture_frame(void *data, context_bind_hw_render(gl, false); if (!gl->menu_texture) - { glGenTextures(1, &gl->menu_texture); - glBindTexture(GL_TEXTURE_2D, gl->menu_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - else - glBindTexture(GL_TEXTURE_2D, gl->menu_texture); + + + gl_load_texture_data(gl->menu_texture, + RARCH_WRAP_EDGE, TEXTURE_FILTER_LINEAR, + video_pixel_get_alignment(width * base_size), + width, height, frame, + base_size); gl->menu_texture_alpha = alpha; - - base_size = rgb32 ? sizeof(uint32_t) : sizeof(uint16_t); - glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(width * base_size)); - - if (rgb32) - { - glTexImage2D(GL_TEXTURE_2D, - 0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, - width, height, - 0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, - RARCH_GL_FORMAT32, frame); - } - else - { - glTexImage2D(GL_TEXTURE_2D, - 0, GL_RGBA, width, height, 0, GL_RGBA, - GL_UNSIGNED_SHORT_4_4_4_4, frame); - } - glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); + context_bind_hw_render(gl, true); } static void gl_set_texture_enable(void *data, bool state, bool full_screen) { - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; if (!gl) return; - gl->menu_texture_enable = state; + gl->menu_texture_enable = state; gl->menu_texture_full_screen = full_screen; } #endif diff --git a/gfx/drivers/gx_gfx.c b/gfx/drivers/gx_gfx.c index 9bb1b66bda..8006e69dc9 100644 --- a/gfx/drivers/gx_gfx.c +++ b/gfx/drivers/gx_gfx.c @@ -18,7 +18,7 @@ #include "../../driver.h" #include "../../general.h" #include "../drivers_font_renderer/bitmap.h" -#include "../../menu/menu.h" +#include "../../menu/menu_driver.h" #include "../video_viewport.h" #include "../video_monitor.h" @@ -118,6 +118,7 @@ void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines) max_width, max_height, i; bool progressive; gx_video_t *gx = (gx_video_t*)data; + menu_handle_t *menu = menu_driver_resolve(); (void)level; @@ -277,17 +278,17 @@ void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines) gx_mode.efbHeight, (gx_mode.viTVMode & 3) == VI_INTERLACE ? "interlaced" : "progressive"); - if (driver.menu) + if (menu) { - driver.menu->height = gx_mode.efbHeight / (gx->double_strike ? 1 : 2); - driver.menu->height &= ~3; - if (driver.menu->height > 240) - driver.menu->height = 240; + menu->frame_buf.height = gx_mode.efbHeight / (gx->double_strike ? 1 : 2); + menu->frame_buf.height &= ~3; + if (menu->frame_buf.height > 240) + menu->frame_buf.height = 240; - driver.menu->width = gx_mode.fbWidth / (gx_mode.fbWidth < 400 ? 1 : 2); - driver.menu->width &= ~3; - if (driver.menu->width > 400) - driver.menu->width = 400; + menu->frame_buf.width = gx_mode.fbWidth / (gx_mode.fbWidth < 400 ? 1 : 2); + menu->frame_buf.width &= ~3; + if (menu->frame_buf.width > 400) + menu->frame_buf.width = 400; } if (tvmode == VI_PAL) @@ -357,6 +358,7 @@ static void init_texture(void *data, unsigned width, unsigned height) gx_video_t *gx = (gx_video_t*)data; struct __gx_texobj *fb_ptr = (struct __gx_texobj*)&g_tex.obj; struct __gx_texobj *menu_ptr = (struct __gx_texobj*)&menu_tex.obj; + menu_handle_t *menu = menu_driver_resolve(); width &= ~3; height &= ~3; @@ -364,10 +366,10 @@ static void init_texture(void *data, unsigned width, unsigned height) menu_w = 320; menu_h = 240; - if (driver.menu) + if (menu) { - menu_w = driver.menu->width; - menu_h = driver.menu->height; + menu_w = menu->frame_buf.width; + menu_h = menu->frame_buf.height; } __GX_InitTexObj(fb_ptr, g_tex.data, width, height, @@ -960,10 +962,18 @@ static bool gx_frame(void *data, const void *frame, if (gx->menu_texture_enable && gx->menu_data) { - convert_texture16(gx->menu_data, menu_tex.data, - driver.menu->width, driver.menu->height, driver.menu->width * 2); - DCFlushRange(menu_tex.data, - driver.menu->width * driver.menu->height * 2); + menu_handle_t *menu = menu_driver_resolve(); + + if (menu) + { + convert_texture16(gx->menu_data, menu_tex.data, + menu->frame_buf.width, + menu->frame_buf.height, + menu->frame_buf.width * 2); + DCFlushRange(menu_tex.data, + menu->frame_buf.width * + menu->frame_buf.height * 2); + } } __GX_InvalidateTexAll(__gx); diff --git a/gfx/gl_common.c b/gfx/gl_common.c index 9dfbe2aa7d..888fb3d322 100644 --- a/gfx/gl_common.c +++ b/gfx/gl_common.c @@ -16,67 +16,111 @@ #include "gl_common.h" -void gl_load_texture_data(GLuint obj, const struct texture_image *img, - GLenum wrap, bool linear, bool mipmap) +void gl_load_texture_data(GLuint id, + enum gfx_wrap_type wrap_type, + enum texture_filter_type filter_type, + unsigned alignment, + unsigned width, unsigned height, + const void *frame, unsigned base_size) { - glBindTexture(GL_TEXTURE_2D, obj); + GLint mag_filter, min_filter; + GLenum wrap; + bool want_mipmap = false; + bool rgb32 = (base_size == (sizeof(uint32_t))); + + glBindTexture(GL_TEXTURE_2D, id); + + wrap = gl_wrap_type_to_enum(wrap_type); -#ifdef HAVE_PSGL - mipmap = false; -#endif glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); - GLint mag_filter = linear ? GL_LINEAR : GL_NEAREST; - GLint min_filter = linear ? (mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) : - (mipmap ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST); + switch (filter_type) + { + case TEXTURE_FILTER_MIPMAP_LINEAR: + min_filter = GL_LINEAR_MIPMAP_LINEAR; + mag_filter = GL_LINEAR; +#ifndef HAVE_PSGL + want_mipmap = true; +#endif + break; + case TEXTURE_FILTER_MIPMAP_NEAREST: + min_filter = GL_NEAREST_MIPMAP_NEAREST; + mag_filter = GL_NEAREST; +#ifndef HAVE_PSGL + want_mipmap = true; +#endif + break; + case TEXTURE_FILTER_NEAREST: + min_filter = GL_NEAREST; + mag_filter = GL_NEAREST; + break; + case TEXTURE_FILTER_LINEAR: + default: + min_filter = GL_LINEAR; + mag_filter = GL_LINEAR; + break; + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); #ifndef HAVE_PSGL - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); #endif glTexImage2D(GL_TEXTURE_2D, - 0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, - img->width, img->height, - 0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, - RARCH_GL_FORMAT32, img->pixels); -#ifndef HAVE_PSGL - if (mipmap) + 0, + (driver.gfx_use_rgba || !rgb32) ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, + width, height, 0, + (driver.gfx_use_rgba || !rgb32) ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, + (rgb32) ? RARCH_GL_FORMAT32 : GL_UNSIGNED_SHORT_4_4_4_4, frame); + + if (want_mipmap) glGenerateMipmap(GL_TEXTURE_2D); -#endif } -bool gl_load_luts(const struct video_shader *generic_shader, +bool gl_load_luts(const struct video_shader *shader, GLuint *textures_lut) { unsigned i; - unsigned num_luts = min(generic_shader->luts, GFX_MAX_TEXTURES); + unsigned num_luts = min(shader->luts, GFX_MAX_TEXTURES); - if (!generic_shader->luts) + if (!shader->luts) return true; - /* Original shader_glsl.c code only generated one - * texture handle. I assume it was a bug, but if not, - * replace num_luts with 1 when GLSL is used. */ glGenTextures(num_luts, textures_lut); + for (i = 0; i < num_luts; i++) { struct texture_image img = {0}; - RARCH_LOG("Loading texture image from: \"%s\" ...\n", - generic_shader->lut[i].path); + enum texture_filter_type filter_type = TEXTURE_FILTER_LINEAR; - if (!texture_image_load(&img, generic_shader->lut[i].path)) + RARCH_LOG("Loading texture image from: \"%s\" ...\n", + shader->lut[i].path); + + if (!texture_image_load(&img, shader->lut[i].path)) { RARCH_ERR("Failed to load texture image from: \"%s\"\n", - generic_shader->lut[i].path); + shader->lut[i].path); return false; } - gl_load_texture_data(textures_lut[i], &img, - driver.video->wrap_type_to_enum(generic_shader->lut[i].wrap), - generic_shader->lut[i].filter != RARCH_FILTER_NEAREST, - generic_shader->lut[i].mipmap); + if (shader->lut[i].filter == RARCH_FILTER_NEAREST) + filter_type = TEXTURE_FILTER_NEAREST; + + if (shader->lut[i].mipmap) + { + if (filter_type == TEXTURE_FILTER_NEAREST) + filter_type = TEXTURE_FILTER_MIPMAP_NEAREST; + else + filter_type = TEXTURE_FILTER_MIPMAP_LINEAR; + } + + gl_load_texture_data(textures_lut[i], + shader->lut[i].wrap, + filter_type, 4, + img.width, img.height, + img.pixels, sizeof(uint32_t)); texture_image_free(&img); } diff --git a/gfx/gl_common.h b/gfx/gl_common.h index dd589d9f5b..221c291f7c 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -403,10 +403,36 @@ static inline bool gl_check_error(void) void gl_set_viewport(gl_t *gl, unsigned width, unsigned height, bool force_full, bool allow_rotate); -void gl_load_texture_data(GLuint obj, const struct texture_image *img, - GLenum wrap, bool linear, bool mipmap); +void gl_load_texture_data(GLuint id, + enum gfx_wrap_type wrap_type, + enum texture_filter_type filter_type, + unsigned alignment, + unsigned width, unsigned height, + const void *frame, + unsigned base_size); bool gl_load_luts(const struct video_shader *generic_shader, GLuint *lut_textures); +static INLINE unsigned gl_wrap_type_to_enum(enum gfx_wrap_type type) +{ + switch (type) + { +#ifndef HAVE_OPENGLES + case RARCH_WRAP_BORDER: + return GL_CLAMP_TO_BORDER; +#else + case RARCH_WRAP_BORDER: +#endif + 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; + } + + return 0; +} + #endif diff --git a/gfx/image/image_rpng.c b/gfx/image/image_rpng.c index 6ec68cdc81..e548d82de2 100644 --- a/gfx/image/image_rpng.c +++ b/gfx/image/image_rpng.c @@ -25,33 +25,22 @@ #include #include #include "../../general.h" -#include "../rpng/rpng.h" +#include -static bool rpng_image_load_tga_shift(const char *path, +static bool rtga_image_load_shift(uint8_t *buf, struct texture_image *out_img, unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift) { unsigned i, bits, size, bits_mul; - uint8_t info[6], *buf; + uint8_t info[6]; unsigned width = 0; unsigned height = 0; const uint8_t *tmp = NULL; - void *raw_buf = NULL; - ssize_t len = read_file(path, &raw_buf); - - if (len < 0) - { - RARCH_ERR("Failed to read image: %s.\n", path); - return false; - } - - buf = (uint8_t*)raw_buf; if (buf[2] != 2) { RARCH_ERR("TGA image is not uncompressed RGB.\n"); - free(buf); return false; } @@ -71,7 +60,6 @@ static bool rpng_image_load_tga_shift(const char *path, if (!out_img->pixels) { RARCH_ERR("Failed to allocate TGA pixels.\n"); - free(buf); return false; } @@ -81,7 +69,6 @@ static bool rpng_image_load_tga_shift(const char *path, if (bits != 32 && bits != 24) { RARCH_ERR("Bit depth of TGA image is wrong. Only 32-bit and 24-bit supported.\n"); - free(buf); free(out_img->pixels); out_img->pixels = NULL; return false; @@ -104,7 +91,6 @@ static bool rpng_image_load_tga_shift(const char *path, (r << r_shift) | (g << g_shift) | (b << b_shift); } - free(buf); return true; } @@ -225,12 +211,31 @@ bool texture_image_load(struct texture_image *out_img, const char *path) unsigned b_shift = use_rgba ? 16 : 0; if (strstr(path, ".tga")) - ret = rpng_image_load_tga_shift(path, out_img, + { + void *raw_buf = NULL; + uint8_t *buf = NULL; + ssize_t len = read_file(path, &raw_buf); + + if (len < 0) + { + RARCH_ERR("Failed to read image: %s.\n", path); + return false; + } + + buf = (uint8_t*)raw_buf; + + ret = rtga_image_load_shift(buf, out_img, a_shift, r_shift, g_shift, b_shift); + + if (buf) + free(buf); + } #ifdef HAVE_ZLIB else if (strstr(path, ".png")) + { ret = rpng_image_load_argb_shift(path, out_img, a_shift, r_shift, g_shift, b_shift); + } #endif #ifdef GEKKO diff --git a/gfx/video_driver.h b/gfx/video_driver.h index dfacbc979c..bde75854ce 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -74,6 +74,13 @@ struct font_params bool align_right; }; +enum texture_filter_type +{ + TEXTURE_FILTER_LINEAR = 0, + TEXTURE_FILTER_NEAREST, + TEXTURE_FILTER_MIPMAP_LINEAR, + TEXTURE_FILTER_MIPMAP_NEAREST, +}; #define FONT_COLOR_RGBA(r, g, b, a) (((r) << 0) | ((g) << 8) | ((b) << 16) | ((a) << 24)) #define FONT_COLOR_GET_RED(col) (((col) >> 0) & 0xff) diff --git a/gfx/video_pixel_converter.c b/gfx/video_pixel_converter.c index 9a0bab90b8..6e2f979c4b 100644 --- a/gfx/video_pixel_converter.c +++ b/gfx/video_pixel_converter.c @@ -52,3 +52,14 @@ bool init_video_pixel_converter(unsigned size) return true; } + +unsigned video_pixel_get_alignment(unsigned pitch) +{ + if (pitch & 1) + return 1; + if (pitch & 2) + return 2; + if (pitch & 4) + return 4; + return 8; +} diff --git a/gfx/video_pixel_converter.h b/gfx/video_pixel_converter.h index d6a8d22f16..f08abed0c4 100644 --- a/gfx/video_pixel_converter.h +++ b/gfx/video_pixel_converter.h @@ -27,6 +27,8 @@ void deinit_pixel_converter(void); bool init_video_pixel_converter(unsigned size); +unsigned video_pixel_get_alignment(unsigned pitch); + #ifdef __cplusplus } #endif diff --git a/griffin/griffin.c b/griffin/griffin.c index 7b912efb03..5ce297ed66 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -180,7 +180,7 @@ VIDEO IMAGE #include "../gfx/image/image_rpng.c" #endif -#include "../gfx/rpng/rpng.c" +#include "../libretro-sdk/formats/png/rpng.c" /*============================================================ VIDEO DRIVER @@ -686,6 +686,7 @@ MENU #include "../menu/menu_entries.c" #include "../menu/menu_entries_cbs.c" #include "../menu/menu_shader.c" +#include "../menu/menu_texture.c" #include "../menu/menu_navigation.c" #include "../menu/menu_animation.c" #include "../menu/menu_database.c" @@ -778,7 +779,7 @@ XML #if 0 #ifndef HAVE_LIBXML2 #define RXML_LIBXML2_COMPAT -#include "../compat/rxml/rxml.c" +#include "../libretro-sdk/formats/xml/rxml.c" #endif #endif diff --git a/input/drivers/apple_input.c b/input/drivers/apple_input.c index 7e234118b6..e0c47d078d 100644 --- a/input/drivers/apple_input.c +++ b/input/drivers/apple_input.c @@ -247,14 +247,13 @@ static void apple_input_poll(void *data) return; for (i = 0; i < apple->touch_count; i++) - { - input_translate_coord_viewport(apple->touches[i].screen_x, - apple->touches[i].screen_y, - &apple->touches[i].fixed_x, - &apple->touches[i].fixed_y, - &apple->touches[i].full_x, - &apple->touches[i].full_y); - } + input_translate_coord_viewport( + apple->touches[i].screen_x, + apple->touches[i].screen_y, + &apple->touches[i].fixed_x, + &apple->touches[i].fixed_y, + &apple->touches[i].full_x, + &apple->touches[i].full_y); if (apple->joypad) apple->joypad->poll(); @@ -293,8 +292,14 @@ static int16_t apple_pointer_state(apple_input_data_t *apple, { const apple_touch_data_t *touch = (const apple_touch_data_t *) &apple->touches[idx]; - int16_t x = want_full ? touch->full_x : touch->fixed_x; - int16_t y = want_full ? touch->full_y : touch->fixed_y; + int16_t x = touch->fixed_x; + int16_t y = touch->fixed_y; + + if (want_full) + { + x = touch->full_x; + y = touch->full_y; + } switch (id) { @@ -310,6 +315,12 @@ static int16_t apple_pointer_state(apple_input_data_t *apple, return 0; } +static int16_t apple_keyboard_state(apple_input_data_t *apple, unsigned id) +{ + unsigned bit = input_keymaps_translate_rk_to_keysym((enum retro_key)id); + return (id < RETROK_LAST) && apple->key_state[bit]; +} + static int16_t apple_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned idx, unsigned id) @@ -328,10 +339,7 @@ static int16_t apple_input_state(void *data, return input_joypad_analog(apple->joypad, port, idx, id, binds[port]); case RETRO_DEVICE_KEYBOARD: - { - unsigned bit = input_keymaps_translate_rk_to_keysym((enum retro_key)id); - return (id < RETROK_LAST) && apple->key_state[bit]; - } + return apple_keyboard_state(apple, id); case RETRO_DEVICE_MOUSE: return apple_mouse_state(apple, id); case RETRO_DEVICE_POINTER: diff --git a/input/drivers_joypad/udev_joypad.c b/input/drivers_joypad/udev_joypad.c index 288074b6cc..f28aa04442 100644 --- a/input/drivers_joypad/udev_joypad.c +++ b/input/drivers_joypad/udev_joypad.c @@ -85,11 +85,10 @@ static inline int16_t compute_axis(const struct input_absinfo *info, int value) return axis; } -static void udev_poll_pad(unsigned p) +static void udev_poll_pad(struct udev_joypad *pad, unsigned p) { int i, len; struct input_event events[32]; - struct udev_joypad *pad = (struct udev_joypad*)&udev_pads[p]; if (pad->fd < 0) return; @@ -268,7 +267,7 @@ static void udev_joypad_poll(void) handle_hotplug(); for (i = 0; i < MAX_USERS; i++) - udev_poll_pad(i); + udev_poll_pad(&udev_pads[i], i); } #define test_bit(nr, addr) \ diff --git a/gfx/rpng/Makefile b/libretro-sdk/formats/png/Makefile similarity index 84% rename from gfx/rpng/Makefile rename to libretro-sdk/formats/png/Makefile index 46e2137164..ed00d89b45 100644 --- a/gfx/rpng/Makefile +++ b/libretro-sdk/formats/png/Makefile @@ -3,7 +3,7 @@ TARGET := rpng SOURCES := $(wildcard *.c) OBJS := $(SOURCES:.c=.o) -CFLAGS += -Wall -pedantic -std=gnu99 -O0 -g -DHAVE_ZLIB -DHAVE_ZLIB_DEFLATE -DRPNG_TEST -I../../libretro-sdk/include +CFLAGS += -Wall -pedantic -std=gnu99 -O0 -g -DHAVE_ZLIB -DHAVE_ZLIB_DEFLATE -DRPNG_TEST -I../../include all: $(TARGET) diff --git a/gfx/rpng/rpng.c b/libretro-sdk/formats/png/rpng.c similarity index 94% rename from gfx/rpng/rpng.c rename to libretro-sdk/formats/png/rpng.c index c21af16700..80344edbf5 100644 --- a/gfx/rpng/rpng.c +++ b/libretro-sdk/formats/png/rpng.c @@ -1,19 +1,26 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * - * 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. +/* Copyright (C) 2010-2015 The RetroArch team * - * 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. + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (rpng.c). + * --------------------------------------------------------------------------------------- * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . + * 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 "rpng.h" +#include #include @@ -26,8 +33,9 @@ #endif #ifdef RARCH_INTERNAL -#include "../../hash.h" +#include "../../../hash.h" #else + static inline uint32_t crc32_calculate(const uint8_t *data, size_t length) { return crc32(0, data, length); @@ -303,11 +311,10 @@ static inline void copy_line_rgba(uint32_t *data, static inline void copy_line_bw(uint32_t *data, const uint8_t *decoded, unsigned width, unsigned depth) { - unsigned i, bit = 0; + unsigned i, bit; static const unsigned mul_table[] = { 0, 0xff, 0x55, 0, 0x11, 0, 0, 0, 0x01 }; - unsigned mul = mul_table[depth]; - unsigned mask = (1 << depth) - 1; - + unsigned mul, mask; + if (depth == 16) { for (i = 0; i < width; i++) @@ -318,6 +325,10 @@ static inline void copy_line_bw(uint32_t *data, return; } + mul = mul_table[depth]; + mask = (1 << depth) - 1; + bit = 0; + for (i = 0; i < width; i++, bit += depth) { unsigned byte = bit >> 3; diff --git a/gfx/rpng/rpng_test.c b/libretro-sdk/formats/png/rpng_test.c similarity index 60% rename from gfx/rpng/rpng_test.c rename to libretro-sdk/formats/png/rpng_test.c index 0870de0f32..0d3ad73265 100644 --- a/gfx/rpng/rpng_test.c +++ b/libretro-sdk/formats/png/rpng_test.c @@ -1,19 +1,26 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * - * 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. +/* Copyright (C) 2010-2015 The RetroArch team * - * 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. + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (rpng_test.c). + * --------------------------------------------------------------------------------------- * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . + * 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 "rpng.h" +#include #include #include #include diff --git a/compat/rxml/Makefile b/libretro-sdk/formats/xml/Makefile similarity index 75% rename from compat/rxml/Makefile rename to libretro-sdk/formats/xml/Makefile index f3d54f17e1..3c2a6e1fcb 100644 --- a/compat/rxml/Makefile +++ b/libretro-sdk/formats/xml/Makefile @@ -3,7 +3,7 @@ TARGET := rxml SOURCES := $(wildcard *.c) OBJS := $(SOURCES:.c=.o) -CFLAGS += -DRXML_TEST -Wall -pedantic -std=gnu99 -O0 -g +CFLAGS += -DRXML_TEST -Wall -pedantic -std=gnu99 -O0 -g -I../../include all: $(TARGET) diff --git a/compat/rxml/rxml.c b/libretro-sdk/formats/xml/rxml.c similarity index 88% rename from compat/rxml/rxml.c rename to libretro-sdk/formats/xml/rxml.c index bf44c1d303..410fbf6230 100644 --- a/compat/rxml/rxml.c +++ b/libretro-sdk/formats/xml/rxml.c @@ -1,19 +1,26 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * - * 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. +/* Copyright (C) 2010-2015 The RetroArch team * - * 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. + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (rxml.c). + * --------------------------------------------------------------------------------------- * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . + * 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 "rxml.h" +#include #include #include #include @@ -23,10 +30,6 @@ #include #include -#ifndef RXML_TEST -#include "../../general.h" -#endif - struct rxml_document { struct rxml_node *root_node; diff --git a/libretro-sdk/formats/xml/rxml_test.c b/libretro-sdk/formats/xml/rxml_test.c new file mode 100644 index 0000000000..1156f64f8f --- /dev/null +++ b/libretro-sdk/formats/xml/rxml_test.c @@ -0,0 +1,67 @@ +/* Copyright (C) 2010-2015 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (rxml_test.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 + +static void print_siblings(struct rxml_node *node, unsigned level) +{ + fprintf(stderr, "\n%*sName: %s\n", level * 4, "", node->name); + if (node->data) + fprintf(stderr, "%*sData: %s\n", level * 4, "", node->data); + + for (const struct rxml_attrib_node *attrib = + node->attrib; attrib; attrib = attrib->next) + fprintf(stderr, "%*s Attrib: %s = %s\n", level * 4, "", + attrib->attrib, attrib->value); + + if (node->children) + print_siblings(node->children, level + 1); + + if (node->next) + print_siblings(node->next, level); +} + +static void rxml_log_document(const char *path) +{ + rxml_document_t *doc = rxml_load_document(path); + if (!doc) + { + fprintf(stderr, "rxml: Failed to load document: %s\n", path); + return; + } + + print_siblings(rxml_root_node(doc), 0); + rxml_free_document(doc); +} + +int main(int argc, char *argv[]) +{ + if (argc != 2) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + rxml_log_document(argv[1]); +} + diff --git a/libretro-sdk/include/formats/rpng.h b/libretro-sdk/include/formats/rpng.h new file mode 100644 index 0000000000..077afc67e5 --- /dev/null +++ b/libretro-sdk/include/formats/rpng.h @@ -0,0 +1,53 @@ +/* Copyright (C) 2010-2015 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (rpng.h). + * --------------------------------------------------------------------------------------- + * + * 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 __LIBRETRO_SDK_FORMAT_RPNG_H__ +#define __LIBRETRO_SDK_FORMAT_RPNG_H__ + +#include + +#include + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +bool rpng_load_image_argb(const char *path, uint32_t **data, + unsigned *width, unsigned *height); + +#ifdef HAVE_ZLIB_DEFLATE +bool rpng_save_image_argb(const char *path, const uint32_t *data, + unsigned width, unsigned height, unsigned pitch); +bool rpng_save_image_bgr24(const char *path, const uint8_t *data, + unsigned width, unsigned height, unsigned pitch); +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/compat/rxml/rxml.h b/libretro-sdk/include/formats/rxml.h similarity index 58% rename from compat/rxml/rxml.h rename to libretro-sdk/include/formats/rxml.h index 3a0b87eefc..ecebefee96 100644 --- a/compat/rxml/rxml.h +++ b/libretro-sdk/include/formats/rxml.h @@ -1,20 +1,26 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * - * 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. +/* Copyright (C) 2010-2015 The RetroArch team * - * 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. + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (rxml.h). + * --------------------------------------------------------------------------------------- * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . + * 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 RXML_H__ -#define RXML_H__ +#ifndef __LIBRETRO_SDK_FORMAT_RXML_H__ +#define __LIBRETRO_SDK_FORMAT_RXML_H__ #ifdef __cplusplus extern "C" { diff --git a/libretro_version_1.c b/libretro_version_1.c index 4f139c3d1f..555734abcb 100644 --- a/libretro_version_1.c +++ b/libretro_version_1.c @@ -141,33 +141,6 @@ static void video_frame(const void *data, unsigned width, driver.video_active = false; } -/* - * readjust_audio_input_rate: - * - * Readjust the audio input rate. - */ -static void readjust_audio_input_rate(void) -{ - int avail = driver.audio->write_avail(driver.audio_data); - - //RARCH_LOG_OUTPUT("Audio buffer is %u%% full\n", - // (unsigned)(100 - (avail * 100) / g_extern.audio_data.driver_buffer_size)); - - unsigned write_idx = g_extern.measure_data.buffer_free_samples_count++ & - (AUDIO_BUFFER_FREE_SAMPLES_COUNT - 1); - int half_size = g_extern.audio_data.driver_buffer_size / 2; - int delta_mid = avail - half_size; - double direction = (double)delta_mid / half_size; - double adjust = 1.0 + g_settings.audio.rate_control_delta * - direction; - - g_extern.measure_data.buffer_free_samples[write_idx] = avail; - g_extern.audio_data.src_ratio = g_extern.audio_data.orig_src_ratio * adjust; - - //RARCH_LOG_OUTPUT("New rate: %lf, Orig rate: %lf\n", - // g_extern.audio_data.src_ratio, g_extern.audio_data.orig_src_ratio); -} - /** * retro_flush_audio: * @data : pointer to audio buffer. @@ -231,7 +204,7 @@ bool retro_flush_audio(const int16_t *data, size_t samples) src_data.data_out = g_extern.audio_data.outsamples; if (g_extern.audio_data.rate_control) - readjust_audio_input_rate(); + audio_driver_readjust_input_rate(); src_data.ratio = g_extern.audio_data.src_ratio; if (g_extern.is_slowmotion) diff --git a/menu/drivers/glui.c b/menu/drivers/glui.c index 52028735d9..4206f570d1 100644 --- a/menu/drivers/glui.c +++ b/menu/drivers/glui.c @@ -22,11 +22,11 @@ #include #include "../menu.h" +#include "../menu_texture.h" + #include #include "../../gfx/gl_common.h" -#include "../../gfx/video_thread_wrapper.h" #include -#include "../menu_input.h" #include "shared.h" @@ -38,20 +38,29 @@ typedef struct glui_handle unsigned term_width; unsigned term_height; char box_message[PATH_MAX_LENGTH]; - GLuint bg; + struct + { + struct + { + GLuint id; + char path[PATH_MAX_LENGTH]; + } bg; + } textures; } glui_handle_t; static int glui_entry_iterate(unsigned action) { const char *label = NULL; - menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(driver.menu->menu_list->selection_buf, - driver.menu->selection_ptr); + menu_file_list_cbs_t *cbs = NULL; + menu_handle_t *menu = menu_driver_resolve(); - menu_list_get_last_stack(driver.menu->menu_list, NULL, &label, NULL); + if (!menu) + return -1; - if (driver.video_data && driver.menu_ctx && driver.menu_ctx->set_texture) - driver.menu_ctx->set_texture(driver.menu); + cbs = (menu_file_list_cbs_t*)menu_list_get_actiondata_at_offset( + menu->menu_list->selection_buf, menu->navigation.selection_ptr); + + menu_list_get_last_stack(menu->menu_list, NULL, &label, NULL); if (cbs && cbs->action_iterate) return cbs->action_iterate(label, action); @@ -59,13 +68,9 @@ static int glui_entry_iterate(unsigned action) return -1; } -static void glui_blit_line(float x, float y, const char *message, bool green) +static void glui_blit_line(gl_t *gl, float x, float y, const char *message, bool green) { struct font_params params = {0}; - gl_t *gl = (gl_t*)video_driver_resolve(NULL); - - if (!driver.menu || !gl) - return; gl_set_viewport(gl, gl->win_width, gl->win_height, false, false); @@ -89,7 +94,8 @@ static void glui_blit_line(float x, float y, const char *message, bool green) message, ¶ms, NULL); } -static void glui_render_background(bool force_transparency) +static void glui_render_background(gl_t *gl, glui_handle_t *glui, + bool force_transparency) { static const GLfloat vertex[] = { 0, 0, @@ -106,8 +112,6 @@ static void glui_render_background(bool force_transparency) }; struct gl_coords coords; float alpha = 0.75f; - gl_t *gl = NULL; - glui_handle_t *glui = NULL; GLfloat color[] = { 1.0f, 1.0f, 1.0f, alpha, 1.0f, 1.0f, 1.0f, alpha, @@ -122,19 +126,6 @@ static void glui_render_background(bool force_transparency) 0.0f, 0.0f, 0.0f, alpha, }; - if (!driver.menu) - return; - - glui = (glui_handle_t*)driver.menu->userdata; - - if (!glui) - return; - - gl = (gl_t*)video_driver_resolve(NULL); - - if (!gl) - return; - glViewport(0, 0, gl->win_width, gl->win_height); coords.vertices = 4; @@ -145,10 +136,10 @@ static void glui_render_background(bool force_transparency) if ((g_settings.menu.pause_libretro || !g_extern.main_is_init || g_extern.libretro_dummy) && !force_transparency - && glui->bg) + && glui->textures.bg.id) { coords.color = color; - glBindTexture(GL_TEXTURE_2D, glui->bg); + glBindTexture(GL_TEXTURE_2D, glui->textures.bg.id); } else { @@ -167,8 +158,9 @@ static void glui_render_background(bool force_transparency) gl->coords.color = gl->white_color_ptr; } -static void glui_draw_cursor(float x, float y) +static void glui_draw_cursor(gl_t *gl, glui_handle_t *glui, float x, float y) { + struct gl_coords coords; static const GLfloat vertex[] = { 0, 0, 1, 0, @@ -188,22 +180,6 @@ static void glui_draw_cursor(float x, float y) 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, }; - struct gl_coords coords; - gl_t *gl = NULL; - glui_handle_t *glui = NULL; - - if (!driver.menu) - return; - - glui = (glui_handle_t*)driver.menu->userdata; - - if (!glui) - return; - - gl = (gl_t*)video_driver_resolve(NULL); - - if (!gl) - return; glViewport(x - 5, gl->win_height - y, 11, 11); @@ -229,11 +205,15 @@ static void glui_draw_cursor(float x, float y) static void glui_get_message(const char *message) { glui_handle_t *glui = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu || !message || !*message) + if (!menu) return; - glui = (glui_handle_t*)driver.menu->userdata; + if (!message || !*message) + return; + + glui = (glui_handle_t*)menu->userdata; if (glui) strlcpy(glui->box_message, message, sizeof(glui->box_message)); @@ -245,12 +225,18 @@ static void glui_render_messagebox(const char *message) int x, y; struct string_list *list = NULL; glui_handle_t *glui = NULL; - gl_t *gl = (gl_t*)video_driver_resolve(NULL); + gl_t *gl = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu || !gl) + if (!menu) return; - glui = (glui_handle_t*)driver.menu->userdata; + gl = (gl_t*)video_driver_resolve(NULL); + + if (!gl) + return; + + glui = (glui_handle_t*)menu->userdata; if (!glui) return; @@ -270,7 +256,7 @@ static void glui_render_messagebox(const char *message) { const char *msg = list->elems[i].data; if (msg) - glui_blit_line(x, y + i * glui->line_height, msg, false); + glui_blit_line(gl, x, y + i * glui->line_height, msg, false); } end: @@ -288,22 +274,28 @@ static void glui_frame(void) const char *label = NULL; unsigned menu_type = 0; size_t end; - gl_t *gl = (gl_t*)video_driver_resolve(NULL); + gl_t *gl = NULL; glui_handle_t *glui = NULL; const char *core_name = NULL; const char *core_version = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu || !gl) + if (!menu) return; - glui = (glui_handle_t*)driver.menu->userdata; + gl = (gl_t*)video_driver_resolve(NULL); + + if (!gl) + return; + + glui = (glui_handle_t*)menu->userdata; if (!glui) return; - if (driver.menu->need_refresh + if (menu->need_refresh && g_extern.is_menu - && !driver.menu->msg_force) + && !menu->msg_force) return; glui->line_height = g_settings.video.font_size * 4 / 3; @@ -312,36 +304,36 @@ static void glui_frame(void) glui->term_width = (gl->win_width - glui->margin * 2) / glui->glyph_width; glui->term_height = (gl->win_height - glui->margin * 2) / glui->line_height - 2; - driver.menu->mouse.ptr = (driver.menu->mouse.y - glui->margin) / - glui->line_height - 2 + driver.menu->begin; + menu->mouse.ptr = (menu->mouse.y - glui->margin) / + glui->line_height - 2 + menu->begin; glViewport(0, 0, gl->win_width, gl->win_height); - if (driver.menu->mouse.wheeldown && driver.menu->begin - < menu_list_get_size(driver.menu->menu_list) - glui->term_height) - driver.menu->begin++; + if (menu->mouse.wheeldown && menu->begin + < menu_list_get_size(menu->menu_list) - glui->term_height) + menu->begin++; - if (driver.menu->mouse.wheelup && driver.menu->begin > 0) - driver.menu->begin--; + if (menu->mouse.wheelup && menu->begin > 0) + menu->begin--; /* Do not scroll if all items are visible. */ - if (menu_list_get_size(driver.menu->menu_list) <= glui->term_height) - driver.menu->begin = 0; + if (menu_list_get_size(menu->menu_list) <= glui->term_height) + menu->begin = 0; - end = (driver.menu->begin + glui->term_height <= - menu_list_get_size(driver.menu->menu_list)) ? - driver.menu->begin + glui->term_height : - menu_list_get_size(driver.menu->menu_list); + end = (menu->begin + glui->term_height <= + menu_list_get_size(menu->menu_list)) ? + menu->begin + glui->term_height : + menu_list_get_size(menu->menu_list); - glui_render_background(false); + glui_render_background(gl, glui, false); - menu_list_get_last_stack(driver.menu->menu_list, &dir, &label, &menu_type); + menu_list_get_last_stack(menu->menu_list, &dir, &label, &menu_type); get_title(label, dir, menu_type, title, sizeof(title)); - menu_ticker_line(title_buf, glui->term_width - 3, + menu_animation_ticker_line(title_buf, glui->term_width - 3, g_extern.frame_count / glui->margin, title, true); - glui_blit_line(glui->margin * 2, glui->margin + glui->line_height, + glui_blit_line(gl, glui->margin * 2, glui->margin + glui->line_height, title_buf, true); core_name = g_extern.menu.info.library_name; @@ -350,33 +342,37 @@ static void glui_frame(void) if (!core_name) core_name = "No Core"; - core_version = g_extern.menu.info.library_version; - if (!core_version) - core_version = g_extern.system.info.library_version; - if (!core_version) - core_version = ""; + if (g_settings.menu.core_enable) + { + core_version = g_extern.menu.info.library_version; + if (!core_version) + core_version = g_extern.system.info.library_version; + if (!core_version) + core_version = ""; - snprintf(title_msg, sizeof(title_msg), "%s - %s %s", PACKAGE_VERSION, - core_name, core_version); + snprintf(title_msg, sizeof(title_msg), "%s - %s %s", PACKAGE_VERSION, + core_name, core_version); - disp_timedate_set_label(timedate, sizeof(timedate), 0); + glui_blit_line(gl, + glui->margin * 2, + glui->margin + glui->term_height * glui->line_height + + glui->line_height * 2, title_msg, true); + } - glui_blit_line( - glui->margin * 2, - glui->margin + glui->term_height * glui->line_height - + glui->line_height * 2, title_msg, true); if (g_settings.menu.timedate_enable) - glui_blit_line( + { + disp_timedate_set_label(timedate, sizeof(timedate), 0); + glui_blit_line(gl, glui->margin * 14, glui->margin + glui->term_height * glui->line_height + glui->line_height * 2, timedate, true); - + } x = glui->margin; y = glui->margin + glui->line_height * 2; - for (i = driver.menu->begin; i < end; i++, y += glui->line_height) + for (i = menu->begin; i < end; i++, y += glui->line_height) { char message[PATH_MAX_LENGTH], type_str[PATH_MAX_LENGTH], entry_title_buf[PATH_MAX_LENGTH], type_str_buf[PATH_MAX_LENGTH], @@ -386,42 +382,42 @@ static void glui_frame(void) bool selected = false; menu_file_list_cbs_t *cbs = NULL; - menu_list_get_at_offset(driver.menu->menu_list->selection_buf, i, &path, + menu_list_get_at_offset(menu->menu_list->selection_buf, i, &path, &entry_label, &type); cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(driver.menu->menu_list->selection_buf, + menu_list_get_actiondata_at_offset(menu->menu_list->selection_buf, i); if (cbs && cbs->action_get_representation) - cbs->action_get_representation(driver.menu->menu_list->selection_buf, + cbs->action_get_representation(menu->menu_list->selection_buf, &w, type, i, label, type_str, sizeof(type_str), entry_label, path, path_buf, sizeof(path_buf)); - selected = (i == driver.menu->selection_ptr); + selected = (i == menu->navigation.selection_ptr); - menu_ticker_line(entry_title_buf, glui->term_width - (w + 1 + 2), + menu_animation_ticker_line(entry_title_buf, glui->term_width - (w + 1 + 2), g_extern.frame_count / glui->margin, path_buf, selected); - menu_ticker_line(type_str_buf, w, + menu_animation_ticker_line(type_str_buf, w, g_extern.frame_count / glui->margin, type_str, selected); strlcpy(message, entry_title_buf, sizeof(message)); - glui_blit_line(x, y, message, selected); + glui_blit_line(gl, x, y, message, selected); - glui_blit_line(gl->win_width - glui->glyph_width * w - glui->margin , + glui_blit_line(gl, gl->win_width - glui->glyph_width * w - glui->margin , y, type_str_buf, selected); } #ifdef GEKKO const char *message_queue; - if (driver.menu->msg_force) + if (menu->msg_force) { message_queue = msg_queue_pull(g_extern.msg_queue); - driver.menu->msg_force = false; + menu->msg_force = false; } else message_queue = driver.current_msg; @@ -429,35 +425,35 @@ static void glui_frame(void) glui_render_messagebox(message_queue); #endif - if (driver.menu->keyboard.display) + if (menu->keyboard.display) { char msg[PATH_MAX_LENGTH]; - const char *str = *driver.menu->keyboard.buffer; + const char *str = *menu->keyboard.buffer; if (!str) str = ""; - glui_render_background(true); - snprintf(msg, sizeof(msg), "%s\n%s", driver.menu->keyboard.label, str); + glui_render_background(gl, glui, true); + snprintf(msg, sizeof(msg), "%s\n%s", menu->keyboard.label, str); glui_render_messagebox(msg); } if (glui->box_message[0] != '\0') { - glui_render_background(true); + glui_render_background(gl, glui, true); glui_render_messagebox(glui->box_message); glui->box_message[0] = '\0'; } - if (driver.menu->mouse.enable) - glui_draw_cursor(driver.menu->mouse.x, driver.menu->mouse.y); + if (menu->mouse.enable) + glui_draw_cursor(gl, glui, menu->mouse.x, menu->mouse.y); gl_set_viewport(gl, gl->win_width, gl->win_height, false, false); } static void *glui_init(void) { - menu_handle_t *menu; glui_handle_t *glui = NULL; const video_driver_t *video_driver = NULL; + menu_handle_t *menu = NULL; gl_t *gl = (gl_t*)video_driver_resolve(&video_driver); if (video_driver != &video_gl || !gl) @@ -477,7 +473,7 @@ static void *glui_init(void) goto error; glui = (glui_handle_t*)menu->userdata; - glui->bg = 0; + glui->textures.bg.id = 0; return menu; error: @@ -497,65 +493,13 @@ static void glui_free(void *data) free(menu->userdata); } -static GLuint glui_png_texture_load_(const char * file_name) + + +static void glui_context_destroy(void) { - GLuint texture = 0; - struct texture_image ti = {0}; - if (! path_file_exists(file_name)) - return 0; - - texture_image_load(&ti, file_name); - - /* Generate the OpenGL texture object */ - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexImage2D(GL_TEXTURE_2D, 0, driver.gfx_use_rgba ? - GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, - ti.width, ti.height, 0, - driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, - RARCH_GL_FORMAT32, ti.pixels); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - free(ti.pixels); - - return texture; -} -static int glui_png_texture_load_wrap(void *data) -{ - const char *filename = (const char*)data; - return glui_png_texture_load_(filename); -} - - -static GLuint glui_png_texture_load(const char* file_name) -{ - if (g_settings.video.threaded - && !g_extern.system.hw_render_callback.context_type) - { - thread_video_t *thr = (thread_video_t*)driver.video_data; - thr->cmd_data.custom_command.method = glui_png_texture_load_wrap; - thr->cmd_data.custom_command.data = (void*)file_name; - thr->send_cmd_func(thr, CMD_CUSTOM_COMMAND); - thr->wait_reply_func(thr, CMD_CUSTOM_COMMAND); - - return thr->cmd_data.custom_command.return_value; - - } - - return glui_png_texture_load_(file_name); -} - - -static void glui_context_reset(void *data) -{ - char bgpath[PATH_MAX_LENGTH]; glui_handle_t *glui = NULL; - menu_handle_t *menu = (menu_handle_t*)data; - gl_t *gl = (gl_t*)video_driver_resolve(NULL); + menu_handle_t *menu = menu_driver_resolve(); - (void)gl; - if (!menu) return; @@ -564,65 +508,117 @@ static void glui_context_reset(void *data) if (!glui) return; - fill_pathname_join(bgpath, g_settings.assets_directory, - "glui", sizeof(bgpath)); + if (glui->textures.bg.id) + glDeleteTextures(1, &glui->textures.bg.id); +} + +static bool glui_load_wallpaper(const char *path) +{ + glui_handle_t *glui = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return false; + + glui = (glui_handle_t*)menu->userdata; + + if (!glui) + return false; + if (!path) + return false; + + if (glui->textures.bg.id) + glDeleteTextures(1, &glui->textures.bg.id); + + strlcpy(glui->textures.bg.path, path, sizeof(glui->textures.bg.path)); + + glui->textures.bg.id = menu_texture_load(glui->textures.bg.path, + TEXTURE_BACKEND_OPENGL, TEXTURE_FILTER_MIPMAP_LINEAR); + + return true; +} + +static void glui_context_reset(void) +{ + glui_handle_t *glui = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; + + glui = (glui_handle_t*)menu->userdata; + + if (!glui) + return; + + fill_pathname_join(glui->textures.bg.path, g_settings.assets_directory, + "glui", sizeof(glui->textures.bg.path)); if (*g_settings.menu.wallpaper) - strlcpy(bgpath, g_settings.menu.wallpaper, sizeof(bgpath)); + strlcpy(glui->textures.bg.path, + g_settings.menu.wallpaper, sizeof(glui->textures.bg.path)); else - fill_pathname_join(bgpath, bgpath, "bg.png", sizeof(bgpath)); + fill_pathname_join(glui->textures.bg.path, + glui->textures.bg.path, "bg.png", + sizeof(glui->textures.bg.path)); - if (path_file_exists(bgpath)) - glui->bg = glui_png_texture_load(bgpath); + if (path_file_exists(glui->textures.bg.path)) + glui_load_wallpaper(glui->textures.bg.path); } -static void glui_navigation_clear(void *data, bool pending_push) +static void glui_navigation_clear(bool pending_push) { - driver.menu->begin = 0; + menu_handle_t *menu = menu_driver_resolve(); + if (menu) + menu->begin = 0; } -static void glui_navigation_set(void *data, bool scroll) +static void glui_navigation_set(bool scroll) { glui_handle_t *glui = NULL; - - menu_handle_t *menu = (menu_handle_t*)data; + menu_handle_t *menu = menu_driver_resolve(); if (!menu) return; - + glui = (glui_handle_t*)menu->userdata; if (!glui) return; - if (!scroll) return; - if (driver.menu->selection_ptr < glui->term_height/2) - driver.menu->begin = 0; - else if (driver.menu->selection_ptr >= glui->term_height/2 - && driver.menu->selection_ptr < - menu_list_get_size(driver.menu->menu_list) - glui->term_height/2) - driver.menu->begin = driver.menu->selection_ptr - glui->term_height/2; - else if (driver.menu->selection_ptr >= - menu_list_get_size(driver.menu->menu_list) - glui->term_height/2) - driver.menu->begin = menu_list_get_size(driver.menu->menu_list) + if (menu->navigation.selection_ptr < glui->term_height/2) + menu->begin = 0; + else if (menu->navigation.selection_ptr >= glui->term_height/2 + && menu->navigation.selection_ptr < + menu_list_get_size(menu->menu_list) - glui->term_height/2) + menu->begin = menu->navigation.selection_ptr - glui->term_height/2; + else if (menu->navigation.selection_ptr >= + menu_list_get_size(menu->menu_list) - glui->term_height/2) + menu->begin = menu_list_get_size(menu->menu_list) - glui->term_height; } -static void glui_navigation_set_last(void *data) +static void glui_navigation_set_last(void) { - glui_navigation_set(data, true); + menu_handle_t *menu = menu_driver_resolve(); + if (menu) + glui_navigation_set(true); } -static void glui_navigation_descend_alphabet(void *data, size_t *unused) +static void glui_navigation_descend_alphabet(size_t *unused) { - glui_navigation_set(data, true); + menu_handle_t *menu = menu_driver_resolve(); + if (menu) + glui_navigation_set(true); } -static void glui_navigation_ascend_alphabet(void *data, size_t *unused) +static void glui_navigation_ascend_alphabet(size_t *unused) { - glui_navigation_set(data, true); + menu_handle_t *menu = menu_driver_resolve(); + if (menu) + glui_navigation_set(true); } menu_ctx_driver_t menu_ctx_glui = { @@ -633,7 +629,7 @@ menu_ctx_driver_t menu_ctx_glui = { glui_init, glui_free, glui_context_reset, - NULL, + glui_context_destroy, NULL, NULL, glui_navigation_clear, @@ -649,5 +645,6 @@ menu_ctx_driver_t menu_ctx_glui = { NULL, NULL, glui_entry_iterate, + glui_load_wallpaper, "glui", }; diff --git a/menu/drivers/ios.c b/menu/drivers/ios.c index 6df78ff90a..d06a8ff50a 100644 --- a/menu/drivers/ios.c +++ b/menu/drivers/ios.c @@ -25,38 +25,21 @@ #include "ios.h" #include "../menu_input.h" -#if 1 static int ios_entry_iterate(unsigned action) { - ios_handle_t *ios = NULL; - if (!driver.menu) - return 0; + ios_handle_t *ios = NULL; + menu_handle_t *menu = menu_driver_resolve(); - ios = (ios_handle_t*)driver.menu->userdata; - if (ios->switch_to_ios) + if (!menu) + return -1; + + ios = (ios_handle_t*)menu->userdata; + + if (ios && ios->switch_to_ios) ios->switch_to_ios(); return 0; } -#else -static int ios_entry_iterate(unsigned action) -{ - const char *label = NULL; - menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(driver.menu->menu_list->selection_buf, - driver.menu->selection_ptr); - - menu_list_get_last_stack(driver.menu->menu_list, NULL, &label, NULL); - - if (driver.video_data && driver.menu_ctx && driver.menu_ctx->set_texture) - driver.menu_ctx->set_texture(driver.menu); - - if (cbs && cbs->action_iterate) - return cbs->action_iterate(label, action); - - return -1; -} -#endif static void *ios_init(void) { @@ -113,5 +96,6 @@ menu_ctx_driver_t menu_ctx_ios = { NULL, // list_cache NULL, // list_set_selection ios_entry_iterate, + NULL, "ios", }; diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 6412ae8a61..be4a6aecc5 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -22,8 +22,6 @@ #include #include "../menu.h" -#include "../menu_input.h" -#include "../../retroarch.h" #include #include @@ -31,40 +29,31 @@ #include "shared.h" -typedef struct rgui_handle -{ - unsigned term_height; - uint16_t *frame_buf; - size_t frame_buf_pitch; -} rgui_handle_t; - -#define RGUI_TERM_START_X (driver.menu->width / 21) -#define RGUI_TERM_START_Y (driver.menu->height / 9) -#define RGUI_TERM_WIDTH (((driver.menu->width - RGUI_TERM_START_X - RGUI_TERM_START_X) / (FONT_WIDTH_STRIDE))) -#define RGUI_TERM_HEIGHT (((driver.menu->height - RGUI_TERM_START_Y - RGUI_TERM_START_X) / (FONT_HEIGHT_STRIDE)) - 1) +#define RGUI_TERM_START_X (menu->frame_buf.width / 21) +#define RGUI_TERM_START_Y (menu->frame_buf.height / 9) +#define RGUI_TERM_WIDTH (((menu->frame_buf.width - RGUI_TERM_START_X - RGUI_TERM_START_X) / (FONT_WIDTH_STRIDE))) +#define RGUI_TERM_HEIGHT (((menu->frame_buf.height - RGUI_TERM_START_Y - RGUI_TERM_START_X) / (FONT_HEIGHT_STRIDE)) - 1) static int rgui_entry_iterate(unsigned action) { const char *label = NULL; + menu_file_list_cbs_t *cbs = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu || !driver.menu->menu_list) + if (!menu) + return -1; + if (!menu->menu_list) return -1; - menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(driver.menu->menu_list->selection_buf, - driver.menu->selection_ptr); + cbs = (menu_file_list_cbs_t*)menu_list_get_actiondata_at_offset( + menu->menu_list->selection_buf, menu->navigation.selection_ptr); - menu_list_get_last_stack(driver.menu->menu_list, NULL, &label, NULL); + menu_list_get_last_stack(menu->menu_list, NULL, &label, NULL); - if (driver.video_data && driver.menu_ctx && driver.menu_ctx->set_texture) - driver.menu_ctx->set_texture(driver.menu); + if (cbs && cbs->action_iterate) + return cbs->action_iterate(label, action); - if (!cbs) - return -1; - if (!cbs->action_iterate) - return -1; - - return cbs->action_iterate(label, action); + return -1; } static void rgui_copy_glyph(uint8_t *glyph, const uint8_t *buf) @@ -83,7 +72,7 @@ static void rgui_copy_glyph(uint8_t *glyph, const uint8_t *buf) ((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); + uint8_t rem = 1 << ((x + y * FONT_WIDTH) & 7); unsigned offset = (x + y * FONT_WIDTH) >> 3; if (col != 0xff) @@ -121,48 +110,40 @@ static uint16_t green_filler(unsigned x, unsigned y) #endif } -static void fill_rect(uint16_t *buf, unsigned pitch, +static void fill_rect(menu_framebuf_t *frame_buf, unsigned x, unsigned y, unsigned width, unsigned height, uint16_t (*col)(unsigned x, unsigned y)) { unsigned i, j; - if (!buf || !col) + if (!frame_buf->data || !col) return; for (j = y; j < y + height; j++) for (i = x; i < x + width; i++) - buf[j * (pitch >> 1) + i] = col(i, j); + frame_buf->data[j * (frame_buf->pitch >> 1) + i] = col(i, j); } -static void color_rect(uint16_t *buf, unsigned pitch, + +static void color_rect(menu_handle_t *menu, unsigned x, unsigned y, unsigned width, unsigned height, uint16_t color) { unsigned i, j; - if (!buf) + if (!menu->frame_buf.data) return; for (j = y; j < y + height; j++) for (i = x; i < x + width; i++) - if (i < driver.menu->width && j < driver.menu->height) - buf[j * (pitch >> 1) + i] = color; + if (i < menu->frame_buf.width && j < menu->frame_buf.height) + menu->frame_buf.data[j * (menu->frame_buf.pitch >> 1) + i] = color; } -static void blit_line(int x, int y, const char *message, bool green) +static void blit_line(menu_handle_t *menu, int x, int y, const char *message, bool green) { unsigned i, j; - rgui_handle_t *rgui = NULL; - - if (!driver.menu) - return; - - rgui = (rgui_handle_t*)driver.menu->userdata; - - if (!rgui) - return; while (*message) { @@ -172,14 +153,14 @@ static void blit_line(int x, int y, const char *message, bool green) { uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); int offset = (i + j * FONT_WIDTH) >> 3; - bool col = (driver.menu->font[FONT_OFFSET + bool col = (menu->font[FONT_OFFSET ((unsigned char)*message) + offset] & rem); if (!col) continue; - rgui->frame_buf[(y + j) * - (rgui->frame_buf_pitch >> 1) + (x + i)] = green ? + menu->frame_buf.data[(y + j) * + (menu->frame_buf.pitch >> 1) + (x + i)] = green ? #if defined(GEKKO)|| defined(PSP) (3 << 0) | (10 << 4) | (3 << 8) | (7 << 12) : 0x7FFF; #else @@ -217,13 +198,14 @@ static bool init_font(menu_handle_t *menu, const uint8_t *font_bmp_buf) return true; } -static bool rguidisp_init_font(void *data) +static bool rguidisp_init_font(menu_handle_t *menu) { - menu_handle_t *menu = (menu_handle_t*)data; - const uint8_t *font_bmp_buf = NULL; const uint8_t *font_bin_buf = bitmap_bin; + if (!menu) + return false; + if (font_bmp_buf) return init_font(menu, font_bmp_buf); @@ -235,28 +217,19 @@ static bool rguidisp_init_font(void *data) return true; } -static void rgui_render_background(void *data) +static void rgui_render_background(void) { - rgui_handle_t *rgui = (rgui_handle_t*)data; - - if (!rgui) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return; - fill_rect(rgui->frame_buf, rgui->frame_buf_pitch, - 0, 0, driver.menu->width, driver.menu->height, gray_filler); - - fill_rect(rgui->frame_buf, rgui->frame_buf_pitch, - 5, 5, driver.menu->width - 10, 5, green_filler); - - fill_rect(rgui->frame_buf, rgui->frame_buf_pitch, - 5, driver.menu->height - 10, driver.menu->width - 10, 5, + fill_rect(&menu->frame_buf, 0, 0, menu->frame_buf.width, menu->frame_buf.height, gray_filler); + fill_rect(&menu->frame_buf, 5, 5, menu->frame_buf.width - 10, 5, green_filler); + fill_rect(&menu->frame_buf, 5, menu->frame_buf.height - 10, menu->frame_buf.width - 10, 5, green_filler); - fill_rect(rgui->frame_buf, rgui->frame_buf_pitch, - 5, 5, 5, driver.menu->height - 10, green_filler); - - fill_rect(rgui->frame_buf, rgui->frame_buf_pitch, - driver.menu->width - 10, 5, 5, driver.menu->height - 10, + fill_rect(&menu->frame_buf, 5, 5, 5, menu->frame_buf.height - 10, green_filler); + fill_rect(&menu->frame_buf, menu->frame_buf.width - 10, 5, 5, menu->frame_buf.height - 10, green_filler); } @@ -265,15 +238,12 @@ static void rgui_render_messagebox(const char *message) size_t i; int x, y; unsigned width, glyphs_width, height; - rgui_handle_t *rgui = NULL; struct string_list *list = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu || !message || !*message) + if (!menu) return; - - rgui = (rgui_handle_t*)driver.menu->userdata; - - if (!rgui) + if (!message || !*message) return; list = string_split(message, "\n"); @@ -282,8 +252,9 @@ static void rgui_render_messagebox(const char *message) if (list->elems == 0) goto end; - width = 0; + width = 0; glyphs_width = 0; + for (i = 0; i < list->size; i++) { unsigned line_width; @@ -305,49 +276,34 @@ static void rgui_render_messagebox(const char *message) } height = FONT_HEIGHT_STRIDE * list->size + 6 + 10; - x = (driver.menu->width - width) / 2; - y = (driver.menu->height - height) / 2; + x = (menu->frame_buf.width - width) / 2; + y = (menu->frame_buf.height - height) / 2; - fill_rect(rgui->frame_buf, rgui->frame_buf_pitch, - x + 5, y + 5, width - 10, height - 10, gray_filler); - - fill_rect(rgui->frame_buf, rgui->frame_buf_pitch, - x, y, width - 5, 5, green_filler); - - fill_rect(rgui->frame_buf, rgui->frame_buf_pitch, - x + width - 5, y, 5, height - 5, green_filler); - - fill_rect(rgui->frame_buf, rgui->frame_buf_pitch, - x + 5, y + height - 5, width - 5, 5, green_filler); - - fill_rect(rgui->frame_buf, rgui->frame_buf_pitch, - x, y + 5, 5, height - 5, green_filler); + fill_rect(&menu->frame_buf, x + 5, y + 5, width - 10, height - 10, gray_filler); + fill_rect(&menu->frame_buf, x, y, width - 5, 5, green_filler); + fill_rect(&menu->frame_buf, x + width - 5, y, 5, height - 5, green_filler); + fill_rect(&menu->frame_buf, x + 5, y + height - 5, width - 5, 5, green_filler); + fill_rect(&menu->frame_buf, x, y + 5, 5, height - 5, green_filler); for (i = 0; i < list->size; i++) { const char *msg = list->elems[i].data; int offset_x = FONT_WIDTH_STRIDE * (glyphs_width - strlen(msg)) / 2; int offset_y = FONT_HEIGHT_STRIDE * i; - blit_line(x + 8 + offset_x, y + 8 + offset_y, msg, false); + blit_line(menu, x + 8 + offset_x, y + 8 + offset_y, msg, false); } end: string_list_free(list); } -static void rgui_blit_cursor(void* data) +static void rgui_blit_cursor(menu_handle_t *menu) { - rgui_handle_t *rgui = (rgui_handle_t*)data; - int16_t x = driver.menu->mouse.x; - int16_t y = driver.menu->mouse.y; + int16_t x = menu->mouse.x; + int16_t y = menu->mouse.y; - if (!rgui) - return; - - color_rect(rgui->frame_buf, rgui->frame_buf_pitch, - x, y-5, 1, 11, 0xFFFF); - color_rect(rgui->frame_buf, rgui->frame_buf_pitch, - x-5, y, 11, 1, 0xFFFF); + color_rect(menu, x, y - 5, 1, 11, 0xFFFF); + color_rect(menu, x - 5, y, 11, 1, 0xFFFF); } static void rgui_render(void) @@ -358,41 +314,37 @@ static void rgui_render(void) unsigned x, y, menu_type = 0; const char *dir = NULL; const char *label = NULL; - rgui_handle_t *rgui = NULL; const char *core_name = NULL; const char *core_version = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (driver.menu->need_refresh - && g_extern.is_menu - && !driver.menu->msg_force) + if (!menu) + return; + if (menu->need_refresh && g_extern.is_menu + && !menu->msg_force) return; - rgui = (rgui_handle_t*)driver.menu->userdata; + menu->mouse.ptr = menu->mouse.y / 11 - 2 + menu->begin; - if (!rgui) - return; + if (menu->mouse.wheeldown && menu->begin + < menu_list_get_size(menu->menu_list) - RGUI_TERM_HEIGHT) + menu->begin++; - driver.menu->mouse.ptr = driver.menu->mouse.y / 11 - 2 + driver.menu->begin; - - if (driver.menu->mouse.wheeldown && driver.menu->begin - < menu_list_get_size(driver.menu->menu_list) - RGUI_TERM_HEIGHT) - driver.menu->begin++; - - if (driver.menu->mouse.wheelup && driver.menu->begin > 0) - driver.menu->begin--; + if (menu->mouse.wheelup && menu->begin > 0) + menu->begin--; /* Do not scroll if all items are visible. */ - if (menu_list_get_size(driver.menu->menu_list) <= RGUI_TERM_HEIGHT) - driver.menu->begin = 0; + if (menu_list_get_size(menu->menu_list) <= RGUI_TERM_HEIGHT) + menu->begin = 0; - end = (driver.menu->begin + RGUI_TERM_HEIGHT <= - menu_list_get_size(driver.menu->menu_list)) ? - driver.menu->begin + RGUI_TERM_HEIGHT : - menu_list_get_size(driver.menu->menu_list); + end = (menu->begin + RGUI_TERM_HEIGHT <= + menu_list_get_size(menu->menu_list)) ? + menu->begin + RGUI_TERM_HEIGHT : + menu_list_get_size(menu->menu_list); - rgui_render_background(rgui); + rgui_render_background(); - menu_list_get_last_stack(driver.menu->menu_list, + menu_list_get_last_stack(menu->menu_list, &dir, &label, &menu_type); #if 0 @@ -401,9 +353,9 @@ static void rgui_render(void) get_title(label, dir, menu_type, title, sizeof(title)); - menu_ticker_line(title_buf, RGUI_TERM_WIDTH - 3, + menu_animation_ticker_line(title_buf, RGUI_TERM_WIDTH - 3, g_extern.frame_count / RGUI_TERM_START_X, title, true); - blit_line(RGUI_TERM_START_X + RGUI_TERM_START_X, RGUI_TERM_START_X, title_buf, true); + blit_line(menu, RGUI_TERM_START_X + RGUI_TERM_START_X, RGUI_TERM_START_X, title_buf, true); core_name = g_extern.menu.info.library_name; if (!core_name) @@ -411,32 +363,38 @@ static void rgui_render(void) if (!core_name) core_name = "No Core"; - core_version = g_extern.menu.info.library_version; - if (!core_version) - core_version = g_extern.system.info.library_version; - if (!core_version) - core_version = ""; + if (g_settings.menu.core_enable) + { + core_version = g_extern.menu.info.library_version; + if (!core_version) + core_version = g_extern.system.info.library_version; + if (!core_version) + core_version = ""; - disp_timedate_set_label(timedate, sizeof(timedate), 3); - snprintf(title_msg, sizeof(title_msg), "%s - %s %s", PACKAGE_VERSION, - core_name, core_version); - blit_line( - RGUI_TERM_START_X + RGUI_TERM_START_X, - (RGUI_TERM_HEIGHT * FONT_HEIGHT_STRIDE) + - RGUI_TERM_START_Y + 2, title_msg, true); + snprintf(title_msg, sizeof(title_msg), "%s - %s %s", PACKAGE_VERSION, + core_name, core_version); + blit_line(menu, + RGUI_TERM_START_X + RGUI_TERM_START_X, + (RGUI_TERM_HEIGHT * FONT_HEIGHT_STRIDE) + + RGUI_TERM_START_Y + 2, title_msg, true); + } if (g_settings.menu.timedate_enable) - blit_line( + { + disp_timedate_set_label(timedate, sizeof(timedate), 3); + + blit_line(menu, (RGUI_TERM_WIDTH * FONT_HEIGHT_STRIDE) + (60), (RGUI_TERM_HEIGHT * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y + 2, timedate, true); + } x = RGUI_TERM_START_X; y = RGUI_TERM_START_Y; - for (i = driver.menu->begin; i < end; i++, y += FONT_HEIGHT_STRIDE) + for (i = menu->begin; i < end; i++, y += FONT_HEIGHT_STRIDE) { char message[PATH_MAX_LENGTH], type_str[PATH_MAX_LENGTH], entry_title_buf[PATH_MAX_LENGTH], type_str_buf[PATH_MAX_LENGTH], @@ -446,28 +404,28 @@ static void rgui_render(void) bool selected = false; menu_file_list_cbs_t *cbs = NULL; - menu_list_get_at_offset(driver.menu->menu_list->selection_buf, i, &path, + menu_list_get_at_offset(menu->menu_list->selection_buf, i, &path, &entry_label, &type); cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(driver.menu->menu_list->selection_buf, + menu_list_get_actiondata_at_offset(menu->menu_list->selection_buf, i); if (cbs && cbs->action_get_representation) - cbs->action_get_representation(driver.menu->menu_list->selection_buf, + cbs->action_get_representation(menu->menu_list->selection_buf, &w, type, i, label, type_str, sizeof(type_str), entry_label, path, path_buf, sizeof(path_buf)); - selected = (i == driver.menu->selection_ptr); + selected = (i == menu->navigation.selection_ptr); - if (i > (driver.menu->selection_ptr + 100)) + if (i > (menu->navigation.selection_ptr + 100)) continue; - menu_ticker_line(entry_title_buf, RGUI_TERM_WIDTH - (w + 1 + 2), + menu_animation_ticker_line(entry_title_buf, RGUI_TERM_WIDTH - (w + 1 + 2), g_extern.frame_count / RGUI_TERM_START_X, path_buf, selected); - menu_ticker_line(type_str_buf, w, g_extern.frame_count / RGUI_TERM_START_X, + menu_animation_ticker_line(type_str_buf, w, g_extern.frame_count / RGUI_TERM_START_X, type_str, selected); snprintf(message, sizeof(message), "%c %-*.*s %-*s", @@ -478,116 +436,98 @@ static void rgui_render(void) w, type_str_buf); - blit_line(x, y, message, selected); + blit_line(menu, x, y, message, selected); } #ifdef GEKKO const char *message_queue; - if (driver.menu->msg_force) + if (menu->msg_force) { message_queue = msg_queue_pull(g_extern.msg_queue); - driver.menu->msg_force = false; + menu->msg_force = false; } else message_queue = driver.current_msg; - rgui_render_messagebox(message_queue); + rgui_render_messagebox( message_queue); #endif - if (driver.menu->keyboard.display) + if (menu->keyboard.display) { char msg[PATH_MAX_LENGTH]; - const char *str = *driver.menu->keyboard.buffer; + const char *str = *menu->keyboard.buffer; if (!str) str = ""; - snprintf(msg, sizeof(msg), "%s\n%s", driver.menu->keyboard.label, str); + snprintf(msg, sizeof(msg), "%s\n%s", menu->keyboard.label, str); rgui_render_messagebox(msg); } - if (driver.menu->mouse.enable) - rgui_blit_cursor(rgui); + if (menu->mouse.enable) + rgui_blit_cursor(menu); } static void *rgui_init(void) { bool ret = false; - rgui_handle_t *rgui = NULL; menu_handle_t *menu = (menu_handle_t*)calloc(1, sizeof(*menu)); if (!menu) return NULL; - menu->userdata = (rgui_handle_t*)calloc(1, sizeof(rgui_handle_t)); - - if (!menu->userdata) + menu->frame_buf.data = (uint16_t*)calloc(400 * 240, sizeof(uint16_t)); + + if (!menu->frame_buf.data) goto error; - rgui = (rgui_handle_t*)menu->userdata; - - rgui->frame_buf = (uint16_t*)malloc(400 * 240 * sizeof(uint16_t)); - - if (!rgui->frame_buf) - goto error; - - menu->width = 320; - menu->height = 240; - menu->begin = 0; - rgui->frame_buf_pitch = menu->width * sizeof(uint16_t); + menu->frame_buf.width = 320; + menu->frame_buf.height = 240; + menu->begin = 0; + menu->frame_buf.pitch = menu->frame_buf.width * sizeof(uint16_t); ret = rguidisp_init_font(menu); if (!ret) { RARCH_ERR("No font bitmap or binary, abort"); - - rarch_main_command(RARCH_CMD_QUIT_RETROARCH); goto error; } return menu; error: - if (rgui && rgui->frame_buf) - free(rgui->frame_buf); - if (menu && menu->userdata) - free(menu->userdata); if (menu) + { + if (menu->frame_buf.data) + free(menu->frame_buf.data); + if (menu->userdata) + free(menu->userdata); free(menu); + } return NULL; } static void rgui_free(void *data) { - rgui_handle_t *rgui = NULL; menu_handle_t *menu = (menu_handle_t*)data; if (!menu) return; - rgui = (rgui_handle_t*)menu->userdata; - - if (!rgui) - return; - - if (rgui->frame_buf) - free(rgui->frame_buf); - if (menu->userdata) free(menu->userdata); - driver.menu->userdata = NULL; + menu->userdata = NULL; if (menu->alloc_font) free((uint8_t*)menu->font); } -static void rgui_set_texture(void *data) +static void rgui_set_texture(void) { - menu_handle_t *menu = (menu_handle_t*)data; - rgui_handle_t *rgui = (rgui_handle_t*)menu->userdata; - - if (!menu || !rgui) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return; + if (!driver.video_data) return; if (!driver.video_poke) @@ -596,62 +536,64 @@ static void rgui_set_texture(void *data) return; driver.video_poke->set_texture_frame(driver.video_data, - rgui->frame_buf, false, menu->width, menu->height, 1.0f); + menu->frame_buf.data, false, menu->frame_buf.width, menu->frame_buf.height, 1.0f); } -static void rgui_navigation_clear(void *data, bool pending_push) +static void rgui_navigation_clear(bool pending_push) { - driver.menu->begin = 0; + menu_handle_t *menu = menu_driver_resolve(); + if (menu) + menu->begin = 0; } -static void rgui_navigation_set(void *data, bool scroll) +static void rgui_navigation_set(bool scroll) { - rgui_handle_t *rgui = NULL; - - menu_handle_t *menu = (menu_handle_t*)data; - + menu_handle_t *menu = menu_driver_resolve(); if (!menu) return; - rgui = (rgui_handle_t*)menu->userdata; - - if (!rgui) - return; - if (!scroll) return; - if (driver.menu->selection_ptr < RGUI_TERM_HEIGHT/2) - driver.menu->begin = 0; - else if (driver.menu->selection_ptr >= RGUI_TERM_HEIGHT/2 - && driver.menu->selection_ptr < - menu_list_get_size(driver.menu->menu_list) - RGUI_TERM_HEIGHT/2) - driver.menu->begin = driver.menu->selection_ptr - RGUI_TERM_HEIGHT/2; - else if (driver.menu->selection_ptr >= - menu_list_get_size(driver.menu->menu_list) - RGUI_TERM_HEIGHT/2) - driver.menu->begin = menu_list_get_size(driver.menu->menu_list) + if (menu->navigation.selection_ptr < RGUI_TERM_HEIGHT/2) + menu->begin = 0; + else if (menu->navigation.selection_ptr >= RGUI_TERM_HEIGHT/2 + && menu->navigation.selection_ptr < + menu_list_get_size(menu->menu_list) - RGUI_TERM_HEIGHT/2) + menu->begin = menu->navigation.selection_ptr - RGUI_TERM_HEIGHT/2; + else if (menu->navigation.selection_ptr >= + menu_list_get_size(menu->menu_list) - RGUI_TERM_HEIGHT/2) + menu->begin = menu_list_get_size(menu->menu_list) - RGUI_TERM_HEIGHT; } -static void rgui_navigation_set_last(void *data) +static void rgui_navigation_set_last(void) { - rgui_navigation_set(data, true); + menu_handle_t *menu = menu_driver_resolve(); + if (menu) + rgui_navigation_set(true); } -static void rgui_navigation_descend_alphabet(void *data, size_t *unused) +static void rgui_navigation_descend_alphabet(size_t *unused) { - rgui_navigation_set(data, true); + menu_handle_t *menu = menu_driver_resolve(); + if (menu) + rgui_navigation_set(true); } -static void rgui_navigation_ascend_alphabet(void *data, size_t *unused) +static void rgui_navigation_ascend_alphabet(size_t *unused) { - rgui_navigation_set(data, true); + menu_handle_t *menu = menu_driver_resolve(); + if (menu) + rgui_navigation_set(true); } -static void rgui_populate_entries(void *data, const char *path, +static void rgui_populate_entries(const char *path, const char *label, unsigned k) { - rgui_navigation_set(data, true); + menu_handle_t *menu = menu_driver_resolve(); + if (menu) + rgui_navigation_set(true); } menu_ctx_driver_t menu_ctx_rgui = { @@ -678,5 +620,6 @@ menu_ctx_driver_t menu_ctx_rgui = { NULL, NULL, rgui_entry_iterate, + NULL, "rgui", }; diff --git a/menu/drivers/rmenu.c b/menu/drivers/rmenu.c index 0f7d84883c..fa6feb614c 100644 --- a/menu/drivers/rmenu.c +++ b/menu/drivers/rmenu.c @@ -67,14 +67,16 @@ static bool menu_texture_inited =false; static int rmenu_entry_iterate(unsigned action) { const char *label = NULL; - menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(driver.menu->menu_list->selection_buf, - driver.menu->selection_ptr); + menu_file_list_cbs_t *cbs = NULL; + menu_handle_t *menu = menu_driver_resolve(); - menu_list_get_last_stack(driver.menu->menu_list, NULL, &label, NULL); + if (!menu) + return -1; + + cbs = (menu_file_list_cbs_t*)menu_list_get_actiondata_at_offset( + menu->menu_list->selection_buf, menu->navigation.selection_ptr); - if (driver.video_data && driver.menu_ctx && driver.menu_ctx->set_texture) - driver.menu_ctx->set_texture(driver.menu); + menu_list_get_last_stack(menu->menu_list, NULL, &label, NULL); if (cbs && cbs->action_iterate) return cbs->action_iterate(label, action); @@ -91,6 +93,10 @@ static void rmenu_render_messagebox(const char *message) struct font_params font_parms; size_t i, j; struct string_list *list = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; if (!message || !*message) return; @@ -101,10 +107,7 @@ static void rmenu_render_messagebox(const char *message) return; if (list->elems == 0) - { - string_list_free(list); - return; - } + goto end; j = 0; @@ -134,6 +137,8 @@ static void rmenu_render_messagebox(const char *message) } render_normal = false; +end: + string_list_free(list); } static void rmenu_render(void) @@ -148,7 +153,7 @@ static void rmenu_render(void) const char *core_name = NULL; const char *core_version = NULL; unsigned menu_type = 0; - menu_handle_t *menu = (menu_handle_t*)driver.menu; + menu_handle_t *menu = menu_driver_resolve(); if (!menu) return; @@ -163,17 +168,17 @@ static void rmenu_render(void) && !menu->msg_force) return; - if (!driver.menu->menu_list->selection_buf) + if (!menu->menu_list->selection_buf) return; - begin = (menu->selection_ptr >= (ENTRIES_HEIGHT / 2)) ? - (menu->selection_ptr - (ENTRIES_HEIGHT / 2)) : 0; - end = ((menu->selection_ptr + ENTRIES_HEIGHT) <= - menu_list_get_size(driver.menu->menu_list)) ? - menu->selection_ptr + ENTRIES_HEIGHT : - menu_list_get_size(driver.menu->menu_list); + begin = (menu->navigation.selection_ptr >= (ENTRIES_HEIGHT / 2)) ? + (menu->navigation.selection_ptr - (ENTRIES_HEIGHT / 2)) : 0; + end = ((menu->navigation.selection_ptr + ENTRIES_HEIGHT) <= + menu_list_get_size(menu->menu_list)) ? + menu->navigation.selection_ptr + ENTRIES_HEIGHT : + menu_list_get_size(menu->menu_list); - if (menu_list_get_size(driver.menu->menu_list) <= ENTRIES_HEIGHT) + if (menu_list_get_size(menu->menu_list) <= ENTRIES_HEIGHT) begin = 0; if (end - begin > ENTRIES_HEIGHT) @@ -181,11 +186,11 @@ static void rmenu_render(void) rmenu_render_background(); - menu_list_get_last_stack(driver.menu->menu_list, &dir, &label, &menu_type); + menu_list_get_last_stack(menu->menu_list, &dir, &label, &menu_type); get_title(label, dir, menu_type, title, sizeof(title)); - menu_ticker_line(title_buf, RMENU_TERM_WIDTH, + menu_animation_ticker_line(title_buf, RMENU_TERM_WIDTH, g_extern.frame_count / 15, title, true); font_parms.x = POSITION_EDGE_MIN + POSITION_OFFSET; @@ -240,28 +245,28 @@ static void rmenu_render(void) &path, &entry_label, &type); cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(driver.menu->menu_list->selection_buf, + menu_list_get_actiondata_at_offset(menu->menu_list->selection_buf, i); if (cbs && cbs->action_get_representation) - cbs->action_get_representation(driver.menu->menu_list->selection_buf, + cbs->action_get_representation(menu->menu_list->selection_buf, &w, type, i, label, type_str, sizeof(type_str), entry_label, path, path_buf, sizeof(path_buf)); - selected = (i == driver.menu->selection_ptr); + selected = (i == menu->navigation.selection_ptr); - menu_ticker_line(entry_title_buf, RMENU_TERM_WIDTH - (w + 1 + 2), + menu_animation_ticker_line(entry_title_buf, RMENU_TERM_WIDTH - (w + 1 + 2), g_extern.frame_count / 15, path, selected); - menu_ticker_line(type_str_buf, w, g_extern.frame_count / 15, + menu_animation_ticker_line(type_str_buf, w, g_extern.frame_count / 15, type_str, selected); snprintf(message, sizeof(message), "%c %s", selected ? '>' : ' ', entry_title_buf); #if 0 - blit_line(menu, x, y, message, selected); + blit_line(x, y, message, selected); #endif font_parms.x = POSITION_EDGE_MIN + POSITION_OFFSET; font_parms.y = POSITION_EDGE_MIN + POSITION_RENDER_OFFSET @@ -283,13 +288,14 @@ static void rmenu_render(void) } } -void rmenu_set_texture(void *data) +static void rmenu_set_texture(void) { - menu_handle_t *menu = (menu_handle_t*)data; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; if (menu_texture_inited) return; - if (!driver.video_data) return; if (!driver.video_poke) @@ -303,7 +309,7 @@ void rmenu_set_texture(void *data) driver.video_poke->set_texture_frame(driver.video_data, menu_texture->pixels, - true, menu->width, menu->height, 1.0f); + true, menu->frame_buf.width, menu->frame_buf.height, 1.0f); menu_texture_inited = true; } @@ -319,10 +325,10 @@ static void rmenu_wallpaper_set_defaults(char *menu_bg, size_t sizeof_menu_bg) fill_pathname_join(menu_bg, menu_bg, "main_menu.png", sizeof_menu_bg); } -static void rmenu_context_reset(void *data) +static void rmenu_context_reset(void) { char menu_bg[PATH_MAX_LENGTH]; - menu_handle_t *menu = (menu_handle_t*)data; + menu_handle_t *menu = menu_driver_resolve(); if (!menu) return; @@ -334,8 +340,8 @@ static void rmenu_context_reset(void *data) if (path_file_exists(menu_bg)) texture_image_load(menu_texture, menu_bg); - menu->width = menu_texture->width; - menu->height = menu_texture->height; + menu->frame_buf.width = menu_texture->width; + menu->frame_buf.height = menu_texture->height; menu_texture_inited = false; } @@ -358,7 +364,7 @@ static void *rmenu_init(void) return menu; } -static void rmenu_context_destroy(void *data) +static void rmenu_context_destroy(void) { texture_image_free(menu_texture); } @@ -391,5 +397,6 @@ menu_ctx_driver_t menu_ctx_rmenu = { NULL, NULL, rmenu_entry_iterate, + NULL, "rmenu", }; diff --git a/menu/drivers/rmenu_xui.cpp b/menu/drivers/rmenu_xui.cpp index 562ae0fa72..9bdc2bc7ef 100644 --- a/menu/drivers/rmenu_xui.cpp +++ b/menu/drivers/rmenu_xui.cpp @@ -46,8 +46,8 @@ #define FONT_HEIGHT_STRIDE (FONT_HEIGHT + 1) #define RXUI_TERM_START_X 15 #define RXUI_TERM_START_Y 27 -#define RXUI_TERM_WIDTH (((driver.menu->width - RXUI_TERM_START_X - 15) / (FONT_WIDTH_STRIDE))) -#define RXUI_TERM_HEIGHT (((driver.menu->height - RXUI_TERM_START_Y - 15) / (FONT_HEIGHT_STRIDE)) - 1) +#define RXUI_TERM_WIDTH (((menu->frame_buf.width - RXUI_TERM_START_X - 15) / (FONT_WIDTH_STRIDE))) +#define RXUI_TERM_HEIGHT (((menu->frame_buf.height - RXUI_TERM_START_Y - 15) / (FONT_HEIGHT_STRIDE)) - 1) HXUIOBJ m_menulist; HXUIOBJ m_menutitle; @@ -61,14 +61,16 @@ static msg_queue_t *xui_msg_queue; static int rmenu_xui_entry_iterate(unsigned action) { const char *label = NULL; - menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(driver.menu->menu_list->selection_buf, - driver.menu->selection_ptr); + menu_file_list_cbs_t *cbs = NULL; + menu_handle_t *menu = menu_driver_resolve(); - menu_list_get_last_stack(driver.menu->menu_list, NULL, &label, NULL); + if (!menu) + return -1; + + cbs = (menu_file_list_cbs_t*)menu_list_get_actiondata_at_offset( + menu->menu_list->selection_buf, menu->navigation.selection_ptr); - if (driver.video_data && driver.menu_ctx && driver.menu_ctx->set_texture) - driver.menu_ctx->set_texture(driver.menu); + menu_list_get_last_stack(menu->menu_list, NULL, &label, NULL); if (cbs && cbs->action_iterate) return cbs->action_iterate(label, action); @@ -374,33 +376,24 @@ static void xui_render_message(const char *msg) struct font_params font_parms; size_t i = 0; size_t j = 0; - - struct string_list *list = string_split(msg, "\n"); + struct string_list *list = NULL; d3d_video_t *d3d = (d3d_video_t*)driver.video_data; + if (!d3d) + return; + + list = string_split(msg, "\n"); + if (!list) return; - if (!d3d || list->elems == 0) - { - string_list_free(list); - return; - } + if (list->elems == 0) + goto end; for (i = 0; i < list->size; i++, j++) { char *msg = (char*)list->elems[i].data; unsigned msglen = strlen(msg); - #if 0 - if (msglen > RMENU_TERM_WIDTH) - { - msg[RMENU_TERM_WIDTH - 2] = '.'; - msg[RMENU_TERM_WIDTH - 1] = '.'; - msg[RMENU_TERM_WIDTH - 0] = '.'; - msg[RMENU_TERM_WIDTH + 1] = '\0'; - msglen = RMENU_TERM_WIDTH; - } - #endif float msg_width = d3d->resolution_hd_enable ? 160 : 100; float msg_height = 120; float msg_offset = 32; @@ -413,6 +406,9 @@ static void xui_render_message(const char *msg) driver.video_poke->set_osd_msg(driver.video_data, msg, &font_parms, NULL); } + +end: + string_list_free(list); } static void rmenu_xui_frame(void) @@ -421,8 +417,24 @@ static void rmenu_xui_frame(void) XUIMessageRender msgRender; D3DXMATRIX matOrigView; D3DVIEWPORT vp_full; - d3d_video_t *d3d = (d3d_video_t*)driver.video_data; - LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev; + LPDIRECT3DDEVICE d3dr; + d3d_video_t *d3d = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; + + d3d = (d3d_video_t*)driver.video_data; + + if (!d3d) + return; + + d3dr = (LPDIRECT3DDEVICE)d3d->dev; + + if (!d3dr) + return; + + (void)menu; vp_full.X = 0; vp_full.Y = 0; @@ -540,21 +552,24 @@ static void rmenu_xui_render(void) char title[PATH_MAX_LENGTH]; const char *dir = NULL, *label = NULL; unsigned menu_type = 0; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu || driver.menu->need_refresh && - g_extern.is_menu && !driver.menu->msg_force) + if (!menu) + return; + if (menu->need_refresh && + g_extern.is_menu && !menu->msg_force) return; rmenu_xui_render_background(); - menu_list_get_last_stack(driver.menu->menu_list, &dir, &label, &menu_type); + menu_list_get_last_stack(menu->menu_list, &dir, &label, &menu_type); if (XuiHandleIsValid(m_menutitle)) { get_title(label, dir, menu_type, title, sizeof(title)); mbstowcs(strw_buffer, title, sizeof(strw_buffer) / sizeof(wchar_t)); XuiTextElementSetText(m_menutitle, strw_buffer); - menu_ticker_line(title, RXUI_TERM_WIDTH - 3, g_extern.frame_count / 15, title, true); + menu_animation_ticker_line(title, RXUI_TERM_WIDTH - 3, g_extern.frame_count / 15, title, true); } if (XuiHandleIsValid(m_menutitle)) @@ -579,7 +594,7 @@ static void rmenu_xui_render(void) XuiTextElementSetText(m_menutitlebottom, strw_buffer); } - end = menu_list_get_size(driver.menu->menu_list); + end = menu_list_get_size(menu->menu_list); for (i = 0; i < end; i++) { wchar_t msg_left[PATH_MAX_LENGTH], msg_right[PATH_MAX_LENGTH]; @@ -588,15 +603,15 @@ static void rmenu_xui_render(void) unsigned type = 0, w = 0; menu_file_list_cbs_t *cbs = NULL; - menu_list_get_at_offset(driver.menu->menu_list->selection_buf, i, &path, + menu_list_get_at_offset(menu->menu_list->selection_buf, i, &path, &entry_label, &type); cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(driver.menu->menu_list->selection_buf, + menu_list_get_actiondata_at_offset(menu->menu_list->selection_buf, i); if (cbs && cbs->action_get_representation) - cbs->action_get_representation(driver.menu->menu_list->selection_buf, + cbs->action_get_representation(menu->menu_list->selection_buf, &w, type, i, label, type_str, sizeof(type_str), entry_label, path, @@ -606,54 +621,57 @@ static void rmenu_xui_render(void) mbstowcs(msg_right, type_str, sizeof(msg_right) / sizeof(wchar_t)); rmenu_xui_set_list_text(i, msg_left, msg_right); } - XuiListSetCurSelVisible(m_menulist, driver.menu->selection_ptr); + XuiListSetCurSelVisible(m_menulist, menu->navigation.selection_ptr); - if (driver.menu->keyboard.display) + if (menu->keyboard.display) { char msg[1024]; - const char *str = *driver.menu->keyboard.buffer; + const char *str = *menu->keyboard.buffer; if (!str) str = ""; - snprintf(msg, sizeof(msg), "%s\n%s", driver.menu->keyboard.label, str); + snprintf(msg, sizeof(msg), "%s\n%s", menu->keyboard.label, str); rmenu_xui_render_messagebox(msg); } } -static void rmenu_xui_populate_entries(void *data, const char *path, +static void rmenu_xui_populate_entries(const char *path, const char *label, unsigned i) { - menu_handle_t *menu = (menu_handle_t*)data; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; + (void)label; (void)path; - XuiListSetCurSelVisible(m_menulist, menu->selection_ptr); + XuiListSetCurSelVisible(m_menulist, menu->navigation.selection_ptr); } -static void rmenu_xui_navigation_clear(void *data, bool pending_push) +static void rmenu_xui_navigation_clear(bool pending_push) { - menu_handle_t *menu = (menu_handle_t*)data; - - (void)pending_push; + menu_handle_t *menu = menu_driver_resolve(); if (menu) - XuiListSetCurSelVisible(m_menulist, menu->selection_ptr); + XuiListSetCurSelVisible(m_menulist, menu->navigation.selection_ptr); } -static void rmenu_xui_navigation_set_visible(void *data) +static void rmenu_xui_navigation_set_visible(void) { - menu_handle_t *menu = (menu_handle_t*)data; - XuiListSetCurSelVisible(m_menulist, menu->selection_ptr); + menu_handle_t *menu = menu_driver_resolve(); + + if (menu) + XuiListSetCurSelVisible(m_menulist, menu->navigation.selection_ptr); } -static void rmenu_xui_navigation_alphabet(void *data, size_t *ptr_out) +static void rmenu_xui_navigation_alphabet(size_t *ptr_out) { XuiListSetCurSelVisible(m_menulist, *ptr_out); } -static void rmenu_xui_list_insert(void *data, +static void rmenu_xui_list_insert(file_list_t *list, const char *path, const char *, size_t list_size) { - (void)data; wchar_t buf[PATH_MAX_LENGTH]; XuiListInsertItems(m_menulist, list_size, 1); @@ -661,12 +679,11 @@ static void rmenu_xui_list_insert(void *data, XuiListSetText(m_menulist, list_size, buf); } -static void rmenu_xui_list_delete(void *data, size_t idx, +static void rmenu_xui_list_delete(file_list_t *list, size_t idx, size_t list_size) { int x = XuiListGetItemCount( m_menulist ); - (void)data; (void)idx; if( list_size > x ) @@ -675,15 +692,13 @@ static void rmenu_xui_list_delete(void *data, size_t idx, XuiListDeleteItems(m_menulist, 0, list_size); } -static void rmenu_xui_list_clear(void *data) +static void rmenu_xui_list_clear(file_list_t *list) { - (void)data; XuiListDeleteItems(m_menulist, 0, XuiListGetItemCount(m_menulist)); } -static void rmenu_xui_list_set_selection(void *data) +static void rmenu_xui_list_set_selection(file_list_t *list) { - file_list_t *list = (file_list_t*)data; if (list) XuiListSetCurSel(m_menulist, file_list_get_directory_ptr(list)); } @@ -698,6 +713,7 @@ menu_ctx_driver_t menu_ctx_rmenu_xui = { NULL, NULL, rmenu_xui_populate_entries, + NULL, rmenu_xui_navigation_clear, rmenu_xui_navigation_set_visible, rmenu_xui_navigation_set_visible, @@ -711,5 +727,6 @@ menu_ctx_driver_t menu_ctx_rmenu_xui = { NULL, rmenu_xui_list_set_selection, rmenu_xui_entry_iterate, + NULL, "rmenu_xui", }; diff --git a/menu/drivers/shared.h b/menu/drivers/shared.h index b78e3b175d..01928db5e5 100644 --- a/menu/drivers/shared.h +++ b/menu/drivers/shared.h @@ -49,14 +49,16 @@ static INLINE void get_title(const char *label, const char *dir, #endif if (!strcmp(label, "core_list")) snprintf(title, sizeof_title, "CORE SELECTION %s", dir); - else if (!strcmp(label, "core_manager_list")) + else if (!strcmp(label, "core_updater_list")) snprintf(title, sizeof_title, "CORE UPDATER %s", dir); + else if (!strcmp(label, "deferred_database_manager_list")) + snprintf(title, sizeof_title, "DATABASE SELECTION - %s", (elem0_path[0] != '\0') ? path_basename(elem0_path) : ""); else if (!strcmp(label, "database_manager_list")) - snprintf(title, sizeof_title, "DATABASE SELECTION %s", dir); + snprintf(title, sizeof_title, "DATABASE SELECTION"); else if (!strcmp(label, "cursor_manager_list")) - snprintf(title, sizeof_title, "DATABASE CURSOR SELECTION %s", dir); + snprintf(title, sizeof_title, "DATABASE CURSOR SELECTION"); else if (!strcmp(label, "deferred_cursor_manager_list")) - snprintf(title, sizeof_title, "DATABASE CURSOR LIST %s", dir); + snprintf(title, sizeof_title, "DATABASE CURSOR LIST - %s", (elem0_path[0] != '\0') ? path_basename(elem0_path) : ""); else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_developer")) snprintf(title, sizeof_title, "DATABASE CURSOR LIST (FILTER: DEVELOPER - %s)", elem0_path); else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_publisher")) @@ -93,9 +95,9 @@ static INLINE void get_title(const char *label, const char *dir, snprintf(title, sizeof_title, "CONFIG %s", dir); else if (!strcmp(label, "disk_image_append")) snprintf(title, sizeof_title, "DISK APPEND %s", dir); - else if (!strcmp(elem0, "Video Options")) + else if (!strcmp(elem0, "Video Settings")) { - strlcpy(title, "VIDEO OPTIONS", sizeof_title); + strlcpy(title, "VIDEO SETTINGS", sizeof_title); if (!strcmp(elem1, "Monitor")) strlcat(title, " - MONITOR", sizeof_title); else if (!strcmp(elem1, "Aspect")) @@ -109,11 +111,11 @@ static INLINE void get_title(const char *label, const char *dir, else if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); } - else if (!strcmp(elem0, "Input Options") || + else if (!strcmp(elem0, "Input Settings") || menu_type == MENU_SETTINGS_CUSTOM_BIND || menu_type == MENU_SETTINGS_CUSTOM_BIND_KEYBOARD) { - strlcpy(title, "INPUT OPTIONS", sizeof_title); + strlcpy(title, "INPUT SETTINGS", sizeof_title); if (strstr(elem1, "User")) strlcat(title, " - USER", sizeof_title); else if (!strcmp(elem1, "Meta Keys")) @@ -127,15 +129,15 @@ static INLINE void get_title(const char *label, const char *dir, else if (!strcmp(elem1, "Miscellaneous")) strlcat(title, " - MISCELLANEOUS", sizeof_title); } - else if (!strcmp(elem0, "Overlay Options")) + else if (!strcmp(elem0, "Overlay Settings")) { - strlcpy(title, "OVERLAY OPTIONS", sizeof_title); + strlcpy(title, "OVERLAY SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); } - else if (!strcmp(elem0, "Menu Options")) + else if (!strcmp(elem0, "Menu Settings")) { - strlcpy(title, "MENU OPTIONS", sizeof_title); + strlcpy(title, "MENU SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); else if (!strcmp(elem1, "Navigation")) @@ -145,35 +147,35 @@ static INLINE void get_title(const char *label, const char *dir, else if (!strcmp(elem1, "Browser")) strlcat(title, " - BROWSER", sizeof_title); } - else if (!strcmp(elem0, "Onscreen Keyboard Overlay Options")) + else if (!strcmp(elem0, "Onscreen Keyboard Overlay Settings")) { - strlcpy(title, "ONSCREEN KEYBOARD OVERLAY OPTIONS", sizeof_title); + strlcpy(title, "ONSCREEN KEYBOARD OVERLAY SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); } - else if (!strcmp(elem0, "Patch Options")) + else if (!strcmp(elem0, "Patch Settings")) { - strlcpy(title, "PATCH OPTIONS", sizeof_title); + strlcpy(title, "PATCH SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); } - else if (!strcmp(elem0, "UI Options")) + else if (!strcmp(elem0, "UI Settings")) { - strlcpy(title, "UI OPTIONS", sizeof_title); + strlcpy(title, "UI SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); } - else if (!strcmp(elem0, "Playlist Options")) + else if (!strcmp(elem0, "Playlist Settings")) { - strlcpy(title, "PLAYLIST OPTIONS", sizeof_title); + strlcpy(title, "PLAYLIST SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); if (!strcmp(elem1, "History")) strlcat(title, " - HISTORY", sizeof_title); } - else if (!strcmp(elem0, "Network Options")) + else if (!strcmp(elem0, "Network Settings")) { - strlcpy(title, "NETWORK OPTIONS", sizeof_title); + strlcpy(title, "NETWORK SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); if (!strcmp(elem1, "Netplay")) @@ -181,31 +183,35 @@ static INLINE void get_title(const char *label, const char *dir, if (!strcmp(elem1, "Miscellaneous")) strlcat(title, " - MISCELLANEOUS", sizeof_title); } - else if (!strcmp(elem0, "Core Updater Options")) + else if (!strcmp(elem0, "Core Updater Settings")) { - strlcpy(title, "CORE UPDATER OPTIONS", sizeof_title); + strlcpy(title, "CORE UPDATER SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); } - else if (!strcmp(elem0, "User Options")) + else if (!strcmp(elem0, "User Settings")) { - strlcpy(title, "USER OPTIONS", sizeof_title); + strlcpy(title, "USER SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); } - else if (!strcmp(elem0, "Path Options")) + else if (!strcmp(elem0, "Path Settings")) { - strlcpy(title, "PATH OPTIONS", sizeof_title); + strlcpy(title, "PATH SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); if (!strcmp(elem1, "Paths")) strlcat(title, " - PATHS", sizeof_title); } + else if (!strcmp(label, "management")) + strlcpy(title, "MANAGEMENT", sizeof_title); + else if (!strcmp(label, "options")) + strlcpy(title, "OPTIONS", sizeof_title); else if (!strcmp(label, "settings")) strlcpy(title, "SETTINGS", sizeof_title); - else if (!strcmp(elem0, "Driver Options")) + else if (!strcmp(elem0, "Driver Settings")) { - strlcpy(title, "DRIVER OPTIONS", sizeof_title); + strlcpy(title, "DRIVER SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); } @@ -215,15 +221,15 @@ static INLINE void get_title(const char *label, const char *dir, strlcpy(title, "FRONTEND PERFORMANCE COUNTERS", sizeof_title); else if (!strcmp(label, "core_counters")) strlcpy(title, "CORE PERFORMANCE COUNTERS", sizeof_title); - else if (!strcmp(elem0, "Shader Options")) + else if (!strcmp(elem0, "Shader Settings")) { - strlcpy(title, "SHADER OPTIONS", sizeof_title); + strlcpy(title, "SHADER SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); } - else if (!strcmp(elem0, "Archive Options")) + else if (!strcmp(elem0, "Archive Settings")) { - strlcpy(title, "ARCHIVE OPTIONS", sizeof_title); + strlcpy(title, "ARCHIVE SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); } @@ -231,21 +237,21 @@ static INLINE void get_title(const char *label, const char *dir, strlcpy(title, "SHADER PARAMETERS (CURRENT)", sizeof_title); else if (!strcmp(label, "video_shader_preset_parameters")) strlcpy(title, "SHADER PARAMETERS (MENU PRESET)", sizeof_title); - else if (!strcmp(elem0, "Font Options")) + else if (!strcmp(elem0, "Font Settings")) { - strlcpy(title, "FONT OPTIONS", sizeof_title); + strlcpy(title, "FONT SETTINGS", sizeof_title); if (!strcmp(elem1, "Messages")) strlcat(title, " - MESSAGES", sizeof_title); } - else if (!strcmp(elem0, "General Options")) + else if (!strcmp(elem0, "General Settings")) { - strlcpy(title, "GENERAL OPTIONS", sizeof_title); + strlcpy(title, "GENERAL SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); } - else if (!strcmp(elem0, "Audio Options")) + else if (!strcmp(elem0, "Audio Settings")) { - strlcpy(title, "AUDIO OPTIONS", sizeof_title); + strlcpy(title, "AUDIO SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); else if (!strcmp(elem1, "Synchronization")) @@ -257,15 +263,17 @@ static INLINE void get_title(const char *label, const char *dir, strlcpy(title, "DISK OPTIONS", sizeof_title); else if (!strcmp(label, "core_options")) strlcpy(title, "CORE OPTIONS", sizeof_title); + else if (!strcmp(label, "shader_options")) + strlcpy(title, "SHADER OPTIONS", sizeof_title); else if (!strcmp(label, "core_cheat_options")) strlcpy(title, "CORE CHEAT OPTIONS", sizeof_title); else if (!strcmp(label, "core_input_remapping_options")) strlcpy(title, "CORE INPUT REMAPPING OPTIONS", sizeof_title); else if (!strcmp(label, "core_information")) strlcpy(title, "CORE INFO", sizeof_title); - else if (!strcmp(elem0, "Privacy Options")) + else if (!strcmp(elem0, "Privacy Settings")) { - strlcpy(title, "PRIVACY OPTIONS", sizeof_title); + strlcpy(title, "PRIVACY SETTINGS", sizeof_title); if (!strcmp(elem1, "State")) strlcat(title, " - STATE", sizeof_title); } diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 30fe093ce1..44f4391a5d 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -21,14 +21,15 @@ #include #include "../menu.h" -#include "../menu_input.h" +#include "../menu_animation.h" +#include "../menu_texture.h" + #include #include "../../gfx/gl_common.h" #include "../../gfx/video_thread_wrapper.h" #include #include "shared.h" -#include "../menu_animation.h" #ifndef XMB_THEME #define XMB_THEME "monochrome" @@ -51,8 +52,7 @@ typedef struct enum { - XMB_TEXTURE_BG = 0, - XMB_TEXTURE_SETTINGS, + XMB_TEXTURE_SETTINGS = 0, XMB_TEXTURE_SETTING, XMB_TEXTURE_SUBSETTING, XMB_TEXTURE_ARROW, @@ -84,45 +84,120 @@ typedef struct xmb_handle { file_list_t *menu_stack_old; file_list_t *selection_buf_old; - size_t cat_selection_ptr_old; size_t selection_ptr_old; - int active_category; - int active_category_old; int depth; int old_depth; - char icon_dir[4]; char box_message[PATH_MAX_LENGTH]; - char title[PATH_MAX_LENGTH]; - struct xmb_texture_item textures[XMB_TEXTURE_LAST]; - int icon_size; float x; - float categories_x; float alpha; - float arrow_alpha; - float hspacing; - float vspacing; - float margin_left; - float margin_top; - float title_margin_left; - float title_margin_top; - float title_margin_bottom; - float label_margin_left; - float label_margin_top; - float setting_margin_left; - float above_item_offset; - float active_item_factor; - float under_item_offset; - float above_subitem_offset; - float c_active_zoom; - float c_active_alpha; - float i_active_zoom; - float i_active_alpha; - float c_passive_zoom; - float c_passive_alpha; - float i_passive_zoom; - float i_passive_alpha; - void *font; - int font_size; + + struct + { + struct + { + float left; + float top; + + } screen; + + struct + { + float left; + } setting; + + struct + { + float left; + float top; + float bottom; + } title; + + struct + { + float left; + float top; + } label; + } margins; + + char title_name[PATH_MAX_LENGTH]; + + struct + { + struct + { + float alpha; + } arrow; + + struct xmb_texture_item bg; + struct xmb_texture_item list[XMB_TEXTURE_LAST]; + } textures; + + struct + { + float item; + float subitem; + } above_offset; + + struct + { + float item; + } under_offset; + + struct + { + struct + { + float horizontal; + float vertical; + } spacing; + + char dir[4]; + int size; + } icon; + + + struct + { + struct + { + float zoom; + float alpha; + int idx; + int idx_old; + } active; + + struct + { + float zoom; + float alpha; + } passive; + + float x_pos; + size_t selection_ptr_old; + } categories; + + struct + { + struct + { + float zoom; + float alpha; + float factor; + } active; + + struct + { + float zoom; + float alpha; + } passive; + } item; + + struct + { + void *buf; + int size; + } font; + xmb_node_t settings_node; bool prevent_populate; } xmb_handle_t; @@ -141,27 +216,20 @@ static const GLfloat rmb_tex_coord[] = { 1, 0, }; -static float xmb_item_y(int i, size_t current) +static float xmb_item_y(xmb_handle_t *xmb, int i, size_t current) { - float iy; - xmb_handle_t *xmb; - - xmb = (xmb_handle_t*)driver.menu->userdata; - if (!xmb) - return 0; - - iy = xmb->vspacing; + float iy = xmb->icon.spacing.vertical; if (i < current) if (xmb->depth > 1) - iy *= (i - (int)current + xmb->above_subitem_offset); + iy *= (i - (int)current + xmb->above_offset.subitem); else - iy *= (i - (int)current + xmb->above_item_offset); + iy *= (i - (int)current + xmb->above_offset.item); else - iy *= (i - (int)current + xmb->under_item_offset); + iy *= (i - (int)current + xmb->under_offset.item); if (i == current) - iy = xmb->vspacing * xmb->active_item_factor; + iy = xmb->icon.spacing.vertical * xmb->item.active.factor; return iy; } @@ -169,14 +237,17 @@ static float xmb_item_y(int i, size_t current) static int xmb_entry_iterate(unsigned action) { const char *label = NULL; - menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(driver.menu->menu_list->selection_buf, - driver.menu->selection_ptr); + menu_file_list_cbs_t *cbs = NULL; + menu_handle_t *menu = menu_driver_resolve(); - menu_list_get_last_stack(driver.menu->menu_list, NULL, &label, NULL); + if (!menu) + return -1; + + cbs = (menu_file_list_cbs_t*) + menu_list_get_actiondata_at_offset(menu->menu_list->selection_buf, + menu->navigation.selection_ptr); - if (driver.video_data && driver.menu_ctx && driver.menu_ctx->set_texture) - driver.menu_ctx->set_texture(driver.menu); + menu_list_get_last_stack(menu->menu_list, NULL, &label, NULL); if (cbs && cbs->action_iterate) return cbs->action_iterate(label, action); @@ -227,16 +298,12 @@ static char *xmb_str_replace (const char *string, return newstr; } -static void xmb_draw_icon(GLuint texture, float x, float y, +static void xmb_draw_icon(gl_t *gl, xmb_handle_t *xmb, + GLuint texture, float x, float y, float alpha, float rotation, float scale_factor) { struct gl_coords coords; math_matrix_4x4 mymat, mrot, mscal; - gl_t *gl; - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; - - if (!xmb) - return; if (alpha > xmb->alpha) alpha = xmb->alpha; @@ -244,16 +311,11 @@ static void xmb_draw_icon(GLuint texture, float x, float y, if (alpha == 0) return; - gl = (gl_t*)video_driver_resolve(NULL); - - if (!gl) - return; - if ( - x < -xmb->icon_size/2 || + x < -xmb->icon.size/2 || x > gl->win_width || - y < xmb->icon_size/2 || - y > gl->win_height + xmb->icon_size) + y < xmb->icon.size/2 || + y > gl->win_height + xmb->icon.size) return; GLfloat color[] = { @@ -266,7 +328,7 @@ static void xmb_draw_icon(GLuint texture, float x, float y, if (gl->shader && gl->shader->use) gl->shader->use(gl, GL_SHADER_STOCK_BLEND); - glViewport(x, gl->win_height - y, xmb->icon_size, xmb->icon_size); + glViewport(x, gl->win_height - y, xmb->icon.size, xmb->icon.size); coords.vertices = 4; coords.vertex = rmb_vertex; @@ -290,16 +352,11 @@ static void xmb_draw_icon(GLuint texture, float x, float y, glDisable(GL_BLEND); } -static void xmb_draw_text(const char *str, float x, +static void xmb_draw_text(gl_t *gl, xmb_handle_t *xmb, const char *str, float x, float y, float scale_factor, float alpha, bool align_right) { - gl_t *gl = NULL; uint8_t a8 = 0; struct font_params params = {0}; - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; - - if (!xmb) - return; if (alpha > xmb->alpha) alpha = xmb->alpha; @@ -309,13 +366,8 @@ static void xmb_draw_text(const char *str, float x, if (a8 == 0) return; - gl = (gl_t*)video_driver_resolve(NULL); - - if (!gl) - return; - - if (x < -xmb->icon_size || x > gl->win_width + xmb->icon_size - || y < -xmb->icon_size || y > gl->win_height + xmb->icon_size) + if (x < -xmb->icon.size || x > gl->win_width + xmb->icon.size + || y < -xmb->icon.size || y > gl->win_height + xmb->icon.size) return; gl_set_viewport(gl, gl->win_width, gl->win_height, false, false); @@ -331,15 +383,14 @@ static void xmb_draw_text(const char *str, float x, if (driver.video_data && driver.video_poke && driver.video_poke->set_osd_msg) driver.video_poke->set_osd_msg(driver.video_data, - str, ¶ms, xmb->font); + str, ¶ms, xmb->font.buf); } -static void xmb_render_background(bool force_transparency) +static void xmb_render_background(gl_t *gl, xmb_handle_t *xmb, + bool force_transparency) { struct gl_coords coords; float alpha = 0.75f; - gl_t *gl = NULL; - xmb_handle_t *xmb = NULL; static const GLfloat vertex[] = { 0, 0, 1, 0, @@ -354,14 +405,6 @@ static void xmb_render_background(bool force_transparency) 1, 0, }; - if (!driver.menu) - return; - - xmb = (xmb_handle_t*)driver.menu->userdata; - - if (!xmb) - return; - GLfloat color[] = { 1.0f, 1.0f, 1.0f, xmb->alpha, 1.0f, 1.0f, 1.0f, xmb->alpha, @@ -379,14 +422,8 @@ static void xmb_render_background(bool force_transparency) 0.0f, 0.0f, 0.0f, alpha, }; - gl = (gl_t*)video_driver_resolve(NULL); - - if (!gl) - return; - glViewport(0, 0, gl->win_width, gl->win_height); - coords.vertices = 4; coords.vertex = vertex; coords.tex_coord = tex_coord; @@ -395,10 +432,10 @@ static void xmb_render_background(bool force_transparency) if ((g_settings.menu.pause_libretro || !g_extern.main_is_init || g_extern.libretro_dummy) && !force_transparency - && xmb->textures[XMB_TEXTURE_BG].id) + && xmb->textures.bg.id) { coords.color = color; - glBindTexture(GL_TEXTURE_2D, xmb->textures[XMB_TEXTURE_BG].id); + glBindTexture(GL_TEXTURE_2D, xmb->textures.bg.id); } else { @@ -419,7 +456,13 @@ static void xmb_render_background(bool force_transparency) static void xmb_get_message(const char *message) { - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + xmb_handle_t *xmb = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; + + xmb = (xmb_handle_t*)menu->userdata; if (!xmb || !message || !*message) return; @@ -432,10 +475,21 @@ static void xmb_render_messagebox(const char *message) int x, y; unsigned i; struct string_list *list = NULL; - gl_t *gl = (gl_t*)video_driver_resolve(NULL); - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + gl_t *gl = NULL; + xmb_handle_t *xmb = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!gl || !xmb) + if (!menu) + return; + + xmb = (xmb_handle_t*)menu->userdata; + + if (!xmb) + return; + + gl = (gl_t*)video_driver_resolve(NULL); + + if (!gl) return; list = string_split(message, "\n"); @@ -443,22 +497,20 @@ static void xmb_render_messagebox(const char *message) return; if (list->elems == 0) - { - string_list_free(list); - return; - } + goto end; - x = gl->win_width / 2 - strlen(list->elems[0].data) * xmb->font_size / 4; - y = gl->win_height / 2 - list->size * xmb->font_size / 2; + x = gl->win_width / 2 - strlen(list->elems[0].data) * xmb->font.size / 4; + y = gl->win_height / 2 - list->size * xmb->font.size / 2; for (i = 0; i < list->size; i++) { const char *msg = list->elems[i].data; if (msg) - xmb_draw_text(msg, x, y + i * xmb->font_size, 1, 1, 0); + xmb_draw_text(gl, xmb, msg, x, y + i * xmb->font.size, 1, 1, 0); } +end: string_list_free(list); } @@ -466,46 +518,52 @@ static void xmb_selection_pointer_changed(void) { int i; unsigned current, end; - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + xmb_handle_t *xmb = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; + + xmb = (xmb_handle_t*)menu->userdata; if (!xmb) return; - current = driver.menu->selection_ptr; - end = menu_list_get_size(driver.menu->menu_list); + current = menu->navigation.selection_ptr; + end = menu_list_get_size(menu->menu_list); for (i = 0; i < end; i++) { float iy; - float ia = xmb->i_passive_alpha; - float iz = xmb->i_passive_zoom; + float ia = xmb->item.passive.alpha; + float iz = xmb->item.passive.zoom; xmb_node_t *node = (xmb_node_t*)file_list_get_userdata_at_offset( - driver.menu->menu_list->selection_buf, i); + menu->menu_list->selection_buf, i); if (!node) continue; - iy = xmb_item_y(i, current); + iy = xmb_item_y(xmb, i, current); if (i == current) { - ia = xmb->i_active_alpha; - iz = xmb->i_active_zoom; + ia = xmb->item.active.alpha; + iz = xmb->item.active.zoom; } - add_tween(XMB_DELAY, ia, &node->alpha, &inOutQuad, NULL); - add_tween(XMB_DELAY, ia, &node->label_alpha, &inOutQuad, NULL); - add_tween(XMB_DELAY, iz, &node->zoom, &inOutQuad, NULL); - add_tween(XMB_DELAY, iy, &node->y, &inOutQuad, NULL); + menu_animation_push(menu->animation, XMB_DELAY, ia, &node->alpha, EASING_IN_OUT_QUAD, NULL); + menu_animation_push(menu->animation, XMB_DELAY, ia, &node->label_alpha, EASING_IN_OUT_QUAD, NULL); + menu_animation_push(menu->animation, XMB_DELAY, iz, &node->zoom, EASING_IN_OUT_QUAD, NULL); + menu_animation_push(menu->animation, XMB_DELAY, iy, &node->y, EASING_IN_OUT_QUAD, NULL); } } -static void xmb_list_open_old(file_list_t *list, int dir, size_t current) +static void xmb_list_open_old(xmb_handle_t *xmb, file_list_t *list, int dir, size_t current) { int i; - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + menu_handle_t *menu = menu_driver_resolve(); - if (!xmb) + if (!menu) return; for (i = 0; i < file_list_get_size(list); i++) @@ -517,30 +575,29 @@ static void xmb_list_open_old(file_list_t *list, int dir, size_t current) continue; if (i == current) - ia = xmb->i_active_alpha; + ia = xmb->item.active.alpha; if (dir == -1) ia = 0; - add_tween(XMB_DELAY, ia, &node->alpha, &inOutQuad, NULL); - add_tween(XMB_DELAY, 0, &node->label_alpha, &inOutQuad, NULL); - add_tween(XMB_DELAY, xmb->icon_size*dir*-2, &node->x, &inOutQuad, NULL); + menu_animation_push(menu->animation, XMB_DELAY, ia, &node->alpha, EASING_IN_OUT_QUAD, NULL); + menu_animation_push(menu->animation, XMB_DELAY, 0, &node->label_alpha, EASING_IN_OUT_QUAD, NULL); + menu_animation_push(menu->animation, XMB_DELAY, xmb->icon.size * dir * -2, &node->x, EASING_IN_OUT_QUAD, NULL); } } -static void xmb_list_open_new(file_list_t *list, int dir, size_t current) +static void xmb_list_open_new(xmb_handle_t *xmb, file_list_t *list, int dir, size_t current) { int i; - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + menu_handle_t *menu = menu_driver_resolve(); - if (!xmb) + if (!menu) return; for (i = 0; i < file_list_get_size(list); i++) { - float iy = 0; xmb_node_t *node = (xmb_node_t*)file_list_get_userdata_at_offset(list, i); - if (!xmb) + if (!node) continue; if (dir == 1 || (dir == -1 && i != current)) @@ -549,9 +606,8 @@ static void xmb_list_open_new(file_list_t *list, int dir, size_t current) if (dir == 1 || dir == -1) node->label_alpha = 0; - node->x = xmb->icon_size*dir*2; - - node->y = xmb_item_y(i, current); + node->x = xmb->icon.size * dir * 2; + node->y = xmb_item_y(xmb, i, current); if (i == current) node->zoom = 1; @@ -561,87 +617,33 @@ static void xmb_list_open_new(file_list_t *list, int dir, size_t current) float ia; xmb_node_t *node = (xmb_node_t*)file_list_get_userdata_at_offset(list, i); - if (!xmb) + if (!node) continue; - ia = xmb->i_passive_alpha; + ia = xmb->item.passive.alpha; if (i == current) - ia = xmb->i_active_alpha; + ia = xmb->item.active.alpha; - add_tween(XMB_DELAY, ia, &node->alpha, &inOutQuad, NULL); - add_tween(XMB_DELAY, ia, &node->label_alpha, &inOutQuad, NULL); - add_tween(XMB_DELAY, 0, &node->x, &inOutQuad, NULL); + menu_animation_push(menu->animation, XMB_DELAY, ia, &node->alpha, EASING_IN_OUT_QUAD, NULL); + menu_animation_push(menu->animation, XMB_DELAY, ia, &node->label_alpha, EASING_IN_OUT_QUAD, NULL); + menu_animation_push(menu->animation, XMB_DELAY, 0, &node->x, EASING_IN_OUT_QUAD, NULL); } xmb->old_depth = xmb->depth; } -static GLuint xmb_png_texture_load_(const char * file_name) -{ - struct texture_image ti = {0}; - GLuint texture = 0; - - if (! path_file_exists(file_name)) - return 0; - - texture_image_load(&ti, file_name); - - /* Generate the OpenGL texture object */ - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexImage2D(GL_TEXTURE_2D, 0, driver.gfx_use_rgba ? - GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, - ti.width, ti.height, 0, - driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, - RARCH_GL_FORMAT32, ti.pixels); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glGenerateMipmap(GL_TEXTURE_2D); - - free(ti.pixels); - - return texture; -} - -static int xmb_png_texture_load_wrap(void *data) -{ - const char *filename = (const char*)data; - return xmb_png_texture_load_(filename); -} - -static GLuint xmb_png_texture_load(const char* file_name) -{ - if (g_settings.video.threaded - && !g_extern.system.hw_render_callback.context_type) - { - thread_video_t *thr = (thread_video_t*)driver.video_data; - thr->cmd_data.custom_command.method = xmb_png_texture_load_wrap; - thr->cmd_data.custom_command.data = (void*)file_name; - thr->send_cmd_func(thr, CMD_CUSTOM_COMMAND); - thr->wait_reply_func(thr, CMD_CUSTOM_COMMAND); - - return thr->cmd_data.custom_command.return_value; - } - - return xmb_png_texture_load_(file_name); -} - -static xmb_node_t* xmb_node_for_core(int i) +static xmb_node_t* xmb_get_userdata_from_core(xmb_handle_t *xmb, int i) { core_info_t *info = NULL; - core_info_list_t *info_list = NULL; xmb_node_t *node = NULL; - - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; - - if (!xmb) - return NULL; - - info_list = (core_info_list_t*)g_extern.core_info; + core_info_list_t *info_list = (core_info_list_t*)g_extern.core_info; if (!info_list) return NULL; + if (!info_list->count) + return NULL; + info = (core_info_t*)&info_list->list[i]; if (!info) @@ -665,85 +667,99 @@ static xmb_node_t* xmb_node_for_core(int i) if (!node) return NULL; - node->alpha = xmb->c_passive_alpha; - node->zoom = xmb->c_passive_zoom; + node->alpha = xmb->categories.passive.alpha; + node->zoom = xmb->categories.passive.zoom; - if ((i + 1) == xmb->active_category) + if ((i + 1) == xmb->categories.active.idx) { - node->alpha = xmb->c_active_alpha; - node->zoom = xmb->c_active_zoom; + node->alpha = xmb->categories.active.alpha; + node->zoom = xmb->categories.active.zoom; } return node; } -static void xmb_list_switch_old(file_list_t *list, int dir, size_t current) +static void xmb_push_animations(xmb_node_t *node, float ia, float ix) { - int i; - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; - - if (!xmb) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return; - for (i = 0; i < file_list_get_size(list); i++) + menu_animation_push(menu->animation, XMB_DELAY, ia, &node->alpha, EASING_IN_OUT_QUAD, NULL); + menu_animation_push(menu->animation, XMB_DELAY, ia, &node->label_alpha, EASING_IN_OUT_QUAD, NULL); + menu_animation_push(menu->animation, XMB_DELAY, ix, &node->x, EASING_IN_OUT_QUAD, NULL); +} + +static void xmb_list_switch_old(xmb_handle_t *xmb, file_list_t *list, int dir, size_t current) +{ + int i; + size_t end = 0; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; + + end = file_list_get_size(list); + + for (i = 0; i < end; i++) { xmb_node_t *node = (xmb_node_t*) file_list_get_userdata_at_offset(list, i); + float ia = 0; - if (!xmb) + if (!node) continue; - add_tween(XMB_DELAY, 0, &node->alpha, &inOutQuad, NULL); - add_tween(XMB_DELAY, 0, &node->label_alpha, &inOutQuad, NULL); - add_tween(XMB_DELAY, -xmb->hspacing*dir, &node->x, &inOutQuad, NULL); + xmb_push_animations(node, ia, -xmb->icon.spacing.horizontal * dir); } } -static void xmb_list_switch_new(file_list_t *list, int dir, size_t current) +static void xmb_list_switch_new(xmb_handle_t *xmb, file_list_t *list, int dir, size_t current) { int i; - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + size_t end = 0; + menu_handle_t *menu = menu_driver_resolve(); - if (!xmb) + if (!menu) return; - for (i = 0; i < file_list_get_size(list); i++) + end = file_list_get_size(list); + + for (i = 0; i < end; i++) { - float ia = 0.5; xmb_node_t *node = (xmb_node_t*) file_list_get_userdata_at_offset(list, i); + float ia = 0.5; - if (!xmb) + if (!node) continue; - node->x = xmb->hspacing * dir; + node->x = xmb->icon.spacing.horizontal * dir; node->alpha = 0; node->label_alpha = 0; if (i == current) ia = 1.0; - add_tween(XMB_DELAY, ia, &node->alpha, &inOutQuad, NULL); - add_tween(XMB_DELAY, ia, &node->label_alpha, &inOutQuad, NULL); - add_tween(XMB_DELAY, 0, &node->x, &inOutQuad, NULL); + xmb_push_animations(node, ia, 0); } } -static void xmb_set_title(void) +static void xmb_set_title(xmb_handle_t *xmb) { - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + menu_handle_t *menu = menu_driver_resolve(); - if (!xmb) + if (!menu) return; - if (driver.menu->cat_selection_ptr == 0) + if (menu->categories.selection_ptr == 0) { const char *dir = NULL; const char *label = NULL; unsigned menu_type = 0; - menu_list_get_last_stack(driver.menu->menu_list, &dir, &label, &menu_type); - get_title(label, dir, menu_type, xmb->title, sizeof(xmb->title)); + menu_list_get_last_stack(menu->menu_list, &dir, &label, &menu_type); + get_title(label, dir, menu_type, xmb->title_name, sizeof(xmb->title_name)); } else { @@ -753,112 +769,124 @@ static void xmb_set_title(void) if (!info_list) return; - info = (core_info_t*)&info_list->list[driver.menu->cat_selection_ptr - 1]; + info = (core_info_t*)&info_list->list[menu->categories.selection_ptr - 1]; if (info) - strlcpy(xmb->title, info->display_name, sizeof(xmb->title)); + strlcpy(xmb->title_name, info->display_name, sizeof(xmb->title_name)); } } -static void xmb_list_open(void) +static void xmb_list_open(xmb_handle_t *xmb) { unsigned j; int dir = -1; - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + menu_handle_t *menu = menu_driver_resolve(); - if (!xmb) + if (!menu) return; - if (driver.menu->cat_selection_ptr > xmb->cat_selection_ptr_old) + if (menu->categories.selection_ptr > xmb->categories.selection_ptr_old) dir = 1; - xmb->active_category += dir; + xmb->categories.active.idx += dir; - for (j = 0; j < driver.menu->num_categories; j++) + for (j = 0; j < menu->categories.size; j++) { - float ia = xmb->c_passive_alpha; - float iz = xmb->c_passive_zoom; - xmb_node_t *node = j ? xmb_node_for_core(j-1) : &xmb->settings_node; + float ia = xmb->categories.passive.alpha; + float iz = xmb->categories.passive.zoom; + xmb_node_t *node = j ? xmb_get_userdata_from_core(xmb, j - 1) : &xmb->settings_node; if (!node) continue; - if (j == xmb->active_category) + if (j == xmb->categories.active.idx) { - ia = xmb->c_active_alpha; - iz = xmb->c_active_zoom; + ia = xmb->categories.active.alpha; + iz = xmb->categories.active.zoom; } - add_tween(XMB_DELAY, ia, &node->alpha, &inOutQuad, NULL); - add_tween(XMB_DELAY, iz, &node->zoom, &inOutQuad, NULL); + menu_animation_push(menu->animation, XMB_DELAY, ia, &node->alpha, EASING_IN_OUT_QUAD, NULL); + menu_animation_push(menu->animation, XMB_DELAY, iz, &node->zoom, EASING_IN_OUT_QUAD, NULL); } - add_tween(XMB_DELAY, xmb->hspacing * -(float)driver.menu->cat_selection_ptr, - &xmb->categories_x, &inOutQuad, NULL); + menu_animation_push(menu->animation, XMB_DELAY, + xmb->icon.spacing.horizontal * -(float)menu->categories.selection_ptr, + &xmb->categories.x_pos, EASING_IN_OUT_QUAD, NULL); dir = -1; - if (driver.menu->cat_selection_ptr > xmb->cat_selection_ptr_old) + if (menu->categories.selection_ptr > xmb->categories.selection_ptr_old) dir = 1; - xmb_list_switch_old(xmb->selection_buf_old, dir, xmb->selection_ptr_old); - xmb_list_switch_new(driver.menu->menu_list->selection_buf, dir, driver.menu->selection_ptr); - xmb->active_category_old = driver.menu->cat_selection_ptr; + xmb_list_switch_old(xmb, xmb->selection_buf_old, dir, xmb->selection_ptr_old); + xmb_list_switch_new(xmb, menu->menu_list->selection_buf, dir, menu->navigation.selection_ptr); + xmb->categories.active.idx_old = menu->categories.selection_ptr; } -static void xmb_list_switch(void) +static void xmb_list_switch(xmb_handle_t *xmb) { unsigned j; int dir = 0; - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + menu_handle_t *menu = menu_driver_resolve(); - if (!xmb) + if (!menu) return; - xmb->depth = file_list_get_size(driver.menu->menu_list->menu_stack); + xmb->depth = file_list_get_size(menu->menu_list->menu_stack); if (xmb->depth > xmb->old_depth) dir = 1; else if (xmb->depth < xmb->old_depth) dir = -1; - for (j = 0; j < driver.menu->num_categories; j++) + for (j = 0; j < menu->categories.size; j++) { float ia = 0; - xmb_node_t *node = j ? xmb_node_for_core(j-1) : &xmb->settings_node; + xmb_node_t *node = j ? xmb_get_userdata_from_core(xmb, j - 1) : &xmb->settings_node; if (!node) continue; - if (j == xmb->active_category) - ia = xmb->c_active_alpha; + if (j == xmb->categories.active.idx) + ia = xmb->categories.active.alpha; else if (xmb->depth <= 1) - ia = xmb->c_passive_alpha; + ia = xmb->categories.passive.alpha; - add_tween(XMB_DELAY, ia, &node->alpha, &inOutQuad, NULL); + menu_animation_push(menu->animation, XMB_DELAY, ia, + &node->alpha, EASING_IN_OUT_QUAD, NULL); } - xmb_list_open_old(xmb->selection_buf_old, dir, xmb->selection_ptr_old); - xmb_list_open_new(driver.menu->menu_list->selection_buf, dir, driver.menu->selection_ptr); + xmb_list_open_old(xmb, xmb->selection_buf_old, dir, xmb->selection_ptr_old); + xmb_list_open_new(xmb, menu->menu_list->selection_buf, dir, menu->navigation.selection_ptr); switch (xmb->depth) { case 1: - add_tween(XMB_DELAY, xmb->icon_size*-(xmb->depth*2-2), &xmb->x, &inOutQuad, NULL); - add_tween(XMB_DELAY, 0, &xmb->arrow_alpha, &inOutQuad, NULL); + menu_animation_push(menu->animation, XMB_DELAY, xmb->icon.size * -(xmb->depth*2-2), + &xmb->x, EASING_IN_OUT_QUAD, NULL); + menu_animation_push(menu->animation, XMB_DELAY, 0, &xmb->textures.arrow.alpha, + EASING_IN_OUT_QUAD, NULL); break; case 2: - add_tween(XMB_DELAY, xmb->icon_size*-(xmb->depth*2-2), &xmb->x, &inOutQuad, NULL); - add_tween(XMB_DELAY, 1, &xmb->arrow_alpha, &inOutQuad, NULL); + menu_animation_push(menu->animation, XMB_DELAY, + xmb->icon.size * -(xmb->depth*2-2), &xmb->x, EASING_IN_OUT_QUAD, NULL); + menu_animation_push(menu->animation, XMB_DELAY, 1, &xmb->textures.arrow.alpha, + EASING_IN_OUT_QUAD, NULL); break; } xmb->old_depth = xmb->depth; } -static void xmb_populate_entries(void *data, const char *path, +static void xmb_populate_entries(const char *path, const char *label, unsigned k) { - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + xmb_handle_t *xmb = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; + + xmb = (xmb_handle_t*)menu->userdata; if (!xmb) return; @@ -869,58 +897,59 @@ static void xmb_populate_entries(void *data, const char *path, return; } - xmb_set_title(); + xmb_set_title(xmb); - if (driver.menu->cat_selection_ptr != xmb->active_category_old) - xmb_list_open(); + if (menu->categories.selection_ptr != xmb->categories.active.idx_old) + xmb_list_open(xmb); else - xmb_list_switch(); + xmb_list_switch(xmb); } -static void xmb_draw_items(file_list_t *list, file_list_t *stack, +static void xmb_draw_items(xmb_handle_t *xmb, gl_t *gl, + file_list_t *list, file_list_t *stack, size_t current, size_t cat_selection_ptr) { unsigned i; - const char *dir = NULL; const char *label = NULL; - unsigned menu_type = 0; xmb_node_t *core_node = NULL; - size_t end = file_list_get_size(list); - gl_t *gl = (gl_t*)video_driver_resolve(NULL); - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + size_t end = 0; - if (!xmb || !list->size || !gl) + if (!list || !list->size) return; - file_list_get_last(stack, &dir, &label, &menu_type); + file_list_get_last(stack, NULL, &label, NULL); - if (xmb->active_category) - core_node = xmb_node_for_core(cat_selection_ptr - 1); + if (xmb->categories.active.idx) + core_node = xmb_get_userdata_from_core(xmb, cat_selection_ptr - 1); + + end = file_list_get_size(list); for (i = 0; i < end; i++) { float icon_x, icon_y; char type_str[PATH_MAX_LENGTH], path_buf[PATH_MAX_LENGTH]; - char name[256], value[256]; + char name[PATH_MAX_LENGTH], value[PATH_MAX_LENGTH]; const char *path = NULL, *entry_label = NULL; unsigned type = 0, w = 0; - xmb_node_t *node = NULL; menu_file_list_cbs_t *cbs = NULL; GLuint icon = 0; + xmb_node_t *node = (xmb_node_t*)file_list_get_userdata_at_offset(list, i); - menu_list_get_at_offset(list, i, &path, &entry_label, &type); - node = (xmb_node_t*)file_list_get_userdata_at_offset(list, i); - - icon_x = node->x + xmb->margin_left + xmb->hspacing - xmb->icon_size/2.0; - icon_y = xmb->margin_top + node->y + xmb->icon_size/2.0; + if (!node) + continue; + + icon_x = node->x + xmb->margins.screen.left + xmb->icon.spacing.horizontal - xmb->icon.size / 2.0; + icon_y = xmb->margins.screen.top + node->y + xmb->icon.size / 2.0; if ( - icon_x < -xmb->icon_size/2 || + icon_x < -xmb->icon.size / 2 || icon_x > gl->win_width || - icon_y < xmb->icon_size/2 || - icon_y > gl->win_height + xmb->icon_size) + icon_y < xmb->icon.size / 2 || + icon_y > gl->win_height + xmb->icon.size) continue; + menu_list_get_at_offset(list, i, &path, &entry_label, &type); + cbs = (menu_file_list_cbs_t*)menu_list_get_actiondata_at_offset(list, i); if (cbs && cbs->action_get_representation) @@ -936,70 +965,70 @@ static void xmb_draw_items(file_list_t *list, file_list_t *stack, switch(type) { case MENU_FILE_DIRECTORY: - icon = xmb->textures[XMB_TEXTURE_FOLDER].id; + icon = xmb->textures.list[XMB_TEXTURE_FOLDER].id; break; case MENU_FILE_PLAIN: - icon = xmb->textures[XMB_TEXTURE_FILE].id; + icon = xmb->textures.list[XMB_TEXTURE_FILE].id; break; case MENU_FILE_PLAYLIST_ENTRY: - icon = xmb->textures[XMB_TEXTURE_FILE].id; + icon = xmb->textures.list[XMB_TEXTURE_FILE].id; break; case MENU_FILE_CONTENTLIST_ENTRY: - icon = xmb->textures[XMB_TEXTURE_FILE].id; + icon = xmb->textures.list[XMB_TEXTURE_FILE].id; if (core_node) icon = core_node->content_icon; break; case MENU_FILE_CARCHIVE: - icon = xmb->textures[XMB_TEXTURE_ZIP].id; + icon = xmb->textures.list[XMB_TEXTURE_ZIP].id; break; case MENU_FILE_CORE: - icon = xmb->textures[XMB_TEXTURE_CORE].id; + icon = xmb->textures.list[XMB_TEXTURE_CORE].id; break; case MENU_FILE_RDB: - icon = xmb->textures[XMB_TEXTURE_RDB].id; + icon = xmb->textures.list[XMB_TEXTURE_RDB].id; break; case MENU_FILE_CURSOR: - icon = xmb->textures[XMB_TEXTURE_CURSOR].id; + icon = xmb->textures.list[XMB_TEXTURE_CURSOR].id; break; case MENU_SETTING_ACTION_RUN: - icon = xmb->textures[XMB_TEXTURE_RUN].id; + icon = xmb->textures.list[XMB_TEXTURE_RUN].id; break; case MENU_SETTING_ACTION_SAVESTATE: - icon = xmb->textures[XMB_TEXTURE_SAVESTATE].id; + icon = xmb->textures.list[XMB_TEXTURE_SAVESTATE].id; break; case MENU_SETTING_ACTION_LOADSTATE: - icon = xmb->textures[XMB_TEXTURE_LOADSTATE].id; + icon = xmb->textures.list[XMB_TEXTURE_LOADSTATE].id; break; case MENU_SETTING_ACTION_SCREENSHOT: - icon = xmb->textures[XMB_TEXTURE_SCREENSHOT].id; + icon = xmb->textures.list[XMB_TEXTURE_SCREENSHOT].id; break; case MENU_SETTING_ACTION_RESET: - icon = xmb->textures[XMB_TEXTURE_RELOAD].id; + icon = xmb->textures.list[XMB_TEXTURE_RELOAD].id; break; case MENU_SETTING_ACTION: - icon = xmb->textures[XMB_TEXTURE_SETTING].id; + icon = xmb->textures.list[XMB_TEXTURE_SETTING].id; if (xmb->depth == 3) - icon = xmb->textures[XMB_TEXTURE_SUBSETTING].id; + icon = xmb->textures.list[XMB_TEXTURE_SUBSETTING].id; break; case MENU_SETTING_GROUP: - icon = xmb->textures[XMB_TEXTURE_SETTING].id; + icon = xmb->textures.list[XMB_TEXTURE_SETTING].id; break; default: - icon = xmb->textures[XMB_TEXTURE_SUBSETTING].id; + icon = xmb->textures.list[XMB_TEXTURE_SUBSETTING].id; break; } - xmb_draw_icon(icon, icon_x, icon_y, node->alpha, 0, node->zoom); + xmb_draw_icon(gl, xmb, icon, icon_x, icon_y, node->alpha, 0, node->zoom); - menu_ticker_line(name, 35, g_extern.frame_count / 20, path_buf, + menu_animation_ticker_line(name, 35, g_extern.frame_count / 20, path_buf, (i == current)); - xmb_draw_text(name, - node->x + xmb->margin_left + xmb->hspacing + xmb->label_margin_left, - xmb->margin_top + node->y + xmb->label_margin_top, + xmb_draw_text(gl, xmb, name, + node->x + xmb->margins.screen.left + xmb->icon.spacing.horizontal + xmb->margins.label.left, + xmb->margins.screen.top + node->y + xmb->margins.label.top, 1, node->label_alpha, 0); - menu_ticker_line(value, 35, g_extern.frame_count / 20, type_str, + menu_animation_ticker_line(value, 35, g_extern.frame_count / 20, type_str, (i == current)); if(( strcmp(type_str, "...") @@ -1012,31 +1041,31 @@ static void xmb_draw_items(file_list_t *list, file_list_t *stack, && strcmp(type_str, "ON") && strcmp(type_str, "OFF")) || ((!strcmp(type_str, "ON") - && !xmb->textures[XMB_TEXTURE_SWITCH_ON].id) + && !xmb->textures.list[XMB_TEXTURE_SWITCH_ON].id) || (!strcmp(type_str, "OFF") - && !xmb->textures[XMB_TEXTURE_SWITCH_OFF].id))) - xmb_draw_text(value, - node->x + xmb->margin_left + xmb->hspacing + - xmb->label_margin_left + xmb->setting_margin_left, - xmb->margin_top + node->y + xmb->label_margin_top, + && !xmb->textures.list[XMB_TEXTURE_SWITCH_OFF].id))) + xmb_draw_text(gl, xmb, value, + node->x + xmb->margins.screen.left + xmb->icon.spacing.horizontal + + xmb->margins.label.left + xmb->margins.setting.left, + xmb->margins.screen.top + node->y + xmb->margins.label.top, 1, node->label_alpha, 0); - if (!strcmp(type_str, "ON") && xmb->textures[XMB_TEXTURE_SWITCH_ON].id) - xmb_draw_icon(xmb->textures[XMB_TEXTURE_SWITCH_ON].id, - node->x + xmb->margin_left + xmb->hspacing - + xmb->icon_size/2.0 + xmb->setting_margin_left, - xmb->margin_top + node->y + xmb->icon_size/2.0, + if (!strcmp(type_str, "ON") && xmb->textures.list[XMB_TEXTURE_SWITCH_ON].id) + xmb_draw_icon(gl, xmb, xmb->textures.list[XMB_TEXTURE_SWITCH_ON].id, + node->x + xmb->margins.screen.left + xmb->icon.spacing.horizontal + + xmb->icon.size / 2.0 + xmb->margins.setting.left, + xmb->margins.screen.top + node->y + xmb->icon.size / 2.0, node->alpha, 0, 1); - if (!strcmp(type_str, "OFF") && xmb->textures[XMB_TEXTURE_SWITCH_OFF].id) - xmb_draw_icon(xmb->textures[XMB_TEXTURE_SWITCH_OFF].id, - node->x + xmb->margin_left + xmb->hspacing - + xmb->icon_size/2.0 + xmb->setting_margin_left, - xmb->margin_top + node->y + xmb->icon_size/2.0, + if (!strcmp(type_str, "OFF") && xmb->textures.list[XMB_TEXTURE_SWITCH_OFF].id) + xmb_draw_icon(gl, xmb, xmb->textures.list[XMB_TEXTURE_SWITCH_OFF].id, + node->x + xmb->margins.screen.left + xmb->icon.spacing.horizontal + + xmb->icon.size / 2.0 + xmb->margins.setting.left, + xmb->margins.screen.top + node->y + xmb->icon.size / 2.0, node->alpha, 0, 1); @@ -1049,94 +1078,106 @@ static void xmb_frame(void) char title_msg[PATH_MAX_LENGTH], timedate[PATH_MAX_LENGTH]; const char *core_name = NULL; const char *core_version = NULL; - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + xmb_handle_t *xmb = NULL; + gl_t *gl = NULL; + menu_handle_t *menu = menu_driver_resolve(); - gl_t *gl = (gl_t*)video_driver_resolve(NULL); - - if (!xmb || !gl) + if (!menu) return; - update_tweens(0.002); + xmb = (xmb_handle_t*)menu->userdata; + + if (!xmb) + return; + + gl = (gl_t*)video_driver_resolve(NULL); + + if (!gl) + return; + + menu_animation_update(menu->animation, 0.002); glViewport(0, 0, gl->win_width, gl->win_height); - xmb_render_background(false); + xmb_render_background(gl, xmb, false); - core_name = g_extern.menu.info.library_name; - - if (!core_name) - core_name = g_extern.system.info.library_name; - if (!core_name) - core_name = "No Core"; - - xmb_draw_text( - xmb->title, xmb->title_margin_left, xmb->title_margin_top, 1, 1, 0); - - disp_timedate_set_label(timedate, sizeof(timedate), 0); + xmb_draw_text(gl, xmb, + xmb->title_name, xmb->margins.title.left, xmb->margins.title.top, 1, 1, 0); if (g_settings.menu.timedate_enable) { - xmb_draw_text( - timedate, gl->win_width - xmb->title_margin_left - xmb->icon_size/4, - xmb->title_margin_top, 1, 1, 1); + disp_timedate_set_label(timedate, sizeof(timedate), 0); - xmb_draw_icon(xmb->textures[XMB_TEXTURE_CLOCK].id, - gl->win_width - xmb->icon_size, xmb->icon_size, 1, 0, 1); + xmb_draw_text(gl, xmb, + timedate, gl->win_width - xmb->margins.title.left - xmb->icon.size / 4, + xmb->margins.title.top, 1, 1, 1); + + xmb_draw_icon(gl, xmb, xmb->textures.list[XMB_TEXTURE_CLOCK].id, + gl->win_width - xmb->icon.size, xmb->icon.size, 1, 0, 1); } - core_version = g_extern.menu.info.library_version; + if (g_settings.menu.core_enable) + { + core_name = g_extern.menu.info.library_name; - if (!core_version) - core_version = g_extern.system.info.library_version; - if (!core_version) - core_version = ""; + if (!core_name) + core_name = g_extern.system.info.library_name; + if (!core_name) + core_name = "No Core"; - snprintf(title_msg, sizeof(title_msg), "%s - %s %s", PACKAGE_VERSION, - core_name, core_version); - xmb_draw_text(title_msg, xmb->title_margin_left, - gl->win_height - xmb->title_margin_bottom, 1, 1, 0); + core_version = g_extern.menu.info.library_version; - xmb_draw_icon(xmb->textures[XMB_TEXTURE_ARROW].id, - xmb->x + xmb->margin_left + xmb->hspacing - xmb->icon_size/2.0 + xmb->icon_size, - xmb->margin_top + xmb->icon_size/2.0 + xmb->vspacing * xmb->active_item_factor, - xmb->arrow_alpha, 0, 1); + if (!core_version) + core_version = g_extern.system.info.library_version; + if (!core_version) + core_version = ""; - depth = file_list_get_size(driver.menu->menu_list->menu_stack); + snprintf(title_msg, sizeof(title_msg), "%s - %s %s", PACKAGE_VERSION, + core_name, core_version); + xmb_draw_text(gl, xmb, title_msg, xmb->margins.title.left, + gl->win_height - xmb->margins.title.bottom, 1, 1, 0); + } - xmb_draw_items( + xmb_draw_icon(gl, xmb, xmb->textures.list[XMB_TEXTURE_ARROW].id, + xmb->x + xmb->margins.screen.left + xmb->icon.spacing.horizontal - xmb->icon.size / 2.0 + xmb->icon.size, + xmb->margins.screen.top + xmb->icon.size / 2.0 + xmb->icon.spacing.vertical * xmb->item.active.factor, + xmb->textures.arrow.alpha, 0, 1); + + depth = file_list_get_size(menu->menu_list->menu_stack); + + xmb_draw_items(xmb, gl, xmb->selection_buf_old, xmb->menu_stack_old, xmb->selection_ptr_old, - depth > 1 ? driver.menu->cat_selection_ptr : - xmb->cat_selection_ptr_old); - xmb_draw_items( - driver.menu->menu_list->selection_buf, - driver.menu->menu_list->menu_stack, - driver.menu->selection_ptr, - driver.menu->cat_selection_ptr); + depth > 1 ? menu->categories.selection_ptr : + xmb->categories.selection_ptr_old); - for (i = 0; i < driver.menu->num_categories; i++) + xmb_draw_items(xmb, gl, + menu->menu_list->selection_buf, + menu->menu_list->menu_stack, + menu->navigation.selection_ptr, + menu->categories.selection_ptr); + + for (i = 0; i < menu->categories.size; i++) { - xmb_node_t *node = i ? xmb_node_for_core(i-1) : &xmb->settings_node; + xmb_node_t *node = i ? xmb_get_userdata_from_core(xmb, i - 1) : &xmb->settings_node; - if (!node) - continue; - - xmb_draw_icon(node->icon, - xmb->x + xmb->categories_x + xmb->margin_left + xmb->hspacing*(i+1) - xmb->icon_size / 2.0, - xmb->margin_top + xmb->icon_size / 2.0, - node->alpha, - 0, - node->zoom); + if (node) + xmb_draw_icon(gl, xmb, node->icon, + xmb->x + xmb->categories.x_pos + xmb->margins.screen.left + xmb->icon.spacing.horizontal * (i + 1) - xmb->icon.size / 2.0, + xmb->margins.screen.top + xmb->icon.size / 2.0, + node->alpha, + 0, + node->zoom); } #ifdef GEKKO const char *message_queue; - if (driver.menu->msg_force) + if (menu->msg_force) { message_queue = msg_queue_pull(g_extern.msg_queue); - driver.menu->msg_force = false; + menu->msg_force = false; } else message_queue = driver.current_msg; @@ -1144,22 +1185,22 @@ static void xmb_frame(void) xmb_render_messagebox(message_queue); #endif - if (driver.menu->keyboard.display) + if (menu->keyboard.display) { char msg[PATH_MAX_LENGTH]; - const char *str = *driver.menu->keyboard.buffer; + const char *str = *menu->keyboard.buffer; if (!str) str = ""; snprintf(msg, sizeof(msg), "%s\n%s", - driver.menu->keyboard.label, str); - xmb_render_background(true); + menu->keyboard.label, str); + xmb_render_background(gl, xmb, true); xmb_render_messagebox(msg); } if (xmb->box_message[0] != '\0') { - xmb_render_background(true); + xmb_render_background(gl, xmb, true); xmb_render_messagebox(xmb->box_message); xmb->box_message[0] = '\0'; } @@ -1186,80 +1227,80 @@ static void *xmb_init(void) if (!menu) goto error; - menu->userdata = (xmb_handle_t*)calloc(1, sizeof(xmb_handle_t)); + menu->userdata = (xmb_handle_t*)calloc(1, sizeof(xmb_handle_t)); if (!menu->userdata) goto error; xmb = (xmb_handle_t*)menu->userdata; - xmb->menu_stack_old = (file_list_t*)calloc(1, sizeof(file_list_t)); + xmb->menu_stack_old = (file_list_t*)calloc(1, sizeof(file_list_t)); if (!xmb->menu_stack_old) goto error; - xmb->selection_buf_old = (file_list_t*)calloc(1, sizeof(file_list_t)); + xmb->selection_buf_old = (file_list_t*)calloc(1, sizeof(file_list_t)); if (!xmb->selection_buf_old) goto error; - xmb->active_category = 0; - xmb->active_category_old = 0; - xmb->x = 0; - xmb->categories_x = 0; - xmb->alpha = 1.0f; - xmb->arrow_alpha = 0; - xmb->depth = 1; - xmb->old_depth = 1; - xmb->alpha = 0; - xmb->prevent_populate = false; + xmb->categories.active.idx = 0; + xmb->categories.active.idx_old = 0; + xmb->x = 0; + xmb->categories.x_pos = 0; + xmb->textures.arrow.alpha = 0; + xmb->depth = 1; + xmb->old_depth = 1; + xmb->alpha = 0; + xmb->prevent_populate = false; - xmb->c_active_zoom = 1.0; - xmb->c_passive_zoom = 0.5; - xmb->i_active_zoom = 1.0; - xmb->i_passive_zoom = 0.5; + xmb->categories.active.zoom = 1.0; + xmb->categories.passive.zoom = 0.5; + xmb->item.active.zoom = 1.0; + xmb->item.passive.zoom = 0.5; - xmb->c_active_alpha = 1.0; - xmb->c_passive_alpha = 0.5; - xmb->i_active_alpha = 1.0; - xmb->i_passive_alpha = 0.5; + xmb->categories.active.alpha = 1.0; + xmb->categories.passive.alpha= 0.5; + xmb->item.active.alpha = 1.0; + xmb->item.passive.alpha = 0.5; - xmb->above_subitem_offset = 1.5; - xmb->above_item_offset = -1.0; - xmb->active_item_factor = 3.0; - xmb->under_item_offset = 5.0; + xmb->above_offset.subitem = 1.5; + xmb->above_offset.item = -1.0; + xmb->item.active.factor = 3.0; + xmb->under_offset.item = 5.0; if (gl->win_width >= 3840) - scale_factor = 2.0; + scale_factor = 2.0; else if (gl->win_width >= 2560) - scale_factor = 1.5; + scale_factor = 1.5; else if (gl->win_width >= 1920) - scale_factor = 1.0; + scale_factor = 1.0; else if (gl->win_width >= 1280) - scale_factor = 0.75; + scale_factor = 0.75; else if (gl->win_width >= 640) - scale_factor = 0.5; + scale_factor = 0.5; else if (gl->win_width >= 320) - scale_factor = 0.25; + scale_factor = 0.25; - strlcpy(xmb->icon_dir, "256", sizeof(xmb->icon_dir)); + strlcpy(xmb->icon.dir, "256", sizeof(xmb->icon.dir)); - xmb->icon_size = 128.0 * scale_factor; - xmb->font_size = 32.0 * scale_factor; - xmb->hspacing = 200.0 * scale_factor; - xmb->vspacing = 64.0 * scale_factor; - xmb->margin_left = 336.0 * scale_factor; - xmb->margin_top = (256+32) * scale_factor; - xmb->title_margin_left = 60 * scale_factor; - xmb->title_margin_top = 60 * scale_factor + xmb->font_size/3; - xmb->title_margin_bottom = 60 * scale_factor - xmb->font_size/3; - xmb->label_margin_left = 85.0 * scale_factor; - xmb->label_margin_top = xmb->font_size/3.0; - xmb->setting_margin_left = 600.0 * scale_factor; + xmb->icon.size = 128.0 * scale_factor; + xmb->font.size = 32.0 * scale_factor; + xmb->icon.spacing.horizontal = 200.0 * scale_factor; + xmb->icon.spacing.vertical = 64.0 * scale_factor; + xmb->margins.screen.left = 336.0 * scale_factor; + xmb->margins.screen.top = (256+32) * scale_factor; + xmb->margins.title.left = 60 * scale_factor; + xmb->margins.title.top = 60 * scale_factor + xmb->font.size/3; + xmb->margins.title.bottom = 60 * scale_factor - xmb->font.size/3; + xmb->margins.label.left = 85.0 * scale_factor; + xmb->margins.label.top = xmb->font.size/3.0; + xmb->margins.setting.left = 600.0 * scale_factor; + + menu->categories.size = 1; - menu->num_categories = 1; if (g_extern.core_info) - menu->num_categories = g_extern.core_info->count + 1; + menu->categories.size = g_extern.core_info->count + 1; return menu; @@ -1277,7 +1318,7 @@ static void xmb_free(void *data) { menu_handle_t *menu = (menu_handle_t*)data; - if (menu->userdata) + if (menu && menu->userdata) free(menu->userdata); } @@ -1289,6 +1330,10 @@ static bool xmb_font_init_first(const gl_font_renderer_t **font_driver, && !g_extern.system.hw_render_callback.context_type) { thread_video_t *thr = (thread_video_t*)driver.video_data; + + if (!thr) + return false; + thr->cmd_data.font_init.method = gl_font_init_first; thr->cmd_data.font_init.font_driver = font_driver; thr->cmd_data.font_init.font_handle = font_handle; @@ -1305,7 +1350,33 @@ static bool xmb_font_init_first(const gl_font_renderer_t **font_driver, font_path, xmb_font_size); } -static void xmb_context_reset(void *data) +static bool xmb_load_wallpaper(const char *path) +{ + xmb_handle_t *xmb = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return false; + + xmb = (xmb_handle_t*)menu->userdata; + + if (!xmb) + return false; + if (!path) + return false; + + if (xmb->textures.bg.id) + glDeleteTextures(1, &xmb->textures.bg.id); + + strlcpy(xmb->textures.bg.path, path, sizeof(xmb->textures.bg.path)); + + xmb->textures.bg.id = menu_texture_load(xmb->textures.bg.path, + TEXTURE_BACKEND_OPENGL, TEXTURE_FILTER_MIPMAP_LINEAR); + + return true; +} + +static void xmb_context_reset(void) { int i, k; char bgpath[PATH_MAX_LENGTH]; @@ -1317,8 +1388,8 @@ static void xmb_context_reset(void *data) core_info_list_t* info_list = NULL; gl_t *gl = NULL; xmb_handle_t *xmb = NULL; - menu_handle_t *menu = (menu_handle_t*)data; xmb_node_t *node = NULL; + menu_handle_t *menu = menu_driver_resolve(); if (!menu) return; @@ -1339,78 +1410,81 @@ static void xmb_context_reset(void *data) fill_pathname_join(mediapath, g_settings.assets_directory, "lakka", sizeof(mediapath)); fill_pathname_join(themepath, mediapath, XMB_THEME, sizeof(themepath)); - fill_pathname_join(iconpath, themepath, xmb->icon_dir, sizeof(iconpath)); + fill_pathname_join(iconpath, themepath, xmb->icon.dir, sizeof(iconpath)); fill_pathname_slash(iconpath, sizeof(iconpath)); fill_pathname_join(fontpath, themepath, "font.ttf", sizeof(fontpath)); - xmb_font_init_first(&gl->font_driver, &xmb->font, gl, fontpath, xmb->font_size); + xmb_font_init_first(&gl->font_driver, &xmb->font.buf, gl, fontpath, xmb->font.size); if (*g_settings.menu.wallpaper) - strlcpy(xmb->textures[XMB_TEXTURE_BG].path, g_settings.menu.wallpaper, - sizeof(xmb->textures[XMB_TEXTURE_BG].path)); + strlcpy(xmb->textures.bg.path, g_settings.menu.wallpaper, + sizeof(xmb->textures.bg.path)); else - fill_pathname_join(xmb->textures[XMB_TEXTURE_BG].path, iconpath, - "bg.png", sizeof(xmb->textures[XMB_TEXTURE_BG].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_SETTINGS].path, iconpath, - "settings.png", sizeof(xmb->textures[XMB_TEXTURE_SETTINGS].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_SETTING].path, iconpath, - "setting.png", sizeof(xmb->textures[XMB_TEXTURE_SETTING].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_SUBSETTING].path, iconpath, - "subsetting.png", sizeof(xmb->textures[XMB_TEXTURE_SUBSETTING].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_ARROW].path, iconpath, - "arrow.png", sizeof(xmb->textures[XMB_TEXTURE_ARROW].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_RUN].path, iconpath, - "run.png", sizeof(xmb->textures[XMB_TEXTURE_RUN].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_RESUME].path, iconpath, - "resume.png", sizeof(xmb->textures[XMB_TEXTURE_RESUME].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_SAVESTATE].path, iconpath, - "savestate.png", sizeof(xmb->textures[XMB_TEXTURE_SAVESTATE].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_LOADSTATE].path, iconpath, - "loadstate.png", sizeof(xmb->textures[XMB_TEXTURE_LOADSTATE].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_SCREENSHOT].path, iconpath, - "screenshot.png", sizeof(xmb->textures[XMB_TEXTURE_SCREENSHOT].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_RELOAD].path, iconpath, - "reload.png", sizeof(xmb->textures[XMB_TEXTURE_RELOAD].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_FILE].path, iconpath, - "file.png", sizeof(xmb->textures[XMB_TEXTURE_FILE].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_FOLDER].path, iconpath, - "folder.png", sizeof(xmb->textures[XMB_TEXTURE_FOLDER].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_ZIP].path, iconpath, - "zip.png", sizeof(xmb->textures[XMB_TEXTURE_ZIP].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_CORE].path, iconpath, - "core.png", sizeof(xmb->textures[XMB_TEXTURE_CORE].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_RDB].path, iconpath, - "database.png", sizeof(xmb->textures[XMB_TEXTURE_RDB].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_CURSOR].path, iconpath, - "cursor.png", sizeof(xmb->textures[XMB_TEXTURE_CURSOR].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_SWITCH_ON].path, iconpath, - "on.png", sizeof(xmb->textures[XMB_TEXTURE_SWITCH_ON].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_SWITCH_OFF].path, iconpath, - "off.png", sizeof(xmb->textures[XMB_TEXTURE_SWITCH_OFF].path)); - fill_pathname_join(xmb->textures[XMB_TEXTURE_CLOCK].path, iconpath, - "clock.png", sizeof(xmb->textures[XMB_TEXTURE_CLOCK].path)); + fill_pathname_join(xmb->textures.bg.path, iconpath, + "bg.png", sizeof(xmb->textures.bg.path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_SETTINGS].path, iconpath, + "settings.png", sizeof(xmb->textures.list[XMB_TEXTURE_SETTINGS].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_SETTING].path, iconpath, + "setting.png", sizeof(xmb->textures.list[XMB_TEXTURE_SETTING].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_SUBSETTING].path, iconpath, + "subsetting.png", sizeof(xmb->textures.list[XMB_TEXTURE_SUBSETTING].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_ARROW].path, iconpath, + "arrow.png", sizeof(xmb->textures.list[XMB_TEXTURE_ARROW].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_RUN].path, iconpath, + "run.png", sizeof(xmb->textures.list[XMB_TEXTURE_RUN].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_RESUME].path, iconpath, + "resume.png", sizeof(xmb->textures.list[XMB_TEXTURE_RESUME].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_SAVESTATE].path, iconpath, + "savestate.png", sizeof(xmb->textures.list[XMB_TEXTURE_SAVESTATE].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_LOADSTATE].path, iconpath, + "loadstate.png", sizeof(xmb->textures.list[XMB_TEXTURE_LOADSTATE].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_SCREENSHOT].path, iconpath, + "screenshot.png", sizeof(xmb->textures.list[XMB_TEXTURE_SCREENSHOT].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_RELOAD].path, iconpath, + "reload.png", sizeof(xmb->textures.list[XMB_TEXTURE_RELOAD].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_FILE].path, iconpath, + "file.png", sizeof(xmb->textures.list[XMB_TEXTURE_FILE].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_FOLDER].path, iconpath, + "folder.png", sizeof(xmb->textures.list[XMB_TEXTURE_FOLDER].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_ZIP].path, iconpath, + "zip.png", sizeof(xmb->textures.list[XMB_TEXTURE_ZIP].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_CORE].path, iconpath, + "core.png", sizeof(xmb->textures.list[XMB_TEXTURE_CORE].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_RDB].path, iconpath, + "database.png", sizeof(xmb->textures.list[XMB_TEXTURE_RDB].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_CURSOR].path, iconpath, + "cursor.png", sizeof(xmb->textures.list[XMB_TEXTURE_CURSOR].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_SWITCH_ON].path, iconpath, + "on.png", sizeof(xmb->textures.list[XMB_TEXTURE_SWITCH_ON].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_SWITCH_OFF].path, iconpath, + "off.png", sizeof(xmb->textures.list[XMB_TEXTURE_SWITCH_OFF].path)); + fill_pathname_join(xmb->textures.list[XMB_TEXTURE_CLOCK].path, iconpath, + "clock.png", sizeof(xmb->textures.list[XMB_TEXTURE_CLOCK].path)); for (k = 0; k < XMB_TEXTURE_LAST; k++) - xmb->textures[k].id = xmb_png_texture_load(xmb->textures[k].path); + xmb->textures.list[k].id = menu_texture_load(xmb->textures.list[k].path, + TEXTURE_BACKEND_OPENGL, TEXTURE_FILTER_MIPMAP_LINEAR); - xmb->settings_node.icon = xmb->textures[XMB_TEXTURE_SETTINGS].id; - xmb->settings_node.alpha = xmb->c_active_alpha; - xmb->settings_node.zoom = xmb->c_active_zoom; + xmb_load_wallpaper(xmb->textures.bg.path); + + xmb->settings_node.icon = xmb->textures.list[XMB_TEXTURE_SETTINGS].id; + xmb->settings_node.alpha = xmb->categories.active.alpha; + xmb->settings_node.zoom = xmb->categories.active.zoom; info_list = (core_info_list_t*)g_extern.core_info; if (!info_list) return; - for (i = 1; i < driver.menu->num_categories; i++) + for (i = 1; i < menu->categories.size; i++) { - node = xmb_node_for_core(i-1); + node = xmb_get_userdata_from_core(xmb, i - 1); fill_pathname_join(mediapath, g_settings.assets_directory, "lakka", sizeof(mediapath)); fill_pathname_join(themepath, mediapath, XMB_THEME, sizeof(themepath)); - fill_pathname_join(iconpath, themepath, xmb->icon_dir, sizeof(iconpath)); + fill_pathname_join(iconpath, themepath, xmb->icon.dir, sizeof(iconpath)); fill_pathname_slash(iconpath, sizeof(iconpath)); info = (core_info_t*)&info_list->list[i-1]; @@ -1436,81 +1510,70 @@ static void xmb_context_reset(void *data) strlcat(content_texturepath, "-content.png", sizeof(content_texturepath)); node->alpha = 0; - node->zoom = xmb->c_passive_zoom; - node->icon = xmb_png_texture_load(texturepath); - node->content_icon = xmb_png_texture_load(content_texturepath); + node->zoom = xmb->categories.passive.zoom; + node->icon = menu_texture_load(texturepath, + TEXTURE_BACKEND_OPENGL, TEXTURE_FILTER_MIPMAP_LINEAR); + node->content_icon = menu_texture_load(content_texturepath, + TEXTURE_BACKEND_OPENGL, TEXTURE_FILTER_MIPMAP_LINEAR); - if (i == xmb->active_category) + + if (i == xmb->categories.active.idx) { - node->alpha = xmb->c_active_alpha; - node->zoom = xmb->c_active_zoom; + node->alpha = xmb->categories.active.alpha; + node->zoom = xmb->categories.active.zoom; } else if (xmb->depth <= 1) - node->alpha = xmb->c_passive_alpha; + node->alpha = xmb->categories.passive.alpha; } } -static void xmb_navigation_clear(void *data, bool pending_push) +static void xmb_navigation_clear(bool pending_push) { - (void)data; - - if (!pending_push) - xmb_selection_pointer_changed(); -} - -static void xmb_navigation_decrement(void *data) -{ - (void)data; - xmb_selection_pointer_changed(); } -static void xmb_navigation_increment(void *data) +static void xmb_navigation_decrement(void) { - (void)data; - xmb_selection_pointer_changed(); } -static void xmb_navigation_set(void *data, bool scroll) +static void xmb_navigation_increment(void) { - (void)data; - (void)scroll; - xmb_selection_pointer_changed(); } -static void xmb_navigation_set_last(void *data) +static void xmb_navigation_set(bool scroll) { - (void)data; - xmb_selection_pointer_changed(); } -static void xmb_navigation_descend_alphabet(void *data, size_t *unused) +static void xmb_navigation_set_last(void) { - (void)data; - (void)unused; - xmb_selection_pointer_changed(); } -static void xmb_navigation_ascend_alphabet(void *data, size_t *unused) +static void xmb_navigation_descend_alphabet(size_t *unused) { - (void)data; - (void)unused; - xmb_selection_pointer_changed(); } -static void xmb_list_insert(void *data, +static void xmb_navigation_ascend_alphabet(size_t *unused) +{ + xmb_selection_pointer_changed(); +} + +static void xmb_list_insert(file_list_t *list, const char *path, const char *unused, size_t list_size) { - float iy; int current = 0, i = list_size; xmb_node_t *node = NULL; - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; - file_list_t *list = (file_list_t*)data; + xmb_handle_t *xmb = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; + + xmb = (xmb_handle_t*)menu->userdata; if (!list || !xmb) return; @@ -1528,27 +1591,25 @@ static void xmb_list_insert(void *data, if (!node) return; - current = driver.menu->selection_ptr; + current = menu->navigation.selection_ptr; - node->alpha = xmb->i_passive_alpha; - node->zoom = xmb->i_passive_zoom; + node->alpha = xmb->item.passive.alpha; + node->zoom = xmb->item.passive.zoom; node->label_alpha = node->alpha; - node->y = xmb_item_y(i, current); + node->y = xmb_item_y(xmb, i, current); node->x = 0; if (i == current) { - node->alpha = xmb->i_active_alpha; - node->label_alpha = xmb->i_active_alpha; - node->zoom = xmb->i_active_zoom; + node->alpha = xmb->item.active.alpha; + node->label_alpha = xmb->item.active.alpha; + node->zoom = xmb->item.active.zoom; } } -static void xmb_list_delete(void *data, size_t idx, - size_t list_size) +static void xmb_list_delete(file_list_t *list, + size_t idx, size_t list_size) { - file_list_t *list = (file_list_t*)data; - if (!list) return; @@ -1557,64 +1618,60 @@ static void xmb_list_delete(void *data, size_t idx, list->list[idx].userdata = NULL; } -static void xmb_list_clear(void *data) -{ - (void)data; -} - static void xmb_list_cache(bool horizontal, unsigned action) { size_t stack_size; - xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + xmb_handle_t *xmb = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; + + xmb = (xmb_handle_t*)menu->userdata; if (!xmb) return; - file_list_copy(driver.menu->menu_list->selection_buf, xmb->selection_buf_old); - file_list_copy(driver.menu->menu_list->menu_stack, xmb->menu_stack_old); - xmb->selection_ptr_old = driver.menu->selection_ptr; + file_list_copy(menu->menu_list->selection_buf, xmb->selection_buf_old); + file_list_copy(menu->menu_list->menu_stack, xmb->menu_stack_old); + xmb->selection_ptr_old = menu->navigation.selection_ptr; if(!horizontal) return; - xmb->cat_selection_ptr_old = driver.menu->cat_selection_ptr; + xmb->categories.selection_ptr_old = menu->categories.selection_ptr; switch (action) { case MENU_ACTION_LEFT: - driver.menu->cat_selection_ptr--; + menu->categories.selection_ptr--; break; default: - driver.menu->cat_selection_ptr++; + menu->categories.selection_ptr++; break; } - stack_size = driver.menu->menu_list->menu_stack->size; + stack_size = menu->menu_list->menu_stack->size; - strlcpy(driver.menu->menu_list->menu_stack->list[stack_size-1].label, + strlcpy(menu->menu_list->menu_stack->list[stack_size-1].label, "Main Menu", PATH_MAX_LENGTH); - driver.menu->menu_list->menu_stack->list[stack_size-1].type = + menu->menu_list->menu_stack->list[stack_size-1].type = MENU_SETTINGS; - if (driver.menu->cat_selection_ptr == 0) + if (menu->categories.selection_ptr == 0) return; - strlcpy(driver.menu->menu_list->menu_stack->list[stack_size-1].label, + strlcpy(menu->menu_list->menu_stack->list[stack_size-1].label, "Horizontal Menu", PATH_MAX_LENGTH); - driver.menu->menu_list->menu_stack->list[stack_size-1].type = + menu->menu_list->menu_stack->list[stack_size-1].type = MENU_SETTING_HORIZONTAL_MENU; } -static void xmb_list_set_selection(void *data) -{ - (void)data; -} - -static void xmb_context_destroy(void *data) +static void xmb_context_destroy(void) { unsigned i; xmb_handle_t *xmb = NULL; - menu_handle_t *menu = (menu_handle_t*)driver.menu; + menu_handle_t *menu = menu_driver_resolve(); if (!menu) return; @@ -1625,11 +1682,11 @@ static void xmb_context_destroy(void *data) return; for (i = 0; i < XMB_TEXTURE_LAST; i++) - glDeleteTextures(1, &xmb->textures[i].id); + glDeleteTextures(1, &xmb->textures.list[i].id); - for (i = 1; i < driver.menu->num_categories; i++) + for (i = 1; i < menu->categories.size; i++) { - xmb_node_t *node = xmb_node_for_core(i-1); + xmb_node_t *node = xmb_get_userdata_from_core(xmb, i - 1); if (!node) continue; @@ -1643,7 +1700,7 @@ static void xmb_toggle(bool menu_on) { int i; xmb_handle_t *xmb = NULL; - menu_handle_t *menu = (menu_handle_t*)driver.menu; + menu_handle_t *menu = menu_driver_resolve(); if (!menu) return; @@ -1653,7 +1710,7 @@ static void xmb_toggle(bool menu_on) if (!xmb) return; - xmb->depth = file_list_get_size(driver.menu->menu_list->menu_stack); + xmb->depth = file_list_get_size(menu->menu_list->menu_stack); if (!menu_on) { @@ -1661,27 +1718,28 @@ static void xmb_toggle(bool menu_on) return; } - add_tween(XMB_DELAY, 1.0f, &xmb->alpha, &inOutQuad, NULL); + menu_animation_push(menu->animation, XMB_DELAY, 1.0f, + &xmb->alpha, EASING_IN_OUT_QUAD, NULL); xmb->prevent_populate = !menu->need_refresh; - for (i = 0; i < driver.menu->num_categories; i++) + for (i = 0; i < menu->categories.size; i++) { - xmb_node_t *node = i ? xmb_node_for_core(i-1) : &xmb->settings_node; + xmb_node_t *node = i ? xmb_get_userdata_from_core(xmb, i - 1) : &xmb->settings_node; if (!node) continue; node->alpha = 0; - node->zoom = xmb->c_passive_zoom; + node->zoom = xmb->categories.passive.zoom; - if (i == xmb->active_category) + if (i == xmb->categories.active.idx) { - node->alpha = xmb->c_active_alpha; - node->zoom = xmb->c_active_zoom; + node->alpha = xmb->categories.active.alpha; + node->zoom = xmb->categories.active.zoom; } else if (xmb->depth <= 1) - node->alpha = xmb->c_passive_alpha; + node->alpha = xmb->categories.passive.alpha; } } @@ -1705,9 +1763,10 @@ menu_ctx_driver_t menu_ctx_xmb = { xmb_navigation_ascend_alphabet, xmb_list_insert, xmb_list_delete, - xmb_list_clear, + NULL, xmb_list_cache, - xmb_list_set_selection, + NULL, xmb_entry_iterate, + xmb_load_wallpaper, "xmb", }; diff --git a/menu/menu.c b/menu/menu.c index 9c420663aa..a95c7506fe 100644 --- a/menu/menu.c +++ b/menu/menu.c @@ -15,6 +15,7 @@ */ #include "menu.h" +#include "menu_animation.h" #include "menu_entries.h" #include "menu_shader.h" #include "../dynamic.h" @@ -66,7 +67,7 @@ void menu_update_libretro_info(struct retro_system_info *info) if (*g_settings.libretro_directory) g_extern.core_info = core_info_list_new(g_settings.libretro_directory); if (driver.menu_ctx && driver.menu_ctx->context_reset) - driver.menu_ctx->context_reset(driver.menu); + driver.menu_ctx->context_reset(); rarch_update_system_info(info, NULL); } @@ -185,18 +186,41 @@ void *menu_init(const void *data) sizeof(g_settings.menu.driver)); if (!(menu->menu_list = (menu_list_t*)menu_list_new())) - return NULL; + goto error; g_extern.core_info_current = (core_info_t*)calloc(1, sizeof(core_info_t)); + if (!g_extern.core_info_current) + goto error; + #ifdef HAVE_SHADER_MANAGER menu->shader = (struct video_shader*)calloc(1, sizeof(struct video_shader)); + if (!menu->shader) + goto error; #endif menu->push_start_screen = g_settings.menu_show_start_screen; g_settings.menu_show_start_screen = false; menu_shader_manager_init(menu); + menu->animation = (animation_t*)calloc(1, sizeof(animation_t)); + + if (!menu->animation) + goto error; + return menu; +error: + if (menu->menu_list) + menu_list_free(menu->menu_list); + menu->menu_list = NULL; + if (g_extern.core_info_current) + free(g_extern.core_info_current); + g_extern.core_info_current = NULL; + if (menu->shader) + free(menu->shader); + menu->shader = NULL; + if (menu) + free(menu); + return NULL; } /** @@ -245,6 +269,13 @@ void menu_free(void *data) libretro_free_system_info(&g_extern.menu.info); #endif + menu_animation_free(menu->animation); + menu->animation = NULL; + + if (menu->frame_buf.data) + free(menu->frame_buf.data); + menu->frame_buf.data = NULL; + menu_list_free(menu->menu_list); menu->menu_list = NULL; @@ -259,73 +290,15 @@ void menu_free(void *data) free(data); } -/** - * menu_ticker_line: - * @buf : buffer to write new message line to. - * @len : length of buffer @input. - * @idx : Index. Will be used for ticker logic. - * @str : Input string. - * @selected : Is the item currently selected in the menu? - * - * Take the contents of @str and apply a ticker effect to it, - * and write the results in @buf. - **/ -void menu_ticker_line(char *buf, size_t len, unsigned idx, - const char *str, bool selected) -{ - unsigned ticker_period, phase, phase_left_stop; - unsigned phase_left_moving, phase_right_stop; - unsigned left_offset, right_offset; - size_t str_len = strlen(str); - - if (str_len <= len) - { - strlcpy(buf, str, len + 1); - return; - } - - if (!selected) - { - strlcpy(buf, str, len + 1 - 3); - strlcat(buf, "...", len + 1); - return; - } - - /* Wrap long strings in options with some kind of ticker line. */ - ticker_period = 2 * (str_len - len) + 4; - phase = idx % ticker_period; - - phase_left_stop = 2; - phase_left_moving = phase_left_stop + (str_len - len); - phase_right_stop = phase_left_moving + 2; - - left_offset = phase - phase_left_stop; - right_offset = (str_len - len) - (phase - phase_right_stop); - - /* Ticker period: - * [Wait at left (2 ticks), - * Progress to right(type_len - w), - * Wait at right (2 ticks), - * Progress to left]. - */ - if (phase < phase_left_stop) - strlcpy(buf, str, len + 1); - else if (phase < phase_left_moving) - strlcpy(buf, str + left_offset, len + 1); - else if (phase < phase_right_stop) - strlcpy(buf, str + str_len - len, len + 1); - else - strlcpy(buf, str + right_offset, len + 1); -} - void menu_apply_deferred_settings(void) { rarch_setting_t *setting = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu) + if (!menu) return; - setting = (rarch_setting_t*)driver.menu->list_settings; + setting = (rarch_setting_t*)menu->list_settings; if (!setting) return; @@ -398,8 +371,13 @@ int menu_iterate(retro_input_t input, int32_t ret = 0; unsigned action = menu_input_frame(input, trigger_input); - if (driver.menu_ctx && driver.menu_ctx->entry_iterate) - ret = driver.menu_ctx->entry_iterate(action); + if (driver.menu_ctx) + { + if (driver.menu_ctx->set_texture) + driver.menu_ctx->set_texture(); + if (driver.menu_ctx->entry_iterate) + ret = driver.menu_ctx->entry_iterate(action); + } if (g_extern.is_menu) draw_frame(); diff --git a/menu/menu.h b/menu/menu.h index 56eaae055b..0557603f59 100644 --- a/menu/menu.h +++ b/menu/menu.h @@ -24,11 +24,7 @@ #include #include #include "../../general.h" -#include "menu_navigation.h" -#include "../../core_info.h" -#include "../../playlist.h" #include "menu_input.h" -#include "../gfx/video_shader_driver.h" #ifndef GFX_MAX_SHADERS #define GFX_MAX_SHADERS 16 @@ -177,20 +173,6 @@ int menu_iterate(retro_input_t input, **/ void menu_free(void *data); -/** - * menu_ticker_line: - * @buf : buffer to write new message line to. - * @len : length of buffer @input. - * @idx : Index. Will be used for ticker logic. - * @str : Input string. - * @selected : Is the item currently selected in the menu? - * - * Take the contents of @str and apply a ticker effect to it, - * and write the results in @buf. - **/ -void menu_ticker_line(char *buf, size_t len, unsigned tick, - const char *str, bool selected); - /** * menu_load_content: * diff --git a/menu/menu_action.c b/menu/menu_action.c index 4ed7164e54..eeab07bee6 100644 --- a/menu/menu_action.c +++ b/menu/menu_action.c @@ -95,7 +95,7 @@ static int menu_action_handle_setting(rarch_setting_t *setting, setting->default_value.string, setting->name, type, - driver.menu->selection_ptr); + driver.menu->navigation.selection_ptr); /* fall-through. */ case ST_BOOL: case ST_INT: @@ -124,7 +124,7 @@ int menu_action_setting_set(unsigned type, const char *label, unsigned action) { rarch_setting_t *setting = menu_action_find_setting( driver.menu->menu_list->selection_buf->list - [driver.menu->selection_ptr].label); + [driver.menu->navigation.selection_ptr].label); if (!setting) return 0; diff --git a/menu/menu_animation.c b/menu/menu_animation.c index 7c95fbdded..ffe71b7521 100644 --- a/menu/menu_animation.c +++ b/menu/menu_animation.c @@ -15,54 +15,394 @@ */ #include "menu_animation.h" -#include "../driver.h" #include +#include +#include -static void tween_free(tween_t *tween) +/* from https://github.com/kikito/tween.lua/blob/master/tween.lua */ + +static float easing_linear(float t, float b, float c, float d) { - if (tween) - free(tween); - tween = NULL; + return c * t / d + b; } -bool add_tween(float duration, float target_value, float* subject, - easingFunc easing, tween_cb cb) +static float easing_in_out_quad(float t, float b, float c, float d) { - tween_t *tween = NULL, *temp_tweens = NULL; + t = t / d * 2; + if (t < 1) + return c / 2 * pow(t, 2) + b; + return -c / 2 * ((t - 1) * (t - 3) - 1) + b; +} - if (!driver.menu) - return false; - - temp_tweens = (tween_t*)realloc(driver.menu->tweens, - (driver.menu->numtweens + 1) * sizeof(tween_t)); +static float easing_in_quad(float t, float b, float c, float d) +{ + return c * pow(t / d, 2) + b; +} - if (!temp_tweens) +static float easing_out_quad(float t, float b, float c, float d) +{ + t = t / d; + return -c * t * (t - 2) + b; +} + +static float easing_out_in_quad(float t, float b, float c, float d) +{ + if (t < d / 2) + return easing_out_quad(t * 2, b, c / 2, d); + return easing_in_quad((t * 2) - d, b + c / 2, c / 2, d); +} + +static float easing_in_cubic(float t, float b, float c, float d) +{ + return c * pow(t / d, 3) + b; +} + +static float easing_out_cubic(float t, float b, float c, float d) +{ + return c * (pow(t / d - 1, 3) + 1) + b; +} + +static float easing_in_out_cubic(float t, float b, float c, float d) +{ + t = t / d * 2; + if (t < 1) + return c / 2 * t * t * t + b; + t = t - 2; + return c / 2 * (t * t * t + 2) + b; +} + +static float easing_out_in_cubic(float t, float b, float c, float d) +{ + if (t < d / 2) + return easing_out_cubic(t * 2, b, c / 2, d); + return easing_in_cubic((t * 2) - d, b + c / 2, c / 2, d); +} + +static float easing_in_quart(float t, float b, float c, float d) +{ + return c * pow(t / d, 4) + b; +} + +static float easing_out_quart(float t, float b, float c, float d) +{ + return -c * (pow(t / d - 1, 4) - 1) + b; +} + +static float easing_in_out_quart(float t, float b, float c, float d) +{ + t = t / d * 2; + if (t < 1) + return c / 2 * pow(t, 4) + b; + return -c / 2 * (pow(t - 2, 4) - 2) + b; +} + +static float easing_out_in_quart(float t, float b, float c, float d) +{ + if (t < d / 2) + return easing_out_quart(t * 2, b, c / 2, d); + return easing_in_quart((t * 2) - d, b + c / 2, c / 2, d); +} + +static float easing_in_quint(float t, float b, float c, float d) +{ + return c * pow(t / d, 5) + b; +} + +static float easing_out_quint(float t, float b, float c, float d) +{ + return c * (pow(t / d - 1, 5) + 1) + b; +} + +static float easing_in_out_quint(float t, float b, float c, float d) +{ + t = t / d * 2; + if (t < 1) + return c / 2 * pow(t, 5) + b; + return c / 2 * (pow(t - 2, 5) + 2) + b; +} + +static float easing_out_in_quint(float t, float b, float c, float d) +{ + if (t < d / 2) + return easing_out_quint(t * 2, b, c / 2, d); + return easing_in_quint((t * 2) - d, b + c / 2, c / 2, d); +} + +static float easing_in_sine(float t, float b, float c, float d) +{ + return -c * cos(t / d * (M_PI / 2)) + c + b; +} + +static float easing_out_sine(float t, float b, float c, float d) +{ + return c * sin(t / d * (M_PI / 2)) + b; +} + +static float easing_in_out_sine(float t, float b, float c, float d) +{ + return -c / 2 * (cos(M_PI * t / d) - 1) + b; +} + +static float easing_out_in_sine(float t, float b, float c, float d) +{ + if (t < d / 2) + return easing_out_sine(t * 2, b, c / 2, d); + return easing_in_sine((t * 2) -d, b + c / 2, c / 2, d); +} + +static float easing_in_expo(float t, float b, float c, float d) +{ + if (t == 0) + return b; + return c * powf(2, 10 * (t / d - 1)) + b - c * 0.001; +} + +static float easing_out_expo(float t, float b, float c, float d) +{ + if (t == d) + return b + c; + return c * 1.001 * (-powf(2, -10 * t / d) + 1) + b; +} + +static float easing_in_out_expo(float t, float b, float c, float d) +{ + if (t == 0) + return b; + if (t == d) + return b + c; + t = t / d * 2; + if (t < 1) + return c / 2 * powf(2, 10 * (t - 1)) + b - c * 0.0005; + return c / 2 * 1.0005 * (-powf(2, -10 * (t - 1)) + 2) + b; +} + +static float easing_out_in_expo(float t, float b, float c, float d) +{ + if (t < d / 2) + return easing_out_expo(t * 2, b, c / 2, d); + return easing_in_expo((t * 2) - d, b + c / 2, c / 2, d); +} + +static float easing_in_circ(float t, float b, float c, float d) +{ + return(-c * (sqrt(1 - powf(t / d, 2)) - 1) + b); +} + +static float easing_out_circ(float t, float b, float c, float d) +{ + return(c * sqrt(1 - powf(t / d - 1, 2)) + b); +} + +static float easing_in_out_circ(float t, float b, float c, float d) +{ + t = t / d * 2; + if (t < 1) + return -c / 2 * (sqrt(1 - t * t) - 1) + b; + t = t - 2; + return c / 2 * (sqrt(1 - t * t) + 1) + b; +} + +static float easing_out_in_circ(float t, float b, float c, float d) +{ + if (t < d / 2) + return easing_out_circ(t * 2, b, c / 2, d); + return easing_in_circ((t * 2) - d, b + c / 2, c / 2, d); +} + +static float easing_out_bounce(float t, float b, float c, float d) +{ + t = t / d; + if (t < 1 / 2.75) + return c * (7.5625 * t * t) + b; + if (t < 2 / 2.75) { - tween_free(driver.menu->tweens); - return false; + t = t - (1.5 / 2.75); + return c * (7.5625 * t * t + 0.75) + b; + } + else if (t < 2.5 / 2.75) + { + t = t - (2.25 / 2.75); + return c * (7.5625 * t * t + 0.9375) + b; + } + t = t - (2.625 / 2.75); + return c * (7.5625 * t * t + 0.984375) + b; +} + +static float easing_in_bounce(float t, float b, float c, float d) +{ + return c - easing_out_bounce(d - t, 0, c, d) + b; +} + +static float easing_in_out_bounce(float t, float b, float c, float d) +{ + if (t < d / 2) + return easing_in_bounce(t * 2, 0, c, d) * 0.5 + b; + return easing_out_bounce(t * 2 - d, 0, c, d) * 0.5 + c * .5 + b; +} + +static float easing_out_in_bounce(float t, float b, float c, float d) +{ + if (t < d / 2) + return easing_out_bounce(t * 2, b, c / 2, d); + return easing_in_bounce((t * 2) - d, b + c / 2, c / 2, d); +} + +void menu_animation_free(animation_t *animation) +{ + size_t i; + + if (!animation) + return; + + for (i = 0; i < animation->size; i++) + { + if (animation->list[i].subject) + animation->list[i].subject = NULL; } - driver.menu->tweens = temp_tweens; - tween = (tween_t*)&driver.menu->tweens[driver.menu->numtweens]; + free(animation->list); + free(animation); +} - if (!tween) - return false; +bool menu_animation_push(animation_t *animation, + float duration, float target_value, float* subject, + enum animation_easing_type easing_enum, tween_cb cb) +{ + if (animation->size >= animation->capacity) + { + animation->capacity++; + animation->list = (struct tween*)realloc(animation->list, + animation->capacity * sizeof(struct tween)); + } - tween->alive = 1; - tween->duration = duration; - tween->running_since = 0; - tween->initial_value = *subject; - tween->target_value = target_value; - tween->subject = subject; - tween->easing = easing; - tween->cb = cb; + animation->list[animation->size].alive = 1; + animation->list[animation->size].duration = duration; + animation->list[animation->size].running_since = 0; + animation->list[animation->size].initial_value = *subject; + animation->list[animation->size].target_value = target_value; + animation->list[animation->size].subject = subject; + animation->list[animation->size].cb = cb; - driver.menu->numtweens++; + switch (easing_enum) + { + case EASING_LINEAR: + animation->list[animation->size].easing = &easing_linear; + break; + /* Quad */ + case EASING_IN_QUAD: + animation->list[animation->size].easing = &easing_in_quad; + break; + case EASING_OUT_QUAD: + animation->list[animation->size].easing = &easing_out_quad; + break; + case EASING_IN_OUT_QUAD: + animation->list[animation->size].easing = &easing_in_out_quad; + break; + case EASING_OUT_IN_QUAD: + animation->list[animation->size].easing = &easing_out_in_quad; + break; + /* Cubic */ + case EASING_IN_CUBIC: + animation->list[animation->size].easing = &easing_in_cubic; + break; + case EASING_OUT_CUBIC: + animation->list[animation->size].easing = &easing_out_cubic; + break; + case EASING_IN_OUT_CUBIC: + animation->list[animation->size].easing = &easing_in_out_cubic; + break; + case EASING_OUT_IN_CUBIC: + animation->list[animation->size].easing = &easing_out_in_cubic; + break; + /* Quart */ + case EASING_IN_QUART: + animation->list[animation->size].easing = &easing_in_quart; + break; + case EASING_OUT_QUART: + animation->list[animation->size].easing = &easing_out_quart; + break; + case EASING_IN_OUT_QUART: + animation->list[animation->size].easing = &easing_in_out_quart; + break; + case EASING_OUT_IN_QUART: + animation->list[animation->size].easing = &easing_out_in_quart; + break; + /* Quint */ + case EASING_IN_QUINT: + animation->list[animation->size].easing = &easing_in_quint; + break; + case EASING_OUT_QUINT: + animation->list[animation->size].easing = &easing_out_quint; + break; + case EASING_IN_OUT_QUINT: + animation->list[animation->size].easing = &easing_in_out_quint; + break; + case EASING_OUT_IN_QUINT: + animation->list[animation->size].easing = &easing_out_in_quint; + break; + /* Sine */ + case EASING_IN_SINE: + animation->list[animation->size].easing = &easing_in_sine; + break; + case EASING_OUT_SINE: + animation->list[animation->size].easing = &easing_out_sine; + break; + case EASING_IN_OUT_SINE: + animation->list[animation->size].easing = &easing_in_out_sine; + break; + case EASING_OUT_IN_SINE: + animation->list[animation->size].easing = &easing_out_in_sine; + break; + /* Expo */ + case EASING_IN_EXPO: + animation->list[animation->size].easing = &easing_in_expo; + break; + case EASING_OUT_EXPO: + animation->list[animation->size].easing = &easing_out_expo; + break; + case EASING_IN_OUT_EXPO: + animation->list[animation->size].easing = &easing_in_out_expo; + break; + case EASING_OUT_IN_EXPO: + animation->list[animation->size].easing = &easing_out_in_expo; + break; + /* Circ */ + case EASING_IN_CIRC: + animation->list[animation->size].easing = &easing_in_circ; + break; + case EASING_OUT_CIRC: + animation->list[animation->size].easing = &easing_out_circ; + break; + case EASING_IN_OUT_CIRC: + animation->list[animation->size].easing = &easing_in_out_circ; + break; + case EASING_OUT_IN_CIRC: + animation->list[animation->size].easing = &easing_out_in_circ; + break; + /* Bounce */ + case EASING_IN_BOUNCE: + animation->list[animation->size].easing = &easing_in_bounce; + break; + case EASING_OUT_BOUNCE: + animation->list[animation->size].easing = &easing_out_bounce; + break; + case EASING_IN_OUT_BOUNCE: + animation->list[animation->size].easing = &easing_in_out_bounce; + break; + case EASING_OUT_IN_BOUNCE: + animation->list[animation->size].easing = &easing_out_in_bounce; + break; + default: + animation->list[animation->size].easing = NULL; + break; + } + + animation->size++; return true; } -static int iterate_tween(tween_t *tween, float dt, +static int menu_animation_iterate(struct tween *tween, float dt, unsigned *active_tweens) { if (!tween) @@ -93,259 +433,73 @@ static int iterate_tween(tween_t *tween, float dt, return 0; } -void update_tweens(float dt) +void menu_animation_update(animation_t *animation, float dt) { unsigned i; unsigned active_tweens = 0; - tween_t *tween = &driver.menu->tweens[0]; - for(i = 0; i < driver.menu->numtweens; i++) - iterate_tween(tween++, dt, &active_tweens); + for(i = 0; i < animation->size; i++) + menu_animation_iterate(&animation->list[i], dt, &active_tweens); if (!active_tweens) - driver.menu->numtweens = 0; + animation->size = 0; } -/* Linear */ - -float linear(float t, float b, float c, float d) +/** + * menu_animation_ticker_line: + * @buf : buffer to write new message line to. + * @len : length of buffer @input. + * @idx : Index. Will be used for ticker logic. + * @str : Input string. + * @selected : Is the item currently selected in the menu? + * + * Take the contents of @str and apply a ticker effect to it, + * and write the results in @buf. + **/ +void menu_animation_ticker_line(char *buf, size_t len, unsigned idx, + const char *str, bool selected) { - return c * t / d + b; -} + unsigned ticker_period, phase, phase_left_stop; + unsigned phase_left_moving, phase_right_stop; + unsigned left_offset, right_offset; + size_t str_len = strlen(str); -/* Quad */ - -float inQuad(float t, float b, float c, float d) -{ - return c * pow(t / d, 2) + b; -} - -float outQuad(float t, float b, float c, float d) -{ - t = t / d; - return -c * t * (t - 2) + b; -} - -float inOutQuad(float t, float b, float c, float d) -{ - t = t / d * 2; - if (t < 1) - return c / 2 * pow(t, 2) + b; - return -c / 2 * ((t - 1) * (t - 3) - 1) + b; -} - -float outInQuad(float t, float b, float c, float d) -{ - if (t < d / 2) - return outQuad(t * 2, b, c / 2, d); - return inQuad((t * 2) - d, b + c / 2, c / 2, d); -} - -/* Cubic */ - -float inCubic(float t, float b, float c, float d) -{ - return c * pow(t / d, 3) + b; -} - -float outCubic(float t, float b, float c, float d) -{ - return c * (pow(t / d - 1, 3) + 1) + b; -} - -float inOutCubic(float t, float b, float c, float d) -{ - t = t / d * 2; - if (t < 1) - return c / 2 * t * t * t + b; - t = t - 2; - return c / 2 * (t * t * t + 2) + b; -} - -float outInCubic(float t, float b, float c, float d) -{ - if (t < d / 2) - return outCubic(t * 2, b, c / 2, d); - return inCubic((t * 2) - d, b + c / 2, c / 2, d); -} - -/* Quart */ - -float inQuart(float t, float b, float c, float d) -{ - return c * pow(t / d, 4) + b; -} - -float outQuart(float t, float b, float c, float d) -{ - return -c * (pow(t / d - 1, 4) - 1) + b; -} - -float inOutQuart(float t, float b, float c, float d) -{ - t = t / d * 2; - if (t < 1) - return c / 2 * pow(t, 4) + b; - return -c / 2 * (pow(t - 2, 4) - 2) + b; -} - -float outInQuart(float t, float b, float c, float d) -{ - if (t < d / 2) - return outQuart(t * 2, b, c / 2, d); - return inQuart((t * 2) - d, b + c / 2, c / 2, d); -} - -/* Quint */ - -float inQuint(float t, float b, float c, float d) -{ - return c * pow(t / d, 5) + b; -} - -float outQuint(float t, float b, float c, float d) -{ - return c * (pow(t / d - 1, 5) + 1) + b; -} - -float inOutQuint(float t, float b, float c, float d) -{ - t = t / d * 2; - if (t < 1) - return c / 2 * pow(t, 5) + b; - return c / 2 * (pow(t - 2, 5) + 2) + b; -} - -float outInQuint(float t, float b, float c, float d) -{ - if (t < d / 2) - return outQuint(t * 2, b, c / 2, d); - return inQuint((t * 2) - d, b + c / 2, c / 2, d); -} - -/* Sine */ - -float inSine(float t, float b, float c, float d) -{ - return -c * cos(t / d * (M_PI / 2)) + c + b; -} - -float outSine(float t, float b, float c, float d) -{ - return c * sin(t / d * (M_PI / 2)) + b; -} - -float inOutSine(float t, float b, float c, float d) -{ - return -c / 2 * (cos(M_PI * t / d) - 1) + b; -} - -float outInSine(float t, float b, float c, float d) -{ - if (t < d / 2) - return outSine(t * 2, b, c / 2, d); - return inSine((t * 2) -d, b + c / 2, c / 2, d); -} - -/* Expo */ - -float inExpo(float t, float b, float c, float d) -{ - if (t == 0) - return b; - return c * powf(2, 10 * (t / d - 1)) + b - c * 0.001; -} - -float outExpo(float t, float b, float c, float d) -{ - if (t == d) - return b + c; - return c * 1.001 * (-powf(2, -10 * t / d) + 1) + b; -} - -float inOutExpo(float t, float b, float c, float d) -{ - if (t == 0) - return b; - if (t == d) - return b + c; - t = t / d * 2; - if (t < 1) - return c / 2 * powf(2, 10 * (t - 1)) + b - c * 0.0005; - return c / 2 * 1.0005 * (-powf(2, -10 * (t - 1)) + 2) + b; -} - -float outInExpo(float t, float b, float c, float d) -{ - if (t < d / 2) - return outExpo(t * 2, b, c / 2, d); - return inExpo((t * 2) - d, b + c / 2, c / 2, d); -} - -/* Circ */ - -float inCirc(float t, float b, float c, float d) -{ - return(-c * (sqrt(1 - powf(t / d, 2)) - 1) + b); -} - -float outCirc(float t, float b, float c, float d) -{ - return(c * sqrt(1 - powf(t / d - 1, 2)) + b); -} - -float inOutCirc(float t, float b, float c, float d) -{ - t = t / d * 2; - if (t < 1) - return -c / 2 * (sqrt(1 - t * t) - 1) + b; - t = t - 2; - return c / 2 * (sqrt(1 - t * t) + 1) + b; -} - -float outInCirc(float t, float b, float c, float d) -{ - if (t < d / 2) - return outCirc(t * 2, b, c / 2, d); - return inCirc((t * 2) - d, b + c / 2, c / 2, d); -} - -/* Bounce */ - -float outBounce(float t, float b, float c, float d) -{ - t = t / d; - if (t < 1 / 2.75) - return c * (7.5625 * t * t) + b; - if (t < 2 / 2.75) + if (str_len <= len) { - t = t - (1.5 / 2.75); - return c * (7.5625 * t * t + 0.75) + b; + strlcpy(buf, str, len + 1); + return; } - else if (t < 2.5 / 2.75) + + if (!selected) { - t = t - (2.25 / 2.75); - return c * (7.5625 * t * t + 0.9375) + b; + strlcpy(buf, str, len + 1 - 3); + strlcat(buf, "...", len + 1); + return; } - t = t - (2.625 / 2.75); - return c * (7.5625 * t * t + 0.984375) + b; -} -float inBounce(float t, float b, float c, float d) -{ - return c - outBounce(d - t, 0, c, d) + b; -} + /* Wrap long strings in options with some kind of ticker line. */ + ticker_period = 2 * (str_len - len) + 4; + phase = idx % ticker_period; -float inOutBounce(float t, float b, float c, float d) -{ - if (t < d / 2) - return inBounce(t * 2, 0, c, d) * 0.5 + b; - return outBounce(t * 2 - d, 0, c, d) * 0.5 + c * .5 + b; -} + phase_left_stop = 2; + phase_left_moving = phase_left_stop + (str_len - len); + phase_right_stop = phase_left_moving + 2; -float outInBounce(float t, float b, float c, float d) -{ - if (t < d / 2) - return outBounce(t * 2, b, c / 2, d); - return inBounce((t * 2) - d, b + c / 2, c / 2, d); + left_offset = phase - phase_left_stop; + right_offset = (str_len - len) - (phase - phase_right_stop); + + /* Ticker period: + * [Wait at left (2 ticks), + * Progress to right(type_len - w), + * Wait at right (2 ticks), + * Progress to left]. + */ + if (phase < phase_left_stop) + strlcpy(buf, str, len + 1); + else if (phase < phase_left_moving) + strlcpy(buf, str + left_offset, len + 1); + else if (phase < phase_right_stop) + strlcpy(buf, str + str_len - len, len + 1); + else + strlcpy(buf, str + right_offset, len + 1); } diff --git a/menu/menu_animation.h b/menu/menu_animation.h index fdc2e5cc11..0bbca69282 100644 --- a/menu/menu_animation.h +++ b/menu/menu_animation.h @@ -28,7 +28,7 @@ extern "C" { typedef float (*easingFunc)(float, float, float, float); typedef void (*tween_cb) (void); -typedef struct +struct tween { int alive; float duration; @@ -38,80 +38,83 @@ typedef struct float* subject; easingFunc easing; tween_cb cb; -} tween_t; +}; -bool add_tween(float duration, float target_value, float* subject, - easingFunc easing, tween_cb cb); +typedef struct animation +{ + struct tween *list; -void update_tweens(float dt); + size_t capacity; + size_t size; +} animation_t; -/* from https://github.com/kikito/tween.lua/blob/master/tween.lua */ +enum animation_easing_type +{ + /* Linear */ + EASING_LINEAR = 0, + /* Quad */ + EASING_IN_QUAD, + EASING_OUT_QUAD, + EASING_IN_OUT_QUAD, + EASING_OUT_IN_QUAD, + /* Cubic */ + EASING_IN_CUBIC, + EASING_OUT_CUBIC, + EASING_IN_OUT_CUBIC, + EASING_OUT_IN_CUBIC, + /* Quart */ + EASING_IN_QUART, + EASING_OUT_QUART, + EASING_IN_OUT_QUART, + EASING_OUT_IN_QUART, + /* Quint */ + EASING_IN_QUINT, + EASING_OUT_QUINT, + EASING_IN_OUT_QUINT, + EASING_OUT_IN_QUINT, + /* Sine */ + EASING_IN_SINE, + EASING_OUT_SINE, + EASING_IN_OUT_SINE, + EASING_OUT_IN_SINE, + /* Expo */ + EASING_IN_EXPO, + EASING_OUT_EXPO, + EASING_IN_OUT_EXPO, + EASING_OUT_IN_EXPO, + /* Circ */ + EASING_IN_CIRC, + EASING_OUT_CIRC, + EASING_IN_OUT_CIRC, + EASING_OUT_IN_CIRC, + /* Bounce */ + EASING_IN_BOUNCE, + EASING_OUT_BOUNCE, + EASING_IN_OUT_BOUNCE, + EASING_OUT_IN_BOUNCE, +}; -float linear(float t, float b, float c, float d); +void menu_animation_free(animation_t *animation); -float inQuad(float t, float b, float c, float d); +bool menu_animation_push(animation_t *animation, float duration, + float target_value, float* subject, + enum animation_easing_type easing_enum, tween_cb cb); -float outQuad(float t, float b, float c, float d); +void menu_animation_update(animation_t *animation, float dt); -float inOutQuad(float t, float b, float c, float d); - -float outInQuad(float t, float b, float c, float d); - -float inCubic(float t, float b, float c, float d); - -float outCubic(float t, float b, float c, float d); - -float inOutCubic(float t, float b, float c, float d); - -float outInCubic(float t, float b, float c, float d); - -float inQuart(float t, float b, float c, float d); - -float outQuart(float t, float b, float c, float d); - -float inOutQuart(float t, float b, float c, float d); - -float outInQuart(float t, float b, float c, float d); - -float inQuint(float t, float b, float c, float d); - -float outQuint(float t, float b, float c, float d); - -float inOutQuint(float t, float b, float c, float d); - -float outInQuint(float t, float b, float c, float d); - -float inSine(float t, float b, float c, float d); - -float outSine(float t, float b, float c, float d); - -float inOutSine(float t, float b, float c, float d); - -float outInSine(float t, float b, float c, float d); - -float inExpo(float t, float b, float c, float d); - -float outExpo(float t, float b, float c, float d); - -float inOutExpo(float t, float b, float c, float d); - -float outInExpo(float t, float b, float c, float d); - -float inCirc(float t, float b, float c, float d); - -float outCirc(float t, float b, float c, float d); - -float inOutCirc(float t, float b, float c, float d); - -float outInCirc(float t, float b, float c, float d); - -float inBounce(float t, float b, float c, float d); - -float outBounce(float t, float b, float c, float d); - -float inOutBounce(float t, float b, float c, float d); - -float outInBounce(float t, float b, float c, float d); +/** + * menu_animation_ticker_line: + * @buf : buffer to write new message line to. + * @len : length of buffer @input. + * @idx : Index. Will be used for ticker logic. + * @str : Input string. + * @selected : Is the item currently selected in the menu? + * + * Take the contents of @str and apply a ticker effect to it, + * and write the results in @buf. + **/ +void menu_animation_ticker_line(char *buf, size_t len, unsigned tick, + const char *str, bool selected); #ifdef __cplusplus } diff --git a/menu/menu_database.c b/menu/menu_database.c index fe10269ab2..3e26caabf4 100644 --- a/menu/menu_database.c +++ b/menu/menu_database.c @@ -27,7 +27,7 @@ int menu_database_populate_query(file_list_t *list, const char *path, #ifdef HAVE_LIBRETRODB libretrodb_t db; libretrodb_cursor_t cur; - + if ((libretrodb_open(path, &db)) != 0) return -1; if ((database_open_cursor(&db, &cur, query) != 0)) @@ -54,9 +54,13 @@ void menu_database_free(menu_handle_t *menu) menu_database_playlist_free(menu); } -bool menu_database_realloc(menu_handle_t *menu, const char *path, +bool menu_database_realloc(const char *path, bool force) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return false; + if (!strcmp(menu->db_playlist_file, path) && !force) return true; diff --git a/menu/menu_database.h b/menu/menu_database.h index 41ba3c7b40..84c035f682 100644 --- a/menu/menu_database.h +++ b/menu/menu_database.h @@ -32,7 +32,7 @@ int menu_database_populate_query(file_list_t *list, const char *path, void menu_database_free(menu_handle_t *menu); -bool menu_database_realloc(menu_handle_t *menu, const char *path, +bool menu_database_realloc(const char *path, bool force); #ifdef __cplusplus diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 04502c23d5..46ee40bc7d 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -160,3 +160,10 @@ void init_menu(void) rarch_fail(1, "init_menu()"); } } + +menu_handle_t *menu_driver_resolve(void) +{ + if (!driver.menu) + return NULL; + return driver.menu; +} diff --git a/menu/menu_driver.h b/menu/menu_driver.h index de3c171c47..1e84e17ea4 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -68,22 +68,52 @@ struct menu_bind_state bool skip; }; +typedef struct menu_framebuf +{ + uint16_t *data; + unsigned width; + unsigned height; + size_t pitch; +} menu_framebuf_t; + +typedef struct menu_navigation +{ + struct + { + /* Quick jumping indices with L/R. + * Rebuilt when parsing directory. */ + struct + { + size_t list[2 * (26 + 2) + 1]; + unsigned size; + } indices; + unsigned acceleration; + } scroll; + size_t selection_ptr; +} menu_navigation_t; + typedef struct { void *userdata; /* Used for key repeat */ - unsigned delay_timer; - unsigned delay_count; + struct + { + unsigned timer; + unsigned count; + } delay; - unsigned width; - unsigned height; size_t begin; menu_list_t *menu_list; - size_t cat_selection_ptr; - size_t num_categories; - size_t selection_ptr; + menu_navigation_t navigation; + + struct + { + size_t selection_ptr; + size_t size; + } categories; + bool need_refresh; bool msg_force; bool push_start_screen; @@ -97,15 +127,12 @@ typedef struct */ char message_contents[PATH_MAX_LENGTH]; - /* Quick jumping indices with L/R. - * Rebuilt when parsing directory. */ - size_t scroll_indices[2 * (26 + 2) + 1]; - unsigned scroll_indices_size; - unsigned scroll_accel; char default_glslp[PATH_MAX_LENGTH]; char default_cgp[PATH_MAX_LENGTH]; + menu_framebuf_t frame_buf; + const uint8_t *font; bool alloc_font; @@ -142,8 +169,7 @@ typedef struct } keyboard; rarch_setting_t *list_settings; - tween_t* tweens; - unsigned numtweens; + animation_t *animation; content_playlist_t *db_playlist; char db_playlist_file[PATH_MAX_LENGTH]; @@ -176,30 +202,31 @@ typedef struct menu_file_list_cbs typedef struct menu_ctx_driver { - void (*set_texture)(void*); - void (*render_messagebox)(const char*); + void (*set_texture)(void); + void (*render_messagebox)(const char *msg); void (*render)(void); void (*frame)(void); void* (*init)(void); void (*free)(void*); - void (*context_reset)(void*); - void (*context_destroy)(void*); - void (*populate_entries)(void*, const char *, const char *, - unsigned); + void (*context_reset)(void); + void (*context_destroy)(void); + void (*populate_entries)(const char *path, const char *label, + unsigned k); void (*toggle)(bool); - void (*navigation_clear)(void *, bool); - void (*navigation_decrement)(void *); - void (*navigation_increment)(void *); - void (*navigation_set)(void *, bool); - void (*navigation_set_last)(void *); - void (*navigation_descend_alphabet)(void *, size_t *); - void (*navigation_ascend_alphabet)(void *, size_t *); - void (*list_insert)(void *, const char *, const char *, size_t); - void (*list_delete)(void *, size_t, size_t); - void (*list_clear)(void *); + void (*navigation_clear)(bool); + void (*navigation_decrement)(void); + void (*navigation_increment)(void); + void (*navigation_set)(bool); + void (*navigation_set_last)(void); + void (*navigation_descend_alphabet)(size_t *); + void (*navigation_ascend_alphabet)(size_t *); + void (*list_insert)(file_list_t *list, const char *, const char *, size_t); + void (*list_delete)(file_list_t *list, size_t, size_t); + void (*list_clear)(file_list_t *list); void (*list_cache)(bool, unsigned); - void (*list_set_selection)(void *); + void (*list_set_selection)(file_list_t *list); int (*entry_iterate)(unsigned); + bool (*load_background)(const char * path); const char *ident; } menu_ctx_driver_t; @@ -243,6 +270,8 @@ void find_menu_driver(void); void init_menu(void); +menu_handle_t *menu_driver_resolve(void); + #ifdef __cplusplus } #endif diff --git a/menu/menu_entries.c b/menu/menu_entries.c index 6d99f910bc..af30776c1a 100644 --- a/menu/menu_entries.c +++ b/menu/menu_entries.c @@ -16,6 +16,7 @@ #include "menu_entries.h" #include "menu_action.h" +#include "menu_navigation.h" #include #include #include "../file_extract.h" @@ -63,6 +64,9 @@ int menu_entries_push_query(libretrodb_t *db, { struct rmsgpack_dom_value *key = &item.map.items[i].key; struct rmsgpack_dom_value *val = &item.map.items[i].value; + + if (!key || !val) + continue; if (!strcmp(key->string.buff, "name")) { @@ -94,7 +98,7 @@ int menu_entries_push_list(menu_handle_t *menu, /* Hack - should come up with something cleaner * here. */ - if (!strcmp(label, "Video Options")) + if (!strcmp(label, "Video Settings")) { #if defined(GEKKO) || defined(__CELLOS_LV2__) menu_list_push(list, "Screen Resolution", "", @@ -118,7 +122,7 @@ int menu_entries_push_list(menu_handle_t *menu, } if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } @@ -143,6 +147,9 @@ static void menu_entries_content_list_push( for (j = 0; j < str_list->size; j++) { const char *name = str_list->elems[j].data; + + if (!name) + continue; if (str_list->elems[j].attr.i == RARCH_DIRECTORY) menu_entries_content_list_push(list, info, name); @@ -156,7 +163,7 @@ static void menu_entries_content_list_push( string_list_free(str_list); } -int menu_entries_push_cores_list(file_list_t *list, core_info_t *info, +static int menu_entries_push_cores_list(file_list_t *list, core_info_t *info, const char *path, bool push_databases_enable) { size_t i; @@ -205,7 +212,7 @@ int menu_entries_push_horizontal_menu_list(menu_handle_t *menu, if (!info_list) return -1; - info = (core_info_t*)&info_list->list[driver.menu->cat_selection_ptr - 1]; + info = (core_info_t*)&info_list->list[menu->categories.selection_ptr - 1]; if (!info) return -1; @@ -216,7 +223,7 @@ int menu_entries_push_horizontal_menu_list(menu_handle_t *menu, menu_entries_push_cores_list(list, info, g_settings.content_directory, true); - menu_list_populate_generic(menu, list, path, label, menu_type); + menu_list_populate_generic(list, path, label, menu_type); return 0; } @@ -338,7 +345,7 @@ int menu_entries_parse_list( { menu_entries_parse_drive_list(list); if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, dir, label, type); + driver.menu_ctx->populate_entries(dir, label, type); return 0; } #if defined(GEKKO) && defined(HW_RVL) @@ -469,7 +476,7 @@ int menu_entries_parse_list( menu_list_sort_on_alt(list); } - menu_list_populate_generic(driver.menu, list, dir, label, type); + menu_list_populate_generic(list, dir, label, type); return 0; } @@ -514,7 +521,7 @@ bool menu_entries_init(menu_handle_t *menu) menu->list_settings = setting_data_new(SL_FLAG_ALL); menu_list_push_stack(menu->menu_list, "", "Main Menu", MENU_SETTINGS, 0); - menu_navigation_clear(menu, true); + menu_navigation_clear(&menu->navigation, true); menu_entries_push_list(menu, menu->menu_list->selection_buf, "", "Main Menu", 0, SL_FLAG_MAIN_MENU); diff --git a/menu/menu_entries_cbs.c b/menu/menu_entries_cbs.c index f6725c08e5..7a55c2b5e7 100644 --- a/menu/menu_entries_cbs.c +++ b/menu/menu_entries_cbs.c @@ -20,6 +20,7 @@ #include "menu_input.h" #include "menu_entries.h" #include "menu_shader.h" +#include "menu_navigation.h" #include "../file_ext.h" #include "../file_extract.h" @@ -141,34 +142,43 @@ static int archive_open(void) const char *menu_label = NULL; const char* path = NULL; unsigned int type = 0; + menu_handle_t *menu = menu_driver_resolve(); - menu_list_pop_stack(driver.menu->menu_list); + if (!menu) + return -1; - menu_list_get_last_stack(driver.menu->menu_list, + menu_list_pop_stack(menu->menu_list); + + menu_list_get_last_stack(menu->menu_list, &menu_path, &menu_label, NULL); - if (menu_list_get_size(driver.menu->menu_list) == 0) + if (menu_list_get_size(menu->menu_list) == 0) return 0; - menu_list_get_at_offset(driver.menu->menu_list->selection_buf, - driver.menu->selection_ptr, &path, NULL, &type); + menu_list_get_at_offset(menu->menu_list->selection_buf, + menu->navigation.selection_ptr, &path, NULL, &type); fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, cat_path, menu_label, type, - driver.menu->selection_ptr); + menu->navigation.selection_ptr); return 0; } static void common_load_content(bool persist) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; + rarch_main_command(persist ? RARCH_CMD_LOAD_CONTENT_PERSIST : RARCH_CMD_LOAD_CONTENT); - menu_list_flush_stack(driver.menu->menu_list, MENU_SETTINGS); - driver.menu->msg_force = true; + + menu_list_flush_stack(menu->menu_list, MENU_SETTINGS); + menu->msg_force = true; } static int archive_load(void) @@ -178,20 +188,24 @@ static int archive_load(void) const char *menu_label = NULL; const char* path = NULL; unsigned int type = 0; + menu_handle_t *menu = menu_driver_resolve(); - menu_list_pop_stack(driver.menu->menu_list); + if (!menu) + return -1; - menu_list_get_last_stack(driver.menu->menu_list, + menu_list_pop_stack(menu->menu_list); + + menu_list_get_last_stack(menu->menu_list, &menu_path, &menu_label, NULL); - if (menu_list_get_size(driver.menu->menu_list) == 0) + if (menu_list_get_size(menu->menu_list) == 0) return 0; - menu_list_get_at_offset(driver.menu->menu_list->selection_buf, - driver.menu->selection_ptr, &path, NULL, &type); + menu_list_get_at_offset(menu->menu_list->selection_buf, + menu->navigation.selection_ptr, &path, NULL, &type); ret = rarch_defer_core(g_extern.core_info, menu_path, path, menu_label, - driver.menu->deferred_path, sizeof(driver.menu->deferred_path)); + menu->deferred_path, sizeof(menu->deferred_path)); switch (ret) { @@ -201,11 +215,11 @@ static int archive_load(void) break; case 0: menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, g_settings.libretro_directory, "deferred_core_list", 0, - driver.menu->selection_ptr); + menu->navigation.selection_ptr); break; } @@ -215,6 +229,10 @@ static int archive_load(void) static int load_or_open_zip_iterate(unsigned action) { char msg[PATH_MAX_LENGTH]; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return -1; snprintf(msg, sizeof(msg), "Opening compressed file\n" " \n" @@ -252,10 +270,11 @@ int menu_action_setting_set_current_string( static int action_ok_rdb_playlist_entry(const char *path, const char *label, unsigned type, size_t idx) { - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; - rarch_playlist_load_content(driver.menu->db_playlist, + rarch_playlist_load_content(menu->db_playlist, rdb_entry_start_game_selection_ptr); return -1; } @@ -263,12 +282,13 @@ static int action_ok_rdb_playlist_entry(const char *path, static int action_ok_playlist_entry(const char *path, const char *label, unsigned type, size_t idx) { - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; rarch_playlist_load_content(g_defaults.history, - driver.menu->selection_ptr); - menu_list_flush_stack(driver.menu->menu_list, MENU_SETTINGS); + menu->navigation.selection_ptr); + menu_list_flush_stack(menu->menu_list, MENU_SETTINGS); return -1; } @@ -294,21 +314,23 @@ static int action_ok_shader_pass_load(const char *path, const char *label, unsigned type, size_t idx) { const char *menu_path = NULL; - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; + (void)menu_path; #ifdef HAVE_SHADER_MANAGER - menu_list_get_last_stack(driver.menu->menu_list, &menu_path, NULL, + menu_list_get_last_stack(menu->menu_list, &menu_path, NULL, NULL); - fill_pathname_join(driver.menu->shader->pass[hack_shader_pass].source.path, + fill_pathname_join(menu->shader->pass[hack_shader_pass].source.path, menu_path, path, - sizeof(driver.menu->shader->pass[hack_shader_pass].source.path)); + sizeof(menu->shader->pass[hack_shader_pass].source.path)); /* This will reset any changed parameters. */ - video_shader_resolve_parameters(NULL, driver.menu->shader); - menu_list_flush_stack_by_needle(driver.menu->menu_list, "Shader Options"); + video_shader_resolve_parameters(NULL, menu->shader); + menu_list_flush_stack_by_needle(menu->menu_list, "shader_options"); return 0; #else return -1; @@ -323,9 +345,12 @@ static int action_ok_shader_pass(const char *path, const char *label, unsigned type, size_t idx) { hack_shader_pass = type - MENU_SETTINGS_SHADER_PASS_0; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, g_settings.video.shader_dir, label, type, @@ -335,8 +360,11 @@ static int action_ok_shader_pass(const char *path, static int action_ok_shader_parameters(const char *path, const char *label, unsigned type, size_t idx) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, "", label, MENU_SETTING_ACTION, idx); } @@ -344,27 +372,38 @@ static int action_ok_shader_parameters(const char *path, static int action_ok_push_generic_list(const char *path, const char *label, unsigned type, size_t idx) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + if (path) - strlcpy(driver.menu->deferred_path, path, - sizeof(driver.menu->deferred_path)); + strlcpy(menu->deferred_path, path, + sizeof(menu->deferred_path)); + return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, "", label, type, idx); } static int action_ok_push_default(const char *path, const char *label, unsigned type, size_t idx) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, label, label, type, idx); } static int action_ok_shader_preset(const char *path, const char *label, unsigned type, size_t idx) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, g_settings.video.shader_dir, label, type, idx); } @@ -372,8 +411,11 @@ static int action_ok_shader_preset(const char *path, static int action_ok_push_content_list(const char *path, const char *label, unsigned type, size_t idx) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, g_settings.menu_content_directory, label, MENU_FILE_DIRECTORY, idx); } @@ -381,8 +423,11 @@ static int action_ok_push_content_list(const char *path, static int action_ok_disk_image_append_list(const char *path, const char *label, unsigned type, size_t idx) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, g_settings.menu_content_directory, label, type, idx); } @@ -391,8 +436,12 @@ static int action_ok_configurations_list(const char *path, const char *label, unsigned type, size_t idx) { const char *dir = g_settings.menu_config_directory; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, dir ? dir : label, label, type, idx); } @@ -400,17 +449,62 @@ static int action_ok_configurations_list(const char *path, static int action_ok_cheat_file(const char *path, const char *label, unsigned type, size_t idx) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + if (!path_file_exists(g_settings.cheat_database)) + { + msg_queue_clear(g_extern.msg_queue); + msg_queue_push(g_extern.msg_queue, "Cheat Directory doesn't exist or cannot be accessed.\n", 1, 180); + return -1; + } + return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, g_settings.cheat_database, label, type, idx); } +static int action_ok_audio_dsp_plugin(const char *path, + const char *label, unsigned type, size_t idx) +{ + if (!path_file_exists(path)) + { + msg_queue_clear(g_extern.msg_queue); + msg_queue_push(g_extern.msg_queue, "Audio Filter Directory doesn't exist or cannot be accessed.\n", 1, 180); + return -1; + } + return 0; +} + +static int action_ok_video_filter(const char *path, + const char *label, unsigned type, size_t idx) +{ + if (!path_file_exists(path)) + { + msg_queue_clear(g_extern.msg_queue); + msg_queue_push(g_extern.msg_queue, "Video Filter Directory doesn't exist or cannot be accessed.\n", 1, 180); + return -1; + } + return 0; +} + static int action_ok_remap_file(const char *path, const char *label, unsigned type, size_t idx) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + if (!path_file_exists(g_settings.input_remapping_directory)) + { + msg_queue_clear(g_extern.msg_queue); + msg_queue_push(g_extern.msg_queue, "Remapping Directory doesn't exist or cannot be accessed.\n", 1, 180); + return -1; + } return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, g_settings.input_remapping_directory, label, type, idx); } @@ -418,8 +512,18 @@ static int action_ok_remap_file(const char *path, static int action_ok_core_list(const char *path, const char *label, unsigned type, size_t idx) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + if (!path_file_exists(g_settings.libretro_directory)) + { + msg_queue_clear(g_extern.msg_queue); + msg_queue_push(g_extern.msg_queue, "Core Directory doesn't exist or cannot be accessed.\n", 1, 180); + return -1; + } return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, g_settings.libretro_directory, label, type, idx); } @@ -429,18 +533,20 @@ static int action_ok_remap_file_load(const char *path, { const char *menu_path = NULL; char remap_path[PATH_MAX_LENGTH]; - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; (void)remap_path; (void)menu_path; - menu_list_get_last_stack(driver.menu->menu_list, &menu_path, NULL, + + menu_list_get_last_stack(menu->menu_list, &menu_path, NULL, NULL); fill_pathname_join(remap_path, menu_path, path, sizeof(remap_path)); input_remapping_load_file(remap_path); - menu_list_flush_stack_by_needle(driver.menu->menu_list, "core_input_remapping_options"); + menu_list_flush_stack_by_needle(menu->menu_list, "core_input_remapping_options"); return 0; } @@ -450,12 +556,13 @@ static int action_ok_cheat_file_load(const char *path, { const char *menu_path = NULL; char cheat_path[PATH_MAX_LENGTH]; - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; (void)cheat_path; (void)menu_path; - menu_list_get_last_stack(driver.menu->menu_list, &menu_path, NULL, + menu_list_get_last_stack(menu->menu_list, &menu_path, NULL, NULL); fill_pathname_join(cheat_path, menu_path, path, sizeof(cheat_path)); @@ -468,7 +575,7 @@ static int action_ok_cheat_file_load(const char *path, if (!g_extern.cheat) return -1; - menu_list_flush_stack_by_needle(driver.menu->menu_list, "core_cheat_options"); + menu_list_flush_stack_by_needle(menu->menu_list, "core_cheat_options"); return 0; } @@ -480,11 +587,11 @@ static int action_ok_menu_wallpaper_load(const char *path, const char *menu_path = NULL; rarch_setting_t *setting = NULL; char wallpaper_path[PATH_MAX_LENGTH]; - - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; - menu_list_get_last_stack(driver.menu->menu_list, &menu_path, &menu_label, + menu_list_get_last_stack(menu->menu_list, &menu_path, &menu_label, NULL); setting = menu_action_find_setting(menu_label); @@ -494,8 +601,16 @@ static int action_ok_menu_wallpaper_load(const char *path, fill_pathname_join(wallpaper_path, menu_path, path, sizeof(wallpaper_path)); + if (!path_file_exists(wallpaper_path)) + goto end; + strlcpy(g_settings.menu.wallpaper, wallpaper_path, sizeof(g_settings.menu.wallpaper)); - menu_list_pop_stack_by_needle(driver.menu->menu_list, setting->name); + + if (driver.menu_ctx && driver.menu_ctx->load_background) + driver.menu_ctx->load_background(wallpaper_path); + +end: + menu_list_pop_stack_by_needle(menu->menu_list, setting->name); return 0; } @@ -505,20 +620,21 @@ static int action_ok_shader_preset_load(const char *path, { const char *menu_path = NULL; char shader_path[PATH_MAX_LENGTH]; - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; (void)shader_path; (void)menu_path; #ifdef HAVE_SHADER_MANAGER - menu_list_get_last_stack(driver.menu->menu_list, &menu_path, NULL, + menu_list_get_last_stack(menu->menu_list, &menu_path, NULL, NULL); fill_pathname_join(shader_path, menu_path, path, sizeof(shader_path)); - menu_shader_manager_set_preset(driver.menu->shader, + menu_shader_manager_set_preset(menu->shader, video_shader_parse_type(shader_path, RARCH_SHADER_NONE), shader_path); - menu_list_flush_stack_by_needle(driver.menu->menu_list, "Shader Options"); + menu_list_flush_stack_by_needle(menu->menu_list, "shader_options"); return 0; #else return -1; @@ -528,7 +644,7 @@ static int action_ok_shader_preset_load(const char *path, static int action_ok_cheat(const char *path, const char *label, unsigned type, size_t idx) { - menu_input_key_start_line(driver.menu, "Input Cheat", + menu_input_key_start_line("Input Cheat", label, type, idx, menu_input_st_cheat_callback); return 0; } @@ -536,7 +652,7 @@ static int action_ok_cheat(const char *path, static int action_ok_shader_preset_save_as(const char *path, const char *label, unsigned type, size_t idx) { - menu_input_key_start_line(driver.menu, "Preset Filename", + menu_input_key_start_line("Preset Filename", label, type, idx, menu_input_st_string_callback); return 0; } @@ -544,7 +660,7 @@ static int action_ok_shader_preset_save_as(const char *path, static int action_ok_cheat_file_save_as(const char *path, const char *label, unsigned type, size_t idx) { - menu_input_key_start_line(driver.menu, "Cheat Filename", + menu_input_key_start_line("Cheat Filename", label, type, idx, menu_input_st_string_callback); return 0; } @@ -552,7 +668,7 @@ static int action_ok_cheat_file_save_as(const char *path, static int action_ok_remap_file_save_as(const char *path, const char *label, unsigned type, size_t idx) { - menu_input_key_start_line(driver.menu, "Remapping Filename", + menu_input_key_start_line("Remapping Filename", label, type, idx, menu_input_st_string_callback); return 0; } @@ -563,11 +679,11 @@ static int action_ok_path_use_directory(const char *path, const char *menu_label = NULL; const char *menu_path = NULL; rarch_setting_t *setting = NULL; - - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; - menu_list_get_last_stack(driver.menu->menu_list, + menu_list_get_last_stack(menu->menu_list, &menu_path, &menu_label, NULL); setting = menu_action_find_setting(menu_label); @@ -579,7 +695,7 @@ static int action_ok_path_use_directory(const char *path, return -1; menu_action_setting_set_current_string(setting, menu_path); - menu_list_pop_stack_by_needle(driver.menu->menu_list, setting->name); + menu_list_pop_stack_by_needle(menu->menu_list, setting->name); return 0; } @@ -587,12 +703,13 @@ static int action_ok_path_use_directory(const char *path, static int action_ok_core_load_deferred(const char *path, const char *label, unsigned type, size_t idx) { - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; if (path) strlcpy(g_settings.libretro, path, sizeof(g_settings.libretro)); - strlcpy(g_extern.fullpath, driver.menu->deferred_path, + strlcpy(g_extern.fullpath, menu->deferred_path, sizeof(g_extern.fullpath)); common_load_content(false); @@ -744,7 +861,7 @@ static int deferred_push_core_information(void *data, void *userdata, MENU_SETTINGS_CORE_OPTION_NONE, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } @@ -791,7 +908,7 @@ static int create_string_list_rdb_entry_string(const char *desc, const char *lab return 0; } -static uint32_t create_string_list_rdb_entry_int(const char *desc, const char *label, +static int create_string_list_rdb_entry_int(const char *desc, const char *label, int actual_int, const char *path, file_list_t *list) { char tmp[PATH_MAX_LENGTH]; @@ -807,8 +924,8 @@ static uint32_t create_string_list_rdb_entry_int(const char *desc, const char *l str_len += strlen(label) + 1; string_list_append(str_list, label, attr); - str_len += sizeof(actual_int); snprintf(str, sizeof(str), "%d", actual_int); + str_len += strlen(str) + 1; string_list_append(str_list, str, attr); str_len += strlen(path) + 1; @@ -847,9 +964,16 @@ static int deferred_push_rdb_entry_detail(void *data, void *userdata, unsigned i, j; int ret = 0; database_info_list_t *db_info = NULL; - file_list_t *list = (file_list_t*)data; - file_list_t *menu_list = (file_list_t*)userdata; - struct string_list *str_list = string_split(label, "|"); + file_list_t *list = NULL; + file_list_t *menu_list = NULL; + struct string_list *str_list = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + list = (file_list_t*)data; + menu_list = (file_list_t*)userdata; + str_list = string_split(label, "|"); if (!str_list) return -1; @@ -879,9 +1003,9 @@ static int deferred_push_rdb_entry_detail(void *data, void *userdata, fill_pathname_join(path_rdl, g_settings.content_database, path_base, sizeof(path_rdl)); - menu_database_realloc(driver.menu, path_rdl, false); + menu_database_realloc(path_rdl, false); - playlist = driver.menu->db_playlist; + playlist = menu->db_playlist; for (i = 0; i < db_info->count; i++) { @@ -1095,7 +1219,7 @@ static int deferred_push_rdb_entry_detail(void *data, void *userdata, 0, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, + driver.menu_ctx->populate_entries(path, str_list->elems[0].data, type); ret = 0; @@ -1113,11 +1237,15 @@ static int action_ok_rdb_entry(const char *path, const char *label, unsigned type, size_t idx) { char tmp[PATH_MAX_LENGTH]; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + strlcpy(tmp, "deferred_rdb_entry_detail|", sizeof(tmp)); strlcat(tmp, path, sizeof(tmp)); return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, label, tmp, 0, idx); @@ -1133,19 +1261,20 @@ static int action_ok_core_load(const char *path, const char *label, unsigned type, size_t idx) { const char *menu_path = NULL; - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; - menu_list_get_last_stack(driver.menu->menu_list, + menu_list_get_last_stack(menu->menu_list, &menu_path, NULL, NULL); fill_pathname_join(g_settings.libretro, menu_path, path, sizeof(g_settings.libretro)); rarch_main_command(RARCH_CMD_LOAD_CORE); - menu_list_flush_stack(driver.menu->menu_list, MENU_SETTINGS); + menu_list_flush_stack(menu->menu_list, MENU_SETTINGS); #if defined(HAVE_DYNAMIC) /* No content needed for this core, load core immediately. */ - if (driver.menu->load_no_content) + if (menu->load_no_content) { *g_extern.fullpath = '\0'; common_load_content(false); @@ -1170,11 +1299,12 @@ static int action_ok_core_download(const char *path, static int action_ok_compressed_archive_push(const char *path, const char *label, unsigned type, size_t idx) { - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; menu_list_push_stack( - driver.menu->menu_list, + menu->menu_list, path, "load_open_zip", 0, @@ -1189,19 +1319,19 @@ static int action_ok_directory_push(const char *path, const char *menu_path = NULL; const char *menu_label = NULL; char cat_path[PATH_MAX_LENGTH]; - - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; if (!path) return -1; - menu_list_get_last_stack(driver.menu->menu_list, + menu_list_get_last_stack(menu->menu_list, &menu_path, &menu_label, NULL); fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); - return menu_list_push_stack_refresh(driver.menu->menu_list, + return menu_list_push_stack_refresh(menu->menu_list, cat_path, menu_label, type, idx); } @@ -1209,6 +1339,9 @@ static int action_ok_database_manager_list(const char *path, const char *label, unsigned type, size_t idx) { char rdb_path[PATH_MAX_LENGTH]; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; if (!path) return -1; if (!label) @@ -1217,8 +1350,16 @@ static int action_ok_database_manager_list(const char *path, fill_pathname_join(rdb_path, g_settings.content_database, path, sizeof(rdb_path)); + if (!path_file_exists(rdb_path)) + { + msg_queue_clear(g_extern.msg_queue); + msg_queue_push(g_extern.msg_queue, + "Database Directory doesn't exist or cannot be accessed.\n", + 1, 180); + return -1; + } return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, rdb_path, "deferred_database_manager_list", 0, idx); @@ -1228,12 +1369,24 @@ static int action_ok_cursor_manager_list(const char *path, const char *label, unsigned type, size_t idx) { char cursor_path[PATH_MAX_LENGTH]; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return -1; fill_pathname_join(cursor_path, g_settings.cursor_directory, path, sizeof(cursor_path)); + if (!path_file_exists(cursor_path)) + { + msg_queue_clear(g_extern.msg_queue); + msg_queue_push(g_extern.msg_queue, + "Cursor Directory doesn't exist or cannot be accessed.\n", + 1, 180); + return -1; + } return menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, cursor_path, "deferred_cursor_manager_list", 0, idx); @@ -1244,19 +1397,20 @@ static int action_ok_config_load(const char *path, { const char *menu_path = NULL; char config[PATH_MAX_LENGTH]; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu) + if (!menu) return -1; - menu_list_get_last_stack(driver.menu->menu_list, + menu_list_get_last_stack(menu->menu_list, &menu_path, NULL, NULL); fill_pathname_join(config, menu_path, path, sizeof(config)); - menu_list_flush_stack(driver.menu->menu_list, MENU_SETTINGS); - driver.menu->msg_force = true; + menu_list_flush_stack(menu->menu_list, MENU_SETTINGS); + menu->msg_force = true; if (rarch_replace_config(config)) { - menu_navigation_clear(driver.menu, false); + menu_navigation_clear(&menu->navigation, false); return -1; } @@ -1266,13 +1420,14 @@ static int action_ok_config_load(const char *path, static int action_ok_disk_image_append(const char *path, const char *label, unsigned type, size_t idx) { - const char *menu_path = NULL; char image[PATH_MAX_LENGTH]; + const char *menu_path = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu) + if (!menu) return -1; - menu_list_get_last_stack(driver.menu->menu_list, + menu_list_get_last_stack(menu->menu_list, &menu_path, NULL, NULL); fill_pathname_join(image, menu_path, path, sizeof(image)); @@ -1280,25 +1435,26 @@ static int action_ok_disk_image_append(const char *path, rarch_main_command(RARCH_CMD_RESUME); - menu_list_flush_stack(driver.menu->menu_list, MENU_SETTINGS); + menu_list_flush_stack(menu->menu_list, MENU_SETTINGS); return -1; } static int action_ok_file_load_with_detect_core(const char *path, const char *label, unsigned type, size_t idx) { - const char *menu_path = NULL; int ret; + const char *menu_path = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu) + if (!menu) return -1; - menu_list_get_last_stack(driver.menu->menu_list, + menu_list_get_last_stack(menu->menu_list, &menu_path, NULL, NULL); ret = rarch_defer_core(g_extern.core_info, - menu_path, path, label, driver.menu->deferred_path, - sizeof(driver.menu->deferred_path)); + menu_path, path, label, menu->deferred_path, + sizeof(menu->deferred_path)); if (ret == -1) { @@ -1309,7 +1465,7 @@ static int action_ok_file_load_with_detect_core(const char *path, if (ret == 0) menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, g_settings.libretro_directory, "deferred_core_list", 0, idx); @@ -1331,11 +1487,12 @@ static int action_ok_file_load(const char *path, const char *menu_label = NULL; const char *menu_path = NULL; rarch_setting_t *setting = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu) + if (!menu) return -1; - menu_list_get_last(driver.menu->menu_list->menu_stack, + menu_list_get_last(menu->menu_list->menu_stack, &menu_path, &menu_label, NULL); setting = menu_action_find_setting(menu_label); @@ -1343,7 +1500,7 @@ static int action_ok_file_load(const char *path, if (setting && setting->type == ST_PATH) { menu_action_setting_set_current_string_path(setting, menu_path, path); - menu_list_pop_stack_by_needle(driver.menu->menu_list, setting->name); + menu_list_pop_stack_by_needle(menu->menu_list, setting->name); } else { @@ -1368,11 +1525,12 @@ static int action_ok_set_path(const char *path, const char *menu_path = NULL; const char *menu_label = NULL; rarch_setting_t *setting = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu) + if (!menu) return -1; - menu_list_get_last_stack(driver.menu->menu_list, + menu_list_get_last_stack(menu->menu_list, &menu_path, &menu_label, NULL); setting = menu_action_find_setting(menu_label); @@ -1381,7 +1539,7 @@ static int action_ok_set_path(const char *path, return -1; menu_action_setting_set_current_string_path(setting, menu_path, path); - menu_list_pop_stack_by_needle(driver.menu->menu_list, setting->name); + menu_list_pop_stack_by_needle(menu->menu_list, setting->name); return 0; } @@ -1389,12 +1547,18 @@ static int action_ok_set_path(const char *path, static int action_ok_custom_viewport(const char *path, const char *label, unsigned type, size_t idx) { + rarch_viewport_t *custom = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return -1; + /* Start with something sane. */ - rarch_viewport_t *custom = (rarch_viewport_t*) + custom = (rarch_viewport_t*) &g_extern.console.screen.viewports.custom_vp; menu_list_push_stack( - driver.menu->menu_list, + menu->menu_list, "", "custom_viewport_1", MENU_SETTINGS_CUSTOM_VIEWPORT, @@ -1416,8 +1580,6 @@ static int action_ok_custom_viewport(const char *path, static int generic_action_ok_command(unsigned cmd) { - if (!driver.menu) - return -1; if (!rarch_main_command(cmd)) return -1; @@ -1591,12 +1753,17 @@ static int action_ok_screenshot(const char *path, static int action_ok_file_load_or_resume(const char *path, const char *label, unsigned type, size_t idx) { - if (!strcmp(driver.menu->deferred_path, g_extern.fullpath)) + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return -1; + + if (!strcmp(menu->deferred_path, g_extern.fullpath)) return generic_action_ok_command(RARCH_CMD_RESUME); else { strlcpy(g_extern.fullpath, - driver.menu->deferred_path, sizeof(g_extern.fullpath)); + menu->deferred_path, sizeof(g_extern.fullpath)); rarch_main_command(RARCH_CMD_LOAD_CORE); rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT); return -1; @@ -1625,6 +1792,10 @@ static int action_ok_rdb_entry_submenu(const char *path, int len = 0; struct string_list *str_list = NULL; struct string_list *str_list2 = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return -1; if (!label) return -1; @@ -1667,7 +1838,7 @@ static int action_ok_rdb_entry_submenu(const char *path, strlcat(new_label, str_list->elems[0].data, sizeof(new_label)); ret = menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, rdb, new_label, 0, idx); @@ -1688,8 +1859,12 @@ static int action_cancel_lookup_setting(const char *path, static int action_cancel_pop_default(const char *path, const char *label, unsigned type, size_t idx) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + menu_apply_deferred_settings(); - menu_list_pop_stack(driver.menu->menu_list); + menu_list_pop_stack(menu->menu_list); return 0; } @@ -1697,16 +1872,17 @@ static int action_cancel_pop_default(const char *path, static int action_ok_help(const char *path, const char *label, unsigned type, size_t idx) { - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; menu_list_push_stack( - driver.menu->menu_list, + menu->menu_list, "", "help", 0, 0); - driver.menu->push_start_screen = false; + menu->push_start_screen = false; return 0; } @@ -1781,8 +1957,11 @@ static int action_start_shader_action_preset_parameter(unsigned type, const char #ifdef HAVE_SHADER_MANAGER struct video_shader *shader = NULL; struct video_shader_parameter *param = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; - if (!(shader = driver.menu->shader)) + if (!(shader = menu->shader)) return 0; param = &shader->parameters[type - MENU_SETTINGS_SHADER_PRESET_PARAMETER_0]; @@ -1834,8 +2013,11 @@ static int shader_action_parameter_preset_toggle(unsigned type, const char *labe #ifdef HAVE_SHADER_MANAGER struct video_shader *shader = NULL; struct video_shader_parameter *param = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; - if (!(shader = driver.menu->shader)) + if (!(shader = menu->shader)) return 0; param = &shader->parameters[type - MENU_SETTINGS_SHADER_PRESET_PARAMETER_0]; @@ -1909,8 +2091,13 @@ static int action_start_shader_pass(unsigned type, const char *label, { #ifdef HAVE_SHADER_MANAGER hack_shader_pass = type - MENU_SETTINGS_SHADER_PASS_0; - struct video_shader *shader = driver.menu->shader; + struct video_shader *shader = NULL; struct video_shader_pass *shader_pass = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + shader = menu->shader; if (shader) shader_pass = &shader->pass[hack_shader_pass]; @@ -1927,14 +2114,24 @@ static int action_start_shader_scale_pass(unsigned type, const char *label, unsigned action) { #ifdef HAVE_SHADER_MANAGER + struct video_shader *shader = NULL; + struct video_shader_pass *shader_pass = NULL; unsigned pass = type - MENU_SETTINGS_SHADER_PASS_SCALE_0; - struct video_shader *shader = driver.menu->shader; - struct video_shader_pass *shader_pass = &shader->pass[pass]; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + shader = menu->shader; if (shader) { - shader_pass->fbo.scale_x = shader_pass->fbo.scale_y = 0; - shader_pass->fbo.valid = false; + shader_pass = &shader->pass[pass]; + + if (shader_pass) + { + shader_pass->fbo.scale_x = shader_pass->fbo.scale_y = 0; + shader_pass->fbo.valid = false; + } } #endif @@ -1963,29 +2160,30 @@ static int action_toggle_scroll(unsigned type, const char *label, unsigned action) { unsigned scroll_speed = 0, fast_scroll_speed = 0; - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; - scroll_speed = (max(driver.menu->scroll_accel, 2) - 2) / 4 + 1; + scroll_speed = (max(menu->navigation.scroll.acceleration, 2) - 2) / 4 + 1; fast_scroll_speed = 4 + 4 * scroll_speed; switch (action) { case MENU_ACTION_LEFT: - if (driver.menu->selection_ptr > fast_scroll_speed) - menu_navigation_set(driver.menu, - driver.menu->selection_ptr - fast_scroll_speed, true); + if (menu->navigation.selection_ptr > fast_scroll_speed) + menu_navigation_set(&menu->navigation, + menu->navigation.selection_ptr - fast_scroll_speed, true); else - menu_navigation_clear(driver.menu, false); + menu_navigation_clear(&menu->navigation, false); break; case MENU_ACTION_RIGHT: - if (driver.menu->selection_ptr + fast_scroll_speed < (menu_list_get_size(driver.menu->menu_list))) - menu_navigation_set(driver.menu, - driver.menu->selection_ptr + fast_scroll_speed, true); + if (menu->navigation.selection_ptr + fast_scroll_speed < (menu_list_get_size(menu->menu_list))) + menu_navigation_set(&menu->navigation, + menu->navigation.selection_ptr + fast_scroll_speed, true); else { - if ((menu_list_get_size(driver.menu->menu_list) > 0)) - menu_navigation_set_last(driver.menu); + if ((menu_list_get_size(menu->menu_list) > 0)) + menu_navigation_set_last(&menu->navigation); } break; } @@ -1998,23 +2196,24 @@ static int action_toggle_mainmenu(unsigned type, const char *label, { menu_file_list_cbs_t *cbs = NULL; unsigned push_list = 0; - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return -1; - if (file_list_get_size(driver.menu->menu_list->menu_stack) == 1) + if (file_list_get_size(menu->menu_list->menu_stack) == 1) { if (!strcmp(driver.menu_ctx->ident, "xmb")) { - driver.menu->selection_ptr = 0; + menu->navigation.selection_ptr = 0; switch (action) { case MENU_ACTION_LEFT: - if (driver.menu->cat_selection_ptr == 0) + if (menu->categories.selection_ptr == 0) break; push_list = 1; break; case MENU_ACTION_RIGHT: - if (driver.menu->cat_selection_ptr == driver.menu->num_categories-1) + if (menu->categories.selection_ptr == (menu->categories.size - 1)) break; push_list = 1; break; @@ -2025,8 +2224,8 @@ static int action_toggle_mainmenu(unsigned type, const char *label, push_list = 2; cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(driver.menu->menu_list->selection_buf, - driver.menu->selection_ptr); + menu_list_get_actiondata_at_offset(menu->menu_list->selection_buf, + menu->navigation.selection_ptr); switch (push_list) { @@ -2036,8 +2235,8 @@ static int action_toggle_mainmenu(unsigned type, const char *label, if (cbs && cbs->action_content_list_switch) return cbs->action_content_list_switch( - driver.menu->menu_list->selection_buf, - driver.menu->menu_list->menu_stack, + menu->menu_list->selection_buf, + menu->menu_list->menu_stack, "", "", 0); @@ -2058,23 +2257,30 @@ static int action_toggle_shader_scale_pass(unsigned type, const char *label, { #ifdef HAVE_SHADER_MANAGER unsigned pass = type - MENU_SETTINGS_SHADER_PASS_SCALE_0; - struct video_shader *shader = driver.menu->shader; - struct video_shader_pass *shader_pass = &shader->pass[pass]; + struct video_shader *shader = NULL; + struct video_shader_pass *shader_pass = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + shader = menu->shader; + if (!shader) + return -1; + shader_pass = &shader->pass[pass]; + if (!shader_pass) + return -1; switch (action) { case MENU_ACTION_LEFT: case MENU_ACTION_RIGHT: { - unsigned current_scale = shader_pass->fbo.scale_x; - unsigned delta = action == MENU_ACTION_LEFT ? 5 : 1; - current_scale = (current_scale + delta) % 6; + unsigned current_scale = shader_pass->fbo.scale_x; + unsigned delta = (action == MENU_ACTION_LEFT) ? 5 : 1; + current_scale = (current_scale + delta) % 6; - if (shader_pass) - { - shader_pass->fbo.valid = current_scale; - shader_pass->fbo.scale_x = shader_pass->fbo.scale_y = current_scale; - } + shader_pass->fbo.valid = current_scale; + shader_pass->fbo.scale_x = shader_pass->fbo.scale_y = current_scale; } break; } @@ -2087,11 +2293,20 @@ static int action_start_shader_filter_pass(unsigned type, const char *label, { #ifdef HAVE_SHADER_MANAGER unsigned pass = type - MENU_SETTINGS_SHADER_PASS_FILTER_0; - struct video_shader *shader = driver.menu->shader; - struct video_shader_pass *shader_pass = &shader->pass[pass]; + struct video_shader *shader = NULL; + struct video_shader_pass *shader_pass = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + shader = menu->shader; + if (!shader) + return -1; + shader_pass = &shader->pass[pass]; + if (!shader_pass) + return -1; - if (shader && shader_pass) - shader_pass->filter = RARCH_FILTER_UNSPEC; + shader_pass->filter = RARCH_FILTER_UNSPEC; #endif return 0; @@ -2102,8 +2317,18 @@ static int action_toggle_shader_filter_pass(unsigned type, const char *label, { #ifdef HAVE_SHADER_MANAGER unsigned pass = type - MENU_SETTINGS_SHADER_PASS_FILTER_0; - struct video_shader *shader = driver.menu->shader; - struct video_shader_pass *shader_pass = &shader->pass[pass]; + struct video_shader *shader = NULL; + struct video_shader_pass *shader_pass = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + shader = menu->shader; + if (!shader) + return -1; + shader_pass = &shader->pass[pass]; + if (!shader_pass) + return -1; switch (action) { @@ -2111,8 +2336,7 @@ static int action_toggle_shader_filter_pass(unsigned type, const char *label, case MENU_ACTION_RIGHT: { unsigned delta = (action == MENU_ACTION_LEFT) ? 2 : 1; - if (shader_pass) - shader_pass->filter = ((shader_pass->filter + delta) % 3); + shader_pass->filter = ((shader_pass->filter + delta) % 3); } break; } @@ -2135,16 +2359,19 @@ static int action_start_shader_num_passes(unsigned type, const char *label, unsigned action) { #ifdef HAVE_SHADER_MANAGER - struct video_shader *shader = driver.menu->shader; - + struct video_shader *shader = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + shader = menu->shader; if (!shader) return -1; - if (shader->passes) shader->passes = 0; - driver.menu->need_refresh = true; + menu->need_refresh = true; - video_shader_resolve_parameters(NULL, driver.menu->shader); + video_shader_resolve_parameters(NULL, menu->shader); #endif return 0; } @@ -2153,6 +2380,9 @@ static int action_start_cheat_num_passes(unsigned type, const char *label, unsigned action) { cheat_manager_t *cheat = g_extern.cheat; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; if (!cheat) return -1; @@ -2160,7 +2390,7 @@ static int action_start_cheat_num_passes(unsigned type, const char *label, if (cheat->size) { cheat_manager_realloc(cheat, 0); - driver.menu->need_refresh = true; + menu->need_refresh = true; } return 0; @@ -2171,6 +2401,9 @@ static int action_toggle_cheat_num_passes(unsigned type, const char *label, { unsigned new_size = 0; cheat_manager_t *cheat = g_extern.cheat; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; if (!cheat) return -1; @@ -2180,16 +2413,16 @@ static int action_toggle_cheat_num_passes(unsigned type, const char *label, case MENU_ACTION_LEFT: if (cheat->size) new_size = cheat->size - 1; - driver.menu->need_refresh = true; + menu->need_refresh = true; break; case MENU_ACTION_RIGHT: new_size = cheat->size + 1; - driver.menu->need_refresh = true; + menu->need_refresh = true; break; } - if (driver.menu->need_refresh) + if (menu->need_refresh) cheat_manager_realloc(cheat, new_size); return 0; @@ -2199,8 +2432,12 @@ static int action_toggle_shader_num_passes(unsigned type, const char *label, unsigned action) { #ifdef HAVE_SHADER_MANAGER - struct video_shader *shader = driver.menu->shader; - + struct video_shader *shader = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + shader = menu->shader; if (!shader) return -1; @@ -2209,18 +2446,18 @@ static int action_toggle_shader_num_passes(unsigned type, const char *label, case MENU_ACTION_LEFT: if (shader->passes) shader->passes--; - driver.menu->need_refresh = true; + menu->need_refresh = true; break; case MENU_ACTION_RIGHT: if ((shader->passes < GFX_MAX_SHADERS)) shader->passes++; - driver.menu->need_refresh = true; + menu->need_refresh = true; break; } - if (driver.menu->need_refresh) - video_shader_resolve_parameters(NULL, driver.menu->shader); + if (menu->need_refresh) + video_shader_resolve_parameters(NULL, menu->shader); #endif return 0; @@ -2378,15 +2615,21 @@ static int deferred_push_core_list_deferred(void *data, void *userdata, unsigned i; size_t list_size = 0; const core_info_t *info = NULL; - file_list_t *list = (file_list_t*)data; - file_list_t *menu_list = (file_list_t*)userdata; + file_list_t *list = NULL; + file_list_t *menu_list = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + list = (file_list_t*)data; + menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; menu_list_clear(list); core_info_list_get_supported_cores(g_extern.core_info, - driver.menu->deferred_path, &info, &list_size); + menu->deferred_path, &info, &list_size); for (i = 0; i < list_size; i++) { @@ -2398,7 +2641,7 @@ static int deferred_push_core_list_deferred(void *data, void *userdata, menu_list_sort_on_alt(list); - menu_list_populate_generic(driver.menu, list, path, label, type); + menu_list_populate_generic(list, path, label, type); return 0; } @@ -2406,8 +2649,14 @@ static int deferred_push_core_list_deferred(void *data, void *userdata, static int deferred_push_database_manager_list_deferred(void *data, void *userdata, const char *path, const char *label, unsigned type) { - file_list_t *list = (file_list_t*)data; - file_list_t *menu_list = (file_list_t*)userdata; + file_list_t *list = NULL; + file_list_t *menu_list = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + list = (file_list_t*)data; + menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; @@ -2418,7 +2667,7 @@ static int deferred_push_database_manager_list_deferred(void *data, void *userda menu_list_sort_on_alt(list); - menu_list_populate_generic(driver.menu, list, path, label, type); + menu_list_populate_generic(list, path, label, type); return 0; } @@ -2429,8 +2678,14 @@ static int deferred_push_cursor_manager_list_deferred(void *data, void *userdata char *query = NULL, *rdb = NULL; char rdb_path[PATH_MAX_LENGTH]; config_file_t *conf = NULL; - file_list_t *list = (file_list_t*)data; - file_list_t *menu_list = (file_list_t*)userdata; + file_list_t *list = NULL; + file_list_t *menu_list = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + list = (file_list_t*)data; + menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; @@ -2455,7 +2710,7 @@ static int deferred_push_cursor_manager_list_deferred(void *data, void *userdata menu_list_sort_on_alt(list); - menu_list_populate_generic(driver.menu, list, path, label, type); + menu_list_populate_generic(list, path, label, type); return 0; } @@ -2465,10 +2720,18 @@ static int deferred_push_cursor_manager_list_deferred_query_subsearch( const char *path, const char *label, unsigned type) { char query[PATH_MAX_LENGTH]; - file_list_t *list = (file_list_t*)data; - file_list_t *menu_list = (file_list_t*)userdata; - struct string_list *str_list = string_split(path, "|"); + struct string_list *str_list = NULL; bool add_quotes = true; + file_list_t *list = NULL; + file_list_t *menu_list = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + str_list = string_split(path, "|"); + + list = (file_list_t*)data; + menu_list = (file_list_t*)userdata; if (!list || !menu_list) { @@ -2548,7 +2811,7 @@ static int deferred_push_cursor_manager_list_deferred_query_subsearch( menu_list_sort_on_alt(list); - menu_list_populate_generic(driver.menu, list, str_list->elems[0].data, label, type); + menu_list_populate_generic(list, str_list->elems[0].data, label, type); string_list_free(str_list); @@ -2694,7 +2957,7 @@ static int deferred_push_core_information(void *data, void *userdata, MENU_SETTINGS_CORE_OPTION_NONE, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } @@ -2716,14 +2979,17 @@ static int deferred_push_performance_counters(void *data, void *userdata, MENU_SETTING_ACTION, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } -static inline struct video_shader *shader_manager_get_current_shader( - menu_handle_t *menu, const char *label, unsigned type) +static inline struct video_shader *shader_manager_get_current_shader(const char *label, unsigned type) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return NULL; + if (!strcmp(label, "video_shader_preset_parameters")) return menu->shader; else if (!strcmp(label, "video_shader_parameters") && @@ -2753,7 +3019,7 @@ static int deferred_push_video_shader_parameters_common(void *data, void *userda } if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } @@ -2761,12 +3027,15 @@ static int deferred_push_video_shader_parameters_common(void *data, void *userda static int deferred_push_video_shader_preset_parameters(void *data, void *userdata, const char *path, const char *label, unsigned type) { - if (!driver.menu->shader) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + if (!menu->shader) return 0; return deferred_push_video_shader_parameters_common(data, userdata, path, label, type, - driver.menu->shader, MENU_SETTINGS_SHADER_PRESET_PARAMETER_0); + menu->shader, MENU_SETTINGS_SHADER_PRESET_PARAMETER_0); } static int deferred_push_video_shader_parameters(void *data, void *userdata, @@ -2788,16 +3057,23 @@ static int deferred_push_settings(void *data, void *userdata, const char *path, const char *label, unsigned type) { rarch_setting_t *setting = NULL; - file_list_t *list = (file_list_t*)data; - file_list_t *menu_list = (file_list_t*)userdata; + file_list_t *list = NULL; + file_list_t *menu_list = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return -1; + + list = (file_list_t*)data; + menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; - settings_list_free(driver.menu->list_settings); - driver.menu->list_settings = (rarch_setting_t *)setting_data_new(SL_FLAG_ALL_SETTINGS); + settings_list_free(menu->list_settings); + menu->list_settings = (rarch_setting_t *)setting_data_new(SL_FLAG_ALL_SETTINGS); - setting = menu_action_find_setting("Driver Options"); + setting = menu_action_find_setting("Driver Settings"); menu_list_clear(list); @@ -2838,7 +3114,7 @@ static int deferred_push_settings(void *data, void *userdata, } if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } @@ -2849,8 +3125,15 @@ static int deferred_push_settings_subgroup(void *data, void *userdata, char elem0[PATH_MAX_LENGTH], elem1[PATH_MAX_LENGTH]; rarch_setting_t *setting = NULL; struct string_list *str_list = NULL; - file_list_t *list = (file_list_t*)data; - file_list_t *menu_list = (file_list_t*)userdata; + file_list_t *list = NULL; + file_list_t *menu_list = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return -1; + + list = (file_list_t*)data; + menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; @@ -2871,8 +3154,8 @@ static int deferred_push_settings_subgroup(void *data, void *userdata, } } - settings_list_free(driver.menu->list_settings); - driver.menu->list_settings = (rarch_setting_t *)setting_data_new(SL_FLAG_ALL_SETTINGS); + settings_list_free(menu->list_settings); + menu->list_settings = (rarch_setting_t *)setting_data_new(SL_FLAG_ALL_SETTINGS); setting = menu_action_find_setting(elem0); @@ -2905,7 +3188,7 @@ static int deferred_push_settings_subgroup(void *data, void *userdata, } if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } @@ -2913,7 +3196,11 @@ static int deferred_push_settings_subgroup(void *data, void *userdata, static int deferred_push_category(void *data, void *userdata, const char *path, const char *label, unsigned type) { - return menu_entries_push_list(driver.menu, (file_list_t*)data, + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return -1; + return menu_entries_push_list(menu, (file_list_t*)data, path, label, type, SL_FLAG_ALL_SETTINGS); } @@ -2922,13 +3209,20 @@ static int deferred_push_shader_options(void *data, void *userdata, { unsigned i; struct video_shader *shader = NULL; - file_list_t *list = (file_list_t*)data; - file_list_t *menu_list = (file_list_t*)userdata; + file_list_t *list = NULL; + file_list_t *menu_list = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return -1; + + list = (file_list_t*)data; + menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; - shader = driver.menu->shader; + shader = menu->shader; if (!shader) return -1; @@ -2967,7 +3261,63 @@ static int deferred_push_shader_options(void *data, void *userdata, } if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); + + return 0; +} + +static int deferred_push_options(void *data, void *userdata, + const char *path, const char *label, unsigned type) +{ + file_list_t *list = (file_list_t*)data; + file_list_t *menu_list = (file_list_t*)userdata; + + if (!list || !menu_list) + return -1; + + menu_list_clear(list); + menu_list_push(list, "Core Options", "core_options", + MENU_SETTING_ACTION, 0); + if (g_extern.main_is_init) + { + if (g_extern.has_set_input_descriptors) + menu_list_push(list, "Core Input Remapping Options", "core_input_remapping_options", + MENU_SETTING_ACTION, 0); + menu_list_push(list, "Core Cheat Options", "core_cheat_options", + MENU_SETTING_ACTION, 0); + if (!g_extern.libretro_dummy && g_extern.system.disk_control.get_num_images) + menu_list_push(list, "Core Disk Options", "core_disk_options", + MENU_SETTING_ACTION, 0); + } + menu_list_push(list, "Shader Options", "shader_options", + MENU_SETTING_ACTION, 0); + + if (driver.menu_ctx && driver.menu_ctx->populate_entries) + driver.menu_ctx->populate_entries(path, label, type); + + return 0; +} + +static int deferred_push_management_options(void *data, void *userdata, + const char *path, const char *label, unsigned type) +{ + file_list_t *list = (file_list_t*)data; + file_list_t *menu_list = (file_list_t*)userdata; + + if (!list || !menu_list) + return -1; + + menu_list_clear(list); + +#ifdef HAVE_LIBRETRODB + menu_list_push(list, "Database Manager", "database_manager_list", + MENU_SETTING_ACTION, 0); + menu_list_push(list, "Cursor Manager", "cursor_manager_list", + MENU_SETTING_ACTION, 0); +#endif + + if (driver.menu_ctx && driver.menu_ctx->populate_entries) + driver.menu_ctx->populate_entries(path, label, type); return 0; } @@ -2996,17 +3346,24 @@ static int push_perfcounter_generic( unsigned num, unsigned ident, unsigned type) { - file_list_t *list = (file_list_t*)data; - file_list_t *menu_list = (file_list_t*)userdata; + file_list_t *list = NULL; + file_list_t *menu_list = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return -1; + + list = (file_list_t*)data; + menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; menu_list_clear(list); - push_perfcounter(driver.menu, list, counters, num, ident); + push_perfcounter(menu, list, counters, num, ident); if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } @@ -3069,7 +3426,7 @@ static int deferred_push_core_cheat_options(void *data, void *userdata, } if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } @@ -3112,7 +3469,7 @@ static int deferred_push_core_input_remapping_options(void *data, void *userdata } if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } @@ -3144,7 +3501,7 @@ static int deferred_push_core_options(void *data, void *userdata, MENU_SETTINGS_CORE_OPTION_NONE, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } @@ -3168,7 +3525,7 @@ static int deferred_push_disk_options(void *data, void *userdata, MENU_SETTINGS_CORE_DISK_OPTIONS_DISK_IMAGE_APPEND, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } @@ -3226,11 +3583,14 @@ static int cb_core_updater_list(void *data_, size_t len) { char *data = (char*)data_; file_list_t *list = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; if (!data) return -1; - list = (file_list_t*)driver.menu->menu_list->selection_buf; + list = (file_list_t*)menu->menu_list->selection_buf; if (!list) return -1; @@ -3240,8 +3600,7 @@ static int cb_core_updater_list(void *data_, size_t len) print_buf_lines(list, data, len, MENU_FILE_DOWNLOAD_CORE); - menu_list_populate_generic(driver.menu, - list, core_updater_list_path, + menu_list_populate_generic(list, core_updater_list_path, core_updater_list_label, core_updater_list_type); return 0; @@ -3275,7 +3634,7 @@ static int deferred_push_core_updater_list(void *data, void *userdata, 0, 0); #endif - menu_list_populate_generic(driver.menu, list, path, label, type); + menu_list_populate_generic(list, path, label, type); return 0; } @@ -3302,11 +3661,11 @@ static int deferred_push_history_list(void *data, void *userdata, size_t list_size = 0; file_list_t *list = (file_list_t*)data; - (void)userdata; - - if (!list || !driver.menu) + if (!list) return -1; + (void)userdata; + menu_list_clear(list); list_size = content_playlist_size(g_defaults.history); @@ -3331,7 +3690,7 @@ static int deferred_push_history_list(void *data, void *userdata, MENU_FILE_PLAYLIST_ENTRY, 0); } - menu_list_populate_generic(driver.menu, list, path, label, type); + menu_list_populate_generic(list, path, label, type); return 0; } @@ -3340,35 +3699,38 @@ static int deferred_push_content_actions(void *data, void *userdata, const char *path, const char *label, unsigned type) { file_list_t *list = (file_list_t*)data; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; (void)userdata; - if (!list || !driver.menu) + if (!list) return -1; menu_list_clear(list); if (g_extern.main_is_init && !g_extern.libretro_dummy && - !strcmp(driver.menu->deferred_path, g_extern.fullpath)) + !strcmp(menu->deferred_path, g_extern.fullpath)) { menu_list_push(list, "Resume", "file_load_or_resume", MENU_SETTING_ACTION_RUN, 0); - menu_list_push(list, "Core Informations", "core_information", MENU_SETTING_ACTION_CORE_INFORMATION, 0); + menu_list_push(list, "Save State", "savestate", MENU_SETTING_ACTION_SAVESTATE, 0); + menu_list_push(list, "Load State", "loadstate", MENU_SETTING_ACTION_LOADSTATE, 0); + menu_list_push(list, "Core Information", "core_information", MENU_SETTING_ACTION_CORE_INFORMATION, 0); menu_list_push(list, "Core Options", "core_options", MENU_SETTING_ACTION_CORE_OPTIONS, 0); if (g_extern.has_set_input_descriptors) menu_list_push(list, "Core Input Remapping Options", "core_input_remapping_options", MENU_SETTING_ACTION_CORE_INPUT_REMAPPING_OPTIONS, 0); menu_list_push(list, "Core Cheat Options", "core_cheat_options", MENU_SETTING_ACTION_CORE_CHEAT_OPTIONS, 0); if ( !g_extern.libretro_dummy && g_extern.system.disk_control.get_num_images) menu_list_push(list, "Core Disk Options", "disk_options", MENU_SETTING_ACTION_CORE_DISK_OPTIONS, 0); - menu_list_push(list, "Save State", "savestate", MENU_SETTING_ACTION_SAVESTATE, 0); - menu_list_push(list, "Load State", "loadstate", MENU_SETTING_ACTION_LOADSTATE, 0); menu_list_push(list, "Take Screenshot", "take_screenshot", MENU_SETTING_ACTION_SCREENSHOT, 0); menu_list_push(list, "Reset", "restart_content", MENU_SETTING_ACTION_RESET, 0); } else menu_list_push(list, "Run", "file_load_or_resume", MENU_SETTING_ACTION_RUN, 0); - menu_list_populate_generic(driver.menu, list, path, label, type); + menu_list_populate_generic(list, path, label, type); return 0; } @@ -3376,7 +3738,10 @@ static int deferred_push_content_actions(void *data, void *userdata, static int deferred_push_content_list(void *data, void *userdata, const char *path, const char *label, unsigned type) { - return menu_entries_deferred_push((file_list_t*)data, driver.menu->menu_list->selection_buf); + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + return menu_entries_deferred_push((file_list_t*)data, menu->menu_list->selection_buf); } static int deferred_push_database_manager_list(void *data, void *userdata, @@ -3529,38 +3894,42 @@ static int deferred_push_default(void *data, void *userdata, static int action_bind_up_or_down_generic(unsigned type, const char *label, unsigned action) { - unsigned scroll_speed = (max(driver.menu->scroll_accel, 2) - 2) / 4 + 1; + unsigned scroll_speed = 0; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; - if (menu_list_get_size(driver.menu->menu_list) <= 0) + scroll_speed = (max(menu->navigation.scroll.acceleration, 2) - 2) / 4 + 1; + + if (menu_list_get_size(menu->menu_list) <= 0) return 0; switch (action) { case MENU_ACTION_UP: - if (driver.menu->selection_ptr >= scroll_speed) - menu_navigation_set(driver.menu, - driver.menu->selection_ptr - scroll_speed, true); + if (menu->navigation.selection_ptr >= scroll_speed) + menu_navigation_set(&menu->navigation, + menu->navigation.selection_ptr - scroll_speed, true); else { if (g_settings.menu.navigation.wraparound.vertical_enable) - menu_navigation_set(driver.menu, - menu_list_get_size(driver.menu->menu_list) - 1, true); + menu_navigation_set(&menu->navigation, + menu_list_get_size(menu->menu_list) - 1, true); else - menu_navigation_set(driver.menu, - 0, true); + menu_navigation_set(&menu->navigation, 0, true); } break; case MENU_ACTION_DOWN: - if (driver.menu->selection_ptr + scroll_speed < (menu_list_get_size(driver.menu->menu_list))) - menu_navigation_set(driver.menu, - driver.menu->selection_ptr + scroll_speed, true); + if (menu->navigation.selection_ptr + scroll_speed < (menu_list_get_size(menu->menu_list))) + menu_navigation_set(&menu->navigation, + menu->navigation.selection_ptr + scroll_speed, true); else { if (g_settings.menu.navigation.wraparound.vertical_enable) - menu_navigation_clear(driver.menu, false); + menu_navigation_clear(&menu->navigation, false); else - menu_navigation_set(driver.menu, - menu_list_get_size(driver.menu->menu_list) - 1, true); + menu_navigation_set(&menu->navigation, + menu_list_get_size(menu->menu_list) - 1, true); } break; } @@ -3570,43 +3939,55 @@ static int action_bind_up_or_down_generic(unsigned type, const char *label, static int action_refresh_default(file_list_t *list, file_list_t *menu_list) { - int ret = menu_entries_deferred_push(list, menu_list); - driver.menu->need_refresh = false; + int ret = 0; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + ret = menu_entries_deferred_push(list, menu_list); + + menu->need_refresh = false; + return ret; } static int mouse_post_iterate(menu_file_list_cbs_t *cbs, const char *path, const char *label, unsigned type, unsigned action) { - if (!driver.menu->mouse.enable) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + + if (!menu->mouse.enable) return 0; - if (driver.menu->mouse.ptr <= menu_list_get_size(driver.menu->menu_list)-1) - menu_navigation_set(driver.menu, driver.menu->mouse.ptr, false); + if (menu->mouse.ptr <= menu_list_get_size(menu->menu_list)-1) + menu_navigation_set(&menu->navigation, menu->mouse.ptr, false); - if (driver.menu->mouse.left) + if (menu->mouse.left) { - if (!driver.menu->mouse.oldleft) + if (!menu->mouse.oldleft) { - driver.menu->mouse.oldleft = true; + menu->mouse.oldleft = true; if (cbs && cbs->action_ok) - return cbs->action_ok(path, label, type, driver.menu->selection_ptr); + return cbs->action_ok(path, label, type, + menu->navigation.selection_ptr); } } else - driver.menu->mouse.oldleft = false; + menu->mouse.oldleft = false; - if (driver.menu->mouse.right) + if (menu->mouse.right) { - if (!driver.menu->mouse.oldright) + if (!menu->mouse.oldright) { - driver.menu->mouse.oldright = true; - menu_list_pop_stack(driver.menu->menu_list); + menu->mouse.oldright = true; + menu_list_pop_stack(menu->menu_list); } } else - driver.menu->mouse.oldright = false; + menu->mouse.oldright = false; return 0; } @@ -3622,11 +4003,12 @@ static int action_iterate_help(const char *label, unsigned action) RETRO_DEVICE_ID_JOYPAD_SELECT, RARCH_MENU_TOGGLE, RARCH_QUIT_KEY, + RETRO_DEVICE_ID_JOYPAD_X, }; char desc[ARRAY_SIZE(binds)][64]; char msg[PATH_MAX_LENGTH]; - - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return 0; if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render) @@ -3654,23 +4036,24 @@ static int action_iterate_help(const char *label, unsigned action) " Info: %-20s\n" "Enter/Exit Menu: %-20s\n" " Exit RetroArch: %-20s\n" + "Toggle Keyboard: %-20s\n" " \n" "To run content:\n" "Load a libretro core (Core).\n" "Load a content file (Load Content). \n" " \n" - "See Path Options to set directories for faster access to files.\n" + "See Path Settings to set directories for faster access to files.\n" " \n" "Press Accept/OK to continue.", - desc[0], desc[1], desc[2], desc[3], desc[4], desc[5], desc[6]); + desc[0], desc[1], desc[2], desc[3], desc[4], desc[5], desc[6], desc[7]); if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render_messagebox) driver.menu_ctx->render_messagebox(msg); if (action == MENU_ACTION_OK) - menu_list_pop(driver.menu->menu_list->menu_stack, NULL); + menu_list_pop(menu->menu_list->menu_stack, NULL); return 0; } @@ -3681,23 +4064,25 @@ static int action_iterate_info(const char *label, unsigned action) char needle[PATH_MAX_LENGTH]; unsigned info_type = 0; rarch_setting_t *current_setting = NULL; - file_list_t *list = (file_list_t*)driver.menu->menu_list->selection_buf; - - if (!driver.menu) + file_list_t *list = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return 0; + list = (file_list_t*)menu->menu_list->selection_buf; + if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render) driver.menu_ctx->render(); current_setting = (rarch_setting_t*)setting_data_find_setting( - driver.menu->list_settings, - list->list[driver.menu->selection_ptr].label); + menu->list_settings, + list->list[menu->navigation.selection_ptr].label); if (current_setting) strlcpy(needle, current_setting->name, sizeof(needle)); else if ((current_setting = (rarch_setting_t*)setting_data_find_setting( - driver.menu->list_settings, - list->list[driver.menu->selection_ptr].label))) + menu->list_settings, + list->list[menu->navigation.selection_ptr].label))) { if (current_setting) strlcpy(needle, current_setting->name, sizeof(needle)); @@ -3705,8 +4090,8 @@ static int action_iterate_info(const char *label, unsigned action) else { const char *lbl = NULL; - menu_list_get_at_offset(driver.menu->menu_list->selection_buf, - driver.menu->selection_ptr, NULL, &lbl, + menu_list_get_at_offset(list, + menu->navigation.selection_ptr, NULL, &lbl, &info_type); if (lbl) @@ -3723,7 +4108,7 @@ static int action_iterate_info(const char *label, unsigned action) } if (action == MENU_ACTION_OK) - menu_list_pop(driver.menu->menu_list->menu_stack, &driver.menu->selection_ptr); + menu_list_pop(menu->menu_list->menu_stack, &menu->navigation.selection_ptr); return 0; } @@ -3754,8 +4139,11 @@ static int action_iterate_menu_viewport(const char *label, unsigned action) unsigned type = 0; rarch_viewport_t *custom = (rarch_viewport_t*) &g_extern.console.screen.viewports.custom_vp; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; - menu_list_get_last_stack(driver.menu->menu_list, NULL, NULL, &type); + menu_list_get_last_stack(menu->menu_list, NULL, NULL, &type); geom = (struct retro_game_geometry*)&g_extern.system.av_info.geometry; @@ -3818,24 +4206,24 @@ static int action_iterate_menu_viewport(const char *label, unsigned action) break; case MENU_ACTION_CANCEL: - menu_list_pop_stack(driver.menu->menu_list); + menu_list_pop_stack(menu->menu_list); if (!strcmp(label, "custom_viewport_2")) { - menu_list_push_stack(driver.menu->menu_list, "", "", + menu_list_push_stack(menu->menu_list, "", "", MENU_SETTINGS_CUSTOM_VIEWPORT, - driver.menu->selection_ptr); + menu->navigation.selection_ptr); } break; case MENU_ACTION_OK: - menu_list_pop_stack(driver.menu->menu_list); + menu_list_pop_stack(menu->menu_list); if (type == MENU_SETTINGS_CUSTOM_VIEWPORT && !g_settings.video.scale_integer) { - menu_list_push_stack(driver.menu->menu_list, "", - "custom_viewport_2", 0, driver.menu->selection_ptr); + menu_list_push_stack(menu->menu_list, "", + "custom_viewport_2", 0, menu->navigation.selection_ptr); } break; @@ -3866,14 +4254,14 @@ static int action_iterate_menu_viewport(const char *label, unsigned action) break; case MENU_ACTION_MESSAGE: - driver.menu->msg_force = true; + menu->msg_force = true; break; default: break; } - menu_list_get_last_stack(driver.menu->menu_list, NULL, &label, &type); + menu_list_get_last_stack(menu->menu_list, NULL, &label, &type); if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render) driver.menu_ctx->render(); @@ -3924,26 +4312,36 @@ static int action_iterate_menu_viewport(const char *label, unsigned action) static int action_iterate_custom_bind(const char *label, unsigned action) { - if (menu_input_bind_iterate(driver.menu)) - menu_list_pop_stack(driver.menu->menu_list); + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + if (menu_input_bind_iterate()) + menu_list_pop_stack(menu->menu_list); return 0; } static int action_iterate_custom_bind_keyboard(const char *label, unsigned action) { - if (menu_input_bind_iterate_keyboard(driver.menu)) - menu_list_pop_stack(driver.menu->menu_list); + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + if (menu_input_bind_iterate_keyboard()) + menu_list_pop_stack(menu->menu_list); return 0; } static int action_iterate_message(const char *label, unsigned action) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; + if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render_messagebox) - driver.menu_ctx->render_messagebox(driver.menu->message_contents); + driver.menu_ctx->render_messagebox(menu->message_contents); if (action == MENU_ACTION_OK) - menu_list_pop_stack(driver.menu->menu_list); + menu_list_pop_stack(menu->menu_list); return 0; } @@ -3951,40 +4349,43 @@ static int action_iterate_message(const char *label, unsigned action) static int mouse_iterate(unsigned action) { const struct retro_keybind *binds[MAX_USERS]; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; - if (!driver.menu->mouse.enable) + if (!menu->mouse.enable) return 0; - driver.menu->mouse.dx = driver.input->input_state(driver.input_data, + menu->mouse.dx = driver.input->input_state(driver.input_data, binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X); - driver.menu->mouse.dy = driver.input->input_state(driver.input_data, + menu->mouse.dy = driver.input->input_state(driver.input_data, binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y); - driver.menu->mouse.x += driver.menu->mouse.dx; - driver.menu->mouse.y += driver.menu->mouse.dy; + menu->mouse.x += menu->mouse.dx; + menu->mouse.y += menu->mouse.dy; - if (driver.menu->mouse.x < 5) - driver.menu->mouse.x = 5; - if (driver.menu->mouse.y < 5) - driver.menu->mouse.y = 5; - if (driver.menu->mouse.x > driver.menu->width - 5) - driver.menu->mouse.x = driver.menu->width - 5; - if (driver.menu->mouse.y > driver.menu->height - 5) - driver.menu->mouse.y = driver.menu->height - 5; + if (menu->mouse.x < 5) + menu->mouse.x = 5; + if (menu->mouse.y < 5) + menu->mouse.y = 5; + if (menu->mouse.x > menu->frame_buf.width - 5) + menu->mouse.x = menu->frame_buf.width - 5; + if (menu->mouse.y > menu->frame_buf.height - 5) + menu->mouse.y = menu->frame_buf.height - 5; - driver.menu->mouse.left = driver.input->input_state(driver.input_data, + menu->mouse.left = driver.input->input_state(driver.input_data, binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT); - driver.menu->mouse.right = driver.input->input_state(driver.input_data, + menu->mouse.right = driver.input->input_state(driver.input_data, binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT); - driver.menu->mouse.wheelup = driver.input->input_state(driver.input_data, + menu->mouse.wheelup = driver.input->input_state(driver.input_data, binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELUP) - || driver.menu->mouse.y == 5; + || menu->mouse.y == 5; - driver.menu->mouse.wheeldown = driver.input->input_state(driver.input_data, + menu->mouse.wheeldown = driver.input->input_state(driver.input_data, binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELDOWN) - || driver.menu->mouse.y == driver.menu->height - 5; + || menu->mouse.y == menu->frame_buf.height - 5; return 0; } @@ -3995,13 +4396,17 @@ static int action_iterate_main(const char *label, unsigned action) unsigned type_offset = 0; const char *label_offset = NULL; const char *path_offset = NULL; + menu_file_list_cbs_t *cbs = NULL; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return 0; - menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*) - menu_list_get_actiondata_at_offset(driver.menu->menu_list->selection_buf, - driver.menu->selection_ptr); + cbs = (menu_file_list_cbs_t*) + menu_list_get_actiondata_at_offset(menu->menu_list->selection_buf, + menu->navigation.selection_ptr); - menu_list_get_at_offset(driver.menu->menu_list->selection_buf, - driver.menu->selection_ptr, &path_offset, &label_offset, &type_offset); + menu_list_get_at_offset(menu->menu_list->selection_buf, + menu->navigation.selection_ptr, &path_offset, &label_offset, &type_offset); mouse_iterate(action); @@ -4030,7 +4435,7 @@ static int action_iterate_main(const char *label, unsigned action) return action_iterate_custom_bind(label, action); } - if (driver.menu->need_refresh && action != MENU_ACTION_MESSAGE) + if (menu->need_refresh && action != MENU_ACTION_MESSAGE) action = MENU_ACTION_REFRESH; switch (action) @@ -4041,20 +4446,20 @@ static int action_iterate_main(const char *label, unsigned action) ret = cbs->action_up_or_down(type_offset, label_offset, action); break; case MENU_ACTION_SCROLL_UP: - menu_navigation_descend_alphabet(driver.menu, &driver.menu->selection_ptr); + menu_navigation_descend_alphabet(&menu->navigation, &menu->navigation.selection_ptr); break; case MENU_ACTION_SCROLL_DOWN: - menu_navigation_ascend_alphabet(driver.menu, &driver.menu->selection_ptr); + menu_navigation_ascend_alphabet(&menu->navigation, &menu->navigation.selection_ptr); break; case MENU_ACTION_CANCEL: if (cbs && cbs->action_cancel) - return cbs->action_cancel(path_offset, label_offset, type_offset, driver.menu->selection_ptr); + return cbs->action_cancel(path_offset, label_offset, type_offset, menu->navigation.selection_ptr); break; case MENU_ACTION_OK: if (cbs && cbs->action_ok) - return cbs->action_ok(path_offset, label_offset, type_offset, driver.menu->selection_ptr); + return cbs->action_ok(path_offset, label_offset, type_offset, menu->navigation.selection_ptr); break; case MENU_ACTION_START: if (cbs && cbs->action_start) @@ -4072,12 +4477,12 @@ static int action_iterate_main(const char *label, unsigned action) case MENU_ACTION_REFRESH: if (cbs && cbs->action_refresh) - ret = cbs->action_refresh(driver.menu->menu_list->selection_buf, - driver.menu->menu_list->menu_stack); + ret = cbs->action_refresh(menu->menu_list->selection_buf, + menu->menu_list->menu_stack); break; case MENU_ACTION_MESSAGE: - driver.menu->msg_force = true; + menu->msg_force = true; break; case MENU_ACTION_SEARCH: @@ -4100,10 +4505,10 @@ static int action_iterate_main(const char *label, unsigned action) driver.menu_ctx->render(); /* Have to defer it so we let settings refresh. */ - if (driver.menu->push_start_screen) + if (menu->push_start_screen) { - menu_list_push_stack(driver.menu->menu_list, "", "help", 0, 0); - driver.menu->push_start_screen = false; + menu_list_push_stack(menu->menu_list, "", "help", 0, 0); + menu->push_start_screen = false; } return ret; @@ -4112,8 +4517,11 @@ static int action_iterate_main(const char *label, unsigned action) static int action_select_default(unsigned type, const char *label, unsigned action) { - menu_list_push_stack(driver.menu->menu_list, "", "info_screen", - 0, driver.menu->selection_ptr); + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return 0; + menu_list_push_stack(menu->menu_list, "", "info_screen", + 0, menu->navigation.selection_ptr); return 0; } @@ -4179,24 +4587,31 @@ static void menu_action_setting_disp_set_label_shader_filter_pass( const char *path, char *path_buf, size_t path_buf_size) { - unsigned pass; + unsigned pass = 0; static const char *modes[] = { "Don't care", "Linear", "Nearest" }; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; + + (void)pass; + (void)modes; + (void)menu; *type_str = '\0'; *w = 19; strlcpy(path_buf, path, path_buf_size); #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_HLSL) - if (!driver.menu->shader) + if (!menu->shader) return; pass = (type - MENU_SETTINGS_SHADER_PASS_FILTER_0); - strlcpy(type_str, modes[driver.menu->shader->pass[pass].filter], + strlcpy(type_str, modes[menu->shader->pass[pass].filter], type_str_size); #endif } @@ -4210,11 +4625,17 @@ static void menu_action_setting_disp_set_label_shader_num_passes( const char *path, char *path_buf, size_t path_buf_size) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; + + (void)menu; + *type_str = '\0'; *w = 19; strlcpy(path_buf, path, path_buf_size); #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_HLSL) - snprintf(type_str, type_str_size, "%u", driver.menu->shader->passes); + snprintf(type_str, type_str_size, "%u", menu->shader->passes); #endif } @@ -4228,6 +4649,12 @@ static void menu_action_setting_disp_set_label_shader_pass( char *path_buf, size_t path_buf_size) { unsigned pass = (type - MENU_SETTINGS_SHADER_PASS_0); + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; + + (void)pass; + (void)menu; *type_str = '\0'; *w = 19; @@ -4235,9 +4662,9 @@ static void menu_action_setting_disp_set_label_shader_pass( strlcpy(type_str, "N/A", type_str_size); #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_HLSL) - if (*driver.menu->shader->pass[pass].source.path) + if (*menu->shader->pass[pass].source.path) fill_pathname_base(type_str, - driver.menu->shader->pass[pass].source.path, type_str_size); + menu->shader->pass[pass].source.path, type_str_size); #endif } @@ -4311,16 +4738,21 @@ static void menu_action_setting_disp_set_label_shader_preset_parameter( #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_HLSL) const struct video_shader_parameter *param = NULL; #endif + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; + + (void)menu; *type_str = '\0'; *w = 19; strlcpy(path_buf, path, path_buf_size); #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_HLSL) - if (!driver.menu->shader) + if (!menu->shader) return; - param = &driver.menu->shader->parameters[type - MENU_SETTINGS_SHADER_PRESET_PARAMETER_0]; + param = &menu->shader->parameters[type - MENU_SETTINGS_SHADER_PRESET_PARAMETER_0]; if (!param) return; @@ -4339,18 +4771,26 @@ static void menu_action_setting_disp_set_label_shader_scale_pass( const char *path, char *path_buf, size_t path_buf_size) { - unsigned pass, scale_value; + unsigned pass = 0; + unsigned scale_value = 0; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; *type_str = '\0'; *w = 19; strlcpy(path_buf, path, path_buf_size); + (void)pass; + (void)scale_value; + (void)menu; + #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_HLSL) - if (!driver.menu->shader) + if (!menu->shader) return; pass = (type - MENU_SETTINGS_SHADER_PASS_SCALE_0); - scale_value = driver.menu->shader->pass[pass].fbo.scale_x; + scale_value = menu->shader->pass[pass].fbo.scale_x; if (!scale_value) strlcpy(type_str, "Don't care", type_str_size); @@ -4500,19 +4940,6 @@ static void menu_action_setting_disp_set_label_menu_more( strlcpy(path_buf, path, path_buf_size); } -static void menu_action_setting_disp_set_label_menu_file_plain( - file_list_t* list, - unsigned *w, unsigned type, unsigned i, - const char *label, - char *type_str, size_t type_str_size, - const char *entry_label, - const char *path, - char *path_buf, size_t path_buf_size) -{ - strlcpy(type_str, "(FILE)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); -} static void menu_action_setting_disp_set_label_menu_disk_index( file_list_t* list, @@ -4575,6 +5002,33 @@ static void menu_action_setting_disp_set_label_menu_video_resolution( #endif } +static void menu_action_setting_generic_disp_set_label( + unsigned *w, char *type_str, size_t type_str_size, + const char *path, const char *label, + char *path_buf, size_t path_buf_size) +{ + *type_str = '\0'; + + if (label) + strlcpy(type_str, label, type_str_size); + *w = strlen(type_str); + + strlcpy(path_buf, path, path_buf_size); +} + +static void menu_action_setting_disp_set_label_menu_file_plain( + file_list_t* list, + unsigned *w, unsigned type, unsigned i, + const char *label, + char *type_str, size_t type_str_size, + const char *entry_label, + const char *path, + char *path_buf, size_t path_buf_size) +{ + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(FILE)", path_buf, path_buf_size); +} + static void menu_action_setting_disp_set_label_menu_file_use_directory( file_list_t* list, unsigned *w, unsigned type, unsigned i, @@ -4584,9 +5038,8 @@ static void menu_action_setting_disp_set_label_menu_file_use_directory( const char *path, char *path_buf, size_t path_buf_size) { - *type_str = '\0'; - *w = 0; - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, NULL, path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_directory( @@ -4598,9 +5051,8 @@ static void menu_action_setting_disp_set_label_menu_file_directory( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(DIR)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(DIR)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_carchive( @@ -4612,9 +5064,8 @@ static void menu_action_setting_disp_set_label_menu_file_carchive( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(COMP)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(COMP)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_shader( @@ -4626,9 +5077,8 @@ static void menu_action_setting_disp_set_label_menu_file_shader( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(SHADER)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(SHADER)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_subgroup( @@ -4640,9 +5090,8 @@ static void menu_action_setting_disp_set_label_menu_file_subgroup( const char *path, char *path_buf, size_t path_buf_size) { - *type_str = '\0'; - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, NULL, path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_shader_preset( @@ -4654,9 +5103,8 @@ static void menu_action_setting_disp_set_label_menu_file_shader_preset( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(PRESET)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(PRESET)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_in_carchive( @@ -4668,9 +5116,8 @@ static void menu_action_setting_disp_set_label_menu_file_in_carchive( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(CFILE)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(CFILE)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_overlay( @@ -4682,9 +5129,8 @@ static void menu_action_setting_disp_set_label_menu_file_overlay( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(OVERLAY)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(OVERLAY)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_config( @@ -4696,9 +5142,8 @@ static void menu_action_setting_disp_set_label_menu_file_config( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(CONFIG)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(CONFIG)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_font( @@ -4710,9 +5155,8 @@ static void menu_action_setting_disp_set_label_menu_file_font( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(FONT)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(FONT)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_filter( @@ -4724,9 +5168,8 @@ static void menu_action_setting_disp_set_label_menu_file_filter( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(FILTER)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(FILTER)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_url( @@ -4738,9 +5181,8 @@ static void menu_action_setting_disp_set_label_menu_file_url( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(URL)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(URL)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_rdb( @@ -4752,9 +5194,8 @@ static void menu_action_setting_disp_set_label_menu_file_rdb( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(RDB)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(RDB)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_cursor( @@ -4766,9 +5207,8 @@ static void menu_action_setting_disp_set_label_menu_file_cursor( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(CURSOR)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(CURSOR)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label_menu_file_cheat( @@ -4780,9 +5220,8 @@ static void menu_action_setting_disp_set_label_menu_file_cheat( const char *path, char *path_buf, size_t path_buf_size) { - strlcpy(type_str, "(CHEAT)", type_str_size); - *w = strlen(type_str); - strlcpy(path_buf, path, path_buf_size); + menu_action_setting_generic_disp_set_label(w, type_str, type_str_size, + path, "(CHEAT)", path_buf, path_buf_size); } static void menu_action_setting_disp_set_label(file_list_t* list, @@ -4912,25 +5351,25 @@ static int is_rdb_entry(const char *label) static int is_settings_entry(const char *label) { return ( - !strcmp(label, "Driver Options") || - !strcmp(label, "General Options") || - !strcmp(label, "Video Options") || - !strcmp(label, "Shader Options") || - !strcmp(label, "Font Options") || - !strcmp(label, "Audio Options") || - !strcmp(label, "Input Options") || - !strcmp(label, "Overlay Options") || - !strcmp(label, "Menu Options") || - !strcmp(label, "UI Options") || - !strcmp(label, "Patch Options") || - !strcmp(label, "Playlist Options") || - !strcmp(label, "Onscreen Keyboard Overlay Options") || - !strcmp(label, "Core Updater Options") || - !strcmp(label, "Network Options") || - !strcmp(label, "Archive Options") || - !strcmp(label, "User Options") || - !strcmp(label, "Path Options") || - !strcmp(label, "Privacy Options")); + !strcmp(label, "Driver Settings") || + !strcmp(label, "General Settings") || + !strcmp(label, "Video Settings") || + !strcmp(label, "Shader Settings") || + !strcmp(label, "Font Settings") || + !strcmp(label, "Audio Settings") || + !strcmp(label, "Input Settings") || + !strcmp(label, "Overlay Settings") || + !strcmp(label, "Menu Settings") || + !strcmp(label, "UI Settings") || + !strcmp(label, "Patch Settings") || + !strcmp(label, "Playlist Settings") || + !strcmp(label, "Onscreen Keyboard Overlay Settings") || + !strcmp(label, "Core Updater Settings") || + !strcmp(label, "Network Settings") || + !strcmp(label, "Archive Settings") || + !strcmp(label, "User Settings") || + !strcmp(label, "Path Settings") || + !strcmp(label, "Privacy Settings")); } static void menu_entries_cbs_init_bind_ok(menu_file_list_cbs_t *cbs, @@ -4938,10 +5377,13 @@ static void menu_entries_cbs_init_bind_ok(menu_file_list_cbs_t *cbs, const char *elem0, const char *elem1, const char *menu_label) { rarch_setting_t *setting = menu_action_find_setting(label); + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; if (!cbs) return; - if (!driver.menu) + if (!menu) return; cbs->action_ok = action_ok_lookup_setting; @@ -4990,6 +5432,10 @@ static void menu_entries_cbs_init_bind_ok(menu_file_list_cbs_t *cbs, cbs->action_ok = action_ok_shader_preset; else if (!strcmp(label, "cheat_file_load")) cbs->action_ok = action_ok_cheat_file; + else if (!strcmp(label, "audio_dsp_plugin")) + cbs->action_ok = action_ok_audio_dsp_plugin; + else if (!strcmp(label, "video_filter")) + cbs->action_ok = action_ok_video_filter; else if (!strcmp(label, "remap_file_load")) cbs->action_ok = action_ok_remap_file; else if (!strcmp(label, "video_shader_parameters") || @@ -4997,8 +5443,8 @@ static void menu_entries_cbs_init_bind_ok(menu_file_list_cbs_t *cbs, ) cbs->action_ok = action_ok_shader_parameters; else if ( - !strcmp(label, "Shader Options") || - !strcmp(label, "Input Options") || + !strcmp(label, "shader_options") || + !strcmp(label, "Input Settings") || !strcmp(label, "core_options") || !strcmp(label, "core_cheat_options") || !strcmp(label, "core_input_remapping_options") || @@ -5007,7 +5453,9 @@ static void menu_entries_cbs_init_bind_ok(menu_file_list_cbs_t *cbs, !strcmp(label, "settings") || !strcmp(label, "performance_counters") || !strcmp(label, "frontend_counters") || - !strcmp(label, "core_counters") + !strcmp(label, "core_counters") || + !strcmp(label, "management") || + !strcmp(label, "options") ) cbs->action_ok = action_ok_push_default; else if ( @@ -5191,6 +5639,7 @@ static void menu_entries_cbs_init_bind_toggle(menu_file_list_cbs_t *cbs, case MENU_FILE_RDB_ENTRY: case MENU_FILE_CURSOR: case MENU_FILE_SHADER: + case MENU_FILE_SHADER_PRESET: case MENU_FILE_IMAGE: case MENU_FILE_OVERLAY: case MENU_FILE_VIDEOFILTER: @@ -5261,27 +5710,23 @@ static void menu_entries_cbs_init_bind_refresh(menu_file_list_cbs_t *cbs, const char *path, const char *label, unsigned type, size_t idx, const char *elem0, const char *elem1) { - if (!cbs || !driver.menu) - return; - - cbs->action_refresh = action_refresh_default; + if (cbs) + cbs->action_refresh = action_refresh_default; } static void menu_entries_cbs_init_bind_iterate(menu_file_list_cbs_t *cbs, const char *path, const char *label, unsigned type, size_t idx, const char *elem0, const char *elem1) { - if (!cbs || !driver.menu) - return; - - cbs->action_iterate = action_iterate_main; + if (cbs) + cbs->action_iterate = action_iterate_main; } static void menu_entries_cbs_init_bind_get_string_representation(menu_file_list_cbs_t *cbs, const char *path, const char *label, unsigned type, size_t idx, const char *elem0, const char *elem1) { - if (!cbs || !driver.menu) + if (!cbs) return; if (type >= MENU_SETTINGS_INPUT_DESC_BEGIN @@ -5430,7 +5875,7 @@ static void menu_entries_cbs_init_bind_deferred_push(menu_file_list_cbs_t *cbs, const char *path, const char *label, unsigned type, size_t idx, const char *elem0, const char *elem1) { - if (!cbs || !driver.menu) + if (!cbs) return; cbs->action_deferred_push = deferred_push_default; @@ -5463,8 +5908,12 @@ static void menu_entries_cbs_init_bind_deferred_push(menu_file_list_cbs_t *cbs, cbs->action_deferred_push = deferred_push_remap_file_load; else if (!strcmp(label, "content_actions")) cbs->action_deferred_push = deferred_push_content_actions; - else if (!strcmp(label, "Shader Options")) + else if (!strcmp(label, "shader_options")) cbs->action_deferred_push = deferred_push_shader_options; + else if (!strcmp(label, "options")) + cbs->action_deferred_push = deferred_push_options; + else if (!strcmp(label, "management")) + cbs->action_deferred_push = deferred_push_management_options; else if (type == MENU_SETTING_GROUP) cbs->action_deferred_push = deferred_push_category; else if (!strcmp(label, "deferred_core_list")) @@ -5548,6 +5997,9 @@ void menu_entries_cbs_init(void *data, const char *menu_label = NULL; menu_file_list_cbs_t *cbs = NULL; file_list_t *list = (file_list_t*)data; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; if (!list) return; @@ -5555,7 +6007,7 @@ void menu_entries_cbs_init(void *data, if (!(cbs = (menu_file_list_cbs_t*)list->list[idx].actiondata)) return; - menu_list_get_last_stack(driver.menu->menu_list, + menu_list_get_last_stack(menu->menu_list, NULL, &menu_label, NULL); if (label) @@ -5563,8 +6015,10 @@ void menu_entries_cbs_init(void *data, if (str_list && str_list->size > 0) strlcpy(elem0, str_list->elems[0].data, sizeof(elem0)); + else elem0[0]='\0'; if (str_list && str_list->size > 1) strlcpy(elem1, str_list->elems[1].data, sizeof(elem1)); + else elem1[0]='\0'; if (str_list) { diff --git a/menu/menu_input.c b/menu/menu_input.c index 4cc18e9dc3..454c382e0b 100644 --- a/menu/menu_input.c +++ b/menu/menu_input.c @@ -26,18 +26,18 @@ #include "menu.h" #include "menu_action.h" #include "menu_shader.h" +#include "menu_navigation.h" #include "../cheats.h" #include "../performance.h" #include "../settings_data.h" #include "../input/input_joypad.h" #include "../input/input_remapping.h" -void menu_input_key_start_line(void *data, const char *label, +void menu_input_key_start_line(const char *label, const char *label_setting, unsigned type, unsigned idx, input_keyboard_line_complete_t cb) { - menu_handle_t *menu = (menu_handle_t*)data; - + menu_handle_t *menu = menu_driver_resolve(); if (!menu) return; @@ -49,10 +49,9 @@ void menu_input_key_start_line(void *data, const char *label, menu->keyboard.buffer = input_keyboard_start_line(menu, cb); } -static void menu_input_key_end_line(void *data) +static void menu_input_key_end_line(void) { - menu_handle_t *menu = (menu_handle_t*)data; - + menu_handle_t *menu = menu_driver_resolve(); if (!menu) return; @@ -67,37 +66,48 @@ static void menu_input_key_end_line(void *data) static void menu_input_search_callback(void *userdata, const char *str) { size_t idx; - menu_handle_t *menu = (menu_handle_t*)userdata; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; if (str && *str && file_list_search(menu->menu_list->selection_buf, str, &idx)) - menu_navigation_set(menu, idx, true); + menu_navigation_set(&menu->navigation, idx, true); - menu_input_key_end_line(menu); + menu_input_key_end_line(); } void menu_input_st_uint_callback(void *userdata, const char *str) { - menu_handle_t *menu = (menu_handle_t*)userdata; - rarch_setting_t *current_setting = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; if (str && *str) { + rarch_setting_t *current_setting = NULL; if ((current_setting = (rarch_setting_t*) setting_data_find_setting( menu->list_settings, menu->keyboard.label_setting))) *current_setting->value.unsigned_integer = strtoul(str, NULL, 0); } - menu_input_key_end_line(menu); + + menu_input_key_end_line(); } void menu_input_st_string_callback(void *userdata, const char *str) { - menu_handle_t *menu = (menu_handle_t*)userdata; - rarch_setting_t *current_setting = NULL; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return; if (str && *str) { + rarch_setting_t *current_setting = NULL; + if ((current_setting = (rarch_setting_t*) setting_data_find_setting( menu->list_settings, menu->keyboard.label_setting))) @@ -113,13 +123,16 @@ void menu_input_st_string_callback(void *userdata, const char *str) } } - menu_input_key_end_line(menu); + menu_input_key_end_line(); } void menu_input_st_cheat_callback(void *userdata, const char *str) { - menu_handle_t *menu = (menu_handle_t*)userdata; cheat_manager_t *cheat = g_extern.cheat; + menu_handle_t *menu = (menu_handle_t*)userdata; + + if (!menu) + return; if (cheat && str && *str) { @@ -130,26 +143,24 @@ void menu_input_st_cheat_callback(void *userdata, const char *str) cheat->cheats[cheat_index].state = true; } - menu_input_key_end_line(menu); + menu_input_key_end_line(); } void menu_input_search_start(void) { - if (!driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) return; - driver.menu->keyboard.display = true; - driver.menu->keyboard.label = "Search: "; - driver.menu->keyboard.buffer = + menu->keyboard.display = true; + menu->keyboard.label = "Search: "; + menu->keyboard.buffer = input_keyboard_start_line(driver.menu, menu_input_search_callback); } void menu_input_key_event(bool down, unsigned keycode, uint32_t character, uint16_t mod) { - if (!driver.menu) - return; - (void)down; (void)keycode; (void)mod; @@ -333,14 +344,19 @@ bool menu_input_custom_bind_keyboard_cb(void *data, unsigned code) menu->binds.timeout_end = rarch_get_time_usec() + MENU_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000; - return menu->binds.begin <= menu->binds.last; + return (menu->binds.begin <= menu->binds.last); } -int menu_input_bind_iterate(void *data) +int menu_input_bind_iterate(void) { char msg[PATH_MAX_LENGTH]; - menu_handle_t *menu = (menu_handle_t*)data; - struct menu_bind_state binds = menu->binds; + struct menu_bind_state binds; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return 1; + + binds = menu->binds; if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render) @@ -348,11 +364,11 @@ int menu_input_bind_iterate(void *data) snprintf(msg, sizeof(msg), "[%s]\npress joypad\n(RETURN to skip)", input_config_bind_map[ - driver.menu->binds.begin - MENU_SETTINGS_BIND_BEGIN].desc); + menu->binds.begin - MENU_SETTINGS_BIND_BEGIN].desc); if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render_messagebox) - driver.menu_ctx->render_messagebox(msg); + driver.menu_ctx->render_messagebox( msg); driver.block_input = true; menu_input_poll_bind_state(&binds); @@ -377,23 +393,26 @@ int menu_input_bind_iterate(void *data) return 0; } -int menu_input_bind_iterate_keyboard(void *data) +int menu_input_bind_iterate_keyboard(void) { char msg[PATH_MAX_LENGTH]; int64_t current; int timeout = 0; bool timed_out = false; - menu_handle_t *menu = (menu_handle_t*)data; + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return -1; if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render) driver.menu_ctx->render(); current = rarch_get_time_usec(); - timeout = (driver.menu->binds.timeout_end - current) / 1000000; + timeout = (menu->binds.timeout_end - current) / 1000000; snprintf(msg, sizeof(msg), "[%s]\npress keyboard\n(timeout %d seconds)", input_config_bind_map[ - driver.menu->binds.begin - MENU_SETTINGS_BIND_BEGIN].desc, + menu->binds.begin - MENU_SETTINGS_BIND_BEGIN].desc, timeout); if (driver.video_data && driver.menu_ctx @@ -440,6 +459,10 @@ unsigned menu_input_frame(retro_input_t input, retro_input_t trigger_input) | (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) | (1ULL << RETRO_DEVICE_ID_JOYPAD_L) | (1ULL << RETRO_DEVICE_ID_JOYPAD_R); + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu) + return 0; driver.retro_ctx.poll_cb(); @@ -451,15 +474,16 @@ unsigned menu_input_frame(retro_input_t input, retro_input_t trigger_input) if (!first_held) { first_held = true; - driver.menu->delay_timer = initial_held ? 12 : 6; - driver.menu->delay_count = 0; + menu->delay.timer = initial_held ? 12 : 6; + menu->delay.count = 0; } - if (driver.menu->delay_count >= driver.menu->delay_timer) + if (menu->delay.count >= menu->delay.timer) { first_held = false; trigger_input |= input & input_repeat; - driver.menu->scroll_accel = min(driver.menu->scroll_accel + 1, 64); + menu->navigation.scroll.acceleration = + min(menu->navigation.scroll.acceleration + 1, 64); } initial_held = false; @@ -468,12 +492,12 @@ unsigned menu_input_frame(retro_input_t input, retro_input_t trigger_input) { first_held = false; initial_held = true; - driver.menu->scroll_accel = 0; + menu->navigation.scroll.acceleration = 0; } - driver.menu->mouse.enable = g_settings.menu.mouse_enable; + menu->mouse.enable = g_settings.menu.mouse_enable; - driver.menu->delay_count++; + menu->delay.count++; if (driver.block_input) trigger_input = 0; diff --git a/menu/menu_input.h b/menu/menu_input.h index 081f53d5dc..126c2d9c91 100644 --- a/menu/menu_input.h +++ b/menu/menu_input.h @@ -47,7 +47,7 @@ typedef enum void menu_input_key_event(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers); -void menu_input_key_start_line(void *data, const char *label, +void menu_input_key_start_line(const char *label, const char *label_setting, unsigned type, unsigned idx, input_keyboard_line_complete_t cb); @@ -66,9 +66,9 @@ bool menu_input_poll_find_trigger(struct menu_bind_state *state, bool menu_input_custom_bind_keyboard_cb(void *data, unsigned code); -int menu_input_bind_iterate(void *data); +int menu_input_bind_iterate(void); -int menu_input_bind_iterate_keyboard(void *data); +int menu_input_bind_iterate_keyboard(void); unsigned menu_input_frame(retro_input_t input, retro_input_t trigger_state); diff --git a/menu/menu_list.c b/menu/menu_list.c index d8b9337204..79ce72c182 100644 --- a/menu/menu_list.c +++ b/menu/menu_list.c @@ -28,16 +28,20 @@ * * Ensure it doesn't overflow. **/ -static void menu_entries_refresh(menu_handle_t *menu, file_list_t *list) +static void menu_entries_refresh(file_list_t *list) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; if (!list) return; - if (menu->selection_ptr >= menu_list_get_size(menu->menu_list) + if (menu->navigation.selection_ptr >= menu_list_get_size(menu->menu_list) && menu_list_get_size(menu->menu_list)) - menu_navigation_set(menu, menu_list_get_size(menu->menu_list) - 1, true); + menu_navigation_set(&menu->navigation, + menu_list_get_size(menu->menu_list) - 1, true); else if (!menu_list_get_size(menu->menu_list)) - menu_navigation_clear(menu, true); + menu_navigation_clear(&menu->navigation, true); } /** @@ -94,15 +98,23 @@ static void menu_entries_build_scroll_indices(file_list_t *list) size_t i; int current; bool current_is_dir; + menu_navigation_t *nav = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu || !list) + if (!menu || !list) return; - driver.menu->scroll_indices_size = 0; + nav = &menu->navigation; + + if (!nav) + return; + + nav->scroll.indices.size = 0; + if (!list->size) return; - driver.menu->scroll_indices[driver.menu->scroll_indices_size++] = 0; + nav->scroll.indices.list[nav->scroll.indices.size++] = 0; current = menu_entries_list_get_first_char(list, 0); current_is_dir = menu_entries_list_elem_is_dir(list, 0); @@ -113,13 +125,13 @@ static void menu_entries_build_scroll_indices(file_list_t *list) bool is_dir = menu_entries_list_elem_is_dir(list, i); if ((current_is_dir && !is_dir) || (first > current)) - driver.menu->scroll_indices[driver.menu->scroll_indices_size++] = i; + nav->scroll.indices.list[nav->scroll.indices.size++] = i; current = first; current_is_dir = is_dir; } - driver.menu->scroll_indices[driver.menu->scroll_indices_size++] = + nav->scroll.indices.list[nav->scroll.indices.size++] = list->size - 1; } @@ -228,16 +240,16 @@ void menu_list_flush_stack(menu_list_t *list, const char *path = NULL; const char *label = NULL; unsigned type = 0; - - if (!driver.menu || !list) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu || !list) return; - driver.menu->need_refresh = true; + menu->need_refresh = true; file_list_get_last(list->menu_stack, &path, &label, &type); while (type != final_type) { - menu_list_pop(list->menu_stack, &driver.menu->selection_ptr); + menu_list_pop(list->menu_stack, &menu->navigation.selection_ptr); file_list_get_last(list->menu_stack, &path, &label, &type); } } @@ -248,23 +260,24 @@ void menu_list_flush_stack_by_needle(menu_list_t *list, const char *path = NULL; const char *label = NULL; unsigned type = 0; - - if (!driver.menu || !list) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu || !list) return; - driver.menu->need_refresh = true; + menu->need_refresh = true; file_list_get_last(list->menu_stack, &path, &label, &type); while (strcmp(needle, label) != 0) { - menu_list_pop(list->menu_stack, &driver.menu->selection_ptr); + menu_list_pop(list->menu_stack, &menu->navigation.selection_ptr); file_list_get_last(list->menu_stack, &path, &label, &type); } } void menu_list_pop_stack(menu_list_t *list) { - if (!list) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu || !list) return; if (file_list_get_size(list->menu_stack) <= 1) @@ -273,8 +286,8 @@ void menu_list_pop_stack(menu_list_t *list) if (driver.menu_ctx->list_cache) driver.menu_ctx->list_cache(false, 0); - menu_list_pop(list->menu_stack, &driver.menu->selection_ptr); - driver.menu->need_refresh = true; + menu_list_pop(list->menu_stack, &menu->navigation.selection_ptr); + menu->need_refresh = true; } void menu_list_pop_stack_by_needle(menu_list_t *list, @@ -283,16 +296,17 @@ void menu_list_pop_stack_by_needle(menu_list_t *list, const char *path = NULL; const char *label = NULL; unsigned type = 0; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu || !list) + if (!menu || !list) return; - driver.menu->need_refresh = true; + menu->need_refresh = true; file_list_get_last(list->menu_stack, &path, &label, &type); while (strcmp(needle, label) == 0) { - menu_list_pop(list->menu_stack, &driver.menu->selection_ptr); + menu_list_pop(list->menu_stack, &menu->navigation.selection_ptr); file_list_get_last(list->menu_stack, &path, &label, &type); } } @@ -363,26 +377,28 @@ void menu_list_push_refresh(file_list_t *list, const char *path, const char *label, unsigned type, size_t directory_ptr) { - if (!list) + menu_handle_t *menu = menu_driver_resolve(); + if (!menu || !list) return; menu_list_push(list, path, label, type, directory_ptr); - menu_navigation_clear(driver.menu, true); - driver.menu->need_refresh = true; + menu_navigation_clear(&menu->navigation, true); + menu->need_refresh = true; } -void menu_list_push_stack(menu_list_t *list, - const char *path, const char *label, +void menu_list_push_stack(menu_list_t *list, const char *path, const char *label, unsigned type, size_t directory_ptr) { if (list) menu_list_push(list->menu_stack, path, label, type, directory_ptr); } -int menu_list_push_stack_refresh(menu_list_t *list, - const char *path, const char *label, +int menu_list_push_stack_refresh(menu_list_t *list, const char *path, const char *label, unsigned type, size_t directory_ptr) { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; if (!list) return -1; @@ -390,8 +406,8 @@ int menu_list_push_stack_refresh(menu_list_t *list, driver.menu_ctx->list_cache(false, 0); menu_list_push_stack(list, path, label, type, directory_ptr); - menu_navigation_clear(driver.menu, true); - driver.menu->need_refresh = true; + menu_navigation_clear(&menu->navigation, true); + menu->need_refresh = true; return 0; } @@ -413,21 +429,21 @@ void menu_list_sort_on_alt(file_list_t *list) file_list_sort_on_alt(list); } -int menu_list_populate_generic(void *data, - file_list_t *list, const char *path, +int menu_list_populate_generic(file_list_t *list, const char *path, const char *label, unsigned type) { - menu_handle_t *menu = (menu_handle_t*)data; + menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; - driver.menu->scroll_indices_size = 0; + menu->navigation.scroll.indices.size = 0; + menu_entries_build_scroll_indices(list); - menu_entries_refresh(menu, list); + menu_entries_refresh(list); if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(menu, path, label, type); + driver.menu_ctx->populate_entries(path, label, type); return 0; } diff --git a/menu/menu_list.h b/menu/menu_list.h index 29183c06db..7e866291ad 100644 --- a/menu/menu_list.h +++ b/menu/menu_list.h @@ -94,7 +94,7 @@ void menu_list_get_alt_at_offset(const file_list_t *list, size_t idx, void menu_list_set_alt_at_offset(file_list_t *list, size_t idx, const char *alt); -int menu_list_populate_generic(void *data, file_list_t *list, +int menu_list_populate_generic(file_list_t *list, const char *path, const char *label, unsigned type); #ifdef __cplusplus diff --git a/menu/menu_navigation.c b/menu/menu_navigation.c index 14d2907f6a..a4f3b26339 100644 --- a/menu/menu_navigation.c +++ b/menu/menu_navigation.c @@ -24,80 +24,91 @@ /** * menu_navigation_clear: - * @menu : menu handle * @pending_push : pending push ? * * Clears the navigation pointer. **/ -void menu_navigation_clear(menu_handle_t *menu, bool pending_push) +void menu_navigation_clear(menu_navigation_t *nav, bool pending_push) { - menu->selection_ptr = 0; + if (!nav) + return; + + nav->selection_ptr = 0; if (driver.menu_ctx && driver.menu_ctx->navigation_clear) - driver.menu_ctx->navigation_clear(menu, pending_push); + driver.menu_ctx->navigation_clear(pending_push); } /** * menu_navigation_decrement: - * @menu : menu handle * * Decrement the navigation pointer. **/ -void menu_navigation_decrement(menu_handle_t *menu) +void menu_navigation_decrement(menu_navigation_t *nav) { - menu->selection_ptr--; + if (!nav) + return; + + nav->selection_ptr--; if (driver.menu_ctx && driver.menu_ctx->navigation_decrement) - driver.menu_ctx->navigation_decrement(menu); + driver.menu_ctx->navigation_decrement(); } /** * menu_navigation_increment: - * @menu : menu handle * * Increment the navigation pointer. **/ -void menu_navigation_increment(menu_handle_t *menu) +void menu_navigation_increment(menu_navigation_t *nav) { - menu->selection_ptr++; + if (!nav) + return; + + nav->selection_ptr++; if (driver.menu_ctx && driver.menu_ctx->navigation_increment) - driver.menu_ctx->navigation_increment(menu); + driver.menu_ctx->navigation_increment(); } /** * menu_navigation_set: - * @menu : menu handle * @idx : index to set navigation pointer to. * @scroll : should we scroll when needed? * * Sets navigation pointer to index @idx. **/ -void menu_navigation_set(menu_handle_t *menu, size_t idx, bool scroll) +void menu_navigation_set(menu_navigation_t *nav, + size_t idx, bool scroll) { - menu->selection_ptr = idx; + if (!nav) + return; + + nav->selection_ptr = idx; if (driver.menu_ctx && driver.menu_ctx->navigation_set) - driver.menu_ctx->navigation_set(menu, scroll); + driver.menu_ctx->navigation_set(scroll); } /** * menu_navigation_set_last: - * @menu : menu handle * * Sets navigation pointer to last index. **/ -void menu_navigation_set_last(menu_handle_t *menu) +void menu_navigation_set_last(menu_navigation_t *nav) { - menu->selection_ptr = menu_list_get_size(driver.menu->menu_list) - 1; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu || !nav) + return; + + nav->selection_ptr = menu_list_get_size(menu->menu_list) - 1; if (driver.menu_ctx && driver.menu_ctx->navigation_set_last) - driver.menu_ctx->navigation_set_last(menu); + driver.menu_ctx->navigation_set_last(); } /** * menu_navigation_descend_alphabet: - * @menu : menu handle * @ptr_out : Amount of indices to 'scroll' to get * to the next entry. * @@ -106,30 +117,30 @@ void menu_navigation_set_last(menu_handle_t *menu) * If navigation points to an entry called 'Beta', * navigation pointer will be set to an entry called 'Alpha'. **/ -void menu_navigation_descend_alphabet(menu_handle_t *menu, size_t *ptr_out) +void menu_navigation_descend_alphabet(menu_navigation_t *nav, size_t *ptr_out) { - size_t i = 0; - size_t ptr = *ptr_out; + size_t i = 0, ptr = *ptr_out; + if (!nav) + return; - if (!menu->scroll_indices_size) + if (!nav->scroll.indices.size) return; if (ptr == 0) return; - i = menu->scroll_indices_size - 1; + i = nav->scroll.indices.size - 1; - while (i && menu->scroll_indices[i - 1] >= ptr) + while (i && nav->scroll.indices.list[i - 1] >= ptr) i--; - *ptr_out = menu->scroll_indices[i - 1]; + *ptr_out = nav->scroll.indices.list[i - 1]; if (driver.menu_ctx && driver.menu_ctx->navigation_descend_alphabet) - driver.menu_ctx->navigation_descend_alphabet(menu, ptr_out); + driver.menu_ctx->navigation_descend_alphabet(ptr_out); } /** * menu_navigation_ascends_alphabet: - * @menu : menu handle * @ptr_out : Amount of indices to 'scroll' to get * to the next entry. * @@ -138,22 +149,23 @@ void menu_navigation_descend_alphabet(menu_handle_t *menu, size_t *ptr_out) * If navigation points to an entry called 'Alpha', * navigation pointer will be set to an entry called 'Beta'. **/ -void menu_navigation_ascend_alphabet(menu_handle_t *menu, size_t *ptr_out) +void menu_navigation_ascend_alphabet(menu_navigation_t *nav, size_t *ptr_out) { - size_t i = 0; - size_t ptr = *ptr_out; - - if (!menu->scroll_indices_size) + size_t i = 0, ptr = *ptr_out; + if (!nav) return; - if (ptr == menu->scroll_indices[menu->scroll_indices_size - 1]) + if (!nav->scroll.indices.size) return; - while (i < menu->scroll_indices_size - 1 - && menu->scroll_indices[i + 1] <= ptr) + if (ptr == nav->scroll.indices.list[nav->scroll.indices.size - 1]) + return; + + while (i < nav->scroll.indices.size - 1 + && nav->scroll.indices.list[i + 1] <= ptr) i++; - *ptr_out = menu->scroll_indices[i + 1]; + *ptr_out = nav->scroll.indices.list[i + 1]; if (driver.menu_ctx && driver.menu_ctx->navigation_descend_alphabet) - driver.menu_ctx->navigation_descend_alphabet(menu, ptr_out); + driver.menu_ctx->navigation_descend_alphabet(ptr_out); } diff --git a/menu/menu_navigation.h b/menu/menu_navigation.h index 5222a46154..25bfd4d14b 100644 --- a/menu/menu_navigation.h +++ b/menu/menu_navigation.h @@ -25,50 +25,44 @@ extern "C" { /** * menu_navigation_clear: - * @menu : menu handle * @pending_push : pending push ? * * Clears the navigation pointer. **/ -void menu_navigation_clear(menu_handle_t *menu, bool pending_push); +void menu_navigation_clear(menu_navigation_t *nav, bool pending_push); /** * menu_navigation_decrement: - * @menu : menu handle * * Decrement the navigation pointer. **/ -void menu_navigation_decrement(menu_handle_t *menu); +void menu_navigation_decrement(menu_navigation_t *nav); /** * menu_navigation_increment: - * @menu : menu handle * * Increment the navigation pointer. **/ -void menu_navigation_increment(menu_handle_t *menu); +void menu_navigation_increment(menu_navigation_t *nav); /** * menu_navigation_set: - * @menu : menu handle * @idx : index to set navigation pointer to. * @scroll : should we scroll when needed? * * Sets navigation pointer to index @idx. **/ -void menu_navigation_set(menu_handle_t *menu, size_t i, bool scroll); +void menu_navigation_set(menu_navigation_t *nav, size_t i, bool scroll); /** * menu_navigation_set_last: - * @menu : menu handle * * Sets navigation pointer to last index. **/ -void menu_navigation_set_last(menu_handle_t *menu); +void menu_navigation_set_last(menu_navigation_t *nav); /** * menu_navigation_descend_alphabet: - * @menu : menu handle * @ptr_out : Amount of indices to 'scroll' to get * to the next entry. * @@ -77,11 +71,10 @@ void menu_navigation_set_last(menu_handle_t *menu); * If navigation points to an entry called 'Beta', * navigation pointer will be set to an entry called 'Alpha'. **/ -void menu_navigation_descend_alphabet(menu_handle_t *menu, size_t *ptr_out); +void menu_navigation_descend_alphabet(menu_navigation_t *nav, size_t *ptr_out); /** * menu_navigation_ascends_alphabet: - * @menu : menu handle * @ptr_out : Amount of indices to 'scroll' to get * to the next entry. * @@ -90,7 +83,7 @@ void menu_navigation_descend_alphabet(menu_handle_t *menu, size_t *ptr_out); * If navigation points to an entry called 'Alpha', * navigation pointer will be set to an entry called 'Beta'. **/ -void menu_navigation_ascend_alphabet(menu_handle_t *menu, size_t *ptr_out); +void menu_navigation_ascend_alphabet(menu_navigation_t *nav, size_t *ptr_out); #ifdef __cplusplus } diff --git a/menu/menu_shader.c b/menu/menu_shader.c index 2cb73f094e..6b14d1c92e 100644 --- a/menu/menu_shader.c +++ b/menu/menu_shader.c @@ -24,7 +24,7 @@ * * Initializes shader manager. **/ -void menu_shader_manager_init(void *data) +void menu_shader_manager_init(menu_handle_t *menu) { #ifdef HAVE_SHADER_MANAGER char preset_path[PATH_MAX_LENGTH]; @@ -32,7 +32,6 @@ void menu_shader_manager_init(void *data) struct video_shader *shader = NULL; config_file_t *conf = NULL; const char *config_path = NULL; - menu_handle_t *menu = (menu_handle_t*)data; if (!menu) return; diff --git a/menu/menu_shader.h b/menu/menu_shader.h index c62c20a7d1..991441d53b 100644 --- a/menu/menu_shader.h +++ b/menu/menu_shader.h @@ -28,7 +28,7 @@ extern "C" { * * Initializes shader manager. **/ -void menu_shader_manager_init(void *data); +void menu_shader_manager_init(menu_handle_t *menu); /** * menu_shader_manager_set_preset: diff --git a/menu/menu_texture.c b/menu/menu_texture.c new file mode 100644 index 0000000000..7518c3176c --- /dev/null +++ b/menu/menu_texture.c @@ -0,0 +1,132 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2015 - Daniel De Matteis + * Copyright (C) 2014-2015 - Jean-AndrĂ© Santoni + * + * 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 "menu_texture.h" +#include +#include "../general.h" +#include "../gfx/video_pixel_converter.h" +#include "../gfx/video_thread_wrapper.h" + +#ifdef HAVE_OPENGL +#include "../gfx/gl_common.h" + +static void menu_texture_png_load_gl(struct texture_image *ti, + enum texture_filter_type filter_type, + unsigned *id) +{ + /* Generate the OpenGL texture object */ + glGenTextures(1, id); + gl_load_texture_data((GLuint)*id, + RARCH_WRAP_EDGE, filter_type, + 4 /* TODO/FIXME - dehardcode */, + ti->width, ti->height, ti->pixels, + sizeof(uint32_t) /* TODO/FIXME - dehardcode */ + ); +} +#endif + +static unsigned menu_texture_png_load(const char *path, + enum texture_backend_type type, + enum texture_filter_type filter_type) +{ + unsigned id = 0; + struct texture_image ti = {0}; + if (! path_file_exists(path)) + return 0; + + texture_image_load(&ti, path); + + switch (type) + { + case TEXTURE_BACKEND_OPENGL: +#ifdef HAVE_OPENGL + menu_texture_png_load_gl(&ti, filter_type, &id); +#endif + break; + case TEXTURE_BACKEND_DEFAULT: + default: + break; + } + + free(ti.pixels); + + return id; +} + +static int menu_texture_png_load_wrap(void *data) +{ + const char *filename = (const char*)data; + if (!filename) + return 0; + return menu_texture_png_load(filename, TEXTURE_BACKEND_DEFAULT, + TEXTURE_FILTER_LINEAR); +} + +static int menu_texture_png_load_wrap_gl_mipmap(void *data) +{ + const char *filename = (const char*)data; + if (!filename) + return 0; + return menu_texture_png_load(filename, TEXTURE_BACKEND_OPENGL, + TEXTURE_FILTER_MIPMAP_LINEAR); +} + +static int menu_texture_png_load_wrap_gl(void *data) +{ + const char *filename = (const char*)data; + if (!filename) + return 0; + return menu_texture_png_load(filename, TEXTURE_BACKEND_OPENGL, + TEXTURE_FILTER_LINEAR); +} + +unsigned menu_texture_load(const char *path, + enum texture_backend_type type, + enum texture_filter_type filter_type) +{ + if (g_settings.video.threaded + && !g_extern.system.hw_render_callback.context_type) + { + thread_video_t *thr = (thread_video_t*)driver.video_data; + + if (!thr) + return 0; + + switch (type) + { + case TEXTURE_BACKEND_OPENGL: + if (filter_type == TEXTURE_FILTER_MIPMAP_LINEAR || + filter_type == TEXTURE_FILTER_MIPMAP_NEAREST) + thr->cmd_data.custom_command.method = menu_texture_png_load_wrap_gl_mipmap; + else + thr->cmd_data.custom_command.method = menu_texture_png_load_wrap_gl; + break; + case TEXTURE_BACKEND_DEFAULT: + default: + thr->cmd_data.custom_command.method = menu_texture_png_load_wrap; + break; + } + + thr->cmd_data.custom_command.data = (void*)path; + + thr->send_cmd_func(thr, CMD_CUSTOM_COMMAND); + thr->wait_reply_func(thr, CMD_CUSTOM_COMMAND); + + return thr->cmd_data.custom_command.return_value; + } + + return menu_texture_png_load(path, type, filter_type); +} diff --git a/gfx/rpng/rpng.h b/menu/menu_texture.h similarity index 57% rename from gfx/rpng/rpng.h rename to menu/menu_texture.h index 95fa96d512..202eac5006 100644 --- a/gfx/rpng/rpng.h +++ b/menu/menu_texture.h @@ -1,6 +1,7 @@ /* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * + * Copyright (C) 2011-2015 - Daniel De Matteis + * Copyright (C) 2014-2015 - Jean-AndrĂ© Santoni + * * 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. @@ -13,34 +14,27 @@ * If not, see . */ -#ifndef RPNG_H__ -#define RPNG_H__ +#ifndef _MENU_TEXTURE_MANAGER_H +#define _MENU_TEXTURE_MANAGER_H -#include +#include "../gfx/video_driver.h" -#include - -#ifdef HAVE_CONFIG_H -#include "../../config.h" -#endif +enum texture_backend_type +{ + TEXTURE_BACKEND_DEFAULT = 0, + TEXTURE_BACKEND_OPENGL, +}; #ifdef __cplusplus extern "C" { #endif -bool rpng_load_image_argb(const char *path, uint32_t **data, - unsigned *width, unsigned *height); - -#ifdef HAVE_ZLIB_DEFLATE -bool rpng_save_image_argb(const char *path, const uint32_t *data, - unsigned width, unsigned height, unsigned pitch); -bool rpng_save_image_bgr24(const char *path, const uint8_t *data, - unsigned width, unsigned height, unsigned pitch); -#endif +unsigned menu_texture_load(const char *path, + enum texture_backend_type type, + enum texture_filter_type filter_type); #ifdef __cplusplus } #endif #endif - diff --git a/msvc/RetroArch-360/RetroArch-360.vcxproj b/msvc/RetroArch-360/RetroArch-360.vcxproj index 1ea7fac582..5ca8c859c4 100644 --- a/msvc/RetroArch-360/RetroArch-360.vcxproj +++ b/msvc/RetroArch-360/RetroArch-360.vcxproj @@ -115,7 +115,7 @@ MultiThreadedDebug _DEBUG;_XBOX;HAVE_XINPUT2;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_RMENU_XUI;HAVE_MENU;HAVE_NETPLAY;HAVE_NETWORKING;HAVE_NETWORKING;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_D3D9;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_MINIZ;SINC_LOWER_QUALITY;HAVE_XAUDIO;WANT_RPNG;HAVE_THREADS;HAVE_BUILTIN_AUTOCONFIG;HAVE_FILTERS_BUILTIN Callcap - $(SolutionDir)\..\deps\rzlib;$(SolutionDir)\..\libretro-sdk\include;%(AdditionalIncludeDirectories) + $(SolutionDir)\..\deps\rzlib;$(SolutionDir)\..\libretro-sdk\include;$(SolutionDir)\..\;%(AdditionalIncludeDirectories) true @@ -154,7 +154,7 @@ MultiThreadedDebug _DEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_RMENU_XUI;HAVE_MENU;HAVE_ZLIB;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_D3D9;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_MINIZ;SINC_LOWER_QUALITY;WANT_RPNG;HAVE_THREADS;HAVE_BUILTIN_AUTOCONFIG;HAVE_FILTERS_BUILTIN Callcap - $(SolutionDir)\..\deps\rzlib;$(SolutionDir)\..\libretro-sdk\include;%(AdditionalIncludeDirectories) + $(SolutionDir)\..\deps\rzlib;$(SolutionDir)\..\libretro-sdk\include;$(SolutionDir)\..\;%(AdditionalIncludeDirectories) true @@ -194,7 +194,7 @@ MultiThreaded NDEBUG;_XBOX;PROFILE;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_RMENU_XUI;HAVE_MENU;HAVE_ZLIB;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_D3D9;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_MINIZ;SINC_LOWER_QUALITY;HAVE_XAUDIO;WANT_RPNG;HAVE_THREADS;HAVE_BUILTIN_AUTOCONFIG;HAVE_FILTERS_BUILTIN Callcap - $(SolutionDir)\..\deps\rzlib;$(SolutionDir)\..\libretro-sdk\include;%(AdditionalIncludeDirectories) + $(SolutionDir)\..\deps\rzlib;$(SolutionDir)\..\libretro-sdk\include;$(SolutionDir)\..\;%(AdditionalIncludeDirectories) true @@ -238,7 +238,7 @@ false MultiThreaded NDEBUG;_XBOX;PROFILE;FASTCAP;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;HAVE_ZLIB;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_D3D9;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_MINIZ;SINC_LOWER_QUALITY;HAVE_RMENU_XUI;HAVE_MENU;HAVE_XAUDIO;WANT_RPNG;HAVE_THREADS;HAVE_BUILTIN_AUTOCONFIG;HAVE_FILTERS_BUILTIN - $(SolutionDir)\..\deps\rzlib;$(SolutionDir)\..\libretro-sdk\include;%(AdditionalIncludeDirectories) + $(SolutionDir)\..\deps\rzlib;$(SolutionDir)\..\libretro-sdk\include;$(SolutionDir)\..\;%(AdditionalIncludeDirectories) true @@ -280,7 +280,7 @@ false MultiThreaded NDEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE=1;HAVE_NETPLAY;HAVE_NETWORKING;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_D3D9;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_MINIZ;SINC_LOWER_QUALITY;HAVE_RMENU_XUI;HAVE_MENU;HAVE_XAUDIO;WANT_RPNG;HAVE_THREADS;HAVE_BUILTIN_AUTOCONFIG;HAVE_FILTERS_BUILTIN - $(SolutionDir)\..\deps\rzlib;$(SolutionDir)\..\libretro-sdk\include;%(AdditionalIncludeDirectories) + $(SolutionDir)\..\deps\rzlib;$(SolutionDir)\..\libretro-sdk\include;$(SolutionDir)\..\;%(AdditionalIncludeDirectories) true @@ -322,7 +322,7 @@ false MultiThreaded NDEBUG;_XBOX;LTCG;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_RMENU_XUI;HAVE_MENU;HAVE_NETPLAY;HAVE_NETWORKING;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_D3D9;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_MINIZ;SINC_LOWER_QUALITY;HAVE_XAUDIO;WANT_RPNG;HAVE_THREADS;HAVE_BUILTIN_AUTOCONFIG;HAVE_FILTERS_BUILTIN - $(SolutionDir)\..\deps\rzlib;$(SolutionDir)\..\libretro-sdk\include;%(AdditionalIncludeDirectories) + $(SolutionDir)\..\deps\rzlib;$(SolutionDir)\..\libretro-sdk\include;$(SolutionDir)\..\;%(AdditionalIncludeDirectories) true @@ -437,4 +437,4 @@ - + \ No newline at end of file diff --git a/retroarch.c b/retroarch.c index c02e3e0e28..8027d93ffd 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1955,29 +1955,32 @@ void rarch_main_set_state(unsigned cmd) { case RARCH_ACTION_STATE_MENU_RUNNING: #ifdef HAVE_MENU - if (!driver.menu) - return; + { + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return; - if (driver.menu && driver.menu_ctx && driver.menu_ctx->toggle) - driver.menu_ctx->toggle(true); + if (driver.menu_ctx && driver.menu_ctx->toggle) + driver.menu_ctx->toggle(true); - /* Menu should always run with vsync on. */ - rarch_main_command(RARCH_CMD_VIDEO_SET_BLOCKING_STATE); - /* Stop all rumbling before entering the menu. */ - rarch_main_command(RARCH_CMD_RUMBLE_STOP); + /* Menu should always run with vsync on. */ + rarch_main_command(RARCH_CMD_VIDEO_SET_BLOCKING_STATE); + /* Stop all rumbling before entering the menu. */ + rarch_main_command(RARCH_CMD_RUMBLE_STOP); - if (g_settings.menu.pause_libretro) - rarch_main_command(RARCH_CMD_AUDIO_STOP); + if (g_settings.menu.pause_libretro) + rarch_main_command(RARCH_CMD_AUDIO_STOP); - /* Override keyboard callback to redirect to menu instead. - * We'll use this later for something ... - * FIXME: This should probably be moved to menu_common somehow. */ - g_extern.frontend_key_event = g_extern.system.key_event; - g_extern.system.key_event = menu_input_key_event; + /* Override keyboard callback to redirect to menu instead. + * We'll use this later for something ... + * FIXME: This should probably be moved to menu_common somehow. */ + g_extern.frontend_key_event = g_extern.system.key_event; + g_extern.system.key_event = menu_input_key_event; - driver.menu->need_refresh = true; - g_extern.system.frame_time_last = 0; - g_extern.is_menu = true; + menu->need_refresh = true; + g_extern.system.frame_time_last = 0; + g_extern.is_menu = true; + } #endif break; case RARCH_ACTION_STATE_LOAD_CONTENT: @@ -1993,7 +1996,7 @@ void rarch_main_set_state(unsigned cmd) #ifdef HAVE_MENU menu_apply_deferred_settings(); - if (driver.menu && driver.menu_ctx && driver.menu_ctx->toggle) + if (driver.menu_ctx && driver.menu_ctx->toggle) driver.menu_ctx->toggle(false); g_extern.is_menu = false; @@ -2158,14 +2161,17 @@ bool rarch_main_command(unsigned cmd) #endif break; case RARCH_CMD_LOAD_CORE: + { #ifdef HAVE_MENU - if (driver.menu) - rarch_update_system_info(&g_extern.menu.info, - &driver.menu->load_no_content); + menu_handle_t *menu = menu_driver_resolve(); + if (menu) + rarch_update_system_info(&g_extern.menu.info, + &menu->load_no_content); #endif #ifndef HAVE_DYNAMIC - rarch_main_command(RARCH_CMD_QUIT); + rarch_main_command(RARCH_CMD_QUIT); #endif + } break; case RARCH_CMD_LOAD_STATE: /* Immutable - disallow savestate load when @@ -2220,15 +2226,20 @@ bool rarch_main_command(unsigned cmd) return false; break; case RARCH_CMD_PREPARE_DUMMY: - *g_extern.fullpath = '\0'; + { + menu_handle_t *menu = menu_driver_resolve(); + *g_extern.fullpath = '\0'; + + (void)menu; #ifdef HAVE_MENU - if (driver.menu) - driver.menu->load_no_content = false; + if (menu) + menu->load_no_content = false; #endif - rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT); - g_extern.system.shutdown = false; + rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT); + g_extern.system.shutdown = false; + } break; case RARCH_CMD_QUIT: rarch_main_set_state(RARCH_ACTION_STATE_QUIT); @@ -2825,13 +2836,15 @@ void rarch_playlist_load_content(content_playlist_t *playlist, { const char *path = NULL; const char *core_path = NULL; + menu_handle_t *menu = menu_driver_resolve(); content_playlist_get_index(playlist, idx, &path, &core_path, NULL); strlcpy(g_settings.libretro, core_path, sizeof(g_settings.libretro)); - driver.menu->load_no_content = (path) ? false : true; + if (menu) + menu->load_no_content = (path) ? false : true; rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, (void*)path); diff --git a/retroarch.cfg b/retroarch.cfg index 784b4e28db..ff5b9d0c86 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -597,6 +597,9 @@ # Shows current date and/or time inside menu. # menu_timedate_enable = true +# Shows current core inside menu. +# menu_core_enable = true + # Throttle the menu to ~60 FPS instead of using v-sync. Useful for 120+Hz monitors. # menu_throttle = false diff --git a/runloop.c b/runloop.c index ceafd0b734..3504d53ca3 100644 --- a/runloop.c +++ b/runloop.c @@ -1036,7 +1036,8 @@ int rarch_main_iterate(void) #ifdef HAVE_MENU if (g_extern.is_menu) { - if (driver.menu) + menu_handle_t *menu = menu_driver_resolve(); + if (menu) if (menu_iterate(input, old_input, trigger_input) == -1) rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED); diff --git a/screenshot.c b/screenshot.c index 127b20d1f0..13233aa011 100644 --- a/screenshot.c +++ b/screenshot.c @@ -35,7 +35,7 @@ #ifdef HAVE_ZLIB_DEFLATE -#include "gfx/rpng/rpng.h" +#include #define IMG_EXT "png" #else diff --git a/settings.c b/settings.c index f3db9cefda..4ecf4b7af8 100644 --- a/settings.c +++ b/settings.c @@ -485,6 +485,7 @@ static void config_set_defaults(void) g_settings.menu.pause_libretro = true; g_settings.menu.mouse_enable = false; g_settings.menu.timedate_enable = true; + g_settings.menu.core_enable = true; g_settings.menu.throttle = false; *g_settings.menu.wallpaper = '\0'; g_settings.menu.navigation.wraparound.horizontal_enable = true; @@ -679,6 +680,9 @@ static void config_set_defaults(void) sizeof(g_settings.osk.overlay)); #endif } + else + strlcpy(g_extern.osk_overlay_dir, + g_extern.overlay_dir, sizeof(g_extern.osk_overlay_dir)); #endif #ifdef HAVE_MENU if (*g_defaults.menu_config_dir) @@ -1104,6 +1108,7 @@ static bool config_load_file(const char *path, bool set_defaults) CONFIG_GET_BOOL(menu.pause_libretro, "menu_pause_libretro"); CONFIG_GET_BOOL(menu.mouse_enable, "menu_mouse_enable"); CONFIG_GET_BOOL(menu.timedate_enable, "menu_timedate_enable"); + CONFIG_GET_BOOL(menu.core_enable, "menu_core_enable"); CONFIG_GET_BOOL(menu.navigation.wraparound.horizontal_enable, "menu_navigation_wraparound_horizontal_enable"); CONFIG_GET_BOOL(menu.navigation.wraparound.vertical_enable, "menu_navigation_wraparound_vertical_enable"); CONFIG_GET_BOOL(menu.navigation.browser.filter.supported_extensions_enable, "menu_navigation_browser_filter_supported_extensions_enable"); @@ -1878,6 +1883,7 @@ bool config_save_file(const char *path) config_set_bool(conf,"menu_pause_libretro", g_settings.menu.pause_libretro); config_set_bool(conf,"menu_mouse_enable", g_settings.menu.mouse_enable); config_set_bool(conf,"menu_timedate_enable", g_settings.menu.timedate_enable); + config_set_bool(conf,"menu_core_enable", g_settings.menu.core_enable); config_set_bool(conf,"menu_throttle", g_settings.menu.throttle); config_set_path(conf, "menu_wallpaper", g_settings.menu.wallpaper); #endif diff --git a/settings_data.c b/settings_data.c index 81250fa8ec..a0239f1989 100644 --- a/settings_data.c +++ b/settings_data.c @@ -418,7 +418,7 @@ static int setting_data_string_action_start_allow_input(void *data) { rarch_setting_t *setting = (rarch_setting_t*)data; - if (!setting || !driver.menu) + if (!setting) return -1; *setting->value.string = '\0'; @@ -432,7 +432,7 @@ static int setting_data_bind_action_start(void *data) struct retro_keybind *def_binds = (struct retro_keybind *)retro_keybinds_1; struct retro_keybind *keybind = NULL; - if (!setting || !driver.menu) + if (!setting) return -1; keybind = (struct retro_keybind*)setting->value.keybind; @@ -814,37 +814,39 @@ static int load_content_action_toggle(void *data, unsigned action) static int setting_data_action_ok_bind_all(void *data, unsigned action) { rarch_setting_t *setting = (rarch_setting_t*)data; + menu_handle_t *menu = menu_driver_resolve(); - if (!setting || !driver.menu) + if (!setting || !menu) return -1; - driver.menu->binds.target = &g_settings.input.binds + menu->binds.target = &g_settings.input.binds [setting->index_offset][0]; - driver.menu->binds.begin = MENU_SETTINGS_BIND_BEGIN; - driver.menu->binds.last = MENU_SETTINGS_BIND_LAST; + menu->binds.begin = MENU_SETTINGS_BIND_BEGIN; + menu->binds.last = MENU_SETTINGS_BIND_LAST; menu_list_push_stack( - driver.menu->menu_list, + menu->menu_list, "", "custom_bind_all", g_extern.menu.bind_mode_keyboard ? MENU_SETTINGS_CUSTOM_BIND_KEYBOARD : MENU_SETTINGS_CUSTOM_BIND, - driver.menu->selection_ptr); + menu->navigation.selection_ptr); if (g_extern.menu.bind_mode_keyboard) { - driver.menu->binds.timeout_end = + menu->binds.timeout_end = rarch_get_time_usec() + MENU_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000; - input_keyboard_wait_keys(driver.menu, + input_keyboard_wait_keys(menu, menu_input_custom_bind_keyboard_cb); } else { - menu_input_poll_bind_get_rested_axes(&driver.menu->binds); - menu_input_poll_bind_state(&driver.menu->binds); + menu_input_poll_bind_get_rested_axes(&menu->binds); + menu_input_poll_bind_state(&menu->binds); } + return 0; } @@ -854,7 +856,10 @@ static int setting_data_action_ok_bind_defaults(void *data, unsigned action) struct retro_keybind *target = NULL; const struct retro_keybind *def_binds = NULL; rarch_setting_t *setting = (rarch_setting_t*)data; + menu_handle_t *menu = menu_driver_resolve(); + if (!menu) + return -1; if (!setting) return -1; @@ -863,11 +868,11 @@ static int setting_data_action_ok_bind_defaults(void *data, unsigned action) def_binds = (setting->index_offset) ? retro_keybinds_rest : retro_keybinds_1; - if (!driver.menu || !target) + if (!target) return -1; - driver.menu->binds.begin = MENU_SETTINGS_BIND_BEGIN; - driver.menu->binds.last = MENU_SETTINGS_BIND_LAST; + menu->binds.begin = MENU_SETTINGS_BIND_BEGIN; + menu->binds.last = MENU_SETTINGS_BIND_LAST; for (i = MENU_SETTINGS_BIND_BEGIN; i <= MENU_SETTINGS_BIND_LAST; i++, target++) @@ -978,7 +983,7 @@ static int setting_data_uint_action_ok_linefeed(void *data, unsigned action) if (!setting) return -1; - menu_input_key_start_line(driver.menu, setting->short_description, + menu_input_key_start_line(setting->short_description, setting->name, 0, 0, menu_input_st_uint_callback); return 0; @@ -1001,11 +1006,12 @@ static int setting_data_bind_action_ok(void *data, unsigned action) { struct retro_keybind *keybind = NULL; rarch_setting_t *setting = (rarch_setting_t*)data; + menu_handle_t *menu = menu_driver_resolve(); if (!setting) return -1; - if (!driver.menu || !driver.menu->menu_list) + if (!menu || !menu->menu_list) return -1; keybind = (struct retro_keybind*)setting->value.keybind; @@ -1013,29 +1019,29 @@ static int setting_data_bind_action_ok(void *data, unsigned action) if (!keybind) return -1; - driver.menu->binds.begin = setting->bind_type; - driver.menu->binds.last = setting->bind_type; - driver.menu->binds.target = keybind; - driver.menu->binds.user = setting->index_offset; + menu->binds.begin = setting->bind_type; + menu->binds.last = setting->bind_type; + menu->binds.target = keybind; + menu->binds.user = setting->index_offset; menu_list_push_stack( - driver.menu->menu_list, + menu->menu_list, "", "custom_bind", g_extern.menu.bind_mode_keyboard ? MENU_SETTINGS_CUSTOM_BIND_KEYBOARD : MENU_SETTINGS_CUSTOM_BIND, - driver.menu->selection_ptr); + menu->navigation.selection_ptr); if (g_extern.menu.bind_mode_keyboard) { - driver.menu->binds.timeout_end = rarch_get_time_usec() + + menu->binds.timeout_end = rarch_get_time_usec() + MENU_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000; - input_keyboard_wait_keys(driver.menu, + input_keyboard_wait_keys(menu, menu_input_custom_bind_keyboard_cb); } else { - menu_input_poll_bind_get_rested_axes(&driver.menu->binds); - menu_input_poll_bind_state(&driver.menu->binds); + menu_input_poll_bind_get_rested_axes(&menu->binds); + menu_input_poll_bind_state(&menu->binds); } return 0; @@ -1046,10 +1052,10 @@ static int setting_data_string_action_ok_allow_input(void *data, { rarch_setting_t *setting = (rarch_setting_t*)data; - if (!setting || !driver.menu) + if (!setting) return -1; - menu_input_key_start_line(driver.menu, setting->short_description, + menu_input_key_start_line(setting->short_description, setting->name, 0, 0, menu_input_st_string_callback); return 0; @@ -2791,11 +2797,12 @@ void setting_data_get_label(file_list_t *list, char *type_str, { rarch_setting_t *setting_data = NULL; rarch_setting_t *setting = NULL; + menu_handle_t *menu = menu_driver_resolve(); - if (!driver.menu || !driver.menu->menu_list || !label) + if (!menu || !menu->menu_list || !label) return; - setting_data = (rarch_setting_t*)driver.menu->list_settings; + setting_data = (rarch_setting_t*)menu->list_settings; if (!setting_data) return; @@ -2867,14 +2874,16 @@ static void general_write_handler(void *data) if (!strcmp(setting->name, "help")) { - if (!driver.menu || !driver.menu->menu_list) + menu_handle_t *menu = menu_driver_resolve(); + + if (!menu || !menu->menu_list) return; if (*setting->value.boolean) { #ifdef HAVE_MENU menu_list_push_stack_refresh( - driver.menu->menu_list, + menu->menu_list, "", "help", 0, @@ -3195,20 +3204,6 @@ static bool setting_data_append_list_main_menu_options( subgroup_info.name); #endif -#ifdef HAVE_LIBRETRODB - CONFIG_ACTION( - "database_manager_list", - "Database Manager", - group_info.name, - subgroup_info.name); - - CONFIG_ACTION( - "cursor_manager_list", - "Cursor Manager", - group_info.name, - subgroup_info.name); -#endif - if (g_settings.history_list_enable) { CONFIG_ACTION( @@ -3240,12 +3235,6 @@ static bool setting_data_append_list_main_menu_options( (*list)[list_info->index - 1].change_handler = load_content_change_handler; settings_data_list_current_add_flags(list, list_info, SD_FLAG_BROWSER_ACTION); - CONFIG_ACTION( - "core_options", - "Core Options", - group_info.name, - subgroup_info.name); - CONFIG_ACTION( "core_information", @@ -3253,31 +3242,17 @@ static bool setting_data_append_list_main_menu_options( group_info.name, subgroup_info.name); - if (g_extern.main_is_init) - { - if (g_extern.has_set_input_descriptors) - CONFIG_ACTION( - "core_input_remapping_options", - "Core Input Remapping Options", - group_info.name, - subgroup_info.name); + CONFIG_ACTION( + "management", + "Management", + group_info.name, + subgroup_info.name); - CONFIG_ACTION( - "core_cheat_options", - "Core Cheat Options", - group_info.name, - subgroup_info.name); - - if ( !g_extern.libretro_dummy - && g_extern.system.disk_control.get_num_images) - { - CONFIG_ACTION( - "disk_options", - "Core Disk Options", - group_info.name, - subgroup_info.name); - } - } + CONFIG_ACTION( + "options", + "Options", + group_info.name, + subgroup_info.name); CONFIG_ACTION( "settings", @@ -3391,7 +3366,7 @@ static bool setting_data_append_list_driver_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Driver Options"); + START_GROUP(group_info, "Driver Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); @@ -3506,7 +3481,7 @@ static bool setting_data_append_list_general_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "General Options"); + START_GROUP(group_info, "General Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_BOOL( @@ -3750,7 +3725,7 @@ static bool setting_data_append_list_video_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Video Options"); + START_GROUP(group_info, "Video Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_BOOL( @@ -4327,7 +4302,7 @@ static bool setting_data_append_list_shader_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Shader Options"); + START_GROUP(group_info, "Shader Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_BOOL( @@ -4366,7 +4341,7 @@ static bool setting_data_append_list_font_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Font Options"); + START_GROUP(group_info, "Font Settings"); START_SUB_GROUP(list, list_info, "Messages", group_info.name, subgroup_info); CONFIG_PATH( @@ -4443,7 +4418,7 @@ static bool setting_data_append_list_audio_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Audio Options"); + START_GROUP(group_info, "Audio Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_BOOL( @@ -4635,7 +4610,7 @@ static bool setting_data_append_list_input_options( rarch_setting_group_info_t subgroup_info; unsigned i, user; - START_GROUP(group_info, "Input Options"); + START_GROUP(group_info, "Input Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_UINT( @@ -5004,7 +4979,7 @@ static bool setting_data_append_list_overlay_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Overlay Options"); + START_GROUP(group_info, "Overlay Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_BOOL( @@ -5076,7 +5051,7 @@ static bool setting_data_append_list_osk_overlay_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Onscreen Keyboard Overlay Options"); + START_GROUP(group_info, "Onscreen Keyboard Overlay Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_BOOL( @@ -5118,7 +5093,7 @@ static bool setting_data_append_list_menu_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Menu Options"); + START_GROUP(group_info, "Menu Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_PATH( @@ -5145,17 +5120,6 @@ static bool setting_data_append_list_menu_options( general_write_handler, general_read_handler); - CONFIG_BOOL( - g_settings.menu_show_start_screen, - "rgui_show_start_screen", - "Show Start Screen", - menu_show_start_screen, - "OFF", - "ON", - group_info.name, - subgroup_info.name, - general_write_handler, - general_read_handler); CONFIG_BOOL( g_settings.menu.pause_libretro, @@ -5243,10 +5207,34 @@ static bool setting_data_append_list_menu_options( general_write_handler, general_read_handler); + CONFIG_BOOL( + g_settings.menu_show_start_screen, + "rgui_show_start_screen", + "Show Start Screen", + menu_show_start_screen, + "OFF", + "ON", + group_info.name, + subgroup_info.name, + general_write_handler, + general_read_handler); + CONFIG_BOOL( g_settings.menu.timedate_enable, "menu_timedate_enable", - "Time / date enable", + "Show time / date", + true, + "OFF", + "ON", + group_info.name, + subgroup_info.name, + general_write_handler, + general_read_handler); + + CONFIG_BOOL( + g_settings.menu.core_enable, + "menu_core_enable", + "Show core name", true, "OFF", "ON", @@ -5271,7 +5259,7 @@ static bool setting_data_append_list_ui_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "UI Options"); + START_GROUP(group_info, "UI Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_BOOL( @@ -5338,7 +5326,7 @@ static bool setting_data_append_list_archive_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Archive Options"); + START_GROUP(group_info, "Archive Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_UINT( @@ -5368,7 +5356,7 @@ static bool setting_data_append_list_core_updater_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Core Updater Options"); + START_GROUP(group_info, "Core Updater Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); @@ -5421,7 +5409,7 @@ static bool setting_data_append_list_netplay_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Network Options"); + START_GROUP(group_info, "Network Settings"); START_SUB_GROUP(list, list_info, "Netplay", group_info.name, subgroup_info); @@ -5553,7 +5541,7 @@ static bool setting_data_append_list_patch_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Patch Options"); + START_GROUP(group_info, "Patch Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_BOOL( @@ -5605,7 +5593,7 @@ static bool setting_data_append_list_playlist_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Playlist Options"); + START_GROUP(group_info, "Playlist Settings"); START_SUB_GROUP(list, list_info, "History", group_info.name, subgroup_info); CONFIG_BOOL( @@ -5644,7 +5632,7 @@ static bool setting_data_append_list_user_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "User Options"); + START_GROUP(group_info, "User Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_STRING( @@ -5692,7 +5680,7 @@ static bool setting_data_append_list_path_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Path Options"); + START_GROUP(group_info, "Path Settings"); START_SUB_GROUP(list, list_info, "Paths", group_info.name, subgroup_info); #ifdef HAVE_MENU @@ -6074,7 +6062,7 @@ static bool setting_data_append_list_privacy_options( rarch_setting_group_info_t group_info; rarch_setting_group_info_t subgroup_info; - START_GROUP(group_info, "Privacy Options"); + START_GROUP(group_info, "Privacy Settings"); START_SUB_GROUP(list, list_info, "State", group_info.name, subgroup_info); CONFIG_BOOL(