diff --git a/AUTHORS.h b/AUTHORS.h index 7ef8548e1f..a7f3298fb4 100644 --- a/AUTHORS.h +++ b/AUTHORS.h @@ -92,6 +92,7 @@ Fabio Ritrovato (Sephiroth87) Fayne Aldan (FayneAldan) FIX94 Flame Sage (chris062689) +flyinghead Francisco José García García (frangarcj) GameDragon2k Garrett Brown (garbear) @@ -124,6 +125,7 @@ Jay McCarthy (jeapostrophe) Jean-André Santoni (kivutar) Jean-Paul Mari (djipi) Jean-Sébastien Guay (Skylark13) +Jesse Bryan (winneon) Joel (joel16) Joerg Sonnenberger (jsonn) Johannes Schickel (lordhoto) @@ -260,6 +262,7 @@ Vladimir Panteleev (CyberShadow) Víctor "IlDucci" (IlDucci) Wang Vincent (susemm) webgeek1234 +Wiktor Strzębała (wiktorek140) xhp-creations Yarsan Hoessain (hyarsan) Yongwoon Cho (ssangkong) diff --git a/CHANGES.md b/CHANGES.md index 0ddf01b29a..864d7f10db 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,10 @@ - MENU/QT/WIMP: Initial grid view. - MENU/QT/WIMP: Drag&drop to add new playlist items, add option to add/edit/delete playlists. - MENU/QT/WIMP: Add menu option to update RetroArch (Windows only for now). +- MENU/QT/WIMP: Add menu option to manage shaders. +- MENU/QT/WIMP: Add menu option to manage core options. +- MENU/XMB: Add new icons for the settings +- MENU/XMB: Add an option to show the desktop ui - METAL: Initial work-in-progress video driver for Metal. macOS-only right now, and currently requires macOS 10.13. - METAL: Supports XMB/MaterialUI, has a menu display driver. Has a font rendering driver. - METAL/SLANG: Slang shaders should be compatible with Metal video driver. @@ -91,7 +95,7 @@ video drivers that implement it (D3D8/9/10/11/12/GL) - MENU/RGUI: D3D8/D3D9: Hookup Menu Linear Filter - MENU/XMB: Disable XMB shadow icons by default for PowerPC and ARM for performance reasons. - MENU/XMB: Left/right thumbnails are now automatically scaled according to layout. -- MENU/XMB: Add Left Thumbnails (additional to the right). +- MENU/XMB: Add Left Thumbnails (additional to the right). - MENU/XMB: Fixed left/right tab regression. - MENU/XMB: Fix scaling of tall images that were cut on bottom previously. - MENU/XMB: Menu scale factor setting now changes texts length, image scaling and margins. diff --git a/Makefile.common b/Makefile.common index 3cd2c39654..125afe8532 100644 --- a/Makefile.common +++ b/Makefile.common @@ -332,6 +332,11 @@ endif # Qt WIMP GUI +ifeq ($(HAVE_OPENSSL), 1) +DEFINES += $(OPENSSL_CFLAGS) +LIBS += $(OPENSSL_LIBS) +endif + ifeq ($(HAVE_QT), 1) OBJ += ui/drivers/ui_qt.o \ ui/drivers/qt/ui_qt_application.o \ @@ -339,11 +344,28 @@ OBJ += ui/drivers/ui_qt.o \ ui/drivers/qt/ui_qt_browser_window.o \ ui/drivers/qt/ui_qt_load_core_window.o \ ui/drivers/qt/ui_qt_msg_window.o \ - ui/drivers/qt/flowlayout.o + ui/drivers/qt/flowlayout.o \ + ui/drivers/qt/shaderparamsdialog.o \ + ui/drivers/qt/coreoptionsdialog.o \ + ui/drivers/qt/filedropwidget.o \ + ui/drivers/qt/coreinfodialog.o \ + ui/drivers/qt/playlistentrydialog.o \ + ui/drivers/qt/viewoptionsdialog.o \ + ui/drivers/qt/playlist.o \ + ui/drivers/qt/updateretroarch.o \ + ui/drivers/qt/thumbnaildownload.o \ + ui/drivers/qt/thumbnailpackdownload.o \ + ui/drivers/qt/playlistthumbnaildownload.o MOC_HEADERS += ui/drivers/ui_qt.h \ ui/drivers/qt/ui_qt_load_core_window.h \ - ui/drivers/qt/flowlayout.h + ui/drivers/qt/flowlayout.h \ + ui/drivers/qt/shaderparamsdialog.h \ + ui/drivers/qt/coreoptionsdialog.h \ + ui/drivers/qt/filedropwidget.h \ + ui/drivers/qt/coreinfodialog.h \ + ui/drivers/qt/playlistentrydialog.h \ + ui/drivers/qt/viewoptionsdialog.h DEFINES += $(QT5CORE_CFLAGS) $(QT5GUI_CFLAGS) $(QT5WIDGETS_CFLAGS) $(QT5CONCURRENT_CFLAGS) $(QT5NETWORK_CFLAGS) -DHAVE_MAIN #DEFINES += $(QT5WEBENGINE_CFLAGS) @@ -374,7 +396,6 @@ OBJ += libretro-db/bintree.o \ endif ifneq ($(C89_BUILD), 1) -HAVE_LIBUI = 0 HAVE_GTKPLUS = 0 ifeq ($(HAVE_SSL), 1) @@ -463,157 +484,6 @@ OBJS_TLS = deps/mbedtls/debug.o \ OBJ += $(OBJS_TLS_CRYPTO) $(OBJS_TLS_X509) $(OBJS_TLS) endif - -ifeq ($(HAVE_LIBUI), 1) -DEFINES += -DHAVE_LIBUI -ifneq ($(findstring Win32,$(OS)),) -OBJ += deps/libui/windows/alloc.o \ - deps/libui/windows/area.o \ - deps/libui/windows/areadraw.o \ - deps/libui/windows/areaevents.o \ - deps/libui/windows/areascroll.o \ - deps/libui/windows/areautil.o \ - deps/libui/windows/box.o \ - deps/libui/windows/button.o \ - deps/libui/windows/checkbox.o \ - deps/libui/windows/colorbutton.o \ - deps/libui/windows/colordialog.o \ - deps/libui/windows/combobox.o \ - deps/libui/windows/container.o \ - deps/libui/windows/control.o \ - deps/libui/windows/d2dscratch.o \ - deps/libui/windows/datetimepicker.o \ - deps/libui/windows/debug.o \ - deps/libui/windows/draw.o \ - deps/libui/windows/drawmatrix.o \ - deps/libui/windows/drawpath.o \ - deps/libui/windows/drawtext.o \ - deps/libui/windows/dwrite.o \ - deps/libui/windows/editablecombo.o \ - deps/libui/windows/entry.o \ - deps/libui/windows/events.o \ - deps/libui/windows/fontbutton.o \ - deps/libui/windows/fontdialog.o \ - deps/libui/windows/form.o \ - deps/libui/windows/graphemes.o \ - deps/libui/windows/grid.o \ - deps/libui/windows/group.o \ - deps/libui/windows/init.o \ - deps/libui/windows/label.o \ - deps/libui/windows/main.o \ - deps/libui/windows/menu.o \ - deps/libui/windows/multilineentry.o \ - deps/libui/windows/parent.o \ - deps/libui/windows/progressbar.o \ - deps/libui/windows/radiobuttons.o \ - deps/libui/windows/separator.o \ - deps/libui/windows/sizing.o \ - deps/libui/windows/slider.o \ - deps/libui/windows/spinbox.o \ - deps/libui/windows/stddialogs.o \ - deps/libui/windows/tab.o \ - deps/libui/windows/tabpage.o \ - deps/libui/windows/text.o \ - deps/libui/windows/utf16.o \ - deps/libui/windows/utilwin.o \ - deps/libui/windows/window.o \ - deps/libui/windows/winpublic.o \ - deps/libui/windows/winutil.o -LIBS += -luxtheme -ld2d1 -ldwrite -lusp10 -else -ifneq ($(findstring Darwin,$(OS)),) -OBJ += deps/libui/darwin/alloc.o \ - deps/libui/darwin/area.o \ - deps/libui/darwin/areaevents.o \ - deps/libui/darwin/autolayout.o \ - deps/libui/darwin/box.o \ - deps/libui/darwin/button.o \ - deps/libui/darwin/checkbox.o \ - deps/libui/darwin/colorbutton.o \ - deps/libui/darwin/combobox.o \ - deps/libui/darwin/control.o \ - deps/libui/darwin/datetimepicker.o \ - deps/libui/darwin/debug.o \ - deps/libui/darwin/draw.o \ - deps/libui/darwin/drawtext.o \ - deps/libui/darwin/editablecombo.o \ - deps/libui/darwin/entry.o \ - deps/libui/darwin/fontbutton.o \ - deps/libui/darwin/form.o \ - deps/libui/darwin/grid.o \ - deps/libui/darwin/group.o \ - deps/libui/darwin/image.o \ - deps/libui/darwin/label.o \ - deps/libui/darwin/main.o \ - deps/libui/darwin/map.o \ - deps/libui/darwin/menu.o \ - deps/libui/darwin/multilineentry.o \ - deps/libui/darwin/progressbar.o \ - deps/libui/darwin/radiobuttons.o \ - deps/libui/darwin/scrollview.o \ - deps/libui/darwin/separator.o \ - deps/libui/darwin/slider.o \ - deps/libui/darwin/spinbox.o \ - deps/libui/darwin/stddialogs.o \ - deps/libui/darwin/tab.o \ - deps/libui/darwin/text.o \ - deps/libui/darwin/util.o \ - deps/libui/darwin/window.o \ - deps/libui/darwin/winmoveresize.o -else -CFLAGS += -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/atk-1.0 -LIBS += -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -OBJ += deps/libui/unix/alloc.o \ - deps/libui/unix/area.o \ - deps/libui/unix/box.o \ - deps/libui/unix/button.o \ - deps/libui/unix/cellrendererbutton.o \ - deps/libui/unix/checkbox.o \ - deps/libui/unix/child.o \ - deps/libui/unix/colorbutton.o \ - deps/libui/unix/combobox.o \ - deps/libui/unix/control.o \ - deps/libui/unix/datetimepicker.o \ - deps/libui/unix/debug.o \ - deps/libui/unix/draw.o \ - deps/libui/unix/drawmatrix.o \ - deps/libui/unix/drawpath.o \ - deps/libui/unix/drawtext.o \ - deps/libui/unix/editablecombo.o \ - deps/libui/unix/entry.o \ - deps/libui/unix/fontbutton.o \ - deps/libui/unix/form.o \ - deps/libui/unix/future.o \ - deps/libui/unix/graphemes.o \ - deps/libui/unix/grid.o \ - deps/libui/unix/group.o \ - deps/libui/unix/image.o \ - deps/libui/unix/label.o \ - deps/libui/unix/main.o \ - deps/libui/unix/menu.o \ - deps/libui/unix/multilineentry.o \ - deps/libui/unix/progressbar.o \ - deps/libui/unix/radiobuttons.o \ - deps/libui/unix/separator.o \ - deps/libui/unix/slider.o \ - deps/libui/unix/spinbox.o \ - deps/libui/unix/stddialogs.o \ - deps/libui/unix/tab.o \ - deps/libui/unix/text.o \ - deps/libui/unix/util.o \ - deps/libui/unix/window.o -endif -endif - -OBJ += deps/libui/common/areaevents.o \ - deps/libui/common/control.o \ - deps/libui/common/debug.o \ - deps/libui/common/matrix.o \ - deps/libui/common/shouldquit.o \ - deps/libui/common/userbugs.o - -OBJ += deps/libui/libui_main.o -endif endif # Miscellaneous @@ -960,6 +830,9 @@ endif ifeq ($(HAVE_WAYLAND), 1) OBJ += gfx/drivers_context/wayland_ctx.o \ input/drivers/wayland_input.o + ifeq ($(HAVE_EGL), 1) + LIBS += $(EGL_LIBS) + endif DEFINES += $(WAYLAND_CFLAGS) $(WAYLAND_CURSOR_CFLAGS) LIBS += $(WAYLAND_LIBS) $(WAYLAND_CURSOR_LIBS) endif @@ -1278,7 +1151,7 @@ ifeq ($(HAVE_VULKAN), 1) CXXFLAGS += -fpermissive endif - CXXFLAGS += -Wno-switch -Wno-sign-compare -fno-strict-aliasing -Wno-maybe-uninitialized -Wno-reorder -Wno-parentheses + CXXFLAGS += -Wno-switch -Wno-sign-compare -fno-strict-aliasing -Wno-reorder -Wno-parentheses OBJ += gfx/drivers/vulkan.o \ gfx/common/vulkan_common.o \ @@ -1732,6 +1605,7 @@ ifeq ($(HAVE_NETWORKING), 1) endif ifeq ($(HAVE_DISCORD), 1) + NEED_CXX_LINKER = 1 DEFINES += -DHAVE_DISCORD DEFINES += -Ideps/discord-rpc/include/ -Ideps/discord-rpc/thirdparty/rapidjson-1.1.0/include/ OBJ += deps/discord-rpc/src/discord_rpc.o \ diff --git a/Makefile.psp1 b/Makefile.psp1 index cf57142100..be0ae8e25a 100644 --- a/Makefile.psp1 +++ b/Makefile.psp1 @@ -13,7 +13,7 @@ TARGET = retroarchpsp ifeq ($(DEBUG), 1) OPTIMIZE_LV := -O0 -g else - OPTIMIZE_LV := -O2 + OPTIMIZE_LV := -O3 endif ifeq ($(WHOLE_ARCHIVE_LINK), 1) @@ -22,7 +22,7 @@ ifeq ($(WHOLE_ARCHIVE_LINK), 1) endif INCDIR = deps deps/stb deps/libz deps/7zip deps/pthreads deps/pthreads/platform/psp deps/pthreads/platform/helper libretro-common/include -CFLAGS = $(OPTIMIZE_LV) -G0 -std=gnu99 -ffast-math +CFLAGS = $(OPTIMIZE_LV) -G0 -std=gnu99 -ffast-math -fsingle-precision-constant ASFLAGS = $(CFLAGS) RARCH_DEFINES = -DPSP -D_MIPS_ARCH_ALLEGREX -DHAVE_LANGEXTRA -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DWANT_ZLIB -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -DHAVE_CC_RESAMPLER diff --git a/audio/drivers/dsound.c b/audio/drivers/dsound.c index d6a89db3c0..396ff8a332 100644 --- a/audio/drivers/dsound.c +++ b/audio/drivers/dsound.c @@ -32,7 +32,9 @@ #include #include #include +#ifdef HAVE_THREADS #include +#endif #include #include "../audio_driver.h" @@ -59,7 +61,11 @@ typedef struct dsound CRITICAL_SECTION crit; HANDLE event; +#ifdef HAVE_THREADS sthread_t *thread; +#else + HANDLE thread; +#endif unsigned buffer_size; @@ -137,7 +143,11 @@ static INLINE void release_region(dsound_t *ds, const struct audio_lock *region) region->size1, region->chunk2, region->size2); } +#ifdef HAVE_THREADS static void dsound_thread(void *data) +#else +static DWORD CALLBACK dsound_thread(PVOID data) +#endif { DWORD write_ptr; dsound_t *ds = (dsound_t*)data; @@ -219,7 +229,13 @@ static void dsound_stop_thread(dsound_t *ds) ds->thread_alive = false; +#ifdef HAVE_THREADS sthread_join(ds->thread); +#else + WaitForSingleObject(ds->thread, INFINITE); + CloseHandle(ds->thread); +#endif + ds->thread = NULL; } @@ -228,7 +244,12 @@ static bool dsound_start_thread(dsound_t *ds) if (!ds->thread) { ds->thread_alive = true; - ds->thread = sthread_create(dsound_thread, ds); + +#ifdef HAVE_THREADS + ds->thread = sthread_create(dsound_thread, ds); +#else + ds->thread = CreateThread(NULL, 0, dsound_thread, ds, 0, NULL); +#endif if (!ds->thread) return false; } @@ -261,7 +282,12 @@ static void dsound_free(void *data) if (ds->thread) { ds->thread_alive = false; +#ifdef HAVE_THREADS sthread_join(ds->thread); +#else + WaitForSingleObject(ds->thread, INFINITE); + CloseHandle(ds->thread); +#endif } DeleteCriticalSection(&ds->crit); diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index d65ed9ec32..0e21e3687a 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -1674,7 +1674,7 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) shotname[sizeof(shotname) - 1] = '\0'; if (take_screenshot(shotname, true, - video_driver_cached_frame_has_valid_framebuffer())) + video_driver_cached_frame_has_valid_framebuffer(), false, true)) CHEEVOS_LOG("[CHEEVOS]: got a screenshot for cheevo %u\n", cheevo->id); else CHEEVOS_LOG("[CHEEVOS]: failed to get screenshot for cheevo %u\n", cheevo->id); @@ -2080,7 +2080,7 @@ void cheevos_populate_menu(void *data) cheevo_t *cheevo = cheevos_locals.core.cheevos; end = cheevo + cheevos_locals.core.count; - if(settings->bools.cheevos_enable && settings->bools.cheevos_hardcore_mode_enable + if(settings->bools.cheevos_enable && settings->bools.cheevos_hardcore_mode_enable && cheevos_loaded) { if (!cheevos_hardcore_paused) diff --git a/command.c b/command.c index 18ca322b53..40f6310c3e 100644 --- a/command.c +++ b/command.c @@ -1,6 +1,6 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis - * Copyright (C) 2015-2017 - Andrés Suárez + * Copyright (C) 2015-2017 - Andres Suarez * Copyright (C) 2016-2017 - Brad Parker * * RetroArch is free software: you can redistribute it and/or modify it under the terms @@ -230,9 +230,11 @@ bool command_set_shader(const char *arg) { char msg[256]; bool is_preset = false; - struct video_shader *shader = menu_shader_get(); enum rarch_shader_type type = video_shader_get_type_from_ext( path_get_extension(arg), &is_preset); +#ifdef HAVE_MENU + struct video_shader *shader = menu_shader_get(); +#endif if (type == RARCH_SHADER_NONE) return false; @@ -244,18 +246,23 @@ bool command_set_shader(const char *arg) arg); retroarch_set_shader_preset(arg); +#ifdef HAVE_MENU return menu_shader_manager_set_preset(shader, type, arg); +#else + return true; +#endif } static bool command_version(const char* arg) { - char reply[256] = {0}; + char reply[256] = {0}; - sprintf(reply, "%s\n", PACKAGE_VERSION); + sprintf(reply, "%s\n", PACKAGE_VERSION); #if defined(HAVE_CHEEVOS) && (defined(HAVE_STDIN_CMD) || defined(HAVE_NETWORK_CMD) && defined(HAVE_NETWORKING)) - command_reply(reply, strlen(reply)); + command_reply(reply, strlen(reply)); #endif - return true; + + return true; } #if defined(HAVE_COMMAND) && defined(HAVE_CHEEVOS) @@ -550,10 +557,10 @@ bool command_network_send(const char *cmd_) } free(command); - return ret; -#else - return false; + if (ret) + return true; #endif + return false; } #ifdef HAVE_STDIN_CMD @@ -1059,7 +1066,7 @@ static void command_event_init_controllers(void) break; } - if (set_controller && i < info->ports.size) + if (set_controller && info && i < info->ports.size) { pad.device = device; pad.port = i; @@ -1336,8 +1343,8 @@ static void command_event_restore_default_shader_preset(void) static void command_event_restore_remaps(void) { - if (rarch_ctl(RARCH_CTL_IS_REMAPS_CORE_ACTIVE, NULL) || - rarch_ctl(RARCH_CTL_IS_REMAPS_CONTENT_DIR_ACTIVE, NULL) || + if (rarch_ctl(RARCH_CTL_IS_REMAPS_CORE_ACTIVE, NULL) || + rarch_ctl(RARCH_CTL_IS_REMAPS_CONTENT_DIR_ACTIVE, NULL) || rarch_ctl(RARCH_CTL_IS_REMAPS_GAME_ACTIVE, NULL)) input_remapping_set_defaults(true); } @@ -1947,7 +1954,7 @@ bool command_event(enum event_command cmd, void *data) break; case CMD_EVENT_TAKE_SCREENSHOT: if (!take_screenshot(path_get(RARCH_PATH_BASENAME), false, - video_driver_cached_frame_has_valid_framebuffer())) + video_driver_cached_frame_has_valid_framebuffer(), false, true)) return false; break; case CMD_EVENT_UNLOAD_CORE: @@ -2441,10 +2448,14 @@ TODO: Add a setting for these tweaks */ if (!command_event_save_core_config()) return false; break; + case CMD_EVENT_SHADER_PRESET_LOADED: + ui_companion_event_command(cmd); + break; case CMD_EVENT_SHADERS_APPLY_CHANGES: #ifdef HAVE_MENU menu_shader_manager_apply_changes(); #endif + ui_companion_event_command(cmd); break; case CMD_EVENT_PAUSE_CHECKS: { @@ -2466,6 +2477,13 @@ TODO: Add a setting for these tweaks */ if (!is_idle) video_driver_cached_frame(); + +#ifdef HAVE_DISCORD + discord_userdata_t userdata; + userdata.status = DISCORD_PRESENCE_GAME_PAUSED; + + command_event(CMD_EVENT_DISCORD_UPDATE, &userdata); +#endif } else { @@ -2875,12 +2893,6 @@ TODO: Add a setting for these tweaks */ case CMD_EVENT_RESTORE_DEFAULT_SHADER_PRESET: command_event_restore_default_shader_preset(); break; - case CMD_EVENT_LIBUI_TEST: -#if HAVE_LIBUI - extern int libui_main(void); - libui_main(); -#endif - break; case CMD_EVENT_DISCORD_INIT: #ifdef HAVE_DISCORD { diff --git a/command.h b/command.h index 6b50d6f3eb..85712bd027 100644 --- a/command.h +++ b/command.h @@ -158,6 +158,8 @@ enum event_command CMD_EVENT_MENU_REFRESH, /* Applies shader changes. */ CMD_EVENT_SHADERS_APPLY_CHANGES, + /* A new shader preset has been loaded */ + CMD_EVENT_SHADER_PRESET_LOADED, /* Initializes shader directory. */ CMD_EVENT_SHADER_DIR_INIT, /* Deinitializes shader directory. */ @@ -233,8 +235,7 @@ enum event_command CMD_EVENT_RESTORE_DEFAULT_SHADER_PRESET, CMD_EVENT_DISCORD_INIT, CMD_EVENT_DISCORD_DEINIT, - CMD_EVENT_DISCORD_UPDATE, - CMD_EVENT_LIBUI_TEST + CMD_EVENT_DISCORD_UPDATE }; bool command_set_shader(const char *arg); diff --git a/configuration.c b/configuration.c index 868dc5ab7b..cd33faec0d 100644 --- a/configuration.c +++ b/configuration.c @@ -1069,7 +1069,7 @@ bool config_overlay_enable_default(void) static struct config_array_setting *populate_settings_array(settings_t *settings, int *size) { unsigned count = 0; - struct config_array_setting *tmp = (struct config_array_setting*)malloc((*size + 1) * sizeof(struct config_array_setting)); + struct config_array_setting *tmp = (struct config_array_setting*)calloc(1, (*size + 1) * sizeof(struct config_array_setting)); /* Arrays */ SETTING_ARRAY("playlist_names", settings->arrays.playlist_names, false, NULL, true); @@ -1112,7 +1112,7 @@ static struct config_path_setting *populate_settings_path(settings_t *settings, { unsigned count = 0; global_t *global = global_get_ptr(); - struct config_path_setting *tmp = (struct config_path_setting*)malloc((*size + 1) * sizeof(struct config_path_setting)); + struct config_path_setting *tmp = (struct config_path_setting*)calloc(1, (*size + 1) * sizeof(struct config_path_setting)); /* Paths */ #ifdef HAVE_XMB @@ -1308,7 +1308,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("video_vsync", &settings->bools.video_vsync, true, vsync, false); SETTING_BOOL("video_hard_sync", &settings->bools.video_hard_sync, true, hard_sync, false); SETTING_BOOL("video_black_frame_insertion", &settings->bools.video_black_frame_insertion, true, black_frame_insertion, false); - SETTING_BOOL("crt_switch_resolution", &settings->bools.crt_switch_resolution, true, crt_switch_resolution, false); + SETTING_BOOL("crt_switch_resolution", &settings->bools.crt_switch_resolution, true, crt_switch_resolution, false); SETTING_BOOL("video_disable_composition", &settings->bools.video_disable_composition, true, disable_composition, false); SETTING_BOOL("pause_nonactive", &settings->bools.pause_nonactive, true, pause_nonactive, false); SETTING_BOOL("video_gpu_screenshot", &settings->bools.video_gpu_screenshot, true, gpu_screenshot, false); @@ -1480,7 +1480,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, static struct config_float_setting *populate_settings_float(settings_t *settings, int *size) { unsigned count = 0; - struct config_float_setting *tmp = (struct config_float_setting*)malloc((*size + 1) * sizeof(struct config_float_setting)); + struct config_float_setting *tmp = (struct config_float_setting*)calloc(1, (*size + 1) * sizeof(struct config_float_setting)); SETTING_FLOAT("video_aspect_ratio", &settings->floats.video_aspect_ratio, true, aspect_ratio, false); SETTING_FLOAT("video_scale", &settings->floats.video_scale, false, 0.0f, false); @@ -3027,6 +3027,8 @@ end: free(array_settings); if (path_settings) free(path_settings); + if (size_settings) + free(size_settings); free(tmp_str); return ret; } @@ -4431,7 +4433,7 @@ bool config_save_overrides(int override_type) for (i = 0; i < (unsigned)path_settings_size; i++) { - /* blacklist video_shader, better handled by shader presets*/ + /* blacklist video_shader, better handled by shader presets*/ /* to-do: add setting to control blacklisting */ if (string_is_equal(path_settings[i].ident, "video_shader")) continue; @@ -4536,6 +4538,8 @@ bool config_save_overrides(int override_type) free(path_settings); if (path_overrides) free(path_overrides); + if (size_overrides) + free(size_overrides); free(settings); free(config_directory); free(override_directory); diff --git a/core_info.c b/core_info.c index 18bcfeffec..18c8caf448 100644 --- a/core_info.c +++ b/core_info.c @@ -149,6 +149,7 @@ static void core_info_list_free(core_info_list_t *core_info_list) free(info->path); free(info->core_name); free(info->systemname); + free(info->system_id); free(info->system_manufacturer); free(info->display_name); free(info->display_version); @@ -302,6 +303,14 @@ static core_info_list_t *core_info_list_new(const char *path, tmp = NULL; } + if (config_get_string(conf, "systemid", &tmp) + && !string_is_empty(tmp)) + { + core_info[i].system_id = strdup(tmp); + free(tmp); + tmp = NULL; + } + if (config_get_string(conf, "manufacturer", &tmp) && !string_is_empty(tmp)) { @@ -679,6 +688,9 @@ bool core_info_load(core_info_ctx_find_t *info) if (!info) return false; + if (!core_info_current) + core_info_init_current_core(); + core_info_get_current_core(&core_info); if (!core_info_curr_list) diff --git a/core_info.h b/core_info.h index f87805e605..1390dac56d 100644 --- a/core_info.h +++ b/core_info.h @@ -47,6 +47,7 @@ typedef struct char *core_name; char *system_manufacturer; char *systemname; + char *system_id; char *supported_extensions; char *authors; char *permissions; diff --git a/database_info.c b/database_info.c index 894ae250ac..96da1c48a9 100644 --- a/database_info.c +++ b/database_info.c @@ -478,6 +478,36 @@ database_info_list_t *database_info_list_new( if (!new_ptr) { + if (db_info.bbfc_rating) + free(db_info.bbfc_rating); + if (db_info.cero_rating) + free(db_info.cero_rating); + if (db_info.description) + free(db_info.description); + if (db_info.edge_magazine_review) + free(db_info.edge_magazine_review); + if (db_info.elspa_rating) + free(db_info.elspa_rating); + if (db_info.enhancement_hw) + free(db_info.enhancement_hw); + if (db_info.esrb_rating) + free(db_info.esrb_rating); + if (db_info.franchise) + free(db_info.franchise); + if (db_info.genre) + free(db_info.genre); + if (db_info.name) + free(db_info.name); + if (db_info.origin) + free(db_info.origin); + if (db_info.pegi_rating) + free(db_info.pegi_rating); + if (db_info.publisher) + free(db_info.publisher); + if (db_info.rom_name) + free(db_info.rom_name); + if (db_info.serial) + free(db_info.serial); database_info_list_free(database_info_list); free(database_info); free(database_info_list); diff --git a/deps/libui/LICENSE b/deps/libui/LICENSE deleted file mode 100644 index 2351d66d93..0000000000 --- a/deps/libui/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -Copyright (c) 2014 Pietro Gagliardi - -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. - -(this is called the MIT License or Expat License; see http://www.opensource.org/licenses/MIT) diff --git a/deps/libui/common/CMakeLists.txt b/deps/libui/common/CMakeLists.txt deleted file mode 100644 index 91d794936f..0000000000 --- a/deps/libui/common/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# 3 june 2016 - -list(APPEND _LIBUI_SOURCES - common/areaevents.c - common/control.c - common/debug.c - common/matrix.c - common/shouldquit.c - common/userbugs.c -) -set(_LIBUI_SOURCES ${_LIBUI_SOURCES} PARENT_SCOPE) - -list(APPEND _LIBUI_INCLUDEDIRS - common -) -set(_LIBUI_INCLUDEDIRS ${_LIBUI_INCLUDEDIRS} PARENT_SCOPE) diff --git a/deps/libui/common/areaevents.c b/deps/libui/common/areaevents.c deleted file mode 100644 index cf3c288c4f..0000000000 --- a/deps/libui/common/areaevents.c +++ /dev/null @@ -1,167 +0,0 @@ -// 29 march 2014 -#include "../ui.h" -#include "uipriv.h" - -/* -Windows and GTK+ have a limit of 2 and 3 clicks, respectively, natively supported. Fortunately, we can simulate the double/triple-click behavior to build higher-order clicks. We can use the same algorithm Windows uses on both: - http://blogs.msdn.com/b/oldnewthing/archive/2004/10/18/243925.aspx -For GTK+, we pull the double-click time and double-click distance, which work the same as the equivalents on Windows (so the distance is in all directions), from the GtkSettings system. - -On GTK+ this will also allow us to discard the GDK_BUTTON_2PRESS and GDK_BUTTON_3PRESS events, so the button press stream will be just like on other platforms. - -Thanks to mclasen, garnacho_, halfline, and tristan in irc.gimp.net/#gtk+. -*/ - -// x, y, xdist, ydist, and c.rect must have the same units -// so must time, maxTime, and c.prevTime -int clickCounterClick(clickCounter *c, int button, int x, int y, uintptr_t time, uintptr_t maxTime, int32_t xdist, int32_t ydist) -{ - // different button than before? if so, don't count - if (button != c->curButton) - c->count = 0; - - // (x, y) in the allowed region for a double-click? if not, don't count - if (x < c->rectX0) - c->count = 0; - if (y < c->rectY0) - c->count = 0; - if (x >= c->rectX1) - c->count = 0; - if (y >= c->rectY1) - c->count = 0; - - // too slow? if so, don't count - // note the below expression; time > (c.prevTime + maxTime) can overflow! - if ((time - c->prevTime) > maxTime) // too slow; don't count - c->count = 0; - - c->count++; // if either of the above ifs happened, this will make the click count 1; otherwise it will make the click count 2, 3, 4, 5, ... - - // now we need to update the internal structures for the next test - c->curButton = button; - c->prevTime = time; - c->rectX0 = x - xdist; - c->rectY0 = y - ydist; - c->rectX1 = x + xdist; - c->rectY1 = y + ydist; - - return c->count; -} - -void clickCounterReset(clickCounter *c) -{ - c->curButton = 0; - c->rectX0 = 0; - c->rectY0 = 0; - c->rectX1 = 0; - c->rectY1 = 0; - c->prevTime = 0; - c->count = 0; -} - -/* -For position independence across international keyboard layouts, typewriter keys are read using scancodes (which are always set 1). -Windows provides the scancodes directly in the LPARAM. -GTK+ provides the scancodes directly from the underlying window system via GdkEventKey.hardware_keycode. -On X11, this is scancode + 8 (because X11 keyboard codes have a range of [8,255]). -Wayland is guaranteed to give the same result (thanks ebassi in irc.gimp.net/#gtk+). -On Linux, where evdev is used instead of polling scancodes directly from the keyboard, evdev's typewriter section key code constants are the same as scancodes anyway, so the rules above apply. -Typewriter section scancodes are the same across international keyboards with some exceptions that have been accounted for (see KeyEvent's documentation); see http://www.quadibloc.com/comp/scan.htm for details. -Non-typewriter keys can be handled safely using constants provided by the respective backend API. - -Because GTK+ keysyms may or may not obey Num Lock, we also handle the 0-9 and . keys on the numeric keypad with scancodes (they match too). -*/ - -// use uintptr_t to be safe; the size of the scancode/hardware key code field on each platform is different -static const struct { - uintptr_t scancode; - char equiv; -} scancodeKeys[] = { - { 0x02, '1' }, - { 0x03, '2' }, - { 0x04, '3' }, - { 0x05, '4' }, - { 0x06, '5' }, - { 0x07, '6' }, - { 0x08, '7' }, - { 0x09, '8' }, - { 0x0A, '9' }, - { 0x0B, '0' }, - { 0x0C, '-' }, - { 0x0D, '=' }, - { 0x0E, '\b' }, - { 0x0F, '\t' }, - { 0x10, 'q' }, - { 0x11, 'w' }, - { 0x12, 'e' }, - { 0x13, 'r' }, - { 0x14, 't' }, - { 0x15, 'y' }, - { 0x16, 'u' }, - { 0x17, 'i' }, - { 0x18, 'o' }, - { 0x19, 'p' }, - { 0x1A, '[' }, - { 0x1B, ']' }, - { 0x1C, '\n' }, - { 0x1E, 'a' }, - { 0x1F, 's' }, - { 0x20, 'd' }, - { 0x21, 'f' }, - { 0x22, 'g' }, - { 0x23, 'h' }, - { 0x24, 'j' }, - { 0x25, 'k' }, - { 0x26, 'l' }, - { 0x27, ';' }, - { 0x28, '\'' }, - { 0x29, '`' }, - { 0x2B, '\\' }, - { 0x2C, 'z' }, - { 0x2D, 'x' }, - { 0x2E, 'c' }, - { 0x2F, 'v' }, - { 0x30, 'b' }, - { 0x31, 'n' }, - { 0x32, 'm' }, - { 0x33, ',' }, - { 0x34, '.' }, - { 0x35, '/' }, - { 0x39, ' ' }, - { 0xFFFF, 0 }, -}; - -static const struct { - uintptr_t scancode; - uiExtKey equiv; -} scancodeExtKeys[] = { - { 0x47, uiExtKeyN7 }, - { 0x48, uiExtKeyN8 }, - { 0x49, uiExtKeyN9 }, - { 0x4B, uiExtKeyN4 }, - { 0x4C, uiExtKeyN5 }, - { 0x4D, uiExtKeyN6 }, - { 0x4F, uiExtKeyN1 }, - { 0x50, uiExtKeyN2 }, - { 0x51, uiExtKeyN3 }, - { 0x52, uiExtKeyN0 }, - { 0x53, uiExtKeyNDot }, - { 0xFFFF, 0 }, -}; - -int fromScancode(uintptr_t scancode, uiAreaKeyEvent *ke) -{ - int i; - - for (i = 0; scancodeKeys[i].scancode != 0xFFFF; i++) - if (scancodeKeys[i].scancode == scancode) { - ke->Key = scancodeKeys[i].equiv; - return 1; - } - for (i = 0; scancodeExtKeys[i].scancode != 0xFFFF; i++) - if (scancodeExtKeys[i].scancode == scancode) { - ke->ExtKey = scancodeExtKeys[i].equiv; - return 1; - } - return 0; -} diff --git a/deps/libui/common/control.c b/deps/libui/common/control.c deleted file mode 100644 index 2806646168..0000000000 --- a/deps/libui/common/control.c +++ /dev/null @@ -1,101 +0,0 @@ -// 26 may 2015 -#include "../ui.h" -#include "uipriv.h" - -void uiControlDestroy(uiControl *c) -{ - (*(c->Destroy))(c); -} - -uintptr_t uiControlHandle(uiControl *c) -{ - return (*(c->Handle))(c); -} - -uiControl *uiControlParent(uiControl *c) -{ - return (*(c->Parent))(c); -} - -void uiControlSetParent(uiControl *c, uiControl *parent) -{ - (*(c->SetParent))(c, parent); -} - -int uiControlToplevel(uiControl *c) -{ - return (*(c->Toplevel))(c); -} - -int uiControlVisible(uiControl *c) -{ - return (*(c->Visible))(c); -} - -void uiControlShow(uiControl *c) -{ - (*(c->Show))(c); -} - -void uiControlHide(uiControl *c) -{ - (*(c->Hide))(c); -} - -int uiControlEnabled(uiControl *c) -{ - return (*(c->Enabled))(c); -} - -void uiControlEnable(uiControl *c) -{ - (*(c->Enable))(c); -} - -void uiControlDisable(uiControl *c) -{ - (*(c->Disable))(c); -} - -#define uiControlSignature 0x7569436F - -uiControl *uiAllocControl(size_t size, uint32_t OSsig, uint32_t typesig, const char *typenamestr) -{ - uiControl *c; - - c = (uiControl *) uiAlloc(size, typenamestr); - c->Signature = uiControlSignature; - c->OSSignature = OSsig; - c->TypeSignature = typesig; - return c; -} - -void uiFreeControl(uiControl *c) -{ - if (uiControlParent(c) != NULL) - userbug("You cannot destroy a uiControl while it still has a parent. (control: %p)", c); - uiFree(c); -} - -void uiControlVerifySetParent(uiControl *c, uiControl *parent) -{ - uiControl *curParent; - - if (uiControlToplevel(c)) - userbug("You cannot give a toplevel uiControl a parent. (control: %p)", c); - curParent = uiControlParent(c); - if (parent != NULL && curParent != NULL) - userbug("You cannot give a uiControl a parent while it already has one. (control: %p; current parent: %p; new parent: %p)", c, curParent, parent); - if (parent == NULL && curParent == NULL) - implbug("attempt to double unparent uiControl %p", c); -} - -int uiControlEnabledToUser(uiControl *c) -{ - while (c != NULL) { - if (!uiControlEnabled(c)) - return 0; - c = uiControlParent(c); - } - return 1; -} diff --git a/deps/libui/common/controlsigs.h b/deps/libui/common/controlsigs.h deleted file mode 100644 index 1cbf18d5da..0000000000 --- a/deps/libui/common/controlsigs.h +++ /dev/null @@ -1,25 +0,0 @@ -// 24 april 2016 - -#define uiAreaSignature 0x41726561 -#define uiBoxSignature 0x426F784C -#define uiButtonSignature 0x42746F6E -#define uiCheckboxSignature 0x43686B62 -#define uiColorButtonSignature 0x436F6C42 -#define uiComboboxSignature 0x436F6D62 -#define uiDateTimePickerSignature 0x44545069 -#define uiEditableComboboxSignature 0x45644362 -#define uiEntrySignature 0x456E7472 -#define uiFontButtonSignature 0x466F6E42 -#define uiFormSignature 0x466F726D -#define uiGridSignature 0x47726964 -#define uiGroupSignature 0x47727062 -#define uiLabelSignature 0x4C61626C -#define uiMultilineEntrySignature 0x4D6C6E45 -#define uiProgressBarSignature 0x50426172 -#define uiRadioButtonsSignature 0x5264696F -#define uiSeparatorSignature 0x53657061 -#define uiSliderSignature 0x536C6964 -#define uiSpinboxSignature 0x5370696E -#define uiTabSignature 0x54616273 -#define uiTableSignature 0x5461626C -#define uiWindowSignature 0x57696E64 diff --git a/deps/libui/common/debug.c b/deps/libui/common/debug.c deleted file mode 100644 index 97280b47ba..0000000000 --- a/deps/libui/common/debug.c +++ /dev/null @@ -1,21 +0,0 @@ -// 13 may 2016 -#include "../ui.h" -#include "uipriv.h" - -void _implbug(const char *file, const char *line, const char *func, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - realbug(file, line, func, "POSSIBLE IMPLEMENTATION BUG; CONTACT ANDLABS:\n", format, ap); - va_end(ap); -} - -void _userbug(const char *file, const char *line, const char *func, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - realbug(file, line, func, "You have a bug: ", format, ap); - va_end(ap); -} diff --git a/deps/libui/common/matrix.c b/deps/libui/common/matrix.c deleted file mode 100644 index 676885d1bf..0000000000 --- a/deps/libui/common/matrix.c +++ /dev/null @@ -1,50 +0,0 @@ -// 11 october 2015 -#include -#include "../ui.h" -#include "uipriv.h" - -void uiDrawMatrixSetIdentity(uiDrawMatrix *m) -{ - m->M11 = 1; - m->M12 = 0; - m->M21 = 0; - m->M22 = 1; - m->M31 = 0; - m->M32 = 0; -} - -// The rest of this file provides basic utilities in case the platform doesn't provide any of its own for these tasks. -// Keep these as minimal as possible. They should generally not call other fallbacks. - -// see https://msdn.microsoft.com/en-us/library/windows/desktop/ff684171%28v=vs.85%29.aspx#skew_transform -// TODO see if there's a way we can avoid the multiplication -void fallbackSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount) -{ - uiDrawMatrix n; - - uiDrawMatrixSetIdentity(&n); - // TODO explain this - n.M12 = tan(yamount); - n.M21 = tan(xamount); - n.M31 = -y * tan(xamount); - n.M32 = -x * tan(yamount); - uiDrawMatrixMultiply(m, &n); -} - -void scaleCenter(double xCenter, double yCenter, double *x, double *y) -{ - *x = xCenter - (*x * xCenter); - *y = yCenter - (*y * yCenter); -} - -// the basic algorithm is from cairo -// but it's the same algorithm as the transform point, just without M31 and M32 taken into account, so let's just do that instead -void fallbackTransformSize(uiDrawMatrix *m, double *x, double *y) -{ - uiDrawMatrix m2; - - m2 = *m; - m2.M31 = 0; - m2.M32 = 0; - uiDrawMatrixTransformPoint(&m2, x, y); -} diff --git a/deps/libui/common/shouldquit.c b/deps/libui/common/shouldquit.c deleted file mode 100644 index 4e7aa5c322..0000000000 --- a/deps/libui/common/shouldquit.c +++ /dev/null @@ -1,22 +0,0 @@ -// 9 may 2015 -#include "../ui.h" -#include "uipriv.h" - -static int defaultOnShouldQuit(void *data) -{ - return 0; -} - -static int (*onShouldQuit)(void *) = defaultOnShouldQuit; -static void *onShouldQuitData; - -void uiOnShouldQuit(int (*f)(void *), void *data) -{ - onShouldQuit = f; - onShouldQuitData = data; -} - -int shouldQuit(void) -{ - return (*onShouldQuit)(onShouldQuitData); -} diff --git a/deps/libui/common/uipriv.h b/deps/libui/common/uipriv.h deleted file mode 100644 index d6b54e89ad..0000000000 --- a/deps/libui/common/uipriv.h +++ /dev/null @@ -1,58 +0,0 @@ -// 6 april 2015 -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "controlsigs.h" - -extern uiInitOptions options; - -extern void *uiAlloc(size_t, const char *); -#define uiNew(T) ((T *) uiAlloc(sizeof (T), #T)) -extern void *uiRealloc(void *, size_t, const char *); -extern void uiFree(void *); - -// ugh, this was only introduced in MSVC 2015... -#ifdef _MSC_VER -#define __func__ __FUNCTION__ -#endif -extern void realbug(const char *file, const char *line, const char *func, const char *prefix, const char *format, va_list ap); -#define _ns2(s) #s -#define _ns(s) _ns2(s) -extern void _implbug(const char *file, const char *line, const char *func, const char *format, ...); -#define implbug(...) _implbug(__FILE__, _ns(__LINE__), __func__, __VA_ARGS__) -extern void _userbug(const char *file, const char *line, const char *func, const char *format, ...); -#define userbug(...) _userbug(__FILE__, _ns(__LINE__), __func__, __VA_ARGS__) - -// control.c -extern uiControl *newControl(size_t size, uint32_t OSsig, uint32_t typesig, const char *typenamestr); - -// shouldquit.c -extern int shouldQuit(void); - -// areaevents.c -typedef struct clickCounter clickCounter; -// you should call Reset() to zero-initialize a new instance -// it doesn't matter that all the non-count fields are zero: the first click will fail the curButton test straightaway, so it'll return 1 and set the rest of the structure accordingly -struct clickCounter { - int curButton; - int rectX0; - int rectY0; - int rectX1; - int rectY1; - uintptr_t prevTime; - int count; -}; -int clickCounterClick(clickCounter *c, int button, int x, int y, uintptr_t time, uintptr_t maxTime, int32_t xdist, int32_t ydist); -extern void clickCounterReset(clickCounter *); -extern int fromScancode(uintptr_t, uiAreaKeyEvent *); - -// matrix.c -extern void fallbackSkew(uiDrawMatrix *, double, double, double, double); -extern void scaleCenter(double, double, double *, double *); -extern void fallbackTransformSize(uiDrawMatrix *, double *, double *); - -#ifdef __cplusplus -} -#endif diff --git a/deps/libui/common/userbugs.c b/deps/libui/common/userbugs.c deleted file mode 100644 index 0a85874c91..0000000000 --- a/deps/libui/common/userbugs.c +++ /dev/null @@ -1,8 +0,0 @@ -// 22 may 2016 -#include "../ui.h" -#include "uipriv.h" - -void uiUserBugCannotSetParentOnToplevel(const char *type) -{ - userbug("You cannot make a %s a child of another uiControl,", type); -} diff --git a/deps/libui/darwin/CMakeLists.txt b/deps/libui/darwin/CMakeLists.txt deleted file mode 100644 index dbef5d432c..0000000000 --- a/deps/libui/darwin/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ -# 3 june 2016 - -list(APPEND _LIBUI_SOURCES - darwin/alloc.m - darwin/area.m - darwin/areaevents.m - darwin/autolayout.m - darwin/box.m - darwin/button.m - darwin/checkbox.m - darwin/colorbutton.m - darwin/combobox.m - darwin/control.m - darwin/datetimepicker.m - darwin/debug.m - darwin/draw.m - darwin/drawtext.m - darwin/editablecombo.m - darwin/entry.m - darwin/fontbutton.m - darwin/form.m - darwin/grid.m - darwin/group.m - darwin/image.m - darwin/label.m - darwin/main.m - darwin/map.m - darwin/menu.m - darwin/multilineentry.m - darwin/progressbar.m - darwin/radiobuttons.m - darwin/scrollview.m - darwin/separator.m - darwin/slider.m - darwin/spinbox.m - darwin/stddialogs.m - darwin/tab.m - darwin/text.m - darwin/util.m - darwin/window.m - darwin/winmoveresize.m -) -set(_LIBUI_SOURCES ${_LIBUI_SOURCES} PARENT_SCOPE) - -list(APPEND _LIBUI_INCLUDEDIRS - darwin -) -set(_LIBUI_INCLUDEDIRS _LIBUI_INCLUDEDIRS PARENT_SCOPE) - -set(_LIBUINAME libui PARENT_SCOPE) -if(NOT BUILD_SHARED_LIBS) - set(_LIBUINAME libui-temporary PARENT_SCOPE) -endif() -# thanks to Mr-Hide in irc.freenode.net/#cmake -macro(_handle_static) - set_target_properties(${_LIBUINAME} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") - set(_aname $) - set(_lname libui-combined.list) - set(_oname libui-combined.o) - add_custom_command( - OUTPUT ${_oname} - COMMAND - nm -m ${_aname} | sed -E -n "'s/^[0-9a-f]* \\([A-Z_]+,[a-z_]+\\) external //p'" > ${_lname} - COMMAND - ld -exported_symbols_list ${_lname} -r -all_load ${_aname} -o ${_oname} - COMMENT "Removing hidden symbols") - add_library(libui STATIC ${_oname}) - # otherwise cmake won't know which linker to use - set_target_properties(libui PROPERTIES - LINKER_LANGUAGE C) - set(_aname) - set(_lname) - set(_oname) -endmacro() - -set(_LIBUI_LIBS - objc "-framework Foundation" "-framework AppKit" -PARENT_SCOPE) diff --git a/deps/libui/darwin/alloc.m b/deps/libui/darwin/alloc.m deleted file mode 100644 index e271b90ec1..0000000000 --- a/deps/libui/darwin/alloc.m +++ /dev/null @@ -1,89 +0,0 @@ -// 4 december 2014 -#import -#import "uipriv_darwin.h" - -static NSMutableArray *allocations; -NSMutableArray *delegates; - -void initAlloc(void) -{ - allocations = [NSMutableArray new]; - delegates = [NSMutableArray new]; -} - -#define UINT8(p) ((uint8_t *) (p)) -#define PVOID(p) ((void *) (p)) -#define EXTRA (sizeof (size_t) + sizeof (const char **)) -#define DATA(p) PVOID(UINT8(p) + EXTRA) -#define BASE(p) PVOID(UINT8(p) - EXTRA) -#define SIZE(p) ((size_t *) (p)) -#define CCHAR(p) ((const char **) (p)) -#define TYPE(p) CCHAR(UINT8(p) + sizeof (size_t)) - -void uninitAlloc(void) -{ - NSMutableString *str; - NSValue *v; - - [delegates release]; - if ([allocations count] == 0) { - [allocations release]; - return; - } - str = [NSMutableString new]; - for (v in allocations) { - void *ptr; - - ptr = [v pointerValue]; - [str appendString:[NSString stringWithFormat:@"%p %s\n", ptr, *TYPE(ptr)]]; - } - userbug("Some data was leaked; either you left a uiControl lying around or there's a bug in libui itself. Leaked data:\n%s", [str UTF8String]); - [str release]; -} - -void *uiAlloc(size_t size, const char *type) -{ - void *out; - - out = malloc(EXTRA + size); - if (out == NULL) { - fprintf(stderr, "memory exhausted in uiAlloc()\n"); - abort(); - } - memset(DATA(out), 0, size); - *SIZE(out) = size; - *TYPE(out) = type; - [allocations addObject:[NSValue valueWithPointer:out]]; - return DATA(out); -} - -void *uiRealloc(void *p, size_t new, const char *type) -{ - void *out; - size_t *s; - - if (p == NULL) - return uiAlloc(new, type); - p = BASE(p); - out = realloc(p, EXTRA + new); - if (out == NULL) { - fprintf(stderr, "memory exhausted in uiRealloc()\n"); - abort(); - } - s = SIZE(out); - if (new <= *s) - memset(((uint8_t *) DATA(out)) + *s, 0, new - *s); - *s = new; - [allocations removeObject:[NSValue valueWithPointer:p]]; - [allocations addObject:[NSValue valueWithPointer:out]]; - return DATA(out); -} - -void uiFree(void *p) -{ - if (p == NULL) - implbug("attempt to uiFree(NULL)"); - p = BASE(p); - free(p); - [allocations removeObject:[NSValue valueWithPointer:p]]; -} diff --git a/deps/libui/darwin/area.m b/deps/libui/darwin/area.m deleted file mode 100644 index 23162e6cff..0000000000 --- a/deps/libui/darwin/area.m +++ /dev/null @@ -1,475 +0,0 @@ -// 9 september 2015 -#import "uipriv_darwin.h" - -// 10.8 fixups -#define NSEventModifierFlags NSUInteger - -@interface areaView : NSView { - uiArea *libui_a; - NSTrackingArea *libui_ta; - NSSize libui_ss; - BOOL libui_enabled; -} -- (id)initWithFrame:(NSRect)r area:(uiArea *)a; -- (uiModifiers)parseModifiers:(NSEvent *)e; -- (void)doMouseEvent:(NSEvent *)e; -- (int)sendKeyEvent:(uiAreaKeyEvent *)ke; -- (int)doKeyDownUp:(NSEvent *)e up:(int)up; -- (int)doKeyDown:(NSEvent *)e; -- (int)doKeyUp:(NSEvent *)e; -- (int)doFlagsChanged:(NSEvent *)e; -- (void)setupNewTrackingArea; -- (void)setScrollingSize:(NSSize)s; -- (BOOL)isEnabled; -- (void)setEnabled:(BOOL)e; -@end - -struct uiArea { - uiDarwinControl c; - NSView *view; // either sv or area depending on whether it is scrolling - NSScrollView *sv; - areaView *area; - struct scrollViewData *d; - uiAreaHandler *ah; - BOOL scrolling; - NSEvent *dragevent; -}; - -@implementation areaView - -- (id)initWithFrame:(NSRect)r area:(uiArea *)a -{ - self = [super initWithFrame:r]; - if (self) { - self->libui_a = a; - [self setupNewTrackingArea]; - self->libui_ss = r.size; - self->libui_enabled = YES; - } - return self; -} - -- (void)drawRect:(NSRect)r -{ - uiArea *a = self->libui_a; - CGContextRef c; - uiAreaDrawParams dp; - - c = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; - // see draw.m under text for why we need the height - dp.Context = newContext(c, [self bounds].size.height); - - dp.AreaWidth = 0; - dp.AreaHeight = 0; - if (!a->scrolling) { - dp.AreaWidth = [self frame].size.width; - dp.AreaHeight = [self frame].size.height; - } - - dp.ClipX = r.origin.x; - dp.ClipY = r.origin.y; - dp.ClipWidth = r.size.width; - dp.ClipHeight = r.size.height; - - // no need to save or restore the graphics state to reset transformations; Cocoa creates a brand-new context each time - (*(a->ah->Draw))(a->ah, a, &dp); - - freeContext(dp.Context); -} - -- (BOOL)isFlipped -{ - return YES; -} - -- (BOOL)acceptsFirstResponder -{ - return YES; -} - -- (uiModifiers)parseModifiers:(NSEvent *)e -{ - NSEventModifierFlags mods; - uiModifiers m; - - m = 0; - mods = [e modifierFlags]; - if ((mods & NSControlKeyMask) != 0) - m |= uiModifierCtrl; - if ((mods & NSAlternateKeyMask) != 0) - m |= uiModifierAlt; - if ((mods & NSShiftKeyMask) != 0) - m |= uiModifierShift; - if ((mods & NSCommandKeyMask) != 0) - m |= uiModifierSuper; - return m; -} - -- (void)setupNewTrackingArea -{ - self->libui_ta = [[NSTrackingArea alloc] initWithRect:[self bounds] - options:(NSTrackingMouseEnteredAndExited | - NSTrackingMouseMoved | - NSTrackingActiveAlways | - NSTrackingInVisibleRect | - NSTrackingEnabledDuringMouseDrag) - owner:self - userInfo:nil]; - [self addTrackingArea:self->libui_ta]; -} - -- (void)updateTrackingAreas -{ - [self removeTrackingArea:self->libui_ta]; - [self->libui_ta release]; - [self setupNewTrackingArea]; -} - -// capture on drag is done automatically on OS X -- (void)doMouseEvent:(NSEvent *)e -{ - uiArea *a = self->libui_a; - uiAreaMouseEvent me; - NSPoint point; - int buttonNumber; - NSUInteger pmb; - unsigned int i, max; - - // this will convert point to drawing space - // thanks swillits in irc.freenode.net/#macdev - point = [self convertPoint:[e locationInWindow] fromView:nil]; - me.X = point.x; - me.Y = point.y; - - me.AreaWidth = 0; - me.AreaHeight = 0; - if (!a->scrolling) { - me.AreaWidth = [self frame].size.width; - me.AreaHeight = [self frame].size.height; - } - - buttonNumber = [e buttonNumber] + 1; - // swap button numbers 2 and 3 (right and middle) - if (buttonNumber == 2) - buttonNumber = 3; - else if (buttonNumber == 3) - buttonNumber = 2; - - me.Down = 0; - me.Up = 0; - me.Count = 0; - switch ([e type]) { - case NSLeftMouseDown: - case NSRightMouseDown: - case NSOtherMouseDown: - me.Down = buttonNumber; - me.Count = [e clickCount]; - break; - case NSLeftMouseUp: - case NSRightMouseUp: - case NSOtherMouseUp: - me.Up = buttonNumber; - break; - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: - // we include the button that triggered the dragged event in the Held fields - buttonNumber = 0; - break; - } - - me.Modifiers = [self parseModifiers:e]; - - pmb = [NSEvent pressedMouseButtons]; - me.Held1To64 = 0; - if (buttonNumber != 1 && (pmb & 1) != 0) - me.Held1To64 |= 1; - if (buttonNumber != 2 && (pmb & 4) != 0) - me.Held1To64 |= 2; - if (buttonNumber != 3 && (pmb & 2) != 0) - me.Held1To64 |= 4; - // buttons 4..32 - // https://developer.apple.com/library/mac/documentation/Carbon/Reference/QuartzEventServicesRef/index.html#//apple_ref/c/tdef/CGMouseButton says Quartz only supports up to 32 buttons - max = 32; - for (i = 4; i <= max; i++) { - uint64_t j; - - if (buttonNumber == i) - continue; - j = 1 << (i - 1); - if ((pmb & j) != 0) - me.Held1To64 |= j; - } - - if (self->libui_enabled) { - // and allow dragging here - a->dragevent = e; - (*(a->ah->MouseEvent))(a->ah, a, &me); - a->dragevent = nil; - } -} - -#define mouseEvent(name) \ - - (void)name:(NSEvent *)e \ - { \ - [self doMouseEvent:e]; \ - } -mouseEvent(mouseMoved) -mouseEvent(mouseDragged) -mouseEvent(rightMouseDragged) -mouseEvent(otherMouseDragged) -mouseEvent(mouseDown) -mouseEvent(rightMouseDown) -mouseEvent(otherMouseDown) -mouseEvent(mouseUp) -mouseEvent(rightMouseUp) -mouseEvent(otherMouseUp) - -- (void)mouseEntered:(NSEvent *)e -{ - uiArea *a = self->libui_a; - - if (self->libui_enabled) - (*(a->ah->MouseCrossed))(a->ah, a, 0); -} - -- (void)mouseExited:(NSEvent *)e -{ - uiArea *a = self->libui_a; - - if (self->libui_enabled) - (*(a->ah->MouseCrossed))(a->ah, a, 1); -} - -// note: there is no equivalent to WM_CAPTURECHANGED on Mac OS X; there literally is no way to break a grab like that -// even if I invoke the task switcher and switch processes, the mouse grab will still be held until I let go of all buttons -// therefore, no DragBroken() - -- (int)sendKeyEvent:(uiAreaKeyEvent *)ke -{ - uiArea *a = self->libui_a; - - return (*(a->ah->KeyEvent))(a->ah, a, ke); -} - -- (int)doKeyDownUp:(NSEvent *)e up:(int)up -{ - uiAreaKeyEvent ke; - - ke.Key = 0; - ke.ExtKey = 0; - ke.Modifier = 0; - - ke.Modifiers = [self parseModifiers:e]; - - ke.Up = up; - - if (!fromKeycode([e keyCode], &ke)) - return 0; - return [self sendKeyEvent:&ke]; -} - -- (int)doKeyDown:(NSEvent *)e -{ - return [self doKeyDownUp:e up:0]; -} - -- (int)doKeyUp:(NSEvent *)e -{ - return [self doKeyDownUp:e up:1]; -} - -- (int)doFlagsChanged:(NSEvent *)e -{ - uiAreaKeyEvent ke; - uiModifiers whichmod; - - ke.Key = 0; - ke.ExtKey = 0; - - // Mac OS X sends this event on both key up and key down. - // Fortunately -[e keyCode] IS valid here, so we can simply map from key code to Modifiers, get the value of [e modifierFlags], and check if the respective bit is set or not — that will give us the up/down state - if (!keycodeModifier([e keyCode], &whichmod)) - return 0; - ke.Modifier = whichmod; - ke.Modifiers = [self parseModifiers:e]; - ke.Up = (ke.Modifiers & ke.Modifier) == 0; - // and then drop the current modifier from Modifiers - ke.Modifiers &= ~ke.Modifier; - return [self sendKeyEvent:&ke]; -} - -- (void)setFrameSize:(NSSize)size -{ - uiArea *a = self->libui_a; - - [super setFrameSize:size]; - if (!a->scrolling) - // we must redraw everything on resize because Windows requires it - [self setNeedsDisplay:YES]; -} - -// TODO does this update the frame? -- (void)setScrollingSize:(NSSize)s -{ - self->libui_ss = s; - [self invalidateIntrinsicContentSize]; -} - -- (NSSize)intrinsicContentSize -{ - if (!self->libui_a->scrolling) - return [super intrinsicContentSize]; - return self->libui_ss; -} - -- (BOOL)becomeFirstResponder -{ - return [self isEnabled]; -} - -- (BOOL)isEnabled -{ - return self->libui_enabled; -} - -- (void)setEnabled:(BOOL)e -{ - self->libui_enabled = e; - if (!self->libui_enabled && [self window] != nil) - if ([[self window] firstResponder] == self) - [[self window] makeFirstResponder:nil]; -} - -@end - -uiDarwinControlAllDefaultsExceptDestroy(uiArea, view) - -static void uiAreaDestroy(uiControl *c) -{ - uiArea *a = uiArea(c); - - if (a->scrolling) - scrollViewFreeData(a->sv, a->d); - [a->area release]; - if (a->scrolling) - [a->sv release]; - uiFreeControl(uiControl(a)); -} - -// called by subclasses of -[NSApplication sendEvent:] -// by default, NSApplication eats some key events -// this prevents that from happening with uiArea -// see http://stackoverflow.com/questions/24099063/how-do-i-detect-keyup-in-my-nsview-with-the-command-key-held and http://lists.apple.com/archives/cocoa-dev/2003/Oct/msg00442.html -int sendAreaEvents(NSEvent *e) -{ - NSEventType type; - id focused; - areaView *view; - - type = [e type]; - if (type != NSKeyDown && type != NSKeyUp && type != NSFlagsChanged) - return 0; - focused = [[e window] firstResponder]; - if (focused == nil) - return 0; - if (![focused isKindOfClass:[areaView class]]) - return 0; - view = (areaView *) focused; - switch (type) { - case NSKeyDown: - return [view doKeyDown:e]; - case NSKeyUp: - return [view doKeyUp:e]; - case NSFlagsChanged: - return [view doFlagsChanged:e]; - } - return 0; -} - -void uiAreaSetSize(uiArea *a, int width, int height) -{ - if (!a->scrolling) - userbug("You cannot call uiAreaSetSize() on a non-scrolling uiArea. (area: %p)", a); - [a->area setScrollingSize:NSMakeSize(width, height)]; -} - -void uiAreaQueueRedrawAll(uiArea *a) -{ - [a->area setNeedsDisplay:YES]; -} - -void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height) -{ - if (!a->scrolling) - userbug("You cannot call uiAreaScrollTo() on a non-scrolling uiArea. (area: %p)", a); - [a->area scrollRectToVisible:NSMakeRect(x, y, width, height)]; - // don't worry about the return value; it just says whether scrolling was needed -} - -void uiAreaBeginUserWindowMove(uiArea *a) -{ - libuiNSWindow *w; - - w = (libuiNSWindow *) [a->area window]; - if (w == nil) - return; // TODO - if (a->dragevent == nil) - return; // TODO - [w libui_doMove:a->dragevent]; -} - -void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge) -{ - libuiNSWindow *w; - - w = (libuiNSWindow *) [a->area window]; - if (w == nil) - return; // TODO - if (a->dragevent == nil) - return; // TODO - [w libui_doResize:a->dragevent on:edge]; -} - -uiArea *uiNewArea(uiAreaHandler *ah) -{ - uiArea *a; - - uiDarwinNewControl(uiArea, a); - - a->ah = ah; - a->scrolling = NO; - - a->area = [[areaView alloc] initWithFrame:NSZeroRect area:a]; - - a->view = a->area; - - return a; -} - -uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height) -{ - uiArea *a; - struct scrollViewCreateParams p; - - uiDarwinNewControl(uiArea, a); - - a->ah = ah; - a->scrolling = YES; - - a->area = [[areaView alloc] initWithFrame:NSMakeRect(0, 0, width, height) - area:a]; - - memset(&p, 0, sizeof (struct scrollViewCreateParams)); - p.DocumentView = a->area; - p.BackgroundColor = [NSColor controlColor]; - p.DrawsBackground = 1; - p.Bordered = NO; - p.HScroll = YES; - p.VScroll = YES; - a->sv = mkScrollView(&p, &(a->d)); - - a->view = a->sv; - - return a; -} diff --git a/deps/libui/darwin/areaevents.m b/deps/libui/darwin/areaevents.m deleted file mode 100644 index d7ceaaadc5..0000000000 --- a/deps/libui/darwin/areaevents.m +++ /dev/null @@ -1,159 +0,0 @@ -// 30 march 2014 -#import "uipriv_darwin.h" - -/* -Mac OS X uses its own set of hardware key codes that are different from PC keyboard scancodes, but are positional (like PC keyboard scancodes). These are defined in , a Carbon header. As far as I can tell, there's no way to include this header without either using an absolute path or linking Carbon into the program, so the constant values are used here instead. - -The Cocoa docs do guarantee that -[NSEvent keyCode] results in key codes that are the same as those returned by Carbon; that is, these codes. -*/ - -// use uintptr_t to be safe -static const struct { - uintptr_t keycode; - char equiv; -} keycodeKeys[] = { - { 0x00, 'a' }, - { 0x01, 's' }, - { 0x02, 'd' }, - { 0x03, 'f' }, - { 0x04, 'h' }, - { 0x05, 'g' }, - { 0x06, 'z' }, - { 0x07, 'x' }, - { 0x08, 'c' }, - { 0x09, 'v' }, - { 0x0B, 'b' }, - { 0x0C, 'q' }, - { 0x0D, 'w' }, - { 0x0E, 'e' }, - { 0x0F, 'r' }, - { 0x10, 'y' }, - { 0x11, 't' }, - { 0x12, '1' }, - { 0x13, '2' }, - { 0x14, '3' }, - { 0x15, '4' }, - { 0x16, '6' }, - { 0x17, '5' }, - { 0x18, '=' }, - { 0x19, '9' }, - { 0x1A, '7' }, - { 0x1B, '-' }, - { 0x1C, '8' }, - { 0x1D, '0' }, - { 0x1E, ']' }, - { 0x1F, 'o' }, - { 0x20, 'u' }, - { 0x21, '[' }, - { 0x22, 'i' }, - { 0x23, 'p' }, - { 0x25, 'l' }, - { 0x26, 'j' }, - { 0x27, '\'' }, - { 0x28, 'k' }, - { 0x29, ';' }, - { 0x2A, '\\' }, - { 0x2B, ',' }, - { 0x2C, '/' }, - { 0x2D, 'n' }, - { 0x2E, 'm' }, - { 0x2F, '.' }, - { 0x32, '`' }, - { 0x24, '\n' }, - { 0x30, '\t' }, - { 0x31, ' ' }, - { 0x33, '\b' }, - { 0xFFFF, 0 }, -}; - -static const struct { - uintptr_t keycode; - uiExtKey equiv; -} keycodeExtKeys[] = { - { 0x41, uiExtKeyNDot }, - { 0x43, uiExtKeyNMultiply }, - { 0x45, uiExtKeyNAdd }, - { 0x4B, uiExtKeyNDivide }, - { 0x4C, uiExtKeyNEnter }, - { 0x4E, uiExtKeyNSubtract }, - { 0x52, uiExtKeyN0 }, - { 0x53, uiExtKeyN1 }, - { 0x54, uiExtKeyN2 }, - { 0x55, uiExtKeyN3 }, - { 0x56, uiExtKeyN4 }, - { 0x57, uiExtKeyN5 }, - { 0x58, uiExtKeyN6 }, - { 0x59, uiExtKeyN7 }, - { 0x5B, uiExtKeyN8 }, - { 0x5C, uiExtKeyN9 }, - { 0x35, uiExtKeyEscape }, - { 0x60, uiExtKeyF5 }, - { 0x61, uiExtKeyF6 }, - { 0x62, uiExtKeyF7 }, - { 0x63, uiExtKeyF3 }, - { 0x64, uiExtKeyF8 }, - { 0x65, uiExtKeyF9 }, - { 0x67, uiExtKeyF11 }, - { 0x6D, uiExtKeyF10 }, - { 0x6F, uiExtKeyF12 }, - { 0x72, uiExtKeyInsert }, // listed as the Help key but it's in the same position on an Apple keyboard as the Insert key on a Windows keyboard; thanks to SeanieB from irc.badnik.net and Psy in irc.freenode.net/#macdev for confirming they have the same code - { 0x73, uiExtKeyHome }, - { 0x74, uiExtKeyPageUp }, - { 0x75, uiExtKeyDelete }, - { 0x76, uiExtKeyF4 }, - { 0x77, uiExtKeyEnd }, - { 0x78, uiExtKeyF2 }, - { 0x79, uiExtKeyPageDown }, - { 0x7A, uiExtKeyF1 }, - { 0x7B, uiExtKeyLeft }, - { 0x7C, uiExtKeyRight }, - { 0x7D, uiExtKeyDown }, - { 0x7E, uiExtKeyUp }, - { 0xFFFF, 0 }, -}; - -static const struct { - uintptr_t keycode; - uiModifiers equiv; -} keycodeModifiers[] = { - { 0x37, uiModifierSuper }, // left command - { 0x38, uiModifierShift }, // left shift - { 0x3A, uiModifierAlt }, // left option - { 0x3B, uiModifierCtrl }, // left control - { 0x3C, uiModifierShift }, // right shift - { 0x3D, uiModifierAlt }, // right alt - { 0x3E, uiModifierCtrl }, // right control - // the following is not in Events.h for some reason - // thanks to Nicole and jedivulcan from irc.badnik.net - { 0x36, uiModifierSuper }, // right command - { 0xFFFF, 0 }, -}; - -BOOL fromKeycode(unsigned short keycode, uiAreaKeyEvent *ke) -{ - int i; - - for (i = 0; keycodeKeys[i].keycode != 0xFFFF; i++) - if (keycodeKeys[i].keycode == keycode) { - ke->Key = keycodeKeys[i].equiv; - return YES; - } - for (i = 0; keycodeExtKeys[i].keycode != 0xFFFF; i++) - if (keycodeExtKeys[i].keycode == keycode) { - ke->ExtKey = keycodeExtKeys[i].equiv; - return YES; - } - return NO; -} - -BOOL keycodeModifier(unsigned short keycode, uiModifiers *mod) -{ - int i; - - for (i = 0; keycodeModifiers[i].keycode != 0xFFFF; i++) - if (keycodeModifiers[i].keycode == keycode) { - *mod = keycodeModifiers[i].equiv; - return YES; - } - return NO; -} diff --git a/deps/libui/darwin/autolayout.m b/deps/libui/darwin/autolayout.m deleted file mode 100644 index 9964155fd3..0000000000 --- a/deps/libui/darwin/autolayout.m +++ /dev/null @@ -1,161 +0,0 @@ -// 15 august 2015 -#import "uipriv_darwin.h" - -NSLayoutConstraint *mkConstraint(id view1, NSLayoutAttribute attr1, NSLayoutRelation relation, id view2, NSLayoutAttribute attr2, CGFloat multiplier, CGFloat c, NSString *desc) -{ - NSLayoutConstraint *constraint; - - constraint = [NSLayoutConstraint constraintWithItem:view1 - attribute:attr1 - relatedBy:relation - toItem:view2 - attribute:attr2 - multiplier:multiplier - constant:c]; - // apparently only added in 10.9 - if ([constraint respondsToSelector:@selector(setIdentifier:)]) - [((id) constraint) setIdentifier:desc]; - return constraint; -} - -CGFloat uiDarwinMarginAmount(void *reserved) -{ - return 20.0; -} - -CGFloat uiDarwinPaddingAmount(void *reserved) -{ - return 8.0; -} - -// this is needed for NSSplitView to work properly; see http://stackoverflow.com/questions/34574478/how-can-i-set-the-position-of-a-nssplitview-nowadays-setpositionofdivideratind (stal in irc.freenode.net/#macdev came up with the exact combination) -// turns out it also works on NSTabView and NSBox too, possibly others! -// and for bonus points, it even seems to fix unsatisfiable-constraint-autoresizing-mask issues with NSTabView and NSBox too!!! this is nuts -void jiggleViewLayout(NSView *view) -{ - [view setNeedsLayout:YES]; - [view layoutSubtreeIfNeeded]; -} - -static CGFloat margins(int margined) -{ - if (!margined) - return 0.0; - return uiDarwinMarginAmount(NULL); -} - -void singleChildConstraintsEstablish(struct singleChildConstraints *c, NSView *contentView, NSView *childView, BOOL hugsTrailing, BOOL hugsBottom, int margined, NSString *desc) -{ - CGFloat margin; - - margin = margins(margined); - - c->leadingConstraint = mkConstraint(contentView, NSLayoutAttributeLeading, - NSLayoutRelationEqual, - childView, NSLayoutAttributeLeading, - 1, -margin, - [desc stringByAppendingString:@" leading constraint"]); - [contentView addConstraint:c->leadingConstraint]; - [c->leadingConstraint retain]; - - c->topConstraint = mkConstraint(contentView, NSLayoutAttributeTop, - NSLayoutRelationEqual, - childView, NSLayoutAttributeTop, - 1, -margin, - [desc stringByAppendingString:@" top constraint"]); - [contentView addConstraint:c->topConstraint]; - [c->topConstraint retain]; - - c->trailingConstraintGreater = mkConstraint(contentView, NSLayoutAttributeTrailing, - NSLayoutRelationGreaterThanOrEqual, - childView, NSLayoutAttributeTrailing, - 1, margin, - [desc stringByAppendingString:@" trailing >= constraint"]); - if (hugsTrailing) - [c->trailingConstraintGreater setPriority:NSLayoutPriorityDefaultLow]; - [contentView addConstraint:c->trailingConstraintGreater]; - [c->trailingConstraintGreater retain]; - - c->trailingConstraintEqual = mkConstraint(contentView, NSLayoutAttributeTrailing, - NSLayoutRelationEqual, - childView, NSLayoutAttributeTrailing, - 1, margin, - [desc stringByAppendingString:@" trailing == constraint"]); - if (!hugsTrailing) - [c->trailingConstraintEqual setPriority:NSLayoutPriorityDefaultLow]; - [contentView addConstraint:c->trailingConstraintEqual]; - [c->trailingConstraintEqual retain]; - - c->bottomConstraintGreater = mkConstraint(contentView, NSLayoutAttributeBottom, - NSLayoutRelationGreaterThanOrEqual, - childView, NSLayoutAttributeBottom, - 1, margin, - [desc stringByAppendingString:@" bottom >= constraint"]); - if (hugsBottom) - [c->bottomConstraintGreater setPriority:NSLayoutPriorityDefaultLow]; - [contentView addConstraint:c->bottomConstraintGreater]; - [c->bottomConstraintGreater retain]; - - c->bottomConstraintEqual = mkConstraint(contentView, NSLayoutAttributeBottom, - NSLayoutRelationEqual, - childView, NSLayoutAttributeBottom, - 1, margin, - [desc stringByAppendingString:@" bottom == constraint"]); - if (!hugsBottom) - [c->bottomConstraintEqual setPriority:NSLayoutPriorityDefaultLow]; - [contentView addConstraint:c->bottomConstraintEqual]; - [c->bottomConstraintEqual retain]; -} - -void singleChildConstraintsRemove(struct singleChildConstraints *c, NSView *cv) -{ - if (c->leadingConstraint != nil) { - [cv removeConstraint:c->leadingConstraint]; - [c->leadingConstraint release]; - c->leadingConstraint = nil; - } - if (c->topConstraint != nil) { - [cv removeConstraint:c->topConstraint]; - [c->topConstraint release]; - c->topConstraint = nil; - } - if (c->trailingConstraintGreater != nil) { - [cv removeConstraint:c->trailingConstraintGreater]; - [c->trailingConstraintGreater release]; - c->trailingConstraintGreater = nil; - } - if (c->trailingConstraintEqual != nil) { - [cv removeConstraint:c->trailingConstraintEqual]; - [c->trailingConstraintEqual release]; - c->trailingConstraintEqual = nil; - } - if (c->bottomConstraintGreater != nil) { - [cv removeConstraint:c->bottomConstraintGreater]; - [c->bottomConstraintGreater release]; - c->bottomConstraintGreater = nil; - } - if (c->bottomConstraintEqual != nil) { - [cv removeConstraint:c->bottomConstraintEqual]; - [c->bottomConstraintEqual release]; - c->bottomConstraintEqual = nil; - } -} - -void singleChildConstraintsSetMargined(struct singleChildConstraints *c, int margined) -{ - CGFloat margin; - - margin = margins(margined); - if (c->leadingConstraint != nil) - [c->leadingConstraint setConstant:-margin]; - if (c->topConstraint != nil) - [c->topConstraint setConstant:-margin]; - if (c->trailingConstraintGreater != nil) - [c->trailingConstraintGreater setConstant:margin]; - if (c->trailingConstraintEqual != nil) - [c->trailingConstraintEqual setConstant:margin]; - if (c->bottomConstraintGreater != nil) - [c->bottomConstraintGreater setConstant:margin]; - if (c->bottomConstraintEqual != nil) - [c->bottomConstraintEqual setConstant:margin]; -} diff --git a/deps/libui/darwin/box.m b/deps/libui/darwin/box.m deleted file mode 100644 index 18d536d5ac..0000000000 --- a/deps/libui/darwin/box.m +++ /dev/null @@ -1,469 +0,0 @@ -// 15 august 2015 -#import "uipriv_darwin.h" - -// TODO hiding all stretchy controls still hugs trailing edge - -@interface boxChild : NSObject -@property uiControl *c; -@property BOOL stretchy; -@property NSLayoutPriority oldPrimaryHuggingPri; -@property NSLayoutPriority oldSecondaryHuggingPri; -- (NSView *)view; -@end - -@interface boxView : NSView { - uiBox *b; - NSMutableArray *children; - BOOL vertical; - int padded; - - NSLayoutConstraint *first; - NSMutableArray *inBetweens; - NSLayoutConstraint *last; - NSMutableArray *otherConstraints; - - NSLayoutAttribute primaryStart; - NSLayoutAttribute primaryEnd; - NSLayoutAttribute secondaryStart; - NSLayoutAttribute secondaryEnd; - NSLayoutAttribute primarySize; - NSLayoutConstraintOrientation primaryOrientation; - NSLayoutConstraintOrientation secondaryOrientation; -} -- (id)initWithVertical:(BOOL)vert b:(uiBox *)bb; -- (void)onDestroy; -- (void)removeOurConstraints; -- (void)syncEnableStates:(int)enabled; -- (CGFloat)paddingAmount; -- (void)establishOurConstraints; -- (void)append:(uiControl *)c stretchy:(int)stretchy; -- (void)delete:(int)n; -- (int)isPadded; -- (void)setPadded:(int)p; -- (BOOL)hugsTrailing; -- (BOOL)hugsBottom; -- (int)nStretchy; -@end - -struct uiBox { - uiDarwinControl c; - boxView *view; -}; - -@implementation boxChild - -- (NSView *)view -{ - return (NSView *) uiControlHandle(self.c); -} - -@end - -@implementation boxView - -- (id)initWithVertical:(BOOL)vert b:(uiBox *)bb -{ - self = [super initWithFrame:NSZeroRect]; - if (self != nil) { - // the weird names vert and bb are to shut the compiler up about shadowing because implicit this/self is stupid - self->b = bb; - self->vertical = vert; - self->padded = 0; - self->children = [NSMutableArray new]; - - self->inBetweens = [NSMutableArray new]; - self->otherConstraints = [NSMutableArray new]; - - if (self->vertical) { - self->primaryStart = NSLayoutAttributeTop; - self->primaryEnd = NSLayoutAttributeBottom; - self->secondaryStart = NSLayoutAttributeLeading; - self->secondaryEnd = NSLayoutAttributeTrailing; - self->primarySize = NSLayoutAttributeHeight; - self->primaryOrientation = NSLayoutConstraintOrientationVertical; - self->secondaryOrientation = NSLayoutConstraintOrientationHorizontal; - } else { - self->primaryStart = NSLayoutAttributeLeading; - self->primaryEnd = NSLayoutAttributeTrailing; - self->secondaryStart = NSLayoutAttributeTop; - self->secondaryEnd = NSLayoutAttributeBottom; - self->primarySize = NSLayoutAttributeWidth; - self->primaryOrientation = NSLayoutConstraintOrientationHorizontal; - self->secondaryOrientation = NSLayoutConstraintOrientationVertical; - } - } - return self; -} - -- (void)onDestroy -{ - boxChild *bc; - - [self removeOurConstraints]; - [self->inBetweens release]; - [self->otherConstraints release]; - - for (bc in self->children) { - uiControlSetParent(bc.c, NULL); - uiDarwinControlSetSuperview(uiDarwinControl(bc.c), nil); - uiControlDestroy(bc.c); - } - [self->children release]; -} - -- (void)removeOurConstraints -{ - if (self->first != nil) { - [self removeConstraint:self->first]; - [self->first release]; - self->first = nil; - } - if ([self->inBetweens count] != 0) { - [self removeConstraints:self->inBetweens]; - [self->inBetweens removeAllObjects]; - } - if (self->last != nil) { - [self removeConstraint:self->last]; - [self->last release]; - self->last = nil; - } - if ([self->otherConstraints count] != 0) { - [self removeConstraints:self->otherConstraints]; - [self->otherConstraints removeAllObjects]; - } -} - -- (void)syncEnableStates:(int)enabled -{ - boxChild *bc; - - for (bc in self->children) - uiDarwinControlSyncEnableState(uiDarwinControl(bc.c), enabled); -} - -- (CGFloat)paddingAmount -{ - if (!self->padded) - return 0.0; - return uiDarwinPaddingAmount(NULL); -} - -- (void)establishOurConstraints -{ - boxChild *bc; - CGFloat padding; - NSView *prev; - NSLayoutConstraint *c; - BOOL (*hugsSecondary)(uiDarwinControl *); - - [self removeOurConstraints]; - if ([self->children count] == 0) - return; - padding = [self paddingAmount]; - - // first arrange in the primary direction - prev = nil; - for (bc in self->children) { - if (!uiControlVisible(bc.c)) - continue; - if (prev == nil) { // first view - self->first = mkConstraint(self, self->primaryStart, - NSLayoutRelationEqual, - [bc view], self->primaryStart, - 1, 0, - @"uiBox first primary constraint"); - [self addConstraint:self->first]; - [self->first retain]; - prev = [bc view]; - continue; - } - // not the first; link it - c = mkConstraint(prev, self->primaryEnd, - NSLayoutRelationEqual, - [bc view], self->primaryStart, - 1, -padding, - @"uiBox in-between primary constraint"); - [self addConstraint:c]; - [self->inBetweens addObject:c]; - prev = [bc view]; - } - if (prev == nil) // no control visible; act as if no controls - return; - self->last = mkConstraint(prev, self->primaryEnd, - NSLayoutRelationEqual, - self, self->primaryEnd, - 1, 0, - @"uiBox last primary constraint"); - [self addConstraint:self->last]; - [self->last retain]; - - // then arrange in the secondary direction - hugsSecondary = uiDarwinControlHugsTrailingEdge; - if (!self->vertical) - hugsSecondary = uiDarwinControlHugsBottom; - for (bc in self->children) { - if (!uiControlVisible(bc.c)) - continue; - c = mkConstraint(self, self->secondaryStart, - NSLayoutRelationEqual, - [bc view], self->secondaryStart, - 1, 0, - @"uiBox secondary start constraint"); - [self addConstraint:c]; - [self->otherConstraints addObject:c]; - c = mkConstraint([bc view], self->secondaryEnd, - NSLayoutRelationLessThanOrEqual, - self, self->secondaryEnd, - 1, 0, - @"uiBox secondary end <= constraint"); - if ((*hugsSecondary)(uiDarwinControl(bc.c))) - [c setPriority:NSLayoutPriorityDefaultLow]; - [self addConstraint:c]; - [self->otherConstraints addObject:c]; - c = mkConstraint([bc view], self->secondaryEnd, - NSLayoutRelationEqual, - self, self->secondaryEnd, - 1, 0, - @"uiBox secondary end == constraint"); - if (!(*hugsSecondary)(uiDarwinControl(bc.c))) - [c setPriority:NSLayoutPriorityDefaultLow]; - [self addConstraint:c]; - [self->otherConstraints addObject:c]; - } - - // and make all stretchy controls the same size - if ([self nStretchy] == 0) - return; - prev = nil; // first stretchy view - for (bc in self->children) { - if (!uiControlVisible(bc.c)) - continue; - if (!bc.stretchy) - continue; - if (prev == nil) { - prev = [bc view]; - continue; - } - c = mkConstraint(prev, self->primarySize, - NSLayoutRelationEqual, - [bc view], self->primarySize, - 1, 0, - @"uiBox stretchy size constraint"); - [self addConstraint:c]; - [self->otherConstraints addObject:c]; - } -} - -- (void)append:(uiControl *)c stretchy:(int)stretchy -{ - boxChild *bc; - NSLayoutPriority priority; - int oldnStretchy; - - bc = [boxChild new]; - bc.c = c; - bc.stretchy = stretchy; - bc.oldPrimaryHuggingPri = uiDarwinControlHuggingPriority(uiDarwinControl(bc.c), self->primaryOrientation); - bc.oldSecondaryHuggingPri = uiDarwinControlHuggingPriority(uiDarwinControl(bc.c), self->secondaryOrientation); - - uiControlSetParent(bc.c, uiControl(self->b)); - uiDarwinControlSetSuperview(uiDarwinControl(bc.c), self); - uiDarwinControlSyncEnableState(uiDarwinControl(bc.c), uiControlEnabledToUser(uiControl(self->b))); - - // if a control is stretchy, it should not hug in the primary direction - // otherwise, it should *forcibly* hug - if (bc.stretchy) - priority = NSLayoutPriorityDefaultLow; - else - // LONGTERM will default high work? - priority = NSLayoutPriorityRequired; - uiDarwinControlSetHuggingPriority(uiDarwinControl(bc.c), priority, self->primaryOrientation); - // make sure controls don't hug their secondary direction so they fill the width of the view - uiDarwinControlSetHuggingPriority(uiDarwinControl(bc.c), NSLayoutPriorityDefaultLow, self->secondaryOrientation); - - oldnStretchy = [self nStretchy]; - [self->children addObject:bc]; - - [self establishOurConstraints]; - if (bc.stretchy) - if (oldnStretchy == 0) - uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(self->b)); - - [bc release]; // we don't need the initial reference now -} - -- (void)delete:(int)n -{ - boxChild *bc; - int stretchy; - - bc = (boxChild *) [self->children objectAtIndex:n]; - stretchy = bc.stretchy; - - uiControlSetParent(bc.c, NULL); - uiDarwinControlSetSuperview(uiDarwinControl(bc.c), nil); - - uiDarwinControlSetHuggingPriority(uiDarwinControl(bc.c), bc.oldPrimaryHuggingPri, self->primaryOrientation); - uiDarwinControlSetHuggingPriority(uiDarwinControl(bc.c), bc.oldSecondaryHuggingPri, self->secondaryOrientation); - - [self->children removeObjectAtIndex:n]; - - [self establishOurConstraints]; - if (stretchy) - if ([self nStretchy] == 0) - uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(self->b)); -} - -- (int)isPadded -{ - return self->padded; -} - -- (void)setPadded:(int)p -{ - CGFloat padding; - NSLayoutConstraint *c; - - self->padded = p; - padding = [self paddingAmount]; - for (c in self->inBetweens) - [c setConstant:-padding]; -} - -- (BOOL)hugsTrailing -{ - if (self->vertical) // always hug if vertical - return YES; - return [self nStretchy] != 0; -} - -- (BOOL)hugsBottom -{ - if (!self->vertical) // always hug if horizontal - return YES; - return [self nStretchy] != 0; -} - -- (int)nStretchy -{ - boxChild *bc; - int n; - - n = 0; - for (bc in self->children) { - if (!uiControlVisible(bc.c)) - continue; - if (bc.stretchy) - n++; - } - return n; -} - -@end - -static void uiBoxDestroy(uiControl *c) -{ - uiBox *b = uiBox(c); - - [b->view onDestroy]; - [b->view release]; - uiFreeControl(uiControl(b)); -} - -uiDarwinControlDefaultHandle(uiBox, view) -uiDarwinControlDefaultParent(uiBox, view) -uiDarwinControlDefaultSetParent(uiBox, view) -uiDarwinControlDefaultToplevel(uiBox, view) -uiDarwinControlDefaultVisible(uiBox, view) -uiDarwinControlDefaultShow(uiBox, view) -uiDarwinControlDefaultHide(uiBox, view) -uiDarwinControlDefaultEnabled(uiBox, view) -uiDarwinControlDefaultEnable(uiBox, view) -uiDarwinControlDefaultDisable(uiBox, view) - -static void uiBoxSyncEnableState(uiDarwinControl *c, int enabled) -{ - uiBox *b = uiBox(c); - - if (uiDarwinShouldStopSyncEnableState(uiDarwinControl(b), enabled)) - return; - [b->view syncEnableStates:enabled]; -} - -uiDarwinControlDefaultSetSuperview(uiBox, view) - -static BOOL uiBoxHugsTrailingEdge(uiDarwinControl *c) -{ - uiBox *b = uiBox(c); - - return [b->view hugsTrailing]; -} - -static BOOL uiBoxHugsBottom(uiDarwinControl *c) -{ - uiBox *b = uiBox(c); - - return [b->view hugsBottom]; -} - -static void uiBoxChildEdgeHuggingChanged(uiDarwinControl *c) -{ - uiBox *b = uiBox(c); - - [b->view establishOurConstraints]; -} - -uiDarwinControlDefaultHuggingPriority(uiBox, view) -uiDarwinControlDefaultSetHuggingPriority(uiBox, view) - -static void uiBoxChildVisibilityChanged(uiDarwinControl *c) -{ - uiBox *b = uiBox(c); - - [b->view establishOurConstraints]; -} - -void uiBoxAppend(uiBox *b, uiControl *c, int stretchy) -{ - // LONGTERM on other platforms - // or at leat allow this and implicitly turn it into a spacer - if (c == NULL) - userbug("You cannot add NULL to a uiBox."); - [b->view append:c stretchy:stretchy]; -} - -void uiBoxDelete(uiBox *b, int n) -{ - [b->view delete:n]; -} - -int uiBoxPadded(uiBox *b) -{ - return [b->view isPadded]; -} - -void uiBoxSetPadded(uiBox *b, int padded) -{ - [b->view setPadded:padded]; -} - -static uiBox *finishNewBox(BOOL vertical) -{ - uiBox *b; - - uiDarwinNewControl(uiBox, b); - - b->view = [[boxView alloc] initWithVertical:vertical b:b]; - - return b; -} - -uiBox *uiNewHorizontalBox(void) -{ - return finishNewBox(NO); -} - -uiBox *uiNewVerticalBox(void) -{ - return finishNewBox(YES); -} diff --git a/deps/libui/darwin/button.m b/deps/libui/darwin/button.m deleted file mode 100644 index baccabbb38..0000000000 --- a/deps/libui/darwin/button.m +++ /dev/null @@ -1,113 +0,0 @@ -// 13 august 2015 -#import "uipriv_darwin.h" - -struct uiButton { - uiDarwinControl c; - NSButton *button; - void (*onClicked)(uiButton *, void *); - void *onClickedData; -}; - -@interface buttonDelegateClass : NSObject { - struct mapTable *buttons; -} -- (IBAction)onClicked:(id)sender; -- (void)registerButton:(uiButton *)b; -- (void)unregisterButton:(uiButton *)b; -@end - -@implementation buttonDelegateClass - -- (id)init -{ - self = [super init]; - if (self) - self->buttons = newMap(); - return self; -} - -- (void)dealloc -{ - mapDestroy(self->buttons); - [super dealloc]; -} - -- (IBAction)onClicked:(id)sender -{ - uiButton *b; - - b = (uiButton *) mapGet(self->buttons, sender); - (*(b->onClicked))(b, b->onClickedData); -} - -- (void)registerButton:(uiButton *)b -{ - mapSet(self->buttons, b->button, b); - [b->button setTarget:self]; - [b->button setAction:@selector(onClicked:)]; -} - -- (void)unregisterButton:(uiButton *)b -{ - [b->button setTarget:nil]; - mapDelete(self->buttons, b->button); -} - -@end - -static buttonDelegateClass *buttonDelegate = nil; - -uiDarwinControlAllDefaultsExceptDestroy(uiButton, button) - -static void uiButtonDestroy(uiControl *c) -{ - uiButton *b = uiButton(c); - - [buttonDelegate unregisterButton:b]; - [b->button release]; - uiFreeControl(uiControl(b)); -} - -char *uiButtonText(uiButton *b) -{ - return uiDarwinNSStringToText([b->button title]); -} - -void uiButtonSetText(uiButton *b, const char *text) -{ - [b->button setTitle:toNSString(text)]; -} - -void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *, void *), void *data) -{ - b->onClicked = f; - b->onClickedData = data; -} - -static void defaultOnClicked(uiButton *b, void *data) -{ - // do nothing -} - -uiButton *uiNewButton(const char *text) -{ - uiButton *b; - - uiDarwinNewControl(uiButton, b); - - b->button = [[NSButton alloc] initWithFrame:NSZeroRect]; - [b->button setTitle:toNSString(text)]; - [b->button setButtonType:NSMomentaryPushInButton]; - [b->button setBordered:YES]; - [b->button setBezelStyle:NSRoundedBezelStyle]; - uiDarwinSetControlFont(b->button, NSRegularControlSize); - - if (buttonDelegate == nil) { - buttonDelegate = [[buttonDelegateClass new] autorelease]; - [delegates addObject:buttonDelegate]; - } - [buttonDelegate registerButton:b]; - uiButtonOnClicked(b, defaultOnClicked, NULL); - - return b; -} diff --git a/deps/libui/darwin/checkbox.m b/deps/libui/darwin/checkbox.m deleted file mode 100644 index dd1ce09357..0000000000 --- a/deps/libui/darwin/checkbox.m +++ /dev/null @@ -1,129 +0,0 @@ -// 14 august 2015 -#import "uipriv_darwin.h" - -struct uiCheckbox { - uiDarwinControl c; - NSButton *button; - void (*onToggled)(uiCheckbox *, void *); - void *onToggledData; -}; - -@interface checkboxDelegateClass : NSObject { - struct mapTable *buttons; -} -- (IBAction)onToggled:(id)sender; -- (void)registerCheckbox:(uiCheckbox *)c; -- (void)unregisterCheckbox:(uiCheckbox *)c; -@end - -@implementation checkboxDelegateClass - -- (id)init -{ - self = [super init]; - if (self) - self->buttons = newMap(); - return self; -} - -- (void)dealloc -{ - mapDestroy(self->buttons); - [super dealloc]; -} - -- (IBAction)onToggled:(id)sender -{ - uiCheckbox *c; - - c = (uiCheckbox *) mapGet(self->buttons, sender); - (*(c->onToggled))(c, c->onToggledData); -} - -- (void)registerCheckbox:(uiCheckbox *)c -{ - mapSet(self->buttons, c->button, c); - [c->button setTarget:self]; - [c->button setAction:@selector(onToggled:)]; -} - -- (void)unregisterCheckbox:(uiCheckbox *)c -{ - [c->button setTarget:nil]; - mapDelete(self->buttons, c->button); -} - -@end - -static checkboxDelegateClass *checkboxDelegate = nil; - -uiDarwinControlAllDefaultsExceptDestroy(uiCheckbox, button) - -static void uiCheckboxDestroy(uiControl *cc) -{ - uiCheckbox *c = uiCheckbox(cc); - - [checkboxDelegate unregisterCheckbox:c]; - [c->button release]; - uiFreeControl(uiControl(c)); -} - -char *uiCheckboxText(uiCheckbox *c) -{ - return uiDarwinNSStringToText([c->button title]); -} - -void uiCheckboxSetText(uiCheckbox *c, const char *text) -{ - [c->button setTitle:toNSString(text)]; -} - -void uiCheckboxOnToggled(uiCheckbox *c, void (*f)(uiCheckbox *, void *), void *data) -{ - c->onToggled = f; - c->onToggledData = data; -} - -int uiCheckboxChecked(uiCheckbox *c) -{ - return [c->button state] == NSOnState; -} - -void uiCheckboxSetChecked(uiCheckbox *c, int checked) -{ - NSInteger state; - - state = NSOnState; - if (!checked) - state = NSOffState; - [c->button setState:state]; -} - -static void defaultOnToggled(uiCheckbox *c, void *data) -{ - // do nothing -} - -uiCheckbox *uiNewCheckbox(const char *text) -{ - uiCheckbox *c; - - uiDarwinNewControl(uiCheckbox, c); - - c->button = [[NSButton alloc] initWithFrame:NSZeroRect]; - [c->button setTitle:toNSString(text)]; - [c->button setButtonType:NSSwitchButton]; - // doesn't seem to have an associated bezel style - [c->button setBordered:NO]; - [c->button setTransparent:NO]; - uiDarwinSetControlFont(c->button, NSRegularControlSize); - - if (checkboxDelegate == nil) { - checkboxDelegate = [[checkboxDelegateClass new] autorelease]; - [delegates addObject:checkboxDelegate]; - } - [checkboxDelegate registerCheckbox:c]; - uiCheckboxOnToggled(c, defaultOnToggled, NULL); - - return c; -} diff --git a/deps/libui/darwin/colorbutton.m b/deps/libui/darwin/colorbutton.m deleted file mode 100644 index 83b61571eb..0000000000 --- a/deps/libui/darwin/colorbutton.m +++ /dev/null @@ -1,159 +0,0 @@ -// 15 may 2016 -#import "uipriv_darwin.h" - -// TODO no intrinsic height? - -@interface colorButton : NSColorWell { - uiColorButton *libui_b; - BOOL libui_changing; - BOOL libui_setting; -} -- (id)initWithFrame:(NSRect)frame libuiColorButton:(uiColorButton *)b; -- (void)deactivateOnClose:(NSNotification *)note; -- (void)libuiColor:(double *)r g:(double *)g b:(double *)b a:(double *)a; -- (void)libuiSetColor:(double)r g:(double)g b:(double)b a:(double)a; -@end - -// only one may be active at one time -static colorButton *activeColorButton = nil; - -struct uiColorButton { - uiDarwinControl c; - colorButton *button; - void (*onChanged)(uiColorButton *, void *); - void *onChangedData; -}; - -@implementation colorButton - -- (id)initWithFrame:(NSRect)frame libuiColorButton:(uiColorButton *)b -{ - self = [super initWithFrame:frame]; - if (self) { - // the default color is white; set it to black first (see -setColor: below for why we do it first) - [self libuiSetColor:0.0 g:0.0 b:0.0 a:1.0]; - - self->libui_b = b; - self->libui_changing = NO; - } - return self; -} - -- (void)activate:(BOOL)exclusive -{ - if (activeColorButton != nil) - activeColorButton->libui_changing = YES; - [NSColorPanel setPickerMask:NSColorPanelAllModesMask]; - [[NSColorPanel sharedColorPanel] setShowsAlpha:YES]; - [super activate:YES]; - activeColorButton = self; - // see stddialogs.m for details - [[NSColorPanel sharedColorPanel] setWorksWhenModal:NO]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(deactivateOnClose:) - name:NSWindowWillCloseNotification - object:[NSColorPanel sharedColorPanel]]; -} - -- (void)deactivate -{ - [super deactivate]; - activeColorButton = nil; - if (!self->libui_changing) - [[NSColorPanel sharedColorPanel] orderOut:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:NSWindowWillCloseNotification - object:[NSColorPanel sharedColorPanel]]; - self->libui_changing = NO; -} - -- (void)deactivateOnClose:(NSNotification *)note -{ - [self deactivate]; -} - -- (void)setColor:(NSColor *)color -{ - uiColorButton *b = self->libui_b; - - [super setColor:color]; - // this is called by NSColorWell's init, so we have to guard - // also don't signal during a programmatic change - if (b != nil && !self->libui_setting) - (*(b->onChanged))(b, b->onChangedData); -} - -- (void)libuiColor:(double *)r g:(double *)g b:(double *)b a:(double *)a -{ - NSColor *rgba; - CGFloat cr, cg, cb, ca; - - // the given color may not be an RGBA color, which will cause the -getRed:green:blue:alpha: call to throw an exception - rgba = [[self color] colorUsingColorSpace:[NSColorSpace sRGBColorSpace]]; - [rgba getRed:&cr green:&cg blue:&cb alpha:&ca]; - *r = cr; - *g = cg; - *b = cb; - *a = ca; - // rgba will be autoreleased since it isn't a new or init call -} - -- (void)libuiSetColor:(double)r g:(double)g b:(double)b a:(double)a -{ - self->libui_setting = YES; - [self setColor:[NSColor colorWithSRGBRed:r green:g blue:b alpha:a]]; - self->libui_setting = NO; -} - -// NSColorWell has no intrinsic size by default; give it the default Interface Builder size. -- (NSSize)intrinsicContentSize -{ - return NSMakeSize(44, 23); -} - -@end - -uiDarwinControlAllDefaults(uiColorButton, button) - -// we do not want color change events to be sent to any controls other than the color buttons -// see main.m for more details -BOOL colorButtonInhibitSendAction(SEL sel, id from, id to) -{ - if (sel != @selector(changeColor:)) - return NO; - return ![to isKindOfClass:[colorButton class]]; -} - -static void defaultOnChanged(uiColorButton *b, void *data) -{ - // do nothing -} - -void uiColorButtonColor(uiColorButton *b, double *r, double *g, double *bl, double *a) -{ - [b->button libuiColor:r g:g b:bl a:a]; -} - -void uiColorButtonSetColor(uiColorButton *b, double r, double g, double bl, double a) -{ - [b->button libuiSetColor:r g:g b:bl a:a]; -} - -void uiColorButtonOnChanged(uiColorButton *b, void (*f)(uiColorButton *, void *), void *data) -{ - b->onChanged = f; - b->onChangedData = data; -} - -uiColorButton *uiNewColorButton(void) -{ - uiColorButton *b; - - uiDarwinNewControl(uiColorButton, b); - - b->button = [[colorButton alloc] initWithFrame:NSZeroRect libuiColorButton:b]; - - uiColorButtonOnChanged(b, defaultOnChanged, NULL); - - return b; -} diff --git a/deps/libui/darwin/combobox.m b/deps/libui/darwin/combobox.m deleted file mode 100644 index 89a2e28cb8..0000000000 --- a/deps/libui/darwin/combobox.m +++ /dev/null @@ -1,145 +0,0 @@ -// 14 august 2015 -#import "uipriv_darwin.h" - -// NSComboBoxes have no intrinsic width; we'll use the default Interface Builder width for them. -// NSPopUpButton is fine. -#define comboboxWidth 96 - -struct uiCombobox { - uiDarwinControl c; - NSPopUpButton *pb; - NSArrayController *pbac; - void (*onSelected)(uiCombobox *, void *); - void *onSelectedData; -}; - -@interface comboboxDelegateClass : NSObject { - struct mapTable *comboboxes; -} -- (IBAction)onSelected:(id)sender; -- (void)registerCombobox:(uiCombobox *)c; -- (void)unregisterCombobox:(uiCombobox *)c; -@end - -@implementation comboboxDelegateClass - -- (id)init -{ - self = [super init]; - if (self) - self->comboboxes = newMap(); - return self; -} - -- (void)dealloc -{ - mapDestroy(self->comboboxes); - [super dealloc]; -} - -- (IBAction)onSelected:(id)sender -{ - uiCombobox *c; - - c = uiCombobox(mapGet(self->comboboxes, sender)); - (*(c->onSelected))(c, c->onSelectedData); -} - -- (void)registerCombobox:(uiCombobox *)c -{ - mapSet(self->comboboxes, c->pb, c); - [c->pb setTarget:self]; - [c->pb setAction:@selector(onSelected:)]; -} - -- (void)unregisterCombobox:(uiCombobox *)c -{ - [c->pb setTarget:nil]; - mapDelete(self->comboboxes, c->pb); -} - -@end - -static comboboxDelegateClass *comboboxDelegate = nil; - -uiDarwinControlAllDefaultsExceptDestroy(uiCombobox, pb) - -static void uiComboboxDestroy(uiControl *cc) -{ - uiCombobox *c = uiCombobox(cc); - - [comboboxDelegate unregisterCombobox:c]; - [c->pb unbind:@"contentObjects"]; - [c->pb unbind:@"selectedIndex"]; - [c->pbac release]; - [c->pb release]; - uiFreeControl(uiControl(c)); -} - -void uiComboboxAppend(uiCombobox *c, const char *text) -{ - [c->pbac addObject:toNSString(text)]; -} - -int uiComboboxSelected(uiCombobox *c) -{ - return [c->pb indexOfSelectedItem]; -} - -void uiComboboxSetSelected(uiCombobox *c, int n) -{ - [c->pb selectItemAtIndex:n]; -} - -void uiComboboxOnSelected(uiCombobox *c, void (*f)(uiCombobox *c, void *data), void *data) -{ - c->onSelected = f; - c->onSelectedData = data; -} - -static void defaultOnSelected(uiCombobox *c, void *data) -{ - // do nothing -} - -uiCombobox *uiNewCombobox(void) -{ - uiCombobox *c; - NSPopUpButtonCell *pbcell; - - uiDarwinNewControl(uiCombobox, c); - - c->pb = [[NSPopUpButton alloc] initWithFrame:NSZeroRect pullsDown:NO]; - [c->pb setPreferredEdge:NSMinYEdge]; - pbcell = (NSPopUpButtonCell *) [c->pb cell]; - [pbcell setArrowPosition:NSPopUpArrowAtBottom]; - // the font defined by Interface Builder is Menu 13, which is lol - // just use the regular control size for consistency - uiDarwinSetControlFont(c->pb, NSRegularControlSize); - - // NSPopUpButton doesn't work like a combobox - // - it automatically selects the first item - // - it doesn't support duplicates - // but we can use a NSArrayController and Cocoa bindings to bypass these restrictions - c->pbac = [NSArrayController new]; - [c->pbac setAvoidsEmptySelection:NO]; - [c->pbac setSelectsInsertedObjects:NO]; - [c->pbac setAutomaticallyRearrangesObjects:NO]; - [c->pb bind:@"contentValues" - toObject:c->pbac - withKeyPath:@"arrangedObjects" - options:nil]; - [c->pb bind:@"selectedIndex" - toObject:c->pbac - withKeyPath:@"selectionIndex" - options:nil]; - - if (comboboxDelegate == nil) { - comboboxDelegate = [[comboboxDelegateClass new] autorelease]; - [delegates addObject:comboboxDelegate]; - } - [comboboxDelegate registerCombobox:c]; - uiComboboxOnSelected(c, defaultOnSelected, NULL); - - return c; -} diff --git a/deps/libui/darwin/control.m b/deps/libui/darwin/control.m deleted file mode 100644 index 9eaf47a274..0000000000 --- a/deps/libui/darwin/control.m +++ /dev/null @@ -1,84 +0,0 @@ -// 16 august 2015 -#import "uipriv_darwin.h" - -void uiDarwinControlSyncEnableState(uiDarwinControl *c, int state) -{ - (*(c->SyncEnableState))(c, state); -} - -void uiDarwinControlSetSuperview(uiDarwinControl *c, NSView *superview) -{ - (*(c->SetSuperview))(c, superview); -} - -BOOL uiDarwinControlHugsTrailingEdge(uiDarwinControl *c) -{ - return (*(c->HugsTrailingEdge))(c); -} - -BOOL uiDarwinControlHugsBottom(uiDarwinControl *c) -{ - return (*(c->HugsBottom))(c); -} - -void uiDarwinControlChildEdgeHuggingChanged(uiDarwinControl *c) -{ - (*(c->ChildEdgeHuggingChanged))(c); -} - -NSLayoutPriority uiDarwinControlHuggingPriority(uiDarwinControl *c, NSLayoutConstraintOrientation orientation) -{ - return (*(c->HuggingPriority))(c, orientation); -} - -void uiDarwinControlSetHuggingPriority(uiDarwinControl *c, NSLayoutPriority priority, NSLayoutConstraintOrientation orientation) -{ - (*(c->SetHuggingPriority))(c, priority, orientation); -} - -void uiDarwinControlChildVisibilityChanged(uiDarwinControl *c) -{ - (*(c->ChildVisibilityChanged))(c); -} - -void uiDarwinSetControlFont(NSControl *c, NSControlSize size) -{ - [c setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:size]]]; -} - -#define uiDarwinControlSignature 0x44617277 - -uiDarwinControl *uiDarwinAllocControl(size_t n, uint32_t typesig, const char *typenamestr) -{ - return uiDarwinControl(uiAllocControl(n, uiDarwinControlSignature, typesig, typenamestr)); -} - -BOOL uiDarwinShouldStopSyncEnableState(uiDarwinControl *c, BOOL enabled) -{ - int ce; - - ce = uiControlEnabled(uiControl(c)); - // only stop if we're going from disabled back to enabled; don't stop under any other condition - // (if we stop when going from enabled to disabled then enabled children of a disabled control won't get disabled at the OS level) - if (!ce && enabled) - return YES; - return NO; -} - -void uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl *c) -{ - uiControl *parent; - - parent = uiControlParent(uiControl(c)); - if (parent != NULL) - uiDarwinControlChildEdgeHuggingChanged(uiDarwinControl(parent)); -} - -void uiDarwinNotifyVisibilityChanged(uiDarwinControl *c) -{ - uiControl *parent; - - parent = uiControlParent(uiControl(c)); - if (parent != NULL) - uiDarwinControlChildVisibilityChanged(uiDarwinControl(parent)); -} diff --git a/deps/libui/darwin/datetimepicker.m b/deps/libui/darwin/datetimepicker.m deleted file mode 100644 index 44364d9d03..0000000000 --- a/deps/libui/darwin/datetimepicker.m +++ /dev/null @@ -1,42 +0,0 @@ -// 14 august 2015 -#import "uipriv_darwin.h" - -struct uiDateTimePicker { - uiDarwinControl c; - NSDatePicker *dp; -}; - -uiDarwinControlAllDefaults(uiDateTimePicker, dp) - -static uiDateTimePicker *finishNewDateTimePicker(NSDatePickerElementFlags elements) -{ - uiDateTimePicker *d; - - uiDarwinNewControl(uiDateTimePicker, d); - - d->dp = [[NSDatePicker alloc] initWithFrame:NSZeroRect]; - [d->dp setBordered:NO]; - [d->dp setBezeled:YES]; - [d->dp setDrawsBackground:YES]; - [d->dp setDatePickerStyle:NSTextFieldAndStepperDatePickerStyle]; - [d->dp setDatePickerElements:elements]; - [d->dp setDatePickerMode:NSSingleDateMode]; - uiDarwinSetControlFont(d->dp, NSRegularControlSize); - - return d; -} - -uiDateTimePicker *uiNewDateTimePicker(void) -{ - return finishNewDateTimePicker(NSYearMonthDayDatePickerElementFlag | NSHourMinuteSecondDatePickerElementFlag); -} - -uiDateTimePicker *uiNewDatePicker(void) -{ - return finishNewDateTimePicker(NSYearMonthDayDatePickerElementFlag); -} - -uiDateTimePicker *uiNewTimePicker(void) -{ - return finishNewDateTimePicker(NSHourMinuteSecondDatePickerElementFlag); -} diff --git a/deps/libui/darwin/debug.m b/deps/libui/darwin/debug.m deleted file mode 100644 index c91c6a738f..0000000000 --- a/deps/libui/darwin/debug.m +++ /dev/null @@ -1,19 +0,0 @@ -// 13 may 2016 -#import "uipriv_darwin.h" - -// LONGTERM don't halt on release builds - -void realbug(const char *file, const char *line, const char *func, const char *prefix, const char *format, va_list ap) -{ - NSMutableString *str; - NSString *formatted; - - str = [NSMutableString new]; - [str appendString:[NSString stringWithFormat:@"[libui] %s:%s:%s() %s", file, line, func, prefix]]; - formatted = [[NSString alloc] initWithFormat:[NSString stringWithUTF8String:format] arguments:ap]; - [str appendString:formatted]; - [formatted release]; - NSLog(@"%@", str); - [str release]; - __builtin_trap(); -} diff --git a/deps/libui/darwin/draw.m b/deps/libui/darwin/draw.m deleted file mode 100644 index 262ad3e2b3..0000000000 --- a/deps/libui/darwin/draw.m +++ /dev/null @@ -1,454 +0,0 @@ -// 6 september 2015 -#import "uipriv_darwin.h" - -struct uiDrawPath { - CGMutablePathRef path; - uiDrawFillMode fillMode; - BOOL ended; -}; - -uiDrawPath *uiDrawNewPath(uiDrawFillMode mode) -{ - uiDrawPath *p; - - p = uiNew(uiDrawPath); - p->path = CGPathCreateMutable(); - p->fillMode = mode; - return p; -} - -void uiDrawFreePath(uiDrawPath *p) -{ - CGPathRelease((CGPathRef) (p->path)); - uiFree(p); -} - -void uiDrawPathNewFigure(uiDrawPath *p, double x, double y) -{ - if (p->ended) - userbug("You cannot call uiDrawPathNewFigure() on a uiDrawPath that has already been ended. (path; %p)", p); - CGPathMoveToPoint(p->path, NULL, x, y); -} - -void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative) -{ - double sinStart, cosStart; - double startx, starty; - - if (p->ended) - userbug("You cannot call uiDrawPathNewFigureWithArc() on a uiDrawPath that has already been ended. (path; %p)", p); - sinStart = sin(startAngle); - cosStart = cos(startAngle); - startx = xCenter + radius * cosStart; - starty = yCenter + radius * sinStart; - CGPathMoveToPoint(p->path, NULL, startx, starty); - uiDrawPathArcTo(p, xCenter, yCenter, radius, startAngle, sweep, negative); -} - -void uiDrawPathLineTo(uiDrawPath *p, double x, double y) -{ - // TODO refine this to require being in a path - if (p->ended) - implbug("attempt to add line to ended path in uiDrawPathLineTo()"); - CGPathAddLineToPoint(p->path, NULL, x, y); -} - -void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative) -{ - bool cw; - - // TODO likewise - if (p->ended) - implbug("attempt to add arc to ended path in uiDrawPathArcTo()"); - if (sweep > 2 * uiPi) - sweep = 2 * uiPi; - cw = false; - if (negative) - cw = true; - CGPathAddArc(p->path, NULL, - xCenter, yCenter, - radius, - startAngle, startAngle + sweep, - cw); -} - -void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY) -{ - // TODO likewise - if (p->ended) - implbug("attempt to add bezier to ended path in uiDrawPathBezierTo()"); - CGPathAddCurveToPoint(p->path, NULL, - c1x, c1y, - c2x, c2y, - endX, endY); -} - -void uiDrawPathCloseFigure(uiDrawPath *p) -{ - // TODO likewise - if (p->ended) - implbug("attempt to close figure of ended path in uiDrawPathCloseFigure()"); - CGPathCloseSubpath(p->path); -} - -void uiDrawPathAddRectangle(uiDrawPath *p, double x, double y, double width, double height) -{ - if (p->ended) - userbug("You cannot call uiDrawPathAddRectangle() on a uiDrawPath that has already been ended. (path; %p)", p); - CGPathAddRect(p->path, NULL, CGRectMake(x, y, width, height)); -} - -void uiDrawPathEnd(uiDrawPath *p) -{ - p->ended = TRUE; -} - -struct uiDrawContext { - CGContextRef c; - CGFloat height; // needed for text; see below -}; - -uiDrawContext *newContext(CGContextRef ctxt, CGFloat height) -{ - uiDrawContext *c; - - c = uiNew(uiDrawContext); - c->c = ctxt; - c->height = height; - return c; -} - -void freeContext(uiDrawContext *c) -{ - uiFree(c); -} - -// a stroke is identical to a fill of a stroked path -// we need to do this in order to stroke with a gradient; see http://stackoverflow.com/a/25034854/3408572 -// doing this for other brushes works too -void uiDrawStroke(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b, uiDrawStrokeParams *p) -{ - CGLineCap cap; - CGLineJoin join; - CGPathRef dashPath; - CGFloat *dashes; - size_t i; - uiDrawPath p2; - - if (!path->ended) - userbug("You cannot call uiDrawStroke() on a uiDrawPath that has not been ended. (path: %p)", path); - - switch (p->Cap) { - case uiDrawLineCapFlat: - cap = kCGLineCapButt; - break; - case uiDrawLineCapRound: - cap = kCGLineCapRound; - break; - case uiDrawLineCapSquare: - cap = kCGLineCapSquare; - break; - } - switch (p->Join) { - case uiDrawLineJoinMiter: - join = kCGLineJoinMiter; - break; - case uiDrawLineJoinRound: - join = kCGLineJoinRound; - break; - case uiDrawLineJoinBevel: - join = kCGLineJoinBevel; - break; - } - - // create a temporary path identical to the previous one - dashPath = (CGPathRef) path->path; - if (p->NumDashes != 0) { - dashes = (CGFloat *) uiAlloc(p->NumDashes * sizeof (CGFloat), "CGFloat[]"); - for (i = 0; i < p->NumDashes; i++) - dashes[i] = p->Dashes[i]; - dashPath = CGPathCreateCopyByDashingPath(path->path, - NULL, - p->DashPhase, - dashes, - p->NumDashes); - uiFree(dashes); - } - // the documentation is wrong: this produces a path suitable for calling CGPathCreateCopyByStrokingPath(), not for filling directly - // the cast is safe; we never modify the CGPathRef and always cast it back to a CGPathRef anyway - p2.path = (CGMutablePathRef) CGPathCreateCopyByStrokingPath(dashPath, - NULL, - p->Thickness, - cap, - join, - p->MiterLimit); - if (p->NumDashes != 0) - CGPathRelease(dashPath); - - // always draw stroke fills using the winding rule - // otherwise intersecting figures won't draw correctly - p2.fillMode = uiDrawFillModeWinding; - p2.ended = path->ended; - uiDrawFill(c, &p2, b); - // and clean up - CGPathRelease((CGPathRef) (p2.path)); -} - -// for a solid fill, we can merely have Core Graphics fill directly -static void fillSolid(CGContextRef ctxt, uiDrawPath *p, uiDrawBrush *b) -{ - // TODO this uses DeviceRGB; switch to sRGB - CGContextSetRGBFillColor(ctxt, b->R, b->G, b->B, b->A); - switch (p->fillMode) { - case uiDrawFillModeWinding: - CGContextFillPath(ctxt); - break; - case uiDrawFillModeAlternate: - CGContextEOFillPath(ctxt); - break; - } -} - -// for a gradient fill, we need to clip to the path and then draw the gradient -// see http://stackoverflow.com/a/25034854/3408572 -static void fillGradient(CGContextRef ctxt, uiDrawPath *p, uiDrawBrush *b) -{ - CGGradientRef gradient; - CGColorSpaceRef colorspace; - CGFloat *colors; - CGFloat *locations; - size_t i; - - // gradients need a color space - // for consistency with windows, use sRGB - colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); - - // make the gradient - colors = uiAlloc(b->NumStops * 4 * sizeof (CGFloat), "CGFloat[]"); - locations = uiAlloc(b->NumStops * sizeof (CGFloat), "CGFloat[]"); - for (i = 0; i < b->NumStops; i++) { - colors[i * 4 + 0] = b->Stops[i].R; - colors[i * 4 + 1] = b->Stops[i].G; - colors[i * 4 + 2] = b->Stops[i].B; - colors[i * 4 + 3] = b->Stops[i].A; - locations[i] = b->Stops[i].Pos; - } - gradient = CGGradientCreateWithColorComponents(colorspace, colors, locations, b->NumStops); - uiFree(locations); - uiFree(colors); - - // because we're mucking with clipping, we need to save the graphics state and restore it later - CGContextSaveGState(ctxt); - - // clip - switch (p->fillMode) { - case uiDrawFillModeWinding: - CGContextClip(ctxt); - break; - case uiDrawFillModeAlternate: - CGContextEOClip(ctxt); - break; - } - - // draw the gradient - switch (b->Type) { - case uiDrawBrushTypeLinearGradient: - CGContextDrawLinearGradient(ctxt, - gradient, - CGPointMake(b->X0, b->Y0), - CGPointMake(b->X1, b->Y1), - kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); - break; - case uiDrawBrushTypeRadialGradient: - CGContextDrawRadialGradient(ctxt, - gradient, - CGPointMake(b->X0, b->Y0), - // make the start circle radius 0 to make it a point - 0, - CGPointMake(b->X1, b->Y1), - b->OuterRadius, - kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); - break; - } - - // and clean up - CGContextRestoreGState(ctxt); - CGGradientRelease(gradient); - CGColorSpaceRelease(colorspace); -} - -void uiDrawFill(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b) -{ - if (!path->ended) - userbug("You cannot call uiDrawStroke() on a uiDrawPath that has not been ended. (path: %p)", path); - CGContextAddPath(c->c, (CGPathRef) (path->path)); - switch (b->Type) { - case uiDrawBrushTypeSolid: - fillSolid(c->c, path, b); - return; - case uiDrawBrushTypeLinearGradient: - case uiDrawBrushTypeRadialGradient: - fillGradient(c->c, path, b); - return; -// case uiDrawBrushTypeImage: - // TODO - return; - } - userbug("Unknown brush type %d passed to uiDrawFill().", b->Type); -} - -static void m2c(uiDrawMatrix *m, CGAffineTransform *c) -{ - c->a = m->M11; - c->b = m->M12; - c->c = m->M21; - c->d = m->M22; - c->tx = m->M31; - c->ty = m->M32; -} - -static void c2m(CGAffineTransform *c, uiDrawMatrix *m) -{ - m->M11 = c->a; - m->M12 = c->b; - m->M21 = c->c; - m->M22 = c->d; - m->M31 = c->tx; - m->M32 = c->ty; -} - -void uiDrawMatrixTranslate(uiDrawMatrix *m, double x, double y) -{ - CGAffineTransform c; - - m2c(m, &c); - c = CGAffineTransformTranslate(c, x, y); - c2m(&c, m); -} - -void uiDrawMatrixScale(uiDrawMatrix *m, double xCenter, double yCenter, double x, double y) -{ - CGAffineTransform c; - double xt, yt; - - m2c(m, &c); - xt = x; - yt = y; - scaleCenter(xCenter, yCenter, &xt, &yt); - c = CGAffineTransformTranslate(c, xt, yt); - c = CGAffineTransformScale(c, x, y); - c = CGAffineTransformTranslate(c, -xt, -yt); - c2m(&c, m); -} - -void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount) -{ - CGAffineTransform c; - - m2c(m, &c); - c = CGAffineTransformTranslate(c, x, y); - c = CGAffineTransformRotate(c, amount); - c = CGAffineTransformTranslate(c, -x, -y); - c2m(&c, m); -} - -void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount) -{ - fallbackSkew(m, x, y, xamount, yamount); -} - -void uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src) -{ - CGAffineTransform c; - CGAffineTransform d; - - m2c(dest, &c); - m2c(src, &d); - c = CGAffineTransformConcat(c, d); - c2m(&c, dest); -} - -// there is no test for invertibility; CGAffineTransformInvert() is merely documented as returning the matrix unchanged if it isn't invertible -// therefore, special care must be taken to catch matrices who are their own inverses -// TODO figure out which matrices these are and do so -int uiDrawMatrixInvertible(uiDrawMatrix *m) -{ - CGAffineTransform c, d; - - m2c(m, &c); - d = CGAffineTransformInvert(c); - return CGAffineTransformEqualToTransform(c, d) == false; -} - -int uiDrawMatrixInvert(uiDrawMatrix *m) -{ - CGAffineTransform c, d; - - m2c(m, &c); - d = CGAffineTransformInvert(c); - if (CGAffineTransformEqualToTransform(c, d)) - return 0; - c2m(&d, m); - return 1; -} - -void uiDrawMatrixTransformPoint(uiDrawMatrix *m, double *x, double *y) -{ - CGAffineTransform c; - CGPoint p; - - m2c(m, &c); - p = CGPointApplyAffineTransform(CGPointMake(*x, *y), c); - *x = p.x; - *y = p.y; -} - -void uiDrawMatrixTransformSize(uiDrawMatrix *m, double *x, double *y) -{ - CGAffineTransform c; - CGSize s; - - m2c(m, &c); - s = CGSizeApplyAffineTransform(CGSizeMake(*x, *y), c); - *x = s.width; - *y = s.height; -} - -void uiDrawTransform(uiDrawContext *c, uiDrawMatrix *m) -{ - CGAffineTransform cm; - - m2c(m, &cm); - CGContextConcatCTM(c->c, cm); -} - -void uiDrawClip(uiDrawContext *c, uiDrawPath *path) -{ - if (!path->ended) - userbug("You cannot call uiDrawCilp() on a uiDrawPath that has not been ended. (path: %p)", path); - CGContextAddPath(c->c, (CGPathRef) (path->path)); - switch (path->fillMode) { - case uiDrawFillModeWinding: - CGContextClip(c->c); - break; - case uiDrawFillModeAlternate: - CGContextEOClip(c->c); - break; - } -} - -// TODO figure out what besides transforms these save/restore on all platforms -void uiDrawSave(uiDrawContext *c) -{ - CGContextSaveGState(c->c); -} - -void uiDrawRestore(uiDrawContext *c) -{ - CGContextRestoreGState(c->c); -} - -void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout) -{ - doDrawText(c->c, c->height, x, y, layout); -} diff --git a/deps/libui/darwin/drawtext.m b/deps/libui/darwin/drawtext.m deleted file mode 100644 index c376536a02..0000000000 --- a/deps/libui/darwin/drawtext.m +++ /dev/null @@ -1,655 +0,0 @@ -// 6 september 2015 -#import "uipriv_darwin.h" - -// TODO -#define complain(...) implbug(__VA_ARGS__) - -// TODO double-check that we are properly handling allocation failures (or just toll free bridge from cocoa) -struct uiDrawFontFamilies { - CFArrayRef fonts; -}; - -uiDrawFontFamilies *uiDrawListFontFamilies(void) -{ - uiDrawFontFamilies *ff; - - ff = uiNew(uiDrawFontFamilies); - ff->fonts = CTFontManagerCopyAvailableFontFamilyNames(); - if (ff->fonts == NULL) - implbug("error getting available font names (no reason specified) (TODO)"); - return ff; -} - -int uiDrawFontFamiliesNumFamilies(uiDrawFontFamilies *ff) -{ - return CFArrayGetCount(ff->fonts); -} - -char *uiDrawFontFamiliesFamily(uiDrawFontFamilies *ff, int n) -{ - CFStringRef familystr; - char *family; - - familystr = (CFStringRef) CFArrayGetValueAtIndex(ff->fonts, n); - // toll-free bridge - family = uiDarwinNSStringToText((NSString *) familystr); - // Get Rule means we do not free familystr - return family; -} - -void uiDrawFreeFontFamilies(uiDrawFontFamilies *ff) -{ - CFRelease(ff->fonts); - uiFree(ff); -} - -struct uiDrawTextFont { - CTFontRef f; -}; - -uiDrawTextFont *mkTextFont(CTFontRef f, BOOL retain) -{ - uiDrawTextFont *font; - - font = uiNew(uiDrawTextFont); - font->f = f; - if (retain) - CFRetain(font->f); - return font; -} - -uiDrawTextFont *mkTextFontFromNSFont(NSFont *f) -{ - // toll-free bridging; we do retain, though - return mkTextFont((CTFontRef) f, YES); -} - -static CFMutableDictionaryRef newAttrList(void) -{ - CFMutableDictionaryRef attr; - - attr = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - if (attr == NULL) - complain("error creating attribute dictionary in newAttrList()()"); - return attr; -} - -static void addFontFamilyAttr(CFMutableDictionaryRef attr, const char *family) -{ - CFStringRef cfstr; - - cfstr = CFStringCreateWithCString(NULL, family, kCFStringEncodingUTF8); - if (cfstr == NULL) - complain("error creating font family name CFStringRef in addFontFamilyAttr()"); - CFDictionaryAddValue(attr, kCTFontFamilyNameAttribute, cfstr); - CFRelease(cfstr); // dictionary holds its own reference -} - -static void addFontSizeAttr(CFMutableDictionaryRef attr, double size) -{ - CFNumberRef n; - - n = CFNumberCreate(NULL, kCFNumberDoubleType, &size); - CFDictionaryAddValue(attr, kCTFontSizeAttribute, n); - CFRelease(n); -} - -#if 0 -TODO -// See http://stackoverflow.com/questions/4810409/does-coretext-support-small-caps/4811371#4811371 and https://git.gnome.org/browse/pango/tree/pango/pangocoretext-fontmap.c for what these do -// And fortunately, unlike the traits (see below), unmatched features are simply ignored without affecting the other features :D -static void addFontSmallCapsAttr(CFMutableDictionaryRef attr) -{ - CFMutableArrayRef outerArray; - CFMutableDictionaryRef innerDict; - CFNumberRef numType, numSelector; - int num; - - outerArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - if (outerArray == NULL) - complain("error creating outer CFArray for adding small caps attributes in addFontSmallCapsAttr()"); - - // Apple's headers say these are deprecated, but a few fonts still rely on them - num = kLetterCaseType; - numType = CFNumberCreate(NULL, kCFNumberIntType, &num); - num = kSmallCapsSelector; - numSelector = CFNumberCreate(NULL, kCFNumberIntType, &num); - innerDict = newAttrList(); - CFDictionaryAddValue(innerDict, kCTFontFeatureTypeIdentifierKey, numType); - CFRelease(numType); - CFDictionaryAddValue(innerDict, kCTFontFeatureSelectorIdentifierKey, numSelector); - CFRelease(numSelector); - CFArrayAppendValue(outerArray, innerDict); - CFRelease(innerDict); // and likewise for CFArray - - // these are the non-deprecated versions of the above; some fonts have these instead - num = kLowerCaseType; - numType = CFNumberCreate(NULL, kCFNumberIntType, &num); - num = kLowerCaseSmallCapsSelector; - numSelector = CFNumberCreate(NULL, kCFNumberIntType, &num); - innerDict = newAttrList(); - CFDictionaryAddValue(innerDict, kCTFontFeatureTypeIdentifierKey, numType); - CFRelease(numType); - CFDictionaryAddValue(innerDict, kCTFontFeatureSelectorIdentifierKey, numSelector); - CFRelease(numSelector); - CFArrayAppendValue(outerArray, innerDict); - CFRelease(innerDict); // and likewise for CFArray - - CFDictionaryAddValue(attr, kCTFontFeatureSettingsAttribute, outerArray); - CFRelease(outerArray); -} -#endif - -// Named constants for these were NOT added until 10.11, and even then they were added as external symbols instead of macros, so we can't use them directly :( -// kode54 got these for me before I had access to El Capitan; thanks to him. -#define ourNSFontWeightUltraLight -0.800000 -#define ourNSFontWeightThin -0.600000 -#define ourNSFontWeightLight -0.400000 -#define ourNSFontWeightRegular 0.000000 -#define ourNSFontWeightMedium 0.230000 -#define ourNSFontWeightSemibold 0.300000 -#define ourNSFontWeightBold 0.400000 -#define ourNSFontWeightHeavy 0.560000 -#define ourNSFontWeightBlack 0.620000 -static const CGFloat ctWeights[] = { - // yeah these two have their names swapped; blame Pango - [uiDrawTextWeightThin] = ourNSFontWeightUltraLight, - [uiDrawTextWeightUltraLight] = ourNSFontWeightThin, - [uiDrawTextWeightLight] = ourNSFontWeightLight, - // for this one let's go between Light and Regular - // we're doing nearest so if there happens to be an exact value hopefully it's close enough - [uiDrawTextWeightBook] = ourNSFontWeightLight + ((ourNSFontWeightRegular - ourNSFontWeightLight) / 2), - [uiDrawTextWeightNormal] = ourNSFontWeightRegular, - [uiDrawTextWeightMedium] = ourNSFontWeightMedium, - [uiDrawTextWeightSemiBold] = ourNSFontWeightSemibold, - [uiDrawTextWeightBold] = ourNSFontWeightBold, - // for this one let's go between Bold and Heavy - [uiDrawTextWeightUltraBold] = ourNSFontWeightBold + ((ourNSFontWeightHeavy - ourNSFontWeightBold) / 2), - [uiDrawTextWeightHeavy] = ourNSFontWeightHeavy, - [uiDrawTextWeightUltraHeavy] = ourNSFontWeightBlack, -}; - -// Unfortunately there are still no named constants for these. -// Let's just use normalized widths. -// As far as I can tell (OS X only ships with condensed fonts, not expanded fonts; TODO), regardless of condensed or expanded, negative means condensed and positive means expanded. -// TODO verify this is correct -static const CGFloat ctStretches[] = { - [uiDrawTextStretchUltraCondensed] = -1.0, - [uiDrawTextStretchExtraCondensed] = -0.75, - [uiDrawTextStretchCondensed] = -0.5, - [uiDrawTextStretchSemiCondensed] = -0.25, - [uiDrawTextStretchNormal] = 0.0, - [uiDrawTextStretchSemiExpanded] = 0.25, - [uiDrawTextStretchExpanded] = 0.5, - [uiDrawTextStretchExtraExpanded] = 0.75, - [uiDrawTextStretchUltraExpanded] = 1.0, -}; - -struct closeness { - CFIndex index; - CGFloat weight; - CGFloat italic; - CGFloat stretch; - CGFloat distance; -}; - -// Stupidity: CTFont requires an **exact match for the entire traits dictionary**, otherwise it will **drop ALL the traits**. -// We have to implement the closest match ourselves. -// Also we have to do this before adding the small caps flags, because the matching descriptors won't have those. -CTFontDescriptorRef matchTraits(CTFontDescriptorRef against, uiDrawTextWeight weight, uiDrawTextItalic italic, uiDrawTextStretch stretch) -{ - CGFloat targetWeight; - CGFloat italicCloseness, obliqueCloseness, normalCloseness; - CGFloat targetStretch; - CFArrayRef matching; - CFIndex i, n; - struct closeness *closeness; - CTFontDescriptorRef current; - CTFontDescriptorRef out; - - targetWeight = ctWeights[weight]; - switch (italic) { - case uiDrawTextItalicNormal: - italicCloseness = 1; - obliqueCloseness = 1; - normalCloseness = 0; - break; - case uiDrawTextItalicOblique: - italicCloseness = 0.5; - obliqueCloseness = 0; - normalCloseness = 1; - break; - case uiDrawTextItalicItalic: - italicCloseness = 0; - obliqueCloseness = 0.5; - normalCloseness = 1; - break; - } - targetStretch = ctStretches[stretch]; - - matching = CTFontDescriptorCreateMatchingFontDescriptors(against, NULL); - if (matching == NULL) - // no matches; give the original back and hope for the best - return against; - n = CFArrayGetCount(matching); - if (n == 0) { - // likewise - CFRelease(matching); - return against; - } - - closeness = (struct closeness *) uiAlloc(n * sizeof (struct closeness), "struct closeness[]"); - for (i = 0; i < n; i++) { - CFDictionaryRef traits; - CFNumberRef cfnum; - CTFontSymbolicTraits symbolic; - - closeness[i].index = i; - - current = CFArrayGetValueAtIndex(matching, i); - traits = CTFontDescriptorCopyAttribute(current, kCTFontTraitsAttribute); - if (traits == NULL) { - // couldn't get traits; be safe by ranking it lowest - // LONGTERM figure out what the longest possible distances are - closeness[i].weight = 3; - closeness[i].italic = 2; - closeness[i].stretch = 3; - continue; - } - - symbolic = 0; // assume no symbolic traits if none are listed - cfnum = CFDictionaryGetValue(traits, kCTFontSymbolicTrait); - if (cfnum != NULL) { - SInt32 s; - - if (CFNumberGetValue(cfnum, kCFNumberSInt32Type, &s) == false) - complain("error getting symbolic traits in matchTraits()"); - symbolic = (CTFontSymbolicTraits) s; - // Get rule; do not release cfnum - } - - // now try weight - cfnum = CFDictionaryGetValue(traits, kCTFontWeightTrait); - if (cfnum != NULL) { - CGFloat val; - - // LONGTERM instead of complaining for this and width and possibly also symbolic traits above, should we just fall through to the default? - if (CFNumberGetValue(cfnum, kCFNumberCGFloatType, &val) == false) - complain("error getting weight value in matchTraits()"); - closeness[i].weight = val - targetWeight; - } else - // okay there's no weight key; let's try the literal meaning of the symbolic constant - // LONGTERM is the weight key guaranteed? - if ((symbolic & kCTFontBoldTrait) != 0) - closeness[i].weight = ourNSFontWeightBold - targetWeight; - else - closeness[i].weight = ourNSFontWeightRegular - targetWeight; - - // italics is a bit harder because Core Text doesn't expose a concept of obliqueness - // Pango just does a g_strrstr() (backwards case-sensitive search) for "Oblique" in the font's style name (see https://git.gnome.org/browse/pango/tree/pango/pangocoretext-fontmap.c); let's do that too I guess - if ((symbolic & kCTFontItalicTrait) != 0) - closeness[i].italic = italicCloseness; - else { - CFStringRef styleName; - BOOL isOblique; - - isOblique = NO; // default value - styleName = CTFontDescriptorCopyAttribute(current, kCTFontStyleNameAttribute); - if (styleName != NULL) { - CFRange range; - - // note the use of the toll-free bridge for the string literal, since CFSTR() *can* return NULL - range = CFStringFind(styleName, (CFStringRef) @"Oblique", kCFCompareBackwards); - if (range.location != kCFNotFound) - isOblique = YES; - CFRelease(styleName); - } - if (isOblique) - closeness[i].italic = obliqueCloseness; - else - closeness[i].italic = normalCloseness; - } - - // now try width - // TODO this does not seem to be enough for Skia's extended variants; the width trait is 0 but the Expanded flag is on - // TODO verify the rest of this matrix (what matrix?) - cfnum = CFDictionaryGetValue(traits, kCTFontWidthTrait); - if (cfnum != NULL) { - CGFloat val; - - if (CFNumberGetValue(cfnum, kCFNumberCGFloatType, &val) == false) - complain("error getting width value in matchTraits()"); - closeness[i].stretch = val - targetStretch; - } else - // okay there's no width key; let's try the literal meaning of the symbolic constant - // LONGTERM is the width key guaranteed? - if ((symbolic & kCTFontExpandedTrait) != 0) - closeness[i].stretch = 1.0 - targetStretch; - else if ((symbolic & kCTFontCondensedTrait) != 0) - closeness[i].stretch = -1.0 - targetStretch; - else - closeness[i].stretch = 0.0 - targetStretch; - - CFRelease(traits); - } - - // now figure out the 3-space difference between the three and sort by that - for (i = 0; i < n; i++) { - CGFloat weight, italic, stretch; - - weight = closeness[i].weight; - weight *= weight; - italic = closeness[i].italic; - italic *= italic; - stretch = closeness[i].stretch; - stretch *= stretch; - closeness[i].distance = sqrt(weight + italic + stretch); - } - qsort_b(closeness, n, sizeof (struct closeness), ^(const void *aa, const void *bb) { - const struct closeness *a = (const struct closeness *) aa; - const struct closeness *b = (const struct closeness *) bb; - - // via http://www.gnu.org/software/libc/manual/html_node/Comparison-Functions.html#Comparison-Functions - // LONGTERM is this really the best way? isn't it the same as if (*a < *b) return -1; if (*a > *b) return 1; return 0; ? - return (a->distance > b->distance) - (a->distance < b->distance); - }); - // and the first element of the sorted array is what we want - out = CFArrayGetValueAtIndex(matching, closeness[0].index); - CFRetain(out); // get rule - - // release everything - uiFree(closeness); - CFRelease(matching); - // and release the original descriptor since we no longer need it - CFRelease(against); - - return out; -} - -// Now remember what I said earlier about having to add the small caps traits after calling the above? This gets a dictionary back so we can do so. -CFMutableDictionaryRef extractAttributes(CTFontDescriptorRef desc) -{ - CFDictionaryRef dict; - CFMutableDictionaryRef mdict; - - dict = CTFontDescriptorCopyAttributes(desc); - // this might not be mutable, so make a mutable copy - mdict = CFDictionaryCreateMutableCopy(NULL, 0, dict); - CFRelease(dict); - return mdict; -} - -uiDrawTextFont *uiDrawLoadClosestFont(const uiDrawTextFontDescriptor *desc) -{ - CTFontRef f; - CFMutableDictionaryRef attr; - CTFontDescriptorRef cfdesc; - - attr = newAttrList(); - addFontFamilyAttr(attr, desc->Family); - addFontSizeAttr(attr, desc->Size); - - // now we have to do the traits matching, so create a descriptor, match the traits, and then get the attributes back - cfdesc = CTFontDescriptorCreateWithAttributes(attr); - // TODO release attr? - cfdesc = matchTraits(cfdesc, desc->Weight, desc->Italic, desc->Stretch); - - // specify the initial size again just to be safe - f = CTFontCreateWithFontDescriptor(cfdesc, desc->Size, NULL); - // TODO release cfdesc? - - return mkTextFont(f, NO); // we hold the initial reference; no need to retain again -} - -void uiDrawFreeTextFont(uiDrawTextFont *font) -{ - CFRelease(font->f); - uiFree(font); -} - -uintptr_t uiDrawTextFontHandle(uiDrawTextFont *font) -{ - return (uintptr_t) (font->f); -} - -void uiDrawTextFontDescribe(uiDrawTextFont *font, uiDrawTextFontDescriptor *desc) -{ - // TODO -} - -// text sizes and user space points are identical: -// - https://developer.apple.com/library/mac/documentation/TextFonts/Conceptual/CocoaTextArchitecture/TypoFeatures/TextSystemFeatures.html#//apple_ref/doc/uid/TP40009459-CH6-51627-BBCCHIFF text points are 72 per inch -// - https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Transforms/Transforms.html#//apple_ref/doc/uid/TP40003290-CH204-SW5 user space points are 72 per inch -void uiDrawTextFontGetMetrics(uiDrawTextFont *font, uiDrawTextFontMetrics *metrics) -{ - metrics->Ascent = CTFontGetAscent(font->f); - metrics->Descent = CTFontGetDescent(font->f); - metrics->Leading = CTFontGetLeading(font->f); - metrics->UnderlinePos = CTFontGetUnderlinePosition(font->f); - metrics->UnderlineThickness = CTFontGetUnderlineThickness(font->f); -} - -struct uiDrawTextLayout { - CFMutableAttributedStringRef mas; - CFRange *charsToRanges; - double width; -}; - -uiDrawTextLayout *uiDrawNewTextLayout(const char *str, uiDrawTextFont *defaultFont, double width) -{ - uiDrawTextLayout *layout; - CFAttributedStringRef immutable; - CFMutableDictionaryRef attr; - CFStringRef backing; - CFIndex i, j, n; - - layout = uiNew(uiDrawTextLayout); - - // TODO docs say we need to use a different set of key callbacks - // TODO see if the font attribute key callbacks need to be the same - attr = newAttrList(); - // this will retain defaultFont->f; no need to worry - CFDictionaryAddValue(attr, kCTFontAttributeName, defaultFont->f); - - immutable = CFAttributedStringCreate(NULL, (CFStringRef) [NSString stringWithUTF8String:str], attr); - if (immutable == NULL) - complain("error creating immutable attributed string in uiDrawNewTextLayout()"); - CFRelease(attr); - - layout->mas = CFAttributedStringCreateMutableCopy(NULL, 0, immutable); - if (layout->mas == NULL) - complain("error creating attributed string in uiDrawNewTextLayout()"); - CFRelease(immutable); - - uiDrawTextLayoutSetWidth(layout, width); - - // unfortunately the CFRanges for attributes expect UTF-16 codepoints - // we want graphemes - // fortunately CFStringGetRangeOfComposedCharactersAtIndex() is here for us - // https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Strings/Articles/stringsClusters.html says that this does work on all multi-codepoint graphemes (despite the name), and that this is the preferred function for this particular job anyway - backing = CFAttributedStringGetString(layout->mas); - n = CFStringGetLength(backing); - // allocate one extra, just to be safe - layout->charsToRanges = (CFRange *) uiAlloc((n + 1) * sizeof (CFRange), "CFRange[]"); - i = 0; - j = 0; - while (i < n) { - CFRange range; - - range = CFStringGetRangeOfComposedCharactersAtIndex(backing, i); - i = range.location + range.length; - layout->charsToRanges[j] = range; - j++; - } - // and set the last one - layout->charsToRanges[j].location = i; - layout->charsToRanges[j].length = 0; - - return layout; -} - -void uiDrawFreeTextLayout(uiDrawTextLayout *layout) -{ - uiFree(layout->charsToRanges); - CFRelease(layout->mas); - uiFree(layout); -} - -void uiDrawTextLayoutSetWidth(uiDrawTextLayout *layout, double width) -{ - layout->width = width; -} - -struct framesetter { - CTFramesetterRef fs; - CFMutableDictionaryRef frameAttrib; - CGSize extents; -}; - -// TODO CTFrameProgression for RTL/LTR -// TODO kCTParagraphStyleSpecifierMaximumLineSpacing, kCTParagraphStyleSpecifierMinimumLineSpacing, kCTParagraphStyleSpecifierLineSpacingAdjustment for line spacing -static void mkFramesetter(uiDrawTextLayout *layout, struct framesetter *fs) -{ - CFRange fitRange; - CGFloat width; - - fs->fs = CTFramesetterCreateWithAttributedString(layout->mas); - if (fs->fs == NULL) - complain("error creating CTFramesetter object in mkFramesetter()"); - - // TODO kCTFramePathWidthAttributeName? - fs->frameAttrib = NULL; - - width = layout->width; - if (layout->width < 0) - width = CGFLOAT_MAX; - // TODO these seem to be floor()'d or truncated? - fs->extents = CTFramesetterSuggestFrameSizeWithConstraints(fs->fs, - CFRangeMake(0, 0), - fs->frameAttrib, - CGSizeMake(width, CGFLOAT_MAX), - &fitRange); // not documented as accepting NULL -} - -static void freeFramesetter(struct framesetter *fs) -{ - if (fs->frameAttrib != NULL) - CFRelease(fs->frameAttrib); - CFRelease(fs->fs); -} - -// LONGTERM allow line separation and leading to be factored into a wrapping text layout - -// TODO reconcile differences in character wrapping on platforms -void uiDrawTextLayoutExtents(uiDrawTextLayout *layout, double *width, double *height) -{ - struct framesetter fs; - - mkFramesetter(layout, &fs); - *width = fs.extents.width; - *height = fs.extents.height; - freeFramesetter(&fs); -} - -// Core Text doesn't draw onto a flipped view correctly; we have to do this -// see the iOS bits of the first example at https://developer.apple.com/library/mac/documentation/StringsTextFonts/Conceptual/CoreText_Programming/LayoutOperations/LayoutOperations.html#//apple_ref/doc/uid/TP40005533-CH12-SW1 (iOS is naturally flipped) -// TODO how is this affected by the CTM? -static void prepareContextForText(CGContextRef c, CGFloat cheight, double *y) -{ - CGContextSaveGState(c); - CGContextTranslateCTM(c, 0, cheight); - CGContextScaleCTM(c, 1.0, -1.0); - CGContextSetTextMatrix(c, CGAffineTransformIdentity); - - // wait, that's not enough; we need to offset y values to account for our new flipping - *y = cheight - *y; -} - -// TODO placement is incorrect for Helvetica -void doDrawText(CGContextRef c, CGFloat cheight, double x, double y, uiDrawTextLayout *layout) -{ - struct framesetter fs; - CGRect rect; - CGPathRef path; - CTFrameRef frame; - - prepareContextForText(c, cheight, &y); - mkFramesetter(layout, &fs); - - // oh, and since we're flipped, y is the bottom-left coordinate of the rectangle, not the top-left - // since we are flipped, we subtract - y -= fs.extents.height; - - rect.origin = CGPointMake(x, y); - rect.size = fs.extents; - path = CGPathCreateWithRect(rect, NULL); - - frame = CTFramesetterCreateFrame(fs.fs, - CFRangeMake(0, 0), - path, - fs.frameAttrib); - if (frame == NULL) - complain("error creating CTFrame object in doDrawText()"); - CTFrameDraw(frame, c); - CFRelease(frame); - - CFRelease(path); - - freeFramesetter(&fs); - CGContextRestoreGState(c); -} - -// LONGTERM provide an equivalent to CTLineGetTypographicBounds() on uiDrawTextLayout? - -// LONGTERM keep this for later features and documentation purposes -#if 0 - w = CTLineGetTypographicBounds(line, &ascent, &descent, NULL); - // though CTLineGetTypographicBounds() returns 0 on error, it also returns 0 on an empty string, so we can't reasonably check for error - CFRelease(line); - - // LONGTERM provide a way to get the image bounds as a separate function later - bounds = CTLineGetImageBounds(line, c); - // though CTLineGetImageBounds() returns CGRectNull on error, it also returns CGRectNull on an empty string, so we can't reasonably check for error - - // CGContextSetTextPosition() positions at the baseline in the case of CTLineDraw(); we need the top-left corner instead - CTLineGetTypographicBounds(line, &yoff, NULL, NULL); - // remember that we're flipped, so we subtract - y -= yoff; - CGContextSetTextPosition(c, x, y); -#endif - -static CFRange charsToRange(uiDrawTextLayout *layout, int startChar, int endChar) -{ - CFRange start, end; - CFRange out; - - start = layout->charsToRanges[startChar]; - end = layout->charsToRanges[endChar]; - out.location = start.location; - out.length = end.location - start.location; - return out; -} - -#define rangeToCFRange() charsToRange(layout, startChar, endChar) - -void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, int startChar, int endChar, double r, double g, double b, double a) -{ - CGColorSpaceRef colorspace; - CGFloat components[4]; - CGColorRef color; - - // for consistency with windows, use sRGB - colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); - components[0] = r; - components[1] = g; - components[2] = b; - components[3] = a; - color = CGColorCreate(colorspace, components); - CGColorSpaceRelease(colorspace); - - CFAttributedStringSetAttribute(layout->mas, - rangeToCFRange(), - kCTForegroundColorAttributeName, - color); - CGColorRelease(color); // TODO safe? -} diff --git a/deps/libui/darwin/editablecombo.m b/deps/libui/darwin/editablecombo.m deleted file mode 100644 index 434add70f2..0000000000 --- a/deps/libui/darwin/editablecombo.m +++ /dev/null @@ -1,185 +0,0 @@ -// 14 august 2015 -#import "uipriv_darwin.h" - -// So why did I split uiCombobox into uiCombobox and uiEditableCombobox? Here's (90% of the; the other 10% is GTK+ events) answer: -// When you type a value into a NSComboBox that just happens to be in the list, it will autoselect that item! -// I can't seem to find a workaround. -// Fortunately, there's other weird behaviors that made this split worth it. -// And besides, selected items make little sense with editable comboboxes... you either separate or combine them with the text entry :V - -// NSComboBoxes have no intrinsic width; we'll use the default Interface Builder width for them. -#define comboboxWidth 96 - -@interface libui_intrinsicWidthNSComboBox : NSComboBox -@end - -@implementation libui_intrinsicWidthNSComboBox - -- (NSSize)intrinsicContentSize -{ - NSSize s; - - s = [super intrinsicContentSize]; - s.width = comboboxWidth; - return s; -} - -@end - -struct uiEditableCombobox { - uiDarwinControl c; - NSComboBox *cb; - void (*onChanged)(uiEditableCombobox *, void *); - void *onChangedData; -}; - -@interface editableComboboxDelegateClass : NSObject { - struct mapTable *comboboxes; -} -- (void)controlTextDidChange:(NSNotification *)note; -- (void)comboBoxSelectionDidChange:(NSNotification *)note; -- (void)registerCombobox:(uiEditableCombobox *)c; -- (void)unregisterCombobox:(uiEditableCombobox *)c; -@end - -@implementation editableComboboxDelegateClass - -- (id)init -{ - self = [super init]; - if (self) - self->comboboxes = newMap(); - return self; -} - -- (void)dealloc -{ - mapDestroy(self->comboboxes); - [super dealloc]; -} - -- (void)controlTextDidChange:(NSNotification *)note -{ - uiEditableCombobox *c; - - c = uiEditableCombobox(mapGet(self->comboboxes, [note object])); - (*(c->onChanged))(c, c->onChangedData); -} - -// the above doesn't handle when an item is selected; this will -- (void)comboBoxSelectionDidChange:(NSNotification *)note -{ - // except this is sent BEFORE the entry is changed, and that doesn't send the above, so - // this is via http://stackoverflow.com/a/21059819/3408572 - it avoids the need to manage selected items - // this still isn't perfect — I get residual changes to the same value while navigating the list — but it's good enough - [self performSelector:@selector(controlTextDidChange:) - withObject:note - afterDelay:0]; -} - -- (void)registerCombobox:(uiEditableCombobox *)c -{ - mapSet(self->comboboxes, c->cb, c); - [c->cb setDelegate:self]; -} - -- (void)unregisterCombobox:(uiEditableCombobox *)c -{ - [c->cb setDelegate:nil]; - mapDelete(self->comboboxes, c->cb); -} - -@end - -static editableComboboxDelegateClass *comboboxDelegate = nil; - -uiDarwinControlAllDefaultsExceptDestroy(uiEditableCombobox, cb) - -static void uiEditableComboboxDestroy(uiControl *cc) -{ - uiEditableCombobox *c = uiEditableCombobox(cc); - - [comboboxDelegate unregisterCombobox:c]; - [c->cb release]; - uiFreeControl(uiControl(c)); -} - -void uiEditableComboboxAppend(uiEditableCombobox *c, const char *text) -{ - [c->cb addItemWithObjectValue:toNSString(text)]; -} - -char *uiEditableComboboxText(uiEditableCombobox *c) -{ - return uiDarwinNSStringToText([c->cb stringValue]); -} - -void uiEditableComboboxSetText(uiEditableCombobox *c, const char *text) -{ - NSString *t; - - t = toNSString(text); - [c->cb setStringValue:t]; - // yes, let's imitate the behavior that caused uiEditableCombobox to be separate in the first place! - // just to avoid confusion when users see an option in the list in the text field but not selected in the list - [c->cb selectItemWithObjectValue:t]; -} - -#if 0 -// LONGTERM -void uiEditableComboboxSetSelected(uiEditableCombobox *c, int n) -{ - if (c->editable) { - // see https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ComboBox/Tasks/SettingComboBoxValue.html#//apple_ref/doc/uid/20000256 - id delegate; - - // this triggers the delegate; turn it off for now - delegate = [c->cb delegate]; - [c->cb setDelegate:nil]; - - // this seems to work fine for -1 too - [c->cb selectItemAtIndex:n]; - if (n == -1) - [c->cb setObjectValue:@""]; - else - [c->cb setObjectValue:[c->cb objectValueOfSelectedItem]]; - - [c->cb setDelegate:delegate]; - return; - } - [c->pb selectItemAtIndex:n]; -} -#endif - -void uiEditableComboboxOnChanged(uiEditableCombobox *c, void (*f)(uiEditableCombobox *c, void *data), void *data) -{ - c->onChanged = f; - c->onChangedData = data; -} - -static void defaultOnChanged(uiEditableCombobox *c, void *data) -{ - // do nothing -} - -uiEditableCombobox *uiNewEditableCombobox(void) -{ - uiEditableCombobox *c; - - uiDarwinNewControl(uiEditableCombobox, c); - - c->cb = [[libui_intrinsicWidthNSComboBox alloc] initWithFrame:NSZeroRect]; - [c->cb setUsesDataSource:NO]; - [c->cb setButtonBordered:YES]; - [c->cb setCompletes:NO]; - uiDarwinSetControlFont(c->cb, NSRegularControlSize); - - if (comboboxDelegate == nil) { - comboboxDelegate = [[editableComboboxDelegateClass new] autorelease]; - [delegates addObject:comboboxDelegate]; - } - [comboboxDelegate registerCombobox:c]; - uiEditableComboboxOnChanged(c, defaultOnChanged, NULL); - - return c; -} diff --git a/deps/libui/darwin/entry.m b/deps/libui/darwin/entry.m deleted file mode 100644 index 219d080576..0000000000 --- a/deps/libui/darwin/entry.m +++ /dev/null @@ -1,251 +0,0 @@ -// 14 august 2015 -#import "uipriv_darwin.h" - -// Text fields for entering text have no intrinsic width; we'll use the default Interface Builder width for them. -#define textfieldWidth 96 - -@interface libui_intrinsicWidthNSTextField : NSTextField -@end - -@implementation libui_intrinsicWidthNSTextField - -- (NSSize)intrinsicContentSize -{ - NSSize s; - - s = [super intrinsicContentSize]; - s.width = textfieldWidth; - return s; -} - -@end - -// TODO does this have one on its own? -@interface libui_intrinsicWidthNSSecureTextField : NSSecureTextField -@end - -@implementation libui_intrinsicWidthNSSecureTextField - -- (NSSize)intrinsicContentSize -{ - NSSize s; - - s = [super intrinsicContentSize]; - s.width = textfieldWidth; - return s; -} - -@end - -// TODO does this have one on its own? -@interface libui_intrinsicWidthNSSearchField : NSSearchField -@end - -@implementation libui_intrinsicWidthNSSearchField - -- (NSSize)intrinsicContentSize -{ - NSSize s; - - s = [super intrinsicContentSize]; - s.width = textfieldWidth; - return s; -} - -@end - -struct uiEntry { - uiDarwinControl c; - NSTextField *textfield; - void (*onChanged)(uiEntry *, void *); - void *onChangedData; -}; - -static BOOL isSearchField(NSTextField *tf) -{ - return [tf isKindOfClass:[NSSearchField class]]; -} - -@interface entryDelegateClass : NSObject { - struct mapTable *entries; -} -- (void)controlTextDidChange:(NSNotification *)note; -- (IBAction)onSearch:(id)sender; -- (void)registerEntry:(uiEntry *)e; -- (void)unregisterEntry:(uiEntry *)e; -@end - -@implementation entryDelegateClass - -- (id)init -{ - self = [super init]; - if (self) - self->entries = newMap(); - return self; -} - -- (void)dealloc -{ - mapDestroy(self->entries); - [super dealloc]; -} - -- (void)controlTextDidChange:(NSNotification *)note -{ - [self onSearch:[note object]]; -} - -- (IBAction)onSearch:(id)sender -{ - uiEntry *e; - - e = (uiEntry *) mapGet(self->entries, sender); - (*(e->onChanged))(e, e->onChangedData); -} - -- (void)registerEntry:(uiEntry *)e -{ - mapSet(self->entries, e->textfield, e); - if (isSearchField(e->textfield)) { - [e->textfield setTarget:self]; - [e->textfield setAction:@selector(onSearch:)]; - } else - [e->textfield setDelegate:self]; -} - -- (void)unregisterEntry:(uiEntry *)e -{ - if (isSearchField(e->textfield)) - [e->textfield setTarget:nil]; - else - [e->textfield setDelegate:nil]; - mapDelete(self->entries, e->textfield); -} - -@end - -static entryDelegateClass *entryDelegate = nil; - -uiDarwinControlAllDefaultsExceptDestroy(uiEntry, textfield) - -static void uiEntryDestroy(uiControl *c) -{ - uiEntry *e = uiEntry(c); - - [entryDelegate unregisterEntry:e]; - [e->textfield release]; - uiFreeControl(uiControl(e)); -} - -char *uiEntryText(uiEntry *e) -{ - return uiDarwinNSStringToText([e->textfield stringValue]); -} - -void uiEntrySetText(uiEntry *e, const char *text) -{ - [e->textfield setStringValue:toNSString(text)]; - // don't queue the control for resize; entry sizes are independent of their contents -} - -void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *, void *), void *data) -{ - e->onChanged = f; - e->onChangedData = data; -} - -int uiEntryReadOnly(uiEntry *e) -{ - return [e->textfield isEditable] == NO; -} - -void uiEntrySetReadOnly(uiEntry *e, int readonly) -{ - BOOL editable; - - editable = YES; - if (readonly) - editable = NO; - [e->textfield setEditable:editable]; -} - -static void defaultOnChanged(uiEntry *e, void *data) -{ - // do nothing -} - -// these are based on interface builder defaults; my comments in the old code weren't very good so I don't really know what talked about what, sorry :/ -void finishNewTextField(NSTextField *t, BOOL isEntry) -{ - uiDarwinSetControlFont(t, NSRegularControlSize); - - // THE ORDER OF THESE CALLS IS IMPORTANT; CHANGE IT AND THE BORDERS WILL DISAPPEAR - [t setBordered:NO]; - [t setBezelStyle:NSTextFieldSquareBezel]; - [t setBezeled:isEntry]; - - // we don't need to worry about substitutions/autocorrect here; see window_darwin.m for details - - [[t cell] setLineBreakMode:NSLineBreakByClipping]; - [[t cell] setScrollable:YES]; -} - -static NSTextField *realNewEditableTextField(Class class) -{ - NSTextField *tf; - - tf = [[class alloc] initWithFrame:NSZeroRect]; - [tf setSelectable:YES]; // otherwise the setting is masked by the editable default of YES - finishNewTextField(tf, YES); - return tf; -} - -NSTextField *newEditableTextField(void) -{ - return realNewEditableTextField([libui_intrinsicWidthNSTextField class]); -} - -static uiEntry *finishNewEntry(Class class) -{ - uiEntry *e; - - uiDarwinNewControl(uiEntry, e); - - e->textfield = realNewEditableTextField(class); - - if (entryDelegate == nil) { - entryDelegate = [[entryDelegateClass new] autorelease]; - [delegates addObject:entryDelegate]; - } - [entryDelegate registerEntry:e]; - uiEntryOnChanged(e, defaultOnChanged, NULL); - - return e; -} - -uiEntry *uiNewEntry(void) -{ - return finishNewEntry([libui_intrinsicWidthNSTextField class]); -} - -uiEntry *uiNewPasswordEntry(void) -{ - return finishNewEntry([libui_intrinsicWidthNSSecureTextField class]); -} - -uiEntry *uiNewSearchEntry(void) -{ - uiEntry *e; - NSSearchField *s; - - e = finishNewEntry([libui_intrinsicWidthNSSearchField class]); - s = (NSSearchField *) (e->textfield); - // TODO these are only on 10.10 -// [s setSendsSearchStringImmediately:NO]; -// [s setSendsWholeSearchString:NO]; - [s setBordered:NO]; - [s setBezelStyle:NSTextFieldRoundedBezel]; - [s setBezeled:YES]; - return e; -} diff --git a/deps/libui/darwin/fontbutton.m b/deps/libui/darwin/fontbutton.m deleted file mode 100644 index 22bc64659b..0000000000 --- a/deps/libui/darwin/fontbutton.m +++ /dev/null @@ -1,218 +0,0 @@ -// 14 april 2016 -#import "uipriv_darwin.h" - -@interface fontButton : NSButton { - uiFontButton *libui_b; - NSFont *libui_font; -} -- (id)initWithFrame:(NSRect)frame libuiFontButton:(uiFontButton *)b; -- (void)updateFontButtonLabel; -- (IBAction)fontButtonClicked:(id)sender; -- (void)activateFontButton; -- (void)deactivateFontButton:(BOOL)activatingAnother; -- (void)deactivateOnClose:(NSNotification *)note; -- (uiDrawTextFont *)libuiFont; -@end - -// only one may be active at one time -static fontButton *activeFontButton = nil; - -struct uiFontButton { - uiDarwinControl c; - fontButton *button; - void (*onChanged)(uiFontButton *, void *); - void *onChangedData; -}; - -@implementation fontButton - -- (id)initWithFrame:(NSRect)frame libuiFontButton:(uiFontButton *)b -{ - self = [super initWithFrame:frame]; - if (self) { - self->libui_b = b; - - // imitate a NSColorWell in appearance - [self setButtonType:NSPushOnPushOffButton]; - [self setBordered:YES]; - [self setBezelStyle:NSShadowlessSquareBezelStyle]; - - // default font values according to the CTFontDescriptor reference - // this is autoreleased (thanks swillits in irc.freenode.net/#macdev) - self->libui_font = [[NSFont fontWithName:@"Helvetica" size:12.0] retain]; - [self updateFontButtonLabel]; - - // for when clicked - [self setTarget:self]; - [self setAction:@selector(fontButtonClicked:)]; - } - return self; -} - -- (void)dealloc -{ - // clean up notifications - if (activeFontButton == self) - [self deactivateFontButton:NO]; - [self->libui_font release]; - [super dealloc]; -} - -- (void)updateFontButtonLabel -{ - NSString *title; - - title = [NSString stringWithFormat:@"%@ %g", - [self->libui_font displayName], - [self->libui_font pointSize]]; - [self setTitle:title]; -} - -- (IBAction)fontButtonClicked:(id)sender -{ - if ([self state] == NSOnState) - [self activateFontButton]; - else - [self deactivateFontButton:NO]; -} - -- (void)activateFontButton -{ - NSFontManager *sfm; - - sfm = [NSFontManager sharedFontManager]; - if (activeFontButton != nil) - [activeFontButton deactivateFontButton:YES]; - [sfm setTarget:self]; - [sfm setSelectedFont:self->libui_font isMultiple:NO]; - [sfm orderFrontFontPanel:self]; - activeFontButton = self; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(deactivateOnClose:) - name:NSWindowWillCloseNotification - object:[NSFontPanel sharedFontPanel]]; - [self setState:NSOnState]; -} - -- (void)deactivateFontButton:(BOOL)activatingAnother -{ - NSFontManager *sfm; - - sfm = [NSFontManager sharedFontManager]; - [sfm setTarget:nil]; - if (!activatingAnother) - [[NSFontPanel sharedFontPanel] orderOut:self]; - activeFontButton = nil; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:NSWindowWillCloseNotification - object:[NSFontPanel sharedFontPanel]]; - [self setState:NSOffState]; -} - -- (void)deactivateOnClose:(NSNotification *)note -{ - [self deactivateFontButton:NO]; -} - -- (void)changeFont:(id)sender -{ - NSFontManager *fm; - NSFont *old; - uiFontButton *b = self->libui_b; - - fm = (NSFontManager *) sender; - old = self->libui_font; - self->libui_font = [sender convertFont:self->libui_font]; - // do this even if it returns the same; we don't own anything that isn't from a new or alloc/init - [self->libui_font retain]; - // do this second just in case - [old release]; - [self updateFontButtonLabel]; - (*(b->onChanged))(b, b->onChangedData); -} - -- (NSUInteger)validModesForFontPanel:(NSFontPanel *)panel -{ - return NSFontPanelFaceModeMask | - NSFontPanelSizeModeMask | - NSFontPanelCollectionModeMask; -} - -- (uiDrawTextFont *)libuiFont -{ - return mkTextFontFromNSFont(self->libui_font); -} - -@end - -uiDarwinControlAllDefaults(uiFontButton, button) - -// we do not want font change events to be sent to any controls other than the font buttons -// see main.m for more details -BOOL fontButtonInhibitSendAction(SEL sel, id from, id to) -{ - if (sel != @selector(changeFont:)) - return NO; - return ![to isKindOfClass:[fontButton class]]; -} - -// we do not want NSFontPanelValidation messages to be sent to any controls other than the font buttons when a font button is active -// see main.m for more details -BOOL fontButtonOverrideTargetForAction(SEL sel, id from, id to, id *override) -{ - if (activeFontButton == nil) - return NO; - if (sel != @selector(validModesForFontPanel:)) - return NO; - *override = activeFontButton; - return YES; -} - -// we also don't want the panel to be usable when there's a dialog running; see stddialogs.m for more details on that -// unfortunately the panel seems to ignore -setWorksWhenModal: so we'll have to do things ourselves -@interface nonModalFontPanel : NSFontPanel -@end - -@implementation nonModalFontPanel - -- (BOOL)worksWhenModal -{ - return NO; -} - -@end - -void setupFontPanel(void) -{ - [NSFontManager setFontPanelFactory:[nonModalFontPanel class]]; -} - -static void defaultOnChanged(uiFontButton *b, void *data) -{ - // do nothing -} - -uiDrawTextFont *uiFontButtonFont(uiFontButton *b) -{ - return [b->button libuiFont]; -} - -void uiFontButtonOnChanged(uiFontButton *b, void (*f)(uiFontButton *, void *), void *data) -{ - b->onChanged = f; - b->onChangedData = data; -} - -uiFontButton *uiNewFontButton(void) -{ - uiFontButton *b; - - uiDarwinNewControl(uiFontButton, b); - - b->button = [[fontButton alloc] initWithFrame:NSZeroRect libuiFontButton:b]; - uiDarwinSetControlFont(b->button, NSRegularControlSize); - - uiFontButtonOnChanged(b, defaultOnChanged, NULL); - - return b; -} diff --git a/deps/libui/darwin/form.m b/deps/libui/darwin/form.m deleted file mode 100644 index 7cdb965a90..0000000000 --- a/deps/libui/darwin/form.m +++ /dev/null @@ -1,561 +0,0 @@ -// 7 june 2016 -#import "uipriv_darwin.h" - -// TODO in the test program, sometimes one of the radio buttons can disappear (try when spaced) - -@interface formChild : NSView -@property uiControl *c; -@property (strong) NSTextField *label; -@property BOOL stretchy; -@property NSLayoutPriority oldHorzHuggingPri; -@property NSLayoutPriority oldVertHuggingPri; -@property (strong) NSLayoutConstraint *baseline; -@property (strong) NSLayoutConstraint *leading; -@property (strong) NSLayoutConstraint *top; -@property (strong) NSLayoutConstraint *trailing; -@property (strong) NSLayoutConstraint *bottom; -- (id)initWithLabel:(NSTextField *)l; -- (void)onDestroy; -- (NSView *)view; -@end - -@interface formView : NSView { - uiForm *f; - NSMutableArray *children; - int padded; - - NSLayoutConstraint *first; - NSMutableArray *inBetweens; - NSLayoutConstraint *last; - NSMutableArray *widths; - NSMutableArray *leadings; - NSMutableArray *middles; - NSMutableArray *trailings; -} -- (id)initWithF:(uiForm *)ff; -- (void)onDestroy; -- (void)removeOurConstraints; -- (void)syncEnableStates:(int)enabled; -- (CGFloat)paddingAmount; -- (void)establishOurConstraints; -- (void)append:(NSString *)label c:(uiControl *)c stretchy:(int)stretchy; -- (void)delete:(int)n; -- (int)isPadded; -- (void)setPadded:(int)p; -- (BOOL)hugsTrailing; -- (BOOL)hugsBottom; -- (int)nStretchy; -@end - -struct uiForm { - uiDarwinControl c; - formView *view; -}; - -@implementation formChild - -- (id)initWithLabel:(NSTextField *)l -{ - self = [super initWithFrame:NSZeroRect]; - if (self) { - self.label = l; - [self.label setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self.label setContentHuggingPriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal]; - [self.label setContentHuggingPriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationVertical]; - [self.label setContentCompressionResistancePriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal]; - [self.label setContentCompressionResistancePriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationVertical]; - [self addSubview:self.label]; - - self.leading = mkConstraint(self.label, NSLayoutAttributeLeading, - NSLayoutRelationGreaterThanOrEqual, - self, NSLayoutAttributeLeading, - 1, 0, - @"uiForm label leading"); - [self addConstraint:self.leading]; - self.top = mkConstraint(self.label, NSLayoutAttributeTop, - NSLayoutRelationEqual, - self, NSLayoutAttributeTop, - 1, 0, - @"uiForm label top"); - [self addConstraint:self.top]; - self.trailing = mkConstraint(self.label, NSLayoutAttributeTrailing, - NSLayoutRelationEqual, - self, NSLayoutAttributeTrailing, - 1, 0, - @"uiForm label trailing"); - [self addConstraint:self.trailing]; - self.bottom = mkConstraint(self.label, NSLayoutAttributeBottom, - NSLayoutRelationEqual, - self, NSLayoutAttributeBottom, - 1, 0, - @"uiForm label bottom"); - [self addConstraint:self.bottom]; - } - return self; -} - -- (void)onDestroy -{ - [self removeConstraint:self.trailing]; - self.trailing = nil; - [self removeConstraint:self.top]; - self.top = nil; - [self removeConstraint:self.bottom]; - self.bottom = nil; - - [self.label removeFromSuperview]; - self.label = nil; -} - -- (NSView *)view -{ - return (NSView *) uiControlHandle(self.c); -} - -@end - -@implementation formView - -- (id)initWithF:(uiForm *)ff -{ - self = [super initWithFrame:NSZeroRect]; - if (self != nil) { - self->f = ff; - self->padded = 0; - self->children = [NSMutableArray new]; - - self->inBetweens = [NSMutableArray new]; - self->widths = [NSMutableArray new]; - self->leadings = [NSMutableArray new]; - self->middles = [NSMutableArray new]; - self->trailings = [NSMutableArray new]; - } - return self; -} - -- (void)onDestroy -{ - formChild *fc; - - [self removeOurConstraints]; - [self->inBetweens release]; - [self->widths release]; - [self->leadings release]; - [self->middles release]; - [self->trailings release]; - - for (fc in self->children) { - [self removeConstraint:fc.baseline]; - fc.baseline = nil; - uiControlSetParent(fc.c, NULL); - uiDarwinControlSetSuperview(uiDarwinControl(fc.c), nil); - uiControlDestroy(fc.c); - [fc onDestroy]; - [fc removeFromSuperview]; - } - [self->children release]; -} - -- (void)removeOurConstraints -{ - if (self->first != nil) { - [self removeConstraint:self->first]; - [self->first release]; - self->first = nil; - } - if ([self->inBetweens count] != 0) { - [self removeConstraints:self->inBetweens]; - [self->inBetweens removeAllObjects]; - } - if (self->last != nil) { - [self removeConstraint:self->last]; - [self->last release]; - self->last = nil; - } - if ([self->widths count] != 0) { - [self removeConstraints:self->widths]; - [self->widths removeAllObjects]; - } - if ([self->leadings count] != 0) { - [self removeConstraints:self->leadings]; - [self->leadings removeAllObjects]; - } - if ([self->middles count] != 0) { - [self removeConstraints:self->middles]; - [self->middles removeAllObjects]; - } - if ([self->trailings count] != 0) { - [self removeConstraints:self->trailings]; - [self->trailings removeAllObjects]; - } -} - -- (void)syncEnableStates:(int)enabled -{ - formChild *fc; - - for (fc in self->children) - uiDarwinControlSyncEnableState(uiDarwinControl(fc.c), enabled); -} - -- (CGFloat)paddingAmount -{ - if (!self->padded) - return 0.0; - return uiDarwinPaddingAmount(NULL); -} - -- (void)establishOurConstraints -{ - formChild *fc; - CGFloat padding; - NSView *prev, *prevlabel; - NSLayoutConstraint *c; - - [self removeOurConstraints]; - if ([self->children count] == 0) - return; - padding = [self paddingAmount]; - - // first arrange the children vertically and make them the same width - prev = nil; - for (fc in self->children) { - [fc setHidden:!uiControlVisible(fc.c)]; - if (!uiControlVisible(fc.c)) - continue; - if (prev == nil) { // first view - self->first = mkConstraint(self, NSLayoutAttributeTop, - NSLayoutRelationEqual, - [fc view], NSLayoutAttributeTop, - 1, 0, - @"uiForm first vertical constraint"); - [self addConstraint:self->first]; - [self->first retain]; - prev = [fc view]; - prevlabel = fc; - continue; - } - // not the first; link it - c = mkConstraint(prev, NSLayoutAttributeBottom, - NSLayoutRelationEqual, - [fc view], NSLayoutAttributeTop, - 1, -padding, - @"uiForm in-between vertical constraint"); - [self addConstraint:c]; - [self->inBetweens addObject:c]; - // and make the same width - c = mkConstraint(prev, NSLayoutAttributeWidth, - NSLayoutRelationEqual, - [fc view], NSLayoutAttributeWidth, - 1, 0, - @"uiForm control width constraint"); - [self addConstraint:c]; - [self->widths addObject:c]; - c = mkConstraint(prevlabel, NSLayoutAttributeWidth, - NSLayoutRelationEqual, - fc, NSLayoutAttributeWidth, - 1, 0, - @"uiForm label lwidth constraint"); - [self addConstraint:c]; - [self->widths addObject:c]; - prev = [fc view]; - prevlabel = fc; - } - if (prev == nil) // all hidden; act as if nothing there - return; - self->last = mkConstraint(prev, NSLayoutAttributeBottom, - NSLayoutRelationEqual, - self, NSLayoutAttributeBottom, - 1, 0, - @"uiForm last vertical constraint"); - [self addConstraint:self->last]; - [self->last retain]; - - // now arrange the controls horizontally - for (fc in self->children) { - if (!uiControlVisible(fc.c)) - continue; - c = mkConstraint(self, NSLayoutAttributeLeading, - NSLayoutRelationEqual, - fc, NSLayoutAttributeLeading, - 1, 0, - @"uiForm leading constraint"); - [self addConstraint:c]; - [self->leadings addObject:c]; - // coerce the control to be as wide as possible - // see http://stackoverflow.com/questions/37710892/in-auto-layout-i-set-up-labels-that-shouldnt-grow-horizontally-and-controls-th - c = mkConstraint(self, NSLayoutAttributeLeading, - NSLayoutRelationEqual, - [fc view], NSLayoutAttributeLeading, - 1, 0, - @"uiForm leading constraint"); - [c setPriority:NSLayoutPriorityDefaultHigh]; - [self addConstraint:c]; - [self->leadings addObject:c]; - c = mkConstraint(fc, NSLayoutAttributeTrailing, - NSLayoutRelationEqual, - [fc view], NSLayoutAttributeLeading, - 1, -padding, - @"uiForm middle constraint"); - [self addConstraint:c]; - [self->middles addObject:c]; - c = mkConstraint([fc view], NSLayoutAttributeTrailing, - NSLayoutRelationEqual, - self, NSLayoutAttributeTrailing, - 1, 0, - @"uiForm trailing constraint"); - [self addConstraint:c]; - [self->trailings addObject:c]; - // TODO - c = mkConstraint(fc, NSLayoutAttributeBottom, - NSLayoutRelationLessThanOrEqual, - self, NSLayoutAttributeBottom, - 1, 0, - @"TODO"); - [self addConstraint:c]; - [self->trailings addObject:c]; - } - - // and make all stretchy controls have the same height - prev = nil; - for (fc in self->children) { - if (!uiControlVisible(fc.c)) - continue; - if (!fc.stretchy) - continue; - if (prev == nil) { - prev = [fc view]; - continue; - } - c = mkConstraint([fc view], NSLayoutAttributeHeight, - NSLayoutRelationEqual, - prev, NSLayoutAttributeHeight, - 1, 0, - @"uiForm stretchy constraint"); - [self addConstraint:c]; - // TODO make a dedicated array for this - [self->leadings addObject:c]; - } - - // we don't arrange the labels vertically; that's done when we add the control since those constraints don't need to change (they just need to be at their baseline) -} - -- (void)append:(NSString *)label c:(uiControl *)c stretchy:(int)stretchy -{ - formChild *fc; - NSLayoutPriority priority; - NSLayoutAttribute attribute; - int oldnStretchy; - - fc = [[formChild alloc] initWithLabel:newLabel(label)]; - fc.c = c; - fc.stretchy = stretchy; - fc.oldHorzHuggingPri = uiDarwinControlHuggingPriority(uiDarwinControl(fc.c), NSLayoutConstraintOrientationHorizontal); - fc.oldVertHuggingPri = uiDarwinControlHuggingPriority(uiDarwinControl(fc.c), NSLayoutConstraintOrientationVertical); - [fc setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self addSubview:fc]; - - uiControlSetParent(fc.c, uiControl(self->f)); - uiDarwinControlSetSuperview(uiDarwinControl(fc.c), self); - uiDarwinControlSyncEnableState(uiDarwinControl(fc.c), uiControlEnabledToUser(uiControl(self->f))); - - // if a control is stretchy, it should not hug vertically - // otherwise, it should *forcibly* hug - if (fc.stretchy) - priority = NSLayoutPriorityDefaultLow; - else - // LONGTERM will default high work? - priority = NSLayoutPriorityRequired; - uiDarwinControlSetHuggingPriority(uiDarwinControl(fc.c), priority, NSLayoutConstraintOrientationVertical); - // make sure controls don't hug their horizontal direction so they fill the width of the view - uiDarwinControlSetHuggingPriority(uiDarwinControl(fc.c), NSLayoutPriorityDefaultLow, NSLayoutConstraintOrientationHorizontal); - - // and constrain the baselines to position the label vertically - // if the view is a scroll view, align tops, not baselines - // this is what Interface Builder does - attribute = NSLayoutAttributeBaseline; - if ([[fc view] isKindOfClass:[NSScrollView class]]) - attribute = NSLayoutAttributeTop; - fc.baseline = mkConstraint(fc.label, attribute, - NSLayoutRelationEqual, - [fc view], attribute, - 1, 0, - @"uiForm baseline constraint"); - [self addConstraint:fc.baseline]; - - oldnStretchy = [self nStretchy]; - [self->children addObject:fc]; - - [self establishOurConstraints]; - if (fc.stretchy) - if (oldnStretchy == 0) - uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(self->f)); - - [fc release]; // we don't need the initial reference now -} - -- (void)delete:(int)n -{ - formChild *fc; - int stretchy; - - fc = (formChild *) [self->children objectAtIndex:n]; - stretchy = fc.stretchy; - - uiControlSetParent(fc.c, NULL); - uiDarwinControlSetSuperview(uiDarwinControl(fc.c), nil); - - uiDarwinControlSetHuggingPriority(uiDarwinControl(fc.c), fc.oldHorzHuggingPri, NSLayoutConstraintOrientationHorizontal); - uiDarwinControlSetHuggingPriority(uiDarwinControl(fc.c), fc.oldVertHuggingPri, NSLayoutConstraintOrientationVertical); - - [fc onDestroy]; - [self->children removeObjectAtIndex:n]; - - [self establishOurConstraints]; - if (stretchy) - if ([self nStretchy] == 0) - uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(self->f)); -} - -- (int)isPadded -{ - return self->padded; -} - -- (void)setPadded:(int)p -{ - CGFloat padding; - NSLayoutConstraint *c; - - self->padded = p; - padding = [self paddingAmount]; - for (c in self->inBetweens) - [c setConstant:-padding]; - for (c in self->middles) - [c setConstant:-padding]; -} - -- (BOOL)hugsTrailing -{ - return YES; // always hug trailing -} - -- (BOOL)hugsBottom -{ - // only hug if we have stretchy - return [self nStretchy] != 0; -} - -- (int)nStretchy -{ - formChild *fc; - int n; - - n = 0; - for (fc in self->children) { - if (!uiControlVisible(fc.c)) - continue; - if (fc.stretchy) - n++; - } - return n; -} - -@end - -static void uiFormDestroy(uiControl *c) -{ - uiForm *f = uiForm(c); - - [f->view onDestroy]; - [f->view release]; - uiFreeControl(uiControl(f)); -} - -uiDarwinControlDefaultHandle(uiForm, view) -uiDarwinControlDefaultParent(uiForm, view) -uiDarwinControlDefaultSetParent(uiForm, view) -uiDarwinControlDefaultToplevel(uiForm, view) -uiDarwinControlDefaultVisible(uiForm, view) -uiDarwinControlDefaultShow(uiForm, view) -uiDarwinControlDefaultHide(uiForm, view) -uiDarwinControlDefaultEnabled(uiForm, view) -uiDarwinControlDefaultEnable(uiForm, view) -uiDarwinControlDefaultDisable(uiForm, view) - -static void uiFormSyncEnableState(uiDarwinControl *c, int enabled) -{ - uiForm *f = uiForm(c); - - if (uiDarwinShouldStopSyncEnableState(uiDarwinControl(f), enabled)) - return; - [f->view syncEnableStates:enabled]; -} - -uiDarwinControlDefaultSetSuperview(uiForm, view) - -static BOOL uiFormHugsTrailingEdge(uiDarwinControl *c) -{ - uiForm *f = uiForm(c); - - return [f->view hugsTrailing]; -} - -static BOOL uiFormHugsBottom(uiDarwinControl *c) -{ - uiForm *f = uiForm(c); - - return [f->view hugsBottom]; -} - -static void uiFormChildEdgeHuggingChanged(uiDarwinControl *c) -{ - uiForm *f = uiForm(c); - - [f->view establishOurConstraints]; -} - -uiDarwinControlDefaultHuggingPriority(uiForm, view) -uiDarwinControlDefaultSetHuggingPriority(uiForm, view) - -static void uiFormChildVisibilityChanged(uiDarwinControl *c) -{ - uiForm *f = uiForm(c); - - [f->view establishOurConstraints]; -} - -void uiFormAppend(uiForm *f, const char *label, uiControl *c, int stretchy) -{ - // LONGTERM on other platforms - // or at leat allow this and implicitly turn it into a spacer - if (c == NULL) - userbug("You cannot add NULL to a uiForm."); - [f->view append:toNSString(label) c:c stretchy:stretchy]; -} - -void uiFormDelete(uiForm *f, int n) -{ - [f->view delete:n]; -} - -int uiFormPadded(uiForm *f) -{ - return [f->view isPadded]; -} - -void uiFormSetPadded(uiForm *f, int padded) -{ - [f->view setPadded:padded]; -} - -uiForm *uiNewForm(void) -{ - uiForm *f; - - uiDarwinNewControl(uiForm, f); - - f->view = [[formView alloc] initWithF:f]; - - return f; -} diff --git a/deps/libui/darwin/grid.m b/deps/libui/darwin/grid.m deleted file mode 100644 index d5c5fb1e86..0000000000 --- a/deps/libui/darwin/grid.m +++ /dev/null @@ -1,800 +0,0 @@ -// 11 june 2016 -#import "uipriv_darwin.h" - -// TODO the assorted test doesn't work right at all - -@interface gridChild : NSView -@property uiControl *c; -@property int left; -@property int top; -@property int xspan; -@property int yspan; -@property int hexpand; -@property uiAlign halign; -@property int vexpand; -@property uiAlign valign; - -@property (strong) NSLayoutConstraint *leadingc; -@property (strong) NSLayoutConstraint *topc; -@property (strong) NSLayoutConstraint *trailingc; -@property (strong) NSLayoutConstraint *bottomc; -@property (strong) NSLayoutConstraint *xcenterc; -@property (strong) NSLayoutConstraint *ycenterc; - -@property NSLayoutPriority oldHorzHuggingPri; -@property NSLayoutPriority oldVertHuggingPri; -- (void)setC:(uiControl *)c grid:(uiGrid *)g; -- (void)onDestroy; -- (NSView *)view; -@end - -@interface gridView : NSView { - uiGrid *g; - NSMutableArray *children; - int padded; - - NSMutableArray *edges; - NSMutableArray *inBetweens; - - NSMutableArray *emptyCellViews; -} -- (id)initWithG:(uiGrid *)gg; -- (void)onDestroy; -- (void)removeOurConstraints; -- (void)syncEnableStates:(int)enabled; -- (CGFloat)paddingAmount; -- (void)establishOurConstraints; -- (void)append:(gridChild *)gc; -- (void)insert:(gridChild *)gc after:(uiControl *)c at:(uiAt)at; -- (int)isPadded; -- (void)setPadded:(int)p; -- (BOOL)hugsTrailing; -- (BOOL)hugsBottom; -- (int)nhexpand; -- (int)nvexpand; -@end - -struct uiGrid { - uiDarwinControl c; - gridView *view; -}; - -@implementation gridChild - -- (void)setC:(uiControl *)c grid:(uiGrid *)g -{ - self.c = c; - self.oldHorzHuggingPri = uiDarwinControlHuggingPriority(uiDarwinControl(self.c), NSLayoutConstraintOrientationHorizontal); - self.oldVertHuggingPri = uiDarwinControlHuggingPriority(uiDarwinControl(self.c), NSLayoutConstraintOrientationVertical); - - uiControlSetParent(self.c, uiControl(g)); - uiDarwinControlSetSuperview(uiDarwinControl(self.c), self); - uiDarwinControlSyncEnableState(uiDarwinControl(self.c), uiControlEnabledToUser(uiControl(g))); - - if (self.halign == uiAlignStart || self.halign == uiAlignFill) { - self.leadingc = mkConstraint(self, NSLayoutAttributeLeading, - NSLayoutRelationEqual, - [self view], NSLayoutAttributeLeading, - 1, 0, - @"uiGrid child horizontal alignment start constraint"); - [self addConstraint:self.leadingc]; - } - if (self.halign == uiAlignCenter) { - self.xcenterc = mkConstraint(self, NSLayoutAttributeCenterX, - NSLayoutRelationEqual, - [self view], NSLayoutAttributeCenterX, - 1, 0, - @"uiGrid child horizontal alignment center constraint"); - [self addConstraint:self.xcenterc]; - } - if (self.halign == uiAlignEnd || self.halign == uiAlignFill) { - self.trailingc = mkConstraint(self, NSLayoutAttributeTrailing, - NSLayoutRelationEqual, - [self view], NSLayoutAttributeTrailing, - 1, 0, - @"uiGrid child horizontal alignment end constraint"); - [self addConstraint:self.trailingc]; - } - - if (self.valign == uiAlignStart || self.valign == uiAlignFill) { - self.topc = mkConstraint(self, NSLayoutAttributeTop, - NSLayoutRelationEqual, - [self view], NSLayoutAttributeTop, - 1, 0, - @"uiGrid child vertical alignment start constraint"); - [self addConstraint:self.topc]; - } - if (self.valign == uiAlignCenter) { - self.ycenterc = mkConstraint(self, NSLayoutAttributeCenterY, - NSLayoutRelationEqual, - [self view], NSLayoutAttributeCenterY, - 1, 0, - @"uiGrid child vertical alignment center constraint"); - [self addConstraint:self.ycenterc]; - } - if (self.valign == uiAlignEnd || self.valign == uiAlignFill) { - self.bottomc = mkConstraint(self, NSLayoutAttributeBottom, - NSLayoutRelationEqual, - [self view], NSLayoutAttributeBottom, - 1, 0, - @"uiGrid child vertical alignment end constraint"); - [self addConstraint:self.bottomc]; - } -} - -- (void)onDestroy -{ - if (self.leadingc != nil) { - [self removeConstraint:self.leadingc]; - self.leadingc = nil; - } - if (self.topc != nil) { - [self removeConstraint:self.topc]; - self.topc = nil; - } - if (self.trailingc != nil) { - [self removeConstraint:self.trailingc]; - self.trailingc = nil; - } - if (self.bottomc != nil) { - [self removeConstraint:self.bottomc]; - self.bottomc = nil; - } - if (self.xcenterc != nil) { - [self removeConstraint:self.xcenterc]; - self.xcenterc = nil; - } - if (self.ycenterc != nil) { - [self removeConstraint:self.ycenterc]; - self.ycenterc = nil; - } - - uiControlSetParent(self.c, NULL); - uiDarwinControlSetSuperview(uiDarwinControl(self.c), nil); - uiDarwinControlSetHuggingPriority(uiDarwinControl(self.c), self.oldHorzHuggingPri, NSLayoutConstraintOrientationHorizontal); - uiDarwinControlSetHuggingPriority(uiDarwinControl(self.c), self.oldVertHuggingPri, NSLayoutConstraintOrientationVertical); -} - -- (NSView *)view -{ - return (NSView *) uiControlHandle(self.c); -} - -@end - -@implementation gridView - -- (id)initWithG:(uiGrid *)gg -{ - self = [super initWithFrame:NSZeroRect]; - if (self != nil) { - self->g = gg; - self->padded = 0; - self->children = [NSMutableArray new]; - - self->edges = [NSMutableArray new]; - self->inBetweens = [NSMutableArray new]; - - self->emptyCellViews = [NSMutableArray new]; - } - return self; -} - -- (void)onDestroy -{ - gridChild *gc; - - [self removeOurConstraints]; - [self->edges release]; - [self->inBetweens release]; - - [self->emptyCellViews release]; - - for (gc in self->children) { - [gc onDestroy]; - uiControlDestroy(gc.c); - [gc removeFromSuperview]; - } - [self->children release]; -} - -- (void)removeOurConstraints -{ - NSView *v; - - if ([self->edges count] != 0) { - [self removeConstraints:self->edges]; - [self->edges removeAllObjects]; - } - if ([self->inBetweens count] != 0) { - [self removeConstraints:self->inBetweens]; - [self->inBetweens removeAllObjects]; - } - - for (v in self->emptyCellViews) - [v removeFromSuperview]; - [self->emptyCellViews removeAllObjects]; -} - -- (void)syncEnableStates:(int)enabled -{ - gridChild *gc; - - for (gc in self->children) - uiDarwinControlSyncEnableState(uiDarwinControl(gc.c), enabled); -} - -- (CGFloat)paddingAmount -{ - if (!self->padded) - return 0.0; - return uiDarwinPaddingAmount(NULL); -} - -// LONGTERM stop early if all controls are hidden -- (void)establishOurConstraints -{ - gridChild *gc; - CGFloat padding; - int xmin, ymin; - int xmax, ymax; - int xcount, ycount; - BOOL first; - int **gg; - NSView ***gv; - BOOL **gspan; - int x, y; - int i; - NSLayoutConstraint *c; - int firstx, firsty; - BOOL *hexpand, *vexpand; - BOOL doit; - BOOL onlyEmptyAndSpanning; - - [self removeOurConstraints]; - if ([self->children count] == 0) - return; - padding = [self paddingAmount]; - - // first, figure out the minimum and maximum row and column numbers - // ignore hidden controls - first = YES; - for (gc in self->children) { - // this bit is important: it ensures row ymin and column xmin have at least one cell to draw, so the onlyEmptyAndSpanning logic below will never run on those rows - if (!uiControlVisible(gc.c)) - continue; - if (first) { - xmin = gc.left; - ymin = gc.top; - xmax = gc.left + gc.xspan; - ymax = gc.top + gc.yspan; - first = NO; - continue; - } - if (xmin > gc.left) - xmin = gc.left; - if (ymin > gc.top) - ymin = gc.top; - if (xmax < (gc.left + gc.xspan)) - xmax = gc.left + gc.xspan; - if (ymax < (gc.top + gc.yspan)) - ymax = gc.top + gc.yspan; - } - if (first != NO) // the entire grid is hidden; do nothing - return; - xcount = xmax - xmin; - ycount = ymax - ymin; - - // now build a topological map of the grid gg[y][x] - // also figure out which cells contain spanned views so they can be ignored later - // treat hidden controls by keeping the indices -1 - gg = (int **) uiAlloc(ycount * sizeof (int *), "int[][]"); - gspan = (BOOL **) uiAlloc(ycount * sizeof (BOOL *), "BOOL[][]"); - for (y = 0; y < ycount; y++) { - gg[y] = (int *) uiAlloc(xcount * sizeof (int), "int[]"); - gspan[y] = (BOOL *) uiAlloc(xcount * sizeof (BOOL), "BOOL[]"); - for (x = 0; x < xcount; x++) - gg[y][x] = -1; // empty - } - for (i = 0; i < [self->children count]; i++) { - gc = (gridChild *) [self->children objectAtIndex:i]; - if (!uiControlVisible(gc.c)) - continue; - for (y = gc.top; y < gc.top + gc.yspan; y++) - for (x = gc.left; x < gc.left + gc.xspan; x++) { - gg[y - ymin][x - xmin] = i; - if (x != gc.left || y != gc.top) - gspan[y - ymin][x - xmin] = YES; - } - } - - // if a row or column only contains emptys and spanning cells of a opposite-direction spannings, remove it by duplicating the previous row or column - for (y = 0; y < ycount; y++) { - onlyEmptyAndSpanning = YES; - for (x = 0; x < xcount; x++) - if (gg[y][x] != -1) { - gc = (gridChild *) [self->children objectAtIndex:gg[y][x]]; - if (gc.yspan == 1 || gc.top - ymin == y) { - onlyEmptyAndSpanning = NO; - break; - } - } - if (onlyEmptyAndSpanning) - for (x = 0; x < xcount; x++) { - gg[y][x] = gg[y - 1][x]; - gspan[y][x] = YES; - } - } - for (x = 0; x < xcount; x++) { - onlyEmptyAndSpanning = YES; - for (y = 0; y < ycount; y++) - if (gg[y][x] != -1) { - gc = (gridChild *) [self->children objectAtIndex:gg[y][x]]; - if (gc.xspan == 1 || gc.left - xmin == x) { - onlyEmptyAndSpanning = NO; - break; - } - } - if (onlyEmptyAndSpanning) - for (y = 0; y < ycount; y++) { - gg[y][x] = gg[y][x - 1]; - gspan[y][x] = YES; - } - } - - // now build a topological map of the grid's views gv[y][x] - // for any empty cell, create a dummy view - gv = (NSView ***) uiAlloc(ycount * sizeof (NSView **), "NSView *[][]"); - for (y = 0; y < ycount; y++) { - gv[y] = (NSView **) uiAlloc(xcount * sizeof (NSView *), "NSView *[]"); - for (x = 0; x < xcount; x++) - if (gg[y][x] == -1) { - gv[y][x] = [[NSView alloc] initWithFrame:NSZeroRect]; - [gv[y][x] setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self addSubview:gv[y][x]]; - [self->emptyCellViews addObject:gv[y][x]]; - } else { - gc = (gridChild *) [self->children objectAtIndex:gg[y][x]]; - gv[y][x] = gc; - } - } - - // now figure out which rows and columns really expand - hexpand = (BOOL *) uiAlloc(xcount * sizeof (BOOL), "BOOL[]"); - vexpand = (BOOL *) uiAlloc(ycount * sizeof (BOOL), "BOOL[]"); - // first, which don't span - for (gc in self->children) { - if (!uiControlVisible(gc.c)) - continue; - if (gc.hexpand && gc.xspan == 1) - hexpand[gc.left - xmin] = YES; - if (gc.vexpand && gc.yspan == 1) - vexpand[gc.top - ymin] = YES; - } - // second, which do span - // the way we handle this is simple: if none of the spanned rows/columns expand, make all rows/columns expand - for (gc in self->children) { - if (!uiControlVisible(gc.c)) - continue; - if (gc.hexpand && gc.xspan != 1) { - doit = YES; - for (x = gc.left; x < gc.left + gc.xspan; x++) - if (hexpand[x - xmin]) { - doit = NO; - break; - } - if (doit) - for (x = gc.left; x < gc.left + gc.xspan; x++) - hexpand[x - xmin] = YES; - } - if (gc.vexpand && gc.yspan != 1) { - doit = YES; - for (y = gc.top; y < gc.top + gc.yspan; y++) - if (vexpand[y - ymin]) { - doit = NO; - break; - } - if (doit) - for (y = gc.top; y < gc.top + gc.yspan; y++) - vexpand[y - ymin] = YES; - } - } - - // now establish all the edge constraints - // leading and trailing edges - for (y = 0; y < ycount; y++) { - c = mkConstraint(self, NSLayoutAttributeLeading, - NSLayoutRelationEqual, - gv[y][0], NSLayoutAttributeLeading, - 1, 0, - @"uiGrid leading edge constraint"); - [self addConstraint:c]; - [self->edges addObject:c]; - c = mkConstraint(self, NSLayoutAttributeTrailing, - NSLayoutRelationEqual, - gv[y][xcount - 1], NSLayoutAttributeTrailing, - 1, 0, - @"uiGrid trailing edge constraint"); - [self addConstraint:c]; - [self->edges addObject:c]; - } - // top and bottom edges - for (x = 0; x < xcount; x++) { - c = mkConstraint(self, NSLayoutAttributeTop, - NSLayoutRelationEqual, - gv[0][x], NSLayoutAttributeTop, - 1, 0, - @"uiGrid top edge constraint"); - [self addConstraint:c]; - [self->edges addObject:c]; - c = mkConstraint(self, NSLayoutAttributeBottom, - NSLayoutRelationEqual, - gv[ycount - 1][x], NSLayoutAttributeBottom, - 1, 0, - @"uiGrid bottom edge constraint"); - [self addConstraint:c]; - [self->edges addObject:c]; - } - - // now align leading and top edges - // do NOT align spanning cells! - for (x = 0; x < xcount; x++) { - for (y = 0; y < ycount; y++) - if (!gspan[y][x]) - break; - firsty = y; - for (y++; y < ycount; y++) { - if (gspan[y][x]) - continue; - c = mkConstraint(gv[firsty][x], NSLayoutAttributeLeading, - NSLayoutRelationEqual, - gv[y][x], NSLayoutAttributeLeading, - 1, 0, - @"uiGrid column leading constraint"); - [self addConstraint:c]; - [self->edges addObject:c]; - } - } - for (y = 0; y < ycount; y++) { - for (x = 0; x < xcount; x++) - if (!gspan[y][x]) - break; - firstx = x; - for (x++; x < xcount; x++) { - if (gspan[y][x]) - continue; - c = mkConstraint(gv[y][firstx], NSLayoutAttributeTop, - NSLayoutRelationEqual, - gv[y][x], NSLayoutAttributeTop, - 1, 0, - @"uiGrid row top constraint"); - [self addConstraint:c]; - [self->edges addObject:c]; - } - } - - // now string adjacent views together - for (y = 0; y < ycount; y++) - for (x = 1; x < xcount; x++) - if (gv[y][x - 1] != gv[y][x]) { - c = mkConstraint(gv[y][x - 1], NSLayoutAttributeTrailing, - NSLayoutRelationEqual, - gv[y][x], NSLayoutAttributeLeading, - 1, -padding, - @"uiGrid internal horizontal constraint"); - [self addConstraint:c]; - [self->inBetweens addObject:c]; - } - for (x = 0; x < xcount; x++) - for (y = 1; y < ycount; y++) - if (gv[y - 1][x] != gv[y][x]) { - c = mkConstraint(gv[y - 1][x], NSLayoutAttributeBottom, - NSLayoutRelationEqual, - gv[y][x], NSLayoutAttributeTop, - 1, -padding, - @"uiGrid internal vertical constraint"); - [self addConstraint:c]; - [self->inBetweens addObject:c]; - } - - // now set priorities for all widgets that expand or not - // if a cell is in an expanding row, OR If it spans, then it must be willing to stretch - // otherwise, it tries not to - // note we don't use NSLayoutPriorityRequired as that will cause things to squish when they shouldn't - for (gc in self->children) { - NSLayoutPriority priority; - - if (!uiControlVisible(gc.c)) - continue; - if (hexpand[gc.left - xmin] || gc.xspan != 1) - priority = NSLayoutPriorityDefaultLow; - else - priority = NSLayoutPriorityDefaultHigh; - uiDarwinControlSetHuggingPriority(uiDarwinControl(gc.c), priority, NSLayoutConstraintOrientationHorizontal); - // same for vertical direction - if (vexpand[gc.top - ymin] || gc.yspan != 1) - priority = NSLayoutPriorityDefaultLow; - else - priority = NSLayoutPriorityDefaultHigh; - uiDarwinControlSetHuggingPriority(uiDarwinControl(gc.c), priority, NSLayoutConstraintOrientationVertical); - } - - // TODO make all expanding rows/columns the same height/width - - // and finally clean up - uiFree(hexpand); - uiFree(vexpand); - for (y = 0; y < ycount; y++) { - uiFree(gg[y]); - uiFree(gv[y]); - uiFree(gspan[y]); - } - uiFree(gg); - uiFree(gv); - uiFree(gspan); -} - -- (void)append:(gridChild *)gc -{ - BOOL update; - int oldnh, oldnv; - - [gc setTranslatesAutoresizingMaskIntoConstraints:NO]; - [self addSubview:gc]; - - // no need to set priority here; that's done in establishOurConstraints - - oldnh = [self nhexpand]; - oldnv = [self nvexpand]; - [self->children addObject:gc]; - - [self establishOurConstraints]; - update = NO; - if (gc.hexpand) - if (oldnh == 0) - update = YES; - if (gc.vexpand) - if (oldnv == 0) - update = YES; - if (update) - uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(self->g)); - - [gc release]; // we don't need the initial reference now -} - -- (void)insert:(gridChild *)gc after:(uiControl *)c at:(uiAt)at -{ - gridChild *other; - BOOL found; - - found = NO; - for (other in self->children) - if (other.c == c) { - found = YES; - break; - } - if (!found) - userbug("Existing control %p is not in grid %p; you cannot add other controls next to it", c, self->g); - - switch (at) { - case uiAtLeading: - gc.left = other.left - gc.xspan; - gc.top = other.top; - break; - case uiAtTop: - gc.left = other.left; - gc.top = other.top - gc.yspan; - break; - case uiAtTrailing: - gc.left = other.left + other.xspan; - gc.top = other.top; - break; - case uiAtBottom: - gc.left = other.left; - gc.top = other.top + other.yspan; - break; - // TODO add error checks to ALL enums - } - - [self append:gc]; -} - -- (int)isPadded -{ - return self->padded; -} - -- (void)setPadded:(int)p -{ - CGFloat padding; - NSLayoutConstraint *c; - -#if 0 /* TODO */ -dispatch_after( -dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), -dispatch_get_main_queue(), -^{ [[self window] visualizeConstraints:[self constraints]]; } -); -#endif - self->padded = p; - padding = [self paddingAmount]; - for (c in self->inBetweens) - switch ([c firstAttribute]) { - case NSLayoutAttributeLeading: - case NSLayoutAttributeTop: - [c setConstant:padding]; - break; - case NSLayoutAttributeTrailing: - case NSLayoutAttributeBottom: - [c setConstant:-padding]; - break; - } -} - -- (BOOL)hugsTrailing -{ - // only hug if we have horizontally expanding - return [self nhexpand] != 0; -} - -- (BOOL)hugsBottom -{ - // only hug if we have vertically expanding - return [self nvexpand] != 0; -} - -- (int)nhexpand -{ - gridChild *gc; - int n; - - n = 0; - for (gc in self->children) { - if (!uiControlVisible(gc.c)) - continue; - if (gc.hexpand) - n++; - } - return n; -} - -- (int)nvexpand -{ - gridChild *gc; - int n; - - n = 0; - for (gc in self->children) { - if (!uiControlVisible(gc.c)) - continue; - if (gc.vexpand) - n++; - } - return n; -} - -@end - -static void uiGridDestroy(uiControl *c) -{ - uiGrid *g = uiGrid(c); - - [g->view onDestroy]; - [g->view release]; - uiFreeControl(uiControl(g)); -} - -uiDarwinControlDefaultHandle(uiGrid, view) -uiDarwinControlDefaultParent(uiGrid, view) -uiDarwinControlDefaultSetParent(uiGrid, view) -uiDarwinControlDefaultToplevel(uiGrid, view) -uiDarwinControlDefaultVisible(uiGrid, view) -uiDarwinControlDefaultShow(uiGrid, view) -uiDarwinControlDefaultHide(uiGrid, view) -uiDarwinControlDefaultEnabled(uiGrid, view) -uiDarwinControlDefaultEnable(uiGrid, view) -uiDarwinControlDefaultDisable(uiGrid, view) - -static void uiGridSyncEnableState(uiDarwinControl *c, int enabled) -{ - uiGrid *g = uiGrid(c); - - if (uiDarwinShouldStopSyncEnableState(uiDarwinControl(g), enabled)) - return; - [g->view syncEnableStates:enabled]; -} - -uiDarwinControlDefaultSetSuperview(uiGrid, view) - -static BOOL uiGridHugsTrailingEdge(uiDarwinControl *c) -{ - uiGrid *g = uiGrid(c); - - return [g->view hugsTrailing]; -} - -static BOOL uiGridHugsBottom(uiDarwinControl *c) -{ - uiGrid *g = uiGrid(c); - - return [g->view hugsBottom]; -} - -static void uiGridChildEdgeHuggingChanged(uiDarwinControl *c) -{ - uiGrid *g = uiGrid(c); - - [g->view establishOurConstraints]; -} - -uiDarwinControlDefaultHuggingPriority(uiGrid, view) -uiDarwinControlDefaultSetHuggingPriority(uiGrid, view) - -static void uiGridChildVisibilityChanged(uiDarwinControl *c) -{ - uiGrid *g = uiGrid(c); - - [g->view establishOurConstraints]; -} - -static gridChild *toChild(uiControl *c, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign, uiGrid *g) -{ - gridChild *gc; - - if (xspan < 0) - userbug("You cannot have a negative xspan in a uiGrid cell."); - if (yspan < 0) - userbug("You cannot have a negative yspan in a uiGrid cell."); - gc = [gridChild new]; - gc.xspan = xspan; - gc.yspan = yspan; - gc.hexpand = hexpand; - gc.halign = halign; - gc.vexpand = vexpand; - gc.valign = valign; - [gc setC:c grid:g]; - return gc; -} - -void uiGridAppend(uiGrid *g, uiControl *c, int left, int top, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign) -{ - gridChild *gc; - - // LONGTERM on other platforms - // or at leat allow this and implicitly turn it into a spacer - if (c == NULL) - userbug("You cannot add NULL to a uiGrid."); - gc = toChild(c, xspan, yspan, hexpand, halign, vexpand, valign, g); - gc.left = left; - gc.top = top; - [g->view append:gc]; -} - -void uiGridInsertAt(uiGrid *g, uiControl *c, uiControl *existing, uiAt at, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign) -{ - gridChild *gc; - - gc = toChild(c, xspan, yspan, hexpand, halign, vexpand, valign, g); - [g->view insert:gc after:existing at:at]; -} - -int uiGridPadded(uiGrid *g) -{ - return [g->view isPadded]; -} - -void uiGridSetPadded(uiGrid *g, int padded) -{ - [g->view setPadded:padded]; -} - -uiGrid *uiNewGrid(void) -{ - uiGrid *g; - - uiDarwinNewControl(uiGrid, g); - - g->view = [[gridView alloc] initWithG:g]; - - return g; -} diff --git a/deps/libui/darwin/group.m b/deps/libui/darwin/group.m deleted file mode 100644 index 0050bbdd3c..0000000000 --- a/deps/libui/darwin/group.m +++ /dev/null @@ -1,194 +0,0 @@ -// 14 august 2015 -#import "uipriv_darwin.h" - -struct uiGroup { - uiDarwinControl c; - NSBox *box; - uiControl *child; - NSLayoutPriority oldHorzHuggingPri; - NSLayoutPriority oldVertHuggingPri; - int margined; - struct singleChildConstraints constraints; - NSLayoutPriority horzHuggingPri; - NSLayoutPriority vertHuggingPri; -}; - -static void removeConstraints(uiGroup *g) -{ - // set to contentView instead of to the box itself, otherwise we get clipping underneath the label - singleChildConstraintsRemove(&(g->constraints), [g->box contentView]); -} - -static void uiGroupDestroy(uiControl *c) -{ - uiGroup *g = uiGroup(c); - - removeConstraints(g); - if (g->child != NULL) { - uiControlSetParent(g->child, NULL); - uiDarwinControlSetSuperview(uiDarwinControl(g->child), nil); - uiControlDestroy(g->child); - } - [g->box release]; - uiFreeControl(uiControl(g)); -} - -uiDarwinControlDefaultHandle(uiGroup, box) -uiDarwinControlDefaultParent(uiGroup, box) -uiDarwinControlDefaultSetParent(uiGroup, box) -uiDarwinControlDefaultToplevel(uiGroup, box) -uiDarwinControlDefaultVisible(uiGroup, box) -uiDarwinControlDefaultShow(uiGroup, box) -uiDarwinControlDefaultHide(uiGroup, box) -uiDarwinControlDefaultEnabled(uiGroup, box) -uiDarwinControlDefaultEnable(uiGroup, box) -uiDarwinControlDefaultDisable(uiGroup, box) - -static void uiGroupSyncEnableState(uiDarwinControl *c, int enabled) -{ - uiGroup *g = uiGroup(c); - - if (uiDarwinShouldStopSyncEnableState(uiDarwinControl(g), enabled)) - return; - if (g->child != NULL) - uiDarwinControlSyncEnableState(uiDarwinControl(g->child), enabled); -} - -uiDarwinControlDefaultSetSuperview(uiGroup, box) - -static void groupRelayout(uiGroup *g) -{ - NSView *childView; - - removeConstraints(g); - if (g->child == NULL) - return; - childView = (NSView *) uiControlHandle(g->child); - singleChildConstraintsEstablish(&(g->constraints), - [g->box contentView], childView, - uiDarwinControlHugsTrailingEdge(uiDarwinControl(g->child)), - uiDarwinControlHugsBottom(uiDarwinControl(g->child)), - g->margined, - @"uiGroup"); - // needed for some very rare drawing errors... - jiggleViewLayout(g->box); -} - -// TODO rename these since I'm starting to get confused by what they mean by hugging -BOOL uiGroupHugsTrailingEdge(uiDarwinControl *c) -{ - uiGroup *g = uiGroup(c); - - // TODO make a function? - return g->horzHuggingPri < NSLayoutPriorityWindowSizeStayPut; -} - -BOOL uiGroupHugsBottom(uiDarwinControl *c) -{ - uiGroup *g = uiGroup(c); - - return g->vertHuggingPri < NSLayoutPriorityWindowSizeStayPut; -} - -static void uiGroupChildEdgeHuggingChanged(uiDarwinControl *c) -{ - uiGroup *g = uiGroup(c); - - groupRelayout(g); -} - -static NSLayoutPriority uiGroupHuggingPriority(uiDarwinControl *c, NSLayoutConstraintOrientation orientation) -{ - uiGroup *g = uiGroup(c); - - if (orientation == NSLayoutConstraintOrientationHorizontal) - return g->horzHuggingPri; - return g->vertHuggingPri; -} - -static void uiGroupSetHuggingPriority(uiDarwinControl *c, NSLayoutPriority priority, NSLayoutConstraintOrientation orientation) -{ - uiGroup *g = uiGroup(c); - - if (orientation == NSLayoutConstraintOrientationHorizontal) - g->horzHuggingPri = priority; - else - g->vertHuggingPri = priority; - uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(g)); -} - -static void uiGroupChildVisibilityChanged(uiDarwinControl *c) -{ - uiGroup *g = uiGroup(c); - - groupRelayout(g); -} - -char *uiGroupTitle(uiGroup *g) -{ - return uiDarwinNSStringToText([g->box title]); -} - -void uiGroupSetTitle(uiGroup *g, const char *title) -{ - [g->box setTitle:toNSString(title)]; -} - -void uiGroupSetChild(uiGroup *g, uiControl *child) -{ - NSView *childView; - - if (g->child != NULL) { - removeConstraints(g); - uiDarwinControlSetHuggingPriority(uiDarwinControl(g->child), g->oldHorzHuggingPri, NSLayoutConstraintOrientationHorizontal); - uiDarwinControlSetHuggingPriority(uiDarwinControl(g->child), g->oldVertHuggingPri, NSLayoutConstraintOrientationVertical); - uiControlSetParent(g->child, NULL); - uiDarwinControlSetSuperview(uiDarwinControl(g->child), nil); - } - g->child = child; - if (g->child != NULL) { - childView = (NSView *) uiControlHandle(g->child); - uiControlSetParent(g->child, uiControl(g)); - uiDarwinControlSetSuperview(uiDarwinControl(g->child), [g->box contentView]); - uiDarwinControlSyncEnableState(uiDarwinControl(g->child), uiControlEnabledToUser(uiControl(g))); - // don't hug, just in case we're a stretchy group - g->oldHorzHuggingPri = uiDarwinControlHuggingPriority(uiDarwinControl(g->child), NSLayoutConstraintOrientationHorizontal); - g->oldVertHuggingPri = uiDarwinControlHuggingPriority(uiDarwinControl(g->child), NSLayoutConstraintOrientationVertical); - uiDarwinControlSetHuggingPriority(uiDarwinControl(g->child), NSLayoutPriorityDefaultLow, NSLayoutConstraintOrientationHorizontal); - uiDarwinControlSetHuggingPriority(uiDarwinControl(g->child), NSLayoutPriorityDefaultLow, NSLayoutConstraintOrientationVertical); - } - groupRelayout(g); -} - -int uiGroupMargined(uiGroup *g) -{ - return g->margined; -} - -void uiGroupSetMargined(uiGroup *g, int margined) -{ - g->margined = margined; - singleChildConstraintsSetMargined(&(g->constraints), g->margined); -} - -uiGroup *uiNewGroup(const char *title) -{ - uiGroup *g; - - uiDarwinNewControl(uiGroup, g); - - g->box = [[NSBox alloc] initWithFrame:NSZeroRect]; - [g->box setTitle:toNSString(title)]; - [g->box setBoxType:NSBoxPrimary]; - [g->box setBorderType:NSLineBorder]; - [g->box setTransparent:NO]; - [g->box setTitlePosition:NSAtTop]; - // we can't use uiDarwinSetControlFont() because the selector is different - [g->box setTitleFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]]; - - // default to low hugging to not hug edges - g->horzHuggingPri = NSLayoutPriorityDefaultLow; - g->vertHuggingPri = NSLayoutPriorityDefaultLow; - - return g; -} diff --git a/deps/libui/darwin/image.m b/deps/libui/darwin/image.m deleted file mode 100644 index b62de31d8c..0000000000 --- a/deps/libui/darwin/image.m +++ /dev/null @@ -1,82 +0,0 @@ -// 25 june 2016 -#import "uipriv_darwin.h" - -struct uiImage { - NSImage *i; - NSSize size; - NSMutableArray *swizzled; -}; - -uiImage *uiNewImage(double width, double height) -{ - uiImage *i; - - i = uiNew(uiImage); - i->size = NSMakeSize(width, height); - i->i = [[NSImage alloc] initWithSize:i->size]; - i->swizzled = [NSMutableArray new]; - return i; -} - -void uiFreeImage(uiImage *i) -{ - NSValue *v; - - [i->i release]; - // to be safe, do this after releasing the image - for (v in i->swizzled) - uiFree([v pointerValue]); - [i->swizzled release]; - uiFree(i); -} - -void uiImageAppend(uiImage *i, void *pixels, int pixelWidth, int pixelHeight, int pixelStride) -{ - NSBitmapImageRep *repCalibrated, *repsRGB; - uint8_t *swizzled, *bp, *sp; - int x, y; - unsigned char *pix[1]; - - // OS X demands that R and B are in the opposite order from what we expect - // we must swizzle :( - // LONGTERM test on a big-endian system - swizzled = (uint8_t *) uiAlloc((pixelStride * pixelHeight * 4) * sizeof (uint8_t), "uint8_t[]"); - bp = (uint8_t *) pixels; - sp = swizzled; - for (y = 0; y < pixelHeight * pixelStride; y += pixelStride) - for (x = 0; x < pixelStride; x++) { - sp[0] = bp[2]; - sp[1] = bp[1]; - sp[2] = bp[0]; - sp[3] = bp[3]; - sp += 4; - bp += 4; - } - - pix[0] = (unsigned char *) swizzled; - repCalibrated = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:pix - pixelsWide:pixelWidth - pixelsHigh:pixelHeight - bitsPerSample:8 - samplesPerPixel:4 - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSCalibratedRGBColorSpace - bitmapFormat:0 - bytesPerRow:pixelStride - bitsPerPixel:32]; - repsRGB = [repCalibrated bitmapImageRepByRetaggingWithColorSpace:[NSColorSpace sRGBColorSpace]]; - [repCalibrated release]; - - [i->i addRepresentation:repsRGB]; - [repsRGB setSize:i->size]; - [repsRGB release]; - - // we need to keep swizzled alive for NSBitmapImageRep - [i->swizzled addObject:[NSValue valueWithPointer:swizzled]]; -} - -NSImage *imageImage(uiImage *i) -{ - return i->i; -} diff --git a/deps/libui/darwin/label.m b/deps/libui/darwin/label.m deleted file mode 100644 index 897bc3ff44..0000000000 --- a/deps/libui/darwin/label.m +++ /dev/null @@ -1,43 +0,0 @@ -// 14 august 2015 -#import "uipriv_darwin.h" - -struct uiLabel { - uiDarwinControl c; - NSTextField *textfield; -}; - -uiDarwinControlAllDefaults(uiLabel, textfield) - -char *uiLabelText(uiLabel *l) -{ - return uiDarwinNSStringToText([l->textfield stringValue]); -} - -void uiLabelSetText(uiLabel *l, const char *text) -{ - [l->textfield setStringValue:toNSString(text)]; -} - -NSTextField *newLabel(NSString *str) -{ - NSTextField *tf; - - tf = [[NSTextField alloc] initWithFrame:NSZeroRect]; - [tf setStringValue:str]; - [tf setEditable:NO]; - [tf setSelectable:NO]; - [tf setDrawsBackground:NO]; - finishNewTextField(tf, NO); - return tf; -} - -uiLabel *uiNewLabel(const char *text) -{ - uiLabel *l; - - uiDarwinNewControl(uiLabel, l); - - l->textfield = newLabel(toNSString(text)); - - return l; -} diff --git a/deps/libui/darwin/main.m b/deps/libui/darwin/main.m deleted file mode 100644 index 59a8683bff..0000000000 --- a/deps/libui/darwin/main.m +++ /dev/null @@ -1,239 +0,0 @@ -// 6 april 2015 -#import "uipriv_darwin.h" - -static BOOL canQuit = NO; -static NSAutoreleasePool *globalPool; -static applicationClass *app; -static appDelegate *delegate; - -static BOOL (^isRunning)(void); -static BOOL stepsIsRunning; - -@implementation applicationClass - -- (void)sendEvent:(NSEvent *)e -{ - if (sendAreaEvents(e) != 0) - return; - [super sendEvent:e]; -} - -// NSColorPanel always sends changeColor: to the first responder regardless of whether there's a target set on it -// we can override it here (see colorbutton.m) -// thanks to mikeash in irc.freenode.net/#macdev for informing me this is how the first responder chain is initiated -// it turns out NSFontManager also sends changeFont: through this; let's inhibit that here too (see fontbutton.m) -- (BOOL)sendAction:(SEL)sel to:(id)to from:(id)from -{ - if (colorButtonInhibitSendAction(sel, from, to)) - return NO; - if (fontButtonInhibitSendAction(sel, from, to)) - return NO; - return [super sendAction:sel to:to from:from]; -} - -// likewise, NSFontManager also sends NSFontPanelValidation messages to the first responder, however it does NOT use sendAction:from:to:! -// instead, it uses this one (thanks swillits in irc.freenode.net/#macdev) -// we also need to override it (see fontbutton.m) -- (id)targetForAction:(SEL)sel to:(id)to from:(id)from -{ - id override; - - if (fontButtonOverrideTargetForAction(sel, from, to, &override)) - return override; - return [super targetForAction:sel to:to from:from]; -} - -// hey look! we're overriding terminate:! -// we're going to make sure we can go back to main() whether Cocoa likes it or not! -// and just how are we going to do that, hm? -// (note: this is called after applicationShouldTerminate:) -- (void)terminate:(id)sender -{ - // yes that's right folks: DO ABSOLUTELY NOTHING. - // the magic is [NSApp run] will just... stop. - - // well let's not do nothing; let's actually quit our graceful way - NSEvent *e; - - if (!canQuit) - implbug("call to [NSApp terminate:] when not ready to terminate; definitely contact andlabs"); - - [realNSApp() stop:realNSApp()]; - // stop: won't register until another event has passed; let's synthesize one - e = [NSEvent otherEventWithType:NSApplicationDefined - location:NSZeroPoint - modifierFlags:0 - timestamp:[[NSProcessInfo processInfo] systemUptime] - windowNumber:0 - context:[NSGraphicsContext currentContext] - subtype:0 - data1:0 - data2:0]; - [realNSApp() postEvent:e atStart:NO]; // let pending events take priority (this is what PostQuitMessage() on Windows does so we have to do it here too for parity; thanks to mikeash in irc.freenode.net/#macdev for confirming that this parameter should indeed be NO) - - // and in case uiMainSteps() was called - stepsIsRunning = NO; -} - -@end - -@implementation appDelegate - -- (void)dealloc -{ - // Apple docs: "Don't Use Accessor Methods in Initializer Methods and dealloc" - [_menuManager release]; - [super dealloc]; -} - -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app -{ - // for debugging - NSLog(@"in applicationShouldTerminate:"); - if (shouldQuit()) { - canQuit = YES; - // this will call terminate:, which is the same as uiQuit() - return NSTerminateNow; - } - return NSTerminateCancel; -} - -- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app -{ - return NO; -} - -@end - -uiInitOptions options; - -const char *uiInit(uiInitOptions *o) -{ - @autoreleasepool { - options = *o; - app = [[applicationClass sharedApplication] retain]; - // don't check for a NO return; something (launch services?) causes running from application bundles to always return NO when asking to change activation policy, even if the change is to the same activation policy! - // see https://github.com/andlabs/ui/issues/6 - [realNSApp() setActivationPolicy:NSApplicationActivationPolicyRegular]; - delegate = [appDelegate new]; - [realNSApp() setDelegate:delegate]; - - initAlloc(); - - // always do this so we always have an application menu - appDelegate().menuManager = [[menuManager new] autorelease]; - [realNSApp() setMainMenu:[appDelegate().menuManager makeMenubar]]; - - setupFontPanel(); - } - - globalPool = [[NSAutoreleasePool alloc] init]; - - return NULL; -} - -void uiUninit(void) -{ - if (!globalPool) { - userbug("You must call uiInit() first!"); - } - [globalPool release]; - - @autoreleasepool { - [delegate release]; - [realNSApp() setDelegate:nil]; - [app release]; - uninitAlloc(); - } -} - -void uiFreeInitError(const char *err) -{ -} - -void uiMain(void) -{ - isRunning = ^{ - return [realNSApp() isRunning]; - }; - [realNSApp() run]; -} - -void uiMainSteps(void) -{ - // SDL does this and it seems to be necessary for the menubar to work (see #182) - [realNSApp() finishLaunching]; - isRunning = ^{ - return stepsIsRunning; - }; - stepsIsRunning = YES; -} - -int uiMainStep(int wait) -{ - struct nextEventArgs nea; - - nea.mask = NSAnyEventMask; - - // ProPuke did this in his original PR requesting this - // I'm not sure if this will work, but I assume it will... - nea.duration = [NSDate distantPast]; - if (wait) // but this is normal so it will work - nea.duration = [NSDate distantFuture]; - - nea.mode = NSDefaultRunLoopMode; - nea.dequeue = YES; - - return mainStep(&nea, ^(NSEvent *e) { - return NO; - }); -} - -// see also: -// - http://www.cocoawithlove.com/2009/01/demystifying-nsapplication-by.html -// - https://github.com/gnustep/gui/blob/master/Source/NSApplication.m -int mainStep(struct nextEventArgs *nea, BOOL (^interceptEvent)(NSEvent *e)) -{ - NSDate *expire; - NSEvent *e; - NSEventType type; - - @autoreleasepool { - if (!isRunning()) - return 0; - - e = [realNSApp() nextEventMatchingMask:nea->mask - untilDate:nea->duration - inMode:nea->mode - dequeue:nea->dequeue]; - if (e == nil) - return 1; - - type = [e type]; - if (!interceptEvent(e)) - [realNSApp() sendEvent:e]; - [realNSApp() updateWindows]; - - // GNUstep does this - // it also updates the Services menu but there doesn't seem to be a public API for that so - if (type != NSPeriodic && type != NSMouseMoved) - [[realNSApp() mainMenu] update]; - - return 1; - } -} - -void uiQuit(void) -{ - canQuit = YES; - [realNSApp() terminate:realNSApp()]; -} - -// thanks to mikeash in irc.freenode.net/#macdev for suggesting the use of Grand Central Dispatch for this -// LONGTERM will dispatch_get_main_queue() break after _CFRunLoopSetCurrent()? -void uiQueueMain(void (*f)(void *data), void *data) -{ - // dispatch_get_main_queue() is a serial queue so it will not execute multiple uiQueueMain() functions concurrently - // the signature of f matches dispatch_function_t - dispatch_async_f(dispatch_get_main_queue(), data, f); -} diff --git a/deps/libui/darwin/map.m b/deps/libui/darwin/map.m deleted file mode 100644 index 46a7b8d242..0000000000 --- a/deps/libui/darwin/map.m +++ /dev/null @@ -1,59 +0,0 @@ -// 17 august 2015 -#import "uipriv_darwin.h" - -// unfortunately NSMutableDictionary copies its keys, meaning we can't use it for pointers -// hence, this file -// we could expose a NSMapTable directly, but let's treat all pointers as opaque and hide the implementation, just to be safe and prevent even more rewrites later -struct mapTable { - NSMapTable *m; -}; - -struct mapTable *newMap(void) -{ - struct mapTable *m; - - m = uiNew(struct mapTable); - m->m = [[NSMapTable alloc] initWithKeyOptions:(NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality) - valueOptions:(NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality) - capacity:0]; - return m; -} - -void mapDestroy(struct mapTable *m) -{ - if ([m->m count] != 0) - implbug("attempt to destroy map with items inside"); - [m->m release]; - uiFree(m); -} - -void *mapGet(struct mapTable *m, void *key) -{ - return NSMapGet(m->m, key); -} - -void mapSet(struct mapTable *m, void *key, void *value) -{ - NSMapInsert(m->m, key, value); -} - -void mapDelete(struct mapTable *m, void *key) -{ - NSMapRemove(m->m, key); -} - -void mapWalk(struct mapTable *m, void (*f)(void *key, void *value)) -{ - NSMapEnumerator e = NSEnumerateMapTable(m->m); - void *k = NULL; - void *v = NULL; - while (NSNextMapEnumeratorPair(&e, &k, &v)) { - f(k, v); - } - NSEndMapTableEnumeration(&e); -} - -void mapReset(struct mapTable *m) -{ - NSResetMapTable(m->m); -} diff --git a/deps/libui/darwin/menu.m b/deps/libui/darwin/menu.m deleted file mode 100644 index 735cac5052..0000000000 --- a/deps/libui/darwin/menu.m +++ /dev/null @@ -1,368 +0,0 @@ -// 28 april 2015 -#import "uipriv_darwin.h" - -static NSMutableArray *menus = nil; -static BOOL menusFinalized = NO; - -struct uiMenu { - NSMenu *menu; - NSMenuItem *item; - NSMutableArray *items; -}; - -struct uiMenuItem { - NSMenuItem *item; - int type; - BOOL disabled; - void (*onClicked)(uiMenuItem *, uiWindow *, void *); - void *onClickedData; -}; - -enum { - typeRegular, - typeCheckbox, - typeQuit, - typePreferences, - typeAbout, - typeSeparator, -}; - -static void mapItemReleaser(void *key, void *value) -{ - uiMenuItem *item; - - item = (uiMenuItem *)value; - [item->item release]; -} - -@implementation menuManager - -- (id)init -{ - self = [super init]; - if (self) { - self->items = newMap(); - self->hasQuit = NO; - self->hasPreferences = NO; - self->hasAbout = NO; - } - return self; -} - -- (void)dealloc -{ - mapWalk(self->items, mapItemReleaser); - mapReset(self->items); - mapDestroy(self->items); - uninitMenus(); - [super dealloc]; -} - -- (IBAction)onClicked:(id)sender -{ - uiMenuItem *item; - - item = (uiMenuItem *) mapGet(self->items, sender); - if (item->type == typeCheckbox) - uiMenuItemSetChecked(item, !uiMenuItemChecked(item)); - // use the key window as the source of the menu event; it's the active window - (*(item->onClicked))(item, windowFromNSWindow([realNSApp() keyWindow]), item->onClickedData); -} - -- (IBAction)onQuitClicked:(id)sender -{ - if (shouldQuit()) - uiQuit(); -} - -- (void)register:(NSMenuItem *)item to:(uiMenuItem *)smi -{ - switch (smi->type) { - case typeQuit: - if (self->hasQuit) - userbug("You can't have multiple Quit menu items in one program."); - self->hasQuit = YES; - break; - case typePreferences: - if (self->hasPreferences) - userbug("You can't have multiple Preferences menu items in one program."); - self->hasPreferences = YES; - break; - case typeAbout: - if (self->hasAbout) - userbug("You can't have multiple About menu items in one program."); - self->hasAbout = YES; - break; - } - mapSet(self->items, item, smi); -} - -// on OS X there are two ways to handle menu items being enabled or disabled: automatically and manually -// unfortunately, the application menu requires automatic menu handling for the Hide, Hide Others, and Show All items to work correctly -// therefore, we have to handle enabling of the other options ourselves -- (BOOL)validateMenuItem:(NSMenuItem *)item -{ - uiMenuItem *smi; - - // disable the special items if they aren't present - if (item == self.quitItem && !self->hasQuit) - return NO; - if (item == self.preferencesItem && !self->hasPreferences) - return NO; - if (item == self.aboutItem && !self->hasAbout) - return NO; - // then poll the item's enabled/disabled state - smi = (uiMenuItem *) mapGet(self->items, item); - return !smi->disabled; -} - -// Cocoa constructs the default application menu by hand for each program; that's what MainMenu.[nx]ib does -- (void)buildApplicationMenu:(NSMenu *)menubar -{ - NSString *appName; - NSMenuItem *appMenuItem; - NSMenu *appMenu; - NSMenuItem *item; - NSString *title; - NSMenu *servicesMenu; - - // note: no need to call setAppleMenu: on this anymore; see https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKitOlderNotes/#X10_6Notes - appName = [[NSProcessInfo processInfo] processName]; - appMenuItem = [[[NSMenuItem alloc] initWithTitle:appName action:NULL keyEquivalent:@""] autorelease]; - appMenu = [[[NSMenu alloc] initWithTitle:appName] autorelease]; - [appMenuItem setSubmenu:appMenu]; - [menubar addItem:appMenuItem]; - - // first is About - title = [@"About " stringByAppendingString:appName]; - item = [[[NSMenuItem alloc] initWithTitle:title action:@selector(onClicked:) keyEquivalent:@""] autorelease]; - [item setTarget:self]; - [appMenu addItem:item]; - self.aboutItem = item; - - [appMenu addItem:[NSMenuItem separatorItem]]; - - // next is Preferences - item = [[[NSMenuItem alloc] initWithTitle:@"Preferences…" action:@selector(onClicked:) keyEquivalent:@","] autorelease]; - [item setTarget:self]; - [appMenu addItem:item]; - self.preferencesItem = item; - - [appMenu addItem:[NSMenuItem separatorItem]]; - - // next is Services - item = [[[NSMenuItem alloc] initWithTitle:@"Services" action:NULL keyEquivalent:@""] autorelease]; - servicesMenu = [[[NSMenu alloc] initWithTitle:@"Services"] autorelease]; - [item setSubmenu:servicesMenu]; - [realNSApp() setServicesMenu:servicesMenu]; - [appMenu addItem:item]; - - [appMenu addItem:[NSMenuItem separatorItem]]; - - // next are the three hiding options - title = [@"Hide " stringByAppendingString:appName]; - item = [[[NSMenuItem alloc] initWithTitle:title action:@selector(hide:) keyEquivalent:@"h"] autorelease]; - // the .xib file says they go to -1 ("First Responder", which sounds wrong...) - // to do that, we simply leave the target as nil - [appMenu addItem:item]; - item = [[[NSMenuItem alloc] initWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"] autorelease]; - [item setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)]; - [appMenu addItem:item]; - item = [[[NSMenuItem alloc] initWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""] autorelease]; - [appMenu addItem:item]; - - [appMenu addItem:[NSMenuItem separatorItem]]; - - // and finally Quit - // DON'T use @selector(terminate:) as the action; we handle termination ourselves - title = [@"Quit " stringByAppendingString:appName]; - item = [[[NSMenuItem alloc] initWithTitle:title action:@selector(onQuitClicked:) keyEquivalent:@"q"] autorelease]; - [item setTarget:self]; - [appMenu addItem:item]; - self.quitItem = item; -} - -- (NSMenu *)makeMenubar -{ - NSMenu *menubar; - - menubar = [[[NSMenu alloc] initWithTitle:@""] autorelease]; - [self buildApplicationMenu:menubar]; - return menubar; -} - -@end - -static void defaultOnClicked(uiMenuItem *item, uiWindow *w, void *data) -{ - // do nothing -} - -void uiMenuItemEnable(uiMenuItem *item) -{ - item->disabled = NO; - // we don't need to explicitly update the menus here; they'll be updated the next time they're opened (thanks mikeash in irc.freenode.net/#macdev) -} - -void uiMenuItemDisable(uiMenuItem *item) -{ - item->disabled = YES; -} - -void uiMenuItemOnClicked(uiMenuItem *item, void (*f)(uiMenuItem *, uiWindow *, void *), void *data) -{ - if (item->type == typeQuit) - userbug("You can't call uiMenuItemOnClicked() on a Quit item; use uiOnShouldQuit() instead."); - item->onClicked = f; - item->onClickedData = data; -} - -int uiMenuItemChecked(uiMenuItem *item) -{ - return [item->item state] != NSOffState; -} - -void uiMenuItemSetChecked(uiMenuItem *item, int checked) -{ - NSInteger state; - - state = NSOffState; - if ([item->item state] == NSOffState) - state = NSOnState; - [item->item setState:state]; -} - -static uiMenuItem *newItem(uiMenu *m, int type, const char *name) -{ - @autoreleasepool { - - uiMenuItem *item; - - if (menusFinalized) - userbug("You can't create a new menu item after menus have been finalized."); - - item = uiNew(uiMenuItem); - - item->type = type; - switch (item->type) { - case typeQuit: - item->item = [appDelegate().menuManager.quitItem retain]; - break; - case typePreferences: - item->item = [appDelegate().menuManager.preferencesItem retain]; - break; - case typeAbout: - item->item = [appDelegate().menuManager.aboutItem retain]; - break; - case typeSeparator: - item->item = [[NSMenuItem separatorItem] retain]; - [m->menu addItem:item->item]; - break; - default: - item->item = [[NSMenuItem alloc] initWithTitle:toNSString(name) action:@selector(onClicked:) keyEquivalent:@""]; - [item->item setTarget:appDelegate().menuManager]; - [m->menu addItem:item->item]; - break; - } - - [appDelegate().menuManager register:item->item to:item]; - item->onClicked = defaultOnClicked; - - [m->items addObject:[NSValue valueWithPointer:item]]; - - return item; - - } // @autoreleasepool -} - -uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name) -{ - return newItem(m, typeRegular, name); -} - -uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const char *name) -{ - return newItem(m, typeCheckbox, name); -} - -uiMenuItem *uiMenuAppendQuitItem(uiMenu *m) -{ - // duplicate check is in the register:to: selector - return newItem(m, typeQuit, NULL); -} - -uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m) -{ - // duplicate check is in the register:to: selector - return newItem(m, typePreferences, NULL); -} - -uiMenuItem *uiMenuAppendAboutItem(uiMenu *m) -{ - // duplicate check is in the register:to: selector - return newItem(m, typeAbout, NULL); -} - -void uiMenuAppendSeparator(uiMenu *m) -{ - newItem(m, typeSeparator, NULL); -} - -uiMenu *uiNewMenu(const char *name) -{ - @autoreleasepool { - - uiMenu *m; - - if (menusFinalized) - userbug("You can't create a new menu after menus have been finalized."); - if (menus == nil) - menus = [NSMutableArray new]; - - m = uiNew(uiMenu); - - m->menu = [[NSMenu alloc] initWithTitle:toNSString(name)]; - // use automatic menu item enabling for all menus for consistency's sake - - m->item = [[NSMenuItem alloc] initWithTitle:toNSString(name) action:NULL keyEquivalent:@""]; - [m->item setSubmenu:m->menu]; - - m->items = [NSMutableArray new]; - - [[realNSApp() mainMenu] addItem:m->item]; - - [menus addObject:[NSValue valueWithPointer:m]]; - - return m; - - } // @autoreleasepool -} - -void finalizeMenus(void) -{ - menusFinalized = YES; -} - -void uninitMenus(void) -{ - if (menus == NULL) - return; - [menus enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) { - NSValue *v; - uiMenu *m; - - v = (NSValue *) obj; - m = (uiMenu *) [v pointerValue]; - [m->items enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) { - NSValue *v; - uiMenuItem *mi; - - v = (NSValue *) obj; - mi = (uiMenuItem *) [v pointerValue]; - uiFree(mi); - }]; - [m->items release]; - uiFree(m); - }]; - [menus release]; -} diff --git a/deps/libui/darwin/multilineentry.m b/deps/libui/darwin/multilineentry.m deleted file mode 100644 index 605e90041f..0000000000 --- a/deps/libui/darwin/multilineentry.m +++ /dev/null @@ -1,233 +0,0 @@ -// 8 december 2015 -#import "uipriv_darwin.h" - -// NSTextView has no intrinsic content size by default, which wreaks havoc on a pure-Auto Layout system -// we'll have to take over to get it to work -// see also http://stackoverflow.com/questions/24210153/nstextview-not-properly-resizing-with-auto-layout and http://stackoverflow.com/questions/11237622/using-autolayout-with-expanding-nstextviews -@interface intrinsicSizeTextView : NSTextView { - uiMultilineEntry *libui_e; -} -- (id)initWithFrame:(NSRect)r e:(uiMultilineEntry *)e; -@end - -struct uiMultilineEntry { - uiDarwinControl c; - NSScrollView *sv; - intrinsicSizeTextView *tv; - struct scrollViewData *d; - void (*onChanged)(uiMultilineEntry *, void *); - void *onChangedData; - BOOL changing; -}; - -@implementation intrinsicSizeTextView - -- (id)initWithFrame:(NSRect)r e:(uiMultilineEntry *)e -{ - self = [super initWithFrame:r]; - if (self) - self->libui_e = e; - return self; -} - -- (NSSize)intrinsicContentSize -{ - NSTextContainer *textContainer; - NSLayoutManager *layoutManager; - NSRect rect; - - textContainer = [self textContainer]; - layoutManager = [self layoutManager]; - [layoutManager ensureLayoutForTextContainer:textContainer]; - rect = [layoutManager usedRectForTextContainer:textContainer]; - return rect.size; -} - -- (void)didChangeText -{ - [super didChangeText]; - [self invalidateIntrinsicContentSize]; - if (!self->libui_e->changing) - (*(self->libui_e->onChanged))(self->libui_e, self->libui_e->onChangedData); -} - -@end - -uiDarwinControlAllDefaultsExceptDestroy(uiMultilineEntry, sv) - -static void uiMultilineEntryDestroy(uiControl *c) -{ - uiMultilineEntry *e = uiMultilineEntry(c); - - scrollViewFreeData(e->sv, e->d); - [e->tv release]; - [e->sv release]; - uiFreeControl(uiControl(e)); -} - -static void defaultOnChanged(uiMultilineEntry *e, void *data) -{ - // do nothing -} - -char *uiMultilineEntryText(uiMultilineEntry *e) -{ - return uiDarwinNSStringToText([e->tv string]); -} - -void uiMultilineEntrySetText(uiMultilineEntry *e, const char *text) -{ - [[e->tv textStorage] replaceCharactersInRange:NSMakeRange(0, [[e->tv string] length]) - withString:toNSString(text)]; - // must be called explicitly according to the documentation of shouldChangeTextInRange:replacementString: - e->changing = YES; - [e->tv didChangeText]; - e->changing = NO; -} - -// TODO scroll to end? -void uiMultilineEntryAppend(uiMultilineEntry *e, const char *text) -{ - [[e->tv textStorage] replaceCharactersInRange:NSMakeRange([[e->tv string] length], 0) - withString:toNSString(text)]; - e->changing = YES; - [e->tv didChangeText]; - e->changing = NO; -} - -void uiMultilineEntryOnChanged(uiMultilineEntry *e, void (*f)(uiMultilineEntry *e, void *data), void *data) -{ - e->onChanged = f; - e->onChangedData = data; -} - -int uiMultilineEntryReadOnly(uiMultilineEntry *e) -{ - return [e->tv isEditable] == NO; -} - -void uiMultilineEntrySetReadOnly(uiMultilineEntry *e, int readonly) -{ - BOOL editable; - - editable = YES; - if (readonly) - editable = NO; - [e->tv setEditable:editable]; -} - -static uiMultilineEntry *finishMultilineEntry(BOOL hscroll) -{ - uiMultilineEntry *e; - NSFont *font; - struct scrollViewCreateParams p; - - uiDarwinNewControl(uiMultilineEntry, e); - - e->tv = [[intrinsicSizeTextView alloc] initWithFrame:NSZeroRect e:e]; - - // verified against Interface Builder for a sufficiently customized text view - - // NSText properties: - // this is what Interface Builder sets the background color to - [e->tv setBackgroundColor:[NSColor colorWithCalibratedWhite:1.0 alpha:1.0]]; - [e->tv setDrawsBackground:YES]; - [e->tv setEditable:YES]; - [e->tv setSelectable:YES]; - [e->tv setFieldEditor:NO]; - [e->tv setRichText:NO]; - [e->tv setImportsGraphics:NO]; - [e->tv setUsesFontPanel:NO]; - [e->tv setRulerVisible:NO]; - // we'll handle font last - // while setAlignment: has been around since 10.0, the named constant "NSTextAlignmentNatural" seems to have only been introduced in 10.11 -#define ourNSTextAlignmentNatural 4 - [e->tv setAlignment:ourNSTextAlignmentNatural]; - // textColor is set to nil, just keep the dfault - [e->tv setBaseWritingDirection:NSWritingDirectionNatural]; - [e->tv setHorizontallyResizable:NO]; - [e->tv setVerticallyResizable:YES]; - - // NSTextView properties: - [e->tv setAllowsDocumentBackgroundColorChange:NO]; - [e->tv setAllowsUndo:YES]; - // default paragraph style is nil; keep default - [e->tv setAllowsImageEditing:NO]; - [e->tv setAutomaticQuoteSubstitutionEnabled:NO]; - [e->tv setAutomaticLinkDetectionEnabled:NO]; - [e->tv setDisplaysLinkToolTips:YES]; - [e->tv setUsesRuler:NO]; - [e->tv setUsesInspectorBar:NO]; - [e->tv setSelectionGranularity:NSSelectByCharacter]; - // there is a dedicated named insertion point color but oh well - [e->tv setInsertionPointColor:[NSColor controlTextColor]]; - // typing attributes is nil; keep default (we change it below for fonts though) - [e->tv setSmartInsertDeleteEnabled:NO]; - [e->tv setContinuousSpellCheckingEnabled:NO]; - [e->tv setGrammarCheckingEnabled:NO]; - [e->tv setUsesFindPanel:YES]; - [e->tv setEnabledTextCheckingTypes:0]; - [e->tv setAutomaticDashSubstitutionEnabled:NO]; - [e->tv setAutomaticDataDetectionEnabled:NO]; - [e->tv setAutomaticSpellingCorrectionEnabled:NO]; - [e->tv setAutomaticTextReplacementEnabled:NO]; - [e->tv setUsesFindBar:NO]; - [e->tv setIncrementalSearchingEnabled:NO]; - - // NSTextContainer properties: - [[e->tv textContainer] setWidthTracksTextView:YES]; - [[e->tv textContainer] setHeightTracksTextView:NO]; - - // NSLayoutManager properties: - [[e->tv layoutManager] setAllowsNonContiguousLayout:YES]; - - // now just to be safe; this will do some of the above but whatever - disableAutocorrect(e->tv); - - // see https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextUILayer/Tasks/TextInScrollView.html - // notice we don't use the Auto Layout code; see scrollview.m for more details - [e->tv setMaxSize:NSMakeSize(CGFLOAT_MAX, CGFLOAT_MAX)]; - [e->tv setVerticallyResizable:YES]; - [e->tv setHorizontallyResizable:hscroll]; - if (hscroll) { - [e->tv setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; - [[e->tv textContainer] setWidthTracksTextView:NO]; - } else { - [e->tv setAutoresizingMask:NSViewWidthSizable]; - [[e->tv textContainer] setWidthTracksTextView:YES]; - } - [[e->tv textContainer] setContainerSize:NSMakeSize(CGFLOAT_MAX, CGFLOAT_MAX)]; - - // don't use uiDarwinSetControlFont() directly; we have to do a little extra work to set the font - font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]; - [e->tv setTypingAttributes:[NSDictionary - dictionaryWithObject:font - forKey:NSFontAttributeName]]; - // e->tv font from Interface Builder is nil, but setFont:nil throws an exception - // let's just set it to the standard control font anyway, just to be safe - [e->tv setFont:font]; - - memset(&p, 0, sizeof (struct scrollViewCreateParams)); - p.DocumentView = e->tv; - // this is what Interface Builder sets it to - p.BackgroundColor = [NSColor colorWithCalibratedWhite:1.0 alpha:1.0]; - p.DrawsBackground = YES; - p.Bordered = YES; - p.HScroll = hscroll; - p.VScroll = YES; - e->sv = mkScrollView(&p, &(e->d)); - - uiMultilineEntryOnChanged(e, defaultOnChanged, NULL); - - return e; -} - -uiMultilineEntry *uiNewMultilineEntry(void) -{ - return finishMultilineEntry(NO); -} - -uiMultilineEntry *uiNewNonWrappingMultilineEntry(void) -{ - return finishMultilineEntry(YES); -} diff --git a/deps/libui/darwin/progressbar.m b/deps/libui/darwin/progressbar.m deleted file mode 100644 index b538228195..0000000000 --- a/deps/libui/darwin/progressbar.m +++ /dev/null @@ -1,78 +0,0 @@ -// 14 august 2015 -#import "uipriv_darwin.h" - -// NSProgressIndicator has no intrinsic width by default; use the default width in Interface Builder -#define progressIndicatorWidth 100 - -@interface intrinsicWidthNSProgressIndicator : NSProgressIndicator -@end - -@implementation intrinsicWidthNSProgressIndicator - -- (NSSize)intrinsicContentSize -{ - NSSize s; - - s = [super intrinsicContentSize]; - s.width = progressIndicatorWidth; - return s; -} - -@end - -struct uiProgressBar { - uiDarwinControl c; - NSProgressIndicator *pi; -}; - -uiDarwinControlAllDefaults(uiProgressBar, pi) - -int uiProgressBarValue(uiProgressBar *p) -{ - if ([p->pi isIndeterminate]) - return -1; - return [p->pi doubleValue]; -} - -void uiProgressBarSetValue(uiProgressBar *p, int value) -{ - if (value == -1) { - [p->pi setIndeterminate:YES]; - [p->pi startAnimation:p->pi]; - return; - } - - if ([p->pi isIndeterminate]) { - [p->pi setIndeterminate:NO]; - [p->pi stopAnimation:p->pi]; - } - - if (value < 0 || value > 100) - userbug("Value %d out of range for a uiProgressBar.", value); - - // on 10.8 there's an animation when the progress bar increases, just like with Aero - if (value == 100) { - [p->pi setMaxValue:101]; - [p->pi setDoubleValue:101]; - [p->pi setDoubleValue:100]; - [p->pi setMaxValue:100]; - return; - } - [p->pi setDoubleValue:((double) (value + 1))]; - [p->pi setDoubleValue:((double) value)]; -} - -uiProgressBar *uiNewProgressBar(void) -{ - uiProgressBar *p; - - uiDarwinNewControl(uiProgressBar, p); - - p->pi = [[intrinsicWidthNSProgressIndicator alloc] initWithFrame:NSZeroRect]; - [p->pi setControlSize:NSRegularControlSize]; - [p->pi setBezeled:YES]; - [p->pi setStyle:NSProgressIndicatorBarStyle]; - [p->pi setIndeterminate:NO]; - - return p; -} diff --git a/deps/libui/darwin/radiobuttons.m b/deps/libui/darwin/radiobuttons.m deleted file mode 100644 index 25d773c972..0000000000 --- a/deps/libui/darwin/radiobuttons.m +++ /dev/null @@ -1,207 +0,0 @@ -// 14 august 2015 -#import "uipriv_darwin.h" - -// TODO resizing the controlgallery vertically causes the third button to still resize :| - -// In the old days you would use a NSMatrix for this; as of OS X 10.8 this was deprecated and now you need just a bunch of NSButtons with the same superview AND same action method. -// This is documented on the NSMatrix page, but the rest of the OS X documentation says to still use NSMatrix. -// NSMatrix has weird quirks anyway... - -// LONGTERM 6 units of spacing between buttons, as suggested by Interface Builder? - -@interface radioButtonsDelegate : NSObject { - uiRadioButtons *libui_r; -} -- (id)initWithR:(uiRadioButtons *)r; -- (IBAction)onClicked:(id)sender; -@end - -struct uiRadioButtons { - uiDarwinControl c; - NSView *view; - NSMutableArray *buttons; - NSMutableArray *constraints; - NSLayoutConstraint *lastv; - radioButtonsDelegate *delegate; - void (*onSelected)(uiRadioButtons *, void *); - void *onSelectedData; -}; - -@implementation radioButtonsDelegate - -- (id)initWithR:(uiRadioButtons *)r -{ - self = [super init]; - if (self) - self->libui_r = r; - return self; -} - -- (IBAction)onClicked:(id)sender -{ - uiRadioButtons *r = self->libui_r; - - (*(r->onSelected))(r, r->onSelectedData); -} - -@end - -uiDarwinControlAllDefaultsExceptDestroy(uiRadioButtons, view) - -static void defaultOnSelected(uiRadioButtons *r, void *data) -{ - // do nothing -} - -static void uiRadioButtonsDestroy(uiControl *c) -{ - uiRadioButtons *r = uiRadioButtons(c); - NSButton *b; - - // drop the constraints - [r->view removeConstraints:r->constraints]; - [r->constraints release]; - if (r->lastv != nil) - [r->lastv release]; - // destroy the buttons - for (b in r->buttons) { - [b setTarget:nil]; - [b removeFromSuperview]; - } - [r->buttons release]; - // destroy the delegate - [r->delegate release]; - // and destroy ourselves - [r->view release]; - uiFreeControl(uiControl(r)); -} - -static NSButton *buttonAt(uiRadioButtons *r, int n) -{ - return (NSButton *) [r->buttons objectAtIndex:n]; -} - -void uiRadioButtonsAppend(uiRadioButtons *r, const char *text) -{ - NSButton *b, *b2; - NSLayoutConstraint *constraint; - - b = [[NSButton alloc] initWithFrame:NSZeroRect]; - [b setTitle:toNSString(text)]; - [b setButtonType:NSRadioButton]; - // doesn't seem to have an associated bezel style - [b setBordered:NO]; - [b setTransparent:NO]; - uiDarwinSetControlFont(b, NSRegularControlSize); - [b setTranslatesAutoresizingMaskIntoConstraints:NO]; - - [b setTarget:r->delegate]; - [b setAction:@selector(onClicked:)]; - - [r->buttons addObject:b]; - [r->view addSubview:b]; - - // pin horizontally to the edges of the superview - constraint = mkConstraint(b, NSLayoutAttributeLeading, - NSLayoutRelationEqual, - r->view, NSLayoutAttributeLeading, - 1, 0, - @"uiRadioButtons button leading constraint"); - [r->view addConstraint:constraint]; - [r->constraints addObject:constraint]; - constraint = mkConstraint(b, NSLayoutAttributeTrailing, - NSLayoutRelationEqual, - r->view, NSLayoutAttributeTrailing, - 1, 0, - @"uiRadioButtons button trailing constraint"); - [r->view addConstraint:constraint]; - [r->constraints addObject:constraint]; - - // if this is the first view, pin it to the top - // otherwise pin to the bottom of the last - if ([r->buttons count] == 1) - constraint = mkConstraint(b, NSLayoutAttributeTop, - NSLayoutRelationEqual, - r->view, NSLayoutAttributeTop, - 1, 0, - @"uiRadioButtons first button top constraint"); - else { - b2 = buttonAt(r, [r->buttons count] - 2); - constraint = mkConstraint(b, NSLayoutAttributeTop, - NSLayoutRelationEqual, - b2, NSLayoutAttributeBottom, - 1, 0, - @"uiRadioButtons non-first button top constraint"); - } - [r->view addConstraint:constraint]; - [r->constraints addObject:constraint]; - - // if there is a previous bottom constraint, remove it - if (r->lastv != nil) { - [r->view removeConstraint:r->lastv]; - [r->constraints removeObject:r->lastv]; - [r->lastv release]; - } - - // and make the new bottom constraint - r->lastv = mkConstraint(b, NSLayoutAttributeBottom, - NSLayoutRelationEqual, - r->view, NSLayoutAttributeBottom, - 1, 0, - @"uiRadioButtons last button bottom constraint"); - [r->view addConstraint:r->lastv]; - [r->constraints addObject:r->lastv]; - [r->lastv retain]; -} - -int uiRadioButtonsSelected(uiRadioButtons *r) -{ - NSButton *b; - NSUInteger i; - - for (i = 0; i < [r->buttons count]; i++) { - b = (NSButton *) [r->buttons objectAtIndex:i]; - if ([b state] == NSOnState) - return i; - } - return -1; -} - -void uiRadioButtonsSetSelected(uiRadioButtons *r, int n) -{ - NSButton *b; - NSInteger state; - - state = NSOnState; - if (n == -1) { - n = uiRadioButtonsSelected(r); - if (n == -1) // from nothing to nothing; do nothing - return; - state = NSOffState; - } - b = (NSButton *) [r->buttons objectAtIndex:n]; - [b setState:state]; -} - -void uiRadioButtonsOnSelected(uiRadioButtons *r, void (*f)(uiRadioButtons *, void *), void *data) -{ - r->onSelected = f; - r->onSelectedData = data; -} - -uiRadioButtons *uiNewRadioButtons(void) -{ - uiRadioButtons *r; - - uiDarwinNewControl(uiRadioButtons, r); - - r->view = [[NSView alloc] initWithFrame:NSZeroRect]; - r->buttons = [NSMutableArray new]; - r->constraints = [NSMutableArray new]; - - r->delegate = [[radioButtonsDelegate alloc] initWithR:r]; - - uiRadioButtonsOnSelected(r, defaultOnSelected, NULL); - - return r; -} diff --git a/deps/libui/darwin/scrollview.m b/deps/libui/darwin/scrollview.m deleted file mode 100644 index b0b4040c3a..0000000000 --- a/deps/libui/darwin/scrollview.m +++ /dev/null @@ -1,61 +0,0 @@ -// 27 may 2016 -#include "uipriv_darwin.h" - -// see http://stackoverflow.com/questions/37979445/how-do-i-properly-set-up-a-scrolling-nstableview-using-auto-layout-what-ive-tr for why we don't use auto layout -// TODO do the same with uiGroup and uiTab? - -struct scrollViewData { - BOOL hscroll; - BOOL vscroll; -}; - -NSScrollView *mkScrollView(struct scrollViewCreateParams *p, struct scrollViewData **dout) -{ - NSScrollView *sv; - NSBorderType border; - struct scrollViewData *d; - - sv = [[NSScrollView alloc] initWithFrame:NSZeroRect]; - if (p->BackgroundColor != nil) - [sv setBackgroundColor:p->BackgroundColor]; - [sv setDrawsBackground:p->DrawsBackground]; - border = NSNoBorder; - if (p->Bordered) - border = NSBezelBorder; - // document view seems to set the cursor properly - [sv setBorderType:border]; - [sv setAutohidesScrollers:YES]; - [sv setHasHorizontalRuler:NO]; - [sv setHasVerticalRuler:NO]; - [sv setRulersVisible:NO]; - [sv setScrollerKnobStyle:NSScrollerKnobStyleDefault]; - // the scroller style is documented as being set by default for us - // LONGTERM verify line and page for programmatically created NSTableView - [sv setScrollsDynamically:YES]; - [sv setFindBarPosition:NSScrollViewFindBarPositionAboveContent]; - [sv setUsesPredominantAxisScrolling:NO]; - [sv setHorizontalScrollElasticity:NSScrollElasticityAutomatic]; - [sv setVerticalScrollElasticity:NSScrollElasticityAutomatic]; - [sv setAllowsMagnification:NO]; - - [sv setDocumentView:p->DocumentView]; - d = uiNew(struct scrollViewData); - scrollViewSetScrolling(sv, d, p->HScroll, p->VScroll); - - *dout = d; - return sv; -} - -// based on http://blog.bjhomer.com/2014/08/nsscrollview-and-autolayout.html because (as pointed out there) Apple's official guide is really only for iOS -void scrollViewSetScrolling(NSScrollView *sv, struct scrollViewData *d, BOOL hscroll, BOOL vscroll) -{ - d->hscroll = hscroll; - [sv setHasHorizontalScroller:d->hscroll]; - d->vscroll = vscroll; - [sv setHasVerticalScroller:d->vscroll]; -} - -void scrollViewFreeData(NSScrollView *sv, struct scrollViewData *d) -{ - uiFree(d); -} diff --git a/deps/libui/darwin/separator.m b/deps/libui/darwin/separator.m deleted file mode 100644 index a37a376e75..0000000000 --- a/deps/libui/darwin/separator.m +++ /dev/null @@ -1,45 +0,0 @@ -// 14 august 2015 -#import "uipriv_darwin.h" - -// TODO make this intrinsic -#define separatorWidth 96 -#define separatorHeight 96 - -struct uiSeparator { - uiDarwinControl c; - NSBox *box; -}; - -uiDarwinControlAllDefaults(uiSeparator, box) - -uiSeparator *uiNewHorizontalSeparator(void) -{ - uiSeparator *s; - - uiDarwinNewControl(uiSeparator, s); - - // make the initial width >= initial height to force horizontal - s->box = [[NSBox alloc] initWithFrame:NSMakeRect(0, 0, 100, 1)]; - [s->box setBoxType:NSBoxSeparator]; - [s->box setBorderType:NSGrooveBorder]; - [s->box setTransparent:NO]; - [s->box setTitlePosition:NSNoTitle]; - - return s; -} - -uiSeparator *uiNewVerticalSeparator(void) -{ - uiSeparator *s; - - uiDarwinNewControl(uiSeparator, s); - - // make the initial height >= initial width to force vertical - s->box = [[NSBox alloc] initWithFrame:NSMakeRect(0, 0, 1, 100)]; - [s->box setBoxType:NSBoxSeparator]; - [s->box setBorderType:NSGrooveBorder]; - [s->box setTransparent:NO]; - [s->box setTitlePosition:NSNoTitle]; - - return s; -} diff --git a/deps/libui/darwin/slider.m b/deps/libui/darwin/slider.m deleted file mode 100644 index f00da50fdd..0000000000 --- a/deps/libui/darwin/slider.m +++ /dev/null @@ -1,147 +0,0 @@ -// 14 august 2015 -#import "uipriv_darwin.h" - -// Horizontal sliders have no intrinsic width; we'll use the default Interface Builder width for them. -// This will also be used for the initial frame size, to ensure the slider is always horizontal (see below). -#define sliderWidth 92 - -@interface libui_intrinsicWidthNSSlider : NSSlider -@end - -@implementation libui_intrinsicWidthNSSlider - -- (NSSize)intrinsicContentSize -{ - NSSize s; - - s = [super intrinsicContentSize]; - s.width = sliderWidth; - return s; -} - -@end - -struct uiSlider { - uiDarwinControl c; - NSSlider *slider; - void (*onChanged)(uiSlider *, void *); - void *onChangedData; -}; - -@interface sliderDelegateClass : NSObject { - struct mapTable *sliders; -} -- (IBAction)onChanged:(id)sender; -- (void)registerSlider:(uiSlider *)b; -- (void)unregisterSlider:(uiSlider *)b; -@end - -@implementation sliderDelegateClass - -- (id)init -{ - self = [super init]; - if (self) - self->sliders = newMap(); - return self; -} - -- (void)dealloc -{ - mapDestroy(self->sliders); - [super dealloc]; -} - -- (IBAction)onChanged:(id)sender -{ - uiSlider *s; - - s = (uiSlider *) mapGet(self->sliders, sender); - (*(s->onChanged))(s, s->onChangedData); -} - -- (void)registerSlider:(uiSlider *)s -{ - mapSet(self->sliders, s->slider, s); - [s->slider setTarget:self]; - [s->slider setAction:@selector(onChanged:)]; -} - -- (void)unregisterSlider:(uiSlider *)s -{ - [s->slider setTarget:nil]; - mapDelete(self->sliders, s->slider); -} - -@end - -static sliderDelegateClass *sliderDelegate = nil; - -uiDarwinControlAllDefaultsExceptDestroy(uiSlider, slider) - -static void uiSliderDestroy(uiControl *c) -{ - uiSlider *s = uiSlider(c); - - [sliderDelegate unregisterSlider:s]; - [s->slider release]; - uiFreeControl(uiControl(s)); -} - -int uiSliderValue(uiSlider *s) -{ - return [s->slider integerValue]; -} - -void uiSliderSetValue(uiSlider *s, int value) -{ - [s->slider setIntegerValue:value]; -} - -void uiSliderOnChanged(uiSlider *s, void (*f)(uiSlider *, void *), void *data) -{ - s->onChanged = f; - s->onChangedData = data; -} - -static void defaultOnChanged(uiSlider *s, void *data) -{ - // do nothing -} - -uiSlider *uiNewSlider(int min, int max) -{ - uiSlider *s; - NSSliderCell *cell; - int temp; - - if (min >= max) { - temp = min; - min = max; - max = temp; - } - - uiDarwinNewControl(uiSlider, s); - - // a horizontal slider is defined as one where the width > height, not by a flag - // to be safe, don't use NSZeroRect, but make it horizontal from the get-go - s->slider = [[libui_intrinsicWidthNSSlider alloc] - initWithFrame:NSMakeRect(0, 0, sliderWidth, 2)]; - [s->slider setMinValue:min]; - [s->slider setMaxValue:max]; - [s->slider setAllowsTickMarkValuesOnly:NO]; - [s->slider setNumberOfTickMarks:0]; - [s->slider setTickMarkPosition:NSTickMarkAbove]; - - cell = (NSSliderCell *) [s->slider cell]; - [cell setSliderType:NSLinearSlider]; - - if (sliderDelegate == nil) { - sliderDelegate = [[sliderDelegateClass new] autorelease]; - [delegates addObject:sliderDelegate]; - } - [sliderDelegate registerSlider:s]; - uiSliderOnChanged(s, defaultOnChanged, NULL); - - return s; -} diff --git a/deps/libui/darwin/spinbox.m b/deps/libui/darwin/spinbox.m deleted file mode 100644 index 73474d04e0..0000000000 --- a/deps/libui/darwin/spinbox.m +++ /dev/null @@ -1,214 +0,0 @@ -// 14 august 2015 -#import "uipriv_darwin.h" - -@interface libui_spinbox : NSView { - NSTextField *tf; - NSNumberFormatter *formatter; - NSStepper *stepper; - - NSInteger value; - NSInteger minimum; - NSInteger maximum; - - uiSpinbox *spinbox; -} -- (id)initWithFrame:(NSRect)r spinbox:(uiSpinbox *)sb; -// see https://github.com/andlabs/ui/issues/82 -- (NSInteger)libui_value; -- (void)libui_setValue:(NSInteger)val; -- (void)setMinimum:(NSInteger)min; -- (void)setMaximum:(NSInteger)max; -- (IBAction)stepperClicked:(id)sender; -- (void)controlTextDidChange:(NSNotification *)note; -@end - -struct uiSpinbox { - uiDarwinControl c; - libui_spinbox *spinbox; - void (*onChanged)(uiSpinbox *, void *); - void *onChangedData; -}; - -// yes folks, this varies by operating system! woo! -// 10.10 started drawing the NSStepper one point too low, so we have to fix it up conditionally -// TODO test this; we'll probably have to substitute 10_9 -static CGFloat stepperYDelta(void) -{ - // via https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKit/ - if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9) - return 0; - return -1; -} - -@implementation libui_spinbox - -- (id)initWithFrame:(NSRect)r spinbox:(uiSpinbox *)sb -{ - self = [super initWithFrame:r]; - if (self) { - self->tf = newEditableTextField(); - [self->tf setTranslatesAutoresizingMaskIntoConstraints:NO]; - - self->formatter = [NSNumberFormatter new]; - [self->formatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; - [self->formatter setLocalizesFormat:NO]; - [self->formatter setUsesGroupingSeparator:NO]; - [self->formatter setHasThousandSeparators:NO]; - [self->formatter setAllowsFloats:NO]; - [self->tf setFormatter:self->formatter]; - - self->stepper = [[NSStepper alloc] initWithFrame:NSZeroRect]; - [self->stepper setIncrement:1]; - [self->stepper setValueWraps:NO]; - [self->stepper setAutorepeat:YES]; // hold mouse button to step repeatedly - [self->stepper setTranslatesAutoresizingMaskIntoConstraints:NO]; - - [self->tf setDelegate:self]; - [self->stepper setTarget:self]; - [self->stepper setAction:@selector(stepperClicked:)]; - - [self addSubview:self->tf]; - [self addSubview:self->stepper]; - - [self addConstraint:mkConstraint(self->tf, NSLayoutAttributeLeading, - NSLayoutRelationEqual, - self, NSLayoutAttributeLeading, - 1, 0, - @"uiSpinbox left edge")]; - [self addConstraint:mkConstraint(self->stepper, NSLayoutAttributeTrailing, - NSLayoutRelationEqual, - self, NSLayoutAttributeTrailing, - 1, 0, - @"uiSpinbox right edge")]; - [self addConstraint:mkConstraint(self->tf, NSLayoutAttributeTop, - NSLayoutRelationEqual, - self, NSLayoutAttributeTop, - 1, 0, - @"uiSpinbox top edge text field")]; - [self addConstraint:mkConstraint(self->tf, NSLayoutAttributeBottom, - NSLayoutRelationEqual, - self, NSLayoutAttributeBottom, - 1, 0, - @"uiSpinbox bottom edge text field")]; - [self addConstraint:mkConstraint(self->stepper, NSLayoutAttributeTop, - NSLayoutRelationEqual, - self, NSLayoutAttributeTop, - 1, stepperYDelta(), - @"uiSpinbox top edge stepper")]; - [self addConstraint:mkConstraint(self->stepper, NSLayoutAttributeBottom, - NSLayoutRelationEqual, - self, NSLayoutAttributeBottom, - 1, stepperYDelta(), - @"uiSpinbox bottom edge stepper")]; - [self addConstraint:mkConstraint(self->tf, NSLayoutAttributeTrailing, - NSLayoutRelationEqual, - self->stepper, NSLayoutAttributeLeading, - 1, -3, // arbitrary amount; good enough visually (and it seems to match NSDatePicker too, at least on 10.11, which is even better) - @"uiSpinbox space between text field and stepper")]; - - self->spinbox = sb; - } - return self; -} - -- (void)dealloc -{ - [self->tf setDelegate:nil]; - [self->tf removeFromSuperview]; - [self->tf release]; - [self->formatter release]; - [self->stepper setTarget:nil]; - [self->stepper removeFromSuperview]; - [self->stepper release]; - [super dealloc]; -} - -- (NSInteger)libui_value -{ - return self->value; -} - -- (void)libui_setValue:(NSInteger)val -{ - self->value = val; - if (self->value < self->minimum) - self->value = self->minimum; - if (self->value > self->maximum) - self->value = self->maximum; - [self->tf setIntegerValue:self->value]; - [self->stepper setIntegerValue:self->value]; -} - -- (void)setMinimum:(NSInteger)min -{ - self->minimum = min; - [self->formatter setMinimum:[NSNumber numberWithInteger:self->minimum]]; - [self->stepper setMinValue:((double) (self->minimum))]; -} - -- (void)setMaximum:(NSInteger)max -{ - self->maximum = max; - [self->formatter setMaximum:[NSNumber numberWithInteger:self->maximum]]; - [self->stepper setMaxValue:((double) (self->maximum))]; -} - -- (IBAction)stepperClicked:(id)sender -{ - [self libui_setValue:[self->stepper integerValue]]; - (*(self->spinbox->onChanged))(self->spinbox, self->spinbox->onChangedData); -} - -- (void)controlTextDidChange:(NSNotification *)note -{ - [self libui_setValue:[self->tf integerValue]]; - (*(self->spinbox->onChanged))(self->spinbox, self->spinbox->onChangedData); -} - -@end - -uiDarwinControlAllDefaults(uiSpinbox, spinbox) - -int uiSpinboxValue(uiSpinbox *s) -{ - return [s->spinbox libui_value]; -} - -void uiSpinboxSetValue(uiSpinbox *s, int value) -{ - [s->spinbox libui_setValue:value]; -} - -void uiSpinboxOnChanged(uiSpinbox *s, void (*f)(uiSpinbox *, void *), void *data) -{ - s->onChanged = f; - s->onChangedData = data; -} - -static void defaultOnChanged(uiSpinbox *s, void *data) -{ - // do nothing -} - -uiSpinbox *uiNewSpinbox(int min, int max) -{ - uiSpinbox *s; - int temp; - - if (min >= max) { - temp = min; - min = max; - max = temp; - } - - uiDarwinNewControl(uiSpinbox, s); - - s->spinbox = [[libui_spinbox alloc] initWithFrame:NSZeroRect spinbox:s]; - [s->spinbox setMinimum:min]; - [s->spinbox setMaximum:max]; - [s->spinbox libui_setValue:min]; - - uiSpinboxOnChanged(s, defaultOnChanged, NULL); - - return s; -} diff --git a/deps/libui/darwin/stddialogs.m b/deps/libui/darwin/stddialogs.m deleted file mode 100644 index 57ce9596ad..0000000000 --- a/deps/libui/darwin/stddialogs.m +++ /dev/null @@ -1,123 +0,0 @@ -// 26 june 2015 -#import "uipriv_darwin.h" - -// LONGTERM restructure this whole file -// LONGTERM explicitly document this works as we want -// LONGTERM note that font and color buttons also do this - -#define windowWindow(w) ((NSWindow *) uiControlHandle(uiControl(w))) - -// source of code modal logic: http://stackoverflow.com/questions/604768/wait-for-nsalert-beginsheetmodalforwindow - -// note: whether extensions are actually shown depends on a user setting in Finder; we can't control it here -static void setupSavePanel(NSSavePanel *s) -{ - [s setCanCreateDirectories:YES]; - [s setShowsHiddenFiles:YES]; - [s setExtensionHidden:NO]; - [s setCanSelectHiddenExtension:NO]; - [s setTreatsFilePackagesAsDirectories:YES]; -} - -static char *runSavePanel(NSWindow *parent, NSSavePanel *s) -{ - char *filename; - - [s beginSheetModalForWindow:parent completionHandler:^(NSInteger result) { - [realNSApp() stopModalWithCode:result]; - }]; - if ([realNSApp() runModalForWindow:s] != NSFileHandlingPanelOKButton) - return NULL; - filename = uiDarwinNSStringToText([[s URL] path]); - return filename; -} - -char *uiOpenFile(uiWindow *parent) -{ - NSOpenPanel *o; - - o = [NSOpenPanel openPanel]; - [o setCanChooseFiles:YES]; - [o setCanChooseDirectories:NO]; - [o setResolvesAliases:NO]; - [o setAllowsMultipleSelection:NO]; - setupSavePanel(o); - // panel is autoreleased - return runSavePanel(windowWindow(parent), o); -} - -char *uiSaveFile(uiWindow *parent) -{ - NSSavePanel *s; - - s = [NSSavePanel savePanel]; - setupSavePanel(s); - // panel is autoreleased - return runSavePanel(windowWindow(parent), s); -} - -// I would use a completion handler for NSAlert as well, but alas NSAlert's are 10.9 and higher only -@interface libuiCodeModalAlertPanel : NSObject { - NSAlert *panel; - NSWindow *parent; -} -- (id)initWithPanel:(NSAlert *)p parent:(NSWindow *)w; -- (NSInteger)run; -- (void)panelEnded:(NSAlert *)panel result:(NSInteger)result data:(void *)data; -@end - -@implementation libuiCodeModalAlertPanel - -- (id)initWithPanel:(NSAlert *)p parent:(NSWindow *)w -{ - self = [super init]; - if (self) { - self->panel = p; - self->parent = w; - } - return self; -} - -- (NSInteger)run -{ - [self->panel beginSheetModalForWindow:self->parent - modalDelegate:self - didEndSelector:@selector(panelEnded:result:data:) - contextInfo:NULL]; - return [realNSApp() runModalForWindow:[self->panel window]]; -} - -- (void)panelEnded:(NSAlert *)panel result:(NSInteger)result data:(void *)data -{ - [realNSApp() stopModalWithCode:result]; -} - -@end - -static void msgbox(NSWindow *parent, const char *title, const char *description, NSAlertStyle style) -{ - NSAlert *a; - libuiCodeModalAlertPanel *cm; - - a = [NSAlert new]; - [a setAlertStyle:style]; - [a setShowsHelp:NO]; - [a setShowsSuppressionButton:NO]; - [a setMessageText:toNSString(title)]; - [a setInformativeText:toNSString(description)]; - [a addButtonWithTitle:@"OK"]; - cm = [[libuiCodeModalAlertPanel alloc] initWithPanel:a parent:parent]; - [cm run]; - [cm release]; - [a release]; -} - -void uiMsgBox(uiWindow *parent, const char *title, const char *description) -{ - msgbox(windowWindow(parent), title, description, NSInformationalAlertStyle); -} - -void uiMsgBoxError(uiWindow *parent, const char *title, const char *description) -{ - msgbox(windowWindow(parent), title, description, NSCriticalAlertStyle); -} diff --git a/deps/libui/darwin/tab.m b/deps/libui/darwin/tab.m deleted file mode 100644 index 3d2ca9f0d0..0000000000 --- a/deps/libui/darwin/tab.m +++ /dev/null @@ -1,292 +0,0 @@ -// 15 august 2015 -#import "uipriv_darwin.h" - -// TODO need to jiggle on tab change too (second page disabled tab label initially ambiguous) - -@interface tabPage : NSObject { - struct singleChildConstraints constraints; - int margined; - NSView *view; // the NSTabViewItem view itself - NSObject *pageID; -} -@property uiControl *c; -@property NSLayoutPriority oldHorzHuggingPri; -@property NSLayoutPriority oldVertHuggingPri; -- (id)initWithView:(NSView *)v pageID:(NSObject *)o; -- (NSView *)childView; -- (void)establishChildConstraints; -- (void)removeChildConstraints; -- (int)isMargined; -- (void)setMargined:(int)m; -@end - -struct uiTab { - uiDarwinControl c; - NSTabView *tabview; - NSMutableArray *pages; - NSLayoutPriority horzHuggingPri; - NSLayoutPriority vertHuggingPri; -}; - -@implementation tabPage - -- (id)initWithView:(NSView *)v pageID:(NSObject *)o -{ - self = [super init]; - if (self != nil) { - self->view = [v retain]; - self->pageID = [o retain]; - } - return self; -} - -- (void)dealloc -{ - [self removeChildConstraints]; - [self->view release]; - [self->pageID release]; - [super dealloc]; -} - -- (NSView *)childView -{ - return (NSView *) uiControlHandle(self.c); -} - -- (void)establishChildConstraints -{ - [self removeChildConstraints]; - if (self.c == NULL) - return; - singleChildConstraintsEstablish(&(self->constraints), - self->view, [self childView], - uiDarwinControlHugsTrailingEdge(uiDarwinControl(self.c)), - uiDarwinControlHugsBottom(uiDarwinControl(self.c)), - self->margined, - @"uiTab page"); -} - -- (void)removeChildConstraints -{ - singleChildConstraintsRemove(&(self->constraints), self->view); -} - -- (int)isMargined -{ - return self->margined; -} - -- (void)setMargined:(int)m -{ - self->margined = m; - singleChildConstraintsSetMargined(&(self->constraints), self->margined); -} - -@end - -static void uiTabDestroy(uiControl *c) -{ - uiTab *t = uiTab(c); - tabPage *page; - - // first remove all tab pages so we can destroy all the children - while ([t->tabview numberOfTabViewItems] != 0) - [t->tabview removeTabViewItem:[t->tabview tabViewItemAtIndex:0]]; - // then destroy all the children - for (page in t->pages) { - [page removeChildConstraints]; - uiControlSetParent(page.c, NULL); - uiDarwinControlSetSuperview(uiDarwinControl(page.c), nil); - uiControlDestroy(page.c); - } - // and finally destroy ourselves - [t->pages release]; - [t->tabview release]; - uiFreeControl(uiControl(t)); -} - -uiDarwinControlDefaultHandle(uiTab, tabview) -uiDarwinControlDefaultParent(uiTab, tabview) -uiDarwinControlDefaultSetParent(uiTab, tabview) -uiDarwinControlDefaultToplevel(uiTab, tabview) -uiDarwinControlDefaultVisible(uiTab, tabview) -uiDarwinControlDefaultShow(uiTab, tabview) -uiDarwinControlDefaultHide(uiTab, tabview) -uiDarwinControlDefaultEnabled(uiTab, tabview) -uiDarwinControlDefaultEnable(uiTab, tabview) -uiDarwinControlDefaultDisable(uiTab, tabview) - -static void uiTabSyncEnableState(uiDarwinControl *c, int enabled) -{ - uiTab *t = uiTab(c); - tabPage *page; - - if (uiDarwinShouldStopSyncEnableState(uiDarwinControl(t), enabled)) - return; - for (page in t->pages) - uiDarwinControlSyncEnableState(uiDarwinControl(page.c), enabled); -} - -uiDarwinControlDefaultSetSuperview(uiTab, tabview) - -static void tabRelayout(uiTab *t) -{ - tabPage *page; - - for (page in t->pages) - [page establishChildConstraints]; - // and this gets rid of some weird issues with regards to box alignment - jiggleViewLayout(t->tabview); -} - -BOOL uiTabHugsTrailingEdge(uiDarwinControl *c) -{ - uiTab *t = uiTab(c); - - return t->horzHuggingPri < NSLayoutPriorityWindowSizeStayPut; -} - -BOOL uiTabHugsBottom(uiDarwinControl *c) -{ - uiTab *t = uiTab(c); - - return t->vertHuggingPri < NSLayoutPriorityWindowSizeStayPut; -} - -static void uiTabChildEdgeHuggingChanged(uiDarwinControl *c) -{ - uiTab *t = uiTab(c); - - tabRelayout(t); -} - -static NSLayoutPriority uiTabHuggingPriority(uiDarwinControl *c, NSLayoutConstraintOrientation orientation) -{ - uiTab *t = uiTab(c); - - if (orientation == NSLayoutConstraintOrientationHorizontal) - return t->horzHuggingPri; - return t->vertHuggingPri; -} - -static void uiTabSetHuggingPriority(uiDarwinControl *c, NSLayoutPriority priority, NSLayoutConstraintOrientation orientation) -{ - uiTab *t = uiTab(c); - - if (orientation == NSLayoutConstraintOrientationHorizontal) - t->horzHuggingPri = priority; - else - t->vertHuggingPri = priority; - uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(t)); -} - -static void uiTabChildVisibilityChanged(uiDarwinControl *c) -{ - uiTab *t = uiTab(c); - - tabRelayout(t); -} - -void uiTabAppend(uiTab *t, const char *name, uiControl *child) -{ - uiTabInsertAt(t, name, [t->pages count], child); -} - -void uiTabInsertAt(uiTab *t, const char *name, int n, uiControl *child) -{ - tabPage *page; - NSView *view; - NSTabViewItem *i; - NSObject *pageID; - - uiControlSetParent(child, uiControl(t)); - - view = [[[NSView alloc] initWithFrame:NSZeroRect] autorelease]; - // note: if we turn off the autoresizing mask, nothing shows up - uiDarwinControlSetSuperview(uiDarwinControl(child), view); - uiDarwinControlSyncEnableState(uiDarwinControl(child), uiControlEnabledToUser(uiControl(t))); - - // the documentation says these can be nil but the headers say these must not be; let's be safe and make them non-nil anyway - pageID = [NSObject new]; - page = [[[tabPage alloc] initWithView:view pageID:pageID] autorelease]; - page.c = child; - - // don't hug, just in case we're a stretchy tab - page.oldHorzHuggingPri = uiDarwinControlHuggingPriority(uiDarwinControl(page.c), NSLayoutConstraintOrientationHorizontal); - page.oldVertHuggingPri = uiDarwinControlHuggingPriority(uiDarwinControl(page.c), NSLayoutConstraintOrientationVertical); - uiDarwinControlSetHuggingPriority(uiDarwinControl(page.c), NSLayoutPriorityDefaultLow, NSLayoutConstraintOrientationHorizontal); - uiDarwinControlSetHuggingPriority(uiDarwinControl(page.c), NSLayoutPriorityDefaultLow, NSLayoutConstraintOrientationVertical); - - [t->pages insertObject:page atIndex:n]; - - i = [[[NSTabViewItem alloc] initWithIdentifier:pageID] autorelease]; - [i setLabel:toNSString(name)]; - [i setView:view]; - [t->tabview insertTabViewItem:i atIndex:n]; - - tabRelayout(t); -} - -void uiTabDelete(uiTab *t, int n) -{ - tabPage *page; - uiControl *child; - NSTabViewItem *i; - - page = (tabPage *) [t->pages objectAtIndex:n]; - - uiDarwinControlSetHuggingPriority(uiDarwinControl(page.c), page.oldHorzHuggingPri, NSLayoutConstraintOrientationHorizontal); - uiDarwinControlSetHuggingPriority(uiDarwinControl(page.c), page.oldVertHuggingPri, NSLayoutConstraintOrientationVertical); - - child = page.c; - [page removeChildConstraints]; - [t->pages removeObjectAtIndex:n]; - - uiControlSetParent(child, NULL); - uiDarwinControlSetSuperview(uiDarwinControl(child), nil); - - i = [t->tabview tabViewItemAtIndex:n]; - [t->tabview removeTabViewItem:i]; - - tabRelayout(t); -} - -int uiTabNumPages(uiTab *t) -{ - return [t->pages count]; -} - -int uiTabMargined(uiTab *t, int n) -{ - tabPage *page; - - page = (tabPage *) [t->pages objectAtIndex:n]; - return [page isMargined]; -} - -void uiTabSetMargined(uiTab *t, int n, int margined) -{ - tabPage *page; - - page = (tabPage *) [t->pages objectAtIndex:n]; - [page setMargined:margined]; -} - -uiTab *uiNewTab(void) -{ - uiTab *t; - - uiDarwinNewControl(uiTab, t); - - t->tabview = [[NSTabView alloc] initWithFrame:NSZeroRect]; - // also good for NSTabView (same selector and everything) - uiDarwinSetControlFont((NSControl *) (t->tabview), NSRegularControlSize); - - t->pages = [NSMutableArray new]; - - // default to low hugging to not hug edges - t->horzHuggingPri = NSLayoutPriorityDefaultLow; - t->vertHuggingPri = NSLayoutPriorityDefaultLow; - - return t; -} diff --git a/deps/libui/darwin/text.m b/deps/libui/darwin/text.m deleted file mode 100644 index f0d3dab69e..0000000000 --- a/deps/libui/darwin/text.m +++ /dev/null @@ -1,19 +0,0 @@ -// 10 april 2015 -#import "uipriv_darwin.h" - -char *uiDarwinNSStringToText(NSString *s) -{ - char *out; - - out = strdup([s UTF8String]); - if (out == NULL) { - fprintf(stderr, "memory exhausted in uiDarwinNSStringToText()\n"); - abort(); - } - return out; -} - -void uiFreeText(char *s) -{ - free(s); -} diff --git a/deps/libui/darwin/uipriv_darwin.h b/deps/libui/darwin/uipriv_darwin.h deleted file mode 100644 index 6bca87b269..0000000000 --- a/deps/libui/darwin/uipriv_darwin.h +++ /dev/null @@ -1,146 +0,0 @@ -// 6 january 2015 -#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_8 -#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_8 -#import -#import "../ui.h" -#import "../ui_darwin.h" -#import "../common/uipriv.h" - -#if __has_feature(objc_arc) -#error Sorry, libui cannot be compiled with ARC. -#endif - -#define toNSString(str) [NSString stringWithUTF8String:(str)] -#define fromNSString(str) [(str) UTF8String] - -#ifndef NSAppKitVersionNumber10_9 -#define NSAppKitVersionNumber10_9 1265 -#endif - -/*TODO remove this*/typedef struct uiImage uiImage; - -// menu.m -@interface menuManager : NSObject { - struct mapTable *items; - BOOL hasQuit; - BOOL hasPreferences; - BOOL hasAbout; -} -@property (strong) NSMenuItem *quitItem; -@property (strong) NSMenuItem *preferencesItem; -@property (strong) NSMenuItem *aboutItem; -// NSMenuValidation is only informal -- (BOOL)validateMenuItem:(NSMenuItem *)item; -- (NSMenu *)makeMenubar; -@end -extern void finalizeMenus(void); -extern void uninitMenus(void); - -// main.m -@interface applicationClass : NSApplication -@end -// this is needed because NSApp is of type id, confusing clang -#define realNSApp() ((applicationClass *) NSApp) -@interface appDelegate : NSObject -@property (strong) menuManager *menuManager; -@end -#define appDelegate() ((appDelegate *) [realNSApp() delegate]) -struct nextEventArgs { - NSEventMask mask; - NSDate *duration; - // LONGTERM no NSRunLoopMode? - NSString *mode; - BOOL dequeue; -}; -extern int mainStep(struct nextEventArgs *nea, BOOL (^interceptEvent)(NSEvent *)); - -// util.m -extern void disableAutocorrect(NSTextView *); - -// entry.m -extern void finishNewTextField(NSTextField *, BOOL); -extern NSTextField *newEditableTextField(void); - -// window.m -@interface libuiNSWindow : NSWindow -- (void)libui_doMove:(NSEvent *)initialEvent; -- (void)libui_doResize:(NSEvent *)initialEvent on:(uiWindowResizeEdge)edge; -@end -extern uiWindow *windowFromNSWindow(NSWindow *); - -// alloc.m -extern NSMutableArray *delegates; -extern void initAlloc(void); -extern void uninitAlloc(void); - -// autolayout.m -extern NSLayoutConstraint *mkConstraint(id view1, NSLayoutAttribute attr1, NSLayoutRelation relation, id view2, NSLayoutAttribute attr2, CGFloat multiplier, CGFloat c, NSString *desc); -extern void jiggleViewLayout(NSView *view); -struct singleChildConstraints { - NSLayoutConstraint *leadingConstraint; - NSLayoutConstraint *topConstraint; - NSLayoutConstraint *trailingConstraintGreater; - NSLayoutConstraint *trailingConstraintEqual; - NSLayoutConstraint *bottomConstraintGreater; - NSLayoutConstraint *bottomConstraintEqual; -}; -extern void singleChildConstraintsEstablish(struct singleChildConstraints *c, NSView *contentView, NSView *childView, BOOL hugsTrailing, BOOL hugsBottom, int margined, NSString *desc); -extern void singleChildConstraintsRemove(struct singleChildConstraints *c, NSView *cv); -extern void singleChildConstraintsSetMargined(struct singleChildConstraints *c, int margined); - -// map.m -extern struct mapTable *newMap(void); -extern void mapDestroy(struct mapTable *m); -extern void *mapGet(struct mapTable *m, void *key); -extern void mapSet(struct mapTable *m, void *key, void *value); -extern void mapDelete(struct mapTable *m, void *key); -extern void mapWalk(struct mapTable *m, void (*f)(void *key, void *value)); -extern void mapReset(struct mapTable *m); - -// area.m -extern int sendAreaEvents(NSEvent *); - -// areaevents.m -extern BOOL fromKeycode(unsigned short keycode, uiAreaKeyEvent *ke); -extern BOOL keycodeModifier(unsigned short keycode, uiModifiers *mod); - -// draw.m -extern uiDrawContext *newContext(CGContextRef, CGFloat); -extern void freeContext(uiDrawContext *); - -// drawtext.m -extern uiDrawTextFont *mkTextFont(CTFontRef f, BOOL retain); -extern uiDrawTextFont *mkTextFontFromNSFont(NSFont *f); -extern void doDrawText(CGContextRef c, CGFloat cheight, double x, double y, uiDrawTextLayout *layout); - -// fontbutton.m -extern BOOL fontButtonInhibitSendAction(SEL sel, id from, id to); -extern BOOL fontButtonOverrideTargetForAction(SEL sel, id from, id to, id *override); -extern void setupFontPanel(void); - -// colorbutton.m -extern BOOL colorButtonInhibitSendAction(SEL sel, id from, id to); - -// scrollview.m -struct scrollViewCreateParams { - NSView *DocumentView; - NSColor *BackgroundColor; - BOOL DrawsBackground; - BOOL Bordered; - BOOL HScroll; - BOOL VScroll; -}; -struct scrollViewData; -extern NSScrollView *mkScrollView(struct scrollViewCreateParams *p, struct scrollViewData **dout); -extern void scrollViewSetScrolling(NSScrollView *sv, struct scrollViewData *d, BOOL hscroll, BOOL vscroll); -extern void scrollViewFreeData(NSScrollView *sv, struct scrollViewData *d); - -// label.m -extern NSTextField *newLabel(NSString *str); - -// image.m -extern NSImage *imageImage(uiImage *); - -// winmoveresize.m -extern void doManualMove(NSWindow *w, NSEvent *initialEvent); -extern void doManualResize(NSWindow *w, NSEvent *initialEvent, uiWindowResizeEdge edge); diff --git a/deps/libui/darwin/util.m b/deps/libui/darwin/util.m deleted file mode 100644 index ab873906d5..0000000000 --- a/deps/libui/darwin/util.m +++ /dev/null @@ -1,15 +0,0 @@ -// 7 april 2015 -#import "uipriv_darwin.h" - -// LONGTERM do we really want to do this? make it an option? -void disableAutocorrect(NSTextView *tv) -{ - [tv setEnabledTextCheckingTypes:0]; - [tv setAutomaticDashSubstitutionEnabled:NO]; - // don't worry about automatic data detection; it won't change stringValue (thanks pretty_function in irc.freenode.net/#macdev) - [tv setAutomaticSpellingCorrectionEnabled:NO]; - [tv setAutomaticTextReplacementEnabled:NO]; - [tv setAutomaticQuoteSubstitutionEnabled:NO]; - [tv setAutomaticLinkDetectionEnabled:NO]; - [tv setSmartInsertDeleteEnabled:NO]; -} diff --git a/deps/libui/darwin/window.m b/deps/libui/darwin/window.m deleted file mode 100644 index 97c22e6229..0000000000 --- a/deps/libui/darwin/window.m +++ /dev/null @@ -1,407 +0,0 @@ -// 15 august 2015 -#import "uipriv_darwin.h" - -#define defaultStyleMask (NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask) - -struct uiWindow { - uiDarwinControl c; - NSWindow *window; - uiControl *child; - int margined; - int (*onClosing)(uiWindow *, void *); - void *onClosingData; - struct singleChildConstraints constraints; - void (*onContentSizeChanged)(uiWindow *, void *); - void *onContentSizeChangedData; - BOOL suppressSizeChanged; - int fullscreen; - int borderless; -}; - -@implementation libuiNSWindow - -- (void)libui_doMove:(NSEvent *)initialEvent -{ - doManualMove(self, initialEvent); -} - -- (void)libui_doResize:(NSEvent *)initialEvent on:(uiWindowResizeEdge)edge -{ - doManualResize(self, initialEvent, edge); -} - -@end - -@interface windowDelegateClass : NSObject { - struct mapTable *windows; -} -- (BOOL)windowShouldClose:(id)sender; -- (void)windowDidResize:(NSNotification *)note; -- (void)windowDidEnterFullScreen:(NSNotification *)note; -- (void)windowDidExitFullScreen:(NSNotification *)note; -- (void)registerWindow:(uiWindow *)w; -- (void)unregisterWindow:(uiWindow *)w; -- (uiWindow *)lookupWindow:(NSWindow *)w; -@end - -@implementation windowDelegateClass - -- (id)init -{ - self = [super init]; - if (self) - self->windows = newMap(); - return self; -} - -- (void)dealloc -{ - mapDestroy(self->windows); - [super dealloc]; -} - -- (BOOL)windowShouldClose:(id)sender -{ - uiWindow *w; - - w = [self lookupWindow:((NSWindow *) sender)]; - // w should not be NULL; we are only the delegate of registered windows - if ((*(w->onClosing))(w, w->onClosingData)) - uiControlDestroy(uiControl(w)); - return NO; -} - -- (void)windowDidResize:(NSNotification *)note -{ - uiWindow *w; - - w = [self lookupWindow:((NSWindow *) [note object])]; - if (!w->suppressSizeChanged) - (*(w->onContentSizeChanged))(w, w->onContentSizeChangedData); -} - -- (void)windowDidEnterFullScreen:(NSNotification *)note -{ - uiWindow *w; - - w = [self lookupWindow:((NSWindow *) [note object])]; - if (!w->suppressSizeChanged) - w->fullscreen = 1; -} - -- (void)windowDidExitFullScreen:(NSNotification *)note -{ - uiWindow *w; - - w = [self lookupWindow:((NSWindow *) [note object])]; - if (!w->suppressSizeChanged) - w->fullscreen = 0; -} - -- (void)registerWindow:(uiWindow *)w -{ - mapSet(self->windows, w->window, w); - [w->window setDelegate:self]; -} - -- (void)unregisterWindow:(uiWindow *)w -{ - [w->window setDelegate:nil]; - mapDelete(self->windows, w->window); -} - -- (uiWindow *)lookupWindow:(NSWindow *)w -{ - uiWindow *v; - - v = uiWindow(mapGet(self->windows, w)); - // this CAN (and IS ALLOWED TO) return NULL, just in case we're called with some OS X-provided window as the key window - return v; -} - -@end - -static windowDelegateClass *windowDelegate = nil; - -static void removeConstraints(uiWindow *w) -{ - NSView *cv; - - cv = [w->window contentView]; - singleChildConstraintsRemove(&(w->constraints), cv); -} - -static void uiWindowDestroy(uiControl *c) -{ - uiWindow *w = uiWindow(c); - - // hide the window - [w->window orderOut:w->window]; - removeConstraints(w); - if (w->child != NULL) { - uiControlSetParent(w->child, NULL); - uiDarwinControlSetSuperview(uiDarwinControl(w->child), nil); - uiControlDestroy(w->child); - } - [windowDelegate unregisterWindow:w]; - [w->window release]; - uiFreeControl(uiControl(w)); -} - -uiDarwinControlDefaultHandle(uiWindow, window) - -uiControl *uiWindowParent(uiControl *c) -{ - return NULL; -} - -void uiWindowSetParent(uiControl *c, uiControl *parent) -{ - uiUserBugCannotSetParentOnToplevel("uiWindow"); -} - -static int uiWindowToplevel(uiControl *c) -{ - return 1; -} - -static int uiWindowVisible(uiControl *c) -{ - uiWindow *w = uiWindow(c); - - return [w->window isVisible]; -} - -static void uiWindowShow(uiControl *c) -{ - uiWindow *w = (uiWindow *) c; - - [w->window makeKeyAndOrderFront:w->window]; -} - -static void uiWindowHide(uiControl *c) -{ - uiWindow *w = (uiWindow *) c; - - [w->window orderOut:w->window]; -} - -uiDarwinControlDefaultEnabled(uiWindow, window) -uiDarwinControlDefaultEnable(uiWindow, window) -uiDarwinControlDefaultDisable(uiWindow, window) - -static void uiWindowSyncEnableState(uiDarwinControl *c, int enabled) -{ - uiWindow *w = uiWindow(c); - - if (uiDarwinShouldStopSyncEnableState(uiDarwinControl(w), enabled)) - return; - if (w->child != NULL) - uiDarwinControlSyncEnableState(uiDarwinControl(w->child), enabled); -} - -static void uiWindowSetSuperview(uiDarwinControl *c, NSView *superview) -{ - // TODO -} - -static void windowRelayout(uiWindow *w) -{ - NSView *childView; - NSView *contentView; - - removeConstraints(w); - if (w->child == NULL) - return; - childView = (NSView *) uiControlHandle(w->child); - contentView = [w->window contentView]; - singleChildConstraintsEstablish(&(w->constraints), - contentView, childView, - uiDarwinControlHugsTrailingEdge(uiDarwinControl(w->child)), - uiDarwinControlHugsBottom(uiDarwinControl(w->child)), - w->margined, - @"uiWindow"); -} - -uiDarwinControlDefaultHugsTrailingEdge(uiWindow, window) -uiDarwinControlDefaultHugsBottom(uiWindow, window) - -static void uiWindowChildEdgeHuggingChanged(uiDarwinControl *c) -{ - uiWindow *w = uiWindow(c); - - windowRelayout(w); -} - -// TODO -uiDarwinControlDefaultHuggingPriority(uiWindow, window) -uiDarwinControlDefaultSetHuggingPriority(uiWindow, window) -// end TODO - -static void uiWindowChildVisibilityChanged(uiDarwinControl *c) -{ - uiWindow *w = uiWindow(c); - - windowRelayout(w); -} - -char *uiWindowTitle(uiWindow *w) -{ - return uiDarwinNSStringToText([w->window title]); -} - -void uiWindowSetTitle(uiWindow *w, const char *title) -{ - [w->window setTitle:toNSString(title)]; -} - -void uiWindowContentSize(uiWindow *w, int *width, int *height) -{ - NSRect r; - - r = [w->window contentRectForFrameRect:[w->window frame]]; - *width = r.size.width; - *height = r.size.height; -} - -void uiWindowSetContentSize(uiWindow *w, int width, int height) -{ - w->suppressSizeChanged = YES; - [w->window setContentSize:NSMakeSize(width, height)]; - w->suppressSizeChanged = NO; -} - -int uiWindowFullscreen(uiWindow *w) -{ - return w->fullscreen; -} - -void uiWindowSetFullscreen(uiWindow *w, int fullscreen) -{ - if (w->fullscreen && fullscreen) - return; - if (!w->fullscreen && !fullscreen) - return; - w->fullscreen = fullscreen; - if (w->fullscreen && w->borderless) // borderless doesn't play nice with fullscreen; don't toggle while borderless - return; - w->suppressSizeChanged = YES; - [w->window toggleFullScreen:w->window]; - w->suppressSizeChanged = NO; - if (!w->fullscreen && w->borderless) // borderless doesn't play nice with fullscreen; restore borderless after removing - [w->window setStyleMask:NSBorderlessWindowMask]; -} - -void uiWindowOnContentSizeChanged(uiWindow *w, void (*f)(uiWindow *, void *), void *data) -{ - w->onContentSizeChanged = f; - w->onContentSizeChangedData = data; -} - -void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *, void *), void *data) -{ - w->onClosing = f; - w->onClosingData = data; -} - -int uiWindowBorderless(uiWindow *w) -{ - return w->borderless; -} - -void uiWindowSetBorderless(uiWindow *w, int borderless) -{ - w->borderless = borderless; - if (w->borderless) { - // borderless doesn't play nice with fullscreen; wait for later - if (!w->fullscreen) - [w->window setStyleMask:NSBorderlessWindowMask]; - } else { - [w->window setStyleMask:defaultStyleMask]; - // borderless doesn't play nice with fullscreen; restore state - if (w->fullscreen) { - w->suppressSizeChanged = YES; - [w->window toggleFullScreen:w->window]; - w->suppressSizeChanged = NO; - } - } -} - -void uiWindowSetChild(uiWindow *w, uiControl *child) -{ - NSView *childView; - - if (w->child != NULL) { - childView = (NSView *) uiControlHandle(w->child); - [childView removeFromSuperview]; - uiControlSetParent(w->child, NULL); - } - w->child = child; - if (w->child != NULL) { - uiControlSetParent(w->child, uiControl(w)); - childView = (NSView *) uiControlHandle(w->child); - uiDarwinControlSetSuperview(uiDarwinControl(w->child), [w->window contentView]); - uiDarwinControlSyncEnableState(uiDarwinControl(w->child), uiControlEnabledToUser(uiControl(w))); - } - windowRelayout(w); -} - -int uiWindowMargined(uiWindow *w) -{ - return w->margined; -} - -void uiWindowSetMargined(uiWindow *w, int margined) -{ - w->margined = margined; - singleChildConstraintsSetMargined(&(w->constraints), w->margined); -} - -static int defaultOnClosing(uiWindow *w, void *data) -{ - return 0; -} - -static void defaultOnPositionContentSizeChanged(uiWindow *w, void *data) -{ - // do nothing -} - -uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar) -{ - uiWindow *w; - - finalizeMenus(); - - uiDarwinNewControl(uiWindow, w); - - w->window = [[libuiNSWindow alloc] initWithContentRect:NSMakeRect(0, 0, (CGFloat) width, (CGFloat) height) - styleMask:defaultStyleMask - backing:NSBackingStoreBuffered - defer:YES]; - [w->window setTitle:toNSString(title)]; - - // do NOT release when closed - // we manually do this in uiWindowDestroy() above - [w->window setReleasedWhenClosed:NO]; - - if (windowDelegate == nil) { - windowDelegate = [[windowDelegateClass new] autorelease]; - [delegates addObject:windowDelegate]; - } - [windowDelegate registerWindow:w]; - uiWindowOnClosing(w, defaultOnClosing, NULL); - uiWindowOnContentSizeChanged(w, defaultOnPositionContentSizeChanged, NULL); - - return w; -} - -// utility function for menus -uiWindow *windowFromNSWindow(NSWindow *w) -{ - if (w == nil) - return NULL; - if (windowDelegate == nil) // no windows were created yet; we're called with some OS X-provided window - return NULL; - return [windowDelegate lookupWindow:w]; -} diff --git a/deps/libui/darwin/winmoveresize.m b/deps/libui/darwin/winmoveresize.m deleted file mode 100644 index 9145b7bb33..0000000000 --- a/deps/libui/darwin/winmoveresize.m +++ /dev/null @@ -1,253 +0,0 @@ -// 1 november 2016 -#import "uipriv_darwin.h" - -// because we are changing the window frame each time the mouse moves, the successive -[NSEvent locationInWindow]s cannot be meaningfully used together -// make sure they are all following some sort of standard to avoid this problem; the screen is the most obvious possibility since it requires only one conversion (the only one that a NSWindow provides) -static NSPoint makeIndependent(NSPoint p, NSWindow *w) -{ - NSRect r; - - r.origin = p; - // mikeash in irc.freenode.net/#macdev confirms both that any size will do and that we can safely ignore the resultant size - r.size = NSZeroSize; - return [w convertRectToScreen:r].origin; -} - -struct onMoveDragParams { - NSWindow *w; - // using the previous point causes weird issues like the mouse seeming to fall behind the window edge... so do this instead - // TODO will this make things like the menubar and dock easier too? - NSRect initialFrame; - NSPoint initialPoint; -}; - -void onMoveDrag(struct onMoveDragParams *p, NSEvent *e) -{ - NSPoint new; - NSRect frame; - CGFloat offx, offy; - - new = makeIndependent([e locationInWindow], p->w); - frame = p->initialFrame; - - offx = new.x - p->initialPoint.x; - offy = new.y - p->initialPoint.y; - frame.origin.x += offx; - frame.origin.y += offy; - - // TODO handle the menubar - // TODO wait the system does this for us already?! - - [p->w setFrameOrigin:frame.origin]; -} - -void doManualMove(NSWindow *w, NSEvent *initialEvent) -{ - __block struct onMoveDragParams mdp; - struct nextEventArgs nea; - BOOL (^handleEvent)(NSEvent *e); - __block BOOL done; - - // this is only available on 10.11 and newer (LONGTERM FUTURE) - // but use it if available; this lets us use the real OS dragging code, which means we can take advantage of OS features like Spaces - if ([w respondsToSelector:@selector(performWindowDragWithEvent:)]) { - [((id) w) performWindowDragWithEvent:initialEvent]; - return; - } - - mdp.w = w; - mdp.initialFrame = [mdp.w frame]; - mdp.initialPoint = makeIndependent([initialEvent locationInWindow], mdp.w); - - nea.mask = NSLeftMouseDraggedMask | NSLeftMouseUpMask; - nea.duration = [NSDate distantFuture]; - nea.mode = NSEventTrackingRunLoopMode; // nextEventMatchingMask: docs suggest using this for manual mouse tracking - nea.dequeue = YES; - handleEvent = ^(NSEvent *e) { - if ([e type] == NSLeftMouseUp) { - done = YES; - return YES; // do not send - } - onMoveDrag(&mdp, e); - return YES; // do not send - }; - done = NO; - while (mainStep(&nea, handleEvent)) - if (done) - break; -} - -// see http://stackoverflow.com/a/40352996/3408572 -static void minMaxAutoLayoutSizes(NSWindow *w, NSSize *min, NSSize *max) -{ - NSLayoutConstraint *cw, *ch; - NSView *contentView; - NSRect prevFrame; - - // if adding these constraints causes the window to change size somehow, don't show it to the user and change it back afterwards - NSDisableScreenUpdates(); - prevFrame = [w frame]; - - // minimum: encourage the window to be as small as possible - contentView = [w contentView]; - cw = mkConstraint(contentView, NSLayoutAttributeWidth, - NSLayoutRelationEqual, - nil, NSLayoutAttributeNotAnAttribute, - 0, 0, - @"window minimum width finding constraint"); - [cw setPriority:NSLayoutPriorityDragThatCanResizeWindow]; - [contentView addConstraint:cw]; - ch = mkConstraint(contentView, NSLayoutAttributeHeight, - NSLayoutRelationEqual, - nil, NSLayoutAttributeNotAnAttribute, - 0, 0, - @"window minimum height finding constraint"); - [ch setPriority:NSLayoutPriorityDragThatCanResizeWindow]; - [contentView addConstraint:ch]; - *min = [contentView fittingSize]; - [contentView removeConstraint:cw]; - [contentView removeConstraint:ch]; - - // maximum: encourage the window to be as large as possible - contentView = [w contentView]; - cw = mkConstraint(contentView, NSLayoutAttributeWidth, - NSLayoutRelationEqual, - nil, NSLayoutAttributeNotAnAttribute, - 0, CGFLOAT_MAX, - @"window maximum width finding constraint"); - [cw setPriority:NSLayoutPriorityDragThatCanResizeWindow]; - [contentView addConstraint:cw]; - ch = mkConstraint(contentView, NSLayoutAttributeHeight, - NSLayoutRelationEqual, - nil, NSLayoutAttributeNotAnAttribute, - 0, CGFLOAT_MAX, - @"window maximum height finding constraint"); - [ch setPriority:NSLayoutPriorityDragThatCanResizeWindow]; - [contentView addConstraint:ch]; - *max = [contentView fittingSize]; - [contentView removeConstraint:cw]; - [contentView removeConstraint:ch]; - - [w setFrame:prevFrame display:YES]; // TODO really YES? - NSEnableScreenUpdates(); -} - -static void handleResizeLeft(NSRect *frame, NSPoint old, NSPoint new) -{ - frame->origin.x += new.x - old.x; - frame->size.width -= new.x - old.x; -} - -// TODO properly handle the menubar -// TODO wait, OS X does it for us?! -static void handleResizeTop(NSRect *frame, NSPoint old, NSPoint new) -{ - frame->size.height += new.y - old.y; -} - -static void handleResizeRight(NSRect *frame, NSPoint old, NSPoint new) -{ - frame->size.width += new.x - old.x; -} - - -// TODO properly handle the menubar -static void handleResizeBottom(NSRect *frame, NSPoint old, NSPoint new) -{ - frame->origin.y += new.y - old.y; - frame->size.height -= new.y - old.y; -} - -struct onResizeDragParams { - NSWindow *w; - // using the previous point causes weird issues like the mouse seeming to fall behind the window edge... so do this instead - // TODO will this make things like the menubar and dock easier too? - NSRect initialFrame; - NSPoint initialPoint; - uiWindowResizeEdge edge; - NSSize min; - NSSize max; -}; - -static void onResizeDrag(struct onResizeDragParams *p, NSEvent *e) -{ - NSPoint new; - NSRect frame; - - new = makeIndependent([e locationInWindow], p->w); - frame = p->initialFrame; - - // horizontal - switch (p->edge) { - case uiWindowResizeEdgeLeft: - case uiWindowResizeEdgeTopLeft: - case uiWindowResizeEdgeBottomLeft: - handleResizeLeft(&frame, p->initialPoint, new); - break; - case uiWindowResizeEdgeRight: - case uiWindowResizeEdgeTopRight: - case uiWindowResizeEdgeBottomRight: - handleResizeRight(&frame, p->initialPoint, new); - break; - } - // vertical - switch (p->edge) { - case uiWindowResizeEdgeTop: - case uiWindowResizeEdgeTopLeft: - case uiWindowResizeEdgeTopRight: - handleResizeTop(&frame, p->initialPoint, new); - break; - case uiWindowResizeEdgeBottom: - case uiWindowResizeEdgeBottomLeft: - case uiWindowResizeEdgeBottomRight: - handleResizeBottom(&frame, p->initialPoint, new); - break; - } - - // constrain - // TODO should we constrain against anything else as well? minMaxAutoLayoutSizes() already gives us nonnegative sizes, but... - if (frame.size.width < p->min.width) - frame.size.width = p->min.width; - if (frame.size.height < p->min.height) - frame.size.height = p->min.height; - // TODO > or >= ? - if (frame.size.width > p->max.width) - frame.size.width = p->max.width; - if (frame.size.height > p->max.height) - frame.size.height = p->max.height; - - [p->w setFrame:frame display:YES]; // and do reflect the new frame immediately -} - -// TODO do our events get fired with this? *should* they? -void doManualResize(NSWindow *w, NSEvent *initialEvent, uiWindowResizeEdge edge) -{ - __block struct onResizeDragParams rdp; - struct nextEventArgs nea; - BOOL (^handleEvent)(NSEvent *e); - __block BOOL done; - - rdp.w = w; - rdp.initialFrame = [rdp.w frame]; - rdp.initialPoint = makeIndependent([initialEvent locationInWindow], rdp.w); - rdp.edge = edge; - // TODO what happens if these change during the loop? - minMaxAutoLayoutSizes(rdp.w, &(rdp.min), &(rdp.max)); - - nea.mask = NSLeftMouseDraggedMask | NSLeftMouseUpMask; - nea.duration = [NSDate distantFuture]; - nea.mode = NSEventTrackingRunLoopMode; // nextEventMatchingMask: docs suggest using this for manual mouse tracking - nea.dequeue = YES; - handleEvent = ^(NSEvent *e) { - if ([e type] == NSLeftMouseUp) { - done = YES; - return YES; // do not send - } - onResizeDrag(&rdp, e); - return YES; // do not send - }; - done = NO; - while (mainStep(&nea, handleEvent)) - if (done) - break; -} diff --git a/deps/libui/libui_main.c b/deps/libui/libui_main.c deleted file mode 100644 index 8c54f05849..0000000000 --- a/deps/libui/libui_main.c +++ /dev/null @@ -1,543 +0,0 @@ -/* 2 september 2015 */ -#include -#include -#include "ui.h" -#include "../../verbosity.h" - -static int onClosing(uiWindow *w, void *data) -{ - uiQuit(); - return 1; -} - -static int onShouldQuit(void *data) -{ - uiWindow *mainwin = uiWindow(data); - - uiControlDestroy(uiControl(mainwin)); - return 1; -} - -static uiControl *makeBasicControlsPage(void) -{ - uiBox *vbox; - uiBox *hbox; - uiGroup *group; - uiForm *entryForm; - - vbox = uiNewVerticalBox(); - uiBoxSetPadded(vbox, 1); - - hbox = uiNewHorizontalBox(); - uiBoxSetPadded(hbox, 1); - uiBoxAppend(vbox, uiControl(hbox), 0); - - uiBoxAppend(hbox, - uiControl(uiNewButton("Button")), - 0); - uiBoxAppend(hbox, - uiControl(uiNewCheckbox("Checkbox")), - 0); - - uiBoxAppend(vbox, - uiControl(uiNewLabel("This is a label. Right now, labels can only span one line.")), - 0); - - uiBoxAppend(vbox, - uiControl(uiNewHorizontalSeparator()), - 0); - - group = uiNewGroup("Entries"); - uiGroupSetMargined(group, 1); - uiBoxAppend(vbox, uiControl(group), 1); - - entryForm = uiNewForm(); - uiFormSetPadded(entryForm, 1); - uiGroupSetChild(group, uiControl(entryForm)); - - uiFormAppend(entryForm, - "Entry", - uiControl(uiNewEntry()), - 0); - uiFormAppend(entryForm, - "Password Entry", - uiControl(uiNewPasswordEntry()), - 0); - uiFormAppend(entryForm, - "Search Entry", - uiControl(uiNewSearchEntry()), - 0); - uiFormAppend(entryForm, - "Multiline Entry", - uiControl(uiNewMultilineEntry()), - 1); - uiFormAppend(entryForm, - "Multiline Entry No Wrap", - uiControl(uiNewNonWrappingMultilineEntry()), - 1); - - return uiControl(vbox); -} - -// TODO make these not global -static uiSpinbox *spinbox; -static uiSlider *slider; -static uiProgressBar *pbar; - -static void onSpinboxChanged(uiSpinbox *s, void *data) -{ - uiSliderSetValue(slider, uiSpinboxValue(s)); - uiProgressBarSetValue(pbar, uiSpinboxValue(s)); -} - -static void onSliderChanged(uiSlider *s, void *data) -{ - uiSpinboxSetValue(spinbox, uiSliderValue(s)); - uiProgressBarSetValue(pbar, uiSliderValue(s)); -} - -static uiControl *makeNumbersPage() -{ - uiBox *hbox; - uiGroup *group; - uiBox *vbox; - uiProgressBar *ip; - uiCombobox *cbox; - uiEditableCombobox *ecbox; - uiRadioButtons *rb; - - hbox = uiNewHorizontalBox(); - uiBoxSetPadded(hbox, 1); - - group = uiNewGroup("Numbers"); - uiGroupSetMargined(group, 1); - uiBoxAppend(hbox, uiControl(group), 1); - - vbox = uiNewVerticalBox(); - uiBoxSetPadded(vbox, 1); - uiGroupSetChild(group, uiControl(vbox)); - - spinbox = uiNewSpinbox(0, 100); - slider = uiNewSlider(0, 100); - pbar = uiNewProgressBar(); - uiSpinboxOnChanged(spinbox, onSpinboxChanged, NULL); - uiSliderOnChanged(slider, onSliderChanged, NULL); - uiBoxAppend(vbox, uiControl(spinbox), 0); - uiBoxAppend(vbox, uiControl(slider), 0); - uiBoxAppend(vbox, uiControl(pbar), 0); - - ip = uiNewProgressBar(); - uiProgressBarSetValue(ip, -1); - uiBoxAppend(vbox, uiControl(ip), 0); - - group = uiNewGroup("Lists"); - uiGroupSetMargined(group, 1); - uiBoxAppend(hbox, uiControl(group), 1); - - vbox = uiNewVerticalBox(); - uiBoxSetPadded(vbox, 1); - uiGroupSetChild(group, uiControl(vbox)); - - cbox = uiNewCombobox(); - uiComboboxAppend(cbox, "Combobox Item 1"); - uiComboboxAppend(cbox, "Combobox Item 2"); - uiComboboxAppend(cbox, "Combobox Item 3"); - uiBoxAppend(vbox, uiControl(cbox), 0); - - ecbox = uiNewEditableCombobox(); - uiEditableComboboxAppend(ecbox, "Editable Item 1"); - uiEditableComboboxAppend(ecbox, "Editable Item 2"); - uiEditableComboboxAppend(ecbox, "Editable Item 3"); - uiBoxAppend(vbox, uiControl(ecbox), 0); - - rb = uiNewRadioButtons(); - uiRadioButtonsAppend(rb, "Radio Button 1"); - uiRadioButtonsAppend(rb, "Radio Button 2"); - uiRadioButtonsAppend(rb, "Radio Button 3"); - uiBoxAppend(vbox, uiControl(rb), 0); - - return uiControl(hbox); -} - -// TODO make this not global -static uiWindow *mainwin; - -static void onOpenFileClicked(uiButton *b, void *data) -{ - uiEntry *entry = uiEntry(data); - char *filename; - - filename = uiOpenFile(mainwin); - if (filename == NULL) { - uiEntrySetText(entry, "(cancelled)"); - return; - } - uiEntrySetText(entry, filename); - uiFreeText(filename); -} - -static void onSaveFileClicked(uiButton *b, void *data) -{ - uiEntry *entry = uiEntry(data); - char *filename; - - filename = uiSaveFile(mainwin); - if (filename == NULL) { - uiEntrySetText(entry, "(cancelled)"); - return; - } - uiEntrySetText(entry, filename); - uiFreeText(filename); -} - -static void onMsgBoxClicked(uiButton *b, void *data) -{ - uiMsgBox(mainwin, - "This is a normal message box.", - "More detailed information can be shown here."); -} - -static void onMsgBoxErrorClicked(uiButton *b, void *data) -{ - uiMsgBoxError(mainwin, - "This message box describes an error.", - "More detailed information can be shown here."); -} - -static uiControl *makeDataChoosersPage(void) -{ - uiBox *hbox; - uiBox *vbox; - uiGrid *grid; - uiButton *button; - uiEntry *entry; - uiGrid *msggrid; - - hbox = uiNewHorizontalBox(); - uiBoxSetPadded(hbox, 1); - - vbox = uiNewVerticalBox(); - uiBoxSetPadded(vbox, 1); - uiBoxAppend(hbox, uiControl(vbox), 0); - - uiBoxAppend(vbox, - uiControl(uiNewDatePicker()), - 0); - uiBoxAppend(vbox, - uiControl(uiNewTimePicker()), - 0); - uiBoxAppend(vbox, - uiControl(uiNewDateTimePicker()), - 0); - - uiBoxAppend(vbox, - uiControl(uiNewFontButton()), - 0); - uiBoxAppend(vbox, - uiControl(uiNewColorButton()), - 0); - - uiBoxAppend(hbox, - uiControl(uiNewVerticalSeparator()), - 0); - - vbox = uiNewVerticalBox(); - uiBoxSetPadded(vbox, 1); - uiBoxAppend(hbox, uiControl(vbox), 1); - - grid = uiNewGrid(); - uiGridSetPadded(grid, 1); - uiBoxAppend(vbox, uiControl(grid), 0); - - button = uiNewButton("Open File"); - entry = uiNewEntry(); - uiEntrySetReadOnly(entry, 1); - uiButtonOnClicked(button, onOpenFileClicked, entry); - uiGridAppend(grid, uiControl(button), - 0, 0, 1, 1, - 0, uiAlignFill, 0, uiAlignFill); - uiGridAppend(grid, uiControl(entry), - 1, 0, 1, 1, - 1, uiAlignFill, 0, uiAlignFill); - - button = uiNewButton("Save File"); - entry = uiNewEntry(); - uiEntrySetReadOnly(entry, 1); - uiButtonOnClicked(button, onSaveFileClicked, entry); - uiGridAppend(grid, uiControl(button), - 0, 1, 1, 1, - 0, uiAlignFill, 0, uiAlignFill); - uiGridAppend(grid, uiControl(entry), - 1, 1, 1, 1, - 1, uiAlignFill, 0, uiAlignFill); - - msggrid = uiNewGrid(); - uiGridSetPadded(msggrid, 1); - uiGridAppend(grid, uiControl(msggrid), - 0, 2, 2, 1, - 0, uiAlignCenter, 0, uiAlignStart); - - button = uiNewButton("Message Box"); - uiButtonOnClicked(button, onMsgBoxClicked, NULL); - uiGridAppend(msggrid, uiControl(button), - 0, 0, 1, 1, - 0, uiAlignFill, 0, uiAlignFill); - button = uiNewButton("Error Box"); - uiButtonOnClicked(button, onMsgBoxErrorClicked, NULL); - uiGridAppend(msggrid, uiControl(button), - 1, 0, 1, 1, - 0, uiAlignFill, 0, uiAlignFill); - - return uiControl(hbox); -} - -int libui_main(void) -{ - uiInitOptions options; - const char *err; - uiTab *tab; - - memset(&options, 0, sizeof (uiInitOptions)); - err = uiInit(&options); - if (err != NULL) - { - RARCH_ERR("Failed to initialize uiInit\n"); - fprintf(stderr, "error initializing libui: %s", err); - uiFreeInitError(err); - return 1; - } - - mainwin = uiNewWindow("libui Control Gallery", 640, 480, 1); - uiWindowOnClosing(mainwin, onClosing, NULL); - uiOnShouldQuit(onShouldQuit, mainwin); - - tab = uiNewTab(); - uiWindowSetChild(mainwin, uiControl(tab)); - uiWindowSetMargined(mainwin, 1); - - uiTabAppend(tab, "Basic Controls", makeBasicControlsPage()); - uiTabSetMargined(tab, 0, 1); - - uiTabAppend(tab, "Numbers and Lists", makeNumbersPage()); - uiTabSetMargined(tab, 1, 1); - - uiTabAppend(tab, "Data Choosers", makeDataChoosersPage()); - uiTabSetMargined(tab, 2, 1); - - uiControlShow(uiControl(mainwin)); - uiMain(); - return 0; -} - -#if 0 - -static void openClicked(uiMenuItem *item, uiWindow *w, void *data) -{ - char *filename; - - filename = uiOpenFile(mainwin); - if (filename == NULL) { - uiMsgBoxError(mainwin, "No file selected", "Don't be alarmed!"); - return; - } - uiMsgBox(mainwin, "File selected", filename); - uiFreeText(filename); -} - -static void saveClicked(uiMenuItem *item, uiWindow *w, void *data) -{ - char *filename; - - filename = uiSaveFile(mainwin); - if (filename == NULL) { - uiMsgBoxError(mainwin, "No file selected", "Don't be alarmed!"); - return; - } - uiMsgBox(mainwin, "File selected (don't worry, it's still there)", filename); - uiFreeText(filename); -} - -static uiSpinbox *spinbox; -static uiSlider *slider; -static uiProgressBar *progressbar; - -static void update(int value) -{ - uiSpinboxSetValue(spinbox, value); - uiSliderSetValue(slider, value); - uiProgressBarSetValue(progressbar, value); -} - -static void onSpinboxChanged(uiSpinbox *s, void *data) -{ - update(uiSpinboxValue(spinbox)); -} - -static void onSliderChanged(uiSlider *s, void *data) -{ - update(uiSliderValue(slider)); -} - -int main(void) -{ - uiInitOptions o; - const char *err; - uiMenu *menu; - uiMenuItem *item; - uiBox *box; - uiBox *hbox; - uiGroup *group; - uiBox *inner; - uiBox *inner2; - uiEntry *entry; - uiCombobox *cbox; - uiEditableCombobox *ecbox; - uiRadioButtons *rb; - uiTab *tab; - - memset(&o, 0, sizeof (uiInitOptions)); - err = uiInit(&o); - if (err != NULL) { - fprintf(stderr, "error initializing ui: %s\n", err); - uiFreeInitError(err); - return 1; - } - - menu = uiNewMenu("File"); - item = uiMenuAppendItem(menu, "Open"); - uiMenuItemOnClicked(item, openClicked, NULL); - item = uiMenuAppendItem(menu, "Save"); - uiMenuItemOnClicked(item, saveClicked, NULL); - item = uiMenuAppendQuitItem(menu); - uiOnShouldQuit(shouldQuit, NULL); - - menu = uiNewMenu("Edit"); - item = uiMenuAppendCheckItem(menu, "Checkable Item"); - uiMenuAppendSeparator(menu); - item = uiMenuAppendItem(menu, "Disabled Item"); - uiMenuItemDisable(item); - item = uiMenuAppendPreferencesItem(menu); - - menu = uiNewMenu("Help"); - item = uiMenuAppendItem(menu, "Help"); - item = uiMenuAppendAboutItem(menu); - - mainwin = uiNewWindow("libui Control Gallery", 640, 480, 1); - uiWindowSetMargined(mainwin, 1); - uiWindowOnClosing(mainwin, onClosing, NULL); - - box = uiNewVerticalBox(); - uiBoxSetPadded(box, 1); - uiWindowSetChild(mainwin, uiControl(box)); - - hbox = uiNewHorizontalBox(); - uiBoxSetPadded(hbox, 1); - uiBoxAppend(box, uiControl(hbox), 1); - - group = uiNewGroup("Basic Controls"); - uiGroupSetMargined(group, 1); - uiBoxAppend(hbox, uiControl(group), 0); - - inner = uiNewVerticalBox(); - uiBoxSetPadded(inner, 1); - uiGroupSetChild(group, uiControl(inner)); - - uiBoxAppend(inner, - uiControl(uiNewButton("Button")), - 0); - uiBoxAppend(inner, - uiControl(uiNewCheckbox("Checkbox")), - 0); - entry = uiNewEntry(); - uiEntrySetText(entry, "Entry"); - uiBoxAppend(inner, - uiControl(entry), - 0); - uiBoxAppend(inner, - uiControl(uiNewLabel("Label")), - 0); - - uiBoxAppend(inner, - uiControl(uiNewHorizontalSeparator()), - 0); - - uiBoxAppend(inner, - uiControl(uiNewDatePicker()), - 0); - uiBoxAppend(inner, - uiControl(uiNewTimePicker()), - 0); - uiBoxAppend(inner, - uiControl(uiNewDateTimePicker()), - 0); - - uiBoxAppend(inner, - uiControl(uiNewFontButton()), - 0); - - uiBoxAppend(inner, - uiControl(uiNewColorButton()), - 0); - - inner2 = uiNewVerticalBox(); - uiBoxSetPadded(inner2, 1); - uiBoxAppend(hbox, uiControl(inner2), 1); - - group = uiNewGroup("Numbers"); - uiGroupSetMargined(group, 1); - uiBoxAppend(inner2, uiControl(group), 0); - - inner = uiNewVerticalBox(); - uiBoxSetPadded(inner, 1); - uiGroupSetChild(group, uiControl(inner)); - - spinbox = uiNewSpinbox(0, 100); - uiSpinboxOnChanged(spinbox, onSpinboxChanged, NULL); - uiBoxAppend(inner, uiControl(spinbox), 0); - - slider = uiNewSlider(0, 100); - uiSliderOnChanged(slider, onSliderChanged, NULL); - uiBoxAppend(inner, uiControl(slider), 0); - - progressbar = uiNewProgressBar(); - uiBoxAppend(inner, uiControl(progressbar), 0); - - group = uiNewGroup("Lists"); - uiGroupSetMargined(group, 1); - uiBoxAppend(inner2, uiControl(group), 0); - - inner = uiNewVerticalBox(); - uiBoxSetPadded(inner, 1); - uiGroupSetChild(group, uiControl(inner)); - - cbox = uiNewCombobox(); - uiComboboxAppend(cbox, "Combobox Item 1"); - uiComboboxAppend(cbox, "Combobox Item 2"); - uiComboboxAppend(cbox, "Combobox Item 3"); - uiBoxAppend(inner, uiControl(cbox), 0); - - ecbox = uiNewEditableCombobox(); - uiEditableComboboxAppend(ecbox, "Editable Item 1"); - uiEditableComboboxAppend(ecbox, "Editable Item 2"); - uiEditableComboboxAppend(ecbox, "Editable Item 3"); - uiBoxAppend(inner, uiControl(ecbox), 0); - - rb = uiNewRadioButtons(); - uiRadioButtonsAppend(rb, "Radio Button 1"); - uiRadioButtonsAppend(rb, "Radio Button 2"); - uiRadioButtonsAppend(rb, "Radio Button 3"); - uiBoxAppend(inner, uiControl(rb), 1); - - tab = uiNewTab(); - uiTabAppend(tab, "Page 1", uiControl(uiNewHorizontalBox())); - uiTabAppend(tab, "Page 2", uiControl(uiNewHorizontalBox())); - uiTabAppend(tab, "Page 3", uiControl(uiNewHorizontalBox())); - uiBoxAppend(inner2, uiControl(tab), 1); - - uiControlShow(uiControl(mainwin)); - uiMain(); - uiUninit(); - return 0; -} - -#endif diff --git a/deps/libui/ui.h b/deps/libui/ui.h deleted file mode 100644 index 5a2069e8a7..0000000000 --- a/deps/libui/ui.h +++ /dev/null @@ -1,691 +0,0 @@ -// 6 april 2015 - -// TODO add a uiVerifyControlType() function that can be used by control implementations to verify controls - -#ifndef __LIBUI_UI_H__ -#define __LIBUI_UI_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// this macro is generated by cmake -#ifdef libui_EXPORTS -#ifdef _WIN32 -#define _UI_EXTERN __declspec(dllexport) extern -#else -#define _UI_EXTERN __attribute__((visibility("default"))) extern -#endif -#else -// TODO add __declspec(dllimport) on windows, but only if not static -#define _UI_EXTERN extern -#endif - -// C++ is really really really really really really dumb about enums, so screw that and just make them anonymous -// This has the advantage of being ABI-able should we ever need an ABI... -#define _UI_ENUM(s) typedef unsigned int s; enum - -// This constant is provided because M_PI is nonstandard. -// This comes from Go's math.Pi, which in turn comes from http://oeis.org/A000796. -#define uiPi 3.14159265358979323846264338327950288419716939937510582097494459 - -// TODO uiBool? - -typedef struct uiInitOptions uiInitOptions; - -struct uiInitOptions { - size_t Size; -}; - -_UI_EXTERN const char *uiInit(uiInitOptions *options); -_UI_EXTERN void uiUninit(void); -_UI_EXTERN void uiFreeInitError(const char *err); - -_UI_EXTERN void uiMain(void); -_UI_EXTERN void uiMainSteps(void); -_UI_EXTERN int uiMainStep(int wait); -_UI_EXTERN void uiQuit(void); - -_UI_EXTERN void uiQueueMain(void (*f)(void *data), void *data); - -_UI_EXTERN void uiOnShouldQuit(int (*f)(void *data), void *data); - -_UI_EXTERN void uiFreeText(char *text); - -typedef struct uiControl uiControl; - -struct uiControl { - uint32_t Signature; - uint32_t OSSignature; - uint32_t TypeSignature; - void (*Destroy)(uiControl *); - uintptr_t (*Handle)(uiControl *); - uiControl *(*Parent)(uiControl *); - void (*SetParent)(uiControl *, uiControl *); - int (*Toplevel)(uiControl *); - int (*Visible)(uiControl *); - void (*Show)(uiControl *); - void (*Hide)(uiControl *); - int (*Enabled)(uiControl *); - void (*Enable)(uiControl *); - void (*Disable)(uiControl *); -}; -// TOOD add argument names to all arguments -#define uiControl(this) ((uiControl *) (this)) -_UI_EXTERN void uiControlDestroy(uiControl *); -_UI_EXTERN uintptr_t uiControlHandle(uiControl *); -_UI_EXTERN uiControl *uiControlParent(uiControl *); -_UI_EXTERN void uiControlSetParent(uiControl *, uiControl *); -_UI_EXTERN int uiControlToplevel(uiControl *); -_UI_EXTERN int uiControlVisible(uiControl *); -_UI_EXTERN void uiControlShow(uiControl *); -_UI_EXTERN void uiControlHide(uiControl *); -_UI_EXTERN int uiControlEnabled(uiControl *); -_UI_EXTERN void uiControlEnable(uiControl *); -_UI_EXTERN void uiControlDisable(uiControl *); - -_UI_EXTERN uiControl *uiAllocControl(size_t n, uint32_t OSsig, uint32_t typesig, const char *typenamestr); -_UI_EXTERN void uiFreeControl(uiControl *); - -// TODO make sure all controls have these -_UI_EXTERN void uiControlVerifySetParent(uiControl *, uiControl *); -_UI_EXTERN int uiControlEnabledToUser(uiControl *); - -_UI_EXTERN void uiUserBugCannotSetParentOnToplevel(const char *type); - -typedef struct uiWindow uiWindow; -#define uiWindow(this) ((uiWindow *) (this)) -_UI_EXTERN char *uiWindowTitle(uiWindow *w); -_UI_EXTERN void uiWindowSetTitle(uiWindow *w, const char *title); -_UI_EXTERN void uiWindowContentSize(uiWindow *w, int *width, int *height); -_UI_EXTERN void uiWindowSetContentSize(uiWindow *w, int width, int height); -_UI_EXTERN int uiWindowFullscreen(uiWindow *w); -_UI_EXTERN void uiWindowSetFullscreen(uiWindow *w, int fullscreen); -_UI_EXTERN void uiWindowOnContentSizeChanged(uiWindow *w, void (*f)(uiWindow *, void *), void *data); -_UI_EXTERN void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *w, void *data), void *data); -_UI_EXTERN int uiWindowBorderless(uiWindow *w); -_UI_EXTERN void uiWindowSetBorderless(uiWindow *w, int borderless); -_UI_EXTERN void uiWindowSetChild(uiWindow *w, uiControl *child); -_UI_EXTERN int uiWindowMargined(uiWindow *w); -_UI_EXTERN void uiWindowSetMargined(uiWindow *w, int margined); -_UI_EXTERN uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar); - -typedef struct uiButton uiButton; -#define uiButton(this) ((uiButton *) (this)) -_UI_EXTERN char *uiButtonText(uiButton *b); -_UI_EXTERN void uiButtonSetText(uiButton *b, const char *text); -_UI_EXTERN void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *b, void *data), void *data); -_UI_EXTERN uiButton *uiNewButton(const char *text); - -typedef struct uiBox uiBox; -#define uiBox(this) ((uiBox *) (this)) -_UI_EXTERN void uiBoxAppend(uiBox *b, uiControl *child, int stretchy); -_UI_EXTERN void uiBoxDelete(uiBox *b, int index); -_UI_EXTERN int uiBoxPadded(uiBox *b); -_UI_EXTERN void uiBoxSetPadded(uiBox *b, int padded); -_UI_EXTERN uiBox *uiNewHorizontalBox(void); -_UI_EXTERN uiBox *uiNewVerticalBox(void); - -typedef struct uiCheckbox uiCheckbox; -#define uiCheckbox(this) ((uiCheckbox *) (this)) -_UI_EXTERN char *uiCheckboxText(uiCheckbox *c); -_UI_EXTERN void uiCheckboxSetText(uiCheckbox *c, const char *text); -_UI_EXTERN void uiCheckboxOnToggled(uiCheckbox *c, void (*f)(uiCheckbox *c, void *data), void *data); -_UI_EXTERN int uiCheckboxChecked(uiCheckbox *c); -_UI_EXTERN void uiCheckboxSetChecked(uiCheckbox *c, int checked); -_UI_EXTERN uiCheckbox *uiNewCheckbox(const char *text); - -typedef struct uiEntry uiEntry; -#define uiEntry(this) ((uiEntry *) (this)) -_UI_EXTERN char *uiEntryText(uiEntry *e); -_UI_EXTERN void uiEntrySetText(uiEntry *e, const char *text); -_UI_EXTERN void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *e, void *data), void *data); -_UI_EXTERN int uiEntryReadOnly(uiEntry *e); -_UI_EXTERN void uiEntrySetReadOnly(uiEntry *e, int readonly); -_UI_EXTERN uiEntry *uiNewEntry(void); -_UI_EXTERN uiEntry *uiNewPasswordEntry(void); -_UI_EXTERN uiEntry *uiNewSearchEntry(void); - -typedef struct uiLabel uiLabel; -#define uiLabel(this) ((uiLabel *) (this)) -_UI_EXTERN char *uiLabelText(uiLabel *l); -_UI_EXTERN void uiLabelSetText(uiLabel *l, const char *text); -_UI_EXTERN uiLabel *uiNewLabel(const char *text); - -typedef struct uiTab uiTab; -#define uiTab(this) ((uiTab *) (this)) -_UI_EXTERN void uiTabAppend(uiTab *t, const char *name, uiControl *c); -_UI_EXTERN void uiTabInsertAt(uiTab *t, const char *name, int before, uiControl *c); -_UI_EXTERN void uiTabDelete(uiTab *t, int index); -_UI_EXTERN int uiTabNumPages(uiTab *t); -_UI_EXTERN int uiTabMargined(uiTab *t, int page); -_UI_EXTERN void uiTabSetMargined(uiTab *t, int page, int margined); -_UI_EXTERN uiTab *uiNewTab(void); - -typedef struct uiGroup uiGroup; -#define uiGroup(this) ((uiGroup *) (this)) -_UI_EXTERN char *uiGroupTitle(uiGroup *g); -_UI_EXTERN void uiGroupSetTitle(uiGroup *g, const char *title); -_UI_EXTERN void uiGroupSetChild(uiGroup *g, uiControl *c); -_UI_EXTERN int uiGroupMargined(uiGroup *g); -_UI_EXTERN void uiGroupSetMargined(uiGroup *g, int margined); -_UI_EXTERN uiGroup *uiNewGroup(const char *title); - -// spinbox/slider rules: -// setting value outside of range will automatically clamp -// initial value is minimum -// complaint if min >= max? - -typedef struct uiSpinbox uiSpinbox; -#define uiSpinbox(this) ((uiSpinbox *) (this)) -_UI_EXTERN int uiSpinboxValue(uiSpinbox *s); -_UI_EXTERN void uiSpinboxSetValue(uiSpinbox *s, int value); -_UI_EXTERN void uiSpinboxOnChanged(uiSpinbox *s, void (*f)(uiSpinbox *s, void *data), void *data); -_UI_EXTERN uiSpinbox *uiNewSpinbox(int min, int max); - -typedef struct uiSlider uiSlider; -#define uiSlider(this) ((uiSlider *) (this)) -_UI_EXTERN int uiSliderValue(uiSlider *s); -_UI_EXTERN void uiSliderSetValue(uiSlider *s, int value); -_UI_EXTERN void uiSliderOnChanged(uiSlider *s, void (*f)(uiSlider *s, void *data), void *data); -_UI_EXTERN uiSlider *uiNewSlider(int min, int max); - -typedef struct uiProgressBar uiProgressBar; -#define uiProgressBar(this) ((uiProgressBar *) (this)) -_UI_EXTERN int uiProgressBarValue(uiProgressBar *p); -_UI_EXTERN void uiProgressBarSetValue(uiProgressBar *p, int n); -_UI_EXTERN uiProgressBar *uiNewProgressBar(void); - -typedef struct uiSeparator uiSeparator; -#define uiSeparator(this) ((uiSeparator *) (this)) -_UI_EXTERN uiSeparator *uiNewHorizontalSeparator(void); -_UI_EXTERN uiSeparator *uiNewVerticalSeparator(void); - -typedef struct uiCombobox uiCombobox; -#define uiCombobox(this) ((uiCombobox *) (this)) -_UI_EXTERN void uiComboboxAppend(uiCombobox *c, const char *text); -_UI_EXTERN int uiComboboxSelected(uiCombobox *c); -_UI_EXTERN void uiComboboxSetSelected(uiCombobox *c, int n); -_UI_EXTERN void uiComboboxOnSelected(uiCombobox *c, void (*f)(uiCombobox *c, void *data), void *data); -_UI_EXTERN uiCombobox *uiNewCombobox(void); - -typedef struct uiEditableCombobox uiEditableCombobox; -#define uiEditableCombobox(this) ((uiEditableCombobox *) (this)) -_UI_EXTERN void uiEditableComboboxAppend(uiEditableCombobox *c, const char *text); -_UI_EXTERN char *uiEditableComboboxText(uiEditableCombobox *c); -_UI_EXTERN void uiEditableComboboxSetText(uiEditableCombobox *c, const char *text); -// TODO what do we call a function that sets the currently selected item and fills the text field with it? editable comboboxes have no consistent concept of selected item -_UI_EXTERN void uiEditableComboboxOnChanged(uiEditableCombobox *c, void (*f)(uiEditableCombobox *c, void *data), void *data); -_UI_EXTERN uiEditableCombobox *uiNewEditableCombobox(void); - -typedef struct uiRadioButtons uiRadioButtons; -#define uiRadioButtons(this) ((uiRadioButtons *) (this)) -_UI_EXTERN void uiRadioButtonsAppend(uiRadioButtons *r, const char *text); -_UI_EXTERN int uiRadioButtonsSelected(uiRadioButtons *r); -_UI_EXTERN void uiRadioButtonsSetSelected(uiRadioButtons *r, int n); -_UI_EXTERN void uiRadioButtonsOnSelected(uiRadioButtons *r, void (*f)(uiRadioButtons *, void *), void *data); -_UI_EXTERN uiRadioButtons *uiNewRadioButtons(void); - -typedef struct uiDateTimePicker uiDateTimePicker; -#define uiDateTimePicker(this) ((uiDateTimePicker *) (this)) -_UI_EXTERN uiDateTimePicker *uiNewDateTimePicker(void); -_UI_EXTERN uiDateTimePicker *uiNewDatePicker(void); -_UI_EXTERN uiDateTimePicker *uiNewTimePicker(void); - -// TODO provide a facility for entering tab stops? -typedef struct uiMultilineEntry uiMultilineEntry; -#define uiMultilineEntry(this) ((uiMultilineEntry *) (this)) -_UI_EXTERN char *uiMultilineEntryText(uiMultilineEntry *e); -_UI_EXTERN void uiMultilineEntrySetText(uiMultilineEntry *e, const char *text); -_UI_EXTERN void uiMultilineEntryAppend(uiMultilineEntry *e, const char *text); -_UI_EXTERN void uiMultilineEntryOnChanged(uiMultilineEntry *e, void (*f)(uiMultilineEntry *e, void *data), void *data); -_UI_EXTERN int uiMultilineEntryReadOnly(uiMultilineEntry *e); -_UI_EXTERN void uiMultilineEntrySetReadOnly(uiMultilineEntry *e, int readonly); -_UI_EXTERN uiMultilineEntry *uiNewMultilineEntry(void); -_UI_EXTERN uiMultilineEntry *uiNewNonWrappingMultilineEntry(void); - -typedef struct uiMenuItem uiMenuItem; -#define uiMenuItem(this) ((uiMenuItem *) (this)) -_UI_EXTERN void uiMenuItemEnable(uiMenuItem *m); -_UI_EXTERN void uiMenuItemDisable(uiMenuItem *m); -_UI_EXTERN void uiMenuItemOnClicked(uiMenuItem *m, void (*f)(uiMenuItem *sender, uiWindow *window, void *data), void *data); -_UI_EXTERN int uiMenuItemChecked(uiMenuItem *m); -_UI_EXTERN void uiMenuItemSetChecked(uiMenuItem *m, int checked); - -typedef struct uiMenu uiMenu; -#define uiMenu(this) ((uiMenu *) (this)) -_UI_EXTERN uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name); -_UI_EXTERN uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const char *name); -_UI_EXTERN uiMenuItem *uiMenuAppendQuitItem(uiMenu *m); -_UI_EXTERN uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m); -_UI_EXTERN uiMenuItem *uiMenuAppendAboutItem(uiMenu *m); -_UI_EXTERN void uiMenuAppendSeparator(uiMenu *m); -_UI_EXTERN uiMenu *uiNewMenu(const char *name); - -_UI_EXTERN char *uiOpenFile(uiWindow *parent); -_UI_EXTERN char *uiSaveFile(uiWindow *parent); -_UI_EXTERN void uiMsgBox(uiWindow *parent, const char *title, const char *description); -_UI_EXTERN void uiMsgBoxError(uiWindow *parent, const char *title, const char *description); - -typedef struct uiArea uiArea; -typedef struct uiAreaHandler uiAreaHandler; -typedef struct uiAreaDrawParams uiAreaDrawParams; -typedef struct uiAreaMouseEvent uiAreaMouseEvent; -typedef struct uiAreaKeyEvent uiAreaKeyEvent; - -typedef struct uiDrawContext uiDrawContext; - -struct uiAreaHandler { - void (*Draw)(uiAreaHandler *, uiArea *, uiAreaDrawParams *); - // TODO document that resizes cause a full redraw for non-scrolling areas; implementation-defined for scrolling areas - void (*MouseEvent)(uiAreaHandler *, uiArea *, uiAreaMouseEvent *); - // TODO document that on first show if the mouse is already in the uiArea then one gets sent with left=0 - // TODO what about when the area is hidden and then shown again? - void (*MouseCrossed)(uiAreaHandler *, uiArea *, int left); - void (*DragBroken)(uiAreaHandler *, uiArea *); - int (*KeyEvent)(uiAreaHandler *, uiArea *, uiAreaKeyEvent *); -}; - -// TODO RTL layouts? -// TODO reconcile edge and corner naming -_UI_ENUM(uiWindowResizeEdge) { - uiWindowResizeEdgeLeft, - uiWindowResizeEdgeTop, - uiWindowResizeEdgeRight, - uiWindowResizeEdgeBottom, - uiWindowResizeEdgeTopLeft, - uiWindowResizeEdgeTopRight, - uiWindowResizeEdgeBottomLeft, - uiWindowResizeEdgeBottomRight, - // TODO have one for keyboard resizes? - // TODO GDK doesn't seem to have any others, including for keyboards... - // TODO way to bring up the system menu instead? -}; - -#define uiArea(this) ((uiArea *) (this)) -// TODO give a better name -// TODO document the types of width and height -_UI_EXTERN void uiAreaSetSize(uiArea *a, int width, int height); -// TODO uiAreaQueueRedraw() -_UI_EXTERN void uiAreaQueueRedrawAll(uiArea *a); -_UI_EXTERN void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height); -// TODO document these can only be called within Mouse() handlers -// TODO should these be allowed on scrolling areas? -// TODO decide which mouse events should be accepted; Down is the only one guaranteed to work right now -// TODO what happens to events after calling this up to and including the next mouse up? -// TODO release capture? -_UI_EXTERN void uiAreaBeginUserWindowMove(uiArea *a); -_UI_EXTERN void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge); -_UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah); -_UI_EXTERN uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height); - -struct uiAreaDrawParams { - uiDrawContext *Context; - - // TODO document that this is only defined for nonscrolling areas - double AreaWidth; - double AreaHeight; - - double ClipX; - double ClipY; - double ClipWidth; - double ClipHeight; -}; - -typedef struct uiDrawPath uiDrawPath; -typedef struct uiDrawBrush uiDrawBrush; -typedef struct uiDrawStrokeParams uiDrawStrokeParams; -typedef struct uiDrawMatrix uiDrawMatrix; - -typedef struct uiDrawBrushGradientStop uiDrawBrushGradientStop; - -_UI_ENUM(uiDrawBrushType) { - uiDrawBrushTypeSolid, - uiDrawBrushTypeLinearGradient, - uiDrawBrushTypeRadialGradient, - uiDrawBrushTypeImage, -}; - -_UI_ENUM(uiDrawLineCap) { - uiDrawLineCapFlat, - uiDrawLineCapRound, - uiDrawLineCapSquare, -}; - -_UI_ENUM(uiDrawLineJoin) { - uiDrawLineJoinMiter, - uiDrawLineJoinRound, - uiDrawLineJoinBevel, -}; - -// this is the default for botoh cairo and Direct2D (in the latter case, from the C++ helper functions) -// Core Graphics doesn't explicitly specify a default, but NSBezierPath allows you to choose one, and this is the initial value -// so we're good to use it too! -#define uiDrawDefaultMiterLimit 10.0 - -_UI_ENUM(uiDrawFillMode) { - uiDrawFillModeWinding, - uiDrawFillModeAlternate, -}; - -struct uiDrawMatrix { - double M11; - double M12; - double M21; - double M22; - double M31; - double M32; -}; - -struct uiDrawBrush { - uiDrawBrushType Type; - - // solid brushes - double R; - double G; - double B; - double A; - - // gradient brushes - double X0; // linear: start X, radial: start X - double Y0; // linear: start Y, radial: start Y - double X1; // linear: end X, radial: outer circle center X - double Y1; // linear: end Y, radial: outer circle center Y - double OuterRadius; // radial gradients only - uiDrawBrushGradientStop *Stops; - size_t NumStops; - // TODO extend mode - // cairo: none, repeat, reflect, pad; no individual control - // Direct2D: repeat, reflect, pad; no individual control - // Core Graphics: none, pad; before and after individually - // TODO cairo documentation is inconsistent about pad - - // TODO images - - // TODO transforms -}; - -struct uiDrawBrushGradientStop { - double Pos; - double R; - double G; - double B; - double A; -}; - -struct uiDrawStrokeParams { - uiDrawLineCap Cap; - uiDrawLineJoin Join; - // TODO what if this is 0? on windows there will be a crash with dashing - double Thickness; - double MiterLimit; - double *Dashes; - // TOOD what if this is 1 on Direct2D? - // TODO what if a dash is 0 on Cairo or Quartz? - size_t NumDashes; - double DashPhase; -}; - -_UI_EXTERN uiDrawPath *uiDrawNewPath(uiDrawFillMode fillMode); -_UI_EXTERN void uiDrawFreePath(uiDrawPath *p); - -_UI_EXTERN void uiDrawPathNewFigure(uiDrawPath *p, double x, double y); -_UI_EXTERN void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative); -_UI_EXTERN void uiDrawPathLineTo(uiDrawPath *p, double x, double y); -// notes: angles are both relative to 0 and go counterclockwise -// TODO is the initial line segment on cairo and OS X a proper join? -// TODO what if sweep < 0? -_UI_EXTERN void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative); -_UI_EXTERN void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY); -// TODO quadratic bezier -_UI_EXTERN void uiDrawPathCloseFigure(uiDrawPath *p); - -// TODO effect of these when a figure is already started -_UI_EXTERN void uiDrawPathAddRectangle(uiDrawPath *p, double x, double y, double width, double height); - -_UI_EXTERN void uiDrawPathEnd(uiDrawPath *p); - -_UI_EXTERN void uiDrawStroke(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b, uiDrawStrokeParams *p); -_UI_EXTERN void uiDrawFill(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b); - -// TODO primitives: -// - rounded rectangles -// - elliptical arcs -// - quadratic bezier curves - -_UI_EXTERN void uiDrawMatrixSetIdentity(uiDrawMatrix *m); -_UI_EXTERN void uiDrawMatrixTranslate(uiDrawMatrix *m, double x, double y); -_UI_EXTERN void uiDrawMatrixScale(uiDrawMatrix *m, double xCenter, double yCenter, double x, double y); -_UI_EXTERN void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount); -_UI_EXTERN void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount); -_UI_EXTERN void uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src); -_UI_EXTERN int uiDrawMatrixInvertible(uiDrawMatrix *m); -_UI_EXTERN int uiDrawMatrixInvert(uiDrawMatrix *m); -_UI_EXTERN void uiDrawMatrixTransformPoint(uiDrawMatrix *m, double *x, double *y); -_UI_EXTERN void uiDrawMatrixTransformSize(uiDrawMatrix *m, double *x, double *y); - -_UI_EXTERN void uiDrawTransform(uiDrawContext *c, uiDrawMatrix *m); - -// TODO add a uiDrawPathStrokeToFill() or something like that -_UI_EXTERN void uiDrawClip(uiDrawContext *c, uiDrawPath *path); - -_UI_EXTERN void uiDrawSave(uiDrawContext *c); -_UI_EXTERN void uiDrawRestore(uiDrawContext *c); - -// TODO manage the use of Text, Font, and TextFont, and of the uiDrawText prefix in general - -///// TODO reconsider this -typedef struct uiDrawFontFamilies uiDrawFontFamilies; - -_UI_EXTERN uiDrawFontFamilies *uiDrawListFontFamilies(void); -_UI_EXTERN int uiDrawFontFamiliesNumFamilies(uiDrawFontFamilies *ff); -_UI_EXTERN char *uiDrawFontFamiliesFamily(uiDrawFontFamilies *ff, int n); -_UI_EXTERN void uiDrawFreeFontFamilies(uiDrawFontFamilies *ff); -///// END TODO - -typedef struct uiDrawTextLayout uiDrawTextLayout; -typedef struct uiDrawTextFont uiDrawTextFont; -typedef struct uiDrawTextFontDescriptor uiDrawTextFontDescriptor; -typedef struct uiDrawTextFontMetrics uiDrawTextFontMetrics; - -_UI_ENUM(uiDrawTextWeight) { - uiDrawTextWeightThin, - uiDrawTextWeightUltraLight, - uiDrawTextWeightLight, - uiDrawTextWeightBook, - uiDrawTextWeightNormal, - uiDrawTextWeightMedium, - uiDrawTextWeightSemiBold, - uiDrawTextWeightBold, - uiDrawTextWeightUltraBold, - uiDrawTextWeightHeavy, - uiDrawTextWeightUltraHeavy, -}; - -_UI_ENUM(uiDrawTextItalic) { - uiDrawTextItalicNormal, - uiDrawTextItalicOblique, - uiDrawTextItalicItalic, -}; - -_UI_ENUM(uiDrawTextStretch) { - uiDrawTextStretchUltraCondensed, - uiDrawTextStretchExtraCondensed, - uiDrawTextStretchCondensed, - uiDrawTextStretchSemiCondensed, - uiDrawTextStretchNormal, - uiDrawTextStretchSemiExpanded, - uiDrawTextStretchExpanded, - uiDrawTextStretchExtraExpanded, - uiDrawTextStretchUltraExpanded, -}; - -struct uiDrawTextFontDescriptor { - const char *Family; - double Size; - uiDrawTextWeight Weight; - uiDrawTextItalic Italic; - uiDrawTextStretch Stretch; -}; - -struct uiDrawTextFontMetrics { - double Ascent; - double Descent; - double Leading; - // TODO do these two mean the same across all platforms? - double UnderlinePos; - double UnderlineThickness; -}; - -_UI_EXTERN uiDrawTextFont *uiDrawLoadClosestFont(const uiDrawTextFontDescriptor *desc); -_UI_EXTERN void uiDrawFreeTextFont(uiDrawTextFont *font); -_UI_EXTERN uintptr_t uiDrawTextFontHandle(uiDrawTextFont *font); -_UI_EXTERN void uiDrawTextFontDescribe(uiDrawTextFont *font, uiDrawTextFontDescriptor *desc); -// TODO make copy with given attributes methods? -// TODO yuck this name -_UI_EXTERN void uiDrawTextFontGetMetrics(uiDrawTextFont *font, uiDrawTextFontMetrics *metrics); - -// TODO initial line spacing? and what about leading? -_UI_EXTERN uiDrawTextLayout *uiDrawNewTextLayout(const char *text, uiDrawTextFont *defaultFont, double width); -_UI_EXTERN void uiDrawFreeTextLayout(uiDrawTextLayout *layout); -// TODO get width -_UI_EXTERN void uiDrawTextLayoutSetWidth(uiDrawTextLayout *layout, double width); -_UI_EXTERN void uiDrawTextLayoutExtents(uiDrawTextLayout *layout, double *width, double *height); - -// and the attributes that you can set on a text layout -_UI_EXTERN void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, int startChar, int endChar, double r, double g, double b, double a); - -_UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout); - -_UI_ENUM(uiModifiers) { - uiModifierCtrl = 1 << 0, - uiModifierAlt = 1 << 1, - uiModifierShift = 1 << 2, - uiModifierSuper = 1 << 3, -}; - -// TODO document drag captures -struct uiAreaMouseEvent { - // TODO document what these mean for scrolling areas - double X; - double Y; - - // TODO see draw above - double AreaWidth; - double AreaHeight; - - int Down; - int Up; - - int Count; - - uiModifiers Modifiers; - - uint64_t Held1To64; -}; - -_UI_ENUM(uiExtKey) { - uiExtKeyEscape = 1, - uiExtKeyInsert, // equivalent to "Help" on Apple keyboards - uiExtKeyDelete, - uiExtKeyHome, - uiExtKeyEnd, - uiExtKeyPageUp, - uiExtKeyPageDown, - uiExtKeyUp, - uiExtKeyDown, - uiExtKeyLeft, - uiExtKeyRight, - uiExtKeyF1, // F1..F12 are guaranteed to be consecutive - uiExtKeyF2, - uiExtKeyF3, - uiExtKeyF4, - uiExtKeyF5, - uiExtKeyF6, - uiExtKeyF7, - uiExtKeyF8, - uiExtKeyF9, - uiExtKeyF10, - uiExtKeyF11, - uiExtKeyF12, - uiExtKeyN0, // numpad keys; independent of Num Lock state - uiExtKeyN1, // N0..N9 are guaranteed to be consecutive - uiExtKeyN2, - uiExtKeyN3, - uiExtKeyN4, - uiExtKeyN5, - uiExtKeyN6, - uiExtKeyN7, - uiExtKeyN8, - uiExtKeyN9, - uiExtKeyNDot, - uiExtKeyNEnter, - uiExtKeyNAdd, - uiExtKeyNSubtract, - uiExtKeyNMultiply, - uiExtKeyNDivide, -}; - -struct uiAreaKeyEvent { - char Key; - uiExtKey ExtKey; - uiModifiers Modifier; - - uiModifiers Modifiers; - - int Up; -}; - -typedef struct uiFontButton uiFontButton; -#define uiFontButton(this) ((uiFontButton *) (this)) -// TODO document this returns a new font -_UI_EXTERN uiDrawTextFont *uiFontButtonFont(uiFontButton *b); -// TOOD SetFont, mechanics -_UI_EXTERN void uiFontButtonOnChanged(uiFontButton *b, void (*f)(uiFontButton *, void *), void *data); -_UI_EXTERN uiFontButton *uiNewFontButton(void); - -typedef struct uiColorButton uiColorButton; -#define uiColorButton(this) ((uiColorButton *) (this)) -_UI_EXTERN void uiColorButtonColor(uiColorButton *b, double *r, double *g, double *bl, double *a); -_UI_EXTERN void uiColorButtonSetColor(uiColorButton *b, double r, double g, double bl, double a); -_UI_EXTERN void uiColorButtonOnChanged(uiColorButton *b, void (*f)(uiColorButton *, void *), void *data); -_UI_EXTERN uiColorButton *uiNewColorButton(void); - -typedef struct uiForm uiForm; -#define uiForm(this) ((uiForm *) (this)) -_UI_EXTERN void uiFormAppend(uiForm *f, const char *label, uiControl *c, int stretchy); -_UI_EXTERN void uiFormDelete(uiForm *f, int index); -_UI_EXTERN int uiFormPadded(uiForm *f); -_UI_EXTERN void uiFormSetPadded(uiForm *f, int padded); -_UI_EXTERN uiForm *uiNewForm(void); - -_UI_ENUM(uiAlign) { - uiAlignFill, - uiAlignStart, - uiAlignCenter, - uiAlignEnd, -}; - -_UI_ENUM(uiAt) { - uiAtLeading, - uiAtTop, - uiAtTrailing, - uiAtBottom, -}; - -typedef struct uiGrid uiGrid; -#define uiGrid(this) ((uiGrid *) (this)) -_UI_EXTERN void uiGridAppend(uiGrid *g, uiControl *c, int left, int top, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign); -_UI_EXTERN void uiGridInsertAt(uiGrid *g, uiControl *c, uiControl *existing, uiAt at, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign); -_UI_EXTERN int uiGridPadded(uiGrid *g); -_UI_EXTERN void uiGridSetPadded(uiGrid *g, int padded); -_UI_EXTERN uiGrid *uiNewGrid(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/deps/libui/ui_darwin.h b/deps/libui/ui_darwin.h deleted file mode 100644 index c9c6ad54e9..0000000000 --- a/deps/libui/ui_darwin.h +++ /dev/null @@ -1,224 +0,0 @@ -// 7 april 2015 - -/* -This file assumes that you have imported and "ui.h" beforehand. It provides API-specific functions for interfacing with foreign controls on Mac OS X. -*/ - -#ifndef __LIBUI_UI_DARWIN_H__ -#define __LIBUI_UI_DARWIN_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct uiDarwinControl uiDarwinControl; -struct uiDarwinControl { - uiControl c; - uiControl *parent; - BOOL enabled; - BOOL visible; - void (*SyncEnableState)(uiDarwinControl *, int); - void (*SetSuperview)(uiDarwinControl *, NSView *); - BOOL (*HugsTrailingEdge)(uiDarwinControl *); - BOOL (*HugsBottom)(uiDarwinControl *); - void (*ChildEdgeHuggingChanged)(uiDarwinControl *); - NSLayoutPriority (*HuggingPriority)(uiDarwinControl *, NSLayoutConstraintOrientation); - void (*SetHuggingPriority)(uiDarwinControl *, NSLayoutPriority, NSLayoutConstraintOrientation); - void (*ChildVisibilityChanged)(uiDarwinControl *); -}; -#define uiDarwinControl(this) ((uiDarwinControl *) (this)) -// TODO document -_UI_EXTERN void uiDarwinControlSyncEnableState(uiDarwinControl *, int); -_UI_EXTERN void uiDarwinControlSetSuperview(uiDarwinControl *, NSView *); -_UI_EXTERN BOOL uiDarwinControlHugsTrailingEdge(uiDarwinControl *); -_UI_EXTERN BOOL uiDarwinControlHugsBottom(uiDarwinControl *); -_UI_EXTERN void uiDarwinControlChildEdgeHuggingChanged(uiDarwinControl *); -_UI_EXTERN NSLayoutPriority uiDarwinControlHuggingPriority(uiDarwinControl *, NSLayoutConstraintOrientation); -_UI_EXTERN void uiDarwinControlSetHuggingPriority(uiDarwinControl *, NSLayoutPriority, NSLayoutConstraintOrientation); -_UI_EXTERN void uiDarwinControlChildVisibilityChanged(uiDarwinControl *); - -#define uiDarwinControlDefaultDestroy(type, handlefield) \ - static void type ## Destroy(uiControl *c) \ - { \ - [type(c)->handlefield release]; \ - uiFreeControl(c); \ - } -#define uiDarwinControlDefaultHandle(type, handlefield) \ - static uintptr_t type ## Handle(uiControl *c) \ - { \ - return (uintptr_t) (type(c)->handlefield); \ - } -#define uiDarwinControlDefaultParent(type, handlefield) \ - static uiControl *type ## Parent(uiControl *c) \ - { \ - return uiDarwinControl(c)->parent; \ - } -#define uiDarwinControlDefaultSetParent(type, handlefield) \ - static void type ## SetParent(uiControl *c, uiControl *parent) \ - { \ - uiControlVerifySetParent(c, parent); \ - uiDarwinControl(c)->parent = parent; \ - } -#define uiDarwinControlDefaultToplevel(type, handlefield) \ - static int type ## Toplevel(uiControl *c) \ - { \ - return 0; \ - } -#define uiDarwinControlDefaultVisible(type, handlefield) \ - static int type ## Visible(uiControl *c) \ - { \ - return uiDarwinControl(c)->visible; \ - } -#define uiDarwinControlDefaultShow(type, handlefield) \ - static void type ## Show(uiControl *c) \ - { \ - uiDarwinControl(c)->visible = YES; \ - [type(c)->handlefield setHidden:NO]; \ - uiDarwinNotifyVisibilityChanged(uiDarwinControl(c)); \ - } -#define uiDarwinControlDefaultHide(type, handlefield) \ - static void type ## Hide(uiControl *c) \ - { \ - uiDarwinControl(c)->visible = NO; \ - [type(c)->handlefield setHidden:YES]; \ - uiDarwinNotifyVisibilityChanged(uiDarwinControl(c)); \ - } -#define uiDarwinControlDefaultEnabled(type, handlefield) \ - static int type ## Enabled(uiControl *c) \ - { \ - return uiDarwinControl(c)->enabled; \ - } -#define uiDarwinControlDefaultEnable(type, handlefield) \ - static void type ## Enable(uiControl *c) \ - { \ - uiDarwinControl(c)->enabled = YES; \ - uiDarwinControlSyncEnableState(uiDarwinControl(c), uiControlEnabledToUser(c)); \ - } -#define uiDarwinControlDefaultDisable(type, handlefield) \ - static void type ## Disable(uiControl *c) \ - { \ - uiDarwinControl(c)->enabled = NO; \ - uiDarwinControlSyncEnableState(uiDarwinControl(c), uiControlEnabledToUser(c)); \ - } -#define uiDarwinControlDefaultSyncEnableState(type, handlefield) \ - static void type ## SyncEnableState(uiDarwinControl *c, int enabled) \ - { \ - if (uiDarwinShouldStopSyncEnableState(c, enabled)) \ - return; \ - if ([type(c)->handlefield respondsToSelector:@selector(setEnabled:)]) \ - [((id) (type(c)->handlefield)) setEnabled:enabled]; /* id cast to make compiler happy; thanks mikeash in irc.freenode.net/#macdev */ \ - } -#define uiDarwinControlDefaultSetSuperview(type, handlefield) \ - static void type ## SetSuperview(uiDarwinControl *c, NSView *superview) \ - { \ - [type(c)->handlefield setTranslatesAutoresizingMaskIntoConstraints:NO]; \ - if (superview == nil) \ - [type(c)->handlefield removeFromSuperview]; \ - else \ - [superview addSubview:type(c)->handlefield]; \ - } -#define uiDarwinControlDefaultHugsTrailingEdge(type, handlefield) \ - static BOOL type ## HugsTrailingEdge(uiDarwinControl *c) \ - { \ - return YES; /* always hug by default */ \ - } -#define uiDarwinControlDefaultHugsBottom(type, handlefield) \ - static BOOL type ## HugsBottom(uiDarwinControl *c) \ - { \ - return YES; /* always hug by default */ \ - } -#define uiDarwinControlDefaultChildEdgeHuggingChanged(type, handlefield) \ - static void type ## ChildEdgeHuggingChanged(uiDarwinControl *c) \ - { \ - /* do nothing */ \ - } -#define uiDarwinControlDefaultHuggingPriority(type, handlefield) \ - static NSLayoutPriority type ## HuggingPriority(uiDarwinControl *c, NSLayoutConstraintOrientation orientation) \ - { \ - return [type(c)->handlefield contentHuggingPriorityForOrientation:orientation]; \ - } -#define uiDarwinControlDefaultSetHuggingPriority(type, handlefield) \ - static void type ## SetHuggingPriority(uiDarwinControl *c, NSLayoutPriority priority, NSLayoutConstraintOrientation orientation) \ - { \ - [type(c)->handlefield setContentHuggingPriority:priority forOrientation:orientation]; \ - } -#define uiDarwinControlDefaultChildVisibilityChanged(type, handlefield) \ - static void type ## ChildVisibilityChanged(uiDarwinControl *c) \ - { \ - /* do nothing */ \ - } - -#define uiDarwinControlAllDefaultsExceptDestroy(type, handlefield) \ - uiDarwinControlDefaultHandle(type, handlefield) \ - uiDarwinControlDefaultParent(type, handlefield) \ - uiDarwinControlDefaultSetParent(type, handlefield) \ - uiDarwinControlDefaultToplevel(type, handlefield) \ - uiDarwinControlDefaultVisible(type, handlefield) \ - uiDarwinControlDefaultShow(type, handlefield) \ - uiDarwinControlDefaultHide(type, handlefield) \ - uiDarwinControlDefaultEnabled(type, handlefield) \ - uiDarwinControlDefaultEnable(type, handlefield) \ - uiDarwinControlDefaultDisable(type, handlefield) \ - uiDarwinControlDefaultSyncEnableState(type, handlefield) \ - uiDarwinControlDefaultSetSuperview(type, handlefield) \ - uiDarwinControlDefaultHugsTrailingEdge(type, handlefield) \ - uiDarwinControlDefaultHugsBottom(type, handlefield) \ - uiDarwinControlDefaultChildEdgeHuggingChanged(type, handlefield) \ - uiDarwinControlDefaultHuggingPriority(type, handlefield) \ - uiDarwinControlDefaultSetHuggingPriority(type, handlefield) \ - uiDarwinControlDefaultChildVisibilityChanged(type, handlefield) - -#define uiDarwinControlAllDefaults(type, handlefield) \ - uiDarwinControlDefaultDestroy(type, handlefield) \ - uiDarwinControlAllDefaultsExceptDestroy(type, handlefield) - -// TODO document -#define uiDarwinNewControl(type, var) \ - var = type(uiDarwinAllocControl(sizeof (type), type ## Signature, #type)); \ - uiControl(var)->Destroy = type ## Destroy; \ - uiControl(var)->Handle = type ## Handle; \ - uiControl(var)->Parent = type ## Parent; \ - uiControl(var)->SetParent = type ## SetParent; \ - uiControl(var)->Toplevel = type ## Toplevel; \ - uiControl(var)->Visible = type ## Visible; \ - uiControl(var)->Show = type ## Show; \ - uiControl(var)->Hide = type ## Hide; \ - uiControl(var)->Enabled = type ## Enabled; \ - uiControl(var)->Enable = type ## Enable; \ - uiControl(var)->Disable = type ## Disable; \ - uiDarwinControl(var)->SyncEnableState = type ## SyncEnableState; \ - uiDarwinControl(var)->SetSuperview = type ## SetSuperview; \ - uiDarwinControl(var)->HugsTrailingEdge = type ## HugsTrailingEdge; \ - uiDarwinControl(var)->HugsBottom = type ## HugsBottom; \ - uiDarwinControl(var)->ChildEdgeHuggingChanged = type ## ChildEdgeHuggingChanged; \ - uiDarwinControl(var)->HuggingPriority = type ## HuggingPriority; \ - uiDarwinControl(var)->SetHuggingPriority = type ## SetHuggingPriority; \ - uiDarwinControl(var)->ChildVisibilityChanged = type ## ChildVisibilityChanged; \ - uiDarwinControl(var)->visible = YES; \ - uiDarwinControl(var)->enabled = YES; -// TODO document -_UI_EXTERN uiDarwinControl *uiDarwinAllocControl(size_t n, uint32_t typesig, const char *typenamestr); - -// Use this function as a shorthand for setting control fonts. -_UI_EXTERN void uiDarwinSetControlFont(NSControl *c, NSControlSize size); - -// You can use this function from within your control implementations to return text strings that can be freed with uiFreeText(). -_UI_EXTERN char *uiDarwinNSStringToText(NSString *); - -// TODO document -_UI_EXTERN BOOL uiDarwinShouldStopSyncEnableState(uiDarwinControl *, BOOL); - -// TODO document -_UI_EXTERN void uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl *); -_UI_EXTERN void uiDarwinNotifyVisibilityChanged(uiDarwinControl *c); - -// TODO document -// TODO document that values should not be cached -_UI_EXTERN CGFloat uiDarwinMarginAmount(void *reserved); -_UI_EXTERN CGFloat uiDarwinPaddingAmount(void *reserved); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/deps/libui/ui_unix.h b/deps/libui/ui_unix.h deleted file mode 100644 index 5a91257bdd..0000000000 --- a/deps/libui/ui_unix.h +++ /dev/null @@ -1,140 +0,0 @@ -// 7 april 2015 - -/* -This file assumes that you have included and "ui.h" beforehand. It provides API-specific functions for interfacing with foreign controls on Unix systems that use GTK+ to provide their UI (currently all except Mac OS X). -*/ - -#ifndef __LIBUI_UI_UNIX_H__ -#define __LIBUI_UI_UNIX_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct uiUnixControl uiUnixControl; -struct uiUnixControl { - uiControl c; - uiControl *parent; - gboolean addedBefore; - void (*SetContainer)(uiUnixControl *, GtkContainer *, gboolean); -}; -#define uiUnixControl(this) ((uiUnixControl *) (this)) -// TODO document -_UI_EXTERN void uiUnixControlSetContainer(uiUnixControl *, GtkContainer *, gboolean); - -#define uiUnixControlDefaultDestroy(type) \ - static void type ## Destroy(uiControl *c) \ - { \ - /* TODO is this safe on floating refs? */ \ - g_object_unref(type(c)->widget); \ - uiFreeControl(c); \ - } -#define uiUnixControlDefaultHandle(type) \ - static uintptr_t type ## Handle(uiControl *c) \ - { \ - return (uintptr_t) (type(c)->widget); \ - } -#define uiUnixControlDefaultParent(type) \ - static uiControl *type ## Parent(uiControl *c) \ - { \ - return uiUnixControl(c)->parent; \ - } -#define uiUnixControlDefaultSetParent(type) \ - static void type ## SetParent(uiControl *c, uiControl *parent) \ - { \ - uiControlVerifySetParent(c, parent); \ - uiUnixControl(c)->parent = parent; \ - } -#define uiUnixControlDefaultToplevel(type) \ - static int type ## Toplevel(uiControl *c) \ - { \ - return 0; \ - } -#define uiUnixControlDefaultVisible(type) \ - static int type ## Visible(uiControl *c) \ - { \ - return gtk_widget_get_visible(type(c)->widget); \ - } -#define uiUnixControlDefaultShow(type) \ - static void type ## Show(uiControl *c) \ - { \ - gtk_widget_show(type(c)->widget); \ - } -#define uiUnixControlDefaultHide(type) \ - static void type ## Hide(uiControl *c) \ - { \ - gtk_widget_hide(type(c)->widget); \ - } -#define uiUnixControlDefaultEnabled(type) \ - static int type ## Enabled(uiControl *c) \ - { \ - return gtk_widget_get_sensitive(type(c)->widget); \ - } -#define uiUnixControlDefaultEnable(type) \ - static void type ## Enable(uiControl *c) \ - { \ - gtk_widget_set_sensitive(type(c)->widget, TRUE); \ - } -#define uiUnixControlDefaultDisable(type) \ - static void type ## Disable(uiControl *c) \ - { \ - gtk_widget_set_sensitive(type(c)->widget, FALSE); \ - } -// TODO this whole addedBefore stuff is a MASSIVE HACK. -#define uiUnixControlDefaultSetContainer(type) \ - static void type ## SetContainer(uiUnixControl *c, GtkContainer *container, gboolean remove) \ - { \ - if (!uiUnixControl(c)->addedBefore) { \ - g_object_ref_sink(type(c)->widget); /* our own reference, which we release in Destroy() */ \ - gtk_widget_show(type(c)->widget); \ - uiUnixControl(c)->addedBefore = TRUE; \ - } \ - if (remove) \ - gtk_container_remove(container, type(c)->widget); \ - else \ - gtk_container_add(container, type(c)->widget); \ - } - -#define uiUnixControlAllDefaultsExceptDestroy(type) \ - uiUnixControlDefaultHandle(type) \ - uiUnixControlDefaultParent(type) \ - uiUnixControlDefaultSetParent(type) \ - uiUnixControlDefaultToplevel(type) \ - uiUnixControlDefaultVisible(type) \ - uiUnixControlDefaultShow(type) \ - uiUnixControlDefaultHide(type) \ - uiUnixControlDefaultEnabled(type) \ - uiUnixControlDefaultEnable(type) \ - uiUnixControlDefaultDisable(type) \ - uiUnixControlDefaultSetContainer(type) - -#define uiUnixControlAllDefaults(type) \ - uiUnixControlDefaultDestroy(type) \ - uiUnixControlAllDefaultsExceptDestroy(type) - -// TODO document -#define uiUnixNewControl(type, var) \ - var = type(uiUnixAllocControl(sizeof (type), type ## Signature, #type)); \ - uiControl(var)->Destroy = type ## Destroy; \ - uiControl(var)->Handle = type ## Handle; \ - uiControl(var)->Parent = type ## Parent; \ - uiControl(var)->SetParent = type ## SetParent; \ - uiControl(var)->Toplevel = type ## Toplevel; \ - uiControl(var)->Visible = type ## Visible; \ - uiControl(var)->Show = type ## Show; \ - uiControl(var)->Hide = type ## Hide; \ - uiControl(var)->Enabled = type ## Enabled; \ - uiControl(var)->Enable = type ## Enable; \ - uiControl(var)->Disable = type ## Disable; \ - uiUnixControl(var)->SetContainer = type ## SetContainer; -// TODO document -_UI_EXTERN uiUnixControl *uiUnixAllocControl(size_t n, uint32_t typesig, const char *typenamestr); - -// uiUnixStrdupText() takes the given string and produces a copy of it suitable for being freed by uiFreeText(). -_UI_EXTERN char *uiUnixStrdupText(const char *); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/deps/libui/ui_windows.h b/deps/libui/ui_windows.h deleted file mode 100644 index 69dda3666c..0000000000 --- a/deps/libui/ui_windows.h +++ /dev/null @@ -1,267 +0,0 @@ -// 21 april 2016 - -/* -This file assumes that you have included and "ui.h" beforehand. It provides API-specific functions for interfacing with foreign controls in Windows. -*/ - -#ifndef __LIBUI_UI_WINDOWS_H__ -#define __LIBUI_UI_WINDOWS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct uiWindowsSizing uiWindowsSizing; - -typedef struct uiWindowsControl uiWindowsControl; -struct uiWindowsControl { - uiControl c; - uiControl *parent; - // TODO this should be int on both os x and windows - BOOL enabled; - BOOL visible; - void (*SyncEnableState)(uiWindowsControl *, int); - void (*SetParentHWND)(uiWindowsControl *, HWND); - void (*MinimumSize)(uiWindowsControl *, int *, int *); - void (*MinimumSizeChanged)(uiWindowsControl *); - void (*LayoutRect)(uiWindowsControl *c, RECT *r); - void (*AssignControlIDZOrder)(uiWindowsControl *, LONG_PTR *, HWND *); - void (*ChildVisibilityChanged)(uiWindowsControl *); -}; -#define uiWindowsControl(this) ((uiWindowsControl *) (this)) -// TODO document -_UI_EXTERN void uiWindowsControlSyncEnableState(uiWindowsControl *, int); -_UI_EXTERN void uiWindowsControlSetParentHWND(uiWindowsControl *, HWND); -_UI_EXTERN void uiWindowsControlMinimumSize(uiWindowsControl *, int *, int *); -_UI_EXTERN void uiWindowsControlMinimumSizeChanged(uiWindowsControl *); -_UI_EXTERN void uiWindowsControlLayoutRect(uiWindowsControl *, RECT *); -_UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_PTR *, HWND *); -_UI_EXTERN void uiWindowsControlChildVisibilityChanged(uiWindowsControl *); - -// TODO document -#define uiWindowsControlDefaultDestroy(type) \ - static void type ## Destroy(uiControl *c) \ - { \ - uiWindowsEnsureDestroyWindow(type(c)->hwnd); \ - uiFreeControl(c); \ - } -#define uiWindowsControlDefaultHandle(type) \ - static uintptr_t type ## Handle(uiControl *c) \ - { \ - return (uintptr_t) (type(c)->hwnd); \ - } -#define uiWindowsControlDefaultParent(type) \ - static uiControl *type ## Parent(uiControl *c) \ - { \ - return uiWindowsControl(c)->parent; \ - } -#define uiWindowsControlDefaultSetParent(type) \ - static void type ## SetParent(uiControl *c, uiControl *parent) \ - { \ - uiControlVerifySetParent(c, parent); \ - uiWindowsControl(c)->parent = parent; \ - } -#define uiWindowsControlDefaultToplevel(type) \ - static int type ## Toplevel(uiControl *c) \ - { \ - return 0; \ - } -#define uiWindowsControlDefaultVisible(type) \ - static int type ## Visible(uiControl *c) \ - { \ - return uiWindowsControl(c)->visible; \ - } -#define uiWindowsControlDefaultShow(type) \ - static void type ## Show(uiControl *c) \ - { \ - uiWindowsControl(c)->visible = 1; \ - ShowWindow(type(c)->hwnd, SW_SHOW); \ - uiWindowsControlNotifyVisibilityChanged(uiWindowsControl(c)); \ - } -#define uiWindowsControlDefaultHide(type) \ - static void type ## Hide(uiControl *c) \ - { \ - uiWindowsControl(c)->visible = 0; \ - ShowWindow(type(c)->hwnd, SW_HIDE); \ - uiWindowsControlNotifyVisibilityChanged(uiWindowsControl(c)); \ - } -#define uiWindowsControlDefaultEnabled(type) \ - static int type ## Enabled(uiControl *c) \ - { \ - return uiWindowsControl(c)->enabled; \ - } -#define uiWindowsControlDefaultEnable(type) \ - static void type ## Enable(uiControl *c) \ - { \ - uiWindowsControl(c)->enabled = 1; \ - uiWindowsControlSyncEnableState(uiWindowsControl(c), uiControlEnabledToUser(c)); \ - } -#define uiWindowsControlDefaultDisable(type) \ - static void type ## Disable(uiControl *c) \ - { \ - uiWindowsControl(c)->enabled = 0; \ - uiWindowsControlSyncEnableState(uiWindowsControl(c), uiControlEnabledToUser(c)); \ - } -#define uiWindowsControlDefaultSyncEnableState(type) \ - static void type ## SyncEnableState(uiWindowsControl *c, int enabled) \ - { \ - if (uiWindowsShouldStopSyncEnableState(c, enabled)) \ - return; \ - EnableWindow(type(c)->hwnd, enabled); \ - } -#define uiWindowsControlDefaultSetParentHWND(type) \ - static void type ## SetParentHWND(uiWindowsControl *c, HWND parent) \ - { \ - uiWindowsEnsureSetParentHWND(type(c)->hwnd, parent); \ - } -// note that there is no uiWindowsControlDefaultMinimumSize(); you MUST define this yourself! -#define uiWindowsControlDefaultMinimumSizeChanged(type) \ - static void type ## MinimumSizeChanged(uiWindowsControl *c) \ - { \ - if (uiWindowsControlTooSmall(c)) { \ - uiWindowsControlContinueMinimumSizeChanged(c); \ - return; \ - } \ - /* otherwise do nothing; we have no children */ \ - } -#define uiWindowsControlDefaultLayoutRect(type) \ - static void type ## LayoutRect(uiWindowsControl *c, RECT *r) \ - { \ - /* use the window rect as we include the non-client area in the sizes */ \ - uiWindowsEnsureGetWindowRect(type(c)->hwnd, r); \ - } -#define uiWindowsControlDefaultAssignControlIDZOrder(type) \ - static void type ## AssignControlIDZOrder(uiWindowsControl *c, LONG_PTR *controlID, HWND *insertAfter) \ - { \ - uiWindowsEnsureAssignControlIDZOrder(type(c)->hwnd, controlID, insertAfter); \ - } -#define uiWindowsControlDefaultChildVisibilityChanged(type) \ - static void type ## ChildVisibilityChanged(uiWindowsControl *c) \ - { \ - /* do nothing */ \ - } - -#define uiWindowsControlAllDefaultsExceptDestroy(type) \ - uiWindowsControlDefaultHandle(type) \ - uiWindowsControlDefaultParent(type) \ - uiWindowsControlDefaultSetParent(type) \ - uiWindowsControlDefaultToplevel(type) \ - uiWindowsControlDefaultVisible(type) \ - uiWindowsControlDefaultShow(type) \ - uiWindowsControlDefaultHide(type) \ - uiWindowsControlDefaultEnabled(type) \ - uiWindowsControlDefaultEnable(type) \ - uiWindowsControlDefaultDisable(type) \ - uiWindowsControlDefaultSyncEnableState(type) \ - uiWindowsControlDefaultSetParentHWND(type) \ - uiWindowsControlDefaultMinimumSizeChanged(type) \ - uiWindowsControlDefaultLayoutRect(type) \ - uiWindowsControlDefaultAssignControlIDZOrder(type) \ - uiWindowsControlDefaultChildVisibilityChanged(type) - -#define uiWindowsControlAllDefaults(type) \ - uiWindowsControlDefaultDestroy(type) \ - uiWindowsControlAllDefaultsExceptDestroy(type) - -// TODO document -#define uiWindowsNewControl(type, var) \ - var = type(uiWindowsAllocControl(sizeof (type), type ## Signature, #type)); \ - uiControl(var)->Destroy = type ## Destroy; \ - uiControl(var)->Handle = type ## Handle; \ - uiControl(var)->Parent = type ## Parent; \ - uiControl(var)->SetParent = type ## SetParent; \ - uiControl(var)->Toplevel = type ## Toplevel; \ - uiControl(var)->Visible = type ## Visible; \ - uiControl(var)->Show = type ## Show; \ - uiControl(var)->Hide = type ## Hide; \ - uiControl(var)->Enabled = type ## Enabled; \ - uiControl(var)->Enable = type ## Enable; \ - uiControl(var)->Disable = type ## Disable; \ - uiWindowsControl(var)->SyncEnableState = type ## SyncEnableState; \ - uiWindowsControl(var)->SetParentHWND = type ## SetParentHWND; \ - uiWindowsControl(var)->MinimumSize = type ## MinimumSize; \ - uiWindowsControl(var)->MinimumSizeChanged = type ## MinimumSizeChanged; \ - uiWindowsControl(var)->LayoutRect = type ## LayoutRect; \ - uiWindowsControl(var)->AssignControlIDZOrder = type ## AssignControlIDZOrder; \ - uiWindowsControl(var)->ChildVisibilityChanged = type ## ChildVisibilityChanged; \ - uiWindowsControl(var)->visible = 1; \ - uiWindowsControl(var)->enabled = 1; -// TODO document -_UI_EXTERN uiWindowsControl *uiWindowsAllocControl(size_t n, uint32_t typesig, const char *typenamestr); - -// TODO document -_UI_EXTERN HWND uiWindowsEnsureCreateControlHWND(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, HINSTANCE hInstance, LPVOID lpParam, BOOL useStandardControlFont); - -// TODO document -_UI_EXTERN void uiWindowsEnsureDestroyWindow(HWND hwnd); - -// TODO document -// TODO document that this should only be used in SetParentHWND() implementations -_UI_EXTERN void uiWindowsEnsureSetParentHWND(HWND hwnd, HWND parent); - -// TODO document -_UI_EXTERN void uiWindowsEnsureAssignControlIDZOrder(HWND hwnd, LONG_PTR *controlID, HWND *insertAfter); - -// TODO document -_UI_EXTERN void uiWindowsEnsureGetClientRect(HWND hwnd, RECT *r); -_UI_EXTERN void uiWindowsEnsureGetWindowRect(HWND hwnd, RECT *r); - -// TODO document -_UI_EXTERN char *uiWindowsWindowText(HWND hwnd); -_UI_EXTERN void uiWindowsSetWindowText(HWND hwnd, const char *text); - -// TODO document -_UI_EXTERN int uiWindowsWindowTextWidth(HWND hwnd); - -// TODO document -// TODO point out this should only be used in a resize cycle -_UI_EXTERN void uiWindowsEnsureMoveWindowDuringResize(HWND hwnd, int x, int y, int width, int height); - -// TODO document -_UI_EXTERN void uiWindowsRegisterWM_COMMANDHandler(HWND hwnd, BOOL (*handler)(uiControl *, HWND, WORD, LRESULT *), uiControl *c); -_UI_EXTERN void uiWindowsUnregisterWM_COMMANDHandler(HWND hwnd); - -// TODO document -_UI_EXTERN void uiWindowsRegisterWM_NOTIFYHandler(HWND hwnd, BOOL (*handler)(uiControl *, HWND, NMHDR *, LRESULT *), uiControl *c); -_UI_EXTERN void uiWindowsUnregisterWM_NOTIFYHandler(HWND hwnd); - -// TODO document -_UI_EXTERN void uiWindowsRegisterWM_HSCROLLHandler(HWND hwnd, BOOL (*handler)(uiControl *, HWND, WORD, LRESULT *), uiControl *c); -_UI_EXTERN void uiWindowsUnregisterWM_HSCROLLHandler(HWND hwnd); - -// TODO document -_UI_EXTERN void uiWindowsRegisterReceiveWM_WININICHANGE(HWND hwnd); -_UI_EXTERN void uiWindowsUnregisterReceiveWM_WININICHANGE(HWND hwnd); - -// TODO document -typedef struct uiWindowsSizing uiWindowsSizing; -struct uiWindowsSizing { - int BaseX; - int BaseY; - LONG InternalLeading; -}; -_UI_EXTERN void uiWindowsGetSizing(HWND hwnd, uiWindowsSizing *sizing); -_UI_EXTERN void uiWindowsSizingDlgUnitsToPixels(uiWindowsSizing *sizing, int *x, int *y); -_UI_EXTERN void uiWindowsSizingStandardPadding(uiWindowsSizing *sizing, int *x, int *y); - -// TODO document -_UI_EXTERN HWND uiWindowsMakeContainer(uiWindowsControl *c, void (*onResize)(uiWindowsControl *)); - -// TODO document -_UI_EXTERN BOOL uiWindowsControlTooSmall(uiWindowsControl *c); -_UI_EXTERN void uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl *c); - -// TODO document -_UI_EXTERN void uiWindowsControlAssignSoleControlIDZOrder(uiWindowsControl *); - -// TODO document -_UI_EXTERN BOOL uiWindowsShouldStopSyncEnableState(uiWindowsControl *c, int enabled); - -// TODO document -_UI_EXTERN void uiWindowsControlNotifyVisibilityChanged(uiWindowsControl *c); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/deps/libui/unix/CMakeLists.txt b/deps/libui/unix/CMakeLists.txt deleted file mode 100644 index 9300bcb701..0000000000 --- a/deps/libui/unix/CMakeLists.txt +++ /dev/null @@ -1,85 +0,0 @@ -# 3 june 2016 - -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED gtk+-3.0) - -list(APPEND _LIBUI_SOURCES - unix/alloc.c - unix/area.c - unix/box.c - unix/button.c - unix/cellrendererbutton.c - unix/checkbox.c - unix/child.c - unix/colorbutton.c - unix/combobox.c - unix/control.c - unix/datetimepicker.c - unix/debug.c - unix/draw.c - unix/drawmatrix.c - unix/drawpath.c - unix/drawtext.c - unix/editablecombo.c - unix/entry.c - unix/fontbutton.c - unix/form.c - unix/future.c - unix/graphemes.c - unix/grid.c - unix/group.c - unix/image.c - unix/label.c - unix/main.c - unix/menu.c - unix/multilineentry.c - unix/progressbar.c - unix/radiobuttons.c - unix/separator.c - unix/slider.c - unix/spinbox.c - unix/stddialogs.c - unix/tab.c - unix/text.c - unix/util.c - unix/window.c -) -set(_LIBUI_SOURCES ${_LIBUI_SOURCES} PARENT_SCOPE) - -list(APPEND _LIBUI_INCLUDEDIRS - unix -) -set(_LIBUI_INCLUDEDIRS _LIBUI_INCLUDEDIRS PARENT_SCOPE) - -set(_LIBUINAME libui PARENT_SCOPE) -if(NOT BUILD_SHARED_LIBS) - set(_LIBUINAME libui-temporary PARENT_SCOPE) -endif() -macro(_handle_static) - set_target_properties(${_LIBUINAME} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") - set(_aname $) - set(_oname libui-combined.o) - add_custom_command( - OUTPUT ${_oname} - COMMAND - ld -r --whole-archive ${_aname} -o ${_oname} - COMMAND - objcopy --localize-hidden ${_oname} - COMMENT "Removing hidden symbols") - add_library(libui STATIC ${_oname}) - # otherwise cmake won't know which linker to use - set_target_properties(libui PROPERTIES - LINKER_LANGUAGE C) - set(_aname) - set(_oname) -endmacro() - -# TODO the other variables don't work? -set(_LIBUI_CFLAGS - ${GTK_CFLAGS} -PARENT_SCOPE) - -set(_LIBUI_LIBS - ${GTK_LDFLAGS} m ${CMAKE_DL_LIBS} -PARENT_SCOPE) diff --git a/deps/libui/unix/alloc.c b/deps/libui/unix/alloc.c deleted file mode 100644 index 2561efa6e2..0000000000 --- a/deps/libui/unix/alloc.c +++ /dev/null @@ -1,84 +0,0 @@ -// 7 april 2015 -#include -#include "uipriv_unix.h" - -static GPtrArray *allocations; - -#define UINT8(p) ((uint8_t *) (p)) -#define PVOID(p) ((void *) (p)) -#define EXTRA (sizeof (size_t) + sizeof (const char **)) -#define DATA(p) PVOID(UINT8(p) + EXTRA) -#define BASE(p) PVOID(UINT8(p) - EXTRA) -#define SIZE(p) ((size_t *) (p)) -#define CCHAR(p) ((const char **) (p)) -#define TYPE(p) CCHAR(UINT8(p) + sizeof (size_t)) - -void initAlloc(void) -{ - allocations = g_ptr_array_new(); -} - -static void uninitComplain(gpointer ptr, gpointer data) -{ - char **str = (char **) data; - char *str2; - - if (*str == NULL) - *str = g_strdup_printf(""); - str2 = g_strdup_printf("%s%p %s\n", *str, ptr, *TYPE(ptr)); - g_free(*str); - *str = str2; -} - -void uninitAlloc(void) -{ - char *str = NULL; - - if (allocations->len == 0) { - g_ptr_array_free(allocations, TRUE); - return; - } - g_ptr_array_foreach(allocations, uninitComplain, &str); - userbug("Some data was leaked; either you left a uiControl lying around or there's a bug in libui itself. Leaked data:\n%s", str); - g_free(str); -} - -void *uiAlloc(size_t size, const char *type) -{ - void *out; - - out = g_malloc0(EXTRA + size); - *SIZE(out) = size; - *TYPE(out) = type; - g_ptr_array_add(allocations, out); - return DATA(out); -} - -void *uiRealloc(void *p, size_t new, const char *type) -{ - void *out; - size_t *s; - - if (p == NULL) - return uiAlloc(new, type); - p = BASE(p); - out = g_realloc(p, EXTRA + new); - s = SIZE(out); - if (new <= *s) - memset(((uint8_t *) DATA(out)) + *s, 0, new - *s); - *s = new; - if (g_ptr_array_remove(allocations, p) == FALSE) - implbug("%p not found in allocations array in uiRealloc()", p); - g_ptr_array_add(allocations, out); - return DATA(out); -} - -void uiFree(void *p) -{ - if (p == NULL) - implbug("attempt to uiFree(NULL)"); - p = BASE(p); - g_free(p); - if (g_ptr_array_remove(allocations, p) == FALSE) - implbug("%p not found in allocations array in uiFree()", p); -} diff --git a/deps/libui/unix/area.c b/deps/libui/unix/area.c deleted file mode 100644 index c46447cc33..0000000000 --- a/deps/libui/unix/area.c +++ /dev/null @@ -1,633 +0,0 @@ -// 4 september 2015 -#include "uipriv_unix.h" - -// notes: -// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14) -#define areaWidgetType (areaWidget_get_type()) -#define areaWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), areaWidgetType, areaWidget)) -#define isAreaWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), areaWidgetType)) -#define areaWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), areaWidgetType, areaWidgetClass)) -#define isAreaWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), areaWidget)) -#define getAreaWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), areaWidgetType, areaWidgetClass)) - -typedef struct areaWidget areaWidget; -typedef struct areaWidgetClass areaWidgetClass; - -struct areaWidget { - GtkDrawingArea parent_instance; - uiArea *a; - // construct-only parameters aare not set until after the init() function has returned - // we need this particular object available during init(), so put it here instead of in uiArea - // keep a pointer in uiArea for convenience, though - clickCounter cc; -}; - -struct areaWidgetClass { - GtkDrawingAreaClass parent_class; -}; - -struct uiArea { - uiUnixControl c; - GtkWidget *widget; // either swidget or areaWidget depending on whether it is scrolling - - GtkWidget *swidget; - GtkContainer *scontainer; - GtkScrolledWindow *sw; - - GtkWidget *areaWidget; - GtkDrawingArea *drawingArea; - areaWidget *area; - - uiAreaHandler *ah; - - gboolean scrolling; - int scrollWidth; - int scrollHeight; - - // note that this is a pointer; see above - clickCounter *cc; - - // for user window drags - GdkEventButton *dragevent; -}; - -G_DEFINE_TYPE(areaWidget, areaWidget, GTK_TYPE_DRAWING_AREA) - -static void areaWidget_init(areaWidget *aw) -{ - // for events - gtk_widget_add_events(GTK_WIDGET(aw), - GDK_POINTER_MOTION_MASK | - GDK_BUTTON_MOTION_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_KEY_PRESS_MASK | - GDK_KEY_RELEASE_MASK | - GDK_ENTER_NOTIFY_MASK | - GDK_LEAVE_NOTIFY_MASK); - - gtk_widget_set_can_focus(GTK_WIDGET(aw), TRUE); - - clickCounterReset(&(aw->cc)); -} - -static void areaWidget_dispose(GObject *obj) -{ - G_OBJECT_CLASS(areaWidget_parent_class)->dispose(obj); -} - -static void areaWidget_finalize(GObject *obj) -{ - G_OBJECT_CLASS(areaWidget_parent_class)->finalize(obj); -} - -static void areaWidget_size_allocate(GtkWidget *w, GtkAllocation *allocation) -{ - areaWidget *aw = areaWidget(w); - uiArea *a = aw->a; - - // GtkDrawingArea has a size_allocate() implementation; we need to call it - // this will call gtk_widget_set_allocation() for us - GTK_WIDGET_CLASS(areaWidget_parent_class)->size_allocate(w, allocation); - - if (!a->scrolling) - // we must redraw everything on resize because Windows requires it - gtk_widget_queue_resize(w); -} - -static void loadAreaSize(uiArea *a, double *width, double *height) -{ - GtkAllocation allocation; - - *width = 0; - *height = 0; - // don't provide size information for scrolling areas - if (!a->scrolling) { - gtk_widget_get_allocation(a->areaWidget, &allocation); - // these are already in drawing space coordinates - // for drawing, the size of drawing space has the same value as the widget allocation - // thanks to tristan in irc.gimp.net/#gtk+ - *width = allocation.width; - *height = allocation.height; - } -} - -static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr) -{ - areaWidget *aw = areaWidget(w); - uiArea *a = aw->a; - uiAreaDrawParams dp; - double clipX0, clipY0, clipX1, clipY1; - - dp.Context = newContext(cr); - - loadAreaSize(a, &(dp.AreaWidth), &(dp.AreaHeight)); - - cairo_clip_extents(cr, &clipX0, &clipY0, &clipX1, &clipY1); - dp.ClipX = clipX0; - dp.ClipY = clipY0; - dp.ClipWidth = clipX1 - clipX0; - dp.ClipHeight = clipY1 - clipY0; - - // no need to save or restore the graphics state to reset transformations; GTK+ does that for us - (*(a->ah->Draw))(a->ah, a, &dp); - - freeContext(dp.Context); - return FALSE; -} - -// to do this properly for scrolling areas, we need to -// - return the same value for min and nat -// - call gtk_widget_queue_resize() when the size changes -// thanks to Company in irc.gimp.net/#gtk+ -static void areaWidget_get_preferred_height(GtkWidget *w, gint *min, gint *nat) -{ - areaWidget *aw = areaWidget(w); - uiArea *a = aw->a; - - // always chain up just in case - GTK_WIDGET_CLASS(areaWidget_parent_class)->get_preferred_height(w, min, nat); - if (a->scrolling) { - *min = a->scrollHeight; - *nat = a->scrollHeight; - } -} - -static void areaWidget_get_preferred_width(GtkWidget *w, gint *min, gint *nat) -{ - areaWidget *aw = areaWidget(w); - uiArea *a = aw->a; - - // always chain up just in case - GTK_WIDGET_CLASS(areaWidget_parent_class)->get_preferred_width(w, min, nat); - if (a->scrolling) { - *min = a->scrollWidth; - *nat = a->scrollWidth; - } -} - -static guint translateModifiers(guint state, GdkWindow *window) -{ - GdkModifierType statetype; - - // GDK doesn't initialize the modifier flags fully; we have to explicitly tell it to (thanks to Daniel_S and daniels (two different people) in irc.gimp.net/#gtk+) - statetype = state; - gdk_keymap_add_virtual_modifiers( - gdk_keymap_get_for_display(gdk_window_get_display(window)), - &statetype); - return statetype; -} - -static uiModifiers toModifiers(guint state) -{ - uiModifiers m; - - m = 0; - if ((state & GDK_CONTROL_MASK) != 0) - m |= uiModifierCtrl; - if ((state & GDK_META_MASK) != 0) - m |= uiModifierAlt; - if ((state & GDK_MOD1_MASK) != 0) // GTK+ itself requires this to be Alt (just read through gtkaccelgroup.c) - m |= uiModifierAlt; - if ((state & GDK_SHIFT_MASK) != 0) - m |= uiModifierShift; - if ((state & GDK_SUPER_MASK) != 0) - m |= uiModifierSuper; - return m; -} - -// capture on drag is done automatically on GTK+ -static void finishMouseEvent(uiArea *a, uiAreaMouseEvent *me, guint mb, gdouble x, gdouble y, guint state, GdkWindow *window) -{ - // on GTK+, mouse buttons 4-7 are for scrolling; if we got here, that's a mistake - if (mb >= 4 && mb <= 7) - return; - // if the button ID >= 8, continue counting from 4, as in the MouseEvent spec - if (me->Down >= 8) - me->Down -= 4; - if (me->Up >= 8) - me->Up -= 4; - - state = translateModifiers(state, window); - me->Modifiers = toModifiers(state); - - // the mb != # checks exclude the Up/Down button from Held - me->Held1To64 = 0; - if (mb != 1 && (state & GDK_BUTTON1_MASK) != 0) - me->Held1To64 |= 1 << 0; - if (mb != 2 && (state & GDK_BUTTON2_MASK) != 0) - me->Held1To64 |= 1 << 1; - if (mb != 3 && (state & GDK_BUTTON3_MASK) != 0) - me->Held1To64 |= 1 << 2; - // don't check GDK_BUTTON4_MASK or GDK_BUTTON5_MASK because those are for the scrolling buttons mentioned above - // GDK expressly does not support any more buttons in the GdkModifierType; see https://git.gnome.org/browse/gtk+/tree/gdk/x11/gdkdevice-xi2.c#n763 (thanks mclasen in irc.gimp.net/#gtk+) - - // these are already in drawing space coordinates - // the size of drawing space has the same value as the widget allocation - // thanks to tristan in irc.gimp.net/#gtk+ - me->X = x; - me->Y = y; - - loadAreaSize(a, &(me->AreaWidth), &(me->AreaHeight)); - - (*(a->ah->MouseEvent))(a->ah, a, me); -} - -static gboolean areaWidget_button_press_event(GtkWidget *w, GdkEventButton *e) -{ - areaWidget *aw = areaWidget(w); - uiArea *a = aw->a; - gint maxTime, maxDistance; - GtkSettings *settings; - uiAreaMouseEvent me; - - // clicking doesn't automatically transfer keyboard focus; we must do so manually (thanks tristan in irc.gimp.net/#gtk+) - gtk_widget_grab_focus(w); - - // we handle multiple clicks ourselves here, in the same way as we do on Windows - if (e->type != GDK_BUTTON_PRESS) - // ignore GDK's generated double-clicks and beyond - return GDK_EVENT_PROPAGATE; - settings = gtk_widget_get_settings(w); - g_object_get(settings, - "gtk-double-click-time", &maxTime, - "gtk-double-click-distance", &maxDistance, - NULL); - // don't unref settings; it's transfer-none (thanks gregier in irc.gimp.net/#gtk+) - // e->time is guint32 - // e->x and e->y are floating-point; just make them 32-bit integers - // maxTime and maxDistance... are gint, which *should* fit, hopefully... - me.Count = clickCounterClick(a->cc, me.Down, - e->x, e->y, - e->time, maxTime, - maxDistance, maxDistance); - - me.Down = e->button; - me.Up = 0; - - // and set things up for window drags - a->dragevent = e; - finishMouseEvent(a, &me, e->button, e->x, e->y, e->state, e->window); - a->dragevent = NULL; - return GDK_EVENT_PROPAGATE; -} - -static gboolean areaWidget_button_release_event(GtkWidget *w, GdkEventButton *e) -{ - areaWidget *aw = areaWidget(w); - uiArea *a = aw->a; - uiAreaMouseEvent me; - - me.Down = 0; - me.Up = e->button; - me.Count = 0; - finishMouseEvent(a, &me, e->button, e->x, e->y, e->state, e->window); - return GDK_EVENT_PROPAGATE; -} - -static gboolean areaWidget_motion_notify_event(GtkWidget *w, GdkEventMotion *e) -{ - areaWidget *aw = areaWidget(w); - uiArea *a = aw->a; - uiAreaMouseEvent me; - - me.Down = 0; - me.Up = 0; - me.Count = 0; - finishMouseEvent(a, &me, 0, e->x, e->y, e->state, e->window); - return GDK_EVENT_PROPAGATE; -} - -// we want switching away from the control to reset the double-click counter, like with WM_ACTIVATE on Windows -// according to tristan in irc.gimp.net/#gtk+, doing this on both enter-notify-event and leave-notify-event is correct (and it seems to be true in my own tests; plus the events DO get sent when switching programs with the keyboard (just pointing that out)) -static gboolean onCrossing(areaWidget *aw, int left) -{ - uiArea *a = aw->a; - - (*(a->ah->MouseCrossed))(a->ah, a, left); - clickCounterReset(a->cc); - return GDK_EVENT_PROPAGATE; -} - -static gboolean areaWidget_enter_notify_event(GtkWidget *w, GdkEventCrossing *e) -{ - return onCrossing(areaWidget(w), 0); -} - -static gboolean areaWidget_leave_notify_event(GtkWidget *w, GdkEventCrossing *e) -{ - return onCrossing(areaWidget(w), 1); -} - -// note: there is no equivalent to WM_CAPTURECHANGED on GTK+; there literally is no way to break a grab like that (at least not on X11 and Wayland) -// even if I invoke the task switcher and switch processes, the mouse grab will still be held until I let go of all buttons -// therefore, no DragBroken() - -// we use GDK_KEY_Print as a sentinel because libui will never support the print screen key; that key belongs to the user - -static const struct { - guint keyval; - uiExtKey extkey; -} extKeys[] = { - { GDK_KEY_Escape, uiExtKeyEscape }, - { GDK_KEY_Insert, uiExtKeyInsert }, - { GDK_KEY_Delete, uiExtKeyDelete }, - { GDK_KEY_Home, uiExtKeyHome }, - { GDK_KEY_End, uiExtKeyEnd }, - { GDK_KEY_Page_Up, uiExtKeyPageUp }, - { GDK_KEY_Page_Down, uiExtKeyPageDown }, - { GDK_KEY_Up, uiExtKeyUp }, - { GDK_KEY_Down, uiExtKeyDown }, - { GDK_KEY_Left, uiExtKeyLeft }, - { GDK_KEY_Right, uiExtKeyRight }, - { GDK_KEY_F1, uiExtKeyF1 }, - { GDK_KEY_F2, uiExtKeyF2 }, - { GDK_KEY_F3, uiExtKeyF3 }, - { GDK_KEY_F4, uiExtKeyF4 }, - { GDK_KEY_F5, uiExtKeyF5 }, - { GDK_KEY_F6, uiExtKeyF6 }, - { GDK_KEY_F7, uiExtKeyF7 }, - { GDK_KEY_F8, uiExtKeyF8 }, - { GDK_KEY_F9, uiExtKeyF9 }, - { GDK_KEY_F10, uiExtKeyF10 }, - { GDK_KEY_F11, uiExtKeyF11 }, - { GDK_KEY_F12, uiExtKeyF12 }, - // numpad numeric keys and . are handled in events.c - { GDK_KEY_KP_Enter, uiExtKeyNEnter }, - { GDK_KEY_KP_Add, uiExtKeyNAdd }, - { GDK_KEY_KP_Subtract, uiExtKeyNSubtract }, - { GDK_KEY_KP_Multiply, uiExtKeyNMultiply }, - { GDK_KEY_KP_Divide, uiExtKeyNDivide }, - { GDK_KEY_Print, 0 }, -}; - -static const struct { - guint keyval; - uiModifiers mod; -} modKeys[] = { - { GDK_KEY_Control_L, uiModifierCtrl }, - { GDK_KEY_Control_R, uiModifierCtrl }, - { GDK_KEY_Alt_L, uiModifierAlt }, - { GDK_KEY_Alt_R, uiModifierAlt }, - { GDK_KEY_Meta_L, uiModifierAlt }, - { GDK_KEY_Meta_R, uiModifierAlt }, - { GDK_KEY_Shift_L, uiModifierShift }, - { GDK_KEY_Shift_R, uiModifierShift }, - { GDK_KEY_Super_L, uiModifierSuper }, - { GDK_KEY_Super_R, uiModifierSuper }, - { GDK_KEY_Print, 0 }, -}; - -static int areaKeyEvent(uiArea *a, int up, GdkEventKey *e) -{ - uiAreaKeyEvent ke; - guint state; - int i; - - ke.Key = 0; - ke.ExtKey = 0; - ke.Modifier = 0; - - state = translateModifiers(e->state, e->window); - ke.Modifiers = toModifiers(state); - - ke.Up = up; - - for (i = 0; extKeys[i].keyval != GDK_KEY_Print; i++) - if (extKeys[i].keyval == e->keyval) { - ke.ExtKey = extKeys[i].extkey; - goto keyFound; - } - - for (i = 0; modKeys[i].keyval != GDK_KEY_Print; i++) - if (modKeys[i].keyval == e->keyval) { - ke.Modifier = modKeys[i].mod; - // don't include the modifier in ke.Modifiers - ke.Modifiers &= ~ke.Modifier; - goto keyFound; - } - - if (fromScancode(e->hardware_keycode - 8, &ke)) - goto keyFound; - - // no supported key found; treat as unhandled - return 0; - -keyFound: - return (*(a->ah->KeyEvent))(a->ah, a, &ke); -} - -static gboolean areaWidget_key_press_event(GtkWidget *w, GdkEventKey *e) -{ - areaWidget *aw = areaWidget(w); - uiArea *a = aw->a; - - if (areaKeyEvent(a, 0, e)) - return GDK_EVENT_STOP; - return GDK_EVENT_PROPAGATE; -} - -static gboolean areaWidget_key_release_event(GtkWidget *w, GdkEventKey *e) -{ - areaWidget *aw = areaWidget(w); - uiArea *a = aw->a; - - if (areaKeyEvent(a, 1, e)) - return GDK_EVENT_STOP; - return GDK_EVENT_PROPAGATE; -} - -enum { - pArea = 1, - nProps, -}; - -static GParamSpec *pspecArea; - -static void areaWidget_set_property(GObject *obj, guint prop, const GValue *value, GParamSpec *pspec) -{ - areaWidget *aw = areaWidget(obj); - - switch (prop) { - case pArea: - aw->a = (uiArea *) g_value_get_pointer(value); - aw->a->cc = &(aw->cc); - return; - } - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop, pspec); -} - -static void areaWidget_get_property(GObject *obj, guint prop, GValue *value, GParamSpec *pspec) -{ - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop, pspec); -} - -static void areaWidget_class_init(areaWidgetClass *class) -{ - G_OBJECT_CLASS(class)->dispose = areaWidget_dispose; - G_OBJECT_CLASS(class)->finalize = areaWidget_finalize; - G_OBJECT_CLASS(class)->set_property = areaWidget_set_property; - G_OBJECT_CLASS(class)->get_property = areaWidget_get_property; - - GTK_WIDGET_CLASS(class)->size_allocate = areaWidget_size_allocate; - GTK_WIDGET_CLASS(class)->draw = areaWidget_draw; - GTK_WIDGET_CLASS(class)->get_preferred_height = areaWidget_get_preferred_height; - GTK_WIDGET_CLASS(class)->get_preferred_width = areaWidget_get_preferred_width; - GTK_WIDGET_CLASS(class)->button_press_event = areaWidget_button_press_event; - GTK_WIDGET_CLASS(class)->button_release_event = areaWidget_button_release_event; - GTK_WIDGET_CLASS(class)->motion_notify_event = areaWidget_motion_notify_event; - GTK_WIDGET_CLASS(class)->enter_notify_event = areaWidget_enter_notify_event; - GTK_WIDGET_CLASS(class)->leave_notify_event = areaWidget_leave_notify_event; - GTK_WIDGET_CLASS(class)->key_press_event = areaWidget_key_press_event; - GTK_WIDGET_CLASS(class)->key_release_event = areaWidget_key_release_event; - - pspecArea = g_param_spec_pointer("libui-area", - "libui-area", - "uiArea.", - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - g_object_class_install_property(G_OBJECT_CLASS(class), pArea, pspecArea); -} - -// control implementation - -uiUnixControlAllDefaults(uiArea) - -void uiAreaSetSize(uiArea *a, int width, int height) -{ - if (!a->scrolling) - userbug("You cannot call uiAreaSetSize() on a non-scrolling uiArea. (area: %p)", a); - a->scrollWidth = width; - a->scrollHeight = height; - gtk_widget_queue_resize(a->areaWidget); -} - -void uiAreaQueueRedrawAll(uiArea *a) -{ - gtk_widget_queue_draw(a->areaWidget); -} - -void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height) -{ - // TODO - // TODO adjust adjustments and find source for that -} - -void uiAreaBeginUserWindowMove(uiArea *a) -{ - GtkWidget *toplevel; - - if (a->dragevent == NULL) - userbug("cannot call uiAreaBeginUserWindowMove() outside of a Mouse() with Down != 0"); - // TODO don't we have a libui function for this? did I scrap it? - // TODO widget or areaWidget? - toplevel = gtk_widget_get_toplevel(a->widget); - if (toplevel == NULL) { - // TODO - return; - } - // the docs say to do this - if (!gtk_widget_is_toplevel(toplevel)) { - // TODO - return; - } - if (!GTK_IS_WINDOW(toplevel)) { - // TODO - return; - } - gtk_window_begin_move_drag(GTK_WINDOW(toplevel), - a->dragevent->button, - a->dragevent->x_root, // TODO are these correct? - a->dragevent->y_root, - a->dragevent->time); -} - -static const GdkWindowEdge edges[] = { - [uiWindowResizeEdgeLeft] = GDK_WINDOW_EDGE_WEST, - [uiWindowResizeEdgeTop] = GDK_WINDOW_EDGE_NORTH, - [uiWindowResizeEdgeRight] = GDK_WINDOW_EDGE_EAST, - [uiWindowResizeEdgeBottom] = GDK_WINDOW_EDGE_SOUTH, - [uiWindowResizeEdgeTopLeft] = GDK_WINDOW_EDGE_NORTH_WEST, - [uiWindowResizeEdgeTopRight] = GDK_WINDOW_EDGE_NORTH_EAST, - [uiWindowResizeEdgeBottomLeft] = GDK_WINDOW_EDGE_SOUTH_WEST, - [uiWindowResizeEdgeBottomRight] = GDK_WINDOW_EDGE_SOUTH_EAST, -}; - -void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge) -{ - GtkWidget *toplevel; - - if (a->dragevent == NULL) - userbug("cannot call uiAreaBeginUserWindowResize() outside of a Mouse() with Down != 0"); - // TODO don't we have a libui function for this? did I scrap it? - // TODO widget or areaWidget? - toplevel = gtk_widget_get_toplevel(a->widget); - if (toplevel == NULL) { - // TODO - return; - } - // the docs say to do this - if (!gtk_widget_is_toplevel(toplevel)) { - // TODO - return; - } - if (!GTK_IS_WINDOW(toplevel)) { - // TODO - return; - } - gtk_window_begin_resize_drag(GTK_WINDOW(toplevel), - edges[edge], - a->dragevent->button, - a->dragevent->x_root, // TODO are these correct? - a->dragevent->y_root, - a->dragevent->time); -} - -uiArea *uiNewArea(uiAreaHandler *ah) -{ - uiArea *a; - - uiUnixNewControl(uiArea, a); - - a->ah = ah; - a->scrolling = FALSE; - - a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType, - "libui-area", a, - NULL)); - a->drawingArea = GTK_DRAWING_AREA(a->areaWidget); - a->area = areaWidget(a->areaWidget); - - a->widget = a->areaWidget; - - return a; -} - -uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height) -{ - uiArea *a; - - uiUnixNewControl(uiArea, a); - - a->ah = ah; - a->scrolling = TRUE; - a->scrollWidth = width; - a->scrollHeight = height; - - a->swidget = gtk_scrolled_window_new(NULL, NULL); - a->scontainer = GTK_CONTAINER(a->swidget); - a->sw = GTK_SCROLLED_WINDOW(a->swidget); - - a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType, - "libui-area", a, - NULL)); - a->drawingArea = GTK_DRAWING_AREA(a->areaWidget); - a->area = areaWidget(a->areaWidget); - - a->widget = a->swidget; - - gtk_container_add(a->scontainer, a->areaWidget); - // and make the area visible; only the scrolled window's visibility is controlled by libui - gtk_widget_show(a->areaWidget); - - return a; -} diff --git a/deps/libui/unix/box.c b/deps/libui/unix/box.c deleted file mode 100644 index 23fb7f7c6c..0000000000 --- a/deps/libui/unix/box.c +++ /dev/null @@ -1,159 +0,0 @@ -// 7 april 2015 -#include "uipriv_unix.h" - -struct boxChild { - uiControl *c; - int stretchy; - gboolean oldhexpand; - GtkAlign oldhalign; - gboolean oldvexpand; - GtkAlign oldvalign; -}; - -struct uiBox { - uiUnixControl c; - GtkWidget *widget; - GtkContainer *container; - GtkBox *box; - GArray *controls; - int vertical; - int padded; - GtkSizeGroup *stretchygroup; // ensures all stretchy controls have the same size -}; - -uiUnixControlAllDefaultsExceptDestroy(uiBox) - -#define ctrl(b, i) &g_array_index(b->controls, struct boxChild, i) - -static void uiBoxDestroy(uiControl *c) -{ - uiBox *b = uiBox(c); - struct boxChild *bc; - guint i; - - // kill the size group - g_object_unref(b->stretchygroup); - // free all controls - for (i = 0; i < b->controls->len; i++) { - bc = ctrl(b, i); - uiControlSetParent(bc->c, NULL); - // and make sure the widget itself stays alive - uiUnixControlSetContainer(uiUnixControl(bc->c), b->container, TRUE); - uiControlDestroy(bc->c); - } - g_array_free(b->controls, TRUE); - // and then ourselves - g_object_unref(b->widget); - uiFreeControl(uiControl(b)); -} - -void uiBoxAppend(uiBox *b, uiControl *c, int stretchy) -{ - struct boxChild bc; - GtkWidget *widget; - - bc.c = c; - bc.stretchy = stretchy; - widget = GTK_WIDGET(uiControlHandle(bc.c)); - bc.oldhexpand = gtk_widget_get_hexpand(widget); - bc.oldhalign = gtk_widget_get_halign(widget); - bc.oldvexpand = gtk_widget_get_vexpand(widget); - bc.oldvalign = gtk_widget_get_valign(widget); - - if (bc.stretchy) { - if (b->vertical) { - gtk_widget_set_vexpand(widget, TRUE); - gtk_widget_set_valign(widget, GTK_ALIGN_FILL); - } else { - gtk_widget_set_hexpand(widget, TRUE); - gtk_widget_set_halign(widget, GTK_ALIGN_FILL); - } - gtk_size_group_add_widget(b->stretchygroup, widget); - } else - if (b->vertical) - gtk_widget_set_vexpand(widget, FALSE); - else - gtk_widget_set_hexpand(widget, FALSE); - // and make them fill the opposite direction - if (b->vertical) { - gtk_widget_set_hexpand(widget, TRUE); - gtk_widget_set_halign(widget, GTK_ALIGN_FILL); - } else { - gtk_widget_set_vexpand(widget, TRUE); - gtk_widget_set_valign(widget, GTK_ALIGN_FILL); - } - - uiControlSetParent(bc.c, uiControl(b)); - uiUnixControlSetContainer(uiUnixControl(bc.c), b->container, FALSE); - g_array_append_val(b->controls, bc); -} - -void uiBoxDelete(uiBox *b, int index) -{ - struct boxChild *bc; - GtkWidget *widget; - - bc = ctrl(b, index); - widget = GTK_WIDGET(uiControlHandle(bc->c)); - - uiControlSetParent(bc->c, NULL); - uiUnixControlSetContainer(uiUnixControl(bc->c), b->container, TRUE); - - if (bc->stretchy) - gtk_size_group_remove_widget(b->stretchygroup, widget); - gtk_widget_set_hexpand(widget, bc->oldhexpand); - gtk_widget_set_halign(widget, bc->oldhalign); - gtk_widget_set_vexpand(widget, bc->oldvexpand); - gtk_widget_set_valign(widget, bc->oldvalign); - - g_array_remove_index(b->controls, index); -} - -int uiBoxPadded(uiBox *b) -{ - return b->padded; -} - -void uiBoxSetPadded(uiBox *b, int padded) -{ - b->padded = padded; - if (b->padded) - if (b->vertical) - gtk_box_set_spacing(b->box, gtkYPadding); - else - gtk_box_set_spacing(b->box, gtkXPadding); - else - gtk_box_set_spacing(b->box, 0); -} - -static uiBox *finishNewBox(GtkOrientation orientation) -{ - uiBox *b; - - uiUnixNewControl(uiBox, b); - - b->widget = gtk_box_new(orientation, 0); - b->container = GTK_CONTAINER(b->widget); - b->box = GTK_BOX(b->widget); - - b->vertical = orientation == GTK_ORIENTATION_VERTICAL; - - if (b->vertical) - b->stretchygroup = gtk_size_group_new(GTK_SIZE_GROUP_VERTICAL); - else - b->stretchygroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - - b->controls = g_array_new(FALSE, TRUE, sizeof (struct boxChild)); - - return b; -} - -uiBox *uiNewHorizontalBox(void) -{ - return finishNewBox(GTK_ORIENTATION_HORIZONTAL); -} - -uiBox *uiNewVerticalBox(void) -{ - return finishNewBox(GTK_ORIENTATION_VERTICAL); -} diff --git a/deps/libui/unix/button.c b/deps/libui/unix/button.c deleted file mode 100644 index 00a87f491a..0000000000 --- a/deps/libui/unix/button.c +++ /dev/null @@ -1,55 +0,0 @@ -// 10 june 2015 -#include "uipriv_unix.h" - -struct uiButton { - uiUnixControl c; - GtkWidget *widget; - GtkButton *button; - void (*onClicked)(uiButton *, void *); - void *onClickedData; -}; - -uiUnixControlAllDefaults(uiButton) - -static void onClicked(GtkButton *button, gpointer data) -{ - uiButton *b = uiButton(data); - - (*(b->onClicked))(b, b->onClickedData); -} - -static void defaultOnClicked(uiButton *b, void *data) -{ - // do nothing -} - -char *uiButtonText(uiButton *b) -{ - return uiUnixStrdupText(gtk_button_get_label(b->button)); -} - -void uiButtonSetText(uiButton *b, const char *text) -{ - gtk_button_set_label(b->button, text); -} - -void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *, void *), void *data) -{ - b->onClicked = f; - b->onClickedData = data; -} - -uiButton *uiNewButton(const char *text) -{ - uiButton *b; - - uiUnixNewControl(uiButton, b); - - b->widget = gtk_button_new_with_label(text); - b->button = GTK_BUTTON(b->widget); - - g_signal_connect(b->widget, "clicked", G_CALLBACK(onClicked), b); - uiButtonOnClicked(b, defaultOnClicked, NULL); - - return b; -} diff --git a/deps/libui/unix/cellrendererbutton.c b/deps/libui/unix/cellrendererbutton.c deleted file mode 100644 index e3bbf48b7c..0000000000 --- a/deps/libui/unix/cellrendererbutton.c +++ /dev/null @@ -1,299 +0,0 @@ -// 28 june 2016 -#include "uipriv_unix.h" - -// TODOs -// - it's a rather tight fit -// - selected row text color is white -// - resizing a column with a button in it crashes the program -// - accessibility -// - right side too big? - -#define cellRendererButtonType (cellRendererButton_get_type()) -#define cellRendererButton(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), cellRendererButtonType, cellRendererButton)) -#define isCellRendererButton(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), cellRendererButtonType)) -#define cellRendererButtonClass(class) (G_TYPE_CHECK_CLASS_CAST((class), cellRendererButtonType, cellRendererButtonClass)) -#define isCellRendererButtonClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), cellRendererButton)) -#define getCellRendererButtonClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), cellRendererButtonType, cellRendererButtonClass)) - -typedef struct cellRendererButton cellRendererButton; -typedef struct cellRendererButtonClass cellRendererButtonClass; - -struct cellRendererButton { - GtkCellRenderer parent_instance; - char *text; -}; - -struct cellRendererButtonClass { - GtkCellRendererClass parent_class; -}; - -G_DEFINE_TYPE(cellRendererButton, cellRendererButton, GTK_TYPE_CELL_RENDERER) - -static void cellRendererButton_init(cellRendererButton *c) -{ - g_object_set(c, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL); - // the standard cell renderers all do this - gtk_cell_renderer_set_padding(GTK_CELL_RENDERER(c), 2, 2); -} - -static void cellRendererButton_dispose(GObject *obj) -{ - G_OBJECT_CLASS(cellRendererButton_parent_class)->dispose(obj); -} - -static void cellRendererButton_finalize(GObject *obj) -{ - cellRendererButton *c = cellRendererButton(obj); - - if (c->text != NULL) { - g_free(c->text); - c->text = NULL; - } - G_OBJECT_CLASS(cellRendererButton_parent_class)->finalize(obj); -} - -static GtkSizeRequestMode cellRendererButton_get_request_mode(GtkCellRenderer *r) -{ - return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH; -} - -// this is basically what GtkCellRendererToggle did in 3.10 and does in 3.20, as well as what the Foreign Drawing gtk3-demo demo does -static GtkStyleContext *setButtonStyle(GtkWidget *widget) -{ - GtkStyleContext *base, *context; - GtkWidgetPath *path; - - base = gtk_widget_get_style_context(widget); - context = gtk_style_context_new(); - - path = gtk_widget_path_copy(gtk_style_context_get_path(base)); - gtk_widget_path_append_type(path, G_TYPE_NONE); - if (!FUTURE_gtk_widget_path_iter_set_object_name(path, -1, "button")) - // not on 3.20; try the type - gtk_widget_path_iter_set_object_type(path, -1, GTK_TYPE_BUTTON); - - gtk_style_context_set_path(context, path); - gtk_style_context_set_parent(context, base); - // the gtk3-demo example (which says we need to do this) uses gtk_widget_path_iter_get_state(path, -1) but that's not available until 3.14 - // TODO make a future for that too - gtk_style_context_set_state(context, gtk_style_context_get_state(base)); - gtk_widget_path_unref(path); - - // and if the above widget path screwery stil doesn't work, this will - gtk_style_context_add_class(context, GTK_STYLE_CLASS_BUTTON); - - return context; -} - -void unsetButtonStyle(GtkStyleContext *context) -{ - g_object_unref(context); -} - -// this is based on what GtkCellRendererText does -static void cellRendererButton_get_preferred_width(GtkCellRenderer *r, GtkWidget *widget, gint *minimum, gint *natural) -{ - cellRendererButton *c = cellRendererButton(r); - gint xpad; - PangoLayout *layout; - PangoRectangle rect; - gint out; - - gtk_cell_renderer_get_padding(GTK_CELL_RENDERER(c), &xpad, NULL); - - layout = gtk_widget_create_pango_layout(widget, c->text); - pango_layout_set_width(layout, -1); - pango_layout_get_extents(layout, NULL, &rect); - g_object_unref(layout); - - out = 2 * xpad + PANGO_PIXELS_CEIL(rect.width); - if (minimum != NULL) - *minimum = out; - if (natural != NULL) - *natural = out; -} - -// this is based on what GtkCellRendererText does -static void cellRendererButton_get_preferred_height_for_width(GtkCellRenderer *r, GtkWidget *widget, gint width, gint *minimum, gint *natural) -{ - cellRendererButton *c = cellRendererButton(r); - gint xpad, ypad; - PangoLayout *layout; - gint height; - gint out; - - gtk_cell_renderer_get_padding(GTK_CELL_RENDERER(c), &xpad, &ypad); - - layout = gtk_widget_create_pango_layout(widget, c->text); - pango_layout_set_width(layout, ((2 * xpad + width) * PANGO_SCALE)); - pango_layout_get_pixel_size(layout, NULL, &height); - g_object_unref(layout); - - out = 2 * ypad + height; - if (minimum != NULL) - *minimum = out; - if (natural != NULL) - *natural = out; -} - -// this is basically what GtkCellRendererText does -static void cellRendererButton_get_preferred_height(GtkCellRenderer *r, GtkWidget *widget, gint *minimum, gint *natural) -{ - gint width; - - gtk_cell_renderer_get_preferred_width(r, widget, &width, NULL); - gtk_cell_renderer_get_preferred_height_for_width(r, widget, width, minimum, natural); -} - -// this is based on what GtkCellRendererText does -static void cellRendererButton_get_aligned_area(GtkCellRenderer *r, GtkWidget *widget, GtkCellRendererState flags, const GdkRectangle *cell_area, GdkRectangle *aligned_area) -{ - cellRendererButton *c = cellRendererButton(r); - gint xpad, ypad; - PangoLayout *layout; - PangoRectangle rect; - gfloat xalign, yalign; - gint xoffset, yoffset; - - gtk_cell_renderer_get_padding(GTK_CELL_RENDERER(c), &xpad, &ypad); - - layout = gtk_widget_create_pango_layout(widget, c->text); - pango_layout_set_width(layout, -1); - pango_layout_get_pixel_extents(layout, NULL, &rect); - - xoffset = 0; - yoffset = 0; - if (cell_area != NULL) { - gtk_cell_renderer_get_alignment(GTK_CELL_RENDERER(c), &xalign, &yalign); - xoffset = cell_area->width - (2 * xpad + rect.width); - // use explicit casts just to be safe - if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) - xoffset = ((gdouble) xoffset) * (1.0 - xalign); - else - xoffset *= ((gdouble) xoffset) * xalign; - yoffset = yalign * (cell_area->height - (2 * ypad + rect.height)); - yoffset = MAX(yoffset, 0); - } - - aligned_area->x = cell_area->x + xoffset; - aligned_area->y = cell_area->y + yoffset; - aligned_area->width = 2 * xpad + rect.width; - aligned_area->height = 2 * ypad + rect.height; - - g_object_unref(layout); -} - -// this is based on both what GtkCellRendererText does and what GtkCellRendererToggle does -static void cellRendererButton_render(GtkCellRenderer *r, cairo_t *cr, GtkWidget *widget, const GdkRectangle *background_area, const GdkRectangle *cell_area, GtkCellRendererState flags) -{ - cellRendererButton *c = cellRendererButton(r); - gint xpad, ypad; - GdkRectangle alignedArea; - gint xoffset, yoffset; - GtkStyleContext *context; - PangoLayout *layout; - PangoRectangle rect; - - gtk_cell_renderer_get_padding(GTK_CELL_RENDERER(c), &xpad, &ypad); - gtk_cell_renderer_get_aligned_area(GTK_CELL_RENDERER(c), widget, flags, cell_area, &alignedArea); - xoffset = alignedArea.x - cell_area->x; - yoffset = alignedArea.y - cell_area->y; - - context = setButtonStyle(widget); - layout = gtk_widget_create_pango_layout(widget, c->text); - - gtk_render_background(context, cr, - background_area->x + xoffset + xpad, - background_area->y + yoffset + ypad, - background_area->width - 2 * xpad, - background_area->height - 2 * ypad); - gtk_render_frame(context, cr, - background_area->x + xoffset + xpad, - background_area->y + yoffset + ypad, - background_area->width - 2 * xpad, - background_area->height - 2 * ypad); - - pango_layout_set_width(layout, -1); - pango_layout_get_pixel_extents(layout, NULL, &rect); - xoffset -= rect.x; - gtk_render_layout(context, cr, - cell_area->x + xoffset + xpad, - cell_area->y + yoffset + ypad, - layout); - - g_object_unref(layout); - unsetButtonStyle(context); -} - -static guint clickedSignal; - -static gboolean cellRendererButton_activate(GtkCellRenderer *r, GdkEvent *e, GtkWidget *widget, const gchar *path, const GdkRectangle *background_area, const GdkRectangle *cell_area, GtkCellRendererState flags) -{ - g_signal_emit(r, clickedSignal, 0, path); - return TRUE; -} - -static GParamSpec *props[2] = { NULL, NULL }; - -static void cellRendererButton_set_property(GObject *object, guint prop, const GValue *value, GParamSpec *pspec) -{ - cellRendererButton *c = cellRendererButton(object); - - if (prop != 1) { - G_OBJECT_WARN_INVALID_PROPERTY_ID(c, prop, pspec); - return; - } - if (c->text != NULL) - g_free(c->text); - c->text = g_value_dup_string(value); - // GtkCellRendererText doesn't queue a redraw; we won't either -} - -static void cellRendererButton_get_property(GObject *object, guint prop, GValue *value, GParamSpec *pspec) -{ - cellRendererButton *c = cellRendererButton(object); - - if (prop != 1) { - G_OBJECT_WARN_INVALID_PROPERTY_ID(c, prop, pspec); - return; - } - g_value_set_string(value, c->text); -} - -static void cellRendererButton_class_init(cellRendererButtonClass *class) -{ - G_OBJECT_CLASS(class)->dispose = cellRendererButton_dispose; - G_OBJECT_CLASS(class)->finalize = cellRendererButton_finalize; - G_OBJECT_CLASS(class)->set_property = cellRendererButton_set_property; - G_OBJECT_CLASS(class)->get_property = cellRendererButton_get_property; - GTK_CELL_RENDERER_CLASS(class)->get_request_mode = cellRendererButton_get_request_mode; - GTK_CELL_RENDERER_CLASS(class)->get_preferred_width = cellRendererButton_get_preferred_width; - GTK_CELL_RENDERER_CLASS(class)->get_preferred_height_for_width = cellRendererButton_get_preferred_height_for_width; - GTK_CELL_RENDERER_CLASS(class)->get_preferred_height = cellRendererButton_get_preferred_height; - // don't provide a get_preferred_width_for_height() - GTK_CELL_RENDERER_CLASS(class)->get_aligned_area = cellRendererButton_get_aligned_area; - // don't provide a get_size() - GTK_CELL_RENDERER_CLASS(class)->render = cellRendererButton_render; - GTK_CELL_RENDERER_CLASS(class)->activate = cellRendererButton_activate; - // don't provide a start_editing() - - props[1] = g_param_spec_string("text", - "Text", - "Button text", - "", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties(G_OBJECT_CLASS(class), 2, props); - - clickedSignal = g_signal_new("clicked", - G_TYPE_FROM_CLASS(class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, - 1, G_TYPE_STRING); -} - -GtkCellRenderer *newCellRendererButton(void) -{ - return GTK_CELL_RENDERER(g_object_new(cellRendererButtonType, NULL)); -} diff --git a/deps/libui/unix/checkbox.c b/deps/libui/unix/checkbox.c deleted file mode 100644 index 47f851456a..0000000000 --- a/deps/libui/unix/checkbox.c +++ /dev/null @@ -1,78 +0,0 @@ -// 10 june 2015 -#include "uipriv_unix.h" - -struct uiCheckbox { - uiUnixControl c; - GtkWidget *widget; - GtkButton *button; - GtkToggleButton *toggleButton; - GtkCheckButton *checkButton; - void (*onToggled)(uiCheckbox *, void *); - void *onToggledData; - gulong onToggledSignal; -}; - -uiUnixControlAllDefaults(uiCheckbox) - -static void onToggled(GtkToggleButton *b, gpointer data) -{ - uiCheckbox *c = uiCheckbox(data); - - (*(c->onToggled))(c, c->onToggledData); -} - -static void defaultOnToggled(uiCheckbox *c, void *data) -{ - // do nothing -} - -char *uiCheckboxText(uiCheckbox *c) -{ - return uiUnixStrdupText(gtk_button_get_label(c->button)); -} - -void uiCheckboxSetText(uiCheckbox *c, const char *text) -{ - gtk_button_set_label(GTK_BUTTON(c->button), text); -} - -void uiCheckboxOnToggled(uiCheckbox *c, void (*f)(uiCheckbox *, void *), void *data) -{ - c->onToggled = f; - c->onToggledData = data; -} - -int uiCheckboxChecked(uiCheckbox *c) -{ - return gtk_toggle_button_get_active(c->toggleButton) != FALSE; -} - -void uiCheckboxSetChecked(uiCheckbox *c, int checked) -{ - gboolean active; - - active = FALSE; - if (checked) - active = TRUE; - // we need to inhibit sending of ::toggled because this WILL send a ::toggled otherwise - g_signal_handler_block(c->toggleButton, c->onToggledSignal); - gtk_toggle_button_set_active(c->toggleButton, active); - g_signal_handler_unblock(c->toggleButton, c->onToggledSignal); -} - -uiCheckbox *uiNewCheckbox(const char *text) -{ - uiCheckbox *c; - - uiUnixNewControl(uiCheckbox, c); - - c->widget = gtk_check_button_new_with_label(text); - c->button = GTK_BUTTON(c->widget); - c->toggleButton = GTK_TOGGLE_BUTTON(c->widget); - c->checkButton = GTK_CHECK_BUTTON(c->widget); - - c->onToggledSignal = g_signal_connect(c->widget, "toggled", G_CALLBACK(onToggled), c); - uiCheckboxOnToggled(c, defaultOnToggled, NULL); - - return c; -} diff --git a/deps/libui/unix/child.c b/deps/libui/unix/child.c deleted file mode 100644 index b4a0967740..0000000000 --- a/deps/libui/unix/child.c +++ /dev/null @@ -1,120 +0,0 @@ -// 28 august 2015 -#include "uipriv_unix.h" - -// This file contains helpers for managing child controls. - -struct child { - uiControl *c; - GtkWidget *widget; - - gboolean oldhexpand; - GtkAlign oldhalign; - gboolean oldvexpand; - GtkAlign oldvalign; - - // Some children can be boxed; that is, they can have an optionally-margined box around them. - // uiGroup, uiTab, and uiWindow all do this. - GtkWidget *box; - - // If the child is not boxed, this is its parent. - // If the child is boxed, this is the box. - GtkContainer *parent; - - // This flag is for users of these functions. - // For uiBox, this is "spaced". - // For uiTab, this is "margined". (uiGroup and uiWindow have to maintain their margined state themselves, since the margined state is independent of whether there is a child for those two.) - int flag; -}; - -struct child *newChild(uiControl *child, uiControl *parent, GtkContainer *parentContainer) -{ - struct child *c; - - if (child == NULL) - return NULL; - - c = uiNew(struct child); - c->c = child; - c->widget = GTK_WIDGET(uiControlHandle(c->c)); - - c->oldhexpand = gtk_widget_get_hexpand(c->widget); - c->oldhalign = gtk_widget_get_halign(c->widget); - c->oldvexpand = gtk_widget_get_vexpand(c->widget); - c->oldvalign = gtk_widget_get_valign(c->widget); - - uiControlSetParent(c->c, parent); - uiUnixControlSetContainer(uiUnixControl(c->c), parentContainer, FALSE); - c->parent = parentContainer; - - return c; -} - -struct child *newChildWithBox(uiControl *child, uiControl *parent, GtkContainer *parentContainer, int margined) -{ - struct child *c; - GtkWidget *box; - - if (child == NULL) - return NULL; - box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_widget_show(box); - c = newChild(child, parent, GTK_CONTAINER(box)); - gtk_widget_set_hexpand(c->widget, TRUE); - gtk_widget_set_halign(c->widget, GTK_ALIGN_FILL); - gtk_widget_set_vexpand(c->widget, TRUE); - gtk_widget_set_valign(c->widget, GTK_ALIGN_FILL); - c->box = box; - gtk_container_add(parentContainer, c->box); - childSetMargined(c, margined); - return c; -} - -void childRemove(struct child *c) -{ - uiControlSetParent(c->c, NULL); - uiUnixControlSetContainer(uiUnixControl(c->c), c->parent, TRUE); - - gtk_widget_set_hexpand(c->widget, c->oldhexpand); - gtk_widget_set_halign(c->widget, c->oldhalign); - gtk_widget_set_vexpand(c->widget, c->oldvexpand); - gtk_widget_set_valign(c->widget, c->oldvalign); - - if (c->box != NULL) - gtk_widget_destroy(c->box); - - uiFree(c); -} - -void childDestroy(struct child *c) -{ - uiControl *child; - - child = c->c; - childRemove(c); - uiControlDestroy(child); -} - -GtkWidget *childWidget(struct child *c) -{ - return c->widget; -} - -int childFlag(struct child *c) -{ - return c->flag; -} - -void childSetFlag(struct child *c, int flag) -{ - c->flag = flag; -} - -GtkWidget *childBox(struct child *c) -{ - return c->box; -} - -void childSetMargined(struct child *c, int margined) -{ - setMargined(GTK_CONTAINER(c->box), margined); -} diff --git a/deps/libui/unix/colorbutton.c b/deps/libui/unix/colorbutton.c deleted file mode 100644 index 393b16f1d3..0000000000 --- a/deps/libui/unix/colorbutton.c +++ /dev/null @@ -1,80 +0,0 @@ -// 15 may 2016 -#include "uipriv_unix.h" - -struct uiColorButton { - uiUnixControl c; - GtkWidget *widget; - GtkButton *button; - GtkColorButton *cb; - GtkColorChooser *cc; - void (*onChanged)(uiColorButton *, void *); - void *onChangedData; -}; - -uiUnixControlAllDefaults(uiColorButton) - -static void onColorSet(GtkColorButton *button, gpointer data) -{ - uiColorButton *b = uiColorButton(data); - - (*(b->onChanged))(b, b->onChangedData); -} - -static void defaultOnChanged(uiColorButton *b, void *data) -{ - // do nothing -} - -void uiColorButtonColor(uiColorButton *b, double *r, double *g, double *bl, double *a) -{ - GdkRGBA rgba; - - gtk_color_chooser_get_rgba(b->cc, &rgba); - *r = rgba.red; - *g = rgba.green; - *bl = rgba.blue; - *a = rgba.alpha; -} - -void uiColorButtonSetColor(uiColorButton *b, double r, double g, double bl, double a) -{ - GdkRGBA rgba; - - rgba.red = r; - rgba.green = g; - rgba.blue = bl; - rgba.alpha = a; - // no need to inhibit the signal; color-set is documented as only being sent when the user changes the color - gtk_color_chooser_set_rgba(b->cc, &rgba); -} - -void uiColorButtonOnChanged(uiColorButton *b, void (*f)(uiColorButton *, void *), void *data) -{ - b->onChanged = f; - b->onChangedData = data; -} - -uiColorButton *uiNewColorButton(void) -{ - uiColorButton *b; - GdkRGBA black; - - uiUnixNewControl(uiColorButton, b); - - // I'm not sure what the initial color is; set up a real one - black.red = 0.0; - black.green = 0.0; - black.blue = 0.0; - black.alpha = 1.0; - b->widget = gtk_color_button_new_with_rgba(&black); - b->button = GTK_BUTTON(b->widget); - b->cb = GTK_COLOR_BUTTON(b->widget); - b->cc = GTK_COLOR_CHOOSER(b->widget); - - gtk_color_chooser_set_use_alpha(b->cc, TRUE); - - g_signal_connect(b->widget, "color-set", G_CALLBACK(onColorSet), b); - uiColorButtonOnChanged(b, defaultOnChanged, NULL); - - return b; -} diff --git a/deps/libui/unix/combobox.c b/deps/libui/unix/combobox.c deleted file mode 100644 index 6fed804bb1..0000000000 --- a/deps/libui/unix/combobox.c +++ /dev/null @@ -1,66 +0,0 @@ -// 11 june 2015 -#include "uipriv_unix.h" - -struct uiCombobox { - uiUnixControl c; - GtkWidget *widget; - GtkComboBox *combobox; - GtkComboBoxText *comboboxText; - void (*onSelected)(uiCombobox *, void *); - void *onSelectedData; - gulong onSelectedSignal; -}; - -uiUnixControlAllDefaults(uiCombobox) - -static void onChanged(GtkComboBox *cbox, gpointer data) -{ - uiCombobox *c = uiCombobox(data); - - (*(c->onSelected))(c, c->onSelectedData); -} - -static void defaultOnSelected(uiCombobox *c, void *data) -{ - // do nothing -} - -void uiComboboxAppend(uiCombobox *c, const char *text) -{ - gtk_combo_box_text_append(c->comboboxText, NULL, text); -} - -int uiComboboxSelected(uiCombobox *c) -{ - return gtk_combo_box_get_active(c->combobox); -} - -void uiComboboxSetSelected(uiCombobox *c, int n) -{ - // we need to inhibit sending of ::changed because this WILL send a ::changed otherwise - g_signal_handler_block(c->combobox, c->onSelectedSignal); - gtk_combo_box_set_active(c->combobox, n); - g_signal_handler_unblock(c->combobox, c->onSelectedSignal); -} - -void uiComboboxOnSelected(uiCombobox *c, void (*f)(uiCombobox *c, void *data), void *data) -{ - c->onSelected = f; - c->onSelectedData = data; -} - -uiCombobox *uiNewCombobox(void) -{ - uiCombobox *c; - - uiUnixNewControl(uiCombobox, c); - - c->widget = gtk_combo_box_text_new(); - c->combobox = GTK_COMBO_BOX(c->widget); - c->comboboxText = GTK_COMBO_BOX_TEXT(c->widget); - - c->onSelectedSignal = g_signal_connect(c->widget, "changed", G_CALLBACK(onChanged), c); - uiComboboxOnSelected(c, defaultOnSelected, NULL); - - return c; -} diff --git a/deps/libui/unix/control.c b/deps/libui/unix/control.c deleted file mode 100644 index f6fdcea2a3..0000000000 --- a/deps/libui/unix/control.c +++ /dev/null @@ -1,14 +0,0 @@ -// 16 august 2015 -#include "uipriv_unix.h" - -void uiUnixControlSetContainer(uiUnixControl *c, GtkContainer *container, gboolean remove) -{ - (*(c->SetContainer))(c, container, remove); -} - -#define uiUnixControlSignature 0x556E6978 - -uiUnixControl *uiUnixAllocControl(size_t n, uint32_t typesig, const char *typenamestr) -{ - return uiUnixControl(uiAllocControl(n, uiUnixControlSignature, typesig, typenamestr)); -} diff --git a/deps/libui/unix/datetimepicker.c b/deps/libui/unix/datetimepicker.c deleted file mode 100644 index 19689a2205..0000000000 --- a/deps/libui/unix/datetimepicker.c +++ /dev/null @@ -1,599 +0,0 @@ -// 4 september 2015 -#include "uipriv_unix.h" - -// LONGTERM imitate gnome-calendar's day/month/year entries above the calendar -// LONGTERM allow entering a 24-hour hour in the hour spinbutton and adjust accordingly - -#define dateTimePickerWidgetType (dateTimePickerWidget_get_type()) -#define dateTimePickerWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), dateTimePickerWidgetType, dateTimePickerWidget)) -#define isDateTimePickerWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), dateTimePickerWidgetType)) -#define dateTimePickerWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), dateTimePickerWidgetType, dateTimePickerWidgetClass)) -#define isDateTimePickerWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), dateTimePickerWidget)) -#define getDateTimePickerWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), dateTimePickerWidgetType, dateTimePickerWidgetClass)) - -typedef struct dateTimePickerWidget dateTimePickerWidget; -typedef struct dateTimePickerWidgetClass dateTimePickerWidgetClass; - -struct dateTimePickerWidget { - GtkToggleButton parent_instance; - - gulong toggledSignal; - - gboolean hasTime; - gboolean hasDate; - - GtkWidget *window; - GtkWidget *box; - GtkWidget *calendar; - GtkWidget *timebox; - GtkWidget *hours; - GtkWidget *minutes; - GtkWidget *seconds; - GtkWidget *ampm; - - gulong hoursBlock; - gulong minutesBlock; - gulong secondsBlock; - gulong ampmBlock; - - GdkDevice *keyboard; - GdkDevice *mouse; -}; - -struct dateTimePickerWidgetClass { - GtkToggleButtonClass parent_class; -}; - -G_DEFINE_TYPE(dateTimePickerWidget, dateTimePickerWidget, GTK_TYPE_TOGGLE_BUTTON) - -static int realSpinValue(GtkSpinButton *spinButton) -{ - GtkAdjustment *adj; - - adj = gtk_spin_button_get_adjustment(spinButton); - return (int) gtk_adjustment_get_value(adj); -} - -static void setRealSpinValue(GtkSpinButton *spinButton, int value, gulong block) -{ - GtkAdjustment *adj; - - g_signal_handler_block(spinButton, block); - adj = gtk_spin_button_get_adjustment(spinButton); - gtk_adjustment_set_value(adj, value); - g_signal_handler_unblock(spinButton, block); -} - -static GDateTime *selected(dateTimePickerWidget *d) -{ - // choose a day for which all times are likely to be valid for the default date in case we're only dealing with time - guint year = 1970, month = 1, day = 1; - guint hour = 0, minute = 0, second = 0; - - if (d->hasDate) { - gtk_calendar_get_date(GTK_CALENDAR(d->calendar), &year, &month, &day); - month++; // GtkCalendar/GDateTime differences - } - if (d->hasTime) { - hour = realSpinValue(GTK_SPIN_BUTTON(d->hours)); - if (realSpinValue(GTK_SPIN_BUTTON(d->ampm)) != 0) - hour += 12; - minute = realSpinValue(GTK_SPIN_BUTTON(d->minutes)); - second = realSpinValue(GTK_SPIN_BUTTON(d->seconds)); - } - return g_date_time_new_local(year, month, day, hour, minute, second); -} - -static void setLabel(dateTimePickerWidget *d) -{ - GDateTime *dt; - char *fmt; - char *msg; - gboolean free; - - dt = selected(d); - free = FALSE; - if (d->hasDate && d->hasTime) { - // don't use D_T_FMT; that's too verbose - fmt = g_strdup_printf("%s %s", nl_langinfo(D_FMT), nl_langinfo(T_FMT)); - free = TRUE; - } else if (d->hasDate) - fmt = nl_langinfo(D_FMT); - else - fmt = nl_langinfo(T_FMT); - msg = g_date_time_format(dt, fmt); - gtk_button_set_label(GTK_BUTTON(d), msg); - g_free(msg); - if (free) - g_free(fmt); - g_date_time_unref(dt); -} - -static void dateTimeChanged(dateTimePickerWidget *d) -{ - setLabel(d); - // TODO fire event here -} - -// we don't want ::toggled to be sent again -static void setActive(dateTimePickerWidget *d, gboolean active) -{ - g_signal_handler_block(d, d->toggledSignal); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(d), active); - g_signal_handler_unblock(d, d->toggledSignal); -} - -// like startGrab() below, a lot of this is in the order that GtkComboBox does it -static void endGrab(dateTimePickerWidget *d) -{ - if (d->keyboard != NULL) - gdk_device_ungrab(d->keyboard, GDK_CURRENT_TIME); - gdk_device_ungrab(d->mouse, GDK_CURRENT_TIME); - gtk_device_grab_remove(d->window, d->mouse); - d->keyboard = NULL; - d->mouse = NULL; -} - -static void hidePopup(dateTimePickerWidget *d) -{ - endGrab(d); - gtk_widget_hide(d->window); - setActive(d, FALSE); -} - -// this consolidates a good chunk of what GtkComboBox does -static gboolean startGrab(dateTimePickerWidget *d) -{ - GdkDevice *dev; - guint32 time; - GdkWindow *window; - GdkDevice *keyboard, *mouse; - - dev = gtk_get_current_event_device(); - if (dev == NULL) { - // this is what GtkComboBox does - // since no device was set, just use the first available "master device" - GdkDisplay *disp; - GdkDeviceManager *dm; - GList *list; - - disp = gtk_widget_get_display(GTK_WIDGET(d)); - dm = gdk_display_get_device_manager(disp); - list = gdk_device_manager_list_devices(dm, GDK_DEVICE_TYPE_MASTER); - dev = (GdkDevice *) (list->data); - g_list_free(list); - } - - time = gtk_get_current_event_time(); - keyboard = dev; - mouse = gdk_device_get_associated_device(dev); - if (gdk_device_get_source(dev) != GDK_SOURCE_KEYBOARD) { - dev = mouse; - mouse = keyboard; - keyboard = dev; - } - - window = gtk_widget_get_window(d->window); - if (keyboard != NULL) - if (gdk_device_grab(keyboard, window, - GDK_OWNERSHIP_WINDOW, TRUE, - GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK, - NULL, time) != GDK_GRAB_SUCCESS) - return FALSE; - if (mouse != NULL) - if (gdk_device_grab(mouse, window, - GDK_OWNERSHIP_WINDOW, TRUE, - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, - NULL, time) != GDK_GRAB_SUCCESS) { - if (keyboard != NULL) - gdk_device_ungrab(keyboard, time); - return FALSE; - } - - gtk_device_grab_add(d->window, mouse, TRUE); - d->keyboard = keyboard; - d->mouse = mouse; - return TRUE; -} - -// based on gtk_combo_box_list_position() in the GTK+ source code -static void allocationToScreen(dateTimePickerWidget *d, gint *x, gint *y) -{ - GdkWindow *window; - GtkAllocation a; - GtkRequisition aWin; - GdkScreen *screen; - GdkRectangle workarea; - int otherY; - - gtk_widget_get_allocation(GTK_WIDGET(d), &a); - gtk_widget_get_preferred_size(d->window, &aWin, NULL); - *x = 0; - *y = 0; - if (!gtk_widget_get_has_window(GTK_WIDGET(d))) { - *x = a.x; - *y = a.y; - } - window = gtk_widget_get_window(GTK_WIDGET(d)); - gdk_window_get_root_coords(window, *x, *y, x, y); - if (gtk_widget_get_direction(GTK_WIDGET(d)) == GTK_TEXT_DIR_RTL) - *x += a.width - aWin.width; - - // now adjust to prevent the box from going offscreen - screen = gtk_widget_get_screen(GTK_WIDGET(d)); - gdk_screen_get_monitor_workarea(screen, - gdk_screen_get_monitor_at_window(screen, window), - &workarea); - if (*x < workarea.x) // too far to the left? - *x = workarea.x; - else if (*x + aWin.width > (workarea.x + workarea.width)) // too far to the right? - *x = (workarea.x + workarea.width) - aWin.width; - // this isn't the same algorithm used by GtkComboBox - // first, get our two choices; *y for down and otherY for up - otherY = *y - aWin.height; - *y += a.height; - // and use otherY if we're too low - if (*y + aWin.height >= workarea.y + workarea.height) - *y = otherY; -} - -static void showPopup(dateTimePickerWidget *d) -{ - GtkWidget *toplevel; - gint x, y; - - // GtkComboBox does it - toplevel = gtk_widget_get_toplevel(GTK_WIDGET(d)); - if (GTK_IS_WINDOW(toplevel)) - gtk_window_group_add_window(gtk_window_get_group(GTK_WINDOW(toplevel)), GTK_WINDOW(d->window)); - - allocationToScreen(d, &x, &y); - gtk_window_move(GTK_WINDOW(d->window), x, y); - - gtk_widget_show(d->window); - setActive(d, TRUE); - - if (!startGrab(d)) - hidePopup(d); -} - -static void onToggled(GtkToggleButton *b, gpointer data) -{ - dateTimePickerWidget *d = dateTimePickerWidget(b); - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(d))) - showPopup(d); - else - hidePopup(d); -} - -static gboolean grabBroken(GtkWidget *w, GdkEventGrabBroken *e, gpointer data) -{ - dateTimePickerWidget *d = dateTimePickerWidget(data); - - hidePopup(d); - return TRUE; // this is what GtkComboBox does -} - -static gboolean buttonReleased(GtkWidget *w, GdkEventButton *e, gpointer data) -{ - dateTimePickerWidget *d = dateTimePickerWidget(data); - int winx, winy; - GtkAllocation wina; - gboolean in; - - gtk_widget_get_allocation(d->window, &wina); - winx = 0; - winy = 0; - if (!gtk_widget_get_has_window(d->window)) { - winx = wina.x; - winy = wina.y; - } - gdk_window_get_root_coords(gtk_widget_get_window(d->window), winx, winy, &winx, &winy); - in = TRUE; - if (e->x_root < winx) - in = FALSE; - if (e->x_root >= (winx + wina.width)) - in = FALSE; - if (e->y_root < winy) - in = FALSE; - if (e->y_root >= (winy + wina.height)) - in = FALSE; - if (!in) - hidePopup(d); - return TRUE; // this is what GtkComboBox does -} - -static gint hoursSpinboxInput(GtkSpinButton *sb, gpointer ptr, gpointer data) -{ - double *out = (double *) ptr; - const gchar *text; - int value; - - text = gtk_entry_get_text(GTK_ENTRY(sb)); - value = (int) g_strtod(text, NULL); - if (value < 0 || value > 12) - return GTK_INPUT_ERROR; - if (value == 12) // 12 to the user is 0 internally - value = 0; - *out = (double) value; - return TRUE; -} - -static gboolean hoursSpinboxOutput(GtkSpinButton *sb, gpointer data) -{ - gchar *text; - int value; - - value = realSpinValue(sb); - if (value == 0) // 0 internally is 12 to the user - value = 12; - text = g_strdup_printf("%d", value); - gtk_entry_set_text(GTK_ENTRY(sb), text); - g_free(text); - return TRUE; -} - -static gboolean zeroPadSpinbox(GtkSpinButton *sb, gpointer data) -{ - gchar *text; - int value; - - value = realSpinValue(sb); - text = g_strdup_printf("%02d", value); - gtk_entry_set_text(GTK_ENTRY(sb), text); - g_free(text); - return TRUE; -} - -// this is really hacky but we can't use GtkCombobox here :( -static gint ampmSpinboxInput(GtkSpinButton *sb, gpointer ptr, gpointer data) -{ - double *out = (double *) ptr; - const gchar *text; - char firstAM, firstPM; - - text = gtk_entry_get_text(GTK_ENTRY(sb)); - // LONGTERM don't use ASCII here for case insensitivity - firstAM = g_ascii_tolower(nl_langinfo(AM_STR)[0]); - firstPM = g_ascii_tolower(nl_langinfo(PM_STR)[0]); - for (; *text != '\0'; text++) - if (g_ascii_tolower(*text) == firstAM) { - *out = 0; - return TRUE; - } else if (g_ascii_tolower(*text) == firstPM) { - *out = 1; - return TRUE; - } - return GTK_INPUT_ERROR; -} - -static gboolean ampmSpinboxOutput(GtkSpinButton *sb, gpointer data) -{ - int value; - - value = gtk_spin_button_get_value_as_int(sb); - if (value == 0) - gtk_entry_set_text(GTK_ENTRY(sb), nl_langinfo(AM_STR)); - else - gtk_entry_set_text(GTK_ENTRY(sb), nl_langinfo(PM_STR)); - return TRUE; -} - -static void spinboxChanged(GtkSpinButton *sb, gpointer data) -{ - dateTimePickerWidget *d = dateTimePickerWidget(data); - - dateTimeChanged(d); -} - -static GtkWidget *newSpinbox(dateTimePickerWidget *d, int min, int max, gint (*input)(GtkSpinButton *, gpointer, gpointer), gboolean (*output)(GtkSpinButton *, gpointer), gulong *block) -{ - GtkWidget *sb; - - sb = gtk_spin_button_new_with_range(min, max, 1); - gtk_spin_button_set_digits(GTK_SPIN_BUTTON(sb), 0); - gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(sb), TRUE); - gtk_orientable_set_orientation(GTK_ORIENTABLE(sb), GTK_ORIENTATION_VERTICAL); - *block = g_signal_connect(sb, "value-changed", G_CALLBACK(spinboxChanged), d); - if (input != NULL) - g_signal_connect(sb, "input", G_CALLBACK(input), NULL); - if (output != NULL) - g_signal_connect(sb, "output", G_CALLBACK(output), NULL); - return sb; -} - -static void dateChanged(GtkCalendar *c, gpointer data) -{ - dateTimePickerWidget *d = dateTimePickerWidget(data); - - dateTimeChanged(d); -} - -static void setDateOnly(dateTimePickerWidget *d) -{ - d->hasTime = FALSE; - gtk_container_remove(GTK_CONTAINER(d->box), d->timebox); -} - -static void setTimeOnly(dateTimePickerWidget *d) -{ - d->hasDate = FALSE; - gtk_container_remove(GTK_CONTAINER(d->box), d->calendar); -} - -static void dateTimePickerWidget_init(dateTimePickerWidget *d) -{ - GDateTime *dt; - gint year, month, day; - gint hour; - gulong calendarBlock; - - d->window = gtk_window_new(GTK_WINDOW_POPUP); - gtk_window_set_resizable(GTK_WINDOW(d->window), FALSE); - gtk_window_set_attached_to(GTK_WINDOW(d->window), GTK_WIDGET(d)); - gtk_window_set_decorated(GTK_WINDOW(d->window), FALSE); - gtk_window_set_deletable(GTK_WINDOW(d->window), FALSE); - gtk_window_set_type_hint(GTK_WINDOW(d->window), GDK_WINDOW_TYPE_HINT_COMBO); - gtk_window_set_skip_taskbar_hint(GTK_WINDOW(d->window), TRUE); - gtk_window_set_skip_pager_hint(GTK_WINDOW(d->window), TRUE); - gtk_window_set_has_resize_grip(GTK_WINDOW(d->window), FALSE); - gtk_container_set_border_width(GTK_CONTAINER(d->window), 12); - // and make it stand out a bit - gtk_style_context_add_class(gtk_widget_get_style_context(d->window), "frame"); - - d->box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); - gtk_container_add(GTK_CONTAINER(d->window), d->box); - - d->calendar = gtk_calendar_new(); - calendarBlock = g_signal_connect(d->calendar, "day-selected", G_CALLBACK(dateChanged), d); - gtk_container_add(GTK_CONTAINER(d->box), d->calendar); - - d->timebox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); - gtk_widget_set_valign(d->timebox, GTK_ALIGN_CENTER); - gtk_container_add(GTK_CONTAINER(d->box), d->timebox); - - d->hours = newSpinbox(d, 0, 11, hoursSpinboxInput, hoursSpinboxOutput, &(d->hoursBlock)); - gtk_container_add(GTK_CONTAINER(d->timebox), d->hours); - - gtk_container_add(GTK_CONTAINER(d->timebox), - gtk_label_new(":")); - - d->minutes = newSpinbox(d, 0, 59, NULL, zeroPadSpinbox, &(d->minutesBlock)); - gtk_container_add(GTK_CONTAINER(d->timebox), d->minutes); - - gtk_container_add(GTK_CONTAINER(d->timebox), - gtk_label_new(":")); - - d->seconds = newSpinbox(d, 0, 59, NULL, zeroPadSpinbox, &(d->secondsBlock)); - gtk_container_add(GTK_CONTAINER(d->timebox), d->seconds); - - // LONGTERM this should be the case, but that interferes with grabs - // switch to it when we can drop GTK+ 3.10 and use popovers -#if 0 - d->ampm = gtk_combo_box_text_new(); - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(d->ampm), NULL, "AM"); - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(d->ampm), NULL, "PM"); -#endif - d->ampm = newSpinbox(d, 0, 1, ampmSpinboxInput, ampmSpinboxOutput, &(d->ampmBlock)); - gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(d->ampm), FALSE); - gtk_widget_set_valign(d->ampm, GTK_ALIGN_CENTER); - gtk_container_add(GTK_CONTAINER(d->timebox), d->ampm); - - gtk_widget_show_all(d->box); - - g_signal_connect(d->window, "grab-broken-event", G_CALLBACK(grabBroken), d); - g_signal_connect(d->window, "button-release-event", G_CALLBACK(buttonReleased), d); - - d->toggledSignal = g_signal_connect(d, "toggled", G_CALLBACK(onToggled), NULL); - d->keyboard = NULL; - d->mouse = NULL; - - d->hasTime = TRUE; - d->hasDate = TRUE; - - // set the current date/time - // notice how we block signals from firing - dt = g_date_time_new_now_local(); - g_date_time_get_ymd(dt, &year, &month, &day); - month--; // GDateTime/GtkCalendar differences - g_signal_handler_block(d->calendar, calendarBlock); - gtk_calendar_select_month(GTK_CALENDAR(d->calendar), month, year); - gtk_calendar_select_day(GTK_CALENDAR(d->calendar), day); - g_signal_handler_unblock(d->calendar, calendarBlock); - hour = g_date_time_get_hour(dt); - if (hour >= 12) { - hour -= 12; - setRealSpinValue(GTK_SPIN_BUTTON(d->ampm), 1, d->ampmBlock); - } - setRealSpinValue(GTK_SPIN_BUTTON(d->hours), hour, d->hoursBlock); - setRealSpinValue(GTK_SPIN_BUTTON(d->minutes), g_date_time_get_minute(dt), d->minutesBlock); - setRealSpinValue(GTK_SPIN_BUTTON(d->seconds), g_date_time_get_seconds(dt), d->secondsBlock); - g_date_time_unref(dt); -} - -static void dateTimePickerWidget_dispose(GObject *obj) -{ - dateTimePickerWidget *d = dateTimePickerWidget(obj); - - if (d->window != NULL) { - gtk_widget_destroy(d->window); - d->window = NULL; - } - G_OBJECT_CLASS(dateTimePickerWidget_parent_class)->dispose(obj); -} - -static void dateTimePickerWidget_finalize(GObject *obj) -{ - G_OBJECT_CLASS(dateTimePickerWidget_parent_class)->finalize(obj); -} - -static void dateTimePickerWidget_class_init(dateTimePickerWidgetClass *class) -{ - G_OBJECT_CLASS(class)->dispose = dateTimePickerWidget_dispose; - G_OBJECT_CLASS(class)->finalize = dateTimePickerWidget_finalize; -} - -static GtkWidget *newDTP(void) -{ - GtkWidget *w; - - w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL)); - setLabel(dateTimePickerWidget(w)); - return w; -} - -static GtkWidget *newDP(void) -{ - GtkWidget *w; - - w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL)); - setDateOnly(dateTimePickerWidget(w)); - setLabel(dateTimePickerWidget(w)); - return w; -} - -static GtkWidget *newTP(void) -{ - GtkWidget *w; - - w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL)); - setTimeOnly(dateTimePickerWidget(w)); - setLabel(dateTimePickerWidget(w)); - return w; -} - -struct uiDateTimePicker { - uiUnixControl c; - GtkWidget *widget; - dateTimePickerWidget *d; -}; - -uiUnixControlAllDefaults(uiDateTimePicker) - -uiDateTimePicker *finishNewDateTimePicker(GtkWidget *(*fn)(void)) -{ - uiDateTimePicker *d; - - uiUnixNewControl(uiDateTimePicker, d); - - d->widget = (*fn)(); - d->d = dateTimePickerWidget(d->widget); - - return d; -} - -uiDateTimePicker *uiNewDateTimePicker(void) -{ - return finishNewDateTimePicker(newDTP); -} - -uiDateTimePicker *uiNewDatePicker(void) -{ - return finishNewDateTimePicker(newDP); -} - -uiDateTimePicker *uiNewTimePicker(void) -{ - return finishNewDateTimePicker(newTP); -} diff --git a/deps/libui/unix/debug.c b/deps/libui/unix/debug.c deleted file mode 100644 index c948db6201..0000000000 --- a/deps/libui/unix/debug.c +++ /dev/null @@ -1,14 +0,0 @@ -// 13 may 2016 -#include "uipriv_unix.h" - -// LONGTERM don't halt on release builds - -void realbug(const char *file, const char *line, const char *func, const char *prefix, const char *format, va_list ap) -{ - char *a, *b; - - a = g_strdup_printf("[libui] %s:%s:%s() %s", file, line, func, prefix); - b = g_strdup_vprintf(format, ap); - g_critical("%s%s", a, b); - G_BREAKPOINT(); -} diff --git a/deps/libui/unix/draw.c b/deps/libui/unix/draw.c deleted file mode 100644 index 2d7a6367da..0000000000 --- a/deps/libui/unix/draw.c +++ /dev/null @@ -1,141 +0,0 @@ -// 6 september 2015 -#include "uipriv_unix.h" -#include "draw.h" - -uiDrawContext *newContext(cairo_t *cr) -{ - uiDrawContext *c; - - c = uiNew(uiDrawContext); - c->cr = cr; - return c; -} - -void freeContext(uiDrawContext *c) -{ - uiFree(c); -} - -static cairo_pattern_t *mkbrush(uiDrawBrush *b) -{ - cairo_pattern_t *pat; - size_t i; - - switch (b->Type) { - case uiDrawBrushTypeSolid: - pat = cairo_pattern_create_rgba(b->R, b->G, b->B, b->A); - break; - case uiDrawBrushTypeLinearGradient: - pat = cairo_pattern_create_linear(b->X0, b->Y0, b->X1, b->Y1); - break; - case uiDrawBrushTypeRadialGradient: - // make the start circle radius 0 to make it a point - pat = cairo_pattern_create_radial( - b->X0, b->Y0, 0, - b->X1, b->Y1, b->OuterRadius); - break; -// case uiDrawBrushTypeImage: - } - if (cairo_pattern_status(pat) != CAIRO_STATUS_SUCCESS) - implbug("error creating pattern in mkbrush(): %s", - cairo_status_to_string(cairo_pattern_status(pat))); - switch (b->Type) { - case uiDrawBrushTypeLinearGradient: - case uiDrawBrushTypeRadialGradient: - for (i = 0; i < b->NumStops; i++) - cairo_pattern_add_color_stop_rgba(pat, - b->Stops[i].Pos, - b->Stops[i].R, - b->Stops[i].G, - b->Stops[i].B, - b->Stops[i].A); - } - return pat; -} - -void uiDrawStroke(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b, uiDrawStrokeParams *p) -{ - cairo_pattern_t *pat; - - runPath(path, c->cr); - pat = mkbrush(b); - cairo_set_source(c->cr, pat); - switch (p->Cap) { - case uiDrawLineCapFlat: - cairo_set_line_cap(c->cr, CAIRO_LINE_CAP_BUTT); - break; - case uiDrawLineCapRound: - cairo_set_line_cap(c->cr, CAIRO_LINE_CAP_ROUND); - break; - case uiDrawLineCapSquare: - cairo_set_line_cap(c->cr, CAIRO_LINE_CAP_SQUARE); - break; - } - switch (p->Join) { - case uiDrawLineJoinMiter: - cairo_set_line_join(c->cr, CAIRO_LINE_JOIN_MITER); - cairo_set_miter_limit(c->cr, p->MiterLimit); - break; - case uiDrawLineJoinRound: - cairo_set_line_join(c->cr, CAIRO_LINE_JOIN_ROUND); - break; - case uiDrawLineJoinBevel: - cairo_set_line_join(c->cr, CAIRO_LINE_JOIN_BEVEL); - break; - } - cairo_set_line_width(c->cr, p->Thickness); - cairo_set_dash(c->cr, p->Dashes, p->NumDashes, p->DashPhase); - cairo_stroke(c->cr); - cairo_pattern_destroy(pat); -} - -void uiDrawFill(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b) -{ - cairo_pattern_t *pat; - - runPath(path, c->cr); - pat = mkbrush(b); - cairo_set_source(c->cr, pat); - switch (pathFillMode(path)) { - case uiDrawFillModeWinding: - cairo_set_fill_rule(c->cr, CAIRO_FILL_RULE_WINDING); - break; - case uiDrawFillModeAlternate: - cairo_set_fill_rule(c->cr, CAIRO_FILL_RULE_EVEN_ODD); - break; - } - cairo_fill(c->cr); - cairo_pattern_destroy(pat); -} - -void uiDrawTransform(uiDrawContext *c, uiDrawMatrix *m) -{ - cairo_matrix_t cm; - - m2c(m, &cm); - cairo_transform(c->cr, &cm); -} - -void uiDrawClip(uiDrawContext *c, uiDrawPath *path) -{ - runPath(path, c->cr); - switch (pathFillMode(path)) { - case uiDrawFillModeWinding: - cairo_set_fill_rule(c->cr, CAIRO_FILL_RULE_WINDING); - break; - case uiDrawFillModeAlternate: - cairo_set_fill_rule(c->cr, CAIRO_FILL_RULE_EVEN_ODD); - break; - } - cairo_clip(c->cr); -} - -void uiDrawSave(uiDrawContext *c) -{ - cairo_save(c->cr); -} - -void uiDrawRestore(uiDrawContext *c) -{ - cairo_restore(c->cr); -} diff --git a/deps/libui/unix/draw.h b/deps/libui/unix/draw.h deleted file mode 100644 index dbd82ff565..0000000000 --- a/deps/libui/unix/draw.h +++ /dev/null @@ -1,13 +0,0 @@ -// 5 may 2016 - -// draw.c -struct uiDrawContext { - cairo_t *cr; -}; - -// drawpath.c -extern void runPath(uiDrawPath *p, cairo_t *cr); -extern uiDrawFillMode pathFillMode(uiDrawPath *path); - -// drawmatrix.c -extern void m2c(uiDrawMatrix *m, cairo_matrix_t *c); diff --git a/deps/libui/unix/drawmatrix.c b/deps/libui/unix/drawmatrix.c deleted file mode 100644 index ac7ac579c7..0000000000 --- a/deps/libui/unix/drawmatrix.c +++ /dev/null @@ -1,109 +0,0 @@ -// 6 september 2015 -#include "uipriv_unix.h" -#include "draw.h" - -void m2c(uiDrawMatrix *m, cairo_matrix_t *c) -{ - c->xx = m->M11; - c->yx = m->M12; - c->xy = m->M21; - c->yy = m->M22; - c->x0 = m->M31; - c->y0 = m->M32; -} - -static void c2m(cairo_matrix_t *c, uiDrawMatrix *m) -{ - m->M11 = c->xx; - m->M12 = c->yx; - m->M21 = c->xy; - m->M22 = c->yy; - m->M31 = c->x0; - m->M32 = c->y0; -} - -void uiDrawMatrixTranslate(uiDrawMatrix *m, double x, double y) -{ - cairo_matrix_t c; - - m2c(m, &c); - cairo_matrix_translate(&c, x, y); - c2m(&c, m); -} - -void uiDrawMatrixScale(uiDrawMatrix *m, double xCenter, double yCenter, double x, double y) -{ - cairo_matrix_t c; - double xt, yt; - - m2c(m, &c); - xt = x; - yt = y; - scaleCenter(xCenter, yCenter, &xt, &yt); - cairo_matrix_translate(&c, xt, yt); - cairo_matrix_scale(&c, x, y); - cairo_matrix_translate(&c, -xt, -yt); - c2m(&c, m); -} - -void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount) -{ - cairo_matrix_t c; - - m2c(m, &c); - cairo_matrix_translate(&c, x, y); - cairo_matrix_rotate(&c, amount); - cairo_matrix_translate(&c, -x, -y); - c2m(&c, m); -} - -void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount) -{ - fallbackSkew(m, x, y, xamount, yamount); -} - -void uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src) -{ - cairo_matrix_t c; - cairo_matrix_t d; - - m2c(dest, &c); - m2c(src, &d); - cairo_matrix_multiply(&c, &c, &d); - c2m(&c, dest); -} - -int uiDrawMatrixInvertible(uiDrawMatrix *m) -{ - cairo_matrix_t c; - - m2c(m, &c); - return cairo_matrix_invert(&c) == CAIRO_STATUS_SUCCESS; -} - -int uiDrawMatrixInvert(uiDrawMatrix *m) -{ - cairo_matrix_t c; - - m2c(m, &c); - if (cairo_matrix_invert(&c) != CAIRO_STATUS_SUCCESS) - return 0; - c2m(&c, m); - return 1; -} - -void uiDrawMatrixTransformPoint(uiDrawMatrix *m, double *x, double *y) -{ - cairo_matrix_t c; - - m2c(m, &c); - cairo_matrix_transform_point(&c, x, y); -} - -void uiDrawMatrixTransformSize(uiDrawMatrix *m, double *x, double *y) -{ - cairo_matrix_t c; - - m2c(m, &c); - cairo_matrix_transform_distance(&c, x, y); -} diff --git a/deps/libui/unix/drawpath.c b/deps/libui/unix/drawpath.c deleted file mode 100644 index a0165fb882..0000000000 --- a/deps/libui/unix/drawpath.c +++ /dev/null @@ -1,199 +0,0 @@ -// 6 september 2015 -#include "uipriv_unix.h" -#include "draw.h" - -struct uiDrawPath { - GArray *pieces; - uiDrawFillMode fillMode; - gboolean ended; -}; - -struct piece { - int type; - double d[8]; - int b; -}; - -enum { - newFigure, - newFigureArc, - lineTo, - arcTo, - bezierTo, - closeFigure, - addRect, -}; - -uiDrawPath *uiDrawNewPath(uiDrawFillMode mode) -{ - uiDrawPath *p; - - p = uiNew(uiDrawPath); - p->pieces = g_array_new(FALSE, TRUE, sizeof (struct piece)); - p->fillMode = mode; - return p; -} - -void uiDrawFreePath(uiDrawPath *p) -{ - g_array_free(p->pieces, TRUE); - uiFree(p); -} - -static void add(uiDrawPath *p, struct piece *piece) -{ - if (p->ended) - userbug("You cannot modify a uiDrawPath that has been ended. (path: %p)", p); - g_array_append_vals(p->pieces, piece, 1); -} - -void uiDrawPathNewFigure(uiDrawPath *p, double x, double y) -{ - struct piece piece; - - piece.type = newFigure; - piece.d[0] = x; - piece.d[1] = y; - add(p, &piece); -} - -void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative) -{ - struct piece piece; - - if (sweep > 2 * uiPi) - sweep = 2 * uiPi; - piece.type = newFigureArc; - piece.d[0] = xCenter; - piece.d[1] = yCenter; - piece.d[2] = radius; - piece.d[3] = startAngle; - piece.d[4] = sweep; - piece.b = negative; - add(p, &piece); -} - -void uiDrawPathLineTo(uiDrawPath *p, double x, double y) -{ - struct piece piece; - - piece.type = lineTo; - piece.d[0] = x; - piece.d[1] = y; - add(p, &piece); -} - -void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative) -{ - struct piece piece; - - if (sweep > 2 * uiPi) - sweep = 2 * uiPi; - piece.type = arcTo; - piece.d[0] = xCenter; - piece.d[1] = yCenter; - piece.d[2] = radius; - piece.d[3] = startAngle; - piece.d[4] = sweep; - piece.b = negative; - add(p, &piece); -} - -void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY) -{ - struct piece piece; - - piece.type = bezierTo; - piece.d[0] = c1x; - piece.d[1] = c1y; - piece.d[2] = c2x; - piece.d[3] = c2y; - piece.d[4] = endX; - piece.d[5] = endY; - add(p, &piece); -} - -void uiDrawPathCloseFigure(uiDrawPath *p) -{ - struct piece piece; - - piece.type = closeFigure; - add(p, &piece); -} - -void uiDrawPathAddRectangle(uiDrawPath *p, double x, double y, double width, double height) -{ - struct piece piece; - - piece.type = addRect; - piece.d[0] = x; - piece.d[1] = y; - piece.d[2] = width; - piece.d[3] = height; - add(p, &piece); -} - -void uiDrawPathEnd(uiDrawPath *p) -{ - p->ended = TRUE; -} - -void runPath(uiDrawPath *p, cairo_t *cr) -{ - guint i; - struct piece *piece; - void (*arc)(cairo_t *, double, double, double, double, double); - - if (!p->ended) - userbug("You cannot draw with a uiDrawPath that has not been ended. (path: %p)", p); - cairo_new_path(cr); - for (i = 0; i < p->pieces->len; i++) { - piece = &g_array_index(p->pieces, struct piece, i); - switch (piece->type) { - case newFigure: - cairo_move_to(cr, piece->d[0], piece->d[1]); - break; - case newFigureArc: - cairo_new_sub_path(cr); - // fall through - case arcTo: - arc = cairo_arc; - if (piece->b) - arc = cairo_arc_negative; - (*arc)(cr, - piece->d[0], - piece->d[1], - piece->d[2], - piece->d[3], - piece->d[3] + piece->d[4]); - break; - case lineTo: - cairo_line_to(cr, piece->d[0], piece->d[1]); - break; - case bezierTo: - cairo_curve_to(cr, - piece->d[0], - piece->d[1], - piece->d[2], - piece->d[3], - piece->d[4], - piece->d[5]); - break; - case closeFigure: - cairo_close_path(cr); - break; - case addRect: - cairo_rectangle(cr, - piece->d[0], - piece->d[1], - piece->d[2], - piece->d[3]); - break; - } - } -} - -uiDrawFillMode pathFillMode(uiDrawPath *path) -{ - return path->fillMode; -} diff --git a/deps/libui/unix/drawtext.c b/deps/libui/unix/drawtext.c deleted file mode 100644 index 7078e1ac6a..0000000000 --- a/deps/libui/unix/drawtext.c +++ /dev/null @@ -1,293 +0,0 @@ -// 6 september 2015 -#include "uipriv_unix.h" -#include "draw.h" - -struct uiDrawFontFamilies { - PangoFontFamily **f; - int n; -}; - -uiDrawFontFamilies *uiDrawListFontFamilies(void) -{ - uiDrawFontFamilies *ff; - PangoFontMap *map; - - ff = uiNew(uiDrawFontFamilies); - map = pango_cairo_font_map_get_default(); - pango_font_map_list_families(map, &(ff->f), &(ff->n)); - // do not free map; it's a shared resource - return ff; -} - -int uiDrawFontFamiliesNumFamilies(uiDrawFontFamilies *ff) -{ - return ff->n; -} - -char *uiDrawFontFamiliesFamily(uiDrawFontFamilies *ff, int n) -{ - PangoFontFamily *f; - - f = ff->f[n]; - return uiUnixStrdupText(pango_font_family_get_name(f)); -} - -void uiDrawFreeFontFamilies(uiDrawFontFamilies *ff) -{ - g_free(ff->f); - uiFree(ff); -} - -struct uiDrawTextFont { - PangoFont *f; -}; - -uiDrawTextFont *mkTextFont(PangoFont *f, gboolean ref) -{ - uiDrawTextFont *font; - - font = uiNew(uiDrawTextFont); - font->f = f; - if (ref) - g_object_ref(font->f); - return font; -} - -static const PangoWeight pangoWeights[] = { - [uiDrawTextWeightThin] = PANGO_WEIGHT_THIN, - [uiDrawTextWeightUltraLight] = PANGO_WEIGHT_ULTRALIGHT, - [uiDrawTextWeightLight] = PANGO_WEIGHT_LIGHT, - [uiDrawTextWeightBook] = PANGO_WEIGHT_BOOK, - [uiDrawTextWeightNormal] = PANGO_WEIGHT_NORMAL, - [uiDrawTextWeightMedium] = PANGO_WEIGHT_MEDIUM, - [uiDrawTextWeightSemiBold] = PANGO_WEIGHT_SEMIBOLD, - [uiDrawTextWeightBold] = PANGO_WEIGHT_BOLD, - [uiDrawTextWeightUltraBold] = PANGO_WEIGHT_ULTRABOLD, - [uiDrawTextWeightHeavy] = PANGO_WEIGHT_HEAVY, - [uiDrawTextWeightUltraHeavy] = PANGO_WEIGHT_ULTRAHEAVY, -}; - -static const PangoStyle pangoItalics[] = { - [uiDrawTextItalicNormal] = PANGO_STYLE_NORMAL, - [uiDrawTextItalicOblique] = PANGO_STYLE_OBLIQUE, - [uiDrawTextItalicItalic] = PANGO_STYLE_ITALIC, -}; - -static const PangoStretch pangoStretches[] = { - [uiDrawTextStretchUltraCondensed] = PANGO_STRETCH_ULTRA_CONDENSED, - [uiDrawTextStretchExtraCondensed] = PANGO_STRETCH_EXTRA_CONDENSED, - [uiDrawTextStretchCondensed] = PANGO_STRETCH_CONDENSED, - [uiDrawTextStretchSemiCondensed] = PANGO_STRETCH_SEMI_CONDENSED, - [uiDrawTextStretchNormal] = PANGO_STRETCH_NORMAL, - [uiDrawTextStretchSemiExpanded] = PANGO_STRETCH_SEMI_EXPANDED, - [uiDrawTextStretchExpanded] = PANGO_STRETCH_EXPANDED, - [uiDrawTextStretchExtraExpanded] = PANGO_STRETCH_EXTRA_EXPANDED, - [uiDrawTextStretchUltraExpanded] = PANGO_STRETCH_ULTRA_EXPANDED, -}; - -// we need a context for a few things -// the documentation suggests creating cairo_t-specific, GdkScreen-specific, or even GtkWidget-specific contexts, but we can't really do that because we want our uiDrawTextFonts and uiDrawTextLayouts to be context-independent -// we could use pango_font_map_create_context(pango_cairo_font_map_get_default()) but that will ignore GDK-specific settings -// so let's use gdk_pango_context_get() instead; even though it's for the default screen only, it's good enough for us -#define mkGenericPangoCairoContext() (gdk_pango_context_get()) - -PangoFont *pangoDescToPangoFont(PangoFontDescription *pdesc) -{ - PangoFont *f; - PangoContext *context; - - // in this case, the context is necessary for the metrics to be correct - context = mkGenericPangoCairoContext(); - f = pango_font_map_load_font(pango_cairo_font_map_get_default(), context, pdesc); - if (f == NULL) { - // LONGTERM - g_error("[libui] no match in pangoDescToPangoFont(); report to andlabs"); - } - g_object_unref(context); - return f; -} - -uiDrawTextFont *uiDrawLoadClosestFont(const uiDrawTextFontDescriptor *desc) -{ - PangoFont *f; - PangoFontDescription *pdesc; - - pdesc = pango_font_description_new(); - pango_font_description_set_family(pdesc, - desc->Family); - pango_font_description_set_size(pdesc, - (gint) (desc->Size * PANGO_SCALE)); - pango_font_description_set_weight(pdesc, - pangoWeights[desc->Weight]); - pango_font_description_set_style(pdesc, - pangoItalics[desc->Italic]); - pango_font_description_set_stretch(pdesc, - pangoStretches[desc->Stretch]); - f = pangoDescToPangoFont(pdesc); - pango_font_description_free(pdesc); - return mkTextFont(f, FALSE); // we hold the initial reference; no need to ref -} - -void uiDrawFreeTextFont(uiDrawTextFont *font) -{ - g_object_unref(font->f); - uiFree(font); -} - -uintptr_t uiDrawTextFontHandle(uiDrawTextFont *font) -{ - return (uintptr_t) (font->f); -} - -void uiDrawTextFontDescribe(uiDrawTextFont *font, uiDrawTextFontDescriptor *desc) -{ - PangoFontDescription *pdesc; - - // this creates a copy; we free it later - pdesc = pango_font_describe(font->f); - - // TODO - - pango_font_description_free(pdesc); -} - -// See https://developer.gnome.org/pango/1.30/pango-Cairo-Rendering.html#pango-Cairo-Rendering.description -// Note that we convert to double before dividing to make sure the floating-point stuff is right -#define pangoToCairo(pango) (((double) (pango)) / PANGO_SCALE) -#define cairoToPango(cairo) ((gint) ((cairo) * PANGO_SCALE)) - -void uiDrawTextFontGetMetrics(uiDrawTextFont *font, uiDrawTextFontMetrics *metrics) -{ - PangoFontMetrics *pm; - - pm = pango_font_get_metrics(font->f, NULL); - metrics->Ascent = pangoToCairo(pango_font_metrics_get_ascent(pm)); - metrics->Descent = pangoToCairo(pango_font_metrics_get_descent(pm)); - // Pango doesn't seem to expose this :( Use 0 and hope for the best. - metrics->Leading = 0; - metrics->UnderlinePos = pangoToCairo(pango_font_metrics_get_underline_position(pm)); - metrics->UnderlineThickness = pangoToCairo(pango_font_metrics_get_underline_thickness(pm)); - pango_font_metrics_unref(pm); -} - -// note: PangoCairoLayouts are tied to a given cairo_t, so we can't store one in this device-independent structure -struct uiDrawTextLayout { - char *s; - ptrdiff_t *graphemes; - PangoFont *defaultFont; - double width; - PangoAttrList *attrs; -}; - -uiDrawTextLayout *uiDrawNewTextLayout(const char *text, uiDrawTextFont *defaultFont, double width) -{ - uiDrawTextLayout *layout; - PangoContext *context; - - layout = uiNew(uiDrawTextLayout); - layout->s = g_strdup(text); - context = mkGenericPangoCairoContext(); - layout->graphemes = graphemes(layout->s, context); - g_object_unref(context); - layout->defaultFont = defaultFont->f; - g_object_ref(layout->defaultFont); // retain a copy - uiDrawTextLayoutSetWidth(layout, width); - layout->attrs = pango_attr_list_new(); - return layout; -} - -void uiDrawFreeTextLayout(uiDrawTextLayout *layout) -{ - pango_attr_list_unref(layout->attrs); - g_object_unref(layout->defaultFont); - uiFree(layout->graphemes); - g_free(layout->s); - uiFree(layout); -} - -void uiDrawTextLayoutSetWidth(uiDrawTextLayout *layout, double width) -{ - layout->width = width; -} - -static void prepareLayout(uiDrawTextLayout *layout, PangoLayout *pl) -{ - PangoFontDescription *desc; - int width; - - pango_layout_set_text(pl, layout->s, -1); - - // again, this makes a copy - desc = pango_font_describe(layout->defaultFont); - // this is safe; the description is copied - pango_layout_set_font_description(pl, desc); - pango_font_description_free(desc); - - width = cairoToPango(layout->width); - if (layout->width < 0) - width = -1; - pango_layout_set_width(pl, width); - - pango_layout_set_attributes(pl, layout->attrs); -} - -void uiDrawTextLayoutExtents(uiDrawTextLayout *layout, double *width, double *height) -{ - PangoContext *context; - PangoLayout *pl; - PangoRectangle logical; - - // in this case, the context is necessary to create the layout - // the layout takes a ref on the context so we can unref it afterward - context = mkGenericPangoCairoContext(); - pl = pango_layout_new(context); - g_object_unref(context); - prepareLayout(layout, pl); - - pango_layout_get_extents(pl, NULL, &logical); - - g_object_unref(pl); - - *width = pangoToCairo(logical.width); - *height = pangoToCairo(logical.height); -} - -void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout) -{ - PangoLayout *pl; - - pl = pango_cairo_create_layout(c->cr); - prepareLayout(layout, pl); - - cairo_move_to(c->cr, x, y); - pango_cairo_show_layout(c->cr, pl); - - g_object_unref(pl); -} - -static void addAttr(uiDrawTextLayout *layout, PangoAttribute *attr, int startChar, int endChar) -{ - attr->start_index = layout->graphemes[startChar]; - attr->end_index = layout->graphemes[endChar]; - pango_attr_list_insert(layout->attrs, attr); - // pango_attr_list_insert() takes attr; we don't free it -} - -void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, int startChar, int endChar, double r, double g, double b, double a) -{ - PangoAttribute *attr; - guint16 rr, gg, bb, aa; - - rr = (guint16) (r * 65535); - gg = (guint16) (g * 65535); - bb = (guint16) (b * 65535); - aa = (guint16) (a * 65535); - - attr = pango_attr_foreground_new(rr, gg, bb); - addAttr(layout, attr, startChar, endChar); - - // TODO what if aa == 0? - attr = FUTURE_pango_attr_foreground_alpha_new(aa); - if (attr != NULL) - addAttr(layout, attr, startChar, endChar); -} diff --git a/deps/libui/unix/editablecombo.c b/deps/libui/unix/editablecombo.c deleted file mode 100644 index 7ee3829eea..0000000000 --- a/deps/libui/unix/editablecombo.c +++ /dev/null @@ -1,79 +0,0 @@ -// 11 june 2015 -#include "uipriv_unix.h" - -struct uiEditableCombobox { - uiUnixControl c; - GtkWidget *widget; - GtkBin *bin; - GtkComboBox *combobox; - GtkComboBoxText *comboboxText; - void (*onChanged)(uiEditableCombobox *, void *); - void *onChangedData; - gulong onChangedSignal; -}; - -uiUnixControlAllDefaults(uiEditableCombobox) - -static void onChanged(GtkComboBox *cbox, gpointer data) -{ - uiEditableCombobox *c = uiEditableCombobox(data); - - (*(c->onChanged))(c, c->onChangedData); -} - -static void defaultOnChanged(uiEditableCombobox *c, void *data) -{ - // do nothing -} - -void uiEditableComboboxAppend(uiEditableCombobox *c, const char *text) -{ - gtk_combo_box_text_append(c->comboboxText, NULL, text); -} - -char *uiEditableComboboxText(uiEditableCombobox *c) -{ - char *s; - char *out; - - s = gtk_combo_box_text_get_active_text(c->comboboxText); - // s will always be non-NULL in the case of a combobox with an entry (according to the source code) - out = uiUnixStrdupText(s); - g_free(s); - return out; -} - -void uiEditableComboboxSetText(uiEditableCombobox *c, const char *text) -{ - GtkEntry *e; - - // we need to inhibit sending of ::changed because this WILL send a ::changed otherwise - g_signal_handler_block(c->combobox, c->onChangedSignal); - // since there isn't a gtk_combo_box_text_set_active_text()... - e = GTK_ENTRY(gtk_bin_get_child(c->bin)); - gtk_entry_set_text(e, text); - g_signal_handler_unblock(c->combobox, c->onChangedSignal); -} - -void uiEditableComboboxOnChanged(uiEditableCombobox *c, void (*f)(uiEditableCombobox *c, void *data), void *data) -{ - c->onChanged = f; - c->onChangedData = data; -} - -uiEditableCombobox *uiNewEditableCombobox(void) -{ - uiEditableCombobox *c; - - uiUnixNewControl(uiEditableCombobox, c); - - c->widget = gtk_combo_box_text_new_with_entry(); - c->bin = GTK_BIN(c->widget); - c->combobox = GTK_COMBO_BOX(c->widget); - c->comboboxText = GTK_COMBO_BOX_TEXT(c->widget); - - c->onChangedSignal = g_signal_connect(c->widget, "changed", G_CALLBACK(onChanged), c); - uiEditableComboboxOnChanged(c, defaultOnChanged, NULL); - - return c; -} diff --git a/deps/libui/unix/entry.c b/deps/libui/unix/entry.c deleted file mode 100644 index 4a9a1d0410..0000000000 --- a/deps/libui/unix/entry.c +++ /dev/null @@ -1,97 +0,0 @@ -// 11 june 2015 -#include "uipriv_unix.h" - -struct uiEntry { - uiUnixControl c; - GtkWidget *widget; - GtkEntry *entry; - GtkEditable *editable; - void (*onChanged)(uiEntry *, void *); - void *onChangedData; - gulong onChangedSignal; -}; - -uiUnixControlAllDefaults(uiEntry) - -static void onChanged(GtkEditable *editable, gpointer data) -{ - uiEntry *e = uiEntry(data); - - (*(e->onChanged))(e, e->onChangedData); -} - -static void defaultOnChanged(uiEntry *e, void *data) -{ - // do nothing -} - -char *uiEntryText(uiEntry *e) -{ - return uiUnixStrdupText(gtk_entry_get_text(e->entry)); -} - -void uiEntrySetText(uiEntry *e, const char *text) -{ - // we need to inhibit sending of ::changed because this WILL send a ::changed otherwise - g_signal_handler_block(e->editable, e->onChangedSignal); - gtk_entry_set_text(e->entry, text); - g_signal_handler_unblock(e->editable, e->onChangedSignal); - // don't queue the control for resize; entry sizes are independent of their contents -} - -void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *, void *), void *data) -{ - e->onChanged = f; - e->onChangedData = data; -} - -int uiEntryReadOnly(uiEntry *e) -{ - return gtk_editable_get_editable(e->editable) == FALSE; -} - -void uiEntrySetReadOnly(uiEntry *e, int readonly) -{ - gboolean editable; - - editable = TRUE; - if (readonly) - editable = FALSE; - gtk_editable_set_editable(e->editable, editable); -} - -static uiEntry *finishNewEntry(GtkWidget *w, const gchar *signal) -{ - uiEntry *e; - - uiUnixNewControl(uiEntry, e); - - e->widget = w; - e->entry = GTK_ENTRY(e->widget); - e->editable = GTK_EDITABLE(e->widget); - - e->onChangedSignal = g_signal_connect(e->widget, signal, G_CALLBACK(onChanged), e); - uiEntryOnChanged(e, defaultOnChanged, NULL); - - return e; -} - -uiEntry *uiNewEntry(void) -{ - return finishNewEntry(gtk_entry_new(), "changed"); -} - -uiEntry *uiNewPasswordEntry(void) -{ - GtkWidget *e; - - e = gtk_entry_new(); - gtk_entry_set_visibility(GTK_ENTRY(e), FALSE); - return finishNewEntry(e, "changed"); -} - -// TODO make it use a separate function to be type-safe -uiEntry *uiNewSearchEntry(void) -{ - return finishNewEntry(gtk_search_entry_new(), "search-changed"); -} diff --git a/deps/libui/unix/fontbutton.c b/deps/libui/unix/fontbutton.c deleted file mode 100644 index f8047e0803..0000000000 --- a/deps/libui/unix/fontbutton.c +++ /dev/null @@ -1,70 +0,0 @@ -// 14 april 2016 -#include "uipriv_unix.h" - -struct uiFontButton { - uiUnixControl c; - GtkWidget *widget; - GtkButton *button; - GtkFontButton *fb; - GtkFontChooser *fc; - void (*onChanged)(uiFontButton *, void *); - void *onChangedData; -}; - -uiUnixControlAllDefaults(uiFontButton) - -// TODO NOTE no need to inhibit the signal; font-set is documented as only being sent when the user changes the font -static void onFontSet(GtkFontButton *button, gpointer data) -{ - uiFontButton *b = uiFontButton(data); - - (*(b->onChanged))(b, b->onChangedData); -} - -static void defaultOnChanged(uiFontButton *b, void *data) -{ - // do nothing -} - -uiDrawTextFont *uiFontButtonFont(uiFontButton *b) -{ - PangoFont *f; - PangoFontDescription *desc; - - desc = gtk_font_chooser_get_font_desc(b->fc); - f = pangoDescToPangoFont(desc); - // desc is transfer-full and thus is a copy - pango_font_description_free(desc); - return mkTextFont(f, FALSE); // we hold the initial reference; no need to ref -} - -void uiFontButtonOnChanged(uiFontButton *b, void (*f)(uiFontButton *, void *), void *data) -{ - b->onChanged = f; - b->onChangedData = data; -} - -uiFontButton *uiNewFontButton(void) -{ - uiFontButton *b; - - uiUnixNewControl(uiFontButton, b); - - b->widget = gtk_font_button_new(); - b->button = GTK_BUTTON(b->widget); - b->fb = GTK_FONT_BUTTON(b->widget); - b->fc = GTK_FONT_CHOOSER(b->widget); - - // match behavior on other platforms - gtk_font_button_set_show_style(b->fb, TRUE); - gtk_font_button_set_show_size(b->fb, TRUE); - gtk_font_button_set_use_font(b->fb, FALSE); - gtk_font_button_set_use_size(b->fb, FALSE); - // other customizations - gtk_font_chooser_set_show_preview_entry(b->fc, TRUE); - - g_signal_connect(b->widget, "font-set", G_CALLBACK(onFontSet), b); - uiFontButtonOnChanged(b, defaultOnChanged, NULL); - - return b; -} diff --git a/deps/libui/unix/form.c b/deps/libui/unix/form.c deleted file mode 100644 index 54422b3d40..0000000000 --- a/deps/libui/unix/form.c +++ /dev/null @@ -1,159 +0,0 @@ -// 8 june 2016 -#include "uipriv_unix.h" - -struct formChild { - uiControl *c; - int stretchy; - GtkWidget *label; - gboolean oldhexpand; - GtkAlign oldhalign; - gboolean oldvexpand; - GtkAlign oldvalign; - GBinding *labelBinding; -}; - -struct uiForm { - uiUnixControl c; - GtkWidget *widget; - GtkContainer *container; - GtkGrid *grid; - GArray *children; - int padded; - GtkSizeGroup *stretchygroup; // ensures all stretchy controls have the same size -}; - -uiUnixControlAllDefaultsExceptDestroy(uiForm) - -#define ctrl(f, i) &g_array_index(f->children, struct formChild, i) - -static void uiFormDestroy(uiControl *c) -{ - uiForm *f = uiForm(c); - struct formChild *fc; - guint i; - - // kill the size group - g_object_unref(f->stretchygroup); - // free all controls - for (i = 0; i < f->children->len; i++) { - fc = ctrl(f, i); - uiControlSetParent(fc->c, NULL); - uiUnixControlSetContainer(uiUnixControl(fc->c), f->container, TRUE); - uiControlDestroy(fc->c); - gtk_widget_destroy(fc->label); - } - g_array_free(f->children, TRUE); - // and then ourselves - g_object_unref(f->widget); - uiFreeControl(uiControl(f)); -} - -void uiFormAppend(uiForm *f, const char *label, uiControl *c, int stretchy) -{ - struct formChild fc; - GtkWidget *widget; - guint row; - - fc.c = c; - widget = GTK_WIDGET(uiControlHandle(fc.c)); - fc.stretchy = stretchy; - fc.oldhexpand = gtk_widget_get_hexpand(widget); - fc.oldhalign = gtk_widget_get_halign(widget); - fc.oldvexpand = gtk_widget_get_vexpand(widget); - fc.oldvalign = gtk_widget_get_valign(widget); - - if (stretchy) { - gtk_widget_set_vexpand(widget, TRUE); - gtk_widget_set_valign(widget, GTK_ALIGN_FILL); - gtk_size_group_add_widget(f->stretchygroup, widget); - } else - gtk_widget_set_vexpand(widget, FALSE); - // and make them fill horizontally - gtk_widget_set_hexpand(widget, TRUE); - gtk_widget_set_halign(widget, GTK_ALIGN_FILL); - - fc.label = gtk_label_new(label); - gtk_widget_set_hexpand(fc.label, FALSE); - gtk_widget_set_halign(fc.label, GTK_ALIGN_END); - gtk_widget_set_vexpand(fc.label, FALSE); - if (GTK_IS_SCROLLED_WINDOW(widget)) - gtk_widget_set_valign(fc.label, GTK_ALIGN_START); - else - gtk_widget_set_valign(fc.label, GTK_ALIGN_CENTER); - gtk_style_context_add_class(gtk_widget_get_style_context(fc.label), "dim-label"); - row = f->children->len; - gtk_grid_attach(f->grid, fc.label, - 0, row, - 1, 1); - // and make them share visibility so if the control is hidden, so is its label - fc.labelBinding = g_object_bind_property(GTK_WIDGET(uiControlHandle(fc.c)), "visible", - fc.label, "visible", - G_BINDING_SYNC_CREATE); - - uiControlSetParent(fc.c, uiControl(f)); - uiUnixControlSetContainer(uiUnixControl(fc.c), f->container, FALSE); - g_array_append_val(f->children, fc); - - // move the widget to the correct place - gtk_container_child_set(f->container, widget, - "left-attach", 1, - "top-attach", row, - NULL); -} - -void uiFormDelete(uiForm *f, int index) -{ - struct formChild *fc; - GtkWidget *widget; - - fc = ctrl(f, index); - widget = GTK_WIDGET(uiControlHandle(fc->c)); - - gtk_widget_destroy(fc->label); - - uiControlSetParent(fc->c, NULL); - uiUnixControlSetContainer(uiUnixControl(fc->c), f->container, TRUE); - - if (fc->stretchy) - gtk_size_group_remove_widget(f->stretchygroup, widget); - gtk_widget_set_hexpand(widget, fc->oldhexpand); - gtk_widget_set_halign(widget, fc->oldhalign); - gtk_widget_set_vexpand(widget, fc->oldvexpand); - gtk_widget_set_valign(widget, fc->oldvalign); - - g_array_remove_index(f->children, index); -} - -int uiFormPadded(uiForm *f) -{ - return f->padded; -} - -void uiFormSetPadded(uiForm *f, int padded) -{ - f->padded = padded; - if (f->padded) { - gtk_grid_set_row_spacing(f->grid, gtkYPadding); - gtk_grid_set_column_spacing(f->grid, gtkXPadding); - } else { - gtk_grid_set_row_spacing(f->grid, 0); - gtk_grid_set_column_spacing(f->grid, 0); - } -} - -uiForm *uiNewForm(void) -{ - uiForm *f; - - uiUnixNewControl(uiForm, f); - - f->widget = gtk_grid_new(); - f->container = GTK_CONTAINER(f->widget); - f->grid = GTK_GRID(f->widget); - - f->stretchygroup = gtk_size_group_new(GTK_SIZE_GROUP_VERTICAL); - - f->children = g_array_new(FALSE, TRUE, sizeof (struct formChild)); - - return f; -} diff --git a/deps/libui/unix/future.c b/deps/libui/unix/future.c deleted file mode 100644 index 1f9f532b11..0000000000 --- a/deps/libui/unix/future.c +++ /dev/null @@ -1,42 +0,0 @@ -// 29 june 2016 -#include "uipriv_unix.h" - -// functions FROM THE FUTURE! -// in some cases, because being held back by LTS releases sucks :/ -// in others, because parts of GTK+ being unstable until recently also sucks :/ - -// added in pango 1.38; we need 1.36 -static PangoAttribute *(*newFGAlphaAttr)(guint16 alpha) = NULL; - -// added in GTK+ 3.20; we need 3.10 -static void (*gwpIterSetObjectName)(GtkWidgetPath *path, gint pos, const char *name) = NULL; - -// note that we treat any error as "the symbols aren't there" (and don't care if dlclose() failed) -void loadFutures(void) -{ - void *handle; - - // dlsym() walks the dependency chain, so opening the current process should be sufficient - handle = dlopen(NULL, RTLD_LAZY); - if (handle == NULL) - return; -#define GET(var, fn) *((void **) (&var)) = dlsym(handle, #fn) - GET(newFGAlphaAttr, pango_attr_foreground_alpha_new); - GET(gwpIterSetObjectName, gtk_widget_path_iter_set_object_name); - dlclose(handle); -} - -PangoAttribute *FUTURE_pango_attr_foreground_alpha_new(guint16 alpha) -{ - if (newFGAlphaAttr == NULL) - return NULL; - return (*newFGAlphaAttr)(alpha); -} - -gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, gint pos, const char *name) -{ - if (gwpIterSetObjectName == NULL) - return FALSE; - (*gwpIterSetObjectName)(path, pos, name); - return TRUE; -} diff --git a/deps/libui/unix/graphemes.c b/deps/libui/unix/graphemes.c deleted file mode 100644 index a2c47b7251..0000000000 --- a/deps/libui/unix/graphemes.c +++ /dev/null @@ -1,31 +0,0 @@ -// 25 may 2016 -#include "uipriv_unix.h" - -ptrdiff_t *graphemes(const char *text, PangoContext *context) -{ - size_t len, lenchars; - PangoLogAttr *logattrs; - ptrdiff_t *out; - ptrdiff_t *op; - size_t i; - - len = strlen(text); - lenchars = g_utf8_strlen(text, -1); - logattrs = (PangoLogAttr *) uiAlloc((lenchars + 1) * sizeof (PangoLogAttr), "PangoLogAttr[]"); - pango_get_log_attrs(text, len, - -1, NULL, - logattrs, lenchars + 1); - - // should be more than enough - out = (ptrdiff_t *) uiAlloc((lenchars + 2) * sizeof (ptrdiff_t), "ptrdiff_t[]"); - op = out; - for (i = 0; i < lenchars; i++) - if (logattrs[i].is_cursor_position != 0) - // TODO optimize this - *op++ = g_utf8_offset_to_pointer(text, i) - text; - // and do the last one - *op++ = len; - - uiFree(logattrs); - return out; -} diff --git a/deps/libui/unix/grid.c b/deps/libui/unix/grid.c deleted file mode 100644 index 6d9813b35d..0000000000 --- a/deps/libui/unix/grid.c +++ /dev/null @@ -1,141 +0,0 @@ -// 9 june 2016 -#include "uipriv_unix.h" - -struct gridChild { - uiControl *c; - GtkWidget *label; - gboolean oldhexpand; - GtkAlign oldhalign; - gboolean oldvexpand; - GtkAlign oldvalign; -}; - -struct uiGrid { - uiUnixControl c; - GtkWidget *widget; - GtkContainer *container; - GtkGrid *grid; - GArray *children; - int padded; -}; - -uiUnixControlAllDefaultsExceptDestroy(uiGrid) - -#define ctrl(g, i) &g_array_index(g->children, struct gridChild, i) - -static void uiGridDestroy(uiControl *c) -{ - uiGrid *g = uiGrid(c); - struct gridChild *gc; - guint i; - - // free all controls - for (i = 0; i < g->children->len; i++) { - gc = ctrl(g, i); - uiControlSetParent(gc->c, NULL); - uiUnixControlSetContainer(uiUnixControl(gc->c), g->container, TRUE); - uiControlDestroy(gc->c); - } - g_array_free(g->children, TRUE); - // and then ourselves - g_object_unref(g->widget); - uiFreeControl(uiControl(g)); -} - -#define TODO_MASSIVE_HACK(c) \ - if (!uiUnixControl(c)->addedBefore) { \ - g_object_ref_sink(GTK_WIDGET(uiControlHandle(uiControl(c)))); \ - gtk_widget_show(GTK_WIDGET(uiControlHandle(uiControl(c)))); \ - uiUnixControl(c)->addedBefore = TRUE; \ - } - -static const GtkAlign gtkAligns[] = { - [uiAlignFill] = GTK_ALIGN_FILL, - [uiAlignStart] = GTK_ALIGN_START, - [uiAlignCenter] = GTK_ALIGN_CENTER, - [uiAlignEnd] = GTK_ALIGN_END, -}; - -static const GtkPositionType gtkPositions[] = { - [uiAtLeading] = GTK_POS_LEFT, - [uiAtTop] = GTK_POS_TOP, - [uiAtTrailing] = GTK_POS_RIGHT, - [uiAtBottom] = GTK_POS_BOTTOM, -}; - -static GtkWidget *prepare(struct gridChild *gc, uiControl *c, int hexpand, uiAlign halign, int vexpand, uiAlign valign) -{ - GtkWidget *widget; - - gc->c = c; - widget = GTK_WIDGET(uiControlHandle(gc->c)); - gc->oldhexpand = gtk_widget_get_hexpand(widget); - gc->oldhalign = gtk_widget_get_halign(widget); - gc->oldvexpand = gtk_widget_get_vexpand(widget); - gc->oldvalign = gtk_widget_get_valign(widget); - gtk_widget_set_hexpand(widget, hexpand != 0); - gtk_widget_set_halign(widget, gtkAligns[halign]); - gtk_widget_set_vexpand(widget, vexpand != 0); - gtk_widget_set_valign(widget, gtkAligns[valign]); - return widget; -} - -void uiGridAppend(uiGrid *g, uiControl *c, int left, int top, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign) -{ - struct gridChild gc; - GtkWidget *widget; - - widget = prepare(&gc, c, hexpand, halign, vexpand, valign); - uiControlSetParent(gc.c, uiControl(g)); - TODO_MASSIVE_HACK(uiUnixControl(gc.c)); - gtk_grid_attach(g->grid, widget, - left, top, - xspan, yspan); - g_array_append_val(g->children, gc); -} - -void uiGridInsertAt(uiGrid *g, uiControl *c, uiControl *existing, uiAt at, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign) -{ - struct gridChild gc; - GtkWidget *widget; - - widget = prepare(&gc, c, hexpand, halign, vexpand, valign); - uiControlSetParent(gc.c, uiControl(g)); - TODO_MASSIVE_HACK(uiUnixControl(gc.c)); - gtk_grid_attach_next_to(g->grid, widget, - GTK_WIDGET(uiControlHandle(existing)), gtkPositions[at], - xspan, yspan); - g_array_append_val(g->children, gc); -} - -int uiGridPadded(uiGrid *g) -{ - return g->padded; -} - -void uiGridSetPadded(uiGrid *g, int padded) -{ - g->padded = padded; - if (g->padded) { - gtk_grid_set_row_spacing(g->grid, gtkYPadding); - gtk_grid_set_column_spacing(g->grid, gtkXPadding); - } else { - gtk_grid_set_row_spacing(g->grid, 0); - gtk_grid_set_column_spacing(g->grid, 0); - } -} - -uiGrid *uiNewGrid(void) -{ - uiGrid *g; - - uiUnixNewControl(uiGrid, g); - - g->widget = gtk_grid_new(); - g->container = GTK_CONTAINER(g->widget); - g->grid = GTK_GRID(g->widget); - - g->children = g_array_new(FALSE, TRUE, sizeof (struct gridChild)); - - return g; -} diff --git a/deps/libui/unix/group.c b/deps/libui/unix/group.c deleted file mode 100644 index 6238a1b650..0000000000 --- a/deps/libui/unix/group.c +++ /dev/null @@ -1,89 +0,0 @@ -// 11 june 2015 -#include "uipriv_unix.h" - -struct uiGroup { - uiUnixControl c; - GtkWidget *widget; - GtkContainer *container; - GtkBin *bin; - GtkFrame *frame; - - // unfortunately, even though a GtkFrame is a GtkBin, calling gtk_container_set_border_width() on it /includes/ the GtkFrame's label; we don't want tht - struct child *child; - - int margined; -}; - -uiUnixControlAllDefaultsExceptDestroy(uiGroup) - -static void uiGroupDestroy(uiControl *c) -{ - uiGroup *g = uiGroup(c); - - if (g->child != NULL) - childDestroy(g->child); - g_object_unref(g->widget); - uiFreeControl(uiControl(g)); -} - -char *uiGroupTitle(uiGroup *g) -{ - return uiUnixStrdupText(gtk_frame_get_label(g->frame)); -} - -void uiGroupSetTitle(uiGroup *g, const char *text) -{ - gtk_frame_set_label(g->frame, text); -} - -void uiGroupSetChild(uiGroup *g, uiControl *child) -{ - if (g->child != NULL) - childRemove(g->child); - g->child = newChildWithBox(child, uiControl(g), g->container, g->margined); -} - -int uiGroupMargined(uiGroup *g) -{ - return g->margined; -} - -void uiGroupSetMargined(uiGroup *g, int margined) -{ - g->margined = margined; - if (g->child != NULL) - childSetMargined(g->child, g->margined); -} - -uiGroup *uiNewGroup(const char *text) -{ - uiGroup *g; - gfloat yalign; - GtkLabel *label; - PangoAttribute *bold; - PangoAttrList *boldlist; - - uiUnixNewControl(uiGroup, g); - - g->widget = gtk_frame_new(text); - g->container = GTK_CONTAINER(g->widget); - g->bin = GTK_BIN(g->widget); - g->frame = GTK_FRAME(g->widget); - - // with GTK+, groupboxes by default have frames and slightly x-offset regular text - // they should have no frame and fully left-justified, bold text - // preserve default y-alignment - gtk_frame_get_label_align(g->frame, NULL, &yalign); - gtk_frame_set_label_align(g->frame, 0, yalign); - gtk_frame_set_shadow_type(g->frame, GTK_SHADOW_NONE); - label = GTK_LABEL(gtk_frame_get_label_widget(g->frame)); - // this is the boldness level used by GtkPrintUnixDialog - // (it technically uses "bold" but see pango's pango-enum-types.c for the name conversion; GType is weird) - bold = pango_attr_weight_new(PANGO_WEIGHT_BOLD); - boldlist = pango_attr_list_new(); - pango_attr_list_insert(boldlist, bold); - gtk_label_set_attributes(label, boldlist); - pango_attr_list_unref(boldlist); // thanks baedert in irc.gimp.net/#gtk+ - - return g; -} diff --git a/deps/libui/unix/image.c b/deps/libui/unix/image.c deleted file mode 100644 index a79e550f93..0000000000 --- a/deps/libui/unix/image.c +++ /dev/null @@ -1,120 +0,0 @@ -// 27 june 2016 -#include "uipriv_unix.h" - -struct uiImage { - double width; - double height; - GPtrArray *images; -}; - -static void freeImageRep(gpointer item) -{ - cairo_surface_t *cs = (cairo_surface_t *) item; - unsigned char *buf; - - buf = cairo_image_surface_get_data(cs); - cairo_surface_destroy(cs); - uiFree(buf); -} - -uiImage *uiNewImage(double width, double height) -{ - uiImage *i; - - i = uiNew(uiImage); - i->width = width; - i->height = height; - i->images = g_ptr_array_new_with_free_func(freeImageRep); - return i; -} - -void uiFreeImage(uiImage *i) -{ - g_ptr_array_free(i->images, TRUE); - uiFree(i); -} - -void uiImageAppend(uiImage *i, void *pixels, int pixelWidth, int pixelHeight, int pixelStride) -{ - cairo_surface_t *cs; - unsigned char *buf, *p; - uint8_t *src = (uint8_t *) pixels; - int cstride; - int y; - - cstride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, pixelWidth); - buf = (unsigned char *) uiAlloc((cstride * pixelHeight * 4) * sizeof (unsigned char), "unsigned char[]"); - p = buf; - for (y = 0; y < pixelStride * pixelHeight; y += pixelStride) { - memmove(p, src + y, cstride); - p += cstride; - } - cs = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_ARGB32, - pixelWidth, pixelHeight, - cstride); - if (cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS) - /* TODO */; - cairo_surface_flush(cs); - g_ptr_array_add(i->images, cs); -} - -struct matcher { - cairo_surface_t *best; - int distX; - int distY; - int targetX; - int targetY; - gboolean foundLarger; -}; - -// TODO is this the right algorithm? -static void match(gpointer surface, gpointer data) -{ - cairo_surface_t *cs = (cairo_surface_t *) surface; - struct matcher *m = (struct matcher *) data; - int x, y; - int x2, y2; - - x = cairo_image_surface_get_width(cs); - y = cairo_image_surface_get_height(cs); - if (m->best == NULL) - goto writeMatch; - - if (x < m->targetX && y < m->targetY) - if (m->foundLarger) - // always prefer larger ones - return; - if (x >= m->targetX && y >= m->targetY && !m->foundLarger) - // we set foundLarger below - goto writeMatch; - - x2 = abs(m->targetX - x); - y2 = abs(m->targetY - y); - if (x2 < m->distX && y2 < m->distY) - goto writeMatch; - - // TODO weight one dimension? threshhold? - return; - -writeMatch: - // must set this here too; otherwise the first image will never have ths set - if (x >= m->targetX && y >= m->targetY && !m->foundLarger) - m->foundLarger = TRUE; - m->best = cs; - m->distX = abs(m->targetX - x); - m->distY = abs(m->targetY - y); -} - -cairo_surface_t *imageAppropriateSurface(uiImage *i, GtkWidget *w) -{ - struct matcher m; - - m.best = NULL; - m.distX = G_MAXINT; - m.distY = G_MAXINT; - m.targetX = i->width * gtk_widget_get_scale_factor(w); - m.targetY = i->height * gtk_widget_get_scale_factor(w); - m.foundLarger = FALSE; - g_ptr_array_foreach(i->images, match, &m); - return m.best; -} diff --git a/deps/libui/unix/label.c b/deps/libui/unix/label.c deleted file mode 100644 index b39fc7ccd0..0000000000 --- a/deps/libui/unix/label.c +++ /dev/null @@ -1,36 +0,0 @@ -// 11 june 2015 -#include "uipriv_unix.h" - -struct uiLabel { - uiUnixControl c; - GtkWidget *widget; - GtkMisc *misc; - GtkLabel *label; -}; - -uiUnixControlAllDefaults(uiLabel) - -char *uiLabelText(uiLabel *l) -{ - return uiUnixStrdupText(gtk_label_get_text(l->label)); -} - -void uiLabelSetText(uiLabel *l, const char *text) -{ - gtk_label_set_text(l->label, text); -} - -uiLabel *uiNewLabel(const char *text) -{ - uiLabel *l; - - uiUnixNewControl(uiLabel, l); - - l->widget = gtk_label_new(text); - l->misc = GTK_MISC(l->widget); - l->label = GTK_LABEL(l->widget); - - gtk_misc_set_alignment(l->misc, 0, 0); - - return l; -} diff --git a/deps/libui/unix/main.c b/deps/libui/unix/main.c deleted file mode 100644 index 2998bf3194..0000000000 --- a/deps/libui/unix/main.c +++ /dev/null @@ -1,108 +0,0 @@ -// 6 april 2015 -#include "uipriv_unix.h" - -uiInitOptions options; - -const char *uiInit(uiInitOptions *o) -{ - GError *err = NULL; - const char *msg; - - options = *o; - if (gtk_init_with_args(NULL, NULL, NULL, NULL, NULL, &err) == FALSE) { - msg = g_strdup(err->message); - g_error_free(err); - return msg; - } - initAlloc(); - loadFutures(); - return NULL; -} - -void uiUninit(void) -{ - uninitMenus(); - uninitAlloc(); -} - -void uiFreeInitError(const char *err) -{ - g_free((gpointer) err); -} - -static gboolean (*iteration)(gboolean) = NULL; - -void uiMain(void) -{ - iteration = gtk_main_iteration_do; - gtk_main(); -} - -static gboolean stepsQuit = FALSE; - -// the only difference is we ignore the return value from gtk_main_iteration_do(), since it will always be TRUE if gtk_main() was never called -// gtk_main_iteration_do() will still run the main loop regardless -static gboolean stepsIteration(gboolean block) -{ - gtk_main_iteration_do(block); - return stepsQuit; -} - -void uiMainSteps(void) -{ - iteration = stepsIteration; -} - -int uiMainStep(int wait) -{ - gboolean block; - - block = FALSE; - if (wait) - block = TRUE; - return (*iteration)(block) == FALSE; -} - -// gtk_main_quit() may run immediately, or it may wait for other pending events; "it depends" (thanks mclasen in irc.gimp.net/#gtk+) -// PostQuitMessage() on Windows always waits, so we must do so too -// we'll do it by using an idle callback -static gboolean quit(gpointer data) -{ - if (iteration == stepsIteration) - stepsQuit = TRUE; - // TODO run a gtk_main() here just to do the cleanup steps of syncing the clipboard and other stuff gtk_main() does before it returns - else - gtk_main_quit(); - return FALSE; -} - -void uiQuit(void) -{ - gdk_threads_add_idle(quit, NULL); -} - -struct queued { - void (*f)(void *); - void *data; -}; - -static gboolean doqueued(gpointer data) -{ - struct queued *q = (struct queued *) data; - - (*(q->f))(q->data); - g_free(q); - return FALSE; -} - -void uiQueueMain(void (*f)(void *data), void *data) -{ - struct queued *q; - - // we have to use g_new0()/g_free() because uiAlloc() is only safe to call on the main thread - // for some reason it didn't affect me, but it did affect krakjoe - q = g_new0(struct queued, 1); - q->f = f; - q->data = data; - gdk_threads_add_idle(doqueued, q); -} diff --git a/deps/libui/unix/menu.c b/deps/libui/unix/menu.c deleted file mode 100644 index 5ccb4a51a3..0000000000 --- a/deps/libui/unix/menu.c +++ /dev/null @@ -1,366 +0,0 @@ -// 23 april 2015 -#include "uipriv_unix.h" - -static GArray *menus = NULL; -static gboolean menusFinalized = FALSE; -static gboolean hasQuit = FALSE; -static gboolean hasPreferences = FALSE; -static gboolean hasAbout = FALSE; - -struct uiMenu { - char *name; - GArray *items; // []*uiMenuItem -}; - -struct uiMenuItem { - char *name; - int type; - void (*onClicked)(uiMenuItem *, uiWindow *, void *); - void *onClickedData; - GType gtype; // template for new instances; kept in sync with everything else - gboolean disabled; - gboolean checked; - GHashTable *windows; // map[GtkMenuItem]*menuItemWindow -}; - -struct menuItemWindow { - uiWindow *w; - gulong signal; -}; - -enum { - typeRegular, - typeCheckbox, - typeQuit, - typePreferences, - typeAbout, - typeSeparator, -}; - -// we do NOT want programmatic updates to raise an ::activated signal -static void singleSetChecked(GtkCheckMenuItem *menuitem, gboolean checked, gulong signal) -{ - g_signal_handler_block(menuitem, signal); - gtk_check_menu_item_set_active(menuitem, checked); - g_signal_handler_unblock(menuitem, signal); -} - -static void setChecked(uiMenuItem *item, gboolean checked) -{ - GHashTableIter iter; - gpointer widget; - gpointer ww; - struct menuItemWindow *w; - - item->checked = checked; - g_hash_table_iter_init(&iter, item->windows); - while (g_hash_table_iter_next(&iter, &widget, &ww)) { - w = (struct menuItemWindow *) ww; - singleSetChecked(GTK_CHECK_MENU_ITEM(widget), item->checked, w->signal); - } -} - -static void onClicked(GtkMenuItem *menuitem, gpointer data) -{ - uiMenuItem *item = uiMenuItem(data); - struct menuItemWindow *w; - - // we need to manually update the checked states of all menu items if one changes - // notice that this is getting the checked state of the menu item that this signal is sent from - if (item->type == typeCheckbox) - setChecked(item, gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))); - - w = (struct menuItemWindow *) g_hash_table_lookup(item->windows, menuitem); - (*(item->onClicked))(item, w->w, item->onClickedData); -} - -static void defaultOnClicked(uiMenuItem *item, uiWindow *w, void *data) -{ - // do nothing -} - -static void onQuitClicked(uiMenuItem *item, uiWindow *w, void *data) -{ - if (shouldQuit()) - uiQuit(); -} - -static void menuItemEnableDisable(uiMenuItem *item, gboolean enabled) -{ - GHashTableIter iter; - gpointer widget; - - item->disabled = !enabled; - g_hash_table_iter_init(&iter, item->windows); - while (g_hash_table_iter_next(&iter, &widget, NULL)) - gtk_widget_set_sensitive(GTK_WIDGET(widget), enabled); -} - -void uiMenuItemEnable(uiMenuItem *item) -{ - menuItemEnableDisable(item, TRUE); -} - -void uiMenuItemDisable(uiMenuItem *item) -{ - menuItemEnableDisable(item, FALSE); -} - -void uiMenuItemOnClicked(uiMenuItem *item, void (*f)(uiMenuItem *, uiWindow *, void *), void *data) -{ - if (item->type == typeQuit) - userbug("You cannot call uiMenuItemOnClicked() on a Quit item; use uiOnShouldQuit() instead."); - item->onClicked = f; - item->onClickedData = data; -} - -int uiMenuItemChecked(uiMenuItem *item) -{ - return item->checked != FALSE; -} - -void uiMenuItemSetChecked(uiMenuItem *item, int checked) -{ - gboolean c; - - // use explicit values - c = FALSE; - if (checked) - c = TRUE; - setChecked(item, c); -} - -static uiMenuItem *newItem(uiMenu *m, int type, const char *name) -{ - uiMenuItem *item; - - if (menusFinalized) - userbug("You cannot create a new menu item after menus have been finalized."); - - item = uiNew(uiMenuItem); - - g_array_append_val(m->items, item); - - item->type = type; - switch (item->type) { - case typeQuit: - item->name = g_strdup("Quit"); - break; - case typePreferences: - item->name = g_strdup("Preferences..."); - break; - case typeAbout: - item->name = g_strdup("About"); - break; - case typeSeparator: - break; - default: - item->name = g_strdup(name); - break; - } - - if (item->type == typeQuit) { - // can't call uiMenuItemOnClicked() here - item->onClicked = onQuitClicked; - item->onClickedData = NULL; - } else - uiMenuItemOnClicked(item, defaultOnClicked, NULL); - - switch (item->type) { - case typeCheckbox: - item->gtype = GTK_TYPE_CHECK_MENU_ITEM; - break; - case typeSeparator: - item->gtype = GTK_TYPE_SEPARATOR_MENU_ITEM; - break; - default: - item->gtype = GTK_TYPE_MENU_ITEM; - break; - } - - item->windows = g_hash_table_new(g_direct_hash, g_direct_equal); - - return item; -} - -uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name) -{ - return newItem(m, typeRegular, name); -} - -uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const char *name) -{ - return newItem(m, typeCheckbox, name); -} - -uiMenuItem *uiMenuAppendQuitItem(uiMenu *m) -{ - if (hasQuit) - userbug("You cannot have multiple Quit menu items in the same program."); - hasQuit = TRUE; - newItem(m, typeSeparator, NULL); - return newItem(m, typeQuit, NULL); -} - -uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m) -{ - if (hasPreferences) - userbug("You cannot have multiple Preferences menu items in the same program."); - hasPreferences = TRUE; - newItem(m, typeSeparator, NULL); - return newItem(m, typePreferences, NULL); -} - -uiMenuItem *uiMenuAppendAboutItem(uiMenu *m) -{ - if (hasAbout) - userbug("You cannot have multiple About menu items in the same program."); - hasAbout = TRUE; - newItem(m, typeSeparator, NULL); - return newItem(m, typeAbout, NULL); -} - -void uiMenuAppendSeparator(uiMenu *m) -{ - newItem(m, typeSeparator, NULL); -} - -uiMenu *uiNewMenu(const char *name) -{ - uiMenu *m; - - if (menusFinalized) - userbug("You cannot create a new menu after menus have been finalized."); - if (menus == NULL) - menus = g_array_new(FALSE, TRUE, sizeof (uiMenu *)); - - m = uiNew(uiMenu); - - g_array_append_val(menus, m); - - m->name = g_strdup(name); - m->items = g_array_new(FALSE, TRUE, sizeof (uiMenuItem *)); - - return m; -} - -static void appendMenuItem(GtkMenuShell *submenu, uiMenuItem *item, uiWindow *w) -{ - GtkWidget *menuitem; - gulong signal; - struct menuItemWindow *ww; - - menuitem = g_object_new(item->gtype, NULL); - if (item->name != NULL) - gtk_menu_item_set_label(GTK_MENU_ITEM(menuitem), item->name); - if (item->type != typeSeparator) { - signal = g_signal_connect(menuitem, "activate", G_CALLBACK(onClicked), item); - gtk_widget_set_sensitive(menuitem, !item->disabled); - if (item->type == typeCheckbox) - singleSetChecked(GTK_CHECK_MENU_ITEM(menuitem), item->checked, signal); - } - gtk_menu_shell_append(submenu, menuitem); - ww = uiNew(struct menuItemWindow); - ww->w = w; - ww->signal = signal; - g_hash_table_insert(item->windows, menuitem, ww); -} - -GtkWidget *makeMenubar(uiWindow *w) -{ - GtkWidget *menubar; - guint i, j; - uiMenu *m; - GtkWidget *menuitem; - GtkWidget *submenu; - - menusFinalized = TRUE; - - menubar = gtk_menu_bar_new(); - - if (menus != NULL) - for (i = 0; i < menus->len; i++) { - m = g_array_index(menus, uiMenu *, i); - menuitem = gtk_menu_item_new_with_label(m->name); - submenu = gtk_menu_new(); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); - for (j = 0; j < m->items->len; j++) - appendMenuItem(GTK_MENU_SHELL(submenu), g_array_index(m->items, uiMenuItem *, j), w); - gtk_menu_shell_append(GTK_MENU_SHELL(menubar), menuitem); - } - - gtk_widget_set_hexpand(menubar, TRUE); - gtk_widget_set_halign(menubar, GTK_ALIGN_FILL); - return menubar; -} - -struct freeMenuItemData { - GArray *items; - guint i; -}; - -static void freeMenuItem(GtkWidget *widget, gpointer data) -{ - struct freeMenuItemData *fmi = (struct freeMenuItemData *) data; - uiMenuItem *item; - struct menuItemWindow *w; - - item = g_array_index(fmi->items, uiMenuItem *, fmi->i); - w = (struct menuItemWindow *) g_hash_table_lookup(item->windows, widget); - if (g_hash_table_remove(item->windows, widget) == FALSE) - implbug("GtkMenuItem %p not in menu item's item/window map", widget); - uiFree(w); - fmi->i++; -} - -static void freeMenu(GtkWidget *widget, gpointer data) -{ - guint *i = (guint *) data; - uiMenu *m; - GtkMenuItem *item; - GtkWidget *submenu; - struct freeMenuItemData fmi; - - m = g_array_index(menus, uiMenu *, *i); - item = GTK_MENU_ITEM(widget); - submenu = gtk_menu_item_get_submenu(item); - fmi.items = m->items; - fmi.i = 0; - gtk_container_foreach(GTK_CONTAINER(submenu), freeMenuItem, &fmi); - (*i)++; -} - -void freeMenubar(GtkWidget *mb) -{ - guint i; - - i = 0; - gtk_container_foreach(GTK_CONTAINER(mb), freeMenu, &i); - // no need to worry about destroying any widgets; destruction of the window they're in will do it for us -} - -void uninitMenus(void) -{ - uiMenu *m; - uiMenuItem *item; - guint i, j; - - if (menus == NULL) - return; - for (i = 0; i < menus->len; i++) { - m = g_array_index(menus, uiMenu *, i); - g_free(m->name); - for (j = 0; j < m->items->len; j++) { - item = g_array_index(m->items, uiMenuItem *, j); - if (g_hash_table_size(item->windows) != 0) - // TODO is this really a userbug()? - implbug("menu item %p (%s) still has uiWindows attached; did you forget to destroy some windows?", item, item->name); - g_free(item->name); - g_hash_table_destroy(item->windows); - uiFree(item); - } - g_array_free(m->items, TRUE); - uiFree(m); - } - g_array_free(menus, TRUE); -} diff --git a/deps/libui/unix/multilineentry.c b/deps/libui/unix/multilineentry.c deleted file mode 100644 index 09ffd46014..0000000000 --- a/deps/libui/unix/multilineentry.c +++ /dev/null @@ -1,124 +0,0 @@ -// 6 december 2015 -#include "uipriv_unix.h" - -struct uiMultilineEntry { - uiUnixControl c; - GtkWidget *widget; - GtkContainer *scontainer; - GtkScrolledWindow *sw; - GtkWidget *textviewWidget; - GtkTextView *textview; - GtkTextBuffer *textbuf; - void (*onChanged)(uiMultilineEntry *, void *); - void *onChangedData; - gulong onChangedSignal; -}; - -uiUnixControlAllDefaults(uiMultilineEntry) - -static void onChanged(GtkTextBuffer *textbuf, gpointer data) -{ - uiMultilineEntry *e = uiMultilineEntry(data); - - (*(e->onChanged))(e, e->onChangedData); -} - -static void defaultOnChanged(uiMultilineEntry *e, void *data) -{ - // do nothing -} - -char *uiMultilineEntryText(uiMultilineEntry *e) -{ - GtkTextIter start, end; - char *tret, *out; - - gtk_text_buffer_get_start_iter(e->textbuf, &start); - gtk_text_buffer_get_end_iter(e->textbuf, &end); - tret = gtk_text_buffer_get_text(e->textbuf, &start, &end, TRUE); - // theoretically we could just return tret because uiUnixStrdupText() is just g_strdup(), but if that ever changes we can't, so let's do it this way to be safe - out = uiUnixStrdupText(tret); - g_free(tret); - return out; -} - -void uiMultilineEntrySetText(uiMultilineEntry *e, const char *text) -{ - // we need to inhibit sending of ::changed because this WILL send a ::changed otherwise - g_signal_handler_block(e->textbuf, e->onChangedSignal); - gtk_text_buffer_set_text(e->textbuf, text, -1); - g_signal_handler_unblock(e->textbuf, e->onChangedSignal); -} - -// TODO scroll to end? -void uiMultilineEntryAppend(uiMultilineEntry *e, const char *text) -{ - GtkTextIter end; - - gtk_text_buffer_get_end_iter(e->textbuf, &end); - // we need to inhibit sending of ::changed because this WILL send a ::changed otherwise - g_signal_handler_block(e->textbuf, e->onChangedSignal); - gtk_text_buffer_insert(e->textbuf, &end, text, -1); - g_signal_handler_unblock(e->textbuf, e->onChangedSignal); -} - -void uiMultilineEntryOnChanged(uiMultilineEntry *e, void (*f)(uiMultilineEntry *e, void *data), void *data) -{ - e->onChanged = f; - e->onChangedData = data; -} - -int uiMultilineEntryReadOnly(uiMultilineEntry *e) -{ - return gtk_text_view_get_editable(e->textview) == FALSE; -} - -void uiMultilineEntrySetReadOnly(uiMultilineEntry *e, int readonly) -{ - gboolean editable; - - editable = TRUE; - if (readonly) - editable = FALSE; - gtk_text_view_set_editable(e->textview, editable); -} - -static uiMultilineEntry *finishMultilineEntry(GtkPolicyType hpolicy, GtkWrapMode wrapMode) -{ - uiMultilineEntry *e; - - uiUnixNewControl(uiMultilineEntry, e); - - e->widget = gtk_scrolled_window_new(NULL, NULL); - e->scontainer = GTK_CONTAINER(e->widget); - e->sw = GTK_SCROLLED_WINDOW(e->widget); - gtk_scrolled_window_set_policy(e->sw, - hpolicy, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(e->sw, GTK_SHADOW_IN); - - e->textviewWidget = gtk_text_view_new(); - e->textview = GTK_TEXT_VIEW(e->textviewWidget); - gtk_text_view_set_wrap_mode(e->textview, wrapMode); - - gtk_container_add(e->scontainer, e->textviewWidget); - // and make the text view visible; only the scrolled window's visibility is controlled by libui - gtk_widget_show(e->textviewWidget); - - e->textbuf = gtk_text_view_get_buffer(e->textview); - - e->onChangedSignal = g_signal_connect(e->textbuf, "changed", G_CALLBACK(onChanged), e); - uiMultilineEntryOnChanged(e, defaultOnChanged, NULL); - - return e; -} - -uiMultilineEntry *uiNewMultilineEntry(void) -{ - return finishMultilineEntry(GTK_POLICY_NEVER, GTK_WRAP_WORD); -} - -uiMultilineEntry *uiNewNonWrappingMultilineEntry(void) -{ - return finishMultilineEntry(GTK_POLICY_AUTOMATIC, GTK_WRAP_NONE); -} diff --git a/deps/libui/unix/progressbar.c b/deps/libui/unix/progressbar.c deleted file mode 100644 index 9b543b04ad..0000000000 --- a/deps/libui/unix/progressbar.c +++ /dev/null @@ -1,71 +0,0 @@ -// 11 june 2015 -#include "uipriv_unix.h" - -struct uiProgressBar { - uiUnixControl c; - GtkWidget *widget; - GtkProgressBar *pbar; - gboolean indeterminate; - guint pulser; -}; - -uiUnixControlAllDefaultsExceptDestroy(uiProgressBar) - -static void uiProgressBarDestroy(uiControl *c) -{ - uiProgressBar *p = uiProgressBar(c); - - // be sure to stop the timeout now - if (p->indeterminate) - g_source_remove(p->pulser); - g_object_unref(p->widget); - uiFreeControl(uiControl(p)); -} - -int uiProgressBarValue(uiProgressBar *p) -{ - if (p->indeterminate) - return -1; - return (int) (gtk_progress_bar_get_fraction(p->pbar) * 100); -} - -static gboolean pulse(void* data) -{ - uiProgressBar *p = uiProgressBar(data); - - gtk_progress_bar_pulse(p->pbar); - return TRUE; -} - -void uiProgressBarSetValue(uiProgressBar *p, int value) -{ - if (value == -1) { - if (!p->indeterminate) { - p->indeterminate = TRUE; - // TODO verify the timeout - p->pulser = g_timeout_add(100, pulse, p); - } - return; - } - if (p->indeterminate) { - p->indeterminate = FALSE; - g_source_remove(p->pulser); - } - - if (value < 0 || value > 100) - userbug("Value %d is out of range for a uiProgressBar.", value); - - gtk_progress_bar_set_fraction(p->pbar, ((gdouble) value) / 100); -} - -uiProgressBar *uiNewProgressBar(void) -{ - uiProgressBar *p; - - uiUnixNewControl(uiProgressBar, p); - - p->widget = gtk_progress_bar_new(); - p->pbar = GTK_PROGRESS_BAR(p->widget); - - return p; -} diff --git a/deps/libui/unix/radiobuttons.c b/deps/libui/unix/radiobuttons.c deleted file mode 100644 index da41107e8c..0000000000 --- a/deps/libui/unix/radiobuttons.c +++ /dev/null @@ -1,121 +0,0 @@ -// 11 june 2015 -#include "uipriv_unix.h" - -// on GTK+ a uiRadioButtons is a GtkBox with each of the GtkRadioButtons as children - -struct uiRadioButtons { - uiUnixControl c; - GtkWidget *widget; - GtkContainer *container; - GtkBox *box; - GPtrArray *buttons; - void (*onSelected)(uiRadioButtons *, void *); - void *onSelectedData; - gboolean changing; -}; - -uiUnixControlAllDefaultsExceptDestroy(uiRadioButtons) - -static void defaultOnSelected(uiRadioButtons *r, void *data) -{ - // do nothing -} - -static void onToggled(GtkToggleButton *tb, gpointer data) -{ - uiRadioButtons *r = uiRadioButtons(data); - - // only care if a button is selected - if (!gtk_toggle_button_get_active(tb)) - return; - // ignore programmatic changes - if (r->changing) - return; - (*(r->onSelected))(r, r->onSelectedData); -} - -static void uiRadioButtonsDestroy(uiControl *c) -{ - uiRadioButtons *r = uiRadioButtons(c); - GtkWidget *b; - - while (r->buttons->len != 0) { - b = GTK_WIDGET(g_ptr_array_remove_index(r->buttons, 0)); - gtk_widget_destroy(b); - } - g_ptr_array_free(r->buttons, TRUE); - // and free ourselves - g_object_unref(r->widget); - uiFreeControl(uiControl(r)); -} - -void uiRadioButtonsAppend(uiRadioButtons *r, const char *text) -{ - GtkWidget *rb; - GtkRadioButton *previous; - - previous = NULL; - if (r->buttons->len > 0) - previous = GTK_RADIO_BUTTON(g_ptr_array_index(r->buttons, 0)); - rb = gtk_radio_button_new_with_label_from_widget(previous, text); - g_signal_connect(rb, "toggled", G_CALLBACK(onToggled), r); - gtk_container_add(r->container, rb); - g_ptr_array_add(r->buttons, rb); - gtk_widget_show(rb); -} - -int uiRadioButtonsSelected(uiRadioButtons *r) -{ - GtkToggleButton *tb; - guint i; - - for (i = 0; i < r->buttons->len; i++) { - tb = GTK_TOGGLE_BUTTON(g_ptr_array_index(r->buttons, i)); - if (gtk_toggle_button_get_active(tb)) - return i; - } - return -1; -} - -void uiRadioButtonsSetSelected(uiRadioButtons *r, int n) -{ - GtkToggleButton *tb; - gboolean active; - - active = TRUE; - // TODO this doesn't work - if (n == -1) { - n = uiRadioButtonsSelected(r); - if (n == -1) // no selection; keep it that way - return; - active = FALSE; - } - tb = GTK_TOGGLE_BUTTON(g_ptr_array_index(r->buttons, n)); - // this is easier than remembering all the signals - r->changing = TRUE; - gtk_toggle_button_set_active(tb, active); - r->changing = FALSE; -} - -void uiRadioButtonsOnSelected(uiRadioButtons *r, void (*f)(uiRadioButtons *, void *), void *data) -{ - r->onSelected = f; - r->onSelectedData = data; -} - -uiRadioButtons *uiNewRadioButtons(void) -{ - uiRadioButtons *r; - - uiUnixNewControl(uiRadioButtons, r); - - r->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - r->container = GTK_CONTAINER(r->widget); - r->box = GTK_BOX(r->widget); - - r->buttons = g_ptr_array_new(); - - uiRadioButtonsOnSelected(r, defaultOnSelected, NULL); - - return r; -} diff --git a/deps/libui/unix/separator.c b/deps/libui/unix/separator.c deleted file mode 100644 index 02c75da536..0000000000 --- a/deps/libui/unix/separator.c +++ /dev/null @@ -1,34 +0,0 @@ -// 11 june 2015 -#include "uipriv_unix.h" - -struct uiSeparator { - uiUnixControl c; - GtkWidget *widget; - GtkSeparator *separator; -}; - -uiUnixControlAllDefaults(uiSeparator) - -uiSeparator *uiNewHorizontalSeparator(void) -{ - uiSeparator *s; - - uiUnixNewControl(uiSeparator, s); - - s->widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL); - s->separator = GTK_SEPARATOR(s->widget); - - return s; -} - -uiSeparator *uiNewVerticalSeparator(void) -{ - uiSeparator *s; - - uiUnixNewControl(uiSeparator, s); - - s->widget = gtk_separator_new(GTK_ORIENTATION_VERTICAL); - s->separator = GTK_SEPARATOR(s->widget); - - return s; -} diff --git a/deps/libui/unix/slider.c b/deps/libui/unix/slider.c deleted file mode 100644 index 7f0cc24a18..0000000000 --- a/deps/libui/unix/slider.c +++ /dev/null @@ -1,71 +0,0 @@ -// 11 june 2015 -#include "uipriv_unix.h" - -struct uiSlider { - uiUnixControl c; - GtkWidget *widget; - GtkRange *range; - GtkScale *scale; - void (*onChanged)(uiSlider *, void *); - void *onChangedData; - gulong onChangedSignal; -}; - -uiUnixControlAllDefaults(uiSlider) - -static void onChanged(GtkRange *range, gpointer data) -{ - uiSlider *s = uiSlider(data); - - (*(s->onChanged))(s, s->onChangedData); -} - -static void defaultOnChanged(uiSlider *s, void *data) -{ - // do nothing -} - -int uiSliderValue(uiSlider *s) -{ - return gtk_range_get_value(s->range); -} - -void uiSliderSetValue(uiSlider *s, int value) -{ - // we need to inhibit sending of ::value-changed because this WILL send a ::value-changed otherwise - g_signal_handler_block(s->range, s->onChangedSignal); - gtk_range_set_value(s->range, value); - g_signal_handler_unblock(s->range, s->onChangedSignal); -} - -void uiSliderOnChanged(uiSlider *s, void (*f)(uiSlider *, void *), void *data) -{ - s->onChanged = f; - s->onChangedData = data; -} - -uiSlider *uiNewSlider(int min, int max) -{ - uiSlider *s; - int temp; - - if (min >= max) { - temp = min; - min = max; - max = temp; - } - - uiUnixNewControl(uiSlider, s); - - s->widget = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, min, max, 1); - s->range = GTK_RANGE(s->widget); - s->scale = GTK_SCALE(s->widget); - - // ensure integers, just to be safe - gtk_scale_set_digits(s->scale, 0); - - s->onChangedSignal = g_signal_connect(s->scale, "value-changed", G_CALLBACK(onChanged), s); - uiSliderOnChanged(s, defaultOnChanged, NULL); - - return s; -} diff --git a/deps/libui/unix/spinbox.c b/deps/libui/unix/spinbox.c deleted file mode 100644 index 90a5d3c1db..0000000000 --- a/deps/libui/unix/spinbox.c +++ /dev/null @@ -1,72 +0,0 @@ -// 11 june 2015 -#include "uipriv_unix.h" - -struct uiSpinbox { - uiUnixControl c; - GtkWidget *widget; - GtkEntry *entry; - GtkSpinButton *spinButton; - void (*onChanged)(uiSpinbox *, void *); - void *onChangedData; - gulong onChangedSignal; -}; - -uiUnixControlAllDefaults(uiSpinbox) - -static void onChanged(GtkSpinButton *sb, gpointer data) -{ - uiSpinbox *s = uiSpinbox(data); - - (*(s->onChanged))(s, s->onChangedData); -} - -static void defaultOnChanged(uiSpinbox *s, void *data) -{ - // do nothing -} - -int uiSpinboxValue(uiSpinbox *s) -{ - return gtk_spin_button_get_value(s->spinButton); -} - -void uiSpinboxSetValue(uiSpinbox *s, int value) -{ - // we need to inhibit sending of ::value-changed because this WILL send a ::value-changed otherwise - g_signal_handler_block(s->spinButton, s->onChangedSignal); - // this clamps for us - gtk_spin_button_set_value(s->spinButton, (gdouble) value); - g_signal_handler_unblock(s->spinButton, s->onChangedSignal); -} - -void uiSpinboxOnChanged(uiSpinbox *s, void (*f)(uiSpinbox *, void *), void *data) -{ - s->onChanged = f; - s->onChangedData = data; -} - -uiSpinbox *uiNewSpinbox(int min, int max) -{ - uiSpinbox *s; - int temp; - - if (min >= max) { - temp = min; - min = max; - max = temp; - } - - uiUnixNewControl(uiSpinbox, s); - - s->widget = gtk_spin_button_new_with_range(min, max, 1); - s->entry = GTK_ENTRY(s->widget); - s->spinButton = GTK_SPIN_BUTTON(s->widget); - - // ensure integers, just to be safe - gtk_spin_button_set_digits(s->spinButton, 0); - - s->onChangedSignal = g_signal_connect(s->spinButton, "value-changed", G_CALLBACK(onChanged), s); - uiSpinboxOnChanged(s, defaultOnChanged, NULL); - - return s; -} diff --git a/deps/libui/unix/stddialogs.c b/deps/libui/unix/stddialogs.c deleted file mode 100644 index 93302f75e8..0000000000 --- a/deps/libui/unix/stddialogs.c +++ /dev/null @@ -1,66 +0,0 @@ -// 26 june 2015 -#include "uipriv_unix.h" - -// LONGTERM figure out why, and describe, that this is the desired behavior -// LONGTERM also point out that font and color buttons also work like this - -#define windowWindow(w) (GTK_WINDOW(uiControlHandle(uiControl(w)))) - -static char *filedialog(GtkWindow *parent, GtkFileChooserAction mode, const gchar *confirm) -{ - GtkWidget *fcd; - GtkFileChooser *fc; - gint response; - char *filename; - - fcd = gtk_file_chooser_dialog_new(NULL, parent, mode, - "_Cancel", GTK_RESPONSE_CANCEL, - confirm, GTK_RESPONSE_ACCEPT, - NULL); - fc = GTK_FILE_CHOOSER(fcd); - gtk_file_chooser_set_local_only(fc, FALSE); - gtk_file_chooser_set_select_multiple(fc, FALSE); - gtk_file_chooser_set_show_hidden(fc, TRUE); - gtk_file_chooser_set_do_overwrite_confirmation(fc, TRUE); - gtk_file_chooser_set_create_folders(fc, TRUE); - response = gtk_dialog_run(GTK_DIALOG(fcd)); - if (response != GTK_RESPONSE_ACCEPT) { - gtk_widget_destroy(fcd); - return NULL; - } - filename = uiUnixStrdupText(gtk_file_chooser_get_filename(fc)); - gtk_widget_destroy(fcd); - return filename; -} - -char *uiOpenFile(uiWindow *parent) -{ - return filedialog(windowWindow(parent), GTK_FILE_CHOOSER_ACTION_OPEN, "_Open"); -} - -char *uiSaveFile(uiWindow *parent) -{ - return filedialog(windowWindow(parent), GTK_FILE_CHOOSER_ACTION_SAVE, "_Save"); -} - -static void msgbox(GtkWindow *parent, const char *title, const char *description, GtkMessageType type, GtkButtonsType buttons) -{ - GtkWidget *md; - - md = gtk_message_dialog_new(parent, GTK_DIALOG_MODAL, - type, buttons, - "%s", title); - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(md), "%s", description); - gtk_dialog_run(GTK_DIALOG(md)); - gtk_widget_destroy(md); -} - -void uiMsgBox(uiWindow *parent, const char *title, const char *description) -{ - msgbox(windowWindow(parent), title, description, GTK_MESSAGE_OTHER, GTK_BUTTONS_OK); -} - -void uiMsgBoxError(uiWindow *parent, const char *title, const char *description) -{ - msgbox(windowWindow(parent), title, description, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK); -} diff --git a/deps/libui/unix/tab.c b/deps/libui/unix/tab.c deleted file mode 100644 index 552e0e31a5..0000000000 --- a/deps/libui/unix/tab.c +++ /dev/null @@ -1,97 +0,0 @@ -// 11 june 2015 -#include "uipriv_unix.h" - -struct uiTab { - uiUnixControl c; - - GtkWidget *widget; - GtkContainer *container; - GtkNotebook *notebook; - - GArray *pages; // []*struct child -}; - -uiUnixControlAllDefaultsExceptDestroy(uiTab) - -static void uiTabDestroy(uiControl *c) -{ - uiTab *t = uiTab(c); - guint i; - struct child *page; - - for (i = 0; i < t->pages->len; i++) { - page = g_array_index(t->pages, struct child *, i); - childDestroy(page); - } - g_array_free(t->pages, TRUE); - // and free ourselves - g_object_unref(t->widget); - uiFreeControl(uiControl(t)); -} - -void uiTabAppend(uiTab *t, const char *name, uiControl *child) -{ - uiTabInsertAt(t, name, t->pages->len, child); -} - -void uiTabInsertAt(uiTab *t, const char *name, int n, uiControl *child) -{ - struct child *page; - - // this will create a tab, because of gtk_container_add() - page = newChildWithBox(child, uiControl(t), t->container, 0); - - gtk_notebook_set_tab_label_text(t->notebook, childBox(page), name); - gtk_notebook_reorder_child(t->notebook, childBox(page), n); - - g_array_insert_val(t->pages, n, page); -} - -void uiTabDelete(uiTab *t, int n) -{ - struct child *page; - - page = g_array_index(t->pages, struct child *, n); - // this will remove the tab, because gtk_widget_destroy() calls gtk_container_remove() - childRemove(page); - g_array_remove_index(t->pages, n); -} - -int uiTabNumPages(uiTab *t) -{ - return t->pages->len; -} - -int uiTabMargined(uiTab *t, int n) -{ - struct child *page; - - page = g_array_index(t->pages, struct child *, n); - return childFlag(page); -} - -void uiTabSetMargined(uiTab *t, int n, int margined) -{ - struct child *page; - - page = g_array_index(t->pages, struct child *, n); - childSetFlag(page, margined); - childSetMargined(page, childFlag(page)); -} - -uiTab *uiNewTab(void) -{ - uiTab *t; - - uiUnixNewControl(uiTab, t); - - t->widget = gtk_notebook_new(); - t->container = GTK_CONTAINER(t->widget); - t->notebook = GTK_NOTEBOOK(t->widget); - - gtk_notebook_set_scrollable(t->notebook, TRUE); - - t->pages = g_array_new(FALSE, TRUE, sizeof (struct child *)); - - return t; -} diff --git a/deps/libui/unix/text.c b/deps/libui/unix/text.c deleted file mode 100644 index ad92738d4a..0000000000 --- a/deps/libui/unix/text.c +++ /dev/null @@ -1,12 +0,0 @@ -// 9 april 2015 -#include "uipriv_unix.h" - -char *uiUnixStrdupText(const char *t) -{ - return g_strdup(t); -} - -void uiFreeText(char *t) -{ - g_free(t); -} diff --git a/deps/libui/unix/uipriv_unix.h b/deps/libui/unix/uipriv_unix.h deleted file mode 100644 index 33ff1e3553..0000000000 --- a/deps/libui/unix/uipriv_unix.h +++ /dev/null @@ -1,65 +0,0 @@ -// 22 april 2015 -#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_40 -#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_40 -#define GDK_VERSION_MIN_REQUIRED GDK_VERSION_3_10 -#define GDK_VERSION_MAX_ALLOWED GDK_VERSION_3_10 -#include -#include -#include // see drawtext.c -#include -#include -#include -#include "../ui.h" -#include "../ui_unix.h" -#include "../common/uipriv.h" - -#define gtkXMargin 12 -#define gtkYMargin 12 -#define gtkXPadding 12 -#define gtkYPadding 6 - -// menu.c -extern GtkWidget *makeMenubar(uiWindow *); -extern void freeMenubar(GtkWidget *); -extern void uninitMenus(void); - -// alloc.c -extern void initAlloc(void); -extern void uninitAlloc(void); - -// util.c -extern void setMargined(GtkContainer *, int); - -// child.c -extern struct child *newChild(uiControl *child, uiControl *parent, GtkContainer *parentContainer); -extern struct child *newChildWithBox(uiControl *child, uiControl *parent, GtkContainer *parentContainer, int margined); -extern void childRemove(struct child *c); -extern void childDestroy(struct child *c); -extern GtkWidget *childWidget(struct child *c); -extern int childFlag(struct child *c); -extern void childSetFlag(struct child *c, int flag); -extern GtkWidget *childBox(struct child *c); -extern void childSetMargined(struct child *c, int margined); - -// draw.c -extern uiDrawContext *newContext(cairo_t *); -extern void freeContext(uiDrawContext *); - -// drawtext.c -extern uiDrawTextFont *mkTextFont(PangoFont *f, gboolean add); -extern PangoFont *pangoDescToPangoFont(PangoFontDescription *pdesc); - -// graphemes.c -extern ptrdiff_t *graphemes(const char *text, PangoContext *context); - -// image.c -/*TODO remove this*/typedef struct uiImage uiImage; -extern cairo_surface_t *imageAppropriateSurface(uiImage *i, GtkWidget *w); - -// cellrendererbutton.c -extern GtkCellRenderer *newCellRendererButton(void); - -// future.c -extern void loadFutures(void); -extern PangoAttribute *FUTURE_pango_attr_foreground_alpha_new(guint16 alpha); -extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, gint pos, const char *name); diff --git a/deps/libui/unix/util.c b/deps/libui/unix/util.c deleted file mode 100644 index 7f4f43fb4a..0000000000 --- a/deps/libui/unix/util.c +++ /dev/null @@ -1,10 +0,0 @@ -// 18 april 2015 -#include "uipriv_unix.h" - -void setMargined(GtkContainer *c, int margined) -{ - if (margined) - gtk_container_set_border_width(c, gtkXMargin); - else - gtk_container_set_border_width(c, 0); -} diff --git a/deps/libui/unix/window.c b/deps/libui/unix/window.c deleted file mode 100644 index ea9ba370f4..0000000000 --- a/deps/libui/unix/window.c +++ /dev/null @@ -1,279 +0,0 @@ -// 11 june 2015 -#include "uipriv_unix.h" - -struct uiWindow { - uiUnixControl c; - - GtkWidget *widget; - GtkContainer *container; - GtkWindow *window; - - GtkWidget *vboxWidget; - GtkContainer *vboxContainer; - GtkBox *vbox; - - GtkWidget *childHolderWidget; - GtkContainer *childHolderContainer; - - GtkWidget *menubar; - - uiControl *child; - int margined; - - int (*onClosing)(uiWindow *, void *); - void *onClosingData; - void (*onContentSizeChanged)(uiWindow *, void *); - void *onContentSizeChangedData; - gboolean fullscreen; -}; - -static gboolean onClosing(GtkWidget *win, GdkEvent *e, gpointer data) -{ - uiWindow *w = uiWindow(data); - - // manually destroy the window ourselves; don't let the delete-event handler do it - if ((*(w->onClosing))(w, w->onClosingData)) - uiControlDestroy(uiControl(w)); - // don't continue to the default delete-event handler; we destroyed the window by now - return TRUE; -} - -static void onSizeAllocate(GtkWidget *widget, GdkRectangle *allocation, gpointer data) -{ - uiWindow *w = uiWindow(data); - - // TODO deal with spurious size-allocates - (*(w->onContentSizeChanged))(w, w->onContentSizeChangedData); -} - -static int defaultOnClosing(uiWindow *w, void *data) -{ - return 0; -} - -static void defaultOnPositionContentSizeChanged(uiWindow *w, void *data) -{ - // do nothing -} - -static void uiWindowDestroy(uiControl *c) -{ - uiWindow *w = uiWindow(c); - - // first hide ourselves - gtk_widget_hide(w->widget); - // now destroy the child - if (w->child != NULL) { - uiControlSetParent(w->child, NULL); - uiUnixControlSetContainer(uiUnixControl(w->child), w->childHolderContainer, TRUE); - uiControlDestroy(w->child); - } - // now destroy the menus, if any - if (w->menubar != NULL) - freeMenubar(w->menubar); - gtk_widget_destroy(w->childHolderWidget); - gtk_widget_destroy(w->vboxWidget); - // and finally free ourselves - // use gtk_widget_destroy() instead of g_object_unref() because GTK+ has internal references (see #165) - gtk_widget_destroy(w->widget); - uiFreeControl(uiControl(w)); -} - -uiUnixControlDefaultHandle(uiWindow) - -uiControl *uiWindowParent(uiControl *c) -{ - return NULL; -} - -void uiWindowSetParent(uiControl *c, uiControl *parent) -{ - uiUserBugCannotSetParentOnToplevel("uiWindow"); -} - -static int uiWindowToplevel(uiControl *c) -{ - return 1; -} - -uiUnixControlDefaultVisible(uiWindow) - -static void uiWindowShow(uiControl *c) -{ - uiWindow *w = uiWindow(c); - - // don't use gtk_widget_show_all() as that will show all children, regardless of user settings - // don't use gtk_widget_show(); that doesn't bring to front or give keyboard focus - // (gtk_window_present() does call gtk_widget_show() though) - gtk_window_present(w->window); -} - -uiUnixControlDefaultHide(uiWindow) -uiUnixControlDefaultEnabled(uiWindow) -uiUnixControlDefaultEnable(uiWindow) -uiUnixControlDefaultDisable(uiWindow) -// TODO? -uiUnixControlDefaultSetContainer(uiWindow) - -char *uiWindowTitle(uiWindow *w) -{ - return uiUnixStrdupText(gtk_window_get_title(w->window)); -} - -void uiWindowSetTitle(uiWindow *w, const char *title) -{ - gtk_window_set_title(w->window, title); -} - -void uiWindowContentSize(uiWindow *w, int *width, int *height) -{ - GtkAllocation allocation; - - gtk_widget_get_allocation(w->childHolderWidget, &allocation); - *width = allocation.width; - *height = allocation.height; -} - -void uiWindowSetContentSize(uiWindow *w, int width, int height) -{ - GtkAllocation childAlloc; - gint winWidth, winHeight; - - // we need to resize the child holder widget to the given size - // we can't resize that without running the event loop - // but we can do gtk_window_set_size() - // so how do we deal with the differences in sizes? - // simple arithmetic, of course! - - // from what I can tell, the return from gtk_widget_get_allocation(w->window) and gtk_window_get_size(w->window) will be the same - // this is not affected by Wayland and not affected by GTK+ builtin CSD - // so we can safely juse use them to get the real window size! - // since we're using gtk_window_resize(), use the latter - gtk_window_get_size(w->window, &winWidth, &winHeight); - - // now get the child holder widget's current allocation - gtk_widget_get_allocation(w->childHolderWidget, &childAlloc); - // and punch that out of the window size - winWidth -= childAlloc.width; - winHeight -= childAlloc.height; - - // now we just need to add the new size back in - winWidth += width; - winHeight += height; - // and set it - // this will not move the window in my tests, so we're good - gtk_window_resize(w->window, winWidth, winHeight); -} - -int uiWindowFullscreen(uiWindow *w) -{ - return w->fullscreen; -} - -// TODO use window-state-event to track -// TODO does this send an extra size changed? -// TODO what behavior do we want? -void uiWindowSetFullscreen(uiWindow *w, int fullscreen) -{ - w->fullscreen = fullscreen; - if (w->fullscreen) - gtk_window_fullscreen(w->window); - else - gtk_window_unfullscreen(w->window); -} - -void uiWindowOnContentSizeChanged(uiWindow *w, void (*f)(uiWindow *, void *), void *data) -{ - w->onContentSizeChanged = f; - w->onContentSizeChangedData = data; -} - -void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *, void *), void *data) -{ - w->onClosing = f; - w->onClosingData = data; -} - -int uiWindowBorderless(uiWindow *w) -{ - return gtk_window_get_decorated(w->window) == FALSE; -} - -void uiWindowSetBorderless(uiWindow *w, int borderless) -{ - gtk_window_set_decorated(w->window, borderless == 0); -} - -// TODO save and restore expands and aligns -void uiWindowSetChild(uiWindow *w, uiControl *child) -{ - if (w->child != NULL) { - uiControlSetParent(w->child, NULL); - uiUnixControlSetContainer(uiUnixControl(w->child), w->childHolderContainer, TRUE); - } - w->child = child; - if (w->child != NULL) { - uiControlSetParent(w->child, uiControl(w)); - uiUnixControlSetContainer(uiUnixControl(w->child), w->childHolderContainer, FALSE); - } -} - -int uiWindowMargined(uiWindow *w) -{ - return w->margined; -} - -void uiWindowSetMargined(uiWindow *w, int margined) -{ - w->margined = margined; - setMargined(w->childHolderContainer, w->margined); -} - -uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar) -{ - uiWindow *w; - - uiUnixNewControl(uiWindow, w); - - w->widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); - w->container = GTK_CONTAINER(w->widget); - w->window = GTK_WINDOW(w->widget); - - gtk_window_set_title(w->window, title); - gtk_window_resize(w->window, width, height); - - w->vboxWidget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - w->vboxContainer = GTK_CONTAINER(w->vboxWidget); - w->vbox = GTK_BOX(w->vboxWidget); - - // set the vbox as the GtkWindow child - gtk_container_add(w->container, w->vboxWidget); - - if (hasMenubar) { - w->menubar = makeMenubar(uiWindow(w)); - gtk_container_add(w->vboxContainer, w->menubar); - } - - w->childHolderWidget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - w->childHolderContainer = GTK_CONTAINER(w->childHolderWidget); - gtk_widget_set_hexpand(w->childHolderWidget, TRUE); - gtk_widget_set_halign(w->childHolderWidget, GTK_ALIGN_FILL); - gtk_widget_set_vexpand(w->childHolderWidget, TRUE); - gtk_widget_set_valign(w->childHolderWidget, GTK_ALIGN_FILL); - gtk_container_add(w->vboxContainer, w->childHolderWidget); - - // show everything in the vbox, but not the GtkWindow itself - gtk_widget_show_all(w->vboxWidget); - - // and connect our events - g_signal_connect(w->widget, "delete-event", G_CALLBACK(onClosing), w); - g_signal_connect(w->childHolderWidget, "size-allocate", G_CALLBACK(onSizeAllocate), w); - uiWindowOnClosing(w, defaultOnClosing, NULL); - uiWindowOnContentSizeChanged(w, defaultOnPositionContentSizeChanged, NULL); - - // normally it's SetParent() that does this, but we can't call SetParent() on a uiWindow - // TODO we really need to clean this up, especially since see uiWindowDestroy() above - g_object_ref(w->widget); - - return w; -} diff --git a/deps/libui/windows/CMakeLists.txt b/deps/libui/windows/CMakeLists.txt deleted file mode 100644 index 4695eb4f6e..0000000000 --- a/deps/libui/windows/CMakeLists.txt +++ /dev/null @@ -1,91 +0,0 @@ -# 3 june 2016 - -list(APPEND _LIBUI_SOURCES - windows/alloc.cpp - windows/area.cpp - windows/areadraw.cpp - windows/areaevents.cpp - windows/areascroll.cpp - windows/areautil.cpp - windows/box.cpp - windows/button.cpp - windows/checkbox.cpp - windows/colorbutton.cpp - windows/colordialog.cpp - windows/combobox.cpp - windows/container.cpp - windows/control.cpp - windows/d2dscratch.cpp - windows/datetimepicker.cpp - windows/debug.cpp - windows/draw.cpp - windows/drawmatrix.cpp - windows/drawpath.cpp - windows/drawtext.cpp - windows/dwrite.cpp - windows/editablecombo.cpp - windows/entry.cpp - windows/events.cpp - windows/fontbutton.cpp - windows/fontdialog.cpp - windows/form.cpp - windows/graphemes.cpp - windows/grid.cpp - windows/group.cpp - windows/init.cpp - windows/label.cpp - windows/main.cpp - windows/menu.cpp - windows/multilineentry.cpp - windows/parent.cpp - windows/progressbar.cpp - windows/radiobuttons.cpp - windows/separator.cpp - windows/sizing.cpp - windows/slider.cpp - windows/spinbox.cpp - windows/stddialogs.cpp - windows/tab.cpp - windows/tabpage.cpp - windows/text.cpp - windows/utf16.cpp - windows/utilwin.cpp - windows/window.cpp - windows/winpublic.cpp - windows/winutil.cpp - windows/resources.rc -) -set(_LIBUI_SOURCES ${_LIBUI_SOURCES} PARENT_SCOPE) - -list(APPEND _LIBUI_INCLUDEDIRS - windows -) -set(_LIBUI_INCLUDEDIRS _LIBUI_INCLUDEDIRS PARENT_SCOPE) - -# Windows won't link resources in static libraries; we need to provide the libui.res file in this case. -set(_LIBUINAME libui PARENT_SCOPE) -if(NOT BUILD_SHARED_LIBS) - set(_LIBUI_STATIC_RES ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/libui.res PARENT_SCOPE) -endif() -macro(_handle_static) - # TODO this full path feels hacky - add_custom_command( - TARGET libui POST_BUILD - COMMAND - ${CMAKE_COMMAND} -E copy $/CMakeFiles/libui.dir/windows/resources.rc.* ${_LIBUI_STATIC_RES} - COMMENT "Copying libui.res") -endmacro() - -# notice that usp10 comes before gdi32 -# TODO prune this list -set(_LIBUI_LIBS - user32 kernel32 usp10 gdi32 comctl32 uxtheme msimg32 comdlg32 d2d1 dwrite ole32 oleaut32 oleacc uuid -PARENT_SCOPE) - -if(NOT MSVC) - if(BUILD_SHARED_LIBS) - message(FATAL_ERROR - "Sorry, but libui for Windows can currently only be built as a static library with MinGW. You will need to either build as a static library or switch to MSVC." - ) - endif() -endif() diff --git a/deps/libui/windows/_uipriv_migrate.hpp b/deps/libui/windows/_uipriv_migrate.hpp deleted file mode 100644 index 13d3670ea9..0000000000 --- a/deps/libui/windows/_uipriv_migrate.hpp +++ /dev/null @@ -1,61 +0,0 @@ - -// menu.c -extern HMENU makeMenubar(void); -extern const uiMenuItem *menuIDToItem(UINT_PTR); -extern void runMenuEvent(WORD, uiWindow *); -extern void freeMenubar(HMENU); -extern void uninitMenus(void); - -// draw.c -extern HRESULT initDraw(void); -extern void uninitDraw(void); -extern ID2D1HwndRenderTarget *makeHWNDRenderTarget(HWND hwnd); -extern uiDrawContext *newContext(ID2D1RenderTarget *); -extern void freeContext(uiDrawContext *); - -// dwrite.cpp -#ifdef __cplusplus -extern IDWriteFactory *dwfactory; -#endif -extern HRESULT initDrawText(void); -extern void uninitDrawText(void); -#ifdef __cplusplus -struct fontCollection { - IDWriteFontCollection *fonts; - WCHAR userLocale[LOCALE_NAME_MAX_LENGTH]; - int userLocaleSuccess; -}; -extern fontCollection *loadFontCollection(void); -extern WCHAR *fontCollectionFamilyName(fontCollection *fc, IDWriteFontFamily *family); -extern void fontCollectionFree(fontCollection *fc); -extern WCHAR *fontCollectionCorrectString(fontCollection *fc, IDWriteLocalizedStrings *names); -#endif - -// drawtext.cpp -#ifdef __cplusplus -extern uiDrawTextFont *mkTextFont(IDWriteFont *df, BOOL addRef, WCHAR *family, BOOL copyFamily, double size); -struct dwriteAttr { - uiDrawTextWeight weight; - uiDrawTextItalic italic; - uiDrawTextStretch stretch; - DWRITE_FONT_WEIGHT dweight; - DWRITE_FONT_STYLE ditalic; - DWRITE_FONT_STRETCH dstretch; -}; -extern void attrToDWriteAttr(struct dwriteAttr *attr); -extern void dwriteAttrToAttr(struct dwriteAttr *attr); -#endif - -// fontdialog.cpp -#ifdef __cplusplus -struct fontDialogParams { - IDWriteFont *font; - double size; - WCHAR *familyName; - WCHAR *styleName; -}; -extern BOOL showFontDialog(HWND parent, struct fontDialogParams *params); -extern void loadInitialFontDialogParams(struct fontDialogParams *params); -extern void destroyFontDialogParams(struct fontDialogParams *params); -extern WCHAR *fontDialogParamsToString(struct fontDialogParams *params); -#endif diff --git a/deps/libui/windows/alloc.cpp b/deps/libui/windows/alloc.cpp deleted file mode 100644 index eeee3ad4b1..0000000000 --- a/deps/libui/windows/alloc.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// 4 december 2014 -#include "uipriv_windows.hpp" - -typedef std::vector byteArray; - -static std::map heap; -static std::map types; - -void initAlloc(void) -{ - // do nothing -} - -void uninitAlloc(void) -{ - std::ostringstream oss; - std::string ossstr; // keep alive, just to be safe - - if (heap.size() == 0) - return; - for (const auto &alloc : heap) - // note the void * cast; otherwise it'll be treated as a string - oss << (void *) (alloc.first) << " " << types[alloc.second] << "\n"; - ossstr = oss.str(); - userbug("Some data was leaked; either you left a uiControl lying around or there's a bug in libui itself. Leaked data:\n%s", ossstr.c_str()); -} - -#define rawBytes(pa) (&((*pa)[0])) - -void *uiAlloc(size_t size, const char *type) -{ - byteArray *out; - - out = new byteArray(size, 0); - heap[rawBytes(out)] = out; - types[out] = type; - return rawBytes(out); -} - -void *uiRealloc(void *_p, size_t size, const char *type) -{ - uint8_t *p = (uint8_t *) _p; - byteArray *arr; - - if (p == NULL) - return uiAlloc(size, type); - arr = heap[p]; - arr->resize(size, 0); - heap.erase(p); - heap[rawBytes(arr)] = arr; - return rawBytes(arr); -} - -void uiFree(void *_p) -{ - uint8_t *p = (uint8_t *) _p; - - if (p == NULL) - implbug("attempt to uiFree(NULL)"); - types.erase(heap[p]); - delete heap[p]; - heap.erase(p); -} diff --git a/deps/libui/windows/area.cpp b/deps/libui/windows/area.cpp deleted file mode 100644 index ab69ff1523..0000000000 --- a/deps/libui/windows/area.cpp +++ /dev/null @@ -1,206 +0,0 @@ -// 8 september 2015 -#include "uipriv_windows.hpp" -#include "area.hpp" - -// TODO handle WM_DESTROY/WM_NCDESTROY -// TODO same for other Direct2D stuff -static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - uiArea *a; - CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam; - RECT client; - WINDOWPOS *wp = (WINDOWPOS *) lParam; - LRESULT lResult; - - a = (uiArea *) GetWindowLongPtrW(hwnd, GWLP_USERDATA); - if (a == NULL) { - if (uMsg == WM_CREATE) { - a = (uiArea *) (cs->lpCreateParams); - // assign a->hwnd here so we can use it immediately - a->hwnd = hwnd; - SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) a); - } - // fall through to DefWindowProcW() anyway - return DefWindowProcW(hwnd, uMsg, wParam, lParam); - } - - // always recreate the render target if necessary - if (a->rt == NULL) - a->rt = makeHWNDRenderTarget(a->hwnd); - - if (areaDoDraw(a, uMsg, wParam, lParam, &lResult) != FALSE) - return lResult; - - if (uMsg == WM_WINDOWPOSCHANGED) { - if ((wp->flags & SWP_NOSIZE) != 0) - return DefWindowProcW(hwnd, uMsg, wParam, lParam); - uiWindowsEnsureGetClientRect(a->hwnd, &client); - areaDrawOnResize(a, &client); - areaScrollOnResize(a, &client); - return 0; - } - - if (areaDoScroll(a, uMsg, wParam, lParam, &lResult) != FALSE) - return lResult; - if (areaDoEvents(a, uMsg, wParam, lParam, &lResult) != FALSE) - return lResult; - - // nothing done - return DefWindowProc(hwnd, uMsg, wParam, lParam); -} - -// control implementation - -uiWindowsControlAllDefaults(uiArea) - -static void uiAreaMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - // TODO - *width = 0; - *height = 0; -} - -ATOM registerAreaClass(HICON hDefaultIcon, HCURSOR hDefaultCursor) -{ - WNDCLASSW wc; - - ZeroMemory(&wc, sizeof (WNDCLASSW)); - wc.lpszClassName = areaClass; - wc.lpfnWndProc = areaWndProc; - wc.hInstance = hInstance; - wc.hIcon = hDefaultIcon; - wc.hCursor = hDefaultCursor; - wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); - // this is just to be safe; see the InvalidateRect() call in the WM_WINDOWPOSCHANGED handler for more details - wc.style = CS_HREDRAW | CS_VREDRAW; - return RegisterClassW(&wc); -} - -void unregisterArea(void) -{ - if (UnregisterClassW(areaClass, hInstance) == 0) - logLastError(L"error unregistering uiArea window class"); -} - -void uiAreaSetSize(uiArea *a, int width, int height) -{ - a->scrollWidth = width; - a->scrollHeight = height; - areaUpdateScroll(a); -} - -void uiAreaQueueRedrawAll(uiArea *a) -{ - // don't erase the background; we do that ourselves in doPaint() - invalidateRect(a->hwnd, NULL, FALSE); -} - -void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height) -{ - // TODO -} - -void uiAreaBeginUserWindowMove(uiArea *a) -{ - HWND toplevel; - - // TODO restrict execution - ReleaseCapture(); // TODO use properly and reset internal data structures - toplevel = parentToplevel(a->hwnd); - if (toplevel == NULL) { - // TODO - return; - } - // see http://stackoverflow.com/questions/40249940/how-do-i-initiate-a-user-mouse-driven-move-or-resize-for-custom-window-borders-o#40250654 - SendMessageW(toplevel, WM_SYSCOMMAND, - SC_MOVE | 2, 0); -} - -void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge) -{ - HWND toplevel; - WPARAM wParam; - - // TODO restrict execution - ReleaseCapture(); // TODO use properly and reset internal data structures - toplevel = parentToplevel(a->hwnd); - if (toplevel == NULL) { - // TODO - return; - } - // see http://stackoverflow.com/questions/40249940/how-do-i-initiate-a-user-mouse-driven-move-or-resize-for-custom-window-borders-o#40250654 - wParam = SC_SIZE; - switch (edge) { - case uiWindowResizeEdgeLeft: - wParam |= 1; - break; - case uiWindowResizeEdgeTop: - wParam |= 3; - break; - case uiWindowResizeEdgeRight: - wParam |= 2; - break; - case uiWindowResizeEdgeBottom: - wParam |= 6; - break; - case uiWindowResizeEdgeTopLeft: - wParam |= 4; - break; - case uiWindowResizeEdgeTopRight: - wParam |= 5; - break; - case uiWindowResizeEdgeBottomLeft: - wParam |= 7; - break; - case uiWindowResizeEdgeBottomRight: - wParam |= 8; - break; - } - SendMessageW(toplevel, WM_SYSCOMMAND, - wParam, 0); -} - -uiArea *uiNewArea(uiAreaHandler *ah) -{ - uiArea *a; - - uiWindowsNewControl(uiArea, a); - - a->ah = ah; - a->scrolling = FALSE; - clickCounterReset(&(a->cc)); - - // a->hwnd is assigned in areaWndProc() - uiWindowsEnsureCreateControlHWND(0, - areaClass, L"", - 0, - hInstance, a, - FALSE); - - return a; -} - -uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height) -{ - uiArea *a; - - uiWindowsNewControl(uiArea, a); - - a->ah = ah; - a->scrolling = TRUE; - a->scrollWidth = width; - a->scrollHeight = height; - clickCounterReset(&(a->cc)); - - // a->hwnd is assigned in areaWndProc() - uiWindowsEnsureCreateControlHWND(0, - areaClass, L"", - WS_HSCROLL | WS_VSCROLL, - hInstance, a, - FALSE); - - // set initial scrolling parameters - areaUpdateScroll(a); - - return a; -} diff --git a/deps/libui/windows/area.hpp b/deps/libui/windows/area.hpp deleted file mode 100644 index 86a62de659..0000000000 --- a/deps/libui/windows/area.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// 18 december 2015 - -// TODOs -// - things look very wrong on initial draw -// - initial scrolling is not set properly -// - should background be inherited from parent control? - -struct uiArea { - uiWindowsControl c; - HWND hwnd; - uiAreaHandler *ah; - - BOOL scrolling; - int scrollWidth; - int scrollHeight; - int hscrollpos; - int vscrollpos; - int hwheelCarry; - int vwheelCarry; - - clickCounter cc; - BOOL capturing; - - BOOL inside; - BOOL tracking; - - ID2D1HwndRenderTarget *rt; -}; - -// areadraw.cpp -extern BOOL areaDoDraw(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult); -extern void areaDrawOnResize(uiArea *, RECT *); - -// areascroll.cpp -extern BOOL areaDoScroll(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult); -extern void areaScrollOnResize(uiArea *, RECT *); -extern void areaUpdateScroll(uiArea *a); - -// areaevents.cpp -extern BOOL areaDoEvents(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult); - -// areautil.cpp -extern void loadAreaSize(uiArea *a, ID2D1RenderTarget *rt, double *width, double *height); -extern void pixelsToDIP(uiArea *a, double *x, double *y); -extern void dipToPixels(uiArea *a, double *x, double *y); diff --git a/deps/libui/windows/areadraw.cpp b/deps/libui/windows/areadraw.cpp deleted file mode 100644 index 7b3dc69600..0000000000 --- a/deps/libui/windows/areadraw.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// 8 september 2015 -#include "uipriv_windows.hpp" -#include "area.hpp" - -static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *clip) -{ - uiAreaHandler *ah = a->ah; - uiAreaDrawParams dp; - COLORREF bgcolorref; - D2D1_COLOR_F bgcolor; - D2D1_MATRIX_3X2_F scrollTransform; - - // no need to save or restore the graphics state to reset transformations; it's handled by resetTarget() in draw.c, called during the following - dp.Context = newContext(rt); - - loadAreaSize(a, rt, &(dp.AreaWidth), &(dp.AreaHeight)); - - dp.ClipX = clip->left; - dp.ClipY = clip->top; - dp.ClipWidth = clip->right - clip->left; - dp.ClipHeight = clip->bottom - clip->top; - if (a->scrolling) { - dp.ClipX += a->hscrollpos; - dp.ClipY += a->vscrollpos; - } - - rt->BeginDraw(); - - if (a->scrolling) { - ZeroMemory(&scrollTransform, sizeof (D2D1_MATRIX_3X2_F)); - scrollTransform._11 = 1; - scrollTransform._22 = 1; - // negative because we want nonzero scroll positions to move the drawing area up/left - scrollTransform._31 = -a->hscrollpos; - scrollTransform._32 = -a->vscrollpos; - rt->SetTransform(&scrollTransform); - } - - // TODO push axis aligned clip - - // TODO only clear the clip area - // TODO clear with actual background brush - bgcolorref = GetSysColor(COLOR_BTNFACE); - bgcolor.r = ((float) GetRValue(bgcolorref)) / 255.0; - // due to utter apathy on Microsoft's part, GetGValue() does not work with MSVC's Run-Time Error Checks - // it has not worked since 2008 and they have *never* fixed it - // TODO now that -RTCc has just been deprecated entirely, should we switch back? - bgcolor.g = ((float) ((BYTE) ((bgcolorref & 0xFF00) >> 8))) / 255.0; - bgcolor.b = ((float) GetBValue(bgcolorref)) / 255.0; - bgcolor.a = 1.0; - rt->Clear(&bgcolor); - - (*(ah->Draw))(ah, a, &dp); - - freeContext(dp.Context); - - // TODO pop axis aligned clip - - return rt->EndDraw(NULL, NULL); -} - -static void onWM_PAINT(uiArea *a) -{ - RECT clip; - HRESULT hr; - - // do not clear the update rect; we do that ourselves in doPaint() - if (GetUpdateRect(a->hwnd, &clip, FALSE) == 0) { - // set a zero clip rect just in case GetUpdateRect() didn't change clip - clip.left = 0; - clip.top = 0; - clip.right = 0; - clip.bottom = 0; - } - hr = doPaint(a, a->rt, &clip); - switch (hr) { - case S_OK: - if (ValidateRect(a->hwnd, NULL) == 0) - logLastError(L"error validating rect"); - break; - case D2DERR_RECREATE_TARGET: - // DON'T validate the rect - // instead, simply drop the render target - // we'll get another WM_PAINT and make the render target again - // TODO would this require us to invalidate the entire client area? - a->rt->Release();; - a->rt = NULL; - break; - default: - logHRESULT(L"error painting", hr); - } -} - -static void onWM_PRINTCLIENT(uiArea *a, HDC dc) -{ - ID2D1DCRenderTarget *rt; - RECT client; - HRESULT hr; - - uiWindowsEnsureGetClientRect(a->hwnd, &client); - rt = makeHDCRenderTarget(dc, &client); - hr = doPaint(a, rt, &client); - if (hr != S_OK) - logHRESULT(L"error printing uiArea client area", hr); - rt->Release(); -} - -BOOL areaDoDraw(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult) -{ - switch (uMsg) { - case WM_PAINT: - onWM_PAINT(a); - *lResult = 0; - return TRUE; - case WM_PRINTCLIENT: - onWM_PRINTCLIENT(a, (HDC) wParam); - *lResult = 0; - return TRUE; - } - return FALSE; -} - -// TODO only if the render target wasn't just created? -void areaDrawOnResize(uiArea *a, RECT *newClient) -{ - D2D1_SIZE_U size; - - size.width = newClient->right - newClient->left; - size.height = newClient->bottom - newClient->top; - // don't track the error; we'll get that in EndDraw() - // see https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994%28v=vs.85%29.aspx - a->rt->Resize(&size); - - // according to Rick Brewster, we must always redraw the entire client area after calling ID2D1RenderTarget::Resize() (see http://stackoverflow.com/a/33222983/3408572) - // we used to have a uiAreaHandler.RedrawOnResize() method to decide this; now you know why we don't anymore - invalidateRect(a->hwnd, NULL, TRUE); -} diff --git a/deps/libui/windows/areaevents.cpp b/deps/libui/windows/areaevents.cpp deleted file mode 100644 index 7d391b853b..0000000000 --- a/deps/libui/windows/areaevents.cpp +++ /dev/null @@ -1,421 +0,0 @@ -// 8 september 2015 -#include "uipriv_windows.hpp" -#include "area.hpp" - -static uiModifiers getModifiers(void) -{ - uiModifiers m = 0; - - if ((GetKeyState(VK_CONTROL) & 0x80) != 0) - m |= uiModifierCtrl; - if ((GetKeyState(VK_MENU) & 0x80) != 0) - m |= uiModifierAlt; - if ((GetKeyState(VK_SHIFT) & 0x80) != 0) - m |= uiModifierShift; - if ((GetKeyState(VK_LWIN) & 0x80) != 0) - m |= uiModifierSuper; - if ((GetKeyState(VK_RWIN) & 0x80) != 0) - m |= uiModifierSuper; - return m; -} - -/* -Windows doesn't natively support mouse crossing events. - -TrackMouseEvent() (and its comctl32.dll wrapper _TrackMouseEvent()) both allow for a window to receive the WM_MOUSELEAVE message when the mouse leaves the client area. There's no equivalent WM_MOUSEENTER because it can be simulated (https://blogs.msdn.microsoft.com/oldnewthing/20031013-00/?p=42193). - -Unfortunately, WM_MOUSELEAVE does not get generated while the mouse is captured. We need to capture for drag behavior to work properly, so this isn't going to mix well. - -So what we do: -- on WM_MOUSEMOVE, if we don't have the capture, start tracking - - this will handle the case of the capture being released while still in the area -- on WM_MOUSELEAVE, mark that we are no longer tracking - - Windows has already done the work of that for us; it's just a flag we use for the next part -- when starting capture, stop tracking if we are tracking -- if capturing, manually check if the pointer is in the client rect on each area event -*/ -static void track(uiArea *a, BOOL tracking) -{ - TRACKMOUSEEVENT tm; - - // do nothing if there's no change - if (a->tracking && tracking) - return; - if (!a->tracking && !tracking) - return; - - a->tracking = tracking; - ZeroMemory(&tm, sizeof (TRACKMOUSEEVENT)); - tm.cbSize = sizeof (TRACKMOUSEEVENT); - tm.dwFlags = TME_LEAVE; - if (!a->tracking) - tm.dwFlags |= TME_CANCEL; - tm.hwndTrack = a->hwnd; - if (_TrackMouseEvent(&tm) == 0) - logLastError(L"error setting up mouse tracking"); -} - -static void capture(uiArea *a, BOOL capturing) -{ - // do nothing if there's no change - if (a->capturing && capturing) - return; - if (!a->capturing && !capturing) - return; - - // change flag first as ReleaseCapture() sends WM_CAPTURECHANGED - a->capturing = capturing; - if (a->capturing) { - track(a, FALSE); - SetCapture(a->hwnd); - } else - if (ReleaseCapture() == 0) - logLastError(L"error releasing capture on drag"); -} - -static void areaMouseEvent(uiArea *a, int down, int up, WPARAM wParam, LPARAM lParam) -{ - uiAreaMouseEvent me; - int button; - POINT clientpt; - RECT client; - BOOL inClient; - double xpix, ypix; - - if (a->capturing) { - clientpt.x = GET_X_LPARAM(lParam); - clientpt.y = GET_Y_LPARAM(lParam); - uiWindowsEnsureGetClientRect(a->hwnd, &client); - inClient = PtInRect(&client, clientpt); - if (inClient && !a->inside) { - a->inside = TRUE; - (*(a->ah->MouseCrossed))(a->ah, a, 0); - clickCounterReset(&(a->cc)); - } else if (!inClient && a->inside) { - a->inside = FALSE; - (*(a->ah->MouseCrossed))(a->ah, a, 1); - clickCounterReset(&(a->cc)); - } - } - - xpix = (double) GET_X_LPARAM(lParam); - ypix = (double) GET_Y_LPARAM(lParam); - // these are in pixels; we need points - pixelsToDIP(a, &xpix, &ypix); - me.X = xpix; - me.Y = ypix; - if (a->scrolling) { - me.X += a->hscrollpos; - me.Y += a->vscrollpos; - } - - loadAreaSize(a, NULL, &(me.AreaWidth), &(me.AreaHeight)); - - me.Down = down; - me.Up = up; - me.Count = 0; - if (me.Down != 0) - // GetMessageTime() returns LONG and GetDoubleClckTime() returns UINT, which are int32 and uint32, respectively, but we don't need to worry about the signedness because for the same bit widths and two's complement arithmetic, s1-s2 == u1-u2 if bits(s1)==bits(s2) and bits(u1)==bits(u2) (and Windows requires two's complement: http://blogs.msdn.com/b/oldnewthing/archive/2005/05/27/422551.aspx) - // signedness isn't much of an issue for these calls anyway because http://stackoverflow.com/questions/24022225/what-are-the-sign-extension-rules-for-calling-windows-api-functions-stdcall-t and that we're only using unsigned values (think back to how you (didn't) handle signedness in assembly language) AND because of the above AND because the statistics below (time interval and width/height) really don't make sense if negative - // GetSystemMetrics() returns int, which is int32 - me.Count = clickCounterClick(&(a->cc), me.Down, - me.X, me.Y, - GetMessageTime(), GetDoubleClickTime(), - GetSystemMetrics(SM_CXDOUBLECLK) / 2, - GetSystemMetrics(SM_CYDOUBLECLK) / 2); - - // though wparam will contain control and shift state, let's just one function to get modifiers for both keyboard and mouse events; it'll work the same anyway since we have to do this for alt and windows key (super) - me.Modifiers = getModifiers(); - - button = me.Down; - if (button == 0) - button = me.Up; - me.Held1To64 = 0; - if (button != 1 && (wParam & MK_LBUTTON) != 0) - me.Held1To64 |= 1 << 0; - if (button != 2 && (wParam & MK_MBUTTON) != 0) - me.Held1To64 |= 1 << 1; - if (button != 3 && (wParam & MK_RBUTTON) != 0) - me.Held1To64 |= 1 << 2; - if (button != 4 && (wParam & MK_XBUTTON1) != 0) - me.Held1To64 |= 1 << 3; - if (button != 5 && (wParam & MK_XBUTTON2) != 0) - me.Held1To64 |= 1 << 4; - - // on Windows, we have to capture on drag ourselves - if (me.Down != 0) - capture(a, TRUE); - // only release capture when all buttons released - if (me.Up != 0 && me.Held1To64 == 0) - capture(a, FALSE); - - (*(a->ah->MouseEvent))(a->ah, a, &me); -} - -// TODO genericize this so it can be called above -static void onMouseEntered(uiArea *a) -{ - if (a->inside) - return; - if (a->capturing) // we handle mouse crossing in areaMouseEvent() - return; - track(a, TRUE); - (*(a->ah->MouseCrossed))(a->ah, a, 0); - // TODO figure out why we did this to begin with; either we do it on both GTK+ and Windows or not at all - clickCounterReset(&(a->cc)); -} - -// TODO genericize it so that it can be called above -static void onMouseLeft(uiArea *a) -{ - a->tracking = FALSE; - a->inside = FALSE; - (*(a->ah->MouseCrossed))(a->ah, a, 1); - // TODO figure out why we did this to begin with; either we do it on both GTK+ and Windows or not at all - clickCounterReset(&(a->cc)); -} - -// we use VK_SNAPSHOT as a sentinel because libui will never support the print screen key; that key belongs to the user -struct extkeymap { - WPARAM vk; - uiExtKey extkey; -}; - -// all mappings come from GLFW - https://github.com/glfw/glfw/blob/master/src/win32_window.c#L152 -static const struct extkeymap numpadExtKeys[] = { - { VK_HOME, uiExtKeyN7 }, - { VK_UP, uiExtKeyN8 }, - { VK_PRIOR, uiExtKeyN9 }, - { VK_LEFT, uiExtKeyN4 }, - { VK_CLEAR, uiExtKeyN5 }, - { VK_RIGHT, uiExtKeyN6 }, - { VK_END, uiExtKeyN1 }, - { VK_DOWN, uiExtKeyN2 }, - { VK_NEXT, uiExtKeyN3 }, - { VK_INSERT, uiExtKeyN0 }, - { VK_DELETE, uiExtKeyNDot }, - { VK_SNAPSHOT, 0 }, -}; - -static const struct extkeymap extKeys[] = { - { VK_ESCAPE, uiExtKeyEscape }, - { VK_INSERT, uiExtKeyInsert }, - { VK_DELETE, uiExtKeyDelete }, - { VK_HOME, uiExtKeyHome }, - { VK_END, uiExtKeyEnd }, - { VK_PRIOR, uiExtKeyPageUp }, - { VK_NEXT, uiExtKeyPageDown }, - { VK_UP, uiExtKeyUp }, - { VK_DOWN, uiExtKeyDown }, - { VK_LEFT, uiExtKeyLeft }, - { VK_RIGHT, uiExtKeyRight }, - { VK_F1, uiExtKeyF1 }, - { VK_F2, uiExtKeyF2 }, - { VK_F3, uiExtKeyF3 }, - { VK_F4, uiExtKeyF4 }, - { VK_F5, uiExtKeyF5 }, - { VK_F6, uiExtKeyF6 }, - { VK_F7, uiExtKeyF7 }, - { VK_F8, uiExtKeyF8 }, - { VK_F9, uiExtKeyF9 }, - { VK_F10, uiExtKeyF10 }, - { VK_F11, uiExtKeyF11 }, - { VK_F12, uiExtKeyF12 }, - // numpad numeric keys and . are handled in common/areaevents.c - // numpad enter is handled in code below - { VK_ADD, uiExtKeyNAdd }, - { VK_SUBTRACT, uiExtKeyNSubtract }, - { VK_MULTIPLY, uiExtKeyNMultiply }, - { VK_DIVIDE, uiExtKeyNDivide }, - { VK_SNAPSHOT, 0 }, -}; - -static const struct { - WPARAM vk; - uiModifiers mod; -} modKeys[] = { - // even if the separate left/right aren't necessary, have them here anyway, just to be safe - { VK_CONTROL, uiModifierCtrl }, - { VK_LCONTROL, uiModifierCtrl }, - { VK_RCONTROL, uiModifierCtrl }, - { VK_MENU, uiModifierAlt }, - { VK_LMENU, uiModifierAlt }, - { VK_RMENU, uiModifierAlt }, - { VK_SHIFT, uiModifierShift }, - { VK_LSHIFT, uiModifierShift }, - { VK_RSHIFT, uiModifierShift }, - // there's no combined Windows key virtual-key code as there is with the others - { VK_LWIN, uiModifierSuper }, - { VK_RWIN, uiModifierSuper }, - { VK_SNAPSHOT, 0 }, -}; - -static int areaKeyEvent(uiArea *a, int up, WPARAM wParam, LPARAM lParam) -{ - uiAreaKeyEvent ke; - int righthand; - int i; - - ke.Key = 0; - ke.ExtKey = 0; - ke.Modifier = 0; - - ke.Modifiers = getModifiers(); - - ke.Up = up; - - // the numeric keypad keys when Num Lock is off are considered left-hand keys as the separate navigation buttons were added later - // the numeric keypad Enter, however, is a right-hand key because it has the same virtual-key code as the typewriter Enter - righthand = (lParam & 0x01000000) != 0; - if (righthand) { - if (wParam == VK_RETURN) { - ke.ExtKey = uiExtKeyNEnter; - goto keyFound; - } - } else - // this is special handling for numpad keys to ignore the state of Num Lock and Shift; see http://blogs.msdn.com/b/oldnewthing/archive/2004/09/06/226045.aspx and https://github.com/glfw/glfw/blob/master/src/win32_window.c#L152 - for (i = 0; numpadExtKeys[i].vk != VK_SNAPSHOT; i++) - if (numpadExtKeys[i].vk == wParam) { - ke.ExtKey = numpadExtKeys[i].extkey; - goto keyFound; - } - - // okay, those above cases didn't match anything - // first try the extended keys - for (i = 0; extKeys[i].vk != VK_SNAPSHOT; i++) - if (extKeys[i].vk == wParam) { - ke.ExtKey = extKeys[i].extkey; - goto keyFound; - } - - // then try modifier keys - for (i = 0; modKeys[i].vk != VK_SNAPSHOT; i++) - if (modKeys[i].vk == wParam) { - ke.Modifier = modKeys[i].mod; - // and don't include the key in Modifiers - ke.Modifiers &= ~ke.Modifier; - goto keyFound; - } - - // and finally everything else - if (fromScancode((lParam >> 16) & 0xFF, &ke)) - goto keyFound; - - // not a supported key, assume unhandled - // TODO the original code only did this if ke.Modifiers == 0 - why? - return 0; - -keyFound: - return (*(a->ah->KeyEvent))(a->ah, a, &ke); -} - -// We don't handle the standard Windows keyboard messages directly, to avoid both the dialog manager and TranslateMessage(). -// Instead, we set up a message filter and do things there. -// That stuff is later in this file. -enum { - // start at 0x40 to avoid clobbering dialog messages - msgAreaKeyDown = WM_USER + 0x40, - msgAreaKeyUp, -}; - -BOOL areaDoEvents(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult) -{ - switch (uMsg) { - case WM_ACTIVATE: - // don't keep the double-click timer running if the user switched programs in between clicks - clickCounterReset(&(a->cc)); - *lResult = 0; - return TRUE; - case WM_MOUSEMOVE: - onMouseEntered(a); - areaMouseEvent(a, 0, 0, wParam, lParam); - *lResult = 0; - return TRUE; - case WM_MOUSELEAVE: - onMouseLeft(a); - *lResult = 0; - return TRUE; - case WM_LBUTTONDOWN: - SetFocus(a->hwnd); - areaMouseEvent(a, 1, 0, wParam, lParam); - *lResult = 0; - return TRUE; - case WM_LBUTTONUP: - areaMouseEvent(a, 0, 1, wParam, lParam); - *lResult = 0; - return TRUE; - case WM_MBUTTONDOWN: - SetFocus(a->hwnd); - areaMouseEvent(a, 2, 0, wParam, lParam); - *lResult = 0; - return TRUE; - case WM_MBUTTONUP: - areaMouseEvent(a, 0, 2, wParam, lParam); - *lResult = 0; - return TRUE; - case WM_RBUTTONDOWN: - SetFocus(a->hwnd); - areaMouseEvent(a, 3, 0, wParam, lParam); - *lResult = 0; - return TRUE; - case WM_RBUTTONUP: - areaMouseEvent(a, 0, 3, wParam, lParam); - *lResult = 0; - return TRUE; - case WM_XBUTTONDOWN: - SetFocus(a->hwnd); - // values start at 1; we want them to start at 4 - areaMouseEvent(a, - GET_XBUTTON_WPARAM(wParam) + 3, 0, - GET_KEYSTATE_WPARAM(wParam), lParam); - *lResult = TRUE; // XBUTTON messages are different! - return TRUE; - case WM_XBUTTONUP: - areaMouseEvent(a, - 0, GET_XBUTTON_WPARAM(wParam) + 3, - GET_KEYSTATE_WPARAM(wParam), lParam); - *lResult = TRUE; // XBUTTON messages are different! - return TRUE; - case WM_CAPTURECHANGED: - if (a->capturing) { - a->capturing = FALSE; - (*(a->ah->DragBroken))(a->ah, a); - } - *lResult = 0; - return TRUE; - case msgAreaKeyDown: - *lResult = (LRESULT) areaKeyEvent(a, 0, wParam, lParam); - return TRUE; - case msgAreaKeyUp: - *lResult = (LRESULT) areaKeyEvent(a, 1, wParam, lParam); - return TRUE; - } - return FALSE; -} - -// TODO affect visibility properly -// TODO what did this mean -BOOL areaFilter(MSG *msg) -{ - LRESULT handled; - - // is the recipient an area? - if (msg->hwnd == NULL) // this can happen; for example, WM_TIMER - return FALSE; - if (windowClassOf(msg->hwnd, areaClass, NULL) != 0) - return FALSE; // nope - - handled = 0; - switch (msg->message) { - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - handled = SendMessageW(msg->hwnd, msgAreaKeyDown, msg->wParam, msg->lParam); - break; - case WM_KEYUP: - case WM_SYSKEYUP: - handled = SendMessageW(msg->hwnd, msgAreaKeyUp, msg->wParam, msg->lParam); - break; - // otherwise handled remains 0, as we didn't handle this - } - return (BOOL) handled; -} diff --git a/deps/libui/windows/areascroll.cpp b/deps/libui/windows/areascroll.cpp deleted file mode 100644 index f18d0ad874..0000000000 --- a/deps/libui/windows/areascroll.cpp +++ /dev/null @@ -1,247 +0,0 @@ -// 8 september 2015 -#include "uipriv_windows.hpp" -#include "area.hpp" - -// TODO -// - move from pixels to points somehow -// - add a function to offset points and rects by scrolling amounts; call it from doPaint() in areadraw.c -// - recalculate scrolling after: -// - creation? -// - resize? -// - recreating the render target? (after moving to points) -// - error if these are called without scrollbars? - -struct scrollParams { - int *pos; - int pagesize; - int length; - int *wheelCarry; - UINT wheelSPIAction; -}; - -static void scrollto(uiArea *a, int which, struct scrollParams *p, int pos) -{ - SCROLLINFO si; - - // note that the pos < 0 check is /after/ the p->length - p->pagesize check - // it used to be /before/; this was actually a bug in Raymond Chen's original algorithm: if there are fewer than a page's worth of items, p->length - p->pagesize will be negative and our content draw at the bottom of the window - // this SHOULD have the same effect with that bug fixed and no others introduced... (thanks to devin on irc.badnik.net for confirming this logic) - if (pos > p->length - p->pagesize) - pos = p->length - p->pagesize; - if (pos < 0) - pos = 0; - - // Direct2D doesn't have a method for scrolling the existing contents of a render target. - // We'll have to just invalidate everything and hope for the best. - invalidateRect(a->hwnd, NULL, FALSE); - - *(p->pos) = pos; - - // now commit our new scrollbar setup... - ZeroMemory(&si, sizeof (SCROLLINFO)); - si.cbSize = sizeof (SCROLLINFO); - si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; - si.nPage = p->pagesize; - si.nMin = 0; - si.nMax = p->length - 1; // endpoint inclusive - si.nPos = *(p->pos); - SetScrollInfo(a->hwnd, which, &si, TRUE); -} - -static void scrollby(uiArea *a, int which, struct scrollParams *p, int delta) -{ - scrollto(a, which, p, *(p->pos) + delta); -} - -static void scroll(uiArea *a, int which, struct scrollParams *p, WPARAM wParam, LPARAM lParam) -{ - int pos; - SCROLLINFO si; - - pos = *(p->pos); - switch (LOWORD(wParam)) { - case SB_LEFT: // also SB_TOP - pos = 0; - break; - case SB_RIGHT: // also SB_BOTTOM - pos = p->length - p->pagesize; - break; - case SB_LINELEFT: // also SB_LINEUP - pos--; - break; - case SB_LINERIGHT: // also SB_LINEDOWN - pos++; - break; - case SB_PAGELEFT: // also SB_PAGEUP - pos -= p->pagesize; - break; - case SB_PAGERIGHT: // also SB_PAGEDOWN - pos += p->pagesize; - break; - case SB_THUMBPOSITION: - ZeroMemory(&si, sizeof (SCROLLINFO)); - si.cbSize = sizeof (SCROLLINFO); - si.fMask = SIF_POS; - if (GetScrollInfo(a->hwnd, which, &si) == 0) - logLastError(L"error getting thumb position for area"); - pos = si.nPos; - break; - case SB_THUMBTRACK: - ZeroMemory(&si, sizeof (SCROLLINFO)); - si.cbSize = sizeof (SCROLLINFO); - si.fMask = SIF_TRACKPOS; - if (GetScrollInfo(a->hwnd, which, &si) == 0) - logLastError(L"error getting thumb track position for area"); - pos = si.nTrackPos; - break; - } - scrollto(a, which, p, pos); -} - -static void wheelscroll(uiArea *a, int which, struct scrollParams *p, WPARAM wParam, LPARAM lParam) -{ - int delta; - int lines; - UINT scrollAmount; - - delta = GET_WHEEL_DELTA_WPARAM(wParam); - if (SystemParametersInfoW(p->wheelSPIAction, 0, &scrollAmount, 0) == 0) - // TODO use scrollAmount == 3 (for both v and h) instead? - logLastError(L"error getting area wheel scroll amount"); - if (scrollAmount == WHEEL_PAGESCROLL) - scrollAmount = p->pagesize; - if (scrollAmount == 0) // no mouse wheel scrolling (or t->pagesize == 0) - return; - // the rest of this is basically http://blogs.msdn.com/b/oldnewthing/archive/2003/08/07/54615.aspx and http://blogs.msdn.com/b/oldnewthing/archive/2003/08/11/54624.aspx - // see those pages for information on subtleties - delta += *(p->wheelCarry); - lines = delta * ((int) scrollAmount) / WHEEL_DELTA; - *(p->wheelCarry) = delta - lines * WHEEL_DELTA / ((int) scrollAmount); - scrollby(a, which, p, -lines); -} - -static void hscrollParams(uiArea *a, struct scrollParams *p) -{ - RECT r; - - ZeroMemory(p, sizeof (struct scrollParams)); - p->pos = &(a->hscrollpos); - // TODO get rid of these and replace with points - uiWindowsEnsureGetClientRect(a->hwnd, &r); - p->pagesize = r.right - r.left; - p->length = a->scrollWidth; - p->wheelCarry = &(a->hwheelCarry); - p->wheelSPIAction = SPI_GETWHEELSCROLLCHARS; -} - -static void hscrollto(uiArea *a, int pos) -{ - struct scrollParams p; - - hscrollParams(a, &p); - scrollto(a, SB_HORZ, &p, pos); -} - -static void hscrollby(uiArea *a, int delta) -{ - struct scrollParams p; - - hscrollParams(a, &p); - scrollby(a, SB_HORZ, &p, delta); -} - -static void hscroll(uiArea *a, WPARAM wParam, LPARAM lParam) -{ - struct scrollParams p; - - hscrollParams(a, &p); - scroll(a, SB_HORZ, &p, wParam, lParam); -} - -static void hwheelscroll(uiArea *a, WPARAM wParam, LPARAM lParam) -{ - struct scrollParams p; - - hscrollParams(a, &p); - wheelscroll(a, SB_HORZ, &p, wParam, lParam); -} - -static void vscrollParams(uiArea *a, struct scrollParams *p) -{ - RECT r; - - ZeroMemory(p, sizeof (struct scrollParams)); - p->pos = &(a->vscrollpos); - uiWindowsEnsureGetClientRect(a->hwnd, &r); - p->pagesize = r.bottom - r.top; - p->length = a->scrollHeight; - p->wheelCarry = &(a->vwheelCarry); - p->wheelSPIAction = SPI_GETWHEELSCROLLLINES; -} - -static void vscrollto(uiArea *a, int pos) -{ - struct scrollParams p; - - vscrollParams(a, &p); - scrollto(a, SB_VERT, &p, pos); -} - -static void vscrollby(uiArea *a, int delta) -{ - struct scrollParams p; - - vscrollParams(a, &p); - scrollby(a, SB_VERT, &p, delta); -} - -static void vscroll(uiArea *a, WPARAM wParam, LPARAM lParam) -{ - struct scrollParams p; - - vscrollParams(a, &p); - scroll(a, SB_VERT, &p, wParam, lParam); -} - -static void vwheelscroll(uiArea *a, WPARAM wParam, LPARAM lParam) -{ - struct scrollParams p; - - vscrollParams(a, &p); - wheelscroll(a, SB_VERT, &p, wParam, lParam); -} - -BOOL areaDoScroll(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult) -{ - switch (uMsg) { - case WM_HSCROLL: - hscroll(a, wParam, lParam); - *lResult = 0; - return TRUE; - case WM_MOUSEHWHEEL: - hwheelscroll(a, wParam, lParam); - *lResult = 0; - return TRUE; - case WM_VSCROLL: - vscroll(a, wParam, lParam); - *lResult = 0; - return TRUE; - case WM_MOUSEWHEEL: - vwheelscroll(a, wParam, lParam); - *lResult = 0; - return TRUE; - } - return FALSE; -} - -void areaScrollOnResize(uiArea *a, RECT *client) -{ - areaUpdateScroll(a); -} - -void areaUpdateScroll(uiArea *a) -{ - // use a no-op scroll to simulate scrolling - hscrollby(a, 0); - vscrollby(a, 0); -} diff --git a/deps/libui/windows/areautil.cpp b/deps/libui/windows/areautil.cpp deleted file mode 100644 index 9dc72fbb4a..0000000000 --- a/deps/libui/windows/areautil.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// 18 december 2015 -#include "uipriv_windows.hpp" -#include "area.hpp" - -void loadAreaSize(uiArea *a, ID2D1RenderTarget *rt, double *width, double *height) -{ - D2D1_SIZE_F size; - - *width = 0; - *height = 0; - if (!a->scrolling) { - if (rt == NULL) - rt = a->rt; - size = realGetSize(rt); - *width = size.width; - *height = size.height; - } -} - -void pixelsToDIP(uiArea *a, double *x, double *y) -{ - FLOAT dpix, dpiy; - - a->rt->GetDpi(&dpix, &dpiy); - // see https://msdn.microsoft.com/en-us/library/windows/desktop/dd756649%28v=vs.85%29.aspx (and others; search "direct2d mouse") - *x = (*x * 96) / dpix; - *y = (*y * 96) / dpiy; -} - -void dipToPixels(uiArea *a, double *x, double *y) -{ - FLOAT dpix, dpiy; - - a->rt->GetDpi(&dpix, &dpiy); - *x = (*x * dpix) / 96; - *y = (*y * dpiy) / 96; -} diff --git a/deps/libui/windows/box.cpp b/deps/libui/windows/box.cpp deleted file mode 100644 index 9567954b5c..0000000000 --- a/deps/libui/windows/box.cpp +++ /dev/null @@ -1,320 +0,0 @@ -// 7 april 2015 -#include "uipriv_windows.hpp" - -struct boxChild { - uiControl *c; - int stretchy; - int width; - int height; -}; - -struct uiBox { - uiWindowsControl c; - HWND hwnd; - std::vector *controls; - int vertical; - int padded; -}; - -static void boxPadding(uiBox *b, int *xpadding, int *ypadding) -{ - uiWindowsSizing sizing; - - *xpadding = 0; - *ypadding = 0; - if (b->padded) { - uiWindowsGetSizing(b->hwnd, &sizing); - uiWindowsSizingStandardPadding(&sizing, xpadding, ypadding); - } -} - -static void boxRelayout(uiBox *b) -{ - RECT r; - int x, y, width, height; - int xpadding, ypadding; - int nStretchy; - int stretchywid, stretchyht; - int i; - int minimumWidth, minimumHeight; - int nVisible; - uiWindowsSizing *d; - - if (b->controls->size() == 0) - return; - - uiWindowsEnsureGetClientRect(b->hwnd, &r); - x = r.left; - y = r.top; - width = r.right - r.left; - height = r.bottom - r.top; - - // -1) get this Box's padding - boxPadding(b, &xpadding, &ypadding); - - // 1) get width and height of non-stretchy controls - // this will tell us how much space will be left for stretchy controls - stretchywid = width; - stretchyht = height; - nStretchy = 0; - nVisible = 0; - for (struct boxChild &bc : *(b->controls)) { - if (!uiControlVisible(bc.c)) - continue; - nVisible++; - if (bc.stretchy) { - nStretchy++; - continue; - } - uiWindowsControlMinimumSize(uiWindowsControl(bc.c), &minimumWidth, &minimumHeight); - if (b->vertical) { // all controls have same width - bc.width = width; - bc.height = minimumHeight; - stretchyht -= minimumHeight; - } else { // all controls have same height - bc.width = minimumWidth; - bc.height = height; - stretchywid -= minimumWidth; - } - } - if (nVisible == 0) // nothing to do - return; - - // 2) now inset the available rect by the needed padding - if (b->vertical) { - height -= (nVisible - 1) * ypadding; - stretchyht -= (nVisible - 1) * ypadding; - } else { - width -= (nVisible - 1) * xpadding; - stretchywid -= (nVisible - 1) * xpadding; - } - - // 3) now get the size of stretchy controls - if (nStretchy != 0) { - if (b->vertical) - stretchyht /= nStretchy; - else - stretchywid /= nStretchy; - for (struct boxChild &bc : *(b->controls)) { - if (!uiControlVisible(bc.c)) - continue; - if (bc.stretchy) { - bc.width = stretchywid; - bc.height = stretchyht; - } - } - } - - // 4) now we can position controls - // first, make relative to the top-left corner of the container - x = 0; - y = 0; - for (const struct boxChild &bc : *(b->controls)) { - if (!uiControlVisible(bc.c)) - continue; - uiWindowsEnsureMoveWindowDuringResize((HWND) uiControlHandle(bc.c), x, y, bc.width, bc.height); - if (b->vertical) - y += bc.height + ypadding; - else - x += bc.width + xpadding; - } -} - -static void uiBoxDestroy(uiControl *c) -{ - uiBox *b = uiBox(c); - - for (const struct boxChild &bc : *(b->controls)) { - uiControlSetParent(bc.c, NULL); - uiControlDestroy(bc.c); - } - delete b->controls; - uiWindowsEnsureDestroyWindow(b->hwnd); - uiFreeControl(uiControl(b)); -} - -uiWindowsControlDefaultHandle(uiBox) -uiWindowsControlDefaultParent(uiBox) -uiWindowsControlDefaultSetParent(uiBox) -uiWindowsControlDefaultToplevel(uiBox) -uiWindowsControlDefaultVisible(uiBox) -uiWindowsControlDefaultShow(uiBox) -uiWindowsControlDefaultHide(uiBox) -uiWindowsControlDefaultEnabled(uiBox) -uiWindowsControlDefaultEnable(uiBox) -uiWindowsControlDefaultDisable(uiBox) - -static void uiBoxSyncEnableState(uiWindowsControl *c, int enabled) -{ - uiBox *b = uiBox(c); - - if (uiWindowsShouldStopSyncEnableState(uiWindowsControl(b), enabled)) - return; - for (const struct boxChild &bc : *(b->controls)) - uiWindowsControlSyncEnableState(uiWindowsControl(bc.c), enabled); -} - -uiWindowsControlDefaultSetParentHWND(uiBox) - -static void uiBoxMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiBox *b = uiBox(c); - int xpadding, ypadding; - int nStretchy; - // these two contain the largest minimum width and height of all stretchy controls in the box - // all stretchy controls will use this value to determine the final minimum size - int maxStretchyWidth, maxStretchyHeight; - int i; - int minimumWidth, minimumHeight; - int nVisible; - uiWindowsSizing sizing; - - *width = 0; - *height = 0; - if (b->controls->size() == 0) - return; - - // 0) get this Box's padding - boxPadding(b, &xpadding, &ypadding); - - // 1) add in the size of non-stretchy controls and get (but not add in) the largest widths and heights of stretchy controls - // we still add in like direction of stretchy controls - nStretchy = 0; - maxStretchyWidth = 0; - maxStretchyHeight = 0; - nVisible = 0; - for (const struct boxChild &bc : *(b->controls)) { - if (!uiControlVisible(bc.c)) - continue; - nVisible++; - uiWindowsControlMinimumSize(uiWindowsControl(bc.c), &minimumWidth, &minimumHeight); - if (bc.stretchy) { - nStretchy++; - if (maxStretchyWidth < minimumWidth) - maxStretchyWidth = minimumWidth; - if (maxStretchyHeight < minimumHeight) - maxStretchyHeight = minimumHeight; - } - if (b->vertical) { - if (*width < minimumWidth) - *width = minimumWidth; - if (!bc.stretchy) - *height += minimumHeight; - } else { - if (!bc.stretchy) - *width += minimumWidth; - if (*height < minimumHeight) - *height = minimumHeight; - } - } - if (nVisible == 0) // just return 0x0 - return; - - // 2) now outset the desired rect with the needed padding - if (b->vertical) - *height += (nVisible - 1) * ypadding; - else - *width += (nVisible - 1) * xpadding; - - // 3) and now we can add in stretchy controls - if (b->vertical) - *height += nStretchy * maxStretchyHeight; - else - *width += nStretchy * maxStretchyWidth; -} - -static void uiBoxMinimumSizeChanged(uiWindowsControl *c) -{ - uiBox *b = uiBox(c); - - if (uiWindowsControlTooSmall(uiWindowsControl(b))) { - uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl(b)); - return; - } - boxRelayout(b); -} - -uiWindowsControlDefaultLayoutRect(uiBox) -uiWindowsControlDefaultAssignControlIDZOrder(uiBox) - -static void uiBoxChildVisibilityChanged(uiWindowsControl *c) -{ - // TODO eliminate the redundancy - uiWindowsControlMinimumSizeChanged(c); -} - -static void boxArrangeChildren(uiBox *b) -{ - LONG_PTR controlID; - HWND insertAfter; - - controlID = 100; - insertAfter = NULL; - for (const struct boxChild &bc : *(b->controls)) - uiWindowsControlAssignControlIDZOrder(uiWindowsControl(bc.c), &controlID, &insertAfter); -} - -void uiBoxAppend(uiBox *b, uiControl *c, int stretchy) -{ - struct boxChild bc; - - bc.c = c; - bc.stretchy = stretchy; - uiControlSetParent(bc.c, uiControl(b)); - uiWindowsControlSetParentHWND(uiWindowsControl(bc.c), b->hwnd); - b->controls->push_back(bc); - boxArrangeChildren(b); - uiWindowsControlMinimumSizeChanged(uiWindowsControl(b)); -} - -void uiBoxDelete(uiBox *b, int index) -{ - uiControl *c; - - c = (*(b->controls))[index].c; - uiControlSetParent(c, NULL); - uiWindowsControlSetParentHWND(uiWindowsControl(c), NULL); - b->controls->erase(b->controls->begin() + index); - boxArrangeChildren(b); - uiWindowsControlMinimumSizeChanged(uiWindowsControl(b)); -} - -int uiBoxPadded(uiBox *b) -{ - return b->padded; -} - -void uiBoxSetPadded(uiBox *b, int padded) -{ - b->padded = padded; - uiWindowsControlMinimumSizeChanged(uiWindowsControl(b)); -} - -static void onResize(uiWindowsControl *c) -{ - boxRelayout(uiBox(c)); -} - -static uiBox *finishNewBox(int vertical) -{ - uiBox *b; - - uiWindowsNewControl(uiBox, b); - - b->hwnd = uiWindowsMakeContainer(uiWindowsControl(b), onResize); - - b->vertical = vertical; - b->controls = new std::vector; - - return b; -} - -uiBox *uiNewHorizontalBox(void) -{ - return finishNewBox(0); -} - -uiBox *uiNewVerticalBox(void) -{ - return finishNewBox(1); -} diff --git a/deps/libui/windows/button.cpp b/deps/libui/windows/button.cpp deleted file mode 100644 index 3b12e726db..0000000000 --- a/deps/libui/windows/button.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// 7 april 2015 -#include "uipriv_windows.hpp" - -struct uiButton { - uiWindowsControl c; - HWND hwnd; - void (*onClicked)(uiButton *, void *); - void *onClickedData; -}; - -static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) -{ - uiButton *b = uiButton(c); - - if (code != BN_CLICKED) - return FALSE; - (*(b->onClicked))(b, b->onClickedData); - *lResult = 0; - return TRUE; -} - -static void uiButtonDestroy(uiControl *c) -{ - uiButton *b = uiButton(c); - - uiWindowsUnregisterWM_COMMANDHandler(b->hwnd); - uiWindowsEnsureDestroyWindow(b->hwnd); - uiFreeControl(uiControl(b)); -} - -uiWindowsControlAllDefaultsExceptDestroy(uiButton) - -// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define buttonHeight 14 - -static void uiButtonMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiButton *b = uiButton(c); - SIZE size; - uiWindowsSizing sizing; - int y; - - // try the comctl32 version 6 way - size.cx = 0; // explicitly ask for ideal size - size.cy = 0; - if (SendMessageW(b->hwnd, BCM_GETIDEALSIZE, 0, (LPARAM) (&size)) != FALSE) { - *width = size.cx; - *height = size.cy; - return; - } - - // that didn't work; fall back to using Microsoft's metrics - // Microsoft says to use a fixed width for all buttons; this isn't good enough - // use the text width instead, with some edge padding - *width = uiWindowsWindowTextWidth(b->hwnd) + (2 * GetSystemMetrics(SM_CXEDGE)); - y = buttonHeight; - uiWindowsGetSizing(b->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &y); - *height = y; -} - -static void defaultOnClicked(uiButton *b, void *data) -{ - // do nothing -} - -char *uiButtonText(uiButton *b) -{ - return uiWindowsWindowText(b->hwnd); -} - -void uiButtonSetText(uiButton *b, const char *text) -{ - uiWindowsSetWindowText(b->hwnd, text); - // changing the text might necessitate a change in the button's size - uiWindowsControlMinimumSizeChanged(uiWindowsControl(b)); -} - -void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *, void *), void *data) -{ - b->onClicked = f; - b->onClickedData = data; -} - -uiButton *uiNewButton(const char *text) -{ - uiButton *b; - WCHAR *wtext; - - uiWindowsNewControl(uiButton, b); - - wtext = toUTF16(text); - b->hwnd = uiWindowsEnsureCreateControlHWND(0, - L"button", wtext, - BS_PUSHBUTTON | WS_TABSTOP, - hInstance, NULL, - TRUE); - uiFree(wtext); - - uiWindowsRegisterWM_COMMANDHandler(b->hwnd, onWM_COMMAND, uiControl(b)); - uiButtonOnClicked(b, defaultOnClicked, NULL); - - return b; -} diff --git a/deps/libui/windows/checkbox.cpp b/deps/libui/windows/checkbox.cpp deleted file mode 100644 index be425c0041..0000000000 --- a/deps/libui/windows/checkbox.cpp +++ /dev/null @@ -1,117 +0,0 @@ -// 7 april 2015 -#include "uipriv_windows.hpp" - -struct uiCheckbox { - uiWindowsControl c; - HWND hwnd; - void (*onToggled)(uiCheckbox *, void *); - void *onToggledData; -}; - -static BOOL onWM_COMMAND(uiControl *cc, HWND hwnd, WORD code, LRESULT *lResult) -{ - uiCheckbox *c = uiCheckbox(cc); - WPARAM check; - - if (code != BN_CLICKED) - return FALSE; - - // we didn't use BS_AUTOCHECKBOX (http://blogs.msdn.com/b/oldnewthing/archive/2014/05/22/10527522.aspx) so we have to manage the check state ourselves - check = BST_CHECKED; - if (SendMessage(c->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED) - check = BST_UNCHECKED; - SendMessage(c->hwnd, BM_SETCHECK, check, 0); - - (*(c->onToggled))(c, c->onToggledData); - *lResult = 0; - return TRUE; -} - -static void uiCheckboxDestroy(uiControl *cc) -{ - uiCheckbox *c = uiCheckbox(cc); - - uiWindowsUnregisterWM_COMMANDHandler(c->hwnd); - uiWindowsEnsureDestroyWindow(c->hwnd); - uiFreeControl(uiControl(c)); -} - -uiWindowsControlAllDefaultsExceptDestroy(uiCheckbox) - -// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define checkboxHeight 10 -// from http://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx -#define checkboxXFromLeftOfBoxToLeftOfLabel 12 - -static void uiCheckboxMinimumSize(uiWindowsControl *cc, int *width, int *height) -{ - uiCheckbox *c = uiCheckbox(cc); - uiWindowsSizing sizing; - int x, y; - - x = checkboxXFromLeftOfBoxToLeftOfLabel; - y = checkboxHeight; - uiWindowsGetSizing(c->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); - *width = x + uiWindowsWindowTextWidth(c->hwnd); - *height = y; -} - -static void defaultOnToggled(uiCheckbox *c, void *data) -{ - // do nothing -} - -char *uiCheckboxText(uiCheckbox *c) -{ - return uiWindowsWindowText(c->hwnd); -} - -void uiCheckboxSetText(uiCheckbox *c, const char *text) -{ - uiWindowsSetWindowText(c->hwnd, text); - // changing the text might necessitate a change in the checkbox's size - uiWindowsControlMinimumSizeChanged(uiWindowsControl(c)); -} - -void uiCheckboxOnToggled(uiCheckbox *c, void (*f)(uiCheckbox *, void *), void *data) -{ - c->onToggled = f; - c->onToggledData = data; -} - -int uiCheckboxChecked(uiCheckbox *c) -{ - return SendMessage(c->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED; -} - -void uiCheckboxSetChecked(uiCheckbox *c, int checked) -{ - WPARAM check; - - check = BST_CHECKED; - if (!checked) - check = BST_UNCHECKED; - SendMessage(c->hwnd, BM_SETCHECK, check, 0); -} - -uiCheckbox *uiNewCheckbox(const char *text) -{ - uiCheckbox *c; - WCHAR *wtext; - - uiWindowsNewControl(uiCheckbox, c); - - wtext = toUTF16(text); - c->hwnd = uiWindowsEnsureCreateControlHWND(0, - L"button", wtext, - BS_CHECKBOX | WS_TABSTOP, - hInstance, NULL, - TRUE); - uiFree(wtext); - - uiWindowsRegisterWM_COMMANDHandler(c->hwnd, onWM_COMMAND, uiControl(c)); - uiCheckboxOnToggled(c, defaultOnToggled, NULL); - - return c; -} diff --git a/deps/libui/windows/colorbutton.cpp b/deps/libui/windows/colorbutton.cpp deleted file mode 100644 index c1ba6954ec..0000000000 --- a/deps/libui/windows/colorbutton.cpp +++ /dev/null @@ -1,192 +0,0 @@ -// 16 may 2016 -#include "uipriv_windows.hpp" - -struct uiColorButton { - uiWindowsControl c; - HWND hwnd; - double r; - double g; - double b; - double a; - void (*onChanged)(uiColorButton *, void *); - void *onChangedData; -}; - -static void uiColorButtonDestroy(uiControl *c) -{ - uiColorButton *b = uiColorButton(c); - - uiWindowsUnregisterWM_COMMANDHandler(b->hwnd); - uiWindowsUnregisterWM_NOTIFYHandler(b->hwnd); - uiWindowsEnsureDestroyWindow(b->hwnd); - uiFreeControl(uiControl(b)); -} - -static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) -{ - uiColorButton *b = uiColorButton(c); - HWND parent; - struct colorDialogRGBA rgba; - - if (code != BN_CLICKED) - return FALSE; - - parent = parentToplevel(b->hwnd); - rgba.r = b->r; - rgba.g = b->g; - rgba.b = b->b; - rgba.a = b->a; - if (showColorDialog(parent, &rgba)) { - b->r = rgba.r; - b->g = rgba.g; - b->b = rgba.b; - b->a = rgba.a; - invalidateRect(b->hwnd, NULL, TRUE); - (*(b->onChanged))(b, b->onChangedData); - } - - *lResult = 0; - return TRUE; -} - -static BOOL onWM_NOTIFY(uiControl *c, HWND hwnd, NMHDR *nmhdr, LRESULT *lResult) -{ - uiColorButton *b = uiColorButton(c); - NMCUSTOMDRAW *nm = (NMCUSTOMDRAW *) nmhdr; - RECT client; - ID2D1DCRenderTarget *rt; - D2D1_RECT_F r; - D2D1_COLOR_F color; - D2D1_BRUSH_PROPERTIES bprop; - ID2D1SolidColorBrush *brush; - uiWindowsSizing sizing; - int x, y; - HRESULT hr; - - if (nmhdr->code != NM_CUSTOMDRAW) - return FALSE; - // and allow the button to draw its background - if (nm->dwDrawStage != CDDS_PREPAINT) - return FALSE; - - uiWindowsEnsureGetClientRect(b->hwnd, &client); - rt = makeHDCRenderTarget(nm->hdc, &client); - rt->BeginDraw(); - - uiWindowsGetSizing(b->hwnd, &sizing); - x = 3; // should be enough - y = 3; - uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); - r.left = client.left + x; - r.top = client.top + y; - r.right = client.right - x; - r.bottom = client.bottom - y; - - color.r = b->r; - color.g = b->g; - color.b = b->b; - color.a = b->a; - ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES)); - bprop.opacity = 1.0; - bprop.transform._11 = 1; - bprop.transform._22 = 1; - hr = rt->CreateSolidColorBrush(&color, &bprop, &brush); - if (hr != S_OK) - logHRESULT(L"error creating brush for color button", hr); - rt->FillRectangle(&r, brush); - brush->Release(); - - hr = rt->EndDraw(NULL, NULL); - if (hr != S_OK) - logHRESULT(L"error drawing color on color button", hr); - rt->Release(); - - // skip default processing (don't draw text) - *lResult = CDRF_SKIPDEFAULT; - return TRUE; -} - -uiWindowsControlAllDefaultsExceptDestroy(uiColorButton) - -// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define buttonHeight 14 - -// TODO check widths -static void uiColorButtonMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiColorButton *b = uiColorButton(c); - SIZE size; - uiWindowsSizing sizing; - int y; - - // try the comctl32 version 6 way - size.cx = 0; // explicitly ask for ideal size - size.cy = 0; - if (SendMessageW(b->hwnd, BCM_GETIDEALSIZE, 0, (LPARAM) (&size)) != FALSE) { - *width = size.cx; - *height = size.cy; - return; - } - - // that didn't work; fall back to using Microsoft's metrics - // Microsoft says to use a fixed width for all buttons; this isn't good enough - // use the text width instead, with some edge padding - *width = uiWindowsWindowTextWidth(b->hwnd) + (2 * GetSystemMetrics(SM_CXEDGE)); - y = buttonHeight; - uiWindowsGetSizing(b->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &y); - *height = y; -} - -static void defaultOnChanged(uiColorButton *b, void *data) -{ - // do nothing -} - -void uiColorButtonColor(uiColorButton *b, double *r, double *g, double *bl, double *a) -{ - *r = b->r; - *g = b->g; - *bl = b->b; - *a = b->a; -} - -void uiColorButtonSetColor(uiColorButton *b, double r, double g, double bl, double a) -{ - b->r = r; - b->g = g; - b->b = bl; - b->a = a; - invalidateRect(b->hwnd, NULL, TRUE); -} - -void uiColorButtonOnChanged(uiColorButton *b, void (*f)(uiColorButton *, void *), void *data) -{ - b->onChanged = f; - b->onChangedData = data; -} - -uiColorButton *uiNewColorButton(void) -{ - uiColorButton *b; - - uiWindowsNewControl(uiColorButton, b); - - // initial color is black - b->r = 0.0; - b->g = 0.0; - b->b = 0.0; - b->a = 1.0; - - b->hwnd = uiWindowsEnsureCreateControlHWND(0, - L"button", L" ", // TODO; can't use "" TODO - BS_PUSHBUTTON | WS_TABSTOP, - hInstance, NULL, - TRUE); - - uiWindowsRegisterWM_COMMANDHandler(b->hwnd, onWM_COMMAND, uiControl(b)); - uiWindowsRegisterWM_NOTIFYHandler(b->hwnd, onWM_NOTIFY, uiControl(b)); - uiColorButtonOnChanged(b, defaultOnChanged, NULL); - - return b; -} diff --git a/deps/libui/windows/colordialog.cpp b/deps/libui/windows/colordialog.cpp deleted file mode 100644 index 2efe72c8c8..0000000000 --- a/deps/libui/windows/colordialog.cpp +++ /dev/null @@ -1,1264 +0,0 @@ -// 16 may 2016 -#include "uipriv_windows.hpp" - -// TODO should the d2dscratch programs capture mouse? - -struct colorDialog { - HWND hwnd; - - HWND svChooser; - HWND hSlider; - HWND preview; - HWND opacitySlider; - HWND editH; - HWND editS; - HWND editV; - HWND editRDouble, editRInt; - HWND editGDouble, editGInt; - HWND editBDouble, editBInt; - HWND editADouble, editAInt; - HWND editHex; - - double h; - double s; - double v; - double a; - struct colorDialogRGBA *out; - - BOOL updating; -}; - -// both of these are from the wikipedia page on HSV -// TODO what to do about negative h? -static void rgb2HSV(double r, double g, double b, double *h, double *s, double *v) -{ - double M, m; - int whichmax; - double c; - - M = r; - whichmax = 0; - if (M < g) { - M = g; - whichmax = 1; - } - if (M < b) { - M = b; - whichmax = 2; - } - m = r; - if (m > g) - m = g; - if (m > b) - m = b; - c = M - m; - - if (c == 0) - *h = 0; - else { - switch (whichmax) { - case 0: - *h = ((g - b) / c); - *h = fmod(*h, 6); - break; - case 1: - *h = ((b - r) / c) + 2; - break; - case 2: - *h = ((r - g) / c) + 4; - break; - } - *h /= 6; // put in range [0,1) - } - - *v = M; - - if (c == 0) - *s = 0; - else - *s = c / *v; -} - -// TODO negative R values? -static void hsv2RGB(double h, double s, double v, double *r, double *g, double *b) -{ - double c; - double hPrime; - int h60; - double x; - double m; - double c1, c2; - - c = v * s; - hPrime = h * 6; - h60 = (int) hPrime; // equivalent to splitting into 60° chunks - x = c * (1.0 - fabs(fmod(hPrime, 2) - 1.0)); - m = v - c; - switch (h60) { - case 0: - *r = c + m; - *g = x + m; - *b = m; - return; - case 1: - *r = x + m; - *g = c + m; - *b = m; - return; - case 2: - *r = m; - *g = c + m; - *b = x + m; - return; - case 3: - *r = m; - *g = x + m; - *b = c + m; - return; - case 4: - *r = x + m; - *g = m; - *b = c + m; - return; - case 5: - *r = c + m; - *g = m; - *b = x + m; - return; - } - // TODO -} - -#define hexd L"0123456789ABCDEF" - -static void rgba2Hex(uint8_t r, uint8_t g, uint8_t b, uint8_t a, WCHAR *buf) -{ - buf[0] = L'#'; - buf[1] = hexd[(a >> 4) & 0xF]; - buf[2] = hexd[a & 0xF]; - buf[3] = hexd[(r >> 4) & 0xF]; - buf[4] = hexd[r & 0xF]; - buf[5] = hexd[(g >> 4) & 0xF]; - buf[6] = hexd[g & 0xF]; - buf[7] = hexd[(b >> 4) & 0xF]; - buf[8] = hexd[b & 0xF]; - buf[9] = L'\0'; -} - -static int convHexDigit(WCHAR c) -{ - if (c >= L'0' && c <= L'9') - return c - L'0'; - if (c >= L'A' && c <= L'F') - return c - L'A' + 0xA; - if (c >= L'a' && c <= L'f') - return c - L'a' + 0xA; - return -1; -} - -// TODO allow #NNN shorthand -static BOOL hex2RGBA(WCHAR *buf, double *r, double *g, double *b, double *a) -{ - uint8_t component; - int i; - - if (*buf == L'#') - buf++; - - component = 0; - i = convHexDigit(*buf++); - if (i < 0) - return FALSE; - component |= ((uint8_t) i) << 4; - i = convHexDigit(*buf++); - if (i < 0) - return FALSE; - component |= ((uint8_t) i); - *a = ((double) component) / 255; - - component = 0; - i = convHexDigit(*buf++); - if (i < 0) - return FALSE; - component |= ((uint8_t) i) << 4; - i = convHexDigit(*buf++); - if (i < 0) - return FALSE; - component |= ((uint8_t) i); - *r = ((double) component) / 255; - - component = 0; - i = convHexDigit(*buf++); - if (i < 0) - return FALSE; - component |= ((uint8_t) i) << 4; - i = convHexDigit(*buf++); - if (i < 0) - return FALSE; - component |= ((uint8_t) i); - *g = ((double) component) / 255; - - if (*buf == L'\0') { // #NNNNNN syntax - *b = *g; - *g = *r; - *r = *a; - *a = 1; - return TRUE; - } - - component = 0; - i = convHexDigit(*buf++); - if (i < 0) - return FALSE; - component |= ((uint8_t) i) << 4; - i = convHexDigit(*buf++); - if (i < 0) - return FALSE; - component |= ((uint8_t) i); - *b = ((double) component) / 255; - - return *buf == L'\0'; -} - -static void updateDouble(HWND hwnd, double d, HWND whichChanged) -{ - WCHAR *str; - - if (whichChanged == hwnd) - return; - str = ftoutf16(d); - setWindowText(hwnd, str); - uiFree(str); -} - -static void updateDialog(struct colorDialog *c, HWND whichChanged) -{ - double r, g, b; - uint8_t rb, gb, bb, ab; - WCHAR *str; - WCHAR hexbuf[16]; // more than enough - - c->updating = TRUE; - - updateDouble(c->editH, c->h, whichChanged); - updateDouble(c->editS, c->s, whichChanged); - updateDouble(c->editV, c->v, whichChanged); - - hsv2RGB(c->h, c->s, c->v, &r, &g, &b); - - updateDouble(c->editRDouble, r, whichChanged); - updateDouble(c->editGDouble, g, whichChanged); - updateDouble(c->editBDouble, b, whichChanged); - updateDouble(c->editADouble, c->a, whichChanged); - - rb = (uint8_t) (r * 255); - gb = (uint8_t) (g * 255); - bb = (uint8_t) (b * 255); - ab = (uint8_t) (c->a * 255); - - if (whichChanged != c->editRInt) { - str = itoutf16(rb); - setWindowText(c->editRInt, str); - uiFree(str); - } - if (whichChanged != c->editGInt) { - str = itoutf16(gb); - setWindowText(c->editGInt, str); - uiFree(str); - } - if (whichChanged != c->editBInt) { - str = itoutf16(bb); - setWindowText(c->editBInt, str); - uiFree(str); - } - if (whichChanged != c->editAInt) { - str = itoutf16(ab); - setWindowText(c->editAInt, str); - uiFree(str); - } - - if (whichChanged != c->editHex) { - rgba2Hex(rb, gb, bb, ab, hexbuf); - setWindowText(c->editHex, hexbuf); - } - - // TODO TRUE? - invalidateRect(c->svChooser, NULL, TRUE); - invalidateRect(c->hSlider, NULL, TRUE); - invalidateRect(c->preview, NULL, TRUE); - invalidateRect(c->opacitySlider, NULL, TRUE); - - c->updating = FALSE; -} - -// this imitates http://blogs.msdn.com/b/wpfsdk/archive/2006/10/26/uncommon-dialogs--font-chooser-and-color-picker-dialogs.aspx -static void drawGrid(ID2D1RenderTarget *rt, D2D1_RECT_F *fillRect) -{ - D2D1_SIZE_F size; - D2D1_PIXEL_FORMAT pformat; - ID2D1BitmapRenderTarget *brt; - D2D1_COLOR_F color; - D2D1_BRUSH_PROPERTIES bprop; - ID2D1SolidColorBrush *brush; - D2D1_RECT_F rect; - ID2D1Bitmap *bitmap; - D2D1_BITMAP_BRUSH_PROPERTIES bbp; - ID2D1BitmapBrush *bb; - HRESULT hr; - - // mind the divisions; they represent the fact the original uses a viewport - size.width = 100 / 10; - size.height = 100 / 10; - // yay more ABI bugs -#ifdef _MSC_VER - pformat = rt->GetPixelFormat(); -#else - { - typedef D2D1_PIXEL_FORMAT *(__stdcall ID2D1RenderTarget::* GetPixelFormatF)(D2D1_PIXEL_FORMAT *); - GetPixelFormatF gpf; - - gpf = (GetPixelFormatF) (&(rt->GetPixelFormat)); - (rt->*gpf)(&pformat); - } -#endif - hr = rt->CreateCompatibleRenderTarget(&size, NULL, - &pformat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, - &brt); - if (hr != S_OK) - logHRESULT(L"error creating render target for grid", hr); - - brt->BeginDraw(); - - color.r = 1.0; - color.g = 1.0; - color.b = 1.0; - color.a = 1.0; - brt->Clear(&color); - - color = D2D1::ColorF(D2D1::ColorF::LightGray, 1.0); - ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES)); - bprop.opacity = 1.0; - bprop.transform._11 = 1; - bprop.transform._22 = 1; - hr = brt->CreateSolidColorBrush(&color, &bprop, &brush); - if (hr != S_OK) - logHRESULT(L"error creating brush for grid", hr); - rect.left = 0; - rect.top = 0; - rect.right = 50 / 10; - rect.bottom = 50 / 10; - brt->FillRectangle(&rect, brush); - rect.left = 50 / 10; - rect.top = 50 / 10; - rect.right = 100 / 10; - rect.bottom = 100 / 10; - brt->FillRectangle(&rect, brush); - brush->Release(); - - hr = brt->EndDraw(NULL, NULL); - if (hr != S_OK) - logHRESULT(L"error finalizing render target for grid", hr); - hr = brt->GetBitmap(&bitmap); - if (hr != S_OK) - logHRESULT(L"error getting bitmap for grid", hr); - brt->Release(); - - ZeroMemory(&bbp, sizeof (D2D1_BITMAP_BRUSH_PROPERTIES)); - bbp.extendModeX = D2D1_EXTEND_MODE_WRAP; - bbp.extendModeY = D2D1_EXTEND_MODE_WRAP; - bbp.interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR; - hr = rt->CreateBitmapBrush(bitmap, &bbp, &bprop, &bb); - if (hr != S_OK) - logHRESULT(L"error creating bitmap brush for grid", hr); - rt->FillRectangle(fillRect, bb); - bb->Release(); - bitmap->Release(); -} - -// this interesting approach comes from http://blogs.msdn.com/b/wpfsdk/archive/2006/10/26/uncommon-dialogs--font-chooser-and-color-picker-dialogs.aspx -static void drawSVChooser(struct colorDialog *c, ID2D1RenderTarget *rt) -{ - D2D1_SIZE_F size; - D2D1_RECT_F rect; - double rTop, gTop, bTop; - D2D1_GRADIENT_STOP stops[2]; - ID2D1GradientStopCollection *collection; - D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES lprop; - D2D1_BRUSH_PROPERTIES bprop; - ID2D1LinearGradientBrush *brush; - ID2D1LinearGradientBrush *opacity; - ID2D1Layer *layer; - D2D1_LAYER_PARAMETERS layerparams; - D2D1_ELLIPSE mparam; - D2D1_COLOR_F mcolor; - ID2D1SolidColorBrush *markerBrush; - HRESULT hr; - - size = realGetSize(rt); - rect.left = 0; - rect.top = 0; - rect.right = size.width; - rect.bottom = size.height; - - drawGrid(rt, &rect); - - // first, draw a vertical gradient from the current hue at max S/V to black - // the source example draws it upside down; let's do so too just to be safe - hsv2RGB(c->h, 1.0, 1.0, &rTop, &gTop, &bTop); - stops[0].position = 0; - stops[0].color.r = 0.0; - stops[0].color.g = 0.0; - stops[0].color.b = 0.0; - stops[0].color.a = 1.0; - stops[1].position = 1; - stops[1].color.r = rTop; - stops[1].color.g = gTop; - stops[1].color.b = bTop; - stops[1].color.a = 1.0; - hr = rt->CreateGradientStopCollection(stops, 2, - D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, - &collection); - if (hr != S_OK) - logHRESULT(L"error making gradient stop collection for first gradient in SV chooser", hr); - ZeroMemory(&lprop, sizeof (D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES)); - lprop.startPoint.x = size.width / 2; - lprop.startPoint.y = size.height; - lprop.endPoint.x = size.width / 2; - lprop.endPoint.y = 0; - // TODO decide what to do about the duplication of this - ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES)); - bprop.opacity = c->a; // note this part; we also use it below for the layer - bprop.transform._11 = 1; - bprop.transform._22 = 1; - hr = rt->CreateLinearGradientBrush(&lprop, &bprop, - collection, &brush); - if (hr != S_OK) - logHRESULT(L"error making gradient brush for first gradient in SV chooser", hr); - rt->FillRectangle(&rect, brush); - brush->Release(); - collection->Release(); - - // second, create an opacity mask for the third step: a horizontal gradientthat goes from opaque to translucent - stops[0].position = 0; - stops[0].color.r = 0.0; - stops[0].color.g = 0.0; - stops[0].color.b = 0.0; - stops[0].color.a = 1.0; - stops[1].position = 1; - stops[1].color.r = 0.0; - stops[1].color.g = 0.0; - stops[1].color.b = 0.0; - stops[1].color.a = 0.0; - hr = rt->CreateGradientStopCollection(stops, 2, - D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, - &collection); - if (hr != S_OK) - logHRESULT(L"error making gradient stop collection for opacity mask gradient in SV chooser", hr); - ZeroMemory(&lprop, sizeof (D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES)); - lprop.startPoint.x = 0; - lprop.startPoint.y = size.height / 2; - lprop.endPoint.x = size.width; - lprop.endPoint.y = size.height / 2; - ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES)); - bprop.opacity = 1.0; - bprop.transform._11 = 1; - bprop.transform._22 = 1; - hr = rt->CreateLinearGradientBrush(&lprop, &bprop, - collection, &opacity); - if (hr != S_OK) - logHRESULT(L"error making gradient brush for opacity mask gradient in SV chooser", hr); - collection->Release(); - - // finally, make a vertical gradient from white at the top to black at the bottom (right side up this time) and with the previous opacity mask - stops[0].position = 0; - stops[0].color.r = 1.0; - stops[0].color.g = 1.0; - stops[0].color.b = 1.0; - stops[0].color.a = 1.0; - stops[1].position = 1; - stops[1].color.r = 0.0; - stops[1].color.g = 0.0; - stops[1].color.b = 0.0; - stops[1].color.a = 1.0; - hr = rt->CreateGradientStopCollection(stops, 2, - D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, - &collection); - if (hr != S_OK) - logHRESULT(L"error making gradient stop collection for second gradient in SV chooser", hr); - ZeroMemory(&lprop, sizeof (D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES)); - lprop.startPoint.x = size.width / 2; - lprop.startPoint.y = 0; - lprop.endPoint.x = size.width / 2; - lprop.endPoint.y = size.height; - ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES)); - bprop.opacity = 1.0; - bprop.transform._11 = 1; - bprop.transform._22 = 1; - hr = rt->CreateLinearGradientBrush(&lprop, &bprop, - collection, &brush); - if (hr != S_OK) - logHRESULT(L"error making gradient brush for second gradient in SV chooser", hr); - // oh but wait we can't use FillRectangle() with an opacity mask - // and we can't use FillGeometry() with both an opacity mask and a non-bitmap - // layers it is! - hr = rt->CreateLayer(&size, &layer); - if (hr != S_OK) - logHRESULT(L"error making layer for second gradient in SV chooser", hr); - ZeroMemory(&layerparams, sizeof (D2D1_LAYER_PARAMETERS)); - layerparams.contentBounds = rect; - // TODO make sure these are right - layerparams.geometricMask = NULL; - layerparams.maskAntialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE; - layerparams.maskTransform._11 = 1; - layerparams.maskTransform._22 = 1; - layerparams.opacity = c->a; // here's the other use of c->a to note - layerparams.opacityBrush = opacity; - layerparams.layerOptions = D2D1_LAYER_OPTIONS_NONE; - rt->PushLayer(&layerparams, layer); - rt->FillRectangle(&rect, brush); - rt->PopLayer(); - layer->Release(); - brush->Release(); - collection->Release(); - opacity->Release(); - - // and now we just draw the marker - ZeroMemory(&mparam, sizeof (D2D1_ELLIPSE)); - mparam.point.x = c->s * size.width; - mparam.point.y = (1 - c->v) * size.height; - mparam.radiusX = 7; - mparam.radiusY = 7; - // TODO make the color contrast? - mcolor.r = 1.0; - mcolor.g = 1.0; - mcolor.b = 1.0; - mcolor.a = 1.0; - bprop.opacity = 1.0; // the marker should always be opaque - hr = rt->CreateSolidColorBrush(&mcolor, &bprop, &markerBrush); - if (hr != S_OK) - logHRESULT(L"error creating brush for SV chooser marker", hr); - rt->DrawEllipse(&mparam, markerBrush, 2, NULL); - markerBrush->Release(); -} - -static LRESULT CALLBACK svChooserSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) -{ - ID2D1RenderTarget *rt; - struct colorDialog *c; - D2D1_POINT_2F *pos; - D2D1_SIZE_F *size; - - c = (struct colorDialog *) dwRefData; - switch (uMsg) { - case msgD2DScratchPaint: - rt = (ID2D1RenderTarget *) lParam; - drawSVChooser(c, rt); - return 0; - case msgD2DScratchLButtonDown: - pos = (D2D1_POINT_2F *) wParam; - size = (D2D1_SIZE_F *) lParam; - c->s = pos->x / size->width; - c->v = 1 - (pos->y / size->height); - updateDialog(c, NULL); - return 0; - case WM_NCDESTROY: - if (RemoveWindowSubclass(hwnd, svChooserSubProc, uIdSubclass) == FALSE) - logLastError(L"error removing color dialog SV chooser subclass"); - break; - } - return DefSubclassProc(hwnd, uMsg, wParam, lParam); -} - -static void drawArrow(ID2D1RenderTarget *rt, D2D1_POINT_2F center, double hypot) -{ - double leg; - D2D1_RECT_F rect; - D2D1_MATRIX_3X2_F oldtf, rotate; - D2D1_COLOR_F color; - D2D1_BRUSH_PROPERTIES bprop; - ID2D1SolidColorBrush *brush; - HRESULT hr; - - // to avoid needing a geometry, this will just be a rotated square - // compute the length of each side; the diagonal of the square is 2 * offset to gradient - // a^2 + a^2 = c^2 -> 2a^2 = c^2 - // a = sqrt(c^2/2) - hypot *= hypot; - hypot /= 2; - leg = sqrt(hypot); - rect.left = center.x - leg; - rect.top = center.y - leg; - rect.right = center.x + leg; - rect.bottom = center.y + leg; - - // now we need to rotate the render target 45° (either way works) about the center point - rt->GetTransform(&oldtf); - rotate = oldtf * D2D1::Matrix3x2F::Rotation(45, center); - rt->SetTransform(&rotate); - - // and draw - color.r = 0.0; - color.g = 0.0; - color.b = 0.0; - color.a = 1.0; - ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES)); - bprop.opacity = 1.0; - bprop.transform._11 = 1; - bprop.transform._22 = 1; - hr = rt->CreateSolidColorBrush(&color, &bprop, &brush); - if (hr != S_OK) - logHRESULT(L"error creating brush for arrow", hr); - rt->FillRectangle(&rect, brush); - brush->Release(); - - // clean up - rt->SetTransform(&oldtf); -} - -// the gradient stuff also comes from http://blogs.msdn.com/b/wpfsdk/archive/2006/10/26/uncommon-dialogs--font-chooser-and-color-picker-dialogs.aspx -#define nStops (30) -#define degPerStop (360 / nStops) -#define stopIncr (1.0 / ((double) nStops)) - -static void drawHSlider(struct colorDialog *c, ID2D1RenderTarget *rt) -{ - D2D1_SIZE_F size; - D2D1_RECT_F rect; - D2D1_GRADIENT_STOP stops[nStops]; - double r, g, b; - int i; - double h; - ID2D1GradientStopCollection *collection; - D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES lprop; - D2D1_BRUSH_PROPERTIES bprop; - ID2D1LinearGradientBrush *brush; - double hypot; - D2D1_POINT_2F center; - HRESULT hr; - - size = realGetSize(rt); - rect.left = size.width / 6; // leftmost sixth for arrow - rect.top = 0; - rect.right = size.width; - rect.bottom = size.height; - - for (i = 0; i < nStops; i++) { - h = ((double) (i * degPerStop)) / 360.0; - if (i == (nStops - 1)) - h = 0; - hsv2RGB(h, 1.0, 1.0, &r, &g, &b); - stops[i].position = ((double) i) * stopIncr; - stops[i].color.r = r; - stops[i].color.g = g; - stops[i].color.b = b; - stops[i].color.a = 1.0; - } - // and pin the last one - stops[i - 1].position = 1.0; - - hr = rt->CreateGradientStopCollection(stops, nStops, - // note that in this case this gamma is explicitly specified by the original - D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, - &collection); - if (hr != S_OK) - logHRESULT(L"error creating stop collection for H slider gradient", hr); - ZeroMemory(&lprop, sizeof (D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES)); - lprop.startPoint.x = (rect.right - rect.left) / 2; - lprop.startPoint.y = 0; - lprop.endPoint.x = (rect.right - rect.left) / 2; - lprop.endPoint.y = size.height; - ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES)); - bprop.opacity = 1.0; - bprop.transform._11 = 1; - bprop.transform._22 = 1; - hr = rt->CreateLinearGradientBrush(&lprop, &bprop, - collection, &brush); - if (hr != S_OK) - logHRESULT(L"error creating gradient brush for H slider", hr); - rt->FillRectangle(&rect, brush); - brush->Release(); - collection->Release(); - - // now draw a black arrow - center.x = 0; - center.y = c->h * size.height; - hypot = rect.left; - drawArrow(rt, center, hypot); -} - -static LRESULT CALLBACK hSliderSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) -{ - ID2D1RenderTarget *rt; - struct colorDialog *c; - D2D1_POINT_2F *pos; - D2D1_SIZE_F *size; - - c = (struct colorDialog *) dwRefData; - switch (uMsg) { - case msgD2DScratchPaint: - rt = (ID2D1RenderTarget *) lParam; - drawHSlider(c, rt); - return 0; - case msgD2DScratchLButtonDown: - pos = (D2D1_POINT_2F *) wParam; - size = (D2D1_SIZE_F *) lParam; - c->h = pos->y / size->height; - updateDialog(c, NULL); - return 0; - case WM_NCDESTROY: - if (RemoveWindowSubclass(hwnd, hSliderSubProc, uIdSubclass) == FALSE) - logLastError(L"error removing color dialog H slider subclass"); - break; - } - return DefSubclassProc(hwnd, uMsg, wParam, lParam); -} - -static void drawPreview(struct colorDialog *c, ID2D1RenderTarget *rt) -{ - D2D1_SIZE_F size; - D2D1_RECT_F rect; - double r, g, b; - D2D1_COLOR_F color; - D2D1_BRUSH_PROPERTIES bprop; - ID2D1SolidColorBrush *brush; - HRESULT hr; - - size = realGetSize(rt); - rect.left = 0; - rect.top = 0; - rect.right = size.width; - rect.bottom = size.height; - - drawGrid(rt, &rect); - - hsv2RGB(c->h, c->s, c->v, &r, &g, &b); - color.r = r; - color.g = g; - color.b = b; - color.a = c->a; - ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES)); - bprop.opacity = 1.0; - bprop.transform._11 = 1; - bprop.transform._22 = 1; - hr = rt->CreateSolidColorBrush(&color, &bprop, &brush); - if (hr != S_OK) - logHRESULT(L"error creating brush for preview", hr); - rt->FillRectangle(&rect, brush); - brush->Release(); -} - -static LRESULT CALLBACK previewSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) -{ - ID2D1RenderTarget *rt; - struct colorDialog *c; - - c = (struct colorDialog *) dwRefData; - switch (uMsg) { - case msgD2DScratchPaint: - rt = (ID2D1RenderTarget *) lParam; - drawPreview(c, rt); - return 0; - case WM_NCDESTROY: - if (RemoveWindowSubclass(hwnd, previewSubProc, uIdSubclass) == FALSE) - logLastError(L"error removing color dialog previewer subclass"); - break; - } - return DefSubclassProc(hwnd, uMsg, wParam, lParam); -} - -// once again, this is based on the Microsoft sample above -static void drawOpacitySlider(struct colorDialog *c, ID2D1RenderTarget *rt) -{ - D2D1_SIZE_F size; - D2D1_RECT_F rect; - D2D1_GRADIENT_STOP stops[2]; - ID2D1GradientStopCollection *collection; - D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES lprop; - D2D1_BRUSH_PROPERTIES bprop; - ID2D1LinearGradientBrush *brush; - double hypot; - D2D1_POINT_2F center; - HRESULT hr; - - size = realGetSize(rt); - rect.left = 0; - rect.top = 0; - rect.right = size.width; - rect.bottom = size.height * (5.0 / 6.0); // bottommost sixth for arrow - - drawGrid(rt, &rect); - - stops[0].position = 0.0; - stops[0].color.r = 0.0; - stops[0].color.g = 0.0; - stops[0].color.b = 0.0; - stops[0].color.a = 1.0; - stops[1].position = 1.0; - stops[1].color.r = 1.0; // this is the XAML color Transparent, as in the source - stops[1].color.g = 1.0; - stops[1].color.b = 1.0; - stops[1].color.a = 0.0; - hr = rt->CreateGradientStopCollection(stops, 2, - // note that in this case this gamma is explicitly specified by the original - D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, - &collection); - if (hr != S_OK) - logHRESULT(L"error creating stop collection for opacity slider gradient", hr); - ZeroMemory(&lprop, sizeof (D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES)); - lprop.startPoint.x = 0; - lprop.startPoint.y = (rect.bottom - rect.top) / 2; - lprop.endPoint.x = size.width; - lprop.endPoint.y = (rect.bottom - rect.top) / 2; - ZeroMemory(&bprop, sizeof (D2D1_BRUSH_PROPERTIES)); - bprop.opacity = 1.0; - bprop.transform._11 = 1; - bprop.transform._22 = 1; - hr = rt->CreateLinearGradientBrush(&lprop, &bprop, - collection, &brush); - if (hr != S_OK) - logHRESULT(L"error creating gradient brush for opacity slider", hr); - rt->FillRectangle(&rect, brush); - brush->Release(); - collection->Release(); - - // now draw a black arrow - center.x = (1 - c->a) * size.width; - center.y = size.height; - hypot = size.height - rect.bottom; - drawArrow(rt, center, hypot); -} - -static LRESULT CALLBACK opacitySliderSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) -{ - ID2D1RenderTarget *rt; - struct colorDialog *c; - D2D1_POINT_2F *pos; - D2D1_SIZE_F *size; - - c = (struct colorDialog *) dwRefData; - switch (uMsg) { - case msgD2DScratchPaint: - rt = (ID2D1RenderTarget *) lParam; - drawOpacitySlider(c, rt); - return 0; - case msgD2DScratchLButtonDown: - pos = (D2D1_POINT_2F *) wParam; - size = (D2D1_SIZE_F *) lParam; - c->a = 1 - (pos->x / size->width); - updateDialog(c, NULL); - return 0; - case WM_NCDESTROY: - if (RemoveWindowSubclass(hwnd, opacitySliderSubProc, uIdSubclass) == FALSE) - logLastError(L"error removing color dialog opacity slider subclass"); - break; - } - return DefSubclassProc(hwnd, uMsg, wParam, lParam); -} - -// TODO extract into d2dscratch.cpp, use in font dialog -HWND replaceWithD2DScratch(HWND parent, int id, SUBCLASSPROC subproc, void *data) -{ - HWND replace; - RECT r; - - replace = getDlgItem(parent, id); - uiWindowsEnsureGetWindowRect(replace, &r); - mapWindowRect(NULL, parent, &r); - uiWindowsEnsureDestroyWindow(replace); - return newD2DScratch(parent, &r, (HMENU) id, subproc, (DWORD_PTR) data); - // TODO preserve Z-order -} - -// a few issues: -// - some controls are positioned wrong; see http://stackoverflow.com/questions/37263267/why-are-some-of-my-controls-positioned-slightly-off-in-a-dialog-template-in-a-re -// - labels are too low; need to adjust them by the font's internal leading -// fixupControlPositions() and the following helper routines fix that for us - -static LONG offsetTo(HWND a, HWND b) -{ - RECT ra, rb; - - uiWindowsEnsureGetWindowRect(a, &ra); - uiWindowsEnsureGetWindowRect(b, &rb); - return rb.top - ra.bottom; -} - -static void moveWindowsUp(struct colorDialog *c, LONG by, ...) -{ - va_list ap; - HWND cur; - RECT r; - - va_start(ap, by); - for (;;) { - cur = va_arg(ap, HWND); - if (cur == NULL) - break; - uiWindowsEnsureGetWindowRect(cur, &r); - mapWindowRect(NULL, c->hwnd, &r); - r.top -= by; - r.bottom -= by; - // TODO this isn't technically during a resize - uiWindowsEnsureMoveWindowDuringResize(cur, - r.left, r.top, - r.right - r.left, r.bottom - r.top); - } - va_end(ap); -} - -static void fixupControlPositions(struct colorDialog *c) -{ - HWND labelH; - HWND labelS; - HWND labelV; - HWND labelR; - HWND labelG; - HWND labelB; - HWND labelA; - HWND labelHex; - LONG offset; - uiWindowsSizing sizing; - - labelH = getDlgItem(c->hwnd, rcHLabel); - labelS = getDlgItem(c->hwnd, rcSLabel); - labelV = getDlgItem(c->hwnd, rcVLabel); - labelR = getDlgItem(c->hwnd, rcRLabel); - labelG = getDlgItem(c->hwnd, rcGLabel); - labelB = getDlgItem(c->hwnd, rcBLabel); - labelA = getDlgItem(c->hwnd, rcALabel); - labelHex = getDlgItem(c->hwnd, rcHexLabel); - - offset = offsetTo(c->editH, c->editS); - moveWindowsUp(c, offset, - labelS, c->editS, - labelG, c->editGDouble, c->editGInt, - NULL); - offset = offsetTo(c->editS, c->editV); - moveWindowsUp(c, offset, - labelV, c->editV, - labelB, c->editBDouble, c->editBInt, - NULL); - offset = offsetTo(c->editBDouble, c->editADouble); - moveWindowsUp(c, offset, - labelA, c->editADouble, c->editAInt, - NULL); - - getSizing(c->hwnd, &sizing, (HFONT) SendMessageW(labelH, WM_GETFONT, 0, 0)); - offset = sizing.InternalLeading; - moveWindowsUp(c, offset, - labelH, labelS, labelV, - labelR, labelG, labelB, labelA, - labelHex, - NULL); -} - -static struct colorDialog *beginColorDialog(HWND hwnd, LPARAM lParam) -{ - struct colorDialog *c; - - c = uiNew(struct colorDialog); - c->hwnd = hwnd; - c->out = (struct colorDialogRGBA *) lParam; - // load initial values now - rgb2HSV(c->out->r, c->out->g, c->out->b, &(c->h), &(c->s), &(c->v)); - c->a = c->out->a; - - // TODO set up d2dscratches - - // TODO prefix all these with rcColor instead of just rc - c->editH = getDlgItem(c->hwnd, rcH); - c->editS = getDlgItem(c->hwnd, rcS); - c->editV = getDlgItem(c->hwnd, rcV); - c->editRDouble = getDlgItem(c->hwnd, rcRDouble); - c->editRInt = getDlgItem(c->hwnd, rcRInt); - c->editGDouble = getDlgItem(c->hwnd, rcGDouble); - c->editGInt = getDlgItem(c->hwnd, rcGInt); - c->editBDouble = getDlgItem(c->hwnd, rcBDouble); - c->editBInt = getDlgItem(c->hwnd, rcBInt); - c->editADouble = getDlgItem(c->hwnd, rcADouble); - c->editAInt = getDlgItem(c->hwnd, rcAInt); - c->editHex = getDlgItem(c->hwnd, rcHex); - - c->svChooser = replaceWithD2DScratch(c->hwnd, rcColorSVChooser, svChooserSubProc, c); - c->hSlider = replaceWithD2DScratch(c->hwnd, rcColorHSlider, hSliderSubProc, c); - c->preview = replaceWithD2DScratch(c->hwnd, rcPreview, previewSubProc, c); - c->opacitySlider = replaceWithD2DScratch(c->hwnd, rcOpacitySlider, opacitySliderSubProc, c); - - fixupControlPositions(c); - - // and get the ball rolling - updateDialog(c, NULL); - return c; -} - -static void endColorDialog(struct colorDialog *c, INT_PTR code) -{ - if (EndDialog(c->hwnd, code) == 0) - logLastError(L"error ending color dialog"); - uiFree(c); -} - -// TODO make this void on the font dialog too -static void tryFinishDialog(struct colorDialog *c, WPARAM wParam) -{ - // cancelling - if (LOWORD(wParam) != IDOK) { - endColorDialog(c, 1); - return; - } - - // OK - hsv2RGB(c->h, c->s, c->v, &(c->out->r), &(c->out->g), &(c->out->b)); - c->out->a = c->a; - endColorDialog(c, 2); -} - -static double editDouble(HWND hwnd) -{ - WCHAR *s; - double d; - - s = windowText(hwnd); - d = _wtof(s); - uiFree(s); - return d; -} - -static void hChanged(struct colorDialog *c) -{ - double h; - - h = editDouble(c->editH); - if (h < 0 || h >= 1.0) // note the >= - return; - c->h = h; - updateDialog(c, c->editH); -} - -static void sChanged(struct colorDialog *c) -{ - double s; - - s = editDouble(c->editS); - if (s < 0 || s > 1) - return; - c->s = s; - updateDialog(c, c->editS); -} - -static void vChanged(struct colorDialog *c) -{ - double v; - - v = editDouble(c->editV); - if (v < 0 || v > 1) - return; - c->v = v; - updateDialog(c, c->editV); -} - -static void rDoubleChanged(struct colorDialog *c) -{ - double r, g, b; - - hsv2RGB(c->h, c->s, c->v, &r, &g, &b); - r = editDouble(c->editRDouble); - if (r < 0 || r > 1) - return; - rgb2HSV(r, g, b, &(c->h), &(c->s), &(c->v)); - updateDialog(c, c->editRDouble); -} - -static void gDoubleChanged(struct colorDialog *c) -{ - double r, g, b; - - hsv2RGB(c->h, c->s, c->v, &r, &g, &b); - g = editDouble(c->editGDouble); - if (g < 0 || g > 1) - return; - rgb2HSV(r, g, b, &(c->h), &(c->s), &(c->v)); - updateDialog(c, c->editGDouble); -} - -static void bDoubleChanged(struct colorDialog *c) -{ - double r, g, b; - - hsv2RGB(c->h, c->s, c->v, &r, &g, &b); - b = editDouble(c->editBDouble); - if (b < 0 || b > 1) - return; - rgb2HSV(r, g, b, &(c->h), &(c->s), &(c->v)); - updateDialog(c, c->editBDouble); -} - -static void aDoubleChanged(struct colorDialog *c) -{ - double a; - - a = editDouble(c->editADouble); - if (a < 0 || a > 1) - return; - c->a = a; - updateDialog(c, c->editADouble); -} - -static int editInt(HWND hwnd) -{ - WCHAR *s; - int i; - - s = windowText(hwnd); - i = _wtoi(s); - uiFree(s); - return i; -} - -static void rIntChanged(struct colorDialog *c) -{ - double r, g, b; - int i; - - hsv2RGB(c->h, c->s, c->v, &r, &g, &b); - i = editInt(c->editRInt); - if (i < 0 || i > 255) - return; - r = ((double) i) / 255.0; - rgb2HSV(r, g, b, &(c->h), &(c->s), &(c->v)); - updateDialog(c, c->editRInt); -} - -static void gIntChanged(struct colorDialog *c) -{ - double r, g, b; - int i; - - hsv2RGB(c->h, c->s, c->v, &r, &g, &b); - i = editInt(c->editGInt); - if (i < 0 || i > 255) - return; - g = ((double) i) / 255.0; - rgb2HSV(r, g, b, &(c->h), &(c->s), &(c->v)); - updateDialog(c, c->editGInt); -} - -static void bIntChanged(struct colorDialog *c) -{ - double r, g, b; - int i; - - hsv2RGB(c->h, c->s, c->v, &r, &g, &b); - i = editInt(c->editBInt); - if (i < 0 || i > 255) - return; - b = ((double) i) / 255.0; - rgb2HSV(r, g, b, &(c->h), &(c->s), &(c->v)); - updateDialog(c, c->editBInt); -} - -static void aIntChanged(struct colorDialog *c) -{ - int a; - - a = editInt(c->editAInt); - if (a < 0 || a > 255) - return; - c->a = ((double) a) / 255; - updateDialog(c, c->editAInt); -} - -static void hexChanged(struct colorDialog *c) -{ - WCHAR *buf; - double r, g, b, a; - BOOL is; - - buf = windowText(c->editHex); - is = hex2RGBA(buf, &r, &g, &b, &a); - uiFree(buf); - if (!is) - return; - rgb2HSV(r, g, b, &(c->h), &(c->s), &(c->v)); - c->a = a; - updateDialog(c, c->editHex); -} - -// TODO change fontdialog to use this -// note that if we make this const, we get lots of weird compiler errors -static std::map changed = { - { rcH, hChanged }, - { rcS, sChanged }, - { rcV, vChanged }, - { rcRDouble, rDoubleChanged }, - { rcGDouble, gDoubleChanged }, - { rcBDouble, bDoubleChanged }, - { rcADouble, aDoubleChanged }, - { rcRInt, rIntChanged }, - { rcGInt, gIntChanged }, - { rcBInt, bIntChanged }, - { rcAInt, aIntChanged }, - { rcHex, hexChanged }, -}; - -static INT_PTR CALLBACK colorDialogDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - struct colorDialog *c; - - c = (struct colorDialog *) GetWindowLongPtrW(hwnd, DWLP_USER); - if (c == NULL) { - if (uMsg == WM_INITDIALOG) { - c = beginColorDialog(hwnd, lParam); - SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR) c); - return TRUE; - } - return FALSE; - } - - switch (uMsg) { - case WM_COMMAND: - SetWindowLongPtrW(c->hwnd, DWLP_MSGRESULT, 0); // just in case - switch (LOWORD(wParam)) { - case IDOK: - case IDCANCEL: - if (HIWORD(wParam) != BN_CLICKED) - return FALSE; - tryFinishDialog(c, wParam); - return TRUE; - case rcH: - case rcS: - case rcV: - case rcRDouble: - case rcGDouble: - case rcBDouble: - case rcADouble: - case rcRInt: - case rcGInt: - case rcBInt: - case rcAInt: - case rcHex: - if (HIWORD(wParam) != EN_CHANGE) - return FALSE; - if (c->updating) // prevent infinite recursion during an update - return FALSE; - (*(changed[LOWORD(wParam)]))(c); - return TRUE; - } - return FALSE; - } - return FALSE; -} - -BOOL showColorDialog(HWND parent, struct colorDialogRGBA *c) -{ - switch (DialogBoxParamW(hInstance, MAKEINTRESOURCE(rcColorDialog), parent, colorDialogDlgProc, (LPARAM) c)) { - case 1: // cancel - return FALSE; - case 2: // ok - // make the compiler happy by putting the return after the switch - break; - default: - logLastError(L"error running color dialog"); - } - return TRUE; -} diff --git a/deps/libui/windows/combobox.cpp b/deps/libui/windows/combobox.cpp deleted file mode 100644 index 87c999ea3a..0000000000 --- a/deps/libui/windows/combobox.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// 20 may 2015 -#include "uipriv_windows.hpp" - -// we as Common Controls 6 users don't need to worry about the height of comboboxes; see http://blogs.msdn.com/b/oldnewthing/archive/2006/03/10/548537.aspx - -struct uiCombobox { - uiWindowsControl c; - HWND hwnd; - void (*onSelected)(uiCombobox *, void *); - void *onSelectedData; -}; - -static BOOL onWM_COMMAND(uiControl *cc, HWND hwnd, WORD code, LRESULT *lResult) -{ - uiCombobox *c = uiCombobox(cc); - - if (code != CBN_SELCHANGE) - return FALSE; - (*(c->onSelected))(c, c->onSelectedData); - *lResult = 0; - return TRUE; -} - -void uiComboboxDestroy(uiControl *cc) -{ - uiCombobox *c = uiCombobox(cc); - - uiWindowsUnregisterWM_COMMANDHandler(c->hwnd); - uiWindowsEnsureDestroyWindow(c->hwnd); - uiFreeControl(uiControl(c)); -} - -uiWindowsControlAllDefaultsExceptDestroy(uiCombobox) - -// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define comboboxWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary; LONGTERM */ -#define comboboxHeight 14 /* LONGTERM: is this too high? */ - -static void uiComboboxMinimumSize(uiWindowsControl *cc, int *width, int *height) -{ - uiCombobox *c = uiCombobox(cc); - uiWindowsSizing sizing; - int x, y; - - x = comboboxWidth; - y = comboboxHeight; - uiWindowsGetSizing(c->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); - *width = x; - *height = y; -} - -static void defaultOnSelected(uiCombobox *c, void *data) -{ - // do nothing -} - -void uiComboboxAppend(uiCombobox *c, const char *text) -{ - WCHAR *wtext; - LRESULT res; - - wtext = toUTF16(text); - res = SendMessageW(c->hwnd, CB_ADDSTRING, 0, (LPARAM) wtext); - if (res == (LRESULT) CB_ERR) - logLastError(L"error appending item to uiCombobox"); - else if (res == (LRESULT) CB_ERRSPACE) - logLastError(L"memory exhausted appending item to uiCombobox"); - uiFree(wtext); -} - -int uiComboboxSelected(uiCombobox *c) -{ - LRESULT n; - - n = SendMessage(c->hwnd, CB_GETCURSEL, 0, 0); - if (n == (LRESULT) CB_ERR) - return -1; - return n; -} - -void uiComboboxSetSelected(uiCombobox *c, int n) -{ - // TODO error check - SendMessageW(c->hwnd, CB_SETCURSEL, (WPARAM) n, 0); -} - -void uiComboboxOnSelected(uiCombobox *c, void (*f)(uiCombobox *c, void *data), void *data) -{ - c->onSelected = f; - c->onSelectedData = data; -} - -uiCombobox *uiNewCombobox(void) -{ - uiCombobox *c; - - uiWindowsNewControl(uiCombobox, c); - - c->hwnd = uiWindowsEnsureCreateControlHWND(WS_EX_CLIENTEDGE, - L"combobox", L"", - CBS_DROPDOWNLIST | WS_TABSTOP, - hInstance, NULL, - TRUE); - - uiWindowsRegisterWM_COMMANDHandler(c->hwnd, onWM_COMMAND, uiControl(c)); - uiComboboxOnSelected(c, defaultOnSelected, NULL); - - return c; -} diff --git a/deps/libui/windows/compilerver.hpp b/deps/libui/windows/compilerver.hpp deleted file mode 100644 index 6c9e6b815a..0000000000 --- a/deps/libui/windows/compilerver.hpp +++ /dev/null @@ -1,13 +0,0 @@ -// 9 june 2015 - -// Visual Studio (Microsoft's compilers) -// VS2013 is needed for va_copy(). -#ifdef _MSC_VER -#if _MSC_VER < 1800 -#error Visual Studio 2013 or higher is required to build libui. -#endif -#endif - -// LONGTERM MinGW - -// other compilers can be added here as necessary diff --git a/deps/libui/windows/container.cpp b/deps/libui/windows/container.cpp deleted file mode 100644 index 9ec1e2803c..0000000000 --- a/deps/libui/windows/container.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// 26 april 2015 -#include "uipriv_windows.hpp" - -// Code for the HWND of the following uiControls: -// - uiBox -// - uiRadioButtons -// - uiSpinbox -// - uiTab -// - uiForm -// - uiGrid - -struct containerInit { - uiWindowsControl *c; - void (*onResize)(uiWindowsControl *); -}; - -static LRESULT CALLBACK containerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - RECT r; - HDC dc; - PAINTSTRUCT ps; - CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam; - WINDOWPOS *wp = (WINDOWPOS *) lParam; - MINMAXINFO *mmi = (MINMAXINFO *) lParam; - struct containerInit *init; - uiWindowsControl *c; - void (*onResize)(uiWindowsControl *); - int minwid, minht; - LRESULT lResult; - - if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE) - return lResult; - switch (uMsg) { - case WM_CREATE: - init = (struct containerInit *) (cs->lpCreateParams); - SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) (init->onResize)); - SetWindowLongPtrW(hwnd, 0, (LONG_PTR) (init->c)); - break; // defer to DefWindowProc() - case WM_WINDOWPOSCHANGED: - if ((wp->flags & SWP_NOSIZE) != 0) - break; // defer to DefWindowProc(); - onResize = (void (*)(uiWindowsControl *)) GetWindowLongPtrW(hwnd, GWLP_USERDATA); - c = (uiWindowsControl *) GetWindowLongPtrW(hwnd, 0); - (*(onResize))(c); - return 0; - case WM_GETMINMAXINFO: - lResult = DefWindowProcW(hwnd, uMsg, wParam, lParam); - c = (uiWindowsControl *) GetWindowLongPtrW(hwnd, 0); - uiWindowsControlMinimumSize(c, &minwid, &minht); - mmi->ptMinTrackSize.x = minwid; - mmi->ptMinTrackSize.y = minht; - return lResult; - case WM_PAINT: - dc = BeginPaint(hwnd, &ps); - if (dc == NULL) { - logLastError(L"error beginning container paint"); - // bail out; hope DefWindowProc() catches us - break; - } - r = ps.rcPaint; - paintContainerBackground(hwnd, dc, &r); - EndPaint(hwnd, &ps); - return 0; - // tab controls use this to draw the background of the tab area - case WM_PRINTCLIENT: - uiWindowsEnsureGetClientRect(hwnd, &r); - paintContainerBackground(hwnd, (HDC) wParam, &r); - return 0; - case WM_ERASEBKGND: - // avoid some flicker - // we draw the whole update area anyway - return 1; - } - return DefWindowProcW(hwnd, uMsg, wParam, lParam); -} - -ATOM initContainer(HICON hDefaultIcon, HCURSOR hDefaultCursor) -{ - WNDCLASSW wc; - - ZeroMemory(&wc, sizeof (WNDCLASSW)); - wc.lpszClassName = containerClass; - wc.lpfnWndProc = containerWndProc; - wc.hInstance = hInstance; - wc.hIcon = hDefaultIcon; - wc.hCursor = hDefaultCursor; - wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); - wc.cbWndExtra = sizeof (void *); - return RegisterClassW(&wc); -} - -void uninitContainer(void) -{ - if (UnregisterClassW(containerClass, hInstance) == 0) - logLastError(L"error unregistering container window class"); -} - -HWND uiWindowsMakeContainer(uiWindowsControl *c, void (*onResize)(uiWindowsControl *)) -{ - struct containerInit init; - - // TODO onResize cannot be NULL - init.c = c; - init.onResize = onResize; - return uiWindowsEnsureCreateControlHWND(WS_EX_CONTROLPARENT, - containerClass, L"", - 0, - hInstance, (LPVOID) (&init), - FALSE); -} diff --git a/deps/libui/windows/control.cpp b/deps/libui/windows/control.cpp deleted file mode 100644 index ce953cf941..0000000000 --- a/deps/libui/windows/control.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// 16 august 2015 -#include "uipriv_windows.hpp" - -void uiWindowsControlSyncEnableState(uiWindowsControl *c, int enabled) -{ - (*(c->SyncEnableState))(c, enabled); -} - -void uiWindowsControlSetParentHWND(uiWindowsControl *c, HWND parent) -{ - (*(c->SetParentHWND))(c, parent); -} - -void uiWindowsControlMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - (*(c->MinimumSize))(c, width, height); -} - -void uiWindowsControlMinimumSizeChanged(uiWindowsControl *c) -{ - (*(c->MinimumSizeChanged))(c); -} - -// TODO get rid of this -void uiWindowsControlLayoutRect(uiWindowsControl *c, RECT *r) -{ - (*(c->LayoutRect))(c, r); -} - -void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *c, LONG_PTR *controlID, HWND *insertAfter) -{ - (*(c->AssignControlIDZOrder))(c, controlID, insertAfter); -} - -void uiWindowsControlChildVisibilityChanged(uiWindowsControl *c) -{ - (*(c->ChildVisibilityChanged))(c); -} - -HWND uiWindowsEnsureCreateControlHWND(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, HINSTANCE hInstance, LPVOID lpParam, BOOL useStandardControlFont) -{ - HWND hwnd; - - // don't let using the arrow keys in a uiRadioButtons leave the radio buttons - if ((dwStyle & WS_TABSTOP) != 0) - dwStyle |= WS_GROUP; - hwnd = CreateWindowExW(dwExStyle, - lpClassName, lpWindowName, - dwStyle | WS_CHILD | WS_VISIBLE, - 0, 0, - // use a nonzero initial size just in case some control breaks with a zero initial size - 100, 100, - utilWindow, NULL, hInstance, lpParam); - if (hwnd == NULL) { - logLastError(L"error creating window"); - // TODO return a decoy window - } - if (useStandardControlFont) - SendMessageW(hwnd, WM_SETFONT, (WPARAM) hMessageFont, (LPARAM) TRUE); - return hwnd; -} - -// choose a value distinct from uiWindowSignature -#define uiWindowsControlSignature 0x4D53576E - -uiWindowsControl *uiWindowsAllocControl(size_t n, uint32_t typesig, const char *typenamestr) -{ - return uiWindowsControl(uiAllocControl(n, uiWindowsControlSignature, typesig, typenamestr)); -} - -BOOL uiWindowsShouldStopSyncEnableState(uiWindowsControl *c, BOOL enabled) -{ - int ce; - - ce = uiControlEnabled(uiControl(c)); - // only stop if we're going from disabled back to enabled; don't stop under any other condition - // (if we stop when going from enabled to disabled then enabled children of a disabled control won't get disabled at the OS level) - if (!ce && enabled) - return TRUE; - return FALSE; -} - -void uiWindowsControlAssignSoleControlIDZOrder(uiWindowsControl *c) -{ - LONG_PTR controlID; - HWND insertAfter; - - controlID = 100; - insertAfter = NULL; - uiWindowsControlAssignControlIDZOrder(c, &controlID, &insertAfter); -} - -BOOL uiWindowsControlTooSmall(uiWindowsControl *c) -{ - RECT r; - int width, height; - - uiWindowsControlLayoutRect(c, &r); - uiWindowsControlMinimumSize(c, &width, &height); - if ((r.right - r.left) < width) - return TRUE; - if ((r.bottom - r.top) < height) - return TRUE; - return FALSE; -} - -void uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl *c) -{ - uiControl *parent; - - parent = uiControlParent(uiControl(c)); - if (parent != NULL) - uiWindowsControlMinimumSizeChanged(uiWindowsControl(parent)); -} - -// TODO rename this nad the OS X this and hugging ones to NotifyChild -void uiWindowsControlNotifyVisibilityChanged(uiWindowsControl *c) -{ - // TODO we really need to figure this out; the duplication is a mess - uiWindowsControlContinueMinimumSizeChanged(c); -} diff --git a/deps/libui/windows/d2dscratch.cpp b/deps/libui/windows/d2dscratch.cpp deleted file mode 100644 index 6dc2ba5fd3..0000000000 --- a/deps/libui/windows/d2dscratch.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// 17 april 2016 -#include "uipriv_windows.hpp" - -// The Direct2D scratch window is a utility for libui internal use to do quick things with Direct2D. -// To use, call newD2DScratch() passing in a subclass procedure. This subclass procedure should handle the msgD2DScratchPaint message, which has the following usage: -// - wParam - 0 -// - lParam - ID2D1RenderTarget * -// - lResult - 0 -// You can optionally also handle msgD2DScratchLButtonDown, which is sent when the left mouse button is either pressed for the first time or held while the mouse is moving. -// - wParam - position in DIPs, as D2D1_POINT_2F * -// - lParam - size of render target in DIPs, as D2D1_SIZE_F * -// - lResult - 0 -// Other messages can also be handled here. - -// TODO allow resize - -#define d2dScratchClass L"libui_d2dScratchClass" - -// TODO clip rect -static HRESULT d2dScratchDoPaint(HWND hwnd, ID2D1RenderTarget *rt) -{ - COLORREF bgcolorref; - D2D1_COLOR_F bgcolor; - - rt->BeginDraw(); - - // TODO only clear the clip area - // TODO clear with actual background brush - bgcolorref = GetSysColor(COLOR_BTNFACE); - bgcolor.r = ((float) GetRValue(bgcolorref)) / 255.0; - // due to utter apathy on Microsoft's part, GetGValue() does not work with MSVC's Run-Time Error Checks - // it has not worked since 2008 and they have *never* fixed it - // TODO now that -RTCc has just been deprecated entirely, should we switch back? - bgcolor.g = ((float) ((BYTE) ((bgcolorref & 0xFF00) >> 8))) / 255.0; - bgcolor.b = ((float) GetBValue(bgcolorref)) / 255.0; - bgcolor.a = 1.0; - rt->Clear(&bgcolor); - - SendMessageW(hwnd, msgD2DScratchPaint, 0, (LPARAM) rt); - - return rt->EndDraw(NULL, NULL); -} - -static void d2dScratchDoLButtonDown(HWND hwnd, ID2D1RenderTarget *rt, LPARAM lParam) -{ - double xpix, ypix; - FLOAT dpix, dpiy; - D2D1_POINT_2F pos; - D2D1_SIZE_F size; - - xpix = (double) GET_X_LPARAM(lParam); - ypix = (double) GET_Y_LPARAM(lParam); - // these are in pixels; we need points - // TODO separate the function from areautil.cpp? - rt->GetDpi(&dpix, &dpiy); - pos.x = (xpix * 96) / dpix; - pos.y = (ypix * 96) / dpiy; - - size = realGetSize(rt); - - SendMessageW(hwnd, msgD2DScratchLButtonDown, (WPARAM) (&pos), (LPARAM) (&size)); -} - -static LRESULT CALLBACK d2dScratchWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - LONG_PTR init; - ID2D1HwndRenderTarget *rt; - ID2D1DCRenderTarget *dcrt; - RECT client; - HRESULT hr; - - init = GetWindowLongPtrW(hwnd, 0); - if (!init) { - if (uMsg == WM_CREATE) - SetWindowLongPtrW(hwnd, 0, (LONG_PTR) TRUE); - return DefWindowProcW(hwnd, uMsg, wParam, lParam); - } - - rt = (ID2D1HwndRenderTarget *) GetWindowLongPtrW(hwnd, GWLP_USERDATA); - if (rt == NULL) { - rt = makeHWNDRenderTarget(hwnd); - SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) rt); - } - - switch (uMsg) { - case WM_DESTROY: - rt->Release(); - SetWindowLongPtrW(hwnd, 0, (LONG_PTR) FALSE); - break; - case WM_PAINT: - hr = d2dScratchDoPaint(hwnd, rt); - switch (hr) { - case S_OK: - if (ValidateRect(hwnd, NULL) == 0) - logLastError(L"error validating D2D scratch control rect"); - break; - case D2DERR_RECREATE_TARGET: - // DON'T validate the rect - // instead, simply drop the render target - // we'll get another WM_PAINT and make the render target again - // TODO would this require us to invalidate the entire client area? - rt->Release(); - SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) NULL); - break; - default: - logHRESULT(L"error drawing D2D scratch window", hr); - } - return 0; - case WM_PRINTCLIENT: - uiWindowsEnsureGetClientRect(hwnd, &client); - dcrt = makeHDCRenderTarget((HDC) wParam, &client); - hr = d2dScratchDoPaint(hwnd, dcrt); - if (hr != S_OK) - logHRESULT(L"error printing D2D scratch window client area", hr); - dcrt->Release(); - return 0; - case WM_LBUTTONDOWN: - d2dScratchDoLButtonDown(hwnd, rt, lParam); - return 0; - case WM_MOUSEMOVE: - // also send LButtonDowns when dragging - if ((wParam & MK_LBUTTON) != 0) - d2dScratchDoLButtonDown(hwnd, rt, lParam); - return 0; - } - return DefWindowProcW(hwnd, uMsg, wParam, lParam); -} - -ATOM registerD2DScratchClass(HICON hDefaultIcon, HCURSOR hDefaultCursor) -{ - WNDCLASSW wc; - - ZeroMemory(&wc, sizeof (WNDCLASSW)); - wc.lpszClassName = d2dScratchClass; - wc.lpfnWndProc = d2dScratchWndProc; - wc.hInstance = hInstance; - wc.hIcon = hDefaultIcon; - wc.hCursor = hDefaultCursor; - wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); - wc.cbWndExtra = sizeof (LONG_PTR); // for the init status - return RegisterClassW(&wc); -} - -void unregisterD2DScratchClass(void) -{ - if (UnregisterClassW(d2dScratchClass, hInstance) == 0) - logLastError(L"error unregistering D2D scratch window class"); -} - -HWND newD2DScratch(HWND parent, RECT *rect, HMENU controlID, SUBCLASSPROC subclass, DWORD_PTR subclassData) -{ - HWND hwnd; - - hwnd = CreateWindowExW(0, - d2dScratchClass, L"", - WS_CHILD | WS_VISIBLE, - rect->left, rect->top, - rect->right - rect->left, rect->bottom - rect->top, - parent, controlID, hInstance, NULL); - if (hwnd == NULL) - // TODO return decoy window - logLastError(L"error creating D2D scratch window"); - if (SetWindowSubclass(hwnd, subclass, 0, subclassData) == FALSE) - logLastError(L"error subclassing D2D scratch window"); - return hwnd; -} diff --git a/deps/libui/windows/datetimepicker.cpp b/deps/libui/windows/datetimepicker.cpp deleted file mode 100644 index e105c2fdb7..0000000000 --- a/deps/libui/windows/datetimepicker.cpp +++ /dev/null @@ -1,191 +0,0 @@ -// 22 may 2015 -#include "uipriv_windows.hpp" - -struct uiDateTimePicker { - uiWindowsControl c; - HWND hwnd; -}; - -// utility functions - -#define GLI(what, buf, n) GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, what, buf, n) - -// The real date/time picker does a manual replacement of "yy" with "yyyy" for DTS_SHORTDATECENTURYFORMAT. -// Because we're also duplicating its functionality (see below), we have to do it too. -static WCHAR *expandYear(WCHAR *dts, int n) -{ - WCHAR *out; - WCHAR *p, *q; - int ny = 0; - - // allocate more than we need to be safe - out = (WCHAR *) uiAlloc((n * 3) * sizeof (WCHAR), "WCHAR[]"); - q = out; - for (p = dts; *p != L'\0'; p++) { - // first, if the current character is a y, increment the number of consecutive ys - // otherwise, stop counting, and if there were only two, add two more to make four - if (*p != L'y') { - if (ny == 2) { - *q++ = L'y'; - *q++ = L'y'; - } - ny = 0; - } else - ny++; - // next, handle quoted blocks - // we do this AFTER the above so yy'abc' becomes yyyy'abc' and not yy'abc'yy - // this handles the case of 'a''b' elegantly as well - if (*p == L'\'') { - // copy the opening quote - *q++ = *p; - // copy the contents - for (;;) { - p++; - if (*p == L'\'') - break; - if (*p == L'\0') - implbug("unterminated quote in system-provided locale date string in expandYear()"); - *q++ = *p; - } - // and fall through to copy the closing quote - } - // copy the current character - *q++ = *p; - } - // handle trailing yy - if (ny == 2) { - *q++ = L'y'; - *q++ = L'y'; - } - *q++ = L'\0'; - return out; -} - -// Windows has no combined date/time prebuilt constant; we have to build the format string ourselves -// TODO use a default format if one fails -static void setDateTimeFormat(HWND hwnd) -{ - WCHAR *unexpandedDate, *date; - WCHAR *time; - WCHAR *datetime; - int ndate, ntime; - - ndate = GLI(LOCALE_SSHORTDATE, NULL, 0); - if (ndate == 0) - logLastError(L"error getting date string length"); - date = (WCHAR *) uiAlloc(ndate * sizeof (WCHAR), "WCHAR[]"); - if (GLI(LOCALE_SSHORTDATE, date, ndate) == 0) - logLastError(L"error geting date string"); - unexpandedDate = date; // so we can free it - date = expandYear(unexpandedDate, ndate); - uiFree(unexpandedDate); - - ntime = GLI(LOCALE_STIMEFORMAT, NULL, 0); - if (ndate == 0) - logLastError(L"error getting time string length"); - time = (WCHAR *) uiAlloc(ntime * sizeof (WCHAR), "WCHAR[]"); - if (GLI(LOCALE_STIMEFORMAT, time, ntime) == 0) - logLastError(L"error geting time string"); - - datetime = strf(L"%s %s", date, time); - if (SendMessageW(hwnd, DTM_SETFORMAT, 0, (LPARAM) datetime) == 0) - logLastError(L"error applying format string to date/time picker"); - - uiFree(datetime); - uiFree(time); - uiFree(date); -} - -// control implementation - -static void uiDateTimePickerDestroy(uiControl *c) -{ - uiDateTimePicker *d = uiDateTimePicker(c); - - uiWindowsUnregisterReceiveWM_WININICHANGE(d->hwnd); - uiWindowsEnsureDestroyWindow(d->hwnd); - uiFreeControl(uiControl(d)); -} - -uiWindowsControlAllDefaultsExceptDestroy(uiDateTimePicker) - -// the height returned from DTM_GETIDEALSIZE is unreliable; see http://stackoverflow.com/questions/30626549/what-is-the-proper-use-of-dtm-getidealsize-treating-the-returned-size-as-pixels -// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define entryHeight 14 - -static void uiDateTimePickerMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiDateTimePicker *d = uiDateTimePicker(c); - SIZE s; - uiWindowsSizing sizing; - int y; - - s.cx = 0; - s.cy = 0; - SendMessageW(d->hwnd, DTM_GETIDEALSIZE, 0, (LPARAM) (&s)); - *width = s.cx; - - y = entryHeight; - uiWindowsGetSizing(d->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &y); - *height = y; -} - -static uiDateTimePicker *finishNewDateTimePicker(DWORD style) -{ - uiDateTimePicker *d; - - uiWindowsNewControl(uiDateTimePicker, d); - - d->hwnd = uiWindowsEnsureCreateControlHWND(WS_EX_CLIENTEDGE, - DATETIMEPICK_CLASSW, L"", - style | WS_TABSTOP, - hInstance, NULL, - TRUE); - - // automatically update date/time format when user changes locale settings - // for the standard styles, this is in the date-time picker itself - // for our date/time mode, we do it in a subclass assigned in uiNewDateTimePicker() - uiWindowsRegisterReceiveWM_WININICHANGE(d->hwnd); - - return d; -} - -static LRESULT CALLBACK datetimepickerSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) -{ - switch (uMsg) { - case WM_WININICHANGE: - // we can optimize this by only doing it when the real date/time picker does it - // unfortunately, I don't know when that is :/ - // hopefully this won't hurt - setDateTimeFormat(hwnd); - return 0; - case WM_NCDESTROY: - if (RemoveWindowSubclass(hwnd, datetimepickerSubProc, uIdSubclass) == FALSE) - logLastError(L"error removing date-time picker locale change handling subclass"); - break; - } - return DefSubclassProc(hwnd, uMsg, wParam, lParam); -} - -uiDateTimePicker *uiNewDateTimePicker(void) -{ - uiDateTimePicker *d; - - d = finishNewDateTimePicker(0); - setDateTimeFormat(d->hwnd); - if (SetWindowSubclass(d->hwnd, datetimepickerSubProc, 0, (DWORD_PTR) d) == FALSE) - logLastError(L"error subclassing date-time-picker to assist in locale change handling"); - // TODO set a suitable default in this case - return d; -} - -uiDateTimePicker *uiNewDatePicker(void) -{ - return finishNewDateTimePicker(DTS_SHORTDATECENTURYFORMAT); -} - -uiDateTimePicker *uiNewTimePicker(void) -{ - return finishNewDateTimePicker(DTS_TIMEFORMAT); -} diff --git a/deps/libui/windows/debug.cpp b/deps/libui/windows/debug.cpp deleted file mode 100644 index cfafffdc86..0000000000 --- a/deps/libui/windows/debug.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// 25 february 2015 -#include "uipriv_windows.hpp" - -// LONGTERM disable logging and stopping on no-debug builds - -static void printDebug(const WCHAR *msg) -{ - OutputDebugStringW(msg); -} - -HRESULT _logLastError(debugargs, const WCHAR *s) -{ - DWORD le; - WCHAR *msg; - WCHAR *formatted; - BOOL useFormatted; - - le = GetLastError(); - - useFormatted = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, le, 0, (LPWSTR) (&formatted), 0, NULL) != 0; - if (!useFormatted) - formatted = L"\n"; - msg = strf(L"[libui] %s:%s:%s() %s: GetLastError() == %I32u %s", - file, line, func, - s, le, formatted); - if (useFormatted) - LocalFree(formatted); // ignore error - printDebug(msg); - uiFree(msg); - DebugBreak(); - - SetLastError(le); - // a function does not have to set a last error - // if the last error we get is actually 0, then HRESULT_FROM_WIN32(0) will return S_OK (0 cast to an HRESULT, since 0 <= 0), which we don't want - // prevent this by returning E_FAIL - if (le == 0) - return E_FAIL; - return HRESULT_FROM_WIN32(le); -} - -HRESULT _logHRESULT(debugargs, const WCHAR *s, HRESULT hr) -{ - WCHAR *msg; - WCHAR *formatted; - BOOL useFormatted; - - useFormatted = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, 0, (LPWSTR) (&formatted), 0, NULL) != 0; - if (!useFormatted) - formatted = L"\n"; - msg = strf(L"[libui] %s:%s:%s() %s: HRESULT == 0x%08I32X %s", - file, line, func, - s, hr, formatted); - if (useFormatted) - LocalFree(formatted); // ignore error - printDebug(msg); - uiFree(msg); - DebugBreak(); - - return hr; -} - -void realbug(const char *file, const char *line, const char *func, const char *prefix, const char *format, va_list ap) -{ - va_list ap2; - char *msg; - size_t n; - WCHAR *final; - - va_copy(ap2, ap); - n = _vscprintf(format, ap2); - va_end(ap2); - n++; // terminating '\0' - - msg = (char *) uiAlloc(n * sizeof (char), "char[]"); - // includes terminating '\0' according to example in https://msdn.microsoft.com/en-us/library/xa1a1a6z.aspx - vsprintf_s(msg, n, format, ap); - - final = strf(L"[libui] %hs:%hs:%hs() %hs%hs\n", file, line, func, prefix, msg); - uiFree(msg); - printDebug(final); - uiFree(final); - - DebugBreak(); -} diff --git a/deps/libui/windows/draw.cpp b/deps/libui/windows/draw.cpp deleted file mode 100644 index 5f4d29f1a0..0000000000 --- a/deps/libui/windows/draw.cpp +++ /dev/null @@ -1,511 +0,0 @@ -// 7 september 2015 -#include "uipriv_windows.hpp" -#include "draw.hpp" - -ID2D1Factory *d2dfactory = NULL; - -HRESULT initDraw(void) -{ - D2D1_FACTORY_OPTIONS opts; - - ZeroMemory(&opts, sizeof (D2D1_FACTORY_OPTIONS)); - // TODO make this an option - opts.debugLevel = D2D1_DEBUG_LEVEL_NONE; - return D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, - IID_ID2D1Factory, - &opts, - (void **) (&d2dfactory)); -} - -void uninitDraw(void) -{ - d2dfactory->Release(); -} - -ID2D1HwndRenderTarget *makeHWNDRenderTarget(HWND hwnd) -{ - D2D1_RENDER_TARGET_PROPERTIES props; - D2D1_HWND_RENDER_TARGET_PROPERTIES hprops; - HDC dc; - RECT r; - ID2D1HwndRenderTarget *rt; - HRESULT hr; - - // we need a DC for the DPI - // we *could* just use the screen DPI but why when we have a window handle and its DC has a DPI - dc = GetDC(hwnd); - if (dc == NULL) - logLastError(L"error getting DC to find DPI"); - - ZeroMemory(&props, sizeof (D2D1_RENDER_TARGET_PROPERTIES)); - props.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; - props.pixelFormat.format = DXGI_FORMAT_UNKNOWN; - props.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN; - props.dpiX = GetDeviceCaps(dc, LOGPIXELSX); - props.dpiY = GetDeviceCaps(dc, LOGPIXELSY); - props.usage = D2D1_RENDER_TARGET_USAGE_NONE; - props.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; - - if (ReleaseDC(hwnd, dc) == 0) - logLastError(L"error releasing DC for finding DPI"); - - uiWindowsEnsureGetClientRect(hwnd, &r); - - ZeroMemory(&hprops, sizeof (D2D1_HWND_RENDER_TARGET_PROPERTIES)); - hprops.hwnd = hwnd; - hprops.pixelSize.width = r.right - r.left; - hprops.pixelSize.height = r.bottom - r.top; - // according to Rick Brewster, some drivers will misbehave if we don't specify this (see http://stackoverflow.com/a/33222983/3408572) - hprops.presentOptions = D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS; - - hr = d2dfactory->CreateHwndRenderTarget( - &props, - &hprops, - &rt); - if (hr != S_OK) - logHRESULT(L"error creating HWND render target", hr); - return rt; -} - -ID2D1DCRenderTarget *makeHDCRenderTarget(HDC dc, RECT *r) -{ - D2D1_RENDER_TARGET_PROPERTIES props; - ID2D1DCRenderTarget *rt; - HRESULT hr; - - ZeroMemory(&props, sizeof (D2D1_RENDER_TARGET_PROPERTIES)); - props.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; - props.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; - props.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - props.dpiX = GetDeviceCaps(dc, LOGPIXELSX); - props.dpiY = GetDeviceCaps(dc, LOGPIXELSY); - props.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; - props.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; - - hr = d2dfactory->CreateDCRenderTarget(&props, &rt); - if (hr != S_OK) - logHRESULT(L"error creating DC render target", hr); - hr = rt->BindDC(dc, r); - if (hr != S_OK) - logHRESULT(L"error binding DC to DC render target", hr); - return rt; -} - -static void resetTarget(ID2D1RenderTarget *rt) -{ - D2D1_MATRIX_3X2_F dm; - - // transformations persist - // reset to the identity matrix - ZeroMemory(&dm, sizeof (D2D1_MATRIX_3X2_F)); - dm._11 = 1; - dm._22 = 1; - rt->SetTransform(&dm); -} - -uiDrawContext *newContext(ID2D1RenderTarget *rt) -{ - uiDrawContext *c; - - c = uiNew(uiDrawContext); - c->rt = rt; - c->states = new std::vector; - resetTarget(c->rt); - return c; -} - -void freeContext(uiDrawContext *c) -{ - if (c->currentClip != NULL) - c->currentClip->Release(); - if (c->states->size() != 0) - // TODO do this on other platforms - userbug("You did not balance uiDrawSave() and uiDrawRestore() calls."); - delete c->states; - uiFree(c); -} - -static ID2D1Brush *makeSolidBrush(uiDrawBrush *b, ID2D1RenderTarget *rt, D2D1_BRUSH_PROPERTIES *props) -{ - D2D1_COLOR_F color; - ID2D1SolidColorBrush *brush; - HRESULT hr; - - color.r = b->R; - color.g = b->G; - color.b = b->B; - color.a = b->A; - - hr = rt->CreateSolidColorBrush( - &color, - props, - &brush); - if (hr != S_OK) - logHRESULT(L"error creating solid brush", hr); - return brush; -} - -static ID2D1GradientStopCollection *mkstops(uiDrawBrush *b, ID2D1RenderTarget *rt) -{ - ID2D1GradientStopCollection *s; - D2D1_GRADIENT_STOP *stops; - size_t i; - HRESULT hr; - - stops = (D2D1_GRADIENT_STOP *) uiAlloc(b->NumStops * sizeof (D2D1_GRADIENT_STOP), "D2D1_GRADIENT_STOP[]"); - for (i = 0; i < b->NumStops; i++) { - stops[i].position = b->Stops[i].Pos; - stops[i].color.r = b->Stops[i].R; - stops[i].color.g = b->Stops[i].G; - stops[i].color.b = b->Stops[i].B; - stops[i].color.a = b->Stops[i].A; - } - - hr = rt->CreateGradientStopCollection( - stops, - b->NumStops, - D2D1_GAMMA_2_2, // this is the default for the C++-only overload of ID2D1RenderTarget::GradientStopCollection() - D2D1_EXTEND_MODE_CLAMP, - &s); - if (hr != S_OK) - logHRESULT(L"error creating stop collection", hr); - - uiFree(stops); - return s; -} - -static ID2D1Brush *makeLinearBrush(uiDrawBrush *b, ID2D1RenderTarget *rt, D2D1_BRUSH_PROPERTIES *props) -{ - ID2D1LinearGradientBrush *brush; - D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES gprops; - ID2D1GradientStopCollection *stops; - HRESULT hr; - - ZeroMemory(&gprops, sizeof (D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES)); - gprops.startPoint.x = b->X0; - gprops.startPoint.y = b->Y0; - gprops.endPoint.x = b->X1; - gprops.endPoint.y = b->Y1; - - stops = mkstops(b, rt); - - hr = rt->CreateLinearGradientBrush( - &gprops, - props, - stops, - &brush); - if (hr != S_OK) - logHRESULT(L"error creating gradient brush", hr); - - // the example at https://msdn.microsoft.com/en-us/library/windows/desktop/dd756682%28v=vs.85%29.aspx says this is safe to do now - stops->Release(); - return brush; -} - -static ID2D1Brush *makeRadialBrush(uiDrawBrush *b, ID2D1RenderTarget *rt, D2D1_BRUSH_PROPERTIES *props) -{ - ID2D1RadialGradientBrush *brush; - D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES gprops; - ID2D1GradientStopCollection *stops; - HRESULT hr; - - ZeroMemory(&gprops, sizeof (D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES)); - gprops.gradientOriginOffset.x = b->X0 - b->X1; - gprops.gradientOriginOffset.y = b->Y0 - b->Y1; - gprops.center.x = b->X1; - gprops.center.y = b->Y1; - gprops.radiusX = b->OuterRadius; - gprops.radiusY = b->OuterRadius; - - stops = mkstops(b, rt); - - hr = rt->CreateRadialGradientBrush( - &gprops, - props, - stops, - &brush); - if (hr != S_OK) - logHRESULT(L"error creating gradient brush", hr); - - stops->Release(); - return brush; -} - -static ID2D1Brush *makeBrush(uiDrawBrush *b, ID2D1RenderTarget *rt) -{ - D2D1_BRUSH_PROPERTIES props; - - ZeroMemory(&props, sizeof (D2D1_BRUSH_PROPERTIES)); - props.opacity = 1.0; - // identity matrix - props.transform._11 = 1; - props.transform._22 = 1; - - switch (b->Type) { - case uiDrawBrushTypeSolid: - return makeSolidBrush(b, rt, &props); - case uiDrawBrushTypeLinearGradient: - return makeLinearBrush(b, rt, &props); - case uiDrawBrushTypeRadialGradient: - return makeRadialBrush(b, rt, &props); -// case uiDrawBrushTypeImage: -// TODO - } - - // TODO do this on all platforms - userbug("Invalid brush type %d given to drawing operation.", b->Type); - // TODO dummy brush? - return NULL; // make compiler happy -} - -// how clipping works: -// every fill and stroke is done on a temporary layer with the clip geometry applied to it -// this is really the only way to clip in Direct2D that doesn't involve opacity images -// reference counting: -// - initially the clip is NULL, which means do not use a layer -// - the first time uiDrawClip() is called, we take a reference on the path passed in (this is also why uiPathEnd() is needed) -// - every successive time, we create a new PathGeometry and merge the current clip with the new path, releasing the reference we took earlier and taking a reference to the new one -// - in Save, we take another reference; in Restore we drop the refernece to the existing path geometry and transfer that saved ref to the new path geometry over to the context -// uiDrawFreePath() doesn't destroy the path geometry, it just drops the reference count, so a clip can exist independent of its path - -static ID2D1Layer *applyClip(uiDrawContext *c) -{ - ID2D1Layer *layer; - D2D1_LAYER_PARAMETERS params; - HRESULT hr; - - // if no clip, don't do anything - if (c->currentClip == NULL) - return NULL; - - // create a layer for clipping - // we have to explicitly make the layer because we're still targeting Windows 7 - hr = c->rt->CreateLayer(NULL, &layer); - if (hr != S_OK) - logHRESULT(L"error creating clip layer", hr); - - // apply it as the clip - ZeroMemory(¶ms, sizeof (D2D1_LAYER_PARAMETERS)); - // this is the equivalent of InfiniteRect() in d2d1helper.h - params.contentBounds.left = -FLT_MAX; - params.contentBounds.top = -FLT_MAX; - params.contentBounds.right = FLT_MAX; - params.contentBounds.bottom = FLT_MAX; - params.geometricMask = (ID2D1Geometry *) (c->currentClip); - // TODO is this correct? - params.maskAntialiasMode = c->rt->GetAntialiasMode(); - // identity matrix - params.maskTransform._11 = 1; - params.maskTransform._22 = 1; - params.opacity = 1.0; - params.opacityBrush = NULL; - params.layerOptions = D2D1_LAYER_OPTIONS_NONE; - // TODO is this correct? - if (c->rt->GetTextAntialiasMode() == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE) - params.layerOptions = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE; - c->rt->PushLayer(¶ms, layer); - - // return the layer so it can be freed later - return layer; -} - -static void unapplyClip(uiDrawContext *c, ID2D1Layer *layer) -{ - if (layer == NULL) - return; - c->rt->PopLayer(); - layer->Release(); -} - -void uiDrawStroke(uiDrawContext *c, uiDrawPath *p, uiDrawBrush *b, uiDrawStrokeParams *sp) -{ - ID2D1Brush *brush; - ID2D1StrokeStyle *style; - D2D1_STROKE_STYLE_PROPERTIES dsp; - FLOAT *dashes; - size_t i; - ID2D1Layer *cliplayer; - HRESULT hr; - - brush = makeBrush(b, c->rt); - - ZeroMemory(&dsp, sizeof (D2D1_STROKE_STYLE_PROPERTIES)); - switch (sp->Cap) { - case uiDrawLineCapFlat: - dsp.startCap = D2D1_CAP_STYLE_FLAT; - dsp.endCap = D2D1_CAP_STYLE_FLAT; - dsp.dashCap = D2D1_CAP_STYLE_FLAT; - break; - case uiDrawLineCapRound: - dsp.startCap = D2D1_CAP_STYLE_ROUND; - dsp.endCap = D2D1_CAP_STYLE_ROUND; - dsp.dashCap = D2D1_CAP_STYLE_ROUND; - break; - case uiDrawLineCapSquare: - dsp.startCap = D2D1_CAP_STYLE_SQUARE; - dsp.endCap = D2D1_CAP_STYLE_SQUARE; - dsp.dashCap = D2D1_CAP_STYLE_SQUARE; - break; - } - switch (sp->Join) { - case uiDrawLineJoinMiter: - dsp.lineJoin = D2D1_LINE_JOIN_MITER_OR_BEVEL; - dsp.miterLimit = sp->MiterLimit; - break; - case uiDrawLineJoinRound: - dsp.lineJoin = D2D1_LINE_JOIN_ROUND; - break; - case uiDrawLineJoinBevel: - dsp.lineJoin = D2D1_LINE_JOIN_BEVEL; - break; - } - dsp.dashStyle = D2D1_DASH_STYLE_SOLID; - dashes = NULL; - // note that dash widths and the dash phase are scaled up by the thickness by Direct2D - // TODO be sure to formally document this - if (sp->NumDashes != 0) { - dsp.dashStyle = D2D1_DASH_STYLE_CUSTOM; - dashes = (FLOAT *) uiAlloc(sp->NumDashes * sizeof (FLOAT), "FLOAT[]"); - for (i = 0; i < sp->NumDashes; i++) - dashes[i] = sp->Dashes[i] / sp->Thickness; - } - dsp.dashOffset = sp->DashPhase / sp->Thickness; - hr = d2dfactory->CreateStrokeStyle( - &dsp, - dashes, - sp->NumDashes, - &style); - if (hr != S_OK) - logHRESULT(L"error creating stroke style", hr); - if (sp->NumDashes != 0) - uiFree(dashes); - - cliplayer = applyClip(c); - c->rt->DrawGeometry( - pathGeometry(p), - brush, - sp->Thickness, - style); - unapplyClip(c, cliplayer); - - style->Release(); - brush->Release(); -} - -void uiDrawFill(uiDrawContext *c, uiDrawPath *p, uiDrawBrush *b) -{ - ID2D1Brush *brush; - ID2D1Layer *cliplayer; - - brush = makeBrush(b, c->rt); - cliplayer = applyClip(c); - c->rt->FillGeometry( - pathGeometry(p), - brush, - NULL); - unapplyClip(c, cliplayer); - brush->Release(); -} - -void uiDrawTransform(uiDrawContext *c, uiDrawMatrix *m) -{ - D2D1_MATRIX_3X2_F dm, cur; - - c->rt->GetTransform(&cur); - m2d(m, &dm); - // you would think we have to do already * m, right? - // WRONG! we have to do m * already - // why? a few reasons - // a) this lovely comment in cairo's source - http://cgit.freedesktop.org/cairo/tree/src/cairo-matrix.c?id=0537479bd1d4c5a3bc0f6f41dec4deb98481f34a#n330 - // Direct2D uses column vectors and I don't know if this is even documented - // b) that's what Core Graphics does - // TODO see if Microsoft says to do this - dm = dm * cur; // for whatever reason operator * is defined but not operator *= - c->rt->SetTransform(&dm); -} - -void uiDrawClip(uiDrawContext *c, uiDrawPath *path) -{ - ID2D1PathGeometry *newPath; - ID2D1GeometrySink *newSink; - HRESULT hr; - - // if there's no current clip, borrow the path - if (c->currentClip == NULL) { - c->currentClip = pathGeometry(path); - // we have to take our own reference to that clip - c->currentClip->AddRef(); - return; - } - - // otherwise we have to intersect the current path with the new one - // we do that into a new path, and then replace c->currentClip with that new path - hr = d2dfactory->CreatePathGeometry(&newPath); - if (hr != S_OK) - logHRESULT(L"error creating new path", hr); - hr = newPath->Open(&newSink); - if (hr != S_OK) - logHRESULT(L"error opening new path", hr); - hr = c->currentClip->CombineWithGeometry( - pathGeometry(path), - D2D1_COMBINE_MODE_INTERSECT, - NULL, - // TODO is this correct or can this be set per target? - D2D1_DEFAULT_FLATTENING_TOLERANCE, - newSink); - if (hr != S_OK) - logHRESULT(L"error intersecting old path with new path", hr); - hr = newSink->Close(); - if (hr != S_OK) - logHRESULT(L"error closing new path", hr); - newSink->Release(); - - // okay we have the new clip; we just need to replace the old one with it - c->currentClip->Release(); - c->currentClip = newPath; - // we have a reference already; no need for another -} - -struct drawState { - ID2D1DrawingStateBlock *dsb; - ID2D1PathGeometry *clip; -}; - -void uiDrawSave(uiDrawContext *c) -{ - struct drawState state; - HRESULT hr; - - hr = d2dfactory->CreateDrawingStateBlock( - // TODO verify that these are correct - NULL, - NULL, - &(state.dsb)); - if (hr != S_OK) - logHRESULT(L"error creating drawing state block", hr); - c->rt->SaveDrawingState(state.dsb); - - // if we have a clip, we need to hold another reference to it - if (c->currentClip != NULL) - c->currentClip->AddRef(); - state.clip = c->currentClip; // even if NULL assign it - - c->states->push_back(state); -} - -void uiDrawRestore(uiDrawContext *c) -{ - struct drawState state; - - state = (*(c->states))[c->states->size() - 1]; - c->states->pop_back(); - - c->rt->RestoreDrawingState(state.dsb); - state.dsb->Release(); - - // if we have a current clip, we need to drop it - if (c->currentClip != NULL) - c->currentClip->Release(); - // no need to explicitly addref or release; just transfer the ref - c->currentClip = state.clip; -} diff --git a/deps/libui/windows/draw.hpp b/deps/libui/windows/draw.hpp deleted file mode 100644 index b015791fe9..0000000000 --- a/deps/libui/windows/draw.hpp +++ /dev/null @@ -1,16 +0,0 @@ -// 5 may 2016 - -// draw.cpp -extern ID2D1Factory *d2dfactory; -struct uiDrawContext { - ID2D1RenderTarget *rt; - // TODO find out how this works - std::vector *states; - ID2D1PathGeometry *currentClip; -}; - -// drawpath.cpp -extern ID2D1PathGeometry *pathGeometry(uiDrawPath *p); - -// drawmatrix.cpp -extern void m2d(uiDrawMatrix *m, D2D1_MATRIX_3X2_F *d); diff --git a/deps/libui/windows/drawmatrix.cpp b/deps/libui/windows/drawmatrix.cpp deleted file mode 100644 index 090972a558..0000000000 --- a/deps/libui/windows/drawmatrix.cpp +++ /dev/null @@ -1,117 +0,0 @@ -// 7 september 2015 -#include "uipriv_windows.hpp" -#include "draw.hpp" - -void m2d(uiDrawMatrix *m, D2D1_MATRIX_3X2_F *d) -{ - d->_11 = m->M11; - d->_12 = m->M12; - d->_21 = m->M21; - d->_22 = m->M22; - d->_31 = m->M31; - d->_32 = m->M32; -} - -static void d2m(D2D1_MATRIX_3X2_F *d, uiDrawMatrix *m) -{ - m->M11 = d->_11; - m->M12 = d->_12; - m->M21 = d->_21; - m->M22 = d->_22; - m->M31 = d->_31; - m->M32 = d->_32; -} - -void uiDrawMatrixTranslate(uiDrawMatrix *m, double x, double y) -{ - D2D1_MATRIX_3X2_F dm; - - m2d(m, &dm); - dm = dm * D2D1::Matrix3x2F::Translation(x, y); - d2m(&dm, m); -} - -void uiDrawMatrixScale(uiDrawMatrix *m, double xCenter, double yCenter, double x, double y) -{ - D2D1_MATRIX_3X2_F dm; - D2D1_POINT_2F center; - - m2d(m, &dm); - center.x = xCenter; - center.y = yCenter; - dm = dm * D2D1::Matrix3x2F::Scale(x, y, center); - d2m(&dm, m); -} - -#define r2d(x) (x * (180.0 / uiPi)) - -void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount) -{ - D2D1_MATRIX_3X2_F dm; - D2D1_POINT_2F center; - - m2d(m, &dm); - center.x = x; - center.y = y; - dm = dm * D2D1::Matrix3x2F::Rotation(r2d(amount), center); - d2m(&dm, m); -} - -void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount) -{ - D2D1_MATRIX_3X2_F dm; - D2D1_POINT_2F center; - - m2d(m, &dm); - center.x = x; - center.y = y; - dm = dm * D2D1::Matrix3x2F::Skew(r2d(xamount), r2d(yamount), center); - d2m(&dm, m); -} - -void uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src) -{ - D2D1_MATRIX_3X2_F c, d; - - m2d(dest, &c); - m2d(src, &d); - c = c * d; - d2m(&c, dest); -} - -int uiDrawMatrixInvertible(uiDrawMatrix *m) -{ - D2D1_MATRIX_3X2_F d; - - m2d(m, &d); - return D2D1IsMatrixInvertible(&d) != FALSE; -} - -int uiDrawMatrixInvert(uiDrawMatrix *m) -{ - D2D1_MATRIX_3X2_F d; - - m2d(m, &d); - if (D2D1InvertMatrix(&d) == FALSE) - return 0; - d2m(&d, m); - return 1; -} - -void uiDrawMatrixTransformPoint(uiDrawMatrix *m, double *x, double *y) -{ - D2D1::Matrix3x2F dm; - D2D1_POINT_2F pt; - - m2d(m, &dm); - pt.x = *x; - pt.y = *y; - pt = dm.TransformPoint(pt); - *x = pt.x; - *y = pt.y; -} - -void uiDrawMatrixTransformSize(uiDrawMatrix *m, double *x, double *y) -{ - fallbackTransformSize(m, x, y); -} diff --git a/deps/libui/windows/drawpath.cpp b/deps/libui/windows/drawpath.cpp deleted file mode 100644 index 49855be6c3..0000000000 --- a/deps/libui/windows/drawpath.cpp +++ /dev/null @@ -1,246 +0,0 @@ -// 7 september 2015 -#include "uipriv_windows.hpp" -#include "draw.hpp" - -// TODO -// - write a test for transform followed by clip and clip followed by transform to make sure they work the same as on gtk+ and cocoa -// - write a test for nested transforms for gtk+ - -struct uiDrawPath { - ID2D1PathGeometry *path; - ID2D1GeometrySink *sink; - BOOL inFigure; -}; - -uiDrawPath *uiDrawNewPath(uiDrawFillMode fillmode) -{ - uiDrawPath *p; - HRESULT hr; - - p = uiNew(uiDrawPath); - hr = d2dfactory->CreatePathGeometry(&(p->path)); - if (hr != S_OK) - logHRESULT(L"error creating path", hr); - hr = p->path->Open(&(p->sink)); - if (hr != S_OK) - logHRESULT(L"error opening path", hr); - switch (fillmode) { - case uiDrawFillModeWinding: - p->sink->SetFillMode(D2D1_FILL_MODE_WINDING); - break; - case uiDrawFillModeAlternate: - p->sink->SetFillMode(D2D1_FILL_MODE_ALTERNATE); - break; - } - return p; -} - -void uiDrawFreePath(uiDrawPath *p) -{ - if (p->inFigure) - p->sink->EndFigure(D2D1_FIGURE_END_OPEN); - if (p->sink != NULL) - // TODO close sink first? - p->sink->Release(); - p->path->Release(); - uiFree(p); -} - -void uiDrawPathNewFigure(uiDrawPath *p, double x, double y) -{ - D2D1_POINT_2F pt; - - if (p->inFigure) - p->sink->EndFigure(D2D1_FIGURE_END_OPEN); - pt.x = x; - pt.y = y; - p->sink->BeginFigure(pt, D2D1_FIGURE_BEGIN_FILLED); - p->inFigure = TRUE; -} - -// Direct2D arcs require a little explanation. -// An arc in Direct2D is defined by the chord between the endpoints. -// There are four possible arcs with the same two endpoints that you can draw this way. -// See https://www.youtube.com/watch?v=ATS0ANW1UxQ for a demonstration. -// There is a property rotationAngle which deals with the rotation /of the entire ellipse that forms an ellpitical arc/ - it's effectively a transformation on the arc. -// That is to say, it's NOT THE SWEEP. -// The sweep is defined by the start and end points and whether the arc is "large". -// As a result, this design does not allow for full circles or ellipses with a single arc; they have to be simulated with two. - -struct arc { - double xCenter; - double yCenter; - double radius; - double startAngle; - double sweep; - int negative; -}; - -// this is used for the comparison below -// if it falls apart it can be changed later -#define aerMax 6 * DBL_EPSILON - -static void drawArc(uiDrawPath *p, struct arc *a, void (*startFunction)(uiDrawPath *, double, double)) -{ - double sinx, cosx; - double startX, startY; - double endX, endY; - D2D1_ARC_SEGMENT as; - BOOL fullCircle; - double absSweep; - - // as above, we can't do a full circle with one arc - // simulate it with two half-circles - // of course, we have a dragon: equality on floating-point values! - // I've chosen to do the AlmostEqualRelative() technique in https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ - fullCircle = FALSE; - // use the absolute value to tackle both ≥2π and ≤-2π at the same time - absSweep = fabs(a->sweep); - if (absSweep > (2 * uiPi)) // this part is easy - fullCircle = TRUE; - else { - double aerDiff; - - aerDiff = fabs(absSweep - (2 * uiPi)); - // if we got here then we know a->sweep is larger (or the same!) - fullCircle = aerDiff <= absSweep * aerMax; - } - // TODO make sure this works right for the negative direction - if (fullCircle) { - a->sweep = uiPi; - drawArc(p, a, startFunction); - a->startAngle += uiPi; - drawArc(p, a, NULL); - return; - } - - // first, figure out the arc's endpoints - // unfortunately D2D1SinCos() is only defined on Windows 8 and newer - // the MSDN page doesn't say this, but says it requires d2d1_1.h, which is listed as only supported on Windows 8 and newer elsewhere on MSDN - // so we must use sin() and cos() and hope it's right... - sinx = sin(a->startAngle); - cosx = cos(a->startAngle); - startX = a->xCenter + a->radius * cosx; - startY = a->yCenter + a->radius * sinx; - sinx = sin(a->startAngle + a->sweep); - cosx = cos(a->startAngle + a->sweep); - endX = a->xCenter + a->radius * cosx; - endY = a->yCenter + a->radius * sinx; - - // now do the initial step to get the current point to be the start point - // this is either creating a new figure, drawing a line, or (in the case of our full circle code above) doing nothing - if (startFunction != NULL) - (*startFunction)(p, startX, startY); - - // now we can draw the arc - as.point.x = endX; - as.point.y = endY; - as.size.width = a->radius; - as.size.height = a->radius; - as.rotationAngle = 0; // as above, not relevant for circles - if (a->negative) - as.sweepDirection = D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE; - else - as.sweepDirection = D2D1_SWEEP_DIRECTION_CLOCKWISE; - // TODO explain the outer if - if (!a->negative) - if (a->sweep > uiPi) - as.arcSize = D2D1_ARC_SIZE_LARGE; - else - as.arcSize = D2D1_ARC_SIZE_SMALL; - else - // TODO especially this part - if (a->sweep > uiPi) - as.arcSize = D2D1_ARC_SIZE_SMALL; - else - as.arcSize = D2D1_ARC_SIZE_LARGE; - p->sink->AddArc(&as); -} - -void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative) -{ - struct arc a; - - a.xCenter = xCenter; - a.yCenter = yCenter; - a.radius = radius; - a.startAngle = startAngle; - a.sweep = sweep; - a.negative = negative; - drawArc(p, &a, uiDrawPathNewFigure); -} - -void uiDrawPathLineTo(uiDrawPath *p, double x, double y) -{ - D2D1_POINT_2F pt; - - pt.x = x; - pt.y = y; - p->sink->AddLine(pt); -} - -void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative) -{ - struct arc a; - - a.xCenter = xCenter; - a.yCenter = yCenter; - a.radius = radius; - a.startAngle = startAngle; - a.sweep = sweep; - a.negative = negative; - drawArc(p, &a, uiDrawPathLineTo); -} - -void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY) -{ - D2D1_BEZIER_SEGMENT s; - - s.point1.x = c1x; - s.point1.y = c1y; - s.point2.x = c2x; - s.point2.y = c2y; - s.point3.x = endX; - s.point3.y = endY; - p->sink->AddBezier(&s); -} - -void uiDrawPathCloseFigure(uiDrawPath *p) -{ - p->sink->EndFigure(D2D1_FIGURE_END_CLOSED); - p->inFigure = FALSE; -} - -void uiDrawPathAddRectangle(uiDrawPath *p, double x, double y, double width, double height) -{ - // this is the same algorithm used by cairo and Core Graphics, according to their documentations - uiDrawPathNewFigure(p, x, y); - uiDrawPathLineTo(p, x + width, y); - uiDrawPathLineTo(p, x + width, y + height); - uiDrawPathLineTo(p, x, y + height); - uiDrawPathCloseFigure(p); -} - -void uiDrawPathEnd(uiDrawPath *p) -{ - HRESULT hr; - - if (p->inFigure) { - p->sink->EndFigure(D2D1_FIGURE_END_OPEN); - // needed for uiDrawFreePath() - p->inFigure = FALSE; - } - hr = p->sink->Close(); - if (hr != S_OK) - logHRESULT(L"error closing path", hr); - p->sink->Release(); - // also needed for uiDrawFreePath() - p->sink = NULL; -} - -ID2D1PathGeometry *pathGeometry(uiDrawPath *p) -{ - if (p->sink != NULL) - userbug("You cannot draw with a uiDrawPath that was not ended. (path: %p)", p); - return p->path; -} diff --git a/deps/libui/windows/drawtext.cpp b/deps/libui/windows/drawtext.cpp deleted file mode 100644 index 05a24f6776..0000000000 --- a/deps/libui/windows/drawtext.cpp +++ /dev/null @@ -1,531 +0,0 @@ -// 22 december 2015 -#include "uipriv_windows.hpp" -#include "draw.hpp" -// TODO really migrate - -// notes: -// only available in windows 8 and newer: -// - character spacing -// - kerning control -// - justficiation (how could I possibly be making this up?!) -// - vertical text (SERIOUSLY?! WHAT THE ACTUAL FUCK, MICROSOFT?!?!?!? DID YOU NOT THINK ABOUT THIS THE FIRST TIME, TRYING TO IMPROVE THE INTERNATIONALIZATION OF WINDOWS 7?!?!?! bonus: some parts of MSDN even say 8.1 and up only!) - -struct uiDrawFontFamilies { - fontCollection *fc; -}; - -uiDrawFontFamilies *uiDrawListFontFamilies(void) -{ - struct uiDrawFontFamilies *ff; - - ff = uiNew(struct uiDrawFontFamilies); - ff->fc = loadFontCollection(); - return ff; -} - -int uiDrawFontFamiliesNumFamilies(uiDrawFontFamilies *ff) -{ - return ff->fc->fonts->GetFontFamilyCount(); -} - -char *uiDrawFontFamiliesFamily(uiDrawFontFamilies *ff, int n) -{ - IDWriteFontFamily *family; - WCHAR *wname; - char *name; - HRESULT hr; - - hr = ff->fc->fonts->GetFontFamily(n, &family); - if (hr != S_OK) - logHRESULT(L"error getting font out of collection", hr); - wname = fontCollectionFamilyName(ff->fc, family); - name = toUTF8(wname); - uiFree(wname); - family->Release(); - return name; -} - -void uiDrawFreeFontFamilies(uiDrawFontFamilies *ff) -{ - fontCollectionFree(ff->fc); - uiFree(ff); -} - -struct uiDrawTextFont { - IDWriteFont *f; - WCHAR *family; // save for convenience in uiDrawNewTextLayout() - double size; -}; - -uiDrawTextFont *mkTextFont(IDWriteFont *df, BOOL addRef, WCHAR *family, BOOL copyFamily, double size) -{ - uiDrawTextFont *font; - WCHAR *copy; - HRESULT hr; - - font = uiNew(uiDrawTextFont); - font->f = df; - if (addRef) - font->f->AddRef(); - if (copyFamily) { - copy = (WCHAR *) uiAlloc((wcslen(family) + 1) * sizeof (WCHAR), "WCHAR[]"); - wcscpy(copy, family); - font->family = copy; - } else - font->family = family; - font->size = size; - return font; -} - -// TODO consider moving these all to dwrite.cpp - -// TODO MinGW-w64 is missing this one -#define DWRITE_FONT_WEIGHT_SEMI_LIGHT (DWRITE_FONT_WEIGHT(350)) -static const struct { - bool lastOne; - uiDrawTextWeight uival; - DWRITE_FONT_WEIGHT dwval; -} dwriteWeights[] = { - { false, uiDrawTextWeightThin, DWRITE_FONT_WEIGHT_THIN }, - { false, uiDrawTextWeightUltraLight, DWRITE_FONT_WEIGHT_ULTRA_LIGHT }, - { false, uiDrawTextWeightLight, DWRITE_FONT_WEIGHT_LIGHT }, - { false, uiDrawTextWeightBook, DWRITE_FONT_WEIGHT_SEMI_LIGHT }, - { false, uiDrawTextWeightNormal, DWRITE_FONT_WEIGHT_NORMAL }, - { false, uiDrawTextWeightMedium, DWRITE_FONT_WEIGHT_MEDIUM }, - { false, uiDrawTextWeightSemiBold, DWRITE_FONT_WEIGHT_SEMI_BOLD }, - { false, uiDrawTextWeightBold, DWRITE_FONT_WEIGHT_BOLD }, - { false, uiDrawTextWeightUltraBold, DWRITE_FONT_WEIGHT_ULTRA_BOLD }, - { false, uiDrawTextWeightHeavy, DWRITE_FONT_WEIGHT_HEAVY }, - { true, uiDrawTextWeightUltraHeavy, DWRITE_FONT_WEIGHT_ULTRA_BLACK, }, -}; - -static const struct { - bool lastOne; - uiDrawTextItalic uival; - DWRITE_FONT_STYLE dwval; -} dwriteItalics[] = { - { false, uiDrawTextItalicNormal, DWRITE_FONT_STYLE_NORMAL }, - { false, uiDrawTextItalicOblique, DWRITE_FONT_STYLE_OBLIQUE }, - { true, uiDrawTextItalicItalic, DWRITE_FONT_STYLE_ITALIC }, -}; - -static const struct { - bool lastOne; - uiDrawTextStretch uival; - DWRITE_FONT_STRETCH dwval; -} dwriteStretches[] = { - { false, uiDrawTextStretchUltraCondensed, DWRITE_FONT_STRETCH_ULTRA_CONDENSED }, - { false, uiDrawTextStretchExtraCondensed, DWRITE_FONT_STRETCH_EXTRA_CONDENSED }, - { false, uiDrawTextStretchCondensed, DWRITE_FONT_STRETCH_CONDENSED }, - { false, uiDrawTextStretchSemiCondensed, DWRITE_FONT_STRETCH_SEMI_CONDENSED }, - { false, uiDrawTextStretchNormal, DWRITE_FONT_STRETCH_NORMAL }, - { false, uiDrawTextStretchSemiExpanded, DWRITE_FONT_STRETCH_SEMI_EXPANDED }, - { false, uiDrawTextStretchExpanded, DWRITE_FONT_STRETCH_EXPANDED }, - { false, uiDrawTextStretchExtraExpanded, DWRITE_FONT_STRETCH_EXTRA_EXPANDED }, - { true, uiDrawTextStretchUltraExpanded, DWRITE_FONT_STRETCH_ULTRA_EXPANDED }, -}; - -void attrToDWriteAttr(struct dwriteAttr *attr) -{ - bool found; - int i; - - found = false; - for (i = 0; ; i++) { - if (dwriteWeights[i].uival == attr->weight) { - attr->dweight = dwriteWeights[i].dwval; - found = true; - break; - } - if (dwriteWeights[i].lastOne) - break; - } - if (!found) - userbug("Invalid text weight %d passed to text function.", attr->weight); - - found = false; - for (i = 0; ; i++) { - if (dwriteItalics[i].uival == attr->italic) { - attr->ditalic = dwriteItalics[i].dwval; - found = true; - break; - } - if (dwriteItalics[i].lastOne) - break; - } - if (!found) - userbug("Invalid text italic %d passed to text function.", attr->italic); - - found = false; - for (i = 0; ; i++) { - if (dwriteStretches[i].uival == attr->stretch) { - attr->dstretch = dwriteStretches[i].dwval; - found = true; - break; - } - if (dwriteStretches[i].lastOne) - break; - } - if (!found) - // TODO on other platforms too - userbug("Invalid text stretch %d passed to text function.", attr->stretch); -} - -void dwriteAttrToAttr(struct dwriteAttr *attr) -{ - int weight, against, n; - int curdiff, curindex; - bool found; - int i; - - // weight is scaled; we need to test to see what's nearest - weight = (int) (attr->dweight); - against = (int) (dwriteWeights[0].dwval); - curdiff = abs(against - weight); - curindex = 0; - for (i = 1; ; i++) { - against = (int) (dwriteWeights[i].dwval); - n = abs(against - weight); - if (n < curdiff) { - curdiff = n; - curindex = i; - } - if (dwriteWeights[i].lastOne) - break; - } - attr->weight = dwriteWeights[i].uival; - - // italic and stretch are simple values; we can just do a matching search - found = false; - for (i = 0; ; i++) { - if (dwriteItalics[i].dwval == attr->ditalic) { - attr->italic = dwriteItalics[i].uival; - found = true; - break; - } - if (dwriteItalics[i].lastOne) - break; - } - if (!found) - // these are implbug()s because users shouldn't be able to get here directly; TODO? - implbug("invalid italic %d passed to dwriteAttrToAttr()", attr->ditalic); - - found = false; - for (i = 0; ; i++) { - if (dwriteStretches[i].dwval == attr->dstretch) { - attr->stretch = dwriteStretches[i].uival; - found = true; - break; - } - if (dwriteStretches[i].lastOne) - break; - } - if (!found) - implbug("invalid stretch %d passed to dwriteAttrToAttr()", attr->dstretch); -} - -uiDrawTextFont *uiDrawLoadClosestFont(const uiDrawTextFontDescriptor *desc) -{ - uiDrawTextFont *font; - IDWriteFontCollection *collection; - UINT32 index; - BOOL exists; - struct dwriteAttr attr; - IDWriteFontFamily *family; - WCHAR *wfamily; - IDWriteFont *match; - HRESULT hr; - - // always get the latest available font information - hr = dwfactory->GetSystemFontCollection(&collection, TRUE); - if (hr != S_OK) - logHRESULT(L"error getting system font collection", hr); - - wfamily = toUTF16(desc->Family); - hr = collection->FindFamilyName(wfamily, &index, &exists); - if (hr != S_OK) - logHRESULT(L"error finding font family", hr); - if (!exists) - implbug("LONGTERM family not found in uiDrawLoadClosestFont()", hr); - hr = collection->GetFontFamily(index, &family); - if (hr != S_OK) - logHRESULT(L"error loading font family", hr); - - attr.weight = desc->Weight; - attr.italic = desc->Italic; - attr.stretch = desc->Stretch; - attrToDWriteAttr(&attr); - hr = family->GetFirstMatchingFont( - attr.dweight, - attr.dstretch, - attr.ditalic, - &match); - if (hr != S_OK) - logHRESULT(L"error loading font", hr); - - font = mkTextFont(match, - FALSE, // we own the initial reference; no need to add another one - wfamily, FALSE, // will be freed with font - desc->Size); - - family->Release(); - collection->Release(); - - return font; -} - -void uiDrawFreeTextFont(uiDrawTextFont *font) -{ - font->f->Release(); - uiFree(font->family); - uiFree(font); -} - -uintptr_t uiDrawTextFontHandle(uiDrawTextFont *font) -{ - return (uintptr_t) (font->f); -} - -void uiDrawTextFontDescribe(uiDrawTextFont *font, uiDrawTextFontDescriptor *desc) -{ - // TODO - - desc->Size = font->size; - - // TODO -} - -// text sizes are 1/72 of an inch -// points in Direct2D are 1/96 of an inch (https://msdn.microsoft.com/en-us/library/windows/desktop/ff684173%28v=vs.85%29.aspx, https://msdn.microsoft.com/en-us/library/windows/desktop/hh447022%28v=vs.85%29.aspx) -// As for the actual conversion from design units, see: -// - http://cboard.cprogramming.com/windows-programming/136733-directwrite-font-height-issues.html -// - https://sourceforge.net/p/vstgui/mailman/message/32483143/ -// - http://xboxforums.create.msdn.com/forums/t/109445.aspx -// - https://msdn.microsoft.com/en-us/library/dd183564%28v=vs.85%29.aspx -// - http://www.fontbureau.com/blog/the-em/ -// TODO make points here about how DIPs in DirectWrite == DIPs in Direct2D; if not, figure out what they really are? for the width and layout functions later -static double scaleUnits(double what, double designUnitsPerEm, double size) -{ - return (what / designUnitsPerEm) * (size * (96.0 / 72.0)); -} - -void uiDrawTextFontGetMetrics(uiDrawTextFont *font, uiDrawTextFontMetrics *metrics) -{ - DWRITE_FONT_METRICS dm; - - font->f->GetMetrics(&dm); - metrics->Ascent = scaleUnits(dm.ascent, dm.designUnitsPerEm, font->size); - metrics->Descent = scaleUnits(dm.descent, dm.designUnitsPerEm, font->size); - // TODO what happens if dm.xxx is negative? - // TODO remember what this was for - metrics->Leading = scaleUnits(dm.lineGap, dm.designUnitsPerEm, font->size); - metrics->UnderlinePos = scaleUnits(dm.underlinePosition, dm.designUnitsPerEm, font->size); - metrics->UnderlineThickness = scaleUnits(dm.underlineThickness, dm.designUnitsPerEm, font->size); -} - -// some attributes, such as foreground color, can't be applied until after we establish a Direct2D context :/ so we have to prepare all attributes in advance -// also since there's no way to clear the attributes from a layout en masse (apart from overwriting them all), we'll play it safe by creating a new layout each time -enum layoutAttrType { - layoutAttrColor, -}; - -struct layoutAttr { - enum layoutAttrType type; - int start; - int end; - double components[4]; -}; - -struct uiDrawTextLayout { - WCHAR *text; - size_t textlen; - size_t *graphemes; - double width; - IDWriteTextFormat *format; - std::vector *attrs; -}; - -uiDrawTextLayout *uiDrawNewTextLayout(const char *text, uiDrawTextFont *defaultFont, double width) -{ - uiDrawTextLayout *layout; - HRESULT hr; - - layout = uiNew(uiDrawTextLayout); - - hr = dwfactory->CreateTextFormat(defaultFont->family, - NULL, - defaultFont->f->GetWeight(), - defaultFont->f->GetStyle(), - defaultFont->f->GetStretch(), - // typographic points are 1/72 inch; this parameter is 1/96 inch - // fortunately Microsoft does this too, in https://msdn.microsoft.com/en-us/library/windows/desktop/dd371554%28v=vs.85%29.aspx - defaultFont->size * (96.0 / 72.0), - // see http://stackoverflow.com/questions/28397971/idwritefactorycreatetextformat-failing and https://msdn.microsoft.com/en-us/library/windows/desktop/dd368203.aspx - // TODO use the current locale again? - L"", - &(layout->format)); - if (hr != S_OK) - logHRESULT(L"error creating IDWriteTextFormat", hr); - - layout->text = toUTF16(text); - layout->textlen = wcslen(layout->text); - layout->graphemes = graphemes(layout->text); - - uiDrawTextLayoutSetWidth(layout, width); - - layout->attrs = new std::vector; - - return layout; -} - -void uiDrawFreeTextLayout(uiDrawTextLayout *layout) -{ - delete layout->attrs; - layout->format->Release(); - uiFree(layout->graphemes); - uiFree(layout->text); - uiFree(layout); -} - -static ID2D1SolidColorBrush *mkSolidBrush(ID2D1RenderTarget *rt, double r, double g, double b, double a) -{ - D2D1_BRUSH_PROPERTIES props; - D2D1_COLOR_F color; - ID2D1SolidColorBrush *brush; - HRESULT hr; - - ZeroMemory(&props, sizeof (D2D1_BRUSH_PROPERTIES)); - props.opacity = 1.0; - // identity matrix - props.transform._11 = 1; - props.transform._22 = 1; - color.r = r; - color.g = g; - color.b = b; - color.a = a; - hr = rt->CreateSolidColorBrush( - &color, - &props, - &brush); - if (hr != S_OK) - logHRESULT(L"error creating solid brush", hr); - return brush; -} - -IDWriteTextLayout *prepareLayout(uiDrawTextLayout *layout, ID2D1RenderTarget *rt) -{ - IDWriteTextLayout *dl; - DWRITE_TEXT_RANGE range; - IUnknown *unkBrush; - DWRITE_WORD_WRAPPING wrap; - FLOAT maxWidth; - HRESULT hr; - - hr = dwfactory->CreateTextLayout(layout->text, layout->textlen, - layout->format, - // FLOAT is float, not double, so this should work... TODO - FLT_MAX, FLT_MAX, - &dl); - if (hr != S_OK) - logHRESULT(L"error creating IDWriteTextLayout", hr); - - for (const struct layoutAttr &attr : *(layout->attrs)) { - range.startPosition = layout->graphemes[attr.start]; - range.length = layout->graphemes[attr.end] - layout->graphemes[attr.start]; - switch (attr.type) { - case layoutAttrColor: - if (rt == NULL) // determining extents, not drawing - break; - unkBrush = mkSolidBrush(rt, - attr.components[0], - attr.components[1], - attr.components[2], - attr.components[3]); - hr = dl->SetDrawingEffect(unkBrush, range); - unkBrush->Release(); // associated with dl - break; - default: - hr = E_FAIL; - logHRESULT(L"invalid text attribute type", hr); - } - if (hr != S_OK) - logHRESULT(L"error adding attribute to text layout", hr); - } - - // and set the width - // this is the only wrapping mode (apart from "no wrap") available prior to Windows 8.1 - wrap = DWRITE_WORD_WRAPPING_WRAP; - maxWidth = layout->width; - if (layout->width < 0) { - wrap = DWRITE_WORD_WRAPPING_NO_WRAP; - // setting the max width in this case technically isn't needed since the wrap mode will simply ignore the max width, but let's do it just to be safe - maxWidth = FLT_MAX; // see TODO above - } - hr = dl->SetWordWrapping(wrap); - if (hr != S_OK) - logHRESULT(L"error setting word wrapping mode", hr); - hr = dl->SetMaxWidth(maxWidth); - if (hr != S_OK) - logHRESULT(L"error setting max layout width", hr); - - return dl; -} - - -void uiDrawTextLayoutSetWidth(uiDrawTextLayout *layout, double width) -{ - layout->width = width; -} - -// TODO for a single line the height includes the leading; it should not -void uiDrawTextLayoutExtents(uiDrawTextLayout *layout, double *width, double *height) -{ - IDWriteTextLayout *dl; - DWRITE_TEXT_METRICS metrics; - HRESULT hr; - - dl = prepareLayout(layout, NULL); - hr = dl->GetMetrics(&metrics); - if (hr != S_OK) - logHRESULT(L"error getting layout metrics", hr); - *width = metrics.width; - // TODO make sure the behavior of this on empty strings is the same on all platforms - *height = metrics.height; - dl->Release(); -} - -void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout) -{ - IDWriteTextLayout *dl; - D2D1_POINT_2F pt; - ID2D1Brush *black; - HRESULT hr; - - // TODO document that fully opaque black is the default text color; figure out whether this is upheld in various scenarios on other platforms - black = mkSolidBrush(c->rt, 0.0, 0.0, 0.0, 1.0); - - dl = prepareLayout(layout, c->rt); - pt.x = x; - pt.y = y; - // TODO D2D1_DRAW_TEXT_OPTIONS_NO_SNAP? - // TODO D2D1_DRAW_TEXT_OPTIONS_CLIP? - // TODO when setting 8.1 as minimum, D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT? - c->rt->DrawTextLayout(pt, dl, black, D2D1_DRAW_TEXT_OPTIONS_NONE); - dl->Release(); - - black->Release(); -} - -void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, int startChar, int endChar, double r, double g, double b, double a) -{ - struct layoutAttr attr; - - attr.type = layoutAttrColor; - attr.start = startChar; - attr.end = endChar; - attr.components[0] = r; - attr.components[1] = g; - attr.components[2] = b; - attr.components[3] = a; - layout->attrs->push_back(attr); -} diff --git a/deps/libui/windows/dwrite.cpp b/deps/libui/windows/dwrite.cpp deleted file mode 100644 index 9156f179d6..0000000000 --- a/deps/libui/windows/dwrite.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// 14 april 2016 -#include "uipriv_windows.hpp" -// TODO really migrate? - -IDWriteFactory *dwfactory = NULL; - -HRESULT initDrawText(void) -{ - // TOOD use DWRITE_FACTORY_TYPE_ISOLATED instead? - return DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, - __uuidof (IDWriteFactory), - (IUnknown **) (&dwfactory)); -} - -void uninitDrawText(void) -{ - dwfactory->Release(); -} - -fontCollection *loadFontCollection(void) -{ - fontCollection *fc; - HRESULT hr; - - fc = uiNew(fontCollection); - // always get the latest available font information - hr = dwfactory->GetSystemFontCollection(&(fc->fonts), TRUE); - if (hr != S_OK) - logHRESULT(L"error getting system font collection", hr); - fc->userLocaleSuccess = GetUserDefaultLocaleName(fc->userLocale, LOCALE_NAME_MAX_LENGTH); - return fc; -} - -WCHAR *fontCollectionFamilyName(fontCollection *fc, IDWriteFontFamily *family) -{ - IDWriteLocalizedStrings *names; - WCHAR *str; - HRESULT hr; - - hr = family->GetFamilyNames(&names); - if (hr != S_OK) - logHRESULT(L"error getting names of font out", hr); - str = fontCollectionCorrectString(fc, names); - names->Release(); - return str; -} - -WCHAR *fontCollectionCorrectString(fontCollection *fc, IDWriteLocalizedStrings *names) -{ - UINT32 index; - BOOL exists; - UINT32 length; - WCHAR *wname; - HRESULT hr; - - // this is complex, but we ignore failure conditions to allow fallbacks - // 1) If the user locale name was successfully retrieved, try it - // 2) If the user locale name was not successfully retrieved, or that locale's string does not exist, or an error occurred, try L"en-us", the US English locale - // 3) And if that fails, assume the first one - // This algorithm is straight from MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/dd368214%28v=vs.85%29.aspx - // For step 2 to work, start by setting hr to S_OK and exists to FALSE. - // TODO does it skip step 2 entirely if step 1 fails? rewrite it to be a more pure conversion of the MSDN code? - hr = S_OK; - exists = FALSE; - if (fc->userLocaleSuccess != 0) - hr = names->FindLocaleName(fc->userLocale, &index, &exists); - if (hr != S_OK || (hr == S_OK && !exists)) - hr = names->FindLocaleName(L"en-us", &index, &exists); - if (!exists) - index = 0; - - hr = names->GetStringLength(index, &length); - if (hr != S_OK) - logHRESULT(L"error getting length of font name", hr); - // GetStringLength() does not include the null terminator, but GetString() does - wname = (WCHAR *) uiAlloc((length + 1) * sizeof (WCHAR), "WCHAR[]"); - hr = names->GetString(index, wname, length + 1); - if (hr != S_OK) - logHRESULT(L"error getting font name", hr); - - return wname; -} - -void fontCollectionFree(fontCollection *fc) -{ - fc->fonts->Release(); - uiFree(fc); -} diff --git a/deps/libui/windows/editablecombo.cpp b/deps/libui/windows/editablecombo.cpp deleted file mode 100644 index 9e1fdbfbc3..0000000000 --- a/deps/libui/windows/editablecombo.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// 20 may 2015 -#include "uipriv_windows.hpp" - -// we as Common Controls 6 users don't need to worry about the height of comboboxes; see http://blogs.msdn.com/b/oldnewthing/archive/2006/03/10/548537.aspx - -struct uiEditableCombobox { - uiWindowsControl c; - HWND hwnd; - void (*onChanged)(uiEditableCombobox *, void *); - void *onChangedData; -}; - -static BOOL onWM_COMMAND(uiControl *cc, HWND hwnd, WORD code, LRESULT *lResult) -{ - uiEditableCombobox *c = uiEditableCombobox(cc); - - if (code == CBN_SELCHANGE) { - // like on OS X, this is sent before the edit has been updated :( - if (PostMessage(parentOf(hwnd), - WM_COMMAND, - MAKEWPARAM(GetWindowLongPtrW(hwnd, GWLP_ID), CBN_EDITCHANGE), - (LPARAM) hwnd) == 0) - logLastError(L"error posting CBN_EDITCHANGE after CBN_SELCHANGE"); - *lResult = 0; - return TRUE; - } - if (code != CBN_EDITCHANGE) - return FALSE; - (*(c->onChanged))(c, c->onChangedData); - *lResult = 0; - return TRUE; -} - -void uiEditableComboboxDestroy(uiControl *cc) -{ - uiEditableCombobox *c = uiEditableCombobox(cc); - - uiWindowsUnregisterWM_COMMANDHandler(c->hwnd); - uiWindowsEnsureDestroyWindow(c->hwnd); - uiFreeControl(uiControl(c)); -} - -uiWindowsControlAllDefaultsExceptDestroy(uiEditableCombobox) - -// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define comboboxWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary; LONGTERM */ -#define comboboxHeight 14 /* LONGTERM: is this too high? */ - -static void uiEditableComboboxMinimumSize(uiWindowsControl *cc, int *width, int *height) -{ - uiEditableCombobox *c = uiEditableCombobox(cc); - uiWindowsSizing sizing; - int x, y; - - x = comboboxWidth; - y = comboboxHeight; - uiWindowsGetSizing(c->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); - *width = x; - *height = y; -} - -static void defaultOnChanged(uiEditableCombobox *c, void *data) -{ - // do nothing -} - -void uiEditableComboboxAppend(uiEditableCombobox *c, const char *text) -{ - WCHAR *wtext; - LRESULT res; - - wtext = toUTF16(text); - res = SendMessageW(c->hwnd, CB_ADDSTRING, 0, (LPARAM) wtext); - if (res == (LRESULT) CB_ERR) - logLastError(L"error appending item to uiEditableCombobox"); - else if (res == (LRESULT) CB_ERRSPACE) - logLastError(L"memory exhausted appending item to uiEditableCombobox"); - uiFree(wtext); -} - -char *uiEditableComboboxText(uiEditableCombobox *c) -{ - return uiWindowsWindowText(c->hwnd); -} - -void uiEditableComboboxSetText(uiEditableCombobox *c, const char *text) -{ - // does not trigger any notifications - uiWindowsSetWindowText(c->hwnd, text); -} - -void uiEditableComboboxOnChanged(uiEditableCombobox *c, void (*f)(uiEditableCombobox *c, void *data), void *data) -{ - c->onChanged = f; - c->onChangedData = data; -} - -uiEditableCombobox *uiNewEditableCombobox(void) -{ - uiEditableCombobox *c; - - uiWindowsNewControl(uiEditableCombobox, c); - - c->hwnd = uiWindowsEnsureCreateControlHWND(WS_EX_CLIENTEDGE, - L"combobox", L"", - CBS_DROPDOWN | WS_TABSTOP, - hInstance, NULL, - TRUE); - - uiWindowsRegisterWM_COMMANDHandler(c->hwnd, onWM_COMMAND, uiControl(c)); - uiEditableComboboxOnChanged(c, defaultOnChanged, NULL); - - return c; -} diff --git a/deps/libui/windows/entry.cpp b/deps/libui/windows/entry.cpp deleted file mode 100644 index a7a077f203..0000000000 --- a/deps/libui/windows/entry.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// 8 april 2015 -#include "uipriv_windows.hpp" - -struct uiEntry { - uiWindowsControl c; - HWND hwnd; - void (*onChanged)(uiEntry *, void *); - void *onChangedData; - BOOL inhibitChanged; -}; - -static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) -{ - uiEntry *e = uiEntry(c); - - if (code != EN_CHANGE) - return FALSE; - if (e->inhibitChanged) - return FALSE; - (*(e->onChanged))(e, e->onChangedData); - *lResult = 0; - return TRUE; -} - -static void uiEntryDestroy(uiControl *c) -{ - uiEntry *e = uiEntry(c); - - uiWindowsUnregisterWM_COMMANDHandler(e->hwnd); - uiWindowsEnsureDestroyWindow(e->hwnd); - uiFreeControl(uiControl(e)); -} - -uiWindowsControlAllDefaultsExceptDestroy(uiEntry) - -// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define entryWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary */ -#define entryHeight 14 - -static void uiEntryMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiEntry *e = uiEntry(c); - uiWindowsSizing sizing; - int x, y; - - x = entryWidth; - y = entryHeight; - uiWindowsGetSizing(e->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); - *width = x; - *height = y; -} - -static void defaultOnChanged(uiEntry *e, void *data) -{ - // do nothing -} - -char *uiEntryText(uiEntry *e) -{ - return uiWindowsWindowText(e->hwnd); -} - -void uiEntrySetText(uiEntry *e, const char *text) -{ - // doing this raises an EN_CHANGED - e->inhibitChanged = TRUE; - uiWindowsSetWindowText(e->hwnd, text); - e->inhibitChanged = FALSE; - // don't queue the control for resize; entry sizes are independent of their contents -} - -void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *, void *), void *data) -{ - e->onChanged = f; - e->onChangedData = data; -} - -int uiEntryReadOnly(uiEntry *e) -{ - return (getStyle(e->hwnd) & ES_READONLY) != 0; -} - -void uiEntrySetReadOnly(uiEntry *e, int readonly) -{ - WPARAM ro; - - ro = (WPARAM) FALSE; - if (readonly) - ro = (WPARAM) TRUE; - if (SendMessage(e->hwnd, EM_SETREADONLY, ro, 0) == 0) - logLastError(L"error making uiEntry read-only"); -} - -static uiEntry *finishNewEntry(DWORD style) -{ - uiEntry *e; - - uiWindowsNewControl(uiEntry, e); - - e->hwnd = uiWindowsEnsureCreateControlHWND(WS_EX_CLIENTEDGE, - L"edit", L"", - style | ES_AUTOHSCROLL | ES_LEFT | ES_NOHIDESEL | WS_TABSTOP, - hInstance, NULL, - TRUE); - - uiWindowsRegisterWM_COMMANDHandler(e->hwnd, onWM_COMMAND, uiControl(e)); - uiEntryOnChanged(e, defaultOnChanged, NULL); - - return e; -} - -uiEntry *uiNewEntry(void) -{ - return finishNewEntry(0); -} - -uiEntry *uiNewPasswordEntry(void) -{ - return finishNewEntry(ES_PASSWORD); -} - -uiEntry *uiNewSearchEntry(void) -{ - uiEntry *e; - HRESULT hr; - - e = finishNewEntry(0); - // TODO this is from ThemeExplorer; is it documented anywhere? - // TODO SearchBoxEditComposited has no border - hr = SetWindowTheme(e->hwnd, L"SearchBoxEdit", NULL); - // TODO will hr be S_OK if themes are disabled? - return e; -} diff --git a/deps/libui/windows/events.cpp b/deps/libui/windows/events.cpp deleted file mode 100644 index 45e8d43d97..0000000000 --- a/deps/libui/windows/events.cpp +++ /dev/null @@ -1,151 +0,0 @@ -// 20 may 2015 -#include "uipriv_windows.hpp" - -struct handler { - BOOL (*commandHandler)(uiControl *, HWND, WORD, LRESULT *); - BOOL (*notifyHandler)(uiControl *, HWND, NMHDR *, LRESULT *); - BOOL (*hscrollHandler)(uiControl *, HWND, WORD, LRESULT *); - uiControl *c; - - // just to ensure handlers[new HWND] initializes properly - // TODO gcc can't handle a struct keyword here? or is that a MSVC extension? - handler() - { - this->commandHandler = NULL; - this->notifyHandler = NULL; - this->hscrollHandler = NULL; - this->c = NULL; - } -}; - -static std::map handlers; - -void uiWindowsRegisterWM_COMMANDHandler(HWND hwnd, BOOL (*handler)(uiControl *, HWND, WORD, LRESULT *), uiControl *c) -{ - if (handlers[hwnd].commandHandler != NULL) - implbug("already registered a WM_COMMAND handler to window handle %p", hwnd); - handlers[hwnd].commandHandler = handler; - handlers[hwnd].c = c; -} - -void uiWindowsRegisterWM_NOTIFYHandler(HWND hwnd, BOOL (*handler)(uiControl *, HWND, NMHDR *, LRESULT *), uiControl *c) -{ - if (handlers[hwnd].notifyHandler != NULL) - implbug("already registered a WM_NOTIFY handler to window handle %p", hwnd); - handlers[hwnd].notifyHandler = handler; - handlers[hwnd].c = c; -} - -void uiWindowsRegisterWM_HSCROLLHandler(HWND hwnd, BOOL (*handler)(uiControl *, HWND, WORD, LRESULT *), uiControl *c) -{ - if (handlers[hwnd].hscrollHandler != NULL) - implbug("already registered a WM_HSCROLL handler to window handle %p", hwnd); - handlers[hwnd].hscrollHandler = handler; - handlers[hwnd].c = c; -} - -void uiWindowsUnregisterWM_COMMANDHandler(HWND hwnd) -{ - if (handlers[hwnd].commandHandler == NULL) - implbug("window handle %p not registered to receive WM_COMMAND events", hwnd); - handlers[hwnd].commandHandler = NULL; -} - -void uiWindowsUnregisterWM_NOTIFYHandler(HWND hwnd) -{ - if (handlers[hwnd].notifyHandler == NULL) - implbug("window handle %p not registered to receive WM_NOTIFY events", hwnd); - handlers[hwnd].notifyHandler = NULL; -} - -void uiWindowsUnregisterWM_HSCROLLHandler(HWND hwnd) -{ - if (handlers[hwnd].hscrollHandler == NULL) - implbug("window handle %p not registered to receive WM_HSCROLL events", hwnd); - handlers[hwnd].hscrollHandler = NULL; -} - -template -static BOOL shouldRun(HWND hwnd, T method) -{ - // not from a window - if (hwnd == NULL) - return FALSE; - // don't bounce back if to the utility window, in which case act as if the message was ignored - if (IsChild(utilWindow, hwnd) != 0) - return FALSE; - // registered? - return method != NULL; -} - -BOOL runWM_COMMAND(WPARAM wParam, LPARAM lParam, LRESULT *lResult) -{ - HWND hwnd; - WORD arg3; - BOOL (*handler)(uiControl *, HWND, WORD, LRESULT *); - uiControl *c; - - hwnd = (HWND) lParam; - arg3 = HIWORD(wParam); - handler = handlers[hwnd].commandHandler; - c = handlers[hwnd].c; - if (shouldRun(hwnd, handler)) - return (*handler)(c, hwnd, arg3, lResult); - return FALSE; -} - -BOOL runWM_NOTIFY(WPARAM wParam, LPARAM lParam, LRESULT *lResult) -{ - HWND hwnd; - NMHDR *arg3; - BOOL (*handler)(uiControl *, HWND, NMHDR *, LRESULT *); - uiControl *c; - - arg3 = (NMHDR *) lParam; - hwnd = arg3->hwndFrom; - handler = handlers[hwnd].notifyHandler; - c = handlers[hwnd].c; - if (shouldRun(hwnd, handler)) - return (*handler)(c, hwnd, arg3, lResult); - return FALSE; -} - -BOOL runWM_HSCROLL(WPARAM wParam, LPARAM lParam, LRESULT *lResult) -{ - HWND hwnd; - WORD arg3; - BOOL (*handler)(uiControl *, HWND, WORD, LRESULT *); - uiControl *c; - - hwnd = (HWND) lParam; - arg3 = LOWORD(wParam); - handler = handlers[hwnd].hscrollHandler; - c = handlers[hwnd].c; - if (shouldRun(hwnd, handler)) - return (*handler)(c, hwnd, arg3, lResult); - return FALSE; -} - -static std::map wininichanges; - -void uiWindowsRegisterReceiveWM_WININICHANGE(HWND hwnd) -{ - if (wininichanges[hwnd]) - implbug("window handle %p already subscribed to receive WM_WINICHANGEs", hwnd); - wininichanges[hwnd] = true; -} - -void uiWindowsUnregisterReceiveWM_WININICHANGE(HWND hwnd) -{ - if (!wininichanges[hwnd]) - implbug("window handle %p not registered to receive WM_WININICHANGEs", hwnd); - wininichanges[hwnd] = false; -} - -void issueWM_WININICHANGE(WPARAM wParam, LPARAM lParam) -{ - struct wininichange *ch; - - for (const auto &iter : wininichanges) - SendMessageW(iter.first, WM_WININICHANGE, wParam, lParam); -} diff --git a/deps/libui/windows/fontbutton.cpp b/deps/libui/windows/fontbutton.cpp deleted file mode 100644 index d2d4dabfa9..0000000000 --- a/deps/libui/windows/fontbutton.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// 14 april 2016 -#include "uipriv_windows.hpp" - -struct uiFontButton { - uiWindowsControl c; - HWND hwnd; - struct fontDialogParams params; - BOOL already; - void (*onChanged)(uiFontButton *, void *); - void *onChangedData; -}; - -static void uiFontButtonDestroy(uiControl *c) -{ - uiFontButton *b = uiFontButton(c); - - uiWindowsUnregisterWM_COMMANDHandler(b->hwnd); - destroyFontDialogParams(&(b->params)); - uiWindowsEnsureDestroyWindow(b->hwnd); - uiFreeControl(uiControl(b)); -} - -static void updateFontButtonLabel(uiFontButton *b) -{ - WCHAR *text; - - text = fontDialogParamsToString(&(b->params)); - setWindowText(b->hwnd, text); - uiFree(text); - - // changing the text might necessitate a change in the button's size - uiWindowsControlMinimumSizeChanged(uiWindowsControl(b)); -} - -static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) -{ - uiFontButton *b = uiFontButton(c); - HWND parent; - - if (code != BN_CLICKED) - return FALSE; - - parent = parentToplevel(b->hwnd); - if (showFontDialog(parent, &(b->params))) { - updateFontButtonLabel(b); - (*(b->onChanged))(b, b->onChangedData); - } - - *lResult = 0; - return TRUE; -} - -uiWindowsControlAllDefaultsExceptDestroy(uiFontButton) - -// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define buttonHeight 14 - -static void uiFontButtonMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiFontButton *b = uiFontButton(c); - SIZE size; - uiWindowsSizing sizing; - int y; - - // try the comctl32 version 6 way - size.cx = 0; // explicitly ask for ideal size - size.cy = 0; - if (SendMessageW(b->hwnd, BCM_GETIDEALSIZE, 0, (LPARAM) (&size)) != FALSE) { - *width = size.cx; - *height = size.cy; - return; - } - - // that didn't work; fall back to using Microsoft's metrics - // Microsoft says to use a fixed width for all buttons; this isn't good enough - // use the text width instead, with some edge padding - *width = uiWindowsWindowTextWidth(b->hwnd) + (2 * GetSystemMetrics(SM_CXEDGE)); - y = buttonHeight; - uiWindowsGetSizing(b->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &y); - *height = y; -} - -static void defaultOnChanged(uiFontButton *b, void *data) -{ - // do nothing -} - -uiDrawTextFont *uiFontButtonFont(uiFontButton *b) -{ - // we don't own b->params.font; we have to add a reference - // we don't own b->params.familyName either; we have to copy it - return mkTextFont(b->params.font, TRUE, b->params.familyName, TRUE, b->params.size); -} - -void uiFontButtonOnChanged(uiFontButton *b, void (*f)(uiFontButton *, void *), void *data) -{ - b->onChanged = f; - b->onChangedData = data; -} - -uiFontButton *uiNewFontButton(void) -{ - uiFontButton *b; - - uiWindowsNewControl(uiFontButton, b); - - b->hwnd = uiWindowsEnsureCreateControlHWND(0, - L"button", L"you should not be seeing this", - BS_PUSHBUTTON | WS_TABSTOP, - hInstance, NULL, - TRUE); - - loadInitialFontDialogParams(&(b->params)); - - uiWindowsRegisterWM_COMMANDHandler(b->hwnd, onWM_COMMAND, uiControl(b)); - uiFontButtonOnChanged(b, defaultOnChanged, NULL); - - updateFontButtonLabel(b); - - return b; -} diff --git a/deps/libui/windows/fontdialog.cpp b/deps/libui/windows/fontdialog.cpp deleted file mode 100644 index 603a17dbd2..0000000000 --- a/deps/libui/windows/fontdialog.cpp +++ /dev/null @@ -1,686 +0,0 @@ -// 14 april 2016 -#include "uipriv_windows.hpp" - -// TODOs -// - quote the Choose Font sample here for reference -// - the Choose Font sample defaults to Regular/Italic/Bold/Bold Italic in some case (no styles?); do we? find out what the case is -// - do we set initial family and style topmost as well? -// - this should probably just handle IDWriteFonts - -struct fontDialog { - HWND hwnd; - HWND familyCombobox; - HWND styleCombobox; - HWND sizeCombobox; - - struct fontDialogParams *params; - - fontCollection *fc; - - RECT sampleRect; - HWND sampleBox; - - // we store the current selections in case an invalid string is typed in (partial or nonexistent or invalid number) - // on OK, these are what are read - LRESULT curFamily; - LRESULT curStyle; - double curSize; - - // these are finding the style that's closest to the previous one (these fields) when changing a font - DWRITE_FONT_WEIGHT weight; - DWRITE_FONT_STYLE style; - DWRITE_FONT_STRETCH stretch; -}; - -static LRESULT cbAddString(HWND cb, const WCHAR *str) -{ - LRESULT lr; - - lr = SendMessageW(cb, CB_ADDSTRING, 0, (LPARAM) str); - if (lr == (LRESULT) CB_ERR || lr == (LRESULT) CB_ERRSPACE) - logLastError(L"error adding item to combobox"); - return lr; -} - -static LRESULT cbInsertString(HWND cb, const WCHAR *str, WPARAM pos) -{ - LRESULT lr; - - lr = SendMessageW(cb, CB_INSERTSTRING, pos, (LPARAM) str); - if (lr != (LRESULT) pos) - logLastError(L"error inserting item to combobox"); - return lr; -} - -static LRESULT cbGetItemData(HWND cb, WPARAM item) -{ - LRESULT data; - - data = SendMessageW(cb, CB_GETITEMDATA, item, 0); - if (data == (LRESULT) CB_ERR) - logLastError(L"error getting combobox item data for font dialog"); - return data; -} - -static void cbSetItemData(HWND cb, WPARAM item, LPARAM data) -{ - if (SendMessageW(cb, CB_SETITEMDATA, item, data) == (LRESULT) CB_ERR) - logLastError(L"error setting combobox item data"); -} - -static BOOL cbGetCurSel(HWND cb, LRESULT *sel) -{ - LRESULT n; - - n = SendMessageW(cb, CB_GETCURSEL, 0, 0); - if (n == (LRESULT) CB_ERR) - return FALSE; - if (sel != NULL) - *sel = n; - return TRUE; -} - -static void cbSetCurSel(HWND cb, WPARAM item) -{ - if (SendMessageW(cb, CB_SETCURSEL, item, 0) != (LRESULT) item) - logLastError(L"error selecting combobox item"); -} - -static LRESULT cbGetCount(HWND cb) -{ - LRESULT n; - - n = SendMessageW(cb, CB_GETCOUNT, 0, 0); - if (n == (LRESULT) CB_ERR) - logLastError(L"error getting combobox item count"); - return n; -} - -static void cbWipeAndReleaseData(HWND cb) -{ - IUnknown *obj; - LRESULT i, n; - - n = cbGetCount(cb); - for (i = 0; i < n; i++) { - obj = (IUnknown *) cbGetItemData(cb, (WPARAM) i); - obj->Release(); - } - SendMessageW(cb, CB_RESETCONTENT, 0, 0); -} - -static WCHAR *cbGetItemText(HWND cb, WPARAM item) -{ - LRESULT len; - WCHAR *text; - - // note: neither message includes the terminating L'\0' - len = SendMessageW(cb, CB_GETLBTEXTLEN, item, 0); - if (len == (LRESULT) CB_ERR) - logLastError(L"error getting item text length from combobox"); - text = (WCHAR *) uiAlloc((len + 1) * sizeof (WCHAR), "WCHAR[]"); - if (SendMessageW(cb, CB_GETLBTEXT, item, (LPARAM) text) != len) - logLastError(L"error getting item text from combobox"); - return text; -} - -static BOOL cbTypeToSelect(HWND cb, LRESULT *posOut, BOOL restoreAfter) -{ - WCHAR *text; - LRESULT pos; - DWORD selStart, selEnd; - - // start by saving the current selection as setting the item will change the selection - SendMessageW(cb, CB_GETEDITSEL, (WPARAM) (&selStart), (LPARAM) (&selEnd)); - text = windowText(cb); - pos = SendMessageW(cb, CB_FINDSTRINGEXACT, (WPARAM) (-1), (LPARAM) text); - if (pos == (LRESULT) CB_ERR) { - uiFree(text); - return FALSE; - } - cbSetCurSel(cb, (WPARAM) pos); - if (posOut != NULL) - *posOut = pos; - if (restoreAfter) - if (SendMessageW(cb, WM_SETTEXT, 0, (LPARAM) text) != (LRESULT) TRUE) - logLastError(L"error restoring old combobox text"); - uiFree(text); - // and restore the selection like above - // TODO isn't there a 32-bit version of this - if (SendMessageW(cb, CB_SETEDITSEL, 0, MAKELPARAM(selStart, selEnd)) != (LRESULT) TRUE) - logLastError(L"error restoring combobox edit selection"); - return TRUE; -} - -static void wipeStylesBox(struct fontDialog *f) -{ - cbWipeAndReleaseData(f->styleCombobox); -} - -static WCHAR *fontStyleName(struct fontCollection *fc, IDWriteFont *font) -{ - IDWriteLocalizedStrings *str; - WCHAR *wstr; - HRESULT hr; - - hr = font->GetFaceNames(&str); - if (hr != S_OK) - logHRESULT(L"error getting font style name for font dialog", hr); - wstr = fontCollectionCorrectString(fc, str); - str->Release(); - return wstr; -} - -static void queueRedrawSampleText(struct fontDialog *f) -{ - // TODO TRUE? - invalidateRect(f->sampleBox, NULL, TRUE); -} - -static void styleChanged(struct fontDialog *f) -{ - LRESULT pos; - BOOL selected; - IDWriteFont *font; - - selected = cbGetCurSel(f->styleCombobox, &pos); - if (!selected) // on deselect, do nothing - return; - f->curStyle = pos; - - font = (IDWriteFont *) cbGetItemData(f->styleCombobox, (WPARAM) (f->curStyle)); - // these are for the nearest match when changing the family; see below - f->weight = font->GetWeight(); - f->style = font->GetStyle(); - f->stretch = font->GetStretch(); - - queueRedrawSampleText(f); -} - -static void styleEdited(struct fontDialog *f) -{ - if (cbTypeToSelect(f->styleCombobox, &(f->curStyle), FALSE)) - styleChanged(f); -} - -static void familyChanged(struct fontDialog *f) -{ - LRESULT pos; - BOOL selected; - IDWriteFontFamily *family; - IDWriteFont *font, *matchFont; - DWRITE_FONT_WEIGHT weight; - DWRITE_FONT_STYLE style; - DWRITE_FONT_STRETCH stretch; - UINT32 i, n; - UINT32 matching; - WCHAR *label; - HRESULT hr; - - selected = cbGetCurSel(f->familyCombobox, &pos); - if (!selected) // on deselect, do nothing - return; - f->curFamily = pos; - - family = (IDWriteFontFamily *) cbGetItemData(f->familyCombobox, (WPARAM) (f->curFamily)); - - // for the nearest style match - // when we select a new family, we want the nearest style to the previously selected one to be chosen - // this is how the Choose Font sample does it - hr = family->GetFirstMatchingFont( - f->weight, - f->stretch, - f->style, - &matchFont); - if (hr != S_OK) - logHRESULT(L"error finding first matching font to previous style in font dialog", hr); - // we can't just compare pointers; a "newly created" object comes out - // the Choose Font sample appears to do this instead - weight = matchFont->GetWeight(); - style = matchFont->GetStyle(); - stretch = matchFont->GetStretch(); - matchFont->Release(); - - // TODO test mutliple streteches; all the fonts I have have only one stretch value? - wipeStylesBox(f); - n = family->GetFontCount(); - matching = 0; // a safe/suitable default just in case - for (i = 0; i < n; i++) { - hr = family->GetFont(i, &font); - if (hr != S_OK) - logHRESULT(L"error getting font for filling styles box", hr); - label = fontStyleName(f->fc, font); - pos = cbAddString(f->styleCombobox, label); - uiFree(label); - cbSetItemData(f->styleCombobox, (WPARAM) pos, (LPARAM) font); - if (font->GetWeight() == weight && - font->GetStyle() == style && - font->GetStretch() == stretch) - matching = i; - } - - // and now, load the match - cbSetCurSel(f->styleCombobox, (WPARAM) matching); - styleChanged(f); -} - -// TODO search language variants like the sample does -static void familyEdited(struct fontDialog *f) -{ - if (cbTypeToSelect(f->familyCombobox, &(f->curFamily), FALSE)) - familyChanged(f); -} - -static const struct { - const WCHAR *text; - double value; -} defaultSizes[] = { - { L"8", 8 }, - { L"9", 9 }, - { L"10", 10 }, - { L"11", 11 }, - { L"12", 12 }, - { L"14", 14 }, - { L"16", 16 }, - { L"18", 18 }, - { L"20", 20 }, - { L"22", 22 }, - { L"24", 24 }, - { L"26", 26 }, - { L"28", 28 }, - { L"36", 36 }, - { L"48", 48 }, - { L"72", 72 }, - { NULL, 0 }, -}; - -static void sizeChanged(struct fontDialog *f) -{ - LRESULT pos; - BOOL selected; - - selected = cbGetCurSel(f->sizeCombobox, &pos); - if (!selected) // on deselect, do nothing - return; - f->curSize = defaultSizes[pos].value; - queueRedrawSampleText(f); -} - -static void sizeEdited(struct fontDialog *f) -{ - WCHAR *wsize; - double size; - - // handle type-to-selection - if (cbTypeToSelect(f->sizeCombobox, NULL, FALSE)) { - sizeChanged(f); - return; - } - // selection not chosen, try to parse the typing - wsize = windowText(f->sizeCombobox); - // this is what the Choose Font dialog does; it swallows errors while the real ChooseFont() is not lenient (and only checks on OK) - size = wcstod(wsize, NULL); - if (size <= 0) // don't change on invalid size - return; - f->curSize = size; - queueRedrawSampleText(f); -} - -static void fontDialogDrawSampleText(struct fontDialog *f, ID2D1RenderTarget *rt) -{ - D2D1_COLOR_F color; - D2D1_BRUSH_PROPERTIES props; - ID2D1SolidColorBrush *black; - IDWriteFont *font; - IDWriteLocalizedStrings *sampleStrings; - BOOL exists; - WCHAR *sample; - WCHAR *family; - IDWriteTextFormat *format; - D2D1_RECT_F rect; - HRESULT hr; - - color.r = 0.0; - color.g = 0.0; - color.b = 0.0; - color.a = 1.0; - ZeroMemory(&props, sizeof (D2D1_BRUSH_PROPERTIES)); - props.opacity = 1.0; - // identity matrix - props.transform._11 = 1; - props.transform._22 = 1; - hr = rt->CreateSolidColorBrush( - &color, - &props, - &black); - if (hr != S_OK) - logHRESULT(L"error creating solid brush", hr); - - font = (IDWriteFont *) cbGetItemData(f->styleCombobox, (WPARAM) f->curStyle); - hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_SAMPLE_TEXT, &sampleStrings, &exists); - if (hr != S_OK) - exists = FALSE; - if (exists) { - sample = fontCollectionCorrectString(f->fc, sampleStrings); - sampleStrings->Release(); - } else - sample = L"The quick brown fox jumps over the lazy dog."; - - // DirectWrite doesn't allow creating a text format from a font; we need to get this ourselves - family = cbGetItemText(f->familyCombobox, f->curFamily); - hr = dwfactory->CreateTextFormat(family, - NULL, - font->GetWeight(), - font->GetStyle(), - font->GetStretch(), - // typographic points are 1/72 inch; this parameter is 1/96 inch - // fortunately Microsoft does this too, in https://msdn.microsoft.com/en-us/library/windows/desktop/dd371554%28v=vs.85%29.aspx - f->curSize * (96.0 / 72.0), - // see http://stackoverflow.com/questions/28397971/idwritefactorycreatetextformat-failing and https://msdn.microsoft.com/en-us/library/windows/desktop/dd368203.aspx - // TODO use the current locale again? - L"", - &format); - if (hr != S_OK) - logHRESULT(L"error creating IDWriteTextFormat", hr); - uiFree(family); - - rect.left = 0; - rect.top = 0; - rect.right = realGetSize(rt).width; - rect.bottom = realGetSize(rt).height; - rt->DrawText(sample, wcslen(sample), - format, - &rect, - black, - // TODO really? - D2D1_DRAW_TEXT_OPTIONS_NONE, - DWRITE_MEASURING_MODE_NATURAL); - - format->Release(); - if (exists) - uiFree(sample); - black->Release(); -} - -static LRESULT CALLBACK fontDialogSampleSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) -{ - ID2D1RenderTarget *rt; - struct fontDialog *f; - - switch (uMsg) { - case msgD2DScratchPaint: - rt = (ID2D1RenderTarget *) lParam; - f = (struct fontDialog *) dwRefData; - fontDialogDrawSampleText(f, rt); - return 0; - case WM_NCDESTROY: - if (RemoveWindowSubclass(hwnd, fontDialogSampleSubProc, uIdSubclass) == FALSE) - logLastError(L"error removing font dialog sample text subclass"); - break; - } - return DefSubclassProc(hwnd, uMsg, wParam, lParam); -} - -static void setupInitialFontDialogState(struct fontDialog *f) -{ - WCHAR wsize[512]; // this should be way more than enough - LRESULT pos; - - // first let's load the size - // the real font dialog: - // - if the chosen font size is in the list, it selects that item AND makes it topmost - // - if the chosen font size is not in the list, don't bother - // we'll simulate it by setting the text to a %f representation, then pretending as if it was entered - // TODO is 512 the correct number to pass to _snwprintf()? - // TODO will this revert to scientific notation? - _snwprintf(wsize, 512, L"%g", f->params->size); - // TODO make this a setWindowText() - if (SendMessageW(f->sizeCombobox, WM_SETTEXT, 0, (LPARAM) wsize) != (LRESULT) TRUE) - logLastError(L"error setting size combobox to initial font size"); - sizeEdited(f); - if (cbGetCurSel(f->sizeCombobox, &pos)) - if (SendMessageW(f->sizeCombobox, CB_SETTOPINDEX, (WPARAM) pos, 0) != 0) - logLastError(L"error making chosen size topmost in the size combobox"); - - // now we set the family and style - // we do this by first setting the previous style attributes, then simulating a font entered - f->weight = f->params->font->GetWeight(); - f->style = f->params->font->GetStyle(); - f->stretch = f->params->font->GetStretch(); - if (SendMessageW(f->familyCombobox, WM_SETTEXT, 0, (LPARAM) (f->params->familyName)) != (LRESULT) TRUE) - logLastError(L"error setting family combobox to initial font family"); - familyEdited(f); -} - -static struct fontDialog *beginFontDialog(HWND hwnd, LPARAM lParam) -{ - struct fontDialog *f; - UINT32 i, nFamilies; - IDWriteFontFamily *family; - WCHAR *wname; - LRESULT pos; - HWND samplePlacement; - HRESULT hr; - - f = uiNew(struct fontDialog); - f->hwnd = hwnd; - f->params = (struct fontDialogParams *) lParam; - - f->familyCombobox = getDlgItem(f->hwnd, rcFontFamilyCombobox); - f->styleCombobox = getDlgItem(f->hwnd, rcFontStyleCombobox); - f->sizeCombobox = getDlgItem(f->hwnd, rcFontSizeCombobox); - - f->fc = loadFontCollection(); - nFamilies = f->fc->fonts->GetFontFamilyCount(); - for (i = 0; i < nFamilies; i++) { - hr = f->fc->fonts->GetFontFamily(i, &family); - if (hr != S_OK) - logHRESULT(L"error getting font family", hr); - wname = fontCollectionFamilyName(f->fc, family); - pos = cbAddString(f->familyCombobox, wname); - uiFree(wname); - cbSetItemData(f->familyCombobox, (WPARAM) pos, (LPARAM) family); - } - - for (i = 0; defaultSizes[i].text != NULL; i++) - cbInsertString(f->sizeCombobox, defaultSizes[i].text, (WPARAM) i); - - samplePlacement = getDlgItem(f->hwnd, rcFontSamplePlacement); - uiWindowsEnsureGetWindowRect(samplePlacement, &(f->sampleRect)); - mapWindowRect(NULL, f->hwnd, &(f->sampleRect)); - uiWindowsEnsureDestroyWindow(samplePlacement); - f->sampleBox = newD2DScratch(f->hwnd, &(f->sampleRect), (HMENU) rcFontSamplePlacement, fontDialogSampleSubProc, (DWORD_PTR) f); - - setupInitialFontDialogState(f); - return f; -} - -static void endFontDialog(struct fontDialog *f, INT_PTR code) -{ - wipeStylesBox(f); - cbWipeAndReleaseData(f->familyCombobox); - fontCollectionFree(f->fc); - if (EndDialog(f->hwnd, code) == 0) - logLastError(L"error ending font dialog"); - uiFree(f); -} - -static INT_PTR tryFinishDialog(struct fontDialog *f, WPARAM wParam) -{ - IDWriteFontFamily *family; - - // cancelling - if (LOWORD(wParam) != IDOK) { - endFontDialog(f, 1); - return TRUE; - } - - // OK - destroyFontDialogParams(f->params); - f->params->font = (IDWriteFont *) cbGetItemData(f->styleCombobox, f->curStyle); - // we need to save font from being destroyed with the combobox - f->params->font->AddRef(); - f->params->size = f->curSize; - family = (IDWriteFontFamily *) cbGetItemData(f->familyCombobox, f->curFamily); - f->params->familyName = fontCollectionFamilyName(f->fc, family); - f->params->styleName = fontStyleName(f->fc, f->params->font); - endFontDialog(f, 2); - return TRUE; -} - -static INT_PTR CALLBACK fontDialogDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - struct fontDialog *f; - - f = (struct fontDialog *) GetWindowLongPtrW(hwnd, DWLP_USER); - if (f == NULL) { - if (uMsg == WM_INITDIALOG) { - f = beginFontDialog(hwnd, lParam); - SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR) f); - return TRUE; - } - return FALSE; - } - - switch (uMsg) { - case WM_COMMAND: - SetWindowLongPtrW(f->hwnd, DWLP_MSGRESULT, 0); // just in case - switch (LOWORD(wParam)) { - case IDOK: - case IDCANCEL: - if (HIWORD(wParam) != BN_CLICKED) - return FALSE; - return tryFinishDialog(f, wParam); - case rcFontFamilyCombobox: - if (HIWORD(wParam) == CBN_SELCHANGE) { - familyChanged(f); - return TRUE; - } - if (HIWORD(wParam) == CBN_EDITCHANGE) { - familyEdited(f); - return TRUE; - } - return FALSE; - case rcFontStyleCombobox: - if (HIWORD(wParam) == CBN_SELCHANGE) { - styleChanged(f); - return TRUE; - } - if (HIWORD(wParam) == CBN_EDITCHANGE) { - styleEdited(f); - return TRUE; - } - return FALSE; - case rcFontSizeCombobox: - if (HIWORD(wParam) == CBN_SELCHANGE) { - sizeChanged(f); - return TRUE; - } - if (HIWORD(wParam) == CBN_EDITCHANGE) { - sizeEdited(f); - return TRUE; - } - return FALSE; - } - return FALSE; - } - return FALSE; -} - -BOOL showFontDialog(HWND parent, struct fontDialogParams *params) -{ - switch (DialogBoxParamW(hInstance, MAKEINTRESOURCE(rcFontDialog), parent, fontDialogDlgProc, (LPARAM) params)) { - case 1: // cancel - return FALSE; - case 2: // ok - // make the compiler happy by putting the return after the switch - break; - default: - logLastError(L"error running font dialog"); - } - return TRUE; -} - -static IDWriteFontFamily *tryFindFamily(IDWriteFontCollection *fc, const WCHAR *name) -{ - UINT32 index; - BOOL exists; - IDWriteFontFamily *family; - HRESULT hr; - - hr = fc->FindFamilyName(name, &index, &exists); - if (hr != S_OK) - logHRESULT(L"error finding font family for font dialog", hr); - if (!exists) - return NULL; - hr = fc->GetFontFamily(index, &family); - if (hr != S_OK) - logHRESULT(L"error extracting found font family for font dialog", hr); - return family; -} - -void loadInitialFontDialogParams(struct fontDialogParams *params) -{ - struct fontCollection *fc; - IDWriteFontFamily *family; - IDWriteFont *font; - HRESULT hr; - - // Our preferred font is Arial 10 Regular. - // 10 comes from the official font dialog. - // Arial Regular is a reasonable, if arbitrary, default; it's similar to the defaults on other systems. - // If Arial isn't found, we'll use Helvetica and then MS Sans Serif as fallbacks, and if not, we'll just grab the first font family in the collection. - - // We need the correct localized name for Regular (and possibly Arial too? let's say yes to be safe), so let's grab the strings from DirectWrite instead of hardcoding them. - fc = loadFontCollection(); - family = tryFindFamily(fc->fonts, L"Arial"); - if (family == NULL) { - family = tryFindFamily(fc->fonts, L"Helvetica"); - if (family == NULL) { - family = tryFindFamily(fc->fonts, L"MS Sans Serif"); - if (family == NULL) { - hr = fc->fonts->GetFontFamily(0, &family); - if (hr != S_OK) - logHRESULT(L"error getting first font out of font collection (worst case scenario)", hr); - } - } - } - - // next part is simple: just get the closest match to regular - hr = family->GetFirstMatchingFont( - DWRITE_FONT_WEIGHT_NORMAL, - DWRITE_FONT_STRETCH_NORMAL, - DWRITE_FONT_STYLE_NORMAL, - &font); - if (hr != S_OK) - logHRESULT(L"error getting Regular font from Arial", hr); - - params->font = font; - params->size = 10; - params->familyName = fontCollectionFamilyName(fc, family); - params->styleName = fontStyleName(fc, font); - - // don't release font; we still need it - family->Release(); - fontCollectionFree(fc); -} - -void destroyFontDialogParams(struct fontDialogParams *params) -{ - params->font->Release(); - uiFree(params->familyName); - uiFree(params->styleName); -} - -WCHAR *fontDialogParamsToString(struct fontDialogParams *params) -{ - WCHAR *text; - - // TODO dynamically allocate - text = (WCHAR *) uiAlloc(512 * sizeof (WCHAR), "WCHAR[]"); - _snwprintf(text, 512, L"%s %s %g", - params->familyName, - params->styleName, - params->size); - return text; -} diff --git a/deps/libui/windows/form.cpp b/deps/libui/windows/form.cpp deleted file mode 100644 index febcc693bc..0000000000 --- a/deps/libui/windows/form.cpp +++ /dev/null @@ -1,319 +0,0 @@ -// 8 june 2016 -#include "uipriv_windows.hpp" - -struct formChild { - uiControl *c; - HWND label; - int stretchy; - int height; -}; - -struct uiForm { - uiWindowsControl c; - HWND hwnd; - std::vector *controls; - int padded; -}; - -static void formPadding(uiForm *f, int *xpadding, int *ypadding) -{ - uiWindowsSizing sizing; - - *xpadding = 0; - *ypadding = 0; - if (f->padded) { - uiWindowsGetSizing(f->hwnd, &sizing); - uiWindowsSizingStandardPadding(&sizing, xpadding, ypadding); - } -} - -// via http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define labelHeight 8 -#define labelYOffset 3 - -static void formRelayout(uiForm *f) -{ - RECT r; - int x, y, width, height; - int xpadding, ypadding; - int nStretchy; - int labelwid, stretchyht; - int thiswid; - int i; - int minimumWidth, minimumHeight; - uiWindowsSizing sizing; - int labelht, labelyoff; - int nVisible; - - if (f->controls->size() == 0) - return; - - uiWindowsEnsureGetClientRect(f->hwnd, &r); - x = r.left; - y = r.top; - width = r.right - r.left; - height = r.bottom - r.top; - - // 0) get this Form's padding - formPadding(f, &xpadding, &ypadding); - - // 1) get width of labels and height of non-stretchy controls - // this will tell us how much space will be left for controls - labelwid = 0; - stretchyht = height; - nStretchy = 0; - nVisible = 0; - for (struct formChild &fc : *(f->controls)) { - if (!uiControlVisible(fc.c)) { - ShowWindow(fc.label, SW_HIDE); - continue; - } - ShowWindow(fc.label, SW_SHOW); - nVisible++; - thiswid = uiWindowsWindowTextWidth(fc.label); - if (labelwid < thiswid) - labelwid = thiswid; - if (fc.stretchy) { - nStretchy++; - continue; - } - uiWindowsControlMinimumSize(uiWindowsControl(fc.c), &minimumWidth, &minimumHeight); - fc.height = minimumHeight; - stretchyht -= minimumHeight; - } - if (nVisible == 0) // nothing to do - return; - - // 2) inset the available rect by the needed padding - width -= xpadding; - height -= (nVisible - 1) * ypadding; - stretchyht -= (nVisible - 1) * ypadding; - - // 3) now get the width of controls and the height of stretchy controls - width -= labelwid; - if (nStretchy != 0) { - stretchyht /= nStretchy; - for (struct formChild &fc : *(f->controls)) { - if (!uiControlVisible(fc.c)) - continue; - if (fc.stretchy) - fc.height = stretchyht; - } - } - - // 4) get the y offset - labelyoff = labelYOffset; - uiWindowsGetSizing(f->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &labelyoff); - - // 5) now we can position controls - // first, make relative to the top-left corner of the container - // also prefer left alignment on Windows - x = labelwid + xpadding; - y = 0; - for (const struct formChild &fc : *(f->controls)) { - if (!uiControlVisible(fc.c)) - continue; - labelht = labelHeight; - uiWindowsGetSizing(f->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &labelht); - uiWindowsEnsureMoveWindowDuringResize(fc.label, 0, y + labelyoff - sizing.InternalLeading, labelwid, labelht); - uiWindowsEnsureMoveWindowDuringResize((HWND) uiControlHandle(fc.c), x, y, width, fc.height); - y += fc.height + ypadding; - } -} - -static void uiFormDestroy(uiControl *c) -{ - uiForm *f = uiForm(c); - - for (const struct formChild &fc : *(f->controls)) { - uiControlSetParent(fc.c, NULL); - uiControlDestroy(fc.c); - uiWindowsEnsureDestroyWindow(fc.label); - } - delete f->controls; - uiWindowsEnsureDestroyWindow(f->hwnd); - uiFreeControl(uiControl(f)); -} - -uiWindowsControlDefaultHandle(uiForm) -uiWindowsControlDefaultParent(uiForm) -uiWindowsControlDefaultSetParent(uiForm) -uiWindowsControlDefaultToplevel(uiForm) -uiWindowsControlDefaultVisible(uiForm) -uiWindowsControlDefaultShow(uiForm) -uiWindowsControlDefaultHide(uiForm) -uiWindowsControlDefaultEnabled(uiForm) -uiWindowsControlDefaultEnable(uiForm) -uiWindowsControlDefaultDisable(uiForm) - -static void uiFormSyncEnableState(uiWindowsControl *c, int enabled) -{ - uiForm *f = uiForm(c); - - if (uiWindowsShouldStopSyncEnableState(uiWindowsControl(f), enabled)) - return; - for (const struct formChild &fc : *(f->controls)) - uiWindowsControlSyncEnableState(uiWindowsControl(fc.c), enabled); -} - -uiWindowsControlDefaultSetParentHWND(uiForm) - -static void uiFormMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiForm *f = uiForm(c); - int xpadding, ypadding; - int nStretchy; - // these two contain the largest minimum width and height of all stretchy controls in the form - // all stretchy controls will use this value to determine the final minimum size - int maxLabelWidth, maxControlWidth; - int maxStretchyHeight; - int labelwid; - int i; - int minimumWidth, minimumHeight; - int nVisible; - uiWindowsSizing sizing; - - *width = 0; - *height = 0; - if (f->controls->size() == 0) - return; - - // 0) get this Form's padding - formPadding(f, &xpadding, &ypadding); - - // 1) determine the longest width of all controls and labels; add in the height of non-stretchy controls and get (but not add in) the largest heights of stretchy controls - // we still add in like direction of stretchy controls - nStretchy = 0; - maxLabelWidth = 0; - maxControlWidth = 0; - maxStretchyHeight = 0; - nVisible = 0; - for (const struct formChild &fc : *(f->controls)) { - if (!uiControlVisible(fc.c)) - continue; - nVisible++; - labelwid = uiWindowsWindowTextWidth(fc.label); - if (maxLabelWidth < labelwid) - maxLabelWidth = labelwid; - uiWindowsControlMinimumSize(uiWindowsControl(fc.c), &minimumWidth, &minimumHeight); - if (fc.stretchy) { - nStretchy++; - if (maxStretchyHeight < minimumHeight) - maxStretchyHeight = minimumHeight; - } - if (maxControlWidth < minimumWidth) - maxControlWidth = minimumWidth; - if (!fc.stretchy) - *height += minimumHeight; - } - if (nVisible == 0) // nothing to show; return 0x0 - return; - *width += maxLabelWidth + maxControlWidth; - - // 2) outset the desired rect with the needed padding - *width += xpadding; - *height += (nVisible - 1) * ypadding; - - // 3) and now we can add in stretchy controls - *height += nStretchy * maxStretchyHeight; -} - -static void uiFormMinimumSizeChanged(uiWindowsControl *c) -{ - uiForm *f = uiForm(c); - - if (uiWindowsControlTooSmall(uiWindowsControl(f))) { - uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl(f)); - return; - } - formRelayout(f); -} - -uiWindowsControlDefaultLayoutRect(uiForm) -uiWindowsControlDefaultAssignControlIDZOrder(uiForm) - -static void uiFormChildVisibilityChanged(uiWindowsControl *c) -{ - // TODO eliminate the redundancy - uiWindowsControlMinimumSizeChanged(c); -} - -static void formArrangeChildren(uiForm *f) -{ - LONG_PTR controlID; - HWND insertAfter; - int i; - - controlID = 100; - insertAfter = NULL; - for (const struct formChild &fc : *(f->controls)) { - // TODO assign label ID and z-order - uiWindowsControlAssignControlIDZOrder(uiWindowsControl(fc.c), &controlID, &insertAfter); - } -} - -void uiFormAppend(uiForm *f, const char *label, uiControl *c, int stretchy) -{ - struct formChild fc; - WCHAR *wlabel; - - fc.c = c; - wlabel = toUTF16(label); - fc.label = uiWindowsEnsureCreateControlHWND(0, - L"STATIC", wlabel, - SS_LEFT | SS_NOPREFIX, - hInstance, NULL, - TRUE); - uiFree(wlabel); - uiWindowsEnsureSetParentHWND(fc.label, f->hwnd); - fc.stretchy = stretchy; - uiControlSetParent(fc.c, uiControl(f)); - uiWindowsControlSetParentHWND(uiWindowsControl(fc.c), f->hwnd); - f->controls->push_back(fc); - formArrangeChildren(f); - uiWindowsControlMinimumSizeChanged(uiWindowsControl(f)); -} - -void uiFormDelete(uiForm *f, int index) -{ - struct formChild fc; - - fc = (*(f->controls))[index]; - uiControlSetParent(fc.c, NULL); - uiWindowsControlSetParentHWND(uiWindowsControl(fc.c), NULL); - uiWindowsEnsureDestroyWindow(fc.label); - f->controls->erase(f->controls->begin() + index); - formArrangeChildren(f); - uiWindowsControlMinimumSizeChanged(uiWindowsControl(f)); -} - -int uiFormPadded(uiForm *f) -{ - return f->padded; -} - -void uiFormSetPadded(uiForm *f, int padded) -{ - f->padded = padded; - uiWindowsControlMinimumSizeChanged(uiWindowsControl(f)); -} - -static void onResize(uiWindowsControl *c) -{ - formRelayout(uiForm(c)); -} - -uiForm *uiNewForm(void) -{ - uiForm *f; - - uiWindowsNewControl(uiForm, f); - - f->hwnd = uiWindowsMakeContainer(uiWindowsControl(f), onResize); - - f->controls = new std::vector; - - return f; -} diff --git a/deps/libui/windows/graphemes.cpp b/deps/libui/windows/graphemes.cpp deleted file mode 100644 index 355e403764..0000000000 --- a/deps/libui/windows/graphemes.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// 25 may 2016 -#include "uipriv_windows.hpp" - -// We could use CharNext() to generate grapheme cluster boundaries, but it doesn't handle surrogate pairs properly (see http://archives.miloush.net/michkap/archive/2008/12/16/9223301.html). -// So let's use Uniscribe (see http://archives.miloush.net/michkap/archive/2005/01/14/352802.html) -// See also http://www.catch22.net/tuts/uniscribe-mysteries and http://www.catch22.net/tuts/keyboard-navigation for more details. - -static HRESULT itemize(WCHAR *msg, size_t len, SCRIPT_ITEM **out, int *outn) -{ - SCRIPT_CONTROL sc; - SCRIPT_STATE ss; - SCRIPT_ITEM *items; - size_t maxItems; - int n; - HRESULT hr; - - // make sure these are zero-initialized to avoid mangling the text - ZeroMemory(&sc, sizeof (SCRIPT_CONTROL)); - ZeroMemory(&ss, sizeof (SCRIPT_STATE)); - - maxItems = len + 2; - for (;;) { - items = new SCRIPT_ITEM[maxItems]; - hr = ScriptItemize(msg, len, - maxItems, - &sc, &ss, - items, &n); - if (hr == S_OK) - break; - // otherwise either an error or not enough room - delete[] items; - if (hr != E_OUTOFMEMORY) - return hr; - maxItems *= 2; // add some more and try again - } - - *out = items; - *outn = n; - return S_OK; -} - -size_t *graphemes(WCHAR *msg) -{ - size_t len; - SCRIPT_ITEM *items; - int i, n; - size_t *out; - size_t *op; - SCRIPT_LOGATTR *logattr; - int j, nn; - HRESULT hr; - - len = wcslen(msg); - hr = itemize(msg, len, &items, &n); - if (hr != S_OK) - logHRESULT(L"error itemizing string for finding grapheme cluster boundaries", hr); - - // should be enough; 2 more just to be safe - out = (size_t *) uiAlloc((len + 2) * sizeof (size_t), "size_t[]"); - op = out; - - // note that there are actually n + 1 elements in items - for (i = 0; i < n; i++) { - nn = items[i + 1].iCharPos - items[i].iCharPos; - logattr = new SCRIPT_LOGATTR[nn]; - hr = ScriptBreak(msg + items[i].iCharPos, nn, - &(items[i].a), logattr); - if (hr != S_OK) - logHRESULT(L"error breaking string for finding grapheme cluster boundaries", hr); - for (j = 0; j < nn; j++) - if (logattr[j].fCharStop != 0) - *op++ = items[i].iCharPos + j; - delete[] logattr; - } - // and handle the last item for the end of the string - *op++ = items[i].iCharPos; - - delete[] items; - return out; -} diff --git a/deps/libui/windows/grid.cpp b/deps/libui/windows/grid.cpp deleted file mode 100644 index c63cd1e4a8..0000000000 --- a/deps/libui/windows/grid.cpp +++ /dev/null @@ -1,658 +0,0 @@ -// 10 june 2016 -#include "uipriv_windows.hpp" - -// TODO compare with GTK+: -// - what happens if you call InsertAt() twice? -// - what happens if you call Append() twice? - -// TODOs -// - the Assorted page has clipping and repositioning issues - -struct gridChild { - uiControl *c; - int left; - int top; - int xspan; - int yspan; - int hexpand; - uiAlign halign; - int vexpand; - uiAlign valign; - - // have these here so they don't need to be reallocated each relayout - int finalx, finaly; - int finalwidth, finalheight; - int minwidth, minheight; -}; - -struct uiGrid { - uiWindowsControl c; - HWND hwnd; - std::vector *children; - std::map *indexof; - int padded; - - int xmin, ymin; - int xmax, ymax; -}; - -static bool gridRecomputeMinMax(uiGrid *g) -{ - bool first = true; - - for (struct gridChild *gc : *(g->children)) { - // this is important; we want g->xmin/g->ymin to satisfy gridLayoutData::visibleRow()/visibleColumn() - if (!uiControlVisible(gc->c)) - continue; - if (first) { - g->xmin = gc->left; - g->ymin = gc->top; - g->xmax = gc->left + gc->xspan; - g->ymax = gc->top + gc->yspan; - first = false; - continue; - } - if (g->xmin > gc->left) - g->xmin = gc->left; - if (g->ymin > gc->top) - g->ymin = gc->top; - if (g->xmax < (gc->left + gc->xspan)) - g->xmax = gc->left + gc->xspan; - if (g->ymax < (gc->top + gc->yspan)) - g->ymax = gc->top + gc->yspan; - } - return first != false; -} - -#define xcount(g) ((g)->xmax - (g)->xmin) -#define ycount(g) ((g)->ymax - (g)->ymin) -#define toxindex(g, x) ((x) - (g)->xmin) -#define toyindex(g, y) ((y) - (g)->ymin) - -class gridLayoutData { - int ycount; -public: - int **gg; // topological map gg[y][x] = control index - int *colwidths; - int *rowheights; - bool *hexpand; - bool *vexpand; - int nVisibleRows; - int nVisibleColumns; - - bool noVisible; - - gridLayoutData(uiGrid *g) - { - size_t i; - int x, y; - - this->noVisible = gridRecomputeMinMax(g); - - this->gg = new int *[ycount(g)]; - for (y = 0; y < ycount(g); y++) { - this->gg[y] = new int[xcount(g)]; - for (x = 0; x < xcount(g); x++) - this->gg[y][x] = -1; - } - - for (i = 0; i < g->children->size(); i++) { - struct gridChild *gc; - - gc = (*(g->children))[i]; - if (!uiControlVisible(gc->c)) - continue; - for (y = gc->top; y < gc->top + gc->yspan; y++) - for (x = gc->left; x < gc->left + gc->xspan; x++) - this->gg[toyindex(g, y)][toxindex(g, x)] = i; - } - - this->colwidths = new int[xcount(g)]; - ZeroMemory(this->colwidths, xcount(g) * sizeof (int)); - this->rowheights = new int[ycount(g)]; - ZeroMemory(this->rowheights, ycount(g) * sizeof (int)); - this->hexpand = new bool[xcount(g)]; - ZeroMemory(this->hexpand, xcount(g) * sizeof (bool)); - this->vexpand = new bool[ycount(g)]; - ZeroMemory(this->vexpand, ycount(g) * sizeof (bool)); - - this->ycount = ycount(g); - - // if a row or column only contains emptys and spanning cells of a opposite-direction spannings, it is invisible and should not be considered for padding amount calculations - // note that the first row and column will always be visible because gridRecomputeMinMax() computed a smallest fitting rectangle - if (this->noVisible) - return; - this->nVisibleRows = 0; - for (y = 0; y < this->ycount; y++) - if (this->visibleRow(g, y)) - this->nVisibleRows++; - this->nVisibleColumns = 0; - for (x = 0; x < xcount(g); x++) - if (this->visibleColumn(g, x)) - this->nVisibleColumns++; - } - - ~gridLayoutData() - { - size_t y; - - delete[] this->hexpand; - delete[] this->vexpand; - delete[] this->colwidths; - delete[] this->rowheights; - for (y = 0; y < this->ycount; y++) - delete[] this->gg[y]; - delete[] this->gg; - } - - bool visibleRow(uiGrid *g, int y) - { - int x; - struct gridChild *gc; - - for (x = 0; x < xcount(g); x++) - if (this->gg[y][x] != -1) { - gc = (*(g->children))[this->gg[y][x]]; - if (gc->yspan == 1 || gc->top - g->ymin == y) - return true; - } - return false; - } - - bool visibleColumn(uiGrid *g, int x) - { - int y; - struct gridChild *gc; - - for (y = 0; y < this->ycount; y++) - if (this->gg[y][x] != -1) { - gc = (*(g->children))[this->gg[y][x]]; - if (gc->xspan == 1 || gc->left - g->xmin == x) - return true; - } - return false; - } -}; - -static void gridPadding(uiGrid *g, int *xpadding, int *ypadding) -{ - uiWindowsSizing sizing; - - *xpadding = 0; - *ypadding = 0; - if (g->padded) { - uiWindowsGetSizing(g->hwnd, &sizing); - uiWindowsSizingStandardPadding(&sizing, xpadding, ypadding); - } -} - -static void gridRelayout(uiGrid *g) -{ - RECT r; - int x, y, width, height; - gridLayoutData *ld; - int xpadding, ypadding; - int ix, iy; - int iwidth, iheight; - int i; - struct gridChild *gc; - int nhexpand, nvexpand; - - if (g->children->size() == 0) - return; // nothing to do - - uiWindowsEnsureGetClientRect(g->hwnd, &r); - x = r.left; - y = r.top; - width = r.right - r.left; - height = r.bottom - r.top; - - gridPadding(g, &xpadding, &ypadding); - ld = new gridLayoutData(g); - if (ld->noVisible) { // nothing to do - delete ld; - return; - } - - // 0) discount padding from width/height - width -= (ld->nVisibleColumns - 1) * xpadding; - height -= (ld->nVisibleRows - 1) * ypadding; - - // 1) compute colwidths and rowheights before handling expansion - // we only count non-spanning controls to avoid weirdness - for (iy = 0; iy < ycount(g); iy++) - for (ix = 0; ix < xcount(g); ix++) { - i = ld->gg[iy][ix]; - if (i == -1) - continue; - gc = (*(g->children))[i]; - uiWindowsControlMinimumSize(uiWindowsControl(gc->c), &iwidth, &iheight); - if (gc->xspan == 1) - if (ld->colwidths[ix] < iwidth) - ld->colwidths[ix] = iwidth; - if (gc->yspan == 1) - if (ld->rowheights[iy] < iheight) - ld->rowheights[iy] = iheight; - // save these for step 6 - gc->minwidth = iwidth; - gc->minheight = iheight; - } - - // 2) figure out which rows/columns expand but not span - // we need to know which expanding rows/columns don't span before we can handle the ones that do - for (i = 0; i < g->children->size(); i++) { - gc = (*(g->children))[i]; - if (!uiControlVisible(gc->c)) - continue; - if (gc->hexpand && gc->xspan == 1) - ld->hexpand[toxindex(g, gc->left)] = true; - if (gc->vexpand && gc->yspan == 1) - ld->vexpand[toyindex(g, gc->top)] = true; - } - - // 3) figure out which rows/columns expand that do span - // the way we handle this is simple: if none of the spanned rows/columns expand, make all rows/columns expand - for (i = 0; i < g->children->size(); i++) { - gc = (*(g->children))[i]; - if (!uiControlVisible(gc->c)) - continue; - if (gc->hexpand && gc->xspan != 1) { - bool doit = true; - - for (ix = gc->left; ix < gc->left + gc->xspan; ix++) - if (ld->hexpand[toxindex(g, ix)]) { - doit = false; - break; - } - if (doit) - for (ix = gc->left; ix < gc->left + gc->xspan; ix++) - ld->hexpand[toxindex(g, ix)] = true; - } - if (gc->vexpand && gc->yspan != 1) { - bool doit = true; - - for (iy = gc->top; iy < gc->top + gc->yspan; iy++) - if (ld->vexpand[toyindex(g, iy)]) { - doit = false; - break; - } - if (doit) - for (iy = gc->top; iy < gc->top + gc->yspan; iy++) - ld->vexpand[toyindex(g, iy)] = true; - } - } - - // 4) compute and assign expanded widths/heights - nhexpand = 0; - nvexpand = 0; - for (i = 0; i < xcount(g); i++) - if (ld->hexpand[i]) - nhexpand++; - else - width -= ld->colwidths[i]; - for (i = 0; i < ycount(g); i++) - if (ld->vexpand[i]) - nvexpand++; - else - height -= ld->rowheights[i]; - for (i = 0; i < xcount(g); i++) - if (ld->hexpand[i]) - ld->colwidths[i] = width / nhexpand; - for (i = 0; i < ycount(g); i++) - if (ld->vexpand[i]) - ld->rowheights[i] = height / nvexpand; - - // 5) reset the final coordinates for the next step - for (i = 0; i < g->children->size(); i++) { - gc = (*(g->children))[i]; - if (!uiControlVisible(gc->c)) - continue; - gc->finalx = 0; - gc->finaly = 0; - gc->finalwidth = 0; - gc->finalheight = 0; - } - - // 6) compute cell positions and sizes - for (iy = 0; iy < ycount(g); iy++) { - int curx; - int prev; - - curx = 0; - prev = -1; - for (ix = 0; ix < xcount(g); ix++) { - if (!ld->visibleColumn(g, ix)) - continue; - i = ld->gg[iy][ix]; - if (i != -1) { - gc = (*(g->children))[i]; - if (iy == toyindex(g, gc->top)) { // don't repeat this step if the control spans vertically - if (i != prev) - gc->finalx = curx; - else - gc->finalwidth += xpadding; - gc->finalwidth += ld->colwidths[ix]; - } - } - curx += ld->colwidths[ix] + xpadding; - prev = i; - } - } - for (ix = 0; ix < xcount(g); ix++) { - int cury; - int prev; - - cury = 0; - prev = -1; - for (iy = 0; iy < ycount(g); iy++) { - if (!ld->visibleRow(g, iy)) - continue; - i = ld->gg[iy][ix]; - if (i != -1) { - gc = (*(g->children))[i]; - if (ix == toxindex(g, gc->left)) { // don't repeat this step if the control spans horizontally - if (i != prev) - gc->finaly = cury; - else - gc->finalheight += ypadding; - gc->finalheight += ld->rowheights[iy]; - } - } - cury += ld->rowheights[iy] + ypadding; - prev = i; - } - } - - // 7) everything as it stands now is set for xalign == Fill yalign == Fill; set the correct alignments - // this is why we saved minwidth/minheight above - for (i = 0; i < g->children->size(); i++) { - gc = (*(g->children))[i]; - if (!uiControlVisible(gc->c)) - continue; - if (gc->halign != uiAlignFill) { - switch (gc->halign) { - case uiAlignEnd: - gc->finalx += gc->finalwidth - gc->minwidth; - break; - case uiAlignCenter: - gc->finalx += (gc->finalwidth - gc->minwidth) / 2; - break; - } - gc->finalwidth = gc->minwidth; // for all three - } - if (gc->valign != uiAlignFill) { - switch (gc->valign) { - case uiAlignEnd: - gc->finaly += gc->finalheight - gc->minheight; - break; - case uiAlignCenter: - gc->finaly += (gc->finalheight - gc->minheight) / 2; - break; - } - gc->finalheight = gc->minheight; // for all three - } - } - - // 8) and FINALLY we resize - for (iy = 0; iy < ycount(g); iy++) - for (ix = 0; ix < xcount(g); ix++) { - i = ld->gg[iy][ix]; - if (i != -1) { // treat empty cells like spaces - gc = (*(g->children))[i]; - uiWindowsEnsureMoveWindowDuringResize( - (HWND) uiControlHandle(gc->c), - gc->finalx,//TODO + x, - gc->finaly,//TODO + y, - gc->finalwidth, - gc->finalheight); - } - } - - delete ld; -} - -static void uiGridDestroy(uiControl *c) -{ - uiGrid *g = uiGrid(c); - - for (struct gridChild *gc : *(g->children)) { - uiControlSetParent(gc->c, NULL); - uiControlDestroy(gc->c); - uiFree(gc); - } - delete g->indexof; - delete g->children; - uiWindowsEnsureDestroyWindow(g->hwnd); - uiFreeControl(uiControl(g)); -} - -uiWindowsControlDefaultHandle(uiGrid) -uiWindowsControlDefaultParent(uiGrid) -uiWindowsControlDefaultSetParent(uiGrid) -uiWindowsControlDefaultToplevel(uiGrid) -uiWindowsControlDefaultVisible(uiGrid) -uiWindowsControlDefaultShow(uiGrid) -uiWindowsControlDefaultHide(uiGrid) -uiWindowsControlDefaultEnabled(uiGrid) -uiWindowsControlDefaultEnable(uiGrid) -uiWindowsControlDefaultDisable(uiGrid) - -static void uiGridSyncEnableState(uiWindowsControl *c, int enabled) -{ - uiGrid *g = uiGrid(c); - - if (uiWindowsShouldStopSyncEnableState(uiWindowsControl(g), enabled)) - return; - for (const struct gridChild *gc : *(g->children)) - uiWindowsControlSyncEnableState(uiWindowsControl(gc->c), enabled); -} - -uiWindowsControlDefaultSetParentHWND(uiGrid) - -static void uiGridMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiGrid *g = uiGrid(c); - int xpadding, ypadding; - gridLayoutData *ld; - int x, y; - int i; - struct gridChild *gc; - int minwid, minht; - int colwidth, rowheight; - - *width = 0; - *height = 0; - if (g->children->size() == 0) - return; // nothing to do - - gridPadding(g, &xpadding, &ypadding); - ld = new gridLayoutData(g); - if (ld->noVisible) { // nothing to do; return 0x0 - delete ld; - return; - } - - // 1) compute colwidths and rowheights before handling expansion - // TODO put this in its own function (but careful about the spanning calculation in gridRelayout()) - for (y = 0; y < ycount(g); y++) - for (x = 0; x < xcount(g); x++) { - i = ld->gg[y][x]; - if (i == -1) - continue; - gc = (*(g->children))[i]; - uiWindowsControlMinimumSize(uiWindowsControl(gc->c), &minwid, &minht); - // allot equal space in the presence of spanning to keep things sane - if (ld->colwidths[x] < minwid / gc->xspan) - ld->colwidths[x] = minwid / gc->xspan; - if (ld->rowheights[y] < minht / gc->yspan) - ld->rowheights[y] = minht / gc->yspan; - // save these for step 6 - gc->minwidth = minwid; - gc->minheight = minht; - } - - // 2) compute total column width/row height - colwidth = 0; - rowheight = 0; - for (x = 0; x < xcount(g); x++) - colwidth += ld->colwidths[x]; - for (y = 0; y < ycount(g); y++) - rowheight += ld->rowheights[y]; - - // and that's it; just account for padding - *width = colwidth + (ld->nVisibleColumns - 1) * xpadding; - *height = rowheight + (ld->nVisibleRows - 1) * ypadding; -} - -static void uiGridMinimumSizeChanged(uiWindowsControl *c) -{ - uiGrid *g = uiGrid(c); - - if (uiWindowsControlTooSmall(uiWindowsControl(g))) { - uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl(g)); - return; - } - gridRelayout(g); -} - -uiWindowsControlDefaultLayoutRect(uiGrid) -uiWindowsControlDefaultAssignControlIDZOrder(uiGrid) - -static void uiGridChildVisibilityChanged(uiWindowsControl *c) -{ - // TODO eliminate the redundancy - uiWindowsControlMinimumSizeChanged(c); -} - -// must have called gridRecomputeMinMax() first -static void gridArrangeChildren(uiGrid *g) -{ - LONG_PTR controlID; - HWND insertAfter; - gridLayoutData *ld; - bool *visited; - int x, y; - int i; - struct gridChild *gc; - - if (g->children->size() == 0) - return; // nothing to do - ld = new gridLayoutData(g); - controlID = 100; - insertAfter = NULL; - visited = new bool[g->children->size()]; - ZeroMemory(visited, g->children->size() * sizeof (bool)); - for (y = 0; y < ycount(g); y++) - for (x = 0; x < xcount(g); x++) { - i = ld->gg[y][x]; - if (i == -1) - continue; - if (visited[i]) - continue; - visited[i] = true; - gc = (*(g->children))[i]; - uiWindowsControlAssignControlIDZOrder(uiWindowsControl(gc->c), &controlID, &insertAfter); - } - delete[] visited; - delete ld; -} - -static struct gridChild *toChild(uiControl *c, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign) -{ - struct gridChild *gc; - - if (xspan < 0) - userbug("You cannot have a negative xspan in a uiGrid cell."); - if (yspan < 0) - userbug("You cannot have a negative yspan in a uiGrid cell."); - gc = uiNew(struct gridChild); - gc->c = c; - gc->xspan = xspan; - gc->yspan = yspan; - gc->hexpand = hexpand; - gc->halign = halign; - gc->vexpand = vexpand; - gc->valign = valign; - return gc; -} - -static void add(uiGrid *g, struct gridChild *gc) -{ - uiControlSetParent(gc->c, uiControl(g)); - uiWindowsControlSetParentHWND(uiWindowsControl(gc->c), g->hwnd); - g->children->push_back(gc); - (*(g->indexof))[gc->c] = g->children->size() - 1; - gridRecomputeMinMax(g); - gridArrangeChildren(g); - uiWindowsControlMinimumSizeChanged(uiWindowsControl(g)); -} - -void uiGridAppend(uiGrid *g, uiControl *c, int left, int top, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign) -{ - struct gridChild *gc; - - gc = toChild(c, xspan, yspan, hexpand, halign, vexpand, valign); - gc->left = left; - gc->top = top; - add(g, gc); -} - -// TODO decide what happens if existing is NULL -void uiGridInsertAt(uiGrid *g, uiControl *c, uiControl *existing, uiAt at, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign) -{ - struct gridChild *gc; - struct gridChild *other; - - gc = toChild(c, xspan, yspan, hexpand, halign, vexpand, valign); - other = (*(g->children))[(*(g->indexof))[existing]]; - switch (at) { - case uiAtLeading: - gc->left = other->left - gc->xspan; - gc->top = other->top; - break; - case uiAtTop: - gc->left = other->left; - gc->top = other->top - gc->yspan; - break; - case uiAtTrailing: - gc->left = other->left + other->xspan; - gc->top = other->top; - break; - case uiAtBottom: - gc->left = other->left; - gc->top = other->top + other->yspan; - break; - // TODO add error checks to ALL enums - } - add(g, gc); -} - -int uiGridPadded(uiGrid *g) -{ - return g->padded; -} - -void uiGridSetPadded(uiGrid *g, int padded) -{ - g->padded = padded; - uiWindowsControlMinimumSizeChanged(uiWindowsControl(g)); -} - -static void onResize(uiWindowsControl *c) -{ - gridRelayout(uiGrid(c)); -} - -uiGrid *uiNewGrid(void) -{ - uiGrid *g; - - uiWindowsNewControl(uiGrid, g); - - g->hwnd = uiWindowsMakeContainer(uiWindowsControl(g), onResize); - - g->children = new std::vector; - g->indexof = new std::map; - - return g; -} diff --git a/deps/libui/windows/group.cpp b/deps/libui/windows/group.cpp deleted file mode 100644 index 8824c5a4d7..0000000000 --- a/deps/libui/windows/group.cpp +++ /dev/null @@ -1,217 +0,0 @@ -// 16 may 2015 -#include "uipriv_windows.hpp" - -struct uiGroup { - uiWindowsControl c; - HWND hwnd; - struct uiControl *child; - int margined; -}; - -// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define groupXMargin 6 -#define groupYMarginTop 11 /* note this value /includes/ the groupbox label */ -#define groupYMarginBottom 7 - -// unfortunately because the client area of a groupbox includes the frame and caption text, we have to apply some margins ourselves, even if we don't want "any" -// these were deduced by hand based on the standard DLU conversions; the X and Y top margins are the width and height, respectively, of one character cell -// they can be fine-tuned later -#define groupUnmarginedXMargin 4 -#define groupUnmarginedYMarginTop 8 -#define groupUnmarginedYMarginBottom 3 - -static void groupMargins(uiGroup *g, int *mx, int *mtop, int *mbottom) -{ - uiWindowsSizing sizing; - - *mx = groupUnmarginedXMargin; - *mtop = groupUnmarginedYMarginTop; - *mbottom = groupUnmarginedYMarginBottom; - if (g->margined) { - *mx = groupXMargin; - *mtop = groupYMarginTop; - *mbottom = groupYMarginBottom; - } - uiWindowsGetSizing(g->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, mx, mtop); - uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, mbottom); -} - -static void groupRelayout(uiGroup *g) -{ - RECT r; - int mx, mtop, mbottom; - - if (g->child == NULL) - return; - uiWindowsEnsureGetClientRect(g->hwnd, &r); - groupMargins(g, &mx, &mtop, &mbottom); - r.left += mx; - r.top += mtop; - r.right -= mx; - r.bottom -= mbottom; - uiWindowsEnsureMoveWindowDuringResize((HWND) uiControlHandle(g->child), r.left, r.top, r.right - r.left, r.bottom - r.top); -} - -static void uiGroupDestroy(uiControl *c) -{ - uiGroup *g = uiGroup(c); - - if (g->child != NULL) { - uiControlSetParent(g->child, NULL); - uiControlDestroy(g->child); - } - uiWindowsEnsureDestroyWindow(g->hwnd); - uiFreeControl(uiControl(g)); -} - -uiWindowsControlDefaultHandle(uiGroup) -uiWindowsControlDefaultParent(uiGroup) -uiWindowsControlDefaultSetParent(uiGroup) -uiWindowsControlDefaultToplevel(uiGroup) -uiWindowsControlDefaultVisible(uiGroup) -uiWindowsControlDefaultShow(uiGroup) -uiWindowsControlDefaultHide(uiGroup) -uiWindowsControlDefaultEnabled(uiGroup) -uiWindowsControlDefaultEnable(uiGroup) -uiWindowsControlDefaultDisable(uiGroup) - -static void uiGroupSyncEnableState(uiWindowsControl *c, int enabled) -{ - uiGroup *g = uiGroup(c); - - if (uiWindowsShouldStopSyncEnableState(uiWindowsControl(g), enabled)) - return; - EnableWindow(g->hwnd, enabled); - if (g->child != NULL) - uiWindowsControlSyncEnableState(uiWindowsControl(g->child), enabled); -} - -uiWindowsControlDefaultSetParentHWND(uiGroup) - -static void uiGroupMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiGroup *g = uiGroup(c); - int mx, mtop, mbottom; - int labelWidth; - - *width = 0; - *height = 0; - if (g->child != NULL) - uiWindowsControlMinimumSize(uiWindowsControl(g->child), width, height); - labelWidth = uiWindowsWindowTextWidth(g->hwnd); - if (*width < labelWidth) // don't clip the label; it doesn't ellipsize - *width = labelWidth; - groupMargins(g, &mx, &mtop, &mbottom); - *width += 2 * mx; - *height += mtop + mbottom; -} - -static void uiGroupMinimumSizeChanged(uiWindowsControl *c) -{ - uiGroup *g = uiGroup(c); - - if (uiWindowsControlTooSmall(uiWindowsControl(g))) { - uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl(g)); - return; - } - groupRelayout(g); -} - -uiWindowsControlDefaultLayoutRect(uiGroup) -uiWindowsControlDefaultAssignControlIDZOrder(uiGroup) - -static void uiGroupChildVisibilityChanged(uiWindowsControl *c) -{ - // TODO eliminate the redundancy - uiWindowsControlMinimumSizeChanged(c); -} - -char *uiGroupTitle(uiGroup *g) -{ - return uiWindowsWindowText(g->hwnd); -} - -void uiGroupSetTitle(uiGroup *g, const char *text) -{ - uiWindowsSetWindowText(g->hwnd, text); - // changing the text might necessitate a change in the groupbox's size - uiWindowsControlMinimumSizeChanged(uiWindowsControl(g)); -} - -void uiGroupSetChild(uiGroup *g, uiControl *child) -{ - if (g->child != NULL) { - uiControlSetParent(g->child, NULL); - uiWindowsControlSetParentHWND(uiWindowsControl(g->child), NULL); - } - g->child = child; - if (g->child != NULL) { - uiControlSetParent(g->child, uiControl(g)); - uiWindowsControlSetParentHWND(uiWindowsControl(g->child), g->hwnd); - uiWindowsControlAssignSoleControlIDZOrder(uiWindowsControl(g->child)); - uiWindowsControlMinimumSizeChanged(uiWindowsControl(g)); - } -} - -int uiGroupMargined(uiGroup *g) -{ - return g->margined; -} - -void uiGroupSetMargined(uiGroup *g, int margined) -{ - g->margined = margined; - uiWindowsControlMinimumSizeChanged(uiWindowsControl(g)); -} - -static LRESULT CALLBACK groupSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) -{ - uiGroup *g = uiGroup(dwRefData); - WINDOWPOS *wp = (WINDOWPOS *) lParam; - MINMAXINFO *mmi = (MINMAXINFO *) lParam; - int minwid, minht; - LRESULT lResult; - - if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE) - return lResult; - switch (uMsg) { - case WM_WINDOWPOSCHANGED: - if ((wp->flags & SWP_NOSIZE) != 0) - break; - groupRelayout(g); - return 0; - case WM_GETMINMAXINFO: - lResult = DefWindowProcW(hwnd, uMsg, wParam, lParam); - uiWindowsControlMinimumSize(uiWindowsControl(g), &minwid, &minht); - mmi->ptMinTrackSize.x = minwid; - mmi->ptMinTrackSize.y = minht; - return lResult; - case WM_NCDESTROY: - if (RemoveWindowSubclass(hwnd, groupSubProc, uIdSubclass) == FALSE) - logLastError(L"error removing groupbox subclass"); - break; - } - return DefSubclassProc(hwnd, uMsg, wParam, lParam); -} - -uiGroup *uiNewGroup(const char *text) -{ - uiGroup *g; - WCHAR *wtext; - - uiWindowsNewControl(uiGroup, g); - - wtext = toUTF16(text); - g->hwnd = uiWindowsEnsureCreateControlHWND(WS_EX_CONTROLPARENT, - L"button", wtext, - BS_GROUPBOX, - hInstance, NULL, - TRUE); - uiFree(wtext); - - if (SetWindowSubclass(g->hwnd, groupSubProc, 0, (DWORD_PTR) g) == FALSE) - logLastError(L"error subclassing groupbox to handle parent messages"); - - return g; -} diff --git a/deps/libui/windows/init.cpp b/deps/libui/windows/init.cpp deleted file mode 100644 index 228741653c..0000000000 --- a/deps/libui/windows/init.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// 6 april 2015 -#include "uipriv_windows.hpp" - -HINSTANCE hInstance; -int nCmdShow; - -HFONT hMessageFont; - -// LONGTERM needed? -HBRUSH hollowBrush; - -// the returned pointer is actually to the second character -// if the first character is - then free, otherwise don't -static const char *initerr(const char *message, const WCHAR *label, DWORD value) -{ - WCHAR *sysmsg; - BOOL hassysmsg; - WCHAR *wmessage; - WCHAR *wout; - char *out; - - hassysmsg = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, value, 0, (LPWSTR) (&sysmsg), 0, NULL) != 0; - if (!hassysmsg) - sysmsg = L""; - wmessage = toUTF16(message + 1); - wout = strf(L"-error initializing libui: %s; code %I32d (0x%08I32X) %s", - wmessage, - value, value, - sysmsg); - uiFree(wmessage); - if (hassysmsg) - LocalFree(sysmsg); // ignore error - out = toUTF8(wout); - uiFree(wout); - return out + 1; -} - -#define ieLastErr(msg) initerr("=" msg, L"GetLastError() ==", GetLastError()) -#define ieHRESULT(msg, hr) initerr("=" msg, L"HRESULT", (DWORD) hr) - -// LONGTERM make common -uiInitOptions options; - -#define wantedICCClasses ( \ - ICC_STANDARD_CLASSES | /* user32.dll controls */ \ - ICC_PROGRESS_CLASS | /* progress bars */ \ - ICC_TAB_CLASSES | /* tabs */ \ - ICC_LISTVIEW_CLASSES | /* table headers */ \ - ICC_UPDOWN_CLASS | /* spinboxes */ \ - ICC_BAR_CLASSES | /* trackbar */ \ - ICC_DATE_CLASSES | /* date/time picker */ \ - 0) - -const char *uiInit(uiInitOptions *o) -{ - STARTUPINFOW si; - const char *ce; - HICON hDefaultIcon; - HCURSOR hDefaultCursor; - NONCLIENTMETRICSW ncm; - INITCOMMONCONTROLSEX icc; - HRESULT hr; - - options = *o; - - initAlloc(); - - nCmdShow = SW_SHOWDEFAULT; - GetStartupInfoW(&si); - if ((si.dwFlags & STARTF_USESHOWWINDOW) != 0) - nCmdShow = si.wShowWindow; - - // LONGTERM set DPI awareness - - hDefaultIcon = LoadIconW(NULL, IDI_APPLICATION); - if (hDefaultIcon == NULL) - return ieLastErr("loading default icon for window classes"); - hDefaultCursor = LoadCursorW(NULL, IDC_ARROW); - if (hDefaultCursor == NULL) - return ieLastErr("loading default cursor for window classes"); - - ce = initUtilWindow(hDefaultIcon, hDefaultCursor); - if (ce != NULL) - return initerr(ce, L"GetLastError() ==", GetLastError()); - - if (registerWindowClass(hDefaultIcon, hDefaultCursor) == 0) - return ieLastErr("registering uiWindow window class"); - - ZeroMemory(&ncm, sizeof (NONCLIENTMETRICSW)); - ncm.cbSize = sizeof (NONCLIENTMETRICSW); - if (SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof (NONCLIENTMETRICSW), &ncm, sizeof (NONCLIENTMETRICSW)) == 0) - return ieLastErr("getting default fonts"); - hMessageFont = CreateFontIndirectW(&(ncm.lfMessageFont)); - if (hMessageFont == NULL) - return ieLastErr("loading default messagebox font; this is the default UI font"); - - if (initContainer(hDefaultIcon, hDefaultCursor) == 0) - return ieLastErr("initializing uiWindowsMakeContainer() window class"); - - hollowBrush = (HBRUSH) GetStockObject(HOLLOW_BRUSH); - if (hollowBrush == NULL) - return ieLastErr("getting hollow brush"); - - ZeroMemory(&icc, sizeof (INITCOMMONCONTROLSEX)); - icc.dwSize = sizeof (INITCOMMONCONTROLSEX); - icc.dwICC = wantedICCClasses; - if (InitCommonControlsEx(&icc) == 0) - return ieLastErr("initializing Common Controls"); - - hr = CoInitialize(NULL); - if (hr != S_OK && hr != S_FALSE) - return ieHRESULT("initializing COM", hr); - // LONGTERM initialize COM security - // LONGTERM (windows vista) turn off COM exception handling - - hr = initDraw(); - if (hr != S_OK) - return ieHRESULT("initializing Direct2D", hr); - - hr = initDrawText(); - if (hr != S_OK) - return ieHRESULT("initializing DirectWrite", hr); - - if (registerAreaClass(hDefaultIcon, hDefaultCursor) == 0) - return ieLastErr("registering uiArea window class"); - - if (registerMessageFilter() == 0) - return ieLastErr("registering libui message filter"); - - if (registerD2DScratchClass(hDefaultIcon, hDefaultCursor) == 0) - return ieLastErr("initializing D2D scratch window class"); - - return NULL; -} - -void uiUninit(void) -{ - uninitMenus(); - unregisterD2DScratchClass(); - unregisterMessageFilter(); - unregisterArea(); - uninitDrawText(); - uninitDraw(); - CoUninitialize(); - if (DeleteObject(hollowBrush) == 0) - logLastError(L"error freeing hollow brush"); - uninitContainer(); - if (DeleteObject(hMessageFont) == 0) - logLastError(L"error deleting control font"); - unregisterWindowClass(); - // no need to delete the default icon or cursor; see http://stackoverflow.com/questions/30603077/ - uninitUtilWindow(); - uninitAlloc(); -} - -void uiFreeInitError(const char *err) -{ - if (*(err - 1) == '-') - uiFree((void *) (err - 1)); -} - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - if (fdwReason == DLL_PROCESS_ATTACH) - hInstance = hinstDLL; - return TRUE; -} diff --git a/deps/libui/windows/label.cpp b/deps/libui/windows/label.cpp deleted file mode 100644 index d74b7d183f..0000000000 --- a/deps/libui/windows/label.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// 11 april 2015 -#include "uipriv_windows.hpp" - -struct uiLabel { - uiWindowsControl c; - HWND hwnd; -}; - -uiWindowsControlAllDefaults(uiLabel) - -// via http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define labelHeight 8 - -static void uiLabelMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiLabel *l = uiLabel(c); - uiWindowsSizing sizing; - int y; - - *width = uiWindowsWindowTextWidth(l->hwnd); - y = labelHeight; - uiWindowsGetSizing(l->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &y); - *height = y; -} - -char *uiLabelText(uiLabel *l) -{ - return uiWindowsWindowText(l->hwnd); -} - -void uiLabelSetText(uiLabel *l, const char *text) -{ - uiWindowsSetWindowText(l->hwnd, text); - // changing the text might necessitate a change in the label's size - uiWindowsControlMinimumSizeChanged(uiWindowsControl(l)); -} - -uiLabel *uiNewLabel(const char *text) -{ - uiLabel *l; - WCHAR *wtext; - - uiWindowsNewControl(uiLabel, l); - - wtext = toUTF16(text); - l->hwnd = uiWindowsEnsureCreateControlHWND(0, - L"static", wtext, - // SS_LEFTNOWORDWRAP clips text past the end; SS_NOPREFIX avoids accelerator translation - // controls are vertically aligned to the top by default (thanks Xeek in irc.freenode.net/#winapi) - SS_LEFTNOWORDWRAP | SS_NOPREFIX, - hInstance, NULL, - TRUE); - uiFree(wtext); - - return l; -} diff --git a/deps/libui/windows/libui.manifest b/deps/libui/windows/libui.manifest deleted file mode 100644 index 8beb6cfc89..0000000000 --- a/deps/libui/windows/libui.manifest +++ /dev/null @@ -1,31 +0,0 @@ - - - -Your application description here. - - - - - - - - - - - - - - - diff --git a/deps/libui/windows/main.cpp b/deps/libui/windows/main.cpp deleted file mode 100644 index eb6d84921d..0000000000 --- a/deps/libui/windows/main.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// 6 april 2015 -#include "uipriv_windows.hpp" - -static HHOOK filter; - -static LRESULT CALLBACK filterProc(int code, WPARAM wParam, LPARAM lParam) -{ - MSG *msg = (MSG *) lParam; - - if (code < 0) - goto callNext; - - if (areaFilter(msg)) // don't continue to our IsDialogMessage() hack if the area handled it - goto discard; - - // TODO IsDialogMessage() hack here - - // otherwise keep going - goto callNext; - -discard: - // we handled it; discard the message so the dialog manager doesn't see it - return 1; - -callNext: - return CallNextHookEx(filter, code, wParam, lParam); -} - -int registerMessageFilter(void) -{ - filter = SetWindowsHookExW(WH_MSGFILTER, - filterProc, - hInstance, - GetCurrentThreadId()); - return filter != NULL; -} - -void unregisterMessageFilter(void) -{ - if (UnhookWindowsHookEx(filter) == 0) - logLastError(L"error unregistering libui message filter"); -} - -// LONGTERM http://blogs.msdn.com/b/oldnewthing/archive/2005/04/08/406509.aspx when adding accelerators, TranslateAccelerators() before IsDialogMessage() - -static void processMessage(MSG *msg) -{ - HWND correctParent; - - if (msg->hwnd != NULL) - correctParent = parentToplevel(msg->hwnd); - else // just to be safe - correctParent = GetActiveWindow(); - if (correctParent != NULL) - // this calls our mesage filter above for us - if (IsDialogMessage(correctParent, msg) != 0) - return; - TranslateMessage(msg); - DispatchMessageW(msg); -} - -static int waitMessage(MSG *msg) -{ - int res; - - res = GetMessageW(msg, NULL, 0, 0); - if (res < 0) { - logLastError(L"error calling GetMessage()"); - return 0; // bail out on error - } - return res != 0; // returns false on WM_QUIT -} - -void uiMain(void) -{ - while (uiMainStep(1)) - ; -} - -void uiMainSteps(void) -{ - // don't need to do anything here -} - -static int peekMessage(MSG *msg) -{ - BOOL res; - - res = PeekMessageW(msg, NULL, 0, 0, PM_REMOVE); - if (res == 0) - return 2; // no message available - if (msg->message != WM_QUIT) - return 1; // a message - return 0; // WM_QUIT -} - -int uiMainStep(int wait) -{ - MSG msg; - - if (wait) { - if (!waitMessage(&msg)) - return 0; - processMessage(&msg); - return 1; - } - - // don't wait for a message - switch (peekMessage(&msg)) { - case 0: // quit - // TODO PostQuitMessage() again? - return 0; - case 1: // process a message - processMessage(&msg); - // fall out to the case for no message - } - return 1; // no message -} - -void uiQuit(void) -{ - PostQuitMessage(0); -} - -void uiQueueMain(void (*f)(void *data), void *data) -{ - if (PostMessageW(utilWindow, msgQueued, (WPARAM) f, (LPARAM) data) == 0) - // LONGTERM this is likely not safe to call across threads (allocates memory) - logLastError(L"error queueing function to run on main thread"); -} diff --git a/deps/libui/windows/menu.cpp b/deps/libui/windows/menu.cpp deleted file mode 100644 index 6112fc13b1..0000000000 --- a/deps/libui/windows/menu.cpp +++ /dev/null @@ -1,369 +0,0 @@ -// 24 april 2015 -#include "uipriv_windows.hpp" - -// LONGTERM migrate to std::vector - -static uiMenu **menus = NULL; -static size_t len = 0; -static size_t cap = 0; -static BOOL menusFinalized = FALSE; -static WORD curID = 100; // start somewhere safe -static BOOL hasQuit = FALSE; -static BOOL hasPreferences = FALSE; -static BOOL hasAbout = FALSE; - -struct uiMenu { - WCHAR *name; - uiMenuItem **items; - size_t len; - size_t cap; -}; - -struct uiMenuItem { - WCHAR *name; - int type; - WORD id; - void (*onClicked)(uiMenuItem *, uiWindow *, void *); - void *onClickedData; - BOOL disabled; // template for new instances; kept in sync with everything else - BOOL checked; - HMENU *hmenus; - size_t len; - size_t cap; -}; - -enum { - typeRegular, - typeCheckbox, - typeQuit, - typePreferences, - typeAbout, - typeSeparator, -}; - -#define grow 32 - -static void sync(uiMenuItem *item) -{ - size_t i; - MENUITEMINFOW mi; - - ZeroMemory(&mi, sizeof (MENUITEMINFOW)); - mi.cbSize = sizeof (MENUITEMINFOW); - mi.fMask = MIIM_STATE; - if (item->disabled) - mi.fState |= MFS_DISABLED; - if (item->checked) - mi.fState |= MFS_CHECKED; - - for (i = 0; i < item->len; i++) - if (SetMenuItemInfo(item->hmenus[i], item->id, FALSE, &mi) == 0) - logLastError(L"error synchronizing menu items"); -} - -static void defaultOnClicked(uiMenuItem *item, uiWindow *w, void *data) -{ - // do nothing -} - -static void onQuitClicked(uiMenuItem *item, uiWindow *w, void *data) -{ - if (shouldQuit()) - uiQuit(); -} - -void uiMenuItemEnable(uiMenuItem *i) -{ - i->disabled = FALSE; - sync(i); -} - -void uiMenuItemDisable(uiMenuItem *i) -{ - i->disabled = TRUE; - sync(i); -} - -void uiMenuItemOnClicked(uiMenuItem *i, void (*f)(uiMenuItem *, uiWindow *, void *), void *data) -{ - if (i->type == typeQuit) - userbug("You can not call uiMenuItemOnClicked() on a Quit item; use uiOnShouldQuit() instead."); - i->onClicked = f; - i->onClickedData = data; -} - -int uiMenuItemChecked(uiMenuItem *i) -{ - return i->checked != FALSE; -} - -void uiMenuItemSetChecked(uiMenuItem *i, int checked) -{ - // use explicit values - i->checked = FALSE; - if (checked) - i->checked = TRUE; - sync(i); -} - -static uiMenuItem *newItem(uiMenu *m, int type, const char *name) -{ - uiMenuItem *item; - - if (menusFinalized) - userbug("You can not create a new menu item after menus have been finalized."); - - if (m->len >= m->cap) { - m->cap += grow; - m->items = (uiMenuItem **) uiRealloc(m->items, m->cap * sizeof (uiMenuItem *), "uiMenuitem *[]"); - } - - item = uiNew(uiMenuItem); - - m->items[m->len] = item; - m->len++; - - item->type = type; - switch (item->type) { - case typeQuit: - item->name = toUTF16("Quit"); - break; - case typePreferences: - item->name = toUTF16("Preferences..."); - break; - case typeAbout: - item->name = toUTF16("About"); - break; - case typeSeparator: - break; - default: - item->name = toUTF16(name); - break; - } - - if (item->type != typeSeparator) { - item->id = curID; - curID++; - } - - if (item->type == typeQuit) { - // can't call uiMenuItemOnClicked() here - item->onClicked = onQuitClicked; - item->onClickedData = NULL; - } else - uiMenuItemOnClicked(item, defaultOnClicked, NULL); - - return item; -} - -uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name) -{ - return newItem(m, typeRegular, name); -} - -uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const char *name) -{ - return newItem(m, typeCheckbox, name); -} - -uiMenuItem *uiMenuAppendQuitItem(uiMenu *m) -{ - if (hasQuit) - userbug("You can not have multiple Quit menu items in a program."); - hasQuit = TRUE; - newItem(m, typeSeparator, NULL); - return newItem(m, typeQuit, NULL); -} - -uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m) -{ - if (hasPreferences) - userbug("You can not have multiple Preferences menu items in a program."); - hasPreferences = TRUE; - newItem(m, typeSeparator, NULL); - return newItem(m, typePreferences, NULL); -} - -uiMenuItem *uiMenuAppendAboutItem(uiMenu *m) -{ - if (hasAbout) - // TODO place these userbug strings in a header - userbug("You can not have multiple About menu items in a program."); - hasAbout = TRUE; - newItem(m, typeSeparator, NULL); - return newItem(m, typeAbout, NULL); -} - -void uiMenuAppendSeparator(uiMenu *m) -{ - newItem(m, typeSeparator, NULL); -} - -uiMenu *uiNewMenu(const char *name) -{ - uiMenu *m; - - if (menusFinalized) - userbug("You can not create a new menu after menus have been finalized."); - if (len >= cap) { - cap += grow; - menus = (uiMenu **) uiRealloc(menus, cap * sizeof (uiMenu *), "uiMenu *[]"); - } - - m = uiNew(uiMenu); - - menus[len] = m; - len++; - - m->name = toUTF16(name); - - return m; -} - -static void appendMenuItem(HMENU menu, uiMenuItem *item) -{ - UINT uFlags; - - uFlags = MF_SEPARATOR; - if (item->type != typeSeparator) { - uFlags = MF_STRING; - if (item->disabled) - uFlags |= MF_DISABLED | MF_GRAYED; - if (item->checked) - uFlags |= MF_CHECKED; - } - if (AppendMenuW(menu, uFlags, item->id, item->name) == 0) - logLastError(L"error appending menu item"); - - if (item->len >= item->cap) { - item->cap += grow; - item->hmenus = (HMENU *) uiRealloc(item->hmenus, item->cap * sizeof (HMENU), "HMENU[]"); - } - item->hmenus[item->len] = menu; - item->len++; -} - -static HMENU makeMenu(uiMenu *m) -{ - HMENU menu; - size_t i; - - menu = CreatePopupMenu(); - if (menu == NULL) - logLastError(L"error creating menu"); - for (i = 0; i < m->len; i++) - appendMenuItem(menu, m->items[i]); - return menu; -} - -HMENU makeMenubar(void) -{ - HMENU menubar; - HMENU menu; - size_t i; - - menusFinalized = TRUE; - - menubar = CreateMenu(); - if (menubar == NULL) - logLastError(L"error creating menubar"); - - for (i = 0; i < len; i++) { - menu = makeMenu(menus[i]); - if (AppendMenuW(menubar, MF_POPUP | MF_STRING, (UINT_PTR) menu, menus[i]->name) == 0) - logLastError(L"error appending menu to menubar"); - } - - return menubar; -} - -void runMenuEvent(WORD id, uiWindow *w) -{ - uiMenu *m; - uiMenuItem *item; - size_t i, j; - - // this isn't optimal, but it works, and it should be just fine for most cases - for (i = 0; i < len; i++) { - m = menus[i]; - for (j = 0; j < m->len; j++) { - item = m->items[j]; - if (item->id == id) - goto found; - } - } - // no match - implbug("unknown menu ID %hu in runMenuEvent()", id); - -found: - // first toggle checkboxes, if any - if (item->type == typeCheckbox) - uiMenuItemSetChecked(item, !uiMenuItemChecked(item)); - - // then run the event - (*(item->onClicked))(item, w, item->onClickedData); -} - -static void freeMenu(uiMenu *m, HMENU submenu) -{ - size_t i; - uiMenuItem *item; - size_t j; - - for (i = 0; i < m->len; i++) { - item = m->items[i]; - for (j = 0; j < item->len; j++) - if (item->hmenus[j] == submenu) - break; - if (j >= item->len) - implbug("submenu handle %p not found in freeMenu()", submenu); - for (; j < item->len - 1; j++) - item->hmenus[j] = item->hmenus[j + 1]; - item->hmenus[j] = NULL; - item->len--; - } -} - -void freeMenubar(HMENU menubar) -{ - size_t i; - MENUITEMINFOW mi; - - for (i = 0; i < len; i++) { - ZeroMemory(&mi, sizeof (MENUITEMINFOW)); - mi.cbSize = sizeof (MENUITEMINFOW); - mi.fMask = MIIM_SUBMENU; - if (GetMenuItemInfoW(menubar, i, TRUE, &mi) == 0) - logLastError(L"error getting menu to delete item references from"); - freeMenu(menus[i], mi.hSubMenu); - } - // no need to worry about destroying any menus; destruction of the window they're in will do it for us -} - -void uninitMenus(void) -{ - uiMenu *m; - uiMenuItem *item; - size_t i, j; - - for (i = 0; i < len; i++) { - m = menus[i]; - uiFree(m->name); - for (j = 0; j < m->len; j++) { - item = m->items[j]; - if (item->len != 0) - // LONGTERM userbug()? - implbug("menu item %p (%ws) still has uiWindows attached; did you forget to destroy some windows?", item, item->name); - if (item->name != NULL) - uiFree(item->name); - if (item->hmenus != NULL) - uiFree(item->hmenus); - uiFree(item); - } - if (m->items != NULL) - uiFree(m->items); - uiFree(m); - } - if (menus != NULL) - uiFree(menus); -} diff --git a/deps/libui/windows/multilineentry.cpp b/deps/libui/windows/multilineentry.cpp deleted file mode 100644 index a32960cb8a..0000000000 --- a/deps/libui/windows/multilineentry.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// 8 april 2015 -#include "uipriv_windows.hpp" - -// TODO there's alpha darkening of text going on in read-only ones; something is up in our parent logic - -struct uiMultilineEntry { - uiWindowsControl c; - HWND hwnd; - void (*onChanged)(uiMultilineEntry *, void *); - void *onChangedData; - BOOL inhibitChanged; -}; - -static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) -{ - uiMultilineEntry *e = uiMultilineEntry(c); - - if (code != EN_CHANGE) - return FALSE; - if (e->inhibitChanged) - return FALSE; - (*(e->onChanged))(e, e->onChangedData); - *lResult = 0; - return TRUE; -} - -static void uiMultilineEntryDestroy(uiControl *c) -{ - uiMultilineEntry *e = uiMultilineEntry(c); - - uiWindowsUnregisterWM_COMMANDHandler(e->hwnd); - uiWindowsEnsureDestroyWindow(e->hwnd); - uiFreeControl(uiControl(e)); -} - -uiWindowsControlAllDefaultsExceptDestroy(uiMultilineEntry) - -// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define entryWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary */ -// LONGTERM change this for multiline text boxes (longterm because how?) -#define entryHeight 14 - -static void uiMultilineEntryMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiMultilineEntry *e = uiMultilineEntry(c); - uiWindowsSizing sizing; - int x, y; - - x = entryWidth; - y = entryHeight; - uiWindowsGetSizing(e->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); - *width = x; - *height = y; -} - -static void defaultOnChanged(uiMultilineEntry *e, void *data) -{ - // do nothing -} - -char *uiMultilineEntryText(uiMultilineEntry *e) -{ - char *out; - - out = uiWindowsWindowText(e->hwnd); - CRLFtoLF(out); - return out; -} - -void uiMultilineEntrySetText(uiMultilineEntry *e, const char *text) -{ - char *crlf; - - // doing this raises an EN_CHANGED - e->inhibitChanged = TRUE; - crlf = LFtoCRLF(text); - uiWindowsSetWindowText(e->hwnd, text); - uiFree(crlf); - e->inhibitChanged = FALSE; - // don't queue the control for resize; entry sizes are independent of their contents -} - -void uiMultilineEntryAppend(uiMultilineEntry *e, const char *text) -{ - LRESULT n; - char *crlf; - WCHAR *wtext; - - // doing this raises an EN_CHANGED - e->inhibitChanged = TRUE; - // TODO preserve selection? caret? what if caret used to be at end? - // TODO scroll to bottom? - n = SendMessageW(e->hwnd, WM_GETTEXTLENGTH, 0, 0); - SendMessageW(e->hwnd, EM_SETSEL, n, n); - crlf = LFtoCRLF(text); - wtext = toUTF16(crlf); - uiFree(crlf); - SendMessageW(e->hwnd, EM_REPLACESEL, FALSE, (LPARAM) wtext); - uiFree(wtext); - e->inhibitChanged = FALSE; -} - -void uiMultilineEntryOnChanged(uiMultilineEntry *e, void (*f)(uiMultilineEntry *, void *), void *data) -{ - e->onChanged = f; - e->onChangedData = data; -} - -int uiMultilineEntryReadOnly(uiMultilineEntry *e) -{ - return (getStyle(e->hwnd) & ES_READONLY) != 0; -} - -void uiMultilineEntrySetReadOnly(uiMultilineEntry *e, int readonly) -{ - WPARAM ro; - - ro = (WPARAM) FALSE; - if (readonly) - ro = (WPARAM) TRUE; - if (SendMessage(e->hwnd, EM_SETREADONLY, ro, 0) == 0) - logLastError(L"error making uiMultilineEntry read-only"); -} - -static uiMultilineEntry *finishMultilineEntry(DWORD style) -{ - uiMultilineEntry *e; - - uiWindowsNewControl(uiMultilineEntry, e); - - e->hwnd = uiWindowsEnsureCreateControlHWND(WS_EX_CLIENTEDGE, - L"edit", L"", - ES_AUTOVSCROLL | ES_LEFT | ES_MULTILINE | ES_NOHIDESEL | ES_WANTRETURN | WS_TABSTOP | WS_VSCROLL | style, - hInstance, NULL, - TRUE); - - uiWindowsRegisterWM_COMMANDHandler(e->hwnd, onWM_COMMAND, uiControl(e)); - uiMultilineEntryOnChanged(e, defaultOnChanged, NULL); - - return e; -} - -uiMultilineEntry *uiNewMultilineEntry(void) -{ - return finishMultilineEntry(0); -} - -uiMultilineEntry *uiNewNonWrappingMultilineEntry(void) -{ - return finishMultilineEntry(WS_HSCROLL | ES_AUTOHSCROLL); -} diff --git a/deps/libui/windows/notes b/deps/libui/windows/notes deleted file mode 100644 index f554dd282d..0000000000 --- a/deps/libui/windows/notes +++ /dev/null @@ -1,3 +0,0 @@ -DIALOGS -do not accelerate OK and Cancel buttons in dialogs - http://blogs.msdn.com/b/oldnewthing/archive/2008/05/08/8467905.aspx diff --git a/deps/libui/windows/parent.cpp b/deps/libui/windows/parent.cpp deleted file mode 100644 index bde6fb94e4..0000000000 --- a/deps/libui/windows/parent.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// 26 april 2015 -#include "uipriv_windows.hpp" - -// This contains code used by all uiControls that contain other controls. -// It also contains the code to draw the background of a container.c container, as that is a variant of the WM_CTLCOLORxxx handler code. - -static HBRUSH parentBrush = NULL; - -static HWND parentWithBackground(HWND hwnd) -{ - HWND parent; - int cls; - - parent = hwnd; - for (;;) { - parent = parentOf(parent); - // skip groupboxes; they're (supposed to be) transparent - // skip uiContainers; they don't draw anything - cls = windowClassOf(parent, L"button", containerClass, NULL); - if (cls != 0 && cls != 1) - break; - } - return parent; -} - -struct parentDraw { - HDC cdc; - HBITMAP bitmap; - HBITMAP prevbitmap; -}; - -static HRESULT parentDraw(HDC dc, HWND parent, struct parentDraw *pd) -{ - RECT r; - - uiWindowsEnsureGetClientRect(parent, &r); - pd->cdc = CreateCompatibleDC(dc); - if (pd->cdc == NULL) - return logLastError(L"error creating compatible DC"); - pd->bitmap = CreateCompatibleBitmap(dc, r.right - r.left, r.bottom - r.top); - if (pd->bitmap == NULL) - return logLastError(L"error creating compatible bitmap"); - pd->prevbitmap = (HBITMAP) SelectObject(pd->cdc, pd->bitmap); - if (pd->prevbitmap == NULL) - return logLastError(L"error selecting bitmap into compatible DC"); - SendMessageW(parent, WM_PRINTCLIENT, (WPARAM) (pd->cdc), PRF_CLIENT); - return S_OK; -} - -static void endParentDraw(struct parentDraw *pd) -{ - // continue in case of any error - if (pd->prevbitmap != NULL) - if (((HBITMAP) SelectObject(pd->cdc, pd->prevbitmap)) != pd->bitmap) - logLastError(L"error selecting previous bitmap back into compatible DC"); - if (pd->bitmap != NULL) - if (DeleteObject(pd->bitmap) == 0) - logLastError(L"error deleting compatible bitmap"); - if (pd->cdc != NULL) - if (DeleteDC(pd->cdc) == 0) - logLastError(L"error deleting compatible DC"); -} - -// see http://www.codeproject.com/Articles/5978/Correctly-drawn-themed-dialogs-in-WinXP -static HBRUSH getControlBackgroundBrush(HWND hwnd, HDC dc) -{ - HWND parent; - RECT hwndScreenRect; - struct parentDraw pd; - HBRUSH brush; - HRESULT hr; - - parent = parentWithBackground(hwnd); - - hr = parentDraw(dc, parent, &pd); - if (hr != S_OK) - return NULL; - brush = CreatePatternBrush(pd.bitmap); - if (brush == NULL) { - logLastError(L"error creating pattern brush"); - endParentDraw(&pd); - return NULL; - } - endParentDraw(&pd); - - // now figure out where the control is relative to the parent so we can align the brush properly - // if anything fails, give up and return the brush as-is - uiWindowsEnsureGetWindowRect(hwnd, &hwndScreenRect); - // this will be in screen coordinates; convert to parent coordinates - mapWindowRect(NULL, parent, &hwndScreenRect); - if (SetBrushOrgEx(dc, -hwndScreenRect.left, -hwndScreenRect.top, NULL) == 0) - logLastError(L"error setting brush origin"); - - return brush; -} - -void paintContainerBackground(HWND hwnd, HDC dc, RECT *paintRect) -{ - HWND parent; - RECT paintRectParent; - struct parentDraw pd; - HRESULT hr; - - parent = parentWithBackground(hwnd); - hr = parentDraw(dc, parent, &pd); - if (hr != S_OK) // we couldn't get it; draw nothing - return; - - paintRectParent = *paintRect; - mapWindowRect(hwnd, parent, &paintRectParent); - if (BitBlt(dc, paintRect->left, paintRect->top, paintRect->right - paintRect->left, paintRect->bottom - paintRect->top, - pd.cdc, paintRectParent.left, paintRectParent.top, - SRCCOPY) == 0) - logLastError(L"error drawing parent background over uiContainer"); - - endParentDraw(&pd); -} - -// TODO make this public if we want custom containers -// why have this to begin with? http://blogs.msdn.com/b/oldnewthing/archive/2010/03/16/9979112.aspx -BOOL handleParentMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult) -{ - switch (uMsg) { - case WM_COMMAND: - return runWM_COMMAND(wParam, lParam, lResult); - case WM_NOTIFY: - return runWM_NOTIFY(wParam, lParam, lResult); - case WM_HSCROLL: - return runWM_HSCROLL(wParam, lParam, lResult); - case WM_CTLCOLORSTATIC: - case WM_CTLCOLORBTN: - if (parentBrush != NULL) - if (DeleteObject(parentBrush) == 0) - logLastError(L"error deleting old background brush()"); // but continue anyway; we will leak a brush but whatever - if (SetBkMode((HDC) wParam, TRANSPARENT) == 0) - logLastError(L"error setting transparent background mode to controls"); // but continue anyway; text will be wrong - parentBrush = getControlBackgroundBrush((HWND) lParam, (HDC) wParam); - if (parentBrush == NULL) // failed; just do default behavior - return FALSE; - *lResult = (LRESULT) parentBrush; - return TRUE; - } - return FALSE; -} diff --git a/deps/libui/windows/progressbar.cpp b/deps/libui/windows/progressbar.cpp deleted file mode 100644 index 3750eb6aee..0000000000 --- a/deps/libui/windows/progressbar.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// 19 may 2015 -#include "uipriv_windows.hpp" - -struct uiProgressBar { - uiWindowsControl c; - HWND hwnd; -}; - -uiWindowsControlAllDefaults(uiProgressBar) - -// via http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define pbarWidth 237 -#define pbarHeight 8 - -static void uiProgressBarMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiProgressBar *p = uiProgressBar(c); - uiWindowsSizing sizing; - int x, y; - - x = pbarWidth; - y = pbarHeight; - uiWindowsGetSizing(p->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); - *width = x; - *height = y; -} - -#define indeterminate(p) ((getStyle(p->hwnd) & PBS_MARQUEE) != 0) - -int uiProgressBarValue(uiProgressBar *p) -{ - if (indeterminate(p)) - return -1; - return SendMessage(p->hwnd, PBM_GETPOS, 0, 0); -} - -// unfortunately, as of Vista progress bars have a forced animation on increase -// we have to set the progress bar to value + 1 and decrease it back to value if we want an "instant" change -// see http://stackoverflow.com/questions/2217688/windows-7-aero-theme-progress-bar-bug -// it's not ideal/perfect, but it will have to do -void uiProgressBarSetValue(uiProgressBar *p, int value) -{ - if (value == -1) { - if (!indeterminate(p)) { - setStyle(p->hwnd, getStyle(p->hwnd) | PBS_MARQUEE); - SendMessageW(p->hwnd, PBM_SETMARQUEE, (WPARAM) TRUE, 0); - } - return; - } - if (indeterminate(p)) { - SendMessageW(p->hwnd, PBM_SETMARQUEE, (WPARAM) FALSE, 0); - setStyle(p->hwnd, getStyle(p->hwnd) & ~PBS_MARQUEE); - } - - if (value < 0 || value > 100) - userbug("Value %d is out of range for uiProgressBars.", value); - - if (value == 100) { // because we can't 101 - SendMessageW(p->hwnd, PBM_SETRANGE32, 0, 101); - SendMessageW(p->hwnd, PBM_SETPOS, 101, 0); - SendMessageW(p->hwnd, PBM_SETPOS, 100, 0); - SendMessageW(p->hwnd, PBM_SETRANGE32, 0, 100); - return; - } - SendMessageW(p->hwnd, PBM_SETPOS, (WPARAM) (value + 1), 0); - SendMessageW(p->hwnd, PBM_SETPOS, (WPARAM) value, 0); -} - -uiProgressBar *uiNewProgressBar(void) -{ - uiProgressBar *p; - - uiWindowsNewControl(uiProgressBar, p); - - p->hwnd = uiWindowsEnsureCreateControlHWND(0, - PROGRESS_CLASSW, L"", - PBS_SMOOTH, - hInstance, NULL, - FALSE); - - return p; -} diff --git a/deps/libui/windows/radiobuttons.cpp b/deps/libui/windows/radiobuttons.cpp deleted file mode 100644 index 29cd2e6611..0000000000 --- a/deps/libui/windows/radiobuttons.cpp +++ /dev/null @@ -1,196 +0,0 @@ -// 20 may 2015 -#include "uipriv_windows.hpp" - -// desired behavior: -// - tab moves between the radio buttons and the adjacent controls -// - arrow keys navigate between radio buttons -// - arrow keys do not leave the radio buttons (this is done in control.c) -// - arrow keys wrap around bare groups (if the previous control has WS_GROUP but the first radio button doesn't, then it doesn't; since our radio buttons are all in their own child window we can't do that) -// - clicking on a radio button draws a focus rect (TODO) - -struct uiRadioButtons { - uiWindowsControl c; - HWND hwnd; // of the container - std::vector *hwnds; // of the buttons - void (*onSelected)(uiRadioButtons *, void *); - void *onSelectedData; -}; - -static BOOL onWM_COMMAND(uiControl *c, HWND clicked, WORD code, LRESULT *lResult) -{ - uiRadioButtons *r = uiRadioButtons(c); - WPARAM check; - - if (code != BN_CLICKED) - return FALSE; - for (const HWND &hwnd : *(r->hwnds)) { - check = BST_UNCHECKED; - if (clicked == hwnd) - check = BST_CHECKED; - SendMessage(hwnd, BM_SETCHECK, check, 0); - } - (*(r->onSelected))(r, r->onSelectedData); - *lResult = 0; - return TRUE; -} - -static void defaultOnSelected(uiRadioButtons *r, void *data) -{ - // do nothing -} - -static void uiRadioButtonsDestroy(uiControl *c) -{ - uiRadioButtons *r = uiRadioButtons(c); - - for (const HWND &hwnd : *(r->hwnds)) { - uiWindowsUnregisterWM_COMMANDHandler(hwnd); - uiWindowsEnsureDestroyWindow(hwnd); - } - delete r->hwnds; - uiWindowsEnsureDestroyWindow(r->hwnd); - uiFreeControl(uiControl(r)); -} - -// TODO SyncEnableState -uiWindowsControlAllDefaultsExceptDestroy(uiRadioButtons) - -// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define radiobuttonHeight 10 -// from http://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx -#define radiobuttonXFromLeftOfBoxToLeftOfLabel 12 - -static void uiRadioButtonsMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiRadioButtons *r = uiRadioButtons(c); - int wid, maxwid; - uiWindowsSizing sizing; - int x, y; - - if (r->hwnds->size() == 0) { - *width = 0; - *height = 0; - return; - } - maxwid = 0; - for (const HWND &hwnd : *(r->hwnds)) { - wid = uiWindowsWindowTextWidth(hwnd); - if (maxwid < wid) - maxwid = wid; - } - - x = radiobuttonXFromLeftOfBoxToLeftOfLabel; - y = radiobuttonHeight; - uiWindowsGetSizing((*(r->hwnds))[0], &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); - - *width = x + maxwid; - *height = y * r->hwnds->size(); -} - -static void radiobuttonsRelayout(uiRadioButtons *r) -{ - RECT client; - int x, y, width, height; - int height1; - uiWindowsSizing sizing; - - if (r->hwnds->size() == 0) - return; - uiWindowsEnsureGetClientRect(r->hwnd, &client); - x = client.left; - y = client.top; - width = client.right - client.left; - height1 = radiobuttonHeight; - uiWindowsGetSizing((*(r->hwnds))[0], &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &height1); - height = height1; - for (const HWND &hwnd : *(r->hwnds)) { - uiWindowsEnsureMoveWindowDuringResize(hwnd, x, y, width, height); - y += height; - } -} - -static void radiobuttonsArrangeChildren(uiRadioButtons *r) -{ - LONG_PTR controlID; - HWND insertAfter; - - controlID = 100; - insertAfter = NULL; - for (const HWND &hwnd : *(r->hwnds)) - uiWindowsEnsureAssignControlIDZOrder(hwnd, &controlID, &insertAfter); -} - -void uiRadioButtonsAppend(uiRadioButtons *r, const char *text) -{ - HWND hwnd; - WCHAR *wtext; - DWORD groupTabStop; - - // the first radio button gets both WS_GROUP and WS_TABSTOP - // successive radio buttons get *neither* - groupTabStop = 0; - if (r->hwnds->size() == 0) - groupTabStop = WS_GROUP | WS_TABSTOP; - - wtext = toUTF16(text); - hwnd = uiWindowsEnsureCreateControlHWND(0, - L"button", wtext, - BS_RADIOBUTTON | groupTabStop, - hInstance, NULL, - TRUE); - uiFree(wtext); - uiWindowsEnsureSetParentHWND(hwnd, r->hwnd); - uiWindowsRegisterWM_COMMANDHandler(hwnd, onWM_COMMAND, uiControl(r)); - r->hwnds->push_back(hwnd); - radiobuttonsArrangeChildren(r); - uiWindowsControlMinimumSizeChanged(uiWindowsControl(r)); -} - -int uiRadioButtonsSelected(uiRadioButtons *r) -{ - size_t i; - - for (i = 0; i < r->hwnds->size(); i++) - if (SendMessage((*(r->hwnds))[i], BM_GETCHECK, 0, 0) == BST_CHECKED) - return i; - return -1; -} - -void uiRadioButtonsSetSelected(uiRadioButtons *r, int n) -{ - int m; - - m = uiRadioButtonsSelected(r); - if (m != -1) - SendMessage((*(r->hwnds))[m], BM_SETCHECK, BST_UNCHECKED, 0); - if (n != -1) - SendMessage((*(r->hwnds))[n], BM_SETCHECK, BST_CHECKED, 0); -} - -void uiRadioButtonsOnSelected(uiRadioButtons *r, void (*f)(uiRadioButtons *, void *), void *data) -{ - r->onSelected = f; - r->onSelectedData = data; -} - -static void onResize(uiWindowsControl *c) -{ - radiobuttonsRelayout(uiRadioButtons(c)); -} - -uiRadioButtons *uiNewRadioButtons(void) -{ - uiRadioButtons *r; - - uiWindowsNewControl(uiRadioButtons, r); - - r->hwnd = uiWindowsMakeContainer(uiWindowsControl(r), onResize); - - r->hwnds = new std::vector; - - uiRadioButtonsOnSelected(r, defaultOnSelected, NULL); - - return r; -} diff --git a/deps/libui/windows/resources.hpp b/deps/libui/windows/resources.hpp deleted file mode 100644 index 4ae547255c..0000000000 --- a/deps/libui/windows/resources.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// 30 may 2015 - -#define rcTabPageDialog 29000 -#define rcFontDialog 29001 -#define rcColorDialog 29002 - -// TODO normalize these - -#define rcFontFamilyCombobox 1000 -#define rcFontStyleCombobox 1001 -#define rcFontSizeCombobox 1002 -#define rcFontSamplePlacement 1003 - -#define rcColorSVChooser 1100 -#define rcColorHSlider 1101 -#define rcPreview 1102 -#define rcOpacitySlider 1103 -#define rcH 1104 -#define rcS 1105 -#define rcV 1106 -#define rcRDouble 1107 -#define rcRInt 1108 -#define rcGDouble 1109 -#define rcGInt 1110 -#define rcBDouble 1111 -#define rcBInt 1112 -#define rcADouble 1113 -#define rcAInt 1114 -#define rcHex 1115 -#define rcHLabel 1116 -#define rcSLabel 1117 -#define rcVLabel 1118 -#define rcRLabel 1119 -#define rcGLabel 1120 -#define rcBLabel 1121 -#define rcALabel 1122 -#define rcHexLabel 1123 diff --git a/deps/libui/windows/resources.rc b/deps/libui/windows/resources.rc deleted file mode 100644 index 989dfc9147..0000000000 --- a/deps/libui/windows/resources.rc +++ /dev/null @@ -1,96 +0,0 @@ -// 30 may 2015 -#include "winapi.hpp" -#include "resources.hpp" - -// this is a UTF-8 file -#pragma code_page(65001) - -// this is the Common Controls 6 manifest -// we only define it in a shared build; static builds have to include the appropriate parts of the manifest in the output executable -// LONGTERM set up the string values here -#ifndef _UI_STATIC -ISOLATIONAWARE_MANIFEST_RESOURCE_ID RT_MANIFEST "libui.manifest" -#endif - -// this is the dialog template used by tab pages; see windows/tabpage.c for details -rcTabPageDialog DIALOGEX 0, 0, 100, 100 -STYLE DS_CONTROL | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_CONTROLPARENT -BEGIN - // nothing -END - -// this is for our custom DirectWrite-based font dialog (see fontdialog.cpp) -// this is based on the "New Font Dialog with Syslink" in Microsoft's font.dlg -// LONGTERM look at localization -// LONGTERM make it look tighter and nicer like the real one, including the actual heights of the font family and style comboboxes -rcFontDialog DIALOGEX 13, 54, 243, 200 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_3DLOOK -CAPTION "Font" -FONT 9, "Segoe UI" -BEGIN - LTEXT "&Font:", -1, 7, 7, 98, 9 - COMBOBOX rcFontFamilyCombobox, 7, 16, 98, 76, - CBS_SIMPLE | CBS_AUTOHSCROLL | CBS_DISABLENOSCROLL | - CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_HASSTRINGS - - LTEXT "Font st&yle:", -1, 114, 7, 74, 9 - COMBOBOX rcFontStyleCombobox, 114, 16, 74, 76, - CBS_SIMPLE | CBS_AUTOHSCROLL | CBS_DISABLENOSCROLL | - WS_VSCROLL | WS_TABSTOP | CBS_HASSTRINGS - - LTEXT "&Size:", -1, 198, 7, 36, 9 - COMBOBOX rcFontSizeCombobox, 198, 16, 36, 76, - CBS_SIMPLE | CBS_AUTOHSCROLL | CBS_DISABLENOSCROLL | - CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_HASSTRINGS - - GROUPBOX "Sample", -1, 7, 97, 227, 70, WS_GROUP - CTEXT "AaBbYyZz", rcFontSamplePlacement, 9, 106, 224, 60, SS_NOPREFIX | NOT WS_VISIBLE - - DEFPUSHBUTTON "OK", IDOK, 141, 181, 45, 14, WS_GROUP - PUSHBUTTON "Cancel", IDCANCEL, 190, 181, 45, 14, WS_GROUP -END - -rcColorDialog DIALOGEX 13, 54, 344, 209 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_3DLOOK -CAPTION "Color" -FONT 9, "Segoe UI" -BEGIN - // this size should be big enough to get at least 256x256 on font sizes >= 8 pt - CTEXT "AaBbYyZz", rcColorSVChooser, 7, 7, 195, 195, SS_NOPREFIX | SS_BLACKRECT - - // width is the suggested slider height since this is vertical - CTEXT "AaBbYyZz", rcColorHSlider, 206, 7, 15, 195, SS_NOPREFIX | SS_BLACKRECT - - LTEXT "Preview:", -1, 230, 7, 107, 9, SS_NOPREFIX - CTEXT "AaBbYyZz", rcPreview, 230, 16, 107, 20, SS_NOPREFIX | SS_BLACKRECT - - LTEXT "Opacity:", -1, 230, 45, 107, 9, SS_NOPREFIX - CTEXT "AaBbYyZz", rcOpacitySlider, 230, 54, 107, 15, SS_NOPREFIX | SS_BLACKRECT - - LTEXT "&H:", rcHLabel, 230, 81, 8, 8 - EDITTEXT rcH, 238, 78, 30, 14, ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP, WS_EX_CLIENTEDGE - LTEXT "&S:", rcSLabel, 230, 95, 8, 8 - EDITTEXT rcS, 238, 92, 30, 14, ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP, WS_EX_CLIENTEDGE - LTEXT "&V:", rcVLabel, 230, 109, 8, 8 - EDITTEXT rcV, 238, 106, 30, 14, ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP, WS_EX_CLIENTEDGE - - LTEXT "&R:", rcRLabel, 277, 81, 8, 8 - EDITTEXT rcRDouble, 285, 78, 30, 14, ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP, WS_EX_CLIENTEDGE - EDITTEXT rcRInt, 315, 78, 20, 14, ES_LEFT | ES_AUTOHSCROLL | ES_NUMBER | WS_TABSTOP, WS_EX_CLIENTEDGE - LTEXT "&G:", rcGLabel, 277, 95, 8, 8 - EDITTEXT rcGDouble, 285, 92, 30, 14, ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP, WS_EX_CLIENTEDGE - EDITTEXT rcGInt, 315, 92, 20, 14, ES_LEFT | ES_AUTOHSCROLL | ES_NUMBER | WS_TABSTOP, WS_EX_CLIENTEDGE - LTEXT "&B:", rcBLabel, 277, 109, 8, 8 - EDITTEXT rcBDouble, 285, 106, 30, 14, ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP, WS_EX_CLIENTEDGE - EDITTEXT rcBInt, 315, 106, 20, 14, ES_LEFT | ES_AUTOHSCROLL | ES_NUMBER | WS_TABSTOP, WS_EX_CLIENTEDGE - LTEXT "&A:", rcALabel, 277, 123, 8, 8 - EDITTEXT rcADouble, 285, 120, 30, 14, ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP, WS_EX_CLIENTEDGE - EDITTEXT rcAInt, 315, 120, 20, 14, ES_LEFT | ES_AUTOHSCROLL | ES_NUMBER | WS_TABSTOP, WS_EX_CLIENTEDGE - - LTEXT "He&x:", rcHexLabel, 269, 146, 16, 8 - EDITTEXT rcHex, 285, 143, 50, 14, ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP, WS_EX_CLIENTEDGE - - DEFPUSHBUTTON "OK", IDOK, 243, 188, 45, 14, WS_GROUP - PUSHBUTTON "Cancel", IDCANCEL, 292, 188, 45, 14, WS_GROUP -END diff --git a/deps/libui/windows/separator.cpp b/deps/libui/windows/separator.cpp deleted file mode 100644 index e123e2756f..0000000000 --- a/deps/libui/windows/separator.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// 20 may 2015 -#include "uipriv_windows.hpp" - -// references: -// - http://stackoverflow.com/questions/2892703/how-do-i-draw-separators -// - https://msdn.microsoft.com/en-us/library/windows/desktop/dn742405%28v=vs.85%29.aspx - -struct uiSeparator { - uiWindowsControl c; - HWND hwnd; - BOOL vertical; -}; - -uiWindowsControlAllDefaults(uiSeparator) - -// via https://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx -#define separatorHeight 1 - -// TODO -#define separatorWidth 1 - -static void uiSeparatorMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiSeparator *s = uiSeparator(c); - uiWindowsSizing sizing; - int x, y; - - *width = 1; // TODO - *height = 1; - x = separatorWidth; - y = separatorHeight; - uiWindowsGetSizing(s->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); - if (s->vertical) - *width = x; - else - *height = y; -} - -uiSeparator *uiNewHorizontalSeparator(void) -{ - uiSeparator *s; - - uiWindowsNewControl(uiSeparator, s); - - s->hwnd = uiWindowsEnsureCreateControlHWND(0, - L"static", L"", - SS_ETCHEDHORZ, - hInstance, NULL, - TRUE); - - return s; -} - -uiSeparator *uiNewVerticalSeparator(void) -{ - uiSeparator *s; - - uiWindowsNewControl(uiSeparator, s); - - s->hwnd = uiWindowsEnsureCreateControlHWND(0, - L"static", L"", - SS_ETCHEDHORZ, - hInstance, NULL, - TRUE); - s->vertical = TRUE; - - return s; -} diff --git a/deps/libui/windows/sizing.cpp b/deps/libui/windows/sizing.cpp deleted file mode 100644 index a6d25d6ef3..0000000000 --- a/deps/libui/windows/sizing.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// 14 may 2015 -#include "uipriv_windows.hpp" - -// TODO rework the error handling -void getSizing(HWND hwnd, uiWindowsSizing *sizing, HFONT font) -{ - HDC dc; - HFONT prevfont; - TEXTMETRICW tm; - SIZE size; - - dc = GetDC(hwnd); - if (dc == NULL) - logLastError(L"error getting DC"); - prevfont = (HFONT) SelectObject(dc, font); - if (prevfont == NULL) - logLastError(L"error loading control font into device context"); - - ZeroMemory(&tm, sizeof (TEXTMETRICW)); - if (GetTextMetricsW(dc, &tm) == 0) - logLastError(L"error getting text metrics"); - if (GetTextExtentPoint32W(dc, L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &size) == 0) - logLastError(L"error getting text extent point"); - - sizing->BaseX = (int) ((size.cx / 26 + 1) / 2); - sizing->BaseY = (int) tm.tmHeight; - sizing->InternalLeading = tm.tmInternalLeading; - - if (SelectObject(dc, prevfont) != font) - logLastError(L"error restoring previous font into device context"); - if (ReleaseDC(hwnd, dc) == 0) - logLastError(L"error releasing DC"); -} - -void uiWindowsGetSizing(HWND hwnd, uiWindowsSizing *sizing) -{ - return getSizing(hwnd, sizing, hMessageFont); -} - -#define dlgUnitsToX(dlg, baseX) MulDiv((dlg), (baseX), 4) -#define dlgUnitsToY(dlg, baseY) MulDiv((dlg), (baseY), 8) - -void uiWindowsSizingDlgUnitsToPixels(uiWindowsSizing *sizing, int *x, int *y) -{ - if (x != NULL) - *x = dlgUnitsToX(*x, sizing->BaseX); - if (y != NULL) - *y = dlgUnitsToY(*y, sizing->BaseY); -} - -// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing and https://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx -// this X value is really only for buttons but I don't see a better one :/ -#define winXPadding 4 -#define winYPadding 4 - -void uiWindowsSizingStandardPadding(uiWindowsSizing *sizing, int *x, int *y) -{ - if (x != NULL) - *x = dlgUnitsToX(winXPadding, sizing->BaseX); - if (y != NULL) - *y = dlgUnitsToY(winYPadding, sizing->BaseY); -} diff --git a/deps/libui/windows/slider.cpp b/deps/libui/windows/slider.cpp deleted file mode 100644 index 5c671dda09..0000000000 --- a/deps/libui/windows/slider.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// 20 may 2015 -#include "uipriv_windows.hpp" - -struct uiSlider { - uiWindowsControl c; - HWND hwnd; - void (*onChanged)(uiSlider *, void *); - void *onChangedData; -}; - -static BOOL onWM_HSCROLL(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) -{ - uiSlider *s = uiSlider(c); - - (*(s->onChanged))(s, s->onChangedData); - *lResult = 0; - return TRUE; -} - -static void uiSliderDestroy(uiControl *c) -{ - uiSlider *s = uiSlider(c); - - uiWindowsUnregisterWM_HSCROLLHandler(s->hwnd); - uiWindowsEnsureDestroyWindow(s->hwnd); - uiFreeControl(uiControl(s)); -} - -uiWindowsControlAllDefaultsExceptDestroy(uiSlider); - -// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define sliderWidth 107 /* this is actually the shorter progress bar width, but Microsoft doesn't indicate a width */ -#define sliderHeight 15 - -static void uiSliderMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiSlider *s = uiSlider(c); - uiWindowsSizing sizing; - int x, y; - - x = sliderWidth; - y = sliderHeight; - uiWindowsGetSizing(s->hwnd, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); - *width = x; - *height = y; -} - -static void defaultOnChanged(uiSlider *s, void *data) -{ - // do nothing -} - -int uiSliderValue(uiSlider *s) -{ - return SendMessageW(s->hwnd, TBM_GETPOS, 0, 0); -} - -void uiSliderSetValue(uiSlider *s, int value) -{ - // don't use TBM_SETPOSNOTIFY; that triggers an event - SendMessageW(s->hwnd, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) value); -} - -void uiSliderOnChanged(uiSlider *s, void (*f)(uiSlider *, void *), void *data) -{ - s->onChanged = f; - s->onChangedData = data; -} - -uiSlider *uiNewSlider(int min, int max) -{ - uiSlider *s; - int temp; - - if (min >= max) { - temp = min; - min = max; - max = temp; - } - - uiWindowsNewControl(uiSlider, s); - - s->hwnd = uiWindowsEnsureCreateControlHWND(0, - TRACKBAR_CLASSW, L"", - TBS_HORZ | TBS_TOOLTIPS | TBS_TRANSPARENTBKGND | WS_TABSTOP, - hInstance, NULL, - TRUE); - - uiWindowsRegisterWM_HSCROLLHandler(s->hwnd, onWM_HSCROLL, uiControl(s)); - uiSliderOnChanged(s, defaultOnChanged, NULL); - - SendMessageW(s->hwnd, TBM_SETRANGEMIN, (WPARAM) TRUE, (LPARAM) min); - SendMessageW(s->hwnd, TBM_SETRANGEMAX, (WPARAM) TRUE, (LPARAM) max); - SendMessageW(s->hwnd, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) min); - - return s; -} diff --git a/deps/libui/windows/spinbox.cpp b/deps/libui/windows/spinbox.cpp deleted file mode 100644 index 2b6af66d33..0000000000 --- a/deps/libui/windows/spinbox.cpp +++ /dev/null @@ -1,215 +0,0 @@ -// 8 april 2015 -#include "uipriv_windows.hpp" - -struct uiSpinbox { - uiWindowsControl c; - HWND hwnd; - HWND edit; - HWND updown; - void (*onChanged)(uiSpinbox *, void *); - void *onChangedData; - BOOL inhibitChanged; -}; - -// utility functions - -static int value(uiSpinbox *s) -{ - BOOL neededCap = FALSE; - LRESULT val; - - // This verifies the value put in, capping it automatically. - // We don't need to worry about checking for an error; that flag should really be called "did we have to cap?". - // We DO need to set the value in case of a cap though. - val = SendMessageW(s->updown, UDM_GETPOS32, 0, (LPARAM) (&neededCap)); - if (neededCap) { - s->inhibitChanged = TRUE; - SendMessageW(s->updown, UDM_SETPOS32, 0, (LPARAM) val); - s->inhibitChanged = FALSE; - } - return val; -} - -// control implementation - -static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) -{ - uiSpinbox *s = (uiSpinbox *) c; - WCHAR *wtext; - - if (code != EN_CHANGE) - return FALSE; - if (s->inhibitChanged) - return FALSE; - // We want to allow typing negative numbers; the natural way to do so is to start with a -. - // However, if we just have the code below, the up-down will catch the bare - and reject it. - // Let's fix that. - // This won't handle leading spaces, but spaces aren't allowed *anyway*. - wtext = windowText(s->edit); - if (wcscmp(wtext, L"-") == 0) { - uiFree(wtext); - return TRUE; - } - uiFree(wtext); - // value() does the work for us - value(s); - (*(s->onChanged))(s, s->onChangedData); - return TRUE; -} - -static void uiSpinboxDestroy(uiControl *c) -{ - uiSpinbox *s = uiSpinbox(c); - - uiWindowsUnregisterWM_COMMANDHandler(s->edit); - uiWindowsEnsureDestroyWindow(s->updown); - uiWindowsEnsureDestroyWindow(s->edit); - uiWindowsEnsureDestroyWindow(s->hwnd); - uiFreeControl(uiControl(s)); -} - -// TODO SyncEnableState -uiWindowsControlAllDefaultsExceptDestroy(uiSpinbox) - -// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -// TODO reduce this? -#define entryWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary */ -#define entryHeight 14 - -static void uiSpinboxMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiSpinbox *s = uiSpinbox(c); - uiWindowsSizing sizing; - int x, y; - - x = entryWidth; - y = entryHeight; - // note that we go by the edit here - uiWindowsGetSizing(s->edit, &sizing); - uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); - *width = x; - *height = y; -} - -static void spinboxArrangeChildren(uiSpinbox *s) -{ - LONG_PTR controlID; - HWND insertAfter; - - controlID = 100; - insertAfter = NULL; - uiWindowsEnsureAssignControlIDZOrder(s->edit, &controlID, &insertAfter); - uiWindowsEnsureAssignControlIDZOrder(s->updown, &controlID, &insertAfter); -} - -// an up-down control will only properly position itself the first time -// stupidly, there are no messages to force a size calculation, nor can I seem to reset the buddy window to force a new position -// alas, we have to make a new up/down control each time :( -static void recreateUpDown(uiSpinbox *s) -{ - BOOL preserve = FALSE; - int current; - // Microsoft's commctrl.h says to use this type - INT min, max; - - if (s->updown != NULL) { - preserve = TRUE; - current = value(s); - SendMessageW(s->updown, UDM_GETRANGE32, (WPARAM) (&min), (LPARAM) (&max)); - uiWindowsEnsureDestroyWindow(s->updown); - } - s->inhibitChanged = TRUE; - s->updown = CreateWindowExW(0, - UPDOWN_CLASSW, L"", - // no WS_VISIBLE; we set visibility ourselves - // up-down control should not be a tab stop - WS_CHILD | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_HOTTRACK | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, - // this is important; it's necessary for autosizing to work - 0, 0, 0, 0, - s->hwnd, NULL, hInstance, NULL); - if (s->updown == NULL) - logLastError(L"error creating updown"); - SendMessageW(s->updown, UDM_SETBUDDY, (WPARAM) (s->edit), 0); - if (preserve) { - SendMessageW(s->updown, UDM_SETRANGE32, (WPARAM) min, (LPARAM) max); - SendMessageW(s->updown, UDM_SETPOS32, 0, (LPARAM) current); - } - // preserve the Z-order - spinboxArrangeChildren(s); - // TODO properly show/enable - ShowWindow(s->updown, SW_SHOW); - s->inhibitChanged = FALSE; -} - -static void spinboxRelayout(uiSpinbox *s) -{ - RECT r; - - // make the edit fill the container first; the new updown will resize it - uiWindowsEnsureGetClientRect(s->hwnd, &r); - uiWindowsEnsureMoveWindowDuringResize(s->edit, r.left, r.top, r.right - r.left, r.bottom - r.top); - recreateUpDown(s); -} - -static void defaultOnChanged(uiSpinbox *s, void *data) -{ - // do nothing -} - -int uiSpinboxValue(uiSpinbox *s) -{ - return value(s); -} - -void uiSpinboxSetValue(uiSpinbox *s, int value) -{ - s->inhibitChanged = TRUE; - SendMessageW(s->updown, UDM_SETPOS32, 0, (LPARAM) value); - s->inhibitChanged = FALSE; -} - -void uiSpinboxOnChanged(uiSpinbox *s, void (*f)(uiSpinbox *, void *), void *data) -{ - s->onChanged = f; - s->onChangedData = data; -} - -static void onResize(uiWindowsControl *c) -{ - spinboxRelayout(uiSpinbox(c)); -} - -uiSpinbox *uiNewSpinbox(int min, int max) -{ - uiSpinbox *s; - int temp; - - if (min >= max) { - temp = min; - min = max; - max = temp; - } - - uiWindowsNewControl(uiSpinbox, s); - - s->hwnd = uiWindowsMakeContainer(uiWindowsControl(s), onResize); - - s->edit = uiWindowsEnsureCreateControlHWND(WS_EX_CLIENTEDGE, - L"edit", L"", - // don't use ES_NUMBER; it doesn't allow typing in a leading - - ES_AUTOHSCROLL | ES_LEFT | ES_NOHIDESEL | WS_TABSTOP, - hInstance, NULL, - TRUE); - uiWindowsEnsureSetParentHWND(s->edit, s->hwnd); - - uiWindowsRegisterWM_COMMANDHandler(s->edit, onWM_COMMAND, uiControl(s)); - uiSpinboxOnChanged(s, defaultOnChanged, NULL); - - recreateUpDown(s); - s->inhibitChanged = TRUE; - SendMessageW(s->updown, UDM_SETRANGE32, (WPARAM) min, (LPARAM) max); - SendMessageW(s->updown, UDM_SETPOS32, 0, (LPARAM) min); - s->inhibitChanged = FALSE; - - return s; -} diff --git a/deps/libui/windows/stddialogs.cpp b/deps/libui/windows/stddialogs.cpp deleted file mode 100644 index 89d26bacd7..0000000000 --- a/deps/libui/windows/stddialogs.cpp +++ /dev/null @@ -1,133 +0,0 @@ -// 22 may 2015 -#include "uipriv_windows.hpp" - -// TODO document all this is what we want -// TODO do the same for font and color buttons - -// notes: -// - FOS_SUPPORTSTREAMABLEITEMS doesn't seem to be supported on windows vista, or at least not with the flags we use -// - even with FOS_NOVALIDATE the dialogs will reject invalid filenames (at least on Vista, anyway) -// - lack of FOS_NOREADONLYRETURN doesn't seem to matter on Windows 7 - -// TODO -// - http://blogs.msdn.com/b/wpfsdk/archive/2006/10/26/uncommon-dialogs--font-chooser-and-color-picker-dialogs.aspx -// - when a dialog is active, tab navigation in other windows stops working -// - when adding uiOpenFolder(), use IFileDialog as well - https://msdn.microsoft.com/en-us/library/windows/desktop/bb762115%28v=vs.85%29.aspx - -#define windowHWND(w) ((HWND) uiControlHandle(uiControl(w))) - -char *commonItemDialog(HWND parent, REFCLSID clsid, REFIID iid, FILEOPENDIALOGOPTIONS optsadd) -{ - IFileDialog *d = NULL; - FILEOPENDIALOGOPTIONS opts; - IShellItem *result = NULL; - WCHAR *wname = NULL; - char *name = NULL; - HRESULT hr; - - hr = CoCreateInstance(clsid, - NULL, CLSCTX_INPROC_SERVER, - iid, (LPVOID *) (&d)); - if (hr != S_OK) { - logHRESULT(L"error creating common item dialog", hr); - // always return NULL on error - goto out; - } - hr = d->GetOptions(&opts); - if (hr != S_OK) { - logHRESULT(L"error getting current options", hr); - goto out; - } - opts |= optsadd; - // the other platforms don't check read-only; we won't either - opts &= ~FOS_NOREADONLYRETURN; - hr = d->SetOptions(opts); - if (hr != S_OK) { - logHRESULT(L"error setting options", hr); - goto out; - } - hr = d->Show(parent); - if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) - // cancelled; return NULL like we have ready - goto out; - if (hr != S_OK) { - logHRESULT(L"error showing dialog", hr); - goto out; - } - hr = d->GetResult(&result); - if (hr != S_OK) { - logHRESULT(L"error getting dialog result", hr); - goto out; - } - hr = result->GetDisplayName(SIGDN_FILESYSPATH, &wname); - if (hr != S_OK) { - logHRESULT(L"error getting filename", hr); - goto out; - } - name = toUTF8(wname); - -out: - if (wname != NULL) - CoTaskMemFree(wname); - if (result != NULL) - result->Release(); - if (d != NULL) - d->Release(); - return name; -} - -char *uiOpenFile(uiWindow *parent) -{ - char *res; - - disableAllWindowsExcept(parent); - res = commonItemDialog(windowHWND(parent), - CLSID_FileOpenDialog, IID_IFileOpenDialog, - FOS_NOCHANGEDIR | FOS_ALLNONSTORAGEITEMS | FOS_NOVALIDATE | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_SHAREAWARE | FOS_NOTESTFILECREATE | FOS_NODEREFERENCELINKS | FOS_FORCESHOWHIDDEN | FOS_DEFAULTNOMINIMODE); - enableAllWindowsExcept(parent); - return res; -} - -char *uiSaveFile(uiWindow *parent) -{ - char *res; - - disableAllWindowsExcept(parent); - res = commonItemDialog(windowHWND(parent), - CLSID_FileSaveDialog, IID_IFileSaveDialog, - FOS_OVERWRITEPROMPT | FOS_NOCHANGEDIR | FOS_ALLNONSTORAGEITEMS | FOS_NOVALIDATE | FOS_SHAREAWARE | FOS_NOTESTFILECREATE | FOS_NODEREFERENCELINKS | FOS_FORCESHOWHIDDEN | FOS_DEFAULTNOMINIMODE); - enableAllWindowsExcept(parent); - return res; -} - -// TODO switch to TaskDialogIndirect()? - -static void msgbox(HWND parent, const char *title, const char *description, TASKDIALOG_COMMON_BUTTON_FLAGS buttons, PCWSTR icon) -{ - WCHAR *wtitle, *wdescription; - HRESULT hr; - - wtitle = toUTF16(title); - wdescription = toUTF16(description); - - hr = TaskDialog(parent, NULL, NULL, wtitle, wdescription, buttons, icon, NULL); - if (hr != S_OK) - logHRESULT(L"error showing task dialog", hr); - - uiFree(wdescription); - uiFree(wtitle); -} - -void uiMsgBox(uiWindow *parent, const char *title, const char *description) -{ - disableAllWindowsExcept(parent); - msgbox(windowHWND(parent), title, description, TDCBF_OK_BUTTON, NULL); - enableAllWindowsExcept(parent); -} - -void uiMsgBoxError(uiWindow *parent, const char *title, const char *description) -{ - disableAllWindowsExcept(parent); - msgbox(windowHWND(parent), title, description, TDCBF_OK_BUTTON, TD_ERROR_ICON); - enableAllWindowsExcept(parent); -} diff --git a/deps/libui/windows/tab.cpp b/deps/libui/windows/tab.cpp deleted file mode 100644 index 365f5a1fa9..0000000000 --- a/deps/libui/windows/tab.cpp +++ /dev/null @@ -1,287 +0,0 @@ -// 16 may 2015 -#include "uipriv_windows.hpp" - -// You don't add controls directly to a tab control on Windows; instead you make them siblings and swap between them on a TCN_SELCHANGING/TCN_SELCHANGE notification pair. -// In addition, you use dialogs because they can be textured properly; other controls cannot. (Things will look wrong if the tab background in the current theme is fancy if you just use the tab background by itself; see http://stackoverflow.com/questions/30087540/why-are-my-programss-tab-controls-rendering-their-background-in-a-blocky-way-b.) - -struct uiTab { - uiWindowsControl c; - HWND hwnd; // of the outer container - HWND tabHWND; // of the tab control itself - std::vector *pages; - HWND parent; -}; - -// utility functions - -static LRESULT curpage(uiTab *t) -{ - return SendMessageW(t->tabHWND, TCM_GETCURSEL, 0, 0); -} - -static struct tabPage *tabPage(uiTab *t, int i) -{ - return (*(t->pages))[i]; -} - -static void tabPageRect(uiTab *t, RECT *r) -{ - // this rect needs to be in parent window coordinates, but TCM_ADJUSTRECT wants a window rect, which is screen coordinates - // because we have each page as a sibling of the tab, use the tab's own rect as the input rect - uiWindowsEnsureGetWindowRect(t->tabHWND, r); - SendMessageW(t->tabHWND, TCM_ADJUSTRECT, (WPARAM) FALSE, (LPARAM) r); - // and get it in terms of the container instead of the screen - mapWindowRect(NULL, t->hwnd, r); -} - -static void tabRelayout(uiTab *t) -{ - struct tabPage *page; - RECT r; - - // first move the tab control itself - uiWindowsEnsureGetClientRect(t->hwnd, &r); - uiWindowsEnsureMoveWindowDuringResize(t->tabHWND, r.left, r.top, r.right - r.left, r.bottom - r.top); - - // then the current page - if (t->pages->size() == 0) - return; - page = tabPage(t, curpage(t)); - tabPageRect(t, &r); - uiWindowsEnsureMoveWindowDuringResize(page->hwnd, r.left, r.top, r.right - r.left, r.bottom - r.top); -} - -static void showHidePage(uiTab *t, LRESULT which, int hide) -{ - struct tabPage *page; - - if (which == (LRESULT) (-1)) - return; - page = tabPage(t, which); - if (hide) - ShowWindow(page->hwnd, SW_HIDE); - else { - ShowWindow(page->hwnd, SW_SHOW); - // we only resize the current page, so we have to resize it; before we can do that, we need to make sure we are of the right size - uiWindowsControlMinimumSizeChanged(uiWindowsControl(t)); - } -} - -// control implementation - -static BOOL onWM_NOTIFY(uiControl *c, HWND hwnd, NMHDR *nm, LRESULT *lResult) -{ - uiTab *t = uiTab(c); - - if (nm->code != TCN_SELCHANGING && nm->code != TCN_SELCHANGE) - return FALSE; - showHidePage(t, curpage(t), nm->code == TCN_SELCHANGING); - *lResult = 0; - if (nm->code == TCN_SELCHANGING) - *lResult = FALSE; - return TRUE; -} - -static void uiTabDestroy(uiControl *c) -{ - uiTab *t = uiTab(c); - uiControl *child; - - for (struct tabPage *&page : *(t->pages)) { - child = page->child; - tabPageDestroy(page); - if (child != NULL) { - uiControlSetParent(child, NULL); - uiControlDestroy(child); - } - } - delete t->pages; - uiWindowsUnregisterWM_NOTIFYHandler(t->tabHWND); - uiWindowsEnsureDestroyWindow(t->tabHWND); - uiWindowsEnsureDestroyWindow(t->hwnd); - uiFreeControl(uiControl(t)); -} - -uiWindowsControlDefaultHandle(uiTab) -uiWindowsControlDefaultParent(uiTab) -uiWindowsControlDefaultSetParent(uiTab) -uiWindowsControlDefaultToplevel(uiTab) -uiWindowsControlDefaultVisible(uiTab) -uiWindowsControlDefaultShow(uiTab) -uiWindowsControlDefaultHide(uiTab) -uiWindowsControlDefaultEnabled(uiTab) -uiWindowsControlDefaultEnable(uiTab) -uiWindowsControlDefaultDisable(uiTab) - -static void uiTabSyncEnableState(uiWindowsControl *c, int enabled) -{ - uiTab *t = uiTab(c); - - if (uiWindowsShouldStopSyncEnableState(uiWindowsControl(t), enabled)) - return; - EnableWindow(t->tabHWND, enabled); - for (struct tabPage *&page : *(t->pages)) - if (page->child != NULL) - uiWindowsControlSyncEnableState(uiWindowsControl(page->child), enabled); -} - -uiWindowsControlDefaultSetParentHWND(uiTab) - -static void uiTabMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiTab *t = uiTab(c); - int pagewid, pageht; - struct tabPage *page; - RECT r; - - // only consider the current page - pagewid = 0; - pageht = 0; - if (t->pages->size() != 0) { - page = tabPage(t, curpage(t)); - tabPageMinimumSize(page, &pagewid, &pageht); - } - - r.left = 0; - r.top = 0; - r.right = pagewid; - r.bottom = pageht; - // this also includes the tabs themselves - SendMessageW(t->tabHWND, TCM_ADJUSTRECT, (WPARAM) TRUE, (LPARAM) (&r)); - *width = r.right - r.left; - *height = r.bottom - r.top; -} - -static void uiTabMinimumSizeChanged(uiWindowsControl *c) -{ - uiTab *t = uiTab(c); - - if (uiWindowsControlTooSmall(uiWindowsControl(t))) { - uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl(t)); - return; - } - tabRelayout(t); -} - -uiWindowsControlDefaultLayoutRect(uiTab) -uiWindowsControlDefaultAssignControlIDZOrder(uiTab) - -static void uiTabChildVisibilityChanged(uiWindowsControl *c) -{ - // TODO eliminate the redundancy - uiWindowsControlMinimumSizeChanged(c); -} - -static void tabArrangePages(uiTab *t) -{ - LONG_PTR controlID = 100; - HWND insertAfter = NULL; - - // TODO is this first or last? - uiWindowsEnsureAssignControlIDZOrder(t->tabHWND, &controlID, &insertAfter); - for (struct tabPage *&page : *(t->pages)) - uiWindowsEnsureAssignControlIDZOrder(page->hwnd, &controlID, &insertAfter); -} - -void uiTabAppend(uiTab *t, const char *name, uiControl *child) -{ - uiTabInsertAt(t, name, t->pages->size(), child); -} - -void uiTabInsertAt(uiTab *t, const char *name, int n, uiControl *child) -{ - struct tabPage *page; - LRESULT hide, show; - TCITEMW item; - WCHAR *wname; - - // see below - hide = curpage(t); - - if (child != NULL) - uiControlSetParent(child, uiControl(t)); - - page = newTabPage(child); - uiWindowsEnsureSetParentHWND(page->hwnd, t->hwnd); - t->pages->insert(t->pages->begin() + n, page); - tabArrangePages(t); - - ZeroMemory(&item, sizeof (TCITEMW)); - item.mask = TCIF_TEXT; - wname = toUTF16(name); - item.pszText = wname; - if (SendMessageW(t->tabHWND, TCM_INSERTITEM, (WPARAM) n, (LPARAM) (&item)) == (LRESULT) -1) - logLastError(L"error adding tab to uiTab"); - uiFree(wname); - - // we need to do this because adding the first tab doesn't send a TCN_SELCHANGE; it just shows the page - show = curpage(t); - if (show != hide) { - showHidePage(t, hide, 1); - showHidePage(t, show, 0); - } -} - -void uiTabDelete(uiTab *t, int n) -{ - struct tabPage *page; - - // first delete the tab from the tab control - // if this is the current tab, no tab will be selected, which is good - if (SendMessageW(t->tabHWND, TCM_DELETEITEM, (WPARAM) n, 0) == FALSE) - logLastError(L"error deleting uiTab tab"); - - // now delete the page itself - page = tabPage(t, n); - if (page->child != NULL) - uiControlSetParent(page->child, NULL); - tabPageDestroy(page); - t->pages->erase(t->pages->begin() + n); -} - -int uiTabNumPages(uiTab *t) -{ - return t->pages->size(); -} - -int uiTabMargined(uiTab *t, int n) -{ - return tabPage(t, n)->margined; -} - -void uiTabSetMargined(uiTab *t, int n, int margined) -{ - struct tabPage *page; - - page = tabPage(t, n); - page->margined = margined; - // even if the page doesn't have a child it might still have a new minimum size with margins; this is the easiest way to verify it - uiWindowsControlMinimumSizeChanged(uiWindowsControl(t)); -} - -static void onResize(uiWindowsControl *c) -{ - tabRelayout(uiTab(c)); -} - -uiTab *uiNewTab(void) -{ - uiTab *t; - - uiWindowsNewControl(uiTab, t); - - t->hwnd = uiWindowsMakeContainer(uiWindowsControl(t), onResize); - - t->tabHWND = uiWindowsEnsureCreateControlHWND(0, - WC_TABCONTROLW, L"", - TCS_TOOLTIPS | WS_TABSTOP, - hInstance, NULL, - TRUE); - uiWindowsEnsureSetParentHWND(t->tabHWND, t->hwnd); - - uiWindowsRegisterWM_NOTIFYHandler(t->tabHWND, onWM_NOTIFY, uiControl(t)); - - t->pages = new std::vector; - - return t; -} diff --git a/deps/libui/windows/tabpage.cpp b/deps/libui/windows/tabpage.cpp deleted file mode 100644 index 5283ce7909..0000000000 --- a/deps/libui/windows/tabpage.cpp +++ /dev/null @@ -1,131 +0,0 @@ -// 30 may 2015 -#include "uipriv_windows.hpp" - -// TODO refine error handling - -// from http://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx -#define tabMargin 7 - -static void tabPageMargins(struct tabPage *tp, int *mx, int *my) -{ - uiWindowsSizing sizing; - - *mx = 0; - *my = 0; - if (!tp->margined) - return; - uiWindowsGetSizing(tp->hwnd, &sizing); - *mx = tabMargin; - *my = tabMargin; - uiWindowsSizingDlgUnitsToPixels(&sizing, mx, my); -} - -static void tabPageRelayout(struct tabPage *tp) -{ - RECT r; - int mx, my; - HWND child; - - if (tp->child == NULL) - return; - uiWindowsEnsureGetClientRect(tp->hwnd, &r); - tabPageMargins(tp, &mx, &my); - r.left += mx; - r.top += my; - r.right -= mx; - r.bottom -= my; - child = (HWND) uiControlHandle(tp->child); - uiWindowsEnsureMoveWindowDuringResize(child, r.left, r.top, r.right - r.left, r.bottom - r.top); -} - -// dummy dialog procedure; see below for details -// let's handle parent messages here to avoid needing to subclass -// TODO do we need to handle DM_GETDEFID/DM_SETDEFID here too because of the ES_WANTRETURN stuff at http://blogs.msdn.com/b/oldnewthing/archive/2007/08/20/4470527.aspx? what about multiple default buttons (TODO)? -// TODO we definitely need to do something about edit message handling; it does a fake close of our parent on pressing escape, causing uiWindow to stop responding to maximizes but still respond to events and then die horribly on destruction -static INT_PTR CALLBACK dlgproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - struct tabPage *tp; - LRESULT lResult; - - if (uMsg == WM_INITDIALOG) { - tp = (struct tabPage *) lParam; - tp->hwnd = hwnd; - SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR) tp); - return TRUE; - } - if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE) { - SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, (LONG_PTR) lResult); - return TRUE; - } - if (uMsg == WM_WINDOWPOSCHANGED) { - tp = (struct tabPage *) GetWindowLongPtrW(hwnd, DWLP_USER); - tabPageRelayout(tp); - // pretend the dialog hasn't handled this just in case it needs to do something special - return FALSE; - } - - // unthemed dialogs don't respond to WM_PRINTCLIENT - // fortunately they don't have any special painting - if (uMsg == WM_PRINTCLIENT) { - // don't worry about the return value; hopefully DefWindowProcW() caught it (if not the dialog procedure itself) - // we COULD paint the dialog background brush ourselves but meh, it works - SendMessageW(hwnd, WM_ERASEBKGND, wParam, lParam); - // and pretend we did nothing just so the themed dialog can still paint its content - // TODO see if w ecan avoid erasing the background in this case in the first place, or if we even need to - return FALSE; - } - - return FALSE; -} - -struct tabPage *newTabPage(uiControl *child) -{ - struct tabPage *tp; - HRESULT hr; - - tp = uiNew(struct tabPage); - - // unfortunately this needs to be a proper dialog for EnableThemeDialogTexture() to work; CreateWindowExW() won't suffice - if (CreateDialogParamW(hInstance, MAKEINTRESOURCE(rcTabPageDialog), - utilWindow, dlgproc, (LPARAM) tp) == NULL) - logLastError(L"error creating tab page"); - - tp->child = child; - if (tp->child != NULL) { - uiWindowsEnsureSetParentHWND((HWND) uiControlHandle(tp->child), tp->hwnd); - uiWindowsControlAssignSoleControlIDZOrder(uiWindowsControl(tp->child)); - } - - hr = EnableThemeDialogTexture(tp->hwnd, ETDT_ENABLE | ETDT_USETABTEXTURE | ETDT_ENABLETAB); - if (hr != S_OK) - logHRESULT(L"error setting tab page background", hr); - // continue anyway; it'll look wrong but eh - - // and start the tab page hidden - ShowWindow(tp->hwnd, SW_HIDE); - - return tp; -} - -void tabPageDestroy(struct tabPage *tp) -{ - // don't destroy the child with the page - if (tp->child != NULL) - uiWindowsControlSetParentHWND(uiWindowsControl(tp->child), NULL); - // don't call EndDialog(); that's for the DialogBox() family of functions instead of CreateDialog() - uiWindowsEnsureDestroyWindow(tp->hwnd); - uiFree(tp); -} - -void tabPageMinimumSize(struct tabPage *tp, int *width, int *height) -{ - int mx, my; - - *width = 0; - *height = 0; - if (tp->child != NULL) - uiWindowsControlMinimumSize(uiWindowsControl(tp->child), width, height); - tabPageMargins(tp, &mx, &my); - *width += 2 * mx; - *height += 2 * my; -} diff --git a/deps/libui/windows/text.cpp b/deps/libui/windows/text.cpp deleted file mode 100644 index af79fb8078..0000000000 --- a/deps/libui/windows/text.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// 9 april 2015 -#include "uipriv_windows.hpp" - -WCHAR *windowTextAndLen(HWND hwnd, LRESULT *len) -{ - LRESULT n; - WCHAR *text; - - n = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0); - if (len != NULL) - *len = n; - // WM_GETTEXTLENGTH does not include the null terminator - text = (WCHAR *) uiAlloc((n + 1) * sizeof (WCHAR), "WCHAR[]"); - // note the comparison: the size includes the null terminator, but the return does not - if (GetWindowTextW(hwnd, text, n + 1) != n) { - logLastError(L"error getting window text"); - // on error, return an empty string to be safe - *text = L'\0'; - if (len != NULL) - *len = 0; - } - return text; -} - -WCHAR *windowText(HWND hwnd) -{ - return windowTextAndLen(hwnd, NULL); -} - -void setWindowText(HWND hwnd, WCHAR *wtext) -{ - if (SetWindowTextW(hwnd, wtext) == 0) - logLastError(L"error setting window text"); -} - -void uiFreeText(char *text) -{ - uiFree(text); -} - -int uiWindowsWindowTextWidth(HWND hwnd) -{ - LRESULT len; - WCHAR *text; - HDC dc; - HFONT prevfont; - SIZE size; - - size.cx = 0; - size.cy = 0; - - text = windowTextAndLen(hwnd, &len); - if (len == 0) // no text; nothing to do - goto noTextOrError; - - // now we can do the calculations - dc = GetDC(hwnd); - if (dc == NULL) { - logLastError(L"error getting DC"); - // on any error, assume no text - goto noTextOrError; - } - prevfont = (HFONT) SelectObject(dc, hMessageFont); - if (prevfont == NULL) { - logLastError(L"error loading control font into device context"); - ReleaseDC(hwnd, dc); - goto noTextOrError; - } - if (GetTextExtentPoint32W(dc, text, len, &size) == 0) { - logLastError(L"error getting text extent point"); - // continue anyway, assuming size is 0 - size.cx = 0; - size.cy = 0; - } - // continue on errors; we got what we want - if (SelectObject(dc, prevfont) != hMessageFont) - logLastError(L"error restoring previous font into device context"); - if (ReleaseDC(hwnd, dc) == 0) - logLastError(L"error releasing DC"); - - uiFree(text); - return size.cx; - -noTextOrError: - uiFree(text); - return 0; -} - -char *uiWindowsWindowText(HWND hwnd) -{ - WCHAR *wtext; - char *text; - - wtext = windowText(hwnd); - text = toUTF8(wtext); - uiFree(wtext); - return text; -} - -void uiWindowsSetWindowText(HWND hwnd, const char *text) -{ - WCHAR *wtext; - - wtext = toUTF16(text); - setWindowText(hwnd, wtext); - uiFree(wtext); -} diff --git a/deps/libui/windows/uipriv_windows.hpp b/deps/libui/windows/uipriv_windows.hpp deleted file mode 100644 index 6ffe09f1ad..0000000000 --- a/deps/libui/windows/uipriv_windows.hpp +++ /dev/null @@ -1,164 +0,0 @@ -// 21 april 2016 -#include "winapi.hpp" -#include "../ui.h" -#include "../ui_windows.h" -#include "../common/uipriv.h" -#include "resources.hpp" -#include "compilerver.hpp" - -// ui internal window messages -enum { - // redirected WM_COMMAND and WM_NOTIFY - msgCOMMAND = WM_APP + 0x40, // start offset just to be safe - msgNOTIFY, - msgHSCROLL, - msgQueued, - msgD2DScratchPaint, - msgD2DScratchLButtonDown, -}; - -// alloc.cpp -extern void initAlloc(void); -extern void uninitAlloc(void); - -// events.cpp -extern BOOL runWM_COMMAND(WPARAM wParam, LPARAM lParam, LRESULT *lResult); -extern BOOL runWM_NOTIFY(WPARAM wParam, LPARAM lParam, LRESULT *lResult); -extern BOOL runWM_HSCROLL(WPARAM wParam, LPARAM lParam, LRESULT *lResult); -extern void issueWM_WININICHANGE(WPARAM wParam, LPARAM lParam); - -// utf16.cpp -#define emptyUTF16() ((WCHAR *) uiAlloc(1 * sizeof (WCHAR), "WCHAR[]")) -#define emptyUTF8() ((char *) uiAlloc(1 * sizeof (char), "char[]")) -extern WCHAR *toUTF16(const char *str); -extern char *toUTF8(const WCHAR *wstr); -extern WCHAR *utf16dup(const WCHAR *orig); -extern WCHAR *strf(const WCHAR *format, ...); -extern WCHAR *vstrf(const WCHAR *format, va_list ap); -extern char *LFtoCRLF(const char *lfonly); -extern void CRLFtoLF(char *s); -extern WCHAR *ftoutf16(double d); -extern WCHAR *itoutf16(int i); - -// debug.cpp -// see http://stackoverflow.com/questions/14421656/is-there-widely-available-wide-character-variant-of-file -// we turn __LINE__ into a string because PRIiMAX can't be converted to a wide string in MSVC (it seems to be defined as "ll" "i" according to the compiler errors) -// also note the use of __FUNCTION__ here; __func__ doesn't seem to work for some reason -#define _ws2(m) L ## m -#define _ws(m) _ws2(m) -#define _ws2n(m) L ## #m -#define _wsn(m) _ws2n(m) -#define debugargs const WCHAR *file, const WCHAR *line, const WCHAR *func -extern HRESULT _logLastError(debugargs, const WCHAR *s); -#ifdef _MSC_VER -#define logLastError(s) _logLastError(_ws(__FILE__), _wsn(__LINE__), _ws(__FUNCTION__), s) -#else -#define logLastError(s) _logLastError(_ws(__FILE__), _wsn(__LINE__), L"TODO none of the function name macros are macros in MinGW", s) -#endif -extern HRESULT _logHRESULT(debugargs, const WCHAR *s, HRESULT hr); -#ifdef _MSC_VER -#define logHRESULT(s, hr) _logHRESULT(_ws(__FILE__), _wsn(__LINE__), _ws(__FUNCTION__), s, hr) -#else -#define logHRESULT(s, hr) _logHRESULT(_ws(__FILE__), _wsn(__LINE__), L"TODO none of the function name macros are macros in MinGW", s, hr) -#endif - -// winutil.cpp -extern int windowClassOf(HWND hwnd, ...); -extern void mapWindowRect(HWND from, HWND to, RECT *r); -extern DWORD getStyle(HWND hwnd); -extern void setStyle(HWND hwnd, DWORD style); -extern DWORD getExStyle(HWND hwnd); -extern void setExStyle(HWND hwnd, DWORD exstyle); -extern void clientSizeToWindowSize(HWND hwnd, int *width, int *height, BOOL hasMenubar); -extern HWND parentOf(HWND child); -extern HWND parentToplevel(HWND child); -extern void setWindowInsertAfter(HWND hwnd, HWND insertAfter); -extern HWND getDlgItem(HWND hwnd, int id); -extern void invalidateRect(HWND hwnd, RECT *r, BOOL erase); - -// text.cpp -extern WCHAR *windowTextAndLen(HWND hwnd, LRESULT *len); -extern WCHAR *windowText(HWND hwnd); -extern void setWindowText(HWND hwnd, WCHAR *wtext); - -// init.cpp -extern HINSTANCE hInstance; -extern int nCmdShow; -extern HFONT hMessageFont; -extern HBRUSH hollowBrush; -extern uiInitOptions options; - -// utilwin.cpp -extern HWND utilWindow; -extern const char *initUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor); -extern void uninitUtilWindow(void); - -// main.cpp -extern int registerMessageFilter(void); -extern void unregisterMessageFilter(void); - -// parent.cpp -extern void paintContainerBackground(HWND hwnd, HDC dc, RECT *paintRect); -extern BOOL handleParentMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult); - -// d2dscratch.cpp -extern ATOM registerD2DScratchClass(HICON hDefaultIcon, HCURSOR hDefaultCursor); -extern void unregisterD2DScratchClass(void); -extern HWND newD2DScratch(HWND parent, RECT *rect, HMENU controlID, SUBCLASSPROC subclass, DWORD_PTR subclassData); - -// area.cpp -#define areaClass L"libui_uiAreaClass" -extern ATOM registerAreaClass(HICON, HCURSOR); -extern void unregisterArea(void); - -// areaevents.cpp -extern BOOL areaFilter(MSG *); - -// window.cpp -extern ATOM registerWindowClass(HICON, HCURSOR); -extern void unregisterWindowClass(void); -extern void ensureMinimumWindowSize(uiWindow *); -extern void disableAllWindowsExcept(uiWindow *which); -extern void enableAllWindowsExcept(uiWindow *which); - -// container.cpp -#define containerClass L"libui_uiContainerClass" -extern ATOM initContainer(HICON, HCURSOR); -extern void uninitContainer(void); - -// tabpage.cpp -struct tabPage { - HWND hwnd; - uiControl *child; - BOOL margined; -}; -extern struct tabPage *newTabPage(uiControl *child); -extern void tabPageDestroy(struct tabPage *tp); -extern void tabPageMinimumSize(struct tabPage *tp, int *width, int *height); - -// colordialog.cpp -struct colorDialogRGBA { - double r; - double g; - double b; - double a; -}; -extern BOOL showColorDialog(HWND parent, struct colorDialogRGBA *c); - -// sizing.cpp -extern void getSizing(HWND hwnd, uiWindowsSizing *sizing, HFONT font); - -// graphemes.cpp -extern size_t *graphemes(WCHAR *msg); - -// TODO move into a dedicated file abibugs.cpp when we rewrite the drawing code -extern D2D1_SIZE_F realGetSize(ID2D1RenderTarget *rt); - - - - -// TODO -#include "_uipriv_migrate.hpp" - -// draw.cpp -extern ID2D1DCRenderTarget *makeHDCRenderTarget(HDC dc, RECT *r); diff --git a/deps/libui/windows/utf16.cpp b/deps/libui/windows/utf16.cpp deleted file mode 100644 index 98954d0ada..0000000000 --- a/deps/libui/windows/utf16.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// 21 april 2016 -#include "uipriv_windows.hpp" - -// see http://stackoverflow.com/a/29556509/3408572 - -#define MBTWC(str, wstr, bufsiz) MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, bufsiz) - -WCHAR *toUTF16(const char *str) -{ - WCHAR *wstr; - int n; - - if (*str == '\0') // empty string - return emptyUTF16(); - n = MBTWC(str, NULL, 0); - if (n == 0) { - logLastError(L"error figuring out number of characters to convert to"); - return emptyUTF16(); - } - wstr = (WCHAR *) uiAlloc(n * sizeof (WCHAR), "WCHAR[]"); - if (MBTWC(str, wstr, n) != n) { - logLastError(L"error converting from UTF-8 to UTF-16"); - // and return an empty string - *wstr = L'\0'; - } - return wstr; -} - -#define WCTMB(wstr, str, bufsiz) WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, bufsiz, NULL, NULL) - -char *toUTF8(const WCHAR *wstr) -{ - char *str; - int n; - - if (*wstr == L'\0') // empty string - return emptyUTF8(); - n = WCTMB(wstr, NULL, 0); - if (n == 0) { - logLastError(L"error figuring out number of characters to convert to"); - return emptyUTF8(); - } - str = (char *) uiAlloc(n * sizeof (char), "char[]"); - if (WCTMB(wstr, str, n) != n) { - logLastError(L"error converting from UTF-16 to UTF-8"); - // and return an empty string - *str = '\0'; - } - return str; -} - -WCHAR *utf16dup(const WCHAR *orig) -{ - WCHAR *out; - size_t len; - - len = wcslen(orig); - out = (WCHAR *) uiAlloc((len + 1) * sizeof (WCHAR), "WCHAR[]"); - wcscpy_s(out, len + 1, orig); - return out; -} - -WCHAR *strf(const WCHAR *format, ...) -{ - va_list ap; - WCHAR *str; - - va_start(ap, format); - str = vstrf(format, ap); - va_end(ap); - return str; -} - -WCHAR *vstrf(const WCHAR *format, va_list ap) -{ - va_list ap2; - WCHAR *buf; - size_t n; - - if (*format == L'\0') - return emptyUTF16(); - - va_copy(ap2, ap); - n = _vscwprintf(format, ap2); - va_end(ap2); - n++; // terminating L'\0' - - buf = (WCHAR *) uiAlloc(n * sizeof (WCHAR), "WCHAR[]"); - // includes terminating L'\0' according to example in https://msdn.microsoft.com/en-us/library/xa1a1a6z.aspx - vswprintf_s(buf, n, format, ap); - - return buf; -} - -// Let's shove these utility routines here too. -// Prerequisite: lfonly is UTF-8. -char *LFtoCRLF(const char *lfonly) -{ - char *crlf; - size_t i, len; - char *out; - - len = strlen(lfonly); - crlf = (char *) uiAlloc((len * 2 + 1) * sizeof (char), "char[]"); - out = crlf; - for (i = 0; i < len; i++) { - if (*lfonly == '\n') - *crlf++ = '\r'; - *crlf++ = *lfonly++; - } - *crlf = '\0'; - return out; -} - -// Prerequisite: s is UTF-8. -void CRLFtoLF(char *s) -{ - char *t = s; - - for (; *s != '\0'; s++) { - // be sure to preserve \rs that are genuinely there - if (*s == '\r' && *(s + 1) == '\n') - continue; - *t++ = *s; - } - *t = '\0'; - // pad out the rest of t, just to be safe - while (t != s) - *t++ = '\0'; -} - -// std::to_string() always uses %f; we want %g -// fortunately std::iostream seems to use %g by default so -WCHAR *ftoutf16(double d) -{ - std::wostringstream ss; - std::wstring s; - - ss << d; - s = ss.str(); // to be safe - return utf16dup(s.c_str()); -} - -// to complement the above -WCHAR *itoutf16(int i) -{ - std::wostringstream ss; - std::wstring s; - - ss << i; - s = ss.str(); // to be safe - return utf16dup(s.c_str()); -} diff --git a/deps/libui/windows/utilwin.cpp b/deps/libui/windows/utilwin.cpp deleted file mode 100644 index 414ae83aba..0000000000 --- a/deps/libui/windows/utilwin.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// 14 may 2015 -#include "uipriv_windows.hpp" - -// The utility window is a special window that performs certain tasks internal to libui. -// It is not a message-only window, and it is always hidden and disabled. -// Its roles: -// - It is the initial parent of all controls. When a control loses its parent, it also becomes that control's parent. -// - It handles WM_QUERYENDSESSION and console end session requests. -// - It handles WM_WININICHANGE and forwards the message to any child windows that request it. -// - It handles executing functions queued to run by uiQueueMain(). - -#define utilWindowClass L"libui_utilWindowClass" - -HWND utilWindow; - -static LRESULT CALLBACK utilWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - void (*qf)(void *); - LRESULT lResult; - - if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE) - return lResult; - switch (uMsg) { - case WM_QUERYENDSESSION: - // TODO block handler - if (shouldQuit()) { - uiQuit(); - return TRUE; - } - return FALSE; - case WM_WININICHANGE: - issueWM_WININICHANGE(wParam, lParam); - return 0; - case msgQueued: - qf = (void (*)(void *)) wParam; - (*qf)((void *) lParam); - return 0; - } - return DefWindowProcW(hwnd, uMsg, wParam, lParam); -} - -const char *initUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor) -{ - WNDCLASSW wc; - - ZeroMemory(&wc, sizeof (WNDCLASSW)); - wc.lpszClassName = utilWindowClass; - wc.lpfnWndProc = utilWindowWndProc; - wc.hInstance = hInstance; - wc.hIcon = hDefaultIcon; - wc.hCursor = hDefaultCursor; - wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); - if (RegisterClass(&wc) == 0) - // see init.cpp for an explanation of the =s - return "=registering utility window class"; - - utilWindow = CreateWindowExW(0, - utilWindowClass, L"libui utility window", - WS_OVERLAPPEDWINDOW, - 0, 0, 100, 100, - NULL, NULL, hInstance, NULL); - if (utilWindow == NULL) - return "=creating utility window"; - // and just to be safe - EnableWindow(utilWindow, FALSE); - - return NULL; -} - -void uninitUtilWindow(void) -{ - if (DestroyWindow(utilWindow) == 0) - logLastError(L"error destroying utility window"); - if (UnregisterClass(utilWindowClass, hInstance) == 0) - logLastError(L"error unregistering utility window class"); -} diff --git a/deps/libui/windows/winapi.hpp b/deps/libui/windows/winapi.hpp deleted file mode 100644 index 86aba5d7eb..0000000000 --- a/deps/libui/windows/winapi.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// 31 may 2015 -#define UNICODE -#define _UNICODE -#define STRICT -#define STRICT_TYPED_ITEMIDS - -// see https://github.com/golang/go/issues/9916#issuecomment-74812211 -// TODO get rid of this -#define INITGUID - -// for the manifest -#ifndef _UI_STATIC -#define ISOLATION_AWARE_ENABLED 1 -#endif - -// get Windows version right; right now Windows Vista -// unless otherwise stated, all values from Microsoft's sdkddkver.h -// TODO is all of this necessary? how is NTDDI_VERSION used? -// TODO plaform update sp2 -#define WINVER 0x0600 /* from Microsoft's winnls.h */ -#define _WIN32_WINNT 0x0600 -#define _WIN32_WINDOWS 0x0600 /* from Microsoft's pdh.h */ -#define _WIN32_IE 0x0700 -#define NTDDI_VERSION 0x06000000 - -#include - -// Microsoft's resource compiler will segfault if we feed it headers it was not designed to handle -#ifndef RC_INVOKED -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#endif diff --git a/deps/libui/windows/window.cpp b/deps/libui/windows/window.cpp deleted file mode 100644 index 9cf13a25e8..0000000000 --- a/deps/libui/windows/window.cpp +++ /dev/null @@ -1,533 +0,0 @@ -// 27 april 2015 -#include "uipriv_windows.hpp" - -#define windowClass L"libui_uiWindowClass" - -struct uiWindow { - uiWindowsControl c; - HWND hwnd; - HMENU menubar; - uiControl *child; - BOOL shownOnce; - int visible; - int (*onClosing)(uiWindow *, void *); - void *onClosingData; - int margined; - BOOL hasMenubar; - void (*onContentSizeChanged)(uiWindow *, void *); - void *onContentSizeChangedData; - BOOL changingSize; - int fullscreen; - WINDOWPLACEMENT fsPrevPlacement; - int borderless; -}; - -// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing -#define windowMargin 7 - -static void windowMargins(uiWindow *w, int *mx, int *my) -{ - uiWindowsSizing sizing; - - *mx = 0; - *my = 0; - if (!w->margined) - return; - uiWindowsGetSizing(w->hwnd, &sizing); - *mx = windowMargin; - *my = windowMargin; - uiWindowsSizingDlgUnitsToPixels(&sizing, mx, my); -} - -static void windowRelayout(uiWindow *w) -{ - int x, y, width, height; - RECT r; - int mx, my; - HWND child; - - if (w->child == NULL) - return; - x = 0; - y = 0; - uiWindowsEnsureGetClientRect(w->hwnd, &r); - width = r.right - r.left; - height = r.bottom - r.top; - windowMargins(w, &mx, &my); - x += mx; - y += my; - width -= 2 * mx; - height -= 2 * my; - child = (HWND) uiControlHandle(w->child); - uiWindowsEnsureMoveWindowDuringResize(child, x, y, width, height); -} - -static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - LONG_PTR ww; - uiWindow *w; - CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam; - WINDOWPOS *wp = (WINDOWPOS *) lParam; - MINMAXINFO *mmi = (MINMAXINFO *) lParam; - int width, height; - LRESULT lResult; - - ww = GetWindowLongPtrW(hwnd, GWLP_USERDATA); - if (ww == 0) { - if (uMsg == WM_CREATE) - SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) (cs->lpCreateParams)); - // fall through to DefWindowProc() anyway - return DefWindowProcW(hwnd, uMsg, wParam, lParam); - } - w = uiWindow((void *) ww); - if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE) - return lResult; - switch (uMsg) { - case WM_COMMAND: - // not a menu - if (lParam != 0) - break; - if (HIWORD(wParam) != 0) - break; - runMenuEvent(LOWORD(wParam), uiWindow(w)); - return 0; - case WM_WINDOWPOSCHANGED: - if ((wp->flags & SWP_NOSIZE) != 0) - break; - if (w->onContentSizeChanged != NULL) // TODO figure out why this is happening too early - if (!w->changingSize) - (*(w->onContentSizeChanged))(w, w->onContentSizeChangedData); - windowRelayout(w); - return 0; - case WM_GETMINMAXINFO: - // ensure the user cannot resize the window smaller than its minimum size - lResult = DefWindowProcW(hwnd, uMsg, wParam, lParam); - uiWindowsControlMinimumSize(uiWindowsControl(w), &width, &height); - // width and height are in client coordinates; ptMinTrackSize is in window coordinates - clientSizeToWindowSize(w->hwnd, &width, &height, w->hasMenubar); - mmi->ptMinTrackSize.x = width; - mmi->ptMinTrackSize.y = height; - return lResult; - case WM_PRINTCLIENT: - // we do no special painting; just erase the background - // don't worry about the return value; we let DefWindowProcW() handle this message - SendMessageW(hwnd, WM_ERASEBKGND, wParam, lParam); - return 0; - case WM_CLOSE: - if ((*(w->onClosing))(w, w->onClosingData)) - uiControlDestroy(uiControl(w)); - return 0; // we destroyed it already - } - return DefWindowProcW(hwnd, uMsg, wParam, lParam); -} - -ATOM registerWindowClass(HICON hDefaultIcon, HCURSOR hDefaultCursor) -{ - WNDCLASSW wc; - - ZeroMemory(&wc, sizeof (WNDCLASSW)); - wc.lpszClassName = windowClass; - wc.lpfnWndProc = windowWndProc; - wc.hInstance = hInstance; - wc.hIcon = hDefaultIcon; - wc.hCursor = hDefaultCursor; - wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); - return RegisterClassW(&wc); -} - -void unregisterWindowClass(void) -{ - if (UnregisterClassW(windowClass, hInstance) == 0) - logLastError(L"error unregistering uiWindow window class"); -} - -static int defaultOnClosing(uiWindow *w, void *data) -{ - return 0; -} - -static void defaultOnPositionContentSizeChanged(uiWindow *w, void *data) -{ - // do nothing -} - -static std::map windows; - -static void uiWindowDestroy(uiControl *c) -{ - uiWindow *w = uiWindow(c); - - // first hide ourselves - ShowWindow(w->hwnd, SW_HIDE); - // now destroy the child - if (w->child != NULL) { - uiControlSetParent(w->child, NULL); - uiControlDestroy(w->child); - } - // now free the menubar, if any - if (w->menubar != NULL) - freeMenubar(w->menubar); - // and finally free ourselves - windows.erase(w); - uiWindowsEnsureDestroyWindow(w->hwnd); - uiFreeControl(uiControl(w)); -} - -uiWindowsControlDefaultHandle(uiWindow) - -uiControl *uiWindowParent(uiControl *c) -{ - return NULL; -} - -void uiWindowSetParent(uiControl *c, uiControl *parent) -{ - uiUserBugCannotSetParentOnToplevel("uiWindow"); -} - -static int uiWindowToplevel(uiControl *c) -{ - return 1; -} - -// TODO initial state of windows is hidden; ensure this here and make it so on other platforms -static int uiWindowVisible(uiControl *c) -{ - uiWindow *w = uiWindow(c); - - return w->visible; -} - -static void uiWindowShow(uiControl *c) -{ - uiWindow *w = uiWindow(c); - - w->visible = 1; - // just in case the window's minimum size wasn't recalculated already - ensureMinimumWindowSize(w); - if (w->shownOnce) { - ShowWindow(w->hwnd, SW_SHOW); - return; - } - w->shownOnce = TRUE; - // make sure the child is the correct size - uiWindowsControlMinimumSizeChanged(uiWindowsControl(w)); - ShowWindow(w->hwnd, nCmdShow); - if (UpdateWindow(w->hwnd) == 0) - logLastError(L"error calling UpdateWindow() after showing uiWindow for the first time"); -} - -static void uiWindowHide(uiControl *c) -{ - uiWindow *w = uiWindow(c); - - w->visible = 0; - ShowWindow(w->hwnd, SW_HIDE); -} - -// TODO we don't want the window to be disabled completely; that would prevent it from being moved! ...would it? -uiWindowsControlDefaultEnabled(uiWindow) -uiWindowsControlDefaultEnable(uiWindow) -uiWindowsControlDefaultDisable(uiWindow) -// TODO we need to do something about undocumented fields in the OS control types -uiWindowsControlDefaultSyncEnableState(uiWindow) -// TODO -uiWindowsControlDefaultSetParentHWND(uiWindow) - -static void uiWindowMinimumSize(uiWindowsControl *c, int *width, int *height) -{ - uiWindow *w = uiWindow(c); - int mx, my; - - *width = 0; - *height = 0; - if (w->child != NULL) - uiWindowsControlMinimumSize(uiWindowsControl(w->child), width, height); - windowMargins(w, &mx, &my); - *width += 2 * mx; - *height += 2 * my; -} - -static void uiWindowMinimumSizeChanged(uiWindowsControl *c) -{ - uiWindow *w = uiWindow(c); - - if (uiWindowsControlTooSmall(uiWindowsControl(w))) { - // TODO figure out what to do with this function - // maybe split it into two so WM_GETMINMAXINFO can use it? - ensureMinimumWindowSize(w); - return; - } - // otherwise we only need to re-layout everything - windowRelayout(w); -} - -static void uiWindowLayoutRect(uiWindowsControl *c, RECT *r) -{ - uiWindow *w = uiWindow(c); - - // the layout rect is the client rect in this case - uiWindowsEnsureGetClientRect(w->hwnd, r); -} - -uiWindowsControlDefaultAssignControlIDZOrder(uiWindow) - -static void uiWindowChildVisibilityChanged(uiWindowsControl *c) -{ - // TODO eliminate the redundancy - uiWindowsControlMinimumSizeChanged(c); -} - -char *uiWindowTitle(uiWindow *w) -{ - return uiWindowsWindowText(w->hwnd); -} - -void uiWindowSetTitle(uiWindow *w, const char *title) -{ - uiWindowsSetWindowText(w->hwnd, title); - // don't queue resize; the caption isn't part of what affects layout and sizing of the client area (it'll be ellipsized if too long) -} - -// this is used for both fullscreening and centering -// see also https://blogs.msdn.microsoft.com/oldnewthing/20100412-00/?p=14353 and https://blogs.msdn.microsoft.com/oldnewthing/20050505-04/?p=35703 -static void windowMonitorRect(HWND hwnd, RECT *r) -{ - HMONITOR monitor; - MONITORINFO mi; - - monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY); - ZeroMemory(&mi, sizeof (MONITORINFO)); - mi.cbSize = sizeof (MONITORINFO); - if (GetMonitorInfoW(monitor, &mi) == 0) { - logLastError(L"error getting window monitor rect"); - // default to SM_CXSCREEN x SM_CYSCREEN to be safe - r->left = 0; - r->top = 0; - r->right = GetSystemMetrics(SM_CXSCREEN); - r->bottom = GetSystemMetrics(SM_CYSCREEN); - return; - } - *r = mi.rcMonitor; -} - -void uiWindowContentSize(uiWindow *w, int *width, int *height) -{ - RECT r; - - uiWindowsEnsureGetClientRect(w->hwnd, &r); - *width = r.right - r.left; - *height = r.bottom - r.top; -} - -// TODO should this disallow too small? -void uiWindowSetContentSize(uiWindow *w, int width, int height) -{ - w->changingSize = TRUE; - clientSizeToWindowSize(w->hwnd, &width, &height, w->hasMenubar); - if (SetWindowPos(w->hwnd, NULL, 0, 0, width, height, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER) == 0) - logLastError(L"error resizing window"); - w->changingSize = FALSE; -} - -int uiWindowFullscreen(uiWindow *w) -{ - return w->fullscreen; -} - -void uiWindowSetFullscreen(uiWindow *w, int fullscreen) -{ - RECT r; - - if (w->fullscreen && fullscreen) - return; - if (!w->fullscreen && !fullscreen) - return; - w->fullscreen = fullscreen; - w->changingSize = TRUE; - if (w->fullscreen) { - ZeroMemory(&(w->fsPrevPlacement), sizeof (WINDOWPLACEMENT)); - w->fsPrevPlacement.length = sizeof (WINDOWPLACEMENT); - if (GetWindowPlacement(w->hwnd, &(w->fsPrevPlacement)) == 0) - logLastError(L"error getting old window placement"); - windowMonitorRect(w->hwnd, &r); - setStyle(w->hwnd, getStyle(w->hwnd) & ~WS_OVERLAPPEDWINDOW); - if (SetWindowPos(w->hwnd, HWND_TOP, - r.left, r.top, - r.right - r.left, r.bottom - r.top, - SWP_FRAMECHANGED | SWP_NOOWNERZORDER) == 0) - logLastError(L"error making window fullscreen"); - } else { - if (!w->borderless) // keep borderless until that is turned off - setStyle(w->hwnd, getStyle(w->hwnd) | WS_OVERLAPPEDWINDOW); - if (SetWindowPlacement(w->hwnd, &(w->fsPrevPlacement)) == 0) - logLastError(L"error leaving fullscreen"); - if (SetWindowPos(w->hwnd, NULL, - 0, 0, 0, 0, - SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER) == 0) - logLastError(L"error restoring window border after fullscreen"); - } - w->changingSize = FALSE; -} - -void uiWindowOnContentSizeChanged(uiWindow *w, void (*f)(uiWindow *, void *), void *data) -{ - w->onContentSizeChanged = f; - w->onContentSizeChangedData = data; -} - -void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *, void *), void *data) -{ - w->onClosing = f; - w->onClosingData = data; -} - -int uiWindowBorderless(uiWindow *w) -{ - return w->borderless; -} - -// TODO window should move to the old client position and should not have the extra space the borders left behind -// TODO extract the relevant styles from WS_OVERLAPPEDWINDOW? -void uiWindowSetBorderless(uiWindow *w, int borderless) -{ - w->borderless = borderless; - if (w->borderless) - setStyle(w->hwnd, getStyle(w->hwnd) & ~WS_OVERLAPPEDWINDOW); - else - if (!w->fullscreen) // keep borderless until leaving fullscreen - setStyle(w->hwnd, getStyle(w->hwnd) | WS_OVERLAPPEDWINDOW); -} - -void uiWindowSetChild(uiWindow *w, uiControl *child) -{ - if (w->child != NULL) { - uiControlSetParent(w->child, NULL); - uiWindowsControlSetParentHWND(uiWindowsControl(w->child), NULL); - } - w->child = child; - if (w->child != NULL) { - uiControlSetParent(w->child, uiControl(w)); - uiWindowsControlSetParentHWND(uiWindowsControl(w->child), w->hwnd); - uiWindowsControlAssignSoleControlIDZOrder(uiWindowsControl(w->child)); - windowRelayout(w); - } -} - -int uiWindowMargined(uiWindow *w) -{ - return w->margined; -} - -void uiWindowSetMargined(uiWindow *w, int margined) -{ - w->margined = margined; - windowRelayout(w); -} - -// see http://blogs.msdn.com/b/oldnewthing/archive/2003/09/11/54885.aspx and http://blogs.msdn.com/b/oldnewthing/archive/2003/09/13/54917.aspx -// TODO use clientSizeToWindowSize() -static void setClientSize(uiWindow *w, int width, int height, BOOL hasMenubar, DWORD style, DWORD exstyle) -{ - RECT window; - - window.left = 0; - window.top = 0; - window.right = width; - window.bottom = height; - if (AdjustWindowRectEx(&window, style, hasMenubar, exstyle) == 0) - logLastError(L"error getting real window coordinates"); - if (hasMenubar) { - RECT temp; - - temp = window; - temp.bottom = 0x7FFF; // infinite height - SendMessageW(w->hwnd, WM_NCCALCSIZE, (WPARAM) FALSE, (LPARAM) (&temp)); - window.bottom += temp.top; - } - if (SetWindowPos(w->hwnd, NULL, 0, 0, window.right - window.left, window.bottom - window.top, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER) == 0) - logLastError(L"error resizing window"); -} - -uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar) -{ - uiWindow *w; - WCHAR *wtitle; - BOOL hasMenubarBOOL; - - uiWindowsNewControl(uiWindow, w); - - hasMenubarBOOL = FALSE; - if (hasMenubar) - hasMenubarBOOL = TRUE; - w->hasMenubar = hasMenubarBOOL; - -#define style WS_OVERLAPPEDWINDOW -#define exstyle 0 - - wtitle = toUTF16(title); - w->hwnd = CreateWindowExW(exstyle, - windowClass, wtitle, - style, - CW_USEDEFAULT, CW_USEDEFAULT, - // use the raw width and height for now - // this will get CW_USEDEFAULT (hopefully) predicting well - // even if it doesn't, we're adjusting it later - width, height, - NULL, NULL, hInstance, w); - if (w->hwnd == NULL) - logLastError(L"error creating window"); - uiFree(wtitle); - - if (hasMenubar) { - w->menubar = makeMenubar(); - if (SetMenu(w->hwnd, w->menubar) == 0) - logLastError(L"error giving menu to window"); - } - - // and use the proper size - setClientSize(w, width, height, hasMenubarBOOL, style, exstyle); - - uiWindowOnClosing(w, defaultOnClosing, NULL); - uiWindowOnContentSizeChanged(w, defaultOnPositionContentSizeChanged, NULL); - - windows[w] = true; - return w; -} - -// this cannot queue a resize because it's called by the resize handler -void ensureMinimumWindowSize(uiWindow *w) -{ - int width, height; - RECT r; - - uiWindowsControlMinimumSize(uiWindowsControl(w), &width, &height); - uiWindowsEnsureGetClientRect(w->hwnd, &r); - if (width < (r.right - r.left)) // preserve width if larger - width = r.right - r.left; - if (height < (r.bottom - r.top)) // preserve height if larger - height = r.bottom - r.top; - clientSizeToWindowSize(w->hwnd, &width, &height, w->hasMenubar); - if (SetWindowPos(w->hwnd, NULL, 0, 0, width, height, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER) == 0) - logLastError(L"error resizing window"); -} - -void disableAllWindowsExcept(uiWindow *which) -{ - for (auto &w : windows) { - if (w.first == which) - continue; - EnableWindow(w.first->hwnd, FALSE); - } -} - -void enableAllWindowsExcept(uiWindow *which) -{ - for (auto &w : windows) { - if (w.first == which) - continue; - if (!uiControlEnabled(uiControl(w.first))) - continue; - EnableWindow(w.first->hwnd, TRUE); - } -} diff --git a/deps/libui/windows/winpublic.cpp b/deps/libui/windows/winpublic.cpp deleted file mode 100644 index 397a3b54c9..0000000000 --- a/deps/libui/windows/winpublic.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// 6 april 2015 -#include "uipriv_windows.hpp" - -void uiWindowsEnsureDestroyWindow(HWND hwnd) -{ - if (DestroyWindow(hwnd) == 0) - logLastError(L"error destroying window"); -} - -void uiWindowsEnsureSetParentHWND(HWND hwnd, HWND parent) -{ - if (parent == NULL) - parent = utilWindow; - if (SetParent(hwnd, parent) == 0) - logLastError(L"error setting window parent"); -} - -void uiWindowsEnsureAssignControlIDZOrder(HWND hwnd, LONG_PTR *controlID, HWND *insertAfter) -{ - SetWindowLongPtrW(hwnd, GWLP_ID, *controlID); - (*controlID)++; - setWindowInsertAfter(hwnd, *insertAfter); - *insertAfter = hwnd; -} - -void uiWindowsEnsureMoveWindowDuringResize(HWND hwnd, int x, int y, int width, int height) -{ - RECT r; - - r.left = x; - r.top = y; - r.right = x + width; - r.bottom = y + height; - if (SetWindowPos(hwnd, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER) == 0) - logLastError(L"error moving window"); -} - -// do these function even error out in any case other than invalid parameters?! I thought all windows had rects -void uiWindowsEnsureGetClientRect(HWND hwnd, RECT *r) -{ - if (GetClientRect(hwnd, r) == 0) { - logLastError(L"error getting window client rect"); - // zero out the rect on error just to be safe - r->left = 0; - r->top = 0; - r->right = 0; - r->bottom = 0; - } -} - -void uiWindowsEnsureGetWindowRect(HWND hwnd, RECT *r) -{ - if (GetWindowRect(hwnd, r) == 0) { - logLastError(L"error getting window rect"); - // zero out the rect on error just to be safe - r->left = 0; - r->top = 0; - r->right = 0; - r->bottom = 0; - } -} diff --git a/deps/libui/windows/winutil.cpp b/deps/libui/windows/winutil.cpp deleted file mode 100644 index 507c5a3f71..0000000000 --- a/deps/libui/windows/winutil.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// 6 april 2015 -#include "uipriv_windows.hpp" - -// this is a helper function that takes the logic of determining window classes and puts it all in one place -// there are a number of places where we need to know what window class an arbitrary handle has -// theoretically we could use the class atom to avoid a _wcsicmp() -// however, raymond chen advises against this - http://blogs.msdn.com/b/oldnewthing/archive/2004/10/11/240744.aspx (and we're not in control of the Tab class, before you say anything) -// usage: windowClassOf(hwnd, L"class 1", L"class 2", ..., NULL) -int windowClassOf(HWND hwnd, ...) -{ -// MSDN says 256 is the maximum length of a class name; add a few characters just to be safe (because it doesn't say whether this includes the terminating null character) -#define maxClassName 260 - WCHAR classname[maxClassName + 1]; - va_list ap; - WCHAR *curname; - int i; - - if (GetClassNameW(hwnd, classname, maxClassName) == 0) { - logLastError(L"error getting name of window class"); - // assume no match on error, just to be safe - return -1; - } - va_start(ap, hwnd); - i = 0; - for (;;) { - curname = va_arg(ap, WCHAR *); - if (curname == NULL) - break; - if (_wcsicmp(classname, curname) == 0) { - va_end(ap); - return i; - } - i++; - } - // no match - va_end(ap); - return -1; -} - -// wrapper around MapWindowRect() that handles the complex error handling -void mapWindowRect(HWND from, HWND to, RECT *r) -{ - RECT prevr; - DWORD le; - - prevr = *r; - SetLastError(0); - if (MapWindowRect(from, to, r) == 0) { - le = GetLastError(); - SetLastError(le); // just to be safe - if (le != 0) { - logLastError(L"error calling MapWindowRect()"); - // restore original rect on error, just in case - *r = prevr; - } - } -} - -DWORD getStyle(HWND hwnd) -{ - return (DWORD) GetWindowLongPtrW(hwnd, GWL_STYLE); -} - -void setStyle(HWND hwnd, DWORD style) -{ - SetWindowLongPtrW(hwnd, GWL_STYLE, (LONG_PTR) style); -} - -DWORD getExStyle(HWND hwnd) -{ - return (DWORD) GetWindowLongPtrW(hwnd, GWL_EXSTYLE); -} - -void setExStyle(HWND hwnd, DWORD exstyle) -{ - SetWindowLongPtrW(hwnd, GWL_EXSTYLE, (LONG_PTR) exstyle); -} - -// see http://blogs.msdn.com/b/oldnewthing/archive/2003/09/11/54885.aspx and http://blogs.msdn.com/b/oldnewthing/archive/2003/09/13/54917.aspx -void clientSizeToWindowSize(HWND hwnd, int *width, int *height, BOOL hasMenubar) -{ - RECT window; - - window.left = 0; - window.top = 0; - window.right = *width; - window.bottom = *height; - if (AdjustWindowRectEx(&window, getStyle(hwnd), hasMenubar, getExStyle(hwnd)) == 0) { - logLastError(L"error getting adjusted window rect"); - // on error, don't give up; the window will be smaller but whatever - window.left = 0; - window.top = 0; - window.right = *width; - window.bottom = *height; - } - if (hasMenubar) { - RECT temp; - - temp = window; - temp.bottom = 0x7FFF; // infinite height - SendMessageW(hwnd, WM_NCCALCSIZE, (WPARAM) FALSE, (LPARAM) (&temp)); - window.bottom += temp.top; - } - *width = window.right - window.left; - *height = window.bottom - window.top; -} - -HWND parentOf(HWND child) -{ - return GetAncestor(child, GA_PARENT); -} - -HWND parentToplevel(HWND child) -{ - return GetAncestor(child, GA_ROOT); -} - -void setWindowInsertAfter(HWND hwnd, HWND insertAfter) -{ - if (SetWindowPos(hwnd, insertAfter, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE) == 0) - logLastError(L"error reordering window"); -} - -HWND getDlgItem(HWND hwnd, int id) -{ - HWND out; - - out = GetDlgItem(hwnd, id); - if (out == NULL) - logLastError(L"error getting dialog item handle"); - return out; -} - -void invalidateRect(HWND hwnd, RECT *r, BOOL erase) -{ - if (InvalidateRect(hwnd, r, erase) == 0) - logLastError(L"error invalidating window rect"); -} - -// that damn ABI bug is never going to escape me is it -D2D1_SIZE_F realGetSize(ID2D1RenderTarget *rt) -{ -#ifdef _MSC_VER - return rt->GetSize(); -#else - D2D1_SIZE_F size; - typedef D2D1_SIZE_F *(__stdcall ID2D1RenderTarget::* GetSizeF)(D2D1_SIZE_F *); - GetSizeF gs; - - gs = (GetSizeF) (&(rt->GetSize)); - (rt->*gs)(&size); - return size; -#endif -} diff --git a/discord/discord.c b/discord/discord.c index 9b7aa2d3bc..8e1ba00e70 100644 --- a/discord/discord.c +++ b/discord/discord.c @@ -21,14 +21,18 @@ #include "../core.h" #include "../core_info.h" #include "../paths.h" +#include "../playlist.h" #include "../msg_hash.h" static const char* APPLICATION_ID = "475456035851599874"; static int FrustrationLevel = 0; + static int64_t start_time = 0; +static int64_t pause_time = 0; static bool discord_ready = false; +static bool in_menu = false; static unsigned discord_status = 0; DiscordRichPresence discord_presence; @@ -73,51 +77,82 @@ static void handle_discord_join_request(const DiscordUser* request) void discord_update(enum discord_presence presence) { - rarch_system_info_t *system = runloop_get_system_info(); - core_info_t *core_info = NULL; + core_info_t *core_info = NULL; + bool skip = false; + + core_info_get_current_core(&core_info); if (!discord_ready) return; if ( - (discord_status != DISCORD_PRESENCE_MENU) && + (discord_status != DISCORD_PRESENCE_MENU) && (discord_status == presence)) return; - RARCH_LOG("[Discord] updating (%d)\n", presence); - memset(&discord_presence, 0, sizeof(discord_presence)); switch (presence) { case DISCORD_PRESENCE_MENU: - discord_presence.state = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU); - discord_presence.largeImageKey = "base"; - discord_presence.instance = 0; - discord_presence.startTimestamp = start_time; - break; - case DISCORD_PRESENCE_GAME: - core_info_get_current_core(&core_info); + discord_presence.details = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU); + discord_presence.largeImageKey = "base"; + discord_presence.largeImageText = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_CORE); + discord_presence.instance = 0; + in_menu = true; + break; + case DISCORD_PRESENCE_GAME_PAUSED: + discord_presence.smallImageKey = "paused"; + discord_presence.smallImageText = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED); + discord_presence.details = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED); + + pause_time = time(0); + skip = true; + + if (in_menu) + break; + case DISCORD_PRESENCE_GAME: if (core_info) { - const char *system_name = string_replace_substring( - string_to_lower(core_info->core_name), " ", "_"); + const char *system_id = core_info->system_id ? core_info->system_id : "core"; - start_time = time(0); - discord_presence.state = system ? system->info.library_name : "---"; - discord_presence.details = path_basename(path_get(RARCH_PATH_BASENAME)); + char *label = NULL; + playlist_t *current_playlist = playlist_get_cached(); + + if (current_playlist) + playlist_get_index_by_path( + current_playlist, path_get(RARCH_PATH_CONTENT), NULL, &label, NULL, NULL, NULL, NULL); + + if (!label) + label = (char *)path_basename(path_get(RARCH_PATH_BASENAME)); #if 1 - RARCH_LOG("[Discord] system name: %s\n", system_name); + RARCH_LOG("[Discord] current core: %s\n", system_id); + RARCH_LOG("[Discord] current content: %s\n", label); #endif - discord_presence.largeImageKey = system_name; + discord_presence.largeImageKey = system_id; - discord_presence.smallImageKey = "base"; + if (core_info->display_name) + discord_presence.largeImageText = core_info->display_name; - discord_presence.instance = 0; - discord_presence.startTimestamp = start_time; + if (in_menu) + start_time = time(0); + else + start_time = start_time + difftime(time(0), pause_time); + if (!skip) + { + discord_presence.smallImageKey = "playing"; + discord_presence.smallImageText = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING); + discord_presence.startTimestamp = start_time; + discord_presence.details = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME); + } + + discord_presence.state = label; + discord_presence.instance = 0; } + + in_menu = false; break; case DISCORD_PRESENCE_NETPLAY_HOSTING: case DISCORD_PRESENCE_NETPLAY_CLIENT: @@ -125,6 +160,12 @@ void discord_update(enum discord_presence presence) /* TODO/FIXME */ break; } + + if (in_menu && skip) + return; + + RARCH_LOG("[Discord] updating (%d)\n", presence); + Discord_UpdatePresence(&discord_presence); discord_status = presence; } diff --git a/discord/discord.h b/discord/discord.h index 8b5c96050b..84aa87f8ad 100644 --- a/discord/discord.h +++ b/discord/discord.h @@ -34,6 +34,7 @@ enum discord_presence { DISCORD_PRESENCE_MENU = 0, DISCORD_PRESENCE_GAME, + DISCORD_PRESENCE_GAME_PAUSED, DISCORD_PRESENCE_CHEEVO_UNLOCKED, DISCORD_PRESENCE_NETPLAY_HOSTING, DISCORD_PRESENCE_NETPLAY_CLIENT diff --git a/frontend/drivers/platform_darwin.m b/frontend/drivers/platform_darwin.m index 4df8be17df..12a9004f93 100644 --- a/frontend/drivers/platform_darwin.m +++ b/frontend/drivers/platform_darwin.m @@ -292,7 +292,7 @@ static void frontend_darwin_get_os(char *s, size_t len, int *major, int *minor) get_ios_version(major, minor); strlcpy(s, "iOS", len); #elif defined(OSX) -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion]; *major = (int)version.majorVersion; *minor = (int)version.minorVersion; diff --git a/gfx/common/dxgi_common.h b/gfx/common/dxgi_common.h index 32af9b89b2..0323b5d839 100644 --- a/gfx/common/dxgi_common.h +++ b/gfx/common/dxgi_common.h @@ -804,6 +804,7 @@ RETRO_END_DECLS #ifndef PERF_START #define PERF_START() \ + { \ static struct retro_perf_counter perfcounter = { __FUNCTION__ }; \ LARGE_INTEGER start, stop; \ rarch_perf_register(&perfcounter); \ @@ -812,7 +813,8 @@ RETRO_END_DECLS #define PERF_STOP() \ QueryPerformanceCounter(&stop); \ - perfcounter.total += stop.QuadPart - start.QuadPart + perfcounter.total += stop.QuadPart - start.QuadPart; \ + } #endif #else #define PERF_START() diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index 31c7f3d620..7c92a96643 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -1827,7 +1827,10 @@ bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk, VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; info.pfnCallback = vulkan_debug_cb; - vkCreateDebugReportCallbackEXT(vk->context.instance, &info, NULL, &vk->context.debug_callback); + + if (vk->context.instance) + vkCreateDebugReportCallbackEXT(vk->context.instance, &info, NULL, + &vk->context.debug_callback); } RARCH_LOG("[Vulkan]: Enabling Vulkan debug layers.\n"); #endif @@ -1969,11 +1972,12 @@ static bool vulkan_create_display_surface(gfx_ctx_vulkan_data_t *vk, retry: for (dpy = 0; dpy < display_count; dpy++) { + VkDisplayKHR display; if (monitor_index != 0 && (monitor_index - 1) != dpy) continue; - VkDisplayKHR display = displays[dpy].display; - best_mode = VK_NULL_HANDLE; + display = displays[dpy].display; + best_mode = VK_NULL_HANDLE; best_plane = UINT32_MAX; if (vkGetDisplayModePropertiesKHR(vk->context.gpu, @@ -2371,8 +2375,6 @@ void vulkan_present(gfx_ctx_vulkan_data_t *vk, unsigned index) void vulkan_context_destroy(gfx_ctx_vulkan_data_t *vk, bool destroy_surface) { - unsigned i; - if (!vk->context.instance) return; diff --git a/gfx/common/wayland_common.h b/gfx/common/wayland_common.h index e48f450907..3cbedb9048 100644 --- a/gfx/common/wayland_common.h +++ b/gfx/common/wayland_common.h @@ -28,6 +28,16 @@ #define UDEV_KEY_MAX 0x2ff #define UDEV_MAX_KEYS (UDEV_KEY_MAX + 7) / 8 +#define MAX_TOUCHES 16 + +typedef struct +{ + bool active; + int16_t x; + int16_t y; +} wayland_touch_data_t; + + typedef struct input_ctx_wayland_data { /* Wayland uses Linux keysyms. */ @@ -49,6 +59,9 @@ typedef struct input_ctx_wayland_data const input_device_driver_t *joypad; bool blocked; + + wayland_touch_data_t touches[MAX_TOUCHES]; + } input_ctx_wayland_data_t; #endif diff --git a/gfx/common/win32_common.h b/gfx/common/win32_common.h index 7afe7d0dd3..04eeeef936 100644 --- a/gfx/common/win32_common.h +++ b/gfx/common/win32_common.h @@ -63,14 +63,14 @@ void create_gdi_context(HWND hwnd, bool *quit); bool gdi_has_menu_frame(void); -void shader_dlg_params_reload(void); - +#if !defined(__WINRT__) bool win32_window_init(WNDCLASSEX *wndclass, bool fullscreen, const char *class_name); void win32_set_style(MONITORINFOEX *current_mon, HMONITOR *hm_to_use, unsigned *width, unsigned *height, bool fullscreen, bool windowed_full, RECT *rect, RECT *mon_rect, DWORD *style); #endif +#endif void win32_monitor_from_window(void); diff --git a/gfx/display_servers/dispserv_x11.c b/gfx/display_servers/dispserv_x11.c index aeb45e71f0..dbc22ece98 100644 --- a/gfx/display_servers/dispserv_x11.c +++ b/gfx/display_servers/dispserv_x11.c @@ -14,6 +14,8 @@ * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ +#include +#include #include "../video_display_server.h" #include "../common/x11_common.h" @@ -21,9 +23,6 @@ #include "../video_driver.h" /* needed to set refresh rate in set resolution */ #include "../video_crt_switch.h" /* needed to set aspect for low res in linux */ -#include -#include - static char old_mode[150]; static char new_mode[150]; static bool crt_en = false; @@ -99,7 +98,7 @@ static bool x11_set_resolution(void *data, float pixel_clock = 0; char xrandr[250]; char fbset[150]; - char output[150]; + char output[250]; crt_en = true; @@ -205,58 +204,58 @@ static bool x11_set_resolution(void *data, /* create progressive newmode from modline variables */ if (height < 300) { - sprintf(xrandr,"xrandr --newmode \"%dx%d_%0.2f\" %lf %d %d %d %d %d %d %d %d -hsync -vsync", width, height, hz, pixel_clock, width, hfp, hsp, hbp, height, vfp, vsp, vbp); + snprintf(xrandr, sizeof(xrandr), "xrandr --newmode \"%dx%d_%0.2f\" %lf %d %d %d %d %d %d %d %d -hsync -vsync", width, height, hz, pixel_clock, width, hfp, hsp, hbp, height, vfp, vsp, vbp); system(xrandr); } /* create interlaced newmode from modline variables */ if (height > 300) { - sprintf(xrandr,"xrandr --newmode \"%dx%d_%0.2f\" %lf %d %d %d %d %d %d %d %d interlace -hsync -vsync", width, height, hz, pixel_clock, width, hfp, hsp, hbp, height, vfp, vsp, vbp); + snprintf(xrandr, sizeof(xrandr), "xrandr --newmode \"%dx%d_%0.2f\" %lf %d %d %d %d %d %d %d %d interlace -hsync -vsync", width, height, hz, pixel_clock, width, hfp, hsp, hbp, height, vfp, vsp, vbp); system(xrandr); } /* variable for new mode */ - sprintf(new_mode,"%dx%d_%0.2f", width, height, hz); + snprintf(new_mode, sizeof(new_mode), "%dx%d_%0.2f", width, height, hz); /* need to run loops for DVI0 - DVI-2 and VGA0 - VGA-2 outputs to add and delete modes */ for (i =0; i < 3; i++) { - sprintf(output,"xrandr --addmode %s%d %s", "DVI",i ,new_mode); + snprintf(output, sizeof(output), "xrandr --addmode %s%d %s", "DVI",i ,new_mode); system(output); - sprintf(output,"xrandr --delmode %s%d %s", "DVI",i ,old_mode); + snprintf(output, sizeof(output), "xrandr --delmode %s%d %s", "DVI",i ,old_mode); system(output); } for (i =0; i < 3; i++) { - sprintf(output,"xrandr --addmode %s-%d %s", "DVI",i ,new_mode); + snprintf(output, sizeof(output), "xrandr --addmode %s-%d %s", "DVI",i ,new_mode); system(output); - sprintf(output,"xrandr --delmode %s-%d %s", "DVI",i ,old_mode); + snprintf(output, sizeof(output), "xrandr --delmode %s-%d %s", "DVI",i ,old_mode); system(output); } for (i =0; i < 3; i++) { - sprintf(output,"xrandr --addmode %s%d %s", "VGA",i ,new_mode); + snprintf(output, sizeof(output), "xrandr --addmode %s%d %s", "VGA",i ,new_mode); system(output); - sprintf(output,"xrandr --delmode %s%d %s", "VGA",i ,old_mode); + snprintf(output, sizeof(output), "xrandr --delmode %s%d %s", "VGA",i ,old_mode); system(output); } for (i =0; i < 3; i++) { - sprintf(output,"xrandr --addmode %s-%d %s", "VGA",i ,new_mode); + snprintf(output, sizeof(output), "xrandr --addmode %s-%d %s", "VGA",i ,new_mode); system(output); - sprintf(output,"xrandr --delmode %s-%d %s", "VGA",i ,old_mode); + snprintf(output, sizeof(output), "xrandr --delmode %s-%d %s", "VGA",i ,old_mode); system(output); } - sprintf(output,"xrandr -s %s", new_mode); + snprintf(output, sizeof(output), "xrandr -s %s", new_mode); system(output); /* remove old mode */ - sprintf(output,"xrandr --rmmode %s", old_mode); + snprintf(output, sizeof(output), "xrandr --rmmode %s", old_mode); system(output); system("xdotool windowactivate $(xdotool search --class RetroArch)"); /* needs xdotool installed. needed to recaputure window. */ /* variable for old mode */ - sprintf(old_mode,"%s", new_mode); + snprintf(old_mode, sizeof(old_mode), "%s", new_mode); system("xdotool windowactivate $(xdotool search --class RetroArch)"); /* needs xdotool installed. needed to recaputure window. */ /* Second run needed as some times it runs to fast to capture first time */ diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index ea557a2084..dd08fdf786 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -43,10 +43,10 @@ static void d3d10_free_overlays(d3d10_video_t* d3d10) Release(d3d10->overlays.vbo); } -static void + static void d3d10_overlay_vertex_geom(void* data, unsigned index, float x, float y, float w, float h) { - d3d10_sprite_t* sprites = NULL; + d3d10_sprite_t* sprites = NULL; d3d10_video_t* d3d10 = (d3d10_video_t*)data; if (!d3d10) @@ -54,16 +54,16 @@ d3d10_overlay_vertex_geom(void* data, unsigned index, float x, float y, float w, D3D10MapBuffer(d3d10->overlays.vbo, D3D10_MAP_WRITE_NO_OVERWRITE, 0, (void**)&sprites); - sprites[index].pos.x = x; - sprites[index].pos.y = y; - sprites[index].pos.w = w; - sprites[index].pos.h = h; + sprites[index].pos.x = x; + sprites[index].pos.y = y; + sprites[index].pos.w = w; + sprites[index].pos.h = h; D3D10UnmapBuffer(d3d10->overlays.vbo); } static void d3d10_overlay_tex_geom(void* data, unsigned index, float u, float v, float w, float h) { - d3d10_sprite_t* sprites = NULL; + d3d10_sprite_t* sprites = NULL; d3d10_video_t* d3d10 = (d3d10_video_t*)data; if (!d3d10) @@ -72,16 +72,16 @@ static void d3d10_overlay_tex_geom(void* data, unsigned index, float u, float v, D3D10MapBuffer( d3d10->overlays.vbo, D3D10_MAP_WRITE_NO_OVERWRITE, 0, (void**)&sprites); - sprites[index].coords.u = u; - sprites[index].coords.v = v; - sprites[index].coords.w = w; - sprites[index].coords.h = h; + sprites[index].coords.u = u; + sprites[index].coords.v = v; + sprites[index].coords.w = w; + sprites[index].coords.h = h; D3D10UnmapBuffer(d3d10->overlays.vbo); } static void d3d10_overlay_set_alpha(void* data, unsigned index, float mod) { - d3d10_sprite_t* sprites = NULL; + d3d10_sprite_t* sprites = NULL; d3d10_video_t* d3d10 = (d3d10_video_t*)data; if (!d3d10) @@ -90,10 +90,10 @@ static void d3d10_overlay_set_alpha(void* data, unsigned index, float mod) D3D10MapBuffer( d3d10->overlays.vbo, D3D10_MAP_WRITE_NO_OVERWRITE, 0, (void**)&sprites); - sprites[index].colors[0] = DXGI_COLOR_RGBA(0xFF, 0xFF, 0xFF, mod * 0xFF); - sprites[index].colors[1] = sprites[index].colors[0]; - sprites[index].colors[2] = sprites[index].colors[0]; - sprites[index].colors[3] = sprites[index].colors[0]; + sprites[index].colors[0] = DXGI_COLOR_RGBA(0xFF, 0xFF, 0xFF, mod * 0xFF); + sprites[index].colors[1] = sprites[index].colors[0]; + sprites[index].colors[2] = sprites[index].colors[0]; + sprites[index].colors[3] = sprites[index].colors[0]; D3D10UnmapBuffer(d3d10->overlays.vbo); } @@ -213,7 +213,7 @@ static void d3d10_set_filtering(void* data, unsigned index, bool smooth) static void d3d10_gfx_set_rotation(void* data, unsigned rotation) { - math_matrix_4x4 rot; + math_matrix_4x4 rot; void* mapped_ubo = NULL; d3d10_video_t* d3d10 = (d3d10_video_t*)data; @@ -242,7 +242,7 @@ static void d3d10_update_viewport(void* data, bool force_full) d3d10->frame.viewport.MaxDepth = 1.0f; if (d3d10->shader_preset && (d3d10->frame.output_size.x != d3d10->vp.width || - d3d10->frame.output_size.y != d3d10->vp.height)) + d3d10->frame.output_size.y != d3d10->vp.height)) d3d10->resize_render_targets = true; d3d10->frame.output_size.x = d3d10->vp.width; @@ -375,16 +375,16 @@ static bool d3d10_gfx_set_shader(void* data, /* clang-format on */ if (!slang_process( - d3d10->shader_preset, i, RARCH_SHADER_HLSL, 40, &semantics_map, - &d3d10->pass[i].semantics)) + d3d10->shader_preset, i, RARCH_SHADER_HLSL, 40, &semantics_map, + &d3d10->pass[i].semantics)) goto error; { static const D3D10_INPUT_ELEMENT_DESC desc[] = { { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d10_vertex_t, position), - D3D10_INPUT_PER_VERTEX_DATA, 0 }, + D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d10_vertex_t, texcoord), - D3D10_INPUT_PER_VERTEX_DATA, 0 }, + D3D10_INPUT_PER_VERTEX_DATA, 0 }, }; #ifdef DEBUG bool save_hlsl = true; @@ -393,29 +393,26 @@ static bool d3d10_gfx_set_shader(void* data, #endif static const char vs_ext[] = ".vs.hlsl"; static const char ps_ext[] = ".ps.hlsl"; - char vs_path[PATH_MAX_LENGTH]; - char ps_path[PATH_MAX_LENGTH]; + char vs_path[PATH_MAX_LENGTH] = {0}; + char ps_path[PATH_MAX_LENGTH] = {0}; const char* slang_path = d3d10->shader_preset->pass[i].source.path; const char* vs_src = d3d10->shader_preset->pass[i].source.string.vertex; const char* ps_src = d3d10->shader_preset->pass[i].source.string.fragment; int base_len = strlen(slang_path) - strlen(".slang"); - if (base_len <= 0) - base_len = strlen(slang_path); - - strncpy(vs_path, slang_path, base_len); - strncpy(ps_path, slang_path, base_len); - strncpy(vs_path + base_len, vs_ext, sizeof(vs_ext)); - strncpy(ps_path + base_len, ps_ext, sizeof(ps_ext)); + strlcpy(vs_path, slang_path, sizeof(vs_path)); + strlcpy(ps_path, slang_path, sizeof(ps_path)); + strlcat(vs_path, vs_ext, sizeof(vs_path)); + strlcat(ps_path, ps_ext, sizeof(ps_path)); if (!d3d10_init_shader( - d3d10->device, vs_src, 0, vs_path, "main", NULL, NULL, desc, countof(desc), - &d3d10->pass[i].shader)) + d3d10->device, vs_src, 0, vs_path, "main", NULL, NULL, desc, countof(desc), + &d3d10->pass[i].shader)) save_hlsl = true; if (!d3d10_init_shader( - d3d10->device, ps_src, 0, ps_path, NULL, "main", NULL, NULL, 0, - &d3d10->pass[i].shader)) + d3d10->device, ps_src, 0, ps_path, NULL, "main", NULL, NULL, 0, + &d3d10->pass[i].shader)) save_hlsl = true; if (save_hlsl) @@ -546,16 +543,16 @@ static void d3d10_gfx_free(void* data) font_driver_free_osd(); #if 0 - if (video_driver_is_video_cache_context()) - { + if (video_driver_is_video_cache_context()) + { cached_device_d3d10 = d3d10->device; - cached_context = d3d10->context; - } - else + cached_context = d3d10->context; + } + else #endif - { - Release(d3d10->device); - } + { + Release(d3d10->device); + } win32_monitor_from_window(); win32_destroy_window(); @@ -593,7 +590,7 @@ d3d10_gfx_init(const video_info_t* video, d3d10->vp.full_height = current_mon.rcMonitor.bottom - current_mon.rcMonitor.top; - if (!win32_set_video_mode(d3d10, + if (!win32_set_video_mode(d3d10, d3d10->vp.full_width, d3d10->vp.full_height, video->fullscreen)) { RARCH_ERR("[D3D10]: win32_set_video_mode failed.\n"); @@ -616,9 +613,9 @@ d3d10_gfx_init(const video_info_t* video, desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Windowed = TRUE; - desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; + desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; #if 0 - desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; #endif @@ -628,9 +625,9 @@ d3d10_gfx_init(const video_info_t* video, #endif if (FAILED(D3D10CreateDeviceAndSwapChain( - NULL, D3D10_DRIVER_TYPE_HARDWARE, - NULL, flags, D3D10_SDK_VERSION, &desc, - (IDXGISwapChain**)&d3d10->swapChain, &d3d10->device))) + NULL, D3D10_DRIVER_TYPE_HARDWARE, + NULL, flags, D3D10_SDK_VERSION, &desc, + (IDXGISwapChain**)&d3d10->swapChain, &d3d10->device))) goto error; } @@ -642,7 +639,7 @@ d3d10_gfx_init(const video_info_t* video, Release(backBuffer); } - D3D10SetRenderTargets(d3d10->device, 1, &d3d10->renderTargetView, NULL); + D3D10SetRenderTargets(d3d10->device, 1, &d3d10->renderTargetView, NULL); video_driver_set_size(&d3d10->vp.full_width, &d3d10->vp.full_height); d3d10->viewport.Width = d3d10->vp.full_width; @@ -687,7 +684,7 @@ d3d10_gfx_init(const video_info_t* video, d3d10_gfx_set_rotation(d3d10, 0); { - D3D10_SAMPLER_DESC desc = { D3D10_FILTER_MIN_MAG_MIP_POINT }; + D3D10_SAMPLER_DESC desc = { D3D10_FILTER_MIN_MAG_MIP_POINT }; desc.MaxAnisotropy = 1; desc.ComparisonFunc = D3D10_COMPARISON_NEVER; desc.MinLOD = -D3D10_FLOAT32_MAX; @@ -759,52 +756,52 @@ d3d10_gfx_init(const video_info_t* video, { D3D10_INPUT_ELEMENT_DESC desc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d10_vertex_t, position), - D3D10_INPUT_PER_VERTEX_DATA, 0 }, + D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d10_vertex_t, texcoord), - D3D10_INPUT_PER_VERTEX_DATA, 0 }, + D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d10_vertex_t, color), - D3D10_INPUT_PER_VERTEX_DATA, 0 }, + D3D10_INPUT_PER_VERTEX_DATA, 0 }, }; static const char shader[] = #include "d3d_shaders/opaque_sm5.hlsl.h" - ; + ; if (!d3d10_init_shader( - d3d10->device, shader, sizeof(shader), NULL, "VSMain", "PSMain", NULL, desc, - countof(desc), &d3d10->shaders[VIDEO_SHADER_STOCK_BLEND])) + d3d10->device, shader, sizeof(shader), NULL, "VSMain", "PSMain", NULL, desc, + countof(desc), &d3d10->shaders[VIDEO_SHADER_STOCK_BLEND])) goto error; } { D3D10_INPUT_ELEMENT_DESC desc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d10_sprite_t, pos), - D3D10_INPUT_PER_VERTEX_DATA, 0 }, + D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d10_sprite_t, coords), - D3D10_INPUT_PER_VERTEX_DATA, 0 }, + D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d10_sprite_t, colors[0]), - D3D10_INPUT_PER_VERTEX_DATA, 0 }, + D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d10_sprite_t, colors[1]), - D3D10_INPUT_PER_VERTEX_DATA, 0 }, + D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 2, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d10_sprite_t, colors[2]), - D3D10_INPUT_PER_VERTEX_DATA, 0 }, + D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 3, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d10_sprite_t, colors[3]), - D3D10_INPUT_PER_VERTEX_DATA, 0 }, + D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "PARAMS", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d10_sprite_t, params), - D3D10_INPUT_PER_VERTEX_DATA, 0 }, + D3D10_INPUT_PER_VERTEX_DATA, 0 }, }; static const char shader[] = #include "d3d_shaders/sprite_sm4.hlsl.h" - ; + ; if (!d3d10_init_shader( - d3d10->device, shader, sizeof(shader), NULL, "VSMain", "PSMain", "GSMain", desc, - countof(desc), &d3d10->sprites.shader)) + d3d10->device, shader, sizeof(shader), NULL, "VSMain", "PSMain", "GSMain", desc, + countof(desc), &d3d10->sprites.shader)) goto error; if (!d3d10_init_shader( - d3d10->device, shader, sizeof(shader), NULL, "VSMain", "PSMainA8", "GSMain", desc, - countof(desc), &d3d10->sprites.shader_font)) + d3d10->device, shader, sizeof(shader), NULL, "VSMain", "PSMainA8", "GSMain", desc, + countof(desc), &d3d10->sprites.shader_font)) goto error; } @@ -876,7 +873,7 @@ d3d10_gfx_init(const video_info_t* video, } { - D3D10_BLEND_DESC blend_desc = { 0 }; + D3D10_BLEND_DESC blend_desc = { 0 }; blend_desc.AlphaToCoverageEnable = FALSE; blend_desc.BlendEnable[0] = TRUE; @@ -920,7 +917,7 @@ d3d10_gfx_init(const video_info_t* video, #if 0 if (video_driver_get_hw_context()->context_type == RETRO_HW_CONTEXT_DIRECT3D && - video_driver_get_hw_context()->version_major == 11) + video_driver_get_hw_context()->version_major == 11) { d3d10->hw.enable = true; d3d10->hw.iface.interface_type = RETRO_HW_RENDER_INTERFACE_D3D10; @@ -1026,7 +1023,7 @@ static void d3d10_init_render_targets(d3d10_video_t* d3d10, RARCH_LOG("[D3D10]: Updating framebuffer size %u x %u.\n", width, height); if ((i != (d3d10->shader_preset->passes - 1)) || (width != d3d10->vp.width) || - (height != d3d10->vp.height)) + (height != d3d10->vp.height)) { d3d10->pass[i].viewport.Width = width; d3d10->pass[i].viewport.Height = height; @@ -1107,7 +1104,7 @@ static bool d3d10_gfx_frame( #if 0 /* custom viewport doesn't call apply_state_changes, so we can't rely on this for now */ if (d3d10->resize_viewport) #endif - d3d10_update_viewport(d3d10, false); + d3d10_update_viewport(d3d10, false); D3D10SetPrimitiveTopology(context, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); @@ -1124,7 +1121,7 @@ static bool d3d10_gfx_frame( if (d3d10->shader_preset) { if (d3d10->frame.texture[0].desc.Width != width || - d3d10->frame.texture[0].desc.Height != height) + d3d10->frame.texture[0].desc.Height != height) d3d10->resize_render_targets = true; if (d3d10->resize_render_targets) @@ -1160,7 +1157,7 @@ static bool d3d10_gfx_frame( /* either no history, or we moved a texture of a different size in the front slot */ if (d3d10->frame.texture[0].desc.Width != width || - d3d10->frame.texture[0].desc.Height != height) + d3d10->frame.texture[0].desc.Height != height) { d3d10->frame.texture[0].desc.Width = width; d3d10->frame.texture[0].desc.Height = height; @@ -1203,7 +1200,7 @@ static bool d3d10_gfx_frame( if (d3d10->shader_preset->pass[i].frame_count_mod) d3d10->pass[i].frame_count = - frame_count % d3d10->shader_preset->pass[i].frame_count_mod; + frame_count % d3d10->shader_preset->pass[i].frame_count_mod; else d3d10->pass[i].frame_count = frame_count; @@ -1331,19 +1328,19 @@ static bool d3d10_gfx_frame( else #endif if (video_info->statistics_show) - { - struct font_params* osd_params = (struct font_params*)&video_info->osd_stat_params; - - if (osd_params) { - D3D10SetViewports(context, 1, &d3d10->viewport); - D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK); - D3D10SetVertexBuffer(context, 0, d3d10->sprites.vbo, sizeof(d3d10_sprite_t), 0); - font_driver_render_msg( - video_info, NULL, video_info->stat_text, - (const struct font_params*)&video_info->osd_stat_params); + struct font_params* osd_params = (struct font_params*)&video_info->osd_stat_params; + + if (osd_params) + { + D3D10SetViewports(context, 1, &d3d10->viewport); + D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK); + D3D10SetVertexBuffer(context, 0, d3d10->sprites.vbo, sizeof(d3d10_sprite_t), 0); + font_driver_render_msg( + video_info, NULL, video_info->stat_text, + (const struct font_params*)&video_info->osd_stat_params); + } } - } #ifdef HAVE_OVERLAY if (d3d10->overlays.enabled) @@ -1386,7 +1383,7 @@ static void d3d10_gfx_set_nonblock_state(void* data, bool toggle) { d3d10_video_t* d3d10 = (d3d10_video_t*)data; - if (!d3d10) + if (!d3d10) return; d3d10->vsync = !toggle; @@ -1474,7 +1471,7 @@ static void d3d10_set_menu_texture_enable(void* data, bool state, bool full_scre { d3d10_video_t* d3d10 = (d3d10_video_t*)data; - if (!d3d10) + if (!d3d10) return; d3d10->menu.enabled = state; @@ -1574,7 +1571,7 @@ static void d3d10_gfx_unload_texture(void* data, uintptr_t handle) } #if 0 -static bool + static bool d3d10_get_hw_render_interface(void* data, const struct retro_hw_render_interface** iface) { d3d10_video_t* d3d10 = (d3d10_video_t*)data; diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 3a96048a38..405894bbef 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -55,7 +55,7 @@ static void d3d11_free_overlays(d3d11_video_t* d3d11) Release(d3d11->overlays.vbo); } -static void + static void d3d11_overlay_vertex_geom(void* data, unsigned index, float x, float y, float w, float h) { D3D11_MAPPED_SUBRESOURCE mapped_vbo; @@ -230,6 +230,7 @@ static void d3d11_set_filtering(void* data, unsigned index, bool smooth) static void d3d11_gfx_set_rotation(void* data, unsigned rotation) { math_matrix_4x4 rot; + D3D11_MAPPED_SUBRESOURCE mapped_ubo; d3d11_video_t* d3d11 = (d3d11_video_t*)data; if (!d3d11) @@ -238,7 +239,6 @@ static void d3d11_gfx_set_rotation(void* data, unsigned rotation) matrix_4x4_rotate_z(rot, rotation * (M_PI / 2.0f)); matrix_4x4_multiply(d3d11->mvp, rot, d3d11->ubo_values.mvp); - D3D11_MAPPED_SUBRESOURCE mapped_ubo; D3D11MapBuffer(d3d11->context, d3d11->frame.ubo, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_ubo); *(math_matrix_4x4*)mapped_ubo.pData = d3d11->mvp; D3D11UnmapBuffer(d3d11->context, d3d11->frame.ubo, 0); @@ -258,7 +258,7 @@ static void d3d11_update_viewport(void* data, bool force_full) d3d11->frame.viewport.MaxDepth = 1.0f; if (d3d11->shader_preset && (d3d11->frame.output_size.x != d3d11->vp.width || - d3d11->frame.output_size.y != d3d11->vp.height)) + d3d11->frame.output_size.y != d3d11->vp.height)) d3d11->resize_render_targets = true; d3d11->frame.output_size.x = d3d11->vp.width; @@ -318,8 +318,9 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const { #if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) unsigned i; - d3d11_texture_t* source; - d3d11_video_t* d3d11 = (d3d11_video_t*)data; + config_file_t* conf = NULL; + d3d11_texture_t* source = NULL; + d3d11_video_t* d3d11 = (d3d11_video_t*)data; if (!d3d11) return false; @@ -336,7 +337,7 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const return false; } - config_file_t* conf = config_file_new(path); + conf = config_file_new(path); if (!conf) return false; @@ -389,16 +390,16 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const /* clang-format on */ if (!slang_process( - d3d11->shader_preset, i, RARCH_SHADER_HLSL, 40, &semantics_map, - &d3d11->pass[i].semantics)) + d3d11->shader_preset, i, RARCH_SHADER_HLSL, 40, &semantics_map, + &d3d11->pass[i].semantics)) goto error; { static const D3D11_INPUT_ELEMENT_DESC desc[] = { { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, position), - D3D11_INPUT_PER_VERTEX_DATA, 0 }, + D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, texcoord), - D3D11_INPUT_PER_VERTEX_DATA, 0 }, + D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; #ifdef DEBUG bool save_hlsl = true; @@ -407,29 +408,25 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const #endif static const char vs_ext[] = ".vs.hlsl"; static const char ps_ext[] = ".ps.hlsl"; - char vs_path[PATH_MAX_LENGTH]; - char ps_path[PATH_MAX_LENGTH]; + char vs_path[PATH_MAX_LENGTH] = {0}; + char ps_path[PATH_MAX_LENGTH] = {0}; const char* slang_path = d3d11->shader_preset->pass[i].source.path; const char* vs_src = d3d11->shader_preset->pass[i].source.string.vertex; const char* ps_src = d3d11->shader_preset->pass[i].source.string.fragment; - int base_len = strlen(slang_path) - strlen(".slang"); - if (base_len <= 0) - base_len = strlen(slang_path); - - strncpy(vs_path, slang_path, base_len); - strncpy(ps_path, slang_path, base_len); - strncpy(vs_path + base_len, vs_ext, sizeof(vs_ext)); - strncpy(ps_path + base_len, ps_ext, sizeof(ps_ext)); + strlcpy(vs_path, slang_path, sizeof(vs_path)); + strlcpy(ps_path, slang_path, sizeof(ps_path)); + strlcat(vs_path, vs_ext, sizeof(vs_path)); + strlcat(ps_path, ps_ext, sizeof(ps_path)); if (!d3d11_init_shader( - d3d11->device, vs_src, 0, vs_path, "main", NULL, NULL, desc, countof(desc), - &d3d11->pass[i].shader)) + d3d11->device, vs_src, 0, vs_path, "main", NULL, NULL, desc, countof(desc), + &d3d11->pass[i].shader)) save_hlsl = true; if (!d3d11_init_shader( - d3d11->device, ps_src, 0, ps_path, NULL, "main", NULL, NULL, 0, - &d3d11->pass[i].shader)) + d3d11->device, ps_src, 0, ps_path, NULL, "main", NULL, NULL, 0, + &d3d11->pass[i].shader)) save_hlsl = true; if (save_hlsl) @@ -556,24 +553,24 @@ static void d3d11_gfx_free(void* data) font_driver_free_osd(); - if (video_driver_is_video_cache_context()) - { + if (video_driver_is_video_cache_context()) + { cached_device_d3d11 = d3d11->device; - cached_context = d3d11->context; - cached_supportedFeatureLevel = d3d11->supportedFeatureLevel; - } - else - { - Release(d3d11->context); - Release(d3d11->device); - } + cached_context = d3d11->context; + cached_supportedFeatureLevel = d3d11->supportedFeatureLevel; + } + else + { + Release(d3d11->context); + Release(d3d11->device); + } win32_monitor_from_window(); win32_destroy_window(); free(d3d11); } -static void* + static void* d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) { unsigned i; @@ -613,12 +610,12 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i UINT flags = 0; D3D_FEATURE_LEVEL requested_feature_levels[] = - { - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, - D3D_FEATURE_LEVEL_9_3 - }; + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3 + }; DXGI_SWAP_CHAIN_DESC desc = { 0 }; UINT number_feature_levels = ARRAY_SIZE(requested_feature_levels); @@ -646,39 +643,39 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i #ifdef DEBUG flags |= D3D11_CREATE_DEVICE_DEBUG; #endif - if(cached_device_d3d11 && cached_context) - { - IDXGIFactory* dxgiFactory = NULL; - IDXGIDevice* dxgiDevice = NULL; - IDXGIAdapter* adapter = NULL; + if(cached_device_d3d11 && cached_context) + { + IDXGIFactory* dxgiFactory = NULL; + IDXGIDevice* dxgiDevice = NULL; + IDXGIAdapter* adapter = NULL; - d3d11->device = cached_device_d3d11; - d3d11->context = cached_context; - d3d11->supportedFeatureLevel = cached_supportedFeatureLevel; + d3d11->device = cached_device_d3d11; + d3d11->context = cached_context; + d3d11->supportedFeatureLevel = cached_supportedFeatureLevel; - d3d11->device->lpVtbl->QueryInterface( + d3d11->device->lpVtbl->QueryInterface( d3d11->device, uuidof(IDXGIDevice), (void**)&dxgiDevice); - dxgiDevice->lpVtbl->GetAdapter(dxgiDevice, &adapter); - adapter->lpVtbl->GetParent( + dxgiDevice->lpVtbl->GetAdapter(dxgiDevice, &adapter); + adapter->lpVtbl->GetParent( adapter, uuidof(IDXGIFactory1), (void**)&dxgiFactory); - dxgiFactory->lpVtbl->CreateSwapChain( + dxgiFactory->lpVtbl->CreateSwapChain( dxgiFactory, (IUnknown*)d3d11->device, &desc, (IDXGISwapChain**)&d3d11->swapChain); - dxgiFactory->lpVtbl->Release(dxgiFactory); - adapter->lpVtbl->Release(adapter); - dxgiDevice->lpVtbl->Release(dxgiDevice); - } - else - { - if (FAILED(D3D11CreateDeviceAndSwapChain( - NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, - requested_feature_levels, number_feature_levels, - D3D11_SDK_VERSION, &desc, - (IDXGISwapChain**)&d3d11->swapChain, &d3d11->device, - &d3d11->supportedFeatureLevel, &d3d11->context))) + dxgiFactory->lpVtbl->Release(dxgiFactory); + adapter->lpVtbl->Release(adapter); + dxgiDevice->lpVtbl->Release(dxgiDevice); + } + else + { + if (FAILED(D3D11CreateDeviceAndSwapChain( + NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, + requested_feature_levels, number_feature_levels, + D3D11_SDK_VERSION, &desc, + (IDXGISwapChain**)&d3d11->swapChain, &d3d11->device, + &d3d11->supportedFeatureLevel, &d3d11->context))) goto error; - } + } } { @@ -805,52 +802,52 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i { D3D11_INPUT_ELEMENT_DESC desc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, position), - D3D11_INPUT_PER_VERTEX_DATA, 0 }, + D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, texcoord), - D3D11_INPUT_PER_VERTEX_DATA, 0 }, + D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d11_vertex_t, color), - D3D11_INPUT_PER_VERTEX_DATA, 0 }, + D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; static const char shader[] = #include "d3d_shaders/opaque_sm5.hlsl.h" - ; + ; if (!d3d11_init_shader( - d3d11->device, shader, sizeof(shader), NULL, "VSMain", "PSMain", NULL, desc, - countof(desc), &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND])) + d3d11->device, shader, sizeof(shader), NULL, "VSMain", "PSMain", NULL, desc, + countof(desc), &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND])) goto error; } { D3D11_INPUT_ELEMENT_DESC desc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d11_sprite_t, pos), - D3D11_INPUT_PER_VERTEX_DATA, 0 }, + D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d11_sprite_t, coords), - D3D11_INPUT_PER_VERTEX_DATA, 0 }, + D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d11_sprite_t, colors[0]), - D3D11_INPUT_PER_VERTEX_DATA, 0 }, + D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d11_sprite_t, colors[1]), - D3D11_INPUT_PER_VERTEX_DATA, 0 }, + D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 2, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d11_sprite_t, colors[2]), - D3D11_INPUT_PER_VERTEX_DATA, 0 }, + D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 3, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d11_sprite_t, colors[3]), - D3D11_INPUT_PER_VERTEX_DATA, 0 }, + D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "PARAMS", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_sprite_t, params), - D3D11_INPUT_PER_VERTEX_DATA, 0 }, + D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; static const char shader[] = #include "d3d_shaders/sprite_sm4.hlsl.h" - ; + ; if (!d3d11_init_shader( - d3d11->device, shader, sizeof(shader), NULL, "VSMain", "PSMain", "GSMain", desc, - countof(desc), &d3d11->sprites.shader)) + d3d11->device, shader, sizeof(shader), NULL, "VSMain", "PSMain", "GSMain", desc, + countof(desc), &d3d11->sprites.shader)) goto error; if (!d3d11_init_shader( - d3d11->device, shader, sizeof(shader), NULL, "VSMain", "PSMainA8", "GSMain", desc, - countof(desc), &d3d11->sprites.shader_font)) + d3d11->device, shader, sizeof(shader), NULL, "VSMain", "PSMainA8", "GSMain", desc, + countof(desc), &d3d11->sprites.shader_font)) goto error; } @@ -964,7 +961,7 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i } if (video_driver_get_hw_context()->context_type == RETRO_HW_CONTEXT_DIRECT3D && - video_driver_get_hw_context()->version_major == 11) + video_driver_get_hw_context()->version_major == 11) { d3d11->hw.enable = true; d3d11->hw.iface.interface_type = RETRO_HW_RENDER_INTERFACE_D3D11; @@ -1068,7 +1065,7 @@ static void d3d11_init_render_targets(d3d11_video_t* d3d11, unsigned width, unsi RARCH_LOG("[D3D11]: Updating framebuffer size %u x %u.\n", width, height); if ((i != (d3d11->shader_preset->passes - 1)) || (width != d3d11->vp.width) || - (height != d3d11->vp.height)) + (height != d3d11->vp.height)) { d3d11->pass[i].viewport.Width = width; d3d11->pass[i].viewport.Height = height; @@ -1149,7 +1146,7 @@ static bool d3d11_gfx_frame( #if 0 /* custom viewport doesn't call apply_state_changes, so we can't rely on this for now */ if (d3d11->resize_viewport) #endif - d3d11_update_viewport(d3d11, false); + d3d11_update_viewport(d3d11, false); D3D11SetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); @@ -1164,7 +1161,7 @@ static bool d3d11_gfx_frame( if (d3d11->shader_preset) { if (d3d11->frame.texture[0].desc.Width != width || - d3d11->frame.texture[0].desc.Height != height) + d3d11->frame.texture[0].desc.Height != height) d3d11->resize_render_targets = true; if (d3d11->resize_render_targets) @@ -1198,7 +1195,7 @@ static bool d3d11_gfx_frame( /* either no history, or we moved a texture of a different size in the front slot */ if (d3d11->frame.texture[0].desc.Width != width || - d3d11->frame.texture[0].desc.Height != height) + d3d11->frame.texture[0].desc.Height != height) { d3d11->frame.texture[0].desc.Width = width; d3d11->frame.texture[0].desc.Height = height; @@ -1238,7 +1235,7 @@ static bool d3d11_gfx_frame( if (d3d11->shader_preset->pass[i].frame_count_mod) d3d11->pass[i].frame_count = - frame_count % d3d11->shader_preset->pass[i].frame_count_mod; + frame_count % d3d11->shader_preset->pass[i].frame_count_mod; else d3d11->pass[i].frame_count = frame_count; @@ -1600,7 +1597,7 @@ static void d3d11_gfx_unload_texture(void* data, uintptr_t handle) free(texture); } -static bool + static bool d3d11_get_hw_render_interface(void* data, const struct retro_hw_render_interface** iface) { d3d11_video_t* d3d11 = (d3d11_video_t*)data; diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index 4f7e884c0c..b64fa654f2 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -420,20 +420,17 @@ static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const #endif static const char vs_ext[] = ".vs.hlsl"; static const char ps_ext[] = ".ps.hlsl"; - char vs_path[PATH_MAX_LENGTH]; - char ps_path[PATH_MAX_LENGTH]; + char vs_path[PATH_MAX_LENGTH] = {0}; + char ps_path[PATH_MAX_LENGTH] = {0}; const char* slang_path = d3d12->shader_preset->pass[i].source.path; const char* vs_src = d3d12->shader_preset->pass[i].source.string.vertex; const char* ps_src = d3d12->shader_preset->pass[i].source.string.fragment; int base_len = strlen(slang_path) - strlen(".slang"); - if (base_len <= 0) - base_len = strlen(slang_path); - - strncpy(vs_path, slang_path, base_len); - strncpy(ps_path, slang_path, base_len); - strncpy(vs_path + base_len, vs_ext, sizeof(vs_ext)); - strncpy(ps_path + base_len, ps_ext, sizeof(ps_ext)); + strlcpy(vs_path, slang_path, sizeof(vs_path)); + strlcpy(ps_path, slang_path, sizeof(ps_path)); + strlcat(vs_path, vs_ext, sizeof(vs_path)); + strlcat(ps_path, ps_ext, sizeof(ps_path)); if (!d3d_compile(vs_src, 0, vs_path, "main", "vs_5_0", &vs_code)) save_hlsl = true; diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 1008697366..b6a919108c 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -380,7 +380,7 @@ static bool gl_shader_init(gl_t *gl, const gfx_ctx_driver_t *ctx_driver, video_shader_ctx_init_t init_data; enum rarch_shader_type type = DEFAULT_SHADER_TYPE; const char *shader_path = retroarch_get_shader_preset(); - + if (shader_path) { type = video_shader_parse_type(shader_path, @@ -832,7 +832,6 @@ static void gl_set_osd_msg(void *data, font_driver_render_msg(video_info, font, msg, (const struct font_params *)params); } -#if defined(HAVE_MENU) static void gl_show_mouse(void *data, bool state) { video_context_driver_show_mouse(&state); @@ -840,13 +839,14 @@ static void gl_show_mouse(void *data, bool state) static struct video_shader *gl_get_current_shader(void *data) { - video_shader_ctx_t shader_info; + video_shader_ctx_t shader_info = {0}; video_shader_driver_direct_get_current_shader(&shader_info); return shader_info.data; } +#if defined(HAVE_MENU) static INLINE void gl_draw_texture(gl_t *gl, video_frame_info_t *video_info) { video_shader_ctx_coords_t coords; @@ -1798,9 +1798,9 @@ static void *gl_init(const video_info_t *video, } if (!renderchain_gl_init_first(&gl->renderchain_driver, - &gl->renderchain_data)) + &gl->renderchain_data)) { - RARCH_ERR("[GL]: Renderchain could not be initialized.\n"); + RARCH_ERR("[GL]: Renderchain could not be initialized.\n"); goto error; } @@ -2200,11 +2200,6 @@ static bool gl_set_shader(void *data, /* Apparently need to set viewport for passes when we aren't using FBOs. */ gl_set_shader_viewports(gl); context_bind_hw_render(true); -#if defined(_WIN32) && !defined(_XBOX) - /* Shader dialog is disabled for now, until video_threaded issues are fixed. - shader_dlg_params_reload();*/ -#endif - #endif return true; diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index a4f2c55267..3d162d0118 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -744,6 +744,9 @@ static bool vulkan_init_default_filter_chain(vk_t *vk) memset(&info, 0, sizeof(info)); + if (!vk->context) + return false; + info.device = vk->context->device; info.gpu = vk->context->gpu; info.memory_properties = &vk->context->memory_properties; @@ -808,8 +811,7 @@ static bool vulkan_init_filter_chain_preset(vk_t *vk, const char *shader_path) static bool vulkan_init_filter_chain(vk_t *vk) { - settings_t *settings = config_get_ptr(); - const char *shader_path = retroarch_get_shader_preset(); + const char *shader_path = retroarch_get_shader_preset(); enum rarch_shader_type type = video_shader_parse_type(shader_path, RARCH_SHADER_NONE); @@ -833,7 +835,7 @@ static bool vulkan_init_filter_chain(vk_t *vk) static void vulkan_init_resources(vk_t *vk) { - if (!vk) + if (!vk->context) return; vk->num_swapchain_images = vk->context->num_swapchain_images; @@ -856,6 +858,9 @@ static void vulkan_init_static_resources(vk_t *vk) VkPipelineCacheCreateInfo cache = { VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; + if (!vk->context) + return; + vkCreatePipelineCache(vk->context->device, &cache, NULL, &vk->pipelines.cache); @@ -2228,10 +2233,16 @@ static void vulkan_set_osd_msg(void *data, static uintptr_t vulkan_load_texture(void *video_data, void *data, bool threaded, enum texture_filter_type filter_type) { + struct vk_texture *texture = NULL; vk_t *vk = (vk_t*)video_data; struct texture_image *image = (struct texture_image*)data; - struct vk_texture *texture = (struct vk_texture*)calloc(1, sizeof(*texture)); - if (!image || !texture) + if (!image) + return 0; + + texture = (struct vk_texture*) + calloc(1, sizeof(*texture)); + + if (!texture) return 0; if (!image->pixels || !image->width || !image->height) @@ -2352,6 +2363,9 @@ static void vulkan_viewport_info(void *data, struct video_viewport *vp) video_driver_get_size(&width, &height); + if (!vk) + return; + /* Make sure we get the correct viewport. */ vulkan_set_viewport(vk, width, height, false, true); diff --git a/gfx/drivers_context/cocoa_gl_ctx.m b/gfx/drivers_context/cocoa_gl_ctx.m index a95478f59d..69911d0cdb 100644 --- a/gfx/drivers_context/cocoa_gl_ctx.m +++ b/gfx/drivers_context/cocoa_gl_ctx.m @@ -365,7 +365,7 @@ static bool cocoagl_gfx_ctx_set_video_mode(void *data, g_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 if (g_format == nil) { /* NSOpenGLFPAAllowOfflineRenderers is diff --git a/gfx/drivers_context/macos_ctx.m b/gfx/drivers_context/macos_ctx.m index 7c1aedc2dd..64c92a0e76 100644 --- a/gfx/drivers_context/macos_ctx.m +++ b/gfx/drivers_context/macos_ctx.m @@ -446,7 +446,7 @@ static bool cocoagl_gfx_ctx_set_video_mode(void *data, } #endif -#if MAC_OS_X_VERSION_10_10 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 if (g_major == 4 && g_minor == 1) { attributes[6] = NSOpenGLPFAOpenGLProfile; @@ -456,7 +456,7 @@ static bool cocoagl_gfx_ctx_set_video_mode(void *data, g_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 if (g_format == nil) { /* NSOpenGLFPAAllowOfflineRenderers is diff --git a/gfx/drivers_context/wayland_ctx.c b/gfx/drivers_context/wayland_ctx.c index 2462fc5ef0..cbd5418a7a 100644 --- a/gfx/drivers_context/wayland_ctx.c +++ b/gfx/drivers_context/wayland_ctx.c @@ -51,6 +51,19 @@ #include "../../input/input_driver.h" #include "../../input/input_keymaps.h" + +typedef struct touch_pos +{ + bool active; + int32_t id; + unsigned x; + unsigned y; +} touch_pos_t; + +static int num_active_touches; +static touch_pos_t active_touch_positions[MAX_TOUCHES]; + + typedef struct gfx_ctx_wayland_data { #ifdef HAVE_EGL @@ -70,6 +83,7 @@ typedef struct gfx_ctx_wayland_data struct wl_shell *shell; struct wl_keyboard *wl_keyboard; struct wl_pointer *wl_pointer; + struct wl_touch *wl_touch; struct wl_seat *seat; struct wl_shm *shm; unsigned swap_interval; @@ -93,6 +107,7 @@ typedef struct gfx_ctx_wayland_data #endif } gfx_ctx_wayland_data_t; + static enum gfx_ctx_api wl_api = GFX_CTX_NONE; #ifndef EGL_OPENGL_ES3_BIT_KHR @@ -329,8 +344,139 @@ static const struct wl_pointer_listener pointer_listener = { pointer_handle_axis, }; +static void touch_handle_down(void *data, + struct wl_touch *wl_touch, + uint32_t serial, + uint32_t time, + struct wl_surface *surface, + int32_t id, + wl_fixed_t x, + wl_fixed_t y) +{ + int i; + gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; + + if (num_active_touches < MAX_TOUCHES) + { + for (i = 0; i < MAX_TOUCHES; i++) + { + /* Use next empty slot */ + if (!active_touch_positions[i].active) + { + active_touch_positions[num_active_touches].active = true; + active_touch_positions[num_active_touches].id = id; + active_touch_positions[num_active_touches].x = (unsigned) wl_fixed_to_int(x); + active_touch_positions[num_active_touches].y = (unsigned) wl_fixed_to_int(y); + num_active_touches++; + break; + } + } + } +} +static void reorder_touches(void) +{ + int i, j; + if (num_active_touches == 0) + return; + + for (i = 0; i < MAX_TOUCHES; i++) + { + if (!active_touch_positions[i].active) + { + for (j=i+1; jwl_pointer); wl->wl_pointer = NULL; } + if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !wl->wl_touch) + { + wl->wl_touch = wl_seat_get_touch(seat); + wl_touch_add_listener(wl->wl_touch, &touch_listener, wl); + } + else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && wl->wl_touch) + { + wl_touch_destroy(wl->wl_touch); + wl->wl_touch = NULL; + } + } static void seat_handle_name(void *data, struct wl_seat *seat, const char *name) @@ -368,6 +525,22 @@ static const struct wl_seat_listener seat_listener = { seat_handle_name, }; +/* Touch handle functions */ + +bool wayland_context_gettouchpos(void *data, unsigned id, + unsigned* touch_x, unsigned* touch_y) +{ + gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; + + if (id >= MAX_TOUCHES) + return false; + *touch_x = active_touch_positions[id].x; + *touch_y = active_touch_positions[id].y; + return active_touch_positions[id].active; +} + + + /* Shell surface callbacks. */ static void shell_surface_handle_ping(void *data, struct wl_shell_surface *shell_surface, @@ -503,7 +676,7 @@ static void registry_handle_global(void *data, struct wl_registry *reg, wl->shm = (struct wl_shm*)wl_registry_bind(reg, id, &wl_shm_interface, 1); else if (string_is_equal(interface, "wl_seat")) { - wl->seat = (struct wl_seat*)wl_registry_bind(reg, id, &wl_seat_interface, 4); + wl->seat = (struct wl_seat*)wl_registry_bind(reg, id, &wl_seat_interface, 2); wl_seat_add_listener(wl->seat, &seat_listener, wl); } } @@ -568,6 +741,8 @@ static void gfx_ctx_wl_destroy_resources(gfx_ctx_wayland_data_t *wl) wl_keyboard_destroy(wl->wl_keyboard); if (wl->wl_pointer) wl_pointer_destroy(wl->wl_pointer); + if (wl->wl_touch) + wl_touch_destroy(wl->wl_touch); if (wl->cursor.theme) wl_cursor_theme_destroy(wl->cursor.theme); @@ -776,6 +951,7 @@ static bool gfx_ctx_wl_get_metrics(void *data, static void *gfx_ctx_wl_init(video_frame_info_t *video_info, void *video_driver) { + int i; #ifdef HAVE_OPENGL static const EGLint egl_attribs_gl[] = { WL_EGL_ATTRIBS_BASE, @@ -924,12 +1100,23 @@ static void *gfx_ctx_wl_init(video_frame_info_t *video_info, void *video_driver) break; } + wl->input.keyboard_focus = true; wl->input.mouse.focus = true; wl->cursor.surface = wl_compositor_create_surface(wl->compositor); wl->cursor.theme = wl_cursor_theme_load(NULL, 16, wl->shm); wl->cursor.default_cursor = wl_cursor_theme_get_cursor(wl->cursor.theme, "left_ptr"); + + num_active_touches = 0; + for (i = 0;i < MAX_TOUCHES;i++) + { + active_touch_positions[i].active = false; + active_touch_positions[i].id = -1; + active_touch_positions[i].x = (unsigned) 0; + active_touch_positions[i].y = (unsigned) 0; + } + flush_wayland_fd(&wl->input); #ifdef HAVE_DBUS diff --git a/gfx/drivers_shader/shader_glsl.c b/gfx/drivers_shader/shader_glsl.c index 8d8dbb4590..784cf41c7f 100644 --- a/gfx/drivers_shader/shader_glsl.c +++ b/gfx/drivers_shader/shader_glsl.c @@ -539,8 +539,6 @@ static bool gl_glsl_compile_programs( return false; } - *pass->source.path = '\0'; - vertex = pass->source.string.vertex; fragment = pass->source.string.fragment; diff --git a/gfx/drivers_shader/slang_process.cpp b/gfx/drivers_shader/slang_process.cpp index d1a113c3af..a8a6db588b 100644 --- a/gfx/drivers_shader/slang_process.cpp +++ b/gfx/drivers_shader/slang_process.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -200,7 +201,7 @@ static bool slang_process_reflection( string uniform_id = get_semantic_name( sl_reflection, (slang_semantic)semantic, 0); - strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); + strlcpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); if (src.push_constant) { @@ -226,7 +227,7 @@ static bool slang_process_reflection( string uniform_id = get_semantic_name( sl_reflection, SLANG_SEMANTIC_FLOAT_PARAMETER, i); - strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); + strlcpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); if (src.push_constant) { @@ -272,7 +273,7 @@ static bool slang_process_reflection( string id = get_semantic_name( sl_reflection, (slang_texture_semantic)semantic, index); - strncpy(texture.id, id.c_str(), sizeof(texture.id)); + strlcpy(texture.id, id.c_str(), sizeof(texture.id)); textures.push_back(texture); @@ -297,7 +298,7 @@ static bool slang_process_reflection( sl_reflection, (slang_texture_semantic)semantic, index); - strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); + strlcpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); if (src.push_constant) { @@ -361,7 +362,7 @@ bool slang_process( return false; if (!*pass.alias && !output.meta.name.empty()) - strncpy(pass.alias, output.meta.name.c_str(), sizeof(pass.alias) - 1); + strlcpy(pass.alias, output.meta.name.c_str(), sizeof(pass.alias) - 1); out->format = output.meta.rt_format; diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 3a38c46eed..37efe7b01a 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -262,12 +262,12 @@ struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END] = { }; static const video_driver_t *video_drivers[] = { -#ifdef HAVE_VULKAN - &video_vulkan, -#endif #ifdef HAVE_OPENGL &video_gl, #endif +#ifdef HAVE_VULKAN + &video_vulkan, +#endif #ifdef HAVE_METAL &video_metal, #endif @@ -1641,7 +1641,7 @@ bool video_driver_is_stub_frame(void) bool video_driver_supports_recording(void) { settings_t *settings = config_get_ptr(); - return settings->bools.video_gpu_record + return settings->bools.video_gpu_record && current_video->read_viewport; } @@ -1668,7 +1668,7 @@ void video_driver_set_viewport_config(void) { struct retro_game_geometry *geom = &video_driver_av_info.geometry; - if (geom->aspect_ratio > 0.0f && + if (geom->aspect_ratio > 0.0f && settings->bools.video_aspect_ratio_auto) aspectratio_lut[ASPECT_RATIO_CONFIG].value = geom->aspect_ratio; else @@ -1898,7 +1898,7 @@ void video_driver_update_viewport(struct video_viewport* vp, bool force_full, bo } else if (device_aspect > desired_aspect) { - delta = (desired_aspect / device_aspect - 1.0f) + delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; vp->x = (int)roundf(vp->full_width * (0.5f - delta)); vp->width = (unsigned)roundf(2.0f * vp->full_width * delta); @@ -1909,7 +1909,7 @@ void video_driver_update_viewport(struct video_viewport* vp, bool force_full, bo { vp->x = 0; vp->width = vp->full_width; - delta = (device_aspect / desired_aspect - 1.0f) + delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; vp->y = (int)roundf(vp->full_height * (0.5f - delta)); vp->height = (unsigned)roundf(2.0f * vp->full_height * delta); @@ -2324,7 +2324,7 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp, unsigned base_width; /* Use system reported sizes as these define the * geometry for the "normal" case. */ - unsigned base_height = + unsigned base_height = video_driver_av_info.geometry.base_height; if (base_height == 0) @@ -2631,9 +2631,9 @@ void video_driver_frame(const void *data, unsigned width, /* Display the FPS, with a higher priority. */ if (video_info.fps_show) runloop_msg_queue_push(video_info.fps_text, 2, 1, true); - - /* trigger set resolution*/ - if (video_info.crt_switch_resolution) + + /* trigger set resolution*/ + if (video_info.crt_switch_resolution) { video_driver_crt_switching_active = true; @@ -2646,9 +2646,9 @@ void video_driver_frame(const void *data, unsigned width, crt_switch_res_core(width, height, video_driver_core_hz); } else if (!video_info.crt_switch_resolution) - video_driver_crt_switching_active = false; - - /* trigger set resolution*/ + video_driver_crt_switching_active = false; + + /* trigger set resolution*/ } void video_driver_display_type_set(enum rarch_display_type type) @@ -2741,8 +2741,8 @@ void video_driver_build_info(video_frame_info_t *video_info) settings = config_get_ptr(); custom_vp = &settings->video_viewport_custom; video_info->refresh_rate = settings->floats.video_refresh_rate; - video_info->crt_switch_resolution = settings->bools.crt_switch_resolution; - video_info->crt_switch_resolution_super = settings->uints.crt_switch_resolution_super; + video_info->crt_switch_resolution = settings->bools.crt_switch_resolution; + video_info->crt_switch_resolution_super = settings->uints.crt_switch_resolution_super; video_info->black_frame_insertion = settings->bools.video_black_frame_insertion; video_info->hard_sync = settings->bools.video_hard_sync; video_info->hard_sync_frames = settings->uints.video_hard_sync_frames; @@ -2873,13 +2873,13 @@ bool video_driver_translate_coord_viewport( return false; if (mouse_x >= 0 && mouse_x <= norm_full_vp_width) - scaled_screen_x = ((2 * mouse_x * 0x7fff) + scaled_screen_x = ((2 * mouse_x * 0x7fff) / norm_full_vp_width) - 0x7fff; else scaled_screen_x = -0x8000; /* OOB */ if (mouse_y >= 0 && mouse_y <= norm_full_vp_height) - scaled_screen_y = ((2 * mouse_y * 0x7fff) + scaled_screen_y = ((2 * mouse_y * 0x7fff) / norm_full_vp_height) - 0x7fff; else scaled_screen_y = -0x8000; /* OOB */ @@ -2888,13 +2888,13 @@ bool video_driver_translate_coord_viewport( mouse_y -= vp->y; if (mouse_x >= 0 && mouse_x <= norm_vp_width) - scaled_x = ((2 * mouse_x * 0x7fff) + scaled_x = ((2 * mouse_x * 0x7fff) / norm_vp_width) - 0x7fff; else scaled_x = -0x8000; /* OOB */ if (mouse_y >= 0 && mouse_y <= norm_vp_height) - scaled_y = ((2 * mouse_y * 0x7fff) + scaled_y = ((2 * mouse_y * 0x7fff) / norm_vp_height) - 0x7fff; else scaled_y = -0x8000; /* OOB */ @@ -2920,7 +2920,7 @@ void video_driver_get_status(uint64_t *frame_count, bool * is_alive, bool *is_focused) { *frame_count = video_driver_frame_count; - *is_alive = current_video ? + *is_alive = current_video ? current_video->alive(video_driver_data) : true; *is_focused = video_driver_cb_has_focus(); } @@ -3002,7 +3002,7 @@ bool video_context_driver_find_next_driver(void) * * Initialize graphics context driver. * - * Returns: graphics context driver if successfully initialized, + * Returns: graphics context driver if successfully initialized, * otherwise NULL. **/ static const gfx_ctx_driver_t *video_context_driver_init( @@ -3238,7 +3238,7 @@ bool video_context_driver_get_refresh_rate(float *refresh_rate) return false; if (refresh_rate) - *refresh_rate = + *refresh_rate = current_video_context.get_refresh_rate(video_context_data); return true; @@ -3247,7 +3247,7 @@ bool video_context_driver_get_refresh_rate(float *refresh_rate) bool video_context_driver_input_driver(gfx_ctx_input_t *inp) { settings_t *settings = config_get_ptr(); - const char *joypad_name = settings ? + const char *joypad_name = settings ? settings->arrays.input_joypad_driver : NULL; if (!current_video_context.input_driver) @@ -3518,6 +3518,9 @@ bool video_shader_driver_get_current_shader(video_shader_ctx_t *shader) bool video_shader_driver_direct_get_current_shader( video_shader_ctx_t *shader) { + if (!current_shader) + return false; + shader->data = current_shader->get_current_shader(current_shader_data); return true; diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index 00d96ece1d..6151618f15 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -35,6 +35,7 @@ #include "../verbosity.h" #include "../configuration.h" #include "../frontend/frontend_driver.h" +#include "../command.h" #include "video_driver.h" #include "video_shader_parse.h" @@ -155,6 +156,7 @@ static bool video_shader_parse_pass(config_file_t *conf, strlcpy(pass->source.path, tmp_str, sizeof(pass->source.path)); else strlcpy(pass->source.path, tmp_path, sizeof(pass->source.path)); + free(tmp_path); /* Smooth */ @@ -208,7 +210,10 @@ static bool video_shader_parse_pass(config_file_t *conf, config_get_array(conf, scale_name_buf, scale_type_y, sizeof(scale_type_y)); if (!*scale_type && !*scale_type_x && !*scale_type_y) + { + free(tmp_str); return true; + } if (*scale_type) { @@ -253,6 +258,7 @@ static bool video_shader_parse_pass(config_file_t *conf, } snprintf(attr_name_buf, sizeof(attr_name_buf), "scale%u", i); + if (scale->type_x == RARCH_SCALE_ABSOLUTE) { if (config_get_int(conf, attr_name_buf, &iattr)) @@ -277,6 +283,7 @@ static bool video_shader_parse_pass(config_file_t *conf, } snprintf(attr_name_buf, sizeof(attr_name_buf), "scale%u", i); + if (scale->type_y == RARCH_SCALE_ABSOLUTE) { if (config_get_int(conf, attr_name_buf, &iattr)) @@ -496,13 +503,13 @@ bool video_shader_resolve_parameters(config_file_t *conf, char *line = NULL; const char *path = shader->pass[i].source.path; - if (string_is_empty(path)) - continue; + if (string_is_empty(path)) + continue; #if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) - /* First try to use the more robust slang + /* First try to use the more robust slang * implementation to support #includes. */ - /* FIXME: The check for slang can be removed + /* FIXME: The check for slang can be removed * if it's sufficiently tested for * GLSL/Cg as well, it should be the same implementation. */ if (string_is_equal(path_get_extension(path), "slang") && @@ -522,6 +529,9 @@ bool video_shader_resolve_parameters(config_file_t *conf, line = (char*)malloc(4096 * sizeof(char)); line[0] = '\0'; + /* even though the pass is set in the loop too, not all passes have parameters */ + param->pass = i; + while (shader->num_parameters < ARRAY_SIZE(shader->parameters) && intfstream_gets(file, line, line_size)) { @@ -539,9 +549,11 @@ bool video_shader_resolve_parameters(config_file_t *conf, if (ret == 5) param->step = 0.1f * (param->maximum - param->minimum); - RARCH_LOG("Found #pragma parameter %s (%s) %f %f %f %f\n", + param->pass = i; + + RARCH_LOG("Found #pragma parameter %s (%s) %f %f %f %f in pass %d\n", param->desc, param->id, param->initial, - param->minimum, param->maximum, param->step); + param->minimum, param->maximum, param->step, param->pass); param->current = param->initial; shader->num_parameters++; @@ -632,7 +644,7 @@ static bool video_shader_parse_imports(config_file_t *conf, var->type = RARCH_STATE_TRANSITION_PREV; else if (string_is_equal(semantic, "python")) var->type = RARCH_STATE_PYTHON; - else + else { RARCH_ERR("Invalid semantic.\n"); goto error; @@ -736,6 +748,8 @@ bool video_shader_read_conf_cgp(config_file_t *conf, shader->passes = MIN(shaders, GFX_MAX_SHADERS); attr.i = 0; + strlcpy(shader->path, conf->path, sizeof(shader->path)); + if (settings->bools.video_shader_watch_files) { if (file_change_data) @@ -752,11 +766,14 @@ bool video_shader_read_conf_cgp(config_file_t *conf, if (!video_shader_parse_pass(conf, &shader->pass[i], i)) { if (file_list) + { string_list_free(file_list); + file_list = NULL; + } return false; } - if (settings->bools.video_shader_watch_files) + if (settings->bools.video_shader_watch_files && file_list) string_list_append(file_list, shader->pass[i].source.path, attr); } @@ -770,9 +787,12 @@ bool video_shader_read_conf_cgp(config_file_t *conf, frontend_driver_watch_path_for_changes(file_list, flags, &file_change_data); - string_list_free(file_list); + if (file_list) + string_list_free(file_list); } + command_event(CMD_EVENT_SHADER_PRESET_LOADED, NULL); + if (!video_shader_parse_textures(conf, shader)) return false; @@ -1116,11 +1136,16 @@ enum rarch_shader_type video_shader_get_type_from_ext( { enum gfx_ctx_api api = video_context_driver_get_api(); + if (string_is_empty(ext)) + return RARCH_SHADER_NONE; + + if (strlen(ext) > 1 && ext[0] == '.') + ext++; + *is_preset = false; if ( - string_is_equal(ext, "cg") || - string_is_equal(ext, "CG") + string_is_equal_case_insensitive(ext, "cg") ) { switch (api) @@ -1130,7 +1155,7 @@ enum rarch_shader_type video_shader_get_type_from_ext( case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: { - struct retro_hw_render_callback *hwr = + struct retro_hw_render_callback *hwr = video_driver_get_hw_context(); if (hwr) { @@ -1162,7 +1187,7 @@ enum rarch_shader_type video_shader_get_type_from_ext( case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: { - struct retro_hw_render_callback *hwr = + struct retro_hw_render_callback *hwr = video_driver_get_hw_context(); if (hwr) { @@ -1227,7 +1252,7 @@ enum rarch_shader_type video_shader_get_type_from_ext( } } if ( - string_is_equal_case_insensitive(ext, "slangp") + string_is_equal_case_insensitive(ext, "slangp") ) { *is_preset = true; diff --git a/gfx/video_shader_parse.h b/gfx/video_shader_parse.h index cb76a23a85..15d228a44f 100644 --- a/gfx/video_shader_parse.h +++ b/gfx/video_shader_parse.h @@ -105,6 +105,7 @@ struct video_shader_parameter float initial; float maximum; float step; + int pass; }; struct video_shader_pass @@ -146,6 +147,7 @@ struct video_shader char prefix[64]; char script_class[512]; char script_path[PATH_MAX_LENGTH]; + char path[PATH_MAX_LENGTH]; char *script; /* Dynamically allocated. Must be free'd. Only used by XML. */ bool modern; /* Only used for XML shaders. */ diff --git a/griffin/griffin_cpp.cpp b/griffin/griffin_cpp.cpp index 970ac5cffe..c3b2bc7116 100644 --- a/griffin/griffin_cpp.cpp +++ b/griffin/griffin_cpp.cpp @@ -41,6 +41,18 @@ UI #include "../ui/drivers/qt/ui_qt_browser_window.cpp" #include "../ui/drivers/qt/ui_qt_msg_window.cpp" #include "../ui/drivers/qt/ui_qt_application.cpp" +#include "../ui/drivers/qt/flowlayout.cpp" +#include "../ui/drivers/qt/shaderparamsdialog.cpp" +#include "../ui/drivers/qt/coreoptionsdialog.cpp" +#include "../ui/drivers/qt/filedropwidget.cpp" +#include "../ui/drivers/qt/coreinfodialog.cpp" +#include "../ui/drivers/qt/playlistentrydialog.cpp" +#include "../ui/drivers/qt/viewoptionsdialog.cpp" +#include "../ui/drivers/qt/playlist.cpp" +#include "../ui/drivers/qt/updateretroarch.cpp" +#include "../ui/drivers/qt/thumbnaildownload.cpp" +#include "../ui/drivers/qt/thumbnailpackdownload.cpp" +#include "../ui/drivers/qt/playlistthumbnaildownload.cpp" #endif /*============================================================ diff --git a/input/drivers/wayland_input.c b/input/drivers/wayland_input.c index 0363624320..88b7169d1d 100644 --- a/input/drivers/wayland_input.c +++ b/input/drivers/wayland_input.c @@ -50,6 +50,7 @@ /* TODO/FIXME - * fix game focus toggle */ + /* Forward declaration */ void flush_wayland_fd(void *data); @@ -98,6 +99,31 @@ static int16_t input_wl_lightgun_state(input_ctx_wayland_data_t *wl, unsigned id return 0; } +/* forward declaration */ +bool wayland_context_gettouchpos(void *data, unsigned id, + unsigned* touch_x, unsigned* touch_y); + +static void input_wl_touch_pool(void *data) +{ + int id; + unsigned touch_x = 0; + unsigned touch_y = 0; + input_ctx_wayland_data_t *wl = (input_ctx_wayland_data_t*)data; + + if (!wl) + return; + + for (id = 0; id < MAX_TOUCHES; id++) + { + if (wayland_context_gettouchpos(wl, id, &touch_x, &touch_y)) + wl->touches[id].active = true; + else + wl->touches[id].active = false; + wl->touches[id].x = touch_x; + wl->touches[id].y = touch_y; + } +} + static void input_wl_poll(void *data) { input_ctx_wayland_data_t *wl = (input_ctx_wayland_data_t*)data; @@ -119,6 +145,8 @@ static void input_wl_poll(void *data) if (wl->joypad) wl->joypad->poll(); + + input_wl_touch_pool(wl); } static int16_t input_wl_analog_pressed(input_ctx_wayland_data_t *wl, @@ -175,8 +203,9 @@ static int16_t input_wl_pointer_state(input_ctx_wayland_data_t *wl, vp.full_height = 0; if (!(video_driver_translate_coord_viewport_wrap(&vp, - wl->mouse.x, wl->mouse.y, + wl->mouse.x, wl->mouse.y, &res_x, &res_y, &res_screen_x, &res_screen_y))) + return 0; if (screen) @@ -203,6 +232,59 @@ static int16_t input_wl_pointer_state(input_ctx_wayland_data_t *wl, return 0; } +static int16_t input_wl_touch_state(input_ctx_wayland_data_t *wl, + unsigned idx, unsigned id, bool screen) +{ + struct video_viewport vp; + + bool inside = false; + int16_t res_x = 0; + int16_t res_y = 0; + int16_t res_screen_x = 0; + int16_t res_screen_y = 0; + + vp.x = 0; + vp.y = 0; + vp.width = 0; + vp.height = 0; + vp.full_width = 0; + vp.full_height = 0; + + if (idx > MAX_TOUCHES) + return 0; + + if (!(video_driver_translate_coord_viewport_wrap(&vp, + wl->touches[idx].x, wl->touches[idx].y, + &res_x, &res_y, &res_screen_x, &res_screen_y))) + return 0; + + if (screen) + { + res_x = res_screen_x; + res_y = res_screen_y; + } + + inside = (res_x >= -0x7fff) && (res_y >= -0x7fff); + + if (!inside) + return 0; + + switch (id) + { + case RETRO_DEVICE_ID_POINTER_X: + return res_x; + case RETRO_DEVICE_ID_POINTER_Y: + return res_y; + case RETRO_DEVICE_ID_POINTER_PRESSED: + return wl->touches[idx].active; + } + + return 0; +} + + + + static int16_t input_wl_state(void *data, rarch_joypad_info_t joypad_info, const struct retro_keybind **binds, @@ -233,11 +315,15 @@ static int16_t input_wl_state(void *data, return input_wl_mouse_state(wl, id, true); case RETRO_DEVICE_POINTER: - case RARCH_DEVICE_POINTER_SCREEN: if (idx == 0) return input_wl_pointer_state(wl, idx, id, device == RARCH_DEVICE_POINTER_SCREEN); break; + case RARCH_DEVICE_POINTER_SCREEN: + if (idx < MAX_TOUCHES) + return input_wl_touch_state(wl, idx, id, + device == RARCH_DEVICE_POINTER_SCREEN); + break; case RETRO_DEVICE_LIGHTGUN: return input_wl_lightgun_state(wl, id); } diff --git a/input/drivers_hid/iohidmanager_hid.c b/input/drivers_hid/iohidmanager_hid.c index 77e9c6defd..2f0a8da0fe 100644 --- a/input/drivers_hid/iohidmanager_hid.c +++ b/input/drivers_hid/iohidmanager_hid.c @@ -56,7 +56,9 @@ struct iohidmanager_hid_adapter apple_input_rec_t *hats; apple_input_rec_t *buttons; uint8_t data[2048]; +#if !(defined(__ppc__) || defined(__ppc64__)) uint32_t uniqueId; +#endif }; CFComparisonResult iohidmanager_sort_elements(const void *val1, const void *val2, void *context) @@ -523,6 +525,7 @@ static uint32_t iohidmanager_hid_device_get_location_id(IOHIDDeviceRef device) CFSTR(kIOHIDLocationIDKey)); } +#if !(defined(__ppc__) || defined(__ppc64__)) static uint32_t iohidmanager_hid_device_get_unique_id(IOHIDDeviceRef device) { /* osx seems to assign an unique id to each device when they are plugged in @@ -530,6 +533,7 @@ static uint32_t iohidmanager_hid_device_get_unique_id(IOHIDDeviceRef device) * other device plugged */ return iohidmanager_hid_device_get_int_property(device,CFSTR(kIOHIDUniqueIDKey)); } +#endif static void iohidmanager_hid_device_get_product_string( IOHIDDeviceRef device, char *buf, size_t len) @@ -561,12 +565,20 @@ static void iohidmanager_hid_device_add_autodetect(unsigned idx, RARCH_LOG("Port %d: %s.\n", idx, device_name); } -static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanager_hid_t* hid) +#if defined(__ppc__) || defined(__ppc64__) +static void iohidmanager_hid_device_add(IOHIDDeviceRef device, + iohidmanager_hid_t* hid) +#else +static void iohidmanager_hid_device_add_device( + IOHIDDeviceRef device, iohidmanager_hid_t* hid) +#endif { int i; /* get device unique id */ +#if !(defined(__ppc__) || defined(__ppc64__)) uint32_t deviceUniqueId = iohidmanager_hid_device_get_unique_id(device); +#endif static const uint32_t axis_use_ids[11] = { @@ -583,6 +595,7 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag kHIDUsage_Sim_Brake }; +#if !(defined(__ppc__) || defined(__ppc64__)) /* check if pad was already registered previously (by deterministic method) * if so do not re-add the pad */ for (i=0; iuniqueId == deviceUniqueId) return; } +#endif IOReturn ret; uint16_t dev_vid, dev_pid; @@ -633,7 +647,9 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag dev_vid = iohidmanager_hid_device_get_vendor_id (device); dev_pid = iohidmanager_hid_device_get_product_id (device); +#if !(defined(__ppc__) || defined(__ppc64__)) adapter->uniqueId = deviceUniqueId; +#endif adapter->slot = pad_connection_pad_init(hid->slots, adapter->name, dev_vid, dev_pid, adapter, @@ -904,13 +920,14 @@ error: } } - +#if !(defined(__ppc__) || defined(__ppc64__)) static void iohidmanager_hid_device_add(void *data, IOReturn result, void* sender, IOHIDDeviceRef device) { iohidmanager_hid_t *hid = (iohidmanager_hid_t*) hid_driver_get_data(); iohidmanager_hid_device_add_device(device, hid); } +#endif static void iohidmanager_hid_append_matching_dictionary( CFMutableArrayRef array, @@ -1029,7 +1046,11 @@ static int iohidmanager_hid_manager_set_device_matching( hid_list_t * ptr = devList; while (ptr != NULL) { +#if defined(__ppc__) || defined(__ppc64__) + iohidmanager_hid_device_add(ptr->device, hid); +#else iohidmanager_hid_device_add_device(ptr->device, hid); +#endif //printf("%d\n",ptr->lid); ptr = ptr->next; @@ -1039,6 +1060,7 @@ static int iohidmanager_hid_manager_set_device_matching( free(device_array); +#if !(defined(__ppc__) || defined(__ppc64__)) /* register call back to dynamically add device plugged when retroarch is * running * those will be added after the one plugged when retroarch was launched, @@ -1061,6 +1083,7 @@ static int iohidmanager_hid_manager_set_device_matching( iohidmanager_hid_device_add, 0); CFRelease(matcher); +#endif return 0; } diff --git a/intl/msg_hash_ar.h b/intl/msg_hash_ar.h index 3653d191b7..881210a828 100644 --- a/intl/msg_hash_ar.h +++ b/intl/msg_hash_ar.h @@ -3456,9 +3456,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Enable background filler thickness") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For 15 kHz CRT displays only. Attempts to use exact core/game resolution and refresh rate.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "When CRT SwitchRes is enabled, force ultrawide horizontal resolution to minimize mode switching.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, "Show Rewind Settings") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, @@ -3517,6 +3517,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Clear") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Enable Discord" diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index 2b0cda9c45..c8ff8960de 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -3240,9 +3240,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Enable background filler thickness") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For 15 kHz CRT displays only. Attempts to use exact core/game resolution and refresh rate.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "When CRT SwitchRes is enabled, force ultrawide horizontal resolution to minimize mode switching.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, "Show Rewind Settings") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, @@ -3301,6 +3301,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Clear") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Enable Discord" diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index fbf997e55e..dcc7565720 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -3232,9 +3232,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Enable background filler thickness") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For 15 kHz CRT displays only. Attempts to use exact core/game resolution and refresh rate.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "When CRT SwitchRes is enabled, force ultrawide horizontal resolution to minimize mode switching.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, "Show Rewind Settings") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, @@ -3293,6 +3293,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Clear") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Enable Discord" diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 69e95be72a..239899abab 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -3342,9 +3342,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Enable background filler thickness") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For 15 kHz CRT displays only. Attempts to use exact core/game resolution and refresh rate.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "When CRT SwitchRes is enabled, force ultrawide horizontal resolution to minimize mode switching.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, "Show Rewind Settings") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, @@ -3403,6 +3403,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Clear") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Enable Discord" diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index bc2fe52fa5..e157edfc74 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -3107,9 +3107,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Enable background filler thickness") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For 15 kHz CRT displays only. Attempts to use exact core/game resolution and refresh rate.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "When CRT SwitchRes is enabled, force ultrawide horizontal resolution to minimize mode switching.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, "Show Rewind Settings") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, @@ -3168,6 +3168,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Clear") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Enable Discord" diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index 7341519c4b..34ede5266d 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -1,7168 +1,7424 @@ MSG_HASH( - MSG_COMPILER, - "Compilador" - ) + MSG_COMPILER, + "Compilador" + ) MSG_HASH( - MSG_UNKNOWN_COMPILER, - "Compilador Desconocido" - ) + MSG_UNKNOWN_COMPILER, + "Compilador Desconocido" + ) MSG_HASH( - MSG_DEVICE_DISCONNECTED_FROM_PORT, - "Dispositivo desconectado del puerto" - ) + MSG_DEVICE_DISCONNECTED_FROM_PORT, + "Dispositivo desconectado del puerto" + ) MSG_HASH( - MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, - "Recibido un comando de juego en red desconocido" - ) + MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, + "Recibido un comando de juego en red desconocido" + ) MSG_HASH( - MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER, - "El archivo ya existe. Guardándolo en el búfer de respaldo" - ) + MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER, + "El archivo ya existe. Guardándolo en el búfer de respaldo" + ) MSG_HASH( - MSG_GOT_CONNECTION_FROM, - "Conexión obtenida de: \"%s\"" - ) + MSG_GOT_CONNECTION_FROM, + "Conexión obtenida de: \"%s\"" + ) MSG_HASH( - MSG_GOT_CONNECTION_FROM_NAME, - "Conexión obtenida de: \"%s (%s)\"" - ) + MSG_GOT_CONNECTION_FROM_NAME, + "Conexión obtenida de: \"%s (%s)\"" + ) MSG_HASH( - MSG_PUBLIC_ADDRESS, - "Dirección pública" - ) + MSG_PUBLIC_ADDRESS, + "Dirección pública" + ) MSG_HASH( - MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, - "No se pasaron argumentos y no hay menú integrado, Mostrando ayuda..." - ) + MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, + "No se pasaron argumentos y no hay menú integrado, Mostrando ayuda..." + ) MSG_HASH( - MSG_SETTING_DISK_IN_TRAY, - "Poniendo disco en bandeja" - ) + MSG_SETTING_DISK_IN_TRAY, + "Poniendo disco en bandeja" + ) MSG_HASH( - MSG_WAITING_FOR_CLIENT, - "Esperando al cliente..." - ) + MSG_WAITING_FOR_CLIENT, + "Esperando al cliente..." + ) MSG_HASH( - MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME, - "As dejado el juego" - ) + MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME, + "As dejado el juego" + ) MSG_HASH( - MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N, - "Unido como jugador %u" - ) + MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N, + "Unido como jugador %u" + ) MSG_HASH( - MSG_NETPLAY_YOU_HAVE_JOINED_WITH_INPUT_DEVICES_S, - "Se ha unido con el dispositivo de entrada %.*s" - ) + MSG_NETPLAY_YOU_HAVE_JOINED_WITH_INPUT_DEVICES_S, + "Se ha unido con el dispositivo de entrada %.*s" + ) MSG_HASH( - MSG_NETPLAY_PLAYER_S_LEFT, - "Jugador %.*s dejó el juego" - ) + MSG_NETPLAY_PLAYER_S_LEFT, + "Jugador %.*s dejó el juego" + ) MSG_HASH( - MSG_NETPLAY_S_HAS_JOINED_AS_PLAYER_N, - "%.*s se ha unido como jugador %u" - ) + MSG_NETPLAY_S_HAS_JOINED_AS_PLAYER_N, + "%.*s se ha unido como jugador %u" + ) MSG_HASH( - MSG_NETPLAY_S_HAS_JOINED_WITH_INPUT_DEVICES_S, - "%.*s se ha unido con los dispositivos de entrada %.*s" - ) + MSG_NETPLAY_S_HAS_JOINED_WITH_INPUT_DEVICES_S, + "%.*s se ha unido con los dispositivos de entrada %.*s" + ) MSG_HASH( - MSG_NETPLAY_NOT_RETROARCH, - "Una conexión de netplay falló, probablemente no este usando RetroArch o esté usando una versión antigua de RetroArch" - ) + MSG_NETPLAY_NOT_RETROARCH, + "Una conexión de netplay falló, probablemente no este usando RetroArch o esté usando una versión antigua de RetroArch" + ) MSG_HASH( - MSG_NETPLAY_OUT_OF_DATE, - "El par de netplay esta usando una versión antigua de RetroArch. No se puede conectar" - ) + MSG_NETPLAY_OUT_OF_DATE, + "El par de netplay esta usando una versión antigua de RetroArch. No se puede conectar" + ) MSG_HASH( - MSG_NETPLAY_DIFFERENT_VERSIONS, - "ADVERTENCIA: Un par de netplay esta usando una versión diferente de Retroarch. Si ocurren problemas, use la misma versión" - ) + MSG_NETPLAY_DIFFERENT_VERSIONS, + "ADVERTENCIA: Un par de netplay esta usando una versión diferente de Retroarch. Si ocurren problemas, use la misma versión" + ) MSG_HASH( - MSG_NETPLAY_DIFFERENT_CORES, - "Un par de netplay esta usando una versión diferente del núcleo. No se puede conectar" - ) + MSG_NETPLAY_DIFFERENT_CORES, + "Un par de netplay esta usando una versión diferente del núcleo. No se puede conectar" + ) MSG_HASH( - MSG_NETPLAY_DIFFERENT_CORE_VERSIONS, - "ADVERTENCIA: Un par de netplay está ejecutando una versión diferente del núcleo. Si ocurren problemas, use la misma versión" - ) + MSG_NETPLAY_DIFFERENT_CORE_VERSIONS, + "ADVERTENCIA: Un par de netplay está ejecutando una versión diferente del núcleo. Si ocurren problemas, use la misma versión" + ) MSG_HASH( - MSG_NETPLAY_ENDIAN_DEPENDENT, - "Este núcleo no soporta juego en red entre diferentes arquitecturas de sistemas" - ) + MSG_NETPLAY_ENDIAN_DEPENDENT, + "Este núcleo no soporta juego en red entre diferentes arquitecturas de sistemas" + ) MSG_HASH( - MSG_NETPLAY_PLATFORM_DEPENDENT, - "Este núcleo no soporta juego en red entre diferentes sistemas" - ) + MSG_NETPLAY_PLATFORM_DEPENDENT, + "Este núcleo no soporta juego en red entre diferentes sistemas" + ) MSG_HASH( - MSG_NETPLAY_ENTER_PASSWORD, - "Introducir la contraseña del servidor de juego en red:" - ) + MSG_NETPLAY_ENTER_PASSWORD, + "Introducir la contraseña del servidor de juego en red:" + ) MSG_HASH( - MSG_NETPLAY_INCORRECT_PASSWORD, - "Contraseña incorrecta" - ) + MSG_NETPLAY_INCORRECT_PASSWORD, + "Contraseña incorrecta" + ) MSG_HASH( - MSG_NETPLAY_SERVER_NAMED_HANGUP, - "\"%s\" se ha desconectado" - ) + MSG_NETPLAY_SERVER_NAMED_HANGUP, + "\"%s\" se ha desconectado" + ) MSG_HASH( - MSG_NETPLAY_SERVER_HANGUP, - "Un cliente de juego en red se ha desconectado" - ) + MSG_NETPLAY_SERVER_HANGUP, + "Un cliente de juego en red se ha desconectado" + ) MSG_HASH( - MSG_NETPLAY_CLIENT_HANGUP, - "Desconectado del juego en red" - ) + MSG_NETPLAY_CLIENT_HANGUP, + "Desconectado del juego en red" + ) MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED, - "No tienes permiso para jugar" - ) + MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED, + "No tienes permiso para jugar" + ) MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS, - "No hay lugar disponible" - ) + MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS, + "No hay lugar disponible" + ) MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY_NOT_AVAILABLE, - "El dispositivo de entrada pedido no esta disponible" - ) + MSG_NETPLAY_CANNOT_PLAY_NOT_AVAILABLE, + "El dispositivo de entrada pedido no esta disponible" + ) MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY, - "No se puede cambiar al modo juego" - ) + MSG_NETPLAY_CANNOT_PLAY, + "No se puede cambiar al modo juego" + ) MSG_HASH( - MSG_NETPLAY_PEER_PAUSED, - "Cliente de juego en red \"%s\" pausado" - ) + MSG_NETPLAY_PEER_PAUSED, + "Cliente de juego en red \"%s\" pausado" + ) MSG_HASH( - MSG_NETPLAY_CHANGED_NICK, - "Tu apodo cambió a \"%s\"" - ) + MSG_NETPLAY_CHANGED_NICK, + "Tu apodo cambió a \"%s\"" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, - "Dar a los núcleos renderizados por hardware un contexto privado. Evita tener que asumir cambios en el estado del hardware entre cuadros" - ) + MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, + "Dar a los núcleos renderizados por hardware un contexto privado. Evita tener que asumir cambios en el estado del hardware entre cuadros" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SETTINGS, - "Ajusta la apariencia del menú" - ) + MENU_ENUM_SUBLABEL_MENU_SETTINGS, + "Ajusta la apariencia del menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, - "Fuerza la Sincronía de CPU y GPU. Reduce la latencia a costa del rendimiento" - ) + MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, + "Fuerza la Sincronía de CPU y GPU. Reduce la latencia a costa del rendimiento" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_THREADED, - "Mejora el rendimiento a costa de la latencia y posiblemente algunos tirones. Usar solo si no puede obtener máxima velocidad de otra manera" - ) + MENU_ENUM_SUBLABEL_VIDEO_THREADED, + "Mejora el rendimiento a costa de la latencia y posiblemente algunos tirones. Usar solo si no puede obtener máxima velocidad de otra manera" + ) MSG_HASH( - MSG_AUDIO_VOLUME, - "Volumen de Audio" - ) + MSG_AUDIO_VOLUME, + "Volumen de Audio" + ) MSG_HASH( - MSG_AUTODETECT, - "Auto-detectar" - ) + MSG_AUTODETECT, + "Auto-detectar" + ) MSG_HASH( - MSG_AUTOLOADING_SAVESTATE_FROM, - "Auto-cargar guardado rápido desde" - ) + MSG_AUTOLOADING_SAVESTATE_FROM, + "Auto-cargar guardado rápido desde" + ) MSG_HASH( - MSG_CAPABILITIES, - "Capacidades" - ) + MSG_CAPABILITIES, + "Capacidades" + ) MSG_HASH( - MSG_CONNECTING_TO_NETPLAY_HOST, - "Conectando al servidor de juego en red" - ) + MSG_CONNECTING_TO_NETPLAY_HOST, + "Conectando al servidor de juego en red" + ) MSG_HASH( - MSG_CONNECTING_TO_PORT, - "Conectando al puerto" - ) + MSG_CONNECTING_TO_PORT, + "Conectando al puerto" + ) MSG_HASH( - MSG_CONNECTION_SLOT, - "Lugar de conexión" - ) + MSG_CONNECTION_SLOT, + "Lugar de conexión" + ) MSG_HASH( - MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY, - "Lo sentimos, no implementado: los núcleos que no requieren contenido no pueden participar en juego en red" - ) + MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY, + "Lo sentimos, no implementado: los núcleos que no requieren contenido no pueden participar en juego en red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, - "Contraseña" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, + "Contraseña" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, - "Cuenta de logros" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, + "Cuenta de logros" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, - "Nombre de usuario" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, + "Nombre de usuario" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, - "Cuentas" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, + "Cuentas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST_END, - "Fin de la lista" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST_END, + "Fin de la lista" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, - "RetroAchievements" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, + "RetroAchievements" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, - "Lista de logros" - ) + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, + "Lista de logros" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_PAUSE, - "Pausar Modo Hardcore de logros" - ) + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_PAUSE, + "Pausar Modo Hardcore de logros" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_RESUME, - "Continuar usando el modo Hardcore de logros" - ) + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_RESUME, + "Continuar usando el modo Hardcore de logros" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, - "Lista de logros (Hardcore)" - ) + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, + "Lista de logros (Hardcore)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, - "Escanear Contenido" - ) + MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, + "Escanear Contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIGURATIONS_LIST, - "Configuraciones" - ) + MENU_ENUM_LABEL_VALUE_CONFIGURATIONS_LIST, + "Configuraciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_TAB, - "Importar contenido" - ) + MENU_ENUM_LABEL_VALUE_ADD_TAB, + "Importar contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, - "Salas de juego en red" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, + "Salas de juego en red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, - "Preguntar" - ) + MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, + "Preguntar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, - "Recursos" - ) + MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, + "Recursos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, - "Bloquear frames" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, + "Bloquear frames" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, - "Dispositivo de audio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, + "Dispositivo de audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_DRIVER, - "Controlador de Audio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_DRIVER, + "Controlador de Audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_DSP_PLUGIN, - "Audio DSP plugin" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_DSP_PLUGIN, + "Audio DSP plugin" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE, - "Activar audio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE, + "Activar audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, - "Filtro de audio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, + "Filtro de audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, - "Turbo/Zona Muerta" - ) + MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, + "Turbo/Zona Muerta" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_LATENCY, - "Latencia de audio (ms)" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_LATENCY, + "Latencia de audio (ms)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MAX_TIMING_SKEW, - "Variación máxima de sincronía de audio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_MAX_TIMING_SKEW, + "Variación máxima de sincronía de audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MUTE, - "Silenciar audio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_MUTE, + "Silenciar audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_OUTPUT_RATE, - "Frecuencia de muestreo de audio (Hz)" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_OUTPUT_RATE, + "Frecuencia de muestreo de audio (Hz)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_RATE_CONTROL_DELTA, - "Control de frecuencia dinámico" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_RATE_CONTROL_DELTA, + "Control de frecuencia dinámico" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_DRIVER, - "Controlador de muestreo de audio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_DRIVER, + "Controlador de muestreo de audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, - "Audio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, + "Audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, - "Sincronía de audio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, + "Sincronía de audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_VOLUME, - "Volumen de Audio (dB)" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_VOLUME, + "Volumen de Audio (dB)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_EXCLUSIVE_MODE, - "WASAPI Mode Exclusivo" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_EXCLUSIVE_MODE, + "WASAPI Mode Exclusivo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_FLOAT_FORMAT, - "WASAPI Formato de coma flotante" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_FLOAT_FORMAT, + "WASAPI Formato de coma flotante" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_SH_BUFFER_LENGTH, - "WASAPI Tamaño del búfer compartido" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_SH_BUFFER_LENGTH, + "WASAPI Tamaño del búfer compartido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, - "Intervalo de auto-guardado SaveRAM" - ) + MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, + "Intervalo de auto-guardado SaveRAM" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, - "Cargar autom. archivos de personalización" - ) + MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, + "Cargar autom. archivos de personalización" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE, - "Cargar autom. archivos de re-mapeo" - ) + MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE, + "Cargar autom. archivos de re-mapeo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, - "Cargar Shaders automáticamente" - ) + MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, + "Cargar Shaders automáticamente" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, - "Atrás" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, + "Atrás" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, - "Confirmar" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, + "Confirmar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, - "Información" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, + "Información" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, - "Salir" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, + "Salir" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_DOWN, - "Desplazar hacia abajo" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_DOWN, + "Desplazar hacia abajo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_UP, - "Desplazar hacia arriba" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_UP, + "Desplazar hacia arriba" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, - "Iniciar" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, + "Iniciar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, - "Mostrar teclado" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, + "Mostrar teclado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_MENU, - "Mostrar menú" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_MENU, + "Mostrar menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS, - "Controles básicos del menú" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS, + "Controles básicos del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_CONFIRM, - "Confirmar" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_CONFIRM, + "Confirmar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_INFO, - "Información" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_INFO, + "Información" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_QUIT, - "Salir" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_QUIT, + "Salir" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_SCROLL_UP, - "Desplazar hacia arriba" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_SCROLL_UP, + "Desplazar hacia arriba" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_START, - "Valores predeterminados" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_START, + "Valores predeterminados" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_KEYBOARD, - "Mostrar teclado" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_KEYBOARD, + "Mostrar teclado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_MENU, - "Mostrar menú" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_MENU, + "Mostrar menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BLOCK_SRAM_OVERWRITE, - "No sobrescribir SaveRAM al cargar un guardado rápido" - ) + MENU_ENUM_LABEL_VALUE_BLOCK_SRAM_OVERWRITE, + "No sobrescribir SaveRAM al cargar un guardado rápido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BLUETOOTH_ENABLE, - "Activar Bluetooth" - ) + MENU_ENUM_LABEL_VALUE_BLUETOOTH_ENABLE, + "Activar Bluetooth" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, - "URL de recursos del Buildbot" - ) + MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, + "URL de recursos del Buildbot" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY, - "Caché" - ) + MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY, + "Caché" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CAMERA_ALLOW, - "Permitir cámara" - ) + MENU_ENUM_LABEL_VALUE_CAMERA_ALLOW, + "Permitir cámara" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, - "Controlador de cámara" - ) + MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, + "Controlador de cámara" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT, - "Truco" - ) + MENU_ENUM_LABEL_VALUE_CHEAT, + "Truco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, - "Aplicar trucos" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, + "Aplicar trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_START_SEARCH, - "Iniciar búsqueda de trucos" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_START_SEARCH, + "Iniciar búsqueda de trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_CONTINUE_SEARCH, - "Continuar búsqueda" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_CONTINUE_SEARCH, + "Continuar búsqueda" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, - "Archivo de trucos" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, + "Archivo de trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE, - "Archivo de trucos" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_FILE, + "Archivo de trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD, - "Cargar archivo de trucos (Reemplazar)" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD, + "Cargar archivo de trucos (Reemplazar)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD_APPEND, - "Cargar archivo de trucos (Agregar)" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD_APPEND, + "Cargar archivo de trucos (Agregar)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, - "Guardar archivo de trucos como" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, + "Guardar archivo de trucos como" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, - "Pasadas de trucos" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, + "Pasadas de trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION, - "Descripción" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION, + "Descripción" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, - "Logros en modo Hardcore" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, + "Logros en modo Hardcore" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_ENABLE, - "Tablas de clasificación" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_ENABLE, + "Tablas de clasificación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_BADGES_ENABLE, - "Insignias de logros" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_BADGES_ENABLE, + "Insignias de logros" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, - "Logros bloqueados:" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, + "Logros bloqueados:" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY, - "Bloqueado" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY, + "Bloqueado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS, - "RetroAchievements" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS, + "RetroAchievements" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL, - "Probar logros No oficiales" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL, + "Probar logros No oficiales" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS, - "Logros desbloqueados:" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS, + "Logros desbloqueados:" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY, - "Desbloqueado" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY, + "Desbloqueado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY_HARDCORE, - "Hardcore" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY_HARDCORE, + "Hardcore" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_VERBOSE_ENABLE, - "Logros modo informativo" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_VERBOSE_ENABLE, + "Logros modo informativo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_AUTO_SCREENSHOT, - "Captura de pantalla automatica" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_AUTO_SCREENSHOT, + "Captura de pantalla automatica" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, - "Cerrar" - ) + MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, + "Cerrar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIG, - "Config" - ) + MENU_ENUM_LABEL_VALUE_CONFIG, + "Config" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIGURATIONS, - "Cargar configuración" - ) + MENU_ENUM_LABEL_VALUE_CONFIGURATIONS, + "Cargar configuración" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS, - "Configuración" - ) + MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS, + "Configuración" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, - "Guardar configuración al salir" - ) + MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, + "Guardar configuración al salir" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Colecciones" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, + "Colecciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, - "Base de datos" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, + "Base de datos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_DIR, - "Contenido" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_DIR, + "Contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, - "Tamaño del historial" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, + "Tamaño del historial" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_REMOVE, - "Permitir quitar entradas" - ) + MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_REMOVE, + "Permitir quitar entradas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS, - "Menú rápido" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS, + "Menú rápido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIR, - "Descargas" - ) + MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIR, + "Descargas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIRECTORY, - "Descargas" - ) + MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIRECTORY, + "Descargas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS, - "Trucos" - ) + MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS, + "Trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_COUNTERS, - "Contadores de núcleo" - ) + MENU_ENUM_LABEL_VALUE_CORE_COUNTERS, + "Contadores de núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_ENABLE, - "Mostrar nombre del núcleo" - ) + MENU_ENUM_LABEL_VALUE_CORE_ENABLE, + "Mostrar nombre del núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_INFORMATION, - "Información del núcleo" - ) + MENU_ENUM_LABEL_VALUE_CORE_INFORMATION, + "Información del núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_INFO_AUTHORS, - "Autores" - ) + MENU_ENUM_LABEL_VALUE_CORE_INFO_AUTHORS, + "Autores" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_INFO_CATEGORIES, - "Categorías" - ) + MENU_ENUM_LABEL_VALUE_CORE_INFO_CATEGORIES, + "Categorías" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_LABEL, - "Etiqueta del núcleo" - ) + MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_LABEL, + "Etiqueta del núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_NAME, - "Nombre del núcleo" - ) + MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_NAME, + "Nombre del núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE, - "Firmware(s)" - ) + MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE, + "Firmware(s)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES, - "Licencia(s)" - ) + MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES, + "Licencia(s)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_INFO_PERMISSIONS, - "Permisos" - ) + MENU_ENUM_LABEL_VALUE_CORE_INFO_PERMISSIONS, + "Permisos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_INFO_SUPPORTED_EXTENSIONS, - "Extensiones compatibles" - ) + MENU_ENUM_LABEL_VALUE_CORE_INFO_SUPPORTED_EXTENSIONS, + "Extensiones compatibles" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_MANUFACTURER, - "Fabricante del sistema" - ) + MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_MANUFACTURER, + "Fabricante del sistema" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_NAME, - "Nombre del sistema" - ) + MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_NAME, + "Nombre del sistema" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS, - "Controles" - ) + MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS, + "Controles" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_LIST, - "Cargar núcleo" - ) + MENU_ENUM_LABEL_VALUE_CORE_LIST, + "Cargar núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, - "Opciones" - ) + MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, + "Opciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_SETTINGS, - "Núcleo" - ) + MENU_ENUM_LABEL_VALUE_CORE_SETTINGS, + "Núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, - "Iniciar un núcleo automáticamente" - ) + MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, + "Iniciar un núcleo automáticamente" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, - "Extraer automáticamente el archivo descargado" - ) + MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, + "Extraer automáticamente el archivo descargado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_UPDATER_BUILDBOT_URL, - "URL de núcleos de Buildbot" - ) + MENU_ENUM_LABEL_VALUE_CORE_UPDATER_BUILDBOT_URL, + "URL de núcleos de Buildbot" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST, - "Actualizador de núcleos" - ) + MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST, + "Actualizador de núcleos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SETTINGS, - "Actualizador" - ) + MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SETTINGS, + "Actualizador" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CPU_ARCHITECTURE, - "Arquitectura de CPU:" - ) + MENU_ENUM_LABEL_VALUE_CPU_ARCHITECTURE, + "Arquitectura de CPU:" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CPU_CORES, - "Núcleos de CPU:" - ) + MENU_ENUM_LABEL_VALUE_CPU_CORES, + "Núcleos de CPU:" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CURSOR_DIRECTORY, - "Cursor" - ) + MENU_ENUM_LABEL_VALUE_CURSOR_DIRECTORY, + "Cursor" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CURSOR_MANAGER, - "Gestor de cursores" - ) + MENU_ENUM_LABEL_VALUE_CURSOR_MANAGER, + "Gestor de cursores" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CUSTOM_RATIO, - "Relación personalizada" - ) + MENU_ENUM_LABEL_VALUE_CUSTOM_RATIO, + "Relación personalizada" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_MANAGER, - "Gestor de bases de datos" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_MANAGER, + "Gestor de bases de datos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_SELECTION, - "Seleccionar bases de datos" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_SELECTION, + "Seleccionar bases de datos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DELETE_ENTRY, - "Quitar" - ) + MENU_ENUM_LABEL_VALUE_DELETE_ENTRY, + "Quitar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_FAVORITES, - "Favoritos" - ) + MENU_ENUM_LABEL_VALUE_FAVORITES, + "Favoritos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DIRECTORY_CONTENT, - "" - ) + MENU_ENUM_LABEL_VALUE_DIRECTORY_CONTENT, + "" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DIRECTORY_DEFAULT, - "" - ) + MENU_ENUM_LABEL_VALUE_DIRECTORY_DEFAULT, + "" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DIRECTORY_NONE, - "" - ) + MENU_ENUM_LABEL_VALUE_DIRECTORY_NONE, + "" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, - "No se ha encontrado la carpeta" - ) + MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, + "No se ha encontrado la carpeta" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS, - "Carpetas" - ) + MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS, + "Carpetas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DISK_CYCLE_TRAY_STATUS, - "Estado de la bandeja de discos" - ) + MENU_ENUM_LABEL_VALUE_DISK_CYCLE_TRAY_STATUS, + "Estado de la bandeja de discos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND, - "Asignar imagen de disco" - ) + MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND, + "Asignar imagen de disco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DISK_INDEX, - "Índice de disco" - ) + MENU_ENUM_LABEL_VALUE_DISK_INDEX, + "Índice de disco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DISK_OPTIONS, - "Control de disco" - ) + MENU_ENUM_LABEL_VALUE_DISK_OPTIONS, + "Control de disco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DONT_CARE, - "No importa" - ) + MENU_ENUM_LABEL_VALUE_DONT_CARE, + "No importa" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST, - "Descargas" - ) + MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST, + "Descargas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE, - "Descargar núcleo" - ) + MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE, + "Descargar núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT, - "Descargador de contenido" - ) + MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT, + "Descargador de contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_ENABLE, - "Forzar DPI" - ) + MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_ENABLE, + "Forzar DPI" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE, - "Anular DPI" - ) + MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE, + "Anular DPI" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS, - "Controladores" - ) + MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS, + "Controladores" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN, - "Cargar vacío al cerrar núcleo" - ) + MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN, + "Cargar vacío al cerrar núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHECK_FOR_MISSING_FIRMWARE, - "Chequear si falta Firmware antes de cargar" - ) + MENU_ENUM_LABEL_VALUE_CHECK_FOR_MISSING_FIRMWARE, + "Chequear si falta Firmware antes de cargar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER, - "Fondo de pantalla dinámico" - ) + MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER, + "Fondo de pantalla dinámico" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY, - "Fondos de pantalla dinámicos" - ) + MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY, + "Fondos de pantalla dinámicos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE, - "Activar logros" - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE, + "Activar logros" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR, - "Color de resaltado del menú" - ) + MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR, + "Color de resaltado del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ENTRY_NORMAL_COLOR, - "Color normal del menú" - ) + MENU_ENUM_LABEL_VALUE_ENTRY_NORMAL_COLOR, + "Color normal del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_FALSE, - "Desactivado" - ) + MENU_ENUM_LABEL_VALUE_FALSE, + "Desactivado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_FASTFORWARD_RATIO, - "Velocidad máxima de ejecución" - ) + MENU_ENUM_LABEL_VALUE_FASTFORWARD_RATIO, + "Velocidad máxima de ejecución" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_FAVORITES_TAB, - "Favoritos" - ) + MENU_ENUM_LABEL_VALUE_FAVORITES_TAB, + "Favoritos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_FPS_SHOW, - "Mostrar FPS" - ) + MENU_ENUM_LABEL_VALUE_FPS_SHOW, + "Mostrar FPS" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE, - "Limitar velocidad máxima de ejecución" - ) + MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE, + "Limitar velocidad máxima de ejecución" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, - "Velocidad de frames" - ) + MENU_ENUM_LABEL_VALUE_VRR_RUNLOOP_ENABLE, + "Sincronizar pantalla al contenido (G-Sync, FreeSync)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, - "Contadores de la interfaz" - ) + MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, + "Velocidad de frames" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, - "Usar opciones de núcleo para cada juego si existen" - ) + MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, + "Contadores de la interfaz" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE, - "Crear archivo de opciones del juego" - ) + MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, + "Usar opciones de núcleo para cada juego si existen" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE, - "Archivo de opciones del juego" - ) + MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE, + "Crear archivo de opciones del juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_HELP, - "Ayuda" - ) + MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE, + "Archivo de opciones del juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING, - "Solucionar problemas de Audio/Video" - ) + MENU_ENUM_LABEL_VALUE_HELP, + "Ayuda" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD, - "Cambiar el mando virtual superpuesto" - ) + MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING, + "Solucionar problemas de Audio/Video" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_HELP_CONTROLS, - "Controles básicos del menú" - ) + MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD, + "Cambiar el mando virtual superpuesto" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_HELP_LIST, - "Ayuda" - ) + MENU_ENUM_LABEL_VALUE_HELP_CONTROLS, + "Controles básicos del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_HELP_LOADING_CONTENT, - "Cargando contenido" - ) + MENU_ENUM_LABEL_VALUE_HELP_LIST, + "Ayuda" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT, - "Buscando contenido" - ) + MENU_ENUM_LABEL_VALUE_HELP_LOADING_CONTENT, + "Cargando contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_HELP_WHAT_IS_A_CORE, - "¿Qué es un núcleo?" - ) + MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT, + "Buscando contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_HISTORY_LIST_ENABLE, - "Activar Historial" - ) + MENU_ENUM_LABEL_VALUE_HELP_WHAT_IS_A_CORE, + "¿Qué es un núcleo?" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_HISTORY_TAB, - "Historial" - ) + MENU_ENUM_LABEL_VALUE_HISTORY_LIST_ENABLE, + "Activar Historial" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, - "Menú Horizontal" - ) + MENU_ENUM_LABEL_VALUE_HISTORY_TAB, + "Historial" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_IMAGES_TAB, - "Imágenes" - ) + MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, + "Menú Horizontal" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INFORMATION, - "Información" - ) + MENU_ENUM_LABEL_VALUE_IMAGES_TAB, + "Imágenes" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INFORMATION_LIST, - "Información" - ) + MENU_ENUM_LABEL_VALUE_INFORMATION, + "Información" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ADC_TYPE, - "Tipo de analógico a digital" - ) + MENU_ENUM_LABEL_VALUE_INFORMATION_LIST, + "Información" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ALL_USERS_CONTROL_MENU, - "Todos controlan el menú" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ADC_TYPE, + "Tipo de analógico a digital" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X, - "Analógico izq. X" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ALL_USERS_CONTROL_MENU, + "Todos controlan el menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_MINUS, - "Analógico izq. X- (IZQUIERDA)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X, + "Analógico izq. X" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_PLUS, - "Analógico izq. X+ (DERECHA)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_MINUS, + "Analógico izq. X- (IZQUIERDA)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y, - "Analógico izq. Y" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_PLUS, + "Analógico izq. X+ (DERECHA)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_MINUS, - "Analógico izq. Y- (ARRIBA)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y, + "Analógico izq. Y" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_PLUS, - "Analógico izq. Y+ (ABAJO)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_MINUS, + "Analógico izq. Y- (ARRIBA)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X, - "Analógico der. X" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_PLUS, + "Analógico izq. Y+ (ABAJO)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_MINUS, - "Analógico der. X- (IZQUIERDA)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X, + "Analógico der. X" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_PLUS, - "Analógico der. X+ (DERECHA)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_MINUS, + "Analógico der. X- (IZQUIERDA)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y, - "Analógico der. Y" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_PLUS, + "Analógico der. X+ (DERECHA)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS, - "Analógico der. Y- (ARRIBA)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y, + "Analógico der. Y" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS, - "Analógico der. Y+ (ABAJO)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS, + "Analógico der. Y- (ARRIBA)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_TRIGGER, - "Arma: Gatillo" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS, + "Analógico der. Y+ (ABAJO)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_RELOAD, - "Arma: Recargar" - ) + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_TRIGGER, + "Arma: Gatillo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_A, - "Arma: Aux A" - ) + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_RELOAD, + "Arma: Recargar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_B, - "Arma: Aux B" - ) + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_A, + "Arma: Aux A" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_C, - "Arma: Aux C" - ) + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_B, + "Arma: Aux B" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_START, - "Arma: Start" - ) + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_C, + "Arma: Aux C" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_SELECT, - "Arma: Select" - ) + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_START, + "Arma: Start" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_UP, - "Arma: D-pad ARRIBA" - ) + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_SELECT, + "Arma: Select" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_DOWN, - "Arma: D-pad ABAJO" - ) + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_UP, + "Arma: D-pad ARRIBA" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT, - "Arma: D-pad IZQUIERDA" - ) + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_DOWN, + "Arma: D-pad ABAJO" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, - "Arma: D-pad DERECHA" - ) + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT, + "Arma: D-pad IZQUIERDA" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, - "Activar Auto-configuración" - ) + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, + "Arma: D-pad DERECHA" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Zona muerta analógica" - ) + MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, + "Activar Auto-configuración" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, - "Menú: cambiar OK y Cancelar" - ) + MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, + "Zona muerta analógica" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, - "Asignar todo" - ) + MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, + "Menú: cambiar OK y Cancelar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL, - "Asignar valores por defecto" - ) + MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, + "Asignar todo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_BIND_TIMEOUT, - "Tiempo limite para asignar" - ) + MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL, + "Asignar valores por defecto" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_BIND_HOLD, - "Asignar (mantener)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_BIND_TIMEOUT, + "Tiempo limite para asignar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_HIDE_UNBOUND, - "Ocultar descripciones de entrada sin asignar de los núcleo" - ) + MENU_ENUM_LABEL_VALUE_INPUT_BIND_HOLD, + "Asignar (mantener)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_LABEL_SHOW, - "Mostrar etiquetas de descripción de entrada" - ) + MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_HIDE_UNBOUND, + "Ocultar descripciones de entrada sin asignar de los núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX, - "Indice de dispositivo" - ) + MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_LABEL_SHOW, + "Mostrar etiquetas de descripción de entrada" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_TYPE, - "Tipo de dispositivo" - ) + MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX, + "Indice de dispositivo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_INDEX, - "Indice de ratón" - ) + MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_TYPE, + "Tipo de dispositivo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_DRIVER, - "Controlador de entrada" - ) + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_INDEX, + "Indice de ratón" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_DUTY_CYCLE, - "Ciclo de trabajo" - ) + MENU_ENUM_LABEL_VALUE_INPUT_DRIVER, + "Controlador de entrada" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS, - "Asignar Hotkeys" - ) + MENU_ENUM_LABEL_VALUE_INPUT_DUTY_CYCLE, + "Ciclo de trabajo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE, - "Activar mapeo de Teclado-Mando" - ) + MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS, + "Asignar Hotkeys" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_A, - "Botón A (DERECHA)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE, + "Activar mapeo de Teclado-Mando" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, - "Botón B (ABAJO)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_A, + "Botón A (DERECHA)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_DOWN, - "D-pad ABAJO" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, + "Botón B (ABAJO)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L2, - "Botón L2 (LT)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_DOWN, + "D-pad ABAJO" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L3, - "Botón L3 (Pulsar analógico IZQ.)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L2, + "Botón L2 (LT)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L, - "Botón L1 (LB)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L3, + "Botón L3 (Pulsar analógico IZQ.)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT, - "D-pad IZQUIERDA" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L, + "Botón L1 (LB)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R2, - "Botón R2 (RT)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT, + "D-pad IZQUIERDA" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R3, - "Botón R3 (Pulsar analógico DER.)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R2, + "Botón R2 (RT)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R, - "Botón R1 (RB)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R3, + "Botón R3 (Pulsar analógico DER.)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_RIGHT, - "D-pad DERECHA" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R, + "Botón R1 (RB)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, - "Botón Select" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_RIGHT, + "D-pad DERECHA" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, - "Botón Start" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, + "Botón Select" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_UP, - "D-pad ARRIBA" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, + "Botón Start" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X, - "Botón X (ARRIBA)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_UP, + "D-pad ARRIBA" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, - "Botón Y (IZQUIERDA)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X, + "Botón X (ARRIBA)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_KEY, - "(Tecla: %s)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, + "Botón Y (IZQUIERDA)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_LEFT, - "Ratón 1" - ) + MENU_ENUM_LABEL_VALUE_INPUT_KEY, + "(Tecla: %s)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_RIGHT, - "Ratón 2" - ) + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_LEFT, + "Ratón 1" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_MIDDLE, - "Ratón 3" - ) + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_RIGHT, + "Ratón 2" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON4, - "Ratón 4" - ) + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_MIDDLE, + "Ratón 3" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON5, - "Ratón 5" - ) + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON4, + "Ratón 4" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_UP, - "Rueda ARRIBA" - ) + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON5, + "Ratón 5" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_DOWN, - "Rueda ABAJO" - ) + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_UP, + "Rueda ARRIBA" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_UP, - "Rueda IZQUIERDA" - ) + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_DOWN, + "Rueda ABAJO" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_DOWN, - "Rueda DERECHA" - ) + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_UP, + "Rueda IZQUIERDA" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, - "Tipo de mapeo Teclado-Mando" - ) + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_DOWN, + "Rueda DERECHA" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_MAX_USERS, - "Máximo de usuarios" - ) + MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, + "Tipo de mapeo Teclado-Mando" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, - "Combinación para mostrar el menú" - ) + MENU_ENUM_LABEL_VALUE_INPUT_MAX_USERS, + "Máximo de usuarios" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS, - "Indice de trucos -" - ) + MENU_ENUM_LABEL_VALUE_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, + "Combinación para mostrar el menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS, - "Indice de trucos +" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS, + "Indice de trucos -" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE, - "Activar truco" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS, + "Indice de trucos +" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE, - "Expulsar disco" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE, + "Activar truco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT, - "Siguiente disco" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE, + "Expulsar disco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, - "Disco previo" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT, + "Siguiente disco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, - "Activar hotkeys" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, + "Disco previo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY, - "Mantener para avance rápido" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, + "Activar hotkeys" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY, - "Avance rápido" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY, + "Mantener para avance rápido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, - "Avanzar frame" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY, + "Avance rápido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, - "Pantalla completa" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, + "Avanzar frame" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, - "Capturar ratón" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, + "Pantalla completa" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, - "Game focus (desactivar hotkeys)" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, + "Capturar ratón" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE, - "Activar menú de escritorio" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, + "Game focus (desactivar hotkeys)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, - "Cargar estado" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE, + "Activar menú de escritorio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, - "Mostrar menú" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, + "Cargar estado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE, - "Grabar video" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, + "Mostrar menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, - "Silenciar audio" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE, + "Grabar video" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, - "Juego en red: cambiar modo juego/espectador" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, + "Silenciar audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, - "Mostrar teclado en pantalla" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, + "Juego en red: cambiar modo juego/espectador" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, - "Siguiente superposición" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, + "Mostrar teclado en pantalla" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE, - "Pausar" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, + "Siguiente superposición" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, - "Cerrar RetroArch" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE, + "Pausar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, - "Resetear juego" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, + "Cerrar RetroArch" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, - "Rebobinar" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, + "Resetear juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, - "Guardar estado" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, + "Rebobinar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, - "Captura de pantalla" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_DETAILS, + "Detalles de truco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, - "Siguiente shader" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_SEARCH, + "Iniciar o continuar búsqueda de trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, - "Shader previo" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, + "Guardar estado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_HOLD_KEY, - "Tecla a mantener para cámara lenta" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, + "Captura de pantalla" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_KEY, - "Activar Cámara lenta" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, + "Siguiente shader" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, - "Posición de guardado -" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, + "Shader previo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, - "Posición de guardado +" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_HOLD_KEY, + "Tecla a mantener para cámara lenta" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, - "Volumen -" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_KEY, + "Activar Cámara lenta" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, - "Volumen +" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, + "Posición de guardado -" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_ENABLE, - "Mostrar superposición" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, + "Posición de guardado +" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU, - "Ocultar superposición en el menú" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, + "Volumen -" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, - "Mostrar entradas en la superposición" - ) + MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, + "Volumen +" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, - "Puerto de escucha para entradas" - ) + MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_ENABLE, + "Mostrar superposición" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR, - "Comportamiento del sondeo" - ) + MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU, + "Ocultar superposición en el menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_EARLY, - "Temprano" - ) + MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, + "Mostrar entradas en la superposición" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_LATE, - "Tarde" - ) + MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, + "Puerto de escucha para entradas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_NORMAL, - "Normal" - ) + MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR, + "Comportamiento del sondeo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_PREFER_FRONT_TOUCH, - "Preferir táctil frontal" - ) + MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_EARLY, + "Temprano" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_REMAPPING_DIRECTORY, - "Reasignación de entrada" - ) + MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_LATE, + "Tarde" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_REMAP_BINDS_ENABLE, - "Permitir reasignar controles" - ) + MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_NORMAL, + "Normal" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_SAVE_AUTOCONFIG, - "Guardar Auto-configuración" - ) + MENU_ENUM_LABEL_VALUE_INPUT_PREFER_FRONT_TOUCH, + "Preferir táctil frontal" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS, - "Controles" - ) + MENU_ENUM_LABEL_VALUE_INPUT_REMAPPING_DIRECTORY, + "Reasignación de entrada" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE, - "Activar teclado pequeño" - ) + MENU_ENUM_LABEL_VALUE_INPUT_REMAP_BINDS_ENABLE, + "Permitir reasignar controles" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_TOUCH_ENABLE, - "Activar táctil" - ) + MENU_ENUM_LABEL_VALUE_INPUT_SAVE_AUTOCONFIG, + "Guardar Auto-configuración" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE, - "Activar turbo" - ) + MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS, + "Controles" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, - "Periodo del turbo" - ) + MENU_ENUM_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE, + "Activar teclado pequeño" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_USER_BINDS, - "Controles del usuario %u" - ) + MENU_ENUM_LABEL_VALUE_INPUT_TOUCH_ENABLE, + "Activar táctil" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LATENCY_SETTINGS, - "Latencia" - ) + MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE, + "Activar turbo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INTERNAL_STORAGE_STATUS, - "Estado del almacenamiento interno" - ) + MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, + "Periodo del turbo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_JOYPAD_AUTOCONFIG_DIR, - "Auto-configuración de controles" - ) + MENU_ENUM_LABEL_VALUE_INPUT_USER_BINDS, + "Controles del usuario %u" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_JOYPAD_DRIVER, - "Controlador de mando" - ) + MENU_ENUM_LABEL_VALUE_LATENCY_SETTINGS, + "Latencia" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LAKKA_SERVICES, - "Servicios" - ) + MENU_ENUM_LABEL_VALUE_INTERNAL_STORAGE_STATUS, + "Estado del almacenamiento interno" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_CHINESE_SIMPLIFIED, - "Chino (Simplificado)" - ) + MENU_ENUM_LABEL_VALUE_JOYPAD_AUTOCONFIG_DIR, + "Auto-configuración de controles" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_CHINESE_TRADITIONAL, - "Chino (Tradicional)" - ) + MENU_ENUM_LABEL_VALUE_JOYPAD_DRIVER, + "Controlador de mando" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_DUTCH, - "Holandés" - ) + MENU_ENUM_LABEL_VALUE_LAKKA_SERVICES, + "Servicios" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_ENGLISH, - "Ingles" - ) + MENU_ENUM_LABEL_VALUE_LANG_CHINESE_SIMPLIFIED, + "Chino (Simplificado)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_ESPERANTO, - "Esperanto" - ) + MENU_ENUM_LABEL_VALUE_LANG_CHINESE_TRADITIONAL, + "Chino (Tradicional)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_FRENCH, - "Francés" - ) + MENU_ENUM_LABEL_VALUE_LANG_DUTCH, + "Holandés" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_GERMAN, - "Alemán" - ) + MENU_ENUM_LABEL_VALUE_LANG_ENGLISH, + "Ingles" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_ITALIAN, - "Italiano" - ) + MENU_ENUM_LABEL_VALUE_LANG_ESPERANTO, + "Esperanto" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_JAPANESE, - "Japones" - ) + MENU_ENUM_LABEL_VALUE_LANG_FRENCH, + "Francés" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_KOREAN, - "Coreano" - ) + MENU_ENUM_LABEL_VALUE_LANG_GERMAN, + "Alemán" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_POLISH, - "Polaco" - ) + MENU_ENUM_LABEL_VALUE_LANG_ITALIAN, + "Italiano" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_BRAZIL, - "Portugués (Brasil)" - ) + MENU_ENUM_LABEL_VALUE_LANG_JAPANESE, + "Japones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_PORTUGAL, - "Portugués (Portugal)" - ) + MENU_ENUM_LABEL_VALUE_LANG_KOREAN, + "Coreano" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_RUSSIAN, - "Ruso" - ) + MENU_ENUM_LABEL_VALUE_LANG_POLISH, + "Polaco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_SPANISH, - "Español" - ) + MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_BRAZIL, + "Portugués (Brasil)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_VIETNAMESE, - "Vietnamita" - ) + MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_PORTUGAL, + "Portugués (Portugal)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_ARABIC, - "Árabe" - ) + MENU_ENUM_LABEL_VALUE_LANG_RUSSIAN, + "Ruso" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LEFT_ANALOG, - "Analógico izquierdo" - ) + MENU_ENUM_LABEL_VALUE_LANG_SPANISH, + "Español" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH, - "Núcleos" - ) + MENU_ENUM_LABEL_VALUE_LANG_VIETNAMESE, + "Vietnamita" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LIBRETRO_INFO_PATH, - "Información de núcleos" - ) + MENU_ENUM_LABEL_VALUE_LANG_ARABIC, + "Árabe" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LIBRETRO_LOG_LEVEL, - "Nivel de registro de los núcleos" - ) + MENU_ENUM_LABEL_VALUE_LEFT_ANALOG, + "Analógico izquierdo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LINEAR, - "Lineal" - ) + MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH, + "Núcleos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LOAD_ARCHIVE, - "Cargar archivo" - ) + MENU_ENUM_LABEL_VALUE_LIBRETRO_INFO_PATH, + "Información de núcleos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY, - "Cargar archivos recientes" - ) + MENU_ENUM_LABEL_VALUE_LIBRETRO_LOG_LEVEL, + "Nivel de registro de los núcleos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST, - "Cargar Contenido" - ) + MENU_ENUM_LABEL_VALUE_LINEAR, + "Lineal" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LOAD_STATE, - "Cargar rápida" - ) + MENU_ENUM_LABEL_VALUE_LOAD_ARCHIVE, + "Cargar archivo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LOCATION_ALLOW, - "Permitir ubicación" - ) + MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY, + "Cargar archivos recientes" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LOCATION_DRIVER, - "Controlador de ubicación" - ) + MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST, + "Cargar Contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS, - "Registros" - ) + MENU_ENUM_LABEL_VALUE_LOAD_STATE, + "Cargar rápida" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LOG_VERBOSITY, - "Verbosidad del registro" - ) + MENU_ENUM_LABEL_VALUE_LOCATION_ALLOW, + "Permitir ubicación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MAIN_MENU, - "Menú principal" - ) + MENU_ENUM_LABEL_VALUE_LOCATION_DRIVER, + "Controlador de ubicación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MANAGEMENT, - "Ajustes de bases de datos" - ) + MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS, + "Registros" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME, - "Tema de color del menú" - ) + MENU_ENUM_LABEL_VALUE_LOG_VERBOSITY, + "Verbosidad del registro" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE, - "Azul" - ) + MENU_ENUM_LABEL_VALUE_MAIN_MENU, + "Menú principal" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE_GREY, - "Azul gris" - ) + MENU_ENUM_LABEL_VALUE_MANAGEMENT, + "Ajustes de bases de datos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_DARK_BLUE, - "Azul obscuro" - ) + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME, + "Tema de color del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_GREEN, - "Verde" - ) + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE, + "Azul" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_NVIDIA_SHIELD, - "Shield" - ) + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE_GREY, + "Azul gris" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_RED, - "Rojo" - ) + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_DARK_BLUE, + "Azul obscuro" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_YELLOW, - "Amarillo" - ) + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_GREEN, + "Verde" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_FOOTER_OPACITY, - "Opacidad del pie de página" - ) + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_NVIDIA_SHIELD, + "Shield" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_HEADER_OPACITY, - "Opacidad del encabezado" - ) + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_RED, + "Rojo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_DRIVER, - "Controlador del menú" - ) + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_YELLOW, + "Amarillo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE, - "Controlar FPS del menú" - ) + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_FOOTER_OPACITY, + "Opacidad del pie de página" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_FILE_BROWSER_SETTINGS, - "Configuraciones" - ) + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_HEADER_OPACITY, + "Opacidad del encabezado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, - "Filtro lineal del menú" - ) + MENU_ENUM_LABEL_VALUE_MENU_DRIVER, + "Controlador del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_HORIZONTAL_ANIMATION, - "Animación horizontal" - ) + MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE, + "Controlar FPS del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, - "Apariencia" - ) + MENU_ENUM_LABEL_VALUE_MENU_FILE_BROWSER_SETTINGS, + "Configuraciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER, - "Fondo" - ) + MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, + "Filtro lineal del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY, - "Opacidad del fondo" - ) + MENU_ENUM_LABEL_VALUE_MENU_HORIZONTAL_ANIMATION, + "Animación horizontal" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MISSING, - "Faltante" - ) + MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, + "Apariencia" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MORE, - "..." - ) + MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER, + "Fondo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MOUSE_ENABLE, - "Soporte para ratón" - ) + MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY, + "Opacidad del fondo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MULTIMEDIA_SETTINGS, - "Multimedia" - ) + MENU_ENUM_LABEL_VALUE_MISSING, + "Faltante" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MUSIC_TAB, - "Música" - ) + MENU_ENUM_LABEL_VALUE_MORE, + "..." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, - "Filtrar extensiones desconocidas" - ) + MENU_ENUM_LABEL_VALUE_MOUSE_ENABLE, + "Soporte para ratón" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NAVIGATION_WRAPAROUND, - "Volver al inicio al llegar al final" - ) + MENU_ENUM_LABEL_VALUE_MULTIMEDIA_SETTINGS, + "Multimedia" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NEAREST, - "Mas cercano" - ) + MENU_ENUM_LABEL_VALUE_MUSIC_TAB, + "Música" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY, - "Juego en red" - ) + MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, + "Filtrar extensiones desconocidas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_ALLOW_SLAVES, - "Permitir clientes en modo esclavo" - ) + MENU_ENUM_LABEL_VALUE_NAVIGATION_WRAPAROUND, + "Volver al inicio al llegar al final" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, - "Juego en red: chequear frames" - ) + MENU_ENUM_LABEL_VALUE_NEAREST, + "Mas cercano" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN, - "Latencia mínima en frames" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY, + "Juego en red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, - "Rango de latencia en frames" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_ALLOW_SLAVES, + "Permitir clientes en modo esclavo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES, - "Juego en red: retrasar frames" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, + "Juego en red: chequear frames" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT, - "Desconectar del servidor" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN, + "Latencia mínima en frames" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE, - "Activar juego en red" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, + "Rango de latencia en frames" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT, - "Conectar a un servidor de juego" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES, + "Juego en red: retrasar frames" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_HOST, - "Iniciar servidor de juego" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT, + "Desconectar del servidor" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_DISABLE_HOST, - "Terminar juego en red" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE, + "Activar juego en red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS, - "Dirección del servidor" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT, + "Conectar a un servidor de juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_LAN_SCAN_SETTINGS, - "Escanear red local" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_HOST, + "Iniciar servidor de juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, - "Activar cliente de juego en red" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_DISABLE_HOST, + "Terminar juego en red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, - "Apodo para juego en red" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS, + "Dirección del servidor" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, - "Contraseña del servidor" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_LAN_SCAN_SETTINGS, + "Escanear red local" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE, - "Anunciar juego en red públicamente" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, + "Activar cliente de juego en red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_REQUEST_DEVICE_I, - "Pedir dispositivo %u" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, + "Apodo para juego en red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_REQUIRE_SLAVES, - "Desactivar clientes sin modo esclavo" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, + "Contraseña del servidor" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, - "Configurar juego en red" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE, + "Anunciar juego en red públicamente" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG, - "Comparir entrada analoga" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_REQUEST_DEVICE_I, + "Pedir dispositivo %u" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_MAX, - "Max" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_REQUIRE_SLAVES, + "Desactivar clientes sin modo esclavo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_AVERAGE, - "Promedio" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, + "Configurar juego en red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL, - "Compartir entrada digital" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG, + "Comparir entrada analoga" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_OR, - "Compartir" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_MAX, + "Max" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_XOR, - "Grapple" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_AVERAGE, + "Promedio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_VOTE, - "Votar" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL, + "Compartir entrada digital" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NONE, - "Nada" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_OR, + "Compartir" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NO_PREFERENCE, - "Sin preferencia" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_XOR, + "Grapple" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_START_AS_SPECTATOR, - "Juego en red: modo espectador" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_VOTE, + "Votar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, - "Juego en red: modo sin estados" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NONE, + "Nada" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, - "Contraseña del servidor para espectadores" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NO_PREFERENCE, + "Sin preferencia" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, - "Juego en red: activar espectadores" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_START_AS_SPECTATOR, + "Juego en red: modo espectador" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, - "Juego en red: Puerto TCP" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, + "Juego en red: modo sin estados" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, - "Juego en red: NAT Traversal" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, + "Contraseña del servidor para espectadores" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETWORK_CMD_ENABLE, - "Comandos de red" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, + "Juego en red: activar espectadores" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT, - "Puerto de comandos de red" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, + "Juego en red: Puerto TCP" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETWORK_INFORMATION, - "Información de red" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, + "Juego en red: NAT Traversal" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_ENABLE, - "Mando en red" - ) + MENU_ENUM_LABEL_VALUE_NETWORK_CMD_ENABLE, + "Comandos de red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_PORT, - "Puerto de base remota de red" - ) + MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT, + "Puerto de comandos de red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETWORK_SETTINGS, - "Red" - ) + MENU_ENUM_LABEL_VALUE_NETWORK_INFORMATION, + "Información de red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO, - "No" - ) + MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_ENABLE, + "Mando en red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NONE, - "Ninguno" - ) + MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_PORT, + "Puerto de base remota de red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE, - "No disponible" - ) + MENU_ENUM_LABEL_VALUE_NETWORK_SETTINGS, + "Red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_ACHIEVEMENTS_TO_DISPLAY, - "Sin logros que mostrar" - ) + MENU_ENUM_LABEL_VALUE_NO, + "No" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_CORE, - "Sin núcleo" - ) + MENU_ENUM_LABEL_VALUE_NONE, + "Ninguno" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_CORES_AVAILABLE, - "No hay núcleos disponibles" - ) + MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE, + "No disponible" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_CORE_INFORMATION_AVAILABLE, - "No hay información del núcleo" - ) + MENU_ENUM_LABEL_VALUE_NO_ACHIEVEMENTS_TO_DISPLAY, + "Sin logros que mostrar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_CORE_OPTIONS_AVAILABLE, - "No hay opciones del núcleo" - ) + MENU_ENUM_LABEL_VALUE_NO_CORE, + "Sin núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY, - "No hay entradas disponibles" - ) + MENU_ENUM_LABEL_VALUE_NO_CORES_AVAILABLE, + "No hay núcleos disponibles" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_HISTORY_AVAILABLE, - "No hay historial disponible" - ) + MENU_ENUM_LABEL_VALUE_NO_CORE_INFORMATION_AVAILABLE, + "No hay información del núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE, - "No hay información disponible" - ) + MENU_ENUM_LABEL_VALUE_NO_CORE_OPTIONS_AVAILABLE, + "No hay opciones del núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_ITEMS, - "No hay elementos" - ) + MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY, + "No hay entradas disponibles" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_NETPLAY_HOSTS_FOUND, - "No se encontraron anfitriones" - ) + MENU_ENUM_LABEL_VALUE_NO_HISTORY_AVAILABLE, + "No hay historial disponible" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, - "No se encuentran redes" - ) + MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE, + "No hay información disponible" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, - "No hay contadores de rendimiento" - ) + MENU_ENUM_LABEL_VALUE_NO_ITEMS, + "No hay elementos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, - "No hay listas de reproducción" - ) + MENU_ENUM_LABEL_VALUE_NO_NETPLAY_HOSTS_FOUND, + "No se encontraron anfitriones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_PLAYLIST_ENTRIES_AVAILABLE, - "No hay entradas en la lista de reproducción" - ) + MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, + "No se encuentran redes" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, - "No se ha encontrado una configuración" - ) + MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, + "No hay contadores de rendimiento" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, - "No hay parámetros de shaders" - ) + MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, + "No hay listas de reproducción" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_OFF, - "OFF" - ) + MENU_ENUM_LABEL_VALUE_NO_PLAYLIST_ENTRIES_AVAILABLE, + "No hay entradas en la lista de reproducción" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ON, - "ON" - ) + MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, + "No se ha encontrado una configuración" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ONLINE, - "En línea" - ) + MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, + "No hay parámetros de shaders" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER, - "Actualizador en línea" - ) + MENU_ENUM_LABEL_VALUE_OFF, + "OFF" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS, - "Información en pantalla (OSD)" - ) + MENU_ENUM_LABEL_VALUE_ON, + "ON" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS, - "Superposiciones" - ) + MENU_ENUM_LABEL_VALUE_ONLINE, + "En línea" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ONSCREEN_OVERLAY_SETTINGS, - "Opciones de controles en pantalla o marcos" - ) + MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER, + "Actualizador en línea" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS, - "Notificaciones" - ) + MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS, + "Información en pantalla (OSD)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ONSCREEN_NOTIFICATIONS_SETTINGS, - "Ajusta las notificaciones en pantalla" - ) + MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS, + "Superposiciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_OPEN_ARCHIVE, - "Explorar archivo" - ) + MENU_ENUM_SUBLABEL_ONSCREEN_OVERLAY_SETTINGS, + "Opciones de controles en pantalla o marcos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_OPTIONAL, - "Opcional" - ) + MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS, + "Notificaciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_OVERLAY, - "Superposiciones" - ) + MENU_ENUM_SUBLABEL_ONSCREEN_NOTIFICATIONS_SETTINGS, + "Ajusta las notificaciones en pantalla" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED, - "Auto-cargar superposición preferida" - ) + MENU_ENUM_LABEL_VALUE_OPEN_ARCHIVE, + "Explorar archivo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_OVERLAY_DIRECTORY, - "Superposiciones" - ) + MENU_ENUM_LABEL_VALUE_OPTIONAL, + "Opcional" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_OVERLAY_OPACITY, - "Opacidad" - ) + MENU_ENUM_LABEL_VALUE_OVERLAY, + "Superposiciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_OVERLAY_PRESET, - "Superposición" - ) + MENU_ENUM_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED, + "Auto-cargar superposición preferida" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_OVERLAY_SCALE, - "Escala" - ) + MENU_ENUM_LABEL_VALUE_OVERLAY_DIRECTORY, + "Superposiciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS, - "Superposición de pantalla" - ) + MENU_ENUM_LABEL_VALUE_OVERLAY_OPACITY, + "Opacidad" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PAL60_ENABLE, - "Usar modo PAL60" - ) + MENU_ENUM_LABEL_VALUE_OVERLAY_PRESET, + "Superposición" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY, - "Carpeta superior" - ) + MENU_ENUM_LABEL_VALUE_OVERLAY_SCALE, + "Escala" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PAUSE_LIBRETRO, - "Pausar al activar el menú" - ) + MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS, + "Superposición de pantalla" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, - "Pausar al quedar en segundo plano" - ) + MENU_ENUM_LABEL_VALUE_PAL60_ENABLE, + "Usar modo PAL60" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, - "Contadores de rendimiento" - ) + MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY, + "Carpeta superior" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, - "Listas de reproducción" - ) + MENU_ENUM_LABEL_VALUE_PAUSE_LIBRETRO, + "Pausar al activar el menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Listas de reproducción" - ) + MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, + "Pausar al quedar en segundo plano" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, - "Listas de reproducción" - ) + MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, + "Contadores de rendimiento" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, - "Soporte táctil" - ) + MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, + "Listas de reproducción" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PORT, - "Puerto" - ) + MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, + "Listas de reproducción" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PRESENT, - "Presente" - ) + MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, + "Listas de reproducción" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PRIVACY_SETTINGS, - "Privacidad" - ) + MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, + "Soporte táctil" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MIDI_SETTINGS, - "MIDI" - ) + MENU_ENUM_LABEL_VALUE_PORT, + "Puerto" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH, - "Cerrar RetroArch" - ) + MENU_ENUM_LABEL_VALUE_PRESENT, + "Presente" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ANALOG, - "Soporte de analógico" - ) + MENU_ENUM_LABEL_VALUE_PRIVACY_SETTINGS, + "Privacidad" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_BBFC_RATING, - "BBFC Rating" - ) + MENU_ENUM_LABEL_VALUE_MIDI_SETTINGS, + "MIDI" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CERO_RATING, - "CERO Rating" - ) + MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH, + "Cerrar RetroArch" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_COOP, - "Soporte de Co-op" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ANALOG, + "Soporte de analógico" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CRC32, - "CRC32" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_BBFC_RATING, + "BBFC Rating" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DESCRIPTION, - "Descripción" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CERO_RATING, + "CERO Rating" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DEVELOPER, - "Desarrollador" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_COOP, + "Soporte de Co-op" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_ISSUE, - "Edición de la revista Edge" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CRC32, + "CRC32" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_RATING, - "Calificación de la revista Edge" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DESCRIPTION, + "Descripción" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_REVIEW, - "Analisis de la revista Edge" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DEVELOPER, + "Desarrollador" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ELSPA_RATING, - "ELSPA Rating" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_ISSUE, + "Edición de la revista Edge" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ENHANCEMENT_HW, - "Enhancement Hardware" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_RATING, + "Calificación de la revista Edge" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ESRB_RATING, - "ESRB Rating" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_REVIEW, + "Analisis de la revista Edge" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FAMITSU_MAGAZINE_RATING, - "Calificación de la revista Famitsu" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ELSPA_RATING, + "ELSPA Rating" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FRANCHISE, - "Franquicia" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ENHANCEMENT_HW, + "Hardware de mejora" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_GENRE, - "Género" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ESRB_RATING, + "ESRB Rating" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_MD5, - "MD5" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FAMITSU_MAGAZINE_RATING, + "Calificación de la revista Famitsu" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME, - "Nombre" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FRANCHISE, + "Franquicia" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ORIGIN, - "Origen" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_GENRE, + "Género" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PEGI_RATING, - "PEGI Rating" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_MD5, + "MD5" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PUBLISHER, - "Distribuidora" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME, + "Nombre" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_MONTH, - "Mes de lanzamiento" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ORIGIN, + "Origen" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_YEAR, - "Año de lanzamiento" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PEGI_RATING, + "PEGI Rating" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RUMBLE, - "Soporte de vibración" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PUBLISHER, + "Distribuidora" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SERIAL, - "Serial" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_MONTH, + "Mes de lanzamiento" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SHA1, - "SHA1" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_YEAR, + "Año de lanzamiento" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_START_CONTENT, - "Ejecutar contenido" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RUMBLE, + "Soporte de vibración" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, - "TGDB Rating" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SERIAL, + "Serial" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REBOOT, - "Reiniciar" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SHA1, + "SHA1" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY, - "Carpeta de configuración de grabación" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_START_CONTENT, + "Ejecutar contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RECORDING_OUTPUT_DIRECTORY, - "Carpeta de salida de grabación" - ) + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, + "TGDB Rating" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, - "Grabación" - ) + MENU_ENUM_LABEL_VALUE_REBOOT, + "Reiniciar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, - "Cargar configuración de grabación..." - ) + MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY, + "Carpeta de configuración de grabación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RECORD_DRIVER, - "Controlador de grabación" - ) + MENU_ENUM_LABEL_VALUE_RECORDING_OUTPUT_DIRECTORY, + "Carpeta de salida de grabación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MIDI_DRIVER, - "Controlador MIDI" - ) + MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, + "Grabación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RECORD_ENABLE, - "Activar grabación" - ) + MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, + "Cargar configuración de grabación..." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RECORD_PATH, - "Guardar grabación como..." - ) + MENU_ENUM_LABEL_VALUE_RECORD_DRIVER, + "Controlador de grabación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RECORD_USE_OUTPUT_DIRECTORY, - "Usar carpeta de salida" - ) + MENU_ENUM_LABEL_VALUE_MIDI_DRIVER, + "Controlador MIDI" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REMAP_FILE, - "Archivo de reasignación de controles" - ) + MENU_ENUM_LABEL_VALUE_RECORD_ENABLE, + "Activar grabación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REMAP_FILE_LOAD, - "Cargar archivo de reasignación" - ) + MENU_ENUM_LABEL_VALUE_RECORD_PATH, + "Guardar grabación como..." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CORE, - "Guardar controles para el núcleo" - ) + MENU_ENUM_LABEL_VALUE_RECORD_USE_OUTPUT_DIRECTORY, + "Usar carpeta de salida" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CONTENT_DIR, - "Lugar donde guardar controles para el núcleo" - ) + MENU_ENUM_LABEL_VALUE_REMAP_FILE, + "Archivo de reasignación de controles" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_GAME, - "Guardar controles para el juego" - ) + MENU_ENUM_LABEL_VALUE_REMAP_FILE_LOAD, + "Cargar archivo de reasignación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CORE, - "Borrar controles personalizados del núcleo" - ) + MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CORE, + "Guardar controles para el núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_GAME, - "Borrar controles personalizados del juego" - ) + MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CONTENT_DIR, + "Lugar donde guardar controles para el núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CONTENT_DIR, - "Borrar directorio de controles personalizados" - ) + MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_GAME, + "Guardar controles para el juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REQUIRED, - "Necesario" - ) + MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CORE, + "Borrar controles personalizados del núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RESTART_CONTENT, - "Reiniciar" - ) + MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_GAME, + "Borrar controles personalizados del juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH, - "Reiniciar RetroArch" - ) + MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CONTENT_DIR, + "Borrar directorio de controles personalizados" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RESUME, - "Reanudar" - ) + MENU_ENUM_LABEL_VALUE_REQUIRED, + "Necesario" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RESUME_CONTENT, - "Reanudar" - ) + MENU_ENUM_LABEL_VALUE_RESTART_CONTENT, + "Reiniciar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RETROKEYBOARD, - "RetroKeyboard" - ) + MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH, + "Reiniciar RetroArch" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RETROPAD, - "RetroPad" - ) + MENU_ENUM_LABEL_VALUE_RESUME, + "Reanudar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RETROPAD_WITH_ANALOG, - "RetroPad con Analógicos" - ) + MENU_ENUM_LABEL_VALUE_RESUME_CONTENT, + "Reanudar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS, - "Logros" - ) + MENU_ENUM_LABEL_VALUE_RETROKEYBOARD, + "RetroKeyboard" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REWIND_ENABLE, - "Activar rebobinado" - ) + MENU_ENUM_LABEL_VALUE_RETROPAD, + "RetroPad" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REWIND_GRANULARITY, - "Nivel de detalle del rebobinado" - ) + MENU_ENUM_LABEL_VALUE_RETROPAD_WITH_ANALOG, + "RetroPad con Analógicos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE, - "Tamaño del Búfer de rebobinado (MB)" - ) + MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS, + "Logros" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE_STEP, - "Tamaño del intervalo de ajuste del Búfer (MB)" - ) + MENU_ENUM_LABEL_VALUE_REWIND_ENABLE, + "Activar rebobinado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS, - "Rebobinado" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_AFTER_TOGGLE, + "Aplicar después de cambiar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_DETAILS_SETTINGS, - "Detalles del truco" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_AFTER_LOAD, + "Auto-aplicar trucos durante la carga" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_SETTINGS, - "Iniciar o continuar búsqueda de trucos" - ) + MENU_ENUM_LABEL_VALUE_REWIND_GRANULARITY, + "Nivel de detalle del rebobinado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY, - "Explorador de archivos" - ) + MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE, + "Tamaño del Búfer de rebobinado (MB)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY, - "Config" - ) + MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE_STEP, + "Tamaño del intervalo de ajuste del Búfer (MB)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN, - "Mostrar pantalla de inicio" - ) + MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS, + "Rebobinado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG, - "Analógico derecho" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_SETTINGS, + "Opciones de trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES, - "Agregar a Favoritos" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_DETAILS_SETTINGS, + "Detalles del truco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST, - "Agregar a Favoritos" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_SETTINGS, + "Iniciar o continuar búsqueda de trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RESET_CORE_ASSOCIATION, - "Restablecer asociación de núcleo" - ) + MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY, + "Explorador de archivos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RUN, - "Iniciar" - ) + MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY, + "Config" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RUN_MUSIC, - "Iniciar" - ) + MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN, + "Mostrar pantalla de inicio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAMBA_ENABLE, - "Activar SAMBA" - ) + MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG, + "Analógico derecho" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVEFILE_DIRECTORY, - "Partidas guardadas" - ) + MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES, + "Agregar a Favoritos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX, - "Indizar automáticamente guardados rápidos" - ) + MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST, + "Agregar a Favoritos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD, - "Cargar guardado rápido automáticamente" - ) + MENU_ENUM_LABEL_VALUE_RESET_CORE_ASSOCIATION, + "Restablecer asociación de núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE, - "Guardado rápido automático" - ) + MENU_ENUM_LABEL_VALUE_RUN, + "Iniciar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVESTATE_DIRECTORY, - "Guardados rápidos" - ) + MENU_ENUM_LABEL_VALUE_RUN_MUSIC, + "Iniciar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE, - "Miniaturas de guardados rápidos" - ) + MENU_ENUM_LABEL_VALUE_SAMBA_ENABLE, + "Activar SAMBA" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG, - "Guardar configuración actual" - ) + MENU_ENUM_LABEL_VALUE_SAVEFILE_DIRECTORY, + "Partidas guardadas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, - "Guardar personalizaciones del núcleo" - ) + MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX, + "Indizar automáticamente guardados rápidos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, - "Lugar donde guardar personalizaciones del juego" - ) + MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD, + "Cargar guardado rápido automáticamente" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, - "Guardar personalizaciones del juego" - ) + MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE, + "Guardado rápido automático" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVE_NEW_CONFIG, - "Guardar configuración nueva" - ) + MENU_ENUM_LABEL_VALUE_SAVESTATE_DIRECTORY, + "Guardados rápidos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVE_STATE, - "Guardado rápido" - ) + MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE, + "Miniaturas de guardados rápidos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS, - "Guardado" - ) + MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG, + "Guardar configuración actual" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY, - "Escanear carpeta" - ) + MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, + "Guardar personalizaciones del núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SCAN_FILE, - "Escanear archivo" - ) + MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, + "Lugar donde guardar personalizaciones del juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY, - "" - ) + MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, + "Guardar personalizaciones del juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SCREENSHOT_DIRECTORY, - "Capturas de pantalla" - ) + MENU_ENUM_LABEL_VALUE_SAVE_NEW_CONFIG, + "Guardar configuración nueva" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION, - "Resolución de pantalla" - ) + MENU_ENUM_LABEL_VALUE_SAVE_STATE, + "Guardado rápido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SEARCH, - "Buscar" - ) + MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS, + "Guardado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SECONDS, - "segundos" - ) + MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY, + "Escanear carpeta" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SETTINGS, - "Ajustes" - ) + MENU_ENUM_LABEL_VALUE_SCAN_FILE, + "Escanear archivo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SETTINGS_TAB, - "Ajustes" - ) + MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY, + "" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHADER, - "Shader" - ) + MENU_ENUM_LABEL_VALUE_SCREENSHOT_DIRECTORY, + "Capturas de pantalla" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHADER_APPLY_CHANGES, - "Aplicar cambios" - ) + MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION, + "Resolución de pantalla" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS, - "Shaders" - ) + MENU_ENUM_LABEL_VALUE_SEARCH, + "Buscar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON, - "Ribbon" - ) + MENU_ENUM_LABEL_VALUE_SECONDS, + "segundos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON_SIMPLIFIED, - "Ribbon (simplificado)" - ) + MENU_ENUM_LABEL_VALUE_SETTINGS, + "Ajustes" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SIMPLE_SNOW, - "Nieve Simple" - ) + MENU_ENUM_LABEL_VALUE_SETTINGS_TAB, + "Ajustes" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOW, - "Nieve" - ) + MENU_ENUM_LABEL_VALUE_SHADER, + "Shader" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHOW_ADVANCED_SETTINGS, - "Mostrar ajustes avanzados" - ) + MENU_ENUM_LABEL_VALUE_SHADER_APPLY_CHANGES, + "Aplicar cambios" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHOW_HIDDEN_FILES, - "Mostrar archivos y carpetas ocultos" - ) + MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS, + "Shaders" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHUTDOWN, - "Apagar" - ) + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON, + "Ribbon" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO, - "Velocidad de cámara lenta" - ) + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON_SIMPLIFIED, + "Ribbon (simplificado)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RUN_AHEAD_ENABLED, - "Reducir latencia usando Run-Ahead" - ) + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SIMPLE_SNOW, + "Nieve Simple" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RUN_AHEAD_FRAMES, - "Frames a ir por delante" - ) + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOW, + "Nieve" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RUN_AHEAD_SECONDARY_INSTANCE, - "Segunda instancia de RunAhead" - ) + MENU_ENUM_LABEL_VALUE_SHOW_ADVANCED_SETTINGS, + "Mostrar ajustes avanzados" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RUN_AHEAD_HIDE_WARNINGS, - "Ocultar advertencias de RunAhead" - ) + MENU_ENUM_LABEL_VALUE_SHOW_HIDDEN_FILES, + "Mostrar archivos y carpetas ocultos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SORT_SAVEFILES_ENABLE, - "Ordenar partidas guardadas por carpetas" - ) + MENU_ENUM_LABEL_VALUE_SHUTDOWN, + "Apagar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SORT_SAVESTATES_ENABLE, - "Ordenar guardados rápidos por carpetas" - ) + MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO, + "Velocidad de cámara lenta" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVESTATES_IN_CONTENT_DIR_ENABLE, - "Escribir guardado rápido en la carpeta del contenido" - ) + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_ENABLED, + "Reducir latencia usando Run-Ahead" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SAVEFILES_IN_CONTENT_DIR_ENABLE, - "Escribir partida guardada en la carpeta del contenido" - ) + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_FRAMES, + "Frames a ir por delante" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEMFILES_IN_CONTENT_DIR_ENABLE, - "Archivos de Sistema están en la carpeta del contenido" - ) + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_SECONDARY_INSTANCE, + "Segunda instancia de RunAhead" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SCREENSHOTS_IN_CONTENT_DIR_ENABLE, - "Escribir capturas de pantalla en la carpeta del contenido" - ) + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_HIDE_WARNINGS, + "Ocultar advertencias de RunAhead" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SSH_ENABLE, - "Activar SSH" - ) + MENU_ENUM_LABEL_VALUE_SORT_SAVEFILES_ENABLE, + "Ordenar partidas guardadas por carpetas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_START_CORE, - "Iniciar núcleo" - ) + MENU_ENUM_LABEL_VALUE_SORT_SAVESTATES_ENABLE, + "Ordenar guardados rápidos por carpetas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_START_NET_RETROPAD, - "Iniciar RetroPad remoto" - ) + MENU_ENUM_LABEL_VALUE_SAVESTATES_IN_CONTENT_DIR_ENABLE, + "Escribir guardado rápido en la carpeta del contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_START_VIDEO_PROCESSOR, - "Iniciar procesador de video" - ) + MENU_ENUM_LABEL_VALUE_SAVEFILES_IN_CONTENT_DIR_ENABLE, + "Escribir partida guardada en la carpeta del contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_STATE_SLOT, - "Posición de guardado" - ) + MENU_ENUM_LABEL_VALUE_SYSTEMFILES_IN_CONTENT_DIR_ENABLE, + "Archivos de Sistema están en la carpeta del contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_STATUS, - "Estado" - ) + MENU_ENUM_LABEL_VALUE_SCREENSHOTS_IN_CONTENT_DIR_ENABLE, + "Escribir capturas de pantalla en la carpeta del contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_STDIN_CMD_ENABLE, - "Comandos stdin" - ) + MENU_ENUM_LABEL_VALUE_SSH_ENABLE, + "Activar SSH" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES, - "Núcleos sugeridos" - ) + MENU_ENUM_LABEL_VALUE_START_CORE, + "Iniciar núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SUSPEND_SCREENSAVER_ENABLE, - "Suspender salvapantallas" - ) + MENU_ENUM_LABEL_VALUE_START_NET_RETROPAD, + "Iniciar RetroPad remoto" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_BGM_ENABLE, - "Activar música del sistema" - ) + MENU_ENUM_LABEL_VALUE_START_VIDEO_PROCESSOR, + "Iniciar procesador de video" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_DIRECTORY, - "Sistema/BIOS" - ) + MENU_ENUM_LABEL_VALUE_STATE_SLOT, + "Posición de guardado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFORMATION, - "Información del sistema" - ) + MENU_ENUM_LABEL_VALUE_STATUS, + "Estado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_7ZIP_SUPPORT, - "Soporte de 7zip" - ) + MENU_ENUM_LABEL_VALUE_STDIN_CMD_ENABLE, + "Comandos stdin" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ALSA_SUPPORT, - "Soporte de ALSA" - ) + MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES, + "Núcleos sugeridos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_BUILD_DATE, - "Fecha de compilación" - ) + MENU_ENUM_LABEL_VALUE_SUSPEND_SCREENSAVER_ENABLE, + "Suspender salvapantallas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CG_SUPPORT, - "Soporte de Cg" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_BGM_ENABLE, + "Activar música del sistema" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COCOA_SUPPORT, - "Soporte de Cocoa" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_DIRECTORY, + "Sistema/BIOS" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COMMAND_IFACE_SUPPORT, - "Soporte de interfaz de comandos" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFORMATION, + "Información del sistema" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CORETEXT_SUPPORT, - "Soporte de CoreText" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_7ZIP_SUPPORT, + "Soporte de 7zip" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CPU_FEATURES, - "Características de CPU" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ALSA_SUPPORT, + "Soporte de ALSA" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_DPI, - "Mostrar DPI métricos" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_BUILD_DATE, + "Fecha de compilación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_HEIGHT, - "Mostrar alto métrico (mm)" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CG_SUPPORT, + "Soporte de Cg" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_WIDTH, - "Mostrar ancho métrico (mm)" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COCOA_SUPPORT, + "Soporte de Cocoa" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DSOUND_SUPPORT, - "Soporte de DirectSound" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COMMAND_IFACE_SUPPORT, + "Soporte de interfaz de comandos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WASAPI_SUPPORT, - "Soporte de WASAPI" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CORETEXT_SUPPORT, + "Soporte de CoreText" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYLIB_SUPPORT, - "Soporte de librerías dinámicas" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CPU_FEATURES, + "Características de CPU" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYNAMIC_SUPPORT, - "Carga dinámica en tiempo real de librería libretro" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_DPI, + "Mostrar DPI métricos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_EGL_SUPPORT, - "Soporte de EGL" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_HEIGHT, + "Mostrar alto métrico (mm)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FBO_SUPPORT, - "Soporte de render-to-texture OpenGL/Direct3D (shaders multipasos)" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_WIDTH, + "Mostrar ancho métrico (mm)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FFMPEG_SUPPORT, - "Soporte de FFmpeg" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DSOUND_SUPPORT, + "Soporte de DirectSound" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FREETYPE_SUPPORT, - "Soporte de FreeType" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WASAPI_SUPPORT, + "Soporte de WASAPI" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_IDENTIFIER, - "Identificador del frontend" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYLIB_SUPPORT, + "Soporte de librerías dinámicas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_NAME, - "Nombre del frontend" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYNAMIC_SUPPORT, + "Carga dinámica en tiempo real de librería libretro" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_OS, - "S.O. del frontend" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_EGL_SUPPORT, + "Soporte de EGL" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GIT_VERSION, - "Versión de Git" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FBO_SUPPORT, + "Soporte de render-to-texture OpenGL/Direct3D (shaders multipasos)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GLSL_SUPPORT, - "Soporte de GLSL" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FFMPEG_SUPPORT, + "Soporte de FFmpeg" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_HLSL_SUPPORT, - "Soporte de HLSL" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FREETYPE_SUPPORT, + "Soporte de FreeType" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_JACK_SUPPORT, - "Soporte de JACK" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_IDENTIFIER, + "Identificador del frontend" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_KMS_SUPPORT, - "Soporte de KMS/EGL" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_NAME, + "Nombre del frontend" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LAKKA_VERSION, - "Versión de Lakka" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_OS, + "S.O. del frontend" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, - "Soporte de LibretroDB" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GIT_VERSION, + "Versión de Git" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, - "Soporte de Libusb" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GLSL_SUPPORT, + "Soporte de GLSL" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "Soporte de parseo XML libxml2" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_HLSL_SUPPORT, + "Soporte de HLSL" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, - "Soporte de juego en red (peer-to-peer)" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_JACK_SUPPORT, + "Soporte de JACK" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, - "Soporte de interfaz de comandos en red" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_KMS_SUPPORT, + "Soporte de KMS/EGL" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_REMOTE_SUPPORT, - "Soporte de mando en red" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LAKKA_VERSION, + "Versión de Lakka" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENAL_SUPPORT, - "Soporte de OpenAL" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, + "Soporte de LibretroDB" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGLES_SUPPORT, - "Soporte de OpenGL ES" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, + "Soporte de Libusb" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGL_SUPPORT, - "Soporte de OpenGL" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, + "Soporte de parseo XML libxml2" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENSL_SUPPORT, - "Soporte de OpenSL" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, + "Soporte de juego en red (peer-to-peer)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENVG_SUPPORT, - "Soporte de OpenVG" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, + "Soporte de interfaz de comandos en red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OSS_SUPPORT, - "Soporte de OSS" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_REMOTE_SUPPORT, + "Soporte de mando en red" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OVERLAY_SUPPORT, - "Soporte de superposiciones" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENAL_SUPPORT, + "Soporte de OpenAL" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE, - "Fuente de alimentación" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGLES_SUPPORT, + "Soporte de OpenGL ES" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGED, - "Cargada" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGL_SUPPORT, + "Soporte de OpenGL" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGING, - "Cargando" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENSL_SUPPORT, + "Soporte de OpenSL" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_DISCHARGING, - "Descargando" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENVG_SUPPORT, + "Soporte de OpenVG" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_NO_SOURCE, - "No hay una fuente" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OSS_SUPPORT, + "Soporte de OSS" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PULSEAUDIO_SUPPORT, - "Soporte de PulseAudio" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OVERLAY_SUPPORT, + "Soporte de superposiciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PYTHON_SUPPORT, - "Soporte de Python (soporte de scripts para shaders)" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE, + "Fuente de alimentación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RBMP_SUPPORT, - "Soporte de BMP (RBMP)" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGED, + "Cargada" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RETRORATING_LEVEL, - "Nivel de RetroRating" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGING, + "Cargando" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RJPEG_SUPPORT, - "Soporte de JPEG (RJPEG)" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_DISCHARGING, + "Descargando" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ROARAUDIO_SUPPORT, - "Soporte de RoarAudio" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_NO_SOURCE, + "No hay una fuente" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RPNG_SUPPORT, - "Soporte de PNG (RPNG)" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PULSEAUDIO_SUPPORT, + "Soporte de PulseAudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RSOUND_SUPPORT, - "Soporte de RSound" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PYTHON_SUPPORT, + "Soporte de Python (soporte de scripts para shaders)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RTGA_SUPPORT, - "Soporte de TGA (RTGA)" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RBMP_SUPPORT, + "Soporte de BMP (RBMP)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL2_SUPPORT, - "Soporte de SDL2" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RETRORATING_LEVEL, + "Nivel de RetroRating" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_IMAGE_SUPPORT, - "Soporte de imágenes SDL" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RJPEG_SUPPORT, + "Soporte de JPEG (RJPEG)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_SUPPORT, - "Soporte de SDL1.2" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ROARAUDIO_SUPPORT, + "Soporte de RoarAudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SLANG_SUPPORT, - "Soporte de Slang" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RPNG_SUPPORT, + "Soporte de PNG (RPNG)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_THREADING_SUPPORT, - "Soporte de hilos" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RSOUND_SUPPORT, + "Soporte de RSound" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_UDEV_SUPPORT, - "Soporte de Udev" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RTGA_SUPPORT, + "Soporte de TGA (RTGA)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_V4L2_SUPPORT, - "Soporte de Video4Linux2" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL2_SUPPORT, + "Soporte de SDL2" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VIDEO_CONTEXT_DRIVER, - "Controlador de contexto de video" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_IMAGE_SUPPORT, + "Soporte de imágenes SDL" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VULKAN_SUPPORT, - "Soporte de Vulkan" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_SUPPORT, + "Soporte de SDL1.2" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_METAL_SUPPORT, - "Soporte de Metal" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SLANG_SUPPORT, + "Soporte de Slang" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WAYLAND_SUPPORT, - "Soporte de Wayland" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_THREADING_SUPPORT, + "Soporte de hilos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_X11_SUPPORT, - "Soporte de X11" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_UDEV_SUPPORT, + "Soporte de Udev" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XAUDIO2_SUPPORT, - "Soporte de XAudio2" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_V4L2_SUPPORT, + "Soporte de Video4Linux2" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XVIDEO_SUPPORT, - "Soporte de XVideo" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VIDEO_CONTEXT_DRIVER, + "Controlador de contexto de video" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ZLIB_SUPPORT, - "Soporte de Zlib" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VULKAN_SUPPORT, + "Soporte de Vulkan" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT, - "Capturar pantalla" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_METAL_SUPPORT, + "Soporte de Metal" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, - "Tareas en hilos" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WAYLAND_SUPPORT, + "Soporte de Wayland" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_THUMBNAILS, - "Miniaturas" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_X11_SUPPORT, + "Soporte de X11" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS, - "Miniaturas Izquierdas" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XAUDIO2_SUPPORT, + "Soporte de XAudio2" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS, - "Miniaturas Disposición Vertical" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XVIDEO_SUPPORT, + "Soporte de XVideo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, - "Miniaturas" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ZLIB_SUPPORT, + "Soporte de Zlib" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST, - "Actualizador de miniaturas" - ) + MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT, + "Capturar pantalla" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS, - "Cajas" - ) + MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, + "Tareas en hilos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS, - "Capturas de pantalla" - ) + MENU_ENUM_LABEL_VALUE_THUMBNAILS, + "Miniaturas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS, - "Pantallas de título" - ) + MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS, + "Miniaturas Izquierdas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_TIMEDATE_ENABLE, - "Mostrar fecha y hora" - ) + MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS, + "Miniaturas Disposición Vertical" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_TITLE_COLOR, - "Color de títulos del menú" - ) + MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, + "Miniaturas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_TRUE, - "Activado" - ) + MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST, + "Actualizador de miniaturas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UI_COMPANION_ENABLE, - "Activar IU ayudante" - ) + MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS, + "Cajas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UI_COMPANION_START_ON_BOOT, - "Ejecutar al inicio la IU ayudante" - ) + MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS, + "Capturas de pantalla" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UI_COMPANION_TOGGLE, - "Mostrar menú de escritorio al inicio" - ) + MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS, + "Pantallas de título" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DESKTOP_MENU_ENABLE, - "Activar menú de escritorio (reiniciar)" - ) + MENU_ENUM_LABEL_VALUE_TIMEDATE_ENABLE, + "Mostrar fecha y hora" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UI_MENUBAR_ENABLE, - "Barra de menús" - ) + MENU_ENUM_LABEL_VALUE_TITLE_COLOR, + "Color de títulos del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE, - "No se ha podido leer el archivo comprimido" - ) + MENU_ENUM_LABEL_VALUE_TRUE, + "Activado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UNDO_LOAD_STATE, - "Deshacer carga" - ) + MENU_ENUM_LABEL_VALUE_UI_COMPANION_ENABLE, + "Activar IU ayudante" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UNDO_SAVE_STATE, - "Deshacer guardado" - ) + MENU_ENUM_LABEL_VALUE_UI_COMPANION_START_ON_BOOT, + "Ejecutar al inicio la IU ayudante" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UNKNOWN, - "Desconocido" - ) + MENU_ENUM_LABEL_VALUE_UI_COMPANION_TOGGLE, + "Mostrar menú de escritorio al inicio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS, - "Actualizador" - ) + MENU_ENUM_LABEL_VALUE_DESKTOP_MENU_ENABLE, + "Activar menú de escritorio (reiniciar)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UPDATE_ASSETS, - "Actualizar recursos" - ) + MENU_ENUM_LABEL_VALUE_UI_MENUBAR_ENABLE, + "Barra de menús" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UPDATE_AUTOCONFIG_PROFILES, - "Actualizar perfiles de auto-configuración" - ) + MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE, + "No se ha podido leer el archivo comprimido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UPDATE_CG_SHADERS, - "Actualizar shaders Cg" - ) + MENU_ENUM_LABEL_VALUE_UNDO_LOAD_STATE, + "Deshacer carga" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UPDATE_CHEATS, - "Actualizar trucos" - ) + MENU_ENUM_LABEL_VALUE_UNDO_SAVE_STATE, + "Deshacer guardado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UPDATE_CORE_INFO_FILES, - "Actualizar archivos de info de núcleo" - ) + MENU_ENUM_LABEL_VALUE_UNKNOWN, + "Desconocido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UPDATE_DATABASES, - "Actualizar bases de datos" - ) + MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS, + "Actualizador" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UPDATE_GLSL_SHADERS, - "Actualizar shaders GLSL" - ) + MENU_ENUM_LABEL_VALUE_UPDATE_ASSETS, + "Actualizar recursos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UPDATE_LAKKA, - "Actualizar Lakka" - ) + MENU_ENUM_LABEL_VALUE_UPDATE_AUTOCONFIG_PROFILES, + "Actualizar perfiles de auto-configuración" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UPDATE_OVERLAYS, - "Actualizar superposiciones" - ) + MENU_ENUM_LABEL_VALUE_UPDATE_CG_SHADERS, + "Actualizar shaders Cg" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_UPDATE_SLANG_SHADERS, - "Actualizar shaders Slang" - ) + MENU_ENUM_LABEL_VALUE_UPDATE_CHEATS, + "Actualizar trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_USER, - "Usuario" - ) + MENU_ENUM_LABEL_VALUE_UPDATE_CORE_INFO_FILES, + "Actualizar archivos de info de núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_KEYBOARD, - "Teclado" - ) + MENU_ENUM_LABEL_VALUE_UPDATE_DATABASES, + "Actualizar bases de datos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS, - "Interfaz de usuario" - ) + MENU_ENUM_LABEL_VALUE_UPDATE_GLSL_SHADERS, + "Actualizar shaders GLSL" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_USER_LANGUAGE, - "Idioma" - ) + MENU_ENUM_LABEL_VALUE_UPDATE_LAKKA, + "Actualizar Lakka" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_USER_SETTINGS, - "Usuario" - ) + MENU_ENUM_LABEL_VALUE_UPDATE_OVERLAYS, + "Actualizar superposiciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER, - "Usar visor de imágenes integrado" - ) + MENU_ENUM_LABEL_VALUE_UPDATE_SLANG_SHADERS, + "Actualizar shaders Slang" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_USE_BUILTIN_PLAYER, - "Usar visor de medios integrado" - ) + MENU_ENUM_LABEL_VALUE_USER, + "Usuario" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY, - "" - ) + MENU_ENUM_LABEL_VALUE_KEYBOARD, + "Teclado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_ALLOW_ROTATE, - "Permitir rotación" - ) + MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS, + "Interfaz de usuario" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO, - "Configurar relación de aspecto" - ) + MENU_ENUM_LABEL_VALUE_USER_LANGUAGE, + "Idioma" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_AUTO, - "Relación de aspecto automática" - ) + MENU_ENUM_LABEL_VALUE_USER_SETTINGS, + "Usuario" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, - "Relación de aspecto" - ) + MENU_ENUM_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER, + "Usar visor de imágenes integrado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, - "Insertar frames negros" - ) + MENU_ENUM_LABEL_VALUE_USE_BUILTIN_PLAYER, + "Usar visor de medios integrado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, - "Recortar Overscan (Reinicio)" - ) + MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY, + "" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, - "Desactivar composición de escritorio" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_ALLOW_ROTATE, + "Permitir rotación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, - "Controlador de video" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO, + "Configurar relación de aspecto" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, - "Filtro de video" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_AUTO, + "Relación de aspecto automática" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_DIR, - "Filtro de video" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, + "Relación de aspecto" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_FLICKER, - "Filtro de parpadeo" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, + "Insertar frames negros" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_FONT_ENABLE, - "Mostrar notificaciones en pantalla" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, + "Recortar Overscan (Reinicio)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_FONT_PATH, - "Fuente de notificación" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, + "Desactivar composición de escritorio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_FONT_SIZE, - "Tamaño de notificación" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, + "Controlador de video" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_ASPECT, - "Forzar relación de aspecto" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, + "Filtro de video" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_SRGB_DISABLE, - "Forzar desactivación del FBO sRGB" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_DIR, + "Filtro de video" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_FRAME_DELAY, - "Retraso de frames" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_FLICKER, + "Filtro de parpadeo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN, - "Iniciar en pantalla completa" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_FONT_ENABLE, + "Mostrar notificaciones en pantalla" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_GAMMA, - "Gamma de video" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_FONT_PATH, + "Fuente de notificación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_GPU_RECORD, - "Activar grabación de GPU" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_FONT_SIZE, + "Tamaño de notificación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT, - "Permitir capturas de pantalla de GPU" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_ASPECT, + "Forzar relación de aspecto" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, - "Sincronía estricta de GPU" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_SRGB_DISABLE, + "Forzar desactivación del FBO sRGB" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES, - "Frames para sincronía estricta" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_FRAME_DELAY, + "Retraso de frames" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES, - "Máximo de imágenes en swapchain" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN, + "Iniciar en pantalla completa" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_X, - "Posición X de notificaciones" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_GAMMA, + "Gamma de video" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_Y, - "Posición Y de notificaciones" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_GPU_RECORD, + "Activar grabación de GPU" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_MONITOR_INDEX, - "Índice del monitor" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT, + "Permitir capturas de pantalla de GPU" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_POST_FILTER_RECORD, - "Activar grabación con filtros" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, + "Sincronía estricta de GPU" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, - "Frecuencia de actualización" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES, + "Frames para sincronía estricta" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, - "Frecuencia estimada del monitor" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES, + "Máximo de imágenes en swapchain" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, - "Set Display-Reported Refresh Rate" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_X, + "Posición X de notificaciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, - "Rotación" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_Y, + "Posición Y de notificaciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, - "Escala en ventana" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_MONITOR_INDEX, + "Índice del monitor" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER, - "Escalar usando enteros" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_POST_FILTER_RECORD, + "Activar grabación con filtros" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS, - "Video" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, + "Frecuencia de actualización" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DIR, - "Shader de video" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, + "Frecuencia estimada del monitor" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_NUM_PASSES, - "Pasadas del shader" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS, - "Previsualizar parámetros de shaders" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, + "Rotación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET, - "Cargar preset de shaders" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, + "Escala en ventana" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS, - "Guardar preset de shaders como..." - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER, + "Escalar usando enteros" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE, - "Guardar preset para el núcleo" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS, + "Video" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_PARENT, - "Guardar preset de directorio de contenido" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DIR, + "Shader de video" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME, - "Guardar preset para el juego" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_NUM_PASSES, + "Pasadas del shader" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT, - "Activar contexto compartido por HW" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS, + "Previsualizar parámetros de shaders" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH, - "Filtrado bilineal" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET, + "Cargar preset de shaders" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER, - "Activar filtros por software" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS, + "Guardar preset de shaders como..." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_SWAP_INTERVAL, - "Intervalo de intercambio de Vsync" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE, + "Guardar preset para el núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_TAB, - "Video" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_PARENT, + "Guardar preset de directorio de contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_THREADED, - "Video por hilos" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME, + "Guardar preset para el juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_VFILTER, - "Filtro contra parpadeos" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT, + "Activar contexto compartido por HW" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_HEIGHT, - "Altura de relación de aspecto personalizada" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH, + "Filtrado bilineal" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_WIDTH, - "Ancho de relación de aspecto personalizada" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER, + "Activar filtros por software" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X, - "Custom Aspect Ratio X Pos" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_SWAP_INTERVAL, + "Intervalo de intercambio de Vsync" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_Y, - "Custom Aspect Ratio Y Pos" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_TAB, + "Video" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, - "Asignar ancho de interfaz visual" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_THREADED, + "Video por hilos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, - "Sincronía vertical (VSync)" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_VFILTER, + "Filtro contra parpadeos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, - "Pantalla completa en ventana" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_HEIGHT, + "Altura de relación de aspecto personalizada" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_WIDTH, - "Ancho de la ventana" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_WIDTH, + "Ancho de relación de aspecto personalizada" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_HEIGHT, - "Alto de la ventana" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X, + "Custom Aspect Ratio X Pos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_X, - "Ancho en pantalla completa" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_Y, + "Custom Aspect Ratio Y Pos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_Y, - "Alto en pantalla completa" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, + "Asignar ancho de interfaz visual" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_WIFI_DRIVER, - "Controlador Wi-Fi" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, + "Sincronía vertical (VSync)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, - "Wi-Fi" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, + "Pantalla completa en ventana" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, - "Transparencia del menú" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_WIDTH, + "Ancho de la ventana" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_RED, - "Fuente del Menú componente roja" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_HEIGHT, + "Alto de la ventana" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_GREEN, - "Fuente del Menú componente verde" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_X, + "Ancho en pantalla completa" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_BLUE, - "Fuente del Menú componente azul" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_Y, + "Alto en pantalla completa" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_FONT, - "Fuente del menú" - ) + MENU_ENUM_LABEL_VALUE_WIFI_DRIVER, + "Controlador Wi-Fi" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, - "Personalizado" - ) + MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, + "Wi-Fi" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_FLATUI, - "FlatUI" - ) + MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, + "Transparencia del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME, - "Monochrome" - ) + MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_RED, + "Fuente del Menú componente roja" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME_INVERTED, - "Monochrome Invertido" - ) + MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_GREEN, + "Fuente del Menú componente verde" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_SYSTEMATIC, - "Systematic" - ) + MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_BLUE, + "Fuente del Menú componente azul" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_NEOACTIVE, - "NeoActive" - ) + MENU_ENUM_LABEL_VALUE_XMB_FONT, + "Fuente del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL, - "Pixel" - ) + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, + "Personalizado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE, - "RetroActive" - ) + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_FLATUI, + "FlatUI" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM, - "Retrosystem" - ) + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME, + "Monochrome" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART, - "Dot-Art" - ) + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME_INVERTED, + "Monochrome Invertido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME, - "Color del menú" - ) + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_SYSTEMATIC, + "Systematic" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_APPLE_GREEN, - "Verde manzana" - ) + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_NEOACTIVE, + "NeoActive" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK, - "Oscuro" - ) + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL, + "Pixel" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LIGHT, - "Claro" - ) + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE, + "RetroActive" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MORNING_BLUE, - "Azul Mañana" - ) + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM, + "Retrosystem" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK_PURPLE, - "Violeta" - ) + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART, + "Dot-Art" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_ELECTRIC_BLUE, - "Azul Eléctrico" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME, + "Color del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_GOLDEN, - "Dorado" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_APPLE_GREEN, + "Verde manzana" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LEGACY_RED, - "Rojo" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK, + "Oscuro" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MIDNIGHT_BLUE, - "Azul Medianoche" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LIGHT, + "Claro" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_PLAIN, - "Nada" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MORNING_BLUE, + "Azul Mañana" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_UNDERSEA, - "Bajo el mar" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK_PURPLE, + "Violeta" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_VOLCANIC_RED, - "Rojo Volcánico" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_ELECTRIC_BLUE, + "Azul Eléctrico" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_RIBBON_ENABLE, - "Menú Shader Pipeline" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_GOLDEN, + "Dorado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_SCALE_FACTOR, - "Escala del menú" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LEGACY_RED, + "Rojo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE, - "Sombras de iconos" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MIDNIGHT_BLUE, + "Azul Medianoche" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_HISTORY, - "Mostrar pestaña historial" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_PLAIN, + "Nada" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_ADD, - "Mostrar pestaña importar contenido" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_UNDERSEA, + "Bajo el mar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_PLAYLISTS, - "Mostrar pestañas de Playlists" - ) + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_VOLCANIC_RED, + "Rojo Volcánico" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_FAVORITES, - "Mostrar pestaña favoritos" - ) + MENU_ENUM_LABEL_VALUE_XMB_RIBBON_ENABLE, + "Menú Shader Pipeline" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_IMAGES, - "Mostrar pestaña imágenes" - ) + MENU_ENUM_LABEL_VALUE_XMB_SCALE_FACTOR, + "Escala del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_MUSIC, - "Mostrar pestaña música" - ) + MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE, + "Sombras de iconos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, - "Mostrar pestaña configuración" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_HISTORY, + "Mostrar pestaña historial" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, - "Mostrar pestaña video" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_ADD, + "Mostrar pestaña importar contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, - "Mostrar pestaña juego en red" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_PLAYLISTS, + "Mostrar pestañas de Playlists" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, - "Disposición del menú" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_FAVORITES, + "Mostrar pestaña favoritos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_THEME, - "Tema de iconos del menú" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_IMAGES, + "Mostrar pestaña imágenes" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_YES, - "Sí" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_MUSIC, + "Mostrar pestaña música" + ) MSG_HASH( - MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO, - "Preset de shader" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, + "Mostrar pestaña configuración" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, - "Activar logros. Para más información, visita http://retroachievements.org" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, + "Mostrar pestaña video" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, - "Activar logros no oficiales y/o beta para probarlos" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, + "Mostrar pestaña juego en red" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, - "Duplica puntos pero desactiva guardado rápido, trucos, rebobinar, y cámara lenta para todos los juegos" - ) + MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "Disposición del menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEEVOS_LEADERBOARDS_ENABLE, - "No tiene efecto si el modo hardcore está desactivado" - ) + MENU_ENUM_LABEL_VALUE_XMB_THEME, + "Tema de iconos del menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEEVOS_BADGES_ENABLE, - "Activar para ver miniaturas en la lista de logros" - ) + MENU_ENUM_LABEL_VALUE_YES, + "Sí" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEEVOS_VERBOSE_ENABLE, - "Activar para ver notificaciones mas informativas sobre logros" - ) + MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO, + "Preset de shader" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEEVOS_AUTO_SCREENSHOT, - "Automaticamente hacer una captura de pantalla al obtener un logro" - ) + MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, + "Activar logros. Para más información, visita http://retroachievements.org" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, - "Cambia los controladores usados por el sistema" - ) + MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, + "Activar logros no oficiales y/o beta para probarlos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, - "Opciones de los logros" - ) + MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, + "Duplica puntos pero desactiva guardado rápido, trucos, rebobinar, y cámara lenta para todos los juegos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CORE_SETTINGS, - "Opciones de los núcleos" - ) + MENU_ENUM_SUBLABEL_CHEEVOS_LEADERBOARDS_ENABLE, + "No tiene efecto si el modo hardcore está desactivado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RECORDING_SETTINGS, - "Opciones de grabación" - ) + MENU_ENUM_SUBLABEL_CHEEVOS_BADGES_ENABLE, + "Activar para ver miniaturas en la lista de logros" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ONSCREEN_DISPLAY_SETTINGS, - "Opciones de notificaciones, controles en pantalla y marcos" - ) + MENU_ENUM_SUBLABEL_CHEEVOS_VERBOSE_ENABLE, + "Activar para ver notificaciones mas informativas sobre logros" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_FRAME_THROTTLE_SETTINGS, - "Opciones de rebobinado, adelantado y cámara lenta" - ) + MENU_ENUM_SUBLABEL_CHEEVOS_AUTO_SCREENSHOT, + "Automaticamente hacer una captura de pantalla al obtener un logro" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVING_SETTINGS, - "Opciones de guardado" - ) + MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, + "Cambia los controladores usados por el sistema" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LOGGING_SETTINGS, - "Opciones de registro" - ) + MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, + "Opciones de los logros" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_USER_INTERFACE_SETTINGS, - "Opciones de la interfaz de usuario" - ) + MENU_ENUM_SUBLABEL_CORE_SETTINGS, + "Opciones de los núcleos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_USER_SETTINGS, - "Opciones de cuentas, nombre de usuario y lenguaje" - ) + MENU_ENUM_SUBLABEL_RECORDING_SETTINGS, + "Opciones de grabación" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, - "Opciones de privacidad" - ) + MENU_ENUM_SUBLABEL_ONSCREEN_DISPLAY_SETTINGS, + "Opciones de notificaciones, controles en pantalla y marcos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MIDI_SETTINGS, - "Cambiar opciones MIDI" - ) + MENU_ENUM_SUBLABEL_FRAME_THROTTLE_SETTINGS, + "Opciones de rebobinado, adelantado y cámara lenta" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, - "Cambia las carpetas por defecto donde se encuentran los archivos" - ) + MENU_ENUM_SUBLABEL_SAVING_SETTINGS, + "Opciones de guardado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, - "Opciones de las listas de juegos" - ) + MENU_ENUM_SUBLABEL_LOGGING_SETTINGS, + "Opciones de registro" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, - "Opciones de servidor y red" - ) + MENU_ENUM_SUBLABEL_USER_INTERFACE_SETTINGS, + "Opciones de la interfaz de usuario" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, - "Escanear contenido y agregar a la base de datos" - ) + MENU_ENUM_SUBLABEL_USER_SETTINGS, + "Opciones de cuentas, nombre de usuario y lenguaje" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, - "Opciones de salida de audio" - ) + MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, + "Opciones de privacidad" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE, - "Activar o desactivar Bluetooth" - ) + MENU_ENUM_SUBLABEL_MIDI_SETTINGS, + "Cambiar opciones MIDI" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, - "Guarda los cambios en el archivo de configuración al salir" - ) + MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, + "Cambia las carpetas por defecto donde se encuentran los archivos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONFIGURATION_SETTINGS, - "Opciones de los archivos de configuración" - ) + MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, + "Opciones de las listas de juegos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONFIGURATIONS_LIST, - "Administrar y crear archivos de configuración" - ) + MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, + "Opciones de servidor y red" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CPU_CORES, - "Cantidad de núcleos que tiene la CPU" - ) + MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, + "Escanear contenido y agregar a la base de datos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_FPS_SHOW, - "Muestra la velocidad de cuadros por segundo" - ) + MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, + "Opciones de salida de audio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS, - "Opciones de teclas rápidas (hotkeys)" - ) + MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE, + "Activar o desactivar Bluetooth" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, - "Combinación de botones del mando para mostrar el menú" - ) + MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, + "Guarda los cambios en el archivo de configuración al salir" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_SETTINGS, - "Opciones de mando, teclado y ratón" - ) + MENU_ENUM_SUBLABEL_CONFIGURATION_SETTINGS, + "Opciones de los archivos de configuración" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_USER_BINDS, - "Cambiar los controles para este usuario" - ) + MENU_ENUM_SUBLABEL_CONFIGURATIONS_LIST, + "Administrar y crear archivos de configuración" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LATENCY_SETTINGS, - "Ajustar la latencia por medio de opciones relacionadas con el video, audio y entradas" - ) + MENU_ENUM_SUBLABEL_CPU_CORES, + "Cantidad de núcleos que tiene la CPU" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LOG_VERBOSITY, - "Activar o desactivar registros a la terminal" - ) + MENU_ENUM_SUBLABEL_FPS_SHOW, + "Muestra la velocidad de cuadros por segundo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY, - "Unirse o ser servidor de una sesión de juego en red" - ) + MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS, + "Opciones de teclas rápidas (hotkeys)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, - "Buscar y conectarse a anfitriones de juego en red en la red local" - ) + MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, + "Combinación de botones del mando para mostrar el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "Muestra la información de sistema" - ) + MENU_ENUM_SUBLABEL_INPUT_SETTINGS, + "Opciones de mando, teclado y ratón" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ONLINE_UPDATER, - "Descarga componentes y contenido adicional para RetroArch" - ) + MENU_ENUM_SUBLABEL_INPUT_USER_BINDS, + "Cambiar los controles para este usuario" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAMBA_ENABLE, - "Activar o desactivar el compartido de carpetas en red" - ) + MENU_ENUM_SUBLABEL_LATENCY_SETTINGS, + "Ajustar la latencia por medio de opciones relacionadas con el video, audio y entradas" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, - "Administrar los servicios del sistema operativo" - ) + MENU_ENUM_SUBLABEL_LOG_VERBOSITY, + "Activar o desactivar registros a la terminal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES, - "Mostrar archivos y carpetas ocultos en el explorador de archivos" - ) + MENU_ENUM_SUBLABEL_NETPLAY, + "Unirse o ser servidor de una sesión de juego en red" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SSH_ENABLE, - "Activar o desactivar acceso remoto por linea de comandos" - ) + MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, + "Buscar y conectarse a anfitriones de juego en red en la red local" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE, - "Evita que el protector de pantalla se active" - ) + MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, + "Muestra la información de sistema" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_WINDOW_SCALE, - "Hacer que el tamaño de la ventana sea relativo al núcleo. Alternativamente, puedes fijar el tamaño mas abajo" - ) + MENU_ENUM_SUBLABEL_ONLINE_UPDATER, + "Descarga componentes y contenido adicional para RetroArch" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_USER_LANGUAGE, - "Cambia el lenguaje de la interfaz" - ) + MENU_ENUM_SUBLABEL_SAMBA_ENABLE, + "Activar o desactivar el compartido de carpetas en red" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, - "Insertar un cuadro negro intermedio, Útil para usuarios con pantallas de 120hz que quieren eliminar ghosting en el contenido de 60hz" - ) + MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, + "Administrar los servicios del sistema operativo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, - "Reducir latencia a costa de un mayor riesgo de tirones. Agrega un retraso después del VSync en milisegundos" - ) + MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES, + "Mostrar archivos y carpetas ocultos en el explorador de archivos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, - "Cuantos cuadros puede ir la CPU por delante de la GPU al usar 'Sincronía estricta de GPU'" - ) + MENU_ENUM_SUBLABEL_SSH_ENABLE, + "Activar o desactivar acceso remoto por linea de comandos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, - "Informa al controlador que use el modo de buffering especificado (doble, triple, etc.)" - ) + MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE, + "Evita que el protector de pantalla se active" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, - "Seleccionar la pantalla a usar" - ) + MENU_ENUM_SUBLABEL_VIDEO_WINDOW_SCALE, + "Hacer que el tamaño de la ventana sea relativo al núcleo. Alternativamente, puedes fijar el tamaño mas abajo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, - "Estimado preciso de refresco de la pantalla en Hz" - ) + MENU_ENUM_SUBLABEL_USER_LANGUAGE, + "Cambia el lenguaje de la interfaz" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED, - "La tasa de refresco indicada por el controlador de pantalla" - ) + MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, + "Insertar un cuadro negro intermedio, Útil para usuarios con pantallas de 120hz que quieren eliminar ghosting en el contenido de 60hz" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, - "Opciones de salida de video" - ) + MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, + "Reducir latencia a costa de un mayor riesgo de tirones. Agrega un retraso después del VSync en milisegundos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_WIFI_SETTINGS, - "Escanear redes inalambricas y conectarse" - ) + MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, + "Cuantos cuadros puede ir la CPU por delante de la GPU al usar 'Sincronía estricta de GPU'" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_HELP_LIST, - "Aprender como funciona el programa" - ) + MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, + "Informa al controlador que use el modo de buffering especificado (doble, triple, etc.)" + ) MSG_HASH( - MSG_ADDED_TO_FAVORITES, - "Agregado a los favoritos" - ) + MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, + "Seleccionar la pantalla a usar" + ) MSG_HASH( - MSG_RESET_CORE_ASSOCIATION, - "Restablecida la asociación de la entrada de la lista" - ) + MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, + "Estimado preciso de refresco de la pantalla en Hz" + ) MSG_HASH( - MSG_APPENDED_DISK, - "Disco encolado" - ) + MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED, + "La tasa de refresco indicada por el controlador de pantalla" + ) MSG_HASH( - MSG_APPLICATION_DIR, - "Carpeta de la aplicación" - ) + MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, + "Opciones de salida de video" + ) MSG_HASH( - MSG_APPLYING_CHEAT, - "Aplicando trucos" - ) + MENU_ENUM_SUBLABEL_WIFI_SETTINGS, + "Escanear redes inalambricas y conectarse" + ) MSG_HASH( - MSG_APPLYING_SHADER, - "Aplicando shader" - ) + MENU_ENUM_SUBLABEL_HELP_LIST, + "Aprender como funciona el programa" + ) MSG_HASH( - MSG_AUDIO_MUTED, - "Silencio" - ) + MSG_ADDED_TO_FAVORITES, + "Agregado a los favoritos" + ) MSG_HASH( - MSG_AUDIO_UNMUTED, - "Audio normal" - ) + MSG_RESET_CORE_ASSOCIATION, + "Restablecida la asociación de la entrada de la lista" + ) MSG_HASH( - MSG_AUTOCONFIG_FILE_ERROR_SAVING, - "Error guardando archivo de auto-configuración" - ) + MSG_APPENDED_DISK, + "Disco encolado" + ) MSG_HASH( - MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY, - "Archivo de auto-configuración guardado exitosamente" - ) + MSG_APPLICATION_DIR, + "Carpeta de la aplicación" + ) MSG_HASH( - MSG_AUTOSAVE_FAILED, - "No se puede inicializar autogurardado" - ) + MSG_APPLYING_CHEAT, + "Aplicando trucos" + ) MSG_HASH( - MSG_AUTO_SAVE_STATE_TO, - "Auto guardar en" - ) + MSG_APPLYING_SHADER, + "Aplicando shader" + ) MSG_HASH( - MSG_BLOCKING_SRAM_OVERWRITE, - "Bloquear sobrescritura de SaveRAM" - ) + MSG_AUDIO_MUTED, + "Silencio" + ) MSG_HASH( - MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT, - "Iniciando la linea de comandos en el puerto" - ) + MSG_AUDIO_UNMUTED, + "Audio normal" + ) MSG_HASH( - MSG_BYTES, - "bytes" - ) + MSG_AUTOCONFIG_FILE_ERROR_SAVING, + "Error guardando archivo de auto-configuración" + ) MSG_HASH( - MSG_CANNOT_INFER_NEW_CONFIG_PATH, - "No se puede inferir la nueva ruta de configuración. Use el tiempo actual" - ) + MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY, + "Archivo de auto-configuración guardado exitosamente" + ) MSG_HASH( - MSG_CHEEVOS_HARDCORE_MODE_ENABLE, - "Modo hardcore activado, guardado rápido y rebobinado deshabilitados" - ) + MSG_AUTOSAVE_FAILED, + "No se puede inicializar autogurardado" + ) MSG_HASH( - MSG_COMPARING_WITH_KNOWN_MAGIC_NUMBERS, - "Comparando con números mágicos conocidos..." - ) + MSG_AUTO_SAVE_STATE_TO, + "Auto guardar en" + ) MSG_HASH( - MSG_COMPILED_AGAINST_API, - "Compilado para la API" - ) + MSG_BLOCKING_SRAM_OVERWRITE, + "Bloquear sobrescritura de SaveRAM" + ) MSG_HASH( - MSG_CONFIG_DIRECTORY_NOT_SET, - "Carpeta de configuración no establecida. No se puede guardar la configuración" - ) + MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT, + "Iniciando la linea de comandos en el puerto" + ) MSG_HASH( - MSG_CONNECTED_TO, - "Conectado a" - ) + MSG_BYTES, + "bytes" + ) MSG_HASH( - MSG_CONTENT_CRC32S_DIFFER, - "No se pueden usar diferentes juegos. (El CRC32s difiere)" - ) + MSG_CANNOT_INFER_NEW_CONFIG_PATH, + "No se puede inferir la nueva ruta de configuración. Use el tiempo actual" + ) MSG_HASH( - MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT, - "Carga de contenido saltada. La implementación usara la suya" - ) + MSG_CHEEVOS_HARDCORE_MODE_ENABLE, + "Modo hardcore activado, guardado rápido y rebobinado deshabilitados" + ) MSG_HASH( - MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES, - "El núcleo no soporta guardados rápidos" - ) + MSG_COMPARING_WITH_KNOWN_MAGIC_NUMBERS, + "Comparando con números mágicos conocidos..." + ) MSG_HASH( - MSG_CORE_OPTIONS_FILE_CREATED_SUCCESSFULLY, - "Archivo de opciones del núcleo creado exitosamente" - ) + MSG_COMPILED_AGAINST_API, + "Compilado para la API" + ) MSG_HASH( - MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER, - "No se encuentra otro controlador" - ) + MSG_CONFIG_DIRECTORY_NOT_SET, + "Carpeta de configuración no establecida. No se puede guardar la configuración" + ) MSG_HASH( - MSG_COULD_NOT_FIND_COMPATIBLE_SYSTEM, - "No se encuentra un sistema compatible" - ) + MSG_CONNECTED_TO, + "Conectado a" + ) MSG_HASH( - MSG_COULD_NOT_FIND_VALID_DATA_TRACK, - "No se encuentra una pista de datos válido" - ) + MSG_CONTENT_CRC32S_DIFFER, + "No se pueden usar diferentes juegos. (El CRC32s difiere)" + ) MSG_HASH( - MSG_COULD_NOT_OPEN_DATA_TRACK, - "No se puede abrir la pista de datos" - ) + MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT, + "Carga de contenido saltada. La implementación usara la suya" + ) MSG_HASH( - MSG_COULD_NOT_READ_CONTENT_FILE, - "No se puede leer el contenido" - ) + MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES, + "El núcleo no soporta guardados rápidos" + ) MSG_HASH( - MSG_COULD_NOT_READ_MOVIE_HEADER, - "No se puede leer el encabezado de la película" - ) + MSG_CORE_OPTIONS_FILE_CREATED_SUCCESSFULLY, + "Archivo de opciones del núcleo creado exitosamente" + ) MSG_HASH( - MSG_COULD_NOT_READ_STATE_FROM_MOVIE, - "No se puede leer el estado del película" - ) + MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER, + "No se encuentra otro controlador" + ) MSG_HASH( - MSG_CRC32_CHECKSUM_MISMATCH, - "El CRC32 del contenido no concuerda con el del replay, Es probable que se de-sincronice al reproducir" - ) + MSG_COULD_NOT_FIND_COMPATIBLE_SYSTEM, + "No se encuentra un sistema compatible" + ) MSG_HASH( - MSG_CUSTOM_TIMING_GIVEN, - "Timing personalizado provisto" - ) + MSG_COULD_NOT_FIND_VALID_DATA_TRACK, + "No se encuentra una pista de datos válido" + ) MSG_HASH( - MSG_DECOMPRESSION_ALREADY_IN_PROGRESS, - "Descompresión en progreso" - ) + MSG_COULD_NOT_OPEN_DATA_TRACK, + "No se puede abrir la pista de datos" + ) MSG_HASH( - MSG_DECOMPRESSION_FAILED, - "Fallo al descomprimir" - ) + MSG_COULD_NOT_READ_CONTENT_FILE, + "No se puede leer el contenido" + ) MSG_HASH( - MSG_DETECTED_VIEWPORT_OF, - "Detectado viewport de" - ) + MSG_COULD_NOT_READ_MOVIE_HEADER, + "No se puede leer el encabezado de la película" + ) MSG_HASH( - MSG_DID_NOT_FIND_A_VALID_CONTENT_PATCH, - "No se encontró un parche válido" - ) + MSG_COULD_NOT_READ_STATE_FROM_MOVIE, + "No se puede leer el estado del película" + ) MSG_HASH( - MSG_DISCONNECT_DEVICE_FROM_A_VALID_PORT, - "Desconecte el dispositivo desde un puerto válido" - ) + MSG_CRC32_CHECKSUM_MISMATCH, + "El CRC32 del contenido no concuerda con el del replay, Es probable que se de-sincronice al reproducir" + ) MSG_HASH( - MSG_DISK_CLOSED, - "Cerrado" - ) + MSG_CUSTOM_TIMING_GIVEN, + "Timing personalizado provisto" + ) MSG_HASH( - MSG_DISK_EJECTED, - "Expulsado" - ) + MSG_DECOMPRESSION_ALREADY_IN_PROGRESS, + "Descompresión en progreso" + ) MSG_HASH( - MSG_DOWNLOADING, - "Descargando" - ) + MSG_DECOMPRESSION_FAILED, + "Fallo al descomprimir" + ) MSG_HASH( - MSG_INDEX_FILE, - "indice" - ) + MSG_DETECTED_VIEWPORT_OF, + "Detectado viewport de" + ) MSG_HASH( - MSG_DOWNLOAD_FAILED, - "Descarga fallida" - ) + MSG_DID_NOT_FIND_A_VALID_CONTENT_PATCH, + "No se encontró un parche válido" + ) MSG_HASH( - MSG_ERROR, - "Error" - ) + MSG_DISCONNECT_DEVICE_FROM_A_VALID_PORT, + "Desconecte el dispositivo desde un puerto válido" + ) MSG_HASH( - MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT, - "El núcleo Libretro necesita contenido, pero no fue provisto" - ) + MSG_DISK_CLOSED, + "Cerrado" + ) MSG_HASH( - MSG_ERROR_LIBRETRO_CORE_REQUIRES_SPECIAL_CONTENT, - "El núcleo Libretro necesita contenido especial, pero no fue provisto" - ) + MSG_DISK_EJECTED, + "Expulsado" + ) MSG_HASH( - MSG_ERROR_PARSING_ARGUMENTS, - "Error analizando argumentos" - ) + MSG_DOWNLOADING, + "Descargando" + ) MSG_HASH( - MSG_ERROR_SAVING_CORE_OPTIONS_FILE, - "Error guardando archivo de opciones del núcleo" - ) + MSG_INDEX_FILE, + "indice" + ) MSG_HASH( - MSG_ERROR_SAVING_REMAP_FILE, - "Error guardando archivo de reasignación" - ) + MSG_DOWNLOAD_FAILED, + "Descarga fallida" + ) MSG_HASH( - MSG_ERROR_REMOVING_REMAP_FILE, - "Error eliminado archivo de reasignación" - ) + MSG_ERROR, + "Error" + ) MSG_HASH( - MSG_ERROR_SAVING_SHADER_PRESET, - "Error guardando shader preset" - ) + MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT, + "El núcleo Libretro necesita contenido, pero no fue provisto" + ) MSG_HASH( - MSG_EXTERNAL_APPLICATION_DIR, - "Carpeta de aplicación externa" - ) + MSG_ERROR_LIBRETRO_CORE_REQUIRES_SPECIAL_CONTENT, + "El núcleo Libretro necesita contenido especial, pero no fue provisto" + ) MSG_HASH( - MSG_EXTRACTING, - "Extrayendo" - ) + MSG_ERROR_PARSING_ARGUMENTS, + "Error analizando argumentos" + ) MSG_HASH( - MSG_EXTRACTING_FILE, - "Extrayendo archivo" - ) + MSG_ERROR_SAVING_CORE_OPTIONS_FILE, + "Error guardando archivo de opciones del núcleo" + ) MSG_HASH( - MSG_FAILED_SAVING_CONFIG_TO, - "Fallo al guardar configuración en" - ) + MSG_ERROR_SAVING_REMAP_FILE, + "Error guardando archivo de reasignación" + ) MSG_HASH( - MSG_FAILED_TO, - "Fallo al" - ) + MSG_ERROR_REMOVING_REMAP_FILE, + "Error eliminado archivo de reasignación" + ) MSG_HASH( - MSG_FAILED_TO_ACCEPT_INCOMING_SPECTATOR, - "Fallo al aceptar al espectador" - ) + MSG_ERROR_SAVING_SHADER_PRESET, + "Error guardando shader preset" + ) MSG_HASH( - MSG_FAILED_TO_ALLOCATE_MEMORY_FOR_PATCHED_CONTENT, - "Fallo al reservar memoria para el contenido parcheado" - ) + MSG_EXTERNAL_APPLICATION_DIR, + "Carpeta de aplicación externa" + ) MSG_HASH( - MSG_FAILED_TO_APPLY_SHADER, - "Fallo al aplicar el shader" - ) + MSG_EXTRACTING, + "Extrayendo" + ) MSG_HASH( - MSG_FAILED_TO_BIND_SOCKET, - "Fallo al asignar el socket" - ) + MSG_EXTRACTING_FILE, + "Extrayendo archivo" + ) MSG_HASH( - MSG_FAILED_TO_CREATE_THE_DIRECTORY, - "Fallo al crear la carpeta" - ) + MSG_FAILED_SAVING_CONFIG_TO, + "Fallo al guardar configuración en" + ) MSG_HASH( - MSG_FAILED_TO_EXTRACT_CONTENT_FROM_COMPRESSED_FILE, - "Fallo al extraer el contenido desde el archivo comprimido" - ) + MSG_FAILED_TO, + "Fallo al" + ) MSG_HASH( - MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT, - "Fallo al obtener el apodo del cliente" - ) + MSG_FAILED_TO_ACCEPT_INCOMING_SPECTATOR, + "Fallo al aceptar al espectador" + ) MSG_HASH( - MSG_FAILED_TO_LOAD, - "Fallo al cargar" - ) + MSG_FAILED_TO_ALLOCATE_MEMORY_FOR_PATCHED_CONTENT, + "Fallo al reservar memoria para el contenido parcheado" + ) MSG_HASH( - MSG_FAILED_TO_LOAD_CONTENT, - "Fallo al cargar contenido" - ) + MSG_FAILED_TO_APPLY_SHADER, + "Fallo al aplicar el shader" + ) MSG_HASH( - MSG_FAILED_TO_LOAD_MOVIE_FILE, - "Fallo al cargar la película" - ) + MSG_FAILED_TO_BIND_SOCKET, + "Fallo al asignar el socket" + ) MSG_HASH( - MSG_FAILED_TO_LOAD_OVERLAY, - "Fallo al cargar la superposición" - ) + MSG_FAILED_TO_CREATE_THE_DIRECTORY, + "Fallo al crear la carpeta" + ) MSG_HASH( - MSG_FAILED_TO_LOAD_STATE, - "Fallo al cargar guardado de" - ) + MSG_FAILED_TO_EXTRACT_CONTENT_FROM_COMPRESSED_FILE, + "Fallo al extraer el contenido desde el archivo comprimido" + ) MSG_HASH( - MSG_FAILED_TO_OPEN_LIBRETRO_CORE, - "Fallo al abrir el núcleo Libretro" - ) + MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT, + "Fallo al obtener el apodo del cliente" + ) MSG_HASH( - MSG_FAILED_TO_PATCH, - "Fallo el parcheado" - ) + MSG_FAILED_TO_LOAD, + "Fallo al cargar" + ) MSG_HASH( - MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT, - "Fallo al recibir el encabezado desde el cliente" - ) + MSG_FAILED_TO_LOAD_CONTENT, + "Fallo al cargar contenido" + ) MSG_HASH( - MSG_FAILED_TO_RECEIVE_NICKNAME, - "Fallo al recibir el apodo" - ) + MSG_FAILED_TO_LOAD_MOVIE_FILE, + "Fallo al cargar la película" + ) MSG_HASH( - MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST, - "Fallo al recibir el apodo del servidor" - ) + MSG_FAILED_TO_LOAD_OVERLAY, + "Fallo al cargar la superposición" + ) MSG_HASH( - MSG_FAILED_TO_RECEIVE_NICKNAME_SIZE_FROM_HOST, - "Fallo al recibir el tamaño del apodo del servidor" - ) + MSG_FAILED_TO_LOAD_STATE, + "Fallo al cargar guardado de" + ) MSG_HASH( - MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST, - "Fallo al recibir datos SaveRAM del servidor" - ) + MSG_FAILED_TO_OPEN_LIBRETRO_CORE, + "Fallo al abrir el núcleo Libretro" + ) MSG_HASH( - MSG_FAILED_TO_REMOVE_DISK_FROM_TRAY, - "Fallo al sacar el disco de la bandeja" - ) + MSG_FAILED_TO_PATCH, + "Fallo el parcheado" + ) MSG_HASH( - MSG_FAILED_TO_REMOVE_TEMPORARY_FILE, - "Fallo al eliminar el archivo temporal" - ) + MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT, + "Fallo al recibir el encabezado desde el cliente" + ) MSG_HASH( - MSG_FAILED_TO_SAVE_SRAM, - "Fallo al guardar SaveRAM" - ) + MSG_FAILED_TO_RECEIVE_NICKNAME, + "Fallo al recibir el apodo" + ) MSG_HASH( - MSG_FAILED_TO_SAVE_STATE_TO, - "Fallo al guardar en" - ) + MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST, + "Fallo al recibir el apodo del servidor" + ) MSG_HASH( - MSG_FAILED_TO_SEND_NICKNAME, - "Fallo al enviar el apodo" - ) + MSG_FAILED_TO_RECEIVE_NICKNAME_SIZE_FROM_HOST, + "Fallo al recibir el tamaño del apodo del servidor" + ) MSG_HASH( - MSG_FAILED_TO_SEND_NICKNAME_SIZE, - "Fallo al enviar el tamaño del apodo" - ) + MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST, + "Fallo al recibir datos SaveRAM del servidor" + ) MSG_HASH( - MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT, - "Fallo al enviar el apodo al cliente" - ) + MSG_FAILED_TO_REMOVE_DISK_FROM_TRAY, + "Fallo al sacar el disco de la bandeja" + ) MSG_HASH( - MSG_FAILED_TO_SEND_NICKNAME_TO_HOST, - "Fallo al enviar el apodo al servidor" - ) + MSG_FAILED_TO_REMOVE_TEMPORARY_FILE, + "Fallo al eliminar el archivo temporal" + ) MSG_HASH( - MSG_FAILED_TO_SEND_SRAM_DATA_TO_CLIENT, - "Fallo al enviar datos SaveRAM al cliente" - ) + MSG_FAILED_TO_SAVE_SRAM, + "Fallo al guardar SaveRAM" + ) MSG_HASH( - MSG_FAILED_TO_START_AUDIO_DRIVER, - "Fallo al iniciar el controlador de audio. Se continuará en silencio" - ) + MSG_FAILED_TO_SAVE_STATE_TO, + "Fallo al guardar en" + ) MSG_HASH( - MSG_FAILED_TO_START_MOVIE_RECORD, - "Fallo al iniciar clip de grabación" - ) + MSG_FAILED_TO_SEND_NICKNAME, + "Fallo al enviar el apodo" + ) MSG_HASH( - MSG_FAILED_TO_START_RECORDING, - "Fallo al iniciar grabación" - ) + MSG_FAILED_TO_SEND_NICKNAME_SIZE, + "Fallo al enviar el tamaño del apodo" + ) MSG_HASH( - MSG_FAILED_TO_TAKE_SCREENSHOT, - "Fallo al capturar pantalla" - ) + MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT, + "Fallo al enviar el apodo al cliente" + ) MSG_HASH( - MSG_FAILED_TO_UNDO_LOAD_STATE, - "Fallo al deshacer carga" - ) + MSG_FAILED_TO_SEND_NICKNAME_TO_HOST, + "Fallo al enviar el apodo al servidor" + ) MSG_HASH( - MSG_FAILED_TO_UNDO_SAVE_STATE, - "Fallo al deshacer guardado" - ) + MSG_FAILED_TO_SEND_SRAM_DATA_TO_CLIENT, + "Fallo al enviar datos SaveRAM al cliente" + ) MSG_HASH( - MSG_FAILED_TO_UNMUTE_AUDIO, - "Fallo al restablecer el audio" - ) + MSG_FAILED_TO_START_AUDIO_DRIVER, + "Fallo al iniciar el controlador de audio. Se continuará en silencio" + ) MSG_HASH( - MSG_FATAL_ERROR_RECEIVED_IN, - "Fatal error recibido en" - ) + MSG_FAILED_TO_START_MOVIE_RECORD, + "Fallo al iniciar clip de grabación" + ) MSG_HASH( - MSG_FILE_NOT_FOUND, - "Archivo no encontrado" - ) + MSG_FAILED_TO_START_RECORDING, + "Fallo al iniciar grabación" + ) MSG_HASH( - MSG_FOUND_AUTO_SAVESTATE_IN, - "Encontrado autoguardado en" - ) + MSG_FAILED_TO_TAKE_SCREENSHOT, + "Fallo al capturar pantalla" + ) MSG_HASH( - MSG_FOUND_DISK_LABEL, - "Encontrada la etiqueta del disco" - ) + MSG_FAILED_TO_UNDO_LOAD_STATE, + "Fallo al deshacer carga" + ) MSG_HASH( - MSG_FOUND_FIRST_DATA_TRACK_ON_FILE, - "Encontrada la primer pista de datos en el archivo" - ) + MSG_FAILED_TO_UNDO_SAVE_STATE, + "Fallo al deshacer guardado" + ) MSG_HASH( - MSG_FOUND_LAST_STATE_SLOT, - "Encontrada la ultima posición de guardado" - ) + MSG_FAILED_TO_UNMUTE_AUDIO, + "Fallo al restablecer el audio" + ) MSG_HASH( - MSG_FOUND_SHADER, - "Encontrado el shader" - ) + MSG_FATAL_ERROR_RECEIVED_IN, + "Error fatal recibido en" + ) MSG_HASH( - MSG_FRAMES, - "Frames" - ) + MSG_FILE_NOT_FOUND, + "Archivo no encontrado" + ) MSG_HASH( - MSG_GAME_SPECIFIC_CORE_OPTIONS_FOUND_AT, - "Opciones especificas de juego encontradas en" - ) + MSG_FOUND_AUTO_SAVESTATE_IN, + "Encontrado autoguardado en" + ) MSG_HASH( - MSG_GOT_INVALID_DISK_INDEX, - "Indice de disco invalido" - ) + MSG_FOUND_DISK_LABEL, + "Encontrada la etiqueta del disco" + ) MSG_HASH( - MSG_GRAB_MOUSE_STATE, - "Capturar estado del ratón" - ) + MSG_FOUND_FIRST_DATA_TRACK_ON_FILE, + "Encontrada la primer pista de datos en el archivo" + ) MSG_HASH( - MSG_GAME_FOCUS_ON, - "Game focus ON" - ) + MSG_FOUND_LAST_STATE_SLOT, + "Encontrada la ultima posición de guardado" + ) MSG_HASH( - MSG_GAME_FOCUS_OFF, - "Game focus OFF" - ) + MSG_FOUND_SHADER, + "Encontrado el shader" + ) MSG_HASH( - MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING, - "El núcleo Libretro esta renderizado por hardware. Debe usar grabaciones post-shaded" - ) + MSG_FRAMES, + "Frames" + ) MSG_HASH( - MSG_INFLATED_CHECKSUM_DID_NOT_MATCH_CRC32, - "El CRC32 inflado no concuerda" - ) + MSG_GAME_SPECIFIC_CORE_OPTIONS_FOUND_AT, + "Opciones especificas de juego encontradas en" + ) MSG_HASH( - MSG_INPUT_CHEAT, - "Introducir truco" - ) + MSG_GOT_INVALID_DISK_INDEX, + "Indice de disco invalido" + ) MSG_HASH( - MSG_INPUT_CHEAT_FILENAME, - "Introducir nombre de archivo de truco" - ) + MSG_GRAB_MOUSE_STATE, + "Capturar estado del ratón" + ) MSG_HASH( - MSG_INPUT_PRESET_FILENAME, - "Introducir nombre de archivo del preset" - ) + MSG_GAME_FOCUS_ON, + "Game focus ON" + ) MSG_HASH( - MSG_INPUT_RENAME_ENTRY, - "Renombrar titulo" - ) + MSG_GAME_FOCUS_OFF, + "Game focus OFF" + ) MSG_HASH( - MSG_INTERFACE, - "Interfaz" - ) + MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING, + "El núcleo Libretro esta renderizado por hardware. Debe usar grabaciones post-shaded" + ) MSG_HASH( - MSG_INTERNAL_STORAGE, - "Almacenamiento interno" - ) + MSG_INFLATED_CHECKSUM_DID_NOT_MATCH_CRC32, + "El CRC32 inflado no concuerda" + ) MSG_HASH( - MSG_REMOVABLE_STORAGE, - "Almacenamiento extraible" - ) + MSG_INPUT_CHEAT, + "Introducir truco" + ) MSG_HASH( - MSG_INVALID_NICKNAME_SIZE, - "Tamaño de apodo invalido" - ) + MSG_INPUT_CHEAT_FILENAME, + "Introducir nombre de archivo de truco" + ) MSG_HASH( - MSG_IN_BYTES, - "en bytes" - ) + MSG_INPUT_PRESET_FILENAME, + "Introducir nombre de archivo del preset" + ) MSG_HASH( - MSG_IN_GIGABYTES, - "en gigabytes" - ) + MSG_INPUT_RENAME_ENTRY, + "Renombrar titulo" + ) MSG_HASH( - MSG_IN_MEGABYTES, - "en megabytes" - ) + MSG_INTERFACE, + "Interfaz" + ) MSG_HASH( - MSG_LIBRETRO_ABI_BREAK, - "está compilado para otra versión de Libretro" - ) + MSG_INTERNAL_STORAGE, + "Almacenamiento interno" + ) MSG_HASH( - MSG_LIBRETRO_FRONTEND, - "Interfaz de usuario para Libretro" - ) + MSG_REMOVABLE_STORAGE, + "Almacenamiento extraible" + ) MSG_HASH( - MSG_LOADED_STATE_FROM_SLOT, - "Cargado guardado de la posición #%d" - ) + MSG_INVALID_NICKNAME_SIZE, + "Tamaño de apodo invalido" + ) MSG_HASH( - MSG_LOADED_STATE_FROM_SLOT_AUTO, - "Cargado guardado de la posición #-1 (auto)" - ) + MSG_IN_BYTES, + "en bytes" + ) MSG_HASH( - MSG_LOADING, - "Cargando" - ) + MSG_IN_GIGABYTES, + "en gigabytes" + ) MSG_HASH( - MSG_FIRMWARE, - "Faltan archivos de firmware" - ) + MSG_IN_MEGABYTES, + "en megabytes" + ) MSG_HASH( - MSG_LOADING_CONTENT_FILE, - "Cargando contenido" - ) + MSG_LIBRETRO_ABI_BREAK, + "está compilado para otra versión de Libretro" + ) MSG_HASH( - MSG_LOADING_HISTORY_FILE, - "Cargando historial" - ) + MSG_LIBRETRO_FRONTEND, + "Interfaz de usuario para Libretro" + ) MSG_HASH( - MSG_LOADING_STATE, - "Cargando estado" - ) + MSG_LOADED_STATE_FROM_SLOT, + "Cargado guardado de la posición #%d" + ) MSG_HASH( - MSG_MEMORY, - "Memoria" - ) + MSG_LOADED_STATE_FROM_SLOT_AUTO, + "Cargado guardado de la posición #-1 (auto)" + ) MSG_HASH( - MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE, - "La película no es un archivo BSV1 válido" - ) + MSG_LOADING, + "Cargando" + ) MSG_HASH( - MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION, - "El formato de la película parece tener una versión diferente de serializer. Probablemente fallará" - ) + MSG_FIRMWARE, + "Faltan archivos de firmware" + ) MSG_HASH( - MSG_MOVIE_PLAYBACK_ENDED, - "Finalizó la reproducción" - ) + MSG_LOADING_CONTENT_FILE, + "Cargando contenido" + ) MSG_HASH( - MSG_MOVIE_RECORD_STOPPED, - "Deteniendo la grabación" - ) + MSG_LOADING_HISTORY_FILE, + "Cargando historial" + ) MSG_HASH( - MSG_NETPLAY_FAILED, - "Fallo al iniciar juego en red" - ) + MSG_LOADING_STATE, + "Cargando estado" + ) MSG_HASH( - MSG_NO_CONTENT_STARTING_DUMMY_CORE, - "No hay contenido, iniciando núcleo vacío" - ) + MSG_MEMORY, + "Memoria" + ) MSG_HASH( - MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET, - "No hay guardado sobrescrito todavía" - ) + MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE, + "La película no es un archivo BSV1 válido" + ) MSG_HASH( - MSG_NO_STATE_HAS_BEEN_LOADED_YET, - "No hay guardado cargado todavía" - ) + MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION, + "El formato de la película parece tener una versión diferente de serializer. Probablemente fallará" + ) MSG_HASH( - MSG_OVERRIDES_ERROR_SAVING, - "Error guardando personalizaciones" - ) + MSG_MOVIE_PLAYBACK_ENDED, + "Finalizó la reproducción" + ) MSG_HASH( - MSG_OVERRIDES_SAVED_SUCCESSFULLY, - "Personalizaciones guardadas exitosamente" - ) + MSG_MOVIE_RECORD_STOPPED, + "Deteniendo la grabación" + ) MSG_HASH( - MSG_PAUSED, - "Pausado" - ) + MSG_NETPLAY_FAILED, + "Fallo al iniciar juego en red" + ) MSG_HASH( - MSG_PROGRAM, - "RetroArch" - ) + MSG_NO_CONTENT_STARTING_DUMMY_CORE, + "No hay contenido, iniciando núcleo vacío" + ) MSG_HASH( - MSG_READING_FIRST_DATA_TRACK, - "Leyendo la primer pista de datos..." - ) + MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET, + "No hay guardado sobrescrito todavía" + ) MSG_HASH( - MSG_RECEIVED, - "recibido" - ) + MSG_NO_STATE_HAS_BEEN_LOADED_YET, + "No hay guardado cargado todavía" + ) MSG_HASH( - MSG_RECORDING_TERMINATED_DUE_TO_RESIZE, - "Grabación terminada debido al cambio de tamaño" - ) + MSG_OVERRIDES_ERROR_SAVING, + "Error guardando personalizaciones" + ) MSG_HASH( - MSG_RECORDING_TO, - "Grabando en" - ) + MSG_OVERRIDES_SAVED_SUCCESSFULLY, + "Personalizaciones guardadas exitosamente" + ) MSG_HASH( - MSG_REDIRECTING_CHEATFILE_TO, - "Redirigiendo archivo de trucos a" - ) + MSG_PAUSED, + "Pausado" + ) MSG_HASH( - MSG_REDIRECTING_SAVEFILE_TO, - "Redirigiendo archivo de guardado a" - ) + MSG_PROGRAM, + "RetroArch" + ) MSG_HASH( - MSG_REDIRECTING_SAVESTATE_TO, - "Redirigiendo archivo de guardado rápido a" - ) + MSG_READING_FIRST_DATA_TRACK, + "Leyendo la primer pista de datos..." + ) MSG_HASH( - MSG_REMAP_FILE_SAVED_SUCCESSFULLY, - "Reasignaciones guardadas exitosamente" - ) + MSG_RECEIVED, + "recibido" + ) MSG_HASH( - MSG_REMAP_FILE_REMOVED_SUCCESSFULLY, - "Reasignaciones eliminadas exitosamente" - ) + MSG_RECORDING_TERMINATED_DUE_TO_RESIZE, + "Grabación terminada debido al cambio de tamaño" + ) MSG_HASH( - MSG_REMOVED_DISK_FROM_TRAY, - "Quitado el disco de la bandeja" - ) + MSG_RECORDING_TO, + "Grabando en" + ) MSG_HASH( - MSG_REMOVING_TEMPORARY_CONTENT_FILE, - "Eliminando el contenido temporal" - ) + MSG_REDIRECTING_CHEATFILE_TO, + "Redirigiendo archivo de trucos a" + ) MSG_HASH( - MSG_RESET, - "Reset" - ) + MSG_REDIRECTING_SAVEFILE_TO, + "Redirigiendo archivo de guardado a" + ) MSG_HASH( - MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT, - "Reiniciando grabación por reinicio del controlador" - ) + MSG_REDIRECTING_SAVESTATE_TO, + "Redirigiendo archivo de guardado rápido a" + ) MSG_HASH( - MSG_RESTORED_OLD_SAVE_STATE, - "Restaurado antiguo guardado rápido" - ) + MSG_REMAP_FILE_SAVED_SUCCESSFULLY, + "Reasignaciones guardadas exitosamente" + ) MSG_HASH( - MSG_RESTORING_DEFAULT_SHADER_PRESET_TO, - "Shaders: restaurado el preset por defecto en" - ) + MSG_REMAP_FILE_REMOVED_SUCCESSFULLY, + "Reasignaciones eliminadas exitosamente" + ) MSG_HASH( - MSG_REVERTING_SAVEFILE_DIRECTORY_TO, - "Revirtiendo la carpeta de guardado a" - ) + MSG_REMOVED_DISK_FROM_TRAY, + "Quitado el disco de la bandeja" + ) MSG_HASH( - MSG_REVERTING_SAVESTATE_DIRECTORY_TO, - "Revirtiendo la carpeta de guardado rápido a" - ) + MSG_REMOVING_TEMPORARY_CONTENT_FILE, + "Eliminando el contenido temporal" + ) MSG_HASH( - MSG_REWINDING, - "Rebobinando" - ) + MSG_RESET, + "Reset" + ) MSG_HASH( - MSG_REWIND_INIT, - "Iniciando buffer de rebobinado de" - ) + MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT, + "Reiniciando grabación por reinicio del controlador" + ) MSG_HASH( - MSG_REWIND_INIT_FAILED, - "Fallo al iniciar el buffer. El rebobinado se desactivará" - ) + MSG_RESTORED_OLD_SAVE_STATE, + "Restaurado antiguo guardado rápido" + ) MSG_HASH( - MSG_REWIND_INIT_FAILED_THREADED_AUDIO, - "La implementación usa audio por hilos. No se puede usar rebobinado" - ) + MSG_RESTORING_DEFAULT_SHADER_PRESET_TO, + "Shaders: restaurado el preset por defecto en" + ) MSG_HASH( - MSG_REWIND_REACHED_END, - "Fin del buffer de rebobinado" - ) + MSG_REVERTING_SAVEFILE_DIRECTORY_TO, + "Revirtiendo la carpeta de guardado a" + ) MSG_HASH( - MSG_SAVED_NEW_CONFIG_TO, - "Guardada nueva configuración en" - ) + MSG_REVERTING_SAVESTATE_DIRECTORY_TO, + "Revirtiendo la carpeta de guardado rápido a" + ) MSG_HASH( - MSG_SAVED_STATE_TO_SLOT, - "Guardado a la posición #%d" - ) + MSG_REWINDING, + "Rebobinando" + ) MSG_HASH( - MSG_SAVED_STATE_TO_SLOT_AUTO, - "Guardado #-1 (auto)" - ) + MSG_REWIND_INIT, + "Iniciando buffer de rebobinado de" + ) MSG_HASH( - MSG_SAVED_SUCCESSFULLY_TO, - "Guardado exitosamente en" - ) + MSG_REWIND_INIT_FAILED, + "Fallo al iniciar el buffer. El rebobinado se desactivará" + ) MSG_HASH( - MSG_SAVING_RAM_TYPE, - "Guardando RAM" - ) + MSG_REWIND_INIT_FAILED_THREADED_AUDIO, + "La implementación usa audio por hilos. No se puede usar rebobinado" + ) MSG_HASH( - MSG_SAVING_STATE, - "Guardando" - ) + MSG_REWIND_REACHED_END, + "Fin del buffer de rebobinado" + ) MSG_HASH( - MSG_SCANNING, - "Escaneando..." - ) + MSG_SAVED_NEW_CONFIG_TO, + "Guardada nueva configuración en" + ) MSG_HASH( - MSG_SCANNING_OF_DIRECTORY_FINISHED, - "Escaneo de carpeta finalizado" - ) + MSG_SAVED_STATE_TO_SLOT, + "Guardado a la posición #%d" + ) MSG_HASH( - MSG_SENDING_COMMAND, - "Enviando comando" - ) + MSG_SAVED_STATE_TO_SLOT_AUTO, + "Guardado #-1 (auto)" + ) MSG_HASH( - MSG_SEVERAL_PATCHES_ARE_EXPLICITLY_DEFINED, - "Varios parches están explicitamente definidos, ignorando todos..." - ) + MSG_SAVED_SUCCESSFULLY_TO, + "Guardado exitosamente en" + ) MSG_HASH( - MSG_SHADER, - "Shader" - ) + MSG_SAVING_RAM_TYPE, + "Guardando RAM" + ) MSG_HASH( - MSG_SHADER_PRESET_SAVED_SUCCESSFULLY, - "Shader preset guardado exitosamente" - ) + MSG_SAVING_STATE, + "Guardando" + ) MSG_HASH( - MSG_SKIPPING_SRAM_LOAD, - "Saltando carga de SaveRAM" - ) + MSG_SCANNING, + "Escaneando..." + ) MSG_HASH( - MSG_SLOW_MOTION, - "Cámara lenta" - ) + MSG_SCANNING_OF_DIRECTORY_FINISHED, + "Escaneo de carpeta finalizado" + ) MSG_HASH( - MSG_FAST_FORWARD, - "Avance rápido" - ) + MSG_SENDING_COMMAND, + "Enviando comando" + ) MSG_HASH( - MSG_SLOW_MOTION_REWIND, - "Rebobinado lento" - ) + MSG_SEVERAL_PATCHES_ARE_EXPLICITLY_DEFINED, + "Varios parches están explicitamente definidos, ignorando todos..." + ) MSG_HASH( - MSG_SRAM_WILL_NOT_BE_SAVED, - "SaveRAM no se guardará" - ) + MSG_SHADER, + "Shader" + ) MSG_HASH( - MSG_STARTING_MOVIE_PLAYBACK, - "Iniciando reproducción de película" - ) + MSG_SHADER_PRESET_SAVED_SUCCESSFULLY, + "Shader preset guardado exitosamente" + ) MSG_HASH( - MSG_STARTING_MOVIE_RECORD_TO, - "Iniciando grabación de película en" - ) + MSG_SKIPPING_SRAM_LOAD, + "Saltando carga de SaveRAM" + ) MSG_HASH( - MSG_STATE_SIZE, - "Tamaño del guardado" - ) + MSG_SLOW_MOTION, + "Cámara lenta" + ) MSG_HASH( - MSG_STATE_SLOT, - "Posición de guardado" - ) + MSG_FAST_FORWARD, + "Avance rápido" + ) MSG_HASH( - MSG_TAKING_SCREENSHOT, - "Capturando pantalla" - ) + MSG_SLOW_MOTION_REWIND, + "Rebobinado lento" + ) MSG_HASH( - MSG_TO, - "en" - ) + MSG_SRAM_WILL_NOT_BE_SAVED, + "SaveRAM no se guardará" + ) MSG_HASH( - MSG_UNDID_LOAD_STATE, - "Deshecha la carga" - ) + MSG_STARTING_MOVIE_PLAYBACK, + "Iniciando reproducción de película" + ) MSG_HASH( - MSG_UNDOING_SAVE_STATE, - "Deshaciendo el guardado" - ) + MSG_STARTING_MOVIE_RECORD_TO, + "Iniciando grabación de película en" + ) MSG_HASH( - MSG_UNKNOWN, - "Desconocido" - ) + MSG_STATE_SIZE, + "Tamaño del guardado" + ) MSG_HASH( - MSG_UNPAUSED, - "Despausado" - ) + MSG_STATE_SLOT, + "Posición de guardado" + ) MSG_HASH( - MSG_UNRECOGNIZED_COMMAND, - "Comando no reconocido" - ) + MSG_TAKING_SCREENSHOT, + "Capturando pantalla" + ) MSG_HASH( - MSG_USING_CORE_NAME_FOR_NEW_CONFIG, - "Usando el nombre del núcleo para la nueva configuración" - ) + MSG_TO, + "en" + ) MSG_HASH( - MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED, - "Usando núcleo vacío. Saltando grabación" - ) + MSG_UNDID_LOAD_STATE, + "Deshecha la carga" + ) MSG_HASH( - MSG_VALUE_CONNECT_DEVICE_FROM_A_VALID_PORT, - "Conecte el dispositivo a un puerto valido" - ) + MSG_UNDOING_SAVE_STATE, + "Deshaciendo el guardado" + ) MSG_HASH( - MSG_VALUE_DISCONNECTING_DEVICE_FROM_PORT, - "Desconectando el dispositivo del puerto" - ) + MSG_UNKNOWN, + "Desconocido" + ) MSG_HASH( - MSG_VALUE_REBOOTING, - "Reiniciando..." - ) + MSG_UNPAUSED, + "Despausado" + ) MSG_HASH( - MSG_VALUE_SHUTTING_DOWN, - "Apagando..." - ) + MSG_UNRECOGNIZED_COMMAND, + "Comando no reconocido" + ) MSG_HASH( - MSG_VERSION_OF_LIBRETRO_API, - "Versión de la API Libretro" - ) + MSG_USING_CORE_NAME_FOR_NEW_CONFIG, + "Usando el nombre del núcleo para la nueva configuración" + ) MSG_HASH( - MSG_VIEWPORT_SIZE_CALCULATION_FAILED, - "Fallo al calcular de la ventana! Se continuará usando datos en bruto. Probablemente no funcionará bien" - ) + MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED, + "Usando núcleo vacío. Saltando grabación" + ) MSG_HASH( - MSG_VIRTUAL_DISK_TRAY, - "Bandeja de discos virtual" - ) + MSG_VALUE_CONNECT_DEVICE_FROM_A_VALID_PORT, + "Conecte el dispositivo a un puerto valido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_LATENCY, - "Latencia de audio deseada en milisegundos. Puede no ser honrada si el controlador no puede proveerla" - ) + MSG_VALUE_DISCONNECTING_DEVICE_FROM_PORT, + "Desconectando el dispositivo del puerto" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_MUTE, - "Silencia el audio" - ) + MSG_VALUE_REBOOTING, + "Reiniciando..." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, - "Ayuda a suavizar imperfecciones de timing al sincronizar audio y video. desactivarlo hace casi imposible una sincronía correcta" - ) + MSG_VALUE_SHUTTING_DOWN, + "Apagando..." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CAMERA_ALLOW, - "Habilitar o deshabilitar el acceso de los núcleos a la cámara" - ) + MSG_VERSION_OF_LIBRETRO_API, + "Versión de la API Libretro" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LOCATION_ALLOW, - "Habilitar o deshabilitar al núcleo a usar los servicios de ubicación" - ) + MSG_VIEWPORT_SIZE_CALCULATION_FAILED, + "Fallo al calcular de la ventana! Se continuará usando datos en bruto. Probablemente no funcionará bien" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_MAX_USERS, - "Máxima cantidad de usuarios a soportar por RetroArch" - ) + MSG_VIRTUAL_DISK_TRAY, + "Bandeja de discos virtual" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_POLL_TYPE_BEHAVIOR, - "Influencia como el sondeo es hecho dentro de RetroArch. 'Temprano' o 'Tarde' pueden resultar en menor latencia, dependiendo de su configuración" - ) + MENU_ENUM_SUBLABEL_AUDIO_LATENCY, + "Latencia de audio deseada en milisegundos. Puede no ser honrada si el controlador no puede proveerla" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_ALL_USERS_CONTROL_MENU, - "Permite a cualquier usuario a controlar el menú. Si se desactiva solo podrá hacerlo el usuario 1" - ) + MENU_ENUM_SUBLABEL_AUDIO_MUTE, + "Silencia el audio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_VOLUME, - "0 dB es normal, donde no se aplica ganancia" - ) + MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, + "Ayuda a suavizar imperfecciones de timing al sincronizar audio y video. desactivarlo hace casi imposible una sincronía correcta" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_WASAPI_EXCLUSIVE_MODE, - "Permite al controlador WASAPI tomar control exclusivo del disp. de audio. Al deshabilitarlo se usará el modo compartido" - ) + MENU_ENUM_SUBLABEL_CAMERA_ALLOW, + "Habilitar o deshabilitar el acceso de los núcleos a la cámara" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_WASAPI_FLOAT_FORMAT, - "Usar formato de punto flotante en WASAPI, Su dispositivo debe soportarlo" - ) + MENU_ENUM_SUBLABEL_LOCATION_ALLOW, + "Habilitar o deshabilitar al núcleo a usar los servicios de ubicación" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_WASAPI_SH_BUFFER_LENGTH, - "El tamaño del buffer intermedio (en frames) al usar WASAPI en modo compartido" - ) + MENU_ENUM_SUBLABEL_INPUT_MAX_USERS, + "Máxima cantidad de usuarios a soportar por RetroArch" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_SYNC, - "Sincronizar audio. Recomendado" - ) + MENU_ENUM_SUBLABEL_INPUT_POLL_TYPE_BEHAVIOR, + "Influencia como el sondeo es hecho dentro de RetroArch. 'Temprano' o 'Tarde' pueden resultar en menor latencia, dependiendo de su configuración" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "Cuanto debe mover la palanca para ser detectada. Evita movimientos indeseados en los mandos que no vuelven perfectamente al centro" - ) + MENU_ENUM_SUBLABEL_INPUT_ALL_USERS_CONTROL_MENU, + "Permite a cualquier usuario a controlar el menú. Si se desactiva solo podrá hacerlo el usuario 1" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, - "Cantidad de segundos a esperar hasta la siguiente asignación" - ) + MENU_ENUM_SUBLABEL_AUDIO_VOLUME, + "0 dB es normal, donde no se aplica ganancia" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_BIND_HOLD, - "Cantidad de segundos a mantener una entrada para asignarla" - ) + MENU_ENUM_SUBLABEL_AUDIO_WASAPI_EXCLUSIVE_MODE, + "Permite al controlador WASAPI tomar control exclusivo del disp. de audio. Al deshabilitarlo se usará el modo compartido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_TURBO_PERIOD, - "Periodo entre pulsación de los botones turbo (en frames)" - ) + MENU_ENUM_SUBLABEL_AUDIO_WASAPI_FLOAT_FORMAT, + "Usar formato de punto flotante en WASAPI, Su dispositivo debe soportarlo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_DUTY_CYCLE, - "Cuanto debe durar la pulsación de los botones turbo (en frames)" - ) + MENU_ENUM_SUBLABEL_AUDIO_WASAPI_SH_BUFFER_LENGTH, + "El tamaño del buffer intermedio (en frames) al usar WASAPI en modo compartido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_VSYNC, - "Sincroniza la salida de la placa de video al refresco de la pantalla. Recomendado" - ) + MENU_ENUM_SUBLABEL_AUDIO_SYNC, + "Sincronizar audio. Recomendado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_ALLOW_ROTATE, - "Permitir a los núcleos rotar la pantalla. Desactivarlo es útil cuando se puede girar el dispositivo manualmente" - ) + MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, + "Cuanto debe mover la palanca para ser detectada. Evita movimientos indeseados en los mandos que no vuelven perfectamente al centro" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DUMMY_ON_CORE_SHUTDOWN, - "Activarlo previene que algunos núcleos con función de apagado cierren RetroArch, en lugar de eso se cargará un núcleo vacío" - ) + MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, + "Cantidad de segundos a esperar hasta la siguiente asignación" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHECK_FOR_MISSING_FIRMWARE, - "Verificar que el firmware necesario este disponible antes de cargar el contenido" - ) + MENU_ENUM_SUBLABEL_INPUT_BIND_HOLD, + "Cantidad de segundos a mantener una entrada para asignarla" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE, - "Tasa de refresco vertical de su pantalla. Usada para calcular la velocidad de audio. Nota: Se ignorará si 'Video por hilos' esta activado" - ) + MENU_ENUM_SUBLABEL_INPUT_TURBO_PERIOD, + "Periodo entre pulsación de los botones turbo (en frames)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_ENABLE, - "Activar salida de audio" - ) + MENU_ENUM_SUBLABEL_INPUT_DUTY_CYCLE, + "Cuanto debe durar la pulsación de los botones turbo (en frames)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_MAX_TIMING_SKEW, - "El máximo cambio en la velocidad de audio. Incrementarlo permite grandes cambios de timing a costa del tono de audio (Ej. Núcleos PAL en pantallas NTSC)" - ) + MENU_ENUM_SUBLABEL_VIDEO_VSYNC, + "Sincroniza la salida de la placa de video al refresco de la pantalla. Recomendado" + ) MSG_HASH( - MSG_FAILED, - "Fallo" - ) + MENU_ENUM_SUBLABEL_VIDEO_ALLOW_ROTATE, + "Permitir a los núcleos rotar la pantalla. Desactivarlo es útil cuando se puede girar el dispositivo manualmente" + ) MSG_HASH( - MSG_SUCCEEDED, - "Éxito" - ) + MENU_ENUM_SUBLABEL_DUMMY_ON_CORE_SHUTDOWN, + "Activarlo previene que algunos núcleos con función de apagado cierren RetroArch, en lugar de eso se cargará un núcleo vacío" + ) MSG_HASH( - MSG_DEVICE_NOT_CONFIGURED, - "no configurado" - ) + MENU_ENUM_SUBLABEL_CHECK_FOR_MISSING_FIRMWARE, + "Verificar que el firmware necesario este disponible antes de cargar el contenido" + ) MSG_HASH( - MSG_DEVICE_NOT_CONFIGURED_FALLBACK, - "no configurado, usando respaldo" - ) + MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE, + "Tasa de refresco vertical de su pantalla. Usada para calcular la velocidad de audio. Nota: Se ignorará si 'Video por hilos' esta activado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, - "Base de datos: Lista cursor" - ) + MENU_ENUM_SUBLABEL_AUDIO_ENABLE, + "Activar salida de audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DEVELOPER, - "Base de datos - Filtro : Desarrollador" - ) + MENU_ENUM_SUBLABEL_AUDIO_MAX_TIMING_SKEW, + "El máximo cambio en la velocidad de audio. Incrementarlo permite grandes cambios de timing a costa del tono de audio (Ej. Núcleos PAL en pantallas NTSC)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PUBLISHER, - "Base de datos - Filtro : Distribuidora" - ) + MSG_FAILED, + "Fallo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DISABLED, - "Desactivado" - ) + MSG_SUCCEEDED, + "Éxito" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ENABLED, - "Activado" - ) + MSG_DEVICE_NOT_CONFIGURED, + "no configurado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_PATH, - "Ruta del historial" - ) + MSG_DEVICE_NOT_CONFIGURED_FALLBACK, + "no configurado, usando respaldo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ORIGIN, - "Base de datos - Filtro : Origen" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, + "Base de datos: Lista cursor" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_FRANCHISE, - "Base de datos - Filtro : Franquicia" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DEVELOPER, + "Base de datos - Filtro : Desarrollador" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ESRB_RATING, - "Base de datos - Filtro : ESRB Rating" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PUBLISHER, + "Base de datos - Filtro : Distribuidora" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ELSPA_RATING, - "Base de datos - Filtro : ELSPA Rating" - ) + MENU_ENUM_LABEL_VALUE_DISABLED, + "Desactivado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PEGI_RATING, - "Base de datos - Filtro : PEGI Rating" - ) + MENU_ENUM_LABEL_VALUE_ENABLED, + "Activado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_CERO_RATING, - "Base de datos - Filtro : CERO Rating" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_PATH, + "Ruta del historial" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_BBFC_RATING, - "Base de datos - Filtro : BBFC Rating" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ORIGIN, + "Base de datos - Filtro : Origen" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_MAX_USERS, - "Base de datos - Filtro : Máximo de usuarios" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_FRANCHISE, + "Base de datos - Filtro : Franquicia" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_MONTH, - "Base de datos - Filtro : Lanzamiento por mes" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ESRB_RATING, + "Base de datos - Filtro : ESRB Rating" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_YEAR, - "Base de datos - Filtro : Lanzamiento por año" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ELSPA_RATING, + "Base de datos - Filtro : ELSPA Rating" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_ISSUE, - "Base de datos - Filtro : número de la revista Edge" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PEGI_RATING, + "Base de datos - Filtro : PEGI Rating" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_RATING, - "Base de datos - Filtro : Rating de la revista Edge" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_CERO_RATING, + "Base de datos - Filtro : CERO Rating" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DATABASE_INFO, - "Info de base de datos" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_BBFC_RATING, + "Base de datos - Filtro : BBFC Rating" + ) MSG_HASH( - MSG_WIFI_SCAN_COMPLETE, - "Escaneo Wi-Fi completo" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_MAX_USERS, + "Base de datos - Filtro : Máximo de usuarios" + ) MSG_HASH( - MSG_SCANNING_WIRELESS_NETWORKS, - "Escaneando redes inalambricas..." - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_MONTH, + "Base de datos - Filtro : Lanzamiento por mes" + ) MSG_HASH( - MSG_NETPLAY_LAN_SCAN_COMPLETE, - "Juego en red escaneo completo" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_YEAR, + "Base de datos - Filtro : Lanzamiento por año" + ) MSG_HASH( - MSG_NETPLAY_LAN_SCANNING, - "Escaneando en busca de anfitriones de juego en red..." - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_ISSUE, + "Base de datos - Filtro : número de la revista Edge" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, - "Pausar gameplay cuando RetroArch no es la ventana activa" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_RATING, + "Base de datos - Filtro : Rating de la revista Edge" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, - "Activar o desactivar composición (Solo Windows)" - ) + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DATABASE_INFO, + "Info de base de datos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, - "Activar o desactivar lista de elementos recientes para juegos, imágenes, música, y videos" - ) + MSG_WIFI_SCAN_COMPLETE, + "Escaneo Wi-Fi completo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, - "Limitar el número de entradas en la lista de elementos recientes" - ) + MSG_SCANNING_WIRELESS_NETWORKS, + "Escaneando redes inalambricas..." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_INPUT_UNIFIED_MENU_CONTROLS, - "Controles de menú unificados" - ) + MSG_NETPLAY_LAN_SCAN_COMPLETE, + "Juego en red escaneo completo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS, - "Usar los mismos controles para el menú y el juego. Aplica al teclado" - ) + MSG_NETPLAY_LAN_SCANNING, + "Escaneando en busca de anfitriones de juego en red..." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE, - "Mostrar mensajes en pantalla" - ) + MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, + "Pausar gameplay cuando RetroArch no es la ventana activa" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETWORK_USER_REMOTE_ENABLE, - "Usuario %d Remoto Activado" - ) + MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, + "Activar o desactivar composición (Solo Windows)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, - "Mostrar nivel de batería" - ) + MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, + "Activar o desactivar lista de elementos recientes para juegos, imágenes, música, y videos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SELECT_FILE, - "Seleccionar archivo" - ) + MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, + "Limitar el número de entradas en la lista de elementos recientes" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Seleccionar de la colección" - ) + MENU_ENUM_LABEL_VALUE_INPUT_UNIFIED_MENU_CONTROLS, + "Controles de menú unificados" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_FILTER, - "Filtro" - ) + MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS, + "Usar los mismos controles para el menú y el juego. Aplica al teclado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SCALE, - "Escalar" - ) + MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE, + "Mostrar mensajes en pantalla" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED, - "El juego en red comenzará cuando se cargue el contenido" - ) + MENU_ENUM_LABEL_VALUE_NETWORK_USER_REMOTE_ENABLE, + "Usuario %d Remoto Activado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_LOAD_CONTENT_MANUALLY, - "No se encontró el núcleo o contenido, cargue manualmente" - ) + MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, + "Mostrar nivel de batería" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_URL_LIST, - "Ver URLs" - ) + MENU_ENUM_LABEL_VALUE_SELECT_FILE, + "Seleccionar archivo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_URL, - "Ver URL" - ) + MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, + "Seleccionar de la colección" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_START, - "Iniciar" - ) + MENU_ENUM_LABEL_VALUE_FILTER, + "Filtro" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, - "Bokeh" - ) + MENU_ENUM_LABEL_VALUE_SCALE, + "Escalar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOWFLAKE, - "Snowflake" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED, + "El juego en red comenzará cuando se cargue el contenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_ROOMS, - "Actualizar lista de salas" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_LOAD_CONTENT_MANUALLY, + "No se encontró el núcleo o contenido, cargue manualmente" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME, - "Apodo: %s" - ) + MENU_ENUM_LABEL_VALUE_BROWSE_URL_LIST, + "Ver URLs" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME_LAN, - "Apodo (lan): %s" - ) + MENU_ENUM_LABEL_VALUE_BROWSE_URL, + "Ver URL" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND, - "Contenido compatible encontrado" - ) + MENU_ENUM_LABEL_VALUE_BROWSE_START, + "Iniciar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_CROP_OVERSCAN, - "Corta unos pocos pixeles de los bordes de la imagen que normalmente los desarrolladores dejan en blanco o con basura" - ) + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, + "Bokeh" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SMOOTH, - "Aplicar un pequeño desenfoque a la imagen para borrar los bordes de los pixeles. Esta opción tiene muy poco impacto en el rendimiento" - ) + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOWFLAKE, + "Snowflake" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FILTER, - "Aplicar un filtro de video con la CPU. Nota: Puede tener un alto coste de rendimiento. Algunos filtros solo funcionan con núcleos que usan 16 o 32bit de color" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_ROOMS, + "Actualizar lista de salas" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEEVOS_USERNAME, - "Nombre de usuario de su cuenta de RetroAchievements" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME, + "Apodo: %s" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEEVOS_PASSWORD, - "Contraseña de su cuenta de RetroAchievements" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME_LAN, + "Apodo (lan): %s" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_NICKNAME, - "Ingrese su apodo. Esto sera usado para las sesiones de juego en red" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND, + "Contenido compatible encontrado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_POST_FILTER_RECORD, - "Capturar la imagen con los filtros (no shaders)" - ) + MENU_ENUM_SUBLABEL_VIDEO_CROP_OVERSCAN, + "Corta unos pocos pixeles de los bordes de la imagen que normalmente los desarrolladores dejan en blanco o con basura" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CORE_LIST, - "Seleccionar que núcleo usar" - ) + MENU_ENUM_SUBLABEL_VIDEO_SMOOTH, + "Aplicar un pequeño desenfoque a la imagen para borrar los bordes de los pixeles. Esta opción tiene muy poco impacto en el rendimiento" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LOAD_CONTENT_LIST, - "Seleccionar que contenido iniciar" - ) + MENU_ENUM_SUBLABEL_VIDEO_FILTER, + "Aplicar un filtro de video con la CPU. Nota: Puede tener un alto coste de rendimiento. Algunos filtros solo funcionan con núcleos que usan 16 o 32bit de color" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETWORK_INFORMATION, - "Mostrar interfaces de red e IPs asociadas" - ) + MENU_ENUM_SUBLABEL_CHEEVOS_USERNAME, + "Nombre de usuario de su cuenta de RetroAchievements" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SYSTEM_INFORMATION, - "Mostrar información especifica del dispositivo" - ) + MENU_ENUM_SUBLABEL_CHEEVOS_PASSWORD, + "Contraseña de su cuenta de RetroAchievements" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUIT_RETROARCH, - "Salir del programa" - ) + MENU_ENUM_SUBLABEL_NETPLAY_NICKNAME, + "Ingrese su apodo. Esto sera usado para las sesiones de juego en red" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_WINDOW_WIDTH, - "Establece el ancho de la ventana. Al dejarlo en 0 hará que intente ser lo mas grande posible" - ) + MENU_ENUM_SUBLABEL_VIDEO_POST_FILTER_RECORD, + "Capturar la imagen con los filtros (no shaders)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_WINDOW_HEIGHT, - "Establece el alto de la ventana. Al dejarlo en 0 hará que intente ser lo mas grande posible" - ) + MENU_ENUM_SUBLABEL_CORE_LIST, + "Seleccionar que núcleo usar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_X, - "Establece el ancho en pantalla completa. Al dejarlo en 0 se usará la resolución del escritorio" - ) + MENU_ENUM_SUBLABEL_LOAD_CONTENT_LIST, + "Seleccionar que contenido iniciar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_Y, - "Establece el alto en pantalla completa. Al dejarlo en 0 se usará la resolución del escritorio" - ) + MENU_ENUM_SUBLABEL_NETWORK_INFORMATION, + "Mostrar interfaces de red e IPs asociadas" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_X, - "Especificar posición sobre eje X para el texto en pantalla" - ) + MENU_ENUM_SUBLABEL_SYSTEM_INFORMATION, + "Mostrar información especifica del dispositivo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_Y, - "Especificar posición sobre eje Y para el texto en pantalla" - ) + MENU_ENUM_SUBLABEL_QUIT_RETROARCH, + "Salir del programa" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, - "Especificar el tamaño de letra en puntos" - ) + MENU_ENUM_SUBLABEL_VIDEO_WINDOW_WIDTH, + "Establece el ancho de la ventana. Al dejarlo en 0 hará que intente ser lo mas grande posible" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, - "Ocultar la superposición en el menú, mostrarla al salir del menú" - ) + MENU_ENUM_SUBLABEL_VIDEO_WINDOW_HEIGHT, + "Establece el alto de la ventana. Al dejarlo en 0 hará que intente ser lo mas grande posible" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, - "Mostrar pulsaciones en los controles en pantalla" - ) + MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_X, + "Establece el ancho en pantalla completa. Al dejarlo en 0 se usará la resolución del escritorio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, - "Seleccionar el puerto en que los controles en pantalla escucharán las pulsaciones" - ) + MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_Y, + "Establece el alto en pantalla completa. Al dejarlo en 0 se usará la resolución del escritorio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, - "El contenido escaneado aparecerá aquí" - ) + MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_X, + "Especificar posición sobre eje X para el texto en pantalla" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, - "Escalar en múltiplos enteros. El tamaño base dependerá del sistema usado. Si 'Forzar aspecto' no esta activado, X e Y serán escalados individualmente" - ) + MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_Y, + "Especificar posición sobre eje Y para el texto en pantalla" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT, - "Capturas de pantalla de GPU con shaders si está disponible" - ) + MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, + "Especificar el tamaño de letra en puntos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_ROTATION, - "Fuerza una cierta rotación de la pantalla. La rotación se añade a la impuesta por el núcleo" - ) + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, + "Ocultar la superposición en el menú, mostrarla al salir del menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FORCE_SRGB_DISABLE, - "Desactiva forzadamente el soporte de FBO sRGB. Para algunos controladores Intel OpenGL en Windows con problemas" - ) + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, + "Mostrar pulsaciones en los controles en pantalla" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN, - "Puede ser anulado por un argumento en la linea de comandos" - ) + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, + "Seleccionar el puerto en que los controles en pantalla escucharán las pulsaciones" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_WINDOWED_FULLSCREEN, - "Preferir uso de ventana sin bordes a pantalla completa" - ) + MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + "El contenido escaneado aparecerá aquí" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_GPU_RECORD, - "Graba la salida de GPU con shaders si está disponible" - ) + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, + "Escalar en múltiplos enteros. El tamaño base dependerá del sistema usado. Si 'Forzar aspecto' no esta activado, X e Y serán escalados individualmente" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX, - "Al hacer un guardado rápido, el indice es automáticamente incrementado antes de guardar. Al cargar contenido, el indice será el mayor existente" - ) + MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT, + "Capturas de pantalla de GPU con shaders si está disponible" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE, - "Bloquear el guardado de SaveRAM de ser sobrescrito al cargar guardados rápidos. Puede causar problemas" - ) + MENU_ENUM_SUBLABEL_VIDEO_ROTATION, + "Fuerza una cierta rotación de la pantalla. La rotación se añade a la impuesta por el núcleo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO, - "La máxima velocidad del avance rápido (Ej: 5.0x para un juego de 60fps = 300 fps). Si es 0 no habrá limite" - ) + MENU_ENUM_SUBLABEL_VIDEO_FORCE_SRGB_DISABLE, + "Desactiva forzadamente el soporte de FBO sRGB. Para algunos controladores Intel OpenGL en Windows con problemas" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, - "Al usar cámara lenta, el contenido se ralentizará el factor especificado" - ) + MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN, + "Puede ser anulado por un argumento en la linea de comandos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RUN_AHEAD_ENABLED, - "Ejecutar la logica del núcleo uno o mas frames por adelentado, y decidir cuando adelantar basados en las pulsaciones del control, esto puede reducir la latencia de entrada percibida, eliminando el lag interno de la consola o juego emulado" - ) + MENU_ENUM_SUBLABEL_VIDEO_WINDOWED_FULLSCREEN, + "Preferir uso de ventana sin bordes a pantalla completa" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RUN_AHEAD_FRAMES, - "El número de frames que el núcleo irá adelantado, si excedes el número de frames de lag internos del juego, puede causar tirones (jitter)" - ) + MENU_ENUM_SUBLABEL_VIDEO_GPU_RECORD, + "Graba la salida de GPU con shaders si está disponible" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RUN_AHEAD_SECONDARY_INSTANCE, - "Usar una segunda instancia del núcleo para adelantarse (RunAhead). Previene problemas de audio causados por las cargas de estado" - ) + MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX, + "Al hacer un guardado rápido, el indice es automáticamente incrementado antes de guardar. Al cargar contenido, el indice será el mayor existente" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RUN_AHEAD_HIDE_WARNINGS, - "Oculta el mensaje de advertencia que aparece al usar RunAhead si el núcleo no soporta guardar el estado (savestates)" - ) + MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE, + "Bloquear el guardado de SaveRAM de ser sobrescrito al cargar guardados rápidos. Puede causar problemas" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_REWIND_ENABLE, - "Habilita el rebobinado. Tendrá un impacto en el rendimiento del juego" - ) + MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO, + "La máxima velocidad del avance rápido (Ej: 5.0x para un juego de 60fps = 300 fps). Si es 0 no habrá limite" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_REWIND_GRANULARITY, - "Rebobinar un determinado número de frames a la vez, para aumentar la velocidad del rebobinado" - ) + MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, + "Al usar cámara lenta, el contenido se ralentizará el factor especificado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE, - "La cantidad de memoria (en MB) a reservar para el búfer de rebobinado. Aumentar esto aumentará el largo del historial de rebobinado" - ) + MENU_ENUM_SUBLABEL_RUN_AHEAD_ENABLED, + "Ejecutar la logica del núcleo uno o mas frames por adelentado, y decidir cuando adelantar basados en las pulsaciones del control, esto puede reducir la latencia de entrada percibida, eliminando el lag interno de la consola o juego emulado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE_STEP, - "Cada vez que aumentes o disminuyas el tamaño del búfer por medio de está interfaz, cambiará esta cantidad" - ) + MENU_ENUM_SUBLABEL_RUN_AHEAD_FRAMES, + "El número de frames que el núcleo irá adelantado, si excedes el número de frames de lag internos del juego, puede causar tirones (jitter)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_IDX, - "Posición en el indice de la lista" - ) + MENU_ENUM_SUBLABEL_RUN_AHEAD_SECONDARY_INSTANCE, + "Usar una segunda instancia del núcleo para adelantarse (RunAhead). Previene problemas de audio causados por las cargas de estado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_ADDRESS_BIT_POSITION, - "Bitmask de la dirección cuando el tamaño de la búsqueda de memoria es menor a 8 bits" - ) + MENU_ENUM_SUBLABEL_RUN_AHEAD_HIDE_WARNINGS, + "Oculta el mensaje de advertencia que aparece al usar RunAhead si el núcleo no soporta guardar el estado (savestates)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_MATCH_IDX, - "Seleccionar la coincidencia a ver" - ) + MENU_ENUM_SUBLABEL_REWIND_ENABLE, + "Habilita el rebobinado. Tendrá un impacto en el rendimiento del juego" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_START_OR_CONT, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_APPLY_AFTER_TOGGLE, + "Aplicar truco inmediatamente después de cambiar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_START_OR_RESTART, - "Izquierda/Derecha para cambiar el bit-size" - ) + MENU_ENUM_SUBLABEL_CHEAT_APPLY_AFTER_LOAD, + "Auto-aplicar los trucos después que el juego cargue" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EXACT, - "Izquierda/Derecha para cambiar el valor" - ) + MENU_ENUM_SUBLABEL_REWIND_GRANULARITY, + "Rebobinar un determinado número de frames a la vez, para aumentar la velocidad del rebobinado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LT, - "" - ) + MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE, + "La cantidad de memoria (en MB) a reservar para el búfer de rebobinado. Aumentar esto aumentará el largo del historial de rebobinado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GT, - "" - ) + MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE_STEP, + "Cada vez que aumentes o disminuyas el tamaño del búfer por medio de está interfaz, cambiará esta cantidad" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LTE, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_IDX, + "Posición en el indice de la lista" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GTE, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_ADDRESS_BIT_POSITION, + "Bitmask de la dirección cuando el tamaño de la búsqueda de memoria es menor a 8 bits" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQ, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_MATCH_IDX, + "Seleccionar la coincidencia a ver" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_NEQ, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_START_OR_CONT, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQPLUS, - "Izquierda/Derecha para cambiar el valor" - ) + MENU_ENUM_SUBLABEL_CHEAT_START_OR_RESTART, + "Izquierda/Derecha para cambiar el bit-size" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQMINUS, - "Izquierda/Derecha para cambiar el valor" - ) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EXACT, + "Izquierda/Derecha para cambiar el valor" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_ADD_MATCHES, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LT, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_VIEW_MATCHES, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GT, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_CREATE_OPTION, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LTE, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_DELETE_OPTION, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GTE, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_TOP, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQ, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_BOTTOM, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_NEQ, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_DELETE_ALL, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQPLUS, + "Izquierda/Derecha para cambiar el valor" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_BIG_ENDIAN, - "Big endian : 258 = 0x0102,\nLittle endian : 258 = 0x0201" - ) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQMINUS, + "Izquierda/Derecha para cambiar el valor" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL, - "Nivel de registro para núcleos, si el núcleo emite valores por debajo, serán ignorados" - ) + MENU_ENUM_SUBLABEL_CHEAT_ADD_MATCHES, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_PERFCNT_ENABLE, - "Activa los contadores de rendimiento para RetroArch y núcleos" - ) + MENU_ENUM_SUBLABEL_CHEAT_VIEW_MATCHES, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_SAVE, - "Hacer un guardado rápido al salir de RetroArch. Se cargará automáticamente si 'Cargar guardado rápido automáticamente' esta activado" - ) + MENU_ENUM_SUBLABEL_CHEAT_CREATE_OPTION, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_LOAD, - "Carga el guardado rápido automático al inicio" - ) + MENU_ENUM_SUBLABEL_CHEAT_DELETE_OPTION, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_THUMBNAIL_ENABLE, - "Mostrar miniaturas de los guardados rápidos en el menú" - ) + MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_TOP, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL, - "Intervalo en segundos para auto-guardar la memoria no volátil SaveRAM, por defecto desactivado (en 0)" - ) + MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_BOTTOM, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE, - "Al activarlo anula los controles por defecto y usa los controles personalizados para el núcleo actual" - ) + MENU_ENUM_SUBLABEL_CHEAT_DELETE_ALL, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AUTODETECT_ENABLE, - "Activar la auto-detección de controles, se intentará configurarlos estilo 'Plug and Play'" - ) + MENU_ENUM_SUBLABEL_CHEAT_RELOAD_CHEATS, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_INPUT_SWAP_OK_CANCEL, - "Intercambiar los botones de OK y Cancelar. Desactivado es el estilo Japones, Activado el estilo occidental" - ) + MENU_ENUM_SUBLABEL_CHEAT_BIG_ENDIAN, + "Big endian : 258 = 0x0102,\nLittle endian : 258 = 0x0201" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_PAUSE_LIBRETRO, - "Al desactivarlo el contenido continuará ejecutándose cuando estés en el menú" - ) + MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL, + "Nivel de registro para núcleos, si el núcleo emite valores por debajo, serán ignorados" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_DRIVER, - "Controlador de video a usar" - ) + MENU_ENUM_SUBLABEL_PERFCNT_ENABLE, + "Activa los contadores de rendimiento para RetroArch y núcleos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_DRIVER, - "Controlador de audio a usar" - ) + MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_SAVE, + "Hacer un guardado rápido al salir de RetroArch. Se cargará automáticamente si 'Cargar guardado rápido automáticamente' esta activado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_DRIVER, - "Controlador de entrada a usar. El controlador de video puede forzar uno distinto" - ) + MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_LOAD, + "Carga el guardado rápido automático al inicio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_JOYPAD_DRIVER, - "Controlador de mando a usar" - ) + MENU_ENUM_SUBLABEL_SAVESTATE_THUMBNAIL_ENABLE, + "Mostrar miniaturas de los guardados rápidos en el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_DRIVER, - "Audio resampler a usar" - ) + MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL, + "Intervalo en segundos para auto-guardar la memoria no volátil SaveRAM, por defecto desactivado (en 0)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CAMERA_DRIVER, - "Controlador de Cámara a usar" - ) + MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE, + "Al activarlo anula los controles por defecto y usa los controles personalizados para el núcleo actual" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LOCATION_DRIVER, - "Controlador de ubicación a usar" - ) + MENU_ENUM_SUBLABEL_INPUT_AUTODETECT_ENABLE, + "Activar la auto-detección de controles, se intentará configurarlos estilo 'Plug and Play'" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_DRIVER, - "Controlador de menú a usar" - ) + MENU_ENUM_SUBLABEL_MENU_INPUT_SWAP_OK_CANCEL, + "Intercambiar los botones de OK y Cancelar. Desactivado es el estilo Japones, Activado el estilo occidental" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RECORD_DRIVER, - "Controlador de grabación a usar" - ) + MENU_ENUM_SUBLABEL_PAUSE_LIBRETRO, + "Al desactivarlo el contenido continuará ejecutándose cuando estés en el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MIDI_DRIVER, - "Controlador MIDI a usar" - ) + MENU_ENUM_SUBLABEL_VIDEO_DRIVER, + "Controlador de video a usar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_WIFI_DRIVER, - "Controlador WiFi a usar" - ) + MENU_ENUM_SUBLABEL_AUDIO_DRIVER, + "Controlador de audio a usar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, - "Solo mostrar archivos con extensiones conocidas" - ) + MENU_ENUM_SUBLABEL_INPUT_DRIVER, + "Controlador de entrada a usar. El controlador de video puede forzar uno distinto" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_WALLPAPER, - "Seleccionar una imagen para usar de fondo en el menú" - ) + MENU_ENUM_SUBLABEL_JOYPAD_DRIVER, + "Controlador de mando a usar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPER, - "Cargar una imagen de fondo según el contenido" - ) + MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_DRIVER, + "Audio resampler a usar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_DEVICE, - "Dispositivo a usar por el controlador de audio. Depende del controlador" - ) + MENU_ENUM_SUBLABEL_CAMERA_DRIVER, + "Controlador de Cámara a usar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_DSP_PLUGIN, - "DSP que procesa el audio antes de ser enviado al controlador" - ) + MENU_ENUM_SUBLABEL_LOCATION_DRIVER, + "Controlador de ubicación a usar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_OUTPUT_RATE, - "Velocidad de muestreo de la salida de audio" - ) + MENU_ENUM_SUBLABEL_MENU_DRIVER, + "Controlador de menú a usar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_OVERLAY_OPACITY, - "Controla la transparencia de la superposición" - ) + MENU_ENUM_SUBLABEL_RECORD_DRIVER, + "Controlador de grabación a usar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_OVERLAY_SCALE, - "Controla el tamaño de la superposición" - ) + MENU_ENUM_SUBLABEL_MIDI_DRIVER, + "Controlador MIDI a usar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_OVERLAY_ENABLE, - "Activar superposición" - ) + MENU_ENUM_SUBLABEL_WIFI_DRIVER, + "Controlador WiFi a usar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_OVERLAY_PRESET, - "Seleciona una superposición desde el explorador de archivos" - ) + MENU_ENUM_SUBLABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, + "Solo mostrar archivos con extensiones conocidas" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_IP_ADDRESS, - "La dirección IP del servidor a conectar" - ) + MENU_ENUM_SUBLABEL_MENU_WALLPAPER, + "Seleccionar una imagen para usar de fondo en el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_TCP_UDP_PORT, - "El puerto del servidor a conectar. Puede ser TCP o UDP" - ) + MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPER, + "Cargar una imagen de fondo según el contenido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_PASSWORD, - "Contraseña a pedir a los clientes que se conecten al estar en modo servidor" - ) + MENU_ENUM_SUBLABEL_AUDIO_DEVICE, + "Dispositivo a usar por el controlador de audio. Depende del controlador" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_PUBLIC_ANNOUNCE, - "Permite ser encontrado fácilmente, sino los clientes deberán conectarse manualmente" - ) + MENU_ENUM_SUBLABEL_AUDIO_DSP_PLUGIN, + "DSP que procesa el audio antes de ser enviado al controlador" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_SPECTATE_PASSWORD, - "Contraseña a pedir a los espectadores que se conecten al estar en modo servidor" - ) + MENU_ENUM_SUBLABEL_AUDIO_OUTPUT_RATE, + "Velocidad de muestreo de la salida de audio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_START_AS_SPECTATOR, - "Si se debe iniciar juego en red en modo espectador" - ) + MENU_ENUM_SUBLABEL_OVERLAY_OPACITY, + "Controla la transparencia de la superposición" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_ALLOW_SLAVES, - "Si se permiten conexiones en modo esclavo. El modo esclavo usa muy poco poder de procesamiento, pero tendrá un impacto significativo en la latencia" - ) + MENU_ENUM_SUBLABEL_OVERLAY_SCALE, + "Controla el tamaño de la superposición" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_REQUIRE_SLAVES, - "Solo usar modo esclavo. No recomendado excepto en redes muy rápidas con máquinas muy débiles" - ) + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_ENABLE, + "Activar superposición" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_STATELESS_MODE, - "Necesita una red muy rápida, pero se eliminarán los tirones al no realizar rebobinados de sincronización" - ) + MENU_ENUM_SUBLABEL_OVERLAY_PRESET, + "Seleciona una superposición desde el explorador de archivos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_CHECK_FRAMES, - "Frecuencia en frames con la que se verificará si el servidor y el cliente están en sincronía" - ) + MENU_ENUM_SUBLABEL_NETPLAY_IP_ADDRESS, + "La dirección IP del servidor a conectar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_NAT_TRAVERSAL, - "Cuando se es servidor, intentar escuchar conexiones desde Internet, usando UPnP o tecnologías similares" - ) + MENU_ENUM_SUBLABEL_NETPLAY_TCP_UDP_PORT, + "El puerto del servidor a conectar. Puede ser TCP o UDP" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_STDIN_CMD_ENABLE, - "Activar linea de comandos stdin" - ) + MENU_ENUM_SUBLABEL_NETPLAY_PASSWORD, + "Contraseña a pedir a los clientes que se conecten al estar en modo servidor" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MOUSE_ENABLE, - "Activar control con ratón en el menú" - ) + MENU_ENUM_SUBLABEL_NETPLAY_PUBLIC_ANNOUNCE, + "Permite ser encontrado fácilmente, sino los clientes deberán conectarse manualmente" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_POINTER_ENABLE, - "Activar controles táctiles en el menú" - ) + MENU_ENUM_SUBLABEL_NETPLAY_SPECTATE_PASSWORD, + "Contraseña a pedir a los espectadores que se conecten al estar en modo servidor" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_THUMBNAILS, - "Tipo de miniaturas a mostrar" - ) + MENU_ENUM_SUBLABEL_NETPLAY_START_AS_SPECTATOR, + "Si se debe iniciar juego en red en modo espectador" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS, - "Tipo de miniaturas a mostrar a la izquierda" - ) + MENU_ENUM_SUBLABEL_NETPLAY_ALLOW_SLAVES, + "Si se permiten conexiones en modo esclavo. El modo esclavo usa muy poco poder de procesamiento, pero tendrá un impacto significativo en la latencia" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_XMB_VERTICAL_THUMBNAILS, - "Muestra la miniatura izquierda debajo de la derecha, a la derecha de la pantalla" - ) + MENU_ENUM_SUBLABEL_NETPLAY_REQUIRE_SLAVES, + "Solo usar modo esclavo. No recomendado excepto en redes muy rápidas con máquinas muy débiles" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_TIMEDATE_ENABLE, - "Mostrar el día y hora en el menú" - ) + MENU_ENUM_SUBLABEL_NETPLAY_STATELESS_MODE, + "Necesita una red muy rápida, pero se eliminarán los tirones al no realizar rebobinados de sincronización" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_BATTERY_LEVEL_ENABLE, - "Mostrar el nivel de batería actual menú" - ) + MENU_ENUM_SUBLABEL_NETPLAY_CHECK_FRAMES, + "Frecuencia en frames con la que se verificará si el servidor y el cliente están en sincronía" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NAVIGATION_WRAPAROUND, - "Volver al principio cuando llegue al final de la lista tanto sea vertical como horizontal" - ) + MENU_ENUM_SUBLABEL_NETPLAY_NAT_TRAVERSAL, + "Cuando se es servidor, intentar escuchar conexiones desde Internet, usando UPnP o tecnologías similares" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_HOST, - "Este dispositivo será el anfitrión de la partida" - ) + MENU_ENUM_SUBLABEL_STDIN_CMD_ENABLE, + "Activar linea de comandos stdin" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, - "Serás un cliente de la partida" - ) + MENU_ENUM_SUBLABEL_MOUSE_ENABLE, + "Activar control con ratón en el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, - "Desconecta una sesión activa de juego en red" - ) + MENU_ENUM_SUBLABEL_POINTER_ENABLE, + "Activar controles táctiles en el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Escanea una carpeta en busca de archivos compatibles y los añade a la colección" - ) + MENU_ENUM_SUBLABEL_THUMBNAILS, + "Tipo de miniaturas a mostrar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SCAN_FILE, - "Escanea un archivo compatible y lo añade a la colección" - ) + MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS, + "Tipo de miniaturas a mostrar a la izquierda" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, - "Un intervalo de 0 significa que la GPU no esperará a intercambiar los búfers, pero puede causar tearing. Un intervalo de 1 significa que la GPU forzará a la CPU a esperar que al menos un cuadro sea mostrado." - ) + MENU_ENUM_SUBLABEL_XMB_VERTICAL_THUMBNAILS, + "Muestra la miniatura izquierda debajo de la derecha, a la derecha de la pantalla" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE, - "Ordenar archivos de guardado en carpetas nombradas por núcleo" - ) + MENU_ENUM_SUBLABEL_TIMEDATE_ENABLE, + "Mostrar el día y hora en el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE, - "Ordenar guardados rápidos en carpetas nombradas por núcleo" - ) + MENU_ENUM_SUBLABEL_BATTERY_LEVEL_ENABLE, + "Mostrar el nivel de batería actual menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_REQUEST_DEVICE_I, - "Pedir jugar con el dispositivo de entrada dado" - ) + MENU_ENUM_SUBLABEL_NAVIGATION_WRAPAROUND, + "Volver al principio cuando llegue al final de la lista tanto sea vertical como horizontal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL, - "URL de la carpeta del actualizador de núcleos en el buildbot Libretro" - ) + MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_HOST, + "Este dispositivo será el anfitrión de la partida" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL, - "URL de la carpeta de recursos en el buildbot Libretro" - ) + MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, + "Serás un cliente de la partida" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, - "Extraer automáticamente los archivos después de descargarlos" - ) + MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, + "Desconecta una sesión activa de juego en red" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, - "Escanear en busca de nuevas salas" - ) + MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, + "Escanea una carpeta en busca de archivos compatibles y los añade a la colección" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Eliminar esta entrada de la colección" - ) + MENU_ENUM_SUBLABEL_SCAN_FILE, + "Escanea un archivo compatible y lo añade a la colección" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INFORMATION, - "Ver mas información sobre el contenido" - ) + MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, + "Un intervalo de 0 significa que la GPU no esperará a intercambiar los búfers, pero puede causar tearing. Un intervalo de 1 significa que la GPU forzará a la CPU a esperar que al menos un cuadro sea mostrado." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, - "Agregar entrada a sus favoritos" - ) + MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE, + "Ordenar archivos de guardado en carpetas nombradas por núcleo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES_PLAYLIST, - "Agregar entrada a sus favoritos" - ) + MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE, + "Ordenar guardados rápidos en carpetas nombradas por núcleo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RUN, - "Iniciar el contenido" - ) + MENU_ENUM_SUBLABEL_NETPLAY_REQUEST_DEVICE_I, + "Pedir jugar con el dispositivo de entrada dado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_FILE_BROWSER_SETTINGS, - "Ajuste las opciones del explorador de archivos" - ) + MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL, + "URL de la carpeta del actualizador de núcleos en el buildbot Libretro" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUTO_REMAPS_ENABLE, - "Activar controles personalizados por defecto al inicio" - ) + MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL, + "URL de la carpeta de recursos en el buildbot Libretro" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUTO_OVERRIDES_ENABLE, - "Activar configuración personalizada por defecto al inicio" - ) + MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, + "Extraer automáticamente los archivos después de descargarlos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_GAME_SPECIFIC_OPTIONS, - "Activar configuración de núcleos personalizada por defecto al inicio" - ) + MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, + "Escanear en busca de nuevas salas" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CORE_ENABLE, - "Muestra el nombre del núcleo actual en el menú" - ) + MENU_ENUM_SUBLABEL_DELETE_ENTRY, + "Eliminar esta entrada de la colección" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DATABASE_MANAGER, - "Ver bases de datos" - ) + MENU_ENUM_SUBLABEL_INFORMATION, + "Ver mas información sobre el contenido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CURSOR_MANAGER, - "Ver búsquedas previas" - ) + MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, + "Agregar entrada a sus favoritos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_TAKE_SCREENSHOT, - "Captura una imagen de la pantalla" - ) + MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES_PLAYLIST, + "Agregar entrada a sus favoritos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CLOSE_CONTENT, - "Cierra el contenido actual. Cualquier cambio no guardado se perderá" - ) + MENU_ENUM_SUBLABEL_RUN, + "Iniciar el contenido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LOAD_STATE, - "Carga un guardado rápido desde la posición seleccionada" - ) + MENU_ENUM_SUBLABEL_MENU_FILE_BROWSER_SETTINGS, + "Ajuste las opciones del explorador de archivos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVE_STATE, - "Guarda en la posición seleccionada" - ) + MENU_ENUM_SUBLABEL_AUTO_REMAPS_ENABLE, + "Activar controles personalizados por defecto al inicio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RESUME, - "Reanudar la ejecución del contenido y salir del menú rápido" - ) + MENU_ENUM_SUBLABEL_AUTO_OVERRIDES_ENABLE, + "Activar configuración personalizada por defecto al inicio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RESUME_CONTENT, - "Reanudar la ejecución del contenido y salir del menú rápido" - ) + MENU_ENUM_SUBLABEL_GAME_SPECIFIC_OPTIONS, + "Activar configuración de núcleos personalizada por defecto al inicio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_STATE_SLOT, - "Cambia la posición de guardado actual" - ) + MENU_ENUM_SUBLABEL_CORE_ENABLE, + "Muestra el nombre del núcleo actual en el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_UNDO_LOAD_STATE, - "Si se cargo un guardado, el contenido volverá al estado previo a la carga" - ) + MENU_ENUM_SUBLABEL_DATABASE_MANAGER, + "Ver bases de datos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_UNDO_SAVE_STATE, - "Si se sobre-escribió un guardado, se volverá al guardado previo" - ) + MENU_ENUM_SUBLABEL_CURSOR_MANAGER, + "Ver búsquedas previas" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, - "Servicio de RetroAchievements. Para mas información, visite http://retroachievements.org" - ) + MENU_ENUM_SUBLABEL_TAKE_SCREENSHOT, + "Captura una imagen de la pantalla" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ACCOUNTS_LIST, - "Administra las cuentas de usuario" - ) + MENU_ENUM_SUBLABEL_CLOSE_CONTENT, + "Cierra el contenido actual. Cualquier cambio no guardado se perderá" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_META_REWIND, - "Administra las opciones de rebobinado" - ) + MENU_ENUM_SUBLABEL_LOAD_STATE, + "Carga un guardado rápido desde la posición seleccionada" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_DETAILS, - "Administra los detalles de los trucos" - ) + MENU_ENUM_SUBLABEL_SAVE_STATE, + "Guarda en la posición seleccionada" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_SEARCH, - "Iniciar o continuar una búsqueda de trucos" - ) + MENU_ENUM_SUBLABEL_RESUME, + "Reanudar la ejecución del contenido y salir del menú rápido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RESTART_CONTENT, - "Reinicia el contenido desde el principio" - ) + MENU_ENUM_SUBLABEL_RESUME_CONTENT, + "Reanudar la ejecución del contenido y salir del menú rápido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, - "Guarda un archivo de personalización que se aplicará a todo el contenido cargado con este núcleo. Tomará precedencia sobre la configuración principal" - ) + MENU_ENUM_SUBLABEL_STATE_SLOT, + "Cambia la posición de guardado actual" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, - "Guarda un archivo de configuraciones que aplicará a todo el contenido cargado desde el mismo directorio que el archivo actual. Toma precedencia sobre el archivo principal" - ) + MENU_ENUM_SUBLABEL_UNDO_LOAD_STATE, + "Si se cargo un guardado, el contenido volverá al estado previo a la carga" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, - "Guarda un archivo de personalización que se aplicará solo a este contenido cargado. Tomará precedencia sobre la configuración principal" - ) + MENU_ENUM_SUBLABEL_UNDO_SAVE_STATE, + "Si se sobre-escribió un guardado, se volverá al guardado previo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CORE_CHEAT_OPTIONS, - "Configurar trucos" - ) + MENU_ENUM_SUBLABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, + "Servicio de RetroAchievements. Para mas información, visite http://retroachievements.org" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SHADER_OPTIONS, - "Configurar shaders para mejorar la imagen" - ) + MENU_ENUM_SUBLABEL_ACCOUNTS_LIST, + "Administra las cuentas de usuario" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CORE_INPUT_REMAPPING_OPTIONS, - "Cambia los controles para el contenido cargado actualmente" - ) + MENU_ENUM_SUBLABEL_INPUT_META_REWIND, + "Administra las opciones de rebobinado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CORE_OPTIONS, - "Cambia las opciones para el contenido cargado actualmente" - ) + MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_DETAILS, + "Administra los detalles de los trucos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, - "Mostrar opciones avanzadas (ocultas por defecto)" - ) + MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_SEARCH, + "Iniciar o continuar una búsqueda de trucos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, - "Realizar tareas en un hilo separado" - ) + MENU_ENUM_SUBLABEL_RESTART_CONTENT, + "Reinicia el contenido desde el principio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Permitir al usuario eliminar entradas de las colecciones" - ) + MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, + "Guarda un archivo de personalización que se aplicará a todo el contenido cargado con este núcleo. Tomará precedencia sobre la configuración principal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, - "Establece la carpeta de sistema. Los núcleos usan esto para cargar BIOS, configuraciones de sistema, etc." - ) + MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, + "Guarda un archivo de configuraciones que aplicará a todo el contenido cargado desde el mismo directorio que el archivo actual. Toma precedencia sobre el archivo principal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, - "Establece la carpeta inicial del explorador de archivos" - ) + MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, + "Guarda un archivo de personalización que se aplicará solo a este contenido cargado. Tomará precedencia sobre la configuración principal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_DIR, - "Usualmente establecido por desarrolladores que empaquetan aplicaciones libretro/RetroArch para apuntar a los recursos" - ) + MENU_ENUM_SUBLABEL_CORE_CHEAT_OPTIONS, + "Configurar trucos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPERS_DIRECTORY, - "Carpeta donde se guardan los fondos de pantalla dinámicos que cambian según el contenido" - ) + MENU_ENUM_SUBLABEL_SHADER_OPTIONS, + "Configurar shaders para mejorar la imagen" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_THUMBNAILS_DIRECTORY, - "Carpeta de miniaturas (cajas, etc.)" - ) + MENU_ENUM_SUBLABEL_CORE_INPUT_REMAPPING_OPTIONS, + "Cambia los controles para el contenido cargado actualmente" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RGUI_CONFIG_DIRECTORY, - "Establece la ubicación inicial del explorador del menú" - ) + MENU_ENUM_SUBLABEL_CORE_OPTIONS, + "Cambia las opciones para el contenido cargado actualmente" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, - "El número de frames de entrada a usar para ocultar la latencia de red durante juego en red. Reduce los tirones y el uso de CPU, a costa de incrementar la latencia de entrada" - ) + MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, + "Mostrar opciones avanzadas (ocultas por defecto)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, - "El rango de frames de entrada a usar para ocultar la latencia de red durante juego en red. Reduce los tirones y el uso de CPU, a costa de incrementar la latencia de entrada dentro de un rango" - ) + MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, + "Realizar tareas en un hilo separado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DISK_CYCLE_TRAY_STATUS, - "Continua el ciclo de discos. Si el disco fue introducido, se expulsará sino se introducirá" - ) + MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, + "Permitir al usuario eliminar entradas de las colecciones" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DISK_INDEX, - "Cambiar el indice de disco" - ) + MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, + "Establece la carpeta de sistema. Los núcleos usan esto para cargar BIOS, configuraciones de sistema, etc." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DISK_OPTIONS, - "Administrar imágenes de disco" - ) + MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, + "Establece la carpeta inicial del explorador de archivos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, - "Seleccionar una imagen de disco a insertar" - ) + MENU_ENUM_SUBLABEL_CONTENT_DIR, + "Usualmente establecido por desarrolladores que empaquetan aplicaciones libretro/RetroArch para apuntar a los recursos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, - "Limita los FPS en el menú" - ) + MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPERS_DIRECTORY, + "Carpeta donde se guardan los fondos de pantalla dinámicos que cambian según el contenido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_XMB_LAYOUT, - "Seleccionar una disposición diferente para la interfaz XMB" - ) + MENU_ENUM_SUBLABEL_THUMBNAILS_DIRECTORY, + "Carpeta de miniaturas (cajas, etc.)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_XMB_THEME, - "Seleccionar un tema de iconos diferente. Los cambios tendrán efecto al reiniciar" - ) + MENU_ENUM_SUBLABEL_RGUI_CONFIG_DIRECTORY, + "Establece la ubicación inicial del explorador del menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, - "Activar sombra para los iconos. Tendrá un pequeño impacto en el rendimiento" - ) + MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, + "El número de frames de entrada a usar para ocultar la latencia de red durante juego en red. Reduce los tirones y el uso de CPU, a costa de incrementar la latencia de entrada" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MATERIALUI_MENU_COLOR_THEME, - "Seleccionar un color diferente para el menú" - ) + MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, + "El rango de frames de entrada a usar para ocultar la latencia de red durante juego en red. Reduce los tirones y el uso de CPU, a costa de incrementar la latencia de entrada dentro de un rango" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_WALLPAPER_OPACITY, - "Modificar la opacidad de la imagen de fondo" - ) + MENU_ENUM_SUBLABEL_DISK_CYCLE_TRAY_STATUS, + "Continua el ciclo de discos. Si el disco fue introducido, se expulsará sino se introducirá" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_XMB_MENU_COLOR_THEME, - "Seleccionar un color diferente para el menú" - ) + MENU_ENUM_SUBLABEL_DISK_INDEX, + "Cambiar el indice de disco" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_XMB_RIBBON_ENABLE, - "Seleccionar un fondo animado. Puede causar problemas de rendimiento dependiendo del efecto, desactivar si el dispositivo no tiene suficiente potencia" - ) + MENU_ENUM_SUBLABEL_DISK_OPTIONS, + "Administrar imágenes de disco" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_XMB_FONT, - "Seleccionar el tipo de letra usado en el menú" - ) + MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, + "Seleccionar una imagen de disco a insertar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_FAVORITES, - "Mostrar la pestaña de favoritos en el menú principal" - ) + MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, + "Limita los FPS en el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_IMAGES, - "Mostrar la pestaña de imágenes en el menú principal" - ) + MENU_ENUM_SUBLABEL_VRR_RUNLOOP_ENABLE, + "No desviarse del los tiempos del núcleo. Usar con pantallas de refresco variable, G-Sync, FreeSync" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_MUSIC, - "Mostrar la pestaña de música en el menú principal" - ) + MENU_ENUM_SUBLABEL_XMB_LAYOUT, + "Seleccionar una disposición diferente para la interfaz XMB" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_VIDEO, - "Mostrar la pestaña de video en el menú principal" - ) + MENU_ENUM_SUBLABEL_XMB_THEME, + "Seleccionar un tema de iconos diferente. Los cambios tendrán efecto al reiniciar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_NETPLAY, - "Mostrar la pestaña de juego en red en el menú principal" - ) + MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, + "Activar sombra para los iconos. Tendrá un pequeño impacto en el rendimiento" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS, - "Mostrar la pestaña de configuración en el menú principal" - ) + MENU_ENUM_SUBLABEL_MATERIALUI_MENU_COLOR_THEME, + "Seleccionar un color diferente para el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_HISTORY, - "Mostrar la pestaña de historial en el menú principal" - ) + MENU_ENUM_SUBLABEL_MENU_WALLPAPER_OPACITY, + "Modificar la opacidad de la imagen de fondo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_ADD, - "Mostrar la pestaña de importar contenido en el menú principal" - ) + MENU_ENUM_SUBLABEL_XMB_MENU_COLOR_THEME, + "Seleccionar un color diferente para el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_PLAYLISTS, - "Mostrar las pestañas de playlists en el menú principal" - ) + MENU_ENUM_SUBLABEL_XMB_RIBBON_ENABLE, + "Seleccionar un fondo animado. Puede causar problemas de rendimiento dependiendo del efecto, desactivar si el dispositivo no tiene suficiente potencia" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN, - "Mostrar pantalla de inicio. Esto es desactivado automáticamente después del primer inicio" - ) + MENU_ENUM_SUBLABEL_XMB_FONT, + "Seleccionar el tipo de letra usado en el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY, - "Modificar opacidad del encabezado" - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_FAVORITES, + "Mostrar la pestaña de favoritos en el menú principal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MATERIALUI_MENU_FOOTER_OPACITY, - "Modificar opacidad del pie de página" - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_IMAGES, + "Mostrar la pestaña de imágenes en el menú principal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DPI_OVERRIDE_ENABLE, - "El menú es escalado dinamicamente. Activar si desea un valor predefinido" - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_MUSIC, + "Mostrar la pestaña de música en el menú principal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DPI_OVERRIDE_VALUE, - "Establecer DPI. NOTA: Debe activar 'Forzar DPI' para que tenga efecto" - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_VIDEO, + "Mostrar la pestaña de video en el menú principal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CORE_ASSETS_DIRECTORY, - "Guardar archivos descargados en esta carpeta" - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_NETPLAY, + "Mostrar la pestaña de juego en red en el menú principal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_REMAPPING_DIRECTORY, - "Guardar controles reasignados en esta carpeta" - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS, + "Mostrar la pestaña de configuración en el menú principal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LIBRETRO_DIR_PATH, - "Buscar contenido/núcleos en esta carpeta" - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_HISTORY, + "Mostrar la pestaña de historial en el menú principal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, - "Los archivos de información de aplicación y de núcleos se ubican aquí" - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_ADD, + "Mostrar la pestaña de importar contenido en el menú principal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, - "Los archivos de auto-configuración de mandos se guardan aquí" - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_PLAYLISTS, + "Mostrar las pestañas de playlists en el menú principal" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Guardar colecciones en esta carpeta" - ) + MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN, + "Mostrar pantalla de inicio. Esto es desactivado automáticamente después del primer inicio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, - "Almacenar archivos temporales aquí" - ) + MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY, + "Modificar opacidad del encabezado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CURSOR_DIRECTORY, - "Almacenar búsquedas guardadas aquí" - ) + MENU_ENUM_SUBLABEL_MATERIALUI_MENU_FOOTER_OPACITY, + "Modificar opacidad del pie de página" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_DATABASE_DIRECTORY, - "Las bases de datos están aquí" - ) + MENU_ENUM_SUBLABEL_DPI_OVERRIDE_ENABLE, + "El menú es escalado dinamicamente. Activar si desea un valor predefinido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ASSETS_DIRECTORY, - "Carpeta de recursos, donde la interfaz buscará los iconos e imágenes" - ) + MENU_ENUM_SUBLABEL_DPI_OVERRIDE_VALUE, + "Establecer DPI. NOTA: Debe activar 'Forzar DPI' para que tenga efecto" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVEFILE_DIRECTORY, - "Carpeta de guardados, si no se establece se guardará en la carpeta del contenido" - ) + MENU_ENUM_SUBLABEL_CORE_ASSETS_DIRECTORY, + "Guardar archivos descargados en esta carpeta" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_DIRECTORY, - "Carpeta de guardados rápidos, si no se establece se guardará en la carpeta del contenido" - ) + MENU_ENUM_SUBLABEL_INPUT_REMAPPING_DIRECTORY, + "Guardar controles reasignados en esta carpeta" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SCREENSHOT_DIRECTORY, - "Carpeta donde guardar capturas de pantalla" - ) + MENU_ENUM_SUBLABEL_LIBRETRO_DIR_PATH, + "Buscar contenido/núcleos en esta carpeta" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_OVERLAY_DIRECTORY, - "Carpeta de donde cargar superposiciones" - ) + MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, + "Los archivos de información de aplicación y de núcleos se ubican aquí" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_DATABASE_PATH, - "Carpeta de donde cargar trucos" - ) + MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, + "Los archivos de auto-configuración de mandos se guardan aquí" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_FILTER_DIR, - "Carpeta de donde cargar filtros DSP" - ) + MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, + "Guardar colecciones en esta carpeta" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FILTER_DIR, - "Carpeta de donde cargar filtros basados en CPU" - ) + MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, + "Almacenar archivos temporales aquí" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHADER_DIR, - "Carpeta de donde cargar filtros basados en GPU" - ) + MENU_ENUM_SUBLABEL_CURSOR_DIRECTORY, + "Almacenar búsquedas guardadas aquí" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RECORDING_OUTPUT_DIRECTORY, - "Carpeta de donde guardar grabaciones" - ) + MENU_ENUM_SUBLABEL_CONTENT_DATABASE_DIRECTORY, + "Las bases de datos están aquí" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RECORDING_CONFIG_DIRECTORY, - "Carpeta de donde guardar las configuraciones de grabación" - ) + MENU_ENUM_SUBLABEL_ASSETS_DIRECTORY, + "Carpeta de recursos, donde la interfaz buscará los iconos e imágenes" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FONT_PATH, - "Seleccionar un tipo de fuente diferente para las notificaciones" - ) + MENU_ENUM_SUBLABEL_SAVEFILE_DIRECTORY, + "Carpeta de guardados, si no se establece se guardará en la carpeta del contenido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SHADER_APPLY_CHANGES, - "Los cambios en la configuración del shader tomarán efecto inmediatamente. Usalo al cambiar la cantidad de pasadas, filtrado, etc." - ) + MENU_ENUM_SUBLABEL_SAVESTATE_DIRECTORY, + "Carpeta de guardados rápidos, si no se establece se guardará en la carpeta del contenido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHADER_NUM_PASSES, - "Cambiar la cantidad de pasadas de shaders. Puedes asignar shaders individualmente a cada pasada y configurar su escalado y filtrado" - ) + MENU_ENUM_SUBLABEL_SCREENSHOT_DIRECTORY, + "Carpeta donde guardar capturas de pantalla" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET, - "Cargar un preset de shader. Sera configurado automáticamente" - ) + MENU_ENUM_SUBLABEL_OVERLAY_DIRECTORY, + "Carpeta de donde cargar superposiciones" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_AS, - "Guardar la configuración actual de shaders cono un nuevo preset" - ) + MENU_ENUM_SUBLABEL_CHEAT_DATABASE_PATH, + "Carpeta de donde cargar trucos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_CORE, - "Guardar la configuración actual de shaders para este núcleo" - ) + MENU_ENUM_SUBLABEL_AUDIO_FILTER_DIR, + "Carpeta de donde cargar filtros DSP" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_PARENT, - "Guardar la configuración actual de shaders para todos los archivos en el directorio de contenido actual" - ) + MENU_ENUM_SUBLABEL_VIDEO_FILTER_DIR, + "Carpeta de donde cargar filtros basados en CPU" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_GAME, - "Guardar la configuración actual de shaders para este contenido" - ) + MENU_ENUM_SUBLABEL_VIDEO_SHADER_DIR, + "Carpeta de donde cargar filtros basados en GPU" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHADER_PARAMETERS, - "Modifica el shader directamente. Los cambios no serán guardados en el preset" - ) + MENU_ENUM_SUBLABEL_RECORDING_OUTPUT_DIRECTORY, + "Carpeta de donde guardar grabaciones" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_PARAMETERS, - "Modifica el preset de shader actualmente usado en el menú" - ) + MENU_ENUM_SUBLABEL_RECORDING_CONFIG_DIRECTORY, + "Carpeta de donde guardar las configuraciones de grabación" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_NUM_PASSES, - "Cambiar la cantidad de trucos a usar" - ) + MENU_ENUM_SUBLABEL_VIDEO_FONT_PATH, + "Seleccionar un tipo de fuente diferente para las notificaciones" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_APPLY_CHANGES, - "Los cambios en los trucos tendrán efecto inmediatamente" - ) + MENU_ENUM_SUBLABEL_SHADER_APPLY_CHANGES, + "Los cambios en la configuración del shader tomarán efecto inmediatamente. Usalo al cambiar la cantidad de pasadas, filtrado, etc." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_START_SEARCH, - "Inciar búsqueda de un truco nuevo. El número de bits se puede cambiar" - ) + MENU_ENUM_SUBLABEL_VIDEO_SHADER_NUM_PASSES, + "Cambiar la cantidad de pasadas de shaders. Puedes asignar shaders individualmente a cada pasada y configurar su escalado y filtrado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_CONTINUE_SEARCH, - "Continuar búsqueda de un truco nuevo" - ) + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET, + "Cargar un preset de shader. Sera configurado automáticamente" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD, - "Cargar archivo de trucos reemplazando los existentes" - ) + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_AS, + "Guardar la configuración actual de shaders cono un nuevo preset" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD_APPEND, - "Cargar archivo de trucos agregandolos a los existentes" - ) + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_CORE, + "Guardar la configuración actual de shaders para este núcleo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_FILE_SAVE_AS, - "Guardar trucos actuales a un archivo" - ) + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_PARENT, + "Guardar la configuración actual de shaders para todos los archivos en el directorio de contenido actual" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SETTINGS, - "Accede rápidamente a todas las opciones del juego" - ) + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_GAME, + "Guardar la configuración actual de shaders para este contenido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CORE_INFORMATION, - "Ver información pertinente a la aplicación/núcleo" - ) + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PARAMETERS, + "Modifica el shader directamente. Los cambios no serán guardados en el preset" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_ASPECT_RATIO, - "Valor de punto flotante (ancho / alto), usado si la relación de aspecto es 'Personal'" - ) + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_PARAMETERS, + "Modifica el preset de shader actualmente usado en el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT, - "Alto usada si la relación de aspecto es establecida en 'Personal'" - ) + MENU_ENUM_SUBLABEL_CHEAT_NUM_PASSES, + "Cambiar la cantidad de trucos a usar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH, - "Ancho usada si la relación de aspecto es establecida en 'Personal'" - ) + MENU_ENUM_SUBLABEL_CHEAT_APPLY_CHANGES, + "Los cambios en los trucos tendrán efecto inmediatamente" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_X, - "Margen de posición sobre el eje X de la pantalla. Serán ignorados si 'Escalar en múltiplos enteros' es activado, Entonces serán centrados" - ) + MENU_ENUM_SUBLABEL_CHEAT_START_SEARCH, + "Inciar búsqueda de un truco nuevo. El número de bits se puede cambiar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_Y, - "Margen de posición sobre el eje Y de la pantalla. Serán ignorados si 'Escalar en múltiplos enteros' es activado, Entonces serán centrados" - ) + MENU_ENUM_SUBLABEL_CHEAT_CONTINUE_SEARCH, + "Continuar búsqueda de un truco nuevo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_USE_MITM_SERVER, - "Usar servidor relé" - ) + MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD, + "Cargar archivo de trucos reemplazando los existentes" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, - "Enviar conexiones de juego en red a través de otro servidor (man-in-the-middle). Útil si el servidor está detrás de un firewall o tiene problemas NAT/UPnP" - ) + MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD_APPEND, + "Cargar archivo de trucos agregandolos a los existentes" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_MITM_SERVER, - "Ubicación del servidor relé" - ) + MENU_ENUM_SUBLABEL_CHEAT_FILE_SAVE_AS, + "Guardar trucos actuales a un archivo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_MITM_SERVER, - "Elegir un servidor relé especifico. Las ubicaciones geográficamente cercanas tienden a tener menor latencia" - ) + MENU_ENUM_SUBLABEL_CONTENT_SETTINGS, + "Accede rápidamente a todas las opciones del juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, - "Agregar al mezclador" - ) + MENU_ENUM_SUBLABEL_CORE_INFORMATION, + "Ver información pertinente a la aplicación/núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_PLAY, - "Add to mixer and play" - ) + MENU_ENUM_SUBLABEL_VIDEO_ASPECT_RATIO, + "Valor de punto flotante (ancho / alto), usado si la relación de aspecto es 'Personal'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION, - "Agregar al mezclador y colección" - ) + MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT, + "Alto usada si la relación de aspecto es establecida en 'Personal'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY, - "Agregar al mezclador y reproducir" - ) + MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH, + "Ancho usada si la relación de aspecto es establecida en 'Personal'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_FILTER_BY_CURRENT_CORE, - "Filtrar por núcleo actual" - ) + MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_X, + "Margen de posición sobre el eje X de la pantalla. Serán ignorados si 'Escalar en múltiplos enteros' es activado, Entonces serán centrados" + ) MSG_HASH( - MSG_AUDIO_MIXER_VOLUME, - "Volumen del mezclador de audio global" - ) + MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_Y, + "Margen de posición sobre el eje Y de la pantalla. Serán ignorados si 'Escalar en múltiplos enteros' es activado, Entonces serán centrados" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_MIXER_VOLUME, - "Volumen global. 0 dB es normal, donde no se aplica ganancia" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_USE_MITM_SERVER, + "Usar servidor relé" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_VOLUME, - "Volumen del mezclador de audio (dB)" - ) + MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, + "Enviar conexiones de juego en red a través de otro servidor (man-in-the-middle). Útil si el servidor está detrás de un firewall o tiene problemas NAT/UPnP" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_MUTE, - "Silenciar mezclador de audio" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_MITM_SERVER, + "Ubicación del servidor relé" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_MIXER_MUTE, - "Silencia el mezclador de audio" - ) + MENU_ENUM_SUBLABEL_NETPLAY_MITM_SERVER, + "Elegir un servidor relé especifico. Las ubicaciones geográficamente cercanas tienden a tener menor latencia" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_SHOW_ONLINE_UPDATER, - "Mostrar actualizador en linea" - ) + MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, + "Agregar al mezclador" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SHOW_ONLINE_UPDATER, - "Mostrar/ocultar la opción de 'Actualizador en línea'" - ) + MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_PLAY, + "Add to mixer and play" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_VIEWS_SETTINGS, - "Vistas" - ) + MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION, + "Agregar al mezclador y colección" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_VIEWS_SETTINGS, - "Mostrar/ocultar elementos del menú" - ) + MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY, + "Agregar al mezclador y reproducir" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_SHOW_CORE_UPDATER, - "Mostrar 'Actualizador de núcleos'" - ) + MENU_ENUM_LABEL_VALUE_FILTER_BY_CURRENT_CORE, + "Filtrar por núcleo actual" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SHOW_CORE_UPDATER, - "Mostrar/ocultar la habilidad de actualizar núcleos y archivos asociados" - ) + MSG_AUDIO_MIXER_VOLUME, + "Volumen del mezclador de audio global" + ) MSG_HASH( - MSG_PREPARING_FOR_CONTENT_SCAN, - "Preparando para escaneo de contenido..." - ) + MENU_ENUM_SUBLABEL_AUDIO_MIXER_VOLUME, + "Volumen global. 0 dB es normal, donde no se aplica ganancia" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CORE_DELETE, - "Borrar núcleo" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_VOLUME, + "Volumen del mezclador de audio (dB)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CORE_DELETE, - "Eliminar este núcleo del disco" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_MUTE, + "Silenciar mezclador de audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_FRAMEBUFFER_OPACITY, - "Opacidad del Framebuffer" - ) + MENU_ENUM_SUBLABEL_AUDIO_MIXER_MUTE, + "Silencia el mezclador de audio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_FRAMEBUFFER_OPACITY, - "Modifica la opacidad del framebuffer" - ) + MENU_ENUM_LABEL_VALUE_MENU_SHOW_ONLINE_UPDATER, + "Mostrar actualizador en linea" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES, - "Favoritos" - ) + MENU_ENUM_SUBLABEL_MENU_SHOW_ONLINE_UPDATER, + "Mostrar/ocultar la opción de 'Actualizador en línea'" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_GOTO_FAVORITES, - "Contenido agregado a 'Favoritos' aparecerá aquí" - ) + MENU_ENUM_LABEL_VALUE_MENU_VIEWS_SETTINGS, + "Vistas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_GOTO_MUSIC, - "Música" - ) + MENU_ENUM_SUBLABEL_MENU_VIEWS_SETTINGS, + "Mostrar/ocultar elementos del menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_GOTO_MUSIC, - "Música que ha sido previamente reproducida aparecerá aquí" - ) + MENU_ENUM_LABEL_VALUE_MENU_SHOW_CORE_UPDATER, + "Mostrar 'Actualizador de núcleos'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_GOTO_IMAGES, - "Imagen" - ) + MENU_ENUM_SUBLABEL_MENU_SHOW_CORE_UPDATER, + "Mostrar/ocultar la habilidad de actualizar núcleos y archivos asociados" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_GOTO_IMAGES, - "Imágenes previamente vistas aparecerán aquí" - ) + MSG_PREPARING_FOR_CONTENT_SCAN, + "Preparando para escaneo de contenido..." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_GOTO_VIDEO, - "Video" - ) + MENU_ENUM_LABEL_VALUE_CORE_DELETE, + "Borrar núcleo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_GOTO_VIDEO, - "Videos previamente reproducidos aparecerán aquí" - ) + MENU_ENUM_SUBLABEL_CORE_DELETE, + "Eliminar este núcleo del disco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MATERIALUI_ICONS_ENABLE, - "Iconos en el menú" - ) + MENU_ENUM_LABEL_VALUE_MENU_FRAMEBUFFER_OPACITY, + "Opacidad del Framebuffer" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MATERIALUI_ICONS_ENABLE, - "Activar/Desactivar los iconos mostrados a la izquierda del menú" - ) + MENU_ENUM_SUBLABEL_MENU_FRAMEBUFFER_OPACITY, + "Modifica la opacidad del framebuffer" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_XMB_MAIN_MENU_ENABLE_SETTINGS, - "Activar pestaña de opciones" - ) + MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES, + "Favoritos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS_PASSWORD, - "Establecer contraseña para activar la pestaña de opciones" - ) + MENU_ENUM_SUBLABEL_GOTO_FAVORITES, + "Contenido agregado a 'Favoritos' aparecerá aquí" + ) MSG_HASH( - MSG_INPUT_ENABLE_SETTINGS_PASSWORD, - "Introducir contraseña" - ) + MENU_ENUM_LABEL_VALUE_GOTO_MUSIC, + "Música" + ) MSG_HASH( - MSG_INPUT_ENABLE_SETTINGS_PASSWORD_OK, - "Contraseña correcta" - ) + MENU_ENUM_SUBLABEL_GOTO_MUSIC, + "Música que ha sido previamente reproducida aparecerá aquí" + ) MSG_HASH( - MSG_INPUT_ENABLE_SETTINGS_PASSWORD_NOK, - "Contraseña incorrecta" - ) + MENU_ENUM_LABEL_VALUE_GOTO_IMAGES, + "Imagen" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, - "Activa la pestaña de opciones. Es necesario reiniciar para que aparezca" - ) + MENU_ENUM_SUBLABEL_GOTO_IMAGES, + "Imágenes previamente vistas aparecerán aquí" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, - "Proveer una contraseña al ocultar la pestaña de opciones, hace posible restaurarla desde el menú principal, activando 'Mostrar pestaña de opciones'" - ) + MENU_ENUM_LABEL_VALUE_GOTO_VIDEO, + "Video" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Permitir al usuario renombrar entradas en colecciones" - ) + MENU_ENUM_SUBLABEL_GOTO_VIDEO, + "Videos previamente reproducidos aparecerán aquí" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, - "Permitir renombrar entradas" - ) + MENU_ENUM_LABEL_VALUE_MATERIALUI_ICONS_ENABLE, + "Iconos en el menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RENAME_ENTRY, - "Renombrar el título de esta entrada" - ) + MENU_ENUM_SUBLABEL_MATERIALUI_ICONS_ENABLE, + "Activar/Desactivar los iconos mostrados a la izquierda del menú" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_RENAME_ENTRY, - "Renombrar" - ) + MENU_ENUM_LABEL_VALUE_XMB_MAIN_MENU_ENABLE_SETTINGS, + "Activar pestaña de opciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, - "Mostrar cargar núcleo" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS_PASSWORD, + "Establecer contraseña para activar la pestaña de opciones" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CORE, - "Mostrar/ocultar la opción de 'Cargar núcleo'" - ) + MSG_INPUT_ENABLE_SETTINGS_PASSWORD, + "Introducir contraseña" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CONTENT, - "Mostrar cargar contenido" - ) + MSG_INPUT_ENABLE_SETTINGS_PASSWORD_OK, + "Contraseña correcta" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CONTENT, - "Mostrar/ocultar la opción de 'Cargar contenido'" - ) + MSG_INPUT_ENABLE_SETTINGS_PASSWORD_NOK, + "Contraseña incorrecta" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_SHOW_INFORMATION, - "Mostrar Información" - ) + MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, + "Activa la pestaña de opciones. Es necesario reiniciar para que aparezca" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SHOW_INFORMATION, - "Mostrar/ocultar la opción de 'Información'" - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, + "Proveer una contraseña al ocultar la pestaña de opciones, hace posible restaurarla desde el menú principal, activando 'Mostrar pestaña de opciones'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_SHOW_CONFIGURATIONS, - "Mostrar configuraciones" - ) + MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, + "Permitir al usuario renombrar entradas en colecciones" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SHOW_CONFIGURATIONS, - "Mostrar/ocultar la opción de 'Configuraciones'" - ) + MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, + "Permitir renombrar entradas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_SHOW_HELP, - "Mostrar ayuda" - ) + MENU_ENUM_SUBLABEL_RENAME_ENTRY, + "Renombrar el título de esta entrada" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SHOW_HELP, - "Mostrar/ocultar la opción de 'Ayuda'" - ) + MENU_ENUM_LABEL_VALUE_RENAME_ENTRY, + "Renombrar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_SHOW_QUIT_RETROARCH, - "Mostrar salir de RetroArch" - ) + MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, + "Mostrar cargar núcleo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SHOW_QUIT_RETROARCH, - "Mostrar/ocultar la opción de 'Salir de RetroArch'" - ) + MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CORE, + "Mostrar/ocultar la opción de 'Cargar núcleo'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_SHOW_REBOOT, - "Mostrar reiniciar" - ) + MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CONTENT, + "Mostrar cargar contenido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SHOW_REBOOT, - "Mostrar/ocultar la opción de 'Reiniciar'" - ) + MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CONTENT, + "Mostrar/ocultar la opción de 'Cargar contenido'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_SHOW_SHUTDOWN, - "Show Shutdown" - ) + MENU_ENUM_LABEL_VALUE_MENU_SHOW_INFORMATION, + "Mostrar Información" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SHOW_SHUTDOWN, - "Mostrar/ocultar la opción de 'Apagado'" - ) + MENU_ENUM_SUBLABEL_MENU_SHOW_INFORMATION, + "Mostrar/ocultar la opción de 'Información'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_VIEWS_SETTINGS, - "Menú rápido" - ) + MENU_ENUM_LABEL_VALUE_MENU_SHOW_CONFIGURATIONS, + "Mostrar configuraciones" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_VIEWS_SETTINGS, - "Mostrar/ocultar elementos del menú rápido" - ) + MENU_ENUM_SUBLABEL_MENU_SHOW_CONFIGURATIONS, + "Mostrar/ocultar la opción de 'Configuraciones'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_TAKE_SCREENSHOT, - "Mostrar captura de pantalla" - ) + MENU_ENUM_LABEL_VALUE_MENU_SHOW_HELP, + "Mostrar ayuda" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT, - "Mostrar/ocultar la opción de 'Captura de pantalla'" - ) + MENU_ENUM_SUBLABEL_MENU_SHOW_HELP, + "Mostrar/ocultar la opción de 'Ayuda'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_LOAD_STATE, - "Mostrar guardado rápido" - ) + MENU_ENUM_LABEL_VALUE_MENU_SHOW_QUIT_RETROARCH, + "Mostrar salir de RetroArch" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE, - "Mostrar/ocultar la opción de 'Guardado rápido'" - ) + MENU_ENUM_SUBLABEL_MENU_SHOW_QUIT_RETROARCH, + "Mostrar/ocultar la opción de 'Salir de RetroArch'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, - "Mostrar deshacer carga y guardado rápido" - ) + MENU_ENUM_LABEL_VALUE_MENU_SHOW_REBOOT, + "Mostrar reiniciar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, - "Mostrar/ocultar la opción para deshacer la carga y guardado rápido" - ) + MENU_ENUM_SUBLABEL_MENU_SHOW_REBOOT, + "Mostrar/ocultar la opción de 'Reiniciar'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_ADD_TO_FAVORITES, - "Mostrar agregar a favoritos" - ) + MENU_ENUM_LABEL_VALUE_MENU_SHOW_SHUTDOWN, + "Show Shutdown" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, - "Mostrar/ocultar la opción de 'Agregar a favoritos'" - ) + MENU_ENUM_SUBLABEL_MENU_SHOW_SHUTDOWN, + "Mostrar/ocultar la opción de 'Apagado'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_OPTIONS, - "Mostrar opciones" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_VIEWS_SETTINGS, + "Menú rápido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_OPTIONS, - "Mostrar/ocultar la opción de 'Opciones'" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_VIEWS_SETTINGS, + "Mostrar/ocultar elementos del menú rápido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CONTROLS, - "Mostrar Controles" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_TAKE_SCREENSHOT, + "Mostrar captura de pantalla" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CONTROLS, - "Mostrar/ocultar la opción de 'Controles'" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT, + "Mostrar/ocultar la opción de 'Captura de pantalla'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CHEATS, - "Mostrar trucos" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_LOAD_STATE, + "Mostrar guardado rápido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CHEATS, - "Mostrar/ocultar la opción de 'Trucos'" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE, + "Mostrar/ocultar la opción de 'Guardado rápido'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SHADERS, - "Mostrar Shaders" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, + "Mostrar deshacer carga y guardado rápido" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SHADERS, - "Mostrar/ocultar la opción de 'Shaders'" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, + "Mostrar/ocultar la opción para deshacer la carga y guardado rápido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, - "Mostrar personalizaciones de núcleo" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_ADD_TO_FAVORITES, + "Mostrar agregar a favoritos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, - "Mostrar/ocultar la opción de 'Guardar personalizaciones de núcleo'" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, + "Mostrar/ocultar la opción de 'Agregar a favoritos'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, - "Mostrar personalizaciones de juego" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_OPTIONS, + "Mostrar opciones" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, - "Mostrar/ocultar la opción de 'Guardar personalizaciones de juego'" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_OPTIONS, + "Mostrar/ocultar la opción de 'Opciones'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_INFORMATION, - "Mostrar información" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CONTROLS, + "Mostrar Controles" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_INFORMATION, - "Muestra/oculta la opción de 'Información'" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CONTROLS, + "Mostrar/ocultar la opción de 'Controles'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_ENABLE, - "Activar fondo de notificaciones" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CHEATS, + "Mostrar trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_RED, - "Fondo de notif. componente roja" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CHEATS, + "Mostrar/ocultar la opción de 'Trucos'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_GREEN, - "Fondo de notif. componente verde" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SHADERS, + "Mostrar Shaders" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_BLUE, - "Fondo de notif. componente azul" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SHADERS, + "Mostrar/ocultar la opción de 'Shaders'" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_OPACITY, - "Fondo de notif. opacidad" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, + "Mostrar personalizaciones de núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_DISABLE_KIOSK_MODE, - "Desactivar modo kiosco" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, + "Mostrar/ocultar la opción de 'Guardar personalizaciones de núcleo'" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_DISABLE_KIOSK_MODE, - "Desactiva el modo kiosco. Es necesario reiniciar para completar" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, + "Mostrar personalizaciones de juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_ENABLE_KIOSK_MODE, - "Activar modo kiosco" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, + "Mostrar/ocultar la opción de 'Guardar personalizaciones de juego'" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_ENABLE_KIOSK_MODE, - "Protege la configuración ocultándola" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_INFORMATION, + "Mostrar información" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_KIOSK_MODE_PASSWORD, - "Establecer contraseña para desactivar modo kiosco" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_INFORMATION, + "Muestra/oculta la opción de 'Información'" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_KIOSK_MODE_PASSWORD, - "Proveer una contraseña al activar el modo kiosco hace posible desactivarlo desde el menú principal, seleccionando 'Desactivar modo kiosco' e introduciendo la contraseña" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_ENABLE, + "Activar fondo de notificaciones" + ) MSG_HASH( - MSG_INPUT_KIOSK_MODE_PASSWORD, - "Ingresar contraseña" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_RED, + "Fondo de notif. componente roja" + ) MSG_HASH( - MSG_INPUT_KIOSK_MODE_PASSWORD_OK, - "Contraseña correcta" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_GREEN, + "Fondo de notif. componente verde" + ) MSG_HASH( - MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, - "Contraseña incorrecta" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_BLUE, + "Fondo de notif. componente azul" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_RED, - "Notificación componente roja" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_OPACITY, + "Fondo de notif. opacidad" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_GREEN, - "Notificación componente verde" - ) + MENU_ENUM_LABEL_VALUE_MENU_DISABLE_KIOSK_MODE, + "Desactivar modo kiosco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_BLUE, - "Notificación componente azul" - ) + MENU_ENUM_SUBLABEL_MENU_DISABLE_KIOSK_MODE, + "Desactiva el modo kiosco. Es necesario reiniciar para completar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_FRAMECOUNT_SHOW, - "Contador de frames junto a FPS" - ) + MENU_ENUM_LABEL_VALUE_MENU_ENABLE_KIOSK_MODE, + "Activar modo kiosco" + ) MSG_HASH( - MSG_CONFIG_OVERRIDE_LOADED, - "Personalizar configuraciones cargadas" - ) + MENU_ENUM_SUBLABEL_MENU_ENABLE_KIOSK_MODE, + "Protege la configuración ocultándola" + ) MSG_HASH( - MSG_GAME_REMAP_FILE_LOADED, - "Archivo de reasignaciones de juego cargado" - ) + MENU_ENUM_LABEL_VALUE_MENU_KIOSK_MODE_PASSWORD, + "Establecer contraseña para desactivar modo kiosco" + ) MSG_HASH( - MSG_CORE_REMAP_FILE_LOADED, - "Archivo de reasignaciones de núcleo cargado" - ) + MENU_ENUM_SUBLABEL_MENU_KIOSK_MODE_PASSWORD, + "Proveer una contraseña al activar el modo kiosco hace posible desactivarlo desde el menú principal, seleccionando 'Desactivar modo kiosco' e introduciendo la contraseña" + ) MSG_HASH( - MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES, - "RunAhead se desactivó porque este núcleo no soporta archivos de estado (savestates)" - ) + MSG_INPUT_KIOSK_MODE_PASSWORD, + "Ingresar contraseña" + ) MSG_HASH( - MSG_RUNAHEAD_FAILED_TO_SAVE_STATE, - "Fallo al guardar el estado. RunAhead se ha desactivado" - ) + MSG_INPUT_KIOSK_MODE_PASSWORD_OK, + "Contraseña correcta" + ) MSG_HASH( - MSG_RUNAHEAD_FAILED_TO_LOAD_STATE, - "Fallo al cargar el estado. RunAhead se ha desactivado" - ) + MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, + "Contraseña incorrecta" + ) MSG_HASH( - MSG_RUNAHEAD_FAILED_TO_CREATE_SECONDARY_INSTANCE, - "Fallo al crear la segunda instancia. RunAhead usará solo una" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_RED, + "Notificación componente roja" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, - "Agregar contenido automáticamente a la lista de reproducción" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_GREEN, + "Notificación componente verde" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, - "Escanea automáticamente el contenido cargado para que aparezca en las listas de reproducción" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_BLUE, + "Notificación componente azul" + ) MSG_HASH( - MSG_SCANNING_OF_FILE_FINISHED, - "Escaneo de archivo finalizado" - ) + MENU_ENUM_LABEL_VALUE_FRAMECOUNT_SHOW, + "Contador de frames junto a FPS" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_OPACITY, - "Opacidad de la ventana" - ) + MSG_CONFIG_OVERRIDE_LOADED, + "Personalizar configuraciones cargadas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY, - "Calidad del muestreo de audio" - ) + MSG_GAME_REMAP_FILE_LOADED, + "Archivo de reasignaciones de juego cargado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, - "Valores mas bajos favorecen el rendimiento y bajan la latencia a costa de la calidad, incrementar el valor aumentará la calidad a costa del rendimiento y latencia" - ) + MSG_CORE_REMAP_FILE_LOADED, + "Archivo de reasignaciones de núcleo cargado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SHADER_WATCH_FOR_CHANGES, - "Vigilar cambios en los shader" - ) + MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES, + "RunAhead se desactivó porque este núcleo no soporta archivos de estado (savestates)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SHADER_WATCH_FOR_CHANGES, - "Auto-aplica los cambios hechos a los archivos shader del disco" - ) + MSG_RUNAHEAD_FAILED_TO_SAVE_STATE, + "Fallo al guardar el estado. RunAhead se ha desactivado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_SHOW_DECORATIONS, - "Mostrar Decoraciones de Ventanas" - ) + MSG_RUNAHEAD_FAILED_TO_LOAD_STATE, + "Fallo al cargar el estado. RunAhead se ha desactivado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_STATISTICS_SHOW, - "Mostrar Estadísticas" - ) + MSG_RUNAHEAD_FAILED_TO_CREATE_SECONDARY_INSTANCE, + "Fallo al crear la segunda instancia. RunAhead usará solo una" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_STATISTICS_SHOW, - "Mostrar estadísticas técnicas en pantalla" - ) + MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Agregar contenido automáticamente a la lista de reproducción" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_ENABLE, - "Activar relleno de borde" - ) + MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Escanea automáticamente el contenido cargado para que aparezca en las listas de reproducción" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, - "Activar ancho del relleno de borde" - ) + MSG_SCANNING_OF_FILE_FINISHED, + "Escaneo de archivo finalizado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, - "Activar ancho del relleno de fondo" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_OPACITY, + "Opacidad de la ventana" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, - "Para pantallas CRT de 15 kHz. Intenta usar la resolución y refresco exactos del núcleo/juego" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY, + "Calidad del muestreo de audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, - "CRT SwitchRes" - ) + MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, + "Valores mas bajos favorecen el rendimiento y bajan la latencia a costa de la calidad, incrementar el valor aumentará la calidad a costa del rendimiento y latencia" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, - "Al activar CRT SwitchRes, forzar resolución ultrawide horizontal para minimizar el cambio de modos" - ) + MENU_ENUM_LABEL_VALUE_SHADER_WATCH_FOR_CHANGES, + "Vigilar cambios en los shader" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, - "Super Resolucion CRT" - ) + MENU_ENUM_SUBLABEL_SHADER_WATCH_FOR_CHANGES, + "Auto-aplica los cambios hechos a los archivos shader del disco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, - "Mostrar opciones de rebobinado" - ) + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_SHOW_DECORATIONS, + "Mostrar Decoraciones de Ventanas" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, - "Muestra/oculta las opciones de rebobinado" - ) + MENU_ENUM_LABEL_VALUE_STATISTICS_SHOW, + "Mostrar Estadísticas" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_LATENCY, - "Muestra/oculta las opciones de latencia" - ) + MENU_ENUM_SUBLABEL_STATISTICS_SHOW, + "Mostrar estadísticas técnicas en pantalla" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_LATENCY, - "Mostrar opciones de latencia" - ) + MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_ENABLE, + "Activar relleno de borde" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_SHOW_OVERLAYS, - "Muestra/oculta las opciones de superposición" - ) + MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, + "Activar ancho del relleno de borde" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_OVERLAYS, - "Mostrar opciones de superposición" - ) + MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, + "Activar ancho del relleno de fondo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE_MENU, - "Activar el menu de audio" - ) + MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, + "Para pantallas CRT de 15 kHz. Intenta usar la resolución y refresco exactos del núcleo/juego" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_ENABLE_MENU, - "Activa o desactiva el menu de sonido" - ) + MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, + "CRT SwitchRes" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_SETTINGS, - "Opciones del mezclador" - ) + MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, + "Al activar CRT SwitchRes, forzar resolución ultrawide horizontal para minimizar el cambio de modos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_MIXER_SETTINGS, - "Ver o modificar las opciones del mezclador de audio" - ) + MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, + "Super Resolucion CRT" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_INFO, - "Info" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, + "Mostrar opciones de rebobinado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_FILE, - "&Archivo" - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, + "Muestra/oculta las opciones de rebobinado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_LOAD_CORE, - "&Cargar núcleo..." - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_LATENCY, + "Muestra/oculta las opciones de latencia" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_UNLOAD_CORE, - "&Descargar núcleo" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_LATENCY, + "Mostrar opciones de latencia" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_EXIT, - "&Salir" - ) + MENU_ENUM_SUBLABEL_CONTENT_SHOW_OVERLAYS, + "Muestra/oculta las opciones de superposición" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT, - "&Editar" - ) + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_OVERLAYS, + "Mostrar opciones de superposición" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT_SEARCH, - "&Buscar" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE_MENU, + "Activar el menu de audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW, - "&Ver" - ) + MENU_ENUM_SUBLABEL_AUDIO_ENABLE_MENU, + "Activa o desactiva el menu de sonido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_CLOSED_DOCKS, - "Docks cerrados" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_SETTINGS, + "Opciones del mezclador" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS, - "&Opciones..." - ) + MENU_ENUM_SUBLABEL_AUDIO_MIXER_SETTINGS, + "Ver o modificar las opciones del mezclador de audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS, - "Recordar las posiciones de dock:" - ) + MENU_ENUM_LABEL_VALUE_QT_INFO, + "Info" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY, - "Recordar la geometría de la ventana:" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE, + "&Archivo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB, - "Recordar la ultima pestaña de contenido:" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_LOAD_CORE, + "&Cargar núcleo..." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME, - "Tema" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_UNLOAD_CORE, + "&Descargar núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_SYSTEM_DEFAULT, - "" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_EXIT, + "&Salir" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK, - "Oscuro" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT, + "&Editar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM, - "Personalizado..." - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT_SEARCH, + "&Buscar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE, - "Opciones" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW, + "&Ver" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_LOAD_CUSTOM_CORE, - "Cargar nucleo personalizado..." - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_CLOSED_DOCKS, + "Docks cerrados" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_LOAD_CORE, - "Cargar núcleo" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_SHADER_PARAMS, + "Parámetros de Shader" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_LOADING_CORE, - "Cargando núcleo..." - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS, + "&Opciones..." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_NAME, - "Nombre" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS, + "Recordar las posiciones de dock:" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_CORE_VERSION, - "Versión" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY, + "Recordar la geometría de la ventana:" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_TAB_PLAYLISTS, - "Playlists" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB, + "Recordar la ultima pestaña de contenido:" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER, - "Explorador de archivos" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME, + "Tema" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_TOP, - "Inicio" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_SYSTEM_DEFAULT, + "" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_UP, - "Arriba" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK, + "Oscuro" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_DOCK_CONTENT_BROWSER, - "Explorador de contenido" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM, + "Personalizado..." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_BOXART, - "Caja" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE, + "Opciones" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_SCREENSHOT, - "Captura de pantalla" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_TOOLS, + "Herramien&tas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_TITLE_SCREEN, - "Pantalla de título" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP, + "A&yuda" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_ALL_PLAYLISTS, - "Todas las Playlists" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_ABOUT, + "Acerca de RetroArch" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_CORE, - "Núcleo" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_DOCUMENTATION, + "Documentación" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_CORE_INFO, - "Info de núcleo" - ) + MENU_ENUM_LABEL_VALUE_QT_LOAD_CUSTOM_CORE, + "Cargar nucleo personalizado..." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_CORE_SELECTION_ASK, - "" - ) + MENU_ENUM_LABEL_VALUE_QT_LOAD_CORE, + "Cargar núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_INFORMATION, - "Información" - ) + MENU_ENUM_LABEL_VALUE_QT_LOADING_CORE, + "Cargando núcleo..." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_WARNING, - "Advertencia" - ) + MENU_ENUM_LABEL_VALUE_QT_NAME, + "Nombre" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_ERROR, - "Error" - ) + MENU_ENUM_LABEL_VALUE_QT_CORE_VERSION, + "Versión" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_RESTART_TO_TAKE_EFFECT, - "Por favor reinicie el programa para que los cambios tengan efecto" - ) + MENU_ENUM_LABEL_VALUE_QT_TAB_PLAYLISTS, + "Playlists" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_LOG, - "Log" - ) + MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER, + "Explorador de archivos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_TOP, + "Inicio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_UP, + "Arriba" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_DOCK_CONTENT_BROWSER, + "Explorador de contenido" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_BOXART, + "Caja" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_SCREENSHOT, + "Captura de pantalla" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_TITLE_SCREEN, + "Pantalla de título" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ALL_PLAYLISTS, + "Todas las Playlists" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE, + "Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE_INFO, + "Info de núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE_SELECTION_ASK, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_INFORMATION, + "Información" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_WARNING, + "Advertencia" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ERROR, + "Error" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR, + "Error de red" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESTART_TO_TAKE_EFFECT, + "Por favor reinicie el programa para que los cambios tengan efecto" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOG, + "Log" + ) #ifdef HAVE_QT MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_SCAN_FINISHED, - "Escaneo Terminado.

\n" - "En orden para que el contenido sea correctamente escaneado, debes:\n" - "
  • tener un núcleo compatible descargado
  • \n" - "
  • tener los \"Archivos de información de núcleos\" actualizados
  • \n" - "
  • tener las \"Bases de datos\" actualizadas
  • \n" - "
  • reiniciar RetroArch si actualizaste algo con el \"Actualizador en línea\"
\n" - "Por último, el contenido debe coincidir las bases de datos existente de aquí. Si aún no funciona, considere enviar un reporte de error." - ) + MENU_ENUM_LABEL_VALUE_QT_SCAN_FINISHED, + "Escaneo Terminado.

\n" + "En orden para que el contenido sea correctamente escaneado, debes:\n" + "
  • tener un núcleo compatible descargado
  • \n" + "
  • tener los \"Archivos de información de núcleos\" actualizados
  • \n" + "
  • tener las \"Bases de datos\" actualizadas
  • \n" + "
  • reiniciar RetroArch si actualizaste algo con el \"Actualizador en línea\"
\n" + "Por último, el contenido debe coincidir las bases de datos existente de aquí. Si aún no funciona, considere enviar un reporte de error." + ) #endif MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, - "No mostrar esto de nuevo" - ) + MENU_ENUM_SUBLABEL_SHOW_WIMP, + "Abre el menú de escritorio si fue cerrado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_STOP, - "Detener" - ) + MENU_ENUM_LABEL_VALUE_SHOW_WIMP, + "Mostrar el menú de escritorio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE, - "Asociar núcleo" - ) + MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, + "No mostrar esto de nuevo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS, - "Playlists Ocultas" - ) + MENU_ENUM_LABEL_VALUE_QT_STOP, + "Detener" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_HIDE, - "Ocultar" - ) + MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE, + "Asociar núcleo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_HIGHLIGHT_COLOR, - "Color de resaltado" - ) + MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS, + "Playlists Ocultas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_CHOOSE, - "&Elegir..." - ) + MENU_ENUM_LABEL_VALUE_QT_HIDE, + "Ocultar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_SELECT_COLOR, - "Seleccionar Color" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_HIGHLIGHT_COLOR, + "Color de resaltado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_SELECT_THEME, - "Seleccionar tema" - ) + MENU_ENUM_LABEL_VALUE_QT_CHOOSE, + "&Elegir..." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_CUSTOM_THEME, - "Tema personalizado" - ) + MENU_ENUM_LABEL_VALUE_QT_SELECT_COLOR, + "Seleccionar Color" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_FILE_PATH_IS_BLANK, - "La dirección está vacía" - ) + MENU_ENUM_LABEL_VALUE_QT_SELECT_THEME, + "Seleccionar tema" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_FILE_IS_EMPTY, - "Archivo vacío" - ) + MENU_ENUM_LABEL_VALUE_QT_CUSTOM_THEME, + "Tema personalizado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_FILE_READ_OPEN_FAILED, - "No se pudo abrir el archivo para la lectura" - ) + MENU_ENUM_LABEL_VALUE_QT_FILE_PATH_IS_BLANK, + "La dirección está vacía" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST, - "El archivo no existe" - ) + MENU_ENUM_LABEL_VALUE_QT_FILE_IS_EMPTY, + "Archivo vacío" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SUGGEST_LOADED_CORE_FIRST, - "Sugerir el núcleo cargado primero" - ) + MENU_ENUM_LABEL_VALUE_QT_FILE_READ_OPEN_FAILED, + "No se pudo abrir el archivo para la lectura" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_ZOOM, - "Zoom" - ) + MENU_ENUM_LABEL_VALUE_QT_FILE_WRITE_OPEN_FAILED, + "No se pudo abrir el archivo para escribirlo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_VIEW, - "Vista" - ) + MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST, + "El archivo no existe" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_ICONS, - "Iconos" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SUGGEST_LOADED_CORE_FIRST, + "Sugerir el núcleo cargado primero" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_LIST, - "Lista" - ) + MENU_ENUM_LABEL_VALUE_QT_ZOOM, + "Zoom" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS, - "Personalizaciones" - ) + MENU_ENUM_LABEL_VALUE_QT_VIEW, + "Vista" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_QUICK_MENU_OVERRIDE_OPTIONS, - "Opciones para anular las configuraciones globales" - ) + MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_ICONS, + "Iconos" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY, - "Comenzara la reproducción de audio. Al finalizar, será quitado de la memoria" - ) + MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_LIST, + "Lista" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_LOOPED, - "Comenzara la reproducción de audio. Al finalizar, será reproducido nuevamente" - ) + MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS, + "Personalizaciones" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_SEQUENTIAL, - "Comenzara la reproducción de audio. Al finalizar, continuará con el siguiente, útil para albums" - ) + MENU_ENUM_SUBLABEL_QUICK_MENU_OVERRIDE_OPTIONS, + "Opciones para anular las configuraciones globales" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MIXER_ACTION_STOP, - "Detener la reproducción, no lo quitará de la memoria. Puedes continuar la reproducción" - ) + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY, + "Comenzara la reproducción de audio. Al finalizar, será quitado de la memoria" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MIXER_ACTION_REMOVE, - "Detener la reproducción y quitarlo de la memoria" - ) + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_LOOPED, + "Comenzara la reproducción de audio. Al finalizar, será reproducido nuevamente" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MIXER_ACTION_VOLUME, - "Ajusta el volumen del audio" - ) + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_SEQUENTIAL, + "Comenzara la reproducción de audio. Al finalizar, continuará con el siguiente, útil para albums" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ADD_TO_MIXER, - "Agrega esta pista de audio a una casilla, si no hay disponibles, se ignorará" - ) + MENU_ENUM_SUBLABEL_MIXER_ACTION_STOP, + "Detener la reproducción, no lo quitará de la memoria. Puedes continuar la reproducción" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ADD_TO_MIXER_AND_PLAY, - "Agrega esta pista de audio a una casilla, y la reproduce, si no hay disponibles, se ignorará" - ) + MENU_ENUM_SUBLABEL_MIXER_ACTION_REMOVE, + "Detener la reproducción y quitarlo de la memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY, - "Reproducir" - ) + MENU_ENUM_SUBLABEL_MIXER_ACTION_VOLUME, + "Ajusta el volumen del audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_LOOPED, - "Reproducir (Repetir)" - ) + MENU_ENUM_SUBLABEL_ADD_TO_MIXER, + "Agrega esta pista de audio a una casilla, si no hay disponibles, se ignorará" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_SEQUENTIAL, - "Reproducir (Secuencial)" - ) + MENU_ENUM_SUBLABEL_ADD_TO_MIXER_AND_PLAY, + "Agrega esta pista de audio a una casilla, y la reproduce, si no hay disponibles, se ignorará" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MIXER_ACTION_STOP, - "Detener" - ) + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY, + "Reproducir" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MIXER_ACTION_REMOVE, - "Quitar" - ) + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_LOOPED, + "Reproducir (Repetir)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MIXER_ACTION_VOLUME, - "Volumen" - ) + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_SEQUENTIAL, + "Reproducir (Secuencial)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DETECT_CORE_LIST_OK_CURRENT_CORE, - "Núcleo actual" - ) + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_STOP, + "Detener" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, - "Limpiar" - ) + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_REMOVE, + "Quitar" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ACHIEVEMENT_PAUSE, - "Pausar logros por esta sesión (Esto activará los archivos de guardado, cámara lenta, trucos, rebobinado y pausa)" - ) + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_VOLUME, + "Volumen" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_ACHIEVEMENT_RESUME, - "Continuar los logros para esta sesión (Esto desactivará los archivos de guardado, cámara lenta, trucos, rebobinado y pausa)" - ) + MENU_ENUM_LABEL_VALUE_DETECT_CORE_LIST_OK_CURRENT_CORE, + "Núcleo actual" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, - "En-Menú" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, + "Limpiar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, - "Activar Discord" - ) + MENU_ENUM_SUBLABEL_ACHIEVEMENT_PAUSE, + "Pausar logros por esta sesión (Esto activará los archivos de guardado, cámara lenta, trucos, rebobinado y pausa)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DISCORD_ALLOW, - "Activar o desactivar soporte de Discord. No funcionará en la versión web de RetroArch, solo en el cliente de escritorio" - ) + MENU_ENUM_SUBLABEL_ACHIEVEMENT_RESUME, + "Continuar los logros para esta sesión (Esto desactivará los archivos de guardado, cámara lenta, trucos, rebobinado y pausa)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MIDI_INPUT, - "Entrada" - ) + MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, + "En-Menú" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MIDI_INPUT, - "Seleccionar dispositivo de entrada" - ) + MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "En-Juego" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MIDI_OUTPUT, - "Salida" - ) + MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "En-Juego (Pausado)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MIDI_OUTPUT, - "Seleccionar dispositivo de salida" - ) + MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Jugando" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_MIDI_VOLUME, - "Volumen" - ) + MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Pausado" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MIDI_VOLUME, - "Establecer volumen de salida (%)" - ) + MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, + "Activar Discord" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_POWER_MANAGEMENT_SETTINGS, - "Energía" - ) + MENU_ENUM_SUBLABEL_DISCORD_ALLOW, + "Activar o desactivar soporte de Discord. No funcionará en la versión web de RetroArch, solo en el cliente de escritorio" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_POWER_MANAGEMENT_SETTINGS, - "Cambiar opciones de energía" - ) + MENU_ENUM_LABEL_VALUE_MIDI_INPUT, + "Entrada" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SUSTAINED_PERFORMANCE_MODE, - "Modo de rendimiento sostenido" - ) + MENU_ENUM_SUBLABEL_MIDI_INPUT, + "Seleccionar dispositivo de entrada" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_MPV_SUPPORT, - "Soporte de mpv" - ) + MENU_ENUM_LABEL_VALUE_MIDI_OUTPUT, + "Salida" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_IDX, - "Indice" - ) + MENU_ENUM_SUBLABEL_MIDI_OUTPUT, + "Seleccionar dispositivo de salida" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_MATCH_IDX, - "Ver coincidencia #" - ) + MENU_ENUM_LABEL_VALUE_MIDI_VOLUME, + "Volumen" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_MATCH, - "Coindidir dirección: %08X Máscara: %02X" - ) + MENU_ENUM_SUBLABEL_MIDI_VOLUME, + "Establecer volumen de salida (%)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_COPY_MATCH, - "Crear truco de coincidencia #" - ) + MENU_ENUM_LABEL_VALUE_POWER_MANAGEMENT_SETTINGS, + "Energía" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_MATCH, - "Borrar coincidencia #" - ) + MENU_ENUM_SUBLABEL_POWER_MANAGEMENT_SETTINGS, + "Cambiar opciones de energía" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_DESC, - "Descripción" - ) + MENU_ENUM_LABEL_VALUE_SUSTAINED_PERFORMANCE_MODE, + "Modo de rendimiento sostenido" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_STATE, - "Activado" - ) + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_MPV_SUPPORT, + "Soporte de mpv" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_CODE, - "Truco" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_IDX, + "Indice" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_HANDLER, - "Manipulador" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_MATCH_IDX, + "Ver coincidencia #" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_MEMORY_SEARCH_SIZE, - "Tamaño de la memoria de búsqueda" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_MATCH, + "Coindidir dirección: %08X Máscara: %02X" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_TYPE, - "Tipo" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_MATCH, + "Crear truco de coincidencia #" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_VALUE, - "Valor" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_MATCH, + "Borrar coincidencia #" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS, - "Dirección de memoria" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_BROWSE_MEMORY, + "Examinar dirección: %08X" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS_BIT_POSITION, - "Máscara de la dirección de memoria" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_DESC, + "Descripción" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_TYPE, - "Vibrar cuando memoria" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_STATE, + "Activado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_VALUE, - "Valor de vibración" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_CODE, + "Truco" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PORT, - "Puerto de vibración" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_HANDLER, + "Manipulador" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_STRENGTH, - "Fuerza primaria de vibración" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_MEMORY_SEARCH_SIZE, + "Tamaño de la memoria de búsqueda" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_DURATION, - "Duración (ms) de la vibración primaria" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_TYPE, + "Tipo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_STRENGTH, - "Fuerza secundaria de vibración" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_VALUE, + "Valor" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_DURATION, - "Duración (ms) de la vibración secundaria" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS, + "Dirección de memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_AFTER, - "Agregar nuevo truco después de este" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS_BIT_POSITION, + "Máscara de la dirección de memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BEFORE, - "Agregar nuevo truco antes de este" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_TYPE, + "Vibrar cuando memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_COPY_AFTER, - "Copiar este truco después" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_VALUE, + "Valor de vibración" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_COPY_BEFORE, - "Copiar este truco antes" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PORT, + "Puerto de vibración" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_DELETE, - "Borrar este truco" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_STRENGTH, + "Fuerza primaria de vibración" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_EMU, - "Emulador" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_DURATION, + "Duración (ms) de la vibración primaria" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_RETRO, - "RetroArch" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_STRENGTH, + "Fuerza secundaria de vibración" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_TYPE_DISABLED, - "" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_DURATION, + "Duración (ms) de la vibración secundaria" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_TYPE_SET_TO_VALUE, - "Establecer valor" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_AFTER, + "Agregar nuevo truco después de este" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_TYPE_INCREASE_VALUE, - "Aumentar por valor" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BEFORE, + "Agregar nuevo truco antes de este" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_TYPE_DECREASE_VALUE, - "Disminuir por valor" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_AFTER, + "Copiar este truco después" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_EQ, - "Ejecutar siguiente truco si el valor es igual a la memoria" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_BEFORE, + "Copiar este truco antes" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_NEQ, - "Ejecutar siguiente truco si el valor es distinto a la memoria" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE, + "Borrar este truco" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_LT, - "Ejecutar el siguiente truco si el valor es menor a la memoria" - ) + MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_EMU, + "Emulador" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_GT, - "Ejecutar el siguiente truco si el valor es mayor a la memoria" - ) + MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_RETRO, + "RetroArch" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_TYPE_DISABLED, - "" - ) + MENU_ENUM_LABEL_CHEAT_TYPE_DISABLED, + "" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_TYPE_CHANGES, - "Cambios" - ) + MENU_ENUM_LABEL_CHEAT_TYPE_SET_TO_VALUE, + "Establecer valor" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_TYPE_DOES_NOT_CHANGE, - "No cambia" - ) + MENU_ENUM_LABEL_CHEAT_TYPE_INCREASE_VALUE, + "Aumentar por valor" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_TYPE_INCREASE, - "Aumenta" - ) + MENU_ENUM_LABEL_CHEAT_TYPE_DECREASE_VALUE, + "Disminuir por valor" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_TYPE_DECREASE, - "Disminuye" - ) + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_EQ, + "Ejecutar siguiente truco si el valor es igual a la memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_TYPE_EQ_VALUE, - "Igual al valor de vibración" - ) + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_NEQ, + "Ejecutar siguiente truco si el valor es distinto a la memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_TYPE_NEQ_VALUE, - "Distinto al valor de vibración" - ) + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_LT, + "Ejecutar el siguiente truco si el valor es menor a la memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_TYPE_LT_VALUE, - "Menor al valor de vibración" - ) + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_GT, + "Ejecutar el siguiente truco si el valor es mayor a la memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_TYPE_GT_VALUE, - "Mayor al valor de vibración" - ) + MENU_ENUM_LABEL_RUMBLE_TYPE_DISABLED, + "" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_1, - "1-bit, valor máx. = 0x01" - ) + MENU_ENUM_LABEL_RUMBLE_TYPE_CHANGES, + "Cambios" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_2, - "2-bit, valor máx. = 0x03" - ) + MENU_ENUM_LABEL_RUMBLE_TYPE_DOES_NOT_CHANGE, + "No cambia" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_4, - "4-bit, valor máx. = 0x0F" - ) + MENU_ENUM_LABEL_RUMBLE_TYPE_INCREASE, + "Aumenta" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_8, - "8-bit, valor máx. = 0xFF" - ) + MENU_ENUM_LABEL_RUMBLE_TYPE_DECREASE, + "Disminuye" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_16, - "16-bit, valor máx. = 0xFFFF" - ) + MENU_ENUM_LABEL_RUMBLE_TYPE_EQ_VALUE, + "Igual al valor de vibración" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_32, - "32-bit, valor máx. = 0xFFFFFFFF" - ) + MENU_ENUM_LABEL_RUMBLE_TYPE_NEQ_VALUE, + "Distinto al valor de vibración" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_0, - "1" - ) + MENU_ENUM_LABEL_RUMBLE_TYPE_LT_VALUE, + "Menor al valor de vibración" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_1, - "2" - ) + MENU_ENUM_LABEL_RUMBLE_TYPE_GT_VALUE, + "Mayor al valor de vibración" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_2, - "3" - ) + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_1, + "1-bit, valor máx. = 0x01" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_3, - "4" - ) + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_2, + "2-bit, valor máx. = 0x03" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_4, - "5" - ) + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_4, + "4-bit, valor máx. = 0x0F" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_5, - "6" - ) + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_8, + "8-bit, valor máx. = 0xFF" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_6, - "7" - ) + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_16, + "16-bit, valor máx. = 0xFFFF" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_7, - "8" - ) + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_32, + "32-bit, valor máx. = 0xFFFFFFFF" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_8, - "9" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_0, + "1" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_9, - "10" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_1, + "2" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_10, - "11" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_2, + "3" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_11, - "12" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_3, + "4" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_12, - "13" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_4, + "5" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_13, - "14" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_5, + "6" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_14, - "15" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_6, + "7" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_15, - "16" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_7, + "8" + ) MSG_HASH( - MENU_ENUM_LABEL_RUMBLE_PORT_16, - "All" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_8, + "9" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_CONT, - "Inciar o continuar búsqueda de trucos" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_9, + "10" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_RESTART, - "Inciar o reiniciar búsqueda de trucos" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_10, + "11" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EXACT, - "Buscar valores de memoria" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_11, + "12" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LT, - "Buscar valores de memoria" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_12, + "13" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GT, - "Buscar valores de memoria" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_13, + "14" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQ, - "Buscar valores de memoria" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_14, + "15" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GTE, - "Buscar valores de memoria" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_15, + "16" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LTE, - "Buscar valores de memoria" - ) + MENU_ENUM_LABEL_RUMBLE_PORT_16, + "All" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_NEQ, - "Buscar valores de memoria" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_CONT, + "Inciar o continuar búsqueda de trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQPLUS, - "Buscar valores de memoria" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_RESTART, + "Inciar o reiniciar búsqueda de trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQMINUS, - "Buscar valores de memoria" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EXACT, + "Buscar valores de memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_ADD_MATCHES, - "Agregar las %u coincidencias a tu lista" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LT, + "Buscar valores de memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_VIEW_MATCHES, - "Ver lista de %u coincidencias" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GT, + "Buscar valores de memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_CREATE_OPTION, - "Crear truco de esta coincidencia" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQ, + "Buscar valores de memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_OPTION, - "Borrar esta coincidencia" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GTE, + "Buscar valores de memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_TOP, - "Agregar nuevo truco al principio" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LTE, + "Buscar valores de memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BOTTOM, - "Agregar nuevo truco al final" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_NEQ, + "Buscar valores de memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_ALL, - "Borrar todos los trucos" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQPLUS, + "Buscar valores de memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT_VAL, - "Igual a %u (%X)" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQMINUS, + "Buscar valores de memoria" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_SEARCH_LT_VAL, - "Menos que antes" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_MATCHES, + "Agregar las %u coincidencias a tu lista" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_SEARCH_GT_VAL, - "Más que antes" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_VIEW_MATCHES, + "Ver lista de %u coincidencias" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_SEARCH_LTE_VAL, - "Menos o igual que antes" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_CREATE_OPTION, + "Crear truco de esta coincidencia" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_SEARCH_GTE_VAL, - "Más o igual que antes" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_OPTION, + "Borrar esta coincidencia" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_SEARCH_EQ_VAL, - "Igual que antes" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_TOP, + "Agregar nuevo truco al principio" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ_VAL, - "Distinto que antes" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BOTTOM, + "Agregar nuevo truco al final" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS_VAL, - "Igual que antes+%u (%X)" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_ALL, + "Borrar todos los trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS_VAL, - "Igual que antes-%u (%X)" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_RELOAD_CHEATS, + "Recargar trucos específicos del juego" + ) MSG_HASH( - MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS, - "Iniciar o continuar búsqueda de trucos" - ) + MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT_VAL, + "Igual a %u (%X)" + ) MSG_HASH( - MSG_CHEAT_INIT_SUCCESS, - "Búsqueda de trucos iniciada correctamente" - ) + MENU_ENUM_LABEL_CHEAT_SEARCH_LT_VAL, + "Menos que antes" + ) MSG_HASH( - MSG_CHEAT_INIT_FAIL, - "Fallo al iniciar búsqueda de trucos" - ) + MENU_ENUM_LABEL_CHEAT_SEARCH_GT_VAL, + "Más que antes" + ) MSG_HASH( - MSG_CHEAT_SEARCH_NOT_INITIALIZED, - "La búsqueda no ha sido iniciada" - ) + MENU_ENUM_LABEL_CHEAT_SEARCH_LTE_VAL, + "Menos o igual que antes" + ) MSG_HASH( - MSG_CHEAT_SEARCH_FOUND_MATCHES, - "Número de coincidencias = %u" - ) + MENU_ENUM_LABEL_CHEAT_SEARCH_GTE_VAL, + "Más o igual que antes" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_BIG_ENDIAN, - "Big Endian" - ) + MENU_ENUM_LABEL_CHEAT_SEARCH_EQ_VAL, + "Igual que antes" + ) MSG_HASH( - MSG_CHEAT_SEARCH_ADDED_MATCHES_SUCCESS, - "Agregadas %u coincidencias" - ) + MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ_VAL, + "Distinto que antes" + ) MSG_HASH( - MSG_CHEAT_SEARCH_ADDED_MATCHES_FAIL, - "Fallo al agregar coincidencias" - ) + MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS_VAL, + "Igual que antes+%u (%X)" + ) MSG_HASH( - MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS, - "Truco creado desde coincidencia" - ) + MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS_VAL, + "Igual que antes-%u (%X)" + ) MSG_HASH( - MSG_CHEAT_SEARCH_ADD_MATCH_FAIL, - "Fallo al crear truco" - ) + MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS, + "Iniciar o continuar búsqueda de trucos" + ) MSG_HASH( - MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS, - "Borrar coincidencia" - ) + MSG_CHEAT_INIT_SUCCESS, + "Búsqueda de trucos iniciada correctamente" + ) MSG_HASH( - MSG_CHEAT_SEARCH_ADDED_MATCHES_TOO_MANY, - "No hay suficiente espacio. El máximo es 100 trucos" - ) + MSG_CHEAT_INIT_FAIL, + "Fallo al iniciar búsqueda de trucos" + ) MSG_HASH( - MSG_CHEAT_ADD_TOP_SUCCESS, - "Nuevo truco agregado al inicio de la lista" - ) + MSG_CHEAT_SEARCH_NOT_INITIALIZED, + "La búsqueda no ha sido iniciada" + ) MSG_HASH( - MSG_CHEAT_ADD_BOTTOM_SUCCESS, - "Nuevo truco agregado al final de la lista" - ) + MSG_CHEAT_SEARCH_FOUND_MATCHES, + "Número de coincidencias = %u" + ) MSG_HASH( - MSG_CHEAT_DELETE_ALL_INSTRUCTIONS, - "Presiona derecha cinco veces para borrar todos los trucos" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_BIG_ENDIAN, + "Big Endian" + ) MSG_HASH( - MSG_CHEAT_DELETE_ALL_SUCCESS, - "Todos los trucos fueron borrados" - ) + MSG_CHEAT_SEARCH_ADDED_MATCHES_SUCCESS, + "Agregadas %u coincidencias" + ) MSG_HASH( - MSG_CHEAT_ADD_BEFORE_SUCCESS, - "Nuevo truco agregado antes de este" - ) + MSG_CHEAT_SEARCH_ADDED_MATCHES_FAIL, + "Fallo al agregar coincidencias" + ) MSG_HASH( - MSG_CHEAT_ADD_AFTER_SUCCESS, - "Nuevo truco agregado después de este" - ) + MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS, + "Truco creado desde coincidencia" + ) MSG_HASH( - MSG_CHEAT_COPY_BEFORE_SUCCESS, - "Truco copiado antes de este" - ) + MSG_CHEAT_SEARCH_ADD_MATCH_FAIL, + "Fallo al crear truco" + ) MSG_HASH( - MSG_CHEAT_COPY_AFTER_SUCCESS, - "Truco copiado después de este" - ) + MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS, + "Borrar coincidencia" + ) MSG_HASH( - MSG_CHEAT_DELETE_SUCCESS, - "Truco borrado" - ) + MSG_CHEAT_SEARCH_ADDED_MATCHES_TOO_MANY, + "No hay suficiente espacio. El máximo es 100 trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_PROGRESS, - "Progreso:" - ) + MSG_CHEAT_ADD_TOP_SUCCESS, + "Nuevo truco agregado al inicio de la lista" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_LIST_MAX_COUNT, - "\"Todas la Playlists\" máximo de entradas en lista:" - ) + MSG_CHEAT_ADD_BOTTOM_SUCCESS, + "Nuevo truco agregado al final de la lista" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_GRID_MAX_COUNT, - "\"Todas la Playlists\" máximo de entradas en grilla:" - ) + MSG_CHEAT_DELETE_ALL_INSTRUCTIONS, + "Presiona derecha cinco veces para borrar todos los trucos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SHOW_HIDDEN_FILES, - "Mostrar elementos ocultos" - ) + MSG_CHEAT_DELETE_ALL_SUCCESS, + "Todos los trucos fueron borrados" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST, - "Nueva Playlist" - ) + MSG_CHEAT_ADD_BEFORE_SUCCESS, + "Nuevo truco agregado antes de este" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_ENTER_NEW_PLAYLIST_NAME, - "Por favor ingrese el nombre de la nueva Playlist:" - ) + MSG_CHEAT_ADD_AFTER_SUCCESS, + "Nuevo truco agregado después de este" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_DELETE_PLAYLIST, - "Borrar Playlist" - ) + MSG_CHEAT_COPY_BEFORE_SUCCESS, + "Truco copiado antes de este" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST, - "¿Está seguro que desea borrar la playlist \"%1\"?" - ) + MSG_CHEAT_COPY_AFTER_SUCCESS, + "Truco copiado después de este" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_QUESTION, - "Pregunta" - ) + MSG_CHEAT_DELETE_SUCCESS, + "Truco borrado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_DELETE_FILE, - "No se pudo borrar el archivo" - ) + MENU_ENUM_LABEL_VALUE_QT_PROGRESS, + "Progreso:" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_GATHERING_LIST_OF_FILES, - "Cargando lista de archivos..." - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_LIST_MAX_COUNT, + "\"Todas la Playlists\" máximo de entradas en lista:" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_ADDING_FILES_TO_PLAYLIST, - "Agregando archivos a la Playlist..." - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_GRID_MAX_COUNT, + "\"Todas la Playlists\" máximo de entradas en grilla:" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY, - "Entrada de la Playlist" - ) + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SHOW_HIDDEN_FILES, + "Mostrar elementos ocultos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_CORE, - "Núcleo:" - ) + MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST, + "Nueva Playlist" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_DATABASE, - "Base de datos:" - ) + MENU_ENUM_LABEL_VALUE_QT_ENTER_NEW_PLAYLIST_NAME, + "Por favor ingrese el nombre de la nueva Playlist:" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_FOR_THUMBNAILS, - "(usado pata buscar miniaturas)" - ) + MENU_ENUM_LABEL_VALUE_QT_DELETE_PLAYLIST, + "Borrar Playlist" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST_ITEM, - "¿Está seguro que desea borrar \"%1\"?" - ) + MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST, + "¿Está seguro que desea borrar la playlist \"%1\"?" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_CANNOT_ADD_TO_ALL_PLAYLISTS, - "Por favor primero elija solo una Playlist" - ) + MENU_ENUM_LABEL_VALUE_QT_QUESTION, + "Pregunta" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_QT_DELETE, - "Borrar" - ) + MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_DELETE_FILE, + "No se pudo borrar el archivo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_RENAME_FILE, + "No se pudo renombrar el archivo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_GATHERING_LIST_OF_FILES, + "Cargando lista de archivos..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADDING_FILES_TO_PLAYLIST, + "Agregando archivos a la Playlist..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY, + "Entrada de la Playlist" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_NAME, + "Nombre:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_PATH, + "Ruta:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_CORE, + "Núcleo:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_DATABASE, + "Base de datos:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FOR_THUMBNAILS, + "(usado pata buscar miniaturas)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST_ITEM, + "¿Está seguro que desea borrar \"%1\"?" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CANNOT_ADD_TO_ALL_PLAYLISTS, + "Por favor primero elija solo una Playlist" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DELETE, + "Borrar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADD_ENTRY, + "Agregar entrada..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADD_FILES, + "Agregar archivo(s)..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADD_FOLDER, + "Agregar carpeta..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_EDIT, + "Editar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_FILES, + "Seleccionar archivos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_FOLDER, + "Seleccionar carpeta" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FIELD_MULTIPLE, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_UPDATE_PLAYLIST_ENTRY, + "Error actualizando la entrada de la playlist" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLEASE_FILL_OUT_REQUIRED_FIELDS, + "Por favor rellene todos los campos obligatorios" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_NIGHTLY, + "Actualizar RetroArch (nightly)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FINISHED, + "RetroArch actualizado correctamente. Reinicie la aplicación para que los cambios tengan efecto" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FAILED, + "Actualización fallida" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_ABOUT_CONTRIBUTORS, + "Contribuyentes" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CURRENT_SHADER, + "Shader actual" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MOVE_DOWN, + "Mover abajo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MOVE_UP, + "Mover arriba" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOAD, + "Cargar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SAVE, + "Save" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_REMOVE, + "Quitar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_APPLY, + "Aplicar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SHADER_ADD_PASS, + "Agregar pasada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SHADER_CLEAR_ALL_PASSES, + "Quitar todas las pasadas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SHADER_NO_PASSES, + "No hay pasadas de shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESET_PASS, + "Restablecer pasada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESET_ALL_PASSES, + "Restablecer todas las pasadas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESET_PARAMETER, + "Restablecer parámetro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_THUMBNAIL, + "Descargar miniatura" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALREADY_IN_PROGRESS, + "Ya hay un descarga en progreso" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_STARTUP_PLAYLIST, + "Empezar en esta Playlist:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS, + "Descargar todas las miniaturas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_ENTIRE_SYSTEM, + "Sistema completo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_THIS_PLAYLIST, + "Esta Playlist" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_PACK_DOWNLOADED_SUCCESSFULLY, + "Miniaturas descargadas correctamente" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_PLAYLIST_THUMBNAIL_PROGRESS, + "Exitos: %1 Fallos: %2" + ) +MSG_HASH( + MSG_DEVICE_CONFIGURED_IN_PORT, + "Configurado en puerto:" + ) +MSG_HASH( + MSG_FAILED_TO_SET_DISK, + "Fallo al establecer disco" + ) diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index d0b3503a0b..b5d3ab766a 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -3266,9 +3266,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Enable background filler thickness") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For 15 kHz CRT displays only. Attempts to use exact core/game resolution and refresh rate.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "When CRT SwitchRes is enabled, force ultrawide horizontal resolution to minimize mode switching.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, "Show Rewind Settings") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, @@ -3327,6 +3327,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Clear") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Enable Discord" diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index bb5b06fdbd..ec334aef13 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -3326,9 +3326,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Abilita lo spessore del riempimento dello sfondo") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "Solo per schermi CRT a 15 kHz. Tenta di utilizzare la risoluzione esatta core/gioco e la frequenza di aggiornamento.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "Quando CRT SwitchRes è abilitato, forza la risoluzione orizzontale ultrawide per minimizzare il cambio di modalità.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Risoluzione") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Risoluzione") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, "Mostra impostazioni di riavvolgimento") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, @@ -3387,6 +3387,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Cancella") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Abilita Discord" diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index 6612b1adba..b58764d5ea 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -3500,6 +3500,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW, "表示(&V)") MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_CLOSED_DOCKS, "閉じたドック") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_SHADER_PARAMS, + "シェーダーのパラメータ") MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS, "設定(&O)...") MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS, @@ -3660,6 +3662,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "クリア") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Discordを有効" @@ -3752,3 +3762,47 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FAILED, "更新に失敗しました。") MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_ABOUT_CONTRIBUTORS, "作成者") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CURRENT_SHADER, + "現在のシェーダー") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MOVE_DOWN, + "下へ移動") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MOVE_UP, + "上へ移動") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOAD, + "ロード") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SAVE, + "保存") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_REMOVE, + "取り除く") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_APPLY, + "適用") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SHADER_ADD_PASS, + "パスを追加") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SHADER_CLEAR_ALL_PASSES, + "すべてのパスを取り除く") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SHADER_NO_PASSES, + "シェーダーパスはありません。") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_RESET_PASS, + "このパスをリセット") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_RESET_ALL_PASSES, + "すべてのパスをリセット") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_RESET_PARAMETER, + "パラメータをリセット") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_THUMBNAIL, + "サムネイルをダウンロード") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALREADY_IN_PROGRESS, + "他のダウンロードが実行中です。") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_STARTUP_PLAYLIST, + "起動時に表示するプレイリスト:") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS, + "すべてのサムネイルをダウンロード") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_ENTIRE_SYSTEM, + "システムのすべて") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_THIS_PLAYLIST, + "このプレイリスト") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_PACK_DOWNLOADED_SUCCESSFULLY, + "サムネイルのダウンロードが成功しました。") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_PLAYLIST_THUMBNAIL_PROGRESS, + "成功した数: %1 失敗した数: %2") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE_OPTIONS, + "コア設定") diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index 31c7e48614..f867b18e6c 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -3227,9 +3227,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Enable background filler thickness") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For 15 kHz CRT displays only. Attempts to use exact core/game resolution and refresh rate.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "When CRT SwitchRes is enabled, force ultrawide horizontal resolution to minimize mode switching.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, "Show Rewind Settings") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, @@ -3288,6 +3288,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Clear") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Enable Discord" diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 1077bb08a3..1dac8eef33 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1141,10 +1141,10 @@ MSG_HASH(MENU_ENUM_LABEL_USE_THIS_DIRECTORY, "use_this_directory") MSG_HASH(MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE, "video_allow_rotate") -MSG_HASH(MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION, - "crt_switch_resolution") -MSG_HASH(MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER, - "crt_switch_resolution_super") +MSG_HASH(MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION, + "crt_switch_resolution") +MSG_HASH(MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER, + "crt_switch_resolution_super") MSG_HASH(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO, "video_aspect_ratio") MSG_HASH(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_AUTO, @@ -1545,6 +1545,14 @@ MSG_HASH(MENU_ENUM_LABEL_DEFERRED_QUICK_MENU_OVERRIDE_OPTIONS, "deferred_quick_menu_override_options") MSG_HASH(MENU_ENUM_LABEL_DISCORD_IN_MENU, "discord_in_menu") +MSG_HASH(MENU_ENUM_LABEL_DISCORD_IN_GAME, + "discord_in_game") +MSG_HASH(MENU_ENUM_LABEL_DISCORD_IN_GAME_PAUSED, + "discord_in_game_paused") +MSG_HASH(MENU_ENUM_LABEL_DISCORD_STATUS_PLAYING, + "discord_status_playing") +MSG_HASH(MENU_ENUM_LABEL_DISCORD_STATUS_PAUSED, + "discord_status_paused") MSG_HASH(MENU_ENUM_LABEL_MIDI_INPUT, "midi_input") MSG_HASH(MENU_ENUM_LABEL_MIDI_OUTPUT, diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index 4fcbdd1f8a..63f5d9db7a 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -3109,9 +3109,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Enable background filler thickness") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For 15 kHz CRT displays only. Attempts to use exact core/game resolution and refresh rate.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "When CRT SwitchRes is enabled, force ultrawide horizontal resolution to minimize mode switching.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, "Show Rewind Settings") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, @@ -3170,6 +3170,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Clear") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Enable Discord" diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index e929c3004e..a5f446850f 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -3524,10 +3524,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, "Włącz grubość wypełniacza") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Włącz grubość wypełniacza tła") -MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "Tylko dla wyświetlaczy CRT 15 kHz. Próby użycia dokładnej rozdzielczości rdzenia/gry i częstotliwości odświeżania.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT Przełącz rozdzielczość") -MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "Po włączeniu przełączników CRT wymuś ultrafioletową rozdzielczość poziomą, aby zminimalizować przełączanie trybu.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super rozdzielczość") +MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "Tylko dla wyświetlaczy CRT 15 kHz. Próby użycia dokładnej rozdzielczości rdzenia/gry i częstotliwości odświeżania.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT Przełącz rozdzielczość") +MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "Po włączeniu przełączników CRT wymuś ultrafioletową rozdzielczość poziomą, aby zminimalizować przełączanie trybu.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super rozdzielczość") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, "Pokaż ustawienia przewijania") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, @@ -3586,6 +3586,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Oczyść") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "W Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "W Grze") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "W Grze (Wstrzymano)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Gra") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Wstrzymano") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Włącz Discord" diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index 1ce0e087c4..7b8204db0a 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -1,3742 +1,7397 @@ MSG_HASH( - MSG_COMPILER, - "Compilador" - ) + MSG_COMPILER, + "Compilador" + ) MSG_HASH( - MSG_UNKNOWN_COMPILER, - "Compilador desconhecido" - ) + MSG_UNKNOWN_COMPILER, + "Compilador desconhecido" + ) MSG_HASH( - MSG_DEVICE_DISCONNECTED_FROM_PORT, - "Dispositivo desconectado da porta" - ) + MSG_DEVICE_DISCONNECTED_FROM_PORT, + "Dispositivo desconectado da porta" + ) MSG_HASH( - MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, - "Comando Netplay desconhecido recebido" - ) + MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, + "Recebido um comando de jogo em rede desconhecido" + ) MSG_HASH( - MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER, - "Este arquivo já existe. Salvando no buffer de backup" - ) + MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER, + "Este arquivo já existe. Salvando no buffer de backup" + ) MSG_HASH( - MSG_GOT_CONNECTION_FROM, - "Conexão recebida de: \"%s\"" - ) + MSG_GOT_CONNECTION_FROM, + "Conexão recebida de: \"%s\"" + ) MSG_HASH( - MSG_GOT_CONNECTION_FROM_NAME, - "Conexão recebida de: \"%s (%s)\"" - ) + MSG_GOT_CONNECTION_FROM_NAME, + "Conexão recebida de: \"%s (%s)\"" + ) MSG_HASH( - MSG_PUBLIC_ADDRESS, - "Endereço público" - ) + MSG_PUBLIC_ADDRESS, + "Endereço público" + ) MSG_HASH( - MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, - "Nenhum argumento fornecido e nenhum menu interno, exibindo ajuda..." - ) + MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, + "Nenhum argumento fornecido e nenhum menu interno, exibindo ajuda..." + ) MSG_HASH( - MSG_SETTING_DISK_IN_TRAY, - "Definindo disco na bandeja" - ) + MSG_SETTING_DISK_IN_TRAY, + "Definindo disco na bandeja" + ) MSG_HASH( - MSG_WAITING_FOR_CLIENT, - "Aguardando pelo cliente..." - ) + MSG_WAITING_FOR_CLIENT, + "Aguardando pelo cliente..." + ) MSG_HASH( - MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME, - "Você deixou o jogo" - ) + MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME, + "Você deixou o jogo" + ) MSG_HASH( - MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N, - "Você se juntou como jogador %u" - ) + MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N, + "Você se juntou como jogador %u" + ) MSG_HASH( - MSG_NETPLAY_YOU_HAVE_JOINED_WITH_INPUT_DEVICES_S, - "Você se juntou aos dispositivos de entrada %.*s" - ) + MSG_NETPLAY_YOU_HAVE_JOINED_WITH_INPUT_DEVICES_S, + "Você se juntou ao dispositivo de entrada %.*s" + ) MSG_HASH( - MSG_NETPLAY_PLAYER_S_LEFT, - "O jogador %.*s deixou o jogo" - ) + MSG_NETPLAY_PLAYER_S_LEFT, + "O jogador %.*s deixou o jogo" + ) MSG_HASH( - MSG_NETPLAY_S_HAS_JOINED_AS_PLAYER_N, - "%.*s se juntou como jogador %u" - ) + MSG_NETPLAY_S_HAS_JOINED_AS_PLAYER_N, + "%.*s se juntou como jogador %u" + ) MSG_HASH( - MSG_NETPLAY_S_HAS_JOINED_WITH_INPUT_DEVICES_S, - "%.*s juntou-se a dispositivos de entrada %.*s" - ) + MSG_NETPLAY_S_HAS_JOINED_WITH_INPUT_DEVICES_S, + "%.*s juntou-se aos dispositivos de entrada %.*s" + ) MSG_HASH( - MSG_NETPLAY_NOT_RETROARCH, - "Uma tentativa de conexão com o netplay falhou porque o par não está executando o RetroArch ou está executando uma versão antiga do RetroArch." - ) + MSG_NETPLAY_NOT_RETROARCH, + "Uma tentativa de conexão de jogo em rede falhou porque o par não está executando o RetroArch ou está executando uma versão antiga do RetroArch." + ) MSG_HASH( - MSG_NETPLAY_OUT_OF_DATE, - "O par netplay está executando uma versão antiga do RetroArch. Não pode conectar." - ) + MSG_NETPLAY_OUT_OF_DATE, + "O par de jogo em rede está executando uma versão antiga do RetroArch. Não é possível conectar." + ) MSG_HASH( - MSG_NETPLAY_DIFFERENT_VERSIONS, - "ATENÇÃO: Um par de Netplay está executando uma versão diferente do RetroArch. Se ocorrerem problemas, use a mesma versão." - ) + MSG_NETPLAY_DIFFERENT_VERSIONS, + "ATENÇÃO: Um par de jogo em rede está executando uma versão diferente do RetroArch. Se ocorrerem problemas, use a mesma versão." + ) MSG_HASH( - MSG_NETPLAY_DIFFERENT_CORES, - "Um par de netplay está executando um núcleo diferente. Não pode conectar." - ) + MSG_NETPLAY_DIFFERENT_CORES, + "Um par de jogo em rede está executando um núcleo diferente. Não é possível conectar." + ) MSG_HASH( - MSG_NETPLAY_DIFFERENT_CORE_VERSIONS, - "ATENÇÃO: Um par de Netplay está executando uma versão diferente do núcleo. Se ocorrerem problemas, use a mesma versão." - ) + MSG_NETPLAY_DIFFERENT_CORE_VERSIONS, + "ATENÇÃO: Um par de jogo em rede está executando uma versão diferente do núcleo. Se ocorrerem problemas, use a mesma versão." + ) MSG_HASH( - MSG_NETPLAY_ENDIAN_DEPENDENT, - "Este núcleo não suporta Netplay inter-arquitetura entre estes sistemas" - ) + MSG_NETPLAY_ENDIAN_DEPENDENT, + "Este núcleo não suporta jogo em rede entre diferentes arquiteturas de sistemas" + ) MSG_HASH( - MSG_NETPLAY_PLATFORM_DEPENDENT, - "Este núcleo não suporta Netplay inter-arquitetura" - ) + MSG_NETPLAY_PLATFORM_DEPENDENT, + "Este núcleo não suporta jogo em rede entre diferentes sistemas" + ) MSG_HASH( - MSG_NETPLAY_ENTER_PASSWORD, - "Digite a senha do servidor de Netplay:" - ) + MSG_NETPLAY_ENTER_PASSWORD, + "Digite a senha do servidor de jogo em rede:" + ) MSG_HASH( - MSG_NETPLAY_INCORRECT_PASSWORD, - "Senha incorreta" - ) + MSG_NETPLAY_INCORRECT_PASSWORD, + "Senha incorreta" + ) MSG_HASH( - MSG_NETPLAY_SERVER_NAMED_HANGUP, - "\"%s\" desconectou" - ) + MSG_NETPLAY_SERVER_NAMED_HANGUP, + "\"%s\" desconectou" + ) MSG_HASH( - MSG_NETPLAY_SERVER_HANGUP, - "Um cliente do Netplay desconectou" - ) + MSG_NETPLAY_SERVER_HANGUP, + "Um cliente de jogo em rede desconectou" + ) MSG_HASH( - MSG_NETPLAY_CLIENT_HANGUP, - "Desconectado do Netplay" - ) + MSG_NETPLAY_CLIENT_HANGUP, + "Desconectado do jogo em rede" + ) MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED, - "Você não tem permissão para jogar" - ) + MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED, + "Você não tem permissão para jogar" + ) MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS, - "Não há vagas livres para jogadores" - ) + MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS, + "Não há vagas livres para jogadores" + ) MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY_NOT_AVAILABLE, - "Os dispositivos de entrada solicitados não estão disponíveis" - ) + MSG_NETPLAY_CANNOT_PLAY_NOT_AVAILABLE, + "Os dispositivos de entrada solicitados não estão disponíveis" + ) MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY, - "Impossível alterar para modo jogador" - ) + MSG_NETPLAY_CANNOT_PLAY, + "Impossível alterar para modo jogador" + ) MSG_HASH( - MSG_NETPLAY_PEER_PAUSED, - "Par do Netplay \"%s\" pausou" - ) + MSG_NETPLAY_PEER_PAUSED, + "Par do jogo em rede \"%s\" pausou" + ) MSG_HASH( - MSG_NETPLAY_CHANGED_NICK, - "Seu apelido mudou para \"%s\"" - ) + MSG_NETPLAY_CHANGED_NICK, + "Seu apelido mudou para \"%s\"" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, - "Dar aos núcleos renderizados por hardware seu próprio contexto privado. Evita ter que assumir mudanças de estado de hardware entre quadros." - ) + MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, + "Dar aos núcleos renderizados por hardware seu próprio contexto privado. Evita ter que assumir mudanças de estado de hardware entre quadros." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SETTINGS, - "Ajusta as configurações de aparência da tela de menu." - ) + MENU_ENUM_SUBLABEL_MENU_SETTINGS, + "Ajusta as configurações de aparência da tela de menu." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, - "Sincronia rígida entre CPU e GPU. Reduz a latência ao custo de desempenho." - ) + MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, + "Sincronia rígida entre CPU e GPU. Reduz a latência ao custo de desempenho." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_THREADED, - "Melhora o desempenho ao custo de latência e mais engasgamento de vídeo. Use somente se você não puder obter velocidade total de outra forma." - ) + MENU_ENUM_SUBLABEL_VIDEO_THREADED, + "Melhora o desempenho ao custo de latência e mais engasgamento de vídeo. Use somente se você não puder obter velocidade total de outra forma." + ) MSG_HASH( - MSG_AUDIO_VOLUME, - "Volume de áudio" - ) + MSG_AUDIO_VOLUME, + "Volume de áudio" + ) MSG_HASH( - MSG_AUTODETECT, - "Detectar automaticamente" - ) + MSG_AUTODETECT, + "Detectar automaticamente" + ) MSG_HASH( - MSG_AUTOLOADING_SAVESTATE_FROM, - "Autocarregando Estado de Jogo de" - ) + MSG_AUTOLOADING_SAVESTATE_FROM, + "Autocarregando Estado de Jogo de" + ) MSG_HASH( - MSG_CAPABILITIES, - "Capacidades" - ) + MSG_CAPABILITIES, + "Capacidades" + ) MSG_HASH( - MSG_CONNECTING_TO_NETPLAY_HOST, - "Conectando ao hospedeiro de Netplay" - ) + MSG_CONNECTING_TO_NETPLAY_HOST, + "Conectando ao hospedeiro de jogo em rede" + ) MSG_HASH( - MSG_CONNECTING_TO_PORT, - "Conectando a porta" - ) + MSG_CONNECTING_TO_PORT, + "Conectando a porta" + ) MSG_HASH( - MSG_CONNECTION_SLOT, - "Vaga de conexão" - ) + MSG_CONNECTION_SLOT, + "Vaga de conexão" + ) MSG_HASH( - MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY, - "Desculpe, não implementado: núcleos que não exigem conteúdo não podem participar do Netplay." - ) + MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY, + "Desculpe, não implementado: núcleos que não exigem conteúdo não podem participar do jogo em rede." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, - "Senha" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, + "Senha" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, - "Contas Cheevos" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, + "Contas Cheevos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, - "Nome de usuário" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, + "Nome de usuário" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, - "Contas" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, + "Contas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST_END, - "Ponto Final da Lista de Contas" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST_END, + "Ponto Final da Lista de Contas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, - "Retro Achievements" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, + "Retro Achievements" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, - "Lista de Conquistas" - ) + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, + "Lista de Conquistas" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_PAUSE, - "Pausar Conquistas no Modo Hardcore" - ) + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_PAUSE, + "Pausar Conquistas no Modo Hardcore" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_RESUME, - "Contiuar Conquistas no Modo Hardcore" - ) + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_RESUME, + "Contiuar Conquistas no Modo Hardcore" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, - "Lista de Conquistas (Hardcore)" - ) + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, + "Lista de Conquistas (Hardcore)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, - "Analisar Conteúdo" - ) + MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, + "Analisar Conteúdo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIGURATIONS_LIST, - "Configurações" - ) + MENU_ENUM_LABEL_VALUE_CONFIGURATIONS_LIST, + "Configurações" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_TAB, - "Importar conteúdo" - ) + MENU_ENUM_LABEL_VALUE_ADD_TAB, + "Importar conteúdo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, - "Salas de Netplay" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, + "Salas de Jogo em Rede" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, - "Perguntar" - ) + MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, + "Perguntar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, - "Recursos" - ) + MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, + "Recursos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, - "Bloquear Quadros" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, + "Bloquear Quadros" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, - "Dispositivo de Áudio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, + "Dispositivo de Áudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_DRIVER, - "Driver de Áudio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_DRIVER, + "Driver de Áudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_DSP_PLUGIN, - "Plugin DSP de Áudio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_DSP_PLUGIN, + "Plugin DSP de Áudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE, - "Habilitar Áudio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE, + "Habilitar Áudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, - "Filtro de Áudio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, + "Filtro de Áudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, - "Turbo/Zona-Morta" - ) + MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, + "Turbo/Zona-Morta" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_LATENCY, - "Latência de Áudio (ms)" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_LATENCY, + "Latência de Áudio (ms)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MAX_TIMING_SKEW, - "Desvio Máximo de Tempo do Áudio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_MAX_TIMING_SKEW, + "Desvio Máximo de Tempo do Áudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MUTE, - "Áudio Mudo" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_MUTE, + "Silenciar Áudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_OUTPUT_RATE, - "Taxa da Saída de Áudio (Hz)" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_OUTPUT_RATE, + "Taxa da Saída de Áudio (Hz)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_RATE_CONTROL_DELTA, - "Controle Dinâmico da Taxa de Áudio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_RATE_CONTROL_DELTA, + "Controle Dinâmico da Taxa de Áudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_DRIVER, - "Driver de Reamostragem de Áudio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_DRIVER, + "Driver de Reamostragem de Áudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, - "Áudio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, + "Áudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, - "Sincronizar Áudio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, + "Sincronizar Áudio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_VOLUME, - "Nível de Volume de Áudio (dB)" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_VOLUME, + "Nível de Volume de Áudio (dB)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_EXCLUSIVE_MODE, - "WASAPI Modo Exclusivo" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_EXCLUSIVE_MODE, + "WASAPI Modo Exclusivo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_FLOAT_FORMAT, - "WASAPI Formato de Ponto Flutuante" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_FLOAT_FORMAT, + "WASAPI Formato de Ponto Flutuante" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_SH_BUFFER_LENGTH, - "WASAPI Tamanho do Buffer Compartilhado" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_SH_BUFFER_LENGTH, + "WASAPI Tamanho do Buffer Compartilhado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, - "Intervalo do Salvamento Automático da SRAM" - ) + MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, + "Intervalo do Salvamento Automático da SRAM" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, - "Carrega Automaticamente Arquivos de Redefinição" - ) + MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, + "Carrega Automaticamente Arquivos de Redefinição" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE, - "Carrega Automaticamente Arquivos de Remapeamento" - ) + MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE, + "Carrega Automaticamente Arquivos de Remapeamento" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, - "Carrega Automaticamente Predefinições de Shader" - ) + MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, + "Carrega Automaticamente Predefinições de Shader" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, - "Voltar" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, + "Voltar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, - "Confirmar" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, + "Confirmar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, - "Informações" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, + "Informações" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, - "Sair" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, + "Sair" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_DOWN, - "Rolar para Baixo" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_DOWN, + "Rolar para Baixo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_UP, - "Rolar para Cima" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_UP, + "Rolar para Cima" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, - "Iniciar" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, + "Iniciar" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, - "Alternar Teclado" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, + "Alternar Teclado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_MENU, - "Alternar Menu" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_MENU, + "Alternar Menu" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS, - "Controles Básicos de Menu" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS, + "Controles Básicos de Menu" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_CONFIRM, - "Confirmar/OK" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_CONFIRM, + "Confirmar/OK" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_INFO, - "Informação" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_INFO, + "Informação" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_QUIT, - "Sair" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_QUIT, + "Sair" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_SCROLL_UP, - "Rolar para Cima" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_SCROLL_UP, + "Rolar para Cima" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_START, - "Padrões" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_START, + "Padrões" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_KEYBOARD, - "Alternar Teclado" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_KEYBOARD, + "Alternar Teclado" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_MENU, - "Alternar Menu" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_MENU, + "Alternar Menu" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BLOCK_SRAM_OVERWRITE, - "Não sobregravar a SRAM ao carregar Estado de Jogo" - ) + MENU_ENUM_LABEL_VALUE_BLOCK_SRAM_OVERWRITE, + "Não sobregravar a SRAM ao carregar Estado de Jogo" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BLUETOOTH_ENABLE, - "Habilitar Bluetooth" - ) + MENU_ENUM_LABEL_VALUE_BLUETOOTH_ENABLE, + "Habilitar Bluetooth" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, - "URL de Recursos do Buildbot" - ) + MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, + "URL de Recursos do Buildbot" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY, - "Cache" - ) + MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY, + "Cache" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CAMERA_ALLOW, - "Permitir Câmera" - ) + MENU_ENUM_LABEL_VALUE_CAMERA_ALLOW, + "Permitir Câmera" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, - "Driver de Câmera" - ) + MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, + "Driver de Câmera" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT, - "Trapaça" - ) + MENU_ENUM_LABEL_VALUE_CHEAT, + "Trapaça" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, - "Aplicar Alterações" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, + "Aplicar Alterações" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, - "Arquivo de Trapaça" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_START_SEARCH, + "Iniciar Pesquisa Por um Novo Código de Trapaça" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE, - "Arquivo de Trapaça" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_CONTINUE_SEARCH, + "Continuar Pesquisa" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD, - "Carregar Arquivo de Trapaça" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, - "Salvar Arquivo de Trapaça Como" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, - "Estágios de Trapaça" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION, - "Descrição" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, - "Conquistas no Modo Hardcore" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_ENABLE, - "Tabelas de Classificação" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_BADGES_ENABLE, - "Insígnias de Conquistas" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, - "Conquistas Bloqueadas:" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY, - "Bloqueada" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS, - "Retro Achievements" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL, - "Testar Conquistas Não Oficiais" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS, - "Conquistas Desbloqueadas:" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY, - "Desbloqueada" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY_HARDCORE, - "Hardcore" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_VERBOSE_ENABLE, - "Modo Detalhado das Conquistas" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_AUTO_SCREENSHOT, - "Captura de Conquistas Automática" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, - "Fechar Conteúdo" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIG, - "Configuração" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIGURATIONS, - "Carregar Configuração" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS, - "Configuração" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, - "Salvar Configuração ao Sair" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Coleções" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, - "Base de Dados" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_DIR, - "Conteúdo" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, - "Tamanho da Lista de Histórico") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_REMOVE, - "Permitir a remoção de itens") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS, - "Menu Rápido") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIR, - "Recursos de Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIRECTORY, - "Downloads") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS, - "Trapaças") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_COUNTERS, - "Contadores do Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ENABLE, - "Exibir nome do núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION, - "Informação do Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_AUTHORS, - "Autores") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CATEGORIES, - "Categorias") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_LABEL, - "Rótulo do núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_NAME, - "Nome do núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE, - "Firmware(s)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES, - "Licença(s)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_PERMISSIONS, - "Permissões") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SUPPORTED_EXTENSIONS, - "Extensões suportadas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_MANUFACTURER, - "Fabricante do sistema") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_NAME, - "Nome do sistema") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS, - "Controles") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_LIST, - "Carregar Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, - "Opções") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SETTINGS, - "Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, - "Iniciar um Núcleo Automaticamente") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, - "Extrair automaticamente o arquivo baixado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_BUILDBOT_URL, - "URL de Núcleos do Buildbot") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST, - "Atualizador de Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SETTINGS, - "Atualizador") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_ARCHITECTURE, - "Arquitetura da CPU:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_CORES, - "Cores da CPU:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_DIRECTORY, - "Cursor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_MANAGER, - "Gerenciar Cursor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CUSTOM_RATIO, - "Proporção Personalizada") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_MANAGER, - "Gerenciar Base de Dados") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_SELECTION, - "Seleção de Base de Dados") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DELETE_ENTRY, - "Remover") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FAVORITES, - "Diretório Inicial") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_CONTENT, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_DEFAULT, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_NONE, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, - "Diretório não encontrado.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS, - "Diretório") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_CYCLE_TRAY_STATUS, - "Condição da Bandeja do Ciclo de Disco") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND, - "Anexar Imagem de Disco") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_INDEX, - "Índice de Disco") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_OPTIONS, - "Controle de Disco") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DONT_CARE, - "Não importa") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST, - "Downloads") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE, - "Baixar Núcleo...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT, - "Download de Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_ENABLE, - "Habilitar Redefinição de DPI") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE, - "Redefinição de DPI") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS, - "Driver") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN, - "Carregar Modelo no Desligamento do Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHECK_FOR_MISSING_FIRMWARE, - "Verificar por Firmware que Falta Antes de Carregar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER, - "Plano de Fundo Dinâmico") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY, - "Planos de Fundo Dinâmicos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE, - "Habilitar Conquistas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR, - "Cor do item de menu ao passar o cursor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_NORMAL_COLOR, - "Cor normal do item de menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FALSE, - "Falso") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FASTFORWARD_RATIO, - "Velocidade Máxima de Execução") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FAVORITES_TAB, - "Favoritos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FPS_SHOW, - "Mostrar Taxa de Quadros") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE, - "Controlar Velocidade Máxima de Execução") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, - "Controle de Quadros") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, - "Contadores do Frontend") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, - "Carrega Automaticamente Opções de Núcleo Específicas do Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE, - "Criar arquivo de opções do jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE, - "Salvar arquivo de opções do jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP, - "Ajuda") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING, - "Solução de Problemas de Áudio/Vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD, - "Alterando a Transparência de Gamepad Virtual") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CONTROLS, - "Controles Básicos de Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_LIST, - "Ajuda") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_LOADING_CONTENT, - "Carregando Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT, - "Procurando em Busca de Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_WHAT_IS_A_CORE, - "O Que É Um Núcleo?") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HISTORY_LIST_ENABLE, - "Habilitar Lista de Histórico") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HISTORY_TAB, - "Histórico") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, - "Menu Horizontal") -MSG_HASH(MENU_ENUM_LABEL_VALUE_IMAGES_TAB, - "Imagem") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INFORMATION, - "Informação") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INFORMATION_LIST, - "Informação") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ADC_TYPE, - "Tipo de Analógico Para Digital") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ALL_USERS_CONTROL_MENU, - "Todos os Usuários Controlam o Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X, - "Analógico Esquerdo X") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_MINUS, - "Analógico Esquerdo X- (esquerda)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_PLUS, - "Analógico Esquerdo X+ (direita)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y, - "Analógico Esquerdo Y") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_MINUS, - "Analógico Esquerdo Y- (cima)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_PLUS, - "Analógico Esquerdo Y+ (baixo)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X, - "Analógico Direito X") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_MINUS, - "Analógico Direito X- (esquerda)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_PLUS, - "Analógico Direito X+ (direita)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y, - "Analógico Direito Y") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS, - "Analógico Direito Y- (cima)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS, - "Analógico Direito Y+ (baixo)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_TRIGGER, - "Gatinho da Pistola") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_RELOAD, - "Recarregar Pistola") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_A, - "Aux A da Pistola") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_B, - "Aux B da Pistola") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_C, - "Aux C da Pistola") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_START, - "Start da Pistola") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_SELECT, - "Select da Pistola") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_UP, - "D-pad Cima da Pistola") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_DOWN, - "D-pad Baixo da Pistola") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT, - "D-pad Esquerdo da Pistola") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, - "D-pad Direito da Pistola") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, - "Habilitar Autoconfiguração") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Zona Morta do Controle Analógico") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, - "Inverter Botões OK e Cancelar do Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, - "Vincular Todos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL, - "Vincular Todos pelo Padrão") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_TIMEOUT, - "Tempo Limite para Vincular") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_HIDE_UNBOUND, - "Ocultar Descritores de Entrada do Núcleo Não Vinculados") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_LABEL_SHOW, - "Exibir Rótulos do Descritor de Entrada") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX, - "Índice de Dispositivo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_TYPE, - "Tipo de Dispositivo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_INDEX, - "Índice de Mouse") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DRIVER, - "Driver de Entrada") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DUTY_CYCLE, - "Ciclo de Trabalho") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS, - "Vínculos das Teclas de Atalho da Entrada") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE, - "Habilitar Mapeamento de Gamepad no Teclado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_A, - "Botão A (direita)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, - "Botão B (baixo)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_DOWN, - "Direcional para baixo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L2, - "Botão L2 (gatilho)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L3, - "Botão L3 (polegar)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L, - "Botão L (ombro)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT, - "Direcional Esquerdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R2, - "Botão R2 (gatilho)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R3, - "Botão R3 (polegar)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R, - "Botão R (ombro)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_RIGHT, - "Direcional Direito") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, - "Botão Select") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, - "Botão Start") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_UP, - "Direcional para Cima") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X, - "Botão X (topo)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, - "Botão Y (esquerda)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEY, - "(Tecla: %s)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_LEFT, - "Mouse 1") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_RIGHT, - "Mouse 2") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_MIDDLE, - "Mouse 3") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON4, - "Mouse 4") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON5, - "Mouse 5") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_UP, - "Roda do Mouse para Cima") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_DOWN, - "Roda do Mouse para Baixo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_UP, - "Roda do Mouse para Esquerda") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_DOWN, - "Roda do Mouse para Direita") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, - "Tipo de Mapeamento para Gamepad no Teclado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MAX_USERS, - "Usuários Máximos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, - "Combinação do Gamepad para Alternar Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS, - "Índice de Trapaça -") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS, - "Índice de Trapaça +") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE, - "Alternar Trapaça") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE, - "Alternar ejeção de disco") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT, - "Próximo disco") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, - "Disco anterior") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, - "Habilitar teclas de atalho") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY, - "Manter Avanço Rápido") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY, - "Alternar Avanço Rápido") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, - "Avanço de Quadro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, - "Alternar tela cheia") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, - "Alternar captura do Mouse") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, - "Alternar foco do jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE, - "Alternar menu desktop") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, - "Carregar Estado de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, - "Alternar menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE, - "Alternar gravação de filme") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, - "Alternar áudio mudo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, - "Alternar modo jogador/espectador do Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, - "Alternar teclado virtual") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, - "Próxima Transparência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE, - "Alternar pausa") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, - "Sair do RetroArch") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, - "Reiniciar jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, - "Rebobinar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, - "Salvar Estado de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, - "Capturar tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, - "Próximo Shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, - "Shader Anterior") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_HOLD_KEY, - "Câmera Lenta") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_KEY, - "Alternar câmera lenta") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, - "Compartimento do Estado de Jogo -") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, - "Compartimento do Estado de Jogo +") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, - "Volume -") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, - "Volume +") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_ENABLE, - "Mostrar Transparência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU, - "Ocultar Transparência no Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, - "Exibir Comandos Na Transparência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, - "Porta de Escuta do Exibir Comandos ") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR, - "Tipo de Comportamento da Chamada Seletiva") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_EARLY, - "Mais cedo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_LATE, - "Mais tarde") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_NORMAL, - "Normal") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_PREFER_FRONT_TOUCH, - "Preferir Toque Frontal") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAPPING_DIRECTORY, - "Remapeamento de Entrada") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAP_BINDS_ENABLE, - "Habilitar Remapeamento de Vínculos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SAVE_AUTOCONFIG, - "Salvar Autoconfiguração") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS, - "Entrada") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE, - "Habilitar Teclado Pequeno") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TOUCH_ENABLE, - "Habilitar Toque") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE, - "Habilitar Turbo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, - "Período do Turbo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_USER_BINDS, - "Vínculos de Entrada do Usuário %u") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LATENCY_SETTINGS, - "Latência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INTERNAL_STORAGE_STATUS, - "Condição do armazenamento interno") -MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_AUTOCONFIG_DIR, - "Autoconfiguração de Entrada") -MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_DRIVER, - "Driver de Joypad") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LAKKA_SERVICES, - "Serviços") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_CHINESE_SIMPLIFIED, - "Chinês (Simplificado)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_CHINESE_TRADITIONAL, - "Chinês (Tradicional)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_DUTCH, - "Holandês") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ENGLISH, - "Inglês") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ESPERANTO, - "Esperanto") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_FRENCH, - "Francês") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_GERMAN, - "Alemão") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ITALIAN, - "Italiano") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_JAPANESE, - "Japonês") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_KOREAN, - "Coreano") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_POLISH, - "Polonês") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_BRAZIL, - "Português (Brasil)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_PORTUGAL, - "Português (Portugal)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_RUSSIAN, - "Russo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_SPANISH, - "Espanhol") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_VIETNAMESE, - "Vietnamita") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ARABIC, - "Árabe") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LEFT_ANALOG, - "Analógico Esquerdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH, - "Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_INFO_PATH, - "Informação do Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_LOG_LEVEL, - "Nível de Registro de Eventos do Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LINEAR, - "Linear") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_ARCHIVE, - "Carregar Arquivo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY, - "Carregar Recente") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST, - "Carregar Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_STATE, - "Carregar Estado de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_ALLOW, - "Permitir Localização") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_DRIVER, - "Driver de Localização") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS, - "Registro de Eventos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOG_VERBOSITY, - "Verbosidade do Registro de Eventos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MAIN_MENU, - "Menu Principal") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MANAGEMENT, - "Configurações da Base de Dados") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME, - "Tema de Cor do Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE, - "Azul") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE_GREY, - "Cinza Azulado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_DARK_BLUE, - "Azul Escuro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_GREEN, - "Verde") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_NVIDIA_SHIELD, - "Shield") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_RED, - "Vermelho") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_YELLOW, - "Amarelo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_FOOTER_OPACITY, - "Opacidade do Rodapé") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_HEADER_OPACITY, - "Opacidade do Cabeçalho") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DRIVER, - "Driver de Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE, - "Controlar Taxa de Quadros do Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FILE_BROWSER_SETTINGS, - "Configurações") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, - "Filtro Linear de Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_HORIZONTAL_ANIMATION, - "Animação Horizontal") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, - "Aparência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER, - "Plano de Fundo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY, - "Opacidade do plano de fundo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MISSING, - "Faltando") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MORE, - "...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MOUSE_ENABLE, - "Suporte para Mouse") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MULTIMEDIA_SETTINGS, - "Multimídia") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MUSIC_TAB, - "Música") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, - "Filtrar Extensões Desconhecidas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NAVIGATION_WRAPAROUND, - "Navegação Retorna ao Início") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NEAREST, - "Mais Próximo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY, - "Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ALLOW_SLAVES, - "Permitir Clientes em Modo Escravo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, - "Verificar Quadros do Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN, - "Quadros de Latência de Entrada") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, - "Faixa de Quadros de Latência de Entrada") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES, - "Atraso de Quadros do Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT, - "Desconectar do hospedeiro de Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE, - "Habilitar Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT, - "Conectar ao hospedeiro de Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_HOST, - "Iniciar hospedeiro de Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISABLE_HOST, - "Parar hospedeiro de Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS, - "Endereço do Servidor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LAN_SCAN_SETTINGS, - "Analisar a rede local") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, - "Habilitar Cliente Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, - "Usuário") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, - "Senha do Servidor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE, - "Anunciar Netplay Publicamente") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REQUEST_DEVICE_I, - "Solicitar Dispositivo %u") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REQUIRE_SLAVES, - "Não Permitir Clientes em Modo Não Escravo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, - "Configurações do Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG, - "Compartilhamento de Entrada Analógica") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_MAX, - "Máximo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_AVERAGE, - "Médio") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL, - "Compartilhamento de Entrada Digital") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_OR, - "Compartilhar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_XOR, - "Agarrar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_VOTE, - "Eleger") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NONE, - "Nenhum") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NO_PREFERENCE, - "Sem preferência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_START_AS_SPECTATOR, - "Modo Espectador do Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, - "Modo sem Estados de Jogo do Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, - "Senha Apenas Espectador do Servidor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, - "Habilitar Espectador do Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, - "Porta TCP do Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, - "Travessia de NAT do Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_ENABLE, - "Comandos de Rede") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT, - "Porta de Comando de Rede") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_INFORMATION, - "Informação de Rede") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_ENABLE, - "Gamepad de Rede") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_PORT, - "Porta Base Remota de Rede") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_SETTINGS, - "Rede") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO, - "Não") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NONE, - "Nenhum") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE, - "N/D") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ACHIEVEMENTS_TO_DISPLAY, - "Não há Conquistas para mostrar.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE, - "Nenhum Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORES_AVAILABLE, - "Nenhum núcleo disponível") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE_INFORMATION_AVAILABLE, - "Não há informação de núcleo disponível.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE_OPTIONS_AVAILABLE, - "Não há opções de núcleo disponíveis.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY, - "Não há itens para mostrar.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_HISTORY_AVAILABLE, - "Não há histórico disponível.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE, - "Não há informação disponível.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ITEMS, - "Sem itens.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETPLAY_HOSTS_FOUND, - "Nenhum hospedeiro de Netplay encontrado.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, - "Nenhuma rede encontrada.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, - "Não há contadores de desempenho.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, - "Não há listas de reprodução.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLIST_ENTRIES_AVAILABLE, - "Não há itens de lista de reprodução disponível.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, - "Nenhuma configuração encontrada.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, - "Não há parâmetros de Shader.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OFF, - "DESLIGADO") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ON, - "LIGADO") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONLINE, - "Online") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER, - "Atualizador Online") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS, - "Exibição na Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS, - "Transparência na Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS, - "Notificações na Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OPEN_ARCHIVE, - "Navegar no Arquivo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OPTIONAL, - "Opcional") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY, - "Transparência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED, - "Carrega Automaticamente Transparência Favorita") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_DIRECTORY, - "Transparência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_OPACITY, - "Opacidade da Transparência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_PRESET, - "Predefinição de Transparência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_SCALE, - "Escala da Transparência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS, - "Transparência na Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PAL60_ENABLE, - "Utilizar Modo PAL60") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY, - "Diretório superior") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_LIBRETRO, - "Pausar quando o menu for ativado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, - "Não rodar em segundo plano") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, - "Contadores de Desempenho") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, - "Listas de Reprodução") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Lista de Reprodução") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, - "Listas de Reprodução") -MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, - "Suporte para Toque") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, - "Porta") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PRESENT, - "Presente") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PRIVACY_SETTINGS, - "Privacidade") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH, - "Sair do RetroArch") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ANALOG, - "Analógico suportado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_BBFC_RATING, - "Classificação BBFC") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CERO_RATING, - "Classificação CERO") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_COOP, - "Cooperativo suportado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CRC32, - "CRC32") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DESCRIPTION, - "Descrição") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DEVELOPER, - "Desenvolvedor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_ISSUE, - "Edição da Revista Edge") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_RATING, - "Classificação da Revista Edge") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_REVIEW, - "Análise da Revista Edge") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ELSPA_RATING, - "Classificação ELSPA") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ENHANCEMENT_HW, - "Hardware de Aprimoramento") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ESRB_RATING, - "Classificação ESRB") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FAMITSU_MAGAZINE_RATING, - "Classificação da Revista Famitsu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FRANCHISE, - "Franquia") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_GENRE, - "Gênero") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_MD5, - "MD5") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME, - "Nome") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ORIGIN, - "Origem") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PEGI_RATING, - "Classificação PEGI") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PUBLISHER, - "Editor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_MONTH, - "Mês de Lançamento") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_YEAR, - "Ano de Lançamento") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RUMBLE, - "Suporte para Vibração") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SERIAL, - "Número de Série") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SHA1, - "SHA1") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_START_CONTENT, - "Iniciar Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, - "Classificação TGDB") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REBOOT, - "Reiniciar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY, - "Configuração de Gravação") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_OUTPUT_DIRECTORY, - "Saída de Gravação") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, - "Gravação") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, - "Carregar Configuração de Gravação...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_DRIVER, - "Driver de Gravação") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_ENABLE, - "Habilitar Gravação") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_PATH, - "Salvar Saída de Gravação Como...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_USE_OUTPUT_DIRECTORY, - "Salvar Gravações no Diretório de Saída") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE, - "Arquivo de Remapeamento") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_LOAD, - "Carregar Arquivo de Remapeamento") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CORE, - "Salvar Arquivo de Remapeamento de Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CONTENT_DIR, - "Salvar Arquivo de Remapeamento de Jogo do Diretório de Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_GAME, - "Salvar Arquivo de Remapeamento de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CORE, - "Excluir Arquivo de Remapeamento de Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_GAME, - "Excluir Arquivo de Remapeamento de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CONTENT_DIR, - "Excluir Arquivo de Remapeamento de Jogo do Diretório de Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REQUIRED, - "Obrigatório") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_CONTENT, - "Reiniciar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH, - "Reiniciar RetroArch") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME, - "Retomar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME_CONTENT, - "Retomar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROKEYBOARD, - "RetroKeyboard") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD, - "RetroPad") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD_WITH_ANALOG, - "RetroPad com Analógico") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS, - "Conquistas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_ENABLE, - "Habilitar Rebobinagem") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_GRANULARITY, - "Granularidade da Rebobinagem") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS, - "Rebobinagem") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY, - "Navegador de Arquivos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY, - "Configuração") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN, - "Mostrar Tela Inicial") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG, - "Analógico Direito") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES, - "Adicionar aos Favoritos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST, - "Adicionar aos Favoritos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESET_CORE_ASSOCIATION, - "Redefinir Associação do Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN, - "Executar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_MUSIC, - "Executar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAMBA_ENABLE, - "Habilitar SAMBA") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVEFILE_DIRECTORY, - "Arquivo de Jogo-Salvo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX, - "Índice Automático de Estado de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD, - "Carrega Automaticamente Estado de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE, - "Salvar Automaticamente Estado de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_DIRECTORY, - "Arquivo de Estado de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE, - "Miniaturas do Estado de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG, - "Salvar Configuração Atual") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, - "Salvar Redefinição de Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, - "Salvar Redefinições do Diretório de Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, - "Salvar Redefinição de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_NEW_CONFIG, - "Salvar Nova Configuração") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_STATE, - "Salvar Estado de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS, - "Salvando") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY, - "Analisar Diretório") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_FILE, - "Analisar Arquivo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREENSHOT_DIRECTORY, - "Captura de Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION, - "Resolução da Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SEARCH, - "Procurar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SECONDS, - "segundos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SETTINGS, - "Configurações") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SETTINGS_TAB, - "Configurações") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER, - "Shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_APPLY_CHANGES, - "Aplicar Alterações") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS, - "Shaders") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON, - "Faixa") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON_SIMPLIFIED, - "Faixa (simplificada)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SIMPLE_SNOW, - "Neve Simples") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOW, - "Neve") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_ADVANCED_SETTINGS, - "Exibir Configurações Avançadas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_HIDDEN_FILES, - "Exibir Arquivos e Pastas Ocultos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHUTDOWN, - "Desligar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO, - "Taxa de Câmera Lenta") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_ENABLED, - "Adiantar Quadro para Reduzir a Latência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_FRAMES, - "Número de Quadros para Adiantar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_SECONDARY_INSTANCE, - "O Adiantamento de Quadro Usará uma Segunda Instância") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_HIDE_WARNINGS, - "Ocultar Avisos do Adiantamento de Quadro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVEFILES_ENABLE, - "Classificar Arquivos de Jogo-Salvo em Pastas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVESTATES_ENABLE, - "Classificar Arquivos de Estado de Jogo em Pastas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATES_IN_CONTENT_DIR_ENABLE, - "Gravar Estados de Jogo no Diretório de Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVEFILES_IN_CONTENT_DIR_ENABLE, - "Gravar Jogos-Salvos no Diretório de Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEMFILES_IN_CONTENT_DIR_ENABLE, - "Arquivos de Sistema estão no Diretório de Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREENSHOTS_IN_CONTENT_DIR_ENABLE, - "Salvar Capturas de Tela no Diretório de Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SSH_ENABLE, - "Habilitar SSH") -MSG_HASH(MENU_ENUM_LABEL_VALUE_START_CORE, - "Iniciar Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_START_NET_RETROPAD, - "Iniciar RetroPad Remoto") -MSG_HASH(MENU_ENUM_LABEL_VALUE_START_VIDEO_PROCESSOR, - "Iniciar Processador de Vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STATE_SLOT, - "Compartimento do Estado de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STATUS, - "Condição") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STDIN_CMD_ENABLE, - "Comandos stdin") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES, - "Núcleos Sugeridos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SUSPEND_SCREENSAVER_ENABLE, - "Desativar Protetor de Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_BGM_ENABLE, - "Habilitar Música em Segundo Plano do Sistema") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_DIRECTORY, - "Sistema/BIOS") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFORMATION, - "Informação do Sistema") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_7ZIP_SUPPORT, - "Suporte a 7zip") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ALSA_SUPPORT, - "Suporte a ALSA") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_BUILD_DATE, - "Data de Compilação") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CG_SUPPORT, - "Suporte a Cg") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COCOA_SUPPORT, - "Suporte a Cocoa") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COMMAND_IFACE_SUPPORT, - "Suporte à Interface de Comando") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CORETEXT_SUPPORT, - "Suporte a CoreText") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CPU_FEATURES, - "Características de CPU") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_DPI, - "Métrica DPI da Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_HEIGHT, - "Métrica de Altura da Tela (mm)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_WIDTH, - "Métrica de Largura da Tela (mm)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DSOUND_SUPPORT, - "Suporte a DirectSound") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WASAPI_SUPPORT, - "Suporte a WASAPI") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYLIB_SUPPORT, - "Suporte à biblioteca dinâmica") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYNAMIC_SUPPORT, - "Carregamento dinâmico em tempo de execução da biblioteca libretro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_EGL_SUPPORT, - "Suporte a EGL") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FBO_SUPPORT, - "Suporte a OpenGL/Direct3D render-to-texture (multi-pass shaders)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FFMPEG_SUPPORT, - "Suporte a FFmpeg") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FREETYPE_SUPPORT, - "Suporte a FreeType") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_IDENTIFIER, - "Identificador do Frontend") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_NAME, - "Nome do Frontend") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_OS, - "SO do Frontend") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GIT_VERSION, - "Versão Git") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GLSL_SUPPORT, - "Suporte a GLSL") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_HLSL_SUPPORT, - "Suporte a HLSL") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_JACK_SUPPORT, - "Suporte a JACK") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_KMS_SUPPORT, - "Suporte a KMS/EGL") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LAKKA_VERSION, - "Versão Lakka") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, - "Suporte a LibretroDB") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, - "Suporte a Libusb") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "Suporte a libxml2 XML parsing") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, - "Suporte Netplay (ponto-a-ponto)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, - "Suporte à Interface de comando de rede") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_REMOTE_SUPPORT, - "Suporte a Gamepad de Rede") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENAL_SUPPORT, - "Suporte a OpenAL") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGLES_SUPPORT, - "Suporte a OpenGL ES") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGL_SUPPORT, - "Suporte a OpenGL") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENSL_SUPPORT, - "Suporte a OpenSL") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENVG_SUPPORT, - "Suporte a OpenVG") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OSS_SUPPORT, - "Suporte a OSS") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OVERLAY_SUPPORT, - "Suporte à Transparência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE, - "Fonte de Energia") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGED, - "Carregado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGING, - "Carregando") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_DISCHARGING, - "Descarregando") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_NO_SOURCE, - "Não há fonte") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PULSEAUDIO_SUPPORT, - "Suporte a PulseAudio") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PYTHON_SUPPORT, - "Suporte a Python (suporte de script em Shaders)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RBMP_SUPPORT, - "Suporte a BMP (RBMP)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RETRORATING_LEVEL, - "Nível RetroRating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RJPEG_SUPPORT, - "Suporte a JPEG (RJPEG)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ROARAUDIO_SUPPORT, - "Suporte a RoarAudio") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RPNG_SUPPORT, - "Suporte a PNG (RPNG)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RSOUND_SUPPORT, - "Suporte a RSound") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RTGA_SUPPORT, - "Suporte a TGA (RTGA)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL2_SUPPORT, - "Suporte a SDL2") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_IMAGE_SUPPORT, - "Suporte a imagem SDL") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_SUPPORT, - "Suporte a SDL1.2") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SLANG_SUPPORT, - "Suporte a Slang") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_THREADING_SUPPORT, - "Suporte a Paralelismo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_UDEV_SUPPORT, - "Suporte a Udev") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_V4L2_SUPPORT, - "Suporte a Video4Linux2") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VIDEO_CONTEXT_DRIVER, - "Driver de contexto de vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VULKAN_SUPPORT, - "Suporte a Vulkan") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WAYLAND_SUPPORT, - "Suporte a Wayland") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_X11_SUPPORT, - "Suporte a X11") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XAUDIO2_SUPPORT, - "Suporte a XAudio2") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XVIDEO_SUPPORT, - "Suporte a XVideo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ZLIB_SUPPORT, - "Suporte a Zlib") -MSG_HASH(MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT, - "Capturar tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, - "Paralelismo de tarefas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS, - "Miniaturas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS, - "Miniaturas à Esquerda") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS, - "Disposição Vertical de Miniaturas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, - "Miniaturas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST, - "Atualizador de Miniaturas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS, - "Arte da Embalagem") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS, - "Captura de Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS, - "Telas do Título") -MSG_HASH(MENU_ENUM_LABEL_VALUE_TIMEDATE_ENABLE, - "Exibir data e hora") -MSG_HASH(MENU_ENUM_LABEL_VALUE_TITLE_COLOR, - "Cor do título do menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_TRUE, - "Verdadeiro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_ENABLE, - "Habilitar Companheiro da Interface de Usuário") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_START_ON_BOOT, - "Companheiro da Interface de Usuário Roda na Inicialização") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_TOGGLE, - "Mostrar menu desktop na inicialização") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DESKTOP_MENU_ENABLE, - "Habilitar menu desktop (reiniciar)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_MENUBAR_ENABLE, - "Barra de Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE, - "Incapaz de ler o arquivo comprimido.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_LOAD_STATE, - "Desfazer Carregamento de Estado de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_SAVE_STATE, - "Desfazer Salvamento de Estado de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNKNOWN, - "Desconhecido") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS, - "Atualizador") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_ASSETS, - "Atualizar Recursos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_AUTOCONFIG_PROFILES, - "Atualizar Perfis de Autoconfiguração") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CG_SHADERS, - "Atualizar Shaders Cg") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CHEATS, - "Atualizar Trapaças") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CORE_INFO_FILES, - "Atualizar Arquivos de Informação de Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_DATABASES, - "Atualizar Bases de Dados") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_GLSL_SHADERS, - "Atualizar Shaders GLSL") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_LAKKA, - "Atualizar Lakka") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_OVERLAYS, - "Atualizar Transparências") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_SLANG_SHADERS, - "Atualizar Shaders Slang") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USER, - "Usuário") -MSG_HASH(MENU_ENUM_LABEL_VALUE_KEYBOARD, - "Kbd") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS, - "Interface de Usuário") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_LANGUAGE, - "Idioma") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_SETTINGS, - "Usuário") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER, - "Utilizar o Visualizador de Imagem Integrado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_BUILTIN_PLAYER, - "Utilizar o Reprodutor de Mídia Integrado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ALLOW_ROTATE, - "Permitir rotação") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO, - "Configurar Proporção de Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_AUTO, - "Proporção de Tela Automática") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, - "Proporção de Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, - "Inserção de Quadro Opaco") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, - "Cortar Overscan (Recarregar)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, - "Desativar Composição da Área de Trabalho") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, - "Driver de Vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, - "Filtro de Vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_DIR, - "Filtro de Vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_FLICKER, - "Filtro de tremulação de vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_ENABLE, - "Habilitar Notificações na Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_PATH, - "Fonte das Notificações na Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_SIZE, - "Tamanho da Notificação na Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_ASPECT, - "Forçar Proporção de Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_SRGB_DISABLE, - "Forçar Desativação de sRGB FBO") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FRAME_DELAY, - "Atraso de Quadro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN, - "Utilizar Modo de Tela Cheia") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GAMMA, - "Gama de Vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GPU_RECORD, - "Usar Gravação da GPU") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT, - "Habilitar Captura de Tela da GPU") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, - "Sincronia Rígida de GPU") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES, - "Quadros de Sincronia Rígida de GPU") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES, - "Máximo de imagens na cadeia de troca") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_X, - "Posição X da Notificação na Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_Y, - "Posição Y da Notificação na Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MONITOR_INDEX, - "Índice de Monitor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_POST_FILTER_RECORD, - "Usar Gravação Pós-Filtro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, - "Taxa de Atualização Vertical") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, - "Taxa de Quadros Estimada da Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, - "Definir Taxa de Atualização Reportada") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, - "Rotação") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, - "Escala em Janela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER, - "Escala em Inteiros") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS, - "Vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DIR, - "Shader de Vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_NUM_PASSES, - "Estágios de Shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS, - "Pré-visualizar Parâmetros de Shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET, - "Carregar Predefinição de Shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS, - "Salvar Predefinição de Shader Como") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE, - "Salvar Predefinição de Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_PARENT, - "Salvar Predefinição do Diretório de Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME, - "Salvar Predefinição de Jogo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT, - "Habilitar Contexto Compartilhado de Hardware") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH, - "Filtragem Bilinear") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER, - "Habilitar Filtro por Software") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SWAP_INTERVAL, - "Intervalo de Troca da Sincronização Vertical (V-Sync)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_TAB, - "Vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_THREADED, - "Vídeo Paralelizado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VFILTER, - "Reduzir Tremulação de Vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_HEIGHT, - "Altura Personalizada da Proporção de Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_WIDTH, - "Largura Personalizada da Proporção de Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X, - "Posição X Personalizada da Proporção de Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_Y, - "Posição Y Personalizada da Proporção de Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, - "Definir Largura de Tela do VI") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, - "Sincronização Vertical (V-Sync)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, - "Modo Janela em Tela Cheia") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_WIDTH, - "Largura da Janela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_HEIGHT, - "Altura da Janela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_X, - "Largura em Tela Cheia") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_Y, - "Altura em Tela Cheia") -MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_DRIVER, - "Driver de Wi-Fi") -MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, - "Wi-Fi") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, - "Fator Alfa do Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_RED, - "Cor Vermelha da Fonte do Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_GREEN, - "Cor Verde da Fonte do Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_BLUE, - "Cor Azul da Fonte do Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, - "Fonte do Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, - "Personalizado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_FLATUI, - "FlatUI") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME, - "Monocromático") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME_INVERTED, - "Monocromático Invertido") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_SYSTEMATIC, - "Sistemático") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_NEOACTIVE, - "NeoActive") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL, - "Pixel") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE, - "RetroActive") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM, - "Retrosystem") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART, - "Dot-Art") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME, - "Tema de Cor do Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_APPLE_GREEN, - "Verde Maçã") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK, - "Escuro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LIGHT, - "Claro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MORNING_BLUE, - "Azul da manhã") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK_PURPLE, - "Roxo Escuro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_ELECTRIC_BLUE, - "Azul Elétrico") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_GOLDEN, - "Dourado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LEGACY_RED, - "Vermelho Legado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MIDNIGHT_BLUE, - "Azul Meia-noite") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_PLAIN, - "Natural") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_UNDERSEA, - "Submarino") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_VOLCANIC_RED, - "Vermelho Vulcânico") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_RIBBON_ENABLE, - "Pipeline do Shader de Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SCALE_FACTOR, - "Fator de Escala do Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE, - "Habilitar Sombras dos Ícones") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_HISTORY, - "Exibir Aba de Histórico") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_ADD, - "Exibir Aba de Importação de Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_PLAYLISTS, - "Exibir Abas de Lista de Reprodução") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_FAVORITES, - "Exibir Aba de Favoritos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_IMAGES, - "Exibir Aba de Imagem") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_MUSIC, - "Exibir Aba de Música") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, - "Exibir Aba de Configurações") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, - "Exibir Aba de Vídeo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, - "Exibir Aba de Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, - "Layout do Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, - "Tema de Ícones do Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, - "Sim") -MSG_HASH(MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO, - "Predefinição de Shader") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, - "Habilitar ou desabilitar conquistas. Para mais informações, visite http://retroachievements.org") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, - "Habilitar ou desabilitar conquistas não oficiais e/ou recursos beta para fins de teste.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, - "Habilitar ou desabilitar Estado de Jogo, Trapaças, Rebobinagem, Avanço Rápido, Pausa e Câmera Lenta para todos os jogos.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_LEADERBOARDS_ENABLE, - "Habilitar ou desabilitar tabelas de classificação no jogo. Não tem efeito se o modo Hardcore estiver desativado.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_BADGES_ENABLE, - "Habilitar ou desabilitar a exibição de insígnia na Lista de Conquistas.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_VERBOSE_ENABLE, - "Habilitar ou desabilitar detalhes das conquistas na tela.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_AUTO_SCREENSHOT, - "Obter automaticamente uma captura de tela quando uma conquista é acionada.") -MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, - "Alterar os drivers utilizados pelo sistema.") -MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, - "Alterar as configurações de conquistas.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_SETTINGS, - "Alterar as configurações de núcleo.") -MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_SETTINGS, - "Alterar as configurações de gravação.") -MSG_HASH(MENU_ENUM_SUBLABEL_ONSCREEN_DISPLAY_SETTINGS, - "Alterar as configurações de Transparência e Transparência de teclado, e as configurações de notificação na tela.") -MSG_HASH(MENU_ENUM_SUBLABEL_FRAME_THROTTLE_SETTINGS, - "Alterar as configurações de Rebobinagem, Avanço Rápido e Câmera Lenta.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVING_SETTINGS, - "Alterar as configurações de salvamento.") -MSG_HASH(MENU_ENUM_SUBLABEL_LOGGING_SETTINGS, - "Alterar as configurações de registro de eventos.") -MSG_HASH(MENU_ENUM_SUBLABEL_USER_INTERFACE_SETTINGS, - "Alterar as configurações da interface de usuário.") -MSG_HASH(MENU_ENUM_SUBLABEL_USER_SETTINGS, - "Alterar as configurações de conta, nome de usuário e idioma.") -MSG_HASH(MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, - "Alterar as configurações de privacidade.") -MSG_HASH(MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, - "Alterar os diretórios padrão onde os arquivos estão localizados.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, - "Alterar as configurações de lista de reprodução.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, - "Configurar as configurações de servidor e rede.") -MSG_HASH(MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, - "Analisar conteúdo e adicionar na base de dados.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, - "Alterar as configurações de saída de áudio.") -MSG_HASH(MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE, - "Habilitar ou desabilitar o bluetooth.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, - "Salvar as alterações nos arquivos de configuração ao sair.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATION_SETTINGS, - "Alterar as definições padrão para os arquivos de configuração.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATIONS_LIST, - "Gerenciar e criar arquivos de configuração.") -MSG_HASH(MENU_ENUM_SUBLABEL_CPU_CORES, - "Quantidade de Cores que a CPU possui.") -MSG_HASH(MENU_ENUM_SUBLABEL_FPS_SHOW, - "Exibir a taxa atual de quadros por segundo na tela.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS, - "Ajustar configurações das teclas de atalho.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, - "Combinação de botões do Gamepad para alternar o menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_SETTINGS, - "Alterar as configurações de Joypad, teclado e Mouse.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_USER_BINDS, - "Configurar os controles para este usuário.") -MSG_HASH(MENU_ENUM_SUBLABEL_LATENCY_SETTINGS, - "Altere as configurações relacionadas a vídeo, áudio e latência dos comandos.") -MSG_HASH(MENU_ENUM_SUBLABEL_LOG_VERBOSITY, - "Habilitar ou desabilitar registro de eventos no terminal.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, - "Juntar-se ou hospedar uma sessão de Netplay.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, - "Procurar por e conectar aos hospedeiros de Netplay na rede local.") -MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "Exibir informações de núcleo, rede e sistema.") -MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, - "Baixar complementos, componentes e conteúdo para o RetroArch.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, - "Habilitar ou desabilitar compartilhamento de pastas na rede.") -MSG_HASH(MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, - "Gerenciar serviços ao nível de sistema operacional.") -MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES, - "Exibir arquivos/diretórios ocultos no navegador de arquivos.") -MSG_HASH(MENU_ENUM_SUBLABEL_SSH_ENABLE, - "Habilitar ou desabilitar acesso remoto à linha de comando.") -MSG_HASH(MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE, - "Prevenir que o protetor de tela do seu sistema seja ativado.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_WINDOW_SCALE, - "Definir o tamanho da janela em relação ao tamanho da janela de exibição do núcleo. Como alternativa, você pode definir uma largura e altura de janela abaixo para um tamanho de janela fixo.") -MSG_HASH(MENU_ENUM_SUBLABEL_USER_LANGUAGE, - "Definir o idioma da interface.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, - "Inserir um quadro opaco entre quadros. Útil para usuários com telas de 120Hz que desejam jogar conteúdos em 60Hz para eliminar efeito de fantasma.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, - "Reduz a latência ao custo de maior risco de engasgamento de vídeo. Adiciona um atraso após o V-Sync (em ms).") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, - "Definir quantos quadros a CPU pode rodar à frente da GPU quando utilizado o recurso 'Sincronia Rígida de GPU'.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, - "Informar ao driver de vídeo para utilizar explicitamente um modo de buffer específico.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, - "Seleciona qual tela de exibição a ser usada.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, - "A taxa de atualização estimada da tela em Hz.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED, - "A taxa de atualização conforme relatada pelo driver de vídeo.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, - "Alterar as configurações de saída de vídeo.") -MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, - "Analisar por redes sem fio e estabelecer uma conexão.") -MSG_HASH(MENU_ENUM_SUBLABEL_HELP_LIST, - "Saiba mais sobre como o programa funciona.") -MSG_HASH(MSG_ADDED_TO_FAVORITES, - "Adicionado aos favoritos") -MSG_HASH(MSG_RESET_CORE_ASSOCIATION, - "A associação do núcleo de entrada da lista de reprodução foi redefinida.") -MSG_HASH(MSG_APPENDED_DISK, - "Disco anexado") -MSG_HASH(MSG_APPLICATION_DIR, - "Diretório do aplicativo") -MSG_HASH(MSG_APPLYING_CHEAT, - "Aplicando as alterações de Trapaças.") -MSG_HASH(MSG_APPLYING_SHADER, - "Aplicando Shader") -MSG_HASH(MSG_AUDIO_MUTED, - "Áudio mudo.") -MSG_HASH(MSG_AUDIO_UNMUTED, - "Áudio mudo desativado.") -MSG_HASH(MSG_AUTOCONFIG_FILE_ERROR_SAVING, - "Erro em salvar o arquivo de autoconfiguração.") -MSG_HASH(MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY, - "Arquivo de autoconfiguração salvo com sucesso.") -MSG_HASH(MSG_AUTOSAVE_FAILED, - "Não foi possível inicializar o salvamento automático.") -MSG_HASH(MSG_AUTO_SAVE_STATE_TO, - "Salvar Automaticamente Estado de Jogo em") -MSG_HASH(MSG_BLOCKING_SRAM_OVERWRITE, - "Bloqueando Sobrescrita da SRAM") -MSG_HASH(MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT, - "Trazendo a interface de comando na porta") -MSG_HASH(MSG_BYTES, - "bytes") -MSG_HASH(MSG_CANNOT_INFER_NEW_CONFIG_PATH, - "Não é possível inferir o novo caminho de configuração. Use a hora atual.") -MSG_HASH(MSG_CHEEVOS_HARDCORE_MODE_ENABLE, - "Modo Hardcore Habilitado, Estados de Jogo e Rebobinagem estão desabilitados.") -MSG_HASH(MSG_COMPARING_WITH_KNOWN_MAGIC_NUMBERS, - "Comparando com números mágicos conhecidos...") -MSG_HASH(MSG_COMPILED_AGAINST_API, - "Compilado contra a API") -MSG_HASH(MSG_CONFIG_DIRECTORY_NOT_SET, - "Diretório de configuração não definido. Não foi possível salvar a nova configuração.") -MSG_HASH(MSG_CONNECTED_TO, - "Conectado a") -MSG_HASH(MSG_CONTENT_CRC32S_DIFFER, - "O CRC32 dos conteúdos difere. Não é possível utilizar jogos diferentes.") -MSG_HASH(MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT, - "Carregamento de conteúdo ignorado. A implementação irá carregar por conta própria.") -MSG_HASH(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES, - "O núcleo não suporta Estados de Jogo.") -MSG_HASH(MSG_CORE_OPTIONS_FILE_CREATED_SUCCESSFULLY, - "O arquivo de opções de núcleo foi criado com sucesso.") -MSG_HASH(MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER, - "Não foi possível encontrar nenhum driver seguinte") -MSG_HASH(MSG_COULD_NOT_FIND_COMPATIBLE_SYSTEM, - "Não foi possível encontrar um sistema compatível.") -MSG_HASH(MSG_COULD_NOT_FIND_VALID_DATA_TRACK, - "Não foi possível encontrar uma faixa de dados válida") -MSG_HASH(MSG_COULD_NOT_OPEN_DATA_TRACK, - "Não foi possível abrir a faixa de dados") -MSG_HASH(MSG_COULD_NOT_READ_CONTENT_FILE, - "Não foi possível ler o arquivo de conteúdo") -MSG_HASH(MSG_COULD_NOT_READ_MOVIE_HEADER, - "Não foi possível ler o cabeçalho do filme.") -MSG_HASH(MSG_COULD_NOT_READ_STATE_FROM_MOVIE, - "Não foi possível ler o Estado de Jogo do filme.") -MSG_HASH(MSG_CRC32_CHECKSUM_MISMATCH, - "Soma de verificação CRC32 incompatível entre o arquivo de conteúdo e a soma de verificação de conteúdo salva no cabeçalho do arquivo de reprodução. Reprodução altamente susceptível de dessincronizar na reprodução.") -MSG_HASH(MSG_CUSTOM_TIMING_GIVEN, - "Tempo personalizado fornecido") -MSG_HASH(MSG_DECOMPRESSION_ALREADY_IN_PROGRESS, - "Descompressão já está em andamento.") -MSG_HASH(MSG_DECOMPRESSION_FAILED, - "Descompressão falhou.") -MSG_HASH(MSG_DETECTED_VIEWPORT_OF, - "Detectada janela de exibição de") -MSG_HASH(MSG_DID_NOT_FIND_A_VALID_CONTENT_PATCH, - "Não encontrou uma modificação de conteúdo válido.") -MSG_HASH(MSG_DISCONNECT_DEVICE_FROM_A_VALID_PORT, - "Desconectar dispositivo de uma porta válida.") -MSG_HASH(MSG_DISK_CLOSED, - "Fechado") -MSG_HASH(MSG_DISK_EJECTED, - "Ejetado") -MSG_HASH(MSG_DOWNLOADING, - "Baixando") -MSG_HASH(MSG_INDEX_FILE, - "index") -MSG_HASH(MSG_DOWNLOAD_FAILED, - "Download falhou") -MSG_HASH(MSG_ERROR, - "Erro") -MSG_HASH(MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT, - "O núcleo libretro requer conteúdo, mas nada foi fornecido.") -MSG_HASH(MSG_ERROR_LIBRETRO_CORE_REQUIRES_SPECIAL_CONTENT, - "O núcleo libretro requer conteúdo especial, mas nenhum foi fornecido.") -MSG_HASH(MSG_ERROR_PARSING_ARGUMENTS, - "Erro em analisar os argumentos.") -MSG_HASH(MSG_ERROR_SAVING_CORE_OPTIONS_FILE, - "Erro em salvar o arquivo de opções de núcleo.") -MSG_HASH(MSG_ERROR_SAVING_REMAP_FILE, - "Erro em salvar o arquivo de remapeamento.") -MSG_HASH(MSG_ERROR_REMOVING_REMAP_FILE, - "Erro em remover o arquivo de remapeamento.") -MSG_HASH(MSG_ERROR_SAVING_SHADER_PRESET, - "Erro em salvar a predefinição de Shader.") -MSG_HASH(MSG_EXTERNAL_APPLICATION_DIR, - "Diretório de Aplicativo Externo") -MSG_HASH(MSG_EXTRACTING, - "Extraindo") -MSG_HASH(MSG_EXTRACTING_FILE, - "Extraindo arquivo") -MSG_HASH(MSG_FAILED_SAVING_CONFIG_TO, - "Falha em salvar a configuração em") -MSG_HASH(MSG_FAILED_TO, - "Falha em") -MSG_HASH(MSG_FAILED_TO_ACCEPT_INCOMING_SPECTATOR, - "Falha em aceitar o espectador ingresso.") -MSG_HASH(MSG_FAILED_TO_ALLOCATE_MEMORY_FOR_PATCHED_CONTENT, - "Falha em alocar memória para o conteúdo modificado...") -MSG_HASH(MSG_FAILED_TO_APPLY_SHADER, - "Falha em aplicar o Shader.") -MSG_HASH(MSG_FAILED_TO_BIND_SOCKET, - "Falha em vincular o soquete.") -MSG_HASH(MSG_FAILED_TO_CREATE_THE_DIRECTORY, - "Falha em criar o diretório.") -MSG_HASH(MSG_FAILED_TO_EXTRACT_CONTENT_FROM_COMPRESSED_FILE, - "Falha em extrair o conteúdo do arquivo comprimido") -MSG_HASH(MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT, - "Falha em obter o apelido do cliente.") -MSG_HASH(MSG_FAILED_TO_LOAD, - "Falha em carregar") -MSG_HASH(MSG_FAILED_TO_LOAD_CONTENT, - "Falha em carregar o conteúdo") -MSG_HASH(MSG_FAILED_TO_LOAD_MOVIE_FILE, - "Falha em carregar o arquivo de filme") -MSG_HASH(MSG_FAILED_TO_LOAD_OVERLAY, - "Falha em carregar a Transparência.") -MSG_HASH(MSG_FAILED_TO_LOAD_STATE, - "Falha em carregar o Estado de Jogo de") -MSG_HASH(MSG_FAILED_TO_OPEN_LIBRETRO_CORE, - "Falha em abrir o núcleo Libretro") -MSG_HASH(MSG_FAILED_TO_PATCH, - "Falha em executar a modificação") -MSG_HASH(MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT, - "Falha em receber o cabeçalho do cliente.") -MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME, - "Falha em receber o apelido.") -MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST, - "Falha em receber o apelido do hospedeiro.") -MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME_SIZE_FROM_HOST, - "Falha em receber o tamanho do apelido do hospedeiro.") -MSG_HASH(MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST, - "Falha em receber os dados SRAM do hospedeiro.") -MSG_HASH(MSG_FAILED_TO_REMOVE_DISK_FROM_TRAY, - "Falha em remover o disco da bandeja.") -MSG_HASH(MSG_FAILED_TO_REMOVE_TEMPORARY_FILE, - "Falha em remover o arquivo temporário") -MSG_HASH(MSG_FAILED_TO_SAVE_SRAM, - "Falha em salvar SRAM") -MSG_HASH(MSG_FAILED_TO_SAVE_STATE_TO, - "Falha em salvar o Estado de Jogo em") -MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME, - "Falha em enviar o apelido.") -MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_SIZE, - "Falha em enviar o tamanho do apelido.") -MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT, - "Falha em enviar o apelido para o cliente.") -MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_TO_HOST, - "Falha em enviar o apelido para o hospedeiro.") -MSG_HASH(MSG_FAILED_TO_SEND_SRAM_DATA_TO_CLIENT, - "Falha em enviar os dados SRAM para o cliente.") -MSG_HASH(MSG_FAILED_TO_START_AUDIO_DRIVER, - "Falha em iniciar o driver de áudio. Prosseguindo sem áudio.") -MSG_HASH(MSG_FAILED_TO_START_MOVIE_RECORD, - "Falha em iniciar a gravação do filme.") -MSG_HASH(MSG_FAILED_TO_START_RECORDING, - "Falha em iniciar a gravação.") -MSG_HASH(MSG_FAILED_TO_TAKE_SCREENSHOT, - "Falha em obter uma captura de tela.") -MSG_HASH(MSG_FAILED_TO_UNDO_LOAD_STATE, - "Falha em desfazer o carregamento de Estado de Jogo.") -MSG_HASH(MSG_FAILED_TO_UNDO_SAVE_STATE, - "Falha em desfazer o salvamento de Estado de Jogo.") -MSG_HASH(MSG_FAILED_TO_UNMUTE_AUDIO, - "Falha em desativar o áudio mudo.") -MSG_HASH(MSG_FATAL_ERROR_RECEIVED_IN, - "Erro fatal recebido em") -MSG_HASH(MSG_FILE_NOT_FOUND, - "Arquivo não encontrado") -MSG_HASH(MSG_FOUND_AUTO_SAVESTATE_IN, - "Estado de Jogo automático encontrado em") -MSG_HASH(MSG_FOUND_DISK_LABEL, - "Rótulo de disco encontrado") -MSG_HASH(MSG_FOUND_FIRST_DATA_TRACK_ON_FILE, - "Encontrada primeira faixa de dados no arquivo") -MSG_HASH(MSG_FOUND_LAST_STATE_SLOT, - "Encontrada último compartimento de Estado de Jogo") -MSG_HASH(MSG_FOUND_SHADER, - "Shader encontrado") -MSG_HASH(MSG_FRAMES, - "Quadros") -MSG_HASH(MSG_GAME_SPECIFIC_CORE_OPTIONS_FOUND_AT, - "Opções por Jogo: Opções de núcleo específicas do jogo encontradas em") -MSG_HASH(MSG_GOT_INVALID_DISK_INDEX, - "Índice de disco inválido obtido") -MSG_HASH(MSG_GRAB_MOUSE_STATE, - "Capturar estado do Mouse") -MSG_HASH(MSG_GAME_FOCUS_ON, - "Foco do jogo ligado") -MSG_HASH(MSG_GAME_FOCUS_OFF, - "Foco do jogo desligado") -MSG_HASH(MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING, - "O núcleo libretro é renderizado por hardware. Deve usar a gravação pós-Shader também.") -MSG_HASH(MSG_INFLATED_CHECKSUM_DID_NOT_MATCH_CRC32, - "A soma de verificação inflada não corresponde ao CRC32.") -MSG_HASH(MSG_INPUT_CHEAT, - "Entrada de Trapaça") -MSG_HASH(MSG_INPUT_CHEAT_FILENAME, - "Nome do Arquivo de Trapaça") -MSG_HASH(MSG_INPUT_PRESET_FILENAME, - "Nome de Arquivo de Predefinição") -MSG_HASH(MSG_INPUT_RENAME_ENTRY, - "Renomear Título") -MSG_HASH(MSG_INTERFACE, - "Interface") -MSG_HASH(MSG_INTERNAL_STORAGE, - "Armazenamento Interno") -MSG_HASH(MSG_REMOVABLE_STORAGE, - "Armazenamento Removível") -MSG_HASH(MSG_INVALID_NICKNAME_SIZE, - "Tamanho de apelido inválido.") -MSG_HASH(MSG_IN_BYTES, - "em bytes") -MSG_HASH(MSG_IN_GIGABYTES, - "em gigabytes") -MSG_HASH(MSG_IN_MEGABYTES, - "em megabytes") -MSG_HASH(MSG_LIBRETRO_ABI_BREAK, - "foi compilado contra uma versão diferente do libretro do que esta.") -MSG_HASH(MSG_LIBRETRO_FRONTEND, - "Frontend para Libretro") -MSG_HASH(MSG_LOADED_STATE_FROM_SLOT, - "Estado de Jogo carregado do compartimento #%d.") -MSG_HASH(MSG_LOADED_STATE_FROM_SLOT_AUTO, - "Estado de Jogo carregado do compartimento #-1 (automático).") -MSG_HASH(MSG_LOADING, - "Carregando") -MSG_HASH(MSG_FIRMWARE, - "Um ou mais arquivos de firmware estão faltando") -MSG_HASH(MSG_LOADING_CONTENT_FILE, - "Carregando arquivo de conteúdo") -MSG_HASH(MSG_LOADING_HISTORY_FILE, - "Carregando arquivo de histórico") -MSG_HASH(MSG_LOADING_STATE, - "Carregando Estado de Jogo") -MSG_HASH(MSG_MEMORY, - "Memória") -MSG_HASH(MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE, - "O arquivo de filme não é um arquivo BSV1 válido.") -MSG_HASH(MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION, - "O formato de filme parece ter uma versão de serializador diferente. Provavelmente irá falhar.") -MSG_HASH(MSG_MOVIE_PLAYBACK_ENDED, - "Reprodução de filme terminou.") -MSG_HASH(MSG_MOVIE_RECORD_STOPPED, - "Parando a gravação de filme.") -MSG_HASH(MSG_NETPLAY_FAILED, - "Falha em inicializar o Netplay.") -MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE, - "Sem conteúdo, iniciando um núcleo modelo.") -MSG_HASH(MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET, - "Nenhum Estado de Jogo foi sobrescrito até o momento.") -MSG_HASH(MSG_NO_STATE_HAS_BEEN_LOADED_YET, - "Nenhum Estado de Jogo foi carregado até o momento.") -MSG_HASH(MSG_OVERRIDES_ERROR_SAVING, - "Erro em salvar as redefinições.") -MSG_HASH(MSG_OVERRIDES_SAVED_SUCCESSFULLY, - "Redefinições salvas com sucesso.") -MSG_HASH(MSG_PAUSED, - "Pausado.") -MSG_HASH(MSG_PROGRAM, - "RetroArch") -MSG_HASH(MSG_READING_FIRST_DATA_TRACK, - "Lendo a primeira faixa de dados...") -MSG_HASH(MSG_RECEIVED, - "recebido") -MSG_HASH(MSG_RECORDING_TERMINATED_DUE_TO_RESIZE, - "A gravação terminou devido ao redimensionamento.") -MSG_HASH(MSG_RECORDING_TO, - "Gravando em") -MSG_HASH(MSG_REDIRECTING_CHEATFILE_TO, - "Redirecionando o arquivo de Trapaça em") -MSG_HASH(MSG_REDIRECTING_SAVEFILE_TO, - "Redirecionando o Jogo-Salvo em") -MSG_HASH(MSG_REDIRECTING_SAVESTATE_TO, - "Redirecionando o Estado de Jogo em") -MSG_HASH(MSG_REMAP_FILE_SAVED_SUCCESSFULLY, - "Arquivo de remapeamento salvo com sucesso.") -MSG_HASH(MSG_REMAP_FILE_REMOVED_SUCCESSFULLY, - "Arquivo de remapeamento salvo com sucesso.") -MSG_HASH(MSG_REMOVED_DISK_FROM_TRAY, - "Disco removido da bandeja.") -MSG_HASH(MSG_REMOVING_TEMPORARY_CONTENT_FILE, - "Removendo arquivo de conteúdo temporário") -MSG_HASH(MSG_RESET, - "Reinicializar") -MSG_HASH(MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT, - "Reiniciando a gravação devido ao reinício do driver.") -MSG_HASH(MSG_RESTORED_OLD_SAVE_STATE, - "Estado de Jogo antigo restaurado.") -MSG_HASH(MSG_RESTORING_DEFAULT_SHADER_PRESET_TO, - "Shaders: restaurando predefinição padrão de Shader em") -MSG_HASH(MSG_REVERTING_SAVEFILE_DIRECTORY_TO, - "Revertendo diretório de Jogo-Salvo em") -MSG_HASH(MSG_REVERTING_SAVESTATE_DIRECTORY_TO, - "Revertendo diretório de Estado de Jogo em") -MSG_HASH(MSG_REWINDING, - "Voltando atrás.") -MSG_HASH(MSG_REWIND_INIT, - "Inicializando o buffer de Rebobinagem com tamanho") -MSG_HASH(MSG_REWIND_INIT_FAILED, - "Falha em inicializar o buffer de Rebobinagem. Rebobinagem será desativado.") -MSG_HASH(MSG_REWIND_INIT_FAILED_THREADED_AUDIO, - "Esta implementação usa áudio paralelizado. Não é possível utilizar Rebobinagem.") -MSG_HASH(MSG_REWIND_REACHED_END, - "Final do buffer de Rebobinagem atingido.") -MSG_HASH(MSG_SAVED_NEW_CONFIG_TO, - "Nova configuração salva em") -MSG_HASH(MSG_SAVED_STATE_TO_SLOT, - "Estado de Jogo salvo no compartimento #%d.") -MSG_HASH(MSG_SAVED_STATE_TO_SLOT_AUTO, - "Estado de Jogo salvo no compartimento #-1 (automático).") -MSG_HASH(MSG_SAVED_SUCCESSFULLY_TO, - "Salvo com sucesso em") -MSG_HASH(MSG_SAVING_RAM_TYPE, - "Salvando Tipo de RAM") -MSG_HASH(MSG_SAVING_STATE, - "Salvando Estado de Jogo") -MSG_HASH(MSG_SCANNING, - "Analisando") -MSG_HASH(MSG_SCANNING_OF_DIRECTORY_FINISHED, - "Análise de diretório terminada") -MSG_HASH(MSG_SENDING_COMMAND, - "Enviando comando") -MSG_HASH(MSG_SEVERAL_PATCHES_ARE_EXPLICITLY_DEFINED, - "Várias modificações de conteúdo estão explicitamente definidas, ignorando todas...") -MSG_HASH(MSG_SHADER, - "Shader") -MSG_HASH(MSG_SHADER_PRESET_SAVED_SUCCESSFULLY, - "Predefinição de Shader salva com sucesso.") -MSG_HASH(MSG_SKIPPING_SRAM_LOAD, - "Ignorando carregamento da SRAM.") -MSG_HASH(MSG_SLOW_MOTION, - "Câmera Lenta.") -MSG_HASH(MSG_FAST_FORWARD, - "Avanço rápido.") -MSG_HASH(MSG_SLOW_MOTION_REWIND, - "Rebobinagem em Câmera Lenta.") -MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED, - "SRAM não será salva.") -MSG_HASH(MSG_STARTING_MOVIE_PLAYBACK, - "Iniciando reprodução de filme.") -MSG_HASH(MSG_STARTING_MOVIE_RECORD_TO, - "Iniciando a gravação de filme em") -MSG_HASH(MSG_STATE_SIZE, - "Tamanho do Estado de Jogo") -MSG_HASH(MSG_STATE_SLOT, - "Compartimento do Estado de Jogo") -MSG_HASH(MSG_TAKING_SCREENSHOT, - "Fazendo captura de tela") -MSG_HASH(MSG_TO, - "em") -MSG_HASH(MSG_UNDID_LOAD_STATE, - "Desfez o carregamento de Estado de Jogo.") -MSG_HASH(MSG_UNDOING_SAVE_STATE, - "Desfazendo o salvamento de Estado de Jogo") -MSG_HASH(MSG_UNKNOWN, - "Desconhecido") -MSG_HASH(MSG_UNPAUSED, - "Retomando.") -MSG_HASH(MSG_UNRECOGNIZED_COMMAND, - "Comando não reconhecido") -MSG_HASH(MSG_USING_CORE_NAME_FOR_NEW_CONFIG, - "Usando o nome do núcleo para uma nova configuração.") -MSG_HASH(MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED, - "Usando o núcleo libretro modelo. Pulando a gravação.") -MSG_HASH(MSG_VALUE_CONNECT_DEVICE_FROM_A_VALID_PORT, - "Conecte o dispositivo a partir de uma porta válida.") -MSG_HASH(MSG_VALUE_DISCONNECTING_DEVICE_FROM_PORT, - "Desconectando o dispositivo da porta") -MSG_HASH(MSG_VALUE_REBOOTING, - "Reinicializando...") -MSG_HASH(MSG_VALUE_SHUTTING_DOWN, - "Desligando...") -MSG_HASH(MSG_VERSION_OF_LIBRETRO_API, - "Versão da API libretro") -MSG_HASH(MSG_VIEWPORT_SIZE_CALCULATION_FAILED, - "Falha no cálculo de tamanho da janela de exibição! Prosseguindo usando dados brutos. Isto provavelmente não funcionará corretamente...") -MSG_HASH(MSG_VIRTUAL_DISK_TRAY, - "bandeja de disco virtual.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_LATENCY, - "Latência de áudio desejada em milissegundos. Pode não ser honrado se o driver de áudio não puder prover a latência desejada.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MUTE, - "Áudio mudo/não-mudo.") -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, - "Ajuda a suavizar as imperfeições na regulagem ao sincronizar áudio e vídeo. Esteja ciente que se desativado, será quase impossível de se obter a sincronia adequada." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_CAMERA_ALLOW, - "Permitir ou não o acesso à câmera pelos núcleos." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_LOCATION_ALLOW, - "Permitir ou não o acesso ao serviço de localização pelos núcleos." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_MAX_USERS, - "Número máximo de usuários suportados pelo RetroArch." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_POLL_TYPE_BEHAVIOR, - "Influencia como a chamada seletiva de entrada é feita dentro do RetroArch. Definindo com 'Cedo' ou 'Tarde' pode resultar em menos latência, dependendo da sua configuração." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_ALL_USERS_CONTROL_MENU, - "Permitir a qualquer usuário controlar o menu. Se desabilitado, apenas o Usuário 1 poderá controlar o menu." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_VOLUME, - "Volume do áudio (em dB). 0dB é o volume normal, e nenhum ganho é aplicado." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_WASAPI_EXCLUSIVE_MODE, - "Permitir ao driver WASAPI obter controle exclusivo do dispositivo de áudio. Se desativado, o modo compartilhado será utilizado." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_WASAPI_FLOAT_FORMAT, - "Utilizar formato de ponto flutuante para o driver WASAPI, se suportado pelo dispositivo de áudio." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_WASAPI_SH_BUFFER_LENGTH, - "O tamanho (em quadros) do buffer intermediário quando o driver WASAPI estiver em modo compartilhado." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_SYNC, - "Sincroniza o áudio. Recomendado." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "Até que ponto um eixo deve ser movido para resultar em um botão pressionado." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, - "Quantidade de segundos para aguardar até proceder para o próximo vínculo." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_TURBO_PERIOD, - "Descreve o período quando os botões com turbo habilitado são alternados. Os números são descritos em quadros." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_DUTY_CYCLE, - "Descreve quão longo deve ser o período de um botão com turbo habilitado. Os números são descritos como quadros." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_VSYNC, - "Sincroniza o vídeo de saída da placa gráfica com a taxa de atualização da tela. Recomendado." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_ALLOW_ROTATE, - "Permite que os núcleos definam a rotação. Quando desabilitado, as requisições de rotação são ignoradas. Útil para configurações onde se rotaciona manualmente a tela." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_DUMMY_ON_CORE_SHUTDOWN, - "Alguns núcleos podem ter um recurso de desligamento. Se habilitado, impedirá que o núcleo feche o RetroArch. Em vez disto, carrega um núcleo modelo." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_CHECK_FOR_MISSING_FIRMWARE, - "Verifica se todos os firmwares necessários estão presentes antes de tentar carregar conteúdo." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE, - "Taxa de atualização vertical da sua tela. Utilizado para calcular uma taxa de saída de áudio adequada. OBS: Isto será ignorado se a função 'Vídeo Paralelizado' estiver habilitada." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_ENABLE, - "Habilita a saída de áudio." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_MAX_TIMING_SKEW, - "Mudança máxima na taxa de entrada de áudio. Se aumentado habilita grandes mudanças na regulagem ao custo de imprecisão no timbre do som (ex: rodando núcleos PAL em modo NTSC)." - ) -MSG_HASH( - MSG_FAILED, - "falhou" - ) -MSG_HASH( - MSG_SUCCEEDED, - "teve êxito" - ) -MSG_HASH( - MSG_DEVICE_NOT_CONFIGURED, - "não configurado" - ) -MSG_HASH( - MSG_DEVICE_NOT_CONFIGURED_FALLBACK, - "não configurado, usando reserva" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, - "Lista de Cursores da Base de Dados" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DEVELOPER, - "Base de Dados - Filtro : Desenvolvedor" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PUBLISHER, - "Base de Dados - Filtro : Publicador" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DISABLED, - "Desabilitado" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ENABLED, - "Habilitado" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_PATH, - "Caminho do Histórico de Conteúdo" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ORIGIN, - "Base de Dados - Filtro : Origem") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_FRANCHISE, - "Base de Dados - Filtro : Franquia") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ESRB_RATING, - "Base de Dados - Filtro : Classificação ESRB") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ELSPA_RATING, - "Base de Dados - Filtro : Classificação ELSPA") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PEGI_RATING, - "Base de Dados - Filtro : Classificação PEGI") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_CERO_RATING, - "Base de Dados - Filtro : Classificação CERO") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_BBFC_RATING, - "Base de Dados - Filtro : Classificação BBFC") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_MAX_USERS, - "Base de Dados - Filtro : Usuários máximos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_MONTH, - "Base de Dados - Filtro : Data de Lançamento Por Mês") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_YEAR, - "Base de Dados - Filtro : Data de Lançamento Por Ano") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_ISSUE, - "Base de Dados - Filtro : Edição da Revista Edge") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_RATING, - "Base de Dados - Filtro : Classificação da Revista Edge") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DATABASE_INFO, - "Informações da Base de Dados") -MSG_HASH(MSG_WIFI_SCAN_COMPLETE, - "Análise de Wi-Fi completa.") -MSG_HASH(MSG_SCANNING_WIRELESS_NETWORKS, - "Analisando redes sem fio...") -MSG_HASH(MSG_NETPLAY_LAN_SCAN_COMPLETE, - "Análise de Netplay completa.") -MSG_HASH(MSG_NETPLAY_LAN_SCANNING, - "Analisando por hospedeiros de Netplay...") -MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, - "Pausar o jogo quando a janela do RetroArch não estiver ativa.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, - "Habilitar ou desabilitar composição (Somente no Windows).") -MSG_HASH(MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, - "Habilitar ou desabilitar a lista de reprodução recente para jogos, imagens, música e vídeos.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, - "Limita o número de itens da lista de reprodução recente para jogos, imagens, música e vídeos.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_UNIFIED_MENU_CONTROLS, - "Controles de Menu Unificados") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS, - "Utilizar os mesmos controles para o menu e jogo. Aplica-se ao teclado.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE, - "Exibir mensagens na tela.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_USER_REMOTE_ENABLE, - "Habilitar Remoto do Usuário %d") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, - "Exibir nível de bateria") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, - "Selecionar Arquivo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Selecionar de Coleção") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, - "Filtro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, - "Escala") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED, - "O Netplay irá iniciar quando o conteúdo for carregado.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LOAD_CONTENT_MANUALLY, - "Não foi possível encontrar um núcleo adequado ou arquivo de conteúdo, carregue manualmente.") -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_URL_LIST, - "Navegar pela URL" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_URL, - "Caminho da URL" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_START, - "Iniciar" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, - "Bokeh") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOWFLAKE, - "Floco de neve") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_ROOMS, - "Atualizar Lista de Salas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME, - "Apelido: %s") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME_LAN, - "Apelido (lan): %s") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND, - "Conteúdo compatível encontrado") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_CROP_OVERSCAN, - "Corta alguns pixels ao redor das bordas da imagem habitualmente deixada em branco por desenvolvedores, que por vezes também contêm pixels de lixo.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SMOOTH, - "Adiciona um leve embaciado à imagem para suavizar as arestas da borda dos pixels. Esta opção tem pouco impacto no desempenho.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FILTER, - "Aplica um filtro de vídeo processado pela CPU. OBS: Pode vir a um alto custo de desempenho. Alguns filtros de vídeo podem funcionar apenas para núcleos que usam cores de 32 bits ou 16 bits.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_USERNAME, - "Insira o nome de usuário de sua conta Retro Achievements.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_PASSWORD, - "Insira a senha de sua conta Retro Achievements.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_NICKNAME, - "Insira seu nome de usuário aqui. Isto será utilizado para sessões do Netplay, entre outras coisas.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_POST_FILTER_RECORD, - "Capturar a imagem depois que os filtros (mas não os Shaders) forem aplicados. Seu vídeo ficará tão elegante quanto o que você vê na tela.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_LIST, - "Selecionar qual núcleo utilizar.") -MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_CONTENT_LIST, - "Selecionar qual conteúdo iniciar.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_INFORMATION, - "Exibir interfaces de rede e endereços de IP associados.") -MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_INFORMATION, - "Exibir informações específicas do dispositivo.") -MSG_HASH(MENU_ENUM_SUBLABEL_QUIT_RETROARCH, - "Sair do programa.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_WINDOW_WIDTH, - "Define a largura personalizada para a janela de exibição. Deixado em 0 a janela irá dimensionar o mais largo possível.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_WINDOW_HEIGHT, - "Define a altura personalizada para a janela de exibição. Deixado em 0 a janela irá dimensionar o mais alto possível.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_X, - "Define a largura personalizada para o modo de tela cheia em não-janela. Deixar em 0 irá usar a resolução da área de trabalho.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_Y, - "Define a altura personalizada para o modo de tela cheia em não-janela. Deixar em 0 irá usar a resolução da área de trabalho.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_X, - "Especifique a posição personalizada no eixo X para o texto na tela.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_Y, - "Especifique a posição personalizada no eixo Y para o texto na tela.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, - "Especifique o tamanho da fonte em pontos.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, - "Ocultar a Transparência enquanto estiver dentro do menu e exibir novamente ao sair.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, - "Exibir comandos de teclado/controle na transparência.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, - "Selecione a porta para a transparência escutar se Exibir Comandos na Transparência estiver habilitado.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, - "O conteúdo analisado aparecerá aqui." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, - "Apenas dimensiona o vídeo em valores inteiros. O tamanho de base depende da geometria relatada pelo sistema e da proporção de tela. Se 'Forçar Proporção' não estiver definido, X / Y serão dimensionados independentemente em valores inteiros." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT, - "Captura a tela com Shader de GPU se disponível." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_ROTATION, - "Força uma certa rotação da tela. A rotação é adicionada a rotação que o núcleo definir." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FORCE_SRGB_DISABLE, - "Desabilita de forma forçada o suporte sRGB FBO. Alguns drivers Intel OpenGL no Windows possuem problemas de vídeo com o suporte sRGB FBO se estiver habilitado. Habilitando isto pode contornar o problema." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN, - "Inicia em tela cheia. Pode ser mudado a qualquer momento." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_WINDOWED_FULLSCREEN, - "Se estiver em tela cheia, prefira utilizar uma janela de tela cheia." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_GPU_RECORD, - "Grava o material de saída do Shader de GPU se disponível." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX, - "Ao criar um Estado de Jogo, o índice do Estado de Jogo é aumentado automaticamente antes de ser salvo. Ao carregar um conteúdo, o índice será definido para o índice mais alto existente." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE, - "Bloqueia a SRAM de ser sobrescrita ao carregar um Estado de Jogo. Pode causar problemas no jogo." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO, - "Taxa máxima em que o conteúdo será executado quando utilizado o Avanço Rápido (ex: 5.0x para conteúdos em 60fps = 300 fps máx). Se for definido como 0.0x, a taxa de Avanço Rápido é ilimitada (sem FPS máx)." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, - "Quando está em Câmera Lenta, o conteúdo será diminuído pelo fator especificado/definido." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_RUN_AHEAD_ENABLED, - "Executar o núcleo lógico um ou mais quadros à frente e carreguar o estado de volta para reduzir o atraso dos controles percebido." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_RUN_AHEAD_FRAMES, - "O número de quadros para avançar. Causa problemas de jogabilidade, como instabilidade, se você exceder o número de quadros de atraso internos do jogo." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_RUN_AHEAD_SECONDARY_INSTANCE, - "Usa uma segunda instância do núcleo do RetroArch para avançar quadros. Evita problemas de áudio devido ao estado de carregamento." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_RUN_AHEAD_HIDE_WARNINGS, - "Oculta a mensagem de aviso que aparece ao usar o Adiantar Quadro e o núcleo não suporta Estados de Jogo." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_REWIND_ENABLE, - "Habilita a Rebobinagem. Isso irá impactar o desempenho ao jogar." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_REWIND_GRANULARITY, - "Ao definir um número de quadros para Rebobinagem, você pode retroceder vários quadros de uma só vez, aumentando a velocidade da função." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL, - "Define o nível de registro de eventos para os núcleos. Se o nível do registro enviado por um núcleo for abaixo deste valor, o mesmo é ignorado." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_PERFCNT_ENABLE, - "Habilitar os contadores de desempenho para o RetroArch (e núcleos)." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_SAVE, - "Cria automaticamente um Estado de Jogo no final da execução do RetroArch. O RetroArch irá carregar automaticamente este Estado de Jogo se a função 'Autocarregar Estado de Jogo' estiver habilitada." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_LOAD, - "Carrega automaticamente o último Estado de Jogo auto salvo na inicialização do RetroArch." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_THUMBNAIL_ENABLE, - "Mostrar miniaturas de estados salvos dentro do menu." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL, - "Salvar automaticamente o Save RAM não-volátil em um intervalo regular. Isso está desabilitado por padrão, a menos que seja definido de outra forma. O intervalo é medido em segundos. Um valor de 0 desativa o salvamento automático." - ) + MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, + "Arquivo de Trapaça" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE, - "Se ativado, substitui os vínculos de entrada com as associações remapeadas definidas para o núcleo atual." - ) + MENU_ENUM_LABEL_VALUE_CHEAT_FILE, + "Arquivo de Trapaça" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AUTODETECT_ENABLE, - "Habilita a detecção automática de entrada. Tentará configurar automaticamente joypads, estilo Plug-and-Play." - ) + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD, + "Carregar Arquivo de Trapaça" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_INPUT_SWAP_OK_CANCEL, - "Troca de botões para OK/Cancelar. Desabilitado é o estilo de botão japonês, habilitada é oestilo ocidental." - ) + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD_APPEND, + "Carregar Arquivo de Trapaça (Anexado)" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_PAUSE_LIBRETRO, - "Se desabilitado, o conteúdo continuará sendo executado em segundo plano quando o menu do RetroArch for alternado." - ) + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, + "Salvar Arquivo de Trapaça Como" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_DRIVER, - "Driver de vídeo para usar." - ) + MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, + "Estágios de Trapaça" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_DRIVER, - "Driver de áudio para usar." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION, + "Descrição" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_DRIVER, - "Driver de entrada para usar. Dependendo do driver de vídeo, pode forçar um driver de entrada diferente." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, + "Conquistas no Modo Hardcore" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_JOYPAD_DRIVER, - "Driver do Joypad para usar." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_ENABLE, + "Tabelas de Classificação" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_DRIVER, - "Driver de reamostragem de áudio a ser utilizado." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_BADGES_ENABLE, + "Insígnias de Conquistas" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CAMERA_DRIVER, - "Driver de câmera a ser utilizado." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, + "Conquistas Bloqueadas:" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LOCATION_DRIVER, - "Driver de localização a ser utilizado." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY, + "Bloqueada" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_DRIVER, - "Driver de menu a ser utilizado." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS, + "Retro Achievements" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RECORD_DRIVER, - "Driver de gravação a ser utilizado." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL, + "Testar Conquistas Não Oficiais" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_WIFI_DRIVER, - "Driver de WiFi a ser utilizado." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS, + "Conquistas Desbloqueadas:" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, - "Filtra os arquivos em exibição no explorador de arquivos por extensões suportadas." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY, + "Desbloqueada" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_WALLPAPER, - "Seleciona uma imagem para definir como plano de fundo do menu." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY_HARDCORE, + "Hardcore" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPER, - "Carrega dinamicamente um novo plano de fundo dependendo do contexto." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_VERBOSE_ENABLE, + "Modo Detalhado das Conquistas" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_DEVICE, - "Substitui o dispositivo de áudio padrão utilizado pelo driver de áudio. Isto depende do driver." - ) + MENU_ENUM_LABEL_VALUE_CHEEVOS_AUTO_SCREENSHOT, + "Captura de Conquistas Automática" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_DSP_PLUGIN, - "Plugin DSP de Áudio que processa o áudio antes de ser enviado para o driver." - ) + MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, + "Fechar Conteúdo" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_OUTPUT_RATE, - "Taxa de amostragem da saída de áudio." - ) + MENU_ENUM_LABEL_VALUE_CONFIG, + "Configuração" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_OVERLAY_OPACITY, - "Opacidade de todos os elementos de interface da Transparência." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_OVERLAY_SCALE, - "Escala de todos os elementos de interface da Transparência." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_OVERLAY_ENABLE, - "Habilita a Transparência." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_OVERLAY_PRESET, - "Seleciona uma Transparência pelo navegador de arquivos." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_IP_ADDRESS, - "Endereço do hospedeiro a se conectar." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_TCP_UDP_PORT, - "Porta do endereço de IP do hospedeiro. Pode ser uma porta TCP ou uma porta UDP." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_PASSWORD, - "Senha para conectar ao hospedeiro de Netplay. Utilizado apenas no modo hospedeiro." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_PUBLIC_ANNOUNCE, - "Anunciar os jogos de Netplay publicamente. Se não for definido, os clientes deverão conectar manualmente em vez de usar o lobby público." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_SPECTATE_PASSWORD, - "Senha para conectar ao hospedeiro de Netplay apenas com privilégios de espectador. Utilizado apenas no modo hospedeiro." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_START_AS_SPECTATOR, - "Define se o Netplay deve iniciar em modo espectador." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_ALLOW_SLAVES, - "Define se conexões em modo escravo são permitidas. Clientes em modo escravo requerem muito pouco poder de processamento em ambos os lados, mas irão sofrer significamente da latência de rede." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_REQUIRE_SLAVES, - "Define se conexões que não estão em modo escravo são proibidas. Não recomendado, exceto para redes muito rápidas com máquinas muito lentas." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_STATELESS_MODE, - "Define se deve executar o Netplay em modo que não utilize Estados de Jogo. Se definido como verdadeiro, uma rede muito rápida é necessária, mas Rebobinagem não é permitido, então não haverá oscilação no Netplay." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_CHECK_FRAMES, - "Frequência em quadros no qual o Netplay verificará se o hospedeiro e o cliente estão sincronizados." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_NAT_TRAVERSAL, - "Ao hospedar uma partida, tente receber conexões da Internet pública usando UPnP ou tecnologias similares para escapar das redes locais." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_STDIN_CMD_ENABLE, - "Habilitar interface de comando stdin." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_MOUSE_ENABLE, - "Habilitar controle por Mouse dentro do menu." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_POINTER_ENABLE, - "Habilitar controle por toque dentro do menu." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_THUMBNAILS, - "Tipo de miniatura a ser exibida." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS, - "Tipo de miniatura para exibir à esquerda." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_XMB_VERTICAL_THUMBNAILS, - "Exibe a miniatura esquerda sob a direita, no lado direito da tela.") -MSG_HASH( - MENU_ENUM_SUBLABEL_TIMEDATE_ENABLE, - "Exibir data e/ou hora atuais dentro do menu." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_BATTERY_LEVEL_ENABLE, - "Exibir o nível de bateria atual dentro do menu." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NAVIGATION_WRAPAROUND, - "Voltar ao início ou final se o limite da lista for alcançado horizontalmente ou verticalmente." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_HOST, - "Habilita o Netplay no modo hospedeiro (servidor)." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, - "Habilita o Netplay no modo cliente.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, - "Desconecta de uma conexão de Netplay ativa.") -MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Analisa um diretório por arquivos compatíveis e os adiciona à coleção.") -MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Analisa um arquivo compatível e o adiciona à coleção.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, - "Usa um intervalo de troca personalizado para V-Sync. Defina para reduzir efetivamente a taxa de atualização do monitor pela metade." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE, - "Ordenar os Jogos-Salvos em pastas com o nome do núcleo utilizado." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE, - "Ordenar os Estados de Jogo em pastas com o nome do núcleo utilizado." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REQUEST_DEVICE_I, - "Solicitar jogar com o dispositivo de entrada dado.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL, - "URL para o diretório de atualização de núcleos no buildbot do Libreto.") -MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL, - "URL para o diretório de atualizações de recursos no buildbot do Libretro.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, - "Após o download, extrair automaticamente os arquivos contidos nos arquivos comprimidos baixados." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, - "Analisar por novas salas.") -MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Remover esta entrada da coleção.") -MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, - "Visualizar mais informações sobre o conteúdo.") -MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, - "Adicionar o item aos seus favoritos.") -MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES_PLAYLIST, - "Adicionar o item aos seus favoritos.") -MSG_HASH(MENU_ENUM_SUBLABEL_RUN, - "Iniciar o conteúdo.") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_FILE_BROWSER_SETTINGS, - "Ajustar as definições do navegador de arquivos.") -MSG_HASH( - MENU_ENUM_SUBLABEL_AUTO_REMAPS_ENABLE, - "Habilitar por padrão controles personalizados na inicialização." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUTO_OVERRIDES_ENABLE, - "Habilitar por padrão configuração personalizada na inicialização." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_GAME_SPECIFIC_OPTIONS, - "Habilitar por padrão opções de núcleo personalizadas na inicialização.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_ENABLE, - "Exibir o nome do núcleo atual dentro do menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_DATABASE_MANAGER, - "Visualizar bases de dados.") -MSG_HASH(MENU_ENUM_SUBLABEL_CURSOR_MANAGER, - "Visualizar pesquisas anteriores.") -MSG_HASH(MENU_ENUM_SUBLABEL_TAKE_SCREENSHOT, - "Captura uma imagem da tela.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CLOSE_CONTENT, - "Fecha o conteúdo atual. Alterações não salvas serão perdidas." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_STATE, - "Carregar um Estado de Jogo do compartimento selecionado atualmente.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_STATE, - "Salvar um Estado de Jogo no compartimento selecionado atualmente.") -MSG_HASH(MENU_ENUM_SUBLABEL_RESUME, - "Retomar a execução do conteúdo atual e sair do Menu Rápido.") -MSG_HASH(MENU_ENUM_SUBLABEL_RESUME_CONTENT, - "Retomar a execução do conteúdo atual e sair do Menu Rápido.") -MSG_HASH(MENU_ENUM_SUBLABEL_STATE_SLOT, - "Altera o compartimento do Estado de Jogo selecionado atualmente.") -MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_LOAD_STATE, - "Se um Estado de Jogo for carregado, o conteúdo voltará ao estado anterior ao carregamento.") -MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_SAVE_STATE, - "Se o Estado de Jogo foi sobrescrito, ele voltará ao Estado de Jogo salvo anteriormente.") -MSG_HASH( - MENU_ENUM_SUBLABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, - "Serviço Retro Achievements. Para mais informações, visite http://retroachievements.org (em inglês)" - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_ACCOUNTS_LIST, - "Gerenciar contas configuradas atualmente." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_META_REWIND, - "Gerenciar as configurações de Rebobinagem.") -MSG_HASH(MENU_ENUM_SUBLABEL_RESTART_CONTENT, - "Reinicia o conteúdo do começo.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, - "Salva um arquivo de redefinição de configuração que será aplicado a todo o conteúdo carregado por este núcleo. Terá prioridade sobre a configuração principal.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, - "Salva um arquivo de redefinição de configuração que será aplicado a todo o conteúdo carregado no mesmo diretório que o arquivo atual. Terá prioridade sobre a configuração principal.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, - "Salva um arquivo de redefinição de configuração que será aplicado apenas ao conteúdo atual. Terá prioridade sobre a configuração principal.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_CHEAT_OPTIONS, - "Configurar códigos de Trapaça.") -MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_OPTIONS, - "Configurar Shader para realçar a aparência da imagem.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_INPUT_REMAPPING_OPTIONS, - "Alterar os controles para o conteúdo que está sendo executado.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_OPTIONS, - "Alterar as opções para o conteúdo que está sendo executado.") -MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, - "Exibir as configurações avançadas para usuários experientes (oculto por padrão).") -MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, - "Executar tarefas em linhas de processamento paralelas.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Permitir que o usuário possa remover itens das coleções.") -MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, - "Define o diretório de sistema. Os núcleos podem consultar este diretório para carregar arquivos de BIOS, configurações específicas do sistema, etc.") -MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, - "Define o diretório inicial do navegador de arquivos.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_DIR, - "Usualmente definido por desenvolvedores que agrupam aplicativos Libretro/RetroArch para apontar para os recursos." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPERS_DIRECTORY, - "Diretório para armazenar planos de fundo dinamicamente carregados pelo menu dependendo do contexto.") -MSG_HASH(MENU_ENUM_SUBLABEL_THUMBNAILS_DIRECTORY, - "Miniaturas auxiliares (arte da embalagem/imagens diversas e etc.) são armazenadas aqui." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_CONFIG_DIRECTORY, - "Define o diretório inicial para o navegador de configurações do menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, - "O número de quadros de latência de entrada para o Netplay utilizar para mascarar a latência da rede. Reduz a oscilação e torna o Netplay menos intensivo para a CPU, ao custo de atraso perceptível na entrada.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, - "O intervalo de quadros de latência de entrada que pode ser utilizado para mascarar a latência da rede. Reduz a oscilação e torna o Netplay menos intensivo para a CPU, ao custo de atraso imprevisível na entrada.") -MSG_HASH(MENU_ENUM_SUBLABEL_DISK_CYCLE_TRAY_STATUS, - "Alterna o disco atual. Se o disco estiver inserido, o mesmo será ejetado. Se o disco não estiver inserido, o mesmo será inserido.") -MSG_HASH(MENU_ENUM_SUBLABEL_DISK_INDEX, - "Mudar o índice do disco.") -MSG_HASH(MENU_ENUM_SUBLABEL_DISK_OPTIONS, - "Gerenciamento de imagem de disco.") -MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, - "Selecione uma imagem de disco para inserir.") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, - "Certifica-se de que a taxa de quadros é controlada enquanto estiver dentro do menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_LAYOUT, - "Selecione um layout diferente para a interface XMB.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_THEME, - "Selecionar um tema diferente para os ícones. As alterações terão efeito após reiniciar o programa.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, - "Habilitar as sombras para todos os ícones. Isto terá um pequeno impacto no desempenho.") -MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_COLOR_THEME, - "Selecionar um tema de gradiente de cor de plano de fundo diferente.") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_WALLPAPER_OPACITY, - "Modificar a opacidade do plano de fundo.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MENU_COLOR_THEME, - "Selecionar um tema de gradiente de cor de plano de fundo diferente.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_RIBBON_ENABLE, - "Selecionar um efeito de plano de fundo animado. Pode exigir mais processamento da GPU dependendo do efeito. Se o desempenho for insatisfatório, desligue este efeito ou reverta para um efeito mais simples.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_FONT, - "Selecionar uma fonte principal diferente para ser usada pelo menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_FAVORITES, - "Exibir a aba de favoritos dentro do menu principal.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_IMAGES, - "Exibir a aba de imagem dentro do menu principal.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_MUSIC, - "Exibir a aba de música dentro do menu principal.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_VIDEO, - "Exibir a aba de vídeo dentro do menu principal.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_NETPLAY, - "Exibir a aba de Netplay dentro do menu principal.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS, - "Mostrar a aba de configurações dentro do menu principal.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_HISTORY, - "Mostrar a aba de histórico recente dentro do menu principal.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_ADD, - "Mostrar a aba de importação de conteúdo dentro do menu principal.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_PLAYLISTS, - "Exibir abas da lista de reprodução dentro do menu principal.") -MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN, - "Exibir a tela inicial no menu. É automaticamente definido como falso após o programa iniciar pela primeira vez.") -MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY, - "Modificar a opacidade do gráfico do cabeçalho.") -MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_FOOTER_OPACITY, - "Modificar a opacidade do gráfico do rodapé.") -MSG_HASH(MENU_ENUM_SUBLABEL_DPI_OVERRIDE_ENABLE, - "O menu normalmente se dimensiona dinamicamente. Se você desejar definir uma escala de tamanho específica em vez disto, habilite esta função.") -MSG_HASH(MENU_ENUM_SUBLABEL_DPI_OVERRIDE_VALUE, - "Definir o tamanho do dimensionamento personalizado aqui. OBS: Você deve habilitar a função 'Redefinição de DPI' para que este dimensionamento tenha efeito.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_ASSETS_DIRECTORY, - "Salvar todos os arquivos baixados neste diretório.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_REMAPPING_DIRECTORY, - "Salvar todos os controles remapeados neste diretório.") -MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_DIR_PATH, - "Diretório onde o programa busca por conteúdo/núcleos.") -MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, - "Os arquivos de informação do aplicativo/núcleo são armazenados aqui.") -MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, - "Se um Joypad estiver conectado, o mesmo será autoconfigurado se um arquivo de configuração correspondente estiver presente dento deste diretório.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Salvar todas as coleções neste diretório.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, - "Se for definido um diretório, o conteúdo que é temporariamente extraído (ex: dos arquivos) sera extraído para este diretório." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_CURSOR_DIRECTORY, - "As consultas salvas são armazenadas neste diretório.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_DATABASE_DIRECTORY, - "As bases de dados são armazenadas neste diretório." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_ASSETS_DIRECTORY, - "Esta localização é consultada por padrão quando a interface do menu tenta procurar por recursos carregáveis, etc." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_SAVEFILE_DIRECTORY, - "Salvar todos os Jogos-Salvos neste diretório. Se não for definido, tentaremos salvar dentro do diretório de trabalho do arquivo.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVESTATE_DIRECTORY, - "Salvar todos os Estados de Jogo neste diretório. Se não for definido, tentaremos salvar dentro do diretório de trabalho do arquivo.") -MSG_HASH(MENU_ENUM_SUBLABEL_SCREENSHOT_DIRECTORY, - "Diretório para armazenar as capturas de tela.") -MSG_HASH(MENU_ENUM_SUBLABEL_OVERLAY_DIRECTORY, - "Define um diretório onde as Transparências são mantidas para fácil acesso.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_DATABASE_PATH, - "Os arquivos de Trapaça são mantidos aqui." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_FILTER_DIR, - "Diretório onde os arquivos de filtro DSP de áudio são mantidos." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FILTER_DIR, - "Diretório onde os arquivos de filtro de vídeo processado por CPU são mantidos." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_DIR, - "Define um diretório onde os arquivos de Shader de vídeo processado por GPU são mantidos para fácil acesso.") -MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_OUTPUT_DIRECTORY, - "As gravações serão armazenadas neste diretório.") -MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_CONFIG_DIRECTORY, - "As configurações de gravação serão mantidas aqui.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_PATH, - "Selecionar uma fonte diferente para as notificações na tela.") -MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_APPLY_CHANGES, - "As alterações das configurações de Shader terão efeito imediato. Use isto se você alterou a quantidade de estágios de Shader, filtros, escala FBO, etc.") -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHADER_NUM_PASSES, - "Aumentar ou diminuir a quantidade de estágios do pipeline de Shader. Você pode adicionar um Shader separado para cada estágio do pipeline e configurar sua escala e filtro." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET, - "Carregar uma predefinição de Shader. O pipeline de Shader será definido automaticamente.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_AS, - "Salvar as definições de Shader atuais como uma nova predefinição de Shader.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_CORE, - "Salvar as definições de Shader atuais como a definição padrão para esta aplicação/núcleo.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_PARENT, - "Salve as configurações atuais do shader como as configurações padrão para todos os arquivos no diretório de conteúdo atual.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_GAME, - "Salvar as definições de Shader atuais como a definição padrão para o conteúdo.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PARAMETERS, - "Modifica diretamente o Shader atual. As alterações não serão salvas no arquivo de predefinição.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_PARAMETERS, - "Modifica a predefinição de Shader atualmente utilizada no menu.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_NUM_PASSES, - "Aumentar ou diminuir a quantidade de Trapaças." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_CHEAT_APPLY_CHANGES, - "As alterações de Trapaça terão efeito imediato.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD, - "Carregar um arquivo de Trapaça." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_FILE_SAVE_AS, - "Salvar as Trapaças atuais como um arquivo de Jogo-Salvo." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SETTINGS, - "Acessar rapidamente todas as configurações relevantes ao jogo.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_INFORMATION, - "Visualizar informações sobre a aplicação/núcleo.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_ASPECT_RATIO, - "Valor em ponto flutuante da proporção de tela (largura / altura), utilizado se Proporção de Tela estiver definido como 'Configuração'.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT, - "Personalizar a altura da janela de exibição que é usada se a Proporção de Tela estiver definida como 'Personalizada'.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH, - "Personalizar a largura da janela de exibição que é usada se a Proporção de Tela estiver definida como 'Personalizada'.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_X, - "Deslocamento personalizado no eixo-X da janela de exibição. Será ignorado se a 'Escala em Inteiros' estiver habilitada. Neste caso ela será centralizada automaticamente.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_Y, - "Deslocamento personalizado no eixo-Y da janela de exibição. Será ignorado se a 'Escala em Inteiros' estiver habilitada. Neste caso ela será centralizada automaticamente.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_USE_MITM_SERVER, - "Utilizar Servidor MITM") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, - "Encaminhar conexões do Netplay através de um servidor 'homem no meio' (MITM). Útil se o hospedeiro estiver atrás de um firewall ou tiver problemas de NAT/UPnP.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MITM_SERVER, - "Localização do Servidor de Retransmissão") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_MITM_SERVER, - "Escolha um servidor de retransmissão específico para usar. Locais geograficamente mais próximos tendem a ter menor latência.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, - "Adicionar ao mixer") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_PLAY, - "Adicionar ao mixer e reproduzir") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION, - "Adicionar ao mixer") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY, - "Adicionar ao mixer e reproduzir") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER_BY_CURRENT_CORE, - "Filtrar por núcleo atual") -MSG_HASH( - MSG_AUDIO_MIXER_VOLUME, - "Volume global do mixer de áudio" - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_MIXER_VOLUME, - "Volume global do mixer de áudio (em dB). 0dB é o volume normal, e nenhum ganho será aplicado." - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_VOLUME, - "Nível de Volume do Mixer de Áudio (dB)" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_MUTE, - "Mixer de Áudio Mudo" - ) -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MIXER_MUTE, - "Mixer de áudio mudo/não-mudo.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_ONLINE_UPDATER, - "Exibir Atualizador Online") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_ONLINE_UPDATER, - "Exibir/ocultar a opção 'Atualizador Online'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_VIEWS_SETTINGS, - "Visualizações") -MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_VIEWS_SETTINGS, - "Exibir elementos na tela de menu." - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_CORE_UPDATER, - "Exibir Atualizador de Núcleos") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_CORE_UPDATER, - "Exibir/ocultar a opção de atualizar núcleos (e arquivos de informação de núcleo).") -MSG_HASH(MSG_PREPARING_FOR_CONTENT_SCAN, - "Preparando a busca de conteúdo...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_DELETE, - "Remover núcleo") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_DELETE, - "Remover este núcleo do disco.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FRAMEBUFFER_OPACITY, - "Opacidade do Framebuffer") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_FRAMEBUFFER_OPACITY, - "Modificar a opacidade do framebuffer.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES, - "Favoritos") -MSG_HASH(MENU_ENUM_SUBLABEL_GOTO_FAVORITES, - "Conteúdo adicionado aos 'Favoritos' vai aparecer aqui.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GOTO_MUSIC, - "Músicas") -MSG_HASH(MENU_ENUM_SUBLABEL_GOTO_MUSIC, - "Músicas que foram reproduzidas aparecem aqui.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GOTO_IMAGES, - "Imagens") -MSG_HASH(MENU_ENUM_SUBLABEL_GOTO_IMAGES, - "Imagens que foram exibidas aparecem aqui.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GOTO_VIDEO, - "Vídeos") -MSG_HASH(MENU_ENUM_SUBLABEL_GOTO_VIDEO, - "Vídeos que foram reproduzidos aparecem aqui.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_ICONS_ENABLE, - "Ícones do Menu") -MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_ICONS_ENABLE, - "Habilitar/desabilitar os ícones exibidos do lado esquerdo dos itens de menu.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MAIN_MENU_ENABLE_SETTINGS, - "Habilitar aba de configurações") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS_PASSWORD, - "Definir senha para habilitar aba de configurações") -MSG_HASH(MSG_INPUT_ENABLE_SETTINGS_PASSWORD, - "Digite a senha") -MSG_HASH(MSG_INPUT_ENABLE_SETTINGS_PASSWORD_OK, - "Senha correta.") -MSG_HASH(MSG_INPUT_ENABLE_SETTINGS_PASSWORD_NOK, - "Senha incorreta.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, - "Habilita a aba de configurações. É necessário reiniciar para que a aba apareça.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, - "O fornecimento de uma senha ao ocultar a aba de configurações permite restaurar mais tarde a partir do menu, indo para a aba Menu Principal, selecionando Habilitar aba configurações e inserindo a senha.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Permita que o usuário renomeie os itens nas coleções.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, - "Permitir renomear itens" ) -MSG_HASH(MENU_ENUM_SUBLABEL_RENAME_ENTRY, - "Renomear o título do item.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RENAME_ENTRY, - "Renomear") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, - "Exibir 'Carregar Núcleo'") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CORE, - "Exibir/ocultar a opção 'Carregar Núcleo'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CONTENT, - "Exibir Carregar Conteúdo") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CONTENT, - "Exibir/ocultar a opção 'Carregar Conteúdo'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_INFORMATION, - "Exibir Informação") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_INFORMATION, - "Exibir/ocultar a opção 'Informação'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_CONFIGURATIONS, - "Exibir Configurações") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_CONFIGURATIONS, - "Exibir/ocultar a opção 'Configurações'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_HELP, - "Exibir Ajuda") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_HELP, - "Exibir/ocultar a opção 'Ajuda'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_QUIT_RETROARCH, - "Exibir Sair do RetroArch") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_QUIT_RETROARCH, - "Exibir/ocultar a opção 'Sair do RetroArch'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_REBOOT, - "Exibir Reiniciar") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_REBOOT, - "Exibir/ocultar a opção 'Reiniciar'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_SHUTDOWN, - "Exibir Desligar") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_SHUTDOWN, - "Exibir/ocultar a opção 'Desligar'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_VIEWS_SETTINGS, - "Menu Rápido") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_VIEWS_SETTINGS, - "Exibir ou ocultar elementos na tela de Menu Rápido.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_TAKE_SCREENSHOT, - "Exibir 'Captura de Tela'") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT, - "Exibir/ocultar a opção 'Captura de Tela'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_LOAD_STATE, - "Exibir Salvar/Carregar Estado") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE, - "Exibir/ocultar as opções para salvar/carregar estados.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, - "Exibir Desfazer Salvar/Carregar Estado") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, - "Exibir/ocultar as opções para abolir o salvar/carregar estado.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_ADD_TO_FAVORITES, - "Exibir Adicionar aos Favoritos") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, - "Exibir/ocultar a opção 'Adicionar aos Favoritos'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_OPTIONS, - "Exibir Opções") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_OPTIONS, - "Exibir/ocultar a opção 'Opções'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CONTROLS, - "Exibir Controles") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CONTROLS, - "Exibir/ocultar a opção 'Controles'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CHEATS, - "Exibir Trapaças") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CHEATS, - "Exibir/ocultar a opção 'Trapaças'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SHADERS, - "Exibir 'Shaders'") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SHADERS, - "Exibir/ocultar a opção 'Shaders'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, - "Exibir Salvar Redefinição de Núcleo") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, - "Exibir/ocultar a opção 'Salvar Redefinição de Núcleo'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, - "Exibir Salvar Redefinição de Jogo") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, - "Exibir/ocultar a opção 'Salvar Redefinição de Jogo'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_INFORMATION, - "Exibir Informação") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_INFORMATION, - "Exibir/ocultar a opção 'Informação'.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_ENABLE, - "Ativar Notificação de Fundo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_RED, - "Notificação de Fundo em Cor Vermelha") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_GREEN, - "Notificação de Fundo em Cor Verde") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_BLUE, - "Notificação de Fundo em Cor Azul") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_OPACITY, - "Opacidade da Notificação de Fundo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DISABLE_KIOSK_MODE, - "Desabilitar o Modo Quiosque") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_DISABLE_KIOSK_MODE, - "Desabilita o Modo Quiosque. É necessária uma reinicialização para que a mudança tenha total efeito.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_ENABLE_KIOSK_MODE, - "Habilitar o Modo Quiosque") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENABLE_KIOSK_MODE, - "Protege a configuração escondendo todas as configurações relacionadas à configuração.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_KIOSK_MODE_PASSWORD, - "Definir senha para desabilitar o Modo Quiosque") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_KIOSK_MODE_PASSWORD, - "Fornecer uma senha ao habilitar o Modo Quiosque tornando possível desabilitar mais tarde a partir do menu, indo para o Menu Principal, selecionando Desabilitar o Modo Quiosque e inserindo a senha.") -MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD, - "Digite a Senha") -MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, - "Senha correta.") -MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, - "Senha incorreta.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_RED, - "Notificação em Cor Vermelha") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_GREEN, - "Notificação em Cor Verde") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_BLUE, - "Notificação em Cor Azul") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAMECOUNT_SHOW, - "Exibir contagem de quadros na tela FPS") -MSG_HASH(MSG_CONFIG_OVERRIDE_LOADED, - "Substituição de configuração carregada.") -MSG_HASH(MSG_GAME_REMAP_FILE_LOADED, - "Arquivo de remapeamento do jogo carregado.") -MSG_HASH(MSG_CORE_REMAP_FILE_LOADED, - "Arquivo de remapeamento principal carregado.") -MSG_HASH(MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES, - "O Adiantar Quadro foi desativado porque esse núcleo não suporta estados de jogo.") -MSG_HASH(MSG_RUNAHEAD_FAILED_TO_SAVE_STATE, - "Falha ao salvar o estado do jogo. O Adiantar Quadro foi desativado.") -MSG_HASH(MSG_RUNAHEAD_FAILED_TO_LOAD_STATE, - "Falha ao carregar o estado do jogo. O Adiandar Quadro foi desativado.") -MSG_HASH(MSG_RUNAHEAD_FAILED_TO_CREATE_SECONDARY_INSTANCE, - "Falha ao criar uma segunda instância. O Adiantar Quadro agora usará apenas uma instância.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, - "Adicione automaticamente conteúdo à lista de reprodução") -MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, - "Verifica automaticamente o conteúdo carregado para que eles apareçam dentro das listas de reprodução.") -MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, - "Verificação do arquivo terminado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_OPACITY, - "Opacidade da Janela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY, - "Qualidade da Reamostragem do Áudio") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, - "Abaixe esse valor para favorecer o desempenho/baixa latência em relação à qualidade de áudio, aumente se desejar melhor qualidade de áudio à custa do desempenho/baixa latência.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_WATCH_FOR_CHANGES, - "Ver arquivos de shader para mudanças") -MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_WATCH_FOR_CHANGES, - "Aplicar automaticamente as alterações feitas nos arquivos de shader no disco.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_SHOW_DECORATIONS, - "Exibir Decorações da Janela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STATISTICS_SHOW, - "Exibir estatísticas") -MSG_HASH(MENU_ENUM_SUBLABEL_STATISTICS_SHOW, - "Mostrar estatísticas técnicas na tela.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_ENABLE, - "Ativar preenchimento de borda") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, - "Ativar espessura de preenchimento de borda") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, - "Ativar espessura de preenchimento do plano de fundo") -MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, - "Para monitores CRT de 15 kHz apenas. Tenta usar a resolução exata do núcleo/jogo e a taxa de atualização.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, - "Trocar para Resolução CRT") -MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, - "Quando Trocar para Resolução CRT está ativada, força a resolução horizontal ultrawide para minimizar a alternância de modo.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, - "Super Resolução CRT") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, - "Exibir Configurações de Rebobinagem") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, - "Exibir/ocultar as opções de Rebobinagem.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_LATENCY, - "Exibir/ocultar as opções de Latência.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_LATENCY, - "Exibir Configurações de Latência") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_OVERLAYS, - "Exibir/ocultar as opções de Sobreposição.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_OVERLAYS, - "Exibir Configurações de Sobreposição") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE_MENU, - "Ativar áudio de menu") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_ENABLE_MENU, - "Ativar ou desativar o som do menu.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_SETTINGS, - "Configurações do Mixer") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MIXER_SETTINGS, - "Visualizar e/ou modificar as configurações do mixer de áudio.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_INFO, - "Informação") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_FILE, - "&Arquivo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_LOAD_CORE, - "&Carregar Núcleo...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_UNLOAD_CORE, - "&Descarregar Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_EXIT, - "Sai&r") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT, - "&Editar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT_SEARCH, - "&Pesquisar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW, - "&Visualizar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_CLOSED_DOCKS, - "Docas Fechadas") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS, - "&Opções...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS, - "Lembrar Posições da Doca:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY, - "Lembrar Geometria da Janela:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB, - "Lembrar a Última Aba do Navegador de Conteúdo:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME, - "Tema") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_SYSTEM_DEFAULT, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK, - "Escuro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM, - "Personalizado...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE, - "Opções") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOAD_CUSTOM_CORE, - "Carregar Núcleo Personalizado...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOAD_CORE, - "Carregar Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOADING_CORE, - "Carregando Núcleo...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_NAME, - "Nome") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE_VERSION, - "Versão") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_TAB_PLAYLISTS, - "Listas de Reprodução") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER, - "Navegador de Arquivos") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_TOP, - "Topo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_UP, - "Subir") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_DOCK_CONTENT_BROWSER, - "Navegador de Conteúdo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_BOXART, - "Arte da Capa") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_SCREENSHOT, - "Captura de Tela") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_TITLE_SCREEN, - "Tela de Título") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ALL_PLAYLISTS, - "Todas as Listas de Reprodução") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE, - "Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE_INFO, - "Informação do Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE_SELECTION_ASK, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_INFORMATION, - "Informação") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_WARNING, - "Advertência") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ERROR, - "Erro") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_RESTART_TO_TAKE_EFFECT, - "Por favor, reinicie o programa para que as alterações entrem em vigor.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOG, - "Relatório") + MENU_ENUM_LABEL_VALUE_CONFIGURATIONS, + "Carregar Configuração" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS, + "Configuração" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, + "Salvar Configuração ao Sair" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, + "Coleções" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, + "Base de Dados" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_DIR, + "Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, + "Tamanho da Lista de Histórico" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_REMOVE, + "Permitir a remoção de itens" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS, + "Menu Rápido" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIR, + "Recursos de Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIRECTORY, + "Downloads" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS, + "Trapaças" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_COUNTERS, + "Contadores do Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_ENABLE, + "Exibir nome do núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFORMATION, + "Informação do Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_AUTHORS, + "Autores" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_CATEGORIES, + "Categorias" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_LABEL, + "Rótulo do núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_NAME, + "Nome do núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE, + "Firmware(s)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES, + "Licença(s)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_PERMISSIONS, + "Permissões" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_SUPPORTED_EXTENSIONS, + "Extensões suportadas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_MANUFACTURER, + "Fabricante do sistema" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_NAME, + "Nome do sistema" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS, + "Controles" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_LIST, + "Carregar Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, + "Opções" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_SETTINGS, + "Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, + "Iniciar um Núcleo Automaticamente" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, + "Extrair automaticamente o arquivo baixado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_UPDATER_BUILDBOT_URL, + "URL de Núcleos do Buildbot" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST, + "Atualizador de Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SETTINGS, + "Atualizador" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CPU_ARCHITECTURE, + "Arquitetura da CPU:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CPU_CORES, + "Cores da CPU:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CURSOR_DIRECTORY, + "Cursor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CURSOR_MANAGER, + "Gerenciar Cursor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CUSTOM_RATIO, + "Proporção Personalizada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_MANAGER, + "Gerenciar Base de Dados" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_SELECTION, + "Seleção de Base de Dados" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DELETE_ENTRY, + "Remover" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FAVORITES, + "Diretório Inicial" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DIRECTORY_CONTENT, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DIRECTORY_DEFAULT, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DIRECTORY_NONE, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, + "Diretório não encontrado." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS, + "Diretório" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISK_CYCLE_TRAY_STATUS, + "Condição da Bandeja do Ciclo de Disco" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND, + "Anexar Imagem de Disco" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISK_INDEX, + "Índice de Disco" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISK_OPTIONS, + "Controle de Disco" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DONT_CARE, + "Não importa" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST, + "Downloads" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE, + "Baixar Núcleo..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT, + "Download de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_ENABLE, + "Habilitar Redefinição de DPI" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE, + "Redefinição de DPI" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS, + "Driver" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN, + "Carregar Modelo no Desligamento do Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHECK_FOR_MISSING_FIRMWARE, + "Verificar por Firmware que Falta Antes de Carregar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER, + "Plano de Fundo Dinâmico" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY, + "Planos de Fundo Dinâmicos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE, + "Habilitar Conquistas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR, + "Cor do item de menu ao passar o cursor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ENTRY_NORMAL_COLOR, + "Cor normal do item de menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FALSE, + "Falso" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FASTFORWARD_RATIO, + "Velocidade Máxima de Execução" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FAVORITES_TAB, + "Favoritos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FPS_SHOW, + "Mostrar Taxa de Quadros" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE, + "Controlar Velocidade Máxima de Execução" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VRR_RUNLOOP_ENABLE, + "Sincronizar Taxa de Atualização Exata ao Conteúdo (G-Sync, FreeSync)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, + "Controle de Quadros" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, + "Contadores do Frontend" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, + "Carrega Automaticamente Opções de Núcleo Específicas do Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE, + "Criar arquivo de opções do jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE, + "Salvar arquivo de opções do jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP, + "Ajuda" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING, + "Solução de Problemas de Áudio/Vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD, + "Alterando a Transparência de Gamepad Virtual" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_CONTROLS, + "Controles Básicos de Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_LIST, + "Ajuda" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_LOADING_CONTENT, + "Carregando Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT, + "Procurando em Busca de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_WHAT_IS_A_CORE, + "O Que é um Núcleo?" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HISTORY_LIST_ENABLE, + "Habilitar Lista de Histórico" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HISTORY_TAB, + "Histórico" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, + "Menu Horizontal" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_IMAGES_TAB, + "Imagem" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INFORMATION, + "Informação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INFORMATION_LIST, + "Informação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ADC_TYPE, + "Tipo de Analógico Para Digital" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ALL_USERS_CONTROL_MENU, + "Todos os Usuários Controlam o Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X, + "Analógico Esquerdo X" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_MINUS, + "Analógico Esquerdo X- (esquerda)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_PLUS, + "Analógico Esquerdo X+ (direita)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y, + "Analógico Esquerdo Y" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_MINUS, + "Analógico Esquerdo Y- (cima)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_PLUS, + "Analógico Esquerdo Y+ (baixo)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X, + "Analógico Direito X" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_MINUS, + "Analógico Direito X- (esquerda)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_PLUS, + "Analógico Direito X+ (direita)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y, + "Analógico Direito Y" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS, + "Analógico Direito Y- (cima)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS, + "Analógico Direito Y+ (baixo)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_TRIGGER, + "Gatinho da Pistola" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_RELOAD, + "Recarregar Pistola" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_A, + "Aux A da Pistola" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_B, + "Aux B da Pistola" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_C, + "Aux C da Pistola" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_START, + "Start da Pistola" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_SELECT, + "Select da Pistola" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_UP, + "D-pad Cima da Pistola" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_DOWN, + "D-pad Baixo da Pistola" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT, + "D-pad Esquerdo da Pistola" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, + "D-pad Direito da Pistola" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, + "Habilitar Autoconfiguração" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, + "Zona Morta do Controle Analógico" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, + "Inverter Botões OK e Cancelar do Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, + "Vincular Todos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL, + "Vincular Todos pelo Padrão" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_BIND_TIMEOUT, + "Tempo Limite para Vincular" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_BIND_HOLD, + "Vincular (Manter Pressionado)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_HIDE_UNBOUND, + "Ocultar Descritores de Entrada do Núcleo Não Vinculados" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_LABEL_SHOW, + "Exibir Rótulos do Descritor de Entrada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX, + "Índice de Dispositivo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_TYPE, + "Tipo de Dispositivo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_INDEX, + "Índice de Mouse" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_DRIVER, + "Driver de Entrada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_DUTY_CYCLE, + "Ciclo de Trabalho" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS, + "Vínculos das Teclas de Atalho da Entrada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE, + "Habilitar Mapeamento de Gamepad no Teclado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_A, + "Botão A (direita)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, + "Botão B (baixo)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_DOWN, + "Direcional para baixo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L2, + "Botão L2 (gatilho)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L3, + "Botão L3 (polegar)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L, + "Botão L (ombro)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT, + "Direcional Esquerdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R2, + "Botão R2 (gatilho)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R3, + "Botão R3 (polegar)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R, + "Botão R (ombro)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_RIGHT, + "Direcional Direito" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, + "Botão Select" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, + "Botão Start" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_UP, + "Direcional para Cima" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X, + "Botão X (topo)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, + "Botão Y (esquerda)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_KEY, + "(Tecla: %s)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_LEFT, + "Mouse 1" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_RIGHT, + "Mouse 2" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_MIDDLE, + "Mouse 3" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON4, + "Mouse 4" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON5, + "Mouse 5" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_UP, + "Roda do Mouse para Cima" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_DOWN, + "Roda do Mouse para Baixo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_UP, + "Roda do Mouse para Esquerda" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_DOWN, + "Roda do Mouse para Direita" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, + "Tipo de Mapeamento para Gamepad no Teclado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MAX_USERS, + "Usuários Máximos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, + "Combinação do Gamepad para Alternar Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS, + "Índice de Trapaça -" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS, + "Índice de Trapaça +" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE, + "Alternar Trapaça" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE, + "Alternar ejeção de disco" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT, + "Próximo disco" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, + "Disco anterior" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, + "Habilitar teclas de atalho" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY, + "Manter Avanço Rápido" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY, + "Alternar Avanço Rápido" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, + "Avanço de Quadro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, + "Alternar tela cheia" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, + "Alternar captura do Mouse" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, + "Alternar foco do jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE, + "Alternar menu desktop" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, + "Carregar Estado de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, + "Alternar menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE, + "Alternar gravação de filme" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, + "Alternar áudio mudo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, + "Alternar modo jogador/espectador do jogo em rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, + "Alternar teclado virtual" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, + "Próxima Transparência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE, + "Alternar pausa" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, + "Sair do RetroArch" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, + "Reiniciar jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, + "Rebobinar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_DETAILS, + "Detalhes da Trapaça" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_SEARCH, + "Iniciar ou Continuar a Pesquisa de Trapaça" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, + "Salvar Estado de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, + "Capturar tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, + "Próximo ahader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, + "Shader anterior" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_HOLD_KEY, + "Manter câmera lenta" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_KEY, + "Alternar câmera lenta" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, + "Compartimento do Estado de Jogo -" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, + "Compartimento do Estado de Jogo +" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, + "Volume -" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, + "Volume +" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_ENABLE, + "Mostrar Transparência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU, + "Ocultar Transparência no Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, + "Exibir Comandos Na Transparência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, + "Porta de Escuta do Exibir Comandos " + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR, + "Tipo de Comportamento da Chamada Seletiva" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_EARLY, + "Mais cedo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_LATE, + "Mais tarde" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_NORMAL, + "Normal" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_PREFER_FRONT_TOUCH, + "Preferir Toque Frontal" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_REMAPPING_DIRECTORY, + "Remapeamento de Entrada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_REMAP_BINDS_ENABLE, + "Habilitar Remapeamento de Vínculos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_SAVE_AUTOCONFIG, + "Salvar Autoconfiguração" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS, + "Entrada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE, + "Habilitar Teclado Pequeno" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_TOUCH_ENABLE, + "Habilitar Toque" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE, + "Habilitar Turbo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, + "Período do Turbo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_USER_BINDS, + "Vínculos de Entrada do Usuário %u" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LATENCY_SETTINGS, + "Latência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INTERNAL_STORAGE_STATUS, + "Condição do armazenamento interno" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_JOYPAD_AUTOCONFIG_DIR, + "Autoconfiguração de Entrada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_JOYPAD_DRIVER, + "Driver de Joypad" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LAKKA_SERVICES, + "Serviços" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_CHINESE_SIMPLIFIED, + "Chinês (Simplificado)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_CHINESE_TRADITIONAL, + "Chinês (Tradicional)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_DUTCH, + "Holandês" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_ENGLISH, + "Inglês" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_ESPERANTO, + "Esperanto" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_FRENCH, + "Francês" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_GERMAN, + "Alemão" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_ITALIAN, + "Italiano" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_JAPANESE, + "Japonês" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_KOREAN, + "Coreano" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_POLISH, + "Polonês" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_BRAZIL, + "Português (Brasil)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_PORTUGAL, + "Português (Portugal)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_RUSSIAN, + "Russo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_SPANISH, + "Espanhol" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_VIETNAMESE, + "Vietnamita" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_ARABIC, + "Árabe" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LEFT_ANALOG, + "Analógico Esquerdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH, + "Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LIBRETRO_INFO_PATH, + "Informação do Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LIBRETRO_LOG_LEVEL, + "Nível de Registro de Eventos do Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LINEAR, + "Linear" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOAD_ARCHIVE, + "Carregar Arquivo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY, + "Carregar Recente" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST, + "Carregar Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOAD_STATE, + "Carregar Estado de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOCATION_ALLOW, + "Permitir Localização" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOCATION_DRIVER, + "Driver de Localização" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS, + "Registro de Eventos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOG_VERBOSITY, + "Verbosidade do Registro de Eventos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MAIN_MENU, + "Menu Principal" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MANAGEMENT, + "Configurações da Base de Dados" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME, + "Tema de Cor do Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE, + "Azul" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE_GREY, + "Cinza Azulado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_DARK_BLUE, + "Azul Escuro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_GREEN, + "Verde" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_NVIDIA_SHIELD, + "Shield" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_RED, + "Vermelho" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_YELLOW, + "Amarelo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_FOOTER_OPACITY, + "Opacidade do Rodapé" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_HEADER_OPACITY, + "Opacidade do Cabeçalho" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_DRIVER, + "Driver de Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE, + "Controlar Taxa de Quadros do Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_FILE_BROWSER_SETTINGS, + "Configurações" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, + "Filtro Linear de Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_HORIZONTAL_ANIMATION, + "Animação Horizontal" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, + "Aparência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER, + "Plano de Fundo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY, + "Opacidade do plano de fundo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MISSING, + "Faltando" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MORE, + "..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MOUSE_ENABLE, + "Suporte para Mouse" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MULTIMEDIA_SETTINGS, + "Multimídia" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MUSIC_TAB, + "Música" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, + "Filtrar Extensões Desconhecidas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NAVIGATION_WRAPAROUND, + "Navegação Retorna ao Início" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NEAREST, + "Mais Próximo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY, + "Jogo em Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_ALLOW_SLAVES, + "Permitir Clientes em Modo Escravo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, + "Verificar Quadros do Jogo em Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN, + "Quadros de Latência de Entrada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, + "Faixa de Quadros de Latência de Entrada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES, + "Atraso de Quadros do Jogo em Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT, + "Desconectar do hospedeiro de jogo em rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE, + "Habilitar Jogo em Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT, + "Conectar ao hospedeiro de jogo em rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_HOST, + "Iniciar hospedeiro de jogo em rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_DISABLE_HOST, + "Parar hospedeiro de jogo em rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS, + "Endereço do Servidor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_LAN_SCAN_SETTINGS, + "Analisar a rede local" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, + "Habilitar Cliente de Jogo em Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, + "Usuário" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, + "Senha do Servidor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE, + "Anunciar Jogo em Rede Publicamente" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_REQUEST_DEVICE_I, + "Solicitar Dispositivo %u" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_REQUIRE_SLAVES, + "Não Permitir Clientes em Modo Não Escravo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, + "Configurações do jogo em rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG, + "Compartilhamento de Entrada Analógica" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_MAX, + "Máximo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_AVERAGE, + "Médio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL, + "Compartilhamento de Entrada Digital" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_OR, + "Compartilhar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_XOR, + "Agarrar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_VOTE, + "Eleger" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NONE, + "Nenhum" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NO_PREFERENCE, + "Sem preferência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_START_AS_SPECTATOR, + "Modo Espectador do Jogo em Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, + "Modo sem Estados de Jogo do Jogo em Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, + "Senha Apenas Espectador do Servidor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, + "Habilitar Espectador do Jogo em Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, + "Porta TCP do Jogo em Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, + "Travessia de NAT do Jogo em Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_CMD_ENABLE, + "Comandos de Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT, + "Porta de Comando de Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_INFORMATION, + "Informação de Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_ENABLE, + "Gamepad de Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_PORT, + "Porta Base Remota de Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_SETTINGS, + "Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO, + "Não" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NONE, + "Nenhum" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE, + "N/D" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_ACHIEVEMENTS_TO_DISPLAY, + "Não há Conquistas para mostrar." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_CORE, + "Nenhum Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_CORES_AVAILABLE, + "Nenhum núcleo disponível" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_CORE_INFORMATION_AVAILABLE, + "Não há informação de núcleo disponível." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_CORE_OPTIONS_AVAILABLE, + "Não há opções de núcleo disponíveis." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY, + "Não há itens para mostrar." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_HISTORY_AVAILABLE, + "Não há histórico disponível." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE, + "Não há informação disponível." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_ITEMS, + "Sem itens." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_NETPLAY_HOSTS_FOUND, + "Nenhum hospedeiro de jogo em rede encontrado." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, + "Nenhuma rede encontrada." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, + "Não há contadores de desempenho." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, + "Não há listas de reprodução." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_PLAYLIST_ENTRIES_AVAILABLE, + "Não há itens de lista de reprodução disponível." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, + "Nenhuma configuração encontrada." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, + "Não há parâmetros de Shader." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OFF, + "DESLIGADO" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ON, + "LIGADO" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ONLINE, + "Online" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER, + "Atualizador Online" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS, + "Exibição na Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS, + "Transparência na Tela" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ONSCREEN_OVERLAY_SETTINGS, + "Opções de controles de Notificações na Tela ou Molduras" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS, + "Notificações na Tela" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ONSCREEN_NOTIFICATIONS_SETTINGS, + "Ajusta as Notificações na Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OPEN_ARCHIVE, + "Navegar no Arquivo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OPTIONAL, + "Opcional" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY, + "Transparência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED, + "Carrega Automaticamente Transparência Favorita" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY_DIRECTORY, + "Transparência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY_OPACITY, + "Opacidade da Transparência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY_PRESET, + "Predefinição de Transparência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY_SCALE, + "Escala da Transparência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS, + "Transparência na Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PAL60_ENABLE, + "Utilizar Modo PAL60" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY, + "Diretório superior" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PAUSE_LIBRETRO, + "Pausar quando o menu for ativado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, + "Não rodar em segundo plano" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, + "Contadores de Desempenho" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, + "Listas de Reprodução" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, + "Lista de Reprodução" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, + "Listas de Reprodução" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, + "Suporte para Toque" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PORT, + "Porta" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PRESENT, + "Presente" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PRIVACY_SETTINGS, + "Privacidade" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_SETTINGS, + "MIDI" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH, + "Sair do RetroArch" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ANALOG, + "Analógico suportado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_BBFC_RATING, + "Classificação BBFC" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CERO_RATING, + "Classificação CERO" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_COOP, + "Cooperativo suportado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CRC32, + "CRC32" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DESCRIPTION, + "Descrição" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DEVELOPER, + "Desenvolvedor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_ISSUE, + "Edição da Revista Edge" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_RATING, + "Classificação da Revista Edge" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_REVIEW, + "Análise da Revista Edge" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ELSPA_RATING, + "Classificação ELSPA" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ENHANCEMENT_HW, + "Hardware de Aprimoramento" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ESRB_RATING, + "Classificação ESRB" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FAMITSU_MAGAZINE_RATING, + "Classificação da Revista Famitsu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FRANCHISE, + "Franquia" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_GENRE, + "Gênero" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_MD5, + "MD5" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME, + "Nome" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ORIGIN, + "Origem" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PEGI_RATING, + "Classificação PEGI" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PUBLISHER, + "Editor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_MONTH, + "Mês de Lançamento" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_YEAR, + "Ano de Lançamento" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RUMBLE, + "Suporte para Vibração" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SERIAL, + "Número de Série" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SHA1, + "SHA1" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_START_CONTENT, + "Iniciar Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, + "Classificação TGDB" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REBOOT, + "Reiniciar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY, + "Configuração de Gravação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORDING_OUTPUT_DIRECTORY, + "Saída de Gravação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, + "Gravação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, + "Carregar Configuração de Gravação..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORD_DRIVER, + "Driver de Gravação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_DRIVER, + "Driver MIDI" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORD_ENABLE, + "Habilitar Gravação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORD_PATH, + "Salvar Saída de Gravação Como..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORD_USE_OUTPUT_DIRECTORY, + "Salvar Gravações no Diretório de Saída" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE, + "Arquivo de Remapeamento" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_LOAD, + "Carregar Arquivo de Remapeamento" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CORE, + "Salvar Arquivo de Remapeamento de Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CONTENT_DIR, + "Salvar Remapeamento de Controle para o Diretório de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_GAME, + "Salvar Arquivo de Remapeamento de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CORE, + "Excluir Arquivo de Remapeamento de Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_GAME, + "Excluir Arquivo de Remapeamento de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CONTENT_DIR, + "Excluir Arquivo de Remapeamento de Jogo do Diretório de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REQUIRED, + "Obrigatório" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RESTART_CONTENT, + "Reiniciar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH, + "Reiniciar RetroArch" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RESUME, + "Continuar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RESUME_CONTENT, + "Continuar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RETROKEYBOARD, + "RetroKeyboard" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RETROPAD, + "RetroPad" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RETROPAD_WITH_ANALOG, + "RetroPad com Analógico" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS, + "Conquistas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REWIND_ENABLE, + "Habilitar Rebobinagem" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_AFTER_TOGGLE, + "Aplicar Após Alternar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_AFTER_LOAD, + "Aplicar Automaticamente Trapaças Durante o Carregamento do Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REWIND_GRANULARITY, + "Níveis da Rebobinamento" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE, + "Tamanho do Buffer da Rebobinamento (MB)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE_STEP, + "Tamanho do Intervalo de Ajuste do Buffer (MB)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS, + "Rebobinamento" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SETTINGS, + "Configurações da Trapaça" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DETAILS_SETTINGS, + "Detalhes da Trapaça" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_SETTINGS, + "Iniciar ou Continuar a Pesquisa de Trapaça" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY, + "Navegador de Arquivos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY, + "Configuração" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN, + "Mostrar Tela Inicial" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG, + "Analógico Direito" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES, + "Adicionar aos Favoritos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST, + "Adicionar aos Favoritos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RESET_CORE_ASSOCIATION, + "Redefinir Associação do Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUN, + "Executar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUN_MUSIC, + "Executar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAMBA_ENABLE, + "Habilitar SAMBA" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVEFILE_DIRECTORY, + "Arquivo de Jogo-Salvo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX, + "Índice Automático de Estado de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD, + "Carrega Automaticamente Estado de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE, + "Salvar Automaticamente Estado de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATE_DIRECTORY, + "Arquivo de Estado de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE, + "Miniaturas do Estado de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG, + "Salvar Configuração Atual" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, + "Salvar Redefinição de Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, + "Salvar Redefinições do Diretório de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, + "Salvar Redefinição de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVE_NEW_CONFIG, + "Salvar Nova Configuração" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVE_STATE, + "Salvar Estado de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS, + "Salvando" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY, + "Analisar Diretório" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCAN_FILE, + "Analisar Arquivo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCREENSHOT_DIRECTORY, + "Captura de Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION, + "Resolução da Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SEARCH, + "Procurar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SECONDS, + "segundos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SETTINGS, + "Configurações" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SETTINGS_TAB, + "Configurações" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER, + "Shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_APPLY_CHANGES, + "Aplicar Alterações" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS, + "Shaders" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON, + "Faixa" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON_SIMPLIFIED, + "Faixa (simplificada)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SIMPLE_SNOW, + "Neve Simples" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOW, + "Neve" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHOW_ADVANCED_SETTINGS, + "Exibir Configurações Avançadas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHOW_HIDDEN_FILES, + "Exibir Arquivos e Pastas Ocultos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHUTDOWN, + "Desligar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO, + "Taxa de Câmera Lenta" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_ENABLED, + "Adiantar Quadro para Reduzir a Latência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_FRAMES, + "Número de Quadros para Adiantar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_SECONDARY_INSTANCE, + "O Adiantamento de Quadro Usará uma Segunda Instância" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_HIDE_WARNINGS, + "Ocultar Avisos do Adiantamento de Quadro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SORT_SAVEFILES_ENABLE, + "Classificar Arquivos de Jogo-Salvo em Pastas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SORT_SAVESTATES_ENABLE, + "Classificar Arquivos de Estado de Jogo em Pastas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATES_IN_CONTENT_DIR_ENABLE, + "Gravar Estados de Jogo no Diretório de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVEFILES_IN_CONTENT_DIR_ENABLE, + "Gravar Jogos-Salvos no Diretório de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEMFILES_IN_CONTENT_DIR_ENABLE, + "Arquivos de Sistema estão no Diretório de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCREENSHOTS_IN_CONTENT_DIR_ENABLE, + "Salvar Capturas de Tela no Diretório de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SSH_ENABLE, + "Habilitar SSH" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_START_CORE, + "Iniciar Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_START_NET_RETROPAD, + "Iniciar RetroPad Remoto" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_START_VIDEO_PROCESSOR, + "Iniciar Processador de Vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_STATE_SLOT, + "Compartimento do Estado de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_STATUS, + "Condição" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_STDIN_CMD_ENABLE, + "Comandos stdin" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES, + "Núcleos Sugeridos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SUSPEND_SCREENSAVER_ENABLE, + "Desativar Protetor de Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_BGM_ENABLE, + "Habilitar Música em Segundo Plano do Sistema" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_DIRECTORY, + "Sistema/BIOS" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFORMATION, + "Informação do Sistema" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_7ZIP_SUPPORT, + "Suporte a 7zip" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ALSA_SUPPORT, + "Suporte a ALSA" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_BUILD_DATE, + "Data de Compilação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CG_SUPPORT, + "Suporte a Cg" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COCOA_SUPPORT, + "Suporte a Cocoa" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COMMAND_IFACE_SUPPORT, + "Suporte à Interface de Comando" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CORETEXT_SUPPORT, + "Suporte a CoreText" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CPU_FEATURES, + "Características de CPU" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_DPI, + "Métrica DPI da Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_HEIGHT, + "Métrica de Altura da Tela (mm)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_WIDTH, + "Métrica de Largura da Tela (mm)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DSOUND_SUPPORT, + "Suporte a DirectSound" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WASAPI_SUPPORT, + "Suporte a WASAPI" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYLIB_SUPPORT, + "Suporte à biblioteca dinâmica" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYNAMIC_SUPPORT, + "Carregamento dinâmico em tempo de execução da biblioteca libretro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_EGL_SUPPORT, + "Suporte a EGL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FBO_SUPPORT, + "Suporte a OpenGL/Direct3D render-to-texture (multi-pass shaders)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FFMPEG_SUPPORT, + "Suporte a FFmpeg" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FREETYPE_SUPPORT, + "Suporte a FreeType" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_IDENTIFIER, + "Identificador do Frontend" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_NAME, + "Nome do Frontend" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_OS, + "SO do Frontend" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GIT_VERSION, + "Versão Git" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GLSL_SUPPORT, + "Suporte a GLSL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_HLSL_SUPPORT, + "Suporte a HLSL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_JACK_SUPPORT, + "Suporte a JACK" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_KMS_SUPPORT, + "Suporte a KMS/EGL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LAKKA_VERSION, + "Versão Lakka" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, + "Suporte a LibretroDB" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, + "Suporte a Libusb" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, + "Suporte a libxml2 XML parsing" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, + "Suporte de jogo em rede (ponto-a-ponto)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, + "Suporte à Interface de comando de rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_REMOTE_SUPPORT, + "Suporte a Gamepad de Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENAL_SUPPORT, + "Suporte a OpenAL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGLES_SUPPORT, + "Suporte a OpenGL ES" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGL_SUPPORT, + "Suporte a OpenGL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENSL_SUPPORT, + "Suporte a OpenSL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENVG_SUPPORT, + "Suporte a OpenVG" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OSS_SUPPORT, + "Suporte a OSS" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OVERLAY_SUPPORT, + "Suporte à Transparência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE, + "Fonte de Energia" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGED, + "Carregado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGING, + "Carregando" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_DISCHARGING, + "Descarregando" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_NO_SOURCE, + "Não há fonte" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PULSEAUDIO_SUPPORT, + "Suporte a PulseAudio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PYTHON_SUPPORT, + "Suporte a Python (suporte de script em Shaders)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RBMP_SUPPORT, + "Suporte a BMP (RBMP)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RETRORATING_LEVEL, + "Nível RetroRating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RJPEG_SUPPORT, + "Suporte a JPEG (RJPEG)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ROARAUDIO_SUPPORT, + "Suporte a RoarAudio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RPNG_SUPPORT, + "Suporte a PNG (RPNG)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RSOUND_SUPPORT, + "Suporte a RSound" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RTGA_SUPPORT, + "Suporte a TGA (RTGA)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL2_SUPPORT, + "Suporte a SDL2" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_IMAGE_SUPPORT, + "Suporte a imagem SDL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_SUPPORT, + "Suporte a SDL1.2" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SLANG_SUPPORT, + "Suporte a Slang" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_THREADING_SUPPORT, + "Suporte a Paralelismo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_UDEV_SUPPORT, + "Suporte a Udev" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_V4L2_SUPPORT, + "Suporte a Video4Linux2" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VIDEO_CONTEXT_DRIVER, + "Driver de contexto de vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VULKAN_SUPPORT, + "Suporte a Vulkan" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_METAL_SUPPORT, + "Suporte a Metal" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WAYLAND_SUPPORT, + "Suporte a Wayland" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_X11_SUPPORT, + "Suporte a X11" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XAUDIO2_SUPPORT, + "Suporte a XAudio2" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XVIDEO_SUPPORT, + "Suporte a XVideo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ZLIB_SUPPORT, + "Suporte a Zlib" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT, + "Capturar tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, + "Paralelismo de tarefas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAILS, + "Miniaturas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS, + "Miniaturas à Esquerda" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS, + "Disposição Vertical de Miniaturas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, + "Miniaturas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST, + "Atualizador de Miniaturas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS, + "Arte da Embalagem" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS, + "Capturas de Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS, + "Telas do Título" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TIMEDATE_ENABLE, + "Exibir data e hora" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TITLE_COLOR, + "Cor do título do menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TRUE, + "Verdadeiro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UI_COMPANION_ENABLE, + "Habilitar Companheiro da Interface de Usuário" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UI_COMPANION_START_ON_BOOT, + "Companheiro da Interface de Usuário Roda na Inicialização" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UI_COMPANION_TOGGLE, + "Mostrar menu desktop na inicialização" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DESKTOP_MENU_ENABLE, + "Habilitar menu desktop (reiniciar)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UI_MENUBAR_ENABLE, + "Barra de Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE, + "Incapaz de ler o arquivo comprimido." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UNDO_LOAD_STATE, + "Desfazer Carregamento de Estado de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UNDO_SAVE_STATE, + "Desfazer Salvamento de Estado de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UNKNOWN, + "Desconhecido" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS, + "Atualizador" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_ASSETS, + "Atualizar Recursos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_AUTOCONFIG_PROFILES, + "Atualizar Perfis de Autoconfiguração" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_CG_SHADERS, + "Atualizar Shaders Cg" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_CHEATS, + "Atualizar Trapaças" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_CORE_INFO_FILES, + "Atualizar Arquivos de Informação de Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_DATABASES, + "Atualizar Bases de Dados" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_GLSL_SHADERS, + "Atualizar Shaders GLSL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_LAKKA, + "Atualizar Lakka" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_OVERLAYS, + "Atualizar Transparências" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_SLANG_SHADERS, + "Atualizar Shaders Slang" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USER, + "Usuário" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_KEYBOARD, + "Kbd" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS, + "Interface de Usuário" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USER_LANGUAGE, + "Idioma" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USER_SETTINGS, + "Usuário" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER, + "Utilizar o Visualizador de Imagem Integrado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USE_BUILTIN_PLAYER, + "Utilizar o Reprodutor de Mídia Integrado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_ALLOW_ROTATE, + "Permitir rotação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO, + "Configurar Proporção de Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_AUTO, + "Proporção de Tela Automática" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, + "Proporção de Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, + "Inserção de Quadro Opaco" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, + "Cortar Overscan (Recarregar)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, + "Desativar Composição da Área de Trabalho" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, + "Driver de Vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, + "Filtro de Vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_DIR, + "Filtro de Vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_FLICKER, + "Filtro de tremulação de vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FONT_ENABLE, + "Habilitar Notificações na Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FONT_PATH, + "Fonte das Notificações na Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FONT_SIZE, + "Tamanho da Notificação na Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_ASPECT, + "Forçar Proporção de Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_SRGB_DISABLE, + "Forçar Desativação de sRGB FBO" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FRAME_DELAY, + "Atraso de Quadro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN, + "Iniciar em Modo de Tela Cheia" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_GAMMA, + "Gama de Vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_GPU_RECORD, + "Usar Gravação da GPU" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT, + "Habilitar Captura de Tela da GPU" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, + "Sincronia Rígida de GPU" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES, + "Quadros de Sincronia Rígida de GPU" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES, + "Máximo de imagens na cadeia de troca" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_X, + "Posição X da Notificação na Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_Y, + "Posição Y da Notificação na Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MONITOR_INDEX, + "Índice de Monitor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_POST_FILTER_RECORD, + "Usar Gravação Pós-Filtro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, + "Taxa de Atualização Vertical" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, + "Taxa de Quadros Estimada da Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Definir Taxa de Atualização Reportada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, + "Rotação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, + "Escala em Janela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER, + "Escala em Inteiros" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS, + "Vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DIR, + "Shader de Vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_NUM_PASSES, + "Estágios de Shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS, + "Pré-visualizar Parâmetros de Shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET, + "Carregar Predefinição de Shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS, + "Salvar Predefinição de Shader Como" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE, + "Salvar Predefinição de Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_PARENT, + "Salvar Predefinição do Diretório de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME, + "Salvar Predefinição de Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT, + "Habilitar Contexto Compartilhado de Hardware" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH, + "Filtragem Bilinear" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER, + "Habilitar Filtro por Software" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SWAP_INTERVAL, + "Intervalo de Troca da Sincronização Vertical (V-Sync)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_TAB, + "Vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_THREADED, + "Vídeo Paralelizado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VFILTER, + "Reduzir Tremulação de Vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_HEIGHT, + "Altura Personalizada da Proporção de Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_WIDTH, + "Largura Personalizada da Proporção de Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X, + "Posição X Personalizada da Proporção de Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_Y, + "Posição Y Personalizada da Proporção de Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, + "Definir Largura de Tela do VI" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, + "Sincronização Vertical (V-Sync)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, + "Modo Janela em Tela Cheia" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_WIDTH, + "Largura da Janela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_HEIGHT, + "Altura da Janela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_X, + "Largura em Tela Cheia" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_Y, + "Altura em Tela Cheia" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_WIFI_DRIVER, + "Driver de Wi-Fi" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, + "Wi-Fi" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, + "Fator Alfa do Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_RED, + "Cor Vermelha da Fonte do Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_GREEN, + "Cor Verde da Fonte do Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_BLUE, + "Cor Azul da Fonte do Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_FONT, + "Fonte do Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, + "Personalizado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_FLATUI, + "FlatUI" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME, + "Monocromático" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME_INVERTED, + "Monocromático Invertido" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_SYSTEMATIC, + "Sistemático" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_NEOACTIVE, + "NeoActive" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL, + "Pixel" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE, + "RetroActive" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM, + "Retrosystem" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART, + "Dot-Art" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_AUTOMATIC, + "Automático" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME, + "Tema de Cor do Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_APPLE_GREEN, + "Verde Maçã" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK, + "Escuro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LIGHT, + "Claro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MORNING_BLUE, + "Azul da manhã" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK_PURPLE, + "Roxo Escuro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_ELECTRIC_BLUE, + "Azul Elétrico" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_GOLDEN, + "Dourado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LEGACY_RED, + "Vermelho Legado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MIDNIGHT_BLUE, + "Azul Meia-noite" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_PLAIN, + "Natural" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_UNDERSEA, + "Submarino" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_VOLCANIC_RED, + "Vermelho Vulcânico" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_RIBBON_ENABLE, + "Pipeline do Shader de Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_SCALE_FACTOR, + "Fator de Escala do Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE, + "Habilitar Sombras dos Ícones" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_HISTORY, + "Exibir Aba de Histórico" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_ADD, + "Exibir Aba de Importação de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_PLAYLISTS, + "Exibir Abas de Lista de Reprodução" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_FAVORITES, + "Exibir Aba de Favoritos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_IMAGES, + "Exibir Aba de Imagem" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_MUSIC, + "Exibir Aba de Música" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, + "Exibir Aba de Configurações" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, + "Exibir Aba de Vídeo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, + "Exibir Aba de Jogo em Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "Layout do Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_THEME, + "Tema de Ícones do Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_YES, + "Sim" + ) +MSG_HASH( + MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO, + "Predefinição de Shader" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, + "Habilita ou desabilita as conquistas. Para mais informações, visite http://retroachievements.org" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, + "Habilitar ou desabilitar conquistas não oficiais e/ou recursos beta para fins de teste." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, + "Habilita ou desabilita Estado de Jogo, Trapaças, Rebobinamento, Avanço Rápido, Pausa e Câmera Lenta para todos os jogos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_LEADERBOARDS_ENABLE, + "Habilita ou desabilita tabelas de classificação no jogo. Não tem efeito se o modo Hardcore estiver desativado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_BADGES_ENABLE, + "Habilita ou desabilita a exibição de insígnia na Lista de Conquistas." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_VERBOSE_ENABLE, + "Habilita ou desabilita detalhes das conquistas na tela." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_AUTO_SCREENSHOT, + "Obtém automaticamente uma captura de tela quando uma conquista é acionada." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, + "Altera os drivers utilizados pelo sistema." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, + "Altera as configurações de conquistas." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_SETTINGS, + "Altera as configurações de núcleo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RECORDING_SETTINGS, + "Altera as configurações de gravação." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ONSCREEN_DISPLAY_SETTINGS, + "Altera as configurações de Transparência e Transparência de teclado, e as configurações de notificação na tela." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_FRAME_THROTTLE_SETTINGS, + "Altera as configurações de Rebobinamento, Avanço Rápido e Câmera Lenta." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVING_SETTINGS, + "Altera as configurações de salvamento." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOGGING_SETTINGS, + "Altera as configurações de registro de eventos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_USER_INTERFACE_SETTINGS, + "Altera as configurações da interface de usuário." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_USER_SETTINGS, + "Altera as configurações de conta, nome de usuário e idioma." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, + "Altera as configurações de privacidade." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIDI_SETTINGS, + "Altera as configurações de MIDI." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, + "Altera os diretórios padrões onde os arquivos estão localizados." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, + "Altera as configurações de lista de reprodução." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, + "Ajusta as configurações de servidor e rede." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, + "Analisa o conteúdo e adiciona na base de dados." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, + "Altera as configurações de saída de áudio." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE, + "Habilita ou desabilita o bluetooth." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, + "Salva as alterações nos arquivos de configuração ao sair." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONFIGURATION_SETTINGS, + "Altera as definições padrões para os arquivos de configuração." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONFIGURATIONS_LIST, + "Gerencia e cria arquivos de configuração." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CPU_CORES, + "Quantidade de Cores que a CPU possui." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_FPS_SHOW, + "Exibe a taxa atual de quadros por segundo na tela." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS, + "Ajusta as configurações das teclas de atalho." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, + "Combinação de botões do Gamepad para alternar o menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_SETTINGS, + "Altera as configurações de Joypad, Teclado e Mouse." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_USER_BINDS, + "Configura os controles para este usuário." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LATENCY_SETTINGS, + "Altera as configurações relacionadas a vídeo, áudio e latência dos comandos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOG_VERBOSITY, + "Habilita ou desabilita o registro de eventos no terminal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY, + "Juntar-se ou hospedar uma sessão de jogo em rede." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, + "Procura e conecta aos hospedeiros de jogo em rede na rede local." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, + "Exibe informações de núcleo, rede e sistema." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ONLINE_UPDATER, + "Baixe complementos, componentes e conteúdo para o RetroArch." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAMBA_ENABLE, + "Habilita ou desabilita o compartilhamento de pastas na rede." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, + "Gerenciar serviços ao nível de sistema operacional." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES, + "Exibe arquivos/diretórios ocultos no navegador de arquivos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SSH_ENABLE, + "Habilita ou desabilita o acesso remoto à linha de comando." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE, + "Evita que a proteção de tela do seu sistema seja ativada." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_WINDOW_SCALE, + "Define o tamanho da janela em relação ao tamanho da janela de exibição do núcleo. Como alternativa, você pode definir uma largura e altura de janela abaixo para um tamanho de janela fixo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_USER_LANGUAGE, + "Define o idioma da interface." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, + "Insere um quadro opaco entre os quadros. Útil para usuários com telas de 120Hz que desejam jogar conteúdos em 60Hz para eliminar efeito de fantasma." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, + "Reduz a latência ao custo de maior risco de engasgamento de vídeo. Adiciona um atraso após o V-Sync (em ms)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, + "Define quantos quadros a CPU pode rodar à frente da GPU quando utilizado o recurso 'Sincronia Rígida de GPU'." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, + "Informar ao driver de vídeo para utilizar explicitamente um modo de buffer específico." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, + "Selecione qual tela de exibição a ser usada." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, + "A taxa de atualização estimada da tela em Hz." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED, + "A taxa de atualização conforme relatada pelo driver de vídeo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, + "Altera as configurações de saída de vídeo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_WIFI_SETTINGS, + "Analisa redes sem fio e estabelecer uma conexão." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_HELP_LIST, + "Saiba mais sobre como o programa funciona." + ) +MSG_HASH( + MSG_ADDED_TO_FAVORITES, + "Adicionado aos favoritos" + ) +MSG_HASH( + MSG_RESET_CORE_ASSOCIATION, + "A associação do núcleo de entrada da lista de reprodução foi redefinida." + ) +MSG_HASH( + MSG_APPENDED_DISK, + "Disco anexado" + ) +MSG_HASH( + MSG_APPLICATION_DIR, + "Diretório do aplicativo" + ) +MSG_HASH( + MSG_APPLYING_CHEAT, + "Aplicando as alterações de Trapaças." + ) +MSG_HASH( + MSG_APPLYING_SHADER, + "Aplicando Shader" + ) +MSG_HASH( + MSG_AUDIO_MUTED, + "Sem áudio." + ) +MSG_HASH( + MSG_AUDIO_UNMUTED, + "Áudio normal." + ) +MSG_HASH( + MSG_AUTOCONFIG_FILE_ERROR_SAVING, + "Erro em salvar o arquivo de autoconfiguração." + ) +MSG_HASH( + MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY, + "Arquivo de autoconfiguração salvo com sucesso." + ) +MSG_HASH( + MSG_AUTOSAVE_FAILED, + "Não foi possível inicializar o salvamento automático." + ) +MSG_HASH( + MSG_AUTO_SAVE_STATE_TO, + "Salvar Automaticamente Estado de Jogo em" + ) +MSG_HASH( + MSG_BLOCKING_SRAM_OVERWRITE, + "Bloqueando Sobrescrita da SRAM" + ) +MSG_HASH( + MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT, + "Trazendo a interface de comando na porta" + ) +MSG_HASH( + MSG_BYTES, + "bytes" + ) +MSG_HASH( + MSG_CANNOT_INFER_NEW_CONFIG_PATH, + "Não é possível inferir o novo caminho de configuração. Use a hora atual." + ) +MSG_HASH( + MSG_CHEEVOS_HARDCORE_MODE_ENABLE, + "Modo Hardcore Habilitado, Estados de Jogo e Rebobinamento estão desabilitados." + ) +MSG_HASH( + MSG_COMPARING_WITH_KNOWN_MAGIC_NUMBERS, + "Comparando com números mágicos conhecidos..." + ) +MSG_HASH( + MSG_COMPILED_AGAINST_API, + "Compilado contra a API" + ) +MSG_HASH( + MSG_CONFIG_DIRECTORY_NOT_SET, + "Diretório de configuração não definido. Não foi possível salvar a nova configuração." + ) +MSG_HASH( + MSG_CONNECTED_TO, + "Conectado a" + ) +MSG_HASH( + MSG_CONTENT_CRC32S_DIFFER, + "O CRC32 dos conteúdos difere. Não é possível utilizar jogos diferentes." + ) +MSG_HASH( + MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT, + "Carregamento de conteúdo ignorado. A implementação irá carregar por conta própria." + ) +MSG_HASH( + MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES, + "O núcleo não suporta Estados de Jogo." + ) +MSG_HASH( + MSG_CORE_OPTIONS_FILE_CREATED_SUCCESSFULLY, + "O arquivo de opções de núcleo foi criado com sucesso." + ) +MSG_HASH( + MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER, + "Não foi possível encontrar nenhum driver seguinte" + ) +MSG_HASH( + MSG_COULD_NOT_FIND_COMPATIBLE_SYSTEM, + "Não foi possível encontrar um sistema compatível." + ) +MSG_HASH( + MSG_COULD_NOT_FIND_VALID_DATA_TRACK, + "Não foi possível encontrar uma faixa de dados válida" + ) +MSG_HASH( + MSG_COULD_NOT_OPEN_DATA_TRACK, + "Não foi possível abrir a faixa de dados" + ) +MSG_HASH( + MSG_COULD_NOT_READ_CONTENT_FILE, + "Não foi possível ler o arquivo de conteúdo" + ) +MSG_HASH( + MSG_COULD_NOT_READ_MOVIE_HEADER, + "Não foi possível ler o cabeçalho do filme." + ) +MSG_HASH( + MSG_COULD_NOT_READ_STATE_FROM_MOVIE, + "Não foi possível ler o Estado de Jogo do filme." + ) +MSG_HASH( + MSG_CRC32_CHECKSUM_MISMATCH, + "Soma de verificação CRC32 incompatível entre o arquivo de conteúdo e a soma de verificação de conteúdo salva no cabeçalho do arquivo de reprodução. Reprodução altamente susceptível de dessincronizar na reprodução." + ) +MSG_HASH( + MSG_CUSTOM_TIMING_GIVEN, + "Tempo personalizado fornecido" + ) +MSG_HASH( + MSG_DECOMPRESSION_ALREADY_IN_PROGRESS, + "Descompressão já está em andamento." + ) +MSG_HASH( + MSG_DECOMPRESSION_FAILED, + "Descompressão falhou." + ) +MSG_HASH( + MSG_DETECTED_VIEWPORT_OF, + "Detectada janela de exibição de" + ) +MSG_HASH( + MSG_DID_NOT_FIND_A_VALID_CONTENT_PATCH, + "Não encontrou uma modificação de conteúdo válido." + ) +MSG_HASH( + MSG_DISCONNECT_DEVICE_FROM_A_VALID_PORT, + "Desconectar dispositivo de uma porta válida." + ) +MSG_HASH( + MSG_DISK_CLOSED, + "Fechado" + ) +MSG_HASH( + MSG_DISK_EJECTED, + "Ejetado" + ) +MSG_HASH( + MSG_DOWNLOADING, + "Baixando" + ) +MSG_HASH( + MSG_INDEX_FILE, + "index" + ) +MSG_HASH( + MSG_DOWNLOAD_FAILED, + "Download falhou" + ) +MSG_HASH( + MSG_ERROR, + "Erro" + ) +MSG_HASH( + MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT, + "O núcleo libretro requer conteúdo, mas nada foi fornecido." + ) +MSG_HASH( + MSG_ERROR_LIBRETRO_CORE_REQUIRES_SPECIAL_CONTENT, + "O núcleo libretro requer conteúdo especial, mas nenhum foi fornecido." + ) +MSG_HASH( + MSG_ERROR_PARSING_ARGUMENTS, + "Erro em analisar os argumentos." + ) +MSG_HASH( + MSG_ERROR_SAVING_CORE_OPTIONS_FILE, + "Erro em salvar o arquivo de opções de núcleo." + ) +MSG_HASH( + MSG_ERROR_SAVING_REMAP_FILE, + "Erro em salvar o arquivo de remapeamento." + ) +MSG_HASH( + MSG_ERROR_REMOVING_REMAP_FILE, + "Erro em remover o arquivo de remapeamento." + ) +MSG_HASH( + MSG_ERROR_SAVING_SHADER_PRESET, + "Erro em salvar a predefinição de Shader." + ) +MSG_HASH( + MSG_EXTERNAL_APPLICATION_DIR, + "Diretório de Aplicativo Externo" + ) +MSG_HASH( + MSG_EXTRACTING, + "Extraindo" + ) +MSG_HASH( + MSG_EXTRACTING_FILE, + "Extraindo arquivo" + ) +MSG_HASH( + MSG_FAILED_SAVING_CONFIG_TO, + "Falha em salvar a configuração em" + ) +MSG_HASH( + MSG_FAILED_TO, + "Falha em" + ) +MSG_HASH( + MSG_FAILED_TO_ACCEPT_INCOMING_SPECTATOR, + "Falha em aceitar o espectador ingresso." + ) +MSG_HASH( + MSG_FAILED_TO_ALLOCATE_MEMORY_FOR_PATCHED_CONTENT, + "Falha em alocar memória para o conteúdo modificado..." + ) +MSG_HASH( + MSG_FAILED_TO_APPLY_SHADER, + "Falha em aplicar o Shader." + ) +MSG_HASH( + MSG_FAILED_TO_BIND_SOCKET, + "Falha em vincular o soquete." + ) +MSG_HASH( + MSG_FAILED_TO_CREATE_THE_DIRECTORY, + "Falha em criar o diretório." + ) +MSG_HASH( + MSG_FAILED_TO_EXTRACT_CONTENT_FROM_COMPRESSED_FILE, + "Falha em extrair o conteúdo do arquivo comprimido" + ) +MSG_HASH( + MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT, + "Falha em obter o apelido do cliente." + ) +MSG_HASH( + MSG_FAILED_TO_LOAD, + "Falha em carregar" + ) +MSG_HASH( + MSG_FAILED_TO_LOAD_CONTENT, + "Falha em carregar o conteúdo" + ) +MSG_HASH( + MSG_FAILED_TO_LOAD_MOVIE_FILE, + "Falha em carregar o arquivo de filme" + ) +MSG_HASH( + MSG_FAILED_TO_LOAD_OVERLAY, + "Falha em carregar a Transparência." + ) +MSG_HASH( + MSG_FAILED_TO_LOAD_STATE, + "Falha em carregar o Estado de Jogo de" + ) +MSG_HASH( + MSG_FAILED_TO_OPEN_LIBRETRO_CORE, + "Falha em abrir o núcleo Libretro" + ) +MSG_HASH( + MSG_FAILED_TO_PATCH, + "Falha em executar a modificação" + ) +MSG_HASH( + MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT, + "Falha em receber o cabeçalho do cliente." + ) +MSG_HASH( + MSG_FAILED_TO_RECEIVE_NICKNAME, + "Falha em receber o apelido." + ) +MSG_HASH( + MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST, + "Falha em receber o apelido do hospedeiro." + ) +MSG_HASH( + MSG_FAILED_TO_RECEIVE_NICKNAME_SIZE_FROM_HOST, + "Falha em receber o tamanho do apelido do hospedeiro." + ) +MSG_HASH( + MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST, + "Falha em receber os dados SRAM do hospedeiro." + ) +MSG_HASH( + MSG_FAILED_TO_REMOVE_DISK_FROM_TRAY, + "Falha em remover o disco da bandeja." + ) +MSG_HASH( + MSG_FAILED_TO_REMOVE_TEMPORARY_FILE, + "Falha em remover o arquivo temporário" + ) +MSG_HASH( + MSG_FAILED_TO_SAVE_SRAM, + "Falha em salvar SRAM" + ) +MSG_HASH( + MSG_FAILED_TO_SAVE_STATE_TO, + "Falha em salvar o Estado de Jogo em" + ) +MSG_HASH( + MSG_FAILED_TO_SEND_NICKNAME, + "Falha em enviar o apelido." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_NICKNAME_SIZE, + "Falha em enviar o tamanho do apelido." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT, + "Falha em enviar o apelido para o cliente." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_NICKNAME_TO_HOST, + "Falha em enviar o apelido para o hospedeiro." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_SRAM_DATA_TO_CLIENT, + "Falha em enviar os dados SRAM para o cliente." + ) +MSG_HASH( + MSG_FAILED_TO_START_AUDIO_DRIVER, + "Falha em iniciar o driver de áudio. Prosseguindo sem áudio." + ) +MSG_HASH( + MSG_FAILED_TO_START_MOVIE_RECORD, + "Falha em iniciar a gravação do filme." + ) +MSG_HASH( + MSG_FAILED_TO_START_RECORDING, + "Falha em iniciar a gravação." + ) +MSG_HASH( + MSG_FAILED_TO_TAKE_SCREENSHOT, + "Falha em obter uma captura de tela." + ) +MSG_HASH( + MSG_FAILED_TO_UNDO_LOAD_STATE, + "Falha em desfazer o carregamento de Estado de Jogo." + ) +MSG_HASH( + MSG_FAILED_TO_UNDO_SAVE_STATE, + "Falha em desfazer o salvamento de Estado de Jogo." + ) +MSG_HASH( + MSG_FAILED_TO_UNMUTE_AUDIO, + "Falha em desativar o áudio mudo." + ) +MSG_HASH( + MSG_FATAL_ERROR_RECEIVED_IN, + "Erro fatal recebido em" + ) +MSG_HASH( + MSG_FILE_NOT_FOUND, + "Arquivo não encontrado" + ) +MSG_HASH( + MSG_FOUND_AUTO_SAVESTATE_IN, + "Estado de Jogo automático encontrado em" + ) +MSG_HASH( + MSG_FOUND_DISK_LABEL, + "Rótulo de disco encontrado" + ) +MSG_HASH( + MSG_FOUND_FIRST_DATA_TRACK_ON_FILE, + "Encontrada primeira faixa de dados no arquivo" + ) +MSG_HASH( + MSG_FOUND_LAST_STATE_SLOT, + "Encontrada último compartimento de Estado de Jogo" + ) +MSG_HASH( + MSG_FOUND_SHADER, + "Shader encontrado" + ) +MSG_HASH( + MSG_FRAMES, + "Quadros" + ) +MSG_HASH( + MSG_GAME_SPECIFIC_CORE_OPTIONS_FOUND_AT, + "Opções por Jogo: Opções de núcleo específicas do jogo encontradas em" + ) +MSG_HASH( + MSG_GOT_INVALID_DISK_INDEX, + "Índice de disco inválido obtido" + ) +MSG_HASH( + MSG_GRAB_MOUSE_STATE, + "Capturar estado do Mouse" + ) +MSG_HASH( + MSG_GAME_FOCUS_ON, + "Foco do jogo ligado" + ) +MSG_HASH( + MSG_GAME_FOCUS_OFF, + "Foco do jogo desligado" + ) +MSG_HASH( + MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING, + "O núcleo libretro é renderizado por hardware. Deve usar a gravação pós-Shader também." + ) +MSG_HASH( + MSG_INFLATED_CHECKSUM_DID_NOT_MATCH_CRC32, + "A soma de verificação inflada não corresponde ao CRC32." + ) +MSG_HASH( + MSG_INPUT_CHEAT, + "Entrada de Trapaça" + ) +MSG_HASH( + MSG_INPUT_CHEAT_FILENAME, + "Nome do Arquivo de Trapaça" + ) +MSG_HASH( + MSG_INPUT_PRESET_FILENAME, + "Nome de Arquivo de Predefinição" + ) +MSG_HASH( + MSG_INPUT_RENAME_ENTRY, + "Renomear Título" + ) +MSG_HASH( + MSG_INTERFACE, + "Interface" + ) +MSG_HASH( + MSG_INTERNAL_STORAGE, + "Armazenamento Interno" + ) +MSG_HASH( + MSG_REMOVABLE_STORAGE, + "Armazenamento Removível" + ) +MSG_HASH( + MSG_INVALID_NICKNAME_SIZE, + "Tamanho de apelido inválido." + ) +MSG_HASH( + MSG_IN_BYTES, + "em bytes" + ) +MSG_HASH( + MSG_IN_GIGABYTES, + "em gigabytes" + ) +MSG_HASH( + MSG_IN_MEGABYTES, + "em megabytes" + ) +MSG_HASH( + MSG_LIBRETRO_ABI_BREAK, + "foi compilado contra uma versão diferente do libretro do que esta." + ) +MSG_HASH( + MSG_LIBRETRO_FRONTEND, + "Frontend para Libretro" + ) +MSG_HASH( + MSG_LOADED_STATE_FROM_SLOT, + "Estado de Jogo carregado do compartimento #%d." + ) +MSG_HASH( + MSG_LOADED_STATE_FROM_SLOT_AUTO, + "Estado de Jogo carregado do compartimento #-1 (automático)." + ) +MSG_HASH( + MSG_LOADING, + "Carregando" + ) +MSG_HASH( + MSG_FIRMWARE, + "Um ou mais arquivos de firmware estão faltando" + ) +MSG_HASH( + MSG_LOADING_CONTENT_FILE, + "Carregando arquivo de conteúdo" + ) +MSG_HASH( + MSG_LOADING_HISTORY_FILE, + "Carregando arquivo de histórico" + ) +MSG_HASH( + MSG_LOADING_STATE, + "Carregando Estado de Jogo" + ) +MSG_HASH( + MSG_MEMORY, + "Memória" + ) +MSG_HASH( + MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE, + "O arquivo de filme não é um arquivo BSV1 válido." + ) +MSG_HASH( + MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION, + "O formato de filme parece ter uma versão de serializador diferente. Provavelmente irá falhar." + ) +MSG_HASH( + MSG_MOVIE_PLAYBACK_ENDED, + "Reprodução de filme terminou." + ) +MSG_HASH( + MSG_MOVIE_RECORD_STOPPED, + "Parando a gravação de filme." + ) +MSG_HASH( + MSG_NETPLAY_FAILED, + "Falha em inicializar o jogo em rede." + ) +MSG_HASH( + MSG_NO_CONTENT_STARTING_DUMMY_CORE, + "Sem conteúdo, iniciando um núcleo modelo." + ) +MSG_HASH( + MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET, + "Nenhum Estado de Jogo foi sobrescrito até o momento." + ) +MSG_HASH( + MSG_NO_STATE_HAS_BEEN_LOADED_YET, + "Nenhum Estado de Jogo foi carregado até o momento." + ) +MSG_HASH( + MSG_OVERRIDES_ERROR_SAVING, + "Erro em salvar as redefinições." + ) +MSG_HASH( + MSG_OVERRIDES_SAVED_SUCCESSFULLY, + "Redefinições salvas com sucesso." + ) +MSG_HASH( + MSG_PAUSED, + "Pausado." + ) +MSG_HASH( + MSG_PROGRAM, + "RetroArch" + ) +MSG_HASH( + MSG_READING_FIRST_DATA_TRACK, + "Lendo a primeira faixa de dados..." + ) +MSG_HASH( + MSG_RECEIVED, + "recebido" + ) +MSG_HASH( + MSG_RECORDING_TERMINATED_DUE_TO_RESIZE, + "A gravação terminou devido ao redimensionamento." + ) +MSG_HASH( + MSG_RECORDING_TO, + "Gravando em" + ) +MSG_HASH( + MSG_REDIRECTING_CHEATFILE_TO, + "Redirecionando o arquivo de Trapaça em" + ) +MSG_HASH( + MSG_REDIRECTING_SAVEFILE_TO, + "Redirecionando o Jogo-Salvo em" + ) +MSG_HASH( + MSG_REDIRECTING_SAVESTATE_TO, + "Redirecionando o Estado de Jogo em" + ) +MSG_HASH( + MSG_REMAP_FILE_SAVED_SUCCESSFULLY, + "Arquivo de remapeamento salvo com sucesso." + ) +MSG_HASH( + MSG_REMAP_FILE_REMOVED_SUCCESSFULLY, + "Arquivo de remapeamento salvo com sucesso." + ) +MSG_HASH( + MSG_REMOVED_DISK_FROM_TRAY, + "Disco removido da bandeja." + ) +MSG_HASH( + MSG_REMOVING_TEMPORARY_CONTENT_FILE, + "Removendo arquivo de conteúdo temporário" + ) +MSG_HASH( + MSG_RESET, + "Reinicializar" + ) +MSG_HASH( + MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT, + "Reiniciando a gravação devido ao reinício do driver." + ) +MSG_HASH( + MSG_RESTORED_OLD_SAVE_STATE, + "Estado de Jogo antigo restaurado." + ) +MSG_HASH( + MSG_RESTORING_DEFAULT_SHADER_PRESET_TO, + "Shaders: restaurando predefinição padrão de Shader em" + ) +MSG_HASH( + MSG_REVERTING_SAVEFILE_DIRECTORY_TO, + "Revertendo diretório de Jogo-Salvo em" + ) +MSG_HASH( + MSG_REVERTING_SAVESTATE_DIRECTORY_TO, + "Revertendo diretório de Estado de Jogo em" + ) +MSG_HASH( + MSG_REWINDING, + "Voltando atrás." + ) +MSG_HASH( + MSG_REWIND_INIT, + "Inicializando o buffer de Rebobinamento com tamanho" + ) +MSG_HASH( + MSG_REWIND_INIT_FAILED, + "Falha em inicializar o buffer de Rebobinamento. O rebobinamento será desativado." + ) +MSG_HASH( + MSG_REWIND_INIT_FAILED_THREADED_AUDIO, + "Esta implementação usa áudio paralelizado. Não é possível utilizar o rebobinamento." + ) +MSG_HASH( + MSG_REWIND_REACHED_END, + "Final do buffer de rebobinamento atingido." + ) +MSG_HASH( + MSG_SAVED_NEW_CONFIG_TO, + "Nova configuração salva em" + ) +MSG_HASH( + MSG_SAVED_STATE_TO_SLOT, + "Estado de Jogo salvo no compartimento #%d." + ) +MSG_HASH( + MSG_SAVED_STATE_TO_SLOT_AUTO, + "Estado de Jogo salvo no compartimento #-1 (automático)." + ) +MSG_HASH( + MSG_SAVED_SUCCESSFULLY_TO, + "Salvo com sucesso em" + ) +MSG_HASH( + MSG_SAVING_RAM_TYPE, + "Salvando Tipo de RAM" + ) +MSG_HASH( + MSG_SAVING_STATE, + "Salvando Estado de Jogo" + ) +MSG_HASH( + MSG_SCANNING, + "Analisando" + ) +MSG_HASH( + MSG_SCANNING_OF_DIRECTORY_FINISHED, + "Análise de diretório terminada" + ) +MSG_HASH( + MSG_SENDING_COMMAND, + "Enviando comando" + ) +MSG_HASH( + MSG_SEVERAL_PATCHES_ARE_EXPLICITLY_DEFINED, + "Várias modificações de conteúdo estão explicitamente definidas, ignorando todas..." + ) +MSG_HASH( + MSG_SHADER, + "Shader" + ) +MSG_HASH( + MSG_SHADER_PRESET_SAVED_SUCCESSFULLY, + "Predefinição de Shader salva com sucesso." + ) +MSG_HASH( + MSG_SKIPPING_SRAM_LOAD, + "Ignorando carregamento da SRAM." + ) +MSG_HASH( + MSG_SLOW_MOTION, + "Câmera Lenta." + ) +MSG_HASH( + MSG_FAST_FORWARD, + "Avanço rápido." + ) +MSG_HASH( + MSG_SLOW_MOTION_REWIND, + "Rebobinamento em Câmera Lenta." + ) +MSG_HASH( + MSG_SRAM_WILL_NOT_BE_SAVED, + "SRAM não será salva." + ) +MSG_HASH( + MSG_STARTING_MOVIE_PLAYBACK, + "Iniciando reprodução de filme." + ) +MSG_HASH( + MSG_STARTING_MOVIE_RECORD_TO, + "Iniciando a gravação de filme em" + ) +MSG_HASH( + MSG_STATE_SIZE, + "Tamanho do Estado de Jogo" + ) +MSG_HASH( + MSG_STATE_SLOT, + "Compartimento do Estado de Jogo" + ) +MSG_HASH( + MSG_TAKING_SCREENSHOT, + "Fazendo captura de tela" + ) +MSG_HASH( + MSG_TO, + "em" + ) +MSG_HASH( + MSG_UNDID_LOAD_STATE, + "Desfez o carregamento de Estado de Jogo." + ) +MSG_HASH( + MSG_UNDOING_SAVE_STATE, + "Desfazendo o salvamento de Estado de Jogo" + ) +MSG_HASH( + MSG_UNKNOWN, + "Desconhecido" + ) +MSG_HASH( + MSG_UNPAUSED, + "Retomando." + ) +MSG_HASH( + MSG_UNRECOGNIZED_COMMAND, + "Comando não reconhecido" + ) +MSG_HASH( + MSG_USING_CORE_NAME_FOR_NEW_CONFIG, + "Usando o nome do núcleo para uma nova configuração." + ) +MSG_HASH( + MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED, + "Usando o núcleo libretro modelo. Pulando a gravação." + ) +MSG_HASH( + MSG_VALUE_CONNECT_DEVICE_FROM_A_VALID_PORT, + "Conecte o dispositivo a partir de uma porta válida." + ) +MSG_HASH( + MSG_VALUE_DISCONNECTING_DEVICE_FROM_PORT, + "Desconectando o dispositivo da porta" + ) +MSG_HASH( + MSG_VALUE_REBOOTING, + "Reinicializando..." + ) +MSG_HASH( + MSG_VALUE_SHUTTING_DOWN, + "Desligando..." + ) +MSG_HASH( + MSG_VERSION_OF_LIBRETRO_API, + "Versão da API libretro" + ) +MSG_HASH( + MSG_VIEWPORT_SIZE_CALCULATION_FAILED, + "Falha no cálculo de tamanho da janela de exibição! Prosseguindo usando dados brutos. Isto provavelmente não funcionará corretamente..." + ) +MSG_HASH( + MSG_VIRTUAL_DISK_TRAY, + "bandeja de disco virtual." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_LATENCY, + "Latência de áudio desejada em milissegundos. Pode não ser honrado se o driver de áudio não puder prover a latência desejada." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_MUTE, + "Silencia o áudio." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, + "Ajuda a suavizar as imperfeições na regulagem ao sincronizar áudio e vídeo. Esteja ciente que se desativado, será quase impossível de se obter a sincronia adequada." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CAMERA_ALLOW, + "Permitir ou não o acesso à câmera pelos núcleos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOCATION_ALLOW, + "Permitir ou não o acesso ao serviço de localização pelos núcleos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_MAX_USERS, + "Número máximo de usuários suportados pelo RetroArch." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_POLL_TYPE_BEHAVIOR, + "Influencia como a chamada seletiva de entrada é feita dentro do RetroArch. Definindo com 'Cedo' ou 'Tarde' pode resultar em menos latência, dependendo da sua configuração." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_ALL_USERS_CONTROL_MENU, + "Permite a qualquer usuário controlar o menu. Se desabilitado, apenas o Usuário 1 poderá controlar o menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_VOLUME, + "Volume do áudio (em dB). 0dB é o volume normal, e nenhum ganho é aplicado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_WASAPI_EXCLUSIVE_MODE, + "Permitir ao driver WASAPI obter controle exclusivo do dispositivo de áudio. Se desativado, o modo compartilhado será utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_WASAPI_FLOAT_FORMAT, + "Utilizar formato de ponto flutuante para o driver WASAPI, se suportado pelo dispositivo de áudio." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_WASAPI_SH_BUFFER_LENGTH, + "O tamanho (em quadros) do buffer intermediário quando o driver WASAPI estiver em modo compartilhado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_SYNC, + "Sincroniza o áudio. Recomendado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, + "Até que ponto um eixo deve ser movido para resultar em um botão pressionado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, + "Quantidade de segundos para aguardar até proceder para o próximo vínculo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_BIND_HOLD, + "Quantidade de segundos para manter uma entrada para vinculá-la." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_TURBO_PERIOD, + "Descreve o período quando os botões com turbo habilitado são alternados. Os números são descritos em quadros." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_DUTY_CYCLE, + "Descreve quão longo deve ser o período de um botão com turbo habilitado. Os números são descritos como quadros." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_VSYNC, + "Sincroniza o vídeo de saída da placa gráfica com a taxa de atualização da tela. Recomendado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_ALLOW_ROTATE, + "Permite que os núcleos definam a rotação. Quando desabilitado, as requisições de rotação são ignoradas. Útil para configurações onde se rotaciona manualmente a tela." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DUMMY_ON_CORE_SHUTDOWN, + "Alguns núcleos podem ter um recurso de desligamento. Se habilitado, impedirá que o núcleo feche o RetroArch. Em vez disto, carrega um núcleo modelo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHECK_FOR_MISSING_FIRMWARE, + "Verifica se todos os firmwares necessários estão presentes antes de tentar carregar conteúdo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE, + "Taxa de atualização vertical da sua tela. Utilizado para calcular uma taxa de saída de áudio adequada. OBS: Isto será ignorado se a função 'Vídeo Paralelizado' estiver habilitada." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_ENABLE, + "Habilita a saída de áudio." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_MAX_TIMING_SKEW, + "Mudança máxima na taxa de entrada de áudio. Se aumentado habilita grandes mudanças na regulagem ao custo de imprecisão no timbre do som (ex: rodando núcleos PAL em modo NTSC)." + ) +MSG_HASH( + MSG_FAILED, + "falhou" + ) +MSG_HASH( + MSG_SUCCEEDED, + "teve êxito" + ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED, + "não configurado" + ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED_FALLBACK, + "não configurado, usando reserva" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, + "Lista de Cursores da Base de Dados" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DEVELOPER, + "Base de Dados - Filtro : Desenvolvedor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PUBLISHER, + "Base de Dados - Filtro : Publicador" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISABLED, + "Desabilitado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ENABLED, + "Habilitado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_PATH, + "Caminho do Histórico de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ORIGIN, + "Base de Dados - Filtro : Origem" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_FRANCHISE, + "Base de Dados - Filtro : Franquia" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ESRB_RATING, + "Base de Dados - Filtro : Classificação ESRB" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ELSPA_RATING, + "Base de Dados - Filtro : Classificação ELSPA" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PEGI_RATING, + "Base de Dados - Filtro : Classificação PEGI" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_CERO_RATING, + "Base de Dados - Filtro : Classificação CERO" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_BBFC_RATING, + "Base de Dados - Filtro : Classificação BBFC" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_MAX_USERS, + "Base de Dados - Filtro : Usuários máximos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_MONTH, + "Base de Dados - Filtro : Data de Lançamento Por Mês" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_YEAR, + "Base de Dados - Filtro : Data de Lançamento Por Ano" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_ISSUE, + "Base de Dados - Filtro : Edição da Revista Edge" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_RATING, + "Base de Dados - Filtro : Classificação da Revista Edge" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DATABASE_INFO, + "Informações da Base de Dados" + ) +MSG_HASH( + MSG_WIFI_SCAN_COMPLETE, + "Análise de Wi-Fi completa." + ) +MSG_HASH( + MSG_SCANNING_WIRELESS_NETWORKS, + "Analisando redes sem fio..." + ) +MSG_HASH( + MSG_NETPLAY_LAN_SCAN_COMPLETE, + "Análise de jogo em rede completa." + ) +MSG_HASH( + MSG_NETPLAY_LAN_SCANNING, + "Analisando por hospedeiros de jogo em rede..." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, + "Pausa o jogo quando a janela do RetroArch não está ativa." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, + "Ativa ou desativa a composição (Somente no Windows)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, + "Habilitar ou desabilitar a lista de reprodução recente para jogos, imagens, música e vídeos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, + "Limita o número de itens da lista de reprodução recente para jogos, imagens, música e vídeos." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_UNIFIED_MENU_CONTROLS, + "Controles de Menu Unificados" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS, + "Utiliza os mesmos controles para o menu e jogo. Aplica-se ao teclado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE, + "Exibe as mensagens na tela." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_USER_REMOTE_ENABLE, + "Habilitar Remoto do Usuário %d" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, + "Exibir nível de bateria" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SELECT_FILE, + "Selecionar Arquivo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, + "Selecionar de Coleção" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FILTER, + "Filtro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCALE, + "Escala" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED, + "O jogo em rede irá iniciar quando o conteúdo for carregado." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_LOAD_CONTENT_MANUALLY, + "Não foi possível encontrar um núcleo adequado ou arquivo de conteúdo, carregue manualmente." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BROWSE_URL_LIST, + "Navegar pela URL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BROWSE_URL, + "Caminho da URL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BROWSE_START, + "Iniciar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, + "Bokeh" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOWFLAKE, + "Floco de neve" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_ROOMS, + "Atualizar Lista de Salas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME, + "Apelido: %s" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME_LAN, + "Apelido (lan): %s" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND, + "Conteúdo compatível encontrado" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_CROP_OVERSCAN, + "Corta alguns pixels ao redor das bordas da imagem habitualmente deixada em branco por desenvolvedores, que por vezes também contêm pixels de lixo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SMOOTH, + "Adiciona um leve embaciado à imagem para suavizar as arestas da borda dos pixels. Esta opção tem pouco impacto no desempenho." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FILTER, + "Aplica um filtro de vídeo processado pela CPU. OBS: Pode vir a um alto custo de desempenho. Alguns filtros de vídeo podem funcionar apenas para núcleos que usam cores de 32 bits ou 16 bits." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_USERNAME, + "Insira o nome de usuário de sua conta Retro Achievements." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_PASSWORD, + "Insira a senha de sua conta Retro Achievements." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_NICKNAME, + "Insira seu nome de usuário aqui. Isto será utilizado para sessões do jogo em rede, entre outras coisas." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_POST_FILTER_RECORD, + "Captura a imagem depois que os filtros (mas não os Shaders) forem aplicados. Seu vídeo ficará tão bonito quanto o que você vê na tela." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_LIST, + "Selecione qual núcleo utilizar." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOAD_CONTENT_LIST, + "Selecione qual conteúdo iniciar." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETWORK_INFORMATION, + "Exibe as interfaces de rede e endereços de IP associados." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SYSTEM_INFORMATION, + "Exibe informações específicas do dispositivo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUIT_RETROARCH, + "Sai do programa." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_WINDOW_WIDTH, + "Define a largura personalizada para a janela de exibição. Deixado em 0 a janela irá dimensionar o mais largo possível." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_WINDOW_HEIGHT, + "Define a altura personalizada para a janela de exibição. Deixado em 0 a janela irá dimensionar o mais alto possível." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_X, + "Define a largura personalizada para o modo de tela cheia em não-janela. Deixar em 0 irá usar a resolução da área de trabalho." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_Y, + "Define a altura personalizada para o modo de tela cheia em não-janela. Deixar em 0 irá usar a resolução da área de trabalho." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_X, + "Especifique a posição personalizada no eixo X para o texto na tela." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_Y, + "Especifique a posição personalizada no eixo Y para o texto na tela." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, + "Especifique o tamanho da fonte em pontos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, + "Oculta a Transparência enquanto estiver dentro do menu e exibe novamente ao sair." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, + "Exibe comandos de teclado/controle na transparência." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, + "Selecione a porta para a transparência escutar se Exibir Comandos na Transparência estiver habilitado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + "O conteúdo analisado aparecerá aqui." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, + "Apenas dimensiona o vídeo em valores inteiros. O tamanho de base depende da geometria relatada pelo sistema e da proporção de tela. Se 'Forçar Proporção' não estiver definido, X / Y serão dimensionados independentemente em valores inteiros." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT, + "Captura a tela com Shader de GPU se disponível." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_ROTATION, + "Força uma certa rotação da tela. A rotação é adicionada a rotação que o núcleo definir." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FORCE_SRGB_DISABLE, + "Desabilita de forma forçada o suporte sRGB FBO. Alguns drivers Intel OpenGL no Windows possuem problemas de vídeo com o suporte sRGB FBO se estiver habilitado. Habilitando isto pode contornar o problema." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN, + "Inicia em tela cheia. Pode ser mudado a qualquer momento." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_WINDOWED_FULLSCREEN, + "Se estiver em tela cheia, prefira utilizar uma janela de tela cheia." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_GPU_RECORD, + "Grava o material de saída do Shader de GPU se disponível." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX, + "Ao criar um Estado de Jogo, o índice do Estado de Jogo é aumentado automaticamente antes de ser salvo. Ao carregar um conteúdo, o índice será definido para o índice mais alto existente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE, + "Bloqueia a SRAM de ser sobrescrita ao carregar um Estado de Jogo. Pode causar problemas no jogo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO, + "Taxa máxima em que o conteúdo será executado quando utilizado o Avanço Rápido (ex: 5.0x para conteúdos em 60fps = 300 fps máx). Se for definido como 0.0x, a taxa de Avanço Rápido é ilimitada (sem FPS máx)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, + "Quando está em Câmera Lenta, o conteúdo será diminuído pelo fator especificado/definido." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RUN_AHEAD_ENABLED, + "Executa o núcleo lógico um ou mais quadros à frente e carrega o estado de volta para reduzir o atraso dos controles percebido." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RUN_AHEAD_FRAMES, + "O número de quadros para avançar. Causa problemas de jogabilidade, como instabilidade, se você exceder o número de quadros de atraso internos do jogo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RUN_AHEAD_SECONDARY_INSTANCE, + "Usa uma segunda instância do núcleo do RetroArch para avançar quadros. Evita problemas de áudio devido ao estado de carregamento." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RUN_AHEAD_HIDE_WARNINGS, + "Oculta a mensagem de aviso que aparece ao usar o Adiantar Quadro e o núcleo não suporta Estados de Jogo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_REWIND_ENABLE, + "Habilita a rebobinamento. Isso irá impactar o desempenho ao jogar." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_APPLY_AFTER_TOGGLE, + "Aplicar a trapaça imediatamente após alternância." +) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_APPLY_AFTER_LOAD, + "Aplicar trapaças automaticamente quando o jogo for carregado." +) +MSG_HASH( + MENU_ENUM_SUBLABEL_REWIND_GRANULARITY, + "Ao definir um número de quadros para o rebobinamento, você pode retroceder vários quadros de uma só vez, aumentando a velocidade da função." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE, + "A quantidade de memória (em MB) para reservar ao buffer de rebobinamento . Aumentar esse valor aumentará a quantidade de histórico do rebobinamento." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE_STEP, + "Sempre que você aumentar ou diminuir o valor do tamanho do buffer do rebobinamento por meio dessa interface, ele será alterado por esse valor" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_IDX, + "Posição do índice na lista." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_ADDRESS_BIT_POSITION, + "Bitmask o endereço quando o tamanho da busca da memória for < 8-bit." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_MATCH_IDX, + "Selecionar a coincidência para visualizar." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_START_OR_CONT, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_START_OR_RESTART, + "Esquerda/Direita para alterar o tamanho do bit" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EXACT, + "Esquerda/Direita para alterar o valor" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LT, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GT, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LTE, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GTE, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQ, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_NEQ, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQPLUS, + "Esquerda/Direita para alterar o valor" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQMINUS, + "Esquerda/Direita para alterar o valor" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_ADD_MATCHES, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_VIEW_MATCHES, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_CREATE_OPTION, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_DELETE_OPTION, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_TOP, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_BOTTOM, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_DELETE_ALL, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_RELOAD_CHEATS, + "" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_BIG_ENDIAN, + "Big endian : 258 = 0x0102,\nLittle endian : 258 = 0x0201" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL, + "Define o nível de registro de eventos para os núcleos. Se o nível do registro enviado por um núcleo for abaixo deste valor, o mesmo é ignorado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PERFCNT_ENABLE, + "Habilitar os contadores de desempenho para o RetroArch (e núcleos)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_SAVE, + "Cria automaticamente um Estado de Jogo no final da execução do RetroArch. O RetroArch irá carregar automaticamente este Estado de Jogo se a função 'Autocarregar Estado de Jogo' estiver habilitada." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_LOAD, + "Carrega automaticamente o último Estado de Jogo auto salvo na inicialização do RetroArch." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVESTATE_THUMBNAIL_ENABLE, + "Mostrar miniaturas de estados salvos dentro do menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL, + "Salva automaticamente o Save RAM não-volátil em um intervalo regular. Isso está desabilitado por padrão, a menos que seja definido de outra forma. O intervalo é medido em segundos. Um valor de 0 desativa o salvamento automático." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE, + "Se ativado, substitui os vínculos de entrada com as associações remapeadas definidas para o núcleo atual." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_AUTODETECT_ENABLE, + "Habilita a detecção automática de entrada. Tentará configurar automaticamente joypads, estilo Plug-and-Play." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_INPUT_SWAP_OK_CANCEL, + "Troca de botões para OK/Cancelar. Desabilitado é o estilo de botão japonês, habilitada é oestilo ocidental." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PAUSE_LIBRETRO, + "Se desabilitado, o conteúdo continuará sendo executado em segundo plano quando o menu do RetroArch for alternado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_DRIVER, + "Driver de vídeo a ser utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_DRIVER, + "Driver de áudio a ser utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_DRIVER, + "Driver de entrada a ser utilizado. Dependendo do driver de vídeo, pode forçar um driver de entrada diferente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_JOYPAD_DRIVER, + "Driver do Joypad a ser utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_DRIVER, + "Driver de reamostragem de áudio a ser utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CAMERA_DRIVER, + "Driver de câmera a ser utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOCATION_DRIVER, + "Driver de localização a ser utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_DRIVER, + "Driver de menu a ser utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RECORD_DRIVER, + "Driver de gravação a ser utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIDI_DRIVER, + "Driver MIDI a ser utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_WIFI_DRIVER, + "Driver de WiFi a ser utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, + "Filtra os arquivos em exibição no explorador de arquivos por extensões suportadas." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_WALLPAPER, + "Selecione uma imagem para definir como plano de fundo do menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPER, + "Carrega dinamicamente um novo plano de fundo dependendo do contexto." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_DEVICE, + "Substitui o dispositivo de áudio padrão utilizado pelo driver de áudio. Isto depende do driver." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_DSP_PLUGIN, + "Plugin DSP de Áudio que processa o áudio antes de ser enviado para o driver." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_OUTPUT_RATE, + "Taxa de amostragem da saída de áudio." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_OVERLAY_OPACITY, + "Opacidade de todos os elementos de interface da Transparência." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_OVERLAY_SCALE, + "Escala de todos os elementos de interface da Transparência." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_ENABLE, + "Habilita a Transparência." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_OVERLAY_PRESET, + "Selecione uma Transparência pelo navegador de arquivos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_IP_ADDRESS, + "Endereço do hospedeiro a se conectar." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_TCP_UDP_PORT, + "Porta do endereço de IP do hospedeiro. Pode ser uma porta TCP ou uma porta UDP." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_PASSWORD, + "Senha para conectar ao hospedeiro de jogo em rede. Utilizado apenas no modo hospedeiro." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_PUBLIC_ANNOUNCE, + "Anuncia os jogos em rede publicamente. Se não for definido, os clientes deverão conectar manualmente em vez de usar o lobby público." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_SPECTATE_PASSWORD, + "Senha para conectar ao hospedeiro de jogo em rede apenas com privilégios de espectador. Utilizado apenas no modo hospedeiro." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_START_AS_SPECTATOR, + "Define se o jogo em rede deve iniciar em modo espectador." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_ALLOW_SLAVES, + "Define se conexões em modo escravo são permitidas. Clientes em modo escravo requerem muito pouco poder de processamento em ambos os lados, mas irão sofrer significamente da latência de rede." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_REQUIRE_SLAVES, + "Define se conexões que não estão em modo escravo são proibidas. Não recomendado, exceto para redes muito rápidas com máquinas muito lentas." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_STATELESS_MODE, + "Define se deve executar o jogo em rede em modo que não utilize Estados de Jogo. Se definido como verdadeiro, uma rede muito rápida é necessária, mas nenhum rebobinamento é realizado, portanto, não haverá instabilidade no jogo em rede." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_CHECK_FRAMES, + "Frequência em quadros no qual o jogo em rede verificará se o hospedeiro e o cliente estão sincronizados." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_NAT_TRAVERSAL, + "Ao hospedar uma partida, tente receber conexões da Internet pública usando UPnP ou tecnologias similares para escapar das redes locais." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_STDIN_CMD_ENABLE, + "Habilita a interface de comando stdin." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MOUSE_ENABLE, + "Habilita o controle por Mouse dentro do menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_POINTER_ENABLE, + "Habilita o controle por toque dentro do menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_THUMBNAILS, + "Tipo de miniatura a ser exibida." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS, + "Tipo de miniatura para exibir à esquerda." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_VERTICAL_THUMBNAILS, + "Exibe a miniatura esquerda sob a direita, no lado direito da tela." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_TIMEDATE_ENABLE, + "Exibe data e/ou hora atuais dentro do menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_BATTERY_LEVEL_ENABLE, + "Exibe o nível de bateria atual dentro do menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NAVIGATION_WRAPAROUND, + "Volta ao início ou final se o limite da lista for alcançado horizontalmente ou verticalmente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_HOST, + "Habilita o jogo em rede no modo hospedeiro (servidor)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, + "Habilita o jogo em rede no modo cliente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, + "Desconecta de uma conexão de jogo em rede ativa." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, + "Analisa um diretório por arquivos compatíveis e os adiciona à coleção." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SCAN_FILE, + "Analisa um arquivo compatível e o adiciona à coleção." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, + "Usa um intervalo de troca personalizado para V-Sync. Defina para reduzir efetivamente a taxa de atualização do monitor pela metade." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE, + "Ordena os Jogos-Salvos em pastas com o nome do núcleo utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE, + "Ordena os Estados de Jogo em pastas com o nome do núcleo utilizado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_REQUEST_DEVICE_I, + "Solicita jogar com o dispositivo de entrada dado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL, + "URL para o diretório de atualização de núcleos no buildbot do Libreto." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL, + "URL para o diretório de atualizações de recursos no buildbot do Libretro." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, + "Após o download, extrair automaticamente os arquivos contidos nos arquivos comprimidos baixados." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, + "Analisa novas salas." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DELETE_ENTRY, + "Remove esta entrada da coleção." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INFORMATION, + "Visualiza mais informações sobre o conteúdo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, + "Adiciona o item aos seus favoritos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES_PLAYLIST, + "Adiciona o item aos seus favoritos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RUN, + "Inicia o conteúdo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_FILE_BROWSER_SETTINGS, + "Ajusta as definições do navegador de arquivos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUTO_REMAPS_ENABLE, + "Habilita por padrão controles personalizados na inicialização." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUTO_OVERRIDES_ENABLE, + "Habilita por padrão configuração personalizada na inicialização." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_GAME_SPECIFIC_OPTIONS, + "Habilita por padrão opções de núcleo personalizadas na inicialização." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_ENABLE, + "Exibe o nome do núcleo atual dentro do menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DATABASE_MANAGER, + "Visualiza as bases de dados." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CURSOR_MANAGER, + "Visualiza as pesquisas anteriores." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_TAKE_SCREENSHOT, + "Captura uma imagem da tela." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CLOSE_CONTENT, + "Fecha o conteúdo atual. Alterações não salvas serão perdidas." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOAD_STATE, + "Carrega um Estado de Jogo do compartimento selecionado atualmente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVE_STATE, + "Salva um Estado de Jogo no compartimento selecionado atualmente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RESUME, + "Continua a execução do conteúdo atual e sai do Menu Rápido." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RESUME_CONTENT, + "Continua a execução do conteúdo atual e sai do Menu Rápido." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_STATE_SLOT, + "Altera o compartimento do Estado de Jogo selecionado atualmente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_UNDO_LOAD_STATE, + "Se um Estado de Jogo for carregado, o conteúdo voltará ao estado anterior ao carregamento." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_UNDO_SAVE_STATE, + "Se o Estado de Jogo foi sobrescrito, ele voltará ao Estado de Jogo salvo anteriormente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, + "Serviço Retro Achievements. Para mais informações, visite http://retroachievements.org (em inglês)" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ACCOUNTS_LIST, + "Gerencia as contas configuradas atualmente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_REWIND, + "Gerencia as configurações do rebobinamento." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_DETAILS, + "Gerencia as configurações dos detalhes da trapaça." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_SEARCH, + "Inicia ou continua uma pesquisa de código de trapaça." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RESTART_CONTENT, + "Reinicia o conteúdo do começo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, + "Salva um arquivo de redefinição de configuração que será aplicado a todo o conteúdo carregado por este núcleo. Terá prioridade sobre a configuração principal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, + "Salva um arquivo de redefinição de configuração que será aplicado a todo o conteúdo carregado no mesmo diretório que o arquivo atual. Terá prioridade sobre a configuração principal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, + "Salva um arquivo de redefinição de configuração que será aplicado apenas ao conteúdo atual. Terá prioridade sobre a configuração principal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_CHEAT_OPTIONS, + "Configura os códigos de Trapaça." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHADER_OPTIONS, + "Configura o Shader para realçar a aparência da imagem." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_INPUT_REMAPPING_OPTIONS, + "Altera os controles para o conteúdo que está sendo executado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_OPTIONS, + "Altera as opções para o conteúdo que está sendo executado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, + "Exibe as configurações avançadas para usuários experientes (oculto por padrão)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, + "Executar tarefas em linhas de processamento paralelas." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, + "Permite que o usuário possa remover itens das coleções." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, + "Define o diretório de sistema. Os núcleos podem consultar este diretório para carregar arquivos de BIOS, configurações específicas do sistema, etc." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, + "Define o diretório inicial do navegador de arquivos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_DIR, + "Usualmente definido por desenvolvedores que agrupam aplicativos Libretro/RetroArch para apontar para os recursos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPERS_DIRECTORY, + "Diretório para armazenar planos de fundo dinamicamente carregados pelo menu dependendo do contexto." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_THUMBNAILS_DIRECTORY, + "Miniaturas auxiliares (arte da embalagem/imagens diversas e etc.) são armazenadas aqui." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RGUI_CONFIG_DIRECTORY, + "Define o diretório inicial para o navegador de configurações do menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, + "O número de quadros de latência de entrada para o jogo em rede utilizar para mascarar a latência da rede. Reduz a oscilação e torna o jogo em rede menos intensivo para a CPU, ao custo de atraso perceptível na entrada." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, + "O intervalo de quadros de latência de entrada que pode ser utilizado para mascarar a latência da rede. Reduz a oscilação e torna o jogo em rede menos intensivo para a CPU, ao custo de atraso imprevisível na entrada." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DISK_CYCLE_TRAY_STATUS, + "Alterna o disco atual. Se o disco estiver inserido, o mesmo será ejetado. Se o disco não estiver inserido, o mesmo será inserido." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DISK_INDEX, + "Mude o índice do disco." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DISK_OPTIONS, + "Gerenciamento de imagem de disco." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, + "Selecione uma imagem de disco para inserir." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, + "Certifica-se de que a taxa de quadros é controlada enquanto estiver dentro do menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VRR_RUNLOOP_ENABLE, + "Não desvia dos tempos solicitados pelo núcleo. Use com telas de Taxa de Atualização Variável, G-Sync, FreeSync." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_LAYOUT, + "Selecione um layout diferente para a interface XMB." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_THEME, + "Selecione um tema diferente para os ícones. As alterações terão efeito após reiniciar o programa." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, + "Habilite as sombras para todos os ícones. Isto terá um pequeno impacto no desempenho." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MATERIALUI_MENU_COLOR_THEME, + "Selecione um tema de gradiente de cor de plano de fundo diferente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_WALLPAPER_OPACITY, + "Modifica a opacidade do plano de fundo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_MENU_COLOR_THEME, + "Selecione um tema de gradiente de cor de plano de fundo diferente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_RIBBON_ENABLE, + "Selecione um efeito de plano de fundo animado. Pode exigir mais processamento da GPU dependendo do efeito. Se o desempenho for insatisfatório, desligue este efeito ou reverta para um efeito mais simples." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_FONT, + "Selecione uma fonte principal diferente para ser usada pelo menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_FAVORITES, + "Exibe a aba de favoritos dentro do menu principal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_IMAGES, + "Exibe a aba de imagem dentro do menu principal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_MUSIC, + "Exibe a aba de música dentro do menu principal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_VIDEO, + "Exibe a aba de vídeo dentro do menu principal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_NETPLAY, + "Exibe a aba de jogo em rede dentro do menu principal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS, + "Exibe a aba de configurações dentro do menu principal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_HISTORY, + "Exibe a aba de histórico recente dentro do menu principal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_ADD, + "Exibe a aba de importação de conteúdo dentro do menu principal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_PLAYLISTS, + "Exibe abas da lista de reprodução dentro do menu principal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN, + "Exibe a tela inicial no menu. É automaticamente definido como falso após o programa iniciar pela primeira vez." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY, + "Modifica a opacidade do gráfico do cabeçalho." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MATERIALUI_MENU_FOOTER_OPACITY, + "Modifica a opacidade do gráfico do rodapé." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DPI_OVERRIDE_ENABLE, + "O menu normalmente se dimensiona dinamicamente. Se você desejar definir uma escala de tamanho específica em vez disto, habilite esta função." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DPI_OVERRIDE_VALUE, + "Define o tamanho do dimensionamento personalizado aqui. OBS: Você deve habilitar a função 'Redefinição de DPI' para que este dimensionamento tenha efeito." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_ASSETS_DIRECTORY, + "Salva todos os arquivos baixados neste diretório." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_REMAPPING_DIRECTORY, + "Salva todos os controles remapeados neste diretório." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LIBRETRO_DIR_PATH, + "Diretório onde o programa busca por conteúdo/núcleos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, + "Os arquivos de informação do aplicativo/núcleo são armazenados aqui." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, + "Se um Joypad estiver conectado, o mesmo será autoconfigurado se um arquivo de configuração correspondente estiver presente dento deste diretório." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, + "Salva todas as coleções neste diretório." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, + "Se for definido um diretório, o conteúdo que é temporariamente extraído (ex: dos arquivos) sera extraído para este diretório." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CURSOR_DIRECTORY, + "As consultas salvas são armazenadas neste diretório." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_DATABASE_DIRECTORY, + "As bases de dados são armazenadas neste diretório." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ASSETS_DIRECTORY, + "Esta localização é consultada por padrão quando a interface do menu tenta procurar por recursos carregáveis, etc." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVEFILE_DIRECTORY, + "Salva todos os Jogos-Salvos neste diretório. Se não for definido, tentaremos salvar dentro do diretório de trabalho do arquivo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVESTATE_DIRECTORY, + "Salva todos os Estados de Jogo neste diretório. Se não for definido, tentaremos salvar dentro do diretório de trabalho do arquivo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SCREENSHOT_DIRECTORY, + "Diretório para armazenar as capturas de tela." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_OVERLAY_DIRECTORY, + "Define um diretório onde as Transparências são mantidas para fácil acesso." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_DATABASE_PATH, + "Os arquivos de Trapaça são mantidos aqui." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_FILTER_DIR, + "Diretório onde os arquivos de filtro DSP de áudio são mantidos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FILTER_DIR, + "Diretório onde os arquivos de filtro de vídeo processado por CPU são mantidos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_DIR, + "Define um diretório onde os arquivos de Shader de vídeo processado por GPU são mantidos para fácil acesso." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RECORDING_OUTPUT_DIRECTORY, + "As gravações serão armazenadas neste diretório." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RECORDING_CONFIG_DIRECTORY, + "As configurações de gravação serão mantidas aqui." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FONT_PATH, + "Selecione uma fonte diferente para as notificações na tela." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHADER_APPLY_CHANGES, + "As alterações das configurações de Shader terão efeito imediato. Use isto se você alterou a quantidade de estágios de Shader, filtros, escala FBO, etc." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_NUM_PASSES, + "Aumentar ou diminuir a quantidade de estágios do pipeline de Shader. Você pode adicionar um Shader separado para cada estágio do pipeline e configurar sua escala e filtro." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET, + "Carregar uma predefinição de Shader. O pipeline de Shader será definido automaticamente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_AS, + "Salvar as definições de Shader atuais como uma nova predefinição de Shader." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_CORE, + "Salvar as definições de Shader atuais como a definição padrão para esta aplicação/núcleo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_PARENT, + "Salve as configurações atuais do shader como as configurações padrão para todos os arquivos no diretório de conteúdo atual." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_GAME, + "Salvar as definições de Shader atuais como a definição padrão para o conteúdo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PARAMETERS, + "Modifica diretamente o Shader atual. As alterações não serão salvas no arquivo de predefinição." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_PARAMETERS, + "Modifica a predefinição de Shader atualmente utilizada no menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_NUM_PASSES, + "Aumentar ou diminuir a quantidade de Trapaças." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_APPLY_CHANGES, + "As alterações de Trapaça terão efeito imediato." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_START_SEARCH, + "Iniciar a procura por uma nova trapaça. O número de bits pode ser alterado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_CONTINUE_SEARCH, + "Continuar procurando por uma nova trapaça." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD, + "Carregar um arquivo de Trapaça." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD_APPEND, + "Carreguar um arquivo de trapaça e anexar às trapaças existentes." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_FILE_SAVE_AS, + "Salvar as Trapaças atuais como um arquivo de Jogo-Salvo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SETTINGS, + "Acesse rapidamente todas as configurações relevantes ao jogo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_INFORMATION, + "Visualiza as informações sobre a aplicação/núcleo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_ASPECT_RATIO, + "Valor em ponto flutuante da proporção de tela (largura / altura), utilizado se Proporção de Tela estiver definido como 'Configuração'." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT, + "Personaliza a altura da janela de exibição que é usada se a Proporção de Tela estiver definida como 'Personalizada'." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH, + "Personaliza a largura da janela de exibição que é usada se a Proporção de Tela estiver definida como 'Personalizada'." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_X, + "Deslocamento personalizado no eixo-X da janela de exibição. Será ignorado se a 'Escala em Inteiros' estiver habilitada. Neste caso ela será centralizada automaticamente." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_Y, + "Deslocamento personalizado no eixo-Y da janela de exibição. Será ignorado se a 'Escala em Inteiros' estiver habilitada. Neste caso ela será centralizada automaticamente." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_USE_MITM_SERVER, + "Utilizar Servidor MITM" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, + "Encaminha conexões de jogo em rede através de um servidor 'homem no meio' (MITM). Útil se o hospedeiro estiver atrás de um firewall ou tiver problemas de NAT/UPnP." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_MITM_SERVER, + "Localização do Servidor de Retransmissão" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_MITM_SERVER, + "Escolha um servidor de retransmissão específico para usar. Locais geograficamente mais próximos tendem a ter menor latência." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, + "Adicionar ao mixer" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_PLAY, + "Adicionar ao mixer e reproduzir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION, + "Adicionar ao mixer" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY, + "Adicionar ao mixer e reproduzir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FILTER_BY_CURRENT_CORE, + "Filtrar por núcleo atual" + ) +MSG_HASH( + MSG_AUDIO_MIXER_VOLUME, + "Volume global do mixer de áudio" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_MIXER_VOLUME, + "Volume global do mixer de áudio (em dB). 0dB é o volume normal, e nenhum ganho será aplicado." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_VOLUME, + "Nível de Volume do Mixer de Áudio (dB)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_MUTE, + "Silenciar Mixer de Áudio" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_MIXER_MUTE, + "Silencia o mixer de áudio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_ONLINE_UPDATER, + "Exibir Atualizador Online" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_ONLINE_UPDATER, + "Exibir/ocultar a opção 'Atualizador Online'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_VIEWS_SETTINGS, + "Visualizações" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_VIEWS_SETTINGS, + "Exibe elementos na tela de menu." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_CORE_UPDATER, + "Exibir Atualizador de Núcleos" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_CORE_UPDATER, + "Exibir/ocultar a opção de atualizar núcleos (e arquivos de informação de núcleo)." + ) +MSG_HASH( + MSG_PREPARING_FOR_CONTENT_SCAN, + "Preparando a busca de conteúdo..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_DELETE, + "Remover núcleo" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_DELETE, + "Remover este núcleo do disco." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_FRAMEBUFFER_OPACITY, + "Opacidade do Framebuffer" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_FRAMEBUFFER_OPACITY, + "Modificar a opacidade do framebuffer." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES, + "Favoritos" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_GOTO_FAVORITES, + "Conteúdo adicionado aos 'Favoritos' vai aparecer aqui." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GOTO_MUSIC, + "Músicas" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_GOTO_MUSIC, + "Músicas que foram reproduzidas aparecem aqui." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GOTO_IMAGES, + "Imagens" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_GOTO_IMAGES, + "Imagens que foram exibidas aparecem aqui." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GOTO_VIDEO, + "Vídeos" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_GOTO_VIDEO, + "Vídeos que foram reproduzidos aparecem aqui." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_ICONS_ENABLE, + "Ícones do Menu" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MATERIALUI_ICONS_ENABLE, + "Habilitar/desabilitar os ícones exibidos do lado esquerdo dos itens de menu." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MAIN_MENU_ENABLE_SETTINGS, + "Habilitar aba de configurações" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS_PASSWORD, + "Definir senha para habilitar aba de configurações" + ) +MSG_HASH( + MSG_INPUT_ENABLE_SETTINGS_PASSWORD, + "Digite a senha" + ) +MSG_HASH( + MSG_INPUT_ENABLE_SETTINGS_PASSWORD_OK, + "Senha correta." + ) +MSG_HASH( + MSG_INPUT_ENABLE_SETTINGS_PASSWORD_NOK, + "Senha incorreta." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, + "Habilita a aba de configurações. É necessário reiniciar para que a aba apareça." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, + "O fornecimento de uma senha ao ocultar a aba de configurações permite restaurar mais tarde a partir do menu, indo para a aba Menu Principal, selecionando Habilitar aba configurações e inserindo a senha." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, + "Permite que o usuário renomeie os itens nas coleções." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, + "Permitir renomear itens" ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RENAME_ENTRY, + "Renomear o título do item." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RENAME_ENTRY, + "Renomear" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, + "Exibir 'Carregar Núcleo'" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CORE, + "Exibir/ocultar a opção 'Carregar Núcleo'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CONTENT, + "Exibir Carregar Conteúdo" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CONTENT, + "Exibir/ocultar a opção 'Carregar Conteúdo'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_INFORMATION, + "Exibir Informação" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_INFORMATION, + "Exibir/ocultar a opção 'Informação'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_CONFIGURATIONS, + "Exibir Configurações" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_CONFIGURATIONS, + "Exibir/ocultar a opção 'Configurações'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_HELP, + "Exibir Ajuda" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_HELP, + "Exibir/ocultar a opção 'Ajuda'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_QUIT_RETROARCH, + "Exibir Sair do RetroArch" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_QUIT_RETROARCH, + "Exibir/ocultar a opção 'Sair do RetroArch'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_REBOOT, + "Exibir Reiniciar" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_REBOOT, + "Exibir/ocultar a opção 'Reiniciar'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_SHUTDOWN, + "Exibir Desligar" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_SHUTDOWN, + "Exibir/ocultar a opção 'Desligar'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_VIEWS_SETTINGS, + "Menu Rápido" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_VIEWS_SETTINGS, + "Exibir ou ocultar elementos na tela de Menu Rápido." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_TAKE_SCREENSHOT, + "Exibir 'Captura de Tela'" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT, + "Exibir/ocultar a opção 'Captura de Tela'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_LOAD_STATE, + "Exibir Salvar/Carregar Estado" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE, + "Exibir/ocultar as opções para salvar/carregar estados." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, + "Exibir Desfazer Salvar/Carregar Estado" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, + "Exibir/ocultar as opções para abolir o salvar/carregar estado." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_ADD_TO_FAVORITES, + "Exibir Adicionar aos Favoritos" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, + "Exibir/ocultar a opção 'Adicionar aos Favoritos'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_OPTIONS, + "Exibir Opções" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_OPTIONS, + "Exibir/ocultar a opção 'Opções'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CONTROLS, + "Exibir Controles" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CONTROLS, + "Exibir/ocultar a opção 'Controles'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CHEATS, + "Exibir Trapaças" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CHEATS, + "Exibir/ocultar a opção 'Trapaças'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SHADERS, + "Exibir 'Shaders'" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SHADERS, + "Exibir/ocultar a opção 'Shaders'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, + "Exibir Salvar Redefinição de Núcleo" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, + "Exibir/ocultar a opção 'Salvar Redefinição de Núcleo'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, + "Exibir Salvar Redefinição de Jogo" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, + "Exibir/ocultar a opção 'Salvar Redefinição de Jogo'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_INFORMATION, + "Exibir Informação" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_INFORMATION, + "Exibir/ocultar a opção 'Informação'." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_ENABLE, + "Ativar Notificação de Fundo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_RED, + "Notificação de Fundo em Cor Vermelha" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_GREEN, + "Notificação de Fundo em Cor Verde" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_BLUE, + "Notificação de Fundo em Cor Azul" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_OPACITY, + "Opacidade da Notificação de Fundo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_DISABLE_KIOSK_MODE, + "Desabilitar o Modo Quiosque" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_DISABLE_KIOSK_MODE, + "Desabilita o Modo Quiosque. É necessária uma reinicialização para que a mudança tenha total efeito." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_ENABLE_KIOSK_MODE, + "Habilitar o Modo Quiosque" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_ENABLE_KIOSK_MODE, + "Protege a configuração escondendo todas as configurações relacionadas à configuração." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_KIOSK_MODE_PASSWORD, + "Definir senha para desabilitar o Modo Quiosque" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_KIOSK_MODE_PASSWORD, + "Fornece uma senha ao habilitar o Modo Quiosque tornando possível desabilitar mais tarde a partir do menu, indo para o Menu Principal, selecionando Desabilitar o Modo Quiosque e inserindo a senha." + ) +MSG_HASH( + MSG_INPUT_KIOSK_MODE_PASSWORD, + "Digite a Senha" + ) +MSG_HASH( + MSG_INPUT_KIOSK_MODE_PASSWORD_OK, + "Senha correta." + ) +MSG_HASH( + MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, + "Senha incorreta." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_RED, + "Notificação em Cor Vermelha" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_GREEN, + "Notificação em Cor Verde" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_BLUE, + "Notificação em Cor Azul" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FRAMECOUNT_SHOW, + "Exibir contagem de quadros na tela FPS" + ) +MSG_HASH( + MSG_CONFIG_OVERRIDE_LOADED, + "Substituição de configuração carregada." + ) +MSG_HASH( + MSG_GAME_REMAP_FILE_LOADED, + "Arquivo de remapeamento do jogo carregado." + ) +MSG_HASH( + MSG_CORE_REMAP_FILE_LOADED, + "Arquivo de remapeamento principal carregado." + ) +MSG_HASH( + MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES, + "O Adiantar Quadro foi desativado porque esse núcleo não suporta estados de jogo." + ) +MSG_HASH( + MSG_RUNAHEAD_FAILED_TO_SAVE_STATE, + "Falha ao salvar o estado do jogo. O Adiantar Quadro foi desativado." + ) +MSG_HASH( + MSG_RUNAHEAD_FAILED_TO_LOAD_STATE, + "Falha ao carregar o estado do jogo. O Adiandar Quadro foi desativado." + ) +MSG_HASH( + MSG_RUNAHEAD_FAILED_TO_CREATE_SECONDARY_INSTANCE, + "Falha ao criar uma segunda instância. O Adiantar Quadro agora usará apenas uma instância." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Adicione automaticamente conteúdo à lista de reprodução" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Verifica automaticamente o conteúdo carregado para que eles apareçam dentro das listas de reprodução." + ) +MSG_HASH( + MSG_SCANNING_OF_FILE_FINISHED, + "Verificação do arquivo terminado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_OPACITY, + "Opacidade da Janela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY, + "Qualidade da Reamostragem do Áudio" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, + "Abaixe esse valor para favorecer o desempenho/baixa latência em relação à qualidade de áudio, aumente se desejar melhor qualidade de áudio à custa do desempenho/baixa latência." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_WATCH_FOR_CHANGES, + "Ver arquivos de shader para mudanças" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHADER_WATCH_FOR_CHANGES, + "Aplicar automaticamente as alterações feitas nos arquivos de shader no disco." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_SHOW_DECORATIONS, + "Exibir Decorações da Janela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_STATISTICS_SHOW, + "Exibir estatísticas" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_STATISTICS_SHOW, + "Exibe estatísticas técnicas na tela." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_ENABLE, + "Ativar preenchimento de borda" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, + "Ativar espessura de preenchimento de borda" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, + "Ativar espessura de preenchimento do plano de fundo" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, + "Para monitores CRT de 15 kHz apenas. Tenta usar a resolução exata do núcleo/jogo e a taxa de atualização." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, + "Trocar para Resolução CRT" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, + "Quando Trocar para Resolução CRT está ativada, força a resolução horizontal ultrawide para minimizar a alternância de modo." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, + "Super Resolução CRT" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, + "Exibir Configurações de Rebobinamento" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, + "Exibir/ocultar as opções de Rebobinamento." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_LATENCY, + "Exibir/ocultar as opções de Latência." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_LATENCY, + "Exibir Configurações de Latência" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_OVERLAYS, + "Exibir/ocultar as opções de Sobreposição." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_OVERLAYS, + "Exibir Configurações de Sobreposição" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE_MENU, + "Ativar áudio de menu" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_ENABLE_MENU, + "Ativa ou desativa o som do menu." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_SETTINGS, + "Configurações do Mixer" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_MIXER_SETTINGS, + "Visualiza e/ou modifica as configurações do mixer de áudio." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_INFO, + "Informação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE, + "&Arquivo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_LOAD_CORE, + "&Carregar Núcleo..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_UNLOAD_CORE, + "&Descarregar Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_EXIT, + "Sai&r" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT, + "&Editar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT_SEARCH, + "&Pesquisar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW, + "&Visualizar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_CLOSED_DOCKS, + "Docas Fechadas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_SHADER_PARAMS, + "Parâmetros do Shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS, + "&Opções..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS, + "Lembrar Posições da Doca:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY, + "Lembrar Geometria da Janela:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB, + "Lembrar a Última Aba do Navegador de Conteúdo:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME, + "Tema" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_SYSTEM_DEFAULT, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK, + "Escuro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM, + "Personalizado..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE, + "Opções" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_TOOLS, + "&Ferramentas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP, + "&Ajuda" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_ABOUT, + "Sobre o RetroArch" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_DOCUMENTATION, + "Documentação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOAD_CUSTOM_CORE, + "Carregar Núcleo Personalizado..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOAD_CORE, + "Carregar Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOADING_CORE, + "Carregando Núcleo..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_NAME, + "Nome" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE_VERSION, + "Versão" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_TAB_PLAYLISTS, + "Listas de Reprodução" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER, + "Navegador de Arquivos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_TOP, + "Topo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_UP, + "Subir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_DOCK_CONTENT_BROWSER, + "Navegador de Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_BOXART, + "Arte da Capa" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_SCREENSHOT, + "Captura de Tela" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_TITLE_SCREEN, + "Tela de Título" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ALL_PLAYLISTS, + "Todas as Listas de Reprodução" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE, + "Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE_INFO, + "Informação do Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE_SELECTION_ASK, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_INFORMATION, + "Informação" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_WARNING, + "Advertência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ERROR, + "Erro" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR, + "Erro de Rede" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESTART_TO_TAKE_EFFECT, + "Por favor, reinicie o programa para que as alterações entrem em vigor." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOG, + "Relatório" + ) #ifdef HAVE_QT -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SCAN_FINISHED, - "Verificação Terminada.

\n" - "Para que o conteúdo seja verificado corretamente, você deve em ordem:\n" - "
  • ter um núcleo compatível já baixado
  • \n" - "
  • ter os \"Arquivos de Informação de Núcleo\" atualizados via Atualizador Online
  • \n" - "
  • ter a \"Base de Dados\" atualizada via Atualizador Online
  • \n" - "
  • reiniciar o RetroArch caso alguma das situações acima tenha sido feita
\n" - "E finalmente, o conteúdo deve corresponder as bases de dados existentes aqui. Se ainda não estiver funcionando, considere enviar um relatório de erro.") +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SCAN_FINISHED, + "Verificação Terminada.

\n" + "Para que o conteúdo seja verificado corretamente, você deve em ordem:\n" + "
  • ter um núcleo compatível já baixado
  • \n" + "
  • ter os \"Arquivos de Informação de Núcleo\" atualizados via Atualizador Online
  • \n" + "
  • ter a \"Base de Dados\" atualizada via Atualizador Online
  • \n" + "
  • reiniciar o RetroArch caso alguma das situações acima tenha sido feita
\n" + "E finalmente, o conteúdo deve corresponder as bases de dados existentes aqui. Se ainda não estiver funcionando, considere enviar um relatório de erro." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHOW_WIMP, + "Exibir Menu Desktop" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHOW_WIMP, + "Abre o menu desktop se estiver fechado." + ) #endif -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, - "Não mostrar isto novamente") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_STOP, - "Parar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE, - "Associar Núcleo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS, - "Ocultar Listas de Reprodução") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_HIDE, - "Ocultar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_HIGHLIGHT_COLOR, - "Cor de Destaque") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CHOOSE, - "&Escolher...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SELECT_COLOR, - "Selecionar Cor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SELECT_THEME, - "Selecionar Tema") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CUSTOM_THEME, - "Tema Personalizado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_PATH_IS_BLANK, - "O caminho do arquivo está em branco.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_IS_EMPTY, - "O arquivo está vazio.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_READ_OPEN_FAILED, - "Não foi possível abrir o arquivo para leitura.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST, - "O arquivo não existe.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SUGGEST_LOADED_CORE_FIRST, - "Sugerir Primeiro Núcleo Carregado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS, - "Opções de Substituição de Configuração") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_OVERRIDE_OPTIONS, - "Opções para substituir a configuração global.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY, - "Irá iniciar a reprodução do fluxo de áudio. Uma vez terminado, removerá o fluxo de áudio atual da memória.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_LOOPED, - "Irá iniciar a reprodução do fluxo de áudio. Uma vez terminado, ele fará um loop e reproduzirá a faixa novamente desde o começo.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_SEQUENTIAL, - "Irá iniciar a reprodução do fluxo de áudio. Uma vez terminado, ele irá pular para o próximo fluxo de áudio em ordem sequencial e repetirá este comportamento. Útil como um modo de reprodução de álbum.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_STOP, - "Isso interromperá a reprodução do fluxo de áudio, mas não o removerá da memória. Você pode começar a reproduzi-lo novamente selecionando 'Reproduzir'.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_REMOVE, - "Isso interromperá a reprodução do fluxo de áudio e o removerá completamente da memória.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_VOLUME, - "Ajuste o volume do fluxo de áudio.") -MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_MIXER, - "Adiciona esta faixa de áudio a um compartimento de fluxo de áudio disponível. Se nenhum compartimento estiver disponível no momento, ele será ignorado.") -MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_MIXER_AND_PLAY, - "Adiciona esta faixa de áudio a um compartimento de fluxo de áudio disponível e reproduz. Se nenhum compartimento estiver disponível no momento, ele será ignorado.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY, - "Reproduzir") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_LOOPED, - "Reproduzir (Loop)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_SEQUENTIAL, - "Reproduzir (Sequencial)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_STOP, - "Parar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_REMOVE, - "Remover") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_VOLUME, - "Volume") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DETECT_CORE_LIST_OK_CURRENT_CORE, - "Núcleo atual") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, - "Limpar") -MSG_HASH(MENU_ENUM_SUBLABEL_ACHIEVEMENT_PAUSE, - "Pausar conquistas para a sessão atual (Esta ação ativará Estados de Jogos, Trapaças, Rebobinagem, Pausa e Câmera Lenta).") -MSG_HASH(MENU_ENUM_SUBLABEL_ACHIEVEMENT_RESUME, - "Continuar conquistas para a sessão atual (Esta ação desabilitará Estados de Jogos, Trapaças, Rebobinagem, Pausa e Câmera Lenta e reiniciará o jogo atual).") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, - "No Menu") MSG_HASH( - MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, - "Habilitar o Discord" - ) + MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, + "Não mostrar isto novamente" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DISCORD_ALLOW, - "Habilitar ou desabilitar o suporte ao Discord. Não funcionará com a versão do navegador, apenas o cliente nativo de desktop." - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_POWER_MANAGEMENT_SETTINGS, - "Gerenciamento de Energia") -MSG_HASH(MENU_ENUM_SUBLABEL_POWER_MANAGEMENT_SETTINGS, - "Altere as configurações de gerenciamento de energia.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SUSTAINED_PERFORMANCE_MODE, - "Modo de Desempenho Sustentado") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_MPV_SUPPORT, - "Suporte mpv") + MENU_ENUM_LABEL_VALUE_QT_STOP, + "Parar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE, + "Associar Núcleo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS, + "Ocultar Listas de Reprodução" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_HIDE, + "Ocultar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_HIGHLIGHT_COLOR, + "Cor de Destaque" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CHOOSE, + "&Escolher..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_COLOR, + "Selecionar Cor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_THEME, + "Selecionar Tema" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CUSTOM_THEME, + "Tema Personalizado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_PATH_IS_BLANK, + "O caminho do arquivo está em branco." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_IS_EMPTY, + "O arquivo está vazio." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_READ_OPEN_FAILED, + "Não foi possível abrir o arquivo para leitura." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_WRITE_OPEN_FAILED, + "Não foi possível abrir o arquivo para ser gravado." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST, + "O arquivo não existe." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SUGGEST_LOADED_CORE_FIRST, + "Sugerir Primeiro Núcleo Carregado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ZOOM, + "Zoom" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_VIEW, + "Visialização" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_ICONS, + "Ícones" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_LIST, + "Lista" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS, + "Opções de Substituição de Configuração" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_OVERRIDE_OPTIONS, + "Opções para substituir a configuração global." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY, + "Irá iniciar a reprodução do fluxo de áudio. Uma vez terminado, removerá o fluxo de áudio atual da memória." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_LOOPED, + "Irá iniciar a reprodução do fluxo de áudio. Uma vez terminado, ele fará um loop e reproduzirá a faixa novamente desde o começo." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_SEQUENTIAL, + "Irá iniciar a reprodução do fluxo de áudio. Uma vez terminado, ele irá pular para o próximo fluxo de áudio em ordem sequencial e repetirá este comportamento. Útil como um modo de reprodução de álbum." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_STOP, + "Isso interromperá a reprodução do fluxo de áudio, mas não o removerá da memória. Você pode começar a reproduzi-lo novamente selecionando 'Reproduzir'." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_REMOVE, + "Isso interromperá a reprodução do fluxo de áudio e o removerá completamente da memória." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_VOLUME, + "Ajuste o volume do fluxo de áudio." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ADD_TO_MIXER, + "Adiciona esta faixa de áudio a um compartimento de fluxo de áudio disponível. Se nenhum compartimento estiver disponível no momento, ele será ignorado." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ADD_TO_MIXER_AND_PLAY, + "Adiciona esta faixa de áudio a um compartimento de fluxo de áudio disponível e reproduz. Se nenhum compartimento estiver disponível no momento, ele será ignorado." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY, + "Reproduzir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_LOOPED, + "Reproduzir (Loop)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_SEQUENTIAL, + "Reproduzir (Sequencial)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_STOP, + "Parar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_REMOVE, + "Remover" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_VOLUME, + "Volume" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DETECT_CORE_LIST_OK_CURRENT_CORE, + "Núcleo atual" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, + "Limpar" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ACHIEVEMENT_PAUSE, + "Pausar conquistas para a sessão atual (Esta ação ativará Estados de Jogos, Trapaças, Rebobinamento, Pausa e Câmera Lenta)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ACHIEVEMENT_RESUME, + "Continuar conquistas para a sessão atual (Esta ação desabilitará Estados de Jogos, Trapaças, Rebobinamento, Pausa e Câmera Lenta e reiniciará o jogo atual)." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, + "No Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "No Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "No Jogo (Pausado)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Jogando" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Pausado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, + "Habilitar o Discord" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DISCORD_ALLOW, + "Habilitar ou desabilitar o suporte ao Discord. Não funcionará com a versão do navegador, apenas o cliente nativo de desktop." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_INPUT, + "Entrada" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIDI_INPUT, + "Selecionar o dispositivo de entrada." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_OUTPUT, + "Saída" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIDI_OUTPUT, + "Selecionar o dispositivo de saída." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_VOLUME, + "Volume" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIDI_VOLUME, + "Definir o volume de saída (%)." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_POWER_MANAGEMENT_SETTINGS, + "Gerenciamento de Energia" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_POWER_MANAGEMENT_SETTINGS, + "Altera as configurações de gerenciamento de energia." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SUSTAINED_PERFORMANCE_MODE, + "Modo de Desempenho Sustentado" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_MPV_SUPPORT, + "Suporte de mpv" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_IDX, + "Índice" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_MATCH_IDX, + "Ver Coincidência #" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_MATCH, + "Coindidir Endereço: %08X Mask: %02X" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_MATCH, + "Criar Código de Coincidência #" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_MATCH, + "Excluir Coincidência #" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_BROWSE_MEMORY, + "Examinar Endereço: %08X" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DESC, + "Descrição" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_STATE, + "Habilitar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_CODE, + "Código" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_HANDLER, + "Manipulador" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_MEMORY_SEARCH_SIZE, + "Tamanho da Memória de Pesquisa" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_TYPE, + "Tipo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_VALUE, + "Valor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS, + "Endereço da Memória" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS_BIT_POSITION, + "Máscara do Endereço da Memória" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_TYPE, + "Vibrar Quando Memória" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_VALUE, + "Valor da Vibração" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PORT, + "Porta de Vibração" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_STRENGTH, + "Força Primária da Vibração" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_DURATION, + "Duração (ms) da Vibração Primária" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_STRENGTH, + "Força Secundária da Vibração" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_DURATION, + "Duração (ms) da Vibração Secundária" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_AFTER, + "Adicionar Nova Trapaça Depois Desta" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BEFORE, + "Adicionar Nova Trapaça Antes Desta" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_AFTER, + "Copiar Esta Trapaça Depois" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_BEFORE, + "Copiar Esta Trapaça Antes" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE, + "Excluir Esta Trapaça" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_EMU, + "Emulador" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_RETRO, + "RetroArch" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_DISABLED, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_SET_TO_VALUE, + "Ajustar Valor" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_INCREASE_VALUE, + "Aumentar por Valor" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_DECREASE_VALUE, + "Diminuir por Valor" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_EQ, + "Executar próxima trapaça se valor for igual à memória" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_NEQ, + "Executar próxima trapaça se valor for diferente da memória" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_LT, + "Executar próxima trapaça se valor for menor que a memória" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_GT, + "Executar próxima trapaça se valor for maior que a memória" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_DISABLED, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_CHANGES, + "Alterações" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_DOES_NOT_CHANGE, + "Não Altera" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_INCREASE, + "Aumenta" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_DECREASE, + "Diminui" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_EQ_VALUE, + "Igual Ao Valor da Vibração" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_NEQ_VALUE, + "Diferente Ao Valor da Vibração" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_LT_VALUE, + "Menor Ao Valor da Vibração" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_GT_VALUE, + "Maior Ao Valor da Vibração" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_1, + "1-bit, valor máx. = 0x01" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_2, + "2-bit, valor máx. = 0x03" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_4, + "4-bit, valor máx. = 0x0F" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_8, + "8-bit, valor máx. = 0xFF" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_16, + "16-bit, valor máx. = 0xFFFF" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_32, + "32-bit, valor máx. = 0xFFFFFFFF" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_0, + "1" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_1, + "2" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_2, + "3" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_3, + "4" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_4, + "5" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_5, + "6" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_6, + "7" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_7, + "8" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_8, + "9" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_9, + "10" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_10, + "11" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_11, + "12" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_12, + "13" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_13, + "14" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_14, + "15" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_15, + "16" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_16, + "All" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_CONT, + "Iniciar ou Continuar a Pesquisa de Trapaças" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_RESTART, + "Iniciar ou Reiniciar a Pesquisa de Trapaças" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EXACT, + "Pesquisar Memória por Valores" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LT, + "Pesquisar Memória por Valores" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GT, + "Pesquisar Memória por Valores" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQ, + "Pesquisar Memória por Valores" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GTE, + "Pesquisar Memória por Valores" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LTE, + "Pesquisar Memória por Valores" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_NEQ, + "Pesquisar Memória por Valores" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQPLUS, + "Pesquisar Memória por Valores" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQMINUS, + "Pesquisar Memória por Valores" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_MATCHES, + "Adicionar as %u Coincidências para Sua Lista" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_VIEW_MATCHES, + "Ver Lista de %u Coincidências" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_CREATE_OPTION, + "Criar Código Desta CoincidênciaCoincidência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_OPTION, + "Excluir Esta Coincidência" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_TOP, + "Adicionar Novo Código no Início" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BOTTOM, + "Adicionar Novo Código no Final" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_ALL, + "Excluir Todas as Trapaças" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RELOAD_CHEATS, + "Recarregar Trapaças Específicas do Jogo" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT_VAL, + "Igual a %u (%X)" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_LT_VAL, + "Menos do que Antes" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_GT_VAL, + "Maior que Antes" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_LTE_VAL, + "Menos ou Igual a Antes" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_GTE_VAL, + "Maior ou Igual a Antes" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_EQ_VAL, + "Igual a Antes" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ_VAL, + "Diferente a Antes" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS_VAL, + "Igual a Depois+%u (%X)" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS_VAL, + "Igual a Antes-%u (%X)" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS, + "Iniciar ou Continuar Pesquisa de Trapaças" + ) +MSG_HASH( + MSG_CHEAT_INIT_SUCCESS, + "Pesquisa de trapaças iniciada corretamente" + ) +MSG_HASH( + MSG_CHEAT_INIT_FAIL, + "Falha ao iniciar a pesquisa de trapaças" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_NOT_INITIALIZED, + "A pesquisa não foi iniciada" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_FOUND_MATCHES, + "Número de coincidências = %u" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_BIG_ENDIAN, + "Big Endian" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADDED_MATCHES_SUCCESS, + "Adicionadas %u coincidências" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADDED_MATCHES_FAIL, + "Falha ao adicionar coincidências" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS, + "Código criado da coincidência" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADD_MATCH_FAIL, + "Falha ao criar o código" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS, + "Excluir coincidência" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADDED_MATCHES_TOO_MANY, + "Não há espaço suficiente. O máximo é 100 trapaças" + ) +MSG_HASH( + MSG_CHEAT_ADD_TOP_SUCCESS, + "Nova trapaça adicionada ao início da lista." + ) +MSG_HASH( + MSG_CHEAT_ADD_BOTTOM_SUCCESS, + "Nova trapaça adicionada ao final da lista." + ) +MSG_HASH( + MSG_CHEAT_DELETE_ALL_INSTRUCTIONS, + "Pressione direita cinco vezes para excluir todas as trapaças." + ) +MSG_HASH( + MSG_CHEAT_DELETE_ALL_SUCCESS, + "Todas as trapaças foram excluídas." + ) +MSG_HASH( + MSG_CHEAT_ADD_BEFORE_SUCCESS, + "Nova trapaça adicionada antes deste." + ) +MSG_HASH( + MSG_CHEAT_ADD_AFTER_SUCCESS, + "Nova trapaça adicionada depois deste." + ) +MSG_HASH( + MSG_CHEAT_COPY_BEFORE_SUCCESS, + "Trapaça copiada antes deste." + ) +MSG_HASH( + MSG_CHEAT_COPY_AFTER_SUCCESS, + "Trapaça copiada depois deste." + ) +MSG_HASH( + MSG_CHEAT_DELETE_SUCCESS, + "Trapaça excluída." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PROGRESS, + "Progresso:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_LIST_MAX_COUNT, + "\"Todas as Listas de Repr.\" Máx. Entradas em Lista:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_GRID_MAX_COUNT, + "\"Todas as Listas de Repr.\" Máx. Entradas em Grade:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SHOW_HIDDEN_FILES, + "Mostrar Arquivos e Pastas Ocultas:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST, + "Nova Lista de Reprodução" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ENTER_NEW_PLAYLIST_NAME, + "Por favor, insira o novo nome da lista de reprodução:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DELETE_PLAYLIST, + "Excluir Lista de Reprodução" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST, + "Tem certeza de que deseja excluir a lista de reprodução \"%1\"?" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_QUESTION, + "Pergunta" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_DELETE_FILE, + "Não foi possível excluir o arquivo." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_RENAME_FILE, + "Não foi possível renomear o arquivo." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_GATHERING_LIST_OF_FILES, + "Coletando lista de arquivos ..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADDING_FILES_TO_PLAYLIST, + "Adicionando arquivos à lista de reprodução..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY, + "Entrada da Lista de Reprodução" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_NAME, + "Nome:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_PATH, + "Caminho:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_CORE, + "Núcleo:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_DATABASE, + "Banco de Dados:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FOR_THUMBNAILS, + "(usado para encontrar miniaturas)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST_ITEM, + "Tem certeza de que deseja excluir o item? \"%1\"?" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CANNOT_ADD_TO_ALL_PLAYLISTS, + "Por favor, primeiro escolha uma única lista de reprodução." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DELETE, + "Excluir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADD_ENTRY, + "Adicionar Entrada..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADD_FILES, + "Adicionar Arquivo(s)..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADD_FOLDER, + "Adicionar Pasta..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_EDIT, + "Editar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_FILES, + "Selecionar Arquivos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_FOLDER, + "Selecionar Pasta" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FIELD_MULTIPLE, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_UPDATE_PLAYLIST_ENTRY, + "Erro ao atualizar a entrada da lista de reprodução." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLEASE_FILL_OUT_REQUIRED_FIELDS, + "Por favor, preencha todos os campos requeridos." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_NIGHTLY, + "Atualizar o RetroArch (nightly)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FINISHED, + "O RetroArch foi atualizado com sucesso. Por favor, reinicie o aplicativo para que as alterações entrem em vigor." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FAILED, + "Falha na atualização." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_ABOUT_CONTRIBUTORS, + "Colaboradores" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CURRENT_SHADER, + "Shader atual" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MOVE_DOWN, + "Move para Baixo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MOVE_UP, + "Move para Cima" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOAD, + "Carregar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SAVE, + "Salvar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_REMOVE, + "Remover" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_APPLY, + "Aplicar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SHADER_ADD_PASS, + "Adicionar Passada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SHADER_CLEAR_ALL_PASSES, + "Limpar Todas as Passadas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SHADER_NO_PASSES, + "Não há passada de shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESET_PASS, + "Restaurar Passada" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESET_ALL_PASSES, + "Restaurar Todas as Passadas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESET_PARAMETER, + "Restaurar Parâmetro" + ) +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_THUMBNAIL, + "Baixar miniaturas") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALREADY_IN_PROGRESS, + "Um download já está em progresso.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_STARTUP_PLAYLIST, + "Iniciar na lista de reprodução:") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS, + "Baixar Todas as Miniaturas") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_PACK_DOWNLOADED_SUCCESSFULLY, + "Miniaturas baixadas com sucesso.") diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h index b79ce142cf..c20eaff54a 100644 --- a/intl/msg_hash_pt_pt.h +++ b/intl/msg_hash_pt_pt.h @@ -2505,7 +2505,7 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_FORCE_SRGB_DISABLE, "Desativar o suporte de sRGB FBO. Alguns controladores Intel OpenGL para o Windows possuem problemas de vídeo em sRGB FBO, se o mesmo estiver ativo. Ao ativar esta opção, poderá resolver esse problema." ) -MSG_HASH( +MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN, "Executar em ecrã completo. Esta definição poderá ser alterada a qualquer momento." ) @@ -3201,9 +3201,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Enable background filler thickness") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For 15 kHz CRT displays only. Attempts to use exact core/game resolution and refresh rate.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "When CRT SwitchRes is enabled, force ultrawide horizontal resolution to minimize mode switching.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, "Show Rewind Settings") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, @@ -3262,6 +3262,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Clear") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Enable Discord" diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index ea5cb8c63f..d18c31f741 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -3326,6 +3326,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Очистить") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Включить Discord") MSG_HASH(MENU_ENUM_SUBLABEL_DISCORD_ALLOW, @@ -3366,14 +3374,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, "Включить толщину заполнителя границ") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Включить фон заполнителя границ") -MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, +MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "Только для 15 кГц CRT дисплеев. Пытается использовать точное разрешение и частоту обновления ядра/игры.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, - "CRT SwitchRes") -MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, + "CRT SwitchRes") +MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "Когда CRT SwitchRes включен, принудительно устанавливает ультраширокое горизонтальное разрешение чтобы минимизировать изменение режима.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, - "CRT Super Resolution") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, + "CRT Super Resolution") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, "Показывать клавиатуру/контроллер на оверлее.") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index 929df3049f..62651d118f 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -1256,10 +1256,12 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE: snprintf(s, len, - "VRR Runloop Mode.\n" + "Sync to Exact Content Framerate.\n" " \n" - "This option will force x1 speed \n" - "to ensure smooth scrolling."); + "This option is the equivalent of forcing x1 speed\n" + "while still allowing fast forward.\n" + "No deviation from the core requested refresh rate,\n" + "no sound Dynamic Rate Control)."); break; case MENU_ENUM_LABEL_VIDEO_MONITOR_INDEX: snprintf(s, len, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 3eb0d97ea1..2bdf54430b 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1,4256 +1,7432 @@ MSG_HASH( - MSG_COMPILER, - "Compiler" - ) + MSG_COMPILER, + "Compiler" + ) MSG_HASH( - MSG_UNKNOWN_COMPILER, - "Unknown compiler" - ) + MSG_UNKNOWN_COMPILER, + "Unknown compiler" + ) MSG_HASH( - MSG_DEVICE_DISCONNECTED_FROM_PORT, - "Device disconnected from port" - ) + MSG_DEVICE_DISCONNECTED_FROM_PORT, + "Device disconnected from port" + ) MSG_HASH( - MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, - "Unknown netplay command received" - ) + MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, + "Unknown netplay command received" + ) MSG_HASH( - MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER, - "File already exists. Saving to backup buffer" - ) + MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER, + "File already exists. Saving to backup buffer" + ) MSG_HASH( - MSG_GOT_CONNECTION_FROM, - "Got connection from: \"%s\"" - ) + MSG_GOT_CONNECTION_FROM, + "Got connection from: \"%s\"" + ) MSG_HASH( - MSG_GOT_CONNECTION_FROM_NAME, - "Got connection from: \"%s (%s)\"" - ) + MSG_GOT_CONNECTION_FROM_NAME, + "Got connection from: \"%s (%s)\"" + ) MSG_HASH( - MSG_PUBLIC_ADDRESS, - "Public address" - ) + MSG_PUBLIC_ADDRESS, + "Public address" + ) MSG_HASH( - MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, - "No arguments supplied and no menu builtin, displaying help..." - ) + MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, + "No arguments supplied and no menu builtin, displaying help..." + ) MSG_HASH( - MSG_SETTING_DISK_IN_TRAY, - "Setting disk in tray" - ) + MSG_SETTING_DISK_IN_TRAY, + "Setting disk in tray" + ) MSG_HASH( - MSG_WAITING_FOR_CLIENT, - "Waiting for client ..." - ) + MSG_WAITING_FOR_CLIENT, + "Waiting for client ..." + ) MSG_HASH( - MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME, - "You have left the game" - ) + MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME, + "You have left the game" + ) MSG_HASH( - MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N, - "You have joined as player %u" - ) + MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N, + "You have joined as player %u" + ) MSG_HASH( - MSG_NETPLAY_YOU_HAVE_JOINED_WITH_INPUT_DEVICES_S, - "You have joined with input devices %.*s" - ) + MSG_NETPLAY_YOU_HAVE_JOINED_WITH_INPUT_DEVICES_S, + "You have joined with input devices %.*s" + ) MSG_HASH( - MSG_NETPLAY_PLAYER_S_LEFT, - "Player %.*s has left the game" - ) + MSG_NETPLAY_PLAYER_S_LEFT, + "Player %.*s has left the game" + ) MSG_HASH( - MSG_NETPLAY_S_HAS_JOINED_AS_PLAYER_N, - "%.*s has joined as player %u" - ) + MSG_NETPLAY_S_HAS_JOINED_AS_PLAYER_N, + "%.*s has joined as player %u" + ) MSG_HASH( - MSG_NETPLAY_S_HAS_JOINED_WITH_INPUT_DEVICES_S, - "%.*s has joined with input devices %.*s" - ) + MSG_NETPLAY_S_HAS_JOINED_WITH_INPUT_DEVICES_S, + "%.*s has joined with input devices %.*s" + ) MSG_HASH( - MSG_NETPLAY_NOT_RETROARCH, - "A netplay connection attempt failed because the peer is not running RetroArch, or is running an old version of RetroArch." - ) + MSG_NETPLAY_NOT_RETROARCH, + "A netplay connection attempt failed because the peer is not running RetroArch, or is running an old version of RetroArch." + ) MSG_HASH( - MSG_NETPLAY_OUT_OF_DATE, - "The netplay peer is running an old version of RetroArch. Cannot connect." - ) + MSG_NETPLAY_OUT_OF_DATE, + "The netplay peer is running an old version of RetroArch. Cannot connect." + ) MSG_HASH( - MSG_NETPLAY_DIFFERENT_VERSIONS, - "WARNING: A netplay peer is running a different version of RetroArch. If problems occur, use the same version." - ) + MSG_NETPLAY_DIFFERENT_VERSIONS, + "WARNING: A netplay peer is running a different version of RetroArch. If problems occur, use the same version." + ) MSG_HASH( - MSG_NETPLAY_DIFFERENT_CORES, - "A netplay peer is running a different core. Cannot connect." - ) + MSG_NETPLAY_DIFFERENT_CORES, + "A netplay peer is running a different core. Cannot connect." + ) MSG_HASH( - MSG_NETPLAY_DIFFERENT_CORE_VERSIONS, - "WARNING: A netplay peer is running a different version of the core. If problems occur, use the same version." - ) + MSG_NETPLAY_DIFFERENT_CORE_VERSIONS, + "WARNING: A netplay peer is running a different version of the core. If problems occur, use the same version." + ) MSG_HASH( - MSG_NETPLAY_ENDIAN_DEPENDENT, - "This core does not support inter-architecture netplay between these systems" - ) + MSG_NETPLAY_ENDIAN_DEPENDENT, + "This core does not support inter-architecture netplay between these systems" + ) MSG_HASH( - MSG_NETPLAY_PLATFORM_DEPENDENT, - "This core does not support inter-architecture netplay" - ) + MSG_NETPLAY_PLATFORM_DEPENDENT, + "This core does not support inter-architecture netplay" + ) MSG_HASH( - MSG_NETPLAY_ENTER_PASSWORD, - "Enter netplay server password:" - ) + MSG_NETPLAY_ENTER_PASSWORD, + "Enter netplay server password:" + ) MSG_HASH( - MSG_NETPLAY_INCORRECT_PASSWORD, - "Incorrect password" - ) + MSG_NETPLAY_INCORRECT_PASSWORD, + "Incorrect password" + ) MSG_HASH( - MSG_NETPLAY_SERVER_NAMED_HANGUP, - "\"%s\" has disconnected" - ) + MSG_NETPLAY_SERVER_NAMED_HANGUP, + "\"%s\" has disconnected" + ) MSG_HASH( - MSG_NETPLAY_SERVER_HANGUP, - "A netplay client has disconnected" - ) + MSG_NETPLAY_SERVER_HANGUP, + "A netplay client has disconnected" + ) MSG_HASH( - MSG_NETPLAY_CLIENT_HANGUP, - "Netplay disconnected" - ) + MSG_NETPLAY_CLIENT_HANGUP, + "Netplay disconnected" + ) MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED, - "You do not have permission to play" - ) + MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED, + "You do not have permission to play" + ) MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS, - "There are no free player slots" - ) + MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS, + "There are no free player slots" + ) MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY_NOT_AVAILABLE, - "The input devices requested are not available" - ) + MSG_NETPLAY_CANNOT_PLAY_NOT_AVAILABLE, + "The input devices requested are not available" + ) MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY, - "Cannot switch to play mode" - ) + MSG_NETPLAY_CANNOT_PLAY, + "Cannot switch to play mode" + ) MSG_HASH( - MSG_NETPLAY_PEER_PAUSED, - "Netplay peer \"%s\" paused" - ) + MSG_NETPLAY_PEER_PAUSED, + "Netplay peer \"%s\" paused" + ) MSG_HASH( - MSG_NETPLAY_CHANGED_NICK, - "Your nickname changed to \"%s\"" - ) + MSG_NETPLAY_CHANGED_NICK, + "Your nickname changed to \"%s\"" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, - "Give hardware-rendered cores their own private context. Avoids having to assume hardware state changes inbetween frames." - ) + MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, + "Give hardware-rendered cores their own private context. Avoids having to assume hardware state changes inbetween frames." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SETTINGS, - "Adjusts menu screen appearance settings." - ) + MENU_ENUM_SUBLABEL_MENU_SETTINGS, + "Adjusts menu screen appearance settings." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, - "Hard-synchronize the CPU and GPU. Reduces latency at the cost of performance." - ) + MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, + "Hard-synchronize the CPU and GPU. Reduces latency at the cost of performance." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_THREADED, - "Improves performance at the cost of latency and more video stuttering. Use only if you cannot obtain full speed otherwise." - ) + MENU_ENUM_SUBLABEL_VIDEO_THREADED, + "Improves performance at the cost of latency and more video stuttering. Use only if you cannot obtain full speed otherwise." + ) MSG_HASH( - MSG_AUDIO_VOLUME, - "Audio volume" - ) + MSG_AUDIO_VOLUME, + "Audio volume" + ) MSG_HASH( - MSG_AUTODETECT, - "Autodetect" - ) + MSG_AUTODETECT, + "Autodetect" + ) MSG_HASH( - MSG_AUTOLOADING_SAVESTATE_FROM, - "Auto-loading savestate from" - ) + MSG_AUTOLOADING_SAVESTATE_FROM, + "Auto-loading savestate from" + ) MSG_HASH( - MSG_CAPABILITIES, - "Capabilities" - ) + MSG_CAPABILITIES, + "Capabilities" + ) MSG_HASH( - MSG_CONNECTING_TO_NETPLAY_HOST, - "Connecting to netplay host" - ) + MSG_CONNECTING_TO_NETPLAY_HOST, + "Connecting to netplay host" + ) MSG_HASH( - MSG_CONNECTING_TO_PORT, - "Connecting to port" - ) + MSG_CONNECTING_TO_PORT, + "Connecting to port" + ) MSG_HASH( - MSG_CONNECTION_SLOT, - "Connection slot" - ) + MSG_CONNECTION_SLOT, + "Connection slot" + ) MSG_HASH( - MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY, - "Sorry, unimplemented: cores that don't demand content cannot participate in netplay." - ) + MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY, + "Sorry, unimplemented: cores that don't demand content cannot participate in netplay." + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, - "Password" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, + "Password" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, - "Accounts Cheevos" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, + "Accounts Cheevos" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, - "Username" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, + "Username" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, - "Accounts" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, + "Accounts" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST_END, - "Accounts List Endpoint" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST_END, + "Accounts List Endpoint" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, - "RetroAchievements" - ) + MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, + "RetroAchievements" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, - "Achievements" - ) + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, + "Achievements" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_PAUSE, - "Pause Achievements Hardcore Mode" - ) + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_PAUSE, + "Pause Achievements Hardcore Mode" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_RESUME, - "Resume Achievements Hardcore Mode" - ) + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_RESUME, + "Resume Achievements Hardcore Mode" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, - "Achievements (Hardcore)" - ) + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, + "Achievements (Hardcore)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, - "Scan Content" - ) + MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, + "Scan Content" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIGURATIONS_LIST, - "Configurations" - ) + MENU_ENUM_LABEL_VALUE_CONFIGURATIONS_LIST, + "Configurations" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_TAB, - "Import content" - ) + MENU_ENUM_LABEL_VALUE_ADD_TAB, + "Import content" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, - "Netplay Rooms" - ) + MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, + "Netplay Rooms" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, - "Ask" - ) + MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, + "Ask" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, - "Assets" - ) + MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, + "Assets" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, - "Block Frames" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, + "Block Frames" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, - "Audio Device" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, + "Audio Device" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_DRIVER, - "Audio Driver" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_DRIVER, + "Audio Driver" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_DSP_PLUGIN, - "Audio DSP Plugin" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_DSP_PLUGIN, + "Audio DSP Plugin" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE, - "Audio Enable" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE, + "Audio Enable" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, - "Audio Filter" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, + "Audio Filter" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, - "Turbo/Deadzone" - ) + MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, + "Turbo/Deadzone" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_LATENCY, - "Audio Latency (ms)" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_LATENCY, + "Audio Latency (ms)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MAX_TIMING_SKEW, - "Audio Maximum Timing Skew" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_MAX_TIMING_SKEW, + "Audio Maximum Timing Skew" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MUTE, - "Audio Mute" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_MUTE, + "Audio Mute" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_OUTPUT_RATE, - "Audio Output Rate (Hz)" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_OUTPUT_RATE, + "Audio Output Rate (Hz)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_RATE_CONTROL_DELTA, - "Dynamic Audio Rate Control" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_RATE_CONTROL_DELTA, + "Dynamic Audio Rate Control" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_DRIVER, - "Audio Resampler Driver" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_DRIVER, + "Audio Resampler Driver" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, - "Audio" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, + "Audio" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, - "Audio Sync" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, + "Audio Sync" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_VOLUME, - "Audio Volume Level (dB)" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_VOLUME, + "Audio Volume Level (dB)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_EXCLUSIVE_MODE, - "WASAPI Exclusive Mode" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_EXCLUSIVE_MODE, + "WASAPI Exclusive Mode" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_FLOAT_FORMAT, - "WASAPI Float Format" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_FLOAT_FORMAT, + "WASAPI Float Format" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_SH_BUFFER_LENGTH, - "WASAPI Shared Buffer Length" - ) + MENU_ENUM_LABEL_VALUE_AUDIO_WASAPI_SH_BUFFER_LENGTH, + "WASAPI Shared Buffer Length" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, - "SaveRAM Autosave Interval" - ) + MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, + "SaveRAM Autosave Interval" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, - "Load Override Files Automatically" - ) + MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, + "Load Override Files Automatically" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE, - "Load Remap Files Automatically" - ) + MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE, + "Load Remap Files Automatically" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, - "Load Shader Presets Automatically" - ) + MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, + "Load Shader Presets Automatically" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, - "Back" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, + "Back" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, - "Confirm" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, + "Confirm" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, - "Info" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, + "Info" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, - "Quit" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, + "Quit" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_DOWN, - "Scroll Down" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_DOWN, + "Scroll Down" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_UP, - "Scroll Up" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_UP, + "Scroll Up" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, - "Start" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, + "Start" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, - "Toggle Keyboard" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, + "Toggle Keyboard" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_MENU, - "Toggle Menu" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_MENU, + "Toggle Menu" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS, - "Basic menu controls" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS, + "Basic menu controls" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_CONFIRM, - "Confirm/OK" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_CONFIRM, + "Confirm/OK" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_INFO, - "Info" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_INFO, + "Info" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_QUIT, - "Quit" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_QUIT, + "Quit" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_SCROLL_UP, - "Scroll Up" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_SCROLL_UP, + "Scroll Up" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_START, - "Defaults" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_START, + "Defaults" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_KEYBOARD, - "Toggle Keyboard" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_KEYBOARD, + "Toggle Keyboard" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_MENU, - "Toggle Menu" - ) + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_MENU, + "Toggle Menu" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BLOCK_SRAM_OVERWRITE, - "Don't overwrite SaveRAM on loading savestate" - ) + MENU_ENUM_LABEL_VALUE_BLOCK_SRAM_OVERWRITE, + "Don't overwrite SaveRAM on loading savestate" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BLUETOOTH_ENABLE, - "Bluetooth Enable" - ) + MENU_ENUM_LABEL_VALUE_BLUETOOTH_ENABLE, + "Bluetooth Enable" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, - "Buildbot Assets URL" - ) + MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, + "Buildbot Assets URL" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY, - "Cache" - ) + MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY, + "Cache" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CAMERA_ALLOW, - "Allow Camera" - ) + MENU_ENUM_LABEL_VALUE_CAMERA_ALLOW, + "Allow Camera" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, - "Camera Driver" - ) + MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, + "Camera Driver" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT, - "Cheat" - ) + MENU_ENUM_LABEL_VALUE_CHEAT, + "Cheat" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, - "Apply Changes" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, + "Apply Changes" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_START_SEARCH, - "Start Search For New Cheat Code" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_START_SEARCH, + "Start Search For New Cheat Code" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_CONTINUE_SEARCH, - "Continue Search" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_CONTINUE_SEARCH, + "Continue Search" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, - "Cheat File" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, + "Cheat File" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE, - "Cheat File" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_FILE, + "Cheat File" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD, - "Load Cheat File (Replace)" - ) + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD, + "Load Cheat File (Replace)" + ) MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD_APPEND, - "Load Cheat File (Append)" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, - "Save Cheat File As" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, - "Cheat Passes" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION, - "Description" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, - "Hardcore Mode" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_ENABLE, - "Leaderboards" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_BADGES_ENABLE, - "Achievement Badges" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, - "Locked Achievements:" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY, - "Locked" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS, - "RetroAchievements" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL, - "Test Unofficial Achievements" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS, - "Unlocked Achievements:" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY, - "Unlocked" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY_HARDCORE, - "Hardcore" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_VERBOSE_ENABLE, - "Verbose Mode" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_AUTO_SCREENSHOT, - "Automatic Screenshot" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, - "Close Content" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIG, - "Config" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIGURATIONS, - "Load Configuration" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS, - "Configuration" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, - "Save Configuration on Exit" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Collections" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, - "Database" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_DIR, - "Content" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, - "History List Size") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_REMOVE, - "Allow to remove entries") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS, - "Quick Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIR, - "Downloads") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIRECTORY, - "Downloads") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS, - "Cheats") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_COUNTERS, - "Core Counters") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ENABLE, - "Show core name") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION, - "Core Information") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_AUTHORS, - "Authors") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CATEGORIES, - "Categories") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_LABEL, - "Core label") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_NAME, - "Core name") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE, - "Firmware(s)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES, - "License(s)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_PERMISSIONS, - "Permissions") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SUPPORTED_EXTENSIONS, - "Supported extensions") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_MANUFACTURER, - "System manufacturer") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_NAME, - "System name") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS, - "Controls") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_LIST, - "Load Core") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, - "Options") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SETTINGS, - "Core") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, - "Start a Core Automatically") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, - "Automatically extract downloaded archive") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_BUILDBOT_URL, - "Buildbot Cores URL") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST, - "Core Updater") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SETTINGS, - "Updater") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_ARCHITECTURE, - "CPU Architecture:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_CORES, - "CPU Cores:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_DIRECTORY, - "Cursor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_MANAGER, - "Cursor Manager") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CUSTOM_RATIO, - "Custom Ratio") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_MANAGER, - "Database Manager") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_SELECTION, - "Database Selection") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DELETE_ENTRY, - "Remove") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FAVORITES, - "Start directory") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_CONTENT, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_DEFAULT, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_NONE, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, - "Directory not found.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS, - "Directory") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_CYCLE_TRAY_STATUS, - "Disk Cycle Tray Status") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND, - "Disk Image Append") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_INDEX, - "Disk Index") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_OPTIONS, - "Disk Control") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DONT_CARE, - "Don't care") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST, - "Downloads") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE, - "Download Core...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT, - "Content Downloader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_ENABLE, - "DPI Override Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE, - "DPI Override") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS, - "Driver") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN, - "Load Dummy on Core Shutdown") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHECK_FOR_MISSING_FIRMWARE, - "Check for Missing Firmware Before Loading") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER, - "Dynamic Background") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY, - "Dynamic Backgrounds") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE, - "Enable Achievements") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR, - "Menu entry hover color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_NORMAL_COLOR, - "Menu entry normal color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FALSE, - "False") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FASTFORWARD_RATIO, - "Maximum Run Speed") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FAVORITES_TAB, - "Favorites") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FPS_SHOW, - "Display Framerate") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE, - "Limit Maximum Run Speed") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VRR_RUNLOOP_ENABLE, - "VRR Runloop (G-Sync, FreeSync Mode)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, - "Frame Throttle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, - "Frontend Counters") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, - "Load Content-Specific Core Options Automatically") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE, - "Create game-options file") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE, - "Save Game-options file") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP, - "Help") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING, - "Audio/Video Troubleshooting") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD, - "Changing Virtual Gamepad Overlay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CONTROLS, - "Basic Menu Controls") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_LIST, - "Help") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_LOADING_CONTENT, - "Loading Content") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT, - "Scanning For Content") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_WHAT_IS_A_CORE, - "What Is A Core?") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HISTORY_LIST_ENABLE, - "History List Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HISTORY_TAB, - "History") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, - "Horizontal Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_IMAGES_TAB, - "Image") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INFORMATION, - "Information") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INFORMATION_LIST, - "Information") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ADC_TYPE, - "Analog To Digital Type") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ALL_USERS_CONTROL_MENU, - "All Users Control Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X, - "Left Analog X") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_MINUS, - "Left analog X- (left)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_PLUS, - "Left analog X+ (right)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y, - "Left Analog Y") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_MINUS, - "Left analog Y- (up)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_PLUS, - "Left analog Y+ (down)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X, - "Right Analog X") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_MINUS, - "Right analog X- (left)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_PLUS, - "Right analog X+ (right)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y, - "Right Analog Y") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS, - "Right analog Y- (up)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS, - "Right analog Y+ (down)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_TRIGGER, - "Gun Trigger") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_RELOAD, - "Gun Reload") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_A, - "Gun Aux A") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_B, - "Gun Aux B") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_C, - "Gun Aux C") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_START, - "Gun Start") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_SELECT, - "Gun Select") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_UP, - "Gun D-pad Up") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_DOWN, - "Gun D-pad Down") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT, - "Gun D-pad Left") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, - "Gun D-pad Right") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, - "Autoconfig Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Analog Stick Deadzone") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, - "Menu Swap OK & Cancel Buttons") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, - "Bind All") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL, - "Bind Default All") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_TIMEOUT, - "Bind Timeout") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_HOLD, - "Bind Hold") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_HIDE_UNBOUND, - "Hide Unbound Core Input Descriptors") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_LABEL_SHOW, - "Display Input Descriptor Labels") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX, - "Device Index") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_TYPE, - "Device Type") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_INDEX, - "Mouse Index") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DRIVER, - "Input Driver") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DUTY_CYCLE, - "Duty Cycle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS, - "Input Hotkey Binds") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE, - "Keyboard Gamepad Mapping Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_A, - "A button (right)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, - "B button (down)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_DOWN, - "Down D-pad") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L2, - "L2 button (trigger)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L3, - "L3 button (thumb)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L, - "L button (shoulder)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT, - "Left D-pad") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R2, - "R2 button (trigger)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R3, - "R3 button (thumb)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R, - "R button (shoulder)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_RIGHT, - "Right D-pad") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, - "Select button") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, - "Start button") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_UP, - "Up D-pad") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X, - "X button (top)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, - "Y button (left)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEY, - "(Key: %s)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_LEFT, - "Mouse 1") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_RIGHT, - "Mouse 2") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_MIDDLE, - "Mouse 3") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON4, - "Mouse 4") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON5, - "Mouse 5") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_UP, - "Wheel Up") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_DOWN, - "Wheel Down") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_UP, - "Wheel Left") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_DOWN, - "Wheel Right") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, - "Keyboard Gamepad Mapping Type") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MAX_USERS, - "Max Users") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, - "Menu Toggle Gamepad Combo") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS, - "Cheat index -") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS, - "Cheat index +") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE, - "Cheat toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE, - "Disk eject toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT, - "Disk next") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, - "Disk prev") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, - "Enable hotkeys") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY, - "Fast forward hold") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY, - "Fast forward toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, - "Frameadvance") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, - "Fullscreen toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, - "Grab mouse toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, - "Game focus toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE, - "Desktop menu toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, - "Load state") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, - "Menu toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE, - "Movie record toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, - "Audio mute toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, - "Netplay toggle play/spectate mode") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, - "On-screen keyboard toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, - "Overlay next") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE, - "Pause toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, - "Quit RetroArch") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, - "Reset game") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, - "Rewind") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_DETAILS, - "Cheat Details") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_SEARCH, - "Start or Continue Cheat Search") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, - "Save state") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, - "Take screenshot") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, - "Next shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, - "Previous shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_HOLD_KEY, - "Slow motion hold") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_KEY, - "Slow motion toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, - "Savestate slot -") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, - "Savestate slot +") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, - "Volume -") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, - "Volume +") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_ENABLE, - "Display Overlay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU, - "Hide Overlay In Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, - "Show Inputs On Overlay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, - "Show Inputs Listen Port") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR, - "Poll Type Behavior") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_EARLY, - "Early") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_LATE, - "Late") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_NORMAL, - "Normal") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_PREFER_FRONT_TOUCH, - "Prefer Front Touch") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAPPING_DIRECTORY, - "Input Remapping") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAP_BINDS_ENABLE, - "Remap Binds Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SAVE_AUTOCONFIG, - "Save Autoconfig") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS, - "Input") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE, - "Small Keyboard Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TOUCH_ENABLE, - "Touch Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE, - "Turbo enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, - "Turbo Period") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_USER_BINDS, - "Input User %u Binds") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LATENCY_SETTINGS, - "Latency") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INTERNAL_STORAGE_STATUS, - "Internal storage status") -MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_AUTOCONFIG_DIR, - "Input Autoconfig") -MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_DRIVER, - "Joypad Driver") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LAKKA_SERVICES, - "Services") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_CHINESE_SIMPLIFIED, - "Chinese (Simplified)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_CHINESE_TRADITIONAL, - "Chinese (Traditional)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_DUTCH, - "Dutch") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ENGLISH, - "English") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ESPERANTO, - "Esperanto") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_FRENCH, - "French") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_GERMAN, - "German") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ITALIAN, - "Italian") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_JAPANESE, - "Japanese") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_KOREAN, - "Korean") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_POLISH, - "Polish") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_BRAZIL, - "Portuguese (Brazil)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_PORTUGAL, - "Portuguese (Portugal)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_RUSSIAN, - "Russian") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_SPANISH, - "Spanish") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_VIETNAMESE, - "Vietnamese") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ARABIC, - "Arabic") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LEFT_ANALOG, - "Left Analog") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH, - "Core") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_INFO_PATH, - "Core Info") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_LOG_LEVEL, - "Core Logging Level") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LINEAR, - "Linear") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_ARCHIVE, - "Load Archive") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY, - "Load Recent") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST, - "Load Content") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_STATE, - "Load State") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_ALLOW, - "Allow Location") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_DRIVER, - "Location Driver") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS, - "Logging") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOG_VERBOSITY, - "Logging Verbosity") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MAIN_MENU, - "Main Menu") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MANAGEMENT, - "Database Settings") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME, - "Menu Color Theme") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE, - "Blue") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE_GREY, - "Blue Grey") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_DARK_BLUE, - "Dark Blue") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_GREEN, - "Green") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_NVIDIA_SHIELD, - "Shield") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_RED, - "Red") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_YELLOW, - "Yellow") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_FOOTER_OPACITY, - "Footer Opacity") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_HEADER_OPACITY, - "Header Opacity") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DRIVER, - "Menu Driver") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE, - "Throttle Menu Framerate") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FILE_BROWSER_SETTINGS, - "Settings") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, - "Menu Linear Filter") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_HORIZONTAL_ANIMATION, - "Horizontal Animation") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, - "Appearance") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER, - "Background") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY, - "Background opacity") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MISSING, - "Missing") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MORE, - "...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MOUSE_ENABLE, - "Mouse Support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MULTIMEDIA_SETTINGS, - "Multimedia") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MUSIC_TAB, - "Music") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, - "Filter unknown extensions") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NAVIGATION_WRAPAROUND, - "Navigation Wrap-Around") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NEAREST, - "Nearest") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY, - "Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ALLOW_SLAVES, - "Allow Slave-Mode Clients") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, - "Netplay Check Frames") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN, - "Input Latency Frames") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, - "Input Latency Frames Range") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES, - "Netplay Delay Frames") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT, - "Disconnect from netplay host") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE, - "Netplay Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT, - "Connect to netplay host") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_HOST, - "Start netplay host") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISABLE_HOST, - "Stop netplay host") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS, - "Server Address") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LAN_SCAN_SETTINGS, - "Scan local network") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, - "Netplay Client Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, - "Username") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, - "Server Password") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE, - "Publicly Announce Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REQUEST_DEVICE_I, - "Request Device %u") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REQUIRE_SLAVES, - "Disallow Non-Slave-Mode Clients") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, - "Netplay settings") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG, - "Analog Input Sharing") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_MAX, - "Max") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_AVERAGE, - "Average") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL, - "Digital Input Sharing") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_OR, - "Share") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_XOR, - "Grapple") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_VOTE, - "Vote") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NONE, - "None") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NO_PREFERENCE, - "No preference") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_START_AS_SPECTATOR, - "Netplay Spectator Mode") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, - "Netplay Stateless Mode") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, - "Server Spectate-Only Password") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, - "Netplay Spectator Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, - "Netplay TCP Port") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, - "Netplay NAT Traversal") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_ENABLE, - "Network Commands") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT, - "Network Command Port") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_INFORMATION, - "Network Information") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_ENABLE, - "Network Gamepad") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_PORT, - "Network Remote Base Port") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_SETTINGS, - "Network") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO, - "No") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NONE, - "None") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE, - "N/A") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ACHIEVEMENTS_TO_DISPLAY, - "No achievements to display.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE, - "No Core") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORES_AVAILABLE, - "No cores available.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE_INFORMATION_AVAILABLE, - "No core information available.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE_OPTIONS_AVAILABLE, - "No core options available.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY, - "No entries to display.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_HISTORY_AVAILABLE, - "No history available.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE, - "No information is available.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ITEMS, - "No items.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETPLAY_HOSTS_FOUND, - "No netplay hosts found.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, - "No networks found.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, - "No performance counters.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, - "No playlists.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLIST_ENTRIES_AVAILABLE, - "No playlist entries available.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, - "No settings found.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, - "No shader parameters.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OFF, - "OFF") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ON, - "ON") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONLINE, - "Online") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER, - "Online Updater") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS, - "Onscreen Display") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS, - "Onscreen Overlay") -MSG_HASH(MENU_ENUM_SUBLABEL_ONSCREEN_OVERLAY_SETTINGS, - "Adjust Bezels and Onscreen controls") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS, - "Onscreen Notifications") -MSG_HASH(MENU_ENUM_SUBLABEL_ONSCREEN_NOTIFICATIONS_SETTINGS, - "Adjust the Onscreen Notifications") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OPEN_ARCHIVE, - "Browse Archive") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OPTIONAL, - "Optional") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY, - "Overlay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED, - "Autoload Preferred Overlay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_DIRECTORY, - "Overlay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_OPACITY, - "Overlay Opacity") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_PRESET, - "Overlay Preset") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_SCALE, - "Overlay Scale") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS, - "Onscreen Overlay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PAL60_ENABLE, - "Use PAL60 Mode") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY, - "Parent directory") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_LIBRETRO, - "Pause when menu activated") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, - "Don't run in background") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, - "Performance Counters") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, - "Playlists") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Playlist") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, - "Playlists") -MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, - "Touch Support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, - "Port") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PRESENT, - "Present") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PRIVACY_SETTINGS, - "Privacy") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIDI_SETTINGS, - "MIDI") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH, - "Quit RetroArch") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ANALOG, - "Analog supported") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_BBFC_RATING, - "BBFC Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CERO_RATING, - "CERO Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_COOP, - "Co-op supported") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CRC32, - "CRC32") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DESCRIPTION, - "Description") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DEVELOPER, - "Developer") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_ISSUE, - "Edge Magazine Issue") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_RATING, - "Edge Magazine Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_REVIEW, - "Edge Magazine Review") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ELSPA_RATING, - "ELSPA Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ENHANCEMENT_HW, - "Enhancement Hardware") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ESRB_RATING, - "ESRB Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FAMITSU_MAGAZINE_RATING, - "Famitsu Magazine Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FRANCHISE, - "Franchise") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_GENRE, - "Genre") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_MD5, - "MD5") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME, - "Name") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ORIGIN, - "Origin") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PEGI_RATING, - "PEGI Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PUBLISHER, - "Publisher") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_MONTH, - "Releasedate Month") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_YEAR, - "Releasedate Year") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RUMBLE, - "Rumble supported") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SERIAL, - "Serial") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SHA1, - "SHA1") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_START_CONTENT, - "Start Content") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, - "TGDB Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REBOOT, - "Reboot") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY, - "Recording Config") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_OUTPUT_DIRECTORY, - "Recording Output") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, - "Recording") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, - "Load Recording Config...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_DRIVER, - "Record Driver") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIDI_DRIVER, - "MIDI Driver") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_ENABLE, - "Enable Recording") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_PATH, - "Save Output Recording as...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_USE_OUTPUT_DIRECTORY, - "Save Recordings in Output Dir") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE, - "Remap File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_LOAD, - "Load Remap File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CORE, - "Save Core Remap File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CONTENT_DIR, - "Save Content Directory Remap File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_GAME, - "Save Game Remap File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CORE, - "Delete Core Remap File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_GAME, - "Delete Game Remap File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CONTENT_DIR, - "Delete Game Content Directory Remap File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REQUIRED, - "Required") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_CONTENT, - "Restart") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH, - "Restart RetroArch") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME, - "Resume") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME_CONTENT, - "Resume") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROKEYBOARD, - "RetroKeyboard") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD, - "RetroPad") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD_WITH_ANALOG, - "RetroPad w/ Analog") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS, - "Achievements") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_ENABLE, - "Rewind Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_AFTER_TOGGLE, - "Apply After Toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_AFTER_LOAD, - "Auto-Apply Cheats During Game Load") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_GRANULARITY, - "Rewind Granularity") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE, - "Rewind Buffer Size (MB)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE_STEP, - "Rewind Buffer Size Step (MB)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS, - "Rewind") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SETTINGS, - "Cheat Settings") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DETAILS_SETTINGS, - "Cheat Details") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_SETTINGS, - "Start or Continue Cheat Search") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY, - "File Browser") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY, - "Config") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN, - "Display Start Screen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG, - "Right Analog") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES, - "Add to Favorites") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST, - "Add to Favorites") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESET_CORE_ASSOCIATION, - "Reset Core Association") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN, - "Run") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_MUSIC, - "Run") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAMBA_ENABLE, - "SAMBA Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVEFILE_DIRECTORY, - "Savefile") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX, - "Save State Auto Index") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD, - "Auto Load State") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE, - "Auto Save State") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_DIRECTORY, - "Savestate") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE, - "Savestate Thumbnails") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG, - "Save Current Configuration") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, - "Save Core Overrides") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, - "Save Content Directory Overrides") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, - "Save Game Overrides") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_NEW_CONFIG, - "Save New Configuration") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_STATE, - "Save State") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS, - "Saving") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY, - "Scan Directory") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_FILE, - "Scan File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREENSHOT_DIRECTORY, - "Screenshot") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION, - "Screen Resolution") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SEARCH, - "Search") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SECONDS, - "seconds") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SETTINGS, - "Settings") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SETTINGS_TAB, - "Settings") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER, - "Shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_APPLY_CHANGES, - "Apply Changes") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS, - "Shaders") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON, - "Ribbon") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON_SIMPLIFIED, - "Ribbon (simplified)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SIMPLE_SNOW, - "Simple Snow") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOW, - "Snow") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_ADVANCED_SETTINGS, - "Show Advanced Settings") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_HIDDEN_FILES, - "Show Hidden Files and Folders") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHUTDOWN, - "Shutdown") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO, - "Slow-Motion Ratio") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_ENABLED, - "Run-Ahead to Reduce Latency") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_FRAMES, - "Number of Frames to Run Ahead") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_SECONDARY_INSTANCE, - "RunAhead Use Second Instance") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_HIDE_WARNINGS, - "RunAhead Hide Warnings") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVEFILES_ENABLE, - "Sort Saves In Folders") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVESTATES_ENABLE, - "Sort Savestates In Folders") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATES_IN_CONTENT_DIR_ENABLE, - "Write Savestates to Content Dir") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVEFILES_IN_CONTENT_DIR_ENABLE, - "Write Saves to Content Dir") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEMFILES_IN_CONTENT_DIR_ENABLE, - "System Files are in Content Dir") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREENSHOTS_IN_CONTENT_DIR_ENABLE, - "Write Screenshots to Content Dir") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SSH_ENABLE, - "SSH Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_START_CORE, - "Start Core") -MSG_HASH(MENU_ENUM_LABEL_VALUE_START_NET_RETROPAD, - "Start Remote RetroPad") -MSG_HASH(MENU_ENUM_LABEL_VALUE_START_VIDEO_PROCESSOR, - "Start Video Processor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STATE_SLOT, - "State Slot") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STATUS, - "Status") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STDIN_CMD_ENABLE, - "stdin Commands") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES, - "Suggested cores") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SUSPEND_SCREENSAVER_ENABLE, - "Suspend Screensaver") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_BGM_ENABLE, - "System BGM Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_DIRECTORY, - "System/BIOS") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFORMATION, - "System Information") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_7ZIP_SUPPORT, - "7zip support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ALSA_SUPPORT, - "ALSA support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_BUILD_DATE, - "Build date") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CG_SUPPORT, - "Cg support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COCOA_SUPPORT, - "Cocoa support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COMMAND_IFACE_SUPPORT, - "Command interface support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CORETEXT_SUPPORT, - "CoreText support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CPU_FEATURES, - "CPU Features") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_DPI, - "Display metric DPI") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_HEIGHT, - "Display metric height (mm)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_WIDTH, - "Display metric width (mm)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DSOUND_SUPPORT, - "DirectSound support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WASAPI_SUPPORT, - "WASAPI support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYLIB_SUPPORT, - "Dynamic library support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYNAMIC_SUPPORT, - "Dynamic run-time loading of libretro library") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_EGL_SUPPORT, - "EGL support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FBO_SUPPORT, - "OpenGL/Direct3D render-to-texture (multi-pass shaders) support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FFMPEG_SUPPORT, - "FFmpeg support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FREETYPE_SUPPORT, - "FreeType support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_IDENTIFIER, - "Frontend identifier") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_NAME, - "Frontend name") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_OS, - "Frontend OS") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GIT_VERSION, - "Git version") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GLSL_SUPPORT, - "GLSL support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_HLSL_SUPPORT, - "HLSL support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_JACK_SUPPORT, - "JACK support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_KMS_SUPPORT, - "KMS/EGL support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LAKKA_VERSION, - "Lakka Version") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, - "LibretroDB support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, - "Libusb support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "libxml2 XML parsing support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, - "Netplay (peer-to-peer) support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, - "Network Command interface support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_REMOTE_SUPPORT, - "Network Gamepad support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENAL_SUPPORT, - "OpenAL support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGLES_SUPPORT, - "OpenGL ES support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGL_SUPPORT, - "OpenGL support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENSL_SUPPORT, - "OpenSL support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENVG_SUPPORT, - "OpenVG support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OSS_SUPPORT, - "OSS support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OVERLAY_SUPPORT, - "Overlay support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE, - "Power source") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGED, - "Charged") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGING, - "Charging") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_DISCHARGING, - "Discharging") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_NO_SOURCE, - "No source") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PULSEAUDIO_SUPPORT, - "PulseAudio support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PYTHON_SUPPORT, - "Python (script support in shaders) support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RBMP_SUPPORT, - "BMP support (RBMP)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RETRORATING_LEVEL, - "RetroRating level") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RJPEG_SUPPORT, - "JPEG support (RJPEG)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ROARAUDIO_SUPPORT, - "RoarAudio support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RPNG_SUPPORT, - "PNG support (RPNG)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RSOUND_SUPPORT, - "RSound support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RTGA_SUPPORT, - "TGA support (RTGA)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL2_SUPPORT, - "SDL2 support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_IMAGE_SUPPORT, - "SDL image support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_SUPPORT, - "SDL1.2 support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SLANG_SUPPORT, - "Slang support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_THREADING_SUPPORT, - "Threading support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_UDEV_SUPPORT, - "Udev support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_V4L2_SUPPORT, - "Video4Linux2 support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VIDEO_CONTEXT_DRIVER, - "Video context driver") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VULKAN_SUPPORT, - "Vulkan support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_METAL_SUPPORT, - "Metal support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WAYLAND_SUPPORT, - "Wayland support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_X11_SUPPORT, - "X11 support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XAUDIO2_SUPPORT, - "XAudio2 support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XVIDEO_SUPPORT, - "XVideo support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ZLIB_SUPPORT, - "Zlib support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT, - "Take Screenshot") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, - "Threaded tasks") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS, - "Thumbnails") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS, - "Left Thumbnails") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS, - "Thumbnails Vertical Disposition") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, - "Thumbnails") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST, - "Thumbnails Updater") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS, - "Boxarts") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS, - "Screenshots") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS, - "Title Screens") -MSG_HASH(MENU_ENUM_LABEL_VALUE_TIMEDATE_ENABLE, - "Show date / time") -MSG_HASH(MENU_ENUM_LABEL_VALUE_TITLE_COLOR, - "Menu title color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_TRUE, - "True") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_ENABLE, - "UI Companion Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_START_ON_BOOT, - "UI Companion Start On Boot") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_TOGGLE, - "Show desktop menu on startup") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DESKTOP_MENU_ENABLE, - "Enable desktop menu (restart)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_MENUBAR_ENABLE, - "Menubar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE, - "Unable to read compressed file.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_LOAD_STATE, - "Undo Load State") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_SAVE_STATE, - "Undo Save State") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNKNOWN, - "Unknown") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS, - "Updater") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_ASSETS, - "Update Assets") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_AUTOCONFIG_PROFILES, - "Update Joypad Profiles") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CG_SHADERS, - "Update Cg Shaders") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CHEATS, - "Update Cheats") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CORE_INFO_FILES, - "Update Core Info Files") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_DATABASES, - "Update Databases") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_GLSL_SHADERS, - "Update GLSL Shaders") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_LAKKA, - "Update Lakka") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_OVERLAYS, - "Update Overlays") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_SLANG_SHADERS, - "Update Slang Shaders") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USER, - "User") -MSG_HASH(MENU_ENUM_LABEL_VALUE_KEYBOARD, - "Kbd") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS, - "User Interface") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_LANGUAGE, - "Language") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_SETTINGS, - "User") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER, - "Use Builtin Image Viewer") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_BUILTIN_PLAYER, - "Use Builtin Media Player") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ALLOW_ROTATE, - "Allow rotation") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO, - "Config Aspect Ratio") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_AUTO, - "Auto Aspect Ratio") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, - "Aspect Ratio") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, - "Black Frame Insertion") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, - "Crop Overscan (Reload)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, - "Disable Desktop Composition") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, - "Video Driver") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, - "Video Filter") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_DIR, - "Video Filter") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_FLICKER, - "Flicker filter") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_ENABLE, - "Enable Onscreen Notifications") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_PATH, - "Notification Font") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_SIZE, - "Notification Size") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_ASPECT, - "Force aspect ratio") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_SRGB_DISABLE, - "Force-disable sRGB FBO") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FRAME_DELAY, - "Frame Delay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN, - "Start in Fullscreen Mode") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GAMMA, - "Video Gamma") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GPU_RECORD, - "Use GPU Recording") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT, - "GPU Screenshot Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, - "Hard GPU Sync") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES, - "Hard GPU Sync Frames") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES, - "Max swapchain images") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_X, - "Notification X Position") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_Y, - "Notification Y Position") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MONITOR_INDEX, - "Monitor Index") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_POST_FILTER_RECORD, - "Use Post Filter Recording") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, - "Vertical Refresh Rate") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, - "Estimated Screen Framerate") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, - "Set Display-Reported Refresh Rate") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, - "Rotation") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, - "Windowed Scale") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER, - "Integer Scale") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS, - "Video") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DIR, - "Video Shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_NUM_PASSES, - "Shader Passes") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS, - "Shader Parameters") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET, - "Load Shader Preset") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS, - "Save Shader Preset As") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE, - "Save Core Preset") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_PARENT, - "Save Content Directory Preset") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME, - "Save Game Preset") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT, - "Enable Hardware Shared Context") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH, - "Bilinear Filtering") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER, - "Soft Filter Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SWAP_INTERVAL, - "Vertical Sync (Vsync) Swap Interval") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_TAB, - "Video") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_THREADED, - "Threaded Video") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VFILTER, - "Deflicker") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_HEIGHT, - "Custom Aspect Ratio Height") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_WIDTH, - "Custom Aspect Ratio Width") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X, - "Custom Aspect Ratio X Pos.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_Y, - "Custom Aspect Ratio Y Pos.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, - "Set VI Screen Width") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, - "Vertical Sync (Vsync)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, - "Windowed Fullscreen Mode") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_WIDTH, - "Window Width") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_HEIGHT, - "Window Height") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_X, - "Fullscreen Width") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_Y, - "Fullscreen Height") -MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_DRIVER, - "Wi-Fi Driver") -MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, - "Wi-Fi") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, - "Menu Alpha Factor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_RED, - "Menu Font Red Color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_GREEN, - "Menu Font Green Color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_BLUE, - "Menu Font Blue Color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, - "Menu Font") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, - "Custom") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_FLATUI, - "FlatUI") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME, - "Monochrome") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME_INVERTED, - "Monochrome Inverted") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_SYSTEMATIC, - "Systematic") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_NEOACTIVE, - "NeoActive") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL, - "Pixel") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE, - "RetroActive") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM, - "Retrosystem") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART, - "Dot-Art") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME, - "Menu Color Theme") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_APPLE_GREEN, - "Apple Green") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK, - "Dark") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LIGHT, - "Light") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MORNING_BLUE, - "Morning Blue") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK_PURPLE, - "Dark Purple") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_ELECTRIC_BLUE, - "Electric Blue") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_GOLDEN, - "Golden") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LEGACY_RED, - "Legacy Red") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MIDNIGHT_BLUE, - "Midnight Blue") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_PLAIN, - "Plain") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_UNDERSEA, - "Undersea") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_VOLCANIC_RED, - "Volcanic Red") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_RIBBON_ENABLE, - "Menu Shader Pipeline") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SCALE_FACTOR, - "Menu Scale Factor") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE, - "Icon Shadows Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_HISTORY, - "Show History Tab") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_ADD, - "Show Import content Tab") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_PLAYLISTS, - "Show Playlist Tabs") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_FAVORITES, - "Show Favorites Tab") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_IMAGES, - "Show Image Tab") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_MUSIC, - "Show Music Tab") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, - "Show Settings Tab") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, - "Show Video Tab") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, - "Show Netplay Tab") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, - "Menu Layout") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, - "Menu Icon Theme") -MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, - "Yes") -MSG_HASH(MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO, - "Shader Preset") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, - "Enable or disable achievements. For more information, visit http://retroachievements.org") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, - "Enable or disable unofficial achievements and/or beta features for testing purposes.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, - "Enable or disable savestates, cheats, rewind, pause, and slow-motion for all games.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_LEADERBOARDS_ENABLE, - "Enable or disable in-game leaderboards. Has no effect if Hardcore Mode is disabled.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_BADGES_ENABLE, - "Enable or disable badge display in the Achievement List.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_VERBOSE_ENABLE, - "Enable or disable OSD verbosity for achievements.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_AUTO_SCREENSHOT, - "Automatically take a screenshot when an achievement is triggered.") -MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, - "Change drivers used by the system.") -MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, - "Change achievement settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_SETTINGS, - "Change core settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_SETTINGS, - "Change recording settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_ONSCREEN_DISPLAY_SETTINGS, - "Change display overlay and keyboard overlay, and onscreen notification settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_FRAME_THROTTLE_SETTINGS, - "Change rewind, fast-forward, and slow-motion settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVING_SETTINGS, - "Change saving settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_LOGGING_SETTINGS, - "Change logging settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_USER_INTERFACE_SETTINGS, - "Change user interface settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_USER_SETTINGS, - "Change account, username, and language settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, - "Change your privacy settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIDI_SETTINGS, - "Change MIDI settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, - "Change default directories where files are located.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, - "Change playlist settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, - "Configure server and network settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, - "Scan content and add to the database.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, - "Change audio output settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE, - "Enable or disable bluetooth.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, - "Saves changes to the configuration file on exit.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATION_SETTINGS, - "Change default settings for configuration files.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATIONS_LIST, - "Manage and create configuration files.") -MSG_HASH(MENU_ENUM_SUBLABEL_CPU_CORES, - "Amount of cores that the CPU has.") -MSG_HASH(MENU_ENUM_SUBLABEL_FPS_SHOW, - "Displays the current framerate per second onscreen.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS, - "Configure hotkey settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, - "Gamepad button combination to toggle menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_SETTINGS, - "Change joypad, keyboard, and mouse settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_USER_BINDS, - "Configure controls for this user.") -MSG_HASH(MENU_ENUM_SUBLABEL_LATENCY_SETTINGS, - "Change settings related to video, audio and input latency.") -MSG_HASH(MENU_ENUM_SUBLABEL_LOG_VERBOSITY, - "Enable or disable logging to the terminal.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, - "Join or host a netplay session.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, - "Search for and connect to netplay hosts on the local network.") -MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "Display system information.") -MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, - "Download add-ons, components, and content for RetroArch.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, - "Enable or disable network sharing of your folders.") -MSG_HASH(MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, - "Manage operating system level services.") -MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES, - "Show hidden files/directories inside the file browser.") -MSG_HASH(MENU_ENUM_SUBLABEL_SSH_ENABLE, - "Enable or disable remote command line access.") -MSG_HASH(MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE, - "Prevents your system's screensaver from becoming active.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_WINDOW_SCALE, - "Sets the window size relative to the core viewport size. Alternatively, you can set a window width and height below for a fixed window size.") -MSG_HASH(MENU_ENUM_SUBLABEL_USER_LANGUAGE, - "Sets the language of the interface.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, - "Inserts a black frame inbetween frames. Useful for users with 120Hz screens who want to play 60Hz content to eliminate ghosting.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, - "Reduces latency at the cost of a higher risk of video stuttering. Adds a delay after V-Sync (in ms).") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, - "Sets how many frames the CPU can run ahead of the GPU when using 'Hard GPU Sync'.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, - "Tells the video driver to explicitly use a specified buffering mode.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, - "Selects which display screen to use.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, - "The accurate estimated refresh rate of the screen in Hz.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED, - "The refresh rate as reported by the display driver.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, - "Change video output settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, - "Scans for wireless networks and establishes connection.") -MSG_HASH(MENU_ENUM_SUBLABEL_HELP_LIST, - "Learn more about how the program works.") -MSG_HASH(MSG_ADDED_TO_FAVORITES, - "Added to favorites") -MSG_HASH(MSG_RESET_CORE_ASSOCIATION, - "Playlist entry core association has been reset.") -MSG_HASH(MSG_APPENDED_DISK, - "Appended disk") -MSG_HASH(MSG_APPLICATION_DIR, - "Application Dir") -MSG_HASH(MSG_APPLYING_CHEAT, - "Applying cheat changes.") -MSG_HASH(MSG_APPLYING_SHADER, - "Applying shader") -MSG_HASH(MSG_AUDIO_MUTED, - "Audio muted.") -MSG_HASH(MSG_AUDIO_UNMUTED, - "Audio unmuted.") -MSG_HASH(MSG_AUTOCONFIG_FILE_ERROR_SAVING, - "Error saving autoconf file.") -MSG_HASH(MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY, - "Autoconfig file saved successfully.") -MSG_HASH(MSG_AUTOSAVE_FAILED, - "Could not initialize autosave.") -MSG_HASH(MSG_AUTO_SAVE_STATE_TO, - "Auto save state to") -MSG_HASH(MSG_BLOCKING_SRAM_OVERWRITE, - "Blocking SRAM Overwrite") -MSG_HASH(MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT, - "Bringing up command interface on port") -MSG_HASH(MSG_BYTES, - "bytes") -MSG_HASH(MSG_CANNOT_INFER_NEW_CONFIG_PATH, - "Cannot infer new config path. Use current time.") -MSG_HASH(MSG_CHEEVOS_HARDCORE_MODE_ENABLE, - "Hardcore Mode Enabled, savestate & rewind were disabled.") -MSG_HASH(MSG_COMPARING_WITH_KNOWN_MAGIC_NUMBERS, - "Comparing with known magic numbers...") -MSG_HASH(MSG_COMPILED_AGAINST_API, - "Compiled against API") -MSG_HASH(MSG_CONFIG_DIRECTORY_NOT_SET, - "Config directory not set. Cannot save new config.") -MSG_HASH(MSG_CONNECTED_TO, - "Connected to") -MSG_HASH(MSG_CONTENT_CRC32S_DIFFER, - "Content CRC32s differ. Cannot use different games.") -MSG_HASH(MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT, - "Content loading skipped. Implementation will load it on its own.") -MSG_HASH(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES, - "Core does not support save states.") -MSG_HASH(MSG_CORE_OPTIONS_FILE_CREATED_SUCCESSFULLY, - "Core options file created successfully.") -MSG_HASH(MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER, - "Could not find any next driver") -MSG_HASH(MSG_COULD_NOT_FIND_COMPATIBLE_SYSTEM, - "Could not find compatible system.") -MSG_HASH(MSG_COULD_NOT_FIND_VALID_DATA_TRACK, - "Could not find valid data track") -MSG_HASH(MSG_COULD_NOT_OPEN_DATA_TRACK, - "could not open data track") -MSG_HASH(MSG_COULD_NOT_READ_CONTENT_FILE, - "Could not read content file") -MSG_HASH(MSG_COULD_NOT_READ_MOVIE_HEADER, - "Could not read movie header.") -MSG_HASH(MSG_COULD_NOT_READ_STATE_FROM_MOVIE, - "Could not read state from movie.") -MSG_HASH(MSG_CRC32_CHECKSUM_MISMATCH, - "CRC32 checksum mismatch between content file and saved content checksum in replay file header. Replay highly likely to desync on playback.") -MSG_HASH(MSG_CUSTOM_TIMING_GIVEN, - "Custom timing given") -MSG_HASH(MSG_DECOMPRESSION_ALREADY_IN_PROGRESS, - "Decompression already in progress.") -MSG_HASH(MSG_DECOMPRESSION_FAILED, - "Decompression failed.") -MSG_HASH(MSG_DETECTED_VIEWPORT_OF, - "Detected viewport of") -MSG_HASH(MSG_DID_NOT_FIND_A_VALID_CONTENT_PATCH, - "Did not find a valid content patch.") -MSG_HASH(MSG_DISCONNECT_DEVICE_FROM_A_VALID_PORT, - "Disconnect device from a valid port.") -MSG_HASH(MSG_DISK_CLOSED, - "Closed") -MSG_HASH(MSG_DISK_EJECTED, - "Ejected") -MSG_HASH(MSG_DOWNLOADING, - "Downloading") -MSG_HASH(MSG_INDEX_FILE, - "index") -MSG_HASH(MSG_DOWNLOAD_FAILED, - "Download failed") -MSG_HASH(MSG_ERROR, - "Error") -MSG_HASH(MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT, - "Libretro core requires content, but nothing was provided.") -MSG_HASH(MSG_ERROR_LIBRETRO_CORE_REQUIRES_SPECIAL_CONTENT, - "Libretro core requires special content, but none were provided.") -MSG_HASH(MSG_ERROR_PARSING_ARGUMENTS, - "Error parsing arguments.") -MSG_HASH(MSG_ERROR_SAVING_CORE_OPTIONS_FILE, - "Error saving core options file.") -MSG_HASH(MSG_ERROR_SAVING_REMAP_FILE, - "Error saving remap file.") -MSG_HASH(MSG_ERROR_REMOVING_REMAP_FILE, - "Error removing remap file.") -MSG_HASH(MSG_ERROR_SAVING_SHADER_PRESET, - "Error saving shader preset.") -MSG_HASH(MSG_EXTERNAL_APPLICATION_DIR, - "External Application Dir") -MSG_HASH(MSG_EXTRACTING, - "Extracting") -MSG_HASH(MSG_EXTRACTING_FILE, - "Extracting file") -MSG_HASH(MSG_FAILED_SAVING_CONFIG_TO, - "Failed saving config to") -MSG_HASH(MSG_FAILED_TO, - "Failed to") -MSG_HASH(MSG_FAILED_TO_ACCEPT_INCOMING_SPECTATOR, - "Failed to accept incoming spectator.") -MSG_HASH(MSG_FAILED_TO_ALLOCATE_MEMORY_FOR_PATCHED_CONTENT, - "Failed to allocate memory for patched content...") -MSG_HASH(MSG_FAILED_TO_APPLY_SHADER, - "Failed to apply shader.") -MSG_HASH(MSG_FAILED_TO_BIND_SOCKET, - "Failed to bind socket.") -MSG_HASH(MSG_FAILED_TO_CREATE_THE_DIRECTORY, - "Failed to create the directory.") -MSG_HASH(MSG_FAILED_TO_EXTRACT_CONTENT_FROM_COMPRESSED_FILE, - "Failed to extract content from compressed file") -MSG_HASH(MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT, - "Failed to get nickname from client.") -MSG_HASH(MSG_FAILED_TO_LOAD, - "Failed to load") -MSG_HASH(MSG_FAILED_TO_LOAD_CONTENT, - "Failed to load content") -MSG_HASH(MSG_FAILED_TO_LOAD_MOVIE_FILE, - "Failed to load movie file") -MSG_HASH(MSG_FAILED_TO_LOAD_OVERLAY, - "Failed to load overlay.") -MSG_HASH(MSG_FAILED_TO_LOAD_STATE, - "Failed to load state from") -MSG_HASH(MSG_FAILED_TO_OPEN_LIBRETRO_CORE, - "Failed to open libretro core") -MSG_HASH(MSG_FAILED_TO_PATCH, - "Failed to patch") -MSG_HASH(MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT, - "Failed to receive header from client.") -MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME, - "Failed to receive nickname.") -MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST, - "Failed to receive nickname from host.") -MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME_SIZE_FROM_HOST, - "Failed to receive nickname size from host.") -MSG_HASH(MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST, - "Failed to receive SRAM data from host.") -MSG_HASH(MSG_FAILED_TO_REMOVE_DISK_FROM_TRAY, - "Failed to remove disk from tray.") -MSG_HASH(MSG_FAILED_TO_REMOVE_TEMPORARY_FILE, - "Failed to remove temporary file") -MSG_HASH(MSG_FAILED_TO_SAVE_SRAM, - "Failed to save SRAM") -MSG_HASH(MSG_FAILED_TO_SAVE_STATE_TO, - "Failed to save state to") -MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME, - "Failed to send nickname.") -MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_SIZE, - "Failed to send nickname size.") -MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT, - "Failed to send nickname to client.") -MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_TO_HOST, - "Failed to send nickname to host.") -MSG_HASH(MSG_FAILED_TO_SEND_SRAM_DATA_TO_CLIENT, - "Failed to send SRAM data to client.") -MSG_HASH(MSG_FAILED_TO_START_AUDIO_DRIVER, - "Failed to start audio driver. Will continue without audio.") -MSG_HASH(MSG_FAILED_TO_START_MOVIE_RECORD, - "Failed to start movie record.") -MSG_HASH(MSG_FAILED_TO_START_RECORDING, - "Failed to start recording.") -MSG_HASH(MSG_FAILED_TO_TAKE_SCREENSHOT, - "Failed to take screenshot.") -MSG_HASH(MSG_FAILED_TO_UNDO_LOAD_STATE, - "Failed to undo load state.") -MSG_HASH(MSG_FAILED_TO_UNDO_SAVE_STATE, - "Failed to undo save state.") -MSG_HASH(MSG_FAILED_TO_UNMUTE_AUDIO, - "Failed to unmute audio.") -MSG_HASH(MSG_FATAL_ERROR_RECEIVED_IN, - "Fatal error received in") -MSG_HASH(MSG_FILE_NOT_FOUND, - "File not found") -MSG_HASH(MSG_FOUND_AUTO_SAVESTATE_IN, - "Found auto savestate in") -MSG_HASH(MSG_FOUND_DISK_LABEL, - "Found disk label") -MSG_HASH(MSG_FOUND_FIRST_DATA_TRACK_ON_FILE, - "Found first data track on file") -MSG_HASH(MSG_FOUND_LAST_STATE_SLOT, - "Found last state slot") -MSG_HASH(MSG_FOUND_SHADER, - "Found shader") -MSG_HASH(MSG_FRAMES, - "Frames") -MSG_HASH(MSG_GAME_SPECIFIC_CORE_OPTIONS_FOUND_AT, - "Per-Game Options: game-specific core options found at") -MSG_HASH(MSG_GOT_INVALID_DISK_INDEX, - "Got invalid disk index.") -MSG_HASH(MSG_GRAB_MOUSE_STATE, - "Grab mouse state") -MSG_HASH(MSG_GAME_FOCUS_ON, - "Game focus on") -MSG_HASH(MSG_GAME_FOCUS_OFF, - "Game focus off") -MSG_HASH(MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING, - "Libretro core is hardware rendered. Must use post-shaded recording as well.") -MSG_HASH(MSG_INFLATED_CHECKSUM_DID_NOT_MATCH_CRC32, - "Inflated checksum did not match CRC32.") -MSG_HASH(MSG_INPUT_CHEAT, - "Input Cheat") -MSG_HASH(MSG_INPUT_CHEAT_FILENAME, - "Input Cheat Filename") -MSG_HASH(MSG_INPUT_PRESET_FILENAME, - "Input Preset Filename") -MSG_HASH(MSG_INPUT_RENAME_ENTRY, - "Rename Title") -MSG_HASH(MSG_INTERFACE, - "Interface") -MSG_HASH(MSG_INTERNAL_STORAGE, - "Internal Storage") -MSG_HASH(MSG_REMOVABLE_STORAGE, - "Removable Storage") -MSG_HASH(MSG_INVALID_NICKNAME_SIZE, - "Invalid nickname size.") -MSG_HASH(MSG_IN_BYTES, - "in bytes") -MSG_HASH(MSG_IN_GIGABYTES, - "in gigabytes") -MSG_HASH(MSG_IN_MEGABYTES, - "in megabytes") -MSG_HASH(MSG_LIBRETRO_ABI_BREAK, - "is compiled against a different version of libretro than this libretro implementation.") -MSG_HASH(MSG_LIBRETRO_FRONTEND, - "Frontend for libretro") -MSG_HASH(MSG_LOADED_STATE_FROM_SLOT, - "Loaded state from slot #%d.") -MSG_HASH(MSG_LOADED_STATE_FROM_SLOT_AUTO, - "Loaded state from slot #-1 (auto).") -MSG_HASH(MSG_LOADING, - "Loading") -MSG_HASH(MSG_FIRMWARE, - "One or more firmware files are missing") -MSG_HASH(MSG_LOADING_CONTENT_FILE, - "Loading content file") -MSG_HASH(MSG_LOADING_HISTORY_FILE, - "Loading history file") -MSG_HASH(MSG_LOADING_STATE, - "Loading state") -MSG_HASH(MSG_MEMORY, - "Memory") -MSG_HASH(MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE, - "Movie file is not a valid BSV1 file.") -MSG_HASH(MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION, - "Movie format seems to have a different serializer version. Will most likely fail.") -MSG_HASH(MSG_MOVIE_PLAYBACK_ENDED, - "Movie playback ended.") -MSG_HASH(MSG_MOVIE_RECORD_STOPPED, - "Stopping movie record.") -MSG_HASH(MSG_NETPLAY_FAILED, - "Failed to initialize netplay.") -MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE, - "No content, starting dummy core.") -MSG_HASH(MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET, - "No save state has been overwritten yet.") -MSG_HASH(MSG_NO_STATE_HAS_BEEN_LOADED_YET, - "No state has been loaded yet.") -MSG_HASH(MSG_OVERRIDES_ERROR_SAVING, - "Error saving overrides.") -MSG_HASH(MSG_OVERRIDES_SAVED_SUCCESSFULLY, - "Overrides saved successfully.") -MSG_HASH(MSG_PAUSED, - "Paused.") -MSG_HASH(MSG_PROGRAM, - "RetroArch") -MSG_HASH(MSG_READING_FIRST_DATA_TRACK, - "Reading first data track...") -MSG_HASH(MSG_RECEIVED, - "received") -MSG_HASH(MSG_RECORDING_TERMINATED_DUE_TO_RESIZE, - "Recording terminated due to resize.") -MSG_HASH(MSG_RECORDING_TO, - "Recording to") -MSG_HASH(MSG_REDIRECTING_CHEATFILE_TO, - "Redirecting cheat file to") -MSG_HASH(MSG_REDIRECTING_SAVEFILE_TO, - "Redirecting save file to") -MSG_HASH(MSG_REDIRECTING_SAVESTATE_TO, - "Redirecting savestate to") -MSG_HASH(MSG_REMAP_FILE_SAVED_SUCCESSFULLY, - "Remap file saved successfully.") -MSG_HASH(MSG_REMAP_FILE_REMOVED_SUCCESSFULLY, - "Remap file removed successfully.") -MSG_HASH(MSG_REMOVED_DISK_FROM_TRAY, - "Removed disk from tray.") -MSG_HASH(MSG_REMOVING_TEMPORARY_CONTENT_FILE, - "Removing temporary content file") -MSG_HASH(MSG_RESET, - "Reset") -MSG_HASH(MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT, - "Restarting recording due to driver reinit.") -MSG_HASH(MSG_RESTORED_OLD_SAVE_STATE, - "Restored old save state.") -MSG_HASH(MSG_RESTORING_DEFAULT_SHADER_PRESET_TO, - "Shaders: restoring default shader preset to") -MSG_HASH(MSG_REVERTING_SAVEFILE_DIRECTORY_TO, - "Reverting savefile directory to") -MSG_HASH(MSG_REVERTING_SAVESTATE_DIRECTORY_TO, - "Reverting savestate directory to") -MSG_HASH(MSG_REWINDING, - "Rewinding.") -MSG_HASH(MSG_REWIND_INIT, - "Initializing rewind buffer with size") -MSG_HASH(MSG_REWIND_INIT_FAILED, - "Failed to initialize rewind buffer. Rewinding will be disabled.") -MSG_HASH(MSG_REWIND_INIT_FAILED_THREADED_AUDIO, - "Implementation uses threaded audio. Cannot use rewind.") -MSG_HASH(MSG_REWIND_REACHED_END, - "Reached end of rewind buffer.") -MSG_HASH(MSG_SAVED_NEW_CONFIG_TO, - "Saved new config to") -MSG_HASH(MSG_SAVED_STATE_TO_SLOT, - "Saved state to slot #%d.") -MSG_HASH(MSG_SAVED_STATE_TO_SLOT_AUTO, - "Saved state to slot #-1 (auto).") -MSG_HASH(MSG_SAVED_SUCCESSFULLY_TO, - "Saved successfully to") -MSG_HASH(MSG_SAVING_RAM_TYPE, - "Saving RAM type") -MSG_HASH(MSG_SAVING_STATE, - "Saving state") -MSG_HASH(MSG_SCANNING, - "Scanning") -MSG_HASH(MSG_SCANNING_OF_DIRECTORY_FINISHED, - "Scanning of directory finished") -MSG_HASH(MSG_SENDING_COMMAND, - "Sending command") -MSG_HASH(MSG_SEVERAL_PATCHES_ARE_EXPLICITLY_DEFINED, - "Several patches are explicitly defined, ignoring all...") -MSG_HASH(MSG_SHADER, - "Shader") -MSG_HASH(MSG_SHADER_PRESET_SAVED_SUCCESSFULLY, - "Shader preset saved successfully.") -MSG_HASH(MSG_SKIPPING_SRAM_LOAD, - "Skipping SRAM load.") -MSG_HASH(MSG_SLOW_MOTION, - "Slow motion.") -MSG_HASH(MSG_FAST_FORWARD, - "Fast forward.") -MSG_HASH(MSG_SLOW_MOTION_REWIND, - "Slow motion rewind.") -MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED, - "SRAM will not be saved.") -MSG_HASH(MSG_STARTING_MOVIE_PLAYBACK, - "Starting movie playback.") -MSG_HASH(MSG_STARTING_MOVIE_RECORD_TO, - "Starting movie record to") -MSG_HASH(MSG_STATE_SIZE, - "State size") -MSG_HASH(MSG_STATE_SLOT, - "State slot") -MSG_HASH(MSG_TAKING_SCREENSHOT, - "Taking screenshot.") -MSG_HASH(MSG_TO, - "to") -MSG_HASH(MSG_UNDID_LOAD_STATE, - "Undid load state.") -MSG_HASH(MSG_UNDOING_SAVE_STATE, - "Undoing save state") -MSG_HASH(MSG_UNKNOWN, - "Unknown") -MSG_HASH(MSG_UNPAUSED, - "Unpaused.") -MSG_HASH(MSG_UNRECOGNIZED_COMMAND, - "Unrecognized command") -MSG_HASH(MSG_USING_CORE_NAME_FOR_NEW_CONFIG, - "Using core name for new config.") -MSG_HASH(MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED, - "Using libretro dummy core. Skipping recording.") -MSG_HASH(MSG_VALUE_CONNECT_DEVICE_FROM_A_VALID_PORT, - "Connect device from a valid port.") -MSG_HASH(MSG_VALUE_DISCONNECTING_DEVICE_FROM_PORT, - "Disconnecting device from port") -MSG_HASH(MSG_VALUE_REBOOTING, - "Rebooting...") -MSG_HASH(MSG_VALUE_SHUTTING_DOWN, - "Shutting down...") -MSG_HASH(MSG_VERSION_OF_LIBRETRO_API, - "Version of libretro API") -MSG_HASH(MSG_VIEWPORT_SIZE_CALCULATION_FAILED, - "Viewport size calculation failed! Will continue using raw data. This will probably not work right ...") -MSG_HASH(MSG_VIRTUAL_DISK_TRAY, - "virtual disk tray.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_LATENCY, - "Desired audio latency in milliseconds. Might not be honored if the audio driver can't provide given latency.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MUTE, - "Mute/unmute audio.") -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, - "Helps smooth out imperfections in timing when synchronizing audio and video. Be aware that if disabled, proper synchronization is nearly impossible to obtain." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_CAMERA_ALLOW, - "Allow or disallow camera access by cores." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_LOCATION_ALLOW, - "Allow or disallow location services access by cores." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_MAX_USERS, - "Maximum amount of users supported by RetroArch." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_POLL_TYPE_BEHAVIOR, - "Influence how input polling is done inside RetroArch. Setting it to 'Early' or 'Late' can result in less latency, depending on your configuration." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_ALL_USERS_CONTROL_MENU, - "Allows any user to control the menu. If disabled, only User 1 can control the menu." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_VOLUME, - "Audio volume (in dB). 0 dB is normal volume, and no gain is applied." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_WASAPI_EXCLUSIVE_MODE, - "Allow the WASAPI driver to take exclusive control of the audio device. If disabled, it will use shared mode instead." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_WASAPI_FLOAT_FORMAT, - "Use float format for the WASAPI driver, if supported by your audio device." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_WASAPI_SH_BUFFER_LENGTH, - "The intermediate buffer length (in frames) when using the WASAPI driver in shared mode." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_SYNC, - "Synchronize audio. Recommended." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "How far an axis must be tilted to result in a button press." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, - "Amount of seconds to wait until proceeding to the next bind." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_BIND_HOLD, - "Amount of seconds to hold an input to bind it." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_TURBO_PERIOD, - "Describes the period when turbo-enabled buttons are toggled. Numbers are described in frames." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_DUTY_CYCLE, - "Describes how long the period of a turbo-enabled button should be. Numbers are described in frames." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_VSYNC, - "Synchronizes the output video of the graphics card to the refresh rate of the screen. Recommended." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_ALLOW_ROTATE, - "Allow cores to set rotation. When disabled, rotation requests are ignored. Useful for setups where one manually rotates the screen." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_DUMMY_ON_CORE_SHUTDOWN, - "Some cores might have a shutdown feature. If enabled, it will prevent the core from shutting RetroArch down. Instead, it loads a dummy core." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_CHECK_FOR_MISSING_FIRMWARE, - "Check if all the required firmware is present before attempting to load content." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE, - "Vertical refresh rate of your screen. Used to calculate a suitable audio input rate. NOTE: This will be ignored if 'Threaded Video' is enabled." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_ENABLE, - "Enable audio output." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_MAX_TIMING_SKEW, - "The maximum change in audio input rate. Increasing this enables very large changes in timing at the cost of an inaccurate audio pitch (e.g., running PAL cores on NTSC displays)." - ) -MSG_HASH( - MSG_FAILED, - "failed" - ) -MSG_HASH( - MSG_SUCCEEDED, - "succeeded" - ) -MSG_HASH( - MSG_DEVICE_NOT_CONFIGURED, - "not configured" - ) -MSG_HASH( - MSG_DEVICE_NOT_CONFIGURED_FALLBACK, - "not configured, using fallback" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, - "Database Cursor List" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DEVELOPER, - "Database - Filter : Developer" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PUBLISHER, - "Database - Filter : Publisher" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DISABLED, - "Disabled" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ENABLED, - "Enabled" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_PATH, - "Content History Path" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ORIGIN, - "Database - Filter : Origin") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_FRANCHISE, - "Database - Filter : Franchise") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ESRB_RATING, - "Database - Filter : ESRB Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ELSPA_RATING, - "Database - Filter : ELSPA Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PEGI_RATING, - "Database - Filter : PEGI Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_CERO_RATING, - "Database - Filter : CERO Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_BBFC_RATING, - "Database - Filter : BBFC Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_MAX_USERS, - "Database - Filter : Max Users") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_MONTH, - "Database - Filter : Releasedate By Month") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_YEAR, - "Database - Filter : Releasedate By Year") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_ISSUE, - "Database - Filter : Edge Magazine Issue") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_RATING, - "Database - Filter : Edge Magazine Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DATABASE_INFO, - "Database Info") -MSG_HASH(MSG_WIFI_SCAN_COMPLETE, - "Wi-Fi scan complete.") -MSG_HASH(MSG_SCANNING_WIRELESS_NETWORKS, - "Scanning wireless networks...") -MSG_HASH(MSG_NETPLAY_LAN_SCAN_COMPLETE, - "Netplay scan complete.") -MSG_HASH(MSG_NETPLAY_LAN_SCANNING, - "Scanning for netplay hosts...") -MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, - "Pause gameplay when RetroArch is not the active window.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, - "Enable or disable composition.") -MSG_HASH(MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, - "Enable or disable recent playlist for games, images, music, and videos.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, - "Limit the number of entries in recent playlist for games, images, music, and videos.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_UNIFIED_MENU_CONTROLS, - "Unified Menu Controls") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS, - "Use the same controls for both the menu and the game. Applies to the keyboard.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE, - "Show onscreen messages.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_USER_REMOTE_ENABLE, - "User %d Remote Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, - "Show battery level") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, - "Select File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Select From Collection") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, - "Filter") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, - "Scale") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED, - "Netplay will start when content is loaded.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LOAD_CONTENT_MANUALLY, - "Couldn't find a suitable core or content file, load manually.") -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_URL_LIST, - "Browse URL" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_URL, - "URL Path" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_START, - "Start" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, - "Bokeh") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOWFLAKE, - "Snowflake") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_ROOMS, - "Refresh Room List") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME, - "Nickname: %s") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME_LAN, - "Nickname (lan): %s") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND, - "Compatible content found") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_CROP_OVERSCAN, - "Cuts off a few pixels around the edges of the image customarily left blank by developers which sometimes also contain garbage pixels.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SMOOTH, - "Adds a slight blur to the image to take the edge off of the hard pixel edges. This option has very little impact on performance.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FILTER, - "Apply a CPU-powered video filter. NOTE: Might come at a high performance cost. Some video filters might only work for cores that use 32bit or 16bit color.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_USERNAME, - "Input the username of your RetroAchievements account.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_PASSWORD, - "Input the password of your RetroAchievements account.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_NICKNAME, - "Input your user name here. This will be used for netplay sessions, among other things.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_POST_FILTER_RECORD, - "Capture the image after filters (but not shaders) are applied. Your video will look as fancy as what you see on your screen.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_LIST, - "Select which core to use.") -MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_CONTENT_LIST, - "Select which content to start.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_INFORMATION, - "Show network interface(s) and associated IP addresses.") -MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_INFORMATION, - "Show information specific to the device.") -MSG_HASH(MENU_ENUM_SUBLABEL_QUIT_RETROARCH, - "Quit the program.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_WINDOW_WIDTH, - "Set the custom width size for the display window. Leaving it at 0 will attempt to scale the window as large as possible.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_WINDOW_HEIGHT, - "Set the custom height size for the display window. Leaving it at 0 will attempt to scale the window as large as possible.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_X, - "Set the custom width size for the non-windowed fullscreen mode. Leaving it at 0 will use the desktop resolution.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_Y, - "Set the custom height size for the non-windowed fullscreen mode. Leaving it at 0 will use the desktop resolution") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_X, - "Specify custom X axis position for onscreen text.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_Y, - "Specify custom Y axis position for onscreen text.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, - "Specify the font size in points.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, - "Hide the overlay while inside the menu, and show it again when exiting the menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, - "Show keyboard/controller inputs on the onscreen overlay.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, - "Select the port for the overlay to listen to if Show Inputs On Overlay is enabled.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, - "Scanned content will appear here." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, - "Only scales video in integer steps. The base size depends on system-reported geometry and aspect ratio. If 'Force Aspect' is not set, X/Y will be integer scaled independently." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT, - "Screenshots output of GPU shaded material if available." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_ROTATION, - "Forces a certain rotation of the screen. The rotation is added to rotations which the core sets." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FORCE_SRGB_DISABLE, - "Forcibly disable sRGB FBO support. Some Intel OpenGL drivers on Windows have video problems with sRGB FBO support if this is enabled. Enabling this can work around it." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN, - "Start in fullscreen. Can be changed at runtime. Can be overridden by a command line switch" - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_WINDOWED_FULLSCREEN, - "If fullscreen, prefer using a windowed fullscreen mode." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_GPU_RECORD, - "Records output of GPU shaded material if available." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX, - "When making a savestate, save state index is automatically increased before it is saved. When loading content, the index will be set to the highest existing index." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE, - "Block Save RAM from being overwritten when loading save states. Might potentially lead to buggy games." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO, - "The maximum rate at which content will be run when using fast forward (e.g., 5.0x for 60 fps content = 300 fps cap). If set to 0.0x, fastforward ratio is unlimited (no FPS cap)." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, - "When in slow motion, content will slow down by the factor specified/set." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_RUN_AHEAD_ENABLED, - "Run core logic one or more frames ahead then load the state back to reduce perceived input lag." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_RUN_AHEAD_FRAMES, - "The number of frames to run ahead. Causes gameplay issues such as jitter if you exceed the number of lag frames internal to the game." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_RUN_AHEAD_SECONDARY_INSTANCE, - "Use a second instance of the RetroArch core to run ahead. Prevents audio problems due to loading state." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_RUN_AHEAD_HIDE_WARNINGS, - "Hides the warning message that appears when using RunAhead and the core does not support savestates." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_REWIND_ENABLE, - "Enable rewinding. This will take a performance hit when playing." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_APPLY_AFTER_TOGGLE, - "Apply cheat immediately after toggling." + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD_APPEND, + "Load Cheat File (Append)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, + "Save Cheat File As" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, + "Cheat Passes" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION, + "Description" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, + "Hardcore Mode" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_ENABLE, + "Leaderboards" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_BADGES_ENABLE, + "Achievement Badges" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, + "Locked Achievements:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY, + "Locked" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS, + "RetroAchievements" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL, + "Test Unofficial Achievements" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS, + "Unlocked Achievements:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY, + "Unlocked" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY_HARDCORE, + "Hardcore" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_VERBOSE_ENABLE, + "Verbose Mode" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_AUTO_SCREENSHOT, + "Automatic Screenshot" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, + "Close Content" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIG, + "Config" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIGURATIONS, + "Load Configuration" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS, + "Configuration" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, + "Save Configuration on Exit" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, + "Collections" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, + "Database" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_DIR, + "Content" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, + "History List Size" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_REMOVE, + "Allow to remove entries" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS, + "Quick Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIR, + "Downloads" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIRECTORY, + "Downloads" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS, + "Cheats" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_COUNTERS, + "Core Counters" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_ENABLE, + "Show core name" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFORMATION, + "Core Information" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_AUTHORS, + "Authors" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_CATEGORIES, + "Categories" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_LABEL, + "Core label" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_NAME, + "Core name" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE, + "Firmware(s)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES, + "License(s)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_PERMISSIONS, + "Permissions" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_SUPPORTED_EXTENSIONS, + "Supported extensions" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_MANUFACTURER, + "System manufacturer" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_NAME, + "System name" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS, + "Controls" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_LIST, + "Load Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, + "Options" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_SETTINGS, + "Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, + "Start a Core Automatically" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, + "Automatically extract downloaded archive" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_UPDATER_BUILDBOT_URL, + "Buildbot Cores URL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST, + "Core Updater" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SETTINGS, + "Updater" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CPU_ARCHITECTURE, + "CPU Architecture:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CPU_CORES, + "CPU Cores:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CURSOR_DIRECTORY, + "Cursor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CURSOR_MANAGER, + "Cursor Manager" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CUSTOM_RATIO, + "Custom Ratio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_MANAGER, + "Database Manager" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_SELECTION, + "Database Selection" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DELETE_ENTRY, + "Remove" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FAVORITES, + "Start directory" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DIRECTORY_CONTENT, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DIRECTORY_DEFAULT, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DIRECTORY_NONE, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, + "Directory not found." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS, + "Directory" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISK_CYCLE_TRAY_STATUS, + "Disk Cycle Tray Status" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND, + "Disk Image Append" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISK_INDEX, + "Disk Index" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISK_OPTIONS, + "Disk Control" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DONT_CARE, + "Don't care" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST, + "Downloads" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE, + "Download Core..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT, + "Content Downloader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_ENABLE, + "DPI Override Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE, + "DPI Override" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS, + "Driver" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN, + "Load Dummy on Core Shutdown" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHECK_FOR_MISSING_FIRMWARE, + "Check for Missing Firmware Before Loading" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER, + "Dynamic Background" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY, + "Dynamic Backgrounds" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE, + "Enable Achievements" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR, + "Menu entry hover color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ENTRY_NORMAL_COLOR, + "Menu entry normal color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FALSE, + "False" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FASTFORWARD_RATIO, + "Maximum Run Speed" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FAVORITES_TAB, + "Favorites" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FPS_SHOW, + "Display Framerate" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE, + "Limit Maximum Run Speed" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VRR_RUNLOOP_ENABLE, + "Sync to Exact Content Framerate (G-Sync, FreeSync)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, + "Frame Throttle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, + "Frontend Counters" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, + "Load Content-Specific Core Options Automatically" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE, + "Create game-options file" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE, + "Save Game-options file" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP, + "Help" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING, + "Audio/Video Troubleshooting" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD, + "Changing Virtual Gamepad Overlay" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_CONTROLS, + "Basic Menu Controls" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_LIST, + "Help" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_LOADING_CONTENT, + "Loading Content" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT, + "Scanning For Content" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_WHAT_IS_A_CORE, + "What Is A Core?" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HISTORY_LIST_ENABLE, + "History List Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HISTORY_TAB, + "History" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, + "Horizontal Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_IMAGES_TAB, + "Image" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INFORMATION, + "Information" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INFORMATION_LIST, + "Information" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ADC_TYPE, + "Analog To Digital Type" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ALL_USERS_CONTROL_MENU, + "All Users Control Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X, + "Left Analog X" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_MINUS, + "Left analog X- (left)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_PLUS, + "Left analog X+ (right)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y, + "Left Analog Y" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_MINUS, + "Left analog Y- (up)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_PLUS, + "Left analog Y+ (down)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X, + "Right Analog X" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_MINUS, + "Right analog X- (left)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_PLUS, + "Right analog X+ (right)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y, + "Right Analog Y" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS, + "Right analog Y- (up)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS, + "Right analog Y+ (down)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_TRIGGER, + "Gun Trigger" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_RELOAD, + "Gun Reload" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_A, + "Gun Aux A" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_B, + "Gun Aux B" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_C, + "Gun Aux C" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_START, + "Gun Start" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_SELECT, + "Gun Select" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_UP, + "Gun D-pad Up" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_DOWN, + "Gun D-pad Down" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT, + "Gun D-pad Left" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, + "Gun D-pad Right" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, + "Autoconfig Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, + "Analog Stick Deadzone" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, + "Menu Swap OK & Cancel Buttons" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, + "Bind All" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL, + "Bind Default All" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_BIND_TIMEOUT, + "Bind Timeout" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_BIND_HOLD, + "Bind Hold" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_HIDE_UNBOUND, + "Hide Unbound Core Input Descriptors" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_LABEL_SHOW, + "Display Input Descriptor Labels" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX, + "Device Index" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_TYPE, + "Device Type" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_INDEX, + "Mouse Index" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_DRIVER, + "Input Driver" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_DUTY_CYCLE, + "Duty Cycle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS, + "Input Hotkey Binds" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE, + "Keyboard Gamepad Mapping Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_A, + "A button (right)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, + "B button (down)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_DOWN, + "Down D-pad" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L2, + "L2 button (trigger)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L3, + "L3 button (thumb)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L, + "L button (shoulder)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT, + "Left D-pad" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R2, + "R2 button (trigger)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R3, + "R3 button (thumb)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R, + "R button (shoulder)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_RIGHT, + "Right D-pad" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, + "Select button" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, + "Start button" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_UP, + "Up D-pad" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X, + "X button (top)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, + "Y button (left)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_KEY, + "(Key: %s)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_LEFT, + "Mouse 1" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_RIGHT, + "Mouse 2" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_MIDDLE, + "Mouse 3" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON4, + "Mouse 4" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON5, + "Mouse 5" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_UP, + "Wheel Up" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_DOWN, + "Wheel Down" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_UP, + "Wheel Left" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_DOWN, + "Wheel Right" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, + "Keyboard Gamepad Mapping Type" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MAX_USERS, + "Max Users" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, + "Menu Toggle Gamepad Combo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS, + "Cheat index -" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS, + "Cheat index +" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE, + "Cheat toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE, + "Disk eject toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT, + "Disk next" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, + "Disk prev" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, + "Enable hotkeys" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY, + "Fast forward hold" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY, + "Fast forward toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, + "Frameadvance" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, + "Fullscreen toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, + "Grab mouse toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, + "Game focus toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE, + "Desktop menu toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, + "Load state" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, + "Menu toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE, + "Movie record toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, + "Audio mute toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, + "Netplay toggle play/spectate mode" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, + "On-screen keyboard toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, + "Overlay next" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE, + "Pause toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, + "Quit RetroArch" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, + "Reset game" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, + "Rewind" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_DETAILS, + "Cheat Details" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_SEARCH, + "Start or Continue Cheat Search" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, + "Save state" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, + "Take screenshot" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, + "Next shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, + "Previous shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_HOLD_KEY, + "Slow motion hold" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_KEY, + "Slow motion toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, + "Savestate slot -" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, + "Savestate slot +" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, + "Volume -" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, + "Volume +" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_ENABLE, + "Display Overlay" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU, + "Hide Overlay In Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, + "Show Inputs On Overlay" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, + "Show Inputs Listen Port" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR, + "Poll Type Behavior" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_EARLY, + "Early" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_LATE, + "Late" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_NORMAL, + "Normal" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_PREFER_FRONT_TOUCH, + "Prefer Front Touch" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_REMAPPING_DIRECTORY, + "Input Remapping" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_REMAP_BINDS_ENABLE, + "Remap Binds Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_SAVE_AUTOCONFIG, + "Save Autoconfig" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS, + "Input" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE, + "Small Keyboard Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_TOUCH_ENABLE, + "Touch Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE, + "Turbo enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, + "Turbo Period" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_USER_BINDS, + "Input User %u Binds" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LATENCY_SETTINGS, + "Latency" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INTERNAL_STORAGE_STATUS, + "Internal storage status" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_JOYPAD_AUTOCONFIG_DIR, + "Input Autoconfig" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_JOYPAD_DRIVER, + "Joypad Driver" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LAKKA_SERVICES, + "Services" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_CHINESE_SIMPLIFIED, + "Chinese (Simplified)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_CHINESE_TRADITIONAL, + "Chinese (Traditional)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_DUTCH, + "Dutch" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_ENGLISH, + "English" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_ESPERANTO, + "Esperanto" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_FRENCH, + "French" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_GERMAN, + "German" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_ITALIAN, + "Italian" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_JAPANESE, + "Japanese" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_KOREAN, + "Korean" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_POLISH, + "Polish" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_BRAZIL, + "Portuguese (Brazil)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_PORTUGAL, + "Portuguese (Portugal)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_RUSSIAN, + "Russian" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_SPANISH, + "Spanish" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_VIETNAMESE, + "Vietnamese" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LANG_ARABIC, + "Arabic" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LEFT_ANALOG, + "Left Analog" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH, + "Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LIBRETRO_INFO_PATH, + "Core Info" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LIBRETRO_LOG_LEVEL, + "Core Logging Level" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LINEAR, + "Linear" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOAD_ARCHIVE, + "Load Archive" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY, + "Load Recent" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST, + "Load Content" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOAD_STATE, + "Load State" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOCATION_ALLOW, + "Allow Location" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOCATION_DRIVER, + "Location Driver" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS, + "Logging" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LOG_VERBOSITY, + "Logging Verbosity" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MAIN_MENU, + "Main Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MANAGEMENT, + "Database Settings" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME, + "Menu Color Theme" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE, + "Blue" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE_GREY, + "Blue Grey" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_DARK_BLUE, + "Dark Blue" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_GREEN, + "Green" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_NVIDIA_SHIELD, + "Shield" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_RED, + "Red" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_YELLOW, + "Yellow" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_FOOTER_OPACITY, + "Footer Opacity" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_HEADER_OPACITY, + "Header Opacity" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_DRIVER, + "Menu Driver" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE, + "Throttle Menu Framerate" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_FILE_BROWSER_SETTINGS, + "Settings" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, + "Menu Linear Filter" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_HORIZONTAL_ANIMATION, + "Horizontal Animation" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, + "Appearance" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER, + "Background" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY, + "Background opacity" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MISSING, + "Missing" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MORE, + "..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MOUSE_ENABLE, + "Mouse Support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MULTIMEDIA_SETTINGS, + "Multimedia" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MUSIC_TAB, + "Music" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, + "Filter unknown extensions" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NAVIGATION_WRAPAROUND, + "Navigation Wrap-Around" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NEAREST, + "Nearest" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY, + "Netplay" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_ALLOW_SLAVES, + "Allow Slave-Mode Clients" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, + "Netplay Check Frames" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN, + "Input Latency Frames" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, + "Input Latency Frames Range" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES, + "Netplay Delay Frames" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT, + "Disconnect from netplay host" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE, + "Netplay Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT, + "Connect to netplay host" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_HOST, + "Start netplay host" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_DISABLE_HOST, + "Stop netplay host" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS, + "Server Address" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_LAN_SCAN_SETTINGS, + "Scan local network" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, + "Netplay Client Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, + "Username" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, + "Server Password" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE, + "Publicly Announce Netplay" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_REQUEST_DEVICE_I, + "Request Device %u" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_REQUIRE_SLAVES, + "Disallow Non-Slave-Mode Clients" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, + "Netplay settings" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG, + "Analog Input Sharing" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_MAX, + "Max" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_AVERAGE, + "Average" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL, + "Digital Input Sharing" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_OR, + "Share" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_XOR, + "Grapple" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_VOTE, + "Vote" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NONE, + "None" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NO_PREFERENCE, + "No preference" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_START_AS_SPECTATOR, + "Netplay Spectator Mode" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, + "Netplay Stateless Mode" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, + "Server Spectate-Only Password" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, + "Netplay Spectator Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, + "Netplay TCP Port" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, + "Netplay NAT Traversal" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_CMD_ENABLE, + "Network Commands" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT, + "Network Command Port" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_INFORMATION, + "Network Information" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_ENABLE, + "Network Gamepad" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_PORT, + "Network Remote Base Port" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_SETTINGS, + "Network" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO, + "No" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NONE, + "None" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE, + "N/A" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_ACHIEVEMENTS_TO_DISPLAY, + "No achievements to display." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_CORE, + "No Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_CORES_AVAILABLE, + "No cores available." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_CORE_INFORMATION_AVAILABLE, + "No core information available." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_CORE_OPTIONS_AVAILABLE, + "No core options available." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY, + "No entries to display." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_HISTORY_AVAILABLE, + "No history available." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE, + "No information is available." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_ITEMS, + "No items." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_NETPLAY_HOSTS_FOUND, + "No netplay hosts found." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, + "No networks found." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, + "No performance counters." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, + "No playlists." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_PLAYLIST_ENTRIES_AVAILABLE, + "No playlist entries available." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, + "No settings found." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, + "No shader parameters." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OFF, + "OFF" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ON, + "ON" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ONLINE, + "Online" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER, + "Online Updater" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS, + "Onscreen Display" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS, + "Onscreen Overlay" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ONSCREEN_OVERLAY_SETTINGS, + "Adjust Bezels and Onscreen controls" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS, + "Onscreen Notifications" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ONSCREEN_NOTIFICATIONS_SETTINGS, + "Adjust the Onscreen Notifications" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OPEN_ARCHIVE, + "Browse Archive" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OPTIONAL, + "Optional" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY, + "Overlay" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED, + "Autoload Preferred Overlay" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY_DIRECTORY, + "Overlay" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY_OPACITY, + "Overlay Opacity" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY_PRESET, + "Overlay Preset" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY_SCALE, + "Overlay Scale" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS, + "Onscreen Overlay" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PAL60_ENABLE, + "Use PAL60 Mode" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY, + "Parent directory" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PAUSE_LIBRETRO, + "Pause when menu activated" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, + "Don't run in background" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, + "Performance Counters" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, + "Playlists" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, + "Playlist" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, + "Playlists" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, + "Touch Support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PORT, + "Port" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PRESENT, + "Present" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PRIVACY_SETTINGS, + "Privacy" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_SETTINGS, + "MIDI" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH, + "Quit RetroArch" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ANALOG, + "Analog supported" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_BBFC_RATING, + "BBFC Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CERO_RATING, + "CERO Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_COOP, + "Co-op supported" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CRC32, + "CRC32" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DESCRIPTION, + "Description" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DEVELOPER, + "Developer" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_ISSUE, + "Edge Magazine Issue" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_RATING, + "Edge Magazine Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_REVIEW, + "Edge Magazine Review" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ELSPA_RATING, + "ELSPA Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ENHANCEMENT_HW, + "Enhancement Hardware" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ESRB_RATING, + "ESRB Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FAMITSU_MAGAZINE_RATING, + "Famitsu Magazine Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FRANCHISE, + "Franchise" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_GENRE, + "Genre" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_MD5, + "MD5" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME, + "Name" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ORIGIN, + "Origin" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PEGI_RATING, + "PEGI Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PUBLISHER, + "Publisher" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_MONTH, + "Releasedate Month" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_YEAR, + "Releasedate Year" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RUMBLE, + "Rumble supported" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SERIAL, + "Serial" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SHA1, + "SHA1" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_START_CONTENT, + "Start Content" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, + "TGDB Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REBOOT, + "Reboot" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY, + "Recording Config" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORDING_OUTPUT_DIRECTORY, + "Recording Output" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, + "Recording" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, + "Load Recording Config..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORD_DRIVER, + "Record Driver" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_DRIVER, + "MIDI Driver" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORD_ENABLE, + "Enable Recording" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORD_PATH, + "Save Output Recording as..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RECORD_USE_OUTPUT_DIRECTORY, + "Save Recordings in Output Dir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE, + "Remap File" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_LOAD, + "Load Remap File" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CORE, + "Save Core Remap File" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CONTENT_DIR, + "Save Content Directory Remap File" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_GAME, + "Save Game Remap File" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CORE, + "Delete Core Remap File" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_GAME, + "Delete Game Remap File" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CONTENT_DIR, + "Delete Game Content Directory Remap File" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REQUIRED, + "Required" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RESTART_CONTENT, + "Restart" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH, + "Restart RetroArch" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RESUME, + "Resume" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RESUME_CONTENT, + "Resume" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RETROKEYBOARD, + "RetroKeyboard" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RETROPAD, + "RetroPad" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RETROPAD_WITH_ANALOG, + "RetroPad w/ Analog" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS, + "Achievements" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REWIND_ENABLE, + "Rewind Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_AFTER_TOGGLE, + "Apply After Toggle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_AFTER_LOAD, + "Auto-Apply Cheats During Game Load" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REWIND_GRANULARITY, + "Rewind Granularity" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE, + "Rewind Buffer Size (MB)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE_STEP, + "Rewind Buffer Size Step (MB)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS, + "Rewind" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SETTINGS, + "Cheat Settings" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DETAILS_SETTINGS, + "Cheat Details" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_SETTINGS, + "Start or Continue Cheat Search" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY, + "File Browser" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY, + "Config" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN, + "Display Start Screen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG, + "Right Analog" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES, + "Add to Favorites" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST, + "Add to Favorites" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RESET_CORE_ASSOCIATION, + "Reset Core Association" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUN, + "Run" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUN_MUSIC, + "Run" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAMBA_ENABLE, + "SAMBA Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVEFILE_DIRECTORY, + "Savefile" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX, + "Save State Auto Index" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD, + "Auto Load State" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE, + "Auto Save State" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATE_DIRECTORY, + "Savestate" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE, + "Savestate Thumbnails" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG, + "Save Current Configuration" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, + "Save Core Overrides" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, + "Save Content Directory Overrides" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, + "Save Game Overrides" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVE_NEW_CONFIG, + "Save New Configuration" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVE_STATE, + "Save State" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS, + "Saving" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY, + "Scan Directory" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCAN_FILE, + "Scan File" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCREENSHOT_DIRECTORY, + "Screenshot" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION, + "Screen Resolution" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SEARCH, + "Search" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SECONDS, + "seconds" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SETTINGS, + "Settings" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SETTINGS_TAB, + "Settings" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER, + "Shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_APPLY_CHANGES, + "Apply Changes" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS, + "Shaders" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON, + "Ribbon" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON_SIMPLIFIED, + "Ribbon (simplified)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SIMPLE_SNOW, + "Simple Snow" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOW, + "Snow" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHOW_ADVANCED_SETTINGS, + "Show Advanced Settings" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHOW_HIDDEN_FILES, + "Show Hidden Files and Folders" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHUTDOWN, + "Shutdown" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO, + "Slow-Motion Ratio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_ENABLED, + "Run-Ahead to Reduce Latency" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_FRAMES, + "Number of Frames to Run Ahead" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_SECONDARY_INSTANCE, + "RunAhead Use Second Instance" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_HIDE_WARNINGS, + "RunAhead Hide Warnings" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SORT_SAVEFILES_ENABLE, + "Sort Saves In Folders" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SORT_SAVESTATES_ENABLE, + "Sort Savestates In Folders" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATES_IN_CONTENT_DIR_ENABLE, + "Write Savestates to Content Dir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVEFILES_IN_CONTENT_DIR_ENABLE, + "Write Saves to Content Dir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEMFILES_IN_CONTENT_DIR_ENABLE, + "System Files are in Content Dir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCREENSHOTS_IN_CONTENT_DIR_ENABLE, + "Write Screenshots to Content Dir" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SSH_ENABLE, + "SSH Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_START_CORE, + "Start Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_START_NET_RETROPAD, + "Start Remote RetroPad" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_START_VIDEO_PROCESSOR, + "Start Video Processor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_STATE_SLOT, + "State Slot" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_STATUS, + "Status" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_STDIN_CMD_ENABLE, + "stdin Commands" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES, + "Suggested cores" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SUSPEND_SCREENSAVER_ENABLE, + "Suspend Screensaver" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_BGM_ENABLE, + "System BGM Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_DIRECTORY, + "System/BIOS" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFORMATION, + "System Information" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_7ZIP_SUPPORT, + "7zip support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ALSA_SUPPORT, + "ALSA support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_BUILD_DATE, + "Build date" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CG_SUPPORT, + "Cg support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COCOA_SUPPORT, + "Cocoa support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COMMAND_IFACE_SUPPORT, + "Command interface support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CORETEXT_SUPPORT, + "CoreText support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CPU_FEATURES, + "CPU Features" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_DPI, + "Display metric DPI" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_HEIGHT, + "Display metric height (mm)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_WIDTH, + "Display metric width (mm)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DSOUND_SUPPORT, + "DirectSound support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WASAPI_SUPPORT, + "WASAPI support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYLIB_SUPPORT, + "Dynamic library support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYNAMIC_SUPPORT, + "Dynamic run-time loading of libretro library" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_EGL_SUPPORT, + "EGL support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FBO_SUPPORT, + "OpenGL/Direct3D render-to-texture (multi-pass shaders) support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FFMPEG_SUPPORT, + "FFmpeg support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FREETYPE_SUPPORT, + "FreeType support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_IDENTIFIER, + "Frontend identifier" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_NAME, + "Frontend name" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_OS, + "Frontend OS" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GIT_VERSION, + "Git version" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GLSL_SUPPORT, + "GLSL support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_HLSL_SUPPORT, + "HLSL support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_JACK_SUPPORT, + "JACK support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_KMS_SUPPORT, + "KMS/EGL support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LAKKA_VERSION, + "Lakka Version" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, + "LibretroDB support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, + "Libusb support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, + "libxml2 XML parsing support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, + "Netplay (peer-to-peer) support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, + "Network Command interface support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_REMOTE_SUPPORT, + "Network Gamepad support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENAL_SUPPORT, + "OpenAL support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGLES_SUPPORT, + "OpenGL ES support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGL_SUPPORT, + "OpenGL support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENSL_SUPPORT, + "OpenSL support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENVG_SUPPORT, + "OpenVG support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OSS_SUPPORT, + "OSS support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OVERLAY_SUPPORT, + "Overlay support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE, + "Power source" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGED, + "Charged" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGING, + "Charging" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_DISCHARGING, + "Discharging" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_NO_SOURCE, + "No source" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PULSEAUDIO_SUPPORT, + "PulseAudio support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PYTHON_SUPPORT, + "Python (script support in shaders) support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RBMP_SUPPORT, + "BMP support (RBMP)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RETRORATING_LEVEL, + "RetroRating level" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RJPEG_SUPPORT, + "JPEG support (RJPEG)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ROARAUDIO_SUPPORT, + "RoarAudio support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RPNG_SUPPORT, + "PNG support (RPNG)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RSOUND_SUPPORT, + "RSound support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RTGA_SUPPORT, + "TGA support (RTGA)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL2_SUPPORT, + "SDL2 support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_IMAGE_SUPPORT, + "SDL image support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_SUPPORT, + "SDL1.2 support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SLANG_SUPPORT, + "Slang support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_THREADING_SUPPORT, + "Threading support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_UDEV_SUPPORT, + "Udev support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_V4L2_SUPPORT, + "Video4Linux2 support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VIDEO_CONTEXT_DRIVER, + "Video context driver" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VULKAN_SUPPORT, + "Vulkan support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_METAL_SUPPORT, + "Metal support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WAYLAND_SUPPORT, + "Wayland support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_X11_SUPPORT, + "X11 support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XAUDIO2_SUPPORT, + "XAudio2 support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XVIDEO_SUPPORT, + "XVideo support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ZLIB_SUPPORT, + "Zlib support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT, + "Take Screenshot" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, + "Threaded tasks" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAILS, + "Thumbnails" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS, + "Left Thumbnails" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS, + "Thumbnails Vertical Disposition" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, + "Thumbnails" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST, + "Thumbnails Updater" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS, + "Boxarts" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS, + "Screenshots" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS, + "Title Screens" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TIMEDATE_ENABLE, + "Show date / time" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TITLE_COLOR, + "Menu title color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TRUE, + "True" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UI_COMPANION_ENABLE, + "UI Companion Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UI_COMPANION_START_ON_BOOT, + "UI Companion Start On Boot" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UI_COMPANION_TOGGLE, + "Show desktop menu on startup" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DESKTOP_MENU_ENABLE, + "Enable desktop menu (restart)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UI_MENUBAR_ENABLE, + "Menubar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE, + "Unable to read compressed file." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UNDO_LOAD_STATE, + "Undo Load State" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UNDO_SAVE_STATE, + "Undo Save State" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UNKNOWN, + "Unknown" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS, + "Updater" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_ASSETS, + "Update Assets" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_AUTOCONFIG_PROFILES, + "Update Joypad Profiles" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_CG_SHADERS, + "Update Cg Shaders" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_CHEATS, + "Update Cheats" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_CORE_INFO_FILES, + "Update Core Info Files" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_DATABASES, + "Update Databases" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_GLSL_SHADERS, + "Update GLSL Shaders" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_LAKKA, + "Update Lakka" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_OVERLAYS, + "Update Overlays" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_UPDATE_SLANG_SHADERS, + "Update Slang Shaders" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USER, + "User" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_KEYBOARD, + "Kbd" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS, + "User Interface" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USER_LANGUAGE, + "Language" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USER_SETTINGS, + "User" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER, + "Use Builtin Image Viewer" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USE_BUILTIN_PLAYER, + "Use Builtin Media Player" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_ALLOW_ROTATE, + "Allow rotation" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO, + "Config Aspect Ratio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_AUTO, + "Auto Aspect Ratio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, + "Aspect Ratio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, + "Black Frame Insertion" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, + "Crop Overscan (Reload)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, + "Disable Desktop Composition" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, + "Video Driver" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, + "Video Filter" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_DIR, + "Video Filter" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_FLICKER, + "Flicker filter" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FONT_ENABLE, + "Enable Onscreen Notifications" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FONT_PATH, + "Notification Font" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FONT_SIZE, + "Notification Size" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_ASPECT, + "Force aspect ratio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_SRGB_DISABLE, + "Force-disable sRGB FBO" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FRAME_DELAY, + "Frame Delay" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN, + "Start in Fullscreen Mode" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_GAMMA, + "Video Gamma" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_GPU_RECORD, + "Use GPU Recording" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT, + "GPU Screenshot Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, + "Hard GPU Sync" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES, + "Hard GPU Sync Frames" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES, + "Max swapchain images" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_X, + "Notification X Position" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_Y, + "Notification Y Position" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MONITOR_INDEX, + "Monitor Index" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_POST_FILTER_RECORD, + "Use Post Filter Recording" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, + "Vertical Refresh Rate" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, + "Estimated Screen Framerate" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, + "Rotation" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, + "Windowed Scale" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER, + "Integer Scale" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS, + "Video" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DIR, + "Video Shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_NUM_PASSES, + "Shader Passes" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS, + "Shader Parameters" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET, + "Load Shader Preset" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS, + "Save Shader Preset As" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE, + "Save Core Preset" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_PARENT, + "Save Content Directory Preset" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME, + "Save Game Preset" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT, + "Enable Hardware Shared Context" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH, + "Bilinear Filtering" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER, + "Soft Filter Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_SWAP_INTERVAL, + "Vertical Sync (Vsync) Swap Interval" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_TAB, + "Video" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_THREADED, + "Threaded Video" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VFILTER, + "Deflicker" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_HEIGHT, + "Custom Aspect Ratio Height" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_WIDTH, + "Custom Aspect Ratio Width" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X, + "Custom Aspect Ratio X Pos." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_Y, + "Custom Aspect Ratio Y Pos." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, + "Set VI Screen Width" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, + "Vertical Sync (Vsync)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, + "Windowed Fullscreen Mode" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_WIDTH, + "Window Width" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_HEIGHT, + "Window Height" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_X, + "Fullscreen Width" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_Y, + "Fullscreen Height" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_WIFI_DRIVER, + "Wi-Fi Driver" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, + "Wi-Fi" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, + "Menu Alpha Factor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_RED, + "Menu Font Red Color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_GREEN, + "Menu Font Green Color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_FONT_COLOR_BLUE, + "Menu Font Blue Color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_FONT, + "Menu Font" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, + "Custom" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_FLATUI, + "FlatUI" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME, + "Monochrome" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME_INVERTED, + "Monochrome Inverted" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_SYSTEMATIC, + "Systematic" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_NEOACTIVE, + "NeoActive" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL, + "Pixel" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE, + "RetroActive" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM, + "Retrosystem" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART, + "Dot-Art" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_AUTOMATIC, + "Automatic" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME, + "Menu Color Theme" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_APPLE_GREEN, + "Apple Green" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK, + "Dark" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LIGHT, + "Light" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MORNING_BLUE, + "Morning Blue" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK_PURPLE, + "Dark Purple" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_ELECTRIC_BLUE, + "Electric Blue" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_GOLDEN, + "Golden" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LEGACY_RED, + "Legacy Red" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MIDNIGHT_BLUE, + "Midnight Blue" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_PLAIN, + "Plain" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_UNDERSEA, + "Undersea" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_VOLCANIC_RED, + "Volcanic Red" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_RIBBON_ENABLE, + "Menu Shader Pipeline" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_SCALE_FACTOR, + "Menu Scale Factor" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE, + "Icon Shadows Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_HISTORY, + "Show History Tab" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_ADD, + "Show Import content Tab" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_PLAYLISTS, + "Show Playlist Tabs" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_FAVORITES, + "Show Favorites Tab" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_IMAGES, + "Show Image Tab" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_MUSIC, + "Show Music Tab" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, + "Show Settings Tab" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, + "Show Video Tab" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, + "Show Netplay Tab" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "Menu Layout" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_THEME, + "Menu Icon Theme" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_YES, + "Yes" + ) +MSG_HASH( + MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO, + "Shader Preset" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, + "Enable or disable achievements. For more information, visit http://retroachievements.org" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, + "Enable or disable unofficial achievements and/or beta features for testing purposes." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, + "Enable or disable savestates, cheats, rewind, pause, and slow-motion for all games." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_LEADERBOARDS_ENABLE, + "Enable or disable in-game leaderboards. Has no effect if Hardcore Mode is disabled." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_BADGES_ENABLE, + "Enable or disable badge display in the Achievement List." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_VERBOSE_ENABLE, + "Enable or disable OSD verbosity for achievements." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_AUTO_SCREENSHOT, + "Automatically take a screenshot when an achievement is triggered." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, + "Change drivers used by the system." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, + "Change achievement settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_SETTINGS, + "Change core settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RECORDING_SETTINGS, + "Change recording settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ONSCREEN_DISPLAY_SETTINGS, + "Change display overlay and keyboard overlay, and onscreen notification settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_FRAME_THROTTLE_SETTINGS, + "Change rewind, fast-forward, and slow-motion settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVING_SETTINGS, + "Change saving settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOGGING_SETTINGS, + "Change logging settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_USER_INTERFACE_SETTINGS, + "Change user interface settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_USER_SETTINGS, + "Change account, username, and language settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, + "Change your privacy settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIDI_SETTINGS, + "Change MIDI settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, + "Change default directories where files are located." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, + "Change playlist settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, + "Configure server and network settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, + "Scan content and add to the database." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, + "Change audio output settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE, + "Enable or disable bluetooth." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, + "Saves changes to the configuration file on exit." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONFIGURATION_SETTINGS, + "Change default settings for configuration files." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONFIGURATIONS_LIST, + "Manage and create configuration files." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CPU_CORES, + "Amount of cores that the CPU has." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_FPS_SHOW, + "Displays the current framerate per second onscreen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS, + "Configure hotkey settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, + "Gamepad button combination to toggle menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_SETTINGS, + "Change joypad, keyboard, and mouse settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_USER_BINDS, + "Configure controls for this user." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LATENCY_SETTINGS, + "Change settings related to video, audio and input latency." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOG_VERBOSITY, + "Enable or disable logging to the terminal." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY, + "Join or host a netplay session." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, + "Search for and connect to netplay hosts on the local network." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, + "Display system information." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ONLINE_UPDATER, + "Download add-ons, components, and content for RetroArch." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAMBA_ENABLE, + "Enable or disable network sharing of your folders." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, + "Manage operating system level services." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES, + "Show hidden files/directories inside the file browser." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SSH_ENABLE, + "Enable or disable remote command line access." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE, + "Prevents your system's screensaver from becoming active." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_WINDOW_SCALE, + "Sets the window size relative to the core viewport size. Alternatively, you can set a window width and height below for a fixed window size." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_USER_LANGUAGE, + "Sets the language of the interface." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, + "Inserts a black frame inbetween frames. Useful for users with 120Hz screens who want to play 60Hz content to eliminate ghosting." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, + "Reduces latency at the cost of a higher risk of video stuttering. Adds a delay after V-Sync (in ms)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, + "Sets how many frames the CPU can run ahead of the GPU when using 'Hard GPU Sync'." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, + "Tells the video driver to explicitly use a specified buffering mode." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, + "Selects which display screen to use." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, + "The accurate estimated refresh rate of the screen in Hz." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED, + "The refresh rate as reported by the display driver." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, + "Change video output settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_WIFI_SETTINGS, + "Scans for wireless networks and establishes connection." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_HELP_LIST, + "Learn more about how the program works." + ) +MSG_HASH( + MSG_ADDED_TO_FAVORITES, + "Added to favorites" + ) +MSG_HASH( + MSG_RESET_CORE_ASSOCIATION, + "Playlist entry core association has been reset." + ) +MSG_HASH( + MSG_APPENDED_DISK, + "Appended disk" + ) +MSG_HASH( + MSG_APPLICATION_DIR, + "Application Dir" + ) +MSG_HASH( + MSG_APPLYING_CHEAT, + "Applying cheat changes." + ) +MSG_HASH( + MSG_APPLYING_SHADER, + "Applying shader" + ) +MSG_HASH( + MSG_AUDIO_MUTED, + "Audio muted." + ) +MSG_HASH( + MSG_AUDIO_UNMUTED, + "Audio unmuted." + ) +MSG_HASH( + MSG_AUTOCONFIG_FILE_ERROR_SAVING, + "Error saving autoconf file." + ) +MSG_HASH( + MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY, + "Autoconfig file saved successfully." + ) +MSG_HASH( + MSG_AUTOSAVE_FAILED, + "Could not initialize autosave." + ) +MSG_HASH( + MSG_AUTO_SAVE_STATE_TO, + "Auto save state to" + ) +MSG_HASH( + MSG_BLOCKING_SRAM_OVERWRITE, + "Blocking SRAM Overwrite" + ) +MSG_HASH( + MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT, + "Bringing up command interface on port" + ) +MSG_HASH( + MSG_BYTES, + "bytes" + ) +MSG_HASH( + MSG_CANNOT_INFER_NEW_CONFIG_PATH, + "Cannot infer new config path. Use current time." + ) +MSG_HASH( + MSG_CHEEVOS_HARDCORE_MODE_ENABLE, + "Hardcore Mode Enabled, savestate & rewind were disabled." + ) +MSG_HASH( + MSG_COMPARING_WITH_KNOWN_MAGIC_NUMBERS, + "Comparing with known magic numbers..." + ) +MSG_HASH( + MSG_COMPILED_AGAINST_API, + "Compiled against API" + ) +MSG_HASH( + MSG_CONFIG_DIRECTORY_NOT_SET, + "Config directory not set. Cannot save new config." + ) +MSG_HASH( + MSG_CONNECTED_TO, + "Connected to" + ) +MSG_HASH( + MSG_CONTENT_CRC32S_DIFFER, + "Content CRC32s differ. Cannot use different games." + ) +MSG_HASH( + MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT, + "Content loading skipped. Implementation will load it on its own." + ) +MSG_HASH( + MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES, + "Core does not support save states." + ) +MSG_HASH( + MSG_CORE_OPTIONS_FILE_CREATED_SUCCESSFULLY, + "Core options file created successfully." + ) +MSG_HASH( + MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER, + "Could not find any next driver" + ) +MSG_HASH( + MSG_COULD_NOT_FIND_COMPATIBLE_SYSTEM, + "Could not find compatible system." + ) +MSG_HASH( + MSG_COULD_NOT_FIND_VALID_DATA_TRACK, + "Could not find valid data track" + ) +MSG_HASH( + MSG_COULD_NOT_OPEN_DATA_TRACK, + "could not open data track" + ) +MSG_HASH( + MSG_COULD_NOT_READ_CONTENT_FILE, + "Could not read content file" + ) +MSG_HASH( + MSG_COULD_NOT_READ_MOVIE_HEADER, + "Could not read movie header." + ) +MSG_HASH( + MSG_COULD_NOT_READ_STATE_FROM_MOVIE, + "Could not read state from movie." + ) +MSG_HASH( + MSG_CRC32_CHECKSUM_MISMATCH, + "CRC32 checksum mismatch between content file and saved content checksum in replay file header. Replay highly likely to desync on playback." + ) +MSG_HASH( + MSG_CUSTOM_TIMING_GIVEN, + "Custom timing given" + ) +MSG_HASH( + MSG_DECOMPRESSION_ALREADY_IN_PROGRESS, + "Decompression already in progress." + ) +MSG_HASH( + MSG_DECOMPRESSION_FAILED, + "Decompression failed." + ) +MSG_HASH( + MSG_DETECTED_VIEWPORT_OF, + "Detected viewport of" + ) +MSG_HASH( + MSG_DID_NOT_FIND_A_VALID_CONTENT_PATCH, + "Did not find a valid content patch." + ) +MSG_HASH( + MSG_DISCONNECT_DEVICE_FROM_A_VALID_PORT, + "Disconnect device from a valid port." + ) +MSG_HASH( + MSG_DISK_CLOSED, + "Closed" + ) +MSG_HASH( + MSG_DISK_EJECTED, + "Ejected" + ) +MSG_HASH( + MSG_DOWNLOADING, + "Downloading" + ) +MSG_HASH( + MSG_INDEX_FILE, + "index" + ) +MSG_HASH( + MSG_DOWNLOAD_FAILED, + "Download failed" + ) +MSG_HASH( + MSG_ERROR, + "Error" + ) +MSG_HASH( + MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT, + "Libretro core requires content, but nothing was provided." + ) +MSG_HASH( + MSG_ERROR_LIBRETRO_CORE_REQUIRES_SPECIAL_CONTENT, + "Libretro core requires special content, but none were provided." + ) +MSG_HASH( + MSG_ERROR_PARSING_ARGUMENTS, + "Error parsing arguments." + ) +MSG_HASH( + MSG_ERROR_SAVING_CORE_OPTIONS_FILE, + "Error saving core options file." + ) +MSG_HASH( + MSG_ERROR_SAVING_REMAP_FILE, + "Error saving remap file." + ) +MSG_HASH( + MSG_ERROR_REMOVING_REMAP_FILE, + "Error removing remap file." + ) +MSG_HASH( + MSG_ERROR_SAVING_SHADER_PRESET, + "Error saving shader preset." + ) +MSG_HASH( + MSG_EXTERNAL_APPLICATION_DIR, + "External Application Dir" + ) +MSG_HASH( + MSG_EXTRACTING, + "Extracting" + ) +MSG_HASH( + MSG_EXTRACTING_FILE, + "Extracting file" + ) +MSG_HASH( + MSG_FAILED_SAVING_CONFIG_TO, + "Failed saving config to" + ) +MSG_HASH( + MSG_FAILED_TO, + "Failed to" + ) +MSG_HASH( + MSG_FAILED_TO_ACCEPT_INCOMING_SPECTATOR, + "Failed to accept incoming spectator." + ) +MSG_HASH( + MSG_FAILED_TO_ALLOCATE_MEMORY_FOR_PATCHED_CONTENT, + "Failed to allocate memory for patched content..." + ) +MSG_HASH( + MSG_FAILED_TO_APPLY_SHADER, + "Failed to apply shader." + ) +MSG_HASH( + MSG_FAILED_TO_BIND_SOCKET, + "Failed to bind socket." + ) +MSG_HASH( + MSG_FAILED_TO_CREATE_THE_DIRECTORY, + "Failed to create the directory." + ) +MSG_HASH( + MSG_FAILED_TO_EXTRACT_CONTENT_FROM_COMPRESSED_FILE, + "Failed to extract content from compressed file" + ) +MSG_HASH( + MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT, + "Failed to get nickname from client." + ) +MSG_HASH( + MSG_FAILED_TO_LOAD, + "Failed to load" + ) +MSG_HASH( + MSG_FAILED_TO_LOAD_CONTENT, + "Failed to load content" + ) +MSG_HASH( + MSG_FAILED_TO_LOAD_MOVIE_FILE, + "Failed to load movie file" + ) +MSG_HASH( + MSG_FAILED_TO_LOAD_OVERLAY, + "Failed to load overlay." + ) +MSG_HASH( + MSG_FAILED_TO_LOAD_STATE, + "Failed to load state from" + ) +MSG_HASH( + MSG_FAILED_TO_OPEN_LIBRETRO_CORE, + "Failed to open libretro core" + ) +MSG_HASH( + MSG_FAILED_TO_PATCH, + "Failed to patch" + ) +MSG_HASH( + MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT, + "Failed to receive header from client." + ) +MSG_HASH( + MSG_FAILED_TO_RECEIVE_NICKNAME, + "Failed to receive nickname." + ) +MSG_HASH( + MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST, + "Failed to receive nickname from host." + ) +MSG_HASH( + MSG_FAILED_TO_RECEIVE_NICKNAME_SIZE_FROM_HOST, + "Failed to receive nickname size from host." + ) +MSG_HASH( + MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST, + "Failed to receive SRAM data from host." + ) +MSG_HASH( + MSG_FAILED_TO_REMOVE_DISK_FROM_TRAY, + "Failed to remove disk from tray." + ) +MSG_HASH( + MSG_FAILED_TO_REMOVE_TEMPORARY_FILE, + "Failed to remove temporary file" + ) +MSG_HASH( + MSG_FAILED_TO_SAVE_SRAM, + "Failed to save SRAM" + ) +MSG_HASH( + MSG_FAILED_TO_SAVE_STATE_TO, + "Failed to save state to" + ) +MSG_HASH( + MSG_FAILED_TO_SEND_NICKNAME, + "Failed to send nickname." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_NICKNAME_SIZE, + "Failed to send nickname size." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT, + "Failed to send nickname to client." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_NICKNAME_TO_HOST, + "Failed to send nickname to host." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_SRAM_DATA_TO_CLIENT, + "Failed to send SRAM data to client." + ) +MSG_HASH( + MSG_FAILED_TO_START_AUDIO_DRIVER, + "Failed to start audio driver. Will continue without audio." + ) +MSG_HASH( + MSG_FAILED_TO_START_MOVIE_RECORD, + "Failed to start movie record." + ) +MSG_HASH( + MSG_FAILED_TO_START_RECORDING, + "Failed to start recording." + ) +MSG_HASH( + MSG_FAILED_TO_TAKE_SCREENSHOT, + "Failed to take screenshot." + ) +MSG_HASH( + MSG_FAILED_TO_UNDO_LOAD_STATE, + "Failed to undo load state." + ) +MSG_HASH( + MSG_FAILED_TO_UNDO_SAVE_STATE, + "Failed to undo save state." + ) +MSG_HASH( + MSG_FAILED_TO_UNMUTE_AUDIO, + "Failed to unmute audio." + ) +MSG_HASH( + MSG_FATAL_ERROR_RECEIVED_IN, + "Fatal error received in" + ) +MSG_HASH( + MSG_FILE_NOT_FOUND, + "File not found" + ) +MSG_HASH( + MSG_FOUND_AUTO_SAVESTATE_IN, + "Found auto savestate in" + ) +MSG_HASH( + MSG_FOUND_DISK_LABEL, + "Found disk label" + ) +MSG_HASH( + MSG_FOUND_FIRST_DATA_TRACK_ON_FILE, + "Found first data track on file" + ) +MSG_HASH( + MSG_FOUND_LAST_STATE_SLOT, + "Found last state slot" + ) +MSG_HASH( + MSG_FOUND_SHADER, + "Found shader" + ) +MSG_HASH( + MSG_FRAMES, + "Frames" + ) +MSG_HASH( + MSG_GAME_SPECIFIC_CORE_OPTIONS_FOUND_AT, + "Per-Game Options: game-specific core options found at" + ) +MSG_HASH( + MSG_GOT_INVALID_DISK_INDEX, + "Got invalid disk index." + ) +MSG_HASH( + MSG_GRAB_MOUSE_STATE, + "Grab mouse state" + ) +MSG_HASH( + MSG_GAME_FOCUS_ON, + "Game focus on" + ) +MSG_HASH( + MSG_GAME_FOCUS_OFF, + "Game focus off" + ) +MSG_HASH( + MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING, + "Libretro core is hardware rendered. Must use post-shaded recording as well." + ) +MSG_HASH( + MSG_INFLATED_CHECKSUM_DID_NOT_MATCH_CRC32, + "Inflated checksum did not match CRC32." + ) +MSG_HASH( + MSG_INPUT_CHEAT, + "Input Cheat" + ) +MSG_HASH( + MSG_INPUT_CHEAT_FILENAME, + "Input Cheat Filename" + ) +MSG_HASH( + MSG_INPUT_PRESET_FILENAME, + "Input Preset Filename" + ) +MSG_HASH( + MSG_INPUT_RENAME_ENTRY, + "Rename Title" + ) +MSG_HASH( + MSG_INTERFACE, + "Interface" + ) +MSG_HASH( + MSG_INTERNAL_STORAGE, + "Internal Storage" + ) +MSG_HASH( + MSG_REMOVABLE_STORAGE, + "Removable Storage" + ) +MSG_HASH( + MSG_INVALID_NICKNAME_SIZE, + "Invalid nickname size." + ) +MSG_HASH( + MSG_IN_BYTES, + "in bytes" + ) +MSG_HASH( + MSG_IN_GIGABYTES, + "in gigabytes" + ) +MSG_HASH( + MSG_IN_MEGABYTES, + "in megabytes" + ) +MSG_HASH( + MSG_LIBRETRO_ABI_BREAK, + "is compiled against a different version of libretro than this libretro implementation." + ) +MSG_HASH( + MSG_LIBRETRO_FRONTEND, + "Frontend for libretro" + ) +MSG_HASH( + MSG_LOADED_STATE_FROM_SLOT, + "Loaded state from slot #%d." + ) +MSG_HASH( + MSG_LOADED_STATE_FROM_SLOT_AUTO, + "Loaded state from slot #-1 (auto)." + ) +MSG_HASH( + MSG_LOADING, + "Loading" + ) +MSG_HASH( + MSG_FIRMWARE, + "One or more firmware files are missing" + ) +MSG_HASH( + MSG_LOADING_CONTENT_FILE, + "Loading content file" + ) +MSG_HASH( + MSG_LOADING_HISTORY_FILE, + "Loading history file" + ) +MSG_HASH( + MSG_LOADING_STATE, + "Loading state" + ) +MSG_HASH( + MSG_MEMORY, + "Memory" + ) +MSG_HASH( + MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE, + "Movie file is not a valid BSV1 file." + ) +MSG_HASH( + MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION, + "Movie format seems to have a different serializer version. Will most likely fail." + ) +MSG_HASH( + MSG_MOVIE_PLAYBACK_ENDED, + "Movie playback ended." + ) +MSG_HASH( + MSG_MOVIE_RECORD_STOPPED, + "Stopping movie record." + ) +MSG_HASH( + MSG_NETPLAY_FAILED, + "Failed to initialize netplay." + ) +MSG_HASH( + MSG_NO_CONTENT_STARTING_DUMMY_CORE, + "No content, starting dummy core." + ) +MSG_HASH( + MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET, + "No save state has been overwritten yet." + ) +MSG_HASH( + MSG_NO_STATE_HAS_BEEN_LOADED_YET, + "No state has been loaded yet." + ) +MSG_HASH( + MSG_OVERRIDES_ERROR_SAVING, + "Error saving overrides." + ) +MSG_HASH( + MSG_OVERRIDES_SAVED_SUCCESSFULLY, + "Overrides saved successfully." + ) +MSG_HASH( + MSG_PAUSED, + "Paused." + ) +MSG_HASH( + MSG_PROGRAM, + "RetroArch" + ) +MSG_HASH( + MSG_READING_FIRST_DATA_TRACK, + "Reading first data track..." + ) +MSG_HASH( + MSG_RECEIVED, + "received" + ) +MSG_HASH( + MSG_RECORDING_TERMINATED_DUE_TO_RESIZE, + "Recording terminated due to resize." + ) +MSG_HASH( + MSG_RECORDING_TO, + "Recording to" + ) +MSG_HASH( + MSG_REDIRECTING_CHEATFILE_TO, + "Redirecting cheat file to" + ) +MSG_HASH( + MSG_REDIRECTING_SAVEFILE_TO, + "Redirecting save file to" + ) +MSG_HASH( + MSG_REDIRECTING_SAVESTATE_TO, + "Redirecting savestate to" + ) +MSG_HASH( + MSG_REMAP_FILE_SAVED_SUCCESSFULLY, + "Remap file saved successfully." + ) +MSG_HASH( + MSG_REMAP_FILE_REMOVED_SUCCESSFULLY, + "Remap file removed successfully." + ) +MSG_HASH( + MSG_REMOVED_DISK_FROM_TRAY, + "Removed disk from tray." + ) +MSG_HASH( + MSG_REMOVING_TEMPORARY_CONTENT_FILE, + "Removing temporary content file" + ) +MSG_HASH( + MSG_RESET, + "Reset" + ) +MSG_HASH( + MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT, + "Restarting recording due to driver reinit." + ) +MSG_HASH( + MSG_RESTORED_OLD_SAVE_STATE, + "Restored old save state." + ) +MSG_HASH( + MSG_RESTORING_DEFAULT_SHADER_PRESET_TO, + "Shaders: restoring default shader preset to" + ) +MSG_HASH( + MSG_REVERTING_SAVEFILE_DIRECTORY_TO, + "Reverting savefile directory to" + ) +MSG_HASH( + MSG_REVERTING_SAVESTATE_DIRECTORY_TO, + "Reverting savestate directory to" + ) +MSG_HASH( + MSG_REWINDING, + "Rewinding." + ) +MSG_HASH( + MSG_REWIND_INIT, + "Initializing rewind buffer with size" + ) +MSG_HASH( + MSG_REWIND_INIT_FAILED, + "Failed to initialize rewind buffer. Rewinding will be disabled." + ) +MSG_HASH( + MSG_REWIND_INIT_FAILED_THREADED_AUDIO, + "Implementation uses threaded audio. Cannot use rewind." + ) +MSG_HASH( + MSG_REWIND_REACHED_END, + "Reached end of rewind buffer." + ) +MSG_HASH( + MSG_SAVED_NEW_CONFIG_TO, + "Saved new config to" + ) +MSG_HASH( + MSG_SAVED_STATE_TO_SLOT, + "Saved state to slot #%d." + ) +MSG_HASH( + MSG_SAVED_STATE_TO_SLOT_AUTO, + "Saved state to slot #-1 (auto)." + ) +MSG_HASH( + MSG_SAVED_SUCCESSFULLY_TO, + "Saved successfully to" + ) +MSG_HASH( + MSG_SAVING_RAM_TYPE, + "Saving RAM type" + ) +MSG_HASH( + MSG_SAVING_STATE, + "Saving state" + ) +MSG_HASH( + MSG_SCANNING, + "Scanning" + ) +MSG_HASH( + MSG_SCANNING_OF_DIRECTORY_FINISHED, + "Scanning of directory finished" + ) +MSG_HASH( + MSG_SENDING_COMMAND, + "Sending command" + ) +MSG_HASH( + MSG_SEVERAL_PATCHES_ARE_EXPLICITLY_DEFINED, + "Several patches are explicitly defined, ignoring all..." + ) +MSG_HASH( + MSG_SHADER, + "Shader" + ) +MSG_HASH( + MSG_SHADER_PRESET_SAVED_SUCCESSFULLY, + "Shader preset saved successfully." + ) +MSG_HASH( + MSG_SKIPPING_SRAM_LOAD, + "Skipping SRAM load." + ) +MSG_HASH( + MSG_SLOW_MOTION, + "Slow motion." + ) +MSG_HASH( + MSG_FAST_FORWARD, + "Fast forward." + ) +MSG_HASH( + MSG_SLOW_MOTION_REWIND, + "Slow motion rewind." + ) +MSG_HASH( + MSG_SRAM_WILL_NOT_BE_SAVED, + "SRAM will not be saved." + ) +MSG_HASH( + MSG_STARTING_MOVIE_PLAYBACK, + "Starting movie playback." + ) +MSG_HASH( + MSG_STARTING_MOVIE_RECORD_TO, + "Starting movie record to" + ) +MSG_HASH( + MSG_STATE_SIZE, + "State size" + ) +MSG_HASH( + MSG_STATE_SLOT, + "State slot" + ) +MSG_HASH( + MSG_TAKING_SCREENSHOT, + "Taking screenshot." + ) +MSG_HASH( + MSG_TO, + "to" + ) +MSG_HASH( + MSG_UNDID_LOAD_STATE, + "Undid load state." + ) +MSG_HASH( + MSG_UNDOING_SAVE_STATE, + "Undoing save state" + ) +MSG_HASH( + MSG_UNKNOWN, + "Unknown" + ) +MSG_HASH( + MSG_UNPAUSED, + "Unpaused." + ) +MSG_HASH( + MSG_UNRECOGNIZED_COMMAND, + "Unrecognized command" + ) +MSG_HASH( + MSG_USING_CORE_NAME_FOR_NEW_CONFIG, + "Using core name for new config." + ) +MSG_HASH( + MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED, + "Using libretro dummy core. Skipping recording." + ) +MSG_HASH( + MSG_VALUE_CONNECT_DEVICE_FROM_A_VALID_PORT, + "Connect device from a valid port." + ) +MSG_HASH( + MSG_VALUE_DISCONNECTING_DEVICE_FROM_PORT, + "Disconnecting device from port" + ) +MSG_HASH( + MSG_VALUE_REBOOTING, + "Rebooting..." + ) +MSG_HASH( + MSG_VALUE_SHUTTING_DOWN, + "Shutting down..." + ) +MSG_HASH( + MSG_VERSION_OF_LIBRETRO_API, + "Version of libretro API" + ) +MSG_HASH( + MSG_VIEWPORT_SIZE_CALCULATION_FAILED, + "Viewport size calculation failed! Will continue using raw data. This will probably not work right ..." + ) +MSG_HASH( + MSG_VIRTUAL_DISK_TRAY, + "virtual disk tray." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_LATENCY, + "Desired audio latency in milliseconds. Might not be honored if the audio driver can't provide given latency." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_MUTE, + "Mute/unmute audio." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, + "Helps smooth out imperfections in timing when synchronizing audio and video. Be aware that if disabled, proper synchronization is nearly impossible to obtain." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CAMERA_ALLOW, + "Allow or disallow camera access by cores." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOCATION_ALLOW, + "Allow or disallow location services access by cores." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_MAX_USERS, + "Maximum amount of users supported by RetroArch." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_POLL_TYPE_BEHAVIOR, + "Influence how input polling is done inside RetroArch. Setting it to 'Early' or 'Late' can result in less latency, depending on your configuration." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_ALL_USERS_CONTROL_MENU, + "Allows any user to control the menu. If disabled, only User 1 can control the menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_VOLUME, + "Audio volume (in dB). 0 dB is normal volume, and no gain is applied." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_WASAPI_EXCLUSIVE_MODE, + "Allow the WASAPI driver to take exclusive control of the audio device. If disabled, it will use shared mode instead." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_WASAPI_FLOAT_FORMAT, + "Use float format for the WASAPI driver, if supported by your audio device." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_WASAPI_SH_BUFFER_LENGTH, + "The intermediate buffer length (in frames) when using the WASAPI driver in shared mode." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_SYNC, + "Synchronize audio. Recommended." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, + "How far an axis must be tilted to result in a button press." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, + "Amount of seconds to wait until proceeding to the next bind." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_BIND_HOLD, + "Amount of seconds to hold an input to bind it." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_TURBO_PERIOD, + "Describes the period when turbo-enabled buttons are toggled. Numbers are described in frames." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_DUTY_CYCLE, + "Describes how long the period of a turbo-enabled button should be. Numbers are described in frames." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_VSYNC, + "Synchronizes the output video of the graphics card to the refresh rate of the screen. Recommended." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_ALLOW_ROTATE, + "Allow cores to set rotation. When disabled, rotation requests are ignored. Useful for setups where one manually rotates the screen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DUMMY_ON_CORE_SHUTDOWN, + "Some cores might have a shutdown feature. If enabled, it will prevent the core from shutting RetroArch down. Instead, it loads a dummy core." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHECK_FOR_MISSING_FIRMWARE, + "Check if all the required firmware is present before attempting to load content." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE, + "Vertical refresh rate of your screen. Used to calculate a suitable audio input rate. NOTE: This will be ignored if 'Threaded Video' is enabled." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_ENABLE, + "Enable audio output." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_MAX_TIMING_SKEW, + "The maximum change in audio input rate. Increasing this enables very large changes in timing at the cost of an inaccurate audio pitch (e.g., running PAL cores on NTSC displays)." + ) +MSG_HASH( + MSG_FAILED, + "failed" + ) +MSG_HASH( + MSG_SUCCEEDED, + "succeeded" + ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED, + "not configured" + ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED_FALLBACK, + "not configured, using fallback" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, + "Database Cursor List" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DEVELOPER, + "Database - Filter : Developer" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PUBLISHER, + "Database - Filter : Publisher" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISABLED, + "Disabled" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ENABLED, + "Enabled" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_PATH, + "Content History Path" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ORIGIN, + "Database - Filter : Origin" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_FRANCHISE, + "Database - Filter : Franchise" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ESRB_RATING, + "Database - Filter : ESRB Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ELSPA_RATING, + "Database - Filter : ELSPA Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PEGI_RATING, + "Database - Filter : PEGI Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_CERO_RATING, + "Database - Filter : CERO Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_BBFC_RATING, + "Database - Filter : BBFC Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_MAX_USERS, + "Database - Filter : Max Users" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_MONTH, + "Database - Filter : Releasedate By Month" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_YEAR, + "Database - Filter : Releasedate By Year" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_ISSUE, + "Database - Filter : Edge Magazine Issue" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_RATING, + "Database - Filter : Edge Magazine Rating" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DATABASE_INFO, + "Database Info" + ) +MSG_HASH( + MSG_WIFI_SCAN_COMPLETE, + "Wi-Fi scan complete." + ) +MSG_HASH( + MSG_SCANNING_WIRELESS_NETWORKS, + "Scanning wireless networks..." + ) +MSG_HASH( + MSG_NETPLAY_LAN_SCAN_COMPLETE, + "Netplay scan complete." + ) +MSG_HASH( + MSG_NETPLAY_LAN_SCANNING, + "Scanning for netplay hosts..." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, + "Pause gameplay when RetroArch is not the active window." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, + "Enable or disable composition." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, + "Enable or disable recent playlist for games, images, music, and videos." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, + "Limit the number of entries in recent playlist for games, images, music, and videos." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_UNIFIED_MENU_CONTROLS, + "Unified Menu Controls" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS, + "Use the same controls for both the menu and the game. Applies to the keyboard." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE, + "Show onscreen messages." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETWORK_USER_REMOTE_ENABLE, + "User %d Remote Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, + "Show battery level" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SELECT_FILE, + "Select File" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, + "Select From Collection" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FILTER, + "Filter" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SCALE, + "Scale" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED, + "Netplay will start when content is loaded." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_LOAD_CONTENT_MANUALLY, + "Couldn't find a suitable core or content file, load manually." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BROWSE_URL_LIST, + "Browse URL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BROWSE_URL, + "URL Path" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BROWSE_START, + "Start" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, + "Bokeh" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOWFLAKE, + "Snowflake" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_ROOMS, + "Refresh Room List" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME, + "Nickname: %s" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME_LAN, + "Nickname (lan): %s" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND, + "Compatible content found" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_CROP_OVERSCAN, + "Cuts off a few pixels around the edges of the image customarily left blank by developers which sometimes also contain garbage pixels." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SMOOTH, + "Adds a slight blur to the image to take the edge off of the hard pixel edges. This option has very little impact on performance." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FILTER, + "Apply a CPU-powered video filter. NOTE: Might come at a high performance cost. Some video filters might only work for cores that use 32bit or 16bit color." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_USERNAME, + "Input the username of your RetroAchievements account." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEEVOS_PASSWORD, + "Input the password of your RetroAchievements account." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_NICKNAME, + "Input your user name here. This will be used for netplay sessions, among other things." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_POST_FILTER_RECORD, + "Capture the image after filters (but not shaders) are applied. Your video will look as fancy as what you see on your screen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_LIST, + "Select which core to use." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOAD_CONTENT_LIST, + "Select which content to start." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETWORK_INFORMATION, + "Show network interface(s) and associated IP addresses." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SYSTEM_INFORMATION, + "Show information specific to the device." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUIT_RETROARCH, + "Quit the program." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_WINDOW_WIDTH, + "Set the custom width size for the display window. Leaving it at 0 will attempt to scale the window as large as possible." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_WINDOW_HEIGHT, + "Set the custom height size for the display window. Leaving it at 0 will attempt to scale the window as large as possible." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_X, + "Set the custom width size for the non-windowed fullscreen mode. Leaving it at 0 will use the desktop resolution." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_Y, + "Set the custom height size for the non-windowed fullscreen mode. Leaving it at 0 will use the desktop resolution" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_X, + "Specify custom X axis position for onscreen text." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_Y, + "Specify custom Y axis position for onscreen text." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, + "Specify the font size in points." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, + "Hide the overlay while inside the menu, and show it again when exiting the menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, + "Show keyboard/controller inputs on the onscreen overlay." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, + "Select the port for the overlay to listen to if Show Inputs On Overlay is enabled." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + "Scanned content will appear here." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, + "Only scales video in integer steps. The base size depends on system-reported geometry and aspect ratio. If 'Force Aspect' is not set, X/Y will be integer scaled independently." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT, + "Screenshots output of GPU shaded material if available." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_ROTATION, + "Forces a certain rotation of the screen. The rotation is added to rotations which the core sets." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FORCE_SRGB_DISABLE, + "Forcibly disable sRGB FBO support. Some Intel OpenGL drivers on Windows have video problems with sRGB FBO support if this is enabled. Enabling this can work around it." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN, + "Start in fullscreen. Can be changed at runtime. Can be overridden by a command line switch" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_WINDOWED_FULLSCREEN, + "If fullscreen, prefer using a windowed fullscreen mode." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_GPU_RECORD, + "Records output of GPU shaded material if available." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX, + "When making a savestate, save state index is automatically increased before it is saved. When loading content, the index will be set to the highest existing index." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE, + "Block Save RAM from being overwritten when loading save states. Might potentially lead to buggy games." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO, + "The maximum rate at which content will be run when using fast forward (e.g., 5.0x for 60 fps content = 300 fps cap). If set to 0.0x, fastforward ratio is unlimited (no FPS cap)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, + "When in slow motion, content will slow down by the factor specified/set." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RUN_AHEAD_ENABLED, + "Run core logic one or more frames ahead then load the state back to reduce perceived input lag." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RUN_AHEAD_FRAMES, + "The number of frames to run ahead. Causes gameplay issues such as jitter if you exceed the number of lag frames internal to the game." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RUN_AHEAD_SECONDARY_INSTANCE, + "Use a second instance of the RetroArch core to run ahead. Prevents audio problems due to loading state." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RUN_AHEAD_HIDE_WARNINGS, + "Hides the warning message that appears when using RunAhead and the core does not support savestates." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_REWIND_ENABLE, + "Enable rewinding. This will take a performance hit when playing." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_APPLY_AFTER_TOGGLE, + "Apply cheat immediately after toggling." ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_APPLY_AFTER_LOAD, - "Auto-apply cheats when game loads." + MENU_ENUM_SUBLABEL_CHEAT_APPLY_AFTER_LOAD, + "Auto-apply cheats when game loads." ) MSG_HASH( - MENU_ENUM_SUBLABEL_REWIND_GRANULARITY, - "When rewinding a defined number of frames, you can rewind several frames at a time, increasing the rewind speed." - ) + MENU_ENUM_SUBLABEL_REWIND_GRANULARITY, + "When rewinding a defined number of frames, you can rewind several frames at a time, increasing the rewind speed." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE, - "The amount of memory (in MB) to reserve for the rewind buffer. Increasing this will increase the amount of rewind history." - ) + MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE, + "The amount of memory (in MB) to reserve for the rewind buffer. Increasing this will increase the amount of rewind history." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE_STEP, - "Each time you increase or decrease the rewind buffer size value via this UI it will change by this amount" - ) + MENU_ENUM_SUBLABEL_REWIND_BUFFER_SIZE_STEP, + "Each time you increase or decrease the rewind buffer size value via this UI it will change by this amount" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_IDX, - "Index position in list." - ) + MENU_ENUM_SUBLABEL_CHEAT_IDX, + "Index position in list." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_ADDRESS_BIT_POSITION, - "Address bitmask when Memory Search Size < 8-bit." -) + MENU_ENUM_SUBLABEL_CHEAT_ADDRESS_BIT_POSITION, + "Address bitmask when Memory Search Size < 8-bit." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_MATCH_IDX, - "Select the match to view." - ) + MENU_ENUM_SUBLABEL_CHEAT_MATCH_IDX, + "Select the match to view." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_START_OR_CONT, - "" - ) + MENU_ENUM_SUBLABEL_CHEAT_START_OR_CONT, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_START_OR_RESTART, - "Left/Right to change bit-size" - ) + MENU_ENUM_SUBLABEL_CHEAT_START_OR_RESTART, + "Left/Right to change bit-size" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EXACT, - "Left/Right to change value" -) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EXACT, + "Left/Right to change value" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LT, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LT, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GT, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GT, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LTE, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_LTE, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GTE, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_GTE, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQ, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQ, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_NEQ, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_NEQ, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQPLUS, - "Left/Right to change value" -) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQPLUS, + "Left/Right to change value" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQMINUS, - "Left/Right to change value" -) + MENU_ENUM_SUBLABEL_CHEAT_SEARCH_EQMINUS, + "Left/Right to change value" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_ADD_MATCHES, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_ADD_MATCHES, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_VIEW_MATCHES, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_VIEW_MATCHES, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_CREATE_OPTION, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_CREATE_OPTION, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_DELETE_OPTION, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_DELETE_OPTION, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_TOP, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_TOP, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_BOTTOM, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_ADD_NEW_BOTTOM, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_DELETE_ALL, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_DELETE_ALL, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_RELOAD_CHEATS, - "" -) + MENU_ENUM_SUBLABEL_CHEAT_RELOAD_CHEATS, + "" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_BIG_ENDIAN, - "Big endian : 258 = 0x0102,\nLittle endian : 258 = 0x0201" - ) + MENU_ENUM_SUBLABEL_CHEAT_BIG_ENDIAN, + "Big endian : 258 = 0x0102,\nLittle endian : 258 = 0x0201" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL, - "Sets log level for cores. If a log level issued by a core is below this value, it is ignored." - ) + MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL, + "Sets log level for cores. If a log level issued by a core is below this value, it is ignored." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_PERFCNT_ENABLE, - "Enable performance counters for RetroArch (and cores)." - ) + MENU_ENUM_SUBLABEL_PERFCNT_ENABLE, + "Enable performance counters for RetroArch (and cores)." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_SAVE, - "Automatically makes a savestate at the end of RetroArch's runtime. RetroArch will automatically load this savestate if 'Auto Load State' is enabled." - ) + MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_SAVE, + "Automatically makes a savestate at the end of RetroArch's runtime. RetroArch will automatically load this savestate if 'Auto Load State' is enabled." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_LOAD, - "Automatically load the auto save state on startup." - ) + MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_LOAD, + "Automatically load the auto save state on startup." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_SAVESTATE_THUMBNAIL_ENABLE, - "Show thumbnails of save states inside the menu." - ) + MENU_ENUM_SUBLABEL_SAVESTATE_THUMBNAIL_ENABLE, + "Show thumbnails of save states inside the menu." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL, - "Autosaves the non-volatile Save RAM at a regular interval. This is disabled by default unless set otherwise. The interval is measured in seconds. A value of 0 disables autosave." - ) + MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL, + "Autosaves the non-volatile Save RAM at a regular interval. This is disabled by default unless set otherwise. The interval is measured in seconds. A value of 0 disables autosave." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE, - "If enabled, overrides the input binds with the remapped binds set for the current core." - ) + MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE, + "If enabled, overrides the input binds with the remapped binds set for the current core." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AUTODETECT_ENABLE, - "Enable input auto-detection. Will attempt to autoconfigure joypads, Plug-and-Play style." - ) + MENU_ENUM_SUBLABEL_INPUT_AUTODETECT_ENABLE, + "Enable input auto-detection. Will attempt to autoconfigure joypads, Plug-and-Play style." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_INPUT_SWAP_OK_CANCEL, - "Swap buttons for OK/Cancel. Disabled is the Japanese button orientation, enabled is the western orientation." - ) + MENU_ENUM_SUBLABEL_MENU_INPUT_SWAP_OK_CANCEL, + "Swap buttons for OK/Cancel. Disabled is the Japanese button orientation, enabled is the western orientation." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_PAUSE_LIBRETRO, - "If disabled, the content will keep running in the background when RetroArch's menu is toggled." - ) + MENU_ENUM_SUBLABEL_PAUSE_LIBRETRO, + "If disabled, the content will keep running in the background when RetroArch's menu is toggled." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_DRIVER, - "Video driver to use." - ) + MENU_ENUM_SUBLABEL_VIDEO_DRIVER, + "Video driver to use." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_DRIVER, - "Audio driver to use." - ) + MENU_ENUM_SUBLABEL_AUDIO_DRIVER, + "Audio driver to use." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_DRIVER, - "Input driver to use. Depending on the video driver, it might force a different input driver." - ) + MENU_ENUM_SUBLABEL_INPUT_DRIVER, + "Input driver to use. Depending on the video driver, it might force a different input driver." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_JOYPAD_DRIVER, - "Joypad driver to use." - ) + MENU_ENUM_SUBLABEL_JOYPAD_DRIVER, + "Joypad driver to use." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_DRIVER, - "Audio resampler driver to use." - ) + MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_DRIVER, + "Audio resampler driver to use." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_CAMERA_DRIVER, - "Camera driver to use." - ) + MENU_ENUM_SUBLABEL_CAMERA_DRIVER, + "Camera driver to use." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_LOCATION_DRIVER, - "Location driver to use." - ) + MENU_ENUM_SUBLABEL_LOCATION_DRIVER, + "Location driver to use." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_DRIVER, - "Menu driver to use." - ) + MENU_ENUM_SUBLABEL_MENU_DRIVER, + "Menu driver to use." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_RECORD_DRIVER, - "Record driver to use." - ) + MENU_ENUM_SUBLABEL_RECORD_DRIVER, + "Record driver to use." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MIDI_DRIVER, - "MIDI driver to use." - ) + MENU_ENUM_SUBLABEL_MIDI_DRIVER, + "MIDI driver to use." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_WIFI_DRIVER, - "WiFi driver to use." - ) + MENU_ENUM_SUBLABEL_WIFI_DRIVER, + "WiFi driver to use." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, - "Filter files being shown in filebrowser by supported extensions." - ) + MENU_ENUM_SUBLABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, + "Filter files being shown in filebrowser by supported extensions." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_WALLPAPER, - "Select an image to set as menu wallpaper." - ) + MENU_ENUM_SUBLABEL_MENU_WALLPAPER, + "Select an image to set as menu wallpaper." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPER, - "Dynamically load a new wallpaper depending on context." - ) + MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPER, + "Dynamically load a new wallpaper depending on context." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_DEVICE, - "Override the default audio device the audio driver uses. This is driver dependent." - ) + MENU_ENUM_SUBLABEL_AUDIO_DEVICE, + "Override the default audio device the audio driver uses. This is driver dependent." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_DSP_PLUGIN, - "Audio DSP plugin that processes audio before it's sent to the driver." - ) + MENU_ENUM_SUBLABEL_AUDIO_DSP_PLUGIN, + "Audio DSP plugin that processes audio before it's sent to the driver." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_OUTPUT_RATE, - "Audio output sample rate." - ) + MENU_ENUM_SUBLABEL_AUDIO_OUTPUT_RATE, + "Audio output sample rate." + ) MSG_HASH( - MENU_ENUM_SUBLABEL_OVERLAY_OPACITY, - "Opacity of all UI elements of the overlay." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_OVERLAY_SCALE, - "Scale of all UI elements of the overlay." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_OVERLAY_ENABLE, - "Enable the overlay." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_OVERLAY_PRESET, - "Select an overlay from the file browser." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_IP_ADDRESS, - "The address of the host to connect to." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_TCP_UDP_PORT, - "The port of the host IP address. Can be either a TCP or UDP port." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_PASSWORD, - "The password for connecting to the netplay host. Used only in host mode." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_PUBLIC_ANNOUNCE, - "Whether to announce netplay games publicly. If unset, clients must manually connect rather than using the public lobby." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_SPECTATE_PASSWORD, - "The password for connecting to the netplay host with only spectator privileges. Used only in host mode." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_START_AS_SPECTATOR, - "Whether to start netplay in spectator mode." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_ALLOW_SLAVES, - "Whether to allow connections in slave mode. Slave-mode clients require very little processing power on either side, but will suffer significantly from network latency." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_REQUIRE_SLAVES, - "Whether to disallow connections not in slave mode. Not recommended except for very fast networks with very weak machines." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_STATELESS_MODE, - "Whether to run netplay in a mode not requiring save states. If set to true, a very fast network is required, but no rewinding is performed, so there will be no netplay jitter." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_CHECK_FRAMES, - "The frequency in frames with which netplay will verify that the host and client are in sync." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_NAT_TRAVERSAL, - "When hosting, attempt to listen for connections from the public Internet, using UPnP or similar technologies to escape LANs." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_STDIN_CMD_ENABLE, - "Enable stdin command interface." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_MOUSE_ENABLE, - "Enable mouse controls inside the menu." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_POINTER_ENABLE, - "Enable touch controls inside the menu." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_THUMBNAILS, - "Type of thumbnail to display." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS, - "Type of thumbnail to display at the left." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_XMB_VERTICAL_THUMBNAILS, - "Display the left thumbnail under the right one, on the right side of the screen.") -MSG_HASH( - MENU_ENUM_SUBLABEL_TIMEDATE_ENABLE, - "Shows current date and/or time inside the menu." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_BATTERY_LEVEL_ENABLE, - "Shows current battery level inside the menu." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NAVIGATION_WRAPAROUND, - "Wrap-around to beginning and/or end if boundary of list is reached horizontally or vertically." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_HOST, - "Enables netplay in host (server) mode." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, - "Enables netplay in client mode.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, - "Disconnects an active Netplay connection.") -MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, - "Scans a directory for compatible files and add them to the collection.") -MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, - "Scans a compatible file and add it to the collection.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, - "Uses a custom swap interval for Vsync. Set this to effectively halve monitor refresh rate." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE, - "Sort save files in folders named after the core used." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE, - "Sort save states in folders named after the core used." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REQUEST_DEVICE_I, - "Request to play with the given input device.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL, - "URL to core updater directory on the Libretro buildbot.") -MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL, - "URL to assets updater directory on the Libretro buildbot.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, - "After downloading, automatically extract files contained in the downloaded archives." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, - "Scan for new rooms.") -MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Remove this entry from the collection.") -MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, - "View more information about the content.") -MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, - "Add the entry to your favorites.") -MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES_PLAYLIST, - "Add the entry to your favorites.") -MSG_HASH(MENU_ENUM_SUBLABEL_RUN, - "Start the content.") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_FILE_BROWSER_SETTINGS, - "Adjusts filebrowser settings.") -MSG_HASH( - MENU_ENUM_SUBLABEL_AUTO_REMAPS_ENABLE, - "Enable customized controls by default at startup." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUTO_OVERRIDES_ENABLE, - "Enable customized configuration by default at startup." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_GAME_SPECIFIC_OPTIONS, - "Enable customized core options by default at startup.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_ENABLE, - "Shows current core name inside menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_DATABASE_MANAGER, - "View databases.") -MSG_HASH(MENU_ENUM_SUBLABEL_CURSOR_MANAGER, - "View previous searches.") -MSG_HASH(MENU_ENUM_SUBLABEL_TAKE_SCREENSHOT, - "Captures an image of the screen.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CLOSE_CONTENT, - "Closes the current content. Any unsaved changes might be lost." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_STATE, - "Load a saved state from the currently selected slot.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_STATE, - "Save a state to the currently selected slot.") -MSG_HASH(MENU_ENUM_SUBLABEL_RESUME, - "Resume the currently running content and leave the Quick Menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_RESUME_CONTENT, - "Resume the currently running content and leave the Quick Menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_STATE_SLOT, - "Changes the currently selected state slot.") -MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_LOAD_STATE, - "If a state was loaded, content will go back to the state prior to loading.") -MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_SAVE_STATE, - "If a state was overwritten, it will roll back to the previous save state.") -MSG_HASH( - MENU_ENUM_SUBLABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, - "RetroAchievements service. For more information, visit http://retroachievements.org" - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_ACCOUNTS_LIST, - "Manages currently configured accounts." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_META_REWIND, - "Manages rewind settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_DETAILS, - "Manages cheat details settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_SEARCH, - "Start or continue a cheat code search.") -MSG_HASH(MENU_ENUM_SUBLABEL_RESTART_CONTENT, - "Restarts the content from the beginning.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, - "Saves an override configuration file which will apply for all content loaded with this core. Will take precedence over the main configuration.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, - "Saves an override configuration file which will apply for all content loaded from the same directory as the current file. Will take precedence over the main configuration.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, - "Saves an override configuration file which will apply for the current content only. Will take precedence over the main configuration.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_CHEAT_OPTIONS, - "Set up cheat codes.") -MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_OPTIONS, - "Set up shaders to visually augment the image.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_INPUT_REMAPPING_OPTIONS, - "Change the controls for the currently running content.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_OPTIONS, - "Change the options for the currently running content.") -MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, - "Show advanced settings for power users (hidden by default).") -MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, - "Perform tasks on a separate thread.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, - "Allow the user to remove entries from collections.") -MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, - "Sets the System directory. Cores can query for this directory to load BIOSes, system-specific configs, etc.") -MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, - "Sets start directory for the filebrowser.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_DIR, - "Usually set by developers who bundle libretro/RetroArch apps to point to assets." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPERS_DIRECTORY, - "Directory to store wallpapers dynamically loaded by the menu depending on context.") -MSG_HASH(MENU_ENUM_SUBLABEL_THUMBNAILS_DIRECTORY, - "Supplementary thumbnails (boxarts/misc. images, etc.) are stored here." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_CONFIG_DIRECTORY, - "Sets start directory for menu configuration browser.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, - "The number of frames of input latency for netplay to use to hide network latency. Reduces jitter and makes netplay less CPU-intensive, at the expense of noticeable input lag.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, - "The range of frames of input latency that may be used to hide network latency. Reduces jitter and makes netplay less CPU-intensive, at the expense of unpredictable input lag.") -MSG_HASH(MENU_ENUM_SUBLABEL_DISK_CYCLE_TRAY_STATUS, - "Cycle the current disk. If the disk is inserted, it will eject the disk. If the disk has not been inserted, it will be inserted. ") -MSG_HASH(MENU_ENUM_SUBLABEL_DISK_INDEX, - "Change the disk index.") -MSG_HASH(MENU_ENUM_SUBLABEL_DISK_OPTIONS, - "Disk image management.") -MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, - "Select a disk image to insert.") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, - "Makes sure the framerate is capped while inside the menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_VRR_RUNLOOP_ENABLE, - "Force core requested timing for variable refresh rate screens.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_LAYOUT, - "Select a different layout for the XMB interface.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_THEME, - "Select a different theme for the icon. Changes will take effect after you restart the program.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, - "Enable drop shadows for all icons. This will have a minor performance hit.") -MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_COLOR_THEME, - "Select a different background color gradient theme.") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_WALLPAPER_OPACITY, - "Modify the opacity of the background wallpaper.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MENU_COLOR_THEME, - "Select a different background color gradient theme.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_RIBBON_ENABLE, - "Select an animated background effect. Can be GPU-intensive depending on the effect. If performance is unsatisfactory, either turn this off or revert to a simpler effect.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_FONT, - "Select a different main font to be used by the menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_FAVORITES, - "Show the favorites tab inside the main menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_IMAGES, - "Show the image tab inside the main menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_MUSIC, - "Show the music tab inside the main menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_VIDEO, - "Show the video tab inside the main menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_NETPLAY, - "Show the netplay tab inside the main menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS, - "Show the settings tab inside the main menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_HISTORY, - "Show the recent history tab inside the main menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_ADD, - "Show the import content tab inside the main menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_PLAYLISTS, - "Show playlist tabs inside the main menu.") -MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN, - "Show startup screen in menu. This is automatically set to false after the program starts for the first time.") -MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY, - "Modify the opacity of the header graphic.") -MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_FOOTER_OPACITY, - "Modify the opacity of the footer graphic.") -MSG_HASH(MENU_ENUM_SUBLABEL_DPI_OVERRIDE_ENABLE, - "The menu normally scales itself dynamically. If you want to set a specific scaling size instead, enable this.") -MSG_HASH(MENU_ENUM_SUBLABEL_DPI_OVERRIDE_VALUE, - "Set the custom scaling size here. NOTE: You have to enable 'DPI Override' for this scaling size to take effect.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_ASSETS_DIRECTORY, - "Save all downloaded files to this directory.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_REMAPPING_DIRECTORY, - "Save all remapped controls to this directory.") -MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_DIR_PATH, - "Directory where the program searches for content/cores.") -MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, - "Application/core information files are stored here.") -MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, - "If a joypad is plugged in, that joypad will be autoconfigured if a config file corresponding to it is present inside this directory.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, - "Save all collections to this directory.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, - "If set to a directory, content which is temporarily extracted (e.g. from archives) will be extracted to this directory." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_CURSOR_DIRECTORY, - "Saved queries are stored to this directory.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CONTENT_DATABASE_DIRECTORY, - "Databases are stored to this directory." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_ASSETS_DIRECTORY, - "This location is queried by default when menu interfaces try to look for loadable assets, etc." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_SAVEFILE_DIRECTORY, - "Save all save files to this directory. If not set, will try to save inside the content file's working directory.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVESTATE_DIRECTORY, - "Save all save states to this directory. If not set, will try to save inside the content file's working directory.") -MSG_HASH(MENU_ENUM_SUBLABEL_SCREENSHOT_DIRECTORY, - "Directory to dump screenshots to.") -MSG_HASH(MENU_ENUM_SUBLABEL_OVERLAY_DIRECTORY, - "Defines a directory where overlays are kept for easy access.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_DATABASE_PATH, - "Cheat files are kept here." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_FILTER_DIR, - "Directory where audio DSP filter files are kept." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_FILTER_DIR, - "Directory where CPU-based video filter files are kept." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_DIR, - "Defines a directory where GPU-based video shader files are kept for easy access.") -MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_OUTPUT_DIRECTORY, - "Recordings will be dumped to this directory.") -MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_CONFIG_DIRECTORY, - "Recording configurations will be kept here.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_PATH, - "Select a different font for onscreen notifications.") -MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_APPLY_CHANGES, - "Changes to the shader configuration will take effect immediately. Use this if you changed the amount of shader passes, filtering, FBO scale, etc.") -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHADER_NUM_PASSES, - "Increase or decrease the amount of shader pipeline passes. You can bind a separate shader to each pipeline pass and configure its scale and filtering." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET, - "Load a shader preset. The shader pipeline will be automatically set-up.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_AS, - "Save the current shader settings as a new shader preset.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_CORE, - "Save the current shader settings as the default settings for this application/core.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_PARENT, - "Save the current shader settings as the default settings for all files in the current content directory.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_GAME, - "Save the current shader settings as the default settings for the content.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PARAMETERS, - "Modifies the current shader directly. Changes will not be saved to the preset file.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_PARAMETERS, - "Modifies the shader preset itself currently used in the menu.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_NUM_PASSES, - "Increase or decrease the amount of cheats." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_CHEAT_APPLY_CHANGES, - "Cheat changes will take effect immediately.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEAT_START_SEARCH, - "Start search for a new cheat. Number of bits can be changed.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEAT_CONTINUE_SEARCH, - "Continue search for a new cheat.") -MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD, - "Load a cheat file and replace existing cheats." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD_APPEND, - "Load a cheat file and append to existing cheats." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_CHEAT_FILE_SAVE_AS, - "Save current cheats as a save file." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SETTINGS, - "Quickly access all relevant in-game settings.") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_INFORMATION, - "View information pertaining to the application/core.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_ASPECT_RATIO, - "Floating point value for video aspect ratio (width / height), used if the Aspect Ratio is set to 'Config'.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT, - "Custom viewport height that is used if the Aspect Ratio is set to 'Custom'.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH, - "Custom viewport width that is used if the Aspect Ratio is set to 'Custom'.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_X, - "Custom viewport offset used for defining the X-axis position of the viewport. These are ignored if 'Integer Scale' is enabled. It will be automatically centered then.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_Y, - "Custom viewport offset used for defining the Y-axis position of the viewport. These are ignored if 'Integer Scale' is enabled. It will be automatically centered then.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_USE_MITM_SERVER, - "Use Relay Server") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, - "Forward netplay connections through a man-in-the-middle server. Useful if the host is behind a firewall or has NAT/UPnP problems.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MITM_SERVER, - "Relay Server Location") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_MITM_SERVER, - "Choose a specific relay server to use. Geographically closer locations tend to have lower latency.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, - "Add to mixer") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_PLAY, - "Add to mixer and play") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION, - "Add to mixer") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY, - "Add to mixer and play") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER_BY_CURRENT_CORE, - "Filter by current core") -MSG_HASH( - MSG_AUDIO_MIXER_VOLUME, - "Global audio mixer volume" - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_MIXER_VOLUME, - "Global audio mixer volume (in dB). 0 dB is normal volume, and no gain is applied." - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_VOLUME, - "Audio Mixer Volume Level (dB)" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_MUTE, - "Audio Mixer Mute" - ) -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MIXER_MUTE, - "Mute/unmute mixer audio.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_ONLINE_UPDATER, - "Show Online Updater") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_ONLINE_UPDATER, - "Show/hide the 'Online Updater' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_VIEWS_SETTINGS, - "Views") -MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_VIEWS_SETTINGS, - "Show or hide elements on the menu screen." - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_CORE_UPDATER, - "Show Core Updater") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_CORE_UPDATER, - "Show/hide the ability to update cores (and core info files).") -MSG_HASH(MSG_PREPARING_FOR_CONTENT_SCAN, - "Preparing for content scan...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_DELETE, - "Delete core") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_DELETE, - "Remove this core from disk.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FRAMEBUFFER_OPACITY, - "Framebuffer Opacity") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_FRAMEBUFFER_OPACITY, - "Modify the opacity of the framebuffer.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES, - "Favorites") -MSG_HASH(MENU_ENUM_SUBLABEL_GOTO_FAVORITES, - "Content which you have added to 'Favorites' will appear here.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GOTO_MUSIC, - "Music") -MSG_HASH(MENU_ENUM_SUBLABEL_GOTO_MUSIC, - "Music which has been previously played will appear here.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GOTO_IMAGES, - "Image") -MSG_HASH(MENU_ENUM_SUBLABEL_GOTO_IMAGES, - "Images which have been previously viewed will appear here.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GOTO_VIDEO, - "Video") -MSG_HASH(MENU_ENUM_SUBLABEL_GOTO_VIDEO, - "Videos which have been previously played will appear here.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_ICONS_ENABLE, - "Menu Icons") -MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_ICONS_ENABLE, - "Enable/disable the menu icons shown at the lefthand side of the menu entries.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MAIN_MENU_ENABLE_SETTINGS, - "Enable Settings Tab") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS_PASSWORD, - "Set Password For Enabling Settings Tab") -MSG_HASH(MSG_INPUT_ENABLE_SETTINGS_PASSWORD, - "Enter Password") -MSG_HASH(MSG_INPUT_ENABLE_SETTINGS_PASSWORD_OK, - "Password correct.") -MSG_HASH(MSG_INPUT_ENABLE_SETTINGS_PASSWORD_NOK, - "Password incorrect.") -MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, - "Enables the Settings tab. A restart is required for the tab to appear.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, - "Supplying a password when hiding the settings tab makes it possible to later restore it from the menu, by going to the Main Menu tab, selecting Enable Settings Tab and entering the password.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, - "Allow the user to rename entries in collections.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, - "Allow to rename entries") -MSG_HASH(MENU_ENUM_SUBLABEL_RENAME_ENTRY, - "Rename the title of the entry.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RENAME_ENTRY, - "Rename") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, - "Show Load Core") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CORE, - "Show/hide the 'Load Core' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CONTENT, - "Show Load Content") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CONTENT, - "Show/hide the 'Load Content' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_INFORMATION, - "Show Information") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_INFORMATION, - "Show/hide the 'Information' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_CONFIGURATIONS, - "Show Configurations") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_CONFIGURATIONS, - "Show/hide the 'Configurations' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_HELP, - "Show Help") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_HELP, - "Show/hide the 'Help' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_QUIT_RETROARCH, - "Show Quit RetroArch") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_QUIT_RETROARCH, - "Show/hide the 'Quit RetroArch' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_REBOOT, - "Show Reboot") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_REBOOT, - "Show/hide the 'Reboot' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_SHUTDOWN, - "Show Shutdown") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_SHUTDOWN, - "Show/hide the 'Shutdown' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_VIEWS_SETTINGS, - "Quick Menu") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_VIEWS_SETTINGS, - "Show or hide elements on the Quick Menu screen.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_TAKE_SCREENSHOT, - "Show Take Screenshot") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT, - "Show/hide the 'Take Screenshot' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_LOAD_STATE, - "Show Save/Load State") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE, - "Show/hide the options for saving/loading state.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, - "Show Undo Save/Load State") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, - "Show/hide the options for undoing save/load state.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_ADD_TO_FAVORITES, - "Show Add to Favorites") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, - "Show/hide the 'Add to Favorites' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_OPTIONS, - "Show Options") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_OPTIONS, - "Show/hide the 'Options' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CONTROLS, - "Show Controls") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CONTROLS, - "Show/hide the 'Controls' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CHEATS, - "Show Cheats") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CHEATS, - "Show/hide the 'Cheats' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SHADERS, - "Show Shaders") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SHADERS, - "Show/hide the 'Shaders' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, - "Show Save Core Overrides") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, - "Show/hide the 'Save Core Overrides' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, - "Show Save Game Overrides") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, - "Show/hide the 'Save Game Overrides' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_INFORMATION, - "Show Information") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_INFORMATION, - "Show/hide the 'Information' option.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_ENABLE, - "Notification Background Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_RED, - "Notification Background Red Color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_GREEN, - "Notification Background Green Color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_BLUE, - "Notification Background Blue Color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_OPACITY, - "Notification Background Opacity") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DISABLE_KIOSK_MODE, - "Disable Kiosk Mode") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_DISABLE_KIOSK_MODE, - "Disables kiosk mode. A restart is required for the change to take full effect.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_ENABLE_KIOSK_MODE, - "Enable Kiosk Mode") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENABLE_KIOSK_MODE, - "Protects the setup by hiding all configuration related settings.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_KIOSK_MODE_PASSWORD, - "Set Password For Disabling Kiosk Mode") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_KIOSK_MODE_PASSWORD, - "Supplying a password when enabling kiosk mode makes it possible to later disable it from the menu, by going to the Main Menu, selecting Disable Kiosk Mode and entering the password.") -MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD, - "Enter Password") -MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, - "Password correct.") -MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, - "Password incorrect.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_RED, - "Notification Red Color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_GREEN, - "Notification Green Color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_BLUE, - "Notification Blue Color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAMECOUNT_SHOW, - "Show frame count on FPS display") -MSG_HASH(MSG_CONFIG_OVERRIDE_LOADED, - "Configuration override loaded.") -MSG_HASH(MSG_GAME_REMAP_FILE_LOADED, - "Game remap file loaded.") -MSG_HASH(MSG_CORE_REMAP_FILE_LOADED, - "Core remap file loaded.") -MSG_HASH(MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES, - "RunAhead has been disabled because this core does not support save states.") -MSG_HASH(MSG_RUNAHEAD_FAILED_TO_SAVE_STATE, - "Failed to save state. RunAhead has been disabled.") -MSG_HASH(MSG_RUNAHEAD_FAILED_TO_LOAD_STATE, - "Failed to load state. RunAhead has been disabled.") -MSG_HASH(MSG_RUNAHEAD_FAILED_TO_CREATE_SECONDARY_INSTANCE, - "Failed to create second instance. RunAhead will now use only one instance.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, - "Automatically add content to playlist") -MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, - "Automatically scans loaded content so they appear inside playlists.") -MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, - "Scanning of file finished") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_OPACITY, - "Window Opacity") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY, - "Audio Resampler Quality") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, - "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_WATCH_FOR_CHANGES, - "Watch shader files for changes") -MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_WATCH_FOR_CHANGES, - "Auto-apply changes made to shader files on disk.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_SHOW_DECORATIONS, - "Show Window Decorations") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STATISTICS_SHOW, - "Display Statistics") -MSG_HASH(MENU_ENUM_SUBLABEL_STATISTICS_SHOW, - "Show onscreen technical statistics.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_ENABLE, - "Enable border filler") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, - "Enable border filler thickness") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, - "Enable background filler thickness") -MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, - "For 15 kHz CRT displays only. Attempts to use exact core/game resolution and refresh rate.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, - "CRT SwitchRes") -MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, - "When CRT SwitchRes is enabled, force ultrawide horizontal resolution to minimize mode switching.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, - "CRT Super Resolution") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, - "Show Rewind Settings") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, - "Show/hide the Rewind options.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_LATENCY, - "Show/hide the Latency options.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_LATENCY, - "Show Latency Settings") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_OVERLAYS, - "Show/hide the Overlay options.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_OVERLAYS, - "Show Overlay Settings") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE_MENU, - "Enable menu audio") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_ENABLE_MENU, - "Enable or disable menu sound.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_SETTINGS, - "Mixer Settings") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MIXER_SETTINGS, - "View and/or modify audio mixer settings.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_INFO, - "Info") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_FILE, - "&File") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_LOAD_CORE, - "&Load Core...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_UNLOAD_CORE, - "&Unload Core") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_EXIT, - "E&xit") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT, - "&Edit") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT_SEARCH, - "&Search") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW, - "&View") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_CLOSED_DOCKS, - "Closed Docks") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS, - "&Options...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS, - "Remember dock positions:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY, - "Remember window geometry:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB, - "Remember last content browser tab:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME, - "Theme:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_SYSTEM_DEFAULT, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK, - "Dark") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM, - "Custom...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE, - "Options") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_TOOLS, - "&Tools") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_HELP, - "&Help") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_ABOUT, - "About RetroArch") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_DOCUMENTATION, - "Documentation") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOAD_CUSTOM_CORE, - "Load Custom Core...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOAD_CORE, - "Load Core") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOADING_CORE, - "Loading Core...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_NAME, - "Name") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE_VERSION, - "Version") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_TAB_PLAYLISTS, - "Playlists") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER, - "File Browser") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_TOP, - "Top") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_UP, - "Up") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_DOCK_CONTENT_BROWSER, - "Content Browser") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_BOXART, - "Boxart") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_SCREENSHOT, - "Screenshot") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_TITLE_SCREEN, - "Title Screen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ALL_PLAYLISTS, - "All Playlists") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE, - "Core") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE_INFO, - "Core Info") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE_SELECTION_ASK, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_INFORMATION, - "Information") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_WARNING, - "Warning") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ERROR, - "Error") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR, - "Network Error") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_RESTART_TO_TAKE_EFFECT, - "Please restart the program for the changes to take effect.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOG, - "Log") + MENU_ENUM_SUBLABEL_OVERLAY_OPACITY, + "Opacity of all UI elements of the overlay." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_OVERLAY_SCALE, + "Scale of all UI elements of the overlay." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_ENABLE, + "Enable the overlay." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_OVERLAY_PRESET, + "Select an overlay from the file browser." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_IP_ADDRESS, + "The address of the host to connect to." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_TCP_UDP_PORT, + "The port of the host IP address. Can be either a TCP or UDP port." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_PASSWORD, + "The password for connecting to the netplay host. Used only in host mode." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_PUBLIC_ANNOUNCE, + "Whether to announce netplay games publicly. If unset, clients must manually connect rather than using the public lobby." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_SPECTATE_PASSWORD, + "The password for connecting to the netplay host with only spectator privileges. Used only in host mode." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_START_AS_SPECTATOR, + "Whether to start netplay in spectator mode." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_ALLOW_SLAVES, + "Whether to allow connections in slave mode. Slave-mode clients require very little processing power on either side, but will suffer significantly from network latency." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_REQUIRE_SLAVES, + "Whether to disallow connections not in slave mode. Not recommended except for very fast networks with very weak machines." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_STATELESS_MODE, + "Whether to run netplay in a mode not requiring save states. If set to true, a very fast network is required, but no rewinding is performed, so there will be no netplay jitter." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_CHECK_FRAMES, + "The frequency in frames with which netplay will verify that the host and client are in sync." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_NAT_TRAVERSAL, + "When hosting, attempt to listen for connections from the public Internet, using UPnP or similar technologies to escape LANs." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_STDIN_CMD_ENABLE, + "Enable stdin command interface." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MOUSE_ENABLE, + "Enable mouse controls inside the menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_POINTER_ENABLE, + "Enable touch controls inside the menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_THUMBNAILS, + "Type of thumbnail to display." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS, + "Type of thumbnail to display at the left." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_VERTICAL_THUMBNAILS, + "Display the left thumbnail under the right one, on the right side of the screen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_TIMEDATE_ENABLE, + "Shows current date and/or time inside the menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_BATTERY_LEVEL_ENABLE, + "Shows current battery level inside the menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NAVIGATION_WRAPAROUND, + "Wrap-around to beginning and/or end if boundary of list is reached horizontally or vertically." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_HOST, + "Enables netplay in host (server) mode." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, + "Enables netplay in client mode." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, + "Disconnects an active Netplay connection." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, + "Scans a directory for compatible files and add them to the collection." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SCAN_FILE, + "Scans a compatible file and add it to the collection." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, + "Uses a custom swap interval for Vsync. Set this to effectively halve monitor refresh rate." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE, + "Sort save files in folders named after the core used." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE, + "Sort save states in folders named after the core used." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_REQUEST_DEVICE_I, + "Request to play with the given input device." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL, + "URL to core updater directory on the Libretro buildbot." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL, + "URL to assets updater directory on the Libretro buildbot." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, + "After downloading, automatically extract files contained in the downloaded archives." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, + "Scan for new rooms." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DELETE_ENTRY, + "Remove this entry from the collection." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INFORMATION, + "View more information about the content." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, + "Add the entry to your favorites." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES_PLAYLIST, + "Add the entry to your favorites." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RUN, + "Start the content." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_FILE_BROWSER_SETTINGS, + "Adjusts filebrowser settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUTO_REMAPS_ENABLE, + "Enable customized controls by default at startup." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUTO_OVERRIDES_ENABLE, + "Enable customized configuration by default at startup." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_GAME_SPECIFIC_OPTIONS, + "Enable customized core options by default at startup." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_ENABLE, + "Shows current core name inside menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DATABASE_MANAGER, + "View databases." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CURSOR_MANAGER, + "View previous searches." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_TAKE_SCREENSHOT, + "Captures an image of the screen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CLOSE_CONTENT, + "Closes the current content. Any unsaved changes might be lost." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOAD_STATE, + "Load a saved state from the currently selected slot." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVE_STATE, + "Save a state to the currently selected slot." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RESUME, + "Resume the currently running content and leave the Quick Menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RESUME_CONTENT, + "Resume the currently running content and leave the Quick Menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_STATE_SLOT, + "Changes the currently selected state slot." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_UNDO_LOAD_STATE, + "If a state was loaded, content will go back to the state prior to loading." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_UNDO_SAVE_STATE, + "If a state was overwritten, it will roll back to the previous save state." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, + "RetroAchievements service. For more information, visit http://retroachievements.org" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ACCOUNTS_LIST, + "Manages currently configured accounts." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_REWIND, + "Manages rewind settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_DETAILS, + "Manages cheat details settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_CHEAT_SEARCH, + "Start or continue a cheat code search." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RESTART_CONTENT, + "Restarts the content from the beginning." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, + "Saves an override configuration file which will apply for all content loaded with this core. Will take precedence over the main configuration." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, + "Saves an override configuration file which will apply for all content loaded from the same directory as the current file. Will take precedence over the main configuration." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, + "Saves an override configuration file which will apply for the current content only. Will take precedence over the main configuration." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_CHEAT_OPTIONS, + "Set up cheat codes." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHADER_OPTIONS, + "Set up shaders to visually augment the image." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_INPUT_REMAPPING_OPTIONS, + "Change the controls for the currently running content." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_OPTIONS, + "Change the options for the currently running content." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, + "Show advanced settings for power users (hidden by default)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, + "Perform tasks on a separate thread." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, + "Allow the user to remove entries from collections." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, + "Sets the System directory. Cores can query for this directory to load BIOSes, system-specific configs, etc." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, + "Sets start directory for the filebrowser." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_DIR, + "Usually set by developers who bundle libretro/RetroArch apps to point to assets." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPERS_DIRECTORY, + "Directory to store wallpapers dynamically loaded by the menu depending on context." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_THUMBNAILS_DIRECTORY, + "Supplementary thumbnails (boxarts/misc. images, etc.) are stored here." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RGUI_CONFIG_DIRECTORY, + "Sets start directory for menu configuration browser." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, + "The number of frames of input latency for netplay to use to hide network latency. Reduces jitter and makes netplay less CPU-intensive, at the expense of noticeable input lag." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, + "The range of frames of input latency that may be used to hide network latency. Reduces jitter and makes netplay less CPU-intensive, at the expense of unpredictable input lag." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DISK_CYCLE_TRAY_STATUS, + "Cycle the current disk. If the disk is inserted, it will eject the disk. If the disk has not been inserted, it will be inserted. " + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DISK_INDEX, + "Change the disk index." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DISK_OPTIONS, + "Disk image management." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, + "Select a disk image to insert." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, + "Makes sure the framerate is capped while inside the menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VRR_RUNLOOP_ENABLE, + "No deviation from core requested timing. Use for Variable Refresh Rate screens, G-Sync, FreeSync." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_LAYOUT, + "Select a different layout for the XMB interface." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_THEME, + "Select a different theme for the icon. Changes will take effect after you restart the program." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, + "Enable drop shadows for all icons. This will have a minor performance hit." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MATERIALUI_MENU_COLOR_THEME, + "Select a different background color gradient theme." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_WALLPAPER_OPACITY, + "Modify the opacity of the background wallpaper." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_MENU_COLOR_THEME, + "Select a different background color gradient theme." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_RIBBON_ENABLE, + "Select an animated background effect. Can be GPU-intensive depending on the effect. If performance is unsatisfactory, either turn this off or revert to a simpler effect." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_FONT, + "Select a different main font to be used by the menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_FAVORITES, + "Show the favorites tab inside the main menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_IMAGES, + "Show the image tab inside the main menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_MUSIC, + "Show the music tab inside the main menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_VIDEO, + "Show the video tab inside the main menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_NETPLAY, + "Show the netplay tab inside the main menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS, + "Show the settings tab inside the main menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_HISTORY, + "Show the recent history tab inside the main menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_ADD, + "Show the import content tab inside the main menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_PLAYLISTS, + "Show playlist tabs inside the main menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN, + "Show startup screen in menu. This is automatically set to false after the program starts for the first time." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY, + "Modify the opacity of the header graphic." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MATERIALUI_MENU_FOOTER_OPACITY, + "Modify the opacity of the footer graphic." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DPI_OVERRIDE_ENABLE, + "The menu normally scales itself dynamically. If you want to set a specific scaling size instead, enable this." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DPI_OVERRIDE_VALUE, + "Set the custom scaling size here. NOTE: You have to enable 'DPI Override' for this scaling size to take effect." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_ASSETS_DIRECTORY, + "Save all downloaded files to this directory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_REMAPPING_DIRECTORY, + "Save all remapped controls to this directory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LIBRETRO_DIR_PATH, + "Directory where the program searches for content/cores." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, + "Application/core information files are stored here." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, + "If a joypad is plugged in, that joypad will be autoconfigured if a config file corresponding to it is present inside this directory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, + "Save all collections to this directory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, + "If set to a directory, content which is temporarily extracted (e.g. from archives) will be extracted to this directory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CURSOR_DIRECTORY, + "Saved queries are stored to this directory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_DATABASE_DIRECTORY, + "Databases are stored to this directory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ASSETS_DIRECTORY, + "This location is queried by default when menu interfaces try to look for loadable assets, etc." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVEFILE_DIRECTORY, + "Save all save files to this directory. If not set, will try to save inside the content file's working directory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVESTATE_DIRECTORY, + "Save all save states to this directory. If not set, will try to save inside the content file's working directory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SCREENSHOT_DIRECTORY, + "Directory to dump screenshots to." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_OVERLAY_DIRECTORY, + "Defines a directory where overlays are kept for easy access." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_DATABASE_PATH, + "Cheat files are kept here." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_FILTER_DIR, + "Directory where audio DSP filter files are kept." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FILTER_DIR, + "Directory where CPU-based video filter files are kept." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_DIR, + "Defines a directory where GPU-based video shader files are kept for easy access." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RECORDING_OUTPUT_DIRECTORY, + "Recordings will be dumped to this directory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RECORDING_CONFIG_DIRECTORY, + "Recording configurations will be kept here." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FONT_PATH, + "Select a different font for onscreen notifications." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHADER_APPLY_CHANGES, + "Changes to the shader configuration will take effect immediately. Use this if you changed the amount of shader passes, filtering, FBO scale, etc." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_NUM_PASSES, + "Increase or decrease the amount of shader pipeline passes. You can bind a separate shader to each pipeline pass and configure its scale and filtering." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET, + "Load a shader preset. The shader pipeline will be automatically set-up." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_AS, + "Save the current shader settings as a new shader preset." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_CORE, + "Save the current shader settings as the default settings for this application/core." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_PARENT, + "Save the current shader settings as the default settings for all files in the current content directory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_GAME, + "Save the current shader settings as the default settings for the content." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PARAMETERS, + "Modifies the current shader directly. Changes will not be saved to the preset file." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_PARAMETERS, + "Modifies the shader preset itself currently used in the menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_NUM_PASSES, + "Increase or decrease the amount of cheats." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_APPLY_CHANGES, + "Cheat changes will take effect immediately." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_START_SEARCH, + "Start search for a new cheat. Number of bits can be changed." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_CONTINUE_SEARCH, + "Continue search for a new cheat." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD, + "Load a cheat file and replace existing cheats." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD_APPEND, + "Load a cheat file and append to existing cheats." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_FILE_SAVE_AS, + "Save current cheats as a save file." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SETTINGS, + "Quickly access all relevant in-game settings." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_INFORMATION, + "View information pertaining to the application/core." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_ASPECT_RATIO, + "Floating point value for video aspect ratio (width / height), used if the Aspect Ratio is set to 'Config'." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT, + "Custom viewport height that is used if the Aspect Ratio is set to 'Custom'." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH, + "Custom viewport width that is used if the Aspect Ratio is set to 'Custom'." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_X, + "Custom viewport offset used for defining the X-axis position of the viewport. These are ignored if 'Integer Scale' is enabled. It will be automatically centered then." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_Y, + "Custom viewport offset used for defining the Y-axis position of the viewport. These are ignored if 'Integer Scale' is enabled. It will be automatically centered then." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_USE_MITM_SERVER, + "Use Relay Server" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, + "Forward netplay connections through a man-in-the-middle server. Useful if the host is behind a firewall or has NAT/UPnP problems." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_MITM_SERVER, + "Relay Server Location" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_MITM_SERVER, + "Choose a specific relay server to use. Geographically closer locations tend to have lower latency." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, + "Add to mixer" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_PLAY, + "Add to mixer and play" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION, + "Add to mixer" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY, + "Add to mixer and play" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FILTER_BY_CURRENT_CORE, + "Filter by current core" + ) +MSG_HASH( + MSG_AUDIO_MIXER_VOLUME, + "Global audio mixer volume" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_MIXER_VOLUME, + "Global audio mixer volume (in dB). 0 dB is normal volume, and no gain is applied." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_VOLUME, + "Audio Mixer Volume Level (dB)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_MUTE, + "Audio Mixer Mute" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_MIXER_MUTE, + "Mute/unmute mixer audio." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_ONLINE_UPDATER, + "Show Online Updater" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_ONLINE_UPDATER, + "Show/hide the 'Online Updater' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_VIEWS_SETTINGS, + "Views" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_VIEWS_SETTINGS, + "Show or hide elements on the menu screen." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_CORE_UPDATER, + "Show Core Updater" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_CORE_UPDATER, + "Show/hide the ability to update cores (and core info files)." + ) +MSG_HASH( + MSG_PREPARING_FOR_CONTENT_SCAN, + "Preparing for content scan..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CORE_DELETE, + "Delete core" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CORE_DELETE, + "Remove this core from disk." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_FRAMEBUFFER_OPACITY, + "Framebuffer Opacity" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_FRAMEBUFFER_OPACITY, + "Modify the opacity of the framebuffer." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES, + "Favorites" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_GOTO_FAVORITES, + "Content which you have added to 'Favorites' will appear here." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GOTO_MUSIC, + "Music" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_GOTO_MUSIC, + "Music which has been previously played will appear here." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GOTO_IMAGES, + "Image" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_GOTO_IMAGES, + "Images which have been previously viewed will appear here." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_GOTO_VIDEO, + "Video" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_GOTO_VIDEO, + "Videos which have been previously played will appear here." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MATERIALUI_ICONS_ENABLE, + "Menu Icons" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MATERIALUI_ICONS_ENABLE, + "Enable/disable the menu icons shown at the lefthand side of the menu entries." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_XMB_MAIN_MENU_ENABLE_SETTINGS, + "Enable Settings Tab" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS_PASSWORD, + "Set Password For Enabling Settings Tab" + ) +MSG_HASH( + MSG_INPUT_ENABLE_SETTINGS_PASSWORD, + "Enter Password" + ) +MSG_HASH( + MSG_INPUT_ENABLE_SETTINGS_PASSWORD_OK, + "Password correct." + ) +MSG_HASH( + MSG_INPUT_ENABLE_SETTINGS_PASSWORD_NOK, + "Password incorrect." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, + "Enables the Settings tab. A restart is required for the tab to appear." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD, + "Supplying a password when hiding the settings tab makes it possible to later restore it from the menu, by going to the Main Menu tab, selecting Enable Settings Tab and entering the password." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_RENAME, + "Allow the user to rename entries in collections." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, + "Allow to rename entries" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RENAME_ENTRY, + "Rename the title of the entry." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_RENAME_ENTRY, + "Rename" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CORE, + "Show Load Core" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CORE, + "Show/hide the 'Load Core' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CONTENT, + "Show Load Content" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CONTENT, + "Show/hide the 'Load Content' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_INFORMATION, + "Show Information" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_INFORMATION, + "Show/hide the 'Information' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_CONFIGURATIONS, + "Show Configurations" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_CONFIGURATIONS, + "Show/hide the 'Configurations' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_HELP, + "Show Help" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_HELP, + "Show/hide the 'Help' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_QUIT_RETROARCH, + "Show Quit RetroArch" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_QUIT_RETROARCH, + "Show/hide the 'Quit RetroArch' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_REBOOT, + "Show Reboot" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_REBOOT, + "Show/hide the 'Reboot' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_SHOW_SHUTDOWN, + "Show Shutdown" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SHOW_SHUTDOWN, + "Show/hide the 'Shutdown' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_VIEWS_SETTINGS, + "Quick Menu" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_VIEWS_SETTINGS, + "Show or hide elements on the Quick Menu screen." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_TAKE_SCREENSHOT, + "Show Take Screenshot" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT, + "Show/hide the 'Take Screenshot' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_LOAD_STATE, + "Show Save/Load State" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE, + "Show/hide the options for saving/loading state." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, + "Show Undo Save/Load State" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, + "Show/hide the options for undoing save/load state." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_ADD_TO_FAVORITES, + "Show Add to Favorites" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, + "Show/hide the 'Add to Favorites' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_OPTIONS, + "Show Options" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_OPTIONS, + "Show/hide the 'Options' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CONTROLS, + "Show Controls" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CONTROLS, + "Show/hide the 'Controls' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CHEATS, + "Show Cheats" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CHEATS, + "Show/hide the 'Cheats' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SHADERS, + "Show Shaders" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SHADERS, + "Show/hide the 'Shaders' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, + "Show Save Core Overrides" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, + "Show/hide the 'Save Core Overrides' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, + "Show Save Game Overrides" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES, + "Show/hide the 'Save Game Overrides' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_INFORMATION, + "Show Information" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_INFORMATION, + "Show/hide the 'Information' option." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_ENABLE, + "Notification Background Enable" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_RED, + "Notification Background Red Color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_GREEN, + "Notification Background Green Color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_BLUE, + "Notification Background Blue Color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_OPACITY, + "Notification Background Opacity" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_DISABLE_KIOSK_MODE, + "Disable Kiosk Mode" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_DISABLE_KIOSK_MODE, + "Disables kiosk mode. A restart is required for the change to take full effect." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_ENABLE_KIOSK_MODE, + "Enable Kiosk Mode" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_ENABLE_KIOSK_MODE, + "Protects the setup by hiding all configuration related settings." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_KIOSK_MODE_PASSWORD, + "Set Password For Disabling Kiosk Mode" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_KIOSK_MODE_PASSWORD, + "Supplying a password when enabling kiosk mode makes it possible to later disable it from the menu, by going to the Main Menu, selecting Disable Kiosk Mode and entering the password." + ) +MSG_HASH( + MSG_INPUT_KIOSK_MODE_PASSWORD, + "Enter Password" + ) +MSG_HASH( + MSG_INPUT_KIOSK_MODE_PASSWORD_OK, + "Password correct." + ) +MSG_HASH( + MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, + "Password incorrect." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_RED, + "Notification Red Color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_GREEN, + "Notification Green Color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_BLUE, + "Notification Blue Color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_FRAMECOUNT_SHOW, + "Show frame count on FPS display" + ) +MSG_HASH( + MSG_CONFIG_OVERRIDE_LOADED, + "Configuration override loaded." + ) +MSG_HASH( + MSG_GAME_REMAP_FILE_LOADED, + "Game remap file loaded." + ) +MSG_HASH( + MSG_CORE_REMAP_FILE_LOADED, + "Core remap file loaded." + ) +MSG_HASH( + MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES, + "RunAhead has been disabled because this core does not support save states." + ) +MSG_HASH( + MSG_RUNAHEAD_FAILED_TO_SAVE_STATE, + "Failed to save state. RunAhead has been disabled." + ) +MSG_HASH( + MSG_RUNAHEAD_FAILED_TO_LOAD_STATE, + "Failed to load state. RunAhead has been disabled." + ) +MSG_HASH( + MSG_RUNAHEAD_FAILED_TO_CREATE_SECONDARY_INSTANCE, + "Failed to create second instance. RunAhead will now use only one instance." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists." + ) +MSG_HASH( + MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_OPACITY, + "Window Opacity" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY, + "Audio Resampler Quality" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, + "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SHADER_WATCH_FOR_CHANGES, + "Watch shader files for changes" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SHADER_WATCH_FOR_CHANGES, + "Auto-apply changes made to shader files on disk." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_SHOW_DECORATIONS, + "Show Window Decorations" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_STATISTICS_SHOW, + "Display Statistics" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_STATISTICS_SHOW, + "Show onscreen technical statistics." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_ENABLE, + "Enable border filler" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, + "Enable border filler thickness" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, + "Enable background filler thickness" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, + "For 15 kHz CRT displays only. Attempts to use exact core/game resolution and refresh rate." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, + "CRT SwitchRes" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, + "When CRT SwitchRes is enabled, force ultrawide horizontal resolution to minimize mode switching." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, + "CRT Super Resolution" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, + "Show Rewind Settings" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, + "Show/hide the Rewind options." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_LATENCY, + "Show/hide the Latency options." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_LATENCY, + "Show Latency Settings" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_SHOW_OVERLAYS, + "Show/hide the Overlay options." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_OVERLAYS, + "Show Overlay Settings" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE_MENU, + "Enable menu audio" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_ENABLE_MENU, + "Enable or disable menu sound." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_SETTINGS, + "Mixer Settings" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_MIXER_SETTINGS, + "View and/or modify audio mixer settings." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_INFO, + "Info" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE, + "&File" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_LOAD_CORE, + "&Load Core..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_UNLOAD_CORE, + "&Unload Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_EXIT, + "E&xit" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT, + "&Edit" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT_SEARCH, + "&Search" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW, + "&View" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_CLOSED_DOCKS, + "Closed Docks" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_SHADER_PARAMS, + "Shader Parameters" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS, + "&Options..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS, + "Remember dock positions:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY, + "Remember window geometry:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB, + "Remember last content browser tab:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME, + "Theme:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_SYSTEM_DEFAULT, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK, + "Dark" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM, + "Custom..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE, + "Options" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_TOOLS, + "&Tools" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP, + "&Help" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_ABOUT, + "About RetroArch" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_DOCUMENTATION, + "Documentation" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOAD_CUSTOM_CORE, + "Load Custom Core..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOAD_CORE, + "Load Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOADING_CORE, + "Loading Core..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_NAME, + "Name" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE_VERSION, + "Version" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_TAB_PLAYLISTS, + "Playlists" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER, + "File Browser" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_TOP, + "Top" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_UP, + "Up" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_DOCK_CONTENT_BROWSER, + "Content Browser" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_BOXART, + "Boxart" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_SCREENSHOT, + "Screenshot" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_TITLE_SCREEN, + "Title Screen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ALL_PLAYLISTS, + "All Playlists" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE, + "Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE_INFO, + "Core Info" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE_SELECTION_ASK, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_INFORMATION, + "Information" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_WARNING, + "Warning" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ERROR, + "Error" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR, + "Network Error" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESTART_TO_TAKE_EFFECT, + "Please restart the program for the changes to take effect." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOG, + "Log" + ) #ifdef HAVE_QT -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SCAN_FINISHED, - "Scan Finished.

\n" - "In order for content to be correctly scanned, you must:\n" - "
  • have a compatible core already downloaded
  • \n" - "
  • have \"Core Info Files\" updated via Online Updater
  • \n" - "
  • have \"Databases\" updated via Online Updater
  • \n" - "
  • restart RetroArch if any of the above was just done
\n" - "Finally, the content must match existing databases from here. If it is still not working, consider submitting a bug report.") +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SCAN_FINISHED, + "Scan Finished.

\n" + "In order for content to be correctly scanned, you must:\n" + "
  • have a compatible core already downloaded
  • \n" + "
  • have \"Core Info Files\" updated via Online Updater
  • \n" + "
  • have \"Databases\" updated via Online Updater
  • \n" + "
  • restart RetroArch if any of the above was just done
\n" + "Finally, the content must match existing databases from here. If it is still not working, consider submitting a bug report." + ) #endif -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, - "Don't show this again") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_STOP, - "Stop") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE, - "Associate Core") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS, - "Hidden Playlists") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_HIDE, - "Hide") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_HIGHLIGHT_COLOR, - "Highlight color:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CHOOSE, - "&Choose...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SELECT_COLOR, - "Select Color") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SELECT_THEME, - "Select Theme") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CUSTOM_THEME, - "Custom Theme") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_PATH_IS_BLANK, - "File path is blank.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_IS_EMPTY, - "File is empty.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_READ_OPEN_FAILED, - "Could not open file for reading.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_WRITE_OPEN_FAILED, - "Could not open file for writing.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST, - "File does not exist.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SUGGEST_LOADED_CORE_FIRST, - "Suggest loaded core first:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ZOOM, - "Zoom") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_VIEW, - "View") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_ICONS, - "Icons") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_LIST, - "List") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS, - "Overrides") -MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_OVERRIDE_OPTIONS, - "Options for overriding the global configuration.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY, - "Will start playback of the audio stream. Once finished, it will remove the current audio stream from memory.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_LOOPED, - "Will start playback of the audio stream. Once finished, it will loop and play the track again from the beginning.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_SEQUENTIAL, - "Will start playback of the audio stream. Once finished, it will jump to the next audio stream in sequential order and repeat this behavior. Useful as an album playback mode.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_STOP, - "This will stop playback of the audio stream, but not remove it from memory. You can start playing it again by selecting 'Play'.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_REMOVE, - "This will stop playback of the audio stream and remove it entirely from memory.") -MSG_HASH(MENU_ENUM_SUBLABEL_MIXER_ACTION_VOLUME, - "Adjust the volume of the audio stream.") -MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_MIXER, - "Add this audio track to an available audio stream slot. If no slots are currently available, it will be ignored.") -MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_MIXER_AND_PLAY, - "Add this audio track to an available audio stream slot and play it. If no slots are currently available, it will be ignored.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY, - "Play") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_LOOPED, - "Play (Looped)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_SEQUENTIAL, - "Play (Sequential)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_STOP, - "Stop") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_REMOVE, - "Remove") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_VOLUME, - "Volume") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DETECT_CORE_LIST_OK_CURRENT_CORE, - "Current core") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, - "Clear") -MSG_HASH(MENU_ENUM_SUBLABEL_ACHIEVEMENT_PAUSE, - "Pause achievements for current session (This action will enable savestates, cheats, rewind, pause, and slow-motion).") -MSG_HASH(MENU_ENUM_SUBLABEL_ACHIEVEMENT_RESUME, - "Resume achievements for current session (This action will disable savestates, cheats, rewind, pause, and slow-motion and reset the current game).") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, - "In-Menu") MSG_HASH( - MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, - "Enable Discord" - ) + MENU_ENUM_LABEL_VALUE_SHOW_WIMP, + "Show Desktop Menu" + ) MSG_HASH( - MENU_ENUM_SUBLABEL_DISCORD_ALLOW, - "Enable or disable Discord support. Will not work with the browser version, only native desktop client." - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIDI_INPUT, - "Input") -MSG_HASH(MENU_ENUM_SUBLABEL_MIDI_INPUT, - "Select input device.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIDI_OUTPUT, - "Output") -MSG_HASH(MENU_ENUM_SUBLABEL_MIDI_OUTPUT, - "Select output device.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MIDI_VOLUME, - "Volume") -MSG_HASH(MENU_ENUM_SUBLABEL_MIDI_VOLUME, - "Set output volume (%).") -MSG_HASH(MENU_ENUM_LABEL_VALUE_POWER_MANAGEMENT_SETTINGS, - "Power Management") -MSG_HASH(MENU_ENUM_SUBLABEL_POWER_MANAGEMENT_SETTINGS, - "Change power management settings.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SUSTAINED_PERFORMANCE_MODE, - "Sustained Performance Mode") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_MPV_SUPPORT, - "mpv support") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_IDX, - "Index") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_MATCH_IDX, - "View Match #") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_MATCH, - "Match Address: %08X Mask: %02X") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_COPY_MATCH, - "Create Code Match #") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_MATCH, - "Delete Match #") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_BROWSE_MEMORY, - "Browse Address: %08X") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DESC, - "Description") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_STATE, - "Enabled") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_CODE, - "Code") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_HANDLER, - "Handler") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_MEMORY_SEARCH_SIZE, - "Memory Search Size") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_TYPE, - "Type") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_VALUE, - "Value") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS, - "Memory Address") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS_BIT_POSITION, - "Memory Address Mask") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_TYPE, - "Rumble When Memory") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_VALUE, - "Rumble Value") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PORT, - "Rumble Port") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_STRENGTH, - "Rumble Primary Strength") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_DURATION, - "Rumble Primary Duration (ms)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_STRENGTH, - "Rumble Secondary Strength") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_DURATION, - "Rumble Secondary Duration (ms)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_AFTER, - "Add New Cheat After This One") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BEFORE, - "Add New Cheat Before This One") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_COPY_AFTER, - "Copy This Cheat After") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_COPY_BEFORE, - "Copy This Cheat Before") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DELETE, - "Delete This Cheat") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_EMU, - "Emulator") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_RETRO, - "RetroArch") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_DISABLED, - "") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_SET_TO_VALUE, - "Set To Value") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_INCREASE_VALUE, - "Increase By Value") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_DECREASE_VALUE, - "Decrease By Value") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_EQ, - "Run next cheat if value = memory") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_NEQ, - "Run next cheat if value != memory") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_LT, - "Run next cheat if value < memory") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_GT, - "Run next cheat if value > memory") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_DISABLED, - "") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_CHANGES, - "Changes") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_DOES_NOT_CHANGE, - "Does Not Change") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_INCREASE, - "Increases") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_DECREASE, - "Decreases") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_EQ_VALUE, - "= Rumble Value") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_NEQ_VALUE, - "!= Rumble Value") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_LT_VALUE, - "< Rumble Value") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_TYPE_GT_VALUE, - "> Rumble Value") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_1, - "1-bit, max value = 0x01") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_2, - "2-bit, max value = 0x03") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_4, - "4-bit, max value = 0x0F") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_8, - "8-bit, max value = 0xFF") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_16, - "16-bit, max value = 0xFFFF") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_32, - "32-bit, max value = 0xFFFFFFFF") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_0, - "1") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_1, - "2") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_2, - "3") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_3, - "4") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_4, - "5") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_5, - "6") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_6, - "7") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_7, - "8") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_8, - "9") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_9, - "10") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_10, - "11") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_11, - "12") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_12, - "13") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_13, - "14") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_14, - "15") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_15, - "16") -MSG_HASH(MENU_ENUM_LABEL_RUMBLE_PORT_16, - "All") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_CONT, - "Start or Continue Cheat Search") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_RESTART, - "Start or Restart Cheat Search") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EXACT, - "Search Memory For Values") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LT, - "Search Memory For Values") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GT, - "Search Memory For Values") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQ, - "Search Memory For Values") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GTE, - "Search Memory For Values") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LTE, - "Search Memory For Values") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_NEQ, - "Search Memory For Values") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQPLUS, - "Search Memory For Values") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQMINUS, - "Search Memory For Values") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_MATCHES, - "Add the %u Matches to Your List") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_VIEW_MATCHES, - "View the List of %u Matches") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_CREATE_OPTION, - "Create Code From This Match") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_OPTION, - "Delete This Match") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_TOP, - "Add New Code to Top") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BOTTOM, - "Add New Code to Bottom") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_ALL, - "Delete All Codes") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_RELOAD_CHEATS, - "Reload Game-Specific Cheats") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT_VAL, - "Equal to %u (%X)") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_LT_VAL, - "Less Than Before") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_GT_VAL, - "Greater Than Before") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_LTE_VAL, - "Less Than or Equal To Before") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_GTE_VAL, - "Greater Than or Equal To Before") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_EQ_VAL, - "Equal to Before") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ_VAL, - "Not Equal to Before") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS_VAL, - "Equal to Before+%u (%X)") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS_VAL, - "Equal to Before-%u (%X)") -MSG_HASH(MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS, - "Start or Continue Cheat Search") -MSG_HASH(MSG_CHEAT_INIT_SUCCESS, - "Successfully started cheat search") -MSG_HASH(MSG_CHEAT_INIT_FAIL, - "Failed to start cheat search") -MSG_HASH(MSG_CHEAT_SEARCH_NOT_INITIALIZED, - "Searching has not been initialized/started") -MSG_HASH(MSG_CHEAT_SEARCH_FOUND_MATCHES, - "New match count = %u") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_BIG_ENDIAN, - "Big Endian") -MSG_HASH(MSG_CHEAT_SEARCH_ADDED_MATCHES_SUCCESS, - "Added %u matches") -MSG_HASH(MSG_CHEAT_SEARCH_ADDED_MATCHES_FAIL, - "Failed to add matches") -MSG_HASH(MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS, - "Created code from match") -MSG_HASH(MSG_CHEAT_SEARCH_ADD_MATCH_FAIL, - "Failed to create code") -MSG_HASH(MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS, - "Deleted match") -MSG_HASH(MSG_CHEAT_SEARCH_ADDED_MATCHES_TOO_MANY, - "Not enough room. The total number of cheats you can have is 100.") -MSG_HASH(MSG_CHEAT_ADD_TOP_SUCCESS, - "New cheat added to top of list.") -MSG_HASH(MSG_CHEAT_ADD_BOTTOM_SUCCESS, - "New cheat added to bottom of list.") -MSG_HASH(MSG_CHEAT_DELETE_ALL_INSTRUCTIONS, - "Press right five times to delete all cheats.") -MSG_HASH(MSG_CHEAT_DELETE_ALL_SUCCESS, - "All cheats deleted.") -MSG_HASH(MSG_CHEAT_ADD_BEFORE_SUCCESS, - "New cheat added before this one.") -MSG_HASH(MSG_CHEAT_ADD_AFTER_SUCCESS, - "New cheat added after this one.") -MSG_HASH(MSG_CHEAT_COPY_BEFORE_SUCCESS, - "Cheat copied before this one.") -MSG_HASH(MSG_CHEAT_COPY_AFTER_SUCCESS, - "Cheat copied after this one.") -MSG_HASH(MSG_CHEAT_DELETE_SUCCESS, - "Cheat deleted.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_PROGRESS, - "Progress:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_LIST_MAX_COUNT, - "\"All Playlists\" max list entries:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_GRID_MAX_COUNT, - "\"All Playlists\" max grid entries:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SHOW_HIDDEN_FILES, - "Show hidden files and folders:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST, - "New Playlist") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ENTER_NEW_PLAYLIST_NAME, - "Please enter the new playlist name:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DELETE_PLAYLIST, - "Delete Playlist") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST, - "Are you sure you want to delete the playlist \"%1\"?") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_QUESTION, - "Question") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_DELETE_FILE, - "Could not delete file.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_RENAME_FILE, - "Could not rename file.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_GATHERING_LIST_OF_FILES, - "Gathering list of files...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ADDING_FILES_TO_PLAYLIST, - "Adding files to playlist...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY, - "Playlist Entry") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_NAME, - "Name:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_PATH, - "Path:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_CORE, - "Core:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_DATABASE, - "Database:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FOR_THUMBNAILS, - "(used to find thumbnails)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST_ITEM, - "Are you sure you want to delete the item \"%1\"?") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CANNOT_ADD_TO_ALL_PLAYLISTS, - "Please choose a single playlist first.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DELETE, - "Delete") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ADD_ENTRY, - "Add Entry...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ADD_FILES, - "Add File(s)...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ADD_FOLDER, - "Add Folder...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_EDIT, - "Edit") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SELECT_FILES, - "Select Files") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SELECT_FOLDER, - "Select Folder") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FIELD_MULTIPLE, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_UPDATE_PLAYLIST_ENTRY, - "Error updating playlist entry.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_PLEASE_FILL_OUT_REQUIRED_FIELDS, - "Please fill out all required fields.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_NIGHTLY, - "Update RetroArch (nightly)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FINISHED, - "RetroArch updated successfully. Please restart the application for the changes to take effect.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FAILED, - "Update failed.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_ABOUT_CONTRIBUTORS, - "Contributors") + MENU_ENUM_SUBLABEL_SHOW_WIMP, + "Opens the desktop menu if closed." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, + "Don't show this again" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_STOP, + "Stop" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE, + "Associate Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS, + "Hidden Playlists" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_HIDE, + "Hide" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_HIGHLIGHT_COLOR, + "Highlight color:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CHOOSE, + "&Choose..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_COLOR, + "Select Color" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_THEME, + "Select Theme" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CUSTOM_THEME, + "Custom Theme" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_PATH_IS_BLANK, + "File path is blank." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_IS_EMPTY, + "File is empty." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_READ_OPEN_FAILED, + "Could not open file for reading." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_WRITE_OPEN_FAILED, + "Could not open file for writing." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST, + "File does not exist." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SUGGEST_LOADED_CORE_FIRST, + "Suggest loaded core first:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ZOOM, + "Zoom" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_VIEW, + "View" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_ICONS, + "Icons" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_LIST, + "List" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS, + "Overrides" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_QUICK_MENU_OVERRIDE_OPTIONS, + "Options for overriding the global configuration." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY, + "Will start playback of the audio stream. Once finished, it will remove the current audio stream from memory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_LOOPED, + "Will start playback of the audio stream. Once finished, it will loop and play the track again from the beginning." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_SEQUENTIAL, + "Will start playback of the audio stream. Once finished, it will jump to the next audio stream in sequential order and repeat this behavior. Useful as an album playback mode." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_STOP, + "This will stop playback of the audio stream, but not remove it from memory. You can start playing it again by selecting 'Play'." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_REMOVE, + "This will stop playback of the audio stream and remove it entirely from memory." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIXER_ACTION_VOLUME, + "Adjust the volume of the audio stream." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ADD_TO_MIXER, + "Add this audio track to an available audio stream slot. If no slots are currently available, it will be ignored." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ADD_TO_MIXER_AND_PLAY, + "Add this audio track to an available audio stream slot and play it. If no slots are currently available, it will be ignored." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY, + "Play" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_LOOPED, + "Play (Looped)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_SEQUENTIAL, + "Play (Sequential)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_STOP, + "Stop" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_REMOVE, + "Remove" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_VOLUME, + "Volume" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DETECT_CORE_LIST_OK_CURRENT_CORE, + "Current core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, + "Clear" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ACHIEVEMENT_PAUSE, + "Pause achievements for current session (This action will enable savestates, cheats, rewind, pause, and slow-motion)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ACHIEVEMENT_RESUME, + "Resume achievements for current session (This action will disable savestates, cheats, rewind, pause, and slow-motion and reset the current game)." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, + "In-Menu" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, + "Enable Discord" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DISCORD_ALLOW, + "Enable or disable Discord support. Will not work with the browser version, only native desktop client." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_INPUT, + "Input" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIDI_INPUT, + "Select input device." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_OUTPUT, + "Output" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIDI_OUTPUT, + "Select output device." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_MIDI_VOLUME, + "Volume" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MIDI_VOLUME, + "Set output volume (%)." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_POWER_MANAGEMENT_SETTINGS, + "Power Management" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_POWER_MANAGEMENT_SETTINGS, + "Change power management settings." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SUSTAINED_PERFORMANCE_MODE, + "Sustained Performance Mode" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_MPV_SUPPORT, + "mpv support" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_IDX, + "Index" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_MATCH_IDX, + "View Match #" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_MATCH, + "Match Address: %08X Mask: %02X" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_MATCH, + "Create Code Match #" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_MATCH, + "Delete Match #" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_BROWSE_MEMORY, + "Browse Address: %08X" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DESC, + "Description" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_STATE, + "Enabled" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_CODE, + "Code" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_HANDLER, + "Handler" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_MEMORY_SEARCH_SIZE, + "Memory Search Size" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_TYPE, + "Type" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_VALUE, + "Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS, + "Memory Address" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADDRESS_BIT_POSITION, + "Memory Address Mask" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_TYPE, + "Rumble When Memory" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_VALUE, + "Rumble Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PORT, + "Rumble Port" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_STRENGTH, + "Rumble Primary Strength" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_PRIMARY_DURATION, + "Rumble Primary Duration (ms)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_STRENGTH, + "Rumble Secondary Strength" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RUMBLE_SECONDARY_DURATION, + "Rumble Secondary Duration (ms)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_AFTER, + "Add New Cheat After This One" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BEFORE, + "Add New Cheat Before This One" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_AFTER, + "Copy This Cheat After" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_COPY_BEFORE, + "Copy This Cheat Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE, + "Delete This Cheat" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_EMU, + "Emulator" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_HANDLER_TYPE_RETRO, + "RetroArch" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_DISABLED, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_SET_TO_VALUE, + "Set To Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_INCREASE_VALUE, + "Increase By Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_DECREASE_VALUE, + "Decrease By Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_EQ, + "Run next cheat if value = memory" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_NEQ, + "Run next cheat if value != memory" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_LT, + "Run next cheat if value < memory" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_TYPE_RUN_NEXT_IF_GT, + "Run next cheat if value > memory" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_DISABLED, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_CHANGES, + "Changes" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_DOES_NOT_CHANGE, + "Does Not Change" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_INCREASE, + "Increases" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_DECREASE, + "Decreases" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_EQ_VALUE, + "= Rumble Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_NEQ_VALUE, + "!= Rumble Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_LT_VALUE, + "< Rumble Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_TYPE_GT_VALUE, + "> Rumble Value" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_1, + "1-bit, max value = 0x01" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_2, + "2-bit, max value = 0x03" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_4, + "4-bit, max value = 0x0F" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_8, + "8-bit, max value = 0xFF" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_16, + "16-bit, max value = 0xFFFF" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_MEMORY_SIZE_32, + "32-bit, max value = 0xFFFFFFFF" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_0, + "1" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_1, + "2" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_2, + "3" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_3, + "4" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_4, + "5" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_5, + "6" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_6, + "7" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_7, + "8" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_8, + "9" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_9, + "10" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_10, + "11" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_11, + "12" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_12, + "13" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_13, + "14" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_14, + "15" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_15, + "16" + ) +MSG_HASH( + MENU_ENUM_LABEL_RUMBLE_PORT_16, + "All" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_CONT, + "Start or Continue Cheat Search" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_START_OR_RESTART, + "Start or Restart Cheat Search" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EXACT, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LT, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GT, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQ, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_GTE, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_LTE, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_NEQ, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQPLUS, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_EQMINUS, + "Search Memory For Values" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_MATCHES, + "Add the %u Matches to Your List" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_VIEW_MATCHES, + "View the List of %u Matches" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_CREATE_OPTION, + "Create Code From This Match" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_OPTION, + "Delete This Match" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_TOP, + "Add New Code to Top" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_ADD_NEW_BOTTOM, + "Add New Code to Bottom" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DELETE_ALL, + "Delete All Codes" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_RELOAD_CHEATS, + "Reload Game-Specific Cheats" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT_VAL, + "Equal to %u (%X)" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_LT_VAL, + "Less Than Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_GT_VAL, + "Greater Than Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_LTE_VAL, + "Less Than or Equal To Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_GTE_VAL, + "Greater Than or Equal To Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_EQ_VAL, + "Equal to Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_NEQ_VAL, + "Not Equal to Before" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS_VAL, + "Equal to Before+%u (%X)" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS_VAL, + "Equal to Before-%u (%X)" + ) +MSG_HASH( + MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS, + "Start or Continue Cheat Search" + ) +MSG_HASH( + MSG_CHEAT_INIT_SUCCESS, + "Successfully started cheat search" + ) +MSG_HASH( + MSG_CHEAT_INIT_FAIL, + "Failed to start cheat search" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_NOT_INITIALIZED, + "Searching has not been initialized/started" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_FOUND_MATCHES, + "New match count = %u" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_BIG_ENDIAN, + "Big Endian" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADDED_MATCHES_SUCCESS, + "Added %u matches" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADDED_MATCHES_FAIL, + "Failed to add matches" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADD_MATCH_SUCCESS, + "Created code from match" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADD_MATCH_FAIL, + "Failed to create code" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_DELETE_MATCH_SUCCESS, + "Deleted match" + ) +MSG_HASH( + MSG_CHEAT_SEARCH_ADDED_MATCHES_TOO_MANY, + "Not enough room. The total number of cheats you can have is 100." + ) +MSG_HASH( + MSG_CHEAT_ADD_TOP_SUCCESS, + "New cheat added to top of list." + ) +MSG_HASH( + MSG_CHEAT_ADD_BOTTOM_SUCCESS, + "New cheat added to bottom of list." + ) +MSG_HASH( + MSG_CHEAT_DELETE_ALL_INSTRUCTIONS, + "Press right five times to delete all cheats." + ) +MSG_HASH( + MSG_CHEAT_DELETE_ALL_SUCCESS, + "All cheats deleted." + ) +MSG_HASH( + MSG_CHEAT_ADD_BEFORE_SUCCESS, + "New cheat added before this one." + ) +MSG_HASH( + MSG_CHEAT_ADD_AFTER_SUCCESS, + "New cheat added after this one." + ) +MSG_HASH( + MSG_CHEAT_COPY_BEFORE_SUCCESS, + "Cheat copied before this one." + ) +MSG_HASH( + MSG_CHEAT_COPY_AFTER_SUCCESS, + "Cheat copied after this one." + ) +MSG_HASH( + MSG_CHEAT_DELETE_SUCCESS, + "Cheat deleted." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PROGRESS, + "Progress:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_LIST_MAX_COUNT, + "\"All Playlists\" max list entries:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_GRID_MAX_COUNT, + "\"All Playlists\" max grid entries:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SHOW_HIDDEN_FILES, + "Show hidden files and folders:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST, + "New Playlist" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ENTER_NEW_PLAYLIST_NAME, + "Please enter the new playlist name:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DELETE_PLAYLIST, + "Delete Playlist" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST, + "Are you sure you want to delete the playlist \"%1\"?" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_QUESTION, + "Question" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_DELETE_FILE, + "Could not delete file." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_RENAME_FILE, + "Could not rename file." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_GATHERING_LIST_OF_FILES, + "Gathering list of files..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADDING_FILES_TO_PLAYLIST, + "Adding files to playlist..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY, + "Playlist Entry" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_NAME, + "Name:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_PATH, + "Path:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_CORE, + "Core:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_DATABASE, + "Database:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FOR_THUMBNAILS, + "(used to find thumbnails)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST_ITEM, + "Are you sure you want to delete the item \"%1\"?" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CANNOT_ADD_TO_ALL_PLAYLISTS, + "Please choose a single playlist first." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DELETE, + "Delete" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADD_ENTRY, + "Add Entry..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADD_FILES, + "Add File(s)..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_ADD_FOLDER, + "Add Folder..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_EDIT, + "Edit" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_FILES, + "Select Files" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SELECT_FOLDER, + "Select Folder" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_FIELD_MULTIPLE, + "" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_UPDATE_PLAYLIST_ENTRY, + "Error updating playlist entry." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_PLEASE_FILL_OUT_REQUIRED_FIELDS, + "Please fill out all required fields." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_NIGHTLY, + "Update RetroArch (nightly)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FINISHED, + "RetroArch updated successfully. Please restart the application for the changes to take effect." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FAILED, + "Update failed." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_HELP_ABOUT_CONTRIBUTORS, + "Contributors" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CURRENT_SHADER, + "Current shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MOVE_DOWN, + "Move Down" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MOVE_UP, + "Move Up" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_LOAD, + "Load" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SAVE, + "Save" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_REMOVE, + "Remove" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_APPLY, + "Apply" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SHADER_ADD_PASS, + "Add Pass" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SHADER_CLEAR_ALL_PASSES, + "Clear All Passes" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_SHADER_NO_PASSES, + "No shader passes." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESET_PASS, + "Reset Pass" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESET_ALL_PASSES, + "Reset All Passes" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_RESET_PARAMETER, + "Reset Parameter" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_THUMBNAIL, + "Download thumbnail" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALREADY_IN_PROGRESS, + "A download is already in progress." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_STARTUP_PLAYLIST, + "Start on playlist:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS, + "Download All Thumbnails" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_ENTIRE_SYSTEM, + "Entire System" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_THIS_PLAYLIST, + "This Playlist" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_PACK_DOWNLOADED_SUCCESSFULLY, + "Thumbnails downloaded successfully." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_PLAYLIST_THUMBNAIL_PROGRESS, + "Succeeded: %1 Failed: %2" + ) +MSG_HASH( + MSG_DEVICE_CONFIGURED_IN_PORT, + "Configured in port:" + ) +MSG_HASH( + MSG_FAILED_TO_SET_DISK, + "Failed to set disk" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_QT_CORE_OPTIONS, + "Core Options" + ) diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h index 71b81df5b7..9cd2329191 100644 --- a/intl/msg_hash_vn.h +++ b/intl/msg_hash_vn.h @@ -3264,9 +3264,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, "Enable background filler thickness") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION, "For 15 kHz CRT displays only. Attempts to use exact core/game resolution and refresh rate.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, "CRT SwitchRes") MSG_HASH(MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER, "When CRT SwitchRes is enabled, force ultrawide horizontal resolution to minimize mode switching.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, "CRT Super Resolution") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, "Show Rewind Settings") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, @@ -3325,6 +3325,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, "Clear") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, "In-Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + "In-Game") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + "In-Game (Paused)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + "Playing") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, + "Paused") MSG_HASH( MENU_ENUM_LABEL_VALUE_DISCORD_ALLOW, "Enable Discord" diff --git a/libretro-common/compat/compat_snprintf.c b/libretro-common/compat/compat_snprintf.c index f67301ade2..7011644280 100644 --- a/libretro-common/compat/compat_snprintf.c +++ b/libretro-common/compat/compat_snprintf.c @@ -23,10 +23,7 @@ /* THIS FILE HAS NOT BEEN VALIDATED ON PLATFORMS BESIDES MSVC */ #ifdef _MSC_VER -#include -#if _MSC_VER >= 1800 -#include /* added for _vsnprintf_s and _vscprintf on VS2015 and VS2017 */ -#endif +#include #include #if _MSC_VER < 1800 @@ -52,13 +49,16 @@ static int c89_vscprintf_retro__(const char *format, va_list pargs) int c99_vsnprintf_retro__(char *outBuf, size_t size, const char *format, va_list ap) { int count = -1; - + if (size != 0) + { #if (_MSC_VER <= 1310) - count = _vsnprintf(outBuf, size - 1, format, ap); + count = _vsnprintf(outBuf, size - 1, format, ap); #else - count = _vsnprintf_s(outBuf, size, size - 1, format, ap); + count = _vsnprintf_s(outBuf, size, size - 1, format, ap); #endif + } + if (count == -1) count = _vscprintf(format, ap); diff --git a/libretro-common/file/nbio/nbio_windowsmmap.c b/libretro-common/file/nbio/nbio_windowsmmap.c index 2bfd834a71..67860a3909 100644 --- a/libretro-common/file/nbio/nbio_windowsmmap.c +++ b/libretro-common/file/nbio/nbio_windowsmmap.c @@ -22,7 +22,7 @@ #include -#if defined(_WIN32) && !defined(_XBOX) +#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__) #include #include diff --git a/libretro-common/formats/jpeg/rjpeg.c b/libretro-common/formats/jpeg/rjpeg.c index 9ef95e4f08..65cb6c3966 100644 --- a/libretro-common/formats/jpeg/rjpeg.c +++ b/libretro-common/formats/jpeg/rjpeg.c @@ -2505,15 +2505,18 @@ static uint8_t *rjpeg_load_jpeg_image(rjpeg__jpeg *z, if (n >= 3) { uint8_t *y = coutput[0]; - if (z->s->img_n == 3) - z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); - else - for (i=0; i < z->s->img_x; ++i) - { - out[0] = out[1] = out[2] = y[i]; - out[3] = 255; /* not used if n==3 */ - out += n; - } + if (y) + { + if (z->s->img_n == 3) + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + else + for (i=0; i < z->s->img_x; ++i) + { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; /* not used if n==3 */ + out += n; + } + } } else { diff --git a/libretro-common/formats/png/rpng.c b/libretro-common/formats/png/rpng.c index e28272124c..1bf075759d 100644 --- a/libretro-common/formats/png/rpng.c +++ b/libretro-common/formats/png/rpng.c @@ -544,6 +544,7 @@ static int png_reverse_filter_init(const struct png_ihdr *ihdr, if (pngp->pass_size > pngp->total_out) { free(pngp->data); + pngp->data = NULL; return -1; } @@ -721,6 +722,7 @@ static int png_reverse_filter_adam7_iterate(uint32_t **data_, free(pngp->data); + pngp->data = NULL; pngp->pass_width = 0; pngp->pass_height = 0; pngp->pass_size = 0; @@ -746,7 +748,10 @@ static int png_reverse_filter_adam7(uint32_t **data_, return 0; case IMAGE_PROCESS_ERROR: if (pngp->data) + { free(pngp->data); + pngp->data = NULL; + } pngp->inflate_buf -= pngp->adam7_restore_buf_size; pngp->adam7_restore_buf_size = 0; return -1; diff --git a/libretro-common/formats/png/rpng_encode.c b/libretro-common/formats/png/rpng_encode.c index 3500c3aaf4..42df8116aa 100644 --- a/libretro-common/formats/png/rpng_encode.c +++ b/libretro-common/formats/png/rpng_encode.c @@ -150,7 +150,10 @@ static unsigned count_sad(const uint8_t *data, size_t size) size_t i; unsigned cnt = 0; for (i = 0; i < size; i++) - cnt += abs((int8_t)data[i]); + { + if (data[i]) + cnt += abs((int8_t)data[i]); + } return cnt; } diff --git a/libretro-common/include/compat/apple_compat.h b/libretro-common/include/compat/apple_compat.h index 819b39ecf6..74b6829954 100644 --- a/libretro-common/include/compat/apple_compat.h +++ b/libretro-common/include/compat/apple_compat.h @@ -29,7 +29,7 @@ #ifdef __OBJC__ -#if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4) +#if (MAC_OS_X_VERSION_MAX_ALLOWED <= 1040) typedef int NSInteger; typedef unsigned NSUInteger; typedef float CGFloat; diff --git a/libretro-common/include/compat/msvc.h b/libretro-common/include/compat/msvc.h index 822c97339a..0a25cd9370 100644 --- a/libretro-common/include/compat/msvc.h +++ b/libretro-common/include/compat/msvc.h @@ -39,8 +39,8 @@ extern "C" { int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...); #endif -/* Pre-MSVC 2010 compilers don't implement vsnprintf in a cross-platform manner? Not sure about this one. */ -#if _MSC_VER < 1600 +/* Pre-MSVC 2008 compilers don't implement vsnprintf in a cross-platform manner? Not sure about this one. */ +#if _MSC_VER < 1500 #include #include #ifndef vsnprintf diff --git a/managers/cheat_manager.c b/managers/cheat_manager.c index 67abbb0bab..df087cab82 100644 --- a/managers/cheat_manager.c +++ b/managers/cheat_manager.c @@ -593,7 +593,7 @@ bool cheat_manager_get_game_specific_filename(char * cheat_filename, size_t max_ const char *game_name = NULL; struct retro_system_info system_info; - if ( settings == NULL || global == NULL || cheat_filename == NULL) + if (!settings || !global || !cheat_filename) return false ; if ( !core_get_system_info(&system_info) ) @@ -608,15 +608,15 @@ bool cheat_manager_get_game_specific_filename(char * cheat_filename, size_t max_ return false ; cheat_filename[0] = '\0'; - strlcat(cheat_filename, settings->paths.path_cheat_database, max_length-1) ; - fill_pathname_slash(cheat_filename, max_length) ; - strlcat(cheat_filename, core_name, max_length-strlen(cheat_filename)-1) ; - fill_pathname_slash(cheat_filename, max_length) ; + strlcat(cheat_filename, settings->paths.path_cheat_database, max_length); + fill_pathname_slash(cheat_filename, max_length); + strlcat(cheat_filename, core_name, max_length); + fill_pathname_slash(cheat_filename, max_length); if (!filestream_exists(cheat_filename)) path_mkdir(cheat_filename); - strlcat(cheat_filename, game_name, max_length-strlen(cheat_filename)-1) ; + strlcat(cheat_filename, game_name, max_length); return true ; @@ -813,7 +813,7 @@ int cheat_manager_search(enum cheat_search_type search_type) unsigned int bits = 8 ; bool refresh = false; - if ( cheat_manager_state.curr_memory_buf == NULL ) + if (!cheat_manager_state.curr_memory_buf) { runloop_msg_queue_push(msg_hash_to_str(MSG_CHEAT_SEARCH_NOT_INITIALIZED), 1, 180, true); return 0 ; @@ -1290,8 +1290,8 @@ void cheat_manager_match_action(enum cheat_match_action_type match_action, unsig if (target_match_idx > cheat_manager_state.num_matches-1) return; - if (curr == NULL ) - return ; + if (!curr) + return; cheat_manager_setup_search_meta(cheat_manager_state.search_bit_size, &bytes_per_item, &mask, &bits); diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index 066358dfed..4c9aaec8cd 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -976,6 +976,10 @@ static void menu_action_setting_disp_set_label_xmb_theme( strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM), len); break; + case XMB_ICON_THEME_AUTOMATIC: + strlcpy(s, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_AUTOMATIC), len); + break; } } diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 9de84c207b..6bce681d5f 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -88,6 +88,7 @@ enum ACTION_OK_SET_PATH_VIDEO_FILTER, ACTION_OK_SET_PATH_OVERLAY, ACTION_OK_SET_DIRECTORY, + ACTION_OK_SHOW_WIMP, ACTION_OK_LOAD_CHEAT_FILE_APPEND }; @@ -820,11 +821,11 @@ int generic_action_ok_displaylist_push(const char *path, case ACTION_OK_DL_DEFERRED_CORE_LIST_SET: info.directory_ptr = idx; menu->scratchpad.unsigned_var = (unsigned)idx; - info_path = + info_path = settings->paths.directory_libretro; info_label = msg_hash_to_str( MENU_ENUM_LABEL_DEFERRED_CORE_LIST_SET); - info.enum_idx = + info.enum_idx = MENU_ENUM_LABEL_DEFERRED_CORE_LIST_SET; dl_type = DISPLAYLIST_GENERIC; break; @@ -844,7 +845,7 @@ int generic_action_ok_displaylist_push(const char *path, setting->max = (int) pow(2,pow((double) 2,cheat_manager_state.working_cheat.memory_search_size))-1; setting = menu_setting_find(msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_ADDRESS_BIT_POSITION)); if ( setting ) - { + { int max_bit_position = cheat_manager_state.working_cheat.memory_search_size<3 ? 7 : 0 ; setting->max = max_bit_position ; } @@ -993,7 +994,7 @@ static bool menu_content_playlist_load(playlist_t *playlist, size_t idx) path_check = (char *) calloc(strlen(path_tolower) + 1, sizeof(char)); - strncpy(path_check, path, strlen(path_tolower)); + strlcpy(path_check, path, strlen(path_tolower) + 1); valid_path = path_is_valid(path_check); @@ -1525,7 +1526,7 @@ static int action_ok_file_load(const char *path, if (filebrowser_get_type() == FILEBROWSER_SELECT_FILE_SUBSYSTEM) { - /* TODO/FIXME - this path is triggered when we try to load a + /* TODO/FIXME - this path is triggered when we try to load a * file from an archive while inside the load subsystem * action */ menu_handle_t *menu = NULL; @@ -1676,7 +1677,7 @@ static int action_ok_playlist_entry_collection(const char *path, core_info.inf->display_name, NULL, NULL); - } + } else strlcpy(new_core_path, core_path, sizeof(new_core_path)); @@ -1750,7 +1751,7 @@ static int action_ok_playlist_entry(const char *path, core_info.inf->display_name, NULL, NULL); - + } else if (!string_is_empty(core_path)) strlcpy(new_core_path, core_path, sizeof(new_core_path)); @@ -1813,9 +1814,9 @@ static int action_ok_playlist_entry_start_content(const char *path, if (!core_info_find(&core_info, new_core_path)) found_associated_core = false; - /* TODO: figure out if this should refer to + /* TODO: figure out if this should refer to * the inner or outer entry_path. */ - /* TODO: make sure there's only one entry_path + /* TODO: make sure there's only one entry_path * in this function. */ if (!found_associated_core) return action_ok_file_load_with_detect_core(entry_path, @@ -2111,7 +2112,7 @@ static void menu_input_st_string_cb_rename_entry(void *userdata, NULL); } - + menu_input_dialog_end(); } @@ -2719,7 +2720,7 @@ static int action_ok_cheat_add_bottom(const char *path, cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO); msg[0] = '\0'; - strlcpy(msg, + strlcpy(msg, msg_hash_to_str(MSG_CHEAT_ADD_BOTTOM_SUCCESS), sizeof(msg)); msg[sizeof(msg) - 1] = 0; @@ -3167,7 +3168,6 @@ static void cb_generic_dir_download(void *task_data, void *user_data, const char *err) { file_transfer_t *transf = (file_transfer_t*)user_data; - if (transf) { generic_action_ok_network(transf->path, transf->path, 0, 0, 0, @@ -3496,7 +3496,7 @@ static int action_ok_option_create(const char *path, return false; } - if(config_file_write(conf, game_path)) + if (config_file_write(conf, game_path)) { runloop_msg_queue_push( msg_hash_to_str(MSG_CORE_OPTIONS_FILE_CREATED_SUCCESSFULLY), @@ -3521,15 +3521,15 @@ int (func_name)(const char *path, const char *label, unsigned type, size_t idx, return generic_action_ok_command(cmd); \ } -default_action_ok_cmd_func(action_ok_cheat_apply_changes,CMD_EVENT_CHEATS_APPLY) -default_action_ok_cmd_func(action_ok_quit, CMD_EVENT_QUIT) -default_action_ok_cmd_func(action_ok_save_new_config, CMD_EVENT_MENU_SAVE_CONFIG) -default_action_ok_cmd_func(action_ok_resume_content, CMD_EVENT_RESUME) -default_action_ok_cmd_func(action_ok_restart_content, CMD_EVENT_RESET) -default_action_ok_cmd_func(action_ok_screenshot, CMD_EVENT_TAKE_SCREENSHOT) -default_action_ok_cmd_func(action_ok_disk_cycle_tray_status, CMD_EVENT_DISK_EJECT_TOGGLE ) -default_action_ok_cmd_func(action_ok_shader_apply_changes, CMD_EVENT_SHADERS_APPLY_CHANGES ) - +default_action_ok_cmd_func(action_ok_cheat_apply_changes, CMD_EVENT_CHEATS_APPLY) +default_action_ok_cmd_func(action_ok_quit, CMD_EVENT_QUIT) +default_action_ok_cmd_func(action_ok_save_new_config, CMD_EVENT_MENU_SAVE_CONFIG) +default_action_ok_cmd_func(action_ok_resume_content, CMD_EVENT_RESUME) +default_action_ok_cmd_func(action_ok_restart_content, CMD_EVENT_RESET) +default_action_ok_cmd_func(action_ok_screenshot, CMD_EVENT_TAKE_SCREENSHOT) +default_action_ok_cmd_func(action_ok_disk_cycle_tray_status, CMD_EVENT_DISK_EJECT_TOGGLE) +default_action_ok_cmd_func(action_ok_shader_apply_changes, CMD_EVENT_SHADERS_APPLY_CHANGES) +default_action_ok_cmd_func(action_ok_show_wimp, CMD_EVENT_UI_COMPANION_TOGGLE) static int action_ok_reset_core_association(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) @@ -3944,7 +3944,7 @@ void netplay_refresh_rooms_menu(file_list_t *list) char country[PATH_MAX_LENGTH] = {0}; if (*netplay_room_list[i].country) - string_add_between_pairs(country, netplay_room_list[i].country, + string_add_between_pairs(country, netplay_room_list[i].country, sizeof(country)); /* Uncomment this to debug mismatched room parameters*/ @@ -4739,6 +4739,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_XMB_MAIN_MENU_ENABLE_SETTINGS: BIND_ACTION_OK(cbs, action_ok_enable_settings); break; + case MENU_ENUM_LABEL_SHOW_WIMP: + BIND_ACTION_OK(cbs, action_ok_show_wimp); + break; case MENU_ENUM_LABEL_QUIT_RETROARCH: BIND_ACTION_OK(cbs, action_ok_quit); break; diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index d9fea4d60f..2c292437f0 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -461,7 +461,9 @@ default_sublabel_macro(action_bind_sublabel_midi_output, default_sublabel_macro(action_bind_sublabel_midi_volume, MENU_ENUM_SUBLABEL_MIDI_VOLUME) default_sublabel_macro(action_bind_sublabel_onscreen_overlay_settings_list, MENU_ENUM_SUBLABEL_ONSCREEN_OVERLAY_SETTINGS) default_sublabel_macro(action_bind_sublabel_onscreen_notifications_settings_list, MENU_ENUM_SUBLABEL_ONSCREEN_NOTIFICATIONS_SETTINGS) - +#ifdef HAVE_QT +default_sublabel_macro(action_bind_sublabel_show_wimp, MENU_ENUM_SUBLABEL_SHOW_WIMP) +#endif static int action_bind_sublabel_cheevos_entry( file_list_t *list, @@ -1942,6 +1944,14 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_ONSCREEN_NOTIFICATIONS_SETTINGS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_onscreen_notifications_settings_list); break; +#ifdef HAVE_QT + case MENU_ENUM_LABEL_SHOW_WIMP: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_show_wimp); + break; +#endif + case MENU_ENUM_SUBLABEL_CHEAT_APPLY_AFTER_LOAD: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheat_apply_after_load); + break; default: case MSG_UNKNOWN: return -1; diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index 3c34362b30..0c80afa196 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -543,17 +543,20 @@ static void materialui_render_messagebox(materialui_handle_t *mui, } } - menu_display_set_alpha(body_bg_color, 1.0); + if (body_bg_color) + { + menu_display_set_alpha(body_bg_color, 1.0); - menu_display_draw_quad( - video_info, - x - longest_width / 2.0 - mui->margin * 2.0, - y - line_height / 2.0 - mui->margin * 2.0, - longest_width + mui->margin * 4.0, - line_height * list->size + mui->margin * 4.0, - width, - height, - &body_bg_color[0]); + menu_display_draw_quad( + video_info, + x - longest_width / 2.0 - mui->margin * 2.0, + y - line_height / 2.0 - mui->margin * 2.0, + longest_width + mui->margin * 4.0, + line_height * list->size + mui->margin * 4.0, + width, + height, + &body_bg_color[0]); + } /* print each line */ for (i = 0; i < list->size; i++) diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index f0511dc936..c97d052893 100755 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -105,6 +105,8 @@ enum #ifdef HAVE_NETWORKING XMB_TEXTURE_NETPLAY, XMB_TEXTURE_ROOM, + XMB_TEXTURE_IROOM, + XMB_TEXTURE_LANROOM, #if 0 /* stub these out until we have the icons */ XMB_TEXTURE_ROOM_LAN, @@ -155,6 +157,33 @@ enum XMB_TEXTURE_KEY, XMB_TEXTURE_KEY_HOVER, XMB_TEXTURE_DIALOG_SLICE, + XMB_TEXTURE_ACHIEVEMENTS, + XMB_TEXTURE_AUDIO, + XMB_TEXTURE_EXIT, + XMB_TEXTURE_FRAMESKIP, + XMB_TEXTURE_INFO, + XMB_TEXTURE_HELP, + XMB_TEXTURE_NETWORK, + XMB_TEXTURE_POWER, + XMB_TEXTURE_SAVING, + XMB_TEXTURE_UPDATER, + XMB_TEXTURE_VIDEO, + XMB_TEXTURE_RECORD, + XMB_TEXTURE_INPUT, + XMB_TEXTURE_MIXER, + XMB_TEXTURE_LOG, + XMB_TEXTURE_OSD, + XMB_TEXTURE_UI, + XMB_TEXTURE_USER, + XMB_TEXTURE_PRIVACY, + XMB_TEXTURE_LATENCY, + XMB_TEXTURE_DRIVERS, + XMB_TEXTURE_PLAYLIST, + XMB_TEXTURE_QUICKMENU, + XMB_TEXTURE_REWIND, + XMB_TEXTURE_OVERLAY, + XMB_TEXTURE_OVERRIDE, + XMB_TEXTURE_NOTIFICATIONS, XMB_TEXTURE_LAST }; @@ -420,11 +449,12 @@ const char* xmb_theme_ident(void) return "custom"; case XMB_ICON_THEME_MONOCHROME_INVERTED: return "monochrome-inverted"; + case XMB_ICON_THEME_AUTOMATIC: + return "automatic"; case XMB_ICON_THEME_MONOCHROME: default: break; } - return "monochrome"; } @@ -906,7 +936,7 @@ static void xmb_update_thumbnail_path(void *data, unsigned i, char pos) xmb_node_t *node = (xmb_node_t*) file_list_get_userdata_at_offset(selection_buf, i); - if (!string_is_empty(node->fullpath) && + if (!string_is_empty(node->fullpath) && (pos == 'R' || (pos == 'L' && string_is_equal(xmb_thumbnails_ident('R'), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))))) { @@ -937,9 +967,9 @@ static void xmb_update_thumbnail_path(void *data, unsigned i, char pos) if (string_is_equal(core_name, "imageviewer")) { if ( - (pos == 'R') || + (pos == 'R') || ( - pos == 'L' && + pos == 'L' && string_is_equal(xmb_thumbnails_ident('R'), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) ) @@ -1766,7 +1796,7 @@ static void xmb_list_switch(xmb_handle_t *xmb) xmb_list_switch_horizontal_list(xmb); anim_entry.duration = XMB_DELAY; - anim_entry.target_value = xmb->icon_spacing_horizontal + anim_entry.target_value = xmb->icon_spacing_horizontal * -(float)xmb->categories_selection_ptr; anim_entry.subject = &xmb->categories_x_pos; anim_entry.easing_enum = EASING_OUT_QUAD; @@ -1945,7 +1975,7 @@ static void xmb_context_reset_horizontal_list( size_t list_size = xmb_list_get_size(xmb, MENU_LIST_HORIZONTAL); - xmb->categories_x_pos = + xmb->categories_x_pos = xmb->icon_spacing_horizontal * -(float)xmb->categories_selection_ptr; @@ -1998,6 +2028,13 @@ static void xmb_context_reset_horizontal_list( file_path_str(FILE_PATH_PNG_EXTENSION), PATH_MAX_LENGTH * sizeof(char)); + /* If the playlist icon doesn't exist return default */ + + if (!filestream_exists(texturepath)) + fill_pathname_join_concat(texturepath, iconpath, "default", + file_path_str(FILE_PATH_PNG_EXTENSION), + PATH_MAX_LENGTH * sizeof(char)); + ti.width = 0; ti.height = 0; ti.pixels = NULL; @@ -2015,10 +2052,21 @@ static void xmb_context_reset_horizontal_list( image_texture_free(&ti); } - strlcat(iconpath, sysname, PATH_MAX_LENGTH * sizeof(char)); - fill_pathname_join_delim(content_texturepath, iconpath, + fill_pathname_join_delim(sysname, sysname, file_path_str(FILE_PATH_CONTENT_BASENAME), '-', PATH_MAX_LENGTH * sizeof(char)); + strlcat(content_texturepath, iconpath, PATH_MAX_LENGTH * sizeof(char)); + strlcat(content_texturepath, sysname, PATH_MAX_LENGTH * sizeof(char)); + + /* If the content icon doesn't exist return default-content */ + + if (!filestream_exists(content_texturepath)) + { + strlcat(iconpath, "default", PATH_MAX_LENGTH * sizeof(char)); + fill_pathname_join_delim(content_texturepath, iconpath, + file_path_str(FILE_PATH_CONTENT_BASENAME), '-', + PATH_MAX_LENGTH * sizeof(char)); + } if (image_texture_load(&ti, content_texturepath)) { @@ -2195,7 +2243,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, case MENU_ENUM_LABEL_ADD_TO_FAVORITES_PLAYLIST: return xmb->textures.list[XMB_TEXTURE_ADD_FAVORITE]; case MENU_ENUM_LABEL_RESET_CORE_ASSOCIATION: - return xmb->textures.list[XMB_TEXTURE_RENAME]; + return xmb->textures.list[XMB_TEXTURE_UNDO]; case MENU_ENUM_LABEL_CORE_INPUT_REMAPPING_OPTIONS: return xmb->textures.list[XMB_TEXTURE_INPUT_REMAPPING_OPTIONS]; case MENU_ENUM_LABEL_CORE_CHEAT_OPTIONS: @@ -2226,17 +2274,156 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, return xmb->textures.list[XMB_TEXTURE_RENAME]; case MENU_ENUM_LABEL_RESUME_CONTENT: return xmb->textures.list[XMB_TEXTURE_RESUME]; - case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE: - case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR: - case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME: - return xmb->textures.list[XMB_TEXTURE_SAVESTATE]; case MENU_ENUM_LABEL_FAVORITES: case MENU_ENUM_LABEL_DOWNLOADED_FILE_DETECT_CORE_LIST: return xmb->textures.list[XMB_TEXTURE_FOLDER]; case MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR: return xmb->textures.list[XMB_TEXTURE_RDB]; + + + /* Menu collection submenus*/ + case MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST: + return xmb->textures.list[XMB_TEXTURE_ZIP]; + case MENU_ENUM_LABEL_GOTO_FAVORITES: + return xmb->textures.list[XMB_TEXTURE_FAVORITE]; + case MENU_ENUM_LABEL_GOTO_IMAGES: + return xmb->textures.list[XMB_TEXTURE_IMAGE]; + case MENU_ENUM_LABEL_GOTO_VIDEO: + return xmb->textures.list[XMB_TEXTURE_MOVIE]; + case MENU_ENUM_LABEL_GOTO_MUSIC: + return xmb->textures.list[XMB_TEXTURE_MUSIC]; + default: - break; + /* Menu icons are here waiting for theme support*/ + { + settings_t *settings = config_get_ptr(); + if (settings->uints.menu_xmb_theme != XMB_ICON_THEME_FLATUI && + settings->uints.menu_xmb_theme != XMB_ICON_THEME_NEOACTIVE && + settings->uints.menu_xmb_theme != XMB_ICON_THEME_RETROACTIVE && + settings->uints.menu_xmb_theme != XMB_ICON_THEME_PIXEL ) + { + switch (enum_idx) + { + /* Menu icons */ + case MENU_ENUM_LABEL_CONTENT_SETTINGS: + case MENU_ENUM_LABEL_UPDATE_ASSETS: + return xmb->textures.list[XMB_TEXTURE_QUICKMENU]; + case MENU_ENUM_LABEL_START_CORE: + return xmb->textures.list[XMB_TEXTURE_RUN]; + case MENU_ENUM_LABEL_CORE_LIST: + case MENU_ENUM_LABEL_CORE_SETTINGS: + case MENU_ENUM_LABEL_CORE_UPDATER_LIST: + return xmb->textures.list[XMB_TEXTURE_CORE]; + case MENU_ENUM_LABEL_LOAD_CONTENT_LIST: + case MENU_ENUM_LABEL_SCAN_FILE: + return xmb->textures.list[XMB_TEXTURE_FILE]; + case MENU_ENUM_LABEL_ONLINE_UPDATER: + case MENU_ENUM_LABEL_UPDATER_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_UPDATER]; + case MENU_ENUM_LABEL_UPDATE_LAKKA: + return xmb->textures.list[XMB_TEXTURE_MAIN_MENU]; + case MENU_ENUM_LABEL_UPDATE_CHEATS: + return xmb->textures.list[XMB_TEXTURE_CHEAT_OPTIONS]; + case MENU_ENUM_LABEL_THUMBNAILS_UPDATER_LIST: + return xmb->textures.list[XMB_TEXTURE_IMAGE]; + case MENU_ENUM_LABEL_UPDATE_OVERLAYS: + case MENU_ENUM_LABEL_ONSCREEN_OVERLAY_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_OVERLAY]; + case MENU_ENUM_LABEL_UPDATE_CG_SHADERS: + case MENU_ENUM_LABEL_UPDATE_GLSL_SHADERS: + case MENU_ENUM_LABEL_UPDATE_SLANG_SHADERS: + return xmb->textures.list[XMB_TEXTURE_SHADER_OPTIONS]; + case MENU_ENUM_LABEL_INFORMATION: + case MENU_ENUM_LABEL_INFORMATION_LIST: + case MENU_ENUM_LABEL_SYSTEM_INFORMATION: + case MENU_ENUM_LABEL_UPDATE_CORE_INFO_FILES: + return xmb->textures.list[XMB_TEXTURE_INFO]; + case MENU_ENUM_LABEL_UPDATE_DATABASES: + case MENU_ENUM_LABEL_DATABASE_MANAGER_LIST: + return xmb->textures.list[XMB_TEXTURE_RDB]; + case MENU_ENUM_LABEL_CURSOR_MANAGER_LIST: + return xmb->textures.list[XMB_TEXTURE_CURSOR]; + case MENU_ENUM_LABEL_HELP_LIST: + case MENU_ENUM_LABEL_HELP_CONTROLS: + case MENU_ENUM_LABEL_HELP_LOADING_CONTENT: + case MENU_ENUM_LABEL_HELP_SCANNING_CONTENT: + case MENU_ENUM_LABEL_HELP_WHAT_IS_A_CORE: + case MENU_ENUM_LABEL_HELP_CHANGE_VIRTUAL_GAMEPAD: + case MENU_ENUM_LABEL_HELP_AUDIO_VIDEO_TROUBLESHOOTING: + return xmb->textures.list[XMB_TEXTURE_HELP]; + case MENU_ENUM_LABEL_QUIT_RETROARCH: + return xmb->textures.list[XMB_TEXTURE_EXIT]; + /* Settings icons*/ + case MENU_ENUM_LABEL_DRIVER_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_DRIVERS]; + case MENU_ENUM_LABEL_VIDEO_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_VIDEO]; + case MENU_ENUM_LABEL_AUDIO_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_AUDIO]; + case MENU_ENUM_LABEL_AUDIO_MIXER_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_MIXER]; + case MENU_ENUM_LABEL_INPUT_SETTINGS: + case MENU_ENUM_LABEL_UPDATE_AUTOCONFIG_PROFILES: + return xmb->textures.list[XMB_TEXTURE_INPUT]; + case MENU_ENUM_LABEL_LATENCY_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_LATENCY]; + case MENU_ENUM_LABEL_SAVING_SETTINGS: + case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE: + case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR: + case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME: + return xmb->textures.list[XMB_TEXTURE_SAVING]; + case MENU_ENUM_LABEL_LOGGING_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_LOG]; + case MENU_ENUM_LABEL_FRAME_THROTTLE_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_FRAMESKIP]; + case MENU_ENUM_LABEL_RECORDING_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_RECORD]; + case MENU_ENUM_LABEL_ONSCREEN_DISPLAY_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_OSD]; + case MENU_ENUM_LABEL_SHOW_WIMP: + case MENU_ENUM_LABEL_USER_INTERFACE_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_UI]; + case MENU_ENUM_LABEL_POWER_MANAGEMENT_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_POWER]; + case MENU_ENUM_LABEL_RETRO_ACHIEVEMENTS_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_ACHIEVEMENTS]; + case MENU_ENUM_LABEL_NETWORK_INFORMATION: + case MENU_ENUM_LABEL_NETWORK_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_NETWORK]; + case MENU_ENUM_LABEL_PLAYLIST_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_PLAYLIST]; + case MENU_ENUM_LABEL_USER_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_USER]; + case MENU_ENUM_LABEL_DIRECTORY_SETTINGS: + case MENU_ENUM_LABEL_SCAN_DIRECTORY: + return xmb->textures.list[XMB_TEXTURE_FOLDER]; + case MENU_ENUM_LABEL_PRIVACY_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_PRIVACY]; + + case MENU_ENUM_LABEL_REWIND_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_REWIND]; + case MENU_ENUM_LABEL_QUICK_MENU_OVERRIDE_OPTIONS: + return xmb->textures.list[XMB_TEXTURE_OVERRIDE]; + case MENU_ENUM_LABEL_ONSCREEN_NOTIFICATIONS_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_NOTIFICATIONS]; +#ifdef HAVE_NETWORKING + case MENU_ENUM_LABEL_NETPLAY_ENABLE_HOST: + return xmb->textures.list[XMB_TEXTURE_RUN]; + case MENU_ENUM_LABEL_NETPLAY_DISCONNECT: + return xmb->textures.list[XMB_TEXTURE_CLOSE]; + case MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT: + return xmb->textures.list[XMB_TEXTURE_ROOM]; + case MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS: + return xmb->textures.list[XMB_TEXTURE_IROOM]; + case MENU_ENUM_LABEL_NETPLAY_LAN_SCAN_SETTINGS: + return xmb->textures.list[XMB_TEXTURE_LANROOM]; +#endif + default: + break; + } + } + break; + } } switch(type) @@ -2374,7 +2561,7 @@ static void xmb_calculate_visible_range(const xmb_handle_t *xmb, { for (j = current; j-- > 0; ) { - float bottom = xmb_item_y(xmb, j, current) + float bottom = xmb_item_y(xmb, j, current) + base_y + xmb->icon_size; if (bottom < 0) @@ -2984,7 +3171,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) return; scale_factor = (settings->uints.menu_xmb_scale_factor * (float)width) / (1920.0 * 100); - pseudo_font_length = xmb->icon_spacing_horizontal * 4 - xmb->icon_size / 4; + pseudo_font_length = xmb->icon_spacing_horizontal * 4 - xmb->icon_size / 4; xmb->frame_count++; @@ -3071,20 +3258,20 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) /* This is used for hiding thumbnails when going into sub-levels in the * Quick Menu as well as when selecting "Information" for a playlist entry. - * NOTE: This is currently a pretty crude check, simply going by menu depth + * NOTE: This is currently a pretty crude check, simply going by menu depth * and not specifically identifying which menu we're actually in. */ hide_thumbnails = xmb_system_tab > XMB_SYSTEM_TAB_SETTINGS && xmb->depth > 2; /* Right thumbnail big size */ if (!hide_thumbnails && !xmb->savestate_thumbnail && xmb->use_ps3_layout && - (!settings->bools.menu_xmb_vertical_thumbnails || + (!settings->bools.menu_xmb_vertical_thumbnails || (settings->bools.menu_xmb_vertical_thumbnails && !xmb->left_thumbnail))) { /* Do not draw the right thumbnail if there is no space available */ - if (((xmb->margins_screen_top + + if (((xmb->margins_screen_top + xmb->icon_size + min_thumb_size) <= height) && - ((xmb->margins_screen_left * scale_mod[5] + + ((xmb->margins_screen_left * scale_mod[5] + xmb->icon_spacing_horizontal + pseudo_font_length + min_thumb_size) <= width)) { @@ -3096,8 +3283,8 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) float thumb_width = 0.0f; float thumb_height = 0.0f; - float thumb_max_width = (float)width - (xmb->icon_size / 6) - - (xmb->margins_screen_left * scale_mod[5]) - + float thumb_max_width = (float)width - (xmb->icon_size / 6) + - (xmb->margins_screen_left * scale_mod[5]) - xmb->icon_spacing_horizontal - pseudo_font_length; #ifdef XMB_DEBUG @@ -3125,11 +3312,11 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) ((float)height * under_thumb_margin)) { thumb_width = thumb_width * - ((((float)height * under_thumb_margin) - + ((((float)height * under_thumb_margin) - xmb->margins_screen_top - xmb->icon_size) / thumb_height); thumb_height = thumb_height * - ((((float)height * under_thumb_margin) - + ((((float)height * under_thumb_margin) - xmb->margins_screen_top - xmb->icon_size) / thumb_height); } @@ -3185,19 +3372,19 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) } /* Limit left thumbnail height to screen height + margin. */ - if (xmb->margins_screen_top + xmb->icon_size * + if (xmb->margins_screen_top + xmb->icon_size * (!(xmb->depth == 1)? 2.1 : 1) + - left_thumb_height >= + left_thumb_height >= ((float)height - (96.0 * scale_factor))) { left_thumb_width = left_thumb_width * - ((((float)height - (96.0 * scale_factor)) + ((((float)height - (96.0 * scale_factor)) - xmb->margins_screen_top - (xmb->icon_size * (!(xmb->depth == 1)? 2.1 : 1))) / left_thumb_height); left_thumb_height = left_thumb_height * - ((((float)height - (96.0 * scale_factor)) + ((((float)height - (96.0 * scale_factor)) - xmb->margins_screen_top - (xmb->icon_size * (!(xmb->depth == 1)? 2.1 : 1))) / left_thumb_height); @@ -3205,9 +3392,9 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) xmb_draw_thumbnail(video_info, xmb, &coord_white[0], width, height, - (xmb->icon_size / 6) + + (xmb->icon_size / 6) + ((thumb_max_width - left_thumb_width) / 2), - xmb->margins_screen_top + xmb->icon_size * + xmb->margins_screen_top + xmb->icon_size * (!(xmb->depth == 1)? 2.1 : 1) + left_thumb_height, left_thumb_width, left_thumb_height, xmb->left_thumbnail); @@ -3220,9 +3407,9 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) { /* Do not draw the left thumbnail if there is no space available */ - if (((xmb->margins_screen_top + + if (((xmb->margins_screen_top + xmb->icon_size + min_thumb_size) <= height) && - ((xmb->margins_screen_left * scale_mod[5] + + ((xmb->margins_screen_left * scale_mod[5] + xmb->icon_spacing_horizontal + pseudo_font_length + min_thumb_size) <= width)) { @@ -3336,7 +3523,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) } xmb_draw_thumbnail(video_info, - xmb, &coord_white[0], width, height, + xmb, &coord_white[0], width, height, ((thumb_max_width - left_thumb_width) / 2), xmb->margins_screen_top + (xmb->icon_size * (!(xmb->depth == 1)? 2.2 : 0.75)) + left_thumb_height, @@ -3457,7 +3644,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) &mymat, xmb->textures.list[XMB_TEXTURE_ARROW], xmb->x + xmb->margins_screen_left + - xmb->icon_spacing_horizontal - + 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 @@ -3490,9 +3677,9 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) uintptr_t texture = node->icon; float x = xmb->x + xmb->categories_x_pos + xmb->margins_screen_left + - xmb->icon_spacing_horizontal + xmb->icon_spacing_horizontal * (i + 1) - xmb->icon_size / 2.0; - float y = xmb->margins_screen_top + float y = xmb->margins_screen_top + xmb->icon_size / 2.0; float rotation = 0; float scale_factor = node->zoom; @@ -3524,7 +3711,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) /* Right side 2 thumbnails on top of each other */ /* here to be displayed above the horizontal icons */ - if (!hide_thumbnails && !xmb->savestate_thumbnail && xmb->use_ps3_layout && + if (!hide_thumbnails && !xmb->savestate_thumbnail && xmb->use_ps3_layout && xmb->left_thumbnail && xmb->thumbnail && settings->bools.menu_xmb_vertical_thumbnails) { @@ -3593,9 +3780,9 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) /* Do not draw the left thumbnail if there is no space available */ - if (((xmb->margins_screen_top + + if (((xmb->margins_screen_top + xmb->icon_size + min_thumb_size) <= height) && - ((xmb->margins_screen_left * scale_mod[5] + + ((xmb->margins_screen_left * scale_mod[5] + xmb->icon_spacing_horizontal + pseudo_font_length + min_thumb_size) <= width)) { @@ -3667,7 +3854,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) xmb->selection_buf_old, xmb->selection_ptr_old, (xmb_list_get_size(xmb, MENU_LIST_PLAIN) > 1) - ? xmb->categories_selection_ptr : + ? xmb->categories_selection_ptr : xmb->categories_selection_ptr_old, &item_color[0], width, @@ -3803,7 +3990,7 @@ static void xmb_layout_psp(xmb_handle_t *xmb, int width) float scale_factor = ((settings->uints.menu_xmb_scale_factor * width) / (1920.0 * 100)) * 1.5; #ifdef _3DS - scale_factor = + scale_factor = settings->uints.menu_xmb_scale_factor / 400.0; #endif @@ -4346,6 +4533,10 @@ static const char *xmb_texture_path(unsigned id) return "netplay.png"; case XMB_TEXTURE_ROOM: return "room.png"; + case XMB_TEXTURE_LANROOM: + return "netplay - LAN Room.png"; + case XMB_TEXTURE_IROOM: + return "netplay - iRoom.png"; #if 0 /* stub these out until we have the icons */ case XMB_TEXTURE_ROOM_LAN: @@ -4360,7 +4551,60 @@ static const char *xmb_texture_path(unsigned id) return "key-hover.png"; case XMB_TEXTURE_DIALOG_SLICE: return "dialog-slice.png"; - + case XMB_TEXTURE_ACHIEVEMENTS: + return "menu_achievements.png"; + case XMB_TEXTURE_AUDIO: + return "menu_audio.png"; + case XMB_TEXTURE_DRIVERS: + return "menu_drivers.png"; + case XMB_TEXTURE_EXIT: + return "menu_exit.png"; + case XMB_TEXTURE_FRAMESKIP: + return "menu_frameskip.png"; + case XMB_TEXTURE_HELP: + return "menu_help.png"; + case XMB_TEXTURE_INFO: + return "menu_info.png"; + case XMB_TEXTURE_INPUT: + return "Libretro - Pad.png"; + case XMB_TEXTURE_LATENCY: + return "menu_latency.png"; + case XMB_TEXTURE_NETWORK: + return "menu_network.png"; + case XMB_TEXTURE_POWER: + return "menu_power.png"; + case XMB_TEXTURE_RECORD: + return "menu_record.png"; + case XMB_TEXTURE_SAVING: + return "menu_saving.png"; + case XMB_TEXTURE_UPDATER: + return "menu_updater.png"; + case XMB_TEXTURE_VIDEO: + return "menu_video.png"; + case XMB_TEXTURE_MIXER: + return "menu_mixer.png"; + case XMB_TEXTURE_LOG: + return "menu_log.png"; + case XMB_TEXTURE_OSD: + return "menu_osd.png"; + case XMB_TEXTURE_UI: + return "menu_ui.png"; + case XMB_TEXTURE_USER: + return "menu_user.png"; + case XMB_TEXTURE_PRIVACY: + return "menu_privacy.png"; + case XMB_TEXTURE_PLAYLIST: + return "menu_playlist.png"; + case XMB_TEXTURE_QUICKMENU: + return "menu_quickmenu.png"; + case XMB_TEXTURE_REWIND: + return "menu_rewind.png"; + case XMB_TEXTURE_OVERLAY: + return "menu_overlay.png"; + case XMB_TEXTURE_OVERRIDE: + return "menu_override.png"; + case XMB_TEXTURE_NOTIFICATIONS: + return "menu_notifications.png"; } return NULL; @@ -5041,14 +5285,18 @@ static int xmb_list_push(void *data, void *userdata, entry.enum_idx = MENU_ENUM_LABEL_ADD_CONTENT_LIST; menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); -#if defined(HAVE_NETWORKING) +#ifdef HAVE_QT + if (settings->bools.desktop_menu_enable) { - settings_t *settings = config_get_ptr(); - if (settings->bools.menu_show_online_updater && !settings->bools.kiosk_mode_enable) - { - entry.enum_idx = MENU_ENUM_LABEL_ONLINE_UPDATER; - menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); - } + entry.enum_idx = MENU_ENUM_LABEL_SHOW_WIMP; + menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); + } +#endif +#if defined(HAVE_NETWORKING) + if (settings->bools.menu_show_online_updater && !settings->bools.kiosk_mode_enable) + { + entry.enum_idx = MENU_ENUM_LABEL_ONLINE_UPDATER; + menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); } #endif if (!settings->bools.menu_content_show_settings && !string_is_empty(settings->paths.menu_content_show_settings_password)) @@ -5085,7 +5333,6 @@ static int xmb_list_push(void *data, void *userdata, entry.enum_idx = MENU_ENUM_LABEL_HELP_LIST; menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); } - #if !defined(IOS) if (settings->bools.menu_show_quit_retroarch) { diff --git a/menu/drivers_display/menu_display_d3d10.c b/menu/drivers_display/menu_display_d3d10.c index 234524d1ca..6bc9079c41 100644 --- a/menu/drivers_display/menu_display_d3d10.c +++ b/menu/drivers_display/menu_display_d3d10.c @@ -208,8 +208,10 @@ static void menu_display_d3d10_draw_pipeline(menu_display_ctx_draw_t* draw, desc.ByteWidth = ca->coords.vertices * 2 * sizeof(float); desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; - D3D10_SUBRESOURCE_DATA vertexData = { ca->coords.vertex }; - D3D10CreateBuffer(d3d10->device, &desc, &vertexData, &d3d10->menu_pipeline_vbo); + { + D3D10_SUBRESOURCE_DATA vertexData = { ca->coords.vertex }; + D3D10CreateBuffer(d3d10->device, &desc, &vertexData, &d3d10->menu_pipeline_vbo); + } } D3D10SetVertexBuffer(d3d10->device, 0, d3d10->menu_pipeline_vbo, 2 * sizeof(float), 0); draw->coords->vertices = ca->coords.vertices; diff --git a/menu/drivers_display/menu_display_d3d11.c b/menu/drivers_display/menu_display_d3d11.c index ce68977fce..2e579cb49b 100644 --- a/menu/drivers_display/menu_display_d3d11.c +++ b/menu/drivers_display/menu_display_d3d11.c @@ -207,8 +207,10 @@ static void menu_display_d3d11_draw_pipeline(menu_display_ctx_draw_t *draw, desc.ByteWidth = ca->coords.vertices * 2 * sizeof(float); desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - D3D11_SUBRESOURCE_DATA vertexData = { ca->coords.vertex }; - D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->menu_pipeline_vbo); + { + D3D11_SUBRESOURCE_DATA vertexData = { ca->coords.vertex }; + D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->menu_pipeline_vbo); + } } D3D11SetVertexBuffer(d3d11->context, 0, d3d11->menu_pipeline_vbo, 2 * sizeof(float), 0); draw->coords->vertices = ca->coords.vertices; diff --git a/menu/drivers_display/menu_display_metal.m b/menu/drivers_display/menu_display_metal.m index 7ff5a5bfa7..d15e4ed98e 100644 --- a/menu/drivers_display/menu_display_metal.m +++ b/menu/drivers_display/menu_display_metal.m @@ -1,9 +1,17 @@ -// -// menu_display_metal.m -// RetroArch_Metal -// -// Created by Stuart Carnie on 5/25/18. -// +/* RetroArch - A frontend for libretro. + * Copyright (C) 2018 - Stuart Carnie + * + * 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 diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 962eedebbf..1801b78e16 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4857,7 +4857,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) string_is_equal(core_path, path_get(RARCH_PATH_CORE))) { strlcpy(new_path_entry, core_path, sizeof(new_path_entry)); - snprintf(new_entry, sizeof(new_entry), "%s (%s)", + snprintf(new_entry, sizeof(new_entry), "%s (%s)", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DETECT_CORE_LIST_OK_CURRENT_CORE), core_name); new_lbl_entry[0] = '\0'; @@ -5538,7 +5538,11 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_SHOW_HELP, PARSE_ONLY_BOOL, false); - +#ifdef HAVE_QT + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_SHOW_WIMP, + PARSE_ONLY_UINT, false); +#endif menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_SHOW_QUIT_RETROARCH, PARSE_ONLY_BOOL, false); @@ -6291,11 +6295,11 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_SCREEN_RESOLUTION, PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION, + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER, + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER, PARSE_ONLY_UINT, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_PAL60_ENABLE, @@ -6908,7 +6912,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) { settings_t *settings = config_get_ptr(); - if (settings->bools.quick_menu_show_save_core_overrides + if (settings->bools.quick_menu_show_save_core_overrides && !settings->bools.kiosk_mode_enable) { menu_entries_append_enum(info->list, @@ -6919,7 +6923,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) count++; } - if (settings->bools.quick_menu_show_save_content_dir_overrides + if (settings->bools.quick_menu_show_save_content_dir_overrides && !settings->bools.kiosk_mode_enable) { menu_entries_append_enum(info->list, @@ -6930,7 +6934,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) count++; } - if (settings->bools.quick_menu_show_save_game_overrides + if (settings->bools.quick_menu_show_save_game_overrides && !settings->bools.kiosk_mode_enable) { menu_entries_append_enum(info->list, diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index 8fe0bea1a7..0109486219 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -23,6 +23,8 @@ #include #include +#include "../setting_list.h" + #ifndef COLLECTION_SIZE #define COLLECTION_SIZE 99999 #endif diff --git a/menu/menu_driver.c b/menu/menu_driver.c index a3033c9c36..effc75d61a 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -29,6 +29,10 @@ #include #endif +#ifdef HAVE_DISCORD +#include "discord/discord.h" +#endif + #ifdef HAVE_CONFIG_H #include "../config.h" #endif @@ -458,11 +462,18 @@ bool menu_display_libretro(bool is_idle, input_driver_set_libretro_input_blocked(); core_run(); - input_driver_unset_libretro_input_blocked(); + return true; } +#ifdef HAVE_DISCORD + discord_userdata_t userdata; + userdata.status = DISCORD_PRESENCE_GAME_PAUSED; + + command_event(CMD_EVENT_DISCORD_UPDATE, &userdata); +#endif + if (is_idle) return true; /* Maybe return false here for indication of idleness? */ @@ -1472,7 +1483,7 @@ void menu_display_draw_keyboard( } menu_display_draw_text(font, grid[i], - width/2.0 - (11*ptr_width)/2.0 + (i % 11) + width/2.0 - (11*ptr_width)/2.0 + (i % 11) * ptr_width + ptr_width/2.0, height/2.0 + ptr_height + line_y + font->size / 3, width, height, 0xffffffff, TEXT_ALIGN_CENTER, 1.0f, diff --git a/menu/menu_driver.h b/menu/menu_driver.h index 357f677b19..c802d8e812 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -278,6 +278,7 @@ enum xmb_icon_theme XMB_ICON_THEME_CUSTOM, XMB_ICON_THEME_RETROSYSTEM, XMB_ICON_THEME_MONOCHROME_INVERTED, + XMB_ICON_THEME_AUTOMATIC, XMB_ICON_THEME_LAST }; diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 4fb276be24..a83667cd68 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -2468,7 +2468,16 @@ static bool setting_append_list( &subgroup_info, parent_group); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); - +#ifdef HAVE_QT + CONFIG_ACTION( + list, list_info, + MENU_ENUM_LABEL_SHOW_WIMP, + MENU_ENUM_LABEL_VALUE_SHOW_WIMP, + &group_info, + &subgroup_info, + parent_group); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_UI_COMPANION_TOGGLE); +#endif #if !defined(IOS) /* Apple rejects iOS apps that let you forcibly quit them. */ CONFIG_ACTION( @@ -3497,7 +3506,7 @@ static bool setting_append_list( case SETTINGS_LIST_CHEAT_SEARCH: if ( ! cheat_manager_state.cheats ) break ; - + START_GROUP(list, list_info, &group_info, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEAT_SEARCH_SETTINGS), parent_group); parent_group = msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_SEARCH_SETTINGS); @@ -3764,9 +3773,9 @@ static bool setting_append_list( general_write_handler, general_read_handler, SD_FLAG_NONE); - - - CONFIG_BOOL( + + + CONFIG_BOOL( list, list_info, &settings->bools.crt_switch_resolution, MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION, @@ -3780,18 +3789,18 @@ static bool setting_append_list( general_write_handler, general_read_handler, SD_FLAG_ADVANCED - ); - + ); + CONFIG_UINT( - list, list_info, - &settings->uints.crt_switch_resolution_super, - MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER, - MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, - crt_switch_resolution_super, - &group_info, - &subgroup_info, - parent_group, - general_write_handler, + list, list_info, + &settings->uints.crt_switch_resolution_super, + MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER, + MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION_SUPER, + crt_switch_resolution_super, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); @@ -6382,6 +6391,7 @@ static bool setting_append_list( general_read_handler, SD_FLAG_NONE); +#ifdef HAVE_SHADERPIPELINE if (video_shader_any_supported()) { CONFIG_UINT( @@ -6397,6 +6407,7 @@ static bool setting_append_list( general_read_handler); menu_settings_list_current_add_range(list, list_info, 0, XMB_SHADER_PIPELINE_LAST-1, 1, true, true); } +#endif CONFIG_UINT( list, list_info, diff --git a/menu/menu_shader.c b/menu/menu_shader.c index f6855c82fa..379be3709e 100644 --- a/menu/menu_shader.c +++ b/menu/menu_shader.c @@ -303,7 +303,7 @@ bool menu_shader_manager_save_preset( { strlcpy(default_preset, "menu", sizeof(default_preset)); - strlcat(default_preset, + strlcat(default_preset, preset_ext, sizeof(default_preset)); } diff --git a/msg_hash.h b/msg_hash.h index 8c75461637..2a76a08cb5 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -426,6 +426,14 @@ enum msg_hash_enums MENU_ENUM_LABEL_DISCORD_IN_MENU, MENU_ENUM_LABEL_VALUE_DISCORD_IN_MENU, + MENU_ENUM_LABEL_DISCORD_IN_GAME, + MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME, + MENU_ENUM_LABEL_DISCORD_IN_GAME_PAUSED, + MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED, + MENU_ENUM_LABEL_DISCORD_STATUS_PLAYING, + MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING, + MENU_ENUM_LABEL_DISCORD_STATUS_PAUSED, + MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED, MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY, MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_LOOPED, @@ -459,6 +467,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_SYSTEMATIC, MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART, MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, + MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_AUTOMATIC, MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LEGACY_RED, MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK_PURPLE, @@ -1496,6 +1505,7 @@ enum msg_hash_enums MENU_LABEL(BUILDBOT_ASSETS_URL), MENU_LABEL(CORE_SET_SUPPORTS_NO_CONTENT_ENABLE), MENU_LABEL(CLOSE_CONTENT), + MENU_LABEL(SHOW_WIMP), MENU_LABEL(QUIT_RETROARCH), MENU_LABEL(SHUTDOWN), MENU_LABEL(REBOOT), @@ -1886,6 +1896,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW, MENU_ENUM_LABEL_VALUE_QT_MENU_SEARCH_CLEAR, MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_CLOSED_DOCKS, + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_SHADER_PARAMS, MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS, MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS, MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY, @@ -1900,6 +1911,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SHOW_HIDDEN_FILES, MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_LIST_MAX_COUNT, MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_GRID_MAX_COUNT, + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_STARTUP_PLAYLIST, MENU_ENUM_LABEL_VALUE_QT_MENU_TOOLS, MENU_ENUM_LABEL_VALUE_QT_MENU_HELP, MENU_ENUM_LABEL_VALUE_QT_MENU_DOCK_CONTENT_BROWSER, @@ -1978,6 +1990,27 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_NIGHTLY, MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FINISHED, MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FAILED, + MENU_ENUM_LABEL_VALUE_QT_CURRENT_SHADER, + MENU_ENUM_LABEL_VALUE_QT_MOVE_DOWN, + MENU_ENUM_LABEL_VALUE_QT_MOVE_UP, + MENU_ENUM_LABEL_VALUE_QT_LOAD, + MENU_ENUM_LABEL_VALUE_QT_SAVE, + MENU_ENUM_LABEL_VALUE_QT_REMOVE, + MENU_ENUM_LABEL_VALUE_QT_APPLY, + MENU_ENUM_LABEL_VALUE_QT_SHADER_ADD_PASS, + MENU_ENUM_LABEL_VALUE_QT_SHADER_CLEAR_ALL_PASSES, + MENU_ENUM_LABEL_VALUE_QT_SHADER_NO_PASSES, + MENU_ENUM_LABEL_VALUE_QT_RESET_PASS, + MENU_ENUM_LABEL_VALUE_QT_RESET_ALL_PASSES, + MENU_ENUM_LABEL_VALUE_QT_RESET_PARAMETER, + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_THUMBNAIL, + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALREADY_IN_PROGRESS, + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS, + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_ENTIRE_SYSTEM, + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_THIS_PLAYLIST, + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_PACK_DOWNLOADED_SUCCESSFULLY, + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_PLAYLIST_THUMBNAIL_PROGRESS, + MENU_ENUM_LABEL_VALUE_QT_CORE_OPTIONS, MENU_LABEL(MIDI_INPUT), MENU_LABEL(MIDI_OUTPUT), diff --git a/pkg/android/phoenix/AndroidManifest.xml b/pkg/android/phoenix/AndroidManifest.xml index 703a158568..7e5c77ceeb 100644 --- a/pkg/android/phoenix/AndroidManifest.xml +++ b/pkg/android/phoenix/AndroidManifest.xml @@ -1,8 +1,8 @@ diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.NativeActivity/msvc-2017-android.NativeActivity.vcxproj b/pkg/android/phoenix/msvc-2017-android.NativeActivity.vcxproj similarity index 97% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.NativeActivity/msvc-2017-android.NativeActivity.vcxproj rename to pkg/android/phoenix/msvc-2017-android.NativeActivity.vcxproj index b491d44aaf..bc86a3ea31 100644 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.NativeActivity/msvc-2017-android.NativeActivity.vcxproj +++ b/pkg/android/phoenix/msvc-2017-android.NativeActivity.vcxproj @@ -35,7 +35,7 @@ - + CompileAsC CompileAsC CompileAsC @@ -45,7 +45,7 @@ CompileAsC CompileAsC - + c++11 c++11 c++11 @@ -55,7 +55,7 @@ c++11 c++11 - + c++11 c++11 c++11 @@ -69,12 +69,12 @@ {e27d73ec-6148-4817-b75c-adaa0c563939} Android - msvc-2017-android + retroarch-activity en-US 14.0 Android 3.0 - msvc-2017-android.NativeActivity + retroarch-activity.NativeActivity diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.NativeActivity/msvc-2017-android.NativeActivity.vcxproj.filters b/pkg/android/phoenix/msvc-2017-android.NativeActivity.vcxproj.filters similarity index 100% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.NativeActivity/msvc-2017-android.NativeActivity.vcxproj.filters rename to pkg/android/phoenix/msvc-2017-android.NativeActivity.vcxproj.filters diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/msvc-2017-android.Packaging.androidproj b/pkg/android/phoenix/msvc-2017-android.Packaging.androidproj similarity index 90% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/msvc-2017-android.Packaging.androidproj rename to pkg/android/phoenix/msvc-2017-android.Packaging.androidproj index 8c8883cb06..e61050d3de 100644 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/msvc-2017-android.Packaging.androidproj +++ b/pkg/android/phoenix/msvc-2017-android.Packaging.androidproj @@ -35,7 +35,7 @@ - msvc-2017-android + retroarch-activity 14.0 1.0 {94b52983-76de-4545-a708-433c377727c7} @@ -44,42 +44,34 @@ true Application - android-23 false Application - android-23 true Application - android-23 false Application - android-23 true Application - android-23 false Application - android-23 true Application - android-23 false Application - android-23 @@ -129,10 +121,9 @@ - - + {e27d73ec-6148-4817-b75c-adaa0c563939} diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.sln b/pkg/android/phoenix/msvc-2017-android.sln similarity index 92% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.sln rename to pkg/android/phoenix/msvc-2017-android.sln index 3b63d42249..45919ce71c 100644 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.sln +++ b/pkg/android/phoenix/msvc-2017-android.sln @@ -5,9 +5,9 @@ VisualStudioVersion = 15.0.26228.9 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "msvc-2017-android", "msvc-2017-android", "{82FC602D-4083-4ED5-858B-A066A4280E4C}" EndProject -Project("{39E2626F-3545-4960-A6E8-258AD8476CE5}") = "msvc-2017-android.Packaging", "msvc-2017-android.Packaging\msvc-2017-android.Packaging.androidproj", "{94B52983-76DE-4545-A708-433C377727C7}" +Project("{39E2626F-3545-4960-A6E8-258AD8476CE5}") = "msvc-2017-android.Packaging", "msvc-2017-android.Packaging.androidproj", "{94B52983-76DE-4545-A708-433C377727C7}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msvc-2017-android.NativeActivity", "msvc-2017-android.NativeActivity\msvc-2017-android.NativeActivity.vcxproj", "{E27D73EC-6148-4817-B75C-ADAA0C563939}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msvc-2017-android.NativeActivity", "msvc-2017-android.NativeActivity.vcxproj", "{E27D73EC-6148-4817-B75C-ADAA0C563939}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java b/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java index 88d25d6ee8..3861fea250 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java @@ -30,6 +30,7 @@ import android.util.Log; public final class MainMenuActivity extends PreferenceActivity { final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124; + public static String PACKAGE_NAME; boolean checkPermissions = false; public void showMessageOKCancel(String message, DialogInterface.OnClickListener onClickListener) @@ -181,7 +182,7 @@ public final class MainMenuActivity extends PreferenceActivity retro.putExtra("SDCARD", Environment.getExternalStorageDirectory().getAbsolutePath()); retro.putExtra("DOWNLOADS", Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()); retro.putExtra("SCREENSHOTS", Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()); - String external = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/com.retroarch/files"; + String external = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + PACKAGE_NAME + "/files"; retro.putExtra("EXTERNAL", external); } @@ -190,6 +191,8 @@ public final class MainMenuActivity extends PreferenceActivity { super.onCreate(savedInstanceState); + PACKAGE_NAME = getPackageName(); + // Bind audio stream to hardware controls. setVolumeControlStream(AudioManager.STREAM_MUSIC); diff --git a/pkg/android/phoenix64/.classpath b/pkg/android/phoenix64/.classpath new file mode 100644 index 0000000000..51769745b2 --- /dev/null +++ b/pkg/android/phoenix64/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/pkg/android/phoenix64/.gitignore b/pkg/android/phoenix64/.gitignore new file mode 100644 index 0000000000..859bcd7938 --- /dev/null +++ b/pkg/android/phoenix64/.gitignore @@ -0,0 +1,5 @@ +/gen +/bin +/libs/*/*.so +/obj +/jni/modules/*.so diff --git a/pkg/android/phoenix64/.project b/pkg/android/phoenix64/.project new file mode 100644 index 0000000000..4af1961cac --- /dev/null +++ b/pkg/android/phoenix64/.project @@ -0,0 +1,33 @@ + + + RetroArch + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/AndroidManifest.xml b/pkg/android/phoenix64/AndroidManifest.xml similarity index 94% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/AndroidManifest.xml rename to pkg/android/phoenix64/AndroidManifest.xml index 703a158568..eceecb0d32 100644 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/AndroidManifest.xml +++ b/pkg/android/phoenix64/AndroidManifest.xml @@ -1,8 +1,8 @@ @@ -10,7 +10,7 @@ + android:targetSdkVersion="26" /> @@ -18,7 +18,7 @@ diff --git a/pkg/android/phoenix64/Readme.md b/pkg/android/phoenix64/Readme.md new file mode 100644 index 0000000000..ce900d257e --- /dev/null +++ b/pkg/android/phoenix64/Readme.md @@ -0,0 +1,3 @@ +# Phoenix - Android front-end for RetroArch. + +- For instructions on importing the project correctly, please see the document, "Building in Eclipse.txt" within the docs folder. \ No newline at end of file diff --git a/pkg/android/phoenix64/ant.properties b/pkg/android/phoenix64/ant.properties new file mode 100644 index 0000000000..97d04e9d39 --- /dev/null +++ b/pkg/android/phoenix64/ant.properties @@ -0,0 +1,17 @@ +# This file is used to override default values used by the Ant build system. +# +# This file must be checked into Version Control Systems, as it is +# integral to the build system of your project. + +# This file is only used by the Ant script. + +# You can use this to override default values such as +# 'source.dir' for the location of your java source folder and +# 'out.dir' for the location of your output folder. + +# You can also use it define how the release builds are signed by declaring +# the following properties: +# 'key.store' for the location of your keystore and +# 'key.alias' for the name of the key to use. +# The password will be asked during the build when you use the 'release' target. +source.dir=../phoenix/src diff --git a/pkg/android/phoenix64/build.xml b/pkg/android/phoenix64/build.xml new file mode 100644 index 0000000000..9698a04abf --- /dev/null +++ b/pkg/android/phoenix64/build.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pkg/android/phoenix64/docs/Building in Eclipse.md b/pkg/android/phoenix64/docs/Building in Eclipse.md new file mode 100644 index 0000000000..bef2b9aea3 --- /dev/null +++ b/pkg/android/phoenix64/docs/Building in Eclipse.md @@ -0,0 +1,45 @@ +## Building the JNI-related files for Phoenix. + + 1. If you haven't already, install the Android NDK (http://developer.android.com/tools/sdk/ndk/index.html) + + 2. In the Phoenix root directory you should notice the folder named "jni". + + 3. Open Command Prompt/Terminal and cd into this directory. + + 4. Run ndk-build within this directory (just type "ndk-build" and hit Enter) and wait for everything to finish building. + + 5. All built libraries should now reside within the "libs" directory. + + 6. Continue to the next section of this document. + + + +## How to import the project into Eclipse and build the front-end: + + 1. Install the Android ADT plugin for Eclipse if you haven't. (http://developer.android.com/sdk/installing/installing-adt.html) + + 2. In Eclipse, do: File->Import->Existing Android Code Into Workspace. + + 3. Browse to the location of the folder named "phoenix" in the RetroArch repository and select it as the root dir. (as of writing, it is /android/phoenix). + + 4. You should see two projects have been found, "RetroArch" and "android-support-v7-appcompat". Import both of these. + + 5. Let Eclipse finish building the workspace, or whatever. + + 6. You should now be able to build it normally like any application. + + + +## Where do I place the built libretro cores? + +Simply place all built libretro cores within the directory [phoenix root]/assets/cores. Create this directory if it doesn't exist already. +After placing your cores there, they should show up within the core selection screen of the front-end. + +## Where do I place overlays, shaders and core info files? + +Core info files go in [phoenix root]/assets/info, GLSL shaders go in [phoenix root]/assets/shaders_glsl and overlays go in [phoenix root]/assets/overlays. If the folders don't exist, create them first. + +## Notes + +1. If you’re running into an issue where adding an existing Android project results in “Invalid project description”, please select a workspace location that doesn’t contain the Android projects. +2. If Eclipse still complains about missing appcompat, right-click on RetroArch->Properties->Android->Library->Add “android-support-v7-appcompat”, and then remove the old appcompat reference. diff --git a/pkg/android/phoenix64/jni/Android.mk b/pkg/android/phoenix64/jni/Android.mk new file mode 100644 index 0000000000..a44f14fa8b --- /dev/null +++ b/pkg/android/phoenix64/jni/Android.mk @@ -0,0 +1,129 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +RARCH_DIR := ../../../.. + +HAVE_NEON := 1 +HAVE_LOGGER := 0 +HAVE_VULKAN := 1 + +INCFLAGS := +DEFINES := + +LIBRETRO_COMM_DIR := $(RARCH_DIR)/libretro-common +DEPS_DIR := $(RARCH_DIR)/deps + +GIT_VERSION := $(shell git rev-parse --short HEAD 2>/dev/null) +ifneq ($(GIT_VERSION),) + DEFINES += -DHAVE_GIT_VERSION -DGIT_VERSION=$(GIT_VERSION) +endif + +include $(CLEAR_VARS) +ifeq ($(TARGET_ARCH),arm) + DEFINES += -DANDROID_ARM -marm + LOCAL_ARM_MODE := arm +endif + +ifeq ($(TARGET_ARCH),x86) + DEFINES += -DANDROID_X86 -DHAVE_SSSE3 +endif + +ifeq ($(TARGET_ARCH),x86_64) + DEFINES += -DANDROID_X64 +endif + +ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) + +ifeq ($(HAVE_NEON),1) + DEFINES += -D__ARM_NEON__ -DHAVE_NEON + LOCAL_SRC_FILES += $(LIBRETRO_COMM_DIR)/audio/conversion/s16_to_float_neon.S.neon \ + $(LIBRETRO_COMM_DIR)/audio/conversion/float_to_s16_neon.S.neon \ + $(LIBRETRO_COMM_DIR)/audio/resampler/drivers/sinc_resampler_neon.S.neon \ + $(RARCH_DIR)/audio/drivers_resampler/cc_resampler_neon.S.neon +endif +DEFINES += -DANDROID_ARM_V7 +endif + +ifeq ($(TARGET_ARCH_ABI),arm64-v8a) + DEFINES += -DANDROID_AARCH64 +endif + +ifeq ($(TARGET_ARCH),mips) + DEFINES += -DANDROID_MIPS -D__mips__ -D__MIPSEL__ +endif + +LOCAL_MODULE := retroarch-activity + +LOCAL_SRC_FILES += $(RARCH_DIR)/griffin/griffin.c \ + $(RARCH_DIR)/griffin/griffin_cpp.cpp + +ifeq ($(HAVE_LOGGER), 1) + DEFINES += -DHAVE_LOGGER +endif +LOGGER_LDLIBS := -llog + +ifeq ($(GLES),3) + GLES_LIB := -lGLESv3 + DEFINES += -DHAVE_OPENGLES3 +else + GLES_LIB := -lGLESv2 + DEFINES += -DHAVE_OPENGLES2 +endif + +DEFINES += -DRARCH_MOBILE -DHAVE_GRIFFIN -DHAVE_STB_VORBIS -DHAVE_LANGEXTRA -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_OVERLAY -DHAVE_OPENGLES -DGLSL_DEBUG -DHAVE_DYLIB -DHAVE_EGL -DHAVE_GLSL -DHAVE_MENU -DHAVE_RGUI -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DINLINE=inline -DHAVE_THREADS -D__LIBRETRO__ -DHAVE_RSOUND -DHAVE_NETWORKGAMEPAD -DHAVE_NETWORKING -DRARCH_INTERNAL -DHAVE_FILTERS_BUILTIN -DHAVE_MATERIALUI -DHAVE_XMB -DHAVE_SHADERPIPELINE -DHAVE_LIBRETRODB -DHAVE_STB_FONT -DHAVE_IMAGEVIEWER -DHAVE_UPDATE_ASSETS -DHAVE_CC_RESAMPLER -DHAVE_MINIUPNPC -DHAVE_BUILTINMINIUPNPC -DMINIUPNPC_SET_SOCKET_TIMEOUT -DMINIUPNPC_GET_SRC_ADDR -DHAVE_KEYMAPPER -DHAVE_NETWORKGAMEPAD -DHAVE_FLAC -DHAVE_DR_FLAC -DHAVE_DR_MP3 -DHAVE_CHD -DHAVE_RUNAHEAD -DENABLE_HLSL +DEFINES += -DWANT_IFADDRS + +ifeq ($(HAVE_VULKAN),1) +DEFINES += -DHAVE_VULKAN -DHAVE_SLANG -DHAVE_GLSLANG -DHAVE_SPIRV_CROSS -DWANT_GLSLANG -D__STDC_LIMIT_MACROS +endif +DEFINES += -DHAVE_7ZIP +DEFINES += -DHAVE_CHEEVOS +DEFINES += -DHAVE_SL +#DEFINES += -DHAVE_TINYALSA +DEFINES += -DFLAC_PACKAGE_VERSION="\"retroarch\"" -DHAVE_LROUND -DFLAC__HAS_OGG=0 + +LOCAL_CFLAGS += -Wall -std=gnu99 -pthread -Wno-unused-function -fno-stack-protector -funroll-loops $(DEFINES) +LOCAL_CPPFLAGS := -fexceptions -fpermissive -std=gnu++11 -fno-rtti -Wno-reorder $(DEFINES) + +# Let ndk-build set the optimization flags but remove -O3 like in cf3c3 +LOCAL_CFLAGS := $(subst -O3,-O2,$(LOCAL_CFLAGS)) + +LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -landroid -lEGL $(GLES_LIB) $(LOGGER_LDLIBS) -ldl +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/$(RARCH_DIR)/libretro-common/include/ \ + $(LOCAL_PATH)/$(RARCH_DIR)/deps \ + $(LOCAL_PATH)/$(RARCH_DIR)/deps/stb \ + $(LOCAL_PATH)/$(RARCH_DIR)/deps/7zip + + +LOCAL_CFLAGS += -I$(LOCAL_PATH)/$(DEPS_DIR)/stb/ +LOCAL_CFLAGS += -I$(LOCAL_PATH)/$(DEPS_DIR)/7zip/ +LOCAL_CXXFLAGS += -I$(LOCAL_PATH)/$(DEPS_DIR)/stb/ +LOCAL_CXXFLAGS += -I$(LOCAL_PATH)/$(DEPS_DIR)/7zip/ +LOCAL_CFLAGS += -I$(LOCAL_PATH)/$(DEPS_DIR)/libFLAC/include +LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/$(DEPS_DIR)/libFLAC/include + +ifeq ($(HAVE_VULKAN),1) +INCFLAGS += $(LOCAL_PATH)/$(RARCH_DIR)/gfx/include + +LOCAL_C_INCLUDES += $(INCFLAGS) +LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/$(DEPS_DIR)/glslang \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/glslang/glslang/glslang/Public \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/glslang/glslang/SPIRV \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/SPIRV-Cross + +LOCAL_CFLAGS += -Wno-sign-compare -Wno-unused-variable -Wno-parentheses +LOCAL_SRC_FILES += $(RARCH_DIR)/griffin/griffin_glslang.cpp +endif + +LOCAL_LDLIBS += -lOpenSLES -lz + +ifneq ($(SANITIZER),) + LOCAL_CFLAGS += -g -fsanitize=$(SANITIZER) -fno-omit-frame-pointer + LOCAL_CPPFLAGS += -g -fsanitize=$(SANITIZER) -fno-omit-frame-pointer + LOCAL_LDFLAGS += -fsanitize=$(SANITIZER) +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/pkg/android/phoenix64/jni/Application.mk b/pkg/android/phoenix64/jni/Application.mk new file mode 100644 index 0000000000..5058071558 --- /dev/null +++ b/pkg/android/phoenix64/jni/Application.mk @@ -0,0 +1,42 @@ +ifeq ($(GLES),3) + ifndef NDK_GL_HEADER_VER + APP_PLATFORM := android-18 + else + APP_PLATFORM := $(NDK_GL_HEADER_VER) + endif +else + ifndef NDK_NO_GL_HEADER_VER + APP_PLATFORM := android-9 + else + APP_PLATFORM := $(NDK_NO_GL_HEADER_VER) + endif +endif + +ifndef TARGET_ABIS + APP_ABI := arm64-v8a +else + APP_ABI := $(TARGET_ABIS) +endif + +# Run $NDK/toolchains/llvm-3.6/prebuilt/linux-x86_64/bin/asan_device_setup once +# for each AVD you use, replacing llvm-3.6 with the latest you have and +# linux-x86_64 with your host ABI. +ifneq ($(SANITIZER),) + # AddressSanitizer doesn't run on mips + ifndef TARGET_ABIS + APP_ABI := arm64-v8a + else + ifneq ($(findstring mips,$(TARGET_ABIS)),) + $(error "AddressSanitizer does not support mips.") + endif + endif + USE_CLANG := 1 +endif + +ifeq ($(USE_CLANG),1) + NDK_TOOLCHAIN_VERSION := clang + APP_CFLAGS := -Wno-invalid-source-encoding + APP_CPPFLAGS := -Wno-invalid-source-encoding +endif + +APP_STL := c++_static diff --git a/pkg/android/phoenix64/libs/googleplay/.classpath b/pkg/android/phoenix64/libs/googleplay/.classpath new file mode 100644 index 0000000000..51769745b2 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/pkg/android/phoenix64/libs/googleplay/.project b/pkg/android/phoenix64/libs/googleplay/.project new file mode 100644 index 0000000000..06ae985eaa --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/.project @@ -0,0 +1,33 @@ + + + google-play-services_lib + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/pkg/android/phoenix64/libs/googleplay/AndroidManifest.xml b/pkg/android/phoenix64/libs/googleplay/AndroidManifest.xml new file mode 100644 index 0000000000..99c96a3961 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/pkg/android/phoenix64/libs/googleplay/README.txt b/pkg/android/phoenix64/libs/googleplay/README.txt new file mode 100644 index 0000000000..32f8d5eb85 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/README.txt @@ -0,0 +1,17 @@ +Library Project including Google Play services client jar. + +This can be used by an Android project to use the API's provided +by Google Play services. + +There is technically no source, but the src folder is necessary +to ensure that the build system works. The content is actually +located in the libs/ directory. + + +USAGE: + +Make sure you import this Android library project into your IDE +and set this project as a dependency. + +Note that if you use proguard, you will want to include the +options from proguard.txt in your configuration. \ No newline at end of file diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/build.xml b/pkg/android/phoenix64/libs/googleplay/build.xml similarity index 75% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/build.xml rename to pkg/android/phoenix64/libs/googleplay/build.xml index 4dd78480d3..640264ba12 100644 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/build.xml +++ b/pkg/android/phoenix64/libs/googleplay/build.xml @@ -1,90 +1,92 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pkg/android/phoenix64/libs/googleplay/libs/google-play-services.jar b/pkg/android/phoenix64/libs/googleplay/libs/google-play-services.jar new file mode 100644 index 0000000000..dff6f7c241 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/libs/google-play-services.jar differ diff --git a/pkg/android/phoenix64/libs/googleplay/proguard.txt b/pkg/android/phoenix64/libs/googleplay/proguard.txt new file mode 100644 index 0000000000..0c9693a2c0 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/proguard.txt @@ -0,0 +1,20 @@ +-keep class * extends java.util.ListResourceBundle { + protected Object[][] getContents(); +} + +# Keep SafeParcelable value, needed for reflection. This is required to support backwards +# compatibility of some classes. +-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { + public static final *** NULL; +} + +# Keep the names of classes/members we need for client functionality. +-keepnames @com.google.android.gms.common.annotation.KeepName class * +-keepclassmembernames class * { + @com.google.android.gms.common.annotation.KeepName *; +} + +# Needed for Parcelable/SafeParcelable Creators to not get stripped +-keepnames class * implements android.os.Parcelable { + public static final ** CREATOR; +} \ No newline at end of file diff --git a/pkg/android/phoenix64/libs/googleplay/project.properties b/pkg/android/phoenix64/libs/googleplay/project.properties new file mode 100644 index 0000000000..93c8c3c08d --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/project.properties @@ -0,0 +1,15 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-21 +android.library=true diff --git a/pkg/android/phoenix64/libs/googleplay/res/color/common_signin_btn_text_dark.xml b/pkg/android/phoenix64/libs/googleplay/res/color/common_signin_btn_text_dark.xml new file mode 100644 index 0000000000..a615ba2747 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/color/common_signin_btn_text_dark.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/pkg/android/phoenix64/libs/googleplay/res/color/common_signin_btn_text_light.xml b/pkg/android/phoenix64/libs/googleplay/res/color/common_signin_btn_text_light.xml new file mode 100644 index 0000000000..662066899b --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/color/common_signin_btn_text_light.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_disabled_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_disabled_dark.9.png new file mode 100644 index 0000000000..0f9e7917e0 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_disabled_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_disabled_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_disabled_focus_dark.9.png new file mode 100644 index 0000000000..570e432252 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_disabled_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_disabled_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_disabled_focus_light.9.png new file mode 100644 index 0000000000..570e432252 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_disabled_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_disabled_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_disabled_light.9.png new file mode 100644 index 0000000000..0f9e7917e0 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_disabled_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_focus_dark.9.png new file mode 100644 index 0000000000..f507b9f7da Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_focus_light.9.png new file mode 100644 index 0000000000..d5625e5fc1 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_normal_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_normal_dark.9.png new file mode 100644 index 0000000000..aea3c0d168 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_normal_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_normal_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_normal_light.9.png new file mode 100644 index 0000000000..849e89f3aa Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_normal_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_pressed_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_pressed_dark.9.png new file mode 100644 index 0000000000..f4ab2f2a51 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_pressed_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_pressed_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_pressed_light.9.png new file mode 100644 index 0000000000..9fe611d684 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_icon_pressed_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_disabled_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_disabled_dark.9.png new file mode 100644 index 0000000000..bbcde39cf0 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_disabled_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_disabled_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_disabled_focus_dark.9.png new file mode 100644 index 0000000000..53957b698f Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_disabled_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_disabled_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_disabled_focus_light.9.png new file mode 100644 index 0000000000..53957b698f Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_disabled_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_disabled_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_disabled_light.9.png new file mode 100644 index 0000000000..bbcde39cf0 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_disabled_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_focus_dark.9.png new file mode 100644 index 0000000000..000d12e8e3 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_focus_light.9.png new file mode 100644 index 0000000000..d9279405c6 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_normal_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_normal_dark.9.png new file mode 100644 index 0000000000..67f263c80e Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_normal_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_normal_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_normal_light.9.png new file mode 100644 index 0000000000..96324c52f9 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_normal_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_pressed_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_pressed_dark.9.png new file mode 100644 index 0000000000..e4503128f6 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_pressed_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_pressed_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_pressed_light.9.png new file mode 100644 index 0000000000..fb94b77616 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/common_signin_btn_text_pressed_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/ic_plusone_medium_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/ic_plusone_medium_off_client.png new file mode 100644 index 0000000000..894f1b9f93 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/ic_plusone_medium_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/ic_plusone_small_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/ic_plusone_small_off_client.png new file mode 100644 index 0000000000..ac777614e6 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/ic_plusone_small_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/ic_plusone_standard_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/ic_plusone_standard_off_client.png new file mode 100644 index 0000000000..f1c32d3b9e Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/ic_plusone_standard_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/ic_plusone_tall_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/ic_plusone_tall_off_client.png new file mode 100644 index 0000000000..08a4670c47 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-hdpi/ic_plusone_tall_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_disabled_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_disabled_dark.9.png new file mode 100644 index 0000000000..dddcbebf12 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_disabled_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_disabled_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_disabled_focus_dark.9.png new file mode 100644 index 0000000000..58b75bd7de Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_disabled_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_disabled_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_disabled_focus_light.9.png new file mode 100644 index 0000000000..58b75bd7de Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_disabled_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_disabled_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_disabled_light.9.png new file mode 100644 index 0000000000..dddcbebf12 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_disabled_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_focus_dark.9.png new file mode 100644 index 0000000000..7d9ed7834d Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_focus_light.9.png new file mode 100644 index 0000000000..0ca401d376 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_normal_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_normal_dark.9.png new file mode 100644 index 0000000000..f2c3f55717 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_normal_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_normal_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_normal_light.9.png new file mode 100644 index 0000000000..83b4fc9d6d Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_normal_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_pressed_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_pressed_dark.9.png new file mode 100644 index 0000000000..dd74fe8761 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_pressed_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_pressed_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_pressed_light.9.png new file mode 100644 index 0000000000..b7dc7aac7e Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_icon_pressed_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_disabled_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_disabled_dark.9.png new file mode 100644 index 0000000000..efdfe2e616 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_disabled_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_disabled_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_disabled_focus_dark.9.png new file mode 100644 index 0000000000..c7650b09e3 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_disabled_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_disabled_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_disabled_focus_light.9.png new file mode 100644 index 0000000000..c7650b09e3 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_disabled_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_disabled_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_disabled_light.9.png new file mode 100644 index 0000000000..efdfe2e616 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_disabled_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_focus_dark.9.png new file mode 100644 index 0000000000..8c76283e50 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_focus_light.9.png new file mode 100644 index 0000000000..abd26bcd41 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_normal_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_normal_dark.9.png new file mode 100644 index 0000000000..28181c338b Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_normal_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_normal_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_normal_light.9.png new file mode 100644 index 0000000000..34957fad5f Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_normal_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_pressed_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_pressed_dark.9.png new file mode 100644 index 0000000000..e923ee9c75 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_pressed_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_pressed_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_pressed_light.9.png new file mode 100644 index 0000000000..34cf6bbad5 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/common_signin_btn_text_pressed_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/ic_plusone_medium_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/ic_plusone_medium_off_client.png new file mode 100644 index 0000000000..d7e5777153 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/ic_plusone_medium_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/ic_plusone_small_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/ic_plusone_small_off_client.png new file mode 100644 index 0000000000..af301c2dc9 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/ic_plusone_small_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/ic_plusone_standard_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/ic_plusone_standard_off_client.png new file mode 100644 index 0000000000..f43e965fb8 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/ic_plusone_standard_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/ic_plusone_tall_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/ic_plusone_tall_off_client.png new file mode 100644 index 0000000000..0b2b5c9a98 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-mdpi/ic_plusone_tall_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_disabled_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_disabled_dark.9.png new file mode 100644 index 0000000000..9044a118af Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_disabled_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_disabled_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_disabled_focus_dark.9.png new file mode 100644 index 0000000000..e94a49b0ae Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_disabled_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_disabled_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_disabled_focus_light.9.png new file mode 100644 index 0000000000..e94a49b0ae Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_disabled_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_disabled_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_disabled_light.9.png new file mode 100644 index 0000000000..9044a118af Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_disabled_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_focus_dark.9.png new file mode 100644 index 0000000000..bfe4f04639 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_focus_light.9.png new file mode 100644 index 0000000000..876884fad7 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_normal_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_normal_dark.9.png new file mode 100644 index 0000000000..b3e6dd5b40 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_normal_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_normal_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_normal_light.9.png new file mode 100644 index 0000000000..5a888f28f5 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_normal_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_pressed_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_pressed_dark.9.png new file mode 100644 index 0000000000..d0f7b4cbf3 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_pressed_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_pressed_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_pressed_light.9.png new file mode 100644 index 0000000000..0db6b06450 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_icon_pressed_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_disabled_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_disabled_dark.9.png new file mode 100644 index 0000000000..d182b5e2c3 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_disabled_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_disabled_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_disabled_focus_dark.9.png new file mode 100644 index 0000000000..47e2aeaf32 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_disabled_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_disabled_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_disabled_focus_light.9.png new file mode 100644 index 0000000000..47e2aeaf32 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_disabled_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_disabled_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_disabled_light.9.png new file mode 100644 index 0000000000..d182b5e2c3 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_disabled_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_focus_dark.9.png new file mode 100644 index 0000000000..64e9706874 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_focus_light.9.png new file mode 100644 index 0000000000..0fd8cdda14 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_normal_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_normal_dark.9.png new file mode 100644 index 0000000000..3427b47681 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_normal_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_normal_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_normal_light.9.png new file mode 100644 index 0000000000..31e38c4c12 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_normal_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_pressed_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_pressed_dark.9.png new file mode 100644 index 0000000000..e6a7880730 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_pressed_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_pressed_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_pressed_light.9.png new file mode 100644 index 0000000000..972962dcfd Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/common_signin_btn_text_pressed_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/ic_plusone_medium_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/ic_plusone_medium_off_client.png new file mode 100644 index 0000000000..bb933092be Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/ic_plusone_medium_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/ic_plusone_small_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/ic_plusone_small_off_client.png new file mode 100644 index 0000000000..6174fcd9b1 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/ic_plusone_small_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/ic_plusone_standard_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/ic_plusone_standard_off_client.png new file mode 100644 index 0000000000..6a4c298e2d Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/ic_plusone_standard_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/ic_plusone_tall_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/ic_plusone_tall_off_client.png new file mode 100644 index 0000000000..f68e9133bb Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xhdpi/ic_plusone_tall_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_disabled_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_disabled_dark.9.png new file mode 100644 index 0000000000..9044a118af Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_disabled_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_disabled_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_disabled_focus_dark.9.png new file mode 100644 index 0000000000..e94a49b0ae Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_disabled_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_disabled_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_disabled_focus_light.9.png new file mode 100644 index 0000000000..e94a49b0ae Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_disabled_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_disabled_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_disabled_light.9.png new file mode 100644 index 0000000000..9044a118af Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_disabled_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_focus_dark.9.png new file mode 100644 index 0000000000..bfe4f04639 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_focus_light.9.png new file mode 100644 index 0000000000..876884fad7 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_normal_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_normal_dark.9.png new file mode 100644 index 0000000000..b3e6dd5b40 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_normal_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_normal_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_normal_light.9.png new file mode 100644 index 0000000000..5a888f28f5 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_normal_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_pressed_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_pressed_dark.9.png new file mode 100644 index 0000000000..d0f7b4cbf3 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_pressed_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_pressed_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_pressed_light.9.png new file mode 100644 index 0000000000..0db6b06450 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_icon_pressed_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_disabled_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_disabled_dark.9.png new file mode 100644 index 0000000000..d182b5e2c3 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_disabled_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_disabled_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_disabled_focus_dark.9.png new file mode 100644 index 0000000000..47e2aeaf32 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_disabled_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_disabled_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_disabled_focus_light.9.png new file mode 100644 index 0000000000..47e2aeaf32 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_disabled_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_disabled_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_disabled_light.9.png new file mode 100644 index 0000000000..d182b5e2c3 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_disabled_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_focus_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_focus_dark.9.png new file mode 100644 index 0000000000..64e9706874 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_focus_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_focus_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_focus_light.9.png new file mode 100644 index 0000000000..0fd8cdda14 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_focus_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_normal_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_normal_dark.9.png new file mode 100644 index 0000000000..3427b47681 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_normal_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_normal_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_normal_light.9.png new file mode 100644 index 0000000000..31e38c4c12 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_normal_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_pressed_dark.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_pressed_dark.9.png new file mode 100644 index 0000000000..e6a7880730 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_pressed_dark.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_pressed_light.9.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_pressed_light.9.png new file mode 100644 index 0000000000..972962dcfd Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/common_signin_btn_text_pressed_light.9.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/ic_plusone_medium_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/ic_plusone_medium_off_client.png new file mode 100644 index 0000000000..4f23739dc3 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/ic_plusone_medium_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/ic_plusone_small_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/ic_plusone_small_off_client.png new file mode 100644 index 0000000000..8ffa1d72e6 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/ic_plusone_small_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/ic_plusone_standard_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/ic_plusone_standard_off_client.png new file mode 100644 index 0000000000..4d81cf40cd Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/ic_plusone_standard_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/ic_plusone_tall_off_client.png b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/ic_plusone_tall_off_client.png new file mode 100644 index 0000000000..fab5a79b45 Binary files /dev/null and b/pkg/android/phoenix64/libs/googleplay/res/drawable-xxhdpi/ic_plusone_tall_off_client.png differ diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable/common_signin_btn_icon_dark.xml b/pkg/android/phoenix64/libs/googleplay/res/drawable/common_signin_btn_icon_dark.xml new file mode 100644 index 0000000000..dd1cf679fe --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/drawable/common_signin_btn_icon_dark.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable/common_signin_btn_icon_light.xml b/pkg/android/phoenix64/libs/googleplay/res/drawable/common_signin_btn_icon_light.xml new file mode 100644 index 0000000000..abf412bda8 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/drawable/common_signin_btn_icon_light.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable/common_signin_btn_text_dark.xml b/pkg/android/phoenix64/libs/googleplay/res/drawable/common_signin_btn_text_dark.xml new file mode 100644 index 0000000000..2d92217cdf --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/drawable/common_signin_btn_text_dark.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/pkg/android/phoenix64/libs/googleplay/res/drawable/common_signin_btn_text_light.xml b/pkg/android/phoenix64/libs/googleplay/res/drawable/common_signin_btn_text_light.xml new file mode 100644 index 0000000000..810c02112d --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/drawable/common_signin_btn_text_light.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-af/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-af/strings.xml new file mode 100644 index 0000000000..1b211f5076 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-af/strings.xml @@ -0,0 +1,31 @@ + + + "Kry Google Play-dienste" + "Hierdie program sal nie loop sonder Google Play-dienste nie, wat nie op jou foon is nie." + "Hierdie program sal nie loop sonder Google Play-dienste nie, wat nie op jou tablet is nie." + "Kry Google Play-dienste" + "Aktiveer Google Play-dienste" + "Hierdie program sal nie werk tensy jy Google Play-dienste aktiveer nie." + "Aktiveer Google Play-dienste" + "Dateer Google Play-dienste op" + "Hierdie program sal nie loop nie, tensy jy Google Play-dienste opdateer." + "Netwerkfout" + "\'n Dataverbinding is nodig om aan Google Play-dienste te koppel." + "Ongeldige rekening" + "Die gespesifiseerde rekening bestaan nie op hierdie toestel nie. Kies asseblief \'n ander rekening." + "Onbekende probleem met Google Play-dienste." + "Google Play-dienste" + "Google Play-dienste, waarop sommige van jou programme staatmaak, werk nie met jou toestel nie. Kontak asseblief die vervaardiger vir bystand." + "Dit lyk of die datum op die toestel verkeerd is. Gaan asseblief die datum op die toestel na." + "Dateer op" + "Meld aan" + "Meld aan met Google" + + "\'n Program het probeer om \'n slegte weergawe van Google Play-dienste te gebruik." + "\'n Program vereis dat Google Play-dienste geaktiveer word." + "\'n Program vereis dat Google Play-dienste geïnstalleer word." + "\'n Program vereis \'n opdatering vir Google Play-dienste." + "Google Play-dienstefout" + "Versoek deur %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-am/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-am/strings.xml new file mode 100644 index 0000000000..2585210fe0 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-am/strings.xml @@ -0,0 +1,31 @@ + + + "Google Play አገልግሎቶችን አግኝ" + "ይህ መተግበሪያ ያለ Google Play አገልግሎቶች አይሰራም፣ እነሱ ደግሞ ስልክዎ ላይ የሉም።" + "ይህ መተግበሪያ ያለ Google Play አገልግሎቶች አይሰራም፣ እነሱ ደግሞ ጡባዊዎ ላይ የሉም።" + "Google Play አገልግሎቶችን አግኝ" + "Google Play አገልግሎቶችን አንቃ" + "Google Play አገልግሎቶችን እስካላነቁ ድረስ ይህ መተግበሪያ አይሰራም።" + "Google Play አገልግሎቶችን አንቃ" + "Google Play አገልግሎቶችን ያዘምኑ" + "Google Play አገልግሎቶችን እስኪያዘምኑ ድረስ ይህ መተግበሪያ አይሰራም።" + "የአውታረ መረብ ስህተት" + "ከGoogle Play አገልግሎቶች ጋር ለመገናኘት የውሂብ ግንኙነት ያስፈልጋል።" + "ልክ ያልሆነ መለያ" + "የተገለጸው መለያ በዚህ መሣሪያ ላይ የለም። እባክው የተለየ መለያ ይምረጡ።" + "በGoogle Play አገልግሎቶች ላይ ያልታወቀ ችግር።" + "Google Play አገልግሎቶች" + "የGoogle Play አገልግሎቶች፣ አንዳንድ መተግበሪያዎችዎ በእሱ ላይ ጥገኛ የሆኑት፣ በመሣሪያዎ አይደገፍም። እባክዎ ለእርዳታ አምራቹን ያግኙ።" + "በመሣሪያው ላይ ያለው ቀን ትክክል አይመስልም። እባክዎ በመሣሪያው ላይ ያለውን ቀን ያረጋግጡ።" + "ያዘምኑ" + "ግባ" + "በGoogle ይግቡ" + + "መተግበሪያው የGoogle Play አገልግሎቶችን መጥፎ ስሪት ለመጠቀም ሞክሯል።" + "መተግበሪያው Google Play አገልግሎቶች እንዲነቁ ይፈልጋል።" + "መተግበሪያው Google Play አገልግሎቶች እንዲጫኑ ይፈልጋል።" + "መተግበሪያው Google Play አገልግሎቶች እንዲዘምን ይፈልጋል።" + "የGoogle Play አገልግሎቶች ስህተት" + "በ%1$s የተጠየቀ" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-ar/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-ar/strings.xml new file mode 100644 index 0000000000..bbc10b71fa --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-ar/strings.xml @@ -0,0 +1,31 @@ + + + "الحصول على خدمات Google Play" + "لن يتم تشغيل هذا التطبيق بدون خدمات Google Play، والتي لا تتوفر في هاتفك." + "لن يتم تشغيل هذا التطبيق بدون خدمات Google Play، والتي لا تتوفر في جهازك اللوحي." + "الحصول على خدمات Google Play" + "تمكين خدمات Google Play" + "لن يعمل هذا التطبيق ما لم يتم تمكين خدمات Google Play." + "تمكين خدمات Google Play" + "تحديث خدمات Google Play" + "لن يتم تشغيل هذا التطبيق ما لم تحدِّث خدمات Google Play." + "خطأ في الشبكة" + "يتطلب الاتصال بخدمات Google Play وجود اتصال بيانات." + "حساب غير صالح" + "الحساب الذي تمّ تحديده غير موجود على الجهاز. يُرجى اختيار حساب آخر." + "حدثت مشكلة غير معروفة في خدمات Google Play." + "خدمات Google Play" + "خدمات Google Play التي تستجيب لها بعض تطبيقاتك لا تعمل على جهازك. يُرجى الاتصال بجهة التصنيع للحصول على المساعدة." + "يبدو أن التاريخ على الجهاز غير صحيح. الرجاء التحقق من التاريخ على الجهاز." + "تحديث" + "تسجيل الدخول" + "تسجيل الدخول باستخدام Google" + + "يحاول أحد التطبيقات استخدام إصدار غير صالح من خدمات Google Play." + "يتطلب أحد التطبيقات تمكين خدمات Google Play." + "يتطلب أحد التطبيقات تثبيت خدمات Google Play." + "يتطلب أحد التطبيقات تحديث خدمات Google Play." + "خطأ في خدمات Google Play" + "تم الطلب عن طريق %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-be/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-be/strings.xml new file mode 100644 index 0000000000..81382d1c0f --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-be/strings.xml @@ -0,0 +1,36 @@ + + + "Атрымаць службы Google Play" + "Гэта прыкладанне не будзе працаваць без службаў Google Play, якіх няма ў вашым тэлефоне." + "Гэта прыкладанне не будзе працаваць без службаў Google Play, якіх няма на вашым планшэце." + "Атрымаць службы Google Play" + "Уключыць службы Google Play" + "Гэта прыкладанне не будзе працаваць, пакуль вы не ўключыце службы Google Play." + "Уключыць службы Google Play" + "Абнаўленне службаў Google Play" + "Гэта прыкладанне не будзе працаваць падчас абнаўлення службаў Google Play." + + + + + + + + + "Невядомая праблема са службамі Google Play." + "Службы Google Play" + "Службы Google Play, да якiх прывязаны некаторыя прыкладаннi, не падтрымлiваюцца на вашай прыладзе. Па дапамогу звярнiцеся да вытворцы." + + + "Абнавіць" + "Увайсцi" + "Увайсці ў Google" + + "Прыкладанне паспрабавала скарыстацца сапсаванай версіяй службаў Google Play." + "Прыкладанне патрабуе ўключэння службаў Google Play." + "Прыкладанне патрабуе ўсталявання службаў Google Play." + "Прыкладанне патрабуе абнаўлення службаў Google Play." + "Памылка службаў Google Play" + "Запытана прыкладаннем %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-bg/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-bg/strings.xml new file mode 100644 index 0000000000..bb8da3c105 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-bg/strings.xml @@ -0,0 +1,31 @@ + + + "Изтегляне на услугите за Google Play" + "Това приложение няма да се изпълнява без услугите за Google Play, които липсват в телефона ви." + "Това приложение няма да се изпълнява без услугите за Google Play, които липсват в таблета ви." + "Услуги за Google Play: Изтегл." + "Активиране на услугите за Google Play" + "Това приложение няма да работи, освен ако не активирате услугите за Google Play." + "Услуги за Google Play: Актив." + "Актуализиране на услугите за Google Play" + "Това приложение няма да се изпълнява, освен ако не актуализирате услугите за Google Play." + "Грешка в мрежата" + "За свързване с услугите за Google Play се изисква връзка за данни." + "Невалиден профил" + "Посоченият профил не съществува на това устройство. Моля, изберете друг." + "Неизвестен проблем с услугите за Google Play." + "Услуги за Google Play" + "Услугите за Google Play, на които разчитат някои от приложенията ви, не се поддържат от устройството ви. Моля, свържете се с производителя за помощ." + "Изглежда, че датата на устройството е неправилна. Моля, проверете я." + "Актуализиране" + "Вход" + "Вход с Google" + + "Приложение опита да ползва неправилна версия на услуг. за Google Play." + "Приложение изисква активирането на услугите за Google Play." + "Приложение изисква инсталирането на услугите за Google Play." + "Приложение изисква актуализирането на услугите за Google Play." + "Грешка в услугите за Google Play" + "Заявено от %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-ca/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-ca/strings.xml new file mode 100644 index 0000000000..5b63e86af7 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-ca/strings.xml @@ -0,0 +1,31 @@ + + + "Baixa els serveis de Google Play" + "Aquesta aplicació no s\'executarà si el telèfon no té instal·lats els serveis de Google Play." + "Aquesta aplicació no funcionarà si la tauleta no té instal·lats els serveis de Google Play." + "Baixa els serveis de Google Play" + "Activa els serveis de Google Play" + "Aquesta aplicació no funcionarà si no actives els serveis de Google Play." + "Activa els serveis de Google Play" + "Actualitza els serveis de Google Play" + "Aquesta aplicació no s\'executarà si no actualitzes els serveis de Google Play." + "Error de xarxa" + "Es requereix una connexió de dades per connectar amb els serveis de Google Play." + "Compte no vàlid" + "El compte especificat no existeix en aquest dispositiu. Tria un compte diferent." + "Error desconegut relacionat amb els serveis de Google Play." + "Serveis de Google Play" + "El teu dispositiu no és compatible amb els serveis de Google Play, en què es basen les teves aplicacions. Per obtenir assistència, contacta amb el fabricant." + "Sembla que la data del dispositiu no és correcta. Comprova-la." + "Actualitza" + "Inicia sessió" + "Inicia sessió amb Google" + + "Una aplic. ha intentat utilitzar una versió errònia de serveis de Play." + "Una aplicació requereix que s\'activin els serveis de Google Play." + "Una aplicació requereix que s\'instal·lin els serveis de Google Play." + "Una aplicació requereix que s\'actualitzin els serveis de Google Play." + "Error dels serveis de Google Play" + "Sol·licitada per %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-cs/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-cs/strings.xml new file mode 100644 index 0000000000..1b5423b039 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-cs/strings.xml @@ -0,0 +1,31 @@ + + + "Instalovat služby Google Play" + "Ke spuštění této aplikace jsou potřeba služby Google Play, které v telefonu nemáte." + "Ke spuštění této aplikace jsou potřeba služby Google Play, které v tabletu nemáte." + "Instalovat služby Google Play" + "Aktivovat služby Google Play" + "Ke spuštění této aplikace je třeba aktivovat služby Google Play." + "Aktivovat služby Google Play" + "Aktualizace služeb Google Play" + "Ke spuštění této aplikace je třeba aktualizovat služby Google Play." + "Chyba sítě" + "Připojení ke službám Google Play vyžaduje datové připojení." + "Neplatný účet" + "Zadaný účet v tomto zařízení neexistuje. Zvolte prosím jiný účet." + "Nastal neznámý problém se službami Google Play." + "Služby Google Play" + "Některé vaše aplikace vyžadují služby Google Play, které ve vašem zařízení nejsou podporovány. S žádostí o pomoc se prosím obraťte na výrobce." + "Datum v zařízení není správně nastaveno. Zkontrolujte prosím datum." + "Aktualizovat" + "Přihlásit se" + "Přihlásit se účtem Google" + + "Aplikace se pokusila použít nesprávnou verzi Služeb Google Play." + "Aplikace vyžaduje aktivované Služby Google Play." + "Aplikace vyžaduje instalaci Služeb Google Play." + "Aplikace vyžaduje aktualizaci Služeb Google Play." + "Chyba služeb Google Play" + "Požadováno aplikací %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-da/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-da/strings.xml new file mode 100644 index 0000000000..daa2160d3b --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-da/strings.xml @@ -0,0 +1,31 @@ + + + "Hent Google Play-tjenester" + "Denne app kan ikke køre uden Google Play-tjenester, som mangler på din telefon." + "Denne app kan ikke køre uden Google Play-tjenester, som mangler på din tablet." + "Hent Google Play-tjenester" + "Aktivér Google Play-tjenester" + "Denne app virker ikke, medmindre du aktiverer Google Play-tjenester." + "Aktivér Google Play-tjenester" + "Opdater Google Play-tjenester" + "Denne app kan ikke køre, medmindre du opdaterer Google Play-tjenester." + "Netværksfejl" + "Der kræves en dataforbindelse for at oprette forbindelse til Google Play-tjenester." + "Ugyldig konto" + "Den angivne konto findes ikke på denne enhed. Vælg en anden konto." + "Ukendt problem med Google Play-tjenester." + "Google Play-tjenester" + "Google Play-tjenester, som nogle af dine applikationer er afhængige af, understøttes ikke af din enhed. Kontakt producenten for at få hjælp." + "Datoen på enheden ser ud til at være forkert. Husk at kontrollere datoen på enheden." + "Opdater" + "Log ind" + "Log ind med Google" + + "En applikation forsøgte at bruge en defekt version af Google Play." + "En applikation kræver, at Google Play er aktiveret." + "En applikation kræver, at Google Play er installeret." + "En applikation kræver en opdatering af Google Play." + "Fejl i Google Play-tjenester" + "Anmodning fra %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-de/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-de/strings.xml new file mode 100644 index 0000000000..ef6d779eff --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-de/strings.xml @@ -0,0 +1,31 @@ + + + "Google Play-Dienste installieren" + "Zur Nutzung dieser App sind Google Play-Dienste erforderlich, die auf Ihrem Telefon nicht installiert sind." + "Zur Nutzung dieser App sind Google Play-Dienste erforderlich, die auf Ihrem Tablet nicht installiert sind." + "Google Play-Dienste installieren" + "Google Play-Dienste aktivieren" + "Diese App funktioniert nur, wenn Sie die Google Play-Dienste aktivieren." + "Google Play-Dienste aktivieren" + "Google Play-Dienste aktualisieren" + "Diese App wird nur ausgeführt, wenn Sie die Google Play-Dienste aktualisieren." + "Netzwerkfehler" + "Um eine Verbindung zu den Google Play-Diensten herzustellen, ist eine Datenverbindung erforderlich." + "Ungültiges Konto" + "Das angegebene Konto ist auf diesem Gerät nicht vorhanden. Bitte wählen Sie ein anderes Konto aus." + "Unbekanntes Problem mit Google Play-Diensten" + "Google Play-Dienste" + "Google Play-Dienste, auf denen einige Ihrer Apps basieren, werden von diesem Gerät nicht unterstützt. Wenden Sie sich für weitere Informationen an den Hersteller." + "Das Datum auf dem Gerät scheint falsch zu sein. Bitte überprüfen Sie das Datum auf dem Gerät." + "Aktualisieren" + "Anmelden" + "Über Google anmelden" + + "Anwendung versuchte, defekte Google Play-Dienste-Version zu verwenden" + "Anwendung erfordert aktivierte Google Play-Dienste" + "Anwendung erfordert die Installation von Google Play-Diensten" + "Anwendung erfordert ein Update für Google Play-Dienste" + "Fehler bei Google Play-Diensten" + "Angefordert von %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-el/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-el/strings.xml new file mode 100644 index 0000000000..13a5dc5ef3 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-el/strings.xml @@ -0,0 +1,31 @@ + + + "Λήψη υπηρεσιών Google Play" + "Αυτή η εφαρμογή δεν θα εκτελεστεί χωρίς τις υπηρεσίες Google Play, οι οποίες λείπουν από το τηλέφωνό σας." + "Αυτή η εφαρμογή δεν θα εκτελεστεί χωρίς τις υπηρεσίες Google Play, οι οποίες λείπουν από το tablet σας." + "Λήψη υπηρεσιών Google Play" + "Ενεργοποίηση υπηρεσιών Google Play" + "Αυτή η εφαρμογή δεν θα λειτουργήσει εάν δεν έχετε ενεργοποιήσει τις υπηρεσίες Google Play." + "Ενεργοπ. υπηρεσιών Google Play" + "Ενημέρωση υπηρεσιών Google Play" + "Αυτή η εφαρμογή θα εκτελεστεί αφού ενημερώσετε τις υπηρεσίες Google Play." + "Σφάλμα δικτύου" + "Απαιτείται σύνδεση δεδομένων για να συνδεθείτε με τις Υπηρεσίες Google Play." + "Μη έγκυρος λογαριασμός" + "Ο συγκεκριμένος λογαριασμός δεν υπάρχει σε αυτήν τη συσκευή. Επιλέξτε έναν διαφορετικό λογαριασμό." + "Άγνωστο πρόβλημα με τις υπηρεσίες Google Play." + "Υπηρεσίες Google Play" + "Οι υπηρεσίες Google Play, στις οποίες βασίζονται ορισμένες από τις εφαρμογές σας, δεν υποστηρίζονται στη συσκευή σας. Επικοινωνήστε με τον κατασκευαστή για υποστήριξη." + "Η ημερομηνία στη συσκευή φαίνεται λανθασμένη. Ελέγξτε την ημερομηνία στη συσκευή." + "Ενημέρωση" + "Σύνδεση" + "Συνδεθείτε στο Google" + + "Απόπειρα χρήσης ακατάλληλης έκδοσης Υπηρεσιών Google Play από εφαρμογή" + "Μια εφαρμογή απαιτεί τις Υπηρεσίες Google Play για ενεργοποίηση." + "Μια εφαρμογή απαιτεί την εγκατάσταση των Υπηρεσιών Google Play." + "Μια εφαρμογή απαιτεί μια ενημέρωση για τις Υπηρεσίες Google Play." + "Σφάλμα υπηρεσιών Google Play" + "Υποβλήθηκε αίτημα από την εφαρμογή %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-en-rGB/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-en-rGB/strings.xml new file mode 100644 index 0000000000..106d390b3e --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-en-rGB/strings.xml @@ -0,0 +1,31 @@ + + + "Get Google Play services" + "This app won\'t run without Google Play services, which are missing from your phone." + "This app won\'t run without Google Play services, which are missing from your tablet." + "Get Google Play services" + "Enable Google Play services" + "This app won\'t work unless you enable Google Play services." + "Enable Google Play services" + "Update Google Play services" + "This app won\'t run unless you update Google Play services." + "Network Error" + "A data connection is required to connect to Google Play services." + "Invalid Account" + "The specified account does not exist on this device. Please choose a different account." + "Unknown issue with Google Play services." + "Google Play services" + "Google Play services, which some of your applications rely on, is not supported by your device. Please contact the manufacturer for assistance." + "The date on the device appears to be incorrect. Please check the date on the device." + "Update" + "Sign in" + "Sign in with Google" + + "An application attempted to use a bad version of Google Play Services." + "An application requires Google Play Services to be enabled." + "An application requires installation of Google Play Services." + "An application requires an update for Google Play Services." + "Google Play services error" + "Requested by %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-en-rIN/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-en-rIN/strings.xml new file mode 100644 index 0000000000..106d390b3e --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-en-rIN/strings.xml @@ -0,0 +1,31 @@ + + + "Get Google Play services" + "This app won\'t run without Google Play services, which are missing from your phone." + "This app won\'t run without Google Play services, which are missing from your tablet." + "Get Google Play services" + "Enable Google Play services" + "This app won\'t work unless you enable Google Play services." + "Enable Google Play services" + "Update Google Play services" + "This app won\'t run unless you update Google Play services." + "Network Error" + "A data connection is required to connect to Google Play services." + "Invalid Account" + "The specified account does not exist on this device. Please choose a different account." + "Unknown issue with Google Play services." + "Google Play services" + "Google Play services, which some of your applications rely on, is not supported by your device. Please contact the manufacturer for assistance." + "The date on the device appears to be incorrect. Please check the date on the device." + "Update" + "Sign in" + "Sign in with Google" + + "An application attempted to use a bad version of Google Play Services." + "An application requires Google Play Services to be enabled." + "An application requires installation of Google Play Services." + "An application requires an update for Google Play Services." + "Google Play services error" + "Requested by %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-es-rUS/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-es-rUS/strings.xml new file mode 100644 index 0000000000..6be905908c --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-es-rUS/strings.xml @@ -0,0 +1,31 @@ + + + "Obtener Google Play Services" + "Esta aplicación no se ejecutará si no instalasGoogle Play Services en tu dispositivo." + "Esta aplicación no se ejecutará si no instalas Google Play Services en tu tablet." + "Descargar Google Play Services" + "Activar Google Play Services" + "Esta aplicación no funcionará si no activas Google Play Services." + "Activar Google Play Services" + "Actualizar Google Play Services" + "Esta aplicación no se ejecutará si no actualizas Google Play Services." + "Error de red" + "Se necesita una conexión de datos para establecer conexión con Google Play Services." + "Cuenta no válida" + "La cuenta especificada no existe en este dispositivo. Elige otra cuenta." + "Error desconocido relacionado con Google Play Services" + "Google Play Services" + "Google Play Services, del cual dependen algunas de tus aplicaciones, no es compatible con tu dispositivo. Comunícate con el fabricante para obtener ayuda." + "Parece que la fecha del dispositivo es incorrecta. ¿Puedes revisarla?" + "Actualizar" + "Acceder" + "Acceder con Google" + + "Una aplic. intentó usar una versión no válida de Google Play Services" + "Una aplicación requiere que se active Google Play Services" + "Una aplicación requiere que se instale Google Play Services" + "Una aplicación requiere que se actualice Google Play Services" + "Error de Google Play Services" + "Solicitada por %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-es/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-es/strings.xml new file mode 100644 index 0000000000..ed32995cf2 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-es/strings.xml @@ -0,0 +1,31 @@ + + + "Descargar servicios de Google Play" + "Esta aplicación no se ejecutará si tu teléfono no tiene instalados los servicios de Google Play." + "Esta aplicación no se ejecutará si tu tablet no tiene instalados los servicios de Google Play." + "Descargar servicios de Google Play" + "Habilitar servicios de Google Play" + "Esta aplicación no funcionará si no habilitas los servicios de Google Play." + "Habilitar servicios de Google Play" + "Actualizar servicios de Google Play" + "Esta aplicación no se ejecutará si no actualizas los servicios de Google Play." + "Error de red" + "Se necesita una conexión de datos para establecer conexión con los servicios de Google Play." + "Cuenta no válida" + "La cuenta especificada no existe en este dispositivo. Selecciona otra cuenta." + "Error desconocido relacionado con los servicios de Google Play" + "Servicios de Google Play" + "Tu dispositivo no es compatible con los servicios de Google Play, de los cuales dependen tus aplicaciones. Para obtener asistencia, ponte en contacto el fabricante." + "Parece que la fecha del dispositivo es incorrecta. Compruébala." + "Actualizar" + "Iniciar sesión" + "Iniciar sesión con Google" + + "Una aplicación intentó usar versión incorrecta de servicios de Google Play." + "Una aplicación requiere que se habiliten los servicios de Play." + "Una aplicación requiere que se instalen los servicios de Google Play." + "Una aplicación requiere que se actualicen los servicios de Google Play." + "Error de los servicios de Google Play" + "Solicitada por %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-et-rEE/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-et-rEE/strings.xml new file mode 100644 index 0000000000..281caff497 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-et-rEE/strings.xml @@ -0,0 +1,31 @@ + + + "Hankige Google Play teenused" + "Selle rakenduse käitamiseks on vaja Google Play teenuseid, mida teie telefonis pole." + "Selle rakenduse käitamiseks on vaja Google Play teenuseid, mida teie tahvelarvutis pole." + "Hankige Google Play teenused" + "Lubage Google Play teenused" + "See rakendus ei tööta, kui te ei luba Google Play teenuseid." + "Lubage Google Play teenused" + "Värskendage Google Play teenuseid" + "Seda rakendust ei saa käitada, kui te ei värskenda Google Play teenuseid." + "Võrgu viga" + "Google Play teenustega ühenduse loomiseks on vajalik andmesideühendus." + "Vale konto" + "Määratud kontot pole selles seadmes olemas. Valige muu konto." + "Google Play teenuste tundmatu probleem." + "Google Play teenused" + "Teie seade ei toeta Google Play teenuseid, millele mõni teie rakendustest toetub. Abi saamiseks võtke ühendust tootjaga." + "Seadme kuupäev paistab olevat vale. Kontrollige seadme kuupäeva." + "Värskenda" + "Logi sisse" + "Logi sisse Google\'iga" + + "Rakendus püüdis kasutada Google Play teenuste sobimatut versiooni." + "Rakenduse kasutamiseks peavad olema lubatud Google Play teenused." + "Rakenduse kasutamiseks peavad olema installitud Google Play teenused." + "Rakenduse kasutamiseks tuleb värskendada Google Play teenuseid." + "Viga Google Play teenustes" + "Päringu esitas: %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-et/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-et/strings.xml new file mode 100644 index 0000000000..281caff497 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-et/strings.xml @@ -0,0 +1,31 @@ + + + "Hankige Google Play teenused" + "Selle rakenduse käitamiseks on vaja Google Play teenuseid, mida teie telefonis pole." + "Selle rakenduse käitamiseks on vaja Google Play teenuseid, mida teie tahvelarvutis pole." + "Hankige Google Play teenused" + "Lubage Google Play teenused" + "See rakendus ei tööta, kui te ei luba Google Play teenuseid." + "Lubage Google Play teenused" + "Värskendage Google Play teenuseid" + "Seda rakendust ei saa käitada, kui te ei värskenda Google Play teenuseid." + "Võrgu viga" + "Google Play teenustega ühenduse loomiseks on vajalik andmesideühendus." + "Vale konto" + "Määratud kontot pole selles seadmes olemas. Valige muu konto." + "Google Play teenuste tundmatu probleem." + "Google Play teenused" + "Teie seade ei toeta Google Play teenuseid, millele mõni teie rakendustest toetub. Abi saamiseks võtke ühendust tootjaga." + "Seadme kuupäev paistab olevat vale. Kontrollige seadme kuupäeva." + "Värskenda" + "Logi sisse" + "Logi sisse Google\'iga" + + "Rakendus püüdis kasutada Google Play teenuste sobimatut versiooni." + "Rakenduse kasutamiseks peavad olema lubatud Google Play teenused." + "Rakenduse kasutamiseks peavad olema installitud Google Play teenused." + "Rakenduse kasutamiseks tuleb värskendada Google Play teenuseid." + "Viga Google Play teenustes" + "Päringu esitas: %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-fa/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-fa/strings.xml new file mode 100644 index 0000000000..4546e5747e --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-fa/strings.xml @@ -0,0 +1,31 @@ + + + "دریافت خدمات Google Play" + "این برنامه بدون خدمات Google Play اجرا نمی‌شود، این خدمات در تلفن شما وجود ندارد." + "این برنامه بدون خدمات Google Play اجرا نمی‌شود، این خدمات در رایانهٔ لوحی شما وجود ندارد." + "دریافت خدمات Google Play" + "فعال کردن خدمات Google Play" + "تا زمانی‌که خدمات Google Play را فعال نکنید این برنامه کار نمی‌کند." + "فعال کردن خدمات Google Play" + "به‌روزرسانی خدمات Google Play" + "تا زمانی‌که خدمات Google Play را به‌روز نکنید این برنامه کار نمی‌کند." + "خطای شبکه" + "برای اتصال به خدمات Google Play اتصال داده لازم است." + "حساب نامعتبر" + "حسابی که تعیین کردید در این دستگاه وجود ندارد. لطفاً حساب دیگری را انتخاب کنید." + "مشکل نامشخص در خدمات Google Play." + "خدمات Google Play" + "خدمات Google Play، که برخی از برنامه‌های شما به آن وابسته است، توسط دستگاه شما پشتیبانی نمی‌شود. لطفاً برای دریافت کمک با سازنده تماس بگیرید." + "تاریخ روی دستگاه ظاهراً اشتباه است. لطفاً تاریخ روی دستگاه را بررسی کنید." + "به‌روزرسانی" + "ورود به سیستم" + "ورود به سیستم با Google‎" + + "برنامه‌ای تلاش کرد از نسخه نادرستی از خدمات Google Play استفاده کند." + "برنامه‌ای به فعال کردن خدمات Google Play نیاز دارد." + "برنامه‌ای به نصب خدمات Google Play نیاز دارد." + "برنامه‌ای به به‌روزرسانی خدمات Google Play نیاز دارد." + "خطا در خدمات Google Play" + "درخواست توسط %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-fi/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-fi/strings.xml new file mode 100644 index 0000000000..00d3ceb215 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-fi/strings.xml @@ -0,0 +1,31 @@ + + + "Asenna Google Play -palvelut" + "Tämä sovellus ei toimi ilman Google Play -palveluita, jotka puuttuvat puhelimesta." + "Tämä sovellus ei toimi ilman Google Play -palveluita, jotka puuttuvat tablet-laitteesta." + "Asenna Google Play -palvelut" + "Ota Google Play -palvelut käyttöön" + "Tämä sovellus ei toimi, ellet ota Google Play -palveluita käyttöön." + "Ota Google Play -palv. käyttöön" + "Päivitä Google Play -palvelut" + "Tämä sovellus ei toimi, ellet päivitä Google Play -palveluita." + "Verkkovirhe" + "Google Play -palveluiden käyttöön tarvitaan tietoliikenneyhteys." + "Tili ei kelpaa" + "Kyseistä tiliä ei ole tällä laitteella. Valitse toinen tili." + "Tuntematon ongelma käytettäessä Google Play -palveluita." + "Google Play -palvelut" + "Google Play -palveluita, joita osa sovelluksistasi käyttää, ei tueta laitteellasi. Pyydä ohjeita laitteen valmistajalta." + "Laitteen päivämäärä vaikuttaa virheelliseltä. Tarkista laitteen päivämäärä." + "Päivitä" + "Kirjaudu" + "Kirjaudu Google-tiliin" + + "Sovellus yritti käyttää virheellistä Google Play -palveluiden versiota" + "Ota käyttöön Google Play -palvelut, jotta sovellus toimii." + "Asenna Google Play -palvelut, jotta sovellus toimii." + "Päivitä Google Play -palvelut, jotta sovellus toimii." + "Virhe Google Play -palveluissa" + "Pyynnön teki %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-fr-rCA/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-fr-rCA/strings.xml new file mode 100644 index 0000000000..e915fe4067 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-fr-rCA/strings.xml @@ -0,0 +1,31 @@ + + + "Installer les services Google Play" + "Cette application ne fonctionnera pas sans les services Google Play, qui ne sont pas installés sur votre téléphone." + "Cette application ne fonctionnera pas sans les services Google Play, qui ne sont pas installés sur votre tablette." + "Installer les services Google Play" + "Activer les services Google Play" + "Cette application ne fonctionnera pas tant que vous n\'aurez pas activé les services Google Play." + "Activer les services Google Play" + "Mettre à jour les services Google Play" + "Cette application ne fonctionnera pas tant que vous n\'aurez pas mis à jour les services Google Play." + "Erreur réseau" + "Vous devez disposer d\'une connexion de données pour utiliser les services Google Play." + "Compte erroné" + "Le compte indiqué n\'existe pas sur cet appareil. Veuillez sélectionner un autre compte." + "Problème inconnu avec les services Google Play." + "Services Google Play" + "Les services Google Play, dont dépendent certaines de vos applications, ne sont pas compatibles avec votre appareil. Veuillez contacter le fabricant pour obtenir de l\'aide." + "La date sur l\'appareil semble incorrecte. Veuillez la vérifier." + "Mettre à jour" + "Connexion" + "Se connecter via Google" + + "Une application requiert une version valide des services Google Play" + "Une application requiert l\'activation des services Google Play" + "Une application requiert l\'installation des services Google Play" + "Une application requiert la mise à jour des services Google Play" + "Erreur liée aux services Google Play" + "Demandée par %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-fr/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-fr/strings.xml new file mode 100644 index 0000000000..321b28370b --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-fr/strings.xml @@ -0,0 +1,31 @@ + + + "Installer les services Google Play" + "Cette application ne fonctionnera pas sans les services Google Play, qui ne sont pas installés sur votre téléphone." + "Cette application ne fonctionnera pas sans les services Google Play, qui ne sont pas installés sur votre tablette." + "Installer services Google Play" + "Activer les services Google Play" + "Cette application ne fonctionnera pas tant que vous n\'aurez pas activé les services Google Play." + "Activer services Google Play" + "Mettre à jour les services Google Play" + "Cette application ne fonctionnera pas tant que vous n\'aurez pas mis à jour les services Google Play." + "Erreur réseau" + "Vous devez disposer d\'une connexion de données pour utiliser les services Google Play." + "Compte erroné" + "Le compte indiqué n\'existe pas sur cet appareil. Veuillez sélectionner un autre compte." + "Problème inconnu avec les services Google Play." + "Services Google Play" + "Les services Google Play, dont dépendent certaines de vos applications, ne sont pas compatibles avec votre appareil. Veuillez contacter le fabricant pour obtenir de l\'aide." + "La date sur l\'appareil semble incorrecte. Veuillez la vérifier." + "Mettre à jour" + "Connexion" + "Se connecter avec Google" + + "Une application requiert une version valide des services Google Play" + "Une application requiert l\'activation des services Google Play" + "Une application requiert l\'installation des services Google Play" + "Une application requiert la mise à jour des services Google Play" + "Erreur liée aux services Google Play" + "Demandée par %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-hi/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-hi/strings.xml new file mode 100644 index 0000000000..e1b3b95707 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-hi/strings.xml @@ -0,0 +1,31 @@ + + + "Google Play सेवाएं पाएं" + "यह एप्स Google Play सेवाओं के बिना नहीं चलेगा, जो आपके फ़ोन में नहीं हैं." + "यह एप्स Google Play सेवाओं के बिना नहीं चलेगा, जो आपके टेबलेट में नहीं हैं." + "Google Play सेवाएं पाएं" + "Google Play सेवाएं सक्षम करें" + "जब तक आप Google Play सेवाएं सक्षम नहीं करते, तब तक यह एप्स कार्य नहीं करेगा." + "Google Play सेवाएं सक्षम करें" + "Google Play सेवाएं से नई जानकारी" + "जब तक आप Google Play सेवाओं से नई जानकारी नहीं लेते हैं, तब तक यह एप्स नहीं चलेगा." + "नेटवर्क त्रुटि" + "Google Play सेवाओं से कनेक्ट करने के लिए डेटा कनेक्शन की आवश्यकता है." + "अमान्य खाता" + "निर्दिष्ट खाता इस उपकरण पर मौजूद नहीं है. कृपया कोई भिन्न खाता चुनें." + "Google Play सेवाओं के साथ अज्ञात समस्या." + "Google Play सेवाएं" + "Google Play सेवाएं, जिन पर आपके कुछ एप्स निर्भर करते हैं, आपके उपकरण द्वारा समर्थित नहीं हैं. कृपया सहायता के लिए निर्माता से संपर्क करें." + "उपकरण का दिनांक गलत प्रतीत हो रहा है. कृपया उपकरण का दिनांक जांचें." + "नई जानकारी पाएं" + "प्रवेश करें" + "Google से प्रवेश करें" + + "एप्लि. ने Google Play सेवाओं के खराब संस्करण के उपयोग का प्रयास किया." + "एप्स के लिए Google Play सेवाओं को सक्षम किए जाने की आवश्यकता है." + "एप्स के लिए Google Play सेवाओं के इंस्टॉलेशन की आवश्यकता है." + "एप्स के लिए Google Play सेवाओं में Google Play से नई जानकारी की आवश्यकता है." + "Google Play सेवाएं त्रुटि" + "%1$s द्वारा अनुरोधित" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-hr/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-hr/strings.xml new file mode 100644 index 0000000000..b7d462d882 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-hr/strings.xml @@ -0,0 +1,31 @@ + + + "Preuzmi usluge za Google Play" + "Ova aplikacija neće funkcionirati bez usluga za Google Play, koje nisu instalirane na vašem telefonu." + "Ova aplikacija neće funkcionirati bez usluga za Google Play, koje nisu instalirane na vašem tabletnom računalu." + "Preuzmi usluge za Google Play" + "Omogući usluge za Google Play" + "Ova aplikacija neće raditi ako ne omogućite usluge za Google Play." + "Omogući usluge za Google Play" + "Ažuriraj usluge za Google Play" + "Ova se aplikacija neće pokrenuti ako ne ažurirate usluge za Google Play." + "Mrežna pogreška" + "Potrebna je podatkovna veza za povezivanje s uslugama Google Play." + "Nevažeći račun" + "Navedeni račun ne postoji na ovom uređaju. Odaberite neki drugi račun." + "Nepoznata poteškoća s uslugama za Google Play." + "Usluge za Google Play" + "Usluge za Google Play, koje su potrebne za funkcioniranje nekih vaših aplikacija, nisu podržane na vašem uređaju. Pomoć potražite od proizvođača." + "Čini se da datum na uređaju nije točan. Provjerite datum na uređaju." + "Ažuriranje" + "Prijava" + "Prijava uslugom Google" + + "Aplikacija je pokušala upotrijebiti lošu verziju Usluga za Google Play." + "Aplikacija zahtijeva omogućavanje Usluga za Google Play." + "Aplikacija zahtijeva instaliranje Usluga za Google Play." + "Aplikacija zahtijeva ažuriranje Usluga za Google Play." + "Pogreška usluga za Google Play" + "Zahtijeva aplikacija %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-hu/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-hu/strings.xml new file mode 100644 index 0000000000..cd15ad328f --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-hu/strings.xml @@ -0,0 +1,31 @@ + + + "Play Szolgáltatások telepítése" + "Az alkalmazás működéséhez a Google Play Szolgáltatások szükségesek, ezek nincsenek telepítve a telefonon." + "Az alkalmazás működéséhez a Google Play Szolgáltatások szükségesek, ezek nincsenek telepítve a táblagépen." + "Play Szolgáltatások telepítése" + "Google Play Szolgáltatások aktiválása" + "Az alkalmazás csak akkor fog működni, ha engedélyezi a Google Play Szolgáltatásokat." + "Play Szolgáltatások aktiválása" + "Play Szolgáltatások frissítése" + "Az alkalmazás csak akkor fog működni, ha frissíti a Google Play Szolgáltatásokat." + "Hálózati hiba" + "A Google Play Szolgáltatásokhoz történő kapcsolódáshoz adatkapcsolat szükséges." + "Érvénytelen fiók" + "A megadott fiók nem létezik ezen az eszközön. Kérjük, válasszon másik fiókot." + "Ismeretlen hiba a Google Play Szolgáltatásokban." + "Google Play Szolgáltatások" + "A Google Play Szolgáltatásokat, amelyre egyes alkalmazások támaszkodnak, nem támogatja az eszköz. Segítségért forduljon az eszköz gyártójához." + "Az eszközön beállított dátum helytelen. Kérjük, ellenőrizze azt." + "Frissítés" + "Belépés" + "Google-bejelentkezés" + + "Egy alkalmazás a Play Szolgáltatások rossz verzióját akarta használni." + "Egy alkalmazás kéri a Google Play Szolgáltatások engedélyezését." + "Egy alkalmazás kéri a Google Play Szolgáltatások telepítését." + "Egy alkalmazás kéri a Google Play Szolgáltatások frissítését." + "Google Play szolgáltatási hiba" + "Igénylő: %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-hy-rAM/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-hy-rAM/strings.xml new file mode 100644 index 0000000000..d89be9bf64 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-hy-rAM/strings.xml @@ -0,0 +1,31 @@ + + + "Տեղադրեք Google Play ծառայությունները" + "Այս հավելվածը չի գործարկվի առանց Google Play ծառայությունների, որոնք բացակայում են ձեր հեռախոսում:" + "Այս հավելվածը չի գործարկվի առանց Google Play ծառայությունների, որոնք բացակայում են ձեր գրասալիկում:" + "Տեղադրել Google Play ծառայությունները" + "Միացնել Google Play ծառայությունները" + "Այս ծրագիրը չի աշխատի, եթե դուք չմիացնեք Google Play ծառայությունները:" + "Միացնել Google Play ծառայությունները" + "Նորացրեք Google Play ծառայությունները" + "Այս ծրագիրը չի գործարկվի, եթե դուք չնորացնեք Google Play ծառայությունները:" + "Ցանցի սխալ կա" + "Պահանջվում է տվյալների կապ` Google Play ծառայություններին միանալու համար:" + "Հաշիվն անվավեր է" + "Նշված հաշիվը գոյություն չունի այս սարքում: Ընտրեք այլ հաշիվ:" + "Անհայտ խնդիր՝ Google Play ծառայություններում:" + "Google Play ծառայություններ" + "Google Play ծառայությունները, որոնց ապավինում են ձեր ծրագրերից որոշները, չեն աջակցվում ձեր սարքի կողմից: Խնդրում ենք կապվել արտադրողի հետ օգնության համար:" + "Սարքի ամսաթիվը կարծես սխալ է: Ստուգեք սարքի ամսաթիվը:" + "Նորացնել" + "Մուտք գործել" + "Մուտք գործեք Google-ով" + + "Հավելվածը փորձել է կիրառել Google Play ծառայությունների վատ տարբերակը:" + "Հավելվածը պահանջում է միացնել Google Play ծառայությունները:" + "Հավելվածը պահանջում է տեղադրել Google Play ծառայությունները:" + "Հավելվածը պահանջում է թարմացնել Google Play ծառայությունները:" + "Google Play ծառայությունների սխալ" + "%1$s-ի հարցմամբ" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-in/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-in/strings.xml new file mode 100644 index 0000000000..526b84a816 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-in/strings.xml @@ -0,0 +1,31 @@ + + + "Dapatkan layanan Google Play" + "Aplikasi ini tidak akan berjalan tanpa layanan Google Play, yang tidak ada di ponsel Anda." + "Aplikasi ini tidak akan berjalan tanpa layanan Google Play, yang tidak ada di tablet Anda." + "Dapatkan layanan Google Play" + "Aktifkan layanan Google Play" + "Aplikasi ini tidak akan bekerja sampai Anda mengaktifkan layanan Google Play." + "Aktifkan layanan Google Play" + "Perbarui layanan Google Play" + "Aplikasi ini tidak akan berjalan sampai Anda memperbarui layanan Google Play." + "Kesalahan Jaringan" + "Sambungan data diperlukan untuk tersambung ke layanan Google Play." + "Akun Tidak Valid" + "Akun yang ditentukan tidak ada di perangkat ini. Pilih akun lain." + "Masalah tidak diketahui pada layanan Google Play." + "Layanan Google Play" + "Layanan Google Play, yang diandalkan oleh beberapa aplikasi Anda, tidak didukung oleh perangkat Anda. Hubungi pabrikan untuk mendapatkan bantuan." + "Tampaknya tanggal di perangkat salah. Periksa tanggal di perangkat." + "Perbarui" + "Masuk" + "Masuk dengan Google" + + "Aplikasi mencoba menggunakan versi Layanan Google Play yang rusak." + "Aplikasi membutuhkan Layanan Google Play untuk dapat diaktifkan." + "Aplikasi membutuhkan pemasangan Layanan Google Play." + "Aplikasi membutuhkan pembaruan untuk Layanan Google Play." + "Kesalahan layanan Google Play" + "Diminta oleh %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-it/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-it/strings.xml new file mode 100644 index 0000000000..f3c9f1fa5c --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-it/strings.xml @@ -0,0 +1,31 @@ + + + "Installa Google Play Services" + "L\'app non funzionerà senza Google Play Services, non presente sul tuo telefono." + "L\'app non funzionerà senza Google Play Services, non presente sul tuo tablet." + "Installa Google Play Services" + "Attiva Google Play Services" + "L\'app non funzionerà se non attivi Google Play Services." + "Attiva Google Play Services" + "Aggiorna Google Play Services" + "L\'app non funzionerà se non aggiorni Google Play Services." + "Errore di rete" + "È necessaria una connessione dati per connettersi a Google Play Services." + "Account non valido" + "L\'account specificato non esiste su questo dispositivo. Scegli un altro account." + "Problema sconosciuto con Google Play Services." + "Google Play Services" + "La piattaforma Google Play Services, su cui sono basate alcune delle tue applicazioni, non è supportata dal dispositivo in uso. Per assistenza, contatta il produttore." + "La data sul dispositivo sembra sbagliata. Controllala." + "Aggiorna" + "Accedi" + "Accedi con Google" + + "Un\'app ha tentato di usare una versione non valida di Play Services." + "Un\'applicazione richiede l\'attivazione di Google Play Services." + "Un\'applicazione richiede l\'installazione di Google Play Services." + "Un\'applicazione richiede un aggiornamento di Google Play Services." + "Errore Google Play Services" + "Richiesta da %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-iw/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-iw/strings.xml new file mode 100644 index 0000000000..76869a9f38 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-iw/strings.xml @@ -0,0 +1,31 @@ + + + "קבל את שירותי Google Play" + "אפליקציה זו לא תפעל ללא שירותי Google Play, החסרים בטלפון שלך." + "אפליקציה זו לא תפעל ללא שירותי Google Play, החסרים בטאבלט שלך." + "קבל את שירותי Google Play" + "הפעלת שירותי Google Play" + "אפליקציה זו לא תעבוד אם לא תפעיל את שירותי Google Play." + "הפעל את שירותי Google Play" + "עדכון שירותי Google Play" + "אפליקציה זו לא תפעל אם לא תעדכן את שירותי Google Play." + "שגיאת רשת." + "דרוש חיבור נתונים כדי להתחבר לשירותי Google Play." + "חשבון לא חוקי" + "החשבון שצוין לא קיים במכשיר זה. בחר חשבון אחר." + "בעיה לא ידועה בשירותי Google Play." + "שירותי Google Play" + "שירותי Google Play, שחלק מהאפליקציות שלך מתבססות עליהם, אינם נתמכים על ידי המכשיר שברשותך. צור קשר עם היצרן לקבלת סיוע." + "נראה שהתאריך במכשיר שגוי. בדוק את התאריך במכשיר." + "עדכן" + "היכנס" + "היכנס באמצעות Google" + + "יש אפליקציה שניסתה להשתמש בגרסה שגויה של שירותי Google Play." + "יש אפליקציה המחייבת הפעלה של שירותי Google Play." + "יש אפליקציה המחייבת התקנה של שירותי Google Play." + "יש אפליקציה המחייבת עדכון של שירותי Google Play." + "שגיאה בשירותי Google Play" + "התבקשה על ידי %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-ja/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-ja/strings.xml new file mode 100644 index 0000000000..0d8b606230 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-ja/strings.xml @@ -0,0 +1,31 @@ + + + "Play開発者サービスの入手" + "このアプリの実行にはGoogle Play開発者サービスが必要ですが、お使いの携帯端末にはインストールされていません。" + "このアプリの実行にはGoogle Play開発者サービスが必要ですが、お使いのタブレットにはインストールされていません。" + "Play開発者サービスの入手" + "Play開発者サービスの有効化" + "このアプリの実行には、Google Play開発者サービスの有効化が必要です。" + "Play開発者サービスの有効化" + "Play開発者サービスの更新" + "このアプリの実行には、Google Play開発者サービスの更新が必要です。" + "ネットワークエラー" + "Google Play開発者サービスに接続するには、データ接続が必要です。" + "無効なアカウント" + "指定したアカウントはこの端末上に存在しません。別のアカウントを選択してください。" + "Google Play開発者サービスで原因不明の問題が発生しました。" + "Google Play開発者サービス" + "一部のアプリが使用しているGoogle Play開発者サービスは、お使いの端末ではサポートされていません。詳しくは、端末メーカーまでお問い合わせください。" + "端末上の日付が正しくないようです。端末上の日付をご確認ください。" + "更新" + "ログイン" + "Googleでログイン" + + "アプリはGoogle Play開発者サービスの不適切なバージョンを使用しようとしました。" + "アプリではGoogle Play開発者サービスを有効にする必要があります。" + "アプリではGoogle Play開発者サービスをインストールする必要があります。" + "アプリではGoogle Play開発者サービスをアップデートする必要があります。" + "Google Play開発者サービスのエラー" + "%1$sによるリクエスト" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-ka-rGE/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-ka-rGE/strings.xml new file mode 100644 index 0000000000..8a2c74aa98 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-ka-rGE/strings.xml @@ -0,0 +1,31 @@ + + + "Google Play სერვისების მიღება" + "ეს აპი ვერ გაეშვება Google Play სერვისების გარეშე, რაც თქვენს ტელეფონზე ვერ იძებნება." + "ეს აპი ვერ გაეშვება Google Play სერვისების გარეშე, რაც თქვენს ტელეფონზე ვერ იძებნება." + "Google Play სერვისების მიღება" + "Google Play სერვისების გააქტიურება" + "ეს აპი არ იმუშავებს, თუ არ გაააქტიურებთ Google Play სერვისებს." + "Google Play სერვისების გააქტიურება" + "Google Play სერვისების განახლება" + "ეს აპი ვერ გაეშვება, თუ Google Play სერვისებს არ განაახლებთ." + "ქსელის შეცდომა" + "Google Play Services-თან დასაკავშირებლად მონაცემთა გადაცემა აუცილებელია." + "ანგარიში არასწორია" + "მითითებული ანგარიში ამ მოწყობილობაზე არ არსებობს. გთხოვთ, აირჩიოთ სხვა ანგარიში." + "Google Play სერვისებთან დაკავშირებით უცნობი შეფერხება წარმოიშვა." + "Google Play სერვისები" + "Google Play სერვისები, რაც თქვენს ზოგიერთ აპს ჭირდება, თქვენს მოწყობილობაზე მხარდაჭერილი არ არის. გთხოვთ, დაუკავშირდეთ მწარმოებელს დახმარებისათვის." + "როგორც ჩანს, მოწყობილობის თარიღი არასწორია. გთხოვთ, შეამოწმოთ მოწყობილობის თარიღი." + "განახლება" + "შესვლა" + "Google-ით შესვლა" + + "აპლიკაცია შეეცადა გამოეყენებინა Google Play სერვისების არასწორი ვერსია." + "აპლიკაცია საჭიროებს გააქტიურებულ Google Play Services." + "აპლიკაცია საჭიროებს Google Play Services-ის ინსტალაციას." + "აპლიკაცია საჭიროებს Google Play Services-ის განახლებას." + "Google Play სერვისების შეცდომა" + "მომთხოვნი: %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-km-rKH/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-km-rKH/strings.xml new file mode 100644 index 0000000000..afebf30875 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-km-rKH/strings.xml @@ -0,0 +1,31 @@ + + + "ទទួល​សេវាកម្ម​កម្សាន្ត Google" + "កម្មវិធី​នេះ​នឹង​មិន​ដំណើរការ​​ទេ​បើ​គ្មាន​​សេវាកម្ម​កម្សាន្ត​ Google ដែល​ទូរស័ព្ទ​របស់​​អ្នក​មិន​មាន។" + "​​កម្មវិធី​នេះ​នឹង​មិន​ដំណើរការ​​ទេ​បើ​គ្មាន​​សេវាកម្ម​កម្សាន្ត​ Google ដែល​​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក​មិន​មាន។" + "ទទួល​សេវាកម្ម​កម្សាន្ត Google" + "បើក​សេវាកម្ម​កម្សាន្ត Google" + "កម្ម​វិធី​នេះ​នឹង​មិន​ដំណើរការ​ទេ​ លុះត្រាតែ​អ្នក​បើក​សេវាកម្ម​​កម្សាន្ត​ Google ។" + "បើក​សេវាកម្ម​កម្សាន្ត Google" + "ធ្វើ​បច្ចុប្បន្នភាព​សេវាកម្ម​កម្សាន្ត Google" + "កម្មវិធី​នេះ​នឹង​មិន​ដំណើរការ​ទេ​ លុះត្រាតែ​អ្នក​ធ្វើ​បច្ចុប្បន្នភាព​សេវាកម្ម​កម្សាន្ត Google ។" + "កំហុស​​បណ្ដាញ" + "បាន​ទាមទារ​ការ​តភ្ជាប់​ទិន្នន័យ ដើម្បី​ភ្ជាប់​សេវាកម្ម​ឃ្លាំង​កម្មវិធី។" + "គណនី​មិន​ត្រឹមត្រូវ" + "គណនី​ដែល​បាន​បញ្ជាក់​មិន​មាន​នៅ​លើ​ឧបករណ៍​នេះ​ទេ។ សូម​ជ្រើស​គណនី​ផ្សេង​។" + "មិន​ស្គាល់​បញ្ហា​ជាមួយ​សេវាកម្ម​កម្សាន្ត Google ។" + "សេវាកម្ម​កម្សាន្ត​ Google" + "សេវាកម្ម​កម្សាន្ត Google អាស្រ័យ​លើ​កម្មវិធី​របស់​អ្នក មិន​ត្រូវ​បាន​គាំទ្រ​ដោយ​ឧបករណ៍​របស់​អ្នក។ សូម​ទាក់ទង​ក្រុមហ៊ុន​ផលិត​សម្រាប់​ជំនួយ។" + "កាលបរិច្ឆេទ​លើ​ឧបករណ៍​បង្ហាញ​ថា​មិន​ត្រឹមត្រូវ។ សូម​ពិនិត្យ​កាលបរិច្ឆេទ​លើ​ឧបករណ៍។" + "ធ្វើ​បច្ចុប្បន្នភាព" + "ចូល" + "ចូល​ដោយ​ប្រើ​ Google" + + "កម្មវិធី​​​ព្យាយាម​ប្រើ​កំណែ​មិនល្អ​របស់​សេវា​កម្ម​ឃ្លាំ​កម្មវិធី។" + "កម្មវិធី​ទាមទារ​​បើក​សេវាកម្ម​ឃ្លាំង​កម្មវិធី។" + "កម្មវិធី​ទាមទារ​ការ​ដំឡើង​សេវាកម្ម​ឃ្លាំង​កម្មវិធី។" + "កម្មវិធី​ទាមទារ​​ធ្វើ​បច្ចុប្បន្នភាព​សេវាកម្ម​ឃ្លាំង​កម្មវិធី។" + "កំហុស​សេវា​កម្ម​កម្សាន្ត Google" + "បាន​ស្នើ​ដោយ %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-ko/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-ko/strings.xml new file mode 100644 index 0000000000..e37f1fd02a --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-ko/strings.xml @@ -0,0 +1,31 @@ + + + "Google Play 서비스 설치" + "휴대전화에 Google Play 서비스가 설치되어 있어야 이 앱이 실행됩니다." + "태블릿에 Google Play 서비스가 설치되어 있어야 이 앱이 실행됩니다." + "Google Play 서비스 설치" + "Google Play 서비스 사용" + "Google Play 서비스를 사용하도록 설정해야 이 앱이 작동합니다." + "Google Play 서비스 사용" + "Google Play 서비스 업데이트" + "Google Play 서비스를 업데이트해야만 이 앱이 실행됩니다." + "네트워크 오류" + "Google Play 서비스에 연결하려면 데이터 연결이 필요합니다." + "올바르지 않은 계정" + "지정한 계정이 이 기기에 존재하지 않습니다. 다른 계정을 선택하세요." + "Google Play 서비스에 알 수 없는 문제가 발생했습니다." + "Google Play 서비스" + "일부 사용자 애플리케이션에 필요한 Google Play 서비스가 사용자 기기에서 지원되지 않습니다. 기기 제조업체에 문의하시기 바랍니다." + "기기의 날짜가 잘못된 것 같습니다. 기기의 날짜를 확인해 주세요." + "업데이트" + "로그인" + "Google 계정으로 로그인" + + "애플리케이션에서 잘못된 버전의 Google Play 서비스를 사용하려고 했습니다." + "Google Play 서비스를 사용하도록 설정해야 하는 애플리케이션입니다." + "Google Play 서비스를 설치해야 하는 애플리케이션입니다." + "Google Play 서비스를 업데이트해야 하는 애플리케이션입니다." + "Google Play 서비스 오류" + "%1$s에서 요청" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-lo-rLA/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-lo-rLA/strings.xml new file mode 100644 index 0000000000..32bcb0b92b --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-lo-rLA/strings.xml @@ -0,0 +1,31 @@ + + + "ຕິດຕັ້ງບໍລິການ Google Play" + "ແອັບຯນີ້ຈະບໍ່ສາມາດເຮັດວຽກໄດ້ໂດຍທີ່ບໍ່ມີບໍລິການ Google Play ເຊິ່ງຂາດຫາຍໄປໃນໂທລະສັບຂອງທ່ານ." + "ແອັບຯນີ້ຈະບໍ່ສາມາດເຮັດວຽກໄດ້ໂດຍທີ່ບໍ່ມີບໍລິການ Google Play ເຊິ່ງຂາດຫາຍໄປໃນແທັບເລັດຂອງທ່ານ." + "ຕິດຕັ້ງບໍລິການ Google Play" + "ເປີດໃຊ້ບໍລິການ Google Play" + "ແອັບຯນີ້ຈະບໍ່ສາມາດເຮັດວຽກໄດ້ຈົນກວ່າທ່ານຈະເປີດໃຊ້ບໍລິການ Google Play" + "ເປີດໃຊ້ບໍລິການ Google Play" + "ອັບເດດບໍລິການ Google Play" + "ແອັບຯນີ້ຈະບໍ່ສາມາດເຮັດວຽກໄດ້ຈົນກວ່າທ່ານຈະອັບເດດບໍລິການ Google Play." + "ເຄືອຂ່າຍຜິດພາດ" + "ຕ້ອງໃຊ້ການເຊື່ອມຕໍ່ອິນເຕີເນັດເພື່ອໃຊ້ Google Play Services." + "ບັນຊີບໍ່ຖືກຕ້ອງ" + "ບັນຊີທີ່ເລືອກບໍ່ມີໃນອຸປະກອນນີ້. ກະລຸນາເລືອກບັນຊີອື່ນ." + "ມີປັນຫາທີ່ບໍ່ຄາດຄິດໃນບໍລິການ Google Play." + "ບໍລິການ Google Play" + "ບໍລິການ Google Play ທີ່ບາງແອັບພລິເຄຊັນຂອງທ່ານຕ້ອງອາໄສນັ້ນ ບໍ່ຖືກຮອງຮັບໃນອຸປະກອນຂອງທ່ານ. ກະລຸນາຕິດຕໍ່ຜູ້ຜະລິດສຳລັບການແນະນຳ." + "ວັນທີຂອງອຸປະກອນບໍ່ຖືກຕ້ອງ. ກະລຸນາກວດສອບວັນທີຂອງອຸປະກອນຂອງທ່ານ." + "ອັບເດດ" + "ເຂົ້າສູ່ລະບົບ" + "ເຂົ້າສູ່ລະບົບດ້ວຍ Google" + + "ແອັບພລິເຄຊັນໄດ້ພະຍາຍາມໃຊ້ Google Play Services ເວີຊັນທີ່ບໍ່ສາມາດໃຊ້ໄດ້." + "ແອັບພລິເຄຊັນຕ້ອງການເປີດນຳໃຊ້ Google Play Services." + "ແອັບພລິເຄຊັນຕ້ອງການໃຫ້ຕິດຕັ້ງ Google Play Services." + "ແອັບພລິເຄຊັນຕ້ອງການອັບເດດ Google Play Services." + "ບໍລິການ Google Play ຜິດພາດ" + "ຮ້ອງຂໍໂດຍ %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-lt/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-lt/strings.xml new file mode 100644 index 0000000000..73de5fa9aa --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-lt/strings.xml @@ -0,0 +1,31 @@ + + + "Gauti „Google Play“ paslaugų" + "Ši programa neveiks be „Google Play“ paslaugų, kurios neįdiegtos telefone." + "Ši programa neveiks be „Google Play“ paslaugų, kurios neįdiegtos planšetiniame kompiuteryje." + "Gauti „Google Play“ paslaugų" + "Įgalinti „Google Play“ paslaugas" + "Ši programa neveiks, jei neįgalinsite „Google Play“ paslaugų." + "Įgal. „Google Play“ paslaugas" + "Atnaujinti „Google Play“ paslaugas" + "Ši programa neveiks, jei neatnaujinsite „Google Play“ paslaugų." + "Tinklo klaida" + "Norint prisijungti prie „Google Play“ paslaugų reikia duomenų ryšio." + "Netinkama paskyra" + "Nurodytos paskyros šiame įrenginyje nėra. Pasirinkite kitą paskyrą." + "Nežinoma „Google Play“ paslaugų problema." + "„Google Play“ paslaugos" + "Jūsų įrenginys nepalaiko „Google Play“ paslaugų, kuriomis remiasi kai kurios programos. Jei reikia pagalbos, susisiekite su gamintoju." + "Įrenginyje nurodyta data neteisinga. Patikrinkite įrenginyje nurodytą datą." + "Atnaujinti" + "Prisij." + "Prisij. naud. „Google“" + + "Programa bandė naudotis netinkama „Google Play“ paslaugų versija." + "Norint naudoti programą būtina įgalinti „Google Play“ paslaugas." + "Norint naudoti programą būtina įdiegti „Google Play“ paslaugas." + "Norint naudoti programą būtina atnaujinti „Google Play“ paslaugas." + "„Google Play“ paslaugų klaida" + "Užklausą pateikė „%1$s“" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-lv/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-lv/strings.xml new file mode 100644 index 0000000000..9e4b6ee6bd --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-lv/strings.xml @@ -0,0 +1,31 @@ + + + "Google Play pakalpojumu iegūšana" + "Lai šī lietotne darbotos, tālrunī ir jāinstalē Google Play pakalpojumi." + "Lai šī lietotne darbotos, planšetdatorā ir jāinstalē Google Play pakalpojumi." + "Iegūt Google Play pakalpojumus" + "Google Play pakalpojumu iespējošana" + "Lai šī lietotne darbotos, iespējojiet Google Play pakalpojumus." + "Iespējot Google Play pakalpojumus" + "Google Play pakalpojumu atjaunināšana" + "Lai šī lietotne darbotos, atjauniniet Google Play pakalpojumus." + "Tīkla kļūda" + "Lai izveidotu savienojumu ar Google Play pakalpojumiem, ir nepieciešams datu savienojums." + "Nederīgs konts" + "Norādītais konts šajā ierīcē nepastāv. Lūdzu, izvēlieties citu kontu." + "Nezināma problēma ar Google Play pakalpojumiem." + "Google Play pakalpojumi" + "Jūsu ierīce neatbalsta Google Play pakalpojumus, kuri nepieciešami dažu jūsu lietojumprogrammu darbībai. Lūdzu, sazinieties ar ražotāju, lai saņemtu palīdzību." + "Šķiet, ka ierīcē ir iestatīts nepareizs datums. Lūdzu, pārbaudiet ierīces datumu." + "Atjaunināt" + "Pierakst." + "Pierakstīties Google" + + "Lietojumpr. mēģināja izmantot nederīgu Google Play pakalp. versiju." + "Lai lietojumprogramma darbotos, ir jāiespējo Google Play pakalpojumi." + "Lai lietojumprogramma darbotos, ir jāinstalē Google Play pakalpojumi." + "Lai lietojumprogramma darbotos, jāatjaunina Google Play pakalpojumi." + "Google Play pakalpojumu kļūda" + "Pieprasījums no lietotnes %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-mn-rMN/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-mn-rMN/strings.xml new file mode 100644 index 0000000000..1743256a11 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-mn-rMN/strings.xml @@ -0,0 +1,31 @@ + + + "Google Play үйлчилгээ авах" + "Таны утсанд байхгүй байгаа Google Play үйлчилгээг идэвхжүүлж байж энэ апп-г ажиллуулах боломжтой." + "Таны таблетэд байхгүй Google Play үйлчилгээг идэвхжүүлж байж энэ апп-г ажиллуулах боломжтой." + "Google Play үйлчилгээ авах" + "Google Play үйлчилгээг идэвхжүүлэх" + "Та Google Play үйлчилгээг идэвхжүүлж байж энэ апп-г ажиллуулах боломжтой." + "Google Play үйлчилгээг идэвхжүүлэх" + "Google Play үйлчилгээг шинэчлэх" + "Та Google Play үйлчилгээг шинэчлэхгүй бол энэ апп ажиллах боломжгүй." + "Сүлжээний алдаа" + "Google Play үйлчилгээнд холбогдохын тулд дата холболт шаардлагатай." + "Буруу акаунт" + "Заасан акаунт энэ төхөөрөмж дээр байхгүй байна. Өөр акаунт сонгоно уу." + "Google Play үйлчилгээтэй холбоотой тодорхойгүй алдаа." + "Google Play үйлчилгээ" + "Таны зарим аппликешнүүдийн хамаардаг Google Play үйлчилгээ таны төхөөрөмжид дэмжигдэхгүй байна. Тусламж авахын тулд үйлдвэрлэгчтэй холбоо барина уу." + "Төхөөрөмжийн огноо буруу байгаа бололтой. Төхөөрөмжийн огноог шалгана уу." + "Шинэчлэх" + "Нэвтрэх" + "Google-р нэвтрэх:" + + "Аппликешн Google Play Үйлчилгээний муу хувилбарыг ашиглахыг оролдлоо." + "Аппликешн Google Play Үйлчилгээг идэвхжүүлсэн байхыг шаардана." + "Аппликешн Google Play Үйлчилгээг суулгахыг шаардана." + "Аппликешн Google Play Үйлчилгээг шинэчлэхийг шаардана." + "Google Play үйлчилгээний алдаа" + "Хүсэлт гаргасан %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-ms-rMY/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-ms-rMY/strings.xml new file mode 100644 index 0000000000..8e8a4b9b8a --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-ms-rMY/strings.xml @@ -0,0 +1,31 @@ + + + "Dapatkan perkhidmatan Google Play" + "Apl ini tidak akan berfungsi tanpa perkhidmatan Google Play dan apl ini tiada pada telefon anda." + "Apl ini tidak akan berfungsi tanpa perkhidmatan Google Play dan apl ini tiada pada tablet anda." + "Dapatkan perkhidmatan Google Play" + "Dayakan perkhidmatan Google Play" + "Apl ini tidak akan berfungsi kecuali anda mendayakan perkhidmatan Google Play." + "Dayakan perkhidmatan Google Play" + "Kemas kini perkhidmatan Google Play" + "Apl ini tidak akan berfungsi kecuali anda mengemas kini perkhidmatan Google Play." + "Ralat Rangkaian" + "Sambungan data diperlukan untuk menyambung ke perkhidmatan Google Play." + "Akaun Tidak Sah" + "Akaun yang dinyatakan tidak wujud pada peranti ini. Sila pilih akaun yang lain." + "Isu tidak diketahui dengan perkhidmatan Google Play." + "Perkhidmatan Google Play" + "Peranti anda tidak menyokong perkhidmatan Google Play, sedangkan sesetengah aplikasi anda memerlukannya. Sila hubungi pengilang untuk bantuan." + "Tarikh pada peranti kelihatan tidak betul. Sila semak tarikh pada peranti." + "Kemas kini" + "Log masuk" + "Log masuk dengan Google" + + "Aplikasi cuba menggunakan versi Perkhidmatan Google Play yang rosak." + "Perkhidmatan Google Play perlu didayakan untuk menggunakan aplikasi." + "Perkhidmatan Google Play perlu dipasang untuk mengguankan aplikasi." + "Perkhidmatan Google Play perlu dikemas kini untuk menggunakan aplikasi." + "Ralat perkhidmatan Google Play" + "Diminta oleh %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-ms/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-ms/strings.xml new file mode 100644 index 0000000000..8e8a4b9b8a --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-ms/strings.xml @@ -0,0 +1,31 @@ + + + "Dapatkan perkhidmatan Google Play" + "Apl ini tidak akan berfungsi tanpa perkhidmatan Google Play dan apl ini tiada pada telefon anda." + "Apl ini tidak akan berfungsi tanpa perkhidmatan Google Play dan apl ini tiada pada tablet anda." + "Dapatkan perkhidmatan Google Play" + "Dayakan perkhidmatan Google Play" + "Apl ini tidak akan berfungsi kecuali anda mendayakan perkhidmatan Google Play." + "Dayakan perkhidmatan Google Play" + "Kemas kini perkhidmatan Google Play" + "Apl ini tidak akan berfungsi kecuali anda mengemas kini perkhidmatan Google Play." + "Ralat Rangkaian" + "Sambungan data diperlukan untuk menyambung ke perkhidmatan Google Play." + "Akaun Tidak Sah" + "Akaun yang dinyatakan tidak wujud pada peranti ini. Sila pilih akaun yang lain." + "Isu tidak diketahui dengan perkhidmatan Google Play." + "Perkhidmatan Google Play" + "Peranti anda tidak menyokong perkhidmatan Google Play, sedangkan sesetengah aplikasi anda memerlukannya. Sila hubungi pengilang untuk bantuan." + "Tarikh pada peranti kelihatan tidak betul. Sila semak tarikh pada peranti." + "Kemas kini" + "Log masuk" + "Log masuk dengan Google" + + "Aplikasi cuba menggunakan versi Perkhidmatan Google Play yang rosak." + "Perkhidmatan Google Play perlu didayakan untuk menggunakan aplikasi." + "Perkhidmatan Google Play perlu dipasang untuk mengguankan aplikasi." + "Perkhidmatan Google Play perlu dikemas kini untuk menggunakan aplikasi." + "Ralat perkhidmatan Google Play" + "Diminta oleh %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-nb/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-nb/strings.xml new file mode 100644 index 0000000000..1e16bbb6d2 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-nb/strings.xml @@ -0,0 +1,31 @@ + + + "Installer Google Play Tjenester" + "Denne appen kan ikke kjøres uten Google Play Tjenester, som ikke er installert på telefonen din." + "Denne appen kan ikke kjøres uten Google Play Tjenester, som ikke er installert på nettbrettet ditt." + "Installer Google Play Tjenester" + "Aktiver Google Play Tjenester" + "Denne appen fungerer ikke med mindre du aktiverer Google Play Tjenester." + "Aktiver Google Play Tjenester" + "Oppdater Google Play Tjenester" + "Denne appen kan ikke kjøres før du oppdaterer Google Play Tjenester." + "Nettverksfeil" + "Du må ha datatilkobling for å koble deg til Google Play-tjenester." + "Ugyldig konto" + "Den angitte kontoen finnes ikke på enheten. Velg en annen konto." + "Det oppsto et ukjent problem med Google Play Tjenester." + "Google Play-tjenester" + "Google Play Tjenester, som noen av appene er avhengige av, støttes ikke av enheten. Ta kontakt med produsenten for å få hjelp." + "Datoen på enheten ser ut til å være feil. Sjekk datoen på enheten." + "Oppdater" + "Logg på" + "Logg inn med Google" + + "En app prøvde å bruke en skadet versjon av Google Play Tjenester." + "En app krever Google Play Tjenester for å aktiveres." + "En app krever at Google Play Tjenester installeres." + "En app krever at Google Play Tjenester oppdateres." + "Google Play Tjenester-feil" + "Forespurt av %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-nl/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-nl/strings.xml new file mode 100644 index 0000000000..f38db5fcdb --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-nl/strings.xml @@ -0,0 +1,31 @@ + + + "Google Play-services ophalen" + "Deze app kan niet worden uitgevoerd zonder Google Play-services die ontbreken op uw telefoon." + "Deze app kan niet worden uitgevoerd zonder Google Play-services die ontbreken op uw tablet." + "Google Play-services ophalen" + "Google Play-services inschakelen" + "Deze app werkt niet, tenzij u Google Play-services inschakelt." + "Google Play-services inschak." + "Google Play-services bijwerken" + "Deze app kan niet worden uitgevoerd, tenzij u Google Play-services bijwerkt." + "Netwerkfout" + "Er is een gegevensverbinding nodig om verbinding te kunnen maken met Google Play-services." + "Ongeldig account" + "Het gespecificeerde account bestaat niet op dit apparaat. Kies een ander account." + "Onbekend probleem met Google Play-services." + "Google Play-services" + "Google Play-services, dat vereist is voor een aantal van uw applicaties, wordt niet ondersteund door uw apparaat. Neem contact op met de fabrikant voor ondersteuning." + "De datum op het apparaat lijkt onjuist. Controleer de datum op het apparaat." + "Bijwerken" + "Inloggen" + "Inloggen met Google" + + "Onjuiste versie van Google Play-services wordt gebruikt." + "Google Play-services moet zijn ingeschakeld voor een applicatie." + "Google Play-services moet zijn geïnstalleerd voor een applicatie." + "Google Play-services moet worden geüpdatet voor een applicatie." + "Fout met Google Play-services" + "Aangevraagd door %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-pl/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-pl/strings.xml new file mode 100644 index 0000000000..5eba15ff3a --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-pl/strings.xml @@ -0,0 +1,31 @@ + + + "Pobierz Usługi Google Play" + "Ta aplikacja nie będzie działać bez Usług Google Play, których nie masz na telefonie." + "Ta aplikacja nie będzie działać bez Usług Google Play, których nie masz na tablecie." + "Pobierz Usługi Google Play" + "Włącz Usługi Google Play" + "Ta aplikacja nie będzie działać, jeśli nie włączysz Usług Google Play." + "Włącz Usługi Google Play" + "Aktualizuj Usługi Google Play" + "Ta aplikacja nie będzie działać, jeśli nie zaktualizujesz Usług Google Play." + "Błąd sieci" + "Korzystanie z usług Google Play wymaga połączenia z internetem." + "Nieprawidłowe konto" + "Podanego konta nie ma na tym urządzeniu. Wybierz inne konto." + "Nieznany problem z Usługami Google Play." + "Usługi Google Play" + "Usługi Google Play, od których zależy działanie niektórych aplikacji, nie są obsługiwane na Twoim urządzeniu. Skontaktuj się z producentem, by uzyskać pomoc." + "Data ustawiona na urządzeniu wydaje się nieprawidłowa. Sprawdź datę ustawioną na urządzeniu." + "Aktualizuj" + "Zaloguj się" + "Zaloguj się przez Google" + + "Aplikacja próbowała skorzystać z nieprawidłowej wersji Usług Google Play." + "Aplikacja wymaga włączenia Usług Google Play." + "Aplikacja wymaga zainstalowania Usług Google Play." + "Aplikacja wymaga aktualizacji Usług Google Play." + "Błąd usług Google Play" + "Żądanie z aplikacji %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-pt-rBR/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-pt-rBR/strings.xml new file mode 100644 index 0000000000..6db462d709 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-pt-rBR/strings.xml @@ -0,0 +1,31 @@ + + + "Instale o Google Play Services" + "Este aplicativo não funciona sem o Google Play Services, que não está instalado em seu telefone." + "Este aplicativo não funciona sem o Google Play Services, que não está instalado em seu tablet." + "Instalar o Google Play Services" + "Ative o Google Play Services" + "Este aplicativo só funciona com o Google Play Services ativado." + "Ativar o Google Play Services" + "Atualize o Google Play Services" + "Este aplicativo só funciona com uma versão atualizada do Google Play Services." + "Erro na rede" + "É necessária uma conexão de dados para conectar ao Google Play Services." + "Conta inválida" + "A conta especificada não existe no dispositivo. Escolha outra conta." + "Problema desconhecido com o Google Play Services." + "Play Services" + "O Google Play Services, necessário para alguns dos aplicativos, não é compatível com seu dispositivo. Entre em contato com o fabricante para obter assistência." + "A data no dispositivo parece incorreta. Verifique a data no dispositivo." + "Atualizar" + "Login" + "Fazer login com o Google" + + "Um aplicativo tentou usar uma versão errada do Google Play Services." + "Um aplicativo requer a ativação do Google Play Services." + "Um aplicativo requer a instalação do Google Play Services." + "Um aplicativo requer a atualização do Google Play Services." + "Ocorreu um erro no Google Play Services" + "Solicitado por %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-pt-rPT/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-pt-rPT/strings.xml new file mode 100644 index 0000000000..0ceafcb95f --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-pt-rPT/strings.xml @@ -0,0 +1,31 @@ + + + "Obter serviços do Google Play" + "Esta aplicação não será executada sem os serviços do Google Play, que estão em falta no seu telemóvel." + "Esta aplicação não será executada sem os serviços do Google Play, que estão em falta no seu tablet." + "Obter serviços do Google Play" + "Ativar serviços do Google Play" + "Esta aplicação não funcionará enquanto não ativar os serviços do Google Play." + "Ativar serviços do Google Play" + "Atualizar serviços do Google Play" + "Esta aplicação não será executada enquanto não atualizar os serviços do Google Play." + "Erro de Rede" + "É necessária uma ligação de dados para se ligar aos Serviços do Google Play." + "Conta Inválida" + "A conta especificada não existe neste dispositivo. Escolha uma conta diferente." + "Problema desconhecido nos serviços do Google Play." + "Serviços do Google Play" + "Os serviços do Google Play, dos quais dependem algumas das suas aplicações, não são suportados pelo seu dispositivo. Contacte o fabricante para obter assistência." + "A data no dispositivo parece estar incorreta. Verifique a data no dispositivo." + "Atualizar" + "Inic. ses." + "Inic. sessão com o Google" + + "Aplicação tentou utiliz. versão incorreta dos Serviços do Google Play." + "Uma aplicação necessita da ativação dos Serviços do Google Play." + "Uma aplicação necessita da instalação dos Serviços do Google Play." + "Uma aplicação necessita da atualização dos Serviços do Google Play." + "Erro dos serviços do Google Play" + "Solicitado por %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-pt/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-pt/strings.xml new file mode 100644 index 0000000000..6db462d709 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-pt/strings.xml @@ -0,0 +1,31 @@ + + + "Instale o Google Play Services" + "Este aplicativo não funciona sem o Google Play Services, que não está instalado em seu telefone." + "Este aplicativo não funciona sem o Google Play Services, que não está instalado em seu tablet." + "Instalar o Google Play Services" + "Ative o Google Play Services" + "Este aplicativo só funciona com o Google Play Services ativado." + "Ativar o Google Play Services" + "Atualize o Google Play Services" + "Este aplicativo só funciona com uma versão atualizada do Google Play Services." + "Erro na rede" + "É necessária uma conexão de dados para conectar ao Google Play Services." + "Conta inválida" + "A conta especificada não existe no dispositivo. Escolha outra conta." + "Problema desconhecido com o Google Play Services." + "Play Services" + "O Google Play Services, necessário para alguns dos aplicativos, não é compatível com seu dispositivo. Entre em contato com o fabricante para obter assistência." + "A data no dispositivo parece incorreta. Verifique a data no dispositivo." + "Atualizar" + "Login" + "Fazer login com o Google" + + "Um aplicativo tentou usar uma versão errada do Google Play Services." + "Um aplicativo requer a ativação do Google Play Services." + "Um aplicativo requer a instalação do Google Play Services." + "Um aplicativo requer a atualização do Google Play Services." + "Ocorreu um erro no Google Play Services" + "Solicitado por %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-ro/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-ro/strings.xml new file mode 100644 index 0000000000..eb428964ec --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-ro/strings.xml @@ -0,0 +1,31 @@ + + + "Descărcaţi Servicii Google Play" + "Această aplicaţie nu poate rula fără Servicii Google Play, care lipsesc de pe telefon." + "Această aplicaţie nu poate rula fără Servicii Google Play, care lipsesc de pe tabletă." + "Obţineţi Servicii Google Play" + "Activaţi Servicii Google Play" + "Această aplicaţie nu va funcţiona decât dacă activaţi Servicii Google Play." + "Activaţi Servicii Google Play" + "Actualizaţi Servicii Google Play" + "Această aplicaţie nu poate rula decât dacă actualizaţi Servicii Google Play." + "Eroare de reţea" + "Este necesară o conexiune de date pentru a vă conecta la serviciile Google Play." + "Cont nevalid" + "Contul menționat nu există pe acest dispozitiv. Alegeți alt cont." + "Problemă necunoscută privind Servicii Google Play." + "Servicii Google Play" + "Gadgetul nu acceptă serviciile Google Play, pe care se bazează unele dintre aplicații. Pentru asistență, contactați producătorul gadgetului." + "Data de pe dispozitiv pare să fie incorectă. Verificați data de pe dispozitiv." + "Actualizaţi" + "Conectați" + "Conectați-vă cu Google" + + "Aplicația a încercat să utilizeze o vers. Servicii Google Play greșită" + "O aplicație necesită activarea Serviciilor Google Play." + "O aplicație necesită instalarea Serviciilor Google Play." + "O aplicație necesită o actualizare pentru Servicii Google Play." + "Eroare Servicii Google Play" + "Solicitată de %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-ru/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-ru/strings.xml new file mode 100644 index 0000000000..c784aae95c --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-ru/strings.xml @@ -0,0 +1,31 @@ + + + "Установите Сервисы Google Play" + "Для работы этого приложения требуется установить Сервисы Google Play." + "Для работы этого приложения требуется установить Сервисы Google Play." + "Установить" + "Включите Сервисы Google Play" + "Для работы этого приложения требуется включить Сервисы Google Play." + "Включить" + "Обновите Сервисы Google Play" + "Для работы этого приложения требуется обновить Сервисы Google Play." + "Ошибка сети" + "Для работы с Google Play требуется подключение к сети." + "Недействительный аккаунт" + "Этого аккаунта нет на устройстве. Выберите другой." + "Неизвестная ошибка с Сервисами Google Play." + "Сервисы Google Play" + "Сервисы Google Play, необходимые для работы некоторых приложений, не поддерживаются на вашем устройстве. Обратитесь к производителю." + "Проверьте правильность даты, указанной на устройстве." + "Обновить" + "Войти" + "Войти в аккаунт Google" + + "Версия сервисов Google Play неисправна" + "Для работы приложения требуется включить сервисы Google Play" + "Для работы приложения требуется установить сервисы Google Play" + "Для работы приложения требуется обновить сервисы Google Play" + "Ошибка сервисов Google Play" + "Запрос от приложения \"%1$s\"" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-sk/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-sk/strings.xml new file mode 100644 index 0000000000..125d87f6da --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-sk/strings.xml @@ -0,0 +1,31 @@ + + + "Inštalovať služby Google Play" + "Na spustenie tejto aplikácie sa vyžadujú služby Google Play, ktoré v telefóne nemáte." + "Na spustenie tejto aplikácie sa vyžadujú služby Google Play, ktoré v tablete nemáte." + "Inštalovať služby Google Play" + "Povoliť služby Google Play" + "Táto aplikácia bude fungovať až po povolení služieb Google Play." + "Povoliť služby Google Play" + "Aktualizovať služby Google Play" + "Túto aplikáciu bude možné spustiť až po aktualizácii služieb Google Play." + "Chyba siete" + "Pripojenie k službám Google Play si vyžaduje dátové pripojenie." + "Neplatný účet" + "Zadaný účet v tomto zariadení neexistuje. Vyberte iný účet." + "Neznámy problém so službami Google Play." + "Služby Google Play" + "Niektoré vaše aplikácie vyžadujú služby Google Play, ktoré vo vašom zariadení nie sú podporované. Ak potrebujete pomoc, kontaktujte výrobcu." + "Dátum nastavený v zariadení sa zdá byť nesprávny. Skontrolujte ho." + "Aktualizovať" + "Prihlásiť sa" + "Prihlásiť sa do účtu Google" + + "Aplikácia sa pokúsila použiť nesprávnu verziu služieb Google Play." + "Aplikácia vyžaduje povolenie služieb Google Play." + "Aplikácia vyžaduje inštaláciu služieb Google Play." + "Aplikácia vyžaduje aktualizáciu služieb Google Play." + "Chyba služieb Google Play" + "Vyžiadané aplikáciou %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-sl/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-sl/strings.xml new file mode 100644 index 0000000000..df5821f94c --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-sl/strings.xml @@ -0,0 +1,31 @@ + + + "Namestite storitve Google Play" + "Ta aplikacija ne deluje brez storitev Google Play, ki jih ni v telefonu." + "Ta aplikacija ne deluje brez storitev Google Play, ki jih ni v tabličnem računalniku." + "Namestite storitve Google Play" + "Omogočite storitve Google Play" + "Aplikacija ne bo delovala, če ne omogočite storitev Google Play." + "Omogočite storitve Google Play" + "Posodobite storitve Google Play" + "Ta aplikacija ne deluje, če ne posodobite storitev Google Play." + "Omrežna napaka" + "Za povezavo s storitvami Google Play potrebujete internetno povezavo." + "Neveljaven račun" + "V tej napravi ne obstaja navedeni račun. Izberite drugega." + "Neznana težava s storitvami Google Play." + "Storitve Google Play" + "Vaša naprava na podpira storitev Google Play, ki jih potrebujejo nekatere od vaših aplikacij. Za pomoč se obrnite na izdelovalca." + "Videti je, da je datum v napravi napačen. Preverite ga." + "Posodobi" + "Prijava" + "Prijavite se v Google" + + "Aplikacija je poskusila uporabiti napačno različico Storitev Google Play." + "Za delovanje aplikacije morate omogočiti Storitve Google Play." + "Za delovanje aplikacije morate namestiti Storitve Google Play." + "Za delovanje aplikacije morate posodobiti Storitve Google Play." + "Napaka storitev Google Play" + "Zahtevala aplikacija %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-sr/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-sr/strings.xml new file mode 100644 index 0000000000..ad0b549547 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-sr/strings.xml @@ -0,0 +1,31 @@ + + + "Преузимање Google Play услуга" + "Ова апликација не може да се покрене без Google Play услуга, које недостају на телефону." + "Ова апликација не може да се покрене без Google Play услуга, које недостају на таблету." + "Преузми Google Play услуге" + "Омогућавање Google Play услуга" + "Ова апликација неће функционисати ако не омогућите Google Play услуге." + "Омогући Google Play услуге" + "Ажурирање Google Play услуга" + "Ова апликација не може да се покрене ако не ажурирате Google Play услуге." + "Грешка на мрежи" + "За повезивање са Google Play услугама потребна је веза за пренос података." + "Неважећи налог" + "Наведени налог не постоји на овом уређају. Одаберите други налог." + "Непознат проблем са Google Play услугама." + "Google Play услуге" + "Google Play услуге, које су потребне за функционисање неких од апликација, нису подржане на уређају. Контактирајте произвођача да бисте добили помоћ." + "Изгледа да су подаци на уређају нетачни. Проверите датум на уређају." + "Ажурирај" + "Пријави ме" + "Пријави ме преко Google-а" + + "Апликација је покушала да користи лошу верзију Google Play услуга." + "Апликација захтева да Google Play услуге буду омогућене." + "Апликација захтева инсталирање Google Play услуга." + "Апликација захтева ажурирање Google Play услуга." + "Грешка Google Play услуга" + "Захтева %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-sv/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-sv/strings.xml new file mode 100644 index 0000000000..6a10395f4b --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-sv/strings.xml @@ -0,0 +1,31 @@ + + + "Hämta Google Play Tjänster" + "Den här appen kan inte köras utan Google Play Tjänster, som saknas på mobilen." + "Den här appen kan inte köras utan Google Play Tjänster, som saknas på surfplattan." + "Hämta Google Play Tjänster" + "Aktivera Google Play Tjänster" + "Du måste aktivera Google Play Tjänster för att den här appen ska fungera." + "Aktivera Google Play Tjänster" + "Uppdatera Google Play Tjänster" + "Du måste uppdatera Google Play Tjänster innan du kan köra den här appen." + "Nätverksfel" + "En dataanslutning krävs för att ansluta till Google Plays tjänster." + "Ogiltigt konto" + "Det angivna kontot finns inte på den här enheten. Välj ett annat konto." + "Okänt problem med Google Play Tjänster" + "Google Play-tjänster" + "Några av dina appar använder Google Play-tjänster som inte stöds av din enhet. Kontakta tillverkaren om du vill ha hjälp." + "Datumet på enheten verkar inte vara rätt. Kontrollera datumet på enheten." + "Uppdatera" + "Logga in" + "Logga in med Google" + + "En olämplig version av Google Play Tjänster anropades av en app." + "Google Play Tjänster måste aktiveras för en att app ska fungera." + "Google Play Tjänster måste installeras för att en app ska fungera." + "Google Play Tjänster måste uppdateras för en app ska fungera." + "Fel på Google Play Tjänster" + "Begärdes av %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-sw/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-sw/strings.xml new file mode 100644 index 0000000000..37bd92ac68 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-sw/strings.xml @@ -0,0 +1,31 @@ + + + "Pata huduma za Google Play" + "Programu hii haiwezi kuendeshwa bila huduma za Google Play, ambazo hazipo kwenye simu yako." + "Programu hii haiwezi kuendeshwa bila huduma za Google Play, ambazo hazipo kwenye kompyuta yako ndogo." + "Pata huduma za Google Play" + "Wezesha huduma za Google Play" + "Programu hii haitafanya kazi mpaka utakapowezesha huduma za Google Play." + "Wezesha huduma za Google Play" + "Sasisha huduma za Google Play" + "Programu hii haiwezi kuendeshwa mpaka utakaposasisha huduma za Google Play." + "Hitilafu ya Mtandao" + "Muunganisho wa data unahitajika ili kuunganisha kwenye huduma za Google Play." + "Akaunti Batili" + "Akaunti iliyobainishwa haipo kwenye kifaa hiki. Tafadhali chagua akaunti tofauti." + "Suala lisilojulikana na huduma za Google Play." + "Huduma za Google Play" + "Huduma za Google Play, ambazo baadhi ya programu zako zinategemea, si linganifu na kifaa chako. Tafadhali wasiliana na mtengenezaji kwa usaidizi." + "Inaeonekana tarehe ya kifaa sio sahihi. Tafadhali angalia tarehe ya kifaa." + "Sasisha" + "Ingia" + "Ingia ukitumia Google" + + "Programu ilijaribu kutumia toleo baya la Huduma za Google Play." + "Programu inahitaji Huduma za Google Play ili kuwashwa." + "Programu inahitaji usakinishaji wa Huduma za Google Play." + "Programu inahitaji sasisho la Huduma za Google Play." + "Hitilafu kwenye Huduma za Google Play" + "Imeombwa na %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-th/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-th/strings.xml new file mode 100644 index 0000000000..6f098fe801 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-th/strings.xml @@ -0,0 +1,31 @@ + + + "รับบริการ Google Play" + "แอปพลิเคชันนี้จะไม่ทำงานหากไม่มีบริการ Google Play ซึ่งไม่มีในโทรศัพท์ของคุณ" + "แอปพลิเคชันนี้จะไม่ทำงานหากไม่มีบริการ Google Play ซึ่งไม่มีในแท็บเล็ตของคุณ" + "รับบริการ Google Play" + "เปิดใช้งานบริการ Google Play" + "แอปพลิเคชันนี้จะไม่ทำงานจนกว่าคุณจะเปิดใช้งานบริการ Google Play" + "เปิดใช้งานบริการ Google Play" + "อัปเดตบริการ Google Play" + "แอปพลิเคชันนี้จะไม่ทำงานจนกว่าคุณจะอัปเดตบริการ Google Play" + "ข้อผิดพลาดของเครือข่าย" + "ต้องมีการเขื่อมต่อข้อมูลเพื่อเชื่อมต่อกับบริการ Google Play" + "บัญชีไม่ถูกต้อง" + "บัญชีที่ระบุไม่มีอยู่บนอุปกรณ์นี้ โปรดเลือกบัญชีอื่น" + "ปัญหาที่ไม่รู้จักของบริการ Google Play" + "บริการ Google Play" + "บริการ Google Play ซึ่งใช้งานในบางแอปพลิเคชัน ไม่ได้รับการสนับสนุนโดยอุปกรณ์ของคุณ โปรดติดต่อผู้ผลิตเพื่อขอรับความช่วยเหลือ" + "วันที่บนอุปกรณ์ไม่ถูกต้อง โปรดตรวจสอบวันที่บนอุปกรณ์" + "อัปเดต" + "ลงชื่อใช้" + "ลงชื่อเข้าใช้ด้วย Google" + + "แอปพลิเคชันหนึ่งพยายามใช้เวอร์ชันที่ไม่เหมาะสมของบริการ Google Play" + "แอปพลิเคชันหนึ่งจำเป็นต้องมีบริการ Google Play เพื่อเปิดใช้งาน" + "แอปพลิเคชันหนึ่งจำเป็นต้องมีการติดตั้งบริการ Google Play" + "แอปพลิเคชันหนึ่งจำเป็นต้องมีการอัปเดตสำหรับบริการ Google Play" + "ข้อผิดพลาดของบริการ Google Play" + "ขอโดย %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-tl/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-tl/strings.xml new file mode 100644 index 0000000000..337f73c0cd --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-tl/strings.xml @@ -0,0 +1,31 @@ + + + "Kumuha ng mga serbisyo ng Google Play" + "Hindi tatakbo ang app na ito nang wala ang mga serbisyo ng Google Play, na wala sa iyong telepono." + "Hindi gagana ang app na ito nang wala ang mga serbisyo ng Google Play, na wala sa iyong tablet." + "Kumuha ng Google Play services" + "Paganahin ang Google Play services" + "Hindi gagana ang app na ito maliban kung papaganahin mo ang mga serbisyo ng Google Play." + "Enable Google Play services" + "I-update ang mga serbisyo ng Google Play" + "Hindi gagana ang app na ito maliban kung i-a-update mo ang mga serbisyo ng Google Play." + "May Error sa Network" + "Kailangan ng koneksyon ng data upang makakonekta sa mga serbisyo ng Google Play." + "Di-wasto ang Account" + "Hindi umiiral ang tinukoy na account sa device na ito. Mangyaring pumili ng ibang account." + "May hindi alam na isyu sa mga serbisyo ng Google Play." + "Mga serbisyo ng Google Play" + "Ang mga serbisyo ng Google Play, kung saan nakadepende ang ilan sa iyong mga application, ay hindi sinusuportahan ng iyong device. Mangyaring makipag-ugnay sa manufacturer para sa tulong." + "Mukhang hindi tama ang petsa sa device. Pakisuri ang petsa sa device." + "I-update" + "Sign in" + "Mag-sign in sa Google" + + "May app na sumubok ng maling bersyon ng Mga Serbisyo ng Google Play." + "Kailangan ng application na na-enable ang Mga Serbisyo ng Google Play." + "Kailangan ng application na ma-install ang Serbisyo ng Google Play." + "Kailangan ng application na i-update ang Mga Serbisyo ng Google Play." + "Error sa mga serbisyo ng Google Play" + "Hiniling ng %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-tr/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-tr/strings.xml new file mode 100644 index 0000000000..17e61e5fcb --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-tr/strings.xml @@ -0,0 +1,31 @@ + + + "Google Play hizmetlerini edinin" + "Google Play Hizmetleri telefonunuzda yok ve bu uygulama Google Play Hizmetleri olmadan çalışmaz." + "Google Play Hizmetleri tabletinizde yok ve bu uygulama Google Play Hizmetleri olmadan çalışmaz." + "Google Play hizmetlerini edin" + "Google Play hizmetlerini etkinleştir" + "Bu uygulama, Google Play Hizmetleri etkinleştirilmeden çalışmaz" + "Google Play hizmetlerini etkinleştir" + "Google Play hizmetlerini güncelle" + "Bu uygulama Google Play Hizmetleri güncellenmeden çalışmaz." + "Ağ Hatası" + "Google Play hizmetlerine bağlanmak için bir veri bağlantısı gerekiyor." + "Geçersiz Hesap" + "Belirtilen hesap bu cihazda mevcut değil. Lütfen farklı bir hesap seçin." + "Google Play hizmetleriyle ilgili bilinmeyen sorun." + "Google Play hizmetleri" + "Cihazınız, uygulamalarınızdan bazıları için gerekli olan Google Play hizmetlerini desteklemiyor. Lütfen yardım için üreticiyle iletişim kurun." + "Cihazdaki tarih doğru görünmüyor. Lütfen cihazda ayarlı tarihi kontrol edin." + "Güncelle" + "Oturum aç" + "Google\'da oturum aç" + + "Bir uygulama, Google Play Hizmetleri\'nin bozuk bir sürümünü kullanmayı denedi." + "Bir uygulama, Google Play Hizmetleri\'nin etkin olmasını gerektiriyor." + "Bir uygulama, Google Play Hizmetleri\'nin yüklenmesini gerektiriyor." + "Bir uygulama, Google Play Hizmetleri için bir güncelleme gerektiriyor." + "Google Play hizmetleri hatası" + "İstekte bulunan: %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-uk/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-uk/strings.xml new file mode 100644 index 0000000000..d657aea68d --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-uk/strings.xml @@ -0,0 +1,31 @@ + + + "Установити Google Play Послуги" + "Ця програма не запуститься без Google Play Послуг, яких немає у вашому телефоні." + "Ця програма не запуститься без Google Play Послуг, яких немає на вашому планшетному ПК." + "Установити Google Play Послуги" + "Увімкнути Google Play Послуги" + "Ця програма не працюватиме, поки ви не ввімкнете Google Play Послуги." + "Увімкнути Google Play Послуги" + "Оновити Google Play Послуги" + "Ця програма не запуститься, поки ви не оновите Google Play Послуги." + "Помилка мережі" + "Для під’єднання до сервісів Google Play потрібне з’єднання з мережею." + "Недійсний обліковий запис" + "Указаний обліковий запис не існує на цьому пристрої. Виберіть інший обліковий запис." + "Google Play Послуги – невідома проблема." + "Сервіси Google Play" + "Ваш пристрій не підтримує Сервіси Google Play, від яких залежить робота деяких програм. Зверніться по допомогу до виробника." + "Схоже, на пристрої вказано неправильну дату. Перевірте її." + "Оновити" + "Увійти" + "Увійти в обл.запис Google" + + "Програма спробувала застосувати хибну версію Сервісів Google Play." + "Щоб програма працювала, потрібно ввімкнути Сервіси Google Play." + "Щоб програма працювала, потрібно встановити Сервіси Google Play." + "Щоб програма працювала, потрібно оновити Сервіси Google Play." + "Помилка Сервісів Google Play" + "Запит від програми %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-vi/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-vi/strings.xml new file mode 100644 index 0000000000..a0434a08ac --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-vi/strings.xml @@ -0,0 +1,31 @@ + + + "Cài đặt dịch vụ của Google Play" + "Ứng dụng này sẽ không chạy nếu không có dịch vụ của Google Play. Điện thoại của bạn bị thiếu dịch vụ này." + "Ứng dụng này sẽ không chạy nếu không có dịch vụ của Google Play. Máy tính bảng của bạn bị thiếu dịch vụ này." + "Cài đặt dịch vụ của Google Play" + "Bật dịch vụ của Google Play" + "Ứng dụng này sẽ không hoạt động trừ khi bạn bật dịch vụ của Google Play." + "Bật dịch vụ của Google Play" + "Cập nhật dịch vụ của Google Play" + "Ứng dụng này sẽ không chạy trừ khi bạn cập nhật dịch vụ của Google Play." + "Lỗi mạng" + "Cần có kết nối dữ liệu để kết nối với các dịch vụ của Google Play." + "Tài khoản không hợp lệ" + "Tài khoản đã chỉ định không tồn tại trên thiết bị này. Vui lòng chọn một tài khoản khác." + "Sự cố không xác định với dịch vụ của Google Play." + "Dịch vụ của Google Play" + "Các dịch vụ của Google Play mà một số ứng dụng của bạn dựa vào không được thiết bị của bạn hỗ trợ. Vui lòng liên hệ với nhà sản xuất để được hỗ trợ." + "Ngày trên thiết bị có vẻ không chính xác. Vui lòng kiểm tra ngày trên thiết bị." + "Cập nhật" + "Đăng nhập" + "Đăng nhập bằng Google" + + "Ứng dụng đã cố sử dụng phiên bản không đúng của Dịch vụ của Google Play." + "Ứng dụng yêu cầu Dịch vụ của Google Play phải được bật." + "Ứng dụng yêu cầu cài đặt Dịch vụ của Google Play." + "Ứng dụng yêu cầu cập nhật dành cho Dịch vụ Google Play." + "Lỗi dịch vụ của Google Play" + "Được yêu cầu bởi %1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-zh-rCN/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-zh-rCN/strings.xml new file mode 100644 index 0000000000..4339e3eb01 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-zh-rCN/strings.xml @@ -0,0 +1,31 @@ + + + "获取 Google Play 服务" + "您的手机中没有 Google Play 服务,您必须先安装该服务才能运行此应用。" + "您的平板电脑中没有 Google Play 服务,您必须先安装该服务才能运行此应用。" + "获取 Google Play 服务" + "启用 Google Play 服务" + "您必须先启用 Google Play 服务才能运行此应用。" + "启用 Google Play 服务" + "更新 Google Play 服务" + "您必须先更新 Google Play 服务才能运行此应用。" + "网络错误" + "您必须有数据网络连接才能接入 Google Play 服务。" + "无效帐户" + "此设备上不存在指定的帐户,请选择其他帐户。" + "Google Play 服务出现未知问题。" + "Google Play 服务" + "您的设备不支持部分应用所依赖的 Google Play 服务。请与设备制造商联系,以寻求帮助。" + "设备上的日期似乎不正确,请在设备上检查日期。" + "更新" + "登录" + "使用 Google 帐户登录" + + "某个应用尝试使用的 Google Play 服务版本有误。" + "某个应用要求启用 Google Play 服务。" + "某个应用要求安装 Google Play 服务。" + "某个应用要求更新 Google Play 服务。" + "Google Play 服务出错" + "由“%1$s”发出" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-zh-rHK/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-zh-rHK/strings.xml new file mode 100644 index 0000000000..abe6cf1457 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-zh-rHK/strings.xml @@ -0,0 +1,31 @@ + + + "取得 Google Play 服務" + "您的手機未安裝 Google Play 服務,安裝後才能執行這個應用程式。" + "您的平板電腦未安裝 Google Play 服務,安裝後才能執行這個應用程式。" + "取得 Google Play 服務" + "啟用 Google Play 服務" + "您必須啟用 Google Play 服務,才能執行這個應用程式。" + "啟用 Google Play 服務" + "更新 Google Play 服務" + "您必須更新 Google Play 服務,才能執行這個應用程式。" + "網絡錯誤" + "要連接 Google Play 服務,必需數據連線。" + "無效的帳戶" + "這個裝置上沒有您指定的帳戶,請選擇其他帳戶。" + "Google Play 服務出現不明問題。" + "Google Play 服務" + "您的裝置不支援部分應用程式所需的 Google Play 服務。如需協助,請與您的裝置製造商聯絡。" + "裝置上的日期看來不正確,請檢查裝置上的日期。" + "更新" + "登入" + "登入 Google" + + "應用程式嘗試使用錯誤版本的「Google Play 服務」。" + "必須啟用「Google Play 服務」,才能使用應用程式。" + "必須安裝「Google Play 服務」,才能使用應用程式。" + "必須更新「Google Play 服務」,才能使用應用程式。" + "Google Play 服務錯誤" + "「%1$s」提出要求" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-zh-rTW/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-zh-rTW/strings.xml new file mode 100644 index 0000000000..a66018ab52 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-zh-rTW/strings.xml @@ -0,0 +1,31 @@ + + + "取得 Google Play 服務" + "您的手機並未安裝 Google Play 服務,所以無法執行這個應用程式。" + "您的平板電腦並未安裝 Google Play 服務,所以無法執行這個應用程式。" + "取得 Google Play 服務" + "啟用 Google Play 服務" + "您必須啟用 Google Play 服務,這個應用程式才能運作。" + "啟用 Google Play 服務" + "更新 Google Play 服務" + "您必須更新 Google Play 服務,才能執行這個應用程式。" + "網路錯誤" + "需要數據連線才能連上 Google Play 服務。" + "無效的帳戶" + "這個裝置上沒有您所指定的帳戶,請選擇其他帳戶。" + "Google Play 服務發生不明問題。" + "Google Play 服務" + "您的裝置不支援部分應用程式所需的 Google Play 服務。如需協助,請與您的裝置製造商聯絡。" + "裝置上的日期似乎不正確,請檢查裝置上的日期。" + "更新" + "登入" + "使用 Google 帳戶登入" + + "應用程式嘗試使用的 Google Play 服務版本有誤。" + "應用程式需要啟用 Google Play 服務。" + "應用程式需要安裝 Google Play 服務。" + "應用程式需要更新 Google Play 服務。" + "Google Play 服務錯誤" + "提出要求的應用程式:%1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values-zu/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values-zu/strings.xml new file mode 100644 index 0000000000..572d9a52c4 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values-zu/strings.xml @@ -0,0 +1,31 @@ + + + "Thola amasevisi e-Google Play" + "Lolu hlelo lokusebenza ngeke lusebenze ngaphandle kwamasevisi e-Google Play, angekho efonini yakho." + "Lolu hlelo lokusebenza ngeke lusebenze ngaphandle kwamasevisi e-Google Play, angekho kuthebulethi yakho." + "Thola amasevisi e-Google Play" + "Nika amandla amasevisi e-Google Play" + "Lolu hlelo lokusebenza ngeke lusebenze ngaphandle nje kokuthi unike amandla amasevisi e-Google Play." + "Nika amandla amasevisi e-Google Play" + "Buyekeza amasevisi e-Google Play" + "Lolu hlelo lokusebenza ngeke lusebenze ngaphandle nje kokuthi ubuyekeze amasevisi e-Google Play." + "Iphutha lenethiwekhi" + "Kudingeka ukuxhumeka kwedatha ukuze kuxhunyekwe kumasevisi we-Google Play." + "I-Akhawunti engavumelekile" + "I-Akhawunti ecacisiwe ayikho kule divayisi. Sicela ukhethe i-akhawunti ehlukile." + "Indaba engaziwa yamasevisi we-Google Play" + "Amasevisi we-Google Play" + "Amasevisi we-Google Play, okungukuthi ezinye izinhlelo zakho zithembele kuwo, awasekelwe yidivayisi yakho. Sicela uxhumane nomkhiqizi ukuze uthole usizo." + "Idethi kudivayisi ibonakala ingalungile. Sicela uhlole idethi kudivayisi." + "Isibuyekezo" + "Ngena ngemvume" + "Ngena ngemvume nge-Google" + + "Uhlelo lokusebenza luzame ukusebenzisa inguqulo embi yamasevisi we-Google Play." + "Uhlelo lokusebenza ludinga amasevisi we-Google Play ukuze anikwe amandla." + "Uhlelo lokusebenza ludinga ukufakwa kwamasevisi we-Google Play." + "Uhlelo lokusebenza ludinga isibuyekezo samasevisi we-Google Play." + "Iphutha lamasevisi we-Google Play" + "Kucelwe yi-%1$s" + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values/ads_attrs.xml b/pkg/android/phoenix64/libs/googleplay/res/values/ads_attrs.xml new file mode 100644 index 0000000000..519a84272b --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values/ads_attrs.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values/colors.xml b/pkg/android/phoenix64/libs/googleplay/res/values/colors.xml new file mode 100644 index 0000000000..6b2740a509 --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values/colors.xml @@ -0,0 +1,14 @@ + + + + @android:color/white + @android:color/white + #FFAAAAAA + @android:color/white + #FF737373 + @android:color/white + #FFAAAAAA + #FF737373 + #FFDD4B39 + #d2d2d2 + \ No newline at end of file diff --git a/pkg/android/phoenix64/libs/googleplay/res/values/maps_attrs.xml b/pkg/android/phoenix64/libs/googleplay/res/values/maps_attrs.xml new file mode 100644 index 0000000000..aaf65c529e --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values/maps_attrs.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values/strings.xml b/pkg/android/phoenix64/libs/googleplay/res/values/strings.xml new file mode 100644 index 0000000000..24bd58b11d --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values/strings.xml @@ -0,0 +1,111 @@ + + + + + Get Google Play services + + + This app won\'t run without Google Play services, which are missing from your phone. + + + This app won\'t run without Google Play services, which are missing from your tablet. + + + Get Google Play services + + + Enable Google Play services + + + This app won\'t work unless you enable Google Play services. + + + Enable Google Play services + + + Update Google Play services + + + This app won\'t run unless you update Google Play services. + + + Network Error + + + A data connection is required to connect to Google Play services. + + + Invalid Account + + + The specified account does not exist on this device. Please choose a different account. + + + Unknown issue with Google Play services. + + + Google Play services + + + Google Play services, which some of your applications rely on, is not supported by your device. Please contact the manufacturer for assistance. + + + The date on the device appears to be incorrect. Please check the date on the device. + + + Update + + + Sign in + + + Sign in with Google + + + + + + An application attempted to use a bad version of Google Play Services. + + + + An application requires Google Play Services to be enabled. + + + + An application requires installation of Google Play Services. + + + + An application requires an update for Google Play Services. + + + + Google Play services error + + + Requested by %1$s + + + + + + + + diff --git a/pkg/android/phoenix64/libs/googleplay/res/values/version.xml b/pkg/android/phoenix64/libs/googleplay/res/values/version.xml new file mode 100644 index 0000000000..890d9119aa --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/res/values/version.xml @@ -0,0 +1,4 @@ + + + 4030500 + diff --git a/pkg/android/phoenix64/libs/googleplay/src/android/.readme b/pkg/android/phoenix64/libs/googleplay/src/android/.readme new file mode 100644 index 0000000000..4bcebad80c --- /dev/null +++ b/pkg/android/phoenix64/libs/googleplay/src/android/.readme @@ -0,0 +1,2 @@ +This hidden file is there to ensure there is an src folder. +Once we support binary library this will go away. \ No newline at end of file diff --git a/pkg/android/phoenix64/msvc-2017-android.NativeActivity.vcxproj b/pkg/android/phoenix64/msvc-2017-android.NativeActivity.vcxproj new file mode 100644 index 0000000000..bc86a3ea31 --- /dev/null +++ b/pkg/android/phoenix64/msvc-2017-android.NativeActivity.vcxproj @@ -0,0 +1,273 @@ + + + + + Debug + ARM + + + Release + ARM + + + Debug + ARM64 + + + Release + ARM64 + + + Debug + x64 + + + Release + x64 + + + Debug + x86 + + + Release + x86 + + + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + c++11 + c++11 + c++11 + c++11 + c++11 + c++11 + c++11 + c++11 + + + c++11 + c++11 + c++11 + c++11 + c++11 + c++11 + c++11 + c++11 + + + + {e27d73ec-6148-4817-b75c-adaa0c563939} + Android + retroarch-activity + en-US + 14.0 + Android + 3.0 + retroarch-activity.NativeActivity + + + + DynamicLibrary + true + Clang_3_8 + c++_static + android-24 + + + DynamicLibrary + false + Clang_3_8 + c++_static + android-24 + + + DynamicLibrary + true + Clang_3_8 + c++_static + android-24 + + + DynamicLibrary + false + Clang_3_8 + c++_static + android-24 + + + DynamicLibrary + true + Clang_3_8 + c++_static + android-24 + + + DynamicLibrary + false + Clang_3_8 + c++_static + android-24 + + + DynamicLibrary + true + Clang_3_8 + c++_static + android-24 + + + DynamicLibrary + false + Clang_3_8 + c++_static + android-24 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + CompileAsCpp + $(SolutionDir)\..\..\..\libretro-common\include;$(SolutionDir)\..\..\..\deps;$(SolutionDir)\..\..\..\deps\libFLAC\include;$(SolutionDir)\..\..\..\deps\stb;$(SolutionDir)\..\..\..\deps\7zip;$(SolutionDir)\..\..\..\gfx\include;$(SolutionDir)\..\..\..\deps\glslang;$(SolutionDir)\..\..\..\deps\glslang\glslang\Public;$(SolutionDir)\..\..\..\deps\glslang\glslang\MachineIndependent;$(SolutionDir)\..\..\..\deps\glslang\glslang\SPIRV;$(SolutionDir)\..\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + HAVE_OPENGLES2;RARCH_MOBILE;HAVE_GRIFFIN;HAVE_STB_VORBIS;HAVE_LANGEXTRA;ANDROID;HAVE_DYNAMIC;HAVE_OPENGL;HAVE_OVERLAY;HAVE_OPENGLES;HAVE_DYLIB;HAVE_EGL;HAVE_GLSL;HAVE_MENU;HAVE_RGUI;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;INLINE=inline;HAVE_THREADS;__LIBRETRO__;HAVE_RSOUND;HAVE_NETWORKGAMEPAD;HAVE_NETWORKING;RARCH_INTERNAL;HAVE_FILTERS_BUILTIN;HAVE_MATERIALUI;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_IMAGEVIEWER;HAVE_UPDATE_ASSETS;HAVE_CC_RESAMPLER;HAVE_MINIUPNPC;HAVE_BUILTINMINIUPNPC;MINIUPNPC_SET_SOCKET_TIMEOUT;MINIUPNPC_GET_SRC_ADDR;HAVE_KEYMAPPER;HAVE_FLAC;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_CHD;HAVE_RUNAHEAD;ENABLE_HLSL;WANT_IFADDRS;HAVE_7ZIP;HAVE_CHEEVOS;HAVE_SL;FLAC_PACKAGE_VERSION="\"retroarch\"";HAVE_LROUND;FLAC__HAS_OGG=0;DONT_WANT_ARM_OPTIMIZATIONS;__STDC_LIMIT_MACROS;%(PreprocessorDefinitions) + Enabled + + + %(LibraryDependencies);GLESv2;EGL;dl;z;m;OpenSLES + + + + + NotUsing + CompileAsCpp + $(SolutionDir)\..\..\..\libretro-common\include;$(SolutionDir)\..\..\..\deps;$(SolutionDir)\..\..\..\deps\libFLAC\include;$(SolutionDir)\..\..\..\deps\stb;$(SolutionDir)\..\..\..\deps\7zip;$(SolutionDir)\..\..\..\gfx\include;$(SolutionDir)\..\..\..\deps\glslang;$(SolutionDir)\..\..\..\deps\glslang\glslang\Public;$(SolutionDir)\..\..\..\deps\glslang\glslang\MachineIndependent;$(SolutionDir)\..\..\..\deps\glslang\glslang\SPIRV;$(SolutionDir)\..\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + HAVE_OPENGLES2;RARCH_MOBILE;HAVE_GRIFFIN;HAVE_STB_VORBIS;HAVE_LANGEXTRA;ANDROID;HAVE_DYNAMIC;HAVE_OPENGL;HAVE_OVERLAY;HAVE_OPENGLES;HAVE_DYLIB;HAVE_EGL;HAVE_GLSL;HAVE_MENU;HAVE_RGUI;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;INLINE=inline;HAVE_THREADS;__LIBRETRO__;HAVE_RSOUND;HAVE_NETWORKGAMEPAD;HAVE_NETWORKING;RARCH_INTERNAL;HAVE_FILTERS_BUILTIN;HAVE_MATERIALUI;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_IMAGEVIEWER;HAVE_UPDATE_ASSETS;HAVE_CC_RESAMPLER;HAVE_MINIUPNPC;HAVE_BUILTINMINIUPNPC;MINIUPNPC_SET_SOCKET_TIMEOUT;MINIUPNPC_GET_SRC_ADDR;HAVE_KEYMAPPER;HAVE_FLAC;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_CHD;HAVE_RUNAHEAD;ENABLE_HLSL;WANT_IFADDRS;HAVE_7ZIP;HAVE_CHEEVOS;HAVE_SL;FLAC_PACKAGE_VERSION="\"retroarch\"";HAVE_LROUND;FLAC__HAS_OGG=0;DONT_WANT_ARM_OPTIMIZATIONS;__STDC_LIMIT_MACROS;%(PreprocessorDefinitions) + Enabled + + + %(LibraryDependencies);GLESv2;EGL;dl;z;m;OpenSLES + + + + + NotUsing + CompileAsCpp + $(SolutionDir)\..\..\..\libretro-common\include;$(SolutionDir)\..\..\..\deps;$(SolutionDir)\..\..\..\deps\libFLAC\include;$(SolutionDir)\..\..\..\deps\stb;$(SolutionDir)\..\..\..\deps\7zip;$(SolutionDir)\..\..\..\gfx\include;$(SolutionDir)\..\..\..\deps\glslang;$(SolutionDir)\..\..\..\deps\glslang\glslang\Public;$(SolutionDir)\..\..\..\deps\glslang\glslang\MachineIndependent;$(SolutionDir)\..\..\..\deps\glslang\glslang\SPIRV;$(SolutionDir)\..\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + HAVE_OPENGLES2;RARCH_MOBILE;HAVE_GRIFFIN;HAVE_STB_VORBIS;HAVE_LANGEXTRA;ANDROID;HAVE_DYNAMIC;HAVE_OPENGL;HAVE_OVERLAY;HAVE_OPENGLES;HAVE_DYLIB;HAVE_EGL;HAVE_GLSL;HAVE_MENU;HAVE_RGUI;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;INLINE=inline;HAVE_THREADS;__LIBRETRO__;HAVE_RSOUND;HAVE_NETWORKGAMEPAD;HAVE_NETWORKING;RARCH_INTERNAL;HAVE_FILTERS_BUILTIN;HAVE_MATERIALUI;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_IMAGEVIEWER;HAVE_UPDATE_ASSETS;HAVE_CC_RESAMPLER;HAVE_MINIUPNPC;HAVE_BUILTINMINIUPNPC;MINIUPNPC_SET_SOCKET_TIMEOUT;MINIUPNPC_GET_SRC_ADDR;HAVE_KEYMAPPER;HAVE_FLAC;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_CHD;HAVE_RUNAHEAD;ENABLE_HLSL;WANT_IFADDRS;HAVE_7ZIP;HAVE_CHEEVOS;HAVE_SL;FLAC_PACKAGE_VERSION="\"retroarch\"";HAVE_LROUND;FLAC__HAS_OGG=0;DONT_WANT_ARM_OPTIMIZATIONS;__STDC_LIMIT_MACROS;%(PreprocessorDefinitions) + Enabled + + + %(LibraryDependencies);GLESv2;EGL;dl;z;m;OpenSLES + + + + + NotUsing + CompileAsCpp + $(SolutionDir)\..\..\..\libretro-common\include;$(SolutionDir)\..\..\..\deps;$(SolutionDir)\..\..\..\deps\libFLAC\include;$(SolutionDir)\..\..\..\deps\stb;$(SolutionDir)\..\..\..\deps\7zip;$(SolutionDir)\..\..\..\gfx\include;$(SolutionDir)\..\..\..\deps\glslang;$(SolutionDir)\..\..\..\deps\glslang\glslang\Public;$(SolutionDir)\..\..\..\deps\glslang\glslang\MachineIndependent;$(SolutionDir)\..\..\..\deps\glslang\glslang\SPIRV;$(SolutionDir)\..\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + HAVE_OPENGLES2;RARCH_MOBILE;HAVE_GRIFFIN;HAVE_STB_VORBIS;HAVE_LANGEXTRA;ANDROID;HAVE_DYNAMIC;HAVE_OPENGL;HAVE_OVERLAY;HAVE_OPENGLES;HAVE_DYLIB;HAVE_EGL;HAVE_GLSL;HAVE_MENU;HAVE_RGUI;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;INLINE=inline;HAVE_THREADS;__LIBRETRO__;HAVE_RSOUND;HAVE_NETWORKGAMEPAD;HAVE_NETWORKING;RARCH_INTERNAL;HAVE_FILTERS_BUILTIN;HAVE_MATERIALUI;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_IMAGEVIEWER;HAVE_UPDATE_ASSETS;HAVE_CC_RESAMPLER;HAVE_MINIUPNPC;HAVE_BUILTINMINIUPNPC;MINIUPNPC_SET_SOCKET_TIMEOUT;MINIUPNPC_GET_SRC_ADDR;HAVE_KEYMAPPER;HAVE_FLAC;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_CHD;HAVE_RUNAHEAD;ENABLE_HLSL;WANT_IFADDRS;HAVE_7ZIP;HAVE_CHEEVOS;HAVE_SL;FLAC_PACKAGE_VERSION="\"retroarch\"";HAVE_LROUND;FLAC__HAS_OGG=0;DONT_WANT_ARM_OPTIMIZATIONS;__STDC_LIMIT_MACROS;%(PreprocessorDefinitions) + Enabled + + + %(LibraryDependencies);GLESv2;EGL;dl;z;m;OpenSLES + + + + + NotUsing + CompileAsCpp + $(SolutionDir)\..\..\..\libretro-common\include;$(SolutionDir)\..\..\..\deps;$(SolutionDir)\..\..\..\deps\libFLAC\include;$(SolutionDir)\..\..\..\deps\stb;$(SolutionDir)\..\..\..\deps\7zip;$(SolutionDir)\..\..\..\gfx\include;$(SolutionDir)\..\..\..\deps\glslang;$(SolutionDir)\..\..\..\deps\glslang\glslang\Public;$(SolutionDir)\..\..\..\deps\glslang\glslang\MachineIndependent;$(SolutionDir)\..\..\..\deps\glslang\glslang\SPIRV;$(SolutionDir)\..\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + HAVE_OPENGLES2;RARCH_MOBILE;HAVE_GRIFFIN;HAVE_STB_VORBIS;HAVE_LANGEXTRA;ANDROID;HAVE_DYNAMIC;HAVE_OPENGL;HAVE_OVERLAY;HAVE_OPENGLES;HAVE_DYLIB;HAVE_EGL;HAVE_GLSL;HAVE_MENU;HAVE_RGUI;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;INLINE=inline;HAVE_THREADS;__LIBRETRO__;HAVE_RSOUND;HAVE_NETWORKGAMEPAD;HAVE_NETWORKING;RARCH_INTERNAL;HAVE_FILTERS_BUILTIN;HAVE_MATERIALUI;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_IMAGEVIEWER;HAVE_UPDATE_ASSETS;HAVE_CC_RESAMPLER;HAVE_MINIUPNPC;HAVE_BUILTINMINIUPNPC;MINIUPNPC_SET_SOCKET_TIMEOUT;MINIUPNPC_GET_SRC_ADDR;HAVE_KEYMAPPER;HAVE_FLAC;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_CHD;HAVE_RUNAHEAD;ENABLE_HLSL;WANT_IFADDRS;HAVE_7ZIP;HAVE_CHEEVOS;HAVE_SL;FLAC_PACKAGE_VERSION="\"retroarch\"";HAVE_LROUND;FLAC__HAS_OGG=0;DONT_WANT_ARM_OPTIMIZATIONS;__STDC_LIMIT_MACROS;%(PreprocessorDefinitions) + Enabled + + + %(LibraryDependencies);GLESv2;EGL;dl;z;m;OpenSLES + + + + + NotUsing + CompileAsCpp + $(SolutionDir)\..\..\..\libretro-common\include;$(SolutionDir)\..\..\..\deps;$(SolutionDir)\..\..\..\deps\libFLAC\include;$(SolutionDir)\..\..\..\deps\stb;$(SolutionDir)\..\..\..\deps\7zip;$(SolutionDir)\..\..\..\gfx\include;$(SolutionDir)\..\..\..\deps\glslang;$(SolutionDir)\..\..\..\deps\glslang\glslang\Public;$(SolutionDir)\..\..\..\deps\glslang\glslang\MachineIndependent;$(SolutionDir)\..\..\..\deps\glslang\glslang\SPIRV;$(SolutionDir)\..\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + HAVE_OPENGLES2;RARCH_MOBILE;HAVE_GRIFFIN;HAVE_STB_VORBIS;HAVE_LANGEXTRA;ANDROID;HAVE_DYNAMIC;HAVE_OPENGL;HAVE_OVERLAY;HAVE_OPENGLES;HAVE_DYLIB;HAVE_EGL;HAVE_GLSL;HAVE_MENU;HAVE_RGUI;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;INLINE=inline;HAVE_THREADS;__LIBRETRO__;HAVE_RSOUND;HAVE_NETWORKGAMEPAD;HAVE_NETWORKING;RARCH_INTERNAL;HAVE_FILTERS_BUILTIN;HAVE_MATERIALUI;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_IMAGEVIEWER;HAVE_UPDATE_ASSETS;HAVE_CC_RESAMPLER;HAVE_MINIUPNPC;HAVE_BUILTINMINIUPNPC;MINIUPNPC_SET_SOCKET_TIMEOUT;MINIUPNPC_GET_SRC_ADDR;HAVE_KEYMAPPER;HAVE_FLAC;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_CHD;HAVE_RUNAHEAD;ENABLE_HLSL;WANT_IFADDRS;HAVE_7ZIP;HAVE_CHEEVOS;HAVE_SL;FLAC_PACKAGE_VERSION="\"retroarch\"";HAVE_LROUND;FLAC__HAS_OGG=0;DONT_WANT_ARM_OPTIMIZATIONS;__STDC_LIMIT_MACROS;%(PreprocessorDefinitions) + Enabled + + + %(LibraryDependencies);GLESv2;EGL;dl;z;m;OpenSLES + + + + + NotUsing + CompileAsCpp + $(SolutionDir)\..\..\..\libretro-common\include;$(SolutionDir)\..\..\..\deps;$(SolutionDir)\..\..\..\deps\libFLAC\include;$(SolutionDir)\..\..\..\deps\stb;$(SolutionDir)\..\..\..\deps\7zip;$(SolutionDir)\..\..\..\gfx\include;$(SolutionDir)\..\..\..\deps\glslang;$(SolutionDir)\..\..\..\deps\glslang\glslang\Public;$(SolutionDir)\..\..\..\deps\glslang\glslang\MachineIndependent;$(SolutionDir)\..\..\..\deps\glslang\glslang\SPIRV;$(SolutionDir)\..\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + HAVE_OPENGLES2;RARCH_MOBILE;HAVE_GRIFFIN;HAVE_STB_VORBIS;HAVE_LANGEXTRA;ANDROID;HAVE_DYNAMIC;HAVE_OPENGL;HAVE_OVERLAY;HAVE_OPENGLES;HAVE_DYLIB;HAVE_EGL;HAVE_GLSL;HAVE_MENU;HAVE_RGUI;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;INLINE=inline;HAVE_THREADS;__LIBRETRO__;HAVE_RSOUND;HAVE_NETWORKGAMEPAD;HAVE_NETWORKING;RARCH_INTERNAL;HAVE_FILTERS_BUILTIN;HAVE_MATERIALUI;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_IMAGEVIEWER;HAVE_UPDATE_ASSETS;HAVE_CC_RESAMPLER;HAVE_MINIUPNPC;HAVE_BUILTINMINIUPNPC;MINIUPNPC_SET_SOCKET_TIMEOUT;MINIUPNPC_GET_SRC_ADDR;HAVE_KEYMAPPER;HAVE_FLAC;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_CHD;HAVE_RUNAHEAD;ENABLE_HLSL;WANT_IFADDRS;HAVE_7ZIP;HAVE_CHEEVOS;HAVE_SL;FLAC_PACKAGE_VERSION="\"retroarch\"";HAVE_LROUND;FLAC__HAS_OGG=0;DONT_WANT_ARM_OPTIMIZATIONS;__STDC_LIMIT_MACROS;%(PreprocessorDefinitions) + Enabled + + + %(LibraryDependencies);GLESv2;EGL;dl;z;m;OpenSLES + + + + + NotUsing + CompileAsCpp + $(SolutionDir)\..\..\..\libretro-common\include;$(SolutionDir)\..\..\..\deps;$(SolutionDir)\..\..\..\deps\libFLAC\include;$(SolutionDir)\..\..\..\deps\stb;$(SolutionDir)\..\..\..\deps\7zip;$(SolutionDir)\..\..\..\gfx\include;$(SolutionDir)\..\..\..\deps\glslang;$(SolutionDir)\..\..\..\deps\glslang\glslang\Public;$(SolutionDir)\..\..\..\deps\glslang\glslang\MachineIndependent;$(SolutionDir)\..\..\..\deps\glslang\glslang\SPIRV;$(SolutionDir)\..\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + HAVE_OPENGLES2;RARCH_MOBILE;HAVE_GRIFFIN;HAVE_STB_VORBIS;HAVE_LANGEXTRA;ANDROID;HAVE_DYNAMIC;HAVE_OPENGL;HAVE_OVERLAY;HAVE_OPENGLES;HAVE_DYLIB;HAVE_EGL;HAVE_GLSL;HAVE_MENU;HAVE_RGUI;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;INLINE=inline;HAVE_THREADS;__LIBRETRO__;HAVE_RSOUND;HAVE_NETWORKGAMEPAD;HAVE_NETWORKING;RARCH_INTERNAL;HAVE_FILTERS_BUILTIN;HAVE_MATERIALUI;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_IMAGEVIEWER;HAVE_UPDATE_ASSETS;HAVE_CC_RESAMPLER;HAVE_MINIUPNPC;HAVE_BUILTINMINIUPNPC;MINIUPNPC_SET_SOCKET_TIMEOUT;MINIUPNPC_GET_SRC_ADDR;HAVE_KEYMAPPER;HAVE_FLAC;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_CHD;HAVE_RUNAHEAD;ENABLE_HLSL;WANT_IFADDRS;HAVE_7ZIP;HAVE_CHEEVOS;HAVE_SL;FLAC_PACKAGE_VERSION="\"retroarch\"";HAVE_LROUND;FLAC__HAS_OGG=0;DONT_WANT_ARM_OPTIMIZATIONS;__STDC_LIMIT_MACROS;%(PreprocessorDefinitions) + Enabled + + + %(LibraryDependencies);GLESv2;EGL;dl;z;m;OpenSLES + + + + + + diff --git a/pkg/android/phoenix64/msvc-2017-android.NativeActivity.vcxproj.filters b/pkg/android/phoenix64/msvc-2017-android.NativeActivity.vcxproj.filters new file mode 100644 index 0000000000..3ae9a90039 --- /dev/null +++ b/pkg/android/phoenix64/msvc-2017-android.NativeActivity.vcxproj.filters @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/pkg/android/phoenix64/msvc-2017-android.Packaging.androidproj b/pkg/android/phoenix64/msvc-2017-android.Packaging.androidproj new file mode 100644 index 0000000000..e61050d3de --- /dev/null +++ b/pkg/android/phoenix64/msvc-2017-android.Packaging.androidproj @@ -0,0 +1,154 @@ + + + + + Debug + ARM + + + Release + ARM + + + Debug + ARM64 + + + Release + ARM64 + + + Debug + x64 + + + Release + x64 + + + Debug + x86 + + + Release + x86 + + + + retroarch-activity + 14.0 + 1.0 + {94b52983-76de-4545-a708-433c377727c7} + + + + true + Application + + + false + Application + + + true + Application + + + false + Application + + + true + Application + + + false + Application + + + true + Application + + + false + Application + + + + + + + + + $(RootNamespace) + + + + + $(RootNamespace) + + + + + $(RootNamespace) + + + + + $(RootNamespace) + + + + + $(RootNamespace) + + + + + $(RootNamespace) + + + + + $(RootNamespace) + + + + + $(RootNamespace) + + + + + + + + + {e27d73ec-6148-4817-b75c-adaa0c563939} + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pkg/android/phoenix64/msvc-2017-android.sln b/pkg/android/phoenix64/msvc-2017-android.sln new file mode 100644 index 0000000000..45919ce71c --- /dev/null +++ b/pkg/android/phoenix64/msvc-2017-android.sln @@ -0,0 +1,72 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.9 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "msvc-2017-android", "msvc-2017-android", "{82FC602D-4083-4ED5-858B-A066A4280E4C}" +EndProject +Project("{39E2626F-3545-4960-A6E8-258AD8476CE5}") = "msvc-2017-android.Packaging", "msvc-2017-android.Packaging.androidproj", "{94B52983-76DE-4545-A708-433C377727C7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msvc-2017-android.NativeActivity", "msvc-2017-android.NativeActivity.vcxproj", "{E27D73EC-6148-4817-B75C-ADAA0C563939}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {94B52983-76DE-4545-A708-433C377727C7}.Debug|ARM.ActiveCfg = Debug|ARM + {94B52983-76DE-4545-A708-433C377727C7}.Debug|ARM.Build.0 = Debug|ARM + {94B52983-76DE-4545-A708-433C377727C7}.Debug|ARM.Deploy.0 = Debug|ARM + {94B52983-76DE-4545-A708-433C377727C7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {94B52983-76DE-4545-A708-433C377727C7}.Debug|ARM64.Build.0 = Debug|ARM64 + {94B52983-76DE-4545-A708-433C377727C7}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {94B52983-76DE-4545-A708-433C377727C7}.Debug|x64.ActiveCfg = Debug|x64 + {94B52983-76DE-4545-A708-433C377727C7}.Debug|x64.Build.0 = Debug|x64 + {94B52983-76DE-4545-A708-433C377727C7}.Debug|x64.Deploy.0 = Debug|x64 + {94B52983-76DE-4545-A708-433C377727C7}.Debug|x86.ActiveCfg = Debug|x86 + {94B52983-76DE-4545-A708-433C377727C7}.Debug|x86.Build.0 = Debug|x86 + {94B52983-76DE-4545-A708-433C377727C7}.Debug|x86.Deploy.0 = Debug|x86 + {94B52983-76DE-4545-A708-433C377727C7}.Release|ARM.ActiveCfg = Release|ARM + {94B52983-76DE-4545-A708-433C377727C7}.Release|ARM.Build.0 = Release|ARM + {94B52983-76DE-4545-A708-433C377727C7}.Release|ARM.Deploy.0 = Release|ARM + {94B52983-76DE-4545-A708-433C377727C7}.Release|ARM64.ActiveCfg = Release|ARM64 + {94B52983-76DE-4545-A708-433C377727C7}.Release|ARM64.Build.0 = Release|ARM64 + {94B52983-76DE-4545-A708-433C377727C7}.Release|ARM64.Deploy.0 = Release|ARM64 + {94B52983-76DE-4545-A708-433C377727C7}.Release|x64.ActiveCfg = Release|x64 + {94B52983-76DE-4545-A708-433C377727C7}.Release|x64.Build.0 = Release|x64 + {94B52983-76DE-4545-A708-433C377727C7}.Release|x64.Deploy.0 = Release|x64 + {94B52983-76DE-4545-A708-433C377727C7}.Release|x86.ActiveCfg = Release|x86 + {94B52983-76DE-4545-A708-433C377727C7}.Release|x86.Build.0 = Release|x86 + {94B52983-76DE-4545-A708-433C377727C7}.Release|x86.Deploy.0 = Release|x86 + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Debug|ARM.ActiveCfg = Debug|ARM + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Debug|ARM.Build.0 = Debug|ARM + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Debug|ARM64.Build.0 = Debug|ARM64 + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Debug|x64.ActiveCfg = Debug|x64 + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Debug|x64.Build.0 = Debug|x64 + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Debug|x86.ActiveCfg = Debug|x86 + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Debug|x86.Build.0 = Debug|x86 + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Release|ARM.ActiveCfg = Release|ARM + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Release|ARM.Build.0 = Release|ARM + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Release|ARM64.ActiveCfg = Release|ARM64 + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Release|ARM64.Build.0 = Release|ARM64 + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Release|x64.ActiveCfg = Release|x64 + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Release|x64.Build.0 = Release|x64 + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Release|x86.ActiveCfg = Release|x86 + {E27D73EC-6148-4817-B75C-ADAA0C563939}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {94B52983-76DE-4545-A708-433C377727C7} = {82FC602D-4083-4ED5-858B-A066A4280E4C} + {E27D73EC-6148-4817-B75C-ADAA0C563939} = {82FC602D-4083-4ED5-858B-A066A4280E4C} + EndGlobalSection +EndGlobal diff --git a/pkg/android/phoenix64/proguard-project.txt b/pkg/android/phoenix64/proguard-project.txt new file mode 100644 index 0000000000..f2fe1559a2 --- /dev/null +++ b/pkg/android/phoenix64/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/pkg/android/phoenix64/project.properties b/pkg/android/phoenix64/project.properties new file mode 100644 index 0000000000..93ee842b0e --- /dev/null +++ b/pkg/android/phoenix64/project.properties @@ -0,0 +1,15 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-24 +android.library.reference.1=libs/googleplay diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-hdpi/ic_launcher.png b/pkg/android/phoenix64/res/drawable-hdpi/ic_launcher.png similarity index 100% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-hdpi/ic_launcher.png rename to pkg/android/phoenix64/res/drawable-hdpi/ic_launcher.png diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-ldpi/ic_launcher.png b/pkg/android/phoenix64/res/drawable-ldpi/ic_launcher.png similarity index 100% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-ldpi/ic_launcher.png rename to pkg/android/phoenix64/res/drawable-ldpi/ic_launcher.png diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-mdpi/ic_launcher.png b/pkg/android/phoenix64/res/drawable-mdpi/ic_launcher.png similarity index 100% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-mdpi/ic_launcher.png rename to pkg/android/phoenix64/res/drawable-mdpi/ic_launcher.png diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-xhdpi/banner.png b/pkg/android/phoenix64/res/drawable-xhdpi/banner.png similarity index 100% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-xhdpi/banner.png rename to pkg/android/phoenix64/res/drawable-xhdpi/banner.png diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-xhdpi/ic_launcher.png b/pkg/android/phoenix64/res/drawable-xhdpi/ic_launcher.png similarity index 100% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-xhdpi/ic_launcher.png rename to pkg/android/phoenix64/res/drawable-xhdpi/ic_launcher.png diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-xhdpi/ouya_icon.png b/pkg/android/phoenix64/res/drawable-xhdpi/ouya_icon.png similarity index 100% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-xhdpi/ouya_icon.png rename to pkg/android/phoenix64/res/drawable-xhdpi/ouya_icon.png diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-xxhdpi/ic_launcher.png b/pkg/android/phoenix64/res/drawable-xxhdpi/ic_launcher.png similarity index 100% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-xxhdpi/ic_launcher.png rename to pkg/android/phoenix64/res/drawable-xxhdpi/ic_launcher.png diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-xxxhdpi/ic_launcher.png b/pkg/android/phoenix64/res/drawable-xxxhdpi/ic_launcher.png similarity index 100% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable-xxxhdpi/ic_launcher.png rename to pkg/android/phoenix64/res/drawable-xxxhdpi/ic_launcher.png diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable/banner.png b/pkg/android/phoenix64/res/drawable/banner.png similarity index 100% rename from pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/res/drawable/banner.png rename to pkg/android/phoenix64/res/drawable/banner.png diff --git a/pkg/android/phoenix64/version_increment.py b/pkg/android/phoenix64/version_increment.py new file mode 100644 index 0000000000..fbd58ff906 --- /dev/null +++ b/pkg/android/phoenix64/version_increment.py @@ -0,0 +1,20 @@ +#!/usr/bin/python +import time + + +from xml.dom.minidom import parse +dom1 = parse("AndroidManifest.xml") +oldVersion = dom1.documentElement.getAttribute("android:versionCode") +versionNumbers = oldVersion.split('.') + +versionName = dom1.documentElement.getAttribute("android:versionName") +versionName = versionName + "_GIT" + +versionNumbers[-1] = unicode(int(time.time())) +dom1.documentElement.setAttribute("android:versionCode", u'.'.join(versionNumbers)) +dom1.documentElement.setAttribute("android:versionName", versionName) + +with open("AndroidManifest.xml", 'wb') as f: + for line in dom1.toxml("utf-8"): + f.write(line) + diff --git a/pkg/apple/OSX/Info.plist b/pkg/apple/OSX/Info.plist index aeee252500..a28050a571 100644 --- a/pkg/apple/OSX/Info.plist +++ b/pkg/apple/OSX/Info.plist @@ -30,11 +30,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.7.3 + 1.7.4 CFBundleSignature ???? CFBundleVersion - 1.7.2 + 1.7.4 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSHighResolutionCapable diff --git a/pkg/apple/RetroArch_iOS9-Info.plist b/pkg/apple/RetroArch_iOS9-Info.plist index 42f8a9f2f8..ffc3cefb41 100644 --- a/pkg/apple/RetroArch_iOS9-Info.plist +++ b/pkg/apple/RetroArch_iOS9-Info.plist @@ -37,7 +37,7 @@ CFBundleSignature ???? CFBundleVersion - 1.7.2 + 1.7.4 LSRequiresIPhoneOS UIApplicationExitsOnSuspend diff --git a/pkg/apple/iOS/Info.plist b/pkg/apple/iOS/Info.plist index 8afa2ae3ad..02f641bde5 100644 --- a/pkg/apple/iOS/Info.plist +++ b/pkg/apple/iOS/Info.plist @@ -33,11 +33,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.7.2 + 1.7.4 CFBundleSignature ???? CFBundleVersion - 1.7.2 + 1.7.4 LSRequiresIPhoneOS LSSupportsOpeningDocumentsInPlace diff --git a/pkg/ctr/Makefile.cores b/pkg/ctr/Makefile.cores index 8fabdb8bd7..391fe18045 100644 --- a/pkg/ctr/Makefile.cores +++ b/pkg/ctr/Makefile.cores @@ -139,6 +139,14 @@ else ifeq ($(LIBRETRO), mame2003) APP_BANNER = pkg/ctr/assets/mame2003_banner.png APP_BIG_TEXT_SECTION = 1 +else ifeq ($(LIBRETRO), mame2003_plus) + APP_TITLE = MAME-2003-PLUS + APP_PRODUCT_CODE = RARCH-MAME2003-PLUS + APP_UNIQUE_ID = 0xBAC22 + APP_ICON = pkg/ctr/assets/mame2003_plus.png + APP_BANNER = pkg/ctr/assets/mame2003_plus_banner.png + APP_BIG_TEXT_SECTION = 1 + else ifeq ($(LIBRETRO), mednafen_pce_fast) APP_TITLE = Mednafen/Beetle PCE FAST APP_AUTHOR = Ryphecha diff --git a/pkg/ctr/assets/mame2003_plus.png b/pkg/ctr/assets/mame2003_plus.png new file mode 100644 index 0000000000..86509ec999 Binary files /dev/null and b/pkg/ctr/assets/mame2003_plus.png differ diff --git a/pkg/ctr/assets/mame2003_plus_banner.png b/pkg/ctr/assets/mame2003_plus_banner.png new file mode 100644 index 0000000000..6b73ffe5fd Binary files /dev/null and b/pkg/ctr/assets/mame2003_plus_banner.png differ diff --git a/pkg/msvc/RetroArch-msvc2012.sln b/pkg/msvc/RetroArch-msvc2012.sln new file mode 100644 index 0000000000..39a084d720 --- /dev/null +++ b/pkg/msvc/RetroArch-msvc2012.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msvc-2012", "msvc-2012\RetroArch-msvc2012.vcxproj", "{E1D4BAA1-50DB-428E-9462-4F1B31E38119}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E1D4BAA1-50DB-428E-9462-4F1B31E38119}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1D4BAA1-50DB-428E-9462-4F1B31E38119}.Debug|Win32.Build.0 = Debug|Win32 + {E1D4BAA1-50DB-428E-9462-4F1B31E38119}.Release|Win32.ActiveCfg = Release|Win32 + {E1D4BAA1-50DB-428E-9462-4F1B31E38119}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/pkg/msvc/msvc-2008/RetroArch-msvc2008.vcproj b/pkg/msvc/msvc-2008/RetroArch-msvc2008.vcproj index ced820b582..c456b38284 100644 --- a/pkg/msvc/msvc-2008/RetroArch-msvc2008.vcproj +++ b/pkg/msvc/msvc-2008/RetroArch-msvc2008.vcproj @@ -41,8 +41,8 @@ + + + + Debug + Win32 + + + Release + Win32 + + + + {E1D4BAA1-50DB-428E-9462-4F1B31E38119} + Win32Proj + msvc2012 + RetroArch-msvc2012 + + + + Application + true + v110 + Unicode + + + Application + false + v110 + true + Unicode + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_MENU;HAVE_UPDATE_ASSETS;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_RGUI;HAVE_MATERIALUI;NDEBUG;_WINDOWS;HAVE_XAUDIO;HAVE_DSOUND;HAVE_DINPUT;HAVE_D3D;HAVE_D3D9;HAVE_OPENGL;HAVE_GLSL;HAVE_THREADS;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_RJPEG;HAVE_RPNG;HAVE_ZLIB;WANT_ZLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_OVERLAY;HAVE_7ZIP;HAVE_LIBRETRODB;HAVE_STB_FONT;_DEBUG;%(PreprocessorDefinitions) + $(SolutionDir)\..\..\deps;$(SolutionDir)\..\..\gfx\include;$(SolutionDir)\..\..\gfx\include\dxsdk;$(SolutionDir)\..\..\libretro-common\include;$(SolutionDir)\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + + + Windows + true + mainCRTStartup + Iphlpapi.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_MENU;HAVE_UPDATE_ASSETS;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_RGUI;HAVE_MATERIALUI;NDEBUG;_WINDOWS;HAVE_XAUDIO;HAVE_DSOUND;HAVE_DINPUT;HAVE_D3D;HAVE_D3D9;HAVE_OPENGL;HAVE_GLSL;HAVE_THREADS;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_RJPEG;HAVE_RPNG;HAVE_ZLIB;WANT_ZLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_OVERLAY;HAVE_7ZIP;HAVE_LIBRETRODB;HAVE_STB_FONT;%(PreprocessorDefinitions) + $(SolutionDir)\..\..\deps;$(SolutionDir)\..\..\gfx\include;$(SolutionDir)\..\..\gfx\include\dxsdk;$(SolutionDir)\..\..\libretro-common\include;$(SolutionDir)\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + mainCRTStartup + Iphlpapi.lib;%(AdditionalDependencies) + + + + + CompileAsC + CompileAsC + + + + + + + + \ No newline at end of file diff --git a/pkg/msvc/msvc-2012/RetroArch-msvc2012.vcxproj.filters b/pkg/msvc/msvc-2012/RetroArch-msvc2012.vcxproj.filters new file mode 100644 index 0000000000..0d9661f43a --- /dev/null +++ b/pkg/msvc/msvc-2012/RetroArch-msvc2012.vcxproj.filters @@ -0,0 +1,28 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/mainmenu/MainMenuActivity.java b/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/mainmenu/MainMenuActivity.java deleted file mode 100644 index 88d25d6ee8..0000000000 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/mainmenu/MainMenuActivity.java +++ /dev/null @@ -1,200 +0,0 @@ -package com.retroarch.browser.mainmenu; - -import com.retroarch.browser.preferences.util.UserPreferences; -import com.retroarch.browser.retroactivity.RetroActivityFuture; -import com.retroarch.browser.retroactivity.RetroActivityPast; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo; -import android.media.AudioManager; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.preference.PreferenceActivity; -import android.preference.PreferenceManager; -import android.provider.Settings; - -import java.util.List; -import java.util.ArrayList; -import android.content.pm.PackageManager; -import android.Manifest; -import android.content.DialogInterface; -import android.app.AlertDialog; -import android.util.Log; - -/** - * {@link PreferenceActivity} subclass that provides all of the - * functionality of the main menu screen. - */ -public final class MainMenuActivity extends PreferenceActivity -{ - final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124; - boolean checkPermissions = false; - - public void showMessageOKCancel(String message, DialogInterface.OnClickListener onClickListener) - { - new AlertDialog.Builder(this).setMessage(message) - .setPositiveButton("OK", onClickListener).setCancelable(false) - .setNegativeButton("Cancel", null).create().show(); - } - - private boolean addPermission(List permissionsList, String permission) - { - if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) - { - permissionsList.add(permission); - - // Check for Rationale Option - if (!shouldShowRequestPermissionRationale(permission)) - return false; - } - - return true; - } - - public void checkRuntimePermissions() - { - if (android.os.Build.VERSION.SDK_INT >= 23) - { - // Android 6.0+ needs runtime permission checks - List permissionsNeeded = new ArrayList(); - final List permissionsList = new ArrayList(); - - if (!addPermission(permissionsList, Manifest.permission.READ_EXTERNAL_STORAGE)) - permissionsNeeded.add("Read External Storage"); - if (!addPermission(permissionsList, Manifest.permission.WRITE_EXTERNAL_STORAGE)) - permissionsNeeded.add("Write External Storage"); - - if (permissionsList.size() > 0) - { - checkPermissions = true; - - if (permissionsNeeded.size() > 0) - { - // Need Rationale - Log.i("MainMenuActivity", "Need to request external storage permissions."); - - String message = "You need to grant access to " + permissionsNeeded.get(0); - - for (int i = 1; i < permissionsNeeded.size(); i++) - message = message + ", " + permissionsNeeded.get(i); - - showMessageOKCancel(message, - new DialogInterface.OnClickListener() - { - @Override - public void onClick(DialogInterface dialog, int which) - { - if (which == AlertDialog.BUTTON_POSITIVE) - { - requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), - REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); - - Log.i("MainMenuActivity", "User accepted request for external storage permissions."); - } - } - }); - } - else - { - requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), - REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); - - Log.i("MainMenuActivity", "Requested external storage permissions."); - } - } - } - - if (!checkPermissions) - { - finalStartup(); - } - } - - public void finalStartup() - { - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - Intent retro; - - if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)) - { - retro = new Intent(this, RetroActivityFuture.class); - } - else - { - retro = new Intent(this, RetroActivityPast.class); - } - - retro.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - - startRetroActivity( - retro, - null, - prefs.getString("libretro_path", getApplicationInfo().dataDir + "/cores/"), - UserPreferences.getDefaultConfigPath(this), - Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD), - getApplicationInfo().dataDir, - getApplicationInfo().sourceDir); - startActivity(retro); - finish(); - } - - @Override - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) - { - switch (requestCode) - { - case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: - for (int i = 0; i < permissions.length; i++) - { - if(grantResults[i] == PackageManager.PERMISSION_GRANTED) - { - Log.i("MainMenuActivity", "Permission: " + permissions[i] + " was granted."); - } - else - { - Log.i("MainMenuActivity", "Permission: " + permissions[i] + " was not granted."); - } - } - - break; - default: - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - break; - } - - finalStartup(); - } - - public static void startRetroActivity(Intent retro, String contentPath, String corePath, - String configFilePath, String imePath, String dataDirPath, String dataSourcePath) - { - if (contentPath != null) { - retro.putExtra("ROM", contentPath); - } - retro.putExtra("LIBRETRO", corePath); - retro.putExtra("CONFIGFILE", configFilePath); - retro.putExtra("IME", imePath); - retro.putExtra("DATADIR", dataDirPath); - retro.putExtra("APK", dataSourcePath); - retro.putExtra("SDCARD", Environment.getExternalStorageDirectory().getAbsolutePath()); - retro.putExtra("DOWNLOADS", Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()); - retro.putExtra("SCREENSHOTS", Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()); - String external = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/com.retroarch/files"; - retro.putExtra("EXTERNAL", external); - } - - @Override - public void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - - // Bind audio stream to hardware controls. - setVolumeControlStream(AudioManager.STREAM_MUSIC); - - UserPreferences.updateConfigFile(this); - - checkRuntimePermissions(); - } -} diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/preferences/util/ConfigFile.java b/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/preferences/util/ConfigFile.java deleted file mode 100644 index eccaf730cb..0000000000 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/preferences/util/ConfigFile.java +++ /dev/null @@ -1,281 +0,0 @@ -package com.retroarch.browser.preferences.util; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; - -import android.util.Log; - -/** - * Represents a configuration file that works off of a key-value pair - * in the form [key name] = "[value]". - */ -public final class ConfigFile -{ - // Map containing all of the key-value pairs. - private final HashMap map = new HashMap(); - - /** - * Constructor - */ - public ConfigFile() - { - } - - /** - * Constructor - * - * @param filePath The path to the configuration file to open. - */ - public ConfigFile(String filePath) - { - if (filePath == null) - throw new IllegalArgumentException("filePath cannot be null."); - - try - { - open(filePath); - } - catch (IOException ioe) - { - Log.e("ConfigFile", "Stream reading the configuration file was suddenly closed for an unknown reason."); - } - } - - /** - * Parses a configuration file from the given stream - * and appends the parsed values to the key-value map. - * - * @param stream The {@link InputStream} containing the configuration file to parse. - */ - public void append(InputStream stream) throws IOException - { - BufferedReader br = new BufferedReader(new InputStreamReader(stream)); - - String line; - while ((line = br.readLine()) != null) - parseLine(line); - - br.close(); - } - - /** - * Opens a configuration file given by configPath - * and parses all of its key-value pairs, adding - * them to the key-value map. - * - * @param configPath Path to the configuration file to parse. - */ - public void open(String configPath) throws IOException - { - clear(); - append(new FileInputStream(configPath)); - } - - private void parseLine(String line) - { - String[] tokens = line.split("=", 2); - if (tokens.length < 2) - return; - - for (int i = 0; i < tokens.length; i++) - tokens[i] = tokens[i].trim(); - - String key = tokens[0]; - String value = tokens[1]; - - if (value.startsWith("\"")) - value = value.substring(1, value.lastIndexOf('\"')); - else - value = value.split(" ")[0]; - - if (value.length() > 0) - map.put(key, value); - } - - /** - * Clears the key-value map of all currently set keys and values. - */ - public void clear() - { - map.clear(); - } - - /** - * Writes the currently set key-value pairs to - * - * @param path The path to save the - * - * @throws IOException - */ - public void write(String path) throws IOException - { - PrintWriter writer = new PrintWriter(path); - - for (Map.Entry entry : map.entrySet()) - { - writer.println(entry.getKey() + " = \"" + entry.getValue() + "\""); - } - - writer.close(); - } - - /** - * Checks if a key exists in the {@link HashMap} - * backing this ConfigFile instance. - * - * @param key The key to check for. - * - * @return true if the key exists in the HashMap backing - * this ConfigFile; false if it doesn't. - */ - public boolean keyExists(String key) - { - return map.containsKey(key); - } - - /** - * Sets a key to the given String value. - * - * @param key The key to set the String value to. - * @param value The String value to set to the key. - */ - public void setString(String key, String value) - { - map.put(key, value); - } - - /** - * Sets a key to the given boolean value. - * - * @param key The key to set the boolean value to. - * @param value The boolean value to set to the key. - */ - public void setBoolean(String key, boolean value) - { - map.put(key, Boolean.toString(value)); - } - - /** - * Sets a key to the given Integer value. - * - * @param key The key to set the Integer value to. - * @param value The Integer value to set to the key. - */ - public void setInt(String key, int value) - { - map.put(key, Integer.toString(value)); - } - - /** - * Sets a key to the given double value. - * - * @param key The key to set the double value to. - * @param value The double value to set to the key. - */ - public void setDouble(String key, double value) - { - map.put(key, Double.toString(value)); - } - - /** - * Sets a key to the given float value. - * - * @param key The key to set the float value to. - * @param value The float value to set to the key. - */ - public void setFloat(String key, float value) - { - map.put(key, Float.toString(value)); - } - - /** - * Gets the String value associated with the given key. - * - * @param key The key to get the String value from. - * - * @return the String object associated with the given key. - */ - public String getString(String key) - { - String ret = map.get(key); - - if (ret != null) - return ret; - else - return null; - } - - /** - * Gets the Integer value associated with the given key. - * - * @param key The key to get the Integer value from. - * - * @return the Integer value associated with the given key. - */ - public int getInt(String key) - { - String str = getString(key); - - if (str != null) - return Integer.parseInt(str); - else - throw new IllegalArgumentException("Config key '" + key + "' is invalid."); - } - - /** - * Gets the double value associated with the given key. - * - * @param key The key to get the double value from. - * - * @return the double value associated with the given key. - */ - public double getDouble(String key) - { - String str = getString(key); - - if (str != null) - return Double.parseDouble(str); - else - throw new IllegalArgumentException("Config key '" + key + "' is invalid."); - } - - /** - * Gets the float value associated with the given key. - * - * @param key The key to get the float value from. - * - * @return the float value associated with the given key. - */ - public float getFloat(String key) - { - String str = getString(key); - - if (str != null) - return Float.parseFloat(str); - else - throw new IllegalArgumentException("Config key '" + key + "' is invalid."); - } - - /** - * Gets the boolean value associated with the given key. - * - * @param key The key to get the boolean value from. - * - * @return the boolean value associated with the given key. - */ - public boolean getBoolean(String key) - { - String str = getString(key); - - if (str != null) - return Boolean.parseBoolean(str); - else - throw new IllegalArgumentException("Config key '" + key + "' is invalid."); - } -} diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/preferences/util/UserPreferences.java b/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/preferences/util/UserPreferences.java deleted file mode 100644 index 2e1ec9ed61..0000000000 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/preferences/util/UserPreferences.java +++ /dev/null @@ -1,300 +0,0 @@ -package com.retroarch.browser.preferences.util; - -import java.io.File; -import java.io.IOException; - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.SharedPreferences; -import android.media.AudioManager; -import android.media.AudioTrack; -import android.os.Build; -import android.preference.PreferenceManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.util.Log; - -/** - * Utility class for retrieving, saving, or loading preferences. - */ -public final class UserPreferences -{ - // Logging tag. - private static final String TAG = "UserPreferences"; - - // Disallow explicit instantiation. - private UserPreferences() - { - } - - /** - * Retrieves the path to the default location of the libretro config. - * - * @param ctx the current {@link Context} - * - * @return the path to the default location of the libretro config. - */ - public static String getDefaultConfigPath(Context ctx) - { - // Internal/External storage dirs. - final String internal = ctx.getFilesDir().getAbsolutePath(); - String external = null; - - // Get the App's external storage folder - final String state = android.os.Environment.getExternalStorageState(); - if (android.os.Environment.MEDIA_MOUNTED.equals(state)) { - File extsd = ctx.getExternalFilesDir(null); - external = extsd.getAbsolutePath(); - } - - // Native library directory and data directory for this front-end. - final String dataDir = ctx.getApplicationInfo().dataDir; - final String coreDir = dataDir + "/cores/"; - - // Get libretro name and path - final SharedPreferences prefs = getPreferences(ctx); - final String libretro_path = prefs.getString("libretro_path", coreDir); - - // Check if global config is being used. Return true upon failure. - final boolean globalConfigEnabled = prefs.getBoolean("global_config_enable", true); - - String append_path; - // If we aren't using the global config. - if (!globalConfigEnabled && !libretro_path.equals(coreDir)) - { - String sanitized_name = sanitizeLibretroPath(libretro_path); - append_path = File.separator + sanitized_name + ".cfg"; - } - else // Using global config. - { - append_path = File.separator + "retroarch.cfg"; - } - - if (external != null) - { - String confPath = external + append_path; - if (new File(confPath).exists()) - return confPath; - } - else if (internal != null) - { - String confPath = internal + append_path; - if (new File(confPath).exists()) - return confPath; - } - else - { - String confPath = "/mnt/extsd" + append_path; - if (new File(confPath).exists()) - return confPath; - } - - // Config file does not exist. Create empty one. - - // emergency fallback - String new_path = "/mnt/sd" + append_path; - - if (external != null) - new_path = external + append_path; - else if (internal != null) - new_path = internal + append_path; - else if (dataDir != null) - new_path = dataDir + append_path; - - try { - new File(new_path).createNewFile(); - } - catch (IOException e) - { - Log.e(TAG, "Failed to create config file to: " + new_path); - } - return new_path; - } - - /** - * Updates the libretro configuration file - * with new values if settings have changed. - * - * @param ctx the current {@link Context}. - */ - public static void updateConfigFile(Context ctx) - { - String path = getDefaultConfigPath(ctx); - ConfigFile config = new ConfigFile(path); - - Log.i(TAG, "Writing config to: " + path); - - final String dataDir = ctx.getApplicationInfo().dataDir; - final String coreDir = dataDir + "/cores/"; - - final SharedPreferences prefs = getPreferences(ctx); - - config.setString("libretro_directory", coreDir); - config.setInt("audio_out_rate", getOptimalSamplingRate(ctx)); - - try - { - int version = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0).versionCode; - final String dst_path = dataDir; - final String dst_path_subdir = "assets"; - - Log.i(TAG, "dst dir is: " + dst_path); - Log.i(TAG, "dst subdir is: " + dst_path_subdir); - - config.setBoolean("log_verbosity", true); - config.setString("bundle_assets_src_path", ctx.getApplicationInfo().sourceDir); - config.setString("bundle_assets_dst_path", dst_path); - config.setString("bundle_assets_dst_path_subdir", dst_path_subdir); - config.setInt("bundle_assets_extract_version_current", version); - } - catch (NameNotFoundException ignored) - { - } - - // Refactor this entire mess and make this usable for per-core config - if (Build.VERSION.SDK_INT >= 17 && prefs.getBoolean("audio_latency_auto", true)) - { - config.setInt("audio_block_frames", getLowLatencyBufferSize(ctx)); - } - - try - { - config.write(path); - } - catch (IOException e) - { - Log.e(TAG, "Failed to save config file to: " + path); - } - } - - private static void readbackString(ConfigFile cfg, SharedPreferences.Editor edit, String key) - { - if (cfg.keyExists(key)) - edit.putString(key, cfg.getString(key)); - else - edit.remove(key); - } - - private static void readbackBool(ConfigFile cfg, SharedPreferences.Editor edit, String key) - { - if (cfg.keyExists(key)) - edit.putBoolean(key, cfg.getBoolean(key)); - else - edit.remove(key); - } - - private static void readbackDouble(ConfigFile cfg, SharedPreferences.Editor edit, String key) - { - if (cfg.keyExists(key)) - edit.putFloat(key, (float)cfg.getDouble(key)); - else - edit.remove(key); - } - - /* - private static void readbackFloat(ConfigFile cfg, SharedPreferences.Editor edit, String key) - { - if (cfg.keyExists(key)) - edit.putFloat(key, cfg.getFloat(key)); - else - edit.remove(key); - } - */ - - /** - private static void readbackInt(ConfigFile cfg, SharedPreferences.Editor edit, String key) - { - if (cfg.keyExists(key)) - edit.putInt(key, cfg.getInt(key)); - else - edit.remove(key); - } - */ - - /** - * Sanitizes a libretro core path. - * - * @param path The path to the libretro core. - * - * @return the sanitized libretro path. - */ - private static String sanitizeLibretroPath(String path) - { - String sanitized_name = path.substring( - path.lastIndexOf('/') + 1, - path.lastIndexOf('.')); - sanitized_name = sanitized_name.replace("neon", ""); - sanitized_name = sanitized_name.replace("libretro_", ""); - - return sanitized_name; - } - - /** - * Gets a {@link SharedPreferences} instance containing current settings. - * - * @param ctx the current {@link Context}. - * - * @return A SharedPreference instance containing current settings. - */ - public static SharedPreferences getPreferences(Context ctx) - { - return PreferenceManager.getDefaultSharedPreferences(ctx); - } - - /** - * Gets the optimal sampling rate for low-latency audio playback. - * - * @param ctx the current {@link Context}. - * - * @return the optimal sampling rate for low-latency audio playback in Hz. - */ - @TargetApi(17) - private static int getLowLatencyOptimalSamplingRate(Context ctx) - { - AudioManager manager = (AudioManager) ctx.getSystemService(Context.AUDIO_SERVICE); - - return Integer.parseInt(manager - .getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)); - } - - /** - * Gets the optimal buffer size for low-latency audio playback. - * - * @param ctx the current {@link Context}. - * - * @return the optimal output buffer size in decimal PCM frames. - */ - @TargetApi(17) - private static int getLowLatencyBufferSize(Context ctx) - { - AudioManager manager = (AudioManager) ctx.getSystemService(Context.AUDIO_SERVICE); - int buffersize = Integer.parseInt(manager - .getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER)); - Log.i(TAG, "Queried ideal buffer size (frames): " + buffersize); - return buffersize; - } - - /** - * Gets the optimal audio sampling rate. - *

- * On Android 4.2+ devices this will retrieve the optimal low-latency sampling rate, - * since Android 4.2 adds support for low latency audio in general. - *

- * On other devices, it simply returns the regular optimal sampling rate - * as returned by the hardware. - * - * @param ctx The current {@link Context}. - * - * @return the optimal audio sampling rate in Hz. - */ - private static int getOptimalSamplingRate(Context ctx) - { - int ret; - if (Build.VERSION.SDK_INT >= 17) - ret = getLowLatencyOptimalSamplingRate(ctx); - else - ret = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC); - - Log.i(TAG, "Using sampling rate: " + ret + " Hz"); - return ret; - } -} diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityCamera.java b/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityCamera.java deleted file mode 100644 index d51d7f768f..0000000000 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityCamera.java +++ /dev/null @@ -1,225 +0,0 @@ -package com.retroarch.browser.retroactivity; - -import java.io.IOException; - -import com.retroarch.browser.preferences.util.UserPreferences; - -import android.annotation.SuppressLint; -import android.content.SharedPreferences; -import android.graphics.SurfaceTexture; -import android.graphics.SurfaceTexture.OnFrameAvailableListener; -import android.hardware.Camera; -import android.os.Build; -import android.os.Bundle; -import android.util.Log; - -//For Android 3.0 and up - -/** - * Class which provides {@link Camera} functionality - * to {@link RetroActivityFuture}. - */ -@SuppressLint("NewApi") -public class RetroActivityCamera extends RetroActivityCommon -{ - private Camera mCamera = null; - private long lastTimestamp = 0; - private SurfaceTexture texture; - private boolean updateSurface = true; - private boolean camera_service_running = false; - - /** - * Executed when the {@link Camera} - * is staring to capture. - */ - public void onCameraStart() - { - if (camera_service_running) - return; - - if (mCamera != null) - mCamera.startPreview(); - camera_service_running = true; - } - - /** - * Executed when the {@link Camera} is done capturing. - *

- * Note that this does not release the currently held - * {@link Camera} instance and must be freed by calling - * {@link #onCameraFree} - */ - public void onCameraStop() - { - if (!camera_service_running) - return; - - if (mCamera != null) - mCamera.stopPreview(); - camera_service_running = false; - } - - /** - * Releases the currently held {@link Camera} instance. - */ - public void onCameraFree() - { - onCameraStop(); - - if (mCamera != null) - mCamera.release(); - } - - /** - * Initializes the camera for use. - */ - public void onCameraInit() - { - if (mCamera != null) - return; - - mCamera = Camera.open(); - } - - /** - * Polls the camera for updates to the {@link SurfaceTexture}. - * - * @return true if polling was successful, false otherwise. - */ - public boolean onCameraPoll() - { - if (!camera_service_running) - return false; - - if (texture == null) - { - Log.i("RetroActivity", "No texture"); - return true; - } - else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) - { - if (updateSurface) - { - texture.updateTexImage(); - } - - long newTimestamp = texture.getTimestamp(); - - if (newTimestamp != lastTimestamp) - { - lastTimestamp = newTimestamp; - return true; - } - - return false; - } - - return true; - } - - /** - * Initializes the {@link SurfaceTexture} used by the - * {@link Camera} with a given OpenGL texure ID. - * - * @param gl_texid texture ID to initialize the - * {@link SurfaceTexture} with. - */ - public void onCameraTextureInit(int gl_texid) - { - texture = new SurfaceTexture(gl_texid); - texture.setOnFrameAvailableListener(onCameraFrameAvailableListener); - } - - /** - * Sets the {@link Camera} texture with the texture represented - * by the given OpenGL texture ID. - * - * @param gl_texid The texture ID representing the texture to set the camera to. - * @throws IOException If setting the texture fails. - */ - public void onCameraSetTexture(int gl_texid) throws IOException - { - if (texture == null) - onCameraTextureInit(gl_texid); - - if (mCamera != null) - mCamera.setPreviewTexture(texture); - } - - private final OnFrameAvailableListener onCameraFrameAvailableListener = new OnFrameAvailableListener() - { - @Override - public void onFrameAvailable(SurfaceTexture surfaceTexture) - { - updateSurface = true; - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) - { - // Save the current setting for updates - SharedPreferences prefs = UserPreferences.getPreferences(this); - SharedPreferences.Editor edit = prefs.edit(); - edit.putBoolean("CAMERA_UPDATES_ON", false); - edit.apply(); - - camera_service_running = false; - - super.onCreate(savedInstanceState); - } - - @Override - public void onPause() - { - // Save the current setting for updates - SharedPreferences prefs = UserPreferences.getPreferences(this); - SharedPreferences.Editor edit = prefs.edit(); - edit.putBoolean("CAMERA_UPDATES_ON", camera_service_running); - edit.apply(); - - onCameraStop(); - super.onPause(); - } - - @Override - public void onResume() - { - SharedPreferences prefs = UserPreferences.getPreferences(this); - SharedPreferences.Editor edit = prefs.edit(); - - /* - * Get any previous setting for camera updates - * Gets "false" if an error occurs - */ - if (prefs.contains("CAMERA_UPDATES_ON")) - { - camera_service_running = prefs.getBoolean("CAMERA_UPDATES_ON", false); - if (camera_service_running) - { - onCameraStart(); - } - } - else // Otherwise, turn off camera updates - { - edit.putBoolean("CAMERA_UPDATES_ON", false); - edit.apply(); - camera_service_running = false; - } - super.onResume(); - } - - @Override - public void onDestroy() - { - onCameraFree(); - super.onDestroy(); - } - - @Override - public void onStop() - { - onCameraStop(); - super.onStop(); - } -} diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java b/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java deleted file mode 100644 index e660dd2eb9..0000000000 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.retroarch.browser.retroactivity; - -import com.retroarch.browser.preferences.util.UserPreferences; -import android.annotation.TargetApi; -import android.content.res.Configuration; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.app.UiModeManager; -import android.os.BatteryManager; -import android.os.Build; -import android.os.PowerManager; -import android.util.Log; - -import java.util.concurrent.CountDownLatch; - -/** - * Class which provides common methods for RetroActivity related classes. - */ -public class RetroActivityCommon extends RetroActivityLocation -{ - public static int FRONTEND_POWERSTATE_NONE = 0; - public static int FRONTEND_POWERSTATE_NO_SOURCE = 1; - public static int FRONTEND_POWERSTATE_CHARGING = 2; - public static int FRONTEND_POWERSTATE_CHARGED = 3; - public static int FRONTEND_POWERSTATE_ON_POWER_SOURCE = 4; - public boolean sustainedPerformanceMode = true; - - // Exiting cleanly from NDK seems to be nearly impossible. - // Have to use exit(0) to avoid weird things happening, even with runOnUiThread() approaches. - // Use a separate JNI function to explicitly trigger the readback. - public void onRetroArchExit() - { - finish(); - } - - @TargetApi(24) - public void setSustainedPerformanceMode(boolean on) - { - sustainedPerformanceMode = on; - - if (Build.VERSION.SDK_INT >= 24) { - if (isSustainedPerformanceModeSupported()) { - final CountDownLatch latch = new CountDownLatch(1); - - runOnUiThread(new Runnable() { - @Override - public void run() { - Log.i("RetroActivity", "setting sustained performance mode to " + sustainedPerformanceMode); - - getWindow().setSustainedPerformanceMode(sustainedPerformanceMode); - - latch.countDown(); - } - }); - - try { - latch.await(); - }catch(InterruptedException e) { - e.printStackTrace(); - } - } - } - } - - @TargetApi(24) - public boolean isSustainedPerformanceModeSupported() - { - boolean supported = false; - - if (Build.VERSION.SDK_INT >= 24) - { - PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE); - - if (powerManager.isSustainedPerformanceModeSupported()) - supported = true; - } - - - Log.i("RetroActivity", "isSustainedPerformanceModeSupported? " + supported); - - return supported; - } - - public int getBatteryLevel() - { - IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); - // This doesn't actually register anything (or need to) because we know this particular intent is sticky and we do not specify a BroadcastReceiver anyway - Intent batteryStatus = registerReceiver(null, ifilter); - int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); - int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, 100); - - float percent = ((float)level / (float)scale) * 100.0f; - - Log.i("RetroActivity", "battery: level = " + level + ", scale = " + scale + ", percent = " + percent); - - return (int)percent; - } - - public int getPowerstate() - { - IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); - // This doesn't actually register anything (or need to) because we know this particular intent is sticky and we do not specify a BroadcastReceiver anyway - Intent batteryStatus = registerReceiver(null, ifilter); - int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1); - boolean hasBattery = batteryStatus.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false); - boolean isCharging = (status == BatteryManager.BATTERY_STATUS_CHARGING); - boolean isCharged = (status == BatteryManager.BATTERY_STATUS_FULL); - int powerstate = FRONTEND_POWERSTATE_NONE; - - if (isCharged) - powerstate = FRONTEND_POWERSTATE_CHARGED; - else if (isCharging) - powerstate = FRONTEND_POWERSTATE_CHARGING; - else if (!hasBattery) - powerstate = FRONTEND_POWERSTATE_NO_SOURCE; - else - powerstate = FRONTEND_POWERSTATE_ON_POWER_SOURCE; - - Log.i("RetroActivity", "power state = " + powerstate); - - return powerstate; - } - - public boolean isAndroidTV() - { - Configuration config = getResources().getConfiguration(); - UiModeManager uiModeManager = (UiModeManager)getSystemService(UI_MODE_SERVICE); - - if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) - { - Log.i("RetroActivity", "isAndroidTV == true"); - return true; - } - else - { - Log.i("RetroActivity", "isAndroidTV == false"); - return false; - } - } -} diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java b/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java deleted file mode 100644 index eba29872a6..0000000000 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.retroarch.browser.retroactivity; - -import android.view.View; -import android.view.WindowManager; -import android.content.Intent; -import android.content.Context; -import android.hardware.input.InputManager; -import android.os.Build; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public final class RetroActivityFuture extends RetroActivityCamera { - - // If set to true then Retroarch will completely exit when it loses focus - private boolean quitfocus = false; - - @Override - public void onResume() { - super.onResume(); - - setSustainedPerformanceMode(sustainedPerformanceMode); - - if (Build.VERSION.SDK_INT >= 19) { - // Immersive mode - - // Constants from API > 14 - final int API_SYSTEM_UI_FLAG_LAYOUT_STABLE = 0x00000100; - final int API_SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200; - final int API_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400; - final int API_SYSTEM_UI_FLAG_FULLSCREEN = 0x00000004; - final int API_SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000; - - View thisView = getWindow().getDecorView(); - thisView.setSystemUiVisibility(API_SYSTEM_UI_FLAG_LAYOUT_STABLE - | API_SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | API_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | API_SYSTEM_UI_FLAG_FULLSCREEN - | API_SYSTEM_UI_FLAG_IMMERSIVE_STICKY); - - // Check for Android UI specific parameters - Intent retro = getIntent(); - String refresh = retro.getStringExtra("REFRESH"); - - // If REFRESH parameter is provided then try to set refreshrate accordingly - if(refresh != null) { - WindowManager.LayoutParams params = getWindow().getAttributes(); - params.preferredRefreshRate = Integer.parseInt(refresh); - getWindow().setAttributes(params); - } - - // If QUITFOCUS parameter is provided then enable that Retroarch quits when focus is lost - quitfocus = retro.hasExtra("QUITFOCUS"); - - // If HIDEMOUSE parameters is provided then hide the mourse cursor - // This requires NVIDIA Android extensions (available on NVIDIA Shield), if they are not - // available then nothing will be done - if (retro.hasExtra("HIDEMOUSE")) hideMouseCursor(); - } - } - - public void hideMouseCursor() { - - // Check for NVIDIA extensions and minimum SDK version - Method mInputManager_setCursorVisibility; - try { mInputManager_setCursorVisibility = - InputManager.class.getMethod("setCursorVisibility", boolean.class); - } - catch (NoSuchMethodException ex) { - return; // Extensions were not available so do nothing - } - - // Hide the mouse cursor - InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE); - try { mInputManager_setCursorVisibility.invoke(inputManager, false); } - catch (InvocationTargetException ite) { } - catch (IllegalAccessException iae) { } - } - - @Override - public void onStop() { - super.onStop(); - - // If QUITFOCUS parameter was set then completely exit Retroarch when focus is lost - if (quitfocus) System.exit(0); - } -} diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityIntent.java b/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityIntent.java deleted file mode 100644 index 91ccc3f8a6..0000000000 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityIntent.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.retroarch.browser.retroactivity; - -import com.retroarch.browser.mainmenu.MainMenuActivity; - -import android.content.Intent; -import android.util.Log; - -public class RetroActivityIntent extends RetroActivityCommon { - private Intent pendingIntent = null; - private static final String TAG = "RetroArch"; - - @Override - public void onBackPressed() - { - Log.i("RetroActivity", "onBackKeyPressed"); - Intent retro = new Intent(this, MainMenuActivity.class); - retro.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - startActivity(retro); - } - - @Override - public void onNewIntent(Intent intent) - { - Log.i("RetroActivity", "onNewIntent invoked."); - super.onNewIntent(intent); - setIntent(intent); - pendingIntent = intent; - } - - /** - * Gets the ROM file specified in the pending intent. - * - * @return the ROM file specified in the pending intent. - */ - public String getPendingIntentFullPath() - { - return pendingIntent.getStringExtra("ROM"); - } - - /** - * Gets the specified path to the libretro core in the pending intent. - * - * @return the specified path to the libretro core in the pending intent. - */ - public String getPendingIntentLibretroPath() - { - return pendingIntent.getStringExtra("LIBRETRO"); - } - - /** - * Gets the path specified in the pending intent to the retroarch cfg file. - * - * @return the path specified in the pending intent to the retroarch cfg file. - */ - public String getPendingIntentConfigPath() - { - return pendingIntent.getStringExtra("CONFIGFILE"); - } - - public String getPendingIntentStorageLocation() - { - return pendingIntent.getStringExtra("SDCARD"); - } - - public String getPendingIntentDownloadLocation() - { - return pendingIntent.getStringExtra("DOWNLOADS"); - } - - public String getPendingIntentScreenshotsLocation() - { - return pendingIntent.getStringExtra("SCREENSHOTS"); - } - - /** - * Gets the specified IME in the pending intent. - * - * @return the specified IME in the pending intent. - */ - public String getPendingIntentIME() - { - return pendingIntent.getStringExtra("IME"); - } - - /** - * Checks whether or not a pending intent exists. - * - * @return true if a pending intent exists, false otherwise. - */ - public boolean hasPendingIntent() - { - if (pendingIntent == null) - return false; - - return true; - } - - /** - * Clears the current pending intent. - */ - public void clearPendingIntent() - { - pendingIntent = null; - } -} diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityLocation.java b/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityLocation.java deleted file mode 100644 index 9fedbf2e7b..0000000000 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityLocation.java +++ /dev/null @@ -1,316 +0,0 @@ -package com.retroarch.browser.retroactivity; - -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks; -import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener; -import com.google.android.gms.location.LocationClient; -import com.google.android.gms.location.LocationListener; -import com.google.android.gms.location.LocationRequest; -import com.retroarch.browser.preferences.util.UserPreferences; - -import android.app.NativeActivity; -import android.content.IntentSender; -import android.content.SharedPreferences; -import android.location.Location; -import android.os.Bundle; -import android.util.Log; -import android.widget.Toast; - -/** - * Class that implements location-based functionality for - * the {@link RetroActivityFuture} and {@link RetroActivityPast} - * activities. - */ -public class RetroActivityLocation extends NativeActivity -implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener -{ - /* LOCATION VARIABLES */ - private static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 0; - private LocationClient mLocationClient = null; - private Location mCurrentLocation; - - // Define an object that holds accuracy and frequency parameters - LocationRequest mLocationRequest = null; - boolean mUpdatesRequested = false; - boolean locationChanged = false; - boolean location_service_running = false; - - /** - * Called by Location Services when the request to connect the - * client finishes successfully. At this point, you can - * request the current location or start periodic updates - */ - @Override - public void onConnected(Bundle dataBundle) - { - if (mLocationClient == null) - return; - - // Display the connection status - Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show(); - location_service_running = true; - - // If already requested, start periodic updates - if (mUpdatesRequested) - { - mLocationClient.requestLocationUpdates(mLocationRequest, this, null); - } - else - { - // Get last known location - mCurrentLocation = mLocationClient.getLastLocation(); - locationChanged = true; - } - } - - /** - * Called by Location Services if the connection to the - * location client drops because of an error. - */ - @Override - public void onDisconnected() - { - if (mLocationClient == null) - return; - - // Display the connection status - Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show(); - - // If the client is connected - if (mLocationClient.isConnected()) - { - /* - * Remove location updates for a listener. - * The current Activity is the listener, so - * the argument is "this". - */ - mLocationClient.removeLocationUpdates(this); - } - - location_service_running = false; - } - - /** - * Called by Location Services if the attempt to - * Location Services fails. - */ - @Override - public void onConnectionFailed(ConnectionResult connectionResult) - { - /* - * Google Play services can resolve some errors it detects. - * If the error has a resolution, try sending an Intent to - * start a Google Play services activity that can resolve - * error. - */ - if (connectionResult.hasResolution()) - { - try - { - // Start an Activity that tries to resolve the error - connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST); - } - catch (IntentSender.SendIntentException e) - { - // Thrown if Google Play services cancelled the original PendingIntent - e.printStackTrace(); - } - } - else - { - /* - * If no resolution is available, display a dialog to the - * user with the error. - */ - Log.e("Connection failed", "error code: " + connectionResult.getErrorCode()); - } - } - - /** - * Sets the update interval at which location-based updates - * should occur - */ - public void onLocationSetInterval(int update_interval_in_ms, int distance_interval) - { - // Use high accuracy - if (mLocationRequest == null) - return; - - mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); - - if (update_interval_in_ms == 0) - mLocationRequest.setInterval(5 * 1000); // 5 seconds - else - mLocationRequest.setInterval(update_interval_in_ms); - - // Set the fastest update interval to 1 second - mLocationRequest.setFastestInterval(1000); - } - - /** - * Initializing methods for location based functionality. - */ - public void onLocationInit() - { - /* - * Create a new location client, using the enclosing class to - * handle callbacks. - */ - if (mLocationClient == null) - mLocationClient = new LocationClient(this, this, this); - - // Start with updates turned off - mUpdatesRequested = false; - - // Create the LocationRequest object - if (mLocationRequest == null) - mLocationRequest = LocationRequest.create(); - - onLocationSetInterval(0, 0); - } - - - /** - * Executed upon starting the {@link LocationClient}. - */ - public void onLocationStart() - { - if (mLocationClient == null) - return; - - mUpdatesRequested = true; - - // Connect the client. - mLocationClient.connect(); - } - - /** - * Free up location services resources. - */ - public void onLocationFree() - { - /* TODO/FIXME */ - } - - /** - * Executed upon stopping the location client. - * Does nothing if called when the client is not started. - */ - public void onLocationStop() - { - // Disconnecting the client invalidates it. - if (mLocationClient != null && mUpdatesRequested) - mLocationClient.disconnect(); - } - - /** - * Gets the latitude at the current location in degrees. - * - * @return the latitude at the current location. - */ - public double onLocationGetLatitude() - { - return mCurrentLocation.getLatitude(); - } - - /** - * Gets the longitude at the current location in degrees. - * - * @return the longitude at the current location. - */ - public double onLocationGetLongitude() - { - return mCurrentLocation.getLongitude(); - } - - /** - * Gets the horizontal accuracy of the current location - * in meters. (NOTE: There seems to be no vertical accuracy - * for a given location with the Android location API) - * - * @return the horizontal accuracy of the current position. - */ - public double onLocationGetHorizontalAccuracy() - { - return mCurrentLocation.getAccuracy(); - } - - /** - * Tells us whether the location listener callback has - * updated the current location since the last time - * we polled. - * - * @return true if location has changed, false if location has not changed. - */ - public boolean onLocationHasChanged() - { - boolean hasChanged = locationChanged; - - // Reset flag - if (hasChanged) - locationChanged = false; - - return hasChanged; - } - - // Define the callback method that receives location updates - @Override - public void onLocationChanged(Location location) - { - if (!location_service_running) - return; - - locationChanged = true; - mCurrentLocation = location; - - // Report to the UI that the location was updated - String msg = "Updated Location: " + location.getLatitude() + ", " + location.getLongitude(); - Log.i("RetroArch GPS", msg); - //Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); - } - - @Override - public void onPause() - { - // Save the current setting for updates - SharedPreferences prefs = UserPreferences.getPreferences(this); - SharedPreferences.Editor edit = prefs.edit(); - edit.putBoolean("LOCATION_UPDATES_ON", mUpdatesRequested); - edit.apply(); - - super.onPause(); - } - - @Override - public void onResume() - { - SharedPreferences prefs = UserPreferences.getPreferences(this); - SharedPreferences.Editor edit = prefs.edit(); - - /* - * Get any previous setting for location updates - * Gets "false" if an error occurs - */ - if (prefs.contains("LOCATION_UPDATES_ON")) - { - mUpdatesRequested = prefs.getBoolean("LOCATION_UPDATES_ON", false); - if (mUpdatesRequested) - location_service_running = true; - } - else // Otherwise, turn off location updates - { - edit.putBoolean("LOCATION_UPDATES_ON", false); - edit.apply(); - location_service_running = false; - } - - super.onResume(); - } - - @Override - public void onStop() - { - onLocationStop(); - super.onStop(); - } -} diff --git a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityPast.java b/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityPast.java deleted file mode 100644 index 4c11369ee9..0000000000 --- a/pkg/msvc/msvc-2017-android/msvc-2017-android.Packaging/src/com/retroarch/browser/retroactivity/RetroActivityPast.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.retroarch.browser.retroactivity; - -// For Android 2.3.x - -public final class RetroActivityPast extends RetroActivityCommon -{ -} diff --git a/pkg/sailfishos/retroarch-sailfishos.spec b/pkg/sailfishos/retroarch-sailfishos.spec new file mode 100644 index 0000000000..6d2d5558b3 --- /dev/null +++ b/pkg/sailfishos/retroarch-sailfishos.spec @@ -0,0 +1,87 @@ +Name: retroarch +Version: 1.7.4 +Release: v1.2 +Summary: Official reference frontend for libretro + +Group: Applications/Emulators +License: GPLv3+ +URL: http://www.libretro.com/ + +BuildRequires: libxml2-devel +BuildRequires: mesa-llvmpipe-libwayland-egl-devel +BuildRequires: pulseaudio-devel +BuildRequires: OpenAL-devel +BuildRequires: libxkbcommon-devel +BuildRequires: zlib-devel +BuildRequires: freetype-devel +#BuildRequires: ffmpeg-devel +BuildRequires: SDL2-devel +BuildRequires: SDL2_image-devel +#Requires libusb 1.0.16 +#BuildRequires: libusb-devel + +%description +RetroArch is the official reference frontend for the libretro API. +Libretro is a simple but powerful development interface that allows for the +easy creation of emulators, games and multimedia applications that can plug +straight into any libretro-compatible frontend. This development interface +is open to others so that they can run these pluggable emulator and game +cores also in their own programs or devices. + +%build +# No autotools, custom configure script +%ifarch armv7hl +./configure --prefix=%{_prefix} --enable-opengles --enable-neon --enable-egl --enable-wayland +%else +./configure --prefix=%{_prefix} --enable-gles +%endif +make %{?_smp_mflags} + + +%install +make install DESTDIR=%{buildroot} +# Configuration changes +sed -i \ + 's|^# libretro_directory =.*|libretro_directory = "~/.config/retroarch/cores/"|; + s|^# libretro_info_path =.*|libretro_info_path = "~/.config/retroarch/cores/"|; + s|^# joypad_autoconfig_dir =.*|joypad_autoconfig_dir = "/etc/retroarch/joypad"|; + s|^# video_fullscreen =.*|video_fullscreen = "true"|; + s|^# menu_driver =.*|menu_driver = "glui"|; + s|^# menu_pointer_enable =.*|menu_pointer_enable = "true"|; + s|^# input_driver =.*|input_driver = "wayland"|' \ + %{buildroot}/etc/retroarch.cfg + +%ifarch armv7hl +sed -i \ + 's|^# core_updater_buildbot_url =.*|core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/linux/armhf/latest/"|;' \ + %{buildroot}/etc/retroarch.cfg +%endif + +#Disabling audio till it's fixed +sed -i \ + 's|^# audio_enable.*|audio_enable = "false"|' \ + %{buildroot}/etc/retroarch.cfg + +sed -i \ + 's|^Exec=retroarch|Exec=retroarch --menu|' \ + %{buildroot}/usr/share/applications/retroarch.desktop + + # Install icon file in the correct place + mkdir -p %{buildroot}/usr/share/icons/hicolor/86x86/apps + install -m 644 "./media/retroarch-96x96.png" "%{buildroot}/usr/share/icons/hicolor/86x86/apps/retroarch.png" + rm "%{buildroot}/usr/share/pixmaps/retroarch.svg" + rmdir "%{buildroot}/usr/share/pixmaps" + +%files +%doc README.md +%config /etc/retroarch.cfg +%{_prefix}/bin/retroarch +%{_prefix}/bin/retroarch-cg2glsl +%{_prefix}/share/applications/retroarch.desktop +%{_prefix}/share/man/man6/*.6* +%{_prefix}/share/icons/hicolor/86x86/apps/retroarch.* +%{_prefix}/share/doc/retroarch/* +%changelog + + + diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 1a1da11dde..d0d94da004 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -281,6 +281,7 @@ if [ "$HAVE_QT" != 'no' ] && [ "$MOC_PATH" != 'none' ]; then check_pkgconf QT5CONCURRENT Qt5Concurrent 5.2 check_pkgconf QT5NETWORK Qt5Network 5.2 #check_pkgconf QT5WEBENGINE Qt5WebEngine 5.4 + check_pkgconf OPENSSL openssl 1.0.0 check_val '' QT5CORE -lQt5Core QT5CORE check_val '' QT5GUI -lQt5Gui QT5GUI @@ -288,6 +289,7 @@ if [ "$HAVE_QT" != 'no' ] && [ "$MOC_PATH" != 'none' ]; then check_val '' QT5CONCURRENT -lQt5Concurrent QT5CONCURRENT check_val '' QT5NETWORK -lQt5Network QT5NETWORK #check_val '' QT5WEBENGINE -lQt5WebEngine QT5WEBENGINE + check_val '' OPENSSL -lssl OPENSSL if [ "$HAVE_QT5CORE" = "no" ] || [ "$HAVE_QT5GUI" = "no" ] || [ "$HAVE_QT5WIDGETS" = "no" ] || [ "$HAVE_QT5CONCURRENT" = "no" ] || [ "$HAVE_QT5NETWORK" = "no" ]; then die : 'Notice: Not building Qt support, required libraries were not found.' diff --git a/retroarch.c b/retroarch.c index 04ceb7c547..42c8fa24b6 100644 --- a/retroarch.c +++ b/retroarch.c @@ -165,7 +165,9 @@ enum RA_OPT_VERSION, RA_OPT_EOF_EXIT, RA_OPT_LOG_FILE, - RA_OPT_MAX_FRAMES + RA_OPT_MAX_FRAMES, + RA_OPT_MAX_FRAMES_SCREENSHOT, + RA_OPT_MAX_FRAMES_SCREENSHOT_PATH }; enum runloop_state @@ -187,86 +189,88 @@ typedef struct runloop_ctx_msg_info } runloop_ctx_msg_info_t; static jmp_buf error_sjlj_context; -static enum rarch_core_type current_core_type = CORE_TYPE_PLAIN; -static enum rarch_core_type explicit_current_core_type = CORE_TYPE_PLAIN; -static char error_string[255] = {0}; +static enum rarch_core_type current_core_type = CORE_TYPE_PLAIN; +static enum rarch_core_type explicit_current_core_type = CORE_TYPE_PLAIN; +static char error_string[255] = {0}; static char runtime_shader_preset[255] = {0}; #ifdef HAVE_THREAD_STORAGE static sthread_tls_t rarch_tls; -const void *MAGIC_POINTER = (void*)(uintptr_t)0x0DEFACED; +const void *MAGIC_POINTER = (void*)(uintptr_t)0x0DEFACED; #endif static retro_bits_t has_set_libretro_device; -static bool has_set_core = false; -static bool has_set_username = false; +static bool has_set_core = false; +static bool has_set_username = false; #ifdef HAVE_DISCORD -static bool discord_is_inited = false; +static bool discord_is_inited = false; #endif -static bool rarch_is_inited = false; -static bool rarch_error_on_init = false; -static bool rarch_block_config_read = false; -static bool rarch_force_fullscreen = false; -static bool has_set_verbosity = false; -static bool has_set_libretro = false; -static bool has_set_libretro_directory = false; -static bool has_set_save_path = false; -static bool has_set_state_path = false; -static bool has_set_netplay_mode = false; -static bool has_set_netplay_ip_address = false; -static bool has_set_netplay_ip_port = false; -static bool has_set_netplay_stateless_mode = false; -static bool has_set_netplay_check_frames = false; -static bool has_set_ups_pref = false; -static bool has_set_bps_pref = false; -static bool has_set_ips_pref = false; +static bool rarch_is_inited = false; +static bool rarch_error_on_init = false; +static bool rarch_block_config_read = false; +static bool rarch_force_fullscreen = false; +static bool has_set_verbosity = false; +static bool has_set_libretro = false; +static bool has_set_libretro_directory = false; +static bool has_set_save_path = false; +static bool has_set_state_path = false; +static bool has_set_netplay_mode = false; +static bool has_set_netplay_ip_address = false; +static bool has_set_netplay_ip_port = false; +static bool has_set_netplay_stateless_mode = false; +static bool has_set_netplay_check_frames = false; +static bool has_set_ups_pref = false; +static bool has_set_bps_pref = false; +static bool has_set_ips_pref = false; -static bool rarch_is_sram_load_disabled = false; -static bool rarch_is_sram_save_disabled = false; -static bool rarch_use_sram = false; -static bool rarch_ups_pref = false; -static bool rarch_bps_pref = false; -static bool rarch_ips_pref = false; -static bool rarch_patch_blocked = false; -static bool rarch_first_start = true; +static bool rarch_is_sram_load_disabled = false; +static bool rarch_is_sram_save_disabled = false; +static bool rarch_use_sram = false; +static bool rarch_ups_pref = false; +static bool rarch_bps_pref = false; +static bool rarch_ips_pref = false; +static bool rarch_patch_blocked = false; +static bool rarch_first_start = true; -static bool runloop_force_nonblock = false; -static bool runloop_paused = false; -static bool runloop_idle = false; -static bool runloop_exec = false; -static bool runloop_slowmotion = false; -static bool runloop_fastmotion = false; -static bool runloop_shutdown_initiated = false; -static bool runloop_core_shutdown_initiated = false; -static bool runloop_perfcnt_enable = false; -static bool runloop_overrides_active = false; -static bool runloop_remaps_core_active = false; -static bool runloop_remaps_game_active = false; -static bool runloop_remaps_content_dir_active = false; -static bool runloop_game_options_active = false; -static bool runloop_missing_bios = false; -static bool runloop_autosave = false; +static bool runloop_force_nonblock = false; +static bool runloop_paused = false; +static bool runloop_idle = false; +static bool runloop_exec = false; +static bool runloop_slowmotion = false; +static bool runloop_fastmotion = false; +static bool runloop_shutdown_initiated = false; +static bool runloop_core_shutdown_initiated = false; +static bool runloop_perfcnt_enable = false; +static bool runloop_overrides_active = false; +static bool runloop_remaps_core_active = false; +static bool runloop_remaps_game_active = false; +static bool runloop_remaps_content_dir_active = false; +static bool runloop_game_options_active = false; +static bool runloop_missing_bios = false; +static bool runloop_autosave = false; #ifdef HAVE_DYNAMIC -static bool core_set_on_cmdline = false; +static bool core_set_on_cmdline = false; #endif static rarch_system_info_t runloop_system; static struct retro_frame_time_callback runloop_frame_time; -static retro_keyboard_event_t runloop_key_event = NULL; -static retro_keyboard_event_t runloop_frontend_key_event = NULL; -static core_option_manager_t *runloop_core_options = NULL; +static retro_keyboard_event_t runloop_key_event = NULL; +static retro_keyboard_event_t runloop_frontend_key_event = NULL; +static core_option_manager_t *runloop_core_options = NULL; #ifdef HAVE_THREADS -static slock_t *_runloop_msg_queue_lock = NULL; +static slock_t *_runloop_msg_queue_lock = NULL; #endif -static msg_queue_t *runloop_msg_queue = NULL; +static msg_queue_t *runloop_msg_queue = NULL; -static unsigned runloop_pending_windowed_scale = 0; -static unsigned runloop_max_frames = 0; -static unsigned fastforward_after_frames = 0; +static unsigned runloop_pending_windowed_scale = 0; +static unsigned runloop_max_frames = 0; +static bool runloop_max_frames_screenshot = false; +static char runloop_max_frames_screenshot_path[PATH_MAX_LENGTH] = {0}; +static unsigned fastforward_after_frames = 0; -static retro_usec_t runloop_frame_time_last = 0; -static retro_time_t frame_limit_minimum_time = 0.0; -static retro_time_t frame_limit_last_time = 0.0; +static retro_usec_t runloop_frame_time_last = 0; +static retro_time_t frame_limit_minimum_time = 0.0; +static retro_time_t frame_limit_last_time = 0.0; extern bool input_driver_flushing_input; @@ -375,6 +379,7 @@ static void global_free(void) static void retroarch_print_features(void) { + frontend_driver_attach_console(); puts(""); puts("Features:"); @@ -451,7 +456,7 @@ static void retroarch_print_features(void) static void retroarch_print_version(void) { char str[255]; - + frontend_driver_attach_console(); str[0] = '\0'; fprintf(stderr, "%s: %s -- v%s", @@ -473,6 +478,7 @@ static void retroarch_print_version(void) **/ static void retroarch_print_help(const char *arg0) { + frontend_driver_attach_console(); puts("==================================================================="); retroarch_print_version(); puts("==================================================================="); @@ -591,7 +597,11 @@ static void retroarch_print_help(const char *arg0) "Not relevant for all platforms."); puts(" --max-frames=NUMBER\n" " Runs for the specified number of frames, " - "then exits.\n"); + "then exits."); + puts(" --max-frames-ss\n" + " Takes a screenshot at the end of max-frames."); + puts(" --max-frames-ss-path=FILE\n" + " Path to save the screenshot to at the end of max-frames.\n"); } #define FFMPEG_RECORD_ARG "r:" @@ -627,48 +637,50 @@ static void retroarch_parse_input_and_config(int argc, char *argv[]) const struct option opts[] = { #ifdef HAVE_DYNAMIC - { "libretro", 1, NULL, 'L' }, + { "libretro", 1, NULL, 'L' }, #endif - { "menu", 0, NULL, RA_OPT_MENU }, - { "help", 0, NULL, 'h' }, - { "save", 1, NULL, 's' }, - { "fullscreen", 0, NULL, 'f' }, - { "record", 1, NULL, 'r' }, - { "recordconfig", 1, NULL, RA_OPT_RECORDCONFIG }, - { "size", 1, NULL, RA_OPT_SIZE }, - { "verbose", 0, NULL, 'v' }, - { "config", 1, NULL, 'c' }, - { "appendconfig", 1, NULL, RA_OPT_APPENDCONFIG }, - { "nodevice", 1, NULL, 'N' }, - { "dualanalog", 1, NULL, 'A' }, - { "device", 1, NULL, 'd' }, - { "savestate", 1, NULL, 'S' }, - { "bsvplay", 1, NULL, 'P' }, - { "bsvrecord", 1, NULL, 'R' }, - { "sram-mode", 1, NULL, 'M' }, + { "menu", 0, NULL, RA_OPT_MENU }, + { "help", 0, NULL, 'h' }, + { "save", 1, NULL, 's' }, + { "fullscreen", 0, NULL, 'f' }, + { "record", 1, NULL, 'r' }, + { "recordconfig", 1, NULL, RA_OPT_RECORDCONFIG }, + { "size", 1, NULL, RA_OPT_SIZE }, + { "verbose", 0, NULL, 'v' }, + { "config", 1, NULL, 'c' }, + { "appendconfig", 1, NULL, RA_OPT_APPENDCONFIG }, + { "nodevice", 1, NULL, 'N' }, + { "dualanalog", 1, NULL, 'A' }, + { "device", 1, NULL, 'd' }, + { "savestate", 1, NULL, 'S' }, + { "bsvplay", 1, NULL, 'P' }, + { "bsvrecord", 1, NULL, 'R' }, + { "sram-mode", 1, NULL, 'M' }, #ifdef HAVE_NETWORKING - { "host", 0, NULL, 'H' }, - { "connect", 1, NULL, 'C' }, - { "stateless", 0, NULL, RA_OPT_STATELESS }, - { "check-frames", 1, NULL, RA_OPT_CHECK_FRAMES }, - { "port", 1, NULL, RA_OPT_PORT }, + { "host", 0, NULL, 'H' }, + { "connect", 1, NULL, 'C' }, + { "stateless", 0, NULL, RA_OPT_STATELESS }, + { "check-frames", 1, NULL, RA_OPT_CHECK_FRAMES }, + { "port", 1, NULL, RA_OPT_PORT }, #if defined(HAVE_NETWORK_CMD) - { "command", 1, NULL, RA_OPT_COMMAND }, + { "command", 1, NULL, RA_OPT_COMMAND }, #endif #endif - { "nick", 1, NULL, RA_OPT_NICK }, - { "ups", 1, NULL, 'U' }, - { "bps", 1, NULL, RA_OPT_BPS }, - { "ips", 1, NULL, RA_OPT_IPS }, - { "no-patch", 0, NULL, RA_OPT_NO_PATCH }, - { "detach", 0, NULL, 'D' }, - { "features", 0, NULL, RA_OPT_FEATURES }, - { "subsystem", 1, NULL, RA_OPT_SUBSYSTEM }, - { "max-frames", 1, NULL, RA_OPT_MAX_FRAMES }, - { "eof-exit", 0, NULL, RA_OPT_EOF_EXIT }, - { "version", 0, NULL, RA_OPT_VERSION }, + { "nick", 1, NULL, RA_OPT_NICK }, + { "ups", 1, NULL, 'U' }, + { "bps", 1, NULL, RA_OPT_BPS }, + { "ips", 1, NULL, RA_OPT_IPS }, + { "no-patch", 0, NULL, RA_OPT_NO_PATCH }, + { "detach", 0, NULL, 'D' }, + { "features", 0, NULL, RA_OPT_FEATURES }, + { "subsystem", 1, NULL, RA_OPT_SUBSYSTEM }, + { "max-frames", 1, NULL, RA_OPT_MAX_FRAMES }, + { "max-frames-ss", 0, NULL, RA_OPT_MAX_FRAMES_SCREENSHOT }, + { "max-frames-ss-path", 1, NULL, RA_OPT_MAX_FRAMES_SCREENSHOT_PATH }, + { "eof-exit", 0, NULL, RA_OPT_EOF_EXIT }, + { "version", 0, NULL, RA_OPT_VERSION }, #ifdef HAVE_FILE_LOGGER - { "log-file", 1, NULL, RA_OPT_LOG_FILE }, + { "log-file", 1, NULL, RA_OPT_LOG_FILE }, #endif { NULL, 0, NULL, 0 } }; @@ -1086,6 +1098,14 @@ static void retroarch_parse_input_and_config(int argc, char *argv[]) runloop_max_frames = (unsigned)strtoul(optarg, NULL, 10); break; + case RA_OPT_MAX_FRAMES_SCREENSHOT: + runloop_max_frames_screenshot = true; + break; + + case RA_OPT_MAX_FRAMES_SCREENSHOT_PATH: + strlcpy(runloop_max_frames_screenshot_path, optarg, sizeof(runloop_max_frames_screenshot_path)); + break; + case RA_OPT_SUBSYSTEM: path_set(RARCH_PATH_SUBSYSTEM, optarg); break; @@ -2594,11 +2614,7 @@ static enum runloop_state runloop_check_state( current_input, RARCH_GRAB_MOUSE_TOGGLE); if (pressed && !old_pressed) -#if HAVE_LIBUI - command_event(CMD_EVENT_LIBUI_TEST, NULL); -#else command_event(CMD_EVENT_GRAB_MOUSE_TOGGLE, NULL); -#endif old_pressed = pressed; } @@ -2633,6 +2649,32 @@ static enum runloop_state runloop_check_state( if (time_to_exit(trig_quit_key)) { + if ((runloop_max_frames != 0) && (frame_count >= runloop_max_frames)) + { + if (runloop_max_frames_screenshot) + { + const char *screenshot_path = NULL; + bool fullpath = false; + + if (string_is_empty(runloop_max_frames_screenshot_path)) + screenshot_path = path_get(RARCH_PATH_BASENAME); + else + { + fullpath = true; + screenshot_path = runloop_max_frames_screenshot_path; + } + + RARCH_LOG("Taking a screenshot before exiting...\n"); + + /* Take a screenshot before we exit. */ + if (!take_screenshot(screenshot_path, false, + video_driver_cached_frame_has_valid_framebuffer(), fullpath, false)) + { + RARCH_ERR("Could not take a screenshot before exiting.\n"); + } + } + } + if (runloop_exec) runloop_exec = false; @@ -2714,7 +2756,7 @@ static enum runloop_state runloop_check_state( } else { - if ( global->menu.prev_action == action && + if ( global->menu.prev_action == action && global->menu.noop_press_time < 200000) /* 250ms */ { global->menu.action_start_time = global->menu.prev_start_time ; @@ -3446,7 +3488,7 @@ int runloop_iterate(unsigned *sleep_ms) end: { retro_time_t to_sleep_ms; - + if (settings->bools.vrr_runloop_enable) { struct retro_system_av_info *av_info = @@ -3471,7 +3513,7 @@ int runloop_iterate(unsigned *sleep_ms) if (!settings->floats.fastforward_ratio && runloop_fastmotion) return 0; - frame_limit_minimum_time = + frame_limit_minimum_time = (retro_time_t)roundf(1000000.0f / (av_info->timing.fps * (runloop_fastmotion ? settings->floats.fastforward_ratio : 1.0f))); } diff --git a/runahead/dirty_input.c b/runahead/dirty_input.c index 965d932531..7ff4bfee37 100644 --- a/runahead/dirty_input.c +++ b/runahead/dirty_input.c @@ -80,7 +80,7 @@ static void input_state_set_last(unsigned port, unsigned device, element->state[id] = value; } -static int16_t input_state_get_last(unsigned port, +int16_t input_state_get_last(unsigned port, unsigned device, unsigned index, unsigned id) { unsigned i; diff --git a/runahead/dirty_input.h b/runahead/dirty_input.h index 12623d2b02..fc76e8b0bc 100644 --- a/runahead/dirty_input.h +++ b/runahead/dirty_input.h @@ -9,6 +9,8 @@ RETRO_BEGIN_DECLS extern bool input_is_dirty; void add_input_state_hook(void); void remove_input_state_hook(void); +int16_t input_state_get_last(unsigned port, + unsigned device, unsigned index, unsigned id); RETRO_END_DECLS diff --git a/runahead/run_ahead.c b/runahead/run_ahead.c index 77b6117c07..f5ce38b51c 100644 --- a/runahead/run_ahead.c +++ b/runahead/run_ahead.c @@ -30,6 +30,8 @@ static void unset_fast_savestate(void); static void set_hard_disable_audio(void); static void unset_hard_disable_audio(void); +static bool core_run_use_last_input(void); + static size_t runahead_save_state_size = 0; static bool runahead_save_state_size_known = false; @@ -174,13 +176,19 @@ static void runahead_clear_variables(void) runahead_last_frame_count = 0; } +static uint64_t runahead_get_frame_count() +{ + bool is_alive, is_focused = false; + uint64_t frame_count = 0; + video_driver_get_status(&frame_count, &is_alive, &is_focused); + return frame_count; +} + + static void runahead_check_for_gui(void) { /* Hack: If we were in the GUI, force a resync. */ - bool is_alive, is_focused = false; - uint64_t frame_count = 0; - - video_driver_get_status(&frame_count, &is_alive, &is_focused); + uint64_t frame_count = runahead_get_frame_count(); if (frame_count != runahead_last_frame_count + 1) runahead_force_input_dirty = true; @@ -241,7 +249,7 @@ void run_ahead(int runahead_count, bool useSecondary) if (frame_number == 0) core_run(); else - core_run_no_input_polling(); + core_run_use_last_input(); if (suspended_frame) { @@ -418,7 +426,7 @@ static bool runahead_load_state_secondary(void) static bool runahead_run_secondary(void) { - if (!secondary_core_run_no_input_polling()) + if (!secondary_core_run_use_last_input()) { runahead_secondary_core_available = false; return false; @@ -489,3 +497,32 @@ static void unset_hard_disable_audio(void) { hard_disable_audio = false; } + +static void runahead_input_poll_null(void) +{ +} + +static bool core_run_use_last_input(void) +{ + extern struct retro_callbacks retro_ctx; + extern struct retro_core_t current_core; + + retro_input_poll_t old_poll_function = retro_ctx.poll_cb; + retro_input_state_t old_input_function = retro_ctx.state_cb; + + retro_ctx.poll_cb = runahead_input_poll_null; + retro_ctx.state_cb = input_state_get_last; + + current_core.retro_set_input_poll(retro_ctx.poll_cb); + current_core.retro_set_input_state(retro_ctx.state_cb); + + current_core.retro_run(); + + retro_ctx.poll_cb = old_poll_function; + retro_ctx.state_cb = old_input_function; + + current_core.retro_set_input_poll(retro_ctx.poll_cb); + current_core.retro_set_input_state(retro_ctx.state_cb); + + return true; +} diff --git a/runahead/secondary_core.c b/runahead/secondary_core.c index 9d0d67de4b..7d50a2d9ba 100644 --- a/runahead/secondary_core.c +++ b/runahead/secondary_core.c @@ -23,6 +23,7 @@ #include "../content.h" #include "secondary_core.h" +#include "dirty_input.h" static int port_map[16]; @@ -304,11 +305,32 @@ void secondary_core_set_variable_update(void) has_variable_update = true; } -bool secondary_core_run_no_input_polling(void) +static void secondary_core_input_poll_null(void) +{ + +} + +bool secondary_core_run_use_last_input(void) { if (secondary_core_ensure_exists()) { + retro_input_poll_t old_poll_function = secondary_callbacks.poll_cb; + retro_input_state_t old_input_function = secondary_callbacks.state_cb; + + secondary_callbacks.poll_cb = secondary_core_input_poll_null; + secondary_callbacks.state_cb = input_state_get_last; + + secondary_core.retro_set_input_poll(secondary_callbacks.poll_cb); + secondary_core.retro_set_input_state(secondary_callbacks.state_cb); + secondary_core.retro_run(); + + secondary_callbacks.poll_cb = old_poll_function; + secondary_callbacks.state_cb = old_input_function; + + secondary_core.retro_set_input_poll(secondary_callbacks.poll_cb); + secondary_core.retro_set_input_state(secondary_callbacks.state_cb); + return true; } return false; diff --git a/runahead/secondary_core.h b/runahead/secondary_core.h index d4da77cdec..9a6ead0b7c 100644 --- a/runahead/secondary_core.h +++ b/runahead/secondary_core.h @@ -10,7 +10,7 @@ RETRO_BEGIN_DECLS -bool secondary_core_run_no_input_polling(void); +bool secondary_core_run_use_last_input(void); bool secondary_core_deserialize(const void *buffer, int size); bool secondary_core_ensure_exists(void); void secondary_core_destroy(void); diff --git a/tasks/task_content.c b/tasks/task_content.c index 4ca0f0ba67..18d4aee449 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -814,6 +814,11 @@ static bool content_file_init( free(info); } + else if (special == NULL) + { + *error_string = strdup(msg_hash_to_str(MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT)); + ret = false; + } return ret; } @@ -874,7 +879,6 @@ static bool task_load_content(content_ctx_info_t *content_info, if (!content_load(content_info)) { - *error_string = strdup("This core requires a content file, could not load content.\n"); return false; } @@ -1569,6 +1573,10 @@ end: free(content_ctx.name_ups); if (content_ctx.directory_system) free(content_ctx.directory_system); + if (content_ctx.directory_cache) + free(content_ctx.directory_cache); + if (content_ctx.valid_extensions) + free(content_ctx.valid_extensions); if (!ret) { @@ -1772,10 +1780,13 @@ void content_set_subsystem(unsigned idx) pending_subsystem_id = idx; - strlcpy(pending_subsystem_ident, - subsystem->ident, sizeof(pending_subsystem_ident)); + if (subsystem) + { + strlcpy(pending_subsystem_ident, + subsystem->ident, sizeof(pending_subsystem_ident)); - pending_subsystem_rom_num = subsystem->num_roms; + pending_subsystem_rom_num = subsystem->num_roms; + } RARCH_LOG("[subsystem] settings current subsytem to: %d(%s) roms: %d\n", pending_subsystem_id, pending_subsystem_ident, pending_subsystem_rom_num); diff --git a/tasks/task_save.c b/tasks/task_save.c index b7973d02c0..fb08c229b7 100644 --- a/tasks/task_save.c +++ b/tasks/task_save.c @@ -1050,7 +1050,7 @@ static void save_state_cb(void *task_data, char *path = strdup(state->path); if (state->thumbnail_enable) - take_screenshot(path, true, state->has_valid_framebuffer); + take_screenshot(path, true, state->has_valid_framebuffer, false, true); free(path); } diff --git a/tasks/task_screenshot.c b/tasks/task_screenshot.c index 42cc5d8d72..2ea95618ac 100644 --- a/tasks/task_screenshot.c +++ b/tasks/task_screenshot.c @@ -70,39 +70,17 @@ struct screenshot_task_state uint8_t *out_buffer; const void *frame; char filename[PATH_MAX_LENGTH]; - char shotname[256]; void *userbuf; struct scaler_ctx scaler; }; -/** - * task_screenshot_handler: - * @task : the task being worked on - * - * Saves a screenshot to disk. - **/ -static void task_screenshot_handler(retro_task_t *task) +static bool screenshot_dump_direct(screenshot_task_state_t *state) { + struct scaler_ctx *scaler = (struct scaler_ctx*)&state->scaler; + bool ret = false; #ifdef HAVE_RBMP enum rbmp_source_type bmp_type = RBMP_SOURCE_TYPE_DONT_CARE; -#endif - screenshot_task_state_t *state = (screenshot_task_state_t*)task->state; - struct scaler_ctx *scaler = (struct scaler_ctx*)&state->scaler; - bool ret = false; - - if (task_get_progress(task) == 100) - { - task_set_finished(task, true); - - if (state->userbuf) - free(state->userbuf); - - free(state); - return; - } - -#ifdef HAVE_RBMP - (void)bmp_type; + (void)bmp_type; #endif #if defined(HAVE_RPNG) @@ -146,6 +124,33 @@ static void task_screenshot_handler(retro_task_t *task) bmp_type); #endif + return ret; +} + +/** + * task_screenshot_handler: + * @task : the task being worked on + * + * Saves a screenshot to disk. + **/ +static void task_screenshot_handler(retro_task_t *task) +{ + screenshot_task_state_t *state = (screenshot_task_state_t*)task->state; + bool ret = false; + + if (task_get_progress(task) == 100) + { + task_set_finished(task, true); + + if (state->userbuf) + free(state->userbuf); + + free(state); + return; + } + + ret = screenshot_dump_direct(state); + #ifdef HAVE_IMAGEVIEWER if ( ret && !state->silence && @@ -178,7 +183,9 @@ static bool screenshot_dump( int pitch, bool bgr24, void *userbuf, bool savestate, bool is_idle, - bool is_paused) + bool is_paused, + bool fullpath, + bool use_thread) { char screenshot_path[PATH_MAX_LENGTH]; uint8_t *buf = NULL; @@ -187,14 +194,22 @@ static bool screenshot_dump( screenshot_task_state_t *state = (screenshot_task_state_t*) calloc(1, sizeof(*state)); const char *screenshot_dir = settings->paths.directory_screenshot; + char shotname[256]; + shotname[0] = '\0'; screenshot_path[0] = '\0'; - if (string_is_empty(screenshot_dir) || settings->bools.screenshots_in_content_dir) + /* If fullpath is true, name_base already contains a static path + filename to save the screenshot to. */ + if (fullpath) + strlcpy(state->filename, name_base, sizeof(state->filename)); + else { - fill_pathname_basedir(screenshot_path, name_base, - sizeof(screenshot_path)); - screenshot_dir = screenshot_path; + if (string_is_empty(screenshot_dir) || settings->bools.screenshots_in_content_dir) + { + fill_pathname_basedir(screenshot_path, name_base, + sizeof(screenshot_path)); + screenshot_dir = screenshot_path; + } } state->is_idle = is_idle; @@ -209,20 +224,23 @@ static bool screenshot_dump( state->history_list_enable = settings->bools.history_list_enable; state->pixel_format_type = video_driver_get_pixel_format(); - if (savestate) - snprintf(state->filename, - sizeof(state->filename), "%s.png", name_base); - else + if (!fullpath) { - if (settings->bools.auto_screenshot_filename) - fill_str_dated_filename(state->shotname, path_basename(name_base), - IMG_EXT, sizeof(state->shotname)); + if (savestate) + snprintf(state->filename, + sizeof(state->filename), "%s.png", name_base); else - snprintf(state->shotname, sizeof(state->shotname), - "%s.png", path_basename(name_base)); + { + if (settings->bools.auto_screenshot_filename) + fill_str_dated_filename(shotname, path_basename(name_base), + IMG_EXT, sizeof(shotname)); + else + snprintf(shotname, sizeof(shotname), + "%s.png", path_basename(name_base)); - fill_pathname_join(state->filename, screenshot_dir, - state->shotname, sizeof(state->filename)); + fill_pathname_join(state->filename, screenshot_dir, + shotname, sizeof(state->filename)); + } } #if defined(HAVE_RPNG) @@ -241,17 +259,22 @@ static bool screenshot_dump( task->state = state; task->handler = task_screenshot_handler; - if (!savestate) - task->title = strdup(msg_hash_to_str(MSG_TAKING_SCREENSHOT)); + if (use_thread) + { + if (!savestate) + task->title = strdup(msg_hash_to_str(MSG_TAKING_SCREENSHOT)); - task_queue_push(task); + task_queue_push(task); + } + else + return screenshot_dump_direct(state); return true; } #if !defined(VITA) static bool take_screenshot_viewport(const char *name_base, bool savestate, - bool is_idle, bool is_paused) + bool is_idle, bool is_paused, bool fullpath, bool use_thread) { struct video_viewport vp; uint8_t *buffer = NULL; @@ -280,7 +303,7 @@ static bool take_screenshot_viewport(const char *name_base, bool savestate, /* Data read from viewport is in bottom-up order, suitable for BMP. */ if (!screenshot_dump(name_base, buffer, vp.width, vp.height, - vp.width * 3, true, buffer, savestate, is_idle, is_paused)) + vp.width * 3, true, buffer, savestate, is_idle, is_paused, fullpath, use_thread)) goto error; return true; @@ -293,7 +316,7 @@ error: #endif static bool take_screenshot_raw(const char *name_base, void *userbuf, - bool savestate, bool is_idle, bool is_paused) + bool savestate, bool is_idle, bool is_paused, bool fullpath, bool use_thread) { size_t pitch; unsigned width, height; @@ -306,14 +329,14 @@ static bool take_screenshot_raw(const char *name_base, void *userbuf, */ if (!screenshot_dump(name_base, (const uint8_t*)data + (height - 1) * pitch, - width, height, (int)(-pitch), false, userbuf, savestate, is_idle, is_paused)) + width, height, (int)(-pitch), false, userbuf, savestate, is_idle, is_paused, fullpath, use_thread)) return false; return true; } static bool take_screenshot_choice(const char *name_base, bool savestate, - bool is_paused, bool is_idle, bool has_valid_framebuffer) + bool is_paused, bool is_idle, bool has_valid_framebuffer, bool fullpath, bool use_thread) { size_t old_pitch; unsigned old_width, old_height; @@ -335,14 +358,14 @@ static bool take_screenshot_choice(const char *name_base, bool savestate, if (!is_idle) video_driver_cached_frame(); #if defined(VITA) - return take_screenshot_raw(name_base, NULL, savestate, is_idle, is_paused); + return take_screenshot_raw(name_base, NULL, savestate, is_idle, is_paused, fullpath, use_thread); #else - return take_screenshot_viewport(name_base, savestate, is_idle, is_paused); + return take_screenshot_viewport(name_base, savestate, is_idle, is_paused, fullpath, use_thread); #endif } if (!has_valid_framebuffer) - return take_screenshot_raw(name_base, NULL, savestate, is_idle, is_paused); + return take_screenshot_raw(name_base, NULL, savestate, is_idle, is_paused, fullpath, use_thread); if (!video_driver_supports_read_frame_raw()) return false; @@ -359,14 +382,14 @@ static bool take_screenshot_choice(const char *name_base, bool savestate, if (frame_data) { video_driver_set_cached_frame_ptr(frame_data); - if (take_screenshot_raw(name_base, frame_data, savestate, is_idle, is_paused)) + if (take_screenshot_raw(name_base, frame_data, savestate, is_idle, is_paused, fullpath, use_thread)) ret = true; } return ret; } -bool take_screenshot(const char *name_base, bool silence, bool has_valid_framebuffer) +bool take_screenshot(const char *name_base, bool silence, bool has_valid_framebuffer, bool fullpath, bool use_thread) { bool is_paused = false; bool is_idle = false; @@ -377,7 +400,7 @@ bool take_screenshot(const char *name_base, bool silence, bool has_valid_framebu runloop_get_status(&is_paused, &is_idle, &is_slowmotion, &is_perfcnt_enable); ret = take_screenshot_choice(name_base, silence, is_paused, is_idle, - has_valid_framebuffer); + has_valid_framebuffer, fullpath, use_thread); if (is_paused && !is_idle) video_driver_cached_frame(); diff --git a/tasks/tasks_internal.h b/tasks/tasks_internal.h index fe9bd41122..a2632e4ac8 100644 --- a/tasks/tasks_internal.h +++ b/tasks/tasks_internal.h @@ -223,7 +223,7 @@ void task_file_load_handler(retro_task_t *task); bool task_audio_mixer_load_handler(retro_task_t *task); -bool take_screenshot(const char *path, bool silence, bool has_valid_framebuffer); +bool take_screenshot(const char *path, bool silence, bool has_valid_framebuffer, bool fullpath, bool use_thread); bool event_load_save_files(void); diff --git a/ui/drivers/cocoa/ui_cocoa_msg_window.m b/ui/drivers/cocoa/ui_cocoa_msg_window.m index faf6739b99..71c83393c6 100644 --- a/ui/drivers/cocoa/ui_cocoa_msg_window.m +++ b/ui/drivers/cocoa/ui_cocoa_msg_window.m @@ -80,7 +80,7 @@ static enum ui_msg_window_response ui_msg_window_cocoa_dialog(ui_msg_window_stat break; } -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 [alert beginSheetModalForWindow:(BRIDGE NSWindow *)ui_companion_driver_get_main_window() completionHandler:^(NSModalResponse returnCode) { [[NSApplication sharedApplication] stopModalWithCode:returnCode]; diff --git a/ui/drivers/qt/coreinfodialog.cpp b/ui/drivers/qt/coreinfodialog.cpp new file mode 100644 index 0000000000..8361bbcab9 --- /dev/null +++ b/ui/drivers/qt/coreinfodialog.cpp @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include "coreinfodialog.h" +#include "../ui_qt.h" + +extern "C" +{ +#include "../../../msg_hash.h" +} + +CoreInfoDialog::CoreInfoDialog(MainWindow *mainwindow, QWidget *parent) : + QDialog(parent) + ,m_formLayout(new QFormLayout()) + ,m_mainwindow(mainwindow) +{ + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION)); + + m_formLayout->setFormAlignment(Qt::AlignCenter); + m_formLayout->setLabelAlignment(Qt::AlignCenter); + + setLayout(new QVBoxLayout()); + + qobject_cast(layout())->addLayout(m_formLayout); + layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); + layout()->addWidget(buttonBox); +} + +void CoreInfoDialog::showCoreInfo() +{ + int row = 0; + int rowCount = m_formLayout->rowCount(); + int i = 0; + QVector > infoList = m_mainwindow->getCoreInfo(); + + if (rowCount > 0) + { + for (row = 0; row < rowCount; row++) + { +#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) + /* removeRow() and takeRow() was only added in 5.8! */ + m_formLayout->removeRow(0); +#else + /* something is buggy here... sometimes items appear duplicated, and other times not */ + QLayoutItem *item = m_formLayout->itemAt(0); + QWidget *w = NULL; + + if (item) + { + w = item->widget(); + + if (w) + { + QWidget *label = m_formLayout->labelForField(w); + + if (label) + delete label; + + m_formLayout->removeWidget(w); + + delete w; + } + } +#endif + } + } + + if (infoList.count() == 0) + return; + + for (i = 0; i < infoList.count(); i++) + { + const QHash &line = infoList.at(i); + QLabel *label = new QLabel(line.value("key")); + CoreInfoLabel *value = new CoreInfoLabel(line.value("value")); + QString labelStyle = line.value("label_style"); + QString valueStyle = line.value("value_style"); + + if (!labelStyle.isEmpty()) + label->setStyleSheet(labelStyle); + + if (!valueStyle.isEmpty()) + value->setStyleSheet(valueStyle); + + m_formLayout->addRow(label, value); + } + + show(); +} + diff --git a/ui/drivers/qt/coreinfodialog.h b/ui/drivers/qt/coreinfodialog.h new file mode 100644 index 0000000000..c0cb3f9f30 --- /dev/null +++ b/ui/drivers/qt/coreinfodialog.h @@ -0,0 +1,21 @@ +#ifndef COREINFODIALOG_H +#define COREINFODIALOG_H + +#include + +class QFormLayout; +class MainWindow; + +class CoreInfoDialog : public QDialog +{ + Q_OBJECT +public: + CoreInfoDialog(MainWindow *mainwindow, QWidget *parent = 0); +public slots: + void showCoreInfo(); +private: + QFormLayout *m_formLayout; + MainWindow *m_mainwindow; +}; + +#endif diff --git a/ui/drivers/qt/coreoptionsdialog.cpp b/ui/drivers/qt/coreoptionsdialog.cpp new file mode 100644 index 0000000000..088b3e7aef --- /dev/null +++ b/ui/drivers/qt/coreoptionsdialog.cpp @@ -0,0 +1,308 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coreoptionsdialog.h" +#include "../ui_qt.h" + +extern "C" { +#include +#include +#include +#include "../../../command.h" +#include "../../../configuration.h" +#include "../../../retroarch.h" +#include "../../../paths.h" +#include "../../../file_path_special.h" +#include "../../../managers/core_option_manager.h" +} + +CoreOptionsDialog::CoreOptionsDialog(QWidget *parent) : + QDialog(parent) + ,m_layout() + ,m_scrollArea() +{ + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CORE_OPTIONS)); + setObjectName("coreOptionsDialog"); + + resize(720, 480); + + QTimer::singleShot(0, this, SLOT(clearLayout())); +} + +CoreOptionsDialog::~CoreOptionsDialog() +{ +} + +void CoreOptionsDialog::resizeEvent(QResizeEvent *event) +{ + QDialog::resizeEvent(event); + + if (!m_scrollArea) + return; + + m_scrollArea->resize(event->size()); + + emit resized(event->size()); +} + +void CoreOptionsDialog::closeEvent(QCloseEvent *event) +{ + QDialog::closeEvent(event); + + emit closed(); +} + +void CoreOptionsDialog::paintEvent(QPaintEvent *event) +{ + QStyleOption o; + QPainter p; + o.initFrom(this); + p.begin(this); + style()->drawPrimitive( + QStyle::PE_Widget, &o, &p, this); + p.end(); + + QDialog::paintEvent(event); +} + +void CoreOptionsDialog::clearLayout() +{ + QWidget *widget = NULL; + + if (m_scrollArea) + { + foreach (QObject *obj, children()) + { + obj->deleteLater(); + } + } + + m_layout = new QVBoxLayout(); + + widget = new QWidget(); + widget->setLayout(m_layout); + widget->setObjectName("coreOptionsWidget"); + + m_scrollArea = new QScrollArea(); + + m_scrollArea->setParent(this); + m_scrollArea->setWidgetResizable(true); + m_scrollArea->setWidget(widget); + m_scrollArea->setObjectName("coreOptionsScrollArea"); + m_scrollArea->show(); +} + +void CoreOptionsDialog::reload() +{ + buildLayout(); +} + +void CoreOptionsDialog::onSaveGameSpecificOptions() +{ + char game_path[PATH_MAX_LENGTH]; + config_file_t *conf = NULL; + + game_path[0] = '\0'; + + if (!retroarch_validate_game_options(game_path, sizeof(game_path), true)) + { + QMessageBox::critical(this, msg_hash_to_str(MSG_ERROR), msg_hash_to_str(MSG_ERROR_SAVING_CORE_OPTIONS_FILE)); + return; + } + + conf = config_file_new(game_path); + + if (!conf) + { + conf = config_file_new(NULL); + + if (!conf) + { + QMessageBox::critical(this, msg_hash_to_str(MSG_ERROR), msg_hash_to_str(MSG_ERROR_SAVING_CORE_OPTIONS_FILE)); + return; + } + } + + if (config_file_write(conf, game_path)) + { + runloop_msg_queue_push( + msg_hash_to_str(MSG_CORE_OPTIONS_FILE_CREATED_SUCCESSFULLY), + 1, 100, true); + path_set(RARCH_PATH_CORE_OPTIONS, game_path); + } + + config_file_free(conf); +} + +void CoreOptionsDialog::onCoreOptionComboBoxCurrentIndexChanged(int index) +{ + QComboBox *comboBox = qobject_cast(sender()); + QString key, val; + size_t opts = 0; + unsigned i, k; + + if (!comboBox) + return; + + key = comboBox->itemData(index, Qt::UserRole).toString(); + val = comboBox->itemText(index); + + if (rarch_ctl(RARCH_CTL_HAS_CORE_OPTIONS, NULL)) + { + rarch_ctl(RARCH_CTL_GET_CORE_OPTION_SIZE, &opts); + + if (opts) + { + core_option_manager_t *coreopts = NULL; + + rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts); + + if (coreopts) + { + for (i = 0; i < opts; i++) + { + QString optKey; + struct core_option *option = static_cast(&coreopts->opts[i]); + + if (!option) + continue; + + optKey = option->key; + + if (key == optKey) + { + for (k = 0; k < option->vals->size; k++) + { + QString str = option->vals->elems[k].data; + + if (!str.isEmpty() && str == val) + core_option_manager_set_val(coreopts, i, k); + } + } + } + } + } + } +} + +void CoreOptionsDialog::buildLayout() +{ + QFormLayout *form = NULL; + settings_t *settings = config_get_ptr(); + size_t opts = 0; + int i; + unsigned j, k; + + clearLayout(); + + if (rarch_ctl(RARCH_CTL_HAS_CORE_OPTIONS, NULL)) + { + rarch_ctl(RARCH_CTL_GET_CORE_OPTION_SIZE, &opts); + + if (opts) + { + core_option_manager_t *coreopts = NULL; + + form = new QFormLayout(); + + if (settings->bools.game_specific_options) + { + rarch_system_info_t *system = runloop_get_system_info(); + QString contentLabel; + QString label; + + if (system) + contentLabel = QFileInfo(path_get(RARCH_PATH_BASENAME)).completeBaseName(); + + if (!contentLabel.isEmpty()) + { + if (!rarch_ctl(RARCH_CTL_IS_GAME_OPTIONS_ACTIVE, NULL)) + label = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE); + else + label = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE); + + if (!label.isEmpty()) + { + QHBoxLayout *gameOptionsLayout = new QHBoxLayout(); + QPushButton *button = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SAVE), this); + + connect(button, SIGNAL(clicked()), this, SLOT(onSaveGameSpecificOptions())); + + gameOptionsLayout->addWidget(new QLabel(contentLabel, this)); + gameOptionsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred)); + gameOptionsLayout->addWidget(button); + + form->addRow(label, gameOptionsLayout); + } + } + } + + rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts); + + if (coreopts) + { + for (j = 0; j < opts; j++) + { + QString desc = core_option_manager_get_desc(coreopts, j); + QString val = core_option_manager_get_val(coreopts, j); + QComboBox *comboBox = NULL; + struct core_option *option = NULL; + + if (desc.isEmpty() || !coreopts->opts) + continue; + + option = static_cast(&coreopts->opts[j]); + + if (!option->vals || option->vals->size == 0) + continue; + + comboBox = new QComboBox(this); + + for (k = 0; k < option->vals->size; k++) + { + comboBox->addItem(option->vals->elems[k].data, option->key); + } + + comboBox->setCurrentText(val); + + /* Only connect the signal after setting the default item */ + connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onCoreOptionComboBoxCurrentIndexChanged(int))); + + form->addRow(desc, comboBox); + } + + m_layout->addLayout(form); + } + } + } + + if (!opts) + { + QLabel *noParamsLabel = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_CORE_OPTIONS_AVAILABLE), this); + noParamsLabel->setAlignment(Qt::AlignCenter); + + m_layout->addWidget(noParamsLabel); + } + + m_layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + resize(width() + 1, height()); + show(); + resize(width() - 1, height()); +} diff --git a/ui/drivers/qt/coreoptionsdialog.h b/ui/drivers/qt/coreoptionsdialog.h new file mode 100644 index 0000000000..2a9c29023e --- /dev/null +++ b/ui/drivers/qt/coreoptionsdialog.h @@ -0,0 +1,39 @@ +#ifndef COREOPTIONSDIALOG_H +#define COREOPTIONSDIALOG_H + +#include +#include + +class QCloseEvent; +class QResizeEvent; +class QVBoxLayout; +class QFormLayout; +class QLayout; +class QScrollArea; + +class CoreOptionsDialog : public QDialog +{ + Q_OBJECT +public: + CoreOptionsDialog(QWidget *parent = 0); + ~CoreOptionsDialog(); +signals: + void closed(); + void resized(QSize size); +public slots: + void reload(); +private slots: + void clearLayout(); + void buildLayout(); + void onSaveGameSpecificOptions(); + void onCoreOptionComboBoxCurrentIndexChanged(int index); +private: + QPointer m_layout; + QPointer m_scrollArea; +protected: + void closeEvent(QCloseEvent *event); + void resizeEvent(QResizeEvent *event); + void paintEvent(QPaintEvent *event); +}; + +#endif diff --git a/ui/drivers/qt/filedropwidget.cpp b/ui/drivers/qt/filedropwidget.cpp new file mode 100644 index 0000000000..3e5b1bf13c --- /dev/null +++ b/ui/drivers/qt/filedropwidget.cpp @@ -0,0 +1,202 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "filedropwidget.h" +#include "playlistentrydialog.h" +#include "../ui_qt.h" + +extern "C" { +#include "../../../file_path_special.h" +} + +FileDropWidget::FileDropWidget(QWidget *parent) : + QWidget(parent) +{ + setAcceptDrops(true); +} + +void FileDropWidget::paintEvent(QPaintEvent *event) +{ + QStyleOption o; + QPainter p; + o.initFrom(this); + p.begin(this); + style()->drawPrimitive( + QStyle::PE_Widget, &o, &p, this); + p.end(); + + QWidget::paintEvent(event); +} + +void FileDropWidget::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Delete) + { + event->accept(); + emit deletePressed(); + } + else + QWidget::keyPressEvent(event); +} + +void FileDropWidget::dragEnterEvent(QDragEnterEvent *event) +{ + const QMimeData *data = event->mimeData(); + + if (data->hasUrls()) + event->acceptProposedAction(); +} + +void FileDropWidget::dropEvent(QDropEvent *event) +{ + const QMimeData *data = event->mimeData(); + + if (data->hasUrls()) + { + QList urls = data->urls(); + QStringList files; + int i; + + for (i = 0; i < urls.count(); i++) + { + QString path(urls.at(i).toLocalFile()); + + files.append(path); + } + + emit filesDropped(files); + } +} + +void MainWindow::onFileDropWidgetContextMenuRequested(const QPoint &pos) +{ + QScopedPointer menu; + QScopedPointer downloadThumbnailAction; + QScopedPointer addEntryAction; + QScopedPointer addFilesAction; + QScopedPointer addFolderAction; + QScopedPointer editAction; + QScopedPointer deleteAction; + QPointer selectedAction; + QPoint cursorPos = QCursor::pos(); + QHash contentHash = getCurrentContentHash(); + + menu.reset(new QMenu(this)); + + downloadThumbnailAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_THUMBNAIL)), this)); + addEntryAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ADD_ENTRY)), this)); + addFilesAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ADD_FILES)), this)); + addFolderAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ADD_FOLDER)), this)); + editAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_EDIT)), this)); + deleteAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DELETE)), this)); + + menu->addAction(downloadThumbnailAction.data()); + menu->addAction(addEntryAction.data()); + menu->addAction(addFilesAction.data()); + menu->addAction(addFolderAction.data()); + + if (!contentHash.isEmpty()) + { + menu->addAction(editAction.data()); + menu->addAction(deleteAction.data()); + } + + selectedAction = menu->exec(cursorPos); + + if (!selectedAction) + return; + + if (selectedAction == downloadThumbnailAction.data()) + { + QHash hash = getCurrentContentHash(); + QString system = QFileInfo(getCurrentPlaylistPath()).completeBaseName(); + QString title = hash.value("label"); + + if (!title.isEmpty()) + { + if (m_pendingThumbnailDownloadTypes.isEmpty()) + { + m_pendingThumbnailDownloadTypes.append(THUMBNAIL_BOXART); + m_pendingThumbnailDownloadTypes.append(THUMBNAIL_SCREENSHOT); + m_pendingThumbnailDownloadTypes.append(THUMBNAIL_TITLE); + downloadThumbnail(system, title); + } + else + { + showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALREADY_IN_PROGRESS), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); + } + } + } + else if (selectedAction == addFilesAction.data()) + { + QStringList filePaths = QFileDialog::getOpenFileNames(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SELECT_FILES)); + + if (!filePaths.isEmpty()) + addFilesToPlaylist(filePaths); + } + else if (selectedAction == addEntryAction.data()) + { + addFilesToPlaylist(QStringList()); + } + else if (selectedAction == addFolderAction.data()) + { + QString dirPath = QFileDialog::getExistingDirectory(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SELECT_FOLDER), QString(), QFileDialog::ShowDirsOnly); + + if (!dirPath.isEmpty()) + addFilesToPlaylist(QStringList() << dirPath); + } + else if (selectedAction == editAction.data()) + { + PlaylistEntryDialog *playlistDialog = playlistEntryDialog(); + QHash selectedCore; + QString selectedDatabase; + QString selectedName; + QString selectedPath; + QString currentPlaylistPath = getCurrentPlaylistPath(); + + if (!playlistDialog->showDialog(contentHash)) + return; + + selectedName = m_playlistEntryDialog->getSelectedName(); + selectedPath = m_playlistEntryDialog->getSelectedPath(); + selectedCore = m_playlistEntryDialog->getSelectedCore(); + selectedDatabase = m_playlistEntryDialog->getSelectedDatabase(); + + if (selectedCore.isEmpty()) + { + selectedCore["core_name"] = "DETECT"; + selectedCore["core_path"] = "DETECT"; + } + + if (selectedDatabase.isEmpty()) + { + selectedDatabase = QFileInfo(currentPlaylistPath).fileName().remove(file_path_str(FILE_PATH_LPL_EXTENSION)); + } + + contentHash["label"] = selectedName; + contentHash["path"] = selectedPath; + contentHash["core_name"] = selectedCore.value("core_name"); + contentHash["core_path"] = selectedCore.value("core_path"); + contentHash["db_name"] = selectedDatabase; + + if (!updateCurrentPlaylistEntry(contentHash)) + { + showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_UPDATE_PLAYLIST_ENTRY), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); + return; + } + } + else if (selectedAction == deleteAction.data()) + { + deleteCurrentPlaylistItem(); + } +} diff --git a/ui/drivers/qt/filedropwidget.h b/ui/drivers/qt/filedropwidget.h new file mode 100644 index 0000000000..9301d948df --- /dev/null +++ b/ui/drivers/qt/filedropwidget.h @@ -0,0 +1,26 @@ +#ifndef FILEDROPWIDGET_H +#define FILEDROPWIDGET_H + +#include + +class QDragEnterEvent; +class QDropEvent; +class QKeyEvent; +class QPaintEvent; + +class FileDropWidget : public QWidget +{ + Q_OBJECT +public: + FileDropWidget(QWidget *parent = 0); +signals: + void filesDropped(QStringList files); + void deletePressed(); +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + void keyPressEvent(QKeyEvent *event); + void paintEvent(QPaintEvent *event); +}; + +#endif diff --git a/ui/drivers/qt/playlist.cpp b/ui/drivers/qt/playlist.cpp new file mode 100644 index 0000000000..25f8abc53a --- /dev/null +++ b/ui/drivers/qt/playlist.cpp @@ -0,0 +1,1203 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../ui_qt.h" +#include "flowlayout.h" +#include "playlistentrydialog.h" + +extern "C" { +#include +#include +#include +#include +#include "../../../file_path_special.h" +#include "../../../playlist.h" +#include "../../../menu/menu_displaylist.h" +#include "../../../setting_list.h" +#include "../../../configuration.h" +#include "../../../core_info.h" +#include "../../../verbosity.h" +} + +inline static bool comp_hash_name_key_lower(const QHash &lhs, const QHash &rhs) +{ + return lhs.value("name").toLower() < rhs.value("name").toLower(); +} + +inline static bool comp_hash_label_key_lower(const QHash &lhs, const QHash &rhs) +{ + return lhs.value("label").toLower() < rhs.value("label").toLower(); +} + +/* https://stackoverflow.com/questions/7246622/how-to-create-a-slider-with-a-non-linear-scale */ +static void addDirectoryFilesToList(QStringList &list, QDir &dir) +{ + QStringList dirList = dir.entryList(QStringList(), QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System, QDir::Name); + int i; + + for (i = 0; i < dirList.count(); i++) + { + QString path(dir.path() + "/" + dirList.at(i)); + QFileInfo fileInfo(path); + + if (fileInfo.isDir()) + { + QDir fileInfoDir(path); + + addDirectoryFilesToList(list, fileInfoDir); + continue; + } + + if (fileInfo.isFile()) + { + list.append(fileInfo.absoluteFilePath()); + } + } +} + +void MainWindow::onPlaylistFilesDropped(QStringList files) +{ + addFilesToPlaylist(files); +} + +/* Takes a list of files and folders and adds them to the currently selected playlist. Folders will have their contents added recursively. */ +void MainWindow::addFilesToPlaylist(QStringList files) +{ + QStringList list; + QString currentPlaylistPath; + QListWidgetItem *currentItem = m_listWidget->currentItem(); + QByteArray currentPlaylistArray; + QScopedPointer dialog(NULL); + PlaylistEntryDialog *playlistDialog = playlistEntryDialog(); + QHash selectedCore; + QHash itemToAdd; + QString selectedDatabase; + QString selectedName; + QString selectedPath; + const char *currentPlaylistData = NULL; + playlist_t *playlist = NULL; + int i; + + /* Assume a blank list means we will manually enter in all fields. */ + if (files.isEmpty()) + { + /* Make sure hash isn't blank, that would mean there's multiple entries to add at once. */ + itemToAdd["label"] = ""; + itemToAdd["path"] = ""; + } + else if (files.count() == 1) + { + QString path = files.at(0); + QFileInfo info(path); + + if (info.isFile()) + { + itemToAdd["label"] = info.completeBaseName(); + itemToAdd["path"] = path; + } + } + + if (currentItem) + { + currentPlaylistPath = currentItem->data(Qt::UserRole).toString(); + + if (!currentPlaylistPath.isEmpty()) + { + currentPlaylistArray = currentPlaylistPath.toUtf8(); + currentPlaylistData = currentPlaylistArray.constData(); + } + } + + if (currentPlaylistPath == ALL_PLAYLISTS_TOKEN) + { + showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CANNOT_ADD_TO_ALL_PLAYLISTS), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); + return; + } + + /* a blank itemToAdd means there will be multiple */ + if (!playlistDialog->showDialog(itemToAdd)) + return; + + selectedName = m_playlistEntryDialog->getSelectedName(); + selectedPath = m_playlistEntryDialog->getSelectedPath(); + selectedCore = m_playlistEntryDialog->getSelectedCore(); + selectedDatabase = m_playlistEntryDialog->getSelectedDatabase(); + + if (selectedDatabase.isEmpty()) + selectedDatabase = QFileInfo(currentPlaylistPath).fileName(); + else + selectedDatabase += file_path_str(FILE_PATH_LPL_EXTENSION); + + dialog.reset(new QProgressDialog(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_GATHERING_LIST_OF_FILES), "Cancel", 0, 0, this)); + dialog->setWindowModality(Qt::ApplicationModal); + + if (selectedName.isEmpty() || selectedPath.isEmpty() || + selectedDatabase.isEmpty()) + { + showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLEASE_FILL_OUT_REQUIRED_FIELDS), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); + return; + } + + if (files.isEmpty()) + files.append(selectedPath); + + for (i = 0; i < files.count(); i++) + { + QString path(files.at(i)); + QFileInfo fileInfo(path); + + if (dialog->wasCanceled()) + return; + + if (i % 25 == 0) + { + /* Needed to update progress dialog while doing a lot of stuff on the main thread. */ + qApp->processEvents(); + } + + if (fileInfo.isDir()) + { + QDir dir(path); + addDirectoryFilesToList(list, dir); + continue; + } + + if (fileInfo.isFile()) + list.append(fileInfo.absoluteFilePath()); + else if (files.count() == 1) + { + /* If adding a single file, tell user that it doesn't exist. */ + showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); + return; + } + } + + dialog->setLabelText(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ADDING_FILES_TO_PLAYLIST)); + dialog->setMaximum(list.count()); + + playlist = playlist_init(currentPlaylistData, COLLECTION_SIZE); + + for (i = 0; i < list.count(); i++) + { + QString fileName = list.at(i); + QFileInfo fileInfo; + QByteArray fileBaseNameArray; + QByteArray pathArray; + QByteArray corePathArray; + QByteArray coreNameArray; + QByteArray databaseArray; + const char *pathData = NULL; + const char *fileNameNoExten = NULL; + const char *corePathData = NULL; + const char *coreNameData = NULL; + const char *databaseData = NULL; + + if (dialog->wasCanceled()) + { + playlist_free(playlist); + return; + } + + if (fileName.isEmpty()) + continue; + + fileInfo = fileName; + + if (files.count() == 1 && list.count() == 1 && i == 0) + { + fileBaseNameArray = selectedName.toUtf8(); + pathArray = QDir::toNativeSeparators(selectedPath).toUtf8(); + } + else + { + fileBaseNameArray = fileInfo.completeBaseName().toUtf8(); + pathArray = QDir::toNativeSeparators(fileName).toUtf8(); + } + + fileNameNoExten = fileBaseNameArray.constData(); + + /* a modal QProgressDialog calls processEvents() automatically in setValue() */ + dialog->setValue(i + 1); + + pathData = pathArray.constData(); + + if (selectedCore.isEmpty()) + { + corePathData = "DETECT"; + coreNameData = "DETECT"; + } + else + { + corePathArray = QDir::toNativeSeparators(selectedCore.value("core_path")).toUtf8(); + coreNameArray = selectedCore.value("core_name").toUtf8(); + corePathData = corePathArray.constData(); + coreNameData = coreNameArray.constData(); + } + + databaseArray = selectedDatabase.toUtf8(); + databaseData = databaseArray.constData(); + + if (path_is_compressed_file(pathData)) + { + struct string_list *list = file_archive_get_file_list(pathData, NULL); + + if (list) + { + if (list->size == 1) + { + /* assume archives with one file should have that file loaded directly */ + pathArray = QDir::toNativeSeparators(QString(pathData) + "#" + list->elems[0].data).toUtf8(); + pathData = pathArray.constData(); + } + + string_list_free(list); + } + } + + playlist_push(playlist, pathData, fileNameNoExten, + corePathData, coreNameData, "00000000|crc", databaseData); + } + + playlist_write_file(playlist); + playlist_free(playlist); + + reloadPlaylists(); +} + +bool MainWindow::updateCurrentPlaylistEntry(const QHash &contentHash) +{ + QString playlistPath = getCurrentPlaylistPath(); + QString path; + QString label; + QString corePath; + QString coreName; + QString dbName; + QString crc32; + QByteArray playlistPathArray; + QByteArray pathArray; + QByteArray labelArray; + QByteArray corePathArray; + QByteArray coreNameArray; + QByteArray dbNameArray; + QByteArray crc32Array; + const char *playlistPathData = NULL; + const char *pathData = NULL; + const char *labelData = NULL; + const char *corePathData = NULL; + const char *coreNameData = NULL; + const char *dbNameData = NULL; + const char *crc32Data = NULL; + playlist_t *playlist = NULL; + unsigned index = 0; + bool ok = false; + + if (playlistPath.isEmpty() || contentHash.isEmpty() || !contentHash.contains("index")) + return false; + + index = contentHash.value("index").toUInt(&ok); + + if (!ok) + return false; + + path = contentHash.value("path"); + label = contentHash.value("label"); + coreName = contentHash.value("core_name"); + corePath = contentHash.value("core_path"); + dbName = contentHash.value("db_name"); + crc32 = contentHash.value("crc32"); + + if (path.isEmpty() || + label.isEmpty() || + coreName.isEmpty() || + corePath.isEmpty() || + dbName.isEmpty() || + crc32.isEmpty() + ) + return false; + + playlistPathArray = playlistPath.toUtf8(); + pathArray = QDir::toNativeSeparators(path).toUtf8(); + labelArray = label.toUtf8(); + coreNameArray = coreName.toUtf8(); + corePathArray = QDir::toNativeSeparators(corePath).toUtf8(); + dbNameArray = (dbName + file_path_str(FILE_PATH_LPL_EXTENSION)).toUtf8(); + crc32Array = crc32.toUtf8(); + + playlistPathData = playlistPathArray.constData(); + pathData = pathArray.constData(); + labelData = labelArray.constData(); + coreNameData = coreNameArray.constData(); + corePathData = corePathArray.constData(); + dbNameData = dbNameArray.constData(); + crc32Data = crc32Array.constData(); + + if (path_is_compressed_file(pathData)) + { + struct string_list *list = file_archive_get_file_list(pathData, NULL); + + if (list) + { + if (list->size == 1) + { + /* assume archives with one file should have that file loaded directly */ + pathArray = QDir::toNativeSeparators(QString(pathData) + "#" + list->elems[0].data).toUtf8(); + pathData = pathArray.constData(); + } + + string_list_free(list); + } + } + + playlist = playlist_init(playlistPathData, COLLECTION_SIZE); + + playlist_update(playlist, index, pathData, labelData, + corePathData, coreNameData, crc32Data, dbNameData); + playlist_write_file(playlist); + playlist_free(playlist); + + reloadPlaylists(); + + return true; +} + +void MainWindow::onPlaylistWidgetContextMenuRequested(const QPoint&) +{ + settings_t *settings = config_get_ptr(); + QScopedPointer menu; + QScopedPointer associateMenu; + QScopedPointer hiddenPlaylistsMenu; + QScopedPointer downloadAllThumbnailsMenu; + QScopedPointer hideAction; + QScopedPointer newPlaylistAction; + QScopedPointer deletePlaylistAction; + QScopedPointer downloadAllThumbnailsEntireSystemAction; + QScopedPointer downloadAllThumbnailsThisPlaylistAction; + QPointer selectedAction; + QPoint cursorPos = QCursor::pos(); + QListWidgetItem *selectedItem = m_listWidget->itemAt(m_listWidget->viewport()->mapFromGlobal(cursorPos)); + QDir playlistDir(settings->paths.directory_playlist); + QString playlistDirAbsPath = playlistDir.absolutePath(); + QString currentPlaylistDirPath; + QString currentPlaylistPath; + QString currentPlaylistFileName; + QFile currentPlaylistFile; + QByteArray currentPlaylistFileNameArray; + QFileInfo currentPlaylistFileInfo; + QMap coreList; + core_info_list_t *core_info_list = NULL; + union string_list_elem_attr attr = {0}; + struct string_list *stnames = NULL; + struct string_list *stcores = NULL; + unsigned i = 0; + int j = 0; + size_t found = 0; + const char *currentPlaylistFileNameData = NULL; + char new_playlist_names[PATH_MAX_LENGTH]; + char new_playlist_cores[PATH_MAX_LENGTH]; + bool specialPlaylist = false; + bool foundHiddenPlaylist = false; + + new_playlist_names[0] = new_playlist_cores[0] = '\0'; + + stnames = string_split(settings->arrays.playlist_names, ";"); + stcores = string_split(settings->arrays.playlist_cores, ";"); + + if (selectedItem) + { + currentPlaylistPath = selectedItem->data(Qt::UserRole).toString(); + currentPlaylistFile.setFileName(currentPlaylistPath); + + currentPlaylistFileInfo = QFileInfo(currentPlaylistPath); + currentPlaylistFileName = currentPlaylistFileInfo.fileName(); + currentPlaylistDirPath = currentPlaylistFileInfo.absoluteDir().absolutePath(); + + currentPlaylistFileNameArray.append(currentPlaylistFileName); + currentPlaylistFileNameData = currentPlaylistFileNameArray.constData(); + } + + menu.reset(new QMenu(this)); + menu->setObjectName("menu"); + + hiddenPlaylistsMenu.reset(new QMenu(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS), this)); + newPlaylistAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST)) + "...", this)); + + hiddenPlaylistsMenu->setObjectName("hiddenPlaylistsMenu"); + + menu->addAction(newPlaylistAction.data()); + + if (currentPlaylistFile.exists()) + { + deletePlaylistAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DELETE_PLAYLIST)) + "...", this)); + menu->addAction(deletePlaylistAction.data()); + } + + if (selectedItem) + { + hideAction.reset(new QAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_HIDE), this)); + menu->addAction(hideAction.data()); + } + + for (j = 0; j < m_listWidget->count(); j++) + { + QListWidgetItem *item = m_listWidget->item(j); + bool hidden = m_listWidget->isItemHidden(item); + + if (hidden) + { + QAction *action = hiddenPlaylistsMenu->addAction(item->text()); + action->setProperty("row", j); + action->setProperty("core_path", item->data(Qt::UserRole).toString()); + foundHiddenPlaylist = true; + } + } + + if (!foundHiddenPlaylist) + { + QAction *action = hiddenPlaylistsMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NONE)); + action->setProperty("row", -1); + } + + menu->addMenu(hiddenPlaylistsMenu.data()); + + /* Don't just compare strings in case there are case differences on Windows that should be ignored. */ + if (QDir(currentPlaylistDirPath) != QDir(playlistDirAbsPath)) + { + /* special playlists like history etc. can't have an association */ + specialPlaylist = true; + } + + if (!specialPlaylist) + { + associateMenu.reset(new QMenu(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE), this)); + associateMenu->setObjectName("associateMenu"); + + core_info_get_list(&core_info_list); + + for (i = 0; i < core_info_list->count && core_info_list->count > 0; i++) + { + const core_info_t *core = &core_info_list->list[i]; + coreList[core->core_name] = core; + } + + { + QMapIterator coreListIterator(coreList); + QVector > cores; + + while (coreListIterator.hasNext()) + { + QString key; + const core_info_t *core = NULL; + QString name; + QHash hash; + + coreListIterator.next(); + + key = coreListIterator.key(); + core = coreList.value(key); + + if (string_is_empty(core->core_name)) + name = core->display_name; + else + name = core->core_name; + + if (name.isEmpty()) + continue; + + hash["name"] = name; + hash["core_path"] = core->path; + + cores.append(hash); + } + + std::sort(cores.begin(), cores.end(), comp_hash_name_key_lower); + + for (j = 0; j < cores.count(); j++) + { + const QHash &hash = cores.at(j); + QAction *action = associateMenu->addAction(hash.value("name")); + + action->setProperty("core_path", hash.value("core_path")); + } + } + + menu->addMenu(associateMenu.data()); + } + + if (!specialPlaylist) + { + downloadAllThumbnailsMenu.reset(new QMenu(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS), this)); + downloadAllThumbnailsMenu->setObjectName("downloadAllThumbnailsMenu"); + + downloadAllThumbnailsThisPlaylistAction.reset(new QAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_THIS_PLAYLIST), downloadAllThumbnailsMenu.data())); + downloadAllThumbnailsEntireSystemAction.reset(new QAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_ENTIRE_SYSTEM), downloadAllThumbnailsMenu.data())); + + downloadAllThumbnailsMenu->addAction(downloadAllThumbnailsThisPlaylistAction.data()); + downloadAllThumbnailsMenu->addAction(downloadAllThumbnailsEntireSystemAction.data()); + + menu->addMenu(downloadAllThumbnailsMenu.data()); + } + + selectedAction = menu->exec(cursorPos); + + if (!selectedAction) + goto end; + + if (!specialPlaylist && selectedAction->parent() == associateMenu.data()) + { + found = string_list_find_elem(stnames, currentPlaylistFileNameData); + + if (found) + string_list_set(stcores, static_cast(found - 1), selectedAction->property("core_path").toString().toUtf8().constData()); + else + { + string_list_append(stnames, currentPlaylistFileNameData, attr); + string_list_append(stcores, "DETECT", attr); + + found = string_list_find_elem(stnames, currentPlaylistFileNameData); + + if (found) + string_list_set(stcores, static_cast(found - 1), selectedAction->property("core_path").toString().toUtf8().constData()); + } + + string_list_join_concat(new_playlist_names, + sizeof(new_playlist_names), stnames, ";"); + string_list_join_concat(new_playlist_cores, + sizeof(new_playlist_cores), stcores, ";"); + + strlcpy(settings->arrays.playlist_names, + new_playlist_names, sizeof(settings->arrays.playlist_names)); + strlcpy(settings->arrays.playlist_cores, + new_playlist_cores, sizeof(settings->arrays.playlist_cores)); + } + else if (selectedItem && selectedAction == deletePlaylistAction.data()) + { + if (currentPlaylistFile.exists()) + { + if (showMessageBox(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST)).arg(selectedItem->text()), MainWindow::MSGBOX_TYPE_QUESTION_YESNO, Qt::ApplicationModal, false)) + { + if (currentPlaylistFile.remove()) + reloadPlaylists(); + else + showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_DELETE_FILE), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); + } + } + } + else if (selectedAction == newPlaylistAction.data()) + { + QString name = QInputDialog::getText(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ENTER_NEW_PLAYLIST_NAME)); + QString newPlaylistPath = playlistDirAbsPath + "/" + name + file_path_str(FILE_PATH_LPL_EXTENSION); + QFile file(newPlaylistPath); + + if (!name.isEmpty()) + { + if (file.open(QIODevice::WriteOnly)) + file.close(); + + reloadPlaylists(); + } + } + else if (selectedItem && selectedAction == hideAction.data()) + { + int row = m_listWidget->row(selectedItem); + + if (row >= 0) + { + QStringList hiddenPlaylists = m_settings->value("hidden_playlists").toStringList(); + + if (!hiddenPlaylists.contains(currentPlaylistFileName)) + { + hiddenPlaylists.append(currentPlaylistFileName); + m_settings->setValue("hidden_playlists", hiddenPlaylists); + } + + m_listWidget->setRowHidden(row, true); + } + } + else if (selectedAction->parent() == hiddenPlaylistsMenu.data()) + { + QVariant rowVariant = selectedAction->property("row"); + + if (rowVariant.isValid()) + { + QStringList hiddenPlaylists = m_settings->value("hidden_playlists").toStringList(); + int row = rowVariant.toInt(); + + if (row >= 0) + { + QString playlistPath = selectedAction->property("core_path").toString(); + QFileInfo playlistFileInfo(playlistPath); + QString playlistFileName = playlistFileInfo.fileName(); + + if (hiddenPlaylists.contains(playlistFileName)) + { + hiddenPlaylists.removeOne(playlistFileName); + m_settings->setValue("hidden_playlists", hiddenPlaylists); + } + + m_listWidget->setRowHidden(row, false); + } + } + } + else if (selectedItem && !specialPlaylist && selectedAction->parent() == downloadAllThumbnailsMenu.data()) + { + if (selectedAction == downloadAllThumbnailsEntireSystemAction.data()) + { + int row = m_listWidget->row(selectedItem); + + if (row >= 0) + downloadAllThumbnails(currentPlaylistFileInfo.completeBaseName()); + } + else if (selectedAction == downloadAllThumbnailsThisPlaylistAction.data()) + { + downloadPlaylistThumbnails(currentPlaylistPath); + } + } + + setCoreActions(); + +end: + if (stnames) + string_list_free(stnames); + if (stcores) + string_list_free(stcores); +} + +void MainWindow::deferReloadPlaylists() +{ + emit gotReloadPlaylists(); +} + +void MainWindow::onGotReloadPlaylists() +{ + reloadPlaylists(); +} + +void MainWindow::reloadPlaylists() +{ + QListWidgetItem *allPlaylistsItem = NULL; + QListWidgetItem *favoritesPlaylistsItem = NULL; + QListWidgetItem *imagePlaylistsItem = NULL; + QListWidgetItem *musicPlaylistsItem = NULL; + QListWidgetItem *videoPlaylistsItem = NULL; + QListWidgetItem *firstItem = NULL; + QListWidgetItem *currentItem = NULL; + settings_t *settings = config_get_ptr(); + QDir playlistDir(settings->paths.directory_playlist); + QString currentPlaylistPath; + QStringList hiddenPlaylists = m_settings->value("hidden_playlists").toStringList(); + int i = 0; + + currentItem = m_listWidget->currentItem(); + + if (currentItem) + { + currentPlaylistPath = currentItem->data(Qt::UserRole).toString(); + } + + getPlaylistFiles(); + + m_listWidget->clear(); + + allPlaylistsItem = new QListWidgetItem(m_folderIcon, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ALL_PLAYLISTS)); + allPlaylistsItem->setData(Qt::UserRole, ALL_PLAYLISTS_TOKEN); + + favoritesPlaylistsItem = new QListWidgetItem(m_folderIcon, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FAVORITES_TAB)); + favoritesPlaylistsItem->setData(Qt::UserRole, settings->paths.path_content_favorites); + + m_historyPlaylistsItem = new QListWidgetItem(m_folderIcon, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_HISTORY_TAB)); + m_historyPlaylistsItem->setData(Qt::UserRole, settings->paths.path_content_history); + + imagePlaylistsItem = new QListWidgetItem(m_folderIcon, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_IMAGES_TAB)); + imagePlaylistsItem->setData(Qt::UserRole, settings->paths.path_content_image_history); + + musicPlaylistsItem = new QListWidgetItem(m_folderIcon, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MUSIC_TAB)); + musicPlaylistsItem->setData(Qt::UserRole, settings->paths.path_content_music_history); + + videoPlaylistsItem = new QListWidgetItem(m_folderIcon, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_TAB)); + videoPlaylistsItem->setData(Qt::UserRole, settings->paths.path_content_video_history); + + m_listWidget->addItem(allPlaylistsItem); + m_listWidget->addItem(favoritesPlaylistsItem); + m_listWidget->addItem(m_historyPlaylistsItem); + m_listWidget->addItem(imagePlaylistsItem); + m_listWidget->addItem(musicPlaylistsItem); + m_listWidget->addItem(videoPlaylistsItem); + + if (hiddenPlaylists.contains(ALL_PLAYLISTS_TOKEN)) + m_listWidget->setRowHidden(m_listWidget->row(allPlaylistsItem), true); + if (hiddenPlaylists.contains(QFileInfo(settings->paths.path_content_favorites).fileName())) + m_listWidget->setRowHidden(m_listWidget->row(favoritesPlaylistsItem), true); + if (hiddenPlaylists.contains(QFileInfo(settings->paths.path_content_history).fileName())) + m_listWidget->setRowHidden(m_listWidget->row(m_historyPlaylistsItem), true); + if (hiddenPlaylists.contains(QFileInfo(settings->paths.path_content_image_history).fileName())) + m_listWidget->setRowHidden(m_listWidget->row(imagePlaylistsItem), true); + if (hiddenPlaylists.contains(QFileInfo(settings->paths.path_content_music_history).fileName())) + m_listWidget->setRowHidden(m_listWidget->row(musicPlaylistsItem), true); + if (hiddenPlaylists.contains(QFileInfo(settings->paths.path_content_video_history).fileName())) + m_listWidget->setRowHidden(m_listWidget->row(videoPlaylistsItem), true); + + for (i = 0; i < m_playlistFiles.count(); i++) + { + QListWidgetItem *item = NULL; + const QString &file = m_playlistFiles.at(i); + QString fileDisplayName = file; + QString fileName = file; + bool hasIcon = false; + QIcon icon; + QString iconPath; + + fileDisplayName.remove(file_path_str(FILE_PATH_LPL_EXTENSION)); + + iconPath = QString(settings->paths.directory_assets) + ICON_PATH + fileDisplayName + ".png"; + + hasIcon = QFile::exists(iconPath); + + if (hasIcon) + icon = QIcon(iconPath); + else + icon = m_folderIcon; + + item = new QListWidgetItem(icon, fileDisplayName); + item->setData(Qt::UserRole, playlistDir.absoluteFilePath(file)); + + m_listWidget->addItem(item); + + if (hiddenPlaylists.contains(fileName)) + { + int row = m_listWidget->row(item); + + if (row >= 0) + m_listWidget->setRowHidden(row, true); + } + } + + if (m_listWidget->count() > 0) + { + firstItem = m_listWidget->item(0); + + if (firstItem) + { + bool foundCurrent = false; + bool foundInitial = false; + QString initialPlaylist = m_settings->value("initial_playlist", m_historyPlaylistsItem->data(Qt::UserRole).toString()).toString(); + QListWidgetItem *initialItem = NULL; + + for (i = 0; i < m_listWidget->count(); i++) + { + QListWidgetItem *item = m_listWidget->item(i); + QString path; + + if (item) + { + path = item->data(Qt::UserRole).toString(); + + if (!path.isEmpty()) + { + /* don't break early here since we want to make sure we've found both initial and current items if they exist */ + if (!foundInitial && path == initialPlaylist) + { + foundInitial = true; + initialItem = item; + } + if (!foundCurrent && !currentPlaylistPath.isEmpty() && path == currentPlaylistPath) + { + foundCurrent = true; + m_listWidget->setCurrentItem(item); + } + } + } + } + + if (!foundCurrent) + { + if (foundInitial && initialItem) + { + m_listWidget->setCurrentItem(initialItem); + } + else + { + /* the previous playlist must be gone now, just select the first one */ + m_listWidget->setCurrentItem(firstItem); + } + } + } + } +} + +QString MainWindow::getCurrentPlaylistPath() +{ + QListWidgetItem *playlistItem = m_listWidget->currentItem(); + QHash contentHash; + QString playlistPath; + + if (!playlistItem) + return playlistPath; + + playlistPath = playlistItem->data(Qt::UserRole).toString(); + + return playlistPath; +} + +void MainWindow::deleteCurrentPlaylistItem() +{ + QString playlistPath = getCurrentPlaylistPath(); + QByteArray playlistArray; + QHash contentHash = getCurrentContentHash(); + playlist_t *playlist = NULL; + const char *playlistData = NULL; + unsigned index = 0; + bool ok = false; + + if (playlistPath.isEmpty()) + return; + + if (contentHash.isEmpty()) + return; + + playlistArray = playlistPath.toUtf8(); + playlistData = playlistArray.constData(); + + index = contentHash.value("index").toUInt(&ok); + + if (!ok) + return; + + if (!showMessageBox(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST_ITEM)).arg(contentHash["label"]), MainWindow::MSGBOX_TYPE_QUESTION_YESNO, Qt::ApplicationModal, false)) + return; + + playlist = playlist_init(playlistData, COLLECTION_SIZE); + + playlist_delete_index(playlist, index); + playlist_write_file(playlist); + playlist_free(playlist); + + reloadPlaylists(); +} + +QVector > MainWindow::getPlaylistDefaultCores() +{ + settings_t *settings = config_get_ptr(); + struct string_list *playlists = string_split(settings->arrays.playlist_names, ";"); + struct string_list *cores = string_split(settings->arrays.playlist_cores, ";"); + unsigned i = 0; + QVector > coreList; + + if (!playlists || !cores) + { + RARCH_WARN("[Qt]: Could not parse one of playlist_names or playlist_cores\n"); + goto finish; + } + else if (playlists->size != cores->size) + { + RARCH_WARN("[Qt]: playlist_names array size differs from playlist_cores\n"); + goto finish; + } + + if (playlists->size == 0) + goto finish; + + for (i = 0; i < playlists->size; i++) + { + const char *playlist = playlists->elems[i].data; + const char *core = cores->elems[i].data; + QHash hash; + + hash["playlist_filename"] = playlist; + hash["playlist_filename"].remove(file_path_str(FILE_PATH_LPL_EXTENSION)); + hash["core_path"] = core; + + coreList.append(hash); + } + +finish: + if (playlists) + string_list_free(playlists); + if (cores) + string_list_free(cores); + + return coreList; +} + +void MainWindow::getPlaylistFiles() +{ + settings_t *settings = config_get_ptr(); + QDir playlistDir(settings->paths.directory_playlist); + + m_playlistFiles = playlistDir.entryList(QDir::NoDotAndDotDot | QDir::Readable | QDir::Files, QDir::Name); +} + +void MainWindow::addPlaylistItemsToGrid(const QStringList &paths, bool add) +{ + QVector > items; + int i; + + if (paths.isEmpty()) + return; + + for (i = 0; i < paths.size(); i++) + { + int j; + QVector > vec = getPlaylistItems(paths.at(i)); + /* QVector::append() wasn't added until 5.5, so just do it the old fashioned way */ + for (j = 0; j < vec.size(); j++) + { + if (add && m_allPlaylistsGridMaxCount > 0 && items.size() >= m_allPlaylistsGridMaxCount) + goto finish; + + items.append(vec.at(j)); + } + } +finish: + std::sort(items.begin(), items.end(), comp_hash_label_key_lower); + + addPlaylistHashToGrid(items); +} + +void MainWindow::addPlaylistHashToGrid(const QVector > &items) +{ + QScreen *screen = qApp->primaryScreen(); + QSize screenSize = screen->size(); + QListWidgetItem *currentItem = m_listWidget->currentItem(); + settings_t *settings = config_get_ptr(); + int i = 0; + int zoomValue = m_zoomSlider->value(); + + m_gridProgressBar->setMinimum(0); + m_gridProgressBar->setMaximum(qMax(0, items.count() - 1)); + m_gridProgressBar->setValue(0); + + for (i = 0; i < items.count(); i++) + { + const QHash &hash = items.at(i); + QPointer item; + QPointer label; + QString thumbnailFileNameNoExt; + QLabel *newLabel = NULL; + QSize thumbnailWidgetSizeHint(screenSize.width() / 8, screenSize.height() / 8); + QByteArray extension; + QString extensionStr; + QString imagePath; + int lastIndex = -1; + + if (m_listWidget->currentItem() != currentItem) + { + /* user changed the current playlist before we finished loading... abort */ + m_gridProgressWidget->hide(); + break; + } + + item = new GridItem(); + + lastIndex = hash["path"].lastIndexOf('.'); + + if (lastIndex >= 0) + { + extensionStr = hash["path"].mid(lastIndex + 1); + + if (!extensionStr.isEmpty()) + { + extension = extensionStr.toLower().toUtf8(); + } + } + + if (!extension.isEmpty() && m_imageFormats.contains(extension)) + { + /* use thumbnail widgets to show regular image files */ + imagePath = hash["path"]; + } + else + { + thumbnailFileNameNoExt = hash["label_noext"]; + thumbnailFileNameNoExt.replace(m_fileSanitizerRegex, "_"); + imagePath = QString(settings->paths.directory_thumbnails) + "/" + hash.value("db_name") + "/" + THUMBNAIL_BOXART + "/" + thumbnailFileNameNoExt + ".png"; + } + + item->hash = hash; + item->widget = new ThumbnailWidget(); + item->widget->setSizeHint(thumbnailWidgetSizeHint); + item->widget->setFixedSize(item->widget->sizeHint()); + item->widget->setLayout(new QVBoxLayout()); + item->widget->setObjectName("thumbnailWidget"); + item->widget->setProperty("hash", QVariant::fromValue >(hash)); + item->widget->setProperty("image_path", imagePath); + + connect(item->widget, SIGNAL(mouseDoubleClicked()), this, SLOT(onGridItemDoubleClicked())); + connect(item->widget, SIGNAL(mousePressed()), this, SLOT(onGridItemClicked())); + + label = new ThumbnailLabel(item->widget); + label->setObjectName("thumbnailGridLabel"); + + item->label = label; + item->labelText = hash.value("label"); + + newLabel = new QLabel(item->labelText, item->widget); + newLabel->setObjectName("thumbnailQLabel"); + newLabel->setAlignment(Qt::AlignCenter); + newLabel->setToolTip(item->labelText); + + calcGridItemSize(item, zoomValue); + + item->widget->layout()->addWidget(label); + + item->widget->layout()->addWidget(newLabel); + qobject_cast(item->widget->layout())->setStretchFactor(label, 1); + + m_gridLayout->addWidgetDeferred(item->widget); + m_gridItems.append(item); + + loadImageDeferred(item, imagePath); + + if (i % 25 == 0) + { + /* Needed to update progress dialog while doing a lot of stuff on the main thread. */ + qApp->processEvents(); + } + + m_gridProgressBar->setValue(i); + } + + /* If there's only one entry, a min/max/value of all zero would make an indeterminate progress bar that never ends... so just hide it when we are done. */ + if (m_gridProgressBar->value() == m_gridProgressBar->maximum()) + m_gridProgressWidget->hide(); +} + +QVector > MainWindow::getPlaylistItems(QString pathString) +{ + QByteArray pathArray; + QVector > items; + const char *pathData = NULL; + playlist_t *playlist = NULL; + unsigned playlistSize = 0; + unsigned i = 0; + + pathArray.append(pathString); + pathData = pathArray.constData(); + + playlist = playlist_init(pathData, COLLECTION_SIZE); + playlistSize = playlist_get_size(playlist); + + for (i = 0; i < playlistSize; i++) + { + const char *path = NULL; + const char *label = NULL; + const char *core_path = NULL; + const char *core_name = NULL; + const char *crc32 = NULL; + const char *db_name = NULL; + QHash hash; + + playlist_get_index(playlist, i, + &path, &label, &core_path, + &core_name, &crc32, &db_name); + + if (string_is_empty(path)) + continue; + else + hash["path"] = path; + + hash["index"] = QString::number(i); + + if (string_is_empty(label)) + { + hash["label"] = path; + hash["label_noext"] = path; + } + else + { + hash["label"] = label; + hash["label_noext"] = label; + } + + if (!string_is_empty(core_path)) + hash["core_path"] = core_path; + + if (!string_is_empty(core_name)) + hash["core_name"] = core_name; + + if (!string_is_empty(crc32)) + hash["crc32"] = crc32; + + if (!string_is_empty(db_name)) + { + hash["db_name"] = db_name; + hash["db_name"].remove(file_path_str(FILE_PATH_LPL_EXTENSION)); + } + + items.append(hash); + } + + playlist_free(playlist); + playlist = NULL; + + return items; +} + +void MainWindow::addPlaylistItemsToTable(const QStringList &paths, bool add) +{ + QVector > items; + int i; + + if (paths.isEmpty()) + return; + + for (i = 0; i < paths.size(); i++) + { + int j; + QVector > vec = getPlaylistItems(paths.at(i)); + /* QVector::append() wasn't added until 5.5, so just do it the old fashioned way */ + for (j = 0; j < vec.size(); j++) + { + if (add && m_allPlaylistsListMaxCount > 0 && items.size() >= m_allPlaylistsListMaxCount) + goto finish; + + items.append(vec.at(j)); + } + } +finish: + addPlaylistHashToTable(items); +} + +void MainWindow::addPlaylistHashToTable(const QVector > &items) +{ + int i = 0; + int oldRowCount = m_tableWidget->rowCount(); + + m_tableWidget->setRowCount(oldRowCount + items.count()); + + for (i = 0; i < items.count(); i++) + { + QTableWidgetItem *labelItem = NULL; + const QHash &hash = items.at(i); + + labelItem = new QTableWidgetItem(hash.value("label")); + labelItem->setData(Qt::UserRole, QVariant::fromValue >(hash)); + labelItem->setFlags(labelItem->flags() & ~Qt::ItemIsEditable); + + m_tableWidget->setItem(oldRowCount + i, 0, labelItem); + } +} + +void MainWindow::setAllPlaylistsListMaxCount(int count) +{ + if (count < 1) + count = 0; + + m_allPlaylistsListMaxCount = count; +} + +void MainWindow::setAllPlaylistsGridMaxCount(int count) +{ + if (count < 1) + count = 0; + + m_allPlaylistsGridMaxCount = count; +} + diff --git a/ui/drivers/qt/playlistentrydialog.cpp b/ui/drivers/qt/playlistentrydialog.cpp new file mode 100644 index 0000000000..d28dcf4000 --- /dev/null +++ b/ui/drivers/qt/playlistentrydialog.cpp @@ -0,0 +1,259 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "playlistentrydialog.h" +#include "../ui_qt.h" + +extern "C" { +#include "../../../core_info.h" +#include "../../../file_path_special.h" +} + +inline static bool comp_string_lower(const QString &lhs, const QString &rhs) +{ + return lhs.toLower() < rhs.toLower(); +} + +inline static bool comp_hash_ui_display_name_key_lower(const QHash &lhs, const QHash &rhs) +{ + return lhs.value("ui_display_name").toLower() < rhs.value("ui_display_name").toLower(); +} + +PlaylistEntryDialog::PlaylistEntryDialog(MainWindow *mainwindow, QWidget *parent) : + QDialog(parent) + ,m_mainwindow(mainwindow) + ,m_settings(mainwindow->settings()) + ,m_nameLineEdit(new QLineEdit(this)) + ,m_pathLineEdit(new QLineEdit(this)) + ,m_coreComboBox(new QComboBox(this)) + ,m_databaseComboBox(new QComboBox(this)) +{ + QFormLayout *form = new QFormLayout(); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + QVBoxLayout *databaseVBoxLayout = new QVBoxLayout(); + QHBoxLayout *pathHBoxLayout = new QHBoxLayout(); + QLabel *databaseLabel = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FOR_THUMBNAILS), this); + QToolButton *pathPushButton = new QToolButton(this); + + pathPushButton->setText("..."); + + pathHBoxLayout->addWidget(m_pathLineEdit); + pathHBoxLayout->addWidget(pathPushButton); + + databaseVBoxLayout->addWidget(m_databaseComboBox); + databaseVBoxLayout->addWidget(databaseLabel); + + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY)); + + form->setFormAlignment(Qt::AlignCenter); + form->setLabelAlignment(Qt::AlignCenter); + + setLayout(new QVBoxLayout(this)); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + connect(this, SIGNAL(accepted()), this, SLOT(onAccepted())); + connect(this, SIGNAL(rejected()), this, SLOT(onRejected())); + + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_NAME), m_nameLineEdit); + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_PATH), pathHBoxLayout); + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_CORE), m_coreComboBox); + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_DATABASE), databaseVBoxLayout); + + qobject_cast(layout())->addLayout(form); + layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); + layout()->addWidget(buttonBox); + + connect(pathPushButton, SIGNAL(clicked()), this, SLOT(onPathClicked())); +} + +void PlaylistEntryDialog::onPathClicked() +{ + QString filePath = QFileDialog::getOpenFileName(this); + + if (filePath.isEmpty()) + return; + + m_pathLineEdit->setText(filePath); +} + +void PlaylistEntryDialog::loadPlaylistOptions() +{ + core_info_list_t *core_info_list = NULL; + const core_info_t *core_info = NULL; + unsigned i = 0; + int j = 0; + + m_nameLineEdit->clear(); + m_pathLineEdit->clear(); + m_coreComboBox->clear(); + m_databaseComboBox->clear(); + + m_coreComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CORE_SELECTION_ASK)); + m_databaseComboBox->addItem(QString("<") + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE) + ">", QFileInfo(m_mainwindow->getCurrentPlaylistPath()).fileName().remove(file_path_str(FILE_PATH_LPL_EXTENSION))); + + core_info_get_list(&core_info_list); + + if (core_info_list && core_info_list->count > 0) + { + QVector > allCores; + QStringList allDatabases; + + for (i = 0; i < core_info_list->count; i++) + { + const core_info_t *core = &core_info_list->list[i]; + QStringList databases = QString(core->databases).split("|"); + QHash hash; + QString ui_display_name; + + hash["core_name"] = core->core_name; + hash["core_display_name"] = core->display_name; + hash["core_path"] = core->path; + hash["core_databases"] = core->databases; + + ui_display_name = hash.value("core_name"); + + if (ui_display_name.isEmpty()) + ui_display_name = hash.value("core_display_name"); + if (ui_display_name.isEmpty()) + ui_display_name = QFileInfo(hash.value("core_path")).fileName(); + if (ui_display_name.isEmpty()) + continue; + + hash["ui_display_name"] = ui_display_name; + + for (j = 0; j < databases.count(); j++) + { + QString database = databases.at(j); + + if (database.isEmpty()) + continue; + + if (!allDatabases.contains(database)) + allDatabases.append(database); + } + + if (!allCores.contains(hash)) + allCores.append(hash); + } + + std::sort(allCores.begin(), allCores.end(), comp_hash_ui_display_name_key_lower); + std::sort(allDatabases.begin(), allDatabases.end(), comp_string_lower); + + for (j = 0; j < allCores.count(); j++) + { + const QHash &hash = allCores.at(j); + + m_coreComboBox->addItem(hash.value("ui_display_name"), QVariant::fromValue(hash)); + } + + for (j = 0; j < allDatabases.count(); j++) + { + QString database = allDatabases.at(j); + m_databaseComboBox->addItem(database, database); + } + } +} + +void PlaylistEntryDialog::setEntryValues(const QHash &contentHash) +{ + QString db; + QString coreName = contentHash.value("core_name"); + int foundDB = 0; + int i = 0; + + loadPlaylistOptions(); + + if (contentHash.isEmpty()) + { + m_nameLineEdit->setText(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FIELD_MULTIPLE)); + m_pathLineEdit->setText(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FIELD_MULTIPLE)); + m_nameLineEdit->setEnabled(false); + m_pathLineEdit->setEnabled(false); + } + else + { + m_nameLineEdit->setEnabled(true); + m_pathLineEdit->setEnabled(true); + m_nameLineEdit->setText(contentHash.value("label")); + m_pathLineEdit->setText(contentHash.value("path")); + } + + for (i = 0; i < m_coreComboBox->count(); i++) + { + const QHash hash = m_coreComboBox->itemData(i, Qt::UserRole).value >(); + + if (hash.isEmpty() || coreName.isEmpty()) + continue; + + if (hash.value("core_name") == coreName) + { + m_coreComboBox->setCurrentIndex(i); + break; + } + } + + db = contentHash.value("db_name"); + + if (!db.isEmpty()) + { + foundDB = m_databaseComboBox->findText(db); + + if (foundDB >= 0) + m_databaseComboBox->setCurrentIndex(foundDB); + } +} + +const QHash PlaylistEntryDialog::getSelectedCore() +{ + return m_coreComboBox->currentData(Qt::UserRole).value >(); +} + +const QString PlaylistEntryDialog::getSelectedName() +{ + return m_nameLineEdit->text(); +} + +const QString PlaylistEntryDialog::getSelectedPath() +{ + return m_pathLineEdit->text(); +} + +const QString PlaylistEntryDialog::getSelectedDatabase() +{ + return m_databaseComboBox->currentData(Qt::UserRole).toString(); +} + +void PlaylistEntryDialog::onAccepted() +{ +} + +void PlaylistEntryDialog::onRejected() +{ +} + +bool PlaylistEntryDialog::showDialog(const QHash &hash) +{ + loadPlaylistOptions(); + setEntryValues(hash); + + if (exec() == QDialog::Accepted) + return true; + + return false; +} + +void PlaylistEntryDialog::hideDialog() +{ + reject(); +} + diff --git a/ui/drivers/qt/playlistentrydialog.h b/ui/drivers/qt/playlistentrydialog.h new file mode 100644 index 0000000000..723f46304e --- /dev/null +++ b/ui/drivers/qt/playlistentrydialog.h @@ -0,0 +1,39 @@ +#ifndef PLAYLISTENTRYDIALOG_H +#define PLAYLISTENTRYDIALOG_H + +#include + +class QSettings; +class QLineEdit; +class QComboBox; +class MainWindow; + +class PlaylistEntryDialog : public QDialog +{ + Q_OBJECT +public: + PlaylistEntryDialog(MainWindow *mainwindow, QWidget *parent = 0); + const QHash getSelectedCore(); + const QString getSelectedDatabase(); + const QString getSelectedName(); + const QString getSelectedPath(); + void setEntryValues(const QHash &contentHash); +public slots: + bool showDialog(const QHash &hash = QHash()); + void hideDialog(); + void onAccepted(); + void onRejected(); +private slots: + void onPathClicked(); +private: + void loadPlaylistOptions(); + + MainWindow *m_mainwindow; + QSettings *m_settings; + QLineEdit *m_nameLineEdit; + QLineEdit *m_pathLineEdit; + QComboBox *m_coreComboBox; + QComboBox *m_databaseComboBox; +}; + +#endif diff --git a/ui/drivers/qt/playlistthumbnaildownload.cpp b/ui/drivers/qt/playlistthumbnaildownload.cpp new file mode 100644 index 0000000000..52e4b86677 --- /dev/null +++ b/ui/drivers/qt/playlistthumbnaildownload.cpp @@ -0,0 +1,343 @@ +#include +#include +#include + +#include "../ui_qt.h" + +extern "C" { +#include +#include +#include +#include "../../../tasks/tasks_internal.h" +#include "../../../verbosity.h" +#include "../../../config.def.h" +#include "../../../configuration.h" +#include "../../../version.h" +} + +#define USER_AGENT "RetroArch-WIMP/" PACKAGE_VERSION +#define PARTIAL_EXTENSION ".partial" +#define THUMBNAIL_URL_HEADER "https://github.com/libretro-thumbnails/" +#define THUMBNAIL_URL_BRANCH "/blob/master/" +#define THUMBNAIL_IMAGE_EXTENSION ".png" +#define THUMBNAIL_URL_FOOTER THUMBNAIL_IMAGE_EXTENSION "?raw=true" + +void MainWindow::onPlaylistThumbnailDownloadNetworkError(QNetworkReply::NetworkError /*code*/) +{ +} + +void MainWindow::onPlaylistThumbnailDownloadNetworkSslErrors(const QList &errors) +{ + QNetworkReply *reply = m_playlistThumbnailDownloadReply.data(); + int i; + + if (!reply) + return; + + for (i = 0; i < errors.count(); i++) + { + const QSslError &error = errors.at(i); + QString string = QString("Ignoring SSL error code ") + QString::number(error.error()) + ": " + error.errorString(); + QByteArray stringArray = string.toUtf8(); + const char *stringData = stringArray.constData(); + RARCH_ERR("[Qt]: %s\n", stringData); + } + + /* ignore all SSL errors for now, like self-signed, expired etc. */ + reply->ignoreSslErrors(); +} + +void MainWindow::onPlaylistThumbnailDownloadCanceled() +{ + m_playlistThumbnailDownloadProgressDialog->cancel(); + m_playlistThumbnailDownloadWasCanceled = true; + RARCH_LOG("[Qt]: Playlist thumbnail download was canceled.\n"); +} + +void MainWindow::onPlaylistThumbnailDownloadFinished() +{ + QString playlistPath; + QNetworkReply *reply = m_playlistThumbnailDownloadReply.data(); + QNetworkReply::NetworkError error; + int code; + + if (!reply) + return; + + playlistPath = reply->property("playlist").toString(); + + error = reply->error(); + code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (m_playlistThumbnailDownloadFile.isOpen()) + m_playlistThumbnailDownloadFile.close(); + + if (code != 200) + { + QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + + if (!redirectUrl.isEmpty()) + { + QByteArray redirectUrlArray = redirectUrl.toString().toUtf8(); + const char *redirectUrlData = redirectUrlArray.constData(); + + /*RARCH_LOG("[Qt]: Thumbnail download got redirect with HTTP code %d: %s\n", code, redirectUrlData);*/ + + reply->disconnect(); + reply->abort(); + reply->deleteLater(); + + downloadNextPlaylistThumbnail(reply->property("system").toString(), reply->property("title").toString(), reply->property("type").toString(), redirectUrl); + + return; + } + else + { + m_playlistThumbnailDownloadFile.remove(); + + m_failedThumbnails++; + + /*emit showErrorMessageDeferred(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR)) + ": HTTP Code " + QString::number(code)); + + RARCH_ERR("[Qt]: Thumbnail download failed with HTTP status code: %d\n", code); + + reply->disconnect(); + reply->abort(); + reply->deleteLater(); + + return;*/ + } + } + + if (error == QNetworkReply::NoError) + { + int index = m_playlistThumbnailDownloadFile.fileName().lastIndexOf(PARTIAL_EXTENSION); + QString newFileName = m_playlistThumbnailDownloadFile.fileName().left(index); + QFile newFile(newFileName); + + /* rename() requires the old file to be deleted first if it exists */ + if (newFile.exists() && !newFile.remove()) + { + m_failedThumbnails++; + RARCH_ERR("[Qt]: Thumbnail download finished, but old file could not be deleted.\n"); + } + else + { + if (m_playlistThumbnailDownloadFile.rename(newFileName)) + { + /*RARCH_LOG("[Qt]: Thumbnail download finished successfully.\n");*/ + m_downloadedThumbnails++; + } + else + { + /*RARCH_ERR("[Qt]: Thumbnail download finished, but temp file could not be renamed.\n"); + emit showErrorMessageDeferred(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_RENAME_FILE));*/ + m_failedThumbnails++; + } + } + } + else + { + /*QByteArray errorArray = reply->errorString().toUtf8(); + const char *errorData = errorArray.constData();*/ + + m_playlistThumbnailDownloadFile.remove(); + + m_failedThumbnails++; + + /*RARCH_ERR("[Qt]: Thumbnail download ended prematurely: %s\n", errorData); + emit showErrorMessageDeferred(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR)) + ": Code " + QString::number(code) + ": " + errorData);*/ + } + + if (!m_playlistThumbnailDownloadWasCanceled && m_pendingPlaylistThumbnails.count() > 0) + { + QHash nextThumbnail = m_pendingPlaylistThumbnails.takeAt(0); + ViewType viewType = getCurrentViewType(); + + if (viewType == VIEW_TYPE_ICONS) + emit gridItemChanged(reply->property("title").toString()); + + downloadNextPlaylistThumbnail(nextThumbnail.value("db_name"), nextThumbnail.value("label_noext"), nextThumbnail.value("type")); + } + else + { + RARCH_LOG("[Qt]: Playlist thumbnails finished downloading.\n"); + /* update thumbnail */ + emit itemChanged(); + } + + reply->disconnect(); + reply->close(); + reply->deleteLater(); +} + +void MainWindow::onPlaylistThumbnailDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) +{ + QNetworkReply *reply = m_playlistThumbnailDownloadReply.data(); + int progress = (bytesReceived / (float)bytesTotal) * 100.0f; + + if (!reply) + return; +} + +void MainWindow::onPlaylistThumbnailDownloadReadyRead() +{ + QNetworkReply *reply = m_playlistThumbnailDownloadReply.data(); + + if (!reply) + return; + + m_playlistThumbnailDownloadFile.write(reply->readAll()); +} + +void MainWindow::downloadNextPlaylistThumbnail(QString system, QString title, QString type, QUrl url) +{ + QString systemUnderscore = system; + QString urlString; + QNetworkReply *reply = NULL; + QNetworkRequest request; + settings_t *settings = config_get_ptr(); + + if (!settings) + return; + + title = getScrubbedString(title); + systemUnderscore = systemUnderscore.replace(" ", "_"); + + urlString = QString(THUMBNAIL_URL_HEADER) + systemUnderscore + THUMBNAIL_URL_BRANCH + type + "/" + title + THUMBNAIL_URL_FOOTER; + + if (url.isEmpty()) + url = urlString; + + request.setUrl(url); + + if (m_playlistThumbnailDownloadFile.isOpen()) + { + RARCH_ERR("[Qt]: File is already open.\n"); + return; + } + else + { + QString dirString = QString(settings->paths.directory_thumbnails); + QString fileName = dirString + "/" + system + "/" + type + "/" + title + THUMBNAIL_IMAGE_EXTENSION + PARTIAL_EXTENSION; + QByteArray fileNameArray = fileName.toUtf8(); + QDir dir; + const char *fileNameData = fileNameArray.constData(); + + dir.mkpath(dirString + "/" + system + "/" + THUMBNAIL_BOXART); + dir.mkpath(dirString + "/" + system + "/" + THUMBNAIL_SCREENSHOT); + dir.mkpath(dirString + "/" + system + "/" + THUMBNAIL_TITLE); + + m_playlistThumbnailDownloadFile.setFileName(fileName); + + if (!m_playlistThumbnailDownloadFile.open(QIODevice::WriteOnly)) + { + m_failedThumbnails++; + + RARCH_ERR("[Qt]: Could not open file for writing: %s\n", fileNameData); + + if (m_pendingPlaylistThumbnails.count() > 0) + { + QHash nextThumbnail = m_pendingPlaylistThumbnails.takeAt(0); + downloadNextPlaylistThumbnail(nextThumbnail.value("db_name"), nextThumbnail.value("label_noext"), nextThumbnail.value("type")); + } + else + m_playlistThumbnailDownloadProgressDialog->cancel(); + + return; + } + } + + /*RARCH_LOG("[Qt]: Starting thumbnail download...\n"); + RARCH_LOG("[Qt]: Downloading URL %s\n", urlData);*/ + + request.setHeader(QNetworkRequest::UserAgentHeader, USER_AGENT); + + m_playlistThumbnailDownloadReply = m_networkManager->get(request); + + reply = m_playlistThumbnailDownloadReply.data(); + reply->setProperty("system", system); + reply->setProperty("title", title); + reply->setProperty("type", type); + + /* make sure any previous connection is removed first */ + disconnect(m_playlistThumbnailDownloadProgressDialog, SIGNAL(canceled()), reply, SLOT(abort())); + connect(m_playlistThumbnailDownloadProgressDialog, SIGNAL(canceled()), reply, SLOT(abort())); + + connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onPlaylistThumbnailDownloadNetworkError(QNetworkReply::NetworkError))); + connect(reply, SIGNAL(sslErrors(const QList&)), this, SLOT(onPlaylistThumbnailDownloadNetworkSslErrors(const QList&))); + connect(reply, SIGNAL(finished()), this, SLOT(onPlaylistThumbnailDownloadFinished())); + connect(reply, SIGNAL(readyRead()), this, SLOT(onPlaylistThumbnailDownloadReadyRead())); + connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(onPlaylistThumbnailDownloadProgress(qint64, qint64))); + + m_playlistThumbnailDownloadProgressDialog->setValue(m_playlistThumbnailDownloadProgressDialog->maximum() - m_pendingPlaylistThumbnails.count()); + + { + QString labelText = QString(msg_hash_to_str(MSG_DOWNLOADING)) + "...\n"; + + labelText += QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_PLAYLIST_THUMBNAIL_PROGRESS)).arg(m_downloadedThumbnails).arg(m_failedThumbnails); + + m_playlistThumbnailDownloadProgressDialog->setLabelText(labelText); + } +} + +void MainWindow::downloadPlaylistThumbnails(QString playlistPath) +{ + QFile playlistFile(playlistPath); + QString system; + QString title; + QString type; + QVector > playlistItems = getPlaylistItems(playlistPath); + settings_t *settings = config_get_ptr(); + int i; + + if (!settings || !playlistFile.exists()) + return; + + m_pendingPlaylistThumbnails.clear(); + m_downloadedThumbnails = 0; + m_failedThumbnails = 0; + m_playlistThumbnailDownloadWasCanceled = false; + + if (playlistItems.count() == 0) + return; + + for (i = 0; i < playlistItems.count(); i++) + { + const QHash &itemHash = playlistItems.at(i); + QHash hash; + QHash hash2; + QHash hash3; + + hash["db_name"] = itemHash.value("db_name"); + hash["label_noext"] = itemHash.value("label_noext"); + hash["type"] = THUMBNAIL_BOXART; + + hash2 = hash; + hash3 = hash; + + hash2["type"] = THUMBNAIL_SCREENSHOT; + hash3["type"] = THUMBNAIL_TITLE; + + m_pendingPlaylistThumbnails.append(hash); + m_pendingPlaylistThumbnails.append(hash2); + m_pendingPlaylistThumbnails.append(hash3); + } + + m_playlistThumbnailDownloadProgressDialog->setWindowModality(Qt::NonModal); + m_playlistThumbnailDownloadProgressDialog->setMinimumDuration(0); + m_playlistThumbnailDownloadProgressDialog->setRange(0, m_pendingPlaylistThumbnails.count()); + m_playlistThumbnailDownloadProgressDialog->setAutoClose(true); + m_playlistThumbnailDownloadProgressDialog->setAutoReset(true); + m_playlistThumbnailDownloadProgressDialog->setValue(0); + m_playlistThumbnailDownloadProgressDialog->setLabelText(QString(msg_hash_to_str(MSG_DOWNLOADING)) + "..."); + m_playlistThumbnailDownloadProgressDialog->setCancelButtonText(tr("Cancel")); + m_playlistThumbnailDownloadProgressDialog->show(); + + { + QHash firstThumbnail = m_pendingPlaylistThumbnails.takeAt(0); + + /* Start downloading the first thumbnail, the rest will download as each one finishes. */ + downloadNextPlaylistThumbnail(firstThumbnail.value("db_name"), firstThumbnail.value("label_noext"), firstThumbnail.value("type")); + } +} diff --git a/ui/drivers/qt/shaderparamsdialog.cpp b/ui/drivers/qt/shaderparamsdialog.cpp new file mode 100644 index 0000000000..cffcd85498 --- /dev/null +++ b/ui/drivers/qt/shaderparamsdialog.cpp @@ -0,0 +1,1601 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "shaderparamsdialog.h" +#include "../ui_qt.h" + +extern "C" { +#include +#include +#include +#include "../../../command.h" +#include "../../../configuration.h" +#include "../../../retroarch.h" +#include "../../../paths.h" +#include "../../../file_path_special.h" +#ifdef HAVE_MENU +#include "../../../menu/menu_shader.h" +#endif +} + +enum +{ + SHADER_PRESET_SAVE_CORE = 0, + SHADER_PRESET_SAVE_GAME, + SHADER_PRESET_SAVE_PARENT, + SHADER_PRESET_SAVE_NORMAL +}; + +ShaderPass::ShaderPass(struct video_shader_pass *passToCopy) : + pass(NULL) +{ + if (passToCopy) + { + pass = (struct video_shader_pass*)calloc(1, sizeof(*pass)); + memcpy(pass, passToCopy, sizeof(*pass)); + } +} + +ShaderPass::~ShaderPass() +{ + if (pass) + free(pass); +} + +ShaderPass& ShaderPass::operator=(const ShaderPass &other) +{ + if (this != &other && other.pass) + { + pass = (struct video_shader_pass*)calloc(1, sizeof(*pass)); + memcpy(pass, other.pass, sizeof(*pass)); + } + + return *this; +} + +ShaderParamsDialog::ShaderParamsDialog(QWidget *parent) : + QDialog(parent) + ,m_layout() + ,m_scrollArea() +{ + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS)); + setObjectName("shaderParamsDialog"); + + resize(720, 480); + + QTimer::singleShot(0, this, SLOT(clearLayout())); +} + +ShaderParamsDialog::~ShaderParamsDialog() +{ +} + +void ShaderParamsDialog::resizeEvent(QResizeEvent *event) +{ + QDialog::resizeEvent(event); + + if (!m_scrollArea) + return; + + m_scrollArea->resize(event->size()); + + emit resized(event->size()); +} + +void ShaderParamsDialog::closeEvent(QCloseEvent *event) +{ + QDialog::closeEvent(event); + + emit closed(); +} + +void ShaderParamsDialog::paintEvent(QPaintEvent *event) +{ + QStyleOption o; + QPainter p; + o.initFrom(this); + p.begin(this); + style()->drawPrimitive( + QStyle::PE_Widget, &o, &p, this); + p.end(); + + QDialog::paintEvent(event); +} + +QString ShaderParamsDialog::getFilterLabel(unsigned filter) +{ + QString filterString; + + switch (filter) + { + case 0: + filterString = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DONT_CARE); + break; + case 1: + filterString = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LINEAR); + break; + case 2: + filterString = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NEAREST); + break; + default: + break; + } + + return filterString; +} + +void ShaderParamsDialog::clearLayout() +{ + QWidget *widget = NULL; + + if (m_scrollArea) + { + foreach (QObject *obj, children()) + { + obj->deleteLater(); + } + } + + m_layout = new QVBoxLayout(); + + widget = new QWidget(); + widget->setLayout(m_layout); + widget->setObjectName("shaderParamsWidget"); + + m_scrollArea = new QScrollArea(); + + m_scrollArea->setParent(this); + m_scrollArea->setWidgetResizable(true); + m_scrollArea->setWidget(widget); + m_scrollArea->setObjectName("shaderParamsScrollArea"); + m_scrollArea->show(); +} + +void ShaderParamsDialog::getShaders(struct video_shader **menu_shader, struct video_shader **video_shader) +{ + video_shader_ctx_t shader_info = {0}; +#ifdef HAVE_MENU + struct video_shader *shader = menu_shader_get(); + + if (menu_shader) + { + if (shader) + { + *menu_shader = shader; + } + else + { + *menu_shader = NULL; + } + } + + if (video_shader) + { + if (shader) + { + *video_shader = shader_info.data; + } + else + { + *video_shader = NULL; + } + } +#endif + + if (video_shader) + { + if (!video_shader_driver_get_current_shader(&shader_info)) + { + *video_shader = NULL; + return; + } + + if (!shader_info.data || shader_info.data->num_parameters > GFX_MAX_PARAMETERS) + { + *video_shader = NULL; + return; + } + + if (shader_info.data) + { + *video_shader = shader_info.data; + } + else + { + *video_shader = NULL; + } + } +} + +void ShaderParamsDialog::onFilterComboBoxIndexChanged(int) +{ + QComboBox *comboBox = qobject_cast(sender()); + QVariant passVariant; + int pass = 0; + bool ok = false; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + + getShaders(&menu_shader, &video_shader); + + if (!comboBox) + return; + + passVariant = comboBox->property("pass"); + + if (!passVariant.isValid()) + return; + + pass = passVariant.toInt(&ok); + + if (!ok) + return; + + if (menu_shader && pass >= 0 && pass < static_cast(menu_shader->passes)) + { + QVariant data = comboBox->currentData(); + + if (data.isValid()) + { + unsigned filter = data.toUInt(&ok); + + if (ok) + { + if (menu_shader) + menu_shader->pass[pass].filter = filter; + if (video_shader) + video_shader->pass[pass].filter = filter; + + command_event(CMD_EVENT_SHADERS_APPLY_CHANGES, NULL); + } + } + } +} + +void ShaderParamsDialog::onScaleComboBoxIndexChanged(int) +{ + QComboBox *comboBox = qobject_cast(sender()); + QVariant passVariant; + int pass = 0; + bool ok = false; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + + getShaders(&menu_shader, &video_shader); + + if (!comboBox) + return; + + passVariant = comboBox->property("pass"); + + if (!passVariant.isValid()) + return; + + pass = passVariant.toInt(&ok); + + if (!ok) + return; + + if (menu_shader && pass >= 0 && pass < static_cast(menu_shader->passes)) + { + QVariant data = comboBox->currentData(); + + if (data.isValid()) + { + unsigned scale = data.toUInt(&ok); + + if (ok) + { + if (menu_shader) + { + menu_shader->pass[pass].fbo.scale_x = scale; + menu_shader->pass[pass].fbo.scale_y = scale; + menu_shader->pass[pass].fbo.valid = scale; + } + + if (video_shader) + { + video_shader->pass[pass].fbo.scale_x = scale; + video_shader->pass[pass].fbo.scale_y = scale; + video_shader->pass[pass].fbo.valid = scale; + } + + command_event(CMD_EVENT_SHADERS_APPLY_CHANGES, NULL); + } + } + } +} + +void ShaderParamsDialog::onShaderPassMoveDownClicked() +{ + QToolButton *button = qobject_cast(sender()); + QVariant passVariant; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + int pass = 0; + bool ok = false; + + getShaders(&menu_shader, &video_shader); + + if (!button) + return; + + passVariant = button->property("pass"); + + if (!passVariant.isValid()) + return; + + pass = passVariant.toInt(&ok); + + if (!ok) + return; + + if (pass < 0) + return; + + if (video_shader) + { + ShaderPass tempPass; + int i; + + if (pass >= static_cast(video_shader->passes) - 1) + return; + + for (i = 0; i < static_cast(video_shader->num_parameters); i++) + { + struct video_shader_parameter *param = &video_shader->parameters[i]; + + if (param->pass == pass) + { + param->pass += 1; + } + else if (param->pass == pass + 1) + { + param->pass -= 1; + } + } + + tempPass = ShaderPass(&video_shader->pass[pass]); + memcpy(&video_shader->pass[pass], &video_shader->pass[pass + 1], sizeof(struct video_shader_pass)); + memcpy(&video_shader->pass[pass + 1], tempPass.pass, sizeof(struct video_shader_pass)); + } + + if (menu_shader) + { + ShaderPass tempPass; + int i; + + if (pass >= static_cast(menu_shader->passes) - 1) + return; + + for (i = 0; i < static_cast(menu_shader->num_parameters); i++) + { + struct video_shader_parameter *param = &menu_shader->parameters[i]; + + if (param->pass == pass) + { + param->pass += 1; + } + else if (param->pass == pass + 1) + { + param->pass -= 1; + } + } + + tempPass = ShaderPass(&menu_shader->pass[pass]); + memcpy(&menu_shader->pass[pass], &menu_shader->pass[pass + 1], sizeof(struct video_shader_pass)); + memcpy(&menu_shader->pass[pass + 1], tempPass.pass, sizeof(struct video_shader_pass)); + } + + reload(); +} + +void ShaderParamsDialog::onShaderPassMoveUpClicked() +{ + QToolButton *button = qobject_cast(sender()); + QVariant passVariant; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + int pass = 0; + bool ok = false; + + getShaders(&menu_shader, &video_shader); + + if (!button) + return; + + passVariant = button->property("pass"); + + if (!passVariant.isValid()) + return; + + pass = passVariant.toInt(&ok); + + if (!ok) + return; + + if (pass <= 0) + return; + + if (video_shader) + { + ShaderPass tempPass; + int i; + + if (pass > static_cast(video_shader->passes) - 1) + return; + + for (i = 0; i < static_cast(video_shader->num_parameters); i++) + { + struct video_shader_parameter *param = &video_shader->parameters[i]; + + if (param->pass == pass) + { + param->pass -= 1; + } + else if (param->pass == pass - 1) + { + param->pass += 1; + } + } + + tempPass = ShaderPass(&video_shader->pass[pass - 1]); + memcpy(&video_shader->pass[pass - 1], &video_shader->pass[pass], sizeof(struct video_shader_pass)); + memcpy(&video_shader->pass[pass], tempPass.pass, sizeof(struct video_shader_pass)); + } + + if (menu_shader) + { + ShaderPass tempPass; + int i; + + if (pass > static_cast(menu_shader->passes) - 1) + return; + + for (i = 0; i < static_cast(menu_shader->num_parameters); i++) + { + struct video_shader_parameter *param = &menu_shader->parameters[i]; + + if (param->pass == pass) + { + param->pass -= 1; + } + else if (param->pass == pass - 1) + { + param->pass += 1; + } + } + + tempPass = ShaderPass(&menu_shader->pass[pass - 1]); + memcpy(&menu_shader->pass[pass - 1], &menu_shader->pass[pass], sizeof(struct video_shader_pass)); + memcpy(&menu_shader->pass[pass], tempPass.pass, sizeof(struct video_shader_pass)); + } + + reload(); +} + +void ShaderParamsDialog::onShaderLoadPresetClicked() +{ +#ifdef HAVE_MENU + QString path; + QString filter; + QByteArray pathArray; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + const char *pathData = NULL; + settings_t *settings = config_get_ptr(); + enum rarch_shader_type type = RARCH_SHADER_NONE; + bool is_preset = false; + + if (!settings) + return; + + getShaders(&menu_shader, &video_shader); + + if (!menu_shader) + return; + + filter = "Shader Preset ("; + + /* NOTE: Maybe we should have a way to get a list of all shader types instead of hard-coding this? */ + if (video_shader_is_supported(RARCH_SHADER_CG) && + video_shader_get_type_from_ext(file_path_str(FILE_PATH_CGP_EXTENSION), &is_preset) + != RARCH_SHADER_NONE) + filter += QLatin1Literal("*") + file_path_str(FILE_PATH_CGP_EXTENSION); + + if (video_shader_is_supported(RARCH_SHADER_GLSL) && + video_shader_get_type_from_ext(file_path_str(FILE_PATH_GLSLP_EXTENSION), &is_preset) + != RARCH_SHADER_NONE) + filter += QLatin1Literal(" *") + file_path_str(FILE_PATH_GLSLP_EXTENSION); + + if (video_shader_is_supported(RARCH_SHADER_SLANG) && + video_shader_get_type_from_ext(file_path_str(FILE_PATH_SLANGP_EXTENSION), &is_preset) + != RARCH_SHADER_NONE) + filter += QLatin1Literal(" *") + file_path_str(FILE_PATH_SLANGP_EXTENSION); + + filter += ")"; + + path = QFileDialog::getOpenFileName(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET), settings->paths.directory_video_shader, filter); + + if (path.isEmpty()) + return; + + pathArray = path.toUtf8(); + pathData = pathArray.constData(); + + type = video_shader_parse_type(pathData, RARCH_SHADER_NONE); + + menu_shader_manager_set_preset(menu_shader, type, pathData); +#endif +} + +void ShaderParamsDialog::onShaderResetPass(int pass) +{ + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + unsigned i; + + getShaders(&menu_shader, &video_shader); + + if (menu_shader) + { + for (i = 0; i < menu_shader->num_parameters; i++) + { + struct video_shader_parameter *param = &menu_shader->parameters[i]; + + /* if pass < 0, reset all params, otherwise only reset the selected pass */ + if (pass >= 0 && param->pass != pass) + continue; + + param->current = param->initial; + } + } + + if (video_shader) + { + for (i = 0; i < video_shader->num_parameters; i++) + { + struct video_shader_parameter *param = &video_shader->parameters[i]; + + /* if pass < 0, reset all params, otherwise only reset the selected pass */ + if (pass >= 0 && param->pass != pass) + continue; + + param->current = param->initial; + } + } + + reload(); +} + +void ShaderParamsDialog::onShaderResetParameter(QString parameter) +{ + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + unsigned i; + + getShaders(&menu_shader, &video_shader); + + if (menu_shader) + { + struct video_shader_parameter *param = NULL; + int i; + + for (i = 0; i < static_cast(menu_shader->num_parameters); i++) + { + QString id = menu_shader->parameters[i].id; + + if (id == parameter) + param = &menu_shader->parameters[i]; + } + + if (param) + param->current = param->initial; + } + + if (video_shader) + { + struct video_shader_parameter *param = NULL; + int i; + + for (i = 0; i < static_cast(video_shader->num_parameters); i++) + { + QString id = video_shader->parameters[i].id; + + if (id == parameter) + param = &video_shader->parameters[i]; + } + + if (param) + param->current = param->initial; + } + + reload(); +} + +void ShaderParamsDialog::onShaderResetAllPasses() +{ + onShaderResetPass(-1); +} + +void ShaderParamsDialog::onShaderAddPassClicked() +{ +#ifdef HAVE_MENU + QString path; + QString filter; + QByteArray pathArray; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + struct video_shader_pass *shader_pass = NULL; + const char *pathData = NULL; + settings_t *settings = config_get_ptr(); + bool is_preset = false; + + if (!settings) + return; + + getShaders(&menu_shader, &video_shader); + + if (!menu_shader) + return; + + filter = "Shader ("; + + /* NOTE: Maybe we should have a way to get a list of all shader types instead of hard-coding this? */ + if (video_shader_is_supported(RARCH_SHADER_CG) && + video_shader_get_type_from_ext(".cg", &is_preset) + != RARCH_SHADER_NONE) + filter += QLatin1Literal("*.cg"); + + if (video_shader_is_supported(RARCH_SHADER_GLSL) && + video_shader_get_type_from_ext(".glsl", &is_preset) + != RARCH_SHADER_NONE) + filter += QLatin1Literal(" *.glsl"); + + if (video_shader_is_supported(RARCH_SHADER_SLANG) && + video_shader_get_type_from_ext(".slang", &is_preset) + != RARCH_SHADER_NONE) + filter += QLatin1Literal(" *.slang"); + + filter += ")"; + + path = QFileDialog::getOpenFileName(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET), settings->paths.directory_video_shader, filter); + + if (path.isEmpty()) + return; + + pathArray = path.toUtf8(); + pathData = pathArray.constData(); + + if (menu_shader->passes < GFX_MAX_SHADERS) + menu_shader_manager_increment_amount_passes(); + else + return; + + shader_pass = &menu_shader->pass[menu_shader->passes - 1]; + + if (!shader_pass) + return; + + strlcpy(shader_pass->source.path, pathData, sizeof(shader_pass->source.path)); + + video_shader_resolve_parameters(NULL, menu_shader); + + command_event(CMD_EVENT_SHADERS_APPLY_CHANGES, NULL); +#endif +} + +void ShaderParamsDialog::onShaderSavePresetAsClicked() +{ +#ifdef HAVE_MENU + settings_t *settings = config_get_ptr(); + QString path; + QByteArray pathArray; + const char *pathData = NULL; + + path = QFileDialog::getSaveFileName(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS), settings->paths.directory_video_shader); + + if (path.isEmpty()) + return; + + pathArray = path.toUtf8(); + pathData = pathArray.constData(); + + saveShaderPreset(pathData, SHADER_PRESET_SAVE_NORMAL); +#endif +} + +void ShaderParamsDialog::saveShaderPreset(const char *path, unsigned action_type) +{ + char directory[PATH_MAX_LENGTH]; + char file[PATH_MAX_LENGTH]; + char tmp[PATH_MAX_LENGTH]; + settings_t *settings = config_get_ptr(); + const char *core_name = NULL; + rarch_system_info_t *info = runloop_get_system_info(); + + directory[0] = file[0] = tmp[0] = '\0'; + + if (info) + core_name = info->info.library_name; + + if (!string_is_empty(core_name)) + { + fill_pathname_join( + tmp, + settings->paths.directory_video_shader, + "presets", + sizeof(tmp)); + fill_pathname_join( + directory, + tmp, + core_name, + sizeof(directory)); + } + + if (!filestream_exists(directory)) + path_mkdir(directory); + + switch (action_type) + { + case SHADER_PRESET_SAVE_CORE: + if (!string_is_empty(core_name)) + fill_pathname_join(file, directory, core_name, sizeof(file)); + break; + case SHADER_PRESET_SAVE_GAME: + { + const char *game_name = path_basename(path_get(RARCH_PATH_BASENAME)); + fill_pathname_join(file, directory, game_name, sizeof(file)); + break; + } + case SHADER_PRESET_SAVE_PARENT: + { + fill_pathname_parent_dir_name(tmp, path_get(RARCH_PATH_BASENAME), sizeof(tmp)); + fill_pathname_join(file, directory, tmp, sizeof(file)); + break; + } + case SHADER_PRESET_SAVE_NORMAL: + default: + if (!string_is_empty(path)) + strlcpy(file, path, sizeof(file)); + break; + } + + if (menu_shader_manager_save_preset(file, false, true)) + runloop_msg_queue_push( + msg_hash_to_str(MSG_SHADER_PRESET_SAVED_SUCCESSFULLY), + 1, 100, true); + else + runloop_msg_queue_push( + msg_hash_to_str(MSG_ERROR_SAVING_SHADER_PRESET), + 1, 100, true); +} + +void ShaderParamsDialog::onShaderSaveCorePresetClicked() +{ + saveShaderPreset(NULL, SHADER_PRESET_SAVE_CORE); +} + +void ShaderParamsDialog::onShaderSaveParentPresetClicked() +{ + saveShaderPreset(NULL, SHADER_PRESET_SAVE_PARENT); +} + +void ShaderParamsDialog::onShaderSaveGamePresetClicked() +{ + saveShaderPreset(NULL, SHADER_PRESET_SAVE_GAME); +} + +void ShaderParamsDialog::onShaderClearAllPassesClicked() +{ +#ifdef HAVE_MENU + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + + getShaders(&menu_shader, &video_shader); + + if (!menu_shader) + return; + + while (menu_shader->passes > 0) + menu_shader_manager_decrement_amount_passes(); + + onShaderApplyClicked(); +#endif +} + +void ShaderParamsDialog::onShaderRemovePassClicked() +{ +#ifdef HAVE_MENU + QAction *action = qobject_cast(sender()); + QVariant passVariant; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + int pass = 0; + int i; + bool ok = false; + + getShaders(&menu_shader, &video_shader); + + if (!menu_shader || menu_shader->passes == 0 || !action) + return; + + passVariant = action->data(); + + if (!passVariant.isValid()) + return; + + pass = passVariant.toInt(&ok); + + if (!ok) + return; + + if (pass < 0 || pass > static_cast(menu_shader->passes)) + return; + + /* move selected pass to the bottom */ + for (i = pass; i < static_cast(menu_shader->passes) - 1; i++) + { + std::swap(menu_shader->pass[i], menu_shader->pass[i + 1]); + } + + menu_shader_manager_decrement_amount_passes(); + + onShaderApplyClicked(); +#endif +} + +void ShaderParamsDialog::onShaderApplyClicked() +{ + command_event(CMD_EVENT_SHADERS_APPLY_CHANGES, NULL); +} + +void ShaderParamsDialog::reload() +{ + buildLayout(); +} + +void ShaderParamsDialog::buildLayout() +{ + QPushButton *loadButton = NULL; + QPushButton *saveButton = NULL; + QPushButton *removeButton = NULL; + QPushButton *applyButton = NULL; + QHBoxLayout *topButtonLayout = NULL; + QMenu *loadMenu = NULL; + QMenu *saveMenu = NULL; + QMenu *removeMenu = NULL; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + struct video_shader *avail_shader = NULL; + const char *shader_path = NULL; + int i; + unsigned j; + bool hasPasses = false; + + getShaders(&menu_shader, &video_shader); + + /* NOTE: For some reason, menu_shader_get() returns a COPY of what get_current_shader() gives us. + * And if you want to be able to change shader settings/parameters from both the raster menu and + * Qt at the same time... you must change BOTH or one will overwrite the other. + * + * AND, during a context reset, video_shader will be NULL but not menu_shader, so don't totally bail + * just because video_shader is NULL. + * + * Someone please fix this mess. + */ + + if (video_shader) + { + avail_shader = video_shader; + + if (video_shader->passes == 0) + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS)); + } + /* Normally we'd only use video_shader, but the vulkan driver returns a NULL shader when there + * are zero passes, so just fall back to menu_shader. + */ + else if (menu_shader) + { + avail_shader = menu_shader; + + if (menu_shader->passes == 0) + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS)); + } + else + { + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS)); + + /* no shader is available yet, just keep retrying until it is */ + QTimer::singleShot(0, this, SLOT(buildLayout())); + return; + } + + clearLayout(); + + /* Only check video_shader for the path, menu_shader seems stale... e.g. if you remove all the shader passes, + * it still has the old path in it, but video_shader does not + */ + if (video_shader) + { + if (!string_is_empty(video_shader->path)) + { + shader_path = video_shader->path; + setWindowTitle(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CURRENT_SHADER)) + ": " + QFileInfo(shader_path).fileName()); + } + } + else if (menu_shader) + { + if (!string_is_empty(menu_shader->path)) + { + shader_path = menu_shader->path; + setWindowTitle(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CURRENT_SHADER)) + ": " + QFileInfo(shader_path).fileName()); + } + } + else + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS)); + + loadButton = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_LOAD), this); + saveButton = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SAVE), this); + removeButton = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_REMOVE), this); + applyButton = new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_APPLY), this); + + loadMenu = new QMenu(loadButton); + loadMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET), this, SLOT(onShaderLoadPresetClicked())); + loadMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SHADER_ADD_PASS), this, SLOT(onShaderAddPassClicked())); + + loadButton->setMenu(loadMenu); + + saveMenu = new QMenu(saveButton); + saveMenu->addAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS)) + "...", this, SLOT(onShaderSavePresetAsClicked())); + saveMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE), this, SLOT(onShaderSaveCorePresetClicked())); + saveMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_PARENT), this, SLOT(onShaderSaveParentPresetClicked())); + saveMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME), this, SLOT(onShaderSaveGamePresetClicked())); + + saveButton->setMenu(saveMenu); + + removeMenu = new QMenu(removeButton); + + /* When there are no passes, at least on first startup, it seems video_shader erroneously shows 1 pass, with an empty source file. + * So we use menu_shader instead for that. + */ + if (menu_shader) + { + for (i = 0; i < static_cast(menu_shader->passes); i++) + { + QFileInfo fileInfo(menu_shader->pass[i].source.path); + QString shaderBasename = fileInfo.completeBaseName(); + QAction *action = removeMenu->addAction(shaderBasename, this, SLOT(onShaderRemovePassClicked())); + + action->setData(i); + } + } + + removeMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SHADER_CLEAR_ALL_PASSES), this, SLOT(onShaderClearAllPassesClicked())); + + removeButton->setMenu(removeMenu); + + connect(applyButton, SIGNAL(clicked()), this, SLOT(onShaderApplyClicked())); + + topButtonLayout = new QHBoxLayout(); + topButtonLayout->addWidget(loadButton); + topButtonLayout->addWidget(saveButton); + topButtonLayout->addWidget(removeButton); + topButtonLayout->addWidget(applyButton); + + m_layout->addLayout(topButtonLayout); + + /* NOTE: We assume that parameters are always grouped in order by the pass number, e.g., all parameters for pass 0 come first, then params for pass 1, etc. */ + for (i = 0; avail_shader && i < static_cast(avail_shader->passes); i++) + { + QFormLayout *form = NULL; + QGroupBox *groupBox = NULL; + QFileInfo fileInfo(avail_shader->pass[i].source.path); + QString shaderBasename = fileInfo.completeBaseName(); + QHBoxLayout *filterScaleHBoxLayout = NULL; + QComboBox *filterComboBox = new QComboBox(this); + QComboBox *scaleComboBox = new QComboBox(this); + QToolButton *moveDownButton = NULL; + QToolButton *moveUpButton = NULL; + unsigned j = 0; + + /* Sometimes video_shader shows 1 pass with no source file, when there are really 0 passes. */ + if (shaderBasename.isEmpty()) + continue; + + hasPasses = true; + + filterComboBox->setProperty("pass", i); + scaleComboBox->setProperty("pass", i); + + moveDownButton = new QToolButton(this); + moveDownButton->setText("↓"); + moveDownButton->setProperty("pass", i); + + moveUpButton = new QToolButton(this); + moveUpButton->setText("↑"); + moveUpButton->setProperty("pass", i); + + /* Can't move down if we're already at the bottom. */ + if (i < static_cast(avail_shader->passes) - 1) + connect(moveDownButton, SIGNAL(clicked()), this, SLOT(onShaderPassMoveDownClicked())); + else + moveDownButton->setDisabled(true); + + /* Can't move up if we're already at the top. */ + if (i > 0) + connect(moveUpButton, SIGNAL(clicked()), this, SLOT(onShaderPassMoveUpClicked())); + else + moveUpButton->setDisabled(true); + + for (;;) + { + QString filterLabel = getFilterLabel(j); + + if (filterLabel.isEmpty()) + break; + + if (j == 0) + filterLabel = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DONT_CARE); + + filterComboBox->addItem(filterLabel, j); + + j++; + } + + for (j = 0; j < 7; j++) + { + QString label; + + if (j == 0) + label = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DONT_CARE); + else + label = QString::number(j) + "x"; + + scaleComboBox->addItem(label, j); + } + + filterComboBox->setCurrentIndex(static_cast(avail_shader->pass[i].filter)); + scaleComboBox->setCurrentIndex(static_cast(avail_shader->pass[i].fbo.scale_x)); + + /* connect the signals only after the initial index is set */ + connect(filterComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onFilterComboBoxIndexChanged(int))); + connect(scaleComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onScaleComboBoxIndexChanged(int))); + + form = new QFormLayout(); + groupBox = new QGroupBox(shaderBasename); + groupBox->setLayout(form); + groupBox->setProperty("pass", i); + groupBox->setContextMenuPolicy(Qt::CustomContextMenu); + + connect(groupBox, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(onGroupBoxContextMenuRequested(const QPoint&))); + + m_layout->addWidget(groupBox); + + filterScaleHBoxLayout = new QHBoxLayout(); + filterScaleHBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred)); + filterScaleHBoxLayout->addWidget(new QLabel(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FILTER)) + ":", this)); + filterScaleHBoxLayout->addWidget(filterComboBox); + filterScaleHBoxLayout->addWidget(new QLabel(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCALE)) + ":", this)); + filterScaleHBoxLayout->addWidget(scaleComboBox); + filterScaleHBoxLayout->addSpacerItem(new QSpacerItem(20, 0, QSizePolicy::Preferred, QSizePolicy::Preferred)); + + if (moveUpButton) + filterScaleHBoxLayout->addWidget(moveUpButton); + + if (moveDownButton) + filterScaleHBoxLayout->addWidget(moveDownButton); + + form->addRow("", filterScaleHBoxLayout); + + for (j = 0; j < avail_shader->num_parameters; j++) + { + struct video_shader_parameter *param = &avail_shader->parameters[j]; + + if (param->pass != i) + continue; + + addShaderParam(param, form); + } + } + + if (!hasPasses) + { + QLabel *noParamsLabel = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SHADER_NO_PASSES), this); + noParamsLabel->setAlignment(Qt::AlignCenter); + + m_layout->addWidget(noParamsLabel); + } + + m_layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + /* Why is this required?? The layout is corrupt without both resizes. */ + resize(width() + 1, height()); + show(); + resize(width() - 1, height()); +} + +void ShaderParamsDialog::onParameterLabelContextMenuRequested(const QPoint&) +{ + QLabel *label = NULL; + QPointer action; + QList actions; + QScopedPointer resetParamAction; + QVariant paramVariant; + QString parameter; + + label = qobject_cast(sender()); + + if (!label) + return; + + paramVariant = label->property("parameter"); + + if (!paramVariant.isValid()) + return; + + parameter = paramVariant.toString(); + + resetParamAction.reset(new QAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_RESET_PARAMETER), 0)); + + actions.append(resetParamAction.data()); + + action = QMenu::exec(actions, QCursor::pos(), NULL, label); + + if (!action) + return; + + if (action == resetParamAction.data()) + { + onShaderResetParameter(parameter); + } +} + +void ShaderParamsDialog::onGroupBoxContextMenuRequested(const QPoint&) +{ + QGroupBox *groupBox = NULL; + QPointer action; + QList actions; + QScopedPointer resetPassAction; + QScopedPointer resetAllPassesAction; + QVariant passVariant; + int pass = 0; + bool ok = false; + + groupBox = qobject_cast(sender()); + + if (!groupBox) + return; + + passVariant = groupBox->property("pass"); + + if (!passVariant.isValid()) + return; + + pass = passVariant.toInt(&ok); + + if (!ok) + return; + + resetPassAction.reset(new QAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_RESET_PASS), 0)); + resetAllPassesAction.reset(new QAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_RESET_ALL_PASSES), 0)); + + actions.append(resetPassAction.data()); + actions.append(resetAllPassesAction.data()); + + action = QMenu::exec(actions, QCursor::pos(), NULL, groupBox); + + if (!action) + return; + + if (action == resetPassAction.data()) + { + onShaderResetPass(pass); + } + else if (action == resetAllPassesAction.data()) + { + onShaderResetAllPasses(); + } +} + +void ShaderParamsDialog::addShaderParam(struct video_shader_parameter *param, QFormLayout *form) +{ + QString desc = param->desc; + QString parameter = param->id; + QLabel *label = new QLabel(desc); + + label->setProperty("parameter", parameter); + label->setContextMenuPolicy(Qt::CustomContextMenu); + + connect(label, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(onParameterLabelContextMenuRequested(const QPoint&))); + + if ((param->minimum == 0.0) + && (param->maximum + == (param->minimum + + param->step))) + { + /* option is basically a bool, so use a checkbox */ + QCheckBox *checkBox = new QCheckBox(this); + checkBox->setChecked(param->current == param->maximum ? true : false); + checkBox->setProperty("param", parameter); + + connect(checkBox, SIGNAL(clicked()), this, SLOT(onShaderParamCheckBoxClicked())); + + form->addRow(label, checkBox); + } + else + { + QDoubleSpinBox *doubleSpinBox = NULL; + QSpinBox *spinBox = NULL; + QHBoxLayout *box = new QHBoxLayout(); + QSlider *slider = new QSlider(Qt::Horizontal, this); + double value = MainWindow::lerp(param->minimum, param->maximum, 0, 100, param->current); + double intpart = 0; + bool stepIsFractional = modf(param->step, &intpart); + + slider->setRange(0, 100); + slider->setSingleStep(1); + slider->setValue(value); + slider->setProperty("param", parameter); + + struct video_shader *video_shader = NULL; + + getShaders(NULL, &video_shader); + + connect(slider, SIGNAL(valueChanged(int)), this, SLOT(onShaderParamSliderValueChanged(int))); + + box->addWidget(slider); + + if (stepIsFractional) + { + doubleSpinBox = new QDoubleSpinBox(this); + doubleSpinBox->setRange(param->minimum, param->maximum); + doubleSpinBox->setSingleStep(param->step); + doubleSpinBox->setValue(param->current); + doubleSpinBox->setProperty("slider", QVariant::fromValue(slider)); + slider->setProperty("doubleSpinBox", QVariant::fromValue(doubleSpinBox)); + + connect(doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onShaderParamDoubleSpinBoxValueChanged(double))); + + box->addWidget(doubleSpinBox); + } + else + { + spinBox = new QSpinBox(this); + spinBox->setRange(param->minimum, param->maximum); + spinBox->setSingleStep(param->step); + spinBox->setValue(param->current); + spinBox->setProperty("slider", QVariant::fromValue(slider)); + slider->setProperty("spinBox", QVariant::fromValue(spinBox)); + + connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(onShaderParamSpinBoxValueChanged(int))); + + box->addWidget(spinBox); + } + + form->addRow(label, box); + } +} + +void ShaderParamsDialog::onShaderParamCheckBoxClicked() +{ + QCheckBox *checkBox = qobject_cast(sender()); + QVariant paramVariant; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + + getShaders(&menu_shader, &video_shader); + + if (!checkBox) + return; + + if (menu_shader && menu_shader->passes == 0) + return; + + paramVariant = checkBox->property("param"); + + if (paramVariant.isValid()) + { + QString parameter = paramVariant.toString(); + bool ok = false; + + if (!ok) + return; + + if (menu_shader) + { + struct video_shader_parameter *param = NULL; + int i; + + for (i = 0; i < static_cast(menu_shader->num_parameters); i++) + { + QString id = menu_shader->parameters[i].id; + + if (id == parameter) + param = &menu_shader->parameters[i]; + } + + if (param) + param->current = (checkBox->isChecked() ? param->maximum : param->minimum); + } + + if (video_shader) + { + struct video_shader_parameter *param = NULL; + int i; + + for (i = 0; i < static_cast(video_shader->num_parameters); i++) + { + QString id = video_shader->parameters[i].id; + + if (id == parameter) + param = &video_shader->parameters[i]; + } + + if (param) + param->current = (checkBox->isChecked() ? param->maximum : param->minimum); + } + } +} + +void ShaderParamsDialog::onShaderParamSliderValueChanged(int) +{ + QVariant spinBoxVariant; + QVariant paramVariant; + QSlider *slider = qobject_cast(sender()); + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + double newValue = 0.0; + + getShaders(&menu_shader, &video_shader); + + if (!slider) + return; + + spinBoxVariant = slider->property("spinBox"); + paramVariant = slider->property("param"); + + if (paramVariant.isValid()) + { + QString parameter = paramVariant.toString(); + + if (menu_shader) + { + struct video_shader_parameter *param = NULL; + int i; + + for (i = 0; i < static_cast(menu_shader->num_parameters); i++) + { + QString id = menu_shader->parameters[i].id; + + if (id == parameter) + param = &menu_shader->parameters[i]; + } + + if (param) + { + newValue = MainWindow::lerp(0, 100, param->minimum, param->maximum, slider->value()); + param->current = newValue; + } + } + + if (video_shader) + { + struct video_shader_parameter *param = NULL; + int i; + + for (i = 0; i < static_cast(video_shader->num_parameters); i++) + { + QString id = video_shader->parameters[i].id; + + if (id == parameter) + param = &video_shader->parameters[i]; + } + + if (param) + { + newValue = MainWindow::lerp(0, 100, param->minimum, param->maximum, slider->value()); + param->current = newValue; + } + } + } + + if (spinBoxVariant.isValid()) + { + QSpinBox *spinBox = spinBoxVariant.value(); + + if (!spinBox) + return; + + spinBox->blockSignals(true); + spinBox->setValue(newValue); + spinBox->blockSignals(false); + } + else + { + QVariant doubleSpinBoxVariant = slider->property("doubleSpinBox"); + QDoubleSpinBox *doubleSpinBox = doubleSpinBoxVariant.value(); + + if (!doubleSpinBox) + return; + + doubleSpinBox->blockSignals(true); + doubleSpinBox->setValue(newValue); + doubleSpinBox->blockSignals(false); + } +} + +void ShaderParamsDialog::onShaderParamSpinBoxValueChanged(int value) +{ + QSpinBox *spinBox = qobject_cast(sender()); + QVariant sliderVariant; + QVariant paramVariant; + QSlider *slider = NULL; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + + getShaders(&menu_shader, &video_shader); + + if (!spinBox) + return; + + sliderVariant = spinBox->property("slider"); + + if (!sliderVariant.isValid()) + return; + + slider = sliderVariant.value(); + + if (!slider) + return; + + paramVariant = slider->property("param"); + + if (paramVariant.isValid()) + { + QString parameter = paramVariant.toString(); + + double newValue = 0.0; + + if (menu_shader) + { + struct video_shader_parameter *param = NULL; + int i; + + for (i = 0; i < static_cast(menu_shader->num_parameters); i++) + { + QString id = menu_shader->parameters[i].id; + + if (id == parameter) + param = &menu_shader->parameters[i]; + } + + if (param) + { + param->current = value; + newValue = MainWindow::lerp(param->minimum, param->maximum, 0, 100, param->current); + slider->blockSignals(true); + slider->setValue(newValue); + slider->blockSignals(false); + } + } + + if (video_shader) + { + struct video_shader_parameter *param = NULL; + int i; + + for (i = 0; i < static_cast(video_shader->num_parameters); i++) + { + QString id = video_shader->parameters[i].id; + + if (id == parameter) + param = &video_shader->parameters[i]; + } + + if (param) + { + param->current = value; + newValue = MainWindow::lerp(param->minimum, param->maximum, 0, 100, param->current); + slider->blockSignals(true); + slider->setValue(newValue); + slider->blockSignals(false); + } + } + } +} + +void ShaderParamsDialog::onShaderParamDoubleSpinBoxValueChanged(double value) +{ + QDoubleSpinBox *doubleSpinBox = qobject_cast(sender()); + QVariant sliderVariant; + QVariant paramVariant; + QSlider *slider = NULL; + struct video_shader *menu_shader = NULL; + struct video_shader *video_shader = NULL; + + getShaders(&menu_shader, &video_shader); + + if (!doubleSpinBox) + return; + + sliderVariant = doubleSpinBox->property("slider"); + + if (!sliderVariant.isValid()) + return; + + slider = sliderVariant.value(); + + if (!slider) + return; + + paramVariant = slider->property("param"); + + if (paramVariant.isValid()) + { + QString parameter = paramVariant.toString(); + + double newValue = 0.0; + + if (menu_shader) + { + struct video_shader_parameter *param = NULL; + int i; + + for (i = 0; i < static_cast(menu_shader->num_parameters); i++) + { + QString id = menu_shader->parameters[i].id; + + if (id == parameter) + param = &menu_shader->parameters[i]; + } + + if (param) + { + param->current = value; + newValue = MainWindow::lerp(param->minimum, param->maximum, 0, 100, param->current); + slider->blockSignals(true); + slider->setValue(newValue); + slider->blockSignals(false); + } + } + + if (video_shader) + { + struct video_shader_parameter *param = NULL; + int i; + + for (i = 0; i < static_cast(video_shader->num_parameters); i++) + { + QString id = video_shader->parameters[i].id; + + if (id == parameter) + param = &video_shader->parameters[i]; + } + + if (param) + { + param->current = value; + newValue = MainWindow::lerp(param->minimum, param->maximum, 0, 100, param->current); + slider->blockSignals(true); + slider->setValue(newValue); + slider->blockSignals(false); + } + } + } +} diff --git a/ui/drivers/qt/shaderparamsdialog.h b/ui/drivers/qt/shaderparamsdialog.h new file mode 100644 index 0000000000..6397b743ce --- /dev/null +++ b/ui/drivers/qt/shaderparamsdialog.h @@ -0,0 +1,77 @@ +#ifndef SHADERPARAMSDIALOG_H +#define SHADERPARAMSDIALOG_H + +#include +#include + +extern "C" { +#include "../.././gfx/video_shader_parse.h" +} + +class QCloseEvent; +class QResizeEvent; +class QVBoxLayout; +class QFormLayout; +class QLayout; +class QScrollArea; + +class ShaderPass +{ +public: + ShaderPass(struct video_shader_pass *passToCopy = NULL); + ~ShaderPass(); + ShaderPass& operator=(const ShaderPass &other); + struct video_shader_pass *pass; +}; + +class ShaderParamsDialog : public QDialog +{ + Q_OBJECT +public: + ShaderParamsDialog(QWidget *parent = 0); + ~ShaderParamsDialog(); +signals: + void closed(); + void resized(QSize size); +public slots: + void reload(); +private slots: + void onShaderParamCheckBoxClicked(); + void onShaderParamSliderValueChanged(int value); + void onShaderParamSpinBoxValueChanged(int value); + void onShaderParamDoubleSpinBoxValueChanged(double value); + void onFilterComboBoxIndexChanged(int index); + void onGroupBoxContextMenuRequested(const QPoint &pos); + void onParameterLabelContextMenuRequested(const QPoint &pos); + void onScaleComboBoxIndexChanged(int index); + void onShaderPassMoveDownClicked(); + void onShaderPassMoveUpClicked(); + void onShaderResetPass(int pass); + void onShaderResetAllPasses(); + void onShaderResetParameter(QString parameter); + void onShaderLoadPresetClicked(); + void onShaderAddPassClicked(); + void onShaderSavePresetAsClicked(); + void onShaderSaveCorePresetClicked(); + void onShaderSaveParentPresetClicked(); + void onShaderSaveGamePresetClicked(); + void onShaderClearAllPassesClicked(); + void onShaderRemovePassClicked(); + void onShaderApplyClicked(); + void clearLayout(); + void buildLayout(); +private: + QString getFilterLabel(unsigned filter); + void addShaderParam(struct video_shader_parameter *param, QFormLayout *form); + void getShaders(struct video_shader **menu_shader, struct video_shader **video_shader); + void saveShaderPreset(const char *path, unsigned action_type); + + QPointer m_layout; + QPointer m_scrollArea; +protected: + void closeEvent(QCloseEvent *event); + void resizeEvent(QResizeEvent *event); + void paintEvent(QPaintEvent *event); +}; + +#endif diff --git a/ui/drivers/qt/thumbnaildownload.cpp b/ui/drivers/qt/thumbnaildownload.cpp new file mode 100644 index 0000000000..c54d9b85aa --- /dev/null +++ b/ui/drivers/qt/thumbnaildownload.cpp @@ -0,0 +1,309 @@ +#include +#include +#include + +#include "../ui_qt.h" + +extern "C" { +#include +#include +#include +#include "../../../tasks/tasks_internal.h" +#include "../../../verbosity.h" +#include "../../../config.def.h" +#include "../../../configuration.h" +#include "../../../version.h" +} + +#define USER_AGENT "RetroArch-WIMP/" PACKAGE_VERSION +#define PARTIAL_EXTENSION ".partial" +#define THUMBNAIL_URL_HEADER "https://github.com/libretro-thumbnails/" +#define THUMBNAIL_URL_BRANCH "/blob/master/" +#define THUMBNAIL_IMAGE_EXTENSION ".png" +#define THUMBNAIL_URL_FOOTER THUMBNAIL_IMAGE_EXTENSION "?raw=true" + +void MainWindow::onThumbnailDownloadNetworkError(QNetworkReply::NetworkError code) +{ + QNetworkReply *reply = m_thumbnailDownloadReply.data(); + QByteArray errorStringArray; + const char *errorStringData = NULL; + + m_thumbnailDownloadProgressDialog->cancel(); + + if (!reply) + return; + + errorStringArray = reply->errorString().toUtf8(); + errorStringData = errorStringArray.constData(); + + RARCH_ERR("[Qt]: Network error code %d received: %s\n", code, errorStringData); + + /* Deleting the reply here seems to cause a strange heap-use-after-free crash. */ + /* + reply->disconnect(); + reply->abort(); + reply->deleteLater(); + */ +} + +void MainWindow::onThumbnailDownloadNetworkSslErrors(const QList &errors) +{ + QNetworkReply *reply = m_thumbnailDownloadReply.data(); + int i; + + if (!reply) + return; + + for (i = 0; i < errors.count(); i++) + { + const QSslError &error = errors.at(i); + QString string = QString("Ignoring SSL error code ") + QString::number(error.error()) + ": " + error.errorString(); + QByteArray stringArray = string.toUtf8(); + const char *stringData = stringArray.constData(); + RARCH_ERR("[Qt]: %s\n", stringData); + } + + /* ignore all SSL errors for now, like self-signed, expired etc. */ + reply->ignoreSslErrors(); +} + +void MainWindow::onThumbnailDownloadCanceled() +{ + m_thumbnailDownloadProgressDialog->cancel(); +} + +void MainWindow::onThumbnailDownloadFinished() +{ + QString system; + QString title; + QString downloadType; + QNetworkReply *reply = m_thumbnailDownloadReply.data(); + QNetworkReply::NetworkError error; + int code; + + m_thumbnailDownloadProgressDialog->cancel(); + + /* At least on Linux, the progress dialog will refuse to hide itself and will stay on screen in a corrupted way if we happen to show an error message in this function. processEvents() will sometimes fix it, other times not... seems random. */ + qApp->processEvents(); + + if (!reply) + return; + + system = reply->property("system").toString(); + title = reply->property("title").toString(); + downloadType = reply->property("download_type").toString(); + + error = reply->error(); + code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (m_thumbnailDownloadFile.isOpen()) + m_thumbnailDownloadFile.close(); + + if (code != 200) + { + QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + + if (!redirectUrl.isEmpty()) + { + QByteArray redirectUrlArray = redirectUrl.toString().toUtf8(); + const char *redirectUrlData = redirectUrlArray.constData(); + + m_pendingThumbnailDownloadTypes.prepend(downloadType); + + RARCH_LOG("[Qt]: Thumbnail download got redirect with HTTP code %d: %s\n", code, redirectUrlData); + + reply->disconnect(); + reply->abort(); + reply->deleteLater(); + + downloadThumbnail(system, title, redirectUrl); + + return; + } + else + { + /*emit showErrorMessageDeferred(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR)) + ": HTTP Code " + QString::number(code));*/ + m_thumbnailDownloadFile.remove(); + + RARCH_ERR("[Qt]: Thumbnail download failed with HTTP status code: %d\n", code); + + reply->disconnect(); + reply->abort(); + reply->deleteLater(); + + if (!m_pendingThumbnailDownloadTypes.isEmpty()) + downloadThumbnail(system, title); + + return; + } + } + + if (error == QNetworkReply::NoError) + { + int index = m_thumbnailDownloadFile.fileName().lastIndexOf(PARTIAL_EXTENSION); + QString newFileName = m_thumbnailDownloadFile.fileName().left(index); + QFile newFile(newFileName); + + /* rename() requires the old file to be deleted first if it exists */ + if (newFile.exists() && !newFile.remove()) + RARCH_ERR("[Qt]: Thumbnail download finished, but old file could not be deleted.\n"); + else + { + if (m_thumbnailDownloadFile.rename(newFileName)) + { + RARCH_LOG("[Qt]: Thumbnail download finished successfully.\n"); + /* reload thumbnail image */ + emit itemChanged(); + } + else + { + RARCH_ERR("[Qt]: Thumbnail download finished, but temp file could not be renamed.\n"); + emit showErrorMessageDeferred(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_RENAME_FILE)); + } + } + } + else + { + QByteArray errorArray = reply->errorString().toUtf8(); + const char *errorData = errorArray.constData(); + + m_thumbnailDownloadFile.remove(); + + RARCH_ERR("[Qt]: Thumbnail download ended prematurely: %s\n", errorData); + emit showErrorMessageDeferred(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR)) + ": Code " + QString::number(code) + ": " + errorData); + } + + reply->disconnect(); + reply->close(); + reply->deleteLater(); + + if (!m_pendingThumbnailDownloadTypes.isEmpty()) + emit gotThumbnailDownload(system, title); +} + +void MainWindow::onDownloadThumbnail(QString system, QString title) +{ + downloadThumbnail(system, title); +} + +void MainWindow::onThumbnailDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) +{ + QNetworkReply *reply = m_thumbnailDownloadReply.data(); + int progress = (bytesReceived / (float)bytesTotal) * 100.0f; + + if (!reply) + return; + + m_thumbnailDownloadProgressDialog->setValue(progress); +} + +void MainWindow::onThumbnailDownloadReadyRead() +{ + QNetworkReply *reply = m_thumbnailDownloadReply.data(); + + if (!reply) + return; + + m_thumbnailDownloadFile.write(reply->readAll()); +} + +void MainWindow::downloadThumbnail(QString system, QString title, QUrl url) +{ + QString systemUnderscore = system; + QString urlString; + QNetworkReply *reply = NULL; + QNetworkRequest request; + QByteArray urlArray; + QString downloadType; + settings_t *settings = config_get_ptr(); + const char *urlData = NULL; + + if (!settings || m_pendingThumbnailDownloadTypes.isEmpty()) + return; + + title = getScrubbedString(title); + downloadType = m_pendingThumbnailDownloadTypes.takeFirst(); + + systemUnderscore = systemUnderscore.replace(" ", "_"); + + urlString = QString(THUMBNAIL_URL_HEADER) + systemUnderscore + THUMBNAIL_URL_BRANCH + downloadType + "/" + title + THUMBNAIL_URL_FOOTER; + + if (url.isEmpty()) + url = urlString; + + request.setUrl(url); + + urlArray = url.toString().toUtf8(); + urlData = urlArray.constData(); + + if (m_thumbnailDownloadFile.isOpen()) + { + RARCH_ERR("[Qt]: File is already open.\n"); + return; + } + else + { + QString dirString = QString(settings->paths.directory_thumbnails) + "/" + system + "/" + downloadType; + QString fileName = dirString + "/" + title + THUMBNAIL_IMAGE_EXTENSION + PARTIAL_EXTENSION; + QDir dir; + QByteArray fileNameArray = fileName.toUtf8(); + const char *fileNameData = fileNameArray.constData(); + + dir.mkpath(dirString); + + m_thumbnailDownloadFile.setFileName(fileName); + + if (!m_thumbnailDownloadFile.open(QIODevice::WriteOnly)) + { + m_thumbnailDownloadProgressDialog->cancel(); + showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FILE_WRITE_OPEN_FAILED), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); + RARCH_ERR("[Qt]: Could not open file for writing: %s\n", fileNameData); + + if (m_thumbnailDownloadReply) + { + m_thumbnailDownloadReply->disconnect(); + m_thumbnailDownloadReply->abort(); + m_thumbnailDownloadReply->deleteLater(); + } + + if (m_pendingThumbnailDownloadTypes.isEmpty()) + m_thumbnailDownloadProgressDialog->cancel(); + else + downloadThumbnail(system, title); + + return; + } + } + + RARCH_LOG("[Qt]: Starting thumbnail download...\n"); + RARCH_LOG("[Qt]: Downloading URL %s\n", urlData); + + request.setHeader(QNetworkRequest::UserAgentHeader, USER_AGENT); + + m_thumbnailDownloadProgressDialog->setWindowModality(Qt::NonModal); + m_thumbnailDownloadProgressDialog->setMinimumDuration(0); + m_thumbnailDownloadProgressDialog->setRange(0, 100); + m_thumbnailDownloadProgressDialog->setAutoClose(true); + m_thumbnailDownloadProgressDialog->setAutoReset(true); + m_thumbnailDownloadProgressDialog->setValue(0); + m_thumbnailDownloadProgressDialog->setLabelText(QString(msg_hash_to_str(MSG_DOWNLOADING)) + "..."); + m_thumbnailDownloadProgressDialog->setCancelButtonText(tr("Cancel")); + m_thumbnailDownloadProgressDialog->show(); + + m_thumbnailDownloadReply = m_networkManager->get(request); + + reply = m_thumbnailDownloadReply.data(); + reply->setProperty("system", system); + reply->setProperty("title", title); + reply->setProperty("download_type", downloadType); + + /* make sure any previous connection is removed first */ + disconnect(m_thumbnailDownloadProgressDialog, SIGNAL(canceled()), reply, SLOT(abort())); + connect(m_thumbnailDownloadProgressDialog, SIGNAL(canceled()), reply, SLOT(abort())); + + connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onThumbnailDownloadNetworkError(QNetworkReply::NetworkError))); + connect(reply, SIGNAL(sslErrors(const QList&)), this, SLOT(onThumbnailDownloadNetworkSslErrors(const QList&))); + connect(reply, SIGNAL(finished()), this, SLOT(onThumbnailDownloadFinished())); + connect(reply, SIGNAL(readyRead()), this, SLOT(onThumbnailDownloadReadyRead())); + connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(onThumbnailDownloadProgress(qint64, qint64))); +} diff --git a/ui/drivers/qt/thumbnailpackdownload.cpp b/ui/drivers/qt/thumbnailpackdownload.cpp new file mode 100644 index 0000000000..a9b551498b --- /dev/null +++ b/ui/drivers/qt/thumbnailpackdownload.cpp @@ -0,0 +1,313 @@ +#include +#include +#include + +#include "../ui_qt.h" + +extern "C" { +#include +#include +#include +#include "../../../tasks/tasks_internal.h" +#include "../../../verbosity.h" +#include "../../../config.def.h" +#include "../../../configuration.h" +#include "../../../version.h" +} + +#define USER_AGENT "RetroArch-WIMP/" PACKAGE_VERSION +#define PARTIAL_EXTENSION ".partial" +#define TEMP_EXTENSION ".tmp" +#define THUMBNAILPACK_URL_HEADER "http://thumbnailpacks.libretro.com/" +#define THUMBNAILPACK_EXTENSION ".zip" + +static void extractCB(void *task_data, void *user_data, const char *err) +{ + decompress_task_data_t *dec = (decompress_task_data_t*)task_data; + MainWindow *mainwindow = (MainWindow*)user_data; + + if (err) + RARCH_ERR("%s", err); + + if (dec) + { + if (filestream_exists(dec->source_file)) + filestream_delete(dec->source_file); + + free(dec->source_file); + free(dec); + } + + mainwindow->onThumbnailPackExtractFinished(string_is_empty(err)); +} + +void MainWindow::onThumbnailPackDownloadNetworkError(QNetworkReply::NetworkError code) +{ + QNetworkReply *reply = m_thumbnailPackDownloadReply.data(); + QByteArray errorStringArray; + const char *errorStringData = NULL; + + m_thumbnailPackDownloadProgressDialog->cancel(); + + if (!reply) + return; + + errorStringArray = reply->errorString().toUtf8(); + errorStringData = errorStringArray.constData(); + + RARCH_ERR("[Qt]: Network error code %d received: %s\n", code, errorStringData); + + /* Deleting the reply here seems to cause a strange heap-use-after-free crash. */ + /* + reply->disconnect(); + reply->abort(); + reply->deleteLater(); + */ +} + +void MainWindow::onThumbnailPackDownloadNetworkSslErrors(const QList &errors) +{ + QNetworkReply *reply = m_thumbnailPackDownloadReply.data(); + int i; + + if (!reply) + return; + + for (i = 0; i < errors.count(); i++) + { + const QSslError &error = errors.at(i); + QString string = QString("Ignoring SSL error code ") + QString::number(error.error()) + ": " + error.errorString(); + QByteArray stringArray = string.toUtf8(); + const char *stringData = stringArray.constData(); + RARCH_ERR("[Qt]: %s\n", stringData); + } + + /* ignore all SSL errors for now, like self-signed, expired etc. */ + reply->ignoreSslErrors(); +} + +void MainWindow::onThumbnailPackDownloadCanceled() +{ + m_thumbnailPackDownloadProgressDialog->cancel(); +} + +void MainWindow::onThumbnailPackDownloadFinished() +{ + QString system; + QNetworkReply *reply = m_thumbnailPackDownloadReply.data(); + QNetworkReply::NetworkError error; + int code; + + m_thumbnailPackDownloadProgressDialog->cancel(); + + /* At least on Linux, the progress dialog will refuse to hide itself and will stay on screen in a corrupted way if we happen to show an error message in this function. processEvents() will sometimes fix it, other times not... seems random. */ + qApp->processEvents(); + + if (!reply) + return; + + system = reply->property("system").toString(); + + error = reply->error(); + code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (m_thumbnailPackDownloadFile.isOpen()) + m_thumbnailPackDownloadFile.close(); + + if (code != 200) + { + QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + + if (!redirectUrl.isEmpty()) + { + QByteArray redirectUrlArray = redirectUrl.toString().toUtf8(); + const char *redirectUrlData = redirectUrlArray.constData(); + + RARCH_LOG("[Qt]: Thumbnail pack download got redirect with HTTP code %d: %s\n", code, redirectUrlData); + + reply->disconnect(); + reply->abort(); + reply->deleteLater(); + + downloadAllThumbnails(system, redirectUrl); + + return; + } + else + { + emit showErrorMessageDeferred(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR)) + ": HTTP Code " + QString::number(code)); + + m_thumbnailPackDownloadFile.remove(); + + RARCH_ERR("[Qt]: Thumbnail pack download failed with HTTP status code: %d\n", code); + + reply->disconnect(); + reply->abort(); + reply->deleteLater(); + + return; + } + } + + if (error == QNetworkReply::NoError) + { + int index = m_thumbnailPackDownloadFile.fileName().lastIndexOf(PARTIAL_EXTENSION); + QString newFileName = m_thumbnailPackDownloadFile.fileName().left(index); + QFile newFile(newFileName); + + /* rename() requires the old file to be deleted first if it exists */ + if (newFile.exists() && !newFile.remove()) + RARCH_ERR("[Qt]: Thumbnail pack download finished, but old file could not be deleted.\n"); + else + { + if (m_thumbnailPackDownloadFile.rename(newFileName)) + { + settings_t *settings = config_get_ptr(); + + if (settings) + { + RARCH_LOG("[Qt]: Thumbnail pack download finished successfully.\n"); + emit extractArchiveDeferred(newFileName, settings->paths.directory_thumbnails, TEMP_EXTENSION, extractCB); + } + } + else + { + RARCH_ERR("[Qt]: Thumbnail pack download finished, but temp file could not be renamed.\n"); + emit showErrorMessageDeferred(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_RENAME_FILE)); + } + } + } + else + { + QByteArray errorArray = reply->errorString().toUtf8(); + const char *errorData = errorArray.constData(); + + m_thumbnailPackDownloadFile.remove(); + + RARCH_ERR("[Qt]: Thumbnail pack download ended prematurely: %s\n", errorData); + emit showErrorMessageDeferred(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR)) + ": Code " + QString::number(code) + ": " + errorData); + } + + reply->disconnect(); + reply->close(); + reply->deleteLater(); +} + +void MainWindow::onThumbnailPackDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) +{ + QNetworkReply *reply = m_thumbnailPackDownloadReply.data(); + int progress = (bytesReceived / (float)bytesTotal) * 100.0f; + + if (!reply) + return; + + m_thumbnailPackDownloadProgressDialog->setValue(progress); +} + +void MainWindow::onThumbnailPackDownloadReadyRead() +{ + QNetworkReply *reply = m_thumbnailPackDownloadReply.data(); + + if (!reply) + return; + + m_thumbnailPackDownloadFile.write(reply->readAll()); +} + +void MainWindow::downloadAllThumbnails(QString system, QUrl url) +{ + QString urlString; + QNetworkReply *reply = NULL; + QNetworkRequest request; + QByteArray urlArray; + settings_t *settings = config_get_ptr(); + const char *urlData = NULL; + + if (!settings) + return; + + urlString = QString(THUMBNAILPACK_URL_HEADER) + system + THUMBNAILPACK_EXTENSION; + + if (url.isEmpty()) + url = urlString; + + request.setUrl(url); + + urlArray = url.toString().toUtf8(); + urlData = urlArray.constData(); + + if (m_thumbnailPackDownloadFile.isOpen()) + { + RARCH_ERR("[Qt]: File is already open.\n"); + return; + } + else + { + QString dirString = QString(settings->paths.directory_thumbnails); + QString fileName = dirString + "/" + system + THUMBNAILPACK_EXTENSION + PARTIAL_EXTENSION; + QDir dir; + QByteArray fileNameArray = fileName.toUtf8(); + const char *fileNameData = fileNameArray.constData(); + + dir.mkpath(dirString); + + m_thumbnailPackDownloadFile.setFileName(fileName); + + if (!m_thumbnailPackDownloadFile.open(QIODevice::WriteOnly)) + { + m_thumbnailPackDownloadProgressDialog->cancel(); + showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FILE_WRITE_OPEN_FAILED), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); + RARCH_ERR("[Qt]: Could not open file for writing: %s\n", fileNameData); + return; + } + } + + RARCH_LOG("[Qt]: Starting thumbnail pack download...\n"); + RARCH_LOG("[Qt]: Downloading URL %s\n", urlData); + + request.setHeader(QNetworkRequest::UserAgentHeader, USER_AGENT); + + m_thumbnailPackDownloadProgressDialog->setWindowModality(Qt::NonModal); + m_thumbnailPackDownloadProgressDialog->setMinimumDuration(0); + m_thumbnailPackDownloadProgressDialog->setRange(0, 100); + m_thumbnailPackDownloadProgressDialog->setAutoClose(true); + m_thumbnailPackDownloadProgressDialog->setAutoReset(true); + m_thumbnailPackDownloadProgressDialog->setValue(0); + m_thumbnailPackDownloadProgressDialog->setLabelText(QString(msg_hash_to_str(MSG_DOWNLOADING)) + "..."); + m_thumbnailPackDownloadProgressDialog->setCancelButtonText(tr("Cancel")); + m_thumbnailPackDownloadProgressDialog->show(); + + m_thumbnailPackDownloadReply = m_networkManager->get(request); + + reply = m_thumbnailPackDownloadReply.data(); + reply->setProperty("system", system); + + /* make sure any previous connection is removed first */ + disconnect(m_thumbnailPackDownloadProgressDialog, SIGNAL(canceled()), reply, SLOT(abort())); + connect(m_thumbnailPackDownloadProgressDialog, SIGNAL(canceled()), reply, SLOT(abort())); + + connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onThumbnailPackDownloadNetworkError(QNetworkReply::NetworkError))); + connect(reply, SIGNAL(sslErrors(const QList&)), this, SLOT(onThumbnailPackDownloadNetworkSslErrors(const QList&))); + connect(reply, SIGNAL(finished()), this, SLOT(onThumbnailPackDownloadFinished())); + connect(reply, SIGNAL(readyRead()), this, SLOT(onThumbnailPackDownloadReadyRead())); + connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(onThumbnailPackDownloadProgress(qint64, qint64))); +} + +void MainWindow::onThumbnailPackExtractFinished(bool success) +{ + m_updateProgressDialog->cancel(); + + if (!success) + { + RARCH_ERR("[Qt]: Thumbnail pack extraction failed.\n"); + emit showErrorMessageDeferred(msg_hash_to_str(MSG_DECOMPRESSION_FAILED)); + return; + } + + RARCH_LOG("[Qt]: Thumbnail pack extracted successfully.\n"); + + emit showInfoMessageDeferred(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_PACK_DOWNLOADED_SUCCESSFULLY)); + + /* reload thumbnail image */ + emit itemChanged(); +} diff --git a/ui/drivers/qt/ui_qt_application.cpp b/ui/drivers/qt/ui_qt_application.cpp index ff36e92b59..3a45561c53 100644 --- a/ui/drivers/qt/ui_qt_application.cpp +++ b/ui/drivers/qt/ui_qt_application.cpp @@ -25,6 +25,9 @@ extern "C" { #include "../../../frontend/frontend.h" #include "../../../tasks/tasks_internal.h" #include +#ifdef Q_OS_UNIX +#include +#endif } #include "../ui_qt.h" @@ -127,6 +130,9 @@ static void* ui_application_qt_initialize(void) ui_application.app->setApplicationVersion(PACKAGE_VERSION); ui_application.app->connect(ui_application.app, SIGNAL(lastWindowClosed()), appHandler, SLOT(onLastWindowClosed())); +#ifdef Q_OS_UNIX + setlocale(LC_NUMERIC, "C"); +#endif { /* Can't declare the pixmap at the top, because: "QPixmap: Must construct a QGuiApplication before a QPixmap" */ QImage iconImage(16, 16, QImage::Format_ARGB32); diff --git a/ui/drivers/qt/ui_qt_load_core_window.cpp b/ui/drivers/qt/ui_qt_load_core_window.cpp index 00f29f38de..8179b82570 100644 --- a/ui/drivers/qt/ui_qt_load_core_window.cpp +++ b/ui/drivers/qt/ui_qt_load_core_window.cpp @@ -124,6 +124,11 @@ void LoadCoreWindow::loadCore(const char *path) /* const-removing cast is safe here because the path is never written to */ rarch_ctl(RARCH_CTL_SET_LIBRETRO_PATH, const_cast(path)); + command_event(CMD_EVENT_CORE_INFO_DEINIT, NULL); + command_event(CMD_EVENT_CORE_INFO_INIT, NULL); + + core_info_init_current_core(); + if (!command_event(CMD_EVENT_LOAD_CORE, NULL)) { QMessageBox::critical(this, msg_hash_to_str(MSG_ERROR), msg_hash_to_str(MSG_FAILED_TO_OPEN_LIBRETRO_CORE)); diff --git a/ui/drivers/qt/ui_qt_themes.h b/ui/drivers/qt/ui_qt_themes.h index d8e6baeb98..803cf8a37a 100644 --- a/ui/drivers/qt/ui_qt_themes.h +++ b/ui/drivers/qt/ui_qt_themes.h @@ -1,405 +1,435 @@ #include /* %1 is a placeholder for palette(highlight) or the equivalent chosen by the user */ -static const QString qt_theme_default_stylesheet = QStringLiteral("" - "QPushButton[flat=\"true\"] {\n" - " min-height:20px;\n" - " min-width:80px;\n" - " padding:1px 3px 1px 3px;\n" - " background-color: transparent;\n" - " border: 1px solid #ddd;\n" - "}\n" - "ThumbnailWidget#thumbnailWidget, ThumbnailLabel#thumbnailGridLabel, QLabel#thumbnailQLabel {\n" - " background-color:#d4d4d4;\n" - "}\n" - "ThumbnailWidget#thumbnailWidgetSelected {\n" - " background-color:#d4d4d4;\n" - " border:3px solid %1;\n" - "}\n" -); +static const QString qt_theme_default_stylesheet = QStringLiteral(R"( + QPushButton[flat="true"] { + min-height:20px; + min-width:80px; + padding:1px 3px 1px 3px; + background-color: transparent; + border: 1px solid #ddd; + } + ThumbnailWidget#thumbnailWidget, ThumbnailLabel#thumbnailGridLabel, QLabel#thumbnailQLabel { + background-color:#d4d4d4; + } + ThumbnailWidget#thumbnailWidgetSelected { + background-color:#d4d4d4; + border:3px solid %1; + } +)"); -static const QString qt_theme_dark_stylesheet = QStringLiteral("" - "QWidget {\n" - " color:white;\n" - " background-color:rgb(53,53,53);\n" - " selection-background-color:%1;\n" - "}\n" - "QWidget#playlistWidget, QWidget#browserWidget, QWidget#tableWidget, QWidget#logWidget {\n" - " background-color:rgb(66,66,66);\n" - " border-top:1px solid rgba(175,175,175,50%);\n" - " border-left:1px solid rgba(125,125,125,50%);\n" - " border-right:1px solid rgba(125,125,125,50%);\n" - " border-bottom:1px solid rgba(25,25,25,75%);\n" - "}\n" - "QToolTip {\n" - " color:white;\n" - " background-color:rgb(53,53,53);\n" - " border:1px solid rgb(80,80,80);\n" - " border-radius:4px;\n" - "}\n" - "QMenuBar {\n" - " background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - " border-bottom:2px solid rgba(25,25,25,75);\n" - "}\n" - "QMenuBar::item {\n" - " spacing:2px;\n" - " padding:3px 4px;\n" - " background-color:transparent;\n" - "}\n" - "QMenuBar::item:selected {\n" - " background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(106,106,106,255),stop:1 rgba(106,106,106,75));\n" - " border:1px solid %1;\n" - "}\n" - "QMenuBar::item:pressed {\n" - " background-color:%1;\n" - " border-left:1px solid rgba(25,25,25,127);\n" - " border-right:1px solid rgba(25,25,25,127);\n" - "}\n" - "QMenu {\n" - " background-color:rgb(45,45,45);\n" - " border:1px solid palette(shadow);\n" - "}\n" - "QMenu::item {\n" - " padding:3px 25px 3px 25px;\n" - " border:1px solid transparent;\n" - "}\n" - "QMenu::item:disabled {\n" - " color:rgb(127,127,127);\n" - "}\n" - "QMenu::item:selected {\n" - " border-color:rgba(200,200,200,127);\n" - " background-color:%1;\n" - "}\n" - "QMenu::icon:checked {\n" - " background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - " border:1px solid %1;\n" - " border-radius:2px;\n" - "}\n" - "QMenu::separator {\n" - " height:1px;\n" - " background-color:rgb(100,100,100);\n" - " margin-left:5px;\n" - " margin-right:5px;\n" - "}\n" - "QMenu::indicator {\n" - " width:18px;\n" - " height:18px;\n" - "}\n" - "QToolBar::top {\n" - " background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - " border-bottom:3px solid qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - "}\n" - "QToolBar::bottom {\n" - " background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - " border-top:3px solid qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - "}\n" - "QToolBar::left {\n" - " background-color:qlineargradient(x1:0,y1:0,x2:1,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - " border-right:3px solid qlineargradient(x1:0,y1:0,x2:1,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - "}\n" - "QToolBar::right {\n" - " background-color:qlineargradient(x1:1,y1:0,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - " border-left:3px solid qlineargradient(x1:1,y1:0,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - "}\n" - "QMainWindow {\n" - " background-color:rgb(53,53,53);\n" - "}\n" - "QMainWindow::separator {\n" - " width:6px;\n" - " height:5px;\n" - " padding:2px;\n" - " background-color:rgba(25,25,25,50%);\n" - "}\n" - "QLineEdit {\n" - " color:white;\n" - " background-color:rgb(25,25,25);\n" - "}\n" - "QLineEdit::focus {\n" - " border:1px solid %1;\n" - " border-radius:3px;\n" - " color:white;\n" - " background-color:rgb(25,25,25);\n" - "}\n" - "QSplitter::handle:horizontal {\n" - " width:10px;\n" - "}\n" - "QSplitter::handle:vertical {\n" - " height:10px;\n" - "}\n" - "QMainWindow::separator:hover, QSplitter::handle:hover {\n" - "}\n" - "QDockWidget::title {\n" - " padding:4px;\n" - " background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,175),stop:1 rgba(53,53,53,75));\n" - " border:1px solid rgba(25,25,25,75);\n" - " border-top:1px solid rgba(175,175,175,50%);\n" - " border-bottom:1px solid rgba(25,25,25,127);\n" - "}\n" - "QDockWidget::close-button, QDockWidget::float-button {\n" - " subcontrol-position:top right;\n" - " subcontrol-origin:margin;\n" - " position:absolute;\n" - " top:3px;\n" - " bottom:0px;\n" - " width:20px;\n" - " height:20px;\n" - "}\n" - "QDockWidget::close-button:hover, QDockWidget::float-button:hover {\n" - " border:1px solid %1;\n" - " border-radius:4px;\n" - "}\n" - "QDockWidget::close-button {\n" - " right:3px;\n" - "}\n" - "QDockWidget::float-button {\n" - " right:25px;\n" - "}\n" - "QGroupBox {\n" - " background-color:rgba(66,66,66,50%);\n" - " margin-top:27px;\n" - " border:1px solid rgba(25,25,25,127);\n" - " border-top-left-radius:4px;\n" - " border-top-right-radius:4px;\n" - "}\n" - "QGroupBox::title {\n" - " subcontrol-origin:margin;\n" - " subcontrol-position:left top;\n" - " padding:4px 6px;\n" - " margin-left:3px;\n" - " background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - " border:1px solid rgba(25,25,25,75);\n" - " border-top-left-radius:4px;\n" - " border-top-right-radius:4px;\n" - "}\n" - "QTabWidget::pane {\n" - " background-color:rgba(66,66,66,50%);\n" - "}\n" - "QTabWidget::tab-bar {\n" - "}\n" - "QTabBar {\n" - " background-color:transparent;\n" - " qproperty-drawBase:0;\n" - " border-bottom:1px solid rgba(25,25,25,50%);\n" - "}\n" - "QTabBar::tab {\n" - " padding:4px 6px;\n" - " background-color:rgba(25,25,25,127);\n" - " border:1px solid rgba(25,25,25,75);\n" - "}\n" - "QTabBar::tab:selected {\n" - " background-color:rgb(66,66,66);\n" - " border-bottom-color:rgba(66,66,66,75%);\n" - "}\n" - "QTabBar::tab:!selected {\n" - " color:rgb(175,175,175);\n" - "}\n" - "QComboBox {\n" - " min-height:20px;\n" - " padding:1px 18px 1px 3px;\n" - "}\n" - "QComboBox::focus {\n" - " background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgba(255,255,255,50), stop: 1 rgba(100,100,100,25));\n" - " border:1px solid %1;\n" - " border-radius:4px;\n" - "}\n" - "QComboBox::hover {\n" - " background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgba(255,255,255,50), stop: 1 rgba(127,127,127,50));\n" - " border:1px solid %1;\n" - " border-radius:4px;\n" - "}\n" - "QComboBox::drop-down {\n" - " background-color:transparent;\n" - "}\n" - "QComboBox::selected:on, QComboBox::selected:off {\n" - " background-color:%1;\n" - "}\n" - "QTabBar::tab:hover {\n" - " color:white;\n" - " background-color:%1;\n" - "}\n" - "QComboBox::separator {\n" - " background-color:rgb(100,100,100);\n" - " height:1px;\n" - " margin-left:4px;\n" - " margin-right:4px;\n" - "}\n" - "QCheckBox::indicator {\n" - " width:18px;\n" - " height:18px;\n" - "}\n" - "QPushButton {\n" - " min-height:20px;\n" - " min-width:80px;\n" - " padding:1px 3px 1px 3px;\n" - " outline:none;\n" - "}\n" - "QPushButton::focus, QToolButton::focus {\n" - " background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgba(255,255,255,50), stop: 1 rgba(100,100,100,25));\n" - " border:1px solid %1;\n" - " border-radius:4px;\n" - "}\n" - "QPushButton::hover, QToolButton::hover {\n" - " background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgba(255,255,255,75), stop: 1 rgba(100,100,100,50));\n" - " border:1px solid %1;\n" - " border-radius:4px;\n" - "}\n" - "QPushButton::pressed, QToolButton::pressed {\n" - " background-color:transparent;\n" - " border:1px solid %1;\n" - " border-radius:4px;\n" - "}\n" - "QPushButton[flat=\"true\"] {\n" - " background-color: transparent;\n" - "}\n" - "QRadioButton::indicator {\n" - " width:18px;\n" - " height:18px;\n" - "}\n" - "QListWidget::item:selected, QTreeView::item:selected, QTableView::item:selected {\n" - " color:white;\n" - " background-color:%1;\n" - "}\n" - "QTreeView {\n" - " background-color:rgb(25,25,25);\n" - " selection-background-color:%1;\n" - "}\n" - "QTreeView::branch:selected {\n" - " background-color:%1;\n" - "}\n" - "QTreeView::item:selected:disabled, QTableView::item:selected:disabled {\n" - " background-color:rgb(80,80,80);\n" - "}\n" - "QTreeView::branch:open, QTreeView::branch:closed {\n" - " background-color:solid;\n" - "}\n" - "QTableView, QListWidget {\n" - " background-color:rgb(25,25,25);\n" - "}\n" - "QTreeView QHeaderView::section, QTableView QHeaderView::section {\n" - " /*height:24px;*/\n" - " background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - " border-style:none;\n" - " border-bottom:1px solid rgb(65,65,65);\n" - " padding-left:5px;\n" - " padding-right:5px;\n" - "}\n" - "QTableWidget {\n" - " background-color:rgb(25,25,25);\n" - " alternate-background-color:rgb(40,40,40);\n" - "}\n" - "QScrollBar:vertical, QScrollBar:horizontal {\n" - " background-color:rgb(35,35,35);\n" - "}\n" - "QScrollBar::handle:vertical, QScrollBar::handle:horizontal {\n" - " background-color:rgb(65,65,65);\n" - " border-right:1px solid rgba(175,175,175,50%);\n" - " border-top:1px solid rgba(175,175,175,50%);\n" - " border-bottom:1px solid rgba(25,25,25,75);\n" - " border-radius:2px;\n" - "}\n" - "QScrollBar::handle:horizontal:hover, QScrollBar::handle:vertical:hover {\n" - " border:1px solid %1;\n" - " background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgba(255,255,255,75), stop: 1 rgba(127,127,127,75));\n" - "}\n" - "QScrollBar:vertical {\n" - " border-top-right-radius:2px;\n" - " border-bottom-right-radius:2px;\n" - " width:16px;\n" - " margin:0px;\n" - "}\n" - "QScrollBar::handle:vertical {\n" - " min-height:20px;\n" - " margin:2px 4px 2px 4px;\n" - "}\n" - "QScrollBar::add-line:vertical {\n" - " background:none;\n" - " height:0px;\n" - " subcontrol-position:right;\n" - " subcontrol-origin:margin;\n" - "}\n" - "QScrollBar::sub-line:vertical {\n" - " background:none;\n" - " height:0px;\n" - " subcontrol-position:left;\n" - " subcontrol-origin:margin;\n" - "}\n" - "QScrollBar:horizontal {\n" - " height:16px;\n" - " margin:0px;\n" - "}\n" - "QScrollBar::handle:horizontal {\n" - " min-width:20px;\n" - " margin:4px 2px 4px 2px;\n" - "}\n" - "QScrollBar::add-line:horizontal {\n" - " background:none;\n" - " width:0px;\n" - " subcontrol-position:bottom;\n" - " subcontrol-origin:margin;\n" - "}\n" - "QScrollBar::sub-line:horizontal {\n" - " background:none;\n" - " width:0px;\n" - " subcontrol-position:top;\n" - " subcontrol-origin:margin;\n" - "}\n" - "QSlider::sub-page {\n" - " background:%1;\n" - "}\n" - "QSlider::groove:vertical {\n" - " width:3px;\n" - " background:rgb(25,25,25);\n" - "}\n" - "QSlider::handle:vertical {\n" - " background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgb(175,175,175), stop: 1 rgb(75,75,75));\n" - " border:1px solid rgb(35,35,35);\n" - " border-radius:2px;\n" - " height:16px;\n" - " margin:0 -4px;\n" - "}\n" - "QSlider::handle:vertical:hover {\n" - " background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgb(200,200,200), stop: 1 rgba(100,100,100));\n" - " border:1px solid %1;\n" - " border-radius:2px;\n" - " height:16px;\n" - " margin:0 -4px;\n" - "}\n" - "QSlider::groove:horizontal {\n" - " height:3px;\n" - " background:rgb(25,25,25);\n" - "}\n" - "QSlider::handle:horizontal {\n" - " background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgb(175,175,175), stop: 1 rgb(75,75,75));\n" - " border:1px solid rgb(35,35,35);\n" - " border-radius:2px;\n" - " width:16px;\n" - " margin:-4px 0;\n" - "}\n" - "QSlider::handle:horizontal:hover {\n" - " background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgb(200,200,200), stop: 1 rgba(100,100,100));\n" - " border:1px solid %1;\n" - " border-radius:2px;\n" - " width:16px;\n" - " margin:-4px 0;\n" - "}\n" - "QStatusBar {\n" - " color:white;\n" - " background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75));\n" - "}\n" - "QStatusBar QLabel {\n" - " background-color:transparent;\n" - "}\n" - "QSizeGrip {\n" - " background-color:solid;\n" - "}\n" - "ThumbnailWidget#thumbnailWidget, ThumbnailLabel#thumbnailGridLabel, QLabel#thumbnailQLabel {\n" - " background-color:rgb(40,40,40);\n" - "}\n" - "ThumbnailWidget#thumbnailWidgetSelected {\n" - " background-color:rgb(40,40,40);\n" - " border:3px solid %1;\n" - "}\n" - "QScrollArea QWidget {\n" - "background:rgb(25,25,25);\n" - "}\n" -); +static const QString qt_theme_dark_stylesheet = QStringLiteral(R"( + QWidget { + color:white; + background-color:rgb(53,53,53); + selection-background-color:%1; + } + QWidget#playlistWidget, QWidget#browserWidget, QWidget#tableWidget, QWidget#logWidget { + background-color:rgb(66,66,66); + border-top:1px solid rgba(175,175,175,50%); + border-left:1px solid rgba(125,125,125,50%); + border-right:1px solid rgba(125,125,125,50%); + border-bottom:1px solid rgba(25,25,25,75%); + } + QTextEdit, LogTextEdit { + background-color:rgb(25,25,25); + } + QSpinBox, QDoubleSpinBox, QCheckBox { + background-color:rgb(25,25,25); + } + QCheckBox:checked, QCheckBox:unchecked { + background-color:rgb(53,53,53); + } + QWidget#shaderParamsWidget { + background-color:rgb(25,25,25); + } + QDialog#shaderParamsDialog QGroupBox { + background-color:rgb(53,53,53); + border-top-left-radius:0px; + } + QDialog#shaderParamsDialog QGroupBox::title { + margin-left:0px; + min-height:28px; + padding:4px 10px; + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgb(53,53,53),stop:1 rgba(125,125,125,127)); + border:1px solid rgba(25,25,25,75); + border-top:1px solid rgba(175,175,175,50%); + border-bottom:none transparent; + } + QToolTip { + color:white; + background-color:rgb(53,53,53); + border:1px solid rgb(80,80,80); + border-radius:4px; + } + QMenuBar { + background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border-bottom:2px solid rgba(25,25,25,75); + } + QMenuBar::item { + spacing:2px; + padding:3px 4px; + background-color:transparent; + } + QMenuBar::item:selected { + background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(106,106,106,255),stop:1 rgba(106,106,106,75)); + border:1px solid %1; + } + QMenuBar::item:pressed { + background-color:%1; + border-left:1px solid rgba(25,25,25,127); + border-right:1px solid rgba(25,25,25,127); + } + QMenu { + background-color:rgb(45,45,45); + border:1px solid palette(shadow); + } + QMenu::item { + padding:3px 25px 3px 25px; + border:1px solid transparent; + } + QMenu::item:disabled { + color:rgb(127,127,127); + } + QMenu::item:selected { + border-color:rgba(200,200,200,127); + background-color:%1; + } + QMenu::icon:checked { + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border:1px solid %1; + border-radius:2px; + } + QMenu::separator { + height:1px; + background-color:rgb(100,100,100); + margin-left:5px; + margin-right:5px; + } + QMenu::indicator { + width:18px; + height:18px; + } + QToolBar::top { + background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border-bottom:3px solid qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + } + QToolBar::bottom { + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border-top:3px solid qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + } + QToolBar::left { + background-color:qlineargradient(x1:0,y1:0,x2:1,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border-right:3px solid qlineargradient(x1:0,y1:0,x2:1,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + } + QToolBar::right { + background-color:qlineargradient(x1:1,y1:0,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border-left:3px solid qlineargradient(x1:1,y1:0,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + } + QMainWindow { + background-color:rgb(53,53,53); + } + QMainWindow::separator { + width:6px; + height:5px; + padding:2px; + background-color:rgba(25,25,25,50%); + } + QLineEdit { + color:white; + background-color:rgb(25,25,25); + } + QLineEdit::focus { + border:1px solid %1; + border-radius:3px; + color:white; + background-color:rgb(25,25,25); + } + QSplitter::handle:horizontal { + width:10px; + } + QSplitter::handle:vertical { + height:10px; + } + QMainWindow::separator:hover, QSplitter::handle:hover { + } + QDockWidget::title { + padding:4px; + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,175),stop:1 rgba(53,53,53,75)); + border:1px solid rgba(25,25,25,75); + border-top:1px solid rgba(175,175,175,50%); + border-bottom:1px solid rgba(25,25,25,127); + } + QDockWidget::close-button, QDockWidget::float-button { + subcontrol-position:top right; + subcontrol-origin:margin; + position:absolute; + top:3px; + bottom:0px; + width:20px; + height:20px; + } + QDockWidget::close-button:hover, QDockWidget::float-button:hover { + border:1px solid %1; + border-radius:4px; + } + QDockWidget::close-button { + right:3px; + } + QDockWidget::float-button { + right:25px; + } + QGroupBox { + background-color:rgba(66,66,66,50%); + margin-top:27px; + border:1px solid rgba(25,25,25,127); + border-top-left-radius:4px; + border-top-right-radius:4px; + } + QGroupBox::title { + subcontrol-origin:margin; + subcontrol-position:left top; + padding:4px 6px; + margin-left:3px; + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border:1px solid rgba(25,25,25,75); + border-top-left-radius:4px; + border-top-right-radius:4px; + } + QTabWidget::pane { + background-color:rgba(66,66,66,50%); + } + QTabWidget::tab-bar { + } + QTabBar { + background-color:transparent; + qproperty-drawBase:0; + border-bottom:1px solid rgba(25,25,25,50%); + } + QTabBar::tab { + padding:4px 6px; + background-color:rgba(25,25,25,127); + border:1px solid rgba(25,25,25,75); + } + QTabBar::tab:selected { + background-color:rgb(66,66,66); + border-bottom-color:rgba(66,66,66,75%); + } + QTabBar::tab:!selected { + color:rgb(175,175,175); + } + QComboBox { + min-height:20px; + padding:1px 6px 1px 6px; + } + QComboBox::focus { + background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgba(255,255,255,50), stop: 1 rgba(100,100,100,25)); + border:1px solid %1; + border-radius:4px; + } + QComboBox::hover { + background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgba(255,255,255,50), stop: 1 rgba(127,127,127,50)); + border:1px solid %1; + border-radius:4px; + } + QComboBox::drop-down { + background-color:transparent; + width:0px; + } + QComboBox::selected:on, QComboBox::selected:off { + background-color:%1; + } + QTabBar::tab:hover { + color:white; + background-color:%1; + } + QComboBox::separator { + background-color:rgb(100,100,100); + height:1px; + margin-left:4px; + margin-right:4px; + } + QCheckBox::indicator { + width:18px; + height:18px; + } + QPushButton { + min-height:20px; + min-width:80px; + padding:1px 3px 1px 3px; + outline:none; + } + QPushButton::disabled, QToolButton::disabled { + color:grey; + background-color:rgb(25,25,25); + } + QPushButton::focus, QToolButton::focus { + background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgba(255,255,255,50), stop: 1 rgba(100,100,100,25)); + border:1px solid %1; + border-radius:4px; + } + QPushButton::hover, QToolButton::hover { + background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgba(255,255,255,75), stop: 1 rgba(100,100,100,50)); + border:1px solid %1; + border-radius:4px; + } + QPushButton::pressed, QToolButton::pressed { + background-color:transparent; + border:1px solid %1; + border-radius:4px; + } + QPushButton[flat="true"] { + background-color:transparent; + } + QRadioButton::indicator { + width:18px; + height:18px; + } + QListWidget::item:selected, QTreeView::item:selected, QTableView::item:selected { + color:white; + background-color:%1; + } + QTreeView { + background-color:rgb(25,25,25); + selection-background-color:%1; + } + QTreeView::branch:selected { + background-color:%1; + } + QTreeView::item:selected:disabled, QTableView::item:selected:disabled { + background-color:rgb(80,80,80); + } + QTreeView::branch:open, QTreeView::branch:closed { + background-color:solid; + } + QTableView, QListWidget { + background-color:rgb(25,25,25); + } + QTreeView QHeaderView::section, QTableView QHeaderView::section { + /*height:24px;*/ + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border-style:none; + border-bottom:1px solid rgb(65,65,65); + padding-left:5px; + padding-right:5px; + } + QTableWidget { + background-color:rgb(25,25,25); + alternate-background-color:rgb(40,40,40); + } + QScrollBar:vertical, QScrollBar:horizontal { + background-color:rgb(35,35,35); + } + QScrollBar::handle:vertical, QScrollBar::handle:horizontal { + background-color:rgb(65,65,65); + border-right:1px solid rgba(175,175,175,50%); + border-top:1px solid rgba(175,175,175,50%); + border-bottom:1px solid rgba(25,25,25,75); + border-radius:2px; + } + QScrollBar::handle:horizontal:hover, QScrollBar::handle:vertical:hover { + border:1px solid %1; + background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgba(255,255,255,75), stop: 1 rgba(127,127,127,75)); + } + QScrollBar:vertical { + border-top-right-radius:2px; + border-bottom-right-radius:2px; + width:16px; + margin:0px; + } + QScrollBar::handle:vertical { + min-height:20px; + margin:2px 4px 2px 4px; + } + QScrollBar::add-line:vertical { + background:none; + height:0px; + subcontrol-position:right; + subcontrol-origin:margin; + } + QScrollBar::sub-line:vertical { + background:none; + height:0px; + subcontrol-position:left; + subcontrol-origin:margin; + } + QScrollBar:horizontal { + height:16px; + margin:0px; + } + QScrollBar::handle:horizontal { + min-width:20px; + margin:4px 2px 4px 2px; + } + QScrollBar::add-line:horizontal { + background:none; + width:0px; + subcontrol-position:bottom; + subcontrol-origin:margin; + } + QScrollBar::sub-line:horizontal { + background:none; + width:0px; + subcontrol-position:top; + subcontrol-origin:margin; + } + QSlider::sub-page { + background:%1; + } + QSlider::groove:vertical { + width:3px; + background:rgb(25,25,25); + } + QSlider::handle:vertical { + background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgb(175,175,175), stop: 1 rgb(75,75,75)); + border:1px solid rgb(35,35,35); + border-radius:2px; + height:16px; + margin:0 -4px; + } + QSlider::handle:vertical:hover { + background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgb(200,200,200), stop: 1 rgba(100,100,100)); + border:1px solid %1; + border-radius:2px; + height:16px; + margin:0 -4px; + } + QSlider::groove:horizontal { + height:3px; + background:rgb(25,25,25); + } + QSlider::handle:horizontal { + background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgb(175,175,175), stop: 1 rgb(75,75,75)); + border:1px solid rgb(35,35,35); + border-radius:2px; + width:16px; + margin:-4px 0; + } + QSlider::handle:horizontal:hover { + background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgb(200,200,200), stop: 1 rgba(100,100,100)); + border:1px solid %1; + border-radius:2px; + width:16px; + margin:-4px 0; + } + QStatusBar { + color:white; + background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + } + QStatusBar QLabel { + background-color:transparent; + } + QSizeGrip { + background-color:solid; + } + ThumbnailWidget#thumbnailWidget, ThumbnailLabel#thumbnailGridLabel, QLabel#thumbnailQLabel { + background-color:rgb(40,40,40); + } + ThumbnailWidget#thumbnailWidgetSelected { + background-color:rgb(40,40,40); + border:3px solid %1; + } + QWidget#gridLayoutWidget { + background-color:rgb(25,25,25); + } +)"); diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index d8c8d40ad3..1e993bdcb0 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -36,12 +37,19 @@ #include #include #include +#include #include "../ui_qt.h" +#include "invader_png.h" #include "ui_qt_load_core_window.h" #include "ui_qt_themes.h" #include "flowlayout.h" -#include "invader_png.h" +#include "shaderparamsdialog.h" +#include "coreoptionsdialog.h" +#include "filedropwidget.h" +#include "coreinfodialog.h" +#include "playlistentrydialog.h" +#include "viewoptionsdialog.h" extern "C" { #include "../../../version.h" @@ -55,15 +63,21 @@ extern "C" { #include "../../../file_path_special.h" #include "../../../playlist.h" #include "../../../content.h" +#ifdef HAVE_MENU #include "../../../menu/menu_driver.h" -#include "../../../tasks/tasks_internal.h" +#endif #include "../../../config.def.h" +#include "../../../tasks/tasks_internal.h" #include #include #include #include #include #include +#ifdef HAVE_OPENSSL +#include +#include +#endif } #include "../../../AUTHORS.h" @@ -76,21 +90,12 @@ extern "C" { #endif #define GENERIC_FOLDER_ICON "/xmb/dot-art/png/folder.png" -#define ICON_PATH "/xmb/dot-art/png/" -#define THUMBNAIL_BOXART "Named_Boxarts" -#define THUMBNAIL_SCREENSHOT "Named_Snaps" -#define THUMBNAIL_TITLE "Named_Titles" -#define ALL_PLAYLISTS_TOKEN "|||ALL|||" #define HIRAGANA_START 0x3041U #define HIRAGANA_END 0x3096U #define KATAKANA_START 0x30A1U #define KATAKANA_END 0x30F6U #define HIRA_KATA_OFFSET (KATAKANA_START - HIRAGANA_START) -#define USER_AGENT "RetroArch-WIMP/1.0" #define DOCS_URL "http://docs.libretro.com/" -#define PARTIAL_EXTENSION ".partial" -#define TEMP_EXTENSION ".update_tmp" -#define RETROARCH_NIGHTLY_UPDATE_PATH "../RetroArch_update.zip" static ui_window_qt_t ui_window = {0}; @@ -103,22 +108,12 @@ enum CoreSelection CORE_SELECTION_LOAD_CORE }; -static double lerp(double x, double y, double a, double b, double d) { - return a + (b - a) * ((double)(d - x) / (double)(y - x)); -} - -/* https://stackoverflow.com/questions/7246622/how-to-create-a-slider-with-a-non-linear-scale */ -static double expScale(double inputValue, double midValue, double maxValue) +static const QPixmap getInvader() { - double returnValue = 0; - double M = maxValue / midValue; - double C = log(pow(M - 1, 2)); - double B = maxValue / (exp(C) - 1); - double A = -1 * B; + QPixmap pix; + pix.loadFromData(invader_png, invader_png_len, "PNG"); - returnValue = A + B * exp(C * inputValue); - - return returnValue; + return pix; } #ifdef HAVE_LIBRETRODB @@ -133,9 +128,9 @@ static void scan_finished_handler(void *task_data, void *user_data, const char * (void)task_data; (void)user_data; (void)err; - +#ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_ENVIRONMENT, &menu_environ); - +#endif if (!ui_window.qtWindow->settings()->value("scan_finish_confirm", true).toBool()) return; @@ -146,49 +141,17 @@ static void scan_finished_handler(void *task_data, void *user_data, const char * } #endif -inline static bool comp_string_lower(const QString &lhs, const QString &rhs) +static double expScale(double inputValue, double midValue, double maxValue) { - return lhs.toLower() < rhs.toLower(); -} + double returnValue = 0; + double M = maxValue / midValue; + double C = log(pow(M - 1, 2)); + double B = maxValue / (exp(C) - 1); + double A = -1 * B; -inline static bool comp_hash_ui_display_name_key_lower(const QHash &lhs, const QHash &rhs) -{ - return lhs.value("ui_display_name").toLower() < rhs.value("ui_display_name").toLower(); -} + returnValue = A + B * exp(C * inputValue); -inline static bool comp_hash_name_key_lower(const QHash &lhs, const QHash &rhs) -{ - return lhs.value("name").toLower() < rhs.value("name").toLower(); -} - -inline static bool comp_hash_label_key_lower(const QHash &lhs, const QHash &rhs) -{ - return lhs.value("label").toLower() < rhs.value("label").toLower(); -} - -static void addDirectoryFilesToList(QStringList &list, QDir &dir) -{ - QStringList dirList = dir.entryList(QStringList(), QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System, QDir::Name); - int i; - - for (i = 0; i < dirList.count(); i++) - { - QString path(dir.path() + "/" + dirList.at(i)); - QFileInfo fileInfo(path); - - if (fileInfo.isDir()) - { - QDir fileInfoDir(path); - - addDirectoryFilesToList(list, fileInfoDir); - continue; - } - - if (fileInfo.isFile()) - { - list.append(fileInfo.absoluteFilePath()); - } - } + return returnValue; } /* https://gist.github.com/andrey-str/0f9c7709cbf0c9c49ef9 */ @@ -200,8 +163,6 @@ static void setElidedText(QLabel *label, QWidget *clipWidget, int padding, const label->setText(clippedText); } -const QPixmap getInvader(); - GridItem::GridItem() : QObject() ,widget(NULL) @@ -233,65 +194,6 @@ void TreeView::selectionChanged(const QItemSelection &selected, const QItemSelec emit itemsSelected(list); } -FileDropWidget::FileDropWidget(QWidget *parent) : - QWidget(parent) -{ - setAcceptDrops(true); -} - -void FileDropWidget::paintEvent(QPaintEvent *event) -{ - QStyleOption o; - QPainter p; - o.initFrom(this); - p.begin(this); - style()->drawPrimitive( - QStyle::PE_Widget, &o, &p, this); - p.end(); - - QWidget::paintEvent(event); -} - -void FileDropWidget::keyPressEvent(QKeyEvent *event) -{ - if (event->key() == Qt::Key_Delete) - { - event->accept(); - emit deletePressed(); - } - else - QWidget::keyPressEvent(event); -} - -void FileDropWidget::dragEnterEvent(QDragEnterEvent *event) -{ - const QMimeData *data = event->mimeData(); - - if (data->hasUrls()) - event->acceptProposedAction(); -} - -void FileDropWidget::dropEvent(QDropEvent *event) -{ - const QMimeData *data = event->mimeData(); - - if (data->hasUrls()) - { - QList urls = data->urls(); - QStringList files; - int i; - - for (i = 0; i < urls.count(); i++) - { - QString path(urls.at(i).toLocalFile()); - - files.append(path); - } - - emit filesDropped(files); - } -} - TableWidget::TableWidget(QWidget *parent) : QTableWidget(parent) { @@ -319,524 +221,11 @@ CoreInfoLabel::CoreInfoLabel(QString text, QWidget *parent) : setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); } -CoreInfoDialog::CoreInfoDialog(MainWindow *mainwindow, QWidget *parent) : - QDialog(parent) - ,m_formLayout(new QFormLayout()) - ,m_mainwindow(mainwindow) -{ - QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); - - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION)); - - m_formLayout->setFormAlignment(Qt::AlignCenter); - m_formLayout->setLabelAlignment(Qt::AlignCenter); - - setLayout(new QVBoxLayout()); - - qobject_cast(layout())->addLayout(m_formLayout); - layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); - layout()->addWidget(buttonBox); -} - -void CoreInfoDialog::showCoreInfo() -{ - int row = 0; - int rowCount = m_formLayout->rowCount(); - int i = 0; - QVector > infoList = m_mainwindow->getCoreInfo(); - - if (rowCount > 0) - { - for (row = 0; row < rowCount; row++) - { -#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) - /* removeRow() and takeRow() was only added in 5.8! */ - m_formLayout->removeRow(0); -#else - /* something is buggy here... sometimes items appear duplicated, and other times not */ - QLayoutItem *item = m_formLayout->itemAt(0); - QWidget *w = NULL; - - if (item) - { - w = item->widget(); - - if (w) - { - QWidget *label = m_formLayout->labelForField(w); - - if (label) - delete label; - - m_formLayout->removeWidget(w); - - delete w; - } - } -#endif - } - } - - if (infoList.count() == 0) - return; - - for (i = 0; i < infoList.count(); i++) - { - const QHash &line = infoList.at(i); - QLabel *label = new QLabel(line.value("key")); - CoreInfoLabel *value = new CoreInfoLabel(line.value("value")); - QString labelStyle = line.value("label_style"); - QString valueStyle = line.value("value_style"); - - if (!labelStyle.isEmpty()) - label->setStyleSheet(labelStyle); - - if (!valueStyle.isEmpty()) - value->setStyleSheet(valueStyle); - - m_formLayout->addRow(label, value); - } - - show(); -} - -PlaylistEntryDialog::PlaylistEntryDialog(MainWindow *mainwindow, QWidget *parent) : - QDialog(parent) - ,m_mainwindow(mainwindow) - ,m_settings(mainwindow->settings()) - ,m_nameLineEdit(new QLineEdit(this)) - ,m_pathLineEdit(new QLineEdit(this)) - ,m_coreComboBox(new QComboBox(this)) - ,m_databaseComboBox(new QComboBox(this)) -{ - QFormLayout *form = new QFormLayout(); - QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - QVBoxLayout *databaseVBoxLayout = new QVBoxLayout(); - QHBoxLayout *pathHBoxLayout = new QHBoxLayout(); - QLabel *databaseLabel = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FOR_THUMBNAILS), this); - QToolButton *pathPushButton = new QToolButton(this); - - pathPushButton->setText("..."); - - pathHBoxLayout->addWidget(m_pathLineEdit); - pathHBoxLayout->addWidget(pathPushButton); - - databaseVBoxLayout->addWidget(m_databaseComboBox); - databaseVBoxLayout->addWidget(databaseLabel); - - setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY)); - - form->setFormAlignment(Qt::AlignCenter); - form->setLabelAlignment(Qt::AlignCenter); - - setLayout(new QVBoxLayout(this)); - - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - connect(this, SIGNAL(accepted()), this, SLOT(onAccepted())); - connect(this, SIGNAL(rejected()), this, SLOT(onRejected())); - - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_NAME), m_nameLineEdit); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_PATH), pathHBoxLayout); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_CORE), m_coreComboBox); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_DATABASE), databaseVBoxLayout); - - qobject_cast(layout())->addLayout(form); - layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); - layout()->addWidget(buttonBox); - - connect(pathPushButton, SIGNAL(clicked()), this, SLOT(onPathClicked())); -} - -void PlaylistEntryDialog::onPathClicked() -{ - QString filePath = QFileDialog::getOpenFileName(this); - - if (filePath.isEmpty()) - return; - - m_pathLineEdit->setText(filePath); -} - -void PlaylistEntryDialog::loadPlaylistOptions() -{ - core_info_list_t *core_info_list = NULL; - const core_info_t *core_info = NULL; - unsigned i = 0; - int j = 0; - - m_nameLineEdit->clear(); - m_pathLineEdit->clear(); - m_coreComboBox->clear(); - m_databaseComboBox->clear(); - - m_coreComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CORE_SELECTION_ASK)); - m_databaseComboBox->addItem(QString("<") + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE) + ">", QFileInfo(m_mainwindow->getCurrentPlaylistPath()).fileName().remove(file_path_str(FILE_PATH_LPL_EXTENSION))); - - core_info_get_list(&core_info_list); - - if (core_info_list && core_info_list->count > 0) - { - QVector > allCores; - QStringList allDatabases; - - for (i = 0; i < core_info_list->count; i++) - { - const core_info_t *core = &core_info_list->list[i]; - QStringList databases = QString(core->databases).split("|"); - QHash hash; - QString ui_display_name; - - hash["core_name"] = core->core_name; - hash["core_display_name"] = core->display_name; - hash["core_path"] = core->path; - hash["core_databases"] = core->databases; - - ui_display_name = hash.value("core_name"); - - if (ui_display_name.isEmpty()) - ui_display_name = hash.value("core_display_name"); - if (ui_display_name.isEmpty()) - ui_display_name = QFileInfo(hash.value("core_path")).fileName(); - if (ui_display_name.isEmpty()) - continue; - - hash["ui_display_name"] = ui_display_name; - - for (j = 0; j < databases.count(); j++) - { - QString database = databases.at(j); - - if (database.isEmpty()) - continue; - - if (!allDatabases.contains(database)) - allDatabases.append(database); - } - - if (!allCores.contains(hash)) - allCores.append(hash); - } - - std::sort(allCores.begin(), allCores.end(), comp_hash_ui_display_name_key_lower); - std::sort(allDatabases.begin(), allDatabases.end(), comp_string_lower); - - for (j = 0; j < allCores.count(); j++) - { - const QHash &hash = allCores.at(j); - - m_coreComboBox->addItem(hash.value("ui_display_name"), QVariant::fromValue(hash)); - } - - for (j = 0; j < allDatabases.count(); j++) - { - QString database = allDatabases.at(j); - m_databaseComboBox->addItem(database, database); - } - } -} - -void PlaylistEntryDialog::setEntryValues(const QHash &contentHash) -{ - QString db; - QString coreName = contentHash.value("core_name"); - int foundDB = 0; - int i = 0; - - loadPlaylistOptions(); - - if (contentHash.isEmpty()) - { - m_nameLineEdit->setText(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FIELD_MULTIPLE)); - m_pathLineEdit->setText(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FIELD_MULTIPLE)); - m_nameLineEdit->setEnabled(false); - m_pathLineEdit->setEnabled(false); - } - else - { - m_nameLineEdit->setEnabled(true); - m_pathLineEdit->setEnabled(true); - m_nameLineEdit->setText(contentHash.value("label")); - m_pathLineEdit->setText(contentHash.value("path")); - } - - for (i = 0; i < m_coreComboBox->count(); i++) - { - const QHash hash = m_coreComboBox->itemData(i, Qt::UserRole).value >(); - - if (hash.isEmpty() || coreName.isEmpty()) - continue; - - if (hash.value("core_name") == coreName) - { - m_coreComboBox->setCurrentIndex(i); - break; - } - } - - db = contentHash.value("db_name"); - - if (!db.isEmpty()) - { - foundDB = m_databaseComboBox->findText(db); - - if (foundDB >= 0) - m_databaseComboBox->setCurrentIndex(foundDB); - } -} - -const QHash PlaylistEntryDialog::getSelectedCore() -{ - return m_coreComboBox->currentData(Qt::UserRole).value >(); -} - -const QString PlaylistEntryDialog::getSelectedName() -{ - return m_nameLineEdit->text(); -} - -const QString PlaylistEntryDialog::getSelectedPath() -{ - return m_pathLineEdit->text(); -} - -const QString PlaylistEntryDialog::getSelectedDatabase() -{ - return m_databaseComboBox->currentData(Qt::UserRole).toString(); -} - -void PlaylistEntryDialog::onAccepted() -{ -} - -void PlaylistEntryDialog::onRejected() -{ -} - -bool PlaylistEntryDialog::showDialog(const QHash &hash) -{ - loadPlaylistOptions(); - setEntryValues(hash); - - if (exec() == QDialog::Accepted) - return true; - - return false; -} - -void PlaylistEntryDialog::hideDialog() -{ - reject(); -} - -ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : - QDialog(parent) - ,m_mainwindow(mainwindow) - ,m_settings(mainwindow->settings()) - ,m_saveGeometryCheckBox(new QCheckBox(this)) - ,m_saveDockPositionsCheckBox(new QCheckBox(this)) - ,m_saveLastTabCheckBox(new QCheckBox(this)) - ,m_showHiddenFilesCheckBox(new QCheckBox(this)) - ,m_themeComboBox(new QComboBox(this)) - ,m_highlightColorPushButton(new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CHOOSE), this)) - ,m_highlightColor() - ,m_highlightColorLabel(new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_HIGHLIGHT_COLOR), this)) - ,m_customThemePath() - ,m_suggestLoadedCoreFirstCheckBox(new QCheckBox(this)) - ,m_allPlaylistsListMaxCountSpinBox(new QSpinBox(this)) - ,m_allPlaylistsGridMaxCountSpinBox(new QSpinBox(this)) -{ - QFormLayout *form = new QFormLayout(); - QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - - setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE)); - - m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_SYSTEM_DEFAULT), MainWindow::THEME_SYSTEM_DEFAULT); - m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK), MainWindow::THEME_DARK); - m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM), MainWindow::THEME_CUSTOM); - - m_allPlaylistsListMaxCountSpinBox->setRange(0, 99999); - m_allPlaylistsGridMaxCountSpinBox->setRange(0, 99999); - - form->setFormAlignment(Qt::AlignCenter); - form->setLabelAlignment(Qt::AlignCenter); - - setLayout(new QVBoxLayout(this)); - - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - connect(this, SIGNAL(accepted()), this, SLOT(onAccepted())); - connect(this, SIGNAL(rejected()), this, SLOT(onRejected())); - - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY), m_saveGeometryCheckBox); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS), m_saveDockPositionsCheckBox); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB), m_saveLastTabCheckBox); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SHOW_HIDDEN_FILES), m_showHiddenFilesCheckBox); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SUGGEST_LOADED_CORE_FIRST), m_suggestLoadedCoreFirstCheckBox); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_LIST_MAX_COUNT), m_allPlaylistsListMaxCountSpinBox); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_GRID_MAX_COUNT), m_allPlaylistsGridMaxCountSpinBox); - form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME), m_themeComboBox); - form->addRow(m_highlightColorLabel, m_highlightColorPushButton); - - qobject_cast(layout())->addLayout(form); - layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); - layout()->addWidget(buttonBox); - - loadViewOptions(); - - connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThemeComboBoxIndexChanged(int))); - connect(m_highlightColorPushButton, SIGNAL(clicked()), this, SLOT(onHighlightColorChoose())); -} - -void ViewOptionsDialog::onThemeComboBoxIndexChanged(int) -{ - MainWindow::Theme theme = static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()); - - if (theme == MainWindow::THEME_CUSTOM) - { - QString filePath = QFileDialog::getOpenFileName(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SELECT_THEME)); - - if (filePath.isEmpty()) - { - int oldThemeIndex = m_themeComboBox->findData(m_mainwindow->getThemeFromString(m_settings->value("theme", "default").toString())); - - if (m_themeComboBox->count() > oldThemeIndex) - { - disconnect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThemeComboBoxIndexChanged(int))); - m_themeComboBox->setCurrentIndex(oldThemeIndex); - connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThemeComboBoxIndexChanged(int))); - } - } - else - { - m_customThemePath = filePath; - - if (m_mainwindow->setCustomThemeFile(filePath)) - m_mainwindow->setTheme(theme); - } - } - else - m_mainwindow->setTheme(theme); - - showOrHideHighlightColor(); -} - -void ViewOptionsDialog::onHighlightColorChoose() -{ - QPixmap highlightPixmap(m_highlightColorPushButton->iconSize()); - QColor currentHighlightColor = m_settings->value("highlight_color", QApplication::palette().highlight().color()).value(); - QColor newHighlightColor = QColorDialog::getColor(currentHighlightColor, this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SELECT_COLOR)); - - if (newHighlightColor.isValid()) - { - MainWindow::Theme theme = static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()); - - m_highlightColor = newHighlightColor; - m_settings->setValue("highlight_color", m_highlightColor); - highlightPixmap.fill(m_highlightColor); - m_highlightColorPushButton->setIcon(highlightPixmap); - m_mainwindow->setTheme(theme); - } -} - -void ViewOptionsDialog::loadViewOptions() -{ - QColor highlightColor = m_settings->value("highlight_color", QApplication::palette().highlight().color()).value(); - QPixmap highlightPixmap(m_highlightColorPushButton->iconSize()); - int themeIndex = 0; - - m_saveGeometryCheckBox->setChecked(m_settings->value("save_geometry", false).toBool()); - m_saveDockPositionsCheckBox->setChecked(m_settings->value("save_dock_positions", false).toBool()); - m_saveLastTabCheckBox->setChecked(m_settings->value("save_last_tab", false).toBool()); - m_showHiddenFilesCheckBox->setChecked(m_settings->value("show_hidden_files", true).toBool()); - m_suggestLoadedCoreFirstCheckBox->setChecked(m_settings->value("suggest_loaded_core_first", false).toBool()); - m_allPlaylistsListMaxCountSpinBox->setValue(m_settings->value("all_playlists_list_max_count", 0).toInt()); - m_allPlaylistsGridMaxCountSpinBox->setValue(m_settings->value("all_playlists_grid_max_count", 5000).toInt()); - - themeIndex = m_themeComboBox->findData(m_mainwindow->getThemeFromString(m_settings->value("theme", "default").toString())); - - if (m_themeComboBox->count() > themeIndex) - m_themeComboBox->setCurrentIndex(themeIndex); - - if (highlightColor.isValid()) - { - m_highlightColor = highlightColor; - highlightPixmap.fill(m_highlightColor); - m_highlightColorPushButton->setIcon(highlightPixmap); - } - - showOrHideHighlightColor(); -} - -void ViewOptionsDialog::showOrHideHighlightColor() -{ - if (m_mainwindow->theme() == MainWindow::THEME_DARK) - { - m_highlightColorLabel->show(); - m_highlightColorPushButton->show(); - } - else - { - m_highlightColorLabel->hide(); - m_highlightColorPushButton->hide(); - } -} - -void ViewOptionsDialog::saveViewOptions() -{ - m_settings->setValue("save_geometry", m_saveGeometryCheckBox->isChecked()); - m_settings->setValue("save_dock_positions", m_saveDockPositionsCheckBox->isChecked()); - m_settings->setValue("save_last_tab", m_saveLastTabCheckBox->isChecked()); - m_settings->setValue("theme", m_mainwindow->getThemeString(static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()))); - m_settings->setValue("show_hidden_files", m_showHiddenFilesCheckBox->isChecked()); - m_settings->setValue("highlight_color", m_highlightColor); - m_settings->setValue("suggest_loaded_core_first", m_suggestLoadedCoreFirstCheckBox->isChecked()); - m_settings->setValue("all_playlists_list_max_count", m_allPlaylistsListMaxCountSpinBox->value()); - m_settings->setValue("all_playlists_grid_max_count", m_allPlaylistsGridMaxCountSpinBox->value()); - - if (!m_mainwindow->customThemeString().isEmpty()) - m_settings->setValue("custom_theme", m_customThemePath); - - m_mainwindow->setAllPlaylistsListMaxCount(m_allPlaylistsListMaxCountSpinBox->value()); - m_mainwindow->setAllPlaylistsGridMaxCount(m_allPlaylistsGridMaxCountSpinBox->value()); -} - -void ViewOptionsDialog::onAccepted() -{ - MainWindow::Theme newTheme = static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()); - - m_mainwindow->setTheme(newTheme); - - saveViewOptions(); -} - -void ViewOptionsDialog::onRejected() -{ - loadViewOptions(); -} - -void ViewOptionsDialog::showDialog() -{ - loadViewOptions(); - show(); -} - -void ViewOptionsDialog::hideDialog() -{ - reject(); -} - CoreInfoWidget::CoreInfoWidget(CoreInfoLabel *label, QWidget *parent) : QWidget(parent) ,m_label(label) ,m_scrollArea(new QScrollArea(this)) { - //m_scrollArea->setFrameShape(QFrame::NoFrame); m_scrollArea->setWidgetResizable(true); m_scrollArea->setWidget(m_label); } @@ -927,10 +316,26 @@ MainWindow::MainWindow(QWidget *parent) : ,m_allPlaylistsGridMaxCount(0) ,m_playlistEntryDialog(NULL) ,m_statusMessageElapsedTimer() + ,m_shaderParamsDialog(new ShaderParamsDialog()) + ,m_coreOptionsDialog(new CoreOptionsDialog()) ,m_networkManager(new QNetworkAccessManager(this)) ,m_updateProgressDialog(new QProgressDialog()) ,m_updateFile() ,m_updateReply() + ,m_thumbnailDownloadProgressDialog(new QProgressDialog()) + ,m_thumbnailDownloadFile() + ,m_thumbnailDownloadReply() + ,m_pendingThumbnailDownloadTypes() + ,m_thumbnailPackDownloadProgressDialog(new QProgressDialog()) + ,m_thumbnailPackDownloadFile() + ,m_thumbnailPackDownloadReply() + ,m_playlistThumbnailDownloadProgressDialog(new QProgressDialog()) + ,m_playlistThumbnailDownloadFile() + ,m_playlistThumbnailDownloadReply() + ,m_pendingPlaylistThumbnails() + ,m_downloadedThumbnails(0) + ,m_failedThumbnails(0) + ,m_playlistThumbnailDownloadWasCanceled(false) { settings_t *settings = config_get_ptr(); QDir playlistDir(settings->paths.directory_playlist); @@ -949,8 +354,13 @@ MainWindow::MainWindow(QWidget *parent) : int i = 0; qRegisterMetaType >("ThumbnailWidget"); + qRegisterMetaType("retro_task_callback_t"); + /* Cancel all progress dialogs immediately since they show as soon as they're constructed. */ m_updateProgressDialog->cancel(); + m_thumbnailDownloadProgressDialog->cancel(); + m_thumbnailPackDownloadProgressDialog->cancel(); + m_playlistThumbnailDownloadProgressDialog->cancel(); m_gridProgressWidget = new QWidget(); gridProgressLabel = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PROGRESS), m_gridProgressWidget); @@ -983,6 +393,7 @@ MainWindow::MainWindow(QWidget *parent) : m_gridWidget->setLayout(new QVBoxLayout()); m_gridLayout = new FlowLayout(m_gridLayoutWidget); + m_gridLayoutWidget->setObjectName("gridLayoutWidget"); m_gridScrollArea->setAlignment(Qt::AlignCenter); m_gridScrollArea->setFrameShape(QFrame::NoFrame); @@ -1147,12 +558,30 @@ MainWindow::MainWindow(QWidget *parent) : connect(m_gridLayoutWidget, SIGNAL(filesDropped(QStringList)), this, SLOT(onPlaylistFilesDropped(QStringList))); connect(m_gridLayoutWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(onFileDropWidgetContextMenuRequested(const QPoint&))); + connect(m_playlistThumbnailDownloadProgressDialog, SIGNAL(canceled()), m_playlistThumbnailDownloadProgressDialog, SLOT(cancel())); + connect(m_playlistThumbnailDownloadProgressDialog, SIGNAL(canceled()), this, SLOT(onPlaylistThumbnailDownloadCanceled())); + + connect(m_thumbnailDownloadProgressDialog, SIGNAL(canceled()), m_thumbnailDownloadProgressDialog, SLOT(cancel())); + connect(m_thumbnailDownloadProgressDialog, SIGNAL(canceled()), this, SLOT(onThumbnailDownloadCanceled())); + + connect(m_thumbnailPackDownloadProgressDialog, SIGNAL(canceled()), m_thumbnailPackDownloadProgressDialog, SLOT(cancel())); + connect(m_thumbnailPackDownloadProgressDialog, SIGNAL(canceled()), this, SLOT(onThumbnailPackDownloadCanceled())); + + connect(this, SIGNAL(itemChanged()), this, SLOT(onItemChanged())); + connect(this, SIGNAL(gridItemChanged(QString)), this, SLOT(onGridItemChanged(QString))); + connect(this, SIGNAL(gotThumbnailDownload(QString,QString)), this, SLOT(onDownloadThumbnail(QString,QString))); + /* make sure these use an auto connection so it will be queued if called from a different thread (some facilities in RA log messages from other threads) */ connect(this, SIGNAL(gotLogMessage(const QString&)), this, SLOT(onGotLogMessage(const QString&)), Qt::AutoConnection); connect(this, SIGNAL(gotStatusMessage(QString,unsigned,unsigned,bool)), this, SLOT(onGotStatusMessage(QString,unsigned,unsigned,bool)), Qt::AutoConnection); - connect(this, SIGNAL(gotReloadPlaylists()), this, SLOT(onGotReloadPlaylists())); + connect(this, SIGNAL(gotReloadPlaylists()), this, SLOT(onGotReloadPlaylists()), Qt::AutoConnection); + connect(this, SIGNAL(gotReloadShaderParams()), this, SLOT(onGotReloadShaderParams()), Qt::AutoConnection); + connect(this, SIGNAL(gotReloadCoreOptions()), this, SLOT(onGotReloadCoreOptions()), Qt::AutoConnection); + + /* these are always queued */ connect(this, SIGNAL(showErrorMessageDeferred(QString)), this, SLOT(onShowErrorMessage(QString)), Qt::QueuedConnection); - connect(this, SIGNAL(extractArchiveDeferred(QString)), this, SLOT(onExtractArchive(QString)), Qt::QueuedConnection); + connect(this, SIGNAL(showInfoMessageDeferred(QString)), this, SLOT(onShowInfoMessage(QString)), Qt::QueuedConnection); + connect(this, SIGNAL(extractArchiveDeferred(QString,QString,QString,retro_task_callback_t)), this, SLOT(onExtractArchive(QString,QString,QString,retro_task_callback_t)), Qt::QueuedConnection); m_timer->start(TIMER_MSEC); @@ -1175,6 +604,21 @@ MainWindow::MainWindow(QWidget *parent) : #endif removeUpdateTempFiles(); +#ifdef HAVE_OPENSSL + { +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + const SSL_METHOD *method = TLS_method(); + SSL_CTX *ctx = SSL_CTX_new(method); + + if (ctx) + SSL_CTX_free(ctx); +#else + const SSL_METHOD *method = TLSv1_method(); + RARCH_LOG("[Qt]: TLS supports %d ciphers.\n", method->num_ciphers()); +#endif + RARCH_LOG("[Qt]: Using %s\n", OPENSSL_VERSION_TEXT); + } +#endif } MainWindow::~MainWindow() @@ -1189,238 +633,86 @@ MainWindow::~MainWindow() removeGridItems(); } -void MainWindow::removeUpdateTempFiles() +QVector > MainWindow::getPlaylists() { - /* a QDir with no path means the current working directory */ - QDir dir; - QStringList dirList = dir.entryList(QStringList(), QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System, QDir::Name); + QVector > playlists; int i; - for (i = 0; i < dirList.count(); i++) + for (i = 0; i < m_listWidget->count(); i++) { - QString path(dir.path() + "/" + dirList.at(i)); - QFile file(path); + QListWidgetItem *item = m_listWidget->item(i); + QPair pair; + QString label; + QString path; - if (path.endsWith(TEMP_EXTENSION)) + if (!item) + continue; + + label = item->text(); + path = item->data(Qt::UserRole).toString(); + + pair.first = label; + pair.second = path; + + playlists.append(pair); + } + + return playlists; +} + +void MainWindow::onGridItemChanged(QString title) +{ + int i; + + for (i = 0; i < m_gridItems.count(); i++) + { + const QPointer &item = m_gridItems.at(i); + const QHash &hash = item->hash; + + if (hash.value("label_noext") == title) { - QByteArray pathArray = path.toUtf8(); - const char *pathData = pathArray.constData(); - - if (file.remove()) - RARCH_LOG("[Qt]: removed temporary update file %s\n", pathData); - else - RARCH_LOG("[Qt]: could not remove temporary update file %s\n", pathData); + loadImageDeferred(item.data(), item->widget->property("image_path").toString()); + break; } } } -void MainWindow::onPlaylistFilesDropped(QStringList files) +void MainWindow::onItemChanged() { - addFilesToPlaylist(files); -} + ViewType viewType = getCurrentViewType(); -/* Takes a list of files and folders and adds them to the currently selected playlist. Folders will have their contents added recursively. */ -void MainWindow::addFilesToPlaylist(QStringList files) -{ - QStringList list; - QString currentPlaylistPath; - QListWidgetItem *currentItem = m_listWidget->currentItem(); - QByteArray currentPlaylistArray; - QScopedPointer dialog(NULL); - PlaylistEntryDialog *playlistDialog = playlistEntryDialog(); - QHash selectedCore; - QHash itemToAdd; - QString selectedDatabase; - QString selectedName; - QString selectedPath; - const char *currentPlaylistData = NULL; - playlist_t *playlist = NULL; - int i; + currentItemChanged(getCurrentContentHash()); - /* Assume a blank list means we will manually enter in all fields. */ - if (files.isEmpty()) + if (viewType == VIEW_TYPE_ICONS) { - /* Make sure hash isn't blank, that would mean there's multiple entries to add at once. */ - itemToAdd["label"] = ""; - itemToAdd["path"] = ""; - } - else if (files.count() == 1) - { - QString path = files.at(0); - QFileInfo info(path); + int i; - if (info.isFile()) + for (i = 0; i < m_gridItems.count(); i++) { - itemToAdd["label"] = info.completeBaseName(); - itemToAdd["path"] = path; - } - } + const QPointer &item = m_gridItems.at(i); - if (currentItem) - { - currentPlaylistPath = currentItem->data(Qt::UserRole).toString(); - - if (!currentPlaylistPath.isEmpty()) - { - currentPlaylistArray = currentPlaylistPath.toUtf8(); - currentPlaylistData = currentPlaylistArray.constData(); - } - } - - if (currentPlaylistPath == ALL_PLAYLISTS_TOKEN) - { - showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CANNOT_ADD_TO_ALL_PLAYLISTS), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); - return; - } - - /* a blank itemToAdd means there will be multiple */ - if (!playlistDialog->showDialog(itemToAdd)) - return; - - selectedName = m_playlistEntryDialog->getSelectedName(); - selectedPath = m_playlistEntryDialog->getSelectedPath(); - selectedCore = m_playlistEntryDialog->getSelectedCore(); - selectedDatabase = m_playlistEntryDialog->getSelectedDatabase(); - - if (selectedDatabase.isEmpty()) - selectedDatabase = QFileInfo(currentPlaylistPath).fileName(); - else - selectedDatabase += file_path_str(FILE_PATH_LPL_EXTENSION); - - dialog.reset(new QProgressDialog(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_GATHERING_LIST_OF_FILES), "Cancel", 0, 0, this)); - dialog->setWindowModality(Qt::ApplicationModal); - - if (selectedName.isEmpty() || selectedPath.isEmpty() || - selectedDatabase.isEmpty()) - { - showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLEASE_FILL_OUT_REQUIRED_FIELDS), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); - return; - } - - if (files.isEmpty()) - files.append(selectedPath); - - for (i = 0; i < files.count(); i++) - { - QString path(files.at(i)); - QFileInfo fileInfo(path); - - if (dialog->wasCanceled()) - return; - - if (i % 25 == 0) - { - /* Needed to update progress dialog while doing a lot of stuff on the main thread. */ - qApp->processEvents(); - } - - if (fileInfo.isDir()) - { - QDir dir(path); - addDirectoryFilesToList(list, dir); - continue; - } - - if (fileInfo.isFile()) - list.append(fileInfo.absoluteFilePath()); - else if (files.count() == 1) - { - /* If adding a single file, tell user that it doesn't exist. */ - showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); - return; - } - } - - dialog->setLabelText(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ADDING_FILES_TO_PLAYLIST)); - dialog->setMaximum(list.count()); - - playlist = playlist_init(currentPlaylistData, COLLECTION_SIZE); - - for (i = 0; i < list.count(); i++) - { - QString fileName = list.at(i); - QFileInfo fileInfo; - QByteArray fileBaseNameArray; - QByteArray pathArray; - QByteArray corePathArray; - QByteArray coreNameArray; - QByteArray databaseArray; - const char *pathData = NULL; - const char *fileNameNoExten = NULL; - const char *corePathData = NULL; - const char *coreNameData = NULL; - const char *databaseData = NULL; - - if (dialog->wasCanceled()) - { - playlist_free(playlist); - return; - } - - if (fileName.isEmpty()) - continue; - - fileInfo = fileName; - - if (files.count() == 1 && list.count() == 1 && i == 0) - { - fileBaseNameArray = selectedName.toUtf8(); - pathArray = QDir::toNativeSeparators(selectedPath).toUtf8(); - } - else - { - fileBaseNameArray = fileInfo.completeBaseName().toUtf8(); - pathArray = QDir::toNativeSeparators(fileName).toUtf8(); - } - - fileNameNoExten = fileBaseNameArray.constData(); - - /* a modal QProgressDialog calls processEvents() automatically in setValue() */ - dialog->setValue(i + 1); - - pathData = pathArray.constData(); - - if (selectedCore.isEmpty()) - { - corePathData = "DETECT"; - coreNameData = "DETECT"; - } - else - { - corePathArray = QDir::toNativeSeparators(selectedCore.value("core_path")).toUtf8(); - coreNameArray = selectedCore.value("core_name").toUtf8(); - corePathData = corePathArray.constData(); - coreNameData = coreNameArray.constData(); - } - - databaseArray = selectedDatabase.toUtf8(); - databaseData = databaseArray.constData(); - - if (path_is_compressed_file(pathData)) - { - struct string_list *list = file_archive_get_file_list(pathData, NULL); - - if (list) + if (item->widget == m_currentGridWidget) { - if (list->size == 1) - { - /* assume archives with one file should have that file loaded directly */ - pathArray = QDir::toNativeSeparators(QString(pathData) + "#" + list->elems[0].data).toUtf8(); - pathData = pathArray.constData(); - } - - string_list_free(list); + loadImageDeferred(item.data(), m_currentGridWidget->property("image_path").toString()); + break; } } - - playlist_push(playlist, pathData, fileNameNoExten, - corePathData, coreNameData, "00000000|crc", databaseData); } +} - playlist_write_file(playlist); - playlist_free(playlist); +QString MainWindow::getSpecialPlaylistPath(SpecialPlaylist playlist) +{ + switch (playlist) + { + case SPECIAL_PLAYLIST_HISTORY: + return (m_historyPlaylistsItem ? m_historyPlaylistsItem->data(Qt::UserRole).toString() : QString()); + default: + return QString(); + } +} - reloadPlaylists(); +double MainWindow::lerp(double x, double y, double a, double b, double d) { + return a + (b - a) * ((double)(d - x) / (double)(y - x)); } void MainWindow::onGridItemClicked(ThumbnailWidget *widget) @@ -1439,7 +731,6 @@ void MainWindow::onGridItemClicked(ThumbnailWidget *widget) if (m_currentGridWidget) { m_currentGridWidget->setObjectName("thumbnailWidget"); - //m_currentGridWidget->setFrameStyle(QFrame::Plain); m_currentGridWidget->style()->unpolish(m_currentGridWidget); m_currentGridWidget->style()->polish(m_currentGridWidget); } @@ -1480,7 +771,7 @@ void MainWindow::onListViewClicked() onCurrentListItemChanged(m_listWidget->currentItem(), NULL); } -inline void MainWindow::calcGridItemSize(GridItem *item, int zoomValue) +void MainWindow::calcGridItemSize(GridItem *item, int zoomValue) { int newSize = 0; QLabel *label = NULL; @@ -1672,468 +963,6 @@ bool MainWindow::showMessageBox(QString msg, MessageBoxType msgType, Qt::WindowM return true; } -bool MainWindow::updateCurrentPlaylistEntry(const QHash &contentHash) -{ - QString playlistPath = getCurrentPlaylistPath(); - QString path; - QString label; - QString corePath; - QString coreName; - QString dbName; - QString crc32; - QByteArray playlistPathArray; - QByteArray pathArray; - QByteArray labelArray; - QByteArray corePathArray; - QByteArray coreNameArray; - QByteArray dbNameArray; - QByteArray crc32Array; - const char *playlistPathData = NULL; - const char *pathData = NULL; - const char *labelData = NULL; - const char *corePathData = NULL; - const char *coreNameData = NULL; - const char *dbNameData = NULL; - const char *crc32Data = NULL; - playlist_t *playlist = NULL; - unsigned index = 0; - bool ok = false; - - if (playlistPath.isEmpty() || contentHash.isEmpty() || !contentHash.contains("index")) - return false; - - index = contentHash.value("index").toUInt(&ok); - - if (!ok) - return false; - - path = contentHash.value("path"); - label = contentHash.value("label"); - coreName = contentHash.value("core_name"); - corePath = contentHash.value("core_path"); - dbName = contentHash.value("db_name"); - crc32 = contentHash.value("crc32"); - - if (path.isEmpty() || - label.isEmpty() || - coreName.isEmpty() || - corePath.isEmpty() || - dbName.isEmpty() || - crc32.isEmpty() - ) - return false; - - playlistPathArray = playlistPath.toUtf8(); - pathArray = QDir::toNativeSeparators(path).toUtf8(); - labelArray = label.toUtf8(); - coreNameArray = coreName.toUtf8(); - corePathArray = QDir::toNativeSeparators(corePath).toUtf8(); - dbNameArray = (dbName + file_path_str(FILE_PATH_LPL_EXTENSION)).toUtf8(); - crc32Array = crc32.toUtf8(); - - playlistPathData = playlistPathArray.constData(); - pathData = pathArray.constData(); - labelData = labelArray.constData(); - coreNameData = coreNameArray.constData(); - corePathData = corePathArray.constData(); - dbNameData = dbNameArray.constData(); - crc32Data = crc32Array.constData(); - - if (path_is_compressed_file(pathData)) - { - struct string_list *list = file_archive_get_file_list(pathData, NULL); - - if (list) - { - if (list->size == 1) - { - /* assume archives with one file should have that file loaded directly */ - pathArray = QDir::toNativeSeparators(QString(pathData) + "#" + list->elems[0].data).toUtf8(); - pathData = pathArray.constData(); - } - - string_list_free(list); - } - } - - playlist = playlist_init(playlistPathData, COLLECTION_SIZE); - - playlist_update(playlist, index, pathData, labelData, - corePathData, coreNameData, crc32Data, dbNameData); - playlist_write_file(playlist); - playlist_free(playlist); - - reloadPlaylists(); - - return true; -} - -void MainWindow::onFileDropWidgetContextMenuRequested(const QPoint &pos) -{ - QScopedPointer menu; - QScopedPointer addEntryAction; - QScopedPointer addFilesAction; - QScopedPointer addFolderAction; - QScopedPointer editAction; - QScopedPointer deleteAction; - QPointer selectedAction; - QPoint cursorPos = QCursor::pos(); - QHash contentHash = getCurrentContentHash(); - - menu.reset(new QMenu(this)); - - addEntryAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ADD_ENTRY)), this)); - addFilesAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ADD_FILES)), this)); - addFolderAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ADD_FOLDER)), this)); - editAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_EDIT)), this)); - deleteAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DELETE)), this)); - - menu->addAction(addEntryAction.data()); - menu->addAction(addFilesAction.data()); - menu->addAction(addFolderAction.data()); - - if (!contentHash.isEmpty()) - { - menu->addAction(editAction.data()); - menu->addAction(deleteAction.data()); - } - - selectedAction = menu->exec(cursorPos); - - if (!selectedAction) - return; - - if (selectedAction == addFilesAction.data()) - { - QStringList filePaths = QFileDialog::getOpenFileNames(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SELECT_FILES)); - - if (!filePaths.isEmpty()) - addFilesToPlaylist(filePaths); - } - else if (selectedAction == addEntryAction.data()) - { - addFilesToPlaylist(QStringList()); - } - else if (selectedAction == addFolderAction.data()) - { - QString dirPath = QFileDialog::getExistingDirectory(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SELECT_FOLDER), QString(), QFileDialog::ShowDirsOnly); - - if (!dirPath.isEmpty()) - addFilesToPlaylist(QStringList() << dirPath); - } - else if (selectedAction == editAction.data()) - { - PlaylistEntryDialog *playlistDialog = playlistEntryDialog(); - QHash selectedCore; - QString selectedDatabase; - QString selectedName; - QString selectedPath; - QString currentPlaylistPath = getCurrentPlaylistPath(); - - if (!playlistDialog->showDialog(contentHash)) - return; - - selectedName = m_playlistEntryDialog->getSelectedName(); - selectedPath = m_playlistEntryDialog->getSelectedPath(); - selectedCore = m_playlistEntryDialog->getSelectedCore(); - selectedDatabase = m_playlistEntryDialog->getSelectedDatabase(); - - if (selectedCore.isEmpty()) - { - selectedCore["core_name"] = "DETECT"; - selectedCore["core_path"] = "DETECT"; - } - - if (selectedDatabase.isEmpty()) - { - selectedDatabase = QFileInfo(currentPlaylistPath).fileName().remove(file_path_str(FILE_PATH_LPL_EXTENSION)); - } - - contentHash["label"] = selectedName; - contentHash["path"] = selectedPath; - contentHash["core_name"] = selectedCore.value("core_name"); - contentHash["core_path"] = selectedCore.value("core_path"); - contentHash["db_name"] = selectedDatabase; - - if (!updateCurrentPlaylistEntry(contentHash)) - { - showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_UPDATE_PLAYLIST_ENTRY), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); - return; - } - } - else if (selectedAction == deleteAction.data()) - { - deleteCurrentPlaylistItem(); - } -} - -void MainWindow::onPlaylistWidgetContextMenuRequested(const QPoint&) -{ - settings_t *settings = config_get_ptr(); - QScopedPointer menu; - QScopedPointer associateMenu; - QScopedPointer hiddenPlaylistsMenu; - QScopedPointer hideAction; - QScopedPointer newPlaylistAction; - QScopedPointer deletePlaylistAction; - QPointer selectedAction; - QPoint cursorPos = QCursor::pos(); - QListWidgetItem *selectedItem = m_listWidget->itemAt(m_listWidget->viewport()->mapFromGlobal(cursorPos)); - QDir playlistDir(settings->paths.directory_playlist); - QString playlistDirAbsPath = playlistDir.absolutePath(); - QString currentPlaylistDirPath; - QString currentPlaylistPath; - QString currentPlaylistFileName; - QFile currentPlaylistFile; - QByteArray currentPlaylistFileNameArray; - QFileInfo currentPlaylistFileInfo; - QMap coreList; - core_info_list_t *core_info_list = NULL; - union string_list_elem_attr attr = {0}; - struct string_list *stnames = NULL; - struct string_list *stcores = NULL; - unsigned i = 0; - int j = 0; - size_t found = 0; - const char *currentPlaylistFileNameData = NULL; - char new_playlist_names[PATH_MAX_LENGTH]; - char new_playlist_cores[PATH_MAX_LENGTH]; - bool specialPlaylist = false; - bool foundHiddenPlaylist = false; - - new_playlist_names[0] = new_playlist_cores[0] = '\0'; - - stnames = string_split(settings->arrays.playlist_names, ";"); - stcores = string_split(settings->arrays.playlist_cores, ";"); - - if (selectedItem) - { - currentPlaylistPath = selectedItem->data(Qt::UserRole).toString(); - currentPlaylistFile.setFileName(currentPlaylistPath); - - currentPlaylistFileInfo = QFileInfo(currentPlaylistPath); - currentPlaylistFileName = currentPlaylistFileInfo.fileName(); - currentPlaylistDirPath = currentPlaylistFileInfo.absoluteDir().absolutePath(); - - currentPlaylistFileNameArray.append(currentPlaylistFileName); - currentPlaylistFileNameData = currentPlaylistFileNameArray.constData(); - } - - menu.reset(new QMenu(this)); - menu->setObjectName("menu"); - - hiddenPlaylistsMenu.reset(new QMenu(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS), this)); - newPlaylistAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST)) + "...", this)); - - hiddenPlaylistsMenu->setObjectName("hiddenPlaylistsMenu"); - - menu->addAction(newPlaylistAction.data()); - - if (currentPlaylistFile.exists()) - { - deletePlaylistAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DELETE_PLAYLIST)) + "...", this)); - menu->addAction(deletePlaylistAction.data()); - } - - if (selectedItem) - { - hideAction.reset(new QAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_HIDE), this)); - menu->addAction(hideAction.data()); - } - - for (j = 0; j < m_listWidget->count(); j++) - { - QListWidgetItem *item = m_listWidget->item(j); - bool hidden = m_listWidget->isItemHidden(item); - - if (hidden) - { - QAction *action = hiddenPlaylistsMenu->addAction(item->text()); - action->setProperty("row", j); - action->setProperty("core_path", item->data(Qt::UserRole).toString()); - foundHiddenPlaylist = true; - } - } - - if (!foundHiddenPlaylist) - { - QAction *action = hiddenPlaylistsMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NONE)); - action->setProperty("row", -1); - } - - menu->addMenu(hiddenPlaylistsMenu.data()); - - if (currentPlaylistDirPath != playlistDirAbsPath) - { - /* special playlists like history etc. can't have an association */ - specialPlaylist = true; - } - - if (!specialPlaylist) - { - associateMenu.reset(new QMenu(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE), this)); - associateMenu->setObjectName("associateMenu"); - - core_info_get_list(&core_info_list); - - for (i = 0; i < core_info_list->count && core_info_list->count > 0; i++) - { - const core_info_t *core = &core_info_list->list[i]; - coreList[core->core_name] = core; - } - - { - QMapIterator coreListIterator(coreList); - QVector > cores; - - while (coreListIterator.hasNext()) - { - QString key; - const core_info_t *core = NULL; - QString name; - QHash hash; - - coreListIterator.next(); - - key = coreListIterator.key(); - core = coreList.value(key); - - if (string_is_empty(core->core_name)) - name = core->display_name; - else - name = core->core_name; - - if (name.isEmpty()) - continue; - - hash["name"] = name; - hash["core_path"] = core->path; - - cores.append(hash); - } - - std::sort(cores.begin(), cores.end(), comp_hash_name_key_lower); - - for (j = 0; j < cores.count(); j++) - { - const QHash &hash = cores.at(j); - QAction *action = associateMenu->addAction(hash.value("name")); - - action->setProperty("core_path", hash.value("core_path")); - } - } - - menu->addMenu(associateMenu.data()); - } - - selectedAction = menu->exec(cursorPos); - - if (!selectedAction) - goto end; - - if (!specialPlaylist && selectedAction->parent() == associateMenu.data()) - { - found = string_list_find_elem(stnames, currentPlaylistFileNameData); - - if (found) - string_list_set(stcores, static_cast(found - 1), selectedAction->property("core_path").toString().toUtf8().constData()); - else - { - string_list_append(stnames, currentPlaylistFileNameData, attr); - string_list_append(stcores, "DETECT", attr); - - found = string_list_find_elem(stnames, currentPlaylistFileNameData); - - if (found) - string_list_set(stcores, static_cast(found - 1), selectedAction->property("core_path").toString().toUtf8().constData()); - } - - string_list_join_concat(new_playlist_names, - sizeof(new_playlist_names), stnames, ";"); - string_list_join_concat(new_playlist_cores, - sizeof(new_playlist_cores), stcores, ";"); - - strlcpy(settings->arrays.playlist_names, - new_playlist_names, sizeof(settings->arrays.playlist_names)); - strlcpy(settings->arrays.playlist_cores, - new_playlist_cores, sizeof(settings->arrays.playlist_cores)); - } - else if (selectedAction == deletePlaylistAction.data()) - { - if (currentPlaylistFile.exists()) - { - if (showMessageBox(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST)).arg(selectedItem->text()), MainWindow::MSGBOX_TYPE_QUESTION_YESNO, Qt::ApplicationModal, false)) - { - if (currentPlaylistFile.remove()) - reloadPlaylists(); - else - showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_DELETE_FILE), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); - } - } - } - else if (selectedAction == newPlaylistAction.data()) - { - QString name = QInputDialog::getText(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ENTER_NEW_PLAYLIST_NAME)); - QString newPlaylistPath = playlistDirAbsPath + "/" + name + file_path_str(FILE_PATH_LPL_EXTENSION); - QFile file(newPlaylistPath); - - if (file.open(QIODevice::WriteOnly)) - file.close(); - - reloadPlaylists(); - } - else if (selectedAction == hideAction.data()) - { - int row = m_listWidget->row(selectedItem); - - if (row >= 0) - { - QStringList hiddenPlaylists = m_settings->value("hidden_playlists").toStringList(); - - if (!hiddenPlaylists.contains(currentPlaylistFileName)) - { - hiddenPlaylists.append(currentPlaylistFileName); - m_settings->setValue("hidden_playlists", hiddenPlaylists); - } - - m_listWidget->setRowHidden(row, true); - } - } - else if (selectedAction->parent() == hiddenPlaylistsMenu.data()) - { - QVariant rowVariant = selectedAction->property("row"); - - if (rowVariant.isValid()) - { - QStringList hiddenPlaylists = m_settings->value("hidden_playlists").toStringList(); - int row = rowVariant.toInt(); - - if (row >= 0) - { - QString playlistPath = selectedAction->property("core_path").toString(); - QFileInfo playlistFileInfo(playlistPath); - QString playlistFileName = playlistFileInfo.fileName(); - - if (hiddenPlaylists.contains(playlistFileName)) - { - hiddenPlaylists.removeOne(playlistFileName); - m_settings->setValue("hidden_playlists", hiddenPlaylists); - } - - m_listWidget->setRowHidden(row, false); - } - } - } - - setCoreActions(); - -end: - if (stnames) - string_list_free(stnames); - if (stcores) - string_list_free(stcores); -} - void MainWindow::onFileBrowserTreeContextMenuRequested(const QPoint&) { #ifdef HAVE_LIBRETRODB @@ -2141,7 +970,7 @@ void MainWindow::onFileBrowserTreeContextMenuRequested(const QPoint&) QList actions; QScopedPointer scanAction; QDir dir; - QString currentDirString = m_dirModel->filePath(m_dirTree->currentIndex()); + QString currentDirString = QDir::toNativeSeparators(m_dirModel->filePath(m_dirTree->currentIndex())); settings_t *settings = config_get_ptr(); QByteArray dirArray; const char *fullpath = NULL; @@ -2214,149 +1043,41 @@ void MainWindow::onGotStatusMessage(QString msg, unsigned priority, unsigned dur } } -void MainWindow::deferReloadPlaylists() +void MainWindow::deferReloadShaderParams() { - emit gotReloadPlaylists(); + emit gotReloadShaderParams(); } -void MainWindow::onGotReloadPlaylists() +void MainWindow::onShaderParamsClicked() { - reloadPlaylists(); + if (!m_shaderParamsDialog) + return; + + m_shaderParamsDialog->show(); + + onGotReloadShaderParams(); } -void MainWindow::reloadPlaylists() +void MainWindow::onCoreOptionsClicked() { - QListWidgetItem *allPlaylistsItem = NULL; - QListWidgetItem *favoritesPlaylistsItem = NULL; - QListWidgetItem *imagePlaylistsItem = NULL; - QListWidgetItem *musicPlaylistsItem = NULL; - QListWidgetItem *videoPlaylistsItem = NULL; - QListWidgetItem *firstItem = NULL; - QListWidgetItem *currentItem = NULL; - settings_t *settings = config_get_ptr(); - QDir playlistDir(settings->paths.directory_playlist); - QString currentPlaylistPath; - QStringList hiddenPlaylists = m_settings->value("hidden_playlists").toStringList(); - int i = 0; + if (!m_coreOptionsDialog) + return; - currentItem = m_listWidget->currentItem(); + m_coreOptionsDialog->show(); - if (currentItem) - { - currentPlaylistPath = currentItem->data(Qt::UserRole).toString(); - } + onGotReloadCoreOptions(); +} - getPlaylistFiles(); +void MainWindow::onGotReloadShaderParams() +{ + if (m_shaderParamsDialog && m_shaderParamsDialog->isVisible()) + m_shaderParamsDialog->reload(); +} - m_listWidget->clear(); - - allPlaylistsItem = new QListWidgetItem(m_folderIcon, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ALL_PLAYLISTS)); - allPlaylistsItem->setData(Qt::UserRole, ALL_PLAYLISTS_TOKEN); - - favoritesPlaylistsItem = new QListWidgetItem(m_folderIcon, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FAVORITES_TAB)); - favoritesPlaylistsItem->setData(Qt::UserRole, settings->paths.path_content_favorites); - - m_historyPlaylistsItem = new QListWidgetItem(m_folderIcon, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_HISTORY_TAB)); - m_historyPlaylistsItem->setData(Qt::UserRole, settings->paths.path_content_history); - - imagePlaylistsItem = new QListWidgetItem(m_folderIcon, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_IMAGES_TAB)); - imagePlaylistsItem->setData(Qt::UserRole, settings->paths.path_content_image_history); - - musicPlaylistsItem = new QListWidgetItem(m_folderIcon, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MUSIC_TAB)); - musicPlaylistsItem->setData(Qt::UserRole, settings->paths.path_content_music_history); - - videoPlaylistsItem = new QListWidgetItem(m_folderIcon, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_TAB)); - videoPlaylistsItem->setData(Qt::UserRole, settings->paths.path_content_video_history); - - m_listWidget->addItem(allPlaylistsItem); - m_listWidget->addItem(favoritesPlaylistsItem); - m_listWidget->addItem(m_historyPlaylistsItem); - m_listWidget->addItem(imagePlaylistsItem); - m_listWidget->addItem(musicPlaylistsItem); - m_listWidget->addItem(videoPlaylistsItem); - - if (hiddenPlaylists.contains(ALL_PLAYLISTS_TOKEN)) - m_listWidget->setRowHidden(m_listWidget->row(allPlaylistsItem), true); - if (hiddenPlaylists.contains(QFileInfo(settings->paths.path_content_favorites).fileName())) - m_listWidget->setRowHidden(m_listWidget->row(favoritesPlaylistsItem), true); - if (hiddenPlaylists.contains(QFileInfo(settings->paths.path_content_history).fileName())) - m_listWidget->setRowHidden(m_listWidget->row(m_historyPlaylistsItem), true); - if (hiddenPlaylists.contains(QFileInfo(settings->paths.path_content_image_history).fileName())) - m_listWidget->setRowHidden(m_listWidget->row(imagePlaylistsItem), true); - if (hiddenPlaylists.contains(QFileInfo(settings->paths.path_content_music_history).fileName())) - m_listWidget->setRowHidden(m_listWidget->row(musicPlaylistsItem), true); - if (hiddenPlaylists.contains(QFileInfo(settings->paths.path_content_video_history).fileName())) - m_listWidget->setRowHidden(m_listWidget->row(videoPlaylistsItem), true); - - for (i = 0; i < m_playlistFiles.count(); i++) - { - QListWidgetItem *item = NULL; - const QString &file = m_playlistFiles.at(i); - QString fileDisplayName = file; - QString fileName = file; - bool hasIcon = false; - QIcon icon; - QString iconPath; - - fileDisplayName.remove(file_path_str(FILE_PATH_LPL_EXTENSION)); - - iconPath = QString(settings->paths.directory_assets) + ICON_PATH + fileDisplayName + ".png"; - - hasIcon = QFile::exists(iconPath); - - if (hasIcon) - icon = QIcon(iconPath); - else - icon = m_folderIcon; - - item = new QListWidgetItem(icon, fileDisplayName); - item->setData(Qt::UserRole, playlistDir.absoluteFilePath(file)); - - m_listWidget->addItem(item); - - if (hiddenPlaylists.contains(fileName)) - { - int row = m_listWidget->row(item); - - if (row >= 0) - m_listWidget->setRowHidden(row, true); - } - } - - if (m_listWidget->count() > 0) - { - firstItem = m_listWidget->item(0); - - if (firstItem) - { - bool found = false; - - for (i = 0; i < m_listWidget->count(); i++) - { - QListWidgetItem *item = m_listWidget->item(i); - QString path; - - if (item) - { - path = item->data(Qt::UserRole).toString(); - - if (!currentPlaylistPath.isEmpty() && !path.isEmpty()) - { - if (path == currentPlaylistPath) - { - found = true; - m_listWidget->setCurrentItem(item); - break; - } - } - } - } - - /* the previous playlist must be gone now, just select the first one */ - if (!found) - m_listWidget->setCurrentItem(firstItem); - } - } +void MainWindow::onGotReloadCoreOptions() +{ + if (m_coreOptionsDialog && m_coreOptionsDialog->isVisible()) + m_coreOptionsDialog->reload(); } void MainWindow::appendLogMessage(const QString &msg) @@ -2824,7 +1545,7 @@ void MainWindow::selectBrowserDir(QString path) QString fileName = dirList.at(i); QTableWidgetItem *item = new QTableWidgetItem(fileName); QHash hash; - QString filePath(dir.absoluteFilePath(fileName)); + QString filePath(QDir::toNativeSeparators(dir.absoluteFilePath(fileName))); QFileInfo fileInfo(filePath); hash["path"] = filePath; @@ -2861,24 +1582,9 @@ void MainWindow::onTableWidgetDeletePressed() deleteCurrentPlaylistItem(); } -QString MainWindow::getCurrentPlaylistPath() -{ - QListWidgetItem *playlistItem = m_listWidget->currentItem(); - QHash contentHash; - QString playlistPath; - - if (!playlistItem) - return playlistPath; - - playlistPath = playlistItem->data(Qt::UserRole).toString(); - - return playlistPath; -} - QHash MainWindow::getCurrentContentHash() { QTableWidgetItem *contentItem = m_tableWidget->currentItem(); - QListWidgetItem *playlistItem = m_listWidget->currentItem(); QHash contentHash; ViewType viewType = getCurrentViewType(); @@ -2895,42 +1601,6 @@ QHash MainWindow::getCurrentContentHash() return contentHash; } -void MainWindow::deleteCurrentPlaylistItem() -{ - QString playlistPath = getCurrentPlaylistPath(); - QByteArray playlistArray; - QHash contentHash = getCurrentContentHash(); - playlist_t *playlist = NULL; - const char *playlistData = NULL; - unsigned index = 0; - bool ok = false; - - if (playlistPath.isEmpty()) - return; - - if (contentHash.isEmpty()) - return; - - playlistArray = playlistPath.toUtf8(); - playlistData = playlistArray.constData(); - - index = contentHash.value("index").toUInt(&ok); - - if (!ok) - return; - - if (!showMessageBox(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST_ITEM)).arg(contentHash["label"]), MainWindow::MSGBOX_TYPE_QUESTION_YESNO, Qt::ApplicationModal, false)) - return; - - playlist = playlist_init(playlistData, COLLECTION_SIZE); - - playlist_delete_index(playlist, index); - playlist_write_file(playlist); - playlist_free(playlist); - - reloadPlaylists(); -} - void MainWindow::onContentItemDoubleClicked(QTableWidgetItem*) { onRunClicked(); @@ -3212,50 +1882,6 @@ ViewOptionsDialog* MainWindow::viewOptionsDialog() return m_viewOptionsDialog; } -QVector > MainWindow::getPlaylistDefaultCores() -{ - settings_t *settings = config_get_ptr(); - struct string_list *playlists = string_split(settings->arrays.playlist_names, ";"); - struct string_list *cores = string_split(settings->arrays.playlist_cores, ";"); - unsigned i = 0; - QVector > coreList; - - if (!playlists || !cores) - { - RARCH_WARN("[Qt]: Could not parse one of playlist_names or playlist_cores\n"); - goto finish; - } - else if (playlists->size != cores->size) - { - RARCH_WARN("[Qt]: playlist_names array size differs from playlist_cores\n"); - goto finish; - } - - if (playlists->size == 0) - goto finish; - - for (i = 0; i < playlists->size; i++) - { - const char *playlist = playlists->elems[i].data; - const char *core = cores->elems[i].data; - QHash hash; - - hash["playlist_filename"] = playlist; - hash["playlist_filename"].remove(file_path_str(FILE_PATH_LPL_EXTENSION)); - hash["core_path"] = core; - - coreList.append(hash); - } - -finish: - if (playlists) - string_list_free(playlists); - if (cores) - string_list_free(cores); - - return coreList; -} - void MainWindow::setCoreActions() { QTableWidgetItem *currentContentItem = m_tableWidget->currentItem(); @@ -3490,14 +2116,6 @@ QComboBox* MainWindow::launchWithComboBox() return m_launchWithComboBox; } -void MainWindow::getPlaylistFiles() -{ - settings_t *settings = config_get_ptr(); - QDir playlistDir(settings->paths.directory_playlist); - - m_playlistFiles = playlistDir.entryList(QDir::NoDotAndDotDot | QDir::Readable | QDir::Files, QDir::Name); -} - void MainWindow::onSearchLineEditEdited(const QString &text) { int i = 0; @@ -4199,140 +2817,6 @@ GridItem* MainWindow::doDeferredImageLoad(GridItem *item, QString path) return item; } -void MainWindow::addPlaylistItemsToGrid(const QStringList &paths, bool add) -{ - QVector > items; - int i; - - if (paths.isEmpty()) - return; - - for (i = 0; i < paths.size(); i++) - { - int j; - QVector > vec = getPlaylistItems(paths.at(i)); - /* QVector::append() wasn't added until 5.5, so just do it the old fashioned way */ - for (j = 0; j < vec.size(); j++) - { - if (add && m_allPlaylistsGridMaxCount > 0 && items.size() >= m_allPlaylistsGridMaxCount) - goto finish; - - items.append(vec.at(j)); - } - } -finish: - std::sort(items.begin(), items.end(), comp_hash_label_key_lower); - - addPlaylistHashToGrid(items); -} - -void MainWindow::addPlaylistHashToGrid(const QVector > &items) -{ - QScreen *screen = qApp->primaryScreen(); - QSize screenSize = screen->size(); - QListWidgetItem *currentItem = m_listWidget->currentItem(); - settings_t *settings = config_get_ptr(); - int i = 0; - int zoomValue = m_zoomSlider->value(); - - m_gridProgressBar->setMinimum(0); - m_gridProgressBar->setMaximum(qMax(0, items.count() - 1)); - m_gridProgressBar->setValue(0); - - for (i = 0; i < items.count(); i++) - { - const QHash &hash = items.at(i); - QPointer item; - QPointer label; - QString thumbnailFileNameNoExt; - QLabel *newLabel = NULL; - QSize thumbnailWidgetSizeHint(screenSize.width() / 8, screenSize.height() / 8); - QByteArray extension; - QString extensionStr; - QString imagePath; - int lastIndex = -1; - - if (m_listWidget->currentItem() != currentItem) - { - /* user changed the current playlist before we finished loading... abort */ - m_gridProgressWidget->hide(); - break; - } - - item = new GridItem(); - - lastIndex = hash["path"].lastIndexOf('.'); - - if (lastIndex >= 0) - { - extensionStr = hash["path"].mid(lastIndex + 1); - - if (!extensionStr.isEmpty()) - { - extension = extensionStr.toLower().toUtf8(); - } - } - - if (!extension.isEmpty() && m_imageFormats.contains(extension)) - { - /* use thumbnail widgets to show regular image files */ - imagePath = hash["path"]; - } - else - { - thumbnailFileNameNoExt = hash["label_noext"]; - thumbnailFileNameNoExt.replace(m_fileSanitizerRegex, "_"); - imagePath = QString(settings->paths.directory_thumbnails) + "/" + hash.value("db_name") + "/" + THUMBNAIL_BOXART + "/" + thumbnailFileNameNoExt + ".png"; - } - - item->hash = hash; - item->widget = new ThumbnailWidget(); - item->widget->setSizeHint(thumbnailWidgetSizeHint); - item->widget->setFixedSize(item->widget->sizeHint()); - item->widget->setLayout(new QVBoxLayout()); - item->widget->setObjectName("thumbnailWidget"); - item->widget->setProperty("hash", QVariant::fromValue >(hash)); - - connect(item->widget, SIGNAL(mouseDoubleClicked()), this, SLOT(onGridItemDoubleClicked())); - connect(item->widget, SIGNAL(mousePressed()), this, SLOT(onGridItemClicked())); - - label = new ThumbnailLabel(item->widget); - label->setObjectName("thumbnailGridLabel"); - - item->label = label; - item->labelText = hash.value("label"); - - newLabel = new QLabel(item->labelText, item->widget); - newLabel->setObjectName("thumbnailQLabel"); - newLabel->setAlignment(Qt::AlignCenter); - newLabel->setToolTip(item->labelText); - - calcGridItemSize(item, zoomValue); - - item->widget->layout()->addWidget(label); - - item->widget->layout()->addWidget(newLabel); - qobject_cast(item->widget->layout())->setStretchFactor(label, 1); - - m_gridLayout->addWidgetDeferred(item->widget); - m_gridItems.append(item); - - loadImageDeferred(item, imagePath); - - if (i % 25 == 0) - { - /* Needed to update progress dialog while doing a lot of stuff on the main thread. */ - qApp->processEvents(); - } - - m_gridProgressBar->setValue(i); - } - - /* If there's only one entry, a min/max/value of all zero would make an indeterminate progress bar that never ends... so just hide it when we are done. */ - if (m_gridProgressBar->value() == m_gridProgressBar->maximum()) - m_gridProgressWidget->hide(); -} - void MainWindow::initContentGridLayout() { QListWidgetItem *item = m_listWidget->currentItem(); @@ -4481,122 +2965,6 @@ void MainWindow::initContentTableWidget() onSearchEnterPressed(); } -QVector > MainWindow::getPlaylistItems(QString pathString) -{ - QByteArray pathArray; - QVector > items; - const char *pathData = NULL; - playlist_t *playlist = NULL; - unsigned playlistSize = 0; - unsigned i = 0; - - pathArray.append(pathString); - pathData = pathArray.constData(); - - playlist = playlist_init(pathData, COLLECTION_SIZE); - playlistSize = playlist_get_size(playlist); - - for (i = 0; i < playlistSize; i++) - { - const char *path = NULL; - const char *label = NULL; - const char *core_path = NULL; - const char *core_name = NULL; - const char *crc32 = NULL; - const char *db_name = NULL; - QHash hash; - - playlist_get_index(playlist, i, - &path, &label, &core_path, - &core_name, &crc32, &db_name); - - if (string_is_empty(path)) - continue; - else - hash["path"] = path; - - hash["index"] = QString::number(i); - - if (string_is_empty(label)) - { - hash["label"] = path; - hash["label_noext"] = path; - } - else - { - hash["label"] = label; - hash["label_noext"] = label; - } - - if (!string_is_empty(core_path)) - hash["core_path"] = core_path; - - if (!string_is_empty(core_name)) - hash["core_name"] = core_name; - - if (!string_is_empty(crc32)) - hash["crc32"] = crc32; - - if (!string_is_empty(db_name)) - { - hash["db_name"] = db_name; - hash["db_name"].remove(file_path_str(FILE_PATH_LPL_EXTENSION)); - } - - items.append(hash); - } - - playlist_free(playlist); - playlist = NULL; - - return items; -} - -void MainWindow::addPlaylistItemsToTable(const QStringList &paths, bool add) -{ - QVector > items; - int i; - - if (paths.isEmpty()) - return; - - for (i = 0; i < paths.size(); i++) - { - int j; - QVector > vec = getPlaylistItems(paths.at(i)); - /* QVector::append() wasn't added until 5.5, so just do it the old fashioned way */ - for (j = 0; j < vec.size(); j++) - { - if (add && m_allPlaylistsListMaxCount > 0 && items.size() >= m_allPlaylistsListMaxCount) - goto finish; - - items.append(vec.at(j)); - } - } -finish: - addPlaylistHashToTable(items); -} - -void MainWindow::addPlaylistHashToTable(const QVector > &items) -{ - int i = 0; - int oldRowCount = m_tableWidget->rowCount(); - - m_tableWidget->setRowCount(oldRowCount + items.count()); - - for (i = 0; i < items.count(); i++) - { - QTableWidgetItem *labelItem = NULL; - const QHash &hash = items.at(i); - - labelItem = new QTableWidgetItem(hash.value("label")); - labelItem->setData(Qt::UserRole, QVariant::fromValue >(hash)); - labelItem->setFlags(labelItem->flags() & ~Qt::ItemIsEditable); - - m_tableWidget->setItem(oldRowCount + i, 0, labelItem); - } -} - void MainWindow::keyPressEvent(QKeyEvent *event) { /* @@ -4648,22 +3016,6 @@ void MainWindow::closeEvent(QCloseEvent *event) QMainWindow::closeEvent(event); } -void MainWindow::setAllPlaylistsListMaxCount(int count) -{ - if (count < 1) - count = 0; - - m_allPlaylistsListMaxCount = count; -} - -void MainWindow::setAllPlaylistsGridMaxCount(int count) -{ - if (count < 1) - count = 0; - - m_allPlaylistsGridMaxCount = count; -} - void MainWindow::onContributorsClicked() { QScopedPointer dialog(new QDialog()); @@ -4731,168 +3083,22 @@ void MainWindow::showDocs() QDesktopServices::openUrl(QUrl(DOCS_URL)); } -void MainWindow::onUpdateNetworkError(QNetworkReply::NetworkError code) -{ - QNetworkReply *reply = m_updateReply.data(); - QByteArray errorStringArray; - const char *errorStringData = NULL; - - m_updateProgressDialog->cancel(); - - if (!reply) - return; - - errorStringArray = reply->errorString().toUtf8(); - errorStringData = errorStringArray.constData(); - - RARCH_ERR("[Qt]: Network error code %d received: %s\n", code, errorStringData); - - /* Deleting the reply here seems to cause a strange heap-use-after-free crash. */ - /* - reply->disconnect(); - reply->abort(); - reply->deleteLater(); - */ -} - -void MainWindow::onUpdateNetworkSslErrors(const QList &errors) -{ - QNetworkReply *reply = m_updateReply.data(); - int i; - - if (!reply) - return; - - for (i = 0; i < errors.count(); i++) - { - const QSslError &error = errors.at(i); - QString string = QString("Ignoring SSL error code ") + QString::number(error.error()) + ": " + error.errorString(); - QByteArray stringArray = string.toUtf8(); - const char *stringData = stringArray.constData(); - RARCH_ERR("[Qt]: %s\n", stringData); - } - - /* ignore all SSL errors for now, like self-signed, expired etc. */ - reply->ignoreSslErrors(); -} - -void MainWindow::onUpdateDownloadCanceled() -{ - m_updateProgressDialog->cancel(); -} - void MainWindow::onShowErrorMessage(QString msg) { showMessageBox(msg, MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); } -void MainWindow::onRetroArchUpdateDownloadFinished() +void MainWindow::onShowInfoMessage(QString msg) { - QNetworkReply *reply = m_updateReply.data(); - QNetworkReply::NetworkError error; - int code; - - m_updateProgressDialog->cancel(); - - /* At least on Linux, the progress dialog will refuse to hide itself and will stay on screen in a corrupted way if we happen to show an error message in this function. processEvents() will sometimes fix it, other times not... seems random. */ - qApp->processEvents(); - - if (!reply) - return; - - error = reply->error(); - code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - - if (m_updateFile.isOpen()) - m_updateFile.close(); - - if (code != 200) - { - emit showErrorMessageDeferred(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR)) + ": HTTP Code " + QString::number(code)); - RARCH_ERR("[Qt]: RetroArch update failed with HTTP status code: %d\n", code); - reply->disconnect(); - reply->abort(); - reply->deleteLater(); - return; - } - - if (error == QNetworkReply::NoError) - { - int index = m_updateFile.fileName().lastIndexOf(PARTIAL_EXTENSION); - QString newFileName = m_updateFile.fileName().left(index); - QFile newFile(newFileName); - - /* rename() requires the old file to be deleted first if it exists */ - if (newFile.exists() && !newFile.remove()) - RARCH_ERR("[Qt]: RetroArch update finished, but old file could not be deleted.\n"); - else - { - if (m_updateFile.rename(newFileName)) - { - RARCH_LOG("[Qt]: RetroArch update finished downloading successfully.\n"); - emit extractArchiveDeferred(newFileName); - } - else - { - RARCH_ERR("[Qt]: RetroArch update finished, but temp file could not be renamed.\n"); - emit showErrorMessageDeferred(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_RENAME_FILE)); - } - } - } - else - { - QByteArray errorArray = reply->errorString().toUtf8(); - const char *errorData = errorArray.constData(); - - RARCH_ERR("[Qt]: RetroArch update ended prematurely: %s\n", errorData); - emit showErrorMessageDeferred(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR)) + ": Code " + QString::number(code) + ": " + errorData); - } - - reply->disconnect(); - reply->close(); - reply->deleteLater(); + showMessageBox(msg, MainWindow::MSGBOX_TYPE_INFO, Qt::ApplicationModal, false); } -static void extractCB(void *task_data, void *user_data, const char *err) -{ - decompress_task_data_t *dec = (decompress_task_data_t*)task_data; - MainWindow *mainwindow = (MainWindow*)user_data; - - if (err) - RARCH_ERR("%s", err); - - if (dec) - { - if (filestream_exists(dec->source_file)) - filestream_delete(dec->source_file); - - free(dec->source_file); - free(dec); - } - - mainwindow->onUpdateRetroArchFinished(string_is_empty(err)); -} - -void MainWindow::onUpdateRetroArchFinished(bool success) -{ - m_updateProgressDialog->cancel(); - - if (!success) - { - RARCH_ERR("[Qt]: RetroArch update failed.\n"); - emit showErrorMessageDeferred(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FAILED)); - return; - } - - RARCH_LOG("[Qt]: RetroArch update finished successfully.\n"); - - emit showErrorMessageDeferred(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FINISHED)); -} - -int MainWindow::onExtractArchive(QString path) +int MainWindow::onExtractArchive(QString path, QString extractionDir, QString tempExtension, retro_task_callback_t cb) { QByteArray pathArray = path.toUtf8(); + QByteArray dirArray = extractionDir.toUtf8(); const char *file = pathArray.constData(); + const char *dir = dirArray.constData(); file_archive_transfer_t state; struct archive_extract_userdata userdata; struct string_list *file_list = file_archive_get_file_list(file, NULL); @@ -4915,7 +3121,7 @@ int MainWindow::onExtractArchive(QString path) if (!fileObj.remove()) { /* if we cannot delete the existing file to update it, rename it for now and delete later */ - QFile fileTemp(fileObj.fileName() + TEMP_EXTENSION); + QFile fileTemp(fileObj.fileName() + tempExtension); if (fileTemp.exists()) { @@ -4954,9 +3160,9 @@ int MainWindow::onExtractArchive(QString path) m_updateProgressDialog->setCancelButtonText(QString()); m_updateProgressDialog->show(); - if (!task_push_decompress(file, ".", + if (!task_push_decompress(file, dir, NULL, NULL, NULL, - extractCB, this)) + cb, this)) { m_updateProgressDialog->cancel(); return -1; @@ -4965,94 +3171,17 @@ int MainWindow::onExtractArchive(QString path) return returnerr; } -void MainWindow::onUpdateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) +QString MainWindow::getScrubbedString(QString str) { - QNetworkReply *reply = m_updateReply.data(); - int progress = (bytesReceived / (float)bytesTotal) * 100.0f; + const QString chars("&*/:`\"<>?\\|"); + int i; - if (!reply) - return; - - m_updateProgressDialog->setValue(progress); -} - -void MainWindow::onUpdateDownloadReadyRead() -{ - QNetworkReply *reply = m_updateReply.data(); - - if (!reply) - return; - - m_updateFile.write(reply->readAll()); -} - -void MainWindow::updateRetroArchNightly() -{ - QUrl url(QUrl(buildbot_server_url).resolved(QUrl(RETROARCH_NIGHTLY_UPDATE_PATH))); - QNetworkRequest request(url); - QNetworkReply *reply = NULL; - QByteArray urlArray = url.toString().toUtf8(); - const char *urlData = urlArray.constData(); - - if (m_updateFile.isOpen()) + for (i = 0; i < chars.count(); i++) { - RARCH_ERR("[Qt]: File is already open.\n"); - return; - } - else - { - QString fileName = QFileInfo(url.toString()).fileName() + PARTIAL_EXTENSION; - QByteArray fileNameArray = fileName.toUtf8(); - const char *fileNameData = fileNameArray.constData(); - - m_updateFile.setFileName(fileName); - - if (!m_updateFile.open(QIODevice::WriteOnly)) - { - showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FILE_WRITE_OPEN_FAILED), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); - RARCH_ERR("[Qt]: Could not open file for writing: %s\n", fileNameData); - return; - } + str.replace(chars.at(i), '_'); } - RARCH_LOG("[Qt]: Starting update of RetroArch...\n"); - RARCH_LOG("[Qt]: Downloading URL %s\n", urlData); - - request.setHeader(QNetworkRequest::UserAgentHeader, USER_AGENT); - - m_updateProgressDialog->setWindowModality(Qt::NonModal); - m_updateProgressDialog->setMinimumDuration(0); - m_updateProgressDialog->setRange(0, 100); - m_updateProgressDialog->setAutoClose(true); - m_updateProgressDialog->setAutoReset(true); - m_updateProgressDialog->setValue(0); - m_updateProgressDialog->setLabelText(QString(msg_hash_to_str(MSG_DOWNLOADING)) + "..."); - m_updateProgressDialog->setCancelButtonText(tr("Cancel")); - m_updateProgressDialog->show(); - - m_updateReply = m_networkManager->get(request); - reply = m_updateReply.data(); - - /* make sure any previous connection is removed first */ - disconnect(m_updateProgressDialog, SIGNAL(canceled()), reply, SLOT(abort())); - disconnect(m_updateProgressDialog, SIGNAL(canceled()), m_updateProgressDialog, SLOT(cancel())); - connect(m_updateProgressDialog, SIGNAL(canceled()), reply, SLOT(abort())); - connect(m_updateProgressDialog, SIGNAL(canceled()), m_updateProgressDialog, SLOT(cancel())); - - connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onUpdateNetworkError(QNetworkReply::NetworkError))); - connect(reply, SIGNAL(sslErrors(const QList&)), this, SLOT(onUpdateNetworkSslErrors(const QList&))); - connect(reply, SIGNAL(finished()), this, SLOT(onRetroArchUpdateDownloadFinished())); - connect(reply, SIGNAL(readyRead()), this, SLOT(onUpdateDownloadReadyRead())); - connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(onUpdateDownloadProgress(qint64, qint64))); - -} - -const QPixmap getInvader() -{ - QPixmap pix; - pix.loadFromData(invader_png, invader_png_len, "PNG"); - - return pix; + return str; } static void* ui_window_qt_init(void) diff --git a/ui/drivers/qt/updateretroarch.cpp b/ui/drivers/qt/updateretroarch.cpp new file mode 100644 index 0000000000..9f524abc9e --- /dev/null +++ b/ui/drivers/qt/updateretroarch.cpp @@ -0,0 +1,282 @@ +#include +#include +#include + +#include "../ui_qt.h" + +extern "C" { +#include +#include +#include +#include "../../../tasks/tasks_internal.h" +#include "../../../verbosity.h" +#include "../../../config.def.h" +} + +#define USER_AGENT "RetroArch-WIMP/1.0" +#define PARTIAL_EXTENSION ".partial" +#define TEMP_EXTENSION ".update_tmp" +#define RETROARCH_NIGHTLY_UPDATE_PATH "../RetroArch_update.zip" + +static void extractCB(void *task_data, void *user_data, const char *err) +{ + decompress_task_data_t *dec = (decompress_task_data_t*)task_data; + MainWindow *mainwindow = (MainWindow*)user_data; + + if (err) + RARCH_ERR("%s", err); + + if (dec) + { + if (filestream_exists(dec->source_file)) + filestream_delete(dec->source_file); + + free(dec->source_file); + free(dec); + } + + mainwindow->onUpdateRetroArchFinished(string_is_empty(err)); +} + +void MainWindow::removeUpdateTempFiles() +{ + /* a QDir with no path means the current working directory */ + QDir dir; + QStringList dirList = dir.entryList(QStringList(), QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System, QDir::Name); + int i; + + for (i = 0; i < dirList.count(); i++) + { + QString path(dir.path() + "/" + dirList.at(i)); + QFile file(path); + + if (path.endsWith(TEMP_EXTENSION)) + { + QByteArray pathArray = path.toUtf8(); + const char *pathData = pathArray.constData(); + + if (file.remove()) + RARCH_LOG("[Qt]: removed temporary update file %s\n", pathData); + else + RARCH_LOG("[Qt]: could not remove temporary update file %s\n", pathData); + } + } +} + +void MainWindow::onUpdateNetworkError(QNetworkReply::NetworkError code) +{ + QNetworkReply *reply = m_updateReply.data(); + QByteArray errorStringArray; + const char *errorStringData = NULL; + + m_updateProgressDialog->cancel(); + + if (!reply) + return; + + errorStringArray = reply->errorString().toUtf8(); + errorStringData = errorStringArray.constData(); + + RARCH_ERR("[Qt]: Network error code %d received: %s\n", code, errorStringData); + + /* Deleting the reply here seems to cause a strange heap-use-after-free crash. */ + /* + reply->disconnect(); + reply->abort(); + reply->deleteLater(); + */ +} + +void MainWindow::onUpdateNetworkSslErrors(const QList &errors) +{ + QNetworkReply *reply = m_updateReply.data(); + int i; + + if (!reply) + return; + + for (i = 0; i < errors.count(); i++) + { + const QSslError &error = errors.at(i); + QString string = QString("Ignoring SSL error code ") + QString::number(error.error()) + ": " + error.errorString(); + QByteArray stringArray = string.toUtf8(); + const char *stringData = stringArray.constData(); + RARCH_ERR("[Qt]: %s\n", stringData); + } + + /* ignore all SSL errors for now, like self-signed, expired etc. */ + reply->ignoreSslErrors(); +} + +void MainWindow::onUpdateDownloadCanceled() +{ + m_updateProgressDialog->cancel(); +} + +void MainWindow::onRetroArchUpdateDownloadFinished() +{ + QNetworkReply *reply = m_updateReply.data(); + QNetworkReply::NetworkError error; + int code; + + m_updateProgressDialog->cancel(); + + /* At least on Linux, the progress dialog will refuse to hide itself and will stay on screen in a corrupted way if we happen to show an error message in this function. processEvents() will sometimes fix it, other times not... seems random. */ + qApp->processEvents(); + + if (!reply) + return; + + error = reply->error(); + code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (m_updateFile.isOpen()) + m_updateFile.close(); + + if (code != 200) + { + emit showErrorMessageDeferred(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR)) + ": HTTP Code " + QString::number(code)); + RARCH_ERR("[Qt]: RetroArch update failed with HTTP status code: %d\n", code); + reply->disconnect(); + reply->abort(); + reply->deleteLater(); + return; + } + + if (error == QNetworkReply::NoError) + { + int index = m_updateFile.fileName().lastIndexOf(PARTIAL_EXTENSION); + QString newFileName = m_updateFile.fileName().left(index); + QFile newFile(newFileName); + + /* rename() requires the old file to be deleted first if it exists */ + if (newFile.exists() && !newFile.remove()) + RARCH_ERR("[Qt]: RetroArch update finished, but old file could not be deleted.\n"); + else + { + if (m_updateFile.rename(newFileName)) + { + RARCH_LOG("[Qt]: RetroArch update finished downloading successfully.\n"); + emit extractArchiveDeferred(newFileName, ".", TEMP_EXTENSION, extractCB); + } + else + { + RARCH_ERR("[Qt]: RetroArch update finished, but temp file could not be renamed.\n"); + emit showErrorMessageDeferred(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_RENAME_FILE)); + } + } + } + else + { + QByteArray errorArray = reply->errorString().toUtf8(); + const char *errorData = errorArray.constData(); + + m_updateFile.remove(); + + RARCH_ERR("[Qt]: RetroArch update ended prematurely: %s\n", errorData); + emit showErrorMessageDeferred(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR)) + ": Code " + QString::number(code) + ": " + errorData); + } + + reply->disconnect(); + reply->close(); + reply->deleteLater(); +} + +void MainWindow::onUpdateRetroArchFinished(bool success) +{ + m_updateProgressDialog->cancel(); + + if (!success) + { + RARCH_ERR("[Qt]: RetroArch update failed.\n"); + emit showErrorMessageDeferred(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FAILED)); + return; + } + + RARCH_LOG("[Qt]: RetroArch update finished successfully.\n"); + + emit showInfoMessageDeferred(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_UPDATE_RETROARCH_FINISHED)); +} + +void MainWindow::onUpdateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) +{ + QNetworkReply *reply = m_updateReply.data(); + int progress = (bytesReceived / (float)bytesTotal) * 100.0f; + + if (!reply) + return; + + m_updateProgressDialog->setValue(progress); +} + +void MainWindow::onUpdateDownloadReadyRead() +{ + QNetworkReply *reply = m_updateReply.data(); + + if (!reply) + return; + + m_updateFile.write(reply->readAll()); +} + +void MainWindow::updateRetroArchNightly() +{ + QUrl url(QUrl(buildbot_server_url).resolved(QUrl(RETROARCH_NIGHTLY_UPDATE_PATH))); + QNetworkRequest request(url); + QNetworkReply *reply = NULL; + QByteArray urlArray = url.toString().toUtf8(); + const char *urlData = urlArray.constData(); + + if (m_updateFile.isOpen()) + { + RARCH_ERR("[Qt]: File is already open.\n"); + return; + } + else + { + QString fileName = QFileInfo(url.toString()).fileName() + PARTIAL_EXTENSION; + QByteArray fileNameArray = fileName.toUtf8(); + const char *fileNameData = fileNameArray.constData(); + + m_updateFile.setFileName(fileName); + + if (!m_updateFile.open(QIODevice::WriteOnly)) + { + showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FILE_WRITE_OPEN_FAILED), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); + RARCH_ERR("[Qt]: Could not open file for writing: %s\n", fileNameData); + return; + } + } + + RARCH_LOG("[Qt]: Starting update of RetroArch...\n"); + RARCH_LOG("[Qt]: Downloading URL %s\n", urlData); + + request.setHeader(QNetworkRequest::UserAgentHeader, USER_AGENT); + + m_updateProgressDialog->setWindowModality(Qt::NonModal); + m_updateProgressDialog->setMinimumDuration(0); + m_updateProgressDialog->setRange(0, 100); + m_updateProgressDialog->setAutoClose(true); + m_updateProgressDialog->setAutoReset(true); + m_updateProgressDialog->setValue(0); + m_updateProgressDialog->setLabelText(QString(msg_hash_to_str(MSG_DOWNLOADING)) + "..."); + m_updateProgressDialog->setCancelButtonText(tr("Cancel")); + m_updateProgressDialog->show(); + + m_updateReply = m_networkManager->get(request); + + reply = m_updateReply.data(); + + /* make sure any previous connection is removed first */ + disconnect(m_updateProgressDialog, SIGNAL(canceled()), reply, SLOT(abort())); + disconnect(m_updateProgressDialog, SIGNAL(canceled()), m_updateProgressDialog, SLOT(cancel())); + connect(m_updateProgressDialog, SIGNAL(canceled()), reply, SLOT(abort())); + connect(m_updateProgressDialog, SIGNAL(canceled()), m_updateProgressDialog, SLOT(cancel())); + + connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onUpdateNetworkError(QNetworkReply::NetworkError))); + connect(reply, SIGNAL(sslErrors(const QList&)), this, SLOT(onUpdateNetworkSslErrors(const QList&))); + connect(reply, SIGNAL(finished()), this, SLOT(onRetroArchUpdateDownloadFinished())); + connect(reply, SIGNAL(readyRead()), this, SLOT(onUpdateDownloadReadyRead())); + connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(onUpdateDownloadProgress(qint64, qint64))); + +} diff --git a/ui/drivers/qt/viewoptionsdialog.cpp b/ui/drivers/qt/viewoptionsdialog.cpp new file mode 100644 index 0000000000..5d9bce0466 --- /dev/null +++ b/ui/drivers/qt/viewoptionsdialog.cpp @@ -0,0 +1,239 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "viewoptionsdialog.h" +#include "../ui_qt.h" + +extern "C" { +#include "../../../msg_hash.h" +} + +ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) : + QDialog(parent) + ,m_mainwindow(mainwindow) + ,m_settings(mainwindow->settings()) + ,m_saveGeometryCheckBox(new QCheckBox(this)) + ,m_saveDockPositionsCheckBox(new QCheckBox(this)) + ,m_saveLastTabCheckBox(new QCheckBox(this)) + ,m_showHiddenFilesCheckBox(new QCheckBox(this)) + ,m_themeComboBox(new QComboBox(this)) + ,m_startupPlaylistComboBox(new QComboBox(this)) + ,m_highlightColorPushButton(new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CHOOSE), this)) + ,m_highlightColor() + ,m_highlightColorLabel(new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_HIGHLIGHT_COLOR), this)) + ,m_customThemePath() + ,m_suggestLoadedCoreFirstCheckBox(new QCheckBox(this)) + ,m_allPlaylistsListMaxCountSpinBox(new QSpinBox(this)) + ,m_allPlaylistsGridMaxCountSpinBox(new QSpinBox(this)) +{ + QFormLayout *form = new QFormLayout(); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE)); + + m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_SYSTEM_DEFAULT), MainWindow::THEME_SYSTEM_DEFAULT); + m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK), MainWindow::THEME_DARK); + m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM), MainWindow::THEME_CUSTOM); + + m_allPlaylistsListMaxCountSpinBox->setRange(0, 99999); + m_allPlaylistsGridMaxCountSpinBox->setRange(0, 99999); + + form->setFormAlignment(Qt::AlignCenter); + form->setLabelAlignment(Qt::AlignCenter); + + setLayout(new QVBoxLayout(this)); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + connect(this, SIGNAL(accepted()), this, SLOT(onAccepted())); + connect(this, SIGNAL(rejected()), this, SLOT(onRejected())); + + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY), m_saveGeometryCheckBox); + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS), m_saveDockPositionsCheckBox); + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB), m_saveLastTabCheckBox); + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SHOW_HIDDEN_FILES), m_showHiddenFilesCheckBox); + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SUGGEST_LOADED_CORE_FIRST), m_suggestLoadedCoreFirstCheckBox); + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_LIST_MAX_COUNT), m_allPlaylistsListMaxCountSpinBox); + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_GRID_MAX_COUNT), m_allPlaylistsGridMaxCountSpinBox); + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_STARTUP_PLAYLIST), m_startupPlaylistComboBox); + form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME), m_themeComboBox); + form->addRow(m_highlightColorLabel, m_highlightColorPushButton); + + qobject_cast(layout())->addLayout(form); + layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); + layout()->addWidget(buttonBox); + + loadViewOptions(); + + connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThemeComboBoxIndexChanged(int))); + connect(m_highlightColorPushButton, SIGNAL(clicked()), this, SLOT(onHighlightColorChoose())); +} + +void ViewOptionsDialog::onThemeComboBoxIndexChanged(int) +{ + MainWindow::Theme theme = static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()); + + if (theme == MainWindow::THEME_CUSTOM) + { + QString filePath = QFileDialog::getOpenFileName(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SELECT_THEME)); + + if (filePath.isEmpty()) + { + int oldThemeIndex = m_themeComboBox->findData(m_mainwindow->getThemeFromString(m_settings->value("theme", "default").toString())); + + if (m_themeComboBox->count() > oldThemeIndex) + { + disconnect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThemeComboBoxIndexChanged(int))); + m_themeComboBox->setCurrentIndex(oldThemeIndex); + connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThemeComboBoxIndexChanged(int))); + } + } + else + { + m_customThemePath = filePath; + + if (m_mainwindow->setCustomThemeFile(filePath)) + m_mainwindow->setTheme(theme); + } + } + else + m_mainwindow->setTheme(theme); + + showOrHideHighlightColor(); +} + +void ViewOptionsDialog::onHighlightColorChoose() +{ + QPixmap highlightPixmap(m_highlightColorPushButton->iconSize()); + QColor currentHighlightColor = m_settings->value("highlight_color", QApplication::palette().highlight().color()).value(); + QColor newHighlightColor = QColorDialog::getColor(currentHighlightColor, this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SELECT_COLOR)); + + if (newHighlightColor.isValid()) + { + MainWindow::Theme theme = static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()); + + m_highlightColor = newHighlightColor; + m_settings->setValue("highlight_color", m_highlightColor); + highlightPixmap.fill(m_highlightColor); + m_highlightColorPushButton->setIcon(highlightPixmap); + m_mainwindow->setTheme(theme); + } +} + +void ViewOptionsDialog::loadViewOptions() +{ + QColor highlightColor = m_settings->value("highlight_color", QApplication::palette().highlight().color()).value(); + QPixmap highlightPixmap(m_highlightColorPushButton->iconSize()); + QVector > playlists = m_mainwindow->getPlaylists(); + QString initialPlaylist = m_settings->value("initial_playlist", m_mainwindow->getSpecialPlaylistPath(SPECIAL_PLAYLIST_HISTORY)).toString(); + int themeIndex = 0; + int playlistIndex = 0; + int i; + + m_saveGeometryCheckBox->setChecked(m_settings->value("save_geometry", false).toBool()); + m_saveDockPositionsCheckBox->setChecked(m_settings->value("save_dock_positions", false).toBool()); + m_saveLastTabCheckBox->setChecked(m_settings->value("save_last_tab", false).toBool()); + m_showHiddenFilesCheckBox->setChecked(m_settings->value("show_hidden_files", true).toBool()); + m_suggestLoadedCoreFirstCheckBox->setChecked(m_settings->value("suggest_loaded_core_first", false).toBool()); + m_allPlaylistsListMaxCountSpinBox->setValue(m_settings->value("all_playlists_list_max_count", 0).toInt()); + m_allPlaylistsGridMaxCountSpinBox->setValue(m_settings->value("all_playlists_grid_max_count", 5000).toInt()); + + themeIndex = m_themeComboBox->findData(m_mainwindow->getThemeFromString(m_settings->value("theme", "default").toString())); + + if (m_themeComboBox->count() > themeIndex) + m_themeComboBox->setCurrentIndex(themeIndex); + + if (highlightColor.isValid()) + { + m_highlightColor = highlightColor; + highlightPixmap.fill(m_highlightColor); + m_highlightColorPushButton->setIcon(highlightPixmap); + } + + showOrHideHighlightColor(); + + m_startupPlaylistComboBox->clear(); + + for (i = 0; i < playlists.count(); i++) + { + const QPair &pair = playlists.at(i); + + m_startupPlaylistComboBox->addItem(pair.first, pair.second); + } + + playlistIndex = m_startupPlaylistComboBox->findData(initialPlaylist, Qt::UserRole, Qt::MatchFixedString); + + if (playlistIndex >= 0) + m_startupPlaylistComboBox->setCurrentIndex(playlistIndex); +} + +void ViewOptionsDialog::showOrHideHighlightColor() +{ + if (m_mainwindow->theme() == MainWindow::THEME_DARK) + { + m_highlightColorLabel->show(); + m_highlightColorPushButton->show(); + } + else + { + m_highlightColorLabel->hide(); + m_highlightColorPushButton->hide(); + } +} + +void ViewOptionsDialog::saveViewOptions() +{ + m_settings->setValue("save_geometry", m_saveGeometryCheckBox->isChecked()); + m_settings->setValue("save_dock_positions", m_saveDockPositionsCheckBox->isChecked()); + m_settings->setValue("save_last_tab", m_saveLastTabCheckBox->isChecked()); + m_settings->setValue("theme", m_mainwindow->getThemeString(static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()))); + m_settings->setValue("show_hidden_files", m_showHiddenFilesCheckBox->isChecked()); + m_settings->setValue("highlight_color", m_highlightColor); + m_settings->setValue("suggest_loaded_core_first", m_suggestLoadedCoreFirstCheckBox->isChecked()); + m_settings->setValue("all_playlists_list_max_count", m_allPlaylistsListMaxCountSpinBox->value()); + m_settings->setValue("all_playlists_grid_max_count", m_allPlaylistsGridMaxCountSpinBox->value()); + m_settings->setValue("initial_playlist", m_startupPlaylistComboBox->currentData(Qt::UserRole).toString()); + + if (!m_mainwindow->customThemeString().isEmpty()) + m_settings->setValue("custom_theme", m_customThemePath); + + m_mainwindow->setAllPlaylistsListMaxCount(m_allPlaylistsListMaxCountSpinBox->value()); + m_mainwindow->setAllPlaylistsGridMaxCount(m_allPlaylistsGridMaxCountSpinBox->value()); +} + +void ViewOptionsDialog::onAccepted() +{ + MainWindow::Theme newTheme = static_cast(m_themeComboBox->currentData(Qt::UserRole).toInt()); + + m_mainwindow->setTheme(newTheme); + + saveViewOptions(); +} + +void ViewOptionsDialog::onRejected() +{ + loadViewOptions(); +} + +void ViewOptionsDialog::showDialog() +{ + loadViewOptions(); + show(); +} + +void ViewOptionsDialog::hideDialog() +{ + reject(); +} + diff --git a/ui/drivers/qt/viewoptionsdialog.h b/ui/drivers/qt/viewoptionsdialog.h new file mode 100644 index 0000000000..faf0f143df --- /dev/null +++ b/ui/drivers/qt/viewoptionsdialog.h @@ -0,0 +1,50 @@ +#ifndef VIEWOPTIONSDIALOG_H +#define VIEWOPTIONSDIALOG_H + +#include + +class MainWindow; +class QSettings; +class QCheckBox; +class QComboBox; +class QPushButton; +class QColor; +class QLabel; +class QSpinBox; + +class ViewOptionsDialog : public QDialog +{ + Q_OBJECT +public: + ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent = 0); +public slots: + void showDialog(); + void hideDialog(); + void onAccepted(); + void onRejected(); +private slots: + void onThemeComboBoxIndexChanged(int index); + void onHighlightColorChoose(); +private: + void loadViewOptions(); + void saveViewOptions(); + void showOrHideHighlightColor(); + + MainWindow *m_mainwindow; + QSettings *m_settings; + QCheckBox *m_saveGeometryCheckBox; + QCheckBox *m_saveDockPositionsCheckBox; + QCheckBox *m_saveLastTabCheckBox; + QCheckBox *m_showHiddenFilesCheckBox; + QComboBox *m_themeComboBox; + QComboBox *m_startupPlaylistComboBox; + QPushButton *m_highlightColorPushButton; + QColor m_highlightColor; + QLabel *m_highlightColorLabel; + QString m_customThemePath; + QCheckBox *m_suggestLoadedCoreFirstCheckBox; + QSpinBox *m_allPlaylistsListMaxCountSpinBox; + QSpinBox *m_allPlaylistsGridMaxCountSpinBox; +}; + +#endif diff --git a/ui/drivers/ui_cocoa.m b/ui/drivers/ui_cocoa.m index aced897a60..76c27bdaf5 100644 --- a/ui/drivers/ui_cocoa.m +++ b/ui/drivers/ui_cocoa.m @@ -37,11 +37,12 @@ #include "../../retroarch.h" #include "../../tasks/tasks_internal.h" -#if HAVE_METAL +#ifdef HAVE_METAL #import #import #endif +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 @interface WindowListener : NSResponder @end @@ -59,6 +60,7 @@ {} @end +#endif id apple_platform; @@ -72,7 +74,9 @@ id apple_platform; apple_view_type_t _vt; NSView* _renderView; id _sleepActivity; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 WindowListener *_listener; +#endif } @property (nonatomic, retain) NSWindow IBOutlet* window; @@ -251,7 +255,7 @@ static char** waiting_argv; { unsigned i; apple_platform = self; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 self.window.collectionBehavior = NSWindowCollectionBehaviorFullScreenPrimary; #else SEL selector = NSSelectorFromString(BOXSTRING("setCollectionBehavior:")); @@ -264,11 +268,15 @@ static char** waiting_argv; } #endif +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 _listener = [WindowListener new]; +#endif [self.window setAcceptsMouseMovedEvents: YES]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 [self.window setNextResponder:_listener]; self.window.delegate = _listener; +#endif [[self.window contentView] setAutoresizesSubviews:YES]; @@ -286,8 +294,10 @@ static char** waiting_argv; waiting_argc = 0; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 [self.window makeMainWindow]; [self.window makeKeyWindow]; +#endif [self performSelectorOnMainThread:@selector(rarch_main) withObject:nil waitUntilDone:NO]; } @@ -305,7 +315,9 @@ static char** waiting_argv; _renderView.wantsLayer = NO; _renderView.layer = nil; [_renderView removeFromSuperview]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 self.window.contentView = nil; +#endif _renderView = nil; } @@ -334,10 +346,17 @@ static char** waiting_argv; } _renderView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; - _renderView.frame = self.window.contentView.bounds; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 + _renderView.frame = self.window.contentView.bounds; self.window.contentView = _renderView; [self.window.contentView setNextResponder:_listener]; +#else + /* TODO/FIXME - Aussiebloke - we need a workaround for OSX 10.5 for self.window.contentView.bounds - + * error - request for member 'bounds' in something not a structure or union. */ + [self.window.contentView addSubview:_renderView]; + [self.window makeFirstResponder:_renderView]; +#endif } - (apple_view_type_t)viewType { @@ -353,6 +372,7 @@ static char** waiting_argv; } - (void)setVideoMode:(gfx_ctx_mode_t)mode { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 BOOL isFullScreen = (self.window.styleMask & NSFullScreenWindowMask) == NSFullScreenWindowMask; if (mode.fullscreen && !isFullScreen) { @@ -366,11 +386,14 @@ static char** waiting_argv; } if (mode.width > 0) +#endif { // HACK(sgc): ensure MTKView posts a drawable resize event [self.window setContentSize:NSMakeSize(mode.width-1, mode.height)]; } +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 [self.window setContentSize:NSMakeSize(mode.width, mode.height)]; +#endif } - (void)setCursorVisible:(bool)v { @@ -382,7 +405,7 @@ static char** waiting_argv; - (bool)setDisableDisplaySleep:(bool)disable { -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 if (disable && _sleepActivity == nil) { _sleepActivity = [NSProcessInfo.processInfo beginActivityWithOptions:NSActivityIdleDisplaySleepDisabled reason:@"disable screen saver"]; diff --git a/ui/drivers/ui_qt.cpp b/ui/drivers/ui_qt.cpp index 690635a4aa..1c494f1e99 100644 --- a/ui/drivers/ui_qt.cpp +++ b/ui/drivers/ui_qt.cpp @@ -16,6 +16,7 @@ extern "C" { #include +#include #ifdef HAVE_CONFIG_H #include "../../config.h" @@ -31,6 +32,8 @@ extern "C" { } #include "ui_qt.h" +#include "qt/filedropwidget.h" +#include "qt/viewoptionsdialog.h" #include #include @@ -257,6 +260,9 @@ static void* ui_companion_qt_init(void) QComboBox *launchWithComboBox = NULL; QSettings *qsettings = NULL; QListWidget *listWidget = NULL; + QString initialPlaylist; + bool foundPlaylist = false; + int i = 0; if (!handle) @@ -272,6 +278,8 @@ static void* ui_companion_qt_init(void) qsettings = mainwindow->settings(); + initialPlaylist = qsettings->value("initial_playlist", mainwindow->getSpecialPlaylistPath(SPECIAL_PLAYLIST_HISTORY)).toString(); + mainwindow->resize(qMin(desktopRect.width(), INITIAL_WIDTH), qMin(desktopRect.height(), INITIAL_HEIGHT)); mainwindow->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, mainwindow->size(), desktopRect)); @@ -321,6 +329,9 @@ static void* ui_companion_qt_init(void) QObject::connect(viewClosedDocksMenu, SIGNAL(aboutToShow()), mainwindow, SLOT(onViewClosedDocksAboutToShow())); + viewMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CORE_OPTIONS), mainwindow, SLOT(onCoreOptionsClicked())); + viewMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS), mainwindow, SLOT(onShaderParamsClicked())); + viewMenu->addSeparator(); viewMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_ICONS), mainwindow, SLOT(onIconViewClicked())); viewMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_VIEW_TYPE_LIST), mainwindow, SLOT(onListViewClicked())); @@ -566,16 +577,40 @@ static void* ui_companion_qt_init(void) mainwindow->onTabWidgetIndexChanged(0); } - for (i = 0; i < listWidget->count() && listWidget->count() > 0; i++) + /* the initial playlist that is selected is based on the user's setting (initialPlaylist) */ + for (i = 0; listWidget->count() && i < listWidget->count(); i++) { - /* select the first non-hidden row */ - if (!listWidget->isRowHidden(i)) + QListWidgetItem *item = listWidget->item(i); + QString path; + + if (!item) + continue; + + path = item->data(Qt::UserRole).toString(); + + if (path == initialPlaylist) { + foundPlaylist = true; + listWidget->setRowHidden(i, false); listWidget->setCurrentRow(i); break; } } + /* couldn't find the user's initial playlist, just find anything */ + if (!foundPlaylist) + { + for (i = 0; listWidget->count() && i < listWidget->count(); i++) + { + /* select the first non-hidden row */ + if (!listWidget->isRowHidden(i)) + { + listWidget->setCurrentRow(i); + break; + } + } + } + return handle; } @@ -602,6 +637,11 @@ static void ui_companion_qt_toggle(void *data, bool force) #endif if (settings->bools.ui_companion_toggle || force) { + if (settings->bools.video_fullscreen) + command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL); + + win_handle->qtWindow->activateWindow(); + win_handle->qtWindow->raise(); video_driver_show_mouse(); win_handle->qtWindow->show(); @@ -621,11 +661,21 @@ static void ui_companion_qt_toggle(void *data, bool force) static void ui_companion_qt_event_command(void *data, enum event_command cmd) { ui_companion_qt_t *handle = (ui_companion_qt_t*)data; - - (void)cmd; + ui_window_qt_t *win_handle = (ui_window_qt_t*)handle->window; if (!handle) return; + + switch (cmd) + { + case CMD_EVENT_SHADERS_APPLY_CHANGES: + case CMD_EVENT_SHADER_PRESET_LOADED: + RARCH_LOG("[Qt]: Reloading shader parameters.\n"); + win_handle->qtWindow->deferReloadShaderParams(); + break; + default: + break; + } } static void ui_companion_qt_notify_list_pushed(void *data, file_list_t *list, diff --git a/ui/drivers/ui_qt.h b/ui/drivers/ui_qt.h index 628ae62d31..0084890e88 100644 --- a/ui/drivers/ui_qt.h +++ b/ui/drivers/ui_qt.h @@ -41,9 +41,17 @@ extern "C" { #include #include +#include #include "../ui_companion_driver.h" +#include "../../gfx/video_driver.h" } +#define ALL_PLAYLISTS_TOKEN "|||ALL|||" +#define ICON_PATH "/xmb/dot-art/png/" +#define THUMBNAIL_BOXART "Named_Boxarts" +#define THUMBNAIL_SCREENSHOT "Named_Snaps" +#define THUMBNAIL_TITLE "Named_Titles" + class QApplication; class QCloseEvent; class QKeyEvent; @@ -77,6 +85,16 @@ class MainWindow; class ThumbnailWidget; class ThumbnailLabel; class FlowLayout; +class ShaderParamsDialog; +class CoreOptionsDialog; +class CoreInfoDialog; +class PlaylistEntryDialog; +class ViewOptionsDialog; + +enum SpecialPlaylist +{ + SPECIAL_PLAYLIST_HISTORY +}; class GridItem : public QObject { @@ -146,21 +164,6 @@ protected slots: void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); }; -class FileDropWidget : public QWidget -{ - Q_OBJECT -public: - FileDropWidget(QWidget *parent = 0); -signals: - void filesDropped(QStringList files); - void deletePressed(); -protected: - void dragEnterEvent(QDragEnterEvent *event); - void dropEvent(QDropEvent *event); - void keyPressEvent(QKeyEvent *event); - void paintEvent(QPaintEvent *event); -}; - class TableWidget : public QTableWidget { Q_OBJECT @@ -187,68 +190,6 @@ private slots: void onLastWindowClosed(); }; -class PlaylistEntryDialog : public QDialog -{ - Q_OBJECT -public: - PlaylistEntryDialog(MainWindow *mainwindow, QWidget *parent = 0); - const QHash getSelectedCore(); - const QString getSelectedDatabase(); - const QString getSelectedName(); - const QString getSelectedPath(); - void setEntryValues(const QHash &contentHash); -public slots: - bool showDialog(const QHash &hash = QHash()); - void hideDialog(); - void onAccepted(); - void onRejected(); -private slots: - void onPathClicked(); -private: - void loadPlaylistOptions(); - - MainWindow *m_mainwindow; - QSettings *m_settings; - QLineEdit *m_nameLineEdit; - QLineEdit *m_pathLineEdit; - QComboBox *m_coreComboBox; - QComboBox *m_databaseComboBox; -}; - -class ViewOptionsDialog : public QDialog -{ - Q_OBJECT -public: - ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent = 0); -public slots: - void showDialog(); - void hideDialog(); - void onAccepted(); - void onRejected(); -private slots: - void onThemeComboBoxIndexChanged(int index); - void onHighlightColorChoose(); -private: - void loadViewOptions(); - void saveViewOptions(); - void showOrHideHighlightColor(); - - MainWindow *m_mainwindow; - QSettings *m_settings; - QCheckBox *m_saveGeometryCheckBox; - QCheckBox *m_saveDockPositionsCheckBox; - QCheckBox *m_saveLastTabCheckBox; - QCheckBox *m_showHiddenFilesCheckBox; - QComboBox *m_themeComboBox; - QPushButton *m_highlightColorPushButton; - QColor m_highlightColor; - QLabel *m_highlightColorLabel; - QString m_customThemePath; - QCheckBox *m_suggestLoadedCoreFirstCheckBox; - QSpinBox *m_allPlaylistsListMaxCountSpinBox; - QSpinBox *m_allPlaylistsGridMaxCountSpinBox; -}; - class CoreInfoLabel : public QLabel { Q_OBJECT @@ -256,18 +197,6 @@ public: CoreInfoLabel(QString text = QString(), QWidget *parent = 0); }; -class CoreInfoDialog : public QDialog -{ - Q_OBJECT -public: - CoreInfoDialog(MainWindow *mainwindow, QWidget *parent = 0); -public slots: - void showCoreInfo(); -private: - QFormLayout *m_formLayout; - MainWindow *m_mainwindow; -}; - class CoreInfoWidget : public QWidget { Q_OBJECT @@ -356,6 +285,10 @@ public: void addFilesToPlaylist(QStringList files); QString getCurrentPlaylistPath(); QHash getCurrentContentHash(); + static double lerp(double x, double y, double a, double b, double d); + QString getSpecialPlaylistPath(SpecialPlaylist playlist); + QVector > getPlaylists(); + QString getScrubbedString(QString str); signals: void thumbnailChanged(const QPixmap &pixmap); @@ -364,8 +297,14 @@ signals: void gotLogMessage(const QString &msg); void gotStatusMessage(QString msg, unsigned priority, unsigned duration, bool flush); void gotReloadPlaylists(); + void gotReloadShaderParams(); + void gotReloadCoreOptions(); void showErrorMessageDeferred(QString msg); - void extractArchiveDeferred(QString path); + void showInfoMessageDeferred(QString msg); + void extractArchiveDeferred(QString path, QString extractionDir, QString tempExtension, retro_task_callback_t cb); + void itemChanged(); + void gridItemChanged(QString title); + void gotThumbnailDownload(QString system, QString title); public slots: void onBrowserDownloadsClicked(); @@ -392,6 +331,8 @@ public slots: void reloadPlaylists(); void deferReloadPlaylists(); void onGotReloadPlaylists(); + void onGotReloadShaderParams(); + void onGotReloadCoreOptions(); void showWelcomeScreen(); void onIconViewClicked(); void onListViewClicked(); @@ -402,6 +343,12 @@ public slots: void showDocs(); void updateRetroArchNightly(); void onUpdateRetroArchFinished(bool success); + void onThumbnailPackExtractFinished(bool success); + void deferReloadShaderParams(); + void downloadThumbnail(QString system, QString title, QUrl url = QUrl()); + void downloadAllThumbnails(QString system, QUrl url = QUrl()); + void downloadPlaylistThumbnails(QString playlistPath); + void downloadNextPlaylistThumbnail(QString system, QString title, QString type, QUrl url = QUrl()); private slots: void onLoadCoreClicked(const QStringList &extensionFilters = QStringList()); @@ -433,15 +380,43 @@ private slots: void onGridItemDoubleClicked(); void onGridItemClicked(ThumbnailWidget *thumbnailWidget = NULL); void onPlaylistFilesDropped(QStringList files); + void onShaderParamsClicked(); + void onCoreOptionsClicked(); + void onShowErrorMessage(QString msg); + void onShowInfoMessage(QString msg); + void onContributorsClicked(); + void onItemChanged(); + void onGridItemChanged(QString title); + int onExtractArchive(QString path, QString extractionDir, QString tempExtension, retro_task_callback_t cb); + void onUpdateNetworkError(QNetworkReply::NetworkError code); void onUpdateNetworkSslErrors(const QList &errors); void onRetroArchUpdateDownloadFinished(); void onUpdateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); void onUpdateDownloadReadyRead(); void onUpdateDownloadCanceled(); - void onShowErrorMessage(QString msg); - void onContributorsClicked(); - int onExtractArchive(QString path); + + void onThumbnailDownloadNetworkError(QNetworkReply::NetworkError code); + void onThumbnailDownloadNetworkSslErrors(const QList &errors); + void onThumbnailDownloadFinished(); + void onThumbnailDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); + void onThumbnailDownloadReadyRead(); + void onThumbnailDownloadCanceled(); + void onDownloadThumbnail(QString system, QString title); + + void onThumbnailPackDownloadNetworkError(QNetworkReply::NetworkError code); + void onThumbnailPackDownloadNetworkSslErrors(const QList &errors); + void onThumbnailPackDownloadFinished(); + void onThumbnailPackDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); + void onThumbnailPackDownloadReadyRead(); + void onThumbnailPackDownloadCanceled(); + + void onPlaylistThumbnailDownloadNetworkError(QNetworkReply::NetworkError code); + void onPlaylistThumbnailDownloadNetworkSslErrors(const QList &errors); + void onPlaylistThumbnailDownloadFinished(); + void onPlaylistThumbnailDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); + void onPlaylistThumbnailDownloadReadyRead(); + void onPlaylistThumbnailDownloadCanceled(); private: void setCurrentCoreLabel(); @@ -514,11 +489,31 @@ private: int m_allPlaylistsGridMaxCount; PlaylistEntryDialog *m_playlistEntryDialog; QElapsedTimer m_statusMessageElapsedTimer; + QPointer m_shaderParamsDialog; + QPointer m_coreOptionsDialog; QNetworkAccessManager *m_networkManager; + QProgressDialog *m_updateProgressDialog; QFile m_updateFile; QPointer m_updateReply; + QProgressDialog *m_thumbnailDownloadProgressDialog; + QFile m_thumbnailDownloadFile; + QPointer m_thumbnailDownloadReply; + QStringList m_pendingThumbnailDownloadTypes; + + QProgressDialog *m_thumbnailPackDownloadProgressDialog; + QFile m_thumbnailPackDownloadFile; + QPointer m_thumbnailPackDownloadReply; + + QProgressDialog *m_playlistThumbnailDownloadProgressDialog; + QFile m_playlistThumbnailDownloadFile; + QPointer m_playlistThumbnailDownloadReply; + QVector > m_pendingPlaylistThumbnails; + unsigned m_downloadedThumbnails; + unsigned m_failedThumbnails; + bool m_playlistThumbnailDownloadWasCanceled; + protected: void closeEvent(QCloseEvent *event); void keyPressEvent(QKeyEvent *event); @@ -526,6 +521,7 @@ protected: Q_DECLARE_METATYPE(ThumbnailWidget) Q_DECLARE_METATYPE(QPointer) +Q_DECLARE_METATYPE(struct video_shader_parameter*) RETRO_BEGIN_DECLS diff --git a/ui/drivers/ui_win32.c b/ui/drivers/ui_win32.c index 2c771ef916..3811f365ae 100644 --- a/ui/drivers/ui_win32.c +++ b/ui/drivers/ui_win32.c @@ -24,9 +24,6 @@ #pragma comment( lib, "comctl32" ) #endif -#define TITLE_MAX PATH_MAX -#define FULLPATH_MAX 32768 - #define IDI_ICON 1 #ifndef _WIN32_WINNT @@ -55,451 +52,12 @@ #include "ui_win32.h" -#define SHADER_DLG_WIDTH 220 -#define SHADER_DLG_MIN_HEIGHT 200 -#define SHADER_DLG_MAX_HEIGHT 800 -#define SHADER_DLG_CTRL_MARGIN 8 -#define SHADER_DLG_CTRL_X 10 -#define SHADER_DLG_CHECKBOX_HEIGHT 15 -#define SHADER_DLG_SEPARATOR_HEIGHT 10 -#define SHADER_DLG_LABEL_HEIGHT 14 -#define SHADER_DLG_TRACKBAR_HEIGHT 22 -#define SHADER_DLG_TRACKBAR_LABEL_WIDTH 30 - -#define SHADER_DLG_CTRL_WIDTH (SHADER_DLG_WIDTH - 2 * SHADER_DLG_CTRL_X) -#define SHADER_DLG_TRACKBAR_WIDTH (SHADER_DLG_CTRL_WIDTH - SHADER_DLG_TRACKBAR_LABEL_WIDTH) - typedef struct ui_companion_win32 { void *empty; } ui_companion_win32_t; -#ifdef HAVE_SHADERPIPELINE -enum shader_param_ctrl_type -{ - SHADER_PARAM_CTRL_NONE = 0, - SHADER_PARAM_CTRL_CHECKBOX, - SHADER_PARAM_CTRL_TRACKBAR -}; - -enum -{ - SHADER_DLG_CHECKBOX_ONTOP_ID = GFX_MAX_PARAMETERS, - SHADER_DLG_CHECKBOX_BUTTON1_ID, - SHADER_DLG_CHECKBOX_BUTTON2_ID -}; - -typedef struct -{ - enum shader_param_ctrl_type type; - union - { - ui_window_win32_t checkbox; - struct - { - HWND hwnd; - HWND label_title; - HWND label_val; - } trackbar; - } elems; -} shader_param_ctrl_t; - -typedef struct -{ - ui_window_win32_t window; - ui_window_win32_t separator; - ui_window_win32_t on_top_checkbox; - shader_param_ctrl_t controls[GFX_MAX_PARAMETERS]; - int parameters_start_y; -} shader_dlg_t; - -static shader_dlg_t g_shader_dlg = {{0}}; - -static bool shader_dlg_refresh_trackbar_label(int index, - video_shader_ctx_t *shader_info) -{ - char val_buffer[32] = {0}; - - if (floorf(shader_info->data->parameters[index].current) - == shader_info->data->parameters[index].current) - snprintf(val_buffer, sizeof(val_buffer), "%.0f", - shader_info->data->parameters[index].current); - else - snprintf(val_buffer, sizeof(val_buffer), "%.2f", - shader_info->data->parameters[index].current); - - SendMessage(g_shader_dlg.controls[index].elems.trackbar.label_val, - WM_SETTEXT, 0, (LPARAM)val_buffer); - - return true; -} - -static void shader_dlg_params_refresh(void) -{ - int i; - - for (i = 0; i < GFX_MAX_PARAMETERS; i++) - { - shader_param_ctrl_t*control = &g_shader_dlg.controls[i]; - - if (control->type == SHADER_PARAM_CTRL_NONE) - break; - - switch (control->type) - { - case SHADER_PARAM_CTRL_CHECKBOX: - { - bool checked; - - video_shader_ctx_t shader_info; - video_shader_driver_get_current_shader(&shader_info); - - checked = shader_info.data ? - (shader_info.data->parameters[i].current == - shader_info.data->parameters[i].maximum) : false; - SendMessage(control->elems.checkbox.hwnd, BM_SETCHECK, checked, 0); - } - break; - case SHADER_PARAM_CTRL_TRACKBAR: - { - video_shader_ctx_t shader_info; - video_shader_driver_get_current_shader(&shader_info); - if (shader_info.data && !shader_dlg_refresh_trackbar_label(i, &shader_info)) - break; - - if (shader_info.data) - { - SendMessage(control->elems.trackbar.hwnd, - TBM_SETRANGEMIN, (WPARAM)TRUE, (LPARAM)0); - SendMessage(control->elems.trackbar.hwnd, - TBM_SETRANGEMAX, (WPARAM)TRUE, - (LPARAM)((shader_info.data->parameters[i].maximum - - shader_info.data->parameters[i].minimum) - / shader_info.data->parameters[i].step)); - SendMessage(control->elems.trackbar.hwnd, TBM_SETPOS, (WPARAM)TRUE, - (LPARAM)((shader_info.data->parameters[i].current - - shader_info.data->parameters[i].minimum) / - shader_info.data->parameters[i].step)); - } - } - break; - case SHADER_PARAM_CTRL_NONE: - default: - break; - } - } -} - -static void shader_dlg_params_clear(void) -{ - unsigned i; - - for (i = 0; i < GFX_MAX_PARAMETERS; i++) - { - shader_param_ctrl_t*control = &g_shader_dlg.controls[i]; - - if (!control || control->type == SHADER_PARAM_CTRL_NONE) - break; - - switch (control->type) - { - case SHADER_PARAM_CTRL_NONE: - break; - case SHADER_PARAM_CTRL_CHECKBOX: - { - const ui_window_t *window = ui_companion_driver_get_window_ptr(); - if (window) - window->destroy(&control->elems.checkbox); - } - break; - case SHADER_PARAM_CTRL_TRACKBAR: - DestroyWindow(control->elems.trackbar.label_title); - DestroyWindow(control->elems.trackbar.label_val); - DestroyWindow(control->elems.trackbar.hwnd); - break; - } - - control->type = SHADER_PARAM_CTRL_NONE; - } -} -#endif - -void shader_dlg_params_reload(void) -{ -#ifdef HAVE_SHADERPIPELINE - HFONT hFont; - RECT parent_rect; - int i, pos_x, pos_y; - video_shader_ctx_t shader_info; - const ui_window_t *window = NULL; - - shader_dlg_params_clear(); - - video_shader_driver_get_current_shader(&shader_info); - - if (!shader_info.data || shader_info.data->num_parameters > GFX_MAX_PARAMETERS) - return; - - window = ui_companion_driver_get_window_ptr(); - hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); - pos_y = g_shader_dlg.parameters_start_y; - pos_x = SHADER_DLG_CTRL_X; - - for (i = 0; i < (int)shader_info.data->num_parameters; i++) - { - shader_param_ctrl_t*control = &g_shader_dlg.controls[i]; - - if ((shader_info.data->parameters[i].minimum == 0.0) - && (shader_info.data->parameters[i].maximum - == (shader_info.data->parameters[i].minimum - + shader_info.data->parameters[i].step))) - { - if ((pos_y + SHADER_DLG_CHECKBOX_HEIGHT - + SHADER_DLG_CTRL_MARGIN + 20) - > SHADER_DLG_MAX_HEIGHT) - { - pos_y = g_shader_dlg.parameters_start_y; - pos_x += SHADER_DLG_WIDTH; - } - - control->type = SHADER_PARAM_CTRL_CHECKBOX; - control->elems.checkbox.hwnd = CreateWindowEx(0, "BUTTON", - shader_info.data->parameters[i].desc, - WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, pos_x, pos_y, - SHADER_DLG_CTRL_WIDTH, SHADER_DLG_CHECKBOX_HEIGHT, - g_shader_dlg.window.hwnd, (HMENU)(size_t)i, NULL, NULL); - SendMessage(control->elems.checkbox.hwnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); - pos_y += SHADER_DLG_CHECKBOX_HEIGHT + SHADER_DLG_CTRL_MARGIN; - } - else - { - if ((pos_y + SHADER_DLG_LABEL_HEIGHT + SHADER_DLG_TRACKBAR_HEIGHT + - SHADER_DLG_CTRL_MARGIN + 20) > SHADER_DLG_MAX_HEIGHT) - { - pos_y = g_shader_dlg.parameters_start_y; - pos_x += SHADER_DLG_WIDTH; - } - - control->type = SHADER_PARAM_CTRL_TRACKBAR; - control->elems.trackbar.label_title = CreateWindowEx(0, "STATIC", - shader_info.data->parameters[i].desc, - WS_CHILD | WS_VISIBLE | SS_LEFT, pos_x, pos_y, - SHADER_DLG_CTRL_WIDTH, SHADER_DLG_LABEL_HEIGHT, g_shader_dlg.window.hwnd, - (HMENU)(size_t)i, NULL, NULL); - SendMessage(control->elems.trackbar.label_title, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); - - pos_y += SHADER_DLG_LABEL_HEIGHT; - control->elems.trackbar.hwnd = CreateWindowEx(0, (LPCSTR)TRACKBAR_CLASS, "", - WS_CHILD | WS_VISIBLE | TBS_HORZ | TBS_NOTICKS, - pos_x + SHADER_DLG_TRACKBAR_LABEL_WIDTH, pos_y, - SHADER_DLG_TRACKBAR_WIDTH, SHADER_DLG_TRACKBAR_HEIGHT, - g_shader_dlg.window.hwnd, (HMENU)(size_t)i, NULL, NULL); - - control->elems.trackbar.label_val = CreateWindowEx(0, "STATIC", "", - WS_CHILD | WS_VISIBLE | SS_LEFT, pos_x, - pos_y, SHADER_DLG_TRACKBAR_LABEL_WIDTH, SHADER_DLG_LABEL_HEIGHT, - g_shader_dlg.window.hwnd, (HMENU)(size_t)i, NULL, NULL); - SendMessage(control->elems.trackbar.label_val, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); - - SendMessage(control->elems.trackbar.hwnd, TBM_SETBUDDY, (WPARAM)TRUE, - (LPARAM)control->elems.trackbar.label_val); - - pos_y += SHADER_DLG_TRACKBAR_HEIGHT + SHADER_DLG_CTRL_MARGIN; - - } - - } - - if (window && g_shader_dlg.separator.hwnd) - window->destroy(&g_shader_dlg.separator); - - g_shader_dlg.separator.hwnd = CreateWindowEx(0, "STATIC", "", - SS_ETCHEDHORZ | WS_VISIBLE | WS_CHILD, SHADER_DLG_CTRL_X, - g_shader_dlg.parameters_start_y - SHADER_DLG_CTRL_MARGIN - SHADER_DLG_SEPARATOR_HEIGHT / 2, - (pos_x - SHADER_DLG_CTRL_X) + SHADER_DLG_CTRL_WIDTH, - SHADER_DLG_SEPARATOR_HEIGHT / 2, - g_shader_dlg.window.hwnd, NULL, NULL, - NULL); - - shader_dlg_params_refresh(); - - GetWindowRect(g_shader_dlg.window.hwnd, &parent_rect); - SetWindowPos(g_shader_dlg.window.hwnd, NULL, 0, 0, - (pos_x - SHADER_DLG_CTRL_X) + SHADER_DLG_WIDTH, - (pos_x == SHADER_DLG_CTRL_X) ? pos_y + 30 : SHADER_DLG_MAX_HEIGHT, - SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); -#endif -} - -#ifdef HAVE_SHADERPIPELINE -static void shader_dlg_update_on_top_state(void) -{ - bool on_top = SendMessage(g_shader_dlg.on_top_checkbox.hwnd, - BM_GETCHECK, 0, 0) == BST_CHECKED; - - SetWindowPos(g_shader_dlg.window.hwnd, on_top - ? HWND_TOPMOST : HWND_NOTOPMOST , 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); -} - -static void shader_dlg_show(HWND parent_hwnd) -{ - const ui_window_t *window = ui_companion_driver_get_window_ptr(); - - if (!IsWindowVisible(g_shader_dlg.window.hwnd)) - { - if (parent_hwnd) - { - RECT parent_rect; - GetWindowRect(parent_hwnd, &parent_rect); - SetWindowPos(g_shader_dlg.window.hwnd, HWND_TOP, - parent_rect.right, parent_rect.top, - 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); - } - else - window->set_visible(&g_shader_dlg.window, true); - - shader_dlg_update_on_top_state(); - - shader_dlg_params_reload(); - - } - - window->set_focused(&g_shader_dlg.window); -} -#endif - -#if 0 -static LRESULT CALLBACK ShaderDlgWndProc(HWND hwnd, UINT message, - WPARAM wparam, LPARAM lparam) -{ - int i, pos; - const ui_window_t *window = ui_companion_driver_get_window_ptr(); - - switch (message) - { - case WM_CREATE: - break; - - case WM_CLOSE: - case WM_DESTROY: - case WM_QUIT: - if (window) - window->set_visible(&g_shader_dlg.window, false); - return 0; - - case WM_COMMAND: - i = LOWORD(wparam); - - if (i == SHADER_DLG_CHECKBOX_ONTOP_ID) - { - shader_dlg_update_on_top_state(); - break; - } - - if (i >= GFX_MAX_PARAMETERS) - break; - - if (g_shader_dlg.controls[i].type != SHADER_PARAM_CTRL_CHECKBOX) - break; - - { - video_shader_ctx_t shader_info; - video_shader_driver_get_current_shader(&shader_info); - - if (SendMessage(g_shader_dlg.controls[i].elems.checkbox.hwnd, - BM_GETCHECK, 0, 0) == BST_CHECKED) - shader_info.data->parameters[i].current = - shader_info.data->parameters[i].maximum; - else - shader_info.data->parameters[i].current = - shader_info.data->parameters[i].minimum; - } - break; - - case WM_HSCROLL: - { - video_shader_ctx_t shader_info; - video_shader_driver_get_current_shader(&shader_info); - i = GetWindowLong((HWND)lparam, GWL_ID); - - if (i >= GFX_MAX_PARAMETERS) - break; - - if (g_shader_dlg.controls[i].type != SHADER_PARAM_CTRL_TRACKBAR) - break; - - pos = (int)SendMessage(g_shader_dlg.controls[i].elems.trackbar.hwnd, TBM_GETPOS, 0, 0); - - { - - shader_info.data->parameters[i].current = - shader_info.data->parameters[i].minimum + pos * shader_info.data->parameters[i].step; - } - - if (shader_info.data) - shader_dlg_refresh_trackbar_label(i, &shader_info); - } - break; - - } - - return DefWindowProc(hwnd, message, wparam, lparam); -} - -static bool win32_shader_dlg_init(void) -{ - static bool inited = false; - int pos_y; - HFONT hFont; - - if (g_shader_dlg.window.hwnd) - return true; - - if (!inited) - { - WNDCLASSEX wc_shader_dlg = {0}; - INITCOMMONCONTROLSEX comm_ctrl_init = {0}; - - comm_ctrl_init.dwSize = sizeof(comm_ctrl_init); - comm_ctrl_init.dwICC = ICC_BAR_CLASSES; - - if (!InitCommonControlsEx(&comm_ctrl_init)) - return false; - - wc_shader_dlg.lpfnWndProc = ShaderDlgWndProc; - wc_shader_dlg.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); - - if (!win32_window_init(&wc_shader_dlg, true, "Shader Dialog")) - return false; - - inited = true; - } - - hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); - - g_shader_dlg.window.hwnd = CreateWindowEx(0, "Shader Dialog", "Shader Parameters", - WS_POPUPWINDOW | WS_CAPTION, 100, 100, - SHADER_DLG_WIDTH, SHADER_DLG_MIN_HEIGHT, NULL, NULL, NULL, NULL); - - pos_y = SHADER_DLG_CTRL_MARGIN; - g_shader_dlg.on_top_checkbox.hwnd = CreateWindowEx(0, "BUTTON", "Always on Top", - BS_AUTOCHECKBOX | WS_VISIBLE | WS_CHILD, - SHADER_DLG_CTRL_X, pos_y, SHADER_DLG_CTRL_WIDTH, - SHADER_DLG_CHECKBOX_HEIGHT, g_shader_dlg.window.hwnd, - (HMENU)SHADER_DLG_CHECKBOX_ONTOP_ID, NULL, NULL); - pos_y += SHADER_DLG_CHECKBOX_HEIGHT + SHADER_DLG_CTRL_MARGIN; - - SendMessage(g_shader_dlg.on_top_checkbox.hwnd, - WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); - - pos_y += SHADER_DLG_SEPARATOR_HEIGHT + SHADER_DLG_CTRL_MARGIN; - - g_shader_dlg.parameters_start_y = pos_y; - return true; -} -#endif - +#ifndef __WINRT__ bool win32_window_init(WNDCLASSEX *wndclass, bool fullscreen, const char *class_name) { @@ -520,19 +78,9 @@ bool win32_window_init(WNDCLASSEX *wndclass, if (!RegisterClassEx(wndclass)) return false; - /* This is non-NULL when we want a window for shader dialogs, - * therefore early return here */ - /* TODO/FIXME - this is ugly. Find a better way */ - if (class_name != NULL) - return true; - - /* Shader dialog is disabled for now, until - * video_threaded issues are fixed. - if (!win32_shader_dlg_init()) - RARCH_ERR("[WGL]: wgl_shader_dlg_init() failed.\n");*/ return true; } - +#endif static bool win32_browser( HWND owner, @@ -554,8 +102,8 @@ static bool win32_browser( * path/name of any file the user may select. * FIXME: We should really handle the * error case when this isn't big enough. */ - char new_title[TITLE_MAX]; - char new_file[FULLPATH_MAX]; + char new_title[PATH_MAX]; + char new_file[32768]; new_title[0] = '\0'; new_file[0] = '\0'; @@ -680,11 +228,6 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam) case ID_M_FULL_SCREEN: cmd = CMD_EVENT_FULLSCREEN_TOGGLE; break; - case ID_M_SHADER_PARAMETERS: -#if !defined(_XBOX) && defined(HAVE_SHADERPIPELINE) - shader_dlg_show(owner); -#endif - break; case ID_M_MOUSE_GRAB: cmd = CMD_EVENT_GRAB_MOUSE_TOGGLE; break; diff --git a/ui/drivers/ui_win32_resource.h b/ui/drivers/ui_win32_resource.h index 4a4e79259a..e7090d701e 100644 --- a/ui/drivers/ui_win32_resource.h +++ b/ui/drivers/ui_win32_resource.h @@ -29,4 +29,3 @@ #define ID_M_STATE_INDEX_AUTO 40024 #define ID_M_TAKE_SCREENSHOT 40025 #define ID_M_MUTE_TOGGLE 40026 -#define ID_M_SHADER_PARAMETERS 40027 diff --git a/ui/ui_companion_driver.c b/ui/ui_companion_driver.c index 0133e1a56a..a866b6749b 100644 --- a/ui/ui_companion_driver.c +++ b/ui/ui_companion_driver.c @@ -103,6 +103,10 @@ void ui_companion_event_command(enum event_command action) if (ui && ui->event_command) ui->event_command(ui_companion_data, action); +#ifdef HAVE_QT + if (ui_companion_qt.toggle && qt_is_inited) + ui_companion_qt.event_command(ui_companion_qt_data, action); +#endif } void ui_companion_driver_deinit(void) diff --git a/verbosity.c b/verbosity.c index 7b76838eb1..4b8dd7cc92 100644 --- a/verbosity.c +++ b/verbosity.c @@ -214,8 +214,8 @@ void RARCH_LOG_V(const char *tag, const char *fmt, va_list ap) void RARCH_LOG_BUFFER(uint8_t *data, size_t size) { unsigned i, offset; - int padding = size % 16; - uint8_t buf[16]; + int padding = size % 16; + uint8_t buf[16] = {0}; RARCH_LOG("== %d-byte buffer ==================\n", size); diff --git a/version.all b/version.all index bb6f3b2629..6683f2e43c 100644 --- a/version.all +++ b/version.all @@ -6,8 +6,8 @@ # /* - pkg/snap/snapcraft.yaml (including the github url) */ #if 0 -RARCH_VERSION="1.7.3" +RARCH_VERSION="1.7.4" #endif #ifndef PACKAGE_VERSION -#define PACKAGE_VERSION "1.7.3" +#define PACKAGE_VERSION "1.7.4" #endif