diff --git a/.travis.yml b/.travis.yml index e950b2c19b..5fa1900042 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ matrix: - g++-mingw-w64-i686 - mingw-w64-i686-dev script: - - CROSS_COMPILE=i686-w64-mingw32- ./configure --disable-d3d8 --disable-d3d9 --disable-d3d10 --disable-d3d11 --disable-d3d12 && make HAVE_ZLIB=1 HAVE_BUILTINZLIB=1 HAVE_RPNG=1 + - CROSS_COMPILE=i686-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501" ./configure --disable-d3d8 --disable-d3d9 --disable-d3d10 --disable-d3d11 --disable-d3d12 && make HAVE_ZLIB=1 HAVE_BUILTINZLIB=1 HAVE_RPNG=1 - compiler: mingw-x64 addons: apt: @@ -18,7 +18,7 @@ matrix: - g++-mingw-w64-x86-64 - mingw-w64-x86-64-dev script: - - CROSS_COMPILE=x86_64-w64-mingw32- ./configure --disable-d3d8 --disable-d3d9 --disable-d3d10 --disable-d3d11 --disable-d3d12 && make HAVE_ZLIB=1 HAVE_BUILTINZLIB=1 HAVE_RPNG=1 + - CROSS_COMPILE=x86_64-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501" ./configure --disable-d3d8 --disable-d3d9 --disable-d3d10 --disable-d3d11 --disable-d3d12 && make HAVE_ZLIB=1 HAVE_BUILTINZLIB=1 HAVE_RPNG=1 - compiler: gcc - compiler: clang addons: @@ -64,3 +64,5 @@ addons: build_command_prepend: "./configure; make clean" build_command: "make" branch_pattern: coverity_scan +notifications: + email: false diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 81c2529184..52c61506df 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -1,125 +1,127 @@ -{ - "configurations": [ - { - "name": "Mac", - "includePath": [ - "/usr/include", - "/usr/local/include", - "${workspaceRoot}" - ], - "defines": [], - "intelliSenseMode": "clang-x64", - "browse": { - "path": [ - "/usr/include", - "/usr/local/include", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - }, - "macFrameworkPath": [ - "/System/Library/Frameworks", - "/Library/Frameworks" - ] - }, - { - "name": "Linux", - "includePath": [ - "/usr/include", - "/usr/local/include", - "${workspaceRoot}" - ], - "defines": [], - "intelliSenseMode": "clang-x64", - "browse": { - "path": [ - "/usr/include", - "/usr/local/include", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } - }, - { - "name": "Win32", - "includePath": [ - "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um", - "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt", - "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared", - "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt", - "${workspaceRoot}" - ], - "defines": [ - "_DEBUG", - "UNICODE" - ], - "intelliSenseMode": "msvc-x64", - "browse": { - "path": [ - "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um", - "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt", - "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared", - "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } - }, - { - "name": "msys2-mingw32", - "includePath": [ - "C:/msys64/mingw32/include", - "C:/msys64/mingw32/i686-w64-mingw32/include", - "${workspaceRoot}/libretro-common/include", - "${workspaceRoot}/include", - "${workspaceRoot}" - ], - "defines": [ - "_DEBUG", - "UNICODE" - ], - "intelliSenseMode": "msvc-x64", - "browse": { - "path": [ - "C:/msys64/mingw32/include", - "C:/msys64/mingw32/i686-w64-mingw32/include", - "${workspaceRoot}/libretro-common/include", - "${workspaceRoot}/include", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } - }, - { - "name": "msys2-mingw64", - "includePath": [ - "C:/msys64/mingw64/include", - "C:/msys64/mingw64/x86_64-w64-mingw32/include", - "${workspaceRoot}/libretro-common/include", - "${workspaceRoot}/include", - "${workspaceRoot}" - ], - "defines": [ - "_DEBUG", - "UNICODE" - ], - "intelliSenseMode": "msvc-x64", - "browse": { - "path": [ - "C:/msys64/mingw64/include", - "C:/msys64/mingw64/x86_64-w64-mingw32/include", - "${workspaceRoot}/libretro-common/include", - "${workspaceRoot}/include", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } - } - ], - "version": 3 +{ + "configurations": [ + { + "name": "Mac", + "includePath": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "defines": [], + "intelliSenseMode": "clang-x64", + "browse": { + "path": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "macFrameworkPath": [ + "/System/Library/Frameworks", + "/Library/Frameworks" + ] + }, + { + "name": "Linux", + "includePath": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "defines": [], + "intelliSenseMode": "clang-x64", + "browse": { + "path": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + }, + { + "name": "Win32", + "includePath": [ + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um", + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt", + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared", + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt", + "${workspaceRoot}" + ], + "defines": [ + "_DEBUG", + "UNICODE" + ], + "intelliSenseMode": "msvc-x64", + "browse": { + "path": [ + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um", + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt", + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared", + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "cStandard": "c11", + "cppStandard": "c++17" + }, + { + "name": "msys2-mingw32", + "includePath": [ + "C:/msys64/mingw32/include", + "C:/msys64/mingw32/i686-w64-mingw32/include", + "${workspaceRoot}/libretro-common/include", + "${workspaceRoot}/include", + "${workspaceRoot}" + ], + "defines": [ + "_DEBUG", + "UNICODE" + ], + "intelliSenseMode": "msvc-x64", + "browse": { + "path": [ + "C:/msys64/mingw32/include", + "C:/msys64/mingw32/i686-w64-mingw32/include", + "${workspaceRoot}/libretro-common/include", + "${workspaceRoot}/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + }, + { + "name": "msys2-mingw64", + "includePath": [ + "C:/msys64/mingw64/include", + "C:/msys64/mingw64/x86_64-w64-mingw32/include", + "${workspaceRoot}/libretro-common/include", + "${workspaceRoot}/include", + "${workspaceRoot}" + ], + "defines": [ + "_DEBUG", + "UNICODE" + ], + "intelliSenseMode": "msvc-x64", + "browse": { + "path": [ + "C:/msys64/mingw64/include", + "C:/msys64/mingw64/x86_64-w64-mingw32/include", + "${workspaceRoot}/libretro-common/include", + "${workspaceRoot}/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + } + ], + "version": 3 } \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 6e1f69631a..e7552247cc 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,44 +5,41 @@ "version": "0.2.0", "configurations": [ { - "name": "msys2-mingw64 debug", + "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/retroarch.exe", - "args": [], + "args": ["-v"], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], - "externalConsole": true, + "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "c:\\msys64\\mingw64\\bin\\gdb.exe", "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - } + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } ] }, - { - "name": "msys2-mingw32 debug", + { + "name": "(gdb) Attach", "type": "cppdbg", - "request": "launch", + "request": "attach", "program": "${workspaceFolder}/retroarch.exe", - "args": [], - "stopAtEntry": false, - "cwd": "${workspaceFolder}", - "environment": [], - "externalConsole": true, + "processId": "${command:pickProcess}", "MIMode": "gdb", - "miDebuggerPath": "c:\\msys64\\mingw32\\bin\\gdb.exe", + "miDebuggerPath": "c:\\msys64\\mingw64\\bin\\gdb.exe", "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - } + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } ] - } + }, + ] } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index e90ca77e4a..88513c30c2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,4 +14,5 @@ "*.in": "c", "*.rh": "c" }, + "C_Cpp.dimInactiveRegions": false, } \ No newline at end of file diff --git a/CHANGES.md b/CHANGES.md index 4fd33cccb3..7af66aa173 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,22 +1,75 @@ -# 1.7.2 (future) +# 1.7.4 (future) + +# 1.7.3 +- AUDIO: Audio mixer supports FLAC/MP3 file types now! +- COMMON: Fixed bug 'crashing in cores that don't range check retro_set_controller_type'. Some people were having crashes when device is set to RETRO_DEVICE_NONE and the cores don't check the number of ports, in VBAM's case it was overflowing and crashing. QuickNES was crashing too. +- COMMON: Fixed buffer overflow in url encoding (affecting MSVC2010/2013). +- COMMON: (QuickMenu) Added Configuration Override submenu. +- HID: Merge new HID subsystem. +- HID: Fix WaveBird support for the Wii U GCA. +- HID/OSX: Fix regression with IODHIDManager - gamepads which are connected later would not be autoconfigured. +- LOCALIZATION: Update Italian translation. +- LOCALIZATION: Update Japanese translation. +- LOCALIZATION: Update Portuguese translation. +- MENU: New WIMP Qt GUI! +- MENU: Audio mixer now works in the menu without any cores loaded. You have to enable the setting 'Enable menu audio' for this to work. +- REMAPPING/OVERLAYS: Fix regression - overlays could no longer be remapped. +- SCANNER: Add Wii Backup File WBFS support. +- X11: CRT SwitchRes support for X11/Linux. + +# 1.7.2 - ANDROID/OPENSL: Prevent crashes when setting audio latency too low (buffer count can never be lower than 2 now). +- CRT: Added CRT SwitchRes. +- COMMON: Hide the 'Core delete' option if the 'Core updater' is also hidden. - COMMON: Add way to reset core association for playlist entry. +- COMMON: Fix invalid long command line options causing infinite loop on Windows - COMMON: Add OSD statistics for video/audio/core. +- COMMON: Added runahead system; allows you to drive down latency even further. +- COMMON: Fix buggy behavior that could happen with ZIP file reading on some platforms as a result of not initializing struct. - CHEEVOS: Support Atari 2600, Virtual Boy, and Arcade (only Neo Geo, CPS-1, CPS-2 and CPS-3 and only with fbalpha core). - CHEEVOS: Add option to automatically take a screenshot when an achievement is triggered. -- D3D11: Experimental hardware renderer. Allows for libretro cores to use D3D11 for hardware rendering. +- CHEEVOS: Fixed incompatibilities with Neo Geo Pocket achievement sets. +- CHEEVOS: Store only login token, not password. +- D3D10: Added D3D10 driver to release build. Has working shaders (Slang), overlay, and menu display driver support. Should be on par capabilities wise +with D3D11 driver except for there being no hardware rendering right now. +- D3D11: Experimental hardware renderer. Allows for libretro cores to use D3D11 for hardware rendering. First core to use this is PPSSPP. +- D3D11: Increase backwards compatibility, shaders compile with Shader Model 4.0 now, added support for more feature levels. +- D3D10/D3D11/D3D12: Fix crashes with completely black or white thumbnail textures in XMB. +- GUI: Support disabling window decorations on Windows and Linux. - LIBRETRO: Addition - Functions to enable and disable audio and video, and an environment function to query status of audio and video enables. - LOCALIZATION: Update Italian translation. - LOCALIZATION: Update Polish translation. -- MENU: Disable XMB shadow icons by default for PowerPC and ARM for performance reasons. +- MENU: Add Rewind/Latency/Overlay settings to Quick Menu, add options to show/hide them (User Interface -> Views -> Quick Menu) +- MENU/RGUI: Only show Menu Linear Filter for RGUI and only show it for +video drivers that implement it (D3D8/9/10/11/12/GL) +- MENU/RGUI: Add User Interface -> Appearance options. +- 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: 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. - MENU/XMB: Mouse cursor scales correctly now. +- MENU/XMB: Add toggle to show/hide Playlist tabs. +- MENU/XMB: Add menu layout - can switch between Desktop, Handheld and Auto. +- MENU/XMB: Don't load menu pipeline shaders unless XMB is selected (D3D10/D3D11/D3D12/GL/Vulkan) +- MENU/VIDEO: Only show black frame insertion for the video drivers/context drivers +that support it (so far this includes - D3D8/D3D9, OpenGL, Vulkan) +- MENU/VIDEO: Only show max swapchain images if supported by video driver and/or context driver (so far this includes - DRM EGL context driver, VideoCore EGL context driver, Vulkan) +- MENU/MaterialUI: Automatic DPI Scaling should be much improved now, now scales as expected at 1440p and 4K resolutions. - MENU/MaterialUI: Fix wrong calculation of an entry height causing long playlists to end up outside of screen range. This also could cause crashes on low DPI screens. - IOS: Fixed crash when opening downloaded roms from Safari or using the "Open in.." functionality. Added the compiler flag to support keyboard remapping to controls. - IOS: Fixed buffer overlap that caused a crash while trying to download GLSL shaders from the buildbot. - PS3: fix URLS +- REMAPS: Mapping keyboard keys from more than one gamepad (works with dosbox) +- REMAPS: Mapping more than one button to the same action +- REMAPS: Unmapping buttons +- REMAPS: Unmapping analogs +- REMAPS: Mapping a button to trigger an analog response (tested with mupen, can run on SM64 with the d-pad now, triggers a full analog tilt) +- REMAPS: Mapping an analog to another analog (having more than one analog mapped to the same output causes issues) +- REMAPS: Mapping an analog to produce a button response +- SCANNER: Should be able to scan dual-layer Wii disc images now, filestream code now supports files larger than 4GB. - SHADERS/SLANG: Slang shaders should work again on Android version and MSVC versions (basically all the Griffin-based versions). - SHADERS: If GL context is GLES2/3/Core context, Cg shaders are unavailable. Applies to shader list too. - SHADERS: Hide cg/glsl shaders from being able to be selected if D3D8/9/10/11/Vulkan video drivers are selected. @@ -27,8 +80,10 @@ - VULKAN/X11: Fix X11 Vulkan bug from Wayland driver. - VULKAN: Fix multi-line text spacing in menus with Vulkan driver. - WINDOWS XP: Add Cheevos support. -- WINDOWS/MSVC 2005: Add Cheevos support. +- WINDOWS/MSVC 2003/2005/2010/2013/2015/2017: Add Cheevos support. - VITA: Bugfix for 'PS Vita takes many time to start to accept input' issue. +- X11: Allow compositor disabling on X11 fullscreen through _NET_WM_BYPASS_COMPOSITOR +- X11: Prioritize _NET_WM_STATE_FULLSCREEN_ in true fullscreen mode - WIIU: Fix OOB read/write in keyboard driver. # 1.7.1 @@ -69,9 +124,8 @@ - LOCALIZATION: Update Spanish translation. - NETPLAY: Add menu option to select different MITM (relay) server locations. - OSX: Modify HID buttons detection algorithm. -- QB: Added --datarootdir. -- QB: Added --bindir and --mandir and deprecated --with-bin_dir and --with-man_dir. -- QB: Added --docdir. +- QB: Added --datarootdir, --sysconfdir, --bindir, --docdir and --mandir. +- QB: Deprecated --global-config-dir, --with-bin_dir and --with-man_dir. - SHADERS: Allow saving of shader presets based on the parent directory (Saving one for */foo/bar/mario.sfc* would result in *shaders/presets/corename/bar.ext*). We decided it's safer to still isolate the presets to a single core because different cores may treat video output differently. - SHADERS: Don't save the path to the current preset to the main config. This was causing weird behavior, instead it will try to load *currentconfig.ext* and it will save a preset with that name when select *apply shader preset*. The resulting shader will restore properly after restarting and even after core/parent/game specific presets are loaded - SOLARIS: Initial port. diff --git a/Makefile b/Makefile index a9e72cb4b7..7e66bdb181 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ endif include Makefile.common ifeq ($(shell $(CC) -v 2>&1 | grep -c "clang"),1) - DEFINES += -Wno-invalid-source-encoding + DEFINES += -Wno-invalid-source-encoding -Wno-incompatible-ms-struct endif ifeq ($(shell $(CC) -v 2>&1 | grep -c "tcc"),1) @@ -92,21 +92,22 @@ APPEND_CFLAGS := $(CFLAGS) CXXFLAGS += $(APPEND_CFLAGS) -std=c++11 -D__STDC_CONSTANT_MACROS OBJCFLAGS := $(CFLAGS) -D__STDC_CONSTANT_MACROS -ifeq ($(CXX_BUILD), 1) - LINK = $(CXX) - CFLAGS := $(CXXFLAGS) -xc++ - CFLAGS += -DCXX_BUILD - CXXFLAGS += -DCXX_BUILD -else - ifeq ($(NEED_CXX_LINKER),1) +ifeq ($(HAVE_CXX), 1) + ifeq ($(CXX_BUILD), 1) + LINK = $(CXX) + CFLAGS := $(CXXFLAGS) -xc++ + CFLAGS += -DCXX_BUILD + CXXFLAGS += -DCXX_BUILD + else ifeq ($(NEED_CXX_LINKER),1) LINK = $(CXX) - else ifeq ($(findstring Win32,$(OS)),) - LINK = $(CC) else - # directx-related code is c++ - LINK = $(CXX) + LINK = $(CC) endif +else + LINK = $(CC) +endif +ifneq ($(CXX_BUILD), 1) ifneq ($(GNU90_BUILD), 1) ifneq ($(findstring icc,$(CC)),) CFLAGS += -std=c99 -D_GNU_SOURCE @@ -133,7 +134,7 @@ RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ)) ifneq ($(X86),) CFLAGS += -m32 - CXXLAGS += -m32 + CXXFLAGS += -m32 LDFLAGS += -m32 endif @@ -150,8 +151,29 @@ ifneq ($(findstring $(GPERFTOOLS),tcmalloc),) LIBS += -ltcmalloc endif +# Qt MOC generation, required for QObject-derived classes +ifneq ($(MOC_HEADERS),) + # prefix moc_ to base filename of paths and change extension from h to cpp, so a/b/foo.h becomes a/b/moc_foo.cpp + MOC_SRC := $(join $(addsuffix moc_,$(addprefix $(OBJDIR)/,$(dir $(MOC_HEADERS)))), $(notdir $(MOC_HEADERS:.h=.cpp))) + MOC_OBJ := $(patsubst %.cpp,%.o,$(MOC_SRC)) + RARCH_OBJ += $(MOC_OBJ) +endif + all: $(TARGET) config.mk +$(MOC_SRC): + @$(if $(Q), $(shell echo echo MOC $<),) + $(eval MOC_TMP := $(patsubst %.h,%_moc.cpp,$@)) + $(Q)$(MOC) -o $(MOC_TMP) $< + +$(foreach x,$(join $(addsuffix :,$(MOC_SRC)),$(MOC_HEADERS)),$(eval $x)) + +$(MOC_OBJ): + @$(if $(Q), $(shell echo echo CXX $<),) + $(Q)$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEFINES) -MMD -c -o $@ $< + +$(foreach x,$(join $(addsuffix :,$(MOC_OBJ)),$(MOC_SRC)),$(eval $x)) + ifeq ($(MAKECMDGOALS),clean) config.mk: else @@ -250,3 +272,6 @@ clean: rm -f *.d .PHONY: all install uninstall clean + +print-%: + @echo '$*=$($*)' diff --git a/Makefile.common b/Makefile.common index a0931b6a0e..dce6b77e31 100644 --- a/Makefile.common +++ b/Makefile.common @@ -147,6 +147,8 @@ ifneq ($(GIT_VERSION),) endif # General object files +DEFINES += -DHAVE_DR_MP3 +CFLAGS += -DHAVE_DR_MP3 OBJ += frontend/frontend.o \ frontend/frontend_driver.o \ @@ -198,12 +200,15 @@ OBJ += frontend/frontend.o \ $(LIBRETRO_COMM_DIR)/hash/rhash.o \ audio/audio_driver.o \ $(LIBRETRO_COMM_DIR)/audio/audio_mixer.o \ + input/common/input_common.o \ input/input_driver.o \ + input/input_mapper.o \ led/led_driver.o \ led/drivers/led_null.o \ gfx/video_coord_array.o \ gfx/video_display_server.o \ gfx/video_driver.o \ + gfx/video_crt_switch.o \ camera/camera_driver.o \ wifi/wifi_driver.o \ location/location_driver.o \ @@ -258,7 +263,18 @@ OBJ += frontend/frontend.o \ record/drivers/record_null.o \ $(LIBRETRO_COMM_DIR)/features/features_cpu.o \ performance_counters.o \ - verbosity.o + verbosity.o \ + +ifeq ($(HAVE_RUNAHEAD), 1) +DEFINES += -DHAVE_RUNAHEAD +OBJ += runahead/copy_load_info.o \ + runahead/dirty_input.o \ + runahead/mem_util.o \ + runahead/mylist.o \ + runahead/run_ahead.o \ + runahead/secondary_core.o +endif + ifeq ($(HAVE_CC_RESAMPLER), 1) @@ -308,23 +324,27 @@ DEFINES += -DHAVE_IMAGEVIEWER OBJ += cores/libretro-imageviewer/image_core.o endif -# Qt - -ifeq ($(HAVE_QT_WRAPPER), 1) -OBJ += ui/drivers/ui_qt.o -LIBS += -lQt5Quick -lQt5Widgets -lQt5Gui -lQt5Qml -lQt5Network -lQt5Core -L./ui/drivers/qt/build/release/ -LIBS += -lwrapper -endif +# Qt WIMP GUI ifeq ($(HAVE_QT), 1) OBJ += ui/drivers/ui_qt.o \ ui/drivers/qt/ui_qt_application.o \ ui/drivers/qt/ui_qt_window.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 +MOC_HEADERS += ui/drivers/ui_qt.h \ + ui/drivers/qt/ui_qt_load_core_window.h + +DEFINES += $(QT5CORE_CFLAGS) $(QT5GUI_CFLAGS) $(QT5WIDGETS_CFLAGS) -DHAVE_MAIN +#DEFINES += $(QT5WEBENGINE_CFLAGS) +LIBS += $(QT5CORE_LIBS) $(QT5GUI_LIBS) $(QT5WIDGETS_LIBS) +#LIBS += $(QT5WEBENGINE_LIBS) +NEED_CXX_LINKER = 1 + ifneq ($(findstring Linux,$(OS)),) -DEFINES += -I/usr/include/qt -fPIC +DEFINES += -fPIC endif endif @@ -1022,9 +1042,6 @@ ifeq ($(HAVE_PLAIN_DRM), 1) LIBS += -ldrm endif -OBJ += \ - gfx/drivers_renderchain/null_renderchain.o - ifeq ($(HAVE_GL_CONTEXT), 1) DEFINES += -DHAVE_OPENGL -DHAVE_GLSL OBJ += gfx/drivers/gl.o \ @@ -1172,7 +1189,7 @@ ifeq ($(HAVE_VULKAN), 1) ifeq ($(HAVE_MENU_COMMON), 1) OBJ += menu/drivers_display/menu_display_vulkan.o endif - LIBS += -lstdc++ + NEED_CXX_LINKER = 1 DEFINES += -DHAVE_VULKAN INCLUDE_DIRS += -Igfx/include @@ -1254,7 +1271,9 @@ endif ifeq ($(HAVE_D3D10), 1) OBJ += gfx/drivers/d3d10.o \ - gfx/common/d3d10_common.o + gfx/common/d3d10_common.o \ + gfx/drivers_font/d3d10_font.o \ + menu/drivers_display/menu_display_d3d10.o DEFINES += -DHAVE_D3D10 endif @@ -1424,6 +1443,8 @@ endif ifeq ($(HAVE_BUILTINFLAC),1) HAVE_FLAC = 1 + DEFINES += -DHAVE_DR_FLAC -I$(DEPS_DIR) + CFLAGS += -DHAVE_DR_FLAC CFLAGS += -DHAVE_FLAC -I$(DEPS_DIR)/libFLAC/include DEFINES += -DHAVE_STDINT_H -DHAVE_LROUND -DFLAC__HAS_OGG=0 \ -DFLAC_PACKAGE_VERSION="\"retroarch\"" @@ -1450,7 +1471,8 @@ ifeq ($(HAVE_BUILTINFLAC),1) endif OBJ += $(FLACOBJ) else ifeq ($(HAVE_FLAC),1) - LIBS += $(FLAC_LIBS) + DEFINES += -DHAVE_FLAC + LIBS += $(FLAC_LIBS) endif ifeq ($(HAVE_ZLIB), 1) @@ -1461,7 +1483,7 @@ ifeq ($(HAVE_ZLIB), 1) ifeq ($(HAVE_BUILTINZLIB), 1) OBJ += $(DEPS_DIR)/libz/adler32.o \ $(DEPS_DIR)/libz/compress.o \ - $(DEPS_DIR)/libz/crc32.o \ + $(DEPS_DIR)/libz/libz-crc32.o \ $(DEPS_DIR)/libz/deflate.o \ $(DEPS_DIR)/libz/gzclose.o \ $(DEPS_DIR)/libz/gzlib.o \ @@ -1480,19 +1502,27 @@ ifeq ($(HAVE_ZLIB), 1) endif endif -ifeq ($(HAVE_FLAC), 1) -ifeq ($(HAVE_7ZIP), 1) -ifeq ($(HAVE_ZLIB), 1) - DEFINES += -DHAVE_CHD -DWANT_SUBCODE -DWANT_RAW_DATA_SECTOR +ifeq ($(HAVE_CHD), 1) CFLAGS += -I$(LIBRETRO_COMM_DIR)/formats/libchdr - OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/bitstream.o \ - $(LIBRETRO_COMM_DIR)/formats/libchdr/cdrom.o \ - $(LIBRETRO_COMM_DIR)/formats/libchdr/chd.o \ - $(LIBRETRO_COMM_DIR)/formats/libchdr/flac.o \ - $(LIBRETRO_COMM_DIR)/formats/libchdr/huffman.o \ + DEFINES += -DHAVE_CHD -DWANT_SUBCODE -DWANT_RAW_DATA_SECTOR + OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_bitstream.o \ + $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_cdrom.o \ + $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_chd.o \ + $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_huffman.o \ $(LIBRETRO_COMM_DIR)/streams/chd_stream.o -endif -endif + + ifeq ($(HAVE_FLAC), 1) + OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_flac.o \ + $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_flac_codec.o + endif + + ifeq ($(HAVE_7ZIP), 1) + OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_lzma.o + endif + + ifeq ($(HAVE_ZLIB), 1) + OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_zlib.o + endif endif ifeq ($(HAVE_RTGA), 1) @@ -1594,10 +1624,6 @@ ifeq ($(HAVE_NETWORKING), 1) $(LIBRETRO_COMM_DIR)/utils/md5.o endif - ifeq ($(HAVE_KEYMAPPER), 1) - OBJ += input/input_mapper.o - endif - ifeq ($(HAVE_NETWORKGAMEPAD), 1) OBJ += input/input_remote.o \ cores/libretro-net-retropad/net_retropad_core.o diff --git a/Makefile.griffin b/Makefile.griffin index 0f890d36c3..1e8b848e82 100644 --- a/Makefile.griffin +++ b/Makefile.griffin @@ -178,6 +178,7 @@ else ifeq ($(libogc_platform), 1) CFLAGS += -DGEKKO -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int + HAVE_RUNAHEAD := 1 HAVE_FILTERS_BUILTIN := 1 HAVE_THREADS := 1 HAVE_RPNG := 1 @@ -840,6 +841,10 @@ ifeq ($(HAVE_IMAGEVIEWER), 1) CFLAGS += -DHAVE_IMAGEVIEWER endif +ifeq ($(HAVE_RUNAHEAD), 1) + CFLAGS += -DHAVE_RUNAHEAD +endif + ifeq ($(HAVE_7ZIP), 1) CFLAGS += -DHAVE_7ZIP endif diff --git a/Makefile.msvc b/Makefile.msvc index 77d02fc9fa..48405fd5c2 100644 --- a/Makefile.msvc +++ b/Makefile.msvc @@ -53,7 +53,6 @@ HAVE_NETWORK_CMD := 1 HAVE_OVERLAY := 1 HAVE_LANGEXTRA := 1 HAVE_CHEEVOS := 1 -HAVE_KEYMAPPER := 1 HAVE_SHADERPIPELINE := 1 HAVE_IMAGEVIEWER := 1 diff --git a/Makefile.ps3 b/Makefile.ps3 index e4c96fca7a..88f9dfe787 100644 --- a/Makefile.ps3 +++ b/Makefile.ps3 @@ -4,7 +4,7 @@ include version.all #set to GCC for debug builds for use with debugger CELL_BUILD_TOOLS = SNC CELL_GPU_TYPE = RSX -CELL_PSGL_VERSION = ultra-opt +CELL_PSGL_VERSION = opt ASSETS_DIR := media/assets @@ -63,7 +63,7 @@ endif PPU_SRCS = griffin/griffin.c -DEFINES += -DHAVE_MENU -DHAVE_RGUI -DHAVE_XMB -DHAVE_LIBRETRODB -DHAVE_MATERIALUI -DHAVE_SHADERPIPELINE -DRARCH_INTERNAL -DMSB_FIRST -DHAVE_OVERLAY -DHAVE_CC_RESAMPLER -DHAVE_STB_VORBIS -DHAVE_STB_FONT +DEFINES += -DHAVE_MENU -DHAVE_RGUI -DHAVE_XMB -DHAVE_LIBRETRODB -DHAVE_MATERIALUI -DHAVE_SHADERPIPELINE -DRARCH_INTERNAL -DMSB_FIRST -DHAVE_OVERLAY -DHAVE_CC_RESAMPLER -DHAVE_STB_VORBIS -DHAVE_STB_FONT -DHAVE_RUNAHEAD ifeq ($(DEX_BUILD), 1) DEFINES += -DDEX_BUILD @@ -96,7 +96,7 @@ ifeq ($(CELL_BUILD_TOOLS), SNC) PPU_CXXLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe PPU_CXX = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe PPU_CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe -else ifneq($(system_platform), win) +else ifneq ($(system_platform), win) PPU_CXX = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-g++.exe PPU_CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe PPU_CXXLD = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ld.exe @@ -119,7 +119,7 @@ DEFINES += -DHAVE_THREADS -DRARCH_CONSOLE -DHAVE_OPENGL -DHAVE_HEADSET -DHAVE_LA ifeq ($(DEBUG), 1) PPU_OPTIMIZE_LV := -O0 -g else - PPU_OPTIMIZE_LV := -O3 -g + PPU_OPTIMIZE_LV := -O2 -g endif ifeq ($(HAVE_LOGGER), 1) diff --git a/Makefile.ps3.cobra b/Makefile.ps3.cobra index ce6f755c0a..3a270b2dd6 100644 --- a/Makefile.ps3.cobra +++ b/Makefile.ps3.cobra @@ -2,7 +2,7 @@ include version.all #which compiler to build with - GCC or SNC #set to GCC for debug builds for use with debugger -CELL_BUILD_TOOLS = SNC +CELL_BUILD_TOOLS = GCC CELL_GPU_TYPE = RSX CELL_PSGL_VERSION = ultra-opt diff --git a/Makefile.ps3.salamander b/Makefile.ps3.salamander index 49c8c9a719..c769ff105c 100644 --- a/Makefile.ps3.salamander +++ b/Makefile.ps3.salamander @@ -1,4 +1,4 @@ -CELL_BUILD_TOOLS = SNC +CELL_BUILD_TOOLS = GCC CELL_SDK ?= /usr/local/cell HAVE_LOGGER = 0 CELL_MK_DIR ?= $(CELL_SDK)/samples/mk diff --git a/Makefile.switch b/Makefile.switch index a477749409..d81bd05b3c 100644 --- a/Makefile.switch +++ b/Makefile.switch @@ -12,6 +12,7 @@ ifeq ($(GRIFFIN_BUILD), 1) OBJ += griffin/griffin.o DEFINES += -DHAVE_GRIFFIN=1 -DHAVE_NEON -DHAVE_MATERIALUI -DHAVE_LIBRETRODB -DHAVE_CC_RESAMPLER DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DWANT_ZLIB + DEFINES += -DHAVE_RUNAHEAD else HAVE_CC_RESAMPLER = 1 HAVE_MENU_COMMON = 1 @@ -29,6 +30,7 @@ else HAVE_STATIC_VIDEO_FILTERS = 1 HAVE_STATIC_AUDIO_FILTERS = 1 HAVE_MENU = 1 + HAVE_RUNAHEAD = 1 include Makefile.common BLACKLIST := diff --git a/Makefile.vita b/Makefile.vita index 25d79a673e..5645c9cabd 100644 --- a/Makefile.vita +++ b/Makefile.vita @@ -16,7 +16,7 @@ DEFINES := ifeq ($(GRIFFIN_BUILD), 1) OBJ += griffin/griffin.o DEFINES += -DHAVE_GRIFFIN=1 - DEFINES += -DHAVE_NEON -DHAVE_MENU -DHAVE_XMB -DHAVE_MATERIALUI -DHAVE_LIBRETRODB + DEFINES += -DHAVE_NEON -DHAVE_MENU -DHAVE_XMB -DHAVE_MATERIALUI -DHAVE_LIBRETRODB DEFINES -DHAVE_KEYMAPPER DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DWANT_ZLIB -DHAVE_CC_RESAMPLER ifeq ($(DEBUG), 1) DEFINES += -DHAVE_NETLOGGER diff --git a/Makefile.wiiu b/Makefile.wiiu index 4b5eeafc02..59b35b388b 100644 --- a/Makefile.wiiu +++ b/Makefile.wiiu @@ -6,7 +6,8 @@ DEBUG = 0 GRIFFIN_BUILD = 0 SALAMANDER_BUILD = 0 WHOLE_ARCHIVE_LINK = 0 -WIIU_HID = 0 +WIIU_HID = 1 +HAVE_RUNAHEAD = 1 WIIU_LOG_RPX = 0 BUILD_DIR = objs/wiiu PC_DEVELOPMENT_IP_ADDRESS ?= @@ -32,6 +33,7 @@ OBJ += wiiu/input/wpad_driver.o OBJ += wiiu/input/kpad_driver.o OBJ += wiiu/input/pad_functions.o OBJ += wiiu/system/memory.o +OBJ += wiiu/system/atomic.o OBJ += wiiu/system/exception_handler.o OBJ += wiiu/fs/sd_fat_devoptab.o OBJ += wiiu/fs/fs_utils.o @@ -48,15 +50,11 @@ ifeq ($(WIIU_HID),1) OBJ += wiiu/input/hidpad_driver.o OBJ += wiiu/input/wiiu_hid.o OBJ += input/connect/joypad_connection.o \ - input/connect/connect_ps2adapter.o \ - input/connect/connect_psxadapter.o \ - input/connect/connect_ps3.o \ - input/connect/connect_ps4.o \ - input/connect/connect_wii.o \ - input/connect/connect_nesusb.o \ - input/connect/connect_snesusb.o \ - input/connect/connect_wiiupro.o \ - input/connect/connect_wiiugca.o + input/common/hid/hid_device_driver.o \ + input/common/hid/device_wiiu_gca.o \ + input/common/hid/device_ds3.o \ + input/common/hid/device_ds4.o \ + input/common/hid/device_null.o endif ifeq ($(SALAMANDER_BUILD),1) @@ -88,6 +86,10 @@ else DEFINES += -DHAVE_SLANG DEFINES += -DHAVE_SHADERPIPELINE +ifeq ($(HAVE_RUNAHEAD),1) + DEFINES += -DHAVE_RUNAHEAD +endif + OBJ += wiiu/system/missing_libc_functions.o OBJ += wiiu/shader_utils.o OBJ += gfx/drivers/gx2_shaders/tex.o @@ -120,7 +122,6 @@ else HAVE_ZLIB = 1 HAVE_7ZIP = 1 HAVE_BUILTINZLIB = 1 - HAVE_KEYMAPPER = 1 HAVE_LIBRETRODB = 1 HAVE_ZARCH = 0 HAVE_MATERIALUI = 1 diff --git a/README.md b/README.md index ccf7c912ec..abeeea10c6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # RetroArch RetroArch is the reference frontend for the libretro API. -Popular examples of implementations for this API includes videogame system emulators and game engines as well as +Popular examples of implementations for this API includes video game system emulators and game engines as well as more generalized 3D programs. These programs are instantiated as dynamic libraries. We refer to these as "libretro cores". @@ -79,7 +79,7 @@ RetroArch has been ported to the following platforms: - Original Microsoft Xbox - Microsoft Xbox 360 (Libxenon/XeXDK) - Nintendo Wii, GameCube (Libogc) - - Nintendo WiiU + - Nintendo Wii U - Nintendo 3DS - Nintendo Switch - Raspberry Pi @@ -144,3 +144,115 @@ To configure joypads, use the built-in menu or the `retroarch-joyconfig` command ## Compiling and installing Instructions for compiling and installing RetroArch can be found in the [Libretro/RetroArch Documentation Center](https://docs.libretro.com/). + +## CRT 15Khz Resolution Switching + +CRT Switch res will turn on, on the fly. However, you will need to restart retroarch to disable it. With CRT SwitchRes enable Retroarch will start in 2560 x 480 @ 60. + +If you are running windows, before enabling the CRT SwitchRes options please make sure you have installed CRTEmudriver and installed some modelines. The minimum modelins for all games to switch correctly are: + +- 2560 x 192 @ 60.000000 +- 2560 x 200 @ 60.000000 +- 2560 x 240 @ 60.000000 +- 2560 x 224 @ 60.000000 +- 2560 x 237 @ 60.000000 +- 2560 x 256 @ 50.000000 +- 2560 x 254 @ 55.000000 +- 2560 x 448 @ 60.000000 +- 2560 x 480 @ 60.000000 + +Install these modelines replacing 2560 with your desired super resolution. The above resolutions are NTSC only so if you would be playing any PAL content please add pal modelines: + +- 2560 x 192 @ 50.000000 +- 2560 x 200 @ 50.000000 +- 2560 x 240 @ 50.000000 +- 2560 x 224 @ 50.000000 +- 2560 x 288 @ 50.000000 +- 2560 x 237 @ 50.000000 +- 2560 x 254 @ 55.000000 +- 2560 x 448 @ 50.000000 +- 2560 x 480 @ 50.000000 + +Some games will require higher PAL resolutions which should also be installed: + +- 2560 x 512 @ 50.000000 +- 2560 x 576 @ 50.000000 + +Ideally install all these modelines and everything will work great. + +## Super Resolutions + +The default super resolution is 2560. It is displayed just under the CRT switch option, which can be found in video settings. This can be changed within the retroarch.cfg. The only compatible resolutions are 1920, 2560 and 3840. Any other resolutions will be ignored and native switching will be activated. + +## Native Resolutions + +If native resolutions are activated you will need a whole new set of modelines: + +- 512 x 240 @ 50.006977 SNESpal +- 512 x 224 @ 50.006977 SNESpal +- 512 x 448 @ 50.006977 SNESpal +- 512 x 240 @ 60.098812 SNESntsc +- 512 x 224 @ 60.098812 SNESntsc +- 512 x 448 @ 60.098812 SNESntsc +- 256 x 240 @ 50.006977 SNESpal +- 256 x 448 @ 50.006977 SNESpal +- 256 x 240 @ 60.098812 SNESntsc +- 256 x 448 @ 60.098812 SNESntsc +- 320 x 240 @ 59.922745 MDntsc +- 320 x 448 @ 59.922745 MDntp +- 320 x 480 @ 59.922745 MDntsc +- 256 x 192 @ 59.922745 MDntsc +- 320 x 224 @ 59.922745 MDntsc +- 256 x 224 @ 59.922745 MDntsc +- 320 x 288 @ 49.701458 MDpal +- 320 x 576 @ 49.701458 MDpal +- 256 x 192 @ 49.701458 MDpal +- 320 x 224 @ 49.701458 MDpal +- 320 x 240 @ 49.701458 MDpal +- 320 x 448 @ 49.701458 MDpal +- 320 x 480 @ 49.701458 MDpal +- 256 x 224 @ 49.701458 MDpal +- 256 x 288 @ 49.701458 MSYSpal +- 256 x 240 @ 60.098812 NESntsc +- 256 x 240 @ 50.006977 NESpal + +- 640 x 480 @ 60.130001 N64ntsc +- 640 x 237 @ 60.130001 N64ntsc +- 640 x 240 @ 60.130001 N64ntsc +- 640 x 480 @ 50.000000 N64pal +- 640 x 576 @ 50.000000 n64pal +- 640 x 288 @ 50.000000 n64pal + +- 256 x 252 @ 49.759998 PSXpal +- 384 x 252 @ 49.759998 PSXpal +- 640 x 540 @ 49.759998 PSXpal +- 320 x 252 @ 49.759998 PSXpal +- 640 x 252 @ 49.759998 PSXpal + +- 384 x 240 @ 59.941002 PSXntsc +- 256 x 480 @ 59.941002 PSXntsc + +- 352 x 240 @ 59.820000 Saturn/SGFX_NTSCp +- 704 x 240 @ 59.820000 SaturnNTSCp +- 352 x 480 @ 59.820000 SaturnNTSCi +- 704 x 480 @ 59.820000 SaturnNTSCi +- 352 x 288 @ 49.701458 SaturnPALp +- 704 x 288 @ 49.701458 SaturnPALp +- 352 x 576 @ 49.701458 SaturnPALi +- 704 x 576 @ 49.701458 SaturnPALi + +- 240 x 160 @ 59.730000 GBA +- 320 x 200 @ 60.000000 Doom + +// Arcade + +- 400 x 254 @ 54.706841 MK +- 384 x 224 @ 59.637405 CPS1 + +These modelines are more accurate giving exact hz. However, some games may have unwanted results. This is due to mid-scanline resolution changes on the original hardware. For the best results super resolutions are the way to go. + +## CRT resolution switching & Mame + +Some arcade resolutions can be a lot different. There is resolution detection to ensure mame games will be displayed in the closest available resolution but drawn at their native resolution within this resolution. Meaning that the mame game will look just like the original hardware. + +Mame roms that run in a vertical aspect like DoDonPachi need to be rotated within mame before resolution switching and aspect correction will work. Do this before enabling CRT switchRes so that Retroarch will run in your desktop resolution. Once you have roted any games that may need it switch CRT SwitchRes on. diff --git a/audio/audio_driver.c b/audio/audio_driver.c index fb06d65ffb..e35fbd7951 100644 --- a/audio/audio_driver.c +++ b/audio/audio_driver.c @@ -45,7 +45,15 @@ #define AUDIO_BUFFER_FREE_SAMPLES_COUNT (8 * 1024) -#define AUDIO_MIXER_MAX_STREAMS 8 +/** + * db_to_gain: + * @db : Decibels. + * + * Converts decibels to voltage gain. + * + * Returns: voltage gain value. + **/ +#define db_to_gain(db) (powf(10.0f, (db) / 20.0f)) static const audio_driver_t *audio_drivers[] = { #ifdef HAVE_ALSA @@ -122,18 +130,6 @@ static const audio_driver_t *audio_drivers[] = { NULL, }; -struct audio_mixer_stream -{ - audio_mixer_sound_t *handle; - audio_mixer_voice_t *voice; - audio_mixer_stop_cb_t stop_cb; - enum audio_mixer_state state; - float volume; - void *buf; - size_t bufsize; -}; - -static unsigned audio_mixer_current_max_idx = 0; static struct audio_mixer_stream audio_mixer_streams[AUDIO_MIXER_MAX_STREAMS] = {{0}}; static size_t audio_driver_chunk_size = 0; @@ -183,6 +179,11 @@ static void *audio_driver_context_audio_data = NULL; static bool audio_suspended = false; +static void audio_mixer_play_stop_sequential_cb( + audio_mixer_sound_t *sound, unsigned reason); +static void audio_mixer_play_stop_cb( + audio_mixer_sound_t *sound, unsigned reason); + enum resampler_quality audio_driver_get_resampler_quality(void) { settings_t *settings = config_get_ptr(); @@ -193,6 +194,22 @@ enum resampler_quality audio_driver_get_resampler_quality(void) return (enum resampler_quality)settings->uints.audio_resampler_quality; } +audio_mixer_stream_t *audio_driver_mixer_get_stream(unsigned i) +{ + if (i > (AUDIO_MIXER_MAX_STREAMS-1)) + return NULL; + return &audio_mixer_streams[i]; +} + +const char *audio_driver_mixer_get_stream_name(unsigned i) +{ + if (i > (AUDIO_MIXER_MAX_STREAMS-1)) + return "N/A"; + if (!string_is_empty(audio_mixer_streams[i].name)) + return audio_mixer_streams[i].name; + return "N/A"; +} + /** * compute_audio_buffer_statistics: * @@ -213,7 +230,7 @@ bool compute_audio_buffer_statistics(audio_statistics_t *stats) if (!stats || samples < 3) return false; - stats->samples = audio_driver_free_samples_count; + stats->samples = (unsigned)audio_driver_free_samples_count; #ifdef WARPUP /* uint64 to double not implemented, fair chance @@ -368,6 +385,12 @@ static bool audio_driver_deinit_internal(void) return true; } +static void audio_driver_mixer_init(unsigned out_rate) +{ + audio_mixer_init(out_rate); +} + + static bool audio_driver_init_internal(bool audio_cb_inited) { unsigned new_rate = 0; @@ -524,7 +547,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited) { audio_driver_buffer_size = current_audio->buffer_size(audio_driver_context_audio_data); - audio_driver_control = true; + audio_driver_control = true; } else RARCH_WARN("Audio rate control was desired, but driver does not support needed features.\n"); @@ -534,7 +557,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited) audio_driver_free_samples_count = 0; - audio_mixer_init(settings->uints.audio_out_rate); + audio_driver_mixer_init(settings->uints.audio_out_rate); /* Threaded driver is initially stopped. */ if ( @@ -576,20 +599,17 @@ void audio_driver_set_nonblocking_state(bool enable) static void audio_driver_flush(const int16_t *data, size_t samples) { struct resampler_data src_data; - bool is_perfcnt_enable = false; - bool is_paused = false; - bool is_idle = false; - bool is_slowmotion = false; - const void *output_data = NULL; - unsigned output_frames = 0; - float audio_volume_gain = !audio_driver_mute_enable ? + bool is_perfcnt_enable = false; + bool is_paused = false; + bool is_idle = false; + bool is_slowmotion = false; + const void *output_data = NULL; + unsigned output_frames = 0; + float audio_volume_gain = !audio_driver_mute_enable ? audio_driver_volume_gain : 0.0f; - src_data.data_in = NULL; - src_data.data_out = NULL; - src_data.input_frames = 0; - src_data.output_frames = 0; - src_data.ratio = 0.0f; + src_data.data_out = NULL; + src_data.output_frames = 0; if (recording_data) recording_push_audio(data, samples); @@ -606,8 +626,8 @@ static void audio_driver_flush(const int16_t *data, size_t samples) convert_s16_to_float(audio_driver_input_data, data, samples, audio_volume_gain); - src_data.data_in = audio_driver_input_data; - src_data.input_frames = samples >> 1; + src_data.data_in = audio_driver_input_data; + src_data.input_frames = samples >> 1; if (audio_driver_dsp) @@ -662,7 +682,7 @@ static void audio_driver_flush(const int16_t *data, size_t samples) #endif } - src_data.ratio = audio_source_ratio_current; + src_data.ratio = audio_source_ratio_current; if (is_slowmotion) { @@ -675,7 +695,7 @@ static void audio_driver_flush(const int16_t *data, size_t samples) if (audio_mixer_active) { bool override = audio_driver_mixer_mute_enable ? true : - (audio_driver_mixer_volume_gain != 0.0f) ? true : false; + (audio_driver_mixer_volume_gain != 1.0f) ? true : false; float mixer_gain = !audio_driver_mixer_mute_enable ? audio_driver_mixer_volume_gain : 0.0f; audio_mixer_mix(audio_driver_output_samples_buf, @@ -725,6 +745,22 @@ void audio_driver_sample(int16_t left, int16_t right) audio_driver_data_ptr = 0; } +void audio_driver_menu_sample(void) +{ + static int16_t samples_buf[1024] = {0}; + struct retro_system_av_info + *av_info = video_viewport_get_system_av_info(); + const struct retro_system_timing *info = + (const struct retro_system_timing*)&av_info->timing; + unsigned sample_count = (info->sample_rate / info->fps) * 2; + while (sample_count > 1024) + { + audio_driver_flush(samples_buf, 1024); + sample_count -= 1024; + } + audio_driver_flush(samples_buf, sample_count); +} + /** * audio_driver_sample_batch: * @data : pointer to audio buffer. @@ -840,13 +876,13 @@ void audio_driver_monitor_adjust_system_rates(void) { float timing_skew; settings_t *settings = config_get_ptr(); - struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); float video_refresh_rate = settings->floats.video_refresh_rate; float max_timing_skew = settings->floats.audio_max_timing_skew; - const struct retro_system_timing *info = av_info ? - (const struct retro_system_timing*)&av_info->timing : NULL; + struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); + const struct retro_system_timing *info = + (const struct retro_system_timing*)&av_info->timing; - if (!info || info->sample_rate <= 0.0) + if (info->sample_rate <= 0.0) return; timing_skew = fabs(1.0f - info->fps / video_refresh_rate); @@ -976,6 +1012,12 @@ bool audio_driver_mixer_extension_supported(const char *ext) string_list_append(str_list, "mod", attr); string_list_append(str_list, "s3m", attr); string_list_append(str_list, "xm", attr); +#endif +#ifdef HAVE_DR_FLAC + string_list_append(str_list, "flac", attr); +#endif +#ifdef HAVE_DR_MP3 + string_list_append(str_list, "mp3", attr); #endif string_list_append(str_list, "wav", attr); @@ -1021,18 +1063,16 @@ static void audio_mixer_play_stop_cb( { unsigned i = (unsigned)idx; -#if 0 - if (audio_mixer_streams[i].buf != NULL) - free(audio_mixer_streams[i].buf); -#endif + if (!string_is_empty(audio_mixer_streams[i].name)) + free(audio_mixer_streams[i].name); + audio_mixer_streams[i].name = NULL; audio_mixer_streams[i].state = AUDIO_STREAM_STATE_NONE; audio_mixer_streams[i].volume = 0.0f; audio_mixer_streams[i].buf = NULL; audio_mixer_streams[i].stop_cb = NULL; audio_mixer_streams[i].handle = NULL; audio_mixer_streams[i].voice = NULL; - audio_mixer_current_max_idx--; } break; case AUDIO_MIXER_SOUND_STOPPED: @@ -1042,15 +1082,75 @@ static void audio_mixer_play_stop_cb( } } +static void audio_mixer_play_stop_sequential_cb( + audio_mixer_sound_t *sound, unsigned reason) +{ + int idx = audio_mixer_find_index(sound); + + switch (reason) + { + case AUDIO_MIXER_SOUND_FINISHED: + audio_mixer_destroy(sound); + + if (idx >= 0) + { + unsigned i = (unsigned)idx; + + if (!string_is_empty(audio_mixer_streams[i].name)) + free(audio_mixer_streams[i].name); + + audio_mixer_streams[i].name = NULL; + audio_mixer_streams[i].state = AUDIO_STREAM_STATE_NONE; + audio_mixer_streams[i].volume = 0.0f; + audio_mixer_streams[i].buf = NULL; + audio_mixer_streams[i].stop_cb = NULL; + audio_mixer_streams[i].handle = NULL; + audio_mixer_streams[i].voice = NULL; + + i++; + + for (; i < AUDIO_MIXER_MAX_STREAMS; i++) + { + if (audio_mixer_streams[i].state == AUDIO_STREAM_STATE_STOPPED) + { + audio_driver_mixer_play_stream_sequential(i); + break; + } + } + } + break; + case AUDIO_MIXER_SOUND_STOPPED: + break; + case AUDIO_MIXER_SOUND_REPEATED: + break; + } +} + +bool audio_driver_mixer_get_free_stream_slot(unsigned *id) +{ + unsigned i; + for (i = 0; i < AUDIO_MIXER_MAX_STREAMS; i++) + { + if (audio_mixer_streams[i].state == AUDIO_STREAM_STATE_NONE) + { + *id = i; + return true; + } + } + + return false; +} + bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params) { + unsigned free_slot = 0; audio_mixer_voice_t *voice = NULL; audio_mixer_sound_t *handle = NULL; audio_mixer_stop_cb_t stop_cb = audio_mixer_play_stop_cb; bool looped = false; void *buf = NULL; - - if (audio_mixer_current_max_idx >= AUDIO_MIXER_MAX_STREAMS) + + if (!audio_driver_mixer_get_free_stream_slot(&free_slot)) return false; if (params->state == AUDIO_STREAM_STATE_NONE) @@ -1074,9 +1174,18 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params) case AUDIO_MIXER_TYPE_MOD: handle = audio_mixer_load_mod(buf, (int32_t)params->bufsize); break; + case AUDIO_MIXER_TYPE_FLAC: +#ifdef HAVE_DR_FLAC + handle = audio_mixer_load_flac(buf, (int32_t)params->bufsize); +#endif + break; + case AUDIO_MIXER_TYPE_MP3: +#ifdef HAVE_DR_MP3 + handle = audio_mixer_load_mp3(buf, (int32_t)params->bufsize); +#endif + break; case AUDIO_MIXER_TYPE_NONE: - free(buf); - return false; + break; } if (!handle) @@ -1085,74 +1194,193 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params) return false; } - if (params->state == AUDIO_STREAM_STATE_PLAYING) + switch (params->state) { - voice = audio_mixer_play(handle, looped, params->volume, stop_cb); - audio_set_bool(AUDIO_ACTION_MIXER, true); - } - else if (params->state == AUDIO_STREAM_STATE_PLAYING_LOOPED) - { - looped = true; - voice = audio_mixer_play(handle, looped, params->volume, stop_cb); - audio_set_bool(AUDIO_ACTION_MIXER, true); + case AUDIO_STREAM_STATE_PLAYING_LOOPED: + looped = true; + voice = audio_mixer_play(handle, looped, params->volume, stop_cb); + break; + case AUDIO_STREAM_STATE_PLAYING: + voice = audio_mixer_play(handle, looped, params->volume, stop_cb); + break; + case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL: + stop_cb = audio_mixer_play_stop_sequential_cb; + voice = audio_mixer_play(handle, looped, params->volume, stop_cb); + break; + default: + break; } - audio_mixer_streams[audio_mixer_current_max_idx].buf = buf; - audio_mixer_streams[audio_mixer_current_max_idx].handle = handle; - audio_mixer_streams[audio_mixer_current_max_idx].voice = voice; - audio_mixer_streams[audio_mixer_current_max_idx].state = params->state; - audio_mixer_streams[audio_mixer_current_max_idx].volume = params->volume; - audio_mixer_streams[audio_mixer_current_max_idx].stop_cb = stop_cb; + audio_mixer_active = true; - audio_mixer_current_max_idx++; + audio_mixer_streams[free_slot].name = !string_is_empty(params->basename) ? strdup(params->basename) : NULL; + audio_mixer_streams[free_slot].buf = buf; + audio_mixer_streams[free_slot].handle = handle; + audio_mixer_streams[free_slot].voice = voice; + audio_mixer_streams[free_slot].state = params->state; + audio_mixer_streams[free_slot].volume = params->volume; + audio_mixer_streams[free_slot].stop_cb = stop_cb; return true; } -static void audio_driver_mixer_remove_stream(unsigned i) +enum audio_mixer_state audio_driver_mixer_get_stream_state(unsigned i) { - audio_mixer_sound_t *handle = audio_mixer_streams[i].handle; - audio_mixer_voice_t *voice = audio_mixer_streams[i].voice; + if (i >= AUDIO_MIXER_MAX_STREAMS) + return AUDIO_STREAM_STATE_NONE; + + return audio_mixer_streams[i].state; +} + +static void audio_driver_mixer_play_stream_internal(unsigned i, unsigned type) +{ + bool set_state = false; + + if (i >= AUDIO_MIXER_MAX_STREAMS) + return; + + switch (audio_mixer_streams[i].state) + { + case AUDIO_STREAM_STATE_STOPPED: + audio_mixer_streams[i].voice = audio_mixer_play(audio_mixer_streams[i].handle, + (type == AUDIO_STREAM_STATE_PLAYING_LOOPED) ? true : false, + 1.0f, audio_mixer_streams[i].stop_cb); + set_state = true; + break; + case AUDIO_STREAM_STATE_PLAYING: + case AUDIO_STREAM_STATE_PLAYING_LOOPED: + case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL: + case AUDIO_STREAM_STATE_NONE: + break; + } + + if (set_state) + audio_mixer_streams[i].state = (enum audio_mixer_state)type; +} + +void audio_driver_mixer_play_stream(unsigned i) +{ + audio_mixer_streams[i].stop_cb = audio_mixer_play_stop_cb; + audio_driver_mixer_play_stream_internal(i, AUDIO_STREAM_STATE_PLAYING); +} + +void audio_driver_mixer_play_stream_looped(unsigned i) +{ + audio_mixer_streams[i].stop_cb = audio_mixer_play_stop_cb; + audio_driver_mixer_play_stream_internal(i, AUDIO_STREAM_STATE_PLAYING_LOOPED); +} + +void audio_driver_mixer_play_stream_sequential(unsigned i) +{ + audio_mixer_streams[i].stop_cb = audio_mixer_play_stop_sequential_cb; + audio_driver_mixer_play_stream_internal(i, AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL); +} + +float audio_driver_mixer_get_stream_volume(unsigned i) +{ + if (i >= AUDIO_MIXER_MAX_STREAMS) + return 0.0f; + + return audio_mixer_streams[i].volume; +} + +void audio_driver_mixer_set_stream_volume(unsigned i, float vol) +{ + audio_mixer_voice_t *voice = NULL; + + if (i >= AUDIO_MIXER_MAX_STREAMS) + return; + + audio_mixer_streams[i].volume = vol; + + voice = audio_mixer_streams[i].voice; + + if (voice) + audio_mixer_voice_set_volume(voice, db_to_gain(vol)); +} + +void audio_driver_mixer_stop_stream(unsigned i) +{ + bool set_state = false; + + if (i >= AUDIO_MIXER_MAX_STREAMS) + return; switch (audio_mixer_streams[i].state) { case AUDIO_STREAM_STATE_PLAYING: - if (voice) - audio_mixer_stop(voice); - if (handle) - audio_mixer_destroy(handle); - break; case AUDIO_STREAM_STATE_PLAYING_LOOPED: - if (voice) - audio_mixer_stop(voice); - if (handle) - audio_mixer_destroy(handle); + case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL: + set_state = true; break; case AUDIO_STREAM_STATE_STOPPED: - if (handle) - audio_mixer_destroy(handle); + case AUDIO_STREAM_STATE_NONE: + break; + } + + if (set_state) + { + audio_mixer_voice_t *voice = audio_mixer_streams[i].voice; + + if (voice) + audio_mixer_stop(voice); + audio_mixer_streams[i].state = AUDIO_STREAM_STATE_STOPPED; + audio_mixer_streams[i].volume = 1.0f; + } +} + +void audio_driver_mixer_remove_stream(unsigned i) +{ + bool destroy = false; + + if (i >= AUDIO_MIXER_MAX_STREAMS) + return; + + switch (audio_mixer_streams[i].state) + { + case AUDIO_STREAM_STATE_PLAYING: + case AUDIO_STREAM_STATE_PLAYING_LOOPED: + case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL: + audio_driver_mixer_stop_stream(i); + destroy = true; + break; + case AUDIO_STREAM_STATE_STOPPED: + destroy = true; break; case AUDIO_STREAM_STATE_NONE: break; } - audio_mixer_streams[i].state = AUDIO_STREAM_STATE_NONE; - audio_mixer_streams[i].volume = 0.0f; - audio_mixer_streams[i].stop_cb = NULL; - audio_mixer_streams[i].handle = NULL; - audio_mixer_streams[i].voice = NULL; + if (destroy) + { + audio_mixer_sound_t *handle = audio_mixer_streams[i].handle; + if (handle) + audio_mixer_destroy(handle); + + if (!string_is_empty(audio_mixer_streams[i].name)) + free(audio_mixer_streams[i].name); + + audio_mixer_streams[i].state = AUDIO_STREAM_STATE_NONE; + audio_mixer_streams[i].stop_cb = NULL; + audio_mixer_streams[i].volume = 0.0f; + audio_mixer_streams[i].handle = NULL; + audio_mixer_streams[i].voice = NULL; + audio_mixer_streams[i].name = NULL; + } } static void audio_driver_mixer_deinit(void) { unsigned i; - audio_set_bool(AUDIO_ACTION_MIXER, false); + audio_mixer_active = false; for (i = 0; i < AUDIO_MIXER_MAX_STREAMS; i++) + { + audio_driver_mixer_stop_stream(i); audio_driver_mixer_remove_stream(i); + } - audio_mixer_current_max_idx = 0; audio_mixer_done(); } @@ -1351,15 +1579,6 @@ void audio_set_bool(enum audio_action action, bool val) } } -/** - * db_to_gain: - * @db : Decibels. - * - * Converts decibels to voltage gain. - * - * Returns: voltage gain value. - **/ -#define db_to_gain(db) (powf(10.0f, (db) / 20.0f)) void audio_set_float(enum audio_action action, float val) { diff --git a/audio/audio_driver.h b/audio/audio_driver.h index 6dfacaa89f..a2cdad4f41 100644 --- a/audio/audio_driver.h +++ b/audio/audio_driver.h @@ -35,6 +35,8 @@ RETRO_BEGIN_DECLS #define AUDIO_MAX_RATIO 16 +#define AUDIO_MIXER_MAX_STREAMS 16 + enum audio_action { AUDIO_ACTION_NONE = 0, @@ -46,6 +48,27 @@ enum audio_action AUDIO_ACTION_MIXER }; +enum audio_mixer_state +{ + AUDIO_STREAM_STATE_NONE = 0, + AUDIO_STREAM_STATE_STOPPED, + AUDIO_STREAM_STATE_PLAYING, + AUDIO_STREAM_STATE_PLAYING_LOOPED, + AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL +}; + +typedef struct audio_mixer_stream +{ + audio_mixer_sound_t *handle; + audio_mixer_voice_t *voice; + audio_mixer_stop_cb_t stop_cb; + enum audio_mixer_state state; + float volume; + void *buf; + char *name; + size_t bufsize; +} audio_mixer_stream_t; + typedef struct audio_statistics { float average_buffer_saturation; @@ -137,20 +160,13 @@ typedef struct audio_driver size_t (*buffer_size)(void *data); } audio_driver_t; -enum audio_mixer_state -{ - AUDIO_STREAM_STATE_NONE = 0, - AUDIO_STREAM_STATE_STOPPED, - AUDIO_STREAM_STATE_PLAYING, - AUDIO_STREAM_STATE_PLAYING_LOOPED -}; - typedef struct audio_mixer_stream_params { float volume; enum audio_mixer_type type; enum audio_mixer_state state; void *buf; + char *basename; size_t bufsize; audio_mixer_stop_cb_t cb; } audio_mixer_stream_params_t; @@ -271,10 +287,32 @@ bool audio_driver_deinit(void); bool audio_driver_init(void); +void audio_driver_menu_sample(void); + +audio_mixer_stream_t *audio_driver_mixer_get_stream(unsigned i); + bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params); +void audio_driver_mixer_play_stream(unsigned i); + +void audio_driver_mixer_play_stream_sequential(unsigned i); + +void audio_driver_mixer_play_stream_looped(unsigned i); + +void audio_driver_mixer_stop_stream(unsigned i); + +float audio_driver_mixer_get_stream_volume(unsigned i); + +void audio_driver_mixer_set_stream_volume(unsigned i, float vol); + +void audio_driver_mixer_remove_stream(unsigned i); + enum resampler_quality audio_driver_get_resampler_quality(void); +enum audio_mixer_state audio_driver_mixer_get_stream_state(unsigned i); + +const char *audio_driver_mixer_get_stream_name(unsigned i); + bool compute_audio_buffer_statistics(audio_statistics_t *stats); extern audio_driver_t audio_rsound; diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 57f027641f..c4da205828 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -107,6 +107,8 @@ #define CHEEVOS_JSON_KEY_LEADERBOARDS 0xf1247d2dU #define CHEEVOS_JSON_KEY_MEM 0x0b8807e4U #define CHEEVOS_JSON_KEY_FORMAT 0xb341208eU +#define CHEEVOS_JSON_KEY_SUCCESS 0x110461deU +#define CHEEVOS_JSON_KEY_ERROR 0x0d2011cfU typedef struct { @@ -299,6 +301,15 @@ int cheats_were_enabled = 0; Supporting functions. *****************************************************************************/ +#ifndef CHEEVOS_VERBOSE + +void cheevos_log(const char *fmt, ...) +{ + (void)fmt; +} + +#endif + static unsigned size_in_megabytes(unsigned val) { return (val * 1024 * 1024); @@ -308,7 +319,7 @@ static unsigned size_in_megabytes(unsigned val) static void cheevos_log_url(const char* format, const char* url) { #ifdef CHEEVOS_LOG_PASSWORD - RARCH_LOG(format, url); + CHEEVOS_LOG(format, url); #else char copy[256]; char* aux = NULL; @@ -359,340 +370,11 @@ static void cheevos_log_url(const char* format, const char* url) *aux = 0; } - RARCH_LOG(format, copy); + CHEEVOS_LOG(format, copy); #endif } #endif -#ifdef CHEEVOS_VERBOSE -static void cheevos_add_char(char** aux, size_t* left, char k) -{ - if (*left >= 1) - { - **aux = k; - (*aux)++; - (*left)--; - } -} - -static void cheevos_add_string(char** aux, size_t* left, const char* s) -{ - size_t len = strlen(s); - - if (*left >= len) - { - strcpy(*aux, s); - *aux += len; - *left -= len; - } -} - -static void cheevos_add_hex(char** aux, size_t* left, unsigned v) -{ - char buffer[32]; - - snprintf(buffer, sizeof(buffer), "%06x", v); - buffer[sizeof(buffer) - 1] = 0; - - cheevos_add_string(aux, left, buffer); -} - -static void cheevos_add_uint(char** aux, size_t* left, unsigned v) -{ - char buffer[32]; - - snprintf(buffer, sizeof(buffer), "%u", v); - buffer[sizeof(buffer) - 1] = 0; - - cheevos_add_string(aux, left, buffer); -} - -static void cheevos_add_int(char** aux, size_t* left, int v) -{ - char buffer[32]; - - snprintf(buffer, sizeof(buffer), "%d", v); - buffer[sizeof(buffer) - 1] = 0; - - cheevos_add_string(aux, left, buffer); -} - -static void cheevos_log_var(const cheevos_var_t* var) -{ - if (!var) - return; - - RARCH_LOG("[CHEEVOS]: size: %s\n", - var->size == CHEEVOS_VAR_SIZE_BIT_0 ? "bit 0" : - var->size == CHEEVOS_VAR_SIZE_BIT_1 ? "bit 1" : - var->size == CHEEVOS_VAR_SIZE_BIT_2 ? "bit 2" : - var->size == CHEEVOS_VAR_SIZE_BIT_3 ? "bit 3" : - var->size == CHEEVOS_VAR_SIZE_BIT_4 ? "bit 4" : - var->size == CHEEVOS_VAR_SIZE_BIT_5 ? "bit 5" : - var->size == CHEEVOS_VAR_SIZE_BIT_6 ? "bit 6" : - var->size == CHEEVOS_VAR_SIZE_BIT_7 ? "bit 7" : - var->size == CHEEVOS_VAR_SIZE_NIBBLE_LOWER ? "low nibble" : - var->size == CHEEVOS_VAR_SIZE_NIBBLE_UPPER ? "high nibble" : - var->size == CHEEVOS_VAR_SIZE_EIGHT_BITS ? "byte" : - var->size == CHEEVOS_VAR_SIZE_SIXTEEN_BITS ? "word" : - var->size == CHEEVOS_VAR_SIZE_THIRTYTWO_BITS ? "dword" : - "?" - ); - RARCH_LOG("[CHEEVOS]: type: %s\n", - var->type == CHEEVOS_VAR_TYPE_ADDRESS ? "address" : - var->type == CHEEVOS_VAR_TYPE_VALUE_COMP ? "value" : - var->type == CHEEVOS_VAR_TYPE_DELTA_MEM ? "delta" : - var->type == CHEEVOS_VAR_TYPE_DYNAMIC_VAR ? "dynamic" : - "?" - ); - RARCH_LOG("[CHEEVOS]: value: %u\n", var->value); -} - -static void cheevos_log_cond(const cheevos_cond_t* cond) -{ - if (!cond) - return; - - RARCH_LOG("[CHEEVOS]: condition %p\n", cond); - RARCH_LOG("[CHEEVOS]: type: %s\n", - cond->type == CHEEVOS_COND_TYPE_STANDARD ? "standard" : - cond->type == CHEEVOS_COND_TYPE_PAUSE_IF ? "pause" : - cond->type == CHEEVOS_COND_TYPE_RESET_IF ? "reset" : - cond->type == CHEEVOS_COND_TYPE_ADD_SOURCE ? "add source" : - cond->type == CHEEVOS_COND_TYPE_SUB_SOURCE ? "sub source" : - cond->type == CHEEVOS_COND_TYPE_ADD_HITS ? "add hits" : - "?" - ); - RARCH_LOG("[CHEEVOS]: req_hits: %u\n", cond->req_hits); - RARCH_LOG("[CHEEVOS]: source:\n"); - cheevos_log_var(&cond->source); - RARCH_LOG("[CHEEVOS]: op: %s\n", - cond->op == CHEEVOS_COND_OP_EQUALS ? "==" : - cond->op == CHEEVOS_COND_OP_LESS_THAN ? "<" : - cond->op == CHEEVOS_COND_OP_LESS_THAN_OR_EQUAL ? "<=" : - cond->op == CHEEVOS_COND_OP_GREATER_THAN ? ">" : - cond->op == CHEEVOS_COND_OP_GREATER_THAN_OR_EQUAL ? ">=" : - cond->op == CHEEVOS_COND_OP_NOT_EQUAL_TO ? "!=" : - "?" - ); - RARCH_LOG("[CHEEVOS]: target:\n"); - cheevos_log_var(&cond->target); -} - -static void cheevos_log_cheevo(const cheevo_t* cheevo, - const cheevos_field_t* memaddr_ud) -{ - if (!cheevo || !memaddr_ud) - return; - - RARCH_LOG("[CHEEVOS]: cheevo %p\n", cheevo); - RARCH_LOG("[CHEEVOS]: id: %u\n", cheevo->id); - RARCH_LOG("[CHEEVOS]: title: %s\n", cheevo->title); - RARCH_LOG("[CHEEVOS]: desc: %s\n", cheevo->description); - RARCH_LOG("[CHEEVOS]: author: %s\n", cheevo->author); - RARCH_LOG("[CHEEVOS]: badge: %s\n", cheevo->badge); - RARCH_LOG("[CHEEVOS]: points: %u\n", cheevo->points); - RARCH_LOG("[CHEEVOS]: sets: TBD\n"); - RARCH_LOG("[CHEEVOS]: memaddr: %.*s\n", - (int)memaddr_ud->length, memaddr_ud->string); -} - -static void cheevos_add_var_size(char** aux, size_t* left, - const cheevos_var_t* var) -{ - if (!var) - return; - - switch( var->size ) - { - case CHEEVOS_VAR_SIZE_BIT_0: - cheevos_add_char(aux, left, 'M'); - break; - case CHEEVOS_VAR_SIZE_BIT_1: - cheevos_add_char(aux, left, 'N'); - break; - case CHEEVOS_VAR_SIZE_BIT_2: - cheevos_add_char(aux, left, 'O'); - break; - case CHEEVOS_VAR_SIZE_BIT_3: - cheevos_add_char(aux, left, 'P'); - break; - case CHEEVOS_VAR_SIZE_BIT_4: - cheevos_add_char(aux, left, 'Q'); - break; - case CHEEVOS_VAR_SIZE_BIT_5: - cheevos_add_char(aux, left, 'R'); - break; - case CHEEVOS_VAR_SIZE_BIT_6: - cheevos_add_char(aux, left, 'S'); - break; - case CHEEVOS_VAR_SIZE_BIT_7: - cheevos_add_char(aux, left, 'T'); - break; - case CHEEVOS_VAR_SIZE_NIBBLE_LOWER: - cheevos_add_char(aux, left, 'L'); - break; - case CHEEVOS_VAR_SIZE_NIBBLE_UPPER: - cheevos_add_char(aux, left, 'U'); - break; - case CHEEVOS_VAR_SIZE_EIGHT_BITS: - cheevos_add_char(aux, left, 'H'); - break; - case CHEEVOS_VAR_SIZE_THIRTYTWO_BITS: - cheevos_add_char(aux, left, 'X'); - break; - case CHEEVOS_VAR_SIZE_SIXTEEN_BITS: - default: - cheevos_add_char(aux, left, ' '); - break; - } -} - -static void cheevos_add_var(const cheevos_var_t* var, char** memaddr, - size_t *left) -{ - if (!var) - return; - - if ( var->type == CHEEVOS_VAR_TYPE_ADDRESS - || var->type == CHEEVOS_VAR_TYPE_DELTA_MEM) - { - if (var->type == CHEEVOS_VAR_TYPE_DELTA_MEM) - cheevos_add_char(memaddr, left, 'd'); - else if (var->is_bcd) - cheevos_add_char(memaddr, left, 'b'); - - cheevos_add_string(memaddr, left, "0x"); - cheevos_add_var_size(memaddr, left, var); - cheevos_add_hex(memaddr, left, var->value); - } - else if (var->type == CHEEVOS_VAR_TYPE_VALUE_COMP) - { - cheevos_add_uint(memaddr, left, var->value); - } -} - -static void cheevos_build_memaddr(const cheevos_condition_t* condition, - char* memaddr, size_t left) -{ - size_t i, j; - const cheevos_cond_t* cond; - const cheevos_condset_t *condset; - char *aux = memaddr; - - left--; /* reserve one char for the null terminator */ - - for (i = 0, condset = condition->condsets; - i < condition->count; i++, condset++) - { - if (i != 0) - cheevos_add_char(&aux, &left, 'S'); - - for (j = 0, cond = condset->conds; - j < condset->count; j++, cond++) - { - if (j != 0) - cheevos_add_char(&aux, &left, '_'); - - if (cond->type == CHEEVOS_COND_TYPE_RESET_IF) - cheevos_add_string(&aux, &left, "R:"); - else if (cond->type == CHEEVOS_COND_TYPE_PAUSE_IF) - cheevos_add_string(&aux, &left, "P:"); - else if (cond->type == CHEEVOS_COND_TYPE_ADD_SOURCE) - cheevos_add_string(&aux, &left, "A:"); - else if (cond->type == CHEEVOS_COND_TYPE_SUB_SOURCE) - cheevos_add_string(&aux, &left, "B:"); - else if (cond->type == CHEEVOS_COND_TYPE_ADD_HITS) - cheevos_add_string(&aux, &left, "C:"); - - cheevos_add_var(&cond->source, &aux, &left); - - switch (cond->op) - { - case CHEEVOS_COND_OP_EQUALS: - cheevos_add_char(&aux, &left, '='); - break; - case CHEEVOS_COND_OP_GREATER_THAN: - cheevos_add_char(&aux, &left, '>'); - break; - case CHEEVOS_COND_OP_GREATER_THAN_OR_EQUAL: - cheevos_add_string(&aux, &left, ">="); - break; - case CHEEVOS_COND_OP_LESS_THAN: - cheevos_add_char(&aux, &left, '<'); - break; - case CHEEVOS_COND_OP_LESS_THAN_OR_EQUAL: - cheevos_add_string(&aux, &left, "<="); - break; - case CHEEVOS_COND_OP_NOT_EQUAL_TO: - cheevos_add_string(&aux, &left, "!="); - break; - } - - cheevos_add_var(&cond->target, &aux, &left); - - if (cond->req_hits > 0) - { - cheevos_add_char(&aux, &left, '.'); - cheevos_add_uint(&aux, &left, cond->req_hits); - cheevos_add_char(&aux, &left, '.'); - } - } - } - - *aux = 0; -} - -static void cheevos_post_log_cheevo(const cheevo_t* cheevo) -{ - char memaddr[256]; - if (!cheevo) - return; - cheevos_build_memaddr(&cheevo->condition, memaddr, sizeof(memaddr)); - RARCH_LOG("[CHEEVOS]: memaddr (computed): %s\n", memaddr); -} - -static void cheevos_log_lboard(const cheevos_leaderboard_t* lb) -{ - unsigned i; - char mem[256]; - char* aux = NULL; - size_t left = 0; - - if (!lb) - return; - - RARCH_LOG("[CHEEVOS]: leaderboard %p\n", lb); - RARCH_LOG("[CHEEVOS]: id: %u\n", lb->id); - RARCH_LOG("[CHEEVOS]: title: %s\n", lb->title); - RARCH_LOG("[CHEEVOS]: desc: %s\n", lb->description); - - cheevos_build_memaddr(&lb->start, mem, sizeof(mem)); - RARCH_LOG("[CHEEVOS]: start: %s\n", mem); - - cheevos_build_memaddr(&lb->cancel, mem, sizeof(mem)); - RARCH_LOG("[CHEEVOS]: cancel: %s\n", mem); - - cheevos_build_memaddr(&lb->submit, mem, sizeof(mem)); - RARCH_LOG("[CHEEVOS]: submit: %s\n", mem); - - left = sizeof(mem); - aux = mem; - - for (i = 0; i < lb->value.count; i++) - { - if (i != 0) - cheevos_add_char(&aux, &left, '_'); - - cheevos_add_var(&lb->value.terms[i].var, &aux, &left); - cheevos_add_char(&aux, &left, '*'); - cheevos_add_int(&aux, &left, lb->value.terms[i].multiplier); - } - - RARCH_LOG("[CHEEVOS]: value: %s\n", mem); -} -#endif - static uint32_t cheevos_djb2(const char* str, size_t length) { const unsigned char *aux = (const unsigned char*)str; @@ -962,10 +644,8 @@ static int cheevos_parse_condition( cheevos_cond_count_in_set(memaddr, set); condset->conds = NULL; -#ifdef CHEEVOS_VERBOSE - RARCH_LOG("[CHEEVOS]: set %p (index=%u)\n", condset, set); - RARCH_LOG("[CHEEVOS]: conds: %u\n", condset->count); -#endif + CHEEVOS_LOG("[CHEEVOS]: set %p (index=%u)\n", condset, set); + CHEEVOS_LOG("[CHEEVOS]: conds: %u\n", condset->count); if (condset->count) { @@ -1216,17 +896,9 @@ static int cheevos_new_cheevo(cheevos_readud_t *ud) !cheevo->badge) goto error; -#ifdef CHEEVOS_VERBOSE - cheevos_log_cheevo(cheevo, &ud->memaddr); -#endif - if (cheevos_parse_condition(&cheevo->condition, ud->memaddr.string)) goto error; -#ifdef CHEEVOS_VERBOSE - cheevos_post_log_cheevo(cheevo); -#endif - return 0; error: @@ -1334,12 +1006,10 @@ static int cheevos_new_lboard(cheevos_readud_t *ud) if (!ldb || !ud) return -1; + lboard = ldb + ud->lboard_count++; - if (!lboard) - return -1; - - lboard->id = strtol(ud->id.string, NULL, 10); + lboard->id = (unsigned)strtol(ud->id.string, NULL, 10); lboard->format = cheevos_parse_format(&ud->format); lboard->title = cheevos_dupstr(&ud->title); lboard->description = cheevos_dupstr(&ud->desc); @@ -1350,10 +1020,6 @@ static int cheevos_new_lboard(cheevos_readud_t *ud) if (cheevos_parse_mem(lboard, ud->memaddr.string)) goto error; -#ifdef CHEEVOS_VERBOSE - cheevos_log_lboard(lboard); -#endif - return 0; error: @@ -1896,14 +1562,14 @@ static void cheevos_unlocked(void *task_data, void *user_data, if (!error) { - RARCH_LOG("[CHEEVOS]: awarded achievement %u.\n", cheevo->id); + CHEEVOS_LOG("[CHEEVOS]: awarded achievement %u.\n", cheevo->id); } else { char url[256]; url[0] = '\0'; - RARCH_ERR("[CHEEVOS]: error awarding achievement %u, retrying...\n", cheevo->id); + CHEEVOS_ERR("[CHEEVOS]: error awarding achievement %u, retrying...\n", cheevo->id); cheevos_make_unlock_url(cheevo, url, sizeof(url)); task_push_http_transfer(url, true, NULL, cheevos_unlocked, cheevo); @@ -1951,7 +1617,7 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) if (mode == CHEEVOS_ACTIVE_HARDCORE) cheevo->active &= ~CHEEVOS_ACTIVE_SOFTCORE; - RARCH_LOG("[CHEEVOS]: awarding cheevo %u: %s (%s).\n", + CHEEVOS_LOG("[CHEEVOS]: awarding cheevo %u: %s (%s).\n", cheevo->id, cheevo->title, cheevo->description); snprintf(msg, sizeof(msg), "Achievement Unlocked: %s", @@ -1976,9 +1642,9 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) if (take_screenshot(shotname, true, video_driver_cached_frame_has_valid_framebuffer())) - RARCH_LOG("[CHEEVOS]: got a screenshot for cheevo %u\n", cheevo->id); + CHEEVOS_LOG("[CHEEVOS]: got a screenshot for cheevo %u\n", cheevo->id); else - RARCH_LOG("[CHEEVOS]: failed to get screenshot for cheevo %u\n", cheevo->id); + CHEEVOS_LOG("[CHEEVOS]: failed to get screenshot for cheevo %u\n", cheevo->id); } } @@ -2044,7 +1710,7 @@ static int cheevos_expr_value(cheevos_expr_t* expr) if (expr->compare_count >= ARRAY_SIZE(values)) { - RARCH_ERR("[CHEEVOS]: too many values in the leaderboard expression: %u\n", expr->compare_count); + CHEEVOS_ERR("[CHEEVOS]: too many values in the leaderboard expression: %u\n", expr->compare_count); return 0; } @@ -2054,7 +1720,7 @@ static int cheevos_expr_value(cheevos_expr_t* expr) { if (current_value >= ARRAY_SIZE(values)) { - RARCH_ERR("[CHEEVOS]: too many values in the leaderboard expression: %u\n", current_value); + CHEEVOS_ERR("[CHEEVOS]: too many values in the leaderboard expression: %u\n", current_value); return 0; } @@ -2128,11 +1794,11 @@ static void cheevos_lboard_submit(void *task_data, void *user_data, if (!error) { - RARCH_ERR("[CHEEVOS]: error submitting leaderboard %u\n", lboard->id); + CHEEVOS_ERR("[CHEEVOS]: error submitting leaderboard %u\n", lboard->id); return; } - RARCH_LOG("[CHEEVOS]: submitted leaderboard %u.\n", lboard->id); + CHEEVOS_LOG("[CHEEVOS]: submitted leaderboard %u.\n", lboard->id); } static void cheevos_test_leaderboards(void) @@ -2151,10 +1817,8 @@ static void cheevos_test_leaderboards(void) if (value != lboard->last_value) { -#ifdef CHEEVOS_VERBOSE - RARCH_LOG("[CHEEVOS]: value lboard %s %u\n", + CHEEVOS_LOG("[CHEEVOS]: value lboard %s %u\n", lboard->title, value); -#endif lboard->last_value = value; } @@ -2165,7 +1829,7 @@ static void cheevos_test_leaderboards(void) /* failsafe for improper LBs */ if (value == 0) { - RARCH_LOG("[CHEEVOS]: error: lboard %s tried to submit 0\n", + CHEEVOS_LOG("[CHEEVOS]: error: lboard %s tried to submit 0\n", lboard->title); runloop_msg_queue_push("Leaderboard attempt cancelled!", 0, 2 * 60, false); @@ -2179,7 +1843,7 @@ static void cheevos_test_leaderboards(void) cheevos_make_lboard_url(lboard, url, sizeof(url)); task_push_http_transfer(url, true, NULL, cheevos_lboard_submit, lboard); - RARCH_LOG("[CHEEVOS]: submit lboard %s\n", lboard->title); + CHEEVOS_LOG("[CHEEVOS]: submit lboard %s\n", lboard->title); cheevos_format_value(value, lboard->format, formatted_value, sizeof(formatted_value)); @@ -2192,7 +1856,7 @@ static void cheevos_test_leaderboards(void) if (cheevos_test_lboard_condition(&lboard->cancel)) { - RARCH_LOG("[CHEEVOS]: cancel lboard %s\n", lboard->title); + CHEEVOS_LOG("[CHEEVOS]: cancel lboard %s\n", lboard->title); lboard->active = 0; runloop_msg_queue_push("Leaderboard attempt cancelled!", 0, 2 * 60, false); @@ -2204,7 +1868,7 @@ static void cheevos_test_leaderboards(void) { char msg[256]; - RARCH_LOG("[CHEEVOS]: start lboard %s\n", lboard->title); + CHEEVOS_LOG("[CHEEVOS]: start lboard %s\n", lboard->title); lboard->active = 1; lboard->last_value = -1; @@ -2317,10 +1981,10 @@ static int cheevos_deactivate__json_number(void *userdata, } if (found) - RARCH_LOG("[CHEEVOS]: deactivated unlocked cheevo %u (%s).\n", + CHEEVOS_LOG("[CHEEVOS]: deactivated unlocked cheevo %u (%s).\n", cheevo->id, cheevo->title); else - RARCH_ERR("[CHEEVOS]: unknown cheevo to deactivate: %u.\n", id); + CHEEVOS_ERR("[CHEEVOS]: unknown cheevo to deactivate: %u.\n", id); } return 0; @@ -2516,9 +2180,7 @@ bool cheevos_unload(void) if (running) { -#ifdef CHEEVOS_VERBOSE - RARCH_LOG("[CHEEVOS]: Asked the load thread to terminate\n"); -#endif + CHEEVOS_LOG("[CHEEVOS]: Asked the load thread to terminate\n"); task_queue_cancel_task(cheevos_locals.task); #ifdef HAVE_THREADS @@ -2568,7 +2230,7 @@ bool cheevos_toggle_hardcore_mode(void) if (settings->bools.rewind_enable) command_event(CMD_EVENT_REWIND_DEINIT, NULL); - RARCH_LOG("%s\n", msg); + CHEEVOS_LOG("%s\n", msg); runloop_msg_queue_push(msg, 0, 3 * 60, true); } else @@ -2612,7 +2274,7 @@ static void cheevos_patch_addresses(cheevoset_t* set) cheevos_var_patch_addr(&cond->source, cheevos_locals.console_id); #ifdef CHEEVOS_DUMP_ADDRS - RARCH_LOG("[CHEEVOS]: s-var %03d:%08X\n", + CHEEVOS_LOG("[CHEEVOS]: s-var %03d:%08X\n", cond->source.bank_id + 1, cond->source.value); #endif break; @@ -2628,7 +2290,7 @@ static void cheevos_patch_addresses(cheevoset_t* set) cheevos_var_patch_addr(&cond->target, cheevos_locals.console_id); #ifdef CHEEVOS_DUMP_ADDRS - RARCH_LOG("[CHEEVOS]: t-var %03d:%08X\n", + CHEEVOS_LOG("[CHEEVOS]: t-var %03d:%08X\n", cond->target.bank_id + 1, cond->target.value); #endif break; @@ -2665,7 +2327,7 @@ static void cheevos_patch_lb_conditions(cheevos_condition_t* condition) cheevos_var_patch_addr(&cond->source, cheevos_locals.console_id); #ifdef CHEEVOS_DUMP_ADDRS - RARCH_LOG("[CHEEVOS]: s-var %03d:%08X\n", + CHEEVOS_LOG("[CHEEVOS]: s-var %03d:%08X\n", cond->source.bank_id + 1, cond->source.value); #endif break; @@ -2679,7 +2341,7 @@ static void cheevos_patch_lb_conditions(cheevos_condition_t* condition) cheevos_var_patch_addr(&cond->target, cheevos_locals.console_id); #ifdef CHEEVOS_DUMP_ADDRS - RARCH_LOG("[CHEEVOS]: t-var %03d:%08X\n", + CHEEVOS_LOG("[CHEEVOS]: t-var %03d:%08X\n", cond->target.bank_id + 1, cond->target.value); #endif break; @@ -2708,7 +2370,7 @@ static void cheevos_patch_lb_expressions(cheevos_expr_t* expression) case CHEEVOS_VAR_TYPE_DELTA_MEM: cheevos_var_patch_addr(&term->var, cheevos_locals.console_id); #ifdef CHEEVOS_DUMP_ADDRS - RARCH_LOG("[CHEEVOS]: s-var %03d:%08X\n", + CHEEVOS_LOG("[CHEEVOS]: s-var %03d:%08X\n", term->var.bank_id + 1, term->var.value); #endif break; @@ -2927,16 +2589,16 @@ static int cheevos_iterate(coro_t *coro) cheevos_locals.meminfo[3].id = RETRO_MEMORY_RTC; core_get_memory(&cheevos_locals.meminfo[3]); - RARCH_LOG("[CHEEVOS]: system RAM: %p %u\n", + CHEEVOS_LOG("[CHEEVOS]: system RAM: %p %u\n", cheevos_locals.meminfo[0].data, cheevos_locals.meminfo[0].size); - RARCH_LOG("[CHEEVOS]: save RAM: %p %u\n", + CHEEVOS_LOG("[CHEEVOS]: save RAM: %p %u\n", cheevos_locals.meminfo[1].data, cheevos_locals.meminfo[1].size); - RARCH_LOG("[CHEEVOS]: video RAM: %p %u\n", + CHEEVOS_LOG("[CHEEVOS]: video RAM: %p %u\n", cheevos_locals.meminfo[2].data, cheevos_locals.meminfo[2].size); - RARCH_LOG("[CHEEVOS]: RTC: %p %u\n", + CHEEVOS_LOG("[CHEEVOS]: RTC: %p %u\n", cheevos_locals.meminfo[3].data, cheevos_locals.meminfo[3].size); @@ -3034,7 +2696,7 @@ static int cheevos_iterate(coro_t *coro) { if (finders[coro->i].ext_hashes[coro->j] == hash) { - RARCH_LOG("[CHEEVOS]: testing %s.\n", + CHEEVOS_LOG("[CHEEVOS]: testing %s.\n", finders[coro->i].name); /* @@ -3059,7 +2721,7 @@ static int cheevos_iterate(coro_t *coro) if (finders[coro->i].ext_hashes) continue; - RARCH_LOG("[CHEEVOS]: testing %s.\n", + CHEEVOS_LOG("[CHEEVOS]: testing %s.\n", finders[coro->i].name); /* @@ -3072,7 +2734,7 @@ static int cheevos_iterate(coro_t *coro) goto found; } - RARCH_LOG("[CHEEVOS]: this game doesn't feature achievements.\n"); + CHEEVOS_LOG("[CHEEVOS]: this game doesn't feature achievements.\n"); CORO_STOP(); found: @@ -3098,7 +2760,7 @@ found: if (!coro->json) { runloop_msg_queue_push("Error loading achievements.", 0, 5 * 60, false); - RARCH_ERR("[CHEEVOS]: error loading achievements.\n"); + CHEEVOS_ERR("[CHEEVOS]: error loading achievements.\n"); CORO_STOP(); } #endif @@ -3428,7 +3090,7 @@ found: { char gameid[16]; - RARCH_LOG( + CHEEVOS_LOG( "[CHEEVOS]: getting game id for hash %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", coro->hash[ 0], coro->hash[ 1], coro->hash[ 2], coro->hash[ 3], coro->hash[ 4], coro->hash[ 5], coro->hash[ 6], coro->hash[ 7], @@ -3461,14 +3123,14 @@ found: { if ((void*)coro->json) free((void*)coro->json); - RARCH_ERR("[CHEEVOS]: error getting game_id.\n"); + CHEEVOS_ERR("[CHEEVOS]: error getting game_id.\n"); CORO_RET(); } if ((void*)coro->json) free((void*)coro->json); - RARCH_LOG("[CHEEVOS]: got game id %s.\n", gameid); - coro->gameid = strtol(gameid, NULL, 10); + CHEEVOS_LOG("[CHEEVOS]: got game id %s.\n", gameid); + coro->gameid = (unsigned)strtol(gameid, NULL, 10); CORO_RET(); } @@ -3497,11 +3159,11 @@ found: if (!coro->json) { - RARCH_ERR("[CHEEVOS]: error getting achievements for game id %u.\n", coro->gameid); + CHEEVOS_ERR("[CHEEVOS]: error getting achievements for game id %u.\n", coro->gameid); CORO_STOP(); } - RARCH_LOG("[CHEEVOS]: got achievements for game id %u.\n", coro->gameid); + CHEEVOS_LOG("[CHEEVOS]: got achievements for game id %u.\n", coro->gameid); CORO_RET(); /************************************************************************** @@ -3554,7 +3216,7 @@ found: if (!badge_exists(coro->badge_fullpath)) { #ifdef CHEEVOS_LOG_BADGES - RARCH_LOG( + CHEEVOS_LOG( "[CHEEVOS]: downloading badge %s\n", coro->badge_fullpath); #endif @@ -3569,7 +3231,7 @@ found: { if (!filestream_write_file(coro->badge_fullpath, coro->json, coro->k)) - RARCH_ERR("[CHEEVOS]: error writing badge %s\n", coro->badge_fullpath); + CHEEVOS_ERR("[CHEEVOS]: error writing badge %s\n", coro->badge_fullpath); else free(coro->json); } @@ -3589,29 +3251,46 @@ found: { char urle_user[64]; - char urle_pwd[64]; + char urle_login[64]; const char *username = coro ? coro->settings->arrays.cheevos_username : NULL; - const char *password = coro ? coro->settings->arrays.cheevos_password : NULL; + const char *login; + bool via_token; - if (!username || !*username || !password || !*password) + if (coro) + { + if (string_is_empty(coro->settings->arrays.cheevos_password)) + { + via_token = true; + login = coro->settings->arrays.cheevos_token; + } + else + { + via_token = false; + login = coro->settings->arrays.cheevos_password; + } + } + else + login = NULL; + + if (string_is_empty(username) || string_is_empty(login)) { runloop_msg_queue_push( - "Missing Retro Achievements account information.", + "Missing RetroAchievements account information.", 0, 5 * 60, false); runloop_msg_queue_push( "Please fill in your account information in Settings.", 0, 5 * 60, false); - RARCH_ERR("[CHEEVOS]: username and/or password not informed.\n"); + CHEEVOS_ERR("[CHEEVOS]: login info not informed.\n"); CORO_STOP(); } cheevos_url_encode(username, urle_user, sizeof(urle_user)); - cheevos_url_encode(password, urle_pwd, sizeof(urle_pwd)); + cheevos_url_encode(login, urle_login, sizeof(urle_login)); snprintf( coro->url, sizeof(coro->url), - "http://retroachievements.org/dorequest.php?r=login&u=%s&p=%s", - urle_user, urle_pwd + "http://retroachievements.org/dorequest.php?r=login&u=%s&%c=%s", + urle_user, via_token ? 't' : 'p', urle_login ); coro->url[sizeof(coro->url) - 1] = 0; @@ -3626,32 +3305,67 @@ found: if (coro->json) { - int res = cheevos_get_value( + char error_response[64]; + char error_message[256]; + + cheevos_get_value( + coro->json, + CHEEVOS_JSON_KEY_ERROR, + error_response, + sizeof(error_response) + ); + + /* No error, continue with login */ + if (string_is_empty(error_response)) + { + int res = cheevos_get_value( coro->json, CHEEVOS_JSON_KEY_TOKEN, cheevos_locals.token, sizeof(cheevos_locals.token)); + if ((void*)coro->json) + free((void*)coro->json); + + if (!res) + { + if (coro->settings->bools.cheevos_verbose_enable) + { + char msg[256]; + snprintf(msg, sizeof(msg), + "RetroAchievements: Logged in as \"%s\".", + coro->settings->arrays.cheevos_username); + msg[sizeof(msg) - 1] = 0; + runloop_msg_queue_push(msg, 0, 3 * 60, false); + } + + /* Save token to config and clear pass on success */ + *coro->settings->arrays.cheevos_password = '\0'; + strncpy( + coro->settings->arrays.cheevos_token, + cheevos_locals.token, sizeof(cheevos_locals.token) + ); + CORO_RET(); + } + } + if ((void*)coro->json) free((void*)coro->json); - - if (!res) - { - if (coro->settings->bools.cheevos_verbose_enable) - { - char msg[256]; - snprintf(msg, sizeof(msg), - "RetroAchievements: logged in as \"%s\".", - coro->settings->arrays.cheevos_username); - msg[sizeof(msg) - 1] = 0; - runloop_msg_queue_push(msg, 0, 3 * 60, false); - } - CORO_RET(); - } + + /* Site returned error, display it */ + snprintf(error_message, sizeof(error_message), + "RetroAchievements: %s", + error_response); + error_message[sizeof(error_message) - 1] = 0; + runloop_msg_queue_push(error_message, 0, 5 * 60, false); + *coro->settings->arrays.cheevos_token = '\0'; + + CORO_STOP(); } - - runloop_msg_queue_push("Retro Achievements login error.", 0, 5 * 60, false); - RARCH_ERR("[CHEEVOS]: error getting user token.\n"); + + runloop_msg_queue_push("RetroAchievements: Error contacting server.", 0, 5 * 60, false); + CHEEVOS_ERR("[CHEEVOS]: error getting user token.\n"); + CORO_STOP(); /************************************************************************** @@ -3682,7 +3396,7 @@ found: for (coro->k = 0; coro->k < 5; coro->k++) { if (coro->k != 0) - RARCH_LOG("[CHEEVOS]: Retrying HTTP request: %u of 5\n", coro->k + 1); + CHEEVOS_LOG("[CHEEVOS]: Retrying HTTP request: %u of 5\n", coro->k + 1); coro->json = NULL; coro->conn = net_http_connection_new( @@ -3733,7 +3447,7 @@ found: coro->json[length] = 0; } - coro->k = length; + coro->k = (unsigned)length; net_http_delete(coro->http); net_http_connection_free(coro->conn); CORO_RET(); @@ -3744,7 +3458,7 @@ found: net_http_connection_free(coro->conn); } - RARCH_LOG("[CHEEVOS]: Couldn't connect to server after 5 tries\n"); + CHEEVOS_LOG("[CHEEVOS]: Couldn't connect to server after 5 tries\n"); CORO_RET(); /************************************************************************** @@ -3776,15 +3490,15 @@ found: if (coro->json) { if (!cheevos_deactivate_unlocks(coro->json, CHEEVOS_ACTIVE_SOFTCORE)) - RARCH_LOG("[CHEEVOS]: deactivated unlocked achievements in softcore mode.\n"); + CHEEVOS_LOG("[CHEEVOS]: deactivated unlocked achievements in softcore mode.\n"); else - RARCH_ERR("[CHEEVOS]: error deactivating unlocked achievements in softcore mode.\n"); + CHEEVOS_ERR("[CHEEVOS]: error deactivating unlocked achievements in softcore mode.\n"); if ((void*)coro->json) free((void*)coro->json); } else - RARCH_ERR("[CHEEVOS]: error retrieving list of unlocked achievements in softcore mode.\n"); + CHEEVOS_ERR("[CHEEVOS]: error retrieving list of unlocked achievements in softcore mode.\n"); /* Deactivate achievements in hardcore mode. */ snprintf( @@ -3805,15 +3519,15 @@ found: if (coro->json) { if (!cheevos_deactivate_unlocks(coro->json, CHEEVOS_ACTIVE_HARDCORE)) - RARCH_LOG("[CHEEVOS]: deactivated unlocked achievements in hardcore mode.\n"); + CHEEVOS_LOG("[CHEEVOS]: deactivated unlocked achievements in hardcore mode.\n"); else - RARCH_ERR("[CHEEVOS]: error deactivating unlocked achievements in hardcore mode.\n"); + CHEEVOS_ERR("[CHEEVOS]: error deactivating unlocked achievements in hardcore mode.\n"); if ((void*)coro->json) free((void*)coro->json); } else - RARCH_ERR("[CHEEVOS]: error retrieving list of unlocked achievements in hardcore mode.\n"); + CHEEVOS_ERR("[CHEEVOS]: error retrieving list of unlocked achievements in hardcore mode.\n"); #endif CORO_RET(); @@ -3842,14 +3556,14 @@ found: if (coro->json) { - RARCH_LOG("[CHEEVOS]: posted playing activity.\n"); + CHEEVOS_LOG("[CHEEVOS]: posted playing activity.\n"); if ((void*)coro->json) free((void*)coro->json); } else - RARCH_ERR("[CHEEVOS]: error posting playing activity.\n"); + CHEEVOS_ERR("[CHEEVOS]: error posting playing activity.\n"); - RARCH_LOG("[CHEEVOS]: posted playing activity.\n"); + CHEEVOS_LOG("[CHEEVOS]: posted playing activity.\n"); CORO_RET(); CORO_LEAVE(); @@ -3870,16 +3584,14 @@ static void cheevos_task_handler(retro_task_t *task) cheevos_locals.task = NULL; CHEEVOS_UNLOCK(cheevos_locals.task_lock); -#ifdef CHEEVOS_VERBOSE if (task_get_cancelled(task)) { - RARCH_LOG("[CHEEVOS]: Load task cancelled\n"); + CHEEVOS_LOG("[CHEEVOS]: Load task cancelled\n"); } else { - RARCH_LOG("[CHEEVOS]: Load task finished\n"); + CHEEVOS_LOG("[CHEEVOS]: Load task finished\n"); } -#endif if (coro->data) free(coro->data); diff --git a/cheevos/cheevos.h b/cheevos/cheevos.h index dd070ef441..a4f18c7c7f 100644 --- a/cheevos/cheevos.h +++ b/cheevos/cheevos.h @@ -38,6 +38,20 @@ End of setup #define CHEEVOS_TAG "[CHEEVOS]: " +#ifdef CHEEVOS_VERBOSE + +#define CHEEVOS_LOG RARCH_LOG +#define CHEEVOS_ERR RARCH_ERR + +#else + +void cheevos_log(const char *fmt, ...); + +#define CHEEVOS_LOG cheevos_log +#define CHEEVOS_ERR cheevos_log + +#endif + typedef struct cheevos_ctx_desc { unsigned idx; diff --git a/cheevos/cond.c b/cheevos/cond.c index 3566f8e6bf..9f665900c9 100644 --- a/cheevos/cond.c +++ b/cheevos/cond.c @@ -65,7 +65,7 @@ static cheevos_cond_op_t cheevos_cond_parse_operator(const char** memaddr) } else { - RARCH_ERR(CHEEVOS_TAG "unknown operator %c\n.", *str); + CHEEVOS_ERR(CHEEVOS_TAG "unknown operator %c\n.", *str); op = CHEEVOS_COND_OP_EQUALS; } @@ -168,9 +168,6 @@ void cheevos_cond_parse_in_set(cheevos_cond_t* cond, const char* memaddr, unsign if (index == which) { cheevos_cond_parse(cond, &memaddr); -#ifdef CHEEVOS_VERBOSE - /*cheevos_log_cond(cond);*/ -#endif cond++; } else diff --git a/cheevos/var.c b/cheevos/var.c index 41884a72b6..5f13c2b8b6 100644 --- a/cheevos/var.c +++ b/cheevos/var.c @@ -24,17 +24,6 @@ #include "../core.h" #include "../verbosity.h" -static void STUB_LOG(const char *fmt, ...) -{ - (void)fmt; -} - -#ifdef CHEEVOS_VERBOSE -#define CHEEVOS_LOG RARCH_LOG -#else -#define CHEEVOS_LOG STUB_LOG -#endif - /***************************************************************************** Parsing *****************************************************************************/ @@ -191,12 +180,6 @@ void cheevos_var_patch_addr(cheevos_var_t* var, cheevos_console_t console) var->value -= 0x2000; } } - else if (console == CHEEVOS_CONSOLE_NEOGEO_POCKET) - { - if (var->value >= 0x4000 && var->value <= 0x7fff) - CHEEVOS_LOG(CHEEVOS_TAG "NGP memory address %X adjusted to %X\n", var->value, var->value - 0x004000); - var->value -= 0x4000; - } if (system->mmaps.num_descriptors != 0) { @@ -333,7 +316,7 @@ uint8_t* cheevos_var_get_memory(const cheevos_var_t* var) meminfo.id = RETRO_MEMORY_RTC; break; default: - RARCH_ERR(CHEEVOS_TAG "invalid bank id: %s\n", var->bank_id); + CHEEVOS_ERR(CHEEVOS_TAG "invalid bank id: %s\n", var->bank_id); break; } diff --git a/command.c b/command.c index ab871166c0..02223414ef 100644 --- a/command.c +++ b/command.c @@ -169,6 +169,7 @@ static const struct cmd_map map[] = { { "DISK_NEXT", RARCH_DISK_NEXT }, { "DISK_PREV", RARCH_DISK_PREV }, { "GRAB_MOUSE_TOGGLE", RARCH_GRAB_MOUSE_TOGGLE }, + { "UI_COMPANION_TOGGLE", RARCH_UI_COMPANION_TOGGLE }, { "GAME_FOCUS_TOGGLE", RARCH_GAME_FOCUS_TOGGLE }, { "MENU_TOGGLE", RARCH_MENU_TOGGLE }, { "MENU_UP", RETRO_DEVICE_ID_JOYPAD_UP }, @@ -1015,7 +1016,7 @@ static void command_event_init_controllers(void) /* Ideally these checks shouldn't be required but if we always * call core_set_controller_port_device input won't work on * cores that don't set port information properly */ - if (info && info->ports.size != 0 && i < info->ports.size) + if (info && info->ports.size != 0) set_controller = true; break; default: @@ -1029,7 +1030,7 @@ static void command_event_init_controllers(void) break; } - if (set_controller) + if (set_controller && i < info->ports.size) { pad.device = device; pad.port = i; @@ -1705,17 +1706,11 @@ void command_playlist_update_write( const char *core_path, const char *core_display_name, const char *crc32, - const char *db_name) + const char *db_name) { playlist_t *plist = (playlist_t*)data; - playlist_t *playlist = NULL; + playlist_t *playlist = plist ? plist : playlist_get_cached(); - if (plist) - playlist = plist; -#ifdef HAVE_MENU - else - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &playlist); -#endif if (!playlist) return; @@ -1793,10 +1788,11 @@ bool command_event(enum event_command cmd, void *data) return false; #endif - libretro_get_system_info( + if (!libretro_get_system_info( core_path, system, - &system_info->load_no_content); + &system_info->load_no_content)) + return false; info_find.path = core_path; if (!core_info_load(&info_find)) @@ -1809,11 +1805,17 @@ bool command_event(enum event_command cmd, void *data) } break; case CMD_EVENT_LOAD_CORE: - command_event(CMD_EVENT_LOAD_CORE_PERSIST, NULL); + { + bool success = command_event(CMD_EVENT_LOAD_CORE_PERSIST, NULL); + #ifndef HAVE_DYNAMIC command_event(CMD_EVENT_QUIT, NULL); +#else + if (!success) + return false; #endif break; + } case CMD_EVENT_LOAD_STATE: /* Immutable - disallow savestate load when * we absolutely cannot change game state. */ @@ -1931,7 +1933,7 @@ bool command_event(enum event_command cmd, void *data) cheevos_toggle_hardcore_mode(); #endif break; - /* this fallthrough is on purpose, it should do + /* this fallthrough is on purpose, it should do a CMD_EVENT_REINIT too */ case CMD_EVENT_REINIT_FROM_TOGGLE: retroarch_unset_forced_fullscreen(); @@ -2016,7 +2018,7 @@ TODO: Add a setting for these tweaks */ case CMD_EVENT_AUTOSAVE_INIT: command_event(CMD_EVENT_AUTOSAVE_DEINIT, NULL); #ifdef HAVE_THREADS - { + { #ifdef HAVE_NETWORKING /* Only enable state manager if netplay is not underway TODO: Add a setting for these tweaks */ @@ -2030,7 +2032,7 @@ TODO: Add a setting for these tweaks */ else runloop_unset(RUNLOOP_ACTION_AUTOSAVE); } - } + } #endif break; case CMD_EVENT_AUTOSAVE_STATE: @@ -2202,11 +2204,22 @@ TODO: Add a setting for these tweaks */ break; case CMD_EVENT_CORE_INFO_INIT: { + char ext_name[255]; settings_t *settings = config_get_ptr(); + + ext_name[0] = '\0'; + command_event(CMD_EVENT_CORE_INFO_DEINIT, NULL); + if (!frontend_driver_get_core_extension(ext_name, sizeof(ext_name))) + return false; + if (!string_is_empty(settings->paths.directory_libretro)) - core_info_init_list(); + core_info_init_list(settings->paths.path_libretro_info, + settings->paths.directory_libretro, + ext_name, + settings->bools.show_hidden_files + ); } break; case CMD_EVENT_CORE_DEINIT: @@ -2301,7 +2314,7 @@ TODO: Add a setting for these tweaks */ case CMD_EVENT_RESUME: rarch_menu_running_finished(); if (ui_companion_is_on_foreground()) - ui_companion_driver_toggle(); + ui_companion_driver_toggle(false); break; case CMD_EVENT_ADD_TO_FAVORITES: { @@ -2350,7 +2363,7 @@ TODO: Add a setting for these tweaks */ runloop_msg_queue_push(msg_hash_to_str(MSG_RESET_CORE_ASSOCIATION), 1, 180, true); break; - } + } case CMD_EVENT_RESTART_RETROARCH: if (!frontend_driver_set_fork(FRONTEND_FORK_RESTART)) return false; @@ -2572,7 +2585,7 @@ TODO: Add a setting for these tweaks */ case CMD_EVENT_FULLSCREEN_TOGGLE: { settings_t *settings = config_get_ptr(); - bool new_fullscreen_state = !settings->bools.video_fullscreen + bool new_fullscreen_state = !settings->bools.video_fullscreen && !retroarch_is_forced_fullscreen(); if (!video_driver_has_windowed()) return false; @@ -2731,6 +2744,11 @@ TODO: Add a setting for these tweaks */ video_driver_show_mouse(); } break; + case CMD_EVENT_UI_COMPANION_TOGGLE: + { + ui_companion_driver_toggle(true); + break; + } case CMD_EVENT_GAME_FOCUS_TOGGLE: { static bool game_focus_state = false; diff --git a/command.h b/command.h index 9cc3e3ce17..139db92890 100644 --- a/command.h +++ b/command.h @@ -139,7 +139,7 @@ enum event_command /* Add a playlist entry to favorites. */ CMD_EVENT_ADD_TO_FAVORITES, /* Reset playlist entry associated core to DETECT */ - CMD_EVENT_RESET_CORE_ASSOCIATION, + CMD_EVENT_RESET_CORE_ASSOCIATION, /* Toggles pause. */ CMD_EVENT_PAUSE_TOGGLE, /* Pauses RetroArch. */ @@ -218,6 +218,8 @@ enum event_command CMD_EVENT_GRAB_MOUSE_TOGGLE, /* Toggles game focus. */ CMD_EVENT_GAME_FOCUS_TOGGLE, + /* Toggles desktop menu. */ + CMD_EVENT_UI_COMPANION_TOGGLE, /* Toggles fullscreen mode. */ CMD_EVENT_FULLSCREEN_TOGGLE, CMD_EVENT_PERFCNT_REPORT_FRONTEND_LOG, @@ -271,7 +273,7 @@ void command_playlist_push_write( void command_playlist_update_write( void *data, size_t idx, - const char *path, + const char *path, const char *label, const char *core_path, const char *core_display_name, diff --git a/config.def.h b/config.def.h index 829ea18345..155fa181b6 100644 --- a/config.def.h +++ b/config.def.h @@ -67,6 +67,10 @@ static bool bundle_assets_extract_enable = false; static bool materialui_icons_enable = true; #endif +static const bool crt_switch_resolution = false; +static const int crt_switch_resolution_super = 2560; + + static const bool def_history_list_enable = true; static const bool def_playlist_entry_remove = true; static const bool def_playlist_entry_rename = true; @@ -293,6 +297,7 @@ static bool content_show_history = true; #ifdef HAVE_LIBRETRODB static bool content_show_add = true; #endif +static bool content_show_playlists = true; #ifdef HAVE_XMB static unsigned xmb_scale_factor = 100; @@ -300,6 +305,7 @@ static unsigned xmb_alpha_factor = 75; static unsigned menu_font_color_red = 255; static unsigned menu_font_color_green = 255; static unsigned menu_font_color_blue = 255; +static unsigned xmb_menu_layout = 0; static unsigned xmb_icon_theme = XMB_ICON_THEME_MONOCHROME; static unsigned xmb_theme = XMB_THEME_ELECTRIC_BLUE; #if defined(HAVE_LAKKA) || defined(__arm__) || defined(__PPC64__) || defined(__ppc64__) || defined(__powerpc64__) || defined(__powerpc__) || defined(__ppc__) || defined(__POWERPC__) @@ -589,6 +595,12 @@ static const float slowmotion_ratio = 3.0; /* Maximum fast forward ratio. */ static const float fastforward_ratio = 0.0; +/* Run core logic one or more frames ahead then load the state back to reduce perceived input lag. */ +static const unsigned run_ahead_frames = 1; + +/* When using the Run Ahead feature, use a secondary instance of the core. */ +static const bool run_ahead_secondary_instance = true; + /* Enable stdin/network command interface. */ static const bool network_cmd_enable = false; static const uint16_t network_cmd_port = 55355; @@ -646,6 +658,10 @@ static const unsigned input_bind_timeout = 5; static const unsigned menu_thumbnails_default = 3; +static const unsigned menu_left_thumbnails_default = 0; + +static const bool xmb_vertical_thumbnails = false; + #ifdef IOS static const bool ui_companion_start_on_boot = false; #else @@ -654,6 +670,12 @@ static const bool ui_companion_start_on_boot = true; static const bool ui_companion_enable = false; +/* Currently only used to show the WIMP UI on startup */ +static const bool ui_companion_toggle = false; + +/* Only init the WIMP UI for this session if this is enabled */ +static const bool desktop_menu_enable = true; + #if defined(__QNX__) || defined(_XBOX1) || defined(_XBOX360) || defined(__CELLOS_LV2__) || (defined(__MACH__) && defined(IOS)) || defined(ANDROID) || defined(WIIU) || defined(HAVE_NEON) || defined(GEKKO) || defined(__ARM_NEON__) static enum resampler_quality audio_resampler_quality_level = RESAMPLER_QUALITY_LOWER; #elif defined(PSP) || defined(_3DS) || defined(VITA) diff --git a/config.def.keybinds.h b/config.def.keybinds.h index 298f9971a6..d941a210cf 100644 --- a/config.def.keybinds.h +++ b/config.def.keybinds.h @@ -97,6 +97,7 @@ static const struct retro_keybind retro_keybinds_1[] = { { true, RARCH_DISK_PREV, MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_GRAB_MOUSE_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_GAME_FOCUS_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE }, + { true, RARCH_UI_COMPANION_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_MENU_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, RETROK_SPACE, NO_BTN, NO_BTN, 0, AXIS_NONE }, #else { true, RETRO_DEVICE_ID_JOYPAD_B, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, RETROK_z, NO_BTN, NO_BTN, 0, AXIS_NONE }, @@ -172,6 +173,7 @@ static const struct retro_keybind retro_keybinds_1[] = { { true, RARCH_DISK_PREV, MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_GRAB_MOUSE_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, RETROK_F11, NO_BTN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_GAME_FOCUS_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, RETROK_SCROLLOCK, NO_BTN, NO_BTN, 0, AXIS_NONE }, + { true, RARCH_UI_COMPANION_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE, RETROK_F5, NO_BTN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_MENU_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, RETROK_F1, NO_BTN, NO_BTN, 0, AXIS_NONE }, #endif }; diff --git a/configuration.c b/configuration.c index 020302be65..4433f53ad6 100644 --- a/configuration.c +++ b/configuration.c @@ -1033,6 +1033,7 @@ static struct config_array_setting *populate_settings_array(settings_t *settings #ifdef HAVE_CHEEVOS SETTING_ARRAY("cheevos_username", settings->arrays.cheevos_username, false, NULL, true); SETTING_ARRAY("cheevos_password", settings->arrays.cheevos_password, false, NULL, true); + SETTING_ARRAY("cheevos_token", settings->arrays.cheevos_token, false, NULL, true); #endif SETTING_ARRAY("video_context_driver", settings->arrays.video_context_driver, false, NULL, true); SETTING_ARRAY("audio_driver", settings->arrays.audio_driver, false, NULL, true); @@ -1179,6 +1180,8 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("automatically_add_content_to_playlist", &settings->bools.automatically_add_content_to_playlist, true, automatically_add_content_to_playlist, false); SETTING_BOOL("ui_companion_start_on_boot", &settings->bools.ui_companion_start_on_boot, true, ui_companion_start_on_boot, false); SETTING_BOOL("ui_companion_enable", &settings->bools.ui_companion_enable, true, ui_companion_enable, false); + SETTING_BOOL("ui_companion_toggle", &settings->bools.ui_companion_toggle, false, ui_companion_toggle, false); + SETTING_BOOL("desktop_menu_enable", &settings->bools.desktop_menu_enable, true, desktop_menu_enable, false); SETTING_BOOL("video_gpu_record", &settings->bools.video_gpu_record, true, gpu_record, false); SETTING_BOOL("input_remap_binds_enable", &settings->bools.input_remap_binds_enable, true, true, false); SETTING_BOOL("all_users_control_menu", &settings->bools.input_all_users_control_menu, true, all_users_control_menu, false); @@ -1220,6 +1223,8 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("ui_menubar_enable", &settings->bools.ui_menubar_enable, true, true, false); SETTING_BOOL("suspend_screensaver_enable", &settings->bools.ui_suspend_screensaver_enable, true, true, false); SETTING_BOOL("rewind_enable", &settings->bools.rewind_enable, true, rewind_enable, false); + SETTING_BOOL("run_ahead_enabled", &settings->bools.run_ahead_enabled, true, false, false); + SETTING_BOOL("run_ahead_secondary_instance", &settings->bools.run_ahead_secondary_instance, true, false, false); SETTING_BOOL("audio_sync", &settings->bools.audio_sync, true, audio_sync, false); SETTING_BOOL("video_shader_enable", &settings->bools.video_shader_enable, true, shader_enable, false); SETTING_BOOL("video_shader_watch_files", &settings->bools.video_shader_watch_files, true, video_shader_watch_files, false); @@ -1242,6 +1247,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("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); @@ -1249,6 +1255,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("keyboard_gamepad_enable", &settings->bools.input_keyboard_gamepad_enable, true, true, false); SETTING_BOOL("core_set_supports_no_game_enable", &settings->bools.set_supports_no_game_enable, true, true, false); SETTING_BOOL("audio_enable", &settings->bools.audio_enable, true, audio_enable, false); + SETTING_BOOL("audio_enable_menu", &settings->bools.audio_enable_menu, true, false, false); SETTING_BOOL("audio_mute_enable", audio_get_bool_ptr(AUDIO_ACTION_MUTE_ENABLE), true, false, false); SETTING_BOOL("audio_mixer_mute_enable", audio_get_bool_ptr(AUDIO_ACTION_MIXER_MUTE_ENABLE), true, false, false); SETTING_BOOL("location_allow", &settings->bools.location_allow, true, false, false); @@ -1309,10 +1316,14 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, #ifdef HAVE_LIBRETRODB SETTING_BOOL("content_show_add", &settings->bools.menu_content_show_add, true, content_show_add, false); #endif + SETTING_BOOL("content_show_playlists", &settings->bools.menu_content_show_playlists, true, content_show_playlists, false); SETTING_BOOL("menu_show_load_core", &settings->bools.menu_show_load_core, true, menu_show_load_core, false); SETTING_BOOL("menu_show_load_content", &settings->bools.menu_show_load_content, true, menu_show_load_content, false); SETTING_BOOL("menu_show_information", &settings->bools.menu_show_information, true, menu_show_information, false); SETTING_BOOL("menu_show_configurations", &settings->bools.menu_show_configurations, true, menu_show_configurations, false); + SETTING_BOOL("menu_show_latency", &settings->bools.menu_show_latency, true, true, false); + SETTING_BOOL("menu_show_rewind", &settings->bools.menu_show_rewind, true, true, false); + SETTING_BOOL("menu_show_overlays", &settings->bools.menu_show_overlays, true, true, false); SETTING_BOOL("menu_show_help", &settings->bools.menu_show_help, true, menu_show_help, false); SETTING_BOOL("menu_show_quit_retroarch", &settings->bools.menu_show_quit_retroarch, true, menu_show_quit_retroarch, false); SETTING_BOOL("menu_show_reboot", &settings->bools.menu_show_reboot, true, menu_show_reboot, false); @@ -1327,8 +1338,14 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, #ifdef HAVE_MATERIALUI SETTING_BOOL("materialui_icons_enable", &settings->bools.menu_materialui_icons_enable, true, materialui_icons_enable, false); #endif +#ifdef HAVE_RGUI + SETTING_BOOL("rgui_background_filler_thickness_enable", &settings->bools.menu_rgui_background_filler_thickness_enable, true, true, false); + SETTING_BOOL("rgui_border_filler_thickness_enable", &settings->bools.menu_rgui_border_filler_thickness_enable, true, true, false); + SETTING_BOOL("rgui_border_filler_enable", &settings->bools.menu_rgui_border_filler_enable, true, true, false); +#endif #ifdef HAVE_XMB SETTING_BOOL("xmb_shadows_enable", &settings->bools.menu_xmb_shadows_enable, true, xmb_shadows_enable, false); + SETTING_BOOL("xmb_vertical_thumbnails", &settings->bools.menu_xmb_vertical_thumbnails, true, xmb_vertical_thumbnails, false); #endif #endif #ifdef HAVE_CHEEVOS @@ -1355,9 +1372,6 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, #ifdef HAVE_NETWORKGAMEPAD SETTING_BOOL("network_remote_enable", &settings->bools.network_remote_enable, false, false /* TODO */, false); #endif -#ifdef HAVE_KEYMAPPER - SETTING_BOOL("keymapper_enable", &settings->bools.keymapper_enable, true, true /* TODO */, false); -#endif #ifdef HAVE_NETWORKING SETTING_BOOL("netplay_nat_traversal", &settings->bools.netplay_nat_traversal, true, true, false); #endif @@ -1462,9 +1476,6 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, #ifdef HAVE_NETWORKGAMEPAD SETTING_UINT("network_remote_base_port", &settings->uints.network_remote_base_port, true, network_remote_base_port, false); #endif -#ifdef HAVE_KEYMAPPER - SETTING_UINT("keymapper_port", &settings->uints.keymapper_port, true, 0, false); -#endif #ifdef GEKKO SETTING_UINT("video_viwidth", &settings->uints.video_viwidth, true, video_viwidth, false); #endif @@ -1472,8 +1483,10 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("dpi_override_value", &settings->uints.menu_dpi_override_value, true, menu_dpi_override_value, false); SETTING_UINT("menu_thumbnails", &settings->uints.menu_thumbnails, true, menu_thumbnails_default, false); #ifdef HAVE_XMB + SETTING_UINT("menu_left_thumbnails", &settings->uints.menu_left_thumbnails, true, menu_left_thumbnails_default, false); SETTING_UINT("xmb_alpha_factor", &settings->uints.menu_xmb_alpha_factor, true, xmb_alpha_factor, false); SETTING_UINT("xmb_scale_factor", &settings->uints.menu_xmb_scale_factor, true, xmb_scale_factor, false); + SETTING_UINT("xmb_layout", &settings->uints.menu_xmb_layout, true, xmb_menu_layout, false); SETTING_UINT("xmb_theme", &settings->uints.menu_xmb_theme, true, xmb_icon_theme, false); SETTING_UINT("xmb_menu_color_theme", &settings->uints.menu_xmb_color_theme, true, xmb_theme, false); SETTING_UINT("menu_font_color_red", &settings->uints.menu_font_color_red, true, menu_font_color_red, false); @@ -1485,6 +1498,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, #endif SETTING_UINT("audio_out_rate", &settings->uints.audio_out_rate, true, out_rate, false); SETTING_UINT("custom_viewport_width", &settings->video_viewport_custom.width, false, 0 /* TODO */, false); + SETTING_UINT("crt_switch_resolution_super", &settings->uints.crt_switch_resolution_super, true, crt_switch_resolution_super, false); SETTING_UINT("custom_viewport_height", &settings->video_viewport_custom.height, false, 0 /* TODO */, false); SETTING_UINT("custom_viewport_x", (unsigned*)&settings->video_viewport_custom.x, false, 0 /* TODO */, false); SETTING_UINT("custom_viewport_y", (unsigned*)&settings->video_viewport_custom.y, false, 0 /* TODO */, false); @@ -1513,6 +1527,8 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("video_msg_bgcolor_green", &settings->uints.video_msg_bgcolor_green, true, message_bgcolor_green, false); SETTING_UINT("video_msg_bgcolor_blue", &settings->uints.video_msg_bgcolor_blue, true, message_bgcolor_blue, false); + SETTING_UINT("run_ahead_frames", &settings->uints.run_ahead_frames, true, 1, false); + *size = count; return tmp; @@ -1712,6 +1728,7 @@ static void config_set_defaults(void) #ifdef HAVE_CHEEVOS *settings->arrays.cheevos_username = '\0'; *settings->arrays.cheevos_password = '\0'; + *settings->arrays.cheevos_token = '\0'; #endif input_config_reset(); @@ -2926,7 +2943,7 @@ bool config_load_override(void) config_file_t *new_conf = NULL; bool should_append = false; rarch_system_info_t *system = runloop_get_system_info(); - const char *core_name = system ? + const char *core_name = system ? system->info.library_name : NULL; const char *game_name = path_basename(path_get(RARCH_PATH_BASENAME)); @@ -3014,7 +3031,7 @@ bool config_load_override(void) if (!should_append) goto error; - /* Re-load the configuration with any overrides + /* Re-load the configuration with any overrides * that might have been found */ buf[0] = '\0'; @@ -3099,7 +3116,7 @@ bool config_unload_override(void) bool config_load_remap(void) { size_t path_size = PATH_MAX_LENGTH * sizeof(char); - char *remap_directory = NULL; + char *remap_directory = NULL; char *core_path = NULL; char *game_path = NULL; config_file_t *new_conf = NULL; @@ -3119,12 +3136,12 @@ bool config_load_remap(void) /* path to the directory containing retroarch.cfg (prefix) */ remap_directory = (char*) malloc(PATH_MAX_LENGTH * sizeof(char)); - /* final path for core-specific configuration (prefix+suffix) */ + /* final path for core-specific configuration (prefix+suffix) */ core_path = (char*) malloc(PATH_MAX_LENGTH * sizeof(char)); /* final path for game-specific configuration (prefix+suffix) */ game_path = (char*) - malloc(PATH_MAX_LENGTH * sizeof(char)); + malloc(PATH_MAX_LENGTH * sizeof(char)); remap_directory[0] = core_path[0] = game_path[0] = '\0'; strlcpy(remap_directory, @@ -3226,7 +3243,7 @@ bool config_load_shader_preset(void) char *parent_path = NULL; settings_t *settings = config_get_ptr(); rarch_system_info_t *system = runloop_get_system_info(); - const char *core_name = system + const char *core_name = system ? system->info.library_name : NULL; const char *game_name = path_basename(path_get(RARCH_PATH_BASENAME)); @@ -3511,14 +3528,14 @@ static void save_keybind_mbutton(config_file_t *conf, const char *base, const struct retro_keybind *bind, bool save_empty) { - char key[64]; + char key[64]; - key[0] = '\0'; + key[0] = '\0'; - fill_pathname_join_delim_concat(key, prefix, - base, '_', "_mbtn", sizeof(key)); + fill_pathname_join_delim_concat(key, prefix, + base, '_', "_mbtn", sizeof(key)); - switch ( bind->mbutton ) + switch ( bind->mbutton ) { case RETRO_DEVICE_ID_MOUSE_LEFT: config_set_uint64(conf, key, 1); @@ -3764,8 +3781,7 @@ bool config_save_autoconf_profile(const char *path, unsigned user) error: free(buf); free(autoconf_file); - if (path_new) - free(path_new); + free(path_new); return false; } @@ -4177,28 +4193,28 @@ bool config_save_overrides(int override_type) char cfg[64]; cfg[0] = '\0'; - if (settings->uints.input_device[i] + if (settings->uints.input_device[i] != overrides->uints.input_device[i]) { snprintf(cfg, sizeof(cfg), "input_device_p%u", i + 1); config_set_int(conf, cfg, overrides->uints.input_device[i]); } - if (settings->uints.input_joypad_map[i] + if (settings->uints.input_joypad_map[i] != overrides->uints.input_joypad_map[i]) { snprintf(cfg, sizeof(cfg), "input_player%u_joypad_index", i + 1); config_set_int(conf, cfg, overrides->uints.input_joypad_map[i]); } - if (settings->uints.input_libretro_device[i] + if (settings->uints.input_libretro_device[i] != overrides->uints.input_libretro_device[i]) { snprintf(cfg, sizeof(cfg), "input_libretro_device_p%u", i + 1); config_set_int(conf, cfg, overrides->uints.input_libretro_device[i]); } - if (settings->uints.input_analog_dpad_mode[i] + if (settings->uints.input_analog_dpad_mode[i] != overrides->uints.input_analog_dpad_mode[i]) { snprintf(cfg, sizeof(cfg), "input_player%u_analog_dpad_mode", i + 1); diff --git a/configuration.h b/configuration.h index 2f3e01eeb1..64cf46e2d6 100644 --- a/configuration.h +++ b/configuration.h @@ -95,9 +95,11 @@ typedef struct settings bool video_statistics_show; bool video_framecount_show; bool video_msg_bgcolor_enable; + bool crt_switch_resolution; /* Audio */ bool audio_enable; + bool audio_enable_menu; bool audio_sync; bool audio_rate_control; bool audio_wasapi_exclusive_mode; @@ -146,8 +148,15 @@ typedef struct settings bool menu_show_help; bool menu_show_quit_retroarch; bool menu_show_reboot; + bool menu_show_latency; + bool menu_show_rewind; + bool menu_show_overlays; bool menu_materialui_icons_enable; + bool menu_rgui_background_filler_thickness_enable; + bool menu_rgui_border_filler_thickness_enable; + bool menu_rgui_border_filler_enable; bool menu_xmb_shadows_enable; + bool menu_xmb_vertical_thumbnails; bool menu_content_show_settings; bool menu_content_show_favorites; bool menu_content_show_images; @@ -156,6 +165,7 @@ typedef struct settings bool menu_content_show_netplay; bool menu_content_show_history; bool menu_content_show_add; + bool menu_content_show_playlists; bool menu_unified_controls; bool quick_menu_show_take_screenshot; bool quick_menu_show_save_load_state; @@ -188,6 +198,8 @@ typedef struct settings bool ui_suspend_screensaver_enable; bool ui_companion_start_on_boot; bool ui_companion_enable; + bool ui_companion_toggle; + bool desktop_menu_enable; /* Cheevos */ bool cheevos_enable; @@ -223,6 +235,8 @@ typedef struct settings bool playlist_entry_remove; bool playlist_entry_rename; bool rewind_enable; + bool run_ahead_enabled; + bool run_ahead_secondary_instance; bool pause_nonactive; bool block_sram_overwrite; bool savestate_auto_index; @@ -333,6 +347,7 @@ typedef struct settings unsigned video_window_x; unsigned video_window_y; unsigned video_window_opacity; + unsigned crt_switch_resolution_super; unsigned video_monitor_index; unsigned video_fullscreen_x; unsigned video_fullscreen_y; @@ -348,10 +363,12 @@ typedef struct settings unsigned video_msg_bgcolor_blue; unsigned menu_thumbnails; + unsigned menu_left_thumbnails; unsigned menu_dpi_override_value; unsigned menu_entry_normal_color; unsigned menu_entry_hover_color; unsigned menu_title_color; + unsigned menu_xmb_layout; unsigned menu_xmb_shader_pipeline; unsigned menu_xmb_scale_factor; unsigned menu_xmb_alpha_factor; @@ -375,11 +392,13 @@ typedef struct settings unsigned input_libretro_device[MAX_USERS]; unsigned input_analog_dpad_mode[MAX_USERS]; - unsigned input_keymapper_ids[RARCH_CUSTOM_BIND_LIST_END]; + unsigned input_keymapper_ids[MAX_USERS][RARCH_CUSTOM_BIND_LIST_END]; unsigned input_remap_ids[MAX_USERS][RARCH_CUSTOM_BIND_LIST_END]; unsigned led_map[MAX_LEDS]; + + unsigned run_ahead_frames; } uints; struct @@ -395,6 +414,7 @@ typedef struct settings char menu_driver[32]; char cheevos_username[32]; char cheevos_password[32]; + char cheevos_token[32]; char video_context_driver[32]; char audio_driver[32]; char audio_resampler[32]; diff --git a/content.h b/content.h index ad4211c5a0..5e25e47c64 100644 --- a/content.h +++ b/content.h @@ -92,17 +92,16 @@ void content_clear_subsystem(void); void content_set_subsystem(unsigned subsystem); /* Get the current subsystem*/ -int content_get_subsystem(); +int content_get_subsystem(void); /* Add a rom to the subsystem rom buffer */ void content_add_subsystem(const char* path); /* Get the current subsystem rom id */ -int content_get_subsystem_rom_id(); +unsigned content_get_subsystem_rom_id(void); /* Set environment variables before a subsystem load */ -void content_set_subsystem_info(); - +void content_set_subsystem_info(void); RETRO_END_DECLS diff --git a/core.h b/core.h index 35878206b4..06cdbac698 100644 --- a/core.h +++ b/core.h @@ -170,6 +170,9 @@ bool core_set_poll_type(unsigned *type); /* Runs the core for one frame. */ bool core_run(void); +/* Runs the core for one frame, but does not trigger any input polling */ +bool core_run_no_input_polling(void); + bool core_init(void); bool core_deinit(void *data); diff --git a/core_impl.c b/core_impl.c index 62285e6682..7c2585a0c2 100644 --- a/core_impl.c +++ b/core_impl.c @@ -44,6 +44,11 @@ #include "gfx/video_driver.h" #include "audio/audio_driver.h" +#ifdef HAVE_RUNAHEAD +#include "runahead/copy_load_info.h" +#include "runahead/secondary_core.h" +#endif + struct retro_callbacks retro_ctx; struct retro_core_t current_core; @@ -262,6 +267,11 @@ bool core_set_controller_port_device(retro_ctx_controller_info_t *pad) { if (!pad) return false; + +#ifdef HAVE_RUNAHEAD + remember_controller_port_device(pad->port, pad->device); +#endif + current_core.retro_set_controller_port_device(pad->port, pad->device); return true; } @@ -280,6 +290,11 @@ bool core_load_game(retro_ctx_load_content_info_t *load_info) bool contentless = false; bool is_inited = false; +#ifdef HAVE_RUNAHEAD + set_load_content_info(load_info); + clear_controller_port_map(); +#endif + content_get_status(&contentless, &is_inited); if (load_info && load_info->special) @@ -424,6 +439,12 @@ bool core_run(void) return true; } +bool core_run_no_input_polling(void) +{ + current_core.retro_run(); + return true; +} + bool core_load(unsigned poll_type_behavior) { current_core.poll_type = poll_type_behavior; diff --git a/core_info.c b/core_info.c index 76b979046b..18bcfeffec 100644 --- a/core_info.c +++ b/core_info.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -26,14 +27,10 @@ #include "config.h" #endif -#include "retroarch.h" #include "verbosity.h" -#include "config.def.h" #include "core_info.h" -#include "configuration.h" #include "file_path_special.h" -#include "list_special.h" static const char *core_info_tmp_path = NULL; static const struct string_list *core_info_tmp_list = NULL; @@ -154,6 +151,7 @@ static void core_info_list_free(core_info_list_t *core_info_list) free(info->systemname); free(info->system_manufacturer); free(info->display_name); + free(info->display_version); free(info->supported_extensions); free(info->authors); free(info->permissions); @@ -224,21 +222,23 @@ static bool core_info_list_iterate( return true; } -static core_info_list_t *core_info_list_new(const char *path) +static core_info_list_t *core_info_list_new(const char *path, + const char *libretro_info_dir, + const char *exts, + bool show_hidden_files) { size_t i; core_info_t *core_info = NULL; core_info_list_t *core_info_list = NULL; - struct string_list *contents = dir_list_new_special( - path, DIR_LIST_CORES, NULL); - settings_t *settings = config_get_ptr(); - const char *path_basedir = !string_is_empty(settings->paths.path_libretro_info) ? - settings->paths.path_libretro_info : settings->paths.directory_libretro; - + const char *path_basedir = libretro_info_dir; + struct string_list *contents = dir_list_new( + path, exts, + false, + show_hidden_files, + false, false); if (!contents) return NULL; - core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list)); if (!core_info_list) goto error; @@ -279,6 +279,13 @@ static core_info_list_t *core_info_list_new(const char *path) free(tmp); tmp = NULL; } + if (config_get_string(conf, "display_version", &tmp) + && !string_is_empty(tmp)) + { + core_info[i].display_version = strdup(tmp); + free(tmp); + tmp = NULL; + } if (config_get_string(conf, "corename", &tmp) && !string_is_empty(tmp)) { @@ -518,7 +525,8 @@ static core_info_t *core_info_find_internal( static bool core_info_list_update_missing_firmware_internal( core_info_list_t *core_info_list, const char *core, - const char *systemdir) + const char *systemdir, + bool *set_missing_bios) { size_t i; core_info_t *info = NULL; @@ -535,7 +543,6 @@ static bool core_info_list_update_missing_firmware_internal( path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); path[0] = '\0'; - rarch_ctl(RARCH_CTL_UNSET_MISSING_BIOS, NULL); for (i = 0; i < info->firmware_count; i++) { @@ -547,7 +554,7 @@ static bool core_info_list_update_missing_firmware_internal( info->firmware[i].missing = !filestream_exists(path); if (info->firmware[i].missing && !info->firmware[i].optional) { - rarch_ctl(RARCH_CTL_SET_MISSING_BIOS, NULL); + *set_missing_bios = true; RARCH_WARN("Firmware missing: %s\n", info->firmware[i].path); } } @@ -635,14 +642,13 @@ void core_info_deinit_list(void) core_info_curr_list = NULL; } -bool core_info_init_list(void) +bool core_info_init_list(const char *path_info, const char *dir_cores, + const char *exts, bool show_hidden_files) { - settings_t *settings = config_get_ptr(); - - if (settings) - core_info_curr_list = core_info_list_new(settings->paths.directory_libretro); - - if (!core_info_curr_list) + if (!(core_info_curr_list = core_info_list_new(dir_cores, + !string_is_empty(path_info) ? path_info : dir_cores, + exts, + show_hidden_files))) return false; return true; } @@ -655,13 +661,15 @@ bool core_info_get_list(core_info_list_t **core) return true; } -bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info) +bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info, + bool *set_missing_bios) { if (!info) return false; return core_info_list_update_missing_firmware_internal( core_info_curr_list, - info->path, info->directory.system); + info->path, info->directory.system, + set_missing_bios); } bool core_info_load(core_info_ctx_find_t *info) @@ -751,16 +759,15 @@ void core_info_list_get_supported_cores(core_info_list_t *core_info_list, *num_infos = supported; } -void core_info_get_name(const char *path, char *s, size_t len) +void core_info_get_name(const char *path, char *s, size_t len, + const char *path_info, const char *dir_cores, + const char *exts, bool show_hidden_files) { size_t i; - settings_t *settings = config_get_ptr(); - struct string_list *contents = dir_list_new_special( - settings->paths.directory_libretro, - DIR_LIST_CORES, NULL); - const char *path_basedir = !string_is_empty(settings->paths.path_libretro_info) ? - settings->paths.path_libretro_info : settings->paths.directory_libretro; - + const char *path_basedir = !string_is_empty(path_info) ? + path_info : dir_cores; + struct string_list *contents = dir_list_new( + dir_cores, exts, false, show_hidden_files, false, false); if (!contents) return; @@ -786,7 +793,7 @@ void core_info_get_name(const char *path, char *s, size_t len) continue; } - conf = config_file_new(info_path); + conf = config_file_new(info_path); if (!conf) { diff --git a/core_info.h b/core_info.h index c058e8d937..f87805e605 100644 --- a/core_info.h +++ b/core_info.h @@ -43,6 +43,7 @@ typedef struct char *path; void *config_data; char *display_name; + char *display_version; char *core_name; char *system_manufacturer; char *systemname; @@ -97,7 +98,9 @@ bool core_info_list_get_display_name(core_info_list_t *list, bool core_info_get_display_name(const char *path, char *s, size_t len); -void core_info_get_name(const char *path, char *s, size_t len); +void core_info_get_name(const char *path, char *s, size_t len, + const char *path_info, const char *dir_cores, + const char *exts, bool show_hidden_files); core_info_t *core_info_get(core_info_list_t *list, size_t i); @@ -109,11 +112,13 @@ bool core_info_get_current_core(core_info_t **core); void core_info_deinit_list(void); -bool core_info_init_list(void); +bool core_info_init_list(const char *path_info, const char *dir_cores, + const char *exts, bool show_hidden_files); bool core_info_get_list(core_info_list_t **core); -bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info); +bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info, + bool *set_missing_bios); bool core_info_find(core_info_ctx_find_t *info, const char *name); diff --git a/ctr/ctr_system.c b/ctr/ctr_system.c index 29594251e7..9126ba009e 100644 --- a/ctr/ctr_system.c +++ b/ctr/ctr_system.c @@ -1,5 +1,6 @@ #include <3ds.h> #include +#include <3ds/services/apt.h> #include #include #include diff --git a/database_info.c b/database_info.c index 433bd275aa..894ae250ac 100644 --- a/database_info.c +++ b/database_info.c @@ -21,11 +21,13 @@ #include #include #include +#include +#include #include #include "libretro-db/libretrodb.h" -#include "list_special.h" +#include "core_info.h" #include "database_info.h" #include "verbosity.h" @@ -366,16 +368,22 @@ static void dir_list_prioritize(struct string_list *list) } database_info_handle_t *database_info_dir_init(const char *dir, - enum database_type type, retro_task_t *task) + enum database_type type, retro_task_t *task, + bool show_hidden_files) { - struct string_list *list = NULL; - database_info_handle_t *db = (database_info_handle_t*) + core_info_list_t *core_info_list = NULL; + struct string_list *list = NULL; + database_info_handle_t *db = (database_info_handle_t*) calloc(1, sizeof(*db)); if (!db) return NULL; - list = dir_list_new_special(dir, DIR_LIST_RECURSIVE, NULL); + core_info_get_list(&core_info_list); + + list = dir_list_new(dir, core_info_list->all_ext, + false, show_hidden_files, + false, true); if (!list) { diff --git a/database_info.h b/database_info.h index 2664577e6f..aa0f5b8011 100644 --- a/database_info.h +++ b/database_info.h @@ -126,7 +126,8 @@ database_info_list_t *database_info_list_new(const char *rdb_path, void database_info_list_free(database_info_list_t *list); database_info_handle_t *database_info_dir_init(const char *dir, - enum database_type type, retro_task_t *task); + enum database_type type, retro_task_t *task, + bool show_hidden_files); database_info_handle_t *database_info_file_init(const char *path, enum database_type type, retro_task_t *task); diff --git a/deps/dr/dr_flac.h b/deps/dr/dr_flac.h new file mode 100644 index 0000000000..fac749daff --- /dev/null +++ b/deps/dr/dr_flac.h @@ -0,0 +1,5461 @@ +#ifndef dr_flac_h +#define dr_flac_h + +#define DR_FLAC_NO_STDIO + +#include +#include +#include + +typedef int8_t drflac_int8; +typedef uint8_t drflac_uint8; +typedef int16_t drflac_int16; +typedef uint16_t drflac_uint16; +typedef int32_t drflac_int32; +typedef uint32_t drflac_uint32; +typedef int64_t drflac_int64; +typedef uint64_t drflac_uint64; +typedef drflac_uint8 drflac_bool8; +typedef drflac_uint32 drflac_bool32; +#define DRFLAC_TRUE 1 +#define DRFLAC_FALSE 0 + +/* As data is read from the client it is placed into an internal buffer for fast access. This controls the + * size of that buffer. Larger values means more speed, but also more memory. In my testing there is diminishing + * returns after about 4KB, but you can fiddle with this to suit your own needs. Must be a multiple of 8. + */ +#ifndef DR_FLAC_BUFFER_SIZE +#define DR_FLAC_BUFFER_SIZE 4096 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Check if we can enable 64-bit optimizations. */ +#if defined(_WIN64) +#define DRFLAC_64BIT +#endif + +#if defined(__GNUC__) +#if defined(__x86_64__) || defined(__ppc64__) +#define DRFLAC_64BIT +#endif +#endif + +#ifdef DRFLAC_64BIT +typedef drflac_uint64 drflac_cache_t; +#else +typedef drflac_uint32 drflac_cache_t; +#endif + +/* The various metadata block types. */ +#define DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO 0 +#define DRFLAC_METADATA_BLOCK_TYPE_PADDING 1 +#define DRFLAC_METADATA_BLOCK_TYPE_APPLICATION 2 +#define DRFLAC_METADATA_BLOCK_TYPE_SEEKTABLE 3 +#define DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT 4 +#define DRFLAC_METADATA_BLOCK_TYPE_CUESHEET 5 +#define DRFLAC_METADATA_BLOCK_TYPE_PICTURE 6 +#define DRFLAC_METADATA_BLOCK_TYPE_INVALID 127 + +/* The various picture types specified in the PICTURE block. */ +#define DRFLAC_PICTURE_TYPE_OTHER 0 +#define DRFLAC_PICTURE_TYPE_FILE_ICON 1 +#define DRFLAC_PICTURE_TYPE_OTHER_FILE_ICON 2 +#define DRFLAC_PICTURE_TYPE_COVER_FRONT 3 +#define DRFLAC_PICTURE_TYPE_COVER_BACK 4 +#define DRFLAC_PICTURE_TYPE_LEAFLET_PAGE 5 +#define DRFLAC_PICTURE_TYPE_MEDIA 6 +#define DRFLAC_PICTURE_TYPE_LEAD_ARTIST 7 +#define DRFLAC_PICTURE_TYPE_ARTIST 8 +#define DRFLAC_PICTURE_TYPE_CONDUCTOR 9 +#define DRFLAC_PICTURE_TYPE_BAND 10 +#define DRFLAC_PICTURE_TYPE_COMPOSER 11 +#define DRFLAC_PICTURE_TYPE_LYRICIST 12 +#define DRFLAC_PICTURE_TYPE_RECORDING_LOCATION 13 +#define DRFLAC_PICTURE_TYPE_DURING_RECORDING 14 +#define DRFLAC_PICTURE_TYPE_DURING_PERFORMANCE 15 +#define DRFLAC_PICTURE_TYPE_SCREEN_CAPTURE 16 +#define DRFLAC_PICTURE_TYPE_BRIGHT_COLORED_FISH 17 +#define DRFLAC_PICTURE_TYPE_ILLUSTRATION 18 +#define DRFLAC_PICTURE_TYPE_BAND_LOGOTYPE 19 +#define DRFLAC_PICTURE_TYPE_PUBLISHER_LOGOTYPE 20 + +typedef enum +{ + drflac_container_native, + drflac_container_ogg, + drflac_container_unknown +} drflac_container; + +typedef enum +{ + drflac_seek_origin_start, + drflac_seek_origin_current +} drflac_seek_origin; + +/* Packing is important on this structure because we map this directly to the raw data within the SEEKTABLE metadata block. */ +#pragma pack(2) +typedef struct +{ + drflac_uint64 firstSample; + drflac_uint64 frameOffset; /* The offset from the first byte of the header of the first frame. */ + drflac_uint16 sampleCount; +} drflac_seekpoint; +#pragma pack() + +typedef struct +{ + drflac_uint16 minBlockSize; + drflac_uint16 maxBlockSize; + drflac_uint32 minFrameSize; + drflac_uint32 maxFrameSize; + drflac_uint32 sampleRate; + drflac_uint8 channels; + drflac_uint8 bitsPerSample; + drflac_uint64 totalSampleCount; + drflac_uint8 md5[16]; +} drflac_streaminfo; + +typedef struct +{ + /* The metadata type. Use this to know how to interpret the data below. */ + drflac_uint32 type; + + /* A pointer to the raw data. This points to a temporary buffer so don't hold on to it. It's best to + * not modify the contents of this buffer. Use the structures below for more meaningful and structured + * information about the metadata. It's possible for this to be null. + */ + const void* pRawData; + + /* The size in bytes of the block and the buffer pointed to by pRawData if it's non-NULL. */ + drflac_uint32 rawDataSize; + + union + { + drflac_streaminfo streaminfo; + + struct + { + int unused; + } padding; + + struct + { + drflac_uint32 id; + const void* pData; + drflac_uint32 dataSize; + } application; + + struct + { + drflac_uint32 seekpointCount; + const drflac_seekpoint* pSeekpoints; + } seektable; + + struct + { + drflac_uint32 vendorLength; + const char* vendor; + drflac_uint32 commentCount; + const char* comments; + } vorbis_comment; + + struct + { + char catalog[128]; + drflac_uint64 leadInSampleCount; + drflac_bool32 isCD; + drflac_uint8 trackCount; + const drflac_uint8* pTrackData; + } cuesheet; + + struct + { + drflac_uint32 type; + drflac_uint32 mimeLength; + const char* mime; + drflac_uint32 descriptionLength; + const char* description; + drflac_uint32 width; + drflac_uint32 height; + drflac_uint32 colorDepth; + drflac_uint32 indexColorCount; + drflac_uint32 pictureDataSize; + const drflac_uint8* pPictureData; + } picture; + } data; +} drflac_metadata; + + +/* Callback for when data needs to be read from the client. + * + * pUserData [in] The user data that was passed to drflac_open() and family. + * pBufferOut [out] The output buffer. + * bytesToRead [in] The number of bytes to read. + * + * Returns the number of bytes actually read. + * + * A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until + * either the entire bytesToRead is filled or you have reached the end of the stream. + */ +typedef size_t (* drflac_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead); + +/* Callback for when data needs to be seeked. + * + * pUserData [in] The user data that was passed to drflac_open() and family. + * offset [in] The number of bytes to move, relative to the origin. Will never be negative. + * origin [in] The origin of the seek - the current position or the start of the stream. + * + * Returns whether or not the seek was successful. + * + * The offset will never be negative. Whether or not it is relative to the beginning or current position is determined + * by the "origin" parameter which will be either drflac_seek_origin_start or drflac_seek_origin_current. + */ +typedef drflac_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin); + +/* Callback for when a metadata block is read. + * + * pUserData [in] The user data that was passed to drflac_open() and family. + * pMetadata [in] A pointer to a structure containing the data of the metadata block. + * + * Use pMetadata->type to determine which metadata block is being handled and how to read the data. + */ +typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata); + + +/* Structure for internal use. Only used for decoders opened with drflac_open_memory. */ +typedef struct +{ + const drflac_uint8* data; + size_t dataSize; + size_t currentReadPos; +} drflac__memory_stream; + +/* Structure for internal use. Used for bit streaming. */ +typedef struct +{ + /* The function to call when more data needs to be read. */ + drflac_read_proc onRead; + + /* The function to call when the current read position needs to be moved. */ + drflac_seek_proc onSeek; + + /* The user data to pass around to onRead and onSeek. */ + void* pUserData; + + + /* The number of unaligned bytes in the L2 cache. This will always be 0 until the end of the stream is hit. At the end of the + * stream there will be a number of bytes that don't cleanly fit in an L1 cache line, so we use this variable to know whether + * or not the bistreamer needs to run on a slower path to read those last bytes. This will never be more than sizeof(drflac_cache_t). + */ + size_t unalignedByteCount; + + /* The content of the unaligned bytes. */ + drflac_cache_t unalignedCache; + + /* The index of the next valid cache line in the "L2" cache. */ + drflac_uint32 nextL2Line; + + /* The number of bits that have been consumed by the cache. This is used to determine how many valid bits are remaining. */ + drflac_uint32 consumedBits; + + /* The cached data which was most recently read from the client. There are two levels of cache. Data flows as such: + * Client -> L2 -> L1. The L2 -> L1 movement is aligned and runs on a fast path in just a few instructions. */ + drflac_cache_t cacheL2[DR_FLAC_BUFFER_SIZE/sizeof(drflac_cache_t)]; + drflac_cache_t cache; + + /* CRC-16. This is updated whenever bits are read from the bit stream. Manually set this to 0 to reset the CRC. For FLAC, this + * is reset to 0 at the beginning of each frame. */ + drflac_uint16 crc16; + drflac_cache_t crc16Cache; /* A cache for optimizing CRC calculations. This is filled when when the L1 cache is reloaded. */ + drflac_uint32 crc16CacheIgnoredBytes; /* The number of bytes to ignore when updating the CRC-16 from the CRC-16 cache. */ +} drflac_bs; + +typedef struct +{ + /* The type of the subframe: SUBFRAME_CONSTANT, SUBFRAME_VERBATIM, SUBFRAME_FIXED or SUBFRAME_LPC. */ + drflac_uint8 subframeType; + + /* The number of wasted bits per sample as specified by the sub-frame header. */ + drflac_uint8 wastedBitsPerSample; + + /* The order to use for the prediction stage for SUBFRAME_FIXED and SUBFRAME_LPC. */ + drflac_uint8 lpcOrder; + + /* The number of bits per sample for this subframe. This is not always equal to the current frame's bit per sample because + * an extra bit is required for side channels when interchannel decorrelation is being used. */ + drflac_uint32 bitsPerSample; + + /* A pointer to the buffer containing the decoded samples in the subframe. This pointer is an offset from drflac::pExtraData. Note that + * it's a signed 32-bit integer for each value. */ + drflac_int32* pDecodedSamples; +} drflac_subframe; + +typedef struct +{ + /* If the stream uses variable block sizes, this will be set to the index of the first sample. If fixed block sizes are used, this will + * always be set to 0. */ + drflac_uint64 sampleNumber; + + /* If the stream uses fixed block sizes, this will be set to the frame number. If variable block sizes are used, this will always be 0. */ + drflac_uint32 frameNumber; + + /* The sample rate of this frame. */ + drflac_uint32 sampleRate; + + /* The number of samples in each sub-frame within this frame. */ + drflac_uint16 blockSize; + + /* The channel assignment of this frame. This is not always set to the channel count. If interchannel decorrelation is being used this + * will be set to DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE, DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE or DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE. */ + drflac_uint8 channelAssignment; + + /* The number of bits per sample within this frame. */ + drflac_uint8 bitsPerSample; + + /* The frame's CRC. */ + drflac_uint8 crc8; +} drflac_frame_header; + +typedef struct +{ + /* The header. */ + drflac_frame_header header; + + /* The number of samples left to be read in this frame. This is initially set to the block size multiplied by the channel count. As samples + * are read, this will be decremented. When it reaches 0, the decoder will see this frame as fully consumed and load the next frame. + */ + drflac_uint32 samplesRemaining; + + /* The list of sub-frames within the frame. There is one sub-frame for each channel, and there's a maximum of 8 channels. */ + drflac_subframe subframes[8]; +} drflac_frame; + +typedef struct +{ + /* The function to call when a metadata block is read. */ + drflac_meta_proc onMeta; + + /* The user data posted to the metadata callback function. */ + void* pUserDataMD; + + + /* The sample rate. Will be set to something like 44100. */ + drflac_uint32 sampleRate; + + /* The number of channels. This will be set to 1 for monaural streams, 2 for stereo, etc. Maximum 8. This is set based on the + * value specified in the STREAMINFO block. */ + drflac_uint8 channels; + + /* The bits per sample. Will be set to somthing like 16, 24, etc. */ + drflac_uint8 bitsPerSample; + + /* The maximum block size, in samples. This number represents the number of samples in each channel (not combined). */ + drflac_uint16 maxBlockSize; + + /* The total number of samples making up the stream. This includes every channel. For example, if the stream has 2 channels, + * with each channel having a total of 4096, this value will be set to 2*4096 = 8192. Can be 0 in which case it's still a + * valid stream, but just means the total sample count is unknown. Likely the case with streams like internet radio. */ + drflac_uint64 totalSampleCount; + + + /* The container type. This is set based on whether or not the decoder was opened from a native or Ogg stream. */ + drflac_container container; + + /* The position of the seektable in the file. */ + drflac_uint64 seektablePos; + + /* The size of the seektable. */ + drflac_uint32 seektableSize; + + + /* Information about the frame the decoder is currently sitting on. */ + drflac_frame currentFrame; + + /* The position of the first frame in the stream. This is only ever used for seeking. */ + drflac_uint64 firstFramePos; + + + /* A hack to avoid a malloc() when opening a decoder with drflac_open_memory(). */ + drflac__memory_stream memoryStream; + + + /* A pointer to the decoded sample data. This is an offset of pExtraData. */ + drflac_int32* pDecodedSamples; + + /* Internal use only. Only used with Ogg containers. Points to a drflac_oggbs object. This is an offset of pExtraData. */ + void* _oggbs; + + /* The bit streamer. The raw FLAC data is fed through this object. */ + drflac_bs bs; + + /* Variable length extra data. We attach this to the end of the object so we can avoid unnecessary mallocs. */ + drflac_uint8 pExtraData[1]; +} drflac; + + +/* Opens a FLAC decoder. + * + * onRead [in] The function to call when data needs to be read from the client. + * onSeek [in] The function to call when the read position of the client data needs to move. + * pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek. + * + * Returns a pointer to an object representing the decoder. + * + * Close the decoder with drflac_close(). + * + * This function will automatically detect whether or not you are attempting to open a native or Ogg encapsulated + * FLAC, both of which should work seamlessly without any manual intervention. Ogg encapsulation also works with + * multiplexed streams which basically means it can play FLAC encoded audio tracks in videos. + * + * This is the lowest level function for opening a FLAC stream. You can also use drflac_open_file() and drflac_open_memory() + * to open the stream from a file or from a block of memory respectively. + * + * The STREAMINFO block must be present for this to succeed. Use drflac_open_relaxed() to open a FLAC stream where + * the header may not be present. + * + * See also: drflac_open_file(), drflac_open_memory(), drflac_open_with_metadata(), drflac_close() + */ +drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData); + +/* The same as drflac_open(), except attempts to open the stream even when a header block is not present. + * + * Because the header is not necessarily available, the caller must explicitly define the container (Native or Ogg). Do + * not set this to drflac_container_unknown - that is for internal use only. + * + * Opening in relaxed mode will continue reading data from onRead until it finds a valid frame. If a frame is never + * found it will continue forever. To abort, force your onRead callback to return 0, which dr_flac will use as an + * indicator that the end of the stream was found. */ +drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData); + +/* Opens a FLAC decoder and notifies the caller of the metadata chunks (album art, etc.). + * + * onRead [in] The function to call when data needs to be read from the client. + * onSeek [in] The function to call when the read position of the client data needs to move. + * onMeta [in] The function to call for every metadata block. + * pUserData [in, optional] A pointer to application defined data that will be passed to onRead, onSeek and onMeta. + * + * Returns a pointer to an object representing the decoder. + * + * Close the decoder with drflac_close(). + * + * This is slower than drflac_open(), so avoid this one if you don't need metadata. Internally, this will do a DRFLAC_MALLOC() + * and DRFLAC_FREE() for every metadata block except for STREAMINFO and PADDING blocks. + * + * The caller is notified of the metadata via the onMeta callback. All metadata blocks will be handled before the function + * returns. + * + * The STREAMINFO block must be present for this to succeed. Use drflac_open_with_metadata_relaxed() to open a FLAC + * stream where the header may not be present. + * + * Note that this will behave inconsistently with drflac_open() if the stream is an Ogg encapsulated stream and a metadata + * block is corrupted. This is due to the way the Ogg stream recovers from corrupted pages. When drflac_open_with_metadata() + * is being used, the open routine will try to read the contents of the metadata block, whereas drflac_open() will simply + * seek past it (for the sake of efficiency). This inconsistency can result in different samples being returned depending on + * whether or not the stream is being opened with metadata. + * + * See also: drflac_open_file_with_metadata(), drflac_open_memory_with_metadata(), drflac_open(), drflac_close() + */ +drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData); + +/* The same as drflac_open_with_metadata(), except attemps to open the stream even when a header block is not present. + * + * See also: drflac_open_with_metadata(), drflac_open_relaxed() + */ +drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData); + +/* Closes the given FLAC decoder. + * + * pFlac [in] The decoder to close. + * + * This will destroy the decoder object. */ +void drflac_close(drflac* pFlac); + + +/* Reads sample data from the given FLAC decoder, output as interleaved signed 32-bit PCM. + * + * pFlac [in] The decoder. + * samplesToRead [in] The number of samples to read. + * pBufferOut [out, optional] A pointer to the buffer that will receive the decoded samples. + * + * Returns the number of samples actually read. + * + * pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of samples + * seeked. */ +drflac_uint64 drflac_read_s32(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int32* pBufferOut); + +/* Same as drflac_read_s32(), except outputs samples as 16-bit integer PCM rather than 32-bit. + * + * pFlac [in] The decoder. + * samplesToRead [in] The number of samples to read. + * pBufferOut [out, optional] A pointer to the buffer that will receive the decoded samples. + * + * Returns the number of samples actually read. + * + * pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of samples + * seeked. + * + * Note that this is lossy for streams where the bits per sample is larger than 16. + */ +drflac_uint64 drflac_read_s16(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int16* pBufferOut); + +/* Same as drflac_read_s32(), except outputs samples as 32-bit floating-point PCM. + * + * pFlac [in] The decoder. + * samplesToRead [in] The number of samples to read. + * pBufferOut [out, optional] A pointer to the buffer that will receive the decoded samples. + * + * Returns the number of samples actually read. + * + * pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of samples + * seeked. + * + * Note that this should be considered lossy due to the nature of floating point numbers not being able to exactly + * represent every possible number. + */ +drflac_uint64 drflac_read_f32(drflac* pFlac, drflac_uint64 samplesToRead, float* pBufferOut); + +/* Seeks to the sample at the given index. + * + * pFlac [in] The decoder. + * sampleIndex [in] The index of the sample to seek to. See notes below. + * + * Returns DRFLAC_TRUE if successful; DRFLAC_FALSE otherwise. + * + * The sample index is based on interleaving. In a stereo stream, for example, the sample at index 0 is the first sample + * in the left channel; the sample at index 1 is the first sample on the right channel, and so on. + * + * When seeking, you will likely want to ensure it's rounded to a multiple of the channel count. You can do this with + * something like drflac_seek_to_sample(pFlac, (mySampleIndex + (mySampleIndex % pFlac->channels))) + */ +drflac_bool32 drflac_seek_to_sample(drflac* pFlac, drflac_uint64 sampleIndex); + + + +#ifndef DR_FLAC_NO_STDIO +/* Opens a FLAC decoder from the file at the given path. + * + * filename [in] The path of the file to open, either absolute or relative to the current directory. + * + * Returns a pointer to an object representing the decoder. + * + * Close the decoder with drflac_close(). + * + * This will hold a handle to the file until the decoder is closed with drflac_close(). Some platforms will restrict the + * number of files a process can have open at any given time, so keep this mind if you have many decoders open at the + * same time. + * + * See also: drflac_open(), drflac_open_file_with_metadata(), drflac_close() + */ +drflac* drflac_open_file(const char* filename); + +/* Opens a FLAC decoder from the file at the given path and notifies the caller of the metadata chunks (album art, etc.) + * + * Look at the documentation for drflac_open_with_metadata() for more information on how metadata is handled. + */ +drflac* drflac_open_file_with_metadata(const char* filename, drflac_meta_proc onMeta, void* pUserData); +#endif + +/* Opens a FLAC decoder from a pre-allocated block of memory + * + * This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for + * the lifetime of the decoder. + */ +drflac* drflac_open_memory(const void* data, size_t dataSize); + +/* Opens a FLAC decoder from a pre-allocated block of memory and notifies the caller of the metadata chunks (album art, etc.) + * + * Look at the documentation for drflac_open_with_metadata() for more information on how metadata is handled. + */ +drflac* drflac_open_memory_with_metadata(const void* data, size_t dataSize, drflac_meta_proc onMeta, void* pUserData); + +/* High Level APIs */ + +/* Opens a FLAC stream from the given callbacks and fully decodes it in a single operation. The return value is a + * pointer to the sample data as interleaved signed 32-bit PCM. The returned data must be freed with DRFLAC_FREE(). + * + * Sometimes a FLAC file won't keep track of the total sample count. In this situation the function will continuously + * read samples into a dynamically sized buffer on the heap until no samples are left. + * + * Do not call this function on a broadcast type of stream (like internet radio streams and whatnot). + */ +drflac_int32* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); + +/* Same as drflac_open_and_decode_s32(), except returns signed 16-bit integer samples. */ +drflac_int16* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); + +/* Same as drflac_open_and_decode_s32(), except returns 32-bit floating-point samples. */ +float* drflac_open_and_decode_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); + +#ifndef DR_FLAC_NO_STDIO +/* Same as drflac_open_and_decode_s32() except opens the decoder from a file. */ +drflac_int32* drflac_open_and_decode_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); + +/* Same as drflac_open_and_decode_file_s32(), except returns signed 16-bit integer samples. */ +drflac_int16* drflac_open_and_decode_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); + +/* Same as drflac_open_and_decode_file_f32(), except returns 32-bit floating-point samples. */ +float* drflac_open_and_decode_file_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); +#endif + +/* Same as drflac_open_and_decode_s32() except opens the decoder from a block of memory. */ +drflac_int32* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); + +/* Same as drflac_open_and_decode_memory_s32(), except returns signed 16-bit integer samples. */ +drflac_int16* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); + +/* Same as drflac_open_and_decode_memory_s32(), except returns 32-bit floating-point samples. */ +float* drflac_open_and_decode_memory_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); + +/* Frees memory that was allocated internally by dr_flac. */ +void drflac_free(void* p); + + +/* Structure representing an iterator for vorbis comments in a VORBIS_COMMENT metadata block. */ +typedef struct +{ + drflac_uint32 countRemaining; + const char* pRunningData; +} drflac_vorbis_comment_iterator; + +/* Initializes a vorbis comment iterator. This can be used for iterating over the vorbis comments in a VORBIS_COMMENT + * metadata block. */ +void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const char* pComments); + +/* Goes to the next vorbis comment in the given iterator. If null is returned it means there are no more comments. The + * returned string is NOT null terminated. */ +const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut); + + + +#ifdef __cplusplus +} +#endif +#endif /* dr_flac_h */ + + +/* + * + * IMPLEMENTATION + * + */ +#ifdef DR_FLAC_IMPLEMENTATION +#include +#include + +/* CPU architecture. */ +#if defined(__x86_64__) || defined(_M_X64) +#define DRFLAC_X64 +#elif defined(__i386) || defined(_M_IX86) +#define DRFLAC_X86 +#elif defined(__arm__) || defined(_M_ARM) +#define DRFLAC_ARM +#endif + +/* Compile-time CPU feature support. */ +#if !defined(DR_FLAC_NO_SIMD) && (defined(DRFLAC_X86) || defined(DRFLAC_X64)) + #ifdef _MSC_VER + #if _MSC_VER >= 1400 + #include + static void drflac__cpuid(int info[4], int fid) + { + __cpuid(info, fid); + } + #else + #define DRFLAC_NO_CPUID + #endif + #else + #if defined(__GNUC__) || defined(__clang__) + static void drflac__cpuid(int info[4], int fid) + { + __asm__ ( + "movl %[fid], %%eax\n\t" + "cpuid\n\t" + "movl %%eax, %[info0]\n\t" + "movl %%ebx, %[info1]\n\t" + "movl %%ecx, %[info2]\n\t" + "movl %%edx, %[info3]\n\t" + : [info0] "=rm"(info[0]), + [info1] "=rm"(info[1]), + [info2] "=rm"(info[2]), + [info3] "=rm"(info[3]) + : [fid] "rm"(fid) + : "eax", "ebx", "ecx", "edx" + ); + } + #else + #define DRFLAC_NO_CPUID + #endif + #endif +#else +#define DRFLAC_NO_CPUID +#endif + + +#ifdef __linux__ +#define _BSD_SOURCE +#include +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 1500 && (defined(DRFLAC_X86) || defined(DRFLAC_X64)) +#define DRFLAC_HAS_LZCNT_INTRINSIC +#elif (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) +#define DRFLAC_HAS_LZCNT_INTRINSIC +#elif defined(__clang__) + #if __has_builtin(__builtin_clzll) || __has_builtin(__builtin_clzl) + #define DRFLAC_HAS_LZCNT_INTRINSIC + #endif +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 1300 +#define DRFLAC_HAS_BYTESWAP_INTRINSIC +#elif defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +#define DRFLAC_HAS_BYTESWAP_INTRINSIC +#elif defined(__clang__) + #if __has_builtin(__builtin_bswap16) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64) + #define DRFLAC_HAS_BYTESWAP_INTRINSIC + #endif +#endif + +/* Standard library stuff. */ +#ifndef DRFLAC_ASSERT +#include +#define DRFLAC_ASSERT(expression) assert(expression) +#endif +#ifndef DRFLAC_MALLOC +#define DRFLAC_MALLOC(sz) malloc((sz)) +#endif +#ifndef DRFLAC_REALLOC +#define DRFLAC_REALLOC(p, sz) realloc((p), (sz)) +#endif +#ifndef DRFLAC_FREE +#define DRFLAC_FREE(p) free((p)) +#endif +#ifndef DRFLAC_COPY_MEMORY +#define DRFLAC_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz)) +#endif +#ifndef DRFLAC_ZERO_MEMORY +#define DRFLAC_ZERO_MEMORY(p, sz) memset((p), 0, (sz)) +#endif + +#define DRFLAC_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */ + +#ifdef _MSC_VER +#define DRFLAC_INLINE __forceinline +#else +#ifdef __GNUC__ +#define DRFLAC_INLINE INLINE __attribute__((always_inline)) +#else +#define DRFLAC_INLINE INLINE +#endif +#endif + +typedef drflac_int32 drflac_result; +#define DRFLAC_SUCCESS 0 +#define DRFLAC_ERROR -1 /* A generic error. */ +#define DRFLAC_INVALID_ARGS -2 +#define DRFLAC_END_OF_STREAM -128 +#define DRFLAC_CRC_MISMATCH -129 + +#define DRFLAC_SUBFRAME_CONSTANT 0 +#define DRFLAC_SUBFRAME_VERBATIM 1 +#define DRFLAC_SUBFRAME_FIXED 8 +#define DRFLAC_SUBFRAME_LPC 32 +#define DRFLAC_SUBFRAME_RESERVED 255 + +#define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE 0 +#define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 1 + +#define DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT 0 +#define DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE 8 +#define DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE 9 +#define DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE 10 + + +#define drflac_align(x, a) ((((x) + (a) - 1) / (a)) * (a)) +#define drflac_assert DRFLAC_ASSERT +#define drflac_copy_memory DRFLAC_COPY_MEMORY +#define drflac_zero_memory DRFLAC_ZERO_MEMORY + +/* CPU caps. */ +static drflac_bool32 drflac__gIsLZCNTSupported = DRFLAC_FALSE; +#ifndef DRFLAC_NO_CPUID +static drflac_bool32 drflac__gIsSSE42Supported = DRFLAC_FALSE; +static void drflac__init_cpu_caps() +{ + int info[4] = {0}; + + /* LZCNT */ + drflac__cpuid(info, 0x80000001); + drflac__gIsLZCNTSupported = (info[2] & (1 << 5)) != 0; + + /* SSE4.2 */ + drflac__cpuid(info, 1); + drflac__gIsSSE42Supported = (info[2] & (1 << 19)) != 0; +} +#endif + + +/* Endian Management */ +static DRFLAC_INLINE drflac_bool32 drflac__is_little_endian() +{ +#if defined(DRFLAC_X86) || defined(DRFLAC_X64) + return DRFLAC_TRUE; +#else + int n = 1; + return (*(char*)&n) == 1; +#endif +} + +static DRFLAC_INLINE drflac_uint16 drflac__swap_endian_uint16(drflac_uint16 n) +{ +#ifdef DRFLAC_HAS_BYTESWAP_INTRINSIC + #if defined(_MSC_VER) + return _byteswap_ushort(n); + #elif defined(__GNUC__) || defined(__clang__) + return __builtin_bswap16(n); + #else + #error "This compiler does not support the byte swap intrinsic." + #endif +#else + return ((n & 0xFF00) >> 8) | + ((n & 0x00FF) << 8); +#endif +} + +static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n) +{ +#ifdef DRFLAC_HAS_BYTESWAP_INTRINSIC + #if defined(_MSC_VER) + return _byteswap_ulong(n); + #elif defined(__GNUC__) || defined(__clang__) + return __builtin_bswap32(n); + #else + #error "This compiler does not support the byte swap intrinsic." + #endif +#else + return ((n & 0xFF000000) >> 24) | + ((n & 0x00FF0000) >> 8) | + ((n & 0x0000FF00) << 8) | + ((n & 0x000000FF) << 24); +#endif +} + +static DRFLAC_INLINE drflac_uint64 drflac__swap_endian_uint64(drflac_uint64 n) +{ +#ifdef DRFLAC_HAS_BYTESWAP_INTRINSIC + #if defined(_MSC_VER) + return _byteswap_uint64(n); + #elif defined(__GNUC__) || defined(__clang__) + return __builtin_bswap64(n); + #else + #error "This compiler does not support the byte swap intrinsic." + #endif +#else + return ((n & (drflac_uint64)0xFF00000000000000) >> 56) | + ((n & (drflac_uint64)0x00FF000000000000) >> 40) | + ((n & (drflac_uint64)0x0000FF0000000000) >> 24) | + ((n & (drflac_uint64)0x000000FF00000000) >> 8) | + ((n & (drflac_uint64)0x00000000FF000000) << 8) | + ((n & (drflac_uint64)0x0000000000FF0000) << 24) | + ((n & (drflac_uint64)0x000000000000FF00) << 40) | + ((n & (drflac_uint64)0x00000000000000FF) << 56); +#endif +} + + +static DRFLAC_INLINE drflac_uint16 drflac__be2host_16(drflac_uint16 n) +{ +#ifdef __linux__ + return be16toh(n); +#else + if (drflac__is_little_endian()) + return drflac__swap_endian_uint16(n); + + return n; +#endif +} + +static DRFLAC_INLINE drflac_uint32 drflac__be2host_32(drflac_uint32 n) +{ +#ifdef __linux__ + return be32toh(n); +#else + if (drflac__is_little_endian()) + return drflac__swap_endian_uint32(n); + + return n; +#endif +} + +static DRFLAC_INLINE drflac_uint64 drflac__be2host_64(drflac_uint64 n) +{ +#ifdef __linux__ + return be64toh(n); +#else + if (drflac__is_little_endian()) + return drflac__swap_endian_uint64(n); + + return n; +#endif +} + + +static DRFLAC_INLINE drflac_uint32 drflac__le2host_32(drflac_uint32 n) +{ +#ifdef __linux__ + return le32toh(n); +#else + if (!drflac__is_little_endian()) + return drflac__swap_endian_uint32(n); + + return n; +#endif +} + + +static DRFLAC_INLINE drflac_uint32 drflac__unsynchsafe_32(drflac_uint32 n) +{ + drflac_uint32 result = 0; + result |= (n & 0x7F000000) >> 3; + result |= (n & 0x007F0000) >> 2; + result |= (n & 0x00007F00) >> 1; + result |= (n & 0x0000007F) >> 0; + + return result; +} + +/* The CRC code below is based on this document: http://zlib.net/crc_v3.txt */ +static drflac_uint8 drflac__crc8_table[] = { + 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, + 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, + 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, + 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, + 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, + 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, + 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, + 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, + 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, + 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, + 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, + 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, + 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, + 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, + 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, + 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 +}; + +static drflac_uint16 drflac__crc16_table[] = { + 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011, + 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022, + 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072, + 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041, + 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2, + 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1, + 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1, + 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082, + 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192, + 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1, + 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1, + 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2, + 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151, + 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162, + 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132, + 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101, + 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312, + 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321, + 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371, + 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342, + 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1, + 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2, + 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2, + 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381, + 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291, + 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2, + 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2, + 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1, + 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252, + 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261, + 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231, + 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202 +}; + +static DRFLAC_INLINE drflac_uint8 drflac_crc8_byte(drflac_uint8 crc, drflac_uint8 data) +{ + return drflac__crc8_table[crc ^ data]; +} + +static DRFLAC_INLINE drflac_uint8 drflac_crc8(drflac_uint8 crc, drflac_uint32 data, drflac_uint32 count) +{ + +#ifdef DR_FLAC_NO_CRC + (void)crc; + (void)data; + (void)count; + drflac_assert(count <= 32); + return 0; +#else +#if 0 + /* REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc8(crc, 0, 8);") */ + drflac_uint8 p = 0x07; + for (int i = count-1; i >= 0; --i) + { + drflac_uint8 bit = (data & (1 << i)) >> i; + if (crc & 0x80) + crc = ((crc << 1) | bit) ^ p; + else + crc = ((crc << 1) | bit); + } + return crc; +#else + static drflac_uint64 leftoverDataMaskTable[8] = { + 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F + }; + drflac_uint32 wholeBytes = count >> 3; + drflac_uint32 leftoverBits = count - (wholeBytes*8); + drflac_uint64 leftoverDataMask = leftoverDataMaskTable[leftoverBits]; + drflac_assert(count <= 32); + + switch (wholeBytes) + { + case 4: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits))); + case 3: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits))); + case 2: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits))); + case 1: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits))); + case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc8_table[(crc >> (8 - leftoverBits)) ^ (data & leftoverDataMask)]; + } + return crc; +#endif +#endif +} + +static DRFLAC_INLINE drflac_uint16 drflac_crc16_byte(drflac_uint16 crc, drflac_uint8 data) +{ + return (crc << 8) ^ drflac__crc16_table[(drflac_uint8)(crc >> 8) ^ data]; +} + +static DRFLAC_INLINE drflac_uint16 drflac_crc16_bytes(drflac_uint16 crc, drflac_cache_t data, drflac_uint32 byteCount) +{ + switch (byteCount) + { +#ifdef DRFLAC_64BIT + case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 56) & 0xFF)); + case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 48) & 0xFF)); + case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 40) & 0xFF)); + case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 32) & 0xFF)); +#endif + case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 24) & 0xFF)); + case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 16) & 0xFF)); + case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 8) & 0xFF)); + case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 0) & 0xFF)); + } + + return crc; +} + +static DRFLAC_INLINE drflac_uint16 drflac_crc16__32bit(drflac_uint16 crc, drflac_uint32 data, drflac_uint32 count) +{ + +#ifdef DR_FLAC_NO_CRC + (void)crc; + (void)data; + (void)count; + drflac_assert(count <= 64); + return 0; +#else +#if 0 + /* REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc16(crc, 0, 16);") */ + drflac_uint16 p = 0x8005; + for (int i = count-1; i >= 0; --i) + { + drflac_uint16 bit = (data & (1ULL << i)) >> i; + if (r & 0x8000) + r = ((r << 1) | bit) ^ p; + else + r = ((r << 1) | bit); + } + + return crc; +#else + drflac_uint32 wholeBytes = count >> 3; + drflac_uint32 leftoverBits = count - (wholeBytes*8); + + static drflac_uint64 leftoverDataMaskTable[8] = { + 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F + }; + drflac_uint64 leftoverDataMask = leftoverDataMaskTable[leftoverBits]; + + drflac_assert(count <= 64); + + switch (wholeBytes) + { + default: + case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits))); + case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits))); + case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits))); + case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits))); + case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)]; + } + return crc; +#endif +#endif +} + +static DRFLAC_INLINE drflac_uint16 drflac_crc16__64bit(drflac_uint16 crc, drflac_uint64 data, drflac_uint32 count) +{ + +#ifdef DR_FLAC_NO_CRC + (void)crc; + (void)data; + (void)count; + drflac_assert(count <= 64); + return 0; +#else + drflac_uint32 wholeBytes = count >> 3; + drflac_uint32 leftoverBits = count - (wholeBytes*8); + + static drflac_uint64 leftoverDataMaskTable[8] = { + 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F + }; + drflac_uint64 leftoverDataMask = leftoverDataMaskTable[leftoverBits]; + + drflac_assert(count <= 64); + + switch (wholeBytes) + { + default: + case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0xFF00000000000000 << leftoverBits)) >> (56 + leftoverBits))); + case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x00FF000000000000 << leftoverBits)) >> (48 + leftoverBits))); + case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x0000FF0000000000 << leftoverBits)) >> (40 + leftoverBits))); + case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x000000FF00000000 << leftoverBits)) >> (32 + leftoverBits))); + case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x00000000FF000000 << leftoverBits)) >> (24 + leftoverBits))); + case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x0000000000FF0000 << leftoverBits)) >> (16 + leftoverBits))); + case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x000000000000FF00 << leftoverBits)) >> ( 8 + leftoverBits))); + case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & ((drflac_uint64)0x00000000000000FF << leftoverBits)) >> ( 0 + leftoverBits))); + case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)]; + } + return crc; +#endif +} + + +static DRFLAC_INLINE drflac_uint16 drflac_crc16(drflac_uint16 crc, drflac_cache_t data, drflac_uint32 count) +{ +#ifdef DRFLAC_64BIT + return drflac_crc16__64bit(crc, data, count); +#else + return drflac_crc16__32bit(crc, data, count); +#endif +} + + +#ifdef DRFLAC_64BIT +#define drflac__be2host__cache_line drflac__be2host_64 +#else +#define drflac__be2host__cache_line drflac__be2host_32 +#endif + +/* BIT READING ATTEMPT #2 + * + * This uses a 32- or 64-bit bit-shifted cache - as bits are read, the cache is shifted such that the first valid bit is sitting + * on the most significant bit. It uses the notion of an L1 and L2 cache (borrowed from CPU architecture), where the L1 cache + * is a 32- or 64-bit unsigned integer (depending on whether or not a 32- or 64-bit build is being compiled) and the L2 is an + * array of "cache lines", with each cache line being the same size as the L1. The L2 is a buffer of about 4KB and is where data + * from onRead() is read into. + */ +#define DRFLAC_CACHE_L1_SIZE_BYTES(bs) (sizeof((bs)->cache)) +#define DRFLAC_CACHE_L1_SIZE_BITS(bs) (sizeof((bs)->cache)*8) +#define DRFLAC_CACHE_L1_BITS_REMAINING(bs) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - ((bs)->consumedBits)) +#ifdef DRFLAC_64BIT +#define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~(((drflac_uint64)-1LL) >> (_bitCount))) +#else +#define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~(((drflac_uint32)-1) >> (_bitCount))) +#endif +#define DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (_bitCount)) +#define DRFLAC_CACHE_L1_SELECT(bs, _bitCount) (((bs)->cache) & DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount)) +#define DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SELECT((bs), _bitCount) >> DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), _bitCount)) +#define DRFLAC_CACHE_L2_SIZE_BYTES(bs) (sizeof((bs)->cacheL2)) +#define DRFLAC_CACHE_L2_LINE_COUNT(bs) (DRFLAC_CACHE_L2_SIZE_BYTES(bs) / sizeof((bs)->cacheL2[0])) +#define DRFLAC_CACHE_L2_LINES_REMAINING(bs) (DRFLAC_CACHE_L2_LINE_COUNT(bs) - (bs)->nextL2Line) + + +#ifndef DR_FLAC_NO_CRC +static DRFLAC_INLINE void drflac__reset_crc16(drflac_bs* bs) +{ + bs->crc16 = 0; + bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3; +} + +static DRFLAC_INLINE void drflac__update_crc16(drflac_bs* bs) +{ + bs->crc16 = drflac_crc16_bytes(bs->crc16, bs->crc16Cache, DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bs->crc16CacheIgnoredBytes); + bs->crc16CacheIgnoredBytes = 0; +} + +static DRFLAC_INLINE drflac_uint16 drflac__flush_crc16(drflac_bs* bs) +{ + /* We should never be flushing in a situation where we are not aligned on a byte boundary. */ + drflac_assert((DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7) == 0); + + /* The bits that were read from the L1 cache need to be accumulated. The number of bytes needing to be accumulated is determined + * by the number of bits that have been consumed. */ + if (DRFLAC_CACHE_L1_BITS_REMAINING(bs) == 0) + drflac__update_crc16(bs); + else + { + /* We only accumulate the consumed bits. */ + bs->crc16 = drflac_crc16_bytes(bs->crc16, bs->crc16Cache >> DRFLAC_CACHE_L1_BITS_REMAINING(bs), (bs->consumedBits >> 3) - bs->crc16CacheIgnoredBytes); + + /* The bits that we just accumulated should never be accumulated again. We need to keep track of how many bytes were accumulated + * so we can handle that later. */ + bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3; + } + + return bs->crc16; +} +#endif + +static DRFLAC_INLINE drflac_bool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs) +{ + size_t alignedL1LineCount; + size_t bytesRead; + /* Fast path. Try loading straight from L2. */ + if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) + { + bs->cache = bs->cacheL2[bs->nextL2Line++]; + return DRFLAC_TRUE; + } + + /* If we get here it means we've run out of data in the L2 cache. We'll need to fetch more from the client, if there's + * any left. */ + if (bs->unalignedByteCount > 0) + return DRFLAC_FALSE; /* If we have any unaligned bytes it means there's no more aligned bytes left in the client. */ + + bytesRead = bs->onRead(bs->pUserData, bs->cacheL2, DRFLAC_CACHE_L2_SIZE_BYTES(bs)); + + bs->nextL2Line = 0; + if (bytesRead == DRFLAC_CACHE_L2_SIZE_BYTES(bs)) + { + bs->cache = bs->cacheL2[bs->nextL2Line++]; + return DRFLAC_TRUE; + } + + + /* If we get here it means we were unable to retrieve enough data to fill the entire L2 cache. It probably + * means we've just reached the end of the file. We need to move the valid data down to the end of the buffer + * and adjust the index of the next line accordingly. Also keep in mind that the L2 cache must be aligned to + * the size of the L1 so we'll need to seek backwards by any misaligned bytes. + */ + alignedL1LineCount = bytesRead / DRFLAC_CACHE_L1_SIZE_BYTES(bs); + + /* We need to keep track of any unaligned bytes for later use. */ + bs->unalignedByteCount = bytesRead - (alignedL1LineCount * DRFLAC_CACHE_L1_SIZE_BYTES(bs)); + if (bs->unalignedByteCount > 0) + bs->unalignedCache = bs->cacheL2[alignedL1LineCount]; + + if (alignedL1LineCount > 0) + { + size_t i; + size_t offset = DRFLAC_CACHE_L2_LINE_COUNT(bs) - alignedL1LineCount; + for (i = alignedL1LineCount; i > 0; --i) + bs->cacheL2[i-1 + offset] = bs->cacheL2[i-1]; + + bs->nextL2Line = (drflac_uint32)offset; + bs->cache = bs->cacheL2[bs->nextL2Line++]; + return DRFLAC_TRUE; + } + + /* If we get into this branch it means we weren't able to load any L1-aligned data. */ + bs->nextL2Line = DRFLAC_CACHE_L2_LINE_COUNT(bs); + return DRFLAC_FALSE; +} + +static drflac_bool32 drflac__reload_cache(drflac_bs* bs) +{ + size_t bytesRead; + +#ifndef DR_FLAC_NO_CRC + drflac__update_crc16(bs); +#endif + + /* Fast path. Try just moving the next value in the L2 cache to the L1 cache. */ + if (drflac__reload_l1_cache_from_l2(bs)) + { + bs->cache = drflac__be2host__cache_line(bs->cache); + bs->consumedBits = 0; +#ifndef DR_FLAC_NO_CRC + bs->crc16Cache = bs->cache; +#endif + return DRFLAC_TRUE; + } + + /* Slow path. */ + + /* If we get here it means we have failed to load the L1 cache from the L2. Likely we've just reached the end of the stream and the last + * few bytes did not meet the alignment requirements for the L2 cache. In this case we need to fall back to a slower path and read the + * data from the unaligned cache. */ + bytesRead = bs->unalignedByteCount; + if (bytesRead == 0) + return DRFLAC_FALSE; + + drflac_assert(bytesRead < DRFLAC_CACHE_L1_SIZE_BYTES(bs)); + bs->consumedBits = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bytesRead) * 8; + + bs->cache = drflac__be2host__cache_line(bs->unalignedCache); + bs->cache &= DRFLAC_CACHE_L1_SELECTION_MASK(DRFLAC_CACHE_L1_SIZE_BITS(bs) - bs->consumedBits); /* <-- Make sure the consumed bits are always set to zero. Other parts of the library depend on this property. */ + bs->unalignedByteCount = 0; /* <-- At this point the unaligned bytes have been moved into the cache and we thus have no more unaligned bytes. */ + +#ifndef DR_FLAC_NO_CRC + bs->crc16Cache = bs->cache >> bs->consumedBits; + bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3; +#endif + return DRFLAC_TRUE; +} + +static void drflac__reset_cache(drflac_bs* bs) +{ + bs->nextL2Line = DRFLAC_CACHE_L2_LINE_COUNT(bs); /* <-- This clears the L2 cache. */ + bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs); /* <-- This clears the L1 cache. */ + bs->cache = 0; + bs->unalignedByteCount = 0; /* <-- This clears the trailing unaligned bytes. */ + bs->unalignedCache = 0; + +#ifndef DR_FLAC_NO_CRC + bs->crc16Cache = 0; + bs->crc16CacheIgnoredBytes = 0; +#endif +} + + +static DRFLAC_INLINE drflac_bool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, drflac_uint32* pResultOut) +{ + drflac_assert(bs != NULL); + drflac_assert(pResultOut != NULL); + drflac_assert(bitCount > 0); + drflac_assert(bitCount <= 32); + + if (bs->consumedBits == DRFLAC_CACHE_L1_SIZE_BITS(bs)) + { + if (!drflac__reload_cache(bs)) + return DRFLAC_FALSE; + } + + if (bitCount <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) + { + if (bitCount < DRFLAC_CACHE_L1_SIZE_BITS(bs)) + { + *pResultOut = DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount); + bs->consumedBits += bitCount; + bs->cache <<= bitCount; + } else { + *pResultOut = (drflac_uint32)bs->cache; + bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs); + bs->cache = 0; + } + return DRFLAC_TRUE; + } else { + /* It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them. */ + drflac_uint32 bitCountHi = DRFLAC_CACHE_L1_BITS_REMAINING(bs); + drflac_uint32 bitCountLo = bitCount - bitCountHi; + drflac_uint32 resultHi = DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountHi); + + if (!drflac__reload_cache(bs)) + return DRFLAC_FALSE; + + *pResultOut = (resultHi << bitCountLo) | DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountLo); + bs->consumedBits += bitCountLo; + bs->cache <<= bitCountLo; + return DRFLAC_TRUE; + } +} + +static drflac_bool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, drflac_int32* pResult) +{ + drflac_uint32 result; + drflac_uint32 signbit; + + drflac_assert(bs != NULL); + drflac_assert(pResult != NULL); + drflac_assert(bitCount > 0); + drflac_assert(bitCount <= 32); + + if (!drflac__read_uint32(bs, bitCount, &result)) + return DRFLAC_FALSE; + + signbit = ((result >> (bitCount-1)) & 0x01); + result |= (~signbit + 1) << bitCount; + + *pResult = (drflac_int32)result; + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, drflac_uint64* pResultOut) +{ + drflac_uint32 resultHi; + drflac_uint32 resultLo; + + drflac_assert(bitCount <= 64); + drflac_assert(bitCount > 32); + + if (!drflac__read_uint32(bs, bitCount - 32, &resultHi)) + return DRFLAC_FALSE; + + if (!drflac__read_uint32(bs, 32, &resultLo)) + return DRFLAC_FALSE; + + *pResultOut = (((drflac_uint64)resultHi) << 32) | ((drflac_uint64)resultLo); + return DRFLAC_TRUE; +} + +/* Function below is unused, but leaving it here in case I need to quickly add it again. */ +#if 0 +static drflac_bool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, drflac_int64* pResultOut) +{ + drflac_assert(bitCount <= 64); + + drflac_uint64 result; + if (!drflac__read_uint64(bs, bitCount, &result)) + return DRFLAC_FALSE; + + drflac_uint64 signbit = ((result >> (bitCount-1)) & 0x01); + result |= (~signbit + 1) << bitCount; + + *pResultOut = (drflac_int64)result; + return DRFLAC_TRUE; +} +#endif + +static drflac_bool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, drflac_uint16* pResult) +{ + drflac_uint32 result; + + drflac_assert(bs != NULL); + drflac_assert(pResult != NULL); + drflac_assert(bitCount > 0); + drflac_assert(bitCount <= 16); + + if (!drflac__read_uint32(bs, bitCount, &result)) + return DRFLAC_FALSE; + + *pResult = (drflac_uint16)result; + return DRFLAC_TRUE; +} + +#if 0 +static drflac_bool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, drflac_int16* pResult) +{ + drflac_int32 result; + + drflac_assert(bs != NULL); + drflac_assert(pResult != NULL); + drflac_assert(bitCount > 0); + drflac_assert(bitCount <= 16); + + if (!drflac__read_int32(bs, bitCount, &result)) + return DRFLAC_FALSE; + + *pResult = (drflac_int16)result; + return DRFLAC_TRUE; +} +#endif + +static drflac_bool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, drflac_uint8* pResult) +{ + drflac_uint32 result; + + drflac_assert(bs != NULL); + drflac_assert(pResult != NULL); + drflac_assert(bitCount > 0); + drflac_assert(bitCount <= 8); + + if (!drflac__read_uint32(bs, bitCount, &result)) + return DRFLAC_FALSE; + + *pResult = (drflac_uint8)result; + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, drflac_int8* pResult) +{ + drflac_int32 result; + + drflac_assert(bs != NULL); + drflac_assert(pResult != NULL); + drflac_assert(bitCount > 0); + drflac_assert(bitCount <= 8); + + if (!drflac__read_int32(bs, bitCount, &result)) + return DRFLAC_FALSE; + + *pResult = (drflac_int8)result; + return DRFLAC_TRUE; +} + + +static drflac_bool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek) +{ + if (bitsToSeek <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) + { + bs->consumedBits += (drflac_uint32)bitsToSeek; + bs->cache <<= bitsToSeek; + return DRFLAC_TRUE; + } + + /* It straddles the cached data. This function isn't called too frequently so I'm favouring simplicity here. */ + bitsToSeek -= DRFLAC_CACHE_L1_BITS_REMAINING(bs); + bs->consumedBits += DRFLAC_CACHE_L1_BITS_REMAINING(bs); + bs->cache = 0; + + /* Simple case. Seek in groups of the same number as bits that fit within a cache line. */ +#ifdef DRFLAC_64BIT + while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) + { + drflac_uint64 bin; + if (!drflac__read_uint64(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) + return DRFLAC_FALSE; + bitsToSeek -= DRFLAC_CACHE_L1_SIZE_BITS(bs); + } +#else + while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) + { + drflac_uint32 bin; + if (!drflac__read_uint32(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) + return DRFLAC_FALSE; + bitsToSeek -= DRFLAC_CACHE_L1_SIZE_BITS(bs); + } +#endif + + /* Whole leftover bytes. */ + while (bitsToSeek >= 8) + { + drflac_uint8 bin; + if (!drflac__read_uint8(bs, 8, &bin)) + return DRFLAC_FALSE; + bitsToSeek -= 8; + } + + /* Leftover bits. */ + if (bitsToSeek > 0) + { + drflac_uint8 bin; + if (!drflac__read_uint8(bs, (drflac_uint32)bitsToSeek, &bin)) + return DRFLAC_FALSE; + bitsToSeek = 0; /* <-- Necessary for the assert below. */ + } + + drflac_assert(bitsToSeek == 0); + return DRFLAC_TRUE; +} + + +/* This function moves the bit streamer to the first bit after the sync code (bit 15 of the of the frame header). It will also update the CRC-16. */ +static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs* bs) +{ + drflac_assert(bs != NULL); + + /* The sync code is always aligned to 8 bits. This is convenient for us because it means we can do byte-aligned movements. The first + * thing to do is align to the next byte. */ + if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) + return DRFLAC_FALSE; + + for (;;) + { + drflac_uint8 hi; + +#ifndef DR_FLAC_NO_CRC + drflac__reset_crc16(bs); +#endif + + if (!drflac__read_uint8(bs, 8, &hi)) + return DRFLAC_FALSE; + + if (hi == 0xFF) + { + drflac_uint8 lo; + if (!drflac__read_uint8(bs, 6, &lo)) + return DRFLAC_FALSE; + + if (lo == 0x3E) + return DRFLAC_TRUE; + + if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) + return DRFLAC_FALSE; + } + } + +#if 0 + /* Should never get here. */ + return DRFLAC_FALSE; +#endif +} + + +#if !defined(DR_FLAC_NO_SIMD) && defined(DRFLAC_HAS_LZCNT_INTRINSIC) +#define DRFLAC_IMPLEMENT_CLZ_LZCNT +#endif +#if defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(DRFLAC_X64) || defined(DRFLAC_X86)) +#define DRFLAC_IMPLEMENT_CLZ_MSVC +#endif + +static DRFLAC_INLINE drflac_uint32 drflac__clz_software(drflac_cache_t x) +{ + static drflac_uint32 clz_table_4[] = { + 0, + 4, + 3, 3, + 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1 + }; + drflac_uint32 n = clz_table_4[x >> (sizeof(x)*8 - 4)]; + + if (n == 0) + { +#ifdef DRFLAC_64BIT + if ((x & 0xFFFFFFFF00000000ULL) == 0) { n = 32; x <<= 32; } + if ((x & 0xFFFF000000000000ULL) == 0) { n += 16; x <<= 16; } + if ((x & 0xFF00000000000000ULL) == 0) { n += 8; x <<= 8; } + if ((x & 0xF000000000000000ULL) == 0) { n += 4; x <<= 4; } +#else + if ((x & 0xFFFF0000) == 0) { n = 16; x <<= 16; } + if ((x & 0xFF000000) == 0) { n += 8; x <<= 8; } + if ((x & 0xF0000000) == 0) { n += 4; x <<= 4; } +#endif + n += clz_table_4[x >> (sizeof(x)*8 - 4)]; + } + + return n - 1; +} + +#ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT +static DRFLAC_INLINE drflac_bool32 drflac__is_lzcnt_supported() +{ + /* If the compiler itself does not support the intrinsic then we'll need to return false. */ +#ifdef DRFLAC_HAS_LZCNT_INTRINSIC + return drflac__gIsLZCNTSupported; +#else + return DRFLAC_FALSE; +#endif +} + +static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x) +{ +#if defined(_MSC_VER) && !defined(__clang__) +#ifdef DRFLAC_64BIT + return (drflac_uint32)__lzcnt64(x); +#else + return (drflac_uint32)__lzcnt(x); +#endif +#else +#if defined(__GNUC__) || defined(__clang__) +#ifdef DRFLAC_64BIT + return (drflac_uint32)__builtin_clzll((unsigned long long)x); +#else + return (drflac_uint32)__builtin_clzl((unsigned long)x); +#endif +#else + /* Unsupported compiler. */ +#error "This compiler does not support the lzcnt intrinsic." +#endif +#endif +} +#endif + +#ifdef DRFLAC_IMPLEMENT_CLZ_MSVC +static DRFLAC_INLINE drflac_uint32 drflac__clz_msvc(drflac_cache_t x) +{ + drflac_uint32 n; +#ifdef DRFLAC_64BIT + _BitScanReverse64((unsigned long*)&n, x); +#else + _BitScanReverse((unsigned long*)&n, x); +#endif + return sizeof(x)*8 - n - 1; +} +#endif + +static DRFLAC_INLINE drflac_uint32 drflac__clz(drflac_cache_t x) +{ + /* This function assumes at least one bit is set. Checking for 0 needs to be done at a higher level, outside this function. */ +#ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT + if (drflac__is_lzcnt_supported()) + return drflac__clz_lzcnt(x); +#endif + +#ifdef DRFLAC_IMPLEMENT_CLZ_MSVC + return drflac__clz_msvc(x); +#else + return drflac__clz_software(x); +#endif +} + +static INLINE drflac_bool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned int* pOffsetOut) +{ + drflac_uint32 setBitOffsetPlus1; + drflac_uint32 zeroCounter = 0; + while (bs->cache == 0) + { + zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs); + if (!drflac__reload_cache(bs)) + return DRFLAC_FALSE; + } + + setBitOffsetPlus1 = drflac__clz(bs->cache); + zeroCounter += setBitOffsetPlus1; + setBitOffsetPlus1 += 1; + + bs->consumedBits += setBitOffsetPlus1; + bs->cache <<= setBitOffsetPlus1; + + *pOffsetOut = zeroCounter + setBitOffsetPlus1 - 1; + return DRFLAC_TRUE; +} + + + +static drflac_bool32 drflac__seek_to_byte(drflac_bs* bs, drflac_uint64 offsetFromStart) +{ + drflac_assert(bs != NULL); + drflac_assert(offsetFromStart > 0); + + /* Seeking from the start is not quite as trivial as it sounds because the onSeek callback takes a signed 32-bit integer (which + * is intentional because it simplifies the implementation of the onSeek callbacks), however offsetFromStart is unsigned 64-bit. + * To resolve we just need to do an initial seek from the start, and then a series of offset seeks to make up the remainder. */ + if (offsetFromStart > 0x7FFFFFFF) + { + drflac_uint64 bytesRemaining = offsetFromStart; + if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) + return DRFLAC_FALSE; + bytesRemaining -= 0x7FFFFFFF; + + while (bytesRemaining > 0x7FFFFFFF) + { + if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_current)) + return DRFLAC_FALSE; + bytesRemaining -= 0x7FFFFFFF; + } + + if (bytesRemaining > 0) + { + if (!bs->onSeek(bs->pUserData, (int)bytesRemaining, drflac_seek_origin_current)) + return DRFLAC_FALSE; + } + } + else + { + if (!bs->onSeek(bs->pUserData, (int)offsetFromStart, drflac_seek_origin_start)) + return DRFLAC_FALSE; + } + + /* The cache should be reset to force a reload of fresh data from the client. */ + drflac__reset_cache(bs); + return DRFLAC_TRUE; +} + + +static drflac_result drflac__read_utf8_coded_number(drflac_bs* bs, drflac_uint64* pNumberOut, drflac_uint8* pCRCOut) +{ + drflac_uint64 result; + int i; + int byteCount = 1; + unsigned char utf8[7] = {0}; + drflac_uint8 crc; + + drflac_assert(bs != NULL); + drflac_assert(pNumberOut != NULL); + + crc = *pCRCOut; + + if (!drflac__read_uint8(bs, 8, utf8)) + { + *pNumberOut = 0; + return DRFLAC_END_OF_STREAM; + } + crc = drflac_crc8(crc, utf8[0], 8); + + if ((utf8[0] & 0x80) == 0) + { + *pNumberOut = utf8[0]; + *pCRCOut = crc; + return DRFLAC_SUCCESS; + } + + if ((utf8[0] & 0xE0) == 0xC0) + byteCount = 2; + else if ((utf8[0] & 0xF0) == 0xE0) + byteCount = 3; + else if ((utf8[0] & 0xF8) == 0xF0) + byteCount = 4; + else if ((utf8[0] & 0xFC) == 0xF8) + byteCount = 5; + else if ((utf8[0] & 0xFE) == 0xFC) + byteCount = 6; + else if ((utf8[0] & 0xFF) == 0xFE) + byteCount = 7; + else + { + *pNumberOut = 0; + return DRFLAC_CRC_MISMATCH; /* Bad UTF-8 encoding. */ + } + + /* Read extra bytes. */ + drflac_assert(byteCount > 1); + + result = (drflac_uint64)(utf8[0] & (0xFF >> (byteCount + 1))); + for (i = 1; i < byteCount; ++i) + { + if (!drflac__read_uint8(bs, 8, utf8 + i)) + { + *pNumberOut = 0; + return DRFLAC_END_OF_STREAM; + } + crc = drflac_crc8(crc, utf8[i], 8); + + result = (result << 6) | (utf8[i] & 0x3F); + } + + *pNumberOut = result; + *pCRCOut = crc; + return DRFLAC_SUCCESS; +} + + + + +/* The next two functions are responsible for calculating the prediction. + * + * When the bits per sample is >16 we need to use 64-bit integer arithmetic because otherwise we'll run out of precision. It's + * safe to assume this will be slower on 32-bit platforms so we use a more optimal solution when the bits per sample is <=16. + */ +static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_32(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples) +{ + drflac_int32 prediction = 0; + + drflac_assert(order <= 32); + + /* 32-bit version. + + * VC++ optimizes this to a single jmp. I've not yet verified this for other compilers. */ + + switch (order) + { + case 32: prediction += coefficients[31] * pDecodedSamples[-32]; + case 31: prediction += coefficients[30] * pDecodedSamples[-31]; + case 30: prediction += coefficients[29] * pDecodedSamples[-30]; + case 29: prediction += coefficients[28] * pDecodedSamples[-29]; + case 28: prediction += coefficients[27] * pDecodedSamples[-28]; + case 27: prediction += coefficients[26] * pDecodedSamples[-27]; + case 26: prediction += coefficients[25] * pDecodedSamples[-26]; + case 25: prediction += coefficients[24] * pDecodedSamples[-25]; + case 24: prediction += coefficients[23] * pDecodedSamples[-24]; + case 23: prediction += coefficients[22] * pDecodedSamples[-23]; + case 22: prediction += coefficients[21] * pDecodedSamples[-22]; + case 21: prediction += coefficients[20] * pDecodedSamples[-21]; + case 20: prediction += coefficients[19] * pDecodedSamples[-20]; + case 19: prediction += coefficients[18] * pDecodedSamples[-19]; + case 18: prediction += coefficients[17] * pDecodedSamples[-18]; + case 17: prediction += coefficients[16] * pDecodedSamples[-17]; + case 16: prediction += coefficients[15] * pDecodedSamples[-16]; + case 15: prediction += coefficients[14] * pDecodedSamples[-15]; + case 14: prediction += coefficients[13] * pDecodedSamples[-14]; + case 13: prediction += coefficients[12] * pDecodedSamples[-13]; + case 12: prediction += coefficients[11] * pDecodedSamples[-12]; + case 11: prediction += coefficients[10] * pDecodedSamples[-11]; + case 10: prediction += coefficients[ 9] * pDecodedSamples[-10]; + case 9: prediction += coefficients[ 8] * pDecodedSamples[- 9]; + case 8: prediction += coefficients[ 7] * pDecodedSamples[- 8]; + case 7: prediction += coefficients[ 6] * pDecodedSamples[- 7]; + case 6: prediction += coefficients[ 5] * pDecodedSamples[- 6]; + case 5: prediction += coefficients[ 4] * pDecodedSamples[- 5]; + case 4: prediction += coefficients[ 3] * pDecodedSamples[- 4]; + case 3: prediction += coefficients[ 2] * pDecodedSamples[- 3]; + case 2: prediction += coefficients[ 1] * pDecodedSamples[- 2]; + case 1: prediction += coefficients[ 0] * pDecodedSamples[- 1]; + } + + return (drflac_int32)(prediction >> shift); +} + +static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_64(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples) +{ + drflac_int64 prediction; + drflac_assert(order <= 32); + + /* 64-bit version. + + * This method is faster on the 32-bit build when compiling with VC++. See note below. + */ + +#ifndef DRFLAC_64BIT + if (order == 8) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7]; + prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8]; + } + else if (order == 7) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7]; + } + else if (order == 3) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + } + else if (order == 6) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + } + else if (order == 5) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + } + else if (order == 4) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + } + else if (order == 12) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7]; + prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8]; + prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9]; + prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10]; + prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11]; + prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12]; + } + else if (order == 2) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + } + else if (order == 1) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + } + else if (order == 10) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7]; + prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8]; + prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9]; + prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10]; + } + else if (order == 9) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7]; + prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8]; + prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9]; + } + else if (order == 11) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7]; + prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8]; + prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9]; + prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10]; + prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11]; + } + else + { + int j; + prediction = 0; + for (j = 0; j < (int)order; ++j) + prediction += coefficients[j] * (drflac_int64)pDecodedSamples[-j-1]; + } +#endif + + /* VC++ optimizes this to a single jmp instruction, but only the 64-bit build. The 32-bit build generates less efficient code for some + * reason. The ugly version above is faster so we'll just switch between the two depending on the target platform. */ +#ifdef DRFLAC_64BIT + prediction = 0; + + switch (order) + { + case 32: prediction += coefficients[31] * (drflac_int64)pDecodedSamples[-32]; + case 31: prediction += coefficients[30] * (drflac_int64)pDecodedSamples[-31]; + case 30: prediction += coefficients[29] * (drflac_int64)pDecodedSamples[-30]; + case 29: prediction += coefficients[28] * (drflac_int64)pDecodedSamples[-29]; + case 28: prediction += coefficients[27] * (drflac_int64)pDecodedSamples[-28]; + case 27: prediction += coefficients[26] * (drflac_int64)pDecodedSamples[-27]; + case 26: prediction += coefficients[25] * (drflac_int64)pDecodedSamples[-26]; + case 25: prediction += coefficients[24] * (drflac_int64)pDecodedSamples[-25]; + case 24: prediction += coefficients[23] * (drflac_int64)pDecodedSamples[-24]; + case 23: prediction += coefficients[22] * (drflac_int64)pDecodedSamples[-23]; + case 22: prediction += coefficients[21] * (drflac_int64)pDecodedSamples[-22]; + case 21: prediction += coefficients[20] * (drflac_int64)pDecodedSamples[-21]; + case 20: prediction += coefficients[19] * (drflac_int64)pDecodedSamples[-20]; + case 19: prediction += coefficients[18] * (drflac_int64)pDecodedSamples[-19]; + case 18: prediction += coefficients[17] * (drflac_int64)pDecodedSamples[-18]; + case 17: prediction += coefficients[16] * (drflac_int64)pDecodedSamples[-17]; + case 16: prediction += coefficients[15] * (drflac_int64)pDecodedSamples[-16]; + case 15: prediction += coefficients[14] * (drflac_int64)pDecodedSamples[-15]; + case 14: prediction += coefficients[13] * (drflac_int64)pDecodedSamples[-14]; + case 13: prediction += coefficients[12] * (drflac_int64)pDecodedSamples[-13]; + case 12: prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12]; + case 11: prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11]; + case 10: prediction += coefficients[ 9] * (drflac_int64)pDecodedSamples[-10]; + case 9: prediction += coefficients[ 8] * (drflac_int64)pDecodedSamples[- 9]; + case 8: prediction += coefficients[ 7] * (drflac_int64)pDecodedSamples[- 8]; + case 7: prediction += coefficients[ 6] * (drflac_int64)pDecodedSamples[- 7]; + case 6: prediction += coefficients[ 5] * (drflac_int64)pDecodedSamples[- 6]; + case 5: prediction += coefficients[ 4] * (drflac_int64)pDecodedSamples[- 5]; + case 4: prediction += coefficients[ 3] * (drflac_int64)pDecodedSamples[- 4]; + case 3: prediction += coefficients[ 2] * (drflac_int64)pDecodedSamples[- 3]; + case 2: prediction += coefficients[ 1] * (drflac_int64)pDecodedSamples[- 2]; + case 1: prediction += coefficients[ 0] * (drflac_int64)pDecodedSamples[- 1]; + } +#endif + + return (drflac_int32)(prediction >> shift); +} + +#if 0 +/* Reference implementation for reading and decoding samples with residual. This is intentionally left unoptimized for the + * sake of readability and should only be used as a reference. */ +static drflac_bool32 drflac__decode_samples_with_residual__rice__reference(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut) +{ + drflac_assert(bs != NULL); + drflac_assert(count > 0); + drflac_assert(pSamplesOut != NULL); + + for (drflac_uint32 i = 0; i < count; ++i) + { + drflac_uint32 zeroCounter = 0; + for (;;) + { + drflac_uint8 bit; + if (!drflac__read_uint8(bs, 1, &bit)) + return DRFLAC_FALSE; + + if (bit == 0) + zeroCounter += 1; + else + break; + } + + drflac_uint32 decodedRice; + if (riceParam > 0) + { + if (!drflac__read_uint32(bs, riceParam, &decodedRice)) + return DRFLAC_FALSE; + } + else + decodedRice = 0; + + decodedRice |= (zeroCounter << riceParam); + if ((decodedRice & 0x01)) + decodedRice = ~(decodedRice >> 1); + else + decodedRice = (decodedRice >> 1); + + + if (bitsPerSample > 16) + pSamplesOut[i] = decodedRice + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + i); + else + pSamplesOut[i] = decodedRice + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + i); + } + + return DRFLAC_TRUE; +} +#endif + +#if 0 +static drflac_bool32 drflac__read_rice_parts__reference(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut) +{ + drflac_uint32 zeroCounter = 0; + for (;;) { + drflac_uint8 bit; + if (!drflac__read_uint8(bs, 1, &bit)) + return DRFLAC_FALSE; + + if (bit == 0) + zeroCounter += 1; + else + break; + } + + drflac_uint32 decodedRice; + if (riceParam > 0) + { + if (!drflac__read_uint32(bs, riceParam, &decodedRice)) + return DRFLAC_FALSE; + } + else + decodedRice = 0; + + *pZeroCounterOut = zeroCounter; + *pRiceParamPartOut = decodedRice; + return DRFLAC_TRUE; +} +#endif + +static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut) +{ + drflac_uint32 riceLength; + drflac_uint32 riceParamPart; + drflac_uint32 setBitOffsetPlus1; + drflac_cache_t riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam); + drflac_cache_t resultHiShift = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParam; + drflac_uint32 zeroCounter = 0; + while (bs->cache == 0) { + zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs); + if (!drflac__reload_cache(bs)) + return DRFLAC_FALSE; + } + + setBitOffsetPlus1 = drflac__clz(bs->cache); + zeroCounter += setBitOffsetPlus1; + setBitOffsetPlus1 += 1; + + riceLength = setBitOffsetPlus1 + riceParam; + + if (riceLength < DRFLAC_CACHE_L1_BITS_REMAINING(bs)) + { + riceParamPart = (drflac_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> (DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceLength)); + + bs->consumedBits += riceLength; + bs->cache <<= riceLength; + } + else + { + drflac_uint32 bitCountLo; + drflac_cache_t resultHi; + + bs->consumedBits += riceLength; + if (setBitOffsetPlus1 < DRFLAC_CACHE_L1_SIZE_BITS(bs)) + bs->cache <<= setBitOffsetPlus1; + + /* It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them. */ + bitCountLo = bs->consumedBits - DRFLAC_CACHE_L1_SIZE_BITS(bs); + resultHi = bs->cache & riceParamMask; /* <-- This mask is OK because all bits after the first bits are always zero. */ + + if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) { +#ifndef DR_FLAC_NO_CRC + drflac__update_crc16(bs); +#endif + bs->cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]); + bs->consumedBits = 0; +#ifndef DR_FLAC_NO_CRC + bs->crc16Cache = bs->cache; +#endif + } else { + /* Slow path. We need to fetch more data from the client. */ + if (!drflac__reload_cache(bs)) { + return DRFLAC_FALSE; + } + } + + riceParamPart = (drflac_uint32)((resultHi >> resultHiShift) | DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountLo)); + + bs->consumedBits += bitCountLo; + bs->cache <<= bitCountLo; + } + + *pZeroCounterOut = zeroCounter; + *pRiceParamPartOut = riceParamPart; + return DRFLAC_TRUE; +} + + +static drflac_bool32 drflac__decode_samples_with_residual__rice__simple(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut) +{ + drflac_uint32 zeroCountPart; + drflac_uint32 riceParamPart; + drflac_uint32 i = 0; + + drflac_assert(bs != NULL); + drflac_assert(count > 0); + drflac_assert(pSamplesOut != NULL); + + while (i < count) + { + static drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF}; + /* Rice extraction. */ + if (!drflac__read_rice_parts(bs, riceParam, &zeroCountPart, &riceParamPart)) + return DRFLAC_FALSE; + + /* Rice reconstruction. */ + + riceParamPart |= (zeroCountPart << riceParam); + riceParamPart = (riceParamPart >> 1) ^ t[riceParamPart & 0x01]; +#if 0 + riceParamPart = (riceParamPart >> 1) ^ (~(riceParamPart & 0x01) + 1); +#endif + + /* Sample reconstruction. */ + if (bitsPerSample > 16) + { + pSamplesOut[i] = riceParamPart + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + i); + } + else + { + pSamplesOut[i] = riceParamPart + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + i); + } + + i += 1; + } + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__decode_samples_with_residual__rice(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut) +{ +#if 0 + return drflac__decode_samples_with_residual__rice__reference(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut); +#else + return drflac__decode_samples_with_residual__rice__simple(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut); +#endif +} + +/* Reads and seeks past a string of residual values as Rice codes. The decoder should be sitting on the first bit of the Rice codes. */ +static drflac_bool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam) +{ + drflac_uint32 i; + drflac_assert(bs != NULL); + drflac_assert(count > 0); + + for (i = 0; i < count; ++i) + { + drflac_uint32 zeroCountPart; + drflac_uint32 riceParamPart; + if (!drflac__read_rice_parts(bs, riceParam, &zeroCountPart, &riceParamPart)) + return DRFLAC_FALSE; + } + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 unencodedBitsPerSample, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut) +{ + unsigned int i; + drflac_assert(bs != NULL); + drflac_assert(count > 0); + drflac_assert(unencodedBitsPerSample > 0 && unencodedBitsPerSample <= 32); + drflac_assert(pSamplesOut != NULL); + + for (i = 0; i < count; ++i) + { + if (!drflac__read_int32(bs, unencodedBitsPerSample, pSamplesOut + i)) + return DRFLAC_FALSE; + + if (bitsPerSample > 16) + { + pSamplesOut[i] += drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + i); + } + else + { + pSamplesOut[i] += drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + i); + } + } + + return DRFLAC_TRUE; +} + + +/* Reads and decodes the residual for the sub-frame the decoder is currently sitting on. This function should be called + * when the decoder is sitting at the very start of the RESIDUAL block. The first residuals will be ignored. The + * and parameters are used to determine how many residual values need to be decoded. */ +static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 blockSize, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples) +{ + drflac_uint8 partitionOrder; + drflac_uint8 residualMethod; + drflac_uint32 samplesInPartition; + drflac_uint32 partitionsRemaining; + + drflac_assert(bs != NULL); + drflac_assert(blockSize != 0); + drflac_assert(pDecodedSamples != NULL); /* <-- Should we allow NULL, in which case we just seek past the residual rather than do a full decode? */ + + if (!drflac__read_uint8(bs, 2, &residualMethod)) + return DRFLAC_FALSE; + + if (residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) + return DRFLAC_FALSE; /* Unknown or unsupported residual coding method. */ + + /* Ignore the first values. */ + pDecodedSamples += order; + + + if (!drflac__read_uint8(bs, 4, &partitionOrder)) + return DRFLAC_FALSE; + + /* From the FLAC spec: + * The Rice partition order in a Rice-coded residual section must be less than or equal to 8. */ + if (partitionOrder > 8) + return DRFLAC_FALSE; + + /* Validation check. */ + if ((blockSize / (1 << partitionOrder)) <= order) + return DRFLAC_FALSE; + + samplesInPartition = (blockSize / (1 << partitionOrder)) - order; + partitionsRemaining = (1 << partitionOrder); + + for (;;) + { + drflac_uint8 riceParam = 0; + if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) + { + if (!drflac__read_uint8(bs, 4, &riceParam)) + return DRFLAC_FALSE; + if (riceParam == 16) + riceParam = 0xFF; + } + else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) + { + if (!drflac__read_uint8(bs, 5, &riceParam)) + return DRFLAC_FALSE; + if (riceParam == 32) + riceParam = 0xFF; + } + + if (riceParam != 0xFF) + { + if (!drflac__decode_samples_with_residual__rice(bs, bitsPerSample, samplesInPartition, riceParam, order, shift, coefficients, pDecodedSamples)) + return DRFLAC_FALSE; + } + else + { + unsigned char unencodedBitsPerSample = 0; + if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) + return DRFLAC_FALSE; + + if (!drflac__decode_samples_with_residual__unencoded(bs, bitsPerSample, samplesInPartition, unencodedBitsPerSample, order, shift, coefficients, pDecodedSamples)) + return DRFLAC_FALSE; + } + + pDecodedSamples += samplesInPartition; + + + if (partitionsRemaining == 1) + break; + + partitionsRemaining -= 1; + + if (partitionOrder != 0) + samplesInPartition = blockSize / (1 << partitionOrder); + } + + return DRFLAC_TRUE; +} + +/* Reads and seeks past the residual for the sub-frame the decoder is currently sitting on. This function should be called + * when the decoder is sitting at the very start of the RESIDUAL block. The first residuals will be set to 0. The + * and parameters are used to determine how many residual values need to be decoded. */ +static drflac_bool32 drflac__read_and_seek_residual(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 order) +{ + drflac_uint32 partitionsRemaining; + drflac_uint32 samplesInPartition; + drflac_uint8 partitionOrder; + drflac_uint8 residualMethod; + + drflac_assert(bs != NULL); + drflac_assert(blockSize != 0); + + if (!drflac__read_uint8(bs, 2, &residualMethod)) + return DRFLAC_FALSE; + + if (residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) + return DRFLAC_FALSE; /* Unknown or unsupported residual coding method. */ + + if (!drflac__read_uint8(bs, 4, &partitionOrder)) + return DRFLAC_FALSE; + + samplesInPartition = (blockSize / (1 << partitionOrder)) - order; + partitionsRemaining = (1 << partitionOrder); + for (;;) + { + drflac_uint8 riceParam = 0; + if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) + { + if (!drflac__read_uint8(bs, 4, &riceParam)) + return DRFLAC_FALSE; + if (riceParam == 16) + riceParam = 0xFF; + } + else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) { + if (!drflac__read_uint8(bs, 5, &riceParam)) + return DRFLAC_FALSE; + if (riceParam == 32) + riceParam = 0xFF; + } + + if (riceParam != 0xFF) + { + if (!drflac__read_and_seek_residual__rice(bs, samplesInPartition, riceParam)) + return DRFLAC_FALSE; + } + else + { + unsigned char unencodedBitsPerSample = 0; + if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) + return DRFLAC_FALSE; + + if (!drflac__seek_bits(bs, unencodedBitsPerSample * samplesInPartition)) + return DRFLAC_FALSE; + } + + if (partitionsRemaining == 1) + break; + + partitionsRemaining -= 1; + samplesInPartition = blockSize / (1 << partitionOrder); + } + + return DRFLAC_TRUE; +} + + +static drflac_bool32 drflac__decode_samples__constant(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_int32* pDecodedSamples) +{ + drflac_uint32 i; + /* Only a single sample needs to be decoded here. */ + drflac_int32 sample; + if (!drflac__read_int32(bs, bitsPerSample, &sample)) + return DRFLAC_FALSE; + + /* We don't really need to expand this, but it does simplify the process of reading samples. If this becomes a performance issue (unlikely) + * we'll want to look at a more efficient way. */ + for (i = 0; i < blockSize; ++i) + pDecodedSamples[i] = sample; + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_int32* pDecodedSamples) +{ + drflac_uint32 i; + for (i = 0; i < blockSize; ++i) + { + drflac_int32 sample; + if (!drflac__read_int32(bs, bitsPerSample, &sample)) + return DRFLAC_FALSE; + + pDecodedSamples[i] = sample; + } + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__decode_samples__fixed(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples) +{ + drflac_uint32 i; + drflac_int32 lpcCoefficientsTable[5][4] = { + {0, 0, 0, 0}, + {1, 0, 0, 0}, + {2, -1, 0, 0}, + {3, -3, 1, 0}, + {4, -6, 4, -1} + }; + + /* Warm up samples and coefficients. */ + for (i = 0; i < lpcOrder; ++i) + { + drflac_int32 sample; + if (!drflac__read_int32(bs, bitsPerSample, &sample)) + return DRFLAC_FALSE; + + pDecodedSamples[i] = sample; + } + + + if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, 0, lpcCoefficientsTable[lpcOrder], pDecodedSamples)) + return DRFLAC_FALSE; + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__decode_samples__lpc(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples) +{ + drflac_uint8 i; + drflac_uint8 lpcPrecision; + drflac_int8 lpcShift; + drflac_int32 coefficients[32]; + + /* Warm up samples. */ + for (i = 0; i < lpcOrder; ++i) + { + drflac_int32 sample; + if (!drflac__read_int32(bs, bitsPerSample, &sample)) + return DRFLAC_FALSE; + + pDecodedSamples[i] = sample; + } + + if (!drflac__read_uint8(bs, 4, &lpcPrecision)) + return DRFLAC_FALSE; + if (lpcPrecision == 15) + return DRFLAC_FALSE; /* Invalid. */ + lpcPrecision += 1; + + + if (!drflac__read_int8(bs, 5, &lpcShift)) + return DRFLAC_FALSE; + + for (i = 0; i < lpcOrder; ++i) + { + if (!drflac__read_int32(bs, lpcPrecision, coefficients + i)) + return DRFLAC_FALSE; + } + + if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, lpcShift, coefficients, pDecodedSamples)) + return DRFLAC_FALSE; + + return DRFLAC_TRUE; +} + + +static drflac_bool32 drflac__read_next_frame_header(drflac_bs* bs, drflac_uint8 streaminfoBitsPerSample, drflac_frame_header* header) +{ + const drflac_uint32 sampleRateTable[12] = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000}; + const drflac_uint8 bitsPerSampleTable[8] = {0, 8, 12, (drflac_uint8)-1, 16, 20, 24, (drflac_uint8)-1}; /* -1 = reserved. */ + + drflac_assert(bs != NULL); + drflac_assert(header != NULL); + + /* Keep looping until we find a valid sync code. */ + for (;;) + { + drflac_bool32 isVariableBlockSize = false; + drflac_uint8 blockSize = 0; + drflac_uint8 blockingStrategy = 0; + drflac_uint8 crc8 = 0xCE; /* 0xCE = drflac_crc8(0, 0x3FFE, 14); */ + drflac_uint8 reserved = 0; + drflac_uint8 sampleRate = 0; + drflac_uint8 channelAssignment = 0; + drflac_uint8 bitsPerSample = 0; + + if (!drflac__find_and_seek_to_next_sync_code(bs)) + return DRFLAC_FALSE; + + if (!drflac__read_uint8(bs, 1, &reserved)) + return DRFLAC_FALSE; + crc8 = drflac_crc8(crc8, reserved, 1); + + if (!drflac__read_uint8(bs, 1, &blockingStrategy)) + return DRFLAC_FALSE; + crc8 = drflac_crc8(crc8, blockingStrategy, 1); + + if (!drflac__read_uint8(bs, 4, &blockSize)) + return DRFLAC_FALSE; + crc8 = drflac_crc8(crc8, blockSize, 4); + + if (!drflac__read_uint8(bs, 4, &sampleRate)) + return DRFLAC_FALSE; + crc8 = drflac_crc8(crc8, sampleRate, 4); + + if (!drflac__read_uint8(bs, 4, &channelAssignment)) + return DRFLAC_FALSE; + crc8 = drflac_crc8(crc8, channelAssignment, 4); + + if (!drflac__read_uint8(bs, 3, &bitsPerSample)) + return DRFLAC_FALSE; + crc8 = drflac_crc8(crc8, bitsPerSample, 3); + + if (!drflac__read_uint8(bs, 1, &reserved)) + return DRFLAC_FALSE; + crc8 = drflac_crc8(crc8, reserved, 1); + + isVariableBlockSize = blockingStrategy == 1; + + if (isVariableBlockSize) + { + drflac_uint64 sampleNumber; + drflac_result result = drflac__read_utf8_coded_number(bs, &sampleNumber, &crc8); + if (result != DRFLAC_SUCCESS) + { + if (result == DRFLAC_END_OF_STREAM) + return DRFLAC_FALSE; + else + continue; + } + header->frameNumber = 0; + header->sampleNumber = sampleNumber; + } + else + { + drflac_uint64 frameNumber = 0; + drflac_result result = drflac__read_utf8_coded_number(bs, &frameNumber, &crc8); + if (result != DRFLAC_SUCCESS) + { + if (result == DRFLAC_END_OF_STREAM) + return DRFLAC_FALSE; + else + continue; + } + header->frameNumber = (drflac_uint32)frameNumber; /* <-- Safe cast. */ + header->sampleNumber = 0; + } + + + if (blockSize == 1) + header->blockSize = 192; + else if (blockSize >= 2 && blockSize <= 5) + header->blockSize = 576 * (1 << (blockSize - 2)); + else if (blockSize == 6) + { + if (!drflac__read_uint16(bs, 8, &header->blockSize)) + return DRFLAC_FALSE; + crc8 = drflac_crc8(crc8, header->blockSize, 8); + header->blockSize += 1; + } + else if (blockSize == 7) + { + if (!drflac__read_uint16(bs, 16, &header->blockSize)) + return DRFLAC_FALSE; + crc8 = drflac_crc8(crc8, header->blockSize, 16); + header->blockSize += 1; + } + else + header->blockSize = 256 * (1 << (blockSize - 8)); + + if (sampleRate <= 11) + header->sampleRate = sampleRateTable[sampleRate]; + else if (sampleRate == 12) + { + if (!drflac__read_uint32(bs, 8, &header->sampleRate)) + return DRFLAC_FALSE; + crc8 = drflac_crc8(crc8, header->sampleRate, 8); + header->sampleRate *= 1000; + } + else if (sampleRate == 13) + { + if (!drflac__read_uint32(bs, 16, &header->sampleRate)) + return DRFLAC_FALSE; + crc8 = drflac_crc8(crc8, header->sampleRate, 16); + } + else if (sampleRate == 14) + { + if (!drflac__read_uint32(bs, 16, &header->sampleRate)) + return DRFLAC_FALSE; + crc8 = drflac_crc8(crc8, header->sampleRate, 16); + header->sampleRate *= 10; + } + else + continue; /* Invalid. Assume an invalid block. */ + + header->channelAssignment = channelAssignment; + + header->bitsPerSample = bitsPerSampleTable[bitsPerSample]; + if (header->bitsPerSample == 0) + header->bitsPerSample = streaminfoBitsPerSample; + + if (!drflac__read_uint8(bs, 8, &header->crc8)) + return DRFLAC_FALSE; + +#ifndef DR_FLAC_NO_CRC + if (header->crc8 != crc8) + continue; /* CRC mismatch. Loop back to the top and find the next sync code. */ +#endif + return DRFLAC_TRUE; + } +} + +static drflac_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe) +{ + int type; + drflac_uint8 header; + if (!drflac__read_uint8(bs, 8, &header)) + return DRFLAC_FALSE; + + /* First bit should always be 0. */ + if ((header & 0x80) != 0) + return DRFLAC_FALSE; + + type = (header & 0x7E) >> 1; + if (type == 0) + pSubframe->subframeType = DRFLAC_SUBFRAME_CONSTANT; + else if (type == 1) + pSubframe->subframeType = DRFLAC_SUBFRAME_VERBATIM; + else + { + if ((type & 0x20) != 0) { + pSubframe->subframeType = DRFLAC_SUBFRAME_LPC; + pSubframe->lpcOrder = (type & 0x1F) + 1; + } else if ((type & 0x08) != 0) { + pSubframe->subframeType = DRFLAC_SUBFRAME_FIXED; + pSubframe->lpcOrder = (type & 0x07); + if (pSubframe->lpcOrder > 4) { + pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED; + pSubframe->lpcOrder = 0; + } + } else { + pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED; + } + } + + if (pSubframe->subframeType == DRFLAC_SUBFRAME_RESERVED) + return DRFLAC_FALSE; + + /* Wasted bits per sample. */ + pSubframe->wastedBitsPerSample = 0; + if ((header & 0x01) == 1) + { + unsigned int wastedBitsPerSample; + if (!drflac__seek_past_next_set_bit(bs, &wastedBitsPerSample)) + return DRFLAC_FALSE; + pSubframe->wastedBitsPerSample = (unsigned char)wastedBitsPerSample + 1; + } + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, drflac_int32* pDecodedSamplesOut) +{ + drflac_subframe* pSubframe = NULL; + drflac_assert(bs != NULL); + drflac_assert(frame != NULL); + + pSubframe = frame->subframes + subframeIndex; + if (!drflac__read_subframe_header(bs, pSubframe)) + return DRFLAC_FALSE; + + /* Side channels require an extra bit per sample. Took a while to figure that one out... */ + pSubframe->bitsPerSample = frame->header.bitsPerSample; + if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) { + pSubframe->bitsPerSample += 1; + } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) { + pSubframe->bitsPerSample += 1; + } + + /* Need to handle wasted bits per sample. */ + pSubframe->bitsPerSample -= pSubframe->wastedBitsPerSample; + pSubframe->pDecodedSamples = pDecodedSamplesOut; + + switch (pSubframe->subframeType) + { + case DRFLAC_SUBFRAME_CONSTANT: + { + drflac__decode_samples__constant(bs, frame->header.blockSize, pSubframe->bitsPerSample, pSubframe->pDecodedSamples); + } break; + + case DRFLAC_SUBFRAME_VERBATIM: + { + drflac__decode_samples__verbatim(bs, frame->header.blockSize, pSubframe->bitsPerSample, pSubframe->pDecodedSamples); + } break; + + case DRFLAC_SUBFRAME_FIXED: + { + drflac__decode_samples__fixed(bs, frame->header.blockSize, pSubframe->bitsPerSample, pSubframe->lpcOrder, pSubframe->pDecodedSamples); + } break; + + case DRFLAC_SUBFRAME_LPC: + { + drflac__decode_samples__lpc(bs, frame->header.blockSize, pSubframe->bitsPerSample, pSubframe->lpcOrder, pSubframe->pDecodedSamples); + } break; + + default: return DRFLAC_FALSE; + } + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex) +{ + drflac_subframe *pSubframe; + + drflac_assert(bs != NULL); + drflac_assert(frame != NULL); + + pSubframe = frame->subframes + subframeIndex; + if (!drflac__read_subframe_header(bs, pSubframe)) + return DRFLAC_FALSE; + + /* Side channels require an extra bit per sample. Took a while to figure that one out... */ + pSubframe->bitsPerSample = frame->header.bitsPerSample; + if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) { + pSubframe->bitsPerSample += 1; + } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) { + pSubframe->bitsPerSample += 1; + } + + /* Need to handle wasted bits per sample. */ + pSubframe->bitsPerSample -= pSubframe->wastedBitsPerSample; + pSubframe->pDecodedSamples = NULL; + + switch (pSubframe->subframeType) + { + case DRFLAC_SUBFRAME_CONSTANT: + { + if (!drflac__seek_bits(bs, pSubframe->bitsPerSample)) + return DRFLAC_FALSE; + } break; + + case DRFLAC_SUBFRAME_VERBATIM: + { + unsigned int bitsToSeek = frame->header.blockSize * pSubframe->bitsPerSample; + if (!drflac__seek_bits(bs, bitsToSeek)) + return DRFLAC_FALSE; + } break; + + case DRFLAC_SUBFRAME_FIXED: + { + unsigned int bitsToSeek = pSubframe->lpcOrder * pSubframe->bitsPerSample; + if (!drflac__seek_bits(bs, bitsToSeek)) + return DRFLAC_FALSE; + + if (!drflac__read_and_seek_residual(bs, frame->header.blockSize, pSubframe->lpcOrder)) + return DRFLAC_FALSE; + } break; + + case DRFLAC_SUBFRAME_LPC: + { + unsigned char lpcPrecision; + unsigned int bitsToSeek = pSubframe->lpcOrder * pSubframe->bitsPerSample; + if (!drflac__seek_bits(bs, bitsToSeek)) + return DRFLAC_FALSE; + + if (!drflac__read_uint8(bs, 4, &lpcPrecision)) + return DRFLAC_FALSE; + if (lpcPrecision == 15) + return DRFLAC_FALSE; /* Invalid. */ + lpcPrecision += 1; + + + bitsToSeek = (pSubframe->lpcOrder * lpcPrecision) + 5; /* +5 for shift. */ + if (!drflac__seek_bits(bs, bitsToSeek)) + return DRFLAC_FALSE; + + if (!drflac__read_and_seek_residual(bs, frame->header.blockSize, pSubframe->lpcOrder)) + return DRFLAC_FALSE; + } break; + + default: return DRFLAC_FALSE; + } + + return DRFLAC_TRUE; +} + + +static DRFLAC_INLINE drflac_uint8 drflac__get_channel_count_from_channel_assignment(drflac_int8 channelAssignment) +{ + drflac_uint8 lookup[] = {1, 2, 3, 4, 5, 6, 7, 8, 2, 2, 2}; + + drflac_assert(channelAssignment <= 10); + return lookup[channelAssignment]; +} + +static drflac_result drflac__decode_frame(drflac* pFlac) +{ + drflac_uint16 actualCRC16; + drflac_uint8 paddingSizeInBits; + drflac_uint16 desiredCRC16; + int i, channelCount; + + /* This function should be called while the stream is sitting on the first byte after the frame header. */ + drflac_zero_memory(pFlac->currentFrame.subframes, sizeof(pFlac->currentFrame.subframes)); + + /* The frame block size must never be larger than the maximum block size defined by the FLAC stream. */ + if (pFlac->currentFrame.header.blockSize > pFlac->maxBlockSize) + return DRFLAC_ERROR; + + /* The number of channels in the frame must match the channel count from the STREAMINFO block. */ + channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + if (channelCount != (int)pFlac->channels) + return DRFLAC_ERROR; + + for (i = 0; i < channelCount; ++i) + { + if (!drflac__decode_subframe(&pFlac->bs, &pFlac->currentFrame, i, pFlac->pDecodedSamples + (pFlac->currentFrame.header.blockSize * i))) + return DRFLAC_ERROR; + } + + paddingSizeInBits = DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7; + if (paddingSizeInBits > 0) + { + drflac_uint8 padding = 0; + if (!drflac__read_uint8(&pFlac->bs, paddingSizeInBits, &padding)) + return DRFLAC_END_OF_STREAM; + } + +#ifndef DR_FLAC_NO_CRC + actualCRC16 = drflac__flush_crc16(&pFlac->bs); +#endif + if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) + return DRFLAC_END_OF_STREAM; + +#ifndef DR_FLAC_NO_CRC + if (actualCRC16 != desiredCRC16) + return DRFLAC_CRC_MISMATCH; /* CRC mismatch. */ +#endif + + pFlac->currentFrame.samplesRemaining = pFlac->currentFrame.header.blockSize * channelCount; + + return DRFLAC_SUCCESS; +} + +static drflac_result drflac__seek_frame(drflac* pFlac) +{ +#ifndef DR_FLAC_NO_CRC + drflac_uint16 actualCRC16; +#endif + drflac_uint16 desiredCRC16; + int i; + int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + + for (i = 0; i < channelCount; ++i) + { + if (!drflac__seek_subframe(&pFlac->bs, &pFlac->currentFrame, i)) + return DRFLAC_ERROR; + } + + /* Padding. */ + if (!drflac__seek_bits(&pFlac->bs, DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7)) + return DRFLAC_ERROR; + + /* CRC. */ +#ifndef DR_FLAC_NO_CRC + actualCRC16 = drflac__flush_crc16(&pFlac->bs); +#endif + if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) + return DRFLAC_END_OF_STREAM; + +#ifndef DR_FLAC_NO_CRC + if (actualCRC16 != desiredCRC16) + return DRFLAC_CRC_MISMATCH; /* CRC mismatch. */ +#endif + + return DRFLAC_SUCCESS; +} + +static drflac_bool32 drflac__read_and_decode_next_frame(drflac* pFlac) +{ + drflac_assert(pFlac != NULL); + + for (;;) + { + drflac_result result; + + if (!drflac__read_next_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) + return DRFLAC_FALSE; + + result = drflac__decode_frame(pFlac); + if (result != DRFLAC_SUCCESS) + { + if (result == DRFLAC_CRC_MISMATCH) + continue; /* CRC mismatch. Skip to the next frame. */ + return DRFLAC_FALSE; + } + + return DRFLAC_TRUE; + } +} + + +static void drflac__get_current_frame_sample_range(drflac* pFlac, drflac_uint64* pFirstSampleInFrameOut, drflac_uint64* pLastSampleInFrameOut) +{ + unsigned int channelCount; + drflac_uint64 firstSampleInFrame, lastSampleInFrame; + + drflac_assert(pFlac != NULL); + + channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + + firstSampleInFrame = pFlac->currentFrame.header.sampleNumber; + if (firstSampleInFrame == 0) + firstSampleInFrame = pFlac->currentFrame.header.frameNumber * pFlac->maxBlockSize*channelCount; + + lastSampleInFrame = firstSampleInFrame + (pFlac->currentFrame.header.blockSize*channelCount); + if (lastSampleInFrame > 0) + lastSampleInFrame -= 1; /* Needs to be zero based. */ + + if (pFirstSampleInFrameOut) + *pFirstSampleInFrameOut = firstSampleInFrame; + if (pLastSampleInFrameOut) + *pLastSampleInFrameOut = lastSampleInFrame; +} + +static drflac_bool32 drflac__seek_to_first_frame(drflac* pFlac) +{ + drflac_bool32 result; + + drflac_assert(pFlac != NULL); + + result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos); + + drflac_zero_memory(&pFlac->currentFrame, sizeof(pFlac->currentFrame)); + return result; +} + +static DRFLAC_INLINE drflac_result drflac__seek_to_next_frame(drflac* pFlac) +{ + /* This function should only ever be called while the decoder is sitting on the first byte past the FRAME_HEADER section. */ + drflac_assert(pFlac != NULL); + return drflac__seek_frame(pFlac); +} + +static drflac_bool32 drflac__seek_to_sample__brute_force(drflac* pFlac, drflac_uint64 sampleIndex) +{ + drflac_uint64 runningSampleCount = 0; + + /* We need to find the frame that contains the sample. To do this, we iterate over each frame and inspect it's header. If based on the + * header we can determine that the frame contains the sample, we do a full decode of that frame. */ + if (!drflac__seek_to_first_frame(pFlac)) + return DRFLAC_FALSE; + + for (;;) + { + drflac_uint64 sampleCountInThisFrame; + drflac_uint64 firstSampleInFrame = 0; + drflac_uint64 lastSampleInFrame = 0; + + if (!drflac__read_next_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) + return DRFLAC_FALSE; + + drflac__get_current_frame_sample_range(pFlac, &firstSampleInFrame, &lastSampleInFrame); + + sampleCountInThisFrame = (lastSampleInFrame - firstSampleInFrame) + 1; + if (sampleIndex < (runningSampleCount + sampleCountInThisFrame)) + { + /* The sample should be in this frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend + * it never existed and keep iterating. */ + drflac_result result = drflac__decode_frame(pFlac); + if (result == DRFLAC_SUCCESS) + { + /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */ + drflac_uint64 samplesToDecode = (size_t)(sampleIndex - runningSampleCount); /* <-- Safe cast because the maximum number of samples in a frame is 65535. */ + if (samplesToDecode == 0) + return DRFLAC_TRUE; + return drflac_read_s32(pFlac, samplesToDecode, NULL) != 0; /* <-- If this fails, something bad has happened (it should never fail). */ + } + else + { + if (result == DRFLAC_CRC_MISMATCH) + continue; /* CRC mismatch. Pretend this frame never existed. */ + return DRFLAC_FALSE; + } + } + else + { + /* It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this + * frame never existed and leave the running sample count untouched. */ + drflac_result result = drflac__seek_to_next_frame(pFlac); + if (result == DRFLAC_SUCCESS) + runningSampleCount += sampleCountInThisFrame; + else + { + if (result == DRFLAC_CRC_MISMATCH) + continue; /* CRC mismatch. Pretend this frame never existed. */ + return DRFLAC_FALSE; + } + } + } +} + + +static drflac_bool32 drflac__seek_to_sample__seek_table(drflac* pFlac, drflac_uint64 sampleIndex) +{ + drflac_seekpoint closestSeekpoint = {0, 0, 0}; + drflac_uint32 seekpointCount; + drflac_uint32 seekpointsRemaining; + drflac_uint64 runningSampleCount; + + drflac_assert(pFlac != NULL); + + if (pFlac->seektablePos == 0) + return DRFLAC_FALSE; + + if (!drflac__seek_to_byte(&pFlac->bs, pFlac->seektablePos)) + return DRFLAC_FALSE; + + /* The number of seek points is derived from the size of the SEEKTABLE block. */ + seekpointCount = pFlac->seektableSize / 18; /* 18 = the size of each seek point. */ + if (seekpointCount == 0) + return DRFLAC_FALSE; /* Would this ever happen? */ + + seekpointsRemaining = seekpointCount; + while (seekpointsRemaining > 0) + { + drflac_seekpoint seekpoint; + if (!drflac__read_uint64(&pFlac->bs, 64, &seekpoint.firstSample)) + break; + if (!drflac__read_uint64(&pFlac->bs, 64, &seekpoint.frameOffset)) + break; + if (!drflac__read_uint16(&pFlac->bs, 16, &seekpoint.sampleCount)) + break; + + /* Note that the seekpoint sample is based on a single channel. The input sample (sampleIndex) is based on interleaving, thus + * we need to multiple the seekpoint's sample by the channel count. */ + if (seekpoint.firstSample*pFlac->channels > sampleIndex) + break; + + closestSeekpoint = seekpoint; + seekpointsRemaining -= 1; + } + + /* At this point we should have found the seekpoint closest to our sample. We need to seek to it using basically the same + * technique as we use with the brute force method. */ + if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos + closestSeekpoint.frameOffset)) + return DRFLAC_FALSE; + + runningSampleCount = closestSeekpoint.firstSample*pFlac->channels; + for (;;) + { + drflac_uint64 sampleCountInThisFrame; + drflac_uint64 firstSampleInFrame = 0; + drflac_uint64 lastSampleInFrame = 0; + + if (!drflac__read_next_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) + return DRFLAC_FALSE; + + drflac__get_current_frame_sample_range(pFlac, &firstSampleInFrame, &lastSampleInFrame); + + sampleCountInThisFrame = (lastSampleInFrame - firstSampleInFrame) + 1; + if (sampleIndex < (runningSampleCount + sampleCountInThisFrame)) + { + /* The sample should be in this frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend + * it never existed and keep iterating. */ + drflac_result result = drflac__decode_frame(pFlac); + + if (result == DRFLAC_SUCCESS) + { + /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */ + drflac_uint64 samplesToDecode = (size_t)(sampleIndex - runningSampleCount); /* <-- Safe cast because the maximum number of samples in a frame is 65535. */ + if (samplesToDecode == 0) + return DRFLAC_TRUE; + return drflac_read_s32(pFlac, samplesToDecode, NULL) != 0; /* <-- If this fails, something bad has happened (it should never fail). */ + } + else + { + if (result == DRFLAC_CRC_MISMATCH) + continue; /* CRC mismatch. Pretend this frame never existed. */ + return DRFLAC_FALSE; + } + } + else + { + /* It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this + * frame never existed and leave the running sample count untouched. */ + drflac_result result = drflac__seek_to_next_frame(pFlac); + if (result == DRFLAC_SUCCESS) + runningSampleCount += sampleCountInThisFrame; + else + { + if (result == DRFLAC_CRC_MISMATCH) + continue; /* CRC mismatch. Pretend this frame never existed. */ + return DRFLAC_FALSE; + } + } + } +} + + +#ifndef DR_FLAC_NO_OGG +typedef struct +{ + drflac_uint8 capturePattern[4]; /* Should be "OggS" */ + drflac_uint8 structureVersion; /* Always 0. */ + drflac_uint8 headerType; + drflac_uint64 granulePosition; + drflac_uint32 serialNumber; + drflac_uint32 sequenceNumber; + drflac_uint32 checksum; + drflac_uint8 segmentCount; + drflac_uint8 segmentTable[255]; +} drflac_ogg_page_header; +#endif + +typedef struct +{ + drflac_read_proc onRead; + drflac_seek_proc onSeek; + drflac_meta_proc onMeta; + drflac_container container; + void* pUserData; + void* pUserDataMD; + drflac_uint32 sampleRate; + drflac_uint8 channels; + drflac_uint8 bitsPerSample; + drflac_uint64 totalSampleCount; + drflac_uint16 maxBlockSize; + drflac_uint64 runningFilePos; + drflac_bool32 hasStreamInfoBlock; + drflac_bool32 hasMetadataBlocks; + drflac_bs bs; /* <-- A bit streamer is required for loading data during initialization. */ + drflac_frame_header firstFrameHeader; /* <-- The header of the first frame that was read during relaxed initalization. Only set if there is no STREAMINFO block. */ + +#ifndef DR_FLAC_NO_OGG + drflac_uint32 oggSerial; + drflac_uint64 oggFirstBytePos; + drflac_ogg_page_header oggBosHeader; +#endif +} drflac_init_info; + +static DRFLAC_INLINE void drflac__decode_block_header(drflac_uint32 blockHeader, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize) +{ + blockHeader = drflac__be2host_32(blockHeader); + *isLastBlock = (blockHeader & (0x01 << 31)) >> 31; + *blockType = (blockHeader & (0x7F << 24)) >> 24; + *blockSize = (blockHeader & 0xFFFFFF); +} + +static DRFLAC_INLINE drflac_bool32 drflac__read_and_decode_block_header(drflac_read_proc onRead, void* pUserData, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize) +{ + drflac_uint32 blockHeader; + if (onRead(pUserData, &blockHeader, 4) != 4) { + return DRFLAC_FALSE; + } + + drflac__decode_block_header(blockHeader, isLastBlock, blockType, blockSize); + return DRFLAC_TRUE; +} + +drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo) +{ + drflac_uint32 blockSizes; + drflac_uint64 frameSizes = 0; + drflac_uint64 importantProps; + drflac_uint8 md5[16]; + + /* min/max block size. */ + if (onRead(pUserData, &blockSizes, 4) != 4) + return DRFLAC_FALSE; + + /* min/max frame size. */ + if (onRead(pUserData, &frameSizes, 6) != 6) + return DRFLAC_FALSE; + + /* Sample rate, channels, bits per sample and total sample count. */ + if (onRead(pUserData, &importantProps, 8) != 8) + return DRFLAC_FALSE; + + /* MD5 */ + if (onRead(pUserData, md5, sizeof(md5)) != sizeof(md5)) + return DRFLAC_FALSE; + + blockSizes = drflac__be2host_32(blockSizes); + frameSizes = drflac__be2host_64(frameSizes); + importantProps = drflac__be2host_64(importantProps); + + pStreamInfo->minBlockSize = (blockSizes & 0xFFFF0000) >> 16; + pStreamInfo->maxBlockSize = blockSizes & 0x0000FFFF; + pStreamInfo->minFrameSize = (drflac_uint32)((frameSizes & (drflac_uint64)0xFFFFFF0000000000) >> 40); + pStreamInfo->maxFrameSize = (drflac_uint32)((frameSizes & (drflac_uint64)0x000000FFFFFF0000) >> 16); + pStreamInfo->sampleRate = (drflac_uint32)((importantProps & (drflac_uint64)0xFFFFF00000000000) >> 44); + pStreamInfo->channels = (drflac_uint8 )((importantProps & (drflac_uint64)0x00000E0000000000) >> 41) + 1; + pStreamInfo->bitsPerSample = (drflac_uint8 )((importantProps & (drflac_uint64)0x000001F000000000) >> 36) + 1; + pStreamInfo->totalSampleCount = (importantProps & (drflac_uint64)0x0000000FFFFFFFFF) * pStreamInfo->channels; + drflac_copy_memory(pStreamInfo->md5, md5, sizeof(md5)); + + return DRFLAC_TRUE; +} + +drflac_bool32 drflac__read_and_decode_metadata(drflac* pFlac) +{ + /* We want to keep track of the byte position in the stream of the seektable. At the time of calling this function we know that + * we'll be sitting on byte 42. */ + drflac_uint64 runningFilePos = 42; + drflac_uint64 seektablePos = 0; + drflac_uint32 seektableSize = 0; + + drflac_assert(pFlac != NULL); + + for (;;) + { + drflac_metadata metadata; + drflac_uint8 isLastBlock = 0; + drflac_uint8 blockType; + drflac_uint32 blockSize; + + if (!drflac__read_and_decode_block_header(pFlac->bs.onRead, pFlac->bs.pUserData, &isLastBlock, &blockType, &blockSize)) + return DRFLAC_FALSE; + runningFilePos += 4; + + + metadata.type = blockType; + metadata.pRawData = NULL; + metadata.rawDataSize = 0; + + switch (blockType) + { + case DRFLAC_METADATA_BLOCK_TYPE_APPLICATION: + { + if (pFlac->onMeta) { + void* pRawData = DRFLAC_MALLOC(blockSize); + if (pRawData == NULL) + return DRFLAC_FALSE; + + if (pFlac->bs.onRead(pFlac->bs.pUserData, pRawData, blockSize) != blockSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + metadata.pRawData = pRawData; + metadata.rawDataSize = blockSize; + metadata.data.application.id = drflac__be2host_32(*(drflac_uint32*)pRawData); + metadata.data.application.pData = (const void*)((drflac_uint8*)pRawData + sizeof(drflac_uint32)); + metadata.data.application.dataSize = blockSize - sizeof(drflac_uint32); + pFlac->onMeta(pFlac->pUserDataMD, &metadata); + + DRFLAC_FREE(pRawData); + } + } break; + + case DRFLAC_METADATA_BLOCK_TYPE_SEEKTABLE: + { + seektablePos = runningFilePos; + seektableSize = blockSize; + + if (pFlac->onMeta) + { + drflac_uint32 iSeekpoint; + void* pRawData = DRFLAC_MALLOC(blockSize); + if (pRawData == NULL) + return DRFLAC_FALSE; + + if (pFlac->bs.onRead(pFlac->bs.pUserData, pRawData, blockSize) != blockSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + metadata.pRawData = pRawData; + metadata.rawDataSize = blockSize; + metadata.data.seektable.seekpointCount = blockSize/sizeof(drflac_seekpoint); + metadata.data.seektable.pSeekpoints = (const drflac_seekpoint*)pRawData; + + /* Endian swap. */ + for (iSeekpoint = 0; iSeekpoint < metadata.data.seektable.seekpointCount; ++iSeekpoint) { + drflac_seekpoint* pSeekpoint = (drflac_seekpoint*)pRawData + iSeekpoint; + pSeekpoint->firstSample = drflac__be2host_64(pSeekpoint->firstSample); + pSeekpoint->frameOffset = drflac__be2host_64(pSeekpoint->frameOffset); + pSeekpoint->sampleCount = drflac__be2host_16(pSeekpoint->sampleCount); + } + + pFlac->onMeta(pFlac->pUserDataMD, &metadata); + + DRFLAC_FREE(pRawData); + } + } break; + + case DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT: + { + if (pFlac->onMeta) + { + const char* pRunningData; + void* pRawData = DRFLAC_MALLOC(blockSize); + if (pRawData == NULL) + return DRFLAC_FALSE; + + if (pFlac->bs.onRead(pFlac->bs.pUserData, pRawData, blockSize) != blockSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + metadata.pRawData = pRawData; + metadata.rawDataSize = blockSize; + + pRunningData = (const char*)pRawData; + metadata.data.vorbis_comment.vendorLength = drflac__le2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.vorbis_comment.vendor = pRunningData; pRunningData += metadata.data.vorbis_comment.vendorLength; + metadata.data.vorbis_comment.commentCount = drflac__le2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.vorbis_comment.comments = pRunningData; + pFlac->onMeta(pFlac->pUserDataMD, &metadata); + + DRFLAC_FREE(pRawData); + } + } break; + + case DRFLAC_METADATA_BLOCK_TYPE_CUESHEET: + { + if (pFlac->onMeta) + { + const char* pRunningData; + void* pRawData = DRFLAC_MALLOC(blockSize); + if (pRawData == NULL) + return DRFLAC_FALSE; + + if (pFlac->bs.onRead(pFlac->bs.pUserData, pRawData, blockSize) != blockSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + metadata.pRawData = pRawData; + metadata.rawDataSize = blockSize; + + pRunningData = (const char*)pRawData; + drflac_copy_memory(metadata.data.cuesheet.catalog, pRunningData, 128); pRunningData += 128; + metadata.data.cuesheet.leadInSampleCount = drflac__be2host_64(*(drflac_uint64*)pRunningData); pRunningData += 4; + metadata.data.cuesheet.isCD = ((pRunningData[0] & 0x80) >> 7) != 0; pRunningData += 259; + metadata.data.cuesheet.trackCount = pRunningData[0]; pRunningData += 1; + metadata.data.cuesheet.pTrackData = (const drflac_uint8*)pRunningData; + pFlac->onMeta(pFlac->pUserDataMD, &metadata); + + DRFLAC_FREE(pRawData); + } + } break; + + case DRFLAC_METADATA_BLOCK_TYPE_PICTURE: + { + if (pFlac->onMeta) + { + const char* pRunningData; + void* pRawData = DRFLAC_MALLOC(blockSize); + if (pRawData == NULL) + return DRFLAC_FALSE; + + if (pFlac->bs.onRead(pFlac->bs.pUserData, pRawData, blockSize) != blockSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + metadata.pRawData = pRawData; + metadata.rawDataSize = blockSize; + + pRunningData = (const char*)pRawData; + metadata.data.picture.type = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.mimeLength = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength; + metadata.data.picture.descriptionLength = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.description = pRunningData; + metadata.data.picture.width = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.height = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.colorDepth = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.indexColorCount = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.pictureDataSize = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.pPictureData = (const drflac_uint8*)pRunningData; + pFlac->onMeta(pFlac->pUserDataMD, &metadata); + + DRFLAC_FREE(pRawData); + } + } break; + + case DRFLAC_METADATA_BLOCK_TYPE_PADDING: + { + if (pFlac->onMeta) + { + metadata.data.padding.unused = 0; + + /* Padding doesn't have anything meaningful in it, so just skip over it, but make sure the caller is aware of it by firing the callback. */ + if (!pFlac->bs.onSeek(pFlac->bs.pUserData, blockSize, drflac_seek_origin_current)) + isLastBlock = DRFLAC_TRUE; /* An error occured while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop. */ + else + pFlac->onMeta(pFlac->pUserDataMD, &metadata); + } + } + break; + + case DRFLAC_METADATA_BLOCK_TYPE_INVALID: + { + /* Invalid chunk. Just skip over this one. */ + if (pFlac->onMeta) + { + if (!pFlac->bs.onSeek(pFlac->bs.pUserData, blockSize, drflac_seek_origin_current)) + isLastBlock = DRFLAC_TRUE; /* An error occured while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop. */ + } + } + + default: + { + /* It's an unknown chunk, but not necessarily invalid. There's a chance more metadata blocks might be defined later on, so we + * can at the very least report the chunk to the application and let it look at the raw data. */ + if (pFlac->onMeta) + { + void* pRawData = DRFLAC_MALLOC(blockSize); + if (pRawData == NULL) + return DRFLAC_FALSE; + + if (pFlac->bs.onRead(pFlac->bs.pUserData, pRawData, blockSize) != blockSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + metadata.pRawData = pRawData; + metadata.rawDataSize = blockSize; + pFlac->onMeta(pFlac->pUserDataMD, &metadata); + + DRFLAC_FREE(pRawData); + } + } break; + } + + /* If we're not handling metadata, just skip over the block. If we are, it will have been handled earlier in the switch statement above. */ + if (pFlac->onMeta == NULL && blockSize > 0) + { + if (!pFlac->bs.onSeek(pFlac->bs.pUserData, blockSize, drflac_seek_origin_current)) + isLastBlock = DRFLAC_TRUE; + } + + runningFilePos += blockSize; + if (isLastBlock) + break; + } + + pFlac->seektablePos = seektablePos; + pFlac->seektableSize = seektableSize; + pFlac->firstFramePos = runningFilePos; + + return DRFLAC_TRUE; +} + +drflac_bool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_bool32 relaxed) +{ + drflac_uint8 isLastBlock; + drflac_uint8 blockType; + drflac_uint32 blockSize; + + (void)onSeek; + + /* Pre: The bit stream should be sitting just past the 4-byte id header. */ + + pInit->container = drflac_container_native; + + /* The first metadata block should be the STREAMINFO block. */ + if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) + return DRFLAC_FALSE; + + if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) + { + /* We're opening in strict mode and the first block is not the STREAMINFO block. Error. */ + if (!relaxed) + return DRFLAC_FALSE; + + /* Relaxed mode. To open from here we need to just find the first frame and set the sample rate, etc. to whatever is defined + * for that frame. */ + pInit->hasStreamInfoBlock = DRFLAC_FALSE; + pInit->hasMetadataBlocks = DRFLAC_FALSE; + + if (!drflac__read_next_frame_header(&pInit->bs, 0, &pInit->firstFrameHeader)) + return DRFLAC_FALSE; /* Couldn't find a frame. */ + + if (pInit->firstFrameHeader.bitsPerSample == 0) + return DRFLAC_FALSE; /* Failed to initialize because the first frame depends on the STREAMINFO block, which does not exist. */ + + pInit->sampleRate = pInit->firstFrameHeader.sampleRate; + pInit->channels = drflac__get_channel_count_from_channel_assignment(pInit->firstFrameHeader.channelAssignment); + pInit->bitsPerSample = pInit->firstFrameHeader.bitsPerSample; + pInit->maxBlockSize = 65535; /* <-- See notes here: https://xiph.org/flac/format.html#metadata_block_streaminfo */ + return DRFLAC_TRUE; + } + else + { + drflac_streaminfo streaminfo; + if (!drflac__read_streaminfo(onRead, pUserData, &streaminfo)) + return DRFLAC_FALSE; + + pInit->hasStreamInfoBlock = DRFLAC_TRUE; + pInit->sampleRate = streaminfo.sampleRate; + pInit->channels = streaminfo.channels; + pInit->bitsPerSample = streaminfo.bitsPerSample; + pInit->totalSampleCount = streaminfo.totalSampleCount; + pInit->maxBlockSize = streaminfo.maxBlockSize; /* Don't care about the min block size - only the max (used for determining the size of the memory allocation). */ + pInit->hasMetadataBlocks = !isLastBlock; + + if (onMeta) { + drflac_metadata metadata; + metadata.type = DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO; + metadata.pRawData = NULL; + metadata.rawDataSize = 0; + metadata.data.streaminfo = streaminfo; + onMeta(pUserDataMD, &metadata); + } + + return DRFLAC_TRUE; + } +} + +#ifndef DR_FLAC_NO_OGG +#define DRFLAC_OGG_MAX_PAGE_SIZE 65307 +#define DRFLAC_OGG_CAPTURE_PATTERN_CRC32 1605413199 /* CRC-32 of "OggS". */ + +typedef enum +{ + drflac_ogg_recover_on_crc_mismatch, + drflac_ogg_fail_on_crc_mismatch +} drflac_ogg_crc_mismatch_recovery; + + +static drflac_uint32 drflac__crc32_table[] = { + 0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L, + 0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L, + 0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L, + 0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL, + 0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L, + 0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L, + 0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L, + 0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL, + 0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L, + 0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L, + 0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L, + 0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL, + 0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L, + 0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L, + 0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L, + 0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL, + 0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL, + 0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L, + 0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L, + 0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL, + 0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL, + 0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L, + 0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L, + 0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL, + 0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL, + 0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L, + 0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L, + 0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL, + 0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL, + 0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L, + 0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L, + 0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL, + 0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L, + 0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL, + 0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL, + 0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L, + 0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L, + 0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL, + 0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL, + 0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L, + 0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L, + 0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL, + 0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL, + 0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L, + 0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L, + 0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL, + 0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL, + 0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L, + 0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L, + 0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL, + 0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L, + 0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L, + 0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L, + 0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL, + 0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L, + 0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L, + 0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L, + 0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL, + 0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L, + 0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L, + 0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L, + 0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL, + 0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L, + 0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L +}; + +static DRFLAC_INLINE drflac_uint32 drflac_crc32_byte(drflac_uint32 crc32, drflac_uint8 data) +{ +#ifndef DR_FLAC_NO_CRC + return (crc32 << 8) ^ drflac__crc32_table[(drflac_uint8)((crc32 >> 24) & 0xFF) ^ data]; +#else + (void)data; + return crc32; +#endif +} + +#if 0 +static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint32(drflac_uint32 crc32, drflac_uint32 data) +{ + crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 24) & 0xFF)); + crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 16) & 0xFF)); + crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 8) & 0xFF)); + crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 0) & 0xFF)); + return crc32; +} + +static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint64(drflac_uint32 crc32, drflac_uint64 data) +{ + crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 32) & 0xFFFFFFFF)); + crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 0) & 0xFFFFFFFF)); + return crc32; +} +#endif + +static DRFLAC_INLINE drflac_uint32 drflac_crc32_buffer(drflac_uint32 crc32, drflac_uint8* pData, drflac_uint32 dataSize) +{ + drflac_uint32 i; + + /* This can be optimized. */ + for (i = 0; i < dataSize; ++i) + crc32 = drflac_crc32_byte(crc32, pData[i]); + return crc32; +} + + +static DRFLAC_INLINE drflac_bool32 drflac_ogg__is_capture_pattern(drflac_uint8 pattern[4]) +{ + return pattern[0] == 'O' && pattern[1] == 'g' && pattern[2] == 'g' && pattern[3] == 'S'; +} + +static DRFLAC_INLINE drflac_uint32 drflac_ogg__get_page_header_size(drflac_ogg_page_header* pHeader) +{ + return 27 + pHeader->segmentCount; +} + +static DRFLAC_INLINE drflac_uint32 drflac_ogg__get_page_body_size(drflac_ogg_page_header* pHeader) +{ + int i; + drflac_uint32 pageBodySize = 0; + + for (i = 0; i < pHeader->segmentCount; ++i) + pageBodySize += pHeader->segmentTable[i]; + + return pageBodySize; +} + +drflac_result drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, drflac_uint32* pBytesRead, drflac_uint32* pCRC32) +{ + drflac_uint32 i; + drflac_uint8 data[23]; + + drflac_assert(*pCRC32 == DRFLAC_OGG_CAPTURE_PATTERN_CRC32); + + if (onRead(pUserData, data, 23) != 23) + return DRFLAC_END_OF_STREAM; + *pBytesRead += 23; + + pHeader->structureVersion = data[0]; + pHeader->headerType = data[1]; + drflac_copy_memory(&pHeader->granulePosition, &data[ 2], 8); + drflac_copy_memory(&pHeader->serialNumber, &data[10], 4); + drflac_copy_memory(&pHeader->sequenceNumber, &data[14], 4); + drflac_copy_memory(&pHeader->checksum, &data[18], 4); + pHeader->segmentCount = data[22]; + + /* Calculate the CRC. Note that for the calculation the checksum part of the page needs to be set to 0. */ + data[18] = 0; + data[19] = 0; + data[20] = 0; + data[21] = 0; + + for (i = 0; i < 23; ++i) + *pCRC32 = drflac_crc32_byte(*pCRC32, data[i]); + + if (onRead(pUserData, pHeader->segmentTable, pHeader->segmentCount) != pHeader->segmentCount) + return DRFLAC_END_OF_STREAM; + + *pBytesRead += pHeader->segmentCount; + + for (i = 0; i < pHeader->segmentCount; ++i) + *pCRC32 = drflac_crc32_byte(*pCRC32, pHeader->segmentTable[i]); + + return DRFLAC_SUCCESS; +} + +drflac_result drflac_ogg__read_page_header(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, drflac_uint32* pBytesRead, drflac_uint32* pCRC32) +{ + drflac_uint8 id[4]; + + *pBytesRead = 0; + + if (onRead(pUserData, id, 4) != 4) + return DRFLAC_END_OF_STREAM; + *pBytesRead += 4; + + /* We need to read byte-by-byte until we find the OggS capture pattern. */ + for (;;) + { + if (drflac_ogg__is_capture_pattern(id)) + { + drflac_result result; + *pCRC32 = DRFLAC_OGG_CAPTURE_PATTERN_CRC32; + + result = drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, pHeader, pBytesRead, pCRC32); + if (result == DRFLAC_SUCCESS) + return DRFLAC_SUCCESS; + + if (result == DRFLAC_CRC_MISMATCH) + continue; + return result; + } + else + { + /* The first 4 bytes did not equal the capture pattern. Read the next byte and try again. */ + id[0] = id[1]; + id[1] = id[2]; + id[2] = id[3]; + if (onRead(pUserData, &id[3], 1) != 1) + return DRFLAC_END_OF_STREAM; + *pBytesRead += 1; + } + } +} + + +/* The main part of the Ogg encapsulation is the conversion from the physical Ogg bitstream to the native FLAC bitstream. It works + * in three general stages: Ogg Physical Bitstream -> Ogg/FLAC Logical Bitstream -> FLAC Native Bitstream. dr_flac is architecured + * in such a way that the core sections assume everything is delivered in native format. Therefore, for each encapsulation type + * dr_flac is supporting there needs to be a layer sitting on top of the onRead and onSeek callbacks that ensures the bits read from + * the physical Ogg bitstream are converted and delivered in native FLAC format. */ +typedef struct +{ + drflac_read_proc onRead; /* The original onRead callback from drflac_open() and family. */ + drflac_seek_proc onSeek; /* The original onSeek callback from drflac_open() and family. */ + void* pUserData; /* The user data passed on onRead and onSeek. This is the user data that was passed on drflac_open() and family. */ + drflac_uint64 currentBytePos; /* The position of the byte we are sitting on in the physical byte stream. Used for efficient seeking. */ + drflac_uint64 firstBytePos; /* The position of the first byte in the physical bitstream. Points to the start of the "OggS" identifier of the FLAC bos page. */ + drflac_uint32 serialNumber; /* The serial number of the FLAC audio pages. This is determined by the initial header page that was read during initialization. */ + drflac_ogg_page_header bosPageHeader; /* Used for seeking. */ + drflac_ogg_page_header currentPageHeader; + drflac_uint32 bytesRemainingInPage; + drflac_uint32 pageDataSize; + drflac_uint8 pageData[DRFLAC_OGG_MAX_PAGE_SIZE]; +} drflac_oggbs; /* oggbs = Ogg Bitstream */ + +static size_t drflac_oggbs__read_physical(drflac_oggbs* oggbs, void* bufferOut, size_t bytesToRead) +{ + size_t bytesActuallyRead = oggbs->onRead(oggbs->pUserData, bufferOut, bytesToRead); + oggbs->currentBytePos += bytesActuallyRead; + + return bytesActuallyRead; +} + +static drflac_bool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, drflac_uint64 offset, drflac_seek_origin origin) +{ + if (origin == drflac_seek_origin_start) + { + if (offset <= 0x7FFFFFFF) + { + if (!oggbs->onSeek(oggbs->pUserData, (int)offset, drflac_seek_origin_start)) + return DRFLAC_FALSE; + oggbs->currentBytePos = offset; + + return DRFLAC_TRUE; + } + else + { + if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) + return DRFLAC_FALSE; + oggbs->currentBytePos = offset; + + return drflac_oggbs__seek_physical(oggbs, offset - 0x7FFFFFFF, drflac_seek_origin_current); + } + } + else + { + while (offset > 0x7FFFFFFF) + { + if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, drflac_seek_origin_current)) + return DRFLAC_FALSE; + oggbs->currentBytePos += 0x7FFFFFFF; + offset -= 0x7FFFFFFF; + } + + if (!oggbs->onSeek(oggbs->pUserData, (int)offset, drflac_seek_origin_current)) /* <-- Safe cast thanks to the loop above. */ + return DRFLAC_FALSE; + oggbs->currentBytePos += offset; + + return DRFLAC_TRUE; + } +} + +static drflac_bool32 drflac_oggbs__goto_next_page(drflac_oggbs* oggbs, drflac_ogg_crc_mismatch_recovery recoveryMethod) +{ + drflac_ogg_page_header header; + for (;;) { +#ifndef DR_FLAC_NO_CRC + drflac_uint32 actualCRC32; +#endif + drflac_uint32 pageBodySize; + drflac_uint32 crc32 = 0; + drflac_uint32 bytesRead; + if (drflac_ogg__read_page_header(oggbs->onRead, oggbs->pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) + return DRFLAC_FALSE; + oggbs->currentBytePos += bytesRead; + + pageBodySize = drflac_ogg__get_page_body_size(&header); + if (pageBodySize > DRFLAC_OGG_MAX_PAGE_SIZE) + continue; /* Invalid page size. Assume it's corrupted and just move to the next page. */ + + if (header.serialNumber != oggbs->serialNumber) + { + /* It's not a FLAC page. Skip it. */ + if (pageBodySize > 0 && !drflac_oggbs__seek_physical(oggbs, pageBodySize, drflac_seek_origin_current)) + return DRFLAC_FALSE; + continue; + } + + /* We need to read the entire page and then do a CRC check on it. If there's a CRC mismatch we need to skip this page. */ + if (drflac_oggbs__read_physical(oggbs, oggbs->pageData, pageBodySize) != pageBodySize) + return DRFLAC_FALSE; + oggbs->pageDataSize = pageBodySize; + +#ifndef DR_FLAC_NO_CRC + actualCRC32 = drflac_crc32_buffer(crc32, oggbs->pageData, oggbs->pageDataSize); + if (actualCRC32 != header.checksum) + { + if (recoveryMethod == drflac_ogg_recover_on_crc_mismatch) + continue; /* CRC mismatch. Skip this page. */ + + /* Even though we are failing on a CRC mismatch, we still want our stream to be in a good state. Therefore we + * go to the next valid page to ensure we're in a good state, but return false to let the caller know that the + * seek did not fully complete. */ + drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch); + return DRFLAC_FALSE; + } +#endif + + oggbs->currentPageHeader = header; + oggbs->bytesRemainingInPage = pageBodySize; + return DRFLAC_TRUE; + } +} + +/* Function below is unused at the moment, but I might be re-adding it later. */ +#if 0 +static drflac_uint8 drflac_oggbs__get_current_segment_index(drflac_oggbs* oggbs, drflac_uint8* pBytesRemainingInSeg) +{ + drflac_uint32 bytesConsumedInPage = drflac_ogg__get_page_body_size(&oggbs->currentPageHeader) - oggbs->bytesRemainingInPage; + drflac_uint8 iSeg = 0; + drflac_uint32 iByte = 0; + while (iByte < bytesConsumedInPage) + { + drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg]; + if (iByte + segmentSize > bytesConsumedInPage) + break; + + iSeg += 1; + iByte += segmentSize; + } + + *pBytesRemainingInSeg = oggbs->currentPageHeader.segmentTable[iSeg] - (drflac_uint8)(bytesConsumedInPage - iByte); + return iSeg; +} + +static drflac_bool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs) +{ + /* The current packet ends when we get to the segment with a lacing value of < 255 which is not at the end of a page. */ + for (;;) { + drflac_bool32 atEndOfPage = DRFLAC_FALSE; + + drflac_uint8 bytesRemainingInSeg; + drflac_uint8 iFirstSeg = drflac_oggbs__get_current_segment_index(oggbs, &bytesRemainingInSeg); + + drflac_uint32 bytesToEndOfPacketOrPage = bytesRemainingInSeg; + for (drflac_uint8 iSeg = iFirstSeg; iSeg < oggbs->currentPageHeader.segmentCount; ++iSeg) { + drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg]; + if (segmentSize < 255) + { + if (iSeg == oggbs->currentPageHeader.segmentCount-1) + atEndOfPage = DRFLAC_TRUE; + + break; + } + + bytesToEndOfPacketOrPage += segmentSize; + } + + /* At this point we will have found either the packet or the end of the page. If were at the end of the page we'll + * want to load the next page and keep searching for the end of the packet. */ + drflac_oggbs__seek_physical(oggbs, bytesToEndOfPacketOrPage, drflac_seek_origin_current); + oggbs->bytesRemainingInPage -= bytesToEndOfPacketOrPage; + + if (atEndOfPage) + { + /* We're potentially at the next packet, but we need to check the next page first to be sure because the packet may + * straddle pages. */ + if (!drflac_oggbs__goto_next_page(oggbs)) + return DRFLAC_FALSE; + + /* If it's a fresh packet it most likely means we're at the next packet. */ + if ((oggbs->currentPageHeader.headerType & 0x01) == 0) + return DRFLAC_TRUE; + } + else + { + /* We're at the next packet. */ + return DRFLAC_TRUE; + } + } +} + +static drflac_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs) +{ + /* The bitstream should be sitting on the first byte just after the header of the frame. + + * What we're actually doing here is seeking to the start of the next packet. */ + return drflac_oggbs__seek_to_next_packet(oggbs); +} +#endif + +static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytesToRead) +{ + size_t bytesRead = 0; + drflac_uint8* pRunningBufferOut = NULL; + drflac_oggbs* oggbs = (drflac_oggbs*)pUserData; + + drflac_assert(oggbs != NULL); + + pRunningBufferOut = (drflac_uint8*)bufferOut; + + /* Reading is done page-by-page. If we've run out of bytes in the page we need to move to the next one. */ + while (bytesRead < bytesToRead) + { + size_t bytesRemainingToRead = bytesToRead - bytesRead; + + if (oggbs->bytesRemainingInPage >= bytesRemainingToRead) { + drflac_copy_memory(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), bytesRemainingToRead); + bytesRead += bytesRemainingToRead; + oggbs->bytesRemainingInPage -= (drflac_uint32)bytesRemainingToRead; + break; + } + + /* If we get here it means some of the requested data is contained in the next pages. */ + if (oggbs->bytesRemainingInPage > 0) + { + drflac_copy_memory(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), oggbs->bytesRemainingInPage); + bytesRead += oggbs->bytesRemainingInPage; + pRunningBufferOut += oggbs->bytesRemainingInPage; + oggbs->bytesRemainingInPage = 0; + } + + drflac_assert(bytesRemainingToRead > 0); + if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) + break; /* Failed to go to the next page. Might have simply hit the end of the stream. */ + } + + return bytesRead; +} + +static drflac_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_origin origin) +{ + int bytesSeeked = 0; + drflac_oggbs* oggbs = (drflac_oggbs*)pUserData; + + drflac_assert(oggbs != NULL); + drflac_assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start)); + + /* Seeking is always forward which makes things a lot simpler. */ + if (origin == drflac_seek_origin_start) + { + if (!drflac_oggbs__seek_physical(oggbs, (int)oggbs->firstBytePos, drflac_seek_origin_start)) + return DRFLAC_FALSE; + + if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) + return DRFLAC_FALSE; + + return drflac__on_seek_ogg(pUserData, offset, drflac_seek_origin_current); + } + + drflac_assert(origin == drflac_seek_origin_current); + + while (bytesSeeked < offset) + { + int bytesRemainingToSeek = offset - bytesSeeked; + drflac_assert(bytesRemainingToSeek >= 0); + + if (oggbs->bytesRemainingInPage >= (size_t)bytesRemainingToSeek) + { + oggbs->bytesRemainingInPage -= bytesRemainingToSeek; + break; + } + + /* If we get here it means some of the requested data is contained in the next pages. */ + if (oggbs->bytesRemainingInPage > 0) + { + bytesSeeked += (int)oggbs->bytesRemainingInPage; + oggbs->bytesRemainingInPage = 0; + } + + drflac_assert(bytesRemainingToSeek > 0); + + /* Failed to go to the next page. We either hit the end of the stream or had a CRC mismatch. */ + if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) + return DRFLAC_FALSE; + } + + return DRFLAC_TRUE; +} + +drflac_bool32 drflac_ogg__seek_to_sample(drflac* pFlac, drflac_uint64 sampleIndex) +{ + drflac_uint64 runningSampleCount; + drflac_uint64 runningFrameBytePos; + drflac_uint64 runningGranulePosition = 0; + drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs; + + drflac_uint64 originalBytePos = oggbs->currentBytePos; /* For recovery. */ + + /* First seek to the first frame. */ + if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos)) + return DRFLAC_FALSE; + oggbs->bytesRemainingInPage = 0; + + for (;;) + { + if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) { + drflac_oggbs__seek_physical(oggbs, originalBytePos, drflac_seek_origin_start); + return DRFLAC_FALSE; /* Never did find that sample... */ + } + + runningFrameBytePos = oggbs->currentBytePos - drflac_ogg__get_page_header_size(&oggbs->currentPageHeader) - oggbs->pageDataSize; + if (oggbs->currentPageHeader.granulePosition*pFlac->channels >= sampleIndex) + break; /* The sample is somewhere in the previous page. */ + + /* At this point we know the sample is not in the previous page. It could possibly be in this page. For simplicity we + * disregard any pages that do not begin a fresh packet. */ + if ((oggbs->currentPageHeader.headerType & 0x01) == 0) + { /* <-- Is it a fresh page? */ + if (oggbs->currentPageHeader.segmentTable[0] >= 2) + { + drflac_uint8 firstBytesInPage[2]; + firstBytesInPage[0] = oggbs->pageData[0]; + firstBytesInPage[1] = oggbs->pageData[1]; + + if ((firstBytesInPage[0] == 0xFF) && (firstBytesInPage[1] & 0xFC) == 0xF8) /* <-- Does the page begin with a frame's sync code? */ + runningGranulePosition = oggbs->currentPageHeader.granulePosition*pFlac->channels; + + continue; + } + } + } + + + /* We found the page that that is closest to the sample, so now we need to find it. The first thing to do is seek to the + * start of that page. In the loop above we checked that it was a fresh page which means this page is also the start of + * a new frame. This property means that after we've seeked to the page we can immediately start looping over frames until + * we find the one containing the target sample. */ + if (!drflac_oggbs__seek_physical(oggbs, runningFrameBytePos, drflac_seek_origin_start)) + return DRFLAC_FALSE; + if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) + return DRFLAC_FALSE; + + /* At this point we'll be sitting on the first byte of the frame header of the first frame in the page. We just keep + * looping over these frames until we find the one containing the sample we're after. */ + runningSampleCount = runningGranulePosition; + for (;;) + { + drflac_uint64 sampleCountInThisFrame; + drflac_uint64 firstSampleInFrame = 0; + drflac_uint64 lastSampleInFrame = 0; + /* There are two ways to find the sample and seek past irrelevant frames: + * 1) Use the native FLAC decoder. + * 2) Use Ogg's framing system. + * + * Both of these options have their own pros and cons. Using the native FLAC decoder is slower because it needs to + * do a full decode of the frame. Using Ogg's framing system is faster, but more complicated and involves some code + * duplication for the decoding of frame headers. + * + * Another thing to consider is that using the Ogg framing system will perform direct seeking of the physical Ogg + * bitstream. This is important to consider because it means we cannot read data from the drflac_bs object using the + * standard drflac__*() APIs because that will read in extra data for it's own internal caching which in turn breaks + * the positioning of the read pointer of the physical Ogg bitstream. Therefore, anything that would normally be read + * using the native FLAC decoding APIs, such as drflac__read_next_frame_header(), need to be re-implemented so as to + * avoid the use of the drflac_bs object. + * + * Considering these issues, I have decided to use the slower native FLAC decoding method for the following reasons: + * 1) Seeking is already partially accellerated using Ogg's paging system in the code block above. + * 2) Seeking in an Ogg encapsulated FLAC stream is probably quite uncommon. + * 3) Simplicity. + */ + if (!drflac__read_next_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) + return DRFLAC_FALSE; + + drflac__get_current_frame_sample_range(pFlac, &firstSampleInFrame, &lastSampleInFrame); + + sampleCountInThisFrame = (lastSampleInFrame - firstSampleInFrame) + 1; + if (sampleIndex < (runningSampleCount + sampleCountInThisFrame)) { + /* The sample should be in this frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend + * it never existed and keep iterating. */ + drflac_result result = drflac__decode_frame(pFlac); + if (result == DRFLAC_SUCCESS) { + /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */ + drflac_uint64 samplesToDecode = (size_t)(sampleIndex - runningSampleCount); /* <-- Safe cast because the maximum number of samples in a frame is 65535. */ + if (samplesToDecode == 0) + return DRFLAC_TRUE; + return drflac_read_s32(pFlac, samplesToDecode, NULL) != 0; /* <-- If this fails, something bad has happened (it should never fail). */ + } + else + { + if (result == DRFLAC_CRC_MISMATCH) + continue; /* CRC mismatch. Pretend this frame never existed. */ + return DRFLAC_FALSE; + } + } + else + { + /* It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this + * frame never existed and leave the running sample count untouched. */ + drflac_result result = drflac__seek_to_next_frame(pFlac); + if (result == DRFLAC_SUCCESS) + runningSampleCount += sampleCountInThisFrame; + else + { + if (result == DRFLAC_CRC_MISMATCH) + continue; /* CRC mismatch. Pretend this frame never existed. */ + return DRFLAC_FALSE; + } + } + } +} + + +drflac_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_bool32 relaxed) +{ + /* We'll get here if the first 4 bytes of the stream were the OggS capture pattern, however it doesn't necessarily mean the + * stream includes FLAC encoded audio. To check for this we need to scan the beginning-of-stream page markers and check if + * any match the FLAC specification. Important to keep in mind that the stream may be multiplexed. */ + drflac_ogg_page_header header; + + drflac_uint32 crc32 = DRFLAC_OGG_CAPTURE_PATTERN_CRC32; + drflac_uint32 bytesRead = 0; + /* Pre: The bit stream should be sitting just past the 4-byte OggS capture pattern. */ + (void)relaxed; + + pInit->container = drflac_container_ogg; + pInit->oggFirstBytePos = 0; + + if (drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) + return DRFLAC_FALSE; + pInit->runningFilePos += bytesRead; + + for (;;) + { + int pageBodySize; + /* Break if we're past the beginning of stream page. */ + if ((header.headerType & 0x02) == 0) + return DRFLAC_FALSE; + + /* Check if it's a FLAC header. */ + pageBodySize = drflac_ogg__get_page_body_size(&header); + if (pageBodySize == 51) + { + /* 51 = the lacing value of the FLAC header packet. + * It could be a FLAC page... */ + drflac_uint32 bytesRemainingInPage = pageBodySize; + + drflac_uint8 packetType; + if (onRead(pUserData, &packetType, 1) != 1) + return DRFLAC_FALSE; + + bytesRemainingInPage -= 1; + if (packetType == 0x7F) + { + /* Increasingly more likely to be a FLAC page... */ + drflac_uint8 sig[4]; + if (onRead(pUserData, sig, 4) != 4) + return DRFLAC_FALSE; + + bytesRemainingInPage -= 4; + if (sig[0] == 'F' && sig[1] == 'L' && sig[2] == 'A' && sig[3] == 'C') { + /* Almost certainly a FLAC page... */ + drflac_uint8 mappingVersion[2]; + if (onRead(pUserData, mappingVersion, 2) != 2) + return DRFLAC_FALSE; + + if (mappingVersion[0] != 1) + return DRFLAC_FALSE; /* Only supporting version 1.x of the Ogg mapping. */ + + /* The next 2 bytes are the non-audio packets, not including this one. We don't care about this because we're going to + * be handling it in a generic way based on the serial number and packet types. */ + if (!onSeek(pUserData, 2, drflac_seek_origin_current)) + return DRFLAC_FALSE; + + /* Expecting the native FLAC signature "fLaC". */ + if (onRead(pUserData, sig, 4) != 4) + return DRFLAC_FALSE; + + if (sig[0] == 'f' && sig[1] == 'L' && sig[2] == 'a' && sig[3] == 'C') + { + drflac_streaminfo streaminfo; + /* The remaining data in the page should be the STREAMINFO block. */ + drflac_uint8 isLastBlock; + drflac_uint8 blockType; + drflac_uint32 blockSize; + if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) + return DRFLAC_FALSE; + + if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) + return DRFLAC_FALSE; /* Invalid block type. First block must be the STREAMINFO block. */ + + if (drflac__read_streaminfo(onRead, pUserData, &streaminfo)) { + /* Success! */ + pInit->hasStreamInfoBlock = DRFLAC_TRUE; + pInit->sampleRate = streaminfo.sampleRate; + pInit->channels = streaminfo.channels; + pInit->bitsPerSample = streaminfo.bitsPerSample; + pInit->totalSampleCount = streaminfo.totalSampleCount; + pInit->maxBlockSize = streaminfo.maxBlockSize; + pInit->hasMetadataBlocks = !isLastBlock; + + if (onMeta) { + drflac_metadata metadata; + metadata.type = DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO; + metadata.pRawData = NULL; + metadata.rawDataSize = 0; + metadata.data.streaminfo = streaminfo; + onMeta(pUserDataMD, &metadata); + } + + pInit->runningFilePos += pageBodySize; + pInit->oggFirstBytePos = pInit->runningFilePos - 79; /* Subtracting 79 will place us right on top of the "OggS" identifier of the FLAC bos page. */ + pInit->oggSerial = header.serialNumber; + pInit->oggBosHeader = header; + break; + } + else + { + /* Failed to read STREAMINFO block. Aww, so close... */ + return DRFLAC_FALSE; + } + } + else + { + /* Invalid file. */ + return DRFLAC_FALSE; + } + } + else + { + /* Not a FLAC header. Skip it. */ + if (!onSeek(pUserData, bytesRemainingInPage, drflac_seek_origin_current)) + return DRFLAC_FALSE; + } + } + else + { + /* Not a FLAC header. Seek past the entire page and move on to the next. */ + if (!onSeek(pUserData, bytesRemainingInPage, drflac_seek_origin_current)) + return DRFLAC_FALSE; + } + } + else + { + if (!onSeek(pUserData, pageBodySize, drflac_seek_origin_current)) + return DRFLAC_FALSE; + } + + pInit->runningFilePos += pageBodySize; + + /* Read the header of the next page. */ + if (drflac_ogg__read_page_header(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) + return DRFLAC_FALSE; + pInit->runningFilePos += bytesRead; + } + + + /* If we get here it means we found a FLAC audio stream. We should be sitting on the first byte of the header of the next page. The next + * packets in the FLAC logical stream contain the metadata. The only thing left to do in the initialiation phase for Ogg is to create the + * Ogg bistream object. */ + pInit->hasMetadataBlocks = DRFLAC_TRUE; /* <-- Always have at least VORBIS_COMMENT metadata block. */ + return DRFLAC_TRUE; +} +#endif + +drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD) +{ + drflac_uint8 id[4]; + drflac_bool32 relaxed; + + if (pInit == NULL || onRead == NULL || onSeek == NULL) + return DRFLAC_FALSE; + + drflac_zero_memory(pInit, sizeof(*pInit)); + pInit->onRead = onRead; + pInit->onSeek = onSeek; + pInit->onMeta = onMeta; + pInit->container = container; + pInit->pUserData = pUserData; + pInit->pUserDataMD = pUserDataMD; + + pInit->bs.onRead = onRead; + pInit->bs.onSeek = onSeek; + pInit->bs.pUserData = pUserData; + drflac__reset_cache(&pInit->bs); + + + /* If the container is explicitly defined then we can try opening in relaxed mode. */ + relaxed = container != drflac_container_unknown; + + /* Skip over any ID3 tags. */ + for (;;) + { + if (onRead(pUserData, id, 4) != 4) + return DRFLAC_FALSE; /* Ran out of data. */ + pInit->runningFilePos += 4; + + if (id[0] == 'I' && id[1] == 'D' && id[2] == '3') + { + drflac_uint8 flags; + drflac_uint32 headerSize; + drflac_uint8 header[6]; + + if (onRead(pUserData, header, 6) != 6) + return DRFLAC_FALSE; /* Ran out of data. */ + pInit->runningFilePos += 6; + + flags = header[1]; + drflac_copy_memory(&headerSize, header+2, 4); + headerSize = drflac__unsynchsafe_32(drflac__be2host_32(headerSize)); + if (flags & 0x10) + headerSize += 10; + + if (!onSeek(pUserData, headerSize, drflac_seek_origin_current)) + return DRFLAC_FALSE; /* Failed to seek past the tag. */ + pInit->runningFilePos += headerSize; + } + else + break; + } + + if (id[0] == 'f' && id[1] == 'L' && id[2] == 'a' && id[3] == 'C') { + return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed); + } +#ifndef DR_FLAC_NO_OGG + if (id[0] == 'O' && id[1] == 'g' && id[2] == 'g' && id[3] == 'S') { + return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed); + } +#endif + + /* If we get here it means we likely don't have a header. Try opening in relaxed mode, if applicable. */ + if (relaxed) + { + if (container == drflac_container_native) + return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed); +#ifndef DR_FLAC_NO_OGG + if (container == drflac_container_ogg) + return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed); +#endif + } + + /* Unsupported container. */ + return DRFLAC_FALSE; +} + +void drflac__init_from_info(drflac* pFlac, drflac_init_info* pInit) +{ + drflac_assert(pFlac != NULL); + drflac_assert(pInit != NULL); + + drflac_zero_memory(pFlac, sizeof(*pFlac)); + pFlac->bs = pInit->bs; + pFlac->onMeta = pInit->onMeta; + pFlac->pUserDataMD = pInit->pUserDataMD; + pFlac->maxBlockSize = pInit->maxBlockSize; + pFlac->sampleRate = pInit->sampleRate; + pFlac->channels = (drflac_uint8)pInit->channels; + pFlac->bitsPerSample = (drflac_uint8)pInit->bitsPerSample; + pFlac->totalSampleCount = pInit->totalSampleCount; + pFlac->container = pInit->container; +} + +drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD) +{ + drflac_init_info init; + drflac* pFlac; + drflac_uint32 decodedSamplesAllocationSize; + drflac_uint32 allocationSize; + drflac_uint32 wholeSIMDVectorCountPerChannel; + +#ifndef DRFLAC_NO_CPUID + /* CPU support first. */ + drflac__init_cpu_caps(); +#endif + + if (!drflac__init_private(&init, onRead, onSeek, onMeta, container, pUserData, pUserDataMD)) + return NULL; + + /* The size of the allocation for the drflac object needs to be large enough to fit the following: + * 1) The main members of the drflac structure + * 2) A block of memory large enough to store the decoded samples of the largest frame in the stream + * 3) If the container is Ogg, a drflac_oggbs object + * + * The complicated part of the allocation is making sure there's enough room the decoded samples, taking into consideration + * the different SIMD instruction sets. + */ + allocationSize = sizeof(drflac); + + /* The allocation size for decoded frames depends on the number of 32-bit integers that fit inside the largest SIMD vector + * we are supporting. */ + if ((init.maxBlockSize % (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) == 0) { + wholeSIMDVectorCountPerChannel = (init.maxBlockSize / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))); + } else { + wholeSIMDVectorCountPerChannel = (init.maxBlockSize / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) + 1; + } + + decodedSamplesAllocationSize = wholeSIMDVectorCountPerChannel * DRFLAC_MAX_SIMD_VECTOR_SIZE * init.channels; + + allocationSize += decodedSamplesAllocationSize; + allocationSize += DRFLAC_MAX_SIMD_VECTOR_SIZE; /* Allocate extra bytes to ensure we have enough for alignment. */ + +#ifndef DR_FLAC_NO_OGG + /* There's additional data required for Ogg streams. */ + if (init.container == drflac_container_ogg) + allocationSize += sizeof(drflac_oggbs); +#endif + + pFlac = (drflac*)DRFLAC_MALLOC(allocationSize); + drflac__init_from_info(pFlac, &init); + pFlac->pDecodedSamples = (drflac_int32*)drflac_align((size_t)pFlac->pExtraData, DRFLAC_MAX_SIMD_VECTOR_SIZE); + +#ifndef DR_FLAC_NO_OGG + if (init.container == drflac_container_ogg) { + drflac_oggbs* oggbs = (drflac_oggbs*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize); + oggbs->onRead = onRead; + oggbs->onSeek = onSeek; + oggbs->pUserData = pUserData; + oggbs->currentBytePos = init.oggFirstBytePos; + oggbs->firstBytePos = init.oggFirstBytePos; + oggbs->serialNumber = init.oggSerial; + oggbs->bosPageHeader = init.oggBosHeader; + oggbs->bytesRemainingInPage = 0; + + /* The Ogg bistream needs to be layered on top of the original bitstream. */ + pFlac->bs.onRead = drflac__on_read_ogg; + pFlac->bs.onSeek = drflac__on_seek_ogg; + pFlac->bs.pUserData = (void*)oggbs; + pFlac->_oggbs = (void*)oggbs; + } +#endif + + /* Decode metadata before returning. */ + if (init.hasMetadataBlocks) + { + if (!drflac__read_and_decode_metadata(pFlac)) + { + DRFLAC_FREE(pFlac); + return NULL; + } + } + + /* If we get here, but don't have a STREAMINFO block, it means we've opened the stream in relaxed mode and need to decode + * the first frame. */ + if (!init.hasStreamInfoBlock) + { + pFlac->currentFrame.header = init.firstFrameHeader; + do + { + drflac_result result = drflac__decode_frame(pFlac); + if (result == DRFLAC_SUCCESS) + break; + + if (result == DRFLAC_CRC_MISMATCH) + { + if (drflac__read_next_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) + continue; + } + DRFLAC_FREE(pFlac); + return NULL; + } while (1); + } + + return pFlac; +} + +#ifndef DR_FLAC_NO_STDIO +typedef void* drflac_file; + +#if defined(DR_FLAC_NO_WIN32_IO) || !defined(_WIN32) +#include + +static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead) +{ + return fread(bufferOut, 1, bytesToRead, (FILE*)pUserData); +} + +static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin) +{ + drflac_assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start)); + + return fseek((FILE*)pUserData, offset, (origin == drflac_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0; +} + +static drflac_file drflac__open_file_handle(const char* filename) +{ + FILE* pFile; +#ifdef _MSC_VER + if (fopen_s(&pFile, filename, "rb") != 0) { + return NULL; + } +#else + pFile = fopen(filename, "rb"); + if (pFile == NULL) { + return NULL; + } +#endif + + return (drflac_file)pFile; +} + +static void drflac__close_file_handle(drflac_file file) +{ + fclose((FILE*)file); +} +#else +#include + +/* This doesn't seem to be defined for VC6. */ +#ifndef INVALID_SET_FILE_POINTER +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + +static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead) +{ + DWORD bytesRead; + + drflac_assert(bytesToRead < 0xFFFFFFFF); /* dr_flac will never request huge amounts of data at a time. This is a safe assertion. */ + + ReadFile((HANDLE)pUserData, bufferOut, (DWORD)bytesToRead, &bytesRead, NULL); + + return (size_t)bytesRead; +} + +static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin) +{ + drflac_assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start)); + + return SetFilePointer((HANDLE)pUserData, offset, NULL, (origin == drflac_seek_origin_current) ? FILE_CURRENT : FILE_BEGIN) != INVALID_SET_FILE_POINTER; +} + +static drflac_file drflac__open_file_handle(const char* filename) +{ + HANDLE hFile = CreateFileA(filename, FILE_GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + return NULL; + } + + return (drflac_file)hFile; +} + +static void drflac__close_file_handle(drflac_file file) +{ + CloseHandle((HANDLE)file); +} +#endif + + +drflac* drflac_open_file(const char* filename) +{ + drflac_file file = drflac__open_file_handle(filename); + if (file == NULL) { + return NULL; + } + + drflac* pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, (void*)file); + if (pFlac == NULL) { + drflac__close_file_handle(file); + return NULL; + } + + return pFlac; +} + +drflac* drflac_open_file_with_metadata(const char* filename, drflac_meta_proc onMeta, void* pUserData) +{ + drflac_file file = drflac__open_file_handle(filename); + if (file == NULL) { + return NULL; + } + + drflac* pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)file, pUserData); + if (pFlac == NULL) { + drflac__close_file_handle(file); + return pFlac; + } + + return pFlac; +} +#endif /* DR_FLAC_NO_STDIO */ + +static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t bytesToRead) +{ + size_t bytesRemaining; + drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData; + drflac_assert(memoryStream != NULL); + drflac_assert(memoryStream->dataSize >= memoryStream->currentReadPos); + + bytesRemaining = memoryStream->dataSize - memoryStream->currentReadPos; + if (bytesToRead > bytesRemaining) + bytesToRead = bytesRemaining; + + if (bytesToRead > 0) + { + drflac_copy_memory(bufferOut, memoryStream->data + memoryStream->currentReadPos, bytesToRead); + memoryStream->currentReadPos += bytesToRead; + } + + return bytesToRead; +} + +static drflac_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin) +{ + drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData; + drflac_assert(memoryStream != NULL); + drflac_assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start)); + + if (origin == drflac_seek_origin_current) + { + if (memoryStream->currentReadPos + offset <= memoryStream->dataSize) + memoryStream->currentReadPos += offset; + else + memoryStream->currentReadPos = memoryStream->dataSize; /* Trying to seek too far forward. */ + } else { + if ((drflac_uint32)offset <= memoryStream->dataSize) { + memoryStream->currentReadPos = offset; + } else { + memoryStream->currentReadPos = memoryStream->dataSize; /* Trying to seek too far forward. */ + } + } + + return DRFLAC_TRUE; +} + +drflac* drflac_open_memory(const void* data, size_t dataSize) +{ + drflac__memory_stream memoryStream; + drflac* pFlac; + + memoryStream.data = (const unsigned char*)data; + memoryStream.dataSize = dataSize; + memoryStream.currentReadPos = 0; + pFlac = drflac_open(drflac__on_read_memory, drflac__on_seek_memory, &memoryStream); + if (pFlac == NULL) + return NULL; + + pFlac->memoryStream = memoryStream; + + /* This is an awful hack... */ +#ifndef DR_FLAC_NO_OGG + if (pFlac->container == drflac_container_ogg) + { + drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs; + oggbs->pUserData = &pFlac->memoryStream; + } + else +#endif + { + pFlac->bs.pUserData = &pFlac->memoryStream; + } + + return pFlac; +} + +drflac* drflac_open_memory_with_metadata(const void* data, size_t dataSize, drflac_meta_proc onMeta, void* pUserData) +{ + drflac__memory_stream memoryStream; + drflac* pFlac; + + memoryStream.data = (const unsigned char*)data; + memoryStream.dataSize = dataSize; + memoryStream.currentReadPos = 0; + + pFlac = drflac_open_with_metadata_private(drflac__on_read_memory, drflac__on_seek_memory, onMeta, drflac_container_unknown, &memoryStream, pUserData); + if (pFlac == NULL) + return NULL; + + pFlac->memoryStream = memoryStream; + + /* This is an awful hack... */ +#ifndef DR_FLAC_NO_OGG + if (pFlac->container == drflac_container_ogg) + { + drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs; + oggbs->pUserData = &pFlac->memoryStream; + } + else +#endif + { + pFlac->bs.pUserData = &pFlac->memoryStream; + } + + return pFlac; +} + + + +drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData) +{ + return drflac_open_with_metadata_private(onRead, onSeek, NULL, drflac_container_unknown, pUserData, pUserData); +} +drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData) +{ + return drflac_open_with_metadata_private(onRead, onSeek, NULL, container, pUserData, pUserData); +} + +drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData) +{ + return drflac_open_with_metadata_private(onRead, onSeek, onMeta, drflac_container_unknown, pUserData, pUserData); +} +drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData) +{ + return drflac_open_with_metadata_private(onRead, onSeek, onMeta, container, pUserData, pUserData); +} + +void drflac_close(drflac* pFlac) +{ + if (pFlac == NULL) { + return; + } + +#ifndef DR_FLAC_NO_STDIO + /* If we opened the file with drflac_open_file() we will want to close the file handle. We can know whether or not drflac_open_file() + * was used by looking at the callbacks. */ + if (pFlac->bs.onRead == drflac__on_read_stdio) + drflac__close_file_handle((drflac_file)pFlac->bs.pUserData); + +#ifndef DR_FLAC_NO_OGG + /* Need to clean up Ogg streams a bit differently due to the way the bit streaming is chained. */ + if (pFlac->container == drflac_container_ogg) + { + drflac_assert(pFlac->bs.onRead == drflac__on_read_ogg); + drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs; + if (oggbs->onRead == drflac__on_read_stdio) + drflac__close_file_handle((drflac_file)oggbs->pUserData); + } +#endif +#endif + + DRFLAC_FREE(pFlac); +} + +drflac_uint64 drflac__read_s32__misaligned(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int32* bufferOut) +{ + drflac_uint64 samplesRead = 0; + unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + + /* We should never be calling this when the number of samples to read is >= the sample count. */ + drflac_assert(samplesToRead < channelCount); + drflac_assert(pFlac->currentFrame.samplesRemaining > 0 && samplesToRead <= pFlac->currentFrame.samplesRemaining); + + while (samplesToRead > 0) + { + drflac_uint64 totalSamplesInFrame = pFlac->currentFrame.header.blockSize * channelCount; + drflac_uint64 samplesReadFromFrameSoFar = totalSamplesInFrame - pFlac->currentFrame.samplesRemaining; + drflac_uint64 channelIndex = samplesReadFromFrameSoFar % channelCount; + + drflac_uint64 nextSampleInFrame = samplesReadFromFrameSoFar / channelCount; + + int decodedSample = 0; + switch (pFlac->currentFrame.header.channelAssignment) + { + case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE: + { + if (channelIndex == 0) { + decodedSample = pFlac->currentFrame.subframes[channelIndex].pDecodedSamples[nextSampleInFrame]; + } else { + int side = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame]; + int left = pFlac->currentFrame.subframes[channelIndex - 1].pDecodedSamples[nextSampleInFrame]; + decodedSample = left - side; + } + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE: + { + if (channelIndex == 0) { + int side = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame]; + int right = pFlac->currentFrame.subframes[channelIndex + 1].pDecodedSamples[nextSampleInFrame]; + decodedSample = side + right; + } else { + decodedSample = pFlac->currentFrame.subframes[channelIndex].pDecodedSamples[nextSampleInFrame]; + } + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE: + { + int mid; + int side; + if (channelIndex == 0) { + mid = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame]; + side = pFlac->currentFrame.subframes[channelIndex + 1].pDecodedSamples[nextSampleInFrame]; + + mid = (((unsigned int)mid) << 1) | (side & 0x01); + decodedSample = (mid + side) >> 1; + } else { + mid = pFlac->currentFrame.subframes[channelIndex - 1].pDecodedSamples[nextSampleInFrame]; + side = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame]; + + mid = (((unsigned int)mid) << 1) | (side & 0x01); + decodedSample = (mid - side) >> 1; + } + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT: + default: + { + decodedSample = pFlac->currentFrame.subframes[channelIndex].pDecodedSamples[nextSampleInFrame]; + } break; + } + + + decodedSample <<= ((32 - pFlac->bitsPerSample) + pFlac->currentFrame.subframes[channelIndex].wastedBitsPerSample); + + if (bufferOut) { + *bufferOut++ = decodedSample; + } + + samplesRead += 1; + pFlac->currentFrame.samplesRemaining -= 1; + samplesToRead -= 1; + } + + return samplesRead; +} + +drflac_uint64 drflac__seek_forward_by_samples(drflac* pFlac, drflac_uint64 samplesToRead) +{ + drflac_uint64 samplesRead = 0; + while (samplesToRead > 0) { + if (pFlac->currentFrame.samplesRemaining == 0) + { + if (!drflac__read_and_decode_next_frame(pFlac)) + break; /* Couldn't read the next frame, so just break from the loop and return. */ + } + else + { + samplesRead += 1; + pFlac->currentFrame.samplesRemaining -= 1; + samplesToRead -= 1; + } + } + + return samplesRead; +} + +drflac_uint64 drflac_read_s32(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int32* bufferOut) +{ + drflac_uint64 samplesRead = 0; + /* Note that is allowed to be null, in which case this will be treated as something like a seek. */ + if (pFlac == NULL || samplesToRead == 0) + return 0; + + if (bufferOut == NULL) + return drflac__seek_forward_by_samples(pFlac, samplesToRead); + + while (samplesToRead > 0) + { + /* If we've run out of samples in this frame, go to the next. */ + if (pFlac->currentFrame.samplesRemaining == 0) + { + if (!drflac__read_and_decode_next_frame(pFlac)) + break; /* Couldn't read the next frame, so just break from the loop and return. */ + } + else + { + drflac_uint64 alignedSamplesRead; + drflac_uint64 alignedSampleCountPerChannel; + drflac_uint64 firstAlignedSampleInFrame; + unsigned int unusedBitsPerSample; + /* Here is where we grab the samples and interleave them. */ + unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + drflac_uint64 totalSamplesInFrame = pFlac->currentFrame.header.blockSize * channelCount; + drflac_uint64 samplesReadFromFrameSoFar = totalSamplesInFrame - pFlac->currentFrame.samplesRemaining; + drflac_uint64 misalignedSampleCount = samplesReadFromFrameSoFar % channelCount; + if (misalignedSampleCount > 0) + { + drflac_uint64 misalignedSamplesRead = drflac__read_s32__misaligned(pFlac, misalignedSampleCount, bufferOut); + samplesRead += misalignedSamplesRead; + samplesReadFromFrameSoFar += misalignedSamplesRead; + bufferOut += misalignedSamplesRead; + samplesToRead -= misalignedSamplesRead; + } + + alignedSampleCountPerChannel = samplesToRead / channelCount; + if (alignedSampleCountPerChannel > pFlac->currentFrame.samplesRemaining / channelCount) + alignedSampleCountPerChannel = pFlac->currentFrame.samplesRemaining / channelCount; + + firstAlignedSampleInFrame = samplesReadFromFrameSoFar / channelCount; + unusedBitsPerSample = 32 - pFlac->bitsPerSample; + + switch (pFlac->currentFrame.header.channelAssignment) + { + case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE: + { + drflac_uint64 i; + const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame; + const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame; + + for (i = 0; i < alignedSampleCountPerChannel; ++i) { + int left = pDecodedSamples0[i]; + int side = pDecodedSamples1[i]; + int right = left - side; + + bufferOut[i*2+0] = left << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample); + bufferOut[i*2+1] = right << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample); + } + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE: + { + drflac_uint64 i; + const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame; + const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame; + + for (i = 0; i < alignedSampleCountPerChannel; ++i) { + int side = pDecodedSamples0[i]; + int right = pDecodedSamples1[i]; + int left = right + side; + + bufferOut[i*2+0] = left << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample); + bufferOut[i*2+1] = right << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample); + } + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE: + { + drflac_uint64 i; + const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame; + const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame; + + for (i = 0; i < alignedSampleCountPerChannel; ++i) { + int side = pDecodedSamples1[i]; + int mid = (((drflac_uint32)pDecodedSamples0[i]) << 1) | (side & 0x01); + + bufferOut[i*2+0] = ((mid + side) >> 1) << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample); + bufferOut[i*2+1] = ((mid - side) >> 1) << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample); + } + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT: + default: + { + if (pFlac->currentFrame.header.channelAssignment == 1) /* 1 = Stereo */ + { + drflac_uint64 i; + /* Stereo optimized inner loop unroll. */ + const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame; + const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame; + + for (i = 0; i < alignedSampleCountPerChannel; ++i) { + bufferOut[i*2+0] = pDecodedSamples0[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample); + bufferOut[i*2+1] = pDecodedSamples1[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample); + } + } + else + { + drflac_uint64 i; + + /* Generic interleaving. */ + for (i = 0; i < alignedSampleCountPerChannel; ++i) + { + unsigned j; + for (j = 0; j < channelCount; ++j) + { + bufferOut[(i*channelCount)+j] = (pFlac->currentFrame.subframes[j].pDecodedSamples[firstAlignedSampleInFrame + i]) << (unusedBitsPerSample + pFlac->currentFrame.subframes[j].wastedBitsPerSample); + } + } + } + } break; + } + + alignedSamplesRead = alignedSampleCountPerChannel * channelCount; + samplesRead += alignedSamplesRead; + samplesReadFromFrameSoFar += alignedSamplesRead; + bufferOut += alignedSamplesRead; + samplesToRead -= alignedSamplesRead; + pFlac->currentFrame.samplesRemaining -= (unsigned int)alignedSamplesRead; + + /* At this point we may still have some excess samples left to read. */ + if (samplesToRead > 0 && pFlac->currentFrame.samplesRemaining > 0) { + drflac_uint64 excessSamplesRead = 0; + if (samplesToRead < pFlac->currentFrame.samplesRemaining) { + excessSamplesRead = drflac__read_s32__misaligned(pFlac, samplesToRead, bufferOut); + } else { + excessSamplesRead = drflac__read_s32__misaligned(pFlac, pFlac->currentFrame.samplesRemaining, bufferOut); + } + + samplesRead += excessSamplesRead; + samplesReadFromFrameSoFar += excessSamplesRead; + bufferOut += excessSamplesRead; + samplesToRead -= excessSamplesRead; + } + } + } + + return samplesRead; +} + +drflac_uint64 drflac_read_s16(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int16* pBufferOut) +{ + /* This reads samples in 2 passes and can probably be optimized. */ + drflac_uint64 totalSamplesRead = 0; + + while (samplesToRead > 0) + { + drflac_uint64 i; + drflac_int32 samples32[4096]; + drflac_uint64 samplesJustRead = drflac_read_s32(pFlac, (samplesToRead > 4096) ? 4096 : samplesToRead, samples32); + if (samplesJustRead == 0) + break; /* Reached the end. */ + + /* s32 -> s16 */ + for (i = 0; i < samplesJustRead; ++i) + pBufferOut[i] = (drflac_int16)(samples32[i] >> 16); + + totalSamplesRead += samplesJustRead; + samplesToRead -= samplesJustRead; + pBufferOut += samplesJustRead; + } + + return totalSamplesRead; +} + +drflac_uint64 drflac_read_f32(drflac* pFlac, drflac_uint64 samplesToRead, float* pBufferOut) +{ + /* This reads samples in 2 passes and can probably be optimized. */ + drflac_uint64 totalSamplesRead = 0; + + while (samplesToRead > 0) + { + drflac_uint64 i; + drflac_int32 samples32[4096]; + drflac_uint64 samplesJustRead = drflac_read_s32(pFlac, (samplesToRead > 4096) ? 4096 : samplesToRead, samples32); + if (samplesJustRead == 0) + break; /* Reached the end. */ + + /* s32 -> f32 */ + for (i = 0; i < samplesJustRead; ++i) + pBufferOut[i] = (float)(samples32[i] / 2147483648.0); + + totalSamplesRead += samplesJustRead; + samplesToRead -= samplesJustRead; + pBufferOut += samplesJustRead; + } + + return totalSamplesRead; +} + +drflac_bool32 drflac_seek_to_sample(drflac* pFlac, drflac_uint64 sampleIndex) +{ + if (pFlac == NULL) + return DRFLAC_FALSE; + + /* If we don't know where the first frame begins then we can't seek. This will happen when the STREAMINFO block was not present + * when the decoder was opened. */ + if (pFlac->firstFramePos == 0) + return DRFLAC_FALSE; + + if (sampleIndex == 0) + return drflac__seek_to_first_frame(pFlac); + + /* Clamp the sample to the end. */ + if (sampleIndex >= pFlac->totalSampleCount) + sampleIndex = pFlac->totalSampleCount - 1; + + + /* Different techniques depending on encapsulation. Using the native FLAC seektable with Ogg encapsulation is a bit awkward so + * we'll instead use Ogg's natural seeking facility. */ +#ifndef DR_FLAC_NO_OGG + if (pFlac->container == drflac_container_ogg) + return drflac_ogg__seek_to_sample(pFlac, sampleIndex); + else +#endif + { + /* First try seeking via the seek table. If this fails, fall back to a brute force seek which is much slower. */ + if (!drflac__seek_to_sample__seek_table(pFlac, sampleIndex)) + return drflac__seek_to_sample__brute_force(pFlac, sampleIndex); + } + + + return DRFLAC_TRUE; +} + + + +/* High Level APIs */ + +/* I couldn't figure out where SIZE_MAX was defined for VC6. If anybody knows, let me know. */ +#if defined(_MSC_VER) && _MSC_VER <= 1200 +#ifdef DRFLAC_64BIT +#define SIZE_MAX ((drflac_uint64)0xFFFFFFFFFFFFFFFF) +#else +#define SIZE_MAX 0xFFFFFFFF +#endif +#endif + +/* Using a macro as the definition of the drflac__full_decode_and_close_*() API family. Sue me. */ +#define DRFLAC_DEFINE_FULL_DECODE_AND_CLOSE(extension, type) \ +static type* drflac__full_decode_and_close_ ## extension (drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalSampleCountOut)\ +{ \ + drflac_uint64 totalSampleCount; \ + type* pSampleData = NULL; \ + drflac_assert(pFlac != NULL); \ + totalSampleCount = pFlac->totalSampleCount; \ + if (totalSampleCount == 0) { \ + type buffer[4096]; \ + drflac_uint64 samplesRead; \ + size_t sampleDataBufferSize = sizeof(buffer); \ + pSampleData = (type*)DRFLAC_MALLOC(sampleDataBufferSize); \ + if (pSampleData == NULL) \ + goto on_error; \ + while ((samplesRead = (drflac_uint64)drflac_read_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0]), buffer)) > 0) { \ + if (((totalSampleCount + samplesRead) * sizeof(type)) > sampleDataBufferSize) { \ + type *pNewSampleData; \ + sampleDataBufferSize *= 2; \ + pNewSampleData = (type*)DRFLAC_REALLOC(pSampleData, sampleDataBufferSize); \ + if (pNewSampleData == NULL) { \ + DRFLAC_FREE(pSampleData); \ + goto on_error; \ + } \ + \ + pSampleData = pNewSampleData; \ + } \ + \ + drflac_copy_memory(pSampleData + totalSampleCount, buffer, (size_t)(samplesRead*sizeof(type))); \ + totalSampleCount += samplesRead; \ + } \ + \ + /* At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to \ + protect those ears from random noise! */ \ + drflac_zero_memory(pSampleData + totalSampleCount, (size_t)(sampleDataBufferSize - totalSampleCount*sizeof(type))); \ + } else { \ + drflac_uint64 dataSize = totalSampleCount * sizeof(type); \ + if (dataSize > SIZE_MAX) { \ + goto on_error; /* The decoded data is too big. */ \ + } \ + \ + pSampleData = (type*)DRFLAC_MALLOC((size_t)dataSize); /* <-- Safe cast as per the check above. */ \ + if (pSampleData == NULL) { \ + goto on_error; \ + } \ + \ + totalSampleCount = drflac_read_##extension(pFlac, pFlac->totalSampleCount, pSampleData); \ + } \ + \ + if (sampleRateOut) *sampleRateOut = pFlac->sampleRate; \ + if (channelsOut) *channelsOut = pFlac->channels; \ + if (totalSampleCountOut) *totalSampleCountOut = totalSampleCount; \ + \ + drflac_close(pFlac); \ + return pSampleData; \ + \ +on_error: \ + drflac_close(pFlac); \ + return NULL; \ +} + +DRFLAC_DEFINE_FULL_DECODE_AND_CLOSE(s32, drflac_int32) +DRFLAC_DEFINE_FULL_DECODE_AND_CLOSE(s16, drflac_int16) +DRFLAC_DEFINE_FULL_DECODE_AND_CLOSE(f32, float) + +drflac_int32* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount) +{ + drflac* pFlac; + /* Safety. */ + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + pFlac = drflac_open(onRead, onSeek, pUserData); + if (pFlac == NULL) + return NULL; + + return drflac__full_decode_and_close_s32(pFlac, channels, sampleRate, totalSampleCount); +} + +drflac_int16* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount) +{ + drflac* pFlac; + /* Safety. */ + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + pFlac = drflac_open(onRead, onSeek, pUserData); + if (pFlac == NULL) + return NULL; + + return drflac__full_decode_and_close_s16(pFlac, channels, sampleRate, totalSampleCount); +} + +float* drflac_open_and_decode_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount) +{ + drflac* pFlac; + /* Safety. */ + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + pFlac = drflac_open(onRead, onSeek, pUserData); + if (pFlac == NULL) + return NULL; + + return drflac__full_decode_and_close_f32(pFlac, channels, sampleRate, totalSampleCount); +} + +#ifndef DR_FLAC_NO_STDIO +drflac_int32* drflac_open_and_decode_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount) +{ + drflac* pFlac; + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + pFlac = drflac_open_file(filename); + if (pFlac == NULL) + return NULL; + + return drflac__full_decode_and_close_s32(pFlac, channels, sampleRate, totalSampleCount); +} + +drflac_int16* drflac_open_and_decode_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount) +{ + drflac* pFlac; + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + pFlac = drflac_open_file(filename); + if (pFlac == NULL) + return NULL; + + return drflac__full_decode_and_close_s16(pFlac, channels, sampleRate, totalSampleCount); +} + +float* drflac_open_and_decode_file_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount) +{ + drflac* pFlac; + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + pFlac = drflac_open_file(filename); + if (pFlac == NULL) + return NULL; + + return drflac__full_decode_and_close_f32(pFlac, channels, sampleRate, totalSampleCount); +} +#endif + +drflac_int32* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount) +{ + drflac *pFlac; + + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + pFlac = drflac_open_memory(data, dataSize); + if (pFlac == NULL) + return NULL; + + return drflac__full_decode_and_close_s32(pFlac, channels, sampleRate, totalSampleCount); +} + +drflac_int16* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount) +{ + drflac* pFlac; + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + pFlac = drflac_open_memory(data, dataSize); + if (pFlac == NULL) + return NULL; + + return drflac__full_decode_and_close_s16(pFlac, channels, sampleRate, totalSampleCount); +} + +float* drflac_open_and_decode_memory_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount) +{ + drflac* pFlac; + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + pFlac = drflac_open_memory(data, dataSize); + if (pFlac == NULL) + return NULL; + + return drflac__full_decode_and_close_f32(pFlac, channels, sampleRate, totalSampleCount); +} + +void drflac_free(void* pSampleDataReturnedByOpenAndDecode) +{ + DRFLAC_FREE(pSampleDataReturnedByOpenAndDecode); +} + + + + +void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const char* pComments) +{ + if (pIter == NULL) + return; + + pIter->countRemaining = commentCount; + pIter->pRunningData = pComments; +} + +const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut) +{ + const char* pComment; + drflac_uint32 length; + /* Safety. */ + if (pCommentLengthOut) *pCommentLengthOut = 0; + + if (pIter == NULL || pIter->countRemaining == 0 || pIter->pRunningData == NULL) + return NULL; + + length = drflac__le2host_32(*(drflac_uint32*)pIter->pRunningData); + pIter->pRunningData += 4; + + pComment = pIter->pRunningData; + pIter->pRunningData += length; + pIter->countRemaining -= 1; + + if (pCommentLengthOut) *pCommentLengthOut = length; + return pComment; +} +#endif /* DR_FLAC_IMPLEMENTATION */ + +/* +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +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 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. + +For more information, please refer to +*/ diff --git a/deps/dr/dr_mp3.h b/deps/dr/dr_mp3.h new file mode 100644 index 0000000000..9b74cad353 --- /dev/null +++ b/deps/dr/dr_mp3.h @@ -0,0 +1,2745 @@ +#ifndef dr_mp3_h +#define dr_mp3_h + +#define DR_MP3_NO_STDIO + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +typedef int8_t drmp3_int8; +typedef uint8_t drmp3_uint8; +typedef int16_t drmp3_int16; +typedef uint16_t drmp3_uint16; +typedef int32_t drmp3_int32; +typedef uint32_t drmp3_uint32; +typedef int64_t drmp3_int64; +typedef uint64_t drmp3_uint64; +typedef drmp3_uint8 drmp3_bool8; +typedef drmp3_uint32 drmp3_bool32; +#define DRMP3_TRUE 1 +#define DRMP3_FALSE 0 + +#define DRMP3_MAX_SAMPLES_PER_FRAME (1152*2) + + +/* Low Level Push API + * ================== */ +typedef struct +{ + int frame_bytes; + int channels; + int hz; + int layer; + int bitrate_kbps; +} drmp3dec_frame_info; + +typedef struct +{ + float mdct_overlap[2][9*32]; + float qmf_state[15*2*32]; + int reserv; + int free_format_bytes; + unsigned char header[4]; + unsigned char reserv_buf[511]; +} drmp3dec; + +/* Initializes a low level decoder. */ +void drmp3dec_init(drmp3dec *dec); + +/* Reads a frame from a low level decoder. */ +int drmp3dec_decode_frame(drmp3dec *dec, const unsigned char *mp3, int mp3_bytes, short *pcm, drmp3dec_frame_info *info); + + +/* Main API (Pull API) + * ===================*/ + +typedef struct drmp3_src drmp3_src; +typedef drmp3_uint64 (* drmp3_src_read_proc)(drmp3_src* pSRC, drmp3_uint64 frameCount, void* pFramesOut, void* pUserData); /* Returns the number of frames that were read. */ + +typedef enum +{ + drmp3_src_algorithm_none, + drmp3_src_algorithm_linear +} drmp3_src_algorithm; + +#define DRMP3_SRC_CACHE_SIZE_IN_FRAMES 512 +typedef struct +{ + drmp3_src* pSRC; + float pCachedFrames[2 * DRMP3_SRC_CACHE_SIZE_IN_FRAMES]; + drmp3_uint32 cachedFrameCount; + drmp3_uint32 iNextFrame; +} drmp3_src_cache; + +typedef struct +{ + drmp3_uint32 sampleRateIn; + drmp3_uint32 sampleRateOut; + drmp3_uint32 channels; + drmp3_src_algorithm algorithm; + drmp3_uint32 cacheSizeInFrames; /* The number of frames to read from the client at a time. */ +} drmp3_src_config; + +struct drmp3_src +{ + drmp3_src_config config; + drmp3_src_read_proc onRead; + void* pUserData; + float bin[256]; + drmp3_src_cache cache; /* <-- For simplifying and optimizing client -> memory reading. */ + union + { + struct + { + float alpha; + drmp3_bool32 isPrevFramesLoaded : 1; + drmp3_bool32 isNextFramesLoaded : 1; + } linear; + } algo; +}; + +typedef enum +{ + drmp3_seek_origin_start, + drmp3_seek_origin_current +} drmp3_seek_origin; + +/* Callback for when data is read. Return value is the number of bytes actually read. + * + * pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family. + * pBufferOut [out] The output buffer. + * bytesToRead [in] The number of bytes to read. + * + * Returns the number of bytes actually read. + * + * A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until + * either the entire bytesToRead is filled or you have reached the end of the stream. + */ +typedef size_t (* drmp3_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead); + +/* Callback for when data needs to be seeked. + * + * pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family. + * offset [in] The number of bytes to move, relative to the origin. Will never be negative. + * origin [in] The origin of the seek - the current position or the start of the stream. + * + * Returns whether or not the seek was successful. + * + * Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which + * will be either drmp3_seek_origin_start or drmp3_seek_origin_current. + */ +typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek_origin origin); + +typedef struct +{ + drmp3_uint32 outputChannels; + drmp3_uint32 outputSampleRate; +} drmp3_config; + +typedef struct +{ + drmp3dec decoder; + drmp3dec_frame_info frameInfo; + drmp3_uint32 channels; + drmp3_uint32 sampleRate; + drmp3_read_proc onRead; + drmp3_seek_proc onSeek; + void* pUserData; + drmp3_uint32 frameChannels; /* The number of channels in the currently loaded MP3 frame. Internal use only. */ + drmp3_uint32 frameSampleRate; /* The sample rate of the currently loaded MP3 frame. Internal use only */ + drmp3_uint32 framesConsumed; + drmp3_uint32 framesRemaining; + drmp3_int16 frames[DRMP3_MAX_SAMPLES_PER_FRAME]; + drmp3_src src; + size_t dataSize; + size_t dataCapacity; + drmp3_uint8* pData; + drmp3_bool32 atEnd : 1; + struct + { + const drmp3_uint8* pData; + size_t dataSize; + size_t currentReadPos; + } memory; /* Only used for decoders that were opened against a block of memory. */ +} drmp3; + +/* Initializes an MP3 decoder. + * + * onRead [in] The function to call when data needs to be read from the client. + * onSeek [in] The function to call when the read position of the client data needs to move. + * pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek. + * + * Returns true if successful; false otherwise. + * + * Close the loader with drmp3_uninit(). + * + * See also: drmp3_init_file(), drmp3_init_memory(), drmp3_uninit() + */ +drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_config* pConfig); + +/* Initializes an MP3 decoder from a block of memory. + * + * This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for + * the lifetime of the drmp3 object. + * + * The buffer should contain the contents of the entire MP3 file. + */ +drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_config* pConfig); + +#ifndef DR_MP3_NO_STDIO +/* Initializes an MP3 decoder from a file. + * + * This holds the internal FILE object until drmp3_uninit() is called. Keep this in mind if you're caching drmp3 + * objects because the operating system may restrict the number of file handles an application can have open at + * any given time. + */ +drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* filePath, const drmp3_config* pConfig); +#endif + +/* Uninitializes an MP3 decoder. */ +void drmp3_uninit(drmp3* pMP3); + +/* Reads PCM frames as interleaved 32-bit IEEE floating point PCM. + * + * Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames. + */ +drmp3_uint64 drmp3_read_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut); + +/* Seeks to a specific frame. + * + * Note that this is _not_ an MP3 frame, but rather a PCM frame. + */ +drmp3_bool32 drmp3_seek_to_frame(drmp3* pMP3, drmp3_uint64 frameIndex); + + +/* Opens an decodes an entire MP3 stream as a single operation. + * + * pConfig is both an input and output. On input it contains what you want. On output it contains what you got. + * + * Free the returned pointer with drmp3_free(). + */ +float* drmp3_open_and_decode_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount); +float* drmp3_open_and_decode_memory_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount); +#ifndef DR_MP3_NO_STDIO +float* drmp3_open_and_decode_file_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount); +#endif + +/* Frees any memory that was allocated by a public drmp3 API. */ +void drmp3_free(void* p); + +#ifdef __cplusplus +} +#endif +#endif /* dr_mp3_h */ + + +/* + * + * IMPLEMENTATION + * + */ +#ifdef DR_MP3_IMPLEMENTATION +#include +#include +#include +#include /* For INT_MAX */ + +#define DRMP3_MAX_FREE_FORMAT_FRAME_SIZE 2304 /* more than ISO spec's */ +#define DRMP3_MAX_FRAME_SYNC_MATCHES 10 + +#define DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES DRMP3_MAX_FREE_FORMAT_FRAME_SIZE /* MUST be >= 320000/8/32000*1152 = 1440 */ + +#define DRMP3_MAX_BITRESERVOIR_BYTES 511 +#define DRMP3_SHORT_BLOCK_TYPE 2 +#define DRMP3_STOP_BLOCK_TYPE 3 +#define DRMP3_MODE_MONO 3 +#define DRMP3_MODE_JOINT_STEREO 1 +#define DRMP3_HDR_SIZE 4 +#define DRMP3_HDR_IS_MONO(h) (((h[3]) & 0xC0) == 0xC0) +#define DRMP3_HDR_IS_MS_STEREO(h) (((h[3]) & 0xE0) == 0x60) +#define DRMP3_HDR_IS_FREE_FORMAT(h) (((h[2]) & 0xF0) == 0) +#define DRMP3_HDR_IS_CRC(h) (!((h[1]) & 1)) +#define DRMP3_HDR_TEST_PADDING(h) ((h[2]) & 0x2) +#define DRMP3_HDR_TEST_MPEG1(h) ((h[1]) & 0x8) +#define DRMP3_HDR_TEST_NOT_MPEG25(h) ((h[1]) & 0x10) +#define DRMP3_HDR_TEST_I_STEREO(h) ((h[3]) & 0x10) +#define DRMP3_HDR_TEST_MS_STEREO(h) ((h[3]) & 0x20) +#define DRMP3_HDR_GET_STEREO_MODE(h) (((h[3]) >> 6) & 3) +#define DRMP3_HDR_GET_STEREO_MODE_EXT(h) (((h[3]) >> 4) & 3) +#define DRMP3_HDR_GET_LAYER(h) (((h[1]) >> 1) & 3) +#define DRMP3_HDR_GET_BITRATE(h) ((h[2]) >> 4) +#define DRMP3_HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3) +#define DRMP3_HDR_GET_MY_SAMPLE_RATE(h) (DRMP3_HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))*3) +#define DRMP3_HDR_IS_FRAME_576(h) ((h[1] & 14) == 2) +#define DRMP3_HDR_IS_LAYER_1(h) ((h[1] & 6) == 6) + +#define DRMP3_BITS_DEQUANTIZER_OUT -1 +#define DRMP3_MAX_SCF (255 + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210) +#define DRMP3_MAX_SCFI ((DRMP3_MAX_SCF + 3) & ~3) + +#define DRMP3_MIN(a, b) ((a) > (b) ? (b) : (a)) +#define DRMP3_MAX(a, b) ((a) < (b) ? (b) : (a)) + +#if !defined(DR_MP3_NO_SIMD) + +#if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(_M_ARM64) || defined(__x86_64__) || defined(__aarch64__)) +/* x64 always have SSE2, arm64 always have neon, no need for generic code */ +#define DR_MP3_ONLY_SIMD +#endif + +#if (defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))) || ((defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__)) +#if defined(_MSC_VER) +#include +#endif +#include +#define DRMP3_HAVE_SSE 1 +#define DRMP3_HAVE_SIMD 1 +#define DRMP3_VSTORE _mm_storeu_ps +#define DRMP3_VLD _mm_loadu_ps +#define DRMP3_VSET _mm_set1_ps +#define DRMP3_VADD _mm_add_ps +#define DRMP3_VSUB _mm_sub_ps +#define DRMP3_VMUL _mm_mul_ps +#define DRMP3_VMAC(a, x, y) _mm_add_ps(a, _mm_mul_ps(x, y)) +#define DRMP3_VMSB(a, x, y) _mm_sub_ps(a, _mm_mul_ps(x, y)) +#define DRMP3_VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s)) +#define DRMP3_VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3)) +typedef __m128 drmp3_f4; +#if defined(_MSC_VER) || defined(DR_MP3_ONLY_SIMD) +#define drmp3_cpuid __cpuid +#else +static INLINE __attribute__((always_inline)) void drmp3_cpuid(int CPUInfo[], const int InfoType) +{ +#if defined(__PIC__) + __asm__ __volatile__( +#if defined(__x86_64__) + "push %%rbx\n" + "cpuid\n" + "xchgl %%ebx, %1\n" + "pop %%rbx\n" +#else + "xchgl %%ebx, %1\n" + "cpuid\n" + "xchgl %%ebx, %1\n" +#endif + : "=a" (CPUInfo[0]), "=r" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) + : "a" (InfoType)); +#else + __asm__ __volatile__( + "cpuid" + : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) + : "a" (InfoType)); +#endif +} +#endif +static int drmp3_have_simd() +{ +#ifdef DR_MP3_ONLY_SIMD + return 1; +#else + static int g_have_simd; + int CPUInfo[4]; +#ifdef MINIMP3_TEST + static int g_counter; + if (g_counter++ > 100) + goto test_nosimd; +#endif + if (g_have_simd) + return g_have_simd - 1; + drmp3_cpuid(CPUInfo, 0); + if (CPUInfo[0] > 0) + { + drmp3_cpuid(CPUInfo, 1); + g_have_simd = (CPUInfo[3] & (1 << 26)) + 1; /* SSE2 */ + return g_have_simd - 1; + } +#ifdef MINIMP3_TEST +test_nosimd: +#endif + g_have_simd = 1; + return 0; +#endif +} +#elif defined(__ARM_NEON) || defined(__aarch64__) +#include +#define DRMP3_HAVE_SIMD 1 +#define DRMP3_VSTORE vst1q_f32 +#define DRMP3_VLD vld1q_f32 +#define DRMP3_VSET vmovq_n_f32 +#define DRMP3_VADD vaddq_f32 +#define DRMP3_VSUB vsubq_f32 +#define DRMP3_VMUL vmulq_f32 +#define DRMP3_VMAC(a, x, y) vmlaq_f32(a, x, y) +#define DRMP3_VMSB(a, x, y) vmlsq_f32(a, x, y) +#define DRMP3_VMUL_S(x, s) vmulq_f32(x, vmovq_n_f32(s)) +#define DRMP3_VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x))) +typedef float32x4_t drmp3_f4; +static int drmp3_have_simd() +{ /* TODO: detect neon for !DR_MP3_ONLY_SIMD */ + return 1; +} +#else +#define DRMP3_HAVE_SIMD 0 +#ifdef DR_MP3_ONLY_SIMD +#error DR_MP3_ONLY_SIMD used, but SSE/NEON not enabled +#endif +#endif + +#else + +#define DRMP3_HAVE_SIMD 0 + +#endif + +typedef struct +{ + const drmp3_uint8 *buf; + int pos; + int limit; +} drmp3_bs; + +typedef struct +{ + drmp3_uint8 total_bands; + drmp3_uint8 stereo_bands; + drmp3_uint8 bitalloc[64]; + drmp3_uint8 scfcod[64]; + float scf[3*64]; +} drmp3_L12_scale_info; + +typedef struct +{ + drmp3_uint8 tab_offset; + drmp3_uint8 code_tab_width; + drmp3_uint8 band_count; +} drmp3_L12_subband_alloc; + +typedef struct +{ + const drmp3_uint8 *sfbtab; + drmp3_uint16 part_23_length; + drmp3_uint16 big_values; + drmp3_uint16 scalefac_compress; + drmp3_uint8 global_gain; + drmp3_uint8 block_type; + drmp3_uint8 mixed_block_flag; + drmp3_uint8 n_long_sfb; + drmp3_uint8 n_short_sfb; + drmp3_uint8 table_select[3]; + drmp3_uint8 region_count[3]; + drmp3_uint8 subblock_gain[3]; + drmp3_uint8 preflag; + drmp3_uint8 scalefac_scale; + drmp3_uint8 count1_table; + drmp3_uint8 scfsi; +} drmp3_L3_gr_info; + +typedef struct +{ + drmp3_bs bs; + drmp3_uint8 maindata[DRMP3_MAX_BITRESERVOIR_BYTES + DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES]; + drmp3_L3_gr_info gr_info[4]; + float grbuf[2][576]; + float scf[40]; + drmp3_uint8 ist_pos[2][39]; + float syn[18 + 15][2*32]; +} drmp3dec_scratch; + +static void drmp3_bs_init(drmp3_bs *bs, const drmp3_uint8 *data, int bytes) +{ + bs->buf = data; + bs->pos = 0; + bs->limit = bytes*8; +} + +static drmp3_uint32 drmp3_bs_get_bits(drmp3_bs *bs, int n) +{ + drmp3_uint32 next, cache = 0, s = bs->pos & 7; + int shl = n + s; + const drmp3_uint8 *p = bs->buf + (bs->pos >> 3); + if ((bs->pos += n) > bs->limit) + return 0; + next = *p++ & (255 >> s); + while ((shl -= 8) > 0) + { + cache |= next << shl; + next = *p++; + } + return cache | (next >> -shl); +} + +static int drmp3_hdr_valid(const drmp3_uint8 *h) +{ + return h[0] == 0xff && + ((h[1] & 0xF0) == 0xf0 || (h[1] & 0xFE) == 0xe2) && + (DRMP3_HDR_GET_LAYER(h) != 0) && + (DRMP3_HDR_GET_BITRATE(h) != 15) && + (DRMP3_HDR_GET_SAMPLE_RATE(h) != 3); +} + +static int drmp3_hdr_compare(const drmp3_uint8 *h1, const drmp3_uint8 *h2) +{ + return drmp3_hdr_valid(h2) && + ((h1[1] ^ h2[1]) & 0xFE) == 0 && + ((h1[2] ^ h2[2]) & 0x0C) == 0 && + !(DRMP3_HDR_IS_FREE_FORMAT(h1) ^ DRMP3_HDR_IS_FREE_FORMAT(h2)); +} + +static unsigned drmp3_hdr_bitrate_kbps(const drmp3_uint8 *h) +{ + static const drmp3_uint8 halfrate[2][3][15] = { + { { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,16,24,28,32,40,48,56,64,72,80,88,96,112,128 } }, + { { 0,16,20,24,28,32,40,48,56,64,80,96,112,128,160 }, { 0,16,24,28,32,40,48,56,64,80,96,112,128,160,192 }, { 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224 } }, + }; + return 2*halfrate[!!DRMP3_HDR_TEST_MPEG1(h)][DRMP3_HDR_GET_LAYER(h) - 1][DRMP3_HDR_GET_BITRATE(h)]; +} + +static unsigned drmp3_hdr_sample_rate_hz(const drmp3_uint8 *h) +{ + static const unsigned g_hz[3] = { 44100, 48000, 32000 }; + return g_hz[DRMP3_HDR_GET_SAMPLE_RATE(h)] >> (int)!DRMP3_HDR_TEST_MPEG1(h) >> (int)!DRMP3_HDR_TEST_NOT_MPEG25(h); +} + +static unsigned drmp3_hdr_frame_samples(const drmp3_uint8 *h) +{ + return DRMP3_HDR_IS_LAYER_1(h) ? 384 : (1152 >> (int)DRMP3_HDR_IS_FRAME_576(h)); +} + +static int drmp3_hdr_frame_bytes(const drmp3_uint8 *h, int free_format_size) +{ + int frame_bytes = drmp3_hdr_frame_samples(h)*drmp3_hdr_bitrate_kbps(h)*125/drmp3_hdr_sample_rate_hz(h); + if (DRMP3_HDR_IS_LAYER_1(h)) + { + frame_bytes &= ~3; /* slot align */ + } + return frame_bytes ? frame_bytes : free_format_size; +} + +static int drmp3_hdr_padding(const drmp3_uint8 *h) +{ + return DRMP3_HDR_TEST_PADDING(h) ? (DRMP3_HDR_IS_LAYER_1(h) ? 4 : 1) : 0; +} + +#ifndef DR_MP3_ONLY_MP3 +static const drmp3_L12_subband_alloc *drmp3_L12_subband_alloc_table(const drmp3_uint8 *hdr, drmp3_L12_scale_info *sci) +{ + const drmp3_L12_subband_alloc *alloc; + int mode = DRMP3_HDR_GET_STEREO_MODE(hdr); + int nbands, stereo_bands = (mode == DRMP3_MODE_MONO) ? 0 : (mode == DRMP3_MODE_JOINT_STEREO) ? (DRMP3_HDR_GET_STEREO_MODE_EXT(hdr) << 2) + 4 : 32; + + if (DRMP3_HDR_IS_LAYER_1(hdr)) + { + static const drmp3_L12_subband_alloc g_alloc_L1[] = { { 76, 4, 32 } }; + alloc = g_alloc_L1; + nbands = 32; + } else if (!DRMP3_HDR_TEST_MPEG1(hdr)) + { + static const drmp3_L12_subband_alloc g_alloc_L2M2[] = { { 60, 4, 4 }, { 44, 3, 7 }, { 44, 2, 19 } }; + alloc = g_alloc_L2M2; + nbands = 30; + } else + { + static const drmp3_L12_subband_alloc g_alloc_L2M1[] = { { 0, 4, 3 }, { 16, 4, 8 }, { 32, 3, 12 }, { 40, 2, 7 } }; + int sample_rate_idx = DRMP3_HDR_GET_SAMPLE_RATE(hdr); + unsigned kbps = drmp3_hdr_bitrate_kbps(hdr) >> (int)(mode != DRMP3_MODE_MONO); + if (!kbps) /* free-format */ + { + kbps = 192; + } + + alloc = g_alloc_L2M1; + nbands = 27; + if (kbps < 56) + { + static const drmp3_L12_subband_alloc g_alloc_L2M1_lowrate[] = { { 44, 4, 2 }, { 44, 3, 10 } }; + alloc = g_alloc_L2M1_lowrate; + nbands = sample_rate_idx == 2 ? 12 : 8; + } else if (kbps >= 96 && sample_rate_idx != 1) + { + nbands = 30; + } + } + + sci->total_bands = (drmp3_uint8)nbands; + sci->stereo_bands = (drmp3_uint8)DRMP3_MIN(stereo_bands, nbands); + + return alloc; +} + +static void drmp3_L12_read_scalefactors(drmp3_bs *bs, drmp3_uint8 *pba, drmp3_uint8 *scfcod, int bands, float *scf) +{ + static const float g_deq_L12[18*3] = { +#define DRMP3_DQ(x) 9.53674316e-07f/x, 7.56931807e-07f/x, 6.00777173e-07f/x + DRMP3_DQ(3),DRMP3_DQ(7),DRMP3_DQ(15),DRMP3_DQ(31),DRMP3_DQ(63),DRMP3_DQ(127),DRMP3_DQ(255),DRMP3_DQ(511),DRMP3_DQ(1023),DRMP3_DQ(2047),DRMP3_DQ(4095),DRMP3_DQ(8191),DRMP3_DQ(16383),DRMP3_DQ(32767),DRMP3_DQ(65535),DRMP3_DQ(3),DRMP3_DQ(5),DRMP3_DQ(9) + }; + int i, m; + for (i = 0; i < bands; i++) + { + float s = 0; + int ba = *pba++; + int mask = ba ? 4 + ((19 >> scfcod[i]) & 3) : 0; + for (m = 4; m; m >>= 1) + { + if (mask & m) + { + int b = drmp3_bs_get_bits(bs, 6); + s = g_deq_L12[ba*3 - 6 + b % 3]*(1 << 21 >> b/3); + } + *scf++ = s; + } + } +} + +static void drmp3_L12_read_scale_info(const drmp3_uint8 *hdr, drmp3_bs *bs, drmp3_L12_scale_info *sci) +{ + static const drmp3_uint8 g_bitalloc_code_tab[] = { + 0,17, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16, + 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,16, + 0,17,18, 3,19,4,5,16, + 0,17,18,16, + 0,17,18,19, 4,5,6, 7,8, 9,10,11,12,13,14,15, + 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,14, + 0, 2, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16 + }; + const drmp3_L12_subband_alloc *subband_alloc = drmp3_L12_subband_alloc_table(hdr, sci); + + int i, k = 0, ba_bits = 0; + const drmp3_uint8 *ba_code_tab = g_bitalloc_code_tab; + + for (i = 0; i < sci->total_bands; i++) + { + drmp3_uint8 ba; + if (i == k) + { + k += subband_alloc->band_count; + ba_bits = subband_alloc->code_tab_width; + ba_code_tab = g_bitalloc_code_tab + subband_alloc->tab_offset; + subband_alloc++; + } + ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)]; + sci->bitalloc[2*i] = ba; + if (i < sci->stereo_bands) + { + ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)]; + } + sci->bitalloc[2*i + 1] = sci->stereo_bands ? ba : 0; + } + + for (i = 0; i < 2*sci->total_bands; i++) + { + sci->scfcod[i] = (drmp3_uint8)(sci->bitalloc[i] ? DRMP3_HDR_IS_LAYER_1(hdr) ? 2 : drmp3_bs_get_bits(bs, 2) : 6); + } + + drmp3_L12_read_scalefactors(bs, sci->bitalloc, sci->scfcod, sci->total_bands*2, sci->scf); + + for (i = sci->stereo_bands; i < sci->total_bands; i++) + { + sci->bitalloc[2*i + 1] = 0; + } +} + +static int drmp3_L12_dequantize_granule(float *grbuf, drmp3_bs *bs, drmp3_L12_scale_info *sci, int group_size) +{ + int i, j, k, choff = 576; + for (j = 0; j < 4; j++) + { + float *dst = grbuf + group_size*j; + for (i = 0; i < 2*sci->total_bands; i++) + { + int ba = sci->bitalloc[i]; + if (ba != 0) + { + if (ba < 17) + { + int half = (1 << (ba - 1)) - 1; + for (k = 0; k < group_size; k++) + { + dst[k] = (float)((int)drmp3_bs_get_bits(bs, ba) - half); + } + } else + { + unsigned mod = (2 << (ba - 17)) + 1; /* 3, 5, 9 */ + unsigned code = drmp3_bs_get_bits(bs, mod + 2 - (mod >> 3)); /* 5, 7, 10 */ + for (k = 0; k < group_size; k++, code /= mod) + { + dst[k] = (float)((int)(code % mod - mod/2)); + } + } + } + dst += choff; + choff = 18 - choff; + } + } + return group_size*4; +} + +static void drmp3_L12_apply_scf_384(drmp3_L12_scale_info *sci, const float *scf, float *dst) +{ + int i, k; + memcpy(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float)); + for (i = 0; i < sci->total_bands; i++, dst += 18, scf += 6) + { + for (k = 0; k < 12; k++) + { + dst[k + 0] *= scf[0]; + dst[k + 576] *= scf[3]; + } + } +} +#endif + +static int drmp3_L3_read_side_info(drmp3_bs *bs, drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr) +{ + static const drmp3_uint8 g_scf_long[9][23] = { + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 4,4,4,4,4,4,6,6,8,8,10,12,16,20,24,28,34,42,50,54,76,158,0 }, + { 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192,0 }, + { 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26,0 } + }; + static const drmp3_uint8 g_scf_short[9][40] = { + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 8,8,8,8,8,8,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 }, + { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 }, + { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 } + }; + static const drmp3_uint8 g_scf_mixed[9][40] = { + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 12,12,12,4,4,4,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 }, + { 6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 }, + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 }, + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 }, + { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 }, + { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 } + }; + + unsigned tables, scfsi = 0; + int main_data_begin, part_23_sum = 0; + int sr_idx = DRMP3_HDR_GET_MY_SAMPLE_RATE(hdr); + int gr_count = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2; + + if (DRMP3_HDR_TEST_MPEG1(hdr)) + { + gr_count *= 2; + main_data_begin = drmp3_bs_get_bits(bs, 9); + scfsi = drmp3_bs_get_bits(bs, 7 + gr_count); + } else + { + main_data_begin = drmp3_bs_get_bits(bs, 8 + gr_count) >> gr_count; + } + + do + { + if (DRMP3_HDR_IS_MONO(hdr)) + { + scfsi <<= 4; + } + gr->part_23_length = (drmp3_uint16)drmp3_bs_get_bits(bs, 12); + part_23_sum += gr->part_23_length; + gr->big_values = (drmp3_uint16)drmp3_bs_get_bits(bs, 9); + if (gr->big_values > 288) + { + return -1; + } + gr->global_gain = (drmp3_uint8)drmp3_bs_get_bits(bs, 8); + gr->scalefac_compress = (drmp3_uint16)drmp3_bs_get_bits(bs, DRMP3_HDR_TEST_MPEG1(hdr) ? 4 : 9); + gr->sfbtab = g_scf_long[sr_idx]; + gr->n_long_sfb = 22; + gr->n_short_sfb = 0; + if (drmp3_bs_get_bits(bs, 1)) + { + gr->block_type = (drmp3_uint8)drmp3_bs_get_bits(bs, 2); + if (!gr->block_type) + { + return -1; + } + gr->mixed_block_flag = (drmp3_uint8)drmp3_bs_get_bits(bs, 1); + gr->region_count[0] = 7; + gr->region_count[1] = 255; + if (gr->block_type == DRMP3_SHORT_BLOCK_TYPE) + { + scfsi &= 0x0F0F; + if (!gr->mixed_block_flag) + { + gr->region_count[0] = 8; + gr->sfbtab = g_scf_short[sr_idx]; + gr->n_long_sfb = 0; + gr->n_short_sfb = 39; + } else + { + gr->sfbtab = g_scf_mixed[sr_idx]; + gr->n_long_sfb = DRMP3_HDR_TEST_MPEG1(hdr) ? 8 : 6; + gr->n_short_sfb = 30; + } + } + tables = drmp3_bs_get_bits(bs, 10); + tables <<= 5; + gr->subblock_gain[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3); + gr->subblock_gain[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3); + gr->subblock_gain[2] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3); + } else + { + gr->block_type = 0; + gr->mixed_block_flag = 0; + tables = drmp3_bs_get_bits(bs, 15); + gr->region_count[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 4); + gr->region_count[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3); + gr->region_count[2] = 255; + } + gr->table_select[0] = (drmp3_uint8)(tables >> 10); + gr->table_select[1] = (drmp3_uint8)((tables >> 5) & 31); + gr->table_select[2] = (drmp3_uint8)((tables) & 31); + gr->preflag = (drmp3_uint8)(DRMP3_HDR_TEST_MPEG1(hdr) ? drmp3_bs_get_bits(bs, 1) : (gr->scalefac_compress >= 500)); + gr->scalefac_scale = (drmp3_uint8)drmp3_bs_get_bits(bs, 1); + gr->count1_table = (drmp3_uint8)drmp3_bs_get_bits(bs, 1); + gr->scfsi = (drmp3_uint8)((scfsi >> 12) & 15); + scfsi <<= 4; + gr++; + } while(--gr_count); + + if (part_23_sum + bs->pos > bs->limit + main_data_begin*8) + { + return -1; + } + + return main_data_begin; +} + +static void drmp3_L3_read_scalefactors(drmp3_uint8 *scf, drmp3_uint8 *ist_pos, const drmp3_uint8 *scf_size, const drmp3_uint8 *scf_count, drmp3_bs *bitbuf, int scfsi) +{ + int i, k; + for (i = 0; i < 4 && scf_count[i]; i++, scfsi *= 2) + { + int cnt = scf_count[i]; + if (scfsi & 8) + { + memcpy(scf, ist_pos, cnt); + } else + { + int bits = scf_size[i]; + if (!bits) + { + memset(scf, 0, cnt); + memset(ist_pos, 0, cnt); + } else + { + int max_scf = (scfsi < 0) ? (1 << bits) - 1 : -1; + for (k = 0; k < cnt; k++) + { + int s = drmp3_bs_get_bits(bitbuf, bits); + ist_pos[k] = (drmp3_uint8)(s == max_scf ? -1 : s); + scf[k] = (drmp3_uint8)s; + } + } + } + ist_pos += cnt; + scf += cnt; + } + scf[0] = scf[1] = scf[2] = 0; +} + +static float drmp3_L3_ldexp_q2(float y, int exp_q2) +{ + static const float g_expfrac[4] = { 9.31322575e-10f,7.83145814e-10f,6.58544508e-10f,5.53767716e-10f }; + int e; + do + { + e = DRMP3_MIN(30*4, exp_q2); + y *= g_expfrac[e & 3]*(1 << 30 >> (e >> 2)); + } while ((exp_q2 -= e) > 0); + return y; +} + +static void drmp3_L3_decode_scalefactors(const drmp3_uint8 *hdr, drmp3_uint8 *ist_pos, drmp3_bs *bs, const drmp3_L3_gr_info *gr, float *scf, int ch) +{ + static const drmp3_uint8 g_scf_partitions[3][28] = { + { 6,5,5, 5,6,5,5,5,6,5, 7,3,11,10,0,0, 7, 7, 7,0, 6, 6,6,3, 8, 8,5,0 }, + { 8,9,6,12,6,9,9,9,6,9,12,6,15,18,0,0, 6,15,12,0, 6,12,9,6, 6,18,9,0 }, + { 9,9,6,12,9,9,9,9,9,9,12,6,18,18,0,0,12,12,12,0,12, 9,9,6,15,12,9,0 } + }; + const drmp3_uint8 *scf_partition = g_scf_partitions[!!gr->n_short_sfb + !gr->n_long_sfb]; + drmp3_uint8 scf_size[4], iscf[40]; + int i, scf_shift = gr->scalefac_scale + 1, gain_exp, scfsi = gr->scfsi; + float gain; + + if (DRMP3_HDR_TEST_MPEG1(hdr)) + { + static const drmp3_uint8 g_scfc_decode[16] = { 0,1,2,3, 12,5,6,7, 9,10,11,13, 14,15,18,19 }; + int part = g_scfc_decode[gr->scalefac_compress]; + scf_size[1] = scf_size[0] = (drmp3_uint8)(part >> 2); + scf_size[3] = scf_size[2] = (drmp3_uint8)(part & 3); + } else + { + static const drmp3_uint8 g_mod[6*4] = { 5,5,4,4,5,5,4,1,4,3,1,1,5,6,6,1,4,4,4,1,4,3,1,1 }; + int k, modprod, sfc, ist = DRMP3_HDR_TEST_I_STEREO(hdr) && ch; + sfc = gr->scalefac_compress >> ist; + for (k = ist*3*4; sfc >= 0; sfc -= modprod, k += 4) + { + for (modprod = 1, i = 3; i >= 0; i--) + { + scf_size[i] = (drmp3_uint8)(sfc / modprod % g_mod[k + i]); + modprod *= g_mod[k + i]; + } + } + scf_partition += k; + scfsi = -16; + } + drmp3_L3_read_scalefactors(iscf, ist_pos, scf_size, scf_partition, bs, scfsi); + + if (gr->n_short_sfb) + { + int sh = 3 - scf_shift; + for (i = 0; i < gr->n_short_sfb; i += 3) + { + iscf[gr->n_long_sfb + i + 0] += gr->subblock_gain[0] << sh; + iscf[gr->n_long_sfb + i + 1] += gr->subblock_gain[1] << sh; + iscf[gr->n_long_sfb + i + 2] += gr->subblock_gain[2] << sh; + } + } else if (gr->preflag) + { + static const drmp3_uint8 g_preamp[10] = { 1,1,1,1,2,2,3,3,3,2 }; + for (i = 0; i < 10; i++) + { + iscf[11 + i] += g_preamp[i]; + } + } + + gain_exp = gr->global_gain + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210 - (DRMP3_HDR_IS_MS_STEREO(hdr) ? 2 : 0); + gain = drmp3_L3_ldexp_q2(1 << (DRMP3_MAX_SCFI/4), DRMP3_MAX_SCFI - gain_exp); + for (i = 0; i < (int)(gr->n_long_sfb + gr->n_short_sfb); i++) + { + scf[i] = drmp3_L3_ldexp_q2(gain, iscf[i] << scf_shift); + } +} + +static float drmp3_L3_pow_43(int x) +{ + static const float g_pow43[129] = { + 0,1,2.519842f,4.326749f,6.349604f,8.549880f,10.902724f,13.390518f,16.000000f,18.720754f,21.544347f,24.463781f,27.473142f,30.567351f,33.741992f,36.993181f,40.317474f,43.711787f,47.173345f,50.699631f,54.288352f,57.937408f,61.644865f,65.408941f,69.227979f,73.100443f,77.024898f,81.000000f,85.024491f,89.097188f,93.216975f,97.382800f,101.593667f,105.848633f,110.146801f,114.487321f,118.869381f,123.292209f,127.755065f,132.257246f,136.798076f,141.376907f,145.993119f,150.646117f,155.335327f,160.060199f,164.820202f,169.614826f,174.443577f,179.305980f,184.201575f,189.129918f,194.090580f,199.083145f,204.107210f,209.162385f,214.248292f,219.364564f,224.510845f,229.686789f,234.892058f,240.126328f,245.389280f,250.680604f,256.000000f,261.347174f,266.721841f,272.123723f,277.552547f,283.008049f,288.489971f,293.998060f,299.532071f,305.091761f,310.676898f,316.287249f,321.922592f,327.582707f,333.267377f,338.976394f,344.709550f,350.466646f,356.247482f,362.051866f,367.879608f,373.730522f,379.604427f,385.501143f,391.420496f,397.362314f,403.326427f,409.312672f,415.320884f,421.350905f,427.402579f,433.475750f,439.570269f,445.685987f,451.822757f,457.980436f,464.158883f,470.357960f,476.577530f,482.817459f,489.077615f,495.357868f,501.658090f,507.978156f,514.317941f,520.677324f,527.056184f,533.454404f,539.871867f,546.308458f,552.764065f,559.238575f,565.731879f,572.243870f,578.774440f,585.323483f,591.890898f,598.476581f,605.080431f,611.702349f,618.342238f,625.000000f,631.675540f,638.368763f,645.079578f + }; + float frac; + int sign, mult = 256; + + if (x < 129) + { + return g_pow43[x]; + } + + if (x < 1024) + { + mult = 16; + x <<= 3; + } + + sign = 2*x & 64; + frac = (float)((x & 63) - sign) / ((x & ~63) + sign); + return g_pow43[(x + sign) >> 6]*(1.f + frac*((4.f/3) + frac*(2.f/9)))*mult; +} + +static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *gr_info, const float *scf, int layer3gr_limit) +{ + static const float g_pow43_signed[32] = { 0,0,1,-1,2.519842f,-2.519842f,4.326749f,-4.326749f,6.349604f,-6.349604f,8.549880f,-8.549880f,10.902724f,-10.902724f,13.390518f,-13.390518f,16.000000f,-16.000000f,18.720754f,-18.720754f,21.544347f,-21.544347f,24.463781f,-24.463781f,27.473142f,-27.473142f,30.567351f,-30.567351f,33.741992f,-33.741992f,36.993181f,-36.993181f }; + static const drmp3_int16 tab0[32] = { 0, }; + static const drmp3_int16 tab1[] = { 785,785,785,785,784,784,784,784,513,513,513,513,513,513,513,513,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256 }; + static const drmp3_int16 tab2[] = { -255,1313,1298,1282,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,290,288 }; + static const drmp3_int16 tab3[] = { -255,1313,1298,1282,769,769,769,769,529,529,529,529,529,529,529,529,528,528,528,528,528,528,528,528,512,512,512,512,512,512,512,512,290,288 }; + static const drmp3_int16 tab5[] = { -253,-318,-351,-367,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,819,818,547,547,275,275,275,275,561,560,515,546,289,274,288,258 }; + static const drmp3_int16 tab6[] = { -254,-287,1329,1299,1314,1312,1057,1057,1042,1042,1026,1026,784,784,784,784,529,529,529,529,529,529,529,529,769,769,769,769,768,768,768,768,563,560,306,306,291,259 }; + static const drmp3_int16 tab7[] = { -252,-413,-477,-542,1298,-575,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-383,-399,1107,1092,1106,1061,849,849,789,789,1104,1091,773,773,1076,1075,341,340,325,309,834,804,577,577,532,532,516,516,832,818,803,816,561,561,531,531,515,546,289,289,288,258 }; + static const drmp3_int16 tab8[] = { -252,-429,-493,-559,1057,1057,1042,1042,529,529,529,529,529,529,529,529,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,-382,1077,-415,1106,1061,1104,849,849,789,789,1091,1076,1029,1075,834,834,597,581,340,340,339,324,804,833,532,532,832,772,818,803,817,787,816,771,290,290,290,290,288,258 }; + static const drmp3_int16 tab9[] = { -253,-349,-414,-447,-463,1329,1299,-479,1314,1312,1057,1057,1042,1042,1026,1026,785,785,785,785,784,784,784,784,769,769,769,769,768,768,768,768,-319,851,821,-335,836,850,805,849,341,340,325,336,533,533,579,579,564,564,773,832,578,548,563,516,321,276,306,291,304,259 }; + static const drmp3_int16 tab10[] = { -251,-572,-733,-830,-863,-879,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,1396,1351,1381,1366,1395,1335,1380,-559,1334,1138,1138,1063,1063,1350,1392,1031,1031,1062,1062,1364,1363,1120,1120,1333,1348,881,881,881,881,375,374,359,373,343,358,341,325,791,791,1123,1122,-703,1105,1045,-719,865,865,790,790,774,774,1104,1029,338,293,323,308,-799,-815,833,788,772,818,803,816,322,292,307,320,561,531,515,546,289,274,288,258 }; + static const drmp3_int16 tab11[] = { -251,-525,-605,-685,-765,-831,-846,1298,1057,1057,1312,1282,785,785,785,785,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,1399,1398,1383,1367,1382,1396,1351,-511,1381,1366,1139,1139,1079,1079,1124,1124,1364,1349,1363,1333,882,882,882,882,807,807,807,807,1094,1094,1136,1136,373,341,535,535,881,775,867,822,774,-591,324,338,-671,849,550,550,866,864,609,609,293,336,534,534,789,835,773,-751,834,804,308,307,833,788,832,772,562,562,547,547,305,275,560,515,290,290 }; + static const drmp3_int16 tab12[] = { -252,-397,-477,-557,-622,-653,-719,-735,-750,1329,1299,1314,1057,1057,1042,1042,1312,1282,1024,1024,785,785,785,785,784,784,784,784,769,769,769,769,-383,1127,1141,1111,1126,1140,1095,1110,869,869,883,883,1079,1109,882,882,375,374,807,868,838,881,791,-463,867,822,368,263,852,837,836,-543,610,610,550,550,352,336,534,534,865,774,851,821,850,805,593,533,579,564,773,832,578,578,548,548,577,577,307,276,306,291,516,560,259,259 }; + static const drmp3_int16 tab13[] = { -250,-2107,-2507,-2764,-2909,-2974,-3007,-3023,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-767,-1052,-1213,-1277,-1358,-1405,-1469,-1535,-1550,-1582,-1614,-1647,-1662,-1694,-1726,-1759,-1774,-1807,-1822,-1854,-1886,1565,-1919,-1935,-1951,-1967,1731,1730,1580,1717,-1983,1729,1564,-1999,1548,-2015,-2031,1715,1595,-2047,1714,-2063,1610,-2079,1609,-2095,1323,1323,1457,1457,1307,1307,1712,1547,1641,1700,1699,1594,1685,1625,1442,1442,1322,1322,-780,-973,-910,1279,1278,1277,1262,1276,1261,1275,1215,1260,1229,-959,974,974,989,989,-943,735,478,478,495,463,506,414,-1039,1003,958,1017,927,942,987,957,431,476,1272,1167,1228,-1183,1256,-1199,895,895,941,941,1242,1227,1212,1135,1014,1014,490,489,503,487,910,1013,985,925,863,894,970,955,1012,847,-1343,831,755,755,984,909,428,366,754,559,-1391,752,486,457,924,997,698,698,983,893,740,740,908,877,739,739,667,667,953,938,497,287,271,271,683,606,590,712,726,574,302,302,738,736,481,286,526,725,605,711,636,724,696,651,589,681,666,710,364,467,573,695,466,466,301,465,379,379,709,604,665,679,316,316,634,633,436,436,464,269,424,394,452,332,438,363,347,408,393,448,331,422,362,407,392,421,346,406,391,376,375,359,1441,1306,-2367,1290,-2383,1337,-2399,-2415,1426,1321,-2431,1411,1336,-2447,-2463,-2479,1169,1169,1049,1049,1424,1289,1412,1352,1319,-2495,1154,1154,1064,1064,1153,1153,416,390,360,404,403,389,344,374,373,343,358,372,327,357,342,311,356,326,1395,1394,1137,1137,1047,1047,1365,1392,1287,1379,1334,1364,1349,1378,1318,1363,792,792,792,792,1152,1152,1032,1032,1121,1121,1046,1046,1120,1120,1030,1030,-2895,1106,1061,1104,849,849,789,789,1091,1076,1029,1090,1060,1075,833,833,309,324,532,532,832,772,818,803,561,561,531,560,515,546,289,274,288,258 }; + static const drmp3_int16 tab15[] = { -250,-1179,-1579,-1836,-1996,-2124,-2253,-2333,-2413,-2477,-2542,-2574,-2607,-2622,-2655,1314,1313,1298,1312,1282,785,785,785,785,1040,1040,1025,1025,768,768,768,768,-766,-798,-830,-862,-895,-911,-927,-943,-959,-975,-991,-1007,-1023,-1039,-1055,-1070,1724,1647,-1103,-1119,1631,1767,1662,1738,1708,1723,-1135,1780,1615,1779,1599,1677,1646,1778,1583,-1151,1777,1567,1737,1692,1765,1722,1707,1630,1751,1661,1764,1614,1736,1676,1763,1750,1645,1598,1721,1691,1762,1706,1582,1761,1566,-1167,1749,1629,767,766,751,765,494,494,735,764,719,749,734,763,447,447,748,718,477,506,431,491,446,476,461,505,415,430,475,445,504,399,460,489,414,503,383,474,429,459,502,502,746,752,488,398,501,473,413,472,486,271,480,270,-1439,-1455,1357,-1471,-1487,-1503,1341,1325,-1519,1489,1463,1403,1309,-1535,1372,1448,1418,1476,1356,1462,1387,-1551,1475,1340,1447,1402,1386,-1567,1068,1068,1474,1461,455,380,468,440,395,425,410,454,364,467,466,464,453,269,409,448,268,432,1371,1473,1432,1417,1308,1460,1355,1446,1459,1431,1083,1083,1401,1416,1458,1445,1067,1067,1370,1457,1051,1051,1291,1430,1385,1444,1354,1415,1400,1443,1082,1082,1173,1113,1186,1066,1185,1050,-1967,1158,1128,1172,1097,1171,1081,-1983,1157,1112,416,266,375,400,1170,1142,1127,1065,793,793,1169,1033,1156,1096,1141,1111,1155,1080,1126,1140,898,898,808,808,897,897,792,792,1095,1152,1032,1125,1110,1139,1079,1124,882,807,838,881,853,791,-2319,867,368,263,822,852,837,866,806,865,-2399,851,352,262,534,534,821,836,594,594,549,549,593,593,533,533,848,773,579,579,564,578,548,563,276,276,577,576,306,291,516,560,305,305,275,259 }; + static const drmp3_int16 tab16[] = { -251,-892,-2058,-2620,-2828,-2957,-3023,-3039,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,-559,1530,-575,-591,1528,1527,1407,1526,1391,1023,1023,1023,1023,1525,1375,1268,1268,1103,1103,1087,1087,1039,1039,1523,-604,815,815,815,815,510,495,509,479,508,463,507,447,431,505,415,399,-734,-782,1262,-815,1259,1244,-831,1258,1228,-847,-863,1196,-879,1253,987,987,748,-767,493,493,462,477,414,414,686,669,478,446,461,445,474,429,487,458,412,471,1266,1264,1009,1009,799,799,-1019,-1276,-1452,-1581,-1677,-1757,-1821,-1886,-1933,-1997,1257,1257,1483,1468,1512,1422,1497,1406,1467,1496,1421,1510,1134,1134,1225,1225,1466,1451,1374,1405,1252,1252,1358,1480,1164,1164,1251,1251,1238,1238,1389,1465,-1407,1054,1101,-1423,1207,-1439,830,830,1248,1038,1237,1117,1223,1148,1236,1208,411,426,395,410,379,269,1193,1222,1132,1235,1221,1116,976,976,1192,1162,1177,1220,1131,1191,963,963,-1647,961,780,-1663,558,558,994,993,437,408,393,407,829,978,813,797,947,-1743,721,721,377,392,844,950,828,890,706,706,812,859,796,960,948,843,934,874,571,571,-1919,690,555,689,421,346,539,539,944,779,918,873,932,842,903,888,570,570,931,917,674,674,-2575,1562,-2591,1609,-2607,1654,1322,1322,1441,1441,1696,1546,1683,1593,1669,1624,1426,1426,1321,1321,1639,1680,1425,1425,1305,1305,1545,1668,1608,1623,1667,1592,1638,1666,1320,1320,1652,1607,1409,1409,1304,1304,1288,1288,1664,1637,1395,1395,1335,1335,1622,1636,1394,1394,1319,1319,1606,1621,1392,1392,1137,1137,1137,1137,345,390,360,375,404,373,1047,-2751,-2767,-2783,1062,1121,1046,-2799,1077,-2815,1106,1061,789,789,1105,1104,263,355,310,340,325,354,352,262,339,324,1091,1076,1029,1090,1060,1075,833,833,788,788,1088,1028,818,818,803,803,561,561,531,531,816,771,546,546,289,274,288,258 }; + static const drmp3_int16 tab24[] = { -253,-317,-381,-446,-478,-509,1279,1279,-811,-1179,-1451,-1756,-1900,-2028,-2189,-2253,-2333,-2414,-2445,-2511,-2526,1313,1298,-2559,1041,1041,1040,1040,1025,1025,1024,1024,1022,1007,1021,991,1020,975,1019,959,687,687,1018,1017,671,671,655,655,1016,1015,639,639,758,758,623,623,757,607,756,591,755,575,754,559,543,543,1009,783,-575,-621,-685,-749,496,-590,750,749,734,748,974,989,1003,958,988,973,1002,942,987,957,972,1001,926,986,941,971,956,1000,910,985,925,999,894,970,-1071,-1087,-1102,1390,-1135,1436,1509,1451,1374,-1151,1405,1358,1480,1420,-1167,1507,1494,1389,1342,1465,1435,1450,1326,1505,1310,1493,1373,1479,1404,1492,1464,1419,428,443,472,397,736,526,464,464,486,457,442,471,484,482,1357,1449,1434,1478,1388,1491,1341,1490,1325,1489,1463,1403,1309,1477,1372,1448,1418,1433,1476,1356,1462,1387,-1439,1475,1340,1447,1402,1474,1324,1461,1371,1473,269,448,1432,1417,1308,1460,-1711,1459,-1727,1441,1099,1099,1446,1386,1431,1401,-1743,1289,1083,1083,1160,1160,1458,1445,1067,1067,1370,1457,1307,1430,1129,1129,1098,1098,268,432,267,416,266,400,-1887,1144,1187,1082,1173,1113,1186,1066,1050,1158,1128,1143,1172,1097,1171,1081,420,391,1157,1112,1170,1142,1127,1065,1169,1049,1156,1096,1141,1111,1155,1080,1126,1154,1064,1153,1140,1095,1048,-2159,1125,1110,1137,-2175,823,823,1139,1138,807,807,384,264,368,263,868,838,853,791,867,822,852,837,866,806,865,790,-2319,851,821,836,352,262,850,805,849,-2399,533,533,835,820,336,261,578,548,563,577,532,532,832,772,562,562,547,547,305,275,560,515,290,290,288,258 }; + static const drmp3_uint8 tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205}; + static const drmp3_uint8 tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 }; + static const drmp3_int16 * const tabindex[2*16] = { tab0,tab1,tab2,tab3,tab0,tab5,tab6,tab7,tab8,tab9,tab10,tab11,tab12,tab13,tab0,tab15,tab16,tab16,tab16,tab16,tab16,tab16,tab16,tab16,tab24,tab24,tab24,tab24,tab24,tab24,tab24,tab24 }; + static const drmp3_uint8 g_linbits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 }; + +#define DRMP3_PEEK_BITS(n) (bs_cache >> (32 - n)) +#define DRMP3_FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); } +#define DRMP3_CHECK_BITS while (bs_sh >= 0) { bs_cache |= (drmp3_uint32)*bs_next_ptr++ << bs_sh; bs_sh -= 8; } +#define DRMP3_BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh) + + float one = 0.0f; + int ireg = 0, big_val_cnt = gr_info->big_values; + const drmp3_uint8 *sfb = gr_info->sfbtab; + const drmp3_uint8 *bs_next_ptr = bs->buf + bs->pos/8; + drmp3_uint32 bs_cache = (((bs_next_ptr[0]*256u + bs_next_ptr[1])*256u + bs_next_ptr[2])*256u + bs_next_ptr[3]) << (bs->pos & 7); + int pairs_to_decode, np, bs_sh = (bs->pos & 7) - 8; + bs_next_ptr += 4; + + while (big_val_cnt > 0) + { + int tab_num = gr_info->table_select[ireg]; + int sfb_cnt = gr_info->region_count[ireg++]; + const short *codebook = tabindex[tab_num]; + int linbits = g_linbits[tab_num]; + do + { + np = *sfb++ / 2; + pairs_to_decode = DRMP3_MIN(big_val_cnt, np); + one = *scf++; + do + { + int j, w = 5; + int leaf = codebook[DRMP3_PEEK_BITS(w)]; + while (leaf < 0) + { + DRMP3_FLUSH_BITS(w); + w = leaf & 7; + leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)]; + } + DRMP3_FLUSH_BITS(leaf >> 8); + + for (j = 0; j < 2; j++, dst++, leaf >>= 4) + { + int lsb = leaf & 0x0F; + if (lsb == 15 && linbits) + { + lsb += DRMP3_PEEK_BITS(linbits); + DRMP3_FLUSH_BITS(linbits); + DRMP3_CHECK_BITS; + *dst = one*drmp3_L3_pow_43(lsb)*((int32_t)bs_cache < 0 ? -1: 1); + } else + { + *dst = g_pow43_signed[lsb*2 + (bs_cache >> 31)]*one; + } + DRMP3_FLUSH_BITS(lsb ? 1 : 0); + } + DRMP3_CHECK_BITS; + } while (--pairs_to_decode); + } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0); + } + + for (np = 1 - big_val_cnt;; dst += 4) + { + const drmp3_uint8 *codebook_count1 = (gr_info->count1_table) ? tab33 : tab32; + int leaf = codebook_count1[DRMP3_PEEK_BITS(4)]; + if (!(leaf & 8)) + { + leaf = codebook_count1[(leaf >> 3) + (bs_cache << 4 >> (32 - (leaf & 3)))]; + } + DRMP3_FLUSH_BITS(leaf & 7); + if (DRMP3_BSPOS > layer3gr_limit) + { + break; + } +#define DRMP3_RELOAD_SCALEFACTOR if (!--np) { np = *sfb++/2; if (!np) break; one = *scf++; } +#define DRMP3_DEQ_COUNT1(s) if (leaf & (128 >> s)) { dst[s] = ((drmp3_int32)bs_cache < 0) ? -one : one; DRMP3_FLUSH_BITS(1) } + DRMP3_RELOAD_SCALEFACTOR; + DRMP3_DEQ_COUNT1(0); + DRMP3_DEQ_COUNT1(1); + DRMP3_RELOAD_SCALEFACTOR; + DRMP3_DEQ_COUNT1(2); + DRMP3_DEQ_COUNT1(3); + DRMP3_CHECK_BITS; + } + + bs->pos = layer3gr_limit; +} + +static void drmp3_L3_midside_stereo(float *left, int n) +{ + int i = 0; + float *right = left + 576; +#if DRMP3_HAVE_SIMD + if (drmp3_have_simd()) for (; i < n - 3; i += 4) + { + drmp3_f4 vl = DRMP3_VLD(left + i); + drmp3_f4 vr = DRMP3_VLD(right + i); + DRMP3_VSTORE(left + i, DRMP3_VADD(vl, vr)); + DRMP3_VSTORE(right + i, DRMP3_VSUB(vl, vr)); + } +#endif + for (; i < n; i++) + { + float a = left[i]; + float b = right[i]; + left[i] = a + b; + right[i] = a - b; + } +} + +static void drmp3_L3_intensity_stereo_band(float *left, int n, float kl, float kr) +{ + int i; + for (i = 0; i < n; i++) + { + left[i + 576] = left[i]*kr; + left[i] = left[i]*kl; + } +} + +static void drmp3_L3_stereo_top_band(const float *right, const drmp3_uint8 *sfb, int nbands, int max_band[3]) +{ + int i, k; + + max_band[0] = max_band[1] = max_band[2] = -1; + + for (i = 0; i < nbands; i++) + { + for (k = 0; k < sfb[i]; k += 2) + { + if (right[k] != 0 || right[k + 1] != 0) + { + max_band[i % 3] = i; + break; + } + } + right += sfb[i]; + } +} + +static void drmp3_L3_stereo_process(float *left, const drmp3_uint8 *ist_pos, const drmp3_uint8 *sfb, const drmp3_uint8 *hdr, int max_band[3], int mpeg2_sh) +{ + static const float g_pan[7*2] = { 0,1,0.21132487f,0.78867513f,0.36602540f,0.63397460f,0.5f,0.5f,0.63397460f,0.36602540f,0.78867513f,0.21132487f,1,0 }; + unsigned i, max_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 7 : 64; + + for (i = 0; sfb[i]; i++) + { + unsigned ipos = ist_pos[i]; + if ((int)i > max_band[i % 3] && ipos < max_pos) + { + float kl, kr, s = DRMP3_HDR_TEST_MS_STEREO(hdr) ? 1.41421356f : 1; + if (DRMP3_HDR_TEST_MPEG1(hdr)) + { + kl = g_pan[2*ipos]; + kr = g_pan[2*ipos + 1]; + } else + { + kl = 1; + kr = drmp3_L3_ldexp_q2(1, (ipos + 1) >> 1 << mpeg2_sh); + if (ipos & 1) + { + kl = kr; + kr = 1; + } + } + drmp3_L3_intensity_stereo_band(left, sfb[i], kl*s, kr*s); + } else if (DRMP3_HDR_TEST_MS_STEREO(hdr)) + { + drmp3_L3_midside_stereo(left, sfb[i]); + } + left += sfb[i]; + } +} + +static void drmp3_L3_intensity_stereo(float *left, drmp3_uint8 *ist_pos, const drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr) +{ + int max_band[3], n_sfb = gr->n_long_sfb + gr->n_short_sfb; + int i, max_blocks = gr->n_short_sfb ? 3 : 1; + + drmp3_L3_stereo_top_band(left + 576, gr->sfbtab, n_sfb, max_band); + if (gr->n_long_sfb) + { + max_band[0] = max_band[1] = max_band[2] = DRMP3_MAX(DRMP3_MAX(max_band[0], max_band[1]), max_band[2]); + } + for (i = 0; i < max_blocks; i++) + { + int default_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 3 : 0; + int itop = n_sfb - max_blocks + i; + int prev = itop - max_blocks; + ist_pos[itop] = (drmp3_uint8)(max_band[i] >= prev ? default_pos : ist_pos[prev]); + } + drmp3_L3_stereo_process(left, ist_pos, gr->sfbtab, hdr, max_band, gr[1].scalefac_compress&1); +} + +static void drmp3_L3_reorder(float *grbuf, float *scratch, const drmp3_uint8 *sfb) +{ + int i, len; + float *src = grbuf, *dst = scratch; + + for (;0 != (len = *sfb); sfb += 3, src += 2*len) + { + for (i = 0; i < len; i++, src++) + { + *dst++ = src[0*len]; + *dst++ = src[1*len]; + *dst++ = src[2*len]; + } + } + memcpy(grbuf, scratch, (dst - scratch)*sizeof(float)); +} + +static void drmp3_L3_antialias(float *grbuf, int nbands) +{ + static const float g_aa[2][8] = { + {0.85749293f,0.88174200f,0.94962865f,0.98331459f,0.99551782f,0.99916056f,0.99989920f,0.99999316f}, + {0.51449576f,0.47173197f,0.31337745f,0.18191320f,0.09457419f,0.04096558f,0.01419856f,0.00369997f} + }; + + for (; nbands > 0; nbands--, grbuf += 18) + { + int i = 0; +#if DRMP3_HAVE_SIMD + if (drmp3_have_simd()) for (; i < 8; i += 4) + { + drmp3_f4 vu = DRMP3_VLD(grbuf + 18 + i); + drmp3_f4 vd = DRMP3_VLD(grbuf + 14 - i); + drmp3_f4 vc0 = DRMP3_VLD(g_aa[0] + i); + drmp3_f4 vc1 = DRMP3_VLD(g_aa[1] + i); + vd = DRMP3_VREV(vd); + DRMP3_VSTORE(grbuf + 18 + i, DRMP3_VSUB(DRMP3_VMUL(vu, vc0), DRMP3_VMUL(vd, vc1))); + vd = DRMP3_VADD(DRMP3_VMUL(vu, vc1), DRMP3_VMUL(vd, vc0)); + DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vd)); + } +#endif +#ifndef DR_MP3_ONLY_SIMD + for(; i < 8; i++) + { + float u = grbuf[18 + i]; + float d = grbuf[17 - i]; + grbuf[18 + i] = u*g_aa[0][i] - d*g_aa[1][i]; + grbuf[17 - i] = u*g_aa[1][i] + d*g_aa[0][i]; + } +#endif + } +} + +static void drmp3_L3_dct3_9(float *y) +{ + float s0, s1, s2, s3, s4, s5, s6, s7, s8, t0, t2, t4; + + s0 = y[0]; s2 = y[2]; s4 = y[4]; s6 = y[6]; s8 = y[8]; + t0 = s0 + s6*0.5f; + s0 -= s6; + t4 = (s4 + s2)*0.93969262f; + t2 = (s8 + s2)*0.76604444f; + s6 = (s4 - s8)*0.17364818f; + s4 += s8 - s2; + + s2 = s0 - s4*0.5f; + y[4] = s4 + s0; + s8 = t0 - t2 + s6; + s0 = t0 - t4 + t2; + s4 = t0 + t4 - s6; + + s1 = y[1]; s3 = y[3]; s5 = y[5]; s7 = y[7]; + + s3 *= 0.86602540f; + t0 = (s5 + s1)*0.98480775f; + t4 = (s5 - s7)*0.34202014f; + t2 = (s1 + s7)*0.64278761f; + s1 = (s1 - s5 - s7)*0.86602540f; + + s5 = t0 - s3 - t2; + s7 = t4 - s3 - t0; + s3 = t4 + s3 - t2; + + y[0] = s4 - s7; + y[1] = s2 + s1; + y[2] = s0 - s3; + y[3] = s8 + s5; + y[5] = s8 - s5; + y[6] = s0 + s3; + y[7] = s2 - s1; + y[8] = s4 + s7; +} + +static void drmp3_L3_imdct36(float *grbuf, float *overlap, const float *window, int nbands) +{ + int i, j; + static const float g_twid9[18] = { + 0.73727734f,0.79335334f,0.84339145f,0.88701083f,0.92387953f,0.95371695f,0.97629601f,0.99144486f,0.99904822f,0.67559021f,0.60876143f,0.53729961f,0.46174861f,0.38268343f,0.30070580f,0.21643961f,0.13052619f,0.04361938f + }; + + for (j = 0; j < nbands; j++, grbuf += 18, overlap += 9) + { + float co[9], si[9]; + co[0] = -grbuf[0]; + si[0] = grbuf[17]; + for (i = 0; i < 4; i++) + { + si[8 - 2*i] = grbuf[4*i + 1] - grbuf[4*i + 2]; + co[1 + 2*i] = grbuf[4*i + 1] + grbuf[4*i + 2]; + si[7 - 2*i] = grbuf[4*i + 4] - grbuf[4*i + 3]; + co[2 + 2*i] = -(grbuf[4*i + 3] + grbuf[4*i + 4]); + } + drmp3_L3_dct3_9(co); + drmp3_L3_dct3_9(si); + + si[1] = -si[1]; + si[3] = -si[3]; + si[5] = -si[5]; + si[7] = -si[7]; + + i = 0; + +#if DRMP3_HAVE_SIMD + if (drmp3_have_simd()) for (; i < 8; i += 4) + { + drmp3_f4 vovl = DRMP3_VLD(overlap + i); + drmp3_f4 vc = DRMP3_VLD(co + i); + drmp3_f4 vs = DRMP3_VLD(si + i); + drmp3_f4 vr0 = DRMP3_VLD(g_twid9 + i); + drmp3_f4 vr1 = DRMP3_VLD(g_twid9 + 9 + i); + drmp3_f4 vw0 = DRMP3_VLD(window + i); + drmp3_f4 vw1 = DRMP3_VLD(window + 9 + i); + drmp3_f4 vsum = DRMP3_VADD(DRMP3_VMUL(vc, vr1), DRMP3_VMUL(vs, vr0)); + DRMP3_VSTORE(overlap + i, DRMP3_VSUB(DRMP3_VMUL(vc, vr0), DRMP3_VMUL(vs, vr1))); + DRMP3_VSTORE(grbuf + i, DRMP3_VSUB(DRMP3_VMUL(vovl, vw0), DRMP3_VMUL(vsum, vw1))); + vsum = DRMP3_VADD(DRMP3_VMUL(vovl, vw1), DRMP3_VMUL(vsum, vw0)); + DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vsum)); + } +#endif + for (; i < 9; i++) + { + float ovl = overlap[i]; + float sum = co[i]*g_twid9[9 + i] + si[i]*g_twid9[0 + i]; + overlap[i] = co[i]*g_twid9[0 + i] - si[i]*g_twid9[9 + i]; + grbuf[i] = ovl*window[0 + i] - sum*window[9 + i]; + grbuf[17 - i] = ovl*window[9 + i] + sum*window[0 + i]; + } + } +} + +static void drmp3_L3_idct3(float x0, float x1, float x2, float *dst) +{ + float m1 = x1*0.86602540f; + float a1 = x0 - x2*0.5f; + dst[1] = x0 + x2; + dst[0] = a1 + m1; + dst[2] = a1 - m1; +} + +static void drmp3_L3_imdct12(float *x, float *dst, float *overlap) +{ + static const float g_twid3[6] = { 0.79335334f,0.92387953f,0.99144486f, 0.60876143f,0.38268343f,0.13052619f }; + float co[3], si[3]; + int i; + + drmp3_L3_idct3(-x[0], x[6] + x[3], x[12] + x[9], co); + drmp3_L3_idct3(x[15], x[12] - x[9], x[6] - x[3], si); + si[1] = -si[1]; + + for (i = 0; i < 3; i++) + { + float ovl = overlap[i]; + float sum = co[i]*g_twid3[3 + i] + si[i]*g_twid3[0 + i]; + overlap[i] = co[i]*g_twid3[0 + i] - si[i]*g_twid3[3 + i]; + dst[i] = ovl*g_twid3[2 - i] - sum*g_twid3[5 - i]; + dst[5 - i] = ovl*g_twid3[5 - i] + sum*g_twid3[2 - i]; + } +} + +static void drmp3_L3_imdct_short(float *grbuf, float *overlap, int nbands) +{ + for (;nbands > 0; nbands--, overlap += 9, grbuf += 18) + { + float tmp[18]; + memcpy(tmp, grbuf, sizeof(tmp)); + memcpy(grbuf, overlap, 6*sizeof(float)); + drmp3_L3_imdct12(tmp, grbuf + 6, overlap + 6); + drmp3_L3_imdct12(tmp + 1, grbuf + 12, overlap + 6); + drmp3_L3_imdct12(tmp + 2, overlap, overlap + 6); + } +} + +static void drmp3_L3_change_sign(float *grbuf) +{ + int b, i; + for (b = 0, grbuf += 18; b < 32; b += 2, grbuf += 36) + for (i = 1; i < 18; i += 2) + grbuf[i] = -grbuf[i]; +} + +static void drmp3_L3_imdct_gr(float *grbuf, float *overlap, unsigned block_type, unsigned n_long_bands) +{ + static const float g_mdct_window[2][18] = { + { 0.99904822f,0.99144486f,0.97629601f,0.95371695f,0.92387953f,0.88701083f,0.84339145f,0.79335334f,0.73727734f,0.04361938f,0.13052619f,0.21643961f,0.30070580f,0.38268343f,0.46174861f,0.53729961f,0.60876143f,0.67559021f }, + { 1,1,1,1,1,1,0.99144486f,0.92387953f,0.79335334f,0,0,0,0,0,0,0.13052619f,0.38268343f,0.60876143f } + }; + if (n_long_bands) + { + drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[0], n_long_bands); + grbuf += 18*n_long_bands; + overlap += 9*n_long_bands; + } + if (block_type == DRMP3_SHORT_BLOCK_TYPE) + drmp3_L3_imdct_short(grbuf, overlap, 32 - n_long_bands); + else + drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[block_type == DRMP3_STOP_BLOCK_TYPE], 32 - n_long_bands); +} + +static void drmp3_L3_save_reservoir(drmp3dec *h, drmp3dec_scratch *s) +{ + int pos = (s->bs.pos + 7)/8u; + int remains = s->bs.limit/8u - pos; + if (remains > DRMP3_MAX_BITRESERVOIR_BYTES) + { + pos += remains - DRMP3_MAX_BITRESERVOIR_BYTES; + remains = DRMP3_MAX_BITRESERVOIR_BYTES; + } + if (remains > 0) + { + memmove(h->reserv_buf, s->maindata + pos, remains); + } + h->reserv = remains; +} + +static int drmp3_L3_restore_reservoir(drmp3dec *h, drmp3_bs *bs, drmp3dec_scratch *s, int main_data_begin) +{ + int frame_bytes = (bs->limit - bs->pos)/8; + int bytes_have = DRMP3_MIN(h->reserv, main_data_begin); + memcpy(s->maindata, h->reserv_buf + DRMP3_MAX(0, h->reserv - main_data_begin), DRMP3_MIN(h->reserv, main_data_begin)); + memcpy(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes); + drmp3_bs_init(&s->bs, s->maindata, bytes_have + frame_bytes); + return h->reserv >= main_data_begin; +} + +static void drmp3_L3_decode(drmp3dec *h, drmp3dec_scratch *s, drmp3_L3_gr_info *gr_info, int nch) +{ + int ch; + + for (ch = 0; ch < nch; ch++) + { + int layer3gr_limit = s->bs.pos + gr_info[ch].part_23_length; + drmp3_L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch); + drmp3_L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit); + } + + if (DRMP3_HDR_TEST_I_STEREO(h->header)) + { + drmp3_L3_intensity_stereo(s->grbuf[0], s->ist_pos[1], gr_info, h->header); + } else if (DRMP3_HDR_IS_MS_STEREO(h->header)) + { + drmp3_L3_midside_stereo(s->grbuf[0], 576); + } + + for (ch = 0; ch < nch; ch++, gr_info++) + { + int aa_bands = 31; + int n_long_bands = (gr_info->mixed_block_flag ? 2 : 0) << (int)(DRMP3_HDR_GET_MY_SAMPLE_RATE(h->header) == 2); + + if (gr_info->n_short_sfb) + { + aa_bands = n_long_bands - 1; + drmp3_L3_reorder(s->grbuf[ch] + n_long_bands*18, s->syn[0], gr_info->sfbtab + gr_info->n_long_sfb); + } + + drmp3_L3_antialias(s->grbuf[ch], aa_bands); + drmp3_L3_imdct_gr(s->grbuf[ch], h->mdct_overlap[ch], gr_info->block_type, n_long_bands); + drmp3_L3_change_sign(s->grbuf[ch]); + } +} + +static void drmp3d_DCT_II(float *grbuf, int n) +{ + static const float g_sec[24] = { + 10.19000816f,0.50060302f,0.50241929f,3.40760851f,0.50547093f,0.52249861f,2.05778098f,0.51544732f,0.56694406f,1.48416460f,0.53104258f,0.64682180f,1.16943991f,0.55310392f,0.78815460f,0.97256821f,0.58293498f,1.06067765f,0.83934963f,0.62250412f,1.72244716f,0.74453628f,0.67480832f,5.10114861f + }; + int i, k = 0; +#if DRMP3_HAVE_SIMD + if (drmp3_have_simd()) for (; k < n; k += 4) + { + drmp3_f4 t[4][8], *x; + float *y = grbuf + k; + + for (x = t[0], i = 0; i < 8; i++, x++) + { + drmp3_f4 x0 = DRMP3_VLD(&y[i*18]); + drmp3_f4 x1 = DRMP3_VLD(&y[(15 - i)*18]); + drmp3_f4 x2 = DRMP3_VLD(&y[(16 + i)*18]); + drmp3_f4 x3 = DRMP3_VLD(&y[(31 - i)*18]); + drmp3_f4 t0 = DRMP3_VADD(x0, x3); + drmp3_f4 t1 = DRMP3_VADD(x1, x2); + drmp3_f4 t2 = DRMP3_VMUL_S(DRMP3_VSUB(x1, x2), g_sec[3*i + 0]); + drmp3_f4 t3 = DRMP3_VMUL_S(DRMP3_VSUB(x0, x3), g_sec[3*i + 1]); + x[0] = DRMP3_VADD(t0, t1); + x[8] = DRMP3_VMUL_S(DRMP3_VSUB(t0, t1), g_sec[3*i + 2]); + x[16] = DRMP3_VADD(t3, t2); + x[24] = DRMP3_VMUL_S(DRMP3_VSUB(t3, t2), g_sec[3*i + 2]); + } + for (x = t[0], i = 0; i < 4; i++, x += 8) + { + drmp3_f4 x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt; + xt = DRMP3_VSUB(x0, x7); x0 = DRMP3_VADD(x0, x7); + x7 = DRMP3_VSUB(x1, x6); x1 = DRMP3_VADD(x1, x6); + x6 = DRMP3_VSUB(x2, x5); x2 = DRMP3_VADD(x2, x5); + x5 = DRMP3_VSUB(x3, x4); x3 = DRMP3_VADD(x3, x4); + x4 = DRMP3_VSUB(x0, x3); x0 = DRMP3_VADD(x0, x3); + x3 = DRMP3_VSUB(x1, x2); x1 = DRMP3_VADD(x1, x2); + x[0] = DRMP3_VADD(x0, x1); + x[4] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x1), 0.70710677f); + x5 = DRMP3_VADD(x5, x6); + x6 = DRMP3_VMUL_S(DRMP3_VADD(x6, x7), 0.70710677f); + x7 = DRMP3_VADD(x7, xt); + x3 = DRMP3_VMUL_S(DRMP3_VADD(x3, x4), 0.70710677f); + x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f)); /* rotate by PI/8 */ + x7 = DRMP3_VADD(x7, DRMP3_VMUL_S(x5, 0.382683432f)); + x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f)); + x0 = DRMP3_VSUB(xt, x6); xt = DRMP3_VADD(xt, x6); + x[1] = DRMP3_VMUL_S(DRMP3_VADD(xt, x7), 0.50979561f); + x[2] = DRMP3_VMUL_S(DRMP3_VADD(x4, x3), 0.54119611f); + x[3] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x5), 0.60134488f); + x[5] = DRMP3_VMUL_S(DRMP3_VADD(x0, x5), 0.89997619f); + x[6] = DRMP3_VMUL_S(DRMP3_VSUB(x4, x3), 1.30656302f); + x[7] = DRMP3_VMUL_S(DRMP3_VSUB(xt, x7), 2.56291556f); + } + + if (k > n - 3) + { +#if DRMP3_HAVE_SSE +#define DRMP3_VSAVE2(i, v) _mm_storel_pi((__m64 *)(void*)&y[i*18], v) +#else +#define DRMP3_VSAVE2(i, v) vst1_f32((float32_t *)&y[i*18], vget_low_f32(v)) +#endif + for (i = 0; i < 7; i++, y += 4*18) + { + drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]); + DRMP3_VSAVE2(0, t[0][i]); + DRMP3_VSAVE2(1, DRMP3_VADD(t[2][i], s)); + DRMP3_VSAVE2(2, DRMP3_VADD(t[1][i], t[1][i + 1])); + DRMP3_VSAVE2(3, DRMP3_VADD(t[2][1 + i], s)); + } + DRMP3_VSAVE2(0, t[0][7]); + DRMP3_VSAVE2(1, DRMP3_VADD(t[2][7], t[3][7])); + DRMP3_VSAVE2(2, t[1][7]); + DRMP3_VSAVE2(3, t[3][7]); + } else + { +#define DRMP3_VSAVE4(i, v) DRMP3_VSTORE(&y[i*18], v) + for (i = 0; i < 7; i++, y += 4*18) + { + drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]); + DRMP3_VSAVE4(0, t[0][i]); + DRMP3_VSAVE4(1, DRMP3_VADD(t[2][i], s)); + DRMP3_VSAVE4(2, DRMP3_VADD(t[1][i], t[1][i + 1])); + DRMP3_VSAVE4(3, DRMP3_VADD(t[2][1 + i], s)); + } + DRMP3_VSAVE4(0, t[0][7]); + DRMP3_VSAVE4(1, DRMP3_VADD(t[2][7], t[3][7])); + DRMP3_VSAVE4(2, t[1][7]); + DRMP3_VSAVE4(3, t[3][7]); + } + } else +#endif +#ifdef DR_MP3_ONLY_SIMD + {} +#else + for (; k < n; k++) + { + float t[4][8], *x, *y = grbuf + k; + + for (x = t[0], i = 0; i < 8; i++, x++) + { + float x0 = y[i*18]; + float x1 = y[(15 - i)*18]; + float x2 = y[(16 + i)*18]; + float x3 = y[(31 - i)*18]; + float t0 = x0 + x3; + float t1 = x1 + x2; + float t2 = (x1 - x2)*g_sec[3*i + 0]; + float t3 = (x0 - x3)*g_sec[3*i + 1]; + x[0] = t0 + t1; + x[8] = (t0 - t1)*g_sec[3*i + 2]; + x[16] = t3 + t2; + x[24] = (t3 - t2)*g_sec[3*i + 2]; + } + for (x = t[0], i = 0; i < 4; i++, x += 8) + { + float x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt; + xt = x0 - x7; x0 += x7; + x7 = x1 - x6; x1 += x6; + x6 = x2 - x5; x2 += x5; + x5 = x3 - x4; x3 += x4; + x4 = x0 - x3; x0 += x3; + x3 = x1 - x2; x1 += x2; + x[0] = x0 + x1; + x[4] = (x0 - x1)*0.70710677f; + x5 = x5 + x6; + x6 = (x6 + x7)*0.70710677f; + x7 = x7 + xt; + x3 = (x3 + x4)*0.70710677f; + x5 -= x7*0.198912367f; /* rotate by PI/8 */ + x7 += x5*0.382683432f; + x5 -= x7*0.198912367f; + x0 = xt - x6; xt += x6; + x[1] = (xt + x7)*0.50979561f; + x[2] = (x4 + x3)*0.54119611f; + x[3] = (x0 - x5)*0.60134488f; + x[5] = (x0 + x5)*0.89997619f; + x[6] = (x4 - x3)*1.30656302f; + x[7] = (xt - x7)*2.56291556f; + + } + for (i = 0; i < 7; i++, y += 4*18) + { + y[0*18] = t[0][i]; + y[1*18] = t[2][i] + t[3][i] + t[3][i + 1]; + y[2*18] = t[1][i] + t[1][i + 1]; + y[3*18] = t[2][i + 1] + t[3][i] + t[3][i + 1]; + } + y[0*18] = t[0][7]; + y[1*18] = t[2][7] + t[3][7]; + y[2*18] = t[1][7]; + y[3*18] = t[3][7]; + } +#endif +} + +static short drmp3d_scale_pcm(float sample) +{ + int s; + if (sample > 32767.0) return (short) 32767; + if (sample < -32768.0) return (short)-32768; + s = (int)(sample + .5f); + s -= (s < 0); /* away from zero, to be compliant */ + if (s > 32767) return (short) 32767; + if (s < -32768) return (short)-32768; + return (short)s; +} + +static void drmp3d_synth_pair(short *pcm, int nch, const float *z) +{ + float a; + a = (z[14*64] - z[ 0]) * 29; + a += (z[ 1*64] + z[13*64]) * 213; + a += (z[12*64] - z[ 2*64]) * 459; + a += (z[ 3*64] + z[11*64]) * 2037; + a += (z[10*64] - z[ 4*64]) * 5153; + a += (z[ 5*64] + z[ 9*64]) * 6574; + a += (z[ 8*64] - z[ 6*64]) * 37489; + a += z[ 7*64] * 75038; + pcm[0] = drmp3d_scale_pcm(a); + + z += 2; + a = z[14*64] * 104; + a += z[12*64] * 1567; + a += z[10*64] * 9727; + a += z[ 8*64] * 64019; + a += z[ 6*64] * -9975; + a += z[ 4*64] * -45; + a += z[ 2*64] * 146; + a += z[ 0*64] * -5; + pcm[16*nch] = drmp3d_scale_pcm(a); +} + +static void drmp3d_synth(float *xl, short *dstl, int nch, float *lins) +{ + int i; + float *xr = xl + 576*(nch - 1); + short *dstr = dstl + (nch - 1); + + static const float g_win[] = { + -1,26,-31,208,218,401,-519,2063,2000,4788,-5517,7134,5959,35640,-39336,74992, + -1,24,-35,202,222,347,-581,2080,1952,4425,-5879,7640,5288,33791,-41176,74856, + -1,21,-38,196,225,294,-645,2087,1893,4063,-6237,8092,4561,31947,-43006,74630, + -1,19,-41,190,227,244,-711,2085,1822,3705,-6589,8492,3776,30112,-44821,74313, + -1,17,-45,183,228,197,-779,2075,1739,3351,-6935,8840,2935,28289,-46617,73908, + -1,16,-49,176,228,153,-848,2057,1644,3004,-7271,9139,2037,26482,-48390,73415, + -2,14,-53,169,227,111,-919,2032,1535,2663,-7597,9389,1082,24694,-50137,72835, + -2,13,-58,161,224,72,-991,2001,1414,2330,-7910,9592,70,22929,-51853,72169, + -2,11,-63,154,221,36,-1064,1962,1280,2006,-8209,9750,-998,21189,-53534,71420, + -2,10,-68,147,215,2,-1137,1919,1131,1692,-8491,9863,-2122,19478,-55178,70590, + -3,9,-73,139,208,-29,-1210,1870,970,1388,-8755,9935,-3300,17799,-56778,69679, + -3,8,-79,132,200,-57,-1283,1817,794,1095,-8998,9966,-4533,16155,-58333,68692, + -4,7,-85,125,189,-83,-1356,1759,605,814,-9219,9959,-5818,14548,-59838,67629, + -4,7,-91,117,177,-106,-1428,1698,402,545,-9416,9916,-7154,12980,-61289,66494, + -5,6,-97,111,163,-127,-1498,1634,185,288,-9585,9838,-8540,11455,-62684,65290 + }; + float *zlin = lins + 15*64; + const float *w = g_win; + + zlin[4*15] = xl[18*16]; + zlin[4*15 + 1] = xr[18*16]; + zlin[4*15 + 2] = xl[0]; + zlin[4*15 + 3] = xr[0]; + + zlin[4*31] = xl[1 + 18*16]; + zlin[4*31 + 1] = xr[1 + 18*16]; + zlin[4*31 + 2] = xl[1]; + zlin[4*31 + 3] = xr[1]; + + drmp3d_synth_pair(dstr, nch, lins + 4*15 + 1); + drmp3d_synth_pair(dstr + 32*nch, nch, lins + 4*15 + 64 + 1); + drmp3d_synth_pair(dstl, nch, lins + 4*15); + drmp3d_synth_pair(dstl + 32*nch, nch, lins + 4*15 + 64); + +#if DRMP3_HAVE_SIMD + if (drmp3_have_simd()) for (i = 14; i >= 0; i--) + { +#define DRMP3_VLOAD(k) drmp3_f4 w0 = DRMP3_VSET(*w++); drmp3_f4 w1 = DRMP3_VSET(*w++); drmp3_f4 vz = DRMP3_VLD(&zlin[4*i - 64*k]); drmp3_f4 vy = DRMP3_VLD(&zlin[4*i - 64*(15 - k)]); +#define DRMP3_V0(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0)) ; a = DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1)); } +#define DRMP3_V1(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1))); } +#define DRMP3_V2(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vy, w1), DRMP3_VMUL(vz, w0))); } + drmp3_f4 a, b; + zlin[4*i] = xl[18*(31 - i)]; + zlin[4*i + 1] = xr[18*(31 - i)]; + zlin[4*i + 2] = xl[1 + 18*(31 - i)]; + zlin[4*i + 3] = xr[1 + 18*(31 - i)]; + zlin[4*i + 64] = xl[1 + 18*(1 + i)]; + zlin[4*i + 64 + 1] = xr[1 + 18*(1 + i)]; + zlin[4*i - 64 + 2] = xl[18*(1 + i)]; + zlin[4*i - 64 + 3] = xr[18*(1 + i)]; + + DRMP3_V0(0) DRMP3_V2(1) DRMP3_V1(2) DRMP3_V2(3) DRMP3_V1(4) DRMP3_V2(5) DRMP3_V1(6) DRMP3_V2(7) + + { +#if DRMP3_HAVE_SSE + static const drmp3_f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f }; + static const drmp3_f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f }; + __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)), + _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min))); + dstr[(15 - i)*nch] = (short)_mm_extract_epi16(pcm8, 1); + dstr[(17 + i)*nch] = (short)_mm_extract_epi16(pcm8, 5); + dstl[(15 - i)*nch] = (short)_mm_extract_epi16(pcm8, 0); + dstl[(17 + i)*nch] = (short)_mm_extract_epi16(pcm8, 4); + dstr[(47 - i)*nch] = (short)_mm_extract_epi16(pcm8, 3); + dstr[(49 + i)*nch] = (short)_mm_extract_epi16(pcm8, 7); + dstl[(47 - i)*nch] = (short)_mm_extract_epi16(pcm8, 2); + dstl[(49 + i)*nch] = (short)_mm_extract_epi16(pcm8, 6); +#else + int16x4_t pcma, pcmb; + a = DRMP3_VADD(a, DRMP3_VSET(0.5f)); + b = DRMP3_VADD(b, DRMP3_VSET(0.5f)); + pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0))))); + pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0))))); + vst1_lane_s16(dstr + (15 - i)*nch, pcma, 1); + vst1_lane_s16(dstr + (17 + i)*nch, pcmb, 1); + vst1_lane_s16(dstl + (15 - i)*nch, pcma, 0); + vst1_lane_s16(dstl + (17 + i)*nch, pcmb, 0); + vst1_lane_s16(dstr + (47 - i)*nch, pcma, 3); + vst1_lane_s16(dstr + (49 + i)*nch, pcmb, 3); + vst1_lane_s16(dstl + (47 - i)*nch, pcma, 2); + vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2); +#endif + } + } else +#endif +#ifdef DR_MP3_ONLY_SIMD + {} +#else + for (i = 14; i >= 0; i--) + { +#define DRMP3_LOAD(k) float w0 = *w++; float w1 = *w++; float *vz = &zlin[4*i - k*64]; float *vy = &zlin[4*i - (15 - k)*64]; +#define DRMP3_S0(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] = vz[j]*w1 + vy[j]*w0, a[j] = vz[j]*w0 - vy[j]*w1; } +#define DRMP3_S1(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vz[j]*w0 - vy[j]*w1; } +#define DRMP3_S2(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vy[j]*w1 - vz[j]*w0; } + float a[4], b[4]; + + zlin[4*i] = xl[18*(31 - i)]; + zlin[4*i + 1] = xr[18*(31 - i)]; + zlin[4*i + 2] = xl[1 + 18*(31 - i)]; + zlin[4*i + 3] = xr[1 + 18*(31 - i)]; + zlin[4*(i + 16)] = xl[1 + 18*(1 + i)]; + zlin[4*(i + 16) + 1] = xr[1 + 18*(1 + i)]; + zlin[4*(i - 16) + 2] = xl[18*(1 + i)]; + zlin[4*(i - 16) + 3] = xr[18*(1 + i)]; + + DRMP3_S0(0) DRMP3_S2(1) DRMP3_S1(2) DRMP3_S2(3) DRMP3_S1(4) DRMP3_S2(5) DRMP3_S1(6) DRMP3_S2(7) + + dstr[(15 - i)*nch] = drmp3d_scale_pcm(a[1]); + dstr[(17 + i)*nch] = drmp3d_scale_pcm(b[1]); + dstl[(15 - i)*nch] = drmp3d_scale_pcm(a[0]); + dstl[(17 + i)*nch] = drmp3d_scale_pcm(b[0]); + dstr[(47 - i)*nch] = drmp3d_scale_pcm(a[3]); + dstr[(49 + i)*nch] = drmp3d_scale_pcm(b[3]); + dstl[(47 - i)*nch] = drmp3d_scale_pcm(a[2]); + dstl[(49 + i)*nch] = drmp3d_scale_pcm(b[2]); + } +#endif +} + +static void drmp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int nch, short *pcm, float *lins) +{ + int i; + for (i = 0; i < nch; i++) + { + drmp3d_DCT_II(grbuf + 576*i, nbands); + } + + memcpy(lins, qmf_state, sizeof(float)*15*64); + + for (i = 0; i < nbands; i += 2) + { + drmp3d_synth(grbuf + i, pcm + 32*nch*i, nch, lins + i*64); + } +#ifndef DR_MP3_NONSTANDARD_BUT_LOGICAL + if (nch == 1) + { + for (i = 0; i < 15*64; i += 2) + { + qmf_state[i] = lins[nbands*64 + i]; + } + } else +#endif + { + memcpy(qmf_state, lins + nbands*64, sizeof(float)*15*64); + } +} + +static int drmp3d_match_frame(const drmp3_uint8 *hdr, int mp3_bytes, int frame_bytes) +{ + int i, nmatch; + for (i = 0, nmatch = 0; nmatch < DRMP3_MAX_FRAME_SYNC_MATCHES; nmatch++) + { + i += drmp3_hdr_frame_bytes(hdr + i, frame_bytes) + drmp3_hdr_padding(hdr + i); + if (i + DRMP3_HDR_SIZE > mp3_bytes) + return nmatch > 0; + if (!drmp3_hdr_compare(hdr, hdr + i)) + return 0; + } + return 1; +} + +static int drmp3d_find_frame(const drmp3_uint8 *mp3, int mp3_bytes, int *free_format_bytes, int *ptr_frame_bytes) +{ + int i, k; + for (i = 0; i < mp3_bytes - DRMP3_HDR_SIZE; i++, mp3++) + { + if (drmp3_hdr_valid(mp3)) + { + int frame_bytes = drmp3_hdr_frame_bytes(mp3, *free_format_bytes); + int frame_and_padding = frame_bytes + drmp3_hdr_padding(mp3); + + for (k = DRMP3_HDR_SIZE; !frame_bytes && k < DRMP3_MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - DRMP3_HDR_SIZE; k++) + { + if (drmp3_hdr_compare(mp3, mp3 + k)) + { + int fb = k - drmp3_hdr_padding(mp3); + int nextfb = fb + drmp3_hdr_padding(mp3 + k); + if (i + k + nextfb + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + k + nextfb)) + continue; + frame_and_padding = k; + frame_bytes = fb; + *free_format_bytes = fb; + } + } + + if ((frame_bytes && i + frame_and_padding <= mp3_bytes && + drmp3d_match_frame(mp3, mp3_bytes - i, frame_bytes)) || + (!i && frame_and_padding == mp3_bytes)) + { + *ptr_frame_bytes = frame_and_padding; + return i; + } + *free_format_bytes = 0; + } + } + *ptr_frame_bytes = 0; + return i; +} + +void drmp3dec_init(drmp3dec *dec) +{ + dec->header[0] = 0; +} + +int drmp3dec_decode_frame(drmp3dec *dec, const unsigned char *mp3, int mp3_bytes, short *pcm, drmp3dec_frame_info *info) +{ + int i = 0, igr, frame_size = 0, success = 1; + const drmp3_uint8 *hdr; + drmp3_bs bs_frame[1]; + drmp3dec_scratch scratch; + + if (mp3_bytes > 4 && dec->header[0] == 0xff && drmp3_hdr_compare(dec->header, mp3)) + { + frame_size = drmp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + drmp3_hdr_padding(mp3); + if (frame_size != mp3_bytes && (frame_size + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + frame_size))) + { + frame_size = 0; + } + } + if (!frame_size) + { + memset(dec, 0, sizeof(drmp3dec)); + i = drmp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size); + if (!frame_size || i + frame_size > mp3_bytes) + { + info->frame_bytes = i; + return 0; + } + } + + hdr = mp3 + i; + memcpy(dec->header, hdr, DRMP3_HDR_SIZE); + info->frame_bytes = i + frame_size; + info->channels = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2; + info->hz = drmp3_hdr_sample_rate_hz(hdr); + info->layer = 4 - DRMP3_HDR_GET_LAYER(hdr); + info->bitrate_kbps = drmp3_hdr_bitrate_kbps(hdr); + + drmp3_bs_init(bs_frame, hdr + DRMP3_HDR_SIZE, frame_size - DRMP3_HDR_SIZE); + if (DRMP3_HDR_IS_CRC(hdr)) + { + drmp3_bs_get_bits(bs_frame, 16); + } + + if (info->layer == 3) + { + int main_data_begin = drmp3_L3_read_side_info(bs_frame, scratch.gr_info, hdr); + if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit) + { + drmp3dec_init(dec); + return 0; + } + success = drmp3_L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin); + if (success) + { + for (igr = 0; igr < (DRMP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm += 576*info->channels) + { + memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + drmp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels); + drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, pcm, scratch.syn[0]); + } + } + drmp3_L3_save_reservoir(dec, &scratch); + } else + { +#ifdef DR_MP3_ONLY_MP3 + return 0; +#else + drmp3_L12_scale_info sci[1]; + drmp3_L12_read_scale_info(hdr, bs_frame, sci); + + memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + for (i = 0, igr = 0; igr < 3; igr++) + { + if (12 == (i += drmp3_L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1))) + { + i = 0; + drmp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]); + drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, pcm, scratch.syn[0]); + memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + pcm += 384*info->channels; + } + if (bs_frame->pos > bs_frame->limit) + { + drmp3dec_init(dec); + return 0; + } + } +#endif + } + return success*drmp3_hdr_frame_samples(dec->header); +} + + + + +/* + * + * Main Public API + * + */ + +/* Options. */ +#ifndef DR_MP3_DEFAULT_CHANNELS +#define DR_MP3_DEFAULT_CHANNELS 2 +#endif +#ifndef DR_MP3_DEFAULT_SAMPLE_RATE +#define DR_MP3_DEFAULT_SAMPLE_RATE 44100 +#endif + +/* Standard library stuff. */ +#ifndef DRMP3_ASSERT +#include +#define DRMP3_ASSERT(expression) assert(expression) +#endif +#ifndef DRMP3_COPY_MEMORY +#define DRMP3_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz)) +#endif +#ifndef DRMP3_ZERO_MEMORY +#define DRMP3_ZERO_MEMORY(p, sz) memset((p), 0, (sz)) +#endif +#define DRMP3_ZERO_OBJECT(p) DRMP3_ZERO_MEMORY((p), sizeof(*(p))) +#ifndef DRMP3_MALLOC +#define DRMP3_MALLOC(sz) malloc((sz)) +#endif +#ifndef DRMP3_REALLOC +#define DRMP3_REALLOC(p, sz) realloc((p), (sz)) +#endif +#ifndef DRMP3_FREE +#define DRMP3_FREE(p) free((p)) +#endif + +#define drmp3_assert DRMP3_ASSERT +#define drmp3_copy_memory DRMP3_COPY_MEMORY +#define drmp3_zero_memory DRMP3_ZERO_MEMORY +#define drmp3_zero_object DRMP3_ZERO_OBJECT +#define drmp3_malloc DRMP3_MALLOC +#define drmp3_realloc DRMP3_REALLOC + +#define drmp3_countof(x) (sizeof(x) / sizeof(x[0])) +#define drmp3_max(x, y) (((x) > (y)) ? (x) : (y)) +#define drmp3_min(x, y) (((x) < (y)) ? (x) : (y)) + +#define DRMP3_DATA_CHUNK_SIZE 16384 /* The size in bytes of each chunk of data to read from the MP3 stream. minimp3 recommends 16K. */ + +static INLINE float drmp3_mix_f32(float x, float y, float a) +{ + return x*(1-a) + y*a; +} + +static void drmp3_blend_f32(float* pOut, float* pInA, float* pInB, float factor, drmp3_uint32 channels) +{ + uint32_t i; + for (i = 0; i < channels; ++i) + pOut[i] = drmp3_mix_f32(pInA[i], pInB[i], factor); +} + +void drmp3_src_cache_init(drmp3_src* pSRC, drmp3_src_cache* pCache) +{ + drmp3_assert(pSRC != NULL); + drmp3_assert(pCache != NULL); + + pCache->pSRC = pSRC; + pCache->cachedFrameCount = 0; + pCache->iNextFrame = 0; +} + +drmp3_uint64 drmp3_src_cache_read_frames(drmp3_src_cache* pCache, drmp3_uint64 frameCount, float* pFramesOut) +{ + drmp3_uint32 channels; + drmp3_uint64 totalFramesRead = 0; + + drmp3_assert(pCache != NULL); + drmp3_assert(pCache->pSRC != NULL); + drmp3_assert(pCache->pSRC->onRead != NULL); + drmp3_assert(frameCount > 0); + drmp3_assert(pFramesOut != NULL); + + channels = pCache->pSRC->config.channels; + + while (frameCount > 0) + { + drmp3_uint32 framesToReadFromClient; + /* If there's anything in memory go ahead and copy that over first. */ + drmp3_uint64 framesRemainingInMemory = pCache->cachedFrameCount - pCache->iNextFrame; + drmp3_uint64 framesToReadFromMemory = frameCount; + if (framesToReadFromMemory > framesRemainingInMemory) + framesToReadFromMemory = framesRemainingInMemory; + + drmp3_copy_memory(pFramesOut, pCache->pCachedFrames + pCache->iNextFrame*channels, (drmp3_uint32)(framesToReadFromMemory * channels * sizeof(float))); + pCache->iNextFrame += (drmp3_uint32)framesToReadFromMemory; + + totalFramesRead += framesToReadFromMemory; + frameCount -= framesToReadFromMemory; + if (frameCount == 0) + break; + + + /* At this point there are still more frames to read from the client, so we'll need to reload the cache with fresh data. */ + drmp3_assert(frameCount > 0); + pFramesOut += framesToReadFromMemory * channels; + + pCache->iNextFrame = 0; + pCache->cachedFrameCount = 0; + + framesToReadFromClient = drmp3_countof(pCache->pCachedFrames) / pCache->pSRC->config.channels; + if (framesToReadFromClient > pCache->pSRC->config.cacheSizeInFrames) + framesToReadFromClient = pCache->pSRC->config.cacheSizeInFrames; + + pCache->cachedFrameCount = (drmp3_uint32)pCache->pSRC->onRead(pCache->pSRC, framesToReadFromClient, pCache->pCachedFrames, pCache->pSRC->pUserData); + + + /* Get out of this loop if nothing was able to be retrieved. */ + if (pCache->cachedFrameCount == 0) + break; + } + + return totalFramesRead; +} + + +drmp3_uint64 drmp3_src_read_frames_passthrough(drmp3_src* pSRC, drmp3_uint64 frameCount, void* pFramesOut, drmp3_bool32 flush); +drmp3_uint64 drmp3_src_read_frames_linear(drmp3_src* pSRC, drmp3_uint64 frameCount, void* pFramesOut, drmp3_bool32 flush); + +drmp3_bool32 drmp3_src_init(const drmp3_src_config* pConfig, drmp3_src_read_proc onRead, void* pUserData, drmp3_src* pSRC) +{ + if (pSRC == NULL) return DRMP3_FALSE; + drmp3_zero_object(pSRC); + + if (pConfig == NULL || onRead == NULL) return DRMP3_FALSE; + if (pConfig->channels == 0 || pConfig->channels > 2) return DRMP3_FALSE; + + pSRC->config = *pConfig; + pSRC->onRead = onRead; + pSRC->pUserData = pUserData; + + if (pSRC->config.cacheSizeInFrames > DRMP3_SRC_CACHE_SIZE_IN_FRAMES || pSRC->config.cacheSizeInFrames == 0) + pSRC->config.cacheSizeInFrames = DRMP3_SRC_CACHE_SIZE_IN_FRAMES; + + drmp3_src_cache_init(pSRC, &pSRC->cache); + return DRMP3_TRUE; +} + +drmp3_bool32 drmp3_src_set_input_sample_rate(drmp3_src* pSRC, drmp3_uint32 sampleRateIn) +{ + if (pSRC == NULL) return DRMP3_FALSE; + + /* Must have a sample rate of > 0. */ + if (sampleRateIn == 0) + return DRMP3_FALSE; + + pSRC->config.sampleRateIn = sampleRateIn; + return DRMP3_TRUE; +} + +drmp3_bool32 drmp3_src_set_output_sample_rate(drmp3_src* pSRC, drmp3_uint32 sampleRateOut) +{ + if (pSRC == NULL) return DRMP3_FALSE; + + /* Must have a sample rate of > 0. */ + if (sampleRateOut == 0) + return DRMP3_FALSE; + + pSRC->config.sampleRateOut = sampleRateOut; + return DRMP3_TRUE; +} + +drmp3_uint64 drmp3_src_read_frames_ex(drmp3_src* pSRC, drmp3_uint64 frameCount, void* pFramesOut, drmp3_bool32 flush) +{ + drmp3_src_algorithm algorithm; + if (pSRC == NULL || frameCount == 0 || pFramesOut == NULL) return 0; + + algorithm = pSRC->config.algorithm; + + /* Always use passthrough if the sample rates are the same. */ + if (pSRC->config.sampleRateIn == pSRC->config.sampleRateOut) + algorithm = drmp3_src_algorithm_none; + + /* Could just use a function pointer instead of a switch for this... */ + switch (algorithm) + { + case drmp3_src_algorithm_none: return drmp3_src_read_frames_passthrough(pSRC, frameCount, pFramesOut, flush); + case drmp3_src_algorithm_linear: return drmp3_src_read_frames_linear(pSRC, frameCount, pFramesOut, flush); + default: return 0; + } +} + +drmp3_uint64 drmp3_src_read_frames(drmp3_src* pSRC, drmp3_uint64 frameCount, void* pFramesOut) +{ + return drmp3_src_read_frames_ex(pSRC, frameCount, pFramesOut, DRMP3_FALSE); +} + +drmp3_uint64 drmp3_src_read_frames_passthrough(drmp3_src* pSRC, drmp3_uint64 frameCount, void* pFramesOut, drmp3_bool32 flush) +{ + drmp3_assert(pSRC != NULL); + drmp3_assert(frameCount > 0); + drmp3_assert(pFramesOut != NULL); + + (void)flush; /* Passthrough need not care about flushing. */ + return pSRC->onRead(pSRC, frameCount, pFramesOut, pSRC->pUserData); +} + +drmp3_uint64 drmp3_src_read_frames_linear(drmp3_src* pSRC, drmp3_uint64 frameCount, void* pFramesOut, drmp3_bool32 flush) +{ + float factor; + drmp3_uint64 totalFramesRead = 0; + + drmp3_assert(pSRC != NULL); + drmp3_assert(frameCount > 0); + drmp3_assert(pFramesOut != NULL); + + /* For linear SRC, the bin is only 2 frames: 1 prior, 1 future. */ + + /* Load the bin if necessary. */ + if (!pSRC->algo.linear.isPrevFramesLoaded) + { + drmp3_uint64 framesRead = drmp3_src_cache_read_frames(&pSRC->cache, 1, pSRC->bin); + if (framesRead == 0) + return 0; + pSRC->algo.linear.isPrevFramesLoaded = DRMP3_TRUE; + } + if (!pSRC->algo.linear.isNextFramesLoaded) + { + drmp3_uint64 framesRead = drmp3_src_cache_read_frames(&pSRC->cache, 1, pSRC->bin + pSRC->config.channels); + if (framesRead == 0) + return 0; + pSRC->algo.linear.isNextFramesLoaded = DRMP3_TRUE; + } + + factor = (float)pSRC->config.sampleRateIn / pSRC->config.sampleRateOut; + + while (frameCount > 0) + { + drmp3_uint32 i; + drmp3_uint32 framesToReadFromClient; + /* The bin is where the previous and next frames are located. */ + float* pPrevFrame = pSRC->bin; + float* pNextFrame = pSRC->bin + pSRC->config.channels; + + drmp3_blend_f32((float*)pFramesOut, pPrevFrame, pNextFrame, pSRC->algo.linear.alpha, pSRC->config.channels); + + pSRC->algo.linear.alpha += factor; + + /* The new alpha value is how we determine whether or not we need to read fresh frames. */ + framesToReadFromClient = (drmp3_uint32)pSRC->algo.linear.alpha; + pSRC->algo.linear.alpha = pSRC->algo.linear.alpha - framesToReadFromClient; + + for (i = 0; i < framesToReadFromClient; ++i) + { + drmp3_uint32 j; + drmp3_uint64 framesRead; + for (j = 0; j < pSRC->config.channels; ++j) + pPrevFrame[j] = pNextFrame[j]; + + framesRead = drmp3_src_cache_read_frames(&pSRC->cache, 1, pNextFrame); + if (framesRead == 0) + { + drmp3_uint32 j; + for (j = 0; j < pSRC->config.channels; ++j) + pNextFrame[j] = 0; + + if (pSRC->algo.linear.isNextFramesLoaded) + pSRC->algo.linear.isNextFramesLoaded = DRMP3_FALSE; + else + { + if (flush) + pSRC->algo.linear.isPrevFramesLoaded = DRMP3_FALSE; + } + + break; + } + } + + pFramesOut = (drmp3_uint8*)pFramesOut + (1 * pSRC->config.channels * sizeof(float)); + frameCount -= 1; + totalFramesRead += 1; + + /* If there's no frames available we need to get out of this loop. */ + if (!pSRC->algo.linear.isNextFramesLoaded && (!flush || !pSRC->algo.linear.isPrevFramesLoaded)) + break; + } + + return totalFramesRead; +} + + + +static drmp3_bool32 drmp3_decode_next_frame(drmp3* pMP3) +{ + drmp3_assert(pMP3 != NULL); + drmp3_assert(pMP3->onRead != NULL); + + if (pMP3->atEnd) + return DRMP3_FALSE; + + do + { + drmp3dec_frame_info info; + drmp3_uint32 samplesRead; + + /* minimp3 recommends doing data submission in 16K chunks. If we don't have at least 16K bytes available, get more. */ + if (pMP3->dataSize < DRMP3_DATA_CHUNK_SIZE) + { + size_t bytesRead; + + if (pMP3->dataCapacity < DRMP3_DATA_CHUNK_SIZE) + { + drmp3_uint8* pNewData = NULL; + pMP3->dataCapacity = DRMP3_DATA_CHUNK_SIZE; + + pNewData = (drmp3_uint8*) + drmp3_realloc(pMP3->pData, pMP3->dataCapacity); + if (pNewData == NULL) + return DRMP3_FALSE; /* Out of memory. */ + + pMP3->pData = pNewData; + } + + bytesRead = pMP3->onRead(pMP3->pUserData, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize)); + if (bytesRead == 0) + { + pMP3->atEnd = DRMP3_TRUE; + return DRMP3_FALSE; /* No data. */ + } + + pMP3->dataSize += bytesRead; + } + + if (pMP3->dataSize > INT_MAX) + { + pMP3->atEnd = DRMP3_TRUE; + return DRMP3_FALSE; /* File too big. */ + } + + samplesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData, (int)pMP3->dataSize, pMP3->frames, &info); /* <-- Safe size_t -> int conversion thanks to the check above. */ + if (samplesRead != 0) + { + size_t i; + size_t leftoverDataSize = (pMP3->dataSize - (size_t)info.frame_bytes); + for (i = 0; i < leftoverDataSize; ++i) + pMP3->pData[i] = pMP3->pData[i + (size_t)info.frame_bytes]; + + pMP3->dataSize = leftoverDataSize; + pMP3->framesConsumed = 0; + pMP3->framesRemaining = samplesRead; + pMP3->frameChannels = info.channels; + pMP3->frameSampleRate = info.hz; + drmp3_src_set_input_sample_rate(&pMP3->src, pMP3->frameSampleRate); + break; + } + else + { + size_t bytesRead; + /* Need more data. minimp3 recommends doing data submission in 16K chunks. */ + if (pMP3->dataCapacity == pMP3->dataSize) + { + drmp3_uint8 *pNewData = NULL; + /* No room. Expand. */ + pMP3->dataCapacity += DRMP3_DATA_CHUNK_SIZE; + + pNewData = (drmp3_uint8*)drmp3_realloc(pMP3->pData, pMP3->dataCapacity); + if (pNewData == NULL) + return DRMP3_FALSE; /* Out of memory. */ + + pMP3->pData = pNewData; + } + + /* Fill in a chunk. */ + bytesRead = pMP3->onRead(pMP3->pUserData, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize)); + if (bytesRead == 0) + { + pMP3->atEnd = DRMP3_TRUE; + return DRMP3_FALSE; /* Error reading more data. */ + } + + pMP3->dataSize += bytesRead; + } + } while (DRMP3_TRUE); + + return DRMP3_TRUE; +} + +static drmp3_uint64 drmp3_read_src(drmp3_src* pSRC, drmp3_uint64 frameCount, void* pFramesOut, void* pUserData) +{ + float* pFramesOutF; + drmp3_uint32 totalFramesRead = 0; + drmp3* pMP3 = (drmp3*)pUserData; + + drmp3_assert(pMP3 != NULL); + drmp3_assert(pMP3->onRead != NULL); + + pFramesOutF = (float*)pFramesOut; + + while (frameCount > 0) + { + /* Read from the in-memory buffer first. */ + while (pMP3->framesRemaining > 0 && frameCount > 0) + { + if (pMP3->frameChannels == 1) + { + if (pMP3->channels == 1) + { + /* Mono -> Mono. */ + pFramesOutF[0] = pMP3->frames[pMP3->framesConsumed] / 32768.0f; + } else { + /* Mono -> Stereo. */ + pFramesOutF[0] = pMP3->frames[pMP3->framesConsumed] / 32768.0f; + pFramesOutF[1] = pMP3->frames[pMP3->framesConsumed] / 32768.0f; + } + } else { + if (pMP3->channels == 1) + { + /* Stereo -> Mono */ + float sample = 0; + sample += pMP3->frames[(pMP3->framesConsumed*pMP3->frameChannels)+0] / 32768.0f; + sample += pMP3->frames[(pMP3->framesConsumed*pMP3->frameChannels)+1] / 32768.0f; + pFramesOutF[0] = sample * 0.5f; + } else { + /* Stereo -> Stereo */ + pFramesOutF[0] = pMP3->frames[(pMP3->framesConsumed*pMP3->frameChannels)+0] / 32768.0f; + pFramesOutF[1] = pMP3->frames[(pMP3->framesConsumed*pMP3->frameChannels)+1] / 32768.0f; + } + } + + pMP3->framesConsumed += 1; + pMP3->framesRemaining -= 1; + frameCount -= 1; + totalFramesRead += 1; + pFramesOutF += pSRC->config.channels; + } + + if (frameCount == 0) + break; + + drmp3_assert(pMP3->framesRemaining == 0); + + /* At this point we have exhausted our in-memory buffer so we need to re-fill. Note that the sample rate may have changed + * at this point which means we'll also need to update our sample rate conversion pipeline. */ + if (!drmp3_decode_next_frame(pMP3)) + break; + } + + return totalFramesRead; +} + +drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_config* pConfig) +{ + drmp3_config config; + drmp3_src_config srcConfig; + + drmp3_assert(pMP3 != NULL); + drmp3_assert(onRead != NULL); + + /* This function assumes the output object has already been reset to 0. Do not do that here, otherwise things will break. */ + drmp3dec_init(&pMP3->decoder); + + /* The config can be null in which case we use defaults. */ + if (pConfig != NULL) + config = *pConfig; + else + drmp3_zero_object(&config); + + pMP3->channels = config.outputChannels; + if (pMP3->channels == 0) + pMP3->channels = DR_MP3_DEFAULT_CHANNELS; + + /* Cannot have more than 2 channels. */ + if (pMP3->channels > 2) + pMP3->channels = 2; + + pMP3->sampleRate = config.outputSampleRate; + if (pMP3->sampleRate == 0) + pMP3->sampleRate = DR_MP3_DEFAULT_SAMPLE_RATE; + + pMP3->onRead = onRead; + pMP3->onSeek = onSeek; + pMP3->pUserData = pUserData; + + /* We need a sample rate converter for converting the sample rate from the MP3 frames to the requested output sample rate. */ + drmp3_zero_object(&srcConfig); + srcConfig.sampleRateIn = DR_MP3_DEFAULT_SAMPLE_RATE; + srcConfig.sampleRateOut = pMP3->sampleRate; + srcConfig.channels = pMP3->channels; + srcConfig.algorithm = drmp3_src_algorithm_linear; + if (!drmp3_src_init(&srcConfig, drmp3_read_src, pMP3, &pMP3->src)) + return DRMP3_FALSE; + + /* Decode the first frame to confirm that it is indeed a valid MP3 stream. */ + if (!drmp3_decode_next_frame(pMP3)) + return DRMP3_FALSE; /* Not a valid MP3 stream. */ + + return DRMP3_TRUE; +} + +drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_config* pConfig) +{ + if (pMP3 == NULL || onRead == NULL) + return DRMP3_FALSE; + + drmp3_zero_object(pMP3); + return drmp3_init_internal(pMP3, onRead, onSeek, pUserData, pConfig); +} + + +static size_t drmp3__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead) +{ + size_t bytesRemaining; + drmp3* pMP3 = (drmp3*)pUserData; + drmp3_assert(pMP3 != NULL); + drmp3_assert(pMP3->memory.dataSize >= pMP3->memory.currentReadPos); + + bytesRemaining = pMP3->memory.dataSize - pMP3->memory.currentReadPos; + if (bytesToRead > bytesRemaining) + bytesToRead = bytesRemaining; + + if (bytesToRead > 0) + { + drmp3_copy_memory(pBufferOut, pMP3->memory.pData + pMP3->memory.currentReadPos, bytesToRead); + pMP3->memory.currentReadPos += bytesToRead; + } + + return bytesToRead; +} + +static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3_seek_origin origin) +{ + drmp3* pMP3 = (drmp3*)pUserData; + drmp3_assert(pMP3 != NULL); + + if (origin == drmp3_seek_origin_current) + { + if (byteOffset > 0) + { + if (pMP3->memory.currentReadPos + byteOffset > pMP3->memory.dataSize) + byteOffset = (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos); /* Trying to seek too far forward. */ + } + else + { + if (pMP3->memory.currentReadPos < (size_t)-byteOffset) + byteOffset = -(int)pMP3->memory.currentReadPos; /* Trying to seek too far backwards. */ + } + + /* This will never underflow thanks to the clamps above. */ + pMP3->memory.currentReadPos += byteOffset; + } else { + if ((drmp3_uint32)byteOffset <= pMP3->memory.dataSize) + pMP3->memory.currentReadPos = byteOffset; + else + pMP3->memory.currentReadPos = pMP3->memory.dataSize; /* Trying to seek too far forward. */ + } + + return DRMP3_TRUE; +} + +drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_config* pConfig) +{ + if (pMP3 == NULL) + return DRMP3_FALSE; + + drmp3_zero_object(pMP3); + + if (pData == NULL || dataSize == 0) + return DRMP3_FALSE; + + pMP3->memory.pData = (const drmp3_uint8*)pData; + pMP3->memory.dataSize = dataSize; + pMP3->memory.currentReadPos = 0; + + return drmp3_init_internal(pMP3, drmp3__on_read_memory, drmp3__on_seek_memory, pMP3, pConfig); +} + + +#ifndef DR_MP3_NO_STDIO +#include + +static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead) +{ + return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData); +} + +static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek_origin origin) +{ + return fseek((FILE*)pUserData, offset, (origin == drmp3_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0; +} + +drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* filePath, const drmp3_config* pConfig) +{ + FILE* pFile; +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (fopen_s(&pFile, filePath, "rb") != 0) + return DRMP3_FALSE; +#else + pFile = fopen(filePath, "rb"); + if (pFile == NULL) + return DRMP3_FALSE; +#endif + + return drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pConfig); +} +#endif + +void drmp3_uninit(drmp3* pMP3) +{ + if (pMP3 == NULL) return; + +#ifndef DR_MP3_NO_STDIO + if (pMP3->onRead == drmp3__on_read_stdio) + fclose((FILE*)pMP3->pUserData); +#endif + + drmp3_free(pMP3->pData); +} + +drmp3_uint64 drmp3_read_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut) +{ + drmp3_uint64 totalFramesRead = 0; + if (pMP3 == NULL || pMP3->onRead == NULL) return 0; + + if (pBufferOut == NULL) + { + float temp[4096]; + while (framesToRead > 0) + { + drmp3_uint64 framesJustRead; + drmp3_uint64 framesToReadRightNow = sizeof(temp)/sizeof(temp[0]) / pMP3->channels; + if (framesToReadRightNow > framesToRead) + framesToReadRightNow = framesToRead; + + framesJustRead = drmp3_read_f32(pMP3, framesToReadRightNow, temp); + if (framesJustRead == 0) + break; + + framesToRead -= framesJustRead; + totalFramesRead += framesJustRead; + } + } else { + totalFramesRead = drmp3_src_read_frames_ex(&pMP3->src, framesToRead, pBufferOut, DRMP3_TRUE); + } + + return totalFramesRead; +} + +drmp3_bool32 drmp3_seek_to_frame(drmp3* pMP3, drmp3_uint64 frameIndex) +{ + drmp3_uint64 framesRead; + + if (pMP3 == NULL || pMP3->onSeek == NULL) return DRMP3_FALSE; + + /* Seek to the start of the stream to begin with. */ + if (!pMP3->onSeek(pMP3->pUserData, 0, drmp3_seek_origin_start)) + return DRMP3_FALSE; + + /* Clear any cached data. */ + pMP3->framesConsumed = 0; + pMP3->framesRemaining = 0; + pMP3->dataSize = 0; + pMP3->atEnd = DRMP3_FALSE; + + /* TODO: Optimize. + * + * This is inefficient. We simply read frames from the start of the stream. */ + framesRead = drmp3_read_f32(pMP3, frameIndex, NULL); + if (framesRead != frameIndex) + return DRMP3_FALSE; + + return DRMP3_TRUE; +} + + + +float* drmp3__full_decode_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount) +{ + drmp3_uint64 totalFramesRead = 0; + drmp3_uint64 framesCapacity = 0; + float* pFrames = NULL; + + float temp[4096]; + + drmp3_assert(pMP3 != NULL); + + for (;;) + { + drmp3_uint64 framesToReadRightNow = drmp3_countof(temp) / pMP3->channels; + drmp3_uint64 framesJustRead = drmp3_read_f32(pMP3, framesToReadRightNow, temp); + if (framesJustRead == 0) + break; + + /* Reallocate the output buffer if there's not enough room. */ + if (framesCapacity < totalFramesRead + framesJustRead) + { + float* pNewFrames; + drmp3_uint64 newFramesBufferSize; + + framesCapacity *= 2; + if (framesCapacity < totalFramesRead + framesJustRead) + framesCapacity = totalFramesRead + framesJustRead; + + newFramesBufferSize = framesCapacity*pMP3->channels*sizeof(float); + if (newFramesBufferSize > SIZE_MAX) + break; + + pNewFrames = (float*)drmp3_realloc(pFrames, (size_t)newFramesBufferSize); + if (pNewFrames == NULL) + { + drmp3_free(pFrames); + break; + } + + pFrames = pNewFrames; + } + + drmp3_copy_memory(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float))); + totalFramesRead += framesJustRead; + + /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */ + if (framesJustRead != framesToReadRightNow) + break; + } + + if (pConfig != NULL) + { + pConfig->outputChannels = pMP3->channels; + pConfig->outputSampleRate = pMP3->sampleRate; + } + + drmp3_uninit(pMP3); + + if (pTotalFrameCount) *pTotalFrameCount = totalFramesRead; + return pFrames; +} + +float* drmp3_open_and_decode_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount) +{ + drmp3 mp3; + if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pConfig)) + return NULL; + + return drmp3__full_decode_and_close_f32(&mp3, pConfig, pTotalFrameCount); +} + +float* drmp3_open_and_decode_memory_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount) +{ + drmp3 mp3; + if (!drmp3_init_memory(&mp3, pData, dataSize, pConfig)) + return NULL; + + return drmp3__full_decode_and_close_f32(&mp3, pConfig, pTotalFrameCount); +} + +#ifndef DR_MP3_NO_STDIO +float* drmp3_open_and_decode_file_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount) +{ + drmp3 mp3; + if (!drmp3_init_file(&mp3, filePath, pConfig)) + return NULL; + + return drmp3__full_decode_and_close_f32(&mp3, pConfig, pTotalFrameCount); +} +#endif + +void drmp3_free(void* p) +{ + DRMP3_FREE(p); +} + +#endif /*DR_MP3_IMPLEMENTATION*/ + +/* +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +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 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. + +For more information, please refer to +*/ + +/* + https://github.com/lieff/minimp3 + To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. + This software is distributed without any warranty. + See . +*/ diff --git a/deps/libFLAC/bitmath.c b/deps/libFLAC/bitmath.c index b3d797d39b..b700b71e0c 100644 --- a/deps/libFLAC/bitmath.c +++ b/deps/libFLAC/bitmath.c @@ -34,7 +34,7 @@ # include #endif -#include "private/bitmath.h" +#include "include/private/bitmath.h" /* An example of what FLAC__bitmath_silog2() computes: * diff --git a/deps/libFLAC/bitreader.c b/deps/libFLAC/bitreader.c index 902c3a3327..5efde25e3f 100644 --- a/deps/libFLAC/bitreader.c +++ b/deps/libFLAC/bitreader.c @@ -38,13 +38,13 @@ #include #include -#include "private/bitmath.h" -#include "private/bitreader.h" -#include "private/crc.h" -#include "private/macros.h" -#include "FLAC/assert.h" -#include "share/compat.h" -#include "share/endswap.h" +#include "include/private/bitmath.h" +#include "include/private/bitreader.h" +#include "include/private/crc.h" +#include "include/private/macros.h" +#include "include/FLAC/assert.h" +#include "include/share/compat.h" +#include "include/share/endswap.h" /* Things should be fastest when this matches the machine word size */ /* WATCHOUT: if you change this you must also change the following #defines down to COUNT_ZERO_MSBS2 below to match */ diff --git a/deps/libFLAC/cpu.c b/deps/libFLAC/cpu.c index 3f0a2346db..da2b7e3955 100644 --- a/deps/libFLAC/cpu.c +++ b/deps/libFLAC/cpu.c @@ -34,11 +34,12 @@ # include #endif -#include "private/cpu.h" -#include "share/compat.h" #include #include +#include "include/private/cpu.h" +#include "include/share/compat.h" + #if defined(_MSC_VER) # include /* for __cpuid() and _xgetbv() */ #endif @@ -83,7 +84,7 @@ cpu_xgetbv_x86(void) return (uint32_t)_xgetbv(0); #elif defined __GNUC__ uint32_t lo, hi; - asm volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0)); + __asm__ volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0)); return lo; #else return 0; diff --git a/deps/libFLAC/crc.c b/deps/libFLAC/crc.c index 8123c3b69d..b1068cedad 100644 --- a/deps/libFLAC/crc.c +++ b/deps/libFLAC/crc.c @@ -34,7 +34,7 @@ # include #endif -#include "private/crc.h" +#include "include/private/crc.h" /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */ diff --git a/deps/libFLAC/fixed.c b/deps/libFLAC/fixed.c index b33f61f716..f444a1e2dc 100644 --- a/deps/libFLAC/fixed.c +++ b/deps/libFLAC/fixed.c @@ -38,11 +38,11 @@ #include #include -#include "share/compat.h" -#include "private/bitmath.h" -#include "private/fixed.h" -#include "private/macros.h" -#include "FLAC/assert.h" +#include "include/share/compat.h" +#include "include/private/bitmath.h" +#include "include/private/fixed.h" +#include "include/private/macros.h" +#include "include/FLAC/assert.h" #ifdef local_abs #undef local_abs diff --git a/deps/libFLAC/float.c b/deps/libFLAC/float.c index 25d1a78615..fdcfcb0a91 100644 --- a/deps/libFLAC/float.c +++ b/deps/libFLAC/float.c @@ -34,9 +34,9 @@ # include #endif -#include "FLAC/assert.h" -#include "share/compat.h" -#include "private/float.h" +#include "include/FLAC/assert.h" +#include "include/share/compat.h" +#include "include/private/float.h" #ifdef FLAC__INTEGER_ONLY_LIBRARY diff --git a/deps/libFLAC/format.c b/deps/libFLAC/format.c index f320807404..655a908eb9 100644 --- a/deps/libFLAC/format.c +++ b/deps/libFLAC/format.c @@ -40,12 +40,12 @@ #include -#include "FLAC/assert.h" -#include "FLAC/format.h" -#include "share/alloc.h" -#include "share/compat.h" -#include "private/format.h" -#include "private/macros.h" +#include "include/FLAC/assert.h" +#include "include/FLAC/format.h" +#include "include/share/alloc.h" +#include "include/share/compat.h" +#include "include/private/format.h" +#include "include/private/macros.h" /* FLAC_PACKAGE_VERSION should come from configure */ #if defined(__LIBRETRO__) || defined(RARCH_INTERNAL) diff --git a/deps/libFLAC/include/FLAC/format.h b/deps/libFLAC/include/FLAC/format.h index c087d4a70e..99ed7c5116 100644 --- a/deps/libFLAC/include/FLAC/format.h +++ b/deps/libFLAC/include/FLAC/format.h @@ -512,7 +512,7 @@ typedef enum { FLAC__METADATA_TYPE_UNDEFINED = 7, /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */ - FLAC__MAX_METADATA_TYPE = FLAC__MAX_METADATA_TYPE_CODE, + FLAC__MAX_METADATA_TYPE = FLAC__MAX_METADATA_TYPE_CODE /**< No type will ever be greater than this. There is not enough room in the protocol block. */ } FLAC__MetadataType; diff --git a/deps/libFLAC/include/private/bitmath.h b/deps/libFLAC/include/private/bitmath.h index 2c8ecf53b9..24ba5e6003 100644 --- a/deps/libFLAC/include/private/bitmath.h +++ b/deps/libFLAC/include/private/bitmath.h @@ -35,10 +35,10 @@ #include -#include "FLAC/ordinals.h" -#include "FLAC/assert.h" +#include "../FLAC/ordinals.h" +#include "../FLAC/assert.h" -#include "share/compat.h" +#include "../share/compat.h" #if defined(_MSC_VER) #include /* for _BitScanReverse* */ diff --git a/deps/libFLAC/include/private/bitreader.h b/deps/libFLAC/include/private/bitreader.h index 7c7316556a..91230eee8c 100644 --- a/deps/libFLAC/include/private/bitreader.h +++ b/deps/libFLAC/include/private/bitreader.h @@ -34,7 +34,7 @@ #define FLAC__PRIVATE__BITREADER_H #include /* for FILE */ -#include "FLAC/ordinals.h" +#include "../FLAC/ordinals.h" #include "cpu.h" /* diff --git a/deps/libFLAC/include/private/cpu.h b/deps/libFLAC/include/private/cpu.h index 7c6518076b..1353817fe8 100644 --- a/deps/libFLAC/include/private/cpu.h +++ b/deps/libFLAC/include/private/cpu.h @@ -33,7 +33,7 @@ #ifndef FLAC__PRIVATE__CPU_H #define FLAC__PRIVATE__CPU_H -#include "FLAC/ordinals.h" +#include "../FLAC/ordinals.h" #ifdef HAVE_CONFIG_H #include diff --git a/deps/libFLAC/include/private/crc.h b/deps/libFLAC/include/private/crc.h index 294f60eaa2..6c63b3b272 100644 --- a/deps/libFLAC/include/private/crc.h +++ b/deps/libFLAC/include/private/crc.h @@ -33,7 +33,7 @@ #ifndef FLAC__PRIVATE__CRC_H #define FLAC__PRIVATE__CRC_H -#include "FLAC/ordinals.h" +#include "../FLAC/ordinals.h" /* 8 bit CRC generator, MSB shifted first ** polynomial = x^8 + x^2 + x^1 + x^0 diff --git a/deps/libFLAC/include/private/fixed.h b/deps/libFLAC/include/private/fixed.h index 68cdfceb37..b260d29697 100644 --- a/deps/libFLAC/include/private/fixed.h +++ b/deps/libFLAC/include/private/fixed.h @@ -37,9 +37,9 @@ #include #endif -#include "private/cpu.h" -#include "private/float.h" -#include "FLAC/format.h" +#include "../private/cpu.h" +#include "../private/float.h" +#include "../FLAC/format.h" /* * FLAC__fixed_compute_best_predictor() diff --git a/deps/libFLAC/include/private/float.h b/deps/libFLAC/include/private/float.h index 12ece60565..7d50f6103e 100644 --- a/deps/libFLAC/include/private/float.h +++ b/deps/libFLAC/include/private/float.h @@ -37,7 +37,7 @@ #include #endif -#include "FLAC/ordinals.h" +#include "../FLAC/ordinals.h" /* * All the code in libFLAC that uses float and double diff --git a/deps/libFLAC/include/private/format.h b/deps/libFLAC/include/private/format.h index 5b9cfbd0ed..e27f251f85 100644 --- a/deps/libFLAC/include/private/format.h +++ b/deps/libFLAC/include/private/format.h @@ -33,7 +33,7 @@ #ifndef FLAC__PRIVATE__FORMAT_H #define FLAC__PRIVATE__FORMAT_H -#include "FLAC/format.h" +#include "../FLAC/format.h" unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order); unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize); diff --git a/deps/libFLAC/include/private/lpc.h b/deps/libFLAC/include/private/lpc.h index 6eb02be63a..bf7b5d7f25 100644 --- a/deps/libFLAC/include/private/lpc.h +++ b/deps/libFLAC/include/private/lpc.h @@ -37,9 +37,9 @@ #include #endif -#include "private/cpu.h" -#include "private/float.h" -#include "FLAC/format.h" +#include "../private/cpu.h" +#include "../private/float.h" +#include "../FLAC/format.h" #ifndef FLAC__INTEGER_ONLY_LIBRARY diff --git a/deps/libFLAC/include/private/md5.h b/deps/libFLAC/include/private/md5.h index c665ab313f..3d4967c091 100644 --- a/deps/libFLAC/include/private/md5.h +++ b/deps/libFLAC/include/private/md5.h @@ -26,7 +26,7 @@ * Still in the public domain, with no warranty. */ -#include "FLAC/ordinals.h" +#include "../FLAC/ordinals.h" typedef union { FLAC__byte *p8; diff --git a/deps/libFLAC/include/private/memory.h b/deps/libFLAC/include/private/memory.h index f103c531ff..d9116e8bb6 100644 --- a/deps/libFLAC/include/private/memory.h +++ b/deps/libFLAC/include/private/memory.h @@ -39,8 +39,8 @@ #include /* for size_t */ -#include "private/float.h" -#include "FLAC/ordinals.h" /* for FLAC__bool */ +#include "../private/float.h" +#include "../FLAC/ordinals.h" /* for FLAC__bool */ /* Returns the unaligned address returned by malloc. * Use free() on this address to deallocate. diff --git a/deps/libFLAC/include/protected/stream_decoder.h b/deps/libFLAC/include/protected/stream_decoder.h index 5c31c1618d..bf08aa6081 100644 --- a/deps/libFLAC/include/protected/stream_decoder.h +++ b/deps/libFLAC/include/protected/stream_decoder.h @@ -33,9 +33,9 @@ #ifndef FLAC__PROTECTED__STREAM_DECODER_H #define FLAC__PROTECTED__STREAM_DECODER_H -#include "FLAC/stream_decoder.h" +#include "../FLAC/stream_decoder.h" #if FLAC__HAS_OGG -#include "private/ogg_decoder_aspect.h" +#include "../private/ogg_decoder_aspect.h" #endif typedef struct FLAC__StreamDecoderProtected { diff --git a/deps/libFLAC/include/share/alloc.h b/deps/libFLAC/include/share/alloc.h index 914de9ba6b..a66153eee9 100644 --- a/deps/libFLAC/include/share/alloc.h +++ b/deps/libFLAC/include/share/alloc.h @@ -33,6 +33,8 @@ #ifndef FLAC__SHARE__ALLOC_H #define FLAC__SHARE__ALLOC_H +#include + #ifdef HAVE_CONFIG_H # include #endif @@ -46,7 +48,7 @@ #include /* for SIZE_MAX in case limits.h didn't get it */ #endif #include /* for size_t, malloc(), etc */ -#include "share/compat.h" +#include "../share/compat.h" #ifndef SIZE_MAX # ifndef SIZE_T_MAX @@ -66,7 +68,7 @@ /* avoid malloc()ing 0 bytes, see: * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003 */ -static inline void *safe_malloc_(size_t size) +static INLINE void *safe_malloc_(size_t size) { /* malloc(0) is undefined; FLAC src convention is to always allocate */ if(!size) @@ -74,7 +76,7 @@ static inline void *safe_malloc_(size_t size) return malloc(size); } -static inline void *safe_calloc_(size_t nmemb, size_t size) +static INLINE void *safe_calloc_(size_t nmemb, size_t size) { if(!nmemb || !size) return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ @@ -83,7 +85,7 @@ static inline void *safe_calloc_(size_t nmemb, size_t size) /*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */ -static inline void *safe_malloc_add_2op_(size_t size1, size_t size2) +static INLINE void *safe_malloc_add_2op_(size_t size1, size_t size2) { size2 += size1; if(size2 < size1) @@ -91,7 +93,7 @@ static inline void *safe_malloc_add_2op_(size_t size1, size_t size2) return safe_malloc_(size2); } -static inline void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3) +static INLINE void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3) { size2 += size1; if(size2 < size1) @@ -102,7 +104,7 @@ static inline void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size return safe_malloc_(size3); } -static inline void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4) +static INLINE void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4) { size2 += size1; if(size2 < size1) @@ -118,7 +120,7 @@ static inline void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size void *safe_malloc_mul_2op_(size_t size1, size_t size2) ; -static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3) +static INLINE void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3) { if(!size1 || !size2 || !size3) return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ @@ -131,7 +133,7 @@ static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size } /* size1*size2 + size3 */ -static inline void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3) +static INLINE void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3) { if(!size1 || !size2) return safe_malloc_(size3); @@ -141,7 +143,7 @@ static inline void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size } /* size1 * (size2 + size3) */ -static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3) +static INLINE void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3) { if(!size1 || (!size2 && !size3)) return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ @@ -153,7 +155,7 @@ static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size return malloc(size1*size2); } -static inline void *safe_realloc_(void *ptr, size_t size) +static INLINE void *safe_realloc_(void *ptr, size_t size) { void *oldptr = ptr; void *newptr = realloc(ptr, size); @@ -161,7 +163,7 @@ static inline void *safe_realloc_(void *ptr, size_t size) free(oldptr); return newptr; } -static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) +static INLINE void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) { size2 += size1; if(size2 < size1) { @@ -171,7 +173,7 @@ static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) return realloc(ptr, size2); } -static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) +static INLINE void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) { size2 += size1; if(size2 < size1) @@ -182,7 +184,7 @@ static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, return realloc(ptr, size3); } -static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) +static INLINE void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) { size2 += size1; if(size2 < size1) @@ -196,7 +198,7 @@ static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, return realloc(ptr, size4); } -static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) +static INLINE void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) { if(!size1 || !size2) return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ @@ -206,7 +208,7 @@ static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) } /* size1 * (size2 + size3) */ -static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) +static INLINE void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) { if(!size1 || (!size2 && !size3)) return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ diff --git a/deps/libFLAC/lpc.c b/deps/libFLAC/lpc.c index 531247b595..a6ae94446d 100644 --- a/deps/libFLAC/lpc.c +++ b/deps/libFLAC/lpc.c @@ -36,12 +36,12 @@ #include -#include "FLAC/assert.h" -#include "FLAC/format.h" -#include "share/compat.h" -#include "private/bitmath.h" -#include "private/lpc.h" -#include "private/macros.h" +#include "include/FLAC/assert.h" +#include "include/FLAC/format.h" +#include "include/share/compat.h" +#include "include/private/bitmath.h" +#include "include/private/lpc.h" +#include "include/private/macros.h" #if defined DEBUG || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE #include #endif diff --git a/deps/libFLAC/lpc_intrin_avx2.c b/deps/libFLAC/lpc_intrin_avx2.c index f9f5ccdb02..44e2169025 100644 --- a/deps/libFLAC/lpc_intrin_avx2.c +++ b/deps/libFLAC/lpc_intrin_avx2.c @@ -34,16 +34,16 @@ # include #endif -#include "private/cpu.h" +#include "include/private/cpu.h" #ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__NO_ASM #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN -#include "private/lpc.h" +#include "include/private/lpc.h" #ifdef FLAC__AVX2_SUPPORTED -#include "FLAC/assert.h" -#include "FLAC/format.h" +#include "include/FLAC/assert.h" +#include "include/FLAC/format.h" #include /* AVX2 */ diff --git a/deps/libFLAC/lpc_intrin_sse.c b/deps/libFLAC/lpc_intrin_sse.c index 430e73f08e..9c800f5831 100644 --- a/deps/libFLAC/lpc_intrin_sse.c +++ b/deps/libFLAC/lpc_intrin_sse.c @@ -34,15 +34,15 @@ # include #endif -#include "private/cpu.h" +#include "include/private/cpu.h" #ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__NO_ASM #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN -#include "private/lpc.h" +#include "include/private/lpc.h" #ifdef FLAC__SSE_SUPPORTED -#include "FLAC/assert.h" -#include "FLAC/format.h" +#include "include/FLAC/assert.h" +#include "include/FLAC/format.h" #include /* SSE */ diff --git a/deps/libFLAC/lpc_intrin_sse2.c b/deps/libFLAC/lpc_intrin_sse2.c index 138339483f..59b416253f 100644 --- a/deps/libFLAC/lpc_intrin_sse2.c +++ b/deps/libFLAC/lpc_intrin_sse2.c @@ -34,16 +34,16 @@ # include #endif -#include "private/cpu.h" +#include "include/private/cpu.h" #ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__NO_ASM #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN -#include "private/lpc.h" +#include "include/private/lpc.h" #ifdef FLAC__SSE2_SUPPORTED -#include "FLAC/assert.h" -#include "FLAC/format.h" +#include "include/FLAC/assert.h" +#include "include/FLAC/format.h" #include /* SSE2 */ diff --git a/deps/libFLAC/lpc_intrin_sse41.c b/deps/libFLAC/lpc_intrin_sse41.c index bef73f41f6..ea0e2bbc30 100644 --- a/deps/libFLAC/lpc_intrin_sse41.c +++ b/deps/libFLAC/lpc_intrin_sse41.c @@ -34,16 +34,16 @@ # include #endif -#include "private/cpu.h" +#include "include/private/cpu.h" #ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__NO_ASM #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN -#include "private/lpc.h" +#include "include/private/lpc.h" #ifdef FLAC__SSE4_1_SUPPORTED -#include "FLAC/assert.h" -#include "FLAC/format.h" +#include "include/FLAC/assert.h" +#include "include/FLAC/format.h" #include /* SSE4.1 */ diff --git a/deps/libFLAC/md5.c b/deps/libFLAC/md5.c index 9527f38deb..7ca816133e 100644 --- a/deps/libFLAC/md5.c +++ b/deps/libFLAC/md5.c @@ -5,9 +5,9 @@ #include /* for malloc() */ #include /* for memcpy() */ -#include "private/md5.h" -#include "share/alloc.h" -#include "share/endswap.h" +#include "include/private/md5.h" +#include "include/share/alloc.h" +#include "include/share/endswap.h" /* * This code implements the MD5 message-digest algorithm. diff --git a/deps/libFLAC/memory.c b/deps/libFLAC/memory.c index 41cc446034..a7a3f6a721 100644 --- a/deps/libFLAC/memory.c +++ b/deps/libFLAC/memory.c @@ -38,9 +38,9 @@ #include #endif -#include "private/memory.h" -#include "FLAC/assert.h" -#include "share/alloc.h" +#include "include/private/memory.h" +#include "include/FLAC/assert.h" +#include "include/share/alloc.h" void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) { diff --git a/deps/libFLAC/stream_decoder.c b/deps/libFLAC/stream_decoder.c index 8dab5caa18..ec34f75667 100644 --- a/deps/libFLAC/stream_decoder.c +++ b/deps/libFLAC/stream_decoder.c @@ -42,20 +42,20 @@ #include -#include "share/compat.h" -#include "FLAC/assert.h" -#include "share/alloc.h" -#include "protected/stream_decoder.h" -#include "private/bitreader.h" -#include "private/bitmath.h" -#include "private/cpu.h" -#include "private/crc.h" -#include "private/fixed.h" -#include "private/format.h" -#include "private/lpc.h" -#include "private/md5.h" -#include "private/memory.h" -#include "private/macros.h" +#include "include/share/compat.h" +#include "include/FLAC/assert.h" +#include "include/share/alloc.h" +#include "include/protected/stream_decoder.h" +#include "include/private/bitreader.h" +#include "include/private/bitmath.h" +#include "include/private/cpu.h" +#include "include/private/crc.h" +#include "include/private/fixed.h" +#include "include/private/format.h" +#include "include/private/lpc.h" +#include "include/private/md5.h" +#include "include/private/memory.h" +#include "include/private/macros.h" /* technically this should be in an "export.c" but this is convenient enough */ diff --git a/deps/libz/crc32.c b/deps/libz/libz-crc32.c similarity index 100% rename from deps/libz/crc32.c rename to deps/libz/libz-crc32.c diff --git a/deps/miniupnpc/minissdpc.c b/deps/miniupnpc/minissdpc.c index c2a00319ef..2a526d04e8 100644 --- a/deps/miniupnpc/minissdpc.c +++ b/deps/miniupnpc/minissdpc.c @@ -145,7 +145,7 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * err if(n<=0) break; \ bufferindex = 0; \ } \ - lcopy = MIN(l, (n - bufferindex)); \ + lcopy = (unsigned int)MIN(l, (n - bufferindex)); \ memcpy(p, buffer + bufferindex, lcopy); \ l -= lcopy; \ p += lcopy; \ @@ -584,7 +584,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], struct in_addr mc_if; memset(&mc_if, 0, sizeof(mc_if)); mc_if.s_addr = pIPAddrTable->table[i].dwAddr; - setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0; + setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)); ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = pIPAddrTable->table[i].dwAddr; #ifndef DEBUG break; @@ -606,6 +606,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], { if(error) *error = MINISSDPC_SOCKET_ERROR; + closesocket(sudp); return NULL; } diff --git a/deps/stb/stb_rect_pack.h b/deps/stb/stb_rect_pack.h index 6c658de33e..ed1585ba19 100644 --- a/deps/stb/stb_rect_pack.h +++ b/deps/stb/stb_rect_pack.h @@ -528,12 +528,7 @@ STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int n /* we use the 'was_packed' field internally to allow sorting/unsorting */ for (i=0; i < num_rects; ++i) - { rects[i].was_packed = i; - #ifndef STBRP_LARGE_RECTS - STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff); - #endif - } /* sort according to heuristic */ STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); diff --git a/deps/stb/stb_vorbis.h b/deps/stb/stb_vorbis.h index 6adaff4940..be97f0b655 100644 --- a/deps/stb/stb_vorbis.h +++ b/deps/stb/stb_vorbis.h @@ -3278,7 +3278,7 @@ static stb_vorbis * vorbis_alloc(stb_vorbis *f) unsigned int stb_vorbis_get_file_offset(stb_vorbis *f) { - return f->stream - f->stream_start; + return (unsigned int)(f->stream - f->stream_start); } #ifndef STB_VORBIS_NO_PULLDATA_API diff --git a/dynamic.c b/dynamic.c index 3e89144f81..bed42e2370 100644 --- a/dynamic.c +++ b/dynamic.c @@ -66,9 +66,14 @@ #include "msg_hash.h" #include "verbosity.h" +#ifdef HAVE_RUNAHEAD +#include "runahead/secondary_core.h" +#include "runahead/run_ahead.h" +#endif + #ifdef HAVE_DYNAMIC #define SYMBOL(x) do { \ - function_t func = dylib_proc(lib_handle, #x); \ + function_t func = dylib_proc(lib_handle_local, #x); \ memcpy(¤t_core->x, &func, sizeof(func)); \ if (current_core->x == NULL) { RARCH_ERR("Failed to load symbol: \"%s\"\n", #x); retroarch_fail(1, "init_libretro_sym()"); } \ } while (0) @@ -383,14 +388,36 @@ bool libretro_get_system_info(const char *path, * Setup libretro callback symbols. Returns true on success, * or false if symbols could not be loaded. **/ -static bool load_symbols(enum rarch_core_type type, struct retro_core_t *current_core) +bool init_libretro_sym_custom(enum rarch_core_type type, struct retro_core_t *current_core, const char *lib_path, dylib_t *lib_handle_p) { + /* the library handle for use with the SYMBOL macro */ + dylib_t lib_handle_local; switch (type) { case CORE_TYPE_PLAIN: #ifdef HAVE_DYNAMIC - if (!load_dynamic_core()) - return false; +#ifdef HAVE_RUNAHEAD + if (!lib_path || !lib_handle_p) +#endif + { + if (!load_dynamic_core()) + return false; + lib_handle_local = lib_handle; + } +#ifdef HAVE_RUNAHEAD + else + { + /* for a secondary core, we already have a + * primary library loaded, so we can skip + * some checks and just load the library */ + retro_assert(lib_path != NULL && lib_handle_p != NULL); + lib_handle_local = dylib_load(lib_path); + + if (!lib_handle_local) + return false; + *lib_handle_p = lib_handle_local; + } +#endif #endif SYMBOL(retro_init); @@ -615,6 +642,11 @@ static bool load_symbols(enum rarch_core_type type, struct retro_core_t *current return true; } +static bool load_symbols(enum rarch_core_type type, struct retro_core_t *current_core) +{ + return init_libretro_sym_custom(type, current_core, NULL, NULL); +} + /** * init_libretro_sym: * @type : Type of core to be loaded. @@ -634,6 +666,11 @@ bool init_libretro_sym(enum rarch_core_type type, struct retro_core_t *current_c if (!load_symbols(type, current_core)) return false; +#ifdef HAVE_RUNAHEAD + /* remember last core type created, so creating a + * secondary core will know what core type to use. */ + set_last_core_type(type); +#endif return true; } @@ -885,23 +922,27 @@ static bool dynamic_request_hw_context(enum retro_hw_context_type type, break; #endif - case RETRO_HW_CONTEXT_DIRECT3D: - switch(major) - { +#if defined(HAVE_D3D9) || defined(HAVE_D3D11) + case RETRO_HW_CONTEXT_DIRECT3D: + switch (major) + { #ifdef HAVE_D3D9 - case 9: + case 9: + RARCH_LOG("Requesting D3D9 context.\n"); + break; #endif #ifdef HAVE_D3D11 - case 11: + case 11: + RARCH_LOG("Requesting D3D11 context.\n"); + break; +#endif + default: + RARCH_LOG("Requesting unknown context.\n"); + return false; + } + break; #endif - RARCH_LOG("Requesting D3D%i context.\n", major); - break; - default: - goto unknown; - } - break; -unknown: default: RARCH_LOG("Requesting unknown context.\n"); return false; @@ -1718,13 +1759,15 @@ bool rarch_environment_cb(unsigned cmd, void *data) { int result = 0; if (!audio_driver_is_suspended() && audio_driver_is_active()) - { result |= 2; - } if (video_driver_is_active() && !video_driver_is_stub_frame()) - { result |= 1; - } +#ifdef HAVE_RUNAHEAD + if (want_fast_savestate()) + result |= 4; + if (get_hard_disable_audio()) + result |= 8; +#endif if (data != NULL) { int* result_p = (int*)data; diff --git a/dynamic.h b/dynamic.h index 2432704e48..e930a2edc8 100644 --- a/dynamic.h +++ b/dynamic.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "core_type.h" @@ -132,6 +133,8 @@ bool libretro_get_shared_context(void); bool init_libretro_sym(enum rarch_core_type type, struct retro_core_t *core); +bool init_libretro_sym_custom(enum rarch_core_type type, struct retro_core_t *current_core, const char *lib_path, dylib_t *lib_handle_p); + /** * uninit_libretro_sym: * diff --git a/file_path_special.h b/file_path_special.h index b0eeee3bdc..16455f2486 100644 --- a/file_path_special.h +++ b/file_path_special.h @@ -86,6 +86,8 @@ enum file_path_enum FILE_PATH_ZIP_EXTENSION, FILE_PATH_7Z_EXTENSION, FILE_PATH_OGG_EXTENSION, + FILE_PATH_MP3_EXTENSION, + FILE_PATH_FLAC_EXTENSION, FILE_PATH_WAV_EXTENSION, FILE_PATH_MOD_EXTENSION, FILE_PATH_S3M_EXTENSION, diff --git a/file_path_str.c b/file_path_str.c index 219c719720..2d9d73481d 100644 --- a/file_path_str.c +++ b/file_path_str.c @@ -101,6 +101,12 @@ const char *file_path_str(enum file_path_enum enum_idx) case FILE_PATH_PNG_EXTENSION: str = ".png"; break; + case FILE_PATH_MP3_EXTENSION: + str = ".mp3"; + break; + case FILE_PATH_FLAC_EXTENSION: + str = ".flac"; + break; case FILE_PATH_OGG_EXTENSION: str = ".ogg"; break; diff --git a/frontend/drivers/platform_qnx.c b/frontend/drivers/platform_qnx.c index 0b3af7895b..ddd4829852 100644 --- a/frontend/drivers/platform_qnx.c +++ b/frontend/drivers/platform_qnx.c @@ -142,7 +142,9 @@ static void frontend_qnx_get_environment_settings(int *argc, char *argv[], file_path_str(FILE_PATH_MAIN_CONFIG), sizeof(g_defaults.path.config)); /* bundle copy */ - sprintf(data_assets_path, "%s/%s", data_path, "assets"); + snprintf(data_assets_path, + sizeof(data_assets_path), + "%s/%s", data_path, "assets"); if (!filestream_exists(data_assets_path)) { @@ -150,7 +152,9 @@ static void frontend_qnx_get_environment_settings(int *argc, char *argv[], RARCH_LOG( "Copying application assets to data directory...\n" ); - sprintf(copy_command, "cp -r %s/. %s", assets_path, data_path); + snprintf(copy_command, + sizeof(copy_command), + "cp -r %s/. %s", assets_path, data_path); if(system(copy_command) == -1) RARCH_LOG( "Asset copy failed: Shell could not be run.\n" ); diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index 338200cc0d..11e6c2c8d8 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -54,9 +54,6 @@ #ifdef ANDROID #include -#ifdef __arm__ -#include -#endif #endif #include diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index cce85bce6e..8308446f83 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -148,15 +148,15 @@ static void gfx_set_dwm(void) static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) { - char buildStr[11] = {0}; - bool server = false; - const char *arch = ""; - bool serverR2 = false; + char buildStr[11] = {0}; + bool server = false; + const char *arch = ""; + bool serverR2 = false; #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 /* Windows 2000 and later */ - SYSTEM_INFO si = {0}; - OSVERSIONINFOEX vi = {0}; + SYSTEM_INFO si = {{0}}; + OSVERSIONINFOEX vi = {0}; vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); GetSystemInfo(&si); @@ -359,7 +359,7 @@ enum frontend_architecture frontend_win32_get_architecture(void) { #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 /* Windows 2000 and later */ - SYSTEM_INFO si = {0}; + SYSTEM_INFO si = {{0}}; GetSystemInfo(&si); diff --git a/frontend/frontend.c b/frontend/frontend.c index bd2fecde6e..b144761490 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -37,6 +37,13 @@ #include "../paths.h" #include "../retroarch.h" +/* griffin hack */ +#ifdef HAVE_QT +#ifndef HAVE_MAIN +#define HAVE_MAIN +#endif +#endif + #ifndef HAVE_MAIN #include "../retroarch.h" #endif @@ -98,6 +105,9 @@ void main_exit(void *args) int rarch_main(int argc, char *argv[], void *data) { void *args = (void*)data; +#if defined(HAVE_MAIN) && defined(HAVE_QT) + const ui_application_t *ui_application = NULL; +#endif rarch_ctl(RARCH_CTL_PREINIT, NULL); frontend_driver_init_first(args); @@ -124,7 +134,7 @@ int rarch_main(int argc, char *argv[], void *data) ui_companion_driver_init_first(); -#ifndef HAVE_MAIN +#if !defined(HAVE_MAIN) do { unsigned sleep_ms = 0; @@ -140,6 +150,11 @@ int rarch_main(int argc, char *argv[], void *data) }while(1); main_exit(args); +#elif defined(HAVE_QT) + ui_application = ui_companion_driver_get_qt_application_ptr(); + + if (ui_application && ui_application->run) + ui_application->run(args); #endif return 0; diff --git a/gfx/common/d3d10_common.c b/gfx/common/d3d10_common.c index 45d364d08f..1b145015f7 100644 --- a/gfx/common/d3d10_common.c +++ b/gfx/common/d3d10_common.c @@ -18,6 +18,7 @@ #include #include "d3d10_common.h" +#include "d3dcompiler_common.h" #ifdef HAVE_DYNAMIC #include @@ -67,43 +68,72 @@ HRESULT WINAPI D3D10CreateDeviceAndSwapChain( void d3d10_init_texture(D3D10Device device, d3d10_texture_t* texture) { - Release(texture->handle); - Release(texture->staging); - Release(texture->view); + bool is_render_target = texture->desc.BindFlags & D3D10_BIND_RENDER_TARGET; + UINT format_support = D3D10_FORMAT_SUPPORT_TEXTURE2D | D3D10_FORMAT_SUPPORT_SHADER_SAMPLE; - // .Usage = D3D10_USAGE_DYNAMIC, - // .CPUAccessFlags = D3D10_CPU_ACCESS_WRITE, + d3d10_release_texture(texture); texture->desc.MipLevels = 1; texture->desc.ArraySize = 1; texture->desc.SampleDesc.Count = 1; texture->desc.SampleDesc.Quality = 0; - texture->desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; - texture->desc.CPUAccessFlags = 0; - texture->desc.MiscFlags = 0; + texture->desc.BindFlags |= D3D10_BIND_SHADER_RESOURCE; + texture->desc.CPUAccessFlags = + texture->desc.Usage == D3D10_USAGE_DYNAMIC ? D3D10_CPU_ACCESS_WRITE : 0; + + if (texture->desc.MiscFlags & D3D10_RESOURCE_MISC_GENERATE_MIPS) + { + unsigned width, height; + + texture->desc.BindFlags |= D3D10_BIND_RENDER_TARGET; + width = texture->desc.Width >> 5; + height = texture->desc.Height >> 5; + + while (width && height) + { + width >>= 1; + height >>= 1; + texture->desc.MipLevels++; + } + } + + if (texture->desc.BindFlags & D3D10_BIND_RENDER_TARGET) + format_support |= D3D10_FORMAT_SUPPORT_RENDER_TARGET; + + texture->desc.Format = d3d10_get_closest_match(device, texture->desc.Format, format_support); + D3D10CreateTexture2D(device, &texture->desc, NULL, &texture->handle); { D3D10_SHADER_RESOURCE_VIEW_DESC view_desc = { DXGI_FORMAT_UNKNOWN }; - view_desc.Format = texture->desc.Format; - view_desc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D; - view_desc.Texture2D.MostDetailedMip = 0; - view_desc.Texture2D.MipLevels = -1; - - D3D10CreateTexture2DShaderResourceView(device, - texture->handle, &view_desc, &texture->view); + view_desc.Format = texture->desc.Format; + view_desc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D; + view_desc.Texture2D.MostDetailedMip = 0; + view_desc.Texture2D.MipLevels = -1; + D3D10CreateTexture2DShaderResourceView(device, texture->handle, &view_desc, &texture->view); } + if (is_render_target) + D3D10CreateTexture2DRenderTargetView(device, texture->handle, NULL, &texture->rt_view); + else { D3D10_TEXTURE2D_DESC desc = texture->desc; + desc.MipLevels = 1; desc.BindFlags = 0; + desc.MiscFlags = 0; desc.Usage = D3D10_USAGE_STAGING; desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; D3D10CreateTexture2D(device, &desc, NULL, &texture->staging); } + + texture->size_data.x = texture->desc.Width; + texture->size_data.y = texture->desc.Height; + texture->size_data.z = 1.0f / texture->desc.Width; + texture->size_data.w = 1.0f / texture->desc.Height; } void d3d10_update_texture( + D3D10Device ctx, int width, int height, int pitch, @@ -112,8 +142,14 @@ void d3d10_update_texture( d3d10_texture_t* texture) { D3D10_MAPPED_TEXTURE2D mapped_texture; + D3D10_BOX frame_box = { 0, 0, 0, (UINT)width, + (UINT)height, 1 }; - D3D10MapTexture2D(texture->staging, 0, D3D10_MAP_WRITE, 0, + if (!texture || !texture->staging) + return; + + D3D10MapTexture2D(texture->staging, + 0, D3D10_MAP_WRITE, 0, &mapped_texture); #if 0 @@ -130,8 +166,11 @@ void d3d10_update_texture( D3D10UnmapTexture2D(texture->staging, 0); - if (texture->desc.Usage == D3D10_USAGE_DEFAULT) - texture->dirty = true; + D3D10CopyTexture2DSubresourceRegion( + ctx, texture->handle, 0, 0, 0, 0, texture->staging, 0, &frame_box); + + if (texture->desc.MiscFlags & D3D10_RESOURCE_MISC_GENERATE_MIPS) + D3D10GenerateMips(ctx, texture->view); } DXGI_FORMAT @@ -155,3 +194,65 @@ d3d10_get_closest_match(D3D10Device device, assert(*format); return *format; } + +bool d3d10_init_shader( + D3D10Device device, + const char* src, + size_t size, + const void* src_name, + LPCSTR vs_entry, + LPCSTR ps_entry, + LPCSTR gs_entry, + const D3D10_INPUT_ELEMENT_DESC* input_element_descs, + UINT num_elements, + d3d10_shader_t* out) +{ + D3DBlob vs_code = NULL; + D3DBlob ps_code = NULL; + D3DBlob gs_code = NULL; + + bool success = true; + + if (!src) /* LPCWSTR filename */ + { + if (vs_entry && !d3d_compile_from_file((LPCWSTR)src_name, vs_entry, "vs_4_0", &vs_code)) + success = false; + if (ps_entry && !d3d_compile_from_file((LPCWSTR)src_name, ps_entry, "ps_4_0", &ps_code)) + success = false; + if (gs_entry && !d3d_compile_from_file((LPCWSTR)src_name, gs_entry, "gs_4_0", &gs_code)) + success = false; + } + else /* char array */ + { + if (vs_entry && !d3d_compile(src, size, (LPCSTR)src_name, vs_entry, "vs_4_0", &vs_code)) + success = false; + if (ps_entry && !d3d_compile(src, size, (LPCSTR)src_name, ps_entry, "ps_4_0", &ps_code)) + success = false; + if (gs_entry && !d3d_compile(src, size, (LPCSTR)src_name, gs_entry, "gs_4_0", &gs_code)) + success = false; + } + + if (vs_code) + D3D10CreateVertexShader( + device, D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code), &out->vs); + + if (ps_code) + D3D10CreatePixelShader( + device, D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code), &out->ps); + + if (gs_code) + D3D10CreateGeometryShader( + device, D3DGetBufferPointer(gs_code), D3DGetBufferSize(gs_code), &out->gs); + + if (vs_code && input_element_descs) + D3D10CreateInputLayout( + device, + (D3D10_INPUT_ELEMENT_DESC*)input_element_descs, num_elements, D3DGetBufferPointer(vs_code), + D3DGetBufferSize(vs_code), &out->layout); + + Release(vs_code); + Release(ps_code); + Release(gs_code); + + return success; +} diff --git a/gfx/common/d3d10_common.h b/gfx/common/d3d10_common.h index 500f898bd6..ee8373ca57 100644 --- a/gfx/common/d3d10_common.h +++ b/gfx/common/d3d10_common.h @@ -20,6 +20,10 @@ #include "dxgi_common.h" #include +#include "../drivers_shader/slang_process.h" + +typedef const ID3D10SamplerState* D3D10SamplerStateRef; + typedef ID3D10InputLayout* D3D10InputLayout; typedef ID3D10RasterizerState* D3D10RasterizerState; typedef ID3D10DepthStencilState* D3D10DepthStencilState; @@ -50,6 +54,7 @@ typedef ID3D10Debug* D3D10Debug; typedef ID3D10SwitchToRef* D3D10SwitchToRef; typedef ID3D10InfoQueue* D3D10InfoQueue; + #if !defined(__cplusplus) || defined(CINTERFACE) static INLINE void D3D10SetResourceEvictionPriority(D3D10Resource resource, UINT eviction_priority) { @@ -236,6 +241,7 @@ static INLINE void D3D10SetVShader(D3D10Device device, D3D10VertexShader vertex_ { device->lpVtbl->VSSetShader(device, vertex_shader); } + static INLINE void D3D10DrawIndexed( D3D10Device device, UINT index_count, UINT start_index_location, INT base_vertex_location) { @@ -265,6 +271,28 @@ static INLINE void D3D10SetVertexBuffers( device->lpVtbl->IASetVertexBuffers( device, start_slot, num_buffers, vertex_buffers, strides, offsets); } + +static INLINE void D3D10SetVertexBuffer( + D3D10Device device_context, + UINT slot, + D3D10Buffer const vertex_buffer, + UINT stride, + UINT offset) +{ + D3D10SetVertexBuffers(device_context, slot, 1, (D3D10Buffer* const)&vertex_buffer, &stride, &offset); +} +static INLINE void D3D10SetVShaderConstantBuffer( + D3D10Device device_context, UINT slot, D3D10Buffer const constant_buffer) +{ + D3D10SetVShaderConstantBuffers(device_context, slot, 1, (ID3D10Buffer ** const)&constant_buffer); +} + +static INLINE void D3D10SetPShaderConstantBuffer( + D3D10Device device_context, UINT slot, D3D10Buffer const constant_buffer) +{ + D3D10SetPShaderConstantBuffers(device_context, slot, 1, (ID3D10Buffer** const)&constant_buffer); +} + static INLINE void D3D10SetIndexBuffer(D3D10Device device, D3D10Buffer index_buffer, DXGI_FORMAT format, UINT offset) { @@ -1047,25 +1075,74 @@ typedef struct D3D10Texture2D handle; D3D10Texture2D staging; D3D10_TEXTURE2D_DESC desc; + D3D10RenderTargetView rt_view; D3D10ShaderResourceView view; - bool dirty; - bool ignore_alpha; + D3D10SamplerStateRef sampler; + float4_t size_data; } d3d10_texture_t; +typedef struct +{ + struct + { + float x, y, w, h; + } pos; + struct + { + float u, v, w, h; + } coords; + UINT32 colors[4]; + struct + { + float scaling; + float rotation; + } params; +} d3d10_sprite_t; + +#ifndef ALIGN +#ifdef _MSC_VER +#define ALIGN(x) __declspec(align(x)) +#else +#define ALIGN(x) __attribute__((aligned(x))) +#endif +#endif + +typedef struct ALIGN(16) +{ + math_matrix_4x4 mvp; + struct + { + float width; + float height; + } OutputSize; + float time; +} d3d10_uniform_t; + +static_assert( + (!(sizeof(d3d10_uniform_t) & 0xF)), "sizeof(d3d10_uniform_t) must be a multiple of 16"); + +typedef struct d3d10_shader_t +{ + D3D10VertexShader vs; + D3D10PixelShader ps; + D3D10GeometryShader gs; + D3D10InputLayout layout; +} d3d10_shader_t; + typedef struct { unsigned cur_mon_id; DXGISwapChain swapChain; D3D10Device device; + D3D10RasterizerState state; D3D10RenderTargetView renderTargetView; - D3D10InputLayout layout; D3D10Buffer ubo; - D3D10VertexShader vs; - D3D10PixelShader ps; - D3D10SamplerState sampler_nearest; - D3D10SamplerState sampler_linear; + d3d10_uniform_t ubo_values; + D3D10SamplerState samplers[RARCH_FILTER_MAX][RARCH_WRAP_MAX]; D3D10BlendState blend_enable; D3D10BlendState blend_disable; + D3D10BlendState blend_pipeline; + D3D10Buffer menu_pipeline_vbo; math_matrix_4x4 mvp, mvp_no_rot; struct video_viewport vp; D3D10_VIEWPORT viewport; @@ -1075,28 +1152,74 @@ typedef struct bool resize_chain; bool keep_aspect; bool resize_viewport; + bool resize_render_targets; + bool init_history; + d3d10_shader_t shaders[GFX_MAX_SHADERS]; + + struct + { + d3d10_shader_t shader; + d3d10_shader_t shader_font; + D3D10Buffer vbo; + int offset; + int capacity; + bool enabled; + } sprites; + +#ifdef HAVE_OVERLAY + struct + { + D3D10Buffer vbo; + d3d10_texture_t* textures; + bool enabled; + bool fullscreen; + int count; + } overlays; +#endif + struct { d3d10_texture_t texture; D3D10Buffer vbo; - D3D10SamplerState sampler; bool enabled; bool fullscreen; } menu; struct { - d3d10_texture_t texture; + d3d10_texture_t texture[GFX_MAX_FRAME_HISTORY + 1]; D3D10Buffer vbo; D3D10Buffer ubo; - D3D10SamplerState sampler; D3D10_VIEWPORT viewport; + float4_t output_size; int rotation; } frame; + + struct + { + d3d10_shader_t shader; + D3D10Buffer buffers[SLANG_CBUFFER_MAX]; + d3d10_texture_t rt; + d3d10_texture_t feedback; + D3D10_VIEWPORT viewport; + pass_semantics_t semantics; + uint32_t frame_count; + } pass[GFX_MAX_SHADERS]; + + struct video_shader* shader_preset; + d3d10_texture_t luts[GFX_MAX_TEXTURES]; } d3d10_video_t; void d3d10_init_texture(D3D10Device device, d3d10_texture_t* texture); +static INLINE void d3d10_release_texture(d3d10_texture_t* texture) +{ + Release(texture->handle); + Release(texture->staging); + Release(texture->view); + Release(texture->rt_view); +} void d3d10_update_texture( + D3D10Device ctx, int width, int height, int pitch, @@ -1107,6 +1230,26 @@ void d3d10_update_texture( DXGI_FORMAT d3d10_get_closest_match( D3D10Device device, DXGI_FORMAT desired_format, UINT desired_format_support); +bool d3d10_init_shader( + D3D10Device device, + const char* src, + size_t size, + const void* src_name, + LPCSTR vs_entry, + LPCSTR ps_entry, + LPCSTR gs_entry, + const D3D10_INPUT_ELEMENT_DESC* input_element_descs, + UINT num_elements, + d3d10_shader_t* out); + +static INLINE void d3d10_release_shader(d3d10_shader_t* shader) +{ + Release(shader->layout); + Release(shader->vs); + Release(shader->ps); + Release(shader->gs); +} + static INLINE DXGI_FORMAT d3d10_get_closest_match_texture2D(D3D10Device device, DXGI_FORMAT desired_format) { @@ -1114,3 +1257,20 @@ d3d10_get_closest_match_texture2D(D3D10Device device, DXGI_FORMAT desired_format device, desired_format, D3D10_FORMAT_SUPPORT_TEXTURE2D | D3D10_FORMAT_SUPPORT_SHADER_SAMPLE); } + +static INLINE void d3d10_set_shader(D3D10Device ctx, d3d10_shader_t* shader) +{ + D3D10SetInputLayout(ctx, shader->layout); + D3D10SetVShader(ctx, shader->vs); + D3D10SetPShader(ctx, shader->ps); + D3D10SetGShader(ctx, shader->gs); +} + +#if !defined(__cplusplus) || defined(CINTERFACE) +static INLINE void +d3d10_set_texture_and_sampler(D3D10Device ctx, UINT slot, d3d10_texture_t* texture) +{ + D3D10SetPShaderResources(ctx, slot, 1, &texture->view); + D3D10SetPShaderSamplers(ctx, slot, 1, (D3D10SamplerState*)&texture->sampler); +} +#endif diff --git a/gfx/common/d3d11_common.c b/gfx/common/d3d11_common.c index a815f04538..16b32151e1 100644 --- a/gfx/common/d3d11_common.c +++ b/gfx/common/d3d11_common.c @@ -137,11 +137,23 @@ void d3d11_update_texture( D3D11_MAPPED_SUBRESOURCE mapped_texture; D3D11_BOX frame_box = { 0, 0, 0, width, height, 1 }; - D3D11MapTexture2D(ctx, texture->staging, 0, D3D11_MAP_WRITE, 0, &mapped_texture); + if (!texture || !texture->staging) + return; + D3D11MapTexture2D(ctx, texture->staging, + 0, D3D11_MAP_WRITE, 0, &mapped_texture); + +#if 0 + PERF_START(); + conv_rgb565_argb8888(mapped_texture.pData, data, width, height, + mapped_texture.RowPitch, pitch); + PERF_STOP(); +#else dxgi_copy( - width, height, format, pitch, data, texture->desc.Format, mapped_texture.RowPitch, + width, height, format, pitch, data, + texture->desc.Format, mapped_texture.RowPitch, mapped_texture.pData); +#endif D3D11UnmapTexture2D(ctx, texture->staging, 0); @@ -193,20 +205,20 @@ bool d3d11_init_shader( if (!src) /* LPCWSTR filename */ { - if (vs_entry && !d3d_compile_from_file((LPCWSTR)src_name, vs_entry, "vs_5_0", &vs_code)) + if (vs_entry && !d3d_compile_from_file((LPCWSTR)src_name, vs_entry, "vs_4_0", &vs_code)) success = false; - if (ps_entry && !d3d_compile_from_file((LPCWSTR)src_name, ps_entry, "ps_5_0", &ps_code)) + if (ps_entry && !d3d_compile_from_file((LPCWSTR)src_name, ps_entry, "ps_4_0", &ps_code)) success = false; - if (gs_entry && !d3d_compile_from_file((LPCWSTR)src_name, gs_entry, "gs_5_0", &gs_code)) + if (gs_entry && !d3d_compile_from_file((LPCWSTR)src_name, gs_entry, "gs_4_0", &gs_code)) success = false; } else /* char array */ { - if (vs_entry && !d3d_compile(src, size, (LPCSTR)src_name, vs_entry, "vs_5_0", &vs_code)) + if (vs_entry && !d3d_compile(src, size, (LPCSTR)src_name, vs_entry, "vs_4_0", &vs_code)) success = false; - if (ps_entry && !d3d_compile(src, size, (LPCSTR)src_name, ps_entry, "ps_5_0", &ps_code)) + if (ps_entry && !d3d_compile(src, size, (LPCSTR)src_name, ps_entry, "ps_4_0", &ps_code)) success = false; - if (gs_entry && !d3d_compile(src, size, (LPCSTR)src_name, gs_entry, "gs_5_0", &gs_code)) + if (gs_entry && !d3d_compile(src, size, (LPCSTR)src_name, gs_entry, "gs_4_0", &gs_code)) success = false; } diff --git a/gfx/common/d3d11_common.h b/gfx/common/d3d11_common.h index 68333f1605..69128cd07a 100644 --- a/gfx/common/d3d11_common.h +++ b/gfx/common/d3d11_common.h @@ -237,6 +237,7 @@ static INLINE void D3D11SetPShaderSamplers( device_context->lpVtbl->PSSetSamplers( device_context, start_slot, num_samplers, samplers); } + static INLINE void D3D11SetVShader( D3D11DeviceContext device_context, D3D11VertexShader vertex_shader, diff --git a/gfx/common/d3d12_common.c b/gfx/common/d3d12_common.c index 0614c84439..1b8d9478c5 100644 --- a/gfx/common/d3d12_common.c +++ b/gfx/common/d3d12_common.c @@ -206,36 +206,39 @@ bool d3d12_init_queue(d3d12_video_t* d3d12) return true; } -bool d3d12_init_swapchain(d3d12_video_t* d3d12, int width, int height, HWND hwnd) +bool d3d12_init_swapchain(d3d12_video_t* d3d12, + int width, int height, HWND hwnd) { - { - DXGI_SWAP_CHAIN_DESC desc = { 0 }; - desc.BufferCount = countof(d3d12->chain.renderTargets); - desc.BufferDesc.Width = width; - desc.BufferDesc.Height = height; - desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.SampleDesc.Count = 1; + unsigned i; + DXGI_SWAP_CHAIN_DESC desc; + + memset(&desc, 0, sizeof(DXGI_SWAP_CHAIN_DESC)); + + desc.BufferCount = countof(d3d12->chain.renderTargets); + desc.BufferDesc.Width = width; + desc.BufferDesc.Height = height; + desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; #if 0 - desc.BufferDesc.RefreshRate.Numerator = 60; - desc.BufferDesc.RefreshRate.Denominator = 1; - desc.SampleDesc.Quality = 0; + desc.BufferDesc.RefreshRate.Numerator = 60; + desc.BufferDesc.RefreshRate.Denominator = 1; + desc.SampleDesc.Quality = 0; #endif - desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - desc.OutputWindow = hwnd; - desc.Windowed = TRUE; + desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + desc.OutputWindow = hwnd; + desc.Windowed = TRUE; #if 0 - desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; #else - desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; #endif - DXGICreateSwapChain(d3d12->factory, d3d12->queue.handle, &desc, &d3d12->chain.handle); - } + DXGICreateSwapChain(d3d12->factory, d3d12->queue.handle, &desc, &d3d12->chain.handle); DXGIMakeWindowAssociation(d3d12->factory, hwnd, DXGI_MWA_NO_ALT_ENTER); d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(d3d12->chain.handle); - for (int i = 0; i < countof(d3d12->chain.renderTargets); i++) + for (i = 0; i < countof(d3d12->chain.renderTargets); i++) { DXGIGetSwapChainBuffer(d3d12->chain.handle, i, &d3d12->chain.renderTargets[i]); D3D12CreateRenderTargetView( @@ -270,7 +273,7 @@ static D3D12_CPU_DESCRIPTOR_HANDLE d3d12_descriptor_heap_slot_alloc(d3d12_descri int i; D3D12_CPU_DESCRIPTOR_HANDLE handle = { 0 }; - for (i = heap->start; i < heap->desc.NumDescriptors; i++) + for (i = heap->start; i < (int)heap->desc.NumDescriptors; i++) { if (!heap->map[i]) { @@ -372,18 +375,18 @@ bool d3d12_init_descriptors(d3d12_video_t* d3d12) cs_root_params[CS_ROOT_ID_TEXTURE_T].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; cs_root_params[CS_ROOT_ID_TEXTURE_T].DescriptorTable.NumDescriptorRanges = countof(srv_tbl); cs_root_params[CS_ROOT_ID_TEXTURE_T].DescriptorTable.pDescriptorRanges = srv_tbl; - cs_root_params[CS_ROOT_ID_TEXTURE_T].ShaderVisibility = 0; + cs_root_params[CS_ROOT_ID_TEXTURE_T].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; cs_root_params[CS_ROOT_ID_UAV_T].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; cs_root_params[CS_ROOT_ID_UAV_T].DescriptorTable.NumDescriptorRanges = countof(uav_tbl); cs_root_params[CS_ROOT_ID_UAV_T].DescriptorTable.pDescriptorRanges = uav_tbl; - cs_root_params[CS_ROOT_ID_UAV_T].ShaderVisibility = 0; + cs_root_params[CS_ROOT_ID_UAV_T].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; cs_root_params[CS_ROOT_ID_CONSTANTS].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; cs_root_params[CS_ROOT_ID_CONSTANTS].Constants.Num32BitValues = 3; cs_root_params[CS_ROOT_ID_CONSTANTS].Constants.RegisterSpace = 0; cs_root_params[CS_ROOT_ID_CONSTANTS].Constants.ShaderRegister = 0; - cs_root_params[CS_ROOT_ID_CONSTANTS].ShaderVisibility = 0; + cs_root_params[CS_ROOT_ID_CONSTANTS].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; static_sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; static_sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; @@ -733,6 +736,9 @@ void d3d12_update_texture( uint8_t* dst; D3D12_RANGE read_range = { 0, 0 }; + if (!texture || !texture->upload_buffer) + return; + D3D12Map(texture->upload_buffer, 0, &read_range, (void**)&dst); dxgi_copy( diff --git a/gfx/common/d3d8_common.c b/gfx/common/d3d8_common.c index 07fb3cf1a0..f05ab1a18a 100644 --- a/gfx/common/d3d8_common.c +++ b/gfx/common/d3d8_common.c @@ -13,6 +13,8 @@ * If not, see . */ +#define CINTERFACE + /* For Xbox we will just link statically * to Direct3D libraries instead. */ @@ -24,18 +26,11 @@ #include #endif -#include "../../configuration.h" #include "../../verbosity.h" -#include - #ifdef HAVE_D3DX -#ifdef _XBOX #include #include -#else -#include "../include/d3d8/d3dx8tex.h" -#endif #endif #include "d3d8_common.h" @@ -172,143 +167,32 @@ void d3d8_deinitialize_symbols(void) #endif } -bool d3d8_check_device_type(void *_d3d, - unsigned idx, - INT32 disp_format, - INT32 backbuffer_format, - bool windowed_mode) -{ - LPDIRECT3D8 d3d = (LPDIRECT3D8)_d3d; - if (!d3d) - return false; -#ifdef __cplusplus - if (FAILED(d3d->CheckDeviceType( - 0, - D3DDEVTYPE_HAL, - (D3DFORMAT)disp_format, - (D3DFORMAT)backbuffer_format, - windowed_mode))) - return false; -#else - if (FAILED(IDirect3D8_CheckDeviceType(d3d, - 0, - D3DDEVTYPE_HAL, - disp_format, - backbuffer_format, - windowed_mode))) - return false; -#endif - - return true; -} - -bool d3d8_get_adapter_display_mode( - void *_d3d, - unsigned idx, - void *display_mode) -{ - LPDIRECT3D8 d3d = (LPDIRECT3D8)_d3d; - if (!d3d) - return false; -#ifdef __cplusplus - if (FAILED(d3d->GetAdapterDisplayMode(idx, (D3DDISPLAYMODE*)display_mode))) - return false; -#else - if (FAILED(IDirect3D8_GetAdapterDisplayMode(d3d, idx, (D3DDISPLAYMODE*)display_mode))) - return false; -#endif - - return true; -} - -bool d3d8_swap(void *data, void *_dev) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; -#ifdef __cplusplus - if (dev->Present(NULL, NULL, NULL, NULL) != D3D_OK) - return false; -#else - if (IDirect3DDevice8_Present(dev, NULL, NULL, NULL, NULL) - == D3DERR_DEVICELOST) - return false; -#endif - return true; -} - -void d3d8_set_transform(void *_dev, - INT32 state, const void *_matrix) -{ - CONST D3DMATRIX *matrix = (CONST D3DMATRIX*)_matrix; - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; -#ifdef __cplusplus - dev->SetTransform((D3DTRANSFORMSTATETYPE)state, matrix); -#else - IDirect3DDevice8_SetTransform(dev, (D3DTRANSFORMSTATETYPE)state, matrix); -#endif -} - -bool d3d8_texture_get_level_desc(void *_tex, - unsigned idx, void *_ppsurface_level) -{ - LPDIRECT3DTEXTURE8 tex = (LPDIRECT3DTEXTURE8)_tex; -#ifdef __cplusplus - if (SUCCEEDED(tex->GetLevelDesc(idx, (D3DSURFACE_DESC*)_ppsurface_level))) - return true; -#else - if (SUCCEEDED(IDirect3DTexture8_GetLevelDesc(tex, idx, (D3DSURFACE_DESC*)_ppsurface_level))) - return true; -#endif - - return false; -} - -bool d3d8_texture_get_surface_level(void *_tex, - unsigned idx, void **_ppsurface_level) -{ - LPDIRECT3DTEXTURE8 tex = (LPDIRECT3DTEXTURE8)_tex; - if (!tex) - return false; -#ifdef __cplusplus - if (SUCCEEDED(tex->GetSurfaceLevel(idx, (IDirect3DSurface8**)_ppsurface_level))) - return true; -#else - if (SUCCEEDED(IDirect3DTexture8_GetSurfaceLevel(tex, idx, (IDirect3DSurface8**)_ppsurface_level))) - return true; -#endif - - return false; -} - #ifdef HAVE_D3DX static void *d3d8_texture_new_from_file( - void *dev, + LPDIRECT3DDEVICE8 dev, const char *path, unsigned width, unsigned height, unsigned miplevels, unsigned usage, D3DFORMAT format, - INT32 pool, unsigned filter, unsigned mipfilter, + D3DPOOL pool, unsigned filter, unsigned mipfilter, INT32 color_key, void *src_info_data, PALETTEENTRY *palette) { void *buf = NULL; - HRESULT hr = D3DCreateTextureFromFile((LPDIRECT3DDEVICE8)dev, + if (FAILED(D3DCreateTextureFromFile(dev, path, width, height, miplevels, usage, format, - (D3DPOOL)pool, filter, mipfilter, color_key, src_info_data, - palette, (struct IDirect3DTeture8**)&buf); - - if (FAILED(hr)) + pool, filter, mipfilter, color_key, src_info_data, + palette, (struct IDirect3DTeture8**)&buf))) return NULL; - return buf; } #endif -void *d3d8_texture_new(void *_dev, +void *d3d8_texture_new(LPDIRECT3DDEVICE8 dev, const char *path, unsigned width, unsigned height, unsigned miplevels, unsigned usage, INT32 format, INT32 pool, unsigned filter, unsigned mipfilter, INT32 color_key, void *src_info_data, PALETTEENTRY *palette, bool want_mipmap) { - HRESULT hr = S_OK; void *buf = NULL; if (path) @@ -324,528 +208,53 @@ void *d3d8_texture_new(void *_dev, #endif } - { - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; -#ifdef __cplusplus - hr = dev->CreateTexture( - width, height, miplevels, usage, - (D3DFORMAT)format, (D3DPOOL)pool, (IDirect3DTexture8**)&buf); -#else - hr = IDirect3DDevice8_CreateTexture(dev, - width, height, miplevels, usage, - (D3DFORMAT)format, (D3DPOOL)pool, (struct IDirect3DTexture8**)&buf); -#endif - } - - if (FAILED(hr)) + if (FAILED(IDirect3DDevice8_CreateTexture(dev, + width, height, miplevels, usage, + (D3DFORMAT)format, (D3DPOOL)pool, + (struct IDirect3DTexture8**)&buf))) return NULL; return buf; } -void d3d8_texture_free(void *_tex) -{ - LPDIRECT3DTEXTURE8 tex = (LPDIRECT3DTEXTURE8)_tex; - if (!tex) - return; -#ifdef __cplusplus - tex->Release(); -#else - IDirect3DTexture8_Release(tex); -#endif -} - -bool d3d8_surface_lock_rect(void *data, void *data2) -{ - LPDIRECT3DSURFACE8 surf = (LPDIRECT3DSURFACE8)data; - if (!surf) - return false; -#ifdef __cplusplus - if (FAILED(surf->LockRect((D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY))) - return false; -#else - if (FAILED(IDirect3DSurface8_LockRect(surf, (D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY))) - return false; -#endif - - return true; -} - -void d3d8_surface_unlock_rect(void *data) -{ - LPDIRECT3DSURFACE8 surf = (LPDIRECT3DSURFACE8)data; - if (!surf) - return; -#ifdef __cplusplus - surf->UnlockRect(); -#else - IDirect3DSurface8_UnlockRect(surf); -#endif -} - -void d3d8_surface_free(void *data) -{ - LPDIRECT3DSURFACE8 surf = (LPDIRECT3DSURFACE8)data; - if (!surf) - return; -#ifdef __cplusplus - surf->Release(); -#else - IDirect3DSurface8_Release(surf); -#endif -} - -void *d3d8_vertex_buffer_new(void *_dev, - unsigned length, unsigned usage, - unsigned fvf, INT32 pool, void *handle) -{ - void *buf = NULL; - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; -#ifdef __cplusplus - HRESULT hr = dev->CreateVertexBuffer( - length, usage, fvf, (D3DPOOL)pool, (IDirect3DVertexBuffer8**)&buf); -#else - HRESULT hr = IDirect3DDevice8_CreateVertexBuffer( - dev, length, usage, fvf, - (D3DPOOL)pool, - (struct IDirect3DVertexBuffer8**)&buf); -#endif - - if (FAILED(hr)) - return NULL; - - return buf; -} - -void d3d8_vertex_buffer_unlock(void *vertbuf_ptr) -{ - LPDIRECT3DVERTEXBUFFER8 vertbuf = (LPDIRECT3DVERTEXBUFFER8)vertbuf_ptr; - - if (!vertbuf) - return; -#ifdef __cplusplus - vertbuf->Unlock(); -#else - IDirect3DVertexBuffer8_Unlock(vertbuf); -#endif -} - -void *d3d8_vertex_buffer_lock(void *vertbuf_ptr) -{ - void *buf = NULL; - LPDIRECT3DVERTEXBUFFER8 vertbuf = (LPDIRECT3DVERTEXBUFFER8)vertbuf_ptr; - - if (!vertbuf) - return NULL; - -#ifdef __cplusplus - vertbuf->Lock(0, 0, (BYTE**)&buf, 0); -#else - IDirect3DVertexBuffer8_Lock(vertbuf, 0, 0, (BYTE**)&buf, 0); -#endif - - if (!buf) - return NULL; - - return buf; -} - -void d3d8_vertex_buffer_free(void *vertex_data, void *vertex_declaration) -{ - if (vertex_data) - { - LPDIRECT3DVERTEXBUFFER8 buf = (LPDIRECT3DVERTEXBUFFER8)vertex_data; -#ifdef __cplusplus - buf->Release(); -#else - IDirect3DVertexBuffer8_Release(buf); -#endif - buf = NULL; - } -} - -void d3d8_set_stream_source(void *_dev, unsigned stream_no, - void *stream_vertbuf_ptr, unsigned offset_bytes, - unsigned stride) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - LPDIRECT3DVERTEXBUFFER8 stream_vertbuf = (LPDIRECT3DVERTEXBUFFER8)stream_vertbuf_ptr; - if (!stream_vertbuf) - return; -#ifdef __cplusplus - dev->SetStreamSource(stream_no, stream_vertbuf, offset_bytes, stride); -#else - IDirect3DDevice8_SetStreamSource(dev, stream_no, stream_vertbuf, stride); -#endif -} - -static void d3d8_set_texture_stage_state(void *_dev, - unsigned sampler, unsigned type, unsigned value) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; -#ifdef __cplusplus - if (dev->SetTextureStageState(sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) - RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); -#else - if (IDirect3DDevice8_SetTextureStageState(dev, sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) - RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); -#endif -} - -void d3d8_set_sampler_address_u(void *_dev, - unsigned sampler, unsigned value) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - d3d8_set_texture_stage_state(dev, sampler, D3DTSS_ADDRESSU, value); -} - -void d3d8_set_sampler_address_v(void *_dev, - unsigned sampler, unsigned value) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - d3d8_set_texture_stage_state(dev, sampler, D3DTSS_ADDRESSV, value); -} - -void d3d8_set_sampler_minfilter(void *_dev, - unsigned sampler, unsigned value) -{ - d3d8_set_texture_stage_state(_dev, sampler, D3DTSS_MINFILTER, value); -} - -void d3d8_set_sampler_magfilter(void *_dev, - unsigned sampler, unsigned value) -{ - d3d8_set_texture_stage_state(_dev, sampler, D3DTSS_MAGFILTER, value); -} - -bool d3d8_begin_scene(void *_dev) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - if (!dev) - return false; -#ifdef __cplusplus -#ifdef _XBOX - dev->BeginScene(); -#else - if (FAILED(dev->BeginScene())) - return false; -#endif -#else -#ifdef _XBOX - IDirect3DDevice8_BeginScene(dev); -#else - if (FAILED(IDirect3DDevice8_BeginScene(dev))) - return false; -#endif -#endif - - return true; -} - -void d3d8_end_scene(void *_dev) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - if (!dev) - return; -#ifdef __cplusplus - dev->EndScene(); -#else - IDirect3DDevice8_EndScene(dev); -#endif -} - -static void d3d8_draw_primitive_internal(void *_dev, - D3DPRIMITIVETYPE type, unsigned start, unsigned count) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - if (!dev) - return; -#ifdef __cplusplus - dev->DrawPrimitive(type, start, count); -#else - IDirect3DDevice8_DrawPrimitive(dev, type, start, count); -#endif -} - -void d3d8_draw_primitive(void *dev, - INT32 type, unsigned start, unsigned count) -{ - if (!d3d8_begin_scene(dev)) - return; - - d3d8_draw_primitive_internal(dev, (D3DPRIMITIVETYPE)type, start, count); - d3d8_end_scene(dev); -} - -void d3d8_clear(void *_dev, - unsigned count, const void *rects, unsigned flags, - INT32 color, float z, unsigned stencil) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - if (!dev) - return; -#ifdef __cplusplus - dev->Clear(count, (const D3DRECT*)rects, flags, color, z, stencil); -#else - IDirect3DDevice8_Clear(dev, count, (const D3DRECT*)rects, flags, - color, z, stencil); -#endif -} - -bool d3d8_device_get_render_target(void *_dev, - unsigned idx, void **data) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - if (!dev) - return false; -#ifdef __cplusplus - if (SUCCEEDED(dev->GetRenderTarget( - (LPDIRECT3DSURFACE8*)data))) - return true; -#else - if (SUCCEEDED(IDirect3DDevice8_GetRenderTarget(dev, - (LPDIRECT3DSURFACE8*)data))) - return true; -#endif - - return false; -} - - -bool d3d8_lock_rectangle(void *_tex, - unsigned level, void *_lr, RECT *rect, - unsigned rectangle_height, unsigned flags) -{ - D3DLOCKED_RECT *lr = (D3DLOCKED_RECT*)_lr; - LPDIRECT3DTEXTURE8 tex = (LPDIRECT3DTEXTURE8)_tex; - if (!tex) - return false; -#ifdef __cplusplus - if (FAILED(tex->LockRect(level, lr, rect, flags))) - return false; -#else - if (IDirect3DTexture8_LockRect(tex, level, lr, rect, flags) != D3D_OK) - return false; -#endif - - return true; -} - -void d3d8_unlock_rectangle(void *_tex) -{ - LPDIRECT3DTEXTURE8 tex = (LPDIRECT3DTEXTURE8)_tex; - if (!tex) - return; -#ifdef __cplusplus - tex->UnlockRect(0); -#else - IDirect3DTexture8_UnlockRect(tex, 0); -#endif -} - -void d3d8_lock_rectangle_clear(void *tex, - unsigned level, void *_lr, RECT *rect, - unsigned rectangle_height, unsigned flags) -{ - D3DLOCKED_RECT *lr = (D3DLOCKED_RECT*)_lr; -#if defined(_XBOX) - level = 0; -#endif - memset(lr->pBits, level, rectangle_height * lr->Pitch); - d3d8_unlock_rectangle(tex); -} - -void d3d8_set_viewports(void *_dev, void *_vp) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - D3DVIEWPORT8 *vp = (D3DVIEWPORT8*)_vp; - if (!dev) - return; -#ifdef __cplusplus - dev->SetViewport(vp); -#else - IDirect3DDevice8_SetViewport(dev, vp); -#endif -} - -void d3d8_set_texture(void *_dev, unsigned sampler, - void *tex_data) -{ - LPDIRECT3DTEXTURE8 tex = (LPDIRECT3DTEXTURE8)tex_data; - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - if (!dev || !tex) - return; -#ifdef __cplusplus - dev->SetTexture(sampler, tex); -#else - IDirect3DDevice8_SetTexture(dev, sampler, - (IDirect3DBaseTexture8*)tex); -#endif -} - -bool d3d8_set_vertex_shader(void *_dev, unsigned index, - void *data) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; -#ifdef __cplusplus - LPDIRECT3DVERTEXSHADER8 shader = (LPDIRECT3DVERTEXSHADER8)data; - - if (dev->SetVertexShader(shader) != D3D_OK) - return false; -#else - if (IDirect3DDevice8_SetVertexShader(dev, index) != D3D_OK) - return false; -#endif - - return true; -} - -void d3d8_texture_blit(unsigned pixel_size, - void *tex, - void *_lr, const void *frame, - unsigned width, unsigned height, unsigned pitch) -{ - unsigned y; - D3DLOCKED_RECT *lr = (D3DLOCKED_RECT*)_lr; - - for (y = 0; y < height; y++) - { - const uint8_t *in = (const uint8_t*)frame + y * pitch; - uint8_t *out = (uint8_t*)lr->pBits + y * lr->Pitch; - memcpy(out, in, width * pixel_size); - } -} - -bool d3d8_get_render_state(void *data, INT32 state, DWORD *value) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)data; -#ifdef __cplusplus - if (dev && dev->GetRenderState((D3DRENDERSTATETYPE)state, value) == D3D_OK) - return true; -#else - if (dev && IDirect3DDevice8_GetRenderState(dev, (D3DRENDERSTATETYPE)state, value) == D3D_OK) - return true; -#endif - - return false; -} - -void d3d8_set_render_state(void *data, INT32 state, DWORD value) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)data; - if (!dev) - return; -#ifdef __cplusplus - dev->SetRenderState((D3DRENDERSTATETYPE)state, value); -#else - IDirect3DDevice8_SetRenderState(dev, (D3DRENDERSTATETYPE)state, value); -#endif -} - -void d3d8_enable_blend_func(void *data) -{ - if (!data) - return; - - d3d8_set_render_state(data, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - d3d8_set_render_state(data, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - d3d8_set_render_state(data, D3DRS_ALPHABLENDENABLE, true); -} - -void d3d8_device_set_render_target(void *_dev, unsigned idx, - void *data) -{ - LPDIRECT3DSURFACE8 surf = (LPDIRECT3DSURFACE8)data; - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - if (!dev) - return; -#ifdef __cplusplus - dev->SetRenderTarget(idx, surf); -#else - IDirect3DDevice8_SetRenderTarget(dev, surf, NULL); -#endif -} - -void d3d8_enable_alpha_blend_texture_func(void *data) -{ - /* Also blend the texture with the set alpha value. */ - d3d8_set_texture_stage_state(data, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - d3d8_set_texture_stage_state(data, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); - d3d8_set_texture_stage_state(data, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); -} - void d3d8_frame_postprocess(void *data) { #if defined(_XBOX) global_t *global = global_get_ptr(); -#ifdef __cplusplus - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)data; - if (!dev) - return; - - dev->SetFlickerFilter(global->console.screen.flicker_filter_index); - dev->SetSoftDisplayFilter(global->console.softfilter_enable); -#else D3DDevice_SetFlickerFilter(global->console.screen.flicker_filter_index); D3DDevice_SetSoftDisplayFilter(global->console.softfilter_enable); #endif -#endif } -void d3d8_disable_blend_func(void *data) -{ - d3d8_set_render_state(data, D3DRS_ALPHABLENDENABLE, false); -} - -static bool d3d8_reset_internal(void *data, +static bool d3d8_reset_internal(LPDIRECT3DDEVICE8 dev, D3DPRESENT_PARAMETERS *d3dpp ) { - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)data; - if (!dev) - return false; -#ifdef __cplusplus - if ((dev->Reset(d3dpp) == D3D_OK)) + if (dev && + IDirect3DDevice8_Reset(dev, d3dpp) == D3D_OK) return true; -#else - if (IDirect3DDevice8_Reset(dev, d3dpp) == D3D_OK) - return true; -#endif - return false; } -static HRESULT d3d8_test_cooperative_level(void *data) +static HRESULT d3d8_test_cooperative_level(LPDIRECT3DDEVICE8 dev) { -#ifdef _XBOX +#ifndef _XBOX + if (dev) + return IDirect3DDevice8_TestCooperativeLevel(dev); +#endif return E_FAIL; -#else - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)data; - if (!dev) - return E_FAIL; - -#ifdef __cplusplus - return dev->TestCooperativeLevel(); -#else - return IDirect3DDevice8_TestCooperativeLevel(dev); -#endif -#endif } static bool d3d8_create_device_internal( - void *data, + LPDIRECT3DDEVICE8 dev, D3DPRESENT_PARAMETERS *d3dpp, - void *_d3d, + LPDIRECT3D8 d3d, HWND focus_window, unsigned cur_mon_id, DWORD behavior_flags) { - LPDIRECT3D8 d3d = (LPDIRECT3D8)_d3d; - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)data; - if (!dev) - return false; -#ifdef __cplusplus - if (SUCCEEDED(d3d->CreateDevice( + if (dev && + SUCCEEDED(IDirect3D8_CreateDevice(d3d, cur_mon_id, D3DDEVTYPE_HAL, focus_window, @@ -853,23 +262,13 @@ static bool d3d8_create_device_internal( d3dpp, (IDirect3DDevice8**)dev))) return true; -#else - if (SUCCEEDED(IDirect3D8_CreateDevice(d3d, - cur_mon_id, - D3DDEVTYPE_HAL, - focus_window, - behavior_flags, - d3dpp, - (IDirect3DDevice8**)dev))) - return true; -#endif return false; } bool d3d8_create_device(void *dev, void *d3dpp, - void *d3d, + LPDIRECT3D8 d3d, HWND focus_window, unsigned cur_mon_id) { @@ -922,165 +321,47 @@ bool d3d8_reset(void *dev, void *d3dpp) return false; } -bool d3d8_device_get_backbuffer(void *_dev, - unsigned idx, unsigned swapchain_idx, - unsigned backbuffer_type, void **data) -{ - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - if (!dev) - return false; -#ifdef __cplusplus - if (SUCCEEDED(dev->GetBackBuffer(idx, - (D3DBACKBUFFER_TYPE)backbuffer_type, - (LPDIRECT3DSURFACE8*)data))) - return true; -#else - if (SUCCEEDED(IDirect3DDevice8_GetBackBuffer(dev, idx, - (D3DBACKBUFFER_TYPE)backbuffer_type, - (LPDIRECT3DSURFACE8*)data))) - return true; -#endif - - return false; -} - - -void d3d8_device_free(void *_dev, void *_pd3d) -{ - LPDIRECT3D8 pd3d = (LPDIRECT3D8)_pd3d; - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; - if (dev) - { -#ifdef __cplusplus - dev->Release(); -#else - IDirect3DDevice8_Release(dev); -#endif - } - - if (pd3d) - { -#if defined(__cplusplus) - pd3d->Release(); -#else - IDirect3D8_Release(pd3d); -#endif - } -} - -INT32 d3d8_translate_filter(unsigned type) -{ - switch (type) - { - case RARCH_FILTER_UNSPEC: - { - settings_t *settings = config_get_ptr(); - if (!settings->bools.video_smooth) - break; - } - /* fall-through */ - case RARCH_FILTER_LINEAR: - return D3DTEXF_LINEAR; - case RARCH_FILTER_NEAREST: - break; - } - - return D3DTEXF_POINT; -} - -bool d3d8x_create_font_indirect(void *_dev, +bool d3d8x_create_font_indirect(LPDIRECT3DDEVICE8 dev, void *desc, void **font_data) { #ifdef HAVE_D3DX - LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)_dev; if (SUCCEEDED(D3DCreateFontIndirect( dev, (CONST LOGFONT*)desc, (struct ID3DXFont**)font_data))) return true; #endif - return false; } -void d3d8x_font_draw_text(void *data, void *sprite_data, void *string_data, - unsigned count, void *rect_data, unsigned format, unsigned color) +void d3d8x_font_draw_text(void *data, + void *sprite_data, void *string_data, + unsigned count, void *rect_data, + unsigned format, unsigned color) { #ifdef HAVE_D3DX -#if !defined(__cplusplus) || defined(CINTERFACE) ID3DXFont *font = (ID3DXFont*)data; - if (!font) - return; - font->lpVtbl->DrawText(font, (LPD3DXSPRITE)sprite_data, - (LPCTSTR)string_data, count, (LPRECT)rect_data, - (DWORD)format, (D3DCOLOR)color); -#else - LPD3DXFONT font = (LPD3DXFONT)data; - if (!font) - return; - font->DrawText((LPD3DXSPRITE)sprite_data, - (LPCTSTR)string_data, count, (LPRECT)rect_data, - (DWORD)format, (D3DCOLOR)color); -#endif + if (font) + font->lpVtbl->DrawText(font, (LPD3DXSPRITE)sprite_data, + (LPCTSTR)string_data, count, (LPRECT)rect_data, + (DWORD)format, (D3DCOLOR)color); #endif } void d3d8x_font_release(void *data) { #ifdef HAVE_D3DX -#if !defined(__cplusplus) || defined(CINTERFACE) ID3DXFont *font = (ID3DXFont*)data; - if (!font) - return; - font->lpVtbl->Release(font); -#else - LPD3DXFONT font = (LPD3DXFONT)data; - if (!font) - return; - font->Release(); -#endif + if (font) + font->lpVtbl->Release(font); #endif } void d3d8x_font_get_text_metrics(void *data, void *metrics) { #ifdef HAVE_D3DX -#if !defined(__cplusplus) || defined(CINTERFACE) ID3DXFont *font = (ID3DXFont*)data; - if (!font) - return; - font->lpVtbl->GetTextMetrics(font, (TEXTMETRICA*)metrics); -#else - LPD3DXFONT font = (LPD3DXFONT)data; - if (!font) - return; - font->GetTextMetricsA((TEXTMETRICA*)metrics); -#endif + if (font) + font->lpVtbl->GetTextMetrics(font, (TEXTMETRICA*)metrics); #endif } -INT32 d3d8_get_rgb565_format(void) -{ -#ifdef _XBOX - return D3DFMT_LIN_R5G6B5; -#else - return D3DFMT_R5G6B5; -#endif -} - -INT32 d3d8_get_argb8888_format(void) -{ -#ifdef _XBOX - return D3DFMT_LIN_A8R8G8B8; -#else - return D3DFMT_A8R8G8B8; -#endif -} - -INT32 d3d8_get_xrgb8888_format(void) -{ -#ifdef _XBOX - return D3DFMT_LIN_X8R8G8B8; -#else - return D3DFMT_X8R8G8B8; -#endif -} diff --git a/gfx/common/d3d8_common.h b/gfx/common/d3d8_common.h index 41260b7340..eff0cc026b 100644 --- a/gfx/common/d3d8_common.h +++ b/gfx/common/d3d8_common.h @@ -18,166 +18,444 @@ #include #include +#include +#include + +#include "../drivers/d3d.h" #include "../video_driver.h" +#include "../../verbosity.h" RETRO_BEGIN_DECLS -bool d3d8_swap(void *data, void *dev); +typedef struct d3d8_video +{ + bool keep_aspect; + bool should_resize; + bool quitting; + bool needs_restore; + bool overlays_enabled; + /* TODO - refactor this away properly. */ + bool resolution_hd_enable; -void *d3d8_vertex_buffer_new(void *dev, - unsigned length, unsigned usage, unsigned fvf, - INT32 pool, void *handle); + unsigned cur_mon_id; + unsigned dev_rotation; -void *d3d8_vertex_buffer_lock(void *data); -void d3d8_vertex_buffer_unlock(void *data); + overlay_t *menu; + const d3d_renderchain_driver_t *renderchain_driver; + void *renderchain_data; -void d3d8_vertex_buffer_free(void *vertex_data, void *vertex_declaration); + RECT font_rect; + RECT font_rect_shifted; + math_matrix_4x4 mvp; + math_matrix_4x4 mvp_rotate; + math_matrix_4x4 mvp_transposed; -bool d3d8_texture_get_level_desc(void *tex, - unsigned idx, void *_ppsurface_level); + struct video_viewport vp; + struct video_shader shader; + video_info_t video_info; + WNDCLASSEX windowClass; + LPDIRECT3DDEVICE8 dev; + d3d_video_viewport_t final_viewport; -bool d3d8_texture_get_surface_level(void *tex, - unsigned idx, void **_ppsurface_level); + char *shader_path; -void *d3d8_texture_new(void *dev, + struct + { + int size; + int offset; + void *buffer; + void *decl; + }menu_display; + + size_t overlays_size; + overlay_t *overlays; +} d3d8_video_t; + +static INLINE bool d3d8_swap(void *data, LPDIRECT3DDEVICE8 dev) +{ + if (IDirect3DDevice8_Present(dev, NULL, NULL, NULL, NULL) + == D3DERR_DEVICELOST) + return false; + return true; +} + +static INLINE void *d3d8_vertex_buffer_new( + LPDIRECT3DDEVICE8 dev, + unsigned length, unsigned usage, + unsigned fvf, D3DPOOL pool, void *handle) +{ + void *buf = NULL; + if (FAILED(IDirect3DDevice8_CreateVertexBuffer( + dev, length, usage, fvf, + pool, + (struct IDirect3DVertexBuffer8**)&buf))) + return NULL; + return buf; +} + +static INLINE void * +d3d8_vertex_buffer_lock(LPDIRECT3DVERTEXBUFFER8 vertbuf) +{ + void *buf = NULL; + + if (!vertbuf) + return NULL; + + IDirect3DVertexBuffer8_Lock(vertbuf, 0, 0, (BYTE**)&buf, 0); + + if (!buf) + return NULL; + + return buf; +} + +static INLINE void d3d8_vertex_buffer_unlock( + LPDIRECT3DVERTEXBUFFER8 vertbuf) +{ + if (vertbuf) + IDirect3DVertexBuffer8_Unlock(vertbuf); +} + +static INLINE void d3d8_vertex_buffer_free( + LPDIRECT3DVERTEXBUFFER8 buf, + void *vertex_declaration) +{ + if (buf) + { + IDirect3DVertexBuffer8_Release(buf); + buf = NULL; + } +} + +static INLINE bool d3d8_texture_get_level_desc( + LPDIRECT3DTEXTURE8 tex, + unsigned idx, void *_ppsurface_level) +{ + if (SUCCEEDED(IDirect3DTexture8_GetLevelDesc( + tex, idx, (D3DSURFACE_DESC*)_ppsurface_level))) + return true; + return false; +} + +static INLINE bool d3d8_texture_get_surface_level( + LPDIRECT3DTEXTURE8 tex, + unsigned idx, void **_ppsurface_level) +{ + if (tex && + SUCCEEDED( + IDirect3DTexture8_GetSurfaceLevel( + tex, idx, (IDirect3DSurface8**)_ppsurface_level))) + return true; + return false; +} + +void *d3d8_texture_new(LPDIRECT3DDEVICE8 dev, const char *path, unsigned width, unsigned height, unsigned miplevels, unsigned usage, INT32 format, INT32 pool, unsigned filter, unsigned mipfilter, - INT32 color_key, void *src_info, + INT32 color_key, void *src_info_data, PALETTEENTRY *palette, bool want_mipmap); -void d3d8_set_stream_source(void *dev, unsigned stream_no, - void *stream_vertbuf, unsigned offset_bytes, - unsigned stride); +static INLINE void d3d8_set_stream_source(LPDIRECT3DDEVICE8 dev, + unsigned stream_no, + LPDIRECT3DVERTEXBUFFER8 stream_vertbuf, + unsigned offset_bytes, + unsigned stride) +{ + if (stream_vertbuf) + IDirect3DDevice8_SetStreamSource(dev, + stream_no, stream_vertbuf, stride); +} -void d3d8_texture_free(void *tex); +static INLINE void d3d8_texture_free(LPDIRECT3DTEXTURE8 tex) +{ + if (tex) + IDirect3DTexture8_Release(tex); +} -void d3d8_set_transform(void *dev, - INT32 state, const void *_matrix); +static INLINE void d3d8_set_transform(LPDIRECT3DDEVICE8 dev, + D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix) +{ + IDirect3DDevice8_SetTransform(dev, state, matrix); +} -void d3d8_set_sampler_address_u(void *dev, - unsigned sampler, unsigned value); +static INLINE void d3d8_set_texture_stage_state(LPDIRECT3DDEVICE8 dev, + unsigned sampler, D3DTEXTURESTAGESTATETYPE type, unsigned value) +{ + if (IDirect3DDevice8_SetTextureStageState(dev, sampler, + (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) + RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); +} -void d3d8_set_sampler_address_v(void *dev, - unsigned sampler, unsigned value); +static INLINE void d3d8_set_sampler_address_u(LPDIRECT3DDEVICE8 dev, + unsigned sampler, unsigned value) +{ + d3d8_set_texture_stage_state(dev, sampler, D3DTSS_ADDRESSU, value); +} -void d3d8_set_sampler_minfilter(void *dev, - unsigned sampler, unsigned value); +static INLINE void d3d8_set_sampler_address_v(LPDIRECT3DDEVICE8 dev, + unsigned sampler, unsigned value) +{ + d3d8_set_texture_stage_state(dev, sampler, D3DTSS_ADDRESSV, value); +} -void d3d8_set_sampler_magfilter(void *dev, - unsigned sampler, unsigned value); +static INLINE void d3d8_set_sampler_minfilter(void *_dev, + unsigned sampler, unsigned value) +{ + d3d8_set_texture_stage_state(_dev, sampler, D3DTSS_MINFILTER, value); +} + +static INLINE void d3d8_set_sampler_magfilter(void *_dev, + unsigned sampler, unsigned value) +{ + d3d8_set_texture_stage_state(_dev, sampler, D3DTSS_MAGFILTER, value); +} void d3d8_set_sampler_mipfilter(void *dev, unsigned sampler, unsigned value); -bool d3d8_begin_scene(void *dev); +static INLINE bool d3d8_begin_scene(LPDIRECT3DDEVICE8 dev) +{ + if (!dev) + return false; +#ifdef _XBOX + IDirect3DDevice8_BeginScene(dev); +#else + if (FAILED(IDirect3DDevice8_BeginScene(dev))) + return false; +#endif -void d3d8_end_scene(void *dev); + return true; +} -void d3d8_draw_primitive(void *dev, - INT32 type, unsigned start, unsigned count); +static INLINE void d3d8_end_scene(LPDIRECT3DDEVICE8 dev) +{ + if (dev) + IDirect3DDevice8_EndScene(dev); +} -void d3d8_clear(void *dev, +static INLINE void d3d8_draw_primitive(LPDIRECT3DDEVICE8 dev, + D3DPRIMITIVETYPE type, unsigned start, unsigned count) +{ + if (!d3d8_begin_scene(dev)) + return; + + IDirect3DDevice8_DrawPrimitive(dev, type, start, count); + d3d8_end_scene(dev); +} + +static INLINE void d3d8_clear(LPDIRECT3DDEVICE8 dev, unsigned count, const void *rects, unsigned flags, - INT32 color, float z, unsigned stencil); + INT32 color, float z, unsigned stencil) +{ + if (dev) + IDirect3DDevice8_Clear(dev, count, (const D3DRECT*)rects, flags, + color, z, stencil); +} -bool d3d8_lock_rectangle(void *tex, - unsigned level, void *lock_rect, RECT *rect, - unsigned rectangle_height, unsigned flags); +static INLINE bool d3d8_lock_rectangle( + LPDIRECT3DTEXTURE8 tex, + unsigned level, D3DLOCKED_RECT *lr, RECT *rect, + unsigned rectangle_height, unsigned flags) +{ + if (tex && + IDirect3DTexture8_LockRect(tex, + level, lr, rect, flags) == D3D_OK) + return true; + return false; +} -void d3d8_lock_rectangle_clear(void *tex, - unsigned level, void *lock_rect, RECT *rect, - unsigned rectangle_height, unsigned flags); +static INLINE void d3d8_unlock_rectangle(LPDIRECT3DTEXTURE8 tex) +{ + if (tex) + IDirect3DTexture8_UnlockRect(tex, 0); +} -void d3d8_unlock_rectangle(void *tex); - -void d3d8_set_texture(void *dev, unsigned sampler, - void *tex_data); - -bool d3d8_create_vertex_shader(void *dev, - const DWORD *a, void **b); - -bool d3d8_create_pixel_shader(void *dev, - const DWORD *a, void **b); - -void d3d8_free_vertex_shader(void *dev, void *data); - -bool d3d8_set_vertex_shader(void *dev, unsigned index, - void *data); - -void d3d8_texture_blit(unsigned pixel_size, +static INLINE void d3d8_lock_rectangle_clear( void *tex, - void *lr, const void *frame, - unsigned width, unsigned height, unsigned pitch); + unsigned level, void *_lr, RECT *rect, + unsigned rectangle_height, unsigned flags) +{ + D3DLOCKED_RECT *lr = (D3DLOCKED_RECT*)_lr; +#if defined(_XBOX) + level = 0; +#endif + memset(lr->pBits, level, rectangle_height * lr->Pitch); + d3d8_unlock_rectangle(tex); +} -bool d3d8_vertex_declaration_new(void *dev, - const void *vertex_data, void **decl_data); +static INLINE void d3d8_set_texture( + LPDIRECT3DDEVICE8 dev, unsigned sampler, + LPDIRECT3DTEXTURE8 tex) +{ + if (dev && tex) + IDirect3DDevice8_SetTexture(dev, sampler, + (IDirect3DBaseTexture8*)tex); +} -void d3d8_vertex_declaration_free(void *data); +static INLINE bool d3d8_set_vertex_shader( + LPDIRECT3DDEVICE8 dev, + unsigned index, + void *data) +{ + if (IDirect3DDevice8_SetVertexShader(dev, index) != D3D_OK) + return false; + return true; +} -void d3d8_set_viewports(void *dev, void *vp); +static INLINE void d3d8_texture_blit( + unsigned pixel_size, + void *tex, + D3DLOCKED_RECT *lr, + const void *frame, + unsigned width, unsigned height, unsigned pitch) +{ + unsigned y; -void d3d8_enable_blend_func(void *data); + for (y = 0; y < height; y++) + { + const uint8_t *in = (const uint8_t*)frame + y * pitch; + uint8_t *out = (uint8_t*)lr->pBits + y * lr->Pitch; + memcpy(out, in, width * pixel_size); + } +} -void d3d8_disable_blend_func(void *data); +static INLINE void d3d8_set_viewports( + LPDIRECT3DDEVICE8 dev, + void *vp) +{ + if (dev) + IDirect3DDevice8_SetViewport(dev, (D3DVIEWPORT8*)vp); +} -void d3d8_set_vertex_declaration(void *data, void *vertex_data); +static INLINE void d3d8_set_render_state( + LPDIRECT3DDEVICE8 dev, + D3DRENDERSTATETYPE state, + DWORD value) +{ + if (dev) + IDirect3DDevice8_SetRenderState(dev, state, value); +} -void d3d8_enable_alpha_blend_texture_func(void *data); +static INLINE void d3d8_enable_blend_func(void *data) +{ + if (!data) + return; + + d3d8_set_render_state(data, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + d3d8_set_render_state(data, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + d3d8_set_render_state(data, D3DRS_ALPHABLENDENABLE, true); +} + +static INLINE void d3d8_disable_blend_func(void *data) +{ + d3d8_set_render_state(data, D3DRS_ALPHABLENDENABLE, false); +} + +static INLINE void d3d8_enable_alpha_blend_texture_func(void *data) +{ + /* Also blend the texture with the set alpha value. */ + d3d8_set_texture_stage_state(data, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + d3d8_set_texture_stage_state(data, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + d3d8_set_texture_stage_state(data, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); +} void d3d8_frame_postprocess(void *data); -void d3d8_surface_free(void *data); +static INLINE void d3d8_surface_free(LPDIRECT3DSURFACE8 surf) +{ + if (surf) + IDirect3DSurface8_Release(surf); +} -bool d3d8_device_get_render_target_data(void *dev, - void *_src, void *_dst); +static INLINE bool d3d8_device_get_render_target( + LPDIRECT3DDEVICE8 dev, + unsigned idx, void **data) +{ + if (dev && + SUCCEEDED(IDirect3DDevice8_GetRenderTarget(dev, + (LPDIRECT3DSURFACE8*)data))) + return true; + return false; +} -bool d3d8_device_get_render_target(void *dev, - unsigned idx, void **data); +static INLINE void d3d8_device_set_render_target( + LPDIRECT3DDEVICE8 dev, unsigned idx, + LPDIRECT3DSURFACE8 surf) +{ + if (dev) + IDirect3DDevice8_SetRenderTarget(dev, surf, NULL); +} -void d3d8_device_set_render_target(void *dev, unsigned idx, - void *data); +static INLINE bool d3d8_get_render_state(LPDIRECT3DDEVICE8 dev, + D3DRENDERSTATETYPE state, DWORD *value) +{ + if (dev && + IDirect3DDevice8_GetRenderState(dev, state, value) == D3D_OK) + return true; + return false; +} -bool d3d8_get_render_state(void *data, - INT32 state, DWORD *value); +static INLINE bool d3d8_surface_lock_rect( + LPDIRECT3DSURFACE8 surf, void *data2) +{ + if (surf && + SUCCEEDED( + IDirect3DSurface8_LockRect( + surf, (D3DLOCKED_RECT*)data2, + NULL, D3DLOCK_READONLY))) + return true; + return false; +} -void d3d8_set_render_state(void *data, - INT32 state, DWORD value); +static INLINE void d3d8_surface_unlock_rect(LPDIRECT3DSURFACE8 surf) +{ + if (surf) + IDirect3DSurface8_UnlockRect(surf); +} -void d3d8_device_set_render_target(void *dev, unsigned idx, - void *data); - -bool d3d8_device_create_offscreen_plain_surface( - void *dev, - unsigned width, - unsigned height, - unsigned format, - unsigned pool, - void **surf_data, - void *data); - -bool d3d8_surface_lock_rect(void *data, void *data2); - -void d3d8_surface_unlock_rect(void *data); - -bool d3d8_get_adapter_display_mode(void *d3d, +static INLINE bool d3d8_get_adapter_display_mode( + LPDIRECT3D8 d3d, unsigned idx, - void *display_mode); + void *display_mode) +{ + if (d3d && + SUCCEEDED(IDirect3D8_GetAdapterDisplayMode( + d3d, idx, (D3DDISPLAYMODE*)display_mode))) + return true; + return false; +} bool d3d8_create_device(void *dev, void *d3dpp, - void *d3d, + LPDIRECT3D8 d3d, HWND focus_window, unsigned cur_mon_id); bool d3d8_reset(void *dev, void *d3dpp); -bool d3d8_device_get_backbuffer(void *dev, +static INLINE bool d3d8_device_get_backbuffer( + LPDIRECT3DDEVICE8 dev, unsigned idx, unsigned swapchain_idx, - unsigned backbuffer_type, void **data); + unsigned backbuffer_type, void **data) +{ + if (dev && + SUCCEEDED(IDirect3DDevice8_GetBackBuffer(dev, idx, + (D3DBACKBUFFER_TYPE)backbuffer_type, + (LPDIRECT3DSURFACE8*)data))) + return true; + return false; +} -void d3d8_device_free(void *dev, void *pd3d); +static INLINE void d3d8_device_free( + LPDIRECT3DDEVICE8 dev, LPDIRECT3D8 pd3d) +{ + if (dev) + IDirect3DDevice8_Release(dev); + if (pd3d) + IDirect3D8_Release(pd3d); +} void *d3d8_create(void); @@ -185,13 +463,25 @@ bool d3d8_initialize_symbols(enum gfx_ctx_api api); void d3d8_deinitialize_symbols(void); -bool d3d8_check_device_type(void *d3d, +static INLINE bool d3d8_check_device_type( + LPDIRECT3D8 d3d, unsigned idx, INT32 disp_format, INT32 backbuffer_format, - bool windowed_mode); + bool windowed_mode) +{ + if (d3d && + SUCCEEDED(IDirect3D8_CheckDeviceType(d3d, + 0, + D3DDEVTYPE_HAL, + disp_format, + backbuffer_format, + windowed_mode))) + return true; + return false; +} -bool d3d8x_create_font_indirect(void *dev, +bool d3d8x_create_font_indirect(LPDIRECT3DDEVICE8 dev, void *desc, void **font_data); void d3d8x_font_draw_text(void *data, void *sprite_data, void *string_data, @@ -201,11 +491,32 @@ void d3d8x_font_get_text_metrics(void *data, void *metrics); void d3d8x_font_release(void *data); -INT32 d3d8_translate_filter(unsigned type); +static INLINE INT32 d3d8_get_rgb565_format(void) +{ +#ifdef _XBOX + return D3DFMT_LIN_R5G6B5; +#else + return D3DFMT_R5G6B5; +#endif +} -INT32 d3d8_get_rgb565_format(void); -INT32 d3d8_get_argb8888_format(void); -INT32 d3d8_get_xrgb8888_format(void); +static INLINE INT32 d3d8_get_argb8888_format(void) +{ +#ifdef _XBOX + return D3DFMT_LIN_A8R8G8B8; +#else + return D3DFMT_A8R8G8B8; +#endif +} + +static INLINE INT32 d3d8_get_xrgb8888_format(void) +{ +#ifdef _XBOX + return D3DFMT_LIN_X8R8G8B8; +#else + return D3DFMT_X8R8G8B8; +#endif +} RETRO_END_DECLS diff --git a/gfx/common/d3d9_common.c b/gfx/common/d3d9_common.c index a6251e4b53..d71a4ceb18 100644 --- a/gfx/common/d3d9_common.c +++ b/gfx/common/d3d9_common.c @@ -13,6 +13,8 @@ * If not, see . */ +#define CINTERFACE + /* For Xbox we will just link statically * to Direct3D libraries instead. */ @@ -24,23 +26,15 @@ #include #endif -#include "../../configuration.h" #include "../../verbosity.h" -#include +#include "d3d9_common.h" #ifdef HAVE_D3DX -#ifdef _XBOX #include #include -#else -#include "../include/d3d9/d3dx9tex.h" #endif -#endif - -#include "d3d9_common.h" - #ifdef _XBOX #include #endif @@ -240,131 +234,6 @@ void d3d9_deinitialize_symbols(void) #endif } -bool d3d9_check_device_type(void *_d3d, - unsigned idx, - INT32 disp_format, - INT32 backbuffer_format, - bool windowed_mode) -{ - LPDIRECT3D9 d3d = (LPDIRECT3D9)_d3d; - if (!d3d) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (FAILED(d3d->CheckDeviceType( - 0, - D3DDEVTYPE_HAL, - (D3DFORMAT)disp_format, - (D3DFORMAT)backbuffer_format, - windowed_mode))) - return false; -#else - if (FAILED(IDirect3D9_CheckDeviceType(d3d, - 0, - D3DDEVTYPE_HAL, - (D3DFORMAT)disp_format, - (D3DFORMAT)backbuffer_format, - windowed_mode))) - return false; -#endif - - return true; -} - -bool d3d9_get_adapter_display_mode( - void *_d3d, - unsigned idx, - void *display_mode) -{ - LPDIRECT3D9 d3d = (LPDIRECT3D9)_d3d; - if (!d3d) - return false; -#ifdef _XBOX - return true; -#elif defined(__cplusplus) && !defined(CINTERFACE) - if (FAILED(d3d->GetAdapterDisplayMode(idx, (D3DDISPLAYMODE*)display_mode))) - return false; -#else - if (FAILED(IDirect3D9_GetAdapterDisplayMode(d3d, idx, (D3DDISPLAYMODE*)display_mode))) - return false; -#endif - - return true; -} - -bool d3d9_swap(void *data, void *_dev) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; -#if defined(__cplusplus) && !defined(CINTERFACE) -#ifdef _XBOX - dev->Present(NULL, NULL, NULL, NULL); -#else - if (dev->Present(NULL, NULL, NULL, NULL) != D3D_OK) - return false; -#endif -#else -#ifdef _XBOX - IDirect3DDevice9_Present(dev, NULL, NULL, NULL, NULL); -#else - if (IDirect3DDevice9_Present(dev, NULL, NULL, NULL, NULL) - == D3DERR_DEVICELOST) - return false; -#endif -#endif - return true; -} - -void d3d9_set_transform(void *_dev, - INT32 state, const void *_matrix) -{ -#ifndef _XBOX - CONST D3DMATRIX *matrix = (CONST D3DMATRIX*)_matrix; - /* XBox 360 D3D9 does not support fixed-function pipeline. */ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->SetTransform((D3DTRANSFORMSTATETYPE)state, matrix); -#else - IDirect3DDevice9_SetTransform(dev, (D3DTRANSFORMSTATETYPE)state, matrix); -#endif -#endif -} - -bool d3d9_texture_get_level_desc(void *_tex, - unsigned idx, void *_ppsurface_level) -{ - LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)_tex; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (SUCCEEDED(tex->GetLevelDesc(idx, (D3DSURFACE_DESC*)_ppsurface_level))) - return true; -#else -#if defined(_XBOX) - D3DTexture_GetLevelDesc(tex, idx, (D3DSURFACE_DESC*)_ppsurface_level); - return true; -#else - if (SUCCEEDED(IDirect3DTexture9_GetLevelDesc(tex, idx, (D3DSURFACE_DESC*)_ppsurface_level))) - return true; -#endif -#endif - - return false; -} - -bool d3d9_texture_get_surface_level(void *_tex, - unsigned idx, void **_ppsurface_level) -{ - LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)_tex; - if (!tex) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (SUCCEEDED(tex->GetSurfaceLevel(idx, (IDirect3DSurface9**)_ppsurface_level))) - return true; -#else - if (SUCCEEDED(IDirect3DTexture9_GetSurfaceLevel(tex, idx, (IDirect3DSurface9**)_ppsurface_level))) - return true; -#endif - - return false; -} - #ifdef HAVE_D3DX static void *d3d9_texture_new_from_file( void *dev, @@ -375,15 +244,12 @@ static void *d3d9_texture_new_from_file( PALETTEENTRY *palette) { void *buf = NULL; - HRESULT hr = D3D9CreateTextureFromFile((LPDIRECT3DDEVICE9)dev, - path, width, height, miplevels, usage, format, - (D3DPOOL)pool, filter, mipfilter, color_key, - (D3DXIMAGE_INFO*)src_info_data, - palette, (struct IDirect3DTexture9**)&buf); - - if (FAILED(hr)) + if (FAILED(D3D9CreateTextureFromFile((LPDIRECT3DDEVICE9)dev, + path, width, height, miplevels, usage, format, + (D3DPOOL)pool, filter, mipfilter, color_key, + (D3DXIMAGE_INFO*)src_info_data, + palette, (struct IDirect3DTexture9**)&buf))) return NULL; - return buf; } #endif @@ -395,7 +261,7 @@ void *d3d9_texture_new(void *_dev, INT32 color_key, void *src_info_data, PALETTEENTRY *palette, bool want_mipmap) { - HRESULT hr = S_OK; + LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; void *buf = NULL; if (path) @@ -411,189 +277,37 @@ void *d3d9_texture_new(void *_dev, #endif } - { - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; #ifndef _XBOX - if (want_mipmap) - usage |= D3DUSAGE_AUTOGENMIPMAP; + if (want_mipmap) + usage |= D3DUSAGE_AUTOGENMIPMAP; #endif -#if defined(__cplusplus) && !defined(CINTERFACE) - hr = dev->CreateTexture( - width, height, miplevels, usage, - (D3DFORMAT)format, - (D3DPOOL)pool, - (struct IDirect3DTexture9**)&buf, NULL); -#else - hr = IDirect3DDevice9_CreateTexture(dev, - width, height, miplevels, usage, - (D3DFORMAT)format, - (D3DPOOL)pool, - (struct IDirect3DTexture9**)&buf, NULL); -#endif - } - if (FAILED(hr)) + if (FAILED(IDirect3DDevice9_CreateTexture(dev, + width, height, miplevels, usage, + (D3DFORMAT)format, + (D3DPOOL)pool, + (struct IDirect3DTexture9**)&buf, NULL))) return NULL; - return buf; } -void d3d9_texture_free(void *_tex) -{ - LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)_tex; - if (!tex) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - tex->Release(); -#else - IDirect3DTexture9_Release(tex); -#endif -} - -bool d3d9_surface_lock_rect(void *data, void *data2) -{ - LPDIRECT3DSURFACE9 surf = (LPDIRECT3DSURFACE9)data; - if (!surf) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (FAILED(surf->LockRect((D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY))) - return false; -#else -#if defined(_XBOX) - IDirect3DSurface9_LockRect(surf, (D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY); -#else - if (FAILED(IDirect3DSurface9_LockRect(surf, (D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY))) - return false; -#endif -#endif - - return true; -} - -void d3d9_surface_unlock_rect(void *data) -{ - LPDIRECT3DSURFACE9 surf = (LPDIRECT3DSURFACE9)data; - if (!surf) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - surf->UnlockRect(); -#else - IDirect3DSurface9_UnlockRect(surf); -#endif -} - -void d3d9_surface_free(void *data) -{ - LPDIRECT3DSURFACE9 surf = (LPDIRECT3DSURFACE9)data; - if (!surf) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - surf->Release(); -#else - IDirect3DSurface9_Release(surf); -#endif -} - -void d3d9_vertex_declaration_free(void *data) -{ - if (!data) - return; - -#if defined(__cplusplus) && !defined(CINTERFACE) - { - LPDIRECT3DVERTEXDECLARATION9 vertex_decl = - (LPDIRECT3DVERTEXDECLARATION9)data; - if (vertex_decl) - vertex_decl->Release(); - } -#else - IDirect3DVertexDeclaration9_Release((LPDIRECT3DVERTEXDECLARATION9)data); -#endif -} - -bool d3d9_vertex_declaration_new(void *_dev, - const void *vertex_data, void **decl_data) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - const D3DVERTEXELEMENT9 *vertex_elements = (const D3DVERTEXELEMENT9*)vertex_data; - LPDIRECT3DVERTEXDECLARATION9 **vertex_decl = (LPDIRECT3DVERTEXDECLARATION9**)decl_data; - -#if defined(__cplusplus) && !defined(CINTERFACE) - if (SUCCEEDED(dev->CreateVertexDeclaration(vertex_elements, - (IDirect3DVertexDeclaration9**)vertex_decl))) - return true; -#else - if (SUCCEEDED(IDirect3DDevice9_CreateVertexDeclaration(dev, - vertex_elements, (IDirect3DVertexDeclaration9**)vertex_decl))) - return true; -#endif - - return false; -} - void *d3d9_vertex_buffer_new(void *_dev, unsigned length, unsigned usage, unsigned fvf, INT32 pool, void *handle) { - HRESULT hr = S_OK; void *buf = NULL; LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (usage == 0) - { #ifndef _XBOX -#if defined(__cplusplus) && !defined(CINTERFACE) - if (dev->GetSoftwareVertexProcessing()) - usage = D3DUSAGE_SOFTWAREPROCESSING; -#else + if (usage == 0) if (IDirect3DDevice9_GetSoftwareVertexProcessing(dev)) usage = D3DUSAGE_SOFTWAREPROCESSING; -#endif #endif - } -#if defined(__cplusplus) && !defined(CINTERFACE) - hr = dev->CreateVertexBuffer(length, usage, fvf, - (D3DPOOL)pool, - (LPDIRECT3DVERTEXBUFFER9*)&buf, NULL); -#else - hr = IDirect3DDevice9_CreateVertexBuffer(dev, length, usage, fvf, - (D3DPOOL)pool, - (LPDIRECT3DVERTEXBUFFER9*)&buf, NULL); -#endif - - if (FAILED(hr)) - return NULL; - - return buf; -} - -void d3d9_vertex_buffer_unlock(void *vertbuf_ptr) -{ - LPDIRECT3DVERTEXBUFFER9 vertbuf = (LPDIRECT3DVERTEXBUFFER9)vertbuf_ptr; - - if (!vertbuf) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - vertbuf->Unlock(); -#else - IDirect3DVertexBuffer9_Unlock(vertbuf); -#endif -} - -void *d3d9_vertex_buffer_lock(void *vertbuf_ptr) -{ - void *buf = NULL; - LPDIRECT3DVERTEXBUFFER9 vertbuf = (LPDIRECT3DVERTEXBUFFER9)vertbuf_ptr; - if (!vertbuf) - return NULL; -#if defined(__cplusplus) && !defined(CINTERFACE) - vertbuf->Lock(0, 0, &buf, 0); -#else - IDirect3DVertexBuffer9_Lock(vertbuf, 0, 0, &buf, 0); -#endif - - if (!buf) + if (FAILED(IDirect3DDevice9_CreateVertexBuffer( + dev, length, usage, fvf, + (D3DPOOL)pool, + (LPDIRECT3DVERTEXBUFFER9*)&buf, NULL))) return NULL; return buf; @@ -603,595 +317,41 @@ void d3d9_vertex_buffer_free(void *vertex_data, void *vertex_declaration) { if (vertex_data) { - LPDIRECT3DVERTEXBUFFER9 buf = (LPDIRECT3DVERTEXBUFFER9)vertex_data; -#if defined(__cplusplus) && !defined(CINTERFACE) - buf->Release(); -#else + LPDIRECT3DVERTEXBUFFER9 buf = + (LPDIRECT3DVERTEXBUFFER9)vertex_data; IDirect3DVertexBuffer9_Release(buf); -#endif buf = NULL; } if (vertex_declaration) { - LPDIRECT3DVERTEXDECLARATION9 vertex_decl = (LPDIRECT3DVERTEXDECLARATION9)vertex_declaration; + LPDIRECT3DVERTEXDECLARATION9 vertex_decl = + (LPDIRECT3DVERTEXDECLARATION9)vertex_declaration; d3d9_vertex_declaration_free(vertex_decl); vertex_decl = NULL; } } -void d3d9_set_stream_source(void *_dev, unsigned stream_no, - void *stream_vertbuf_ptr, unsigned offset_bytes, - unsigned stride) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - LPDIRECT3DVERTEXBUFFER9 stream_vertbuf = (LPDIRECT3DVERTEXBUFFER9)stream_vertbuf_ptr; - if (!stream_vertbuf) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->SetStreamSource(stream_no, stream_vertbuf, offset_bytes, stride); -#else - IDirect3DDevice9_SetStreamSource(dev, stream_no, stream_vertbuf, - offset_bytes, - stride); -#endif -} - -bool d3d9_device_create_offscreen_plain_surface( - void *_dev, - unsigned width, - unsigned height, - unsigned format, - unsigned pool, - void **surf_data, - void *data) -{ -#ifndef _XBOX - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (SUCCEEDED(dev->CreateOffscreenPlainSurface(width, height, - (D3DFORMAT)format, (D3DPOOL)pool, - (LPDIRECT3DSURFACE9*)surf_data, - (HANDLE*)data))) - return true; -#else - if (SUCCEEDED(IDirect3DDevice9_CreateOffscreenPlainSurface(dev, - width, height, - (D3DFORMAT)format, (D3DPOOL)pool, - (LPDIRECT3DSURFACE9*)surf_data, - (HANDLE*)data))) - return true; -#endif -#endif - - return false; -} - -static void d3d9_set_texture_stage_state(void *_dev, - unsigned sampler, unsigned type, unsigned value) -{ -#ifndef _XBOX - /* XBox 360 has no fixed-function pipeline. */ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (dev->SetTextureStageState(sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) - RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); -#else - if (IDirect3DDevice9_SetTextureStageState(dev, sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) - RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); -#endif -#endif -} - -void d3d9_set_sampler_address_u(void *_dev, - unsigned sampler, unsigned value) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->SetSamplerState(sampler, D3DSAMP_ADDRESSU, value); -#else - IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_ADDRESSU, value); -#endif -} - -void d3d9_set_sampler_address_v(void *_dev, - unsigned sampler, unsigned value) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->SetSamplerState(sampler, D3DSAMP_ADDRESSV, value); -#else - IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_ADDRESSV, value); -#endif -} - -void d3d9_set_sampler_minfilter(void *_dev, - unsigned sampler, unsigned value) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->SetSamplerState(sampler, D3DSAMP_MINFILTER, value); -#else - IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_MINFILTER, value); -#endif -} - -void d3d9_set_sampler_magfilter(void *_dev, - unsigned sampler, unsigned value) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->SetSamplerState(sampler, D3DSAMP_MAGFILTER, value); -#else - IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_MAGFILTER, value); -#endif -} - -void d3d9_set_sampler_mipfilter(void *_dev, - unsigned sampler, unsigned value) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return; - IDirect3DDevice9_SetSamplerState(dev, sampler, - D3DSAMP_MIPFILTER, value); -} - -bool d3d9_begin_scene(void *_dev) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (FAILED(dev->BeginScene())) - return false; -#else -#if defined(_XBOX) - IDirect3DDevice9_BeginScene(dev); -#else - if (FAILED(IDirect3DDevice9_BeginScene(dev))) - return false; -#endif -#endif - - return true; -} - -void d3d9_end_scene(void *_dev) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->EndScene(); -#else - IDirect3DDevice9_EndScene(dev); -#endif -} - -static void d3d9_draw_primitive_internal(void *_dev, - D3DPRIMITIVETYPE type, unsigned start, unsigned count) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->DrawPrimitive(type, start, count); -#else - IDirect3DDevice9_DrawPrimitive(dev, type, start, count); -#endif -} - -void d3d9_draw_primitive(void *dev, - INT32 type, unsigned start, unsigned count) -{ - if (!d3d9_begin_scene(dev)) - return; - - d3d9_draw_primitive_internal(dev, (D3DPRIMITIVETYPE)type, start, count); - d3d9_end_scene(dev); -} - -void d3d9_clear(void *_dev, - unsigned count, const void *rects, unsigned flags, - INT32 color, float z, unsigned stencil) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->Clear(count, (const D3DRECT*)rects, flags, color, z, stencil); -#else - IDirect3DDevice9_Clear(dev, count, (const D3DRECT*)rects, flags, - color, z, stencil); -#endif -} - -bool d3d9_device_get_render_target_data(void *_dev, - void *_src, void *_dst) -{ -#ifndef _XBOX - LPDIRECT3DSURFACE9 src = (LPDIRECT3DSURFACE9)_src; - LPDIRECT3DSURFACE9 dst = (LPDIRECT3DSURFACE9)_dst; - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (SUCCEEDED(dev->GetRenderTargetData(src, dst))) - return true; -#else - if (SUCCEEDED(IDirect3DDevice9_GetRenderTargetData( - dev, src, dst))) - return true; -#endif -#endif - - return false; -} - -bool d3d9_device_get_render_target(void *_dev, - unsigned idx, void **data) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (SUCCEEDED(dev->GetRenderTarget(idx, - (LPDIRECT3DSURFACE9*)data))) - return true; -#else - if (SUCCEEDED(IDirect3DDevice9_GetRenderTarget(dev, - idx, (LPDIRECT3DSURFACE9*)data))) - return true; -#endif - - return false; -} - - -bool d3d9_lock_rectangle(void *_tex, - unsigned level, void *_lr, RECT *rect, - unsigned rectangle_height, unsigned flags) -{ - D3DLOCKED_RECT *lr = (D3DLOCKED_RECT*)_lr; - LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)_tex; - if (!tex) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (FAILED(tex->LockRect(level, lr, rect, flags))) - return false; -#else -#ifdef _XBOX - IDirect3DTexture9_LockRect(tex, level, lr, (const RECT*)rect, flags); -#else - if (IDirect3DTexture9_LockRect(tex, level, lr, (const RECT*)rect, flags) != D3D_OK) - return false; -#endif -#endif - - return true; -} - -void d3d9_unlock_rectangle(void *_tex) -{ - LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)_tex; - if (!tex) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - tex->UnlockRect(0); -#else - IDirect3DTexture9_UnlockRect(tex, 0); -#endif -} - -void d3d9_lock_rectangle_clear(void *tex, - unsigned level, void *_lr, RECT *rect, - unsigned rectangle_height, unsigned flags) -{ - D3DLOCKED_RECT *lr = (D3DLOCKED_RECT*)_lr; -#if defined(_XBOX) - level = 0; -#endif - memset(lr->pBits, level, rectangle_height * lr->Pitch); - d3d9_unlock_rectangle(tex); -} - -void d3d9_set_viewports(void *_dev, void *_vp) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - D3DVIEWPORT9 *vp = (D3DVIEWPORT9*)_vp; - if (!dev) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->SetViewport(vp); -#else - IDirect3DDevice9_SetViewport(dev, vp); -#endif -} - -void d3d9_set_texture(void *_dev, unsigned sampler, - void *tex_data) -{ - LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)tex_data; - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev || !tex) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->SetTexture(sampler, tex); -#else - IDirect3DDevice9_SetTexture(dev, sampler, - (IDirect3DBaseTexture9*)tex); -#endif -} - -void d3d9_free_vertex_shader(void *_dev, void *data) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - IDirect3DVertexShader9 *vs = (IDirect3DVertexShader9*)data; - if (!dev || !vs) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - vs->Release(); -#else - IDirect3DVertexShader9_Release(vs); -#endif -} - -void d3d9_free_pixel_shader(void *_dev, void *data) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - IDirect3DPixelShader9 *ps = (IDirect3DPixelShader9*)data; - if (!dev || !ps) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - ps->Release(); -#else - IDirect3DPixelShader9_Release(ps); -#endif -} - -bool d3d9_create_vertex_shader(void *_dev, const DWORD *a, void **b) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return false; - -#if defined(__cplusplus) && !defined(CINTERFACE) - if (dev->CreateVertexShader(a, (IDirect3DVertexShader9**)b) == D3D_OK) - return true; -#else - if (IDirect3DDevice9_CreateVertexShader(dev, a, - (LPDIRECT3DVERTEXSHADER9*)b) == D3D_OK) - return true; -#endif - - return false; -} - -bool d3d9_create_pixel_shader(void *_dev, const DWORD *a, void **b) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return false; - -#if defined(__cplusplus) && !defined(CINTERFACE) - if (dev->CreatePixelShader(a, (IDirect3DPixelShader9**)b) == D3D_OK) - return true; -#else - if (IDirect3DDevice9_CreatePixelShader(dev, a, - (LPDIRECT3DPIXELSHADER9*)b) == D3D_OK) - return true; -#endif - - return false; -} - -bool d3d9_set_pixel_shader(void *_dev, void *data) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - LPDIRECT3DPIXELSHADER9 d3dps = (LPDIRECT3DPIXELSHADER9)data; - if (!dev || !d3dps) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (dev->SetPixelShader(d3dps) == D3D_OK) - return true; -#else -#ifdef _XBOX - /* Returns void on Xbox */ - IDirect3DDevice9_SetPixelShader(dev, d3dps); - return true; -#else - if (IDirect3DDevice9_SetPixelShader(dev, d3dps) == D3D_OK) - return true; -#endif -#endif - - return false; -} - -bool d3d9_set_vertex_shader(void *_dev, unsigned index, - void *data) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - LPDIRECT3DVERTEXSHADER9 shader = (LPDIRECT3DVERTEXSHADER9)data; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (dev->SetVertexShader(shader) != D3D_OK) - return false; -#else -#ifdef _XBOX - IDirect3DDevice9_SetVertexShader(dev, shader); -#else - if (IDirect3DDevice9_SetVertexShader(dev, shader) != D3D_OK) - return false; -#endif -#endif - - return true; -} - -bool d3d9_set_vertex_shader_constantf(void *_dev, - UINT start_register,const float* constant_data, - unsigned vector4f_count) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; -#if defined(__cplusplus) && !defined(CINTERFACE) -#ifdef _XBOX - dev->SetVertexShaderConstantF( - start_register, constant_data, vector4f_count); -#else - if (dev->SetVertexShaderConstantF( - start_register, constant_data, vector4f_count) == D3D_OK) - return true; -#endif -#else -#ifdef _XBOX - IDirect3DDevice9_SetVertexShaderConstantF(dev, - start_register, constant_data, vector4f_count); - return true; -#else - if (IDirect3DDevice9_SetVertexShaderConstantF(dev, - start_register, constant_data, vector4f_count) == D3D_OK) - return true; -#endif -#endif - - return false; -} - -void d3d9_texture_blit(unsigned pixel_size, - void *tex, - void *_lr, const void *frame, - unsigned width, unsigned height, unsigned pitch) -{ - unsigned y; - D3DLOCKED_RECT *lr = (D3DLOCKED_RECT*)_lr; - - for (y = 0; y < height; y++) - { - const uint8_t *in = (const uint8_t*)frame + y * pitch; - uint8_t *out = (uint8_t*)lr->pBits + y * lr->Pitch; - memcpy(out, in, width * pixel_size); - } -} - -bool d3d9_get_render_state(void *data, INT32 state, DWORD *value) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)data; - if (!dev) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (dev->GetRenderState((D3DRENDERSTATETYPE)state, value) == D3D_OK) - return true; -#else -#ifdef _XBOX - IDirect3DDevice9_GetRenderState(dev, (D3DRENDERSTATETYPE)state, value); - return true; -#else - if (IDirect3DDevice9_GetRenderState(dev, (D3DRENDERSTATETYPE)state, value) == D3D_OK) - return true; -#endif -#endif - - return false; -} - -void d3d9_set_render_state(void *data, INT32 state, DWORD value) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)data; - if (!dev) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->SetRenderState((D3DRENDERSTATETYPE)state, value); -#else - IDirect3DDevice9_SetRenderState(dev, (D3DRENDERSTATETYPE)state, value); -#endif -} - -void d3d9_enable_blend_func(void *data) -{ - if (!data) - return; - - d3d9_set_render_state(data, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - d3d9_set_render_state(data, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - d3d9_set_render_state(data, D3DRS_ALPHABLENDENABLE, true); -} - -void d3d9_device_set_render_target(void *_dev, unsigned idx, - void *data) -{ - LPDIRECT3DSURFACE9 surf = (LPDIRECT3DSURFACE9)data; - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->SetRenderTarget(idx, surf); -#else - IDirect3DDevice9_SetRenderTarget(dev, idx, surf); -#endif -} - -void d3d9_enable_alpha_blend_texture_func(void *data) -{ - /* Also blend the texture with the set alpha value. */ - d3d9_set_texture_stage_state(data, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - d3d9_set_texture_stage_state(data, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); - d3d9_set_texture_stage_state(data, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); -} - -void d3d9_disable_blend_func(void *data) -{ - d3d9_set_render_state(data, D3DRS_ALPHABLENDENABLE, false); -} - -void d3d9_set_vertex_declaration(void *data, void *vertex_data) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)data; - if (!dev) - return; -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->SetVertexDeclaration((LPDIRECT3DVERTEXDECLARATION9)vertex_data); -#else - IDirect3DDevice9_SetVertexDeclaration(dev, (LPDIRECT3DVERTEXDECLARATION9)vertex_data); -#endif -} - static bool d3d9_reset_internal(void *data, D3DPRESENT_PARAMETERS *d3dpp ) { LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)data; - if (!dev) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if ((dev->Reset(d3dpp) == D3D_OK)) + if (dev && + IDirect3DDevice9_Reset(dev, d3dpp) == D3D_OK) return true; -#else - if (IDirect3DDevice9_Reset(dev, d3dpp) == D3D_OK) - return true; -#endif return false; } static HRESULT d3d9_test_cooperative_level(void *data) { -#ifdef _XBOX - return E_FAIL; -#else +#ifndef _XBOX LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)data; - if (!dev) - return E_FAIL; -#if defined(__cplusplus) && !defined(CINTERFACE) - return dev->TestCooperativeLevel(); -#else - return IDirect3DDevice9_TestCooperativeLevel(dev); -#endif + if (dev) + return IDirect3DDevice9_TestCooperativeLevel(dev); #endif + return E_FAIL; } static bool d3d9_create_device_internal( @@ -1204,10 +364,8 @@ static bool d3d9_create_device_internal( { LPDIRECT3D9 d3d = (LPDIRECT3D9)_d3d; LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)data; - if (!dev) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (SUCCEEDED(d3d->CreateDevice( + if (dev && + SUCCEEDED(IDirect3D9_CreateDevice(d3d, cur_mon_id, D3DDEVTYPE_HAL, focus_window, @@ -1215,16 +373,6 @@ static bool d3d9_create_device_internal( d3dpp, (IDirect3DDevice9**)dev))) return true; -#else - if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, - cur_mon_id, - D3DDEVTYPE_HAL, - focus_window, - behavior_flags, - d3dpp, - (IDirect3DDevice9**)dev))) - return true; -#endif return false; } @@ -1284,112 +432,29 @@ bool d3d9_reset(void *dev, void *d3dpp) return false; } -bool d3d9_device_get_backbuffer(void *_dev, - unsigned idx, unsigned swapchain_idx, - unsigned backbuffer_type, void **data) -{ - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (!dev) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (SUCCEEDED(dev->GetBackBuffer( - swapchain_idx, idx, - (D3DBACKBUFFER_TYPE)backbuffer_type, - (LPDIRECT3DSURFACE9*)data))) - return true; -#else - if (SUCCEEDED(IDirect3DDevice9_GetBackBuffer(dev, - swapchain_idx, idx, - (D3DBACKBUFFER_TYPE)backbuffer_type, - (LPDIRECT3DSURFACE9*)data))) - return true; -#endif - - return false; -} - - -void d3d9_device_free(void *_dev, void *_pd3d) -{ - LPDIRECT3D9 pd3d = (LPDIRECT3D9)_pd3d; - LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; - if (dev) - { -#if defined(__cplusplus) && !defined(CINTERFACE) - dev->Release(); -#else - IDirect3DDevice9_Release(dev); -#endif - } - - if (pd3d) - { -#if defined(__cplusplus) && !defined(CINTERFACE) - pd3d->Release(); -#else - IDirect3D9_Release(pd3d); -#endif - } -} - -INT32 d3d9_translate_filter(unsigned type) -{ - switch (type) - { - case RARCH_FILTER_UNSPEC: - { - settings_t *settings = config_get_ptr(); - if (!settings->bools.video_smooth) - break; - } - /* fall-through */ - case RARCH_FILTER_LINEAR: - return D3DTEXF_LINEAR; - case RARCH_FILTER_NEAREST: - break; - } - - return D3DTEXF_POINT; -} - bool d3d9x_create_font_indirect(void *_dev, void *desc, void **font_data) { #ifdef HAVE_D3DX LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; -#ifdef __cplusplus if (SUCCEEDED(D3D9CreateFontIndirect( dev, (D3DXFONT_DESC*)desc, (struct ID3DXFont**)font_data))) return true; -#else - if (SUCCEEDED(D3D9CreateFontIndirect( - dev, (D3DXFONT_DESC*)desc, - (struct ID3DXFont**)font_data))) - return true; -#endif #endif return false; } -void d3dxbuffer_release(void *data) +void d3d9x_buffer_release(void *data) { #ifdef HAVE_D3DX -#ifdef __cplusplus - ID3DXBuffer *p = (ID3DXBuffer*)data; -#else LPD3DXBUFFER p = (LPD3DXBUFFER)data; -#endif if (!p) return; -#if defined(__cplusplus) && !defined(CINTERFACE) - p->Release(); -#else p->lpVtbl->Release(p); #endif -#endif } bool d3d9x_compile_shader( @@ -1426,55 +491,29 @@ void d3d9x_font_draw_text(void *data, void *sprite_data, void *string_data, unsigned count, void *rect_data, unsigned format, unsigned color) { #ifdef HAVE_D3DX -#if !defined(__cplusplus) || defined(CINTERFACE) ID3DXFont *font = (ID3DXFont*)data; - if (!font) - return; - font->lpVtbl->DrawText(font, (LPD3DXSPRITE)sprite_data, - (LPCTSTR)string_data, count, (LPRECT)rect_data, - (DWORD)format, (D3DCOLOR)color); -#else - LPD3DXFONT font = (LPD3DXFONT)data; - if (!font) - return; - font->DrawText((LPD3DXSPRITE)sprite_data, - (LPCTSTR)string_data, count, (LPRECT)rect_data, - (DWORD)format, (D3DCOLOR)color); -#endif + if (font) + font->lpVtbl->DrawText(font, (LPD3DXSPRITE)sprite_data, + (LPCTSTR)string_data, count, (LPRECT)rect_data, + (DWORD)format, (D3DCOLOR)color); #endif } void d3d9x_font_release(void *data) { #ifdef HAVE_D3DX -#if !defined(__cplusplus) || defined(CINTERFACE) ID3DXFont *font = (ID3DXFont*)data; - if (!font) - return; - font->lpVtbl->Release(font); -#else - LPD3DXFONT font = (LPD3DXFONT)data; - if (!font) - return; - font->Release(); -#endif + if (font) + font->lpVtbl->Release(font); #endif } void d3d9x_font_get_text_metrics(void *data, void *metrics) { #ifdef HAVE_D3DX -#if !defined(__cplusplus) || defined(CINTERFACE) ID3DXFont *font = (ID3DXFont*)data; - if (!font) - return; - font->lpVtbl->GetTextMetrics(font, (TEXTMETRICA*)metrics); -#else - LPD3DXFONT font = (LPD3DXFONT)data; - if (!font) - return; - font->GetTextMetricsA((TEXTMETRICA*)metrics); -#endif + if (font) + font->lpVtbl->GetTextMetrics(font, (TEXTMETRICA*)metrics); #endif } @@ -1506,66 +545,77 @@ bool d3d9x_compile_shader_from_file( return false; } -INT32 d3d9_get_rgb565_format(void) -{ -#ifdef _XBOX - return D3DFMT_LIN_R5G6B5; -#else - return D3DFMT_R5G6B5; -#endif -} - -INT32 d3d9_get_argb8888_format(void) -{ -#ifdef _XBOX - return D3DFMT_LIN_A8R8G8B8; -#else - return D3DFMT_A8R8G8B8; -#endif -} - -INT32 d3d9_get_xrgb8888_format(void) -{ -#ifdef _XBOX - return D3DFMT_LIN_X8R8G8B8; -#else - return D3DFMT_X8R8G8B8; -#endif -} - const void *d3d9x_get_buffer_ptr(void *data) { #if defined(HAVE_D3DX) ID3DXBuffer *listing = (ID3DXBuffer*)data; - if (!listing) - return NULL; -#if defined(__cplusplus) && !defined(CINTERFACE) - return listing->GetBufferPointer(); -#else - return listing->lpVtbl->GetBufferPointer(listing); + if (listing) + return listing->lpVtbl->GetBufferPointer(listing); #endif -#else return NULL; +} + +void *d3d9x_constant_table_get_constant_by_name(void *_tbl, + void *_handle, void *_name) +{ +#if defined(HAVE_D3DX) + D3DXHANDLE handle = (D3DXHANDLE)_handle; + LPD3DXCONSTANTTABLE consttbl = (LPD3DXCONSTANTTABLE)_tbl; + LPCSTR name = (LPCSTR)_name; + if (consttbl && handle && name) + return (void*)consttbl->lpVtbl->GetConstantByName(consttbl, + handle, name); +#endif + return NULL; +} + +void d3d9x_constant_table_set_float_array(LPDIRECT3DDEVICE9 dev, + void *p, void *_handle, const void *_pf, unsigned count) +{ +#if defined(HAVE_D3DX) + LPD3DXCONSTANTTABLE consttbl = (LPD3DXCONSTANTTABLE)p; + D3DXHANDLE handle = (D3DXHANDLE)_handle; + CONST FLOAT *pf = (CONST FLOAT*)_pf; + if (consttbl && dev) + consttbl->lpVtbl->SetFloatArray(consttbl, dev, handle, pf, + (UINT)count); +#endif +} + +void d3d9x_constant_table_set_defaults(LPDIRECT3DDEVICE9 dev, + void *p) +{ +#if defined(HAVE_D3DX) + LPD3DXCONSTANTTABLE consttbl = (LPD3DXCONSTANTTABLE)p; + if (consttbl && dev) + consttbl->lpVtbl->SetDefaults(consttbl, dev); +#endif +} + +void d3d9x_constant_table_set_matrix(LPDIRECT3DDEVICE9 dev, + void *p, + void *data, const void *_matrix) +{ +#if defined(HAVE_D3DX) + LPD3DXCONSTANTTABLE consttbl = (LPD3DXCONSTANTTABLE)p; + D3DXHANDLE handle = (D3DXHANDLE)data; + const D3DXMATRIX *matrix = (const D3DXMATRIX*)matrix; + if (consttbl && dev && handle) + consttbl->lpVtbl->SetMatrix(consttbl, dev, handle, matrix); #endif } const bool d3d9x_constant_table_set_float(void *p, - void *a, - const void *b, float val) + void *a, void *b, float val) { #if defined(HAVE_D3DX) LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)a; D3DXHANDLE handle = (D3DXHANDLE)b; LPD3DXCONSTANTTABLE consttbl = (LPD3DXCONSTANTTABLE)p; - if (!consttbl || !dev || !handle) - return false; -#if defined(__cplusplus) && !defined(CINTERFACE) - if (consttbl->SetFloat(dev, handle, val) == D3D_OK) + if (consttbl && dev && handle && + consttbl->lpVtbl->SetFloat( + consttbl, dev, handle, val) == D3D_OK) return true; -#else - if (consttbl->lpVtbl->SetFloat(consttbl, dev, handle, val) == D3D_OK) - return true; -#endif #endif return false; } diff --git a/gfx/common/d3d9_common.h b/gfx/common/d3d9_common.h index 008ae8cde3..cab78e1018 100644 --- a/gfx/common/d3d9_common.h +++ b/gfx/common/d3d9_common.h @@ -18,27 +18,122 @@ #include #include +#include +#include +#include + +#include "../drivers/d3d.h" #include "../video_driver.h" +#include "../../verbosity.h" RETRO_BEGIN_DECLS -bool d3d9_swap(void *data, void *dev); +typedef struct d3d9_video +{ + bool keep_aspect; + bool should_resize; + bool quitting; + bool needs_restore; + bool overlays_enabled; + /* TODO - refactor this away properly. */ + bool resolution_hd_enable; + + unsigned cur_mon_id; + unsigned dev_rotation; + + overlay_t *menu; + const d3d_renderchain_driver_t *renderchain_driver; + void *renderchain_data; + + RECT font_rect; + RECT font_rect_shifted; + math_matrix_4x4 mvp; + math_matrix_4x4 mvp_rotate; + math_matrix_4x4 mvp_transposed; + + struct video_viewport vp; + struct video_shader shader; + video_info_t video_info; + WNDCLASSEX windowClass; + LPDIRECT3DDEVICE9 dev; + d3d_video_viewport_t final_viewport; + + char *shader_path; + + struct + { + int size; + int offset; + void *buffer; + void *decl; + }menu_display; + + size_t overlays_size; + overlay_t *overlays; +} d3d9_video_t; + +static INLINE bool d3d9_swap(void *data, LPDIRECT3DDEVICE9 dev) +{ +#ifdef _XBOX + IDirect3DDevice9_Present(dev, NULL, NULL, NULL, NULL); +#else + if (IDirect3DDevice9_Present(dev, NULL, NULL, NULL, NULL) + == D3DERR_DEVICELOST) + return false; +#endif + return true; +} void *d3d9_vertex_buffer_new(void *dev, unsigned length, unsigned usage, unsigned fvf, INT32 pool, void *handle); -void *d3d9_vertex_buffer_lock(void *data); -void d3d9_vertex_buffer_unlock(void *data); +static INLINE void *d3d9_vertex_buffer_lock(LPDIRECT3DVERTEXBUFFER9 vertbuf) +{ + void *buf = NULL; + if (!vertbuf) + return NULL; + IDirect3DVertexBuffer9_Lock(vertbuf, 0, 0, &buf, 0); + + if (!buf) + return NULL; + + return buf; +} + +static INLINE void d3d9_vertex_buffer_unlock(LPDIRECT3DVERTEXBUFFER9 vertbuf) +{ + if (vertbuf) + IDirect3DVertexBuffer9_Unlock(vertbuf); +} void d3d9_vertex_buffer_free(void *vertex_data, void *vertex_declaration); -bool d3d9_texture_get_level_desc(void *tex, - unsigned idx, void *_ppsurface_level); +static INLINE bool d3d9_texture_get_level_desc( + LPDIRECT3DTEXTURE9 tex, + unsigned idx, + D3DSURFACE_DESC *_ppsurface_level) +{ +#if defined(_XBOX) + D3DTexture_GetLevelDesc(tex, idx, _ppsurface_level); +#else + if (FAILED(IDirect3DTexture9_GetLevelDesc(tex, idx, _ppsurface_level))) + return false; +#endif + return true; +} -bool d3d9_texture_get_surface_level(void *tex, - unsigned idx, void **_ppsurface_level); +static INLINE bool d3d9_texture_get_surface_level( + LPDIRECT3DTEXTURE9 tex, + unsigned idx, void **_ppsurface_level) +{ + if (tex && + SUCCEEDED(IDirect3DTexture9_GetSurfaceLevel( + tex, idx, (IDirect3DSurface9**)_ppsurface_level))) + return true; + return false; +} void *d3d9_texture_new(void *dev, const char *path, unsigned width, unsigned height, @@ -47,130 +142,474 @@ void *d3d9_texture_new(void *dev, INT32 color_key, void *src_info, PALETTEENTRY *palette, bool want_mipmap); -void d3d9_set_stream_source(void *dev, unsigned stream_no, - void *stream_vertbuf, unsigned offset_bytes, - unsigned stride); +static INLINE void d3d9_set_stream_source( + LPDIRECT3DDEVICE9 dev, + unsigned stream_no, + LPDIRECT3DVERTEXBUFFER9 stream_vertbuf, + unsigned offset_bytes, + unsigned stride) +{ + if (stream_vertbuf) + IDirect3DDevice9_SetStreamSource(dev, stream_no, stream_vertbuf, + offset_bytes, + stride); +} -void d3d9_texture_free(void *tex); +static INLINE void d3d9_texture_free(LPDIRECT3DTEXTURE9 tex) +{ + if (tex) + IDirect3DTexture9_Release(tex); +} -void d3d9_set_transform(void *dev, - INT32 state, const void *_matrix); +static INLINE void d3d9_set_transform( + LPDIRECT3DDEVICE9 dev, + D3DTRANSFORMSTATETYPE state, + const void *_matrix) +{ +#ifndef _XBOX + CONST D3DMATRIX *matrix = (CONST D3DMATRIX*)_matrix; + /* XBox 360 D3D9 does not support fixed-function pipeline. */ + IDirect3DDevice9_SetTransform(dev, state, matrix); +#endif +} -void d3d9_set_sampler_address_u(void *dev, - unsigned sampler, unsigned value); +static INLINE void d3d9_set_sampler_address_u( + LPDIRECT3DDEVICE9 dev, + unsigned sampler, unsigned value) +{ + IDirect3DDevice9_SetSamplerState(dev, + sampler, D3DSAMP_ADDRESSU, value); +} -void d3d9_set_sampler_address_v(void *dev, - unsigned sampler, unsigned value); +static INLINE void d3d9_set_sampler_address_v( + LPDIRECT3DDEVICE9 dev, + unsigned sampler, unsigned value) +{ + IDirect3DDevice9_SetSamplerState(dev, + sampler, D3DSAMP_ADDRESSV, value); +} -void d3d9_set_sampler_minfilter(void *dev, - unsigned sampler, unsigned value); +static INLINE void d3d9_set_sampler_minfilter( + LPDIRECT3DDEVICE9 dev, + unsigned sampler, unsigned value) +{ + if (dev) + IDirect3DDevice9_SetSamplerState(dev, + sampler, D3DSAMP_MINFILTER, value); +} -void d3d9_set_sampler_magfilter(void *dev, - unsigned sampler, unsigned value); +static INLINE void d3d9_set_sampler_magfilter( + LPDIRECT3DDEVICE9 dev, + unsigned sampler, unsigned value) +{ + if (dev) + IDirect3DDevice9_SetSamplerState(dev, + sampler, D3DSAMP_MAGFILTER, value); +} -void d3d9_set_sampler_mipfilter(void *dev, - unsigned sampler, unsigned value); +static INLINE void d3d9_set_sampler_mipfilter( + LPDIRECT3DDEVICE9 dev, + unsigned sampler, unsigned value) +{ + if (dev) + IDirect3DDevice9_SetSamplerState(dev, sampler, + D3DSAMP_MIPFILTER, value); +} -bool d3d9_begin_scene(void *dev); +static INLINE bool d3d9_begin_scene(LPDIRECT3DDEVICE9 dev) +{ + if (!dev) + return false; +#if defined(_XBOX) + IDirect3DDevice9_BeginScene(dev); +#else + if (FAILED(IDirect3DDevice9_BeginScene(dev))) + return false; +#endif -void d3d9_end_scene(void *dev); + return true; +} -void d3d9_draw_primitive(void *dev, - INT32 type, unsigned start, unsigned count); +static INLINE void d3d9_end_scene(LPDIRECT3DDEVICE9 dev) +{ + if (dev) + IDirect3DDevice9_EndScene(dev); +} -void d3d9_clear(void *dev, - unsigned count, const void *rects, unsigned flags, - INT32 color, float z, unsigned stencil); +static INLINE void d3d9_draw_primitive( + LPDIRECT3DDEVICE9 dev, + D3DPRIMITIVETYPE type, + unsigned start, unsigned count) +{ + if (!dev || !d3d9_begin_scene(dev)) + return; + IDirect3DDevice9_DrawPrimitive(dev, type, start, count); + d3d9_end_scene(dev); +} -bool d3d9_lock_rectangle(void *tex, - unsigned level, void *lock_rect, RECT *rect, - unsigned rectangle_height, unsigned flags); +static INLINE void d3d9_clear( + LPDIRECT3DDEVICE9 dev, + unsigned count, const D3DRECT *rects, unsigned flags, + INT32 color, float z, unsigned stencil) +{ + if (dev) + IDirect3DDevice9_Clear(dev, count, rects, flags, + color, z, stencil); +} -void d3d9_lock_rectangle_clear(void *tex, - unsigned level, void *lock_rect, RECT *rect, - unsigned rectangle_height, unsigned flags); +static INLINE bool d3d9_lock_rectangle( + LPDIRECT3DTEXTURE9 tex, + unsigned level, + D3DLOCKED_RECT *lr, + const RECT *rect, + unsigned rectangle_height, unsigned flags) +{ + if (!tex) + return false; +#ifdef _XBOX + IDirect3DTexture9_LockRect(tex, level, lr, rect, flags); +#else + if (IDirect3DTexture9_LockRect(tex, level, lr, rect, flags) != D3D_OK) + return false; +#endif -void d3d9_unlock_rectangle(void *tex); + return true; +} -void d3d9_set_texture(void *dev, unsigned sampler, - void *tex_data); +static INLINE void d3d9_unlock_rectangle(LPDIRECT3DTEXTURE9 tex) +{ + if (tex) + IDirect3DTexture9_UnlockRect(tex, 0); +} -bool d3d9_create_vertex_shader(void *dev, - const DWORD *a, void **b); +static INLINE void d3d9_lock_rectangle_clear(void *tex, + unsigned level, void *_lr, RECT *rect, + unsigned rectangle_height, unsigned flags) +{ + D3DLOCKED_RECT *lr = (D3DLOCKED_RECT*)_lr; +#if defined(_XBOX) + level = 0; +#endif + memset(lr->pBits, level, rectangle_height * lr->Pitch); + d3d9_unlock_rectangle((LPDIRECT3DTEXTURE9)tex); +} -bool d3d9_create_pixel_shader(void *dev, - const DWORD *a, void **b); +static INLINE void d3d9_set_texture( + LPDIRECT3DDEVICE9 dev, + unsigned sampler, + LPDIRECT3DTEXTURE9 tex) +{ + if (dev && tex) + IDirect3DDevice9_SetTexture(dev, sampler, + (IDirect3DBaseTexture9*)tex); +} -void d3d9_free_pixel_shader(void *dev, void *data); +static INLINE bool d3d9_create_vertex_shader( + LPDIRECT3DDEVICE9 dev, const DWORD *a, void **b) +{ + if (dev && IDirect3DDevice9_CreateVertexShader(dev, a, + (LPDIRECT3DVERTEXSHADER9*)b) == D3D_OK) + return true; + return false; +} -void d3d9_free_vertex_shader(void *dev, void *data); +static INLINE bool d3d9_create_pixel_shader( + LPDIRECT3DDEVICE9 dev, const DWORD *a, void **b) +{ + if (dev && + IDirect3DDevice9_CreatePixelShader(dev, a, + (LPDIRECT3DPIXELSHADER9*)b) == D3D_OK) + return true; + return false; +} -bool d3d9_set_pixel_shader(void *dev, void *data); +static INLINE void d3d9_free_vertex_shader( + LPDIRECT3DDEVICE9 dev, IDirect3DVertexShader9 *vs) +{ + if (dev && vs) + IDirect3DVertexShader9_Release(vs); +} -bool d3d9_set_vertex_shader(void *dev, unsigned index, - void *data); +static INLINE void d3d9_free_pixel_shader(LPDIRECT3DDEVICE9 dev, + IDirect3DPixelShader9 *ps) +{ + if (dev && ps) + IDirect3DPixelShader9_Release(ps); +} -bool d3d9_set_vertex_shader_constantf(void *dev, - UINT start_register,const float* constant_data, unsigned vector4f_count); +static INLINE bool d3d9_set_pixel_shader( + LPDIRECT3DDEVICE9 dev, + LPDIRECT3DPIXELSHADER9 d3dps) +{ + if (!dev || !d3dps) + return false; -void d3d9_texture_blit(unsigned pixel_size, +#ifdef _XBOX + /* Returns void on Xbox */ + IDirect3DDevice9_SetPixelShader(dev, d3dps); +#else + if (IDirect3DDevice9_SetPixelShader(dev, d3dps) != D3D_OK) + return false; +#endif + return true; +} + +static INLINE bool d3d9_set_vertex_shader( + LPDIRECT3DDEVICE9 dev, unsigned index, + LPDIRECT3DVERTEXSHADER9 shader) +{ +#ifdef _XBOX + IDirect3DDevice9_SetVertexShader(dev, shader); +#else + if (IDirect3DDevice9_SetVertexShader(dev, shader) != D3D_OK) + return false; +#endif + + return true; +} + +static INLINE bool d3d9_set_vertex_shader_constantf( + LPDIRECT3DDEVICE9 dev, + UINT start_register, + const float* constant_data, + unsigned vector4f_count) +{ +#ifdef _XBOX + IDirect3DDevice9_SetVertexShaderConstantF(dev, + start_register, constant_data, vector4f_count); +#else + if (IDirect3DDevice9_SetVertexShaderConstantF(dev, + start_register, constant_data, vector4f_count) != D3D_OK) + return false; +#endif + + return true; +} + +static INLINE void d3d9_texture_blit( + unsigned pixel_size, void *tex, - void *lr, const void *frame, - unsigned width, unsigned height, unsigned pitch); + D3DLOCKED_RECT *lr, const void *frame, + unsigned width, unsigned height, unsigned pitch) +{ + unsigned y; -bool d3d9_vertex_declaration_new(void *dev, - const void *vertex_data, void **decl_data); + for (y = 0; y < height; y++) + { + const uint8_t *in = (const uint8_t*)frame + y * pitch; + uint8_t *out = (uint8_t*)lr->pBits + y * lr->Pitch; + memcpy(out, in, width * pixel_size); + } +} -void d3d9_vertex_declaration_free(void *data); +static INLINE bool d3d9_vertex_declaration_new( + LPDIRECT3DDEVICE9 dev, + const void *vertex_data, void **decl_data) +{ + const D3DVERTEXELEMENT9 *vertex_elements = (const D3DVERTEXELEMENT9*)vertex_data; + LPDIRECT3DVERTEXDECLARATION9 **vertex_decl = (LPDIRECT3DVERTEXDECLARATION9**)decl_data; -void d3d9_set_viewports(void *dev, void *vp); + if (SUCCEEDED(IDirect3DDevice9_CreateVertexDeclaration(dev, + vertex_elements, (IDirect3DVertexDeclaration9**)vertex_decl))) + return true; -void d3d9_enable_blend_func(void *data); + return false; +} -void d3d9_disable_blend_func(void *data); +static INLINE void d3d9_vertex_declaration_free( + LPDIRECT3DVERTEXDECLARATION9 decl) +{ + if (decl) + IDirect3DVertexDeclaration9_Release(decl); +} -void d3d9_set_vertex_declaration(void *data, void *vertex_data); +static INLINE void d3d9_set_viewports(LPDIRECT3DDEVICE9 dev, + void *vp) +{ + if (dev) + IDirect3DDevice9_SetViewport(dev, (D3DVIEWPORT9*)vp); +} -void d3d9_enable_alpha_blend_texture_func(void *data); +static INLINE void d3d9_set_render_state( + LPDIRECT3DDEVICE9 dev, D3DRENDERSTATETYPE state, DWORD value) +{ + IDirect3DDevice9_SetRenderState(dev, state, value); +} + +static INLINE void d3d9_enable_blend_func(LPDIRECT3DDEVICE9 dev) +{ + if (!dev) + return; + + d3d9_set_render_state(dev, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + d3d9_set_render_state(dev, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + d3d9_set_render_state(dev, D3DRS_ALPHABLENDENABLE, true); +} + +static INLINE void d3d9_disable_blend_func(LPDIRECT3DDEVICE9 dev) +{ + if (dev) + d3d9_set_render_state(dev, D3DRS_ALPHABLENDENABLE, false); +} + +static INLINE void +d3d9_set_vertex_declaration(LPDIRECT3DDEVICE9 dev, + LPDIRECT3DVERTEXDECLARATION9 vertex_data) +{ + if (dev) + IDirect3DDevice9_SetVertexDeclaration(dev, vertex_data); +} + +static INLINE void d3d9_set_texture_stage_state( + LPDIRECT3DDEVICE9 dev, + unsigned sampler, + D3DTEXTURESTAGESTATETYPE type, + unsigned value) +{ +#ifndef _XBOX + /* XBox 360 has no fixed-function pipeline. */ + if (IDirect3DDevice9_SetTextureStageState(dev, sampler, + type, value) != D3D_OK) + RARCH_ERR("SetTextureStageState call failed, sampler" + ": %d, value: %d, type: %d\n", sampler, value, type); +#endif +} + +static INLINE void d3d9_enable_alpha_blend_texture_func(LPDIRECT3DDEVICE9 dev) +{ + if (!dev) + return; + + /* Also blend the texture with the set alpha value. */ + d3d9_set_texture_stage_state(dev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + d3d9_set_texture_stage_state(dev, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + d3d9_set_texture_stage_state(dev, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); +} void d3d9_frame_postprocess(void *data); -void d3d9_surface_free(void *data); +static INLINE void d3d9_surface_free(LPDIRECT3DSURFACE9 surf) +{ + if (surf) + IDirect3DSurface9_Release(surf); +} -bool d3d9_device_get_render_target_data(void *dev, - void *_src, void *_dst); +static INLINE bool d3d9_device_get_render_target_data( + void *_dev, + void *_src, void *_dst) +{ +#ifndef _XBOX + LPDIRECT3DSURFACE9 src = (LPDIRECT3DSURFACE9)_src; + LPDIRECT3DSURFACE9 dst = (LPDIRECT3DSURFACE9)_dst; + LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; + if (dev && + SUCCEEDED(IDirect3DDevice9_GetRenderTargetData( + dev, src, dst))) + return true; +#endif -bool d3d9_device_get_render_target(void *dev, - unsigned idx, void **data); + return false; +} -void d3d9_device_set_render_target(void *dev, unsigned idx, - void *data); +static INLINE bool d3d9_device_get_render_target( + LPDIRECT3DDEVICE9 dev, + unsigned idx, void **data) +{ + if (dev && + SUCCEEDED(IDirect3DDevice9_GetRenderTarget(dev, + idx, (LPDIRECT3DSURFACE9*)data))) + return true; + return false; +} -bool d3d9_get_render_state(void *data, - INT32 state, DWORD *value); +static INLINE void d3d9_device_set_render_target( + void *_dev, unsigned idx, + void *data) +{ + LPDIRECT3DSURFACE9 surf = (LPDIRECT3DSURFACE9)data; + LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; + if (dev) + IDirect3DDevice9_SetRenderTarget(dev, idx, surf); +} -void d3d9_set_render_state(void *data, - INT32 state, DWORD value); +static INLINE bool d3d9_get_render_state( + void *data, INT32 state, DWORD *value) +{ + LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)data; + if (!dev) + return false; -void d3d9_device_set_render_target(void *dev, unsigned idx, - void *data); +#ifdef _XBOX + IDirect3DDevice9_GetRenderState(dev, + (D3DRENDERSTATETYPE)state, value); +#else + if (IDirect3DDevice9_GetRenderState(dev, + (D3DRENDERSTATETYPE)state, value) != D3D_OK) + return false; +#endif + return true; +} -bool d3d9_device_create_offscreen_plain_surface( - void *dev, +static INLINE bool d3d9_device_create_offscreen_plain_surface( + void *_dev, unsigned width, unsigned height, unsigned format, unsigned pool, void **surf_data, - void *data); + void *data) +{ +#ifndef _XBOX + LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; + if (SUCCEEDED(IDirect3DDevice9_CreateOffscreenPlainSurface(dev, + width, height, + (D3DFORMAT)format, (D3DPOOL)pool, + (LPDIRECT3DSURFACE9*)surf_data, + (HANDLE*)data))) + return true; +#endif + return false; +} -bool d3d9_surface_lock_rect(void *data, void *data2); +static INLINE bool d3d9_surface_lock_rect(LPDIRECT3DSURFACE9 surf, + D3DLOCKED_RECT *data2) +{ + if (!surf) + return false; +#if defined(_XBOX) + IDirect3DSurface9_LockRect(surf, + data2, NULL, D3DLOCK_READONLY); +#else + if (FAILED(IDirect3DSurface9_LockRect(surf, + data2, NULL, D3DLOCK_READONLY))) + return false; +#endif -void d3d9_surface_unlock_rect(void *data); + return true; +} -bool d3d9_get_adapter_display_mode(void *d3d, +static INLINE void d3d9_surface_unlock_rect(LPDIRECT3DSURFACE9 surf) +{ + if (surf) + IDirect3DSurface9_UnlockRect(surf); +} + +static INLINE bool d3d9_get_adapter_display_mode( + LPDIRECT3D9 d3d, unsigned idx, - void *display_mode); + void *display_mode) +{ + if (!d3d) + return false; +#ifndef _XBOX + if (FAILED( + IDirect3D9_GetAdapterDisplayMode( + d3d, idx, (D3DDISPLAYMODE*)display_mode))) + return false; +#endif + + return true; +} bool d3d9_create_device(void *dev, void *d3dpp, @@ -180,11 +619,29 @@ bool d3d9_create_device(void *dev, bool d3d9_reset(void *dev, void *d3dpp); -bool d3d9_device_get_backbuffer(void *dev, +static INLINE bool d3d9_device_get_backbuffer( + LPDIRECT3DDEVICE9 dev, unsigned idx, unsigned swapchain_idx, - unsigned backbuffer_type, void **data); + unsigned backbuffer_type, void **data) +{ + if (dev && + SUCCEEDED(IDirect3DDevice9_GetBackBuffer(dev, + swapchain_idx, idx, + (D3DBACKBUFFER_TYPE)backbuffer_type, + (LPDIRECT3DSURFACE9*)data))) + return true; + return false; +} -void d3d9_device_free(void *dev, void *pd3d); +static INLINE void d3d9_device_free(void *_dev, void *_pd3d) +{ + LPDIRECT3D9 pd3d = (LPDIRECT3D9)_pd3d; + LPDIRECT3DDEVICE9 dev = (LPDIRECT3DDEVICE9)_dev; + if (dev) + IDirect3DDevice9_Release(dev); + if (pd3d) + IDirect3D9_Release(pd3d); +} void *d3d9_create(void); @@ -192,11 +649,23 @@ bool d3d9_initialize_symbols(enum gfx_ctx_api api); void d3d9_deinitialize_symbols(void); -bool d3d9_check_device_type(void *d3d, +static INLINE bool d3d9_check_device_type( + LPDIRECT3D9 d3d, unsigned idx, INT32 disp_format, INT32 backbuffer_format, - bool windowed_mode); + bool windowed_mode) +{ + if (d3d && + SUCCEEDED(IDirect3D9_CheckDeviceType(d3d, + 0, + D3DDEVTYPE_HAL, + (D3DFORMAT)disp_format, + (D3DFORMAT)backbuffer_format, + windowed_mode))) + return true; + return false; +} bool d3d9x_create_font_indirect(void *dev, void *desc, void **font_data); @@ -206,12 +675,10 @@ void d3d9x_font_draw_text(void *data, void *sprite_data, void *string_data, void d3d9x_font_get_text_metrics(void *data, void *metrics); -void d3dxbuffer_release(void *data); +void d3d9x_buffer_release(void *data); void d3d9x_font_release(void *data); -INT32 d3d9_translate_filter(unsigned type); - bool d3d9x_compile_shader( const char *src, unsigned src_data_len, @@ -235,14 +702,49 @@ bool d3d9x_compile_shader_from_file( void *pperrormsgs, void *ppconstanttable); +void d3d9x_constant_table_set_float_array(LPDIRECT3DDEVICE9 dev, + void *p, void *_handle, const void *_pf, unsigned count); + +void d3d9x_constant_table_set_defaults(LPDIRECT3DDEVICE9 dev, + void *p); + +void d3d9x_constant_table_set_matrix(LPDIRECT3DDEVICE9 dev, + void *p, void *data, const void *matrix); + const void *d3d9x_get_buffer_ptr(void *data); const bool d3d9x_constant_table_set_float(void *p, - void *a, const void *b, float val); + void *a, void *b, float val); -INT32 d3d9_get_rgb565_format(void); -INT32 d3d9_get_argb8888_format(void); -INT32 d3d9_get_xrgb8888_format(void); +void *d3d9x_constant_table_get_constant_by_name(void *_tbl, + void *_handle, void *_name); + +static INLINE INT32 d3d9_get_rgb565_format(void) +{ +#ifdef _XBOX + return D3DFMT_LIN_R5G6B5; +#else + return D3DFMT_R5G6B5; +#endif +} + +static INLINE INT32 d3d9_get_argb8888_format(void) +{ +#ifdef _XBOX + return D3DFMT_LIN_A8R8G8B8; +#else + return D3DFMT_A8R8G8B8; +#endif +} + +static INLINE INT32 d3d9_get_xrgb8888_format(void) +{ +#ifdef _XBOX + return D3DFMT_LIN_X8R8G8B8; +#else + return D3DFMT_X8R8G8B8; +#endif +} RETRO_END_DECLS diff --git a/gfx/common/d3d_common.c b/gfx/common/d3d_common.c index 1908181945..020f20d681 100644 --- a/gfx/common/d3d_common.c +++ b/gfx/common/d3d_common.c @@ -86,7 +86,8 @@ void *d3d_matrix_identity(void *_pout) return pout; } -void *d3d_matrix_ortho_off_center_lh(void *_pout, float l, float r, float b, float t, float zn, float zf) +void *d3d_matrix_ortho_off_center_lh(void *_pout, + float l, float r, float b, float t, float zn, float zf) { D3DMATRIX *pout = (D3DMATRIX*)_pout; @@ -101,7 +102,8 @@ void *d3d_matrix_ortho_off_center_lh(void *_pout, float l, float r, float b, flo return pout; } -void *d3d_matrix_multiply(void *_pout, const void *_pm1, const void *_pm2) +void *d3d_matrix_multiply(void *_pout, + const void *_pm1, const void *_pm2) { unsigned i,j; D3DMATRIX *pout = (D3DMATRIX*)_pout; @@ -127,3 +129,23 @@ void *d3d_matrix_rotation_z(void *_pout, float angle) pout->m[1][0] = -sin(angle); return pout; } + +int32_t d3d_translate_filter(unsigned type) +{ + switch (type) + { + case RARCH_FILTER_UNSPEC: + { + settings_t *settings = config_get_ptr(); + if (!settings->bools.video_smooth) + break; + } + /* fall-through */ + case RARCH_FILTER_LINEAR: + return (int32_t)D3DTEXF_LINEAR; + case RARCH_FILTER_NEAREST: + break; + } + + return (int32_t)D3DTEXF_POINT; +} diff --git a/gfx/common/d3d_common.h b/gfx/common/d3d_common.h index 083cfd7fa1..b951881ae2 100644 --- a/gfx/common/d3d_common.h +++ b/gfx/common/d3d_common.h @@ -33,248 +33,26 @@ typedef struct d3d_texture #define BYTE_CLAMP(i) (int) ((((i) > 255) ? 255 : (((i) < 0) ? 0 : (i)))) #endif -#ifndef D3DCOLOR_ARGB -#define D3DCOLOR_ARGB(_a, _r, _g, _b) ( (DWORD)( ( ( (_a)&0xff)<<24)|( ( (_r)&0xff)<<16)|( ( (_g)&0xff)<<8)|( (_b)&0xff) ) ) -#endif - #define D3DTADDRESS_COMM_CLAMP 3 #define D3DTEXF_COMM_LINEAR 2 #define D3DPT_COMM_TRIANGLESTRIP 5 -#define D3D_COMM_CLEAR_TARGET 0x00000001l /* Clear target surface */ - -bool d3d_swap(void *data, void *dev); - -void *d3d_vertex_buffer_new(void *dev, - unsigned length, unsigned usage, unsigned fvf, - INT32 pool, void *handle); - -void *d3d_vertex_buffer_lock(void *data); -void d3d_vertex_buffer_unlock(void *data); - -void d3d_vertex_buffer_free(void *vertex_data, void *vertex_declaration); - -bool d3d_texture_get_level_desc(void *tex, - unsigned idx, void *_ppsurface_level); - -bool d3d_texture_get_surface_level(void *tex, - unsigned idx, void **_ppsurface_level); - -void *d3d_texture_new(void *dev, - const char *path, unsigned width, unsigned height, - unsigned miplevels, unsigned usage, INT32 format, - INT32 pool, unsigned filter, unsigned mipfilter, - INT32 color_key, void *src_info, - PALETTEENTRY *palette, bool want_mipmap); - -void d3d_set_stream_source(void *dev, unsigned stream_no, - void *stream_vertbuf, unsigned offset_bytes, - unsigned stride); - -void d3d_texture_free(void *tex); - -void d3d_set_transform(void *dev, - INT32 state, const void *_matrix); - -void d3d_set_sampler_address_u(void *dev, - unsigned sampler, unsigned value); - -void d3d_set_sampler_address_v(void *dev, - unsigned sampler, unsigned value); - -void d3d_set_sampler_minfilter(void *dev, - unsigned sampler, unsigned value); - -void d3d_set_sampler_magfilter(void *dev, - unsigned sampler, unsigned value); - -void d3d_set_sampler_mipfilter(void *dev, - unsigned sampler, unsigned value); - -bool d3d_begin_scene(void *dev); - -void d3d_end_scene(void *dev); - -void d3d_draw_primitive(void *dev, - INT32 type, unsigned start, unsigned count); - -void d3d_clear(void *dev, - unsigned count, const void *rects, unsigned flags, - INT32 color, float z, unsigned stencil); - -bool d3d_lock_rectangle(void *tex, - unsigned level, void *lock_rect, RECT *rect, - unsigned rectangle_height, unsigned flags); - -void d3d_lock_rectangle_clear(void *tex, - unsigned level, void *lock_rect, RECT *rect, - unsigned rectangle_height, unsigned flags); - -void d3d_unlock_rectangle(void *tex); - -void d3d_set_texture(void *dev, unsigned sampler, - void *tex_data); - -bool d3d_create_vertex_shader(void *dev, - const DWORD *a, void **b); - -bool d3d_create_pixel_shader(void *dev, - const DWORD *a, void **b); - -void d3d_free_pixel_shader(void *dev, void *data); - -void d3d_free_vertex_shader(void *dev, void *data); - -bool d3d_set_pixel_shader(void *dev, void *data); - -bool d3d_set_vertex_shader(void *dev, unsigned index, - void *data); - -bool d3d_set_vertex_shader_constantf(void *dev, - UINT start_register,const float* constant_data, unsigned vector4f_count); - -void d3d_texture_blit(unsigned pixel_size, - void *tex, - void *lr, const void *frame, - unsigned width, unsigned height, unsigned pitch); - -bool d3d_vertex_declaration_new(void *dev, - const void *vertex_data, void **decl_data); - -void d3d_vertex_declaration_free(void *data); - -void d3d_set_viewports(void *dev, void *vp); - -void d3d_enable_blend_func(void *data); - -void d3d_disable_blend_func(void *data); - -void d3d_set_vertex_declaration(void *data, void *vertex_data); - -void d3d_enable_alpha_blend_texture_func(void *data); - -void d3d_frame_postprocess(void *data); - -void d3d_surface_free(void *data); - -bool d3d_device_get_render_target_data(void *dev, - void *_src, void *_dst); - -bool d3d_device_get_render_target(void *dev, - unsigned idx, void **data); - -void d3d_device_set_render_target(void *dev, unsigned idx, - void *data); - -bool d3d_get_render_state(void *data, - INT32 state, DWORD *value); - -void d3d_set_render_state(void *data, - INT32 state, DWORD value); - -void d3d_device_set_render_target(void *dev, unsigned idx, - void *data); - -bool d3d_device_create_offscreen_plain_surface( - void *dev, - unsigned width, - unsigned height, - unsigned format, - unsigned pool, - void **surf_data, - void *data); - -bool d3d_surface_lock_rect(void *data, void *data2); - -void d3d_surface_unlock_rect(void *data); +/* Clear target surface */ +#define D3D_COMM_CLEAR_TARGET 0x00000001l void *d3d_matrix_transpose(void *_pout, const void *_pm); -void *d3d_matrix_multiply(void *_pout, - const void *_pm1, const void *_pm2); +void *d3d_matrix_identity(void *_pout); void *d3d_matrix_ortho_off_center_lh(void *_pout, float l, float r, float b, float t, float zn, float zf); -void * d3d_matrix_identity(void *_pout); +void *d3d_matrix_multiply(void *_pout, + const void *_pm1, const void *_pm2); void *d3d_matrix_rotation_z(void *_pout, float angle); -bool d3d_get_adapter_display_mode(void *d3d, - unsigned idx, - void *display_mode); - -bool d3d_create_device(void *dev, - void *d3dpp, - void *d3d, - HWND focus_window, - unsigned cur_mon_id); - -bool d3d_reset(void *dev, void *d3dpp); - -bool d3d_device_get_backbuffer(void *dev, - unsigned idx, unsigned swapchain_idx, - unsigned backbuffer_type, void **data); - -void d3d_device_free(void *dev, void *pd3d); - -void *d3d_create(void); - -bool d3d_initialize_symbols(enum gfx_ctx_api api); - -void d3d_deinitialize_symbols(void); - -bool d3d_check_device_type(void *d3d, - unsigned idx, - INT32 disp_format, - INT32 backbuffer_format, - bool windowed_mode); - -bool d3dx_create_font_indirect(void *dev, - void *desc, void **font_data); - -void d3dx_font_draw_text(void *data, void *sprite_data, void *string_data, - unsigned count, void *rect_data, unsigned format, unsigned color); - -void d3dx_font_get_text_metrics(void *data, void *metrics); - -void d3dxbuffer_release(void *data); - -void d3dx_font_release(void *data); - -INT32 d3d_translate_filter(unsigned type); - -bool d3dx_compile_shader( - const char *src, - unsigned src_data_len, - const void *pdefines, - void *pinclude, - const char *pfunctionname, - const char *pprofile, - unsigned flags, - void *ppshader, - void *pperrormsgs, - void *ppconstanttable); - -bool d3dx_compile_shader_from_file( - const char *src, - const void *pdefines, - void *pinclude, - const char *pfunctionname, - const char *pprofile, - unsigned flags, - void *ppshader, - void *pperrormsgs, - void *ppconstanttable); - -const void *d3dx_get_buffer_ptr(void *data); - -const bool d3dx_constant_table_set_float(void *p, - void *a, const void *b, float val); - -INT32 d3d_get_rgb565_format(void); -INT32 d3d_get_argb8888_format(void); -INT32 d3d_get_xrgb8888_format(void); +int32_t d3d_translate_filter(unsigned type); RETRO_END_DECLS diff --git a/gfx/common/drm_common.c b/gfx/common/drm_common.c index 33052c83e1..577d2f09a5 100644 --- a/gfx/common/drm_common.c +++ b/gfx/common/drm_common.c @@ -168,6 +168,18 @@ void drm_setup(int fd) RARCH_WARN("[DRM]: Cannot find original CRTC.\n"); } +float drm_get_refresh_rate(void *data) +{ + float refresh_rate = 0.0f; + + if (g_drm_mode) + { + refresh_rate = g_drm_mode->clock * 1000.0f / g_drm_mode->htotal / g_drm_mode->vtotal; + } + + return refresh_rate; +} + void drm_free(void) { if (g_drm_encoder) diff --git a/gfx/common/drm_common.h b/gfx/common/drm_common.h index 87458dac9a..e8cb3ac411 100644 --- a/gfx/common/drm_common.h +++ b/gfx/common/drm_common.h @@ -55,6 +55,8 @@ void drm_free(void); bool drm_get_connector(int fd, video_frame_info_t *video_info); +float drm_get_refresh_rate(void *data); + static INLINE bool drm_wait_flip(int timeout) { g_drm_fds.revents = 0; diff --git a/gfx/common/dxgi_common.h b/gfx/common/dxgi_common.h index a35090dfb5..32af9b89b2 100644 --- a/gfx/common/dxgi_common.h +++ b/gfx/common/dxgi_common.h @@ -767,7 +767,7 @@ static INLINE HRESULT DXGICreateFactory(DXGIFactory* factory) #define DXGI_COLOR_RGBA(r, g, b, a) (((UINT32)(a) << 24) | ((UINT32)(b) << 16) | ((UINT32)(g) << 8) | ((UINT32)(r) << 0)) typedef enum { - DXGI_FORMAT_EX_A4R4G4B4_UNORM = 1000, + DXGI_FORMAT_EX_A4R4G4B4_UNORM = 1000 } DXGI_FORMAT_EX; typedef struct diff --git a/gfx/common/gx2_common.h b/gfx/common/gx2_common.h index 3ab9d9eefe..3b424f4b44 100644 --- a/gfx/common/gx2_common.h +++ b/gfx/common/gx2_common.h @@ -2,11 +2,13 @@ #include -#include "gfx/drivers/gx2_shaders/frame.h" -#include "gfx/drivers/gx2_shaders/tex.h" -#include "gfx/drivers/gx2_shaders/sprite.h" -#include "gfx/drivers/gx2_shaders/menu_shaders.h" -#include "gfx/video_shader_parse.h" +#include "../video_defines.h" +#include "../video_shader_parse.h" + +#include "../drivers/gx2_shaders/frame.h" +#include "../drivers/gx2_shaders/tex.h" +#include "../drivers/gx2_shaders/sprite.h" +#include "../drivers/gx2_shaders/menu_shaders.h" #undef _X #undef _B @@ -23,7 +25,6 @@ #define _1 0x05 #define GX2_COMP_SEL(c0, c1, c2, c3) (((c0) << 24) | ((c1) << 16) | ((c2) << 8) | (c3)) -#define COLOR_ABGR(r, g, b, a) (((u32)(a) << 24) | ((u32)(b) << 16) | ((u32)(g) << 8) | ((u32)(r) << 0)) #define COLOR_ARGB(r, g, b, a) (((u32)(a) << 24) | ((u32)(r) << 16) | ((u32)(g) << 8) | ((u32)(b) << 0)) #define COLOR_RGBA(r, g, b, a) (((u32)(r) << 24) | ((u32)(g) << 16) | ((u32)(b) << 8) | ((u32)(a) << 0)) diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index 5ea05e04da..c1231e780b 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -962,6 +962,34 @@ void vulkan_image_layout_transition( 1, &barrier); } +void vulkan_image_layout_transition_levels( + VkCommandBuffer cmd, VkImage image, uint32_t levels, + VkImageLayout old_layout, VkImageLayout new_layout, + VkAccessFlags src_access, VkAccessFlags dst_access, + VkPipelineStageFlags src_stages, VkPipelineStageFlags dst_stages) +{ + VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; + + barrier.srcAccessMask = src_access; + barrier.dstAccessMask = dst_access; + barrier.oldLayout = old_layout; + barrier.newLayout = new_layout; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = image; + barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barrier.subresourceRange.levelCount = levels; + barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + + vkCmdPipelineBarrier(cmd, + src_stages, + dst_stages, + false, + 0, NULL, + 0, NULL, + 1, &barrier); +} + struct vk_buffer vulkan_create_buffer( const struct vulkan_context *context, size_t size, VkBufferUsageFlags usage) diff --git a/gfx/common/vulkan_common.h b/gfx/common/vulkan_common.h index e4714142ef..d154d77ac7 100644 --- a/gfx/common/vulkan_common.h +++ b/gfx/common/vulkan_common.h @@ -446,6 +446,12 @@ void vulkan_image_layout_transition(vk_t *vk, VkAccessFlags srcAccess, VkAccessFlags dstAccess, VkPipelineStageFlags srcStages, VkPipelineStageFlags dstStages); +void vulkan_image_layout_transition_levels( + VkCommandBuffer cmd, VkImage image, uint32_t levels, + VkImageLayout old_layout, VkImageLayout new_layout, + VkAccessFlags src_access, VkAccessFlags dst_access, + VkPipelineStageFlags src_stages, VkPipelineStageFlags dst_stages); + static INLINE unsigned vulkan_format_to_bpp(VkFormat format) { switch (format) diff --git a/gfx/common/win32_common.c b/gfx/common/win32_common.c index 6a1af71c1f..39bd8bbdf6 100644 --- a/gfx/common/win32_common.c +++ b/gfx/common/win32_common.c @@ -13,6 +13,22 @@ * If not, see . */ +#if !defined(_XBOX) + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0601 /* Windows 7 */ +#endif + +#if !defined(_MSC_VER) || _WIN32_WINNT >= 0x0601 +#undef WINVER +#define WINVER 0x0601 +#endif + +#define IDI_ICON 1 + +#include +#endif /* !defined(_XBOX) */ + #include #include @@ -33,13 +49,6 @@ #if !defined(_XBOX) -#define IDI_ICON 1 - -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 /* _WIN32_WINNT_WIN2K */ -#endif - -#include #include #include #include "../../retroarch.h" @@ -83,18 +92,192 @@ extern void *dinput_wgl; extern void *dinput; #endif -unsigned g_resize_width = 0; -unsigned g_resize_height = 0; +typedef enum { + DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED_CUSTOM = 0, + DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE_CUSTOM = 1, + DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_CUSTOM = 2, + DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST_CUSTOM = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_CUSTOM, + DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST_CUSTOM = 3, + DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32_CUSTOM = 0xFFFFFFFF +} DISPLAYCONFIG_SCANLINE_ORDERING_CUSTOM; + +typedef enum { + DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE_CUSTOM = 1, + DISPLAYCONFIG_MODE_INFO_TYPE_TARGET_CUSTOM = 2, + DISPLAYCONFIG_MODE_INFO_TYPE_DESKTOP_IMAGE_CUSTOM = 3, + DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32_CUSTOM = 0xFFFFFFFF +} DISPLAYCONFIG_MODE_INFO_TYPE_CUSTOM; + +typedef enum { + DISPLAYCONFIG_PIXELFORMAT_8BPP_CUSTOM = 1, + DISPLAYCONFIG_PIXELFORMAT_16BPP_CUSTOM = 2, + DISPLAYCONFIG_PIXELFORMAT_24BPP_CUSTOM = 3, + DISPLAYCONFIG_PIXELFORMAT_32BPP_CUSTOM = 4, + DISPLAYCONFIG_PIXELFORMAT_NONGDI_CUSTOM = 5, + DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32_CUSTOM = 0xffffffff +} DISPLAYCONFIG_PIXELFORMAT_CUSTOM; + +typedef enum { + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER_CUSTOM = -1, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15_CUSTOM = 0, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO_CUSTOM = 1, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO_CUSTOM = 2, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO_CUSTOM = 3, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI_CUSTOM = 4, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI_CUSTOM = 5, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS_CUSTOM = 6, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN_CUSTOM = 8, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI_CUSTOM = 9, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL_CUSTOM = 10, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED_CUSTOM = 11, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL_CUSTOM = 12, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED_CUSTOM = 13, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE_CUSTOM = 14, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_MIRACAST_CUSTOM = 15, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL_CUSTOM = 0x80000000, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32_CUSTOM = 0xFFFFFFFF +} DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY_CUSTOM; + +typedef enum { + DISPLAYCONFIG_ROTATION_IDENTITY_CUSTOM = 1, + DISPLAYCONFIG_ROTATION_ROTATE90_CUSTOM = 2, + DISPLAYCONFIG_ROTATION_ROTATE180_CUSTOM = 3, + DISPLAYCONFIG_ROTATION_ROTATE270_CUSTOM = 4, + DISPLAYCONFIG_ROTATION_FORCE_UINT32_CUSTOM = 0xFFFFFFFF +} DISPLAYCONFIG_ROTATION_CUSTOM; + +typedef enum { + DISPLAYCONFIG_SCALING_IDENTITY_CUSTOM = 1, + DISPLAYCONFIG_SCALING_CENTERED_CUSTOM = 2, + DISPLAYCONFIG_SCALING_STRETCHED_CUSTOM = 3, + DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX_CUSTOM = 4, + DISPLAYCONFIG_SCALING_CUSTOM_CUSTOM = 5, + DISPLAYCONFIG_SCALING_PREFERRED_CUSTOM = 128, + DISPLAYCONFIG_SCALING_FORCE_UINT32_CUSTOM = 0xFFFFFFFF +} DISPLAYCONFIG_SCALING_CUST; + +typedef enum { + DISPLAYCONFIG_TOPOLOGY_INTERNAL_CUSTOM = 0x00000001, + DISPLAYCONFIG_TOPOLOGY_CLONE_CUSTOM = 0x00000002, + DISPLAYCONFIG_TOPOLOGY_EXTEND_CUSTOM = 0x00000004, + DISPLAYCONFIG_TOPOLOGY_EXTERNAL_CUSTOM = 0x00000008, + DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32_CUSTOM = 0xFFFFFFFF +} DISPLAYCONFIG_TOPOLOGY_ID_CUSTOM; + +typedef struct DISPLAYCONFIG_RATIONAL_CUSTOM { + UINT32 Numerator; + UINT32 Denominator; +} DISPLAYCONFIG_RATIONAL_CUSTOM; + +typedef struct DISPLAYCONFIG_2DREGION_CUSTOM { + UINT32 cx; + UINT32 cy; +} DISPLAYCONFIG_2DREGION_CUSTOM; + +typedef struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO_CUSTOM { + UINT64 pixelRate; + DISPLAYCONFIG_RATIONAL_CUSTOM hSyncFreq; + DISPLAYCONFIG_RATIONAL_CUSTOM vSyncFreq; + DISPLAYCONFIG_2DREGION_CUSTOM activeSize; + DISPLAYCONFIG_2DREGION_CUSTOM totalSize; + union { + struct { + UINT32 videoStandard :16; + UINT32 vSyncFreqDivider :6; + UINT32 reserved :10; + } AdditionalSignalInfo; + UINT32 videoStandard; + }; + DISPLAYCONFIG_SCANLINE_ORDERING_CUSTOM scanLineOrdering; +} DISPLAYCONFIG_VIDEO_SIGNAL_INFO_CUSTOM; + +typedef struct DISPLAYCONFIG_TARGET_MODE_CUSTOM { + DISPLAYCONFIG_VIDEO_SIGNAL_INFO_CUSTOM targetVideoSignalInfo; +} DISPLAYCONFIG_TARGET_MODE_CUSTOM; + +typedef struct DISPLAYCONFIG_PATH_SOURCE_INFO_CUSTOM { + LUID adapterId; + UINT32 id; + union { + UINT32 modeInfoIdx; + struct { + UINT32 cloneGroupId :16; + UINT32 sourceModeInfoIdx :16; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + UINT32 statusFlags; +} DISPLAYCONFIG_PATH_SOURCE_INFO_CUSTOM; + +typedef struct DISPLAYCONFIG_DESKTOP_IMAGE_INFO_CUSTOM { + POINTL PathSourceSize; + RECTL DesktopImageRegion; + RECTL DesktopImageClip; +} DISPLAYCONFIG_DESKTOP_IMAGE_INFO_CUSTOM; + +typedef struct DISPLAYCONFIG_SOURCE_MODE_CUSTOM { + UINT32 width; + UINT32 height; + DISPLAYCONFIG_PIXELFORMAT_CUSTOM pixelFormat; + POINTL position; +} DISPLAYCONFIG_SOURCE_MODE_CUSTOM; + +typedef struct DISPLAYCONFIG_MODE_INFO_CUSTOM { + DISPLAYCONFIG_MODE_INFO_TYPE_CUSTOM infoType; + UINT32 id; + LUID adapterId; + union { + DISPLAYCONFIG_TARGET_MODE_CUSTOM targetMode; + DISPLAYCONFIG_SOURCE_MODE_CUSTOM sourceMode; + DISPLAYCONFIG_DESKTOP_IMAGE_INFO_CUSTOM desktopImageInfo; + }; +} DISPLAYCONFIG_MODE_INFO_CUSTOM; + +typedef struct DISPLAYCONFIG_PATH_TARGET_INFO_CUSTOM { + LUID adapterId; + UINT32 id; + union { + UINT32 modeInfoIdx; + struct { + UINT32 desktopModeInfoIdx :16; + UINT32 targetModeInfoIdx :16; + }; + }; + DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY_CUSTOM outputTechnology; + DISPLAYCONFIG_ROTATION_CUSTOM rotation; + DISPLAYCONFIG_SCALING_CUST scaling; + DISPLAYCONFIG_RATIONAL_CUSTOM refreshRate; + DISPLAYCONFIG_SCANLINE_ORDERING_CUSTOM scanLineOrdering; + BOOL targetAvailable; + UINT32 statusFlags; +} DISPLAYCONFIG_PATH_TARGET_INFO_CUSTOM; + + + +typedef struct DISPLAYCONFIG_PATH_INFO_CUSTOM { + DISPLAYCONFIG_PATH_SOURCE_INFO_CUSTOM sourceInfo; + DISPLAYCONFIG_PATH_TARGET_INFO_CUSTOM targetInfo; + UINT32 flags; +} DISPLAYCONFIG_PATH_INFO_CUSTOM; + +typedef LONG (WINAPI *QUERYDISPLAYCONFIG)(UINT32, UINT32*, DISPLAYCONFIG_PATH_INFO_CUSTOM*, UINT32*, DISPLAYCONFIG_MODE_INFO_CUSTOM*, DISPLAYCONFIG_TOPOLOGY_ID_CUSTOM*); +typedef LONG (WINAPI *GETDISPLAYCONFIGBUFFERSIZES)(UINT32, UINT32*, UINT32*); + static bool g_resized = false; bool g_restore_desktop = false; static bool doubleclick_on_titlebar = false; +static bool g_taskbar_is_created = false; bool g_inited = false; static bool g_quit = false; + static int g_pos_x = CW_USEDEFAULT; static int g_pos_y = CW_USEDEFAULT; -static void *curD3D = NULL; -static bool g_taskbar_is_created = false; + +unsigned g_resize_width = 0; +unsigned g_resize_height = 0; static unsigned g_taskbar_message = 0; +static unsigned win32_monitor_count = 0; + +static void *curD3D = NULL; ui_window_win32_t main_window; @@ -147,7 +330,6 @@ typedef REASON_CONTEXT POWER_REQUEST_CONTEXT, *PPOWER_REQUEST_CONTEXT, *LPPOWER_ static HMONITOR win32_monitor_last; static HMONITOR win32_monitor_all[MAX_MONITORS]; -static unsigned win32_monitor_count = 0; bool win32_taskbar_is_created(void) { @@ -256,6 +438,19 @@ void win32_monitor_from_window(void) #endif } +int win32_change_display_settings(const char *str, void *devmode_data, + unsigned flags) +{ +#if _WIN32_WINDOWS >= 0x0410 || _WIN32_WINNT >= 0x0410 + /* Windows 98 and later codepath */ + return ChangeDisplaySettingsEx(str, (DEVMODE*)devmode_data, + NULL, flags, NULL); +#else + /* Windows 95 / NT codepath */ + return ChangeDisplaySettings((DEVMODE*)devmode_data, flags); +#endif +} + void win32_monitor_get_info(void) { MONITORINFOEX current_mon; @@ -265,13 +460,7 @@ void win32_monitor_get_info(void) GetMonitorInfo(win32_monitor_last, (LPMONITORINFO)¤t_mon); -#if _WIN32_WINDOWS >= 0x0410 || _WIN32_WINNT >= 0x0410 - /* Windows 98 and later codepath */ - ChangeDisplaySettingsEx(current_mon.szDevice, NULL, NULL, 0, NULL); -#else - /* Windows 95 / NT codepath */ - ChangeDisplaySettings(NULL, 0); -#endif + win32_change_display_settings(current_mon.szDevice, NULL, 0); } void win32_monitor_info(void *data, void *hm_data, unsigned *mon_id) @@ -373,10 +562,10 @@ static int win32_drag_query_file(HWND hwnd, WPARAM wparam) { const core_info_t *info = (const core_info_t*)&core_info[i]; - if(!string_is_equal(info->systemname, current_core->systemname)) + if (!string_is_equal(info->systemname, current_core->systemname)) break; - if(string_is_equal(path_get(RARCH_PATH_CORE), info->path)) + if (string_is_equal(path_get(RARCH_PATH_CORE), info->path)) { /* Our previous core supports the current rom */ content_ctx_info_t content_info = {0}; @@ -391,29 +580,22 @@ static int win32_drag_query_file(HWND hwnd, WPARAM wparam) } /* Poll for cores for current rom since none exist. */ - if(list_size ==1) + if (list_size ==1) { /*pick core that only exists and is bound to work. Ish. */ const core_info_t *info = (const core_info_t*)&core_info[0]; if (info) task_push_load_content_with_new_core_from_companion_ui( - info->path, NULL, - &content_info, - NULL, NULL); + info->path, NULL, &content_info, NULL, NULL); } else { /* Pick one core that could be compatible, ew */ - if(DialogBoxParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_PICKCORE), + if (DialogBoxParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_PICKCORE), hwnd,PickCoreProc,(LPARAM)NULL)==IDOK) - { task_push_load_content_with_current_core_from_companion_ui( - NULL, - &content_info, - CORE_TYPE_PLAIN, - NULL, NULL); - } + NULL, &content_info, CORE_TYPE_PLAIN, NULL, NULL); } } @@ -422,11 +604,9 @@ static int win32_drag_query_file(HWND hwnd, WPARAM wparam) #ifndef _XBOX static LRESULT win32_handle_keyboard_event(HWND hwnd, UINT message, - WPARAM wparam, LPARAM lparam) + WPARAM wparam, LPARAM lparam) { - unsigned keycode; - uint16_t mod = 0; - bool keydown = true; + uint16_t mod = 0; if (GetKeyState(VK_SHIFT) & 0x80) mod |= RETROKMOD_SHIFT; @@ -447,7 +627,7 @@ static LRESULT win32_handle_keyboard_event(HWND hwnd, UINT message, * WM_CHAR and WM_KEYDOWN properly. */ case WM_CHAR: - input_keyboard_event(keydown, RETROK_UNKNOWN, wparam, mod, + input_keyboard_event(true, RETROK_UNKNOWN, wparam, mod, RETRO_DEVICE_KEYBOARD); return TRUE; @@ -455,34 +635,35 @@ static LRESULT win32_handle_keyboard_event(HWND hwnd, UINT message, case WM_SYSKEYUP: case WM_KEYDOWN: case WM_SYSKEYDOWN: - /* Key released? */ - if (message == WM_KEYUP || message == WM_SYSKEYUP) - keydown = false; - -#if _WIN32_WINNT >= 0x0501 /* XP */ - if (string_is_equal(config_get_ptr()->arrays.input_driver, "raw")) - keycode = input_keymaps_translate_keysym_to_rk((unsigned)(wparam)); - else -#endif - keycode = input_keymaps_translate_keysym_to_rk((lparam >> 16) & 0xff); - - input_keyboard_event(keydown, keycode, 0, mod, RETRO_DEVICE_KEYBOARD); - - if (message == WM_SYSKEYDOWN) { - switch (wparam) - { - case VK_F10: - case VK_MENU: - case VK_RSHIFT: - return 0; - default: - break; - } - } - else - return 0; + unsigned keycode = 0; + bool keydown = true; + unsigned keysym = (lparam >> 16) & 0xff; +#if _WIN32_WINNT >= 0x0501 /* XP */ + settings_t *settings = config_get_ptr(); + if (settings && string_is_equal(settings->arrays.input_driver, "raw")) + keysym = (unsigned)wparam; +#endif + /* Key released? */ + if (message == WM_KEYUP || message == WM_SYSKEYUP) + keydown = false; + + keycode = input_keymaps_translate_keysym_to_rk(keysym); + + input_keyboard_event(keydown, keycode, + 0, mod, RETRO_DEVICE_KEYBOARD); + + if (message != WM_SYSKEYDOWN) + return 0; + + if ( + wparam == VK_F10 || + wparam == VK_MENU || + wparam == VK_RSHIFT + ) + return 0; + } break; } @@ -542,7 +723,8 @@ static LRESULT CALLBACK WndProcCommon(bool *quit, HWND hwnd, UINT message, break; case WM_SIZE: /* Do not send resize message if we minimize. */ - if (wparam != SIZE_MAXHIDE && wparam != SIZE_MINIMIZED) + if ( wparam != SIZE_MAXHIDE && + wparam != SIZE_MINIMIZED) { g_resize_width = LOWORD(lparam); g_resize_height = HIWORD(lparam); @@ -806,7 +988,7 @@ bool win32_window_create(void *data, unsigned style, notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; notification_filter.dbcc_classguid = GUID_DEVINTERFACE_HID; notification_handler = RegisterDeviceNotification( - main_window.hwnd, ¬ification_filter, DEVICE_NOTIFY_WINDOW_HANDLE); + main_window.hwnd, ¬ification_filter, DEVICE_NOTIFY_WINDOW_HANDLE); if (!notification_handler) RARCH_ERR("Error registering for notifications\n"); @@ -838,9 +1020,7 @@ bool win32_window_create(void *data, unsigned style, bool win32_get_metrics(void *data, enum display_metric_types type, float *value) { -#ifdef _XBOX - return false; -#else +#ifndef _XBOX HDC monitor = GetDC(NULL); int pixels_x = GetDeviceCaps(monitor, HORZRES); int pixels_y = GetDeviceCaps(monitor, VERTRES); @@ -853,22 +1033,22 @@ bool win32_get_metrics(void *data, { case DISPLAY_METRIC_MM_WIDTH: *value = physical_width; - break; + return true; case DISPLAY_METRIC_MM_HEIGHT: *value = physical_height; - break; + return true; case DISPLAY_METRIC_DPI: /* 25.4 mm in an inch. */ *value = 254 * pixels_x / physical_width / 10; - break; + return true; case DISPLAY_METRIC_NONE: default: *value = 0; - return false; + break; } - - return true; #endif + + return false; } void win32_monitor_init(void) @@ -900,14 +1080,8 @@ static bool win32_monitor_set_fullscreen( RARCH_LOG("Setting fullscreen to %ux%u @ %uHz on device %s.\n", width, height, refresh, dev_name); -#if _WIN32_WINDOWS >= 0x0410 || _WIN32_WINNT >= 0x0410 - /* Windows 98 and later codepath */ - return ChangeDisplaySettingsEx(dev_name, &devmode, - NULL, CDS_FULLSCREEN, NULL) == DISP_CHANGE_SUCCESSFUL; -#else - /* Windows 95 / NT codepath */ - return ChangeDisplaySettings(&devmode, CDS_FULLSCREEN); -#endif + return win32_change_display_settings(dev_name, &devmode, + CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL; #endif } @@ -944,10 +1118,11 @@ void win32_check_window(bool *quit, bool *resize, bool win32_suppress_screensaver(void *data, bool enable) { #ifndef _XBOX - if(enable) + if (enable) { - int major, minor; char tmp[PATH_MAX_LENGTH]; + int major = 0; + int minor = 0; const frontend_ctx_driver_t *frontend = frontend_get_ptr(); if (!frontend) @@ -969,16 +1144,20 @@ bool win32_suppress_screensaver(void *data, bool enable) PowerSetRequestPtr powerSetRequest = (PowerSetRequestPtr)GetProcAddress(kernel32, "PowerSetRequest"); - if(powerCreateRequest && powerSetRequest) + if (powerCreateRequest && powerSetRequest) { POWER_REQUEST_CONTEXT RequestContext; HANDLE Request; - RequestContext.Version = POWER_REQUEST_CONTEXT_VERSION; - RequestContext.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING; - RequestContext.Reason.SimpleReasonString = (LPWSTR)L"RetroArch running"; + RequestContext.Version = + POWER_REQUEST_CONTEXT_VERSION; + RequestContext.Flags = + POWER_REQUEST_CONTEXT_SIMPLE_STRING; + RequestContext.Reason.SimpleReasonString = (LPWSTR) + L"RetroArch running"; - Request = powerCreateRequest(&RequestContext); + Request = + powerCreateRequest(&RequestContext); powerSetRequest( Request, PowerRequestDisplayRequired); return true; @@ -1020,7 +1199,7 @@ void win32_set_style(MONITORINFOEX *current_mon, HMONITOR *hm_to_use, float refresh_mod = settings->bools.video_black_frame_insertion ? 2.0f : 1.0f; unsigned refresh = roundf(settings->floats.video_refresh_rate * refresh_mod * settings->uints.video_swap_interval); - + if (windowed_full) { *style = WS_EX_TOPMOST | WS_POPUP; @@ -1032,8 +1211,7 @@ void win32_set_style(MONITORINFOEX *current_mon, HMONITOR *hm_to_use, *style = WS_POPUP | WS_VISIBLE; if (!win32_monitor_set_fullscreen(*width, *height, - refresh, current_mon->szDevice)) - {} + refresh, current_mon->szDevice)) { } /* Display settings might have changed, get new coordinates. */ GetMonitorInfo(*hm_to_use, (LPMONITORINFO)current_mon); @@ -1141,11 +1319,9 @@ bool win32_set_video_mode(void *data, RARCH_ERR("GetMessage error code %d\n", GetLastError()); break; } - else - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } + + TranslateMessage(&msg); + DispatchMessage(&msg); } if (g_quit) @@ -1237,7 +1413,7 @@ void win32_get_video_output_prev( EnumDisplaySettings(NULL, i, &dm) != 0; i++) { - if ( dm.dmPelsWidth == curr_width + if ( dm.dmPelsWidth == curr_width && dm.dmPelsHeight == curr_height) { if ( prev_width != curr_width @@ -1259,6 +1435,70 @@ void win32_get_video_output_prev( } } +float win32_get_refresh_rate(void *data) +{ + float refresh_rate = 0.0f; +#if _WIN32_WINNT >= 0x0601 || _WIN32_WINDOWS >= 0x0601 /* Win 7 */ + OSVERSIONINFO version_info; + DISPLAYCONFIG_TOPOLOGY_ID_CUSTOM TopologyID; + unsigned int NumPathArrayElements = 0; + unsigned int NumModeInfoArrayElements = 0; + DISPLAYCONFIG_PATH_INFO_CUSTOM *PathInfoArray = NULL; + DISPLAYCONFIG_MODE_INFO_CUSTOM *ModeInfoArray = NULL; + int result = 0; +#ifdef HAVE_DYNAMIC + static QUERYDISPLAYCONFIG pQueryDisplayConfig; + static GETDISPLAYCONFIGBUFFERSIZES pGetDisplayConfigBufferSizes; + if (!pQueryDisplayConfig) + pQueryDisplayConfig = (QUERYDISPLAYCONFIG)GetProcAddress(GetModuleHandle("user32.dll"), "QueryDisplayConfig"); + + if (!pGetDisplayConfigBufferSizes) + pGetDisplayConfigBufferSizes = (GETDISPLAYCONFIGBUFFERSIZES)GetProcAddress(GetModuleHandle("user32.dll"), "GetDisplayConfigBufferSizes"); +#else + static QUERYDISPLAYCONFIG pQueryDisplayConfig = QueryDisplayConfig; + static GETDISPLAYCONFIGBUFFERSIZES pGetDisplayConfigBufferSizes = GetDisplayConfigBufferSizes; +#endif + + version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (!GetVersionEx(&version_info)) + return refresh_rate; + + if (version_info.dwMajorVersion < 6 || + (version_info.dwMajorVersion == 6 && version_info.dwMinorVersion < 1)) + return refresh_rate; + + result = pGetDisplayConfigBufferSizes(QDC_DATABASE_CURRENT, + &NumPathArrayElements, + &NumModeInfoArrayElements); + + if (result != ERROR_SUCCESS) + return refresh_rate; + + PathInfoArray = (DISPLAYCONFIG_PATH_INFO_CUSTOM *) + malloc(sizeof(DISPLAYCONFIG_PATH_INFO_CUSTOM) * NumPathArrayElements); + ModeInfoArray = (DISPLAYCONFIG_MODE_INFO_CUSTOM *) + malloc(sizeof(DISPLAYCONFIG_MODE_INFO_CUSTOM) * NumModeInfoArrayElements); + + result = pQueryDisplayConfig(QDC_DATABASE_CURRENT, + &NumPathArrayElements, + PathInfoArray, + &NumModeInfoArrayElements, + ModeInfoArray, + &TopologyID); + + if (result == ERROR_SUCCESS && NumPathArrayElements >= 1) + { + refresh_rate = (float) PathInfoArray[0].targetInfo.refreshRate.Numerator / + PathInfoArray[0].targetInfo.refreshRate.Denominator; + } + + free(ModeInfoArray); + free(PathInfoArray); + +#endif + return refresh_rate; +} + void win32_get_video_output_next( unsigned *width, unsigned *height) { @@ -1284,7 +1524,7 @@ void win32_get_video_output_next( break; } - if ( dm.dmPelsWidth == curr_width + if ( dm.dmPelsWidth == curr_width && dm.dmPelsHeight == curr_height) found = true; } @@ -1294,7 +1534,7 @@ void win32_get_video_output_size(unsigned *width, unsigned *height) { DEVMODE dm; memset(&dm, 0, sizeof(dm)); - dm.dmSize = sizeof(dm); + dm.dmSize = sizeof(dm); if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm) != 0) { diff --git a/gfx/common/win32_common.h b/gfx/common/win32_common.h index 963db7f2cf..40fa4d3b39 100644 --- a/gfx/common/win32_common.h +++ b/gfx/common/win32_common.h @@ -56,14 +56,15 @@ void win32_monitor_get_info(void); void win32_monitor_info(void *data, void *hm_data, unsigned *mon_id); +int win32_change_display_settings(const char *str, void *devmode_data, + unsigned flags); + void create_graphics_context(HWND hwnd, bool *quit); void create_gdi_context(HWND hwnd, bool *quit); bool gdi_has_menu_frame(void); -bool win32_shader_dlg_init(void); -void shader_dlg_show(HWND parent_hwnd); void shader_dlg_params_reload(void); #endif @@ -127,6 +128,8 @@ bool win32_taskbar_is_created(void); void win32_set_taskbar_created(bool created); +float win32_get_refresh_rate(void *data); + #if defined(HAVE_D3D8) || defined(HAVE_D3D9) || defined (HAVE_D3D10) || defined (HAVE_D3D11) || defined (HAVE_D3D12) LRESULT CALLBACK WndProcD3D(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); diff --git a/gfx/common/x11_common.c b/gfx/common/x11_common.c index fd2832536b..d8d3a353dd 100644 --- a/gfx/common/x11_common.c +++ b/gfx/common/x11_common.c @@ -66,7 +66,7 @@ Display *g_x11_dpy = NULL; unsigned g_x11_screen = 0; Colormap g_x11_cmap; -Window g_x11_win; +Window g_x11_win = None; static Atom XA_NET_WM_STATE; static Atom XA_NET_WM_STATE_FULLSCREEN; @@ -107,7 +107,7 @@ void x11_show_mouse(Display *dpy, Window win, bool state) x11_hide_mouse(dpy, win); } -void x11_windowed_fullscreen(Display *dpy, Window win) +void x11_set_net_wm_fullscreen(Display *dpy, Window win) { XEvent xev = {0}; @@ -234,6 +234,28 @@ void x11_suspend_screensaver(Window wnd, bool enable) x11_suspend_screensaver_xdg_screensaver(wnd, enable); } +float x11_get_refresh_rate(void *data) +{ + XWindowAttributes attr; + XF86VidModeModeLine modeline; + Screen *screen; + int screenid; + int dotclock; + + if (!g_x11_dpy || g_x11_win == None) + return 0.0f; + + if (!XGetWindowAttributes(g_x11_dpy, g_x11_win, &attr)) + return 0.0f; + + screen = attr.screen; + screenid = XScreenNumberOfScreen(screen); + + XF86VidModeGetModeLine(g_x11_dpy, screenid, &dotclock, &modeline); + + return (float) dotclock * 1000.0f / modeline.htotal / modeline.vtotal; +} + static bool get_video_mode(video_frame_info_t *video_info, Display *dpy, unsigned width, unsigned height, XF86VidModeModeInfo *mode, XF86VidModeModeInfo *desktop_mode) @@ -408,7 +430,8 @@ static void x11_handle_key_event(XEvent *event, XIC ic, bool filter) status = 0; /* XwcLookupString doesn't seem to work. */ - num = Xutf8LookupString(ic, &event->xkey, keybuf, ARRAY_SIZE(keybuf), &keysym, &status); + num = Xutf8LookupString(ic, &event->xkey, keybuf, + ARRAY_SIZE(keybuf), &keysym, &status); /* libc functions need UTF-8 locale to work properly, * which makes mbrtowc a bit impractical. @@ -417,7 +440,8 @@ static void x11_handle_key_event(XEvent *event, XIC ic, bool filter) num = utf8_conv_utf32(chars, ARRAY_SIZE(chars), keybuf, num); #else (void)ic; - num = XLookupString(&event->xkey, keybuf, sizeof(keybuf), &keysym, NULL); /* ASCII only. */ + num = XLookupString(&event->xkey, keybuf, + sizeof(keybuf), &keysym, NULL); /* ASCII only. */ for (i = 0; i < num; i++) chars[i] = keybuf[i] & 0x7f; #endif @@ -685,3 +709,104 @@ void x11_event_queue_check(XEvent *event) XIfEvent(g_x11_dpy, event, x11_wait_notify, NULL); } +static bool x11_check_atom_supported(Display *dpy, Atom atom) +{ + Atom XA_NET_SUPPORTED = XInternAtom(dpy, "_NET_SUPPORTED", True); + Atom type; + int format; + unsigned long nitems; + unsigned long bytes_after; + Atom *prop; + int i; + + if (XA_NET_SUPPORTED == None) + return false; + + XGetWindowProperty(dpy, DefaultRootWindow(dpy), XA_NET_SUPPORTED, + 0, UINT_MAX, False, XA_ATOM, &type, &format,&nitems, + &bytes_after, (unsigned char **) &prop); + + if (!prop || type != XA_ATOM) + return false; + + for (i = 0; i < nitems; i++) + { + if (prop[i] == atom) + { + XFree(prop); + return true; + } + } + + XFree(prop); + + return false; +} + +bool x11_has_net_wm_fullscreen(Display *dpy) +{ + XA_NET_WM_STATE_FULLSCREEN = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + + return x11_check_atom_supported(dpy, XA_NET_WM_STATE_FULLSCREEN); +} + +char *x11_get_wm_name(Display *dpy) +{ + Atom XA_NET_SUPPORTING_WM_CHECK = XInternAtom(g_x11_dpy, "_NET_SUPPORTING_WM_CHECK", False); + Atom XA_NET_WM_NAME = XInternAtom(g_x11_dpy, "_NET_WM_NAME", False); + Atom XA_UTF8_STRING = XInternAtom(g_x11_dpy, "UTF8_STRING", False); + int status; + Atom type; + int format; + unsigned long nitems; + unsigned long bytes_after; + unsigned char *propdata; + char *title; + Window window; + + if (!XA_NET_SUPPORTING_WM_CHECK || !XA_NET_WM_NAME) + return NULL; + + status = XGetWindowProperty(dpy, + DefaultRootWindow(dpy), + XA_NET_SUPPORTING_WM_CHECK, + 0, + 1, + False, + XA_WINDOW, + &type, + &format, + &nitems, + &bytes_after, + &propdata); + + if (status == Success && propdata) + window = ((Window *) propdata)[0]; + else + return NULL; + + XFree(propdata); + + status = XGetWindowProperty(dpy, + window, + XA_NET_WM_NAME, + 0, + 8192, + False, + XA_UTF8_STRING, + &type, + &format, + &nitems, + &bytes_after, + &propdata); + + if (status == Success && propdata) + title = strdup((char *) propdata); + else + return NULL; + + XFree(propdata); + + return title; +} + diff --git a/gfx/common/x11_common.h b/gfx/common/x11_common.h index 23fc4898bc..3aa8117075 100644 --- a/gfx/common/x11_common.h +++ b/gfx/common/x11_common.h @@ -29,7 +29,7 @@ extern Colormap g_x11_cmap; extern unsigned g_x11_screen; void x11_show_mouse(Display *dpy, Window win, bool state); -void x11_windowed_fullscreen(Display *dpy, Window win); +void x11_set_net_wm_fullscreen(Display *dpy, Window win); void x11_suspend_screensaver(Window win, bool enable); bool x11_enter_fullscreen(video_frame_info_t *video_info, Display *dpy, unsigned width, @@ -48,6 +48,8 @@ void x11_destroy_input_context(XIM *xim, XIC *xic); bool x11_get_metrics(void *data, enum display_metric_types type, float *value); +float x11_get_refresh_rate(void *data); + void x11_check_window(void *data, bool *quit, bool *resize, unsigned *width, unsigned *height, bool is_shutdown); @@ -75,5 +77,9 @@ void x11_install_quit_atom(void); void x11_event_queue_check(XEvent *event); +char *x11_get_wm_name(Display *dpy); + +bool x11_has_net_wm_fullscreen(Display *dpy); + #endif diff --git a/gfx/display_servers/dispserv_null.c b/gfx/display_servers/dispserv_null.c index aa02bcc9c4..65d46c5d12 100644 --- a/gfx/display_servers/dispserv_null.c +++ b/gfx/display_servers/dispserv_null.c @@ -49,6 +49,7 @@ const video_display_server_t dispserv_null = { null_set_window_opacity, null_set_window_progress, NULL, + NULL, "null" }; diff --git a/gfx/display_servers/dispserv_win32.c b/gfx/display_servers/dispserv_win32.c index ce72e247f9..243b0ecf2b 100644 --- a/gfx/display_servers/dispserv_win32.c +++ b/gfx/display_servers/dispserv_win32.c @@ -34,6 +34,7 @@ #include "../video_display_server.h" #include "../common/win32_common.h" #include "../../verbosity.h" +#include "../video_driver.h" /* needed to set refresh rate in set resolution */ #ifdef __ITaskbarList3_INTERFACE_DEFINED__ #define HAS_TASKBAR_EXT @@ -65,10 +66,13 @@ calling RegisterWindowMessage(L("TaskbarButtonCreated")). That message must be received by your application before it calls any ITaskbarList3 method. */ +static unsigned win32_orig_width = 0; +static unsigned win32_orig_height = 0; + static void* win32_display_server_init(void) { - dispserv_win32_t *dispserv = (dispserv_win32_t*)calloc(1, sizeof(*dispserv)); HRESULT hr; + dispserv_win32_t *dispserv = (dispserv_win32_t*)calloc(1, sizeof(*dispserv)); (void)hr; @@ -77,11 +81,13 @@ static void* win32_display_server_init(void) #ifdef HAS_TASKBAR_EXT #ifdef __cplusplus - /* when compiling in C++ mode, GUIDs are references instead of pointers */ - hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void**)&g_taskbarList); + /* When compiling in C++ mode, GUIDs are references instead of pointers */ + hr = CoCreateInstance(CLSID_TaskbarList, NULL, + CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void**)&g_taskbarList); #else - /* mingw GUIDs are pointers instead of references since we're in C mode */ - hr = CoCreateInstance(&CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskbarList3, (void**)&g_taskbarList); + /* Mingw GUIDs are pointers instead of references since we're in C mode */ + hr = CoCreateInstance(&CLSID_TaskbarList, NULL, + CLSCTX_INPROC_SERVER, &IID_ITaskbarList3, (void**)&g_taskbarList); #endif if (!SUCCEEDED(hr)) @@ -97,6 +103,10 @@ static void* win32_display_server_init(void) static void win32_display_server_destroy(void *data) { dispserv_win32_t *dispserv = (dispserv_win32_t*)data; + + if (win32_orig_width > 0 && win32_orig_height > 0 ) + video_display_server_switch_resolution(win32_orig_width, win32_orig_height, + 60, 60); #ifdef HAS_TASKBAR_EXT if (g_taskbarList && win32_taskbar_is_created()) @@ -115,7 +125,8 @@ static bool win32_set_window_opacity(void *data, unsigned opacity) HWND hwnd = win32_get_window(); dispserv_win32_t *serv = (dispserv_win32_t*)data; - serv->opacity = opacity; + if (serv) + serv->opacity = opacity; #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 /* Set window transparency on Windows 2000 and above */ @@ -126,24 +137,23 @@ static bool win32_set_window_opacity(void *data, unsigned opacity) GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); return SetLayeredWindowAttributes(hwnd, 0, (255 * opacity) / 100, LWA_ALPHA); } - else - { - SetWindowLongPtr(hwnd, - GWL_EXSTYLE, - GetWindowLongPtr(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED); - return true; - } -#endif + + SetWindowLongPtr(hwnd, + GWL_EXSTYLE, + GetWindowLongPtr(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED); + return true; +#else return false; +#endif } static bool win32_set_window_progress(void *data, int progress, bool finished) { HWND hwnd = win32_get_window(); dispserv_win32_t *serv = (dispserv_win32_t*)data; - bool ret = false; - serv->progress = progress; + if (serv) + serv->progress = progress; #ifdef HAS_TASKBAR_EXT if (!g_taskbarList || !win32_taskbar_is_created()) @@ -151,53 +161,133 @@ static bool win32_set_window_progress(void *data, int progress, bool finished) if (progress == -1) { - if (ITaskbarList3_SetProgressState(g_taskbarList, hwnd, TBPF_INDETERMINATE) == S_OK) - ret = true; - - if (!ret) + if (ITaskbarList3_SetProgressState( + g_taskbarList, hwnd, TBPF_INDETERMINATE) != S_OK) return false; } else if (finished) { - if (ITaskbarList3_SetProgressState(g_taskbarList, hwnd, TBPF_NOPROGRESS) == S_OK) - ret = true; - - if (!ret) + if (ITaskbarList3_SetProgressState( + g_taskbarList, hwnd, TBPF_NOPROGRESS) != S_OK) return false; } else if (progress >= 0) { - if (ITaskbarList3_SetProgressState(g_taskbarList, hwnd, TBPF_NORMAL) == S_OK) - ret = true; - - if (!ret) + if (ITaskbarList3_SetProgressState( + g_taskbarList, hwnd, TBPF_NORMAL) != S_OK) return false; - if (ITaskbarList3_SetProgressValue(g_taskbarList, hwnd, progress, 100) == S_OK) - ret = true; + if (ITaskbarList3_SetProgressValue( + g_taskbarList, hwnd, progress, 100) != S_OK) + return false; } #endif - return ret; + return true; } static bool win32_set_window_decorations(void *data, bool on) { dispserv_win32_t *serv = (dispserv_win32_t*)data; - serv->decorations = on; + if (serv) + serv->decorations = on; - /* menu_setting performs a reinit instead to properly apply decoration changes */ + /* menu_setting performs a reinit instead to properly + * apply decoration changes */ return true; } +static bool win32_display_server_set_resolution(void *data, + unsigned width, unsigned height, int int_hz, float hz) +{ + LONG res; + DEVMODE curDevmode; + DEVMODE devmode; + + int iModeNum; + int freq = int_hz; + DWORD flags = 0; + int depth = 0; + dispserv_win32_t *serv = (dispserv_win32_t*)data; + + if (!serv) + return false; + + if (win32_orig_width == 0) + win32_orig_width = GetSystemMetrics(SM_CXSCREEN); + if (win32_orig_height == 0) + win32_orig_height = GetSystemMetrics(SM_CYSCREEN); + + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &curDevmode); + + /* Used to stop super resolution bug */ + if (width == curDevmode.dmPelsWidth) + width = 0; + if (width == 0) + width = curDevmode.dmPelsWidth; + if (height == 0) + height = curDevmode.dmPelsHeight; + if (depth == 0) + depth = curDevmode.dmBitsPerPel; + if (freq == 0) + freq = curDevmode.dmDisplayFrequency; + + for (iModeNum = 0; ; iModeNum++) + { + if (!EnumDisplaySettings(NULL, iModeNum, &devmode)) + break; + + if (devmode.dmPelsWidth != width) + continue; + + if (devmode.dmPelsHeight != height) + continue; + + if (devmode.dmBitsPerPel != depth) + continue; + + if (devmode.dmDisplayFrequency != freq) + continue; + + devmode.dmFields |= + DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; + res = + win32_change_display_settings(NULL, &devmode, CDS_TEST); + + switch (res) + { + case DISP_CHANGE_SUCCESSFUL: + res = win32_change_display_settings(NULL, &devmode, flags); + switch (res) + { + case DISP_CHANGE_SUCCESSFUL: + return true; + case DISP_CHANGE_NOTUPDATED: + return true; + default: + break; + } + break; + case DISP_CHANGE_RESTART: + break; + default: + break; + } + } + + return true; +} + + const video_display_server_t dispserv_win32 = { win32_display_server_init, win32_display_server_destroy, win32_set_window_opacity, win32_set_window_progress, win32_set_window_decorations, + win32_display_server_set_resolution, "win32" }; diff --git a/gfx/display_servers/dispserv_x11.c b/gfx/display_servers/dispserv_x11.c index 0d20343315..810ec79cb1 100644 --- a/gfx/display_servers/dispserv_x11.c +++ b/gfx/display_servers/dispserv_x11.c @@ -18,6 +18,15 @@ #include "../video_display_server.h" #include "../common/x11_common.h" #include "../../configuration.h" +#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; typedef struct { @@ -39,6 +48,9 @@ static void x11_display_server_destroy(void *data) { dispserv_x11_t *dispserv = (dispserv_x11_t*)data; + if (crt_en == true) + system("xrandr -s 704x480"); + if (dispserv) free(dispserv); } @@ -72,12 +84,197 @@ static bool x11_set_window_decorations(void *data, bool on) return true; } +static bool x11_set_resolution(void *data, + unsigned width, unsigned height, int int_hz, float hz) +{ + int i = 0; + int hfp = 0; + int hsp = 0; + int hbp = 0; + int vfp = 0; + int vsp = 0; + int vbp = 0; + int hmax = 0; + int vmax = 0; + float pixel_clock = 0; + char xrandr[250]; + char fbset[150]; + char output[150]; + + crt_en = true; + + hsp = width*1.14; + + /* set core refresh from hz */ + video_monitor_set_refresh_rate(hz); + + /* following code is the mode line genorator */ + if (width < 300) + { + width = width*2; + crt_aspect_ratio_switch(width, height); + } + + hfp = width+16; + hbp = width*1.22; + hmax = hbp; + + if (height < 241) + { + vmax = 261; + } + if (height < 241 && hz > 56 && hz < 58) + { + vmax = 280; + } + if (height < 241 && hz < 55) + { + vmax = 313; + } + if (height > 250 && height < 260 && hz > 54) + { + vmax = 296; + } + if (height > 250 && height < 260 && hz > 52 && hz < 54) + { + vmax = 285; + } + if (height > 240 && height < 260 && hz < 52) + { + vmax = 265; + } + if (height > 250 && height < 260 && hz < 52) + { + vmax = 313; + } + if (height > 260 && height < 300) + { + vmax = 313; + } + + if (height > 400 && hz > 56) + { + vmax = 523; + } + if (height > 520 && hz < 57) + { + vmax = 580; + } + + if (height > 300 && hz < 56) + { + vmax = 627; + } + + if (hz < 53) + { + vfp = height+((vmax-height)*0.38); + } + if (hz > 56) + { + vfp = height+((vmax-height)*0.15); + } + if (hz > 53 && hz < 56) + { + vfp = height+((vmax-height)*0.35); + } + + + if ( vfp < 1 ) + { + vfp = height+2; + + } + + if (height < 300) + { + vsp = vfp+3; /* needs to me 3 for progressive */ + } if (height > 300) + { + vsp = vfp+6; /* needs to me 6 for interlaced */ + } + + vbp = vmax; + + if (height < 300) + { + pixel_clock = (hmax*vmax*hz)/1000000; + } + + if (height > 300) + { + pixel_clock = ((hmax*vmax*hz)/1000000)/2; + } + /* above code is the modeline genorator */ + + /* 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); + 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); + system(xrandr); + + } + /* variable for new mode */ + sprintf(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); + system(output); + sprintf(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); + system(output); + sprintf(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); + system(output); + sprintf(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); + system(output); + sprintf(output,"xrandr --delmode %s-%d %s", "VGA",i ,old_mode); + system(output); + } + + sprintf(output,"xrandr -s %s", new_mode); + system(output); + /* remove old mode */ + sprintf(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); + 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 */ + + return true; +} + const video_display_server_t dispserv_x11 = { x11_display_server_init, x11_display_server_destroy, x11_set_window_opacity, NULL, x11_set_window_decorations, + x11_set_resolution, /* set_resolution */ "x11" }; diff --git a/gfx/drivers/caca_gfx.c b/gfx/drivers/caca_gfx.c index ae50a65937..a9405a6be1 100644 --- a/gfx/drivers/caca_gfx.c +++ b/gfx/drivers/caca_gfx.c @@ -305,6 +305,7 @@ static void caca_set_osd_msg(void *data, } static const video_poke_interface_t caca_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, @@ -318,6 +319,7 @@ static const video_poke_interface_t caca_poke_interface = { NULL, NULL, NULL, + NULL, caca_set_texture_frame, NULL, caca_set_osd_msg, diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index bdb3a69596..74a5c074d2 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -1133,11 +1133,13 @@ static void ctr_set_osd_msg(void *data, } static const video_poke_interface_t ctr_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ ctr_load_texture, ctr_unload_texture, NULL, + NULL, ctr_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/d3d.h b/gfx/drivers/d3d.h index d914729a54..fa4814fb33 100644 --- a/gfx/drivers/d3d.h +++ b/gfx/drivers/d3d.h @@ -17,8 +17,6 @@ #ifndef __D3DVIDEO_INTF_H__ #define __D3DVIDEO_INTF_H__ -#include - #ifdef HAVE_CONFIG_H #include "../../config.h" #endif @@ -64,49 +62,5 @@ typedef struct d3d_video_viewport float max_z; } d3d_video_viewport_t; -typedef struct d3d_video -{ - bool keep_aspect; - bool should_resize; - bool quitting; - bool needs_restore; - bool overlays_enabled; - /* TODO - refactor this away properly. */ - bool resolution_hd_enable; - - unsigned cur_mon_id; - unsigned dev_rotation; - - overlay_t *menu; - const d3d_renderchain_driver_t *renderchain_driver; - void *renderchain_data; - - RECT font_rect; - RECT font_rect_shifted; - math_matrix_4x4 mvp; - math_matrix_4x4 mvp_rotate; - math_matrix_4x4 mvp_transposed; - - struct video_viewport vp; - struct video_shader shader; - video_info_t video_info; - WNDCLASSEX windowClass; - void *dev; - d3d_video_viewport_t final_viewport; - - char *shader_path; - - struct - { - int size; - int offset; - void *buffer; - void *decl; - }menu_display; - - size_t overlays_size; - overlay_t *overlays; -} d3d_video_t; - #endif diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index c0f41e9f2d..ea557a2084 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2014-2018 - Ali Bouhlel * * RetroArch is free software: you can redistribute it and/or modify it under the terms @@ -16,44 +16,215 @@ #define CINTERFACE #include + #include +#include #include "../../driver.h" #include "../../verbosity.h" #include "../../configuration.h" #include "../video_driver.h" +#include "../font_driver.h" #include "../common/win32_common.h" #include "../common/d3d10_common.h" #include "../common/dxgi_common.h" #include "../common/d3dcompiler_common.h" +#ifdef HAVE_MENU +#include "../../menu/menu_driver.h" +#endif -static void d3d10_set_filtering(void* data, unsigned index, bool smooth) +#ifdef HAVE_OVERLAY +static void d3d10_free_overlays(d3d10_video_t* d3d10) +{ + unsigned i; + for (i = 0; i < (unsigned)d3d10->overlays.count; i++) + d3d10_release_texture(&d3d10->overlays.textures[i]); + + Release(d3d10->overlays.vbo); +} + +static void +d3d10_overlay_vertex_geom(void* data, unsigned index, float x, float y, float w, float h) +{ + d3d10_sprite_t* sprites = NULL; + d3d10_video_t* d3d10 = (d3d10_video_t*)data; + + if (!d3d10) + return; + + 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; + 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_video_t* d3d10 = (d3d10_video_t*)data; + + if (!d3d10) + return; + + 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; + D3D10UnmapBuffer(d3d10->overlays.vbo); +} + +static void d3d10_overlay_set_alpha(void* data, unsigned index, float mod) +{ + d3d10_sprite_t* sprites = NULL; + d3d10_video_t* d3d10 = (d3d10_video_t*)data; + + if (!d3d10) + return; + + 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]; + D3D10UnmapBuffer(d3d10->overlays.vbo); +} + +static bool d3d10_overlay_load(void* data, const void* image_data, unsigned num_images) +{ + D3D10_BUFFER_DESC desc; + unsigned i; + d3d10_sprite_t* sprites; + d3d10_video_t* d3d10 = (d3d10_video_t*)data; + const struct texture_image* images = (const struct texture_image*)image_data; + + if (!d3d10) + return false; + + d3d10_free_overlays(d3d10); + d3d10->overlays.count = num_images; + d3d10->overlays.textures = (d3d10_texture_t*)calloc( + num_images, sizeof(d3d10_texture_t)); + + desc.ByteWidth = sizeof(d3d10_sprite_t) * num_images; + desc.Usage = D3D10_USAGE_DYNAMIC; + desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; +#if 0 + desc.StructureByteStride = 0; +#endif + D3D10CreateBuffer(d3d10->device, &desc, NULL, &d3d10->overlays.vbo); + + D3D10MapBuffer(d3d10->overlays.vbo, + D3D10_MAP_WRITE_DISCARD, 0, (void**)&sprites); + + for (i = 0; i < (unsigned)num_images; i++) + { + + d3d10->overlays.textures[i].desc.Width = images[i].width; + d3d10->overlays.textures[i].desc.Height = images[i].height; + d3d10->overlays.textures[i].desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + + d3d10_init_texture(d3d10->device, &d3d10->overlays.textures[i]); + + d3d10_update_texture( + d3d10->device, + images[i].width, + images[i].height, 0, DXGI_FORMAT_B8G8R8A8_UNORM, + images[i].pixels, &d3d10->overlays.textures[i]); + + sprites[i].pos.x = 0.0f; + sprites[i].pos.y = 0.0f; + sprites[i].pos.w = 1.0f; + sprites[i].pos.h = 1.0f; + + sprites[i].coords.u = 0.0f; + sprites[i].coords.v = 0.0f; + sprites[i].coords.w = 1.0f; + sprites[i].coords.h = 1.0f; + + sprites[i].params.scaling = 1; + sprites[i].params.rotation = 0; + + sprites[i].colors[0] = 0xFFFFFFFF; + sprites[i].colors[1] = sprites[i].colors[0]; + sprites[i].colors[2] = sprites[i].colors[0]; + sprites[i].colors[3] = sprites[i].colors[0]; + } + D3D10UnmapBuffer(d3d10->overlays.vbo); + + return true; +} + +static void d3d10_overlay_enable(void* data, bool state) { d3d10_video_t* d3d10 = (d3d10_video_t*)data; - if (smooth) - d3d10->frame.sampler = d3d10->sampler_linear; - else - d3d10->frame.sampler = d3d10->sampler_nearest; + if (!d3d10) + return; + + d3d10->overlays.enabled = state; + win32_show_cursor(state); } +static void d3d10_overlay_full_screen(void* data, bool enable) +{ + d3d10_video_t* d3d10 = (d3d10_video_t*)data; + + if (!d3d10) + return; + + d3d10->overlays.fullscreen = enable; +} + +static void d3d10_get_overlay_interface(void* data, const video_overlay_interface_t** iface) +{ + static const video_overlay_interface_t overlay_interface = { + d3d10_overlay_enable, d3d10_overlay_load, d3d10_overlay_tex_geom, + d3d10_overlay_vertex_geom, d3d10_overlay_full_screen, d3d10_overlay_set_alpha, + }; + + *iface = &overlay_interface; +} +#endif + +static void d3d10_set_filtering(void* data, unsigned index, bool smooth) +{ + unsigned i; + d3d10_video_t* d3d10 = (d3d10_video_t*)data; + + for (i = 0; i < RARCH_WRAP_MAX; i++) + { + if (smooth) + d3d10->samplers[RARCH_FILTER_UNSPEC][i] = d3d10->samplers[RARCH_FILTER_LINEAR][i]; + else + d3d10->samplers[RARCH_FILTER_UNSPEC][i] = d3d10->samplers[RARCH_FILTER_NEAREST][i]; + } +} + + static void d3d10_gfx_set_rotation(void* data, unsigned rotation) { - math_matrix_4x4 rot; - math_matrix_4x4* mvp; - d3d10_video_t* d3d10 = (d3d10_video_t*)data; + math_matrix_4x4 rot; + void* mapped_ubo = NULL; + d3d10_video_t* d3d10 = (d3d10_video_t*)data; - if(!d3d10) + if (!d3d10) return; - d3d10->frame.rotation = rotation; + matrix_4x4_rotate_z(rot, rotation * (M_PI / 2.0f)); + matrix_4x4_multiply(d3d10->mvp, rot, d3d10->ubo_values.mvp); - - matrix_4x4_rotate_z(rot, d3d10->frame.rotation * (M_PI / 2.0f)); - matrix_4x4_multiply(d3d10->mvp, rot, d3d10->mvp_no_rot); - - D3D10MapBuffer(d3d10->frame.ubo, D3D10_MAP_WRITE_DISCARD, 0, (void**)&mvp); - *mvp = d3d10->mvp; + D3D10MapBuffer(d3d10->frame.ubo, D3D10_MAP_WRITE_DISCARD, 0, &mapped_ubo); + *(math_matrix_4x4*)mapped_ubo = d3d10->mvp; D3D10UnmapBuffer(d3d10->frame.ubo); } @@ -63,22 +234,342 @@ static void d3d10_update_viewport(void* data, bool force_full) video_driver_update_viewport(&d3d10->vp, force_full, d3d10->keep_aspect); - d3d10->frame.viewport.TopLeftX = (float)d3d10->vp.x; - d3d10->frame.viewport.TopLeftY = (float)d3d10->vp.y; - d3d10->frame.viewport.Width = (float)d3d10->vp.width; - d3d10->frame.viewport.Height = (float)d3d10->vp.height; + d3d10->frame.viewport.TopLeftX = d3d10->vp.x; + d3d10->frame.viewport.TopLeftY = d3d10->vp.y; + d3d10->frame.viewport.Width = d3d10->vp.width; + d3d10->frame.viewport.Height = d3d10->vp.height; d3d10->frame.viewport.MaxDepth = 0.0f; 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->resize_render_targets = true; + + d3d10->frame.output_size.x = d3d10->vp.width; + d3d10->frame.output_size.y = d3d10->vp.height; + d3d10->frame.output_size.z = 1.0f / d3d10->vp.width; + d3d10->frame.output_size.w = 1.0f / d3d10->vp.height; + d3d10->resize_viewport = false; } - static void* -d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) +static void d3d10_free_shader_preset(d3d10_video_t* d3d10) { - WNDCLASSEX wndclass = { 0 }; + unsigned i; + if (!d3d10->shader_preset) + return; + + for (i = 0; i < d3d10->shader_preset->passes; i++) + { + unsigned j; + + free(d3d10->shader_preset->pass[i].source.string.vertex); + free(d3d10->shader_preset->pass[i].source.string.fragment); + free(d3d10->pass[i].semantics.textures); + d3d10_release_shader(&d3d10->pass[i].shader); + d3d10_release_texture(&d3d10->pass[i].rt); + d3d10_release_texture(&d3d10->pass[i].feedback); + + for (j = 0; j < SLANG_CBUFFER_MAX; j++) + { + free(d3d10->pass[i].semantics.cbuffers[j].uniforms); + Release(d3d10->pass[i].buffers[j]); + } + } + + memset(d3d10->pass, 0, sizeof(d3d10->pass)); + + /* only free the history textures here */ + for (i = 1; i <= (unsigned)d3d10->shader_preset->history_size; i++) + d3d10_release_texture(&d3d10->frame.texture[i]); + + memset( + &d3d10->frame.texture[1], 0, + sizeof(d3d10->frame.texture[1]) * d3d10->shader_preset->history_size); + + for (i = 0; i < d3d10->shader_preset->luts; i++) + d3d10_release_texture(&d3d10->luts[i]); + + memset(d3d10->luts, 0, sizeof(d3d10->luts)); + + free(d3d10->shader_preset); + d3d10->shader_preset = NULL; + d3d10->init_history = false; + d3d10->resize_render_targets = false; +} + +static bool d3d10_gfx_set_shader(void* data, + enum rarch_shader_type type, const char* path) +{ +#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) + unsigned i; + config_file_t* conf = NULL; + d3d10_texture_t* source = NULL; + d3d10_video_t* d3d10 = (d3d10_video_t*)data; + + if (!d3d10) + return false; + + D3D10Flush(d3d10->device); + d3d10_free_shader_preset(d3d10); + + if (!path) + return true; + + if (type != RARCH_SHADER_SLANG) + { + RARCH_WARN("Only .slang or .slangp shaders are supported. Falling back to stock.\n"); + return false; + } + + conf = config_file_new(path); + + if (!conf) + return false; + + d3d10->shader_preset = (struct video_shader*)calloc(1, sizeof(*d3d10->shader_preset)); + + if (!video_shader_read_conf_cgp(conf, d3d10->shader_preset)) + goto error; + + video_shader_resolve_relative(d3d10->shader_preset, path); + + source = &d3d10->frame.texture[0]; + for (i = 0; i < d3d10->shader_preset->passes; source = &d3d10->pass[i++].rt) + { + unsigned j; + /* clang-format off */ + semantics_map_t semantics_map = { + { + /* Original */ + { &d3d10->frame.texture[0].view, 0, + &d3d10->frame.texture[0].size_data, 0}, + + /* Source */ + { &source->view, 0, + &source->size_data, 0}, + + /* OriginalHistory */ + { &d3d10->frame.texture[0].view, sizeof(*d3d10->frame.texture), + &d3d10->frame.texture[0].size_data, sizeof(*d3d10->frame.texture)}, + + /* PassOutput */ + { &d3d10->pass[0].rt.view, sizeof(*d3d10->pass), + &d3d10->pass[0].rt.size_data, sizeof(*d3d10->pass)}, + + /* PassFeedback */ + { &d3d10->pass[0].feedback.view, sizeof(*d3d10->pass), + &d3d10->pass[0].feedback.size_data, sizeof(*d3d10->pass)}, + + /* User */ + { &d3d10->luts[0].view, sizeof(*d3d10->luts), + &d3d10->luts[0].size_data, sizeof(*d3d10->luts)}, + }, + { + &d3d10->mvp, /* MVP */ + &d3d10->pass[i].rt.size_data, /* OutputSize */ + &d3d10->frame.output_size, /* FinalViewportSize */ + &d3d10->pass[i].frame_count, /* FrameCount */ + } + }; + /* clang-format on */ + + if (!slang_process( + 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 }, + { "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d10_vertex_t, texcoord), + D3D10_INPUT_PER_VERTEX_DATA, 0 }, + }; +#ifdef DEBUG + bool save_hlsl = true; +#else + bool save_hlsl = false; +#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]; + 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)); + + if (!d3d10_init_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)) + save_hlsl = true; + + if (save_hlsl) + { + FILE* fp = fopen(vs_path, "w"); + fwrite(vs_src, 1, strlen(vs_src), fp); + fclose(fp); + + fp = fopen(ps_path, "w"); + fwrite(ps_src, 1, strlen(ps_src), fp); + fclose(fp); + } + + free(d3d10->shader_preset->pass[i].source.string.vertex); + free(d3d10->shader_preset->pass[i].source.string.fragment); + + d3d10->shader_preset->pass[i].source.string.vertex = NULL; + d3d10->shader_preset->pass[i].source.string.fragment = NULL; + + if (!d3d10->pass[i].shader.vs || !d3d10->pass[i].shader.ps) + goto error; + } + + for (j = 0; j < SLANG_CBUFFER_MAX; j++) + { + D3D10_BUFFER_DESC desc; + desc.ByteWidth = d3d10->pass[i].semantics.cbuffers[j].size; + desc.Usage = D3D10_USAGE_DYNAMIC; + desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; + desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + + if (!desc.ByteWidth) + continue; + + D3D10CreateBuffer(d3d10->device, &desc, + NULL, &d3d10->pass[i].buffers[j]); + } + } + + for (i = 0; i < d3d10->shader_preset->luts; i++) + { + struct texture_image image = { 0 }; + image.supports_rgba = true; + + if (!image_texture_load(&image, d3d10->shader_preset->lut[i].path)) + goto error; + + d3d10->luts[i].desc.Width = image.width; + d3d10->luts[i].desc.Height = image.height; + d3d10->luts[i].desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + + if (d3d10->shader_preset->lut[i].mipmap) + d3d10->luts[i].desc.MiscFlags = D3D10_RESOURCE_MISC_GENERATE_MIPS; + + d3d10_init_texture(d3d10->device, &d3d10->luts[i]); + + d3d10_update_texture( + d3d10->device, + image.width, image.height, 0, + DXGI_FORMAT_R8G8B8A8_UNORM, image.pixels, + &d3d10->luts[i]); + + image_texture_free(&image); + } + + video_shader_resolve_current_parameters(conf, d3d10->shader_preset); + config_file_free(conf); + + d3d10->resize_render_targets = true; + d3d10->init_history = true; + + return true; + +error: + d3d10_free_shader_preset(d3d10); +#endif + + return false; +} + +static void d3d10_gfx_free(void* data) +{ + unsigned i; + d3d10_video_t* d3d10 = (d3d10_video_t*)data; + + if (!d3d10) + return; + +#ifdef HAVE_OVERLAY + d3d10_free_overlays(d3d10); +#endif + + d3d10_free_shader_preset(d3d10); + + d3d10_release_texture(&d3d10->frame.texture[0]); + Release(d3d10->frame.ubo); + Release(d3d10->frame.vbo); + + d3d10_release_texture(&d3d10->menu.texture); + Release(d3d10->menu.vbo); + + d3d10_release_shader(&d3d10->sprites.shader); + d3d10_release_shader(&d3d10->sprites.shader_font); + Release(d3d10->sprites.vbo); + + for (i = 0; i < GFX_MAX_SHADERS; i++) + d3d10_release_shader(&d3d10->shaders[i]); + + Release(d3d10->menu_pipeline_vbo); + Release(d3d10->blend_pipeline); + + Release(d3d10->ubo); + + Release(d3d10->blend_enable); + Release(d3d10->blend_disable); + + for (i = 0; i < RARCH_WRAP_MAX; i++) + { + Release(d3d10->samplers[RARCH_FILTER_LINEAR][i]); + Release(d3d10->samplers[RARCH_FILTER_NEAREST][i]); + } + + Release(d3d10->state); + Release(d3d10->renderTargetView); + Release(d3d10->swapChain); + + font_driver_free_osd(); + +#if 0 + if (video_driver_is_video_cache_context()) + { + cached_device_d3d10 = d3d10->device; + cached_context = d3d10->context; + } + else +#endif + { + Release(d3d10->device); + } + + win32_monitor_from_window(); + win32_destroy_window(); + free(d3d10); +} + + static void* +d3d10_gfx_init(const video_info_t* video, + const input_driver_t** input, void** input_data) +{ + unsigned i; MONITORINFOEX current_mon; HMONITOR hm_to_use; + WNDCLASSEX wndclass = { 0 }; settings_t* settings = config_get_ptr(); d3d10_video_t* d3d10 = (d3d10_video_t*)calloc(1, sizeof(*d3d10)); @@ -96,38 +587,38 @@ d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** i d3d10->vp.full_height = video->height; if (!d3d10->vp.full_width) - d3d10->vp.full_width = current_mon.rcMonitor.right - current_mon.rcMonitor.left; + d3d10->vp.full_width = + current_mon.rcMonitor.right - current_mon.rcMonitor.left; if (!d3d10->vp.full_height) - d3d10->vp.full_height = current_mon.rcMonitor.bottom - current_mon.rcMonitor.top; + d3d10->vp.full_height = + current_mon.rcMonitor.bottom - current_mon.rcMonitor.top; - if (!win32_set_video_mode(d3d10, video->width, video->height, video->fullscreen)) + 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"); goto error; } - dxgi_input_driver(settings->arrays.input_joypad_driver, input, input_data); { UINT flags = 0; DXGI_SWAP_CHAIN_DESC desc = {0}; - desc.BufferCount = 2; - desc.BufferDesc.Width = video->width; - desc.BufferDesc.Height = video->height; + desc.BufferCount = 1; + desc.BufferDesc.Width = d3d10->vp.full_width; + desc.BufferDesc.Height = d3d10->vp.full_height; desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; -#if 0 desc.BufferDesc.RefreshRate.Numerator = 60; desc.BufferDesc.RefreshRate.Denominator = 1; -#endif desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; desc.OutputWindow = main_window.hwnd; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Windowed = TRUE; - desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; #if 0 - desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; + desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; #endif @@ -136,9 +627,11 @@ d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** i flags |= D3D10_CREATE_DEVICE_DEBUG; #endif - D3D10CreateDeviceAndSwapChain( - NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D10_SDK_VERSION, &desc, - (IDXGISwapChain**)&d3d10->swapChain, &d3d10->device); + if (FAILED(D3D10CreateDeviceAndSwapChain( + NULL, D3D10_DRIVER_TYPE_HARDWARE, + NULL, flags, D3D10_SDK_VERSION, &desc, + (IDXGISwapChain**)&d3d10->swapChain, &d3d10->device))) + goto error; } { @@ -149,164 +642,426 @@ d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** i Release(backBuffer); } - D3D10SetRenderTargets(d3d10->device, 1, &d3d10->renderTargetView, NULL); - d3d10->viewport.Width = video->width; - d3d10->viewport.Height = video->height; - d3d10->resize_viewport = true; - d3d10->keep_aspect = video->force_aspect; - d3d10->vsync = video->vsync; - d3d10->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM; + D3D10SetRenderTargets(d3d10->device, 1, &d3d10->renderTargetView, NULL); - d3d10->frame.texture.desc.Format = - d3d10_get_closest_match_texture2D(d3d10->device, d3d10->format); - d3d10->frame.texture.desc.Usage = D3D10_USAGE_DEFAULT; + video_driver_set_size(&d3d10->vp.full_width, &d3d10->vp.full_height); + d3d10->viewport.Width = d3d10->vp.full_width; + d3d10->viewport.Height = d3d10->vp.full_height; + d3d10->resize_viewport = true; + d3d10->vsync = video->vsync; + d3d10->format = video->rgb32 ? + DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM; + + d3d10->frame.texture[0].desc.Format = d3d10->format; + d3d10->frame.texture[0].desc.Usage = D3D10_USAGE_DEFAULT; + d3d10->frame.texture[0].desc.Width = 4; + d3d10->frame.texture[0].desc.Height = 4; + + d3d10_init_texture(d3d10->device, &d3d10->frame.texture[0]); d3d10->menu.texture.desc.Usage = D3D10_USAGE_DEFAULT; - matrix_4x4_ortho(d3d10->mvp_no_rot, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); + matrix_4x4_ortho(d3d10->ubo_values.mvp, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); + + d3d10->ubo_values.OutputSize.width = d3d10->viewport.Width; + d3d10->ubo_values.OutputSize.height = d3d10->viewport.Height; { - D3D10_BUFFER_DESC desc; D3D10_SUBRESOURCE_DATA ubo_data; + D3D10_BUFFER_DESC desc; - desc.ByteWidth = sizeof(math_matrix_4x4); + desc.ByteWidth = sizeof(d3d10->ubo_values); desc.Usage = D3D10_USAGE_DYNAMIC; desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; desc.MiscFlags = 0; - ubo_data.pSysMem = &d3d10->mvp_no_rot; + ubo_data.pSysMem = &d3d10->ubo_values.mvp; ubo_data.SysMemPitch = 0; ubo_data.SysMemSlicePitch = 0; D3D10CreateBuffer(d3d10->device, &desc, &ubo_data, &d3d10->ubo); D3D10CreateBuffer(d3d10->device, &desc, NULL, &d3d10->frame.ubo); } + d3d10_gfx_set_rotation(d3d10, 0); { - unsigned k; - D3D10_SAMPLER_DESC desc; + D3D10_SAMPLER_DESC desc = { D3D10_FILTER_MIN_MAG_MIP_POINT }; + desc.MaxAnisotropy = 1; + desc.ComparisonFunc = D3D10_COMPARISON_NEVER; + desc.MinLOD = -D3D10_FLOAT32_MAX; + desc.MaxLOD = D3D10_FLOAT32_MAX; - desc.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT; - desc.AddressU = D3D10_TEXTURE_ADDRESS_BORDER; - desc.AddressV = D3D10_TEXTURE_ADDRESS_BORDER; - desc.AddressW = D3D10_TEXTURE_ADDRESS_BORDER; - desc.MipLODBias = 0.0f; - desc.MaxAnisotropy = 1; - desc.ComparisonFunc = D3D10_COMPARISON_NEVER; - desc.MinLOD = -D3D10_FLOAT32_MAX; - desc.MaxLOD = D3D10_FLOAT32_MAX; + /* Initialize samplers */ + for (i = 0; i < RARCH_WRAP_MAX; i++) + { + switch (i) + { + case RARCH_WRAP_BORDER: + desc.AddressU = D3D10_TEXTURE_ADDRESS_BORDER; + break; - for (k = 0; k < 4; k++) - desc.BorderColor[k] = 0.0f; + case RARCH_WRAP_EDGE: + desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP; + break; - D3D10CreateSamplerState(d3d10->device, &desc, &d3d10->sampler_nearest); + case RARCH_WRAP_REPEAT: + desc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP; + break; - desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR; - D3D10CreateSamplerState(d3d10->device, &desc, &d3d10->sampler_linear); + case RARCH_WRAP_MIRRORED_REPEAT: + desc.AddressU = D3D10_TEXTURE_ADDRESS_MIRROR; + break; + } + desc.AddressV = desc.AddressU; + desc.AddressW = desc.AddressU; + + desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR; + D3D10CreateSamplerState(d3d10->device, &desc, + &d3d10->samplers[RARCH_FILTER_LINEAR][i]); + + desc.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT; + D3D10CreateSamplerState(d3d10->device, &desc, + &d3d10->samplers[RARCH_FILTER_NEAREST][i]); + } } d3d10_set_filtering(d3d10, 0, video->smooth); { + D3D10_BUFFER_DESC desc; d3d10_vertex_t vertices[] = { { { 0.0f, 0.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 0.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, }; + D3D10_SUBRESOURCE_DATA + vertexData = { vertices }; - { - D3D10_SUBRESOURCE_DATA vertexData; - D3D10_BUFFER_DESC desc; + desc.ByteWidth = sizeof(vertices); + desc.Usage = D3D10_USAGE_IMMUTABLE; + desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; - desc.ByteWidth = sizeof(vertices); - desc.Usage = D3D10_USAGE_DYNAMIC; - desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; - desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; - desc.MiscFlags = 0; + D3D10CreateBuffer(d3d10->device, &desc, &vertexData, &d3d10->frame.vbo); + desc.Usage = D3D10_USAGE_DYNAMIC; + desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + D3D10CreateBuffer(d3d10->device, &desc, &vertexData, &d3d10->menu.vbo); - vertexData.pSysMem = vertices; - vertexData.SysMemPitch = 0; - vertexData.SysMemSlicePitch = 0; - - D3D10CreateBuffer(d3d10->device, &desc, &vertexData, &d3d10->frame.vbo); - desc.Usage = D3D10_USAGE_IMMUTABLE; - desc.CPUAccessFlags = 0; - D3D10CreateBuffer(d3d10->device, &desc, &vertexData, &d3d10->menu.vbo); - } - D3D10SetPrimitiveTopology(d3d10->device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + d3d10->sprites.capacity = 4096; + desc.ByteWidth = sizeof(d3d10_sprite_t) * d3d10->sprites.capacity; + D3D10CreateBuffer(d3d10->device, &desc, NULL, &d3d10->sprites.vbo); } { - D3DBlob vs_code; - D3DBlob ps_code; - - static const char stock[] = -#include "d3d_shaders/opaque_sm5.hlsl.h" - ; - 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 }, }; - d3d_compile(stock, sizeof(stock), NULL, "VSMain", "vs_4_0", &vs_code); - d3d_compile(stock, sizeof(stock), NULL, "PSMain", "ps_4_0", &ps_code); + static const char shader[] = +#include "d3d_shaders/opaque_sm5.hlsl.h" + ; - D3D10CreateVertexShader( - d3d10->device, D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code), &d3d10->vs); - D3D10CreatePixelShader( - d3d10->device, D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code), &d3d10->ps); - D3D10CreateInputLayout( - d3d10->device, desc, countof(desc), D3DGetBufferPointer(vs_code), - D3DGetBufferSize(vs_code), &d3d10->layout); - - Release(vs_code); - Release(ps_code); + if (!d3d10_init_shader( + d3d10->device, shader, sizeof(shader), NULL, "VSMain", "PSMain", NULL, desc, + countof(desc), &d3d10->shaders[VIDEO_SHADER_STOCK_BLEND])) + goto error; } - D3D10SetInputLayout(d3d10->device, d3d10->layout); - D3D10SetVShader(d3d10->device, d3d10->vs); - D3D10SetPShader(d3d10->device, d3d10->ps); - { - unsigned k; - D3D10_BLEND_DESC blend_desc; + D3D10_INPUT_ELEMENT_DESC desc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d10_sprite_t, pos), + D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d10_sprite_t, coords), + 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 }, + { "COLOR", 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d10_sprite_t, colors[1]), + 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 }, + { "COLOR", 3, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d10_sprite_t, colors[3]), + D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "PARAMS", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d10_sprite_t, params), + 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)) + goto error; + if (!d3d10_init_shader( + d3d10->device, shader, sizeof(shader), NULL, "VSMain", "PSMainA8", "GSMain", desc, + countof(desc), &d3d10->sprites.shader_font)) + goto error; + } - for (k = 0; k < 8; k++) + if (string_is_equal(settings->arrays.menu_driver, "xmb")) + { { - blend_desc.BlendEnable[k] = TRUE; - blend_desc.RenderTargetWriteMask[k] = D3D10_COLOR_WRITE_ENABLE_ALL; + D3D10_INPUT_ELEMENT_DESC desc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + }; + + static const char ribbon[] = +#include "d3d_shaders/ribbon_sm4.hlsl.h" + ; + static const char ribbon_simple[] = +#include "d3d_shaders/ribbon_simple_sm4.hlsl.h" + ; + + if (!d3d10_init_shader( + d3d10->device, ribbon, sizeof(ribbon), NULL, "VSMain", "PSMain", NULL, desc, + countof(desc), &d3d10->shaders[VIDEO_SHADER_MENU])) + goto error; + + if (!d3d10_init_shader( + d3d10->device, ribbon_simple, sizeof(ribbon_simple), NULL, "VSMain", "PSMain", NULL, + desc, countof(desc), &d3d10->shaders[VIDEO_SHADER_MENU_2])) + goto error; } - blend_desc.AlphaToCoverageEnable = FALSE; - blend_desc.SrcBlend = D3D10_BLEND_SRC_ALPHA; - blend_desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA; - blend_desc.BlendOp = D3D10_BLEND_OP_ADD; - blend_desc.SrcBlendAlpha = D3D10_BLEND_SRC_ALPHA; - blend_desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA; - blend_desc.BlendOpAlpha = D3D10_BLEND_OP_ADD; + { + D3D10_INPUT_ELEMENT_DESC desc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d10_vertex_t, position), + D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d10_vertex_t, texcoord), + D3D10_INPUT_PER_VERTEX_DATA, 0 }, + }; + static const char simple_snow[] = +#include "d3d_shaders/simple_snow_sm4.hlsl.h" + ; + static const char snow[] = +#include "d3d_shaders/snow_sm4.hlsl.h" + ; + static const char bokeh[] = +#include "d3d_shaders/bokeh_sm4.hlsl.h" + ; + static const char snowflake[] = +#include "d3d_shaders/snowflake_sm4.hlsl.h" + ; + + if (!d3d10_init_shader( + d3d10->device, simple_snow, sizeof(simple_snow), NULL, "VSMain", "PSMain", NULL, + desc, countof(desc), &d3d10->shaders[VIDEO_SHADER_MENU_3])) + goto error; + if (!d3d10_init_shader( + d3d10->device, snow, sizeof(snow), NULL, "VSMain", "PSMain", NULL, desc, + countof(desc), &d3d10->shaders[VIDEO_SHADER_MENU_4])) + goto error; + + if (!d3d10_init_shader( + d3d10->device, bokeh, sizeof(bokeh), NULL, "VSMain", "PSMain", NULL, desc, + countof(desc), &d3d10->shaders[VIDEO_SHADER_MENU_5])) + goto error; + + if (!d3d10_init_shader( + d3d10->device, snowflake, sizeof(snowflake), NULL, "VSMain", "PSMain", NULL, desc, + countof(desc), &d3d10->shaders[VIDEO_SHADER_MENU_6])) + goto error; + } + } + + { + D3D10_BLEND_DESC blend_desc = { 0 }; + + blend_desc.AlphaToCoverageEnable = FALSE; + blend_desc.BlendEnable[0] = TRUE; + blend_desc.SrcBlend = D3D10_BLEND_SRC_ALPHA; + blend_desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA; + blend_desc.BlendOp = D3D10_BLEND_OP_ADD; + blend_desc.SrcBlendAlpha = D3D10_BLEND_SRC_ALPHA; + blend_desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA; + blend_desc.BlendOpAlpha = D3D10_BLEND_OP_ADD; + blend_desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; D3D10CreateBlendState(d3d10->device, &blend_desc, &d3d10->blend_enable); + + blend_desc.SrcBlend = D3D10_BLEND_ONE; + blend_desc.DestBlend = D3D10_BLEND_ONE; + D3D10CreateBlendState(d3d10->device, &blend_desc, &d3d10->blend_pipeline); + blend_desc.BlendEnable[0] = FALSE; D3D10CreateBlendState(d3d10->device, &blend_desc, &d3d10->blend_disable); + } + + { + D3D10_RASTERIZER_DESC desc = { (D3D10_FILL_MODE)0 }; + + desc.FillMode = D3D10_FILL_SOLID; + desc.CullMode = D3D10_CULL_NONE; + + D3D10CreateRasterizerState(d3d10->device, &desc, &d3d10->state); } + D3D10SetState(d3d10->device, d3d10->state); + + font_driver_init_osd(d3d10, false, video->is_threaded, FONT_DRIVER_RENDER_D3D10_API); + + if (settings->bools.video_shader_enable) + { + const char* ext = path_get_extension(settings->paths.path_shader); + + if (ext && !strncmp(ext, "slang", 5)) + d3d10_gfx_set_shader(d3d10, RARCH_SHADER_SLANG, settings->paths.path_shader); + } + +#if 0 + if (video_driver_get_hw_context()->context_type == RETRO_HW_CONTEXT_DIRECT3D && + video_driver_get_hw_context()->version_major == 11) + { + d3d10->hw.enable = true; + d3d10->hw.iface.interface_type = RETRO_HW_RENDER_INTERFACE_D3D10; + d3d10->hw.iface.interface_version = RETRO_HW_RENDER_INTERFACE_D3D10_VERSION; + d3d10->hw.iface.handle = d3d10; + d3d10->hw.iface.device = d3d10->device; + d3d10->hw.iface.context = d3d10->context; + d3d10->hw.iface.featureLevel = d3d10->supportedFeatureLevel; + d3d10->hw.iface.D3DCompile = D3DCompile; + } +#endif + return d3d10; error: - free(d3d10); + d3d10_gfx_free(d3d10); return NULL; } +static void d3d10_init_history(d3d10_video_t* d3d10, unsigned width, unsigned height) +{ + unsigned i; + + /* todo: should we init history to max_width/max_height instead ? + * to prevent out of memory errors happening several frames later + * and to reduce memory fragmentation */ + + assert(d3d10->shader_preset); + for (i = 0; i < (unsigned)d3d10->shader_preset->history_size + 1; i++) + { + d3d10->frame.texture[i].desc.Width = width; + d3d10->frame.texture[i].desc.Height = height; + d3d10->frame.texture[i].desc.Format = d3d10->frame.texture[0].desc.Format; + d3d10->frame.texture[i].desc.Usage = d3d10->frame.texture[0].desc.Usage; + d3d10_init_texture(d3d10->device, &d3d10->frame.texture[i]); + /* todo: clear texture ? */ + } + d3d10->init_history = false; +} + +static void d3d10_init_render_targets(d3d10_video_t* d3d10, + unsigned width, unsigned height) +{ + unsigned i; + + assert(d3d10->shader_preset); + + for (i = 0; i < d3d10->shader_preset->passes; i++) + { + struct video_shader_pass* pass = &d3d10->shader_preset->pass[i]; + + if (pass->fbo.valid) + { + + switch (pass->fbo.type_x) + { + case RARCH_SCALE_INPUT: + width *= pass->fbo.scale_x; + break; + + case RARCH_SCALE_VIEWPORT: + width = d3d10->vp.width * pass->fbo.scale_x; + break; + + case RARCH_SCALE_ABSOLUTE: + width = pass->fbo.abs_x; + break; + + default: + break; + } + + if (!width) + width = d3d10->vp.width; + + switch (pass->fbo.type_y) + { + case RARCH_SCALE_INPUT: + height *= pass->fbo.scale_y; + break; + + case RARCH_SCALE_VIEWPORT: + height = d3d10->vp.height * pass->fbo.scale_y; + break; + + case RARCH_SCALE_ABSOLUTE: + height = pass->fbo.abs_y; + break; + + default: + break; + } + + if (!height) + height = d3d10->vp.height; + } + else if (i == (d3d10->shader_preset->passes - 1)) + { + width = d3d10->vp.width; + height = d3d10->vp.height; + } + + 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)) + { + d3d10->pass[i].viewport.Width = width; + d3d10->pass[i].viewport.Height = height; + d3d10->pass[i].viewport.MaxDepth = 1.0; + d3d10->pass[i].rt.desc.Width = width; + d3d10->pass[i].rt.desc.Height = height; + d3d10->pass[i].rt.desc.BindFlags = D3D10_BIND_RENDER_TARGET; + d3d10->pass[i].rt.desc.Format = glslang_format_to_dxgi(d3d10->pass[i].semantics.format); + d3d10_init_texture(d3d10->device, &d3d10->pass[i].rt); + + if (pass->feedback) + { + d3d10->pass[i].feedback.desc = d3d10->pass[i].rt.desc; + d3d10_init_texture(d3d10->device, &d3d10->pass[i].feedback); + /* todo: do we need to clear it to black here ? */ + } + } + else + { + d3d10->pass[i].rt.size_data.x = width; + d3d10->pass[i].rt.size_data.y = height; + d3d10->pass[i].rt.size_data.z = 1.0f / width; + d3d10->pass[i].rt.size_data.w = 1.0f / height; + } + } + + d3d10->resize_render_targets = false; + +#if 0 +error: + d3d10_free_shader_preset(d3d10); + return false; +#endif +} + static bool d3d10_gfx_frame( void* data, const void* frame, @@ -317,9 +1072,10 @@ static bool d3d10_gfx_frame( const char* msg, video_frame_info_t* video_info) { - (void)msg; - - d3d10_video_t* d3d10 = (d3d10_video_t*)data; + unsigned i; + d3d10_texture_t* texture = NULL; + d3d10_video_t * d3d10 = (d3d10_video_t*)data; + D3D10Device context = d3d10->device; if (d3d10->resize_chain) { @@ -337,71 +1093,291 @@ static bool d3d10_gfx_frame( d3d10->viewport.Width = video_info->width; d3d10->viewport.Height = video_info->height; + d3d10->ubo_values.OutputSize.width = d3d10->viewport.Width; + d3d10->ubo_values.OutputSize.height = d3d10->viewport.Height; + d3d10->resize_chain = false; d3d10->resize_viewport = true; + + video_driver_set_size(&video_info->width, &video_info->height); } PERF_START(); - D3D10ClearRenderTargetView(d3d10->device, d3d10->renderTargetView, d3d10->clearcolor); + +#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); + + D3D10SetPrimitiveTopology(context, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + +#if 0 + if (d3d10->hw.enable) + { + D3D10SetRenderTargets(context, 1, &d3d10->renderTargetView, NULL); + D3D10SetState(context, d3d10->state); + } +#endif if (frame && width && height) { - D3D10_BOX frame_box = { 0, 0, 0, width, height, 1 }; - - if (d3d10->frame.texture.desc.Width != width || d3d10->frame.texture.desc.Height != height) + if (d3d10->shader_preset) { - d3d10->frame.texture.desc.Width = width; - d3d10->frame.texture.desc.Height = height; - d3d10_init_texture(d3d10->device, &d3d10->frame.texture); + if (d3d10->frame.texture[0].desc.Width != width || + d3d10->frame.texture[0].desc.Height != height) + d3d10->resize_render_targets = true; + + if (d3d10->resize_render_targets) + { + unsigned i; + + /* release all render targets first to avoid memory fragmentation */ + for (i = 0; i < d3d10->shader_preset->passes; i++) + { + d3d10_release_texture(&d3d10->pass[i].rt); + d3d10_release_texture(&d3d10->pass[i].feedback); + memset(&d3d10->pass[i].rt, 0, sizeof(d3d10->pass[i].rt)); + memset(&d3d10->pass[i].feedback, 0, sizeof(d3d10->pass[i].feedback)); + } + } + + if (d3d10->shader_preset->history_size) + { + if (d3d10->init_history) + d3d10_init_history(d3d10, width, height); + else + { + int k; + /* todo: what about frame-duping ? + * maybe clone d3d10_texture_t with AddRef */ + d3d10_texture_t tmp = d3d10->frame.texture[d3d10->shader_preset->history_size]; + for (k = d3d10->shader_preset->history_size; k > 0; k--) + d3d10->frame.texture[k] = d3d10->frame.texture[k - 1]; + d3d10->frame.texture[0] = tmp; + } + } } - d3d10_update_texture(width, height, pitch, d3d10->format, frame, &d3d10->frame.texture); - D3D10CopyTexture2DSubresourceRegion( - d3d10->device, d3d10->frame.texture.handle, 0, 0, 0, 0, d3d10->frame.texture.staging, 0, - &frame_box); + /* 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.Width = width; + d3d10->frame.texture[0].desc.Height = height; + d3d10_init_texture(d3d10->device, &d3d10->frame.texture[0]); + } + + if (d3d10->resize_render_targets) + d3d10_init_render_targets(d3d10, width, height); + + if (frame != RETRO_HW_FRAME_BUFFER_VALID) + d3d10_update_texture( + d3d10->device, + width, height, pitch, d3d10->format, frame, &d3d10->frame.texture[0]); } + D3D10SetVertexBuffer(context, 0, d3d10->frame.vbo, sizeof(d3d10_vertex_t), 0); + D3D10SetBlendState(context, d3d10->blend_disable, NULL, D3D10_DEFAULT_SAMPLE_MASK); + + texture = d3d10->frame.texture; + + if (d3d10->shader_preset) { - UINT stride = sizeof(d3d10_vertex_t); - UINT offset = 0; -#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); + unsigned i; - D3D10SetViewports(d3d10->device, 1, &d3d10->frame.viewport); - D3D10SetVertexBuffers(d3d10->device, 0, 1, &d3d10->frame.vbo, &stride, &offset); - D3D10SetVShaderConstantBuffers(d3d10->device, 0, 1, &d3d10->frame.ubo); - D3D10SetPShaderResources(d3d10->device, 0, 1, &d3d10->frame.texture.view); - D3D10SetPShaderSamplers(d3d10->device, 0, 1, &d3d10->frame.sampler); - - D3D10SetBlendState(d3d10->device, d3d10->blend_disable, NULL, D3D10_DEFAULT_SAMPLE_MASK); - D3D10Draw(d3d10->device, 4, 0); - D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK); - - if (d3d10->menu.enabled && d3d10->menu.texture.handle) + for (i = 0; i < d3d10->shader_preset->passes; i++) { - if (d3d10->menu.texture.dirty) - D3D10CopyTexture2DSubresourceRegion( - d3d10->device, d3d10->menu.texture.handle, 0, 0, 0, 0, - d3d10->menu.texture.staging, 0, NULL); + if (d3d10->shader_preset->pass[i].feedback) + { + d3d10_texture_t tmp = d3d10->pass[i].feedback; + d3d10->pass[i].feedback = d3d10->pass[i].rt; + d3d10->pass[i].rt = tmp; + } + } - if (d3d10->menu.fullscreen) - D3D10SetViewports(d3d10->device, 1, &d3d10->viewport); - D3D10SetVertexBuffers(d3d10->device, 0, 1, &d3d10->menu.vbo, &stride, &offset); - D3D10SetVShaderConstantBuffers(d3d10->device, 0, 1, &d3d10->ubo); - D3D10SetPShaderResources(d3d10->device, 0, 1, &d3d10->menu.texture.view); - D3D10SetPShaderSamplers(d3d10->device, 0, 1, &d3d10->menu.sampler); + for (i = 0; i < d3d10->shader_preset->passes; i++) + { + unsigned j; - D3D10Draw(d3d10->device, 4, 0); + d3d10_set_shader(context, &d3d10->pass[i].shader); + + if (d3d10->shader_preset->pass[i].frame_count_mod) + d3d10->pass[i].frame_count = + frame_count % d3d10->shader_preset->pass[i].frame_count_mod; + else + d3d10->pass[i].frame_count = frame_count; + + for (j = 0; j < SLANG_CBUFFER_MAX; j++) + { + D3D10Buffer buffer = d3d10->pass[i].buffers[j]; + cbuffer_sem_t* buffer_sem = &d3d10->pass[i].semantics.cbuffers[j]; + + if (buffer_sem->stage_mask && buffer_sem->uniforms) + { + void* data; + uniform_sem_t* uniform = buffer_sem->uniforms; + + D3D10MapBuffer(buffer, D3D10_MAP_WRITE_DISCARD, 0, (void**)&data); + while (uniform->size) + { + if (uniform->data) + memcpy((uint8_t*)data + uniform->offset, uniform->data, uniform->size); + uniform++; + } + D3D10UnmapBuffer(buffer); + + if (buffer_sem->stage_mask & SLANG_STAGE_VERTEX_MASK) + D3D10SetVShaderConstantBuffers(context, buffer_sem->binding, 1, &buffer); + + if (buffer_sem->stage_mask & SLANG_STAGE_FRAGMENT_MASK) + D3D10SetPShaderConstantBuffers(context, buffer_sem->binding, 1, &buffer); + } + } + + { + D3D10RenderTargetView null_rt = NULL; + D3D10SetRenderTargets(context, 1, &null_rt, NULL); + } + + { + D3D10ShaderResourceView textures[SLANG_NUM_BINDINGS] = { NULL }; + D3D10SamplerState samplers[SLANG_NUM_BINDINGS] = { NULL }; + + texture_sem_t* texture_sem = d3d10->pass[i].semantics.textures; + while (texture_sem->stage_mask) + { + int binding = texture_sem->binding; + textures[binding] = *(D3D10ShaderResourceView*)texture_sem->texture_data; + samplers[binding] = d3d10->samplers[texture_sem->filter][texture_sem->wrap]; + texture_sem++; + } + +#if 0 + if (d3d10->hw.enable && (i == 0)) + D3D10SetPShaderResources(context, 1, SLANG_NUM_BINDINGS - 1, textures + 1); + else +#endif + D3D10SetPShaderResources(context, 0, SLANG_NUM_BINDINGS, textures); + + D3D10SetPShaderSamplers(context, 0, SLANG_NUM_BINDINGS, samplers); + } + + if (d3d10->pass[i].rt.handle) + { + D3D10SetRenderTargets(context, 1, &d3d10->pass[i].rt.rt_view, NULL); +#if 0 + D3D10ClearRenderTargetView(context, d3d10->pass[i].rt.rt_view, d3d10->clearcolor); +#endif + D3D10SetViewports(context, 1, &d3d10->pass[i].viewport); + + D3D10Draw(context, 4, 0); + texture = &d3d10->pass[i].rt; + } + else + { + texture = NULL; + break; + } + } + D3D10SetRenderTargets(context, 1, &d3d10->renderTargetView, NULL); + } + + if (texture) + { + d3d10_set_shader(context, &d3d10->shaders[VIDEO_SHADER_STOCK_BLEND]); +#if 0 + /* TODO/FIXME */ + if (!d3d10->hw.enable || d3d10->shader_preset) +#endif + D3D10SetPShaderResources(context, 0, 1, &texture->view); + D3D10SetPShaderSamplers( + context, 0, 1, &d3d10->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]); + D3D10SetVShaderConstantBuffers(context, 0, 1, &d3d10->frame.ubo); + } + + D3D10ClearRenderTargetView(context, d3d10->renderTargetView, d3d10->clearcolor); + D3D10SetViewports(context, 1, &d3d10->frame.viewport); + + D3D10Draw(context, 4, 0); + + D3D10SetBlendState(context, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK); + + if (d3d10->menu.enabled && d3d10->menu.texture.handle) + { + if (d3d10->menu.fullscreen) + D3D10SetViewports(context, 1, &d3d10->viewport); + + d3d10_set_shader(context, &d3d10->shaders[VIDEO_SHADER_STOCK_BLEND]); + D3D10SetVertexBuffer(context, 0, d3d10->menu.vbo, sizeof(d3d10_vertex_t), 0); + D3D10SetVShaderConstantBuffers(context, 0, 1, &d3d10->ubo); + d3d10_set_texture_and_sampler(context, 0, &d3d10->menu.texture); + D3D10Draw(context, 4, 0); + } + + d3d10_set_shader(context, &d3d10->sprites.shader); + D3D10SetPrimitiveTopology(context, D3D10_PRIMITIVE_TOPOLOGY_POINTLIST); + D3D10SetVShaderConstantBuffer(context, 0, d3d10->ubo); + D3D10SetPShaderConstantBuffer(context, 0, d3d10->ubo); + + d3d10->sprites.enabled = true; + +#ifdef HAVE_MENU + if (d3d10->menu.enabled) + { + D3D10SetViewports(context, 1, &d3d10->viewport); + D3D10SetVertexBuffer(context, 0, d3d10->sprites.vbo, sizeof(d3d10_sprite_t), 0); + menu_driver_frame(video_info); + } + 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); } } - DXGIPresent(d3d10->swapChain, !!d3d10->vsync, 0); - PERF_STOP(); +#ifdef HAVE_OVERLAY + if (d3d10->overlays.enabled) + { + if (d3d10->overlays.fullscreen) + D3D10SetViewports(context, 1, &d3d10->viewport); + else + D3D10SetViewports(context, 1, &d3d10->frame.viewport); + + D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK); + D3D10SetVertexBuffer(context, 0, d3d10->overlays.vbo, sizeof(d3d10_sprite_t), 0); + D3D10SetPShaderSamplers( + context, 0, 1, &d3d10->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]); + + for (i = 0; i < (unsigned)d3d10->overlays.count; i++) + { + D3D10SetPShaderResources(context, 0, 1, &d3d10->overlays.textures[i].view); + D3D10Draw(d3d10->device, 1, i); + } + } +#endif if (msg && *msg) + { + D3D10SetViewports(d3d10->device, 1, &d3d10->viewport); + D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK); + D3D10SetVertexBuffer(d3d10->device, 0, d3d10->sprites.vbo, sizeof(d3d10_sprite_t), 0); + font_driver_render_msg(video_info, NULL, msg, NULL); dxgi_update_title(video_info); + } + d3d10->sprites.enabled = false; + + PERF_STOP(); + DXGIPresent(d3d10->swapChain, !!d3d10->vsync, 0); return true; } @@ -409,6 +1385,10 @@ static bool d3d10_gfx_frame( static void d3d10_gfx_set_nonblock_state(void* data, bool toggle) { d3d10_video_t* d3d10 = (d3d10_video_t*)data; + + if (!d3d10) + return; + d3d10->vsync = !toggle; } @@ -440,45 +1420,14 @@ static bool d3d10_gfx_has_windowed(void* data) return true; } -static void d3d10_gfx_free(void* data) +static struct video_shader* d3d10_gfx_get_current_shader(void* data) { d3d10_video_t* d3d10 = (d3d10_video_t*)data; - Release(d3d10->frame.ubo); - Release(d3d10->frame.vbo); - Release(d3d10->frame.texture.view); - Release(d3d10->frame.texture.handle); - Release(d3d10->frame.texture.staging); + if (!d3d10) + return NULL; - Release(d3d10->menu.texture.handle); - Release(d3d10->menu.texture.staging); - Release(d3d10->menu.texture.view); - Release(d3d10->menu.vbo); - - Release(d3d10->ubo); - Release(d3d10->blend_enable); - Release(d3d10->blend_disable); - Release(d3d10->sampler_nearest); - Release(d3d10->sampler_linear); - Release(d3d10->ps); - Release(d3d10->vs); - Release(d3d10->layout); - Release(d3d10->renderTargetView); - Release(d3d10->swapChain); - Release(d3d10->device); - - win32_monitor_from_window(); - win32_destroy_window(); - free(d3d10); -} - -static bool d3d10_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path) -{ - (void)data; - (void)type; - (void)path; - - return false; + return d3d10->shader_preset; } static void d3d10_gfx_viewport_info(void* data, struct video_viewport* vp) @@ -499,26 +1448,35 @@ static bool d3d10_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle) static void d3d10_set_menu_texture_frame( void* data, const void* frame, bool rgb32, unsigned width, unsigned height, float alpha) { - d3d10_video_t* d3d10 = (d3d10_video_t*)data; - int pitch = width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)); - DXGI_FORMAT format = rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM : (DXGI_FORMAT)DXGI_FORMAT_EX_A4R4G4B4_UNORM; + d3d10_video_t* d3d10 = (d3d10_video_t*)data; + settings_t* settings = config_get_ptr(); + DXGI_FORMAT format = rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM : + (DXGI_FORMAT)DXGI_FORMAT_EX_A4R4G4B4_UNORM; - if (d3d10->menu.texture.desc.Width != width || d3d10->menu.texture.desc.Height != height) + if ( + d3d10->menu.texture.desc.Width != width || + d3d10->menu.texture.desc.Height != height) { - d3d10->menu.texture.desc.Format = d3d10_get_closest_match_texture2D(d3d10->device, format); + d3d10->menu.texture.desc.Format = format; d3d10->menu.texture.desc.Width = width; d3d10->menu.texture.desc.Height = height; d3d10_init_texture(d3d10->device, &d3d10->menu.texture); } - d3d10_update_texture(width, height, pitch, format, frame, &d3d10->menu.texture); - d3d10->menu.sampler = config_get_ptr()->bools.menu_linear_filter ? d3d10->sampler_linear - : d3d10->sampler_nearest; + d3d10_update_texture(d3d10->device, width, height, 0, + format, frame, &d3d10->menu.texture); + d3d10->menu.texture.sampler = d3d10->samplers + [settings->bools.menu_linear_filter + ? RARCH_FILTER_LINEAR + : RARCH_FILTER_NEAREST][RARCH_WRAP_DEFAULT]; } static void d3d10_set_menu_texture_enable(void* data, bool state, bool full_screen) { d3d10_video_t* d3d10 = (d3d10_video_t*)data; + if (!d3d10) + return; + d3d10->menu.enabled = state; d3d10->menu.fullscreen = full_screen; } @@ -538,18 +1496,110 @@ static void d3d10_gfx_apply_state_changes(void* data) { d3d10_video_t* d3d10 = (d3d10_video_t*)data; -#if 0 if (d3d10) d3d10->resize_viewport = true; +} + +static void d3d10_gfx_set_osd_msg( + void* data, video_frame_info_t* video_info, const char* msg, const void* params, void* font) +{ + d3d10_video_t* d3d10 = (d3d10_video_t*)data; + + if (d3d10) + { + if (d3d10->sprites.enabled) + font_driver_render_msg(video_info, font, msg, (const struct font_params*)params); + else + printf("OSD msg: %s\n", msg); + } +} + +static void d3d10_gfx_show_mouse(void* data, bool state) { win32_show_cursor(state); } + +static uintptr_t d3d10_gfx_load_texture( + void* video_data, void* data, bool threaded, enum texture_filter_type filter_type) +{ + d3d10_texture_t* texture = NULL; + d3d10_video_t* d3d10 = (d3d10_video_t*)video_data; + struct texture_image* image = (struct texture_image*)data; + + if (!d3d10) + return 0; + + texture = (d3d10_texture_t*)calloc(1, sizeof(*texture)); + + if (!texture) + return 0; + + switch (filter_type) + { + case TEXTURE_FILTER_MIPMAP_LINEAR: + texture->desc.MiscFlags = D3D10_RESOURCE_MISC_GENERATE_MIPS; + /* fallthrough */ + case TEXTURE_FILTER_LINEAR: + texture->sampler = d3d10->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_EDGE]; + break; + case TEXTURE_FILTER_MIPMAP_NEAREST: + texture->desc.MiscFlags = D3D10_RESOURCE_MISC_GENERATE_MIPS; + /* fallthrough */ + case TEXTURE_FILTER_NEAREST: + texture->sampler = d3d10->samplers[RARCH_FILTER_NEAREST][RARCH_WRAP_EDGE]; + break; + } + + texture->desc.Width = image->width; + texture->desc.Height = image->height; + texture->desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + + d3d10_init_texture(d3d10->device, texture); + + d3d10_update_texture( + d3d10->device, + image->width, image->height, 0, DXGI_FORMAT_B8G8R8A8_UNORM, image->pixels, + texture); + + return (uintptr_t)texture; +} +static void d3d10_gfx_unload_texture(void* data, uintptr_t handle) +{ + d3d10_texture_t* texture = (d3d10_texture_t*)handle; + + if (!texture) + return; + + Release(texture->view); + Release(texture->staging); + Release(texture->handle); + free(texture); +} + +#if 0 +static bool +d3d10_get_hw_render_interface(void* data, const struct retro_hw_render_interface** iface) +{ + d3d10_video_t* d3d10 = (d3d10_video_t*)data; + *iface = (const struct retro_hw_render_interface*)&d3d10->hw.iface; + return d3d10->hw.enable; +} #endif + +static uint32_t d3d10_get_flags(void *data) +{ + uint32_t flags = 0; + + BIT32_SET(flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING); + + return flags; } static const video_poke_interface_t d3d10_poke_interface = { + d3d10_get_flags, NULL, /* set_coords */ NULL, /* set_mvp */ - NULL, /* load_texture */ - NULL, /* unload_texture */ + d3d10_gfx_load_texture, + d3d10_gfx_unload_texture, NULL, /* set_video_mode */ + win32_get_refresh_rate, d3d10_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ @@ -560,12 +1610,16 @@ static const video_poke_interface_t d3d10_poke_interface = { d3d10_gfx_apply_state_changes, d3d10_set_menu_texture_frame, d3d10_set_menu_texture_enable, - NULL, /* set_osd_msg */ - NULL, /* show_mouse */ + d3d10_gfx_set_osd_msg, + d3d10_gfx_show_mouse, NULL, /* grab_mouse_toggle */ - NULL, /* get_current_shader */ + d3d10_gfx_get_current_shader, NULL, /* get_current_software_framebuffer */ +#if 0 + d3d10_get_hw_render_interface, +#else NULL, /* get_hw_render_interface */ +#endif }; static void d3d10_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface) @@ -591,7 +1645,7 @@ video_driver_t video_d3d10 = { NULL, /* read_frame_raw */ #ifdef HAVE_OVERLAY - NULL, /* overlay_interface */ + d3d10_get_overlay_interface, #endif d3d10_gfx_get_poke_interface, }; diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index cddf096d83..e9fc4b71f1 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2014-2018 - Ali Bouhlel * * RetroArch is free software: you can redistribute it and/or modify it under the terms @@ -19,6 +19,7 @@ #include #include +#include #include #include "../../driver.h" @@ -48,7 +49,7 @@ static D3D11DeviceContext cached_context; static void d3d11_free_overlays(d3d11_video_t* d3d11) { unsigned i; - for (i = 0; i < d3d11->overlays.count; i++) + for (i = 0; i < (unsigned)d3d11->overlays.count; i++) d3d11_release_texture(&d3d11->overlays.textures[i]); Release(d3d11->overlays.vbo); @@ -117,9 +118,10 @@ static void d3d11_overlay_set_alpha(void* data, unsigned index, float mod) static bool d3d11_overlay_load(void* data, const void* image_data, unsigned num_images) { - int i; - d3d11_sprite_t* sprites; + D3D11_BUFFER_DESC desc; D3D11_MAPPED_SUBRESOURCE mapped_vbo; + unsigned i; + d3d11_sprite_t* sprites; d3d11_video_t* d3d11 = (d3d11_video_t*)data; const struct texture_image* images = (const struct texture_image*)image_data; @@ -128,19 +130,19 @@ static bool d3d11_overlay_load(void* data, const void* image_data, unsigned num_ d3d11_free_overlays(d3d11); d3d11->overlays.count = num_images; - d3d11->overlays.textures = (d3d11_texture_t*)calloc(num_images, sizeof(d3d11_texture_t)); + d3d11->overlays.textures = (d3d11_texture_t*)calloc( + num_images, sizeof(d3d11_texture_t)); - { - D3D11_BUFFER_DESC desc = { sizeof(d3d11_sprite_t) * num_images }; - desc.Usage = D3D11_USAGE_DYNAMIC; - - desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - D3D11CreateBuffer(d3d11->device, &desc, NULL, &d3d11->overlays.vbo); - } + desc.ByteWidth = sizeof(d3d11_sprite_t) * num_images; + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + desc.StructureByteStride = 0; + D3D11CreateBuffer(d3d11->device, &desc, NULL, &d3d11->overlays.vbo); D3D11MapBuffer(d3d11->context, d3d11->overlays.vbo, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_vbo); - sprites = (d3d11_sprite_t*)mapped_vbo.pData; + sprites = (d3d11_sprite_t*)mapped_vbo.pData; for (i = 0; i < num_images; i++) { @@ -152,26 +154,27 @@ static bool d3d11_overlay_load(void* data, const void* image_data, unsigned num_ d3d11_init_texture(d3d11->device, &d3d11->overlays.textures[i]); d3d11_update_texture( - d3d11->context, images[i].width, images[i].height, 0, DXGI_FORMAT_B8G8R8A8_UNORM, + d3d11->context, images[i].width, + images[i].height, 0, DXGI_FORMAT_B8G8R8A8_UNORM, images[i].pixels, &d3d11->overlays.textures[i]); - sprites[i].pos.x = 0.0f; - sprites[i].pos.y = 0.0f; - sprites[i].pos.w = 1.0f; - sprites[i].pos.h = 1.0f; + sprites[i].pos.x = 0.0f; + sprites[i].pos.y = 0.0f; + sprites[i].pos.w = 1.0f; + sprites[i].pos.h = 1.0f; - sprites[i].coords.u = 0.0f; - sprites[i].coords.v = 0.0f; - sprites[i].coords.w = 1.0f; - sprites[i].coords.h = 1.0f; + sprites[i].coords.u = 0.0f; + sprites[i].coords.v = 0.0f; + sprites[i].coords.w = 1.0f; + sprites[i].coords.h = 1.0f; sprites[i].params.scaling = 1; sprites[i].params.rotation = 0; - sprites[i].colors[0] = 0xFFFFFFFF; - sprites[i].colors[1] = sprites[i].colors[0]; - sprites[i].colors[2] = sprites[i].colors[0]; - sprites[i].colors[3] = sprites[i].colors[0]; + sprites[i].colors[0] = 0xFFFFFFFF; + sprites[i].colors[1] = sprites[i].colors[0]; + sprites[i].colors[2] = sprites[i].colors[0]; + sprites[i].colors[3] = sprites[i].colors[0]; } D3D11UnmapBuffer(d3d11->context, d3d11->overlays.vbo, 0); @@ -293,7 +296,7 @@ static void d3d11_free_shader_preset(d3d11_video_t* d3d11) memset(d3d11->pass, 0, sizeof(d3d11->pass)); /* only free the history textures here */ - for (i = 1; i <= d3d11->shader_preset->history_size; i++) + for (i = 1; i <= (unsigned)d3d11->shader_preset->history_size; i++) d3d11_release_texture(&d3d11->frame.texture[i]); memset( @@ -386,7 +389,7 @@ 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, 50, &semantics_map, + d3d11->shader_preset, i, RARCH_SHADER_HLSL, 40, &semantics_map, &d3d11->pass[i].semantics)) goto error; @@ -574,9 +577,9 @@ static void* d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) { unsigned i; - WNDCLASSEX wndclass = { 0 }; MONITORINFOEX current_mon; HMONITOR hm_to_use; + WNDCLASSEX wndclass = { 0 }; settings_t* settings = config_get_ptr(); d3d11_video_t* d3d11 = (d3d11_video_t*)calloc(1, sizeof(*d3d11)); @@ -607,9 +610,16 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i dxgi_input_driver(settings->arrays.input_joypad_driver, input, input_data); { - UINT flags = 0; - D3D_FEATURE_LEVEL requested_feature_level = D3D_FEATURE_LEVEL_11_0; - DXGI_SWAP_CHAIN_DESC desc = { 0 }; + UINT flags = 0; + D3D_FEATURE_LEVEL + requested_feature_levels[] = + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0 + }; + DXGI_SWAP_CHAIN_DESC desc = { 0 }; + UINT number_feature_levels = ARRAY_SIZE(requested_feature_levels); desc.BufferCount = 1; desc.BufferDesc.Width = d3d11->vp.full_width; @@ -634,18 +644,22 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i #endif if(cached_device_d3d11 && cached_context) { - IDXGIFactory* dxgiFactory = NULL; - IDXGIDevice* dxgiDevice = NULL; - IDXGIAdapter* adapter = NULL; + IDXGIFactory* dxgiFactory = NULL; + IDXGIDevice* dxgiDevice = NULL; + IDXGIAdapter* adapter = NULL; - d3d11->device = cached_device_d3d11; - d3d11->context = cached_context; + d3d11->device = cached_device_d3d11; + d3d11->context = cached_context; d3d11->supportedFeatureLevel = cached_supportedFeatureLevel; - d3d11->device->lpVtbl->QueryInterface(d3d11->device, uuidof(IDXGIDevice), (void**)&dxgiDevice); + d3d11->device->lpVtbl->QueryInterface( + d3d11->device, uuidof(IDXGIDevice), (void**)&dxgiDevice); dxgiDevice->lpVtbl->GetAdapter(dxgiDevice, &adapter); - adapter->lpVtbl->GetParent(adapter, uuidof(IDXGIFactory1), (void**)&dxgiFactory); - dxgiFactory->lpVtbl->CreateSwapChain(dxgiFactory, (IUnknown*)d3d11->device, &desc, (IDXGISwapChain**)&d3d11->swapChain); + adapter->lpVtbl->GetParent( + adapter, uuidof(IDXGIFactory1), (void**)&dxgiFactory); + dxgiFactory->lpVtbl->CreateSwapChain( + dxgiFactory, (IUnknown*)d3d11->device, + &desc, (IDXGISwapChain**)&d3d11->swapChain); dxgiFactory->lpVtbl->Release(dxgiFactory); adapter->lpVtbl->Release(adapter); @@ -653,10 +667,13 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i } else { - D3D11CreateDeviceAndSwapChain( - NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, &requested_feature_level, 1, - D3D11_SDK_VERSION, &desc, (IDXGISwapChain**)&d3d11->swapChain, &d3d11->device, - &d3d11->supportedFeatureLevel, &d3d11->context); + 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; } } @@ -675,12 +692,14 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i d3d11->viewport.Height = d3d11->vp.full_height; d3d11->resize_viewport = true; d3d11->vsync = video->vsync; - d3d11->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM; + d3d11->format = video->rgb32 ? + DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM; d3d11->frame.texture[0].desc.Format = d3d11->format; d3d11->frame.texture[0].desc.Usage = D3D11_USAGE_DEFAULT; d3d11->frame.texture[0].desc.Width = 4; d3d11->frame.texture[0].desc.Height = 4; + d3d11_init_texture(d3d11->device, &d3d11->frame.texture[0]); d3d11->menu.texture.desc.Usage = D3D11_USAGE_DEFAULT; @@ -752,29 +771,31 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i d3d11_set_filtering(d3d11, 0, video->smooth); { + D3D11_BUFFER_DESC desc; d3d11_vertex_t vertices[] = { { { 0.0f, 0.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 0.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, }; + D3D11_SUBRESOURCE_DATA + vertexData = { vertices }; - { - D3D11_BUFFER_DESC desc = { 0 }; - desc.Usage = D3D11_USAGE_IMMUTABLE; - desc.ByteWidth = sizeof(vertices); - desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + desc.ByteWidth = sizeof(vertices); + desc.Usage = D3D11_USAGE_IMMUTABLE; + desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + desc.StructureByteStride = 0; - D3D11_SUBRESOURCE_DATA vertexData = { vertices }; - D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->frame.vbo); - desc.Usage = D3D11_USAGE_DYNAMIC; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->menu.vbo); + D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->frame.vbo); + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->menu.vbo); - d3d11->sprites.capacity = 4096; - desc.ByteWidth = sizeof(d3d11_sprite_t) * d3d11->sprites.capacity; - D3D11CreateBuffer(d3d11->device, &desc, NULL, &d3d11->sprites.vbo); - } + d3d11->sprites.capacity = 4096; + desc.ByteWidth = sizeof(d3d11_sprite_t) * d3d11->sprites.capacity; + D3D11CreateBuffer(d3d11->device, &desc, NULL, &d3d11->sprites.vbo); } { @@ -829,68 +850,71 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i goto error; } + if (string_is_equal(settings->arrays.menu_driver, "xmb")) { - D3D11_INPUT_ELEMENT_DESC desc[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; + { + D3D11_INPUT_ELEMENT_DESC desc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; - static const char ribbon[] = + static const char ribbon[] = #include "d3d_shaders/ribbon_sm4.hlsl.h" ; - static const char ribbon_simple[] = + static const char ribbon_simple[] = #include "d3d_shaders/ribbon_simple_sm4.hlsl.h" ; - if (!d3d11_init_shader( - d3d11->device, ribbon, sizeof(ribbon), NULL, "VSMain", "PSMain", NULL, desc, - countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU])) - goto error; + if (!d3d11_init_shader( + d3d11->device, ribbon, sizeof(ribbon), NULL, "VSMain", "PSMain", NULL, desc, + countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU])) + goto error; - if (!d3d11_init_shader( - d3d11->device, ribbon_simple, sizeof(ribbon_simple), NULL, "VSMain", "PSMain", NULL, - desc, countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_2])) - goto error; - } + if (!d3d11_init_shader( + d3d11->device, ribbon_simple, sizeof(ribbon_simple), NULL, "VSMain", "PSMain", NULL, + desc, countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_2])) + goto error; + } - { - D3D11_INPUT_ELEMENT_DESC desc[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, position), - 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_ELEMENT_DESC desc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, position), + D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, texcoord), + D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; - static const char simple_snow[] = + static const char simple_snow[] = #include "d3d_shaders/simple_snow_sm4.hlsl.h" ; - static const char snow[] = + static const char snow[] = #include "d3d_shaders/snow_sm4.hlsl.h" ; - static const char bokeh[] = + static const char bokeh[] = #include "d3d_shaders/bokeh_sm4.hlsl.h" ; - static const char snowflake[] = + static const char snowflake[] = #include "d3d_shaders/snowflake_sm4.hlsl.h" ; - if (!d3d11_init_shader( - d3d11->device, simple_snow, sizeof(simple_snow), NULL, "VSMain", "PSMain", NULL, - desc, countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_3])) - goto error; - if (!d3d11_init_shader( - d3d11->device, snow, sizeof(snow), NULL, "VSMain", "PSMain", NULL, desc, - countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_4])) - goto error; + if (!d3d11_init_shader( + d3d11->device, simple_snow, sizeof(simple_snow), NULL, "VSMain", "PSMain", NULL, + desc, countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_3])) + goto error; + if (!d3d11_init_shader( + d3d11->device, snow, sizeof(snow), NULL, "VSMain", "PSMain", NULL, desc, + countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_4])) + goto error; - if (!d3d11_init_shader( - d3d11->device, bokeh, sizeof(bokeh), NULL, "VSMain", "PSMain", NULL, desc, - countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_5])) - goto error; + if (!d3d11_init_shader( + d3d11->device, bokeh, sizeof(bokeh), NULL, "VSMain", "PSMain", NULL, desc, + countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_5])) + goto error; - if (!d3d11_init_shader( - d3d11->device, snowflake, sizeof(snowflake), NULL, "VSMain", "PSMain", NULL, desc, - countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_6])) - goto error; + if (!d3d11_init_shader( + d3d11->device, snowflake, sizeof(snowflake), NULL, "VSMain", "PSMain", NULL, desc, + countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_6])) + goto error; + } } { @@ -964,7 +988,7 @@ static void d3d11_init_history(d3d11_video_t* d3d11, unsigned width, unsigned he * and to reduce memory fragmentation */ assert(d3d11->shader_preset); - for (i = 0; i < d3d11->shader_preset->history_size + 1; i++) + for (i = 0; i < (unsigned)d3d11->shader_preset->history_size + 1; i++) { d3d11->frame.texture[i].desc.Width = width; d3d11->frame.texture[i].desc.Height = height; @@ -975,6 +999,7 @@ static void d3d11_init_history(d3d11_video_t* d3d11, unsigned width, unsigned he } d3d11->init_history = false; } + static void d3d11_init_render_targets(d3d11_video_t* d3d11, unsigned width, unsigned height) { unsigned i; @@ -1356,7 +1381,7 @@ static bool d3d11_gfx_frame( D3D11SetPShaderSamplers( context, 0, 1, &d3d11->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]); - for (i = 0; i < d3d11->overlays.count; i++) + for (i = 0; i < (unsigned)d3d11->overlays.count; i++) { D3D11SetPShaderResources(context, 0, 1, &d3d11->overlays.textures[i].view); D3D11Draw(d3d11->context, 1, i); @@ -1446,11 +1471,14 @@ static bool d3d11_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle) static void d3d11_set_menu_texture_frame( void* data, const void* frame, bool rgb32, unsigned width, unsigned height, float alpha) { - d3d11_video_t* d3d11 = (d3d11_video_t*)data; - DXGI_FORMAT format = - rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM : (DXGI_FORMAT)DXGI_FORMAT_EX_A4R4G4B4_UNORM; + d3d11_video_t* d3d11 = (d3d11_video_t*)data; + settings_t* settings = config_get_ptr(); + DXGI_FORMAT format = rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM : + (DXGI_FORMAT)DXGI_FORMAT_EX_A4R4G4B4_UNORM; - if (d3d11->menu.texture.desc.Width != width || d3d11->menu.texture.desc.Height != height) + if ( + d3d11->menu.texture.desc.Width != width || + d3d11->menu.texture.desc.Height != height) { d3d11->menu.texture.desc.Format = format; d3d11->menu.texture.desc.Width = width; @@ -1458,11 +1486,12 @@ static void d3d11_set_menu_texture_frame( d3d11_init_texture(d3d11->device, &d3d11->menu.texture); } - d3d11_update_texture(d3d11->context, width, height, 0, format, frame, &d3d11->menu.texture); + d3d11_update_texture(d3d11->context, width, height, 0, + format, frame, &d3d11->menu.texture); d3d11->menu.texture.sampler = d3d11->samplers - [config_get_ptr()->bools.menu_linear_filter - ? RARCH_FILTER_LINEAR - : RARCH_FILTER_NEAREST][RARCH_WRAP_DEFAULT]; + [settings->bools.menu_linear_filter + ? RARCH_FILTER_LINEAR + : RARCH_FILTER_NEAREST][RARCH_WRAP_DEFAULT]; } static void d3d11_set_menu_texture_enable(void* data, bool state, bool full_screen) @@ -1575,12 +1604,23 @@ d3d11_get_hw_render_interface(void* data, const struct retro_hw_render_interface return d3d11->hw.enable; } +static uint32_t d3d11_get_flags(void *data) +{ + uint32_t flags = 0; + + BIT32_SET(flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING); + + return flags; +} + static const video_poke_interface_t d3d11_poke_interface = { + d3d11_get_flags, NULL, /* set_coords */ NULL, /* set_mvp */ d3d11_gfx_load_texture, d3d11_gfx_unload_texture, NULL, /* set_video_mode */ + win32_get_refresh_rate, d3d11_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index 2b942fc868..4f7e884c0c 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -48,7 +48,7 @@ static void d3d12_gfx_sync(d3d12_video_t* d3d12) static void d3d12_free_overlays(d3d12_video_t* d3d12) { unsigned i; - for (i = 0; i < d3d12->overlays.count; i++) + for (i = 0; i < (unsigned)d3d12->overlays.count; i++) d3d12_release_texture(&d3d12->overlays.textures[i]); Release(d3d12->overlays.vbo); @@ -120,7 +120,7 @@ static void d3d12_overlay_set_alpha(void* data, unsigned index, float mod) static bool d3d12_overlay_load(void* data, const void* image_data, unsigned num_images) { - int i; + unsigned i; d3d12_sprite_t* sprites = NULL; D3D12_RANGE range = { 0, 0 }; d3d12_video_t* d3d12 = (d3d12_video_t*)data; @@ -304,7 +304,7 @@ static void d3d12_free_shader_preset(d3d12_video_t* d3d12) memset(d3d12->pass, 0, sizeof(d3d12->pass)); /* only free the history textures here */ - for (i = 1; i <= d3d12->shader_preset->history_size; i++) + for (i = 1; i <= (unsigned)d3d12->shader_preset->history_size; i++) d3d12_release_texture(&d3d12->frame.texture[i]); memset( @@ -544,6 +544,7 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12) D3DBlob ps_code = NULL; D3DBlob gs_code = NULL; D3DBlob cs_code = NULL; + settings_t * settings = config_get_ptr(); D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = { d3d12->desc.rootSignature }; desc.BlendState.RenderTarget[0] = d3d12_blend_enable_desc; @@ -643,134 +644,137 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12) gs_code = NULL; } + if (string_is_equal(settings->arrays.menu_driver, "xmb")) { - static const char simple_snow[] = -#include "d3d_shaders/simple_snow_sm4.hlsl.h" - ; - static const char snow[] = -#include "d3d_shaders/snow_sm4.hlsl.h" - ; - static const char bokeh[] = -#include "d3d_shaders/bokeh_sm4.hlsl.h" - ; - static const char snowflake[] = -#include "d3d_shaders/snowflake_sm4.hlsl.h" - ; - - D3D12_INPUT_ELEMENT_DESC inputElementDesc[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, position), - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, texcoord), - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - }; - - desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - desc.InputLayout.pInputElementDescs = inputElementDesc; - desc.InputLayout.NumElements = countof(inputElementDesc); - - if (!d3d_compile(simple_snow, sizeof(simple_snow), NULL, "VSMain", "vs_5_0", &vs_code)) - goto error; - if (!d3d_compile(simple_snow, sizeof(simple_snow), NULL, "PSMain", "ps_5_0", &ps_code)) - goto error; - - if (!d3d12_init_pipeline( - d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_3])) - goto error; - - Release(vs_code); - Release(ps_code); - vs_code = NULL; - ps_code = NULL; - - if (!d3d_compile(snow, sizeof(snow), NULL, "VSMain", "vs_5_0", &vs_code)) - goto error; - if (!d3d_compile(snow, sizeof(snow), NULL, "PSMain", "ps_5_0", &ps_code)) - goto error; - - if (!d3d12_init_pipeline( - d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_4])) - goto error; - - Release(vs_code); - Release(ps_code); - vs_code = NULL; - ps_code = NULL; - - if (!d3d_compile(bokeh, sizeof(bokeh), NULL, "VSMain", "vs_5_0", &vs_code)) - goto error; - if (!d3d_compile(bokeh, sizeof(bokeh), NULL, "PSMain", "ps_5_0", &ps_code)) - goto error; - - if (!d3d12_init_pipeline( - d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_5])) - goto error; - - Release(vs_code); - Release(ps_code); - vs_code = NULL; - ps_code = NULL; - - if (!d3d_compile(snowflake, sizeof(snowflake), NULL, "VSMain", "vs_5_0", &vs_code)) - goto error; - if (!d3d_compile(snowflake, sizeof(snowflake), NULL, "PSMain", "ps_5_0", &ps_code)) - goto error; - - if (!d3d12_init_pipeline( - d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_6])) - goto error; - - Release(vs_code); - Release(ps_code); - vs_code = NULL; - ps_code = NULL; - } - - { - static const char ribbon[] = + { + static const char ribbon[] = #include "d3d_shaders/ribbon_sm4.hlsl.h" ; - static const char ribbon_simple[] = + static const char ribbon_simple[] = #include "d3d_shaders/ribbon_simple_sm4.hlsl.h" ; - D3D12_INPUT_ELEMENT_DESC inputElementDesc[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - }; + D3D12_INPUT_ELEMENT_DESC inputElementDesc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; - desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE; - desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_ONE; - desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - desc.InputLayout.pInputElementDescs = inputElementDesc; - desc.InputLayout.NumElements = countof(inputElementDesc); + desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE; + desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_ONE; + desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + desc.InputLayout.pInputElementDescs = inputElementDesc; + desc.InputLayout.NumElements = countof(inputElementDesc); - if (!d3d_compile(ribbon, sizeof(ribbon), NULL, "VSMain", "vs_5_0", &vs_code)) - goto error; - if (!d3d_compile(ribbon, sizeof(ribbon), NULL, "PSMain", "ps_5_0", &ps_code)) - goto error; + if (!d3d_compile(ribbon, sizeof(ribbon), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(ribbon, sizeof(ribbon), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; - if (!d3d12_init_pipeline( - d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU])) - goto error; + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU])) + goto error; - Release(vs_code); - Release(ps_code); - vs_code = NULL; - ps_code = NULL; + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; - if (!d3d_compile(ribbon_simple, sizeof(ribbon_simple), NULL, "VSMain", "vs_5_0", &vs_code)) - goto error; - if (!d3d_compile(ribbon_simple, sizeof(ribbon_simple), NULL, "PSMain", "ps_5_0", &ps_code)) - goto error; + if (!d3d_compile(ribbon_simple, sizeof(ribbon_simple), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(ribbon_simple, sizeof(ribbon_simple), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; - if (!d3d12_init_pipeline( - d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_2])) - goto error; + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_2])) + goto error; - Release(vs_code); - Release(ps_code); - vs_code = NULL; - ps_code = NULL; + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; + } + + { + static const char simple_snow[] = +#include "d3d_shaders/simple_snow_sm4.hlsl.h" + ; + static const char snow[] = +#include "d3d_shaders/snow_sm4.hlsl.h" + ; + static const char bokeh[] = +#include "d3d_shaders/bokeh_sm4.hlsl.h" + ; + static const char snowflake[] = +#include "d3d_shaders/snowflake_sm4.hlsl.h" + ; + + D3D12_INPUT_ELEMENT_DESC inputElementDesc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, position), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, texcoord), + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; + + desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + desc.InputLayout.pInputElementDescs = inputElementDesc; + desc.InputLayout.NumElements = countof(inputElementDesc); + + if (!d3d_compile(simple_snow, sizeof(simple_snow), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(simple_snow, sizeof(simple_snow), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_3])) + goto error; + + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; + + if (!d3d_compile(snow, sizeof(snow), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(snow, sizeof(snow), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_4])) + goto error; + + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; + + if (!d3d_compile(bokeh, sizeof(bokeh), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(bokeh, sizeof(bokeh), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_5])) + goto error; + + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; + + if (!d3d_compile(snowflake, sizeof(snowflake), NULL, "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile(snowflake, sizeof(snowflake), NULL, "PSMain", "ps_5_0", &ps_code)) + goto error; + + if (!d3d12_init_pipeline( + d3d12->device, vs_code, ps_code, NULL, &desc, &d3d12->pipes[VIDEO_SHADER_MENU_6])) + goto error; + + Release(vs_code); + Release(ps_code); + vs_code = NULL; + ps_code = NULL; + } } { @@ -871,9 +875,9 @@ static void d3d12_gfx_free(void* data) static void* d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) { - WNDCLASSEX wndclass = { 0 }; MONITORINFOEX current_mon; HMONITOR hm_to_use; + WNDCLASSEX wndclass = { 0 }; settings_t* settings = config_get_ptr(); d3d12_video_t* d3d12 = (d3d12_video_t*)calloc(1, sizeof(*d3d12)); @@ -993,7 +997,7 @@ static void d3d12_init_history(d3d12_video_t* d3d12, unsigned width, unsigned he * and to reduce memory fragmentation */ assert(d3d12->shader_preset); - for (i = 0; i < d3d12->shader_preset->history_size + 1; i++) + for (i = 0; i < (unsigned)d3d12->shader_preset->history_size + 1; i++) { d3d12->frame.texture[i].desc.Width = width; d3d12->frame.texture[i].desc.Height = height; @@ -1298,19 +1302,20 @@ static bool d3d12_gfx_frame( while (texture_sem->stage_mask) { { - D3D12_CPU_DESCRIPTOR_HANDLE handle = { + D3D12_CPU_DESCRIPTOR_HANDLE handle = { d3d12->pass[i].textures.ptr - d3d12->desc.srv_heap.gpu.ptr + - d3d12->desc.srv_heap.cpu.ptr + - texture_sem->binding * d3d12->desc.srv_heap.stride + d3d12->desc.srv_heap.cpu.ptr + + texture_sem->binding * d3d12->desc.srv_heap.stride }; - d3d12_texture_t* tex = texture_sem->texture_data; + d3d12_texture_t* tex = (d3d12_texture_t*)texture_sem->texture_data; D3D12_SHADER_RESOURCE_VIEW_DESC desc = { tex->desc.Format }; - desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - desc.Texture2D.MipLevels = tex->desc.MipLevels; + desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipLevels = tex->desc.MipLevels; - D3D12CreateShaderResourceView(d3d12->device, tex->handle, &desc, handle); + D3D12CreateShaderResourceView(d3d12->device, + tex->handle, &desc, handle); } { @@ -1491,7 +1496,7 @@ static bool d3d12_gfx_frame( d3d12->queue.cmd, ROOT_ID_SAMPLER_T, d3d12->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]); - for (i = 0; i < d3d12->overlays.count; i++) + for (i = 0; i < (unsigned)d3d12->overlays.count; i++) { if (d3d12->overlays.textures[i].dirty) d3d12_upload_texture(d3d12->queue.cmd, @@ -1596,14 +1601,19 @@ static bool d3d12_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle) } static void d3d12_set_menu_texture_frame( - void* data, const void* frame, bool rgb32, unsigned width, unsigned height, float alpha) + void* data, const void* frame, bool rgb32, + unsigned width, unsigned height, float alpha) { - d3d12_video_t* d3d12 = (d3d12_video_t*)data; - int pitch = width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)); - DXGI_FORMAT format = - rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM : (DXGI_FORMAT)DXGI_FORMAT_EX_A4R4G4B4_UNORM; + d3d12_video_t* d3d12 = (d3d12_video_t*)data; + settings_t* settings = config_get_ptr(); + int pitch = width * + (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)); + DXGI_FORMAT format = rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM + : (DXGI_FORMAT)DXGI_FORMAT_EX_A4R4G4B4_UNORM; - if (d3d12->menu.texture.desc.Width != width || d3d12->menu.texture.desc.Height != height) + if ( + d3d12->menu.texture.desc.Width != width || + d3d12->menu.texture.desc.Height != height) { d3d12->menu.texture.desc.Width = width; d3d12->menu.texture.desc.Height = height; @@ -1612,13 +1622,14 @@ static void d3d12_set_menu_texture_frame( d3d12_init_texture(d3d12->device, &d3d12->menu.texture); } - d3d12_update_texture(width, height, pitch, format, frame, &d3d12->menu.texture); + d3d12_update_texture(width, height, pitch, + format, frame, &d3d12->menu.texture); d3d12->menu.alpha = alpha; { D3D12_RANGE read_range = { 0, 0 }; - d3d12_vertex_t* v; + d3d12_vertex_t* v = NULL; D3D12Map(d3d12->menu.vbo, 0, &read_range, (void**)&v); v[0].color[3] = alpha; @@ -1628,19 +1639,27 @@ static void d3d12_set_menu_texture_frame( D3D12Unmap(d3d12->menu.vbo, 0, NULL); } - d3d12->menu.texture.sampler = config_get_ptr()->bools.menu_linear_filter - ? d3d12->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_DEFAULT] - : d3d12->samplers[RARCH_FILTER_NEAREST][RARCH_WRAP_DEFAULT]; + d3d12->menu.texture.sampler = settings->bools.menu_linear_filter + ? d3d12->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_DEFAULT] + : d3d12->samplers[RARCH_FILTER_NEAREST][RARCH_WRAP_DEFAULT]; } -static void d3d12_set_menu_texture_enable(void* data, bool state, bool full_screen) + +static void d3d12_set_menu_texture_enable(void* data, + bool state, bool full_screen) { - d3d12_video_t* d3d12 = (d3d12_video_t*)data; + d3d12_video_t* d3d12 = (d3d12_video_t*)data; + + if (!d3d12) + return; d3d12->menu.enabled = state; d3d12->menu.fullscreen = full_screen; } -static void d3d12_gfx_show_mouse(void* data, bool state) { win32_show_cursor(state); } +static void d3d12_gfx_show_mouse(void* data, bool state) +{ + win32_show_cursor(state); +} static void d3d12_gfx_set_aspect_ratio(void* data, unsigned aspect_ratio_idx) { @@ -1662,21 +1681,21 @@ static void d3d12_gfx_apply_state_changes(void* data) } static void d3d12_gfx_set_osd_msg( - void* data, video_frame_info_t* video_info, const char* msg, const void* params, void* font) + void* data, video_frame_info_t* video_info, + const char* msg, const void* params, void* font) { d3d12_video_t* d3d12 = (d3d12_video_t*)data; - if (d3d12) - { - if (d3d12->sprites.enabled) - font_driver_render_msg(video_info, font, msg, params); - else - printf("OSD msg: %s\n", msg); - } + if (!d3d12 || !d3d12->sprites.enabled) + return; + + font_driver_render_msg(video_info, font, msg, + (const struct font_params*)params); } static uintptr_t d3d12_gfx_load_texture( - void* video_data, void* data, bool threaded, enum texture_filter_type filter_type) + void* video_data, void* data, bool threaded, + enum texture_filter_type filter_type) { d3d12_texture_t* texture = NULL; d3d12_video_t* d3d12 = (d3d12_video_t*)video_data; @@ -1695,12 +1714,14 @@ static uintptr_t d3d12_gfx_load_texture( case TEXTURE_FILTER_MIPMAP_LINEAR: texture->desc.MipLevels = UINT16_MAX; case TEXTURE_FILTER_LINEAR: - texture->sampler = d3d12->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_EDGE]; + texture->sampler = d3d12->samplers[ + RARCH_FILTER_LINEAR][RARCH_WRAP_EDGE]; break; case TEXTURE_FILTER_MIPMAP_NEAREST: texture->desc.MipLevels = UINT16_MAX; case TEXTURE_FILTER_NEAREST: - texture->sampler = d3d12->samplers[RARCH_FILTER_NEAREST][RARCH_WRAP_EDGE]; + texture->sampler = d3d12->samplers[ + RARCH_FILTER_NEAREST][RARCH_WRAP_EDGE]; break; } @@ -1712,7 +1733,8 @@ static uintptr_t d3d12_gfx_load_texture( d3d12_init_texture(d3d12->device, texture); d3d12_update_texture( - image->width, image->height, 0, DXGI_FORMAT_B8G8R8A8_UNORM, image->pixels, texture); + image->width, image->height, 0, + DXGI_FORMAT_B8G8R8A8_UNORM, image->pixels, texture); return (uintptr_t)texture; } @@ -1728,12 +1750,23 @@ static void d3d12_gfx_unload_texture(void* data, uintptr_t handle) free(texture); } +static uint32_t d3d12_get_flags(void *data) +{ + uint32_t flags = 0; + + BIT32_SET(flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING); + + return flags; +} + static const video_poke_interface_t d3d12_poke_interface = { + d3d12_get_flags, NULL, /* set_coords */ NULL, /* set_mvp */ d3d12_gfx_load_texture, d3d12_gfx_unload_texture, NULL, /* set_video_mode */ + win32_get_refresh_rate, d3d12_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/d3d8.c b/gfx/drivers/d3d8.c index dcb0f51676..50e8f1537a 100644 --- a/gfx/drivers/d3d8.c +++ b/gfx/drivers/d3d8.c @@ -15,6 +15,8 @@ * If not, see . */ +#define CINTERFACE + #ifdef _XBOX #include #include @@ -90,7 +92,7 @@ static void d3d8_renderchain_set_mvp( const void *mat_data) { D3DMATRIX matrix; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; d3d_matrix_identity(&matrix); @@ -106,7 +108,7 @@ static void d3d8_renderchain_set_mvp( static bool d3d8_renderchain_create_first_pass(void *data, const video_info_t *info) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; LPDIRECT3DDEVICE8 d3dr = (LPDIRECT3DDEVICE8)d3d->dev; d3d8_renderchain_t *chain = (d3d8_renderchain_t*)d3d->renderchain_data; @@ -143,7 +145,7 @@ static void d3d8_renderchain_set_vertices(void *data, unsigned pass, unsigned vert_width, unsigned vert_height, uint64_t frame_count) { unsigned width, height; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; d3d8_renderchain_t *chain = d3d ? (d3d8_renderchain_t*)d3d->renderchain_data : NULL; video_driver_get_size(&width, &height); @@ -252,7 +254,7 @@ static void d3d8_renderchain_viewport_info(void *data, struct video_viewport *vp) { unsigned width, height; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (!d3d || !vp) return; @@ -269,7 +271,7 @@ static void d3d8_renderchain_viewport_info(void *data, } static void d3d8_renderchain_render_pass( - d3d_video_t *d3d, LPDIRECT3DDEVICE8 d3dr, + d3d8_video_t *d3d, LPDIRECT3DDEVICE8 d3dr, d3d8_renderchain_t *chain, unsigned pass_index, unsigned rotation) @@ -296,7 +298,7 @@ static bool d3d8_renderchain_render(void *data, const void *frame, unsigned frame_width, unsigned frame_height, unsigned pitch, unsigned rotation) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; LPDIRECT3DDEVICE8 d3dr = (LPDIRECT3DDEVICE8)d3d->dev; d3d8_renderchain_t *chain = (d3d8_renderchain_t*)d3d->renderchain_data; @@ -318,7 +320,7 @@ static bool d3d8_renderchain_init(void *data, ) { unsigned width, height; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; LPDIRECT3DDEVICE8 d3dr = (LPDIRECT3DDEVICE8)d3d->dev; const video_info_t *video_info = (const video_info_t*)_video_info; const struct LinkInfo *link_info = (const struct LinkInfo*)info_data; @@ -328,7 +330,7 @@ static bool d3d8_renderchain_init(void *data, video_driver_get_size(&width, &height); - chain->dev = (LPDIRECT3DDEVICE8)dev_data; + chain->dev = dev_data; chain->pixel_size = (fmt == RETRO_PIXEL_FORMAT_RGB565) ? 2 : 4; chain->tex_w = link_info->tex_w; chain->tex_h = link_info->tex_h; @@ -355,7 +357,7 @@ static void *d3d8_renderchain_new(void) return renderchain; } -static bool d3d8_init_chain(d3d_video_t *d3d, const video_info_t *video_info) +static bool d3d8_init_chain(d3d8_video_t *d3d, const video_info_t *video_info) { struct LinkInfo link_info; unsigned current_width, current_height, out_width, out_height; @@ -392,7 +394,7 @@ static bool d3d8_init_chain(d3d_video_t *d3d, const video_info_t *video_info) return true; } -static bool d3d8_init_singlepass(d3d_video_t *d3d) +static bool d3d8_init_singlepass(d3d8_video_t *d3d) { struct video_shader_pass *pass = NULL; @@ -420,7 +422,7 @@ static bool d3d8_init_singlepass(d3d_video_t *d3d) static void d3d8_viewport_info(void *data, struct video_viewport *vp) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (d3d) d3d8_renderchain_viewport_info(d3d, vp); @@ -430,21 +432,21 @@ static void d3d8_set_mvp(void *data, void *shader_data, const void *mat_data) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (d3d) d3d8_renderchain_set_mvp(d3d, d3d->renderchain_data, shader_data, mat_data); } -static void d3d8_overlay_render(d3d_video_t *d3d, +static void d3d8_overlay_render(d3d8_video_t *d3d, video_frame_info_t *video_info, - overlay_t *overlay) + overlay_t *overlay, bool force_linear) { D3DVIEWPORT8 vp_full; + D3DTEXTUREFILTERTYPE filter_type; struct video_viewport vp; void *verts; unsigned i; Vertex vert[4]; - unsigned width = video_info->width; unsigned height = video_info->height; @@ -512,12 +514,19 @@ static void d3d8_overlay_render(d3d_video_t *d3d, d3d8_set_viewports(d3d->dev, &vp_full); } + if (!force_linear) + { + settings_t *settings = config_get_ptr(); + if (!settings->bools.menu_linear_filter) + filter_type = D3DTEXF_POINT; + } + /* Render overlay. */ d3d8_set_texture(d3d->dev, 0, overlay->tex); d3d8_set_sampler_address_u(d3d->dev, 0, D3DTADDRESS_BORDER); d3d8_set_sampler_address_v(d3d->dev, 0, D3DTADDRESS_BORDER); - d3d8_set_sampler_minfilter(d3d->dev, 0, D3DTEXF_LINEAR); - d3d8_set_sampler_magfilter(d3d->dev, 0, D3DTEXF_LINEAR); + d3d8_set_sampler_minfilter(d3d->dev, 0, filter_type); + d3d8_set_sampler_magfilter(d3d->dev, 0, filter_type); d3d8_draw_primitive(d3d->dev, D3DPT_TRIANGLESTRIP, 0, 2); /* Restore previous state. */ @@ -526,7 +535,7 @@ static void d3d8_overlay_render(d3d_video_t *d3d, d3d8_set_viewports(d3d->dev, &d3d->final_viewport); } -static void d3d8_free_overlay(d3d_video_t *d3d, overlay_t *overlay) +static void d3d8_free_overlay(d3d8_video_t *d3d, overlay_t *overlay) { if (!d3d) return; @@ -535,14 +544,14 @@ static void d3d8_free_overlay(d3d_video_t *d3d, overlay_t *overlay) d3d8_vertex_buffer_free(overlay->vert_buf, NULL); } -static void d3d8_deinit_chain(d3d_video_t *d3d) +static void d3d8_deinit_chain(d3d8_video_t *d3d) { d3d8_renderchain_free(d3d->renderchain_data); d3d->renderchain_data = NULL; } -static void d3d8_deinitialize(d3d_video_t *d3d) +static void d3d8_deinitialize(d3d8_video_t *d3d) { if (!d3d) return; @@ -587,7 +596,7 @@ static bool d3d8_is_windowed_enable(bool info_fullscreen) } #ifdef _XBOX -static void d3d8_get_video_size(d3d_video_t *d3d, +static void d3d8_get_video_size(d3d8_video_t *d3d, unsigned *width, unsigned *height) { DWORD video_mode = XGetVideoFlags(); @@ -653,7 +662,7 @@ static void d3d8_get_video_size(d3d_video_t *d3d, static void d3d8_make_d3dpp(void *data, const video_info_t *info, void *_d3dpp) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; D3DPRESENT_PARAMETERS *d3dpp = (D3DPRESENT_PARAMETERS*)_d3dpp; bool windowed_enable = d3d8_is_windowed_enable(info->fullscreen); @@ -753,7 +762,7 @@ static bool d3d8_init_base(void *data, const video_info_t *info) { D3DPRESENT_PARAMETERS d3dpp; HWND focus_window = NULL; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; #ifndef _XBOX focus_window = win32_get_window(); @@ -792,7 +801,7 @@ static void d3d8_calculate_rect(void *data, bool allow_rotate) { float device_aspect = (float)*width / *height; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; settings_t *settings = config_get_ptr(); video_driver_get_size(width, height); @@ -872,7 +881,7 @@ static void d3d8_set_viewport(void *data, D3DMATRIX proj, ortho, rot, matrix; int x = 0; int y = 0; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; d3d8_calculate_rect(data, &width, &height, &x, &y, force_full, allow_rotate); @@ -898,7 +907,7 @@ static void d3d8_set_viewport(void *data, d3d_matrix_transpose(&d3d->mvp_rotate, &matrix); } -static bool d3d8_initialize(d3d_video_t *d3d, const video_info_t *info) +static bool d3d8_initialize(d3d8_video_t *d3d, const video_info_t *info) { unsigned width, height; bool ret = true; @@ -973,7 +982,7 @@ static bool d3d8_initialize(d3d_video_t *d3d, const video_info_t *info) static bool d3d8_restore(void *data) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (!d3d) return false; @@ -995,7 +1004,7 @@ static bool d3d8_restore(void *data) static void d3d8_set_nonblock_state(void *data, bool state) { unsigned interval = state ? 0 : 1; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (!d3d) return; @@ -1005,7 +1014,7 @@ static void d3d8_set_nonblock_state(void *data, bool state) #ifdef _XBOX d3d8_set_render_state(d3d->dev, D3D8_PRESENTATIONINTERVAL, interval ? - D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; + D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE ); #else d3d->needs_restore = true; @@ -1013,7 +1022,7 @@ static void d3d8_set_nonblock_state(void *data, bool state) #endif } -static bool d3d8_set_resize(d3d_video_t *d3d, +static bool d3d8_set_resize(d3d8_video_t *d3d, unsigned new_width, unsigned new_height) { /* No changes? */ @@ -1034,7 +1043,7 @@ static bool d3d8_alive(void *data) unsigned temp_width = 0; unsigned temp_height = 0; bool ret = false; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; bool quit = false; bool resize = false; @@ -1074,7 +1083,7 @@ static bool d3d8_suppress_screensaver(void *data, bool enable) static void d3d8_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; switch (aspect_ratio_idx) { @@ -1106,7 +1115,7 @@ static void d3d8_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) static void d3d8_apply_state_changes(void *data) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (d3d) d3d->should_resize = true; } @@ -1116,7 +1125,7 @@ static void d3d8_set_osd_msg(void *data, const char *msg, const void *params, void *font) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; d3d8_begin_scene(d3d->dev); font_driver_render_msg(video_info, font, msg, params); @@ -1154,7 +1163,7 @@ static void d3d8_input_driver( #endif } -static bool d3d8_init_internal(d3d_video_t *d3d, +static bool d3d8_init_internal(d3d8_video_t *d3d, const video_info_t *info, const input_driver_t **input, void **input_data) { @@ -1250,7 +1259,7 @@ static bool d3d8_init_internal(d3d_video_t *d3d, static void d3d8_set_rotation(void *data, unsigned rot) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (!d3d) return; @@ -1269,7 +1278,7 @@ static void d3d8_show_mouse(void *data, bool state) static void *d3d8_init(const video_info_t *info, const input_driver_t **input, void **input_data) { - d3d_video_t *d3d = (d3d_video_t*)calloc(1, sizeof(*d3d)); + d3d8_video_t *d3d = (d3d8_video_t*)calloc(1, sizeof(*d3d)); if (!d3d) return NULL; @@ -1308,7 +1317,7 @@ static void *d3d8_init(const video_info_t *info, } #ifdef HAVE_OVERLAY -static void d3d8_free_overlays(d3d_video_t *d3d) +static void d3d8_free_overlays(d3d8_video_t *d3d) { unsigned i; @@ -1325,7 +1334,7 @@ static void d3d8_free_overlays(d3d_video_t *d3d) static void d3d8_free(void *data) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (!d3d) return; @@ -1369,7 +1378,7 @@ static void d3d8_overlay_tex_geom( float x, float y, float w, float h) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (!d3d) return; @@ -1391,7 +1400,7 @@ static void d3d8_overlay_vertex_geom( float x, float y, float w, float h) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (!d3d) return; @@ -1408,7 +1417,7 @@ static bool d3d8_overlay_load(void *data, { unsigned i, y; overlay_t *new_overlays = NULL; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; const struct texture_image *images = (const struct texture_image*) image_data; @@ -1465,7 +1474,7 @@ static bool d3d8_overlay_load(void *data, static void d3d8_overlay_enable(void *data, bool state) { unsigned i; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (!d3d) return; @@ -1479,7 +1488,7 @@ static void d3d8_overlay_enable(void *data, bool state) static void d3d8_overlay_full_screen(void *data, bool enable) { unsigned i; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; for (i = 0; i < d3d->overlays_size; i++) d3d->overlays[i].fullscreen = enable; @@ -1487,7 +1496,7 @@ static void d3d8_overlay_full_screen(void *data, bool enable) static void d3d8_overlay_set_alpha(void *data, unsigned index, float mod) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (d3d) d3d->overlays[index].alpha_mod = mod; } @@ -1511,9 +1520,7 @@ static void d3d8_get_overlay_interface(void *data, static void d3d8_update_title(video_frame_info_t *video_info) { -#ifdef _XBOX - const ui_window_t *window = NULL; -#else +#ifndef _XBOX const ui_window_t *window = ui_companion_driver_get_window_ptr(); #endif @@ -1552,7 +1559,7 @@ static bool d3d8_frame(void *data, const void *frame, { D3DVIEWPORT8 screen_vp; unsigned i = 0; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; unsigned width = video_info->width; unsigned height = video_info->height; (void)i; @@ -1616,7 +1623,7 @@ static bool d3d8_frame(void *data, const void *frame, if (d3d->menu && d3d->menu->enabled) { d3d8_set_mvp(d3d, NULL, &d3d->mvp); - d3d8_overlay_render(d3d, video_info, d3d->menu); + d3d8_overlay_render(d3d, video_info, d3d->menu, false); d3d->menu_display.offset = 0; d3d8_set_stream_source(d3d->dev, 0, d3d->menu_display.buffer, 0, sizeof(Vertex)); @@ -1642,7 +1649,7 @@ static bool d3d8_frame(void *data, const void *frame, { d3d8_set_mvp(d3d, NULL, &d3d->mvp); for (i = 0; i < d3d->overlays_size; i++) - d3d8_overlay_render(d3d, video_info, &d3d->overlays[i]); + d3d8_overlay_render(d3d, video_info, &d3d->overlays[i], true); } #endif @@ -1676,7 +1683,7 @@ static void d3d8_set_menu_texture_frame(void *data, float alpha) { D3DLOCKED_RECT d3dlr; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; (void)d3dlr; (void)frame; @@ -1761,7 +1768,7 @@ static void d3d8_set_menu_texture_frame(void *data, static void d3d8_set_menu_texture_enable(void *data, bool state, bool full_screen) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d8_video_t *d3d = (d3d8_video_t*)data; if (!d3d || !d3d->menu) return; @@ -1783,7 +1790,7 @@ static void d3d8_video_texture_load_d3d( { D3DLOCKED_RECT d3dlr; unsigned usage = 0; - d3d_video_t *d3d = (d3d_video_t*)info->userdata; + d3d8_video_t *d3d = (d3d8_video_t*)info->userdata; struct texture_image *ti = (struct texture_image*)info->data; LPDIRECT3DTEXTURE8 tex = (LPDIRECT3DTEXTURE8)d3d8_texture_new(d3d->dev, NULL, ti->width, ti->height, 0, @@ -1860,12 +1867,28 @@ static void d3d8_set_video_mode(void *data, #endif } +static uint32_t d3d8_get_flags(void *data) +{ + uint32_t flags = 0; + + BIT32_SET(flags, GFX_CTX_FLAGS_BLACK_FRAME_INSERTION); + BIT32_SET(flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING); + + return flags; +} + static const video_poke_interface_t d3d_poke_interface = { - NULL, /* set_coords */ + d3d8_get_flags, + NULL, /* set_coords */ d3d8_set_mvp, d3d8_load_texture, d3d8_unload_texture, d3d8_set_video_mode, +#ifdef _XBOX + NULL, +#else + win32_get_refresh_rate, +#endif NULL, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/d3d9.c b/gfx/drivers/d3d9.c index 24b54dcf77..a65fc54eef 100644 --- a/gfx/drivers/d3d9.c +++ b/gfx/drivers/d3d9.c @@ -15,6 +15,8 @@ * If not, see . */ +#define CINTERFACE + #ifdef _XBOX #include #include @@ -72,7 +74,7 @@ void *dinput; static bool d3d9_widescreen_mode = false; #endif -static bool d3d9_set_resize(d3d_video_t *d3d, +static bool d3d9_set_resize(d3d9_video_t *d3d, unsigned new_width, unsigned new_height) { /* No changes? */ @@ -88,7 +90,7 @@ static bool d3d9_set_resize(d3d_video_t *d3d, return true; } -static bool d3d9_init_imports(d3d_video_t *d3d) +static bool d3d9_init_imports(d3d9_video_t *d3d) { retro_ctx_memory_info_t mem_info; state_tracker_t *state_tracker = NULL; @@ -136,7 +138,6 @@ static bool d3d9_init_imports(d3d_video_t *d3d) extern d3d_renderchain_driver_t cg_d3d9_renderchain; extern d3d_renderchain_driver_t hlsl_d3d9_renderchain; -extern d3d_renderchain_driver_t null_d3d_renderchain; static bool renderchain_d3d_init_first( enum gfx_ctx_api api, @@ -155,7 +156,6 @@ static bool renderchain_d3d_init_first( #if defined(_WIN32) && defined(HAVE_HLSL) &hlsl_d3d9_renderchain, #endif - &null_d3d_renderchain, NULL }; unsigned i; @@ -182,7 +182,7 @@ static bool renderchain_d3d_init_first( return false; } -static bool d3d9_init_chain(d3d_video_t *d3d, const video_info_t *video_info) +static bool d3d9_init_chain(d3d9_video_t *d3d, const video_info_t *video_info) { struct LinkInfo link_info; unsigned current_width, current_height, out_width, out_height; @@ -289,7 +289,7 @@ static bool d3d9_init_chain(d3d_video_t *d3d, const video_info_t *video_info) return true; } -static bool d3d9_init_singlepass(d3d_video_t *d3d) +static bool d3d9_init_singlepass(d3d9_video_t *d3d) { struct video_shader_pass *pass = NULL; @@ -315,7 +315,7 @@ static bool d3d9_init_singlepass(d3d_video_t *d3d) return true; } -static bool d3d9_init_multipass(d3d_video_t *d3d, const char *shader_path) +static bool d3d9_init_multipass(d3d9_video_t *d3d, const char *shader_path) { unsigned i; bool use_extra_pass = false; @@ -383,7 +383,7 @@ static bool d3d9_init_multipass(d3d_video_t *d3d, const char *shader_path) return true; } -static bool d3d9_process_shader(d3d_video_t *d3d) +static bool d3d9_process_shader(d3d9_video_t *d3d) { const char *shader_path = d3d->shader_path; if (d3d && !string_is_empty(shader_path) && @@ -395,7 +395,7 @@ static bool d3d9_process_shader(d3d_video_t *d3d) static void d3d9_viewport_info(void *data, struct video_viewport *vp) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; if ( d3d && d3d->renderchain_driver && @@ -407,15 +407,17 @@ static void d3d9_set_mvp(void *data, void *shader_data, const void *mat_data) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; d3d9_set_vertex_shader_constantf(d3d->dev, 0, (const float*)mat_data, 4); } -static void d3d9_overlay_render(d3d_video_t *d3d, +static void d3d9_overlay_render(d3d9_video_t *d3d, video_frame_info_t *video_info, - overlay_t *overlay) + overlay_t *overlay, bool force_linear) { + D3DTEXTUREFILTERTYPE filter_type; LPDIRECT3DVERTEXDECLARATION9 vertex_decl; + LPDIRECT3DDEVICE9 dev; struct video_viewport vp; void *verts; unsigned i; @@ -435,10 +437,12 @@ static void d3d9_overlay_render(d3d_video_t *d3d, if (!d3d || !overlay || !overlay->tex) return; + dev = d3d->dev; + if (!overlay->vert_buf) { overlay->vert_buf = d3d9_vertex_buffer_new( - d3d->dev, sizeof(vert), D3DUSAGE_WRITEONLY, + dev, sizeof(vert), D3DUSAGE_WRITEONLY, #ifdef _XBOX 0, #else @@ -476,18 +480,18 @@ static void d3d9_overlay_render(d3d_video_t *d3d, vert[2].v = overlay->tex_coords[1] + overlay->tex_coords[3]; vert[3].v = overlay->tex_coords[1] + overlay->tex_coords[3]; - verts = d3d9_vertex_buffer_lock(overlay->vert_buf); + verts = d3d9_vertex_buffer_lock((LPDIRECT3DVERTEXBUFFER9)overlay->vert_buf); memcpy(verts, vert, sizeof(vert)); - d3d9_vertex_buffer_unlock(overlay->vert_buf); + d3d9_vertex_buffer_unlock((LPDIRECT3DVERTEXBUFFER9)overlay->vert_buf); d3d9_enable_blend_func(d3d->dev); /* set vertex declaration for overlay. */ - d3d9_vertex_declaration_new(d3d->dev, &vElems, (void**)&vertex_decl); - d3d9_set_vertex_declaration(d3d->dev, vertex_decl); + d3d9_vertex_declaration_new(dev, &vElems, (void**)&vertex_decl); + d3d9_set_vertex_declaration(dev, vertex_decl); d3d9_vertex_declaration_free(vertex_decl); - d3d9_set_stream_source(d3d->dev, 0, overlay->vert_buf, + d3d9_set_stream_source(dev, 0, (LPDIRECT3DVERTEXBUFFER9)overlay->vert_buf, 0, sizeof(*vert)); if (overlay->fullscreen) @@ -500,32 +504,41 @@ static void d3d9_overlay_render(d3d_video_t *d3d, vp_full.Height = height; vp_full.MinZ = 0.0f; vp_full.MaxZ = 1.0f; - d3d9_set_viewports(d3d->dev, &vp_full); + d3d9_set_viewports(dev, &vp_full); + } + + filter_type = D3DTEXF_LINEAR; + + if (!force_linear) + { + settings_t *settings = config_get_ptr(); + if (!settings->bools.menu_linear_filter) + filter_type = D3DTEXF_POINT; } /* Render overlay. */ - d3d9_set_texture(d3d->dev, 0, overlay->tex); - d3d9_set_sampler_address_u(d3d->dev, 0, D3DTADDRESS_BORDER); - d3d9_set_sampler_address_v(d3d->dev, 0, D3DTADDRESS_BORDER); - d3d9_set_sampler_minfilter(d3d->dev, 0, D3DTEXF_LINEAR); - d3d9_set_sampler_magfilter(d3d->dev, 0, D3DTEXF_LINEAR); - d3d9_draw_primitive(d3d->dev, D3DPT_TRIANGLESTRIP, 0, 2); + d3d9_set_texture(dev, 0, (LPDIRECT3DTEXTURE9)overlay->tex); + d3d9_set_sampler_address_u(dev, 0, D3DTADDRESS_BORDER); + d3d9_set_sampler_address_v(dev, 0, D3DTADDRESS_BORDER); + d3d9_set_sampler_minfilter(dev, 0, filter_type); + d3d9_set_sampler_magfilter(dev, 0, filter_type); + d3d9_draw_primitive(dev, D3DPT_TRIANGLESTRIP, 0, 2); /* Restore previous state. */ - d3d9_disable_blend_func(d3d->dev); - d3d9_set_viewports(d3d->dev, &d3d->final_viewport); + d3d9_disable_blend_func(dev); + d3d9_set_viewports(dev, &d3d->final_viewport); } -static void d3d9_free_overlay(d3d_video_t *d3d, overlay_t *overlay) +static void d3d9_free_overlay(d3d9_video_t *d3d, overlay_t *overlay) { if (!d3d) return; - d3d9_texture_free(overlay->tex); + d3d9_texture_free((LPDIRECT3DTEXTURE9)overlay->tex); d3d9_vertex_buffer_free(overlay->vert_buf, NULL); } -static void d3d9_deinit_chain(d3d_video_t *d3d) +static void d3d9_deinit_chain(d3d9_video_t *d3d) { if (!d3d || !d3d->renderchain_driver) return; @@ -537,7 +550,7 @@ static void d3d9_deinit_chain(d3d_video_t *d3d) d3d->renderchain_data = NULL; } -static void d3d9_deinitialize(d3d_video_t *d3d) +static void d3d9_deinitialize(d3d9_video_t *d3d) { if (!d3d) return; @@ -587,7 +600,7 @@ static bool d3d9_is_windowed_enable(bool info_fullscreen) } #ifdef _XBOX -static void d3d9_get_video_size(d3d_video_t *d3d, +static void d3d9_get_video_size(d3d9_video_t *d3d, unsigned *width, unsigned *height) { XVIDEO_MODE video_mode; @@ -618,7 +631,7 @@ static void d3d9_get_video_size(d3d_video_t *d3d, void d3d9_make_d3dpp(void *data, const video_info_t *info, void *_d3dpp) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; D3DPRESENT_PARAMETERS *d3dpp = (D3DPRESENT_PARAMETERS*)_d3dpp; #ifdef _XBOX /* TODO/FIXME - get rid of global state dependencies. */ @@ -698,11 +711,11 @@ void d3d9_make_d3dpp(void *data, static bool d3d9_init_base(void *data, const video_info_t *info) { D3DPRESENT_PARAMETERS d3dpp; - HWND focus_window = NULL; - d3d_video_t *d3d = (d3d_video_t*)data; + HWND focus_window = NULL; + d3d9_video_t *d3d = (d3d9_video_t*)data; #ifndef _XBOX - focus_window = win32_get_window(); + focus_window = win32_get_window(); #endif memset(&d3dpp, 0, sizeof(d3dpp)); @@ -737,9 +750,9 @@ static void d3d9_calculate_rect(void *data, bool force_full, bool allow_rotate) { - float device_aspect = (float)*width / *height; - d3d_video_t *d3d = (d3d_video_t*)data; - settings_t *settings = config_get_ptr(); + float device_aspect = (float)*width / *height; + d3d9_video_t *d3d = (d3d9_video_t*)data; + settings_t *settings = config_get_ptr(); video_driver_get_size(width, height); @@ -817,7 +830,7 @@ static void d3d9_set_viewport(void *data, { int x = 0; int y = 0; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; d3d9_calculate_rect(data, &width, &height, &x, &y, force_full, allow_rotate); @@ -839,7 +852,7 @@ static void d3d9_set_viewport(void *data, d3d->renderchain_driver->set_font_rect(d3d, NULL); } -static bool d3d9_initialize(d3d_video_t *d3d, const video_info_t *info) +static bool d3d9_initialize(d3d9_video_t *d3d, const video_info_t *info) { unsigned width, height; bool ret = true; @@ -937,7 +950,7 @@ static bool d3d9_initialize(d3d_video_t *d3d, const video_info_t *info) static bool d3d9_restore(void *data) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; if (!d3d) return false; @@ -959,7 +972,7 @@ static bool d3d9_restore(void *data) static void d3d9_set_nonblock_state(void *data, bool state) { unsigned interval = state ? 0 : 1; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; if (!d3d) return; @@ -980,12 +993,12 @@ static void d3d9_set_nonblock_state(void *data, bool state) static bool d3d9_alive(void *data) { - unsigned temp_width = 0; - unsigned temp_height = 0; - bool ret = false; - bool quit = false; - bool resize = false; - d3d_video_t *d3d = (d3d_video_t*)data; + unsigned temp_width = 0; + unsigned temp_height = 0; + bool ret = false; + bool quit = false; + bool resize = false; + d3d9_video_t *d3d = (d3d9_video_t*)data; /* Needed because some context drivers don't track their sizes */ video_driver_get_size(&temp_width, &temp_height); @@ -1024,7 +1037,7 @@ static bool d3d9_suppress_screensaver(void *data, bool enable) static void d3d9_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; switch (aspect_ratio_idx) { @@ -1056,7 +1069,7 @@ static void d3d9_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) static void d3d9_apply_state_changes(void *data) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; if (d3d) d3d->should_resize = true; } @@ -1066,14 +1079,15 @@ static void d3d9_set_osd_msg(void *data, const char *msg, const void *params, void *font) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; + LPDIRECT3DDEVICE9 dev = d3d->dev; if (d3d->renderchain_driver->set_font_rect && params) d3d->renderchain_driver->set_font_rect(d3d, params); - d3d9_begin_scene(d3d->dev); + d3d9_begin_scene(dev); font_driver_render_msg(video_info, font, msg, (const struct font_params *)params); - d3d9_end_scene(d3d->dev); + d3d9_end_scene(dev); } static void d3d9_input_driver( @@ -1108,7 +1122,7 @@ static void d3d9_input_driver( #endif } -static bool d3d9_init_internal(d3d_video_t *d3d, +static bool d3d9_init_internal(d3d9_video_t *d3d, const video_info_t *info, const input_driver_t **input, void **input_data) { @@ -1228,7 +1242,7 @@ static bool d3d9_init_internal(d3d_video_t *d3d, static void d3d9_set_rotation(void *data, unsigned rot) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; struct video_ortho ortho = {0, 1, 0, 1, -1, 1}; if (!d3d) @@ -1247,7 +1261,7 @@ static void d3d9_show_mouse(void *data, bool state) static void *d3d9_init(const video_info_t *info, const input_driver_t **input, void **input_data) { - d3d_video_t *d3d = (d3d_video_t*)calloc(1, sizeof(*d3d)); + d3d9_video_t *d3d = (d3d9_video_t*)calloc(1, sizeof(*d3d)); if (!d3d) return NULL; @@ -1286,7 +1300,7 @@ static void *d3d9_init(const video_info_t *info, } #ifdef HAVE_OVERLAY -static void d3d9_free_overlays(d3d_video_t *d3d) +static void d3d9_free_overlays(d3d9_video_t *d3d) { unsigned i; @@ -1303,7 +1317,7 @@ static void d3d9_free_overlays(d3d_video_t *d3d) static void d3d9_free(void *data) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; if (!d3d) return; @@ -1347,7 +1361,8 @@ static void d3d9_overlay_tex_geom( float x, float y, float w, float h) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; + if (!d3d) return; @@ -1363,7 +1378,8 @@ static void d3d9_overlay_vertex_geom( float x, float y, float w, float h) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; + if (!d3d) return; @@ -1380,7 +1396,7 @@ static bool d3d9_overlay_load(void *data, { unsigned i, y; overlay_t *new_overlays = NULL; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; const struct texture_image *images = (const struct texture_image*) image_data; @@ -1411,7 +1427,7 @@ static bool d3d9_overlay_load(void *data, return false; } - if (d3d9_lock_rectangle(overlay->tex, 0, &d3dlr, + if (d3d9_lock_rectangle((LPDIRECT3DTEXTURE9)overlay->tex, 0, &d3dlr, NULL, 0, D3DLOCK_NOSYSLOCK)) { uint32_t *dst = (uint32_t*)(d3dlr.pBits); @@ -1420,7 +1436,7 @@ static bool d3d9_overlay_load(void *data, for (y = 0; y < height; y++, dst += pitch, src += width) memcpy(dst, src, width << 2); - d3d9_unlock_rectangle(overlay->tex); + d3d9_unlock_rectangle((LPDIRECT3DTEXTURE9)overlay->tex); } overlay->tex_w = width; @@ -1437,7 +1453,7 @@ static bool d3d9_overlay_load(void *data, static void d3d9_overlay_enable(void *data, bool state) { unsigned i; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; if (!d3d) return; @@ -1451,7 +1467,7 @@ static void d3d9_overlay_enable(void *data, bool state) static void d3d9_overlay_full_screen(void *data, bool enable) { unsigned i; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; for (i = 0; i < d3d->overlays_size; i++) d3d->overlays[i].fullscreen = enable; @@ -1459,7 +1475,7 @@ static void d3d9_overlay_full_screen(void *data, bool enable) static void d3d9_overlay_set_alpha(void *data, unsigned index, float mod) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; if (d3d) d3d->overlays[index].alpha_mod = mod; } @@ -1524,7 +1540,7 @@ static bool d3d9_frame(void *data, const void *frame, { D3DVIEWPORT9 screen_vp; unsigned i = 0; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; unsigned width = video_info->width; unsigned height = video_info->height; (void)i; @@ -1592,11 +1608,11 @@ static bool d3d9_frame(void *data, const void *frame, if (d3d->menu && d3d->menu->enabled) { d3d9_set_mvp(d3d, NULL, &d3d->mvp); - d3d9_overlay_render(d3d, video_info, d3d->menu); + d3d9_overlay_render(d3d, video_info, d3d->menu, false); d3d->menu_display.offset = 0; - d3d9_set_vertex_declaration(d3d->dev, d3d->menu_display.decl); - d3d9_set_stream_source(d3d->dev, 0, d3d->menu_display.buffer, 0, sizeof(Vertex)); + d3d9_set_vertex_declaration(d3d->dev, (LPDIRECT3DVERTEXDECLARATION9)d3d->menu_display.decl); + d3d9_set_stream_source(d3d->dev, 0, (LPDIRECT3DVERTEXBUFFER9)d3d->menu_display.buffer, 0, sizeof(Vertex)); d3d9_set_viewports(d3d->dev, &screen_vp); menu_driver_frame(video_info); @@ -1622,7 +1638,7 @@ static bool d3d9_frame(void *data, const void *frame, { d3d9_set_mvp(d3d, NULL, &d3d->mvp); for (i = 0; i < d3d->overlays_size; i++) - d3d9_overlay_render(d3d, video_info, &d3d->overlays[i]); + d3d9_overlay_render(d3d, video_info, &d3d->overlays[i], true); } #endif @@ -1642,7 +1658,7 @@ static bool d3d9_frame(void *data, const void *frame, static bool d3d9_read_viewport(void *data, uint8_t *buffer, bool is_idle) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; if ( !d3d || !d3d->renderchain_driver || @@ -1655,7 +1671,7 @@ static bool d3d9_read_viewport(void *data, uint8_t *buffer, bool is_idle) static bool d3d9_set_shader(void *data, enum rarch_shader_type type, const char *path) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; char *old_shader = (d3d && !string_is_empty(d3d->shader_path)) ? strdup(d3d->shader_path) : NULL; if (!string_is_empty(d3d->shader_path)) @@ -1694,7 +1710,7 @@ static void d3d9_set_menu_texture_frame(void *data, float alpha) { D3DLOCKED_RECT d3dlr; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; (void)d3dlr; (void)frame; @@ -1708,7 +1724,7 @@ static void d3d9_set_menu_texture_frame(void *data, d3d->menu->tex_h != height) { if (d3d->menu) - d3d9_texture_free(d3d->menu->tex); + d3d9_texture_free((LPDIRECT3DTEXTURE9)d3d->menu->tex); d3d->menu->tex = d3d9_texture_new(d3d->dev, NULL, width, height, 1, @@ -1727,7 +1743,7 @@ static void d3d9_set_menu_texture_frame(void *data, d3d->menu->alpha_mod = alpha; - if (d3d9_lock_rectangle(d3d->menu->tex, 0, &d3dlr, + if (d3d9_lock_rectangle((LPDIRECT3DTEXTURE9)d3d->menu->tex, 0, &d3dlr, NULL, 0, D3DLOCK_NOSYSLOCK)) { unsigned h, w; @@ -1768,14 +1784,14 @@ static void d3d9_set_menu_texture_frame(void *data, if (d3d->menu) - d3d9_unlock_rectangle(d3d->menu->tex); + d3d9_unlock_rectangle((LPDIRECT3DTEXTURE9)d3d->menu->tex); } } static void d3d9_set_menu_texture_enable(void *data, bool state, bool full_screen) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; if (!d3d || !d3d->menu) return; @@ -1799,7 +1815,7 @@ static void d3d9_video_texture_load_d3d( LPDIRECT3DTEXTURE9 tex = NULL; unsigned usage = 0; bool want_mipmap = false; - d3d_video_t *d3d = (d3d_video_t*)info->userdata; + d3d9_video_t *d3d = (d3d9_video_t*)info->userdata; struct texture_image *ti = (struct texture_image*)info->data; if (!ti) @@ -1884,12 +1900,27 @@ static void d3d9_set_video_mode(void *data, #endif } +static uint32_t d3d9_get_flags(void *data) +{ + uint32_t flags = 0; + + BIT32_SET(flags, GFX_CTX_FLAGS_BLACK_FRAME_INSERTION); + BIT32_SET(flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING); + + return flags; +} + static const video_poke_interface_t d3d9_poke_interface = { + d3d9_get_flags, NULL, /* set_coords */ d3d9_set_mvp, d3d9_load_texture, d3d9_unload_texture, d3d9_set_video_mode, +#ifdef _XBOX +#else + win32_get_refresh_rate, +#endif NULL, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/dispmanx_gfx.c b/gfx/drivers/dispmanx_gfx.c index 13c925ce79..386d2bcc38 100644 --- a/gfx/drivers/dispmanx_gfx.c +++ b/gfx/drivers/dispmanx_gfx.c @@ -631,11 +631,13 @@ static void dispmanx_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) } static const video_poke_interface_t dispmanx_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, NULL, /* set_video_mode */ + NULL, /* get_refresh_rate */ NULL, /* set_filtering */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/drm_gfx.c b/gfx/drivers/drm_gfx.c index 6dda0b192c..cd43998614 100644 --- a/gfx/drivers/drm_gfx.c +++ b/gfx/drivers/drm_gfx.c @@ -39,6 +39,7 @@ #include "../font_driver.h" #include "../../retroarch.h" #include "../../verbosity.h" +#include "../common/drm_common.h" #include "drm_pixformats.h" @@ -683,6 +684,7 @@ static bool init_drm(void) * on exit in case we change it. */ drm.orig_crtc = drmModeGetCrtc(drm.fd, drm.encoder->crtc_id); drm.current_mode = &(drm.orig_crtc->mode); + g_drm_mode = drm.current_mode; /* Set mode physical video mode. Not really needed, but clears TTY console. */ struct modeset_buf buf; @@ -964,11 +966,13 @@ static void drm_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) } static const video_poke_interface_t drm_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, NULL, /* set_video_mode */ + drm_get_refresh_rate, NULL, /* set_filtering */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ @@ -1011,6 +1015,8 @@ static void drm_gfx_free(void *data) slock_free(_drmvars->vsync_cond_mutex); scond_free(_drmvars->vsync_condition); + g_drm_mode = NULL; + free(_drmvars); } diff --git a/gfx/drivers/exynos_gfx.c b/gfx/drivers/exynos_gfx.c index 91984819b8..2ce72de395 100644 --- a/gfx/drivers/exynos_gfx.c +++ b/gfx/drivers/exynos_gfx.c @@ -663,6 +663,7 @@ static void exynos_deinit(struct exynos_data *pdata) { drm_restore_crtc(); + g_drm_mode = NULL; pdata->width = 0; pdata->height = 0; pdata->num_pages = 0; @@ -1489,11 +1490,13 @@ static void exynos_show_mouse(void *data, bool state) } static const video_poke_interface_t exynos_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, NULL, /* set_video_mode */ + drm_get_refresh_rate, NULL, /* set_filtering */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/gdi_gfx.c b/gfx/drivers/gdi_gfx.c index 6ac92b19c4..dae5a1b091 100644 --- a/gfx/drivers/gdi_gfx.c +++ b/gfx/drivers/gdi_gfx.c @@ -533,11 +533,13 @@ static void gdi_set_video_mode(void *data, unsigned width, unsigned height, } static const video_poke_interface_t gdi_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, gdi_set_video_mode, + win32_get_refresh_rate, NULL, gdi_get_video_output_size, gdi_get_video_output_prev, diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 720a4b238b..34b781fad3 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -747,7 +747,7 @@ static void gl_render_osd_background( float *verts = (float*)malloc(2 * vertices_total * sizeof(float)); settings_t *settings = config_get_ptr(); int msg_width = - font_driver_get_message_width(NULL, msg, strlen(msg), 1.0f); + font_driver_get_message_width(NULL, msg, (unsigned)strlen(msg), 1.0f); /* shader driver expects vertex coords as 0..1 */ float x = video_info->font_msg_pos_x; @@ -1687,13 +1687,10 @@ static void gl_begin_debug(gl_t *gl) extern gl_renderchain_driver_t gl2_renderchain; static const gl_renderchain_driver_t *renderchain_gl_drivers[] = { -#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) &gl2_renderchain, -#endif NULL }; - static bool renderchain_gl_init_first( const gl_renderchain_driver_t **renderchain_driver, void **renderchain_handle) @@ -1715,7 +1712,8 @@ static bool renderchain_gl_init_first( return false; } -static void *gl_init(const video_info_t *video, const input_driver_t **input, void **input_data) +static void *gl_init(const video_info_t *video, + const input_driver_t **input, void **input_data) { gfx_ctx_mode_t mode; gfx_ctx_input_t inp; @@ -2586,6 +2584,14 @@ static void gl_set_coords(void *handle_data, void *shader_data, shader_data, coords); } +static float gl_get_refresh_rate(void *data) +{ + float refresh_rate = 0.0f; + if (video_context_driver_get_refresh_rate(&refresh_rate)) + return refresh_rate; + return 0.0f; +} + static void gl_set_mvp(void *data, void *shader_data, const void *mat_data) { @@ -2595,12 +2601,25 @@ static void gl_set_mvp(void *data, void *shader_data, shader_data, mat_data); } +static uint32_t gl_get_flags(void *data) +{ + uint32_t flags = 0; + + BIT32_SET(flags, GFX_CTX_FLAGS_HARD_SYNC); + BIT32_SET(flags, GFX_CTX_FLAGS_BLACK_FRAME_INSERTION); + BIT32_SET(flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING); + + return flags; +} + static const video_poke_interface_t gl_poke_interface = { + gl_get_flags, gl_set_coords, gl_set_mvp, gl_load_texture, gl_unload_texture, gl_set_video_mode, + gl_get_refresh_rate, NULL, gl_get_video_output_size, gl_get_video_output_prev, diff --git a/gfx/drivers/gx2_gfx.c b/gfx/drivers/gx2_gfx.c index 9e8c4e16c2..f8dc6e1384 100644 --- a/gfx/drivers/gx2_gfx.c +++ b/gfx/drivers/gx2_gfx.c @@ -1711,13 +1711,14 @@ static void wiiu_gfx_set_osd_msg(void *data, } -static const video_poke_interface_t wiiu_poke_interface = -{ +static const video_poke_interface_t wiiu_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ wiiu_gfx_load_texture, wiiu_gfx_unload_texture, NULL, /* set_video_mode */ + NULL, /* get_refresh_rate */ wiiu_gfx_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/gx_gfx.c b/gfx/drivers/gx_gfx.c index c14d1a7f0c..3118fa944b 100644 --- a/gfx/drivers/gx_gfx.c +++ b/gfx/drivers/gx_gfx.c @@ -1266,11 +1266,13 @@ static void gx_get_video_output_next(void *data) } static const video_poke_interface_t gx_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, gx_set_video_mode, + NULL, /* get_refresh_rate */ NULL, gx_get_video_output_size, gx_get_video_output_prev, diff --git a/gfx/drivers/omap_gfx.c b/gfx/drivers/omap_gfx.c index a97d30f198..5b4fcd0d70 100644 --- a/gfx/drivers/omap_gfx.c +++ b/gfx/drivers/omap_gfx.c @@ -1129,12 +1129,24 @@ static void omap_gfx_set_texture_enable(void *data, bool state, bool full_screen (void) full_screen; } +static float omap_get_refresh_rate(void *data) +{ + omap_video_t *vid = (omap_video_t*)data; + struct fb_var_screeninfo *s = &vid->omap->current_state->si; + + return 1000000.0f / s->pixclock / + (s->xres + s->left_margin + s->right_margin + s->hsync_len) * 1000000.0f / + (s->yres + s->upper_margin + s->lower_margin + s->vsync_len); +} + static const video_poke_interface_t omap_gfx_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, NULL, + omap_get_refresh_rate, NULL, /* set_filtering */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/psp1_gfx.c b/gfx/drivers/psp1_gfx.c index 5dc0dd1f74..57b38fe727 100644 --- a/gfx/drivers/psp1_gfx.c +++ b/gfx/drivers/psp1_gfx.c @@ -831,11 +831,13 @@ static void psp_viewport_info(void *data, struct video_viewport *vp) } static const video_poke_interface_t psp_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, NULL, + NULL, /* get_refresh_rate */ psp_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/sdl2_gfx.c b/gfx/drivers/sdl2_gfx.c index 9e6074bd79..75f3105e5e 100644 --- a/gfx/drivers/sdl2_gfx.c +++ b/gfx/drivers/sdl2_gfx.c @@ -721,11 +721,13 @@ static void sdl2_grab_mouse_toggle(void *data) } static video_poke_interface_t sdl2_video_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, NULL, + NULL, /* get_refresh_rate */ sdl2_poke_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/sdl_gfx.c b/gfx/drivers/sdl_gfx.c index 918d0ec66c..83ad492680 100644 --- a/gfx/drivers/sdl_gfx.c +++ b/gfx/drivers/sdl_gfx.c @@ -517,11 +517,13 @@ static void sdl_grab_mouse_toggle(void *data) } static const video_poke_interface_t sdl_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, NULL, + NULL, /* get_refresh_rate */ sdl_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/sunxi_gfx.c b/gfx/drivers/sunxi_gfx.c index 5c71710831..baf909520a 100644 --- a/gfx/drivers/sunxi_gfx.c +++ b/gfx/drivers/sunxi_gfx.c @@ -109,6 +109,7 @@ typedef struct uint32_t framebuffer_size; /* total size of the framebuffer */ int framebuffer_height;/* virtual vertical resolution */ uint32_t gfx_layer_size; /* the size of the primary layer */ + float refresh_rate; /* Layers support */ int gfx_layer_id; @@ -416,6 +417,9 @@ static sunxi_disp_t *sunxi_disp_init(const char *device) ctx->framebuffer_height = ctx->framebuffer_size / (ctx->xres * ctx->bits_per_pixel / 8); ctx->gfx_layer_size = ctx->xres * ctx->yres * fb_var.bits_per_pixel / 8; + ctx->refresh_rate = 1000000.0f / fb_var.pixclock * 1000000.0f / + (fb_var.yres + fb_var.upper_margin + fb_var.lower_margin + fb_var.vsync_len) + (fb_var.xres + fb_var.left_margin + fb_var.right_margin + fb_var.hsync_len); if (ctx->framebuffer_size < ctx->gfx_layer_size) { @@ -931,12 +935,21 @@ static void sunxi_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) } } +static float sunxi_get_refresh_rate (void *data) +{ + struct sunxi_video *_dispvars = (struct sunxi_video*)data; + + return _dispvars->sunxi_disp->refresh_rate; +} + static const video_poke_interface_t sunxi_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, NULL, /* set_video_mode */ + NULL, /* get_refresh_rate */ NULL, /* set_filtering */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/switch_gfx.c b/gfx/drivers/switch_gfx.c index 83d22dddb0..529f74e04a 100644 --- a/gfx/drivers/switch_gfx.c +++ b/gfx/drivers/switch_gfx.c @@ -387,11 +387,13 @@ static void switch_set_texture_enable(void *data, bool enable, bool full_screen) } static const video_poke_interface_t switch_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, /* load_texture */ NULL, /* unload_texture */ NULL, /* set_video_mode */ + NULL, /* get_refresh_rate */ NULL, /* set_filtering */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/vga_gfx.c b/gfx/drivers/vga_gfx.c index d9cdcb9182..d1a0dad125 100644 --- a/gfx/drivers/vga_gfx.c +++ b/gfx/drivers/vga_gfx.c @@ -390,6 +390,7 @@ static void vga_set_osd_msg(void *data, } static const video_poke_interface_t vga_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, @@ -403,6 +404,7 @@ static const video_poke_interface_t vga_poke_interface = { NULL, NULL, NULL, + NULL, vga_set_texture_frame, NULL, vga_set_osd_msg, diff --git a/gfx/drivers/vita2d_gfx.c b/gfx/drivers/vita2d_gfx.c index 50692b62e5..7f49756c5c 100644 --- a/gfx/drivers/vita2d_gfx.c +++ b/gfx/drivers/vita2d_gfx.c @@ -790,11 +790,13 @@ static bool vita_get_current_sw_framebuffer(void *data, } static const video_poke_interface_t vita_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ vita_load_texture, vita_unload_texture, NULL, + NULL, /* get_refresh_rate */ vita_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index cb62be8ffc..a4f2c55267 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -201,8 +201,7 @@ static void vulkan_init_pipeline_layout( &layout_info, NULL, &vk->pipelines.layout); } -static void vulkan_init_pipelines( - vk_t *vk) +static void vulkan_init_pipelines(vk_t *vk) { static const uint32_t alpha_blend_vert[] = #include "vulkan_shaders/alpha_blend.vert.inc" @@ -834,7 +833,11 @@ static bool vulkan_init_filter_chain(vk_t *vk) static void vulkan_init_resources(vk_t *vk) { + if (!vk) + return; + vk->num_swapchain_images = vk->context->num_swapchain_images; + vulkan_init_framebuffers(vk); vulkan_init_pipelines(vk); vulkan_init_descriptor_pool(vk); @@ -2289,12 +2292,34 @@ static void vulkan_unload_texture(void *data, uintptr_t handle) free(texture); } +static float vulkan_get_refresh_rate(void *data) +{ + float refresh_rate; + + if (video_context_driver_get_refresh_rate(&refresh_rate)) + return refresh_rate; + + return 0.0f; +} + +static uint32_t vulkan_get_flags(void *data) +{ + uint32_t flags = 0; + + BIT32_SET(flags, GFX_CTX_FLAGS_CUSTOMIZABLE_SWAPCHAIN_IMAGES); + BIT32_SET(flags, GFX_CTX_FLAGS_BLACK_FRAME_INSERTION); + + return flags; +} + static const video_poke_interface_t vulkan_poke_interface = { + vulkan_get_flags, NULL, /* set_coords */ NULL, /* set_mvp */ vulkan_load_texture, vulkan_unload_texture, vulkan_set_video_mode, + vulkan_get_refresh_rate, /* get_refresh_rate */ NULL, NULL, NULL, diff --git a/gfx/drivers/xshm_gfx.c b/gfx/drivers/xshm_gfx.c index 09121a414d..a953f2d052 100644 --- a/gfx/drivers/xshm_gfx.c +++ b/gfx/drivers/xshm_gfx.c @@ -189,7 +189,7 @@ static void xshm_poke_texture_enable(void *data, static void xshm_poke_set_osd_msg(void *data, video_frame_info_t *video_info, const char *msg, - const struct font_params *params, void *font) + const void *params, void *font) { } @@ -204,11 +204,13 @@ static void xshm_grab_mouse_toggle(void *data) } static video_poke_interface_t xshm_video_poke_interface = { + NULL, /* get_flags */ NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, NULL, + x11_get_refresh_rate, xshm_poke_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/xvideo.c b/gfx/drivers/xvideo.c index 8df8f528bb..d81bc83d61 100644 --- a/gfx/drivers/xvideo.c +++ b/gfx/drivers/xvideo.c @@ -423,7 +423,6 @@ static void *xv_init(const video_info_t *video, unsigned i; int ret; XWindowAttributes target; - char buf[128] = {0}; char title[128] = {0}; XSetWindowAttributes attributes = {0}; XVisualInfo visualtemplate = {0}; @@ -562,6 +561,16 @@ static void *xv_init(const video_info_t *video, XFree(visualinfo); XSetWindowBackground(g_x11_dpy, g_x11_win, 0); + if (video->fullscreen && settings->bools.video_disable_composition) + { + uint32_t value = 1; + Atom cardinal = XInternAtom(g_x11_dpy, "CARDINAL", False); + Atom net_wm_bypass_compositor = XInternAtom(g_x11_dpy, "_NET_WM_BYPASS_COMPOSITOR", False); + + RARCH_LOG("[XVideo]: Requesting compositor bypass.\n"); + XChangeProperty(g_x11_dpy, g_x11_win, net_wm_bypass_compositor, cardinal, 32, PropModeReplace, (const unsigned char*)&value, 1); + } + XMapWindow(g_x11_dpy, g_x11_win); video_driver_get_window_title(title, sizeof(title)); @@ -573,7 +582,7 @@ static void *xv_init(const video_info_t *video, if (video->fullscreen) { - x11_windowed_fullscreen(g_x11_dpy, g_x11_win); + x11_set_net_wm_fullscreen(g_x11_dpy, g_x11_win); x11_show_mouse(g_x11_dpy, g_x11_win, false); } @@ -924,11 +933,37 @@ static bool xv_read_viewport(void *data, uint8_t *buffer, bool is_idle) return true; } +static video_poke_interface_t xv_video_poke_interface = { + NULL, /* get_flags */ + NULL, + NULL, + NULL, + NULL, + NULL, + x11_get_refresh_rate, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + static void xv_get_poke_interface(void *data, const video_poke_interface_t **iface) { (void)data; - (void)iface; + *iface = &xv_video_poke_interface; } static bool xv_set_shader(void *data, diff --git a/gfx/drivers_context/android_ctx.c b/gfx/drivers_context/android_ctx.c index ca0f7911e1..422dc821cf 100644 --- a/gfx/drivers_context/android_ctx.c +++ b/gfx/drivers_context/android_ctx.c @@ -602,6 +602,7 @@ const gfx_ctx_driver_t gfx_ctx_android = { android_gfx_ctx_set_swap_interval, android_gfx_ctx_set_video_mode, android_gfx_ctx_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/cgl_ctx.c b/gfx/drivers_context/cgl_ctx.c index faeb63fc11..fb26355304 100644 --- a/gfx/drivers_context/cgl_ctx.c +++ b/gfx/drivers_context/cgl_ctx.c @@ -343,6 +343,7 @@ const gfx_ctx_driver_t gfx_ctx_cgl = { gfx_ctx_cgl_swap_interval, gfx_ctx_cgl_set_video_mode, gfx_ctx_cgl_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/cocoa_gl_ctx.m b/gfx/drivers_context/cocoa_gl_ctx.m index 8c137375a0..a95478f59d 100644 --- a/gfx/drivers_context/cocoa_gl_ctx.m +++ b/gfx/drivers_context/cocoa_gl_ctx.m @@ -666,6 +666,7 @@ const gfx_ctx_driver_t gfx_ctx_cocoagl = { cocoagl_gfx_ctx_swap_interval, cocoagl_gfx_ctx_set_video_mode, cocoagl_gfx_ctx_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/drm_ctx.c b/gfx/drivers_context/drm_ctx.c index 2300815c18..434c79502b 100644 --- a/gfx/drivers_context/drm_ctx.c +++ b/gfx/drivers_context/drm_ctx.c @@ -908,6 +908,7 @@ const gfx_ctx_driver_t gfx_ctx_drm = { gfx_ctx_drm_swap_interval, gfx_ctx_drm_set_video_mode, gfx_ctx_drm_get_video_size, + drm_get_refresh_rate, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/emscriptenegl_ctx.c b/gfx/drivers_context/emscriptenegl_ctx.c index 1bc927e334..9e3234d86f 100644 --- a/gfx/drivers_context/emscriptenegl_ctx.c +++ b/gfx/drivers_context/emscriptenegl_ctx.c @@ -376,6 +376,7 @@ const gfx_ctx_driver_t gfx_ctx_emscripten = { gfx_ctx_emscripten_swap_interval, gfx_ctx_emscripten_set_video_mode, gfx_ctx_emscripten_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/gdi_ctx.c b/gfx/drivers_context/gdi_ctx.c index 6316df83a8..d251d75cb9 100644 --- a/gfx/drivers_context/gdi_ctx.c +++ b/gfx/drivers_context/gdi_ctx.c @@ -352,6 +352,7 @@ const gfx_ctx_driver_t gfx_ctx_gdi = { gfx_ctx_gdi_swap_interval, gfx_ctx_gdi_set_video_mode, gfx_ctx_gdi_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/gfx_null_ctx.c b/gfx/drivers_context/gfx_null_ctx.c index f7884ad08c..cf0c2cc742 100644 --- a/gfx/drivers_context/gfx_null_ctx.c +++ b/gfx/drivers_context/gfx_null_ctx.c @@ -141,6 +141,7 @@ const gfx_ctx_driver_t gfx_ctx_null = { gfx_ctx_null_swap_interval, gfx_ctx_null_set_video_mode, gfx_ctx_null_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/khr_display_ctx.c b/gfx/drivers_context/khr_display_ctx.c index c597383fee..0d671bbe4a 100644 --- a/gfx/drivers_context/khr_display_ctx.c +++ b/gfx/drivers_context/khr_display_ctx.c @@ -236,6 +236,7 @@ const gfx_ctx_driver_t gfx_ctx_khr_display = { gfx_ctx_khr_display_set_swap_interval, gfx_ctx_khr_display_set_video_mode, gfx_ctx_khr_display_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/mali_fbdev_ctx.c b/gfx/drivers_context/mali_fbdev_ctx.c index 565796345d..3ffd90aedf 100644 --- a/gfx/drivers_context/mali_fbdev_ctx.c +++ b/gfx/drivers_context/mali_fbdev_ctx.c @@ -50,6 +50,7 @@ typedef struct } native_window; bool resize; unsigned width, height; + float refresh_rate; } mali_ctx_data_t; static enum gfx_ctx_api mali_api = GFX_CTX_NONE; @@ -178,6 +179,10 @@ static bool gfx_ctx_mali_fbdev_set_video_mode(void *data, mali->native_window.width = vinfo.xres; mali->native_window.height = vinfo.yres; + mali->refresh_rate = 1000000.0f / vinfo.pixclock * 1000000.0f / + (vinfo.yres + vinfo.upper_margin + vinfo.lower_margin + vinfo.vsync_len) / + (vinfo.xres + vinfo.left_margin + vinfo.right_margin + vinfo.hsync_len); + #ifdef HAVE_EGL if (!egl_create_context(&mali->egl, attribs)) { @@ -286,6 +291,13 @@ static void gfx_ctx_mali_fbdev_set_flags(void *data, uint32_t flags) (void)data; } +static float gfx_ctx_mali_fbdev_get_refresh_rate(void *data) +{ + mali_ctx_data_t *mali = (mali_ctx_data_t*)data; + + return mali->refresh_rate; +} + const gfx_ctx_driver_t gfx_ctx_mali_fbdev = { gfx_ctx_mali_fbdev_init, gfx_ctx_mali_fbdev_destroy, @@ -294,6 +306,7 @@ const gfx_ctx_driver_t gfx_ctx_mali_fbdev = { gfx_ctx_mali_fbdev_set_swap_interval, gfx_ctx_mali_fbdev_set_video_mode, gfx_ctx_mali_fbdev_get_video_size, + gfx_ctx_mali_fbdev_get_refresh_rate, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/opendingux_fbdev_ctx.c b/gfx/drivers_context/opendingux_fbdev_ctx.c index 5d6c0bf820..69ff6a58c6 100644 --- a/gfx/drivers_context/opendingux_fbdev_ctx.c +++ b/gfx/drivers_context/opendingux_fbdev_ctx.c @@ -271,6 +271,7 @@ const gfx_ctx_driver_t gfx_ctx_opendingux_fbdev = { gfx_ctx_opendingux_set_swap_interval, gfx_ctx_opendingux_set_video_mode, gfx_ctx_opendingux_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/osmesa_ctx.c b/gfx/drivers_context/osmesa_ctx.c index df460a14d5..a3ffaf5957 100644 --- a/gfx/drivers_context/osmesa_ctx.c +++ b/gfx/drivers_context/osmesa_ctx.c @@ -398,6 +398,7 @@ const gfx_ctx_driver_t gfx_ctx_osmesa = osmesa_ctx_swap_interval, osmesa_ctx_set_video_mode, osmesa_ctx_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/ps3_ctx.c b/gfx/drivers_context/ps3_ctx.c index 9ff04dd84f..72d1587cb6 100644 --- a/gfx/drivers_context/ps3_ctx.c +++ b/gfx/drivers_context/ps3_ctx.c @@ -418,6 +418,7 @@ const gfx_ctx_driver_t gfx_ctx_ps3 = { gfx_ctx_ps3_set_swap_interval, gfx_ctx_ps3_set_video_mode, gfx_ctx_ps3_get_video_size, + NULL, /* get_refresh_rate */ gfx_ctx_ps3_get_video_output_size, gfx_ctx_ps3_get_video_output_prev, gfx_ctx_ps3_get_video_output_next, diff --git a/gfx/drivers_context/qnx_ctx.c b/gfx/drivers_context/qnx_ctx.c index a425aebdac..2ce96ac7aa 100644 --- a/gfx/drivers_context/qnx_ctx.c +++ b/gfx/drivers_context/qnx_ctx.c @@ -471,6 +471,7 @@ const gfx_ctx_driver_t gfx_ctx_qnx = { gfx_ctx_qnx_set_swap_interval, gfx_ctx_qnx_set_video_mode, gfx_ctx_qnx_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/sdl_gl_ctx.c b/gfx/drivers_context/sdl_gl_ctx.c index 5801c4e9a9..aedb29e5dc 100644 --- a/gfx/drivers_context/sdl_gl_ctx.c +++ b/gfx/drivers_context/sdl_gl_ctx.c @@ -422,6 +422,7 @@ const gfx_ctx_driver_t gfx_ctx_sdl_gl = sdl_ctx_swap_interval, sdl_ctx_set_video_mode, sdl_ctx_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/vc_egl_ctx.c b/gfx/drivers_context/vc_egl_ctx.c index a485eb4e43..56b8ba8933 100644 --- a/gfx/drivers_context/vc_egl_ctx.c +++ b/gfx/drivers_context/vc_egl_ctx.c @@ -695,7 +695,7 @@ static gfx_ctx_proc_t gfx_ctx_vc_get_proc_address(const char *symbol) static uint32_t gfx_ctx_vc_get_flags(void *data) { uint32_t flags = 0; - BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + BIT32_SET(flags, GFX_CTX_FLAGS_CUSTOMIZABLE_SWAPCHAIN_IMAGES); return flags; } @@ -712,6 +712,7 @@ const gfx_ctx_driver_t gfx_ctx_videocore = { gfx_ctx_vc_set_swap_interval, gfx_ctx_vc_set_video_mode, gfx_ctx_vc_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/vivante_fbdev_ctx.c b/gfx/drivers_context/vivante_fbdev_ctx.c index 7176ce976b..512e740add 100644 --- a/gfx/drivers_context/vivante_fbdev_ctx.c +++ b/gfx/drivers_context/vivante_fbdev_ctx.c @@ -277,6 +277,7 @@ const gfx_ctx_driver_t gfx_ctx_vivante_fbdev = { gfx_ctx_vivante_set_swap_interval, gfx_ctx_vivante_set_video_mode, gfx_ctx_vivante_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/wayland_ctx.c b/gfx/drivers_context/wayland_ctx.c index 0b5e3d7a26..50ebe36e06 100644 --- a/gfx/drivers_context/wayland_ctx.c +++ b/gfx/drivers_context/wayland_ctx.c @@ -58,6 +58,7 @@ typedef struct gfx_ctx_wayland_data unsigned height; unsigned physical_width; unsigned physical_height; + int refresh_rate; struct wl_registry *registry; struct wl_compositor *compositor; struct wl_surface *surface; @@ -440,6 +441,7 @@ static void display_handle_mode(void *data, gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; wl->width = width; wl->height = height; + wl->refresh_rate = refresh; /* Certain older Wayland implementations report in Hz, * but it should be mHz. */ @@ -1369,6 +1371,13 @@ static void gfx_ctx_wl_show_mouse(void *data, bool state) wl->cursor.visible = state; } +static float gfx_ctx_wl_get_refresh_rate(void *data) +{ + gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; + + return (float) wl->refresh_rate / 1000.0f; +} + const gfx_ctx_driver_t gfx_ctx_wayland = { gfx_ctx_wl_init, gfx_ctx_wl_destroy, @@ -1377,6 +1386,7 @@ const gfx_ctx_driver_t gfx_ctx_wayland = { gfx_ctx_wl_set_swap_interval, gfx_ctx_wl_set_video_mode, gfx_ctx_wl_get_video_size, + gfx_ctx_wl_get_refresh_rate, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/wgl_ctx.c b/gfx/drivers_context/wgl_ctx.c index 1545862bd3..47c5ad5a55 100644 --- a/gfx/drivers_context/wgl_ctx.c +++ b/gfx/drivers_context/wgl_ctx.c @@ -760,6 +760,7 @@ const gfx_ctx_driver_t gfx_ctx_wgl = { gfx_ctx_wgl_swap_interval, gfx_ctx_wgl_set_video_mode, gfx_ctx_wgl_get_video_size, + win32_get_refresh_rate, gfx_ctx_wgl_get_video_output_size, gfx_ctx_wgl_get_video_output_prev, gfx_ctx_wgl_get_video_output_next, diff --git a/gfx/drivers_context/x_ctx.c b/gfx/drivers_context/x_ctx.c index 448f5df631..aa097bb6cc 100644 --- a/gfx/drivers_context/x_ctx.c +++ b/gfx/drivers_context/x_ctx.c @@ -37,6 +37,7 @@ #endif #include +#include #include "../../configuration.h" #include "../../frontend/frontend_driver.h" @@ -123,7 +124,7 @@ typedef struct Hints } Hints; /* We use long because X11 wants 32-bit pixels for 32-bit systems and 64 for 64... */ -const unsigned long retroarch_icon_data[] = { +static const unsigned long retroarch_icon_data[] = { 16, 16, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -631,6 +632,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, int y_off = 0; XVisualInfo *vi = NULL; XSetWindowAttributes swa = {0}; + char *wm_name = NULL; int (*old_handler)(Display*, XErrorEvent*) = NULL; gfx_ctx_x_data_t *x = (gfx_ctx_x_data_t*)data; Atom net_wm_icon = XInternAtom(g_x11_dpy, "_NET_WM_ICON", False); @@ -678,7 +680,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | LeaveWindowMask | EnterWindowMask | ButtonReleaseMask | ButtonPressMask; - swa.override_redirect = fullscreen ? True : False; + swa.override_redirect = False; if (fullscreen && !windowed_full) { @@ -691,6 +693,21 @@ static bool gfx_ctx_x_set_video_mode(void *data, RARCH_ERR("[GLX]: Entering true fullscreen failed. Will attempt windowed mode.\n"); } + wm_name = x11_get_wm_name(g_x11_dpy); + if (wm_name) + { + RARCH_LOG("[GLX]: Window manager is %s.\n", wm_name); + + if (true_full && strcasestr(wm_name, "xfwm")) + { + RARCH_LOG("[GLX]: Using override-redirect workaround.\n"); + swa.override_redirect = True; + } + free(wm_name); + } + if (!x11_has_net_wm_fullscreen(g_x11_dpy) && true_full) + swa.override_redirect = True; + if (video_info->monitor_index) g_x11_screen = video_info->monitor_index - 1; @@ -720,12 +737,21 @@ static bool gfx_ctx_x_set_video_mode(void *data, g_x11_win = XCreateWindow(g_x11_dpy, RootWindow(g_x11_dpy, vi->screen), x_off, y_off, width, height, 0, vi->depth, InputOutput, vi->visual, - CWBorderPixel | CWColormap | CWEventMask | - (true_full ? CWOverrideRedirect : 0), &swa); + CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, + &swa); XSetWindowBackground(g_x11_dpy, g_x11_win, 0); XChangeProperty(g_x11_dpy, g_x11_win, net_wm_icon, cardinal, 32, PropModeReplace, (const unsigned char*)retroarch_icon_data, sizeof(retroarch_icon_data) / sizeof(*retroarch_icon_data)); + if (fullscreen && settings->bools.video_disable_composition) + { + uint32_t value = 1; + Atom net_wm_bypass_compositor = XInternAtom(g_x11_dpy, "_NET_WM_BYPASS_COMPOSITOR", False); + + RARCH_LOG("[GLX]: Requesting compositor bypass.\n"); + XChangeProperty(g_x11_dpy, g_x11_win, net_wm_bypass_compositor, cardinal, 32, PropModeReplace, (const unsigned char*)&value, 1); + } + if (opacity < (unsigned)-1) { Atom net_wm_opacity = XInternAtom(g_x11_dpy, "_NET_WM_WINDOW_OPACITY", False); @@ -769,6 +795,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, { RARCH_LOG("[GLX]: Using true fullscreen.\n"); XMapRaised(g_x11_dpy, g_x11_win); + x11_set_net_wm_fullscreen(g_x11_dpy, g_x11_win); } else if (fullscreen) { @@ -783,7 +810,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, * x_off and y_off usually get ignored in XCreateWindow(). */ x11_move_window(g_x11_dpy, g_x11_win, x_off, y_off, width, height); - x11_windowed_fullscreen(g_x11_dpy, g_x11_win); + x11_set_net_wm_fullscreen(g_x11_dpy, g_x11_win); } else { @@ -1198,6 +1225,7 @@ const gfx_ctx_driver_t gfx_ctx_x = { gfx_ctx_x_swap_interval, gfx_ctx_x_set_video_mode, x11_get_video_size, + x11_get_refresh_rate, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/xegl_ctx.c b/gfx/drivers_context/xegl_ctx.c index f1e20fd78c..45df7e35c1 100644 --- a/gfx/drivers_context/xegl_ctx.c +++ b/gfx/drivers_context/xegl_ctx.c @@ -24,6 +24,7 @@ #endif #include "../../frontend/frontend_driver.h" +#include "../../configuration.h" #include "../common/egl_common.h" #include "../common/gl_common.h" @@ -271,7 +272,9 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, XVisualInfo temp = {0}; XSetWindowAttributes swa = {0}; XVisualInfo *vi = NULL; + char *wm_name = NULL; xegl_ctx_data_t *xegl = (xegl_ctx_data_t*)data; + settings_t *settings = config_get_ptr(); int (*old_handler)(Display*, XErrorEvent*) = NULL; @@ -296,7 +299,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, vi->visual, AllocNone); swa.event_mask = StructureNotifyMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask | KeyReleaseMask; - swa.override_redirect = fullscreen ? True : False; + swa.override_redirect = False; if (fullscreen && !video_info->windowed_fullscreen) { @@ -309,6 +312,21 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, RARCH_ERR("[X/EGL]: Entering true fullscreen failed. Will attempt windowed mode.\n"); } + wm_name = x11_get_wm_name(g_x11_dpy); + if (wm_name) + { + RARCH_LOG("[X/EGL]: Window manager is %s.\n", wm_name); + + if (true_full && strcasestr(wm_name, "xfwm")) + { + RARCH_LOG("[X/EGL]: Using override-redirect workaround.\n"); + swa.override_redirect = True; + } + free(wm_name); + } + if (!x11_has_net_wm_fullscreen(g_x11_dpy) && true_full) + swa.override_redirect = True; + if (video_info->monitor_index) g_x11_screen = video_info->monitor_index - 1; @@ -338,10 +356,20 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, g_x11_win = XCreateWindow(g_x11_dpy, RootWindow(g_x11_dpy, vi->screen), x_off, y_off, width, height, 0, vi->depth, InputOutput, vi->visual, - CWBorderPixel | CWColormap | CWEventMask | - (true_full ? CWOverrideRedirect : 0), &swa); + CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, + &swa); XSetWindowBackground(g_x11_dpy, g_x11_win, 0); + if (fullscreen && settings && settings->bools.video_disable_composition) + { + uint32_t value = 1; + Atom cardinal = XInternAtom(g_x11_dpy, "CARDINAL", False); + Atom net_wm_bypass_compositor = XInternAtom(g_x11_dpy, "_NET_WM_BYPASS_COMPOSITOR", False); + + RARCH_LOG("[X/EGL]: Requesting compositor bypass.\n"); + XChangeProperty(g_x11_dpy, g_x11_win, net_wm_bypass_compositor, cardinal, 32, PropModeReplace, (const unsigned char*)&value, 1); + } + if (!egl_create_context(&xegl->egl, (attr != egl_attribs) ? egl_attribs : NULL)) { egl_report_error(); @@ -361,6 +389,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, { RARCH_LOG("[X/EGL]: Using true fullscreen.\n"); XMapRaised(g_x11_dpy, g_x11_win); + x11_set_net_wm_fullscreen(g_x11_dpy, g_x11_win); } else if (fullscreen) { @@ -374,7 +403,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, * x_off and y_off usually get ignored in XCreateWindow(). */ x11_move_window(g_x11_dpy, g_x11_win, x_off, y_off, width, height); - x11_windowed_fullscreen(g_x11_dpy, g_x11_win); + x11_set_net_wm_fullscreen(g_x11_dpy, g_x11_win); } else { @@ -592,6 +621,7 @@ const gfx_ctx_driver_t gfx_ctx_x_egl = gfx_ctx_xegl_set_swap_interval, gfx_ctx_xegl_set_video_mode, x11_get_video_size, + x11_get_refresh_rate, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_font/d3d10_font.c b/gfx/drivers_font/d3d10_font.c new file mode 100644 index 0000000000..3252854303 --- /dev/null +++ b/gfx/drivers_font/d3d10_font.c @@ -0,0 +1,379 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2018 - Daniel De Matteis + * Copyright (C) 2014-2018 - Ali Bouhlel + * + * 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 . + */ + +#define CINTERFACE + +#include +#include +#include +#include +#include + +#include "../font_driver.h" +#include "../video_driver.h" +#include "../common/d3d10_common.h" + +#include "../../verbosity.h" + +typedef struct +{ + d3d10_texture_t texture; + const font_renderer_driver_t* font_driver; + void* font_data; + struct font_atlas* atlas; +} d3d10_font_t; + +static void* +d3d10_font_init_font(void* data, const char* font_path, float font_size, bool is_threaded) +{ + d3d10_video_t* d3d10 = (d3d10_video_t*)data; + d3d10_font_t* font = (d3d10_font_t*)calloc(1, sizeof(*font)); + + if (!font) + return NULL; + + if (!font_renderer_create_default( + (const void**)&font->font_driver, &font->font_data, font_path, font_size)) + { + RARCH_WARN("Couldn't initialize font renderer.\n"); + free(font); + return NULL; + } + + font->atlas = font->font_driver->get_atlas(font->font_data); + font->texture.sampler = d3d10->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_BORDER]; + font->texture.desc.Width = font->atlas->width; + font->texture.desc.Height = font->atlas->height; + font->texture.desc.Format = DXGI_FORMAT_A8_UNORM; + d3d10_init_texture(d3d10->device, &font->texture); + d3d10_update_texture( + d3d10->device, + font->atlas->width, font->atlas->height, font->atlas->width, + DXGI_FORMAT_A8_UNORM, font->atlas->buffer, &font->texture); + font->atlas->dirty = false; + + return font; +} + +static void d3d10_font_free_font(void* data, bool is_threaded) +{ + d3d10_font_t* font = (d3d10_font_t*)data; + + if (!font) + return; + + if (font->font_driver && font->font_data && font->font_driver->free) + font->font_driver->free(font->font_data); + + Release(font->texture.handle); + Release(font->texture.staging); + Release(font->texture.view); + free(font); +} + +static int d3d10_font_get_message_width(void* data, const char* msg, unsigned msg_len, float scale) +{ + d3d10_font_t* font = (d3d10_font_t*)data; + + unsigned i; + int delta_x = 0; + + if (!font) + return 0; + + for (i = 0; i < msg_len; i++) + { + const struct font_glyph *glyph; + const char* msg_tmp = &msg[i]; + unsigned code = utf8_walk(&msg_tmp); + unsigned skip = msg_tmp - &msg[i]; + + if (skip > 1) + i += skip - 1; + + glyph = font->font_driver->get_glyph(font->font_data, code); + + if (!glyph) /* Do something smarter here ... */ + glyph = font->font_driver->get_glyph(font->font_data, '?'); + + if (!glyph) + continue; + + delta_x += glyph->advance_x; + } + + return delta_x * scale; +} + +static void d3d10_font_render_line( + video_frame_info_t* video_info, + d3d10_font_t* font, + const char* msg, + unsigned msg_len, + float scale, + const unsigned int color, + float pos_x, + float pos_y, + unsigned text_align) +{ + unsigned i, count; + void* mapped_vbo; + d3d10_sprite_t* v; + d3d10_video_t* d3d10 = (d3d10_video_t*)video_info->userdata; + unsigned width = video_info->width; + unsigned height = video_info->height; + int x = roundf(pos_x * width); + int y = roundf((1.0 - pos_y) * height); + + if ( !d3d10 || + !d3d10->sprites.enabled || + msg_len > (unsigned)d3d10->sprites.capacity) + return; + + if (d3d10->sprites.offset + msg_len > (unsigned)d3d10->sprites.capacity) + d3d10->sprites.offset = 0; + + switch (text_align) + { + case TEXT_ALIGN_RIGHT: + x -= d3d10_font_get_message_width(font, msg, msg_len, scale); + break; + + case TEXT_ALIGN_CENTER: + x -= d3d10_font_get_message_width(font, msg, msg_len, scale) / 2; + break; + } + + D3D10MapBuffer(d3d10->sprites.vbo, D3D10_MAP_WRITE_NO_OVERWRITE, 0, (void**)&mapped_vbo); + v = (d3d10_sprite_t*)mapped_vbo + d3d10->sprites.offset; + + for (i = 0; i < msg_len; i++) + { + const struct font_glyph* glyph; + const char* msg_tmp = &msg[i]; + unsigned code = utf8_walk(&msg_tmp); + unsigned skip = msg_tmp - &msg[i]; + + if (skip > 1) + i += skip - 1; + + glyph = font->font_driver->get_glyph(font->font_data, code); + + if (!glyph) /* Do something smarter here ... */ + glyph = font->font_driver->get_glyph(font->font_data, '?'); + + if (!glyph) + continue; + + v->pos.x = (x + glyph->draw_offset_x) * scale / (float)d3d10->viewport.Width; + v->pos.y = (y + glyph->draw_offset_y) * scale / (float)d3d10->viewport.Height; + v->pos.w = glyph->width * scale / (float)d3d10->viewport.Width; + v->pos.h = glyph->height * scale / (float)d3d10->viewport.Height; + + v->coords.u = glyph->atlas_offset_x / (float)font->texture.desc.Width; + v->coords.v = glyph->atlas_offset_y / (float)font->texture.desc.Height; + v->coords.w = glyph->width / (float)font->texture.desc.Width; + v->coords.h = glyph->height / (float)font->texture.desc.Height; + + v->params.scaling = 1; + v->params.rotation = 0; + + v->colors[0] = color; + v->colors[1] = color; + v->colors[2] = color; + v->colors[3] = color; + + v++; + + x += glyph->advance_x * scale; + y += glyph->advance_y * scale; + } + + count = v - ((d3d10_sprite_t*)mapped_vbo + d3d10->sprites.offset); + D3D10UnmapBuffer(d3d10->sprites.vbo); + + if (!count) + return; + + if (font->atlas->dirty) + { + d3d10_update_texture( + d3d10->device, + font->atlas->width, font->atlas->height, font->atlas->width, + DXGI_FORMAT_A8_UNORM, font->atlas->buffer, &font->texture); + font->atlas->dirty = false; + } + + d3d10_set_texture_and_sampler(d3d10->device, 0, &font->texture); + D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK); + + D3D10SetPShader(d3d10->device, d3d10->sprites.shader_font.ps); + D3D10Draw(d3d10->device, count, d3d10->sprites.offset); + D3D10SetPShader(d3d10->device, d3d10->sprites.shader.ps); + + d3d10->sprites.offset += count; +} + +static void d3d10_font_render_message( + video_frame_info_t* video_info, + d3d10_font_t* font, + const char* msg, + float scale, + const unsigned int color, + float pos_x, + float pos_y, + unsigned text_align) +{ + int lines = 0; + float line_height; + + if (!msg || !*msg) + return; + + /* If the font height is not supported just draw as usual */ + if (!font->font_driver->get_line_height) + { + d3d10_font_render_line( + video_info, font, msg, strlen(msg), scale, color, pos_x, pos_y, text_align); + return; + } + + line_height = font->font_driver->get_line_height(font->font_data) * scale / video_info->height; + + for (;;) + { + const char* delim = strchr(msg, '\n'); + + /* Draw the line */ + if (delim) + { + unsigned msg_len = delim - msg; + d3d10_font_render_line( + video_info, font, msg, msg_len, scale, color, pos_x, + pos_y - (float)lines * line_height, text_align); + msg += msg_len + 1; + lines++; + } + else + { + unsigned msg_len = strlen(msg); + d3d10_font_render_line( + video_info, font, msg, msg_len, scale, color, pos_x, + pos_y - (float)lines * line_height, text_align); + break; + } + } +} + +static void d3d10_font_render_msg( + video_frame_info_t* video_info, void* data, + const char* msg, const struct font_params *params) +{ + float x, y, scale, drop_mod, drop_alpha; + int drop_x, drop_y; + enum text_alignment text_align; + unsigned color, color_dark, r, g, b, + alpha, r_dark, g_dark, b_dark, alpha_dark; + d3d10_font_t* font = (d3d10_font_t*)data; + unsigned width = video_info->width; + unsigned height = video_info->height; + + if (!font || !msg || !*msg) + return; + + if (params) + { + x = params->x; + y = params->y; + scale = params->scale; + text_align = params->text_align; + drop_x = params->drop_x; + drop_y = params->drop_y; + drop_mod = params->drop_mod; + drop_alpha = params->drop_alpha; + + r = FONT_COLOR_GET_RED(params->color); + g = FONT_COLOR_GET_GREEN(params->color); + b = FONT_COLOR_GET_BLUE(params->color); + alpha = FONT_COLOR_GET_ALPHA(params->color); + + color = DXGI_COLOR_RGBA(r, g, b, alpha); + } + else + { + x = video_info->font_msg_pos_x; + y = video_info->font_msg_pos_y; + scale = 1.0f; + text_align = TEXT_ALIGN_LEFT; + + r = (video_info->font_msg_color_r * 255); + g = (video_info->font_msg_color_g * 255); + b = (video_info->font_msg_color_b * 255); + alpha = 255; + color = DXGI_COLOR_RGBA(r, g, b, alpha); + + drop_x = -2; + drop_y = -2; + drop_mod = 0.3f; + drop_alpha = 1.0f; + } + + if (drop_x || drop_y) + { + r_dark = r * drop_mod; + g_dark = g * drop_mod; + b_dark = b * drop_mod; + alpha_dark = alpha * drop_alpha; + color_dark = DXGI_COLOR_RGBA(r_dark, g_dark, b_dark, alpha_dark); + + d3d10_font_render_message( + video_info, font, msg, scale, color_dark, + x + scale * drop_x / width, + y + scale * drop_y / height, text_align); + } + + d3d10_font_render_message(video_info, font, msg, scale, + color, x, y, text_align); +} + +static const struct font_glyph* d3d10_font_get_glyph(void *data, uint32_t code) +{ + d3d10_font_t* font = (d3d10_font_t*)data; + + if (!font || !font->font_driver) + return NULL; + + if (!font->font_driver->ident) + return NULL; + + return font->font_driver->get_glyph((void*)font->font_driver, code); +} + +static void d3d10_font_bind_block(void* data, void *userdata) +{ + (void)data; +} + +font_renderer_t d3d10_font = { + d3d10_font_init_font, + d3d10_font_free_font, + d3d10_font_render_msg, + "d3d10font", + d3d10_font_get_glyph, + d3d10_font_bind_block, + NULL, /* flush */ + d3d10_font_get_message_width, +}; diff --git a/gfx/drivers_font/d3d_w32_font.c b/gfx/drivers_font/d3d_w32_font.c index 6d329cef82..3f368fb3b5 100644 --- a/gfx/drivers_font/d3d_w32_font.c +++ b/gfx/drivers_font/d3d_w32_font.c @@ -14,6 +14,8 @@ * If not, see . */ +#define CINTERFACE + #include #include @@ -46,7 +48,7 @@ typedef struct d3dx_font_desc typedef struct { - d3d_video_t *d3d; + d3d9_video_t *d3d; void *font; uint32_t font_size; uint32_t ascent; @@ -78,7 +80,7 @@ static void *d3dfonts_w32_init_font(void *video_data, #endif d3dfonts->font_size = font_size * 1.2; /* to match the other font drivers */ - d3dfonts->d3d = (d3d_video_t*)video_data; + d3dfonts->d3d = (d3d9_video_t*)video_data; desc.Height = d3dfonts->font_size; diff --git a/gfx/drivers_font/xdk1_xfonts.c b/gfx/drivers_font/xdk1_xfonts.c index ccfc7b8542..e05769faaf 100644 --- a/gfx/drivers_font/xdk1_xfonts.c +++ b/gfx/drivers_font/xdk1_xfonts.c @@ -22,14 +22,14 @@ #endif #include "../drivers/d3d.h" -#include "../drivers/d3d_common.h" -#include "../drivers/d3d8_common.h" +#include "../common/d3d_common.h" +#include "../common/d3d8_common.h" #include "../font_driver.h" typedef struct { - d3d_video_t *d3d; + d3d8_video_t *d3d; XFONT *debug_font; D3DSurface *surf; } xfonts_t; @@ -46,7 +46,7 @@ static void *xfonts_init_font(void *video_data, (void)font_path; (void)font_size; - xfont->d3d = (d3d_video_t*)video_data; + xfont->d3d = (d3d8_video_t*)video_data; XFONT_OpenDefaultFont(&xfont->debug_font); diff --git a/gfx/drivers_font/xdk360_fonts.cpp b/gfx/drivers_font/xdk360_fonts.cpp index 71d0b82fbd..9f4500eb7f 100644 --- a/gfx/drivers_font/xdk360_fonts.cpp +++ b/gfx/drivers_font/xdk360_fonts.cpp @@ -49,15 +49,10 @@ struct XPR_HEADER /* structure member offsets matter */ struct XBRESOURCE { -#if defined(_XBOX1) - char *strName; - DWORD dwOffset; -#elif defined(_XBOX360) DWORD dwType; DWORD dwOffset; DWORD dwSize; char *strName; -#endif }; enum @@ -90,39 +85,19 @@ class PackedResource BOOL m_bInitialized; /* Resource is fully initialized */ - /* Retrieves the resource tags */ - void GetResourceTags( DWORD* pdwNumResourceTags, XBRESOURCE** ppResourceTags ); /* Functions to retrieve resources by their name */ void *GetData( const char* strName ); - void *GetTexture(const char* strName); + LPDIRECT3DTEXTURE9 *GetTexture(const char* strName); /* Constructor/destructor */ PackedResource(); ~PackedResource(); }; -void *PackedResource::GetTexture(const char* strName) +LPDIRECT3DTEXTURE9 *PackedResource::GetTexture(const char* strName) { -#ifdef _XBOX1 - LPDIRECT3DRESOURCE8 pResource = (LPDIRECT3DRESOURCE8)GetData(strName); - /* Register the resource, if it has not yet been registered. We mark - * a resource as registered by upping it's reference count. */ - if( pResource && ( pResource->Common & D3DCOMMON_REFCOUNT_MASK ) == 1 ) - { - /* Special case CPU-copy push buffers (which live in system memory) */ - if( ( pResource->Common & D3DCOMMON_TYPE_PUSHBUFFER ) && - ( pResource->Common & D3DPUSHBUFFER_RUN_USING_CPU_COPY ) ) - pResource->Data += (DWORD)m_pSysMemData; - else - pResource->Register( m_pVidMemData ); - - pResource->AddRef(); - } - return (LPDIRECT3DTEXTURE8)pResource; -#elif defined(_XBOX360) - LPDIRECT3DRESOURCE9 pResource = (LPDIRECT3DRESOURCE9)GetData(strName); - return (LPDIRECT3DTEXTURE9)pResource; -#endif + LPDIRECT3DRESOURCE9 pResource = (LPDIRECT3DRESOURCE9)GetData(strName); + return (LPDIRECT3DTEXTURE9)pResource; } PackedResource::PackedResource() @@ -146,11 +121,7 @@ void *PackedResource::GetData(const char *strName) if (!m_pResourceTags || !strName) return NULL; -#if defined(_XBOX1) - for (DWORD i=0; m_pResourceTags[i].strName; i++) -#elif defined(_XBOX360) for (DWORD i = 0; i < m_dwNumResourceTags; i++) -#endif { if (string_is_equal_noncase(strName, m_pResourceTags[i].strName)) return &m_pSysMemData[m_pResourceTags[i].dwOffset]; @@ -161,106 +132,38 @@ void *PackedResource::GetData(const char *strName) static INLINE void* AllocateContiguousMemory(DWORD Size, DWORD Alignment) { -#if defined(_XBOX1) - return D3D_AllocContiguousMemory(Size, Alignment); -#elif defined(_XBOX360) return XMemAlloc(Size, MAKE_XALLOC_ATTRIBUTES(0, 0, 0, 0, eXALLOCAllocatorId_GameMax, Alignment, XALLOC_MEMPROTECT_WRITECOMBINE, 0, XALLOC_MEMTYPE_PHYSICAL)); -#endif } static INLINE void FreeContiguousMemory(void* pData) { -#if defined(_XBOX1) - return D3D_FreeContiguousMemory(pData); -#elif defined(_XBOX360) return XMemFree(pData, MAKE_XALLOC_ATTRIBUTES(0, 0, 0, 0, eXALLOCAllocatorId_GameMax, 0, 0, 0, XALLOC_MEMTYPE_PHYSICAL)); -#endif } -#ifdef _XBOX1 -char g_strMediaPath[512] = "D:\\Media\\"; - -static HRESULT FindMediaFile(char *strPath, const char *strFilename, size_t strPathsize) -{ - if (!strFilename || !strPath) - return E_INVALIDARG; - - strlcpy(strPath, strFilename, strPathsize); - - if(strFilename[1] != ':') - snprintf(strPath, strPathsize, "%s%s", g_strMediaPath, strFilename); - - HANDLE hFile = CreateFile(strPath, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, 0, NULL); - - if (hFile == INVALID_HANDLE_VALUE) - return 0x82000004; - - CloseHandle(hFile); - - return S_OK; -} - -#endif - HRESULT PackedResource::Create(const char *strFilename, DWORD dwNumResourceTags, void* pResourceTags) { unsigned i; - HANDLE hFile; DWORD dwNumBytesRead; XPR_HEADER xprh; - bool retval = false; -#ifdef _XBOX360 - (void)dwNumResourceTags; - (void)pResourceTags; -#endif -#ifdef _XBOX1 - char strResourcePath[512]; - bool bHasResourceOffsetsTable = false; - - if (FAILED(FindMediaFile(strResourcePath, strFilename, sizeof(strResourcePath)))) - return E_FAIL; - strFilename = strResourcePath; -#endif - - hFile = CreateFile(strFilename, GENERIC_READ, FILE_SHARE_READ, NULL, + HANDLE hFile = CreateFile(strFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); + if (hFile == INVALID_HANDLE_VALUE) return E_FAIL; - retval = ReadFile(hFile, &xprh, sizeof(XPR_HEADER), &dwNumBytesRead, NULL); - -#if defined(_XBOX1) - if(xprh.dwMagic == XPR0_MAGIC_VALUE) - bHasResourceOffsetsTable = false; - else if(xprh.dwMagic == XPR1_MAGIC_VALUE) - bHasResourceOffsetsTable = true; - else -#elif defined(_XBOX360) - if(!retval) - { - CloseHandle(hFile); - return E_FAIL; - } - - if (xprh.dwMagic != XPR2_MAGIC_VALUE) -#endif + if (!ReadFile(hFile, &xprh, sizeof(XPR_HEADER), &dwNumBytesRead, NULL) || + xprh.dwMagic != XPR2_MAGIC_VALUE) { CloseHandle(hFile); return E_FAIL; } /* Compute memory requirements */ -#if defined(_XBOX1) - m_dwSysMemDataSize = xprh.dwHeaderSize - sizeof(XPR_HEADER); - m_dwVidMemDataSize = xprh.dwTotalSize - xprh.dwHeaderSize; -#elif defined(_XBOX360) m_dwSysMemDataSize = xprh.dwHeaderSize; m_dwVidMemDataSize = xprh.dwDataSize; -#endif /* Allocate memory */ m_pSysMemData = (BYTE*)malloc(m_dwSysMemDataSize); @@ -272,12 +175,8 @@ HRESULT PackedResource::Create(const char *strFilename, } m_pVidMemData = (BYTE*)AllocateContiguousMemory(m_dwVidMemDataSize, -#if defined(_XBOX1) - D3DTEXTURE_ALIGNMENT -#elif defined(_XBOX360) XALLOC_PHYSICAL_ALIGNMENT_4K -#endif - ); + ); if(!m_pVidMemData) { @@ -299,59 +198,27 @@ HRESULT PackedResource::Create(const char *strFilename, /* Done with the file */ CloseHandle( hFile); -#ifdef _XBOX1 - if (bHasResourceOffsetsTable) + /* Extract resource table from the header data */ + m_dwNumResourceTags = *(DWORD*)(m_pSysMemData + 0); + m_pResourceTags = (XBRESOURCE*)(m_pSysMemData + 4); + + /* Patch up the resources */ + + for(i = 0; i < m_dwNumResourceTags; i++) { -#endif - - /* Extract resource table from the header data */ - m_dwNumResourceTags = *(DWORD*)(m_pSysMemData + 0); - m_pResourceTags = (XBRESOURCE*)(m_pSysMemData + 4); - - /* Patch up the resources */ - - for(i = 0; i < m_dwNumResourceTags; i++) + m_pResourceTags[i].strName = (char*)(m_pSysMemData + (DWORD)m_pResourceTags[i].strName); + if((m_pResourceTags[i].dwType & 0xffff0000) == (RESOURCETYPE_TEXTURE & 0xffff0000)) { - m_pResourceTags[i].strName = (char*)(m_pSysMemData + (DWORD)m_pResourceTags[i].strName); -#ifdef _XBOX360 - if((m_pResourceTags[i].dwType & 0xffff0000) == (RESOURCETYPE_TEXTURE & 0xffff0000)) - { - D3DTexture *pTexture = (D3DTexture*)&m_pSysMemData[m_pResourceTags[i].dwOffset]; - XGOffsetBaseTextureAddress(pTexture, m_pVidMemData, m_pVidMemData); - } -#endif + D3DTexture *pTexture = (D3DTexture*)&m_pSysMemData[m_pResourceTags[i].dwOffset]; + XGOffsetBaseTextureAddress(pTexture, m_pVidMemData, m_pVidMemData); } - -#ifdef _XBOX1 } -#endif - -#ifdef _XBOX1 - /* Use user-supplied number of resources and the resource tags */ - if(dwNumResourceTags != 0 || pResourceTags != NULL) - { - m_pResourceTags = (XBRESOURCE*)pResourceTags; - m_dwNumResourceTags = dwNumResourceTags; - } -#endif m_bInitialized = true; return S_OK; } -void PackedResource::GetResourceTags(DWORD* pdwNumResourceTags, - XBRESOURCE** ppResourceTags) -{ -#ifdef _XBOX360 - if (pdwNumResourceTags) - (*pdwNumResourceTags) = m_dwNumResourceTags; - - if (ppResourceTags) - (*ppResourceTags) = m_pResourceTags; -#endif -} - void PackedResource::Destroy() { free(m_pSysMemData); @@ -388,7 +255,7 @@ typedef struct typedef struct { Font_Locals_t s_FontLocals; - d3d_video_t *d3d; + d3d9_video_t *d3d; uint32_t m_dwSavedState; uint32_t m_cMaxGlyph; /* Number of entries in the translator table. */ uint32_t m_dwNumGlyphs; /* Number of valid glyphs. */ @@ -397,7 +264,7 @@ typedef struct float m_fFontBottomPadding; /* Padding below the strike zone. */ float m_fFontYAdvance; /* Number of pixels to move the cursor for a line feed. */ wchar_t * m_TranslatorTable; /* ASCII to glyph lookup table. */ - void *m_pFontTexture; + LPDIRECT3DTEXTURE9 m_pFontTexture; const GLYPH_ATTR* m_Glyphs; /* Array of glyphs. */ } xdk360_video_font_t; @@ -420,7 +287,7 @@ typedef struct static PackedResource m_xprResource; -static bool xdk360_video_font_create_shaders(xdk360_video_font_t * font, void *dev) +static bool xdk360_video_font_create_shaders(xdk360_video_font_t * font, LPDIRECT3DDEVICE9 dev) { ID3DXBuffer* pShaderCode = NULL; @@ -443,7 +310,7 @@ static bool xdk360_video_font_create_shaders(xdk360_video_font_t * font, void *d if (!d3d9_vertex_declaration_new(dev, decl, (void**)&font->s_FontLocals.m_pFontVertexDecl)) goto error; - if (!d3dx_compile_shader( font_hlsl_d3d9_program, sizeof(font_hlsl_d3d9_program)-1 , + if (!d3d9x_compile_shader( font_hlsl_d3d9_program, sizeof(font_hlsl_d3d9_program)-1 , NULL, NULL, "main_vertex", "vs.2.0", 0, &pShaderCode, NULL, NULL )) goto error; @@ -451,9 +318,9 @@ static bool xdk360_video_font_create_shaders(xdk360_video_font_t * font, void *d (void**)&font->s_FontLocals.m_pFontVertexShader )) goto error; - d3dxbuffer_release(pShaderCode); + d3d9x_buffer_release(pShaderCode); - if (!d3dx_compile_shader(font_hlsl_d3d9_program, sizeof(font_hlsl_d3d9_program)-1 , + if (!d3d9x_compile_shader(font_hlsl_d3d9_program, sizeof(font_hlsl_d3d9_program)-1 , NULL, NULL, "main_fragment", "ps.2.0", 0,&pShaderCode, NULL, NULL )) goto error; @@ -461,15 +328,15 @@ static bool xdk360_video_font_create_shaders(xdk360_video_font_t * font, void *d (void**)&font->s_FontLocals.m_pFontPixelShader)) goto error; - d3dxbuffer_release(pShaderCode); + d3d9x_buffer_release(pShaderCode); return true; error: if (pShaderCode) - d3dxbuffer_release(pShaderCode); - d3d9_free_pixel_shader(font->d3d->dev, font->s_FontLocals.m_pFontPixelShader); - d3d9_free_vertex_shader(font->d3d->dev, font->s_FontLocals.m_pFontVertexShader); + d3d9x_buffer_release(pShaderCode); + d3d9_free_pixel_shader((LPDIRECT3DDEVICE9)font->d3d->dev, font->s_FontLocals.m_pFontPixelShader); + d3d9_free_vertex_shader((LPDIRECT3DDEVICE9)font->d3d->dev, font->s_FontLocals.m_pFontVertexShader); d3d9_vertex_declaration_free(font->s_FontLocals.m_pFontVertexDecl); font->s_FontLocals.m_pFontPixelShader = NULL; font->s_FontLocals.m_pFontVertexShader = NULL; @@ -493,7 +360,7 @@ static void *xdk360_init_font(void *video_data, (void)font_size; - font->d3d = (d3d_video_t*)video_data; + font->d3d = (d3d9_video_t*)video_data; font->m_pFontTexture = NULL; font->m_dwNumGlyphs = 0L; @@ -505,11 +372,11 @@ static void *xdk360_init_font(void *video_data, if (FAILED( m_xprResource.Create(font_path, 0, NULL))) goto error; - pFontTexture = m_xprResource.GetTexture( "FontTexture" ); + pFontTexture = (LPDIRECT3DTEXTURE9)m_xprResource.GetTexture( "FontTexture" ); pFontData = m_xprResource.GetData( "FontData"); /* Save a copy of the texture. */ - font->m_pFontTexture = pFontTexture; + font->m_pFontTexture = (LPDIRECT3DTEXTURE9)pFontTexture; /* Check version of file (to make sure it matches up with the FontMaker tool). */ pData = (const uint8_t*)pFontData; @@ -537,7 +404,7 @@ static void *xdk360_init_font(void *video_data, font->m_Glyphs = ((const FontFileStrikesImage_t *)pData)->m_Glyphs; /* Create the vertex and pixel shaders for rendering the font */ - if (!xdk360_video_font_create_shaders(font, font->d3d->dev)) + if (!xdk360_video_font_create_shaders(font, (LPDIRECT3DDEVICE9)font->d3d->dev)) { RARCH_ERR( "Could not create font shaders.\n" ); goto error; @@ -566,8 +433,8 @@ static void xdk360_free_font(void *data, bool is_threaded) font->m_cMaxGlyph = 0; font->m_TranslatorTable = NULL; - d3d9_free_pixel_shader(font->d3d->dev, font->s_FontLocals.m_pFontPixelShader); - d3d9_free_vertex_shader(font->d3d->dev, font->s_FontLocals.m_pFontVertexShader); + d3d9_free_pixel_shader((LPDIRECT3DDEVICE9)font->d3d->dev, font->s_FontLocals.m_pFontPixelShader); + d3d9_free_vertex_shader((LPDIRECT3DDEVICE9)font->d3d->dev, font->s_FontLocals.m_pFontVertexShader); d3d9_vertex_declaration_free(font->s_FontLocals.m_pFontVertexDecl); font->s_FontLocals.m_pFontPixelShader = NULL; @@ -583,24 +450,35 @@ static void xdk360_free_font(void *data, bool is_threaded) static void xdk360_render_msg_post(xdk360_video_font_t * font) { - if (!font || !font->d3d || !font->d3d->dev) + LPDIRECT3DDEVICE9 dev; + if (!font || !font->d3d) return; + dev = (LPDIRECT3DDEVICE9)font->d3d->dev; - d3d9_set_texture(font->d3d->dev, 0, NULL); - d3d9_set_vertex_declaration(font->d3d->dev, NULL); - d3d9_set_vertex_shader(font->d3d->dev, 0, NULL); - d3d9_set_pixel_shader(font->d3d->dev, NULL); - d3d9_set_render_state(font->d3d->dev, D3DRS_VIEWPORTENABLE, font->m_dwSavedState); + if (!dev) + return; + + d3d9_set_texture(dev, 0, NULL); + d3d9_set_vertex_declaration(dev, NULL); + d3d9_set_vertex_shader(dev, 0, NULL); + d3d9_set_pixel_shader(dev, NULL); + d3d9_set_render_state(dev, D3DRS_VIEWPORTENABLE, font->m_dwSavedState); } static void xdk360_render_msg_pre(xdk360_video_font_t * font) { float vTexScale[4]; D3DSURFACE_DESC TextureDesc; + LPDIRECT3DDEVICE9 dev; - if (!font || !font->d3d || !font->d3d->dev) + if (!font || !font->d3d) return; + dev = (LPDIRECT3DDEVICE9)font->d3d->dev; + + if (!dev) + return; + /* Save state. */ d3d9_get_render_state(font->d3d->dev, D3DRS_VIEWPORTENABLE, (DWORD*)&font->m_dwSavedState ); @@ -610,18 +488,18 @@ static void xdk360_render_msg_pre(xdk360_video_font_t * font) d3d9_texture_get_level_desc(font->m_pFontTexture, 0, &TextureDesc); /* Set render state. */ - d3d9_set_texture(font->d3d->dev, 0, font->m_pFontTexture); + d3d9_set_texture(dev, 0, font->m_pFontTexture); vTexScale[0] = 1.0f / TextureDesc.Width; vTexScale[1] = 1.0f / TextureDesc.Height; vTexScale[2] = 0.0f; vTexScale[3] = 0.0f; - d3d9_set_render_state(font->d3d->dev, D3DRS_VIEWPORTENABLE, FALSE); - d3d9_set_vertex_declaration(font->d3d->dev, font->s_FontLocals.m_pFontVertexDecl); - d3d9_set_vertex_shader(font->d3d->dev, 0, font->s_FontLocals.m_pFontVertexShader); - d3d9_set_pixel_shader(font->d3d->dev, font->s_FontLocals.m_pFontPixelShader); - d3d9_set_vertex_shader_constantf(font->d3d->dev, 2, vTexScale, 1); + d3d9_set_render_state(dev, D3DRS_VIEWPORTENABLE, FALSE); + d3d9_set_vertex_declaration(dev, font->s_FontLocals.m_pFontVertexDecl); + d3d9_set_vertex_shader(dev, 0, font->s_FontLocals.m_pFontVertexShader); + d3d9_set_pixel_shader(dev, font->s_FontLocals.m_pFontPixelShader); + d3d9_set_vertex_shader_constantf(dev, 2, vTexScale, 1); } static void xdk360_draw_text(xdk360_video_font_t *font, diff --git a/gfx/drivers_renderchain/d3d9_cg_renderchain.c b/gfx/drivers_renderchain/d3d9_cg_renderchain.c index ed8308e1a6..a5a75b3146 100644 --- a/gfx/drivers_renderchain/d3d9_cg_renderchain.c +++ b/gfx/drivers_renderchain/d3d9_cg_renderchain.c @@ -14,6 +14,8 @@ * If not, see . */ +#define CINTERFACE + #include #include @@ -463,9 +465,9 @@ static void d3d9_cg_renderchain_bind_orig(cg_renderchain_t *chain, index = cgGetParameterResourceIndex(param); d3d9_set_texture(chain->dev, index, chain->passes->data[0].tex); d3d9_set_sampler_magfilter(chain->dev, index, - d3d9_translate_filter(chain->passes->data[0].info.pass->filter)); + d3d_translate_filter(chain->passes->data[0].info.pass->filter)); d3d9_set_sampler_minfilter(chain->dev, index, - d3d9_translate_filter(chain->passes->data[0].info.pass->filter)); + d3d_translate_filter(chain->passes->data[0].info.pass->filter)); d3d9_set_sampler_address_u(chain->dev, index, D3DTADDRESS_BORDER); d3d9_set_sampler_address_v(chain->dev, index, D3DTADDRESS_BORDER); unsigned_vector_list_append(chain->bound_tex, index); @@ -539,9 +541,9 @@ static void d3d9_cg_renderchain_bind_prev(void *data, const void *pass_data) unsigned_vector_list_append(chain->bound_tex, index); d3d9_set_sampler_magfilter(chain->dev, index, - d3d9_translate_filter(chain->passes->data[0].info.pass->filter)); + d3d_translate_filter(chain->passes->data[0].info.pass->filter)); d3d9_set_sampler_minfilter(chain->dev, index, - d3d9_translate_filter(chain->passes->data[0].info.pass->filter)); + d3d_translate_filter(chain->passes->data[0].info.pass->filter)); d3d9_set_sampler_address_u(chain->dev, index, D3DTADDRESS_BORDER); d3d9_set_sampler_address_v(chain->dev, index, D3DTADDRESS_BORDER); } @@ -570,9 +572,9 @@ static void d3d9_cg_renderchain_add_lut_internal(void *data, d3d9_set_texture(chain->dev, index, chain->luts->data[i].tex); d3d9_set_sampler_magfilter(chain->dev, index, - d3d9_translate_filter(chain->luts->data[i].smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST)); + d3d_translate_filter(chain->luts->data[i].smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST)); d3d9_set_sampler_minfilter(chain->dev, index, - d3d9_translate_filter(chain->luts->data[i].smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST)); + d3d_translate_filter(chain->luts->data[i].smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST)); d3d9_set_sampler_address_u(chain->dev, index, D3DTADDRESS_BORDER); d3d9_set_sampler_address_v(chain->dev, index, D3DTADDRESS_BORDER); unsigned_vector_list_append(chain->bound_tex, index); @@ -623,9 +625,9 @@ static void d3d9_cg_renderchain_bind_pass( d3d9_set_texture(chain->dev, index, chain->passes->data[i].tex); d3d9_set_sampler_magfilter(chain->dev, index, - d3d9_translate_filter(chain->passes->data[i].info.pass->filter)); + d3d_translate_filter(chain->passes->data[i].info.pass->filter)); d3d9_set_sampler_minfilter(chain->dev, index, - d3d9_translate_filter(chain->passes->data[i].info.pass->filter)); + d3d_translate_filter(chain->passes->data[i].info.pass->filter)); d3d9_set_sampler_address_u(chain->dev, index, D3DTADDRESS_BORDER); d3d9_set_sampler_address_v(chain->dev, index, D3DTADDRESS_BORDER); } @@ -774,7 +776,7 @@ static void *d3d9_cg_renderchain_new(void) static bool d3d9_cg_renderchain_init_shader(void *data, void *renderchain_data) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; cg_renderchain_t *renderchain = (cg_renderchain_t*)renderchain_data; if (!d3d || !renderchain) @@ -887,9 +889,9 @@ static bool d3d9_cg_renderchain_create_first_pass( d3d9_set_texture(chain->dev, 0, chain->prev.tex[i]); d3d9_set_sampler_minfilter(chain->dev, 0, - d3d9_translate_filter(info->pass->filter)); + d3d_translate_filter(info->pass->filter)); d3d9_set_sampler_magfilter(chain->dev, 0, - d3d9_translate_filter(info->pass->filter)); + d3d_translate_filter(info->pass->filter)); d3d9_set_sampler_address_u(chain->dev, 0, D3DTADDRESS_BORDER); d3d9_set_sampler_address_v(chain->dev, 0, D3DTADDRESS_BORDER); d3d9_set_texture(chain->dev, 0, NULL); @@ -911,7 +913,7 @@ static bool d3d9_cg_renderchain_init(void *data, const void *info_data, bool rgb32) { const struct LinkInfo *info = (const struct LinkInfo*)info_data; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; cg_renderchain_t *chain = (cg_renderchain_t*)d3d->renderchain_data; const video_info_t *video_info = (const video_info_t*)_video_info; unsigned fmt = (rgb32) ? RETRO_PIXEL_FORMAT_XRGB8888 : RETRO_PIXEL_FORMAT_RGB565; @@ -1025,7 +1027,7 @@ static void d3d9_cg_renderchain_convert_geometry( } static void d3d_recompute_pass_sizes(cg_renderchain_t *chain, - d3d_video_t *d3d) + d3d9_video_t *d3d) { unsigned i; struct LinkInfo link_info; @@ -1074,7 +1076,7 @@ static void d3d9_cg_renderchain_set_final_viewport( void *renderchain_data, const void *viewport_data) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; cg_renderchain_t *chain = (cg_renderchain_t*)renderchain_data; const D3DVIEWPORT9 *final_viewport = (const D3DVIEWPORT9*)viewport_data; @@ -1331,8 +1333,8 @@ static void cg_d3d9_renderchain_blit_to_texture( unsigned width, unsigned height, unsigned pitch) { - D3DLOCKED_RECT d3dlr; - struct Pass *first = (struct Pass*)&chain->passes->data[0]; + D3DLOCKED_RECT d3dlr = {0, NULL}; + struct Pass *first = (struct Pass*)&chain->passes->data[0]; if ( (first->last_width != width || first->last_height != height) @@ -1426,9 +1428,9 @@ static void cg_d3d9_renderchain_render_pass( d3d9_set_texture(chain->dev, 0, pass->tex); d3d9_set_sampler_minfilter(chain->dev, 0, - d3d9_translate_filter(pass->info.pass->filter)); + d3d_translate_filter(pass->info.pass->filter)); d3d9_set_sampler_magfilter(chain->dev, 0, - d3d9_translate_filter(pass->info.pass->filter)); + d3d_translate_filter(pass->info.pass->filter)); d3d9_set_vertex_declaration(chain->dev, pass->vertex_decl); for (i = 0; i < 4; i++) @@ -1491,7 +1493,7 @@ static bool d3d9_cg_renderchain_render( LPDIRECT3DSURFACE9 back_buffer, target; unsigned i, current_width, current_height, out_width = 0, out_height = 0; struct Pass *last_pass = NULL; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; cg_renderchain_t *chain = d3d ? (cg_renderchain_t*)d3d->renderchain_data : NULL; d3d9_cg_renderchain_start_render(chain); @@ -1594,7 +1596,7 @@ static void d3d9_cg_renderchain_set_font_rect( const void *font_data) { settings_t *settings = config_get_ptr(); - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; float pos_x = settings->floats.video_msg_pos_x; float pos_y = settings->floats.video_msg_pos_y; float font_size = settings->floats.video_font_size; @@ -1630,8 +1632,8 @@ static bool d3d9_cg_renderchain_read_viewport( LPDIRECT3DSURFACE9 target = NULL; LPDIRECT3DSURFACE9 dest = NULL; bool ret = true; - d3d_video_t *d3d = (d3d_video_t*)data; - LPDIRECT3DDEVICE9 d3dr = (LPDIRECT3DDEVICE9)d3d->dev; + d3d9_video_t *d3d = (d3d9_video_t*)data; + LPDIRECT3DDEVICE9 d3dr = d3d->dev; video_driver_get_size(&width, &height); @@ -1688,7 +1690,7 @@ static void d3d9_cg_renderchain_viewport_info( void *data, struct video_viewport *vp) { unsigned width, height; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; if (!d3d || !vp) return; diff --git a/gfx/drivers_renderchain/d3d9_hlsl_renderchain.c b/gfx/drivers_renderchain/d3d9_hlsl_renderchain.c index 0f61b2b0b3..8a56d834f1 100644 --- a/gfx/drivers_renderchain/d3d9_hlsl_renderchain.c +++ b/gfx/drivers_renderchain/d3d9_hlsl_renderchain.c @@ -14,6 +14,8 @@ * If not, see . */ +#define CINTERFACE + #include #include #include @@ -28,6 +30,7 @@ #include "../video_driver.h" #include "../../configuration.h" +#include "../../retroarch.h" #include "../../verbosity.h" typedef struct hlsl_d3d9_renderchain @@ -60,8 +63,8 @@ static bool hlsl_d3d9_renderchain_init_shader_fvf(void *data, void *pass_data) { 0, 2 * sizeof(float), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; - d3d_video_t *d3d = (d3d_video_t*)data; - d3d_video_t *pass = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; + d3d9_video_t *pass = (d3d9_video_t*)data; hlsl_d3d9_renderchain_t *chain = (hlsl_d3d9_renderchain_t*) d3d->renderchain_data; @@ -74,7 +77,7 @@ static bool hlsl_d3d9_renderchain_init_shader_fvf(void *data, void *pass_data) static bool hlsl_d3d9_renderchain_create_first_pass(void *data, const video_info_t *info) { - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; hlsl_d3d9_renderchain_t *chain = (hlsl_d3d9_renderchain_t*) d3d->renderchain_data; @@ -119,7 +122,7 @@ static void hlsl_d3d9_renderchain_set_vertices( video_shader_ctx_params_t params; video_shader_ctx_info_t shader_info; unsigned width, height; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; hlsl_d3d9_renderchain_t *chain = d3d ? (hlsl_d3d9_renderchain_t*)d3d->renderchain_data : NULL; @@ -201,7 +204,7 @@ static void hlsl_d3d9_renderchain_blit_to_texture( void *data, const void *frame, unsigned width, unsigned height, unsigned pitch) { - D3DLOCKED_RECT d3dlr; + D3DLOCKED_RECT d3dlr = { 0, NULL }; hlsl_d3d9_renderchain_t *chain = (hlsl_d3d9_renderchain_t*)data; if (chain->last_width != width || chain->last_height != height) @@ -239,7 +242,7 @@ static void hlsl_d3d9_renderchain_deinit_shader(void *data) static void hlsl_d3d9_renderchain_free(void *data) { - d3d_video_t *chain = (d3d_video_t*)data; + d3d9_video_t *chain = (d3d9_video_t*)data; if (!chain) return; @@ -263,8 +266,7 @@ static bool hlsl_d3d9_renderchain_init_shader(void *data, void *renderchain_data) { video_shader_ctx_init_t init; - bool ret = false; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; settings_t *settings = config_get_ptr(); (void)renderchain_data; @@ -274,13 +276,11 @@ static bool hlsl_d3d9_renderchain_init_shader(void *data, init.shader_type = RARCH_SHADER_HLSL; init.data = data; init.path = retroarch_get_shader_preset(); - init.shader = &hlsl_backend; + init.shader = NULL; RARCH_LOG("D3D]: Using HLSL shader backend.\n"); - ret = video_shader_driver_init(&init); - - return ret; + return video_shader_driver_init(&init); } static bool hlsl_d3d9_renderchain_init(void *data, @@ -292,7 +292,7 @@ static bool hlsl_d3d9_renderchain_init(void *data, ) { unsigned width, height; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; const video_info_t *video_info = (const video_info_t*)_video_info; const struct LinkInfo *link_info = (const struct LinkInfo*)info_data; hlsl_d3d9_renderchain_t *chain = (hlsl_d3d9_renderchain_t*) @@ -342,7 +342,7 @@ static bool hlsl_d3d9_renderchain_render(void *data, const void *frame, { unsigned i; unsigned width, height; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; settings_t *settings = config_get_ptr(); hlsl_d3d9_renderchain_t *chain = (hlsl_d3d9_renderchain_t*)d3d->renderchain_data; bool video_smooth = settings->bools.video_smooth; @@ -411,7 +411,7 @@ static void hlsl_d3d9_renderchain_viewport_info( void *data, struct video_viewport *vp) { unsigned width, height; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d9_video_t *d3d = (d3d9_video_t*)data; if (!d3d || !vp) return; diff --git a/gfx/drivers_renderchain/gl1_renderchain.c b/gfx/drivers_renderchain/gl1_renderchain.c index 3eb1f887c7..f4f06acb43 100644 --- a/gfx/drivers_renderchain/gl1_renderchain.c +++ b/gfx/drivers_renderchain/gl1_renderchain.c @@ -55,8 +55,6 @@ typedef struct gl1_renderchain void *empty; } gl1_renderchain_t; -GLenum min_filter_to_mag(GLenum type); - void gl1_renderchain_free(void *data, void *chain_data) { (void)chain_data; diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 1cb856c4e8..0a72e89137 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -504,27 +504,30 @@ static void gl2_renderchain_deinit_fbo(void *data, gl_t *gl = (gl_t*)data; gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; - if (!gl) - return; + if (gl) + { + if (gl->fbo_feedback) + gl2_delete_fb(1, &gl->fbo_feedback); + if (gl->fbo_feedback_texture) + glDeleteTextures(1, &gl->fbo_feedback_texture); - glDeleteTextures(chain->fbo_pass, chain->fbo_texture); - gl2_delete_fb(chain->fbo_pass, chain->fbo); + gl->fbo_inited = false; + gl->fbo_feedback_enable = false; + gl->fbo_feedback_pass = 0; + gl->fbo_feedback_texture = 0; + gl->fbo_feedback = 0; + } - memset(chain->fbo_texture, 0, sizeof(chain->fbo_texture)); - memset(chain->fbo, 0, sizeof(chain->fbo)); + if (chain) + { + gl2_delete_fb(chain->fbo_pass, chain->fbo); + glDeleteTextures(chain->fbo_pass, chain->fbo_texture); - if (gl->fbo_feedback) - gl2_delete_fb(1, &gl->fbo_feedback); - if (gl->fbo_feedback_texture) - glDeleteTextures(1, &gl->fbo_feedback_texture); + memset(chain->fbo_texture, 0, sizeof(chain->fbo_texture)); + memset(chain->fbo, 0, sizeof(chain->fbo)); - chain->fbo_pass = 0; - - gl->fbo_inited = false; - gl->fbo_feedback_enable = false; - gl->fbo_feedback_pass = 0; - gl->fbo_feedback_texture = 0; - gl->fbo_feedback = 0; + chain->fbo_pass = 0; + } } static void gl2_renderchain_deinit_hw_render( @@ -711,10 +714,9 @@ static void gl_create_fbo_texture(gl_t *gl, } } -static void gl_create_fbo_textures(gl_t *gl, void *chain_data) +static void gl_create_fbo_textures(gl_t *gl, gl2_renderchain_t *chain) { int i; - gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; glGenTextures(chain->fbo_pass, chain->fbo_texture); diff --git a/gfx/drivers_renderchain/null_renderchain.c b/gfx/drivers_renderchain/null_renderchain.c deleted file mode 100644 index 6da4458bc2..0000000000 --- a/gfx/drivers_renderchain/null_renderchain.c +++ /dev/null @@ -1,135 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * Copyright (C) 2011-2017 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#include -#include -#include - -#include "../video_driver.h" - -typedef struct null_renderchain -{ - void *empty; -} null_renderchain_t; - -static void null_renderchain_free(void *data) -{ -} - -static void *null_renderchain_new(void) -{ - null_renderchain_t *renderchain = (null_renderchain_t*)calloc(1, sizeof(*renderchain)); - if (!renderchain) - return NULL; - - return renderchain; -} - -static bool null_renderchain_init(void *data, - const void *info, - void *dev_data, - const void *final_viewport_data, - const void *info_data, - bool rgb32 - ) -{ - (void)data; - (void)info; - (void)dev_data; - (void)final_viewport_data; - (void)info_data; - (void)rgb32; - - return true; -} - -static void null_renderchain_set_final_viewport(void *data, - void *renderchain_data, const void *viewport_data) -{ - (void)data; - (void)renderchain_data; - (void)viewport_data; -} - -static bool null_renderchain_render(void *data, const void *frame, - unsigned width, unsigned height, - unsigned pitch, unsigned rotation) -{ - (void)data; - (void)frame; - (void)width; - (void)height; - (void)pitch; - (void)rotation; - - return true; -} - -static bool null_renderchain_add_lut(void *data, - const char *id, const char *path, bool smooth) -{ - (void)data; - (void)id; - (void)path; - (void)smooth; - - return true; -} - -static bool null_renderchain_add_pass(void *data, const void *info_data) -{ - (void)data; - (void)info_data; - - return true; -} - -static void null_renderchain_add_state_tracker(void *data, void *tracker_data) -{ - (void)data; - (void)tracker_data; -} - -static void null_renderchain_convert_geometry( - void *data, const void *info_data, - unsigned *out_width, unsigned *out_height, - unsigned width, unsigned height, - void *final_viewport_data) -{ - (void)data; - (void)info_data; - (void)out_width; - (void)out_height; - (void)width; - (void)height; - (void)final_viewport_data; -} - -d3d_renderchain_driver_t null_d3d_renderchain = { - null_renderchain_free, - null_renderchain_new, - null_renderchain_init, - null_renderchain_set_final_viewport, - null_renderchain_add_pass, - null_renderchain_add_lut, - null_renderchain_add_state_tracker, - null_renderchain_render, - null_renderchain_convert_geometry, - NULL, - NULL, - NULL, - "null", -}; diff --git a/gfx/drivers_shader/glslang_util.cpp b/gfx/drivers_shader/glslang_util.cpp index 41d3527b36..05a648ca9b 100644 --- a/gfx/drivers_shader/glslang_util.cpp +++ b/gfx/drivers_shader/glslang_util.cpp @@ -44,7 +44,7 @@ bool glslang_read_shader_file(const char *path, vector *output, bool roo char tmp[PATH_MAX_LENGTH]; char *ptr = NULL; char *buf = nullptr; - ssize_t len = 0; + int64_t len = 0; const char *basename = path_basename(path); include_path[0] = tmp[0] = '\0'; diff --git a/gfx/drivers_shader/glslang_util.h b/gfx/drivers_shader/glslang_util.h index 006fadc490..cd26e42380 100644 --- a/gfx/drivers_shader/glslang_util.h +++ b/gfx/drivers_shader/glslang_util.h @@ -23,7 +23,7 @@ typedef enum glslang_format { SLANG_FORMAT_UNKNOWN = 0, - // 8-bit + /* 8-bit */ SLANG_FORMAT_R8_UNORM, SLANG_FORMAT_R8_UINT, SLANG_FORMAT_R8_SINT, @@ -35,11 +35,11 @@ typedef enum glslang_format SLANG_FORMAT_R8G8B8A8_SINT, SLANG_FORMAT_R8G8B8A8_SRGB, - // 10-bit + /* 10-bit */ SLANG_FORMAT_A2B10G10R10_UNORM_PACK32, SLANG_FORMAT_A2B10G10R10_UINT_PACK32, - // 16-bit + /* 16-bit */ SLANG_FORMAT_R16_UINT, SLANG_FORMAT_R16_SINT, SLANG_FORMAT_R16_SFLOAT, @@ -50,7 +50,7 @@ typedef enum glslang_format SLANG_FORMAT_R16G16B16A16_SINT, SLANG_FORMAT_R16G16B16A16_SFLOAT, - // 32-bit + /* 32-bit */ SLANG_FORMAT_R32_UINT, SLANG_FORMAT_R32_SINT, SLANG_FORMAT_R32_SFLOAT, @@ -105,7 +105,7 @@ struct glslang_output bool glslang_compile_shader(const char *shader_path, glslang_output *output); -// Helpers for internal use. +/* Helpers for internal use. */ bool glslang_read_shader_file(const char *path, std::vector *output, bool root_file); bool glslang_parse_meta(const std::vector &lines, glslang_meta *meta); #endif diff --git a/gfx/drivers_shader/shader_gl_cg.c b/gfx/drivers_shader/shader_gl_cg.c index 2fed59a303..4e89540b63 100644 --- a/gfx/drivers_shader/shader_gl_cg.c +++ b/gfx/drivers_shader/shader_gl_cg.c @@ -1053,10 +1053,50 @@ static void gl_cg_set_program_attributes(void *data, unsigned i) } } +static void gl_cg_init_menu_shaders(void *data) +{ + struct shader_program_info shader_prog_info; + cg_shader_data_t *cg = (cg_shader_data_t*)data; + + if (!cg) + return; + +#ifdef HAVE_SHADERPIPELINE + shader_prog_info.combined = stock_xmb_ribbon_simple; + shader_prog_info.is_file = false; + + gl_cg_compile_program( + cg, + VIDEO_SHADER_MENU, + &cg->prg[VIDEO_SHADER_MENU], + &shader_prog_info); + gl_cg_set_program_base_attrib(cg, VIDEO_SHADER_MENU); + + shader_prog_info.combined = stock_xmb_ribbon_simple; + shader_prog_info.is_file = false; + + gl_cg_compile_program( + cg, + VIDEO_SHADER_MENU_2, + &cg->prg[VIDEO_SHADER_MENU_2], + &shader_prog_info); + gl_cg_set_program_base_attrib(cg, VIDEO_SHADER_MENU_2); + + shader_prog_info.combined = stock_xmb_snow; + shader_prog_info.is_file = false; + + gl_cg_compile_program( + cg, + VIDEO_SHADER_MENU_3, + &cg->prg[VIDEO_SHADER_MENU_3], + &shader_prog_info); + gl_cg_set_program_base_attrib(cg, VIDEO_SHADER_MENU_3); +#endif +} + static void *gl_cg_init(void *data, const char *path) { unsigned i; - struct shader_program_info shader_prog_info; cg_shader_data_t *cg = (cg_shader_data_t*) calloc(1, sizeof(cg_shader_data_t)); @@ -1129,37 +1169,6 @@ static void *gl_cg_init(void *data, const char *path) gl_cg_set_shaders(cg->prg[1].fprg, cg->prg[1].vprg); -#ifdef HAVE_SHADERPIPELINE - shader_prog_info.combined = stock_xmb_ribbon_simple; - shader_prog_info.is_file = false; - - gl_cg_compile_program( - cg, - VIDEO_SHADER_MENU, - &cg->prg[VIDEO_SHADER_MENU], - &shader_prog_info); - gl_cg_set_program_base_attrib(cg, VIDEO_SHADER_MENU); - - shader_prog_info.combined = stock_xmb_ribbon_simple; - shader_prog_info.is_file = false; - - gl_cg_compile_program( - cg, - VIDEO_SHADER_MENU_2, - &cg->prg[VIDEO_SHADER_MENU_2], - &shader_prog_info); - gl_cg_set_program_base_attrib(cg, VIDEO_SHADER_MENU_2); - - shader_prog_info.combined = stock_xmb_snow; - shader_prog_info.is_file = false; - - gl_cg_compile_program( - cg, - VIDEO_SHADER_MENU_3, - &cg->prg[VIDEO_SHADER_MENU_3], - &shader_prog_info); - gl_cg_set_program_base_attrib(cg, VIDEO_SHADER_MENU_3); -#endif gl_cg_reset_attrib(cg); @@ -1271,6 +1280,7 @@ static struct video_shader *gl_cg_get_current_shader(void *data) const shader_backend_t gl_cg_backend = { gl_cg_init, + gl_cg_init_menu_shaders, gl_cg_deinit, gl_cg_set_params, gl_cg_set_uniform_parameter, diff --git a/gfx/drivers_shader/shader_glsl.c b/gfx/drivers_shader/shader_glsl.c index 3f5d077d5c..ad12be1116 100644 --- a/gfx/drivers_shader/shader_glsl.c +++ b/gfx/drivers_shader/shader_glsl.c @@ -493,8 +493,8 @@ static void gl_glsl_strip_parameter_pragmas(char *source) static bool gl_glsl_load_source_path(struct video_shader_pass *pass, const char *path) { - ssize_t len; - int nitems = pass ? filestream_read_file(path, + int64_t len = 0; + int64_t nitems = pass ? filestream_read_file(path, (void**)&pass->source.string.vertex, &len) : 0; if (nitems <= 0 || len <= 0) @@ -790,6 +790,113 @@ static void gl_glsl_deinit(void *data) free(glsl); } +static void gl_glsl_init_menu_shaders(void *data) +{ +#ifdef HAVE_SHADERPIPELINE + struct shader_program_info shader_prog_info; + glsl_shader_data_t *glsl = (glsl_shader_data_t*)data; + + if (!glsl) + return; + +#ifdef HAVE_OPENGLES + if (gl_query_extension("GL_OES_standard_derivatives")) + { + shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_ribbon_modern : stock_vertex_xmb_ribbon_legacy; + shader_prog_info.fragment = glsl_core ? core_stock_fragment_xmb : stock_fragment_xmb; + } + else + { + shader_prog_info.vertex = stock_vertex_xmb_ribbon_simple_legacy; + shader_prog_info.fragment = stock_fragment_xmb_ribbon_simple; + } +#else + shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_ribbon_modern : stock_vertex_xmb_ribbon_legacy; + shader_prog_info.fragment = glsl_core ? core_stock_fragment_xmb : stock_fragment_xmb; +#endif + shader_prog_info.is_file = false; + + gl_glsl_compile_program( + glsl, + VIDEO_SHADER_MENU, + &glsl->prg[VIDEO_SHADER_MENU], + &shader_prog_info); + gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU].id, + &glsl->uniforms[VIDEO_SHADER_MENU]); + + shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_simple_modern : stock_vertex_xmb_ribbon_simple_legacy; + shader_prog_info.fragment = stock_fragment_xmb_ribbon_simple; + + gl_glsl_compile_program( + glsl, + VIDEO_SHADER_MENU_2, + &glsl->prg[VIDEO_SHADER_MENU_2], + &shader_prog_info); + gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_2].id, + &glsl->uniforms[VIDEO_SHADER_MENU_2]); + +#if defined(HAVE_OPENGLES) + shader_prog_info.vertex = stock_vertex_xmb_snow_modern; +#else + shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy; +#endif + shader_prog_info.fragment = stock_fragment_xmb_simple_snow; + + gl_glsl_compile_program( + glsl, + VIDEO_SHADER_MENU_3, + &glsl->prg[VIDEO_SHADER_MENU_3], + &shader_prog_info); + gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_3].id, + &glsl->uniforms[VIDEO_SHADER_MENU_3]); + +#if defined(HAVE_OPENGLES) + shader_prog_info.vertex = stock_vertex_xmb_snow_modern; +#else + shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy; +#endif + shader_prog_info.fragment = stock_fragment_xmb_snow; + + gl_glsl_compile_program( + glsl, + VIDEO_SHADER_MENU_4, + &glsl->prg[VIDEO_SHADER_MENU_4], + &shader_prog_info); + gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_4].id, + &glsl->uniforms[VIDEO_SHADER_MENU_4]); + +#if defined(HAVE_OPENGLES) + shader_prog_info.vertex = stock_vertex_xmb_snow_modern; +#else + shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy; +#endif + shader_prog_info.fragment = stock_fragment_xmb_bokeh; + + gl_glsl_compile_program( + glsl, + VIDEO_SHADER_MENU_5, + &glsl->prg[VIDEO_SHADER_MENU_5], + &shader_prog_info); + gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_5].id, + &glsl->uniforms[VIDEO_SHADER_MENU_5]); + +#if defined(HAVE_OPENGLES) + shader_prog_info.vertex = stock_vertex_xmb_snow_modern; +#else + shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy; +#endif + shader_prog_info.fragment = stock_fragment_xmb_snowflake; + + gl_glsl_compile_program( + glsl, + VIDEO_SHADER_MENU_6, + &glsl->prg[VIDEO_SHADER_MENU_6], + &shader_prog_info); + gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_6].id, + &glsl->uniforms[VIDEO_SHADER_MENU_6]); +#endif +} + static void *gl_glsl_init(void *data, const char *path) { unsigned i; @@ -1015,104 +1122,6 @@ static void *gl_glsl_init(void *data, const char *path) glsl->uniforms[VIDEO_SHADER_STOCK_BLEND] = glsl->uniforms[0]; } -#ifdef HAVE_SHADERPIPELINE -#ifdef HAVE_OPENGLES - if (gl_query_extension("GL_OES_standard_derivatives")) - { - shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_ribbon_modern : stock_vertex_xmb_ribbon_legacy; - shader_prog_info.fragment = glsl_core ? core_stock_fragment_xmb : stock_fragment_xmb; - } - else - { - shader_prog_info.vertex = stock_vertex_xmb_ribbon_simple_legacy; - shader_prog_info.fragment = stock_fragment_xmb_ribbon_simple; - } -#else - shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_ribbon_modern : stock_vertex_xmb_ribbon_legacy; - shader_prog_info.fragment = glsl_core ? core_stock_fragment_xmb : stock_fragment_xmb; -#endif - shader_prog_info.is_file = false; - - gl_glsl_compile_program( - glsl, - VIDEO_SHADER_MENU, - &glsl->prg[VIDEO_SHADER_MENU], - &shader_prog_info); - gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU].id, - &glsl->uniforms[VIDEO_SHADER_MENU]); - - shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_simple_modern : stock_vertex_xmb_ribbon_simple_legacy; - shader_prog_info.fragment = stock_fragment_xmb_ribbon_simple; - - gl_glsl_compile_program( - glsl, - VIDEO_SHADER_MENU_2, - &glsl->prg[VIDEO_SHADER_MENU_2], - &shader_prog_info); - gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_2].id, - &glsl->uniforms[VIDEO_SHADER_MENU_2]); - -#if defined(HAVE_OPENGLES) - shader_prog_info.vertex = stock_vertex_xmb_snow_modern; -#else - shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy; -#endif - shader_prog_info.fragment = stock_fragment_xmb_simple_snow; - - gl_glsl_compile_program( - glsl, - VIDEO_SHADER_MENU_3, - &glsl->prg[VIDEO_SHADER_MENU_3], - &shader_prog_info); - gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_3].id, - &glsl->uniforms[VIDEO_SHADER_MENU_3]); - -#if defined(HAVE_OPENGLES) - shader_prog_info.vertex = stock_vertex_xmb_snow_modern; -#else - shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy; -#endif - shader_prog_info.fragment = stock_fragment_xmb_snow; - - gl_glsl_compile_program( - glsl, - VIDEO_SHADER_MENU_4, - &glsl->prg[VIDEO_SHADER_MENU_4], - &shader_prog_info); - gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_4].id, - &glsl->uniforms[VIDEO_SHADER_MENU_4]); - -#if defined(HAVE_OPENGLES) - shader_prog_info.vertex = stock_vertex_xmb_snow_modern; -#else - shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy; -#endif - shader_prog_info.fragment = stock_fragment_xmb_bokeh; - - gl_glsl_compile_program( - glsl, - VIDEO_SHADER_MENU_5, - &glsl->prg[VIDEO_SHADER_MENU_5], - &shader_prog_info); - gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_5].id, - &glsl->uniforms[VIDEO_SHADER_MENU_5]); - -#if defined(HAVE_OPENGLES) - shader_prog_info.vertex = stock_vertex_xmb_snow_modern; -#else - shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy; -#endif - shader_prog_info.fragment = stock_fragment_xmb_snowflake; - - gl_glsl_compile_program( - glsl, - VIDEO_SHADER_MENU_6, - &glsl->prg[VIDEO_SHADER_MENU_6], - &shader_prog_info); - gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_6].id, - &glsl->uniforms[VIDEO_SHADER_MENU_6]); -#endif - gl_glsl_reset_attrib(glsl); for (i = 0; i < GFX_MAX_SHADERS; i++) @@ -1486,9 +1495,9 @@ static bool gl_glsl_set_mvp(void *data, void *shader_data, const void *mat_data) #define gl_glsl_set_coord_array(attribs, coord1, coord2, coords, size, multiplier) \ unsigned y; \ - attribs[attribs_size].loc = coord1; \ - attribs[attribs_size].size = multiplier; \ - attribs[attribs_size].offset = size * sizeof(GLfloat); \ + attribs[attribs_size].loc = (GLint)coord1; \ + attribs[attribs_size].size = (GLsizei)multiplier; \ + attribs[attribs_size].offset = (GLsizei)(size * sizeof(GLfloat)); \ for (y = 0; y < (multiplier * coords->vertices); y++) \ buffer[y + size] = coord2[y]; \ size += multiplier * coords->vertices; \ @@ -1688,6 +1697,7 @@ void gl_glsl_set_context_type(bool core_profile, const shader_backend_t gl_glsl_backend = { gl_glsl_init, + gl_glsl_init_menu_shaders, gl_glsl_deinit, gl_glsl_set_params, gl_glsl_set_uniform_parameter, diff --git a/gfx/drivers_shader/shader_hlsl.c b/gfx/drivers_shader/shader_hlsl.c index be50cad69d..34481d6b3f 100644 --- a/gfx/drivers_shader/shader_hlsl.c +++ b/gfx/drivers_shader/shader_hlsl.c @@ -14,6 +14,8 @@ * If not, see . */ +#define CINTERFACE + #include #include #include @@ -23,6 +25,7 @@ #include "../../defines/d3d_defines.h" #include "../common/d3d_common.h" +#include "../common/d3d9_common.h" #ifdef HAVE_CONFIG_H #include "../../config.h" @@ -36,48 +39,6 @@ #include "../drivers/d3d_shaders/opaque.hlsl.d3d9.h" #include "shader_hlsl.h" -#ifdef __cplusplus - -#ifndef ID3DXConstantTable_SetDefaults -#define ID3DXConstantTable_SetDefaults(p,a) (p)->SetDefaults(a); -#endif - -#ifndef ID3DXConstantTable_SetFloatArray -#define ID3DXConstantTable_SetFloatArray(p,a,b,c,d) (p)->SetFloatArray(a,b,c,d) -#endif - -#ifndef ID3DXConstantTable_GetConstantByName -#define ID3DXConstantTable_GetConstantByName(p,a,b) ((p)->GetConstantByName(a, b)) -#endif - -#ifndef ID3DXConstantTable_SetMatrix -#define ID3DXConstantTable_SetMatrix(p,a,b,c) ((p)->SetMatrix(a,b,c)) -#endif - -#else - -#ifndef ID3DXConstantTable_SetDefaults -#define ID3DXConstantTable_SetDefaults(p,a) (p)->lpVtbl->SetDefaults(p,a) -#endif - -#ifndef ID3DXConstantTable_SetFloatArray -#define ID3DXConstantTable_SetFloatArray(p,a,b,c,d) (p)->lpVtbl->SetFloatArray(p,a,b,c,d) -#endif - -#ifndef ID3DXConstantTable_GetConstantByName -#define ID3DXConstantTable_GetConstantByName(p,a,b) ((p)->lpVtbl->GetConstantByName(p, a, b)) -#endif - -#ifndef ID3DXConstantTable_SetMatrix -#define ID3DXConstantTable_SetMatrix(p,a,b,c) ((p)->lpVtbl->SetMatrix(p,a,b,c)) -#endif - -#endif - -#define set_param_2f(param, xy, constanttable) if (param) { ID3DXConstantTable_SetFloatArray(constanttable, d3dr, param, xy, 2); } -#define get_constant_by_name(a, b, constanttable) ID3DXConstantTable_GetConstantByName(constanttable, a, b) - - struct shader_program_hlsl_data { LPDIRECT3DVERTEXSHADER9 vprg; @@ -165,65 +126,77 @@ static void hlsl_set_uniform_parameter( static void hlsl_set_params(void *dat, void *shader_data) { float ori_size[2], tex_size[2], out_size[2]; - video_shader_ctx_params_t *params = (video_shader_ctx_params_t*)dat; - void *data = params->data; - unsigned width = params->width; - unsigned height = params->height; - unsigned tex_width = params->tex_width; - unsigned tex_height = params->tex_height; - unsigned out_width = params->out_width; - unsigned out_height = params->out_height; - unsigned frame_count = params->frame_counter; - const void *_info = params->info; - const void *_prev_info = params->prev_info; - const void *_feedback_info = params->feedback_info; - const void *_fbo_info = params->fbo_info; - unsigned fbo_info_cnt = params->fbo_info_cnt; - float frame_cnt = frame_count; - const struct video_tex_info *info = (const struct video_tex_info*)_info; - const struct video_tex_info *prev_info = (const struct video_tex_info*)_prev_info; - const struct video_tex_info *fbo_info = (const struct video_tex_info*)_fbo_info; - hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)shader_data; - LPDIRECT3DDEVICE9 d3dr = (LPDIRECT3DDEVICE9)hlsl->dev; + video_shader_ctx_params_t *params = (video_shader_ctx_params_t*)dat; + void *data = params->data; + unsigned width = params->width; + unsigned height = params->height; + unsigned tex_width = params->tex_width; + unsigned tex_height = params->tex_height; + unsigned out_width = params->out_width; + unsigned out_height = params->out_height; + unsigned frame_count = params->frame_counter; + const void *_info = params->info; + const void *_prev_info = params->prev_info; + const void *_feedback_info = params->feedback_info; + const void *_fbo_info = params->fbo_info; + unsigned fbo_info_cnt = params->fbo_info_cnt; + float frame_cnt = frame_count; + const struct video_tex_info *info = (const struct video_tex_info*)_info; + const struct video_tex_info *prev_info = (const struct video_tex_info*)_prev_info; + const struct video_tex_info *fbo_info = (const struct video_tex_info*)_fbo_info; + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)shader_data; + LPDIRECT3DDEVICE9 d3dr = (LPDIRECT3DDEVICE9)hlsl->dev; + struct shader_program_hlsl_data *program = NULL; if (!hlsl || !d3dr) return; - ori_size[0] = (float)width; - ori_size[1] = (float)height; - tex_size[0] = (float)tex_width; - tex_size[1] = (float)tex_height; - out_size[0] = (float)out_width; - out_size[1] = (float)out_height; + program = &hlsl->prg[hlsl->active_idx]; - ID3DXConstantTable_SetDefaults( - hlsl->prg[hlsl->active_idx].f_ctable, d3dr); - ID3DXConstantTable_SetDefaults( - hlsl->prg[hlsl->active_idx].v_ctable, d3dr); + if (!program) + return; - set_param_2f(hlsl->prg[hlsl->active_idx].vid_size_f, ori_size, hlsl->prg[hlsl->active_idx].f_ctable); - set_param_2f(hlsl->prg[hlsl->active_idx].tex_size_f, tex_size, hlsl->prg[hlsl->active_idx].f_ctable); - set_param_2f(hlsl->prg[hlsl->active_idx].out_size_f, out_size, hlsl->prg[hlsl->active_idx].f_ctable); + ori_size[0] = (float)width; + ori_size[1] = (float)height; + tex_size[0] = (float)tex_width; + tex_size[1] = (float)tex_height; + out_size[0] = (float)out_width; + out_size[1] = (float)out_height; - if (hlsl->prg[hlsl->active_idx].frame_cnt_f) - d3dx_constant_table_set_float(hlsl->prg[hlsl->active_idx].f_ctable, - d3dr,hlsl->prg[hlsl->active_idx].frame_cnt_f, frame_cnt); + d3d9x_constant_table_set_defaults(d3dr, program->f_ctable); + d3d9x_constant_table_set_defaults(d3dr, program->v_ctable); - if (hlsl->prg[hlsl->active_idx].frame_dir_f) - d3dx_constant_table_set_float(hlsl->prg[hlsl->active_idx].f_ctable, - d3dr, hlsl->prg[hlsl->active_idx].frame_dir_f, state_manager_frame_is_reversed() ? -1.0 : 1.0); + if (program->vid_size_f) + d3d9x_constant_table_set_float_array(d3dr, program->f_ctable, (void*)program->vid_size_f, ori_size, 2); + if (program->tex_size_f) + d3d9x_constant_table_set_float_array(d3dr, program->f_ctable, (void*)program->tex_size_f, tex_size, 2); + if (program->out_size_f) + d3d9x_constant_table_set_float_array(d3dr, program->f_ctable, (void*)program->out_size_f, out_size, 2); - set_param_2f(hlsl->prg[hlsl->active_idx].vid_size_v, ori_size, hlsl->prg[hlsl->active_idx].v_ctable); - set_param_2f(hlsl->prg[hlsl->active_idx].tex_size_v, tex_size, hlsl->prg[hlsl->active_idx].v_ctable); - set_param_2f(hlsl->prg[hlsl->active_idx].out_size_v, out_size, hlsl->prg[hlsl->active_idx].v_ctable); + if (program->frame_cnt_f) + d3d9x_constant_table_set_float(program->f_ctable, + d3dr, (void*)program->frame_cnt_f, frame_cnt); - if (hlsl->prg[hlsl->active_idx].frame_cnt_v) - d3dx_constant_table_set_float(hlsl->prg[hlsl->active_idx].v_ctable, - d3dr, hlsl->prg[hlsl->active_idx].frame_cnt_v, frame_cnt); + if (program->frame_dir_f) + d3d9x_constant_table_set_float(program->f_ctable, + d3dr, (void*)program->frame_dir_f, + state_manager_frame_is_reversed() ? -1.0 : 1.0); - if (hlsl->prg[hlsl->active_idx].frame_dir_v) - d3dx_constant_table_set_float(hlsl->prg[hlsl->active_idx].v_ctable, - d3dr, hlsl->prg[hlsl->active_idx].frame_dir_v, state_manager_frame_is_reversed() ? -1.0 : 1.0); + if (program->vid_size_v) + d3d9x_constant_table_set_float_array(d3dr, program->v_ctable, (void*)program->vid_size_v, ori_size, 2); + if (program->tex_size_v) + d3d9x_constant_table_set_float_array(d3dr, program->v_ctable, (void*)program->tex_size_v, tex_size, 2); + if (program->out_size_v) + d3d9x_constant_table_set_float_array(d3dr, program->v_ctable, (void*)program->out_size_v, out_size, 2); + + if (program->frame_cnt_v) + d3d9x_constant_table_set_float(program->v_ctable, + d3dr, (void*)program->frame_cnt_v, frame_cnt); + + if (program->frame_dir_v) + d3d9x_constant_table_set_float(program->v_ctable, + d3dr, (void*)program->frame_dir_v, + state_manager_frame_is_reversed() ? -1.0 : 1.0); /* TODO - set lookup textures/FBO textures/state parameters/etc */ } @@ -247,43 +220,49 @@ static bool hlsl_compile_program( if (program_info->is_file) { - if (!d3dx_compile_shader_from_file(program_info->combined, NULL, NULL, + if (!d3d9x_compile_shader_from_file(program_info->combined, NULL, NULL, "main_fragment", "ps_3_0", 0, &code_f, &listing_f, &program->f_ctable)) goto error; - if (!d3dx_compile_shader_from_file(program_info->combined, NULL, NULL, + if (!d3d9x_compile_shader_from_file(program_info->combined, NULL, NULL, "main_vertex", "vs_3_0", 0, &code_v, &listing_v, &program->v_ctable)) goto error; } else { /* TODO - crashes currently - to do with 'end of line' of stock shader */ - if (!d3dx_compile_shader(program_info->combined, + if (!d3d9x_compile_shader(program_info->combined, strlen(program_info->combined), NULL, NULL, "main_fragment", "ps_3_0", 0, &code_f, &listing_f, &program->f_ctable )) + { + RARCH_ERR("Failure building stock fragment shader..\n"); goto error; - if (!d3dx_compile_shader(program_info->combined, + } + if (!d3d9x_compile_shader(program_info->combined, strlen(program_info->combined), NULL, NULL, "main_vertex", "vs_3_0", 0, &code_v, &listing_v, &program->v_ctable )) + { + RARCH_ERR("Failure building stock vertex shader..\n"); goto error; + } } - d3d_create_pixel_shader(d3dr, (const DWORD*)d3dx_get_buffer_ptr(code_f), (void**)&program->fprg); - d3d_create_vertex_shader(d3dr, (const DWORD*)d3dx_get_buffer_ptr(code_v), (void**)&program->vprg); - d3dxbuffer_release((void*)code_f); - d3dxbuffer_release((void*)code_v); + d3d9_create_pixel_shader(d3dr, (const DWORD*)d3d9x_get_buffer_ptr(code_f), (void**)&program->fprg); + d3d9_create_vertex_shader(d3dr, (const DWORD*)d3d9x_get_buffer_ptr(code_v), (void**)&program->vprg); + d3d9x_buffer_release((void*)code_f); + d3d9x_buffer_release((void*)code_v); return true; error: RARCH_ERR("Cg/HLSL error:\n"); if (listing_f) - RARCH_ERR("Fragment:\n%s\n", (char*)d3dx_get_buffer_ptr(listing_f)); + RARCH_ERR("Fragment:\n%s\n", (char*)d3d9x_get_buffer_ptr(listing_f)); if (listing_v) - RARCH_ERR("Vertex:\n%s\n", (char*)d3dx_get_buffer_ptr(listing_v)); - d3dxbuffer_release((void*)listing_f); - d3dxbuffer_release((void*)listing_v); + RARCH_ERR("Vertex:\n%s\n", (char*)d3d9x_get_buffer_ptr(listing_v)); + d3d9x_buffer_release((void*)listing_f); + d3d9x_buffer_release((void*)listing_v); return false; } @@ -306,21 +285,35 @@ static bool hlsl_load_stock(hlsl_shader_data_t *hlsl) static void hlsl_set_program_attributes(hlsl_shader_data_t *hlsl, unsigned i) { + struct shader_program_hlsl_data *program = NULL; if (!hlsl) return; - hlsl->prg[i].vid_size_f = get_constant_by_name(NULL, "$IN.video_size", hlsl->prg[i].f_ctable); - hlsl->prg[i].tex_size_f = get_constant_by_name(NULL, "$IN.texture_size", hlsl->prg[i].f_ctable); - hlsl->prg[i].out_size_f = get_constant_by_name(NULL, "$IN.output_size", hlsl->prg[i].f_ctable); - hlsl->prg[i].frame_cnt_f = get_constant_by_name(NULL, "$IN.frame_count", hlsl->prg[i].f_ctable); - hlsl->prg[i].frame_dir_f = get_constant_by_name(NULL, "$IN.frame_direction", hlsl->prg[i].f_ctable); - hlsl->prg[i].vid_size_v = get_constant_by_name(NULL, "$IN.video_size", hlsl->prg[i].v_ctable); - hlsl->prg[i].tex_size_v = get_constant_by_name(NULL, "$IN.texture_size", hlsl->prg[i].v_ctable); - hlsl->prg[i].out_size_v = get_constant_by_name(NULL, "$IN.output_size", hlsl->prg[i].v_ctable); - hlsl->prg[i].frame_cnt_v = get_constant_by_name(NULL, "$IN.frame_count", hlsl->prg[i].v_ctable); - hlsl->prg[i].frame_dir_v = get_constant_by_name(NULL, "$IN.frame_direction", hlsl->prg[i].v_ctable); - hlsl->prg[i].mvp = get_constant_by_name(NULL, "$modelViewProj", hlsl->prg[i].v_ctable); - d3d_matrix_identity(&hlsl->prg[i].mvp_val); + program = &hlsl->prg[i]; + + if (!program) + return; + + if (program->f_ctable) + { + program->vid_size_f = (D3DXHANDLE)d3d9x_constant_table_get_constant_by_name(program->f_ctable, NULL, "$IN.video_size"); + program->tex_size_f = (D3DXHANDLE)d3d9x_constant_table_get_constant_by_name(program->f_ctable, NULL, "$IN.texture_size"); + program->out_size_f = (D3DXHANDLE)d3d9x_constant_table_get_constant_by_name(program->f_ctable, NULL, "$IN.output_size"); + program->frame_cnt_f = (D3DXHANDLE)d3d9x_constant_table_get_constant_by_name(program->f_ctable, NULL, "$IN.frame_count"); + program->frame_dir_f = (D3DXHANDLE)d3d9x_constant_table_get_constant_by_name(program->f_ctable, NULL, "$IN.frame_direction"); + } + + if (program->v_ctable) + { + program->vid_size_v = (D3DXHANDLE)d3d9x_constant_table_get_constant_by_name(program->v_ctable, NULL, "$IN.video_size"); + program->tex_size_v = (D3DXHANDLE)d3d9x_constant_table_get_constant_by_name(program->v_ctable, NULL, "$IN.texture_size"); + program->out_size_v = (D3DXHANDLE)d3d9x_constant_table_get_constant_by_name(program->v_ctable, NULL, "$IN.output_size"); + program->frame_cnt_v = (D3DXHANDLE)d3d9x_constant_table_get_constant_by_name(program->v_ctable, NULL, "$IN.frame_count"); + program->frame_dir_v = (D3DXHANDLE)d3d9x_constant_table_get_constant_by_name(program->v_ctable, NULL, "$IN.frame_direction"); + program->mvp = (D3DXHANDLE)d3d9x_constant_table_get_constant_by_name(program->v_ctable, NULL, "$modelViewProj"); + } + + d3d_matrix_identity(&program->mvp_val); } static bool hlsl_load_shader(hlsl_shader_data_t *hlsl, @@ -350,7 +343,8 @@ static bool hlsl_load_plain(hlsl_shader_data_t *hlsl, const char *path) if (!hlsl_load_stock(hlsl)) return false; - hlsl->cg_shader = (struct video_shader*)calloc(1, sizeof(*hlsl->cg_shader)); + hlsl->cg_shader = (struct video_shader*) + calloc(1, sizeof(*hlsl->cg_shader)); if (!hlsl->cg_shader) return false; @@ -387,18 +381,18 @@ static void hlsl_deinit_progs(hlsl_shader_data_t *hlsl) for (i = 1; i < RARCH_HLSL_MAX_SHADERS; i++) { if (hlsl->prg[i].fprg && hlsl->prg[i].fprg != hlsl->prg[0].fprg) - d3d_free_pixel_shader(hlsl->dev, hlsl->prg[i].fprg); + d3d9_free_pixel_shader(hlsl->dev, hlsl->prg[i].fprg); if (hlsl->prg[i].vprg && hlsl->prg[i].vprg != hlsl->prg[0].vprg) - d3d_free_vertex_shader(hlsl->dev, hlsl->prg[i].vprg); + d3d9_free_vertex_shader(hlsl->dev, hlsl->prg[i].vprg); hlsl->prg[i].fprg = NULL; hlsl->prg[i].vprg = NULL; } if (hlsl->prg[0].fprg) - d3d_free_pixel_shader(hlsl->dev, hlsl->prg[0].fprg); + d3d9_free_pixel_shader(hlsl->dev, hlsl->prg[0].fprg); if (hlsl->prg[0].vprg) - d3d_free_vertex_shader(hlsl->dev, hlsl->prg[0].vprg); + d3d9_free_vertex_shader(hlsl->dev, hlsl->prg[0].vprg); hlsl->prg[0].fprg = NULL; hlsl->prg[0].vprg = NULL; @@ -419,7 +413,8 @@ static bool hlsl_load_preset(hlsl_shader_data_t *hlsl, const char *path) goto error; if (!hlsl->cg_shader) - hlsl->cg_shader = (struct video_shader*)calloc(1, sizeof(*hlsl->cg_shader)); + hlsl->cg_shader = (struct video_shader*)calloc + (1, sizeof(*hlsl->cg_shader)); if (!hlsl->cg_shader) goto error; @@ -433,7 +428,8 @@ static bool hlsl_load_preset(hlsl_shader_data_t *hlsl, const char *path) if (hlsl->cg_shader->passes > RARCH_HLSL_MAX_SHADERS - 3) { - RARCH_WARN("Too many shaders ... Capping shader amount to %d.\n", RARCH_HLSL_MAX_SHADERS - 3); + RARCH_WARN("Too many shaders ... " + "Capping shader amount to %d.\n", RARCH_HLSL_MAX_SHADERS - 3); hlsl->cg_shader->passes = RARCH_HLSL_MAX_SHADERS - 3; } @@ -458,8 +454,8 @@ error: static void *hlsl_init(void *data, const char *path) { unsigned i; - d3d_video_t *d3d = (d3d_video_t*)data; - hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*) + d3d9_video_t *d3d = (d3d9_video_t*)data; + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*) calloc(1, sizeof(hlsl_shader_data_t)); if (!hlsl || !d3d) @@ -481,11 +477,16 @@ static void *hlsl_init(void *data, const char *path) goto error; } + RARCH_LOG("Setting up program attributes...\n"); + RARCH_LOG("Shader passes: %d\n", hlsl->cg_shader->passes); + for(i = 1; i <= hlsl->cg_shader->passes; i++) hlsl_set_program_attributes(hlsl, i); - d3d_set_vertex_shader(hlsl->dev, 1, hlsl->prg[1].vprg); - d3d_set_pixel_shader(hlsl->dev, hlsl->prg[1].fprg); + RARCH_LOG("Setting up vertex shader...\n"); + d3d9_set_vertex_shader(hlsl->dev, 1, hlsl->prg[1].vprg); + RARCH_LOG("Setting up pixel shader...\n"); + d3d9_set_pixel_shader(hlsl->dev, hlsl->prg[1].fprg); return hlsl; @@ -513,19 +514,26 @@ static void hlsl_deinit(void *data) free(hlsl); } -static void hlsl_use(void *data, void *shader_data, unsigned idx, bool set_active) +static void hlsl_use(void *data, void *shader_data, + unsigned idx, bool set_active) { - hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)shader_data; - LPDIRECT3DDEVICE9 d3dr = hlsl ? (LPDIRECT3DDEVICE9)hlsl->dev : NULL; + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)shader_data; + LPDIRECT3DDEVICE9 d3dr = hlsl ? (LPDIRECT3DDEVICE9)hlsl->dev : NULL; + struct shader_program_hlsl_data *program = NULL; - if (!hlsl || !hlsl->prg[idx].vprg || !hlsl->prg[idx].fprg) + if (!hlsl) + return; + + program = &hlsl->prg[idx]; + + if (!program || !program->vprg || !program->fprg) return; if (set_active) - hlsl->active_idx = idx; + hlsl->active_idx = idx; - d3d_set_vertex_shader(d3dr, idx, hlsl->prg[idx].vprg); - d3d_set_pixel_shader(d3dr, hlsl->prg[idx].fprg); + d3d9_set_vertex_shader(d3dr, idx, program->vprg); + d3d9_set_pixel_shader(d3dr, program->fprg); } static unsigned hlsl_num(void *data) @@ -549,27 +557,34 @@ static bool hlsl_filter_type(void *data, unsigned idx, bool *smooth) return false; } -static void hlsl_shader_scale(void *data, unsigned idx, struct gfx_fbo_scale *scale) +static void hlsl_shader_scale(void *data, unsigned idx, + struct gfx_fbo_scale *scale) { hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)data; if (hlsl && idx) - *scale = hlsl->cg_shader->pass[idx - 1].fbo; + *scale = hlsl->cg_shader->pass[idx - 1].fbo; else - scale->valid = false; + scale->valid = false; } static bool hlsl_set_mvp(void *data, void *shader_data, const void *mat_data) { - hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)shader_data; - LPDIRECT3DDEVICE9 d3dr = hlsl ? (LPDIRECT3DDEVICE9)hlsl->dev : NULL; - const math_matrix_4x4 *mat = (const math_matrix_4x4*)mat_data; + hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)shader_data; + LPDIRECT3DDEVICE9 d3dr = hlsl ? + (LPDIRECT3DDEVICE9)hlsl->dev : NULL; + const math_matrix_4x4 *mat = (const math_matrix_4x4*)mat_data; + struct shader_program_hlsl_data *program = NULL; - if (!hlsl || !hlsl->prg[hlsl->active_idx].mvp) + if (!hlsl) return false; - ID3DXConstantTable_SetMatrix(hlsl->prg[hlsl->active_idx].v_ctable, d3dr, - hlsl->prg[hlsl->active_idx].mvp, - &hlsl->prg[hlsl->active_idx].mvp_val); + program = &hlsl->prg[hlsl->active_idx]; + + if (!program || !program->mvp) + return false; + + d3d9x_constant_table_set_matrix(d3dr, program->v_ctable, + (void*)program->mvp, &program->mvp_val); return true; } @@ -590,8 +605,24 @@ static struct video_shader *hlsl_get_current_shader(void *data) return NULL; } +static enum gfx_wrap_type hlsl_wrap_type(void *data, unsigned idx) +{ +#if 0 + /* TODO/FIXME - actual implementation */ +#endif + return RARCH_WRAP_BORDER; +} + +static bool hlsl_set_coords(void *handle_data, + void *shader_data, const struct video_coords *coords) +{ + /* TODO/FIXME - actual implementation */ + return false; +} + const shader_backend_t hlsl_backend = { hlsl_init, + NULL, /* hlsl_init_menu_shaders */ hlsl_deinit, hlsl_set_params, hlsl_set_uniform_parameter, @@ -599,9 +630,9 @@ const shader_backend_t hlsl_backend = { hlsl_use, hlsl_num, hlsl_filter_type, - NULL, /* hlsl_wrap_type */ + hlsl_wrap_type, hlsl_shader_scale, - NULL, /* hlsl_set_coords */ + hlsl_set_coords, hlsl_set_mvp, NULL, /* hlsl_get_prev_textures */ hlsl_get_feedback_pass, diff --git a/gfx/drivers_shader/shader_null.c b/gfx/drivers_shader/shader_null.c index d85cfd1b97..792c03f759 100644 --- a/gfx/drivers_shader/shader_null.c +++ b/gfx/drivers_shader/shader_null.c @@ -77,6 +77,7 @@ static bool shader_null_compile_program( const shader_backend_t shader_null_backend = { shader_null_init, + NULL, shader_null_deinit, NULL, shader_null_set_uniform_parameter, diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp index de864eaf61..57559d3258 100644 --- a/gfx/drivers_shader/shader_vulkan.cpp +++ b/gfx/drivers_shader/shader_vulkan.cpp @@ -56,62 +56,6 @@ static unsigned num_miplevels(unsigned width, unsigned height) return levels; } -static void image_layout_transition_levels( - VkCommandBuffer cmd, VkImage image, uint32_t levels, - VkImageLayout old_layout, VkImageLayout new_layout, - VkAccessFlags src_access, VkAccessFlags dst_access, - VkPipelineStageFlags src_stages, VkPipelineStageFlags dst_stages) -{ - VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; - - barrier.srcAccessMask = src_access; - barrier.dstAccessMask = dst_access; - barrier.oldLayout = old_layout; - barrier.newLayout = new_layout; - barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.image = image; - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - barrier.subresourceRange.levelCount = levels; - barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; - - vkCmdPipelineBarrier(cmd, - src_stages, - dst_stages, - false, - 0, nullptr, - 0, nullptr, - 1, &barrier); -} - -static void image_layout_transition( - VkCommandBuffer cmd, VkImage image, - VkImageLayout old_layout, VkImageLayout new_layout, - VkAccessFlags src_access, VkAccessFlags dst_access, - VkPipelineStageFlags src_stages, VkPipelineStageFlags dst_stages) -{ - image_layout_transition_levels(cmd, image, VK_REMAINING_MIP_LEVELS, - old_layout, new_layout, - src_access, dst_access, - src_stages, dst_stages); -} - -static uint32_t find_memory_type( - const VkPhysicalDeviceMemoryProperties &mem_props, - uint32_t device_reqs, uint32_t host_reqs) -{ - uint32_t i; - for (i = 0; i < VK_MAX_MEMORY_TYPES; i++) - { - if ((device_reqs & (1u << i)) && - (mem_props.memoryTypes[i].propertyFlags & host_reqs) == host_reqs) - return i; - } - - RARCH_ERR("[Vulkan]: Failed to find valid memory type. This should never happen."); - abort(); -} - static uint32_t find_memory_type_fallback( const VkPhysicalDeviceMemoryProperties &mem_props, uint32_t device_reqs, uint32_t host_reqs) @@ -124,7 +68,7 @@ static uint32_t find_memory_type_fallback( return i; } - return find_memory_type(mem_props, device_reqs, 0); + return vulkan_find_memory_type(&mem_props, device_reqs, 0); } static void build_identity_matrix(float *data) @@ -1048,8 +992,8 @@ void vulkan_filter_chain::update_history(DeferredDisposer &disposer, VkCommandBu // Transition input texture to something appropriate. if (input_texture.layout != VK_IMAGE_LAYOUT_GENERAL) { - image_layout_transition(cmd, - input_texture.image, + vulkan_image_layout_transition_levels(cmd, + input_texture.image,VK_REMAINING_MIP_LEVELS, input_texture.layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0, @@ -1075,8 +1019,8 @@ void vulkan_filter_chain::update_history(DeferredDisposer &disposer, VkCommandBu // Transition input texture back. if (input_texture.layout != VK_IMAGE_LAYOUT_GENERAL) { - image_layout_transition(cmd, - input_texture.image, + vulkan_image_layout_transition_levels(cmd, + input_texture.image,VK_REMAINING_MIP_LEVELS, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, input_texture.layout, 0, @@ -1205,8 +1149,8 @@ Buffer::Buffer(VkDevice device, VkMemoryAllocateInfo alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; alloc.allocationSize = mem_reqs.size; - alloc.memoryTypeIndex = find_memory_type( - mem_props, mem_reqs.memoryTypeBits, + alloc.memoryTypeIndex = vulkan_find_memory_type( + &mem_props, mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); @@ -2056,8 +2000,8 @@ void Pass::build_commands( // the passes that end up on-screen. if (!final_pass) { - // Render. - image_layout_transition_levels(cmd, + /* Render. */ + vulkan_image_layout_transition_levels(cmd, framebuffer->get_image(), 1, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, @@ -2140,9 +2084,9 @@ void Pass::build_commands( else { // Barrier to sync with next pass. - image_layout_transition( + vulkan_image_layout_transition_levels( cmd, - framebuffer->get_image(), + framebuffer->get_image(),VK_REMAINING_MIP_LEVELS, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, @@ -2175,7 +2119,7 @@ void Framebuffer::clear(VkCommandBuffer cmd) VkClearColorValue color; VkImageSubresourceRange range; - image_layout_transition(cmd, image, + vulkan_image_layout_transition_levels(cmd, image,VK_REMAINING_MIP_LEVELS, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, @@ -2191,7 +2135,7 @@ void Framebuffer::clear(VkCommandBuffer cmd) vkCmdClearColorImage(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &color, 1, &range); - image_layout_transition(cmd, image, + vulkan_image_layout_transition_levels(cmd, image,VK_REMAINING_MIP_LEVELS, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, @@ -2330,7 +2274,7 @@ void Framebuffer::copy(VkCommandBuffer cmd, { VkImageCopy region; - image_layout_transition(cmd, image, + vulkan_image_layout_transition_levels(cmd, image,VK_REMAINING_MIP_LEVELS, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, @@ -2350,7 +2294,7 @@ void Framebuffer::copy(VkCommandBuffer cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - image_layout_transition(cmd, image, + vulkan_image_layout_transition_levels(cmd, image,VK_REMAINING_MIP_LEVELS, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, @@ -2688,9 +2632,9 @@ static unique_ptr vulkan_filter_chain_load_lut(VkCommandBuffer cm image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; vkCreateImage(info->device, &image_info, nullptr, &tex); vkGetImageMemoryRequirements(info->device, tex, &mem_reqs); - alloc.allocationSize = mem_reqs.size; - alloc.memoryTypeIndex = find_memory_type( - *info->memory_properties, + alloc.allocationSize = mem_reqs.size; + alloc.memoryTypeIndex = vulkan_find_memory_type( + &*info->memory_properties, mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); @@ -2717,7 +2661,7 @@ static unique_ptr vulkan_filter_chain_load_lut(VkCommandBuffer cm memcpy(ptr, image.pixels, image.width * image.height * sizeof(uint32_t)); buffer->unmap(); - image_layout_transition(cmd, tex, + vulkan_image_layout_transition_levels(cmd, tex,VK_REMAINING_MIP_LEVELS, VK_IMAGE_LAYOUT_UNDEFINED, shader->mipmap ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT, @@ -2758,7 +2702,7 @@ static unique_ptr vulkan_filter_chain_load_lut(VkCommandBuffer cm /* Only injects execution and memory barriers, * not actual transition. */ - image_layout_transition(cmd, tex, + vulkan_image_layout_transition_levels(cmd, tex, VK_REMAINING_MIP_LEVELS, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_TRANSFER_WRITE_BIT, @@ -2772,7 +2716,7 @@ static unique_ptr vulkan_filter_chain_load_lut(VkCommandBuffer cm 1, &blit_region, VK_FILTER_LINEAR); } - image_layout_transition(cmd, tex, + vulkan_image_layout_transition_levels(cmd, tex,VK_REMAINING_MIP_LEVELS, shader->mipmap ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, @@ -3011,7 +2955,8 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset( pass_info.rt_format = tmpinfo.swapchain.format; if (explicit_format) - RARCH_WARN("[slang]: Using explicit format for last pass in chain, but it is not rendered to framebuffer, using swapchain format instead.\n"); + RARCH_WARN("[slang]: Using explicit format for last pass in chain," + " but it is not rendered to framebuffer, using swapchain format instead.\n"); } else { diff --git a/gfx/drivers_shader/slang_preprocess.cpp b/gfx/drivers_shader/slang_preprocess.cpp index ec4daa666e..0119be2346 100644 --- a/gfx/drivers_shader/slang_preprocess.cpp +++ b/gfx/drivers_shader/slang_preprocess.cpp @@ -18,8 +18,10 @@ #include #include #include + +#include + #include "../../verbosity.h" -#include "../../libretro-common/include/compat/strl.h" using namespace std; @@ -28,28 +30,32 @@ bool slang_preprocess_parse_parameters(glslang_meta& meta, { unsigned old_num_parameters = shader->num_parameters; - // Assumes num_parameters is initialized to something sane. + /* Assumes num_parameters is + * initialized to something sane. */ for (auto ¶m : meta.parameters) { bool mismatch_dup = false; - bool dup = false; - - auto itr = find_if(shader->parameters, shader->parameters + shader->num_parameters, - [&](const video_shader_parameter &parsed_param) { + bool dup = false; + auto itr = find_if(shader->parameters, + shader->parameters + shader->num_parameters, + [&](const video_shader_parameter &parsed_param) + { return param.id == parsed_param.id; }); if (itr != shader->parameters + shader->num_parameters) { dup = true; - // Allow duplicate #pragma parameter, but only if they are exactly the same. + /* Allow duplicate #pragma parameter, but only + * if they are exactly the same. */ if (param.desc != itr->desc || - param.initial != itr->initial || - param.minimum != itr->minimum || - param.maximum != itr->maximum || - param.step != itr->step) + param.initial != itr->initial || + param.minimum != itr->minimum || + param.maximum != itr->maximum || + param.step != itr->step) { - RARCH_ERR("[Vulkan]: Duplicate parameters found for \"%s\", but arguments do not match.\n", + RARCH_ERR("[Vulkan]: Duplicate parameters" + " found for \"%s\", but arguments do not match.\n", itr->id); mismatch_dup = true; } @@ -70,7 +76,7 @@ bool slang_preprocess_parse_parameters(glslang_meta& meta, p.initial = param.initial; p.minimum = param.minimum; p.maximum = param.maximum; - p.step = param.step; + p.step = param.step; p.current = param.initial; } @@ -82,12 +88,11 @@ bool slang_preprocess_parse_parameters(const char *shader_path, { glslang_meta meta; vector lines; + if (!glslang_read_shader_file(shader_path, &lines, true)) return false; - if (!glslang_parse_meta(lines, &meta)) return false; - return slang_preprocess_parse_parameters(meta, shader); } diff --git a/gfx/drivers_shader/slang_process.cpp b/gfx/drivers_shader/slang_process.cpp index c8bbf95761..8dc32b6312 100644 --- a/gfx/drivers_shader/slang_process.cpp +++ b/gfx/drivers_shader/slang_process.cpp @@ -17,7 +17,8 @@ using namespace spirv_cross; using namespace std; template -static bool set_unique_map(unordered_map& m, const string& name, const P& p) +static bool set_unique_map(unordered_map& m, + const string& name, const P& p) { auto itr = m.find(name); if (itr != end(m)) @@ -31,7 +32,8 @@ static bool set_unique_map(unordered_map& m, const string& name, cons } template -static string get_semantic_name(const unordered_map* map, S semantic, unsigned index) +static string get_semantic_name(const unordered_map* map, + S semantic, unsigned index) { for (const pair& m : *map) { @@ -42,7 +44,8 @@ static string get_semantic_name(const unordered_map* map, S semantic, } static string -get_semantic_name(slang_reflection& reflection, slang_semantic semantic, unsigned index) +get_semantic_name(slang_reflection& reflection, + slang_semantic semantic, unsigned index) { static const char* names[] = { "MVP", @@ -57,7 +60,8 @@ get_semantic_name(slang_reflection& reflection, slang_semantic semantic, unsigne } static string -get_semantic_name(slang_reflection& reflection, slang_texture_semantic semantic, unsigned index) +get_semantic_name(slang_reflection& reflection, + slang_texture_semantic semantic, unsigned index) { static const char* names[] = { "Original", "Source", "OriginalHistory", "PassOutput", "PassFeedback", @@ -71,7 +75,8 @@ get_semantic_name(slang_reflection& reflection, slang_texture_semantic semantic, } static string get_size_semantic_name( - slang_reflection& reflection, slang_texture_semantic semantic, unsigned index) + slang_reflection& reflection, + slang_texture_semantic semantic, unsigned index) { static const char* names[] = { "OriginalSize", "SourceSize", "OriginalHistorySize", "PassOutputSize", "PassFeedbackSize", @@ -94,10 +99,14 @@ static bool slang_process_reflection( const semantics_map_t* map, pass_semantics_t* out) { + int semantic; + unsigned i; + vector textures; + vector uniforms[SLANG_CBUFFER_MAX]; unordered_map texture_semantic_map; unordered_map texture_semantic_uniform_map; - for (unsigned i = 0; i <= pass_number; i++) + for (i = 0; i <= pass_number; i++) { if (!*shader_info->pass[i].alias) continue; @@ -106,41 +115,48 @@ static bool slang_process_reflection( if (!set_unique_map( texture_semantic_map, name, - slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i })) + slang_texture_semantic_map{ + SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i })) return false; if (!set_unique_map( texture_semantic_uniform_map, name + "Size", - slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i })) + slang_texture_semantic_map{ + SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i })) return false; if (!set_unique_map( texture_semantic_map, name + "Feedback", - slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i })) + slang_texture_semantic_map{ + SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i })) return false; if (!set_unique_map( texture_semantic_uniform_map, name + "FeedbackSize", - slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i })) + slang_texture_semantic_map{ + SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i })) return false; } - for (unsigned i = 0; i < shader_info->luts; i++) + for (i = 0; i < shader_info->luts; i++) { if (!set_unique_map( texture_semantic_map, shader_info->lut[i].id, - slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_USER, i })) + slang_texture_semantic_map{ + SLANG_TEXTURE_SEMANTIC_USER, i })) return false; if (!set_unique_map( - texture_semantic_uniform_map, string(shader_info->lut[i].id) + "Size", - slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_USER, i })) + texture_semantic_uniform_map, + string(shader_info->lut[i].id) + "Size", + slang_texture_semantic_map{ + SLANG_TEXTURE_SEMANTIC_USER, i })) return false; } unordered_map uniform_semantic_map; - for (unsigned i = 0; i < shader_info->num_parameters; i++) + for (i = 0; i < shader_info->num_parameters; i++) { if (!set_unique_map( uniform_semantic_map, shader_info->parameters[i].id, @@ -154,9 +170,11 @@ static bool slang_process_reflection( sl_reflection.texture_semantic_uniform_map = &texture_semantic_uniform_map; sl_reflection.semantic_map = &uniform_semantic_map; - if (!slang_reflect(*vs_compiler, *ps_compiler, vs_resources, ps_resources, &sl_reflection)) + if (!slang_reflect(*vs_compiler, *ps_compiler, + vs_resources, ps_resources, &sl_reflection)) { - RARCH_ERR("[slang]: Failed to reflect SPIR-V. Resource usage is inconsistent with " + RARCH_ERR("[slang]: Failed to reflect SPIR-V." + " Resource usage is inconsistent with " "expectations.\n"); return false; } @@ -168,18 +186,17 @@ static bool slang_process_reflection( out->cbuffers[SLANG_CBUFFER_PC].binding = sl_reflection.ubo_binding ? 0 : 1; out->cbuffers[SLANG_CBUFFER_PC].size = (sl_reflection.push_constant_size + 0xF) & ~0xF; - vector uniforms[SLANG_CBUFFER_MAX]; - vector textures; - - for (int semantic = 0; semantic < SLANG_NUM_BASE_SEMANTICS; semantic++) + for (semantic = 0; semantic < SLANG_NUM_BASE_SEMANTICS; semantic++) { slang_semantic_meta& src = sl_reflection.semantics[semantic]; if (src.push_constant || src.uniform) { uniform_sem_t uniform = { map->uniforms[semantic], - src.num_components * (unsigned)sizeof(float) }; + src.num_components + * (unsigned)sizeof(float) }; + string uniform_id = get_semantic_name( + sl_reflection, (slang_semantic)semantic, 0); - string uniform_id = get_semantic_name(sl_reflection, (slang_semantic)semantic, 0); strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); if (src.push_constant) @@ -195,15 +212,17 @@ static bool slang_process_reflection( } } - for (int i = 0; i < sl_reflection.semantic_float_parameters.size(); i++) + for (i = 0; i < sl_reflection.semantic_float_parameters.size(); i++) { slang_semantic_meta& src = sl_reflection.semantic_float_parameters[i]; if (src.push_constant || src.uniform) { - uniform_sem_t uniform = { &shader_info->parameters[i].current, sizeof(float) }; + uniform_sem_t uniform = { + &shader_info->parameters[i].current, sizeof(float) }; - string uniform_id = get_semantic_name(sl_reflection, SLANG_SEMANTIC_FLOAT_PARAMETER, i); + string uniform_id = get_semantic_name( + sl_reflection, SLANG_SEMANTIC_FLOAT_PARAMETER, i); strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); if (src.push_constant) @@ -219,11 +238,15 @@ static bool slang_process_reflection( } } - for (int semantic = 0; semantic < SLANG_NUM_TEXTURE_SEMANTICS; semantic++) + for (semantic = 0; semantic < SLANG_NUM_TEXTURE_SEMANTICS; semantic++) { - for (int index = 0; index < sl_reflection.semantic_textures[semantic].size(); index++) + unsigned index; + + for (index = 0; index < + sl_reflection.semantic_textures[semantic].size(); index++) { - slang_texture_semantic_meta& src = sl_reflection.semantic_textures[semantic][index]; + slang_texture_semantic_meta& src = + sl_reflection.semantic_textures[semantic][index]; if (src.stage_mask) { @@ -233,17 +256,18 @@ static bool slang_process_reflection( if (semantic == SLANG_TEXTURE_SEMANTIC_USER) { - texture.wrap = shader_info->lut[index].wrap; - texture.filter = shader_info->lut[index].filter; + texture.wrap = shader_info->lut[index].wrap; + texture.filter = shader_info->lut[index].filter; } else { - texture.wrap = shader_info->pass[pass_number].wrap; - texture.filter = shader_info->pass[pass_number].filter; + texture.wrap = shader_info->pass[pass_number].wrap; + texture.filter = shader_info->pass[pass_number].filter; } texture.stage_mask = src.stage_mask; texture.binding = src.binding; - string id = get_semantic_name(sl_reflection, (slang_texture_semantic)semantic, index); + string id = get_semantic_name( + sl_reflection, (slang_texture_semantic)semantic, index); strncpy(texture.id, id.c_str(), sizeof(texture.id)); @@ -253,19 +277,22 @@ static bool slang_process_reflection( shader_info->pass[index].feedback = true; if (semantic == SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY && - shader_info->history_size < index) + (unsigned)shader_info->history_size < index) shader_info->history_size = index; } if (src.push_constant || src.uniform) { uniform_sem_t uniform = { - (void*)((uintptr_t)map->textures[semantic].size + index * map->textures[semantic].size_stride), + (void*)((uintptr_t)map->textures[semantic].size + + index * map->textures[semantic].size_stride), 4 * sizeof(float) }; string uniform_id = - get_size_semantic_name(sl_reflection, (slang_texture_semantic)semantic, index); + get_size_semantic_name( + sl_reflection, + (slang_texture_semantic)semantic, index); strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); @@ -286,10 +313,12 @@ static bool slang_process_reflection( out->texture_count = textures.size(); textures.push_back({ NULL }); - out->textures = (texture_sem_t*)malloc(textures.size() * sizeof(*textures.data())); - memcpy(out->textures, textures.data(), textures.size() * sizeof(*textures.data())); + out->textures = (texture_sem_t*) + malloc(textures.size() * sizeof(*textures.data())); + memcpy(out->textures, textures.data(), + textures.size() * sizeof(*textures.data())); - for (int i = 0; i < SLANG_CBUFFER_MAX; i++) + for (i = 0; i < SLANG_CBUFFER_MAX; i++) { if (uniforms[i].empty()) continue; @@ -298,7 +327,9 @@ static bool slang_process_reflection( uniforms[i].push_back({ NULL }); out->cbuffers[i].uniforms = - (uniform_sem_t*)malloc(uniforms[i].size() * sizeof(*uniforms[i].data())); + (uniform_sem_t*) + malloc(uniforms[i].size() * sizeof(*uniforms[i].data())); + memcpy( out->cbuffers[i].uniforms, uniforms[i].data(), uniforms[i].size() * sizeof(*uniforms[i].data())); @@ -315,10 +346,10 @@ bool slang_process( const semantics_map_t* semantics_map, pass_semantics_t* out) { + glslang_output output; Compiler* vs_compiler = NULL; Compiler* ps_compiler = NULL; video_shader_pass& pass = shader_info->pass[pass_number]; - glslang_output output; if (!glslang_compile_shader(pass.source.path, &output)) return false; @@ -366,9 +397,11 @@ bool slang_process( ps_resources = ps_compiler->get_shader_resources(); if (!vs_resources.uniform_buffers.empty()) - vs_compiler->set_decoration(vs_resources.uniform_buffers[0].id, spv::DecorationBinding, 0); + vs_compiler->set_decoration( + vs_resources.uniform_buffers[0].id, spv::DecorationBinding, 0); if (!ps_resources.uniform_buffers.empty()) - ps_compiler->set_decoration(ps_resources.uniform_buffers[0].id, spv::DecorationBinding, 0); + ps_compiler->set_decoration( + ps_resources.uniform_buffers[0].id, spv::DecorationBinding, 0); if (!vs_resources.push_constant_buffers.empty()) vs_compiler->set_decoration( @@ -386,12 +419,12 @@ bool slang_process( vs->set_options(options); ps->set_options(options); - #if 0 +#if 0 CompilerGLSL::Options glsl_options; glsl_options.vertex.flip_vert_y = true; ((CompilerGLSL*)vs)->set_options(glsl_options); ((CompilerGLSL*)ps)->set_options(glsl_options); - #endif +#endif /* not exactly a vertex attribute but this remaps * float2 FragCoord :TEXCOORD# to float4 FragCoord : SV_POSITION */ @@ -400,9 +433,7 @@ bool slang_process( VariableTypeRemapCallback ps_var_remap_cb = [&](const SPIRType& type, const std::string& var_name, std::string& name_of_type) { if (var_name == "FragCoord") - { name_of_type = "float4"; - } }; for (Resource& resource : ps_resources.stage_inputs) { @@ -436,11 +467,13 @@ bool slang_process( pass.source.string.fragment = strdup(ps_code.c_str()); if (!slang_process_reflection( - vs_compiler, ps_compiler, vs_resources, ps_resources, shader_info, pass_number, + vs_compiler, ps_compiler, + vs_resources, ps_resources, shader_info, pass_number, semantics_map, out)) goto error; - } catch (const std::exception& e) + } + catch (const std::exception& e) { RARCH_ERR("[slang]: SPIRV-Cross threw exception: %s.\n", e.what()); goto error; diff --git a/gfx/drivers_shader/slang_reflection.cpp b/gfx/drivers_shader/slang_reflection.cpp index bd951f1e4b..6128e57661 100644 --- a/gfx/drivers_shader/slang_reflection.cpp +++ b/gfx/drivers_shader/slang_reflection.cpp @@ -83,12 +83,13 @@ static slang_texture_semantic slang_name_to_texture_semantic_array(const string unsigned i = 0; while (*names) { - auto n = *names; + auto n = *names; auto semantic = static_cast(i); + if (slang_texture_semantic_is_array(semantic)) { size_t baselen = strlen(n); - int cmp = strncmp(n, name.c_str(), baselen); + int cmp = strncmp(n, name.c_str(), baselen); if (cmp == 0) { @@ -190,7 +191,7 @@ static bool set_ubo_texture_offset(slang_reflection *reflection, } } - active = true; + active = true; active_offset = offset; return true; } @@ -279,7 +280,7 @@ static bool validate_type_for_semantic(const SPIRType &type, slang_semantic sem) return type.basetype == SPIRType::Float && type.vecsize == 4 && type.columns == 4; /* uint */ case SLANG_SEMANTIC_FRAME_COUNT: - return type.basetype == SPIRType::UInt && type.vecsize == 1 && type.columns == 1; + return type.basetype == SPIRType::UInt && type.vecsize == 1 && type.columns == 1; /* float */ case SLANG_SEMANTIC_FLOAT_PARAMETER: return type.basetype == SPIRType::Float && type.vecsize == 1 && type.columns == 1; @@ -303,13 +304,13 @@ static bool add_active_buffer_ranges(const Compiler &compiler, const Resource &r auto ranges = compiler.get_active_buffer_ranges(resource.id); for (auto &range : ranges) { - auto &name = compiler.get_member_name(resource.base_type_id, range.index); - auto &type = compiler.get_type(compiler.get_type(resource.base_type_id).member_types[range.index]); + auto &name = compiler.get_member_name(resource.base_type_id, range.index); + auto &type = compiler.get_type(compiler.get_type(resource.base_type_id).member_types[range.index]); - unsigned sem_index = 0; + unsigned sem_index = 0; unsigned tex_sem_index = 0; - auto sem = slang_uniform_name_to_semantic(*reflection->semantic_map, name, &sem_index); - auto tex_sem = slang_uniform_name_to_texture_semantic(*reflection->texture_semantic_uniform_map, + auto sem = slang_uniform_name_to_semantic(*reflection->semantic_map, name, &sem_index); + auto tex_sem = slang_uniform_name_to_texture_semantic(*reflection->texture_semantic_uniform_map, name, &tex_sem_index); if (tex_sem == SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT && tex_sem_index >= reflection->pass_number) @@ -658,14 +659,15 @@ bool slang_reflect_spirv(const std::vector &vertex, { Compiler vertex_compiler(vertex); Compiler fragment_compiler(fragment); - auto vertex_resources = vertex_compiler.get_shader_resources(); + auto vertex_resources = vertex_compiler.get_shader_resources(); auto fragment_resources = fragment_compiler.get_shader_resources(); if (!slang_reflect(vertex_compiler, fragment_compiler, vertex_resources, fragment_resources, reflection)) { - RARCH_ERR("[slang]: Failed to reflect SPIR-V. Resource usage is inconsistent with expectations.\n"); + RARCH_ERR("[slang]: Failed to reflect SPIR-V." + " Resource usage is inconsistent with expectations.\n"); return false; } diff --git a/gfx/font_driver.c b/gfx/font_driver.c index 63e4333dd7..28080b80a5 100644 --- a/gfx/font_driver.c +++ b/gfx/font_driver.c @@ -310,6 +310,37 @@ static bool vulkan_font_init_first( } #endif +#ifdef HAVE_D3D10 +static const font_renderer_t *d3d10_font_backends[] = { + &d3d10_font, + NULL, +}; + +static bool d3d10_font_init_first( + const void **font_driver, void **font_handle, + void *video_data, const char *font_path, + float font_size, bool is_threaded) +{ + unsigned i; + + for (i = 0; d3d10_font_backends[i]; i++) + { + void *data = d3d10_font_backends[i]->init(video_data, + font_path, font_size, + is_threaded); + + if (!data) + continue; + + *font_driver = d3d10_font_backends[i]; + *font_handle = data; + return true; + } + + return false; +} +#endif + #ifdef HAVE_D3D11 static const font_renderer_t *d3d11_font_backends[] = { &d3d11_font, @@ -493,6 +524,11 @@ static bool font_init_first( return d3d9_font_init_first(font_driver, font_handle, video_data, font_path, font_size, is_threaded); #endif +#ifdef HAVE_D3D10 + case FONT_DRIVER_RENDER_D3D10_API: + return d3d10_font_init_first(font_driver, font_handle, + video_data, font_path, font_size, is_threaded); +#endif #ifdef HAVE_D3D11 case FONT_DRIVER_RENDER_D3D11_API: return d3d11_font_init_first(font_driver, font_handle, @@ -693,10 +729,10 @@ static INLINE unsigned font_get_replacement(const char* src, const char* start) static char* font_driver_reshape_msg(const char* msg) { /* worst case transformations are 2 bytes to 4 bytes */ - char* buffer = (char*)malloc((strlen(msg) * 2) + 1); - const char* src = msg; - char* dst = buffer; - bool reverse = false; + unsigned char* buffer = (unsigned char*)malloc((strlen(msg) * 2) + 1); + const unsigned char* src = (const unsigned char*)msg; + unsigned char* dst = (unsigned char*)buffer; + bool reverse = false; while (*src || reverse) { @@ -708,7 +744,7 @@ static char* font_driver_reshape_msg(const char* msg) if (IS_RTL(src) || IS_DIR_NEUTRAL(src)) { - unsigned replacement = font_get_replacement(src, msg); + unsigned replacement = font_get_replacement((const char*)src, msg); if (replacement) { if (replacement < 0x80) @@ -770,7 +806,7 @@ static char* font_driver_reshape_msg(const char* msg) *dst = '\0'; - return buffer; + return (char*)buffer; } #endif diff --git a/gfx/font_driver.h b/gfx/font_driver.h index 939eccb951..7d1818b4a3 100644 --- a/gfx/font_driver.h +++ b/gfx/font_driver.h @@ -163,6 +163,7 @@ extern font_renderer_t vita2d_vita_font; extern font_renderer_t ctr_font; extern font_renderer_t wiiu_font; extern font_renderer_t vulkan_raster_font; +extern font_renderer_t d3d10_font; extern font_renderer_t d3d11_font; extern font_renderer_t d3d12_font; extern font_renderer_t caca_font; diff --git a/gfx/video_crt_switch.c b/gfx/video_crt_switch.c new file mode 100644 index 0000000000..c8c5d260fa --- /dev/null +++ b/gfx/video_crt_switch.c @@ -0,0 +1,186 @@ +/* CRT SwitchRes Core + * Copyright (C) 2018 Alphanu / Ben Templeman. + * + * RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . +*/ +#include +#include +#include + +#include "video_driver.h" +#include "video_crt_switch.h" +#include "video_display_server.h" + +static unsigned ra_core_width = 0; +static unsigned ra_core_height = 0; +static unsigned ra_tmp_width = 0; +static unsigned ra_tmp_height = 0; +static unsigned ra_set_core_hz = 0; +static unsigned orig_width = 0; +static unsigned orig_height = 0; + +static bool first_run = true; + +static float ra_tmp_core_hz = 0.0f; +static float fly_aspect = 0.0f; +static float ra_core_hz = 0.0f; + +static void crt_check_first_run(void) +{ + if (!first_run) + return; + + + + first_run = false; +} + +static void switch_crt_hz(void) +{ + if (ra_core_hz == ra_tmp_core_hz) + return; + /* set hz float to an int for windows switching */ + if (ra_core_hz < 53) + ra_set_core_hz = 50; + if (ra_core_hz >= 53 && ra_core_hz < 57) + ra_set_core_hz = 55; + if (ra_core_hz >= 57) + ra_set_core_hz = 60; + + video_monitor_set_refresh_rate(ra_set_core_hz); + + ra_tmp_core_hz = ra_core_hz; +} + + +void crt_aspect_ratio_switch(unsigned width, unsigned height) +{ + /* send aspect float to videeo_driver */ + fly_aspect = (float)width / height; + video_driver_set_aspect_ratio_value((float)fly_aspect); +} + +static void switch_res_crt(unsigned width, unsigned height) +{ + if (height > 100) + { + video_display_server_switch_resolution(width, height, + ra_set_core_hz, ra_core_hz); + video_driver_apply_state_changes(); + } +} + +/* Create correct aspect to fit video if resolution does not exist */ +static void crt_screen_setup_aspect(unsigned width, unsigned height) +{ + + switch_crt_hz(); + /* get original resolution of core */ + if (height == 4) + { + /* detect menu only */ + if (width < 1920) + width = 704; + + height = 480; + + crt_aspect_ratio_switch(width, height); + } + + if (height < 191 && height != 144) + { + crt_aspect_ratio_switch(width, height); + height = 200; + } + + if (height > 191) + crt_aspect_ratio_switch(width, height); + + if (height == 144 && ra_set_core_hz == 50) + { + height = 288; + crt_aspect_ratio_switch(width, height); + } + + if (height > 200 && height < 224) + { + crt_aspect_ratio_switch(width, height); + height = 224; + } + + if (height > 224 && height < 240) + { + crt_aspect_ratio_switch(width, height); + height = 240; + } + + if (height > 240 && height < 255) + { + crt_aspect_ratio_switch(width, height); + height = 254; + } + + if (height == 528 && ra_set_core_hz == 60) + { + crt_aspect_ratio_switch(width, height); + height = 480; + } + + if (height >= 240 && height < 255 && ra_set_core_hz == 55) + { + crt_aspect_ratio_switch(width, height); + height = 254; + } + + switch_res_crt(width, height); +} + + +void crt_switch_res_core(unsigned width, unsigned height, float hz) +{ + /* ra_core_hz float passed from within + * void video_driver_monitor_adjust_system_rates(void) */ + ra_core_width = width; + ra_core_height = height; + ra_core_hz = hz; + + crt_check_first_run(); + + /* Detect resolution change and switch */ + if ( + (ra_tmp_height != ra_core_height) || + (ra_core_width != ra_tmp_width) + ) + crt_screen_setup_aspect(width, height); + + ra_tmp_height = ra_core_height; + ra_tmp_width = ra_core_width; + + /* Check if aspect is correct, if notchange */ + if (video_driver_get_aspect_ratio() != fly_aspect) + { + video_driver_set_aspect_ratio_value((float)fly_aspect); + video_driver_apply_state_changes(); + } +} + +void crt_video_restore(void) +{ + if (first_run) + return; + + first_run = true; +} diff --git a/gfx/video_crt_switch.h b/gfx/video_crt_switch.h new file mode 100644 index 0000000000..e1ca885780 --- /dev/null +++ b/gfx/video_crt_switch.h @@ -0,0 +1,38 @@ +/* CRT SwitchRes Core + * Copyright (C) 2018 Alphanu / Ben Templeman. + * + * RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . +*/ + +#ifndef __VIDEO_CRT_SWITCH_H__ +#define __VIDEO_CRT_SWITCH_H__ + +#include + +#include +#include + +RETRO_BEGIN_DECLS + +void crt_switch_res_core(unsigned width, unsigned height, float hz); + +void crt_aspect_ratio_switch(unsigned width, unsigned height); + +void crt_video_restore(void); + +RETRO_END_DECLS + +#endif diff --git a/gfx/video_defines.h b/gfx/video_defines.h index 96437c0590..997850b856 100644 --- a/gfx/video_defines.h +++ b/gfx/video_defines.h @@ -84,6 +84,7 @@ enum font_driver_render_api FONT_DRIVER_RENDER_OPENGL_API, FONT_DRIVER_RENDER_D3D8_API, FONT_DRIVER_RENDER_D3D9_API, + FONT_DRIVER_RENDER_D3D10_API, FONT_DRIVER_RENDER_D3D11_API, FONT_DRIVER_RENDER_D3D12_API, FONT_DRIVER_RENDER_VITA2D, diff --git a/gfx/video_display_server.c b/gfx/video_display_server.c index 55baa165a2..c0df92ddf3 100644 --- a/gfx/video_display_server.c +++ b/gfx/video_display_server.c @@ -81,3 +81,12 @@ bool video_display_server_set_window_decorations(bool on) return current_display_server->set_window_decorations(current_display_server_data, on); return false; } + + +bool video_display_server_switch_resolution(unsigned width, unsigned height, + int int_hz, float hz) +{ + if (current_display_server && current_display_server->switch_resolution) + return current_display_server->switch_resolution(current_display_server_data, width, height, int_hz, hz); + return false; +} diff --git a/gfx/video_display_server.h b/gfx/video_display_server.h index 4f93a55e15..e672f0bc7d 100644 --- a/gfx/video_display_server.h +++ b/gfx/video_display_server.h @@ -30,15 +30,25 @@ typedef struct video_display_server bool (*set_window_opacity)(void *data, unsigned opacity); bool (*set_window_progress)(void *data, int progress, bool finished); bool (*set_window_decorations)(void *data, bool on); + bool (*switch_resolution)(void *data, unsigned width, + unsigned height, int int_hz, float hz); const char *ident; } video_display_server_t; void* video_display_server_init(void); + void video_display_server_destroy(void); + bool video_display_server_set_window_opacity(unsigned opacity); + bool video_display_server_set_window_progress(int progress, bool finished); + bool video_display_server_set_window_decorations(bool on); +bool video_display_server_switch_resolution( + unsigned width, unsigned height, + int int_hz, float hz); + extern const video_display_server_t dispserv_win32; extern const video_display_server_t dispserv_x11; extern const video_display_server_t dispserv_null; diff --git a/gfx/video_driver.c b/gfx/video_driver.c index e7f8ed667b..1776954fef 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -52,6 +52,7 @@ #include "video_thread_wrapper.h" #include "video_driver.h" #include "video_display_server.h" +#include "video_crt_switch.h" #include "../frontend/frontend_driver.h" #include "../record/record_driver.h" @@ -118,6 +119,7 @@ #define video_driver_context_unlock() ((void)0) #endif + typedef struct video_pixel_scaler { struct scaler_ctx *scaler; @@ -141,10 +143,12 @@ static rarch_softfilter_t *video_driver_state_filter = NULL; static void *video_driver_state_buffer = NULL; static unsigned video_driver_state_scale = 0; static unsigned video_driver_state_out_bpp = 0; -static bool video_driver_state_out_rgb32 = false; +static bool video_driver_state_out_rgb32 = false; +static bool video_driver_crt_switching_active = false; static struct retro_system_av_info video_driver_av_info; + static enum retro_pixel_format video_driver_pix_fmt = RETRO_PIXEL_FORMAT_0RGB1555; static const void *frame_cache_data = NULL; @@ -153,6 +157,7 @@ static unsigned frame_cache_height = 0; static size_t frame_cache_pitch = 0; static bool video_driver_threaded = false; +static float video_driver_core_hz = 0.0f; static float video_driver_aspect_ratio = 0.0f; static unsigned video_driver_width = 0; static unsigned video_driver_height = 0; @@ -224,6 +229,8 @@ static void *video_context_data = NULL; static bool deferred_video_context_driver_set_flags = false; static gfx_ctx_flags_t deferred_flag_data = {0}; +static bool video_started_fullscreen = false; + static shader_backend_t *current_shader = NULL; static void *current_shader_data = NULL; @@ -417,6 +424,11 @@ static const shader_backend_t *shader_ctx_drivers[] = { NULL }; +bool video_driver_started_fullscreen(void) +{ + return video_started_fullscreen; +} + /* Stub functions */ static void update_window_title_null(void *data, void *data2) @@ -873,7 +885,9 @@ static bool video_driver_pixel_converter_init(unsigned size) if (hwr && hwr->context_type != RETRO_HW_CONTEXT_NONE) return true; - RARCH_WARN("0RGB1555 pixel format is deprecated, and will be slower. For 15/16-bit, RGB565 format is preferred.\n"); + RARCH_WARN("0RGB1555 pixel format is deprecated," + " and will be slower. For 15/16-bit, RGB565" + " format is preferred.\n"); scalr = (video_pixel_scaler_t*)calloc(1, sizeof(*scalr)); @@ -1012,6 +1026,9 @@ static bool video_driver_init_internal(bool *video_is_threaded) video.rgb32 = video_driver_state_filter ? video_driver_state_out_rgb32 : (video_driver_pix_fmt == RETRO_PIXEL_FORMAT_XRGB8888); + video.parent = 0; + + video_started_fullscreen = video.fullscreen; /* Reset video frame count */ video_driver_frame_count = 0; @@ -1040,7 +1057,8 @@ static bool video_driver_init_internal(bool *video_is_threaded) } else #endif - video_driver_data = current_video->init(&video, input_get_double_ptr(), + video_driver_data = current_video->init( + &video, input_get_double_ptr(), input_driver_get_data_ptr()); if (!video_driver_data) @@ -1408,29 +1426,35 @@ bool video_driver_cached_frame(void) void video_driver_monitor_adjust_system_rates(void) { - float timing_skew; + float timing_skew = 0.0f; settings_t *settings = config_get_ptr(); float video_refresh_rate = settings->floats.video_refresh_rate; + float timing_skew_hz = video_refresh_rate; const struct retro_system_timing *info = (const struct retro_system_timing*)&video_driver_av_info.timing; rarch_ctl(RARCH_CTL_UNSET_NONBLOCK_FORCED, NULL); - if (!info || info->fps <= 0.0) return; - timing_skew = fabs(1.0f - info->fps / video_refresh_rate); + video_driver_core_hz = info->fps; + + if (video_driver_crt_switching_active) + timing_skew_hz = video_driver_core_hz; + timing_skew = fabs( + 1.0f - info->fps / timing_skew_hz); /* We don't want to adjust pitch too much. If we have extreme cases, * just don't readjust at all. */ if (timing_skew <= settings->floats.audio_max_timing_skew) return; - RARCH_LOG("[Video]: Timings deviate too much. Will not adjust. (Display = %.2f Hz, Game = %.2f Hz)\n", + RARCH_LOG("[Video]: Timings deviate too much. Will not adjust." + " (Display = %.2f Hz, Game = %.2f Hz)\n", video_refresh_rate, (float)info->fps); - if (info->fps <= video_refresh_rate) + if (info->fps <= timing_skew_hz) return; /* We won't be able to do VSync reliably when game FPS > monitor FPS. */ @@ -1538,7 +1562,8 @@ void video_driver_menu_settings(void **list_data, void *list_info_data, parent_group, general_write_handler, general_read_handler); - menu_settings_list_current_add_range(list, list_info, 0, 5, 1, true, true); + menu_settings_list_current_add_range(list, list_info, + 0, 5, 1, true, true); #endif #endif } @@ -1560,6 +1585,8 @@ static void video_driver_lock_new(void) void video_driver_destroy(void) { video_display_server_destroy(); + crt_video_restore(); + video_driver_cb_has_focus = null_driver_has_focus; video_driver_use_rgba = false; video_driver_data_own = false; @@ -1598,7 +1625,8 @@ 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 && current_video->read_viewport; + return settings->bools.video_gpu_record + && current_video->read_viewport; } bool video_driver_supports_viewport_read(void) @@ -1612,7 +1640,7 @@ bool video_driver_supports_viewport_read(void) bool video_driver_supports_read_frame_raw(void) { if (current_video->read_frame_raw) - return true; + return true; return false; } @@ -1624,7 +1652,8 @@ void video_driver_set_viewport_config(void) { struct retro_game_geometry *geom = &video_driver_av_info.geometry; - if (geom->aspect_ratio > 0.0f && settings->bools.video_aspect_ratio_auto) + if (geom->aspect_ratio > 0.0f && + settings->bools.video_aspect_ratio_auto) aspectratio_lut[ASPECT_RATIO_CONFIG].value = geom->aspect_ratio; else { @@ -1851,7 +1880,8 @@ 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) / 2.0f + 0.5f; + 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); vp->y = 0; @@ -1861,7 +1891,8 @@ 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) / 2.0f + 0.5f; + 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); } @@ -1968,18 +1999,17 @@ bool video_driver_find_driver(void) void video_driver_apply_state_changes(void) { - if (!video_driver_poke) - return; - if (video_driver_poke->apply_state_changes) + if (video_driver_poke && + video_driver_poke->apply_state_changes) video_driver_poke->apply_state_changes(video_driver_data); } bool video_driver_read_viewport(uint8_t *buffer, bool is_idle) { if ( current_video->read_viewport - && current_video->read_viewport(video_driver_data, buffer, is_idle)) + && current_video->read_viewport( + video_driver_data, buffer, is_idle)) return true; - return false; } @@ -2188,7 +2218,8 @@ void video_driver_gpu_record_deinit(void) video_driver_record_gpu_buffer = NULL; } -bool video_driver_get_current_software_framebuffer(struct retro_framebuffer *fb) +bool video_driver_get_current_software_framebuffer( + struct retro_framebuffer *fb) { if ( video_driver_poke @@ -2275,7 +2306,8 @@ 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 = video_driver_av_info.geometry.base_height; + unsigned base_height = + video_driver_av_info.geometry.base_height; if (base_height == 0) base_height = 1; @@ -2436,7 +2468,6 @@ void video_driver_frame(const void *data, unsigned width, if (video_info.fps_show) { if (video_info.framecount_show) - { snprintf( video_info.fps_text, sizeof(video_info.fps_text), @@ -2444,15 +2475,12 @@ void video_driver_frame(const void *data, unsigned width, last_fps, msg_hash_to_str(MSG_FRAMES), (uint64_t)video_driver_frame_count); - } else - { snprintf( video_info.fps_text, sizeof(video_info.fps_text), "FPS: %6.1f", last_fps); - } } } else @@ -2488,7 +2516,8 @@ void video_driver_frame(const void *data, unsigned width, || video_driver_record_gpu_buffer ) && recording_data ) - recording_dump_frame(data, width, height, pitch, video_info.runloop_is_idle); + recording_dump_frame(data, width, height, + pitch, video_info.runloop_is_idle); if (data && video_driver_state_filter && video_driver_frame_filter(data, &video_info, width, height, pitch, @@ -2521,12 +2550,13 @@ void video_driver_frame(const void *data, unsigned width, audio_statistics_t audio_stats = {0.0f}; double stddev = 0.0; struct retro_system_av_info *av_info = &video_driver_av_info; - bool measure_frame_time = video_monitor_fps_statistics(NULL, &stddev, NULL); unsigned red = 255; unsigned green = 255; unsigned blue = 255; unsigned alpha = 255; + video_monitor_fps_statistics(NULL, &stddev, NULL); + video_info.osd_stat_params.x = 0.010f; video_info.osd_stat_params.y = 0.950f; video_info.osd_stat_params.scale = 1.0f; @@ -2535,16 +2565,17 @@ void video_driver_frame(const void *data, unsigned width, video_info.osd_stat_params.drop_y = -2; video_info.osd_stat_params.drop_mod = 0.3f; video_info.osd_stat_params.drop_alpha = 1.0f; - video_info.osd_stat_params.color = COLOR_ABGR(red, green, blue, alpha); + video_info.osd_stat_params.color = COLOR_ABGR( + red, green, blue, alpha); compute_audio_buffer_statistics(&audio_stats); snprintf(video_info.stat_text, - sizeof(video_info.stat_text), + sizeof(video_info.stat_text), "Video Statistics:\n -Frame rate: %6.2f fps\n -Frame time: %6.2f ms\n -Frame time deviation: %.3f %%\n" " -Frame count: %" PRIu64"\n -Viewport: %d x %d x %3.2f\n" "Audio Statistics:\n -Average buffer saturation: %.2f %%\n -Standard deviation: %.2f %%\n -Time spent close to underrun: %.2f %%\n -Time spent close to blocking: %.2f %%\n -Sample count: %d\n" - "Core Geometry:\n -Size: %u x %u\n -Max Size: %u x %u\n -Aspect: %3.2f\nCore Timing:\n -FPS: %3.2f\n -Sample Rate: %6.2f\n", + "Core Geometry:\n -Size: %u x %u\n -Max Size: %u x %u\n -Aspect: %3.2f\nCore Timing:\n -FPS: %3.2f\n -Sample Rate: %6.2f\n", video_info.frame_rate, video_info.frame_time, 100.0 * stddev, @@ -2582,6 +2613,24 @@ 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) + { + video_driver_crt_switching_active = true; + + if (video_info.crt_switch_resolution_super == 2560) + width = 2560; + if (video_info.crt_switch_resolution_super == 3840) + width = 3840; + if (video_info.crt_switch_resolution_super == 1920) + width = 1920; + 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*/ } void video_driver_display_type_set(enum rarch_display_type type) @@ -2674,8 +2723,9 @@ 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->black_frame_insertion = - settings->bools.video_black_frame_insertion; + 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; video_info->fps_show = settings->bools.video_fps_show; @@ -2767,9 +2817,6 @@ void video_driver_build_info(video_frame_info_t *video_info) video_info->cb_set_mvp = video_driver_cb_shader_set_mvp; video_info->userdata = video_driver_get_ptr(false); -#if 0 - video_info->cb_set_coords = video_driver_cb_set_coords; -#endif #ifdef HAVE_THREADS video_driver_threaded_unlock(is_threaded); @@ -2808,12 +2855,14 @@ 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) / norm_full_vp_width) - 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) / norm_full_vp_height) - 0x7fff; + scaled_screen_y = ((2 * mouse_y * 0x7fff) + / norm_full_vp_height) - 0x7fff; else scaled_screen_y = -0x8000; /* OOB */ @@ -2821,12 +2870,14 @@ 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) / norm_vp_width) - 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) / norm_vp_height) - 0x7fff; + scaled_y = ((2 * mouse_y * 0x7fff) + / norm_vp_height) - 0x7fff; else scaled_y = -0x8000; /* OOB */ @@ -2851,7 +2902,8 @@ 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 ? current_video->alive(video_driver_data) : true; + *is_alive = current_video ? + current_video->alive(video_driver_data) : true; *is_focused = video_driver_cb_has_focus(); } @@ -2904,7 +2956,8 @@ bool video_context_driver_find_prev_driver(void) bool video_context_driver_find_next_driver(void) { settings_t *settings = config_get_ptr(); - int i = find_video_context_driver_index(settings->arrays.video_context_driver); + int i = find_video_context_driver_index( + settings->arrays.video_context_driver); if (i >= 0 && gfx_ctx_drivers[i + 1]) { @@ -2931,7 +2984,8 @@ bool video_context_driver_find_next_driver(void) * * Initialize graphics context driver. * - * Returns: graphics context driver if successfully initialized, otherwise NULL. + * Returns: graphics context driver if successfully initialized, + * otherwise NULL. **/ static const gfx_ctx_driver_t *video_context_driver_init( void *data, @@ -3052,7 +3106,8 @@ bool video_context_driver_init_image_buffer(const video_info_t *data) { if ( current_video_context.image_buffer_init - && current_video_context.image_buffer_init(video_context_data, data)) + && current_video_context.image_buffer_init( + video_context_data, data)) return true; return false; } @@ -3157,10 +3212,25 @@ bool video_context_driver_get_metrics(gfx_ctx_metrics_t *metrics) return false; } +bool video_context_driver_get_refresh_rate(float *refresh_rate) +{ + if (!current_video_context.get_refresh_rate || !refresh_rate) + return false; + if (!video_context_data) + return false; + + if (refresh_rate) + *refresh_rate = + current_video_context.get_refresh_rate(video_context_data); + + return true; +} + bool video_context_driver_input_driver(gfx_ctx_input_t *inp) { settings_t *settings = config_get_ptr(); - const char *joypad_name = settings ? settings->arrays.input_joypad_driver : NULL; + const char *joypad_name = settings ? + settings->arrays.input_joypad_driver : NULL; if (!current_video_context.input_driver) return false; @@ -3216,7 +3286,8 @@ bool video_context_driver_get_context_data(void *data) { if (!current_video_context.get_context_data) return false; - *(void**)data = current_video_context.get_context_data(video_context_data); + *(void**)data = current_video_context.get_context_data( + video_context_data); return true; } @@ -3233,16 +3304,22 @@ void video_context_driver_set_data(void *data) video_context_data = data; } +bool video_driver_get_flags(gfx_ctx_flags_t *flags) +{ + if (!flags || !video_driver_poke || !video_driver_poke->get_flags) + return false; + flags->flags = video_driver_poke->get_flags(video_driver_data); + return true; +} + bool video_context_driver_get_flags(gfx_ctx_flags_t *flags) { - if (!flags) - return false; - if (!current_video_context.get_flags) + if (!flags || !current_video_context.get_flags) return false; if (deferred_video_context_driver_set_flags) { - flags->flags = deferred_flag_data.flags; + flags->flags = deferred_flag_data.flags; deferred_video_context_driver_set_flags = false; return true; } @@ -3257,7 +3334,7 @@ bool video_context_driver_set_flags(gfx_ctx_flags_t *flags) return false; if (!current_video_context.set_flags) { - deferred_flag_data.flags = flags->flags; + deferred_flag_data.flags = flags->flags; deferred_video_context_driver_set_flags = true; return false; } @@ -3268,7 +3345,7 @@ bool video_context_driver_set_flags(gfx_ctx_flags_t *flags) enum gfx_ctx_api video_context_driver_get_api(void) { - enum gfx_ctx_api ctx_api = video_context_data ? + enum gfx_ctx_api ctx_api = video_context_data ? current_video_context.get_api(video_context_data) : GFX_CTX_NONE; if (ctx_api == GFX_CTX_NONE) @@ -3317,7 +3394,8 @@ bool video_driver_cached_frame_has_valid_framebuffer(void) return false; } -static const shader_backend_t *video_shader_set_backend(enum rarch_shader_type type) +static const shader_backend_t *video_shader_set_backend( + enum rarch_shader_type type) { switch (type) { @@ -3347,6 +3425,13 @@ static const shader_backend_t *video_shader_set_backend(enum rarch_shader_type t return &gl_glsl_backend; #else break; +#endif + case RARCH_SHADER_HLSL: +#ifdef HAVE_HLSL + RARCH_LOG("[Shader driver]: Using HLSL shader backend.\n"); + return &hlsl_backend; +#else + break; #endif case RARCH_SHADER_NONE: default: @@ -3360,7 +3445,7 @@ void video_shader_driver_use(void *data) { if (current_shader && current_shader->use) { - video_shader_ctx_info_t *shader_info = + video_shader_ctx_info_t *shader_info = (video_shader_ctx_info_t*)data; current_shader->use(shader_info->data, current_shader_data, shader_info->idx, shader_info->set_active); @@ -3386,7 +3471,8 @@ void video_shader_driver_set_parameters(void *data) } } -bool video_shader_driver_get_prev_textures(video_shader_ctx_texture_t *texture) +bool video_shader_driver_get_prev_textures( + video_shader_ctx_texture_t *texture) { if (!texture || !current_shader) return false; @@ -3415,7 +3501,8 @@ bool video_shader_driver_get_current_shader(video_shader_ctx_t *shader) return true; } -bool video_shader_driver_direct_get_current_shader(video_shader_ctx_t *shader) +bool video_shader_driver_direct_get_current_shader( + video_shader_ctx_t *shader) { shader->data = current_shader->get_current_shader(current_shader_data); @@ -3431,7 +3518,7 @@ bool video_shader_driver_deinit(void) current_shader->deinit(current_shader_data); current_shader_data = NULL; - current_shader = NULL; + current_shader = NULL; return true; } @@ -3452,7 +3539,8 @@ static bool video_driver_cb_set_mvp(void *data, return true; } -static struct video_shader *video_shader_driver_get_current_shader_null(void *data) +static struct video_shader * +video_shader_driver_get_current_shader_null(void *data) { return NULL; } @@ -3469,13 +3557,15 @@ static void video_shader_driver_scale_null(void *data, (void)scale; } -static bool video_shader_driver_mipmap_input_null(void *data, unsigned idx) +static bool video_shader_driver_mipmap_input_null( + void *data, unsigned idx) { (void)idx; return false; } -static bool video_shader_driver_filter_type_null(void *data, unsigned idx, bool *smooth) +static bool video_shader_driver_filter_type_null( + void *data, unsigned idx, bool *smooth) { (void)idx; (void)smooth; @@ -3487,7 +3577,8 @@ static unsigned video_shader_driver_num_null(void *data) return 0; } -static bool video_shader_driver_get_feedback_pass_null(void *data, unsigned *idx) +static bool video_shader_driver_get_feedback_pass_null( + void *data, unsigned *idx) { (void)idx; return false; @@ -3543,7 +3634,8 @@ bool video_shader_driver_init_first(void) bool video_shader_driver_init(video_shader_ctx_init_t *init) { - void *tmp = NULL; + void *tmp = NULL; + settings_t *settings = config_get_ptr(); if (!init->shader || !init->shader->init) { @@ -3558,7 +3650,17 @@ bool video_shader_driver_init(video_shader_ctx_init_t *init) if (!tmp) return false; + if (string_is_equal(settings->arrays.menu_driver, "xmb") + && init->shader->init_menu_shaders) + { + RARCH_LOG("Setting up menu pipeline shaders for XMB ... \n"); + init->shader->init_menu_shaders(tmp); + } + current_shader_data = tmp; + + RARCH_LOG("Resetting shader to defaults ... \n"); + current_shader = (shader_backend_t*)init->shader; video_shader_driver_reset_to_defaults(); @@ -3625,12 +3727,14 @@ void video_driver_set_coords(video_shader_ctx_coords_t *coords) { if (current_shader && current_shader->set_coords) current_shader->set_coords(coords->handle_data, - current_shader_data, (const struct video_coords*)coords->data); + current_shader_data, + (const struct video_coords*)coords->data); else { if (video_driver_poke && video_driver_poke->set_coords) video_driver_poke->set_coords(coords->handle_data, - current_shader_data, (const struct video_coords*)coords->data); + current_shader_data, + (const struct video_coords*)coords->data); } } @@ -3640,10 +3744,20 @@ void video_driver_set_mvp(video_shader_ctx_mvp_t *mvp) return; if (current_shader && current_shader->set_mvp) - current_shader->set_mvp(mvp->data, current_shader_data, mvp->matrix); + current_shader->set_mvp(mvp->data, + current_shader_data, mvp->matrix); else { if (video_driver_poke && video_driver_poke->set_mvp) - video_driver_poke->set_mvp(mvp->data, current_shader_data, mvp->matrix); + video_driver_poke->set_mvp(mvp->data, + current_shader_data, mvp->matrix); } } + +float video_driver_get_refresh_rate(void) +{ + if (video_driver_poke && video_driver_poke->get_refresh_rate) + return video_driver_poke->get_refresh_rate(video_driver_data); + + return 0.0f; +} diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 878aea7bae..5cb44cf763 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -113,7 +113,10 @@ enum display_flags GFX_CTX_FLAGS_NONE = 0, GFX_CTX_FLAGS_GL_CORE_CONTEXT, GFX_CTX_FLAGS_MULTISAMPLING, - GFX_CTX_FLAGS_CUSTOMIZABLE_SWAPCHAIN_IMAGES + GFX_CTX_FLAGS_CUSTOMIZABLE_SWAPCHAIN_IMAGES, + GFX_CTX_FLAGS_HARD_SYNC, + GFX_CTX_FLAGS_BLACK_FRAME_INSERTION, + GFX_CTX_FLAGS_MENU_FRAME_FILTERING }; enum shader_uniform_type @@ -200,6 +203,7 @@ struct uniform_info typedef struct shader_backend { void *(*init)(void *data, const char *path); + void (*init_menu_shaders)(void *data); void (*deinit)(void *data); /* Set shader parameters. */ @@ -402,6 +406,7 @@ typedef struct video_frame_info bool black_frame_insertion; bool hard_sync; bool fps_show; + bool crt_switch_resolution; bool statistics_show; bool framecount_show; bool scale_integer; @@ -427,6 +432,7 @@ typedef struct video_frame_info unsigned aspect_ratio_idx; unsigned max_swapchain_images; unsigned monitor_index; + unsigned crt_switch_resolution_super; unsigned width; unsigned height; unsigned xmb_theme; @@ -523,6 +529,8 @@ typedef struct gfx_ctx_driver * If not initialized yet, it returns current screen size. */ void (*get_video_size)(void*, unsigned*, unsigned*); + float (*get_refresh_rate)(void*); + void (*get_video_output_size)(void*, unsigned*, unsigned*); void (*get_video_output_prev)(void*); @@ -689,6 +697,7 @@ struct aspect_ratio_elem typedef struct video_poke_interface { + uint32_t (*get_flags)(void *data); void (*set_coords)(void *handle_data, void *shader_data, const struct video_coords *coords); void (*set_mvp)(void *data, void *shader_data, @@ -698,6 +707,7 @@ typedef struct video_poke_interface void (*unload_texture)(void *data, uintptr_t id); void (*set_video_mode)(void *data, unsigned width, unsigned height, bool fullscreen); + float (*get_refresh_rate)(void *data); void (*set_filtering)(void *data, unsigned index, bool smooth); void (*get_video_output_size)(void *data, unsigned *width, unsigned *height); @@ -1271,12 +1281,16 @@ bool video_context_driver_set_video_mode(gfx_ctx_mode_t *mode_info); bool video_context_driver_get_video_size(gfx_ctx_mode_t *mode_info); +bool video_context_driver_get_refresh_rate(float *refresh_rate); + bool video_context_driver_get_context_data(void *data); bool video_context_driver_show_mouse(bool *bool_data); void video_context_driver_set_data(void *data); +bool video_driver_get_flags(gfx_ctx_flags_t *flags); + bool video_context_driver_get_flags(gfx_ctx_flags_t *flags); bool video_context_driver_set_flags(gfx_ctx_flags_t *flags); @@ -1329,8 +1343,12 @@ void video_shader_driver_use(void *data); bool video_shader_driver_wrap_type(video_shader_ctx_wrap_t *wrap); +float video_driver_get_refresh_rate(void); + extern bool (*video_driver_cb_has_focus)(void); +bool video_driver_started_fullscreen(void); + extern video_driver_t video_gl; extern video_driver_t video_vulkan; extern video_driver_t video_psp1; diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index 38f0655827..ed78aa8189 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -1215,6 +1215,7 @@ enum rarch_shader_type video_shader_get_type_from_ext( { switch (api) { + case GFX_CTX_DIRECT3D10_API: case GFX_CTX_DIRECT3D11_API: case GFX_CTX_DIRECT3D12_API: case GFX_CTX_GX2_API: @@ -1232,6 +1233,7 @@ enum rarch_shader_type video_shader_get_type_from_ext( switch (api) { + case GFX_CTX_DIRECT3D10_API: case GFX_CTX_DIRECT3D11_API: case GFX_CTX_DIRECT3D12_API: case GFX_CTX_GX2_API: diff --git a/gfx/video_thread_wrapper.c b/gfx/video_thread_wrapper.c index 027e4a0daf..147ec5782b 100644 --- a/gfx/video_thread_wrapper.c +++ b/gfx/video_thread_wrapper.c @@ -1252,12 +1252,22 @@ static struct video_shader *thread_get_current_shader(void *data) return thr->poke->get_current_shader(thr->driver_data); } +static uint32_t thread_get_flags(void *data) +{ + thread_video_t *thr = (thread_video_t*)data; + if (!thr || !thr->poke || !thr->poke->get_flags) + return 0; + return thr->poke->get_flags(thr->driver_data); +} + static const video_poke_interface_t thread_poke = { + thread_get_flags, NULL, /* set_coords */ NULL, /* set_mvp */ thread_load_texture, thread_unload_texture, thread_set_video_mode, + NULL, thread_set_filtering, thread_get_video_output_size, thread_get_video_output_prev, diff --git a/griffin/griffin.c b/griffin/griffin.c index 7b321d959e..8f73ea6e0c 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -394,7 +394,6 @@ VIDEO DRIVER #include "../gfx/drivers/drm_gfx.c" #endif -#include "../gfx/drivers_renderchain/null_renderchain.c" #include "../gfx/display_servers/dispserv_null.c" #ifdef HAVE_OPENGL @@ -510,6 +509,10 @@ FONTS #include "../gfx/drivers_font/vulkan_raster_font.c" #endif +#if defined(HAVE_D3D10) +#include "../gfx/drivers_font/d3d10_font.c" +#endif + #if defined(HAVE_D3D11) #include "../gfx/drivers_font/d3d11_font.c" #endif @@ -798,6 +801,7 @@ AUDIO DRIVERS ============================================================ */ #include "../gfx/video_driver.c" +#include "../gfx/video_crt_switch.c" #include "../gfx/video_display_server.c" #include "../gfx/video_coord_array.c" #include "../input/input_driver.c" @@ -1168,6 +1172,10 @@ MENU #include "../menu/drivers_display/menu_display_d3d9.c" #endif +#if defined(HAVE_D3D10) +#include "../menu/drivers_display/menu_display_d3d10.c" +#endif + #if defined(HAVE_D3D11) #include "../menu/drivers_display/menu_display_d3d11.c" #endif @@ -1242,9 +1250,7 @@ MENU #include "../cores/libretro-net-retropad/net_retropad_core.c" #endif -#ifdef HAVE_KEYMAPPER #include "../input/input_mapper.c" -#endif #include "../command.c" @@ -1252,13 +1258,22 @@ MENU #include "../libretro-common/net/net_http_parse.c" #endif +#ifdef HAVE_RUNAHEAD +#include "../runahead/mem_util.c" +#include "../runahead/secondary_core.c" +#include "../runahead/run_ahead.c" +#include "../runahead/copy_load_info.c" +#include "../runahead/dirty_input.c" +#include "../runahead/mylist.c" +#endif + /*============================================================ DEPENDENCIES ============================================================ */ #ifdef WANT_ZLIB #include "../deps/libz/adler32.c" #include "../deps/libz/compress.c" -#include "../deps/libz/crc32.c" +#include "../deps/libz/libz-crc32.c" #include "../deps/libz/deflate.c" #include "../deps/libz/gzclose.c" #include "../deps/libz/gzlib.c" @@ -1291,11 +1306,24 @@ DEPENDENCIES #endif #ifdef HAVE_CHD -#include "../libretro-common/formats/libchdr/bitstream.c" -#include "../libretro-common/formats/libchdr/cdrom.c" -#include "../libretro-common/formats/libchdr/chd.c" -#include "../libretro-common/formats/libchdr/flac.c" -#include "../libretro-common/formats/libchdr/huffman.c" +#include "../libretro-common/formats/libchdr/libchdr_bitstream.c" +#include "../libretro-common/formats/libchdr/libchdr_cdrom.c" +#include "../libretro-common/formats/libchdr/libchdr_chd.c" + +#ifdef HAVE_FLAC +#include "../libretro-common/formats/libchdr/libchdr_flac.c" +#include "../libretro-common/formats/libchdr/libchdr_flac_codec.c" +#endif + +#ifdef HAVE_ZLIB +#include "../libretro-common/formats/libchdr/libchdr_zlib.c" +#endif + +#ifdef HAVE_7ZIP +#include "../libretro-common/formats/libchdr/libchdr_lzma.c" +#endif + +#include "../libretro-common/formats/libchdr/libchdr_huffman.c" #include "../libretro-common/streams/chd_stream.c" #endif diff --git a/griffin/griffin_cpp.cpp b/griffin/griffin_cpp.cpp index ac200c1f80..91b377214e 100644 --- a/griffin/griffin_cpp.cpp +++ b/griffin/griffin_cpp.cpp @@ -33,18 +33,16 @@ MENU UI ============================================================ */ #if defined(HAVE_QT) +#define HAVE_MAIN /* also requires defining in frontend.c */ #include "../ui/drivers/ui_qt.cpp" #include "../ui/drivers/qt/ui_qt_window.cpp" +#include "../ui/drivers/qt/ui_qt_load_core_window.cpp" #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" #endif -#if defined(HAVE_QT_WRAPPER) -#include "../ui/drivers/ui_qt.cpp" -#endif - /*============================================================ VIDEO DRIVER ============================================================ */ @@ -74,11 +72,11 @@ FONTS #endif #ifdef WANT_GLSLANG -#ifdef _WIN32 -#include "../deps/glslang/glslang/glslang/OSDependent/Windows/ossource.cpp" -#endif - +#ifdef _WIN32 +#include "../deps/glslang/glslang/glslang/OSDependent/Windows/ossource.cpp" +#endif + #if defined(__linux__) -#include "../deps/glslang/glslang/glslang/OSDependent/Unix/ossource.cpp" +#include "../deps/glslang/glslang/glslang/OSDependent/Unix/ossource.cpp" #endif #endif diff --git a/input/common/hid/device_ds3.c b/input/common/hid/device_ds3.c new file mode 100644 index 0000000000..4b26cd5634 --- /dev/null +++ b/input/common/hid/device_ds3.c @@ -0,0 +1,356 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * 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 "hid_device_driver.h" + +#define DS3_ACTIVATION_REPORT_ID 0xf4 +#define DS3_RUMBLE_REPORT_ID 0x01 + +typedef struct ds3_instance { + void *handle; + joypad_connection_t *pad; + int slot; + bool led_set; + uint32_t buttons; + int16_t analog_state[3][2]; + uint16_t motors[2]; + uint8_t data[64]; +} ds3_instance_t; + +static uint8_t activation_packet[] = { +#if defined(IOS) + 0x53, 0xF4, +#elif defined(HAVE_WIIUSB_HID) + 0x02, +#endif + 0x42, 0x0c, 0x00, 0x00 +}; + +#if defined(WIIU) +#define PACKET_OFFSET 2 +#elif defined(HAVE_WIIUSB_HID) +#define PACKET_OFFSET 1 +#else +#define PACKET_OFFSET 0 +#endif + +#define LED_OFFSET 11 +#define MOTOR1_OFFSET 4 +#define MOTOR2_OFFSET 6 + +static uint8_t control_packet[] = { + 0x52, 0x01, + 0x00, 0xff, 0x00, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +static int control_packet_size = sizeof(control_packet); + +extern pad_connection_interface_t ds3_pad_connection; + +static void update_pad_state(ds3_instance_t *instance); +static void update_analog_state(ds3_instance_t *instance); + +static int32_t send_activation_packet(ds3_instance_t *instance) +{ + int32_t result; +#if defined(WIIU) + result = HID_SET_REPORT(instance->handle, + HID_REPORT_FEATURE, + DS3_ACTIVATION_REPORT_ID, + activation_packet, + sizeof(activation_packet)); +#else + HID_SEND_CONTROL(instance->handle, + activation_packet, sizeof(activation_packet)); +#endif + + return result; +} + +static uint32_t set_protocol(ds3_instance_t *instance, int protocol) +{ + uint32_t result = 0; +#if defined(WIIU) + result = HID_SET_PROTOCOL(instance->handle, 1); +#endif + + return result; +} + +static int32_t send_control_packet(ds3_instance_t *instance) +{ + uint8_t packet_buffer[control_packet_size]; + int32_t result = 0; + memcpy(packet_buffer, control_packet, control_packet_size); + + packet_buffer[LED_OFFSET] = 0; + if(instance->pad) { + packet_buffer[LED_OFFSET] = 1 << ((instance->slot % 4) + 1); + } + packet_buffer[MOTOR1_OFFSET] = instance->motors[1] >> 8; + packet_buffer[MOTOR2_OFFSET] = instance->motors[0] >> 8; + +#if defined(HAVE_WIIUSB_HID) + packet_buffer[1] = 0x03; +#endif + +#if defined(WIIU) + result = HID_SET_REPORT(instance->handle, + HID_REPORT_OUTPUT, + DS3_RUMBLE_REPORT_ID, + packet_buffer+PACKET_OFFSET, + control_packet_size-PACKET_OFFSET); +#else + HID_SEND_CONTROL(instance->handle, + packet_buffer+PACKET_OFFSET, + control_packet_size-PACKET_OFFSET); +#endif /* WIIU */ + return result; +} + +static void *ds3_init(void *handle) +{ + ds3_instance_t *instance; + int errors = 0; + RARCH_LOG("[ds3]: init\n"); + instance = (ds3_instance_t *)calloc(1, sizeof(ds3_instance_t)); + if(!instance) + goto error; + + memset(instance, 0, sizeof(ds3_instance_t)); + instance->handle = handle; + + RARCH_LOG("[ds3]: setting protocol\n"); + + /* this might fail, but we don't care. */ + set_protocol(instance, 1); + + RARCH_LOG("[ds3]: sending control packet\n"); + if(send_control_packet(instance) < 0) + errors++; + + RARCH_LOG("[ds3]: sending activation packet\n"); + if(send_activation_packet(instance) < 0) + errors++; + + if(errors) + goto error; + + instance->pad = hid_pad_register(instance, &ds3_pad_connection); + if(!instance->pad) + goto error; + + RARCH_LOG("[ds3]: init complete.\n"); + return instance; + + error: + RARCH_ERR("[ds3]: init failed.\n"); + if(instance) + free(instance); + return NULL; +} + +static void ds3_free(void *data) +{ + ds3_instance_t *instance = (ds3_instance_t *)data; + + if(instance) { + hid_pad_deregister(instance->pad); + free(instance); + } +} + +static void ds3_handle_packet(void *data, uint8_t *packet, size_t size) +{ + ds3_instance_t *instance = (ds3_instance_t *)data; + + if(!instance || !instance->pad) + return; + + instance->pad->iface->packet_handler(data, packet, size); +} + +static bool ds3_detect(uint16_t vendor_id, uint16_t product_id) +{ + return vendor_id == VID_SONY && product_id == PID_SONY_DS3; +} + +hid_device_t ds3_hid_device = { + ds3_init, + ds3_free, + ds3_handle_packet, + ds3_detect, + "Sony DualShock 3" +}; + +/** + * pad interface implementation + */ + +static void *ds3_pad_init(void *data, uint32_t slot, hid_driver_t *driver) +{ + ds3_instance_t *pad = (ds3_instance_t *)data; + pad->slot = slot; + + return data; +} + +static void ds3_pad_deinit(void *data) +{ + ds3_instance_t *pad = (ds3_instance_t *)data; + if(pad) { + input_autoconfigure_disconnect(pad->slot, ds3_pad_connection.get_name(pad)); + } +} + +static void ds3_get_buttons(void *data, input_bits_t *state) +{ + ds3_instance_t *pad = (ds3_instance_t *)data; + + if(pad) + { + BITS_COPY16_PTR(state, pad->buttons); + + if(pad->buttons & 0x10000) + BIT256_SET_PTR(state, RARCH_MENU_TOGGLE); + } else { + BIT256_CLEAR_ALL_PTR(state); + } +} + +static void ds3_packet_handler(void *data, uint8_t *packet, uint16_t size) +{ + ds3_instance_t *instance = (ds3_instance_t *)data; + + if(instance->pad && !instance->led_set) + { + send_control_packet(instance); + instance->led_set = true; + } + + if(size > control_packet_size) + { + RARCH_ERR("[ds3]: Expecting packet to be %d but was %d\n", + control_packet_size, size); + return; + } + + memcpy(instance->data, packet, size); + update_pad_state(instance); + update_analog_state(instance); +} + +static void update_analog_state(ds3_instance_t *instance) +{ + int pad_axis; + int16_t interpolated; + unsigned stick, axis; + + for(pad_axis = 0; pad_axis < 4; pad_axis++) + { + axis = pad_axis % 2 ? 0 : 1; + stick = pad_axis / 2; + interpolated = instance->data[6+pad_axis]; + instance->analog_state[stick][axis] = (interpolated - 128) * 256; + } +} + +static void update_pad_state(ds3_instance_t *instance) +{ + uint32_t i, pressed_keys; + + static const uint32_t button_mapping[17] = + { + RETRO_DEVICE_ID_JOYPAD_SELECT, + RETRO_DEVICE_ID_JOYPAD_L3, + RETRO_DEVICE_ID_JOYPAD_R3, + RETRO_DEVICE_ID_JOYPAD_START, + RETRO_DEVICE_ID_JOYPAD_UP, + RETRO_DEVICE_ID_JOYPAD_RIGHT, + RETRO_DEVICE_ID_JOYPAD_DOWN, + RETRO_DEVICE_ID_JOYPAD_LEFT, + RETRO_DEVICE_ID_JOYPAD_L2, + RETRO_DEVICE_ID_JOYPAD_R2, + RETRO_DEVICE_ID_JOYPAD_L, + RETRO_DEVICE_ID_JOYPAD_R, + RETRO_DEVICE_ID_JOYPAD_X, + RETRO_DEVICE_ID_JOYPAD_A, + RETRO_DEVICE_ID_JOYPAD_B, + RETRO_DEVICE_ID_JOYPAD_Y, + 16 /* PS button */ + }; + + instance->buttons = 0; + + pressed_keys = instance->data[2]|(instance->data[3] << 8)|((instance->data[4] & 0x01) << 16); + + for(i = 0; i < 17; i++) + instance->buttons |= (pressed_keys & (1 << i)) ? + (1 << button_mapping[i]) : 0; +} + +static void ds3_set_rumble(void *data, enum retro_rumble_effect effect, uint16_t strength) +{ + ds3_instance_t *pad = (ds3_instance_t *)data; +} + +static int16_t ds3_get_axis(void *data, unsigned axis) +{ + axis_data axis_data; + ds3_instance_t *pad = (ds3_instance_t *)data; + + gamepad_read_axis_data(axis, &axis_data); + + if(!pad || axis_data.axis >= 4) + return 0; + + return gamepad_get_axis_value(pad->analog_state, &axis_data); +} + +static const char *ds3_get_name(void *data) +{ + ds3_instance_t *pad = (ds3_instance_t *)data; + return "Sony DualShock 3"; +} + +static bool ds3_button(void *data, uint16_t joykey) +{ + ds3_instance_t *pad = (ds3_instance_t *)data; + if(!pad || joykey > 31) + return false; + + return pad->buttons & (1 << joykey); +} + +pad_connection_interface_t ds3_pad_connection = { + ds3_pad_init, + ds3_pad_deinit, + ds3_packet_handler, + ds3_set_rumble, + ds3_get_buttons, + ds3_get_axis, + ds3_get_name, + ds3_button +}; diff --git a/input/common/hid/device_ds4.c b/input/common/hid/device_ds4.c new file mode 100644 index 0000000000..af923cee13 --- /dev/null +++ b/input/common/hid/device_ds4.c @@ -0,0 +1,154 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * 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 "hid_device_driver.h" + +extern pad_connection_interface_t ds4_pad_connection; + +typedef struct ds4_instance { + void *handle; + joypad_connection_t *pad; + int slot; + uint32_t buttons; + uint16_t motors[2]; + uint8_t data[64]; +} ds4_instance_t; + +/** + * I'm leaving this code in here for posterity, and because maybe it can + * be used on other platforms. But using the DS4 on the Wii U directly is + * impossible because it doesn't generate a HID event. Which makes me think + * it's not a HID device at all--at least, not over USB. + * + * I imagine it might be useful in Bluetooth mode, though. + */ +static void *ds4_init(void *handle) +{ + ds4_instance_t *instance; + instance = (ds4_instance_t *)calloc(1, sizeof(ds4_instance_t)); + if(!instance) + goto error; + + memset(instance, 0, sizeof(ds4_instance_t)); + instance->handle = handle; + instance->pad = hid_pad_register(instance, &ds4_pad_connection); + if(!instance->pad) + goto error; + + RARCH_LOG("[ds4]: init complete.\n"); + return instance; + + error: + RARCH_ERR("[ds4]: init failed.\n"); + if(instance) + free(instance); + + return NULL; +} + +static void ds4_free(void *data) +{ + ds4_instance_t *instance = (ds4_instance_t *)data; + + if(instance) { + hid_pad_deregister(instance->pad); + free(instance); + } +} + +static void ds4_handle_packet(void *data, uint8_t *buffer, size_t size) +{ + ds4_instance_t *instance = (ds4_instance_t *)data; + + if(instance && instance->pad) + instance->pad->iface->packet_handler(instance->pad->data, buffer, size); +} + +static bool ds4_detect(uint16_t vendor_id, uint16_t product_id) +{ + return vendor_id == VID_SONY && product_id == PID_SONY_DS4; +} + +hid_device_t ds4_hid_device = { + ds4_init, + ds4_free, + ds4_handle_packet, + ds4_detect, + "Sony DualShock 4" +}; + +static void *ds4_pad_init(void *data, uint32_t slot, hid_driver_t *driver) +{ + ds4_instance_t *instance = (ds4_instance_t *)data; + + if(!instance) + return NULL; + + instance->slot = slot; + return instance; +} + +static void ds4_pad_deinit(void *data) +{ +} + +static void ds4_get_buttons(void *data, input_bits_t *state) +{ + ds4_instance_t *instance = (ds4_instance_t *)data; + if(!instance) + return; + + /* TODO: get buttons */ +} + +static void ds4_packet_handler(void *data, uint8_t *packet, uint16_t size) +{ + ds4_instance_t *instance = (ds4_instance_t *)data; + if(!instance) + return; + + RARCH_LOG_BUFFER(packet, size); +} + +static void ds4_set_rumble(void *data, enum retro_rumble_effect effect, uint16_t strength) +{ +} + +static int16_t ds4_get_axis(void *data, unsigned axis) +{ + return 0; +} + +static const char *ds4_get_name(void *data) +{ + return "Sony DualShock 4"; +} + +static bool ds4_button(void *data, uint16_t joykey) +{ + return false; +} + +pad_connection_interface_t ds4_pad_connection = { + ds4_pad_init, + ds4_pad_deinit, + ds4_packet_handler, + ds4_set_rumble, + ds4_get_buttons, + ds4_get_axis, + ds4_get_name, + ds4_button +}; diff --git a/input/common/hid/device_null.c b/input/common/hid/device_null.c new file mode 100644 index 0000000000..f5676c87b7 --- /dev/null +++ b/input/common/hid/device_null.c @@ -0,0 +1,219 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * 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 "hid_device_driver.h" + +extern pad_connection_interface_t null_pad_connection; + +/* + * This is the instance data structure for the pad you are implementing. + * This is a good starting point, but you can add/remove things as makes + * sense for the pad you're writing for. The pointer to this structure + * will be passed in as a void pointer to the methods you implement below. + */ +typedef struct null_instance { + void *handle; /* a handle to the HID subsystem adapter */ + joypad_connection_t *pad; /* a pointer to the joypad connection you assign + in init() */ + int slot; /* which slot does this pad occupy? */ + uint32_t buttons; /* a bitmap of the digital buttons for the pad */ + uint16_t motors[2]; /* rumble strength, if appropriate */ + uint8_t data[64]; /* a buffer large enough to hold the device's + max rx packet */ +} null_instance_t; + +/** + * Use the HID_ macros (see input/include/hid_driver.h) to send data packets + * to the device. When this method returns, the device needs to be in a state + * where we can read data packets from the device. So, if there's any + * activation packets (see the ds3 and Wii U GameCube adapter drivers for + * examples), send them here. + * + * While you *can* allocate the retro pad here, it isn't mandatory (see + * the Wii U GC adapter). + * + * If initialization fails, return NULL. + */ +static void *null_init(void *handle) +{ + null_instance_t *instance; + instance = (null_instance_t *)calloc(1, sizeof(null_instance_t)); + if(!instance) + goto error; + + memset(instance, 0, sizeof(null_instance_t)); + instance->handle = handle; + instance->pad = hid_pad_register(instance, &null_pad_connection); + if(!instance->pad) + goto error; + + RARCH_LOG("[null]: init complete.\n"); + return instance; + + error: + RARCH_ERR("[null]: init failed.\n"); + if(instance) + free(instance); + + return NULL; +} + +/* + * Gets called when the pad is disconnected. It must clean up any memory + * allocated and used by the instance data. + */ +static void null_free(void *data) +{ + null_instance_t *instance = (null_instance_t *)data; + + if(instance) { + hid_pad_deregister(instance->pad); + free(instance); + } +} + +/** + * Handle a single packet from the device. + * For most pads you'd just forward it onto the pad driver (see below). + * A more complicated example is in the Wii U GC adapter driver. + */ +static void null_handle_packet(void *data, uint8_t *buffer, size_t size) +{ + null_instance_t *instance = (null_instance_t *)data; + + if(instance && instance->pad) + instance->pad->iface->packet_handler(instance->pad->data, buffer, size); +} + +/** + * Return true if the passed in VID and PID are supported by the driver. + */ +static bool null_detect(uint16_t vendor_id, uint16_t product_id) +{ + return vendor_id == VID_NONE && product_id == PID_NONE; +} + +/** + * Assign function pointers to the driver structure. + */ +hid_device_t null_hid_device = { + null_init, + null_free, + null_handle_packet, + null_detect, + "Null HID device" +}; + +/** + * This is called via hid_pad_register(). In the common case where the + * device only controls one pad, you can simply return the data parameter. + * But if you need to track multiple pads attached to the same HID device + * (see: Wii U GC adapter), you can allocate that memory here. + */ +static void *null_pad_init(void *data, uint32_t slot, hid_driver_t *driver) +{ + null_instance_t *instance = (null_instance_t *)data; + + if(!instance) + return NULL; + + instance->slot = slot; + return instance; +} + +/** + * If you allocate any memory in null_pad_init() above, de-allocate it here. + */ +static void null_pad_deinit(void *data) +{ +} + +/** + * Translate the button data from the pad into the input_bits_t format + * that RetroArch can use. + */ +static void null_get_buttons(void *data, input_bits_t *state) +{ + null_instance_t *instance = (null_instance_t *)data; + if(!instance) + return; + + /* TODO: get buttons */ +} + +/** + * Handle a single packet for the pad. + */ +static void null_packet_handler(void *data, uint8_t *packet, uint16_t size) +{ + null_instance_t *instance = (null_instance_t *)data; + if(!instance) + return; + + RARCH_LOG_BUFFER(packet, size); +} + +/** + * If the pad doesn't support rumble, then this can just be a no-op. + */ +static void null_set_rumble(void *data, enum retro_rumble_effect effect, uint16_t strength) +{ +} + +/** + * Read analog sticks. + * If the pad doesn't have any analog axis, just return 0 here. + * + * The return value must conform to the following characteristics: + * - (0, 0) is center + * - (-32768,-32768) is top-left + * - (32767,32767) is bottom-right + */ +static int16_t null_get_axis(void *data, unsigned axis) +{ + return 0; +} + +/** + * The name the pad will show up as in the UI, also used to auto-assign + * buttons in input/input_autodetect_builtin.c + */ +static const char *null_get_name(void *data) +{ + return "Null HID Pad"; +} + +/** + * Read the state of a single button. + */ +static bool null_button(void *data, uint16_t joykey) +{ + return false; +} + +/** + * Fill in the joypad interface + */ +pad_connection_interface_t null_pad_connection = { + null_pad_init, + null_pad_deinit, + null_packet_handler, + null_set_rumble, + null_get_buttons, + null_get_axis, + null_get_name, + null_button +}; diff --git a/input/common/hid/device_wiiu_gca.c b/input/common/hid/device_wiiu_gca.c new file mode 100644 index 0000000000..73e58681fb --- /dev/null +++ b/input/common/hid/device_wiiu_gca.c @@ -0,0 +1,362 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ +#include +#include "hid_device_driver.h" + +#ifdef WII +static uint8_t activation_packet[] = { 0x01, 0x13 }; +#else +static uint8_t activation_packet[] = { 0x13 }; +#endif + +#define GCA_PORT_INITIALIZING 0x00 +#define GCA_PORT_POWERED 0x04 +#define GCA_PORT_CONNECTED 0x10 +#define GCA_WAVEBIRD_CONNECTED 0x22 + +typedef struct wiiu_gca_instance { + void *handle; + bool online; + uint8_t device_state[37]; + joypad_connection_t *pads[4]; +} wiiu_gca_instance_t; + +typedef struct gca_pad_data +{ + void *gca_handle; // instance handle for the GCA adapter + hid_driver_t *driver; // HID system driver interface + uint8_t data[9]; // pad data + uint32_t slot; // slot this pad occupies + uint32_t buttons; // digital button state + int16_t analog_state[3][2]; // analog state +} gca_pad_t; + + +static void update_pad_state(wiiu_gca_instance_t *instance); +static void unregister_pad(wiiu_gca_instance_t *instance, int port); + +extern pad_connection_interface_t wiiu_gca_pad_connection; + +static void *wiiu_gca_init(void *handle) +{ + RARCH_LOG("[gca]: allocating driver instance...\n"); + wiiu_gca_instance_t *instance = calloc(1, sizeof(wiiu_gca_instance_t)); + if(instance == NULL) goto error; + memset(instance, 0, sizeof(wiiu_gca_instance_t)); + instance->handle = handle; + + hid_instance.os_driver->send_control(handle, activation_packet, sizeof(activation_packet)); + hid_instance.os_driver->read(handle, instance->device_state, sizeof(instance->device_state)); + instance->online = true; + + RARCH_LOG("[gca]: init done\n"); + return instance; + + error: + RARCH_ERR("[gca]: init failed\n"); + if(instance) + free(instance); + return NULL; +} + +static void wiiu_gca_free(void *data) { + wiiu_gca_instance_t *instance = (wiiu_gca_instance_t *)data; + int i; + + if(instance) { + instance->online = false; + + for(i = 0; i < 4; i++) + unregister_pad(instance, i); + + free(instance); + } +} + +static void wiiu_gca_handle_packet(void *data, uint8_t *buffer, size_t size) +{ + wiiu_gca_instance_t *instance = (wiiu_gca_instance_t *)data; + if(!instance || !instance->online) + { + RARCH_WARN("[gca]: instance null or not ready yet.\n"); + return; + } + + if(size > sizeof(instance->device_state)) + { + RARCH_WARN("[gca]: packet size %d is too big for buffer of size %d\n", + size, sizeof(instance->device_state)); + return; + } + + memcpy(instance->device_state, buffer, size); + update_pad_state(instance); +} + +static void update_pad_state(wiiu_gca_instance_t *instance) +{ + int i, port; + unsigned char port_connected; + + if(!instance || !instance->online) + return; + + joypad_connection_t *pad; + /* process each pad */ + for(i = 1; i < 37; i += 9) + { + port = i / 9; + pad = instance->pads[port]; + + port_connected = instance->device_state[i]; + + if(port_connected > GCA_PORT_POWERED) + { + if(pad == NULL) + { + RARCH_LOG("[gca]: Gamepad at port %d connected.\n", port+1); + instance->pads[port] = hid_pad_register(instance, &wiiu_gca_pad_connection); + pad = instance->pads[port]; + if(pad == NULL) + { + RARCH_ERR("[gca]: Failed to register pad.\n"); + break; + } + } + + pad->iface->packet_handler(pad->data, &instance->device_state[i], 9); + } else { + if(pad != NULL) { + RARCH_LOG("[gca]: Gamepad at port %d disconnected.\n", port+1); + unregister_pad(instance, port); + } + } + } +} + +static void unregister_pad(wiiu_gca_instance_t *instance, int slot) +{ + if(!instance || slot < 0 || slot >= 4 || instance->pads[slot] == NULL) + return; + + joypad_connection_t *pad = instance->pads[slot]; + instance->pads[slot] = NULL; + + hid_pad_deregister(pad); +} + +static bool wiiu_gca_detect(uint16_t vendor_id, uint16_t product_id) { + return vendor_id == VID_NINTENDO && product_id == PID_NINTENDO_GCA; +} + +hid_device_t wiiu_gca_hid_device = { + wiiu_gca_init, + wiiu_gca_free, + wiiu_gca_handle_packet, + wiiu_gca_detect, + "Wii U Gamecube Adapter" +}; + +/** + * Pad connection interface implementation. This handles each individual + * GC controller (as opposed to the above that handles the GCA itself). + */ + +static void *wiiu_gca_pad_init(void *data, uint32_t slot, hid_driver_t *driver) +{ + gca_pad_t *pad = (gca_pad_t *)calloc(1, sizeof(gca_pad_t)); + + if(!pad) + return NULL; + + memset(pad, 0, sizeof(gca_pad_t)); + + pad->gca_handle = data; + pad->driver = driver; + pad->slot = slot; + + return pad; +} + +static void wiiu_gca_pad_deinit(void *data) +{ + gca_pad_t *pad = (gca_pad_t *)data; + + if(pad) + { + input_autoconfigure_disconnect(pad->slot, wiiu_gca_pad_connection.get_name(pad)); + free(pad); + } +} + +static void wiiu_gca_get_buttons(void *data, input_bits_t *state) +{ + gca_pad_t *pad = (gca_pad_t *)data; + if(pad) + { + BITS_COPY16_PTR(state, pad->buttons); + } else { + BIT256_CLEAR_ALL_PTR(state); + } +} + +static void update_buttons(gca_pad_t *pad) +{ + uint32_t i, pressed_keys; + + static const uint32_t button_mapping[12] = + { + RETRO_DEVICE_ID_JOYPAD_A, + RETRO_DEVICE_ID_JOYPAD_B, + RETRO_DEVICE_ID_JOYPAD_X, + RETRO_DEVICE_ID_JOYPAD_Y, + RETRO_DEVICE_ID_JOYPAD_LEFT, + RETRO_DEVICE_ID_JOYPAD_RIGHT, + RETRO_DEVICE_ID_JOYPAD_DOWN, + RETRO_DEVICE_ID_JOYPAD_UP, + RETRO_DEVICE_ID_JOYPAD_START, + RETRO_DEVICE_ID_JOYPAD_SELECT, + RETRO_DEVICE_ID_JOYPAD_R, + RETRO_DEVICE_ID_JOYPAD_L, + }; + + if(!pad) + return; + + pressed_keys = pad->data[1] | (pad->data[2] << 8); + pad->buttons = 0; + + for(i = 0; i < 12; i++) + pad->buttons |= (pressed_keys & (1 << i)) ? + (1 << button_mapping[i]) : 0; +} + +#if 0 +const char *axes[] = { + "left x", + "left y", + "right x", + "right y" +}; +#endif + +static void update_analog_state(gca_pad_t *pad) +{ + int pad_axis; + int16_t interpolated; + unsigned stick, axis; + + /* GameCube analog axis are 8-bit unsigned, where 128/128 is center. + * So, we subtract 128 to get a signed, 0-based value and then mulitply + * by 256 to get the 16-bit range RetroArch expects. */ + for(pad_axis = 0; pad_axis < 4; pad_axis++) + { + axis = pad_axis % 2 ? 0 : 1; + stick = pad_axis / 2; + interpolated = pad->data[3 + pad_axis]; + /* libretro requires "up" to be negative, so we invert the y axis */ + interpolated = (axis) ? + ((interpolated - 128) * 256) : + ((interpolated - 128) * -256); + + pad->analog_state[stick][axis] = interpolated; +#if 0 + RARCH_LOG("%s: %d\n", axes[pad_axis], interpolated); +#endif + } +} + + +/** + * The USB packet provides a 9-byte data packet for each pad. + * + * byte 0: connection status (0x14 = connected, 0x04 = disconnected) + * bytes 1-2: digital buttons + * bytes 3-4: left analog stick x/y + * bytes 5-6: right analog stick x/y + * bytes 7-8: L/R analog state (note that these have digital buttons too) + */ +static void wiiu_gca_packet_handler(void *data, uint8_t *packet, uint16_t size) +{ + gca_pad_t *pad = (gca_pad_t *)data; + uint32_t i, pressed_keys; + + if(!pad || !packet || size > sizeof(pad->data)) + return; + + memcpy(pad->data, packet, size); + update_buttons(pad); + update_analog_state(pad); +} + + + +static void wiiu_gca_set_rumble(void *data, enum retro_rumble_effect effect, uint16_t strength) +{ + (void)data; + (void)effect; + (void)strength; +} + +static int16_t wiiu_gca_get_axis(void *data, unsigned axis) +{ + axis_data axis_data; + + gca_pad_t *pad = (gca_pad_t *)data; + + gamepad_read_axis_data(axis, &axis_data); + + if(!pad || axis_data.axis >= 4) + return 0; + + return gamepad_get_axis_value(pad->analog_state, &axis_data); +} + +static const char *wiiu_gca_get_name(void *data) +{ + gca_pad_t *pad = (gca_pad_t *)data; + + return "GameCube Controller"; +} + +/** + * Button bitmask values: + * 0x0001 - A 0x0010 - left 0x0100 - Start/Pause + * 0x0002 - B 0x0020 - right 0x0200 - Z + * 0x0004 - X 0x0040 - down 0x0400 - R + * 0x0008 - Y 0x0080 - up 0x0800 - L + */ + +static bool wiiu_gca_button(void *data, uint16_t joykey) +{ + gca_pad_t *pad = (gca_pad_t *)data; + + if(!pad || joykey > 31) + return false; + + return pad->buttons & (1 << joykey); +} + +pad_connection_interface_t wiiu_gca_pad_connection = { + wiiu_gca_pad_init, + wiiu_gca_pad_deinit, + wiiu_gca_packet_handler, + wiiu_gca_set_rumble, + wiiu_gca_get_buttons, + wiiu_gca_get_axis, + wiiu_gca_get_name, + wiiu_gca_button +}; diff --git a/input/common/hid/hid_device_driver.c b/input/common/hid/hid_device_driver.c new file mode 100644 index 0000000000..ccab2dc569 --- /dev/null +++ b/input/common/hid/hid_device_driver.c @@ -0,0 +1,156 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * 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 "hid_device_driver.h" + +hid_driver_instance_t hid_instance = {0}; + +hid_device_t *hid_device_list[] = { + &wiiu_gca_hid_device, + &ds3_hid_device, +/* &ds4_hid_device, */ + NULL /* must be last entry in list */ +}; + +hid_device_t *hid_device_driver_lookup(uint16_t vendor_id, uint16_t product_id) { + int i = 0; + + for(i = 0; hid_device_list[i] != NULL; i++) { + if(hid_device_list[i]->detect(vendor_id, product_id)) + return hid_device_list[i]; + } + + return NULL; +} + +joypad_connection_t *hid_pad_register(void *pad_handle, pad_connection_interface_t *iface) +{ + int slot; + joypad_connection_t *result; + + if(!pad_handle) + return NULL; + + slot = pad_connection_find_vacant_pad(hid_instance.pad_list); + if(slot < 0) + { + RARCH_ERR("[hid]: failed to find a vacant pad.\n"); + return NULL; + } + + result = &(hid_instance.pad_list[slot]); + result->iface = iface; + result->data = iface->init(pad_handle, slot, hid_instance.os_driver); + result->connected = true; + input_pad_connect(slot, hid_instance.pad_driver); + + return result; +} + +void hid_pad_deregister(joypad_connection_t *pad) +{ + if(!pad) + return; + + if(pad->data) { + pad->iface->deinit(pad->data); + pad->data = NULL; + } + + pad->iface = NULL; + pad->connected = false; +} + +static bool init_pad_list(hid_driver_instance_t *instance, unsigned slots) +{ + if(!instance || slots > MAX_USERS) + return false; + + if(instance->pad_list) + return true; + + RARCH_LOG("[hid]: initializing pad list...\n"); + instance->pad_list = pad_connection_init(slots); + if(!instance->pad_list) + return false; + + instance->max_slot = slots; + + return true; +} + +/** + * Fill in instance with data from initialized hid subsystem. + * + * @argument instance the hid_driver_instance_t struct to fill in + * @argument hid_driver the HID driver to initialize + * @argument pad_driver the gamepad driver to handle HID pads detected by the HID driver. + * + * @returns true if init is successful, false otherwise. + */ +bool hid_init(hid_driver_instance_t *instance, + hid_driver_t *hid_driver, + input_device_driver_t *pad_driver, + unsigned slots) +{ + RARCH_LOG("[hid]: initializing instance with %d pad slots\n", slots); + if(!instance || !hid_driver || !pad_driver || slots > MAX_USERS) + return false; + + RARCH_LOG("[hid]: initializing HID subsystem driver...\n"); + instance->os_driver_data = hid_driver->init(); + if(!instance->os_driver_data) + return false; + + if(!init_pad_list(instance, slots)) + { + hid_driver->free(instance->os_driver_data); + instance->os_driver_data = NULL; + return false; + } + + instance->os_driver = hid_driver; + instance->pad_driver = pad_driver; + + RARCH_LOG("[hid]: instance initialization complete.\n"); + + return true; +} + +/** + * Tear down the HID system set up by hid_init() + * + * @argument instance the hid_driver_instance_t to tear down. + */ +void hid_deinit(hid_driver_instance_t *instance) +{ + if(!instance) + return; + + RARCH_LOG("[hid]: destroying instance\n"); + + if(instance->os_driver && instance->os_driver_data) + { + RARCH_LOG("[hid]: tearing down HID subsystem driver...\n"); + instance->os_driver->free(instance->os_driver_data); + } + + RARCH_LOG("[hid]: destroying pad data...\n"); + pad_connection_destroy(instance->pad_list); + + RARCH_LOG("[hid]: wiping instance data...\n"); + memset(instance, 0, sizeof(hid_driver_instance_t)); +} diff --git a/input/common/hid/hid_device_driver.h b/input/common/hid/hid_device_driver.h new file mode 100644 index 0000000000..8e764f0f78 --- /dev/null +++ b/input/common/hid/hid_device_driver.h @@ -0,0 +1,46 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef HID_DEVICE_DRIVER__H +#define HID_DEVICE_DRIVER__H + +#include "../../input_driver.h" +#include "../../connect/joypad_connection.h" +#include "../../include/hid_driver.h" +#include "../../include/gamepad.h" +#include "../../../verbosity.h" +#include "../../../tasks/tasks_internal.h" + +typedef struct hid_device { + void *(*init)(void *handle); + void (*free)(void *data); + void (*handle_packet)(void *data, uint8_t *buffer, size_t size); + bool (*detect)(uint16_t vid, uint16_t pid); + const char *name; +} hid_device_t; + +extern hid_device_t wiiu_gca_hid_device; +extern hid_device_t ds3_hid_device; +extern hid_device_t ds4_hid_device; +extern hid_driver_instance_t hid_instance; + +hid_device_t *hid_device_driver_lookup(uint16_t vendor_id, uint16_t product_id); +joypad_connection_t *hid_pad_register(void *pad_handle, pad_connection_interface_t *iface); +void hid_pad_deregister(joypad_connection_t *pad); +bool hid_init(hid_driver_instance_t *instance, hid_driver_t *hid_driver, input_device_driver_t *pad_driver, unsigned slots); +void hid_deinit(hid_driver_instance_t *instance); + +#endif /* HID_DEVICE_DRIVER__H */ diff --git a/input/common/input_common.c b/input/common/input_common.c new file mode 100644 index 0000000000..4f6e656363 --- /dev/null +++ b/input/common/input_common.c @@ -0,0 +1,78 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include "../include/gamepad.h" + +enum pad_axes { + AXIS_LEFT_ANALOG_X, + AXIS_LEFT_ANALOG_Y, + AXIS_RIGHT_ANALOG_X, + AXIS_RIGHT_ANALOG_Y, + AXIS_INVALID +}; + +static int16_t clamp_axis(int16_t value, bool is_negative) +{ + if(is_negative && value > 0) + return 0; + if(!is_negative && value < 0) + return 0; + + return value; +} + +void gamepad_read_axis_data(uint32_t axis, axis_data *data) +{ + if(!data) + return; + + data->axis = AXIS_POS_GET(axis); + data->is_negative = false; + + if(data->axis >= AXIS_INVALID) + { + data->axis = AXIS_NEG_GET(axis); + data->is_negative = true; + } +} + +int16_t gamepad_get_axis_value(int16_t state[3][2], axis_data *data) +{ + int16_t value = 0; + + if(!data) + return 0; + + switch(data->axis) + { + case AXIS_LEFT_ANALOG_X: + value = state[RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X]; + break; + case AXIS_LEFT_ANALOG_Y: + value = state[RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y]; + break; + case AXIS_RIGHT_ANALOG_X: + value = state[RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X]; + break; + case AXIS_RIGHT_ANALOG_Y: + value = state[RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y]; + break; + } + + return clamp_axis(value, data->is_negative); +} + + diff --git a/input/connect/connect_nesusb.c b/input/connect/connect_nesusb.c index 43f1f2d51b..fc484ea88d 100644 --- a/input/connect/connect_nesusb.c +++ b/input/connect/connect_nesusb.c @@ -59,7 +59,7 @@ static void hidpad_nesusb_deinit(void *data) free(device); } -static void hidpad_nesusb_get_buttons(void *data, retro_bits_t* state) +static void hidpad_nesusb_get_buttons(void *data, input_bits_t* state) { struct hidpad_nesusb_data *device = (struct hidpad_nesusb_data*)data; if (device) diff --git a/input/connect/connect_ps2adapter.c b/input/connect/connect_ps2adapter.c index c805cb85e2..4ee0e5e6cb 100644 --- a/input/connect/connect_ps2adapter.c +++ b/input/connect/connect_ps2adapter.c @@ -59,9 +59,11 @@ static void hidpad_ps2adapter_deinit(void *data) free(device); } -static void hidpad_ps2adapter_get_buttons(void *data, retro_bits_t *state) +static void hidpad_ps2adapter_get_buttons(void *data, input_bits_t *state) { - struct hidpad_ps2adapter_data *device = (struct hidpad_ps2adapter_data*)data; + struct hidpad_ps2adapter_data *device = (struct hidpad_ps2adapter_data*) + data; + if (device) { BITS_COPY16_PTR(state, device->buttons); diff --git a/input/connect/connect_ps3.c b/input/connect/connect_ps3.c index 61269a9e88..52d0032ecd 100644 --- a/input/connect/connect_ps3.c +++ b/input/connect/connect_ps3.c @@ -21,10 +21,7 @@ #include #include "joypad_connection.h" #include "../input_defines.h" - -#ifdef WIIU -#include -#endif +#include "../common/hid/hid_device_driver.h" struct hidpad_ps3_data { @@ -134,7 +131,7 @@ static void hidpad_ps3_deinit(void *data) free(device); } -static void hidpad_ps3_get_buttons(void *data, retro_bits_t *state) +static void hidpad_ps3_get_buttons(void *data, input_bits_t *state) { struct hidpad_ps3_data *device = (struct hidpad_ps3_data*)data; if ( device ) diff --git a/input/connect/connect_ps4.c b/input/connect/connect_ps4.c index 0356a91537..f33844e6b1 100644 --- a/input/connect/connect_ps4.c +++ b/input/connect/connect_ps4.c @@ -25,6 +25,7 @@ #include "joypad_connection.h" #include "../input_defines.h" #include "../../driver.h" +#include "../common/hid/hid_device_driver.h" enum connect_ps4_dpad_states { @@ -185,7 +186,7 @@ static bool hidpad_ps4_check_dpad(struct ps4 *rpt, unsigned id) return false; } -static void hidpad_ps4_get_buttons(void *data, retro_bits_t* state) +static void hidpad_ps4_get_buttons(void *data, input_bits_t* state) { struct hidpad_ps4_data *device = (struct hidpad_ps4_data*)data; struct ps4 *rpt = device ? diff --git a/input/connect/connect_psxadapter.c b/input/connect/connect_psxadapter.c index 68f921b0b6..cbc6a402f9 100644 --- a/input/connect/connect_psxadapter.c +++ b/input/connect/connect_psxadapter.c @@ -59,9 +59,11 @@ static void hidpad_psxadapter_deinit(void *data) free(device); } -static void hidpad_psxadapter_get_buttons(void *data, retro_bits_t *state) +static void hidpad_psxadapter_get_buttons(void *data, input_bits_t *state) { - struct hidpad_psxadapter_data *device = (struct hidpad_psxadapter_data*)data; + struct hidpad_psxadapter_data *device = (struct hidpad_psxadapter_data*) + data; + if (device) { BITS_COPY16_PTR(state, device->buttons); diff --git a/input/connect/connect_snesusb.c b/input/connect/connect_snesusb.c index bdc9b16a05..314577d863 100644 --- a/input/connect/connect_snesusb.c +++ b/input/connect/connect_snesusb.c @@ -60,7 +60,7 @@ static void hidpad_snesusb_deinit(void *data) free(device); } -static void hidpad_snesusb_get_buttons(void *data, retro_bits_t *state) +static void hidpad_snesusb_get_buttons(void *data, input_bits_t *state) { struct hidpad_snesusb_data *device = (struct hidpad_snesusb_data*)data; if (device) diff --git a/input/connect/connect_wii.c b/input/connect/connect_wii.c index f02e1735be..2008be9ecc 100644 --- a/input/connect/connect_wii.c +++ b/input/connect/connect_wii.c @@ -26,6 +26,7 @@ #include "joypad_connection.h" #include "../input_defines.h" +#include "../common/hid/hid_device_driver.h" /* wiimote state flags*/ #define WIIMOTE_STATE_DEV_FOUND 0x0001 @@ -672,7 +673,7 @@ static int16_t hidpad_wii_get_axis(void *data, unsigned axis) return 0; } -static void hidpad_wii_get_buttons(void *data, retro_bits_t *state) +static void hidpad_wii_get_buttons(void *data, input_bits_t *state) { struct connect_wii_wiimote_t* device = (struct connect_wii_wiimote_t*)data; if ( device ) diff --git a/input/connect/connect_wiiugca.c b/input/connect/connect_wiiugca.c index 7e49969fd2..357e479b58 100644 --- a/input/connect/connect_wiiugca.c +++ b/input/connect/connect_wiiugca.c @@ -21,6 +21,7 @@ #include #include "joypad_connection.h" #include "../input_defines.h" +#include "../common/hid/hid_device_driver.h" struct hidpad_wiiugca_data { @@ -68,7 +69,7 @@ static void hidpad_wiiugca_deinit(void *data) free(device); } -static void hidpad_wiiugca_get_buttons(void *data, retro_bits_t *state) +static void hidpad_wiiugca_get_buttons(void *data, input_bits_t *state) { struct hidpad_wiiugca_data *device = (struct hidpad_wiiugca_data*)data; if (device) diff --git a/input/connect/connect_wiiupro.c b/input/connect/connect_wiiupro.c index 836f17856e..a6194fb922 100644 --- a/input/connect/connect_wiiupro.c +++ b/input/connect/connect_wiiupro.c @@ -23,6 +23,7 @@ #include "joypad_connection.h" #include "../input_defines.h" #include "../../driver.h" +#include "../common/hid/hid_device_driver.h" struct wiiupro_buttons { @@ -118,7 +119,7 @@ static void hidpad_wiiupro_deinit(void *data) free(device); } -static void hidpad_wiiupro_get_buttons(void *data, retro_bits_t *state) +static void hidpad_wiiupro_get_buttons(void *data, input_bits_t *state) { struct hidpad_wiiupro_data *device = (struct hidpad_wiiupro_data*)data; struct wiiupro *rpt = device ? diff --git a/input/connect/joypad_connection.c b/input/connect/joypad_connection.c index 1c7c75353b..777ac5874d 100644 --- a/input/connect/joypad_connection.c +++ b/input/connect/joypad_connection.c @@ -228,7 +228,8 @@ void pad_connection_packet(joypad_connection_t *joyconn, uint32_t pad, joyconn->iface->packet_handler(joyconn->data, data, length); } -void pad_connection_get_buttons(joypad_connection_t *joyconn, unsigned pad, retro_bits_t* state) +void pad_connection_get_buttons(joypad_connection_t *joyconn, + unsigned pad, input_bits_t *state) { if (joyconn && joyconn->iface) joyconn->iface->get_buttons(joyconn->data, state); diff --git a/input/connect/joypad_connection.h b/input/connect/joypad_connection.h index ec78b3c4df..62a454609a 100644 --- a/input/connect/joypad_connection.h +++ b/input/connect/joypad_connection.h @@ -58,13 +58,12 @@ typedef struct pad_connection_interface void (*packet_handler)(void* device, uint8_t *packet, uint16_t size); void (*set_rumble)(void* device, enum retro_rumble_effect effect, uint16_t strength); - void (*get_buttons)(void *data, retro_bits_t *state); + void (*get_buttons)(void *data, input_bits_t *state); int16_t (*get_axis)(void *data, unsigned axis); const char* (*get_name)(void *data); + bool (*button)(void *data, uint16_t joykey); } pad_connection_interface_t; -typedef struct joypad_connection joypad_connection_t; - extern pad_connection_interface_t pad_connection_wii; extern pad_connection_interface_t pad_connection_wiiupro; extern pad_connection_interface_t pad_connection_ps3; @@ -90,7 +89,7 @@ void pad_connection_packet(joypad_connection_t *joyconn, uint32_t idx, uint8_t* data, uint32_t length); void pad_connection_get_buttons(joypad_connection_t *joyconn, - unsigned idx, retro_bits_t* state); + unsigned idx, input_bits_t* state); int16_t pad_connection_get_axis(joypad_connection_t *joyconn, unsigned idx, unsigned i); diff --git a/input/drivers/cocoa_input.c b/input/drivers/cocoa_input.c index da33ccef83..2cba64d44f 100644 --- a/input/drivers/cocoa_input.c +++ b/input/drivers/cocoa_input.c @@ -53,7 +53,7 @@ int32_t cocoa_input_find_any_key(void) } static int cocoa_input_find_any_button_ret(cocoa_input_data_t *apple, - retro_bits_t * state, unsigned port) + input_bits_t * state, unsigned port) { unsigned i; @@ -78,7 +78,7 @@ int32_t cocoa_input_find_any_button(uint32_t port) if (apple->joypad->get_buttons) { - retro_bits_t state; + input_bits_t state; apple->joypad->get_buttons(port,&state); ret = cocoa_input_find_any_button_ret(apple, &state, port); } @@ -93,7 +93,7 @@ int32_t cocoa_input_find_any_button(uint32_t port) if (apple->sec_joypad->get_buttons) { - retro_bits_t state; + input_bits_t state; apple->sec_joypad->poll(); apple->sec_joypad->get_buttons(port,&state); ret = cocoa_input_find_any_button_ret(apple, &state, port); diff --git a/input/drivers/wiiu_input.c b/input/drivers/wiiu_input.c index 5a188c1f21..ba00ed971a 100644 --- a/input/drivers/wiiu_input.c +++ b/input/drivers/wiiu_input.c @@ -33,7 +33,11 @@ #include "wiiu_dbg.h" +#ifdef WIIU_HID +#define MAX_PADS 16 +#else #define MAX_PADS 5 +#endif static uint8_t keyboardChannel = 0x00; static bool keyboardState[RETROK_LAST] = { 0 }; @@ -100,7 +104,7 @@ static int16_t wiiu_pointer_device_state(wiiu_input_t* wiiu, unsigned id) { case RETRO_DEVICE_ID_POINTER_PRESSED: { - retro_bits_t state; + input_bits_t state; wiiu->joypad->get_buttons(0, &state); return BIT256_GET(state, VPAD_BUTTON_TOUCH_BIT) ? 1 : 0; } diff --git a/input/drivers_hid/btstack_hid.c b/input/drivers_hid/btstack_hid.c index 1d277484aa..fb701e7505 100644 --- a/input/drivers_hid/btstack_hid.c +++ b/input/drivers_hid/btstack_hid.c @@ -1364,7 +1364,8 @@ static const char *btstack_hid_joypad_name(void *data, unsigned pad) return NULL; } -static void btstack_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t *state) +static void btstack_hid_joypad_get_buttons(void *data, unsigned port, + input_bits_t *state) { btstack_hid_t *hid = (btstack_hid_t*)data; if (hid) @@ -1373,9 +1374,10 @@ static void btstack_hid_joypad_get_buttons(void *data, unsigned port, retro_bits BIT256_CLEAR_ALL_PTR(state); } -static bool btstack_hid_joypad_button(void *data, unsigned port, uint16_t joykey) +static bool btstack_hid_joypad_button(void *data, + unsigned port, uint16_t joykey) { - retro_bits_t buttons; + input_bits_t buttons; btstack_hid_joypad_get_buttons(data, port, &buttons); /* Check hat. */ diff --git a/input/drivers_hid/iohidmanager_hid.c b/input/drivers_hid/iohidmanager_hid.c index 8145971ad7..b7239e0f02 100644 --- a/input/drivers_hid/iohidmanager_hid.c +++ b/input/drivers_hid/iohidmanager_hid.c @@ -71,7 +71,7 @@ CFComparisonResult iohidmanager_sort_elements(const void *val1, const void *val2 if (page1 != page2) return (CFComparisonResult)(page1 > page2); - if(use1 != use2) + if (use1 != use2) return (CFComparisonResult)(use1 > use2); return (CFComparisonResult)(cookie1 > cookie2); @@ -79,9 +79,9 @@ CFComparisonResult iohidmanager_sort_elements(const void *val1, const void *val2 static bool iohidmanager_check_for_id(apple_input_rec_t *rec, uint32_t id) { - while(rec) + while (rec) { - if(rec->id == id) + if (rec->id == id) return true; rec = rec->next; } @@ -91,7 +91,7 @@ static bool iohidmanager_check_for_id(apple_input_rec_t *rec, uint32_t id) static void iohidmanager_append_record(apple_input_rec_t *rec, apple_input_rec_t *b) { apple_input_rec_t *tmp = rec; - while(tmp->next) + while (tmp->next) tmp = tmp->next; tmp->next = b; } @@ -111,12 +111,13 @@ static void iohidmanager_append_record(apple_input_rec_t *rec, apple_input_rec_t static void iohidmanager_append_record_ordered(apple_input_rec_t **p_rec, apple_input_rec_t *b) { apple_input_rec_t *tmp = *p_rec; - while(tmp && (tmp->id <= b->id)) { - p_rec = &tmp->next; - tmp = tmp->next; + while (tmp && (tmp->id <= b->id)) + { + p_rec = &tmp->next; + tmp = tmp->next; } - b->next = tmp; - *p_rec = b; + b->next = tmp; + *p_rec = b; } static bool iohidmanager_hid_joypad_query(void *data, unsigned pad) @@ -133,7 +134,8 @@ static const char *iohidmanager_hid_joypad_name(void *data, unsigned pad) return NULL; } -static void iohidmanager_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t *state) +static void iohidmanager_hid_joypad_get_buttons(void *data, + unsigned port, input_bits_t *state) { iohidmanager_hid_t *hid = (iohidmanager_hid_t*)data; if (hid) @@ -145,7 +147,7 @@ static void iohidmanager_hid_joypad_get_buttons(void *data, unsigned port, retro static bool iohidmanager_hid_joypad_button(void *data, unsigned port, uint16_t joykey) { - retro_bits_t buttons; + input_bits_t buttons; iohidmanager_hid_t *hid = (iohidmanager_hid_t*)data; unsigned hat_dir = GET_HAT_DIR(joykey); @@ -155,7 +157,7 @@ static bool iohidmanager_hid_joypad_button(void *data, if (hat_dir) { unsigned h = GET_HAT(joykey); - if(h >= 1) + if (h >= 1) return false; switch(hat_dir) @@ -208,7 +210,7 @@ static int16_t iohidmanager_hid_joypad_axis(void *data, if (val >= 0) val = 0; } - else if(AXIS_POS_GET(joyaxis) < 6) + else if (AXIS_POS_GET(joyaxis) < 6) { val += hid->axes[port][AXIS_POS_GET(joyaxis)]; val += pad_connection_get_axis(&hid->slots[port], @@ -283,15 +285,15 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result, { tmp = adapter->hats; - while(tmp && tmp->cookie != (IOHIDElementCookie)cookie) + while (tmp && tmp->cookie != (IOHIDElementCookie)cookie) tmp = tmp->next; - if(tmp->cookie == (IOHIDElementCookie)cookie) + if (tmp->cookie == (IOHIDElementCookie)cookie) { CFIndex range = IOHIDElementGetLogicalMax(element) - IOHIDElementGetLogicalMin(element); CFIndex val = IOHIDValueGetIntegerValue(value); - if(range == 3) + if (range == 3) val *= 2; switch(val) @@ -348,12 +350,12 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result, default: tmp = adapter->axes; - while(tmp && tmp->cookie != (IOHIDElementCookie)cookie) + while (tmp && tmp->cookie != (IOHIDElementCookie)cookie) tmp = tmp->next; if (tmp) { - if(tmp->cookie == (IOHIDElementCookie)cookie) + if (tmp->cookie == (IOHIDElementCookie)cookie) { CFIndex min = IOHIDElementGetPhysicalMin(element); CFIndex state = IOHIDValueGetIntegerValue(value) - min; @@ -385,16 +387,17 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result, if (pushed_button) { - tmp = adapter->buttons; - uint8_t bit = 0; - while(tmp && tmp->cookie != (IOHIDElementCookie)cookie) + + tmp = adapter->buttons; + + while (tmp && tmp->cookie != (IOHIDElementCookie)cookie) { bit++; tmp = tmp->next; } - if(tmp && tmp->cookie == (IOHIDElementCookie)cookie) + if (tmp && tmp->cookie == (IOHIDElementCookie)cookie) { CFIndex state = IOHIDValueGetIntegerValue(value); if (state) @@ -426,19 +429,21 @@ static void iohidmanager_hid_device_remove(void *data, if (adapter) { apple_input_rec_t* tmp = NULL; - while(adapter->hats != NULL) + while (adapter->hats != NULL) { tmp = adapter->hats; adapter->hats = adapter->hats->next; free(tmp); } - while(adapter->axes != NULL) + + while (adapter->axes != NULL) { tmp = adapter->axes; adapter->axes = adapter->axes->next; free(tmp); } - while(adapter->buttons != NULL) + + while (adapter->buttons != NULL) { tmp = adapter->buttons; adapter->buttons = adapter->buttons->next; @@ -451,11 +456,11 @@ static void iohidmanager_hid_device_remove(void *data, static int32_t iohidmanager_hid_device_get_int_property( IOHIDDeviceRef device, CFStringRef key) { - int32_t value; CFNumberRef ref = (CFNumberRef)IOHIDDeviceGetProperty(device, key); if (ref && (CFGetTypeID(ref) == CFNumberGetTypeID())) { + int32_t value = 0; CFNumberGetValue((CFNumberRef)ref, kCFNumberIntType, &value); return value; } @@ -609,17 +614,18 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag for (i = 0; i < count; i++) { + IOHIDElementType type; + uint32_t page, use, cookie; + int detected_button = 0; IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i); if (!element) continue; - IOHIDElementType type = IOHIDElementGetType(element); - uint32_t page = (uint32_t)IOHIDElementGetUsagePage(element); - uint32_t use = (uint32_t)IOHIDElementGetUsage(element); - uint32_t cookie = (uint32_t)IOHIDElementGetCookie(element); - - int detected_button = 0; + type = IOHIDElementGetType(element); + page = (uint32_t)IOHIDElementGetUsagePage(element); + use = (uint32_t)IOHIDElementGetUsage(element); + cookie = (uint32_t)IOHIDElementGetCookie(element); switch (page) { @@ -664,21 +670,21 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag axis->cookie = (IOHIDElementCookie)cookie; axis->next = NULL; - if(iohidmanager_check_for_id(adapter->axes,i)) + if (iohidmanager_check_for_id(adapter->axes,i)) { /* axis ID already exists, save to tmp for appending later */ - if(tmpAxes) + if (tmpAxes) iohidmanager_append_record(tmpAxes, axis); else - tmpAxes = axis; + tmpAxes = axis; } else { found_axis[axis->id] = true; - if(adapter->axes) + if (adapter->axes) iohidmanager_append_record(adapter->axes, axis); else - adapter->axes = axis; + adapter->axes = axis; } } else @@ -715,16 +721,16 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag btn->cookie = (IOHIDElementCookie)cookie; btn->next = NULL; - if(iohidmanager_check_for_id(adapter->buttons,btn->id)) + if (iohidmanager_check_for_id(adapter->buttons,btn->id)) { - if(tmpButtons) + if (tmpButtons) iohidmanager_append_record_ordered(&tmpButtons, btn); else tmpButtons = btn; } else { - if(adapter->buttons) + if (adapter->buttons) iohidmanager_append_record_ordered(&adapter->buttons, btn); else adapter->buttons = btn; @@ -735,13 +741,13 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag /* take care of buttons/axes with duplicate 'use' values */ for (i = 0; i < 6; i++) { - if(found_axis[i] == false && tmpAxes) + if (found_axis[i] == false && tmpAxes) { apple_input_rec_t *next = tmpAxes->next; tmpAxes->id = i; tmpAxes->next = NULL; iohidmanager_append_record(adapter->axes, tmpAxes); - tmpAxes = next; + tmpAxes = next; } } @@ -749,11 +755,11 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag if (tmp) { - while(tmp->next) + while (tmp->next) tmp = tmp->next; } - while(tmpButtons) + while (tmpButtons) { apple_input_rec_t *next = tmpButtons->next; @@ -774,34 +780,34 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag error: { apple_input_rec_t *tmp = NULL; - while(adapter->hats != NULL) + while (adapter->hats != NULL) { - tmp = adapter->hats; - adapter->hats = adapter->hats->next; + tmp = adapter->hats; + adapter->hats = adapter->hats->next; free(tmp); } - while(adapter->axes != NULL) + while (adapter->axes != NULL) { - tmp = adapter->axes; - adapter->axes = adapter->axes->next; + tmp = adapter->axes; + adapter->axes = adapter->axes->next; free(tmp); } - while(adapter->buttons != NULL) + while (adapter->buttons != NULL) { tmp = adapter->buttons; adapter->buttons = adapter->buttons->next; free(tmp); } - while(tmpAxes != NULL) + while (tmpAxes != NULL) { - tmp = tmpAxes; - tmpAxes = tmpAxes->next; + tmp = tmpAxes; + tmpAxes = tmpAxes->next; free(tmp); } - while(tmpButtons != NULL) + while (tmpButtons != NULL) { - tmp = tmpButtons; - tmpButtons = tmpButtons->next; + tmp = tmpButtons; + tmpButtons = tmpButtons->next; free(tmp); } free(adapter); @@ -975,7 +981,8 @@ static void *iohidmanager_hid_init(void) calloc(1, sizeof(*hid_apple)); if (!hid_apple) - goto error; + return NULL; + hid_apple->slots = pad_connection_init(MAX_USERS); if (!hid_apple->slots) diff --git a/input/drivers_hid/libusb_hid.c b/input/drivers_hid/libusb_hid.c index 44580359fa..b7622b92c1 100644 --- a/input/drivers_hid/libusb_hid.c +++ b/input/drivers_hid/libusb_hid.c @@ -443,7 +443,8 @@ static const char *libusb_hid_joypad_name(void *data, unsigned pad) return NULL; } -static void libusb_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t *state) +static void libusb_hid_joypad_get_buttons(void *data, unsigned port, + input_bits_t *state) { libusb_hid_t *hid = (libusb_hid_t*)data; if (hid) @@ -458,7 +459,7 @@ static void libusb_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_ static bool libusb_hid_joypad_button(void *data, unsigned port, uint16_t joykey) { - retro_bits_t buttons; + input_bits_t buttons; libusb_hid_joypad_get_buttons(data, port, &buttons); /* Check hat. */ diff --git a/input/drivers_hid/null_hid.c b/input/drivers_hid/null_hid.c index 70a34d4bf8..44d1cc397b 100644 --- a/input/drivers_hid/null_hid.c +++ b/input/drivers_hid/null_hid.c @@ -18,6 +18,7 @@ #include "../input_defines.h" #include "../input_driver.h" +#include "../include/hid_driver.h" typedef struct null_hid { @@ -38,7 +39,8 @@ static const char *null_hid_joypad_name(void *data, unsigned pad) return NULL; } -static void null_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t *state) +static void null_hid_joypad_get_buttons(void *data, + unsigned port, input_bits_t *state) { (void)data; (void)port; diff --git a/input/drivers_hid/wiiusb_hid.c b/input/drivers_hid/wiiusb_hid.c index 397f0a0a64..9f4fea629a 100644 --- a/input/drivers_hid/wiiusb_hid.c +++ b/input/drivers_hid/wiiusb_hid.c @@ -478,7 +478,8 @@ static bool wiiusb_hid_joypad_query(void *data, unsigned pad) return pad < MAX_USERS; } -static void wiiusb_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t *state) +static void wiiusb_hid_joypad_get_buttons(void *data, + unsigned port, input_bits_t *state) { wiiusb_hid_t *hid = (wiiusb_hid_t*)data; if (hid) @@ -489,9 +490,10 @@ static void wiiusb_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_ BIT256_CLEAR_ALL_PTR(state); } -static bool wiiusb_hid_joypad_button(void *data, unsigned port, uint16_t joykey) +static bool wiiusb_hid_joypad_button(void *data, + unsigned port, uint16_t joykey) { - retro_bits_t buttons; + input_bits_t buttons; wiiusb_hid_joypad_get_buttons(data, port, &buttons); diff --git a/input/drivers_joypad/ctr_joypad.c b/input/drivers_joypad/ctr_joypad.c index 711b88493d..1bfd559cd2 100644 --- a/input/drivers_joypad/ctr_joypad.c +++ b/input/drivers_joypad/ctr_joypad.c @@ -70,7 +70,7 @@ static bool ctr_joypad_button(unsigned port_num, uint16_t key) return (pad_state & (1 << key)); } -static void ctr_joypad_get_buttons(unsigned port_num, retro_bits_t *state) +static void ctr_joypad_get_buttons(unsigned port_num, input_bits_t *state) { if ( port_num < MAX_PADS ) { diff --git a/input/drivers_joypad/gx_joypad.c b/input/drivers_joypad/gx_joypad.c index 392cb602a9..1e4c0b9a4b 100644 --- a/input/drivers_joypad/gx_joypad.c +++ b/input/drivers_joypad/gx_joypad.c @@ -162,7 +162,7 @@ static bool gx_joypad_button(unsigned port, uint16_t key) return (pad_state[port] & (UINT64_C(1) << key)); } -static void gx_joypad_get_buttons(unsigned port, retro_bits_t *state) +static void gx_joypad_get_buttons(unsigned port, input_bits_t *state) { if (port < MAX_PADS) { diff --git a/input/drivers_joypad/hid_joypad.c b/input/drivers_joypad/hid_joypad.c index 203a272922..c35aff850d 100644 --- a/input/drivers_joypad/hid_joypad.c +++ b/input/drivers_joypad/hid_joypad.c @@ -55,7 +55,7 @@ static bool hid_joypad_button(unsigned port, uint16_t joykey) return false; } -static void hid_joypad_get_buttons(unsigned port, retro_bits_t *state) +static void hid_joypad_get_buttons(unsigned port, input_bits_t *state) { if (generic_hid && generic_hid->get_buttons) generic_hid->get_buttons((void*)hid_driver_get_data(), port, state); diff --git a/input/drivers_joypad/linuxraw_joypad.c b/input/drivers_joypad/linuxraw_joypad.c index 4d852f406b..b87a6e7bd0 100644 --- a/input/drivers_joypad/linuxraw_joypad.c +++ b/input/drivers_joypad/linuxraw_joypad.c @@ -326,9 +326,11 @@ static bool linuxraw_joypad_button(unsigned port, uint16_t joykey) return joykey < NUM_BUTTONS && BIT32_GET(pad->buttons, joykey); } -static void linuxraw_joypad_get_buttons(unsigned port, retro_bits_t *state) +static void linuxraw_joypad_get_buttons(unsigned port, input_bits_t *state) { - const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*)&linuxraw_pads[port]; + const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*) + &linuxraw_pads[port]; + if (pad) { BITS_COPY16_PTR(state, pad->buttons); diff --git a/input/drivers_joypad/mfi_joypad.m b/input/drivers_joypad/mfi_joypad.m index 94f56b2147..32f52e334c 100644 --- a/input/drivers_joypad/mfi_joypad.m +++ b/input/drivers_joypad/mfi_joypad.m @@ -221,7 +221,8 @@ static bool apple_gamecontroller_joypad_button(unsigned port, uint16_t joykey) return false; } -static void apple_gamecontroller_joypad_get_buttons(unsigned port, retro_bits_t *state) +static void apple_gamecontroller_joypad_get_buttons(unsigned port, + input_bits_t *state) { BITS_COPY16_PTR(state, mfi_buttons[port]); } diff --git a/input/drivers_joypad/null_joypad.c b/input/drivers_joypad/null_joypad.c index 058d01d5b3..d41198a8bf 100644 --- a/input/drivers_joypad/null_joypad.c +++ b/input/drivers_joypad/null_joypad.c @@ -37,7 +37,7 @@ static bool null_joypad_button(unsigned port_num, uint16_t joykey) return false; } -static void null_joypad_get_buttons(unsigned port_num, retro_bits_t *state) +static void null_joypad_get_buttons(unsigned port_num, input_bits_t *state) { BIT256_CLEAR_ALL_PTR(state); } diff --git a/input/drivers_joypad/parport_joypad.c b/input/drivers_joypad/parport_joypad.c index e236a36fc5..d392745acf 100644 --- a/input/drivers_joypad/parport_joypad.c +++ b/input/drivers_joypad/parport_joypad.c @@ -340,9 +340,11 @@ static bool parport_joypad_button(unsigned port, uint16_t joykey) return joykey < PARPORT_NUM_BUTTONS && BIT32_GET(pad->buttons, joykey); } -static void parport_joypad_get_buttons(unsigned port, retro_bits_t *state) +static void parport_joypad_get_buttons(unsigned port, input_bits_t *state) { - const struct parport_joypad *pad = (const struct parport_joypad*)&parport_pads[port]; + const struct parport_joypad *pad = (const struct parport_joypad*) + &parport_pads[port]; + if (pad) { BITS_COPY16_PTR(state, pad->buttons); diff --git a/input/drivers_joypad/ps3_joypad.c b/input/drivers_joypad/ps3_joypad.c index a85a23fcf9..0088f6d256 100644 --- a/input/drivers_joypad/ps3_joypad.c +++ b/input/drivers_joypad/ps3_joypad.c @@ -68,7 +68,7 @@ static bool ps3_joypad_button(unsigned port_num, uint16_t joykey) return pad_state[port_num] & (UINT64_C(1) << joykey); } -static void ps3_joypad_get_buttons(unsigned port_num, retro_bits_t *state) +static void ps3_joypad_get_buttons(unsigned port_num, input_bits_t *state) { if (port_num < MAX_PADS) { diff --git a/input/drivers_joypad/psp_joypad.c b/input/drivers_joypad/psp_joypad.c index d9cb4dd65a..309a8a0f3c 100644 --- a/input/drivers_joypad/psp_joypad.c +++ b/input/drivers_joypad/psp_joypad.c @@ -124,7 +124,7 @@ static bool psp_joypad_button(unsigned port_num, uint16_t key) return (pad_state[port_num] & (UINT64_C(1) << key)); } -static void psp_joypad_get_buttons(unsigned port_num, retro_bits_t *state) +static void psp_joypad_get_buttons(unsigned port_num, input_bits_t *state) { if (port_num < PSP_MAX_PADS) { diff --git a/input/drivers_joypad/rwebpad_joypad.c b/input/drivers_joypad/rwebpad_joypad.c index f061996e6e..4278afb757 100644 --- a/input/drivers_joypad/rwebpad_joypad.c +++ b/input/drivers_joypad/rwebpad_joypad.c @@ -130,12 +130,11 @@ static bool rwebpad_joypad_button(unsigned port_num, uint16_t joykey) return false; } -static void rwebpad_joypad_get_buttons(unsigned port_num, retro_bits_t *state) +static void rwebpad_joypad_get_buttons(unsigned port_num, input_bits_t *state) { EmscriptenGamepadEvent gamepad_state; - EMSCRIPTEN_RESULT r; - - r = emscripten_get_gamepad_status(port_num, &gamepad_state); + EMSCRIPTEN_RESULT r = emscripten_get_gamepad_status( + port_num, &gamepad_state); if (r == EMSCRIPTEN_RESULT_SUCCESS) { diff --git a/input/drivers_joypad/switch_joypad.c b/input/drivers_joypad/switch_joypad.c index 5a88d9c70b..eb18024ee4 100644 --- a/input/drivers_joypad/switch_joypad.c +++ b/input/drivers_joypad/switch_joypad.c @@ -60,7 +60,7 @@ static bool switch_joypad_button(unsigned port_num, uint16_t key) return (pad_state[port_num] & (1 << key)); } -static void switch_joypad_get_buttons(unsigned port_num, retro_bits_t *state) +static void switch_joypad_get_buttons(unsigned port_num, input_bits_t *state) { if(port_num < MAX_PADS) { diff --git a/input/drivers_joypad/udev_joypad.c b/input/drivers_joypad/udev_joypad.c index 9f79b19f7f..4475c62e5f 100644 --- a/input/drivers_joypad/udev_joypad.c +++ b/input/drivers_joypad/udev_joypad.c @@ -637,9 +637,11 @@ static bool udev_joypad_button(unsigned port, uint16_t joykey) return joykey < UDEV_NUM_BUTTONS && BIT64_GET(pad->buttons, joykey); } -static void udev_joypad_get_buttons(unsigned port, retro_bits_t *state) +static void udev_joypad_get_buttons(unsigned port, input_bits_t *state) { - const struct udev_joypad *pad = (const struct udev_joypad*)&udev_pads[port]; + const struct udev_joypad *pad = (const struct udev_joypad*) + &udev_pads[port]; + if (pad) { BITS_COPY16_PTR( state, pad->buttons ); diff --git a/input/drivers_joypad/wiiu_joypad.c b/input/drivers_joypad/wiiu_joypad.c index 4ae4a4863a..5728a90c6d 100644 --- a/input/drivers_joypad/wiiu_joypad.c +++ b/input/drivers_joypad/wiiu_joypad.c @@ -14,11 +14,13 @@ * If not, see . */ -#include +#include "../../wiiu/input/wiiu_input.h" #include "wiiu_dbg.h" static input_device_driver_t *pad_drivers[MAX_USERS]; +extern pad_connection_listener_t wiiu_pad_connection_listener; + static bool ready = false; @@ -26,69 +28,35 @@ static bool wiiu_joypad_init(void *data); static bool wiiu_joypad_query_pad(unsigned pad); static void wiiu_joypad_destroy(void); static bool wiiu_joypad_button(unsigned pad, uint16_t button); -static void wiiu_joypad_get_buttons(unsigned pad, retro_bits_t *state); +static void wiiu_joypad_get_buttons(unsigned pad, input_bits_t *state); static int16_t wiiu_joypad_axis(unsigned pad, uint32_t axis); static void wiiu_joypad_poll(void); static const char *wiiu_joypad_name(unsigned pad); -/** - * Translates a pad to its appropriate driver. - * Note that this is a helper for build_pad_map and shouldn't be - * used directly. - */ -static input_device_driver_t *get_driver_for_pad(unsigned pad) -{ - if(wpad_driver.query_pad(pad)) - return &wpad_driver; - if(kpad_driver.query_pad(pad)) - return &kpad_driver; - -#ifdef WIIU_HID - return &hidpad_driver; -#else - return NULL; -#endif -} - -/** - * Populates the pad_driver array. We do this once at init time so - * that lookups at runtime are constant time. - */ -static void build_pad_map(void) -{ - unsigned i; - - for(i = 0; i < MAX_USERS; i++) - { - pad_drivers[i] = get_driver_for_pad(i); - } -} - static bool wiiu_joypad_init(void* data) { - /* the sub-drivers have to init first, otherwise - * build_pad_map will fail (because all lookups will return false). */ - wpad_driver.init(data); - kpad_driver.init(data); + set_connection_listener(&wiiu_pad_connection_listener); + hid_instance.pad_list = pad_connection_init(MAX_USERS); + hid_instance.max_slot = MAX_USERS; + + wpad_driver.init(data); + kpad_driver.init(data); #ifdef WIIU_HID - hidpad_driver.init(data); + hidpad_driver.init(data); #endif - build_pad_map(); + ready = true; + (void)data; - ready = true; - (void)data; - - return true; + return true; } static bool wiiu_joypad_query_pad(unsigned pad) { -#ifdef WIIU_HID - return ready && pad < MAX_USERS; -#else - return ready && pad < 5; -#endif + return ready && + pad < MAX_USERS && + pad_drivers[pad] != NULL && + pad_drivers[pad]->query_pad(pad); } static void wiiu_joypad_destroy(void) @@ -110,7 +78,7 @@ static bool wiiu_joypad_button(unsigned pad, uint16_t key) return pad_drivers[pad]->button(pad, key); } -static void wiiu_joypad_get_buttons(unsigned pad, retro_bits_t *state) +static void wiiu_joypad_get_buttons(unsigned pad, input_bits_t *state) { if(!wiiu_joypad_query_pad(pad)) return; @@ -137,10 +105,17 @@ static void wiiu_joypad_poll(void) static const char* wiiu_joypad_name(unsigned pad) { - if(!wiiu_joypad_query_pad(pad)) - return "N/A"; + if(!wiiu_joypad_query_pad(pad)) + return "N/A"; - return pad_drivers[pad]->name(pad); + return pad_drivers[pad]->name(pad); +} + +static void wiiu_joypad_connection_listener(unsigned pad, + input_device_driver_t *driver) +{ + if(pad < MAX_USERS) + pad_drivers[pad] = driver; } input_device_driver_t wiiu_joypad = @@ -156,3 +131,8 @@ input_device_driver_t wiiu_joypad = wiiu_joypad_name, "wiiu", }; + +pad_connection_listener_t wiiu_pad_connection_listener = +{ + wiiu_joypad_connection_listener +}; diff --git a/input/include/gamepad.h b/input/include/gamepad.h new file mode 100644 index 0000000000..d895b55f25 --- /dev/null +++ b/input/include/gamepad.h @@ -0,0 +1,35 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Andrés Suárez + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef GAMEPAD_H__ +#define GAMEPAD_H__ + +#include "../input_driver.h" + +struct pad_connection_listener_interface { + void (*connected)(unsigned port, input_device_driver_t *driver); +}; + +typedef struct _axis_data { + int32_t axis; + bool is_negative; +} axis_data; + +void gamepad_read_axis_data(uint32_t axis, axis_data *data); +int16_t gamepad_get_axis_value(int16_t state[3][2], axis_data *data); + +#endif /* GAMEPAD_H__ */ diff --git a/input/include/hid_driver.h b/input/include/hid_driver.h new file mode 100644 index 0000000000..02b6529f63 --- /dev/null +++ b/input/include/hid_driver.h @@ -0,0 +1,84 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Andrés Suárez + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef HID_DRIVER_H__ +#define HID_DRIVER_H__ + +#include "../connect/joypad_connection.h" +#include "../input_driver.h" + +/* what is 1? */ +#define HID_REPORT_OUTPUT 2 +#define HID_REPORT_FEATURE 3 +/* are there more? */ + +/* + * This is the interface for the HID subsystem. + * + * The handle parameter is the pointer returned by init() and stores the implementation + * state data for the HID driver. + */ + +struct hid_driver +{ + void *(*init)(void); + bool (*query_pad)(void *handle, unsigned pad); + void (*free)(const void *handle); + bool (*button)(void *handle, unsigned pad, uint16_t button); + void (*get_buttons)(void *handle, unsigned pad, input_bits_t *state); + int16_t (*axis)(void *handle, unsigned pad, uint32_t axis); + void (*poll)(void *handle); + bool (*set_rumble)(void *handle, unsigned pad, enum retro_rumble_effect effect, uint16_t); + const char *(*name)(void *handle, unsigned pad); + const char *ident; + void (*send_control)(void *handle, uint8_t *buf, size_t size); + int32_t (*set_report)(void *handle, uint8_t, uint8_t, void *data, uint32_t size); + int32_t (*set_idle)(void *handle, uint8_t amount); + int32_t (*set_protocol)(void *handle, uint8_t protocol); + int32_t (*read)(void *handle, void *buf, size_t size); +}; + +#define HID_GET_BUTTONS(pad, state) hid_instance.os_driver->get_buttons( \ + hid_instance.os_driver_data, pad, state) +#define HID_BUTTON(pad, key) hid_instance.os_driver->button( \ + hid_instance.os_driver_data, pad, key) +#define HID_AXIS(pad, axis) hid_instance.os_driver->axis( \ + hid_instance.os_driver_data, pad, axis) +#define HID_PAD_NAME(pad) \ + hid_instance.os_driver->name(hid_instance.os_driver_data, pad) +#define HID_SET_PROTOCOL(pad, protocol) \ + hid_instance.os_driver->set_protocol(pad, protocol) +#define HID_SET_REPORT(pad, rpttype, rptid, data, len) \ + hid_instance.os_driver->set_report(pad, rpttype, rptid, data, len) +#define HID_SEND_CONTROL(pad, data, len) \ + hid_instance.os_driver->send_control(pad, data, len) +#define HID_POLL() hid_instance.os_driver->poll( \ + hid_instance.os_driver_data) +#define HID_MAX_SLOT() hid_instance.max_slot +#define HID_PAD_CONNECTION_PTR(slot) &(hid_instance.pad_list[(slot)]) + + + +struct hid_driver_instance { + hid_driver_t *os_driver; + void *os_driver_data; + input_device_driver_t *pad_driver; + joypad_connection_t *pad_list; + unsigned max_slot; +}; + +#endif /* HID_DRIVER_H__ */ diff --git a/input/include/hid_types.h b/input/include/hid_types.h new file mode 100644 index 0000000000..28734e9dd8 --- /dev/null +++ b/input/include/hid_types.h @@ -0,0 +1,24 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Andrés Suárez + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef HID_TYPES_H__ +#define HID_TYPES_H__ + +typedef struct hid_driver hid_driver_t; +typedef struct hid_driver_instance hid_driver_instance_t; + +#endif /* HID_TYPES_H__ */ diff --git a/input/input_autodetect_builtin.c b/input/input_autodetect_builtin.c index 0e76b04f4e..db3443cd45 100644 --- a/input/input_autodetect_builtin.c +++ b/input/input_autodetect_builtin.c @@ -29,7 +29,7 @@ #endif #ifdef WIIU -#include +#include #endif #define DECL_BTN(btn, bind) "input_" #btn "_btn = " #bind "\n" @@ -228,6 +228,56 @@ DECL_AXIS(r_y_minus, +3) #ifdef WIIU +#define WIIUINPUT_GAMECUBE_DEFAULT_BINDS \ +DECL_BTN_EX(a, 8, "A") \ +DECL_BTN_EX(b, 0, "B") \ +DECL_BTN_EX(x, 9, "X") \ +DECL_BTN_EX(y, 1, "Y") \ +DECL_BTN_EX(left, 6, "D-Pad Left") \ +DECL_BTN_EX(right, 7, "D-Pad Right") \ +DECL_BTN_EX(down, 5, "D-Pad Down") \ +DECL_BTN_EX(up, 4, "D-Pad Up") \ +DECL_BTN_EX(start, 3, "Start/Pause") \ +DECL_BTN_EX(select, 2, "Z") \ +DECL_BTN_EX(r, 10, "R Trigger") \ +DECL_BTN_EX(l, 11, "L Trigger") \ +DECL_AXIS_EX(l_x_plus, +1, "Analog right") \ +DECL_AXIS_EX(l_x_minus, -1, "Analog left") \ +DECL_AXIS_EX(l_y_plus, +0, "Analog up") \ +DECL_AXIS_EX(l_y_minus, -0, "Analog down") \ +DECL_AXIS_EX(r_x_plus, +3, "C-stick right") \ +DECL_AXIS_EX(r_x_minus, -3, "C-stick left") \ +DECL_AXIS_EX(r_y_plus, +2, "C-stick up") \ +DECL_AXIS_EX(r_y_minus, -2, "C-stick down") + +#define WIIUINPUT_DS3_DEFAULT_BINDS \ +DECL_BTN_EX(menu_toggle, 16, "Playstation") \ +DECL_BTN_EX(select, 2, "Select") \ +DECL_BTN_EX(start, 3, "Start") \ +DECL_BTN_EX(a, 8, "Circle") \ +DECL_BTN_EX(y, 1, "Triangle") \ +DECL_BTN_EX(b, 0, "Cross") \ +DECL_BTN_EX(x, 9, "Square") \ +DECL_BTN_EX(r, 11, "R1") \ +DECL_BTN_EX(l, 10, "L1") \ +DECL_BTN_EX(r2, 13, "R2") \ +DECL_BTN_EX(l2, 12, "L2") \ +DECL_BTN_EX(up, 4, "D-Pad Up") \ +DECL_BTN_EX(down, 5, "D-Pad Down") \ +DECL_BTN_EX(left, 6, "D-Pad left") \ +DECL_BTN_EX(right, 7, "D-Pad Right") \ +DECL_BTN_EX(r3, 15, "R3") \ +DECL_BTN_EX(l3, 14, "L3") \ +DECL_AXIS_EX(l_x_plus, +1, "L Analog right") \ +DECL_AXIS_EX(l_x_minus, -1, "L Analog left") \ +DECL_AXIS_EX(l_y_plus, +0, "L Analog up") \ +DECL_AXIS_EX(l_y_minus, -0, "L Analog down") \ +DECL_AXIS_EX(r_x_plus, +3, "R Analog right") \ +DECL_AXIS_EX(r_x_minus, -3, "R Analog left") \ +DECL_AXIS_EX(r_y_plus, +2, "R Analog up") \ +DECL_AXIS_EX(r_y_minus, -2, "R Analog down") + + #define WIIUINPUT_GAMEPAD_DEFAULT_BINDS \ DECL_BTN_EX(menu_toggle, 1, "Home") \ DECL_BTN_EX(select, 2, "-") \ @@ -612,6 +662,8 @@ const char* const input_builtin_autoconfs[] = DECL_AUTOCONF_DEVICE(PAD_NAME_NUNCHUK, "wiiu", WIIUINPUT_NUNCHUK_DEFAULT_BINDS), DECL_AUTOCONF_DEVICE(PAD_NAME_CLASSIC, "wiiu", WIIUINPUT_CLASSIC_CONTROLLER_DEFAULT_BINDS), DECL_AUTOCONF_DEVICE(PAD_NAME_HID, "wiiu", WIIUINPUT_GAMEPAD_DEFAULT_BINDS), + DECL_AUTOCONF_DEVICE("GameCube Controller", "wiiu", WIIUINPUT_GAMECUBE_DEFAULT_BINDS), + DECL_AUTOCONF_DEVICE("Sony DualShock 3", "wiiu", WIIUINPUT_DS3_DEFAULT_BINDS), #endif #ifdef __CELLOS_LV2__ DECL_AUTOCONF_DEVICE("SixAxis Controller", "ps3", PS3INPUT_DEFAULT_BINDS), diff --git a/input/input_defines.h b/input/input_defines.h index 91f14d2766..5e4103bcc9 100644 --- a/input/input_defines.h +++ b/input/input_defines.h @@ -28,11 +28,15 @@ RETRO_BEGIN_DECLS #define MAX_INPUT_DEVICES 16 +#define RARCH_MAX_KEYS 136 + #define RARCH_FIRST_CUSTOM_BIND 16 #define RARCH_FIRST_LIGHTGUN_BIND RARCH_ANALOG_BIND_LIST_END #define RARCH_FIRST_MISC_CUSTOM_BIND RARCH_LIGHTGUN_BIND_LIST_END #define RARCH_FIRST_META_KEY RARCH_CUSTOM_BIND_LIST_END +#define RARCH_UNMAPPED 1024 + /* RetroArch specific bind IDs. */ enum { @@ -49,19 +53,19 @@ enum RARCH_ANALOG_RIGHT_Y_MINUS, RARCH_ANALOG_BIND_LIST_END, - /* Lightgun */ - RARCH_LIGHTGUN_TRIGGER = RARCH_FIRST_LIGHTGUN_BIND, - RARCH_LIGHTGUN_RELOAD, - RARCH_LIGHTGUN_AUX_A, - RARCH_LIGHTGUN_AUX_B, - RARCH_LIGHTGUN_AUX_C, - RARCH_LIGHTGUN_START, - RARCH_LIGHTGUN_SELECT, - RARCH_LIGHTGUN_DPAD_UP, - RARCH_LIGHTGUN_DPAD_DOWN, - RARCH_LIGHTGUN_DPAD_LEFT, - RARCH_LIGHTGUN_DPAD_RIGHT, - RARCH_LIGHTGUN_BIND_LIST_END, + /* Lightgun */ + RARCH_LIGHTGUN_TRIGGER = RARCH_FIRST_LIGHTGUN_BIND, + RARCH_LIGHTGUN_RELOAD, + RARCH_LIGHTGUN_AUX_A, + RARCH_LIGHTGUN_AUX_B, + RARCH_LIGHTGUN_AUX_C, + RARCH_LIGHTGUN_START, + RARCH_LIGHTGUN_SELECT, + RARCH_LIGHTGUN_DPAD_UP, + RARCH_LIGHTGUN_DPAD_DOWN, + RARCH_LIGHTGUN_DPAD_LEFT, + RARCH_LIGHTGUN_DPAD_RIGHT, + RARCH_LIGHTGUN_BIND_LIST_END, /* Turbo */ RARCH_TURBO_ENABLE = RARCH_FIRST_MISC_CUSTOM_BIND, @@ -103,6 +107,7 @@ enum RARCH_DISK_PREV, RARCH_GRAB_MOUSE_TOGGLE, RARCH_GAME_FOCUS_TOGGLE, + RARCH_UI_COMPANION_TOGGLE, RARCH_MENU_TOGGLE, diff --git a/input/input_driver.c b/input/input_driver.c index 14ed1c17a9..7eb6221aad 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -34,10 +34,12 @@ #include "input_remote.h" #endif -#ifdef HAVE_KEYMAPPER -#include "input_mapper.h" +#ifdef HAVE_OVERLAY +#include "input_overlay.h" #endif +#include "input_mapper.h" + #include "input_driver.h" #include "input_keymaps.h" #include "input_remapping.h" @@ -60,6 +62,22 @@ #include "../verbosity.h" #include "../tasks/tasks_internal.h" #include "../command.h" +#include "include/gamepad.h" + +static pad_connection_listener_t *pad_connection_listener = NULL; + +void set_connection_listener(pad_connection_listener_t *listener) +{ + pad_connection_listener = listener; +} + +void fire_connection_listener(unsigned port, input_device_driver_t *driver) +{ + if(!pad_connection_listener) + return; + + pad_connection_listener->connected(port, driver); +} static const input_driver_t *input_drivers[] = { #ifdef __CELLOS_LV2__ @@ -282,17 +300,17 @@ const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = { DECLARE_BIND(r_y_plus, RARCH_ANALOG_RIGHT_Y_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS), DECLARE_BIND(r_y_minus, RARCH_ANALOG_RIGHT_Y_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS), - DECLARE_BIND( gun_trigger, RARCH_LIGHTGUN_TRIGGER, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_TRIGGER ), - DECLARE_BIND( gun_offscreen_shot, RARCH_LIGHTGUN_RELOAD, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_RELOAD ), - DECLARE_BIND( gun_aux_a, RARCH_LIGHTGUN_AUX_A, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_A ), - DECLARE_BIND( gun_aux_b, RARCH_LIGHTGUN_AUX_B, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_B ), - DECLARE_BIND( gun_aux_c, RARCH_LIGHTGUN_AUX_C, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_C ), - DECLARE_BIND( gun_start, RARCH_LIGHTGUN_START, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_START ), - DECLARE_BIND( gun_select, RARCH_LIGHTGUN_SELECT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_SELECT ), - DECLARE_BIND( gun_dpad_up, RARCH_LIGHTGUN_DPAD_UP, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_UP ), - DECLARE_BIND( gun_dpad_down, RARCH_LIGHTGUN_DPAD_DOWN, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_DOWN ), - DECLARE_BIND( gun_dpad_left, RARCH_LIGHTGUN_DPAD_LEFT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT ), - DECLARE_BIND( gun_dpad_right, RARCH_LIGHTGUN_DPAD_RIGHT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT ), + DECLARE_BIND( gun_trigger, RARCH_LIGHTGUN_TRIGGER, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_TRIGGER ), + DECLARE_BIND( gun_offscreen_shot, RARCH_LIGHTGUN_RELOAD, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_RELOAD ), + DECLARE_BIND( gun_aux_a, RARCH_LIGHTGUN_AUX_A, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_A ), + DECLARE_BIND( gun_aux_b, RARCH_LIGHTGUN_AUX_B, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_B ), + DECLARE_BIND( gun_aux_c, RARCH_LIGHTGUN_AUX_C, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_C ), + DECLARE_BIND( gun_start, RARCH_LIGHTGUN_START, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_START ), + DECLARE_BIND( gun_select, RARCH_LIGHTGUN_SELECT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_SELECT ), + DECLARE_BIND( gun_dpad_up, RARCH_LIGHTGUN_DPAD_UP, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_UP ), + DECLARE_BIND( gun_dpad_down, RARCH_LIGHTGUN_DPAD_DOWN, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_DOWN ), + DECLARE_BIND( gun_dpad_left, RARCH_LIGHTGUN_DPAD_LEFT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT ), + DECLARE_BIND( gun_dpad_right, RARCH_LIGHTGUN_DPAD_RIGHT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT ), DECLARE_BIND(turbo, RARCH_TURBO_ENABLE, MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE), @@ -329,6 +347,7 @@ const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = { DECLARE_META_BIND(2, disk_prev, RARCH_DISK_PREV, MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV), DECLARE_META_BIND(2, grab_mouse_toggle, RARCH_GRAB_MOUSE_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE), DECLARE_META_BIND(2, game_focus_toggle, RARCH_GAME_FOCUS_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE), + DECLARE_META_BIND(2, desktop_menu_toggle, RARCH_UI_COMPANION_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE), #ifdef HAVE_MENU DECLARE_META_BIND(1, menu_toggle, RARCH_MENU_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE), #endif @@ -377,9 +396,7 @@ static command_t *input_driver_command = NULL; #ifdef HAVE_NETWORKGAMEPAD static input_remote_t *input_driver_remote = NULL; #endif -#ifdef HAVE_KEYMAPPER static input_mapper_t *input_driver_mapper = NULL; -#endif static const input_driver_t *current_input = NULL; static void *current_input_data = NULL; static bool input_driver_block_hotkey = false; @@ -579,6 +596,8 @@ void input_poll(void) if (input_driver_block_libretro_input) return; + + for (i = 0; i < max_users; i++) { if (libretro_input_binds[i][RARCH_TURBO_ENABLE].valid) @@ -603,6 +622,9 @@ void input_poll(void) input_driver_axis_threshold); #endif + if (settings->bools.input_remap_binds_enable && input_driver_mapper) + input_mapper_poll(input_driver_mapper); + #ifdef HAVE_COMMAND if (input_driver_command) command_poll(input_driver_command); @@ -612,11 +634,6 @@ void input_poll(void) if (input_driver_remote) input_remote_poll(input_driver_remote, max_users); #endif - -#ifdef HAVE_KEYMAPPER - if (input_driver_mapper) - input_mapper_poll(input_driver_mapper); -#endif } /** @@ -634,7 +651,11 @@ void input_poll(void) int16_t input_state(unsigned port, unsigned device, unsigned idx, unsigned id) { - int16_t res = 0; + int16_t res = 0, res_overlay = 0; + + /* used to reset input state of a button when the gamepad mapper + is in action for that button*/ + bool reset_state = false; device &= RETRO_DEVICE_MASK; @@ -657,22 +678,32 @@ int16_t input_state(unsigned port, unsigned device, switch (device) { case RETRO_DEVICE_JOYPAD: - if (id < RARCH_FIRST_CUSTOM_BIND) - id = settings->uints.input_remap_ids[port][id]; + if (id != settings->uints.input_remap_ids[port][id]) + reset_state = true; break; case RETRO_DEVICE_ANALOG: if (idx < 2 && id < 2) { - unsigned new_id = RARCH_FIRST_CUSTOM_BIND + (idx * 2 + id); - - new_id = settings->uints.input_remap_ids[port][new_id]; - idx = (new_id & 2) >> 1; - id = new_id & 1; + unsigned offset = RARCH_FIRST_CUSTOM_BIND + (idx * 4) + (id * 2); + if (settings->uints.input_remap_ids[port][offset] != offset) + reset_state = true; + if (settings->uints.input_remap_ids[port][offset+1] != (offset+1)) + reset_state = true; } break; } } +#ifdef HAVE_OVERLAY + if (overlay_ptr) + input_state_overlay(overlay_ptr, &res_overlay, port, device, idx, id); +#endif + +#ifdef HAVE_NETWORKGAMEPAD + if (input_driver_remote) + input_remote_state(&res, port, device, idx, id); +#endif + if (((id < RARCH_FIRST_META_KEY) || (device == RETRO_DEVICE_KEYBOARD))) { bool bind_valid = libretro_input_binds[port] && libretro_input_binds[port][id].valid; @@ -680,31 +711,30 @@ int16_t input_state(unsigned port, unsigned device, if (bind_valid || device == RETRO_DEVICE_KEYBOARD) { rarch_joypad_info_t joypad_info; - joypad_info.axis_threshold = input_driver_axis_threshold; joypad_info.joy_idx = settings->uints.input_joypad_map[port]; joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx]; - res = current_input->input_state( - current_input_data, joypad_info, libretro_input_binds, port, device, idx, id); + if (!reset_state) + { + res = current_input->input_state( + current_input_data, joypad_info, libretro_input_binds, port, device, idx, id); + +#ifdef HAVE_OVERLAY + if (input_overlay_is_alive(overlay_ptr) && port == 0) + res |= res_overlay; +#endif + } + else + res = 0; } } -#ifdef HAVE_OVERLAY - if (overlay_ptr) - input_state_overlay(overlay_ptr, &res, port, device, idx, id); -#endif - -#ifdef HAVE_NETWORKGAMEPAD - if (input_driver_remote) - input_remote_state(&res, port, device, idx, id); -#endif - -#ifdef HAVE_KEYMAPPER - if (input_driver_mapper) + if (settings->bools.input_remap_binds_enable && input_driver_mapper) input_mapper_state(input_driver_mapper, &res, port, device, idx, id); -#endif + + /* Don't allow turbo for D-pad. */ if (device == RETRO_DEVICE_JOYPAD && (id < RETRO_DEVICE_ID_JOYPAD_UP || @@ -805,7 +835,7 @@ void state_tracker_update_input(uint16_t *input1, uint16_t *input2) } static INLINE bool input_keys_pressed_iterate(unsigned i, - retro_bits_t* p_new_state) + input_bits_t* p_new_state) { if ((i >= RARCH_FIRST_META_KEY) && BIT64_GET(lifecycle_state, i) @@ -850,14 +880,12 @@ static INLINE bool input_keys_pressed_iterate(unsigned i, * * Returns: Input sample containing a mask of all pressed keys. */ -void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) +void input_menu_keys_pressed(void *data, input_bits_t *p_new_state) { unsigned i, port; rarch_joypad_info_t joypad_info; const struct retro_keybind *binds[MAX_USERS] = {NULL}; settings_t *settings = (settings_t*)data; - const struct retro_keybind *binds_norm = NULL; - const struct retro_keybind *binds_auto = NULL; uint8_t max_users = (uint8_t)input_driver_max_users; uint8_t port_max = settings->bools.input_all_users_control_menu @@ -866,8 +894,6 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) joypad_info.joy_idx = 0; joypad_info.auto_binds = NULL; - BIT256_CLEAR_ALL_PTR(p_new_state); - input_driver_block_libretro_input = false; input_driver_block_hotkey = false; @@ -885,8 +911,8 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) for (port = 0; port < port_max; port++) { - binds_norm = &input_config_binds[port][RARCH_ENABLE_HOTKEY]; - binds_auto = &input_autoconf_binds[port][RARCH_ENABLE_HOTKEY]; + const struct retro_keybind *binds_norm = &input_config_binds[port][RARCH_ENABLE_HOTKEY]; + const struct retro_keybind *binds_auto = &input_autoconf_binds[port][RARCH_ENABLE_HOTKEY]; if (check_input_driver_block_hotkey(binds_norm, binds_auto)) { @@ -972,7 +998,10 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) } } - if (bit_pressed || input_keys_pressed_iterate(i, p_new_state)) + if (!bit_pressed) + bit_pressed = input_keys_pressed_iterate(i, p_new_state); + + if (bit_pressed) { BIT256_SET_PTR(p_new_state, i); } @@ -986,9 +1015,10 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) if (!menu_input_dialog_get_display_kb()) { - unsigned ids[14][2]; + unsigned ids[15][2]; const struct retro_keybind *quitkey = &input_config_binds[0][RARCH_QUIT_KEY]; const struct retro_keybind *fskey = &input_config_binds[0][RARCH_FULLSCREEN_TOGGLE_KEY]; + const struct retro_keybind *companionkey = &input_config_binds[0][RARCH_UI_COMPANION_TOGGLE]; ids[0][0] = RETROK_SPACE; ids[0][1] = RETRO_DEVICE_ID_JOYPAD_START; @@ -1018,6 +1048,8 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) ids[12][1] = RETRO_DEVICE_ID_JOYPAD_A; ids[13][0] = RETROK_DELETE; ids[13][1] = RETRO_DEVICE_ID_JOYPAD_Y; + ids[14][0] = companionkey->key; + ids[14][1] = RARCH_UI_COMPANION_TOGGLE; if (settings->bools.input_menu_swap_ok_cancel_buttons) { @@ -1025,7 +1057,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) ids[12][1] = RETRO_DEVICE_ID_JOYPAD_B; } - for (i = 0; i < 14; i++) + for (i = 0; i < 15; i++) { if (current_input->input_state(current_input_data, joypad_info, binds, 0, @@ -1055,7 +1087,7 @@ int16_t input_driver_input_state( * * Returns: Input sample containing a mask of all pressed keys. */ -void input_keys_pressed(void *data, retro_bits_t* p_new_state) +void input_keys_pressed(void *data, input_bits_t *p_new_state) { unsigned i; rarch_joypad_info_t joypad_info; @@ -1064,13 +1096,6 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) const struct retro_keybind *binds_auto = &input_autoconf_binds[0][RARCH_ENABLE_HOTKEY]; const struct retro_keybind *binds_norm = &binds[RARCH_ENABLE_HOTKEY]; - const struct retro_keybind *focus_binds_auto = &input_autoconf_binds[0][RARCH_GAME_FOCUS_TOGGLE]; - const struct retro_keybind *focus_normal = &binds[RARCH_GAME_FOCUS_TOGGLE]; - const struct retro_keybind *enable_hotkey = &input_config_binds[0][RARCH_ENABLE_HOTKEY]; - bool game_focus_toggle_valid = false; - - BIT256_CLEAR_ALL_PTR(p_new_state); - joypad_info.joy_idx = settings->uints.input_joypad_map[0]; joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx]; joypad_info.axis_threshold = input_driver_axis_threshold; @@ -1084,7 +1109,10 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) if (check_input_driver_block_hotkey(binds_norm, binds_auto)) { - if ( enable_hotkey->valid + const struct retro_keybind *enable_hotkey = + &input_config_binds[0][RARCH_ENABLE_HOTKEY]; + + if ( enable_hotkey && enable_hotkey->valid && current_input->input_state( current_input_data, joypad_info, &binds, 0, RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY)) @@ -1093,16 +1121,22 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) input_driver_block_hotkey = true; } - game_focus_toggle_valid = binds[RARCH_GAME_FOCUS_TOGGLE].valid; - - /* Allows rarch_focus_toggle hotkey to still work - * even though every hotkey is blocked */ - if (check_input_driver_block_hotkey( - focus_normal, focus_binds_auto) && game_focus_toggle_valid) + if (binds[RARCH_GAME_FOCUS_TOGGLE].valid) { - if (current_input->input_state(current_input_data, joypad_info, &binds, 0, - RETRO_DEVICE_JOYPAD, 0, RARCH_GAME_FOCUS_TOGGLE)) - input_driver_block_hotkey = false; + const struct retro_keybind *focus_binds_auto = + &input_autoconf_binds[0][RARCH_GAME_FOCUS_TOGGLE]; + const struct retro_keybind *focus_normal = + &binds[RARCH_GAME_FOCUS_TOGGLE]; + + /* Allows rarch_focus_toggle hotkey to still work + * even though every hotkey is blocked */ + if (check_input_driver_block_hotkey( + focus_normal, focus_binds_auto)) + { + if (current_input->input_state(current_input_data, joypad_info, &binds, 0, + RETRO_DEVICE_JOYPAD, 0, RARCH_GAME_FOCUS_TOGGLE)) + input_driver_block_hotkey = false; + } } for (i = 0; i < RARCH_BIND_LIST_END; i++) @@ -1117,14 +1151,55 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) 0, RETRO_DEVICE_JOYPAD, 0, i) ) bit_pressed = true; + else if (input_keys_pressed_iterate(i, p_new_state)) + bit_pressed = true; - if (bit_pressed || input_keys_pressed_iterate(i, p_new_state)) + if (bit_pressed) { BIT256_SET_PTR(p_new_state, i); } } } +void input_get_state_for_port(void *data, unsigned port, input_bits_t *p_new_state) +{ + unsigned i, j; + rarch_joypad_info_t joypad_info; + settings_t *settings = (settings_t*)data; + const input_device_driver_t *joypad_driver = input_driver_get_joypad_driver(); + + joypad_info.joy_idx = settings->uints.input_joypad_map[port]; + joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx]; + joypad_info.axis_threshold = input_driver_axis_threshold; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + bool bit_pressed = false; + + if (input_driver_input_state(joypad_info, libretro_input_binds, + port, RETRO_DEVICE_JOYPAD, 0, i) != 0) + bit_pressed = true; + + if (bit_pressed) + BIT256_SET_PTR(p_new_state, i); + } + + for (i = 0; i < 2; i++) + { + for (j = 0; j < 2; j++) + { + unsigned offset = 0 + (i * 4) + (j * 2); + int16_t val = input_joypad_analog(joypad_driver, + joypad_info, port, i, j, libretro_input_binds[port]); + + if (val >= 0) + p_new_state->analogs[offset] = val; + else + p_new_state->analogs[offset+1] = val; + } + } +} + void *input_driver_get_data(void) { return current_input_data; @@ -1343,11 +1418,9 @@ void input_driver_deinit_remote(void) void input_driver_deinit_mapper(void) { -#ifdef HAVE_KEYMAPPER if (input_driver_mapper) input_mapper_free(input_driver_mapper); input_driver_mapper = NULL; -#endif } bool input_driver_init_remote(void) @@ -1372,20 +1445,17 @@ bool input_driver_init_remote(void) bool input_driver_init_mapper(void) { -#ifdef HAVE_KEYMAPPER settings_t *settings = config_get_ptr(); - if (!settings->bools.keymapper_enable) + if (!settings->bools.input_remap_binds_enable) return false; - input_driver_mapper = input_mapper_new( - settings->uints.keymapper_port); + input_driver_mapper = input_mapper_new(); if (input_driver_mapper) return true; RARCH_ERR("Failed to initialize input mapper.\n"); -#endif return false; } @@ -1782,6 +1852,21 @@ bool input_mouse_button_raw(unsigned port, unsigned id) return false; } +void input_pad_connect(unsigned port, input_device_driver_t *driver) +{ + if(port >= MAX_USERS || !driver) + { + RARCH_ERR("[input]: input_pad_connect: bad parameters\n"); + return; + } + + fire_connection_listener(port, driver); + + if(!input_autoconfigure_connect(driver->name(port), NULL, driver->ident, + port, 0, 0)) + input_config_set_device_name(port, driver->name(port)); +} + /** * input_conv_analog_id_to_bind_id: * @idx : Analog key index. @@ -2536,7 +2621,7 @@ static void input_config_get_bind_string_joykey( { if (bind->joykey_label && !string_is_empty(bind->joykey_label) && label_show) - snprintf(buf, size, "%s %s ", prefix, bind->joykey_label); + snprintf(buf, size, "%s %s (hat)", prefix, bind->joykey_label); else { const char *dir = "?"; @@ -2693,9 +2778,9 @@ unsigned input_config_get_device_count() unsigned num_devices; for ( num_devices = 0; num_devices < MAX_INPUT_DEVICES; ++num_devices ) { - const char *device_name = input_config_get_device_name(num_devices); - if ( string_is_empty(device_name) ) - break; + const char *device_name = input_config_get_device_name(num_devices); + if ( string_is_empty(device_name) ) + break; } return num_devices; } @@ -2729,7 +2814,7 @@ void input_config_set_device_name(unsigned port, const char *name) name, sizeof(input_device_names[port])); - input_autoconfigure_joypad_reindex_devices(); + input_autoconfigure_joypad_reindex_devices(); } } diff --git a/input/input_driver.h b/input/input_driver.h index 2ef47c7d24..f47e8830eb 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -22,6 +22,8 @@ #include #include +#include "input_types.h" + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -35,16 +37,12 @@ #include "input_defines.h" #include "../msg_hash.h" +#include "include/hid_types.h" +#include "include/hid_driver.h" +#include "include/gamepad.h" RETRO_BEGIN_DECLS -typedef struct rarch_joypad_driver input_device_driver_t; - -typedef struct hid_driver hid_driver_t; - -/* Keyboard line reader. Handles textual input in a direct fashion. */ -typedef struct input_keyboard_line input_keyboard_line_t; - enum input_device_type { INPUT_DEVICE_TYPE_NONE = 0, @@ -121,14 +119,14 @@ struct retro_keybind char *joyaxis_label; }; -typedef struct rarch_joypad_info +struct rarch_joypad_info { uint16_t joy_idx; const struct retro_keybind *auto_binds; float axis_threshold; -} rarch_joypad_info_t; +}; -typedef struct input_driver +struct input_driver { /* Inits input driver. */ @@ -164,7 +162,7 @@ typedef struct input_driver const input_device_driver_t *(*get_sec_joypad_driver)(void *data); bool (*keyboard_mapping_is_blocked)(void *data); void (*keyboard_mapping_set_block)(void *data, bool value); -} input_driver_t; +}; struct rarch_joypad_driver { @@ -172,7 +170,7 @@ struct rarch_joypad_driver bool (*query_pad)(unsigned); void (*destroy)(void); bool (*button)(unsigned, uint16_t); - void (*get_buttons)(unsigned, retro_bits_t *); + void (*get_buttons)(unsigned, input_bits_t *); int16_t (*axis)(unsigned, uint32_t); void (*poll)(void); bool (*set_rumble)(unsigned, enum retro_rumble_effect, uint16_t); @@ -181,25 +179,6 @@ struct rarch_joypad_driver const char *ident; }; -struct hid_driver -{ - void *(*init)(void); - bool (*query_pad)(void *, unsigned); - void (*free)(const void *); - bool (*button)(void *, unsigned, uint16_t); - void (*get_buttons)(void *, unsigned, retro_bits_t *); - int16_t (*axis)(void *, unsigned, uint32_t); - void (*poll)(void *); - bool (*set_rumble)(void *, unsigned, enum retro_rumble_effect, uint16_t); - const char *(*name)(void *, unsigned); - const char *ident; - void (*send_control)(void *data, uint8_t *buf, size_t size); - int32_t (*set_report)(void *, uint8_t, uint8_t, void *, uint32_t); - int32_t (*set_idle)(void *, uint8_t); - int32_t (*set_protocol)(void *, uint8_t); - -}; - /** * input_driver_find_handle: * @index : index of driver to get handle to. @@ -335,14 +314,16 @@ void input_poll(void); int16_t input_state(unsigned port, unsigned device, unsigned idx, unsigned id); -void input_keys_pressed(void *data, retro_bits_t* new_state); +void input_keys_pressed(void *data, input_bits_t* new_state); #ifdef HAVE_MENU -void input_menu_keys_pressed(void *data, retro_bits_t* new_state); +void input_menu_keys_pressed(void *data, input_bits_t* new_state); #endif void *input_driver_get_data(void); +void input_get_state_for_port(void *data, unsigned port, input_bits_t *p_new_state); + const input_driver_t *input_get_ptr(void); void *input_get_data(void); @@ -591,6 +572,15 @@ bool input_joypad_button_raw(const input_device_driver_t *driver, bool input_joypad_hat_raw(const input_device_driver_t *driver, unsigned joypad, unsigned hat_dir, unsigned hat); +/** + * input_pad_connect: + * @port : Joystick number. + * @driver : handle for joypad driver handling joystick's input + * + * Registers a newly connected pad with RetroArch. + **/ +void input_pad_connect(unsigned port, input_device_driver_t *driver); + /** * input_mouse_button_raw: * @port : Mouse number. @@ -619,6 +609,9 @@ const char *input_joypad_name(const input_device_driver_t *driver, bool input_config_get_bind_idx(unsigned port, unsigned *joy_idx_real); #ifdef HAVE_HID + +#include "include/hid_driver.h" + /** * hid_driver_find_handle: * @index : index of driver to get handle to. @@ -668,11 +661,11 @@ typedef void (*input_keyboard_line_complete_t)(void *userdata, typedef bool (*input_keyboard_press_t)(void *userdata, unsigned code); -typedef struct input_keyboard_ctx_wait +struct input_keyboard_ctx_wait { void *userdata; input_keyboard_press_t cb; -} input_keyboard_ctx_wait_t; +}; /** * input_keyboard_event: @@ -800,6 +793,9 @@ uint16_t input_config_get_vid(unsigned port); void input_config_reset(void); +void set_connection_listener(pad_connection_listener_t *listener); +void fire_connection_listener(unsigned port, input_device_driver_t *driver); + extern input_device_driver_t dinput_joypad; extern input_device_driver_t linuxraw_joypad; extern input_device_driver_t parport_joypad; @@ -848,7 +844,6 @@ extern hid_driver_t iohidmanager_hid; extern hid_driver_t btstack_hid; extern hid_driver_t libusb_hid; extern hid_driver_t wiiusb_hid; -extern hid_driver_t wiiu_hid; extern hid_driver_t null_hid; #endif diff --git a/input/input_mapper.c b/input/input_mapper.c index 2b58e9b701..f42c804160 100644 --- a/input/input_mapper.c +++ b/input/input_mapper.c @@ -41,6 +41,10 @@ #include "input_mapper.h" +#ifdef HAVE_OVERLAY +#include "input_overlay.h" +#endif + #include "../configuration.h" #include "../msg_hash.h" #include "../verbosity.h" @@ -50,17 +54,20 @@ struct input_mapper { - /* The controller port that will be polled*/ - uint8_t port; /* Left X, Left Y, Right X, Right Y */ - int16_t analog[4]; + int16_t analog_value[MAX_USERS][8]; /* the whole keyboard state */ uint32_t keys[RETROK_LAST / 32 + 1]; /* This is a bitmask of (1 << key_bind_id). */ - uint64_t buttons; + input_bits_t buttons[MAX_USERS]; }; -input_mapper_t *input_mapper_new(uint16_t port) +static bool input_mapper_button_pressed(input_mapper_t *handle, unsigned port, unsigned id) +{ + return BIT256_GET(handle->buttons[port], id); +} + +input_mapper_t *input_mapper_new(void) { input_mapper_t* handle = (input_mapper_t*) calloc(1, sizeof(*handle)); @@ -68,8 +75,6 @@ input_mapper_t *input_mapper_new(uint16_t port) if (!handle) return NULL; - handle->port = port; - return handle; } @@ -82,41 +87,159 @@ void input_mapper_free(input_mapper_t *handle) void input_mapper_poll(input_mapper_t *handle) { - int i; - settings_t *settings = config_get_ptr(); - unsigned device = settings->uints.input_libretro_device[handle->port]; -#ifdef HAVE_MENU - bool menu_is_alive = menu_driver_is_alive(); + unsigned i, j; + input_bits_t current_input; + settings_t *settings = config_get_ptr(); + unsigned max_users = + *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); + bool key_event[RARCH_CUSTOM_BIND_LIST_END] = { false }; +#ifdef HAVE_OVERLAY + bool poll_overlay = input_overlay_is_alive(overlay_ptr) ? true : false; #endif - device &= RETRO_DEVICE_MASK; - - /* for now we only handle keyboard inputs */ - if (device != RETRO_DEVICE_KEYBOARD) - return; #ifdef HAVE_MENU - if (menu_is_alive) + if (menu_driver_is_alive()) return; #endif memset(handle->keys, 0, sizeof(handle->keys)); - for (i = 0; i < RARCH_CUSTOM_BIND_LIST_END; i++) + for (i = 0; i < max_users; i++) { - if (i < RETROK_LAST) + unsigned device = settings->uints.input_libretro_device[i]; + device &= RETRO_DEVICE_MASK; + + switch (device) { - if (input_state(handle->port, RETRO_DEVICE_JOYPAD, 0, i)) - { - MAPPER_SET_KEY (handle, - settings->uints.input_keymapper_ids[i]); - input_keyboard_event(true, - settings->uints.input_keymapper_ids[i], - 0, 0, RETRO_DEVICE_KEYBOARD); - } - else - input_keyboard_event(false, - settings->uints.input_keymapper_ids[i], - 0, 0, RETRO_DEVICE_KEYBOARD); + /* keyboard to gamepad remapping */ + case RETRO_DEVICE_KEYBOARD: + BIT256_CLEAR_ALL_PTR(¤t_input); + input_get_state_for_port(settings, i, ¤t_input); + for (j = 0; j < RARCH_CUSTOM_BIND_LIST_END; j++) + { + unsigned remap_button = + settings->uints.input_keymapper_ids[i][j]; + bool remap_valid = remap_button != RETROK_UNKNOWN; + + if (remap_valid) + { + unsigned current_button_value = BIT256_GET(current_input, j); + + if ((current_button_value == 1) && (j != remap_button)) + { + MAPPER_SET_KEY (handle, + remap_button); + input_keyboard_event(true, + remap_button, + 0, 0, RETRO_DEVICE_KEYBOARD); + key_event[j] = true; + } + /* key_event tracks if a key is pressed for ANY PLAYER, so we must check + if the key was used by any player before releasing */ + else if (!key_event[j]) + { + input_keyboard_event(false, + remap_button, + 0, 0, RETRO_DEVICE_KEYBOARD); + } + } + } + break; + + /* gamepad remapping */ + case RETRO_DEVICE_JOYPAD: + case RETRO_DEVICE_ANALOG: + /* this loop iterates on all users and all buttons, + * and checks if a pressed button is assigned to any + * other button than the default one, then it sets + * the bit on the mapper input bitmap, later on the + * original input is cleared in input_state */ + BIT256_CLEAR_ALL(handle->buttons[i]); + BIT256_CLEAR_ALL_PTR(¤t_input); + + for (j = 0; j < 8; j++) + handle->analog_value[i][j] = 0; + + input_get_state_for_port(settings, i, ¤t_input); + + for (j = 0; j < RARCH_FIRST_CUSTOM_BIND; j++) + { + bool remap_valid; + unsigned remap_button; + unsigned current_button_value = BIT256_GET(current_input, j); +#ifdef HAVE_OVERLAY + if (poll_overlay && i == 0) + current_button_value |= input_overlay_key_pressed(overlay_ptr, j); +#endif + + remap_button = + settings->uints.input_remap_ids[i][j]; + remap_valid = (current_button_value == 1) && + (j != remap_button) && (remap_button != RARCH_UNMAPPED); + + if (remap_valid) + { + if (remap_button < RARCH_FIRST_CUSTOM_BIND) + { + BIT256_SET(handle->buttons[i], remap_button); + } + else if (remap_button >= RARCH_FIRST_CUSTOM_BIND) + { + int invert = 1; + + if (remap_button % 2 != 0) + invert = -1; + + handle->analog_value[i][ + remap_button - RARCH_FIRST_CUSTOM_BIND] = + 32767 * invert; + } + } + } + + for (j = 0; j < 8; j++) + { + unsigned k = j + RARCH_FIRST_CUSTOM_BIND; + int16_t current_axis_value = current_input.analogs[j]; + unsigned remap_axis = + settings->uints.input_remap_ids[i][k]; + + if ( + (abs(current_axis_value) > + *input_driver_get_float(INPUT_ACTION_AXIS_THRESHOLD) * 32767) && + (k != remap_axis) && + (remap_axis != RARCH_UNMAPPED) + ) + { + if (remap_axis < RARCH_FIRST_CUSTOM_BIND) + { + BIT256_SET(handle->buttons[i], remap_axis); + } + else + { + int invert = 1; + + if ( (k % 2 == 0 && remap_axis % 2 != 0) || + (k % 2 != 0 && remap_axis % 2 == 0) + ) + invert = -1; + + handle->analog_value[i][ + remap_axis - RARCH_FIRST_CUSTOM_BIND] = + current_axis_value * invert; +#if 0 + RARCH_LOG("axis %d(%d) remapped to axis %d val %d\n", + j, k, + remap_axis - RARCH_FIRST_CUSTOM_BIND, + current_axis_value); +#endif + } + } + + } + break; + default: + break; } } } @@ -134,22 +257,34 @@ void input_mapper_state( switch (device) { + case RETRO_DEVICE_JOYPAD: + if (input_mapper_button_pressed(handle, port, id)) + *ret = 1; + break; + case RETRO_DEVICE_ANALOG: + if (idx < 2 && id < 2) + { + int val = 0; + unsigned offset = 0 + (idx * 4) + (id * 2); + int val1 = handle->analog_value[port][offset]; + int val2 = handle->analog_value[port][offset+1]; + + if (val1) + val = val1; + else if (val2) + val = val2; + + if (val1 || val2) + *ret |= val; + } + break; case RETRO_DEVICE_KEYBOARD: if (id < RETROK_LAST) - { - /* - RARCH_LOG("State: UDLR %u %u %u %u\n", - MAPPER_GET_KEY(handle, RETROK_UP), - MAPPER_GET_KEY(handle, RETROK_DOWN), - MAPPER_GET_KEY(handle, RETROK_LEFT), - MAPPER_GET_KEY(handle, RETROK_RIGHT) - );*/ - if (MAPPER_GET_KEY(handle, id)) *ret |= 1; - } break; default: break; } + return; } diff --git a/input/input_mapper.h b/input/input_mapper.h index c50519acd8..21741d008e 100644 --- a/input/input_mapper.h +++ b/input/input_mapper.h @@ -31,13 +31,13 @@ RETRO_BEGIN_DECLS typedef struct input_mapper input_mapper_t; -input_mapper_t *input_mapper_new(uint16_t port); +input_mapper_t *input_mapper_new(void); void input_mapper_free(input_mapper_t *handle); void input_mapper_poll(input_mapper_t *handle); -bool input_mapper_key_pressed(int key); +bool input_mapper_key_pressed(input_mapper_t *handle, int key); void input_mapper_state( input_mapper_t *handle, diff --git a/input/input_overlay.c b/input/input_overlay.c index 9eac1e8012..858457cf76 100644 --- a/input/input_overlay.c +++ b/input/input_overlay.c @@ -46,7 +46,7 @@ typedef struct input_overlay_state int16_t analog[4]; uint32_t keys[RETROK_LAST / 32 + 1]; /* This is a bitmask of (1 << key_bind_id). */ - retro_bits_t buttons; + input_bits_t buttons; } input_overlay_state_t; struct input_overlay @@ -72,8 +72,117 @@ struct input_overlay input_overlay_t *overlay_ptr = NULL; +/** + * input_overlay_add_inputs: + * @ol : pointer to overlay + * @port : the user to show the inputs of + * + * Adds inputs from current_input to the overlay, so it's displayed + * returns true if an input that is pressed will change the overlay + */ +static bool input_overlay_add_inputs_inner(overlay_desc_t *desc, + unsigned port, unsigned analog_dpad_mode) +{ + switch(desc->type) + { + case OVERLAY_TYPE_BUTTONS: + { + unsigned i; + bool all_buttons_pressed = false; + + /*Check each bank of the mask*/ + for (i = 0; i < ARRAY_SIZE(desc->button_mask.data); ++i) + { + /*Get bank*/ + uint32_t bank_mask = BITS_GET_ELEM(desc->button_mask,i); + unsigned id = i * 32; + + /*Worth pursuing? Have we got any bits left in here?*/ + while (bank_mask) + { + /*If this bit is set then we need to query the pad + *The button must be pressed.*/ + if (bank_mask & 1) + { + /* Light up the button if pressed */ + if (!input_state(port, RETRO_DEVICE_JOYPAD, 0, id)) + { + /* We need ALL of the inputs to be active, + * abort. */ + desc->updated = false; + return false; + } + + all_buttons_pressed = true; + desc->updated = true; + } + + bank_mask >>= 1; + ++id; + } + } + + return all_buttons_pressed; + } + + case OVERLAY_TYPE_ANALOG_LEFT: + case OVERLAY_TYPE_ANALOG_RIGHT: + { + unsigned int index = (desc->type == OVERLAY_TYPE_ANALOG_RIGHT) ? + RETRO_DEVICE_INDEX_ANALOG_RIGHT : RETRO_DEVICE_INDEX_ANALOG_LEFT; + + float analog_x = input_state(port, RETRO_DEVICE_ANALOG, + index, RETRO_DEVICE_ID_ANALOG_X); + float analog_y = input_state(port, RETRO_DEVICE_ANALOG, + index, RETRO_DEVICE_ID_ANALOG_Y); + float dx = (analog_x/0x8000)*(desc->range_x/2); + float dy = (analog_y/0x8000)*(desc->range_y/2); + + desc->delta_x = dx; + desc->delta_y = dy; + + /*Maybe use some option here instead of 0, only display + changes greater than some magnitude. + */ + if ((dx * dx) > 0 || (dy*dy) > 0) + return true; + } + break; + + case OVERLAY_TYPE_KEYBOARD: + if (input_state(port, RETRO_DEVICE_KEYBOARD, 0, desc->retro_key_idx)) + { + desc->updated = true; + return true; + } + break; + + default: + break; + } + + return false; +} + static bool input_overlay_add_inputs(input_overlay_t *ol, - unsigned port, unsigned analog_dpad_mode); + unsigned port, unsigned analog_dpad_mode) +{ + unsigned i; + bool button_pressed = false; + input_overlay_state_t *ol_state = &ol->overlay_state; + + if (!ol_state) + return false; + + for (i = 0; i < ol->active->size; i++) + { + overlay_desc_t *desc = &(ol->active->descs[i]); + button_pressed |= input_overlay_add_inputs_inner(desc, + port, analog_dpad_mode); + } + + return button_pressed; +} /** * input_overlay_scale: * @ol : Overlay handle. @@ -234,7 +343,8 @@ static void input_overlay_enable(input_overlay_t *ol, bool enable) * Check whether the given @x and @y coordinates of the overlay * descriptor @desc is inside the overlay descriptor's hitbox. * - * Returns: true (1) if X, Y coordinates are inside a hitbox, otherwise false (0). + * Returns: true (1) if X, Y coordinates are inside a hitbox, + * otherwise false (0). **/ static bool inside_hitbox(const struct overlay_desc *desc, float x, float y) { @@ -305,7 +415,9 @@ static void input_overlay_poll( { case OVERLAY_TYPE_BUTTONS: { - bits_or_bits(out->buttons.data, desc->button_mask.data, ARRAY_SIZE(desc->button_mask.data)); + bits_or_bits(out->buttons.data, + desc->button_mask.data, + ARRAY_SIZE(desc->button_mask.data)); if (BIT256_GET(desc->button_mask, RARCH_OVERLAY_NEXT)) ol->next_index = desc->next_index; @@ -317,15 +429,19 @@ static void input_overlay_poll( break; default: { - float x_val = x_dist / desc->range_x; - float y_val = y_dist / desc->range_y; - float x_val_sat = x_val / desc->analog_saturate_pct; - float y_val_sat = y_val / desc->analog_saturate_pct; + float x_val = x_dist / desc->range_x; + float y_val = y_dist / desc->range_y; + float x_val_sat = x_val / desc->analog_saturate_pct; + float y_val_sat = y_val / desc->analog_saturate_pct; - unsigned int base = (desc->type == OVERLAY_TYPE_ANALOG_RIGHT) ? 2 : 0; + unsigned int base = + (desc->type == OVERLAY_TYPE_ANALOG_RIGHT) + ? 2 : 0; - out->analog[base + 0] = clamp_float(x_val_sat, -1.0f, 1.0f) * 32767.0f; - out->analog[base + 1] = clamp_float(y_val_sat, -1.0f, 1.0f) * 32767.0f; + out->analog[base + 0] = clamp_float(x_val_sat, -1.0f, 1.0f) + * 32767.0f; + out->analog[base + 1] = clamp_float(y_val_sat, -1.0f, 1.0f) + * 32767.0f; } break; } @@ -498,9 +614,12 @@ void input_overlay_loaded(void *task_data, void *user_data, const char *err) } #endif - if (!data->overlay_enable || !video_driver_overlay_interface(&iface) || !iface) + if ( !data->overlay_enable || + !video_driver_overlay_interface(&iface) || + !iface) { - RARCH_ERR("Overlay interface is not present in video driver, or not enabled.\n"); + RARCH_ERR("Overlay interface is not present in video driver," + " or not enabled.\n"); goto abort_load; } @@ -532,37 +651,42 @@ abort_load: free(data); } -void input_overlay_set_visibility(int overlay_idx,enum overlay_visibility vis) +void input_overlay_set_visibility(int overlay_idx, + enum overlay_visibility vis) { - int i; input_overlay_t *ol = overlay_ptr; - if(visibility == NULL) + if (!visibility) { - visibility = (enum overlay_visibility *)calloc(MAX_VISIBILITY,sizeof(enum overlay_visibility)); - for(i=0;iiface->set_alpha(ol->iface_data, overlay_idx, 0.0); } static enum overlay_visibility input_overlay_get_visibility(int overlay_idx) { - if(visibility == NULL) return OVERLAY_VISIBILITY_DEFAULT; - if((overlay_idx < 0) || (overlay_idx >= MAX_VISIBILITY)) return OVERLAY_VISIBILITY_DEFAULT; + if (!visibility) + return OVERLAY_VISIBILITY_DEFAULT; + if ((overlay_idx < 0) || (overlay_idx >= MAX_VISIBILITY)) + return OVERLAY_VISIBILITY_DEFAULT; return visibility[overlay_idx]; } static bool input_overlay_is_hidden(int overlay_idx) { - return (input_overlay_get_visibility(overlay_idx) == OVERLAY_VISIBILITY_HIDDEN); + return (input_overlay_get_visibility(overlay_idx) + == OVERLAY_VISIBILITY_HIDDEN); } /** @@ -582,7 +706,7 @@ void input_overlay_set_alpha_mod(input_overlay_t *ol, float mod) for (i = 0; i < ol->active->load_images_size; i++) { - if(input_overlay_is_hidden(i)) + if (input_overlay_is_hidden(i)) ol->iface->set_alpha(ol->iface_data, i, 0.0); else ol->iface->set_alpha(ol->iface_data, i, mod); @@ -609,7 +733,8 @@ bool input_overlay_key_pressed(input_overlay_t *ol, unsigned key) * * Poll pressed buttons/keys on currently active overlay. **/ -void input_poll_overlay(input_overlay_t *ol, float opacity, unsigned analog_dpad_mode, +void input_poll_overlay(input_overlay_t *ol, float opacity, + unsigned analog_dpad_mode, float axis_threshold) { rarch_joypad_info_t joypad_info; @@ -658,7 +783,9 @@ void input_poll_overlay(input_overlay_t *ol, float opacity, unsigned analog_dpad else ol->blocked = false; - bits_or_bits(ol_state->buttons.data, polled_data.buttons.data, ARRAY_SIZE(polled_data.buttons.data)); + bits_or_bits(ol_state->buttons.data, + polled_data.buttons.data, + ARRAY_SIZE(polled_data.buttons.data)); for (j = 0; j < ARRAY_SIZE(ol_state->keys); j++) ol_state->keys[j] |= polled_data.keys[j]; @@ -749,10 +876,11 @@ void input_poll_overlay(input_overlay_t *ol, float opacity, unsigned analog_dpad break; } - if(settings->bools.input_overlay_show_physical_inputs) - { - button_pressed = input_overlay_add_inputs(ol, settings->uints.input_overlay_show_physical_inputs_port, analog_dpad_mode); - } + if (settings->bools.input_overlay_show_physical_inputs) + button_pressed = input_overlay_add_inputs(ol, + settings->uints.input_overlay_show_physical_inputs_port, + analog_dpad_mode); + if (button_pressed || polled) input_overlay_post_poll(ol, opacity); else @@ -777,12 +905,14 @@ void input_state_overlay(input_overlay_t *ol, int16_t *ret, case RETRO_DEVICE_KEYBOARD: if (id < RETROK_LAST) { - /*RARCH_LOG("UDLR %u %u %u %u\n", - OVERLAY_GET_KEY(ol_state, RETROK_UP), - OVERLAY_GET_KEY(ol_state, RETROK_DOWN), - OVERLAY_GET_KEY(ol_state, RETROK_LEFT), - OVERLAY_GET_KEY(ol_state, RETROK_RIGHT) - );*/ +#if 0 + RARCH_LOG("UDLR %u %u %u %u\n", + OVERLAY_GET_KEY(ol_state, RETROK_UP), + OVERLAY_GET_KEY(ol_state, RETROK_DOWN), + OVERLAY_GET_KEY(ol_state, RETROK_LEFT), + OVERLAY_GET_KEY(ol_state, RETROK_RIGHT) + ); +#endif if (OVERLAY_GET_KEY(ol_state, id)) *ret |= 1; } @@ -801,118 +931,3 @@ void input_state_overlay(input_overlay_t *ol, int16_t *ret, break; } } -/** - * input_overlay_add_inputs: - * @ol : pointer to overlay - * @port : the user to show the inputs of - * - * Adds inputs from current_input to the overlay, so it's displayed - * returns true if an input that is pressed will change the overlay - */ -static bool input_overlay_add_inputs_inner(overlay_desc_t *desc, - unsigned port, unsigned analog_dpad_mode) -{ - switch(desc->type) - { - case OVERLAY_TYPE_BUTTONS: - { - unsigned i; - unsigned id; - uint32_t bank_mask; - bool all_buttons_pressed = false; - - /*Check each bank of the mask*/ - for (i=0; ibutton_mask.data); ++i) - { - /*Get bank*/ - bank_mask = BITS_GET_ELEM(desc->button_mask,i); - id = i*32; - - /*Worth pursuing? Have we got any bits left in here?*/ - while (bank_mask) - { - /*If this bit is set then we need to query the pad - *The button must be pressed.*/ - if (bank_mask & 1) - { - /* Light up the button if pressed */ - if(input_state(port, RETRO_DEVICE_JOYPAD, 0, id)) - { - all_buttons_pressed = true; - desc->updated = true; - } - else - { - /*we need ALL of the inputs to be active*/ - all_buttons_pressed = false; - desc->updated = false; - - /*abort*/ - return false; - } - } - - bank_mask >>= 1; - ++id; - } - } - - return all_buttons_pressed; - } - - case OVERLAY_TYPE_ANALOG_LEFT: - case OVERLAY_TYPE_ANALOG_RIGHT: - { - float analog_x, analog_y; - float dx, dy; - unsigned int index = (desc->type == OVERLAY_TYPE_ANALOG_RIGHT) ? - RETRO_DEVICE_INDEX_ANALOG_RIGHT : RETRO_DEVICE_INDEX_ANALOG_LEFT; - - analog_x = input_state(port, RETRO_DEVICE_ANALOG, index, RETRO_DEVICE_ID_ANALOG_X); - analog_y = input_state(port, RETRO_DEVICE_ANALOG, index, RETRO_DEVICE_ID_ANALOG_Y); - dx = (analog_x/0x8000)*(desc->range_x/2); - dy = (analog_y/0x8000)*(desc->range_y/2); - - desc->delta_x = dx; - desc->delta_y = dy; - /*Maybe use some option here instead of 0, only display - changes greater than some magnitude. - */ - if((dx*dx) > 0 || (dy*dy) > 0) - return true; - } - break; - - case OVERLAY_TYPE_KEYBOARD: - if(input_state(port, RETRO_DEVICE_KEYBOARD, 0, desc->retro_key_idx)) - { - desc->updated = true; - return true; - } - break; - - default: - break; - } - - return false; -} - -static bool input_overlay_add_inputs(input_overlay_t *ol, - unsigned port, unsigned analog_dpad_mode) -{ - unsigned i; - bool button_pressed = false; - input_overlay_state_t *ol_state = &ol->overlay_state; - - if(!ol_state) - return false; - - for(i = 0; i < ol->active->size; i++) - { - overlay_desc_t *desc = &(ol->active->descs[i]); - button_pressed |= input_overlay_add_inputs_inner(desc, port, analog_dpad_mode); - } - - return button_pressed; -} diff --git a/input/input_overlay.h b/input/input_overlay.h index 468e6e5141..ed70af4cd6 100644 --- a/input/input_overlay.h +++ b/input/input_overlay.h @@ -177,7 +177,7 @@ struct overlay_desc unsigned retro_key_idx; /* This is a bit mask of all input binds to set with this overlay control */ - retro_bits_t button_mask; + input_bits_t button_mask; char next_index_name[64]; diff --git a/input/input_remapping.c b/input/input_remapping.c index 5830565e09..f92eb20d86 100644 --- a/input/input_remapping.c +++ b/input/input_remapping.c @@ -39,7 +39,7 @@ static unsigned old_libretro_device[MAX_USERS]; **/ bool input_remapping_load_file(void *data, const char *path) { - unsigned i, j; + unsigned i, j, k; config_file_t *conf = (config_file_t*)data; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); @@ -53,69 +53,77 @@ bool input_remapping_load_file(void *data, const char *path) for (i = 0; i < MAX_USERS; i++) { - char s1[64], s2[64]; - char key_ident[RARCH_FIRST_CUSTOM_BIND + 4][128] = {{0}}; - char keymapper_ident[RARCH_FIRST_CUSTOM_BIND + 4][128] = {{0}}; - char key_strings[RARCH_FIRST_CUSTOM_BIND + 4][128] = - { "b", "y", "select", "start", + char s1[64], s2[64], s3[64]; + char btn_ident[RARCH_FIRST_CUSTOM_BIND][128] = {{0}}; + char key_ident[RARCH_FIRST_CUSTOM_BIND][128] = {{0}}; + char stk_ident[8][128] = {{0}}; + + char key_strings[RARCH_FIRST_CUSTOM_BIND + 8][128] = { + "b", "y", "select", "start", "up", "down", "left", "right", "a", "x", "l", "r", "l2", "r2", - "l3", "r3", "l_x", "l_y", "r_x", "r_y" }; + "l3", "r3", "l_x+", "l_x-", "l_y+", "l_y-", "r_x+", "r_x-", "r_y+", "r_y-" }; old_analog_dpad_mode[i] = settings->uints.input_analog_dpad_mode[i]; old_libretro_device[i] = settings->uints.input_libretro_device[i]; s1[0] = '\0'; s2[0] = '\0'; + s3[0] = '\0'; - snprintf(s1, sizeof(s1), "input_player%u", i + 1); + snprintf(s1, sizeof(s1), "input_player%u_btn", i + 1); snprintf(s2, sizeof(s2), "input_player%u_key", i + 1); + snprintf(s3, sizeof(s3), "input_player%u_stk", i + 1); - for (j = 0; j < RARCH_FIRST_CUSTOM_BIND + 4; j++) + for (j = 0; j < RARCH_FIRST_CUSTOM_BIND + 8; j++) { - int key_remap = -1; - - fill_pathname_join_delim(key_ident[j], s1, - key_strings[j], '_', sizeof(key_ident[j])); - fill_pathname_join_delim(keymapper_ident[j], s2, - key_strings[j], '_', sizeof(key_ident[j])); - - if (config_get_int(conf, key_ident[j], &key_remap) - && key_remap < RARCH_FIRST_CUSTOM_BIND) - settings->uints.input_remap_ids[i][j] = key_remap; - - key_remap = -1; - - if (settings->uints.keymapper_port == i) + if (j < RARCH_FIRST_CUSTOM_BIND) { - if (config_get_int(conf, keymapper_ident[j], &key_remap)) - { - settings->uints.input_keymapper_ids[j] = key_remap; -#if 0 - RARCH_LOG ("%s: %u\n", keymapper_ident[j], settings->uints.input_keymapper_ids[j]); -#endif - } + int btn_remap = -1; + int key_remap = -1; + + fill_pathname_join_delim(btn_ident[j], s1, + key_strings[j], '_', sizeof(btn_ident[j])); + fill_pathname_join_delim(key_ident[j], s2, + key_strings[j], '_', sizeof(btn_ident[j])); + + if (config_get_int(conf, btn_ident[j], &btn_remap) + && btn_remap != -1) + settings->uints.input_remap_ids[i][j] = btn_remap; + else if (config_get_int(conf, btn_ident[j], &btn_remap) + && btn_remap == -1) + settings->uints.input_remap_ids[i][j] = RARCH_UNMAPPED; + /* else do nothing, important */ + + if (config_get_int(conf, key_ident[j], &key_remap)) + settings->uints.input_keymapper_ids[i][j] = key_remap; else - settings->uints.input_keymapper_ids[j] = RETROK_UNKNOWN; + settings->uints.input_keymapper_ids[i][j] = RETROK_UNKNOWN; } + else + { + int stk_remap = -1; + k = j - RARCH_FIRST_CUSTOM_BIND; + fill_pathname_join_delim(stk_ident[k], s3, + key_strings[j], '$', sizeof(stk_ident[k])); - } + snprintf(stk_ident[k], + sizeof(stk_ident[k]), + "%s_%s", + s3, + key_strings[j]); - for (j = 0; j < 4; j++) - { - int key_remap = -1; + /* RARCH_LOG("pre_ident: %s:%d\n", stk_ident[j], settings->uints.input_remap_ids[i][j]); */ - snprintf(key_ident[RARCH_FIRST_CUSTOM_BIND + j], - sizeof(key_ident[RARCH_FIRST_CUSTOM_BIND + j]), - "%s_%s", - s1, - key_strings[RARCH_FIRST_CUSTOM_BIND + j]); + if (config_get_int(conf, stk_ident[k], &stk_remap) && stk_remap != -1) + settings->uints.input_remap_ids[i][j] = stk_remap; + else if (config_get_int(conf, stk_ident[k], &stk_remap) && stk_remap == -1) + settings->uints.input_remap_ids[i][j] = RARCH_UNMAPPED; + /* else do nothing, important */ - if (config_get_int(conf, key_ident[RARCH_FIRST_CUSTOM_BIND + j], - &key_remap) && (key_remap < 4)) - settings->uints.input_remap_ids[i][RARCH_FIRST_CUSTOM_BIND + j] = - key_remap; + /*RARCH_LOG("stk_ident: %s:%d\n", stk_ident[j], settings->uints.input_remap_ids[i][j]);*/ + } } snprintf(s1, sizeof(s1), "input_player%u_analog_dpad_mode", i + 1); @@ -141,7 +149,7 @@ bool input_remapping_load_file(void *data, const char *path) bool input_remapping_save_file(const char *path) { bool ret; - unsigned i, j; + unsigned i, j, k; size_t path_size = PATH_MAX_LENGTH * sizeof(char); char *buf = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); char *remap_file = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); @@ -172,46 +180,63 @@ bool input_remapping_save_file(const char *path) for (i = 0; i < max_users; i++) { - char s1[64], s2[64]; - char key_ident[RARCH_FIRST_CUSTOM_BIND + 4][128] = {{0}}; - char keymapper_ident[RARCH_FIRST_CUSTOM_BIND + 4][128] = {{0}}; - char key_strings[RARCH_FIRST_CUSTOM_BIND + 4][128] = { + char s1[64], s2[64], s3[64]; + char btn_ident[RARCH_FIRST_CUSTOM_BIND][128] = {{0}}; + char key_ident[RARCH_FIRST_CUSTOM_BIND][128] = {{0}}; + char stk_ident[8][128] = {{0}}; + + char key_strings[RARCH_FIRST_CUSTOM_BIND + 8][128] = { "b", "y", "select", "start", "up", "down", "left", "right", "a", "x", "l", "r", "l2", "r2", - "l3", "r3", "l_x", "l_y", "r_x", "r_y" }; + "l3", "r3", "l_x+", "l_x-", "l_y+", "l_y-", "r_x+", "r_x-", "r_y+", "r_y-" }; s1[0] = '\0'; s2[0] = '\0'; - snprintf(s1, sizeof(s1), "input_player%u", i + 1); + snprintf(s1, sizeof(s1), "input_player%u_btn", i + 1); snprintf(s2, sizeof(s2), "input_player%u_key", i + 1); + snprintf(s3, sizeof(s1), "input_player%u_stk", i + 1); - for (j = 0; j < RARCH_FIRST_CUSTOM_BIND + 4; j++) + for (j = 0; j < RARCH_FIRST_CUSTOM_BIND + 8; j++) { - fill_pathname_join_delim(key_ident[j], s1, - key_strings[j], '_', sizeof(key_ident[j])); - fill_pathname_join_delim(keymapper_ident[j], s2, - key_strings[j], '_', sizeof(key_ident[j])); - /* only save values that have been modified */ if(j < RARCH_FIRST_CUSTOM_BIND) { - if(settings->uints.input_remap_ids[i][j] != j) - config_set_int(conf, key_ident[j], settings->uints.input_remap_ids[i][j]); - else - config_unset(conf,key_ident[j]); + fill_pathname_join_delim(btn_ident[j], s1, + key_strings[j], '_', sizeof(btn_ident[j])); + fill_pathname_join_delim(key_ident[j], s2, + key_strings[j], '_', sizeof(btn_ident[j])); - if (settings->uints.keymapper_port == i && - settings->uints.input_keymapper_ids[j] != RETROK_UNKNOWN) - config_set_int(conf, keymapper_ident[j], settings->uints.input_keymapper_ids[j]); + /* only save values that have been modified */ + if(settings->uints.input_remap_ids[i][j] != j && + settings->uints.input_remap_ids[i][j] != RARCH_UNMAPPED) + config_set_int(conf, btn_ident[j], settings->uints.input_remap_ids[i][j]); + else if (settings->uints.input_remap_ids[i][j] != j && + settings->uints.input_remap_ids[i][j] == RARCH_UNMAPPED) + config_set_int(conf, btn_ident[j], -1); + else + config_unset(conf,btn_ident[j]); + + if (settings->uints.input_keymapper_ids[i][j] != RETROK_UNKNOWN) + config_set_int(conf, key_ident[j], + settings->uints.input_keymapper_ids[i][j]); } else { - if(settings->uints.input_remap_ids[i][j] != j - RARCH_FIRST_CUSTOM_BIND) - config_set_int(conf, key_ident[j], settings->uints.input_remap_ids[i][j]); + k = j - RARCH_FIRST_CUSTOM_BIND; + fill_pathname_join_delim(stk_ident[k], s3, + key_strings[j], '_', sizeof(stk_ident[k])); + if(settings->uints.input_remap_ids[i][j] != j && + settings->uints.input_remap_ids[i][j] != RARCH_UNMAPPED) + config_set_int(conf, stk_ident[k], + settings->uints.input_remap_ids[i][j]); + else if(settings->uints.input_remap_ids[i][j] != j && + settings->uints.input_remap_ids[i][j] == RARCH_UNMAPPED) + config_set_int(conf, stk_ident[k], + -1); else - config_unset(conf,key_ident[j]); + config_unset(conf, stk_ident[k]); } } snprintf(s1, sizeof(s1), "input_libretro_device_p%u", i + 1); @@ -268,16 +293,18 @@ void input_remapping_set_defaults(bool deinit) for (i = 0; i < MAX_USERS; i++) { - for (j = 0; j < RARCH_FIRST_CUSTOM_BIND; j++) + for (j = 0; j < RARCH_FIRST_CUSTOM_BIND + 8; j++) { - const struct retro_keybind *keybind = &input_config_binds[i][j]; - if (keybind) - settings->uints.input_remap_ids[i][j] = keybind->id; - settings->uints.input_keymapper_ids[j] = RETROK_UNKNOWN; - + if (j < RARCH_FIRST_CUSTOM_BIND) + { + const struct retro_keybind *keybind = &input_config_binds[i][j]; + if (keybind) + settings->uints.input_remap_ids[i][j] = keybind->id; + settings->uints.input_keymapper_ids[i][j] = RETROK_UNKNOWN; + } + else + settings->uints.input_remap_ids[i][j] = j; } - for (j = 0; j < 4; j++) - settings->uints.input_remap_ids[i][RARCH_FIRST_CUSTOM_BIND + j] = j; if (old_analog_dpad_mode[i]) settings->uints.input_analog_dpad_mode[i] = old_analog_dpad_mode[i]; diff --git a/input/input_types.h b/input/input_types.h new file mode 100644 index 0000000000..0bc64d8c42 --- /dev/null +++ b/input/input_types.h @@ -0,0 +1,32 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef __INPUT_TYPES__H +#define __INPUT_TYPES__H + +typedef struct rarch_joypad_driver input_device_driver_t; +typedef struct input_keyboard_line input_keyboard_line_t; +typedef struct rarch_joypad_info rarch_joypad_info_t; +typedef struct input_driver input_driver_t; +typedef struct input_keyboard_ctx_wait input_keyboard_ctx_wait_t; +typedef struct { + uint32_t data[8]; + uint16_t analogs[8]; +} input_bits_t; +typedef struct joypad_connection joypad_connection_t; +typedef struct pad_connection_listener_interface pad_connection_listener_t; + +#endif /* __INPUT_TYPES__H */ diff --git a/intl/msg_hash_ar.h b/intl/msg_hash_ar.h index bc8f846966..f27b347579 100644 --- a/intl/msg_hash_ar.h +++ b/intl/msg_hash_ar.h @@ -460,7 +460,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, - "Achievements Hardcore Mode" + "Hardcore Mode" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_ENABLE, @@ -500,7 +500,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_VERBOSE_ENABLE, - "Achievements Verbose Mode" + "Verbose Mode" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, @@ -1747,6 +1747,8 @@ 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, @@ -1877,6 +1879,8 @@ 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, @@ -1889,6 +1893,8 @@ 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, @@ -1900,7 +1906,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, 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, fast-forward, pause, and slow-motion for all games.") + "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, @@ -1995,6 +2001,8 @@ 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, @@ -2565,7 +2573,7 @@ MSG_HASH(MSG_NETPLAY_LAN_SCANNING, 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 (Windows only).") + "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, @@ -3047,6 +3055,8 @@ 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_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, @@ -3077,6 +3087,8 @@ 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, @@ -3197,8 +3209,12 @@ 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( @@ -3423,3 +3439,65 @@ 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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index 73c5ac25af..9d3c7bf295 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -413,7 +413,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, -/* FIXME? Translate 'Achievements Hardcore Mode' */ +/* FIXME? Translate 'Hardcore Mode' */ "专家模式" ) MSG_HASH( @@ -1626,6 +1626,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, "刷新率") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "估算的显示器帧率") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "旋转") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, @@ -1756,6 +1758,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, "显示设置页") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "显示视频页") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "Menu Layout") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, "菜单图标主题") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, @@ -1857,6 +1861,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, "选择将要使用哪一个显示器。") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "估算的显示器刷新率(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, "调整视频输出的选项。") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2407,7 +2413,7 @@ MSG_HASH(MSG_NETPLAY_LAN_SCANNING, MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, "当窗口失去焦点时暂停游戏。") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, - "Enable or disable composition (Windows only).") + "Enable or disable composition.") MSG_HASH(MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, "为游戏、图片、音乐和视频启用/禁用历史记录。") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, @@ -2877,6 +2883,8 @@ 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_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, @@ -2905,6 +2913,8 @@ 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, @@ -3021,8 +3031,12 @@ 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_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( @@ -3211,3 +3225,65 @@ 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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index fea49f44f3..8fb48b4472 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -413,7 +413,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, -/* FIXME? Translate 'Achievements Hardcore Mode' */ +/* FIXME? Translate 'Hardcore Mode' */ "成就-專家模式" ) MSG_HASH( @@ -1626,6 +1626,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, "刷新率") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "估算的顯示器幀率") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "旋轉") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, @@ -1748,6 +1750,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, "顯示設定頁") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "顯示視訊頁") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "Menu Layout") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, "選單圖標主題") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, @@ -1849,6 +1853,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, "選擇將要使用哪一個顯示器。") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "估算的顯示器刷新率(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, "調整視訊輸出的選項。") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2399,7 +2405,7 @@ MSG_HASH(MSG_NETPLAY_LAN_SCANNING, MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, "當窗口失去焦點時暫停遊戲。") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, - "Enable or disable composition (Windows only).") + "Enable or disable composition.") MSG_HASH(MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, "為遊戲、圖片、音樂和視訊啟用/禁用歷史記錄。") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, @@ -2869,6 +2875,8 @@ 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_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, @@ -2897,6 +2905,8 @@ 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, @@ -3013,8 +3023,12 @@ 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_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( @@ -3203,3 +3217,65 @@ 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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 311affa126..045a31dc09 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -1673,6 +1673,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, "Bildwiederholrate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "Geschätzte Bildwiederholrate") +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, @@ -1809,6 +1811,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "Zeige Tab 'Video'") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, "Zeige Tab 'Netplay'") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "Menu Layout") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, "Menü-Design") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, @@ -1911,6 +1915,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, "Wält den Bildschirm aus, der für RetroArch verwendet wird.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "Die geschätzte Bildwiederholrate des Bildschirms 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, "Einstellungen für die Videoausgabe anpassen.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2959,6 +2965,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, "Wähle ein Datenträger-Abbild, das eingelegt werden soll.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, "Stelle sicher, dass die Bildwiederholrate im Menü begrenzt wird.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_LAYOUT, + "Select a different layout for the XMB interface.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_THEME, "Wähle ein anderes Thema für das Menü aus. Änderungen werden übernommen, nachdem Du das Programm neu gestartet hast.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, @@ -3105,8 +3113,12 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, "Leite alle Netplay-Verbindungen durch einen Man-in-the-middle-Server. Hilfreich, wenn sich der Host hinter einer Firewall befindet oder Probleme mit NAT/UPnP hat.") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, "Zum Mixer hinzufügen") +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, "zum Mixer hinzufügen") +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, "Nach aktuellem Core filtern") MSG_HASH( @@ -3319,3 +3331,65 @@ 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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index 2914287c26..06dbfd7943 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -345,7 +345,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, - "Achievements Hardcore Mode" + "Hardcore Mode" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, @@ -1526,6 +1526,8 @@ 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, @@ -1652,6 +1654,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, "Display Settings Tab") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "Display Video 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, @@ -1663,7 +1667,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, 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, fast-forward, pause, and slow-motion for all games.") + "Enable or disable savestates, cheats, rewind, pause, and slow-motion for all games.") MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, "Change drivers for this system.") MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, @@ -1750,6 +1754,8 @@ 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, "Adjusts settings for video output.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2286,7 +2292,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DATABASE_INFO, MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, "Pause gameplay when window focus is lost.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, - "Enable or disable composition (Windows only).") + "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, @@ -2740,6 +2746,8 @@ 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_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, @@ -2770,6 +2778,8 @@ 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, @@ -2886,8 +2896,12 @@ 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_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( @@ -3076,3 +3090,65 @@ 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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index 5371d79e03..43ee5c1c4f 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -2953,6 +2953,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "Frecuencia estimada del monitor" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "Rotación" @@ -3229,6 +3233,8 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, "Mostrar pestaña juego en red" ) +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "Menu Layout") MSG_HASH( MENU_ENUM_LABEL_VALUE_XMB_THEME, "Tema de iconos del menú" @@ -3441,6 +3447,10 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "Estimado preciso de refresco de la pantalla en 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, "Opciones de salida de video" @@ -5117,6 +5127,8 @@ MSG_HASH( MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, "Limita los FPS en el menú" ) +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_LAYOUT, + "Select a different layout for the XMB interface.") MSG_HASH( MENU_ENUM_SUBLABEL_XMB_THEME, "Seleccionar un tema de iconos diferente. Los cambios tendrán efecto al reiniciar" @@ -5377,10 +5389,16 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, "Agregar al mezclador" ) +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, "Agregar al mezclador y colección" ) +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, "Filtrar por núcleo actual" @@ -5805,3 +5823,65 @@ 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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 5950a9a29b..223c26e436 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -1643,6 +1643,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, "Fréquence de rafraîchissement verticale") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "Fréquence estimée de l'écran") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "Rotation") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, @@ -1773,6 +1775,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, "Afficher l'onglet Paramètres") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "Afficher l'onglet Vidéo") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "Menu Layout") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, "Thème XMB") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, @@ -1873,6 +1877,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, "Sélectionne l'écran à utiliser.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "Taux de rafraîchissement estimé de l'écran en Hz.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED, + "The refresh rate as reported by the display driver.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, "Ajuster les paramètres de sortie vidéo.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2907,6 +2913,8 @@ 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_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, @@ -2935,6 +2943,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_HISTORY, "Affiche l'onglet de l'historique dans le menu principal.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_ADD, "Show the import content tab inside the main menu.") +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, @@ -3051,8 +3061,12 @@ 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_ADD_TO_MIXER, "Ajouter au mixeur") +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, "Ajouter au mixeur") +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( @@ -3241,3 +3255,65 @@ 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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index a81f223b8c..e632d08ea4 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -1671,6 +1671,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, "Frequenza di aggiornamento verticale") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "Framerate dello schermo stimato") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "Rotazione") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, @@ -1807,6 +1809,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "Visualizza colonna Video") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, "Visualizza colonna Stanze Netplay ") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "Menu Layout") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, "Icone del Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, @@ -1909,6 +1913,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, "Seleziona lo schermo da utilizzare.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "La stima precisa di aggiornamento dello schermo 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, "Cambia le impostazioni per l'uscita video.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2957,6 +2963,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, "Seleziona un'immagine disco da inserire") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, "Assicura che i fotogrammi siano attivi all'interno del menu.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_LAYOUT, + "Select a different layout for the XMB interface.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_THEME, "Seleziona un tema diverso per l'icona. Le modifiche avranno effetto dopo il riavvio del programma.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, @@ -2987,6 +2995,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_HISTORY, "Mostra la colonna cronologia all'interno del menu principale.") MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_ADD, "Mostra la colonna importa contenuto all'interno del menu principale.") +MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_PLAYLISTS, + "Mostra le colonne delle playlist all'interno del menu principale") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN, "Mostra la schermata di avvio nel menu. Questo viene automaticamente impostato su off dopo l'avvio del programma per la prima volta.") MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY, @@ -3103,8 +3113,12 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, "Inoltra le connessioni da netplay attraverso un server man-in-the-middle . Utile se l'host è dietro un firewall o ha problemi NAT/UPnP") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, "Aggiungi al 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, "Aggiungi al 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, "Filtra per core corrente") MSG_HASH( @@ -3299,3 +3313,65 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_STATISTICS_SHOW, "Mostra statistiche") MSG_HASH(MENU_ENUM_SUBLABEL_STATISTICS_SHOW, "Mostra statistiche tecniche su schermo.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_ENABLE, + "Abilita riempimento dei bordi") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, + "Attiva lo spessore del riempimento del bordo") +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_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_CONTENT_SHOW_REWIND, + "Mostra impostazioni di riavvolgimento") +MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND, + "Mostra/nascondi le opzioni di riavvolgimento.") +MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_LATENCY, + "Mostra/nascondi le opzioni di latenza.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_LATENCY, + "Mostra le impostazioni di latenza") +MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SHOW_OVERLAYS, + "Mostra/nascondi le opzioni di Sovrapposizione.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_OVERLAYS, + "Mostra le impostazioni di sovrapposizione") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE_MENU, + "Abilita l'audio del menu") +MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_ENABLE_MENU, + "Abilita o disabilita il suono del menu.") +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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index 42c28851b2..ceb35d4a95 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -498,6 +498,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_VERBOSE_ENABLE, "実績の詳細モード" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_AUTO_SCREENSHOT, + "自動スクリーンショット" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS, "解除可能の実績:" @@ -885,6 +889,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, "マウスグラブを切り替え") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, "ゲームのフォーカスを切り替え") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE, + "デスクトップメニューを切り替え") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DESKTOP_MENU_ENABLE, + "デスクトップメニューを有効(再起動が必要)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, "保存状態をロード") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, @@ -917,6 +925,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, "前のシェーダー") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_HOLD_KEY, "ホルドでスローモーション") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_KEY, + "スローモーションに切り替え") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, "前の状態スロット") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, @@ -961,8 +971,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, "ターボの期間") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_USER_BINDS, "入力ユーザー%uのバインド") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LATENCY_SETTINGS, + "遅延") MSG_HASH(MENU_ENUM_LABEL_VALUE_INTERNAL_STORAGE_STATUS, - "Internal storage status") + "内蔵ストレージ状態") MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_AUTOCONFIG_DIR, "入力デバイスの自動設定") MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_DRIVER, @@ -1431,6 +1443,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SHUTDOWN, "シャットダウン") MSG_HASH(MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO, "スローモーション比") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_ENABLED, + "先読みして遅延を減らす") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_FRAMES, + "先読みするフレーム数") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_SECONDARY_INSTANCE, + "2つ目のコアで先読みする") MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVEFILES_ENABLE, "フォルダでセーブファイルを並び替え") MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVESTATES_ENABLE, @@ -1611,6 +1629,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, "スレッド化タスク") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS, "サムネイル") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS, + "左のサムネイル") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS, + "サムネイル両方を右側に設置") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, "サムネイル") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST, @@ -1631,6 +1653,8 @@ 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, + "起動時にデスクトップメニューを表示") MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_MENUBAR_ENABLE, "メニューバー") MSG_HASH(MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE, @@ -1688,7 +1712,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, "黒いフレームを挿入") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, - "オーバースキャンをクロップ (再起動が必要)") + "オーバースキャンをクロップ(再起動が必要)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "デスクトップのコンポジットを無効") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, @@ -1737,6 +1761,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, "リフレッシュレート") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "画面の予想フレームレート") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "回転") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, @@ -1863,6 +1889,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_HISTORY, "履歴タブを表示") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_ADD, "コンテンツをインポートするタブを表示") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_PLAYLISTS, + "プレイリストタブを表示") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_FAVORITES, "お気に入りタブを表示") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_IMAGES, @@ -1875,6 +1903,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "ビデオタブを表示") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, "ネットプレイタブを表示") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "メニュー配置") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, "メニューのアイコンテーマ") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, @@ -1975,6 +2005,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, "希望する画面を選択する。") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "画面の正確な推定のリフレッシュレート") +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, "ビデオ出力の設定を変える。") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2118,7 +2150,7 @@ MSG_HASH(MSG_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, "パッチに失敗しました") MSG_HASH(MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT, @@ -2204,7 +2236,7 @@ MSG_HASH(MSG_INPUT_RENAME_ENTRY, MSG_HASH(MSG_INTERFACE, "インタフェース") MSG_HASH(MSG_INTERNAL_STORAGE, - "内部ストレージ") + "内蔵ストレージ") MSG_HASH(MSG_REMOVABLE_STORAGE, "リムーバブルストレージ") MSG_HASH(MSG_INVALID_NICKNAME_SIZE, @@ -2525,7 +2557,7 @@ MSG_HASH(MSG_NETPLAY_LAN_SCANNING, MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, "Pause gameplay when window focus is lost.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, - "Enable or disable composition (Windows only).") + "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, @@ -2981,6 +3013,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, "ディスクイメージを追加する。") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, "Makes sure the framerate is capped while inside the menu.") +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, @@ -3087,8 +3121,12 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, "中間者のサーバーにネットプレイ接続を転送する。ファイアウォールやNAT/UPnPが問題の時に便利。") MSG_HASH(MENU_ENUM_LABEL_VALUE_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, "ミキサーに追加") +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, "現在のコアで絞り込み") MSG_HASH( @@ -3265,6 +3303,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES, "お気に入りに追加") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST, "お気に入りに追加") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RESET_CORE_ASSOCIATION, + "コア関連をリセット") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DISABLE_KIOSK_MODE, "キオスクモードを無効") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_DISABLE_KIOSK_MODE, @@ -3314,6 +3354,178 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_WATCH_FOR_CHANGES, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_SHOW_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, + "メニューのオーディオを有効") +MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_ENABLE_MENU, + "Enable or disable menu sound.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_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, + "詳細") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_FILE, + "ファイル(&F)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_LOAD_CORE, + "コアをロード(&L)...") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_UNLOAD_CORE, + "コアをアンロード(&U)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_EXIT, + "終了(&X)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT, + "編集(&E)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT_SEARCH, + "検索(&S)") +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_OPTIONS, + "設定(&O)...") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS, + "ドック配置を記憶:") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY, + "ウィンドウ位置とサイズを記憶:") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB, + "最後のコンテンツブラウザーのタブを記憶:") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_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, + "ダーク") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM, + "カスタム...") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE, + "設定") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_NAME, + "名前") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOAD_CUSTOM_CORE, + "カスタムなコアをロード...") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOAD_CORE, + "コアをロード") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOADING_CORE, + "コアをロード中...") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE_VERSION, + "バージョン") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_TAB_PLAYLISTS, + "プレイリスト") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER, + "ファイルブラウザー") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_TOP, + "先頭") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_UP, + "上へ") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_DOCK_CONTENT_BROWSER, + "コンテンツブラウザー") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_BOXART, + "ボックスアート") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_SCREENSHOT, + "スクリーンショット") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_TITLE_SCREEN, + "タイトルスクリーン") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ALL_PLAYLISTS, + "すべてのプレイリスト") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE, + "コア") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE_INFO, + "コア情報") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CORE_SELECTION_ASK, + "<問い合わせる>") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_INFORMATION, + "情報") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_WARNING, + "警告") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ERROR, + "エラー") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_RESTART_TO_TAKE_EFFECT, + "変更はRetroArchを再起動した後に反映されます。") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOG, + "ログ") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, + "今後表示しない") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_STOP, + "停止") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE, + "コアに関連付ける") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS, + "隠したプレイリスト") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_HIDE, + "隠す") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_HIGHLIGHT_COLOR, + "ハイライトカラー") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CHOOSE, + "選択(&C)...") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SELECT_COLOR, + "色の選択") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_SELECT_THEME, + "テーマの選択") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CUSTOM_THEME, + "カスタムなテーマ") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_PATH_IS_BLANK, + "ファイルのパスは空きです。") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_IS_EMPTY, + "ファイルは空きです。") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_READ_OPEN_FAILED, + "ファイルを読み込みのために開けません。") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST, + "ファイルは存在しません。") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SUGGEST_LOADED_CORE_FIRST, + "ロードしたコアを最初に優先する") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index b900c8370d..9adc53d807 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -1621,6 +1621,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_POST_FILTER_RECORD, "필터 적용된 녹화 사용") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, "수직 리프레시 비율") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "화면 프레임레이트 측정치") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, @@ -1753,6 +1755,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "비디오 탭 보이기") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, "넷플레이 탭 보이기") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "Menu Layout") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, "메뉴 아이콘 테마") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, @@ -1853,6 +1857,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, "사용할 디스플레이를 선택.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "화면의 정확한 리프레시 비율(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, "비디오 출력 설정 변경.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2871,6 +2877,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, "삽입할 디스크 이미지를 선택하십시오.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, "메뉴상에 있을 시에는 프레임 제한을 설정.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_LAYOUT, + "Select a different layout for the XMB interface.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_THEME, "다른 아이콘 테마 선택. 변경 내용은 프로그램을 다시 시작 후 적용됩니다.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, @@ -3014,8 +3022,12 @@ 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_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( @@ -3204,3 +3216,65 @@ 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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index e914210d27..b666ca3b24 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -271,6 +271,8 @@ MSG_HASH(MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN_DETECT_CORE, "deferred_archive_open_detect_core") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_AUDIO_SETTINGS_LIST, "deferred_audio_settings_list") +MSG_HASH(MENU_ENUM_LABEL_DEFERRED_AUDIO_MIXER_SETTINGS_LIST, + "deferred_audio_mixer_settings_list") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_CONFIGURATION_SETTINGS_LIST, "deferred_configuration_settings_list") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_CORE_CONTENT_DIRS_LIST, @@ -301,6 +303,8 @@ MSG_HASH(MENU_ENUM_LABEL_DEFERRED_INPUT_HOTKEY_BINDS_LIST, "deferred_input_hotkey_binds") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_INPUT_SETTINGS_LIST, "deferred_input_settings_list") +MSG_HASH(MENU_ENUM_LABEL_DEFERRED_LATENCY_SETTINGS_LIST, + "deferred_latency_settings_list") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_LAKKA_LIST, "deferred_lakka_list") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_LAKKA_SERVICES_LIST, @@ -529,6 +533,8 @@ MSG_HASH(MENU_ENUM_LABEL_INPUT_SETTINGS, "input_settings") MSG_HASH(MENU_ENUM_LABEL_INPUT_SETTINGS_BEGIN, "input_settings_begin") +MSG_HASH(MENU_ENUM_LABEL_LATENCY_SETTINGS, + "latency_settings") MSG_HASH(MENU_ENUM_LABEL_INPUT_SMALL_KEYBOARD_ENABLE, "input_small_keyboard_enable") MSG_HASH(MENU_ENUM_LABEL_INPUT_TOUCH_ENABLE, @@ -989,6 +995,12 @@ MSG_HASH(MENU_ENUM_LABEL_SHUTDOWN, "shutdown") MSG_HASH(MENU_ENUM_LABEL_SLOWMOTION_RATIO, "slowmotion_ratio") +MSG_HASH(MENU_ENUM_LABEL_RUN_AHEAD_ENABLED, + "run_ahead_enabled") +MSG_HASH(MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE, + "run_ahead_secondary_instance") +MSG_HASH(MENU_ENUM_LABEL_RUN_AHEAD_FRAMES, + "run_ahead_frames") MSG_HASH(MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE, "sort_savefiles_enable") MSG_HASH(MENU_ENUM_LABEL_SORT_SAVESTATES_ENABLE, @@ -1029,6 +1041,10 @@ MSG_HASH(MENU_ENUM_LABEL_THREADED_DATA_RUNLOOP_ENABLE, "threaded_data_runloop_enable") MSG_HASH(MENU_ENUM_LABEL_THUMBNAILS, "thumbnails") +MSG_HASH(MENU_ENUM_LABEL_LEFT_THUMBNAILS, + "left thumbnails") +MSG_HASH(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, + "xmb_vertical_thumbnails") MSG_HASH(MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY, "thumbnails_directory") MSG_HASH(MENU_ENUM_LABEL_THUMBNAILS_UPDATER_LIST, @@ -1041,6 +1057,10 @@ MSG_HASH(MENU_ENUM_LABEL_UI_COMPANION_ENABLE, "ui_companion_enable") MSG_HASH(MENU_ENUM_LABEL_UI_COMPANION_START_ON_BOOT, "ui_companion_start_on_boot") +MSG_HASH(MENU_ENUM_LABEL_UI_COMPANION_TOGGLE, + "ui_companion_toggle") +MSG_HASH(MENU_ENUM_LABEL_DESKTOP_MENU_ENABLE, + "desktop_menu_enable") MSG_HASH(MENU_ENUM_LABEL_UI_MENUBAR_ENABLE, "ui_menubar_enable") MSG_HASH(MENU_ENUM_LABEL_UNDO_LOAD_STATE, @@ -1085,6 +1105,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_VIDEO_ASPECT_RATIO, "video_aspect_ratio") MSG_HASH(MENU_ENUM_LABEL_VIDEO_ASPECT_RATIO_AUTO, @@ -1143,6 +1167,8 @@ MSG_HASH(MENU_ENUM_LABEL_VIDEO_REFRESH_RATE, "video_refresh_rate") MSG_HASH(MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_AUTO, "video_refresh_rate_auto") +MSG_HASH(MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED, + "video_refresh_rate_polled") MSG_HASH(MENU_ENUM_LABEL_VIDEO_ROTATION, "video_rotation") MSG_HASH(MENU_ENUM_LABEL_VIDEO_SCALE, @@ -1233,6 +1259,8 @@ MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_HISTORY, "content_show_history") MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_ADD, "content_show_add") +MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_PLAYLISTS, + "content_show_playlists") MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_FAVORITES, "content_show_favorites") MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_IMAGES, @@ -1247,6 +1275,8 @@ MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_VIDEO, "content_show_video") MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_NETPLAY, "content_show_netplay") +MSG_HASH(MENU_ENUM_LABEL_XMB_LAYOUT, + "xmb_layout") MSG_HASH(MENU_ENUM_LABEL_XMB_THEME, "xmb_theme") MSG_HASH(MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT, @@ -1343,8 +1373,12 @@ MSG_HASH(MENU_ENUM_LABEL_NETPLAY_MITM_SERVER, "netplay_mitm_server") MSG_HASH(MENU_ENUM_LABEL_ADD_TO_MIXER, "audio_add_to_mixer") +MSG_HASH(MENU_ENUM_LABEL_ADD_TO_MIXER_AND_PLAY, + "audio_add_to_mixer_and_play") MSG_HASH(MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION, "audio_add_to_mixer_and_collection") +MSG_HASH(MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY, + "audio_add_to_mixer_and_collection_and_play") MSG_HASH(MENU_ENUM_LABEL_FILTER_BY_CURRENT_CORE, "filter_by_current_Core") MSG_HASH(MENU_ENUM_LABEL_AUDIO_MIXER_VOLUME, @@ -1449,3 +1483,25 @@ MSG_HASH(MENU_ENUM_LABEL_INPUT_DRIVER_LINUXRAW, "linuxraw") MSG_HASH(MENU_ENUM_LABEL_VIDEO_WINDOW_SHOW_DECORATIONS, "video_window_show_decorations") +MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE, + "menu_rgui_border_filler_enable") +MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, + "menu_rgui_border_filler_thickness_enable") +MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, + "menu_rgui_background_filler_thickness_enable") +MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_REWIND, + "menu_show_rewind_settings") +MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY, + "menu_show_latency_settings") +MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_OVERLAYS, + "menu_show_overlay_settings") +MSG_HASH(MENU_ENUM_LABEL_AUDIO_ENABLE_MENU, + "audio_enable_menu") +MSG_HASH(MENU_ENUM_LABEL_AUDIO_MIXER_SETTINGS, + "audio_mixer_settings") +MSG_HASH(MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST, + "deferred_mixer_stream_settings_list") +MSG_HASH(MENU_ENUM_LABEL_QUICK_MENU_OVERRIDE_OPTIONS, + "quick_menu_override_options") +MSG_HASH(MENU_ENUM_LABEL_DEFERRED_QUICK_MENU_OVERRIDE_OPTIONS, + "deferred_quick_menu_override_options") diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index 90eb92fd77..83fcc9b10a 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -345,7 +345,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, - "Achievements Hardcore Mode" + "Hardcore Mode" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, @@ -1524,6 +1524,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, "Vertical Refresh Rate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "Geschatte Scherm Framerate") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "Rotatie") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, @@ -1650,6 +1652,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, "Instellingentab weergeven") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "Videotab weergeven") +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, @@ -1661,7 +1665,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, 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, fast-forward, pause, and slow-motion for all games.") + "Enable or disable savestates, cheats, rewind, pause, and slow-motion for all games.") MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, "Change drivers for this system.") MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, @@ -1748,6 +1752,8 @@ 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, "Adjusts settings for video output.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2288,7 +2294,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DATABASE_INFO, MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, "Pause gameplay when window focus is lost.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, - "Enable or disable composition (Windows only).") + "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, @@ -2744,6 +2750,8 @@ 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_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, @@ -2772,6 +2780,8 @@ 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, @@ -2888,8 +2898,12 @@ 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_ADD_TO_MIXER, "Aan audio mixer toevoegen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_PLAY, + "Aan audio mixer toevoegen en afspelen") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION, "Aan audio mixer toevoegen") +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( @@ -3078,3 +3092,65 @@ 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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index 40167dd3d5..9ead01b5fb 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -1753,6 +1753,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, "Odświeżanie w pionie") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "Szacowana liczba klatek na sekundę na ekranie") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "Obrót") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, @@ -1895,6 +1897,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "Pokaż kartę Wideo") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, "Pokaż kartę Gry Online") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "Menu Layout") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, "Motyw ikon menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, @@ -2003,6 +2007,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, "Określa, który ekran wyświetlacza ma być używany.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "Dokładna szacowana częstotliwość odświeżania ekranu w 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, "Zmień ustawienia wyjścia wideo.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -3059,6 +3065,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, "Wybierz obraz dysku, który chcesz wstawić.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, "Upewnia się, że liczba klatek na sekundę jest ograniczona w menu.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_LAYOUT, + "Select a different layout for the XMB interface.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_THEME, "Wybierz inny motyw dla ikony. Zmiany zaczną obowiązywać po ponownym uruchomieniu programu.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, @@ -3211,8 +3219,12 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_MITM_SERVER, "Wybierz określony serwer przekazujący, którego chcesz użyć. Geograficznie bliższe lokalizacje mają zazwyczaj mniejsze opóźnienie.") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, "Dodaj do miksera") +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, "Dodaj do miksera") +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, "Filtruj według bieżącego rdzenia") MSG_HASH( @@ -3439,3 +3451,65 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_STATISTICS_SHOW, "Wyświetl statystyki") MSG_HASH(MENU_ENUM_SUBLABEL_STATISTICS_SHOW, "Pokaż techniczne statystyki na ekranie.") +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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index 109f33450a..6bc179cf20 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -1,660 +1,740 @@ -MSG_HASH(MSG_COMPILER, - "Compilador" - ) -MSG_HASH(MSG_UNKNOWN_COMPILER, - "Compilador desconhecido" - ) -MSG_HASH(MSG_DEVICE_DISCONNECTED_FROM_PORT, - "Dispositivo desconectado da porta" - ) -MSG_HASH(MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, - "Comando Netplay desconhecido recebido" - ) -MSG_HASH(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_HASH(MSG_GOT_CONNECTION_FROM_NAME, - "Conexão recebida de: \"%s (%s)\"" - ) -MSG_HASH(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_HASH(MSG_SETTING_DISK_IN_TRAY, - "Definindo disco na bandeja" - ) -MSG_HASH(MSG_WAITING_FOR_CLIENT, - "Aguardando pelo cliente..." - ) -MSG_HASH(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_HASH(MSG_NETPLAY_ENDIAN_DEPENDENT, - "Este núcleo não suporta Netplay inter-arquitetura entre estes sistemas" - ) -MSG_HASH(MSG_NETPLAY_PLATFORM_DEPENDENT, - "Este núcleo não suporta Netplay inter-arquitetura" - ) -MSG_HASH(MSG_NETPLAY_ENTER_PASSWORD, - "Digite a senha do servidor de Netplay:" - ) -MSG_HASH(MSG_NETPLAY_INCORRECT_PASSWORD, - "Senha incorreta" - ) -MSG_HASH(MSG_NETPLAY_SERVER_NAMED_HANGUP, - "\"%s\" desconectou" - ) -MSG_HASH(MSG_NETPLAY_SERVER_HANGUP, - "Um cliente do Netplay desconectou" - ) -MSG_HASH(MSG_NETPLAY_CLIENT_HANGUP, - "Desconectado do Netplay" - ) -MSG_HASH(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_HASH(MSG_NETPLAY_CANNOT_PLAY, - "Impossível alterar para modo jogador" - ) -MSG_HASH(MSG_NETPLAY_PEER_PAUSED, - "Par do Netplay \"%s\" pausou" - ) -MSG_HASH(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." - ) -MSG_HASH(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." - ) -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." - ) -MSG_HASH(MSG_AUDIO_VOLUME, - "Volume de áudio" - ) -MSG_HASH(MSG_AUTODETECT, - "Autodetectar" - ) -MSG_HASH(MSG_AUTOLOADING_SAVESTATE_FROM, - "Autocarregando Estado de Jogo de" - ) -MSG_HASH(MSG_CAPABILITIES, - "Capacidades" - ) -MSG_HASH(MSG_CONNECTING_TO_NETPLAY_HOST, - "Conectando ao hospedeiro de Netplay" - ) -MSG_HASH(MSG_CONNECTING_TO_PORT, - "Conectando a porta" - ) -MSG_HASH(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_HASH(MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, - "Senha" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, - "Contas Cheevos" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, - "Nome de usuário" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, - "Contas" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST_END, - "Ponto Final da Lista de Contas" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, - "Retro Achievements" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, - "Lista de Conquistas" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, - "Lista de Conquistas (Hardcore)" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, - "Analisar Conteúdo" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONFIGURATIONS_LIST, - "Configurações" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TAB, - "Importar conteúdo" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, - "Salas de Netplay" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, - "Perguntar" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, - "Recursos" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, - "Bloquear Quadros" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, - "Dispositivo de Áudio" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_DRIVER, - "Driver de Áudio" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_DSP_PLUGIN, - "Plugin DSP de Áudio" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE, - "Habilitar Áudio" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, - "Filtro de Áudio" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, - "Turbo/Zona-Morta" - ) -MSG_HASH(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" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_MUTE, - "Áudio Mudo" - ) -MSG_HASH(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" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_DRIVER, - "Driver de Reamostragem de Áudio" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, - "Áudio" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, - "Sincronizar Áudio" - ) -MSG_HASH(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" - ) -MSG_HASH(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" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, - "Intervalo do Autossalvamento da SRAM" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, - "Autocarregar Arquivos de Redefinição" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE, - "Autocarregar Arquivos de Remapeamento" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, - "Autocarregar Predefinições de Shader" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, - "Voltar" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, - "Confirmar" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, - "Informações" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, - "Sair" - ) -MSG_HASH(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" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, - "Iniciar" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, - "Alternar Teclado" - ) -MSG_HASH(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" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_CONFIRM, - "Confirmar/OK" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_INFO, - "Informação" - ) -MSG_HASH(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" - ) -MSG_HASH(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" - ) -MSG_HASH(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" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_BLUETOOTH_ENABLE, - "Habilitar Bluetooth" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, - "URL de Recursos do Buildbot" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY, - "Cache" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_CAMERA_ALLOW, - "Permitir Câmera" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, - "Driver de Câmera" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT, - "Trapaça" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, - "Aplicar Alterações" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, - "Arquivo de Trapaça" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_FILE, - "Arquivo de Trapaça" - ) -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_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_VERBOSE_ENABLE, - "Modo Detalhado das Conquistas" - ) -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_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( + MSG_COMPILER, + "Compilador" + ) +MSG_HASH( + MSG_UNKNOWN_COMPILER, + "Compilador desconhecido" + ) +MSG_HASH( + MSG_DEVICE_DISCONNECTED_FROM_PORT, + "Dispositivo desconectado da porta" + ) +MSG_HASH( + MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, + "Comando Netplay desconhecido recebido" + ) +MSG_HASH( + 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_HASH( + MSG_GOT_CONNECTION_FROM_NAME, + "Conexão recebida de: \"%s (%s)\"" + ) +MSG_HASH( + 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_HASH( + MSG_SETTING_DISK_IN_TRAY, + "Definindo disco na bandeja" + ) +MSG_HASH( + MSG_WAITING_FOR_CLIENT, + "Aguardando pelo cliente..." + ) +MSG_HASH( + 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_HASH( + MSG_NETPLAY_YOU_HAVE_JOINED_WITH_INPUT_DEVICES_S, + "Você se juntou aos dispositivos de entrada %.*s" + ) +MSG_HASH( + 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_HASH( + MSG_NETPLAY_S_HAS_JOINED_WITH_INPUT_DEVICES_S, + "%.*s juntou-se a 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_HASH( + MSG_NETPLAY_OUT_OF_DATE, + "O par netplay está executando uma versão antiga do RetroArch. Não pode 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_HASH( + MSG_NETPLAY_DIFFERENT_CORES, + "Um par de netplay está executando um núcleo diferente. Não pode 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_HASH( + MSG_NETPLAY_ENDIAN_DEPENDENT, + "Este núcleo não suporta Netplay inter-arquitetura entre estes sistemas" + ) +MSG_HASH( + MSG_NETPLAY_PLATFORM_DEPENDENT, + "Este núcleo não suporta Netplay inter-arquitetura" + ) +MSG_HASH( + MSG_NETPLAY_ENTER_PASSWORD, + "Digite a senha do servidor de Netplay:" + ) +MSG_HASH( + MSG_NETPLAY_INCORRECT_PASSWORD, + "Senha incorreta" + ) +MSG_HASH( + MSG_NETPLAY_SERVER_NAMED_HANGUP, + "\"%s\" desconectou" + ) +MSG_HASH( + MSG_NETPLAY_SERVER_HANGUP, + "Um cliente do Netplay desconectou" + ) +MSG_HASH( + MSG_NETPLAY_CLIENT_HANGUP, + "Desconectado do Netplay" + ) +MSG_HASH( + 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_HASH( + 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_HASH( + MSG_NETPLAY_PEER_PAUSED, + "Par do Netplay \"%s\" pausou" + ) +MSG_HASH( + 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." + ) +MSG_HASH( + 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." + ) +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." + ) +MSG_HASH( + MSG_AUDIO_VOLUME, + "Volume de áudio" + ) +MSG_HASH( + MSG_AUTODETECT, + "Detectar automaticamente" + ) +MSG_HASH( + MSG_AUTOLOADING_SAVESTATE_FROM, + "Autocarregando Estado de Jogo de" + ) +MSG_HASH( + MSG_CAPABILITIES, + "Capacidades" + ) +MSG_HASH( + MSG_CONNECTING_TO_NETPLAY_HOST, + "Conectando ao hospedeiro de Netplay" + ) +MSG_HASH( + MSG_CONNECTING_TO_PORT, + "Conectando a porta" + ) +MSG_HASH( + 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_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, + "Senha" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, + "Contas Cheevos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, + "Nome de usuário" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, + "Contas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST_END, + "Ponto Final da Lista de Contas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, + "Retro Achievements" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, + "Lista de Conquistas" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, + "Lista de Conquistas (Hardcore)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, + "Analisar Conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIGURATIONS_LIST, + "Configurações" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TAB, + "Importar conteúdo" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, + "Salas de Netplay" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, + "Perguntar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, + "Recursos" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, + "Bloquear Quadros" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, + "Dispositivo de Áudio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_DRIVER, + "Driver de Áudio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_DSP_PLUGIN, + "Plugin DSP de Áudio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE, + "Habilitar Áudio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, + "Filtro de Áudio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, + "Turbo/Zona-Morta" + ) +MSG_HASH( + 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" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_MUTE, + "Áudio Mudo" + ) +MSG_HASH( + 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" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_DRIVER, + "Driver de Reamostragem de Áudio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, + "Áudio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, + "Sincronizar Áudio" + ) +MSG_HASH( + 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" + ) +MSG_HASH( + 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" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, + "Intervalo do Salvamento Automático da SRAM" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, + "Carraga Automaticamente Arquivos de Redefinição" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE, + "Carraga Automaticamente Arquivos de Remapeamento" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, + "Carraga Automaticamente Predefinições de Shader" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, + "Voltar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, + "Confirmar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, + "Informações" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, + "Sair" + ) +MSG_HASH( + 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" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, + "Iniciar" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, + "Alternar Teclado" + ) +MSG_HASH( + 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" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_CONFIRM, + "Confirmar/OK" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_INFO, + "Informação" + ) +MSG_HASH( + 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" + ) +MSG_HASH( + 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" + ) +MSG_HASH( + 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" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BLUETOOTH_ENABLE, + "Habilitar Bluetooth" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, + "URL de Recursos do Buildbot" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY, + "Cache" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CAMERA_ALLOW, + "Permitir Câmera" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, + "Driver de Câmera" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT, + "Trapaça" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, + "Aplicar Alterações" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, + "Arquivo de Trapaça" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_FILE, + "Arquivo de Trapaça" + ) +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" - ) + "Permitir a remoção de itens") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS, - "Menu Rápido" - ) + "Menu Rápido") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIR, - "Recursos de Núcleo" - ) + "Recursos de Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIRECTORY, - "Downloads" - ) + "Downloads") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS, - "Trapaças" - ) + "Trapaças") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_COUNTERS, - "Contadores do Núcleo" - ) + "Contadores do Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ENABLE, - "Exibir nome do núcleo" - ) + "Exibir nome do núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION, - "Informação do Núcleo" - ) + "Informação do Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_AUTHORS, - "Autores" - ) + "Autores") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CATEGORIES, - "Categorias" - ) + "Categorias") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_LABEL, - "Rótulo do núcleo" - ) + "Rótulo do núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_NAME, - "Nome do núcleo" - ) + "Nome do núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE, - "Firmware(s)" - ) + "Firmware(s)") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES, - "Licença(s)" - ) + "Licença(s)") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_PERMISSIONS, - "Permissões" - ) + "Permissões") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SUPPORTED_EXTENSIONS, - "Extensões suportadas" - ) + "Extensões suportadas") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_MANUFACTURER, - "Fabricante do sistema" - ) + "Fabricante do sistema") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_NAME, - "Nome do sistema" - ) + "Nome do sistema") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS, - "Controles" - ) + "Controles") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_LIST, - "Carregar Núcleo" - ) + "Carregar Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, - "Opções" - ) + "Opções") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SETTINGS, - "Núcleo" - ) + "Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, - "Iniciar um Núcleo Automaticamente" - ) + "Iniciar um Núcleo Automaticamente") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, - "Extrair automaticamente o arquivo baixado" - ) + "Extrair automaticamente o arquivo baixado") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_BUILDBOT_URL, - "URL de Núcleos do Buildbot" - ) + "URL de Núcleos do Buildbot") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST, - "Atualizador de Núcleo" - ) + "Atualizador de Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SETTINGS, - "Atualizador" - ) + "Atualizador") MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_ARCHITECTURE, - "Arquitetura da CPU:" - ) + "Arquitetura da CPU:") MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_CORES, - "Cores da CPU:" - ) + "Cores da CPU:") MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_DIRECTORY, - "Cursor" - ) + "Cursor") MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_MANAGER, - "Gerenciar Cursor" - ) + "Gerenciar Cursor") MSG_HASH(MENU_ENUM_LABEL_VALUE_CUSTOM_RATIO, - "Proporção Personalizada" - ) + "Proporção Personalizada") MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_MANAGER, - "Gerenciar Base de Dados" - ) + "Gerenciar Base de Dados") MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_SELECTION, - "Seleção de Base de Dados" - ) + "Seleção de Base de Dados") MSG_HASH(MENU_ENUM_LABEL_VALUE_DELETE_ENTRY, - "Remover" - ) + "Remover") MSG_HASH(MENU_ENUM_LABEL_VALUE_FAVORITES, - "Diretório Inicial" - ) + "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." - ) + "Diretório não encontrado.") MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS, - "Diretório" - ) + "Diretório") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_CYCLE_TRAY_STATUS, - "Condição da Bandeja do Ciclo de Disco" - ) + "Condição da Bandeja do Ciclo de Disco") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND, - "Anexar Imagem de Disco" - ) + "Anexar Imagem de Disco") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_INDEX, - "Índice de Disco" - ) + "Índice de Disco") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_OPTIONS, - "Controle de Disco" - ) + "Controle de Disco") MSG_HASH(MENU_ENUM_LABEL_VALUE_DONT_CARE, - "Não importa" - ) + "Não importa") MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST, - "Downloads" - ) + "Downloads") MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE, - "Baixar Núcleo..." - ) + "Baixar Núcleo...") MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT, - "Download de Conteúdo" - ) + "Download de Conteúdo") MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_ENABLE, - "Habilitar Redefinição de DPI" - ) + "Habilitar Redefinição de DPI") MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE, - "Redefinição de DPI" - ) + "Redefinição de DPI") MSG_HASH(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS, - "Driver" - ) + "Driver") MSG_HASH(MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN, - "Carregar Modelo no Desligamento do Núcleo" - ) + "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" - ) + "Verificar por Firmware que Falta Antes de Carregar") MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER, - "Plano de Fundo Dinâmico" - ) + "Plano de Fundo Dinâmico") MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY, - "Planos de Fundo Dinâmicos" - ) + "Planos de Fundo Dinâmicos") MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE, - "Habilitar Conquistas" - ) + "Habilitar Conquistas") MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR, - "Cor do item de menu ao passar o cursor" - ) + "Cor do item de menu ao passar o cursor") MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_NORMAL_COLOR, - "Cor normal do item de menu" - ) + "Cor normal do item de menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_FALSE, - "Falso" - ) + "Falso") MSG_HASH(MENU_ENUM_LABEL_VALUE_FASTFORWARD_RATIO, - "Velocidade Máxima de Execução" - ) + "Velocidade Máxima de Execução") MSG_HASH(MENU_ENUM_LABEL_VALUE_FAVORITES_TAB, - "Favoritos" - ) + "Favoritos") MSG_HASH(MENU_ENUM_LABEL_VALUE_FPS_SHOW, - "Mostrar Taxa de Quadros" - ) + "Mostrar Taxa de Quadros") MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE, - "Controlar Velocidade Máxima de Execução" - ) + "Controlar Velocidade Máxima de Execução") MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, - "Controle de Quadros" - ) + "Controle de Quadros") MSG_HASH(MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, - "Contadores do Frontend" - ) + "Contadores do Frontend") MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, - "Autocarregar Opções de Núcleo Específicas do Conteúdo" - ) + "Carraga 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" - ) + "Criar arquivo de opções do jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE, - "Arquivo de opções do jogo" - ) + "Arquivo de opções do jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP, - "Ajuda" - ) + "Ajuda") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING, - "Solução de Problemas de Áudio/Vídeo" - ) + "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" - ) + "Alterando a Transparência de Gamepad Virtual") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CONTROLS, - "Controles Básicos de Menu" - ) + "Controles Básicos de Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_LIST, - "Ajuda" - ) + "Ajuda") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_LOADING_CONTENT, - "Carregando Conteúdo" - ) + "Carregando Conteúdo") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT, - "Procurando em Busca de Conteúdo" - ) + "Procurando em Busca de Conteúdo") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_WHAT_IS_A_CORE, - "O Que É Um Núcleo?" - ) + "O Que É Um Núcleo?") MSG_HASH(MENU_ENUM_LABEL_VALUE_HISTORY_LIST_ENABLE, - "Habilitar Lista de Histórico" - ) + "Habilitar Lista de Histórico") MSG_HASH(MENU_ENUM_LABEL_VALUE_HISTORY_TAB, - "Histórico" - ) + "Histórico") MSG_HASH(MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, - "Menu Horizontal" - ) + "Menu Horizontal") MSG_HASH(MENU_ENUM_LABEL_VALUE_IMAGES_TAB, - "Imagem" - ) + "Imagem") MSG_HASH(MENU_ENUM_LABEL_VALUE_INFORMATION, - "Informação" - ) + "Informação") MSG_HASH(MENU_ENUM_LABEL_VALUE_INFORMATION_LIST, - "Informação" - ) + "Informação") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ADC_TYPE, - "Tipo de Analógico Para Digital" - ) + "Tipo de Analógico Para Digital") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ALL_USERS_CONTROL_MENU, - "Todos os Usuários Controlam o Menu" - ) + "Todos os Usuários Controlam o Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X, - "Analógico Esquerdo X" - ) + "Analógico Esquerdo X") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_MINUS, - "Analógico Esquerdo X- (esquerda)" - ) + "Analógico Esquerdo X- (esquerda)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_PLUS, - "Analógico Esquerdo X+ (direita)" - ) + "Analógico Esquerdo X+ (direita)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y, - "Analógico Esquerdo Y" - ) + "Analógico Esquerdo Y") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_MINUS, - "Analógico Esquerdo Y- (cima)" - ) + "Analógico Esquerdo Y- (cima)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_PLUS, - "Analógico Esquerdo Y+ (baixo)" - ) + "Analógico Esquerdo Y+ (baixo)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X, - "Analógico Direito X" - ) + "Analógico Direito X") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_MINUS, - "Analógico Direito X- (esquerda)" - ) + "Analógico Direito X- (esquerda)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_PLUS, - "Analógico Direito X+ (direita)" - ) + "Analógico Direito X+ (direita)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y, - "Analógico Direito Y" - ) + "Analógico Direito Y") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS, - "Analógico Direito Y- (cima)" - ) + "Analógico Direito Y- (cima)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS, - "Analógico Direito Y+ (baixo)" - ) + "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, @@ -678,101 +758,69 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT, 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" - ) + "Habilitar Autoconfiguração") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Zona Morta do Controle Analógico" - ) + "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" - ) + "Inverter Botões OK e Cancelar do Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, - "Vincular Todos" - ) + "Vincular Todos") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL, - "Vincular Todos pelo Padrão" - ) + "Vincular Todos pelo Padrão") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_TIMEOUT, - "Tempo Limite para Vincular" - ) + "Tempo Limite para Vincular") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_HIDE_UNBOUND, - "Ocultar Descritores de Entrada do Núcleo Não Vinculados" - ) + "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" - ) + "Exibir Rótulos do Descritor de Entrada") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX, - "Índice de Dispositivo" - ) + "Índice de Dispositivo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_TYPE, - "Tipo de Dispositivo" - ) + "Tipo de Dispositivo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_INDEX, - "Índice de Mouse" - ) + "Índice de Mouse") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DRIVER, - "Driver de Entrada" - ) + "Driver de Entrada") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DUTY_CYCLE, - "Ciclo de Trabalho" - ) + "Ciclo de Trabalho") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS, - "Vínculos das Teclas de Atalho da Entrada" - ) + "Vínculos das Teclas de Atalho da Entrada") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE, - "Habilitar Mapeamento de Gamepad no Teclado" - ) + "Habilitar Mapeamento de Gamepad no Teclado") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_A, - "Botão A (direita)" - ) + "Botão A (direita)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, - "Botão B (baixo)" - ) + "Botão B (baixo)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_DOWN, - "Direcional para baixo" - ) + "Direcional para baixo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L2, - "Botão L2 (gatilho)" - ) + "Botão L2 (gatilho)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L3, - "Botão L3 (polegar)" - ) + "Botão L3 (polegar)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L, - "Botão L (ombro)" - ) + "Botão L (ombro)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT, - "Direcional Esquerdo" - ) + "Direcional Esquerdo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R2, - "Botão R2 (gatilho)" - ) + "Botão R2 (gatilho)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R3, - "Botão R3 (polegar)" - ) + "Botão R3 (polegar)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R, - "Botão R (ombro)" - ) + "Botão R (ombro)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_RIGHT, - "Direcional Direito" - ) + "Direcional Direito") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, - "Botão Select" - ) + "Botão Select") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, - "Botão Start" - ) + "Botão Start") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_UP, - "Direcional para Cima" - ) + "Direcional para Cima") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X, - "Botão X (topo)" - ) + "Botão X (topo)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, - "Botão Y (esquerda)" - ) + "Botão Y (esquerda)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEY, - "(Tecla: %s)" - ) + "(Tecla: %s)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_LEFT, "Mouse 1") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_RIGHT, @@ -792,3395 +840,2841 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_UP, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_DOWN, "Roda do Mouse para Diretira") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, - "Tipo de Mapeamento para Gamepad no Teclado" - ) + "Tipo de Mapeamento para Gamepad no Teclado") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MAX_USERS, - "Usuários Máximos" - ) + "Usuários Máximos") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, - "Combinação do Gamepad para Alternar Menu" - ) + "Combinação do Gamepad para Alternar Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS, - "Índice de Trapaça -" - ) + "Índice de Trapaça -") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS, - "Índice de Trapaça +" - ) + "Índice de Trapaça +") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE, - "Alternar Trapaça" - ) + "Alternar Trapaça") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE, - "Alternar ejeção de disco" - ) + "Alternar ejeção de disco") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT, - "Próximo disco" - ) + "Próximo disco") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, - "Disco anterior" - ) + "Disco anterior") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, - "Habilitar teclas de atalho" - ) + "Habilitar teclas de atalho") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY, - "Manter Avanço Rápido" - ) + "Manter Avanço Rápido") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY, - "Alternar Avanço Rápido" - ) + "Alternar Avanço Rápido") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, - "Avanço de Quadro" - ) + "Avanço de Quadro") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, - "Alternar tela cheia" - ) + "Alternar tela cheia") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, - "Alternar captura do Mouse" - ) + "Alternar captura do Mouse") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, - "Alternar foco do jogo" - ) + "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" - ) + "Carregar Estado de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, - "Alternar menu" - ) + "Alternar menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE, - "Alternar gravação de filme" - ) + "Alternar gravação de filme") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, - "Alternar áudio mudo" - ) + "Alternar áudio mudo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, - "Alternar modo jogador/espectador do Netplay" - ) + "Alternar modo jogador/espectador do Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, - "Alternar teclado virtual" - ) + "Alternar teclado virtual") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, - "Próxima Transparência" - ) + "Próxima Transparência") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE, - "Alternar pausa" - ) + "Alternar pausa") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, - "Sair do RetroArch" - ) + "Sair do RetroArch") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, - "Reinicializar jogo" - ) + "Reiniciar jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, - "Retroceder" - ) + "Rebobinar") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, - "Salvar Estado de Jogo" - ) + "Salvar Estado de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, - "Capturar tela" - ) + "Capturar tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, - "Próximo Shader" - ) + "Próximo Shader") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, - "Shader Anterior" - ) + "Shader Anterior") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_HOLD_KEY, - "Câmera Lenta" - ) + "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 -" - ) + "Compartimento do Estado de Jogo -") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, - "Compartimento do Estado de Jogo +" - ) + "Compartimento do Estado de Jogo +") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, - "Volume -" - ) + "Volume -") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, - "Volume +" - ) + "Volume +") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_ENABLE, - "Mostrar Transparência" - ) + "Mostrar Transparência") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU, - "Ocultar Transparência no Menu" - ) + "Ocultar Transparência no Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS, - "Exibir Comandos Na Transparência" - ) + "Exibir Comandos Na Transparência") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT, - "Porta de Escuta do Exibir Comandos " - ) + "Porta de Escuta do Exibir Comandos ") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR, - "Tipo de Comportamento da Chamada Seletiva" - ) + "Tipo de Comportamento da Chamada Seletiva") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_EARLY, - "Mais cedo" - ) + "Mais cedo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_LATE, - "Mais tarde" - ) + "Mais tarde") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_NORMAL, - "Normal" - ) + "Normal") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_PREFER_FRONT_TOUCH, - "Preferir Toque Frontal" - ) + "Preferir Toque Frontal") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAPPING_DIRECTORY, - "Remapeamento de Entrada" - ) + "Remapeamento de Entrada") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAP_BINDS_ENABLE, - "Habilitar Remapeamento de Vínculos" - ) + "Habilitar Remapeamento de Vínculos") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SAVE_AUTOCONFIG, - "Salvar Autoconfiguração" - ) + "Salvar Autoconfiguração") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS, - "Entrada" - ) + "Entrada") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE, - "Habilitar Teclado Pequeno" - ) + "Habilitar Teclado Pequeno") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TOUCH_ENABLE, - "Habilitar Toque" - ) + "Habilitar Toque") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE, - "Habilitar Turbo" - ) + "Habilitar Turbo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, - "Período do Turbo" - ) + "Período do Turbo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_USER_BINDS, - "Vínculos de Entrada do Usuário %u" - ) + "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" - ) + "Condição do armazenamento interno") MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_AUTOCONFIG_DIR, - "Autoconfiguração de Entrada" - ) + "Autoconfiguração de Entrada") MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_DRIVER, - "Driver de Joypad" - ) + "Driver de Joypad") MSG_HASH(MENU_ENUM_LABEL_VALUE_LAKKA_SERVICES, - "Serviços" - ) + "Serviços") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_CHINESE_SIMPLIFIED, - "Chinês (Simplificado)" - ) + "Chinês (Simplificado)") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_CHINESE_TRADITIONAL, - "Chinês (Tradicional)" - ) + "Chinês (Tradicional)") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_DUTCH, - "Holandês" - ) + "Holandês") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ENGLISH, - "Inglês" - ) + "Inglês") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ESPERANTO, - "Esperanto" - ) + "Esperanto") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_FRENCH, - "Francês" - ) + "Francês") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_GERMAN, - "Alemão" - ) + "Alemão") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ITALIAN, - "Italiano" - ) + "Italiano") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_JAPANESE, - "Japonês" - ) + "Japonês") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_KOREAN, - "Coreano" - ) + "Coreano") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_POLISH, - "Polonês" - ) + "Polonês") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_BRAZIL, - "Português (Brasil)" - ) + "Português (Brasil)") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE_PORTUGAL, - "Português (Portugal)" - ) + "Português (Portugal)") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_RUSSIAN, - "Russo" - ) + "Russo") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_SPANISH, - "Espanhol" - ) + "Espanhol") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_VIETNAMESE, - "Vietnamita" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_LANG_ARABIC, - "Arabic" - ) + "Vietnamita") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ARABIC, + "Árabe") MSG_HASH(MENU_ENUM_LABEL_VALUE_LEFT_ANALOG, - "Analógico Esquerdo" - ) + "Analógico Esquerdo") MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH, - "Núcleo" - ) + "Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_INFO_PATH, - "Informação do Núcleo" - ) + "Informação do Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_LOG_LEVEL, - "Nível de Registro de Eventos do Núcleo" - ) + "Nível de Registro de Eventos do Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_LINEAR, - "Linear" - ) + "Linear") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_ARCHIVE, - "Carregar Arquivo" - ) + "Carregar Arquivo") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY, - "Carregar Recente" - ) + "Carregar Recente") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST, - "Carregar Conteúdo" - ) + "Carregar Conteúdo") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_STATE, - "Carregar Estado de Jogo" - ) + "Carregar Estado de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_ALLOW, - "Permitir Localização" - ) + "Permitir Localização") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_DRIVER, - "Driver de Localização" - ) + "Driver de Localização") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS, - "Registro de Eventos" - ) + "Registro de Eventos") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOG_VERBOSITY, - "Verbosidade do Registro de Eventos" - ) + "Verbosidade do Registro de Eventos") MSG_HASH(MENU_ENUM_LABEL_VALUE_MAIN_MENU, - "Menu Principal" - ) + "Menu Principal") MSG_HASH(MENU_ENUM_LABEL_VALUE_MANAGEMENT, - "Configurações da Base de Dados" - ) + "Configurações da Base de Dados") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME, - "Tema de Cor do Menu" - ) + "Tema de Cor do Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE, - "Azul" - ) + "Azul") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE_GREY, - "Cinza Azulado" - ) + "Cinza Azulado") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_DARK_BLUE, - "Azul Escuro" - ) + "Azul Escuro") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_GREEN, - "Verde" - ) + "Verde") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_NVIDIA_SHIELD, - "Shield" - ) + "Shield") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_RED, - "Vermelho" - ) + "Vermelho") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_YELLOW, - "Amarelo" - ) + "Amarelo") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_FOOTER_OPACITY, - "Opacidade do Rodapé" - ) + "Opacidade do Rodapé") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_HEADER_OPACITY, - "Opacidade do Cabeçalho" - ) + "Opacidade do Cabeçalho") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DRIVER, - "Driver de Menu" - ) + "Driver de Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE, - "Controlar Taxa de Quadros do Menu" - ) + "Controlar Taxa de Quadros do Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FILE_BROWSER_SETTINGS, - "Configurações" - ) + "Configurações") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, - "Filtro Linear de Menu" - ) + "Filtro Linear de Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_HORIZONTAL_ANIMATION, - "Animação Horizontal" - ) + "Animação Horizontal") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, - "Aparência" - ) + "Aparência") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER, - "Plano de Fundo" - ) + "Plano de Fundo") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY, - "Opacidade do plano de fundo" - ) + "Opacidade do plano de fundo") MSG_HASH(MENU_ENUM_LABEL_VALUE_MISSING, - "Faltando" - ) + "Faltando") MSG_HASH(MENU_ENUM_LABEL_VALUE_MORE, - "..." - ) + "...") MSG_HASH(MENU_ENUM_LABEL_VALUE_MOUSE_ENABLE, - "Suporte para Mouse" - ) + "Suporte para Mouse") MSG_HASH(MENU_ENUM_LABEL_VALUE_MULTIMEDIA_SETTINGS, - "Multimídia" - ) + "Multimídia") MSG_HASH(MENU_ENUM_LABEL_VALUE_MUSIC_TAB, - "Música" - ) + "Música") MSG_HASH(MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, - "Filtrar Extensões Desconhecidas" - ) + "Filtrar Extensões Desconhecidas") MSG_HASH(MENU_ENUM_LABEL_VALUE_NAVIGATION_WRAPAROUND, - "Navegação Retorna ao Início" - ) + "Navegação Retorna ao Início") MSG_HASH(MENU_ENUM_LABEL_VALUE_NEAREST, - "Mais Próximo" - ) + "Mais Próximo") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY, - "Netplay" - ) + "Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ALLOW_SLAVES, - "Permitir Clientes em Modo Escravo" - ) + "Permitir Clientes em Modo Escravo") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, - "Verificar Quadros do Netplay" - ) + "Verificar Quadros do Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN, - "Quadros de Latência de Entrada" - ) + "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" - ) + "Faixa de Quadros de Latência de Entrada") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES, - "Atraso de Quadros do Netplay" - ) + "Atraso de Quadros do Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT, - "Desconectar do hospedeiro de Netplay" - ) + "Desconectar do hospedeiro de Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE, - "Habilitar Netplay" - ) + "Habilitar Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT, - "Conectar ao hospedeiro de Netplay" - ) + "Conectar ao hospedeiro de Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_HOST, - "Iniciar hospedeiro de Netplay" - ) + "Iniciar hospedeiro de Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISABLE_HOST, - "Parar hospedeiro de Netplay" - ) + "Parar hospedeiro de Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS, - "Endereço do Servidor" - ) + "Endereço do Servidor") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LAN_SCAN_SETTINGS, - "Analisar a rede local" - ) + "Analisar a rede local") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, - "Habilitar Cliente Netplay" - ) + "Habilitar Cliente Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, - "Usuário" - ) + "Usuário") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, - "Senha do Servidor" - ) + "Senha do Servidor") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE, - "Anunciar Netplay Publicamente" - ) + "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" - ) + "Não Permitir Clientes em Modo Não Escravo") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, - "Configurações do Netplay" - ) + "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" - ) + "Modo Espectador do Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, - "Modo sem Estados de Jogo do Netplay" - ) + "Modo sem Estados de Jogo do Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, - "Senha Apenas Espectador do Servidor" - ) + "Senha Apenas Espectador do Servidor") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, - "Habilitar Espectador do Netplay" - ) + "Habilitar Espectador do Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, - "Porta TCP do Netplay" - ) + "Porta TCP do Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, - "Travessia de NAT do Netplay" - ) + "Travessia de NAT do Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_ENABLE, - "Comandos de Rede" - ) + "Comandos de Rede") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT, - "Porta de Comando de Rede" - ) + "Porta de Comando de Rede") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_INFORMATION, - "Informação de Rede" - ) + "Informação de Rede") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_ENABLE, - "Gamepad de Rede" - ) + "Gamepad de Rede") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_PORT, - "Porta Base Remota de Rede" - ) + "Porta Base Remota de Rede") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_SETTINGS, - "Rede" - ) + "Rede") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO, - "Não" - ) + "Não") MSG_HASH(MENU_ENUM_LABEL_VALUE_NONE, - "Nenhum" - ) + "Nenhum") MSG_HASH(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE, - "N/D" - ) + "N/D") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ACHIEVEMENTS_TO_DISPLAY, - "Não há Conquistas para mostrar." - ) + "Não há Conquistas para mostrar.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE, - "Nenhum Núcleo" - ) + "Nenhum Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORES_AVAILABLE, - "Nenhum núcleo disponível" - ) + "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." - ) + "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." - ) + "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." - ) + "Não há itens para mostrar.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_HISTORY_AVAILABLE, - "Não há histórico disponível." - ) + "Não há histórico disponível.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE, - "Não há informação disponível." - ) + "Não há informação disponível.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ITEMS, - "Sem itens." - ) + "Sem itens.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETPLAY_HOSTS_FOUND, - "Nenhum hospedeiro de Netplay encontrado." - ) + "Nenhum hospedeiro de Netplay encontrado.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, - "Nenhuma rede encontrada." - ) + "Nenhuma rede encontrada.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, - "Não há contadores de desempenho." - ) + "Não há contadores de desempenho.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, - "Não há listas de reprodução." - ) + "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íveis." - ) + "Não há itens de lista de reprodução disponíveis.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, - "Nenhuma configuração encontrada." - ) + "Nenhuma configuração encontrada.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, - "Não há parâmetros de Shader." - ) + "Não há parâmetros de Shader.") MSG_HASH(MENU_ENUM_LABEL_VALUE_OFF, - "DESLIGADO" - ) + "DESLIGADO") MSG_HASH(MENU_ENUM_LABEL_VALUE_ON, - "LIGADO" - ) + "LIGADO") MSG_HASH(MENU_ENUM_LABEL_VALUE_ONLINE, - "Online" - ) + "Online") MSG_HASH(MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER, - "Atualizador Online" - ) + "Atualizador Online") MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS, - "Exibição na Tela" - ) + "Exibição na Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS, - "Transparência na Tela" - ) + "Transparência na Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS, - "Notificações na Tela" - ) + "Notificações na Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_OPEN_ARCHIVE, - "Navegar no Arquivo" - ) + "Navegar no Arquivo") MSG_HASH(MENU_ENUM_LABEL_VALUE_OPTIONAL, - "Opcional" - ) + "Opcional") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY, - "Transparência" - ) + "Transparência") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED, - "Autocarregar Transparência Favorita" - ) + "Carraga Automaticamente Transparência Favorita") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_DIRECTORY, - "Transparência" - ) + "Transparência") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_OPACITY, - "Opacidade da Transparência" - ) + "Opacidade da Transparência") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_PRESET, - "Predefinição de Transparência" - ) + "Predefinição de Transparência") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_SCALE, - "Escala da Transparência" - ) + "Escala da Transparência") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS, - "Transparência na Tela" - ) + "Transparência na Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_PAL60_ENABLE, - "Utilizar Modo PAL60" - ) + "Utilizar Modo PAL60") MSG_HASH(MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY, - "Diretório superior" - ) + "Diretório superior") MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_LIBRETRO, - "Pausar quando o menu for ativado" - ) + "Pausar quando o menu for ativado") MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, - "Não rodar em segundo plano" - ) + "Não rodar em segundo plano") MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, - "Contadores de Desempenho" - ) + "Contadores de Desempenho") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, - "Listas de Reprodução" - ) + "Listas de Reprodução") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Lista de Reprodução" - ) + "Lista de Reprodução") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, - "Listas de Reprodução" - ) + "Listas de Reprodução") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, - "Suporte para Toque" - ) + "Suporte para Toque") MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, - "Porta" - ) + "Porta") MSG_HASH(MENU_ENUM_LABEL_VALUE_PRESENT, - "Presente" - ) + "Presente") MSG_HASH(MENU_ENUM_LABEL_VALUE_PRIVACY_SETTINGS, - "Privacidade" - ) + "Privacidade") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH, - "Sair do RetroArch" - ) + "Sair do RetroArch") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ANALOG, - "Analógico suportado" - ) + "Analógico suportado") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_BBFC_RATING, - "Classificação BBFC" - ) + "Classificação BBFC") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CERO_RATING, - "Classificação CERO" - ) + "Classificação CERO") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_COOP, - "Cooperativo suportado" - ) + "Cooperativo suportado") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CRC32, - "CRC32" - ) + "CRC32") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DESCRIPTION, - "Descrição" - ) + "Descrição") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DEVELOPER, - "Desenvolvedor" - ) + "Desenvolvedor") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_ISSUE, - "Edição da Revista Edge" - ) + "Edição da Revista Edge") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_RATING, - "Classificação da Revista Edge" - ) + "Classificação da Revista Edge") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_REVIEW, - "Análise da Revista Edge" - ) + "Análise da Revista Edge") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ELSPA_RATING, - "Classificação ELSPA" - ) + "Classificação ELSPA") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ENHANCEMENT_HW, - "Hardware de Aprimoramento" - ) + "Hardware de Aprimoramento") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ESRB_RATING, - "Classificação ESRB" - ) + "Classificação ESRB") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FAMITSU_MAGAZINE_RATING, - "Classificação da Revista Famitsu" - ) + "Classificação da Revista Famitsu") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FRANCHISE, - "Franquia" - ) + "Franquia") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_GENRE, - "Gênero" - ) + "Gênero") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_MD5, - "MD5" - ) + "MD5") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME, - "Nome" - ) + "Nome") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ORIGIN, - "Origem" - ) + "Origem") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PEGI_RATING, - "Classificação PEGI" - ) + "Classificação PEGI") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PUBLISHER, - "Editor" - ) + "Editor") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_MONTH, - "Mês de Lançamento" - ) + "Mês de Lançamento") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_YEAR, - "Ano de Lançamento" - ) + "Ano de Lançamento") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RUMBLE, - "Suporte para Vibração" - ) + "Suporte para Vibração") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SERIAL, - "Número de Série" - ) + "Número de Série") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SHA1, - "SHA1" - ) + "SHA1") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_START_CONTENT, - "Iniciar Conteúdo" - ) + "Iniciar Conteúdo") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, - "Classificação TGDB" - ) + "Classificação TGDB") MSG_HASH(MENU_ENUM_LABEL_VALUE_REBOOT, - "Reiniciar" - ) + "Reiniciar") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY, - "Configuração de Gravação" - ) + "Configuração de Gravação") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_OUTPUT_DIRECTORY, - "Saída de Gravação" - ) + "Saída de Gravação") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, - "Gravação" - ) + "Gravação") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, - "Carregar Configuração de Gravação..." - ) + "Carregar Configuração de Gravação...") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_DRIVER, - "Driver de Gravação" - ) + "Driver de Gravação") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_ENABLE, - "Habilitar Gravação" - ) + "Habilitar Gravação") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_PATH, - "Salvar Saída de Gravação Como..." - ) + "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" - ) + "Salvar Gravações no Diretório de Saída") MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE, - "Arquivo de Remapeamento" - ) + "Arquivo de Remapeamento") MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_LOAD, - "Carregar Arquivo de Remapeamento" - ) + "Carregar Arquivo de Remapeamento") MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CORE, - "Salvar Arquivo de Remapeamento de Núcleo" - ) + "Salvar Arquivo de Remapeamento de Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_GAME, - "Salvar Arquivo de Remapeamento de Jogo" - ) + "Salvar Arquivo de Remapeamento de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_CORE, - "Remover Arquivo de Remapeamento de Núcleo" - ) + "Remover Arquivo de Remapeamento de Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_REMOVE_GAME, - "Remover Arquivo de Remapeamento de Jogo" - ) + "Remover Arquivo de Remapeamento de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_REQUIRED, - "Obrigatório" - ) + "Obrigatório") MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_CONTENT, - "Reiniciar" - ) + "Reiniciar") MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH, - "Reiniciar RetroArch" - ) + "Reiniciar RetroArch") MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME, - "Retomar" - ) + "Retomar") MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME_CONTENT, - "Retomar" - ) + "Retomar") MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROKEYBOARD, - "RetroKeyboard" - ) + "RetroKeyboard") MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD, - "RetroPad" - ) + "RetroPad") MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD_WITH_ANALOG, - "RetroPad com Analógico" - ) + "RetroPad com Analógico") MSG_HASH(MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS, - "Conquistas" - ) + "Conquistas") MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_ENABLE, - "Habilitar Voltar Atrás" - ) + "Habilitar Rebobinagem") MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_GRANULARITY, - "Granularidade do Voltar Atrás" - ) + "Granularidade da Rebobinagem") MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS, - "Voltar Atrás" - ) + "Rebobinagem") MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY, - "Navegador de Arquivos" - ) + "Navegador de Arquivos") MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY, - "Configuração" - ) + "Configuração") MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN, - "Mostrar Tela Inicial" - ) + "Mostrar Tela Inicial") MSG_HASH(MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG, - "Analógico Direito" - ) + "Analógico Direito") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES, - "Adicionar aos Favoritos" - ) + "Adicionar aos Favoritos") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST, - "Adicionar aos Favoritos" - ) + "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" - ) + "Executar") MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_MUSIC, - "Executar" - ) + "Executar") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAMBA_ENABLE, - "Habilitar SAMBA" - ) + "Habilitar SAMBA") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVEFILE_DIRECTORY, - "Arquivo de Jogo-Salvo" - ) + "Arquivo de Jogo-Salvo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX, - "Índice Automático de Estado de Jogo" - ) + "Índice Automático de Estado de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD, - "Autocarregar Estado de Jogo" - ) + "Carraga Automaticamente Estado de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE, - "Autosalvar Estado de Jogo" - ) + "Salvar Automaticamente Estado de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_DIRECTORY, - "Arquivo de Estado de Jogo" - ) + "Arquivo de Estado de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE, - "Miniaturas do Estado de Jogo" - ) + "Miniaturas do Estado de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG, - "Salvar Configuração Atual" - ) + "Salvar Configuração Atual") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, - "Salvar Redefinição de Núcleo" - ) + "Salvar Redefinição de Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, - "Salvar Redefinição de Jogo" - ) + "Salvar Redefinição de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_NEW_CONFIG, - "Salvar Nova Configuração" - ) + "Salvar Nova Configuração") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_STATE, - "Salvar Estado de Jogo" - ) + "Salvar Estado de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS, - "Salvando" - ) + "Salvando") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY, - "Analisar Diretório" - ) + "Analisar Diretório") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_FILE, - "Analisar Arquivo" - ) + "Analisar Arquivo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY, - "" - ) + "") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREENSHOT_DIRECTORY, - "Captura de Tela" - ) + "Captura de Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION, - "Resolução da Tela" - ) + "Resolução da Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_SEARCH, - "Procurar" - ) + "Procurar") MSG_HASH(MENU_ENUM_LABEL_VALUE_SECONDS, - "segundos" - ) + "segundos") MSG_HASH(MENU_ENUM_LABEL_VALUE_SETTINGS, - "Configurações" - ) + "Configurações") MSG_HASH(MENU_ENUM_LABEL_VALUE_SETTINGS_TAB, - "Configurações" - ) + "Configurações") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER, - "Shader" - ) + "Shader") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_APPLY_CHANGES, - "Aplicar Alterações" - ) + "Aplicar Alterações") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS, - "Shaders" - ) + "Shaders") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON, - "Faixa" - ) + "Faixa") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON_SIMPLIFIED, - "Faixa (simplificada)" - ) + "Faixa (simplificada)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SIMPLE_SNOW, - "Neve Simples" - ) + "Neve Simples") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOW, - "Neve" - ) + "Neve") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_ADVANCED_SETTINGS, - "Exibir Configurações Avançadas" - ) + "Exibir Configurações Avançadas") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_HIDDEN_FILES, - "Exibir Arquivos e Pastas Ocultos" - ) + "Exibir Arquivos e Pastas Ocultos") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHUTDOWN, - "Desligar" - ) + "Desligar") MSG_HASH(MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO, - "Taxa de Câmera Lenta" - ) + "Taxa de Câmera Lenta") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_ENABLED, + "Adiantar 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, + "Adiantar Usa uma Segunda Instância") MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVEFILES_ENABLE, - "Classificar Arquivos de Jogo-Salvo em Pastas" - ) + "Classificar Arquivos de Jogo-Salvo em Pastas") MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVESTATES_ENABLE, - "Classificar Arquivos de Estado de Jogo em Pastas" - ) + "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" - ) + "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" - ) + "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" - ) + "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" - ) + "Salvar Capturas de Tela no Diretório de Conteúdo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SSH_ENABLE, - "Habilitar SSH" - ) + "Habilitar SSH") MSG_HASH(MENU_ENUM_LABEL_VALUE_START_CORE, - "Iniciar Núcleo" - ) + "Iniciar Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_START_NET_RETROPAD, - "Iniciar RetroPad Remoto" - ) + "Iniciar RetroPad Remoto") MSG_HASH(MENU_ENUM_LABEL_VALUE_START_VIDEO_PROCESSOR, - "Iniciar Processador de Vídeo" - ) + "Iniciar Processador de Vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_STATE_SLOT, - "Compartimento do Estado de Jogo" - ) + "Compartimento do Estado de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_STATUS, - "Condição" - ) + "Condição") MSG_HASH(MENU_ENUM_LABEL_VALUE_STDIN_CMD_ENABLE, - "Comandos stdin" - ) + "Comandos stdin") MSG_HASH(MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES, - "Núcleos Sugeridos" - ) + "Núcleos Sugeridos") MSG_HASH(MENU_ENUM_LABEL_VALUE_SUSPEND_SCREENSAVER_ENABLE, - "Desativar Protetor de Tela" - ) + "Desativar Protetor de Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_BGM_ENABLE, - "Habilitar Música em Segundo Plano do Sistema" - ) + "Habilitar Música em Segundo Plano do Sistema") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_DIRECTORY, - "Sistema/BIOS" - ) + "Sistema/BIOS") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFORMATION, - "Informação do Sistema" - ) + "Informação do Sistema") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_7ZIP_SUPPORT, - "Suporte a 7zip" - ) + "Suporte a 7zip") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ALSA_SUPPORT, - "Suporte a ALSA" - ) + "Suporte a ALSA") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_BUILD_DATE, - "Data de Compilação" - ) + "Data de Compilação") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CG_SUPPORT, - "Suporte a Cg" - ) + "Suporte a Cg") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COCOA_SUPPORT, - "Suporte a Cocoa" - ) + "Suporte a Cocoa") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COMMAND_IFACE_SUPPORT, - "Suporte à Interface de Comando" - ) + "Suporte à Interface de Comando") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CORETEXT_SUPPORT, - "Suporte a CoreText" - ) + "Suporte a CoreText") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CPU_FEATURES, - "Características de CPU" - ) + "Características de CPU") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_DPI, - "Métrica DPI da Tela" - ) + "Métrica DPI da Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_HEIGHT, - "Métrica de Altura da Tela (mm)" - ) + "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)" - ) + "Métrica de Largura da Tela (mm)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DSOUND_SUPPORT, - "Suporte a DirectSound" - ) + "Suporte a DirectSound") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WASAPI_SUPPORT, - "Suporte a WASAPI" - ) + "Suporte a WASAPI") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYLIB_SUPPORT, - "Suporte à biblioteca dinâmica" - ) + "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" - ) + "Carregamento dinâmico em tempo de execução da biblioteca libretro") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_EGL_SUPPORT, - "Suporte a EGL" - ) + "Suporte a EGL") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FBO_SUPPORT, - "Suporte a OpenGL/Direct3D render-to-texture (multi-pass shaders)" - ) + "Suporte a OpenGL/Direct3D render-to-texture (multi-pass shaders)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FFMPEG_SUPPORT, - "Suporte a FFmpeg" - ) + "Suporte a FFmpeg") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FREETYPE_SUPPORT, - "Suporte a FreeType" - ) + "Suporte a FreeType") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_IDENTIFIER, - "Identificador do Frontend" - ) + "Identificador do Frontend") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_NAME, - "Nome do Frontend" - ) + "Nome do Frontend") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_OS, - "SO do Frontend" - ) + "SO do Frontend") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GIT_VERSION, - "Versão Git" - ) + "Versão Git") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GLSL_SUPPORT, - "Suporte a GLSL" - ) + "Suporte a GLSL") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_HLSL_SUPPORT, - "Suporte a HLSL" - ) + "Suporte a HLSL") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_JACK_SUPPORT, - "Suporte a JACK" - ) + "Suporte a JACK") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_KMS_SUPPORT, - "Suporte a KMS/EGL" - ) + "Suporte a KMS/EGL") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LAKKA_VERSION, - "Versão Lakka" - ) + "Versão Lakka") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, - "Suporte a LibretroDB" - ) + "Suporte a LibretroDB") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, - "Suporte a Libusb" - ) + "Suporte a Libusb") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "Suporte a libxml2 XML parsing" - ) + "Suporte a libxml2 XML parsing") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, - "Suporte Netplay (ponto-a-ponto)" - ) + "Suporte Netplay (ponto-a-ponto)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, - "Suporte à Interface de comando de rede" - ) + "Suporte à Interface de comando de rede") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_REMOTE_SUPPORT, - "Suporte a Gamepad de Rede" - ) + "Suporte a Gamepad de Rede") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENAL_SUPPORT, - "Suporte a OpenAL" - ) + "Suporte a OpenAL") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGLES_SUPPORT, - "Suporte a OpenGL ES" - ) + "Suporte a OpenGL ES") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGL_SUPPORT, - "Suporte a OpenGL" - ) + "Suporte a OpenGL") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENSL_SUPPORT, - "Suporte a OpenSL" - ) + "Suporte a OpenSL") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENVG_SUPPORT, - "Suporte a OpenVG" - ) + "Suporte a OpenVG") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OSS_SUPPORT, - "Suporte a OSS" - ) + "Suporte a OSS") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OVERLAY_SUPPORT, - "Suporte à Transparência" - ) + "Suporte à Transparência") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE, - "Fonte de Energia" - ) + "Fonte de Energia") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGED, - "Carregado" - ) + "Carregado") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGING, - "Carregando" - ) + "Carregando") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_DISCHARGING, - "Descarregando" - ) + "Descarregando") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_NO_SOURCE, - "Não há fonte" - ) + "Não há fonte") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PULSEAUDIO_SUPPORT, - "Suporte a PulseAudio" - ) + "Suporte a PulseAudio") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PYTHON_SUPPORT, - "Suporte a Python (suporte de script em Shaders)" - ) + "Suporte a Python (suporte de script em Shaders)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RBMP_SUPPORT, - "Suporte a BMP (RBMP)" - ) + "Suporte a BMP (RBMP)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RETRORATING_LEVEL, - "Nível RetroRating" - ) + "Nível RetroRating") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RJPEG_SUPPORT, - "Suporte a JPEG (RJPEG)" - ) + "Suporte a JPEG (RJPEG)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ROARAUDIO_SUPPORT, - "Suporte a RoarAudio" - ) + "Suporte a RoarAudio") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RPNG_SUPPORT, - "Suporte a PNG (RPNG)" - ) + "Suporte a PNG (RPNG)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RSOUND_SUPPORT, - "Suporte a RSound" - ) + "Suporte a RSound") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RTGA_SUPPORT, - "Suporte a TGA (RTGA)" - ) + "Suporte a TGA (RTGA)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL2_SUPPORT, - "Suporte a SDL2" - ) + "Suporte a SDL2") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_IMAGE_SUPPORT, - "Suporte a imagem SDL" - ) + "Suporte a imagem SDL") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_SUPPORT, - "Suporte a SDL1.2" - ) + "Suporte a SDL1.2") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SLANG_SUPPORT, - "Suporte a Slang" - ) + "Suporte a Slang") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_THREADING_SUPPORT, - "Suporte a Paralelismo" - ) + "Suporte a Paralelismo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_UDEV_SUPPORT, - "Suporte a Udev" - ) + "Suporte a Udev") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_V4L2_SUPPORT, - "Suporte a Video4Linux2" - ) + "Suporte a Video4Linux2") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VIDEO_CONTEXT_DRIVER, - "Driver de contexto de vídeo" - ) + "Driver de contexto de vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VULKAN_SUPPORT, - "Suporte a Vulkan" - ) + "Suporte a Vulkan") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WAYLAND_SUPPORT, - "Suporte a Wayland" - ) + "Suporte a Wayland") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_X11_SUPPORT, - "Suporte a X11" - ) + "Suporte a X11") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XAUDIO2_SUPPORT, - "Suporte a XAudio2" - ) + "Suporte a XAudio2") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XVIDEO_SUPPORT, - "Suporte a XVideo" - ) + "Suporte a XVideo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ZLIB_SUPPORT, - "Suporte a Zlib" - ) + "Suporte a Zlib") MSG_HASH(MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT, - "Capturar tela" - ) + "Capturar tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, - "Paralelismo de tarefas" - ) + "Paralelismo de tarefas") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS, - "Miniaturas" - ) + "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" - ) + "Miniaturas") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST, - "Atualizador de Miniaturas" - ) + "Atualizador de Miniaturas") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS, - "Arte da Embalagem" - ) + "Arte da Embalagem") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS, - "Captura de Tela" - ) + "Captura de Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS, - "Tela do Título" - ) + "Telas do Título") MSG_HASH(MENU_ENUM_LABEL_VALUE_TIMEDATE_ENABLE, - "Exibir data / hora" - ) + "Exibir data e hora") MSG_HASH(MENU_ENUM_LABEL_VALUE_TITLE_COLOR, - "Cor do título do menu" - ) + "Cor do título do menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_TRUE, - "Verdadeiro" - ) + "Verdadeiro") MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_ENABLE, - "Habilitar Companheiro da Interface de Usuário" - ) + "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" - ) + "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" - ) + "Barra de Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE, - "Incapaz de ler o arquivo comprimido." - ) + "Incapaz de ler o arquivo comprimido.") MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_LOAD_STATE, - "Desfazer Carregamento de Estado de Jogo" - ) + "Desfazer Carregamento de Estado de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_SAVE_STATE, - "Desfazer Salvamento de Estado de Jogo" - ) + "Desfazer Salvamento de Estado de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_UNKNOWN, - "Desconhecido" - ) + "Desconhecido") MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS, - "Atualizador" - ) + "Atualizador") MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_ASSETS, - "Atualizar Recursos" - ) + "Atualizar Recursos") MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_AUTOCONFIG_PROFILES, - "Atualizar Perfis de Autoconfiguração" - ) + "Atualizar Perfis de Autoconfiguração") MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CG_SHADERS, - "Atualizar Shaders Cg" - ) + "Atualizar Shaders Cg") MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CHEATS, - "Atualizar Trapaças" - ) + "Atualizar Trapaças") MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CORE_INFO_FILES, - "Atualizar Arquivos de Informação de Núcleo" - ) + "Atualizar Arquivos de Informação de Núcleo") MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_DATABASES, - "Atualizar Bases de Dados" - ) + "Atualizar Bases de Dados") MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_GLSL_SHADERS, - "Atualizar Shaders GLSL" - ) + "Atualizar Shaders GLSL") MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_LAKKA, - "Atualizar Lakka" - ) + "Atualizar Lakka") MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_OVERLAYS, - "Atualizar Transparências" - ) + "Atualizar Transparências") MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_SLANG_SHADERS, - "Atualizar Shaders Slang" - ) + "Atualizar Shaders Slang") MSG_HASH(MENU_ENUM_LABEL_VALUE_USER, - "Usuário" - ) + "Usuário") +MSG_HASH(MENU_ENUM_LABEL_VALUE_KEYBOARD, + "Kbd") MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS, - "Interface de Usuário" - ) + "Interface de Usuário") MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_LANGUAGE, - "Idioma" - ) + "Idioma") MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_SETTINGS, - "Usuário" - ) + "Usuário") MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER, - "Utilizar o Visualizador de Imagem Integrado" - ) + "Utilizar o Visualizador de Imagem Integrado") MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_BUILTIN_PLAYER, - "Utilizar o Reprodutor de Mídia Integrado" - ) + "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" - ) + "Permitir rotação") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO, - "Configurar Proporção de Tela" - ) + "Configurar Proporção de Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_AUTO, - "Proporção de Tela Automática" - ) + "Proporção de Tela Automática") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, - "Proporção de Tela" - ) + "Proporção de Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, - "Inserção de Quadro Opaco" - ) + "Inserção de Quadro Opaco") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, - "Cortar Overscan (Recarregar)" - ) + "Cortar Overscan (Recarregar)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, - "Desativar Composição da Área de Trabalho" - ) + "Desativar Composição da Área de Trabalho") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, - "Driver de Vídeo" - ) + "Driver de Vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, - "Filtro de Vídeo" - ) + "Filtro de Vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_DIR, - "Filtro de Vídeo" - ) + "Filtro de Vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_FLICKER, - "Filtro de tremulação de vídeo" - ) + "Filtro de tremulação de vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_ENABLE, - "Habilitar Notificações na Tela" - ) + "Habilitar Notificações na Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_PATH, - "Fonte das Notificações na Tela" - ) + "Fonte das Notificações na Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_SIZE, - "Tamanho da Notificação na Tela" - ) + "Tamanho da Notificação na Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_ASPECT, - "Forçar Proporção de Tela" - ) + "Forçar Proporção de Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_SRGB_DISABLE, - "Forçar Desativação de sRGB FBO" - ) + "Forçar Desativação de sRGB FBO") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FRAME_DELAY, - "Atraso de Quadro" - ) + "Atraso de Quadro") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN, - "Utilizar Modo de Tela Cheia" - ) + "Utilizar Modo de Tela Cheia") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GAMMA, - "Gama de Vídeo" - ) + "Gama de Vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GPU_RECORD, - "Usar Gravação da GPU" - ) + "Usar Gravação da GPU") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT, - "Habilitar Captura de Tela da GPU" - ) + "Habilitar Captura de Tela da GPU") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, - "Sincronia Rígida de GPU" - ) + "Sincronia Rígida de GPU") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES, - "Quadros de Sincronia Rígida de GPU" - ) + "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" - ) + "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" - ) + "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" - ) + "Posição Y da Notificação na Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MONITOR_INDEX, - "Índice de Monitor" - ) + "Índice de Monitor") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_POST_FILTER_RECORD, - "Usar Gravação Pós-Filtro" - ) + "Usar Gravação Pós-Filtro") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, - "Taxa de Atualização Vertical" - ) + "Taxa de Atualização Vertical") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, - "Taxa de Quadros Estimada da Tela" - ) + "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" - ) + "Rotação") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, - "Escala em Janela" - ) + "Escala em Janela") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER, - "Escala em Inteiros" - ) + "Escala em Inteiros") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS, - "Vídeo" - ) + "Vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DIR, - "Shader de Vídeo" - ) + "Shader de Vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_NUM_PASSES, - "Estágios de Shader" - ) + "Estágios de Shader") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS, - "Pré-visualizar Parâmetros de Shader" - ) + "Pré-visualizar Parâmetros de Shader") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET, - "Carregar Predefinição de Shader" - ) + "Carregar Predefinição de Shader") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS, - "Salvar Predefinição de Shader Como" - ) + "Salvar Predefinição de Shader Como") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE, - "Salvar Predefinição de Núcleo" - ) + "Salvar Predefinição de Núcleo") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_PARENT, + "Salvar Predefinição de Diretório de Conteúdo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME, - "Salvar Predefinição de Jogo" - ) + "Salvar Predefinição de Jogo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT, - "Habilitar Contexto Compartilhado de Hardware" - ) + "Habilitar Contexto Compartilhado de Hardware") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH, - "Filtragem Bilinear" - ) + "Filtragem Bilinear") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER, - "Habilitar Filtro por Software" - ) + "Habilitar Filtro por Software") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SWAP_INTERVAL, - "Intervalo de Troca da Sincronização Vertical (V-Sync)" - ) + "Intervalo de Troca da Sincronização Vertical (V-Sync)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_TAB, - "Vídeo" - ) + "Vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_THREADED, - "Vídeo Paralelizado" - ) + "Vídeo Paralelizado") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VFILTER, - "Reduzir Tremulação de Vídeo" - ) + "Reduzir Tremulação de Vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_HEIGHT, - "Altura Personalizada da Proporção de Tela" - ) + "Altura Personalizada da Proporção de Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_WIDTH, - "Largura Personalizada da Proporção de Tela" - ) + "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" - ) + "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" - ) + "Posição Y Personalizada da Proporção de Tela") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, - "Definir Largura de Tela do VI" - ) + "Definir Largura de Tela do VI") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, - "Sincronização Vertical (V-Sync)" - ) + "Sincronização Vertical (V-Sync)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, - "Modo Janela em Tela Cheia" - ) + "Modo Janela em Tela Cheia") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_WIDTH, - "Largura da Janela" - ) + "Largura da Janela") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_HEIGHT, - "Altura da Janela" - ) + "Altura da Janela") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_X, - "Largura em Tela Cheia" - ) + "Largura em Tela Cheia") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_Y, - "Altura em Tela Cheia" - ) + "Altura em Tela Cheia") MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_DRIVER, - "Driver de Wi-Fi" - ) + "Driver de Wi-Fi") MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, - "Wi-Fi" - ) + "Wi-Fi") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, - "Fator Alfa do Menu" - ) + "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" - ) + "Fonte do Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, - "Personalizado" - ) + "Personalizado") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_FLATUI, - "FlatUI" - ) + "FlatUI") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME, - "Monocromático" - ) + "Monocromático") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME_INVERTED, - "Monocromático Inverted" - ) + "Monocromático Invertido") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_SYSTEMATIC, - "Sistemático" - ) + "Sistemático") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_NEOACTIVE, - "NeoActive" - ) + "NeoActive") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL, - "Pixel" - ) + "Pixel") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE, - "RetroActive" - ) + "RetroActive") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM, - "Retrosystem" - ) + "Retrosystem") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART, - "Dot-Art" - ) + "Dot-Art") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME, - "Tema de Cor do Menu" - ) + "Tema de Cor do Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_APPLE_GREEN, - "Verde Maçã" - ) + "Verde Maçã") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK, - "Escuro" - ) + "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" - ) + "Roxo Escuro") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_ELECTRIC_BLUE, - "Azul Elétrico" - ) + "Azul Elétrico") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_GOLDEN, - "Dourado" - ) + "Dourado") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LEGACY_RED, - "Vermelho Legado" - ) + "Vermelho Legado") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MIDNIGHT_BLUE, - "Azul Meia-noite" - ) + "Azul Meia-noite") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_PLAIN, - "Natural" - ) + "Natural") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_UNDERSEA, - "Submarino" - ) + "Submarino") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_VOLCANIC_RED, - "Vermelho Vulcânico" - ) + "Vermelho Vulcânico") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_RIBBON_ENABLE, - "Pipeline do Shader de Menu" - ) + "Pipeline do Shader de Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SCALE_FACTOR, - "Fator de Escala do Menu" - ) + "Fator de Escala do Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE, - "Habilitar Sombras dos Ícones" - ) + "Habilitar Sombras dos Ícones") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_HISTORY, - "Exibir Aba de Histórico" - ) + "Exibir Aba de Histórico") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_ADD, - "Exibir Aba de Importação de Conteúdo" - ) + "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" - ) + "Exibir Aba de Favoritos") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_IMAGES, - "Exibir Aba de Imagem" - ) + "Exibir Aba de Imagem") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_MUSIC, - "Exibir Aba de Música" - ) + "Exibir Aba de Música") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, - "Exibir Aba de Configurações" - ) + "Exibir Aba de Configurações") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, - "Exibir Aba de Vídeo" - ) + "Exibir Aba de Vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, - "Exibir Aba de 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" - ) + "Tema de Ícones do Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, - "Sim" - ) + "Sim") MSG_HASH(MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO, - "Predefinição de Shader" - ) + "Predefinição de Shader") MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, - "Habilitar ou desabilitar conquistas. Para mais informações, visite http://retroachievements.org" - ) + "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." - ) + "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, Voltar Atrás, Avanço Rápido, Pausa e Câmera Lenta para todos os jogos." - ) + "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." - ) + "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." - ) + "Alterar os drivers utilizados pelo sistema.") MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, - "Alterar as configurações de conquistas." - ) + "Alterar as configurações de conquistas.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_SETTINGS, - "Alterar as configurações de núcleo." - ) + "Alterar as configurações de núcleo.") MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_SETTINGS, - "Alterar as configurações de gravação." - ) + "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." - ) + "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 Voltar Atrás, Avanço Rápido e Câmera Lenta." - ) + "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." - ) + "Alterar as configurações de salvamento.") MSG_HASH(MENU_ENUM_SUBLABEL_LOGGING_SETTINGS, - "Alterar as configurações de registro de eventos." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "Alterar as configurações de lista de reprodução.") MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, - "Configurar as configurações de servidor e rede." - ) + "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." - ) + "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." - ) + "Alterar as configurações de saída de áudio.") MSG_HASH(MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE, - "Habilitar ou desabilitar o bluetooth." - ) + "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." - ) + "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." - ) + "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." - ) + "Gerenciar e criar arquivos de configuração.") MSG_HASH(MENU_ENUM_SUBLABEL_CPU_CORES, - "Quantidade de Cores que a CPU possui." - ) + "Quantidade de Cores que a CPU possui.") MSG_HASH(MENU_ENUM_SUBLABEL_FPS_SHOW, - "Exibir a taxa atual de quadros por segundo na tela." - ) + "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." - ) + "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." - ) + "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." - ) + "Alterar as configurações de Joypad, teclado e Mouse.") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_USER_BINDS, - "Configurar os controles para este usuário." - ) + "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." - ) + "Habilitar ou desabilitar registro de eventos no terminal.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, - "Juntar-se ou hospedar uma sessão de 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." - ) + "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." - ) + "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." - ) + "Baixar complementos, componentes e conteúdo para o RetroArch.") MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, - "Habilitar ou desabilitar compartilhamento de pastas na rede." - ) + "Habilitar ou desabilitar compartilhamento de pastas na rede.") MSG_HASH(MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, - "Gerenciar serviços ao nível de sistema operacional." - ) + "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." - ) + "Exibir arquivos/diretórios ocultos no navegador de arquivos.") MSG_HASH(MENU_ENUM_SUBLABEL_SSH_ENABLE, - "Habilitar ou desabilitar acesso remoto à linha de comando." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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)." - ) + "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'." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "Analisar por redes sem fio e estabelecer uma conexão.") MSG_HASH(MENU_ENUM_SUBLABEL_HELP_LIST, - "Saiba mais sobre como o programa funciona." - ) + "Saiba mais sobre como o programa funciona.") MSG_HASH(MSG_ADDED_TO_FAVORITES, - "Adicionado aos favoritos" - ) + "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" - ) + "Disco anexado") MSG_HASH(MSG_APPLICATION_DIR, - "Diretório do aplicativo" - ) + "Diretório do aplicativo") MSG_HASH(MSG_APPLYING_CHEAT, - "Aplicando as alterações de Trapaças." - ) + "Aplicando as alterações de Trapaças.") MSG_HASH(MSG_APPLYING_SHADER, - "Aplicando Shader" - ) + "Aplicando Shader") MSG_HASH(MSG_AUDIO_MUTED, - "Áudio mudo." - ) + "Áudio mudo.") MSG_HASH(MSG_AUDIO_UNMUTED, - "Áudio mudo desativado." - ) + "Áudio mudo desativado.") MSG_HASH(MSG_AUTOCONFIG_FILE_ERROR_SAVING, - "Erro em salvar o arquivo de autoconfiguração." - ) + "Erro em salvar o arquivo de autoconfiguração.") MSG_HASH(MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY, - "Arquivo de autoconfiguração salvo com sucesso." - ) + "Arquivo de autoconfiguração salvo com sucesso.") MSG_HASH(MSG_AUTOSAVE_FAILED, - "Não foi possível inicializar o autossalvamento." - ) + "Não foi possível inicializar o salvamento automático.") MSG_HASH(MSG_AUTO_SAVE_STATE_TO, - "Autosalvar Estado de Jogo em" - ) + "Salvar Automaticamente Estado de Jogo em") MSG_HASH(MSG_BLOCKING_SRAM_OVERWRITE, - "Bloqueando Sobrescrita da SRAM" - ) + "Bloqueando Sobrescrita da SRAM") MSG_HASH(MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT, - "Trazendo a interface de comando na porta" - ) + "Trazendo a interface de comando na porta") MSG_HASH(MSG_BYTES, - "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." - ) + "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 Voltar Atrás estão desabilitados." - ) + "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..." - ) + "Comparando com números mágicos conhecidos...") MSG_HASH(MSG_COMPILED_AGAINST_API, - "Compilado contra a 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." - ) + "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" - ) + "Conectado a") MSG_HASH(MSG_CONTENT_CRC32S_DIFFER, - "O CRC32 dos conteúdos difere. Não é possível utilizar jogos diferentes." - ) + "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." - ) + "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." - ) + "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." - ) + "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" - ) + "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." - ) + "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" - ) + "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" - ) + "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" - ) + "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." - ) + "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." - ) + "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." - ) + "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" - ) + "Tempo personalizado fornecido") MSG_HASH(MSG_DECOMPRESSION_ALREADY_IN_PROGRESS, - "Descompressão já está em andamento." - ) + "Descompressão já está em andamento.") MSG_HASH(MSG_DECOMPRESSION_FAILED, - "Descompressão falhou." - ) + "Descompressão falhou.") MSG_HASH(MSG_DETECTED_VIEWPORT_OF, - "Detectada janela de exibição de" - ) + "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." - ) + "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." - ) + "Desconectar dispositivo de uma porta válida.") MSG_HASH(MSG_DISK_CLOSED, - "Fechado" - ) + "Fechado") MSG_HASH(MSG_DISK_EJECTED, - "Ejetado" - ) + "Ejetado") MSG_HASH(MSG_DOWNLOADING, - "Baixando" - ) + "Baixando") +MSG_HASH(MSG_INDEX_FILE, + "index") MSG_HASH(MSG_DOWNLOAD_FAILED, - "Download falhou" - ) + "Download falhou") MSG_HASH(MSG_ERROR, - "Erro" - ) + "Erro") MSG_HASH(MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT, - "O núcleo libretro requer conteúdo, mas nada foi fornecido." - ) + "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." - ) + "O núcleo libretro requer conteúdo especial, mas nenhum foi fornecido.") MSG_HASH(MSG_ERROR_PARSING_ARGUMENTS, - "Erro em analisar os argumentos." - ) + "Erro em analisar os argumentos.") MSG_HASH(MSG_ERROR_SAVING_CORE_OPTIONS_FILE, - "Erro em salvar o arquivo de opções de núcleo." - ) + "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." - ) + "Erro em salvar o arquivo de remapeamento.") MSG_HASH(MSG_ERROR_REMOVING_REMAP_FILE, - "Erro em remover o arquivo de remapeamento." - ) + "Erro em remover o arquivo de remapeamento.") MSG_HASH(MSG_ERROR_SAVING_SHADER_PRESET, - "Erro em salvar a predefinição de Shader." - ) + "Erro em salvar a predefinição de Shader.") MSG_HASH(MSG_EXTERNAL_APPLICATION_DIR, - "Diretório de Aplicativo Externo" - ) + "Diretório de Aplicativo Externo") MSG_HASH(MSG_EXTRACTING, - "Extraindo" - ) + "Extraindo") MSG_HASH(MSG_EXTRACTING_FILE, - "Extraindo arquivo" - ) + "Extraindo arquivo") MSG_HASH(MSG_FAILED_SAVING_CONFIG_TO, - "Falha em salvar a configuração em" - ) + "Falha em salvar a configuração em") MSG_HASH(MSG_FAILED_TO, - "Falha em" - ) + "Falha em") MSG_HASH(MSG_FAILED_TO_ACCEPT_INCOMING_SPECTATOR, - "Falha em aceitar o espectador ingresso." - ) + "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..." - ) + "Falha em alocar memória para o conteúdo modificado...") MSG_HASH(MSG_FAILED_TO_APPLY_SHADER, - "Falha em aplicar o Shader." - ) + "Falha em aplicar o Shader.") MSG_HASH(MSG_FAILED_TO_BIND_SOCKET, - "Falha em vincular o soquete." - ) + "Falha em vincular o soquete.") MSG_HASH(MSG_FAILED_TO_CREATE_THE_DIRECTORY, - "Falha em criar o diretório." - ) + "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" - ) + "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." - ) + "Falha em obter o apelido do cliente.") MSG_HASH(MSG_FAILED_TO_LOAD, - "Falha em carregar" - ) + "Falha em carregar") MSG_HASH(MSG_FAILED_TO_LOAD_CONTENT, - "Falha em carregar o conteúdo" - ) + "Falha em carregar o conteúdo") MSG_HASH(MSG_FAILED_TO_LOAD_MOVIE_FILE, - "Falha em carregar o arquivo de filme" - ) + "Falha em carregar o arquivo de filme") MSG_HASH(MSG_FAILED_TO_LOAD_OVERLAY, - "Falha em carregar a Transparência." - ) + "Falha em carregar a Transparência.") MSG_HASH(MSG_FAILED_TO_LOAD_STATE, - "Falha em carregar o Estado de Jogo de" - ) + "Falha em carregar o Estado de Jogo de") MSG_HASH(MSG_FAILED_TO_OPEN_LIBRETRO_CORE, - "Falha em abrir o núcleo Libretro" - ) + "Falha em abrir o núcleo Libretro") MSG_HASH(MSG_FAILED_TO_PATCH, - "Falha em executar a modificação" - ) + "Falha em executar a modificação") MSG_HASH(MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT, - "Falha em receber o cabeçalho do cliente." - ) + "Falha em receber o cabeçalho do cliente.") MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME, - "Falha em receber o apelido." - ) + "Falha em receber o apelido.") MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST, - "Falha em receber o apelido do hospedeiro." - ) + "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." - ) + "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." - ) + "Falha em receber os dados SRAM do hospedeiro.") MSG_HASH(MSG_FAILED_TO_REMOVE_DISK_FROM_TRAY, - "Falha em remover o disco da bandeja." - ) + "Falha em remover o disco da bandeja.") MSG_HASH(MSG_FAILED_TO_REMOVE_TEMPORARY_FILE, - "Falha em remover o arquivo temporário" - ) + "Falha em remover o arquivo temporário") MSG_HASH(MSG_FAILED_TO_SAVE_SRAM, - "Falha em salvar SRAM" - ) + "Falha em salvar SRAM") MSG_HASH(MSG_FAILED_TO_SAVE_STATE_TO, - "Falha em salvar o Estado de Jogo em" - ) + "Falha em salvar o Estado de Jogo em") MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME, - "Falha em enviar o apelido." - ) + "Falha em enviar o apelido.") MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_SIZE, - "Falha em enviar o tamanho do apelido." - ) + "Falha em enviar o tamanho do apelido.") MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT, - "Falha em enviar o apelido para o cliente." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "Falha em iniciar a gravação do filme.") MSG_HASH(MSG_FAILED_TO_START_RECORDING, - "Falha em iniciar a gravação." - ) + "Falha em iniciar a gravação.") MSG_HASH(MSG_FAILED_TO_TAKE_SCREENSHOT, - "Falha em obter uma captura de tela." - ) + "Falha em obter uma captura de tela.") MSG_HASH(MSG_FAILED_TO_UNDO_LOAD_STATE, - "Falha em desfazer o carregamento de Estado de Jogo." - ) + "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." - ) + "Falha em desfazer o salvamento de Estado de Jogo.") MSG_HASH(MSG_FAILED_TO_UNMUTE_AUDIO, - "Falha em desativar o áudio mudo." - ) + "Falha em desativar o áudio mudo.") MSG_HASH(MSG_FATAL_ERROR_RECEIVED_IN, - "Erro fatal recebido em" - ) + "Erro fatal recebido em") MSG_HASH(MSG_FILE_NOT_FOUND, - "Arquivo não encontrado" - ) + "Arquivo não encontrado") MSG_HASH(MSG_FOUND_AUTO_SAVESTATE_IN, - "Estado de Jogo automático encontrado em" - ) + "Estado de Jogo automático encontrado em") MSG_HASH(MSG_FOUND_DISK_LABEL, - "Rótulo de disco encontrado" - ) + "Rótulo de disco encontrado") MSG_HASH(MSG_FOUND_FIRST_DATA_TRACK_ON_FILE, - "Encontrada primeira faixa de dados no arquivo" - ) + "Encontrada primeira faixa de dados no arquivo") MSG_HASH(MSG_FOUND_LAST_STATE_SLOT, - "Encontrada último compartimento de Estado de Jogo" - ) + "Encontrada último compartimento de Estado de Jogo") MSG_HASH(MSG_FOUND_SHADER, - "Shader encontrado" - ) + "Shader encontrado") MSG_HASH(MSG_FRAMES, - "Quadros" - ) + "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" - ) + "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" - ) + "Índice de disco inválido obtido") MSG_HASH(MSG_GRAB_MOUSE_STATE, - "Capturar estado do Mouse" - ) + "Capturar estado do Mouse") MSG_HASH(MSG_GAME_FOCUS_ON, - "Foco do jogo ligado" - ) + "Foco do jogo ligado") MSG_HASH(MSG_GAME_FOCUS_OFF, - "Foco do jogo desligado" - ) + "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." - ) + "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." - ) + "A soma de verificação inflada não corresponde ao CRC32.") MSG_HASH(MSG_INPUT_CHEAT, - "Entrada de Trapaça" - ) + "Entrada de Trapaça") MSG_HASH(MSG_INPUT_CHEAT_FILENAME, - "Nome do Arquivo de Trapaça" - ) + "Nome do Arquivo de Trapaça") MSG_HASH(MSG_INPUT_PRESET_FILENAME, - "Nome de Arquivo de Predefinição" - ) + "Nome de Arquivo de Predefinição") MSG_HASH(MSG_INPUT_RENAME_ENTRY, - "Renomear Título" - ) + "Renomear Título") MSG_HASH(MSG_INTERFACE, - "Interface" - ) + "Interface") MSG_HASH(MSG_INTERNAL_STORAGE, - "Armazenamento Interno" - ) + "Armazenamento Interno") MSG_HASH(MSG_REMOVABLE_STORAGE, - "Armazenamento Removível" - ) + "Armazenamento Removível") MSG_HASH(MSG_INVALID_NICKNAME_SIZE, - "Tamanho de apelido inválido." - ) + "Tamanho de apelido inválido.") MSG_HASH(MSG_IN_BYTES, - "em bytes" - ) + "em bytes") MSG_HASH(MSG_IN_GIGABYTES, - "em gigabytes" - ) + "em gigabytes") MSG_HASH(MSG_IN_MEGABYTES, - "em megabytes" - ) + "em megabytes") MSG_HASH(MSG_LIBRETRO_ABI_BREAK, - "foi compilado contra uma versão diferente do libretro do que esta." - ) + "foi compilado contra uma versão diferente do libretro do que esta.") MSG_HASH(MSG_LIBRETRO_FRONTEND, - "Frontend para Libretro" - ) + "Frontend para Libretro") MSG_HASH(MSG_LOADED_STATE_FROM_SLOT, - "Estado de Jogo carregado do compartimento #%d." - ) + "Estado de Jogo carregado do compartimento #%d.") MSG_HASH(MSG_LOADED_STATE_FROM_SLOT_AUTO, - "Estado de Jogo carregado do compartimento #-1 (automático)." - ) + "Estado de Jogo carregado do compartimento #-1 (automático).") MSG_HASH(MSG_LOADING, - "Carregando" - ) + "Carregando") MSG_HASH(MSG_FIRMWARE, - "Um ou mais arquivos de firmware estão faltando" - ) + "Um ou mais arquivos de firmware estão faltando") MSG_HASH(MSG_LOADING_CONTENT_FILE, - "Carregando arquivo de conteúdo" - ) + "Carregando arquivo de conteúdo") MSG_HASH(MSG_LOADING_HISTORY_FILE, - "Carregando arquivo de histórico" - ) + "Carregando arquivo de histórico") MSG_HASH(MSG_LOADING_STATE, - "Carregando Estado de Jogo" - ) + "Carregando Estado de Jogo") MSG_HASH(MSG_MEMORY, - "Memória" - ) + "Memória") MSG_HASH(MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE, - "O arquivo de filme não é um arquivo BSV1 válido." - ) + "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." - ) + "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." - ) + "Reprodução de filme terminou.") MSG_HASH(MSG_MOVIE_RECORD_STOPPED, - "Parando a gravação de filme." - ) + "Parando a gravação de filme.") MSG_HASH(MSG_NETPLAY_FAILED, - "Falha em inicializar o Netplay." - ) + "Falha em inicializar o Netplay.") MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE, - "Sem conteúdo, iniciando um núcleo modelo." - ) + "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." - ) + "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." - ) + "Nenhum Estado de Jogo foi carregado até o momento.") MSG_HASH(MSG_OVERRIDES_ERROR_SAVING, - "Erro em salvar as redefinições." - ) + "Erro em salvar as redefinições.") MSG_HASH(MSG_OVERRIDES_SAVED_SUCCESSFULLY, - "Redefinições salvas com sucesso." - ) + "Redefinições salvas com sucesso.") MSG_HASH(MSG_PAUSED, - "Pausado." - ) + "Pausado.") MSG_HASH(MSG_PROGRAM, - "RetroArch" - ) + "RetroArch") MSG_HASH(MSG_READING_FIRST_DATA_TRACK, - "Lendo a primeira faixa de dados..." - ) + "Lendo a primeira faixa de dados...") MSG_HASH(MSG_RECEIVED, - "recebido" - ) + "recebido") MSG_HASH(MSG_RECORDING_TERMINATED_DUE_TO_RESIZE, - "A gravação terminou devido ao redimensionamento." - ) + "A gravação terminou devido ao redimensionamento.") MSG_HASH(MSG_RECORDING_TO, - "Gravando em" - ) + "Gravando em") MSG_HASH(MSG_REDIRECTING_CHEATFILE_TO, - "Redirecionando o arquivo de Trapaça em" - ) + "Redirecionando o arquivo de Trapaça em") MSG_HASH(MSG_REDIRECTING_SAVEFILE_TO, - "Redirecionando o Jogo-Salvo em" - ) + "Redirecionando o Jogo-Salvo em") MSG_HASH(MSG_REDIRECTING_SAVESTATE_TO, - "Redirecionando o Estado de Jogo em" - ) + "Redirecionando o Estado de Jogo em") MSG_HASH(MSG_REMAP_FILE_SAVED_SUCCESSFULLY, - "Arquivo de remapeamento salvo com sucesso." - ) + "Arquivo de remapeamento salvo com sucesso.") MSG_HASH(MSG_REMAP_FILE_REMOVED_SUCCESSFULLY, - "Arquivo de remapeamento salvo com sucesso." - ) + "Arquivo de remapeamento salvo com sucesso.") MSG_HASH(MSG_REMOVED_DISK_FROM_TRAY, - "Disco removido da bandeja." - ) + "Disco removido da bandeja.") MSG_HASH(MSG_REMOVING_TEMPORARY_CONTENT_FILE, - "Removendo arquivo de conteúdo temporário" - ) + "Removendo arquivo de conteúdo temporário") MSG_HASH(MSG_RESET, - "Reinicializar" - ) + "Reinicializar") MSG_HASH(MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT, - "Reiniciando a gravação devido ao reinício do driver." - ) + "Reiniciando a gravação devido ao reinício do driver.") MSG_HASH(MSG_RESTORED_OLD_SAVE_STATE, - "Estado de Jogo antigo restaurado." - ) + "Estado de Jogo antigo restaurado.") MSG_HASH(MSG_RESTORING_DEFAULT_SHADER_PRESET_TO, - "Shaders: restaurando predefinição padrão de Shader em" - ) + "Shaders: restaurando predefinição padrão de Shader em") MSG_HASH(MSG_REVERTING_SAVEFILE_DIRECTORY_TO, - "Revertendo diretório de Jogo-Salvo em" - ) + "Revertendo diretório de Jogo-Salvo em") MSG_HASH(MSG_REVERTING_SAVESTATE_DIRECTORY_TO, - "Revertendo diretório de Estado de Jogo em" - ) + "Revertendo diretório de Estado de Jogo em") MSG_HASH(MSG_REWINDING, - "Voltando atrás." - ) + "Voltando atrás.") MSG_HASH(MSG_REWIND_INIT, - "Inicializando o buffer de Voltar Atrás com tamanho" - ) + "Inicializando o buffer de Rebobinagem com tamanho") MSG_HASH(MSG_REWIND_INIT_FAILED, - "Falha em inicializar o buffer de Voltar Atrás. Voltar Atrás será desativado." - ) + "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 Voltar Atrás." - ) + "Esta implementação usa áudio paralelizado. Não é possível utilizar Rebobinagem.") MSG_HASH(MSG_REWIND_REACHED_END, - "Final do buffer de Voltar Atrás atingido." - ) + "Final do buffer de Rebobinagem atingido.") MSG_HASH(MSG_SAVED_NEW_CONFIG_TO, - "Nova configuração salva em" - ) + "Nova configuração salva em") MSG_HASH(MSG_SAVED_STATE_TO_SLOT, - "Estado de Jogo salvo no compartimento #%d." - ) + "Estado de Jogo salvo no compartimento #%d.") MSG_HASH(MSG_SAVED_STATE_TO_SLOT_AUTO, - "Estado de Jogo salvo no compartimento #-1 (automático)." - ) + "Estado de Jogo salvo no compartimento #-1 (automático).") MSG_HASH(MSG_SAVED_SUCCESSFULLY_TO, - "Salvo com sucesso em" - ) + "Salvo com sucesso em") MSG_HASH(MSG_SAVING_RAM_TYPE, - "Salvando Tipo de RAM" - ) + "Salvando Tipo de RAM") MSG_HASH(MSG_SAVING_STATE, - "Salvando Estado de Jogo" - ) + "Salvando Estado de Jogo") MSG_HASH(MSG_SCANNING, - "Analisando" - ) + "Analisando") MSG_HASH(MSG_SCANNING_OF_DIRECTORY_FINISHED, - "Análise de diretório terminada" - ) + "Análise de diretório terminada") MSG_HASH(MSG_SENDING_COMMAND, - "Enviando comando" - ) + "Enviando comando") MSG_HASH(MSG_SEVERAL_PATCHES_ARE_EXPLICITLY_DEFINED, - "Várias modificações de conteúdo estão explicitamente definidas, ignorando todas..." - ) + "Várias modificações de conteúdo estão explicitamente definidas, ignorando todas...") MSG_HASH(MSG_SHADER, - "Shader" - ) + "Shader") MSG_HASH(MSG_SHADER_PRESET_SAVED_SUCCESSFULLY, - "Predefinição de Shader salva com sucesso." - ) + "Predefinição de Shader salva com sucesso.") MSG_HASH(MSG_SKIPPING_SRAM_LOAD, - "Ignorando carregamento da SRAM." - ) + "Ignorando carregamento da SRAM.") MSG_HASH(MSG_SLOW_MOTION, - "Câmera Lenta." - ) + "Câmera Lenta.") MSG_HASH(MSG_FAST_FORWARD, - "Avanço rápido." - ) + "Avanço rápido.") MSG_HASH(MSG_SLOW_MOTION_REWIND, - "Voltar Atrás em Câmera Lenta." - ) + "Rebobinagem em Câmera Lenta.") MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED, - "SRAM não será salva." - ) + "SRAM não será salva.") MSG_HASH(MSG_STARTING_MOVIE_PLAYBACK, - "Iniciando reprodução de filme." - ) + "Iniciando reprodução de filme.") MSG_HASH(MSG_STARTING_MOVIE_RECORD_TO, - "Iniciando a gravação de filme em" - ) + "Iniciando a gravação de filme em") MSG_HASH(MSG_STATE_SIZE, - "Tamanho do Estado de Jogo" - ) + "Tamanho do Estado de Jogo") MSG_HASH(MSG_STATE_SLOT, - "Compartimento do Estado de Jogo" - ) + "Compartimento do Estado de Jogo") MSG_HASH(MSG_TAKING_SCREENSHOT, - "Fazendo captura de tela" - ) + "Fazendo captura de tela") MSG_HASH(MSG_TO, - "em" - ) + "em") MSG_HASH(MSG_UNDID_LOAD_STATE, - "Desfez o carregamento de Estado de Jogo." - ) + "Desfez o carregamento de Estado de Jogo.") MSG_HASH(MSG_UNDOING_SAVE_STATE, - "Desfazendo o salvamento de Estado de Jogo" - ) + "Desfazendo o salvamento de Estado de Jogo") MSG_HASH(MSG_UNKNOWN, - "Desconhecido" - ) + "Desconhecido") MSG_HASH(MSG_UNPAUSED, - "Retomando." - ) + "Retomando.") MSG_HASH(MSG_UNRECOGNIZED_COMMAND, - "Comando não reconhecido" - ) + "Comando não reconhecido") MSG_HASH(MSG_USING_CORE_NAME_FOR_NEW_CONFIG, - "Usando o nome do núcleo para uma nova configuração." - ) + "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." - ) + "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." - ) + "Conecte o dispositivo a partir de uma porta válida.") MSG_HASH(MSG_VALUE_DISCONNECTING_DEVICE_FROM_PORT, - "Desconectando o dispositivo da porta" - ) + "Desconectando o dispositivo da porta") MSG_HASH(MSG_VALUE_REBOOTING, - "Reinicializando..." - ) + "Reinicializando...") MSG_HASH(MSG_VALUE_SHUTTING_DOWN, - "Desligando..." - ) + "Desligando...") MSG_HASH(MSG_VERSION_OF_LIBRETRO_API, - "Versão da API libretro" - ) + "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..." - ) + "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." - ) + "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." - ) + "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 a 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" - ) + "Á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" - ) + "Base de Dados - Filtro : Franquia") MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ESRB_RATING, - "Base de Dados - Filtro : Classificação ESRB" - ) + "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" - ) + "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" - ) + "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" - ) + "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" - ) + "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" - ) + "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" - ) + "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" - ) + "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" - ) + "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" - ) + "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" - ) + "Informações da Base de Dados") MSG_HASH(MSG_WIFI_SCAN_COMPLETE, - "Análise de Wi-Fi completa." - ) + "Análise de Wi-Fi completa.") MSG_HASH(MSG_SCANNING_WIRELESS_NETWORKS, - "Analisando redes sem fio..." - ) + "Analisando redes sem fio...") MSG_HASH(MSG_NETPLAY_LAN_SCAN_COMPLETE, - "Análise de Netplay completa." - ) + "Análise de Netplay completa.") MSG_HASH(MSG_NETPLAY_LAN_SCANNING, - "Analisando por hospedeiros de Netplay..." - ) + "Analisando por hospedeiros de Netplay...") MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, - "Pausar o jogo quando a janela do RetroArch não estiver ativa." - ) + "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)." - ) + "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." - ) + "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." - ) + "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" - ) + "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." - ) + "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." - ) + "Exibir mensagens na tela.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_USER_REMOTE_ENABLE, - "Habilitar Remoto do Usuário %d" - ) + "Habilitar Remoto do Usuário %d") MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, - "Exibir nível de bateria" - ) + "Exibir nível de bateria") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, - "Selecionar Arquivo" - ) + "Selecionar Arquivo") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Selecionar de Coleção" - ) + "Selecionar de Coleção") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, - "Filtro" - ) + "Filtro") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, - "Escala" - ) + "Escala") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED, - "O Netplay irá iniciar quando o conteúdo for carregado." - ) + "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" - ) + "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" - ) + "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" - ) + "Atualizar Lista de Salas") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME, - "Apelido: %s" - ) + "Apelido: %s") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME_LAN, - "Apelido (lan): %s" - ) + "Apelido (lan): %s") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND, - "Conteúdo compatível encontrado" - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "Selecionar qual núcleo utilizar.") MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_CONTENT_LIST, - "Selecionar qual conteúdo iniciar." - ) + "Selecionar qual conteúdo iniciar.") MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_INFORMATION, - "Exibir interfaces de rede e endereços de IP associados." - ) + "Exibir interfaces de rede e endereços de IP associados.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_INFORMATION, - "Exibir informações específicas do dispositivo." - ) + "Exibir informações específicas do dispositivo.") MSG_HASH(MENU_ENUM_SUBLABEL_QUIT_RETROARCH, - "Sair do programa." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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, - "A taxa máxima na qual o conteúdo será executado quando utilizado o Avanço Rápido (ex: 5.0x para conteúdos em 60fps = 300 fps max). Se for definido como 0.0x, a taxa de Avanço Rápido é ilimitada (sem FPS max)." - ) -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_REWIND_ENABLE, - "Habilita Voltar Atrás. Isso irá impactar o desempenho ao jogar." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_REWIND_GRANULARITY, - "Ao definir um número de quadros para Voltar Atrás, 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, - "Autocarrega o último Estado de Jogo autosalvo na inicialização do RetroArch." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_SAVESTATE_THUMBNAIL_ENABLE, - "Exibe miniaturas dos Estados de Jogo salvos dentro do menu." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL, - "Salva automaticamente a SRAM não volátil em um intervalo regular. Isto é desativado por padrão a menos que seja definido de outra forma. O intervalo é medido em segundos. O valor 0 desativa o salvamento automático." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE, - "Se habilitado, substitui os vínculos de entrada com os vínculos remapeados definidos pelo núcleo atual." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_AUTODETECT_ENABLE, - "Habilita a detecção automática de entrada. Isto tentará configurar automaticamente Joypads no estilo 'Plug-and-Play'." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_INPUT_SWAP_OK_CANCEL, - "Inverte os botões para OK/Cancelar. Desabilitado é o estilo japonês, habilitado é o estilo ocidental." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_LIBRETRO, - "Se desabilitado, o conteúdo continuará rodando em segundo plano quando o menu do RetroArch é 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 de 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_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, - "Seleciona 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, - "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 Voltar Atrás 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_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)." - ) + "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. Evita problemas de áudio devido ao estado de carregamento." + ) +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." + ) +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 para usar." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_DRIVER, + "Driver de áudio para usar." + ) +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." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_JOYPAD_DRIVER, + "Driver do Joypad para usar." + ) +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_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, + "Seleciona 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, + "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." - ) + "Habilita o Netplay no modo cliente.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, - "Desconecta de uma conexão de Netplay ativa." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "Analisar por novas salas.") MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, - "Remover esta entrada da coleção." - ) + "Remover esta entrada da coleção.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, - "Visualizar mais informações sobre o conteúdo." - ) + "Visualizar mais informações sobre o conteúdo.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES, - "Adicionar o item aos seus favoritos." - ) + "Adicionar o item aos seus favoritos.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES_PLAYLIST, - "Adicionar o item aos seus favoritos." - ) + "Adicionar o item aos seus favoritos.") MSG_HASH(MENU_ENUM_SUBLABEL_RUN, - "Iniciar o conteúdo." - ) + "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." - ) + "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." - ) + "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." - ) + "Exibir o nome do núcleo atual dentro do menu.") MSG_HASH(MENU_ENUM_SUBLABEL_DATABASE_MANAGER, - "Visualizar bases de dados." - ) + "Visualizar bases de dados.") MSG_HASH(MENU_ENUM_SUBLABEL_CURSOR_MANAGER, - "Visualizar pesquisas anteriores." - ) + "Visualizar pesquisas anteriores.") MSG_HASH(MENU_ENUM_SUBLABEL_TAKE_SCREENSHOT, - "Capturar uma imagem da tela." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_CLOSE_CONTENT, - "Fecha o conteúdo atual. Alterações não salvas serão perdidas." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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 Voltar Atrás." - ) + "Gerenciar as configurações de Rebobinagem.") MSG_HASH(MENU_ENUM_SUBLABEL_RESTART_CONTENT, - "Reinicia o conteúdo do começo." - ) + "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." - ) + "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_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." - ) + "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." - ) + "Configurar códigos de Trapaça.") MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_OPTIONS, - "Configurar Shader para realçar a aparência da imagem." - ) + "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." - ) + "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." - ) + "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)." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "Mudar o índice do disco.") MSG_HASH(MENU_ENUM_SUBLABEL_DISK_OPTIONS, - "Gerenciamento de imagem de disco." - ) + "Gerenciamento de imagem de disco.") MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, - "Selecione uma imagem de disco para inserir." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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é." - ) + "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." - ) + "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." - ) + "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." - ) + "Salvar todos os arquivos baixados neste diretório.") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_REMAPPING_DIRECTORY, - "Salvar todos os controles remapeados neste diretório." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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." - ) + "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'." - ) + "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'." - ) + "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'." - ) + "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." - ) + "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." - ) + "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" - ) + "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." - ) + "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" - ) + "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" - ) + "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" - ) + "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." - ) + "Mixer de áudio mudo/não-mudo.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_ONLINE_UPDATER, - "Exibir Atualizador Online" - ) + "Exibir Atualizador Online") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_ONLINE_UPDATER, - "Exibir a opção 'Atualizador Online'." - ) + "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." - ) + "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" - ) + "Exibir Atualizador de Núcleos") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_CORE_UPDATER, - "Exibir a opção de atualizar núcleos (e arquivos de informação de núcleo)." - ) + "Exibir 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..." - ) + "Preparando a busca de conteúdo...") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_DELETE, - "Remover núcleo" - ) + "Remover núcleo") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_DELETE, - "Remover este núcleo do disco." - ) -MSG_HASH(MENU_ENUM_SUBLABEL_RENAME_ENTRY, - "Renomear o título do item." - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_RENAME_ENTRY, - "Renomear" - ) + "Remover este núcleo do disco.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FRAMEBUFFER_OPACITY, - "Opacidade do Framebuffer" - ) + "Opacidade do Framebuffer") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_FRAMEBUFFER_OPACITY, - "Modificar a opacidade do framebuffer." - ) + "Modificar a opacidade do framebuffer.") MSG_HASH(MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES, - "Favoritos" - ) + "Favoritos") MSG_HASH(MENU_ENUM_SUBLABEL_GOTO_FAVORITES, - "Conteúdo adicionado aos 'Favoritos' vai aparecer aqui." - ) + "Conteúdo adicionado aos 'Favoritos' vai aparecer aqui.") MSG_HASH(MENU_ENUM_LABEL_VALUE_GOTO_MUSIC, - "Músicas" - ) + "Músicas") MSG_HASH(MENU_ENUM_SUBLABEL_GOTO_MUSIC, - "Músicas que foram reproduzidas aparecem aqui." - ) + "Músicas que foram reproduzidas aparecem aqui.") MSG_HASH(MENU_ENUM_LABEL_VALUE_GOTO_IMAGES, - "Imagens" - ) + "Imagens") MSG_HASH(MENU_ENUM_SUBLABEL_GOTO_IMAGES, - "Imagens que foram exibidas aparecem aqui." - ) + "Imagens que foram exibidas aparecem aqui.") MSG_HASH(MENU_ENUM_LABEL_VALUE_GOTO_VIDEO, - "Vídeos" - ) + "Vídeos") MSG_HASH(MENU_ENUM_SUBLABEL_GOTO_VIDEO, - "Vídeos que foram reproduzidos aparecem aqui." - ) + "Vídeos que foram reproduzidos aparecem aqui.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_ICONS_ENABLE, - "Ícones do Menu" - ) + "Ícones do Menu") MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_ICONS_ENABLE, - "Habilitar/desabilitar os ícones exibidos do lado esquerdo dos itens de menu." - ) + "Habilitar/desabilitar os ícones exibidos do lado esquerdo dos itens de menu.") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MAIN_MENU_ENABLE_SETTINGS, - "Habilitar guia de configurações" - ) + "Habilitar aba de configurações") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS_PASSWORD, - "Definir senha para habilitar guia de configurações" - ) + "Definir senha para habilitar aba de configurações") MSG_HASH(MSG_INPUT_ENABLE_SETTINGS_PASSWORD, - "Digite a senha" - ) + "Digite a senha") MSG_HASH(MSG_INPUT_ENABLE_SETTINGS_PASSWORD_OK, - "Senha correta." - ) + "Senha correta.") MSG_HASH(MSG_INPUT_ENABLE_SETTINGS_PASSWORD_NOK, - "Senha incorreta." - ) + "Senha incorreta.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, - "Habilita a guia de configurações. É necessário reiniciar para que a guia apareça." - ) + "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 guia de configurações permite restaurar mais tarde a partir do menu, indo para a guia Menu Principal, selecionando Habilitar guia configurações e inserindo a senha." - ) + "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 as entradas nas coleções." - ) + "Permita que o usuário renomeie os itens nas coleções.") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_RENAME, - "Permitir renomear entradas" - ) + "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" - ) + "Exibir 'Carregar Núcleo'") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CORE, - "Exibir/ocultar a opção 'Carregar Núcleo'." - ) + "Exibir/ocultar a opção 'Carregar Núcleo'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CONTENT, - "Exibir Carregar Conteúdo" - ) + "Exibir Carregar Conteúdo") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_LOAD_CONTENT, - "Exibir/ocultar a opção 'Carregar Conteúdo'." - ) + "Exibir/ocultar a opção 'Carregar Conteúdo'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_INFORMATION, - "Exibir Informação" - ) + "Exibir Informação") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_INFORMATION, - "Exibir/ocultar a opção 'Informação'." - ) + "Exibir/ocultar a opção 'Informação'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_CONFIGURATIONS, - "Exibir Configurações" - ) + "Exibir Configurações") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_CONFIGURATIONS, - "Exibir/ocultar a opção 'Configurações'." - ) + "Exibir/ocultar a opção 'Configurações'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_HELP, - "Exibir Ajuda" - ) + "Exibir Ajuda") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_HELP, - "Exibir/ocultar a opção 'Ajuda'." - ) + "Exibir/ocultar a opção 'Ajuda'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_QUIT_RETROARCH, - "Exibir Sair do RetroArch" - ) + "Exibir Sair do RetroArch") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_QUIT_RETROARCH, - "Exibir/ocultar a opção 'Sair do RetroArch'." - ) + "Exibir/ocultar a opção 'Sair do RetroArch'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SHOW_REBOOT, - "Exibir Reiniciar" - ) + "Exibir Reiniciar") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SHOW_REBOOT, - "Exibir/ocultar a opção 'Reiniciar'." - ) + "Exibir/ocultar a opção 'Reiniciar'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_VIEWS_SETTINGS, - "Menu Rápido" - ) + "Menu Rápido") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_VIEWS_SETTINGS, - "Exibir ou ocultar elementos na tela de Menu Rápido." - ) + "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" - ) + "Exibir 'Captura de Tela'") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_TAKE_SCREENSHOT, - "Exibir/ocultar a opção 'Captura de Tela'." - ) + "Exibir/ocultar a opção 'Captura de Tela'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SAVE_LOAD_STATE, - "Exibir Salvar/Carregar Estado" - ) + "Exibir Salvar/Carregar Estado") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_LOAD_STATE, - "Exibir/ocultar as opções para salvar/carregar estados." - ) + "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" - ) + "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." - ) + "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" - ) + "Exibir Adicionar aos Favoritos") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_ADD_TO_FAVORITES, - "Exibir/ocultar a opção 'Adicionar aos Favoritos'." - ) + "Exibir/ocultar a opção 'Adicionar aos Favoritos'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_OPTIONS, - "Exibir Opções" - ) + "Exibir Opções") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_OPTIONS, - "Exibir/ocultar a opção 'Opções'." - ) + "Exibir/ocultar a opção 'Opções'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CONTROLS, - "Exibir Controles" - ) + "Exibir Controles") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CONTROLS, - "Exibir/ocultar a opção 'Controles'." - ) + "Exibir/ocultar a opção 'Controles'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_CHEATS, - "Exibir Trapaças" - ) + "Exibir Trapaças") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CHEATS, - "Exibir/ocultar a opção 'Trapaças'." - ) + "Exibir/ocultar a opção 'Trapaças'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_SHADERS, - "Exibir Shaders" - ) + "Exibir 'Shaders'") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SHADERS, - "Exibir/ocultar a opção '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" - ) + "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'." - ) + "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" - ) + "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'." - ) + "Exibir/ocultar a opção 'Salvar Redefinição de Jogo'.") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_INFORMATION, - "Exibir Informação" - ) + "Exibir Informação") MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_INFORMATION, - "Exibir/ocultar a opção 'Informação'." - ) + "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" - ) + "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." - ) + "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" - ) + "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." - ) + "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" - ) + "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." - ) + "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" - ) + "Digite a Senha") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, - "Senha correta." - ) + "Senha correta.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, - "Senha incorreta." - ) + "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(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, - "Display Statistics") + "Exibir estatísticas") MSG_HASH(MENU_ENUM_SUBLABEL_STATISTICS_SHOW, - "Show onscreen technical statistics.") + "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") +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_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") diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h index 3e50847c9a..c4cdcd3b25 100644 --- a/intl/msg_hash_pt_pt.h +++ b/intl/msg_hash_pt_pt.h @@ -1615,6 +1615,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, "Taxa de atualização") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "Taxa de atualização estimada do ecrã") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "Rotação") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, @@ -1743,6 +1745,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS, "Mostrar separador de definições") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "Mostrar separador de vídeo") +MSG_HASH(MENU_ENUM_LABEL_XMB_LAYOUT, + "Select a different layout for the XMB interface.") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, "Ícone do tema do menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, @@ -1843,6 +1847,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, "Seleciona o ecrã a ser utilizado.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "A taxa de atualização do ecrã estimada em 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, "Alterar as definições da saída de vídeo.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2848,6 +2854,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, "Selecione uma imagem de disco para inserir.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, "Certifique-se de que a taxa de fotogramas atingida enquanto estiver dentro do menu.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_LAYOUT, + "Select a different layout for the XMB interface.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_THEME, "Selecionar um tema diferente para este ícone. As alterações terão efeito após o reinício do programa.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, @@ -2988,8 +2996,12 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, "Retransmite as ligações de Netplay através de um servidor homem-no-meio. Útil se o anfitrião se encontrar atrás de uma Firewall ou tiver problemas com os protocolos NAT/UPnP.") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, "Adicionar ao misturador") +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, "Adicionar ao misturador e à coleção") +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, "Filtrar pelo núcleo atual") MSG_HASH( @@ -3178,3 +3190,65 @@ 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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index 52eaa1288a..8d4fee335f 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -1652,6 +1652,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, "Вертикальная частота обновления") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, "Оценочная частота экрана") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + "Set Display-Reported Refresh Rate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "Вращение") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, @@ -1786,6 +1788,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "Показать вкладку Видео") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, "Показать вкладку Сетевая игра") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + "Menu Layout") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, "Тема значка меню") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, @@ -1888,6 +1892,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, "Выбирает, какой экран дисплея использовать.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "Точная оценка частоты обновления экрана в Гц.") +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, "Настройка параметров вывода видео.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2922,6 +2928,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, "Выберите образ диска для загрузки.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, "Убедитесь, что частота кадров ограничена внутри меню.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_LAYOUT, + "Select a different layout for the XMB interface.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_THEME, "Выберите другую тему для значка. Изменения заработают после перезагрузки.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, @@ -3066,8 +3074,12 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, "Передать сетевые соединения через сервер «man-in-the-midle». Будет полезным, если хост находится за брандмауэром или имеет проблемы NAT / UPnP.") MSG_HASH(MENU_ENUM_LABEL_VALUE_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, "Добавить в микшер") +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, "Фильтрировать по текущему ядру") MSG_HASH( @@ -3262,3 +3274,65 @@ 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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index 264b0a7860..5acc456d3f 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -22,9 +22,11 @@ #include #include "../msg_hash.h" -#include "../configuration.h" #include "../verbosity.h" +#ifdef RARCH_INTERNAL +#include "../configuration.h" + int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) { settings_t *settings = config_get_ptr(); @@ -888,6 +890,13 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len); } break; + + case MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION: snprintf(s, len, "SET CRT"); + break; + + case MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER: snprintf(s, len, "SET CRT SUPER"); + break; + case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET: snprintf(s, len, "Load Shader Preset. \n" @@ -1194,6 +1203,13 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) "not run at 60Hz, or something close to it, \n" "disable VSync, and leave this at its default."); break; + case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED: + snprintf(s, len, + "Set Polled Refresh Rate\n" + " \n" + "Sets the refresh rate to the actual value\n" + "polled from the display driver."); + break; case MENU_ENUM_LABEL_VIDEO_ROTATION: snprintf(s, len, "Forces a certain rotation \n" @@ -2029,6 +2045,7 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) return 0; } +#endif #ifdef HAVE_MENU static const char *menu_hash_to_str_us_label_enum(enum msg_hash_enums msg) diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index caca939fe1..29a33bc8e8 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -460,7 +460,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, - "Achievements Hardcore Mode" + "Hardcore Mode" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_ENABLE, @@ -500,11 +500,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_VERBOSE_ENABLE, - "Achievements Verbose Mode" + "Verbose Mode" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_AUTO_SCREENSHOT, - "Achievements Automatic Screenshot" + "Automatic Screenshot" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, @@ -871,6 +871,8 @@ 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, @@ -949,6 +951,8 @@ 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, @@ -1445,6 +1449,12 @@ 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_SORT_SAVEFILES_ENABLE, "Sort Saves In Folders") MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVESTATES_ENABLE, @@ -1625,6 +1635,10 @@ 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, @@ -1645,6 +1659,10 @@ 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, @@ -1753,6 +1771,8 @@ 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, @@ -1883,6 +1903,8 @@ 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, @@ -1895,6 +1917,8 @@ 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, @@ -1906,7 +1930,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, 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, fast-forward, pause, and slow-motion for all games.") + "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, @@ -1967,6 +1991,8 @@ 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, @@ -2003,6 +2029,8 @@ 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, @@ -2012,7 +2040,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_HELP_LIST, MSG_HASH(MSG_ADDED_TO_FAVORITES, "Added to favorites") MSG_HASH(MSG_RESET_CORE_ASSOCIATION, - "Playlist entry core association has been reset.") + "Playlist entry core association has been reset.") MSG_HASH(MSG_APPENDED_DISK, "Appended disk") MSG_HASH(MSG_APPLICATION_DIR, @@ -2577,7 +2605,7 @@ MSG_HASH(MSG_NETPLAY_LAN_SCANNING, 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 (Windows only).") + "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, @@ -2720,6 +2748,18 @@ 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_REWIND_ENABLE, "Enable rewinding. This will take a performance hit when playing." @@ -2908,6 +2948,13 @@ 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." @@ -3059,6 +3106,8 @@ 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_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, @@ -3089,6 +3138,8 @@ 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, @@ -3211,8 +3262,12 @@ 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( @@ -3439,3 +3494,187 @@ 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_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_RESTART_TO_TAKE_EFFECT, + "Please restart the program for the changes to take effect.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_LOG, + "Log") +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_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_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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h index 1597d8109c..2765cb868a 100644 --- a/intl/msg_hash_vn.h +++ b/intl/msg_hash_vn.h @@ -1639,6 +1639,8 @@ 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, @@ -1759,6 +1761,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_HISTORY, "Display History Tab") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_ADD, "Display Import content Tab") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_PLAYLISTS, + "Display Playlist Tabs") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_IMAGES, "Display Image Tab") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_MUSIC, @@ -1769,6 +1773,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_VIDEO, "Display Video Tab") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_NETPLAY, "Display 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, @@ -1780,7 +1786,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, 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, fast-forward, pause, and slow-motion for all games.") + "Enable or disable savestates, cheats, rewind, pause, and slow-motion for all games.") MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, "Change drivers used by the system.") MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, @@ -1869,6 +1875,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, "Chọn màn hình hiển thị để sử dụng.") 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, "Điều chỉnh thiết lập cho video ra.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, @@ -2433,7 +2441,7 @@ MSG_HASH(MSG_NETPLAY_LAN_SCANNING, 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 (Windows only).") + "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, @@ -2903,6 +2911,8 @@ 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_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, @@ -2931,6 +2941,8 @@ 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, @@ -3047,8 +3059,12 @@ 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_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( @@ -3231,3 +3247,65 @@ 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_QUICK_MENU_OVERRIDE_OPTIONS, + "Configuration Override options") +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") diff --git a/libretro-common/audio/audio_mix.c b/libretro-common/audio/audio_mix.c index 776a9f21e7..15879ab248 100644 --- a/libretro-common/audio/audio_mix.c +++ b/libretro-common/audio/audio_mix.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (audio_mix.c). @@ -111,7 +111,7 @@ void audio_mix_free_chunk(audio_chunk_t *chunk) audio_chunk_t* audio_mix_load_wav_file(const char *path, int sample_rate) { int sample_size; - ssize_t len = 0; + int64_t len = 0; void *buf = NULL; audio_chunk_t *chunk = (audio_chunk_t*)calloc(1, sizeof(*chunk)); diff --git a/libretro-common/audio/audio_mixer.c b/libretro-common/audio/audio_mixer.c index c781297309..685e4f8716 100644 --- a/libretro-common/audio/audio_mixer.c +++ b/libretro-common/audio/audio_mixer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (audio_mixer.c). @@ -44,7 +44,18 @@ #define STB_VORBIS_NO_STDIO #define STB_VORBIS_NO_CRT -#include +#include +#endif + +#ifdef HAVE_DR_FLAC +#define DR_FLAC_IMPLEMENTATION +#include +#endif + + +#ifdef HAVE_DR_MP3 +#define DR_MP3_IMPLEMENTATION +#include #endif #ifdef HAVE_IBXM @@ -52,7 +63,7 @@ #endif #define AUDIO_MIXER_MAX_VOICES 8 -#define AUDIO_MIXER_TEMP_OGG_BUFFER 8192 +#define AUDIO_MIXER_TEMP_BUFFER 8192 struct audio_mixer_sound { @@ -75,6 +86,24 @@ struct audio_mixer_sound const void* data; } ogg; #endif + +#ifdef HAVE_DR_FLAC + struct + { + /* flac */ + unsigned size; + const void* data; + } flac; +#endif + +#ifdef HAVE_DR_MP3 + struct + { + /* mp */ + unsigned size; + const void* data; + } mp3; +#endif #ifdef HAVE_IBXM struct @@ -116,6 +145,34 @@ struct audio_mixer_voice } ogg; #endif +#ifdef HAVE_DR_FLAC + struct + { + unsigned position; + unsigned samples; + unsigned buf_samples; + float* buffer; + float ratio; + drflac *stream; + void *resampler_data; + const retro_resampler_t *resampler; + } flac; +#endif + +#ifdef HAVE_DR_MP3 + struct + { + unsigned position; + unsigned samples; + unsigned buf_samples; + float* buffer; + float ratio; + drmp3 stream; + void *resampler_data; + const retro_resampler_t *resampler; + } mp3; +#endif + #ifdef HAVE_IBXM struct { @@ -343,6 +400,43 @@ audio_mixer_sound_t* audio_mixer_load_ogg(void *buffer, int32_t size) #endif } + +audio_mixer_sound_t* audio_mixer_load_flac(void *buffer, int32_t size) +{ +#ifdef HAVE_DR_FLAC + audio_mixer_sound_t* sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound)); + + if (!sound) + return NULL; + + sound->type = AUDIO_MIXER_TYPE_FLAC; + sound->types.flac.size = size; + sound->types.flac.data = buffer; + + return sound; +#else + return NULL; +#endif +} + +audio_mixer_sound_t* audio_mixer_load_mp3(void *buffer, int32_t size) +{ +#ifdef HAVE_DR_MP3 + audio_mixer_sound_t* sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound)); + + if (!sound) + return NULL; + + sound->type = AUDIO_MIXER_TYPE_MP3; + sound->types.mp3.size = size; + sound->types.mp3.data = buffer; + + return sound; +#else + return NULL; +#endif +} + audio_mixer_sound_t* audio_mixer_load_mod(void *buffer, int32_t size) { #ifdef HAVE_IBXM @@ -386,6 +480,20 @@ void audio_mixer_destroy(audio_mixer_sound_t* sound) handle = (void*)sound->types.mod.data; if (handle) free(handle); +#endif + break; + case AUDIO_MIXER_TYPE_FLAC: +#ifdef HAVE_DR_FLAC + handle = (void*)sound->types.flac.data; + if (handle) + free(handle); +#endif + break; + case AUDIO_MIXER_TYPE_MP3: +#ifdef HAVE_DR_MP3 + handle = (void*)sound->types.mp3.data; + if (handle) + free(handle); #endif break; case AUDIO_MIXER_TYPE_NONE: @@ -412,7 +520,7 @@ static bool audio_mixer_play_ogg( { stb_vorbis_info info; int res = 0; - float ratio = 0.0f; + float ratio = 1.0f; unsigned samples = 0; void *ogg_buffer = NULL; void *resampler_data = NULL; @@ -436,7 +544,7 @@ static bool audio_mixer_play_ogg( goto error; } - samples = (unsigned)(AUDIO_MIXER_TEMP_OGG_BUFFER * ratio); + samples = (unsigned)(AUDIO_MIXER_TEMP_BUFFER * ratio); ogg_buffer = (float*)memalign_alloc(16, ((samples + 15) & ~15) * sizeof(float)); @@ -531,6 +639,113 @@ error: } #endif + +#ifdef HAVE_DR_FLAC +static bool audio_mixer_play_flac( + audio_mixer_sound_t* sound, + audio_mixer_voice_t* voice, + bool repeat, float volume, + audio_mixer_stop_cb_t stop_cb) +{ + float ratio = 1.0f; + unsigned samples = 0; + void *flac_buffer = NULL; + void *resampler_data = NULL; + const retro_resampler_t* resamp = NULL; + drflac *dr_flac = drflac_open_memory((const unsigned char*)sound->types.flac.data,sound->types.flac.size); + + + if (!dr_flac) + return false; + if (dr_flac->sampleRate != s_rate) + { + ratio = (double)s_rate / (double)(dr_flac->sampleRate); + + if (!retro_resampler_realloc(&resampler_data, + &resamp, NULL, RESAMPLER_QUALITY_DONTCARE, + ratio)) + goto error; + } + + samples = (unsigned)(AUDIO_MIXER_TEMP_BUFFER * ratio); + flac_buffer = (float*)memalign_alloc(16, + ((samples + 15) & ~15) * sizeof(float)); + + if (!flac_buffer) + { + resamp->free(resampler_data); + goto error; + } + + voice->types.flac.resampler = resamp; + voice->types.flac.resampler_data = resampler_data; + voice->types.flac.buffer = (float*)flac_buffer; + voice->types.flac.buf_samples = samples; + voice->types.flac.ratio = ratio; + voice->types.flac.stream = dr_flac; + voice->types.flac.position = 0; + voice->types.flac.samples = 0; + + return true; + +error: + drflac_close(dr_flac); + return false; +} +#endif + +#ifdef HAVE_DR_MP3 +static bool audio_mixer_play_mp3( + audio_mixer_sound_t* sound, + audio_mixer_voice_t* voice, + bool repeat, float volume, + audio_mixer_stop_cb_t stop_cb) +{ + float ratio = 1.0f; + unsigned samples = 0; + void *mp3_buffer = NULL; + void *resampler_data = NULL; + const retro_resampler_t* resamp = NULL; + bool res =drmp3_init_memory(&voice->types.mp3.stream,(const unsigned char*)sound->types.mp3.data,sound->types.mp3.size,NULL); + if (!res) + return false; + if (voice->types.mp3.stream.sampleRate != s_rate) + { + ratio = (double)s_rate / (double)(voice->types.mp3.stream.sampleRate); + + if (!retro_resampler_realloc(&resampler_data, + &resamp, NULL, RESAMPLER_QUALITY_DONTCARE, + ratio)) + goto error; + } + + samples = (unsigned)(AUDIO_MIXER_TEMP_BUFFER * ratio); + mp3_buffer = (float*)memalign_alloc(16, + ((samples + 15) & ~15) * sizeof(float)); + + if (!mp3_buffer) + { + resamp->free(resampler_data); + goto error; + } + + voice->types.mp3.resampler = resamp; + voice->types.mp3.resampler_data = resampler_data; + voice->types.mp3.buffer = (float*)mp3_buffer; + voice->types.mp3.buf_samples = samples; + voice->types.mp3.ratio = ratio; + voice->types.mp3.position = 0; + voice->types.mp3.samples = 0; + + return true; + +error: + drmp3_uninit(&voice->types.mp3.stream); + return false; +} +#endif + + audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat, float volume, audio_mixer_stop_cb_t stop_cb) { @@ -563,6 +778,16 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat, case AUDIO_MIXER_TYPE_MOD: #ifdef HAVE_IBXM res = audio_mixer_play_mod(sound, voice, repeat, volume, stop_cb); +#endif + break; + case AUDIO_MIXER_TYPE_FLAC: +#ifdef HAVE_DR_FLAC + res = audio_mixer_play_flac(sound, voice, repeat, volume, stop_cb); +#endif + break; + case AUDIO_MIXER_TYPE_MP3: +#ifdef HAVE_DR_MP3 + res = audio_mixer_play_mp3(sound, voice, repeat, volume, stop_cb); #endif break; case AUDIO_MIXER_TYPE_NONE: @@ -665,9 +890,9 @@ static void audio_mixer_mix_ogg(float* buffer, size_t num_frames, float volume) { int i; - struct resampler_data info; - float temp_buffer[AUDIO_MIXER_TEMP_OGG_BUFFER]; - unsigned buf_free = num_frames * 2; + struct resampler_data info = { 0 }; + float temp_buffer[AUDIO_MIXER_TEMP_BUFFER] = { 0 }; + unsigned buf_free = (unsigned)(num_frames * 2); unsigned temp_samples = 0; float* pcm = NULL; @@ -676,7 +901,7 @@ static void audio_mixer_mix_ogg(float* buffer, size_t num_frames, again: temp_samples = stb_vorbis_get_samples_float_interleaved( voice->types.ogg.stream, 2, temp_buffer, - AUDIO_MIXER_TEMP_OGG_BUFFER) * 2; + AUDIO_MIXER_TEMP_BUFFER) * 2; if (temp_samples == 0) { @@ -704,7 +929,10 @@ again: info.output_frames = 0; info.ratio = voice->types.ogg.ratio; - voice->types.ogg.resampler->process(voice->types.ogg.resampler_data, &info); + if (voice->types.ogg.resampler) + voice->types.ogg.resampler->process(voice->types.ogg.resampler_data, &info); + else + memcpy(voice->types.ogg.buffer, temp_buffer, temp_samples * sizeof(float)); voice->types.ogg.position = 0; voice->types.ogg.samples = voice->types.ogg.buf_samples; } @@ -740,7 +968,7 @@ static void audio_mixer_mix_mod(float* buffer, size_t num_frames, float samplef = 0.0f; int samplei = 0; unsigned temp_samples = 0; - unsigned buf_free = num_frames * 2; + unsigned buf_free = (unsigned)(num_frames * 2); int* pcm = NULL; if (voice->types.mod.position == voice->types.mod.samples) @@ -806,6 +1034,151 @@ again: } #endif +#ifdef HAVE_DR_FLAC +static void audio_mixer_mix_flac(float* buffer, size_t num_frames, + audio_mixer_voice_t* voice, + float volume) +{ + int i; + struct resampler_data info = { 0 }; + float temp_buffer[AUDIO_MIXER_TEMP_BUFFER] = { 0 }; + unsigned buf_free = (unsigned)(num_frames * 2); + unsigned temp_samples = 0; + float* pcm = NULL; + + if (voice->types.flac.position == voice->types.flac.samples) + { +again: + temp_samples = drflac_read_f32( voice->types.flac.stream, AUDIO_MIXER_TEMP_BUFFER, temp_buffer); + if (temp_samples == 0) + { + if (voice->repeat) + { + if (voice->stop_cb) + voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED); + + drflac_seek_to_sample(voice->types.flac.stream,0); + goto again; + } + else + { + if (voice->stop_cb) + voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED); + + voice->type = AUDIO_MIXER_TYPE_NONE; + return; + } + } + + info.data_in = temp_buffer; + info.data_out = voice->types.flac.buffer; + info.input_frames = temp_samples / 2; + info.output_frames = 0; + info.ratio = voice->types.flac.ratio; + + if (voice->types.flac.resampler) + voice->types.flac.resampler->process(voice->types.flac.resampler_data, &info); + else + memcpy(voice->types.flac.buffer, temp_buffer, temp_samples * sizeof(float)); + voice->types.flac.position = 0; + voice->types.flac.samples = voice->types.flac.buf_samples; + } + + pcm = voice->types.flac.buffer + voice->types.flac.position; + + if (voice->types.flac.samples < buf_free) + { + for (i = voice->types.flac.samples; i != 0; i--) + *buffer++ += *pcm++ * volume; + + buf_free -= voice->types.flac.samples; + goto again; + } + else + { + int i; + for (i = buf_free; i != 0; --i ) + *buffer++ += *pcm++ * volume; + + voice->types.flac.position += buf_free; + voice->types.flac.samples -= buf_free; + } +} +#endif + +#ifdef HAVE_DR_MP3 +static void audio_mixer_mix_mp3(float* buffer, size_t num_frames, + audio_mixer_voice_t* voice, + float volume) +{ + int i; + struct resampler_data info = { 0 }; + float temp_buffer[AUDIO_MIXER_TEMP_BUFFER] = { 0 }; + unsigned buf_free = (unsigned)(num_frames * 2); + unsigned temp_samples = 0; + float* pcm = NULL; + + if (voice->types.mp3.position == voice->types.mp3.samples) + { +again: + temp_samples = drmp3_read_f32(&voice->types.mp3.stream, AUDIO_MIXER_TEMP_BUFFER/2, temp_buffer) * 2; + + if (temp_samples == 0) + { + if (voice->repeat) + { + if (voice->stop_cb) + voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED); + + drmp3_seek_to_frame(&voice->types.mp3.stream,0); + goto again; + } + else + { + if (voice->stop_cb) + voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED); + + voice->type = AUDIO_MIXER_TYPE_NONE; + return; + } + } + + info.data_in = temp_buffer; + info.data_out = voice->types.mp3.buffer; + info.input_frames = temp_samples / 2; + info.output_frames = 0; + info.ratio = voice->types.mp3.ratio; + + if (voice->types.mp3.resampler) + voice->types.mp3.resampler->process(voice->types.mp3.resampler_data, &info); + else + memcpy(voice->types.mp3.buffer, temp_buffer, temp_samples * sizeof(float)); + voice->types.mp3.position = 0; + voice->types.mp3.samples = voice->types.mp3.buf_samples; + } + + pcm = voice->types.mp3.buffer + voice->types.mp3.position; + + if (voice->types.mp3.samples < buf_free) + { + for (i = voice->types.mp3.samples; i != 0; i--) + *buffer++ += *pcm++ * volume; + + buf_free -= voice->types.mp3.samples; + goto again; + } + else + { + int i; + for (i = buf_free; i != 0; --i ) + *buffer++ += *pcm++ * volume; + + voice->types.mp3.position += buf_free; + voice->types.mp3.samples -= buf_free; + } +} +#endif + void audio_mixer_mix(float* buffer, size_t num_frames, float volume_override, bool override) { unsigned i; @@ -834,6 +1207,16 @@ void audio_mixer_mix(float* buffer, size_t num_frames, float volume_override, bo case AUDIO_MIXER_TYPE_MOD: #ifdef HAVE_IBXM audio_mixer_mix_mod(buffer, num_frames, voice, volume); +#endif + break; + case AUDIO_MIXER_TYPE_FLAC: +#ifdef HAVE_DR_FLAC + audio_mixer_mix_flac(buffer, num_frames, voice, volume); +#endif + break; + case AUDIO_MIXER_TYPE_MP3: +#ifdef HAVE_DR_MP3 + audio_mixer_mix_mp3(buffer, num_frames, voice, volume); #endif break; case AUDIO_MIXER_TYPE_NONE: @@ -853,3 +1236,19 @@ void audio_mixer_mix(float* buffer, size_t num_frames, float volume_override, bo *sample = 1.0f; } } + +float audio_mixer_voice_get_volume(audio_mixer_voice_t *voice) +{ + if (!voice) + return 0.0f; + + return voice->volume; +} + +void audio_mixer_voice_set_volume(audio_mixer_voice_t *voice, float val) +{ + if (!voice) + return; + + voice->volume = val; +} diff --git a/libretro-common/audio/conversion/float_to_s16.c b/libretro-common/audio/conversion/float_to_s16.c index bb97945971..baf8b4fd01 100644 --- a/libretro-common/audio/conversion/float_to_s16.c +++ b/libretro-common/audio/conversion/float_to_s16.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (float_to_s16.c). diff --git a/libretro-common/audio/conversion/float_to_s16_neon.S b/libretro-common/audio/conversion/float_to_s16_neon.S index aa9e565671..352c4d3dc7 100644 --- a/libretro-common/audio/conversion/float_to_s16_neon.S +++ b/libretro-common/audio/conversion/float_to_s16_neon.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (float_to_s16_neon.S). diff --git a/libretro-common/audio/conversion/float_to_s16_neon.c b/libretro-common/audio/conversion/float_to_s16_neon.c index 342f4978e1..a5d10e0a68 100644 --- a/libretro-common/audio/conversion/float_to_s16_neon.c +++ b/libretro-common/audio/conversion/float_to_s16_neon.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (float_to_s16_neon.S). diff --git a/libretro-common/audio/conversion/s16_to_float.c b/libretro-common/audio/conversion/s16_to_float.c index 814ddd8261..c8042ea817 100644 --- a/libretro-common/audio/conversion/s16_to_float.c +++ b/libretro-common/audio/conversion/s16_to_float.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (s16_to_float.c). diff --git a/libretro-common/audio/conversion/s16_to_float_neon.S b/libretro-common/audio/conversion/s16_to_float_neon.S index b744924400..3cc47e9f8f 100644 --- a/libretro-common/audio/conversion/s16_to_float_neon.S +++ b/libretro-common/audio/conversion/s16_to_float_neon.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (s16_to_float_neon.S). diff --git a/libretro-common/audio/conversion/s16_to_float_neon.c b/libretro-common/audio/conversion/s16_to_float_neon.c index 464e40fbc9..9912c0d50b 100644 --- a/libretro-common/audio/conversion/s16_to_float_neon.c +++ b/libretro-common/audio/conversion/s16_to_float_neon.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (s16_to_float_neon.S). diff --git a/libretro-common/audio/dsp_filter.c b/libretro-common/audio/dsp_filter.c index 7f428eee12..c7bb2dc9c9 100644 --- a/libretro-common/audio/dsp_filter.c +++ b/libretro-common/audio/dsp_filter.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (dsp_filter.c). diff --git a/libretro-common/audio/dsp_filters/Tremolo.dsp b/libretro-common/audio/dsp_filters/Tremolo.dsp new file mode 100644 index 0000000000..50523333ac --- /dev/null +++ b/libretro-common/audio/dsp_filters/Tremolo.dsp @@ -0,0 +1,7 @@ +filters = 1 +filter0 = tremolo + +# Defaults. +#tremolo_frequency = 4.0 +#tremolo_depth = 0.9 + diff --git a/libretro-common/audio/dsp_filters/Vibrato.dsp b/libretro-common/audio/dsp_filters/Vibrato.dsp new file mode 100644 index 0000000000..b1ea8e1107 --- /dev/null +++ b/libretro-common/audio/dsp_filters/Vibrato.dsp @@ -0,0 +1,7 @@ +filters = 1 +filter0 = vibrato + +# Defaults. +#vibrato_frequency = 5.0 +#vibrato_depth = 0.5 + diff --git a/libretro-common/audio/dsp_filters/fft/fft.c b/libretro-common/audio/dsp_filters/fft/fft.c index e8c80f4f9d..7bafefad1e 100644 --- a/libretro-common/audio/dsp_filters/fft/fft.c +++ b/libretro-common/audio/dsp_filters/fft/fft.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (fft.c). diff --git a/libretro-common/audio/dsp_filters/fft/fft.h b/libretro-common/audio/dsp_filters/fft/fft.h index 8a16c6cb83..e5bcdf7176 100644 --- a/libretro-common/audio/dsp_filters/fft/fft.h +++ b/libretro-common/audio/dsp_filters/fft/fft.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (fft.h). diff --git a/libretro-common/audio/dsp_filters/reverb.c b/libretro-common/audio/dsp_filters/reverb.c index e81d85980d..e9bc8170e1 100644 --- a/libretro-common/audio/dsp_filters/reverb.c +++ b/libretro-common/audio/dsp_filters/reverb.c @@ -91,37 +91,13 @@ static const float initialwidth = 1; static const float initialmode = 0; static const float freezemode = 0.5f; -#define combtuningL1 1116 -#define combtuningL2 1188 -#define combtuningL3 1277 -#define combtuningL4 1356 -#define combtuningL5 1422 -#define combtuningL6 1491 -#define combtuningL7 1557 -#define combtuningL8 1617 -#define allpasstuningL1 556 -#define allpasstuningL2 441 -#define allpasstuningL3 341 -#define allpasstuningL4 225 - struct revmodel { struct comb combL[numcombs]; struct allpass allpassL[numallpasses]; - float bufcombL1[combtuningL1]; - float bufcombL2[combtuningL2]; - float bufcombL3[combtuningL3]; - float bufcombL4[combtuningL4]; - float bufcombL5[combtuningL5]; - float bufcombL6[combtuningL6]; - float bufcombL7[combtuningL7]; - float bufcombL8[combtuningL8]; - - float bufallpassL1[allpasstuningL1]; - float bufallpassL2[allpasstuningL2]; - float bufallpassL3[allpasstuningL3]; - float bufallpassL4[allpasstuningL4]; + float **bufcomb; + float **bufallpass; float gain; float roomsize, roomsize1; @@ -210,21 +186,29 @@ static void revmodel_setmode(struct revmodel *rev, float value) revmodel_update(rev); } -static void revmodel_init(struct revmodel *rev) +static void revmodel_init(struct revmodel *rev,int srate) { - rev->combL[0].buffer = rev->bufcombL1; rev->combL[0].bufsize = combtuningL1; - rev->combL[1].buffer = rev->bufcombL2; rev->combL[1].bufsize = combtuningL2; - rev->combL[2].buffer = rev->bufcombL3; rev->combL[2].bufsize = combtuningL3; - rev->combL[3].buffer = rev->bufcombL4; rev->combL[3].bufsize = combtuningL4; - rev->combL[4].buffer = rev->bufcombL5; rev->combL[4].bufsize = combtuningL5; - rev->combL[5].buffer = rev->bufcombL6; rev->combL[5].bufsize = combtuningL6; - rev->combL[6].buffer = rev->bufcombL7; rev->combL[6].bufsize = combtuningL7; - rev->combL[7].buffer = rev->bufcombL8; rev->combL[7].bufsize = combtuningL8; - rev->allpassL[0].buffer = rev->bufallpassL1; rev->allpassL[0].bufsize = allpasstuningL1; - rev->allpassL[1].buffer = rev->bufallpassL2; rev->allpassL[1].bufsize = allpasstuningL2; - rev->allpassL[2].buffer = rev->bufallpassL3; rev->allpassL[2].bufsize = allpasstuningL3; - rev->allpassL[3].buffer = rev->bufallpassL4; rev->allpassL[3].bufsize = allpasstuningL4; + static const int comb_lengths[8] = { 1116,1188,1277,1356,1422,1491,1557,1617 }; + static const int allpass_lengths[4] = { 225,341,441,556 }; + double r = srate * (1 / 44100.0); + unsigned c; + + rev->bufcomb=malloc(numcombs*sizeof(float*)); + for (c = 0; c < numcombs; ++c) + { + rev->bufcomb[c] = malloc(r*comb_lengths[c]*sizeof(float)); + rev->combL[c].buffer = rev->bufcomb[c]; + rev->combL[c].bufsize=r*comb_lengths[c]; + } + + rev->bufallpass=malloc(numallpasses*sizeof(float*)); + for (c = 0; c < numallpasses; ++c) + { + rev->bufallpass[c] = malloc(r*allpass_lengths[c]*sizeof(float)); + rev->allpassL[c].buffer = rev->bufallpass[c]; + rev->allpassL[c].bufsize=r*allpass_lengths[c]; + } rev->allpassL[0].feedback = 0.5f; rev->allpassL[1].feedback = 0.5f; @@ -246,6 +230,22 @@ struct reverb_data static void reverb_free(void *data) { + struct reverb_data *rev = (struct reverb_data*)data; + unsigned i; + + for (i = 0; i < numcombs; i++) { + free(rev->left.bufcomb[i]); + free(rev->right.bufcomb[i]); + } + free(rev->left.bufcomb); + free(rev->right.bufcomb); + + for (i = 0; i < numallpasses; i++) { + free(rev->left.bufallpass[i]); + free(rev->right.bufallpass[i]); + } + free(rev->left.bufallpass); + free(rev->right.bufallpass); free(data); } @@ -284,8 +284,8 @@ static void *reverb_init(const struct dspfilter_info *info, config->get_float(userdata, "roomwidth", &roomwidth, 0.56f); config->get_float(userdata, "roomsize", &roomsize, 0.56f); - revmodel_init(&rev->left); - revmodel_init(&rev->right); + revmodel_init(&rev->left,info->input_rate); + revmodel_init(&rev->right,info->input_rate); revmodel_setdamp(&rev->left, damping); revmodel_setdry(&rev->left, drytime); diff --git a/libretro-common/audio/dsp_filters/tremolo.c b/libretro-common/audio/dsp_filters/tremolo.c new file mode 100644 index 0000000000..38b535742c --- /dev/null +++ b/libretro-common/audio/dsp_filters/tremolo.c @@ -0,0 +1,133 @@ +/* Copyright (C) 2010-2017 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (tremolo.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include + +#define sqr(a) ((a) * (a)) + +struct tremolo_core +{ + float freq; + float depth; + float* wavetable; + int index; + int maxindex; +}; + +struct tremolo +{ + struct tremolo_core left, right; +}; + +static void tremolo_free(void *data) +{ + struct tremolo *tre = (struct tremolo*)data; + free(tre->left.wavetable); + free(tre->right.wavetable); + free(data); +} + +static void tremolocore_init(struct tremolo_core *core,float depth,int samplerate,float freq) +{ + const double offset = 1. - depth / 2.; + unsigned i; + double env; + core->index = 0; + core->maxindex = samplerate/freq; + core->wavetable = malloc(core->maxindex*sizeof(float)); + memset(core->wavetable, 0, core->maxindex * sizeof(float)); + for (i = 0; i < core->maxindex; i++) { + env = freq * i / samplerate; + env = sin((M_PI*2) * fmod(env + 0.25, 1.0)); + core->wavetable[i] = env * (1 - fabs(offset)) + offset; + } +} + +float tremolocore_core(struct tremolo_core *core,float in) +{ + core->index = core->index % core->maxindex; + return in * core->wavetable[core->index++]; +} + +static void tremolo_process(void *data, struct dspfilter_output *output, + const struct dspfilter_input *input) +{ + unsigned i; + float *out; + struct tremolo *tre = (struct tremolo*)data; + + output->samples = input->samples; + output->frames = input->frames; + out = output->samples; + + for (i = 0; i < input->frames; i++, out += 2) + { + float in[2] = { out[0], out[1] }; + + out[0] = tremolocore_core(&tre->left, in[0]); + out[1] = tremolocore_core(&tre->right, in[1]); + } +} + +static void *tremolo_init(const struct dspfilter_info *info, + const struct dspfilter_config *config, void *userdata) +{ + float freq, depth; + struct tremolo *tre = (struct tremolo*)calloc(1, sizeof(*tre)); + if (!tre) + return NULL; + + config->get_float(userdata, "freq", &freq,4.0f); + config->get_float(userdata, "depth", &depth, 0.9f); + tremolocore_init(&tre->left,depth,info->input_rate,freq); + tremolocore_init(&tre->right,depth,info->input_rate,freq); + return tre; +} + +static const struct dspfilter_implementation tremolo_plug = { + tremolo_init, + tremolo_process, + tremolo_free, + + DSPFILTER_API_VERSION, + "Tremolo", + "tremolo", +}; + +#ifdef HAVE_FILTERS_BUILTIN +#define dspfilter_get_implementation tremolo_dspfilter_get_implementation +#endif + +const struct dspfilter_implementation *dspfilter_get_implementation(dspfilter_simd_mask_t mask) +{ + (void)mask; + return &tremolo_plug; +} + +#undef dspfilter_get_implementation + diff --git a/libretro-common/audio/dsp_filters/vibrato.c b/libretro-common/audio/dsp_filters/vibrato.c new file mode 100644 index 0000000000..6e79d2f0fb --- /dev/null +++ b/libretro-common/audio/dsp_filters/vibrato.c @@ -0,0 +1,169 @@ +/* Copyright (C) 2010-2017 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (vibrato.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include + +#define sqr(a) ((a) * (a)) + + +const float BASE_DELAY_SEC = 0.002; // 2 ms +const float VIBRATO_FREQUENCY_DEFAULT_HZ = 2; +const float VIBRATO_FREQUENCY_MAX_HZ = 14; +const float VIBRATO_DEPTH_DEFAULT_PERCENT = 50; +const int add_delay = 3; + +float hermite_interp(float x, float *y) +{ + float c0, c1, c2, c3; + c0 = y[1]; + c1 = (1.0 / 2.0)*(y[2] - y[0]); + c2 = (y[0] - (5.0 / 2.0)*y[1]) + (2.0*y[2] - (1.0 / 2.0)*y[3]); + c3 = (1.0 / 2.0)*(y[3] - y[0]) + (3.0 / 2.0)*(y[1] - y[2]); + return ((c3*x + c2)*x + c1)*x + c0; +} + +struct vibrato_core +{ + float freq; + float samplerate; + int phase; + float depth; + float* buffer; + int writeindex; + int size; +}; + +struct vibrato +{ + struct vibrato_core left, right; +}; + +static void vibrato_free(void *data) +{ + struct vibrato *vib = (struct vibrato*)data; + free(vib->left.buffer); + free(vib->right.buffer); + free(data); +} + +static void vibratocore_init(struct vibrato_core *core,float depth,int samplerate,float freq) +{ + core->size = BASE_DELAY_SEC * samplerate * 2; + core->buffer = malloc((core->size + add_delay)*sizeof(float)); + memset(core->buffer, 0, (core->size + add_delay) * sizeof(float)); + core->samplerate = samplerate; + core->freq = freq; + core->depth = depth; + core->phase = 0; + core->writeindex = 0; +} + +float vibratocore_core(struct vibrato_core *core,float in) +{ + float M = core->freq / core->samplerate; + int maxphase = core->samplerate / core->freq; + float lfo = sin(M * 2. * M_PI * core->phase++); + core->phase = core->phase % maxphase; + lfo = (lfo + 1) * 1.; // transform from [-1; 1] to [0; 1] + int maxdelay = BASE_DELAY_SEC * core->samplerate; + float delay = lfo * core->depth * maxdelay; + delay += add_delay; + float readindex = core->writeindex - 1 - delay; + while (readindex < 0)readindex += core->size; + while (readindex >= core->size)readindex -= core->size; + int ipart = (int)readindex; // integer part of the delay + float fpart = readindex - ipart; // fractional part of the delay + float value = hermite_interp(fpart, &(core->buffer[ipart])); + core->buffer[core->writeindex] = in; + if (core->writeindex < add_delay){ + core->buffer[core->size + core->writeindex] = in; + } + core->writeindex++; + if (core->writeindex == core->size) { + core->writeindex = 0; + } + return value; +} + +static void vibrato_process(void *data, struct dspfilter_output *output, + const struct dspfilter_input *input) +{ + unsigned i; + float *out; + struct vibrato *vib = (struct vibrato*)data; + + output->samples = input->samples; + output->frames = input->frames; + out = output->samples; + + for (i = 0; i < input->frames; i++, out += 2) + { + float in[2] = { out[0], out[1] }; + + out[0] = vibratocore_core(&vib->left, in[0]); + out[1] = vibratocore_core(&vib->right, in[1]); + } +} + +static void *vibrato_init(const struct dspfilter_info *info, + const struct dspfilter_config *config, void *userdata) +{ + float freq, depth; + struct vibrato *vib = (struct vibrato*)calloc(1, sizeof(*vib)); + if (!vib) + return NULL; + + config->get_float(userdata, "freq", &freq,5.0f); + config->get_float(userdata, "depth", &depth, 0.5f); + vibratocore_init(&vib->left,depth,info->input_rate,freq); + vibratocore_init(&vib->right,depth,info->input_rate,freq); + return vib; +} + +static const struct dspfilter_implementation vibrato_plug = { + vibrato_init, + vibrato_process, + vibrato_free, + + DSPFILTER_API_VERSION, + "Vibrato", + "vibrato", +}; + +#ifdef HAVE_FILTERS_BUILTIN +#define dspfilter_get_implementation vibrato_dspfilter_get_implementation +#endif + +const struct dspfilter_implementation *dspfilter_get_implementation(dspfilter_simd_mask_t mask) +{ + (void)mask; + return &vibrato_plug; +} + +#undef dspfilter_get_implementation + diff --git a/libretro-common/audio/resampler/audio_resampler.c b/libretro-common/audio/resampler/audio_resampler.c index 3cf4660f47..8d27f06932 100644 --- a/libretro-common/audio/resampler/audio_resampler.c +++ b/libretro-common/audio/resampler/audio_resampler.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (audio_resampler.c). diff --git a/libretro-common/audio/resampler/drivers/nearest_resampler.c b/libretro-common/audio/resampler/drivers/nearest_resampler.c index 1083c85836..982d4fe67d 100644 --- a/libretro-common/audio/resampler/drivers/nearest_resampler.c +++ b/libretro-common/audio/resampler/drivers/nearest_resampler.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (nearest_resampler.c). diff --git a/libretro-common/audio/resampler/drivers/null_resampler.c b/libretro-common/audio/resampler/drivers/null_resampler.c index e75026944f..b970dfe0f5 100644 --- a/libretro-common/audio/resampler/drivers/null_resampler.c +++ b/libretro-common/audio/resampler/drivers/null_resampler.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (null_resampler.c). diff --git a/libretro-common/audio/resampler/drivers/sinc_resampler.c b/libretro-common/audio/resampler/drivers/sinc_resampler.c index b5754f6632..c400ab1b23 100644 --- a/libretro-common/audio/resampler/drivers/sinc_resampler.c +++ b/libretro-common/audio/resampler/drivers/sinc_resampler.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (sinc_resampler.c). diff --git a/libretro-common/audio/resampler/drivers/sinc_resampler_neon.S b/libretro-common/audio/resampler/drivers/sinc_resampler_neon.S index 033104e064..15a3773414 100644 --- a/libretro-common/audio/resampler/drivers/sinc_resampler_neon.S +++ b/libretro-common/audio/resampler/drivers/sinc_resampler_neon.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (sinc_resampler_neon.S). diff --git a/libretro-common/compat/compat_fnmatch.c b/libretro-common/compat/compat_fnmatch.c index 81beb3e06b..19f87cc76a 100644 --- a/libretro-common/compat/compat_fnmatch.c +++ b/libretro-common/compat/compat_fnmatch.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (compat_fnmatch.c). diff --git a/libretro-common/compat/compat_getopt.c b/libretro-common/compat/compat_getopt.c index 632f67e9f4..81978b86c2 100644 --- a/libretro-common/compat/compat_getopt.c +++ b/libretro-common/compat/compat_getopt.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (compat_getopt.c). diff --git a/libretro-common/compat/compat_posix_string.c b/libretro-common/compat/compat_posix_string.c index 4bddf11f8f..33a30e5772 100644 --- a/libretro-common/compat/compat_posix_string.c +++ b/libretro-common/compat/compat_posix_string.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (compat_posix_string.c). diff --git a/libretro-common/compat/compat_snprintf.c b/libretro-common/compat/compat_snprintf.c index f31de72d8c..f67301ade2 100644 --- a/libretro-common/compat/compat_snprintf.c +++ b/libretro-common/compat/compat_snprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (compat_snprintf.c). @@ -24,7 +24,9 @@ #ifdef _MSC_VER #include - +#if _MSC_VER >= 1800 +#include /* added for _vsnprintf_s and _vscprintf on VS2015 and VS2017 */ +#endif #include #if _MSC_VER < 1800 @@ -53,13 +55,19 @@ int c99_vsnprintf_retro__(char *outBuf, size_t size, const char *format, va_list if (size != 0) #if (_MSC_VER <= 1310) - count = _vsnprintf(outBuf, size, format, ap); + count = _vsnprintf(outBuf, size - 1, format, ap); #else - count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); + count = _vsnprintf_s(outBuf, size, size - 1, format, ap); #endif if (count == -1) count = _vscprintf(format, ap); + if (count == size) + { + /* there was no room for a NULL, so truncate the last character */ + outBuf[size - 1] = '\0'; + } + return count; } diff --git a/libretro-common/compat/compat_strcasestr.c b/libretro-common/compat/compat_strcasestr.c index 82ce5acb7b..54c93a48d0 100644 --- a/libretro-common/compat/compat_strcasestr.c +++ b/libretro-common/compat/compat_strcasestr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (compat_strcasestr.c). diff --git a/libretro-common/compat/compat_strl.c b/libretro-common/compat/compat_strl.c index d42fca3655..94cb39b62b 100644 --- a/libretro-common/compat/compat_strl.c +++ b/libretro-common/compat/compat_strl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (compat_strl.c). diff --git a/libretro-common/compat/compat_vscprintf.c b/libretro-common/compat/compat_vscprintf.c new file mode 100644 index 0000000000..ddffeb7e77 --- /dev/null +++ b/libretro-common/compat/compat_vscprintf.c @@ -0,0 +1,44 @@ +/* Copyright (C) 2010-2017 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (compat_snprintf.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* THIS FILE HAS NOT BEEN VALIDATED ON PLATFORMS BESIDES MSVC */ +#ifdef _MSC_VER + +#include + +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1800 +#define va_copy(dst, src) ((dst) = (src)) +#endif + +int c89_vscprintf_retro__(const char *format, va_list pargs) +{ + int retval; + va_list argcopy; + va_copy(argcopy, pargs); + retval = vsnprintf(NULL, 0, format, argcopy); + va_end(argcopy); + return retval; +} +#endif diff --git a/libretro-common/compat/fopen_utf8.c b/libretro-common/compat/fopen_utf8.c index d9fe35fec6..52b481e7e7 100644 --- a/libretro-common/compat/fopen_utf8.c +++ b/libretro-common/compat/fopen_utf8.c @@ -1,3 +1,25 @@ +/* Copyright (C) 2010-2018 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (fopen_utf8.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + #include #include #include diff --git a/libretro-common/dynamic/dylib.c b/libretro-common/dynamic/dylib.c index d4864a7057..bc6be9fc40 100644 --- a/libretro-common/dynamic/dylib.c +++ b/libretro-common/dynamic/dylib.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (dylib.c). diff --git a/libretro-common/encodings/encoding_crc32.c b/libretro-common/encodings/encoding_crc32.c index 0c1895a98f..4775e76357 100644 --- a/libretro-common/encodings/encoding_crc32.c +++ b/libretro-common/encodings/encoding_crc32.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (encoding_crc32.c). diff --git a/libretro-common/encodings/encoding_utf.c b/libretro-common/encodings/encoding_utf.c index d6c4ff4650..f7c533f144 100644 --- a/libretro-common/encodings/encoding_utf.c +++ b/libretro-common/encodings/encoding_utf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (encoding_utf.c). diff --git a/libretro-common/features/features_cpu.c b/libretro-common/features/features_cpu.c index dc3872043f..3a32a46c64 100644 --- a/libretro-common/features/features_cpu.c +++ b/libretro-common/features/features_cpu.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (features_cpu.c). diff --git a/libretro-common/file/archive_file.c b/libretro-common/file/archive_file.c index ca39050746..b2f35518f4 100644 --- a/libretro-common/file/archive_file.c +++ b/libretro-common/file/archive_file.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (archive_file.c). @@ -129,7 +129,7 @@ static void file_archive_free(file_archive_file_data_t *data) static file_archive_file_data_t* file_archive_open(const char *path) { - ssize_t ret = -1; + int64_t ret = -1; bool read_from_file = false; file_archive_file_data_t *data = (file_archive_file_data_t*) calloc(1, sizeof(*data)); @@ -722,7 +722,7 @@ error: */ int file_archive_compressed_read( const char * path, void **buf, - const char* optional_filename, ssize_t *length) + const char* optional_filename, int64_t *length) { const struct file_archive_file_backend *backend = NULL; int ret = 0; diff --git a/libretro-common/file/archive_file_7z.c b/libretro-common/file/archive_file_7z.c index 1afd5d4b83..0f00c0723d 100644 --- a/libretro-common/file/archive_file_7z.c +++ b/libretro-common/file/archive_file_7z.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (archive_file_sevenzip.c). diff --git a/libretro-common/file/archive_file_zlib.c b/libretro-common/file/archive_file_zlib.c index 4716ba95a3..293deb9f3a 100644 --- a/libretro-common/file/archive_file_zlib.c +++ b/libretro-common/file/archive_file_zlib.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (archive_file_zlib.c). @@ -240,22 +240,22 @@ static int zip_file_read( const char *needle, void **buf, const char *optional_outfile) { - file_archive_transfer_t zlib; + file_archive_transfer_t zlib = {ARCHIVE_TRANSFER_NONE, 0, NULL, NULL, NULL, NULL, NULL, NULL }; struct archive_extract_userdata userdata = {{0}}; - bool returnerr = true; - int ret = 0; + bool returnerr = true; + int ret = 0; - zlib.type = ARCHIVE_TRANSFER_INIT; + zlib.type = ARCHIVE_TRANSFER_INIT; - userdata.decomp_state.needle = NULL; - userdata.decomp_state.opt_file = NULL; - userdata.decomp_state.found = false; - userdata.decomp_state.buf = buf; + userdata.decomp_state.needle = NULL; + userdata.decomp_state.opt_file = NULL; + userdata.decomp_state.found = false; + userdata.decomp_state.buf = buf; if (needle) - userdata.decomp_state.needle = strdup(needle); + userdata.decomp_state.needle = strdup(needle); if (optional_outfile) - userdata.decomp_state.opt_file = strdup(optional_outfile); + userdata.decomp_state.opt_file = strdup(optional_outfile); do { diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index 50bdfd8e30..a8f8cfa808 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (config_file.c). diff --git a/libretro-common/file/config_file_userdata.c b/libretro-common/file/config_file_userdata.c index 8490fda4ad..e91fb8b04e 100644 --- a/libretro-common/file/config_file_userdata.c +++ b/libretro-common/file/config_file_userdata.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (config_file_userdata.c). diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index 880153ffc8..7c79b0b44f 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (file_path.c). @@ -392,7 +392,7 @@ char *path_remove_extension(char *path) return NULL; if (*last) *last = '\0'; - return last; + return path; } /** diff --git a/libretro-common/file/nbio/nbio_intf.c b/libretro-common/file/nbio/nbio_intf.c index cfcef60d2b..d6254ef08e 100644 --- a/libretro-common/file/nbio/nbio_intf.c +++ b/libretro-common/file/nbio/nbio_intf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (nbio_intf.c). diff --git a/libretro-common/file/nbio/nbio_linux.c b/libretro-common/file/nbio/nbio_linux.c index 8ef3f2bacb..8644bb94cb 100644 --- a/libretro-common/file/nbio/nbio_linux.c +++ b/libretro-common/file/nbio/nbio_linux.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (nbio_linux.c). diff --git a/libretro-common/file/nbio/nbio_stdio.c b/libretro-common/file/nbio/nbio_stdio.c index aa9d3cc522..f80e91a27b 100644 --- a/libretro-common/file/nbio/nbio_stdio.c +++ b/libretro-common/file/nbio/nbio_stdio.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (nbio_stdio.c). diff --git a/libretro-common/file/nbio/nbio_unixmmap.c b/libretro-common/file/nbio/nbio_unixmmap.c index 672b556663..29b574738d 100644 --- a/libretro-common/file/nbio/nbio_unixmmap.c +++ b/libretro-common/file/nbio/nbio_unixmmap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (nbio_unixmmap.c). diff --git a/libretro-common/file/nbio/nbio_windowsmmap.c b/libretro-common/file/nbio/nbio_windowsmmap.c index ff9d9d46e4..2bfd834a71 100644 --- a/libretro-common/file/nbio/nbio_windowsmmap.c +++ b/libretro-common/file/nbio/nbio_windowsmmap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (nbio_windowsmmap.c). diff --git a/libretro-common/file/retro_dirent.c b/libretro-common/file/retro_dirent.c index 9c53504732..0b6ecad246 100644 --- a/libretro-common/file/retro_dirent.c +++ b/libretro-common/file/retro_dirent.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_dirent.c). @@ -106,8 +106,14 @@ struct RDIR *retro_opendir(const char *name) wchar_t *path_wide = NULL; unsigned path_len; #endif - struct RDIR *rdir = (struct RDIR*)calloc(1, sizeof(*rdir)); + struct RDIR *rdir; + /*Reject null or empty string paths*/ + if (!name||(*name==0)) + return NULL; + + /*Allocate RDIR struct. Tidied later with retro_closedir*/ + rdir = (struct RDIR*)calloc(1, sizeof(*rdir)); if (!rdir) return NULL; diff --git a/libretro-common/formats/bmp/rbmp.c b/libretro-common/formats/bmp/rbmp.c index ee2b06f01d..1e7eaa9349 100644 --- a/libretro-common/formats/bmp/rbmp.c +++ b/libretro-common/formats/bmp/rbmp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rbmp.c). diff --git a/libretro-common/formats/bmp/rbmp_encode.c b/libretro-common/formats/bmp/rbmp_encode.c index 8b22f5ce31..50798b080f 100644 --- a/libretro-common/formats/bmp/rbmp_encode.c +++ b/libretro-common/formats/bmp/rbmp_encode.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rbmp_encode.c). diff --git a/libretro-common/formats/image_texture.c b/libretro-common/formats/image_texture.c index c531335e7b..e2f3c3d162 100644 --- a/libretro-common/formats/image_texture.c +++ b/libretro-common/formats/image_texture.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (image_texture.c). diff --git a/libretro-common/formats/image_transfer.c b/libretro-common/formats/image_transfer.c index 4c2bb5dd15..3f78b5356a 100644 --- a/libretro-common/formats/image_transfer.c +++ b/libretro-common/formats/image_transfer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (image_transfer.c). diff --git a/libretro-common/formats/jpeg/rjpeg.c b/libretro-common/formats/jpeg/rjpeg.c index 49490e82eb..0b1f7ea2c6 100644 --- a/libretro-common/formats/jpeg/rjpeg.c +++ b/libretro-common/formats/jpeg/rjpeg.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rjpeg.c). diff --git a/libretro-common/formats/json/jsonsax.c b/libretro-common/formats/json/jsonsax.c index fec8a7df8a..ec57c004da 100644 --- a/libretro-common/formats/json/jsonsax.c +++ b/libretro-common/formats/json/jsonsax.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (jsonsax.c). diff --git a/libretro-common/formats/libchdr/bitstream.c b/libretro-common/formats/libchdr/libchdr_bitstream.c similarity index 100% rename from libretro-common/formats/libchdr/bitstream.c rename to libretro-common/formats/libchdr/libchdr_bitstream.c diff --git a/libretro-common/formats/libchdr/cdrom.c b/libretro-common/formats/libchdr/libchdr_cdrom.c similarity index 100% rename from libretro-common/formats/libchdr/cdrom.c rename to libretro-common/formats/libchdr/libchdr_cdrom.c diff --git a/libretro-common/formats/libchdr/chd.c b/libretro-common/formats/libchdr/libchdr_chd.c similarity index 66% rename from libretro-common/formats/libchdr/chd.c rename to libretro-common/formats/libchdr/libchdr_chd.c index 78cac091bb..79a50aac2f 100644 --- a/libretro-common/formats/libchdr/chd.c +++ b/libretro-common/formats/libchdr/libchdr_chd.c @@ -38,18 +38,29 @@ ***************************************************************************/ #include +#include #include #include #include #include #include #include -#include #include -#include -#include -#include + +#ifdef HAVE_FLAC +#include +#endif + +#ifdef HAVE_7ZIP +#include +#endif + +#ifdef HAVE_ZLIB +#include +#endif + #include +#include #define TRUE 1 #define FALSE 0 @@ -71,33 +82,30 @@ #define OLD_MAP_ENTRY_SIZE 8 /* V1-V2 */ #define METADATA_HEADER_SIZE 16 /* metadata header size */ +#define CRCMAP_HASH_SIZE 4095 /* number of CRC hashtable entries */ + #define MAP_ENTRY_FLAG_TYPE_MASK 0x0f /* what type of hunk */ #define MAP_ENTRY_FLAG_NO_CRC 0x10 /* no CRC is present */ #define CHD_V1_SECTOR_SIZE 512 /* size of a "sector" in the V1 header */ #define COOKIE_VALUE 0xbaadf00d -#define MAX_ZLIB_ALLOCS 64 #define END_OF_LIST_COOKIE "EndOfListCookie" #define NO_MATCH (~0) -#ifdef WANT_RAW_DATA_SECTOR -static const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 }; -#endif +#define MAP_ENTRY_TYPE_INVALID 0x0000 /* invalid type */ +#define MAP_ENTRY_TYPE_COMPRESSED 0x0001 /* standard compression */ +#define MAP_ENTRY_TYPE_UNCOMPRESSED 0x0002 /* uncompressed data */ +#define MAP_ENTRY_TYPE_MINI 0x0003 /* mini: use offset as raw data */ +#define MAP_ENTRY_TYPE_SELF_HUNK 0x0004 /* same as another hunk in this file */ +#define MAP_ENTRY_TYPE_PARENT_HUNK 0x0005 /* same as a hunk in the parent file */ +#define MAP_ENTRY_TYPE_2ND_COMPRESSED 0x0006 /* compressed with secondary algorithm (usually FLAC CDDA) */ -/* V3-V4 entry types */ -enum -{ - V34_MAP_ENTRY_TYPE_INVALID = 0, /* invalid type */ - V34_MAP_ENTRY_TYPE_COMPRESSED = 1, /* standard compression */ - V34_MAP_ENTRY_TYPE_UNCOMPRESSED = 2, /* uncompressed data */ - V34_MAP_ENTRY_TYPE_MINI = 3, /* mini: use offset as raw data */ - V34_MAP_ENTRY_TYPE_SELF_HUNK = 4, /* same as another hunk in this file */ - V34_MAP_ENTRY_TYPE_PARENT_HUNK = 5, /* same as a hunk in the parent file */ - V34_MAP_ENTRY_TYPE_2ND_COMPRESSED = 6 /* compressed with secondary algorithm (usually FLAC CDDA) */ -}; +#ifdef WANT_RAW_DATA_SECTOR +const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 }; +#endif /* V5 compression types */ enum @@ -139,6 +147,8 @@ enum MACROS ***************************************************************************/ +#define SET_ERROR_AND_CLEANUP(err) do { last_error = (err); goto cleanup; } while (0) + #define EARLY_EXIT(x) do { (void)(x); goto cleanup; } while (0) /*************************************************************************** @@ -180,80 +190,12 @@ struct _metadata_entry UINT8 flags; /* flag bits */ }; -/* codec-private data for the ZLIB codec */ - -typedef struct _zlib_allocator zlib_allocator; -struct _zlib_allocator -{ - UINT32 * allocptr[MAX_ZLIB_ALLOCS]; -}; - -typedef struct _zlib_codec_data zlib_codec_data; -struct _zlib_codec_data -{ - z_stream inflater; - zlib_allocator allocator; -}; - -/* codec-private data for the LZMA codec */ -#define MAX_LZMA_ALLOCS 64 - -typedef struct _lzma_allocator lzma_allocator; -struct _lzma_allocator -{ - void *(*Alloc)(void *p, size_t size); - void (*Free)(void *p, void *address); /* address can be 0 */ - void (*FreeSz)(void *p, void *address, size_t size); /* address can be 0 */ - uint32_t* allocptr[MAX_LZMA_ALLOCS]; -}; - -typedef struct _lzma_codec_data lzma_codec_data; -struct _lzma_codec_data -{ - CLzmaDec decoder; - lzma_allocator allocator; -}; - -/* codec-private data for the CDZL codec */ -typedef struct _cdzl_codec_data cdzl_codec_data; -struct _cdzl_codec_data { - /* internal state */ - zlib_codec_data base_decompressor; -#ifdef WANT_SUBCODE - zlib_codec_data subcode_decompressor; -#endif - uint8_t* buffer; -}; - -/* codec-private data for the CDLZ codec */ -typedef struct _cdlz_codec_data cdlz_codec_data; -struct _cdlz_codec_data { - /* internal state */ - lzma_codec_data base_decompressor; -#ifdef WANT_SUBCODE - zlib_codec_data subcode_decompressor; -#endif - uint8_t* buffer; -}; - -/* codec-private data for the CDFL codec */ -typedef struct _cdfl_codec_data cdfl_codec_data; -struct _cdfl_codec_data { - /* internal state */ - int swap_endian; - flac_decoder decoder; -#ifdef WANT_SUBCODE - zlib_codec_data subcode_decompressor; -#endif - uint8_t* buffer; -}; - /* internal representation of an open CHD file */ struct _chd_file { UINT32 cookie; /* cookie, should equal COOKIE_VALUE */ - core_file * file; /* handle to the open core file */ + RFILE * file; /* handle to the open core file */ UINT8 owns_file; /* flag indicating if this file should be closed on chd_close() */ chd_header header; /* header, extracted from file */ @@ -272,14 +214,21 @@ struct _chd_file UINT8 * compressed; /* pointer to buffer for compressed data */ const codec_interface * codecintf[4]; /* interface to the codec */ +#ifdef HAVE_ZLIB zlib_codec_data zlib_codec_data; /* zlib codec data */ cdzl_codec_data cdzl_codec_data; /* cdzl codec data */ +#endif +#ifdef HAVE_7ZIP cdlz_codec_data cdlz_codec_data; /* cdlz codec data */ +#endif +#ifdef HAVE_FLAC cdfl_codec_data cdfl_codec_data; /* cdfl codec data */ +#endif #ifdef NEED_CACHE_HUNK UINT32 maxhunk; /* maximum hunk accessed */ #endif + UINT8 * file_cache; /* cache of underlying file */ }; /*************************************************************************** @@ -309,523 +258,6 @@ static chd_error map_read(chd_file *chd); /* metadata management */ static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metaindex, metadata_entry *metaentry); -/* zlib compression codec */ -static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes); -static void zlib_codec_free(void *codec); -static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); -static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size); -static void zlib_fast_free(voidpf opaque, voidpf address); - -/* lzma compression codec */ -static chd_error lzma_codec_init(void *codec, uint32_t hunkbytes); -static void lzma_codec_free(void *codec); -static chd_error lzma_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); - -/* cdzl compression codec */ -static chd_error cdzl_codec_init(void* codec, uint32_t hunkbytes); -static void cdzl_codec_free(void* codec); -static chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); - -/* cdlz compression codec */ -static chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes); -static void cdlz_codec_free(void* codec); -static chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); - -/* cdfl compression codec */ -static chd_error cdfl_codec_init(void* codec, uint32_t hunkbytes); -static void cdfl_codec_free(void* codec); -static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); - -/*************************************************************************** - * LZMA ALLOCATOR HELPER - *************************************************************************** - */ - -void *lzma_fast_alloc(void *p, size_t size); -void lzma_fast_free(void *p, void *address); - -/*------------------------------------------------- - * lzma_allocator_init - *------------------------------------------------- - */ - -void lzma_allocator_init(void* p) -{ - lzma_allocator *codec = (lzma_allocator *)(p); - - /* reset pointer list */ - memset(codec->allocptr, 0, sizeof(codec->allocptr)); - codec->Alloc = lzma_fast_alloc; - codec->Free = lzma_fast_free; -} - -/*------------------------------------------------- - * lzma_allocator_free - *------------------------------------------------- - */ - -void lzma_allocator_free(void* p ) -{ - lzma_allocator *codec = (lzma_allocator *)(p); - - /* free our memory */ - int i; - for (i = 0 ; i < MAX_LZMA_ALLOCS ; i++) - { - if (codec->allocptr[i] != NULL) - free(codec->allocptr[i]); - } -} - -/*------------------------------------------------- - * lzma_fast_alloc - fast malloc for lzma, which - * allocates and frees memory frequently - *------------------------------------------------- - */ - -void *lzma_fast_alloc(void *p, size_t size) -{ - int scan; - uint32_t *addr = NULL; - lzma_allocator *codec = (lzma_allocator *)(p); - - /* compute the size, rounding to the nearest 1k */ - size = (size + 0x3ff) & ~0x3ff; - - /* reuse a hunk if we can */ - for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++) - { - uint32_t *ptr = codec->allocptr[scan]; - if (ptr != NULL && size == *ptr) - { - /* set the low bit of the size so we don't match next time */ - *ptr |= 1; - return ptr + 1; - } - } - - /* alloc a new one and put it into the list */ - addr = (uint32_t *)malloc(sizeof(uint8_t) * (size + sizeof(uint32_t))); - if (addr==NULL) - return NULL; - for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++) - { - if (codec->allocptr[scan] == NULL) - { - codec->allocptr[scan] = addr; - break; - } - } - - /* set the low bit of the size so we don't match next time */ - *addr = size | 1; - return addr + 1; -} - -/*------------------------------------------------- - * lzma_fast_free - fast free for lzma, which - * allocates and frees memory frequently - *------------------------------------------------- - */ - -void lzma_fast_free(void *p, void *address) -{ - int scan; - uint32_t *ptr; - lzma_allocator *codec; - if (address == NULL) - return; - - codec = (lzma_allocator *)(p); - - /* find the hunk */ - ptr = (uint32_t *)(address) - 1; - for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++) - { - if (ptr == codec->allocptr[scan]) - { - /* clear the low bit of the size to allow matches */ - *ptr &= ~1; - return; - } - } -} - -/*************************************************************************** - * LZMA DECOMPRESSOR - *************************************************************************** - */ - -/*------------------------------------------------- - * lzma_codec_init - constructor - *------------------------------------------------- - */ - -chd_error lzma_codec_init(void* codec, uint32_t hunkbytes) -{ - CLzmaEncProps encoder_props; - CLzmaEncHandle enc; - Byte decoder_props[LZMA_PROPS_SIZE]; - lzma_allocator* alloc; - size_t props_size; - lzma_codec_data* lzma_codec = (lzma_codec_data*) codec; - - /* construct the decoder */ - LzmaDec_Construct(&lzma_codec->decoder); - - /* FIXME: this code is written in a way that makes it impossible to safely upgrade the LZMA SDK - * This code assumes that the current version of the encoder imposes the same requirements on the - * decoder as the encoder used to produce the file. This is not necessarily true. The format - * needs to be changed so the encoder properties are written to the file. - - * configure the properties like the compressor did */ - LzmaEncProps_Init(&encoder_props); - encoder_props.level = 9; - encoder_props.reduceSize = hunkbytes; - LzmaEncProps_Normalize(&encoder_props); - - /* convert to decoder properties */ - alloc = &lzma_codec->allocator; - lzma_allocator_init(alloc); - enc = LzmaEnc_Create((ISzAlloc*)alloc); - if (!enc) - return CHDERR_DECOMPRESSION_ERROR; - if (LzmaEnc_SetProps(enc, &encoder_props) != SZ_OK) - { - LzmaEnc_Destroy(enc, (ISzAlloc*)&alloc, (ISzAlloc*)&alloc); - return CHDERR_DECOMPRESSION_ERROR; - } - props_size = sizeof(decoder_props); - if (LzmaEnc_WriteProperties(enc, decoder_props, &props_size) != SZ_OK) - { - LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc); - return CHDERR_DECOMPRESSION_ERROR; - } - LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc); - - /* do memory allocations */ - if (LzmaDec_Allocate(&lzma_codec->decoder, decoder_props, LZMA_PROPS_SIZE, (ISzAlloc*)alloc) != SZ_OK) - return CHDERR_DECOMPRESSION_ERROR; - - /* Okay */ - return CHDERR_NONE; -} - -/*------------------------------------------------- - * lzma_codec_free - *------------------------------------------------- - */ - -void lzma_codec_free(void* codec) -{ - lzma_codec_data* lzma_codec = (lzma_codec_data*) codec; - lzma_allocator* alloc = &lzma_codec->allocator; - - /* free memory */ - lzma_allocator_free(alloc); - LzmaDec_Free(&lzma_codec->decoder, (ISzAlloc*)&lzma_codec->allocator); -} - -/*------------------------------------------------- - * decompress - decompress data using the LZMA - * codec - *------------------------------------------------- - */ - -chd_error lzma_codec_decompress(void* codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) -{ - ELzmaStatus status; - SRes res; - size_t consumedlen, decodedlen; - /* initialize */ - lzma_codec_data* lzma_codec = (lzma_codec_data*) codec; - LzmaDec_Init(&lzma_codec->decoder); - - /* decode */ - consumedlen = complen; - decodedlen = destlen; - res = LzmaDec_DecodeToBuf(&lzma_codec->decoder, dest, &decodedlen, src, &consumedlen, LZMA_FINISH_END, &status); - if ((res != SZ_OK && res != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) || consumedlen != complen || decodedlen != destlen) - return CHDERR_DECOMPRESSION_ERROR; - return CHDERR_NONE; -} - -/* cdlz */ -chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes) -{ - chd_error ret; - cdlz_codec_data* cdlz = (cdlz_codec_data*) codec; - - /* allocate buffer */ - cdlz->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes); - if (cdlz->buffer == NULL) - return CHDERR_OUT_OF_MEMORY; - - ret = lzma_codec_init(&cdlz->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); - if (ret != CHDERR_NONE) - return ret; - -#ifdef WANT_SUBCODE - ret = zlib_codec_init(&cdlz->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); - if (ret != CHDERR_NONE) - return ret; -#endif - - return CHDERR_NONE; -} - -void cdlz_codec_free(void* codec) -{ - cdlz_codec_data* cdlz = (cdlz_codec_data*) codec; - - lzma_codec_free(&cdlz->base_decompressor); -#ifdef WANT_SUBCODE - zlib_codec_free(&cdlz->subcode_decompressor); -#endif - if (cdlz->buffer) - free(cdlz->buffer); -} - -chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) -{ -#ifdef WANT_RAW_DATA_SECTOR - uint8_t *sector; -#endif - uint32_t framenum; - cdlz_codec_data* cdlz = (cdlz_codec_data*)codec; - - /* determine header bytes */ - uint32_t frames = destlen / CD_FRAME_SIZE; - uint32_t complen_bytes = (destlen < 65536) ? 2 : 3; - uint32_t ecc_bytes = (frames + 7) / 8; - uint32_t header_bytes = ecc_bytes + complen_bytes; - - /* extract compressed length of base */ - uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1]; - if (complen_bytes > 2) - complen_base = (complen_base << 8) | src[ecc_bytes + 2]; - - /* reset and decode */ - lzma_codec_decompress(&cdlz->base_decompressor, &src[header_bytes], complen_base, &cdlz->buffer[0], frames * CD_MAX_SECTOR_DATA); -#ifdef WANT_SUBCODE - if (header_bytes + complen_base >= complen) - return CHDERR_DECOMPRESSION_ERROR; - zlib_codec_decompress(&cdlz->subcode_decompressor, &src[header_bytes + complen_base], complen - complen_base - header_bytes, &cdlz->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA); -#endif - - /* reassemble the data */ - for (framenum = 0; framenum < frames; framenum++) - { - memcpy(&dest[framenum * CD_FRAME_SIZE], &cdlz->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA); -#ifdef WANT_SUBCODE - memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdlz->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA); -#endif - -#ifdef WANT_RAW_DATA_SECTOR - /* reconstitute the ECC data and sync header */ - sector = (uint8_t *)&dest[framenum * CD_FRAME_SIZE]; - if ((src[framenum / 8] & (1 << (framenum % 8))) != 0) - { - memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header)); - ecc_generate(sector); - } -#endif - } - return CHDERR_NONE; -} - -/* cdzl */ - -chd_error cdzl_codec_init(void *codec, uint32_t hunkbytes) -{ - chd_error ret; - cdzl_codec_data* cdzl = (cdzl_codec_data*)codec; - - /* make sure the CHD's hunk size is an even multiple of the frame size */ - if (hunkbytes % CD_FRAME_SIZE != 0) - return CHDERR_CODEC_ERROR; - - cdzl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes); - if (cdzl->buffer == NULL) - return CHDERR_OUT_OF_MEMORY; - - ret = zlib_codec_init(&cdzl->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); - if (ret != CHDERR_NONE) - return ret; - -#ifdef WANT_SUBCODE - ret = zlib_codec_init(&cdzl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); - if (ret != CHDERR_NONE) - return ret; -#endif - - return CHDERR_NONE; -} - -void cdzl_codec_free(void *codec) -{ - cdzl_codec_data* cdzl = (cdzl_codec_data*)codec; - - zlib_codec_free(&cdzl->base_decompressor); -#ifdef WANT_SUBCODE - zlib_codec_free(&cdzl->subcode_decompressor); -#endif - if (cdzl->buffer) - free(cdzl->buffer); -} - -chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) -{ -#ifdef WANT_RAW_DATA_SECTOR - uint8_t *sector; -#endif - uint32_t framenum; - cdzl_codec_data* cdzl = (cdzl_codec_data*)codec; - - /* determine header bytes */ - uint32_t frames = destlen / CD_FRAME_SIZE; - uint32_t complen_bytes = (destlen < 65536) ? 2 : 3; - uint32_t ecc_bytes = (frames + 7) / 8; - uint32_t header_bytes = ecc_bytes + complen_bytes; - - /* extract compressed length of base */ - uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1]; - if (complen_bytes > 2) - complen_base = (complen_base << 8) | src[ecc_bytes + 2]; - - /* reset and decode */ - zlib_codec_decompress(&cdzl->base_decompressor, &src[header_bytes], complen_base, &cdzl->buffer[0], frames * CD_MAX_SECTOR_DATA); -#ifdef WANT_SUBCODE - zlib_codec_decompress(&cdzl->subcode_decompressor, &src[header_bytes + complen_base], complen - complen_base - header_bytes, &cdzl->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA); -#endif - - /* reassemble the data */ - for (framenum = 0; framenum < frames; framenum++) - { - memcpy(&dest[framenum * CD_FRAME_SIZE], &cdzl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA); -#ifdef WANT_SUBCODE - memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdzl->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA); -#endif - -#ifdef WANT_RAW_DATA_SECTOR - /* reconstitute the ECC data and sync header */ - sector = (uint8_t *)&dest[framenum * CD_FRAME_SIZE]; - if ((src[framenum / 8] & (1 << (framenum % 8))) != 0) - { - memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header)); - ecc_generate(sector); - } -#endif - } - return CHDERR_NONE; -} - -/*************************************************************************** - * CD FLAC DECOMPRESSOR - *************************************************************************** - */ - -/*------------------------------------------------------ - * cdfl_codec_blocksize - return the optimal block size - *------------------------------------------------------ - */ - -static uint32_t cdfl_codec_blocksize(uint32_t bytes) -{ - /* determine FLAC block size, which must be 16-65535 - * clamp to 2k since that's supposed to be the sweet spot */ - uint32_t hunkbytes = bytes / 4; - while (hunkbytes > 2048) - hunkbytes /= 2; - return hunkbytes; -} - -chd_error cdfl_codec_init(void *codec, uint32_t hunkbytes) -{ -#ifdef WANT_SUBCODE - chd_error ret; -#endif - uint16_t native_endian = 0; - cdfl_codec_data *cdfl = (cdfl_codec_data*)codec; - - /* make sure the CHD's hunk size is an even multiple of the frame size */ - if (hunkbytes % CD_FRAME_SIZE != 0) - return CHDERR_CODEC_ERROR; - - cdfl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes); - if (cdfl->buffer == NULL) - return CHDERR_OUT_OF_MEMORY; - - /* determine whether we want native or swapped samples */ - *(uint8_t *)(&native_endian) = 1; - cdfl->swap_endian = (native_endian & 1); - -#ifdef WANT_SUBCODE - /* init zlib inflater */ - ret = zlib_codec_init(&cdfl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); - if (ret != CHDERR_NONE) - return ret; -#endif - - /* flac decoder init */ - flac_decoder_init(&cdfl->decoder); - if (cdfl->decoder.decoder == NULL) - return CHDERR_OUT_OF_MEMORY; - - return CHDERR_NONE; -} - -void cdfl_codec_free(void *codec) -{ - cdfl_codec_data *cdfl = (cdfl_codec_data*)codec; - flac_decoder_free(&cdfl->decoder); -#ifdef WANT_SUBCODE - zlib_codec_free(&cdfl->subcode_decompressor); -#endif - if (cdfl->buffer) - free(cdfl->buffer); -} - -chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) -{ - uint32_t framenum; - uint8_t *buffer; -#ifdef WANT_SUBCODE - uint32_t offset; - chd_error ret; -#endif - cdfl_codec_data *cdfl = (cdfl_codec_data*)codec; - - /* reset and decode */ - uint32_t frames = destlen / CD_FRAME_SIZE; - - if (!flac_decoder_reset(&cdfl->decoder, 44100, 2, cdfl_codec_blocksize(frames * CD_MAX_SECTOR_DATA), src, complen)) - return CHDERR_DECOMPRESSION_ERROR; - buffer = &cdfl->buffer[0]; - if (!flac_decoder_decode_interleaved(&cdfl->decoder, (int16_t *)(buffer), frames * CD_MAX_SECTOR_DATA/4, cdfl->swap_endian)) - return CHDERR_DECOMPRESSION_ERROR; - -#ifdef WANT_SUBCODE - /* inflate the subcode data */ - offset = flac_decoder_finish(&cdfl->decoder); - ret = zlib_codec_decompress(&cdfl->subcode_decompressor, src + offset, complen - offset, &cdfl->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA); - if (ret != CHDERR_NONE) - return ret; -#else - flac_decoder_finish(&cdfl->decoder); -#endif - - /* reassemble the data */ - for (framenum = 0; framenum < frames; framenum++) - { - memcpy(&dest[framenum * CD_FRAME_SIZE], &cdfl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA); -#ifdef WANT_SUBCODE - memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdfl->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA); -#endif - } - - return CHDERR_NONE; -} /*************************************************************************** CODEC INTERFACES ***************************************************************************/ @@ -850,6 +282,7 @@ static const codec_interface codec_interfaces[] = NULL }, +#ifdef HAVE_ZLIB /* standard zlib compression */ { CHDCOMPRESSION_ZLIB, @@ -882,7 +315,9 @@ static const codec_interface codec_interfaces[] = cdzl_codec_decompress, NULL }, +#endif +#ifdef HAVE_7ZIP /* V5 CD lzma compression */ { CHD_CODEC_CD_LZMA, @@ -893,7 +328,9 @@ static const codec_interface codec_interfaces[] = cdlz_codec_decompress, NULL }, +#endif +#ifdef HAVE_FLAC /* V5 CD flac compression */ { CHD_CODEC_CD_FLAC, @@ -904,6 +341,7 @@ static const codec_interface codec_interfaces[] = cdfl_codec_decompress, NULL }, +#endif }; /*************************************************************************** @@ -1146,8 +584,8 @@ static chd_error decompress_v5_map(chd_file* chd, chd_header* header) } /* read the reader */ - core_fseek(chd->file, header->mapoffset, SEEK_SET); - core_fread(chd->file, rawbuf, sizeof(rawbuf)); + filestream_seek(chd->file, header->mapoffset, SEEK_SET); + filestream_read(chd->file, rawbuf, sizeof(rawbuf)); mapbytes = get_bigendian_uint32(&rawbuf[0]); firstoffs = get_bigendian_uint48(&rawbuf[4]); mapcrc = get_bigendian_uint16(&rawbuf[10]); @@ -1160,8 +598,8 @@ static chd_error decompress_v5_map(chd_file* chd, chd_header* header) if (compressed == NULL) return CHDERR_OUT_OF_MEMORY; - core_fseek(chd->file, header->mapoffset + 16, SEEK_SET); - core_fread(chd->file, compressed, mapbytes); + filestream_seek(chd->file, header->mapoffset + 16, SEEK_SET); + filestream_read(chd->file, compressed, mapbytes); bitbuf = create_bitstream(compressed, sizeof(uint8_t) * mapbytes); if (bitbuf == NULL) { @@ -1297,7 +735,7 @@ static INLINE void map_extract_old(const UINT8 *base, map_entry *entry, UINT32 h entry->offset = get_bigendian_uint64(&base[0]); entry->crc = 0; entry->length = entry->offset >> 44; - entry->flags = MAP_ENTRY_FLAG_NO_CRC | ((entry->length == hunkbytes) ? V34_MAP_ENTRY_TYPE_UNCOMPRESSED : V34_MAP_ENTRY_TYPE_COMPRESSED); + entry->flags = MAP_ENTRY_FLAG_NO_CRC | ((entry->length == hunkbytes) ? MAP_ENTRY_TYPE_UNCOMPRESSED : MAP_ENTRY_TYPE_COMPRESSED); #ifdef __MWERKS__ entry->offset = entry->offset & 0x00000FFFFFFFFFFFLL; #else @@ -1313,7 +751,7 @@ static INLINE void map_extract_old(const UINT8 *base, map_entry *entry, UINT32 h chd_open_file - open a CHD file for access -------------------------------------------------*/ -chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **chd) +chd_error chd_open_file(RFILE *file, int mode, chd_file *parent, chd_file **chd) { chd_file *newchd = NULL; chd_error err; @@ -1405,29 +843,31 @@ chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file ** /* find the codec interface */ if (newchd->header.version < 5) { - for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++) + for (intfnum = 0; intfnum < ARRAY_SIZE(codec_interfaces); intfnum++) if (codec_interfaces[intfnum].compression == newchd->header.compression[0]) { newchd->codecintf[0] = &codec_interfaces[intfnum]; break; } - if (intfnum == ARRAY_LENGTH(codec_interfaces)) + if (intfnum == ARRAY_SIZE(codec_interfaces)) EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT); +#ifdef HAVE_ZLIB /* initialize the codec */ if (newchd->codecintf[0]->init != NULL) - { - err = (*newchd->codecintf[0]->init)(&newchd->zlib_codec_data, newchd->header.hunkbytes); - (void)err; - } + { + err = (*newchd->codecintf[0]->init)(&newchd->zlib_codec_data, newchd->header.hunkbytes); + (void)err; + } +#endif } else { int i, decompnum; /* verify the compression types and initialize the codecs */ - for (decompnum = 0; decompnum < ARRAY_LENGTH(newchd->header.compression); decompnum++) + for (decompnum = 0; decompnum < ARRAY_SIZE(newchd->header.compression); decompnum++) { - for (i = 0 ; i < ARRAY_LENGTH(codec_interfaces) ; i++) + for (i = 0 ; i < ARRAY_SIZE(codec_interfaces) ; i++) { if (codec_interfaces[i].compression == newchd->header.compression[decompnum]) { @@ -1445,15 +885,21 @@ chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file ** switch (newchd->header.compression[decompnum]) { case CHD_CODEC_CD_ZLIB: +#ifdef HAVE_ZLIB codec = &newchd->cdzl_codec_data; +#endif break; case CHD_CODEC_CD_LZMA: +#ifdef HAVE_7ZIP codec = &newchd->cdlz_codec_data; +#endif break; case CHD_CODEC_CD_FLAC: +#ifdef HAVE_FLAC codec = &newchd->cdfl_codec_data; +#endif break; } if (codec != NULL) @@ -1492,7 +938,7 @@ cleanup: chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd) { chd_error err; - core_file *file = NULL; + RFILE *file = NULL; /* choose the proper mode */ switch(mode) @@ -1506,8 +952,11 @@ chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file ** } /* open the file */ - file = core_fopen(filename); - if (file == 0) + file = filestream_open(filename, + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); + + if (!file) { err = CHDERR_FILE_NOT_FOUND; goto cleanup; @@ -1523,10 +972,36 @@ chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file ** cleanup: if ((err != CHDERR_NONE) && (file != NULL)) - core_fclose(file); + filestream_close(file); return err; } +chd_error chd_precache(chd_file *chd) +{ + int64_t size, count; + + if (!chd->file_cache) + { + filestream_seek(chd->file, 0, SEEK_END); + size = filestream_tell(chd->file); + if (size <= 0) + return CHDERR_INVALID_DATA; + chd->file_cache = malloc(size); + if (chd->file_cache == NULL) + return CHDERR_OUT_OF_MEMORY; + filestream_seek(chd->file, 0, SEEK_SET); + count = filestream_read(chd->file, chd->file_cache, size); + if (count != size) + { + free(chd->file_cache); + chd->file_cache = NULL; + return CHDERR_READ_ERROR; + } + } + + return CHDERR_NONE; +} + /*------------------------------------------------- chd_close - close a CHD file for access -------------------------------------------------*/ @@ -1540,35 +1015,41 @@ void chd_close(chd_file *chd) /* deinit the codec */ if (chd->header.version < 5) { +#ifdef HAVE_ZLIB if (chd->codecintf[0] != NULL && chd->codecintf[0]->free != NULL) (*chd->codecintf[0]->free)(&chd->zlib_codec_data); +#endif } else { int i; /* Free the codecs */ for (i = 0 ; i < 4 ; i++) - { - void* codec = NULL; - switch (chd->codecintf[i]->compression) - { - case CHD_CODEC_CD_LZMA: - codec = &chd->cdlz_codec_data; - break; + { + void* codec = NULL; + switch (chd->codecintf[i]->compression) + { + case CHD_CODEC_CD_LZMA: +#ifdef HAVE_7ZIP + codec = &chd->cdlz_codec_data; +#endif + break; - case CHD_CODEC_CD_ZLIB: - codec = &chd->cdzl_codec_data; - break; + case CHD_CODEC_CD_ZLIB: +#ifdef HAVE_ZLIB + codec = &chd->cdzl_codec_data; +#endif + break; - case CHD_CODEC_CD_FLAC: - codec = &chd->cdfl_codec_data; - break; - } - if (codec) - { - (*chd->codecintf[i]->free)(codec); - } - } + case CHD_CODEC_CD_FLAC: +#ifdef HAVE_FLAC + codec = &chd->cdfl_codec_data; +#endif + break; + } + if (codec) + (*chd->codecintf[i]->free)(codec); + } /* Free the raw map */ if (chd->header.rawmap != NULL) @@ -1593,12 +1074,15 @@ void chd_close(chd_file *chd) /* close the file */ if (chd->owns_file && chd->file != NULL) - core_fclose(chd->file); + filestream_close(chd->file); #ifdef NEED_CACHE_HUNK if (PRINTF_MAX_HUNK) printf("Max hunk = %d/%d\n", chd->maxhunk, chd->header.totalhunks); #endif + if (chd->file_cache) + free(chd->file_cache); + /* free our memory */ free(chd); } @@ -1608,7 +1092,7 @@ void chd_close(chd_file *chd) core_file -------------------------------------------------*/ -core_file *chd_core_file(chd_file *chd) +RFILE *chd_core_file(chd_file *chd) { return chd->file; } @@ -1704,7 +1188,7 @@ chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, { metadata_entry metaentry; chd_error err; - UINT32 count; + int64_t count; /* if we didn't find it, just return */ err = metadata_find_entry(chd, searchtag, searchindex, &metaentry); @@ -1735,8 +1219,8 @@ chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, /* read the metadata */ outputlen = MIN(outputlen, metaentry.length); - core_fseek(chd->file, metaentry.offset + METADATA_HEADER_SIZE, SEEK_SET); - count = core_fread(chd->file, output, outputlen); + filestream_seek(chd->file, metaentry.offset + METADATA_HEADER_SIZE, SEEK_SET); + count = filestream_read(chd->file, output, outputlen); if (count != outputlen) return CHDERR_READ_ERROR; @@ -1807,11 +1291,11 @@ static chd_error header_validate(const chd_header *header) return CHDERR_INVALID_PARAMETER; /* require a supported compression mechanism */ - for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++) + for (intfnum = 0; intfnum < ARRAY_SIZE(codec_interfaces); intfnum++) if (codec_interfaces[intfnum].compression == header->compression[0]) break; - if (intfnum == ARRAY_LENGTH(codec_interfaces)) + if (intfnum == ARRAY_SIZE(codec_interfaces)) return CHDERR_INVALID_PARAMETER; /* require a valid hunksize */ @@ -1875,7 +1359,7 @@ static UINT32 header_guess_unitbytes(chd_file *chd) static chd_error header_read(chd_file *chd, chd_header *header) { UINT8 rawheader[CHD_MAX_HEADER_SIZE]; - UINT32 count; + int64_t count; /* punt if NULL */ if (header == NULL) @@ -1886,8 +1370,8 @@ static chd_error header_read(chd_file *chd, chd_header *header) return CHDERR_INVALID_FILE; /* seek and read */ - core_fseek(chd->file, 0, SEEK_SET); - count = core_fread(chd->file, rawheader, sizeof(rawheader)); + filestream_seek(chd->file, 0, SEEK_SET); + count = filestream_read(chd->file, rawheader, sizeof(rawheader)); if (count != sizeof(rawheader)) return CHDERR_READ_ERROR; @@ -2034,6 +1518,35 @@ static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum) } #endif +static UINT8* read_compressed(chd_file *chd, UINT64 offset, size_t size) +{ + int64_t bytes; + if (chd->file_cache) + return chd->file_cache + offset; + filestream_seek(chd->file, offset, SEEK_SET); + bytes = filestream_read(chd->file, chd->compressed, size); + if (bytes != size) + return NULL; + return chd->compressed; +} + +static chd_error read_uncompressed(chd_file *chd, UINT64 offset, size_t size, UINT8 *dest) +{ + int64_t bytes; + if (chd->file_cache) + { + memcpy(dest, chd->file_cache + offset, size); + return CHDERR_NONE; + } + filestream_seek(chd->file, offset, SEEK_SET); + bytes = filestream_read(chd->file, dest, size); + if (bytes != size) + return CHDERR_READ_ERROR; + return CHDERR_NONE; +} + + + /*------------------------------------------------- hunk_read_into_memory - read a hunk into memory at the given location @@ -2056,7 +1569,6 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des if (chd->header.version < 5) { - void* codec; map_entry *entry = &chd->map[hunknum]; UINT32 bytes; @@ -2064,42 +1576,42 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des switch (entry->flags & MAP_ENTRY_FLAG_TYPE_MASK) { /* compressed data */ - case V34_MAP_ENTRY_TYPE_COMPRESSED: + case MAP_ENTRY_TYPE_COMPRESSED: + { + void *codec; + UINT8 *bytes = read_compressed(chd, entry->offset, + entry->length); + if (bytes == NULL) + return CHDERR_READ_ERROR; - /* read it into the decompression buffer */ - if (core_fseek(chd->file, entry->offset, SEEK_SET) != 0) - return CHDERR_READ_ERROR; - bytes = core_fread(chd->file, chd->compressed, entry->length); - if (bytes != entry->length) - return CHDERR_READ_ERROR; - - /* now decompress using the codec */ - err = CHDERR_NONE; - codec = &chd->zlib_codec_data; - if (chd->codecintf[0]->decompress != NULL) - err = (*chd->codecintf[0]->decompress)(codec, chd->compressed, entry->length, dest, chd->header.hunkbytes); - if (err != CHDERR_NONE) - return err; +#ifdef HAVE_ZLIB + /* now decompress using the codec */ + err = CHDERR_NONE; + codec = &chd->zlib_codec_data; + if (chd->codecintf[0]->decompress != NULL) + err = (*chd->codecintf[0]->decompress)(codec, chd->compressed, entry->length, dest, chd->header.hunkbytes); + if (err != CHDERR_NONE) + return err; +#endif + } break; /* uncompressed data */ - case V34_MAP_ENTRY_TYPE_UNCOMPRESSED: - if (core_fseek(chd->file, entry->offset, SEEK_SET) != 0) - return CHDERR_READ_ERROR; - bytes = core_fread(chd->file, dest, chd->header.hunkbytes); - if (bytes != chd->header.hunkbytes) - return CHDERR_READ_ERROR; + case MAP_ENTRY_TYPE_UNCOMPRESSED: + err = read_uncompressed(chd, entry->offset, chd->header.hunkbytes, dest); + if (err != CHDERR_NONE) + return err; break; /* mini-compressed data */ - case V34_MAP_ENTRY_TYPE_MINI: + case MAP_ENTRY_TYPE_MINI: put_bigendian_uint64(&dest[0], entry->offset); for (bytes = 8; bytes < chd->header.hunkbytes; bytes++) dest[bytes] = dest[bytes - 8]; break; /* self-referenced data */ - case V34_MAP_ENTRY_TYPE_SELF_HUNK: + case MAP_ENTRY_TYPE_SELF_HUNK: #ifdef NEED_CACHE_HUNK if (chd->cachehunk == entry->offset && dest == chd->cache) break; @@ -2107,7 +1619,7 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des return hunk_read_into_memory(chd, entry->offset, dest); /* parent-referenced data */ - case V34_MAP_ENTRY_TYPE_PARENT_HUNK: + case MAP_ENTRY_TYPE_PARENT_HUNK: err = hunk_read_into_memory(chd->parent, entry->offset, dest); if (err != CHDERR_NONE) return err; @@ -2125,6 +1637,7 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des uint16_t blockcrc; #endif uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum]; + UINT8 *bytes; #if 0 /* uncompressed case - TODO */ @@ -2155,23 +1668,27 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des case COMPRESSION_TYPE_1: case COMPRESSION_TYPE_2: case COMPRESSION_TYPE_3: - if (core_fseek(chd->file, blockoffs, SEEK_SET) != 0) - return CHDERR_READ_ERROR; - if(core_fread(chd->file, chd->compressed, blocklen) != blocklen) - return CHDERR_READ_ERROR; - + bytes = read_compressed(chd, blockoffs, blocklen); + if (bytes == NULL) + return CHDERR_READ_ERROR; switch (chd->codecintf[rawmap[0]]->compression) { case CHD_CODEC_CD_LZMA: +#ifdef HAVE_7ZIP codec = &chd->cdlz_codec_data; +#endif break; case CHD_CODEC_CD_ZLIB: +#ifdef HAVE_ZLIB codec = &chd->cdzl_codec_data; +#endif break; case CHD_CODEC_CD_FLAC: +#ifdef HAVE_FLAC codec = &chd->cdfl_codec_data; +#endif break; } if (codec==NULL) @@ -2186,13 +1703,12 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des return CHDERR_NONE; case COMPRESSION_NONE: - if (core_fseek(chd->file, blockoffs, SEEK_SET) != 0) - return CHDERR_READ_ERROR; - if (core_fread(chd->file, dest, chd->header.hunkbytes) != chd->header.hunkbytes) - return CHDERR_READ_ERROR; + err = read_uncompressed(chd, blockoffs, blocklen, dest); + if (err != CHDERR_NONE) + return err; #ifdef VERIFY_BLOCK_CRC - if (crc16(dest, chd->header.hunkbytes) != blockcrc) - return CHDERR_DECOMPRESSION_ERROR; + if (crc16(dest, chd->header.hunkbytes) != blockcrc) + return CHDERR_DECOMPRESSION_ERROR; #endif return CHDERR_NONE; @@ -2219,12 +1735,12 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des INTERNAL MAP ACCESS ***************************************************************************/ -static size_t core_fsize(core_file *f) +static size_t core_fsize(RFILE *f) { - long rv,p = ftell(f); - fseek(f, 0, SEEK_END); - rv = ftell(f); - fseek(f, p, SEEK_SET); + int64_t rv, p = filestream_tell(f); + filestream_seek(f, 0, SEEK_END); + rv = filestream_tell(f); + filestream_seek(f, p, SEEK_SET); return rv; } @@ -2238,7 +1754,7 @@ static chd_error map_read(chd_file *chd) UINT8 raw_map_entries[MAP_STACK_ENTRIES * MAP_ENTRY_SIZE]; UINT64 fileoffset, maxoffset = 0; UINT8 cookie[MAP_ENTRY_SIZE]; - UINT32 count; + int64_t count; chd_error err; int i; @@ -2257,8 +1773,8 @@ static chd_error map_read(chd_file *chd) entries = MAP_STACK_ENTRIES; /* read that many */ - core_fseek(chd->file, fileoffset, SEEK_SET); - count = core_fread(chd->file, raw_map_entries, entries * entrysize); + filestream_seek(chd->file, fileoffset, SEEK_SET); + count = filestream_read(chd->file, raw_map_entries, entries * entrysize); if (count != entries * entrysize) { err = CHDERR_READ_ERROR; @@ -2280,14 +1796,14 @@ static chd_error map_read(chd_file *chd) /* track the maximum offset */ for (j = 0; j < entries; j++) - if ((chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_COMPRESSED || - (chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_UNCOMPRESSED) + if ((chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == MAP_ENTRY_TYPE_COMPRESSED || + (chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == MAP_ENTRY_TYPE_UNCOMPRESSED) maxoffset = MAX(maxoffset, chd->map[i + j].offset + chd->map[i + j].length); } /* verify the cookie */ - core_fseek(chd->file, fileoffset, SEEK_SET); - count = core_fread(chd->file, &cookie, entrysize); + filestream_seek(chd->file, fileoffset, SEEK_SET); + count = filestream_read(chd->file, &cookie, entrysize); if (count != entrysize || memcmp(&cookie, END_OF_LIST_COOKIE, entrysize)) { err = CHDERR_INVALID_FILE; @@ -2327,11 +1843,11 @@ static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metai while (metaentry->offset != 0) { UINT8 raw_meta_header[METADATA_HEADER_SIZE]; - UINT32 count; + int64_t count; /* read the raw header */ - core_fseek(chd->file, metaentry->offset, SEEK_SET); - count = core_fread(chd->file, raw_meta_header, sizeof(raw_meta_header)); + filestream_seek(chd->file, metaentry->offset, SEEK_SET); + count = filestream_read(chd->file, raw_meta_header, sizeof(raw_meta_header)); if (count != sizeof(raw_meta_header)) break; @@ -2357,159 +1873,3 @@ static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metai /* if we get here, we didn't find it */ return CHDERR_METADATA_NOT_FOUND; } - -/*************************************************************************** - ZLIB COMPRESSION CODEC -***************************************************************************/ - -/*------------------------------------------------- - zlib_codec_init - initialize the ZLIB codec --------------------------------------------------*/ - -static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes) -{ - int zerr; - chd_error err; - zlib_codec_data *data = (zlib_codec_data*)codec; - - /* clear the buffers */ - memset(data, 0, sizeof(zlib_codec_data)); - - /* init the inflater first */ - data->inflater.next_in = (Bytef *)data; /* bogus, but that's ok */ - data->inflater.avail_in = 0; - data->inflater.zalloc = zlib_fast_alloc; - data->inflater.zfree = zlib_fast_free; - data->inflater.opaque = &data->allocator; - zerr = inflateInit2(&data->inflater, -MAX_WBITS); - - /* convert errors */ - if (zerr == Z_MEM_ERROR) - err = CHDERR_OUT_OF_MEMORY; - else if (zerr != Z_OK) - err = CHDERR_CODEC_ERROR; - else - err = CHDERR_NONE; - - return err; -} - -/*------------------------------------------------- - zlib_codec_free - free data for the ZLIB - codec --------------------------------------------------*/ - -static void zlib_codec_free(void *codec) -{ - zlib_codec_data *data = (zlib_codec_data *)codec; - - /* deinit the streams */ - if (data != NULL) - { - int i; - zlib_allocator alloc; - - inflateEnd(&data->inflater); - - /* free our fast memory */ - alloc = data->allocator; - for (i = 0; i < MAX_ZLIB_ALLOCS; i++) - if (alloc.allocptr[i]) - free(alloc.allocptr[i]); - } -} - -/*------------------------------------------------- - zlib_codec_decompress - decomrpess data using - the ZLIB codec --------------------------------------------------*/ - -static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) -{ - zlib_codec_data *data = (zlib_codec_data *)codec; - int zerr; - - /* reset the decompressor */ - data->inflater.next_in = (Bytef *)src; - data->inflater.avail_in = complen; - data->inflater.total_in = 0; - data->inflater.next_out = (Bytef *)dest; - data->inflater.avail_out = destlen; - data->inflater.total_out = 0; - zerr = inflateReset(&data->inflater); - if (zerr != Z_OK) - return CHDERR_DECOMPRESSION_ERROR; - - /* do it */ - zerr = inflate(&data->inflater, Z_FINISH); - (void)zerr; - if (data->inflater.total_out != destlen) - return CHDERR_DECOMPRESSION_ERROR; - - return CHDERR_NONE; -} - -/*------------------------------------------------- - zlib_fast_alloc - fast malloc for ZLIB, which - allocates and frees memory frequently --------------------------------------------------*/ - -static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size) -{ - zlib_allocator *alloc = (zlib_allocator *)opaque; - UINT32 *ptr; - int i; - - /* compute the size, rounding to the nearest 1k */ - size = (size * items + 0x3ff) & ~0x3ff; - - /* reuse a hunk if we can */ - for (i = 0; i < MAX_ZLIB_ALLOCS; i++) - { - ptr = alloc->allocptr[i]; - if (ptr && size == *ptr) - { - /* set the low bit of the size so we don't match next time */ - *ptr |= 1; - return ptr + 1; - } - } - - /* alloc a new one */ - ptr = (UINT32 *)malloc(size + sizeof(UINT32)); - if (!ptr) - return NULL; - - /* put it into the list */ - for (i = 0; i < MAX_ZLIB_ALLOCS; i++) - if (!alloc->allocptr[i]) - { - alloc->allocptr[i] = ptr; - break; - } - - /* set the low bit of the size so we don't match next time */ - *ptr = size | 1; - return ptr + 1; -} - -/*------------------------------------------------- - zlib_fast_free - fast free for ZLIB, which - allocates and frees memory frequently --------------------------------------------------*/ - -static void zlib_fast_free(voidpf opaque, voidpf address) -{ - zlib_allocator *alloc = (zlib_allocator *)opaque; - UINT32 *ptr = (UINT32 *)address - 1; - int i; - - /* find the hunk */ - for (i = 0; i < MAX_ZLIB_ALLOCS; i++) - if (ptr == alloc->allocptr[i]) - { - /* clear the low bit of the size to allow matches */ - *ptr &= ~1; - return; - } -} diff --git a/libretro-common/formats/libchdr/flac.c b/libretro-common/formats/libchdr/libchdr_flac.c similarity index 99% rename from libretro-common/formats/libchdr/flac.c rename to libretro-common/formats/libchdr/libchdr_flac.c index 8fe0cf7752..4cc5dc20a4 100644 --- a/libretro-common/formats/libchdr/flac.c +++ b/libretro-common/formats/libchdr/libchdr_flac.c @@ -12,6 +12,7 @@ #include #include #include +#include /*************************************************************************** * FLAC DECODER @@ -153,7 +154,7 @@ bool flac_decoder::decode(int16_t **samples, uint32_t num_samples, bool swap_end { /* make sure we don't have too many channels */ int chans = channels(); - if (chans > ARRAY_LENGTH(m_uncompressed_start)) + if (chans > ARRAY_SIZE(m_uncompressed_start)) return false; /* configure the uncompressed buffer */ diff --git a/libretro-common/formats/libchdr/libchdr_flac_codec.c b/libretro-common/formats/libchdr/libchdr_flac_codec.c new file mode 100644 index 0000000000..83abadd3f2 --- /dev/null +++ b/libretro-common/formats/libchdr/libchdr_flac_codec.c @@ -0,0 +1,163 @@ +/*************************************************************************** + + libchdr_flac_codec.c + + MAME Compressed Hunks of Data file format + +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define TRUE 1 +#define FALSE 0 + +/*************************************************************************** + * CD FLAC DECOMPRESSOR + *************************************************************************** + */ + +/*------------------------------------------------------ + * cdfl_codec_blocksize - return the optimal block size + *------------------------------------------------------ + */ + +static uint32_t cdfl_codec_blocksize(uint32_t bytes) +{ + /* determine FLAC block size, which must be 16-65535 + * clamp to 2k since that's supposed to be the sweet spot */ + uint32_t hunkbytes = bytes / 4; + while (hunkbytes > 2048) + hunkbytes /= 2; + return hunkbytes; +} + +chd_error cdfl_codec_init(void *codec, uint32_t hunkbytes) +{ +#ifdef WANT_SUBCODE + chd_error ret; +#endif + uint16_t native_endian = 0; + cdfl_codec_data *cdfl = (cdfl_codec_data*)codec; + + /* make sure the CHD's hunk size is an even multiple of the frame size */ + if (hunkbytes % CD_FRAME_SIZE != 0) + return CHDERR_CODEC_ERROR; + + cdfl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes); + if (cdfl->buffer == NULL) + return CHDERR_OUT_OF_MEMORY; + + /* determine whether we want native or swapped samples */ + *(uint8_t *)(&native_endian) = 1; + cdfl->swap_endian = (native_endian & 1); + +#ifdef WANT_SUBCODE + /* init zlib inflater */ + ret = zlib_codec_init(&cdfl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); + if (ret != CHDERR_NONE) + return ret; +#endif + + /* flac decoder init */ + flac_decoder_init(&cdfl->decoder); + if (cdfl->decoder.decoder == NULL) + return CHDERR_OUT_OF_MEMORY; + + return CHDERR_NONE; +} + +void cdfl_codec_free(void *codec) +{ + cdfl_codec_data *cdfl = (cdfl_codec_data*)codec; + flac_decoder_free(&cdfl->decoder); +#ifdef WANT_SUBCODE + zlib_codec_free(&cdfl->subcode_decompressor); +#endif + if (cdfl->buffer) + free(cdfl->buffer); +} + +chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) +{ + uint32_t framenum; + uint8_t *buffer; +#ifdef WANT_SUBCODE + uint32_t offset; + chd_error ret; +#endif + cdfl_codec_data *cdfl = (cdfl_codec_data*)codec; + + /* reset and decode */ + uint32_t frames = destlen / CD_FRAME_SIZE; + + if (!flac_decoder_reset(&cdfl->decoder, 44100, 2, cdfl_codec_blocksize(frames * CD_MAX_SECTOR_DATA), src, complen)) + return CHDERR_DECOMPRESSION_ERROR; + buffer = &cdfl->buffer[0]; + if (!flac_decoder_decode_interleaved(&cdfl->decoder, (int16_t *)(buffer), frames * CD_MAX_SECTOR_DATA/4, cdfl->swap_endian)) + return CHDERR_DECOMPRESSION_ERROR; + +#ifdef WANT_SUBCODE + /* inflate the subcode data */ + offset = flac_decoder_finish(&cdfl->decoder); + ret = zlib_codec_decompress(&cdfl->subcode_decompressor, src + offset, complen - offset, &cdfl->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA); + if (ret != CHDERR_NONE) + return ret; +#else + flac_decoder_finish(&cdfl->decoder); +#endif + + /* reassemble the data */ + for (framenum = 0; framenum < frames; framenum++) + { + memcpy(&dest[framenum * CD_FRAME_SIZE], &cdfl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA); +#ifdef WANT_SUBCODE + memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdfl->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA); +#endif + } + + return CHDERR_NONE; +} diff --git a/libretro-common/formats/libchdr/huffman.c b/libretro-common/formats/libchdr/libchdr_huffman.c similarity index 99% rename from libretro-common/formats/libchdr/huffman.c rename to libretro-common/formats/libchdr/libchdr_huffman.c index 04b0300dd0..dd041a76c9 100644 --- a/libretro-common/formats/libchdr/huffman.c +++ b/libretro-common/formats/libchdr/libchdr_huffman.c @@ -294,7 +294,10 @@ enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder, /* make sure we ended up with the right number */ if (curcode != decoder->numcodes) + { + delete_huffman_decoder(smallhuff); return HUFFERR_INVALID_DATA; + } /* assign canonical codes for all nodes based on their code lengths */ error = huffman_assign_canonical_codes(decoder); diff --git a/libretro-common/formats/libchdr/libchdr_lzma.c b/libretro-common/formats/libchdr/libchdr_lzma.c new file mode 100644 index 0000000000..096c6efb0f --- /dev/null +++ b/libretro-common/formats/libchdr/libchdr_lzma.c @@ -0,0 +1,355 @@ +/*************************************************************************** + + libchdr_lzma_codec.c + + MAME Compressed Hunks of Data file format + +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define TRUE 1 +#define FALSE 0 + +/*************************************************************************** + * LZMA ALLOCATOR HELPER + *************************************************************************** + */ + +/*------------------------------------------------- + * lzma_fast_alloc - fast malloc for lzma, which + * allocates and frees memory frequently + *------------------------------------------------- + */ + +static void *lzma_fast_alloc(void *p, size_t size) +{ + int scan; + uint32_t *addr = NULL; + lzma_allocator *codec = (lzma_allocator *)(p); + + /* compute the size, rounding to the nearest 1k */ + size = (size + 0x3ff) & ~0x3ff; + + /* reuse a hunk if we can */ + for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++) + { + uint32_t *ptr = codec->allocptr[scan]; + if (ptr != NULL && size == *ptr) + { + /* set the low bit of the size so we don't match next time */ + *ptr |= 1; + return ptr + 1; + } + } + + /* alloc a new one and put it into the list */ + addr = (uint32_t *)malloc(sizeof(uint32_t) * (size + sizeof(uint32_t))); + if (!addr) + return NULL; + + for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++) + { + if (codec->allocptr[scan] == NULL) + { + codec->allocptr[scan] = addr; + break; + } + } + + /* set the low bit of the size so we don't match next time */ + *addr = size | 1; + return addr + 1; +} + +/*------------------------------------------------- + * lzma_fast_free - fast free for lzma, which + * allocates and frees memory frequently + *------------------------------------------------- + */ +static void lzma_fast_free(void *p, void *address) +{ + int scan; + uint32_t *ptr; + lzma_allocator *codec; + if (address == NULL) + return; + + codec = (lzma_allocator *)(p); + + /* find the hunk */ + ptr = (uint32_t *)(address) - 1; + for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++) + { + if (ptr == codec->allocptr[scan]) + { + /* clear the low bit of the size to allow matches */ + *ptr &= ~1; + return; + } + } +} + + +/*------------------------------------------------- + * lzma_allocator_init + *------------------------------------------------- + */ + +void lzma_allocator_init(void* p) +{ + lzma_allocator *codec = (lzma_allocator *)(p); + + /* reset pointer list */ + memset(codec->allocptr, 0, sizeof(codec->allocptr)); + codec->Alloc = lzma_fast_alloc; + codec->Free = lzma_fast_free; +} + +/*------------------------------------------------- + * lzma_allocator_free + *------------------------------------------------- + */ + +void lzma_allocator_free(void* p ) +{ + lzma_allocator *codec = (lzma_allocator *)(p); + + /* free our memory */ + int i; + for (i = 0 ; i < MAX_LZMA_ALLOCS ; i++) + { + if (codec->allocptr[i] != NULL) + free(codec->allocptr[i]); + } +} + + + +/*************************************************************************** + * LZMA DECOMPRESSOR + *************************************************************************** + */ + +/*------------------------------------------------- + * lzma_codec_init - constructor + *------------------------------------------------- + */ + +chd_error lzma_codec_init(void* codec, uint32_t hunkbytes) +{ + CLzmaEncProps encoder_props; + CLzmaEncHandle enc; + uint8_t decoder_props[LZMA_PROPS_SIZE]; + lzma_allocator* alloc; + size_t props_size; + lzma_codec_data* lzma_codec = (lzma_codec_data*) codec; + + /* construct the decoder */ + LzmaDec_Construct(&lzma_codec->decoder); + + /* FIXME: this code is written in a way that makes it impossible to safely upgrade the LZMA SDK + * This code assumes that the current version of the encoder imposes the same requirements on the + * decoder as the encoder used to produce the file. This is not necessarily true. The format + * needs to be changed so the encoder properties are written to the file. + + * configure the properties like the compressor did */ + LzmaEncProps_Init(&encoder_props); + encoder_props.level = 9; + encoder_props.reduceSize = hunkbytes; + LzmaEncProps_Normalize(&encoder_props); + + /* convert to decoder properties */ + alloc = &lzma_codec->allocator; + lzma_allocator_init(alloc); + enc = LzmaEnc_Create((ISzAlloc*)alloc); + if (!enc) + return CHDERR_DECOMPRESSION_ERROR; + if (LzmaEnc_SetProps(enc, &encoder_props) != SZ_OK) + { + LzmaEnc_Destroy(enc, (ISzAlloc*)&alloc, (ISzAlloc*)&alloc); + return CHDERR_DECOMPRESSION_ERROR; + } + props_size = sizeof(decoder_props); + if (LzmaEnc_WriteProperties(enc, decoder_props, &props_size) != SZ_OK) + { + LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc); + return CHDERR_DECOMPRESSION_ERROR; + } + LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc); + + /* do memory allocations */ + if (LzmaDec_Allocate(&lzma_codec->decoder, decoder_props, LZMA_PROPS_SIZE, (ISzAlloc*)alloc) != SZ_OK) + return CHDERR_DECOMPRESSION_ERROR; + + /* Okay */ + return CHDERR_NONE; +} + +/*------------------------------------------------- + * lzma_codec_free + *------------------------------------------------- + */ + +void lzma_codec_free(void* codec) +{ + lzma_codec_data* lzma_codec = (lzma_codec_data*) codec; + lzma_allocator* alloc = &lzma_codec->allocator; + + /* free memory */ + lzma_allocator_free(alloc); + LzmaDec_Free(&lzma_codec->decoder, (ISzAlloc*)&lzma_codec->allocator); +} + +/*------------------------------------------------- + * decompress - decompress data using the LZMA + * codec + *------------------------------------------------- + */ + +chd_error lzma_codec_decompress(void* codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) +{ + ELzmaStatus status; + SRes res; + size_t consumedlen, decodedlen; + /* initialize */ + lzma_codec_data* lzma_codec = (lzma_codec_data*) codec; + LzmaDec_Init(&lzma_codec->decoder); + + /* decode */ + consumedlen = complen; + decodedlen = destlen; + res = LzmaDec_DecodeToBuf(&lzma_codec->decoder, dest, &decodedlen, src, &consumedlen, LZMA_FINISH_END, &status); + if ((res != SZ_OK && res != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) || consumedlen != complen || decodedlen != destlen) + return CHDERR_DECOMPRESSION_ERROR; + return CHDERR_NONE; +} + +/* cdlz */ +chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes) +{ + chd_error ret; + cdlz_codec_data* cdlz = (cdlz_codec_data*) codec; + + /* allocate buffer */ + cdlz->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes); + if (cdlz->buffer == NULL) + return CHDERR_OUT_OF_MEMORY; + + ret = lzma_codec_init(&cdlz->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); + if (ret != CHDERR_NONE) + return ret; + +#ifdef WANT_SUBCODE + ret = zlib_codec_init(&cdlz->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); + if (ret != CHDERR_NONE) + return ret; +#endif + + return CHDERR_NONE; +} + +void cdlz_codec_free(void* codec) +{ + cdlz_codec_data* cdlz = (cdlz_codec_data*) codec; + + lzma_codec_free(&cdlz->base_decompressor); +#ifdef WANT_SUBCODE + zlib_codec_free(&cdlz->subcode_decompressor); +#endif + if (cdlz->buffer) + free(cdlz->buffer); +} + +chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) +{ +#ifdef WANT_RAW_DATA_SECTOR + uint8_t *sector; +#endif + uint32_t framenum; + cdlz_codec_data* cdlz = (cdlz_codec_data*)codec; + + /* determine header bytes */ + uint32_t frames = destlen / CD_FRAME_SIZE; + uint32_t complen_bytes = (destlen < 65536) ? 2 : 3; + uint32_t ecc_bytes = (frames + 7) / 8; + uint32_t header_bytes = ecc_bytes + complen_bytes; + + /* extract compressed length of base */ + uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1]; + if (complen_bytes > 2) + complen_base = (complen_base << 8) | src[ecc_bytes + 2]; + + /* reset and decode */ + lzma_codec_decompress(&cdlz->base_decompressor, &src[header_bytes], complen_base, &cdlz->buffer[0], frames * CD_MAX_SECTOR_DATA); +#ifdef WANT_SUBCODE + if (header_bytes + complen_base >= complen) + return CHDERR_DECOMPRESSION_ERROR; + zlib_codec_decompress(&cdlz->subcode_decompressor, &src[header_bytes + complen_base], complen - complen_base - header_bytes, &cdlz->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA); +#endif + + /* reassemble the data */ + for (framenum = 0; framenum < frames; framenum++) + { + memcpy(&dest[framenum * CD_FRAME_SIZE], &cdlz->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA); +#ifdef WANT_SUBCODE + memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdlz->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA); +#endif + +#ifdef WANT_RAW_DATA_SECTOR + /* reconstitute the ECC data and sync header */ + sector = (uint8_t *)&dest[framenum * CD_FRAME_SIZE]; + if ((src[framenum / 8] & (1 << (framenum % 8))) != 0) + { + memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header)); + ecc_generate(sector); + } +#endif + } + return CHDERR_NONE; +} + diff --git a/libretro-common/formats/libchdr/libchdr_zlib.c b/libretro-common/formats/libchdr/libchdr_zlib.c new file mode 100644 index 0000000000..44c642f81e --- /dev/null +++ b/libretro-common/formats/libchdr/libchdr_zlib.c @@ -0,0 +1,298 @@ +/*************************************************************************** + + libchdr_zlib.c + + MAME Compressed Hunks of Data file format + +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define TRUE 1 +#define FALSE 0 + +/* cdzl */ + +chd_error cdzl_codec_init(void *codec, uint32_t hunkbytes) +{ + chd_error ret; + cdzl_codec_data* cdzl = (cdzl_codec_data*)codec; + + /* make sure the CHD's hunk size is an even multiple of the frame size */ + if (hunkbytes % CD_FRAME_SIZE != 0) + return CHDERR_CODEC_ERROR; + + cdzl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes); + if (cdzl->buffer == NULL) + return CHDERR_OUT_OF_MEMORY; + + ret = zlib_codec_init(&cdzl->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); + if (ret != CHDERR_NONE) + return ret; + +#ifdef WANT_SUBCODE + ret = zlib_codec_init(&cdzl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); + if (ret != CHDERR_NONE) + return ret; +#endif + + return CHDERR_NONE; +} + +void cdzl_codec_free(void *codec) +{ + cdzl_codec_data* cdzl = (cdzl_codec_data*)codec; + + zlib_codec_free(&cdzl->base_decompressor); +#ifdef WANT_SUBCODE + zlib_codec_free(&cdzl->subcode_decompressor); +#endif + if (cdzl->buffer) + free(cdzl->buffer); +} + +chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) +{ +#ifdef WANT_RAW_DATA_SECTOR + uint8_t *sector; +#endif + uint32_t framenum; + cdzl_codec_data* cdzl = (cdzl_codec_data*)codec; + + /* determine header bytes */ + uint32_t frames = destlen / CD_FRAME_SIZE; + uint32_t complen_bytes = (destlen < 65536) ? 2 : 3; + uint32_t ecc_bytes = (frames + 7) / 8; + uint32_t header_bytes = ecc_bytes + complen_bytes; + + /* extract compressed length of base */ + uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1]; + if (complen_bytes > 2) + complen_base = (complen_base << 8) | src[ecc_bytes + 2]; + + /* reset and decode */ + zlib_codec_decompress(&cdzl->base_decompressor, &src[header_bytes], complen_base, &cdzl->buffer[0], frames * CD_MAX_SECTOR_DATA); +#ifdef WANT_SUBCODE + zlib_codec_decompress(&cdzl->subcode_decompressor, &src[header_bytes + complen_base], complen - complen_base - header_bytes, &cdzl->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA); +#endif + + /* reassemble the data */ + for (framenum = 0; framenum < frames; framenum++) + { + memcpy(&dest[framenum * CD_FRAME_SIZE], &cdzl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA); +#ifdef WANT_SUBCODE + memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdzl->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA); +#endif + +#ifdef WANT_RAW_DATA_SECTOR + /* reconstitute the ECC data and sync header */ + sector = (uint8_t *)&dest[framenum * CD_FRAME_SIZE]; + if ((src[framenum / 8] & (1 << (framenum % 8))) != 0) + { + memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header)); + ecc_generate(sector); + } +#endif + } + return CHDERR_NONE; +} + +/*************************************************************************** + ZLIB COMPRESSION CODEC +***************************************************************************/ + +/*------------------------------------------------- + zlib_codec_init - initialize the ZLIB codec +-------------------------------------------------*/ + +chd_error zlib_codec_init(void *codec, uint32_t hunkbytes) +{ + int zerr; + chd_error err; + zlib_codec_data *data = (zlib_codec_data*)codec; + + /* clear the buffers */ + memset(data, 0, sizeof(zlib_codec_data)); + + /* init the inflater first */ + data->inflater.next_in = (Bytef *)data; /* bogus, but that's ok */ + data->inflater.avail_in = 0; + data->inflater.zalloc = zlib_fast_alloc; + data->inflater.zfree = zlib_fast_free; + data->inflater.opaque = &data->allocator; + zerr = inflateInit2(&data->inflater, -MAX_WBITS); + + /* convert errors */ + if (zerr == Z_MEM_ERROR) + err = CHDERR_OUT_OF_MEMORY; + else if (zerr != Z_OK) + err = CHDERR_CODEC_ERROR; + else + err = CHDERR_NONE; + + return err; +} + +/*------------------------------------------------- + zlib_codec_free - free data for the ZLIB + codec +-------------------------------------------------*/ + +void zlib_codec_free(void *codec) +{ + zlib_codec_data *data = (zlib_codec_data *)codec; + + /* deinit the streams */ + if (data != NULL) + { + int i; + zlib_allocator alloc; + + inflateEnd(&data->inflater); + + /* free our fast memory */ + alloc = data->allocator; + for (i = 0; i < MAX_ZLIB_ALLOCS; i++) + if (alloc.allocptr[i]) + free(alloc.allocptr[i]); + } +} + +/*------------------------------------------------- + zlib_codec_decompress - decomrpess data using + the ZLIB codec +-------------------------------------------------*/ + +chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) +{ + zlib_codec_data *data = (zlib_codec_data *)codec; + int zerr; + + /* reset the decompressor */ + data->inflater.next_in = (Bytef *)src; + data->inflater.avail_in = complen; + data->inflater.total_in = 0; + data->inflater.next_out = (Bytef *)dest; + data->inflater.avail_out = destlen; + data->inflater.total_out = 0; + zerr = inflateReset(&data->inflater); + if (zerr != Z_OK) + return CHDERR_DECOMPRESSION_ERROR; + + /* do it */ + zerr = inflate(&data->inflater, Z_FINISH); + (void)zerr; + if (data->inflater.total_out != destlen) + return CHDERR_DECOMPRESSION_ERROR; + + return CHDERR_NONE; +} + +/*------------------------------------------------- + zlib_fast_alloc - fast malloc for ZLIB, which + allocates and frees memory frequently +-------------------------------------------------*/ + +voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size) +{ + zlib_allocator *alloc = (zlib_allocator *)opaque; + UINT32 *ptr; + int i; + + /* compute the size, rounding to the nearest 1k */ + size = (size * items + 0x3ff) & ~0x3ff; + + /* reuse a hunk if we can */ + for (i = 0; i < MAX_ZLIB_ALLOCS; i++) + { + ptr = alloc->allocptr[i]; + if (ptr && size == *ptr) + { + /* set the low bit of the size so we don't match next time */ + *ptr |= 1; + return ptr + 1; + } + } + + /* alloc a new one */ + ptr = (UINT32 *)malloc(size + sizeof(UINT32)); + if (!ptr) + return NULL; + + /* put it into the list */ + for (i = 0; i < MAX_ZLIB_ALLOCS; i++) + if (!alloc->allocptr[i]) + { + alloc->allocptr[i] = ptr; + break; + } + + /* set the low bit of the size so we don't match next time */ + *ptr = size | 1; + return ptr + 1; +} + +/*------------------------------------------------- + zlib_fast_free - fast free for ZLIB, which + allocates and frees memory frequently +-------------------------------------------------*/ + +void zlib_fast_free(voidpf opaque, voidpf address) +{ + zlib_allocator *alloc = (zlib_allocator *)opaque; + UINT32 *ptr = (UINT32 *)address - 1; + int i; + + /* find the hunk */ + for (i = 0; i < MAX_ZLIB_ALLOCS; i++) + if (ptr == alloc->allocptr[i]) + { + /* clear the low bit of the size to allow matches */ + *ptr &= ~1; + return; + } +} diff --git a/libretro-common/formats/png/rpng.c b/libretro-common/formats/png/rpng.c index b4b9c6c675..e28272124c 100644 --- a/libretro-common/formats/png/rpng.c +++ b/libretro-common/formats/png/rpng.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rpng.c). diff --git a/libretro-common/formats/png/rpng_encode.c b/libretro-common/formats/png/rpng_encode.c index 92e25e16f4..3500c3aaf4 100644 --- a/libretro-common/formats/png/rpng_encode.c +++ b/libretro-common/formats/png/rpng_encode.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rpng_encode.c). diff --git a/libretro-common/formats/png/rpng_internal.h b/libretro-common/formats/png/rpng_internal.h index 440bd3d587..62dcfbc9e0 100644 --- a/libretro-common/formats/png/rpng_internal.h +++ b/libretro-common/formats/png/rpng_internal.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rpng_internal.h). diff --git a/libretro-common/formats/tga/rtga.c b/libretro-common/formats/tga/rtga.c index 7e4e62e306..c96e7ba8f4 100644 --- a/libretro-common/formats/tga/rtga.c +++ b/libretro-common/formats/tga/rtga.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rtga.c). diff --git a/libretro-common/formats/wav/rwav.c b/libretro-common/formats/wav/rwav.c index 7e43ade3ea..e012005ae8 100644 --- a/libretro-common/formats/wav/rwav.c +++ b/libretro-common/formats/wav/rwav.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rwav.c). diff --git a/libretro-common/formats/xml/rxml.c b/libretro-common/formats/xml/rxml.c index b7129653c4..e2a02a77c5 100644 --- a/libretro-common/formats/xml/rxml.c +++ b/libretro-common/formats/xml/rxml.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rxml.c). diff --git a/libretro-common/formats/xml/test/rxml_test.c b/libretro-common/formats/xml/test/rxml_test.c index e966b1d60e..36e794eefc 100644 --- a/libretro-common/formats/xml/test/rxml_test.c +++ b/libretro-common/formats/xml/test/rxml_test.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rxml_test.c). diff --git a/libretro-common/gfx/gl_capabilities.c b/libretro-common/gfx/gl_capabilities.c index d9c8d147b2..d7ec069e4b 100644 --- a/libretro-common/gfx/gl_capabilities.c +++ b/libretro-common/gfx/gl_capabilities.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (gl_capabilities.c). diff --git a/libretro-common/gfx/scaler/pixconv.c b/libretro-common/gfx/scaler/pixconv.c index 604479e404..64f5d89d0d 100644 --- a/libretro-common/gfx/scaler/pixconv.c +++ b/libretro-common/gfx/scaler/pixconv.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (pixconv.c). diff --git a/libretro-common/gfx/scaler/scaler.c b/libretro-common/gfx/scaler/scaler.c index 24b2d0c919..803fecb1aa 100644 --- a/libretro-common/gfx/scaler/scaler.c +++ b/libretro-common/gfx/scaler/scaler.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (scaler.c). diff --git a/libretro-common/gfx/scaler/scaler_filter.c b/libretro-common/gfx/scaler/scaler_filter.c index 6134e99f71..498f80d8f3 100644 --- a/libretro-common/gfx/scaler/scaler_filter.c +++ b/libretro-common/gfx/scaler/scaler_filter.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (scaler_filter.c). diff --git a/libretro-common/gfx/scaler/scaler_int.c b/libretro-common/gfx/scaler/scaler_int.c index 42c8ab58bf..9aa583cef8 100644 --- a/libretro-common/gfx/scaler/scaler_int.c +++ b/libretro-common/gfx/scaler/scaler_int.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (scaler_int.c). diff --git a/libretro-common/glsm/glsm.c b/libretro-common/glsm/glsm.c index ab8c5624e6..85a7ced78a 100644 --- a/libretro-common/glsm/glsm.c +++ b/libretro-common/glsm/glsm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsm). @@ -2207,7 +2207,7 @@ static bool glsm_state_ctx_init(void *data) #ifdef CORE hw_render.context_type = RETRO_HW_CONTEXT_OPENGL_CORE; hw_render.version_major = 3; - hw_render.version_minor = 1; + hw_render.version_minor = 3; #else hw_render.context_type = RETRO_HW_CONTEXT_OPENGL; #endif diff --git a/libretro-common/glsym/glsym_gl.c b/libretro-common/glsym/glsym_gl.c index 5aa92fdca2..d89992c919 100644 --- a/libretro-common/glsym/glsym_gl.c +++ b/libretro-common/glsym/glsym_gl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). diff --git a/libretro-common/glsym/rglgen.c b/libretro-common/glsym/rglgen.c index 0ea1fdc99c..6306eaef47 100644 --- a/libretro-common/glsym/rglgen.c +++ b/libretro-common/glsym/rglgen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). diff --git a/libretro-common/hash/rhash.c b/libretro-common/hash/rhash.c index 616e85990c..b123d4d09b 100644 --- a/libretro-common/hash/rhash.c +++ b/libretro-common/hash/rhash.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rhash.c). diff --git a/libretro-common/include/audio/audio_mix.h b/libretro-common/include/audio/audio_mix.h index 3b59dff689..937c4b28e8 100644 --- a/libretro-common/include/audio/audio_mix.h +++ b/libretro-common/include/audio/audio_mix.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (audio_mix.h). diff --git a/libretro-common/include/audio/audio_mixer.h b/libretro-common/include/audio/audio_mixer.h index 3df9c64931..bb8d35d0c7 100644 --- a/libretro-common/include/audio/audio_mixer.h +++ b/libretro-common/include/audio/audio_mixer.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (audio_mixer.h). @@ -41,7 +41,9 @@ enum audio_mixer_type AUDIO_MIXER_TYPE_NONE = 0, AUDIO_MIXER_TYPE_WAV, AUDIO_MIXER_TYPE_OGG, - AUDIO_MIXER_TYPE_MOD + AUDIO_MIXER_TYPE_MOD, + AUDIO_MIXER_TYPE_FLAC, + AUDIO_MIXER_TYPE_MP3 }; typedef struct audio_mixer_sound audio_mixer_sound_t; @@ -61,6 +63,8 @@ void audio_mixer_done(void); audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size); audio_mixer_sound_t* audio_mixer_load_ogg(void *buffer, int32_t size); audio_mixer_sound_t* audio_mixer_load_mod(void *buffer, int32_t size); +audio_mixer_sound_t* audio_mixer_load_flac(void *buffer, int32_t size); +audio_mixer_sound_t* audio_mixer_load_mp3(void *buffer, int32_t size); void audio_mixer_destroy(audio_mixer_sound_t* sound); @@ -69,6 +73,10 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, void audio_mixer_stop(audio_mixer_voice_t* voice); +float audio_mixer_voice_get_volume(audio_mixer_voice_t *voice); + +void audio_mixer_voice_set_volume(audio_mixer_voice_t *voice, float val); + void audio_mixer_mix(float* buffer, size_t num_frames, float volume_override, bool override); RETRO_END_DECLS diff --git a/libretro-common/include/audio/audio_resampler.h b/libretro-common/include/audio/audio_resampler.h index d950586aea..46eb426a20 100644 --- a/libretro-common/include/audio/audio_resampler.h +++ b/libretro-common/include/audio/audio_resampler.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (audio_resampler.h). diff --git a/libretro-common/include/audio/conversion/float_to_s16.h b/libretro-common/include/audio/conversion/float_to_s16.h index 30903cfd4c..2ddf65e75d 100644 --- a/libretro-common/include/audio/conversion/float_to_s16.h +++ b/libretro-common/include/audio/conversion/float_to_s16.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (float_to_s16.h). diff --git a/libretro-common/include/audio/conversion/s16_to_float.h b/libretro-common/include/audio/conversion/s16_to_float.h index ebe43ac4f4..4f705b8b80 100644 --- a/libretro-common/include/audio/conversion/s16_to_float.h +++ b/libretro-common/include/audio/conversion/s16_to_float.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (s16_to_float.h). diff --git a/libretro-common/include/audio/dsp_filter.h b/libretro-common/include/audio/dsp_filter.h index 2055235f6f..82af77135c 100644 --- a/libretro-common/include/audio/dsp_filter.h +++ b/libretro-common/include/audio/dsp_filter.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (dsp_filter.h). diff --git a/libretro-common/include/boolean.h b/libretro-common/include/boolean.h index 8a5482cde5..f06ac5a742 100644 --- a/libretro-common/include/boolean.h +++ b/libretro-common/include/boolean.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (boolean.h). diff --git a/libretro-common/include/clamping.h b/libretro-common/include/clamping.h index 7919332b95..ec29bf9a38 100644 --- a/libretro-common/include/clamping.h +++ b/libretro-common/include/clamping.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (clamping.h). diff --git a/libretro-common/include/compat/apple_compat.h b/libretro-common/include/compat/apple_compat.h index f656546302..819b39ecf6 100644 --- a/libretro-common/include/compat/apple_compat.h +++ b/libretro-common/include/compat/apple_compat.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (apple_compat.h). diff --git a/libretro-common/include/compat/fnmatch.h b/libretro-common/include/compat/fnmatch.h index 3f3c0254bc..cede1ca6c7 100644 --- a/libretro-common/include/compat/fnmatch.h +++ b/libretro-common/include/compat/fnmatch.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (fnmatch.h). diff --git a/libretro-common/include/compat/fopen_utf8.h b/libretro-common/include/compat/fopen_utf8.h index 1fe6a8aab6..f59822a5ca 100644 --- a/libretro-common/include/compat/fopen_utf8.h +++ b/libretro-common/include/compat/fopen_utf8.h @@ -1,8 +1,30 @@ -#ifndef __FOPEN_UTF8_H -#define __FOPEN_UTF8_H +/* Copyright (C) 2010-2018 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (fopen_utf8.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __LIBRETRO_SDK_COMPAT_FOPEN_UTF8_H +#define __LIBRETRO_SDK_COMPAT_FOPEN_UTF8_H #ifdef _WIN32 -/* defined to error rather than fopen_utf8, to make it clear to everyone reading the code that not worrying about utf16 is fine */ +/* Defined to error rather than fopen_utf8, to make it clear to everyone reading the code that not worrying about utf16 is fine */ /* TODO: enable */ /* #define fopen (use fopen_utf8 instead) */ void *fopen_utf8(const char * filename, const char * mode); diff --git a/libretro-common/include/compat/getopt.h b/libretro-common/include/compat/getopt.h index f685681559..74287b64f5 100644 --- a/libretro-common/include/compat/getopt.h +++ b/libretro-common/include/compat/getopt.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (getopt.h). diff --git a/libretro-common/include/compat/intrinsics.h b/libretro-common/include/compat/intrinsics.h index 5d6e8a5b60..3fc7d92918 100644 --- a/libretro-common/include/compat/intrinsics.h +++ b/libretro-common/include/compat/intrinsics.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (intrinsics.h). diff --git a/libretro-common/include/compat/msvc.h b/libretro-common/include/compat/msvc.h index fea4b53660..822c97339a 100644 --- a/libretro-common/include/compat/msvc.h +++ b/libretro-common/include/compat/msvc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (msvc.h). diff --git a/libretro-common/include/compat/posix_string.h b/libretro-common/include/compat/posix_string.h index 380e1a121f..9f56322ab9 100644 --- a/libretro-common/include/compat/posix_string.h +++ b/libretro-common/include/compat/posix_string.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (posix_string.h). diff --git a/libretro-common/include/compat/strcasestr.h b/libretro-common/include/compat/strcasestr.h index 376f1003fd..f849593b0f 100644 --- a/libretro-common/include/compat/strcasestr.h +++ b/libretro-common/include/compat/strcasestr.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (strcasestr.h). diff --git a/libretro-common/include/compat/strl.h b/libretro-common/include/compat/strl.h index 853aceffcc..290498d9a6 100644 --- a/libretro-common/include/compat/strl.h +++ b/libretro-common/include/compat/strl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (strl.h). diff --git a/libretro-common/include/dynamic/dylib.h b/libretro-common/include/dynamic/dylib.h index b8ee171cf3..f6951273bd 100644 --- a/libretro-common/include/dynamic/dylib.h +++ b/libretro-common/include/dynamic/dylib.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (dylib.h). diff --git a/libretro-common/include/encodings/crc32.h b/libretro-common/include/encodings/crc32.h index 0c9947629d..76fbb5475e 100644 --- a/libretro-common/include/encodings/crc32.h +++ b/libretro-common/include/encodings/crc32.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (crc32.h). diff --git a/libretro-common/include/encodings/utf.h b/libretro-common/include/encodings/utf.h index bad9458966..b513f28a18 100644 --- a/libretro-common/include/encodings/utf.h +++ b/libretro-common/include/encodings/utf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (utf.h). diff --git a/libretro-common/include/encodings/win32.h b/libretro-common/include/encodings/win32.h index 7d8057e8b8..d4221bd9b7 100644 --- a/libretro-common/include/encodings/win32.h +++ b/libretro-common/include/encodings/win32.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2016 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (utf.h). diff --git a/libretro-common/include/fastcpy.h b/libretro-common/include/fastcpy.h index 13b94d97bd..9d40702bf3 100644 --- a/libretro-common/include/fastcpy.h +++ b/libretro-common/include/fastcpy.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (fastcpy.h). diff --git a/libretro-common/include/features/features_cpu.h b/libretro-common/include/features/features_cpu.h index fd8f5f62b6..0aa043dad0 100644 --- a/libretro-common/include/features/features_cpu.h +++ b/libretro-common/include/features/features_cpu.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (features_cpu.h). diff --git a/libretro-common/include/file/archive_file.h b/libretro-common/include/file/archive_file.h index b2b5971931..6cc7d4725b 100644 --- a/libretro-common/include/file/archive_file.h +++ b/libretro-common/include/file/archive_file.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (archive_file.h). @@ -187,7 +187,7 @@ bool file_archive_perform_mode(const char *name, const char *valid_exts, int file_archive_compressed_read( const char* path, void **buf, - const char* optional_filename, ssize_t *length); + const char* optional_filename, int64_t *length); const struct file_archive_file_backend* file_archive_get_zlib_file_backend(void); const struct file_archive_file_backend* file_archive_get_7z_file_backend(void); diff --git a/libretro-common/include/file/config_file.h b/libretro-common/include/file/config_file.h index 3c0d99987a..6b4dde77e7 100644 --- a/libretro-common/include/file/config_file.h +++ b/libretro-common/include/file/config_file.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (config_file.h). diff --git a/libretro-common/include/file/config_file_userdata.h b/libretro-common/include/file/config_file_userdata.h index 0c433ed361..ca6f691785 100644 --- a/libretro-common/include/file/config_file_userdata.h +++ b/libretro-common/include/file/config_file_userdata.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (config_file_userdata.h). diff --git a/libretro-common/include/file/file_path.h b/libretro-common/include/file/file_path.h index 4a29494d98..89321c8f80 100644 --- a/libretro-common/include/file/file_path.h +++ b/libretro-common/include/file/file_path.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (file_path.h). @@ -432,7 +432,7 @@ void path_basedir_wrapper(char *path); #endif /** - * path_default_slash: + * path_default_slash and path_default_slash_c: * * Gets the default slash separator. * @@ -440,8 +440,10 @@ void path_basedir_wrapper(char *path); */ #ifdef _WIN32 #define path_default_slash() "\\" +#define path_default_slash_c() '\\' #else #define path_default_slash() "/" +#define path_default_slash_c() '/' #endif /** diff --git a/libretro-common/include/file/nbio.h b/libretro-common/include/file/nbio.h index 554bd1103d..4b5e5a41bc 100644 --- a/libretro-common/include/file/nbio.h +++ b/libretro-common/include/file/nbio.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (nbio.h). diff --git a/libretro-common/include/filters.h b/libretro-common/include/filters.h index 53743bba7f..69048efd90 100644 --- a/libretro-common/include/filters.h +++ b/libretro-common/include/filters.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (filters.h). diff --git a/libretro-common/include/formats/image.h b/libretro-common/include/formats/image.h index bba886642d..20a3c8058a 100644 --- a/libretro-common/include/formats/image.h +++ b/libretro-common/include/formats/image.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (image.h). diff --git a/libretro-common/include/formats/jsonsax.h b/libretro-common/include/formats/jsonsax.h index d8b18e6b8d..c98331fb39 100644 --- a/libretro-common/include/formats/jsonsax.h +++ b/libretro-common/include/formats/jsonsax.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (jsonsax.h). diff --git a/libretro-common/include/formats/rbmp.h b/libretro-common/include/formats/rbmp.h index 622d8c94d7..9b3a908733 100644 --- a/libretro-common/include/formats/rbmp.h +++ b/libretro-common/include/formats/rbmp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rbmp.h). diff --git a/libretro-common/include/formats/rjpeg.h b/libretro-common/include/formats/rjpeg.h index a999516df0..ed4ee3eea1 100644 --- a/libretro-common/include/formats/rjpeg.h +++ b/libretro-common/include/formats/rjpeg.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rjpeg.h). diff --git a/libretro-common/include/formats/rpng.h b/libretro-common/include/formats/rpng.h index b16a8307fa..aeae7af49a 100644 --- a/libretro-common/include/formats/rpng.h +++ b/libretro-common/include/formats/rpng.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rpng.h). diff --git a/libretro-common/include/formats/rtga.h b/libretro-common/include/formats/rtga.h index a66f4a0ab6..1b9409c365 100644 --- a/libretro-common/include/formats/rtga.h +++ b/libretro-common/include/formats/rtga.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rtga.h). diff --git a/libretro-common/include/formats/rwav.h b/libretro-common/include/formats/rwav.h index 3f4ed170e3..198d24b5b5 100644 --- a/libretro-common/include/formats/rwav.h +++ b/libretro-common/include/formats/rwav.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rwav.h). diff --git a/libretro-common/include/formats/rxml.h b/libretro-common/include/formats/rxml.h index 13bcebac1f..78d01a2972 100644 --- a/libretro-common/include/formats/rxml.h +++ b/libretro-common/include/formats/rxml.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rxml.h). diff --git a/libretro-common/include/gfx/gl_capabilities.h b/libretro-common/include/gfx/gl_capabilities.h index 4e7c97a0a7..c71352efaa 100644 --- a/libretro-common/include/gfx/gl_capabilities.h +++ b/libretro-common/include/gfx/gl_capabilities.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (gl_capabilities.h). diff --git a/libretro-common/include/gfx/math/matrix_3x3.h b/libretro-common/include/gfx/math/matrix_3x3.h index 9bdd886945..791f1dae06 100644 --- a/libretro-common/include/gfx/math/matrix_3x3.h +++ b/libretro-common/include/gfx/math/matrix_3x3.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (matrix_3x3.h). diff --git a/libretro-common/include/gfx/math/matrix_4x4.h b/libretro-common/include/gfx/math/matrix_4x4.h index de5244ef26..dacb37c31c 100644 --- a/libretro-common/include/gfx/math/matrix_4x4.h +++ b/libretro-common/include/gfx/math/matrix_4x4.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (matrix_4x4.h). diff --git a/libretro-common/include/gfx/math/vector_2.h b/libretro-common/include/gfx/math/vector_2.h index 1265c6de45..a38153ea2c 100644 --- a/libretro-common/include/gfx/math/vector_2.h +++ b/libretro-common/include/gfx/math/vector_2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (vector_2.h). diff --git a/libretro-common/include/gfx/math/vector_3.h b/libretro-common/include/gfx/math/vector_3.h index 67256172f0..40c9f7f49c 100644 --- a/libretro-common/include/gfx/math/vector_3.h +++ b/libretro-common/include/gfx/math/vector_3.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (vector_3.h). diff --git a/libretro-common/include/gfx/math/vector_4.h b/libretro-common/include/gfx/math/vector_4.h index 3b9510c511..e985649206 100644 --- a/libretro-common/include/gfx/math/vector_4.h +++ b/libretro-common/include/gfx/math/vector_4.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (vector_4.h). diff --git a/libretro-common/include/gfx/scaler/filter.h b/libretro-common/include/gfx/scaler/filter.h index ba5ae93907..27f677a6c3 100644 --- a/libretro-common/include/gfx/scaler/filter.h +++ b/libretro-common/include/gfx/scaler/filter.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (filter.h). diff --git a/libretro-common/include/gfx/scaler/pixconv.h b/libretro-common/include/gfx/scaler/pixconv.h index 6dfab47a9a..100864de68 100644 --- a/libretro-common/include/gfx/scaler/pixconv.h +++ b/libretro-common/include/gfx/scaler/pixconv.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (pixconv.h). diff --git a/libretro-common/include/gfx/scaler/scaler.h b/libretro-common/include/gfx/scaler/scaler.h index 8d97515616..97854d45b3 100644 --- a/libretro-common/include/gfx/scaler/scaler.h +++ b/libretro-common/include/gfx/scaler/scaler.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (scaler.h). diff --git a/libretro-common/include/gfx/scaler/scaler_int.h b/libretro-common/include/gfx/scaler/scaler_int.h index 87ef68eda2..2cb203a3ba 100644 --- a/libretro-common/include/gfx/scaler/scaler_int.h +++ b/libretro-common/include/gfx/scaler/scaler_int.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (scaler_int.h). diff --git a/libretro-common/include/gfx/video_frame.h b/libretro-common/include/gfx/video_frame.h index e5c0540d9c..c00dc81d57 100644 --- a/libretro-common/include/gfx/video_frame.h +++ b/libretro-common/include/gfx/video_frame.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (video_frame.h). diff --git a/libretro-common/include/glsm/glsm.h b/libretro-common/include/glsm/glsm.h index 8e30acdc04..d422267d11 100644 --- a/libretro-common/include/glsm/glsm.h +++ b/libretro-common/include/glsm/glsm.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsm.h). diff --git a/libretro-common/include/glsm/glsmsym.h b/libretro-common/include/glsm/glsmsym.h index 215f3ecb51..3611441919 100644 --- a/libretro-common/include/glsm/glsmsym.h +++ b/libretro-common/include/glsm/glsmsym.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsmsym.h). diff --git a/libretro-common/include/glsym/glsym.h b/libretro-common/include/glsym/glsym.h index c1c13e2a56..24f4584bb6 100644 --- a/libretro-common/include/glsym/glsym.h +++ b/libretro-common/include/glsym/glsym.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). diff --git a/libretro-common/include/glsym/glsym_gl.h b/libretro-common/include/glsym/glsym_gl.h index 9720c2e1cf..1934287f2a 100644 --- a/libretro-common/include/glsym/glsym_gl.h +++ b/libretro-common/include/glsym/glsym_gl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). diff --git a/libretro-common/include/glsym/rglgen.h b/libretro-common/include/glsym/rglgen.h index 54dcb62a84..b8a1a0c877 100644 --- a/libretro-common/include/glsym/rglgen.h +++ b/libretro-common/include/glsym/rglgen.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). diff --git a/libretro-common/include/glsym/rglgen_headers.h b/libretro-common/include/glsym/rglgen_headers.h index 06d8530b27..766efb6361 100644 --- a/libretro-common/include/glsym/rglgen_headers.h +++ b/libretro-common/include/glsym/rglgen_headers.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro SDK code part (glsym). diff --git a/libretro-common/include/libchdr/chd.h b/libretro-common/include/libchdr/chd.h index 1a33e0cc32..9b4df95349 100644 --- a/libretro-common/include/libchdr/chd.h +++ b/libretro-common/include/libchdr/chd.h @@ -47,6 +47,7 @@ extern "C" { #endif #include "coretypes.h" +#include /*************************************************************************** @@ -347,15 +348,18 @@ struct _chd_verify_result /* chd_error chd_create_file(core_file *file, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 compression, chd_file *parent); */ /* open an existing CHD file */ -chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **chd); +chd_error chd_open_file(RFILE *file, int mode, chd_file *parent, chd_file **chd); + chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd); +/* precache underlying file */ +chd_error chd_precache(chd_file *chd); /* close a CHD file */ void chd_close(chd_file *chd); /* return the associated core_file */ -core_file *chd_core_file(chd_file *chd); +RFILE *chd_core_file(chd_file *chd); /* return an error string for the given CHD error */ const char *chd_error_string(chd_error err); @@ -393,6 +397,8 @@ chd_error chd_codec_config(chd_file *chd, int param, void *config); /* return a string description of a codec */ const char *chd_get_codec_name(UINT32 codec); +extern const uint8_t s_cd_sync_header[12]; + #ifdef __cplusplus } #endif diff --git a/libretro-common/include/libchdr/coretypes.h b/libretro-common/include/libchdr/coretypes.h index 5a769f6a86..2a68a8a4c3 100644 --- a/libretro-common/include/libchdr/coretypes.h +++ b/libretro-common/include/libchdr/coretypes.h @@ -3,8 +3,7 @@ #include #include - -#define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0])) +#include typedef uint64_t UINT64; #ifndef OSD_CPU_H @@ -20,11 +19,4 @@ typedef int16_t INT16; typedef int8_t INT8; #endif -#define core_file FILE -#define core_fopen(file) fopen(file, "rb") -#define core_fseek fseek -#define core_fread(fc, buff, len) fread(buff, 1, len, fc) -#define core_fclose fclose -#define core_ftell ftell - #endif diff --git a/libretro-common/include/libchdr/flac.h b/libretro-common/include/libchdr/flac.h index a9f84962af..2ce112d27a 100644 --- a/libretro-common/include/libchdr/flac.h +++ b/libretro-common/include/libchdr/flac.h @@ -14,6 +14,7 @@ #define __FLAC_H__ #include +#include "libchdr_zlib.h" #include "FLAC/ordinals.h" #include "FLAC/stream_decoder.h" @@ -49,4 +50,21 @@ int flac_decoder_reset(flac_decoder* decoder, uint32_t sample_rate, uint8_t nu int flac_decoder_decode_interleaved(flac_decoder* decoder, int16_t *samples, uint32_t num_samples, int swap_endian); uint32_t flac_decoder_finish(flac_decoder* decoder); +/* codec-private data for the CDFL codec */ +typedef struct _cdfl_codec_data cdfl_codec_data; +struct _cdfl_codec_data { + /* internal state */ + int swap_endian; + flac_decoder decoder; +#ifdef WANT_SUBCODE + zlib_codec_data subcode_decompressor; +#endif + uint8_t* buffer; +}; + +/* cdfl compression codec */ +chd_error cdfl_codec_init(void* codec, uint32_t hunkbytes); +void cdfl_codec_free(void* codec); +chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); + #endif /* __FLAC_H__ */ diff --git a/libretro-common/include/libchdr/libchdr_zlib.h b/libretro-common/include/libchdr/libchdr_zlib.h new file mode 100644 index 0000000000..4f3f141050 --- /dev/null +++ b/libretro-common/include/libchdr/libchdr_zlib.h @@ -0,0 +1,69 @@ +/* license:BSD-3-Clause + * copyright-holders:Aaron Giles + *************************************************************************** + + libchr_zlib.h + + Zlib compression wrappers + +***************************************************************************/ + +#pragma once + +#ifndef __LIBCHDR_ZLIB_H__ +#define __LIBCHDR_ZLIB_H__ + +#include + +#include +#include "coretypes.h" +#include "chd.h" + +#define MAX_ZLIB_ALLOCS 64 + +/* codec-private data for the ZLIB codec */ + +typedef struct _zlib_allocator zlib_allocator; +struct _zlib_allocator +{ + UINT32 * allocptr[MAX_ZLIB_ALLOCS]; +}; + +typedef struct _zlib_codec_data zlib_codec_data; +struct _zlib_codec_data +{ + z_stream inflater; + zlib_allocator allocator; +}; + + +/* codec-private data for the CDZL codec */ +typedef struct _cdzl_codec_data cdzl_codec_data; +struct _cdzl_codec_data { + /* internal state */ + zlib_codec_data base_decompressor; +#ifdef WANT_SUBCODE + zlib_codec_data subcode_decompressor; +#endif + uint8_t* buffer; +}; + +/* zlib compression codec */ +chd_error zlib_codec_init(void *codec, uint32_t hunkbytes); + +void zlib_codec_free(void *codec); + +chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); + +voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size); + +void zlib_fast_free(voidpf opaque, voidpf address); + +/* cdzl compression codec */ +chd_error cdzl_codec_init(void* codec, uint32_t hunkbytes); + +void cdzl_codec_free(void* codec); + +chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); + +#endif /* __LIBCHDR_ZLIB_H__ */ diff --git a/libretro-common/include/libchdr/lzma.h b/libretro-common/include/libchdr/lzma.h new file mode 100644 index 0000000000..e3cccbc196 --- /dev/null +++ b/libretro-common/include/libchdr/lzma.h @@ -0,0 +1,72 @@ +/* license:BSD-3-Clause + * copyright-holders:Aaron Giles + *************************************************************************** + + lzma.h + + LZMA compression wrappers + +***************************************************************************/ + +#pragma once + +#ifndef __LIBCHDR_LZMA_H__ +#define __LIBCHDR_LZMA_H__ + +#include + +#include +#include + +#include + +/* codec-private data for the LZMA codec */ +#define MAX_LZMA_ALLOCS 64 + +typedef struct _lzma_allocator lzma_allocator; +struct _lzma_allocator +{ + void *(*Alloc)(void *p, size_t size); + void (*Free)(void *p, void *address); /* address can be 0 */ + void (*FreeSz)(void *p, void *address, size_t size); /* address can be 0 */ + uint32_t* allocptr[MAX_LZMA_ALLOCS]; +}; + +typedef struct _lzma_codec_data lzma_codec_data; +struct _lzma_codec_data +{ + CLzmaDec decoder; + lzma_allocator allocator; +}; + +/* codec-private data for the CDLZ codec */ +typedef struct _cdlz_codec_data cdlz_codec_data; +struct _cdlz_codec_data { + /* internal state */ + lzma_codec_data base_decompressor; +#ifdef WANT_SUBCODE + zlib_codec_data subcode_decompressor; +#endif + uint8_t* buffer; +}; + +chd_error lzma_codec_init(void* codec, uint32_t hunkbytes); + +void lzma_codec_free(void* codec); + +/*------------------------------------------------- + * decompress - decompress data using the LZMA + * codec + *------------------------------------------------- + */ + +chd_error lzma_codec_decompress(void* codec, const uint8_t *src, + uint32_t complen, uint8_t *dest, uint32_t destlen); + +chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes); + +void cdlz_codec_free(void* codec); + +chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); + +#endif /* __LIBCHDR_LZMA_H__ */ diff --git a/libretro-common/include/libco.h b/libretro-common/include/libco.h index 1599cb2ca0..851b29cc43 100644 --- a/libretro-common/include/libco.h +++ b/libretro-common/include/libco.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (libco.h). diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index bfe832c202..654c799828 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro API header (libretro.h). @@ -599,9 +599,12 @@ enum retro_mod * GET_VARIABLE. * This allows the frontend to present these variables to * a user dynamically. - * This should be called as early as possible (ideally in - * retro_set_environment). - * + * This should be called the first time as early as + * possible (ideally in retro_set_environment). + * Afterward it may be called again for the core to communicate + * updated options to the frontend, but the number of core + * options must not change from the number in the initial call. + * * 'data' points to an array of retro_variable structs * terminated by a { NULL, NULL } element. * retro_variable::key should be namespaced to not collide @@ -1119,12 +1122,44 @@ struct retro_led_interface #define RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE (47 | RETRO_ENVIRONMENT_EXPERIMENTAL) /* int * -- - * Queries the frontend if audio and video are enabled or not. - * If not enabled, the frontend will discard the audio or video, - * so the core may decide to skip producing audio or video. - * Bit 0 (value 1) is set if Video is enabled, - * Bit 1 (value 2) is set if Audio is enabled. - * Other bits are reserved for future use. + * Tells the core if the frontend wants audio or video. + * If disabled, the frontend will discard the audio or video, + * so the core may decide to skip generating a frame or generating audio. + * This is mainly used for increasing performance. + * Bit 0 (value 1): Enable Video + * Bit 1 (value 2): Enable Audio + * Bit 2 (value 4): Use Fast Savestates. + * Bit 3 (value 8): Hard Disable Audio + * Other bits are reserved for future use and will default to zero. + * If video is disabled: + * * The frontend wants the core to not generate any video, + * including presenting frames via hardware acceleration. + * * The frontend's video frame callback will do nothing. + * * After running the frame, the video output of the next frame should be + * no different than if video was enabled, and saving and loading state + * should have no issues. + * If audio is disabled: + * * The frontend wants the core to not generate any audio. + * * The frontend's audio callbacks will do nothing. + * * After running the frame, the audio output of the next frame should be + * no different than if audio was enabled, and saving and loading state + * should have no issues. + * Fast Savestates: + * * Guaranteed to be created by the same binary that will load them. + * * Will not be written to or read from the disk. + * * Suggest that the core assumes loading state will succeed. + * * Suggest that the core updates its memory buffers in-place if possible. + * * Suggest that the core skips clearing memory. + * * Suggest that the core skips resetting the system. + * * Suggest that the core may skip validation steps. + * Hard Disable Audio: + * * Used for a secondary core when running ahead. + * * Indicates that the frontend will never need audio from the core. + * * Suggests that the core may stop synthesizing audio, but this should not + * compromise emulation accuracy. + * * Audio output for the next frame does not matter, and the frontend will + * never need an accurate audio state in the future. + * * State will never be saved when using Hard Disable Audio. */ #define RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE (41 | RETRO_ENVIRONMENT_EXPERIMENTAL) diff --git a/libretro-common/include/libretro_d3d.h b/libretro-common/include/libretro_d3d.h index 2ed71aa7c0..d95931b3e9 100644 --- a/libretro-common/include/libretro_d3d.h +++ b/libretro-common/include/libretro_d3d.h @@ -1,7 +1,7 @@ -/* Copyright (C) 2010-2016 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------------- - * The following license statement only applies to this libretro API header (libretro_vulkan.h) + * The following license statement only applies to this libretro API header (libretro_d3d.h) * --------------------------------------------------------------------------------------------- * * Permission is hereby granted, free of charge, diff --git a/libretro-common/include/libretro_dspfilter.h b/libretro-common/include/libretro_dspfilter.h index 4de515d01b..36bfd88d5f 100644 --- a/libretro-common/include/libretro_dspfilter.h +++ b/libretro-common/include/libretro_dspfilter.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro API header (libretro_dspfilter.h). diff --git a/libretro-common/include/libretro_vulkan.h b/libretro-common/include/libretro_vulkan.h index e1005a163b..5ae7187b7d 100644 --- a/libretro-common/include/libretro_vulkan.h +++ b/libretro-common/include/libretro_vulkan.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------------- * The following license statement only applies to this libretro API header (libretro_vulkan.h) diff --git a/libretro-common/include/lists/dir_list.h b/libretro-common/include/lists/dir_list.h index 3b4a9c573d..4babb02d39 100644 --- a/libretro-common/include/lists/dir_list.h +++ b/libretro-common/include/lists/dir_list.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (dir_list.h). diff --git a/libretro-common/include/lists/file_list.h b/libretro-common/include/lists/file_list.h index f6715a3572..208bf15a59 100644 --- a/libretro-common/include/lists/file_list.h +++ b/libretro-common/include/lists/file_list.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (file_list.h). diff --git a/libretro-common/include/lists/string_list.h b/libretro-common/include/lists/string_list.h index c15cd0eca7..513876e6d1 100644 --- a/libretro-common/include/lists/string_list.h +++ b/libretro-common/include/lists/string_list.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (string_list.h). diff --git a/libretro-common/include/math/complex.h b/libretro-common/include/math/complex.h index d7695c2d22..abfbfa60f5 100644 --- a/libretro-common/include/math/complex.h +++ b/libretro-common/include/math/complex.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (complex.h). diff --git a/libretro-common/include/math/float_minmax.h b/libretro-common/include/math/float_minmax.h index d917ef8ef6..2164dde0f7 100644 --- a/libretro-common/include/math/float_minmax.h +++ b/libretro-common/include/math/float_minmax.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (float_minmax.h). diff --git a/libretro-common/include/math/fxp.h b/libretro-common/include/math/fxp.h index 56b036cd72..46f58bae91 100644 --- a/libretro-common/include/math/fxp.h +++ b/libretro-common/include/math/fxp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (fxp.h). diff --git a/libretro-common/include/memalign.h b/libretro-common/include/memalign.h index ca809f80c3..2c07a7c053 100644 --- a/libretro-common/include/memalign.h +++ b/libretro-common/include/memalign.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (memalign.h). diff --git a/libretro-common/include/memmap.h b/libretro-common/include/memmap.h index 8d939c4351..2bedd5c926 100644 --- a/libretro-common/include/memmap.h +++ b/libretro-common/include/memmap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (memmap.h). diff --git a/libretro-common/include/net/net_compat.h b/libretro-common/include/net/net_compat.h index 7a182af2af..789f944e71 100644 --- a/libretro-common/include/net/net_compat.h +++ b/libretro-common/include/net/net_compat.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_compat.h). diff --git a/libretro-common/include/net/net_http.h b/libretro-common/include/net/net_http.h index 8a9f2c5e0b..f98462764d 100644 --- a/libretro-common/include/net/net_http.h +++ b/libretro-common/include/net/net_http.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_http.h). diff --git a/libretro-common/include/net/net_http_parse.h b/libretro-common/include/net/net_http_parse.h index 4fc4845cd0..6e957d3975 100644 --- a/libretro-common/include/net/net_http_parse.h +++ b/libretro-common/include/net/net_http_parse.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_http.h). diff --git a/libretro-common/include/net/net_ifinfo.h b/libretro-common/include/net/net_ifinfo.h index 9949da2f05..b1d2535500 100644 --- a/libretro-common/include/net/net_ifinfo.h +++ b/libretro-common/include/net/net_ifinfo.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_ifinfo.h). diff --git a/libretro-common/include/net/net_natt.h b/libretro-common/include/net/net_natt.h index 9c8b3d7d7d..66c3ff355a 100644 --- a/libretro-common/include/net/net_natt.h +++ b/libretro-common/include/net/net_natt.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_natt.h). @@ -30,7 +30,8 @@ RETRO_BEGIN_DECLS -struct natt_status { +struct natt_status +{ /** nfds for select when checking for input */ int nfds; diff --git a/libretro-common/include/net/net_socket.h b/libretro-common/include/net/net_socket.h index 5d6dd8784e..098854e658 100644 --- a/libretro-common/include/net/net_socket.h +++ b/libretro-common/include/net/net_socket.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_socket.h). diff --git a/libretro-common/include/net/net_socket_ssl.h b/libretro-common/include/net/net_socket_ssl.h index c9ca75dad0..2691a2d12d 100644 --- a/libretro-common/include/net/net_socket_ssl.h +++ b/libretro-common/include/net/net_socket_ssl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_socket.h). diff --git a/libretro-common/include/queues/fifo_queue.h b/libretro-common/include/queues/fifo_queue.h index f1a3cae13c..b9c22e7ece 100644 --- a/libretro-common/include/queues/fifo_queue.h +++ b/libretro-common/include/queues/fifo_queue.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (fifo_queue.h). diff --git a/libretro-common/include/queues/message_queue.h b/libretro-common/include/queues/message_queue.h index 2339e93578..760ba279d8 100644 --- a/libretro-common/include/queues/message_queue.h +++ b/libretro-common/include/queues/message_queue.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (message_queue.h). diff --git a/libretro-common/include/queues/task_queue.h b/libretro-common/include/queues/task_queue.h index 8e25cc43ac..40c35ddfdb 100644 --- a/libretro-common/include/queues/task_queue.h +++ b/libretro-common/include/queues/task_queue.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (task_queue.h). diff --git a/libretro-common/include/retro_assert.h b/libretro-common/include/retro_assert.h index 3ef0300ec6..9f3abdeafb 100644 --- a/libretro-common/include/retro_assert.h +++ b/libretro-common/include/retro_assert.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_assert.h). diff --git a/libretro-common/include/retro_common.h b/libretro-common/include/retro_common.h index 5938bea1b5..e4804fae08 100644 --- a/libretro-common/include/retro_common.h +++ b/libretro-common/include/retro_common.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_common.h). diff --git a/libretro-common/include/retro_common_api.h b/libretro-common/include/retro_common_api.h index ff38f9837c..c3b3f4927f 100644 --- a/libretro-common/include/retro_common_api.h +++ b/libretro-common/include/retro_common_api.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_common_api.h). diff --git a/libretro-common/include/retro_dirent.h b/libretro-common/include/retro_dirent.h index 090076ec64..c3450732c5 100644 --- a/libretro-common/include/retro_dirent.h +++ b/libretro-common/include/retro_dirent.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_dirent.h). @@ -32,6 +32,16 @@ RETRO_BEGIN_DECLS typedef struct RDIR RDIR; +/** + * + * retro_opendir: + * @name : path to the directory to open. + * + * Opens a directory for reading. Tidy up with retro_closedir. + * + * Returns: RDIR pointer on success, NULL if name is not a + * valid directory, null itself or the empty string. + */ struct RDIR *retro_opendir(const char *name); int retro_readdir(struct RDIR *rdir); diff --git a/libretro-common/include/retro_endianness.h b/libretro-common/include/retro_endianness.h index fc9299e178..e721ec9d4d 100644 --- a/libretro-common/include/retro_endianness.h +++ b/libretro-common/include/retro_endianness.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_endianness.h). diff --git a/libretro-common/include/retro_environment.h b/libretro-common/include/retro_environment.h index 12ee429de8..1a18cd6f8c 100644 --- a/libretro-common/include/retro_environment.h +++ b/libretro-common/include/retro_environment.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_environment.h). diff --git a/libretro-common/include/retro_inline.h b/libretro-common/include/retro_inline.h index ffdaa4a3ab..e4a21f6c41 100644 --- a/libretro-common/include/retro_inline.h +++ b/libretro-common/include/retro_inline.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_inline.h). diff --git a/libretro-common/include/retro_math.h b/libretro-common/include/retro_math.h index c0efb23bd9..03d31dd546 100644 --- a/libretro-common/include/retro_math.h +++ b/libretro-common/include/retro_math.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_math.h). diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index 23f9ef02ac..afcb885cf7 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_miscellaneous.h). diff --git a/libretro-common/include/retro_timers.h b/libretro-common/include/retro_timers.h index 0cd4b4c48b..e56e18fc38 100644 --- a/libretro-common/include/retro_timers.h +++ b/libretro-common/include/retro_timers.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_timers.h). diff --git a/libretro-common/include/rhash.h b/libretro-common/include/rhash.h index d7394885bd..6ed9149f4d 100644 --- a/libretro-common/include/rhash.h +++ b/libretro-common/include/rhash.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rhash.h). diff --git a/libretro-common/include/rthreads/rthreads.h b/libretro-common/include/rthreads/rthreads.h index c9448ec702..6e248f3d94 100644 --- a/libretro-common/include/rthreads/rthreads.h +++ b/libretro-common/include/rthreads/rthreads.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rthreads.h). diff --git a/libretro-common/include/streams/chd_stream.h b/libretro-common/include/streams/chd_stream.h index 86f0ccbcd0..246a2dcfc9 100644 --- a/libretro-common/include/streams/chd_stream.h +++ b/libretro-common/include/streams/chd_stream.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (chd_stream.h). @@ -49,11 +49,11 @@ int chdstream_getc(chdstream_t *stream); char *chdstream_gets(chdstream_t *stream, char *buffer, size_t len); -size_t chdstream_tell(chdstream_t *stream); +uint64_t chdstream_tell(chdstream_t *stream); void chdstream_rewind(chdstream_t *stream); -int chdstream_seek(chdstream_t *stream, ssize_t offset, int whence); +int64_t chdstream_seek(chdstream_t *stream, int64_t offset, int whence); ssize_t chdstream_get_size(chdstream_t *stream); diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index 79fd92ed2e..546fd12697 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (file_stream.h). @@ -47,7 +47,7 @@ typedef struct RFILE RFILE; void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info); -ssize_t filestream_get_size(RFILE *stream); +int64_t filestream_get_size(RFILE *stream); /** * filestream_open: @@ -60,19 +60,19 @@ ssize_t filestream_get_size(RFILE *stream); **/ RFILE *filestream_open(const char *path, unsigned mode, unsigned hints); -ssize_t filestream_seek(RFILE *stream, ssize_t offset, int seek_position); +int64_t filestream_seek(RFILE *stream, int64_t offset, int seek_position); -ssize_t filestream_read(RFILE *stream, void *data, int64_t len); +int64_t filestream_read(RFILE *stream, void *data, int64_t len); -ssize_t filestream_write(RFILE *stream, const void *data, int64_t len); +int64_t filestream_write(RFILE *stream, const void *data, int64_t len); -ssize_t filestream_tell(RFILE *stream); +int64_t filestream_tell(RFILE *stream); void filestream_rewind(RFILE *stream); int filestream_close(RFILE *stream); -int filestream_read_file(const char *path, void **buf, ssize_t *len); +int64_t filestream_read_file(const char *path, void **buf, int64_t *len); char *filestream_gets(RFILE *stream, char *s, size_t len); @@ -80,7 +80,7 @@ int filestream_getc(RFILE *stream); int filestream_eof(RFILE *stream); -bool filestream_write_file(const char *path, const void *data, ssize_t size); +bool filestream_write_file(const char *path, const void *data, int64_t size); int filestream_putc(RFILE *stream, int c); diff --git a/libretro-common/include/streams/file_stream_transforms.h b/libretro-common/include/streams/file_stream_transforms.h index 0cd565b61c..c1690fa6d6 100644 --- a/libretro-common/include/streams/file_stream_transforms.h +++ b/libretro-common/include/streams/file_stream_transforms.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (file_stream_transforms.h). @@ -23,9 +23,10 @@ #ifndef __LIBRETRO_SDK_FILE_STREAM_TRANSFORMS_H #define __LIBRETRO_SDK_FILE_STREAM_TRANSFORMS_H +#include +#include #include #include -#include RETRO_BEGIN_DECLS @@ -61,19 +62,19 @@ RFILE* rfopen(const char *path, const char *mode); int rfclose(RFILE* stream); -long rftell(RFILE* stream); +int64_t rftell(RFILE* stream); -int rfseek(RFILE* stream, long offset, int origin); +int64_t rfseek(RFILE* stream, int64_t offset, int origin); -size_t rfread(void* buffer, - size_t elementSize, size_t elementCount, RFILE* stream); +int64_t rfread(void* buffer, + size_t elem_size, size_t elem_count, RFILE* stream); char *rfgets(char *buffer, int maxCount, RFILE* stream); int rfgetc(RFILE* stream); -size_t rfwrite(void const* buffer, - size_t elementSize, size_t elementCount, RFILE* stream); +int64_t rfwrite(void const* buffer, + size_t elem_size, size_t elem_count, RFILE* stream); int rfputc(int character, RFILE * stream); diff --git a/libretro-common/include/streams/interface_stream.h b/libretro-common/include/streams/interface_stream.h index 468d35eff3..71d5c97fd4 100644 --- a/libretro-common/include/streams/interface_stream.h +++ b/libretro-common/include/streams/interface_stream.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (interface_stream.h). @@ -48,7 +48,7 @@ typedef struct intfstream_info struct { uint8_t *data; - unsigned size; + uint64_t size; } buf; bool writable; } memory; @@ -68,29 +68,29 @@ bool intfstream_resize(intfstream_internal_t *intf, bool intfstream_open(intfstream_internal_t *intf, const char *path, unsigned mode, unsigned hints); -ssize_t intfstream_read(intfstream_internal_t *intf, - void *s, size_t len); +int64_t intfstream_read(intfstream_internal_t *intf, + void *s, uint64_t len); -ssize_t intfstream_write(intfstream_internal_t *intf, - const void *s, size_t len); +int64_t intfstream_write(intfstream_internal_t *intf, + const void *s, uint64_t len); char *intfstream_gets(intfstream_internal_t *intf, - char *buffer, size_t len); + char *buffer, uint64_t len); int intfstream_getc(intfstream_internal_t *intf); -int intfstream_seek(intfstream_internal_t *intf, - int offset, int whence); +int64_t intfstream_seek(intfstream_internal_t *intf, + int64_t offset, int whence); void intfstream_rewind(intfstream_internal_t *intf); -int intfstream_tell(intfstream_internal_t *intf); +int64_t intfstream_tell(intfstream_internal_t *intf); void intfstream_putc(intfstream_internal_t *intf, int c); int intfstream_close(intfstream_internal_t *intf); -ssize_t intfstream_get_size(intfstream_internal_t *intf); +int64_t intfstream_get_size(intfstream_internal_t *intf); int intfstream_flush(intfstream_internal_t *intf); @@ -98,7 +98,7 @@ intfstream_t* intfstream_open_file(const char *path, unsigned mode, unsigned hints); intfstream_t *intfstream_open_memory(void *data, - unsigned mode, unsigned hints, size_t size); + unsigned mode, unsigned hints, uint64_t size); intfstream_t *intfstream_open_chd_track(const char *path, unsigned mode, unsigned hints, int32_t track); diff --git a/libretro-common/include/streams/memory_stream.h b/libretro-common/include/streams/memory_stream.h index dca8e7a6ed..c594808772 100644 --- a/libretro-common/include/streams/memory_stream.h +++ b/libretro-common/include/streams/memory_stream.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (memory_stream.h). @@ -36,9 +36,9 @@ memstream_t *memstream_open(unsigned writing); void memstream_close(memstream_t *stream); -size_t memstream_read(memstream_t *stream, void *data, size_t bytes); +uint64_t memstream_read(memstream_t *stream, void *data, uint64_t bytes); -size_t memstream_write(memstream_t *stream, const void *data, size_t bytes); +uint64_t memstream_write(memstream_t *stream, const void *data, uint64_t bytes); int memstream_getc(memstream_t *stream); @@ -46,15 +46,15 @@ void memstream_putc(memstream_t *stream, int c); char *memstream_gets(memstream_t *stream, char *buffer, size_t len); -size_t memstream_pos(memstream_t *stream); +uint64_t memstream_pos(memstream_t *stream); void memstream_rewind(memstream_t *stream); -int memstream_seek(memstream_t *stream, int offset, int whence); +int64_t memstream_seek(memstream_t *stream, int64_t offset, int whence); -void memstream_set_buffer(uint8_t *buffer, size_t size); +void memstream_set_buffer(uint8_t *buffer, uint64_t size); -size_t memstream_get_last_size(void); +uint64_t memstream_get_last_size(void); RETRO_END_DECLS diff --git a/libretro-common/include/streams/stdin_stream.h b/libretro-common/include/streams/stdin_stream.h index ce5ebe55df..dda02963e4 100644 --- a/libretro-common/include/streams/stdin_stream.h +++ b/libretro-common/include/streams/stdin_stream.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (stdin_stream.h). diff --git a/libretro-common/include/streams/trans_stream.h b/libretro-common/include/streams/trans_stream.h index 4023103e8a..0a10368e73 100644 --- a/libretro-common/include/streams/trans_stream.h +++ b/libretro-common/include/streams/trans_stream.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (trans_stream.h). diff --git a/libretro-common/include/string/stdstring.h b/libretro-common/include/string/stdstring.h index 17e7209529..eb2954b825 100644 --- a/libretro-common/include/string/stdstring.h +++ b/libretro-common/include/string/stdstring.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (stdstring.h). diff --git a/libretro-common/include/vfs/vfs_implementation.h b/libretro-common/include/vfs/vfs_implementation.h index 5ceae39b6f..047b170354 100644 --- a/libretro-common/include/vfs/vfs_implementation.h +++ b/libretro-common/include/vfs/vfs_implementation.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (vfs_implementation.h). diff --git a/libretro-common/lists/dir_list.c b/libretro-common/lists/dir_list.c index 73148c83e3..fc360f748b 100644 --- a/libretro-common/lists/dir_list.c +++ b/libretro-common/lists/dir_list.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (dir_list.c). @@ -185,13 +185,16 @@ static int dir_list_read(const char *dir, bool is_dir = false; int ret = 0; const char *name = retro_dirent_get_name(entry); - const char *file_ext = path_get_extension(name); + const char *file_ext = ""; file_path[0] = '\0'; fill_pathname_join(file_path, dir, name, sizeof(file_path)); is_dir = retro_dirent_is_dir(entry, file_path); + if(!is_dir) + file_ext = path_get_extension(name); + if (!include_hidden) { if (*name == '.') @@ -200,7 +203,7 @@ static int dir_list_read(const char *dir, if(is_dir && recursive) { - if(strstr(name, ".") || strstr(name, "..")) + if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue; dir_list_read(file_path, list, ext_list, include_dirs, diff --git a/libretro-common/lists/file_list.c b/libretro-common/lists/file_list.c index c52523e193..1525d8879e 100644 --- a/libretro-common/lists/file_list.c +++ b/libretro-common/lists/file_list.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (file_list.c). diff --git a/libretro-common/lists/string_list.c b/libretro-common/lists/string_list.c index a5cb4be298..3a5fb96fef 100644 --- a/libretro-common/lists/string_list.c +++ b/libretro-common/lists/string_list.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (string_list.c). diff --git a/libretro-common/lists/vector_list.c b/libretro-common/lists/vector_list.c index 4b8c2314e6..b8493c5675 100644 --- a/libretro-common/lists/vector_list.c +++ b/libretro-common/lists/vector_list.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (vector_list.c). diff --git a/libretro-common/memmap/memalign.c b/libretro-common/memmap/memalign.c index 56d0c94669..449d8471b8 100644 --- a/libretro-common/memmap/memalign.c +++ b/libretro-common/memmap/memalign.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (memalign.c). diff --git a/libretro-common/memmap/memmap.c b/libretro-common/memmap/memmap.c index cda86ff01e..26d9ce031f 100644 --- a/libretro-common/memmap/memmap.c +++ b/libretro-common/memmap/memmap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (memmap.c). diff --git a/libretro-common/net/net_compat.c b/libretro-common/net/net_compat.c index a2950a8586..86c1381221 100644 --- a/libretro-common/net/net_compat.c +++ b/libretro-common/net/net_compat.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_compat.c). diff --git a/libretro-common/net/net_http.c b/libretro-common/net/net_http.c index caa6e56c93..4f2ad2635e 100644 --- a/libretro-common/net/net_http.c +++ b/libretro-common/net/net_http.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_http.c). @@ -90,7 +90,7 @@ struct http_connection_t static char urlencode_lut[256]; static bool urlencode_lut_inited = false; -void urlencode_lut_init() +void urlencode_lut_init(void) { unsigned i; @@ -109,6 +109,7 @@ void net_http_urlencode(char **dest, const char *source) char *enc = NULL; /* Assume every character will be encoded, so we need 3 times the space. */ size_t len = strlen(source) * 3 + 1; + size_t count = len; if (!urlencode_lut_inited) urlencode_lut_init(); @@ -119,11 +120,16 @@ void net_http_urlencode(char **dest, const char *source) for (; *source; source++) { + int written = 0; + /* any non-ascii character will just be encoded without question */ if ((unsigned)*source < sizeof(urlencode_lut) && urlencode_lut[(unsigned)*source]) - snprintf(enc, len, "%c", urlencode_lut[(unsigned)*source]); + written = snprintf(enc, count, "%c", urlencode_lut[(unsigned)*source]); else - snprintf(enc, len, "%%%02X", *source & 0xFF); + written = snprintf(enc, count, "%%%02X", *source & 0xFF); + + if (written > 0) + count -= written; while (*++enc); } diff --git a/libretro-common/net/net_http_parse.c b/libretro-common/net/net_http_parse.c index 69b80f6e37..113eeaa00a 100644 --- a/libretro-common/net/net_http_parse.c +++ b/libretro-common/net/net_http_parse.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_http_parse.c). diff --git a/libretro-common/net/net_ifinfo.c b/libretro-common/net/net_ifinfo.c index e226dda325..77c5971171 100644 --- a/libretro-common/net/net_ifinfo.c +++ b/libretro-common/net/net_ifinfo.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_ifinfo.c). diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c index 34c6f1d648..33d0865208 100644 --- a/libretro-common/net/net_natt.c +++ b/libretro-common/net/net_natt.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2017 The RetroArch team +/* Copyright (C) 2016-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_natt.c). @@ -74,8 +74,9 @@ void natt_init(void) descXML = (char *) miniwget(dev->descURL, &descXMLsize, 0, NULL); if (descXML) { - parserootdesc (descXML, descXMLsize, &data); - free (descXML); descXML = 0; + parserootdesc(descXML, descXMLsize, &data); + free (descXML); + descXML = 0; GetUPNPUrls (&urls, &data, dev->descURL, 0); } freeUPNPDevlist(devlist); @@ -112,44 +113,55 @@ static bool natt_open_port(struct natt_status *status, return false; /* figure out the internal info */ - if (getnameinfo(addr, addrlen, host, PATH_MAX_LENGTH, port_str, 6, NI_NUMERICHOST|NI_NUMERICSERV) != 0) + if (getnameinfo(addr, addrlen, host, PATH_MAX_LENGTH, + port_str, 6, NI_NUMERICHOST|NI_NUMERICSERV) != 0) return false; + proto_str = (proto == SOCKET_PROTOCOL_UDP) ? "UDP" : "TCP"; /* add the port mapping */ - r = UPNP_AddAnyPortMapping(urls.controlURL, data.first.servicetype, port_str, - port_str, host, "retroarch", proto_str, NULL, "3600", ext_port_str); + r = UPNP_AddAnyPortMapping(urls.controlURL, + data.first.servicetype, port_str, + port_str, host, "retroarch", + proto_str, NULL, "3600", ext_port_str); + if (r != 0) { /* try the older AddPortMapping */ memcpy(ext_port_str, port_str, 6); - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port_str, - port_str, host, "retroarch", proto_str, NULL, "3600"); + r = UPNP_AddPortMapping(urls.controlURL, + data.first.servicetype, port_str, + port_str, host, "retroarch", + proto_str, NULL, "3600"); } if (r != 0) return false; /* get the external IP */ - r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, ext_host); + r = UPNP_GetExternalIPAddress(urls.controlURL, + data.first.servicetype, ext_host); if (r != 0) return false; /* update the status */ - if (getaddrinfo_retro(ext_host, ext_port_str, &hints, &ext_addrinfo) != 0) + if (getaddrinfo_retro(ext_host, + ext_port_str, &hints, &ext_addrinfo) != 0) return false; if (ext_addrinfo->ai_family == AF_INET && ext_addrinfo->ai_addrlen >= sizeof(struct sockaddr_in)) { - status->have_inet4 = true; - status->ext_inet4_addr = *((struct sockaddr_in *) ext_addrinfo->ai_addr); + status->have_inet4 = true; + status->ext_inet4_addr = *((struct sockaddr_in *) + ext_addrinfo->ai_addr); } #if defined(AF_INET6) && !defined(HAVE_SOCKET_LEGACY) else if (ext_addrinfo->ai_family == AF_INET6 && ext_addrinfo->ai_addrlen >= sizeof(struct sockaddr_in6)) { - status->have_inet6 = true; - status->ext_inet6_addr = *((struct sockaddr_in6 *) ext_addrinfo->ai_addr); + status->have_inet6 = true; + status->ext_inet6_addr = *((struct sockaddr_in6 *) + ext_addrinfo->ai_addr); } #endif else @@ -169,16 +181,17 @@ static bool natt_open_port(struct natt_status *status, #endif } -bool natt_open_port_any(struct natt_status *status, uint16_t port, enum socket_protocol proto) +bool natt_open_port_any(struct natt_status *status, + uint16_t port, enum socket_protocol proto) { #if !defined(HAVE_SOCKET_LEGACY) && !defined(WIIU) - struct net_ifinfo list; - bool ret = false; size_t i; - struct addrinfo hints = {0}, *addr; char port_str[6]; + struct net_ifinfo list; + struct addrinfo hints = {0}, *addr; + bool ret = false; - sprintf(port_str, "%hu", port); + snprintf(port_str, sizeof(port_str), "%hu", port); /* get our interfaces */ if (!net_ifinfo_new(&list)) @@ -190,13 +203,15 @@ bool natt_open_port_any(struct natt_status *status, uint16_t port, enum socket_p struct net_ifinfo_entry *entry = list.entries + i; /* ignore localhost */ - if (string_is_equal(entry->host, "127.0.0.1") || string_is_equal(entry->host, "::1")) + if ( string_is_equal(entry->host, "127.0.0.1") || + string_is_equal(entry->host, "::1")) continue; /* make a request for this host */ if (getaddrinfo_retro(entry->host, port_str, &hints, &addr) == 0) { - ret = natt_open_port(status, addr->ai_addr, addr->ai_addrlen, proto) || ret; + ret = natt_open_port(status, addr->ai_addr, + addr->ai_addrlen, proto) || ret; freeaddrinfo_retro(addr); } } @@ -218,19 +233,24 @@ bool natt_read(struct natt_status *status) } #if 0 -/* If we want to remove redirects in the future, this is a sample of how to do - * that */ +/* If we want to remove redirects in the future, this is a + * sample of how to do that. */ + void upnp_rem_redir (int port) { - char port_str[16]; int t; + char port_str[16]; + printf("TB : upnp_rem_redir (%d)\n", port); + if(urls.controlURL[0] == '\0') { printf("TB : the init was not done !\n"); return; } - sprintf(port_str, "%d", port); - UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port_str, "TCP", NULL); + + snprintf(port_str, sizeof(port_str), "%d", port); + UPNP_DeletePortMapping(urls.controlURL, + data.first.servicetype, port_str, "TCP", NULL); } #endif diff --git a/libretro-common/net/net_socket.c b/libretro-common/net/net_socket.c index 0c960360bc..e2213c9bac 100644 --- a/libretro-common/net/net_socket.c +++ b/libretro-common/net/net_socket.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_socket.c). diff --git a/libretro-common/net/net_socket_ssl.c b/libretro-common/net/net_socket_ssl.c index 4b9da1206b..04e0babad1 100644 --- a/libretro-common/net/net_socket_ssl.c +++ b/libretro-common/net/net_socket_ssl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (net_socket.c). diff --git a/libretro-common/queues/fifo_queue.c b/libretro-common/queues/fifo_queue.c index 85d0268011..d6b21aca48 100644 --- a/libretro-common/queues/fifo_queue.c +++ b/libretro-common/queues/fifo_queue.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (fifo_queue.c). diff --git a/libretro-common/queues/message_queue.c b/libretro-common/queues/message_queue.c index dda5cbf5a1..a8086c3b9f 100644 --- a/libretro-common/queues/message_queue.c +++ b/libretro-common/queues/message_queue.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (message_queue.c). diff --git a/libretro-common/queues/task_queue.c b/libretro-common/queues/task_queue.c index 2d45f65ea0..2eb51dd9e7 100644 --- a/libretro-common/queues/task_queue.c +++ b/libretro-common/queues/task_queue.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (task_queue.c). diff --git a/libretro-common/rthreads/ctr_pthread.h b/libretro-common/rthreads/ctr_pthread.h index 8c82e6e511..0a393ebb8f 100644 --- a/libretro-common/rthreads/ctr_pthread.h +++ b/libretro-common/rthreads/ctr_pthread.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (gx_pthread.h). diff --git a/libretro-common/rthreads/gx_pthread.h b/libretro-common/rthreads/gx_pthread.h index 8cb4616231..055c6afbde 100644 --- a/libretro-common/rthreads/gx_pthread.h +++ b/libretro-common/rthreads/gx_pthread.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (gx_pthread.h). diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index 9632c2a2d6..e155075555 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rthreads.c). diff --git a/libretro-common/rthreads/xenon_sdl_threads.c b/libretro-common/rthreads/xenon_sdl_threads.c index 0097673528..ff1855c275 100644 --- a/libretro-common/rthreads/xenon_sdl_threads.c +++ b/libretro-common/rthreads/xenon_sdl_threads.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (xenon_sdl_threads.c). diff --git a/libretro-common/streams/chd_stream.c b/libretro-common/streams/chd_stream.c index ebd736f0ad..669bd43391 100644 --- a/libretro-common/streams/chd_stream.c +++ b/libretro-common/streams/chd_stream.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (chd_stream.c). @@ -386,7 +386,7 @@ char *chdstream_gets(chdstream_t *stream, char *buffer, size_t len) return buffer; } -size_t chdstream_tell(chdstream_t *stream) +uint64_t chdstream_tell(chdstream_t *stream) { return stream->offset; } @@ -396,9 +396,9 @@ void chdstream_rewind(chdstream_t *stream) stream->offset = 0; } -int chdstream_seek(chdstream_t *stream, ssize_t offset, int whence) +int64_t chdstream_seek(chdstream_t *stream, int64_t offset, int whence) { - ssize_t new_offset; + int64_t new_offset; switch (whence) { diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 988ba73028..5ccdbcfacb 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (file_stream.c). @@ -111,9 +111,9 @@ bool filestream_exists(const char *path) return true; } -ssize_t filestream_get_size(RFILE *stream) +int64_t filestream_get_size(RFILE *stream) { - ssize_t output; + int64_t output; if (filestream_size_cb != NULL) output = filestream_size_cb(stream->hfile); @@ -191,7 +191,7 @@ int filestream_getc(RFILE *stream) return EOF; } -ssize_t filestream_seek(RFILE *stream, ssize_t offset, int seek_position) +int64_t filestream_seek(RFILE *stream, int64_t offset, int seek_position) { int64_t output; @@ -213,9 +213,9 @@ int filestream_eof(RFILE *stream) } -ssize_t filestream_tell(RFILE *stream) +int64_t filestream_tell(RFILE *stream) { - ssize_t output; + int64_t output; if (filestream_size_cb != NULL) output = filestream_tell_cb(stream->hfile); @@ -237,7 +237,7 @@ void filestream_rewind(RFILE *stream) stream->eof_flag = false; } -ssize_t filestream_read(RFILE *stream, void *s, int64_t len) +int64_t filestream_read(RFILE *stream, void *s, int64_t len) { int64_t output; @@ -294,7 +294,7 @@ const char *filestream_get_path(RFILE *stream) return retro_vfs_file_get_path_impl((libretro_vfs_implementation_file*)stream->hfile); } -ssize_t filestream_write(RFILE *stream, const void *s, int64_t len) +int64_t filestream_write(RFILE *stream, const void *s, int64_t len) { int64_t output; @@ -320,14 +320,14 @@ int filestream_putc(RFILE *stream, int c) int filestream_vprintf(RFILE *stream, const char* format, va_list args) { static char buffer[8 * 1024]; - int num_chars = vsprintf(buffer, format, args); + int64_t num_chars = vsprintf(buffer, format, args); if (num_chars < 0) return -1; else if (num_chars == 0) return 0; - return filestream_write(stream, buffer, num_chars); + return (int)filestream_write(stream, buffer, num_chars); } int filestream_printf(RFILE *stream, const char* format, ...) @@ -373,9 +373,9 @@ int filestream_close(RFILE *stream) * * Returns: number of items read, -1 on error. */ -int filestream_read_file(const char *path, void **buf, ssize_t *len) +int64_t filestream_read_file(const char *path, void **buf, int64_t *len) { - ssize_t ret = 0; + int64_t ret = 0; int64_t content_buf_size = 0; void *content_buf = NULL; RFILE *file = filestream_open(path, @@ -397,7 +397,7 @@ int filestream_read_file(const char *path, void **buf, ssize_t *len) if (!content_buf) goto error; - if ((int64_t)(size_t)(content_buf_size + 1) != (content_buf_size + 1)) + if ((int64_t)(uint64_t)(content_buf_size + 1) != (content_buf_size + 1)) goto error; ret = filestream_read(file, content_buf, (int64_t)content_buf_size); @@ -441,9 +441,9 @@ error: * * Returns: true (1) on success, false (0) otherwise. */ -bool filestream_write_file(const char *path, const void *data, ssize_t size) +bool filestream_write_file(const char *path, const void *data, int64_t size) { - ssize_t ret = 0; + int64_t ret = 0; RFILE *file = filestream_open(path, RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE); diff --git a/libretro-common/streams/file_stream_transforms.c b/libretro-common/streams/file_stream_transforms.c index 8796073693..efeb7edd9c 100644 --- a/libretro-common/streams/file_stream_transforms.c +++ b/libretro-common/streams/file_stream_transforms.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (file_stream_transforms.c). @@ -72,12 +72,12 @@ int rfclose(RFILE* stream) return filestream_close(stream); } -long rftell(RFILE* stream) +int64_t rftell(RFILE* stream) { return filestream_tell(stream); } -int rfseek(RFILE* stream, long offset, int origin) +int64_t rfseek(RFILE* stream, int64_t offset, int origin) { int seek_position = -1; switch (origin) @@ -96,7 +96,7 @@ int rfseek(RFILE* stream, long offset, int origin) return filestream_seek(stream, offset, seek_position); } -size_t rfread(void* buffer, +int64_t rfread(void* buffer, size_t elem_size, size_t elem_count, RFILE* stream) { return filestream_read(stream, buffer, elem_size * elem_count); @@ -112,7 +112,7 @@ int rfgetc(RFILE* stream) return filestream_getc(stream); } -size_t rfwrite(void const* buffer, +int64_t rfwrite(void const* buffer, size_t elem_size, size_t elem_count, RFILE* stream) { return filestream_write(stream, buffer, elem_size * elem_count); diff --git a/libretro-common/streams/interface_stream.c b/libretro-common/streams/interface_stream.c index c61d12234b..0207823ce2 100644 --- a/libretro-common/streams/interface_stream.c +++ b/libretro-common/streams/interface_stream.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (interface_stream.c). @@ -43,7 +43,7 @@ struct intfstream_internal struct { uint8_t *data; - unsigned size; + uint64_t size; } buf; memstream_t *fp; bool writable; @@ -57,7 +57,7 @@ struct intfstream_internal #endif }; -ssize_t intfstream_get_size(intfstream_internal_t *intf) +int64_t intfstream_get_size(intfstream_internal_t *intf) { if (!intf) return 0; @@ -219,7 +219,7 @@ error: return NULL; } -int intfstream_seek(intfstream_internal_t *intf, int offset, int whence) +int64_t intfstream_seek(intfstream_internal_t *intf, int64_t offset, int whence) { if (!intf) return -1; @@ -241,14 +241,14 @@ int intfstream_seek(intfstream_internal_t *intf, int offset, int whence) seek_position = RETRO_VFS_SEEK_POSITION_END; break; } - return (int)filestream_seek(intf->file.fp, (int)offset, + return (int64_t)filestream_seek(intf->file.fp, (int64_t)offset, seek_position); } case INTFSTREAM_MEMORY: - return (int)memstream_seek(intf->memory.fp, offset, whence); + return (int64_t)memstream_seek(intf->memory.fp, offset, whence); case INTFSTREAM_CHD: #ifdef HAVE_CHD - return (int)chdstream_seek(intf->chd.fp, offset, whence); + return (int64_t)chdstream_seek(intf->chd.fp, offset, whence); #else break; #endif @@ -257,7 +257,7 @@ int intfstream_seek(intfstream_internal_t *intf, int offset, int whence) return -1; } -ssize_t intfstream_read(intfstream_internal_t *intf, void *s, size_t len) +int64_t intfstream_read(intfstream_internal_t *intf, void *s, uint64_t len) { if (!intf) return 0; @@ -279,8 +279,8 @@ ssize_t intfstream_read(intfstream_internal_t *intf, void *s, size_t len) return -1; } -ssize_t intfstream_write(intfstream_internal_t *intf, - const void *s, size_t len) +int64_t intfstream_write(intfstream_internal_t *intf, + const void *s, uint64_t len) { if (!intf) return 0; @@ -299,7 +299,7 @@ ssize_t intfstream_write(intfstream_internal_t *intf, } char *intfstream_gets(intfstream_internal_t *intf, - char *buffer, size_t len) + char *buffer, uint64_t len) { if (!intf) return NULL; @@ -307,9 +307,11 @@ char *intfstream_gets(intfstream_internal_t *intf, switch (intf->type) { case INTFSTREAM_FILE: - return filestream_gets(intf->file.fp, buffer, len); + return filestream_gets(intf->file.fp, + buffer, (size_t)len); case INTFSTREAM_MEMORY: - return memstream_gets(intf->memory.fp, buffer, len); + return memstream_gets(intf->memory.fp, + buffer, (size_t)len); case INTFSTREAM_CHD: #ifdef HAVE_CHD return chdstream_gets(intf->chd.fp, buffer, len); @@ -343,7 +345,7 @@ int intfstream_getc(intfstream_internal_t *intf) return -1; } -int intfstream_tell(intfstream_internal_t *intf) +int64_t intfstream_tell(intfstream_internal_t *intf) { if (!intf) return -1; @@ -351,12 +353,12 @@ int intfstream_tell(intfstream_internal_t *intf) switch (intf->type) { case INTFSTREAM_FILE: - return (int)filestream_tell(intf->file.fp); + return (int64_t)filestream_tell(intf->file.fp); case INTFSTREAM_MEMORY: - return (int)memstream_pos(intf->memory.fp); + return (int64_t)memstream_pos(intf->memory.fp); case INTFSTREAM_CHD: #ifdef HAVE_CHD - return (int)chdstream_tell(intf->chd.fp); + return (int64_t)chdstream_tell(intf->chd.fp); #else break; #endif @@ -428,7 +430,7 @@ error: } intfstream_t *intfstream_open_memory(void *data, - unsigned mode, unsigned hints, size_t size) + unsigned mode, unsigned hints, uint64_t size) { intfstream_info_t info; intfstream_t *fd = NULL; diff --git a/libretro-common/streams/memory_stream.c b/libretro-common/streams/memory_stream.c index 014101227d..77a2c008d2 100644 --- a/libretro-common/streams/memory_stream.c +++ b/libretro-common/streams/memory_stream.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (memory_stream.c). @@ -26,16 +26,16 @@ #include -static uint8_t* g_buffer = NULL; -static size_t g_size = 0; -static size_t last_file_size = 0; +static uint8_t* g_buffer = NULL; +static uint64_t g_size = 0; +static uint64_t last_file_size = 0; struct memstream { uint8_t *buf; - size_t size; - size_t ptr; - size_t max_ptr; + uint64_t size; + uint64_t ptr; + uint64_t max_ptr; unsigned writing; }; @@ -45,19 +45,19 @@ static void memstream_update_pos(memstream_t *stream) stream->max_ptr = stream->ptr; } -void memstream_set_buffer(uint8_t *buffer, size_t size) +void memstream_set_buffer(uint8_t *buffer, uint64_t size) { g_buffer = buffer; g_size = size; } -size_t memstream_get_last_size(void) +uint64_t memstream_get_last_size(void) { return last_file_size; } static void memstream_init(memstream_t *stream, - uint8_t *buffer, size_t max_size, unsigned writing) + uint8_t *buffer, uint64_t max_size, unsigned writing) { if (!stream) return; @@ -92,9 +92,9 @@ void memstream_close(memstream_t *stream) free(stream); } -size_t memstream_read(memstream_t *stream, void *data, size_t bytes) +uint64_t memstream_read(memstream_t *stream, void *data, uint64_t bytes) { - size_t avail = 0; + uint64_t avail = 0; if (!stream) return 0; @@ -103,15 +103,15 @@ size_t memstream_read(memstream_t *stream, void *data, size_t bytes) if (bytes > avail) bytes = avail; - memcpy(data, stream->buf + stream->ptr, bytes); + memcpy(data, stream->buf + stream->ptr, (size_t)bytes); stream->ptr += bytes; memstream_update_pos(stream); return bytes; } -size_t memstream_write(memstream_t *stream, const void *data, size_t bytes) +uint64_t memstream_write(memstream_t *stream, const void *data, uint64_t bytes) { - size_t avail = 0; + uint64_t avail = 0; if (!stream) return 0; @@ -120,15 +120,15 @@ size_t memstream_write(memstream_t *stream, const void *data, size_t bytes) if (bytes > avail) bytes = avail; - memcpy(stream->buf + stream->ptr, data, bytes); + memcpy(stream->buf + stream->ptr, data, (size_t)bytes); stream->ptr += bytes; memstream_update_pos(stream); return bytes; } -int memstream_seek(memstream_t *stream, int offset, int whence) +int64_t memstream_seek(memstream_t *stream, int64_t offset, int whence) { - size_t ptr; + uint64_t ptr; switch (whence) { @@ -159,7 +159,7 @@ void memstream_rewind(memstream_t *stream) memstream_seek(stream, 0L, SEEK_SET); } -size_t memstream_pos(memstream_t *stream) +uint64_t memstream_pos(memstream_t *stream) { return stream->ptr; } diff --git a/libretro-common/streams/stdin_stream.c b/libretro-common/streams/stdin_stream.c index c30c0f4575..6aedfae388 100644 --- a/libretro-common/streams/stdin_stream.c +++ b/libretro-common/streams/stdin_stream.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (stdin_stream.c). diff --git a/libretro-common/streams/trans_stream.c b/libretro-common/streams/trans_stream.c index 10eea457a7..92f3207d64 100644 --- a/libretro-common/streams/trans_stream.c +++ b/libretro-common/streams/trans_stream.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (trans_stream.c). diff --git a/libretro-common/streams/trans_stream_pipe.c b/libretro-common/streams/trans_stream_pipe.c index f30d5df390..5a2e076652 100644 --- a/libretro-common/streams/trans_stream_pipe.c +++ b/libretro-common/streams/trans_stream_pipe.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (trans_stream_pipe.c). diff --git a/libretro-common/streams/trans_stream_zlib.c b/libretro-common/streams/trans_stream_zlib.c index ec350119ca..7f797f12d6 100644 --- a/libretro-common/streams/trans_stream_zlib.c +++ b/libretro-common/streams/trans_stream_zlib.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (trans_stream_zlib.c). diff --git a/libretro-common/string/stdstring.c b/libretro-common/string/stdstring.c index 02f8dad8ec..6e1555dbfe 100644 --- a/libretro-common/string/stdstring.c +++ b/libretro-common/string/stdstring.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (stdstring.c). @@ -169,7 +169,7 @@ char *word_wrap(char* buffer, const char *string, int line_width, bool unicode) } character = utf8skip(&string[i], 1); - char_len = character - &string[i]; + char_len = (unsigned)(character - &string[i]); if (!unicode) counter += char_len - 1; diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c index ce6fa5bf0e..ff8100f7f1 100644 --- a/libretro-common/vfs/vfs_implementation.c +++ b/libretro-common/vfs/vfs_implementation.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2018 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (vfs_implementation.c). diff --git a/libretro-db/.gitignore b/libretro-db/.gitignore new file mode 100644 index 0000000000..09ef21d176 --- /dev/null +++ b/libretro-db/.gitignore @@ -0,0 +1,4 @@ +# Ignore compiled binaries. +/c_converter +/libretrodb_tool +/rmsgpack_test diff --git a/libretro-db/c_converter.c b/libretro-db/c_converter.c index f08171ca17..3d2e2ac615 100644 --- a/libretro-db/c_converter.c +++ b/libretro-db/c_converter.c @@ -494,6 +494,7 @@ static dat_converter_list_t* dat_converter_parser( dat_converter_map_t map; dat_converter_list_item_t* current = lexer_list->values; bool skip = true; + bool warning_displayed = false; map.key = NULL; map.type = DAT_CONVERTER_LIST_MAP; @@ -531,13 +532,17 @@ static dat_converter_list_t* dat_converter_parser( // If the key is not found, report, and mark it to be skipped. if (!map.key) { - printf("Missing match key '"); - while (match_key->next) + if (warning_displayed == false) { - printf("%s.", match_key->value); - match_key = match_key->next; + printf(" - Missing match key '"); + while (match_key->next) + { + printf("%s.", match_key->value); + match_key = match_key->next; + } + printf("%s' on line %d\n", match_key->value, current->token.line_no); + warning_displayed = true; } - printf("%s' on line %d\n", match_key->value, current->token.line_no); skip = true; } } diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 6d29ea73d7..b039bc4aef 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -82,6 +82,7 @@ generic_deferred_push(deferred_push_video_shader_preset_parameters, DISPLAYLIST_ generic_deferred_push(deferred_push_video_shader_parameters, DISPLAYLIST_SHADER_PARAMETERS) generic_deferred_push(deferred_push_settings, DISPLAYLIST_SETTINGS_ALL) generic_deferred_push(deferred_push_shader_options, DISPLAYLIST_OPTIONS_SHADERS) +generic_deferred_push(deferred_push_quick_menu_override_options, DISPLAYLIST_OPTIONS_OVERRIDES) generic_deferred_push(deferred_push_options, DISPLAYLIST_OPTIONS) generic_deferred_push(deferred_push_netplay, DISPLAYLIST_NETPLAY_ROOM_LIST) generic_deferred_push(deferred_push_netplay_sublist, DISPLAYLIST_NETPLAY) @@ -134,6 +135,7 @@ generic_deferred_push(deferred_push_core_settings_list, DISPLAYLIST_ generic_deferred_push(deferred_push_video_settings_list, DISPLAYLIST_VIDEO_SETTINGS_LIST) generic_deferred_push(deferred_push_configuration_settings_list, DISPLAYLIST_CONFIGURATION_SETTINGS_LIST) generic_deferred_push(deferred_push_saving_settings_list, DISPLAYLIST_SAVING_SETTINGS_LIST) +generic_deferred_push(deferred_push_mixer_stream_settings_list, DISPLAYLIST_MIXER_STREAM_SETTINGS_LIST) generic_deferred_push(deferred_push_logging_settings_list, DISPLAYLIST_LOGGING_SETTINGS_LIST) generic_deferred_push(deferred_push_frame_throttle_settings_list, DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST) generic_deferred_push(deferred_push_rewind_settings_list, DISPLAYLIST_REWIND_SETTINGS_LIST) @@ -154,7 +156,9 @@ generic_deferred_push(deferred_push_user_settings_list, DISPLAYLIST_ generic_deferred_push(deferred_push_directory_settings_list, DISPLAYLIST_DIRECTORY_SETTINGS_LIST) generic_deferred_push(deferred_push_privacy_settings_list, DISPLAYLIST_PRIVACY_SETTINGS_LIST) generic_deferred_push(deferred_push_audio_settings_list, DISPLAYLIST_AUDIO_SETTINGS_LIST) +generic_deferred_push(deferred_push_audio_mixer_settings_list, DISPLAYLIST_AUDIO_MIXER_SETTINGS_LIST) generic_deferred_push(deferred_push_input_settings_list, DISPLAYLIST_INPUT_SETTINGS_LIST) +generic_deferred_push(deferred_push_latency_settings_list, DISPLAYLIST_LATENCY_SETTINGS_LIST) generic_deferred_push(deferred_push_recording_settings_list, DISPLAYLIST_RECORDING_SETTINGS_LIST) generic_deferred_push(deferred_push_playlist_settings_list, DISPLAYLIST_PLAYLIST_SETTINGS_LIST) generic_deferred_push(deferred_push_input_hotkey_binds_list, DISPLAYLIST_INPUT_HOTKEY_BINDS_LIST) @@ -202,12 +206,15 @@ static int deferred_push_cursor_manager_list_deferred( if (!string_is_empty(info->path_b)) free(info->path_b); + if (!string_is_empty(info->path_c)) free(info->path_c); + + info->path_b = strdup(info->path); + if (!string_is_empty(info->path)) free(info->path); - info->path_b = strdup(info->path); info->path_c = strdup(query); info->path = strdup(rdb_path); @@ -620,6 +627,11 @@ static int menu_cbs_init_bind_deferred_push_compare_label( BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_saving_settings_list); return 0; } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST))) + { + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_mixer_stream_settings_list); + return 0; + } else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_LOGGING_SETTINGS_LIST))) { BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_logging_settings_list); @@ -805,6 +817,16 @@ static int menu_cbs_init_bind_deferred_push_compare_label( { BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_audio_settings_list); } + else if (strstr(label, + msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_AUDIO_MIXER_SETTINGS_LIST))) + { + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_audio_mixer_settings_list); + } + else if (strstr(label, + msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_LATENCY_SETTINGS_LIST))) + { + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_latency_settings_list); + } else if (strstr(label, msg_hash_to_str(MENU_ENUM_LABEL_CORE_INFORMATION))) { @@ -882,6 +904,11 @@ static int menu_cbs_init_bind_deferred_push_compare_label( { BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_input_hotkey_binds_list); } + else if (strstr(label, + msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_QUICK_MENU_OVERRIDE_OPTIONS))) + { + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_quick_menu_override_options); + } else { if (cbs->enum_idx != MSG_UNKNOWN) @@ -1155,6 +1182,9 @@ static int menu_cbs_init_bind_deferred_push_compare_label( case MENU_ENUM_LABEL_DEFERRED_AUDIO_SETTINGS_LIST: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_audio_settings_list); break; + case MENU_ENUM_LABEL_DEFERRED_LATENCY_SETTINGS_LIST: + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_latency_settings_list); + break; case MENU_ENUM_LABEL_DEFERRED_CORE_SETTINGS_LIST: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_core_settings_list); break; diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index ec8c1b4005..9e8d03bece 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -31,6 +31,7 @@ #include "../../tasks/tasks_internal.h" #include "../../input/input_driver.h" +#include "../../audio/audio_driver.h" #include "../../core.h" #include "../../core_info.h" #include "../../configuration.h" @@ -54,7 +55,47 @@ cbs->action_get_value_ident = #name; #endif -extern struct key_desc key_descriptors[MENU_SETTINGS_INPUT_DESC_KBD_END]; +extern struct key_desc key_descriptors[RARCH_MAX_KEYS]; + +static void menu_action_setting_audio_mixer_stream_name( + file_list_t* list, + unsigned *w, unsigned type, unsigned i, + const char *label, + char *s, size_t len, + const char *entry_label, + const char *path, + char *s2, size_t len2) +{ + unsigned offset = (type - MENU_SETTINGS_AUDIO_MIXER_STREAM_BEGIN); + + *w = 19; + strlcpy(s2, path, len2); + + if (offset >= AUDIO_MIXER_MAX_STREAMS) + return; + + strlcpy(s, audio_driver_mixer_get_stream_name(offset), len); +} + +static void menu_action_setting_audio_mixer_stream_volume( + file_list_t* list, + unsigned *w, unsigned type, unsigned i, + const char *label, + char *s, size_t len, + const char *entry_label, + const char *path, + char *s2, size_t len2) +{ + unsigned offset = (type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN); + + *w = 19; + strlcpy(s2, path, len2); + + if (offset >= AUDIO_MIXER_MAX_STREAMS) + return; + + snprintf(s, len, "%.2f dB", audio_driver_mixer_get_stream_volume(offset)); +} static void menu_action_setting_disp_set_label_cheat_num_passes( file_list_t* list, @@ -547,80 +588,50 @@ static void menu_action_setting_disp_set_label_input_desc( const char *path, char *s2, size_t len2) { - char descriptor[255]; - const struct retro_keybind *auto_bind = NULL; - const struct retro_keybind *keybind = NULL; + rarch_system_info_t *system = runloop_get_system_info(); settings_t *settings = config_get_ptr(); - unsigned inp_desc_index_offset = - type - MENU_SETTINGS_INPUT_DESC_BEGIN; - unsigned inp_desc_user = inp_desc_index_offset / - (RARCH_FIRST_CUSTOM_BIND + 4); - unsigned inp_desc_button_index_offset = inp_desc_index_offset - - (inp_desc_user * (RARCH_FIRST_CUSTOM_BIND + 4)); - unsigned remap_id = 0; + const char* descriptor = NULL; + char buf[256]; + + unsigned btn_idx, user_idx, remap_idx; if (!settings) return; - descriptor[0] = '\0'; + user_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8); + btn_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx; - remap_id = settings->uints.input_remap_ids - [inp_desc_user][inp_desc_button_index_offset]; + remap_idx = + settings->uints.input_remap_ids[user_idx][btn_idx]; +/* + if (remap_idx == RARCH_UNMAPPED) + settings->uints.input_remap_ids[user_idx][btn_idx] = RARCH_UNMAPPED; +*/ + if (!system) + return; - keybind = &input_config_binds[inp_desc_user][remap_id]; - auto_bind = (const struct retro_keybind*) - input_config_get_bind_auto(inp_desc_user, remap_id); + descriptor = system->input_desc_btn[user_idx][remap_idx]; - input_config_get_bind_string(descriptor, - keybind, auto_bind, sizeof(descriptor)); - - if (inp_desc_button_index_offset < RARCH_FIRST_CUSTOM_BIND) + if (!string_is_empty(descriptor) && remap_idx < RARCH_FIRST_CUSTOM_BIND) + strlcpy(s, descriptor, len); + else if (!string_is_empty(descriptor) && remap_idx >= RARCH_FIRST_CUSTOM_BIND && remap_idx % 2 == 0) { - if(strstr(descriptor, "Auto") && !strstr(descriptor, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE))) - strlcpy(s, - descriptor, - len); - else - { - const struct retro_keybind *keyptr = &input_config_binds[inp_desc_user] - [remap_id]; - - strlcpy(s, msg_hash_to_str(keyptr->enum_idx), len); - } + snprintf(buf, sizeof(buf), "%s %c", descriptor, '+'); + strlcpy(s, buf, len); + } + else if (!string_is_empty(descriptor) && remap_idx >= RARCH_FIRST_CUSTOM_BIND && remap_idx % 2 != 0) + { + snprintf(buf, sizeof(buf), "%s %c", descriptor, '-'); + strlcpy(s, buf, len); } - - - else - { - const char *str = NULL; - switch (remap_id) - { - case 0: - str = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X); - break; - case 1: - str = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y); - break; - case 2: - str = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X); - break; - case 3: - str = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y); - break; - } + strlcpy(s, "---", len); - if (!string_is_empty(str)) - strlcpy(s, str, len); - } *w = 19; strlcpy(s2, path, len2); - } -#ifdef HAVE_KEYMAPPER static void menu_action_setting_disp_set_label_input_desc_kbd( file_list_t* list, unsigned *w, unsigned type, unsigned i, @@ -631,28 +642,40 @@ static void menu_action_setting_disp_set_label_input_desc_kbd( char *s2, size_t len2) { char desc[PATH_MAX_LENGTH]; - unsigned key_id; + unsigned key_id, id; unsigned remap_id; + unsigned offset = 0; + settings_t *settings = config_get_ptr(); if (!settings) return; - remap_id = - settings->uints.input_keymapper_ids[type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN]; + offset = type / ((MENU_SETTINGS_INPUT_DESC_KBD_END - + (MENU_SETTINGS_INPUT_DESC_KBD_END - + MENU_SETTINGS_INPUT_DESC_KBD_BEGIN))) - 1; - for (key_id = 0; key_id < MENU_SETTINGS_INPUT_DESC_KBD_END - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN; key_id++) + id = (type / (offset + 1)) - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN; + remap_id = + settings->uints.input_keymapper_ids[offset][id]; + + for (key_id = 0; key_id < RARCH_MAX_KEYS - 1; key_id++) { if(remap_id == key_descriptors[key_id].key) break; } - snprintf(desc, sizeof(desc), "Keyboard %s", key_descriptors[key_id].desc); - strlcpy(s, desc, len); + + if (key_descriptors[key_id].key != RETROK_FIRST) + { + snprintf(desc, sizeof(desc), "Keyboard %s", key_descriptors[key_id].desc); + strlcpy(s, desc, len); + } + else + strlcpy(s, "---", len); *w = 19; strlcpy(s2, path, len2); } -#endif static void menu_action_setting_disp_set_label_cheat( file_list_t* list, @@ -940,6 +963,37 @@ static void menu_action_setting_disp_set_label_wifi_is_online( strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ONLINE), len); } +static void menu_action_setting_disp_set_label_xmb_layout( + file_list_t* list, + unsigned *w, unsigned type, unsigned i, + const char *label, + char *s, size_t len, + const char *entry_label, + const char *path, + char *s2, size_t len2) +{ + settings_t *settings = config_get_ptr(); + + strlcpy(s2, path, len2); + *w = 19; + + if (!settings) + return; + + switch (settings->uints.menu_xmb_layout) + { + case 0: + strlcpy(s, "Auto", len); + break; + case 1: + strlcpy(s, "Console", len); + break; + case 2: + strlcpy(s, "Handheld", len); + break; + } +} + static void menu_action_setting_disp_set_label_xmb_menu_color_theme( file_list_t* list, unsigned *w, unsigned type, unsigned i, @@ -1134,6 +1188,47 @@ static void menu_action_setting_disp_set_label_thumbnails( } } +static void menu_action_setting_disp_set_label_left_thumbnails( + file_list_t* list, + unsigned *w, unsigned type, unsigned i, + const char *label, + char *s, size_t len, + const char *entry_label, + const char *path, + char *s2, size_t len2) +{ + settings_t *settings = config_get_ptr(); + + if (!settings) + return; + + strlcpy(s2, path, len2); + *w = 19; + + switch (settings->uints.menu_left_thumbnails) + { + case 0: + strlcpy(s, msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_OFF), len); + break; + case 1: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS), len); + break; + case 2: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS), len); + break; + case 3: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS), len); + break; + } +} + static void menu_action_setting_disp_set_label_menu_toggle_gamepad_combo( file_list_t* list, unsigned *w, unsigned type, unsigned i, @@ -1892,6 +1987,10 @@ static int menu_cbs_init_bind_get_string_representation_compare_label( BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label_poll_type_behavior); break; + case MENU_ENUM_LABEL_XMB_LAYOUT: + BIND_ACTION_GET_VALUE(cbs, + menu_action_setting_disp_set_label_xmb_layout); + break; case MENU_ENUM_LABEL_XMB_THEME: BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label_xmb_theme); @@ -1912,6 +2011,10 @@ static int menu_cbs_init_bind_get_string_representation_compare_label( BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label_thumbnails); break; + case MENU_ENUM_LABEL_LEFT_THUMBNAILS: + BIND_ACTION_GET_VALUE(cbs, + menu_action_setting_disp_set_label_left_thumbnails); + break; case MENU_ENUM_LABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO: BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label_menu_toggle_gamepad_combo); @@ -2032,7 +2135,20 @@ static int menu_cbs_init_bind_get_string_representation_compare_label( static int menu_cbs_init_bind_get_string_representation_compare_type( menu_file_list_cbs_t *cbs, unsigned type) { - if (type >= MENU_SETTINGS_INPUT_DESC_BEGIN + if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_END) + { + BIND_ACTION_GET_VALUE(cbs, + menu_action_setting_audio_mixer_stream_name); + return 0; + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_END) + { + BIND_ACTION_GET_VALUE(cbs, + menu_action_setting_audio_mixer_stream_volume); + } + else if (type >= MENU_SETTINGS_INPUT_DESC_BEGIN && type <= MENU_SETTINGS_INPUT_DESC_END) { BIND_ACTION_GET_VALUE(cbs, @@ -2056,14 +2172,12 @@ static int menu_cbs_init_bind_get_string_representation_compare_type( BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label_libretro_perf_counters); } -#ifdef HAVE_KEYMAPPER else if (type >= MENU_SETTINGS_INPUT_DESC_KBD_BEGIN && type <= MENU_SETTINGS_INPUT_DESC_KBD_END) { BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label_input_desc_kbd); } -#endif else { switch (type) diff --git a/menu/cbs/menu_cbs_left.c b/menu/cbs/menu_cbs_left.c index 230b6fea0d..ecd86c7d0c 100644 --- a/menu/cbs/menu_cbs_left.c +++ b/menu/cbs/menu_cbs_left.c @@ -35,6 +35,9 @@ #include "../../core_info.h" #include "../../managers/cheat_manager.h" #include "../../file_path_special.h" +#include "../../driver.h" +#include "../../audio/audio_driver.h" +#include "../../gfx/video_driver.h" #include "../../retroarch.h" #include "../../network/netplay/netplay.h" @@ -46,7 +49,255 @@ } while(0) #endif -extern struct key_desc key_descriptors[MENU_SETTINGS_INPUT_DESC_KBD_END]; +extern struct key_desc key_descriptors[RARCH_MAX_KEYS]; + +int setting_action_left_analog_dpad_mode(void *data, bool wraparound) +{ + unsigned port = 0; + rarch_setting_t *setting = (rarch_setting_t*)data; + settings_t *settings = config_get_ptr(); + + if (!setting) + return -1; + + port = setting->index_offset; + + configuration_set_uint(settings, settings->uints.input_analog_dpad_mode[port], + (settings->uints.input_analog_dpad_mode + [port] + ANALOG_DPAD_LAST - 1) % ANALOG_DPAD_LAST); + + return 0; +} + +int setting_action_left_libretro_device_type( + void *data, bool wraparound) +{ + retro_ctx_controller_info_t pad; + unsigned current_device, current_idx, i, devices[128], + types = 0, port = 0; + const struct retro_controller_info *desc = NULL; + rarch_setting_t *setting = (rarch_setting_t*)data; + rarch_system_info_t *system = NULL; + + if (!setting) + return -1; + + port = setting->index_offset; + + devices[types++] = RETRO_DEVICE_NONE; + devices[types++] = RETRO_DEVICE_JOYPAD; + + system = runloop_get_system_info(); + + if (system) + { + /* Only push RETRO_DEVICE_ANALOG as default if we use an + * older core which doesn't use SET_CONTROLLER_INFO. */ + if (!system->ports.size) + devices[types++] = RETRO_DEVICE_ANALOG; + + if (port < system->ports.size) + desc = &system->ports.data[port]; + } + + if (desc) + { + for (i = 0; i < desc->num_types; i++) + { + unsigned id = desc->types[i].id; + if (types < ARRAY_SIZE(devices) && + id != RETRO_DEVICE_NONE && + id != RETRO_DEVICE_JOYPAD) + devices[types++] = id; + } + } + + current_device = input_config_get_device(port); + current_idx = 0; + for (i = 0; i < types; i++) + { + if (current_device != devices[i]) + continue; + + current_idx = i; + break; + } + + current_device = devices + [(current_idx + types - 1) % types]; + + input_config_set_device(port, current_device); + + pad.port = port; + pad.device = current_device; + + core_set_controller_port_device(&pad); + + return 0; +} + +int setting_action_left_bind_device(void *data, bool wraparound) +{ + unsigned *p = NULL; + unsigned index_offset = 0; + unsigned max_devices = input_config_get_device_count(); + rarch_setting_t *setting = (rarch_setting_t*)data; + settings_t *settings = config_get_ptr(); + + if (!setting || max_devices == 0) + return -1; + + index_offset = setting->index_offset; + + p = &settings->uints.input_joypad_map[index_offset]; + + if ((*p) >= max_devices) + *p = max_devices - 1; + else if ((*p) > 0) + (*p)--; + + return 0; +} + +int setting_action_left_mouse_index(void *data, bool wraparound) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + settings_t *settings = config_get_ptr(); + + if (!setting) + return -1; + + if (settings->uints.input_mouse_index[setting->index_offset]) + { + --settings->uints.input_mouse_index[setting->index_offset]; + settings->modified = true; + } + + return 0; +} + +int setting_uint_action_left_custom_viewport_width( + void *data, bool wraparound) +{ + video_viewport_t vp; + struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); + video_viewport_t *custom = video_viewport_get_custom(); + settings_t *settings = config_get_ptr(); + struct retro_game_geometry *geom = (struct retro_game_geometry*) + &av_info->geometry; + + if (!settings || !av_info) + return -1; + + video_driver_get_viewport_info(&vp); + + if (custom->width <= 1) + custom->width = 1; + else if (settings->bools.video_scale_integer) + { + if (custom->width > geom->base_width) + custom->width -= geom->base_width; + } + else + custom->width -= 1; + + aspectratio_lut[ASPECT_RATIO_CUSTOM].value = + (float)custom->width / custom->height; + + return 0; +} + +int setting_uint_action_left_custom_viewport_height( + void *data, bool wraparound) +{ + video_viewport_t vp; + struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); + video_viewport_t *custom = video_viewport_get_custom(); + settings_t *settings = config_get_ptr(); + struct retro_game_geometry *geom = (struct retro_game_geometry*) + &av_info->geometry; + + if (!settings || !av_info) + return -1; + + video_driver_get_viewport_info(&vp); + + if (custom->height <= 1) + custom->height = 1; + else if (settings->bools.video_scale_integer) + { + if (custom->height > geom->base_height) + custom->height -= geom->base_height; + } + else + custom->height -= 1; + + aspectratio_lut[ASPECT_RATIO_CUSTOM].value = + (float)custom->width / custom->height; + + return 0; +} + +int setting_string_action_left_audio_device( + void *data, bool wraparound) +{ +#if !defined(RARCH_CONSOLE) + int audio_device_index; + struct string_list *ptr = NULL; + rarch_setting_t *setting = (rarch_setting_t*)data; + + if (!audio_driver_get_devices_list((void**)&ptr)) + return -1; + + if (!ptr) + return -1; + + /* Get index in the string list */ + audio_device_index = string_list_find_elem( + ptr, setting->value.target.string) - 1; + audio_device_index--; + + /* Reset index if needed */ + if (audio_device_index < 0) + audio_device_index = (int)(ptr->size - 1); + + strlcpy(setting->value.target.string, ptr->elems[audio_device_index].data, setting->size); +#endif + + return 0; +} + +int setting_string_action_left_driver(void *data, + bool wraparound) +{ + driver_ctx_info_t drv; + rarch_setting_t *setting = (rarch_setting_t*)data; + + if (!setting) + return -1; + + drv.label = setting->name; + drv.s = setting->value.target.string; + drv.len = setting->size; + + if (!driver_ctl(RARCH_DRIVER_CTL_FIND_PREV, &drv)) + { + settings_t *settings = config_get_ptr(); + + if (settings && settings->bools.menu_navigation_wraparound_enable) + { + drv.label = setting->name; + drv.s = setting->value.target.string; + drv.len = setting->size; + driver_ctl(RARCH_DRIVER_CTL_FIND_LAST, &drv); + } + } + + if (setting->change_handler) + setting->change_handler(setting); + + return 0; +} static int generic_shader_action_parameter_left( struct video_shader_parameter *param, @@ -82,6 +333,23 @@ static int shader_action_parameter_left(unsigned type, const char *label, bool w return ret; } +static int audio_mixer_stream_volume_left(unsigned type, const char *label, + bool wraparound) +{ + unsigned offset = (type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN); + float orig_volume = 0.0f; + + if (offset >= AUDIO_MIXER_MAX_STREAMS) + return 0; + + orig_volume = audio_driver_mixer_get_stream_volume(offset); + orig_volume = orig_volume - 1.00f; + + audio_driver_mixer_set_stream_volume(offset, orig_volume); + + return 0; +} + static int action_left_cheat(unsigned type, const char *label, bool wraparound) { @@ -91,38 +359,59 @@ static int action_left_cheat(unsigned type, const char *label, } static int action_left_input_desc(unsigned type, const char *label, - bool wraparound) + bool wraparound) { - unsigned inp_desc_index_offset = type - - MENU_SETTINGS_INPUT_DESC_BEGIN; - unsigned inp_desc_user = inp_desc_index_offset / - (RARCH_FIRST_CUSTOM_BIND + 4); - unsigned inp_desc_button_index_offset = inp_desc_index_offset - - (inp_desc_user * (RARCH_FIRST_CUSTOM_BIND + 4)); + rarch_system_info_t *system = runloop_get_system_info(); settings_t *settings = config_get_ptr(); + unsigned btn_idx, user_idx, remap_idx; - if (settings->uints.input_remap_ids[inp_desc_user][inp_desc_button_index_offset] > 0) - settings->uints.input_remap_ids[inp_desc_user][inp_desc_button_index_offset]--; + if (!settings || !system) + return 0; + + user_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8); + btn_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx; + + if (settings->uints.input_remap_ids[user_idx][btn_idx] == RARCH_UNMAPPED) + settings->uints.input_remap_ids[user_idx][btn_idx] = RARCH_CUSTOM_BIND_LIST_END - 1; + + if (settings->uints.input_remap_ids[user_idx][btn_idx] > 0) + settings->uints.input_remap_ids[user_idx][btn_idx]--; + else if (settings->uints.input_remap_ids[user_idx][btn_idx] == 0) + settings->uints.input_remap_ids[user_idx][btn_idx] = RARCH_UNMAPPED; + else + settings->uints.input_remap_ids[user_idx][btn_idx] = RARCH_CUSTOM_BIND_LIST_END - 1; + + remap_idx = settings->uints.input_remap_ids[user_idx][btn_idx]; + + /* skip the not used buttons (unless they are at the end by calling the right desc function recursively + also skip all the axes until analog remapping is implemented */ + if ((string_is_empty(system->input_desc_btn[user_idx][remap_idx]) && remap_idx < RARCH_CUSTOM_BIND_LIST_END) /*|| + (remap_idx >= RARCH_FIRST_CUSTOM_BIND && remap_idx < RARCH_CUSTOM_BIND_LIST_END)*/) + action_left_input_desc(type, label, wraparound); return 0; } -#ifdef HAVE_KEYMAPPER static int action_left_input_desc_kbd(unsigned type, const char *label, bool wraparound) { - char desc[PATH_MAX_LENGTH]; - unsigned key_id; unsigned remap_id; - unsigned offset = type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN; + unsigned key_id, id, offset; settings_t *settings = config_get_ptr(); if (!settings) return 0; - remap_id = settings->uints.input_keymapper_ids[offset]; + offset = type / ((MENU_SETTINGS_INPUT_DESC_KBD_END - + (MENU_SETTINGS_INPUT_DESC_KBD_END - + MENU_SETTINGS_INPUT_DESC_KBD_BEGIN))) - 1; - for (key_id = 0; key_id < MENU_SETTINGS_INPUT_DESC_KBD_END - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN; key_id++) + id = (type / (offset + 1)) - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN; + + remap_id = + settings->uints.input_keymapper_ids[offset][id]; + + for (key_id = 0; key_id < RARCH_MAX_KEYS - 1; key_id++) { if(remap_id == key_descriptors[key_id].key) break; @@ -131,13 +420,12 @@ static int action_left_input_desc_kbd(unsigned type, const char *label, if (key_id > 0) key_id--; else - key_id = MENU_SETTINGS_INPUT_DESC_KBD_END - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN; + key_id = (RARCH_MAX_KEYS - 1) + MENU_SETTINGS_INPUT_DESC_KBD_BEGIN; - settings->uints.input_keymapper_ids[offset] = key_descriptors[key_id].key; + settings->uints.input_keymapper_ids[offset][id] = key_descriptors[key_id].key; return 0; } -#endif static int action_left_scroll(unsigned type, const char *label, bool wraparound) @@ -594,6 +882,11 @@ static int menu_cbs_init_bind_left_compare_type(menu_file_list_cbs_t *cbs, { BIND_ACTION_LEFT(cbs, action_left_cheat); } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_END) + { + BIND_ACTION_LEFT(cbs, audio_mixer_stream_volume_left); + } else if (type >= MENU_SETTINGS_SHADER_PARAMETER_0 && type <= MENU_SETTINGS_SHADER_PARAMETER_LAST) { @@ -609,13 +902,11 @@ static int menu_cbs_init_bind_left_compare_type(menu_file_list_cbs_t *cbs, { BIND_ACTION_LEFT(cbs, action_left_input_desc); } -#ifdef HAVE_KEYMAPPER else if (type >= MENU_SETTINGS_INPUT_DESC_KBD_BEGIN && type <= MENU_SETTINGS_INPUT_DESC_KBD_END) { BIND_ACTION_LEFT(cbs, action_left_input_desc_kbd); } -#endif else if ((type >= MENU_SETTINGS_PLAYLIST_ASSOCIATION_START)) { BIND_ACTION_LEFT(cbs, playlist_association_left); diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 3f1915decc..13bc35f1a5 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -26,17 +26,26 @@ #include "../../config.h" #endif +#include "../../config.def.h" +#include "../../config.def.keybinds.h" +#include "../../wifi/wifi_driver.h" +#include "../../driver.h" + #include "../menu_driver.h" #include "../menu_cbs.h" #include "../menu_setting.h" #include "../menu_shader.h" #include "../widgets/menu_dialog.h" +#include "../widgets/menu_entry.h" #include "../widgets/menu_filebrowser.h" #include "../widgets/menu_input_dialog.h" +#include "../widgets/menu_input_bind_dialog.h" +#include "../menu_input.h" #include "../menu_networking.h" #include "../menu_content.h" #include "../menu_shader.h" +#include "../../audio/audio_driver.h" #include "../../core.h" #include "../../configuration.h" #include "../../core_info.h" @@ -121,14 +130,132 @@ static char *lakka_get_project(void) info.enum_idx = a; \ dl_type = b; +int setting_action_ok_video_refresh_rate_auto(void *data, bool wraparound) +{ + double video_refresh_rate = 0.0; + double deviation = 0.0; + unsigned sample_points = 0; + rarch_setting_t *setting = (rarch_setting_t*)data; + + if (!setting) + return -1; + + if (video_monitor_fps_statistics(&video_refresh_rate, + &deviation, &sample_points)) + { + float video_refresh_rate_float = (float)video_refresh_rate; + driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &video_refresh_rate_float); + /* Incase refresh rate update forced non-block video. */ + command_event(CMD_EVENT_VIDEO_SET_BLOCKING_STATE, NULL); + } + + if (setting_generic_action_ok_default(setting, wraparound) != 0) + return -1; + + return 0; +} + +int setting_action_ok_video_refresh_rate_polled(void *data, bool wraparound) +{ + rarch_setting_t *setting = (rarch_setting_t*)data; + float refresh_rate = 0.0; + + if (!setting) + return -1; + + if ((refresh_rate = video_driver_get_refresh_rate()) == 0.0) + return -1; + + driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &refresh_rate); + /* Incase refresh rate update forced non-block video. */ + command_event(CMD_EVENT_VIDEO_SET_BLOCKING_STATE, NULL); + + if (setting_generic_action_ok_default(setting, wraparound) != 0) + return -1; + + return 0; +} + +int setting_action_ok_bind_all(void *data, bool wraparound) +{ + (void)wraparound; + if (!menu_input_key_bind_set_mode(MENU_INPUT_BINDS_CTL_BIND_ALL, data)) + return -1; + return 0; +} + +int setting_action_ok_bind_all_save_autoconfig(void *data, + bool wraparound) +{ + unsigned index_offset; + rarch_setting_t *setting = (rarch_setting_t*)data; + const char *name = NULL; + + (void)wraparound; + + if (!setting) + return -1; + + index_offset = setting->index_offset; + name = input_config_get_device_name(index_offset); + + if(!string_is_empty(name) && config_save_autoconf_profile(name, index_offset)) + runloop_msg_queue_push( + msg_hash_to_str(MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY), 1, 100, true); + else + runloop_msg_queue_push( + msg_hash_to_str(MSG_AUTOCONFIG_FILE_ERROR_SAVING), 1, 100, true); + + + return 0; +} + +int setting_action_ok_bind_defaults(void *data, bool wraparound) +{ + unsigned i; + menu_input_ctx_bind_limits_t lim; + struct retro_keybind *target = NULL; + const struct retro_keybind *def_binds = NULL; + rarch_setting_t *setting = (rarch_setting_t*)data; + + (void)wraparound; + + if (!setting) + return -1; + + target = &input_config_binds[setting->index_offset][0]; + def_binds = (setting->index_offset) ? + retro_keybinds_rest : retro_keybinds_1; + + lim.min = MENU_SETTINGS_BIND_BEGIN; + lim.max = MENU_SETTINGS_BIND_LAST; + + menu_input_key_bind_set_min_max(&lim); + + for (i = MENU_SETTINGS_BIND_BEGIN; + i <= MENU_SETTINGS_BIND_LAST; i++, target++) + { + target->key = def_binds[i - MENU_SETTINGS_BIND_BEGIN].key; + target->joykey = NO_BTN; + target->joyaxis = AXIS_NONE; + target->mbutton = NO_BTN; + } + + return 0; +} + static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl) { switch (lbl) { + case ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST: + return MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST; case ACTION_OK_DL_ACCOUNTS_LIST: return MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_LIST; case ACTION_OK_DL_INPUT_SETTINGS_LIST: return MENU_ENUM_LABEL_DEFERRED_INPUT_SETTINGS_LIST; + case ACTION_OK_DL_LATENCY_SETTINGS_LIST: + return MENU_ENUM_LABEL_DEFERRED_LATENCY_SETTINGS_LIST; case ACTION_OK_DL_DRIVER_SETTINGS_LIST: return MENU_ENUM_LABEL_DEFERRED_DRIVER_SETTINGS_LIST; case ACTION_OK_DL_CORE_SETTINGS_LIST: @@ -157,6 +284,8 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl) return MENU_ENUM_LABEL_DEFERRED_MENU_VIEWS_SETTINGS_LIST; case ACTION_OK_DL_QUICK_MENU_VIEWS_SETTINGS_LIST: return MENU_ENUM_LABEL_DEFERRED_QUICK_MENU_VIEWS_SETTINGS_LIST; + case ACTION_OK_DL_QUICK_MENU_OVERRIDE_OPTIONS_LIST: + return MENU_ENUM_LABEL_DEFERRED_QUICK_MENU_OVERRIDE_OPTIONS; case ACTION_OK_DL_USER_INTERFACE_SETTINGS_LIST: return MENU_ENUM_LABEL_DEFERRED_USER_INTERFACE_SETTINGS_LIST; case ACTION_OK_DL_MENU_FILE_BROWSER_SETTINGS_LIST: @@ -183,6 +312,8 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl) return MENU_ENUM_LABEL_DEFERRED_PRIVACY_SETTINGS_LIST; case ACTION_OK_DL_AUDIO_SETTINGS_LIST: return MENU_ENUM_LABEL_DEFERRED_AUDIO_SETTINGS_LIST; + case ACTION_OK_DL_AUDIO_MIXER_SETTINGS_LIST: + return MENU_ENUM_LABEL_DEFERRED_AUDIO_MIXER_SETTINGS_LIST; case ACTION_OK_DL_INPUT_HOTKEY_BINDS_LIST: return MENU_ENUM_LABEL_DEFERRED_INPUT_HOTKEY_BINDS_LIST; case ACTION_OK_DL_RECORDING_SETTINGS_LIST: @@ -665,7 +796,7 @@ int generic_action_ok_displaylist_push(const char *path, break; case ACTION_OK_DL_DEFERRED_CORE_LIST_SET: info.directory_ptr = idx; - menu->rdb_entry_start_game_selection_ptr = (unsigned)idx; + menu->scratchpad.unsigned_var = (unsigned)idx; info_path = settings->paths.directory_libretro; info_label = msg_hash_to_str( @@ -674,8 +805,10 @@ int generic_action_ok_displaylist_push(const char *path, MENU_ENUM_LABEL_DEFERRED_CORE_LIST_SET; dl_type = DISPLAYLIST_GENERIC; break; + case ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST: case ACTION_OK_DL_ACCOUNTS_LIST: case ACTION_OK_DL_INPUT_SETTINGS_LIST: + case ACTION_OK_DL_LATENCY_SETTINGS_LIST: case ACTION_OK_DL_DRIVER_SETTINGS_LIST: case ACTION_OK_DL_CORE_SETTINGS_LIST: case ACTION_OK_DL_VIDEO_SETTINGS_LIST: @@ -690,6 +823,7 @@ int generic_action_ok_displaylist_push(const char *path, case ACTION_OK_DL_MENU_SETTINGS_LIST: case ACTION_OK_DL_MENU_VIEWS_SETTINGS_LIST: case ACTION_OK_DL_QUICK_MENU_VIEWS_SETTINGS_LIST: + case ACTION_OK_DL_QUICK_MENU_OVERRIDE_OPTIONS_LIST: case ACTION_OK_DL_USER_INTERFACE_SETTINGS_LIST: case ACTION_OK_DL_MENU_FILE_BROWSER_SETTINGS_LIST: case ACTION_OK_DL_RETRO_ACHIEVEMENTS_SETTINGS_LIST: @@ -703,6 +837,7 @@ int generic_action_ok_displaylist_push(const char *path, case ACTION_OK_DL_DIRECTORY_SETTINGS_LIST: case ACTION_OK_DL_PRIVACY_SETTINGS_LIST: case ACTION_OK_DL_AUDIO_SETTINGS_LIST: + case ACTION_OK_DL_AUDIO_MIXER_SETTINGS_LIST: case ACTION_OK_DL_INPUT_HOTKEY_BINDS_LIST: case ACTION_OK_DL_RECORDING_SETTINGS_LIST: case ACTION_OK_DL_PLAYLIST_SETTINGS_LIST: @@ -726,6 +861,20 @@ int generic_action_ok_displaylist_push(const char *path, break; } + /* second pass */ + + switch (action_type) + { + case ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST: + { + unsigned player_no = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_BEGIN; + info.type = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_BEGIN + player_no; + } + break; + default: + break; + } + if (info_label) info.label = strdup(info_label); if (info_path) @@ -882,7 +1031,9 @@ static void content_add_to_playlist(const char *path) task_push_dbscan( settings->paths.directory_playlist, settings->paths.path_content_database, - path, false, handle_dbscan_finished); + path, false, + settings->bools.show_hidden_files, + handle_dbscan_finished); #endif } @@ -1150,7 +1301,7 @@ static int generic_action_ok(const char *path, case ACTION_OK_LOAD_SHADER_PASS: { struct video_shader *shader = menu_shader_get(); - struct video_shader_pass *shader_pass = shader ? &shader->pass[(unsigned)menu->hack_shader_pass] : NULL; + struct video_shader_pass *shader_pass = shader ? &shader->pass[menu->scratchpad.unsigned_var] : NULL; flush_char = msg_hash_to_str((enum msg_hash_enums)flush_id); if (shader_pass) @@ -1388,9 +1539,8 @@ static int action_ok_playlist_entry_collection(const char *path, if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); - new_core_path[0] = '\0'; - - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &tmp_playlist); + new_core_path[0] = '\0'; + tmp_playlist = playlist_get_cached(); if (!tmp_playlist) { @@ -1437,17 +1587,18 @@ static int action_ok_playlist_entry_collection(const char *path, return ret; } - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &tmp_playlist); + tmp_playlist = playlist_get_cached(); - command_playlist_update_write( - tmp_playlist, - selection_ptr, - NULL, - NULL, - new_core_path, - core_info.inf->display_name, - NULL, - NULL); + if (tmp_playlist) + command_playlist_update_write( + tmp_playlist, + selection_ptr, + NULL, + NULL, + new_core_path, + core_info.inf->display_name, + NULL, + NULL); } else strlcpy(new_core_path, core_path, sizeof(new_core_path)); @@ -1547,32 +1698,18 @@ static int action_ok_playlist_entry_start_content(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { size_t selection_ptr = 0; - bool playlist_initialized = false; - playlist_t *playlist = NULL; const char *entry_path = NULL; const char *entry_label = NULL; const char *core_path = NULL; const char *core_name = NULL; - playlist_t *tmp_playlist = NULL; menu_handle_t *menu = NULL; + playlist_t *playlist = playlist_get_cached(); - if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) + if ( !playlist || + !menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &tmp_playlist); - - if (!tmp_playlist) - { - tmp_playlist = playlist_init( - menu->db_playlist_file, COLLECTION_SIZE); - - if (!tmp_playlist) - return menu_cbs_exit(); - playlist_initialized = true; - } - - playlist = tmp_playlist; - selection_ptr = menu->rdb_entry_start_game_selection_ptr; + selection_ptr = menu->scratchpad.unsigned_var; playlist_get_index(playlist, selection_ptr, &entry_path, &entry_label, &core_path, &core_name, NULL, NULL); @@ -1599,21 +1736,16 @@ 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 + * the inner or outer entry_path. */ + /* TODO: make sure there's only one entry_path + * in this function. */ if (!found_associated_core) - { - /* TODO: figure out if this should refer to the inner or outer entry_path */ - /* TODO: make sure there's only one entry_path in this function */ - int ret = action_ok_file_load_with_detect_core(entry_path, + return action_ok_file_load_with_detect_core(entry_path, label, type, selection_ptr, entry_idx); - if (playlist_initialized) - playlist_free(tmp_playlist); - return ret; - } - - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &tmp_playlist); command_playlist_update_write( - tmp_playlist, + playlist, selection_ptr, NULL, NULL, @@ -1621,10 +1753,9 @@ static int action_ok_playlist_entry_start_content(const char *path, core_info.inf->display_name, NULL, NULL); - } - if (!playlist || !menu_content_playlist_load(playlist, selection_ptr)) + if (!menu_content_playlist_load(playlist, selection_ptr)) { runloop_msg_queue_push("File could not be loaded from playlist.\n", 1, 100, true); goto error; @@ -1636,11 +1767,109 @@ static int action_ok_playlist_entry_start_content(const char *path, return default_action_ok_load_content_from_playlist_from_menu(core_path, path, entry_label); error: - if (playlist_initialized) - playlist_free(tmp_playlist); return menu_cbs_exit(); } +static int action_ok_mixer_stream_action_play(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + unsigned stream_id = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN; + enum audio_mixer_state state = audio_driver_mixer_get_stream_state(stream_id); + + switch (state) + { + case AUDIO_STREAM_STATE_STOPPED: + audio_driver_mixer_play_stream(stream_id); + break; + case AUDIO_STREAM_STATE_PLAYING: + case AUDIO_STREAM_STATE_PLAYING_LOOPED: + case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL: + case AUDIO_STREAM_STATE_NONE: + break; + } + return 0; +} + +static int action_ok_mixer_stream_action_play_looped(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + unsigned stream_id = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN; + enum audio_mixer_state state = audio_driver_mixer_get_stream_state(stream_id); + + switch (state) + { + case AUDIO_STREAM_STATE_STOPPED: + audio_driver_mixer_play_stream_looped(stream_id); + break; + case AUDIO_STREAM_STATE_PLAYING: + case AUDIO_STREAM_STATE_PLAYING_LOOPED: + case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL: + case AUDIO_STREAM_STATE_NONE: + break; + } + return 0; +} + +static int action_ok_mixer_stream_action_play_sequential(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + unsigned stream_id = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_SEQUENTIAL_BEGIN; + enum audio_mixer_state state = audio_driver_mixer_get_stream_state(stream_id); + + switch (state) + { + case AUDIO_STREAM_STATE_STOPPED: + audio_driver_mixer_play_stream_sequential(stream_id); + break; + case AUDIO_STREAM_STATE_PLAYING: + case AUDIO_STREAM_STATE_PLAYING_LOOPED: + case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL: + case AUDIO_STREAM_STATE_NONE: + break; + } + return 0; +} + +static int action_ok_mixer_stream_action_remove(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + unsigned stream_id = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_BEGIN; + enum audio_mixer_state state = audio_driver_mixer_get_stream_state(stream_id); + + switch (state) + { + case AUDIO_STREAM_STATE_PLAYING: + case AUDIO_STREAM_STATE_PLAYING_LOOPED: + case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL: + case AUDIO_STREAM_STATE_STOPPED: + audio_driver_mixer_remove_stream(stream_id); + break; + case AUDIO_STREAM_STATE_NONE: + break; + } + return 0; +} + +static int action_ok_mixer_stream_action_stop(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + unsigned stream_id = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_BEGIN; + enum audio_mixer_state state = audio_driver_mixer_get_stream_state(stream_id); + + switch (state) + { + case AUDIO_STREAM_STATE_PLAYING: + case AUDIO_STREAM_STATE_PLAYING_LOOPED: + case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL: + audio_driver_mixer_stop_stream(stream_id); + break; + case AUDIO_STREAM_STATE_STOPPED: + case AUDIO_STREAM_STATE_NONE: + break; + } + return 0; +} + static int action_ok_lookup_setting(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { @@ -1651,8 +1880,7 @@ static int action_ok_audio_add_to_mixer(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { const char *entry_path = NULL; - playlist_t *tmp_playlist = NULL; - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &tmp_playlist); + playlist_t *tmp_playlist = playlist_get_cached(); if (!tmp_playlist) return -1; @@ -1667,6 +1895,25 @@ static int action_ok_audio_add_to_mixer(const char *path, return 0; } +static int action_ok_audio_add_to_mixer_and_play(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + const char *entry_path = NULL; + playlist_t *tmp_playlist = playlist_get_cached(); + + if (!tmp_playlist) + return -1; + + playlist_get_index(tmp_playlist, entry_idx, + &entry_path, NULL, NULL, NULL, NULL, NULL); + + if (filestream_exists(entry_path)) + task_push_audio_mixer_load_and_play(entry_path, + NULL, NULL); + + return 0; +} + static int action_ok_audio_add_to_mixer_and_collection(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { @@ -1695,6 +1942,34 @@ static int action_ok_audio_add_to_mixer_and_collection(const char *path, return 0; } +static int action_ok_audio_add_to_mixer_and_collection_and_play(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + char combined_path[PATH_MAX_LENGTH]; + menu_handle_t *menu = NULL; + + combined_path[0] = '\0'; + + if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) + return menu_cbs_exit(); + + fill_pathname_join(combined_path, menu->scratch2_buf, + menu->scratch_buf, sizeof(combined_path)); + + command_playlist_push_write( + g_defaults.music_history, + combined_path, + NULL, + "builtin", + "musicplayer"); + + if (filestream_exists(combined_path)) + task_push_audio_mixer_load_and_play(combined_path, + NULL, NULL); + + return 0; +} + static int action_ok_menu_wallpaper(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { @@ -1889,12 +2164,12 @@ static void menu_input_st_string_cb_cheat_file_save_as( menu_input_dialog_end(); } -#define default_action_dialog_start(funcname, _label_setting, _idx, _cb) \ -static int (funcname)(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) \ +#define default_action_dialog_start(funcname, _label, _idx, _cb) \ +static int (funcname)(const char *path, const char *label_setting, unsigned type, size_t idx, size_t entry_idx) \ { \ menu_input_ctx_line_t line; \ - line.label = label; \ - line.label_setting = _label_setting; \ + line.label = _label; \ + line.label_setting = label_setting; \ line.type = type; \ line.idx = (_idx); \ line.cb = _cb; \ @@ -2165,20 +2440,31 @@ static int action_ok_path_scan_directory(const char *path, static int action_ok_core_deferred_set(const char *new_core_path, const char *content_label, unsigned type, size_t idx, size_t entry_idx) { + char ext_name[255]; char core_display_name[PATH_MAX_LENGTH]; + settings_t *settings = config_get_ptr(); menu_handle_t *menu = NULL; size_t selection = menu_navigation_get_selection(); + ext_name[0] = '\0'; + if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); + if (!frontend_driver_get_core_extension(ext_name, sizeof(ext_name))) + return menu_cbs_exit(); + core_display_name[0] = '\0'; core_info_get_name(new_core_path, - core_display_name, sizeof(core_display_name)); + core_display_name, sizeof(core_display_name), + settings->paths.path_libretro_info, + settings->paths.directory_libretro, + ext_name, + settings->bools.show_hidden_files); command_playlist_update_write( NULL, - menu->rdb_entry_start_game_selection_ptr, + menu->scratchpad.unsigned_var, NULL, content_label, new_core_path, @@ -2872,16 +3158,13 @@ static int action_ok_reset_core_association(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { const char *tmp_path = NULL; - playlist_t *tmp_playlist = NULL; menu_handle_t *menu = NULL; - - if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) - return menu_cbs_exit(); - - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &tmp_playlist); + playlist_t *tmp_playlist = playlist_get_cached(); if (!tmp_playlist) return 0; + if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) + return menu_cbs_exit(); playlist_get_index(tmp_playlist, menu->rpl_entry_selection_ptr, @@ -2906,16 +3189,13 @@ static int action_ok_add_to_favorites_playlist(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { const char *tmp_path = NULL; - playlist_t *tmp_playlist = NULL; menu_handle_t *menu = NULL; - - if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) - return menu_cbs_exit(); - - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &tmp_playlist); + playlist_t *tmp_playlist = playlist_get_cached(); if (!tmp_playlist) return 0; + if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) + return menu_cbs_exit(); playlist_get_index(tmp_playlist, menu->rpl_entry_selection_ptr, &tmp_path, @@ -2931,7 +3211,6 @@ static int action_ok_delete_entry(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { size_t new_selection_ptr; - playlist_t *playlist = NULL; char *conf_path = NULL; char *def_conf_path = NULL; char *def_conf_music_path = NULL; @@ -2942,12 +3221,11 @@ static int action_ok_delete_entry(const char *path, char *def_conf_img_path = NULL; #endif menu_handle_t *menu = NULL; + playlist_t *playlist = playlist_get_cached(); if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &playlist); - conf_path = playlist_get_conf_path(playlist); def_conf_path = playlist_get_conf_path(g_defaults.content_history); def_conf_music_path = playlist_get_conf_path(g_defaults.music_history); @@ -3081,6 +3359,7 @@ default_action_ok_func(action_ok_onscreen_display_list, ACTION_OK_DL_ONSCREEN_DI default_action_ok_func(action_ok_onscreen_notifications_list, ACTION_OK_DL_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST) default_action_ok_func(action_ok_onscreen_overlay_list, ACTION_OK_DL_ONSCREEN_OVERLAY_SETTINGS_LIST) default_action_ok_func(action_ok_menu_list, ACTION_OK_DL_MENU_SETTINGS_LIST) +default_action_ok_func(action_ok_quick_menu_override_options, ACTION_OK_DL_QUICK_MENU_OVERRIDE_OPTIONS_LIST) default_action_ok_func(action_ok_menu_views_list, ACTION_OK_DL_MENU_VIEWS_SETTINGS_LIST) default_action_ok_func(action_ok_quick_menu_views_list, ACTION_OK_DL_QUICK_MENU_VIEWS_SETTINGS_LIST) default_action_ok_func(action_ok_user_interface_list, ACTION_OK_DL_USER_INTERFACE_SETTINGS_LIST) @@ -3093,6 +3372,7 @@ default_action_ok_func(action_ok_netplay_sublist, ACTION_OK_DL_NETPLAY) default_action_ok_func(action_ok_directory_list, ACTION_OK_DL_DIRECTORY_SETTINGS_LIST) default_action_ok_func(action_ok_privacy_list, ACTION_OK_DL_PRIVACY_SETTINGS_LIST) default_action_ok_func(action_ok_rdb_entry, ACTION_OK_DL_RDB_ENTRY) +default_action_ok_func(action_ok_mixer_stream_actions, ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST) default_action_ok_func(action_ok_browse_url_list, ACTION_OK_DL_BROWSE_URL_LIST) default_action_ok_func(action_ok_core_list, ACTION_OK_DL_CORE_LIST) default_action_ok_func(action_ok_cheat_file, ACTION_OK_DL_CHEAT_FILE) @@ -3114,7 +3394,9 @@ default_action_ok_func(action_ok_push_video_settings_list, ACTION_OK_DL_VIDEO_SE default_action_ok_func(action_ok_push_configuration_settings_list, ACTION_OK_DL_CONFIGURATION_SETTINGS_LIST) default_action_ok_func(action_ok_push_core_settings_list, ACTION_OK_DL_CORE_SETTINGS_LIST) default_action_ok_func(action_ok_push_audio_settings_list, ACTION_OK_DL_AUDIO_SETTINGS_LIST) +default_action_ok_func(action_ok_push_audio_mixer_settings_list, ACTION_OK_DL_AUDIO_MIXER_SETTINGS_LIST) default_action_ok_func(action_ok_push_input_settings_list, ACTION_OK_DL_INPUT_SETTINGS_LIST) +default_action_ok_func(action_ok_push_latency_settings_list, ACTION_OK_DL_LATENCY_SETTINGS_LIST) default_action_ok_func(action_ok_push_recording_settings_list, ACTION_OK_DL_RECORDING_SETTINGS_LIST) default_action_ok_func(action_ok_push_playlist_settings_list, ACTION_OK_DL_PLAYLIST_SETTINGS_LIST) default_action_ok_func(action_ok_push_input_hotkey_binds_list, ACTION_OK_DL_INPUT_HOTKEY_BINDS_LIST) @@ -3130,7 +3412,7 @@ static int action_ok_shader_pass(const char *path, if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); - menu->hack_shader_pass = type - MENU_SETTINGS_SHADER_PASS_0; + menu->scratchpad.unsigned_var = type - MENU_SETTINGS_SHADER_PASS_0; return generic_action_ok_displaylist_push(path, NULL, label, type, idx, entry_idx, ACTION_OK_DL_SHADER_PASS); } @@ -3933,9 +4215,15 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION: BIND_ACTION_OK(cbs, action_ok_audio_add_to_mixer_and_collection); break; + case MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY: + BIND_ACTION_OK(cbs, action_ok_audio_add_to_mixer_and_collection_and_play); + break; case MENU_ENUM_LABEL_ADD_TO_MIXER: BIND_ACTION_OK(cbs, action_ok_audio_add_to_mixer); break; + case MENU_ENUM_LABEL_ADD_TO_MIXER_AND_PLAY: + BIND_ACTION_OK(cbs, action_ok_audio_add_to_mixer_and_play); + break; case MENU_ENUM_LABEL_MENU_WALLPAPER: BIND_ACTION_OK(cbs, action_ok_menu_wallpaper); break; @@ -4114,6 +4402,12 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_AUDIO_SETTINGS: BIND_ACTION_OK(cbs, action_ok_push_audio_settings_list); break; + case MENU_ENUM_LABEL_AUDIO_MIXER_SETTINGS: + BIND_ACTION_OK(cbs, action_ok_push_audio_mixer_settings_list); + break; + case MENU_ENUM_LABEL_LATENCY_SETTINGS: + BIND_ACTION_OK(cbs, action_ok_push_latency_settings_list); + break; case MENU_ENUM_LABEL_CORE_SETTINGS: BIND_ACTION_OK(cbs, action_ok_push_core_settings_list); break; @@ -4271,6 +4565,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_MENU_VIEWS_SETTINGS: BIND_ACTION_OK(cbs, action_ok_menu_views_list); break; + case MENU_ENUM_LABEL_QUICK_MENU_OVERRIDE_OPTIONS: + BIND_ACTION_OK(cbs, action_ok_quick_menu_override_options); + break; case MENU_ENUM_LABEL_QUICK_MENU_VIEWS_SETTINGS: BIND_ACTION_OK(cbs, action_ok_quick_menu_views_list); break; @@ -4457,6 +4754,36 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, { BIND_ACTION_OK(cbs, action_ok_lookup_setting); } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_END) + { + BIND_ACTION_OK(cbs, action_ok_mixer_stream_action_play); + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_END) + { + BIND_ACTION_OK(cbs, action_ok_mixer_stream_action_play_looped); + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_SEQUENTIAL_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_SEQUENTIAL_END) + { + BIND_ACTION_OK(cbs, action_ok_mixer_stream_action_play_sequential); + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_END) + { + BIND_ACTION_OK(cbs, action_ok_mixer_stream_action_remove); + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_END) + { + BIND_ACTION_OK(cbs, action_ok_mixer_stream_action_stop); + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_END) + { + BIND_ACTION_OK(cbs, action_ok_mixer_stream_actions); + } else if (type >= MENU_SETTINGS_SHADER_PARAMETER_0 && type <= MENU_SETTINGS_SHADER_PARAMETER_LAST) { diff --git a/menu/cbs/menu_cbs_right.c b/menu/cbs/menu_cbs_right.c index 9469cbc98b..9d3b8ab9a5 100644 --- a/menu/cbs/menu_cbs_right.c +++ b/menu/cbs/menu_cbs_right.c @@ -30,6 +30,7 @@ #include "../menu_setting.h" #include "../menu_shader.h" +#include "../../audio/audio_driver.h" #include "../../configuration.h" #include "../../core.h" #include "../../core_info.h" @@ -48,7 +49,7 @@ } while(0) #endif -extern struct key_desc key_descriptors[MENU_SETTINGS_INPUT_DESC_KBD_END]; +extern struct key_desc key_descriptors[RARCH_MAX_KEYS]; static int generic_shader_action_parameter_right(struct video_shader_parameter *param, unsigned type, const char *label, bool wraparound) @@ -56,8 +57,6 @@ static int generic_shader_action_parameter_right(struct video_shader_parameter * param->current += param->step; param->current = MIN(MAX(param->minimum, param->current), param->maximum); - if (ui_companion_is_on_foreground()) - ui_companion_driver_notify_refresh(); return 0; } @@ -73,7 +72,7 @@ int shader_action_parameter_right(unsigned type, const char *label, bool wraparo video_shader_driver_get_current_shader(&shader_info); param_prev = &shader_info.data->parameters[type - MENU_SETTINGS_SHADER_PARAMETER_0]; - param_menu = shader ? &shader->parameters[type - + param_menu = shader ? &shader->parameters[type - MENU_SETTINGS_SHADER_PARAMETER_0] : NULL; if (!param_prev || !param_menu) @@ -101,58 +100,78 @@ int action_right_cheat(unsigned type, const char *label, wraparound); } -#ifdef HAVE_KEYMAPPER int action_right_input_desc_kbd(unsigned type, const char *label, bool wraparound) { - unsigned key_id; + unsigned key_id, id, offset; unsigned remap_id; - char desc[PATH_MAX_LENGTH]; - unsigned offset = type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN; settings_t *settings = config_get_ptr(); if (!settings) return 0; - remap_id = settings->uints.input_keymapper_ids[offset]; + offset = type / ((MENU_SETTINGS_INPUT_DESC_KBD_END - + (MENU_SETTINGS_INPUT_DESC_KBD_END - + MENU_SETTINGS_INPUT_DESC_KBD_BEGIN))) - 1; - for (key_id = 0; key_id < MENU_SETTINGS_INPUT_DESC_KBD_END - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN; key_id++) + id = (type / (offset + 1)) - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN; + + remap_id = + settings->uints.input_keymapper_ids[offset][id]; + + for (key_id = 0; key_id < RARCH_MAX_KEYS - 1; key_id++) { if(remap_id == key_descriptors[key_id].key) break; } - if (key_id < MENU_SETTINGS_INPUT_DESC_KBD_END - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) + if (key_id < (RARCH_MAX_KEYS - 1) + MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) key_id++; else key_id = 0; - settings->uints.input_keymapper_ids[offset] = key_descriptors[key_id].key; + settings->uints.input_keymapper_ids[offset][id] = key_descriptors[key_id].key; return 0; } -#endif +/* fix-me: incomplete, lacks error checking */ int action_right_input_desc(unsigned type, const char *label, bool wraparound) { -unsigned inp_desc_index_offset = type - MENU_SETTINGS_INPUT_DESC_BEGIN; -unsigned inp_desc_user = inp_desc_index_offset / (RARCH_FIRST_CUSTOM_BIND + 4); -unsigned inp_desc_button_index_offset = inp_desc_index_offset - (inp_desc_user * (RARCH_FIRST_CUSTOM_BIND + 4)); -settings_t *settings = config_get_ptr(); + rarch_system_info_t *system = runloop_get_system_info(); + settings_t *settings = config_get_ptr(); + unsigned btn_idx, user_idx, remap_idx; -if (inp_desc_button_index_offset < RARCH_FIRST_CUSTOM_BIND) -{ - if (settings->uints.input_remap_ids[inp_desc_user][inp_desc_button_index_offset] < RARCH_FIRST_CUSTOM_BIND - 1) - settings->uints.input_remap_ids[inp_desc_user][inp_desc_button_index_offset]++; -} -else -{ - if (settings->uints.input_remap_ids[inp_desc_user][inp_desc_button_index_offset] < 4 - 1) - settings->uints.input_remap_ids[inp_desc_user][inp_desc_button_index_offset]++; -} + if (!settings || !system) + return 0; -return 0; + user_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8); + btn_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx; + + if (settings->uints.input_remap_ids[user_idx][btn_idx] < RARCH_CUSTOM_BIND_LIST_END - 1) + settings->uints.input_remap_ids[user_idx][btn_idx]++; + else if (settings->uints.input_remap_ids[user_idx][btn_idx] == RARCH_CUSTOM_BIND_LIST_END - 1) + settings->uints.input_remap_ids[user_idx][btn_idx] = RARCH_UNMAPPED; + else + settings->uints.input_remap_ids[user_idx][btn_idx] = 0; + + remap_idx = settings->uints.input_remap_ids[user_idx][btn_idx]; + + /* skip the not used buttons (unless they are at the end by calling the right desc function recursively + also skip all the axes until analog remapping is implemented */ + if ((string_is_empty(system->input_desc_btn[user_idx][remap_idx]) && remap_idx < RARCH_CUSTOM_BIND_LIST_END) /*|| + (remap_idx >= RARCH_FIRST_CUSTOM_BIND && remap_idx < RARCH_CUSTOM_BIND_LIST_END)*/) + action_right_input_desc(type, label, wraparound); + +#if 0 + int i = 0; + //RARCH_LOG("[remap-debug] new descriptor for %d: %s\n", remap_idx, system->input_desc_btn[user_idx][remap_idx]); + for (i = 0; i < RARCH_ANALOG_BIND_LIST_END; i++) + RARCH_LOG("[remap-debug]: user %d button %d new id %d\n", user_idx, i, settings->uints.input_remap_ids[user_idx][i]); +#endif + + return 0; } static int action_right_scroll(unsigned type, const char *label, @@ -184,6 +203,24 @@ static int action_right_scroll(unsigned type, const char *label, return 0; } +static int audio_mixer_stream_volume_right(unsigned type, const char *label, + bool wraparound) +{ + unsigned offset = (type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN); + float orig_volume = 0.0f; + + if (offset >= AUDIO_MIXER_MAX_STREAMS) + return 0; + + orig_volume = audio_driver_mixer_get_stream_volume(offset); + orig_volume = orig_volume + 1.00f; + + audio_driver_mixer_set_stream_volume(offset, orig_volume); + + return 0; +} + + static int action_right_goto_tab(void) { menu_ctx_list_t list_info; @@ -191,7 +228,7 @@ static int action_right_goto_tab(void) file_list_t *menu_stack = menu_entries_get_menu_stack_ptr(0); size_t selection = menu_navigation_get_selection(); menu_file_list_cbs_t *cbs = selection_buf ? (menu_file_list_cbs_t*) - file_list_get_actiondata_at_offset(selection_buf, selection) : NULL; + file_list_get_actiondata_at_offset(selection_buf, selection) : NULL; list_info.type = MENU_LIST_HORIZONTAL; list_info.action = MENU_ACTION_RIGHT; @@ -463,6 +500,11 @@ static int menu_cbs_init_bind_right_compare_type(menu_file_list_cbs_t *cbs, { BIND_ACTION_RIGHT(cbs, action_right_cheat); } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_END) + { + BIND_ACTION_RIGHT(cbs, audio_mixer_stream_volume_right); + } else if (type >= MENU_SETTINGS_SHADER_PARAMETER_0 && type <= MENU_SETTINGS_SHADER_PARAMETER_LAST) { @@ -478,13 +520,11 @@ static int menu_cbs_init_bind_right_compare_type(menu_file_list_cbs_t *cbs, { BIND_ACTION_RIGHT(cbs, action_right_input_desc); } -#ifdef HAVE_KEYMAPPER else if (type >= MENU_SETTINGS_INPUT_DESC_KBD_BEGIN && type <= MENU_SETTINGS_INPUT_DESC_KBD_END) { BIND_ACTION_RIGHT(cbs, action_right_input_desc_kbd); } -#endif else if ((type >= MENU_SETTINGS_PLAYLIST_ASSOCIATION_START)) { BIND_ACTION_RIGHT(cbs, playlist_association_right); diff --git a/menu/cbs/menu_cbs_scan.c b/menu/cbs/menu_cbs_scan.c index ed7fc081c1..150f226fa3 100644 --- a/menu/cbs/menu_cbs_scan.c +++ b/menu/cbs/menu_cbs_scan.c @@ -64,7 +64,9 @@ int action_scan_file(const char *path, task_push_dbscan( settings->paths.directory_playlist, settings->paths.path_content_database, - fullpath, false, handle_dbscan_finished); + fullpath, false, + settings->bools.show_hidden_files, + handle_dbscan_finished); return 0; } @@ -90,7 +92,9 @@ int action_scan_directory(const char *path, task_push_dbscan( settings->paths.directory_playlist, settings->paths.path_content_database, - fullpath, true, handle_dbscan_finished); + fullpath, true, + settings->bools.show_hidden_files, + handle_dbscan_finished); return 0; } @@ -104,14 +108,22 @@ int action_switch_thumbnail(const char *path, if (!settings) return -1; - settings->uints.menu_thumbnails++; - - if (settings->uints.menu_thumbnails > 3) - settings->uints.menu_thumbnails = 0; - - menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_PATH, NULL); - menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_IMAGE, NULL); - + if (settings->uints.menu_thumbnails == 0) + { + settings->uints.menu_left_thumbnails++; + if (settings->uints.menu_left_thumbnails > 3) + settings->uints.menu_left_thumbnails = 1; + menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_PATH, NULL); + menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_IMAGE, NULL); + } + else + { + settings->uints.menu_thumbnails++; + if (settings->uints.menu_thumbnails > 3) + settings->uints.menu_thumbnails = 1; + menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_PATH, NULL); + menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_IMAGE, NULL); + } return 0; } diff --git a/menu/cbs/menu_cbs_select.c b/menu/cbs/menu_cbs_select.c index 0246455d0d..7a6bc5e047 100644 --- a/menu/cbs/menu_cbs_select.c +++ b/menu/cbs/menu_cbs_select.c @@ -146,14 +146,12 @@ static int action_select_input_desc(const char *path, const char *label, unsigne return action_right_input_desc(type, label, true); } -#ifdef HAVE_KEYMAPPER static int action_select_input_desc_kbd(const char *path, const char *label, unsigned type, size_t idx) { return action_right_input_desc_kbd(type, label, true); } -#endif #ifdef HAVE_NETWORKING static int action_select_netplay_connect_room(const char *path, @@ -223,13 +221,11 @@ static int menu_cbs_init_bind_select_compare_type( { BIND_ACTION_SELECT(cbs, action_select_input_desc); } -#ifdef HAVE_KEYMAPPER else if (type >= MENU_SETTINGS_INPUT_DESC_KBD_BEGIN && type <= MENU_SETTINGS_INPUT_DESC_KBD_END) { BIND_ACTION_SELECT(cbs, action_select_input_desc_kbd); } -#endif else { diff --git a/menu/cbs/menu_cbs_start.c b/menu/cbs/menu_cbs_start.c index 399c49b490..7917cc9b0d 100644 --- a/menu/cbs/menu_cbs_start.c +++ b/menu/cbs/menu_cbs_start.c @@ -28,6 +28,7 @@ #include "../menu_setting.h" #include "../menu_shader.h" +#include "../../audio/audio_driver.h" #include "../../configuration.h" #include "../../core.h" #include "../../core_info.h" @@ -49,6 +50,18 @@ cbs->action_start_ident = #name; #endif +static int action_start_audio_mixer_stream_volume(unsigned type, const char *label) +{ + unsigned offset = (type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN); + + if (offset >= AUDIO_MIXER_MAX_STREAMS) + return 0; + + audio_driver_mixer_set_stream_volume(offset, 1.0f); + + return 0; +} + static int action_start_remap_file_load(unsigned type, const char *label) { input_remapping_set_defaults(true); @@ -144,9 +157,9 @@ static int action_start_shader_pass(unsigned type, const char *label) if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); - menu->hack_shader_pass = type - MENU_SETTINGS_SHADER_PASS_0; + menu->scratchpad.unsigned_var = type - MENU_SETTINGS_SHADER_PASS_0; - menu_shader_manager_clear_pass_path((unsigned)menu->hack_shader_pass); + menu_shader_manager_clear_pass_path(menu->scratchpad.unsigned_var); return 0; } @@ -369,6 +382,13 @@ int menu_cbs_init_bind_start(menu_file_list_cbs_t *cbs, if (!cbs) return -1; + if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_END) + { + BIND_ACTION_START(cbs, action_start_audio_mixer_stream_volume); + return 0; + } + BIND_ACTION_START(cbs, action_start_lookup_setting); if (menu_cbs_init_bind_start_compare_label(cbs) == 0) diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 23d511aabd..09942ad099 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -15,6 +15,7 @@ #include +#include "../../audio/audio_driver.h" #include "../menu_driver.h" #include "../menu_cbs.h" @@ -39,6 +40,7 @@ #include "../../retroarch.h" #include "../../content.h" +#include "../../configuration.h" #define default_sublabel_macro(func_name, lbl) \ static int (func_name)(file_list_t *list, unsigned type, unsigned i, const char *label, const char *path, char *s, size_t len) \ @@ -47,6 +49,25 @@ return 0; \ } +default_sublabel_macro(menu_action_sublabel_setting_audio_mixer_add_to_mixer_and_play, + MENU_ENUM_SUBLABEL_ADD_TO_MIXER_AND_PLAY) +default_sublabel_macro(menu_action_sublabel_setting_audio_mixer_add_to_mixer, + MENU_ENUM_SUBLABEL_ADD_TO_MIXER) +default_sublabel_macro(menu_action_sublabel_setting_audio_mixer_stream_play, + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY) +default_sublabel_macro(menu_action_sublabel_setting_audio_mixer_stream_play_looped, + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_LOOPED) +default_sublabel_macro(menu_action_sublabel_setting_audio_mixer_stream_play_sequential, + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_SEQUENTIAL) +default_sublabel_macro(menu_action_sublabel_setting_audio_mixer_stream_stop, + MENU_ENUM_SUBLABEL_MIXER_ACTION_STOP) +default_sublabel_macro(menu_action_sublabel_setting_audio_mixer_stream_remove, + MENU_ENUM_SUBLABEL_MIXER_ACTION_REMOVE) +default_sublabel_macro(menu_action_sublabel_setting_audio_mixer_stream_volume, + MENU_ENUM_SUBLABEL_MIXER_ACTION_VOLUME) +default_sublabel_macro(action_bind_sublabel_quick_menu_override_options, MENU_ENUM_SUBLABEL_QUICK_MENU_OVERRIDE_OPTIONS) +default_sublabel_macro(action_bind_sublabel_crt_switchres, MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION) +default_sublabel_macro(action_bind_sublabel_crt_switchres_super, MENU_ENUM_SUBLABEL_CRT_SWITCH_RESOLUTION_SUPER) default_sublabel_macro(action_bind_sublabel_automatically_add_content_to_playlist, MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST) default_sublabel_macro(action_bind_sublabel_driver_settings_list, MENU_ENUM_SUBLABEL_DRIVER_SETTINGS) default_sublabel_macro(action_bind_sublabel_retro_achievements_settings_list, MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS) @@ -77,7 +98,9 @@ default_sublabel_macro(action_bind_sublabel_video_settings_list, MENU_ default_sublabel_macro(action_bind_sublabel_suspend_screensaver_enable, MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE) default_sublabel_macro(action_bind_sublabel_video_window_scale, MENU_ENUM_SUBLABEL_VIDEO_WINDOW_SCALE) default_sublabel_macro(action_bind_sublabel_audio_settings_list, MENU_ENUM_SUBLABEL_AUDIO_SETTINGS) +default_sublabel_macro(action_bind_sublabel_mixer_settings_list, MENU_ENUM_SUBLABEL_AUDIO_MIXER_SETTINGS) default_sublabel_macro(action_bind_sublabel_input_settings_list, MENU_ENUM_SUBLABEL_INPUT_SETTINGS) +default_sublabel_macro(action_bind_sublabel_latency_settings_list, MENU_ENUM_SUBLABEL_LATENCY_SETTINGS) default_sublabel_macro(action_bind_sublabel_wifi_settings_list, MENU_ENUM_SUBLABEL_WIFI_SETTINGS) default_sublabel_macro(action_bind_sublabel_netplay_lan_scan_settings_list,MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS) default_sublabel_macro(action_bind_sublabel_help_list, MENU_ENUM_SUBLABEL_HELP_LIST) @@ -131,7 +154,9 @@ default_sublabel_macro(action_bind_sublabel_core_allow_rotate, MENU_ default_sublabel_macro(action_bind_sublabel_dummy_on_core_shutdown, MENU_ENUM_SUBLABEL_DUMMY_ON_CORE_SHUTDOWN) default_sublabel_macro(action_bind_sublabel_dummy_check_missing_firmware, MENU_ENUM_SUBLABEL_CHECK_FOR_MISSING_FIRMWARE) default_sublabel_macro(action_bind_sublabel_video_refresh_rate, MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE) +default_sublabel_macro(action_bind_sublabel_video_refresh_rate_polled, MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED) default_sublabel_macro(action_bind_sublabel_audio_enable, MENU_ENUM_SUBLABEL_AUDIO_ENABLE) +default_sublabel_macro(action_bind_sublabel_audio_enable_menu, MENU_ENUM_SUBLABEL_AUDIO_ENABLE_MENU) default_sublabel_macro(action_bind_sublabel_audio_max_timing_skew, MENU_ENUM_SUBLABEL_AUDIO_MAX_TIMING_SKEW) default_sublabel_macro(action_bind_sublabel_pause_nonactive, MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE) default_sublabel_macro(action_bind_sublabel_video_disable_composition, MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION) @@ -172,6 +197,9 @@ default_sublabel_macro(action_bind_sublabel_savestate_auto_index, MENU_ default_sublabel_macro(action_bind_sublabel_block_sram_overwrite, MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE) default_sublabel_macro(action_bind_sublabel_fastforward_ratio, MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO) default_sublabel_macro(action_bind_sublabel_slowmotion_ratio, MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO) +default_sublabel_macro(action_bind_sublabel_run_ahead_enabled, MENU_ENUM_SUBLABEL_RUN_AHEAD_ENABLED) +default_sublabel_macro(action_bind_sublabel_run_ahead_secondary_instance, MENU_ENUM_SUBLABEL_RUN_AHEAD_SECONDARY_INSTANCE) +default_sublabel_macro(action_bind_sublabel_run_ahead_frames, MENU_ENUM_SUBLABEL_RUN_AHEAD_FRAMES) default_sublabel_macro(action_bind_sublabel_rewind, MENU_ENUM_SUBLABEL_REWIND_ENABLE) default_sublabel_macro(action_bind_sublabel_rewind_granularity, MENU_ENUM_SUBLABEL_REWIND_GRANULARITY) default_sublabel_macro(action_bind_sublabel_libretro_log_level, MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL) @@ -222,6 +250,7 @@ default_sublabel_macro(action_bind_sublabel_stdin_cmd_enable, MENU_ default_sublabel_macro(action_bind_sublabel_mouse_enable, MENU_ENUM_SUBLABEL_MOUSE_ENABLE) default_sublabel_macro(action_bind_sublabel_pointer_enable, MENU_ENUM_SUBLABEL_POINTER_ENABLE) default_sublabel_macro(action_bind_sublabel_thumbnails, MENU_ENUM_SUBLABEL_THUMBNAILS) +default_sublabel_macro(action_bind_sublabel_left_thumbnails, MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS) default_sublabel_macro(action_bind_sublabel_timedate_enable, MENU_ENUM_SUBLABEL_TIMEDATE_ENABLE) default_sublabel_macro(action_bind_sublabel_battery_level_enable, MENU_ENUM_SUBLABEL_BATTERY_LEVEL_ENABLE) default_sublabel_macro(action_bind_sublabel_navigation_wraparound, MENU_ENUM_SUBLABEL_NAVIGATION_WRAPAROUND) @@ -291,8 +320,10 @@ default_sublabel_macro(action_bind_sublabel_disk_image_append, default_sublabel_macro(action_bind_sublabel_disk_index, MENU_ENUM_SUBLABEL_DISK_INDEX) default_sublabel_macro(action_bind_sublabel_disk_options, MENU_ENUM_SUBLABEL_DISK_OPTIONS) default_sublabel_macro(action_bind_sublabel_menu_throttle_framerate, MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE) +default_sublabel_macro(action_bind_sublabel_xmb_layout, MENU_ENUM_SUBLABEL_XMB_LAYOUT) default_sublabel_macro(action_bind_sublabel_xmb_icon_theme, MENU_ENUM_SUBLABEL_XMB_THEME) default_sublabel_macro(action_bind_sublabel_xmb_shadows_enable, MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE) +default_sublabel_macro(action_bind_sublabel_xmb_vertical_thumbnails, MENU_ENUM_SUBLABEL_XMB_VERTICAL_THUMBNAILS) default_sublabel_macro(action_bind_sublabel_menu_color_theme, MENU_ENUM_SUBLABEL_MATERIALUI_MENU_COLOR_THEME) default_sublabel_macro(action_bind_sublabel_menu_wallpaper_opacity, MENU_ENUM_SUBLABEL_MENU_WALLPAPER_OPACITY) default_sublabel_macro(action_bind_sublabel_menu_framebuffer_opacity, MENU_ENUM_SUBLABEL_MENU_FRAMEBUFFER_OPACITY) @@ -306,6 +337,9 @@ default_sublabel_macro(action_bind_sublabel_quick_menu_show_options, default_sublabel_macro(action_bind_sublabel_quick_menu_show_controls, MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CONTROLS) default_sublabel_macro(action_bind_sublabel_quick_menu_show_cheats, MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CHEATS) default_sublabel_macro(action_bind_sublabel_quick_menu_show_shaders, MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SHADERS) +default_sublabel_macro(action_bind_sublabel_content_show_overlays, MENU_ENUM_SUBLABEL_CONTENT_SHOW_OVERLAYS) +default_sublabel_macro(action_bind_sublabel_content_show_rewind, MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND) +default_sublabel_macro(action_bind_sublabel_content_show_latency, MENU_ENUM_SUBLABEL_CONTENT_SHOW_LATENCY) default_sublabel_macro(action_bind_sublabel_quick_menu_show_save_core_overrides, MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES) default_sublabel_macro(action_bind_sublabel_quick_menu_show_save_game_overrides, MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES) default_sublabel_macro(action_bind_sublabel_quick_menu_show_information, MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_INFORMATION) @@ -330,6 +364,7 @@ default_sublabel_macro(action_bind_sublabel_menu_settings_tab, default_sublabel_macro(action_bind_sublabel_menu_settings_tab_enable_password, MENU_ENUM_SUBLABEL_CONTENT_SHOW_SETTINGS_PASSWORD) default_sublabel_macro(action_bind_sublabel_menu_history_tab, MENU_ENUM_SUBLABEL_CONTENT_SHOW_HISTORY) default_sublabel_macro(action_bind_sublabel_menu_import_content_tab, MENU_ENUM_SUBLABEL_CONTENT_SHOW_ADD) +default_sublabel_macro(action_bind_sublabel_menu_playlist_tabs, MENU_ENUM_SUBLABEL_CONTENT_SHOW_PLAYLISTS) default_sublabel_macro(action_bind_sublabel_main_menu_enable_settings, MENU_ENUM_SUBLABEL_XMB_MAIN_MENU_ENABLE_SETTINGS) default_sublabel_macro(action_bind_sublabel_rgui_show_start_screen, MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN) default_sublabel_macro(action_bind_sublabel_menu_header_opacity, MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY) @@ -407,20 +442,90 @@ static int action_bind_sublabel_subsystem_add( const char *label, const char *path, char *s, size_t len) { - rarch_system_info_t *system = runloop_get_system_info(); - const struct retro_subsystem_info* subsystem = NULL; - subsystem = system->subsystem.data + (type - MENU_SETTINGS_SUBSYSTEM_ADD); + rarch_system_info_t *system = runloop_get_system_info(); + const struct retro_subsystem_info *subsystem = system ? + system->subsystem.data + (type - MENU_SETTINGS_SUBSYSTEM_ADD) : NULL; if (subsystem && content_get_subsystem_rom_id() < subsystem->num_roms) snprintf(s, len, " Current Content: %s", - content_get_subsystem() == type - MENU_SETTINGS_SUBSYSTEM_ADD - ? subsystem->roms[content_get_subsystem_rom_id()].desc + content_get_subsystem() == type - MENU_SETTINGS_SUBSYSTEM_ADD + ? subsystem->roms[content_get_subsystem_rom_id()].desc : subsystem->roms[0].desc); return 0; } +static int action_bind_sublabel_remap_kbd_sublabel( + file_list_t *list, + unsigned type, unsigned i, + const char *label, const char *path, + char *s, size_t len) +{ + unsigned offset = type / ((MENU_SETTINGS_INPUT_DESC_KBD_END - + (MENU_SETTINGS_INPUT_DESC_KBD_END - + MENU_SETTINGS_INPUT_DESC_KBD_BEGIN))) - 1; + snprintf(s, len, "User #%d: %s", offset + 1, + input_config_get_device_display_name(offset) ? + input_config_get_device_display_name(offset) : + (input_config_get_device_name(offset) ? + input_config_get_device_name(offset) : "N/A")); + return 0; +} + +static int action_bind_sublabel_audio_mixer_stream( + file_list_t *list, + unsigned type, unsigned i, + const char *label, const char *path, + char *s, size_t len) +{ + char msg[64]; + unsigned offset = (type - MENU_SETTINGS_AUDIO_MIXER_STREAM_BEGIN); + audio_mixer_stream_t *stream = audio_driver_mixer_get_stream(offset); + + if (!stream) + return 0; + + switch (stream->state) + { + case AUDIO_STREAM_STATE_NONE: + strlcpy(msg, "N/A", sizeof(msg)); + break; + case AUDIO_STREAM_STATE_STOPPED: + strlcpy(msg, "Stopped", sizeof(msg)); + break; + case AUDIO_STREAM_STATE_PLAYING: + strlcpy(msg, "Playing", sizeof(msg)); + break; + case AUDIO_STREAM_STATE_PLAYING_LOOPED: + strlcpy(msg, "Playing (Looped)", sizeof(msg)); + break; + case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL: + strlcpy(msg, "Playing (Sequential)", sizeof(msg)); + break; + } + + snprintf(s, len, "State : %s | Volume: %.2f dB", msg, + stream->volume); + return 0; +} + +static int action_bind_sublabel_remap_sublabel( + file_list_t *list, + unsigned type, unsigned i, + const char *label, const char *path, + char *s, size_t len) +{ + unsigned offset = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) + / (RARCH_FIRST_CUSTOM_BIND + 8); + + snprintf(s, len, "User #%d: %s", offset + 1, + input_config_get_device_display_name(offset) ? + input_config_get_device_display_name(offset) : + (input_config_get_device_name(offset) ? + input_config_get_device_name(offset) : "N/A")); + return 0; +} #ifdef HAVE_NETWORKING static int action_bind_sublabel_netplay_room( @@ -480,10 +585,88 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_generic); + if (type >= MENU_SETTINGS_INPUT_DESC_KBD_BEGIN + && type <= MENU_SETTINGS_INPUT_DESC_KBD_END) + { + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_remap_kbd_sublabel); + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_END) + { + BIND_ACTION_SUBLABEL(cbs, + menu_action_sublabel_setting_audio_mixer_stream_play); + return 0; + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_END) + { + BIND_ACTION_SUBLABEL(cbs, + menu_action_sublabel_setting_audio_mixer_stream_play_looped); + return 0; + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_SEQUENTIAL_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_SEQUENTIAL_END) + { + BIND_ACTION_SUBLABEL(cbs, + menu_action_sublabel_setting_audio_mixer_stream_play_sequential); + return 0; + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_END) + { + BIND_ACTION_SUBLABEL(cbs, + menu_action_sublabel_setting_audio_mixer_stream_remove); + return 0; + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_END) + { + BIND_ACTION_SUBLABEL(cbs, + menu_action_sublabel_setting_audio_mixer_stream_stop); + return 0; + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_END) + { + BIND_ACTION_SUBLABEL(cbs, + menu_action_sublabel_setting_audio_mixer_stream_volume); + return 0; + } + + if (type >= MENU_SETTINGS_INPUT_DESC_BEGIN + && type <= MENU_SETTINGS_INPUT_DESC_END) + { + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_remap_sublabel); + } + + if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_END) + { + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_audio_mixer_stream); + return 0; + } + if (cbs->enum_idx != MSG_UNKNOWN) { switch (cbs->enum_idx) { + case MENU_ENUM_LABEL_ADD_TO_MIXER: + case MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION: + BIND_ACTION_SUBLABEL(cbs, menu_action_sublabel_setting_audio_mixer_add_to_mixer); + break; + case MENU_ENUM_LABEL_ADD_TO_MIXER_AND_PLAY: + case MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY: + BIND_ACTION_SUBLABEL(cbs, menu_action_sublabel_setting_audio_mixer_add_to_mixer_and_play); + break; + case MENU_ENUM_LABEL_QUICK_MENU_OVERRIDE_OPTIONS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_quick_menu_override_options); + break; + case MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_crt_switchres); + break; + case MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION_SUPER: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_crt_switchres_super); + break; case MENU_ENUM_LABEL_AUDIO_RESAMPLER_QUALITY: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_audio_resampler_quality); break; @@ -634,6 +817,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CONTENT_SHOW_ADD: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_import_content_tab); break; + case MENU_ENUM_LABEL_CONTENT_SHOW_PLAYLISTS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_playlist_tabs); + break; case MENU_ENUM_LABEL_XMB_MAIN_MENU_ENABLE_SETTINGS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_main_menu_enable_settings); break; @@ -679,6 +865,15 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_QUICK_MENU_SHOW_CHEATS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_quick_menu_show_cheats); break; + case MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_show_latency); + break; + case MENU_ENUM_LABEL_CONTENT_SHOW_REWIND: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_show_rewind); + break; + case MENU_ENUM_LABEL_CONTENT_SHOW_OVERLAYS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_show_overlays); + break; case MENU_ENUM_LABEL_QUICK_MENU_SHOW_SHADERS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_quick_menu_show_shaders); break; @@ -761,6 +956,12 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_xmb_shadows_enable); break; + case MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_xmb_vertical_thumbnails); + break; + case MENU_ENUM_LABEL_XMB_LAYOUT: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_xmb_layout); + break; case MENU_ENUM_LABEL_XMB_THEME: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_xmb_icon_theme); break; @@ -959,6 +1160,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_THUMBNAILS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_thumbnails); break; + case MENU_ENUM_LABEL_LEFT_THUMBNAILS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_left_thumbnails); + break; case MENU_ENUM_LABEL_MOUSE_ENABLE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_mouse_enable); break; @@ -1109,6 +1313,15 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_SLOWMOTION_RATIO: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_slowmotion_ratio); break; + case MENU_ENUM_LABEL_RUN_AHEAD_ENABLED: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_run_ahead_enabled); + break; + case MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_run_ahead_secondary_instance); + break; + case MENU_ENUM_LABEL_RUN_AHEAD_FRAMES: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_run_ahead_frames); + break; case MENU_ENUM_LABEL_FASTFORWARD_RATIO: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_fastforward_ratio); break; @@ -1223,6 +1436,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_AUDIO_ENABLE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_audio_enable); break; + case MENU_ENUM_LABEL_AUDIO_ENABLE_MENU: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_audio_enable_menu); + break; case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_refresh_rate); break; @@ -1341,6 +1557,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_AUTO: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_refresh_rate_auto); break; + case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_refresh_rate_polled); + break; case MENU_ENUM_LABEL_VIDEO_MONITOR_INDEX: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_monitor_index); break; @@ -1419,6 +1638,12 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_AUDIO_SETTINGS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_audio_settings_list); break; + case MENU_ENUM_LABEL_AUDIO_MIXER_SETTINGS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_mixer_settings_list); + break; + case MENU_ENUM_LABEL_LATENCY_SETTINGS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_latency_settings_list); + break; case MENU_ENUM_LABEL_RECORDING_SETTINGS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_recording_settings_list); break; diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index c5f99e6dc6..07501c9817 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -19,6 +19,8 @@ #include +#include "../../audio/audio_driver.h" + #include "../menu_driver.h" #include "../menu_cbs.h" @@ -76,6 +78,15 @@ static int action_get_title_action_generic(const char *path, const char *label, return 0; \ } +static int action_get_title_mixer_stream_actions(const char *path, const char *label, unsigned menu_type, char *s, size_t len) +{ + unsigned offset = (menu_type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_BEGIN); + + snprintf(s, len, "Mixer Stream #%d: %s", offset + 1, audio_driver_mixer_get_stream_name(offset)); + return 0; +} + +default_title_macro(action_get_quick_menu_override_options, MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS) default_title_macro(action_get_user_accounts_cheevos_list, MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS) default_title_macro(action_get_download_core_content_list, MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT) default_title_macro(action_get_user_accounts_list, MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST) @@ -124,7 +135,9 @@ default_title_macro(action_get_directory_settings_list, MENU_ENUM_LABEL_ default_title_macro(action_get_privacy_settings_list, MENU_ENUM_LABEL_VALUE_PRIVACY_SETTINGS) default_title_macro(action_get_updater_settings_list, MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS) default_title_macro(action_get_audio_settings_list, MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS) +default_title_macro(action_get_audio_mixer_settings_list, MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_SETTINGS) default_title_macro(action_get_input_settings_list, MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS) +default_title_macro(action_get_latency_settings_list, MENU_ENUM_LABEL_VALUE_LATENCY_SETTINGS) default_title_macro(action_get_core_cheat_options_list, MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS) default_title_macro(action_get_load_content_list, MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST) default_title_macro(action_get_load_content_special, MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_SPECIAL) @@ -475,6 +488,16 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, BIND_ACTION_GET_TITLE(cbs, action_get_audio_settings_list); return 0; } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_AUDIO_MIXER_SETTINGS_LIST))) + { + BIND_ACTION_GET_TITLE(cbs, action_get_audio_mixer_settings_list); + return 0; + } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_LATENCY_SETTINGS_LIST))) + { + BIND_ACTION_GET_TITLE(cbs, action_get_latency_settings_list); + return 0; + } else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_SYSTEM_INFORMATION))) { BIND_ACTION_GET_TITLE(cbs, action_get_system_information_list); @@ -485,6 +508,11 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, BIND_ACTION_GET_TITLE(cbs, action_get_network_information_list); return 0; } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_QUICK_MENU_OVERRIDE_OPTIONS))) + { + BIND_ACTION_GET_TITLE(cbs, action_get_quick_menu_override_options); + return 0; + } else if (cbs->enum_idx != MSG_UNKNOWN) { switch (cbs->enum_idx) @@ -1110,6 +1138,13 @@ int menu_cbs_init_bind_title(menu_file_list_cbs_t *cbs, if (menu_cbs_init_bind_title_compare_type(cbs, type) == 0) return 0; + + if (string_is_equal(label, + msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST))) + { + BIND_ACTION_GET_TITLE(cbs, action_get_title_mixer_stream_actions); + return 0; + } if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS))) { diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index c37f93ab55..91c4ca65bd 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -407,100 +407,6 @@ static void materialui_draw_tab( &tab_color[0]); } -/* Draw the onscreen keyboard */ -static void materialui_render_keyboard(materialui_handle_t *mui, - video_frame_info_t *video_info, - const char *grid[], unsigned id) -{ - int ptr_width, ptr_height; - unsigned i; - unsigned width = video_info->width; - unsigned height = video_info->height; - float dark[16] = { - 0.00, 0.00, 0.00, 0.85, - 0.00, 0.00, 0.00, 0.85, - 0.00, 0.00, 0.00, 0.85, - 0.00, 0.00, 0.00, 0.85, - }; - - float white[16] = { - 1.00, 1.00, 1.00, 1.00, - 1.00, 1.00, 1.00, 1.00, - 1.00, 1.00, 1.00, 1.00, - 1.00, 1.00, 1.00, 1.00, - }; - - menu_display_draw_quad( - video_info, - 0, - height/2.0, width, height/2.0, - width, height, - &dark[0]); - - ptr_width = width / 11; - ptr_height = height / 10; - - if (ptr_width >= ptr_height) - ptr_width = ptr_height; - - for (i = 0; i < 44; i++) - { - int line_y = (i / 11)*height/10.0; - uintptr_t texture = mui->textures.list[MUI_TEXTURE_KEY]; - - if (i == id) - texture = mui->textures.list[MUI_TEXTURE_KEY_HOVER]; - - menu_display_blend_begin(video_info); - - menu_display_draw_texture( - video_info, - width/2.0 - (11*ptr_width)/2.0 + (i % 11) * ptr_width, - height/2.0 + ptr_height*1.5 + line_y, - ptr_width, ptr_height, - width, height, - &white[0], - texture); - - menu_display_draw_text(mui->font, grid[i], - width/2.0 - (11*ptr_width)/2.0 + (i % 11) * ptr_width + ptr_width/2.0, - height/2.0 + ptr_height + line_y + mui->font->size / 3, - width, height, 0xffffffff, TEXT_ALIGN_CENTER, 1.0f, - false, 0); - } -} - -/* Returns the OSK key at a given position */ -static int materialui_osk_ptr_at_pos(void *data, int x, int y, - unsigned width, unsigned height) -{ - unsigned i; - int ptr_width, ptr_height; - materialui_handle_t *mui = (materialui_handle_t*)data; - - if (!mui) - return -1; - - ptr_width = width / 11; - ptr_height = height / 10; - - if (ptr_width >= ptr_height) - ptr_width = ptr_height; - - for (i = 0; i < 44; i++) - { - int line_y = (i / 11)*height/10.0; - int ptr_x = width/2.0 - (11*ptr_width)/2.0 + (i % 11) * ptr_width; - int ptr_y = height/2.0 + ptr_height*1.5 + line_y - ptr_height; - - if (x > ptr_x && x < ptr_x + ptr_width - && y > ptr_y && y < ptr_y + ptr_height) - return i; - } - - return -1; -} - /* Draw the tabs background */ static void materialui_draw_tab_begin( materialui_handle_t *mui, @@ -631,7 +537,7 @@ static void materialui_render_messagebox(materialui_handle_t *mui, { longest = len; longest_width = font_driver_get_message_width( - mui->font, msg, strlen(msg), 1); + mui->font, msg, (unsigned)strlen(msg), 1); } } @@ -661,7 +567,9 @@ static void materialui_render_messagebox(materialui_handle_t *mui, } if (menu_input_dialog_get_display_kb()) - materialui_render_keyboard(mui, + menu_display_draw_keyboard( + mui->textures.list[MUI_TEXTURE_KEY_HOVER], + mui->font, video_info, menu_event_get_osk_grid(), menu_event_get_osk_ptr()); @@ -697,7 +605,7 @@ static void materialui_compute_entries_box(materialui_handle_t* mui, int width) char *sublabel_str = NULL; unsigned lines = 0; materialui_node_t *node = (materialui_node_t*) - file_list_get_userdata_at_offset(list, i); + file_list_get_userdata_at_offset(list, i); menu_entry_init(&entry); menu_entry_get(&entry, 0, i, NULL, true); @@ -733,7 +641,7 @@ static void materialui_compute_entries_box(materialui_handle_t* mui, int width) } /* Called on each frame. We use this callback to implement the touch scroll -with acceleration */ + with acceleration */ static void materialui_render(void *data, bool is_idle) { menu_animation_ctx_delta_t delta; @@ -778,12 +686,12 @@ static void materialui_render(void *data, bool is_idle) for (ii = 0; ii < entries_end; ii++) { materialui_node_t *node = (materialui_node_t*) - file_list_get_userdata_at_offset(list, ii); + file_list_get_userdata_at_offset(list, ii); if (pointer_y > (-mui->scroll_y + header_height + node->y) - && pointer_y < (-mui->scroll_y + header_height + node->y + node->line_height) - ) - menu_input_ctl(MENU_INPUT_CTL_POINTER_PTR, &ii); + && pointer_y < (-mui->scroll_y + header_height + node->y + node->line_height) + ) + menu_input_ctl(MENU_INPUT_CTL_POINTER_PTR, &ii); } menu_input_ctl(MENU_INPUT_CTL_POINTER_ACCEL_READ, &old_accel_val); @@ -804,12 +712,12 @@ static void materialui_render(void *data, bool is_idle) for (ii = 0; ii < entries_end; ii++) { materialui_node_t *node = (materialui_node_t*) - file_list_get_userdata_at_offset(list, ii); + file_list_get_userdata_at_offset(list, ii); if (mouse_y > (-mui->scroll_y + header_height + node->y) - && mouse_y < (-mui->scroll_y + header_height + node->y + node->line_height) - ) - menu_input_ctl(MENU_INPUT_CTL_MOUSE_PTR, &ii); + && mouse_y < (-mui->scroll_y + header_height + node->y + node->line_height) + ) + menu_input_ctl(MENU_INPUT_CTL_MOUSE_PTR, &ii); } } @@ -891,7 +799,7 @@ static void materialui_render_label_value( do_draw_text = true; } else if (string_is_equal(value, msg_hash_to_str(MENU_ENUM_LABEL_ENABLED)) || - (string_is_equal(value, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON)))) + (string_is_equal(value, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON)))) { if (mui->textures.list[MUI_TEXTURE_SWITCH_ON]) { @@ -988,11 +896,11 @@ static void materialui_render_label_value( 0, 1, &label_color[0] - ); + ); if (texture_switch) { - /* This will be used instead of label_color if + /* This will be used instead of label_color if * texture_switch is 'off' icon */ float pure_white[16]= { 1.00, 1.00, 1.00, 1.00, @@ -1051,7 +959,7 @@ static void materialui_render_menu_list( char *rich_label = NULL; bool entry_selected = false; materialui_node_t *node = (materialui_node_t*) - file_list_get_userdata_at_offset(list, i); + file_list_get_userdata_at_offset(list, i); size_t selection = menu_navigation_get_selection(); int y = header_height - mui->scroll_y + sum; @@ -1074,21 +982,21 @@ static void materialui_render_menu_list( /* Render label, value, and associated icons */ materialui_render_label_value( - mui, - video_info, - node, - (int)i, - y, - width, - height, - frame_count / 20, - font_hover_color, - entry_selected, - rich_label, - entry_value, - menu_list_color, - sublabel_color - ); + mui, + video_info, + node, + (int)i, + y, + width, + height, + frame_count / 20, + font_hover_color, + entry_selected, + rich_label, + entry_value, + menu_list_color, + sublabel_color + ); menu_entry_free(&entry); free(rich_label); @@ -1167,7 +1075,7 @@ static void materialui_draw_bg(menu_display_ctx_draw_t *draw, } /* Main function of the menu driver. Takes care of drawing the header, the tabs, -and the menu list */ + and the menu list */ static void materialui_frame(void *data, video_frame_info_t *video_info) { /* This controls the main background color */ @@ -1328,7 +1236,7 @@ static void materialui_frame(void *data, video_frame_info_t *video_info) clearcolor.a = 0.75f; break; case MATERIALUI_THEME_GREEN: - hex32_to_rgba_normalized(0x4CAF50, green_500, 1.00); + hex32_to_rgba_normalized(0x4CAF50, green_500, 1.00); hex32_to_rgba_normalized(0x4CAF50, header_bg_color_real, 1.00); hex32_to_rgba_normalized(0xC8E6C9, green_50, 0.90); hex32_to_rgba_normalized(0xFFFFFF, footer_bg_color_real, 1.00); @@ -1568,7 +1476,7 @@ static void materialui_frame(void *data, video_frame_info_t *video_info) { materialui_draw_tab_begin(mui, video_info, - width, height, + width, height, footer_bg_color ? &footer_bg_color[0] : NULL, &grey_bg[0]); @@ -1630,7 +1538,7 @@ static void materialui_frame(void *data, video_frame_info_t *video_info) ); } - ticker_limit = usable_width / mui->glyph_width; + ticker_limit = (unsigned)(usable_width / mui->glyph_width); ticker.s = title_buf; ticker.len = ticker_limit; @@ -1667,9 +1575,9 @@ static void materialui_frame(void *data, video_frame_info_t *video_info) if (mui->font) menu_display_draw_text(mui->font, title_buf, - title_margin, - header_height / 2 + mui->font->size / 3, - width, height, font_header_color, TEXT_ALIGN_LEFT, 1.0f, false, 0); + title_margin, + header_height / 2 + mui->font->size / 3, + width, height, font_header_color, TEXT_ALIGN_LEFT, 1.0f, false, 0); materialui_draw_scrollbar(mui, video_info, width, height, &grey_bg[0]); @@ -1683,7 +1591,7 @@ static void materialui_frame(void *data, video_frame_info_t *video_info) snprintf(msg, sizeof(msg), "%s\n%s", label, str); materialui_render_messagebox(mui, video_info, - msg, &body_bg_color[0], font_hover_color); + msg, &body_bg_color[0], font_hover_color); } if (!string_is_empty(mui->box_message)) @@ -1692,7 +1600,7 @@ static void materialui_frame(void *data, video_frame_info_t *video_info) 0, 0, width, height, width, height, &black_bg[0]); materialui_render_messagebox(mui, video_info, - mui->box_message, &body_bg_color[0], font_hover_color); + mui->box_message, &body_bg_color[0], font_hover_color); free(mui->box_message); mui->box_message = NULL; @@ -1778,6 +1686,7 @@ static void materialui_layout(materialui_handle_t *mui, bool video_is_threaded) static void *materialui_init(void **userdata, bool video_is_threaded) { + float scale_factor = menu_display_get_dpi(); materialui_handle_t *mui = NULL; menu_handle_t *menu = (menu_handle_t*) calloc(1, sizeof(*menu)); @@ -1794,7 +1703,7 @@ static void *materialui_init(void **userdata, bool video_is_threaded) goto error; *userdata = mui; - mui->cursor_size = 64.0; + mui->cursor_size = scale_factor / 3; mui->need_compute = false; return menu; @@ -1860,6 +1769,7 @@ static bool materialui_load_image(void *userdata, void *data, enum menu_image_ty menu_display_allocate_white_texture(); break; case MENU_IMAGE_THUMBNAIL: + case MENU_IMAGE_LEFT_THUMBNAIL: case MENU_IMAGE_SAVESTATE_THUMBNAIL: break; } @@ -1885,10 +1795,10 @@ static float materialui_get_scroll(materialui_handle_t *mui) for (i = 0; i < selection; i++) { materialui_node_t *node = (materialui_node_t*) - file_list_get_userdata_at_offset(list, i); + file_list_get_userdata_at_offset(list, i); if (node) - sum += node->line_height; + sum += node->line_height; } if (sum < half) @@ -1898,7 +1808,7 @@ static float materialui_get_scroll(materialui_handle_t *mui) } /* The navigation pointer has been updated (for example by pressing up or down -on the keyboard). We use this function to animate the scroll. */ + on the keyboard). We use this function to animate the scroll. */ static void materialui_navigation_set(void *data, bool scroll) { menu_animation_ctx_entry_t entry; @@ -2043,7 +1953,7 @@ static void materialui_preswitch_tabs(materialui_handle_t *mui, unsigned action) } /* This callback is not caching anything. We use it to navigate the tabs -with the keyboard */ + with the keyboard */ static void materialui_list_cache(void *data, enum menu_list_type type, unsigned action) { @@ -2093,7 +2003,7 @@ static void materialui_list_cache(void *data, } /* A new list has been pushed. We use this callback to customize a few lists for -this menu driver */ + this menu driver */ static int materialui_list_push(void *data, void *userdata, menu_displaylist_info_t *info, unsigned type) { @@ -2266,7 +2176,7 @@ static size_t materialui_list_get_selection(void *data) } /* The pointer or the mouse is pressed down. We use this callback to -highlight the entry that has been pressed */ + highlight the entry that has been pressed */ static int materialui_pointer_down(void *userdata, unsigned x, unsigned y, unsigned ptr, menu_file_list_cbs_t *cbs, @@ -2299,11 +2209,11 @@ static int materialui_pointer_down(void *userdata, for (ii = 0; ii < entries_end; ii++) { materialui_node_t *node = (materialui_node_t*) - file_list_get_userdata_at_offset(list, ii); + file_list_get_userdata_at_offset(list, ii); if (y > (-mui->scroll_y + header_height + node->y) - && y < (-mui->scroll_y + header_height + node->y + node->line_height) - ) + && y < (-mui->scroll_y + header_height + node->y + node->line_height) + ) menu_navigation_set_selection(ii); } @@ -2314,9 +2224,9 @@ static int materialui_pointer_down(void *userdata, } /* The pointer or the left mouse button has been released. -If we clicked on the header, we perform a cancel action. -If we clicked on the tabs, we switch to a new list. -If we clicked on a menu entry, we call the entry action callback. */ + If we clicked on the header, we perform a cancel action. + If we clicked on the tabs, we switch to a new list. + If we clicked on a menu entry, we call the entry action callback. */ static int materialui_pointer_up(void *userdata, unsigned x, unsigned y, unsigned ptr, menu_file_list_cbs_t *cbs, @@ -2368,11 +2278,11 @@ static int materialui_pointer_up(void *userdata, for (ii = 0; ii < entries_end; ii++) { materialui_node_t *node = (materialui_node_t*) - file_list_get_userdata_at_offset(list, ii); + file_list_get_userdata_at_offset(list, ii); if (y > (-mui->scroll_y + header_height + node->y) - && y < (-mui->scroll_y + header_height + node->y + node->line_height) - ) + && y < (-mui->scroll_y + header_height + node->y + node->line_height) + ) { if (ptr == ii && cbs && cbs->action_select) return menu_entry_action(entry, (unsigned)ii, MENU_ACTION_SELECT); @@ -2572,21 +2482,24 @@ static void materialui_list_insert(void *userdata, else if ( string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_FAVORITES)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_FAVORITES_PLAYLIST)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_GOTO_FAVORITES)) ) { node->texture_switch2_index = MUI_TEXTURE_ADD_TO_FAVORITES; node->texture_switch2_set = true; } - else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_RENAME_ENTRY))) + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_RENAME_ENTRY)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_RESET_CORE_ASSOCIATION))) { node->texture_switch2_index = MUI_TEXTURE_RENAME; node->texture_switch2_set = true; } else if ( - string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_MIXER)) - || - string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION)) + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_MIXER)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_MIXER_AND_PLAY)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY)) ) { node->texture_switch2_index = MUI_TEXTURE_ADD_TO_MIXER; @@ -2724,8 +2637,12 @@ static void materialui_list_insert(void *userdata, || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_AUDIO_SETTINGS)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_AUDIO_MIXER_SETTINGS)) + || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_INPUT_SETTINGS)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_LATENCY_SETTINGS)) + || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_INPUT_HOTKEY_BINDS)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_CORE_SETTINGS)) @@ -2870,7 +2787,7 @@ menu_ctx_driver_t menu_ctx_mui = { NULL, NULL, NULL, - materialui_osk_ptr_at_pos, + menu_display_osk_ptr_at_pos, NULL, NULL, materialui_pointer_down, diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 16de9c2c43..4c7beca70b 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -55,11 +55,14 @@ typedef struct { + bool bg_modified; bool force_redraw; bool mouse_show; unsigned last_width; unsigned last_height; unsigned frame_count; + bool bg_thickness; + bool border_thickness; float scroll_y; char *msgbox; } rgui_t; @@ -86,10 +89,10 @@ static uint16_t argb32_to_rgba4444(uint32_t col) #endif -static uint16_t rgui_gray_filler(unsigned x, unsigned y) +static uint16_t rgui_gray_filler(rgui_t *rgui, unsigned x, unsigned y) { - unsigned col = (((x >> 1) + (y >> 1)) & 1) + 1; - + unsigned shft = (rgui->bg_thickness ? 1 : 0); + unsigned col = (((x >> shft) + (y >> shft)) & 1) + 1; #if defined(GEKKO) || defined(PSP) return (6 << 12) | (col << 8) | (col << 4) | (col << 0); #else @@ -97,9 +100,10 @@ static uint16_t rgui_gray_filler(unsigned x, unsigned y) #endif } -static uint16_t rgui_green_filler(unsigned x, unsigned y) +static uint16_t rgui_green_filler(rgui_t *rgui, unsigned x, unsigned y) { - unsigned col = (((x >> 1) + (y >> 1)) & 1) + 1; + unsigned shft = (rgui->border_thickness ? 1 : 0); + unsigned col = (((x >> shft) + (y >> shft)) & 1) + 1; #if defined(GEKKO) || defined(PSP) return (6 << 12) | (col << 8) | (col << 5) | (col << 0); #else @@ -108,17 +112,18 @@ static uint16_t rgui_green_filler(unsigned x, unsigned y) } static void rgui_fill_rect( + rgui_t *rgui, uint16_t *data, size_t pitch, unsigned x, unsigned y, unsigned width, unsigned height, - uint16_t (*col)(unsigned x, unsigned y)) + uint16_t (*col)(rgui_t *rgui, unsigned x, unsigned y)) { unsigned i, j; for (j = y; j < y + height; j++) for (i = x; i < x + width; i++) - data[j * (pitch >> 1) + i] = col(i, j); + data[j * (pitch >> 1) + i] = col(rgui, i, j); } static void rgui_color_rect( @@ -239,7 +244,7 @@ static bool rguidisp_init_font(menu_handle_t *menu) return true; } -static void rgui_render_background(void) +static void rgui_render_background(rgui_t *rgui) { size_t pitch_in_pixels, size; size_t fb_pitch; @@ -263,12 +268,17 @@ static void rgui_render_background(void) if (rgui_framebuf_data) { - rgui_fill_rect(rgui_framebuf_data, fb_pitch, 5, 5, fb_width - 10, 5, rgui_green_filler); - rgui_fill_rect(rgui_framebuf_data, fb_pitch, 5, fb_height - 10, fb_width - 10, 5, rgui_green_filler); + settings_t *settings = config_get_ptr(); - rgui_fill_rect(rgui_framebuf_data, fb_pitch, 5, 5, 5, fb_height - 10, rgui_green_filler); - rgui_fill_rect(rgui_framebuf_data, fb_pitch, fb_width - 10, 5, 5, fb_height - 10, - rgui_green_filler); + if (settings->bools.menu_rgui_border_filler_enable) + { + rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, 5, 5, fb_width - 10, 5, rgui_green_filler); + rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, 5, fb_height - 10, fb_width - 10, 5, rgui_green_filler); + + rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, 5, 5, 5, fb_height - 10, rgui_green_filler); + rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, fb_width - 10, 5, 5, fb_height - 10, + rgui_green_filler); + } } } @@ -285,7 +295,7 @@ static void rgui_set_message(void *data, const char *message) rgui->force_redraw = true; } -static void rgui_render_messagebox(const char *message) +static void rgui_render_messagebox(rgui_t *rgui, const char *message) { int x, y; uint16_t color; @@ -338,20 +348,24 @@ static void rgui_render_messagebox(const char *message) if (rgui_framebuf_data) { - rgui_fill_rect(rgui_framebuf_data, + rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, x + 5, y + 5, width - 10, height - 10, rgui_gray_filler); - rgui_fill_rect(rgui_framebuf_data, - fb_pitch, x, y, width - 5, 5, rgui_green_filler); - rgui_fill_rect(rgui_framebuf_data, - fb_pitch, x + width - 5, y, 5, - height - 5, rgui_green_filler); - rgui_fill_rect(rgui_framebuf_data, - fb_pitch, x + 5, y + height - 5, - width - 5, 5, rgui_green_filler); - rgui_fill_rect(rgui_framebuf_data, - fb_pitch, x, y + 5, 5, - height - 5, rgui_green_filler); + + if (settings->bools.menu_rgui_border_filler_enable) + { + rgui_fill_rect(rgui, rgui_framebuf_data, + fb_pitch, x, y, width - 5, 5, rgui_green_filler); + rgui_fill_rect(rgui, rgui_framebuf_data, + fb_pitch, x + width - 5, y, 5, + height - 5, rgui_green_filler); + rgui_fill_rect(rgui, rgui_framebuf_data, + fb_pitch, x + 5, y + height - 5, + width - 5, 5, rgui_green_filler); + rgui_fill_rect(rgui, rgui_framebuf_data, + fb_pitch, x, y + 5, 5, + height - 5, rgui_green_filler); + } } color = NORMAL_COLOR(settings); @@ -390,6 +404,15 @@ static void rgui_blit_cursor(void) static void rgui_frame(void *data, video_frame_info_t *video_info) { rgui_t *rgui = (rgui_t*)data; + settings_t *settings = config_get_ptr(); + + if ((settings->bools.menu_rgui_background_filler_thickness_enable != rgui->bg_thickness) || + (settings->bools.menu_rgui_border_filler_thickness_enable != rgui->border_thickness) + ) + rgui->bg_modified = true; + + rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable; + rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; rgui->frame_count++; } @@ -430,14 +453,17 @@ static void rgui_render(void *data, bool is_idle) &fb_pitch); /* if the framebuffer changed size, recache the background */ - if (rgui->last_width != fb_width || rgui->last_height != fb_height) + if (rgui->bg_modified || rgui->last_width != fb_width || rgui->last_height != fb_height) { if (rgui_framebuf_data) - rgui_fill_rect(rgui_framebuf_data, + rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch, 0, fb_height, fb_width, 4, rgui_gray_filler); rgui->last_width = fb_width; rgui->last_height = fb_height; } + + if (rgui->bg_modified) + rgui->bg_modified = false; menu_display_set_framebuffer_dirty_flag(); menu_animation_ctl(MENU_ANIMATION_CTL_CLEAR_ACTIVE, NULL); @@ -502,7 +528,7 @@ static void rgui_render(void *data, bool is_idle) end = ((old_start + RGUI_TERM_HEIGHT(fb_width, fb_height)) <= (entries_end)) ? old_start + RGUI_TERM_HEIGHT(fb_width, fb_height) : entries_end; - rgui_render_background(); + rgui_render_background(rgui); menu_entries_get_title(title, sizeof(title)); @@ -648,12 +674,12 @@ static void rgui_render(void *data, bool is_idle) const char *label = menu_input_dialog_get_label_buffer(); snprintf(msg, sizeof(msg), "%s\n%s", label, str); - rgui_render_messagebox(msg); + rgui_render_messagebox(rgui, msg); } if (!string_is_empty(rgui->msgbox)) { - rgui_render_messagebox(rgui->msgbox); + rgui_render_messagebox(rgui, rgui->msgbox); free(rgui->msgbox); rgui->msgbox = NULL; rgui->force_redraw = true; @@ -684,6 +710,7 @@ static void *rgui_init(void **userdata, bool video_is_threaded) unsigned fb_width, fb_height, new_font_height; rgui_t *rgui = NULL; bool ret = false; + settings_t *settings = config_get_ptr(); menu_handle_t *menu = (menu_handle_t*)calloc(1, sizeof(*menu)); if (!menu) @@ -694,7 +721,7 @@ static void *rgui_init(void **userdata, bool video_is_threaded) if (!rgui) goto error; - *userdata = rgui; + *userdata = rgui; /* 4 extra lines to cache the checked background */ rgui_framebuf_data = (uint16_t*) @@ -721,10 +748,9 @@ static void *rgui_init(void **userdata, bool video_is_threaded) if (!ret) goto error; - if (rgui_framebuf_data) - rgui_fill_rect(rgui_framebuf_data, - fb_pitch, 0, fb_height, - fb_width, 4, rgui_gray_filler); + rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable; + rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable; + rgui->bg_modified = true; rgui->last_width = fb_width; rgui->last_height = fb_height; diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 532cfac8bf..57dffb84b5 100755 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2,6 +2,7 @@ * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2014-2017 - Jean-André Santoni * Copyright (C) 2016-2017 - Brad Parker + * Copyright (C) 2018 - Alfredo Monclús * * 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- @@ -104,9 +105,11 @@ enum #ifdef HAVE_NETWORKING XMB_TEXTURE_NETPLAY, XMB_TEXTURE_ROOM, -/* stub these out until we have the icons +#if 0 + /* stub these out until we have the icons */ XMB_TEXTURE_ROOM_LAN, - XMB_TEXTURE_ROOM_MITM,*/ + XMB_TEXTURE_ROOM_MITM, +#endif #endif #ifdef HAVE_IMAGEVIEWER XMB_TEXTURE_IMAGES, @@ -180,6 +183,7 @@ enum typedef struct xmb_handle { bool mouse_show; + bool use_ps3_layout; uint8_t system_tab_end; uint8_t tabs[XMB_SYSTEM_TAB_MAX_LENGTH]; @@ -196,12 +200,15 @@ typedef struct xmb_handle unsigned categories_active_idx; unsigned categories_active_idx_old; uintptr_t thumbnail; + uintptr_t left_thumbnail; uintptr_t savestate_thumbnail; float x; float alpha; float thumbnail_width; float thumbnail_height; + float left_thumbnail_width; + float left_thumbnail_height; float savestate_thumbnail_width; float savestate_thumbnail_height; float above_subitem_offset; @@ -243,6 +250,7 @@ typedef struct xmb_handle char *thumbnail_content; char *savestate_thumbnail_file_path; char *thumbnail_file_path; + char *left_thumbnail_file_path; char *bg_file_path; file_list_t *selection_buf_old; @@ -274,27 +282,8 @@ typedef struct xmb_handle video_font_raster_block_t raster_block2; } xmb_handle_t; -/* scaling multiplier resulting from equations using values below */ -/* applied in xmb_init */ -/* values for xmb_scale 50 = {2.5, 2.5, 2, 1.7, 2.5, 4, 2.4, 2.5} */ -/* values for xmb_scale 75 = {2, 1.6, 1.6, 1.4, 1.5, 2.3, 1.9, 1.3} */ float scale_mod[8] = { - /* text length & word wrap (base 35 apply to file browser, 1st column) */ - 1, - /* playlist text length when thumbnail is ON (small, base 40) */ - 1, - /* playlist text length when thumbnail is OFF (large, base 70) */ - 1, - /* sub-label length & word wrap */ - 1, - /* thumbnail size & vertical margin from top */ - 1, - /* thumbnail horizontal left margin (horizontal positioning) */ - 1, - /* margin before 2nd column start (shaders parameters, cheats...) */ - 1, - /* text length & word wrap (base 35 apply to 2nd column in cheats, shaders...) */ - 1 + 1, 1, 1, 1, 1, 1, 1, 1 }; static float coord_shadow[] = { @@ -331,9 +320,9 @@ static float item_color[] = { float gradient_dark_purple[16] = { - 20/255.0, 13/255.0, 20/255.0, 1.0, - 20/255.0, 13/255.0, 20/255.0, 1.0, - 92/255.0, 44/255.0, 92/255.0, 1.0, + 20/255.0, 13/255.0, 20/255.0, 1.0, + 20/255.0, 13/255.0, 20/255.0, 1.0, + 92/255.0, 44/255.0, 92/255.0, 1.0, 148/255.0, 90/255.0, 148/255.0, 1.0, }; @@ -359,24 +348,24 @@ float gradient_legacy_red[16] = { }; float gradient_electric_blue[16] = { - 1/255.0, 2/255.0, 67/255.0, 1.0, - 1/255.0, 73/255.0, 183/255.0, 1.0, - 1/255.0, 93/255.0, 194/255.0, 1.0, - 3/255.0, 162/255.0, 254/255.0, 1.0, + 1/255.0, 2/255.0, 67/255.0, 1.0, + 1/255.0, 73/255.0, 183/255.0, 1.0, + 1/255.0, 93/255.0, 194/255.0, 1.0, + 3/255.0, 162/255.0, 254/255.0, 1.0, }; float gradient_apple_green[16] = { 102/255.0, 134/255.0, 58/255.0, 1.0, 122/255.0, 131/255.0, 52/255.0, 1.0, - 82/255.0, 101/255.0, 35/255.0, 1.0, - 63/255.0, 95/255.0, 30/255.0, 1.0, + 82/255.0, 101/255.0, 35/255.0, 1.0, + 63/255.0, 95/255.0, 30/255.0, 1.0, }; float gradient_undersea[16] = { - 23/255.0, 18/255.0, 41/255.0, 1.0, - 30/255.0, 72/255.0, 114/255.0, 1.0, - 52/255.0, 88/255.0, 110/255.0, 1.0, - 69/255.0, 125/255.0, 140/255.0, 1.0, + 23/255.0, 18/255.0, 41/255.0, 1.0, + 30/255.0, 72/255.0, 114/255.0, 1.0, + 52/255.0, 88/255.0, 110/255.0, 1.0, + 69/255.0, 125/255.0, 140/255.0, 1.0, }; @@ -459,15 +448,15 @@ static xmb_node_t *xmb_alloc_node(void) static void xmb_free_node(xmb_node_t *node) { - if (!node) - return; + if (!node) + return; - if (node->fullpath) - free(node->fullpath); + if (node->fullpath) + free(node->fullpath); - node->fullpath = NULL; + node->fullpath = NULL; - free(node); + free(node); } /** @@ -482,7 +471,7 @@ static void xmb_free_node(xmb_node_t *node) */ static void xmb_free_list_nodes(file_list_t *list, bool actiondata) { - unsigned i, size = file_list_get_size(list); + unsigned i, size = (unsigned)file_list_get_size(list); for (i = 0; i < size; ++i) { @@ -506,11 +495,17 @@ static xmb_node_t *xmb_copy_node(const xmb_node_t *old_node) return new_node; } -static const char *xmb_thumbnails_ident(void) +static const char *xmb_thumbnails_ident(char pos) { + char folder = 0; settings_t *settings = config_get_ptr(); - switch (settings->uints.menu_thumbnails) + if (pos == 'R') + folder = settings->uints.menu_thumbnails; + if (pos == 'L') + folder = settings->uints.menu_left_thumbnails; + + switch (folder) { case 1: return "Named_Snaps"; @@ -587,7 +582,8 @@ static size_t xmb_list_get_size(void *data, enum menu_list_type type) return 0; } -static void *xmb_list_get_entry(void *data, enum menu_list_type type, unsigned i) +static void *xmb_list_get_entry(void *data, + enum menu_list_type type, unsigned i) { size_t list_size = 0; xmb_handle_t *xmb = (xmb_handle_t*)data; @@ -736,8 +732,8 @@ static void xmb_draw_thumbnail( coords.tex_coord = NULL; coords.lut_tex_coord = NULL; - draw.width = w * scale_mod[4]; - draw.height = h * scale_mod[4]; + draw.width = w; + draw.height = h; draw.coords = &coords; draw.matrix_data = &mymat; draw.texture = texture; @@ -807,100 +803,6 @@ static void xmb_messagebox(void *data, const char *message) xmb->box_message = strdup(message); } -static void xmb_render_keyboard(xmb_handle_t *xmb, - video_frame_info_t *video_info, - const char *grid[], unsigned id) -{ - unsigned i; - int ptr_width, ptr_height; - unsigned width = video_info->width; - unsigned height = video_info->height; - float dark[16] = { - 0.00, 0.00, 0.00, 0.85, - 0.00, 0.00, 0.00, 0.85, - 0.00, 0.00, 0.00, 0.85, - 0.00, 0.00, 0.00, 0.85, - }; - - float white[16]= { - 1.00, 1.00, 1.00, 1.00, - 1.00, 1.00, 1.00, 1.00, - 1.00, 1.00, 1.00, 1.00, - 1.00, 1.00, 1.00, 1.00, - }; - - menu_display_draw_quad( - video_info, - 0, height/2.0, width, height/2.0, - width, height, - &dark[0]); - - ptr_width = width / 11; - ptr_height = height / 10; - - if (ptr_width >= ptr_height) - ptr_width = ptr_height; - - for (i = 0; i < 44; i++) - { - int line_y = (i / 11) * height / 10.0; - - if (i == id) - { - uintptr_t texture = xmb->textures.list[XMB_TEXTURE_KEY_HOVER]; - - menu_display_blend_begin(video_info); - - menu_display_draw_texture( - video_info, - width/2.0 - (11*ptr_width)/2.0 + (i % 11) * ptr_width, - height/2.0 + ptr_height*1.5 + line_y, - ptr_width, ptr_height, - width, height, - &white[0], - texture); - - menu_display_blend_end(video_info); - } - - menu_display_draw_text(xmb->font, grid[i], - width/2.0 - (11*ptr_width)/2.0 + (i % 11) * ptr_width + ptr_width/2.0, - height/2.0 + ptr_height + line_y + xmb->font->size / 3, - width, height, 0xffffffff, TEXT_ALIGN_CENTER, 1.0f, - false, 0); - } -} - -/* Returns the OSK key at a given position */ -static int xmb_osk_ptr_at_pos(void *data, int x, int y, unsigned width, unsigned height) -{ - unsigned i; - int ptr_width, ptr_height; - xmb_handle_t *xmb = (xmb_handle_t*)data; - - if (!xmb) - return -1; - - ptr_width = width / 11; - ptr_height = height / 10; - - if (ptr_width >= ptr_height) - ptr_width = ptr_height; - - for (i = 0; i < 44; i++) - { - int line_y = (i / 11)*height/10.0; - int ptr_x = width/2.0 - (11*ptr_width)/2.0 + (i % 11) * ptr_width; - int ptr_y = height/2.0 + ptr_height*1.5 + line_y - ptr_height; - - if (x > ptr_x && x < ptr_x + ptr_width - && y > ptr_y && y < ptr_y + ptr_height) - return i; - } - - return -1; -} - static void xmb_render_messagebox_internal( video_frame_info_t *video_info, xmb_handle_t *xmb, const char *message, float* coord_white) @@ -942,7 +844,7 @@ static void xmb_render_messagebox_internal( { longest = len; longest_width = font_driver_get_message_width( - xmb->font, msg, strlen(msg), 1); + xmb->font, msg, (unsigned)strlen(msg), 1); } } @@ -972,7 +874,9 @@ static void xmb_render_messagebox_internal( } if (menu_input_dialog_get_display_kb()) - xmb_render_keyboard(xmb, + menu_display_draw_keyboard( + xmb->textures.list[XMB_TEXTURE_KEY_HOVER], + xmb->font, video_info, menu_event_get_osk_grid(), menu_event_get_osk_ptr()); @@ -981,7 +885,7 @@ end: string_list_free(list); } -static void xmb_update_thumbnail_path(void *data, unsigned i) +static void xmb_update_thumbnail_path(void *data, unsigned i, char pos) { menu_entry_t entry; unsigned entry_type = 0; @@ -1006,7 +910,9 @@ static void xmb_update_thumbnail_path(void *data, unsigned i) 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))))) { if (!string_is_empty(entry.path)) fill_pathname_join( @@ -1024,7 +930,7 @@ static void xmb_update_thumbnail_path(void *data, unsigned i) goto end; } - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &playlist); + playlist = playlist_get_cached(); if (playlist) { @@ -1034,9 +940,21 @@ static void xmb_update_thumbnail_path(void *data, unsigned i) if (string_is_equal(core_name, "imageviewer")) { - if (!string_is_empty(entry.label)) - strlcpy(new_path, entry.label, - sizeof(new_path)); + if ( + (pos == 'R') || + ( + pos == 'L' && + string_is_equal(xmb_thumbnails_ident('R'), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) + ) + ) + { + if (!string_is_empty(entry.label)) + strlcpy(new_path, entry.label, + sizeof(new_path)); + } + else + xmb->left_thumbnail = 0; goto end; } } @@ -1056,9 +974,13 @@ static void xmb_update_thumbnail_path(void *data, unsigned i) tmp_new2[0] = '\0'; - /* Append Named_Snaps/Named_Boxart/Named_Titles */ - fill_pathname_join(tmp_new2, new_path, - xmb_thumbnails_ident(), PATH_MAX_LENGTH * sizeof(char)); + /* Append Named_Snaps/Named_Boxarts/Named_Titles */ + if (pos == 'R') + fill_pathname_join(tmp_new2, new_path, + xmb_thumbnails_ident('R'), PATH_MAX_LENGTH * sizeof(char)); + if (pos == 'L') + fill_pathname_join(tmp_new2, new_path, + xmb_thumbnails_ident('L'), PATH_MAX_LENGTH * sizeof(char)); strlcpy(new_path, tmp_new2, PATH_MAX_LENGTH * sizeof(char)); @@ -1104,7 +1026,13 @@ static void xmb_update_thumbnail_path(void *data, unsigned i) end: if (xmb && !string_is_empty(new_path)) - xmb->thumbnail_file_path = strdup(new_path); + { + if (pos == 'R') + xmb->thumbnail_file_path = strdup(new_path); + if (pos == 'L') + xmb->left_thumbnail_file_path = strdup(new_path); + } + menu_entry_free(&entry); } @@ -1170,17 +1098,32 @@ static void xmb_update_savestate_thumbnail_path(void *data, unsigned i) static void xmb_update_thumbnail_image(void *data) { xmb_handle_t *xmb = (xmb_handle_t*)data; - if (!xmb || string_is_empty(xmb->thumbnail_file_path)) + if (!xmb) return; - if (filestream_exists(xmb->thumbnail_file_path)) - task_push_image_load(xmb->thumbnail_file_path, - menu_display_handle_thumbnail_upload, NULL); - else - xmb->thumbnail = 0; + if (!(string_is_empty(xmb->thumbnail_file_path))) + { + if (filestream_exists(xmb->thumbnail_file_path)) + task_push_image_load(xmb->thumbnail_file_path, + menu_display_handle_thumbnail_upload, NULL); + else + xmb->thumbnail = 0; - free(xmb->thumbnail_file_path); - xmb->thumbnail_file_path = NULL; + free(xmb->thumbnail_file_path); + xmb->thumbnail_file_path = NULL; + } + + if (!(string_is_empty(xmb->left_thumbnail_file_path))) + { + if (filestream_exists(xmb->left_thumbnail_file_path)) + task_push_image_load(xmb->left_thumbnail_file_path, + menu_display_handle_left_thumbnail_upload, NULL); + else + xmb->left_thumbnail = 0; + + free(xmb->left_thumbnail_file_path); + xmb->left_thumbnail_file_path = NULL; + } } static void xmb_set_thumbnail_system(void *data, char*s, size_t len) @@ -1248,7 +1191,8 @@ static void xmb_selection_pointer_changed( menu_list_t *menu_list = NULL; file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); size_t selection = menu_navigation_get_selection(); - const char *thumb_ident = xmb_thumbnails_ident(); + const char *thumb_ident = xmb_thumbnails_ident('R'); + const char *lft_thumb_ident= xmb_thumbnails_ident('L'); menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); menu_entry_init(&entry); @@ -1290,32 +1234,62 @@ static void xmb_selection_pointer_changed( ia = xmb->items_active_alpha; iz = xmb->items_active_zoom; - if (!string_is_equal(thumb_ident, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) || !string_is_equal(lft_thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) { if ((xmb_system_tab > XMB_SYSTEM_TAB_SETTINGS && depth == 1) || - (xmb_system_tab < XMB_SYSTEM_TAB_SETTINGS && depth == 4)) + (xmb_system_tab < XMB_SYSTEM_TAB_SETTINGS && depth == 4)) { if (!string_is_empty(entry.path)) xmb_set_thumbnail_content(xmb, entry.path, 0 /* will be ignored */); - xmb_update_thumbnail_path(xmb, i); - xmb_update_thumbnail_image(xmb); + if (!string_is_equal(thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + xmb_update_thumbnail_path(xmb, i, 'R'); + xmb_update_thumbnail_image(xmb); + } + if (!string_is_equal(lft_thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + xmb_update_thumbnail_path(xmb, i, 'L'); + xmb_update_thumbnail_image(xmb); + } } else if (((entry_type == FILE_TYPE_IMAGE || entry_type == FILE_TYPE_IMAGEVIEWER || entry_type == FILE_TYPE_RDB || entry_type == FILE_TYPE_RDB_ENTRY) - && xmb_system_tab <= XMB_SYSTEM_TAB_SETTINGS)) + && xmb_system_tab <= XMB_SYSTEM_TAB_SETTINGS)) { if (!string_is_empty(entry.path)) xmb_set_thumbnail_content(xmb, entry.path, 0 /* will be ignored */); - xmb_update_thumbnail_path(xmb, i); - xmb_update_thumbnail_image(xmb); + if (!string_is_equal(thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + xmb_update_thumbnail_path(xmb, i, 'R'); + xmb_update_thumbnail_image(xmb); + } + else if (!string_is_equal(lft_thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + xmb_update_thumbnail_path(xmb, i, 'L'); + xmb_update_thumbnail_image(xmb); + } } else if (filebrowser_get_type() != FILEBROWSER_NONE) { xmb_reset_thumbnail_content(xmb); - xmb_update_thumbnail_path(xmb, i); - xmb_update_thumbnail_image(xmb); + if (!string_is_equal(thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + xmb_update_thumbnail_path(xmb, i, 'R'); + xmb_update_thumbnail_image(xmb); + } + else if (!string_is_equal(lft_thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + xmb_update_thumbnail_path(xmb, i, 'L'); + xmb_update_thumbnail_image(xmb); + } } } xmb_update_savestate_thumbnail_path(xmb, i); @@ -1324,7 +1298,7 @@ static void xmb_selection_pointer_changed( if ( (!allow_animations) || (real_iy < -threshold - || real_iy > height+threshold)) + || real_iy > height+threshold)) { node->alpha = node->label_alpha = ia; node->y = iy; @@ -1495,21 +1469,25 @@ static void xmb_list_open_new(xmb_handle_t *xmb, xmb->old_depth = xmb->depth; menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &skip); - xmb_system_tab = xmb_get_system_tab(xmb, (unsigned)xmb->categories_selection_ptr); + xmb_system_tab = xmb_get_system_tab(xmb, + (unsigned)xmb->categories_selection_ptr); if (xmb_system_tab <= XMB_SYSTEM_TAB_SETTINGS) { if (xmb->depth < 4) xmb_reset_thumbnail_content(xmb); - xmb_update_thumbnail_path(xmb, 0); + xmb_update_thumbnail_path(xmb, 0, 'R'); + xmb_update_thumbnail_image(xmb); + xmb_update_thumbnail_path(xmb, 0, 'L'); xmb_update_thumbnail_image(xmb); } } -static xmb_node_t *xmb_node_allocate_userdata(xmb_handle_t *xmb, unsigned i) +static xmb_node_t *xmb_node_allocate_userdata( + xmb_handle_t *xmb, unsigned i) { + xmb_node_t *tmp = NULL; xmb_node_t *node = xmb_alloc_node(); - xmb_node_t *tmp; if (!node) { @@ -1526,7 +1504,8 @@ static xmb_node_t *xmb_node_allocate_userdata(xmb_handle_t *xmb, unsigned i) node->zoom = xmb->categories_active_zoom; } - tmp = (xmb_node_t*)file_list_get_userdata_at_offset(xmb->horizontal_list, i); + tmp = (xmb_node_t*)file_list_get_userdata_at_offset( + xmb->horizontal_list, i); xmb_free_node(tmp); file_list_set_userdata(xmb->horizontal_list, i, node); @@ -1541,7 +1520,8 @@ static xmb_node_t* xmb_get_userdata_from_horizontal_list( file_list_get_userdata_at_offset(xmb->horizontal_list, i); } -static void xmb_push_animations(xmb_node_t *node, uintptr_t tag, float ia, float ix) +static void xmb_push_animations(xmb_node_t *node, + uintptr_t tag, float ia, float ix) { menu_animation_ctx_entry_t anim_entry; @@ -1567,16 +1547,16 @@ static void xmb_push_animations(xmb_node_t *node, uintptr_t tag, float ia, float static void xmb_list_switch_old(xmb_handle_t *xmb, file_list_t *list, int dir, size_t current) { - unsigned i, first, last, height; - size_t end = file_list_get_size(list); - float ix = -xmb->icon_spacing_horizontal * dir; - float ia = 0; - - first = 0; - last = end > 0 ? end - 1 : 0; + unsigned i, height; + size_t end = file_list_get_size(list); + float ix = -xmb->icon_spacing_horizontal * dir; + float ia = 0; + unsigned first = 0; + unsigned last = (unsigned)(end > 0 ? end - 1 : 0); video_driver_get_size(NULL, &height); - xmb_calculate_visible_range(xmb, height, end, current, &first, &last); + xmb_calculate_visible_range(xmb, height, end, + (unsigned)current, &first, &last); for (i = 0; i < end; i++) { @@ -1629,28 +1609,28 @@ static void xmb_list_switch_new(xmb_handle_t *xmb, fill_pathname_application_special(path, path_size, APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB_BG); - if(!string_is_equal(path, xmb->bg_file_path)) - { - if(filestream_exists(path)) - { - task_push_image_load(path, + if(!string_is_equal(path, xmb->bg_file_path)) + { + if(filestream_exists(path)) + { + task_push_image_load(path, menu_display_handle_wallpaper_upload, NULL); - if (!string_is_empty(xmb->bg_file_path)) - free(xmb->bg_file_path); - xmb->bg_file_path = strdup(path); - } - } + if (!string_is_empty(xmb->bg_file_path)) + free(xmb->bg_file_path); + xmb->bg_file_path = strdup(path); + } + } - free(path); + free(path); } end = file_list_get_size(list); first = 0; - last = end > 0 ? end - 1 : 0; + last = (unsigned)(end > 0 ? end - 1 : 0); video_driver_get_size(NULL, &height); - xmb_calculate_visible_range(xmb, height, end, current, &first, &last); + xmb_calculate_visible_range(xmb, height, end, (unsigned)current, &first, &last); for (i = 0; i < end; i++) { @@ -1695,7 +1675,8 @@ static void xmb_set_title(xmb_handle_t *xmb) if (!path) return; - fill_pathname_base_noext(xmb->title_name, path, sizeof(xmb->title_name)); + fill_pathname_base_noext( + xmb->title_name, path, sizeof(xmb->title_name)); } } @@ -1789,7 +1770,8 @@ 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 * -(float)xmb->categories_selection_ptr; + 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; /* TODO/FIXME - integer conversion resulted in change of sign */ @@ -1811,7 +1793,7 @@ static void xmb_list_switch(xmb_handle_t *xmb) xmb_list_switch_new(xmb, selection_buf, dir, selection); xmb->categories_active_idx_old = (unsigned)xmb->categories_selection_ptr; - if (!string_is_equal(xmb_thumbnails_ident(), + if (!string_is_equal(xmb_thumbnails_ident('R'), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) { menu_entry_t entry; @@ -1824,7 +1806,23 @@ static void xmb_list_switch(xmb_handle_t *xmb) menu_entry_free(&entry); - xmb_update_thumbnail_path(xmb, 0); + xmb_update_thumbnail_path(xmb, 0, 'R'); + xmb_update_thumbnail_image(xmb); + } + if (!string_is_equal(xmb_thumbnails_ident('L'), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + menu_entry_t entry; + + menu_entry_init(&entry); + menu_entry_get(&entry, 0, selection, NULL, true); + + if (!string_is_empty(entry.path)) + xmb_set_thumbnail_content(xmb, entry.path, 0 /* will be ignored */); + + menu_entry_free(&entry); + + xmb_update_thumbnail_path(xmb, 0, 'L'); xmb_update_thumbnail_image(xmb); } } @@ -1903,7 +1901,7 @@ static void xmb_init_horizontal_list(xmb_handle_t *xmb) info.type_default = FILE_TYPE_PLAIN; info.enum_idx = MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST; - if (!string_is_empty(info.path)) + if (settings->bools.menu_content_show_playlists && !string_is_empty(info.path)) { if (menu_displaylist_ctl(DISPLAYLIST_DATABASE_PLAYLISTS_HORIZONTAL, &info)) { @@ -1951,11 +1949,12 @@ static void xmb_context_reset_horizontal_list( size_t list_size = xmb_list_get_size(xmb, MENU_LIST_HORIZONTAL); - xmb->categories_x_pos = xmb->icon_spacing_horizontal * + xmb->categories_x_pos = + xmb->icon_spacing_horizontal * -(float)xmb->categories_selection_ptr; - depth = (xmb->depth > 1) ? 2 : 1; - xmb->x = xmb->icon_size * -(depth*2-2); + depth = (xmb->depth > 1) ? 2 : 1; + xmb->x = xmb->icon_size * -(depth*2-2); for (i = 0; i < list_size; i++) { @@ -1983,12 +1982,15 @@ static void xmb_context_reset_horizontal_list( { struct texture_image ti; char sysname[256]; - char *iconpath = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); - char *texturepath = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); - char *content_texturepath = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + char *iconpath = (char*) + malloc(PATH_MAX_LENGTH * sizeof(char)); + char *texturepath = (char*) + malloc(PATH_MAX_LENGTH * sizeof(char)); + char *content_texturepath = (char*) + malloc(PATH_MAX_LENGTH * sizeof(char)); iconpath[0] = sysname[0] = - texturepath[0] = content_texturepath[0] = '\0'; + texturepath[0] = content_texturepath[0] = '\0'; fill_pathname_base_noext(sysname, path, sizeof(sysname)); @@ -2055,7 +2057,8 @@ static void xmb_refresh_horizontal_list(xmb_handle_t *xmb) menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); - xmb->horizontal_list = (file_list_t*)calloc(1, sizeof(file_list_t)); + xmb->horizontal_list = (file_list_t*) + calloc(1, sizeof(file_list_t)); if (xmb->horizontal_list) xmb_init_horizontal_list(xmb); @@ -2159,10 +2162,13 @@ static void xmb_populate_entries(void *data, { xmb_selection_pointer_changed(xmb, false); menu_driver_ctl(RARCH_MENU_CTL_UNSET_PREVENT_POPULATE, NULL); - if (!string_is_equal(xmb_thumbnails_ident(), + if (!string_is_equal(xmb_thumbnails_ident('R'), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) xmb_update_thumbnail_image(xmb); xmb_update_savestate_thumbnail_image(xmb); + if (!string_is_equal(xmb_thumbnails_ident('L'), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + xmb_update_thumbnail_image(xmb); return; } @@ -2241,7 +2247,8 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, if (core_node) return core_node->content_icon; - switch (xmb_get_system_tab(xmb, (unsigned)xmb->categories_selection_ptr)) + switch (xmb_get_system_tab(xmb, + (unsigned)xmb->categories_selection_ptr)) { case XMB_SYSTEM_TAB_FAVORITES: return xmb->textures.list[XMB_TEXTURE_FAVORITE]; @@ -2259,6 +2266,9 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, break; } return xmb->textures.list[XMB_TEXTURE_FILE]; + case FILE_TYPE_SHADER: + case FILE_TYPE_SHADER_PRESET: + return xmb->textures.list[XMB_TEXTURE_SHADER_OPTIONS]; case FILE_TYPE_CARCHIVE: return xmb->textures.list[XMB_TEXTURE_ZIP]; case FILE_TYPE_MUSIC: @@ -2316,11 +2326,13 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, #ifdef HAVE_NETWORKING case MENU_ROOM: return xmb->textures.list[XMB_TEXTURE_ROOM]; - /* stub these out until we have the icons +#if 0 + /* stub these out until we have the icons */ case MENU_ROOM_LAN: return xmb->textures.list[XMB_TEXTURE_ROOM_LAN]; case MENU_ROOM_MITM: - return xmb->textures.list[XMB_TEXTURE_ROOM_MITM]; */ + return xmb->textures.list[XMB_TEXTURE_ROOM_MITM]; +#endif #endif } @@ -2349,13 +2361,14 @@ static void xmb_calculate_visible_range(const xmb_handle_t *xmb, float base_y = xmb->margins_screen_top; *first = 0; - *last = list_size ? list_size - 1 : 0; + *last = (unsigned)(list_size ? list_size - 1 : 0); if (current) { for (j = current; j-- > 0; ) { - float bottom = xmb_item_y(xmb, j, current) + base_y + xmb->icon_size; + float bottom = xmb_item_y(xmb, j, current) + + base_y + xmb->icon_size; if (bottom < 0) break; @@ -2384,6 +2397,7 @@ static int xmb_draw_item( file_list_t *list, float *color, const char *thumb_ident, + const char *left_thumb_ident, uint64_t frame_count, size_t i, size_t current, @@ -2402,6 +2416,7 @@ static int xmb_draw_item( unsigned ticker_limit = 35 * scale_mod[0]; xmb_node_t * node = (xmb_node_t*) file_list_get_userdata_at_offset(list, i); + settings_t *settings = config_get_ptr(); if (!node) goto iterate; @@ -2440,16 +2455,20 @@ static int xmb_draw_item( } } - if (string_is_equal(entry->value, msg_hash_to_str(MENU_ENUM_LABEL_DISABLED)) || - (string_is_equal(entry->value, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))) + if (string_is_equal(entry->value, + msg_hash_to_str(MENU_ENUM_LABEL_DISABLED)) || + (string_is_equal(entry->value, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))) { if (xmb->textures.list[XMB_TEXTURE_SWITCH_OFF]) texture_switch = xmb->textures.list[XMB_TEXTURE_SWITCH_OFF]; else do_draw_text = true; } - else if (string_is_equal(entry->value, msg_hash_to_str(MENU_ENUM_LABEL_ENABLED)) || - (string_is_equal(entry->value, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON)))) + else if (string_is_equal(entry->value, + msg_hash_to_str(MENU_ENUM_LABEL_ENABLED)) || + (string_is_equal(entry->value, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON)))) { if (xmb->textures.list[XMB_TEXTURE_SWITCH_ON]) texture_switch = xmb->textures.list[XMB_TEXTURE_SWITCH_ON]; @@ -2462,6 +2481,8 @@ static int xmb_draw_item( { if ( string_is_equal(entry->value, "...") || + string_is_equal(entry->value, "(PRESET)") || + string_is_equal(entry->value, "(SHADER)") || string_is_equal(entry->value, "(COMP)") || string_is_equal(entry->value, "(CORE)") || string_is_equal(entry->value, "(MOVIE)") || @@ -2476,7 +2497,7 @@ static int xmb_draw_item( { } else - do_draw_text = true; + do_draw_text = true; } else do_draw_text = true; @@ -2486,10 +2507,16 @@ static int xmb_draw_item( if (string_is_empty(entry->value)) { if (xmb->savestate_thumbnail || + !xmb->use_ps3_layout || (!string_is_equal (thumb_ident, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) - && xmb->thumbnail) + && xmb->thumbnail) || + (!string_is_equal + (left_thumb_ident, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) + && xmb->left_thumbnail + && settings->bools.menu_xmb_vertical_thumbnails) ) ticker_limit = 40 * scale_mod[1]; else @@ -2640,7 +2667,8 @@ static void xmb_draw_items( xmb_node_t *core_node = NULL; size_t end = 0; uint64_t frame_count = xmb ? xmb->frame_count : 0; - const char *thumb_ident = xmb_thumbnails_ident(); + const char *thumb_ident = xmb_thumbnails_ident('R'); + const char *left_thumb_ident= xmb_thumbnails_ident('L'); if (!list || !list->size || !xmb) return; @@ -2665,7 +2693,7 @@ static void xmb_draw_items( if (list == xmb->selection_buf_old) { xmb_node_t *node = (xmb_node_t*) - file_list_get_userdata_at_offset(list, current); + file_list_get_userdata_at_offset(list, current); if (node && (uint8_t)(255 * node->alpha) == 0) return; @@ -2673,10 +2701,10 @@ static void xmb_draw_items( i = 0; } - first = i; - last = end - 1; + first = (unsigned)i; + last = (unsigned)(end - 1); - xmb_calculate_visible_range(xmb, height, end, current, &first, &last); + xmb_calculate_visible_range(xmb, height, end, (unsigned)current, &first, &last); menu_display_blend_begin(video_info); @@ -2690,7 +2718,7 @@ static void xmb_draw_items( &entry, &mymat, xmb, core_node, - list, color, thumb_ident, + list, color, thumb_ident, left_thumb_ident, frame_count, i, current, width, height); @@ -2725,17 +2753,18 @@ static void xmb_render(void *data, bool is_idle) if (pointer_enable || mouse_enable) { + unsigned height; size_t selection = menu_navigation_get_selection(); int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS); int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS) + (xmb->cursor_size/2); unsigned first = 0, last = end; - unsigned height; video_driver_get_size(NULL, &height); if (height) - xmb_calculate_visible_range(xmb, height, end, selection, &first, &last); + xmb_calculate_visible_range(xmb, height, + end, (unsigned)selection, &first, &last); for (i = first; i <= last; i++) { @@ -2923,39 +2952,45 @@ static void xmb_draw_dark_layer( static void xmb_frame(void *data, video_frame_info_t *video_info) { - size_t selection; - size_t percent_width = 0; math_matrix_4x4 mymat; unsigned i; - float thumb_width, thumb_height; menu_display_ctx_rotate_draw_t rotate_draw; char msg[1024]; char title_msg[255]; char title_truncated[255]; - settings_t *settings = config_get_ptr(); - unsigned width = video_info->width; - unsigned height = video_info->height; + size_t selection = 0; + size_t percent_width = 0; + const int min_thumb_size = 50; bool render_background = false; file_list_t *selection_buf = NULL; + unsigned width = video_info->width; + unsigned height = video_info->height; + const float under_thumb_margin = 0.96; + float scale_factor = 0.0f; + float pseudo_font_length = 0.0f; xmb_handle_t *xmb = (xmb_handle_t*)data; + settings_t *settings = config_get_ptr(); if (!xmb) 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; + xmb->frame_count++; msg[0] = '\0'; title_msg[0] = '\0'; title_truncated[0] = '\0'; - font_driver_bind_block(xmb->font, &xmb->raster_block); + font_driver_bind_block(xmb->font, &xmb->raster_block); font_driver_bind_block(xmb->font2, &xmb->raster_block2); - xmb->raster_block.carr.coords.vertices = 0; + xmb->raster_block.carr.coords.vertices = 0; xmb->raster_block2.carr.coords.vertices = 0; menu_display_set_alpha(coord_black, MIN( - (float)video_info->xmb_alpha_factor/100, xmb->alpha)); + (float)video_info->xmb_alpha_factor/100, xmb->alpha)); menu_display_set_alpha(coord_white, xmb->alpha); xmb_draw_bg( @@ -2970,11 +3005,13 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) selection = menu_navigation_get_selection(); - strlcpy(title_truncated, xmb->title_name, sizeof(title_truncated)); + strlcpy(title_truncated, + xmb->title_name, sizeof(title_truncated)); + if (selection > 1) { /* skip 25 utf8 multi-byte chars */ - char* end = title_truncated; + char *end = title_truncated; for(i = 0; i < 25 && *end; i++) { @@ -3009,48 +3046,288 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) menu_display_rotate_z(&rotate_draw, video_info); menu_display_blend_begin(video_info); + /* Save State thumbnail, right side */ if (xmb->savestate_thumbnail) + { xmb_draw_thumbnail(video_info, xmb, &coord_white[0], width, height, - xmb->margins_screen_left * scale_mod[5] - + xmb->icon_spacing_horizontal + - xmb->icon_spacing_horizontal * 4 - xmb->icon_size / 4, - xmb->margins_screen_top + xmb->icon_size + xmb->savestate_thumbnail_height * scale_mod[4], - xmb->savestate_thumbnail_width, xmb->savestate_thumbnail_height, + xmb->margins_screen_left * scale_mod[5] + + xmb->icon_spacing_horizontal + pseudo_font_length, + xmb->margins_screen_top + xmb->icon_size + + xmb->savestate_thumbnail_height * scale_mod[4], + xmb->savestate_thumbnail_width * scale_mod[4], + xmb->savestate_thumbnail_height * scale_mod[4], xmb->savestate_thumbnail); - else if (xmb->thumbnail - && !string_is_equal(xmb_thumbnails_ident(), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + } + + /* Right thumbnail big size */ + if (xmb->use_ps3_layout && + (!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 + + xmb->icon_size + min_thumb_size) <= height) && + ((xmb->margins_screen_left * scale_mod[5] + + xmb->icon_spacing_horizontal + + pseudo_font_length + min_thumb_size) <= width)) + { + if (xmb->thumbnail + && !string_is_equal(xmb_thumbnails_ident('R'), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + /* Limit thumbnail width */ + + 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]) - + xmb->icon_spacing_horizontal - pseudo_font_length; + #ifdef XMB_DEBUG - RARCH_LOG("[XMB thumbnail] width: %.2f, height: %.2f\n", xmb->thumbnail_width, xmb->thumbnail_height); - RARCH_LOG("[XMB thumbnail] w: %.2f, h: %.2f\n", width, height); + RARCH_LOG("[XMB thumbnail] width: %.2f, height: %.2f\n", + xmb->thumbnail_width, xmb->thumbnail_height); + RARCH_LOG("[XMB thumbnail] w: %.2f, h: %.2f\n", width, height); #endif - /* Limit thumbnail height to screen height + margin. */ - if( xmb->margins_screen_top + xmb->icon_size + xmb->thumbnail_height * scale_mod[4] >= - (float)(height * 0.96) ) - { - thumb_width = xmb->thumbnail_width * - (((float)(height * 0.96) - xmb->margins_screen_top - xmb->icon_size) / - (xmb->thumbnail_height * scale_mod[4])); - thumb_height = xmb->thumbnail_height * - (((float)(height * 0.96) - xmb->margins_screen_top - xmb->icon_size) / - (xmb->thumbnail_height * scale_mod[4])); - } - else - { - thumb_width = xmb->thumbnail_width; - thumb_height = xmb->thumbnail_height; - } + if (xmb->thumbnail_width * scale_mod[4] > thumb_max_width) + { + thumb_width = (xmb->thumbnail_width * scale_mod[4]) * + (thumb_max_width / (xmb->thumbnail_width * scale_mod[4])); + thumb_height = (xmb->thumbnail_height * scale_mod[4]) * + (thumb_max_width / (xmb->thumbnail_width * scale_mod[4])); + } + else + { + thumb_width = xmb->thumbnail_width * scale_mod[4]; + thumb_height = xmb->thumbnail_height * scale_mod[4]; + } - xmb_draw_thumbnail(video_info, - xmb, &coord_white[0], width, height, - xmb->margins_screen_left * scale_mod[5] + xmb->icon_spacing_horizontal + - xmb->icon_spacing_horizontal*4 - xmb->icon_size / 4, - xmb->margins_screen_top + xmb->icon_size + thumb_height * scale_mod[4], - thumb_width, thumb_height, - xmb->thumbnail); + /* Limit thumbnail height to screen height + margin. */ + + if (xmb->margins_screen_top + xmb->icon_size + thumb_height >= + ((float)height * under_thumb_margin)) + { + thumb_width = thumb_width * + ((((float)height * under_thumb_margin) - + xmb->margins_screen_top - xmb->icon_size) / + thumb_height); + thumb_height = thumb_height * + ((((float)height * under_thumb_margin) - + xmb->margins_screen_top - xmb->icon_size) / + thumb_height); + } + + xmb_draw_thumbnail(video_info, + xmb, &coord_white[0], width, height, + (float)width - (xmb->icon_size / 6) - thumb_max_width + + ((thumb_max_width - thumb_width) / 2), + xmb->margins_screen_top + xmb->icon_size + thumb_height, + thumb_width, thumb_height, + xmb->thumbnail); + } + } + } + + /* Left thumbnail in the left margin */ + /* Do not draw the left thumbnail if there is no space available */ + if (xmb->use_ps3_layout && + !settings->bools.menu_xmb_vertical_thumbnails && + (xmb->margins_screen_top + xmb->icon_size * + (!(xmb->depth == 1)? 2.1 : 1) + min_thumb_size) + <= (float)height) + { + /* Left Thumbnail in the left margin */ + + if (xmb->left_thumbnail + && !string_is_equal(xmb_thumbnails_ident('L'), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + /* Limit left thumbnail width */ + + float left_thumb_width = 0.0f; + float left_thumb_height = 0.0f; + float thumb_max_width = xmb->icon_size * 3.4; + +#ifdef XMB_DEBUG + RARCH_LOG("[XMB left thumbnail] width: %.2f, height: %.2f\n", + xmb->left_thumbnail_width, xmb->left_thumbnail_height); + RARCH_LOG("[XMB left thumbnail] w: %.2f, h: %.2f\n", width, height); +#endif + + if (xmb->left_thumbnail_width * scale_mod[4] > thumb_max_width) + { + left_thumb_width = (xmb->left_thumbnail_width * scale_mod[4]) * + (thumb_max_width / (xmb->left_thumbnail_width * scale_mod[4])); + left_thumb_height = (xmb->left_thumbnail_height * scale_mod[4]) * + (thumb_max_width / (xmb->left_thumbnail_width * scale_mod[4])); + } + else + { + left_thumb_width = xmb->left_thumbnail_width * scale_mod[4]; + left_thumb_height = xmb->left_thumbnail_height * scale_mod[4]; + } + + /* Limit left thumbnail height to screen height + margin. */ + if (xmb->margins_screen_top + xmb->icon_size * + (!(xmb->depth == 1)? 2.1 : 1) + + left_thumb_height >= + ((float)height - (96.0 * scale_factor))) + { + left_thumb_width = left_thumb_width * + ((((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)) + - xmb->margins_screen_top - + (xmb->icon_size * (!(xmb->depth == 1)? 2.1 : 1))) / + left_thumb_height); + } + + xmb_draw_thumbnail(video_info, + xmb, &coord_white[0], width, height, + (xmb->icon_size / 6) + + ((thumb_max_width - left_thumb_width) / 2), + 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); + } + } + + /* No Right Thumbnail, draw only the left one big size */ + if (xmb->use_ps3_layout && + settings->bools.menu_xmb_vertical_thumbnails && !xmb->thumbnail) + { + /* Do not draw the left thumbnail if there is no space available */ + + if (((xmb->margins_screen_top + + xmb->icon_size + min_thumb_size) <= height) && + ((xmb->margins_screen_left * scale_mod[5] + + xmb->icon_spacing_horizontal + + pseudo_font_length + min_thumb_size) <= width)) + { + if (xmb->left_thumbnail + && !string_is_equal(xmb_thumbnails_ident('L'), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + /* Limit left thumbnail width */ + + float left_thumb_width = 0.0f; + float left_thumb_height = 0.0f; + 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 + RARCH_LOG("[XMB thumbnail] width: %.2f, height: %.2f\n", + xmb->thumbnail_width, xmb->thumbnail_height); + RARCH_LOG("[XMB thumbnail] w: %.2f, h: %.2f\n", width, height); +#endif + + if (xmb->left_thumbnail_width * scale_mod[4] > thumb_max_width) + { + left_thumb_width = (xmb->left_thumbnail_width * scale_mod[4]) * + (thumb_max_width / (xmb->left_thumbnail_width * scale_mod[4])); + left_thumb_height = (xmb->left_thumbnail_height * scale_mod[4]) * + (thumb_max_width / (xmb->left_thumbnail_width * scale_mod[4])); + } + else + { + left_thumb_width = xmb->left_thumbnail_width * scale_mod[4]; + left_thumb_height = xmb->left_thumbnail_height * scale_mod[4]; + } + + /* Limit left thumbnail height to screen height + margin. */ + + if (xmb->margins_screen_top + xmb->icon_size + left_thumb_height >= + ((float)height * under_thumb_margin)) + { + left_thumb_width = left_thumb_width * + ((((float)height * under_thumb_margin) - + xmb->margins_screen_top - xmb->icon_size) / + left_thumb_height); + left_thumb_height = left_thumb_height * + ((((float)height * under_thumb_margin) - + xmb->margins_screen_top - xmb->icon_size) / + left_thumb_height); + } + + xmb_draw_thumbnail(video_info, + xmb, &coord_white[0], width, height, + (float)width - (xmb->icon_size / 6) - thumb_max_width + + ((thumb_max_width - left_thumb_width) / 2), + xmb->margins_screen_top + xmb->icon_size + left_thumb_height, + left_thumb_width, left_thumb_height, + xmb->left_thumbnail); + } + } + } + + /* PSP Layout Only - Left thumbnail in the left margin */ + /* Do not draw the left thumbnail if there is no space available */ + if (!xmb->use_ps3_layout && + (xmb->margins_screen_top + xmb->icon_size * 1.5) + <= (float)height) + { + /* Left Thumbnail in the left margin */ + + if (xmb->left_thumbnail + && !string_is_equal(xmb_thumbnails_ident('L'), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + /* Limit left thumbnail width */ + + float left_thumb_width = 0.0f; + float left_thumb_height = 0.0f; + float thumb_max_width = xmb->icon_size * 2.4; + +#ifdef XMB_DEBUG + RARCH_LOG("[XMB left thumbnail] width: %.2f, height: %.2f\n", + xmb->left_thumbnail_width, xmb->left_thumbnail_height); + RARCH_LOG("[XMB left thumbnail] w: %.2f, h: %.2f\n", width, height); +#endif + + if (xmb->left_thumbnail_width > thumb_max_width) + { + left_thumb_width = xmb->left_thumbnail_width * + (thumb_max_width / xmb->left_thumbnail_width); + left_thumb_height = xmb->left_thumbnail_height * + (thumb_max_width / xmb->left_thumbnail_width); + } + else + { + left_thumb_width = xmb->left_thumbnail_width; + left_thumb_height = xmb->left_thumbnail_height; + } + + /* Limit left thumbnail height to screen height + margin. */ + if (xmb->margins_screen_top + xmb->icon_size + + left_thumb_height >= ((float)height - (xmb->icon_size * 0.5))) + { + left_thumb_width = left_thumb_width * + (((float)height - (xmb->icon_size * 0.5) - + xmb->margins_screen_top - xmb->icon_size) / + left_thumb_height); + + left_thumb_height = left_thumb_height * + (((float)height - (xmb->icon_size * 0.5) - + xmb->margins_screen_top - xmb->icon_size) / + left_thumb_height); + } + + xmb_draw_thumbnail(video_info, + 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, + left_thumb_width, left_thumb_height, + xmb->left_thumbnail); + } } /* Clock image */ @@ -3099,7 +3376,9 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) snprintf(msg, sizeof(msg), "%d%%", percent); - percent_width = (unsigned)font_driver_get_message_width(xmb->font, msg, (unsigned)strlen(msg), 1); + percent_width = (unsigned) + font_driver_get_message_width( + xmb->font, msg, (unsigned)strlen(msg), 1); xmb_draw_text(video_info, xmb, msg, width - xmb->margins_title_left - x_pos, @@ -3154,7 +3433,8 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) } /* Arrow image */ - menu_display_set_alpha(coord_white, MIN(xmb->textures_arrow_alpha, xmb->alpha)); + menu_display_set_alpha(coord_white, + MIN(xmb->textures_arrow_alpha, xmb->alpha)); if (coord_white[3] != 0) xmb_draw_icon(video_info, @@ -3162,7 +3442,8 @@ 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_size / 2.0 + xmb->icon_size, + xmb->icon_spacing_horizontal - + xmb->icon_size / 2.0 + xmb->icon_size, xmb->margins_screen_top + xmb->icon_size / 2.0 + xmb->icon_spacing_vertical * xmb->active_item_factor, @@ -3178,7 +3459,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) /* Horizontal tab icons */ for (i = 0; i <= xmb_list_get_size(xmb, MENU_LIST_HORIZONTAL) - + xmb->system_tab_end; i++) + + xmb->system_tab_end; i++) { xmb_node_t *node = xmb_get_node(xmb, i); @@ -3193,9 +3474,11 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) math_matrix_4x4 mymat; uintptr_t texture = node->icon; float x = xmb->x + xmb->categories_x_pos + - xmb->margins_screen_left + - xmb->icon_spacing_horizontal * (i + 1) - xmb->icon_size / 2.0; - float y = xmb->margins_screen_top + xmb->icon_size / 2.0; + xmb->margins_screen_left + + xmb->icon_spacing_horizontal + * (i + 1) - xmb->icon_size / 2.0; + float y = xmb->margins_screen_top + + xmb->icon_size / 2.0; float rotation = 0; float scale_factor = node->zoom; @@ -3224,6 +3507,141 @@ 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 (xmb->use_ps3_layout && + xmb->left_thumbnail && xmb->thumbnail && + settings->bools.menu_xmb_vertical_thumbnails) + { + /* Do not draw the right thumbnail if there is no space available */ + if (((xmb->margins_screen_top + + xmb->icon_size + min_thumb_size) <= height) && + ((xmb->margins_screen_left * scale_mod[5] + + xmb->icon_spacing_horizontal + + pseudo_font_length + min_thumb_size) <= width)) + { + if (xmb->thumbnail && + !string_is_equal(xmb_thumbnails_ident('R'), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + /* Limit right thumbnail width */ + + 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]) - + xmb->icon_spacing_horizontal - pseudo_font_length; + +#ifdef XMB_DEBUG + RARCH_LOG("[XMB thumbnail] width: %.2f, height: %.2f\n", + xmb->thumbnail_width, xmb->thumbnail_height); + RARCH_LOG("[XMB thumbnail] w: %.2f, h: %.2f\n", width, height); +#endif + + if (xmb->thumbnail_width * scale_mod[4] > thumb_max_width) + { + thumb_width = (xmb->thumbnail_width * scale_mod[4]) * + (thumb_max_width / (xmb->thumbnail_width * scale_mod[4])); + thumb_height = (xmb->thumbnail_height * scale_mod[4]) * + (thumb_max_width / (xmb->thumbnail_width * scale_mod[4])); + } + else + { + thumb_width = xmb->thumbnail_width * scale_mod[4]; + thumb_height = xmb->thumbnail_height * scale_mod[4]; + } + + /* Limit right thumbnail height to usable area. */ + + if (thumb_height >= + ((float)height - ((xmb->icon_size / 6) * 2) - xmb->icon_size) / 2) + { + thumb_width = thumb_width * + ((((float)height - ((xmb->icon_size / 6) * 2) - xmb->icon_size) / 2) / + thumb_height); + thumb_height = thumb_height * + ((((float)height - ((xmb->icon_size / 6) * 2) - xmb->icon_size) / 2) / + thumb_height); + } + + xmb_draw_thumbnail(video_info, + xmb, &coord_white[0], width, height, + (float)width - (xmb->icon_size / 6) - thumb_max_width + + ((thumb_max_width - thumb_width) / 2), + xmb->icon_size + ((((float)height / 2 - + (xmb->icon_size + (xmb->icon_size/12))) - thumb_height) / 2) + + thumb_height, + thumb_width, thumb_height, + xmb->thumbnail); + } + } + + /* Do not draw the left thumbnail if there is no space available */ + + if (((xmb->margins_screen_top + + xmb->icon_size + min_thumb_size) <= height) && + ((xmb->margins_screen_left * scale_mod[5] + + xmb->icon_spacing_horizontal + + pseudo_font_length + min_thumb_size) <= width)) + { + if (xmb->left_thumbnail && + !string_is_equal(xmb_thumbnails_ident('L'), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + { + /* Limit left thumbnail width */ + + float left_thumb_width = 0.0f; + float left_thumb_height = 0.0f; + 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 + RARCH_LOG("[XMB left thumbnail] width: %.2f, height: %.2f\n", + xmb->left_thumbnail_width, xmb->left_thumbnail_height); + RARCH_LOG("[XMB left thumbnail] w: %.2f, h: %.2f\n", width, height); +#endif + + if (xmb->left_thumbnail_width * scale_mod[4] > thumb_max_width) + { + left_thumb_width = (xmb->left_thumbnail_width * scale_mod[4]) * + (thumb_max_width / (xmb->left_thumbnail_width * scale_mod[4])); + left_thumb_height = (xmb->left_thumbnail_height * scale_mod[4]) * + (thumb_max_width / (xmb->left_thumbnail_width * scale_mod[4])); + } + else + { + left_thumb_width = xmb->left_thumbnail_width * scale_mod[4]; + left_thumb_height = xmb->left_thumbnail_height * scale_mod[4]; + } + + /* Limit left thumbnail height to usable area. */ + + if (left_thumb_height >= + ((float)height - ((xmb->icon_size / 6) * 2) - xmb->icon_size) / 2) + { + left_thumb_width = left_thumb_width * + ((((float)height - ((xmb->icon_size / 6) * 2) - xmb->icon_size) / 2) / + left_thumb_height); + left_thumb_height = left_thumb_height * + ((((float)height - ((xmb->icon_size / 6) * 2) - xmb->icon_size) / 2) / + left_thumb_height); + } + + xmb_draw_thumbnail(video_info, + xmb, &coord_white[0], width, height, + (float)width - (xmb->icon_size / 6) - thumb_max_width + + ((thumb_max_width - left_thumb_width) / 2), + xmb->icon_size + + (((float)height - ((xmb->icon_size / 6) * 2) - xmb->icon_size) / 2) + + (((((float)height - ((xmb->icon_size / 6) * 2) - xmb->icon_size) / 2) - + left_thumb_height) / 2) + left_thumb_height, + left_thumb_width, left_thumb_height, + xmb->left_thumbnail); + } + } + } + menu_display_blend_end(video_info); /* Vertical icons */ @@ -3234,7 +3652,8 @@ 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_old, + ? xmb->categories_selection_ptr : + xmb->categories_selection_ptr_old, &item_color[0], width, height); @@ -3333,7 +3752,8 @@ static void xmb_layout_ps3(xmb_handle_t *xmb, int width) new_header_height = 128.0 * scale_factor; - xmb->thumbnail_width = 460.0 * scale_factor; + xmb->thumbnail_width = 1024.0 * scale_factor; + xmb->left_thumbnail_width = 1024.0 * scale_factor; xmb->savestate_thumbnail_width= 460.0 * scale_factor; xmb->cursor_size = 64.0 * scale_factor; @@ -3358,20 +3778,6 @@ static void xmb_layout_ps3(xmb_handle_t *xmb, int width) xmb->icon_size = 128.0 * scale_factor; xmb->font_size = new_font_size; -#ifdef XMB_DEBUG - RARCH_LOG("[XMB] margin screen left: %.2f\n", xmb->margins_screen_left); - RARCH_LOG("[XMB] margin screen top: %.2f\n", xmb->margins_screen_top); - RARCH_LOG("[XMB] margin title left: %.2f\n", xmb->margins_title_left); - RARCH_LOG("[XMB] margin title top: %.2f\n", xmb->margins_title_top); - RARCH_LOG("[XMB] margin title bott: %.2f\n", xmb->margins_title_bottom); - RARCH_LOG("[XMB] margin label left: %.2f\n", xmb->margins_label_left); - RARCH_LOG("[XMB] margin label top: %.2f\n", xmb->margins_label_top); - RARCH_LOG("[XMB] margin sett left: %.2f\n", xmb->margins_setting_left); - RARCH_LOG("[XMB] icon spacing hor: %.2f\n", xmb->icon_spacing_horizontal); - RARCH_LOG("[XMB] icon spacing ver: %.2f\n", xmb->icon_spacing_vertical); - RARCH_LOG("[XMB] icon size: %.2f\n", xmb->icon_size); -#endif - menu_display_set_header_height(new_header_height); } @@ -3381,9 +3787,9 @@ static void xmb_layout_psp(xmb_handle_t *xmb, int width) settings_t *settings = config_get_ptr(); float scale_factor = ((settings->uints.menu_xmb_scale_factor * width) / (1920.0 * 100)) * 1.5; - #ifdef _3DS - scale_factor = settings->uints.menu_xmb_scale_factor / 400.0; + scale_factor = + settings->uints.menu_xmb_scale_factor / 400.0; #endif xmb->above_subitem_offset = 1.5; @@ -3409,6 +3815,7 @@ static void xmb_layout_psp(xmb_handle_t *xmb, int width) xmb->margins_screen_top = (256+32) * scale_factor; xmb->thumbnail_width = 460.0 * scale_factor; + xmb->left_thumbnail_width = 400.0 * scale_factor; xmb->savestate_thumbnail_width= 460.0 * scale_factor; xmb->cursor_size = 64.0; @@ -3427,6 +3834,49 @@ static void xmb_layout_psp(xmb_handle_t *xmb, int width) xmb->icon_size = 128.0 * scale_factor; xmb->font_size = new_font_size; + menu_display_set_header_height(new_header_height); +} + +static void xmb_layout(xmb_handle_t *xmb) +{ + unsigned width, height, i, current, end; + settings_t *settings = config_get_ptr(); + file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); + size_t selection = menu_navigation_get_selection(); + + video_driver_get_size(&width, &height); + + switch (settings->uints.menu_xmb_layout) + { + /* Automatic */ + case 0: + { + xmb->use_ps3_layout = false; + xmb->use_ps3_layout = width > 320 && height > 240; + + /* Mimic the layout of the PSP instead of the PS3 on tiny screens */ + if (xmb->use_ps3_layout) + xmb_layout_ps3(xmb, width); + else + xmb_layout_psp(xmb, width); + } + break; + /* PS3 */ + case 1: + { + xmb->use_ps3_layout = true; + xmb_layout_ps3(xmb, width); + } + break; + /* PSP */ + case 2: + { + xmb->use_ps3_layout = false; + xmb_layout_psp(xmb, width); + } + break; + } + #ifdef XMB_DEBUG RARCH_LOG("[XMB] margin screen left: %.2f\n", xmb->margins_screen_left); RARCH_LOG("[XMB] margin screen top: %.2f\n", xmb->margins_screen_top); @@ -3441,30 +3891,13 @@ static void xmb_layout_psp(xmb_handle_t *xmb, int width) RARCH_LOG("[XMB] icon size: %.2f\n", xmb->icon_size); #endif - menu_display_set_header_height(new_header_height); -} - -static void xmb_layout(xmb_handle_t *xmb) -{ - unsigned width, height, i, current, end; - file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); - size_t selection = menu_navigation_get_selection(); - - video_driver_get_size(&width, &height); - - /* Mimic the layout of the PSP instead of the PS3 on tiny screens */ - if (width > 320 && height > 240) - xmb_layout_ps3(xmb, width); - else - xmb_layout_psp(xmb, width); - current = (unsigned)selection; end = (unsigned)menu_entries_get_size(); for (i = 0; i < end; i++) { - float ia = xmb->items_passive_alpha; - float iz = xmb->items_passive_zoom; + float ia = xmb->items_passive_alpha; + float iz = xmb->items_passive_zoom; xmb_node_t *node = (xmb_node_t*)file_list_get_userdata_at_offset( selection_buf, i); @@ -3565,16 +3998,28 @@ static void *xmb_init(void **userdata, bool video_is_threaded) menu_handle_t *menu = (menu_handle_t*)calloc(1, sizeof(*menu)); float scale_value = settings->uints.menu_xmb_scale_factor; + /* scaling multiplier formulas made from these values: */ + /* xmb_scale 50 = {2.5, 2.5, 2, 1.7, 2.5, 4, 2.4, 2.5} */ + /* xmb_scale 75 = { 2, 1.6, 1.6, 1.4, 1.5, 2.3, 1.9, 1.3} */ + if (scale_value < 100) { - scale_mod[0] = -0.03 * scale_value + 4.083333; + /* text length & word wrap (base 35 apply to file browser, 1st column) */ + scale_mod[0] = -0.03 * scale_value + 4.083; + /* playlist text length when thumbnail is ON (small, base 40) */ scale_mod[1] = -0.03 * scale_value + 3.95; - scale_mod[2] = -0.02 * scale_value + 3.033333; - scale_mod[3] = -0.014 * scale_value + 2.416667; - scale_mod[4] = -0.03 * scale_value + 3.916667; - scale_mod[5] = -0.06 * scale_value + 6.933333; - scale_mod[6] = -0.028 * scale_value + 3.866667; - scale_mod[7] = 134.179 * pow(scale_value, -1.077852); + /* playlist text length when thumbnail is OFF (large, base 70) */ + scale_mod[2] = -0.02 * scale_value + 3.033; + /* sub-label length & word wrap */ + scale_mod[3] = -0.014 * scale_value + 2.416; + /* thumbnail size & vertical margin from top */ + scale_mod[4] = -0.03 * scale_value + 3.916; + /* thumbnail horizontal left margin (horizontal positioning) */ + scale_mod[5] = -0.06 * scale_value + 6.933; + /* margin before 2nd column start (shaders parameters, cheats...) */ + scale_mod[6] = -0.028 * scale_value + 3.866; + /* text length & word wrap (base 35 apply to 2nd column in cheats, shaders, etc) */ + scale_mod[7] = 134.179 * pow(scale_value, -1.0778); for (i = 0; i < 8; i++) if (scale_mod[i] < 1) @@ -3601,7 +4046,7 @@ static void *xmb_init(void **userdata, bool video_is_threaded) if (!xmb->selection_buf_old) goto error; - xmb->categories_active_idx = 0; + xmb->categories_active_idx = 0; xmb->categories_active_idx_old = 0; xmb->x = 0; xmb->categories_x_pos = 0; @@ -3710,6 +4155,8 @@ static void xmb_free(void *data) free(xmb->savestate_thumbnail_file_path); if (!string_is_empty(xmb->thumbnail_file_path)) free(xmb->thumbnail_file_path); + if (!string_is_empty(xmb->left_thumbnail_file_path)) + free(xmb->left_thumbnail_file_path); if (!string_is_empty(xmb->bg_file_path)) free(xmb->bg_file_path); } @@ -3754,6 +4201,16 @@ static bool xmb_load_image(void *userdata, void *data, enum menu_image_type type TEXTURE_FILTER_MIPMAP_LINEAR, &xmb->thumbnail); } break; + case MENU_IMAGE_LEFT_THUMBNAIL: + { + struct texture_image *img = (struct texture_image*)data; + xmb->left_thumbnail_height = xmb->left_thumbnail_width + * (float)img->height / (float)img->width; + video_driver_texture_unload(&xmb->left_thumbnail); + video_driver_texture_load(data, + TEXTURE_FILTER_MIPMAP_LINEAR, &xmb->left_thumbnail); + } + break; case MENU_IMAGE_SAVESTATE_THUMBNAIL: { struct texture_image *img = (struct texture_image*)data; @@ -3876,12 +4333,13 @@ static const char *xmb_texture_path(unsigned id) return "netplay.png"; case XMB_TEXTURE_ROOM: return "room.png"; - /* stub these out until we have the icons +#if 0 + /* stub these out until we have the icons */ case XMB_TEXTURE_ROOM_LAN: return "room_lan.png"; case XMB_TEXTURE_ROOM_MITM: return "room_mitm.png"; - */ +#endif #endif case XMB_TEXTURE_KEY: return "key.png"; @@ -4008,7 +4466,10 @@ static void xmb_context_reset(void *data, bool is_threaded) xmb_context_reset_background(iconpath); xmb_context_reset_horizontal_list(xmb); - if (!string_is_equal(xmb_thumbnails_ident(), + if (!string_is_equal(xmb_thumbnails_ident('R'), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) + xmb_update_thumbnail_image(xmb); + if (!string_is_equal(xmb_thumbnails_ident('R'), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) xmb_update_thumbnail_image(xmb); xmb_update_savestate_thumbnail_image(xmb); @@ -4179,7 +4640,7 @@ static void xmb_list_cache(void *data, enum menu_list_type type, unsigned action xmb->selection_ptr_old = selection; xmb_calculate_visible_range(xmb, height, selection_buf->size, - xmb->selection_ptr_old, &first, &last); + (unsigned)xmb->selection_ptr_old, &first, &last); xmb_list_deep_copy(selection_buf, xmb->selection_buf_old, first, last); @@ -4316,6 +4777,7 @@ static void xmb_context_destroy(void *data) video_driver_texture_unload(&xmb->textures.list[i]); video_driver_texture_unload(&xmb->thumbnail); + video_driver_texture_unload(&xmb->left_thumbnail); video_driver_texture_unload(&xmb->savestate_thumbnail); xmb_context_destroy_horizontal_list(xmb); @@ -4368,7 +4830,7 @@ static void xmb_toggle(void *userdata, bool menu_on) static int deferred_push_content_actions(menu_displaylist_info_t *info) { if (!menu_displaylist_ctl( - DISPLAYLIST_HORIZONTAL_CONTENT_ACTIONS, info)) + DISPLAYLIST_HORIZONTAL_CONTENT_ACTIONS, info)) return -1; menu_displaylist_process(info); menu_displaylist_info_free(info); @@ -4406,7 +4868,7 @@ static int xmb_list_push(void *data, void *userdata, { menu_displaylist_ctx_parse_entry_t entry; int ret = -1; - int i = 0; + unsigned i = 0; core_info_list_t *list = NULL; menu_handle_t *menu = (menu_handle_t*)data; @@ -4509,7 +4971,7 @@ static int xmb_list_push(void *data, void *userdata, if (subsystem) { - for (i = 0; i < system->subsystem.size; i++, subsystem++) + for (i = 0; i < (unsigned)system->subsystem.size; i++, subsystem++) { char s[PATH_MAX_LENGTH]; if (content_get_subsystem() == i) @@ -4732,7 +5194,7 @@ menu_ctx_driver_t menu_ctx_xmb = { xmb_update_thumbnail_image, xmb_set_thumbnail_system, xmb_set_thumbnail_content, - xmb_osk_ptr_at_pos, + menu_display_osk_ptr_at_pos, xmb_update_savestate_thumbnail_path, xmb_update_savestate_thumbnail_image }; diff --git a/menu/drivers/xui.cpp b/menu/drivers/xui.cpp index 0d4c8767d0..3f8adff87d 100644 --- a/menu/drivers/xui.cpp +++ b/menu/drivers/xui.cpp @@ -15,6 +15,8 @@ * If not, see . */ +#define CINTERFACE + #include #include #include @@ -47,6 +49,7 @@ #include "../../gfx/drivers/d3d.h" #include "../../gfx/common/d3d_common.h" +#include "../../gfx/common/d3d9_common.h" #define XUI_CONTROL_NAVIGATE_OK (XUI_CONTROL_NAVIGATE_RIGHT + 1) @@ -236,7 +239,7 @@ HRESULT XuiTextureLoader(IXuiDevice *pDevice, LPCWSTR szFileName, D3DX_DEFAULT_NONPOW2, 1, D3DUSAGE_CPU_CACHED_MEMORY, - (D3DFORMAT)d3d_get_argb8888_format(), + (D3DFORMAT)d3d9_get_argb8888_format(), D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_FILTER_NONE, @@ -276,7 +279,7 @@ void d3d9_make_d3dpp(void *data, const video_info_t *info, void *_d3dpp); static void* xui_init(void **userdata, bool video_is_threaded) { HRESULT hr; - d3d_video_t *d3d = NULL; + d3d9_video_t *d3d = NULL; D3DPRESENT_PARAMETERS d3dpp = {0}; video_info_t video_info = {0}; TypefaceDescriptor typeface = {0}; @@ -286,7 +289,7 @@ static void* xui_init(void **userdata, bool video_is_threaded) if (!menu) return NULL; - d3d = (d3d_video_t*)video_driver_get_ptr(false); + d3d = (d3d9_video_t*)video_driver_get_ptr(false); if (d3d->resolution_hd_enable) RARCH_LOG("HD menus enabled.\n"); @@ -376,7 +379,7 @@ static void xui_render_message(const char *msg) size_t i = 0; size_t j = 0; struct string_list *list = NULL; - d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(false); + d3d9_video_t *d3d = (d3d9_video_t*)video_driver_get_ptr(false); if (!d3d) return; @@ -415,7 +418,7 @@ static void xui_frame(void *data, video_frame_info_t *video_info) D3DXMATRIX matOrigView; const char *message = NULL; D3DVIEWPORT9 vp_full = {0}; - d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(false); + d3d9_video_t *d3d = (d3d9_video_t*)video_driver_get_ptr(false); if (!d3d) return; diff --git a/menu/drivers/zarch.c b/menu/drivers/zarch.c index 609341055f..495f1eab7d 100644 --- a/menu/drivers/zarch.c +++ b/menu/drivers/zarch.c @@ -1084,7 +1084,7 @@ static bool zarch_load_image(void *userdata, &zui->textures.bg); break; case MENU_IMAGE_THUMBNAIL: - break; + case MENU_IMAGE_LEFT_THUMBNAIL: case MENU_IMAGE_SAVESTATE_THUMBNAIL: /* TODO/FIXME -implement */ break; diff --git a/menu/drivers_display/menu_display_d3d10.c b/menu/drivers_display/menu_display_d3d10.c new file mode 100644 index 0000000000..7579fc8791 --- /dev/null +++ b/menu/drivers_display/menu_display_d3d10.c @@ -0,0 +1,289 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2018 - Daniel De Matteis + * Copyright (C) 2014-2018 - Ali Bouhlel + * + * 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 . + */ + +#define CINTERFACE + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "../menu_driver.h" + +#include "../../retroarch.h" +#include "../../gfx/font_driver.h" +#include "../../gfx/video_driver.h" +#include "../../gfx/common/d3d10_common.h" + +static const float* menu_display_d3d10_get_default_vertices(void) +{ + return NULL; +} + +static const float* menu_display_d3d10_get_default_tex_coords(void) +{ + return NULL; +} + +static void* menu_display_d3d10_get_default_mvp(video_frame_info_t *video_info) +{ + return NULL; +} + +static void menu_display_d3d10_blend_begin(video_frame_info_t *video_info) +{ + d3d10_video_t* d3d10 = video_info ? (d3d10_video_t*)video_info->userdata : NULL; + D3D10SetBlendState(d3d10->device, + d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK); +} + +static void menu_display_d3d10_blend_end(video_frame_info_t *video_info) +{ + d3d10_video_t* d3d10 = video_info ? (d3d10_video_t*)video_info->userdata : NULL; + D3D10SetBlendState(d3d10->device, + d3d10->blend_disable, NULL, D3D10_DEFAULT_SAMPLE_MASK); +} + +static void menu_display_d3d10_viewport(void* data, video_frame_info_t *video_info) +{ +} + +static void menu_display_d3d10_draw(void* data, video_frame_info_t *video_info) +{ + int vertex_count; + d3d10_video_t* d3d10 = video_info ? (d3d10_video_t*)video_info->userdata : NULL; + menu_display_ctx_draw_t* draw = (menu_display_ctx_draw_t*)data; + + if (!d3d10 || !draw || !draw->texture) + return; + + switch (draw->pipeline.id) + { + case VIDEO_SHADER_MENU: + case VIDEO_SHADER_MENU_2: + case VIDEO_SHADER_MENU_3: + case VIDEO_SHADER_MENU_4: + case VIDEO_SHADER_MENU_5: + case VIDEO_SHADER_MENU_6: + d3d10_set_shader(d3d10->device, &d3d10->shaders[draw->pipeline.id]); + D3D10Draw(d3d10->device, draw->coords->vertices, 0); + + D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK); + d3d10_set_shader(d3d10->device, &d3d10->sprites.shader); + D3D10SetVertexBuffer(d3d10->device, 0, d3d10->sprites.vbo, sizeof(d3d10_sprite_t), 0); + D3D10SetPrimitiveTopology(d3d10->device, D3D10_PRIMITIVE_TOPOLOGY_POINTLIST); + return; + } + + if (draw->coords->vertex && draw->coords->tex_coord && draw->coords->color) + vertex_count = draw->coords->vertices; + else + vertex_count = 1; + + if (!d3d10->sprites.enabled || vertex_count > d3d10->sprites.capacity) + return; + + if (d3d10->sprites.offset + vertex_count > d3d10->sprites.capacity) + d3d10->sprites.offset = 0; + + { + void* mapped_vbo; + d3d10_sprite_t* sprite = NULL; + + D3D10MapBuffer(d3d10->sprites.vbo, D3D10_MAP_WRITE_NO_OVERWRITE, 0, &mapped_vbo); + + sprite = (d3d10_sprite_t*)mapped_vbo + d3d10->sprites.offset; + + if (vertex_count == 1) + { + sprite->pos.x = draw->x / (float)d3d10->viewport.Width; + sprite->pos.y = + (d3d10->viewport.Height - draw->y - draw->height) / (float)d3d10->viewport.Height; + sprite->pos.w = draw->width / (float)d3d10->viewport.Width; + sprite->pos.h = draw->height / (float)d3d10->viewport.Height; + + sprite->coords.u = 0.0f; + sprite->coords.v = 0.0f; + sprite->coords.w = 1.0f; + sprite->coords.h = 1.0f; + + if (draw->scale_factor) + sprite->params.scaling = draw->scale_factor; + else + sprite->params.scaling = 1.0f; + + sprite->params.rotation = draw->rotation; + + sprite->colors[3] = DXGI_COLOR_RGBA( + 0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1], + 0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]); + sprite->colors[2] = DXGI_COLOR_RGBA( + 0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5], + 0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]); + sprite->colors[1] = DXGI_COLOR_RGBA( + 0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9], + 0xFF * draw->coords->color[10], 0xFF * draw->coords->color[11]); + sprite->colors[0] = DXGI_COLOR_RGBA( + 0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13], + 0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]); + } + else + { + int i; + const float* vertex = draw->coords->vertex; + const float* tex_coord = draw->coords->tex_coord; + const float* color = draw->coords->color; + + for (i = 0; i < vertex_count; i++) + { + d3d10_vertex_t* v = (d3d10_vertex_t*)sprite; + v->position[0] = *vertex++; + v->position[1] = *vertex++; + v->texcoord[0] = *tex_coord++; + v->texcoord[1] = *tex_coord++; + v->color[0] = *color++; + v->color[1] = *color++; + v->color[2] = *color++; + v->color[3] = *color++; + + sprite++; + } + + d3d10_set_shader(d3d10->device, &d3d10->shaders[VIDEO_SHADER_STOCK_BLEND]); + D3D10SetPrimitiveTopology(d3d10->device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + } + + D3D10UnmapBuffer(d3d10->sprites.vbo); + } + + d3d10_set_texture_and_sampler(d3d10->device, 0, (d3d10_texture_t*)draw->texture); + D3D10Draw(d3d10->device, vertex_count, d3d10->sprites.offset); + d3d10->sprites.offset += vertex_count; + + if (vertex_count > 1) + { + d3d10_set_shader(d3d10->device, &d3d10->sprites.shader); + D3D10SetPrimitiveTopology(d3d10->device, D3D10_PRIMITIVE_TOPOLOGY_POINTLIST); + } + + return; +} + +static void menu_display_d3d10_draw_pipeline(void* data, + video_frame_info_t *video_info) +{ + menu_display_ctx_draw_t* draw = (menu_display_ctx_draw_t*)data; + d3d10_video_t* d3d10 = video_info ? (d3d10_video_t*)video_info->userdata : NULL; + + if (!d3d10 || !draw) + return; + + switch (draw->pipeline.id) + { + case VIDEO_SHADER_MENU: + case VIDEO_SHADER_MENU_2: + { + video_coord_array_t* ca = menu_display_get_coords_array(); + + if (!d3d10->menu_pipeline_vbo) + { + D3D10_BUFFER_DESC desc = { 0 }; + desc.Usage = D3D10_USAGE_IMMUTABLE; + 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); + } + D3D10SetVertexBuffer(d3d10->device, 0, d3d10->menu_pipeline_vbo, 2 * sizeof(float), 0); + draw->coords->vertices = ca->coords.vertices; + D3D10SetBlendState(d3d10->device, d3d10->blend_pipeline, NULL, D3D10_DEFAULT_SAMPLE_MASK); + break; + } + + case VIDEO_SHADER_MENU_3: + case VIDEO_SHADER_MENU_4: + case VIDEO_SHADER_MENU_5: + case VIDEO_SHADER_MENU_6: + D3D10SetVertexBuffer(d3d10->device, 0, d3d10->frame.vbo, sizeof(d3d10_vertex_t), 0); + draw->coords->vertices = 4; + break; + default: + return; + } + + D3D10SetPrimitiveTopology(d3d10->device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + d3d10->ubo_values.time += 0.01f; + + { + void* mapped_ubo; + D3D10MapBuffer(d3d10->ubo, D3D10_MAP_WRITE_DISCARD, 0, (void**)&mapped_ubo); + *(d3d10_uniform_t*)mapped_ubo = d3d10->ubo_values; + D3D10UnmapBuffer(d3d10->ubo); + } +} + +static void menu_display_d3d10_restore_clear_color(void) {} + +static void menu_display_d3d10_clear_color( + menu_display_ctx_clearcolor_t* clearcolor, + video_frame_info_t *video_info) +{ + d3d10_video_t *d3d10 = video_info ? + (d3d10_video_t*)video_info->userdata : NULL; + + if (!d3d10 || !clearcolor) + return; + + D3D10ClearRenderTargetView(d3d10->device, + d3d10->renderTargetView, (float*)clearcolor); +} + +static bool menu_display_d3d10_font_init_first( + void** font_handle, + void* video_data, + const char* font_path, + float font_size, + bool is_threaded) +{ + font_data_t** handle = (font_data_t**)font_handle; + font_data_t* new_handle = font_driver_init_first( + video_data, font_path, font_size, true, + is_threaded, FONT_DRIVER_RENDER_D3D10_API); + if (!new_handle) + return false; + *handle = new_handle; + return true; +} + +menu_display_ctx_driver_t menu_display_ctx_d3d10 = { + menu_display_d3d10_draw, + menu_display_d3d10_draw_pipeline, + menu_display_d3d10_viewport, + menu_display_d3d10_blend_begin, + menu_display_d3d10_blend_end, + menu_display_d3d10_restore_clear_color, + menu_display_d3d10_clear_color, + menu_display_d3d10_get_default_mvp, + menu_display_d3d10_get_default_vertices, + menu_display_d3d10_get_default_tex_coords, + menu_display_d3d10_font_init_first, + MENU_VIDEO_DRIVER_DIRECT3D10, + "menu_display_d3d10", + true +}; diff --git a/menu/drivers_display/menu_display_d3d8.c b/menu/drivers_display/menu_display_d3d8.c index 208f6b566d..51851ff027 100644 --- a/menu/drivers_display/menu_display_d3d8.c +++ b/menu/drivers_display/menu_display_d3d8.c @@ -13,6 +13,8 @@ * If not, see . */ +#define CINTERFACE + #include #include @@ -79,8 +81,8 @@ static INT32 menu_display_prim_to_d3d8_enum( static void menu_display_d3d8_blend_begin(video_frame_info_t *video_info) { - d3d_video_t *d3d = video_info ? - (d3d_video_t*)video_info->userdata : NULL; + d3d8_video_t *d3d = video_info ? + (d3d8_video_t*)video_info->userdata : NULL; if (!d3d) return; @@ -90,8 +92,8 @@ static void menu_display_d3d8_blend_begin(video_frame_info_t *video_info) static void menu_display_d3d8_blend_end(video_frame_info_t *video_info) { - d3d_video_t *d3d = video_info ? - (d3d_video_t*)video_info->userdata : NULL; + d3d8_video_t *d3d = video_info ? + (d3d8_video_t*)video_info->userdata : NULL; if (!d3d) return; @@ -103,7 +105,7 @@ static void menu_display_d3d8_viewport(void *data, video_frame_info_t *video_inf { } -static void menu_display_d3d8_bind_texture(void *data, d3d_video_t *d3d) +static void menu_display_d3d8_bind_texture(void *data, d3d8_video_t *d3d) { menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; @@ -123,7 +125,7 @@ static void menu_display_d3d8_draw(void *data, video_frame_info_t *video_info) video_shader_ctx_mvp_t mvp; math_matrix_4x4 mop, m1, m2; unsigned width, height; - d3d_video_t *d3d = video_info ? (d3d_video_t*)video_info->userdata : NULL; + d3d8_video_t *d3d = video_info ? (d3d8_video_t*)video_info->userdata : NULL; menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; Vertex * pv = NULL; const float *vertex = NULL; @@ -214,7 +216,7 @@ static void menu_display_d3d8_draw(void *data, video_frame_info_t *video_info) mvp.data = d3d; mvp.matrix = &m1; video_driver_set_mvp(&mvp); - menu_display_d3d8_bind_texture(draw, (d3d_video_t*)video_info->userdata); + menu_display_d3d8_bind_texture(draw, (d3d8_video_t*)video_info->userdata); d3d8_draw_primitive(d3d->dev, menu_display_prim_to_d3d8_enum(draw->prim_type), d3d->menu_display.offset, @@ -239,8 +241,8 @@ static void menu_display_d3d8_clear_color( menu_display_ctx_clearcolor_t *clearcolor, video_frame_info_t *video_info) { DWORD clear_color = 0; - d3d_video_t *d3d = video_info ? - (d3d_video_t*)video_info->userdata : NULL; + d3d8_video_t *d3d = video_info ? + (d3d8_video_t*)video_info->userdata : NULL; if (!d3d || !clearcolor) return; diff --git a/menu/drivers_display/menu_display_d3d9.c b/menu/drivers_display/menu_display_d3d9.c index cb62c95972..c99396e5b7 100644 --- a/menu/drivers_display/menu_display_d3d9.c +++ b/menu/drivers_display/menu_display_d3d9.c @@ -13,6 +13,8 @@ * If not, see . */ +#define CINTERFACE + #include #include @@ -79,8 +81,8 @@ static INT32 menu_display_prim_to_d3d9_enum( static void menu_display_d3d9_blend_begin(video_frame_info_t *video_info) { - d3d_video_t *d3d = video_info ? - (d3d_video_t*)video_info->userdata : NULL; + d3d9_video_t *d3d = video_info ? + (d3d9_video_t*)video_info->userdata : NULL; if (!d3d) return; @@ -90,8 +92,8 @@ static void menu_display_d3d9_blend_begin(video_frame_info_t *video_info) static void menu_display_d3d9_blend_end(video_frame_info_t *video_info) { - d3d_video_t *d3d = video_info ? - (d3d_video_t*)video_info->userdata : NULL; + d3d9_video_t *d3d = video_info ? + (d3d9_video_t*)video_info->userdata : NULL; if (!d3d) return; @@ -103,19 +105,22 @@ static void menu_display_d3d9_viewport(void *data, video_frame_info_t *video_inf { } -static void menu_display_d3d9_bind_texture(void *data, d3d_video_t *d3d) +static void menu_display_d3d9_bind_texture(void *data, d3d9_video_t *d3d) { menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; + LPDIRECT3DDEVICE9 dev; if (!d3d || !draw || !draw->texture) return; - d3d9_set_texture(d3d->dev, 0, (void*)draw->texture); - d3d9_set_sampler_address_u(d3d->dev, 0, D3DTADDRESS_COMM_CLAMP); - d3d9_set_sampler_address_v(d3d->dev, 0, D3DTADDRESS_COMM_CLAMP); - d3d9_set_sampler_minfilter(d3d->dev, 0, D3DTEXF_COMM_LINEAR); - d3d9_set_sampler_magfilter(d3d->dev, 0, D3DTEXF_COMM_LINEAR); - d3d9_set_sampler_mipfilter(d3d->dev, 0, D3DTEXF_COMM_LINEAR); + dev = (LPDIRECT3DDEVICE9)d3d->dev; + + d3d9_set_texture(dev, 0, (LPDIRECT3DTEXTURE9)draw->texture); + d3d9_set_sampler_address_u(dev, 0, D3DTADDRESS_COMM_CLAMP); + d3d9_set_sampler_address_v(dev, 0, D3DTADDRESS_COMM_CLAMP); + d3d9_set_sampler_minfilter(dev, 0, D3DTEXF_COMM_LINEAR); + d3d9_set_sampler_magfilter(dev, 0, D3DTEXF_COMM_LINEAR); + d3d9_set_sampler_mipfilter(dev, 0, D3DTEXF_COMM_LINEAR); } static void menu_display_d3d9_draw(void *data, video_frame_info_t *video_info) @@ -124,7 +129,8 @@ static void menu_display_d3d9_draw(void *data, video_frame_info_t *video_info) video_shader_ctx_mvp_t mvp; math_matrix_4x4 mop, m1, m2; unsigned width, height; - d3d_video_t *d3d = video_info ? (d3d_video_t*)video_info->userdata : NULL; + LPDIRECT3DDEVICE9 dev; + d3d9_video_t *d3d = video_info ? (d3d9_video_t*)video_info->userdata : NULL; menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data; Vertex * pv = NULL; const float *vertex = NULL; @@ -133,12 +139,15 @@ static void menu_display_d3d9_draw(void *data, video_frame_info_t *video_info) if (!d3d || !draw || draw->pipeline.id) return; + + dev = d3d->dev; + if((d3d->menu_display.offset + draw->coords->vertices ) > (unsigned)d3d->menu_display.size) return; pv = (Vertex*) - d3d9_vertex_buffer_lock(d3d->menu_display.buffer); + d3d9_vertex_buffer_lock((LPDIRECT3DVERTEXBUFFER9)d3d->menu_display.buffer); if (!pv) return; @@ -176,7 +185,7 @@ static void menu_display_d3d9_draw(void *data, video_frame_info_t *video_info) colors[2] /* B */ ); } - d3d9_vertex_buffer_unlock(d3d->menu_display.buffer); + d3d9_vertex_buffer_unlock((LPDIRECT3DVERTEXBUFFER9)d3d->menu_display.buffer); if(!draw->matrix_data) draw->matrix_data = menu_display_d3d9_get_default_mvp(video_info); @@ -203,9 +212,9 @@ static void menu_display_d3d9_draw(void *data, video_frame_info_t *video_info) mvp.data = d3d; mvp.matrix = &m1; video_driver_set_mvp(&mvp); - menu_display_d3d9_bind_texture(draw, (d3d_video_t*)video_info->userdata); - d3d9_draw_primitive(d3d->dev, - menu_display_prim_to_d3d9_enum(draw->prim_type), + menu_display_d3d9_bind_texture(draw, (d3d9_video_t*)video_info->userdata); + d3d9_draw_primitive(dev, + (D3DPRIMITIVETYPE)menu_display_prim_to_d3d9_enum(draw->prim_type), d3d->menu_display.offset, draw->coords->vertices - ((draw->prim_type == MENU_DISPLAY_PRIM_TRIANGLESTRIP) @@ -268,13 +277,16 @@ static void menu_display_d3d9_restore_clear_color(void) static void menu_display_d3d9_clear_color( menu_display_ctx_clearcolor_t *clearcolor, video_frame_info_t *video_info) { + LPDIRECT3DDEVICE9 dev; DWORD clear_color = 0; - d3d_video_t *d3d = video_info ? - (d3d_video_t*)video_info->userdata : NULL; + d3d9_video_t *d3d = video_info ? + (d3d9_video_t*)video_info->userdata : NULL; if (!d3d || !clearcolor) return; + dev = (LPDIRECT3DDEVICE9)d3d->dev; + clear_color = D3DCOLOR_ARGB( BYTE_CLAMP(clearcolor->a * 255.0f), /* A */ BYTE_CLAMP(clearcolor->r * 255.0f), /* R */ @@ -282,7 +294,7 @@ static void menu_display_d3d9_clear_color( BYTE_CLAMP(clearcolor->b * 255.0f) /* B */ ); - d3d9_clear(d3d->dev, 0, NULL, D3D_COMM_CLEAR_TARGET, clear_color, 0, 0); + d3d9_clear(dev, 0, NULL, D3D_COMM_CLEAR_TARGET, clear_color, 0, 0); } static bool menu_display_d3d9_font_init_first( diff --git a/menu/menu_cbs.c b/menu/menu_cbs.c index 28dd055114..33d4b5a01e 100644 --- a/menu/menu_cbs.c +++ b/menu/menu_cbs.c @@ -32,7 +32,7 @@ static void menu_cbs_init_log(const char *entry_label, const char *bind_label, c #endif } -struct key_desc key_descriptors[MENU_SETTINGS_INPUT_DESC_KBD_END] = +struct key_desc key_descriptors[RARCH_MAX_KEYS] = { {RETROK_FIRST, "Unmapped"}, {RETROK_BACKSPACE, "Backspace"}, diff --git a/menu/menu_cbs.h b/menu/menu_cbs.h index a6e629394e..1d88b379fe 100644 --- a/menu/menu_cbs.h +++ b/menu/menu_cbs.h @@ -68,6 +68,8 @@ enum ACTION_OK_DL_DRIVER_SETTINGS_LIST, ACTION_OK_DL_VIDEO_SETTINGS_LIST, ACTION_OK_DL_AUDIO_SETTINGS_LIST, + ACTION_OK_DL_AUDIO_MIXER_SETTINGS_LIST, + ACTION_OK_DL_LATENCY_SETTINGS_LIST, ACTION_OK_DL_CONFIGURATION_SETTINGS_LIST, ACTION_OK_DL_SAVING_SETTINGS_LIST, ACTION_OK_DL_LOGGING_SETTINGS_LIST, @@ -106,11 +108,13 @@ enum ACTION_OK_DL_CORE_CONTENT_DIRS_SUBDIR_LIST, ACTION_OK_DL_DEFERRED_CORE_LIST, ACTION_OK_DL_DEFERRED_CORE_LIST_SET, + ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST, ACTION_OK_DL_ONSCREEN_DISPLAY_SETTINGS_LIST, ACTION_OK_DL_ONSCREEN_OVERLAY_SETTINGS_LIST, ACTION_OK_DL_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST, ACTION_OK_DL_MENU_VIEWS_SETTINGS_LIST, ACTION_OK_DL_QUICK_MENU_VIEWS_SETTINGS_LIST, + ACTION_OK_DL_QUICK_MENU_OVERRIDE_OPTIONS_LIST, ACTION_OK_DL_MENU_SETTINGS_LIST, ACTION_OK_DL_USER_INTERFACE_SETTINGS_LIST, ACTION_OK_DL_MENU_FILE_BROWSER_SETTINGS_LIST, @@ -161,6 +165,38 @@ int action_right_input_desc_kbd(unsigned type, const char *label, int action_right_cheat(unsigned type, const char *label, bool wraparound); +int setting_action_ok_video_refresh_rate_auto(void *data, bool wraparound); + +int setting_action_ok_video_refresh_rate_polled(void *data, bool wraparound); + +int setting_action_ok_bind_all(void *data, bool wraparound); + +int setting_action_ok_bind_all_save_autoconfig(void *data, + bool wraparound); + +int setting_action_ok_bind_defaults(void *data, bool wraparound); + +int setting_action_left_analog_dpad_mode(void *data, bool wraparound); + +int setting_action_left_libretro_device_type( + void *data, bool wraparound); + +int setting_action_left_bind_device(void *data, bool wraparound); + +int setting_action_left_mouse_index(void *data, bool wraparound); + +int setting_uint_action_left_custom_viewport_width( + void *data, bool wraparound); + +int setting_uint_action_left_custom_viewport_height( + void *data, bool wraparound); + +int setting_string_action_left_driver(void *data, + bool wraparound); + +int setting_string_action_left_audio_device( + void *data, bool wraparound); + /* End of function callbacks */ int menu_cbs_init_bind_left(menu_file_list_cbs_t *cbs, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index a3a47fb682..dbb6b10a19 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -153,6 +153,7 @@ static int menu_displaylist_parse_core_info(menu_displaylist_info_t *info) unsigned i; char tmp[PATH_MAX_LENGTH]; core_info_t *core_info = NULL; + settings_t *settings = config_get_ptr(); tmp[0] = '\0'; @@ -284,12 +285,21 @@ static int menu_displaylist_parse_core_info(menu_displaylist_info_t *info) if (core_info->firmware_count > 0) { core_info_ctx_firmware_t firmware_info; + bool update_missing_firmware = false; + bool set_missing_firmware = false; settings_t *settings = config_get_ptr(); firmware_info.path = core_info->path; firmware_info.directory.system = settings->paths.directory_system; - if (core_info_list_update_missing_firmware(&firmware_info)) + rarch_ctl(RARCH_CTL_UNSET_MISSING_BIOS, NULL); + + update_missing_firmware = core_info_list_update_missing_firmware(&firmware_info, &set_missing_firmware); + + if (set_missing_firmware) + rarch_ctl(RARCH_CTL_SET_MISSING_BIOS, NULL); + + if (update_missing_firmware) { fill_pathname_noext(tmp, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE), @@ -336,11 +346,12 @@ static int menu_displaylist_parse_core_info(menu_displaylist_info_t *info) } } - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_DELETE), - msg_hash_to_str(MENU_ENUM_LABEL_CORE_DELETE), - MENU_ENUM_LABEL_CORE_DELETE, - MENU_SETTING_ACTION_CORE_DELETE, 0, 0); + if (settings->bools.menu_show_core_updater) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_DELETE), + msg_hash_to_str(MENU_ENUM_LABEL_CORE_DELETE), + MENU_ENUM_LABEL_CORE_DELETE, + MENU_SETTING_ACTION_CORE_DELETE, 0, 0); return 0; } @@ -505,14 +516,14 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info) MENU_SETTINGS_CORE_INFO_NONE, 0, 0); snprintf(tmp, sizeof(tmp), "Port #%d device display name: %s", controller, - input_config_get_device_display_name(controller) ? + input_config_get_device_display_name(controller) ? input_config_get_device_display_name(controller) : "N/A"); menu_entries_append_enum(info->list, tmp, "", MENU_ENUM_LABEL_SYSTEM_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0); snprintf(tmp, sizeof(tmp), "Port #%d device config name: %s", controller, - input_config_get_device_display_name(controller) ? + input_config_get_device_display_name(controller) ? input_config_get_device_config_name(controller) : "N/A"); menu_entries_append_enum(info->list, tmp, "", MENU_ENUM_LABEL_SYSTEM_INFO_ENTRY, @@ -1563,7 +1574,19 @@ error: return -1; } -static int menu_displaylist_parse_database_entry(menu_displaylist_info_t *info) +static enum msg_file_type extension_to_file_hash_type(const char *ext) +{ + if (string_is_equal(ext, "sha1")) + return FILE_TYPE_SHA1; + else if (string_is_equal(ext, "crc")) + return FILE_TYPE_CRC; + else if (string_is_equal(ext, "md5")) + return FILE_TYPE_MD5; + return FILE_TYPE_NONE; +} + +static int menu_displaylist_parse_database_entry( + menu_displaylist_info_t *info) { unsigned i, j, k; char path_playlist[PATH_MAX_LENGTH]; @@ -1651,7 +1674,7 @@ static int menu_displaylist_parse_database_entry(menu_displaylist_info_t *info) const char *elem0 = tmp_str_list->elems[0].data; const char *elem1 = tmp_str_list->elems[1].data; - switch (msg_hash_to_file_type(msg_hash_calculate(elem1))) + switch (extension_to_file_hash_type(elem1)) { case FILE_TYPE_CRC: if (string_is_equal(crc_str, elem0)) @@ -1676,7 +1699,7 @@ static int menu_displaylist_parse_database_entry(menu_displaylist_info_t *info) if (!match_found) continue; - menu->rdb_entry_start_game_selection_ptr = j; + menu->scratchpad.unsigned_var = j; } } @@ -2464,13 +2487,16 @@ static int menu_displaylist_parse_settings_enum(void *data, static void menu_displaylist_set_new_playlist( menu_handle_t *menu, const char *path) { - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_FREE, NULL); - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_INIT, - (void*)path); - strlcpy( - menu->db_playlist_file, - path, - sizeof(menu->db_playlist_file)); + menu->db_playlist_file[0] = '\0'; + + if (playlist_get_cached()) + playlist_free_cached(); + + if (playlist_init_cached(path, COLLECTION_SIZE)) + strlcpy( + menu->db_playlist_file, + path, + sizeof(menu->db_playlist_file)); } @@ -2523,12 +2549,15 @@ static int menu_displaylist_parse_horizontal_list( menu_displaylist_set_new_playlist(menu, path_playlist); } - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &playlist); + playlist = playlist_get_cached(); - playlist_qsort(playlist); - - menu_displaylist_parse_playlist(info, - playlist, msg_hash_to_str(MENU_ENUM_LABEL_COLLECTION), is_historylist); + if (playlist) + { + playlist_qsort(playlist); + menu_displaylist_parse_playlist(info, + playlist, + msg_hash_to_str(MENU_ENUM_LABEL_COLLECTION), is_historylist); + } return 0; } @@ -2596,7 +2625,7 @@ static int menu_displaylist_parse_load_content_settings( } - if (settings->bools.quick_menu_show_save_load_state + if (settings->bools.quick_menu_show_save_load_state #ifdef HAVE_CHEEVOS && !(settings->bools.cheevos_hardcore_mode_enable && cheevos_loaded) #endif @@ -2656,6 +2685,33 @@ static int menu_displaylist_parse_load_content_settings( MENU_SETTING_ACTION, 0, 0); } + if (settings->bools.menu_show_overlays) + { + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_ONSCREEN_OVERLAY_SETTINGS), + MENU_ENUM_LABEL_ONSCREEN_OVERLAY_SETTINGS, + MENU_SETTING_ACTION, 0, 0); + } + + if (settings->bools.menu_show_rewind) + { + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_REWIND_SETTINGS), + MENU_ENUM_LABEL_REWIND_SETTINGS, + MENU_SETTING_ACTION, 0, 0); + } + + if (settings->bools.menu_show_latency) + { + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LATENCY_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_LATENCY_SETTINGS), + MENU_ENUM_LABEL_LATENCY_SETTINGS, + MENU_SETTING_ACTION, 0, 0); + } + #if 0 menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS), @@ -2702,23 +2758,12 @@ static int menu_displaylist_parse_load_content_settings( } } - if (settings->bools.quick_menu_show_save_core_overrides && !settings->bools.kiosk_mode_enable) - { - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE), - msg_hash_to_str(MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE), - MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, - MENU_SETTING_ACTION, 0, 0); - } + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS), + msg_hash_to_str(MENU_ENUM_LABEL_QUICK_MENU_OVERRIDE_OPTIONS), + MENU_ENUM_LABEL_QUICK_MENU_OVERRIDE_OPTIONS, + MENU_SETTING_ACTION, 0, 0); - if (settings->bools.quick_menu_show_save_game_overrides && !settings->bools.kiosk_mode_enable) - { - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME), - msg_hash_to_str(MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME), - MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, - MENU_SETTING_ACTION, 0, 0); - } #ifdef HAVE_CHEEVOS if(settings->bools.cheevos_enable) @@ -2752,7 +2797,7 @@ static int menu_displaylist_parse_horizontal_content_actions( const char *core_path = NULL; const char *core_name = NULL; const char *db_name = NULL; - playlist_t *playlist = NULL; + playlist_t *playlist = playlist_get_cached(); settings_t *settings = config_get_ptr(); const char *fullpath = path_get(RARCH_PATH_CONTENT); @@ -2761,10 +2806,9 @@ static int menu_displaylist_parse_horizontal_content_actions( idx = menu->rpl_entry_selection_ptr; - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &playlist); - - playlist_get_index(playlist, idx, - &entry_path, &label, &core_path, &core_name, NULL, &db_name); + if (playlist) + playlist_get_index(playlist, idx, + &entry_path, &label, &core_path, &core_name, NULL, &db_name); content_loaded = !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL) && string_is_equal(menu->deferred_path, fullpath); @@ -2786,6 +2830,12 @@ static int menu_displaylist_parse_horizontal_content_actions( msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_MIXER), MENU_ENUM_LABEL_ADD_TO_MIXER, FILE_TYPE_PLAYLIST_ENTRY, 0, idx); + + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_PLAY), + msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_MIXER_AND_PLAY), + MENU_ENUM_LABEL_ADD_TO_MIXER_AND_PLAY, + FILE_TYPE_PLAYLIST_ENTRY, 0, idx); } menu_entries_append_enum(info->list, @@ -2793,14 +2843,16 @@ static int menu_displaylist_parse_horizontal_content_actions( msg_hash_to_str(MENU_ENUM_LABEL_RUN), MENU_ENUM_LABEL_RUN, FILE_TYPE_PLAYLIST_ENTRY, 0, idx); - if (settings->bools.playlist_entry_rename && !settings->bools.kiosk_mode_enable) + if (settings->bools.playlist_entry_rename && + !settings->bools.kiosk_mode_enable) menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_RENAME_ENTRY), msg_hash_to_str(MENU_ENUM_LABEL_RENAME_ENTRY), MENU_ENUM_LABEL_RENAME_ENTRY, FILE_TYPE_PLAYLIST_ENTRY, 0, idx); - if (settings->bools.playlist_entry_remove && !settings->bools.kiosk_mode_enable) + if (settings->bools.playlist_entry_remove && + !settings->bools.kiosk_mode_enable) menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DELETE_ENTRY), msg_hash_to_str(MENU_ENUM_LABEL_DELETE_ENTRY), @@ -3240,73 +3292,74 @@ static int menu_displaylist_parse_options_remappings( if (system) { + settings_t *settings = config_get_ptr(); + unsigned device; for (p = 0; p < max_users; p++) { - for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND + 4; retro_id++) + device = settings->uints.input_libretro_device[p]; + device &= RETRO_DEVICE_MASK; + + if (device == RETRO_DEVICE_JOYPAD || device == RETRO_DEVICE_ANALOG) { - char desc_label[64]; - unsigned user = p + 1; - unsigned desc_offset = retro_id; - const char *description = NULL; - - desc_label[0] = '\0'; - - if (desc_offset >= RARCH_FIRST_CUSTOM_BIND) - desc_offset = RARCH_FIRST_CUSTOM_BIND - + (desc_offset - RARCH_FIRST_CUSTOM_BIND) * 2; - - description = system->input_desc_btn[p][desc_offset]; - - if (!description) - continue; - - snprintf(desc_label, sizeof(desc_label), - "%s %u %s : ", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_USER), - user, description); - menu_entries_append_enum(info->list, desc_label, "", - MSG_UNKNOWN, - MENU_SETTINGS_INPUT_DESC_BEGIN + - (p * (RARCH_FIRST_CUSTOM_BIND + 4)) + retro_id, 0, 0); - } - } - } - #ifdef HAVE_KEYMAPPER - if (system) - { - settings_t *settings = config_get_ptr(); - - unsigned device = settings->uints.input_libretro_device[settings->uints.keymapper_port]; - device &= RETRO_DEVICE_MASK; - - if (device == RETRO_DEVICE_KEYBOARD) - { - for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND; retro_id++) - { - char descriptor[255]; - const struct retro_keybind *keybind = &input_config_binds[settings->uints.keymapper_port][retro_id]; - const struct retro_keybind *auto_bind = (const struct retro_keybind*) - input_config_get_bind_auto(settings->uints.keymapper_port, retro_id); - - descriptor[0] = '\0'; - - input_config_get_bind_string(descriptor, - keybind, auto_bind, sizeof(descriptor)); - - if(!strstr(descriptor, "Auto")) + for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND + 8; retro_id++) { - const struct retro_keybind *keyptr = - &input_config_binds[settings->uints.keymapper_port][retro_id]; + char desc_label[64]; + char descriptor[255]; + const struct retro_keybind *auto_bind = NULL; + const struct retro_keybind *keybind = NULL; - strlcpy(descriptor, msg_hash_to_str(keyptr->enum_idx), sizeof(descriptor)); + keybind = &input_config_binds[p][retro_id]; + auto_bind = (const struct retro_keybind*) + input_config_get_bind_auto(p, retro_id); + + input_config_get_bind_string(descriptor, + keybind, auto_bind, sizeof(descriptor)); + + if(!strstr(descriptor, "Auto")) + { + const struct retro_keybind *keyptr = + &input_config_binds[p][retro_id]; + + snprintf(desc_label, sizeof(desc_label), "%s %s", msg_hash_to_str(keyptr->enum_idx), descriptor); + strlcpy(descriptor, desc_label, sizeof(descriptor)); + } + + menu_entries_append_enum(info->list, descriptor, "", + MSG_UNKNOWN, + MENU_SETTINGS_INPUT_DESC_BEGIN + + (p * (RARCH_FIRST_CUSTOM_BIND + 8)) + retro_id, 0, 0); } + } + else if (device == RETRO_DEVICE_KEYBOARD) + { + for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND; retro_id++) + { + char descriptor[255]; + const struct retro_keybind *auto_bind = NULL; + const struct retro_keybind *keybind = NULL; - menu_entries_append_enum(info->list, descriptor, "", - MSG_UNKNOWN, - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN + retro_id, 0, 0); + keybind = &input_config_binds[p][retro_id]; + auto_bind = (const struct retro_keybind*) + input_config_get_bind_auto(p, retro_id); + + input_config_get_bind_string(descriptor, + keybind, auto_bind, sizeof(descriptor)); + + if(!strstr(descriptor, "Auto")) + { + const struct retro_keybind *keyptr = + &input_config_binds[p][retro_id]; + + strlcpy(descriptor, msg_hash_to_str(keyptr->enum_idx), sizeof(descriptor)); + } + + menu_entries_append_enum(info->list, descriptor, "", + MSG_UNKNOWN, + (MENU_SETTINGS_INPUT_DESC_KBD_BEGIN + retro_id) * (p + 1), 0, 0); + } } } } - #endif return 0; } @@ -3355,20 +3408,20 @@ static int menu_displaylist_parse_playlists( MENU_ENUM_LABEL_SCAN_FILE, MENU_SETTING_ACTION, 0, 0); #endif - if (settings->bools.menu_content_show_favorites) + if (settings->bools.menu_content_show_favorites) menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES), msg_hash_to_str(MENU_ENUM_LABEL_GOTO_FAVORITES), MENU_ENUM_LABEL_GOTO_FAVORITES, MENU_SETTING_ACTION, 0, 0); - if (settings->bools.menu_content_show_images) + if (settings->bools.menu_content_show_images) menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_IMAGES), msg_hash_to_str(MENU_ENUM_LABEL_GOTO_IMAGES), MENU_ENUM_LABEL_GOTO_IMAGES, MENU_SETTING_ACTION, 0, 0); - if (settings->bools.menu_content_show_music) + if (settings->bools.menu_content_show_music) menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_MUSIC), msg_hash_to_str(MENU_ENUM_LABEL_GOTO_MUSIC), @@ -3376,7 +3429,7 @@ static int menu_displaylist_parse_playlists( MENU_SETTING_ACTION, 0, 0); #ifdef HAVE_FFMPEG - if (settings->bools.menu_content_show_video) + if (settings->bools.menu_content_show_video) menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_VIDEO), msg_hash_to_str(MENU_ENUM_LABEL_GOTO_VIDEO), @@ -3947,9 +4000,8 @@ static void menu_displaylist_parse_playlist_generic( menu_displaylist_set_new_playlist(menu, playlist_path); - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &playlist); - - path_playlist = strdup(playlist_name); + playlist = playlist_get_cached(); + path_playlist = strdup(playlist_name); *ret = menu_displaylist_parse_playlist(info, playlist, path_playlist, true); @@ -4144,6 +4196,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) { size_t i; menu_ctx_displaylist_t disp_list; + unsigned count = 0; int ret = 0; core_info_list_t *list = NULL; menu_handle_t *menu = NULL; @@ -4180,12 +4233,20 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); if (audio_driver_mixer_extension_supported(ext)) + { menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION), msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION), MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION, FILE_TYPE_PLAYLIST_ENTRY, 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY), + msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY), + MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY, + FILE_TYPE_PLAYLIST_ENTRY, 0, 0); + } + #ifdef HAVE_FFMPEG if (settings->bools.multimedia_builtin_mediaplayer_enable) menu_entries_append_enum(info->list, @@ -4195,6 +4256,70 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) FILE_TYPE_PLAYLIST_ENTRY, 0, 0); #endif } + info->need_push = true; + info->need_refresh = true; + info->need_clear = true; + break; + case DISPLAYLIST_MIXER_STREAM_SETTINGS_LIST: + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + + { + char lbl_play[128]; + char lbl_play_looped[128]; + char lbl_play_sequential[128]; + char lbl_remove[128]; + char lbl_stop[128]; + char lbl_volume[128]; + unsigned id = info->type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_BEGIN; + + lbl_remove[0] = lbl_stop[0] = lbl_play[0] = lbl_play_looped[0] = '\0'; + lbl_volume[0] = lbl_play_sequential[0] = '\0'; + + snprintf(lbl_volume, sizeof(lbl_volume), "mixer_stream_%d_action_volume", id); + snprintf(lbl_stop, sizeof(lbl_stop), "mixer_stream_%d_action_stop", id); + snprintf(lbl_remove, sizeof(lbl_remove), "mixer_stream_%d_action_remove", id); + snprintf(lbl_play, sizeof(lbl_play), "mixer_stream_%d_action_play", id); + snprintf(lbl_play_looped, sizeof(lbl_play_looped), "mixer_stream_%d_action_play_looped", id); + snprintf(lbl_play_sequential, sizeof(lbl_play_sequential), "mixer_stream_%d_action_play_sequential", id); + + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY), + lbl_play, + MSG_UNKNOWN, + (MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN + id), + 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_LOOPED), + lbl_play_looped, + MSG_UNKNOWN, + (MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN + id), + 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_SEQUENTIAL), + lbl_play_sequential, + MSG_UNKNOWN, + (MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_SEQUENTIAL_BEGIN + id), + 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_STOP), + lbl_stop, + MSG_UNKNOWN, + (MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_BEGIN + id), + 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_REMOVE), + lbl_remove, + MSG_UNKNOWN, + (MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_BEGIN + id), + 0, 0); + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MIXER_ACTION_VOLUME), + lbl_volume, + MSG_UNKNOWN, + (MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN + id), + 0, 0); + } + info->need_push = true; info->need_refresh = true; info->need_clear = true; @@ -4378,12 +4503,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) msg_hash_to_str(MENU_ENUM_LABEL_COLLECTION), sizeof(path_playlist)); - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &playlist); + playlist = playlist_get_cached(); - playlist_qsort(playlist); + if (playlist) + { + playlist_qsort(playlist); - ret = menu_displaylist_parse_playlist(info, - playlist, path_playlist, false); + ret = menu_displaylist_parse_playlist(info, + playlist, path_playlist, false); + } if (ret == 0) { @@ -4593,7 +4721,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) const char *core_name = cores_names->elems[i].data; if ( !path_is_empty(RARCH_PATH_CORE) && - string_is_equal(core_path, path_get(RARCH_PATH_CORE))) + 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), "Current core (%s)", core_name); @@ -4686,7 +4814,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) const char *core_name = cores_names->elems[i].data; if ( !path_is_empty(RARCH_PATH_CORE) && - string_is_equal(core_path, path_get(RARCH_PATH_CORE))) + 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), "Current core (%s)", core_name); @@ -4829,8 +4957,8 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) for (i = 0; i < RARCH_BIND_LIST_END; i++) { ret = menu_displaylist_parse_settings_enum(menu, info, - (enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i), - PARSE_ONLY_BIND, false); + (enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i), + PARSE_ONLY_BIND, false); (void)ret; } } @@ -4982,10 +5110,8 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) break; case DISPLAYLIST_ONSCREEN_DISPLAY_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); -#ifdef HAVE_OVERLAY menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_ONSCREEN_OVERLAY_SETTINGS, PARSE_ACTION, false); -#endif menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_ONSCREEN_NOTIFICATIONS_SETTINGS, PARSE_ACTION, false); @@ -5113,16 +5239,12 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) MENU_ENUM_LABEL_MENU_SHOW_LOAD_CONTENT, PARSE_ONLY_BOOL, false); -#if defined(HAVE_NETWORKING) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_SHOW_ONLINE_UPDATER, PARSE_ONLY_BOOL, false); -#if !defined(HAVE_LAKKA) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_SHOW_CORE_UPDATER, PARSE_ONLY_BOOL, false); -#endif -#endif menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_SHOW_INFORMATION, @@ -5136,7 +5258,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) MENU_ENUM_LABEL_MENU_SHOW_HELP, PARSE_ONLY_BOOL, false); -#if defined(HAVE_LAKKA) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_SHOW_QUIT_RETROARCH, PARSE_ONLY_BOOL, false); @@ -5144,7 +5265,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_MENU_SHOW_REBOOT, PARSE_ONLY_BOOL, false); -#endif menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS, @@ -5155,35 +5275,30 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) PARSE_ONLY_STRING, false); menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_CONTENT_SHOW_FAVORITES, - PARSE_ONLY_BOOL, false); + MENU_ENUM_LABEL_CONTENT_SHOW_FAVORITES, + PARSE_ONLY_BOOL, false); -#ifdef HAVE_IMAGEVIEWER menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CONTENT_SHOW_IMAGES, PARSE_ONLY_BOOL, false); -#endif menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CONTENT_SHOW_MUSIC, PARSE_ONLY_BOOL, false); -#ifdef HAVE_FFMPEG menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CONTENT_SHOW_VIDEO, PARSE_ONLY_BOOL, false); -#endif -#ifdef HAVE_NETWORKING menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CONTENT_SHOW_NETPLAY, PARSE_ONLY_BOOL, false); -#endif menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CONTENT_SHOW_HISTORY, PARSE_ONLY_BOOL, false); -#ifdef HAVE_LIBRETRODB menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CONTENT_SHOW_ADD, PARSE_ONLY_BOOL, false); -#endif + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CONTENT_SHOW_PLAYLISTS, + PARSE_ONLY_BOOL, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_TIMEDATE_ENABLE, PARSE_ONLY_BOOL, false); @@ -5234,6 +5349,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_QUICK_MENU_SHOW_SHADERS, PARSE_ONLY_BOOL, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CONTENT_SHOW_REWIND, + PARSE_ONLY_BOOL, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY, + PARSE_ONLY_BOOL, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CONTENT_SHOW_OVERLAYS, + PARSE_ONLY_BOOL, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES, PARSE_ONLY_BOOL, false); @@ -5252,84 +5376,141 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) case DISPLAYLIST_MENU_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MENU_WALLPAPER, - PARSE_ONLY_PATH, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_DYNAMIC_WALLPAPER, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY, - PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MENU_FRAMEBUFFER_OPACITY, - PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MENU_LINEAR_FILTER, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_ENTRY_NORMAL_COLOR, - PARSE_ONLY_HEX, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_ENTRY_HOVER_COLOR, - PARSE_ONLY_HEX, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_TITLE_COLOR, - PARSE_ONLY_HEX, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_XMB_ALPHA_FACTOR, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_XMB_SCALE_FACTOR, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_XMB_FONT, - PARSE_ONLY_PATH, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MENU_FONT_COLOR_RED, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MENU_FONT_COLOR_GREEN, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_XMB_THEME, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_XMB_RIBBON_ENABLE, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY, - PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY, - PARSE_ONLY_FLOAT, false); - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_THUMBNAILS, - PARSE_ONLY_UINT, false); + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_WALLPAPER, + PARSE_ONLY_PATH, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_DYNAMIC_WALLPAPER, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_WALLPAPER_OPACITY, + PARSE_ONLY_FLOAT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_FRAMEBUFFER_OPACITY, + PARSE_ONLY_FLOAT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_LINEAR_FILTER, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_ENTRY_NORMAL_COLOR, + PARSE_ONLY_HEX, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_ENTRY_HOVER_COLOR, + PARSE_ONLY_HEX, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_TITLE_COLOR, + PARSE_ONLY_HEX, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_XMB_ALPHA_FACTOR, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_XMB_SCALE_FACTOR, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_XMB_FONT, + PARSE_ONLY_PATH, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_FONT_COLOR_RED, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_FONT_COLOR_GREEN, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MENU_FONT_COLOR_BLUE, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_XMB_LAYOUT, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_XMB_THEME, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_XMB_RIBBON_ENABLE, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MATERIALUI_ICONS_ENABLE, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY, + PARSE_ONLY_FLOAT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY, + PARSE_ONLY_FLOAT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_THUMBNAILS, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_LEFT_THUMBNAILS, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (count == 0) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY), + msg_hash_to_str(MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY), + MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY, + FILE_TYPE_NONE, 0, 0); info->need_refresh = true; info->need_push = true; @@ -5380,7 +5561,14 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_UI_MENUBAR_ENABLE, PARSE_ONLY_BOOL, false); - +#ifdef HAVE_QT + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_DESKTOP_MENU_ENABLE, + PARSE_ONLY_BOOL, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_UI_COMPANION_TOGGLE, + PARSE_ONLY_BOOL, false); +#endif info->need_refresh = true; info->need_push = true; break; @@ -5404,8 +5592,8 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) if (string_is_equal(settings->arrays.menu_driver, "xmb")) { menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE, - PARSE_ONLY_BOOL, false); + MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE, + PARSE_ONLY_BOOL, false); } menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CHEEVOS_TEST_UNOFFICIAL, @@ -5422,28 +5610,25 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) break; case DISPLAYLIST_UPDATER_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - { - unsigned count = 0; - if (menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL, - PARSE_ONLY_STRING, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL, + PARSE_ONLY_STRING, false) != -1) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL, PARSE_ONLY_STRING, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, PARSE_ONLY_BOOL, false) != -1) - count++; + count++; - if (count == 0) - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), - msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), - MENU_ENUM_LABEL_NO_SETTINGS_FOUND, - 0, 0, 0); - } + if (count == 0) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), + MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + 0, 0, 0); info->need_refresh = true; info->need_push = true; @@ -5499,161 +5684,184 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) break; case DISPLAYLIST_NETWORK_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - { - unsigned user; - unsigned count = 0; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE, PARSE_ONLY_BOOL, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER, PARSE_ONLY_BOOL, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_MITM_SERVER, PARSE_ONLY_STRING, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS, PARSE_ONLY_STRING, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT, PARSE_ONLY_UINT, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_PASSWORD, PARSE_ONLY_STRING, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD, PARSE_ONLY_STRING, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR, PARSE_ONLY_BOOL, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_ALLOW_SLAVES, PARSE_ONLY_BOOL, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_REQUIRE_SLAVES, PARSE_ONLY_BOOL, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE, PARSE_ONLY_BOOL, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES, PARSE_ONLY_INT, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, PARSE_ONLY_INT, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, PARSE_ONLY_INT, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_NAT_TRAVERSAL, PARSE_ONLY_BOOL, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_SHARE_DIGITAL, PARSE_ONLY_UINT, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_SHARE_ANALOG, PARSE_ONLY_UINT, false) != -1) - count++; + count++; + + { + unsigned user; for (user = 0; user < MAX_USERS; user++) { if (menu_displaylist_parse_settings_enum(menu, info, - (enum msg_hash_enums)(MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1 + user), - PARSE_ONLY_BOOL, false) != -1) + (enum msg_hash_enums)(MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1 + user), + PARSE_ONLY_BOOL, false) != -1) count++; } - if (menu_displaylist_parse_settings_enum(menu, info, + } + + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETWORK_CMD_ENABLE, PARSE_ONLY_BOOL, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETWORK_CMD_PORT, PARSE_ONLY_UINT, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETWORK_REMOTE_ENABLE, PARSE_ONLY_BOOL, false) != -1) - count++; - if (menu_displaylist_parse_settings_enum(menu, info, + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETWORK_REMOTE_PORT, PARSE_ONLY_UINT, false) != -1) - count++; + count++; + { + unsigned user; + unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); + for(user = 0; user < max_users; user++) { - unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); - for(user = 0; user < max_users; user++) - { - if (menu_displaylist_parse_settings_enum(menu, info, - (enum msg_hash_enums)(MENU_ENUM_LABEL_NETWORK_REMOTE_USER_1_ENABLE + user), - PARSE_ONLY_BOOL, false) != -1) - count++; - } + if (menu_displaylist_parse_settings_enum(menu, info, + (enum msg_hash_enums)(MENU_ENUM_LABEL_NETWORK_REMOTE_USER_1_ENABLE + user), + PARSE_ONLY_BOOL, false) != -1) + count++; } + } - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_STDIN_CMD_ENABLE, PARSE_ONLY_BOOL, false) != -1) - count++; + count++; - if (menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_UPDATER_SETTINGS, PARSE_ACTION, false) != -1) - count++; + count++; - if (count == 0) - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), - msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), - MENU_ENUM_LABEL_NO_SETTINGS_FOUND, - 0, 0, 0); - } + if (count == 0) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), + MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + 0, 0, 0); info->need_refresh = true; info->need_push = true; break; case DISPLAYLIST_LAKKA_SERVICES_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_SSH_ENABLE, - PARSE_ONLY_BOOL, false); + PARSE_ONLY_BOOL, false) == 0) + count++; - menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_SAMBA_ENABLE, - PARSE_ONLY_BOOL, false); + PARSE_ONLY_BOOL, false) == 0) + count++; - menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_BLUETOOTH_ENABLE, - PARSE_ONLY_BOOL, false); + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (count == 0) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), + MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + 0, 0, 0); info->need_refresh = true; info->need_push = true; break; case DISPLAYLIST_USER_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_ACCOUNTS_LIST, - PARSE_ACTION, false); - menu_displaylist_parse_settings_enum(menu, info, + PARSE_ACTION, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_NICKNAME, - PARSE_ONLY_STRING, false); - menu_displaylist_parse_settings_enum(menu, info, + PARSE_ONLY_STRING, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_USER_LANGUAGE, - PARSE_ONLY_UINT, false); + PARSE_ONLY_UINT, false) == 0) + count++; + + if (count == 0) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), + MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + 0, 0, 0); info->need_refresh = true; info->need_push = true; @@ -5741,27 +5949,25 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) break; case DISPLAYLIST_PRIVACY_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - { - bool available = false; - if (menu_displaylist_parse_settings_enum(menu, info, + + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CAMERA_ALLOW, PARSE_ONLY_BOOL, false) == 0) - available = true; - if (menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_LOCATION_ALLOW, - PARSE_ONLY_BOOL, true) == 0) - available = true; + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_LOCATION_ALLOW, + PARSE_ONLY_BOOL, true) == 0) + count++; - if (!available) - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), - msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), - MENU_ENUM_LABEL_NO_SETTINGS_FOUND, - 0, 0, 0); + if (count == 0) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), + MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + 0, 0, 0); - info->need_refresh = true; - info->need_push = true; - } + info->need_refresh = true; + info->need_push = true; break; case DISPLAYLIST_VIDEO_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); @@ -5771,6 +5977,12 @@ 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, + PARSE_ONLY_BOOL, false); + 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, PARSE_ONLY_BOOL, false); @@ -5804,6 +6016,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_AUTO, PARSE_ONLY_FLOAT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED, + PARSE_ONLY_FLOAT, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_FORCE_SRGB_DISABLE, PARSE_ONLY_BOOL, false); @@ -5861,18 +6076,22 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL, PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_HARD_SYNC, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES, - PARSE_ONLY_UINT, false); - menu_displaylist_parse_settings_enum(menu, info, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_FRAME_DELAY, - PARSE_ONLY_UINT, false); + PARSE_ONLY_UINT, false) == 0) + count++; menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION, PARSE_ONLY_BOOL, false); @@ -5910,11 +6129,36 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) info->need_refresh = true; info->need_push = true; break; + case DISPLAYLIST_AUDIO_MIXER_SETTINGS_LIST: + { + unsigned i; + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + + for (i = 0; i < AUDIO_MIXER_MAX_STREAMS; i++) + { + char msg[128]; + char msg_lbl[128]; + snprintf(msg, sizeof(msg), "Mixer Stream #%d :\n", i+1); + snprintf(msg_lbl, sizeof(msg_lbl), "audio_mixer_stream_%d\n", i); + menu_entries_append_enum(info->list, msg, msg_lbl, + MSG_UNKNOWN, + (MENU_SETTINGS_AUDIO_MIXER_STREAM_BEGIN + i), + 0, 0); + count++; + } + + info->need_refresh = true; + info->need_push = true; + } + break; case DISPLAYLIST_AUDIO_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_AUDIO_ENABLE, PARSE_ONLY_BOOL, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_AUDIO_ENABLE_MENU, + PARSE_ONLY_BOOL, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_AUDIO_MUTE, PARSE_ONLY_BOOL, false); @@ -5933,9 +6177,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_AUDIO_SYNC, PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_AUDIO_LATENCY, - PARSE_ONLY_UINT, false); + PARSE_ONLY_UINT, false) == 0) + count++; menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_AUDIO_RESAMPLER_QUALITY, PARSE_ONLY_UINT, false); @@ -5957,7 +6202,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN, PARSE_ONLY_PATH, false); -#ifdef HAVE_WASAPI menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_AUDIO_WASAPI_EXCLUSIVE_MODE, PARSE_ONLY_BOOL, false); @@ -5967,7 +6211,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_AUDIO_WASAPI_SH_BUFFER_LENGTH, PARSE_ONLY_INT, false); -#endif info->need_refresh = true; info->need_push = true; @@ -5977,31 +6220,28 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_MAX_USERS, PARSE_ONLY_UINT, false); -#if TARGET_OS_IPHONE ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_SMALL_KEYBOARD_ENABLE, PARSE_ONLY_BOOL, false); -#endif ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_UNIFIED_MENU_CONTROLS, PARSE_ONLY_BOOL, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR, - PARSE_ONLY_UINT, false); + PARSE_ONLY_UINT, false) == 0) + count++; ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_ICADE_ENABLE, PARSE_ONLY_BOOL, false); ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, PARSE_ONLY_UINT, false); -#ifdef VITA ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_TOUCH_ENABLE, PARSE_ONLY_BOOL, false); ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_PREFER_FRONT_TOUCH, PARSE_ONLY_BOOL, false); -#endif ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, PARSE_ONLY_UINT, false); ret = menu_displaylist_parse_settings_enum(menu, info, @@ -6040,6 +6280,56 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) } } + info->need_refresh = true; + info->need_push = true; + break; + case DISPLAYLIST_LATENCY_SETTINGS_LIST: + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_VIDEO_HARD_SYNC, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_VIDEO_FRAME_DELAY, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_AUDIO_LATENCY, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_RUN_AHEAD_ENABLED, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_RUN_AHEAD_FRAMES, + PARSE_ONLY_UINT, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (count == 0) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), + MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + 0, 0, 0); + info->need_refresh = true; info->need_push = true; break; @@ -6051,8 +6341,12 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) MENU_ENUM_LABEL_VIDEO_SETTINGS, PARSE_ACTION, false); ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_AUDIO_SETTINGS, PARSE_ACTION, false); + ret = menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_AUDIO_MIXER_SETTINGS, PARSE_ACTION, false); ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_INPUT_SETTINGS, PARSE_ACTION, false); + ret = menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_LATENCY_SETTINGS, PARSE_ACTION, false); ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CORE_SETTINGS, PARSE_ACTION, false); ret = menu_displaylist_parse_settings_enum(menu, info, @@ -6070,14 +6364,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) MENU_ENUM_LABEL_ONSCREEN_DISPLAY_SETTINGS, PARSE_ACTION, false); ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_USER_INTERFACE_SETTINGS, PARSE_ACTION, false); -#ifdef HAVE_CHEEVOS ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_RETRO_ACHIEVEMENTS_SETTINGS, PARSE_ACTION, false); -#endif -#ifdef HAVE_LAKKA ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_WIFI_SETTINGS, PARSE_ACTION, false); -#endif ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETWORK_SETTINGS, PARSE_ACTION, false); ret = menu_displaylist_parse_settings_enum(menu, info, @@ -6153,7 +6443,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) case DISPLAYLIST_LOAD_CONTENT_LIST: case DISPLAYLIST_LOAD_CONTENT_SPECIAL: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - + if (!string_is_empty(settings->paths.directory_menu_content)) menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FAVORITES), @@ -6161,33 +6451,34 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) MENU_ENUM_LABEL_FAVORITES, MENU_SETTING_ACTION, 0, 0); - if (settings->bools.menu_content_show_favorites) - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES), - msg_hash_to_str(MENU_ENUM_LABEL_GOTO_FAVORITES), - MENU_ENUM_LABEL_GOTO_FAVORITES, - MENU_SETTING_ACTION, 0, 0); + if (settings->bools.menu_content_show_favorites) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES), + msg_hash_to_str(MENU_ENUM_LABEL_GOTO_FAVORITES), + MENU_ENUM_LABEL_GOTO_FAVORITES, + MENU_SETTING_ACTION, 0, 0); - if (settings->bools.menu_content_show_images) - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_IMAGES), - msg_hash_to_str(MENU_ENUM_LABEL_GOTO_IMAGES), - MENU_ENUM_LABEL_GOTO_IMAGES, - MENU_SETTING_ACTION, 0, 0); - if (settings->bools.menu_content_show_music) - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_MUSIC), - msg_hash_to_str(MENU_ENUM_LABEL_GOTO_MUSIC), - MENU_ENUM_LABEL_GOTO_MUSIC, - MENU_SETTING_ACTION, 0, 0); + if (settings->bools.menu_content_show_images) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_IMAGES), + msg_hash_to_str(MENU_ENUM_LABEL_GOTO_IMAGES), + MENU_ENUM_LABEL_GOTO_IMAGES, + MENU_SETTING_ACTION, 0, 0); + + if (settings->bools.menu_content_show_music) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_MUSIC), + msg_hash_to_str(MENU_ENUM_LABEL_GOTO_MUSIC), + MENU_ENUM_LABEL_GOTO_MUSIC, + MENU_SETTING_ACTION, 0, 0); #ifdef HAVE_FFMPEG - if (settings->bools.menu_content_show_video) - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_VIDEO), - msg_hash_to_str(MENU_ENUM_LABEL_GOTO_VIDEO), - MENU_ENUM_LABEL_GOTO_VIDEO, - MENU_SETTING_ACTION, 0, 0); + if (settings->bools.menu_content_show_video) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_VIDEO), + msg_hash_to_str(MENU_ENUM_LABEL_GOTO_VIDEO), + MENU_ENUM_LABEL_GOTO_VIDEO, + MENU_SETTING_ACTION, 0, 0); #endif if (core_info_list_num_info_files(list)) @@ -6249,6 +6540,38 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) info->need_push = true; break; + case DISPLAYLIST_OPTIONS_OVERRIDES: + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + + if (settings->bools.quick_menu_show_save_core_overrides && !settings->bools.kiosk_mode_enable) + { + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE), + msg_hash_to_str(MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE), + MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, + MENU_SETTING_ACTION, 0, 0); + count++; + } + + if (settings->bools.quick_menu_show_save_game_overrides && !settings->bools.kiosk_mode_enable) + { + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME), + msg_hash_to_str(MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME), + MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, + MENU_SETTING_ACTION, 0, 0); + count++; + } + + if (count == 0) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), + MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + 0, 0, 0); + + info->need_push = true; + break; case DISPLAYLIST_SHADER_PARAMETERS: case DISPLAYLIST_SHADER_PARAMETERS_PRESET: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); @@ -6296,24 +6619,37 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) break; case DISPLAYLIST_RECORDING_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - menu_displaylist_parse_settings_enum(menu, info, + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_RECORD_ENABLE, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_RECORD_CONFIG, - PARSE_ONLY_PATH, false); - menu_displaylist_parse_settings_enum(menu, info, + PARSE_ONLY_PATH, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_RECORD_PATH, - PARSE_ONLY_STRING, false); - menu_displaylist_parse_settings_enum(menu, info, + PARSE_ONLY_STRING, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_RECORD_USE_OUTPUT_DIRECTORY, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_GPU_RECORD, - PARSE_ONLY_BOOL, false); - menu_displaylist_parse_settings_enum(menu, info, + PARSE_ONLY_BOOL, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_POST_FILTER_RECORD, - PARSE_ONLY_BOOL, false); + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (count == 0) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), + MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + 0, 0, 0); info->need_push = true; break; @@ -6340,65 +6676,59 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) if (frontend_driver_has_fork()) #endif { - if (settings->bools.menu_show_load_core) - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_CORE_LIST, PARSE_ACTION, false); + if (settings->bools.menu_show_load_core) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CORE_LIST, PARSE_ACTION, false); } - if (settings->bools.menu_show_load_content) - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_LOAD_CONTENT_LIST, - PARSE_ACTION, false); - if (settings->bools.menu_content_show_history) - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY, - PARSE_ACTION, false); - if (settings->bools.menu_content_show_add) - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_ADD_CONTENT_LIST, - PARSE_ACTION, false); -#ifdef HAVE_NETWORKING - if (settings->bools.menu_content_show_netplay) - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_NETPLAY, - PARSE_ACTION, false); - if (settings->bools.menu_show_online_updater) - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_ONLINE_UPDATER, - PARSE_ACTION, false); -#endif + if (settings->bools.menu_show_load_content) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_LOAD_CONTENT_LIST, + PARSE_ACTION, false); + if (settings->bools.menu_content_show_history) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY, + PARSE_ACTION, false); + if (settings->bools.menu_content_show_add) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_ADD_CONTENT_LIST, + PARSE_ACTION, false); + if (settings->bools.menu_content_show_netplay) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_NETPLAY, + PARSE_ACTION, false); + if (settings->bools.menu_show_online_updater) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_ONLINE_UPDATER, + PARSE_ACTION, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_SETTINGS, PARSE_ACTION, false); - if (settings->bools.menu_show_information) - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_INFORMATION_LIST, - PARSE_ACTION, false); -#ifndef HAVE_DYNAMIC + if (settings->bools.menu_show_information) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_INFORMATION_LIST, + PARSE_ACTION, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_RESTART_RETROARCH, PARSE_ACTION, false); -#endif - if (settings->bools.menu_show_configurations) - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_CONFIGURATIONS_LIST, - PARSE_ACTION, false); - if (settings->bools.menu_show_help) - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_HELP_LIST, - PARSE_ACTION, false); - if (settings->bools.menu_show_quit_retroarch) - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_QUIT_RETROARCH, - PARSE_ACTION, false); -#if defined(HAVE_LAKKA) - if (settings->bools.menu_show_reboot) - menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_REBOOT, - PARSE_ACTION, false); + if (settings->bools.menu_show_configurations) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CONFIGURATIONS_LIST, + PARSE_ACTION, false); + if (settings->bools.menu_show_help) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_HELP_LIST, + PARSE_ACTION, false); + if (settings->bools.menu_show_quit_retroarch) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_QUIT_RETROARCH, + PARSE_ACTION, false); + if (settings->bools.menu_show_reboot) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_REBOOT, + PARSE_ACTION, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_SHUTDOWN, PARSE_ACTION, false); -#endif info->need_push = true; } break; @@ -6500,39 +6830,43 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) break; case DISPLAYLIST_ACCOUNTS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); -#ifdef HAVE_CHEEVOS - ret = menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, - PARSE_ACTION, false); -#else - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ITEMS), - msg_hash_to_str(MENU_ENUM_LABEL_NO_ITEMS), - MENU_ENUM_LABEL_NO_ITEMS, - MENU_SETTING_NO_ITEM, 0, 0); - ret = 0; -#endif + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, + PARSE_ACTION, false) == 0) + count++; + + if (count == 0) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ITEMS), + msg_hash_to_str(MENU_ENUM_LABEL_NO_ITEMS), + MENU_ENUM_LABEL_NO_ITEMS, + MENU_SETTING_NO_ITEM, 0, 0); + + ret = 0; info->need_refresh = true; info->need_push = true; break; case DISPLAYLIST_ACCOUNTS_CHEEVOS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); -#ifdef HAVE_CHEEVOS - ret = menu_displaylist_parse_settings_enum(menu, info, + + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CHEEVOS_USERNAME, - PARSE_ONLY_STRING, false); - ret = menu_displaylist_parse_settings_enum(menu, info, + PARSE_ONLY_STRING, false) == 0) + count++; + if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CHEEVOS_PASSWORD, - PARSE_ONLY_STRING, false); -#else - menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ITEMS), - msg_hash_to_str(MENU_ENUM_LABEL_NO_ITEMS), - MENU_ENUM_LABEL_NO_ITEMS, - MENU_SETTING_NO_ITEM, 0, 0); - ret = 0; -#endif + PARSE_ONLY_STRING, false) == 0) + count++; + + if (count == 0) + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ITEMS), + msg_hash_to_str(MENU_ENUM_LABEL_NO_ITEMS), + MENU_ENUM_LABEL_NO_ITEMS, + MENU_SETTING_NO_ITEM, 0, 0); + + ret = 0; info->need_refresh = true; info->need_push = true; break; @@ -6617,16 +6951,19 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) free(info->exts); if (info->path) free(info->path); - info->exts = strdup("dbc"); - info->path = strdup(settings->paths.directory_cursor); + info->exts = strdup("dbc"); + info->path = strdup(settings->paths.directory_cursor); break; case DISPLAYLIST_CONFIG_FILES: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); filebrowser_clear_type(); + info->type_default = FILE_TYPE_CONFIG; + if (!string_is_empty(info->exts)) free(info->exts); - info->exts = strdup("cfg"); + + info->exts = strdup("cfg"); load_content = false; use_filebrowser = true; break; @@ -6646,17 +6983,17 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) info->type_default = FILE_TYPE_SHADER_PRESET; if (video_shader_is_supported(RARCH_SHADER_CG) && - video_shader_get_type_from_ext("cgp", &is_preset) + video_shader_get_type_from_ext("cgp", &is_preset) != RARCH_SHADER_NONE) string_list_append(str_list, "cgp", attr); if (video_shader_is_supported(RARCH_SHADER_GLSL) && - video_shader_get_type_from_ext("glslp", &is_preset) + video_shader_get_type_from_ext("glslp", &is_preset) != RARCH_SHADER_NONE) string_list_append(str_list, "glslp", attr); if (video_shader_is_supported(RARCH_SHADER_SLANG) && - video_shader_get_type_from_ext("slangp", &is_preset) + video_shader_get_type_from_ext("slangp", &is_preset) != RARCH_SHADER_NONE) string_list_append(str_list, "slangp", attr); string_list_join_concat(new_exts, sizeof(new_exts), str_list, "|"); @@ -6685,17 +7022,17 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) if (video_shader_is_supported(RARCH_SHADER_CG) && - video_shader_get_type_from_ext("cg", &is_preset) + video_shader_get_type_from_ext("cg", &is_preset) != RARCH_SHADER_NONE) string_list_append(str_list, "cg", attr); if (video_shader_is_supported(RARCH_SHADER_GLSL) && - video_shader_get_type_from_ext("glsl", &is_preset) + video_shader_get_type_from_ext("glsl", &is_preset) != RARCH_SHADER_NONE) string_list_append(str_list, "glsl", attr); if (video_shader_is_supported(RARCH_SHADER_SLANG) && - video_shader_get_type_from_ext("slang", &is_preset) + video_shader_get_type_from_ext("slang", &is_preset) != RARCH_SHADER_NONE) string_list_append(str_list, "slang", attr); @@ -6715,7 +7052,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) use_filebrowser = true; if (!string_is_empty(info->exts)) free(info->exts); - info->exts = strdup("filt"); + info->exts = strdup("filt"); break; case DISPLAYLIST_IMAGES: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); @@ -6797,7 +7134,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) use_filebrowser = true; if (!string_is_empty(info->exts)) free(info->exts); - info->exts = strdup("dsp"); + info->exts = strdup("dsp"); break; case DISPLAYLIST_CHEAT_FILES: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); @@ -6807,7 +7144,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) use_filebrowser = true; if (!string_is_empty(info->exts)) free(info->exts); - info->exts = strdup("cht"); + info->exts = strdup("cht"); break; case DISPLAYLIST_CONTENT_HISTORY: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); @@ -6816,7 +7153,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) use_filebrowser = true; if (!string_is_empty(info->exts)) free(info->exts); - info->exts = strdup("lpl"); + info->exts = strdup("lpl"); break; case DISPLAYLIST_FONTS: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); @@ -6826,7 +7163,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) use_filebrowser = true; if (!string_is_empty(info->exts)) free(info->exts); - info->exts = strdup("ttf"); + info->exts = strdup("ttf"); break; case DISPLAYLIST_OVERLAYS: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); @@ -6836,7 +7173,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) use_filebrowser = true; if (!string_is_empty(info->exts)) free(info->exts); - info->exts = strdup("cfg"); + info->exts = strdup("cfg"); break; case DISPLAYLIST_RECORD_CONFIG_FILES: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); @@ -6846,17 +7183,17 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) use_filebrowser = true; if (!string_is_empty(info->exts)) free(info->exts); - info->exts = strdup("cfg"); + info->exts = strdup("cfg"); break; case DISPLAYLIST_REMAP_FILES: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); filebrowser_clear_type(); - info->type_default = FILE_TYPE_REMAP; - load_content = false; - use_filebrowser = true; + info->type_default = FILE_TYPE_REMAP; + load_content = false; + use_filebrowser = true; if (!string_is_empty(info->exts)) free(info->exts); - info->exts = strdup("rmp"); + info->exts = strdup("rmp"); break; case DISPLAYLIST_DATABASE_PLAYLISTS_HORIZONTAL: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index 7bcd105959..867ebde73e 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -110,6 +110,7 @@ enum menu_displaylist_ctl_state DISPLAYLIST_ACHIEVEMENT_LIST, DISPLAYLIST_USER_BINDS_LIST, DISPLAYLIST_ACCOUNTS_LIST, + DISPLAYLIST_MIXER_STREAM_SETTINGS_LIST, DISPLAYLIST_DRIVER_SETTINGS_LIST, DISPLAYLIST_VIDEO_SETTINGS_LIST, DISPLAYLIST_CONFIGURATION_SETTINGS_LIST, @@ -118,8 +119,10 @@ enum menu_displaylist_ctl_state DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST, DISPLAYLIST_REWIND_SETTINGS_LIST, DISPLAYLIST_AUDIO_SETTINGS_LIST, + DISPLAYLIST_AUDIO_MIXER_SETTINGS_LIST, DISPLAYLIST_CORE_SETTINGS_LIST, DISPLAYLIST_INPUT_SETTINGS_LIST, + DISPLAYLIST_LATENCY_SETTINGS_LIST, DISPLAYLIST_INPUT_HOTKEY_BINDS_LIST, DISPLAYLIST_ONSCREEN_OVERLAY_SETTINGS_LIST, DISPLAYLIST_ONSCREEN_DISPLAY_SETTINGS_LIST, @@ -153,6 +156,7 @@ enum menu_displaylist_ctl_state DISPLAYLIST_OPTIONS_MANAGEMENT, DISPLAYLIST_OPTIONS_DISK, DISPLAYLIST_OPTIONS_SHADERS, + DISPLAYLIST_OPTIONS_OVERRIDES, DISPLAYLIST_NETPLAY, DISPLAYLIST_ADD_CONTENT_LIST, DISPLAYLIST_CONFIGURATIONS_LIST, diff --git a/menu/menu_driver.c b/menu/menu_driver.c index c335abad97..23b7ca1750 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -25,6 +25,10 @@ #include #include +#ifdef WIIU +#include +#endif + #ifdef HAVE_CONFIG_H #include "../config.h" #endif @@ -61,6 +65,12 @@ #define PARTICLES_COUNT 100 +typedef struct menu_ctx_load_image +{ + void *data; + enum menu_image_type type; +} menu_ctx_load_image_t; + /* Menu drivers */ static const menu_ctx_driver_t *menu_ctx_drivers[] = { #if defined(HAVE_XUI) @@ -93,6 +103,9 @@ static menu_display_ctx_driver_t *menu_display_ctx_drivers[] = { #ifdef HAVE_D3D9 &menu_display_ctx_d3d9, #endif +#ifdef HAVE_D3D10 + &menu_display_ctx_d3d10, +#endif #ifdef HAVE_D3D11 &menu_display_ctx_d3d11, #endif @@ -176,9 +189,6 @@ static bool menu_driver_pending_shutdown = false; /* Are we binding a button inside the menu? */ static bool menu_driver_is_binding = false; -/* The currently active playlist that we are using inside the menu */ -static playlist_t *menu_driver_playlist = NULL; - static menu_handle_t *menu_driver_data = NULL; static const menu_ctx_driver_t *menu_driver_ctx = NULL; static void *menu_userdata = NULL; @@ -190,6 +200,31 @@ static unsigned scroll_index_size = 0; static unsigned scroll_acceleration = 0; static size_t menu_driver_selection_ptr = 0; +/* Returns the OSK key at a given position */ +int menu_display_osk_ptr_at_pos(void *data, int x, int y, + unsigned width, unsigned height) +{ + unsigned i; + int ptr_width = width / 11; + int ptr_height = height / 10; + + if (ptr_width >= ptr_height) + ptr_width = ptr_height; + + for (i = 0; i < 44; i++) + { + int line_y = (i / 11)*height/10.0; + int ptr_x = width/2.0 - (11*ptr_width)/2.0 + (i % 11) * ptr_width; + int ptr_y = height/2.0 + ptr_height*1.5 + line_y - ptr_height; + + if (x > ptr_x && x < ptr_x + ptr_width + && y > ptr_y && y < ptr_y + ptr_height) + return i; + } + + return -1; +} + enum menu_toggle_reason menu_display_toggle_get_reason(void) { return menu_display_toggle_reason; @@ -233,6 +268,10 @@ static bool menu_display_check_compatibility( if (string_is_equal(video_driver, "d3d9")) return true; break; + case MENU_VIDEO_DRIVER_DIRECT3D10: + if (string_is_equal(video_driver, "d3d10")) + return true; + break; case MENU_VIDEO_DRIVER_DIRECT3D11: if (string_is_equal(video_driver, "d3d11")) return true; @@ -388,7 +427,7 @@ void menu_display_set_font_framebuffer(const uint8_t *buffer) menu_display_font_framebuf = buffer; } -static bool menu_display_libretro_running( +bool menu_display_libretro_running( bool rarch_is_inited, bool rarch_is_dummy_core) { @@ -536,16 +575,23 @@ void menu_display_unset_framebuffer_dirty_flag(void) * RGUI or XMB use this. */ float menu_display_get_dpi(void) { - settings_t *settings = config_get_ptr(); - float dpi; unsigned width, height; + settings_t *settings = config_get_ptr(); + float dpi = 0.0f; + float diagonal = 6.5f; video_driver_get_size(&width, &height); if (!settings) return true; - dpi = sqrt((width * width) + (height * height)) / 6.5; +#ifdef RARCH_MOBILE + diagonal = 5.0f; +#endif + + /* Generic dpi calculation formula, + * the divider is the screen diagonal in inches */ + dpi = sqrt((width * width) + (height * height)) / diagonal; if (settings->bools.menu_dpi_override_enable) return settings->uints.menu_dpi_override_value; @@ -629,7 +675,7 @@ void menu_display_draw_bg(menu_display_ctx_draw_t *draw, coords.vertex = new_vertex; coords.tex_coord = new_tex_coord; coords.lut_tex_coord = new_tex_coord; - coords.color = (const float*)draw->color; + coords.color = (const float*)draw->color; draw->coords = &coords; draw->scale_factor = 1.0f; @@ -1023,9 +1069,9 @@ void menu_display_rotate_z(menu_display_ctx_rotate_draw_t *draw, math_matrix_4x4 *b = NULL; if ( - !draw || - !menu_disp || - !menu_disp->get_default_mvp || + !draw || + !menu_disp || + !menu_disp->get_default_mvp || menu_disp->handles_transform ) return; @@ -1058,6 +1104,14 @@ bool menu_display_get_tex_coords(menu_display_ctx_coord_draw_t *draw) return true; } +static bool menu_driver_load_image(menu_ctx_load_image_t *load_image_info) +{ + if (menu_driver_ctx && menu_driver_ctx->load_image) + return menu_driver_ctx->load_image(menu_userdata, + load_image_info->data, load_image_info->type); + return false; +} + void menu_display_handle_thumbnail_upload(void *task_data, void *user_data, const char *err) { @@ -1074,6 +1128,22 @@ void menu_display_handle_thumbnail_upload(void *task_data, free(user_data); } +void menu_display_handle_left_thumbnail_upload(void *task_data, + void *user_data, const char *err) +{ + menu_ctx_load_image_t load_image_info; + struct texture_image *img = (struct texture_image*)task_data; + + load_image_info.data = img; + load_image_info.type = MENU_IMAGE_LEFT_THUMBNAIL; + + menu_driver_load_image(&load_image_info); + + image_texture_free(img); + free(img); + free(user_data); +} + void menu_display_handle_savestate_thumbnail_upload(void *task_data, void *user_data, const char *err) { @@ -1290,6 +1360,71 @@ void menu_display_snow(int width, int height) } } +void menu_display_draw_keyboard( + uintptr_t hover_texture, + const font_data_t *font, + video_frame_info_t *video_info, + char *grid[], unsigned id) +{ + unsigned i; + int ptr_width, ptr_height; + unsigned width = video_info->width; + unsigned height = video_info->height; + float dark[16] = { + 0.00, 0.00, 0.00, 0.85, + 0.00, 0.00, 0.00, 0.85, + 0.00, 0.00, 0.00, 0.85, + 0.00, 0.00, 0.00, 0.85, + }; + + float white[16]= { + 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, + }; + + menu_display_draw_quad( + video_info, + 0, height/2.0, width, height/2.0, + width, height, + &dark[0]); + + ptr_width = width / 11; + ptr_height = height / 10; + + if (ptr_width >= ptr_height) + ptr_width = ptr_height; + + for (i = 0; i < 44; i++) + { + int line_y = (i / 11) * height / 10.0; + + if (i == id) + { + menu_display_blend_begin(video_info); + + menu_display_draw_texture( + video_info, + width/2.0 - (11*ptr_width)/2.0 + (i % 11) * ptr_width, + height/2.0 + ptr_height*1.5 + line_y, + ptr_width, ptr_height, + width, height, + &white[0], + hover_texture); + + menu_display_blend_end(video_info); + } + + menu_display_draw_text(font, grid[i], + 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, + false, 0); + } +} + /* Draw text on top of the screen. */ void menu_display_draw_text( @@ -1525,6 +1660,8 @@ static void menu_driver_toggle(bool on) settings_t *settings = config_get_ptr(); bool pause_libretro = settings ? settings->bools.menu_pause_libretro : false; + bool enable_menu_sound = settings ? + settings->bools.audio_enable_menu : false; menu_driver_toggled = on; @@ -1545,6 +1682,12 @@ static void menu_driver_toggle(bool on) if (menu_driver_alive) { bool refresh = false; + +#ifdef WIIU + /* Enable burn-in protection menu is running */ + IMEnableDim(); +#endif + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); /* Menu should always run with vsync on. */ @@ -1552,7 +1695,7 @@ static void menu_driver_toggle(bool on) /* Stop all rumbling before entering the menu. */ command_event(CMD_EVENT_RUMBLE_STOP, NULL); - if (pause_libretro) + if (pause_libretro && !enable_menu_sound) command_event(CMD_EVENT_AUDIO_STOP, NULL); /* Override keyboard callback to redirect to menu instead. @@ -1568,10 +1711,17 @@ static void menu_driver_toggle(bool on) } else { +#ifdef WIIU + /* Disable burn-in protection while core is running; this is needed + * because HID inputs don't count for the purpose of Wii U + * power-saving. */ + IMDisableDim(); +#endif + if (!rarch_ctl(RARCH_CTL_IS_SHUTDOWN, NULL)) driver_set_nonblock_state(); - if (pause_libretro) + if (pause_libretro && !enable_menu_sound) command_event(CMD_EVENT_AUDIO_START, NULL); /* Restore libretro keyboard callback. */ @@ -1788,14 +1938,6 @@ void menu_driver_populate_entries(menu_displaylist_info_t *info) info->label, info->type); } -bool menu_driver_load_image(menu_ctx_load_image_t *load_image_info) -{ - if (menu_driver_ctx && menu_driver_ctx->load_image) - return menu_driver_ctx->load_image(menu_userdata, - load_image_info->data, load_image_info->type); - return false; -} - bool menu_driver_push_list(menu_ctx_displaylist_t *disp_list) { if (menu_driver_ctx->list_push) @@ -1851,11 +1993,6 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) case RARCH_MENU_CTL_SET_PENDING_SHUTDOWN: menu_driver_pending_shutdown = true; break; - case RARCH_MENU_CTL_PLAYLIST_FREE: - if (menu_driver_playlist) - playlist_free(menu_driver_playlist); - menu_driver_playlist = NULL; - break; case RARCH_MENU_CTL_FIND_DRIVER: { int i; @@ -1896,23 +2033,6 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) } } break; - case RARCH_MENU_CTL_PLAYLIST_INIT: - { - const char *path = (const char*)data; - if (string_is_empty(path)) - return false; - menu_driver_playlist = playlist_init(path, - COLLECTION_SIZE); - } - break; - case RARCH_MENU_CTL_PLAYLIST_GET: - { - playlist_t **playlist = (playlist_t**)data; - if (!playlist) - return false; - *playlist = menu_driver_playlist; - } - break; case RARCH_MENU_CTL_SET_PREVENT_POPULATE: menu_driver_prevent_populate = true; break; @@ -1944,7 +2064,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) if (menu_driver_data_own) return true; - menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_FREE, NULL); + playlist_free_cached(); menu_shader_manager_free(); if (menu_driver_data) @@ -2183,7 +2303,8 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) if (!menu_driver_ctx || !menu_driver_ctx->update_thumbnail_path) return false; - menu_driver_ctx->update_thumbnail_path(menu_userdata, (unsigned)selection); + menu_driver_ctx->update_thumbnail_path(menu_userdata, (unsigned)selection, 'L'); + menu_driver_ctx->update_thumbnail_path(menu_userdata, (unsigned)selection, 'R'); } break; case RARCH_MENU_CTL_UPDATE_THUMBNAIL_IMAGE: diff --git a/menu/menu_driver.h b/menu/menu_driver.h index ed2489c0b1..cca2d9f435 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -32,6 +32,7 @@ #include "menu_input.h" #include "menu_entries.h" +#include "../audio/audio_driver.h" #include "../gfx/video_driver.h" #include "../file_path_special.h" #include "../gfx/font_driver.h" @@ -61,6 +62,7 @@ enum menu_image_type MENU_IMAGE_NONE = 0, MENU_IMAGE_WALLPAPER, MENU_IMAGE_THUMBNAIL, + MENU_IMAGE_LEFT_THUMBNAIL, MENU_IMAGE_SAVESTATE_THUMBNAIL }; @@ -99,9 +101,6 @@ enum rarch_menu_ctl_state RARCH_MENU_CTL_SET_OWN_DRIVER, RARCH_MENU_CTL_UNSET_OWN_DRIVER, RARCH_MENU_CTL_OWNS_DRIVER, - RARCH_MENU_CTL_PLAYLIST_FREE, - RARCH_MENU_CTL_PLAYLIST_INIT, - RARCH_MENU_CTL_PLAYLIST_GET, RARCH_MENU_CTL_FIND_DRIVER, RARCH_MENU_CTL_LIST_FREE, RARCH_MENU_CTL_LIST_SET_SELECTION, @@ -133,6 +132,8 @@ enum rarch_menu_ctl_state MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL }; +#define MENU_SETTINGS_AUDIO_MIXER_MAX_STREAMS (AUDIO_MIXER_MAX_STREAMS-1) + enum menu_settings_type { MENU_SETTINGS_NONE = FILE_TYPE_LAST + 1, @@ -190,6 +191,23 @@ enum menu_settings_type MENU_SETTINGS_CORE_DISK_OPTIONS_DISK_IMAGE_APPEND, MENU_SETTINGS_CORE_DISK_OPTIONS_DISK_CYCLE_TRAY_STATUS, + MENU_SETTINGS_AUDIO_MIXER_STREAM_BEGIN, + MENU_SETTINGS_AUDIO_MIXER_STREAM_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_BEGIN + MENU_SETTINGS_AUDIO_MIXER_MAX_STREAMS, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_BEGIN, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_BEGIN + MENU_SETTINGS_AUDIO_MIXER_MAX_STREAMS, + + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_BEGIN, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_BEGIN + MENU_SETTINGS_AUDIO_MIXER_MAX_STREAMS, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_BEGIN, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_BEGIN + MENU_SETTINGS_AUDIO_MIXER_MAX_STREAMS, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN + MENU_SETTINGS_AUDIO_MIXER_MAX_STREAMS, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN + MENU_SETTINGS_AUDIO_MIXER_MAX_STREAMS, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_SEQUENTIAL_BEGIN, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_SEQUENTIAL_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_SEQUENTIAL_BEGIN + MENU_SETTINGS_AUDIO_MIXER_MAX_STREAMS, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN + MENU_SETTINGS_AUDIO_MIXER_MAX_STREAMS, MENU_SETTINGS_BIND_BEGIN, MENU_SETTINGS_BIND_LAST = MENU_SETTINGS_BIND_BEGIN + RARCH_ANALOG_RIGHT_Y_MINUS, MENU_SETTINGS_BIND_ALL_LAST = MENU_SETTINGS_BIND_BEGIN + RARCH_MENU_TOGGLE, @@ -205,9 +223,9 @@ enum menu_settings_type MENU_SETTINGS_CHEAT_BEGIN, MENU_SETTINGS_CHEAT_END = MENU_SETTINGS_CHEAT_BEGIN + (MAX_CHEAT_COUNTERS - 1), MENU_SETTINGS_INPUT_DESC_BEGIN, - MENU_SETTINGS_INPUT_DESC_END = MENU_SETTINGS_INPUT_DESC_BEGIN + (MAX_USERS * (RARCH_FIRST_CUSTOM_BIND + 4)), + MENU_SETTINGS_INPUT_DESC_END = MENU_SETTINGS_INPUT_DESC_BEGIN + ((RARCH_FIRST_CUSTOM_BIND + 8) * MAX_USERS), MENU_SETTINGS_INPUT_DESC_KBD_BEGIN, - MENU_SETTINGS_INPUT_DESC_KBD_END = MENU_SETTINGS_INPUT_DESC_KBD_BEGIN + 135, + MENU_SETTINGS_INPUT_DESC_KBD_END = MENU_SETTINGS_INPUT_DESC_KBD_BEGIN + (RARCH_MAX_KEYS * MAX_USERS), MENU_SETTINGS_SUBSYSTEM_LOAD, @@ -287,6 +305,7 @@ enum menu_display_driver_type MENU_VIDEO_DRIVER_VULKAN, MENU_VIDEO_DRIVER_DIRECT3D8, MENU_VIDEO_DRIVER_DIRECT3D9, + MENU_VIDEO_DRIVER_DIRECT3D10, MENU_VIDEO_DRIVER_DIRECT3D11, MENU_VIDEO_DRIVER_DIRECT3D12, MENU_VIDEO_DRIVER_VITA2D, @@ -355,9 +374,7 @@ typedef struct menu_display_ctx_driver typedef struct { unsigned rpl_entry_selection_ptr; - unsigned rdb_entry_start_game_selection_ptr; size_t core_len; - size_t hack_shader_pass; uint64_t state; char *core_buf; @@ -372,6 +389,15 @@ typedef struct char db_playlist_file[PATH_MAX_LENGTH]; char filebrowser_label[PATH_MAX_LENGTH]; char detect_content_path[PATH_MAX_LENGTH]; + + /* This is used for storing intermediary variables + * that get used later on during menu actions - + * for instance, selecting a shader pass for a shader + * slot */ + struct + { + unsigned unsigned_var; + } scratchpad; } menu_handle_t; typedef struct menu_display_ctx_draw @@ -491,7 +517,7 @@ typedef struct menu_ctx_driver int (*pointer_tap)(void *data, unsigned x, unsigned y, unsigned ptr, menu_file_list_cbs_t *cbs, menu_entry_t *entry, unsigned action); - void (*update_thumbnail_path)(void *data, unsigned i); + void (*update_thumbnail_path)(void *data, unsigned i, char pos); void (*update_thumbnail_image)(void *data); void (*set_thumbnail_system)(void *data, char* s, size_t len); void (*set_thumbnail_content)(void *data, char* s, size_t len); @@ -506,12 +532,6 @@ typedef struct menu_ctx_driver menu_entry_t *entry, unsigned action); } menu_ctx_driver_t; -typedef struct menu_ctx_load_image -{ - void *data; - enum menu_image_type type; -} menu_ctx_load_image_t; - typedef struct menu_ctx_displaylist { menu_displaylist_info_t *info; @@ -629,8 +649,6 @@ void menu_driver_navigation_set(bool scroll); void menu_driver_populate_entries(menu_displaylist_info_t *info); -bool menu_driver_load_image(menu_ctx_load_image_t *load_image_info); - bool menu_driver_push_list(menu_ctx_displaylist_t *disp_list); bool menu_driver_init(bool video_is_threaded); @@ -657,6 +675,8 @@ video_coord_array_t *menu_display_get_coords_array(void); const uint8_t *menu_display_get_font_framebuffer(void); void menu_display_set_font_framebuffer(const uint8_t *buffer); bool menu_display_libretro(bool is_idle, bool is_inited, bool is_dummy); +bool menu_display_libretro_running(bool rarch_is_inited, + bool rarch_is_dummy_core); void menu_display_set_width(unsigned width); void menu_display_get_fb_size(unsigned *fb_width, unsigned *fb_height, @@ -684,6 +704,11 @@ void menu_display_clear_color(menu_display_ctx_clearcolor_t *color, video_frame_info_t *video_info); void menu_display_draw(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info); +void menu_display_draw_keyboard( + uintptr_t hover_texture, + const font_data_t *font, + video_frame_info_t *video_info, + char *grid[], unsigned id); void menu_display_draw_pipeline(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info); @@ -721,6 +746,9 @@ void menu_display_handle_wallpaper_upload(void *task_data, void menu_display_handle_thumbnail_upload(void *task_data, void *user_data, const char *err); +void menu_display_handle_left_thumbnail_upload(void *task_data, + void *user_data, const char *err); + void menu_display_handle_savestate_thumbnail_upload(void *task_data, void *user_data, const char *err); @@ -746,11 +774,20 @@ void menu_display_draw_text( #define menu_display_set_alpha(color, alpha_value) (color[3] = color[7] = color[11] = color[15] = (alpha_value)) -font_data_t *menu_display_font(enum application_special_type type, float font_size, +font_data_t *menu_display_font( + enum application_special_type type, + float font_size, bool video_is_threaded); -void menu_display_reset_textures_list(const char *texture_path, const char *iconpath, - uintptr_t *item, enum texture_filter_type filter_type); +void menu_display_reset_textures_list( + const char *texture_path, + const char *iconpath, + uintptr_t *item, + enum texture_filter_type filter_type); + +/* Returns the OSK key at a given position */ +int menu_display_osk_ptr_at_pos(void *data, int x, int y, + unsigned width, unsigned height); void menu_driver_destroy(void); @@ -760,6 +797,7 @@ extern menu_display_ctx_driver_t menu_display_ctx_gl; extern menu_display_ctx_driver_t menu_display_ctx_vulkan; extern menu_display_ctx_driver_t menu_display_ctx_d3d8; extern menu_display_ctx_driver_t menu_display_ctx_d3d9; +extern menu_display_ctx_driver_t menu_display_ctx_d3d10; extern menu_display_ctx_driver_t menu_display_ctx_d3d11; extern menu_display_ctx_driver_t menu_display_ctx_d3d12; extern menu_display_ctx_driver_t menu_display_ctx_vita2d; diff --git a/menu/menu_entries.c b/menu/menu_entries.c index ff893aad4d..05d4b69707 100644 --- a/menu/menu_entries.c +++ b/menu/menu_entries.c @@ -62,29 +62,40 @@ static void menu_list_free_list(file_list_t *list) static void menu_list_free(menu_list_t *menu_list) { - unsigned i; if (!menu_list) return; - for (i = 0; i < menu_list->menu_stack_size; i++) + if (menu_list->menu_stack) { - if (!menu_list->menu_stack[i]) - continue; + unsigned i; - menu_list_free_list(menu_list->menu_stack[i]); - menu_list->menu_stack[i] = NULL; - } - for (i = 0; i < menu_list->selection_buf_size; i++) - { - if (!menu_list->selection_buf[i]) - continue; + for (i = 0; i < menu_list->menu_stack_size; i++) + { + if (!menu_list->menu_stack[i]) + continue; - menu_list_free_list(menu_list->selection_buf[i]); - menu_list->selection_buf[i] = NULL; + menu_list_free_list(menu_list->menu_stack[i]); + menu_list->menu_stack[i] = NULL; + } + + free(menu_list->menu_stack); } - free(menu_list->menu_stack); - free(menu_list->selection_buf); + if (menu_list->selection_buf) + { + unsigned i; + + for (i = 0; i < menu_list->selection_buf_size; i++) + { + if (!menu_list->selection_buf[i]) + continue; + + menu_list_free_list(menu_list->selection_buf[i]); + menu_list->selection_buf[i] = NULL; + } + + free(menu_list->selection_buf); + } free(menu_list); } diff --git a/menu/menu_event.c b/menu/menu_event.c index 01eb555188..f08fa404e1 100644 --- a/menu/menu_event.c +++ b/menu/menu_event.c @@ -139,7 +139,7 @@ void menu_event_kb_set(bool down, enum retro_key key) * entire button state either but do a separate event per button * state. */ -unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) +unsigned menu_event(input_bits_t *p_input, input_bits_t *p_trigger_input) { menu_animation_ctx_delta_t delta; float delta_time; diff --git a/menu/menu_event.h b/menu/menu_event.h index ce00c5e5dd..cae9ec381b 100644 --- a/menu/menu_event.h +++ b/menu/menu_event.h @@ -44,7 +44,7 @@ RETRO_BEGIN_DECLS * entire button state either but do a separate event per button * state. */ -unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_state); +unsigned menu_event(input_bits_t *p_input, input_bits_t *p_trigger_state); /* Set a specific keyboard key. * diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 6f17dcfeae..1fc6e9a3fc 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -55,6 +55,7 @@ #include "widgets/menu_input_bind_dialog.h" #include "menu_setting.h" +#include "menu_cbs.h" #include "menu_driver.h" #include "menu_animation.h" #include "menu_input.h" @@ -234,37 +235,8 @@ static void setting_get_string_representation_int_audio_wasapi_sh_buffer_length( } #endif -static int setting_uint_action_left_custom_viewport_width(void *data, bool wraparound) -{ - video_viewport_t vp; - struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); - video_viewport_t *custom = video_viewport_get_custom(); - settings_t *settings = config_get_ptr(); - struct retro_game_geometry *geom = (struct retro_game_geometry*) - &av_info->geometry; - - if (!settings || !av_info) - return -1; - - video_driver_get_viewport_info(&vp); - - if (custom->width <= 1) - custom->width = 1; - else if (settings->bools.video_scale_integer) - { - if (custom->width > geom->base_width) - custom->width -= geom->base_width; - } - else - custom->width -= 1; - - aspectratio_lut[ASPECT_RATIO_CUSTOM].value = - (float)custom->width / custom->height; - - return 0; -} - -static int setting_uint_action_right_custom_viewport_width(void *data, bool wraparound) +static int setting_uint_action_right_custom_viewport_width( + void *data, bool wraparound) { video_viewport_t vp; struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); @@ -289,37 +261,8 @@ static int setting_uint_action_right_custom_viewport_width(void *data, bool wrap return 0; } -static int setting_uint_action_left_custom_viewport_height(void *data, bool wraparound) -{ - video_viewport_t vp; - struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); - video_viewport_t *custom = video_viewport_get_custom(); - settings_t *settings = config_get_ptr(); - struct retro_game_geometry *geom = (struct retro_game_geometry*) - &av_info->geometry; - - if (!settings || !av_info) - return -1; - - video_driver_get_viewport_info(&vp); - - if (custom->height <= 1) - custom->height = 1; - else if (settings->bools.video_scale_integer) - { - if (custom->height > geom->base_height) - custom->height -= geom->base_height; - } - else - custom->height -= 1; - - aspectratio_lut[ASPECT_RATIO_CUSTOM].value = - (float)custom->width / custom->height; - - return 0; -} - -static int setting_uint_action_right_custom_viewport_height(void *data, bool wraparound) +static int setting_uint_action_right_custom_viewport_height( + void *data, bool wraparound) { video_viewport_t vp; struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); @@ -345,32 +288,8 @@ static int setting_uint_action_right_custom_viewport_height(void *data, bool wra } #if !defined(RARCH_CONSOLE) -static int setting_string_action_left_audio_device(void *data, bool wraparound) -{ - int audio_device_index; - struct string_list *ptr = NULL; - rarch_setting_t *setting = (rarch_setting_t*)data; - - if (!audio_driver_get_devices_list((void**)&ptr)) - return -1; - - if (!ptr) - return -1; - - /* Get index in the string list */ - audio_device_index = string_list_find_elem(ptr,setting->value.target.string) - 1; - audio_device_index--; - - /* Reset index if needed */ - if (audio_device_index < 0) - audio_device_index = (int)(ptr->size - 1); - - strlcpy(setting->value.target.string, ptr->elems[audio_device_index].data, setting->size); - - return 0; -} - -static int setting_string_action_right_audio_device(void *data, bool wraparound) +static int setting_string_action_right_audio_device( + void *data, bool wraparound) { int audio_device_index; struct string_list *ptr = NULL; @@ -396,38 +315,6 @@ static int setting_string_action_right_audio_device(void *data, bool wraparound) } #endif -static int setting_string_action_left_driver(void *data, - bool wraparound) -{ - driver_ctx_info_t drv; - rarch_setting_t *setting = (rarch_setting_t*)data; - - if (!setting) - return -1; - - drv.label = setting->name; - drv.s = setting->value.target.string; - drv.len = setting->size; - - if (!driver_ctl(RARCH_DRIVER_CTL_FIND_PREV, &drv)) - { - settings_t *settings = config_get_ptr(); - - if (settings && settings->bools.menu_navigation_wraparound_enable) - { - drv.label = setting->name; - drv.s = setting->value.target.string; - drv.len = setting->size; - driver_ctl(RARCH_DRIVER_CTL_FIND_LAST, &drv); - } - } - - if (setting->change_handler) - setting->change_handler(setting); - - return 0; -} - static int setting_string_action_right_driver(void *data, bool wraparound) { @@ -1145,24 +1032,6 @@ static int setting_action_start_video_refresh_rate_auto( ******* ACTION TOGGLE CALLBACK FUNCTIONS ******* **/ -static int setting_action_left_analog_dpad_mode(void *data, bool wraparound) -{ - unsigned port = 0; - rarch_setting_t *setting = (rarch_setting_t*)data; - settings_t *settings = config_get_ptr(); - - if (!setting) - return -1; - - port = setting->index_offset; - - configuration_set_uint(settings, settings->uints.input_analog_dpad_mode[port], - (settings->uints.input_analog_dpad_mode - [port] + ANALOG_DPAD_LAST - 1) % ANALOG_DPAD_LAST); - - return 0; -} - static int setting_action_right_analog_dpad_mode(void *data, bool wraparound) { unsigned port = 0; @@ -1182,73 +1051,6 @@ static int setting_action_right_analog_dpad_mode(void *data, bool wraparound) return 0; } -static int setting_action_left_libretro_device_type( - void *data, bool wraparound) -{ - retro_ctx_controller_info_t pad; - unsigned current_device, current_idx, i, devices[128], - types = 0, port = 0; - const struct retro_controller_info *desc = NULL; - rarch_setting_t *setting = (rarch_setting_t*)data; - rarch_system_info_t *system = NULL; - - if (!setting) - return -1; - - port = setting->index_offset; - - devices[types++] = RETRO_DEVICE_NONE; - devices[types++] = RETRO_DEVICE_JOYPAD; - - system = runloop_get_system_info(); - - if (system) - { - /* Only push RETRO_DEVICE_ANALOG as default if we use an - * older core which doesn't use SET_CONTROLLER_INFO. */ - if (!system->ports.size) - devices[types++] = RETRO_DEVICE_ANALOG; - - if (port < system->ports.size) - desc = &system->ports.data[port]; - } - - if (desc) - { - for (i = 0; i < desc->num_types; i++) - { - unsigned id = desc->types[i].id; - if (types < ARRAY_SIZE(devices) && - id != RETRO_DEVICE_NONE && - id != RETRO_DEVICE_JOYPAD) - devices[types++] = id; - } - } - - current_device = input_config_get_device(port); - current_idx = 0; - for (i = 0; i < types; i++) - { - if (current_device != devices[i]) - continue; - - current_idx = i; - break; - } - - current_device = devices - [(current_idx + types - 1) % types]; - - input_config_set_device(port, current_device); - - pad.port = port; - pad.device = current_device; - - core_set_controller_port_device(&pad); - - return 0; -} - static int setting_action_right_libretro_device_type( void *data, bool wraparound) { @@ -1314,29 +1116,6 @@ static int setting_action_right_libretro_device_type( return 0; } -static int setting_action_left_bind_device(void *data, bool wraparound) -{ - unsigned *p = NULL; - unsigned index_offset = 0; - unsigned max_devices = input_config_get_device_count(); - rarch_setting_t *setting = (rarch_setting_t*)data; - settings_t *settings = config_get_ptr(); - - if (!setting || max_devices == 0) - return -1; - - index_offset = setting->index_offset; - - p = &settings->uints.input_joypad_map[index_offset]; - - if ((*p) >= max_devices) - *p = max_devices - 1; - else if ((*p) > 0) - (*p)--; - - return 0; -} - static int setting_action_right_bind_device(void *data, bool wraparound) { unsigned index_offset; @@ -1358,23 +1137,6 @@ static int setting_action_right_bind_device(void *data, bool wraparound) return 0; } -static int setting_action_left_mouse_index(void *data, bool wraparound) -{ - rarch_setting_t *setting = (rarch_setting_t*)data; - settings_t *settings = config_get_ptr(); - - if (!setting) - return -1; - - if (settings->uints.input_mouse_index[setting->index_offset]) - { - --settings->uints.input_mouse_index[setting->index_offset]; - settings->modified = true; - } - - return 0; -} - static int setting_action_right_mouse_index(void *data, bool wraparound) { rarch_setting_t *setting = (rarch_setting_t*)data; @@ -1393,71 +1155,11 @@ static int setting_action_right_mouse_index(void *data, bool wraparound) ******* ACTION OK CALLBACK FUNCTIONS ******* **/ -static int setting_action_ok_bind_all(void *data, bool wraparound) +static void +setting_get_string_representation_st_float_video_refresh_rate_polled( + void *data, char *s, size_t len) { - (void)wraparound; - if (!menu_input_key_bind_set_mode(MENU_INPUT_BINDS_CTL_BIND_ALL, data)) - return -1; - return 0; -} - -static int setting_action_ok_bind_all_save_autoconfig(void *data, bool wraparound) -{ - unsigned index_offset; - rarch_setting_t *setting = (rarch_setting_t*)data; - const char *name = NULL; - - (void)wraparound; - - if (!setting) - return -1; - - index_offset = setting->index_offset; - name = input_config_get_device_name(index_offset); - - if(!string_is_empty(name) && config_save_autoconf_profile(name, index_offset)) - runloop_msg_queue_push( - msg_hash_to_str(MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY), 1, 100, true); - else - runloop_msg_queue_push( - msg_hash_to_str(MSG_AUTOCONFIG_FILE_ERROR_SAVING), 1, 100, true); - - - return 0; -} - -static int setting_action_ok_bind_defaults(void *data, bool wraparound) -{ - unsigned i; - menu_input_ctx_bind_limits_t lim; - struct retro_keybind *target = NULL; - const struct retro_keybind *def_binds = NULL; - rarch_setting_t *setting = (rarch_setting_t*)data; - - (void)wraparound; - - if (!setting) - return -1; - - target = &input_config_binds[setting->index_offset][0]; - def_binds = (setting->index_offset) ? - retro_keybinds_rest : retro_keybinds_1; - - lim.min = MENU_SETTINGS_BIND_BEGIN; - lim.max = MENU_SETTINGS_BIND_LAST; - - menu_input_key_bind_set_min_max(&lim); - - for (i = MENU_SETTINGS_BIND_BEGIN; - i <= MENU_SETTINGS_BIND_LAST; i++, target++) - { - target->key = def_binds[i - MENU_SETTINGS_BIND_BEGIN].key; - target->joykey = NO_BTN; - target->joyaxis = AXIS_NONE; - target->mbutton = NO_BTN; - } - - return 0; + snprintf(s, len, "%.3f Hz", video_driver_get_refresh_rate()); } static void @@ -1482,31 +1184,6 @@ setting_get_string_representation_st_float_video_refresh_rate_auto( strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE), len); } -static int setting_action_ok_video_refresh_rate_auto(void *data, bool wraparound) -{ - double video_refresh_rate = 0.0; - double deviation = 0.0; - unsigned sample_points = 0; - rarch_setting_t *setting = (rarch_setting_t*)data; - - if (!setting) - return -1; - - if (video_monitor_fps_statistics(&video_refresh_rate, - &deviation, &sample_points)) - { - float video_refresh_rate_float = (float)video_refresh_rate; - driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &video_refresh_rate_float); - /* Incase refresh rate update forced non-block video. */ - command_event(CMD_EVENT_VIDEO_SET_BLOCKING_STATE, NULL); - } - - if (setting_generic_action_ok_default(setting, wraparound) != 0) - return -1; - - return 0; -} - static void get_string_representation_bind_device(void * data, char *s, size_t len) { @@ -1523,7 +1200,7 @@ static void get_string_representation_bind_device(void * data, char *s, if (map < max_devices) { - const char *device_name = input_config_get_device_display_name(map) ? + const char *device_name = input_config_get_device_display_name(map) ? input_config_get_device_display_name(map) : input_config_get_device_name(map); if (!string_is_empty(device_name)) @@ -1736,6 +1413,12 @@ void general_write_handler(void *data) case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_AUTO: driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, setting->value.target.fraction); + /* In case refresh rate update forced non-block video. */ + rarch_cmd = CMD_EVENT_VIDEO_SET_BLOCKING_STATE; + break; + case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED: + driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, setting->value.target.fraction); + /* In case refresh rate update forced non-block video. */ rarch_cmd = CMD_EVENT_VIDEO_SET_BLOCKING_STATE; break; @@ -2425,7 +2108,7 @@ static bool setting_append_list( &subgroup_info, parent_group); -#ifndef __CELLOS_LV2__ +#if !defined(__CELLOS_LV2__) && !defined(HAVE_DYNAMIC) CONFIG_ACTION( list, list_info, MENU_ENUM_LABEL_RESTART_RETROARCH, @@ -2560,6 +2243,14 @@ static bool setting_append_list( &subgroup_info, parent_group); + CONFIG_ACTION( + list, list_info, + MENU_ENUM_LABEL_AUDIO_MIXER_SETTINGS, + MENU_ENUM_LABEL_VALUE_AUDIO_MIXER_SETTINGS, + &group_info, + &subgroup_info, + parent_group); + CONFIG_ACTION( list, list_info, MENU_ENUM_LABEL_INPUT_SETTINGS, @@ -2568,6 +2259,14 @@ static bool setting_append_list( &subgroup_info, parent_group); + CONFIG_ACTION( + list, list_info, + MENU_ENUM_LABEL_LATENCY_SETTINGS, + MENU_ENUM_LABEL_VALUE_LATENCY_SETTINGS, + &group_info, + &subgroup_info, + parent_group); + CONFIG_ACTION( list, list_info, MENU_ENUM_LABEL_CORE_SETTINGS, @@ -2640,6 +2339,7 @@ static bool setting_append_list( parent_group); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); +#ifdef HAVE_OVERLAY CONFIG_ACTION( list, list_info, MENU_ENUM_LABEL_ONSCREEN_OVERLAY_SETTINGS, @@ -2648,6 +2348,7 @@ static bool setting_append_list( &subgroup_info, parent_group); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); +#endif CONFIG_ACTION( list, list_info, @@ -2699,6 +2400,7 @@ static bool setting_append_list( parent_group); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); +#ifdef HAVE_CHEEVOS CONFIG_ACTION( list, list_info, MENU_ENUM_LABEL_RETRO_ACHIEVEMENTS_SETTINGS, @@ -2706,6 +2408,7 @@ static bool setting_append_list( &group_info, &subgroup_info, parent_group); +#endif CONFIG_ACTION( list, list_info, @@ -2716,6 +2419,7 @@ static bool setting_append_list( parent_group); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); +#ifdef HAVE_LAKKA if (string_is_not_equal(settings->arrays.wifi_driver, "null")) { CONFIG_ACTION( @@ -2726,6 +2430,7 @@ static bool setting_append_list( &subgroup_info, parent_group); } +#endif CONFIG_ACTION( list, list_info, @@ -3327,13 +3032,14 @@ static bool setting_append_list( general_write_handler, general_read_handler, SD_FLAG_NONE); - - CONFIG_BOOL( + + + CONFIG_BOOL( list, list_info, - &settings->bools.video_framecount_show, - MENU_ENUM_LABEL_FRAMECOUNT_SHOW, - MENU_ENUM_LABEL_VALUE_FRAMECOUNT_SHOW, - fps_show, + &settings->bools.crt_switch_resolution, + MENU_ENUM_LABEL_CRT_SWITCH_RESOLUTION, + MENU_ENUM_LABEL_VALUE_CRT_SWITCH_RESOLUTION, + crt_switch_resolution, MENU_ENUM_LABEL_VALUE_OFF, MENU_ENUM_LABEL_VALUE_ON, &group_info, @@ -3341,7 +3047,36 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler, - SD_FLAG_NONE); + 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, + general_read_handler); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); + + CONFIG_BOOL( + list, list_info, + &settings->bools.video_framecount_show, + MENU_ENUM_LABEL_FRAMECOUNT_SHOW, + MENU_ENUM_LABEL_VALUE_FRAMECOUNT_SHOW, + fps_show, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); END_SUB_GROUP(list, list_info, parent_group); START_SUB_GROUP(list, list_info, "Platform-specific", &group_info, &subgroup_info, parent_group); @@ -3468,6 +3203,30 @@ static bool setting_append_list( &setting_get_string_representation_st_float_video_refresh_rate_auto; settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + { + float actual_refresh_rate = video_driver_get_refresh_rate(); + if (actual_refresh_rate > 0.0) + { + CONFIG_FLOAT( + list, list_info, + &settings->floats.video_refresh_rate, + MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED, + MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_POLLED, + actual_refresh_rate, + "%.3f Hz", + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].action_ok = &setting_action_ok_video_refresh_rate_polled; + (*list)[list_info->index - 1].action_select = &setting_action_ok_video_refresh_rate_polled; + (*list)[list_info->index - 1].get_string_representation = + &setting_get_string_representation_st_float_video_refresh_rate_polled; + settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + } + } + if (string_is_equal(settings->arrays.video_driver, "gl")) { CONFIG_BOOL( @@ -3836,53 +3595,83 @@ static bool setting_append_list( settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); - CONFIG_UINT( - list, list_info, - &settings->uints.video_max_swapchain_images, - MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, - MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES, - max_swapchain_images, - &group_info, - &subgroup_info, - parent_group, - general_write_handler, - general_read_handler); - menu_settings_list_current_add_range(list, list_info, 1, 4, 1, true, true); - settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO); - settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); - - if (string_is_equal(settings->arrays.video_driver, "gl")) { - CONFIG_BOOL( - list, list_info, - &settings->bools.video_hard_sync, - MENU_ENUM_LABEL_VIDEO_HARD_SYNC, - MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, - hard_sync, - MENU_ENUM_LABEL_VALUE_OFF, - MENU_ENUM_LABEL_VALUE_ON, - &group_info, - &subgroup_info, - parent_group, - general_write_handler, - general_read_handler, - SD_FLAG_NONE - ); - settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + gfx_ctx_flags_t flags; + bool customizable_swapchain_set = false; - CONFIG_UINT( - list, list_info, - &settings->uints.video_hard_sync_frames, - MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES, - MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES, - hard_sync_frames, - &group_info, - &subgroup_info, - parent_group, - general_write_handler, - general_read_handler); - menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true); - settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + if (video_driver_get_flags(&flags)) + if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_CUSTOMIZABLE_SWAPCHAIN_IMAGES)) + customizable_swapchain_set = true; + + flags.flags = 0; + + if (video_context_driver_get_flags(&flags)) + if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_CUSTOMIZABLE_SWAPCHAIN_IMAGES)) + customizable_swapchain_set = true; + + if (customizable_swapchain_set) + { + CONFIG_UINT( + list, list_info, + &settings->uints.video_max_swapchain_images, + MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, + MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES, + max_swapchain_images, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 1, 4, 1, true, true); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO); + } + } + + { + gfx_ctx_flags_t flags; + bool hard_sync_supported = false; + + if (video_driver_get_flags(&flags)) + if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_HARD_SYNC)) + hard_sync_supported = true; + + flags.flags = 0; + + if (video_context_driver_get_flags(&flags)) + if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_HARD_SYNC)) + hard_sync_supported = true; + + if (hard_sync_supported) + { + CONFIG_BOOL( + list, list_info, + &settings->bools.video_hard_sync, + MENU_ENUM_LABEL_VIDEO_HARD_SYNC, + MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, + hard_sync, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE + ); + + CONFIG_UINT( + list, list_info, + &settings->uints.video_hard_sync_frames, + MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES, + MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES, + hard_sync_frames, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true); + } } CONFIG_UINT( @@ -3900,22 +3689,40 @@ static bool setting_append_list( settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); #if !defined(RARCH_MOBILE) - CONFIG_BOOL( - list, list_info, - &settings->bools.video_black_frame_insertion, - MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION, - MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, - black_frame_insertion, - MENU_ENUM_LABEL_VALUE_OFF, - MENU_ENUM_LABEL_VALUE_ON, - &group_info, - &subgroup_info, - parent_group, - general_write_handler, - general_read_handler, - SD_FLAG_NONE - ); - settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + { + gfx_ctx_flags_t flags; + bool black_frame_insertion_supported = false; + + if (video_driver_get_flags(&flags)) + if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_BLACK_FRAME_INSERTION)) + black_frame_insertion_supported = true; + + flags.flags = 0; + + if (video_context_driver_get_flags(&flags)) + if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_BLACK_FRAME_INSERTION)) + black_frame_insertion_supported = true; + + if (black_frame_insertion_supported) + { + CONFIG_BOOL( + list, list_info, + &settings->bools.video_black_frame_insertion, + MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION, + MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, + black_frame_insertion, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE + ); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + } + } #endif END_SUB_GROUP(list, list_info, parent_group); START_SUB_GROUP( @@ -4002,7 +3809,23 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler, - SD_FLAG_ADVANCED + SD_FLAG_NONE + ); + + CONFIG_BOOL( + list, list_info, + &settings->bools.audio_enable_menu, + MENU_ENUM_LABEL_AUDIO_ENABLE_MENU, + MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE_MENU, + false, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE ); CONFIG_BOOL( @@ -4778,7 +4601,10 @@ static bool setting_append_list( { if (!input_config_bind_map_get_meta(i)) continue; - +#ifndef HAVE_QT + if (i == RARCH_UI_COMPANION_TOGGLE) + continue; +#endif CONFIG_BIND_ALT( list, list_info, &input_config_binds[0][i], @@ -4834,6 +4660,53 @@ static bool setting_append_list( general_read_handler); menu_settings_list_current_add_range(list, list_info, 1, 10, 0.1, true, true); + CONFIG_BOOL( + list, list_info, + &settings->bools.run_ahead_enabled, + MENU_ENUM_LABEL_RUN_AHEAD_ENABLED, + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_ENABLED, + false, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE + ); + + CONFIG_UINT( + list, list_info, + &settings->uints.run_ahead_frames, + MENU_ENUM_LABEL_RUN_AHEAD_FRAMES, + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_FRAMES, + 1, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 1, 6, 1, true, true); + +#ifdef HAVE_DYNAMIC + CONFIG_BOOL( + list, list_info, + &settings->bools.run_ahead_secondary_instance, + MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE, + MENU_ENUM_LABEL_VALUE_RUN_AHEAD_SECONDARY_INSTANCE, + false, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE + ); +#endif + CONFIG_BOOL( list, list_info, &settings->bools.menu_throttle_framerate, @@ -5322,44 +5195,112 @@ static bool setting_append_list( SD_FLAG_ADVANCED ); - CONFIG_BOOL( - list, list_info, - &settings->bools.menu_linear_filter, - MENU_ENUM_LABEL_MENU_LINEAR_FILTER, - MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, - true, - MENU_ENUM_LABEL_VALUE_OFF, - MENU_ENUM_LABEL_VALUE_ON, - &group_info, - &subgroup_info, - parent_group, - general_write_handler, - general_read_handler, - SD_FLAG_ADVANCED - ); + if (string_is_equal(settings->arrays.menu_driver, "rgui")) + { + gfx_ctx_flags_t flags; + bool setting_set = false; - CONFIG_BOOL( - list, list_info, - &settings->bools.menu_horizontal_animation, - MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION, - MENU_ENUM_LABEL_VALUE_MENU_HORIZONTAL_ANIMATION, - true, - MENU_ENUM_LABEL_VALUE_OFF, - MENU_ENUM_LABEL_VALUE_ON, - &group_info, - &subgroup_info, - parent_group, - general_write_handler, - general_read_handler, - SD_FLAG_ADVANCED - ); + if (video_driver_get_flags(&flags)) + if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING)) + setting_set = true; + flags.flags = 0; + + if (video_context_driver_get_flags(&flags)) + if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING)) + setting_set = true; + + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_rgui_border_filler_enable, + MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_ENABLE, + MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_ENABLE, + true, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE + ); + + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_rgui_background_filler_thickness_enable, + MENU_ENUM_LABEL_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, + MENU_ENUM_LABEL_VALUE_MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE, + true, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE + ); + + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_rgui_border_filler_thickness_enable, + MENU_ENUM_LABEL_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, + MENU_ENUM_LABEL_VALUE_MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE, + true, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE + ); + + if (setting_set) + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_linear_filter, + MENU_ENUM_LABEL_MENU_LINEAR_FILTER, + MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, + true, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE + ); + } + + if (string_is_equal(settings->arrays.menu_driver, "xmb")) + { + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_horizontal_animation, + MENU_ENUM_LABEL_MENU_HORIZONTAL_ANIMATION, + MENU_ENUM_LABEL_VALUE_MENU_HORIZONTAL_ANIMATION, + true, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_ADVANCED + ); #ifdef RARCH_MOBILE - /* We don't want mobile users being able to switch this off. */ - (*list)[list_info->index - 1].action_left = NULL; - (*list)[list_info->index - 1].action_right = NULL; - (*list)[list_info->index - 1].action_start = NULL; + /* We don't want mobile users being able to switch this off. */ + (*list)[list_info->index - 1].action_left = NULL; + (*list)[list_info->index - 1].action_right = NULL; + (*list)[list_info->index - 1].action_start = NULL; #endif + } + END_SUB_GROUP(list, list_info, parent_group); @@ -5500,7 +5441,7 @@ static bool setting_append_list( if (string_is_equal(settings->arrays.menu_driver, "glui")) { - /* only GLUI uses these values, don't show + /* only GLUI uses these values, don't show * them on other drivers */ CONFIG_BOOL( list, list_info, @@ -5534,7 +5475,7 @@ static bool setting_append_list( #ifdef HAVE_XMB if (string_is_equal(settings->arrays.menu_driver, "xmb")) { - /* only XMB uses these values, don't show + /* only XMB uses these values, don't show * them on other drivers. */ CONFIG_UINT( list, list_info, @@ -5621,6 +5562,20 @@ static bool setting_append_list( menu_settings_list_current_add_range(list, list_info, 0, 255, 1, true, true); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); + CONFIG_UINT( + list, list_info, + &settings->uints.menu_xmb_layout, + MENU_ENUM_LABEL_XMB_LAYOUT, + MENU_ENUM_LABEL_VALUE_XMB_LAYOUT, + xmb_menu_layout, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, 2, 1, true, true); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REINIT); + CONFIG_UINT( list, list_info, &settings->uints.menu_xmb_theme, @@ -5678,7 +5633,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); menu_settings_list_current_add_range(list, list_info, 0, XMB_THEME_LAST-1, 1, true, true); - } + } #endif CONFIG_BOOL( list, list_info, @@ -5740,6 +5695,51 @@ static bool setting_append_list( general_read_handler, SD_FLAG_LAKKA_ADVANCED); + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_show_overlays, + MENU_ENUM_LABEL_CONTENT_SHOW_OVERLAYS, + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_OVERLAYS, + true, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_LAKKA_ADVANCED); + + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_show_latency, + MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY, + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_LATENCY, + true, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_LAKKA_ADVANCED); + + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_show_rewind, + MENU_ENUM_LABEL_CONTENT_SHOW_REWIND, + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_REWIND, + true, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_LAKKA_ADVANCED); + CONFIG_BOOL( list, list_info, &settings->bools.menu_show_help, @@ -5755,6 +5755,8 @@ static bool setting_append_list( general_read_handler, SD_FLAG_LAKKA_ADVANCED); + +#ifdef HAVE_LAKKA CONFIG_BOOL( list, list_info, &settings->bools.menu_show_quit_retroarch, @@ -5769,8 +5771,7 @@ static bool setting_append_list( general_write_handler, general_read_handler, SD_FLAG_NONE); - -#ifdef HAVE_LAKKA + CONFIG_BOOL( list, list_info, &settings->bools.menu_show_reboot, @@ -5786,7 +5787,7 @@ static bool setting_append_list( general_read_handler, SD_FLAG_NONE); #endif - + #ifdef HAVE_XMB if (string_is_equal(settings->arrays.menu_driver, "xmb")) { @@ -5805,23 +5806,23 @@ static bool setting_append_list( general_read_handler, SD_FLAG_NONE); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); - - CONFIG_STRING( - list, list_info, - settings->paths.menu_content_show_settings_password, - sizeof(settings->paths.menu_content_show_settings_password), - MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS_PASSWORD, - MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS_PASSWORD, - "", - &group_info, - &subgroup_info, - parent_group, - general_write_handler, - general_read_handler); - settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT | SD_FLAG_LAKKA_ADVANCED); - } + + CONFIG_STRING( + list, list_info, + settings->paths.menu_content_show_settings_password, + sizeof(settings->paths.menu_content_show_settings_password), + MENU_ENUM_LABEL_CONTENT_SHOW_SETTINGS_PASSWORD, + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_SETTINGS_PASSWORD, + "", + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT | SD_FLAG_LAKKA_ADVANCED); + } #endif - + CONFIG_BOOL( list, list_info, &settings->bools.menu_content_show_favorites, @@ -5936,10 +5937,25 @@ static bool setting_append_list( settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); #endif + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_content_show_playlists, + MENU_ENUM_LABEL_CONTENT_SHOW_PLAYLISTS, + MENU_ENUM_LABEL_VALUE_CONTENT_SHOW_PLAYLISTS, + content_show_playlists, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); + #ifdef HAVE_MATERIALUI if (string_is_equal(settings->arrays.menu_driver, "glui")) { - /* only MaterialUI uses these values, don't show + /* only MaterialUI uses these values, don't show * them on other drivers. */ CONFIG_BOOL( list, list_info, @@ -6028,6 +6044,34 @@ static bool setting_append_list( general_write_handler, general_read_handler); menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true); + + CONFIG_UINT( + list, list_info, + &settings->uints.menu_left_thumbnails, + MENU_ENUM_LABEL_LEFT_THUMBNAILS, + MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS, + menu_left_thumbnails_default, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true); + + CONFIG_BOOL( + list, list_info, + &settings->bools.menu_xmb_vertical_thumbnails, + MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, + MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS, + xmb_vertical_thumbnails, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); } CONFIG_BOOL( @@ -6226,6 +6270,7 @@ static bool setting_append_list( settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); #endif +#ifdef HAVE_NETWORKING CONFIG_BOOL( list, list_info, &settings->bools.menu_show_online_updater, @@ -6241,6 +6286,7 @@ static bool setting_append_list( general_read_handler, SD_FLAG_NONE); +#if !defined(HAVE_LAKKA) CONFIG_BOOL( list, list_info, &settings->bools.menu_show_core_updater, @@ -6255,6 +6301,8 @@ static bool setting_append_list( general_write_handler, general_read_handler, SD_FLAG_NONE); +#endif +#endif CONFIG_BOOL( list, list_info, @@ -6471,8 +6519,37 @@ static bool setting_append_list( general_read_handler, SD_FLAG_NONE); } +#ifdef HAVE_QT + CONFIG_BOOL( + list, list_info, + &settings->bools.desktop_menu_enable, + MENU_ENUM_LABEL_DESKTOP_MENU_ENABLE, + MENU_ENUM_LABEL_VALUE_DESKTOP_MENU_ENABLE, + desktop_menu_enable, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); - + CONFIG_BOOL( + list, list_info, + &settings->bools.ui_companion_toggle, + MENU_ENUM_LABEL_UI_COMPANION_TOGGLE, + MENU_ENUM_LABEL_VALUE_UI_COMPANION_TOGGLE, + ui_companion_toggle, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); +#endif END_SUB_GROUP(list, list_info, parent_group); END_GROUP(list, list_info, parent_group); break; @@ -6517,7 +6594,7 @@ static bool setting_append_list( END_SUB_GROUP(list, list_info, parent_group); - START_SUB_GROUP(list, list_info, "Playlist", &group_info, &subgroup_info, parent_group); + START_SUB_GROUP(list, list_info, "Playlist", &group_info, &subgroup_info, parent_group); CONFIG_BOOL( list, list_info, @@ -6534,7 +6611,7 @@ static bool setting_append_list( general_read_handler, SD_FLAG_NONE); - CONFIG_BOOL( + CONFIG_BOOL( list, list_info, &settings->bools.playlist_entry_remove, MENU_ENUM_LABEL_PLAYLIST_ENTRY_REMOVE, diff --git a/menu/widgets/menu_filebrowser.c b/menu/widgets/menu_filebrowser.c index ac1edb47f2..86c943adcb 100644 --- a/menu/widgets/menu_filebrowser.c +++ b/menu/widgets/menu_filebrowser.c @@ -66,7 +66,6 @@ void filebrowser_parse(void *data, unsigned type_data) unsigned dirs_count = 0; settings_t *settings = config_get_ptr(); rarch_system_info_t *system = runloop_get_system_info(); - const struct retro_subsystem_info* subsystem = NULL; menu_displaylist_info_t *info = (menu_displaylist_info_t*)data; enum menu_displaylist_ctl_state type = (enum menu_displaylist_ctl_state) type_data; @@ -86,29 +85,31 @@ void filebrowser_parse(void *data, unsigned type_data) str_list = file_archive_get_file_list(path, info->exts); else { - subsystem = system->subsystem.data + content_get_subsystem(); - str_list = file_archive_get_file_list(path, subsystem->roms[content_get_subsystem_rom_id()].valid_extensions); + const struct retro_subsystem_info *subsystem = system->subsystem.data + content_get_subsystem(); + + if (subsystem) + str_list = file_archive_get_file_list(path, subsystem->roms[content_get_subsystem_rom_id()].valid_extensions); } } - else if (!string_is_empty(path) && filebrowser_types != FILEBROWSER_SELECT_FILE_SUBSYSTEM) + else if (!string_is_empty(path)) { - str_list = dir_list_new(path, - (filter_ext && info) ? info->exts : NULL, - true, settings->bools.show_hidden_files, true, false); - } - else if (!string_is_empty(path) && filebrowser_types == FILEBROWSER_SELECT_FILE_SUBSYSTEM) - { - subsystem = system->subsystem.data + content_get_subsystem(); - - if (subsystem && content_get_subsystem_rom_id() < subsystem->num_roms) + if (filebrowser_types == FILEBROWSER_SELECT_FILE_SUBSYSTEM) { - str_list = dir_list_new(path, - (filter_ext && info) ? subsystem->roms[content_get_subsystem_rom_id()].valid_extensions : NULL, - true, settings->bools.show_hidden_files, true, false); - } + const struct retro_subsystem_info *subsystem = + system->subsystem.data + content_get_subsystem(); + if (subsystem && content_get_subsystem_rom_id() < subsystem->num_roms) + str_list = dir_list_new(path, + (filter_ext && info) ? subsystem->roms[content_get_subsystem_rom_id()].valid_extensions : NULL, + true, settings->bools.show_hidden_files, true, false); + } + else + str_list = dir_list_new(path, + (filter_ext && info) ? info->exts : NULL, + true, settings->bools.show_hidden_files, true, false); } + switch (filebrowser_types) { case FILEBROWSER_SCAN_DIR: diff --git a/menu/widgets/menu_osk.c b/menu/widgets/menu_osk.c index 1e2342bb6f..65e17b04cc 100644 --- a/menu/widgets/menu_osk.c +++ b/menu/widgets/menu_osk.c @@ -32,7 +32,7 @@ #include "../../input/input_driver.h" -static const char *osk_grid[45] = {NULL}; +static char *osk_grid[45] = {NULL}; static int osk_ptr = 0; static enum osk_type osk_idx = OSK_LOWERCASE_LATIN; @@ -148,7 +148,7 @@ void menu_event_osk_iterate(void) } } -const char** menu_event_get_osk_grid(void) +char** menu_event_get_osk_grid(void) { return osk_grid; } diff --git a/menu/widgets/menu_osk.h b/menu/widgets/menu_osk.h index be11d86e7f..2c460a7efb 100644 --- a/menu/widgets/menu_osk.h +++ b/menu/widgets/menu_osk.h @@ -59,7 +59,7 @@ void menu_event_osk_append(int a); void menu_event_osk_iterate(void); -const char** menu_event_get_osk_grid(void); +char** menu_event_get_osk_grid(void); RETRO_END_DECLS diff --git a/movie.c b/movie.c index f84635d176..0dc0da9860 100644 --- a/movie.c +++ b/movie.c @@ -290,7 +290,7 @@ static void bsv_movie_frame_rewind(bsv_movie_t *handle) { /* If we're at the beginning... */ handle->frame_ptr = 0; - intfstream_seek(handle->file, handle->min_file_pos, SEEK_SET); + intfstream_seek(handle->file, (int)handle->min_file_pos, SEEK_SET); } else { @@ -303,7 +303,7 @@ static void bsv_movie_frame_rewind(bsv_movie_t *handle) handle->frame_ptr = (handle->frame_ptr - (handle->first_rewind ? 1 : 2)) & handle->frame_mask; intfstream_seek(handle->file, - handle->frame_pos[handle->frame_ptr], SEEK_SET); + (int)handle->frame_pos[handle->frame_ptr], SEEK_SET); } if (intfstream_tell(handle->file) <= (long)handle->min_file_pos) @@ -327,7 +327,7 @@ static void bsv_movie_frame_rewind(bsv_movie_t *handle) intfstream_write(handle->file, handle->state, handle->state_size); } else - intfstream_seek(handle->file, handle->min_file_pos, SEEK_SET); + intfstream_seek(handle->file, (int)handle->min_file_pos, SEEK_SET); } } diff --git a/msg_hash.c b/msg_hash.c index 37a871b222..afdc0c4d0f 100644 --- a/msg_hash.c +++ b/msg_hash.c @@ -31,6 +31,7 @@ static unsigned uint_user_language; int menu_hash_get_help_enum(enum msg_hash_enums msg, char *s, size_t len) { +#ifdef HAVE_MENU int ret = -1; #ifdef HAVE_LANGEXTRA @@ -90,6 +91,9 @@ int menu_hash_get_help_enum(enum msg_hash_enums msg, char *s, size_t len) return ret; return menu_hash_get_help_us_enum(msg, s, len); +#else + return 0; +#endif } const char *msg_hash_to_str(enum msg_hash_enums msg) diff --git a/msg_hash.h b/msg_hash.h index 181814deb1..833b518760 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -136,6 +136,7 @@ enum msg_file_type FILE_TYPE_ISO, FILE_TYPE_LUTRO, FILE_TYPE_CHD, + FILE_TYPE_WBFS, FILE_TYPE_DIRECT_LOAD, @@ -184,7 +185,7 @@ enum msg_hash_enums MSG_NETPLAY_CHANGED_NICK, MSG_ADDED_TO_FAVORITES, MSG_RESET_CORE_ASSOCIATION, - MSG_CORE_ASSOCIATION_RESET, + MSG_CORE_ASSOCIATION_RESET, MSG_AUTODETECT, MSG_AUDIO_VOLUME, MSG_AUDIO_MIXER_VOLUME, @@ -411,13 +412,22 @@ enum msg_hash_enums MSG_CORE_REMAP_FILE_LOADED, MENU_LABEL(ADD_TO_MIXER), + MENU_LABEL(ADD_TO_MIXER_AND_PLAY), MENU_LABEL(ADD_TO_MIXER_AND_COLLECTION), + MENU_LABEL(ADD_TO_MIXER_AND_COLLECTION_AND_PLAY), MENU_ENUM_LABEL_MENU_TOGGLE, MENU_LABEL(FILTER_BY_CURRENT_CORE), MENU_LABEL(NO_HISTORY_AVAILABLE), + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY, + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_LOOPED, + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_PLAY_SEQUENTIAL, + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_STOP, + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_REMOVE, + MENU_ENUM_LABEL_VALUE_MIXER_ACTION_VOLUME, + MENU_ENUM_LABEL_VALUE_REMAP_FILE, MENU_ENUM_LABEL_VALUE_CHEAT_FILE, MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN, @@ -629,6 +639,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, + MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX, @@ -665,6 +676,8 @@ enum msg_hash_enums MENU_LABEL(INPUT_UNIFIED_MENU_CONTROLS), /* Video */ + MENU_LABEL(CRT_SWITCH_RESOLUTION), + MENU_LABEL(CRT_SWITCH_RESOLUTION_SUPER), MENU_LABEL(VIDEO_FONT_ENABLE), MENU_LABEL(VIDEO_FONT_PATH), MENU_LABEL(VIDEO_FONT_SIZE), @@ -717,6 +730,7 @@ enum msg_hash_enums MENU_LABEL(VIDEO_WINDOW_SCALE), MENU_LABEL(VIDEO_REFRESH_RATE), MENU_LABEL(VIDEO_REFRESH_RATE_AUTO), + MENU_LABEL(VIDEO_REFRESH_RATE_POLLED), MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE, @@ -745,6 +759,9 @@ enum msg_hash_enums MENU_LABEL(PAUSE_NONACTIVE), MENU_LABEL(MOUSE_ENABLE), MENU_LABEL(POINTER_ENABLE), + MENU_LABEL(MENU_RGUI_BORDER_FILLER_ENABLE), + MENU_LABEL(MENU_RGUI_BACKGROUND_FILLER_THICKNESS_ENABLE), + MENU_LABEL(MENU_RGUI_BORDER_FILLER_THICKNESS_ENABLE), MENU_LABEL(MENU_LINEAR_FILTER), MENU_LABEL(MENU_HORIZONTAL_ANIMATION), MENU_LABEL(NAVIGATION_WRAPAROUND), @@ -758,10 +775,14 @@ enum msg_hash_enums MENU_LABEL(MENU_FONT_COLOR_GREEN), MENU_LABEL(MENU_FONT_COLOR_BLUE), MENU_LABEL(XMB_FONT), + MENU_LABEL(XMB_LAYOUT), MENU_LABEL(XMB_THEME), MENU_LABEL(XMB_MAIN_MENU_ENABLE_SETTINGS), MENU_LABEL(XMB_MENU_COLOR_THEME), MENU_LABEL(XMB_SHADOWS_ENABLE), + MENU_LABEL(CONTENT_SHOW_REWIND), + MENU_LABEL(CONTENT_SHOW_LATENCY), + MENU_LABEL(CONTENT_SHOW_OVERLAYS), MENU_LABEL(CONTENT_SHOW_SETTINGS), MENU_LABEL(CONTENT_SHOW_SETTINGS_PASSWORD), MENU_LABEL(CONTENT_SHOW_FAVORITES), @@ -771,11 +792,15 @@ enum msg_hash_enums MENU_LABEL(CONTENT_SHOW_NETPLAY), MENU_LABEL(CONTENT_SHOW_HISTORY), MENU_LABEL(CONTENT_SHOW_ADD), + MENU_LABEL(CONTENT_SHOW_PLAYLISTS), MENU_LABEL(XMB_RIBBON_ENABLE), MENU_LABEL(THUMBNAILS), + MENU_LABEL(LEFT_THUMBNAILS), + MENU_LABEL(XMB_VERTICAL_THUMBNAILS), MENU_LABEL(TIMEDATE_ENABLE), MENU_LABEL(BATTERY_LEVEL_ENABLE), MENU_LABEL(MATERIALUI_MENU_COLOR_THEME), + MENU_LABEL(QUICK_MENU_OVERRIDE_OPTIONS), MENU_LABEL(QUICK_MENU_SHOW_TAKE_SCREENSHOT), MENU_LABEL(QUICK_MENU_SHOW_SAVE_LOAD_STATE), MENU_LABEL(QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE), @@ -792,6 +817,8 @@ enum msg_hash_enums MENU_LABEL(VIDEO_DISABLE_COMPOSITION), MENU_LABEL(UI_COMPANION_ENABLE), MENU_LABEL(UI_COMPANION_START_ON_BOOT), + MENU_LABEL(UI_COMPANION_TOGGLE), + MENU_LABEL(DESKTOP_MENU_ENABLE), MENU_LABEL(UI_MENUBAR_ENABLE), MENU_ENUM_LABEL_FILE_CONFIG, @@ -924,6 +951,7 @@ enum msg_hash_enums MENU_LABEL(BROWSE_URL), MENU_LABEL(BROWSE_START), /* Deferred */ + MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_CONFIGURATIONS_LIST, MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST, MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST, @@ -971,6 +999,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_DEFERRED_RECORDING_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_PLAYLIST_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_INPUT_SETTINGS_LIST, + MENU_ENUM_LABEL_DEFERRED_LATENCY_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_DRIVER_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_VIDEO_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_CONFIGURATION_SETTINGS_LIST, @@ -982,6 +1011,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_DEFERRED_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_MENU_VIEWS_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_QUICK_MENU_VIEWS_SETTINGS_LIST, + MENU_ENUM_LABEL_DEFERRED_QUICK_MENU_OVERRIDE_OPTIONS, MENU_ENUM_LABEL_DEFERRED_MENU_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_USER_INTERFACE_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_MENU_FILE_BROWSER_SETTINGS_LIST, @@ -996,6 +1026,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_DEFERRED_PRIVACY_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_LOGGING_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_AUDIO_SETTINGS_LIST, + MENU_ENUM_LABEL_DEFERRED_AUDIO_MIXER_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_CORE_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_USER_BINDS_LIST, MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_CHEEVOS_LIST, @@ -1097,6 +1128,7 @@ enum msg_hash_enums /* Audio */ MENU_LABEL(AUDIO_ENABLE), + MENU_LABEL(AUDIO_ENABLE_MENU), MENU_LABEL(AUDIO_MAX_TIMING_SKEW), MENU_LABEL(AUDIO_OUTPUT_RATE), MENU_LABEL(AUDIO_DEVICE), @@ -1262,6 +1294,9 @@ enum msg_hash_enums MENU_LABEL(THUMBNAILS_DIRECTORY), MENU_LABEL(SLOWMOTION_RATIO), + MENU_LABEL(RUN_AHEAD_ENABLED), + MENU_LABEL(RUN_AHEAD_SECONDARY_INSTANCE), + MENU_LABEL(RUN_AHEAD_FRAMES), MENU_LABEL(TURBO), /* Privacy settings */ @@ -1469,6 +1504,8 @@ enum msg_hash_enums MENU_LABEL(DRIVER_SETTINGS), MENU_LABEL(VIDEO_SETTINGS), MENU_LABEL(AUDIO_SETTINGS), + MENU_LABEL(AUDIO_MIXER_SETTINGS), + MENU_LABEL(LATENCY_SETTINGS), MENU_LABEL(CORE_SETTINGS), MENU_LABEL(CONFIGURATION_SETTINGS), MENU_LABEL(LOGGING_SETTINGS), @@ -1715,6 +1752,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_CB_LAKKA_DOWNLOAD, MENU_ENUM_LABEL_CB_LAKKA_LIST, MENU_ENUM_LABEL_CB_MENU_THUMBNAIL, + MENU_ENUM_LABEL_CB_MENU_LEFT_THUMBNAIL, MENU_ENUM_LABEL_CB_MENU_SAVESTATE_THUMBNAIL, MENU_ENUM_LABEL_CB_MENU_WALLPAPER, MENU_ENUM_LABEL_CB_THUMBNAILS_UPDATER_DOWNLOAD, @@ -1730,6 +1768,12 @@ enum msg_hash_enums MENU_ENUM_LABEL_CB_UPDATE_SHADERS_SLANG, /* Sublabels */ + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY, + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_LOOPED, + MENU_ENUM_SUBLABEL_MIXER_ACTION_PLAY_SEQUENTIAL, + MENU_ENUM_SUBLABEL_MIXER_ACTION_STOP, + MENU_ENUM_SUBLABEL_MIXER_ACTION_REMOVE, + MENU_ENUM_SUBLABEL_MIXER_ACTION_VOLUME, MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, @@ -1746,6 +1790,63 @@ enum msg_hash_enums MENU_LABEL(NETPLAY_MITM_SERVER), MENU_LABEL(VIDEO_WINDOW_SHOW_DECORATIONS), + MENU_ENUM_LABEL_VALUE_QT_INFO, + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE, + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_LOAD_CORE, + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_UNLOAD_CORE, + MENU_ENUM_LABEL_VALUE_QT_MENU_FILE_EXIT, + MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT, + MENU_ENUM_LABEL_VALUE_QT_MENU_EDIT_SEARCH, + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW, + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_CLOSED_DOCKS, + 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, + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB, + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME, + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_SYSTEM_DEFAULT, + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK, + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM, + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE, + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_HIGHLIGHT_COLOR, + MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SUGGEST_LOADED_CORE_FIRST, + MENU_ENUM_LABEL_VALUE_QT_MENU_DOCK_CONTENT_BROWSER, + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_BOXART, + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_SCREENSHOT, + MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_TITLE_SCREEN, + MENU_ENUM_LABEL_VALUE_QT_LOAD_CORE, + MENU_ENUM_LABEL_VALUE_QT_LOAD_CUSTOM_CORE, + MENU_ENUM_LABEL_VALUE_QT_LOADING_CORE, + MENU_ENUM_LABEL_VALUE_QT_NAME, + MENU_ENUM_LABEL_VALUE_QT_CORE_VERSION, + MENU_ENUM_LABEL_VALUE_QT_TAB_PLAYLISTS, + MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER, + MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_TOP, + MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER_UP, + MENU_ENUM_LABEL_VALUE_QT_ALL_PLAYLISTS, + MENU_ENUM_LABEL_VALUE_QT_CORE, + MENU_ENUM_LABEL_VALUE_QT_CORE_INFO, + MENU_ENUM_LABEL_VALUE_QT_CORE_SELECTION_ASK, + MENU_ENUM_LABEL_VALUE_QT_INFORMATION, + MENU_ENUM_LABEL_VALUE_QT_WARNING, + MENU_ENUM_LABEL_VALUE_QT_ERROR, + MENU_ENUM_LABEL_VALUE_QT_RESTART_TO_TAKE_EFFECT, + MENU_ENUM_LABEL_VALUE_QT_LOG, + MENU_ENUM_LABEL_VALUE_QT_SCAN_FINISHED, + MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN, + MENU_ENUM_LABEL_VALUE_QT_STOP, + MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE, + MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS, + MENU_ENUM_LABEL_VALUE_QT_HIDE, + MENU_ENUM_LABEL_VALUE_QT_CHOOSE, + MENU_ENUM_LABEL_VALUE_QT_SELECT_COLOR, + MENU_ENUM_LABEL_VALUE_QT_SELECT_THEME, + MENU_ENUM_LABEL_VALUE_QT_CUSTOM_THEME, + MENU_ENUM_LABEL_VALUE_QT_FILE_PATH_IS_BLANK, + MENU_ENUM_LABEL_VALUE_QT_FILE_IS_EMPTY, + MENU_ENUM_LABEL_VALUE_QT_FILE_READ_OPEN_FAILED, + MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST, + MSG_LAST }; diff --git a/network/netplay/netplay_delta.c b/network/netplay/netplay_delta.c index d6b7efe58b..2b770075ee 100644 --- a/network/netplay/netplay_delta.c +++ b/network/netplay/netplay_delta.c @@ -155,10 +155,10 @@ netplay_input_state_t netplay_input_state_for(netplay_input_state_t *list, ret = (netplay_input_state_t)calloc(1, sizeof(struct netplay_input_state) + (size-1) * sizeof(uint32_t)); if (!ret) return NULL; - *list = ret; + *list = ret; ret->client_num = client_num; - ret->used = true; - ret->size = size; + ret->used = true; + ret->size = (uint32_t)size; return ret; } diff --git a/network/netplay/netplay_discovery.c b/network/netplay/netplay_discovery.c index 33118802b1..372a818b3d 100644 --- a/network/netplay/netplay_discovery.c +++ b/network/netplay/netplay_discovery.c @@ -168,7 +168,7 @@ bool netplay_discovery_driver_ctl(enum rarch_netplay_discovery_ctl_state state, NETPLAY_HOST_STR_LEN); /* And send it off */ - ret = sendto(lan_ad_client_fd, (const char *) &ad_packet_buffer, + ret = (int)sendto(lan_ad_client_fd, (const char *) &ad_packet_buffer, sizeof(struct ad_packet), 0, addr->ai_addr, addr->ai_addrlen); if (ret < (ssize_t) (2*sizeof(uint32_t))) RARCH_WARN("[discovery] Failed to send netplay discovery query (error: %d)\n", errno); @@ -262,8 +262,7 @@ bool netplay_lan_ad_server(netplay_t *netplay) /* Somebody queried, so check that it's valid */ addr_size = sizeof(their_addr); - - ret = recvfrom(lan_ad_server_fd, (char*)&ad_packet_buffer, + ret = (int)recvfrom(lan_ad_server_fd, (char*)&ad_packet_buffer, sizeof(struct ad_packet), 0, &their_addr, &addr_size); if (ret >= (ssize_t) (2 * sizeof(uint32_t))) { diff --git a/network/netplay/netplay_handshake.c b/network/netplay/netplay_handshake.c index a005a963fc..021b51d35c 100644 --- a/network/netplay/netplay_handshake.c +++ b/network/netplay/netplay_handshake.c @@ -564,8 +564,8 @@ bool netplay_handshake_sync(netplay_t *netplay, autosave_unlock(); /* Send basic sync info */ - cmd[0] = htonl(NETPLAY_CMD_SYNC); - cmd[1] = htonl(2*sizeof(uint32_t) + cmd[0] = htonl(NETPLAY_CMD_SYNC); + cmd[1] = htonl(2*sizeof(uint32_t) /* Controller devices */ + MAX_INPUT_DEVICES*sizeof(uint32_t) @@ -580,11 +580,13 @@ bool netplay_handshake_sync(netplay_t *netplay, /* And finally, sram */ + mem_info.size); - cmd[2] = htonl(netplay->self_frame_count); - client_num = connection - netplay->connections + 1; + cmd[2] = htonl(netplay->self_frame_count); + client_num = (uint32_t)(connection - netplay->connections + 1); + if (netplay->local_paused || netplay->remote_paused) client_num |= NETPLAY_CMD_SYNC_BIT_PAUSED; - cmd[3] = htonl(client_num); + + cmd[3] = htonl(client_num); if (!netplay_send(&connection->send_packet_buffer, connection->fd, cmd, sizeof(cmd))) diff --git a/network/netplay/netplay_io.c b/network/netplay/netplay_io.c index d87cc1459a..4028515719 100644 --- a/network/netplay/netplay_io.c +++ b/network/netplay/netplay_io.c @@ -142,7 +142,7 @@ void netplay_hangup(netplay_t *netplay, struct netplay_connection *connection) } else { - uint32_t client_num = connection - netplay->connections + 1; + uint32_t client_num = (uint32_t)(connection - netplay->connections + 1); /* Mark the player for removal */ if (connection->mode == NETPLAY_CONNECTION_PLAYING || @@ -177,22 +177,23 @@ void netplay_hangup(netplay_t *netplay, struct netplay_connection *connection) */ void netplay_delayed_state_change(netplay_t *netplay) { - struct netplay_connection *connection; - size_t i; + unsigned i; for (i = 0; i < netplay->connections_size; i++) { - uint32_t client_num = i+1; - connection = &netplay->connections[i]; + uint32_t client_num = (uint32_t)(i + 1); + struct netplay_connection *connection = &netplay->connections[i]; + if ((connection->active || connection->mode == NETPLAY_CONNECTION_DELAYED_DISCONNECT) && connection->delay_frame && connection->delay_frame <= netplay->self_frame_count) { /* Something was delayed! Prepare the MODE command */ uint32_t payload[15] = {0}; - payload[0] = htonl(connection->delay_frame); - payload[1] = htonl(client_num); - payload[2] = htonl(0); + payload[0] = htonl(connection->delay_frame); + payload[1] = htonl(client_num); + payload[2] = htonl(0); + memcpy(payload + 3, netplay->device_share_modes, sizeof(netplay->device_share_modes)); strncpy((char *) (payload + 7), connection->nick, NETPLAY_NICK_LEN); @@ -294,7 +295,7 @@ bool netplay_send_cur_input(netplay_t *netplay, if (netplay->is_server) { - to_client = connection - netplay->connections + 1; + to_client = (uint32_t)(connection - netplay->connections + 1); /* Send the other players' input data (FIXME: This involves an * unacceptable amount of recalculating) */ @@ -302,6 +303,7 @@ bool netplay_send_cur_input(netplay_t *netplay, { if (from_client == to_client) continue; + if ((netplay->connected_players & (1<have_real[from_client]) @@ -957,7 +959,7 @@ static bool netplay_get_cmd(netplay_t *netplay, RARCH_ERR("Netplay input from non-participating player.\n"); return netplay_cmd_nak(netplay, connection); } - client_num = connection - netplay->connections + 1; + client_num = (uint32_t)(connection - netplay->connections + 1); } if (client_num > MAX_CLIENTS) @@ -1129,7 +1131,7 @@ static bool netplay_get_cmd(netplay_t *netplay, return netplay_cmd_nak(netplay, connection); } - client_num = connection - netplay->connections + 1; + client_num = (uint32_t)(connection - netplay->connections + 1); handle_play_spectate(netplay, client_num, connection, cmd, 0, NULL); break; @@ -1180,7 +1182,7 @@ static bool netplay_get_cmd(netplay_t *netplay, return netplay_cmd_nak(netplay, connection); } - client_num = connection - netplay->connections + 1; + client_num = (unsigned)(connection - netplay->connections + 1); handle_play_spectate(netplay, client_num, connection, cmd, cmd_size, payload); break; @@ -1552,12 +1554,12 @@ static bool netplay_get_cmd(netplay_t *netplay, uint32_t frame; uint32_t isize; uint32_t rd, wn; - uint32_t client, client_num; + uint32_t client; uint32_t load_frame_count; size_t load_ptr; - struct compression_transcoder *ctrans; - - client_num = connection - netplay->connections + 1; + struct compression_transcoder *ctrans = NULL; + uint32_t client_num = (uint32_t) + (connection - netplay->connections + 1); /* Make sure we're ready for it */ if (netplay->quirks & NETPLAY_QUIRK_INITIALIZATION) @@ -1926,8 +1928,8 @@ void netplay_handle_slaves(netplay_t *netplay) if (connection->active && connection->mode == NETPLAY_CONNECTION_SLAVE) { - uint32_t client_num = i + 1; uint32_t devices, device; + uint32_t client_num = (uint32_t)(i + 1); /* This is a slave connection. First, should we do anything at all? If * we've already "read" this data, then we can just ignore it */ diff --git a/network/netplay/netplay_sync.c b/network/netplay/netplay_sync.c index 69386916c5..0035ac7baf 100644 --- a/network/netplay/netplay_sync.c +++ b/network/netplay/netplay_sync.c @@ -126,35 +126,51 @@ static void netplay_merge_digital(netplay_t *netplay, { netplay_input_state_t simstate; uint32_t word, bit, client; - uint8_t share_mode = netplay->device_share_modes[device] & NETPLAY_SHARE_DIGITAL_BITS; + uint8_t share_mode = netplay->device_share_modes[device] + & NETPLAY_SHARE_DIGITAL_BITS; /* Make sure all real clients are accounted for */ - for (simstate = simframe->real_input[device]; simstate; simstate = simstate->next) + for (simstate = simframe->real_input[device]; + simstate; simstate = simstate->next) { - if (!simstate->used || simstate->size != resstate->size) continue; + if (!simstate->used || simstate->size != resstate->size) + continue; clients |= 1<client_num; } if (share_mode == NETPLAY_SHARE_DIGITAL_VOTE) { + unsigned i, j; + /* This just assumes we have no more than + * three words, will need to be adjusted for new devices */ + struct vote_count votes[3]; /* Vote mode requires counting all the bits */ - uint32_t client_count = 0; + uint32_t client_count = 0; + + for (i = 0; i < 3; i++) + for (j = 0; j < 32; j++) + votes[i].votes[j] = 0; - /* This just assumes we have no more than three words, will need to be adjusted for new devices */ - struct vote_count votes[3] = {0}; for (client = 0; client < MAX_CLIENTS; client++) { - if (!(clients & (1<size; word++) { - if (!digital[word]) continue; + if (!digital[word]) + continue; for (bit = 0; bit < 32; bit++) { - if (!(digital[word] & (1<data[word] & (1<data[word] |= (1<size; word++) { uint32_t part; - if (!digital[word]) continue; + if (!digital[word]) + continue; part = simstate->data[word]; + if (digital[word] == (uint32_t) -1) { /* Combine the whole word */ switch (share_mode) { - case NETPLAY_SHARE_DIGITAL_XOR: resstate->data[word] ^= part; break; - default: resstate->data[word] |= part; + case NETPLAY_SHARE_DIGITAL_XOR: + resstate->data[word] ^= part; + break; + default: + resstate->data[word] |= part; } } @@ -199,11 +223,15 @@ static void netplay_merge_digital(netplay_t *netplay, { for (bit = 0; bit < 32; bit++) { - if (!(digital[word] & (1<data[word] ^= part & (1<data[word] |= part & (1<data[word] ^= part & (1<data[word] |= part & (1<device_share_modes[device] & NETPLAY_SHARE_ANALOG_BITS; + uint8_t share_mode = netplay->device_share_modes[device] + & NETPLAY_SHARE_ANALOG_BITS; int32_t value = 0, new_value; /* Make sure all real clients are accounted for */ for (simstate = simframe->real_input[device]; simstate; simstate = simstate->next) { - if (!simstate->used || simstate->size != resstate->size) continue; + if (!simstate->used || simstate->size != resstate->size) + continue; clients |= 1<client_num; } for (client = 0; client < MAX_CLIENTS; client++) { - if (!(clients & (1<data[word]>>bit) & 0xFFFF); switch (share_mode) @@ -259,7 +292,8 @@ static void merge_analog_part(netplay_t *netplay, } if (share_mode == NETPLAY_SHARE_ANALOG_AVERAGE) - value /= client_count; + if (client_count > 0) /* Prevent potential divide by zero */ + value /= client_count; resstate->data[word] |= ((uint32_t) (uint16_t) value) << bit; } @@ -307,37 +341,41 @@ static void netplay_merge_analog(netplay_t *netplay, bool netplay_resolve_input(netplay_t *netplay, size_t sim_ptr, bool resim) { size_t prev; - struct delta_frame *simframe, *pframe; - netplay_input_state_t simstate, client_state = NULL, resstate, oldresstate, pstate; - uint32_t clients, client, client_count; uint32_t device; - bool ret = false; - - simframe = &netplay->buffer[sim_ptr]; + uint32_t clients, client, client_count; + netplay_input_state_t simstate, client_state = NULL, + resstate, oldresstate, pstate; + bool ret = false; + struct delta_frame *pframe = NULL; + struct delta_frame *simframe = &netplay->buffer[sim_ptr]; for (device = 0; device < MAX_INPUT_DEVICES; device++) { unsigned dtype = netplay->config_devices[device]&RETRO_DEVICE_MASK; uint32_t dsize = netplay_expected_input_size(netplay, 1 << device); - clients = netplay->device_clients[device]; - client_count = 0; + clients = netplay->device_clients[device]; + client_count = 0; /* Make sure all real clients are accounted for */ for (simstate = simframe->real_input[device]; simstate; simstate = simstate->next) { - if (!simstate->used || simstate->size != dsize) continue; + if (!simstate->used || simstate->size != dsize) + continue; clients |= 1<client_num; } for (client = 0; client < MAX_CLIENTS; client++) { - if (!(clients & (1<real_input[device], client, dsize, false, true); + simstate = netplay_input_state_for( + &simframe->real_input[device], client, dsize, false, true); if (!simstate) { - /* Don't already have this input, so must simulate if we're supposed to have it at all */ + /* Don't already have this input, so must + * simulate if we're supposed to have it at all */ if (netplay->read_frame_count[client] > simframe->frame) continue; simstate = netplay_input_state_for(&simframe->simlated_input[device], client, dsize, false, false); @@ -368,37 +406,39 @@ bool netplay_resolve_input(netplay_t *netplay, size_t sim_ptr, bool resim) * wavefronts. */ const uint32_t keep = - (1U<data[0] &= keep; simstate->data[0] |= pstate->data[0] & ~keep; } else - { memcpy(simstate->data, pstate->data, dsize * sizeof(uint32_t)); - } } client_state = simstate; client_count++; } - /* The frontend always uses the first resolved input, so make sure it's right */ + /* The frontend always uses the first resolved input, + * so make sure it's right */ while (simframe->resolved_input[device] && (simframe->resolved_input[device]->size != dsize || simframe->resolved_input[device]->client_num != 0)) { /* The default resolved input is of the wrong size! */ - netplay_input_state_t nextistate = simframe->resolved_input[device]->next; + netplay_input_state_t nextistate = + simframe->resolved_input[device]->next; free(simframe->resolved_input[device]); simframe->resolved_input[device] = nextistate; } - /* Now we copy the state, whether real or simulated, out into the resolved state */ - resstate = netplay_input_state_for(&simframe->resolved_input[device], 0, + /* Now we copy the state, whether real or simulated, + * out into the resolved state */ + resstate = netplay_input_state_for( + &simframe->resolved_input[device], 0, dsize, false, false); if (!resstate) continue; @@ -406,9 +446,11 @@ bool netplay_resolve_input(netplay_t *netplay, size_t sim_ptr, bool resim) if (client_count == 1) { /* Trivial in the common 1-client case */ - if (memcmp(resstate->data, client_state->data, dsize * sizeof(uint32_t))) + if (memcmp(resstate->data, client_state->data, + dsize * sizeof(uint32_t))) ret = true; - memcpy(resstate->data, client_state->data, dsize * sizeof(uint32_t)); + memcpy(resstate->data, client_state->data, + dsize * sizeof(uint32_t)); } else if (client_count == 0) @@ -426,23 +468,27 @@ bool netplay_resolve_input(netplay_t *netplay, size_t sim_ptr, bool resim) { /* Merge them */ /* Most devices have all the digital parts in the first word. */ - static const uint32_t digital_common[3] = {~0u, 0u, 0u}; + static const uint32_t digital_common[3] = {~0u, 0u, 0u}; static const uint32_t digital_keyboard[5] = {~0u, ~0u, ~0u, ~0u, ~0u}; const uint32_t *digital; if (dtype == RETRO_DEVICE_KEYBOARD) digital = digital_keyboard; else digital = digital_common; - oldresstate = netplay_input_state_for(&simframe->resolved_input[device], 1, dsize, false, false); + oldresstate = netplay_input_state_for( + &simframe->resolved_input[device], 1, dsize, false, false); if (!oldresstate) continue; memcpy(oldresstate->data, resstate->data, dsize * sizeof(uint32_t)); memset(resstate->data, 0, dsize * sizeof(uint32_t)); - netplay_merge_digital(netplay, resstate, simframe, device, clients, digital); - netplay_merge_analog(netplay, resstate, simframe, device, clients, dtype); + netplay_merge_digital(netplay, resstate, simframe, + device, clients, digital); + netplay_merge_analog(netplay, resstate, simframe, + device, clients, dtype); - if (memcmp(resstate->data, oldresstate->data, dsize * sizeof(uint32_t))) + if (memcmp(resstate->data, oldresstate->data, + dsize * sizeof(uint32_t))) ret = true; } @@ -451,7 +497,8 @@ bool netplay_resolve_input(netplay_t *netplay, size_t sim_ptr, bool resim) return ret; } -static void netplay_handle_frame_hash(netplay_t *netplay, struct delta_frame *delta) +static void netplay_handle_frame_hash(netplay_t *netplay, + struct delta_frame *delta) { if (netplay->is_server) { @@ -468,12 +515,10 @@ static void netplay_handle_frame_hash(netplay_t *netplay, struct delta_frame *de uint32_t local_crc = netplay_delta_frame_crc(netplay, delta); if (local_crc != delta->crc) { + /* If the very first check frame is wrong, + * they probably just don't work */ if (!netplay->crc_validity_checked) - { - /* If the very first check frame is wrong, they probably just don't - * work */ netplay->crcs_valid = false; - } else if (netplay->crcs_valid) { /* Fix this! */ @@ -483,15 +528,11 @@ static void netplay_handle_frame_hash(netplay_t *netplay, struct delta_frame *de RARCH_ERR("Netplay CRCs mismatch!\n"); } else - { netplay_cmd_request_savestate(netplay); - } } } else if (!netplay->crc_validity_checked) - { netplay->crc_validity_checked = true; - } } } @@ -505,29 +546,33 @@ bool netplay_sync_pre_frame(netplay_t *netplay) { retro_ctx_serialize_info_t serial_info; - if (netplay_delta_frame_ready(netplay, &netplay->buffer[netplay->run_ptr], netplay->run_frame_count)) + if (netplay_delta_frame_ready(netplay, + &netplay->buffer[netplay->run_ptr], netplay->run_frame_count)) { serial_info.data_const = NULL; - serial_info.data = netplay->buffer[netplay->run_ptr].state; - serial_info.size = netplay->state_size; + serial_info.data = netplay->buffer[netplay->run_ptr].state; + serial_info.size = netplay->state_size; memset(serial_info.data, 0, serial_info.size); - if ((netplay->quirks & NETPLAY_QUIRK_INITIALIZATION) || netplay->run_frame_count == 0) + if ((netplay->quirks & NETPLAY_QUIRK_INITIALIZATION) + || netplay->run_frame_count == 0) { /* Don't serialize until it's safe */ } - else if (!(netplay->quirks & NETPLAY_QUIRK_NO_SAVESTATES) && core_serialize(&serial_info)) + else if (!(netplay->quirks & NETPLAY_QUIRK_NO_SAVESTATES) + && core_serialize(&serial_info)) { - if (netplay->force_send_savestate && !netplay->stall && !netplay->remote_paused) + if (netplay->force_send_savestate && !netplay->stall + && !netplay->remote_paused) { - /* Bring our running frame and input frames into parity so we don't - * send old info */ + /* Bring our running frame and input frames into + * parity so we don't send old info. */ if (netplay->run_ptr != netplay->self_ptr) { memcpy(netplay->buffer[netplay->self_ptr].state, netplay->buffer[netplay->run_ptr].state, netplay->state_size); - netplay->run_ptr = netplay->self_ptr; + netplay->run_ptr = netplay->self_ptr; netplay->run_frame_count = netplay->self_frame_count; } @@ -545,7 +590,8 @@ bool netplay_sync_pre_frame(netplay_t *netplay) netplay->stateless_mode = true; } - /* If we can't transmit savestates, we must stall until the client is ready */ + /* If we can't transmit savestates, we must stall + * until the client is ready. */ if (netplay->run_frame_count > 0 && (netplay->quirks & (NETPLAY_QUIRK_NO_SAVESTATES|NETPLAY_QUIRK_NO_TRANSMISSION)) && (netplay->connections_size == 0 || !netplay->connections[0].active || @@ -566,11 +612,14 @@ bool netplay_sync_pre_frame(netplay_t *netplay) /* Check for a connection */ FD_ZERO(&fds); FD_SET(netplay->listen_fd, &fds); - if (socket_select(netplay->listen_fd + 1, &fds, NULL, NULL, &tmp_tv) > 0 && + if (socket_select(netplay->listen_fd + 1, + &fds, NULL, NULL, &tmp_tv) > 0 && FD_ISSET(netplay->listen_fd, &fds)) { addr_size = sizeof(their_addr); - new_fd = accept(netplay->listen_fd, (struct sockaddr*)&their_addr, &addr_size); + new_fd = accept(netplay->listen_fd, + (struct sockaddr*)&their_addr, &addr_size); + if (new_fd < 0) { RARCH_ERR("%s\n", msg_hash_to_str(MSG_NETPLAY_FAILED)); @@ -614,8 +663,10 @@ bool netplay_sync_pre_frame(netplay_t *netplay) { if (connection_num == 0) { - netplay->connections = (struct netplay_connection*)malloc(sizeof(struct netplay_connection)); - if (netplay->connections == NULL) + netplay->connections = (struct netplay_connection*) + malloc(sizeof(struct netplay_connection)); + + if (!netplay->connections) { socket_close(new_fd); goto process; @@ -626,10 +677,13 @@ bool netplay_sync_pre_frame(netplay_t *netplay) else { size_t new_connections_size = netplay->connections_size * 2; - struct netplay_connection *new_connections = (struct netplay_connection*) + struct netplay_connection + *new_connections = (struct netplay_connection*) + realloc(netplay->connections, new_connections_size*sizeof(struct netplay_connection)); - if (new_connections == NULL) + + if (!new_connections) { socket_close(new_fd); goto process; @@ -694,7 +748,8 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled) /* We've finished an input frame even if we're stalling */ if ((!stalled || netplay->stall == NETPLAY_STALL_INPUT_LATENCY) && - netplay->self_frame_count < netplay->run_frame_count + netplay->input_latency_frames) + netplay->self_frame_count < + netplay->run_frame_count + netplay->input_latency_frames) { netplay->self_ptr = NEXT_PTR(netplay->self_ptr); netplay->self_frame_count++; @@ -947,12 +1002,14 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled) * clients ahead of us stall */ for (i = 0; i < netplay->connections_size; i++) { - struct netplay_connection *connection = &netplay->connections[i]; uint32_t client_num; + struct netplay_connection *connection = &netplay->connections[i]; + if (!connection->active || connection->mode != NETPLAY_CONNECTION_PLAYING) continue; - client_num = i + 1; + + client_num = (uint32_t)(i + 1); /* Are they ahead? */ if (netplay->self_frame_count + 3 < netplay->read_frame_count[client_num]) diff --git a/pkg/android/phoenix/AndroidManifest.xml b/pkg/android/phoenix/AndroidManifest.xml index 64fb606419..ba922a497f 100644 --- a/pkg/android/phoenix/AndroidManifest.xml +++ b/pkg/android/phoenix/AndroidManifest.xml @@ -1,8 +1,8 @@ diff --git a/pkg/android/phoenix/jni/Android.mk b/pkg/android/phoenix/jni/Android.mk index 20cb44d57a..c5a6291e07 100644 --- a/pkg/android/phoenix/jni/Android.mk +++ b/pkg/android/phoenix/jni/Android.mk @@ -67,7 +67,7 @@ else 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_CHD +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 DEFINES += -DWANT_IFADDRS ifeq ($(HAVE_VULKAN),1) diff --git a/pkg/apple/RetroArch.xcodeproj/project.pbxproj b/pkg/apple/RetroArch.xcodeproj/project.pbxproj index d3f84fbbc0..73e4e0c3bf 100644 --- a/pkg/apple/RetroArch.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch.xcodeproj/project.pbxproj @@ -497,8 +497,11 @@ MACOSX_DEPLOYMENT_TARGET = 10.5; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ( + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_FLAC", + "-DHAVE_DR_FLAC", + "-DHAVE_DR_MP3", "-DHAVE_LROUND", "-DFLAC__HAS_OGG=0", "-DHAVE_CHD", @@ -557,8 +560,11 @@ GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.5; OTHER_CFLAGS = ( + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_FLAC", + "-DHAVE_DR_FLAC", + "-DHAVE_DR_MP3", "-DHAVE_LROUND", "-DFLAC__HAS_OGG=0", "-DHAVE_CHD", diff --git a/pkg/apple/RetroArch_PPC.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_PPC.xcodeproj/project.pbxproj index 88d2fe4f7b..af4c288810 100644 --- a/pkg/apple/RetroArch_PPC.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_PPC.xcodeproj/project.pbxproj @@ -288,6 +288,7 @@ ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( "-DMSB_FIRST", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_MINIUPNPC", "-DHAVE_BUILTINMINIUPNPC", @@ -362,6 +363,7 @@ "-DNS_BLOCK_ASSERTIONS=1", "-DNDEBUG", "-DMSB_FIRST", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_MINIUPNPC", "-DHAVE_BUILTINMINIUPNPC", diff --git a/pkg/apple/RetroArch_iOS10.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_iOS10.xcodeproj/project.pbxproj index 5a76d298f8..b7d7273f6a 100644 --- a/pkg/apple/RetroArch_iOS10.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_iOS10.xcodeproj/project.pbxproj @@ -332,6 +332,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -417,6 +418,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -469,6 +471,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -555,6 +558,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -625,6 +629,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", diff --git a/pkg/apple/RetroArch_iOS11.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_iOS11.xcodeproj/project.pbxproj index 5c0b588200..b1a0bbe5f7 100644 --- a/pkg/apple/RetroArch_iOS11.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_iOS11.xcodeproj/project.pbxproj @@ -332,6 +332,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -418,6 +419,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -471,6 +473,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -558,6 +561,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -628,6 +632,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", diff --git a/pkg/apple/RetroArch_iOS6.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_iOS6.xcodeproj/project.pbxproj index ce77a3519e..0e8c0d9496 100644 --- a/pkg/apple/RetroArch_iOS6.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_iOS6.xcodeproj/project.pbxproj @@ -344,6 +344,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -425,6 +426,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -473,6 +475,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -554,6 +557,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -623,6 +627,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", diff --git a/pkg/apple/RetroArch_iOS8.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_iOS8.xcodeproj/project.pbxproj index 713811bdd1..bf4b24262e 100644 --- a/pkg/apple/RetroArch_iOS8.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_iOS8.xcodeproj/project.pbxproj @@ -347,6 +347,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -416,6 +417,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -490,6 +492,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -574,6 +577,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -625,6 +629,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", diff --git a/pkg/apple/RetroArch_iOS9.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_iOS9.xcodeproj/project.pbxproj index 30534c7f2e..6def3a6b4d 100644 --- a/pkg/apple/RetroArch_iOS9.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_iOS9.xcodeproj/project.pbxproj @@ -362,6 +362,7 @@ "-DHAVE_CORETEXT", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -445,6 +446,7 @@ "-DHAVE_CORETEXT", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -495,6 +497,7 @@ "-DHAVE_CORETEXT", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -580,6 +583,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", @@ -649,6 +653,7 @@ "-DHAVE_HID", "-DHAVE_NETWORKING", "-DHAVE_AVFOUNDATION", + "-DHAVE_RUNAHEAD", "-DHAVE_GRIFFIN", "-DHAVE_STB_VORBIS", "-DHAVE_MINIUPNPC", diff --git a/pkg/ctr/Makefile.cores b/pkg/ctr/Makefile.cores index ec73cf9b5d..8fabdb8bd7 100644 --- a/pkg/ctr/Makefile.cores +++ b/pkg/ctr/Makefile.cores @@ -75,9 +75,9 @@ else ifeq ($(LIBRETRO), freeintv) APP_TITLE = FreeIntv APP_AUTHOR = various APP_PRODUCT_CODE = RARCH-FREEINTV - APP_UNIQUE_ID = 0xBAC1G - APP_ICON = pkg/ctr/assets/default.png - APP_BANNER = pkg/ctr/assets/libretro_banner.png + APP_UNIQUE_ID = 0xBAC21 + APP_ICON = pkg/ctr/assets/freeintv.png + APP_BANNER = pkg/ctr/assets/freeintv_banner.png else ifeq ($(LIBRETRO), fuse) APP_TITLE = Fuse @@ -273,7 +273,7 @@ else ifeq ($(LIBRETRO), stella) APP_UNIQUE_ID = 0xBAC2C APP_ICON = pkg/ctr/assets/stella.png APP_BANNER = pkg/ctr/assets/stella_banner.png - + else ifeq ($(LIBRETRO), pokemini) APP_TITLE = PokeMini APP_AUTHOR = justburn @@ -282,4 +282,4 @@ else ifeq ($(LIBRETRO), pokemini) APP_ICON = pkg/ctr/assets/default.png APP_BANNER = pkg/ctr/assets/libretro_banner.png -endif \ No newline at end of file +endif diff --git a/pkg/ctr/assets/2048.png b/pkg/ctr/assets/2048.png index 04b79d3d21..06e4cc3da7 100644 Binary files a/pkg/ctr/assets/2048.png and b/pkg/ctr/assets/2048.png differ diff --git a/pkg/ctr/assets/2048_banner.png b/pkg/ctr/assets/2048_banner.png index 461bdb396d..c110b894e6 100644 Binary files a/pkg/ctr/assets/2048_banner.png and b/pkg/ctr/assets/2048_banner.png differ diff --git a/pkg/ctr/assets/4do.png b/pkg/ctr/assets/4do.png index 296f31bc51..7eab685bfb 100644 Binary files a/pkg/ctr/assets/4do.png and b/pkg/ctr/assets/4do.png differ diff --git a/pkg/ctr/assets/4do_banner.png b/pkg/ctr/assets/4do_banner.png index 1f3057dd16..c0fcbae420 100644 Binary files a/pkg/ctr/assets/4do_banner.png and b/pkg/ctr/assets/4do_banner.png differ diff --git a/pkg/ctr/assets/81.png b/pkg/ctr/assets/81.png index b0404d6731..691add6e27 100644 Binary files a/pkg/ctr/assets/81.png and b/pkg/ctr/assets/81.png differ diff --git a/pkg/ctr/assets/81_banner.png b/pkg/ctr/assets/81_banner.png index 76697a38e1..8896cc5973 100644 Binary files a/pkg/ctr/assets/81_banner.png and b/pkg/ctr/assets/81_banner.png differ diff --git a/pkg/ctr/assets/assets.7z b/pkg/ctr/assets/assets.7z index de2e1c4acf..b627acef6c 100644 Binary files a/pkg/ctr/assets/assets.7z and b/pkg/ctr/assets/assets.7z differ diff --git a/pkg/ctr/assets/atari800.png b/pkg/ctr/assets/atari800.png index 05796ded0d..501edde06b 100644 Binary files a/pkg/ctr/assets/atari800.png and b/pkg/ctr/assets/atari800.png differ diff --git a/pkg/ctr/assets/atari800_banner.png b/pkg/ctr/assets/atari800_banner.png index 0b731557de..4f93af10e3 100644 Binary files a/pkg/ctr/assets/atari800_banner.png and b/pkg/ctr/assets/atari800_banner.png differ diff --git a/pkg/ctr/assets/default.png b/pkg/ctr/assets/default.png index b6c6d67f6c..54f3fb4c28 100644 Binary files a/pkg/ctr/assets/default.png and b/pkg/ctr/assets/default.png differ diff --git a/pkg/ctr/assets/dosbox.png b/pkg/ctr/assets/dosbox.png index e6700a5d68..44446baa4e 100644 Binary files a/pkg/ctr/assets/dosbox.png and b/pkg/ctr/assets/dosbox.png differ diff --git a/pkg/ctr/assets/dosbox_banner.png b/pkg/ctr/assets/dosbox_banner.png index 30b41d5480..905f917d56 100644 Binary files a/pkg/ctr/assets/dosbox_banner.png and b/pkg/ctr/assets/dosbox_banner.png differ diff --git a/pkg/ctr/assets/fbalpha2012.png b/pkg/ctr/assets/fbalpha2012.png index c0cf19e75d..307f97b345 100644 Binary files a/pkg/ctr/assets/fbalpha2012.png and b/pkg/ctr/assets/fbalpha2012.png differ diff --git a/pkg/ctr/assets/fbalpha2012_banner.png b/pkg/ctr/assets/fbalpha2012_banner.png index 82f6bced5a..4090e9a5d7 100644 Binary files a/pkg/ctr/assets/fbalpha2012_banner.png and b/pkg/ctr/assets/fbalpha2012_banner.png differ diff --git a/pkg/ctr/assets/fbalpha2012_cps1.png b/pkg/ctr/assets/fbalpha2012_cps1.png index 29b32d7855..4ad709cd8b 100644 Binary files a/pkg/ctr/assets/fbalpha2012_cps1.png and b/pkg/ctr/assets/fbalpha2012_cps1.png differ diff --git a/pkg/ctr/assets/fbalpha2012_cps1_banner.png b/pkg/ctr/assets/fbalpha2012_cps1_banner.png index 57ab42ae40..3d2fe99a22 100644 Binary files a/pkg/ctr/assets/fbalpha2012_cps1_banner.png and b/pkg/ctr/assets/fbalpha2012_cps1_banner.png differ diff --git a/pkg/ctr/assets/fbalpha2012_cps2.png b/pkg/ctr/assets/fbalpha2012_cps2.png index e1addcc885..22a3280c19 100644 Binary files a/pkg/ctr/assets/fbalpha2012_cps2.png and b/pkg/ctr/assets/fbalpha2012_cps2.png differ diff --git a/pkg/ctr/assets/fbalpha2012_cps2_banner.png b/pkg/ctr/assets/fbalpha2012_cps2_banner.png index 0c8fde0440..2fc3073b74 100644 Binary files a/pkg/ctr/assets/fbalpha2012_cps2_banner.png and b/pkg/ctr/assets/fbalpha2012_cps2_banner.png differ diff --git a/pkg/ctr/assets/fbalpha2012_cps3.png b/pkg/ctr/assets/fbalpha2012_cps3.png index f153dc1ebf..03f3f01689 100644 Binary files a/pkg/ctr/assets/fbalpha2012_cps3.png and b/pkg/ctr/assets/fbalpha2012_cps3.png differ diff --git a/pkg/ctr/assets/fbalpha2012_cps3_banner.png b/pkg/ctr/assets/fbalpha2012_cps3_banner.png index fab265981a..50bd926bf8 100644 Binary files a/pkg/ctr/assets/fbalpha2012_cps3_banner.png and b/pkg/ctr/assets/fbalpha2012_cps3_banner.png differ diff --git a/pkg/ctr/assets/fbalpha2012_neogeo.png b/pkg/ctr/assets/fbalpha2012_neogeo.png index 444890bdcc..f1b12857d4 100644 Binary files a/pkg/ctr/assets/fbalpha2012_neogeo.png and b/pkg/ctr/assets/fbalpha2012_neogeo.png differ diff --git a/pkg/ctr/assets/fbalpha2012_neogeo_banner.png b/pkg/ctr/assets/fbalpha2012_neogeo_banner.png index 769101af1b..c1cf8f79a5 100644 Binary files a/pkg/ctr/assets/fbalpha2012_neogeo_banner.png and b/pkg/ctr/assets/fbalpha2012_neogeo_banner.png differ diff --git a/pkg/ctr/assets/fceumm.png b/pkg/ctr/assets/fceumm.png index c3b106f7fc..4af02ff4ac 100644 Binary files a/pkg/ctr/assets/fceumm.png and b/pkg/ctr/assets/fceumm.png differ diff --git a/pkg/ctr/assets/fceumm_banner.png b/pkg/ctr/assets/fceumm_banner.png index 7a94dcedf8..fbf12f2523 100644 Binary files a/pkg/ctr/assets/fceumm_banner.png and b/pkg/ctr/assets/fceumm_banner.png differ diff --git a/pkg/ctr/assets/fmsx.png b/pkg/ctr/assets/fmsx.png index 4163e28480..6b62bc3285 100644 Binary files a/pkg/ctr/assets/fmsx.png and b/pkg/ctr/assets/fmsx.png differ diff --git a/pkg/ctr/assets/fmsx_banner.png b/pkg/ctr/assets/fmsx_banner.png index 6a175d2307..0463689a6a 100644 Binary files a/pkg/ctr/assets/fmsx_banner.png and b/pkg/ctr/assets/fmsx_banner.png differ diff --git a/pkg/ctr/assets/freeintv.png b/pkg/ctr/assets/freeintv.png new file mode 100644 index 0000000000..3df7222f04 Binary files /dev/null and b/pkg/ctr/assets/freeintv.png differ diff --git a/pkg/ctr/assets/freeintv_banner.png b/pkg/ctr/assets/freeintv_banner.png new file mode 100644 index 0000000000..a3e13504c4 Binary files /dev/null and b/pkg/ctr/assets/freeintv_banner.png differ diff --git a/pkg/ctr/assets/fuse.png b/pkg/ctr/assets/fuse.png index 4d94048205..93ddeebbd8 100644 Binary files a/pkg/ctr/assets/fuse.png and b/pkg/ctr/assets/fuse.png differ diff --git a/pkg/ctr/assets/fuse_banner.png b/pkg/ctr/assets/fuse_banner.png index eec7ab0ac4..66f402b8f1 100644 Binary files a/pkg/ctr/assets/fuse_banner.png and b/pkg/ctr/assets/fuse_banner.png differ diff --git a/pkg/ctr/assets/gambatte.png b/pkg/ctr/assets/gambatte.png index 8b9226a588..ff939c8356 100644 Binary files a/pkg/ctr/assets/gambatte.png and b/pkg/ctr/assets/gambatte.png differ diff --git a/pkg/ctr/assets/gambatte_banner.png b/pkg/ctr/assets/gambatte_banner.png index 855510b492..4da4319f08 100644 Binary files a/pkg/ctr/assets/gambatte_banner.png and b/pkg/ctr/assets/gambatte_banner.png differ diff --git a/pkg/ctr/assets/genesis_plus_gx.png b/pkg/ctr/assets/genesis_plus_gx.png index 1efb88e4fc..b051576a0d 100644 Binary files a/pkg/ctr/assets/genesis_plus_gx.png and b/pkg/ctr/assets/genesis_plus_gx.png differ diff --git a/pkg/ctr/assets/genesis_plus_gx_banner.png b/pkg/ctr/assets/genesis_plus_gx_banner.png index cb9c2bd297..4c9531b7e7 100644 Binary files a/pkg/ctr/assets/genesis_plus_gx_banner.png and b/pkg/ctr/assets/genesis_plus_gx_banner.png differ diff --git a/pkg/ctr/assets/gpsp.png b/pkg/ctr/assets/gpsp.png index 9373f51939..e237c09b7b 100644 Binary files a/pkg/ctr/assets/gpsp.png and b/pkg/ctr/assets/gpsp.png differ diff --git a/pkg/ctr/assets/gpsp_banner.png b/pkg/ctr/assets/gpsp_banner.png index e5a8777a23..74b0728236 100644 Binary files a/pkg/ctr/assets/gpsp_banner.png and b/pkg/ctr/assets/gpsp_banner.png differ diff --git a/pkg/ctr/assets/gw.png b/pkg/ctr/assets/gw.png index 2ed4457d87..94036488c2 100644 Binary files a/pkg/ctr/assets/gw.png and b/pkg/ctr/assets/gw.png differ diff --git a/pkg/ctr/assets/gw_banner.png b/pkg/ctr/assets/gw_banner.png index a08b68936b..c13466cf54 100644 Binary files a/pkg/ctr/assets/gw_banner.png and b/pkg/ctr/assets/gw_banner.png differ diff --git a/pkg/ctr/assets/handy.png b/pkg/ctr/assets/handy.png index 4681ac4b1d..fe1f44e42b 100644 Binary files a/pkg/ctr/assets/handy.png and b/pkg/ctr/assets/handy.png differ diff --git a/pkg/ctr/assets/handy_banner.png b/pkg/ctr/assets/handy_banner.png index 22be94e292..d8576a5cd3 100644 Binary files a/pkg/ctr/assets/handy_banner.png and b/pkg/ctr/assets/handy_banner.png differ diff --git a/pkg/ctr/assets/libretro_banner.png b/pkg/ctr/assets/libretro_banner.png index 284b6f91e3..6e06290421 100644 Binary files a/pkg/ctr/assets/libretro_banner.png and b/pkg/ctr/assets/libretro_banner.png differ diff --git a/pkg/ctr/assets/libretro_neutral_shaded_banner.png b/pkg/ctr/assets/libretro_neutral_shaded_banner.png index dbfa96dd4a..83254d29af 100644 Binary files a/pkg/ctr/assets/libretro_neutral_shaded_banner.png and b/pkg/ctr/assets/libretro_neutral_shaded_banner.png differ diff --git a/pkg/ctr/assets/mame2000.png b/pkg/ctr/assets/mame2000.png index ad439a5254..d3f6d0b3d5 100644 Binary files a/pkg/ctr/assets/mame2000.png and b/pkg/ctr/assets/mame2000.png differ diff --git a/pkg/ctr/assets/mame2000_banner.png b/pkg/ctr/assets/mame2000_banner.png index 86f5e192d0..a44c77e104 100644 Binary files a/pkg/ctr/assets/mame2000_banner.png and b/pkg/ctr/assets/mame2000_banner.png differ diff --git a/pkg/ctr/assets/mame2003.png b/pkg/ctr/assets/mame2003.png index c6985d7798..edd1cd2ea4 100644 Binary files a/pkg/ctr/assets/mame2003.png and b/pkg/ctr/assets/mame2003.png differ diff --git a/pkg/ctr/assets/mame2003_banner.png b/pkg/ctr/assets/mame2003_banner.png index c44892b266..c1eb1586e0 100644 Binary files a/pkg/ctr/assets/mame2003_banner.png and b/pkg/ctr/assets/mame2003_banner.png differ diff --git a/pkg/ctr/assets/mednafen_ngp.png b/pkg/ctr/assets/mednafen_ngp.png index f8e4987b12..70cdd30f09 100644 Binary files a/pkg/ctr/assets/mednafen_ngp.png and b/pkg/ctr/assets/mednafen_ngp.png differ diff --git a/pkg/ctr/assets/mednafen_ngp_banner.png b/pkg/ctr/assets/mednafen_ngp_banner.png index 22d3061056..ce15124f2e 100644 Binary files a/pkg/ctr/assets/mednafen_ngp_banner.png and b/pkg/ctr/assets/mednafen_ngp_banner.png differ diff --git a/pkg/ctr/assets/mednafen_pce_fast.png b/pkg/ctr/assets/mednafen_pce_fast.png index ed9c7a0434..5e280792be 100644 Binary files a/pkg/ctr/assets/mednafen_pce_fast.png and b/pkg/ctr/assets/mednafen_pce_fast.png differ diff --git a/pkg/ctr/assets/mednafen_pce_fast_banner.png b/pkg/ctr/assets/mednafen_pce_fast_banner.png index ad32f9b9b4..e86d4b38b0 100644 Binary files a/pkg/ctr/assets/mednafen_pce_fast_banner.png and b/pkg/ctr/assets/mednafen_pce_fast_banner.png differ diff --git a/pkg/ctr/assets/mednafen_vb.png b/pkg/ctr/assets/mednafen_vb.png index dae4ed473f..ada5e8b68a 100644 Binary files a/pkg/ctr/assets/mednafen_vb.png and b/pkg/ctr/assets/mednafen_vb.png differ diff --git a/pkg/ctr/assets/mednafen_vb_banner.png b/pkg/ctr/assets/mednafen_vb_banner.png index b48b742841..7349c53e38 100644 Binary files a/pkg/ctr/assets/mednafen_vb_banner.png and b/pkg/ctr/assets/mednafen_vb_banner.png differ diff --git a/pkg/ctr/assets/mednafen_wswan.png b/pkg/ctr/assets/mednafen_wswan.png index e62a1958ce..2e14411161 100644 Binary files a/pkg/ctr/assets/mednafen_wswan.png and b/pkg/ctr/assets/mednafen_wswan.png differ diff --git a/pkg/ctr/assets/mednafen_wswan_banner.png b/pkg/ctr/assets/mednafen_wswan_banner.png index 9d3c1646f1..028a4ed1ad 100644 Binary files a/pkg/ctr/assets/mednafen_wswan_banner.png and b/pkg/ctr/assets/mednafen_wswan_banner.png differ diff --git a/pkg/ctr/assets/mgba_banner.png b/pkg/ctr/assets/mgba_banner.png index fbaef75750..46be827979 100644 Binary files a/pkg/ctr/assets/mgba_banner.png and b/pkg/ctr/assets/mgba_banner.png differ diff --git a/pkg/ctr/assets/nekop2.png b/pkg/ctr/assets/nekop2.png index d7695ba10e..3114361c91 100644 Binary files a/pkg/ctr/assets/nekop2.png and b/pkg/ctr/assets/nekop2.png differ diff --git a/pkg/ctr/assets/nekop2_banner.png b/pkg/ctr/assets/nekop2_banner.png index c97662eb6e..13be556cf4 100644 Binary files a/pkg/ctr/assets/nekop2_banner.png and b/pkg/ctr/assets/nekop2_banner.png differ diff --git a/pkg/ctr/assets/nestopia.png b/pkg/ctr/assets/nestopia.png index b27ec6a51c..bc1793a05f 100644 Binary files a/pkg/ctr/assets/nestopia.png and b/pkg/ctr/assets/nestopia.png differ diff --git a/pkg/ctr/assets/nestopia_banner.png b/pkg/ctr/assets/nestopia_banner.png index 3676f2298e..559d9bf0af 100644 Binary files a/pkg/ctr/assets/nestopia_banner.png and b/pkg/ctr/assets/nestopia_banner.png differ diff --git a/pkg/ctr/assets/np2kai.png b/pkg/ctr/assets/np2kai.png index d7695ba10e..3114361c91 100644 Binary files a/pkg/ctr/assets/np2kai.png and b/pkg/ctr/assets/np2kai.png differ diff --git a/pkg/ctr/assets/np2kai_banner.png b/pkg/ctr/assets/np2kai_banner.png index 83a82db0f6..1321318099 100644 Binary files a/pkg/ctr/assets/np2kai_banner.png and b/pkg/ctr/assets/np2kai_banner.png differ diff --git a/pkg/ctr/assets/nxengine.png b/pkg/ctr/assets/nxengine.png index d6c788a779..f5077b0aba 100644 Binary files a/pkg/ctr/assets/nxengine.png and b/pkg/ctr/assets/nxengine.png differ diff --git a/pkg/ctr/assets/nxengine_banner.png b/pkg/ctr/assets/nxengine_banner.png index fe40fd4541..ab7c613e7f 100644 Binary files a/pkg/ctr/assets/nxengine_banner.png and b/pkg/ctr/assets/nxengine_banner.png differ diff --git a/pkg/ctr/assets/o2em.png b/pkg/ctr/assets/o2em.png index 5be6e266b4..db0595c3d3 100644 Binary files a/pkg/ctr/assets/o2em.png and b/pkg/ctr/assets/o2em.png differ diff --git a/pkg/ctr/assets/o2em_banner.png b/pkg/ctr/assets/o2em_banner.png index 76f4d0647f..86123b74c5 100644 Binary files a/pkg/ctr/assets/o2em_banner.png and b/pkg/ctr/assets/o2em_banner.png differ diff --git a/pkg/ctr/assets/pcsx_rearmed.png b/pkg/ctr/assets/pcsx_rearmed.png index a7a57d55a5..d06c555ea5 100644 Binary files a/pkg/ctr/assets/pcsx_rearmed.png and b/pkg/ctr/assets/pcsx_rearmed.png differ diff --git a/pkg/ctr/assets/pcsx_rearmed_banner.png b/pkg/ctr/assets/pcsx_rearmed_banner.png index 0615758791..be38d0c041 100644 Binary files a/pkg/ctr/assets/pcsx_rearmed_banner.png and b/pkg/ctr/assets/pcsx_rearmed_banner.png differ diff --git a/pkg/ctr/assets/picodrive.png b/pkg/ctr/assets/picodrive.png index 181d1ac951..6f36612ea7 100644 Binary files a/pkg/ctr/assets/picodrive.png and b/pkg/ctr/assets/picodrive.png differ diff --git a/pkg/ctr/assets/picodrive_banner.png b/pkg/ctr/assets/picodrive_banner.png index 5401611057..770107e624 100644 Binary files a/pkg/ctr/assets/picodrive_banner.png and b/pkg/ctr/assets/picodrive_banner.png differ diff --git a/pkg/ctr/assets/prosystem.png b/pkg/ctr/assets/prosystem.png index a9a8c35009..018dc17e70 100644 Binary files a/pkg/ctr/assets/prosystem.png and b/pkg/ctr/assets/prosystem.png differ diff --git a/pkg/ctr/assets/prosystem_banner.png b/pkg/ctr/assets/prosystem_banner.png index a3c616585d..87308ad553 100644 Binary files a/pkg/ctr/assets/prosystem_banner.png and b/pkg/ctr/assets/prosystem_banner.png differ diff --git a/pkg/ctr/assets/quicknes.png b/pkg/ctr/assets/quicknes.png index 151a8a8ec6..b17568a94e 100644 Binary files a/pkg/ctr/assets/quicknes.png and b/pkg/ctr/assets/quicknes.png differ diff --git a/pkg/ctr/assets/quicknes_banner.png b/pkg/ctr/assets/quicknes_banner.png index a8f86f2f75..c6e871a5e8 100644 Binary files a/pkg/ctr/assets/quicknes_banner.png and b/pkg/ctr/assets/quicknes_banner.png differ diff --git a/pkg/ctr/assets/snes9x2002.png b/pkg/ctr/assets/snes9x2002.png index 34ce4dc24a..6c0ae34f6b 100644 Binary files a/pkg/ctr/assets/snes9x2002.png and b/pkg/ctr/assets/snes9x2002.png differ diff --git a/pkg/ctr/assets/snes9x2002_banner.png b/pkg/ctr/assets/snes9x2002_banner.png index ddab3b446a..98b42d2175 100644 Binary files a/pkg/ctr/assets/snes9x2002_banner.png and b/pkg/ctr/assets/snes9x2002_banner.png differ diff --git a/pkg/ctr/assets/snes9x2005.png b/pkg/ctr/assets/snes9x2005.png index a13439df65..e8efbc121b 100644 Binary files a/pkg/ctr/assets/snes9x2005.png and b/pkg/ctr/assets/snes9x2005.png differ diff --git a/pkg/ctr/assets/snes9x2005_banner.png b/pkg/ctr/assets/snes9x2005_banner.png index 1167f68256..79dfbcc6cb 100644 Binary files a/pkg/ctr/assets/snes9x2005_banner.png and b/pkg/ctr/assets/snes9x2005_banner.png differ diff --git a/pkg/ctr/assets/snes9x2005_plus.png b/pkg/ctr/assets/snes9x2005_plus.png index 6d5584c9f8..b415a6644e 100644 Binary files a/pkg/ctr/assets/snes9x2005_plus.png and b/pkg/ctr/assets/snes9x2005_plus.png differ diff --git a/pkg/ctr/assets/snes9x2005_plus_banner.png b/pkg/ctr/assets/snes9x2005_plus_banner.png index 1fb9707b84..41c98ddb78 100644 Binary files a/pkg/ctr/assets/snes9x2005_plus_banner.png and b/pkg/ctr/assets/snes9x2005_plus_banner.png differ diff --git a/pkg/ctr/assets/snes9x2010.png b/pkg/ctr/assets/snes9x2010.png index e4bc6eec8e..428d5add75 100644 Binary files a/pkg/ctr/assets/snes9x2010.png and b/pkg/ctr/assets/snes9x2010.png differ diff --git a/pkg/ctr/assets/snes9x2010_banner.png b/pkg/ctr/assets/snes9x2010_banner.png index 848afe1908..cc5c6df41c 100644 Binary files a/pkg/ctr/assets/snes9x2010_banner.png and b/pkg/ctr/assets/snes9x2010_banner.png differ diff --git a/pkg/ctr/assets/stella.png b/pkg/ctr/assets/stella.png index bc09eaa269..c4a2c1e291 100644 Binary files a/pkg/ctr/assets/stella.png and b/pkg/ctr/assets/stella.png differ diff --git a/pkg/ctr/assets/stella_banner.png b/pkg/ctr/assets/stella_banner.png index 99eba8899b..e9cc2e51a4 100644 Binary files a/pkg/ctr/assets/stella_banner.png and b/pkg/ctr/assets/stella_banner.png differ diff --git a/pkg/ctr/assets/vecx.png b/pkg/ctr/assets/vecx.png index bc2cab2b21..65d0e8fb4b 100644 Binary files a/pkg/ctr/assets/vecx.png and b/pkg/ctr/assets/vecx.png differ diff --git a/pkg/ctr/assets/vecx_banner.png b/pkg/ctr/assets/vecx_banner.png index 9064197771..ad120c78eb 100644 Binary files a/pkg/ctr/assets/vecx_banner.png and b/pkg/ctr/assets/vecx_banner.png differ diff --git a/pkg/ctr/assets/virtualjaguar.png b/pkg/ctr/assets/virtualjaguar.png index 2f998c8895..87856c2670 100644 Binary files a/pkg/ctr/assets/virtualjaguar.png and b/pkg/ctr/assets/virtualjaguar.png differ diff --git a/pkg/ctr/assets/virtualjaguar_banner.png b/pkg/ctr/assets/virtualjaguar_banner.png index b50aee5757..1c8fab5cb0 100644 Binary files a/pkg/ctr/assets/virtualjaguar_banner.png and b/pkg/ctr/assets/virtualjaguar_banner.png differ diff --git a/pkg/ctr/assets/yabause.png b/pkg/ctr/assets/yabause.png index c94d855455..a363fd4ef2 100644 Binary files a/pkg/ctr/assets/yabause.png and b/pkg/ctr/assets/yabause.png differ diff --git a/pkg/ctr/assets/yabause_banner.png b/pkg/ctr/assets/yabause_banner.png index 0dfc9675a4..ed72ed8cd6 100644 Binary files a/pkg/ctr/assets/yabause_banner.png and b/pkg/ctr/assets/yabause_banner.png differ diff --git a/pkg/msvc/RetroArch-360/RetroArch-360.vcxproj b/pkg/msvc/RetroArch-360/RetroArch-360.vcxproj index d297901003..85bd70e68c 100644 --- a/pkg/msvc/RetroArch-360/RetroArch-360.vcxproj +++ b/pkg/msvc/RetroArch-360/RetroArch-360.vcxproj @@ -113,7 +113,7 @@ true false MultiThreadedDebug - _DEBUG;_XBOX;HAVE_XINPUT2;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_XUI;HAVE_MENU;HAVE_NETWORKING;HAVE_NETWORKING;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_EXEC;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_CC_RESAMPLER;HAVE_D3D9;HAVE_D3D;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_ZLIB;HAVE_XAUDIO;HAVE_RPNG;HAVE_RJPEG;HAVE_THREADS;HAVE_FILTERS_BUILTIN + _DEBUG;_XBOX;HAVE_XINPUT2;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_MENU;HAVE_NETWORKING;HAVE_NETWORKING;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_EXEC;D3DCOMPILE_USEVOIDS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_HLSL;HAVE_CC_RESAMPLER;HAVE_D3D9;HAVE_D3D;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_ZLIB;HAVE_XAUDIO;HAVE_RPNG;HAVE_RJPEG;HAVE_THREADS;HAVE_FILTERS_BUILTIN Callcap $(SolutionDir)\..\..\deps\zlib;$(SolutionDir)\..\..\libretro-common\include;$(SolutionDir)\..\..\deps;$(SolutionDir)\..\..\deps\stb;$(SolutionDir)\..\..\;%(AdditionalIncludeDirectories) @@ -152,7 +152,7 @@ AnalyzeOnly false MultiThreadedDebug - _DEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_XUI;HAVE_MENU;HAVE_ZLIB;HAVE_RARCH_EXEC;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_CC_RESAMPLER;HAVE_D3D9;HAVE_D3D;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_THREADS;HAVE_FILTERS_BUILTIN + _DEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_MENU;HAVE_ZLIB;HAVE_RARCH_EXEC;D3DCOMPILE_USEVOIDS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_HLSL;HAVE_CC_RESAMPLER;HAVE_D3D9;HAVE_D3D;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_THREADS;HAVE_FILTERS_BUILTIN Callcap $(SolutionDir)\..\..\deps\zlib;$(SolutionDir)\..\..\libretro-common\include;$(SolutionDir)\..\..\deps;$(SolutionDir)\..\..\deps\stb;$(SolutionDir)\..\..\;%(AdditionalIncludeDirectories) @@ -192,7 +192,7 @@ Size false MultiThreaded - NDEBUG;_XBOX;PROFILE;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_XUI;HAVE_MENU;HAVE_ZLIB;HAVE_RARCH_EXEC;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_CC_RESAMPLER;HAVE_D3D9;HAVE_D3D;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_ZLIB;HAVE_XAUDIO;HAVE_RPNG;HAVE_RJPEG;HAVE_THREADS;HAVE_FILTERS_BUILTIN + NDEBUG;_XBOX;PROFILE;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_MENU;HAVE_ZLIB;HAVE_RARCH_EXEC;D3DCOMPILE_USEVOIDS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_HLSL;HAVE_CC_RESAMPLER;HAVE_D3D9;HAVE_D3D;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_ZLIB;HAVE_XAUDIO;HAVE_RPNG;HAVE_RJPEG;HAVE_THREADS;HAVE_FILTERS_BUILTIN Callcap $(SolutionDir)\..\..\deps\zlib;$(SolutionDir)\..\..\libretro-common\include;$(SolutionDir)\..\..\deps;$(SolutionDir)\..\..\deps\stb;$(SolutionDir)\..\..\;%(AdditionalIncludeDirectories) @@ -237,7 +237,7 @@ Size false MultiThreaded - NDEBUG;_XBOX;PROFILE;FASTCAP;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;HAVE_ZLIB;HAVE_RARCH_EXEC;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_CC_RESAMPLER;HAVE_D3D9;HAVE_D3D;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_ZLIB;HAVE_XUI;HAVE_MENU;HAVE_XAUDIO;HAVE_RPNG;HAVE_RJPEG;HAVE_THREADS;HAVE_FILTERS_BUILTIN + NDEBUG;_XBOX;PROFILE;FASTCAP;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;HAVE_ZLIB;HAVE_RARCH_EXEC;D3DCOMPILE_USEVOIDS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_HLSL;HAVE_CC_RESAMPLER;HAVE_D3D9;HAVE_D3D;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_ZLIB;HAVE_MENU;HAVE_XAUDIO;HAVE_RPNG;HAVE_RJPEG;HAVE_THREADS;HAVE_FILTERS_BUILTIN $(SolutionDir)\..\..\deps\zlib;$(SolutionDir)\..\..\libretro-common\include;$(SolutionDir)\..\..\deps;$(SolutionDir)\..\..\deps\stb;$(SolutionDir)\..\..\;%(AdditionalIncludeDirectories) @@ -279,7 +279,7 @@ false false MultiThreaded - NDEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE=1;HAVE_NETWORKING;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_EXEC;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_CC_RESAMPLER;HAVE_D3D9;HAVE_D3D;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_ZLIB;HAVE_XUI;HAVE_MENU;HAVE_XAUDIO;HAVE_RPNG;HAVE_RJPEG;HAVE_THREADS;HAVE_FILTERS_BUILTIN + NDEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE=1;HAVE_NETWORKING;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_EXEC;D3DCOMPILE_USEVOIDS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_HLSL;HAVE_CC_RESAMPLER;HAVE_D3D9;HAVE_D3D;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_ZLIB;HAVE_MENU;HAVE_XAUDIO;HAVE_RPNG;HAVE_RJPEG;HAVE_THREADS;HAVE_FILTERS_BUILTIN $(SolutionDir)\..\..\deps\zlib;$(SolutionDir)\..\..\libretro-common\include;$(SolutionDir)\..\..\deps;$(SolutionDir)\..\..\deps\stb;$(SolutionDir)\..\..\;%(AdditionalIncludeDirectories) @@ -321,7 +321,7 @@ false false MultiThreaded - NDEBUG;_XBOX;LTCG;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_XUI;HAVE_MENU;HAVE_NETWORKING;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_EXEC;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_CC_RESAMPLER;HAVE_D3D9;HAVE_D3D;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_ZLIB;HAVE_XAUDIO;HAVE_RPNG;HAVE_RJPEG;HAVE_THREADS;HAVE_FILTERS_BUILTIN + NDEBUG;_XBOX;LTCG;%(PreprocessorDefinitions);HAVE_XINPUT2;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_MENU;HAVE_NETWORKING;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_EXEC;D3DCOMPILE_USEVOIDS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_HLSL;HAVE_CC_RESAMPLER;HAVE_D3D9;HAVE_D3D;RARCH_INTERNAL;MSB_FIRST;_XBOX360;WANT_ZLIB;HAVE_XAUDIO;HAVE_RPNG;HAVE_RJPEG;HAVE_THREADS;HAVE_FILTERS_BUILTIN $(SolutionDir)\..\..\deps\zlib;$(SolutionDir)\..\..\libretro-common\include;$(SolutionDir)\..\..\deps;$(SolutionDir)\..\..\deps\stb;$(SolutionDir)\..\..\;%(AdditionalIncludeDirectories) diff --git a/pkg/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/pkg/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index 120cbb84aa..0da7a53238 100644 --- a/pkg/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/pkg/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -22,7 +22,7 @@ Optimization="3" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\..\..\libretro-common\include";"$(SolutionDir)\..\..\deps";"$(SolutionDir)\..\..\deps\stb";"$(SolutionDir)\..\..\libretro-common\include\compat\msvc";"$(SolutionDir)\msvc-71";"$(SolutionDir)\..\..\deps\zlib"" - PreprocessorDefinitions="_DEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" + PreprocessorDefinitions="_DEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" MinimalRebuild="TRUE" BasicRuntimeChecks="0" RuntimeLibrary="1" @@ -72,7 +72,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\..\..\libretro-common\include";"$(SolutionDir)\..\..\deps";"$(SolutionDir)\..\..\deps\stb";"$(SolutionDir)\..\..\libretro-common\include\compat\msvc";"$(SolutionDir)\msvc-71";"$(SolutionDir)\..\..\deps\zlib"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -127,7 +127,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\..\..\libretro-common\include";"$(SolutionDir)\..\..\deps";"$(SolutionDir)\..\..\deps\stb";"$(SolutionDir)\..\..\libretro-common\include\compat\msvc";"$(SolutionDir)\msvc-71";"$(SolutionDir)\..\..\deps\zlib"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;FASTCAP;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;FASTCAP;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -188,7 +188,7 @@ EnableFiberSafeOptimizations="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\..\..\libretro-common\include";"$(SolutionDir)\..\..\deps";"$(SolutionDir)\..\..\deps\stb";"$(SolutionDir)\..\..\libretro-common\include\compat\msvc";"$(SolutionDir)\msvc-71";"$(SolutionDir)\..\..\deps\zlib"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;HAVE_LANGEXTRA;inline=_inline;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;inline=_inline;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -241,7 +241,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\..\..\libretro-common\include";"$(SolutionDir)\..\..\deps";"$(SolutionDir)\..\..\deps\stb";"$(SolutionDir)\..\..\libretro-common\include\compat\msvc";"$(SolutionDir)\msvc-71";"$(SolutionDir)\..\..\deps\zlib"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;LTCG;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;LTCG;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -300,7 +300,7 @@ EnableFiberSafeOptimizations="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\..\..\libretro-common\include";"$(SolutionDir)\..\..\deps";"$(SolutionDir)\..\..\deps\stb";"$(SolutionDir)\..\..\libretro-common\include\compat\msvc";"$(SolutionDir)\msvc-71";"$(SolutionDir)\..\..\deps\zlib"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;HAVE_LANGEXTRA;inline=_inline;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;inline=_inline;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -353,7 +353,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\..\..\libretro-common\include";"$(SolutionDir)\..\..\deps";"$(SolutionDir)\..\..\deps\stb";"$(SolutionDir)\..\..\libretro-common\include\compat\msvc";"$(SolutionDir)\msvc-71";"$(SolutionDir)\..\..\deps\zlib"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;LTCG;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RGUI;HAVE_MENU;HAVE_OVERLAY;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;__STDC_CONSTANT_MACROS;HAVE_ZLIB;LTCG;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RARCH_EXEC;HAVE_DSOUND;HAVE_CC_RESAMPLER;HAVE_D3D;HAVE_D3D8;RARCH_INTERNAL;WANT_ZLIB;HAVE_THREADS;HAVE_RPNG;HAVE_FILTERS_BUILTIN" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" diff --git a/pkg/msvc/RetroArch-msvc2015.sln b/pkg/msvc/RetroArch-msvc2015.sln index 2ee30da985..a20ab722df 100644 --- a/pkg/msvc/RetroArch-msvc2015.sln +++ b/pkg/msvc/RetroArch-msvc2015.sln @@ -1,6 +1,8 @@  -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2015 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-msvc2015", "msvc-2015\RetroArch-msvc2015.vcxproj", "{27FF7CE1-4059-4AA1-8062-FD529560FA54}" EndProject Global @@ -17,16 +19,20 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|Win32.ActiveCfg = Debug Cg|Win32 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|Win32.Build.0 = Debug Cg|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|x64.ActiveCfg = Debug Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|x64.ActiveCfg = Debug Cg|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|x64.Build.0 = Debug Cg|x64 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.ActiveCfg = Debug|Win32 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.Build.0 = Debug|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|x64.ActiveCfg = Debug|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|x64.ActiveCfg = Debug|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|x64.Build.0 = Debug|x64 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|Win32.ActiveCfg = Release Cg|Win32 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|Win32.Build.0 = Release Cg|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|x64.ActiveCfg = Release Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|x64.ActiveCfg = Release Cg|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|x64.Build.0 = Release Cg|x64 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.ActiveCfg = Release|Win32 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.Build.0 = Release|Win32 - {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|x64.ActiveCfg = Release|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|x64.ActiveCfg = Release|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/pkg/msvc/RetroArch-msvc2017.sln b/pkg/msvc/RetroArch-msvc2017.sln index a6526f5447..e7871290e2 100644 --- a/pkg/msvc/RetroArch-msvc2017.sln +++ b/pkg/msvc/RetroArch-msvc2017.sln @@ -9,10 +9,18 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug Cg|x64 = Debug Cg|x64 Debug Cg|x86 = Debug Cg|x86 + Debug QT|x64 = Debug QT|x64 + Debug QT|x86 = Debug QT|x86 + Debug QT+CG|x64 = Debug QT+CG|x64 + Debug QT+CG|x86 = Debug QT+CG|x86 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release Cg|x64 = Release Cg|x64 Release Cg|x86 = Release Cg|x86 + Release QT|x64 = Release QT|x64 + Release QT|x86 = Release QT|x86 + Release QT+CG|x64 = Release QT+CG|x64 + Release QT+CG|x86 = Release QT+CG|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection @@ -21,6 +29,14 @@ Global {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|x64.Build.0 = Debug Cg|x64 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|x86.ActiveCfg = Debug Cg|Win32 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|x86.Build.0 = Debug Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug QT|x64.ActiveCfg = Debug QT|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug QT|x64.Build.0 = Debug QT|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug QT|x86.ActiveCfg = Debug QT|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug QT|x86.Build.0 = Debug QT|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug QT+CG|x64.ActiveCfg = Debug QT+CG|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug QT+CG|x64.Build.0 = Debug QT+CG|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug QT+CG|x86.ActiveCfg = Debug QT+CG|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug QT+CG|x86.Build.0 = Debug QT+CG|Win32 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|x64.ActiveCfg = Debug|x64 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|x64.Build.0 = Debug|x64 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|x86.ActiveCfg = Debug|Win32 @@ -29,6 +45,14 @@ Global {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|x64.Build.0 = Release Cg|x64 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|x86.ActiveCfg = Release Cg|Win32 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|x86.Build.0 = Release Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release QT|x64.ActiveCfg = Release QT|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release QT|x64.Build.0 = Release QT|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release QT|x86.ActiveCfg = Release QT|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release QT|x86.Build.0 = Release QT|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release QT+CG|x64.ActiveCfg = Release QT+CG|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release QT+CG|x64.Build.0 = Release QT+CG|x64 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release QT+CG|x86.ActiveCfg = Release QT+CG|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release QT+CG|x86.Build.0 = Release QT+CG|Win32 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|x64.ActiveCfg = Release|x64 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|x64.Build.0 = Release|x64 {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|x86.ActiveCfg = Release|Win32 @@ -37,4 +61,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C7897994-5FD9-4B08-93CB-5EF58C48CFC6} + EndGlobalSection EndGlobal diff --git a/pkg/msvc/msvc-2003/RetroArch-msvc2003.vcproj b/pkg/msvc/msvc-2003/RetroArch-msvc2003.vcproj index 443c10edce..3bcfe59ddf 100644 --- a/pkg/msvc/msvc-2003/RetroArch-msvc2003.vcproj +++ b/pkg/msvc/msvc-2003/RetroArch-msvc2003.vcproj @@ -21,7 +21,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories=""$(SolutionDir)\..\..\libretro-common\include";"$(SolutionDir)\..\..\libretro-common\include\compat\msvc";"$(SolutionDir)\..\..\deps";"$(SolutionDir)\..\..\deps\stb";"$(SolutionDir)\..\..\gfx\include"" - PreprocessorDefinitions="_WIN32;WINVER=0x0400;_WIN32_WINNT=0x0400;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;WANT_ZLIB;HAVE_DINPUT;HAVE_DSOUND;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_D3D;HAVE_D3D8;DEBUG;_DEBUG;__STDC_CONSTANT_MACROS" + PreprocessorDefinitions="_WIN32;WINVER=0x0400;_WIN32_WINNT=0x0400;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;WANT_ZLIB;HAVE_DINPUT;HAVE_DSOUND;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_D3D;HAVE_D3D8;DEBUG;_DEBUG;__STDC_CONSTANT_MACROS" MinimalRebuild="TRUE" BasicRuntimeChecks="3" RuntimeLibrary="5" @@ -70,7 +70,7 @@ - true + false $(DXSDK_DIR)Include;$(IncludePath) $(DXSDK_DIR)Lib\x86;$(LibraryPath) AllRules.ruleset @@ -121,7 +121,7 @@ - true + false $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) $(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(LibraryPath) AllRules.ruleset @@ -129,7 +129,7 @@ - true + false $(DXSDK_DIR)Include;$(IncludePath) $(DXSDK_DIR)Lib\x64;$(LibraryPath) AllRules.ruleset @@ -137,7 +137,7 @@ - true + false $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) $(DXSDK_DIR)Lib\x64;$(CG_LIB64_PATH);$(LibraryPath) AllRules.ruleset @@ -182,7 +182,7 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3DX;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3DX;HAVE_GLSL;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -202,7 +202,7 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3DX;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3DX;HAVE_CG;HAVE_GLSL;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -223,7 +223,7 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -243,7 +243,7 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -266,7 +266,7 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3DX;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3DX;HAVE_GLSL;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -292,7 +292,7 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3DX;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3DX;HAVE_CG;HAVE_GLSL;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -319,7 +319,7 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -345,7 +345,7 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_CHEEVOS;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -383,4 +383,4 @@ - + \ No newline at end of file diff --git a/pkg/msvc/msvc-2013/RetroArch-msvc2013.vcxproj b/pkg/msvc/msvc-2013/RetroArch-msvc2013.vcxproj index 2eca6af1a1..29d64e782f 100644 --- a/pkg/msvc/msvc-2013/RetroArch-msvc2013.vcxproj +++ b/pkg/msvc/msvc-2013/RetroArch-msvc2013.vcxproj @@ -84,8 +84,9 @@ Level3 Disabled - WIN32;WANT_GLSLANG;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_MENU;HAVE_SLANG;HAVE_GLSLANG;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_RGUI;HAVE_MATERIALUI;_DEBUG;_WINDOWS;HAVE_XAUDIO;HAVE_DSOUND;HAVE_DINPUT;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_OPENGL;HAVE_VULKAN;HAVE_GLSL;HAVE_THREADS;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_CHEEVOS;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) + WIN32;WANT_GLSLANG;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_MENU;HAVE_SLANG;HAVE_GLSLANG;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_RGUI;HAVE_MATERIALUI;_DEBUG;_WINDOWS;HAVE_XAUDIO;HAVE_DSOUND;HAVE_DINPUT;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_OPENGL;HAVE_VULKAN;HAVE_GLSL;HAVE_THREADS;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_CHEEVOS;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)\..\..\gfx\include\dxsdk;$(SolutionDir)\..\..\gfx\include;$(SolutionDir)\..\..\libretro-common\include;$(SolutionDir)\..\..\deps;$(SolutionDir)\..\..\deps\glslang;$(SolutionDir)\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + OldStyle Console @@ -99,8 +100,9 @@ Level3 Disabled - WIN32;WANT_GLSLANG;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_SPIRV_CROSS;HAVE_MENU;HAVE_SLANG;HAVE_GLSLANG;HAVE_UPDATE_ASSETS;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_RGUI;HAVE_MATERIALUI;_DEBUG;_WINDOWS;HAVE_XAUDIO;HAVE_DSOUND;HAVE_DINPUT;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_OPENGL;HAVE_VULKAN;HAVE_GLSL;HAVE_THREADS;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_CHEEVOS;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) + WIN32;WANT_GLSLANG;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_SPIRV_CROSS;HAVE_MENU;HAVE_SLANG;HAVE_GLSLANG;HAVE_UPDATE_ASSETS;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_RGUI;HAVE_MATERIALUI;_DEBUG;_WINDOWS;HAVE_XAUDIO;HAVE_DSOUND;HAVE_DINPUT;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_OPENGL;HAVE_VULKAN;HAVE_GLSL;HAVE_THREADS;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_CHEEVOS;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)\..\..\gfx\include\dxsdk;$(SolutionDir)\..\..\gfx\include;$(SolutionDir)\..\..\libretro-common\include;$(SolutionDir)\..\..\deps;$(SolutionDir)\..\..\deps\glslang;$(SolutionDir)\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + OldStyle Console @@ -116,8 +118,9 @@ MaxSpeed true true - WIN32;WANT_GLSLANG;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;HAVE_MENU;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_RGUI;HAVE_MATERIALUI;NDEBUG;_WINDOWS;HAVE_XAUDIO;HAVE_DSOUND;HAVE_DINPUT;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_OPENGL;HAVE_VULKAN;HAVE_GLSL;HAVE_THREADS;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_RJPEG;HAVE_RPNG;HAVE_ZLIB;WANT_ZLIB;HAVE_NETWORKING;HAVE_COMMAND;HAVE_NETWORK_CMD;HAVE_STDIN_CMD;HAVE_OVERLAY;HAVE_7ZIP;HAVE_LIBRETRODB;HAVE_STB_FONT;%(PreprocessorDefinitions) + WIN32;WANT_GLSLANG;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;HAVE_MENU;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_RGUI;HAVE_MATERIALUI;NDEBUG;_WINDOWS;HAVE_XAUDIO;HAVE_DSOUND;HAVE_DINPUT;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_OPENGL;HAVE_VULKAN;HAVE_GLSL;HAVE_THREADS;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_RJPEG;HAVE_RPNG;HAVE_ZLIB;WANT_ZLIB;HAVE_NETWORKING;HAVE_COMMAND;HAVE_NETWORK_CMD;HAVE_STDIN_CMD;HAVE_OVERLAY;HAVE_7ZIP;HAVE_LIBRETRODB;HAVE_STB_FONT;%(PreprocessorDefinitions) $(SolutionDir)\..\..\gfx\include\dxsdk;$(SolutionDir)\..\..\gfx\include;$(SolutionDir)\..\..\libretro-common\include;$(SolutionDir)\..\..\deps;$(SolutionDir)\..\..\deps\glslang;$(SolutionDir)\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + OldStyle Console @@ -135,8 +138,9 @@ MaxSpeed true true - WIN32;WANT_GLSLANG;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_SPIRV_CROSS;HAVE_MENU;HAVE_SLANG;HAVE_GLSLANG;HAVE_UPDATE_ASSETS;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_RGUI;HAVE_MATERIALUI;NDEBUG;_WINDOWS;HAVE_XAUDIO;HAVE_DSOUND;HAVE_DINPUT;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_OPENGL;HAVE_VULKAN;HAVE_GLSL;HAVE_THREADS;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_CHEEVOS;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) + WIN32;WANT_GLSLANG;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_SPIRV_CROSS;HAVE_MENU;HAVE_SLANG;HAVE_GLSLANG;HAVE_UPDATE_ASSETS;HAVE_XMB;HAVE_SHADERPIPELINE;HAVE_RGUI;HAVE_MATERIALUI;NDEBUG;_WINDOWS;HAVE_XAUDIO;HAVE_DSOUND;HAVE_DINPUT;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_OPENGL;HAVE_VULKAN;HAVE_GLSL;HAVE_THREADS;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_CHEEVOS;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)\..\..\gfx\include\dxsdk;$(SolutionDir)\..\..\gfx\include;$(SolutionDir)\..\..\libretro-common\include;$(SolutionDir)\..\..\deps;$(SolutionDir)\..\..\deps\glslang;$(SolutionDir)\..\..\deps\SPIRV-Cross;%(AdditionalIncludeDirectories) + OldStyle Console @@ -154,9 +158,14 @@ CompileAsC - + + /bigobj %(AdditionalOptions) + /bigobj %(AdditionalOptions) + /bigobj %(AdditionalOptions) + /bigobj %(AdditionalOptions) + - + \ No newline at end of file diff --git a/pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj b/pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj index f9f51b52a9..f58275b30d 100644 --- a/pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj +++ b/pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj @@ -190,12 +190,13 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\gfx\include\dxsdk;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast StreamingSIMDExtensions + OldStyle Console @@ -209,12 +210,13 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\gfx\include\dxsdk;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast StreamingSIMDExtensions + OldStyle Console @@ -229,13 +231,14 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\gfx\include\dxsdk;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp /bigobj Fast StreamingSIMDExtensions2 + OldStyle Console @@ -249,12 +252,13 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\gfx\include\dxsdk;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast StreamingSIMDExtensions2 + OldStyle Console @@ -271,13 +275,14 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\gfx\include\dxsdk;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast StreamingSIMDExtensions true + OldStyle Console @@ -295,13 +300,14 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\gfx\include\dxsdk;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast StreamingSIMDExtensions true + OldStyle Console @@ -320,13 +326,14 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\gfx\include\dxsdk;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast StreamingSIMDExtensions2 true + OldStyle Console @@ -344,13 +351,14 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_SLANG;HAVE_GLSLANG;WANT_GLSLANG;HAVE_VULKAN;HAVE_SPIRV_CROSS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\gfx\include\dxsdk;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast StreamingSIMDExtensions2 true + OldStyle Console diff --git a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj index 824877fbb4..4898855449 100644 --- a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj +++ b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj @@ -9,6 +9,22 @@ Debug Cg x64 + + Debug QT+CG + Win32 + + + Debug QT+CG + x64 + + + Debug QT + Win32 + + + Debug QT + x64 + Debug Win32 @@ -25,6 +41,22 @@ Release Cg x64 + + Release QT+CG + Win32 + + + Release QT+CG + x64 + + + Release QT + Win32 + + + Release QT + x64 + Release Win32 @@ -53,6 +85,18 @@ NotSet v141 + + Application + true + NotSet + v141 + + + Application + true + NotSet + v141 + Application true @@ -65,6 +109,18 @@ NotSet v141 + + Application + true + NotSet + v141 + + + Application + true + NotSet + v141 + Application false @@ -79,6 +135,20 @@ NotSet v141 + + Application + false + true + NotSet + v141 + + + Application + false + true + NotSet + v141 + Application false @@ -93,6 +163,20 @@ NotSet v141 + + Application + false + true + NotSet + v141 + + + Application + false + true + NotSet + v141 + @@ -102,24 +186,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + true @@ -137,6 +245,24 @@ + + true + $(CG_INC_PATH);$(IncludePath);$(DXSDK_DIR)Include;$(QtDirectory)\msvc2015\include\QtCore;$(QtDirectory)\msvc2015\include\QtWidgets;$(QtDirectory)\msvc2015\include\QtGui;$(QtDirectory)\msvc2015\include + $(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(QtDirectory)\msvc2015\lib;$(LibraryPath) + AllRules.ruleset + + + $(QtDirectory)\msvc2015\bin;$(ExecutablePath) + + + true + $(CG_INC_PATH);$(IncludePath);$(DXSDK_DIR)Include;$(QtDirectory)\msvc2015\include\QtCore;$(QtDirectory)\msvc2015\include\QtWidgets;$(QtDirectory)\msvc2015\include\QtGui;$(QtDirectory)\msvc2015\include + $(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(QtDirectory)\msvc2015\lib;$(LibraryPath) + AllRules.ruleset + + + $(QtDirectory)\msvc2015\bin;$(ExecutablePath) + true $(IncludePath);$(DXSDK_DIR)Include @@ -153,6 +279,24 @@ + + true + $(IncludePath);$(DXSDK_DIR)Include;$(QtDirectory)\msvc2017_64\include\QtCore;$(QtDirectory)\msvc2017_64\include\QtWidgets;$(QtDirectory)\msvc2017_64\include\QtGui;$(QtDirectory)\msvc2017_64\include\ + $(DXSDK_DIR)Lib\x64;$(QtDirectory)\msvc2017_64\lib;$(LibraryPath) + AllRules.ruleset + + + $(QtDirectory)\msvc2017_64\bin;$(ExecutablePath) + + + true + $(CG_INC_PATH);$(IncludePath);$(DXSDK_DIR)Include;$(QtDirectory)\msvc2017_64\include\QtCore;$(QtDirectory)\msvc2017_64\include\QtWidgets;$(QtDirectory)\msvc2017_64\include\QtGui;$(QtDirectory)\msvc2017_64\include\ + $(DXSDK_DIR)Lib\x64;$(CG_LIB64_PATH);$(QtDirectory)\msvc2017_64\lib;$(LibraryPath) + AllRules.ruleset + + + $(QtDirectory)\msvc2017_64\bin;$(ExecutablePath) + false $(IncludePath);$(DXSDK_DIR)Include @@ -169,6 +313,24 @@ + + false + $(CG_INC_PATH);$(IncludePath);$(DXSDK_DIR)Include;$(QtDirectory)\msvc2015\include\QtCore;$(QtDirectory)\msvc2015\include\QtWidgets;$(QtDirectory)\msvc2015\include\QtGui;$(QtDirectory)\msvc2015\include + $(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(QtDirectory)\msvc2015\lib;$(LibraryPath) + AllRules.ruleset + + + $(QtDirectory)\msvc2015\bin;$(ExecutablePath) + + + false + $(CG_INC_PATH);$(IncludePath);$(DXSDK_DIR)Include;$(QtDirectory)\msvc2015\include\QtCore;$(QtDirectory)\msvc2015\include\QtWidgets;$(QtDirectory)\msvc2015\include\QtGui;$(QtDirectory)\msvc2015\include + $(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(QtDirectory)\msvc2015\lib;$(LibraryPath) + AllRules.ruleset + + + $(QtDirectory)\msvc2015\bin;$(ExecutablePath) + false $(IncludePath);$(DXSDK_DIR)Include @@ -185,18 +347,37 @@ + + false + $(IncludePath);$(DXSDK_DIR)Include;$(QtDirectory)\msvc2017_64\include\QtCore;$(QtDirectory)\msvc2017_64\include\QtWidgets;$(QtDirectory)\msvc2017_64\include\QtGui;$(QtDirectory)\msvc2017_64\include\ + $(DXSDK_DIR)Lib\x64;$(QtDirectory)\msvc2017_64\lib;$(LibraryPath) + AllRules.ruleset + + + $(QtDirectory)\msvc2017_64\bin;$(ExecutablePath) + + + false + $(CG_INC_PATH);$(IncludePath);$(DXSDK_DIR)Include;$(QtDirectory)\msvc2017_64\include\QtCore;$(QtDirectory)\msvc2017_64\include\QtWidgets;$(QtDirectory)\msvc2017_64\include\QtGui;$(QtDirectory)\msvc2017_64\include\ + $(DXSDK_DIR)Lib\x64;$(CG_LIB64_PATH);$(QtDirectory)\msvc2017_64\lib;$(LibraryPath) + AllRules.ruleset + + + $(QtDirectory)\msvc2017_64\bin;$(ExecutablePath) + Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast StreamingSIMDExtensions + OldStyle Console @@ -210,12 +391,13 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast StreamingSIMDExtensions + OldStyle Console @@ -224,18 +406,61 @@ $(CG_LIB_PATH) + + + + + Level3 + Disabled + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + CompileAsCpp + Fast + StreamingSIMDExtensions + OldStyle + + + Console + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;qtmain.lib;Qt5Widgets.lib;Qt5Gui.lib;Qt5Core.lib;%(AdditionalDependencies) + $(CG_LIB_PATH) + + + + + + + Level3 + Disabled + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + CompileAsCpp + Fast + StreamingSIMDExtensions + OldStyle + + + Console + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;qtmain.lib;Qt5Widgets.lib;Qt5Gui.lib;Qt5Core.lib;%(AdditionalDependencies) + $(CG_LIB_PATH) + + Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast StreamingSIMDExtensions2 + OldStyle Console @@ -249,12 +474,13 @@ Level3 Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast StreamingSIMDExtensions2 + OldStyle Console @@ -263,6 +489,48 @@ $(CG_LIB64_PATH) + + + + + Level3 + Disabled + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + CompileAsCpp + Fast + StreamingSIMDExtensions2 + OldStyle + + + Console + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;qtmain.lib;Qt5Widgets.lib;Qt5Gui.lib;Qt5Core.lib;%(AdditionalDependencies) + $(CG_LIB64_PATH) + + + + + + + Level3 + Disabled + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + CompileAsCpp + Fast + StreamingSIMDExtensions2 + OldStyle + + + Console + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;qtmain.lib;Qt5Widgets.lib;Qt5Gui.lib;Qt5Core.lib;%(AdditionalDependencies) + $(CG_LIB64_PATH) + + Level3 @@ -271,13 +539,14 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast StreamingSIMDExtensions true + OldStyle Console @@ -295,13 +564,14 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast StreamingSIMDExtensions true + OldStyle Console @@ -312,6 +582,58 @@ $(CG_LIB_PATH) + + + Level3 + + + MaxSpeed + true + true + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreaded + CompileAsCpp + Fast + StreamingSIMDExtensions + true + OldStyle + + + Console + true + true + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;qtmain.lib;Qt5Widgets.lib;Qt5Gui.lib;Qt5Core.lib;%(AdditionalDependencies) + $(CG_LIB_PATH) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreaded + CompileAsCpp + Fast + StreamingSIMDExtensions + true + OldStyle + + + Console + true + true + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;qtmain.lib;Qt5Widgets.lib;Qt5Gui.lib;Qt5Core.lib;%(AdditionalDependencies) + $(CG_LIB_PATH) + + Level3 @@ -320,13 +642,14 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast StreamingSIMDExtensions2 true + OldStyle Console @@ -344,13 +667,14 @@ MaxSpeed true true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast StreamingSIMDExtensions2 true + OldStyle Console @@ -361,6 +685,58 @@ $(CG_LIB64_PATH) + + + Level3 + + + MaxSpeed + true + true + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreaded + CompileAsCpp + Fast + StreamingSIMDExtensions2 + true + OldStyle + + + Console + true + true + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;qtmain.lib;Qt5Widgets.lib;Qt5Gui.lib;Qt5Core.lib;%(AdditionalDependencies) + $(CG_LIB64_PATH) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreaded + CompileAsCpp + Fast + StreamingSIMDExtensions2 + true + OldStyle + + + Console + true + true + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;qtmain.lib;Qt5Widgets.lib;Qt5Gui.lib;Qt5Core.lib;%(AdditionalDependencies) + $(CG_LIB64_PATH) + + @@ -368,17 +744,168 @@ CompileAsC CompileAsC + CompileAsC + CompileAsC CompileAsC + CompileAsC + CompileAsC CompileAsC CompileAsC CompileAsC + CompileAsC + CompileAsC CompileAsC + CompileAsC + CompileAsC CompileAsC - + + /bigobj %(AdditionalOptions) + /bigobj %(AdditionalOptions) + /bigobj %(AdditionalOptions) + /bigobj %(AdditionalOptions) + + + true + true + false + false + true + false + false + true + true + true + false + false + true + false + false + true + + + true + true + false + false + true + false + false + true + true + true + false + false + true + false + false + true + + + + + false + false + false + false + false + false + false + false + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + false + false + true + true + true + true + true + true + true + true + + + false + false + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + false + false + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + false + false + false + false + false + false + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + false + false + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + moc.exe "%(FullPath)" > "$(ProjectDir)MetaObjects\moc_%(Filename).cpp" + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + QT: Generate $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + $(ProjectDir)MetaObjects\moc_%(Filename).cpp + false + false + true + true + true + true + true + true + true + true + - + \ No newline at end of file diff --git a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj.filters b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj.filters index cbf777b405..99b62e847d 100644 --- a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj.filters +++ b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj.filters @@ -7,6 +7,9 @@ {9fc175c7-a869-47cf-a0ce-5447d6015ce9} + + {e6159cab-0a32-493f-a119-a2f0fd0cc6ef} + @@ -18,5 +21,19 @@ griffin + + QT + + + QT + + + + + QT + + + QT + \ No newline at end of file diff --git a/pkg/msvc/msvc-2017/readme-build-qt.txt b/pkg/msvc/msvc-2017/readme-build-qt.txt new file mode 100644 index 0000000000..47f4fdf9a1 --- /dev/null +++ b/pkg/msvc/msvc-2017/readme-build-qt.txt @@ -0,0 +1,22 @@ +If you are using the MSVC 2017 project file, you must define the environment varaible QtDirectory. This should point to the directory with the version number. +For example: QtDirectory=C:\qt\5.10.1 + +Two ways to define the variable: + +Windows: + Control Panel > System + Click Advanced System Settings + Go to Advanced Tab + Click Environment Variables button + Create a new variable (either user or system is okay), name it QtDirectory, set the value to your QT directory. + Restart all instances of Visual Studio. You may have to close it, wait 15 seconds, then kill the process. +Visual Studio: + View > Other Windows > Property Manager + Open the x64 build configuration + Double click on Microsoft.Cpp.x64.user + Go to User Macros + Add a new macro, name it QtDirectory, and set the value to your QT directory. + Open the Win32 build configuration + Double click on Microsoft.Cpp.Win32.user + Go to User Macros + Add a new macro, name it QtDirectory, and set the value to your QT directory. diff --git a/pkg/wii/meta.xml b/pkg/wii/meta.xml index aa4c7cc2aa..85eb934150 100644 --- a/pkg/wii/meta.xml +++ b/pkg/wii/meta.xml @@ -4,7 +4,7 @@ RetroArch Libretro &version; - 2012-2017 + 2012-2018 The cross-platform entertainment system A port of RetroArch to the GameCube/Wii. diff --git a/playlist.c b/playlist.c index 91d8ed032b..fba39fee5f 100644 --- a/playlist.c +++ b/playlist.c @@ -52,6 +52,7 @@ struct content_playlist char *conf_path; struct playlist_entry *entries; }; +static playlist_t *playlist_cached = NULL; typedef int (playlist_sort_fun_t)( const struct playlist_entry *a, @@ -554,6 +555,29 @@ end: return true; } +void playlist_free_cached(void) +{ + playlist_free(playlist_cached); + playlist_cached = NULL; +} + +playlist_t *playlist_get_cached(void) +{ + if (playlist_cached) + return playlist_cached; + return NULL; +} + +bool playlist_init_cached(const char *path, size_t size) +{ + playlist_t *playlist = playlist_init(path, size); + if (!playlist) + return false; + + playlist_cached = playlist; + return true; +} + /** * playlist_init: * @path : Path to playlist contents file. diff --git a/playlist.h b/playlist.h index a130df23c8..d3e8ef1176 100644 --- a/playlist.h +++ b/playlist.h @@ -129,6 +129,12 @@ void playlist_write_file(playlist_t *playlist); void playlist_qsort(playlist_t *playlist); +void playlist_free_cached(void); + +playlist_t *playlist_get_cached(void); + +bool playlist_init_cached(const char *path, size_t size); + RETRO_END_DECLS #endif diff --git a/qb/config.comp.sh b/qb/config.comp.sh index 1ce76eeb14..cd894adfb6 100644 --- a/qb/config.comp.sh +++ b/qb/config.comp.sh @@ -1,6 +1,2 @@ USE_LANG_C="yes" - -# C++ compiler is optional in other platforms supported by ./configure -if [ "$OS" = 'Win32' ]; then - USE_LANG_CXX="yes" -fi +USE_LANG_CXX="yes" diff --git a/qb/config.libs.sh b/qb/config.libs.sh index e0c3382d5b..e36974ceef 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -210,7 +210,6 @@ if [ "$HAVE_NETWORKING" = 'yes' ]; then check_lib '' MINIUPNPC '-lminiupnpc' else die : 'Warning: All networking features have been disabled.' - HAVE_KEYMAPPER='no' HAVE_NETWORK_CMD='no' HAVE_NETWORKGAMEPAD='no' HAVE_CHEEVOS='no' @@ -271,6 +270,31 @@ check_val '' PULSE -lpulse check_val '' SDL -lSDL SDL check_val '' SDL2 -lSDL2 SDL2 +check_enabled QT 'Qt companion' + +if [ "$HAVE_QT" != 'no' ] && [ "$MOC_PATH" != 'none' ]; then + check_pkgconf QT5CORE Qt5Core 5.2 + check_pkgconf QT5GUI Qt5Gui 5.2 + check_pkgconf QT5WIDGETS Qt5Widgets 5.2 + #check_pkgconf QT5WEBENGINE Qt5WebEngine 5.4 + + check_val '' QT5CORE -lQt5Core QT5CORE + check_val '' QT5GUI -lQt5Gui QT5GUI + check_val '' QT5WIDGETS -lQt5Widgets QT5WIDGETS + #check_val '' QT5WEBENGINE -lQt5WebEngine QT5WEBENGINE + + if [ "$HAVE_QT5CORE" = "no" ] || [ "$HAVE_QT5GUI" = "no" ] || [ "$HAVE_QT5WIDGETS" = "no" ]; then + die : 'Notice: Not building Qt support, required libraries were not found.' + HAVE_QT=no + else + HAVE_QT=yes + fi + + #if [ "$HAVE_QT5WEBENGINE" = "no" ]; then + # die : 'Notice: Qt5WebEngine not found, disabling web browser support.' + #fi +fi + if [ "$HAVE_SDL2" = 'yes' ] && [ "$HAVE_SDL" = 'yes' ]; then die : 'Notice: SDL drivers will be replaced by SDL2 ones.' HAVE_SDL=no @@ -465,6 +489,8 @@ fi check_lib '' STRCASESTR "$CLIB" strcasestr check_lib '' MMAP "$CLIB" mmap +check_enabled VULKAN vulkan + if [ "$HAVE_VULKAN" != "no" ] && [ "$OS" = 'Win32' ]; then HAVE_VULKAN=yes else diff --git a/qb/config.params.sh b/qb/config.params.sh index a1be97d869..487bc003a5 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -11,6 +11,7 @@ HAVE_MATERIALUI=auto # MaterialUI menu HAVE_XMB=auto # XMB menu HAVE_ZARCH=no # Zarch menu HAVE_NUKLEAR=no # Nuklear menu +HAVE_RUNAHEAD=yes # Runahead support HAVE_OVERLAY=yes # Overlay support HAVE_DYNAMIC=yes # Dynamic loading of libretro library HAVE_SDL=auto # SDL support @@ -30,7 +31,6 @@ HAVE_SSA=auto # SSA/ASS for FFmpeg subtitle support HAVE_DYLIB=auto # Dynamic loading support HAVE_NETWORKING=auto # Networking features (recommended) HAVE_NETWORKGAMEPAD=auto # Networked game pad (plus baked-in core) -HAVE_KEYMAPPER=yes # Networked game pad (plus baked-in core) C89_NETWORKGAMEPAD=no HAVE_MINIUPNPC=auto # Mini UPnP client library (for NAT traversal) HAVE_BUILTINMINIUPNPC=yes # Bake in Mini UPnP client library (for NAT traversal) @@ -38,7 +38,7 @@ C89_BUILTINMINIUPNPC=no HAVE_D3D8=no # Direct3D 8 support HAVE_D3D9=yes # Direct3D 9 support C89_D3D9=no -HAVE_D3D10=no # Direct3D 10 support +HAVE_D3D10=yes # Direct3D 10 support C89_D3D10=no HAVE_D3D11=yes # Direct3D 11 support C89_D3D11=no @@ -92,17 +92,17 @@ HAVE_NEON=no # ARM NEON optimizations HAVE_SSE=no # x86 SSE optimizations (SSE, SSE2) HAVE_FLOATHARD=no # Force hard float ABI (for ARM) HAVE_FLOATSOFTFP=no # Force soft float ABI (for ARM) +HAVE_CHD=yes # Compile in chd support HAVE_7ZIP=yes # Compile in 7z support HAVE_FLAC=auto # Compile in flac support HAVE_BUILTINFLAC=yes # Bake in flac support -C89_BUILTINFLAC=no HAVE_UPDATE_ASSETS=yes # Disable downloading assets with online updater HAVE_PRESERVE_DYLIB=no # Enable dlclose() for Valgrind support HAVE_PARPORT=auto # Parallel port joypad support HAVE_IMAGEVIEWER=yes # Built-in image viewer support. HAVE_MMAP=auto # MMAP support -HAVE_QT=no # Qt companion support -HAVE_QT_WRAPPER=no # Qt wrapper support +HAVE_QT=auto # Qt companion support +C89_QT=no HAVE_XSHM=no # XShm video driver support HAVE_CHEEVOS=yes # Retro Achievements HAVE_SHADERPIPELINE=yes # Additional shader-based pipelines diff --git a/qb/qb.comp.sh b/qb/qb.comp.sh index 147715443d..902afac3c5 100644 --- a/qb/qb.comp.sh +++ b/qb/qb.comp.sh @@ -11,6 +11,7 @@ int main(void) { puts("Hai world!"); return 0; } EOF cc_works=0 +HAVE_CC=no if [ "$CC" ]; then "$CC" -o "$TEMP_EXE" "$TEMP_C" >/dev/null 2>&1 && cc_works=1 else @@ -29,6 +30,7 @@ rm -f -- "$TEMP_C" "$TEMP_EXE" cc_status='does not work' if [ "$cc_works" = '1' ]; then cc_status='works' + HAVE_CC='yes' elif [ -z "$CC" ]; then cc_status='not found' fi @@ -46,6 +48,7 @@ int main() { std::cout << "Hai guise" << std::endl; return 0; } EOF cxx_works=0 +HAVE_CXX=no if [ "$CXX" ]; then "$CXX" -o "$TEMP_EXE" "$TEMP_CXX" >/dev/null 2>&1 && cxx_works=1 else @@ -64,6 +67,7 @@ rm -f -- "$TEMP_CXX" "$TEMP_EXE" cxx_status='does not work' if [ "$cxx_works" = '1' ]; then cxx_status='works' + HAVE_CXX='yes' elif [ -z "$CXX" ]; then cxx_status='not found' fi @@ -71,7 +75,7 @@ fi echo "Checking for suitable working C++ compiler ... $CXX $cxx_status" if [ "$cxx_works" = '0' ] && [ "$USE_LANG_CXX" = 'yes' ]; then - die 1 'Error: Cannot proceed without a working C++ compiler.' + die : 'Warning: A working C++ compiler was not found, C++ features will be disabled.' fi if [ "$OS" = "Win32" ]; then @@ -83,6 +87,26 @@ if [ "$OS" = "Win32" ]; then echo "$echobuf ... $WINDRES" fi +if [ "$HAVE_QT" != "no" ]; then + echobuf="Checking for moc" + if [ -z "$MOC" ]; then + MOC_PATH="none" + for moc in moc-qt5 moc; do + MOC="$(exists "$moc")" || MOC="" + [ "${MOC}" ] && { + MOC_PATH="$MOC" + break + } + done + fi + + echo "$echobuf ... $MOC_PATH" + + if [ "$MOC_PATH" = "none" ]; then + die : 'Warning: moc not found, Qt companion support will be disabled.' + fi +fi + if [ -z "$PKG_CONF_PATH" ]; then PKG_CONF_PATH="none" for pkgconf in pkgconf pkg-config; do diff --git a/qb/qb.libs.sh b/qb/qb.libs.sh index 453de6a612..41b840e7cf 100644 --- a/qb/qb.libs.sh +++ b/qb/qb.libs.sh @@ -28,6 +28,18 @@ check_compiler() # $1 = language $2 = function in lib fi } +check_enabled() # $1 = HAVE_$1 $2 = lib +{ [ "$HAVE_CXX" != 'no' ] && return 0 + tmpval="$(eval "printf %s \"\$HAVE_$1\"")" + + if [ "$tmpval" != 'yes' ]; then + eval "HAVE_$1=no" + return 0 + fi + + die 1 "Forced to build with $2 support and the C++ compiler is disabled. Exiting ..." +} + check_lib() # $1 = language $2 = HAVE_$2 $3 = lib $4 = function in lib $5 = extralibs $6 = headers $7 = critical error message [checked only if non-empty] { tmpval="$(eval "printf %s \"\$HAVE_$2\"")" [ "$tmpval" = 'no' ] && return 0 @@ -222,10 +234,11 @@ create_config_make() printf %s\\n "Creating make config: $outfile" - { [ "$USE_LANG_C" = 'yes' ] && printf %s\\n "CC = $CC" "CFLAGS = $CFLAGS" - [ "$USE_LANG_CXX" = 'yes' ] && printf %s\\n "CXX = $CXX" "CXXFLAGS = $CXXFLAGS" + { [ "$HAVE_CC" = 'yes' ] && printf %s\\n "CC = $CC" "CFLAGS = $CFLAGS" + [ "$HAVE_CXX" = 'yes' ] && printf %s\\n "CXX = $CXX" "CXXFLAGS = $CXXFLAGS" printf %s\\n "WINDRES = $WINDRES" \ + "MOC = $MOC" \ "ASFLAGS = $ASFLAGS" \ "LDFLAGS = $LDFLAGS" \ "INCLUDE_DIRS = $INCLUDE_DIRS" \ diff --git a/qb/qb.params.sh b/qb/qb.params.sh index 8163c3c5c9..2a68f0605e 100644 --- a/qb/qb.params.sh +++ b/qb/qb.params.sh @@ -33,11 +33,12 @@ General environment variables: General options: EOF print_help_option "--prefix=PATH" "Install path prefix" - print_help_option "--global-config-dir=PATH" "System wide config file prefix" + print_help_option "--sysconfdir=PATH" "System wide config file prefix" print_help_option "--bindir=PATH" "Binary install directory" print_help_option "--datarootdir=PATH" "Read-only data install directory" print_help_option "--docdir=PATH" "Documentation install directory" print_help_option "--mandir=PATH" "Manpage install directory" + print_help_option "--global-config-dir=PATH" "System wide config file prefix (Deprecated)" print_help_option "--build=BUILD" "The build system (no-op)" print_help_option "--host=HOST" "Cross-compile with HOST-gcc instead of gcc" print_help_option "--help" "Show this help" @@ -87,7 +88,7 @@ parse_input() # Parse stuff :V while [ "$1" ]; do case "$1" in --prefix=*) PREFIX=${1##--prefix=};; - --global-config-dir=*) GLOBAL_CONFIG_DIR=${1##--global-config-dir=};; + --global-config-dir=*|--sysconfdir=*) GLOBAL_CONFIG_DIR="${1#*=}";; --bindir=*) BIN_DIR="${1#*=}";; --build=*) BUILD="${1#*=}";; --datarootdir=*) SHARE_DIR="${1#*=}";; diff --git a/retroarch.c b/retroarch.c index ed8ef60679..788ee318af 100644 --- a/retroarch.c +++ b/retroarch.c @@ -118,6 +118,10 @@ #include "command.h" +#ifdef HAVE_RUNAHEAD +#include "runahead/run_ahead.h" +#endif + #define _PSUPP(var, name, desc) printf(" %s:\n\t\t%s: %s\n", name, desc, _##var##_supp ? "yes" : "no") #define FAIL_CPU(simd_type) do { \ @@ -218,6 +222,7 @@ 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; @@ -234,7 +239,9 @@ static bool runloop_remaps_game_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; +#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; @@ -254,6 +261,13 @@ static retro_time_t frame_limit_last_time = 0.0; extern bool input_driver_flushing_input; +#ifdef HAVE_DYNAMIC +bool retroarch_core_set_on_cmdline(void) +{ + return core_set_on_cmdline; +} +#endif + #ifdef HAVE_THREADS void runloop_msg_queue_lock(void) { @@ -860,6 +874,11 @@ static void retroarch_parse_input_and_config(int argc, char *argv[]) { settings_t *settings = config_get_ptr(); + if (rarch_first_start) + { + core_set_on_cmdline = true; + } + path_clear(RARCH_PATH_CORE); strlcpy(settings->paths.directory_libretro, optarg, sizeof(settings->paths.directory_libretro)); @@ -872,6 +891,11 @@ static void retroarch_parse_input_and_config(int argc, char *argv[]) } else if (filestream_exists(optarg)) { + if (rarch_first_start) + { + core_set_on_cmdline = true; + } + rarch_ctl(RARCH_CTL_SET_LIBRETRO_PATH, optarg); retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_LIBRETRO, NULL); @@ -1348,11 +1372,18 @@ bool retroarch_main_init(int argc, char *argv[]) rarch_error_on_init = false; rarch_is_inited = true; + if (rarch_first_start) + rarch_first_start = false; + return true; error: command_event(CMD_EVENT_CORE_DEINIT, NULL); rarch_is_inited = false; + + if (rarch_first_start) + rarch_first_start = false; + return false; } @@ -1817,8 +1848,6 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) if (!idx) return false; core_option_manager_prev(runloop_core_options, *idx); - if (ui_companion_is_on_foreground()) - ui_companion_driver_notify_refresh(); } break; case RARCH_CTL_CORE_OPTION_NEXT: @@ -1827,8 +1856,6 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) if (!idx) return false; core_option_manager_next(runloop_core_options, *idx); - if (ui_companion_is_on_foreground()) - ui_companion_driver_notify_refresh(); } break; case RARCH_CTL_CORE_OPTIONS_GET: @@ -2318,13 +2345,8 @@ void runloop_msg_queue_push(const char *msg, msg_queue_push(runloop_msg_queue, msg_info.msg, msg_info.prio, msg_info.duration); - if (ui_companion_is_on_foreground()) - { - const ui_companion_driver_t *ui = ui_companion_get_ptr(); - if (ui->msg_queue_push) - ui->msg_queue_push(msg_info.msg, - msg_info.prio, msg_info.duration, msg_info.flush); - } + ui_companion_driver_msg_queue_push(msg_info.msg, + msg_info.prio, msg_info.duration, msg_info.flush); } #ifdef HAVE_THREADS @@ -2377,7 +2399,7 @@ bool runloop_msg_queue_pull(const char **ret) #ifdef HAVE_MENU static bool input_driver_toggle_button_combo( - unsigned mode, retro_bits_t* p_input) + unsigned mode, input_bits_t* p_input) { switch (mode) { @@ -2427,9 +2449,9 @@ static enum runloop_state runloop_check_state( bool input_nonblock_state, unsigned *sleep_ms) { - retro_bits_t current_input; + input_bits_t current_input; #ifdef HAVE_MENU - static retro_bits_t last_input = {{0}}; + static input_bits_t last_input = {{0}}; #endif static bool old_fs_toggle_pressed= false; static bool old_focus = true; @@ -2442,12 +2464,16 @@ static enum runloop_state runloop_check_state( #ifdef HAVE_MENU bool menu_driver_binding_state = menu_driver_is_binding_state(); bool menu_is_alive = menu_driver_is_alive(); +#endif + BIT256_CLEAR_ALL_PTR(¤t_input); + +#ifdef HAVE_MENU if (menu_is_alive && !(settings->bools.menu_unified_controls && !menu_input_dialog_get_display_kb())) - input_menu_keys_pressed(settings, ¤t_input); + input_menu_keys_pressed(settings, ¤t_input); else #endif - input_keys_pressed(settings, ¤t_input); + input_keys_pressed(settings, ¤t_input); #ifdef HAVE_MENU last_input = current_input; @@ -2595,15 +2621,16 @@ static enum runloop_state runloop_check_state( #ifdef HAVE_MENU if (menu_is_alive) { - static retro_bits_t old_input = {{0}}; + static input_bits_t old_input = {{0}}; menu_ctx_iterate_t iter; retro_ctx.poll_cb(); + { enum menu_action action; bool focused = false; - retro_bits_t trigger_input = current_input; + input_bits_t trigger_input = current_input; bits_clear_bits(trigger_input.data, old_input.data, ARRAY_SIZE(trigger_input.data)); @@ -2619,10 +2646,19 @@ static enum runloop_state runloop_check_state( rarch_menu_running_finished(); if (focused || !runloop_idle) + { + bool libretro_running = menu_display_libretro_running( + rarch_is_inited, + (current_core_type == CORE_TYPE_DUMMY)); + menu_driver_render(runloop_idle, rarch_is_inited, (current_core_type == CORE_TYPE_DUMMY) ) ; + if (settings->bools.audio_enable_menu && + !libretro_running) + audio_driver_menu_sample(); + } old_input = current_input; @@ -2641,7 +2677,6 @@ static enum runloop_state runloop_check_state( if (runloop_idle) return RUNLOOP_STATE_SLEEP; - /* Check game focus toggle */ { static bool old_pressed = false; @@ -2654,6 +2689,20 @@ static enum runloop_state runloop_check_state( old_pressed = pressed; } + /* Check UI companion toggle */ + { + static bool old_pressed = false; + bool pressed = BIT256_GET( + current_input, RARCH_UI_COMPANION_TOGGLE); + + if (pressed && !old_pressed) + { + command_event(CMD_EVENT_UI_COMPANION_TOGGLE, (void*)(intptr_t)0); + } + + old_pressed = pressed; + } + #ifdef HAVE_MENU /* Check menu toggle */ { @@ -2830,11 +2879,13 @@ static enum runloop_state runloop_check_state( if (new_button_state && !old_button_state) { - if (input_nonblock_state) { + if (input_nonblock_state) + { input_driver_unset_nonblock_state(); runloop_fastmotion = false; } - else { + else + { input_driver_set_nonblock_state(); runloop_fastmotion = true; } @@ -2842,11 +2893,13 @@ static enum runloop_state runloop_check_state( } else if (old_hold_button_state != new_hold_button_state) { - if (new_hold_button_state) { + if (new_hold_button_state) + { input_driver_set_nonblock_state(); runloop_fastmotion = true; } - else { + else + { input_driver_unset_nonblock_state(); runloop_fastmotion = false; } @@ -2948,7 +3001,9 @@ static enum runloop_state runloop_check_state( } /* Checks if slowmotion toggle/hold was being pressed and/or held. */ - +#ifdef HAVE_CHEEVOS + if (!settings->bools.cheevos_enable) +#endif { static bool old_slowmotion_button_state = false; static bool old_slowmotion_hold_button_state = false; @@ -2959,21 +3014,17 @@ static enum runloop_state runloop_check_state( if (new_slowmotion_button_state && !old_slowmotion_button_state) { - if (runloop_slowmotion) { + if (runloop_slowmotion) runloop_slowmotion = false; - } - else { + else runloop_slowmotion = true; - } } else if (old_slowmotion_hold_button_state != new_slowmotion_hold_button_state) { - if (new_slowmotion_hold_button_state) { + if (new_slowmotion_hold_button_state) runloop_slowmotion = true; - } - else { + else runloop_slowmotion = false; - } } if (runloop_slowmotion) @@ -3248,7 +3299,13 @@ int runloop_iterate(unsigned *sleep_ms) if ((settings->uints.video_frame_delay > 0) && !input_nonblock_state) retro_sleep(settings->uints.video_frame_delay); - core_run(); +#ifdef HAVE_RUNAHEAD + /* Run Ahead Feature replaces the call to core_run in this loop */ + if (settings->bools.run_ahead_enabled && settings->uints.run_ahead_frames > 0) + run_ahead(settings->uints.run_ahead_frames, settings->bools.run_ahead_secondary_instance); + else +#endif + core_run(); #ifdef HAVE_CHEEVOS if (runloop_check_cheevos()) diff --git a/retroarch.cfg b/retroarch.cfg index f4639e8031..b399933a2f 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -700,6 +700,7 @@ video_message_bgcolor_opacity = 1.0 # Type of thumbnail to display. 0 = none, 1 = snaps, 2 = titles, 3 = boxarts # menu_thumbnails = 0 +# menu_left_thumbnails = 0 # Wrap-around to beginning and/or end if boundary of list is reached horizontally or vertically. # menu_navigation_wraparound_enable = false @@ -719,7 +720,7 @@ video_message_bgcolor_opacity = 1.0 # Check for firmware requirement(s) before loading a content. # check_firmware_before_loading = "false" -#### UI +#### User Interface # Suspends the screensaver if set to true. Is a hint that does not necessarily have to be honored # by video driver. @@ -728,6 +729,12 @@ video_message_bgcolor_opacity = 1.0 # Start UI companion driver's interface on boot (if available). # ui_companion_start_on_boot = true +# Toggle companion UI on startup (currently only used to show the WIMP UI) +# ui_companion_toggle = false + +# Only init the WIMP UI for this session if this is enabled +# desktop_menu_enable = true + #### Camera # Override the default camera device the camera driver uses. This is driver dependant. diff --git a/retroarch.h b/retroarch.h index 63c37428f1..02abfae515 100644 --- a/retroarch.h +++ b/retroarch.h @@ -357,6 +357,10 @@ void runloop_msg_queue_lock(void); void runloop_msg_queue_unlock(void); #endif +#ifdef HAVE_DYNAMIC +bool retroarch_core_set_on_cmdline(void); +#endif + RETRO_END_DECLS #endif diff --git a/runahead/copy_load_info.c b/runahead/copy_load_info.c new file mode 100644 index 0000000000..de9f736b39 --- /dev/null +++ b/runahead/copy_load_info.c @@ -0,0 +1,263 @@ +#include +#include + +#include +#include + +#include "../core.h" +#include "mem_util.h" +#include "copy_load_info.h" + +retro_ctx_load_content_info_t *load_content_info; +enum rarch_core_type last_core_type; + +static void free_retro_game_info(struct retro_game_info *dest) +{ + if (!dest) + return; + FREE(dest->path); + FREE(dest->data); + FREE(dest->meta); +} + +static struct retro_game_info* clone_retro_game_info(const + struct retro_game_info *src) +{ + void *data = NULL; + struct retro_game_info *dest = NULL; + + if (!src) + return NULL; + + dest = (struct retro_game_info*)calloc(1, + sizeof(struct retro_game_info)); + if (!dest) + return NULL; + + dest->data = NULL; + dest->path = strcpy_alloc(src->path); + + if (src->size && src->data) + { + data = malloc(src->size); + + if (data) + { + memcpy(data, src->data, src->size); + dest->data = data; + } + } + + dest->size = src->size; + dest->meta = strcpy_alloc(src->meta); + + return dest; +} + +static void free_string_list(struct string_list *dest) +{ + unsigned i; + if (!dest) + return; + for (i = 0; i < dest->size; i++) + { + FREE(dest->elems[i].data); + } + + FREE(dest->elems); +} + +static struct string_list *string_list_clone( + const struct string_list *src) +{ + unsigned i; + struct string_list_elem *elems = NULL; + struct string_list *dest = (struct string_list*) + calloc(1, sizeof(struct string_list)); + + if (!dest) + return NULL; + + dest->size = src->size; + dest->cap = src->cap; + if (dest->cap < dest->size) + { + dest->cap = dest->size; + } + + elems = (struct string_list_elem*) + calloc(dest->cap, sizeof(struct string_list_elem)); + + if (!elems) + { + free(dest); + return NULL; + } + + dest->elems = elems; + + for (i = 0; i < src->size; i++) + { + dest->elems[i].data = strcpy_alloc(src->elems[i].data); + dest->elems[i].attr = src->elems[i].attr; + } + + return dest; +} + +#if 0 +/* for cloning the Special field, however, attempting + * to use this feature crashes retroarch */ +static void free_retro_subsystem_memory_info(struct + retro_subsystem_memory_info *dest) +{ + if (!dest) + return; + FREE(dest->extension); +} + +static void clone_retro_subsystem_memory_info(struct + retro_subsystem_memory_info* dest, + const struct retro_subsystem_memory_info *src) +{ + dest->extension = strcpy_alloc(src->extension); + dest->type = src->type; +} + +static void free_retro_subsystem_rom_info(struct + retro_subsystem_rom_info *dest) +{ + int i; + if (!dest) + return; + + FREE(dest->desc); + FREE(dest->valid_extensions); + + for (i = 0; i < dest->num_memory; i++) + free_retro_subsystem_memory_info((struct + retro_subsystem_memory_info*)&dest->memory[i]); + + FREE(dest->memory); +} + +static void clone_retro_subsystem_rom_info(struct + retro_subsystem_rom_info *dest, + const struct retro_subsystem_rom_info *src) +{ + int i; + retro_subsystem_memory_info *memory = NULL; + + dest->need_fullpath = src->need_fullpath; + dest->block_extract = src->block_extract; + dest->required = src->required; + dest->num_memory = src->num_memory; + dest->desc = strcpy_alloc(src->desc); + dest->valid_extensions = strcpy_alloc(src->valid_extensions); + + memory = (struct retro_subsystem_memory_info*)calloc(1, + dest->num_memory * sizeof(struct retro_subsystem_memory_info)); + + dest->memory = memory; + + for (i = 0; i < dest->num_memory; i++) + clone_retro_subsystem_memory_info(&memory[i], &src->memory[i]); +} + +static void free_retro_subsystem_info(struct retro_subsystem_info *dest) +{ + int i; + + if (!dest) + return; + + FREE(dest->desc); + FREE(dest->ident); + + for (i = 0; i < dest->num_roms; i++) + free_retro_subsystem_rom_info((struct + retro_subsystem_rom_info*)&dest->roms[i]); + + FREE(dest->roms); +} + +static retro_subsystem_info* clone_retro_subsystem_info(struct + const retro_subsystem_info *src) +{ + int i; + retro_subsystem_info *dest = NULL; + retro_subsystem_rom_info *roms = NULL; + + if (!src) + return NULL; + dest = (struct retro_subsystem_info*)calloc(1, + sizeof(struct retro_subsystem_info)); + dest->desc = strcpy_alloc(src->desc); + dest->ident = strcpy_alloc(src->ident); + dest->num_roms = src->num_roms; + dest->id = src->id; + roms = (struct retro_subsystem_rom_info*) + calloc(src->num_roms, sizeof(struct retro_subsystem_rom_info)); + dest->roms = roms; + + for (i = 0; i < src->num_roms; i++) + clone_retro_subsystem_rom_info(&roms[i], &src->roms[i]); + + return dest; +} +#endif + +static void free_retro_ctx_load_content_info(struct + retro_ctx_load_content_info *dest) +{ + if (!dest) + return; + + free_retro_game_info(dest->info); + free_string_list((struct string_list*)dest->content); + FREE(dest->info); + FREE(dest->content); + +#if 0 + free_retro_subsystem_info((retro_subsystem_info*)dest->special); + FREE(dest->special); +#endif +} + +static struct retro_ctx_load_content_info +*clone_retro_ctx_load_content_info( + const struct retro_ctx_load_content_info *src) +{ + struct retro_ctx_load_content_info *dest = NULL; + if (!src || src->special != NULL) + return NULL; /* refuse to deal with the Special field */ + + dest = (struct retro_ctx_load_content_info*) + calloc(1, sizeof(*dest)); + + if (!dest) + return NULL; + + dest->info = clone_retro_game_info(src->info); + dest->content = NULL; + dest->special = NULL; + + if (src->content) + dest->content = string_list_clone(src->content); +#if 0 + dest->special = clone_retro_subsystem_info(src->special); +#endif + return dest; +} + +void set_load_content_info(const retro_ctx_load_content_info_t *ctx) +{ + free_retro_ctx_load_content_info(load_content_info); + free(load_content_info); + load_content_info = clone_retro_ctx_load_content_info(ctx); +} + +void set_last_core_type(enum rarch_core_type type) +{ + last_core_type = type; +} diff --git a/runahead/copy_load_info.h b/runahead/copy_load_info.h new file mode 100644 index 0000000000..fced73a2d6 --- /dev/null +++ b/runahead/copy_load_info.h @@ -0,0 +1,19 @@ +#ifndef __COPY_LOAD_INFO_H__ +#define __COPY_LOAD_INFO_H__ + +#include +#include + +#include + +#include "../core.h" + +RETRO_BEGIN_DECLS + +void set_load_content_info(const retro_ctx_load_content_info_t *ctx); + +void set_last_core_type(enum rarch_core_type type); + +RETRO_END_DECLS + +#endif diff --git a/runahead/dirty_input.c b/runahead/dirty_input.c new file mode 100644 index 0000000000..5c2086a53a --- /dev/null +++ b/runahead/dirty_input.c @@ -0,0 +1,176 @@ +#include + +#include + +#include "../core.h" +#include "../dynamic.h" + +#include "mylist.h" +#include "mem_util.h" +#include "dirty_input.h" + +bool input_is_dirty = false; +static MyList *input_state_list = NULL; + +typedef struct InputListElement_t +{ + unsigned port; + unsigned device; + unsigned index; + int16_t state[36]; +} InputListElement; + +extern struct retro_core_t current_core; +extern struct retro_callbacks retro_ctx; + +typedef bool(*LoadStateFunction)(const void*, size_t); + +static function_t retro_reset_callback_original = NULL; +static LoadStateFunction retro_unserialize_callback_original = NULL; +static retro_input_state_t input_state_callback_original; + +static void reset_hook(void); +static bool unserialze_hook(const void *buf, size_t size); + +static void* InputListElementConstructor(void) +{ + const int size = sizeof(InputListElement); + void *ptr = calloc(1, size); + + return ptr; +} + +static void input_state_destory(void) +{ + mylist_destroy(&input_state_list); +} + +static void input_state_set_last(unsigned port, unsigned device, + unsigned index, unsigned id, int16_t value) +{ + unsigned i; + InputListElement *element = NULL; + + if (!input_state_list) + mylist_create(&input_state_list, 16, + InputListElementConstructor, free); + + /* find list item */ + for (i = 0; i < (unsigned)input_state_list->size; i++) + { + element = (InputListElement*)input_state_list->data[i]; + if ( element->port == port + && element->device == device && element->index == index) + { + element->state[id] = value; + return; + } + } + + element = (InputListElement*) + mylist_add_element(input_state_list); + element->port = port; + element->device = device; + element->index = index; + element->state[id] = value; +} + +static int16_t input_state_get_last(unsigned port, + unsigned device, unsigned index, unsigned id) +{ + unsigned i; + + if (!input_state_list) + return 0; + + /* find list item */ + for (i = 0; i < (unsigned)input_state_list->size; i++) + { + InputListElement *element = + (InputListElement*)input_state_list->data[i]; + + if ( (element->port == port) && + (element->device == device) && + (element->index == index) + ) + return element->state[id]; + } + return 0; +} + +static int16_t input_state_with_logging(unsigned port, + unsigned device, unsigned index, unsigned id) +{ + if (input_state_callback_original) + { + int16_t result = input_state_callback_original( + port, device, index, id); + int16_t last_input = input_state_get_last(port, device, index, id); + if (result != last_input) + input_is_dirty = true; + input_state_set_last(port, device, index, id, result); + return result; + } + return 0; +} + +static void reset_hook(void) +{ + input_is_dirty = true; + if (retro_reset_callback_original) + retro_reset_callback_original(); +} + +static bool unserialze_hook(const void *buf, size_t size) +{ + input_is_dirty = true; + if (retro_unserialize_callback_original) + return retro_unserialize_callback_original(buf, size); + return false; +} + +void add_input_state_hook(void) +{ + if (!input_state_callback_original) + { + input_state_callback_original = retro_ctx.state_cb; + retro_ctx.state_cb = input_state_with_logging; + current_core.retro_set_input_state(retro_ctx.state_cb); + } + + if (!retro_reset_callback_original) + { + retro_reset_callback_original = current_core.retro_reset; + current_core.retro_reset = reset_hook; + } + + if (!retro_unserialize_callback_original) + { + retro_unserialize_callback_original = current_core.retro_unserialize; + current_core.retro_unserialize = unserialze_hook; + } +} + +void remove_input_state_hook(void) +{ + if (input_state_callback_original) + { + retro_ctx.state_cb = input_state_callback_original; + current_core.retro_set_input_state(retro_ctx.state_cb); + input_state_callback_original = NULL; + input_state_destory(); + } + + if (retro_reset_callback_original) + { + current_core.retro_reset = retro_reset_callback_original; + retro_reset_callback_original = NULL; + } + + if (retro_unserialize_callback_original) + { + current_core.retro_unserialize = retro_unserialize_callback_original; + retro_unserialize_callback_original = NULL; + } +} + diff --git a/runahead/dirty_input.h b/runahead/dirty_input.h new file mode 100644 index 0000000000..12623d2b02 --- /dev/null +++ b/runahead/dirty_input.h @@ -0,0 +1,15 @@ +#ifndef __DIRTY_INPUT_H___ +#define __DIRTY_INPUT_H___ + +#include "retro_common_api.h" +#include "boolean.h" + +RETRO_BEGIN_DECLS + +extern bool input_is_dirty; +void add_input_state_hook(void); +void remove_input_state_hook(void); + +RETRO_END_DECLS + +#endif diff --git a/runahead/mem_util.c b/runahead/mem_util.c new file mode 100644 index 0000000000..d04e3097d9 --- /dev/null +++ b/runahead/mem_util.c @@ -0,0 +1,50 @@ +#include + +#include "mem_util.h" + +char *strcpy_alloc(const char *sourceStr) +{ + size_t len = 0; + char *result = NULL; + + if (sourceStr) + len = strlen(sourceStr); + + if (len == 0) + return NULL; + + result = (char*)malloc(len + 1); + strcpy(result, sourceStr); + return result; +} + +char *strcpy_alloc_force(const char *sourceStr) +{ + char *result = strcpy_alloc(sourceStr); + if (!result) + result = (char*)calloc(1, 1); + return result; +} + +void strcat_alloc(char ** destStr_p, const char *appendStr) +{ + size_t len1, len2, newLen; + char *destStr = *destStr_p; + + if (!destStr) + { + destStr = strcpy_alloc_force(appendStr); + *destStr_p = destStr; + return; + } + + if (!appendStr) + return; + + len1 = strlen(destStr); + len2 = strlen(appendStr); + newLen = len1 + len2 + 1; + destStr = (char*)realloc(destStr, newLen); + *destStr_p = destStr; + strcpy(destStr + len1, appendStr); +} diff --git a/runahead/mem_util.h b/runahead/mem_util.h new file mode 100644 index 0000000000..4ddbe21521 --- /dev/null +++ b/runahead/mem_util.h @@ -0,0 +1,21 @@ +#ifndef __MEM_UTIL__ +#define __MEM_UTIL__ + +#include +#include + +#include + +#include + +#define FREE(xxxx) if ((xxxx) != NULL) { free((void*)(xxxx)); } (xxxx) = NULL + +RETRO_BEGIN_DECLS + +char *strcpy_alloc(const char *sourceStr); +char *strcpy_alloc_force(const char *sourceStr); +void strcat_alloc(char ** destStr_p, const char *appendStr); + +RETRO_END_DECLS + +#endif diff --git a/runahead/mylist.c b/runahead/mylist.c new file mode 100644 index 0000000000..11b3f3d6b4 --- /dev/null +++ b/runahead/mylist.c @@ -0,0 +1,162 @@ +#include +#include + +#include "mylist.h" +#include "mem_util.h" + +void mylist_resize(MyList *list, int newSize, bool runConstructor) +{ + int newCapacity; + int oldSize; + int i; + void *element = NULL; + if (newSize < 0) + newSize = 0; + if (!list) + return; + newCapacity = newSize; + oldSize = list->size; + + if (newSize == oldSize) + return; + + if (newSize > list->capacity) + { + if (newCapacity < list->capacity * 2) + newCapacity = list->capacity * 2; + + /* try to realloc */ + list->data = (void**)realloc((void*)list->data, newCapacity * sizeof(void*)); + + for (i = list->capacity; i < newCapacity; i++) + list->data[i] = NULL; + + list->capacity = newCapacity; + } + if (newSize <= list->size) + { + for (i = newSize; i < list->size; i++) + { + element = list->data[i]; + + if (element) + { + list->Destructor(element); + list->data[i] = NULL; + } + } + } + else + { + for (i = list->size; i < newSize; i++) + { + if (runConstructor) + list->data[i] = list->Constructor(); + else + list->data[i] = NULL; + } + } + list->size = newSize; +} + +void *mylist_add_element(MyList *list) +{ + int oldSize; + + if (!list) + return NULL; + + oldSize = list->size; + mylist_resize(list, oldSize + 1, true); + return list->data[oldSize]; +} + +void mylist_create(MyList **list_p, int initialCapacity, + constructor_t constructor, destructor_t destructor) +{ + MyList *list = NULL; + if (!list_p) + return; + if (initialCapacity < 0) + initialCapacity = 0; + list = *list_p; + if (list) + mylist_destroy(list_p); + + list = (MyList*)malloc(sizeof(MyList)); + *list_p = list; + list->size = 0; + list->Constructor = constructor; + list->Destructor = destructor; + + if (initialCapacity > 0) + { + list->data = (void**)calloc(initialCapacity, sizeof(void*)); + list->capacity = initialCapacity; + } + else + { + list->data = NULL; + list->capacity = 0; + } +} + +void mylist_destroy(MyList **list_p) +{ + MyList *list = NULL; + if (!list_p) + return; + + list = *list_p; + + if (list) + { + mylist_resize(list, 0, false); + free(list->data); + free(list); + *list_p = NULL; + } +} + +void mylist_assign(MyList *list, int index, void *value) +{ + void *oldElement = NULL; + + if (index < 0 || index >= list->size) + return; + + oldElement = list->data[index]; + list->Destructor(oldElement); + list->data[index] = value; +} + +void mylist_remove_at(MyList *list, int index) +{ + int i; + + if (index < 0 || index >= list->size) + return; + + mylist_assign(list, index, NULL); + + for (i = index + 1; i < list->size; i++) + list->data[i - 1] = list->data[i]; + + list->size--; + list->data[list->size] = NULL; +} + +void mylist_pop_front(MyList *list) +{ + mylist_remove_at(list, 0); +} + +void mylist_push_back(MyList *list, void *value) +{ + int oldSize; + if (!list) + return; + oldSize = list->size; + mylist_resize(list, oldSize + 1, false); + list->data[oldSize] = value; +} diff --git a/runahead/mylist.h b/runahead/mylist.h new file mode 100644 index 0000000000..1ec3e9c325 --- /dev/null +++ b/runahead/mylist.h @@ -0,0 +1,40 @@ +#ifndef __MYLIST_H__ +#define __MYLIST_H__ + +#include +#include +#include + +RETRO_BEGIN_DECLS + +typedef void* (*constructor_t)(void); +typedef void(*destructor_t)(void*); + +typedef struct MyList_t +{ + void **data; + int capacity; + int size; + constructor_t Constructor; + destructor_t Destructor; +} MyList; + +void *mylist_add_element(MyList *list); + +void mylist_resize(MyList *list, int newSize, bool runConstructor); + +void mylist_create(MyList **list_p, int initialCapacity, + constructor_t constructor, destructor_t destructor); + +void mylist_destroy(MyList **list_p); + +void mylist_assign(MyList *list, int index, void *value); + +void mylist_remove_at(MyList *list, int index); + +void mylist_pop_front(MyList *list); + +RETRO_END_DECLS + +#endif + diff --git a/runahead/run_ahead.c b/runahead/run_ahead.c new file mode 100644 index 0000000000..71122ce6e6 --- /dev/null +++ b/runahead/run_ahead.c @@ -0,0 +1,494 @@ +#include +#include +#include + +#include + +#include "dirty_input.h" +#include "mylist.h" +#include "secondary_core.h" +#include "run_ahead.h" + +#include "../core.h" +#include "../dynamic.h" +#include "../audio/audio_driver.h" +#include "../gfx/video_driver.h" + +static bool runahead_create(void); +static bool runahead_save_state(void); +static bool runahead_load_state(void); +static bool runahead_load_state_secondary(void); +static bool runahead_run_secondary(void); +static void runahead_suspend_audio(void); +static void runahead_resume_audio(void); +static void runahead_suspend_video(void); +static void runahead_resume_video(void); +static void set_fast_savestate(void); +static void unset_fast_savestate(void); +static void set_hard_disable_audio(void); +static void unset_hard_disable_audio(void); + +/* TODO/FIXME - shouldn't this be signed size_t? */ +static size_t runahead_save_state_size = -1; + +/* Save State List for Run Ahead */ +static MyList *runahead_save_state_list; + +static void *runahead_save_state_alloc(void) +{ + retro_ctx_serialize_info_t *savestate = (retro_ctx_serialize_info_t*) + malloc(sizeof(retro_ctx_serialize_info_t)); + + if (!savestate) + return NULL; + + savestate->data = NULL; + savestate->data_const = NULL; + savestate->size = 0; + + if (runahead_save_state_size > 0 && runahead_save_state_size != -1) + { + savestate->data = malloc(runahead_save_state_size); + savestate->data_const = savestate->data; + savestate->size = runahead_save_state_size; + } + + return savestate; +} + +static void runahead_save_state_free(void *state) +{ + retro_ctx_serialize_info_t *savestate = (retro_ctx_serialize_info_t*)state; + if (!savestate) + return; + free(savestate->data); + free(savestate); +} + +static void runahead_save_state_list_init(size_t saveStateSize) +{ + runahead_save_state_size = saveStateSize; + mylist_create(&runahead_save_state_list, 16, + runahead_save_state_alloc, runahead_save_state_free); +} + +static void runahead_save_state_list_destroy(void) +{ + mylist_destroy(&runahead_save_state_list); +} + +#if 0 +static void runahead_save_state_list_rotate(void) +{ + int i; + void *element; + void *firstElement; + firstElement = runahead_save_state_list->data[0]; + for (i = 1; i < runahead_save_state_list->size; i++) + runahead_save_state_list->data[i - 1] = + runahead_save_state_list->data[i]; + runahead_save_state_list->data[runahead_save_state_list->size - 1] = + firstElement; +} +#endif + +/* Hooks - Hooks to cleanup, and add dirty input hooks */ + +static function_t originalRetroDeinit = NULL; +static function_t originalRetroUnload = NULL; + +extern struct retro_core_t current_core; +extern struct retro_callbacks retro_ctx; + +static void remove_hooks(void) +{ + if (originalRetroDeinit) + { + current_core.retro_deinit = originalRetroDeinit; + originalRetroDeinit = NULL; + } + + if (originalRetroUnload) + { + current_core.retro_unload_game = originalRetroUnload; + originalRetroUnload = NULL; + } + current_core.retro_set_environment(rarch_environment_cb); + remove_input_state_hook(); +} + +static void unload_hook(void) +{ + remove_hooks(); + runahead_destroy(); + secondary_core_destroy(); + if (current_core.retro_unload_game) + current_core.retro_unload_game(); +} + + +static void deinit_hook(void) +{ + remove_hooks(); + runahead_destroy(); + secondary_core_destroy(); + if (current_core.retro_deinit) + current_core.retro_deinit(); +} + +static bool env_hook(unsigned cmd, void *data) +{ + bool result = rarch_environment_cb(cmd, data); + if (cmd == RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE && result) + { + bool *bool_p = (bool*)data; + if (*bool_p == true) + secondary_core_set_variable_update(); + } + return result; +} + +static void add_hooks(void) +{ + if (!originalRetroDeinit) + { + originalRetroDeinit = current_core.retro_deinit; + current_core.retro_deinit = deinit_hook; + } + + if (!originalRetroUnload) + { + originalRetroUnload = current_core.retro_unload_game; + current_core.retro_unload_game = unload_hook; + } + current_core.retro_set_environment(env_hook); + add_input_state_hook(); +} + + +/* Runahead Code */ + +static bool runahead_video_driver_is_active = true; +static bool runahead_available = true; +static bool runahead_secondary_core_available = true; +static bool runahead_force_input_dirty = true; +static uint64_t runahead_last_frame_count = 0; + +static void runahead_clear_variables(void) +{ + runahead_save_state_size = -1; + runahead_video_driver_is_active = true; + runahead_available = true; + runahead_secondary_core_available = true; + runahead_force_input_dirty = true; + runahead_last_frame_count = 0; +} + +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); + + if (frame_count != runahead_last_frame_count + 1) + runahead_force_input_dirty = true; + + runahead_last_frame_count = frame_count; +} + +void run_ahead(int runahead_count, bool useSecondary) +{ + int frame_number = 0; + bool last_frame = false; + bool suspended_frame = false; +#if defined(HAVE_DYNAMIC) || defined(HAVE_DYLIB) + const bool have_dynamic = true; +#else + const bool have_dynamic = false; +#endif + + if (runahead_count <= 0 || !runahead_available) + { + core_run(); + runahead_force_input_dirty = true; + return; + } + + if (runahead_save_state_size == -1) + { + if (!runahead_create()) + { + /* RunAhead has been disabled because the core + * does not support savestates. */ + core_run(); + runahead_force_input_dirty = true; + return; + } + } + + runahead_check_for_gui(); + + if (!useSecondary || !have_dynamic || !runahead_secondary_core_available) + { + /* TODO: multiple savestates for higher performance + * when not using secondary core */ + for (frame_number = 0; frame_number <= runahead_count; frame_number++) + { + last_frame = frame_number == runahead_count; + suspended_frame = !last_frame; + + if (suspended_frame) + { + runahead_suspend_audio(); + runahead_suspend_video(); + } + + if (frame_number == 0) + core_run(); + else + core_run_no_input_polling(); + + if (suspended_frame) + { + runahead_resume_video(); + runahead_resume_audio(); + } + + if (frame_number == 0) + { + /* RunAhead has been disabled due + * to save state failure */ + if (!runahead_save_state()) + return; + } + + if (last_frame) + { + /* RunAhead has been disabled due + * to load state failure */ + if (!runahead_load_state()) + return; + } + } + } + else + { +#if HAVE_DYNAMIC + bool okay = false; + + /* run main core with video suspended */ + runahead_suspend_video(); + core_run(); + runahead_resume_video(); + + if (input_is_dirty || runahead_force_input_dirty) + { + unsigned frame_count; + + input_is_dirty = false; + + if (!runahead_save_state()) + return; + + /* Could not create a secondary core. + * RunAhead wll only use the main core now. */ + if (!runahead_load_state_secondary()) + return; + + for (frame_count = 0; frame_count < + (unsigned)(runahead_count - 1); frame_count++) + { + runahead_suspend_video(); + runahead_suspend_audio(); + set_hard_disable_audio(); + okay = runahead_run_secondary(); + unset_hard_disable_audio(); + runahead_resume_audio(); + runahead_resume_video(); + + /* Could not create a secondary core. RunAhead + * will only use the main core now. */ + if (!okay) + return; + } + } + runahead_suspend_audio(); + set_hard_disable_audio(); + okay = runahead_run_secondary(); + unset_hard_disable_audio(); + runahead_resume_audio(); + + /* Could not create a secondary core. RunAhead + * will only use the main core now. */ + if (!okay) + return; +#endif + } + runahead_force_input_dirty = false; +} + +static void runahead_error(void) +{ + runahead_available = false; + runahead_save_state_list_destroy(); + remove_hooks(); + runahead_save_state_size = 0; +} + +static bool runahead_create(void) +{ + /* get savestate size and allocate buffer */ + retro_ctx_size_info_t info; + core_serialize_size(&info); + + runahead_save_state_list_init(info.size); + runahead_video_driver_is_active = video_driver_is_active(); + + if (runahead_save_state_size == 0 || runahead_save_state_size == -1) + { + runahead_error(); + return false; + } + + add_hooks(); + runahead_force_input_dirty = true; + mylist_resize(runahead_save_state_list, 1, true); + return true; +} + +static bool runahead_save_state(void) +{ + bool okay = false; + retro_ctx_serialize_info_t *serialize_info; + if (!runahead_save_state_list) + return false; + serialize_info = + (retro_ctx_serialize_info_t*)runahead_save_state_list->data[0]; + set_fast_savestate(); + okay = core_serialize(serialize_info); + unset_fast_savestate(); + if (!okay) + { + runahead_error(); + return false; + } + return true; +} + +static bool runahead_load_state(void) +{ + bool okay = false; + retro_ctx_serialize_info_t *serialize_info = (retro_ctx_serialize_info_t*) + runahead_save_state_list->data[0]; + bool last_dirty = input_is_dirty; + + set_fast_savestate(); + /* calling core_unserialize has side effects with + * netplay (it triggers transmitting your save state) + call retro_unserialize directly from the core instead */ + okay = current_core.retro_unserialize( + serialize_info->data_const, serialize_info->size); + unset_fast_savestate(); + input_is_dirty = last_dirty; + + if (!okay) + runahead_error(); + + return okay; +} + +static bool runahead_load_state_secondary(void) +{ + bool okay = false; + retro_ctx_serialize_info_t *serialize_info = + (retro_ctx_serialize_info_t*)runahead_save_state_list->data[0]; + + set_fast_savestate(); + okay = secondary_core_deserialize( + serialize_info->data_const, (int)serialize_info->size); + unset_fast_savestate(); + + if (!okay) + { + runahead_secondary_core_available = false; + return false; + } + + return true; +} + +static bool runahead_run_secondary(void) +{ + if (!secondary_core_run_no_input_polling()) + { + runahead_secondary_core_available = false; + return false; + } + return true; +} + +static void runahead_suspend_audio(void) +{ + audio_driver_suspend(); +} + +static void runahead_resume_audio(void) +{ + audio_driver_resume(); +} + +static void runahead_suspend_video(void) +{ + video_driver_unset_active(); +} + +static void runahead_resume_video(void) +{ + if (runahead_video_driver_is_active) + video_driver_set_active(); + else + video_driver_unset_active(); +} + +void runahead_destroy(void) +{ + runahead_save_state_list_destroy(); + remove_hooks(); + runahead_clear_variables(); +} + +static bool request_fast_savestate; +static bool hard_disable_audio; + + +bool want_fast_savestate(void) +{ + return request_fast_savestate; +} + +static void set_fast_savestate(void) +{ + request_fast_savestate = true; +} + +static void unset_fast_savestate(void) +{ + request_fast_savestate = false; +} + +bool get_hard_disable_audio(void) +{ + return hard_disable_audio; +} + +static void set_hard_disable_audio(void) +{ + hard_disable_audio = true; +} + +static void unset_hard_disable_audio(void) +{ + hard_disable_audio = false; +} diff --git a/runahead/run_ahead.h b/runahead/run_ahead.h new file mode 100644 index 0000000000..8868ce345b --- /dev/null +++ b/runahead/run_ahead.h @@ -0,0 +1,20 @@ +#ifndef __RUN_AHEAD_H__ +#define __RUN_AHEAD_H__ + +#include +#include + +#include + +RETRO_BEGIN_DECLS + +void runahead_destroy(void); + +void run_ahead(int runAheadCount, bool useSecondary); + +bool want_fast_savestate(void); +bool get_hard_disable_audio(void); + +RETRO_END_DECLS + +#endif diff --git a/runahead/secondary_core.c b/runahead/secondary_core.c new file mode 100644 index 0000000000..016f53ca2e --- /dev/null +++ b/runahead/secondary_core.c @@ -0,0 +1,384 @@ +#if defined(HAVE_DYNAMIC) || defined(HAVE_DYLIB) + +#include +#include + +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX) +#ifndef LEGACY_WIN32 +#define LEGACY_WIN32 +#endif +#endif + +#include +#include +#include +#include +#include + +#include "mem_util.h" + +#include "../core.h" +#include "../dynamic.h" +#include "../paths.h" +#include "../content.h" + +#include "secondary_core.h" + +static int port_map[16]; + +static char *secondary_library_path; +static dylib_t secondary_module; +static struct retro_core_t secondary_core; +static struct retro_callbacks secondary_callbacks; + +extern retro_ctx_load_content_info_t *load_content_info; +extern enum rarch_core_type last_core_type; +extern struct retro_callbacks retro_ctx; + +static char* get_temp_directory_alloc(void); + +static char* copy_core_to_temp_file(void); + +static bool write_file_with_random_name(char **tempDllPath, + const char *retroarchTempPath, const void* data, ssize_t dataSize); + +static bool secondary_core_create(void); + +bool secondary_core_run_no_input_polling(void); + +bool secondary_core_deserialize(const void *buffer, int size); + +static bool rarch_environment_secondary_core_hook(unsigned cmd, void *data); + +void secondary_core_destroy(void); + +void set_last_core_type(enum rarch_core_type type); + +void remember_controller_port_device(long port, long device); + +void clear_controller_port_map(void); + +char* get_temp_directory_alloc(void) +{ +#ifdef _WIN32 +#ifdef LEGACY_WIN32 + DWORD pathLength = GetTempPath(0, NULL) + 1; + char *path = (char*)malloc(pathLength * sizeof(char)); + + path[pathLength - 1] = 0; + GetTempPath(pathLength, path); + return path; +#else + char *path; + DWORD pathLength = GetTempPathW(0, NULL) + 1; + wchar_t *wideStr = (wchar_t*)malloc(pathLength * sizeof(wchar_t)); + wideStr[pathLength - 1] = 0; + GetTempPathW(pathLength, wideStr); + + path = utf16_to_utf8_string_alloc(wideStr); + free(wideStr); + return path; +#endif +#else + char *path = strcpy_alloc_force(getenv("TMPDIR")); + return path; +#endif +} + +char* copy_core_to_temp_file(void) +{ + char *tempDirectory = NULL; + char *retroarchTempPath = NULL; + char *tempDllPath = NULL; + void *dllFileData = NULL; + int64_t dllFileSize = 0; + const char *corePath = path_get(RARCH_PATH_CORE); + const char *coreBaseName = path_basename(corePath); + + if (strlen(coreBaseName) == 0) + goto failed; + + tempDirectory = get_temp_directory_alloc(); + if (!tempDirectory) + goto failed; + + strcat_alloc(&retroarchTempPath, tempDirectory); + strcat_alloc(&retroarchTempPath, path_default_slash()); + strcat_alloc(&retroarchTempPath, "retroarch_temp"); + strcat_alloc(&retroarchTempPath, path_default_slash()); + + if (!path_mkdir(retroarchTempPath)) + goto failed; + + if (!filestream_read_file(corePath, &dllFileData, &dllFileSize)) + goto failed; + + strcat_alloc(&tempDllPath, retroarchTempPath); + strcat_alloc(&tempDllPath, coreBaseName); + + if (!filestream_write_file(tempDllPath, dllFileData, dllFileSize)) + { + /* try other file names */ + if (!write_file_with_random_name(&tempDllPath, retroarchTempPath, dllFileData, dllFileSize)) + goto failed; + } + + FREE(tempDirectory); + FREE(retroarchTempPath); + FREE(dllFileData); + return tempDllPath; + +failed: + FREE(tempDirectory); + FREE(retroarchTempPath); + FREE(tempDllPath); + FREE(dllFileData); + return NULL; +} + +bool write_file_with_random_name(char **tempDllPath, + const char *retroarchTempPath, const void* data, ssize_t dataSize) +{ + bool okay = false; + unsigned i; + char number_buf[32]; + const char *prefix = "tmp"; + time_t time_value = time(NULL); + unsigned int number_value= (unsigned int)time_value; + int number = 0; + char *ext = strcpy_alloc_force(path_get_extension(*tempDllPath)); + int ext_len = (int)strlen(ext); + + if (ext_len > 0) + { + strcat_alloc(&ext, "."); + memmove(ext + 1, ext, ext_len); + ext[0] = '.'; + ext_len++; + } + + /* Try up to 30 'random' filenames before giving up */ + for (i = 0; i < 30; i++) + { + number_value = number_value * 214013 + 2531011; + number = (number_value >> 14) % 100000; + + snprintf(number_buf, sizeof(number_buf), "%05d", number); + + FREE(*tempDllPath); + strcat_alloc(tempDllPath, retroarchTempPath); + strcat_alloc(tempDllPath, prefix); + strcat_alloc(tempDllPath, number_buf); + strcat_alloc(tempDllPath, ext); + if (filestream_write_file(*tempDllPath, data, dataSize)) + { + okay = true; + break; + } + } + + FREE(ext); + return okay; +} + +bool secondary_core_create(void) +{ + long port, device; + bool contentless, is_inited; + + if ( last_core_type != CORE_TYPE_PLAIN || + !load_content_info || + load_content_info->special) + return false; + + FREE(secondary_library_path); + secondary_library_path = copy_core_to_temp_file(); + + if (!secondary_library_path) + return false; + + /* Load Core */ + if (init_libretro_sym_custom(CORE_TYPE_PLAIN, &secondary_core, secondary_library_path, &secondary_module)) + { + secondary_core.symbols_inited = true; + secondary_core.retro_set_environment(rarch_environment_secondary_core_hook); + secondary_core_set_variable_update(); + + secondary_core.retro_init(); + + content_get_status(&contentless, &is_inited); + secondary_core.inited = is_inited; + + /* Load Content */ + if (!load_content_info || load_content_info->special) + { + /* disabled due to crashes */ + return false; +#if 0 + secondary_core.game_loaded = secondary_core.retro_load_game_special( + loadContentInfo.special->id, loadContentInfo.info, loadContentInfo.content->size); + if (!secondary_core.game_loaded) + { + secondary_core_destroy(); + return false; + } +#endif + } + else if (load_content_info->content->size > 0 && load_content_info->content->elems[0].data) + { + secondary_core.game_loaded = secondary_core.retro_load_game(load_content_info->info); + if (!secondary_core.game_loaded) + { + secondary_core_destroy(); + return false; + } + } + else if (contentless) + { + secondary_core.game_loaded = secondary_core.retro_load_game(NULL); + if (!secondary_core.game_loaded) + { + secondary_core_destroy(); + return false; + } + } + else + { + secondary_core.game_loaded = false; + } + if (!secondary_core.inited) + { + secondary_core_destroy(); + return false; + } + + core_set_default_callbacks(&secondary_callbacks); + secondary_core.retro_set_video_refresh(secondary_callbacks.frame_cb); + secondary_core.retro_set_audio_sample(secondary_callbacks.sample_cb); + secondary_core.retro_set_audio_sample_batch(secondary_callbacks.sample_batch_cb); + secondary_core.retro_set_input_state(secondary_callbacks.state_cb); + secondary_core.retro_set_input_poll(secondary_callbacks.poll_cb); + + for (port = 0; port < 16; port++) + { + device = port_map[port]; + if (device >= 0) + secondary_core.retro_set_controller_port_device((unsigned)port, (unsigned)device); + } + clear_controller_port_map(); + } + else + return false; + + return true; +} + +static bool has_variable_update; + +static bool rarch_environment_secondary_core_hook(unsigned cmd, void *data) +{ + bool result = rarch_environment_cb(cmd, data); + if (cmd == RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE && has_variable_update) + { + bool *bool_p = (bool*)data; + *bool_p = true; + has_variable_update = false; + return true; + } + return result; +} + +void secondary_core_set_variable_update(void) +{ + has_variable_update = true; +} + +bool secondary_core_run_no_input_polling(void) +{ + if (!secondary_module) + { + if (!secondary_core_create()) + return false; + } + secondary_core.retro_run(); + return true; +} + +bool secondary_core_deserialize(const void *buffer, int size) +{ + if (!secondary_module) + { + if (!secondary_core_create()) + { + secondary_core_destroy(); + return false; + } + } + return secondary_core.retro_unserialize(buffer, size); +} + +void secondary_core_destroy(void) +{ + if (secondary_module) + { + /* unload game from core */ + if (secondary_core.retro_unload_game) + secondary_core.retro_unload_game(); + /* deinit */ + if (secondary_core.retro_deinit) + secondary_core.retro_deinit(); + memset(&secondary_core, 0, sizeof(struct retro_core_t)); + + dylib_close(secondary_module); + secondary_module = NULL; + filestream_delete(secondary_library_path); + FREE(secondary_library_path); + } +} + +void remember_controller_port_device(long port, long device) +{ + if (port >= 0 && port < 16) + port_map[port] = (int)device; + if (secondary_module && secondary_core.retro_set_controller_port_device) + secondary_core.retro_set_controller_port_device((unsigned)port, (unsigned)device); +} + +void clear_controller_port_map(void) +{ + unsigned port; + for (port = 0; port < 16; port++) + port_map[port] = -1; +} + +#else +#include + +#include "../core.h" + +bool secondary_core_run_no_input_polling(void) +{ + return false; +} +bool secondary_core_deserialize(const void *buffer, int size) +{ + return false; +} +void secondary_core_destroy(void) +{ + /* do nothing */ +} +void remember_controller_port_device(long port, long device) +{ + /* do nothing */ +} +void secondary_core_set_variable_update(void) +{ + /* do nothing */ +} +void clear_controller_port_map(void) +{ + /* do nothing */ +} +#endif + diff --git a/runahead/secondary_core.h b/runahead/secondary_core.h new file mode 100644 index 0000000000..9eb4190d09 --- /dev/null +++ b/runahead/secondary_core.h @@ -0,0 +1,23 @@ +#ifndef __SECONDARY_CORE_H__ +#define __SECONDARY_CORE_H__ + +#include +#include + +#include + +#include "../core_type.h" + +RETRO_BEGIN_DECLS + +bool secondary_core_run_no_input_polling(void); +bool secondary_core_deserialize(const void *buffer, int size); +void secondary_core_destroy(void); +void set_last_core_type(enum rarch_core_type type); +void remember_controller_port_device(long port, long device); +void clear_controller_port_map(void); +void secondary_core_set_variable_update(void); + +RETRO_END_DECLS + +#endif diff --git a/samples/tasks/database/Makefile b/samples/tasks/database/Makefile new file mode 100644 index 0000000000..d526f03358 --- /dev/null +++ b/samples/tasks/database/Makefile @@ -0,0 +1,136 @@ +compiler := gcc +extra_flags := +use_neon := 0 +release := release +EXE_EXT := +TARGET := database_task + +ifeq ($(platform),) +platform = unix +ifeq ($(shell uname -a),) + platform = win +else ifneq ($(findstring MINGW,$(shell uname -a)),) + platform = win +else ifneq ($(findstring Darwin,$(shell uname -a)),) + platform = osx + arch = intel +ifeq ($(shell uname -p),powerpc) + arch = ppc +endif +else ifneq ($(findstring win,$(shell uname -a)),) + platform = win +endif +endif + +ifeq ($(compiler),gcc) +extra_rules_gcc := $(shell $(compiler) -dumpmachine) +endif + +ifneq (,$(findstring armv7,$(extra_rules_gcc))) +extra_flags += -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=neon +use_neon := 1 +endif + +ifneq (,$(findstring hardfloat,$(extra_rules_gcc))) +extra_flags += -mfloat-abi=hard +endif + +ifeq (release,$(build)) +extra_flags += -O2 +endif + +ifeq (debug,$(build)) +extra_flags += -O0 -g +endif + +ldflags := + +EXE_EXT := +ifeq ($(platform), unix) +else ifeq ($(platform), osx) +compiler := $(CC) +else +EXE_EXT = .exe +endif + +CORE_DIR = ../../.. +LIBRETRO_COMM_DIR = $(CORE_DIR)/libretro-common + +CC := $(compiler) +CXX := $(subst CC,++,$(compiler)) +flags := -I$(LIBRETRO_COMM_DIR)/include +asflags := $(extra_flags) +LDFLAGS := +flags += -std=c99 +INCFLAGS := -I$(LIBRETRO_COMM_DIR)/include + +SOURCES_C := \ + $(CORE_DIR)/samples/tasks/database/main.c \ + $(CORE_DIR)/tasks/task_database.c \ + $(CORE_DIR)/tasks/task_database_cue.c \ + $(CORE_DIR)/database_info.c \ + $(CORE_DIR)/core_info.c \ + $(CORE_DIR)/file_path_str.c \ + $(CORE_DIR)/msg_hash.c \ + $(CORE_DIR)/intl/msg_hash_us.c \ + $(CORE_DIR)/playlist.c \ + $(CORE_DIR)/verbosity.c \ + $(CORE_DIR)/libretro-db/bintree.c \ + $(CORE_DIR)/libretro-db/libretrodb.c \ + $(CORE_DIR)/libretro-db/query.c \ + $(CORE_DIR)/libretro-db/rmsgpack.c \ + $(CORE_DIR)/libretro-db/rmsgpack_dom.c \ + $(LIBRETRO_COMM_DIR)/file/archive_file.c \ + $(LIBRETRO_COMM_DIR)/file/config_file.c \ + $(LIBRETRO_COMM_DIR)/file/file_path.c \ + $(LIBRETRO_COMM_DIR)/file/retro_dirent.c \ + $(LIBRETRO_COMM_DIR)/hash/rhash.c \ + $(LIBRETRO_COMM_DIR)/compat/compat_fnmatch.c \ + $(LIBRETRO_COMM_DIR)/compat/compat_posix_string.c \ + $(LIBRETRO_COMM_DIR)/compat/compat_strcasestr.c \ + $(LIBRETRO_COMM_DIR)/compat/compat_strl.c \ + $(LIBRETRO_COMM_DIR)/compat/fopen_utf8.c \ + $(LIBRETRO_COMM_DIR)/encodings/encoding_crc32.c \ + $(LIBRETRO_COMM_DIR)/encodings/encoding_utf.c \ + $(LIBRETRO_COMM_DIR)/queues/task_queue.c \ + $(LIBRETRO_COMM_DIR)/lists/dir_list.c \ + $(LIBRETRO_COMM_DIR)/lists/string_list.c \ + $(LIBRETRO_COMM_DIR)/streams/interface_stream.c \ + $(LIBRETRO_COMM_DIR)/streams/memory_stream.c \ + $(LIBRETRO_COMM_DIR)/streams/file_stream.c \ + $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c + +DEFINES = -DHAVE_LIBRETRODB -DHAVE_COMPRESSION + +CFLAGS += $(DEFINES) +CXXFLAGS += $(DEFINES) + +OBJECTS = $(SOURCES_C:.c=.o) + +OBJOUT = -o +LINKOUT = -o + +ifneq (,$(findstring msvc,$(platform))) + OBJOUT = -Fo +LINKOUT = -out: +ifeq ($(STATIC_LINKING),1) + LD ?= lib.exe +else + LD = link.exe +endif +else + LD = $(CC) +endif + +all: $(TARGET)$(EXE_EXT) +$(TARGET)$(EXE_EXT): $(OBJECTS) + $(LD) $(LINKOUT)$@ $(SHARED) $(OBJECTS) $(LDFLAGS) $(LIBS) + +%.o: %.c + $(CC) $(INCFLAGS) $(CFLAGS) -c $(OBJOUT)$@ $< + +%.o: %.cpp + $(CXX) $(INCFLAGS) $(CXXFLAGS) -c $(OBJOUT)$@ $< + +clean: + rm -f $(OBJECTS) diff --git a/samples/tasks/database/main.c b/samples/tasks/database/main.c new file mode 100644 index 0000000000..49b6274a3e --- /dev/null +++ b/samples/tasks/database/main.c @@ -0,0 +1,81 @@ +#include +#include +#include + +#include + +#include "../../../core_info.h" +#include "../../../tasks/tasks_internal.h" + +static bool loop_active = true; + +static void main_msg_queue_push(const char *msg, + unsigned prio, unsigned duration, + bool flush) +{ + fprintf(stderr, "MSGQ: %s\n", msg); +} + +/* + * return codes - + * graceful exit: 1 + * normal exit: 0 + * error exit: -1 + */ + +static void main_db_cb(void *task_data, void *user_data, const char *err) +{ + fprintf(stderr, "DB CB: %s\n", err); + loop_active = false; +} + +int main(int argc, char *argv[]) +{ + const char *db_dir = NULL; + const char *core_info_dir = NULL; + const char *core_dir = NULL; + const char *input_dir = NULL; + const char *playlist_dir = NULL; +#if defined(_WIN32) + const char *exts = "dll"; +#elif defined(__MACH__) + const char *exts = "dylib"; +#else + const char *exts = "so"; +#endif + + if (argc < 6) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + db_dir = argv[1]; + core_dir = argv[2]; + core_info_dir = argv[3]; + input_dir = argv[4]; + playlist_dir = argv[5]; + + fprintf(stderr, "RDB database dir: %s\n", db_dir); + fprintf(stderr, "Core dir: %s\n", core_dir); + fprintf(stderr, "Core info dir: %s\n", core_info_dir); + fprintf(stderr, "Input dir: %s\n", input_dir); + fprintf(stderr, "Playlist dir: %s\n", playlist_dir); + + task_queue_init(false /* threaded enable */, main_msg_queue_push); + + core_info_init_list(core_info_dir, core_dir, exts, true); + + task_push_dbscan(playlist_dir, db_dir, input_dir, true, + true, main_db_cb); + + while (loop_active) + task_queue_check(); + + fprintf(stderr, "Exit loop\n"); + + core_info_deinit_list(); + task_queue_deinit(); + + return 0; +} diff --git a/tasks/task_audio_mixer.c b/tasks/task_audio_mixer.c index f0b95dfadb..833412fd78 100644 --- a/tasks/task_audio_mixer.c +++ b/tasks/task_audio_mixer.c @@ -21,6 +21,7 @@ #include #include +#include #include