diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index ce940e7878..0863b5b89b 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,6 +1,6 @@ # These are supported funding model platforms -github: [twinaphex] +github: [libretro] patreon: libretro open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username diff --git a/.gitignore b/.gitignore index eafc1d0862..1a132fbd29 100644 --- a/.gitignore +++ b/.gitignore @@ -174,7 +174,7 @@ retroarch_switch.nso # PS2 ps2/irx/*.c -ps2/libcdvd/lib/ +*.irx # Wayland gfx/common/wayland/idle-inhibit-unstable-v1.c diff --git a/.travis.yml b/.travis.yml index b1f11c8c56..5af82f59d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,12 +40,16 @@ matrix: env: CXX_BUILD=1 CC=gcc-8 CXX=g++-8 - compiler: gcc env: DISABLE_MENU=1 CC=gcc-8 CXX=g++-8 + - compiler: gcc + env: DISABLE_NETWORKING=1 CC=gcc-8 CXX=g++-8 - compiler: gcc env: DISABLE_OVERLAY=1 CC=gcc-8 CXX=g++-8 - compiler: gcc env: DISABLE_CDROM=1 CC=gcc-8 CXX=g++-8 - compiler: gcc env: DISABLE_VIDEO_LAYOUT=1 CC=gcc-8 CXX=g++-8 + - compiler: gcc + env: DISABLE_THREADS=1 CC=gcc-8 CXX=g++-8 - compiler: gcc env: DISABLE_AUDIOMIXER=1 CC=gcc-8 CXX=g++-8 - compiler: gcc @@ -105,6 +109,10 @@ matrix: - cd pkg/android/phoenix - ./gradlew assembleNormalRelease +jobs: + allow_failure: + - os: osx + before_install: - | if [[ "$CC" =~ ^gcc-8.* ]]; then @@ -132,6 +140,10 @@ before_script: if [ -n "$DISABLE_OVERLAY" ]; then ARGS="$ARGS --disable-overlay" fi + - | + if [ -n "$DISABLE_NETWORKING" ]; then + ARGS="$ARGS --disable-networking" + fi - | if [ -n "$DISABLE_CDROM" ]; then ARGS="$ARGS --disable-cdrom" @@ -140,6 +152,10 @@ before_script: if [ -n "$DISABLE_VIDEO_LAYOUT" ]; then ARGS="$ARGS --disable-video_layout" fi + - | + if [ -n "$DISABLE_THREADS" ]; then + ARGS="$ARGS --disable-threads --disable-glslang" + fi - | if [ -n "$DISABLE_AUDIOMIXER" ]; then ARGS="$ARGS --disable-audiomixer" diff --git a/.vscode/settings.json b/.vscode/settings.json index 56db7a117f..2dc110ece3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,15 +1,15 @@ { - "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe", + "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe", "terminal.integrated.env.windows": { "PATH": "/mingw64/lib/ccache/bin:/mingw64/lib/ccache/bin:/mingw64/lib/ccache/bin:/mingw64/bin:/usr/local/bin:/usr/bin:/bin:$PATH", "MSYSTEM": "MINGW64", }, "terminal.integrated.cursorBlinking": true, - "editor.tabSize": 3, "editor.detectIndentation": false, "editor.renderWhitespace": "all", "editor.insertSpaces": true, + "editor.formatOnSave": false, "files.associations": { "frontend_driver.h": "c", "*.in": "c", diff --git a/CHANGES.md b/CHANGES.md index 3cb3c3a60b..153d3486b0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,9 +1,208 @@ # Future + +# 1.8.9 +- AUTO SAVESTATES: Ensure save states are correctly flushed to disk when quitting RetroArch (fixes broken save states when exiting RetroArch - without first closing content - with 'Auto Save State' enabled) +- BUILTIN CORES: Builtin cores like ffmpeg and imageviewer would previously try to erroneously load a dynamic core named 'builtin' - this would fail and would just be a wasteful operation - this now skips dylib loading in libretro_get_system_info for builtin cores +- CHEEVOS: Report API errors when unlocking achievements or submitting leaderboards +- CHEEVOS: Support less common file extensions +- CHEEVOS: Disable hardcore mode when playing BSV file +- CHEEVOS: Correctly report unlocked non-hardcore achievements when hardcore is paused +- CHEEVOS/M3U: Bugfix - did not handle absolute/relative paths in M3U files correctly before +- CHEEVOS/M3U: Bugfix - it didn't handle comments/directives +- CHEEVOS/M3U: Bugfix - it doesn't handle trailing whitespace +- CHEEVOS/M3U: Bugfix - failed when loading M3U files with certain line endings +- CORE MANAGEMENT: Add 'core management' menu (Settings -> Core) +- CORE MANAGEMENT: Add option to backup/restore installed cores +- CORE MANAGEMENT: Improved core selection logic +- CORE INFO: Search search optimisations +- CORE DOWNLOADER: Rename 'Core Updater' to 'Core Downloader' +- CORE DOWNLOADER: Add 'Show Experimental Cores' setting under Settings > Network > Updater +- CORE DOWNLOADER: Core licenses are now shown for all entries in the Core Updater menu +- CORE DOWNLOADER: Pressing RetroPad select on a Core Updater entry will now display any text in the description field of its info file +- CORE DOWNLOADER: Installed cores are now highlighted via a [#] symbol +- CORE DOWNLOADER: Pressing RetroPad start on a selected, installed entry opens the Core Information menu (when using Material UI, swiping left or right triggers the same action). This means we can now view bios info etc. - and more importantly delete cores - without jumping through all the hoops of loading a core first and navigating all over the place +- CORE DOWNLOADER/UPDATER: Add option to automatically backup cores when updating +- DISK CONTROL: Enable 'Load New Disc' while disk tray is open +- INPUT: Added a hotkey delay option to allow hotkey input to work properly when it is assigned to another action +- INPUT: Remove 'All Users Control Menu' setting, was buggy and will be properly reintroduced after input overhaul +- LINUX: Set default saves/save states/system paths +- LOCALIZATION: Add Persian language +- LOCALIZATION: Add Hebrew language +- LOCALIZATION: Add Asturian language +- MENU: Proper line wrapping for message dialog boxes +- MENU/HOTKEYS: Add sublabels to all hotkey bind entries +- MENU/QUICK MENU: Suppress the display of 'empty' quick menu listings when closing content +- MENU/OZONE: Performance improvements +- MENU/SDL: Add mouse controls +- OPENGL1/VITA: Initial changes for HW context without FBO +- OVERLAYS: Add options for moving the on-screen overlay +- PLAYLISTS/WINDOWS: Fix core path entries in image/video/music history playlists +- PS2: Add back CDFS support +- SDL/GL: Advertise GLSL support +- VIDEO/WIDGETS: Fix heap-use-after-free errors, leading to memory corruption +- VITA: Added custom bubbles support +- VITA: VitaGL update +- VULKAN/WSI: Better frame pacing +- VULKAN/WSI: Fix Intel Mesa being broken when using Fences, we have to use Semaphores to acquire the swapchain or the entire GPU stalls +- VULKAN/WSI: Add support for either using fences or semaphores when syncing +- VULKAN/WSI: Prefer using semaphores for integrated GPUs as it promotes better throughput over fences +- VULKAN/WSI/ANDROID: Do not use mailbox emulation on Android +- UWP/XBOX: Potentially improve performance by enabling 'Game Mode' + +# 1.8.8 +- AUDIO/JACK: Fix regression introduced after 1.8.4 - would hang at startup +- CHEEVOS: Disable hardcore when cheats are enabled +- CHD: Return false when special track cannot be found +- DISCORD/MATCHMAKING: Fix Discord 'Ask To Join' functionality +- FILE PATH: Various file path handling optimisations +- FONT: Fix Arabic, Chinese and Korean font rendering +- INPUT MAPPING/REMAPPING: Restore broken 'reset to default' functionality with RetroPad 'start' button +- INPUT MAPPING/REMAPPING: Fix 'reset to default' action for analog sticks and undefined core inputs +- LOCALIZATION: Update Arabic translation +- LOCALIZATION: Update Chinese (Simplified) translation +- LOCALIZATION: Update Chinese (Traditional) translation +- LOCALIZATION: Update German translation +- LOCALIZATION: Update Greek translation +- LOCALIZATION: Update Spanish translation +- LOCALIZATION: Update French translation +- LOCALIZATION: Update Italian translation +- LOCALIZATION: Update Japanese translation +- LOCALIZATION: Update Korean translation +- LOCALIZATION: Update Dutch translation +- LOCALIZATION: Update Polish translation +- LOCALIZATION: Update Portuguese Brazilian translation +- LOCALIZATION: Update Russian translation +- LOCALIZATION: Update Turkish translation +- LOCALIZATION: Update Vietnamese translation +- LOCALIZATION: Add Slovak translation +- MENU: Small buffer optimizations +- MENU/THUMBNAILS/BUGFIX: Fix heap-use-after-free error +- MENU/OZONE: Add option to sort playlists after name truncation +- MENU/OZONE/ANDROIDTV: Default to Ozone menu driver +- MENU/OZONE/ANDROID: Gamepad-like devices default to Ozone now (Shield Portable) +- NETPLAY: Lower announcement rate +- OVERLAYS: Fix memory leak when loading overlays +- SHADER PRESETS: Improved shader preset dirs +- TIME/DATE: Enable configuration of date seperator in clock and runtime 'last played' displays +- VITA: Fix upside-down vertical games +- UWP: Enable playlist and savefile compression by default (because of slow file I/O) +- WIIU: Gamepad hotplugging support +- WIIU: Theoretical multi-gamepad support +- VIDEO/WIDGETS: Fix overlapping text when simultaneous pop-up notifications and core/shader messages are being displayed +- X11: Fix crash in x11_display_server_get_screen_orientation +- X11/XSHM: Allow X11/XHSM video driver to operate without SHM extension +- X11/XSHM: Fix compatibility with X11 input driver +- XVIDEO: Fix keyboard input initialization +- XVIDEO/XWAYLAND: Fix XVideo support on xwayland (by supporting I420 and YZ12) + +# 1.8.7 +- 3DS: Add IDs for Frodo +- 3DS: Enable basic networking / cheevos +- CHEEVOS/BUGFIX: Opening achievements list would crash RetroArch with badges enabled (on new games) +- CHEEVOS: Option to start a session with all achievements active +- CHEEVOS: Don't perform unnecessary cheevos initialisation when cheevos are disabled. Should reduce startup times when loading content. +- CORE OPTIONS: Disable 'Use Global Core Options File' by default +- DOS/DJGPP: Add 32bit color support for cores +- GLCORE: Switch to glcore video driver when requested by a core +- LINUX/XDG: Use GenericName correctly in desktop entry +- MAC/COCOA: Fix mouse cursor tracking +- MENU/MATERIALUI: Add desktop-style playlist view mode +- MENU/MATERIALUI/DESKTOPVIEW: When scrolling playlists, show last selected thumbnails while waiting for next entry to load +- MENU/MATERIALUI: Limit tab switch rate when input repeat is active +- MENU/OZONE: Fix sidebar playlist sort order when 'Truncate Playlist Names' is enabled +- MENU/RGUI: Adjusted menu defaults, adjusted default scrolling speed +- MENU/RGUI: Enable custom wallpaper when menu size is reduced at low resolutions +- MENU/XMB: Limit tab switch rate when input repeat is active +- NETPLAY: Fix regressions introduced in 1.8.5 +- RGUI: Add option to always stretch menu to fill the screen +- WIIU: Enable graphics widgets + +# 1.8.6 +- 3DS: Add IDs for UZEM, TGB Dual, and NeoCD +- 3DS: Fix font driver horizontal text alignment +- 3DS: Allow button presses up to INPUT_MAX_USERS - this enables the 3DS to bind and use buttons and axis for users up to the maximum set by 'Max Users' in the input settings menu. +- 3DS: Disable video filter if upscaled resolution exceeds hardware limits. The 3DS has a maximum video buffer size of 2048x2048. This is sufficient for every core that it supports, but when using software video filters the core output resolution is doubled. This is made worse by the fact that the video filter upscaling buffer size is dependent upon the maximum output resolution of the core - which in some cases is very large indeed (e.g. pcsx-rearmed sets a maximum width of 1024, for enhanced resolution support). The 3DS has very limited 'linear memory' for graphics buffer purposes, and a large base core buffer + video filter buffer can easily exceed this - which may also disable video output, or cause a crash. This PR very simply adds a 3DS-specific check to the video filter initialisation: if the resultant upscaling buffer exceeds the hardware limitation, then the filter is automatically disabled. +- 3DS/FONT/BUGFIX: Text colour was wrong: the RGBA channels were muddled, and R was always set to 255 +- 3DS/FONT/BUGFIX: When drawing multiline strings, the line spacing was completely incorrect +- 3DS/FONT: Improves the appearance of the drop shadow effect on notification text. +- 3DS/ARCHIVE/7Z: Re-enable 7zip support. +- ARCHIVE/ZIP: Expand functionality of 'rzip_stream' interface. This PR expands the functionality of the new rzip_stream archived stream interface such that it now has almost complete feature parity with the standard file_stream interface, and can therefore be used as a drop-in replacement in most situations +- AI SERVICE: Hide redundant entries when service is disabled +- AI SERVICE: Added in auto-translate support +- AI SERVICE: support for NVDA and SAPI narration +- AUTOCONFIG: Use correct port index in input device configured/disconnected notifications +- BUGFIX: Fix race condition where task could momentarily not be in the queue when reordering +- CHEEVOS/BUGFIX: Prevent null reference rendering achievement list while closing application +- CHEEVOS/BUGFIX: Report non-memorymap GBA cores as unsupported +- COMMANDLINE: Advise against using -s and -S variables on the command line. … +- CONFIG FILE: Only write config files to disk when parameters change +- CONFIG FILE/BUGFIX: RetroArch no longer crashes when attempting to save a config file after 'unsetting' a parameter (currently, this can be triggered quite easily by manipulating input remaps) +- CONFIG FILE/BUGFIX: When using Material UI, RetroArch no longer modifies the wrong setting (or segfaults...) when tapping entries in the Quick Menu > Controls input remapping submenu +- CONFIG FILE/BUGFIX: Quite a few real and potential memory leaks have been fixed. +- CHD: Fixes a crash caused by ignoring the return value from one of the CHD library functions +- FASTFORWARDING: A new Mute When Fast-Forwarding option has been added under Settings > Audio. When enabled, users can fast forward without having to listen to distorted audio. +- GLCORE/SLANG: Set filter and wrap mode correctly when intialising shader textures. Before, the glcore shader driver did not correctly initialise loaded textures. The texture filtering and wrap mode were forced on texture creation, but these settings were not recorded - subsequent updates would set garbage values, that would resolve to linear filtering OFF and wrap mode = CLAMP_TO_EDGE. +- LOCALIZATION: Update Japanese translation +- LOCALIZATION: Update Spanish translation +- LOCALIZATION: Update Portuguese Brazilian translation +- IOS: Set audio session category to ambient so sound does not get cut off on interruption (phone call/playing back audio) +- MAC/IOHIDMANAGER/BUGFIX: Fix for Mayflash N64 adapter. In case last hatswitch does not match cookie. For the mayflash N64 adapter, I was getting a BAD EXC ADDRESS (in mac OS 10.13) for this line (tmp was NULL). Retroarch would crash in the gui if I pressed a button from the DPAD on controller 2. With this change, it no longer crashes in the gui and still registers the button push. +- MAC/COCOA: Fix mouse input - this brings back two lines of code that have been removed over time but +appear to be required in order for mouse input to work on macOS +- METAL/BUGFIX: GPU capture on Metal/OSX/NVidia could crash +- METAL/BUGFIX: Taking screenshots could capture black frames. Resulting PNG screenshots were black. +- METAL/BUGFIX: Corrupted image due to incorrect viewport copy when taking screenshot +- MENU: Prevent font-related segfaults when using extremely small scales/window sizes +- MENU: Fix 'gfx_display_draw_texture_slice()' +- MENU/FONT: Enable correct vertical alignment of text (+ font rendering fixes) +- MENU/RGUI: Enable automatic menu size reduction when running at low resolutions (down to 256x192) +- MENU/OZONE: Update timedate style options for Last Played sublabel metadata +- MENU/OZONE: Hide 'Menu Color Theme' setting when 'Use preferred system color theme' is enabled +- MENU/OZONE: Fix thumbnail switching via 'scan' button functionality +- MENU/OZONE: Prevent glitches when rendering Ozone's selection cursor +- MENU/OZONE: Enable proper vertical text alignment + thumbnail display improvements +- MENU/OZONE: Enable second thumbnail/content metadata toggle using RetroPad 'select' +- MENU/OZONE: Refactor footer display +- MENU/OZONE: Hide thumbnail button hints when viewing file browser lists +- MENU/OZONE/INPUT/BUGFIX: Fix undefined behaviour when using touch screen to change input remaps +- MENU/OZONE/INPUT/BUGFIX: It turns out that Windows reports negative pointer coordinates when the mouse cursor goes beyond the left hand edge of the RetroArch window (this doesn't happen on Linux, so I never encountered this issue before!). As a result, if Ozone is currently not showing the sidebar (menu depth > 1), moving the cursor off the left edge of the window generates a false positive 'cursor in sidebar' event - which breaks menu navigation, as described in #10419. With this PR, we now handle 'cursor in sidebar' status correctly in all cases +- MENU/OZONE/INPUT/BUGFIX: Pointer input is now correctly disabled when message boxes are displayed +- MENU/XMB: Fix thumbnail switching via 'scan' button functionality +- ODROID GO ADVANCE: Add DRM HW context driver +- PSL1GHT: Initial port +- PSL1GHT/KEYBOARD: Implement PSL1GHT keyboard +- PLAYLIST/BUGFIX: Improve handling of 'broken' playlists - RetroArch will no longer segfault when attempting to run content via a playlist entry with missing path or core path fields. +- PLAYLIST/BUGFIX: Improve handling of 'broken' playlists - when a playlist entry has either core path and/or core name set to NULL, DETECT or an empty string, attempting to load content will fallback to the normal 'core selection' code (currently this happens only if both core path and core name are DETECT - this is wholly inadequate!) +- PLAYLIST/BUGFIX: RetroArch will no longer segfault when attempting to fetch content runtime information when core path is NULL +- PLAYLIST/BUGFIX: Core name + runtime info will only be displayed on playlists and in the Information submenu if both the core path and core name fields are 'valid' (i.e. not NULL or DETECT) +- PLAYLIST/BUGFIX: When handling entries with missing path fields, the menu sorting order now matches that of the playlist sorting order (at present, everything goes out of sync when paths are empty). Moreover, entries with missing path fields can now be 'selected', so users can remove them (currently, hitting A on such an entry immediately tries - and fails - to load the content, so the only way to remove the broken entry is via the Playlist Management > Clean Playlist feature) +- PLAYLIST: Add optional per-playlist alphabetical sorting +- PLAYLIST: Omit whitespace when writing compressed JSON format playlists +- PLAYLIST: Add optional playlist compression +- QNX: Support analog sticks +- SAVESTATES: Add optional save state compression (enabled by default now) +- SRAM: Add optional save (SRAM) file compression +- SCANNER: Prevent redundant playlist entries when handling M3U content +- SCANNER/ANDROID: Fix content scanner being unable to identify certain games from CHD images (raw data sector/subcode) +- TASKS/BUGFIX: Fix task deadlocks +- TASKS/SCREENSHOT/BUGFIX: Fix heap-use-after-free error when widgets are disabled +- TVOS: Disable overlays for tvOS, fix app icon +- VIDEO/WIDGETS/BUGFIX: The font ascender/descender metrics added in #10375 are now used to achieve 'pixel perfect' vertical text alignment +- VIDEO/WIDGETS/BUGFIX: Message queue text now uses its own dedicated font. Previously, a single (larger) font was used for all active widgets, and this was scaled down for message queue items. This 'squished' the text a little; more importantly, when using the stb font renderers (on Android. etc.) it caused ugly artefacts around the edges of glyphs due to pixel interpolation errors. Now that a correctly sized font is used, the message queue is always rendered cleanly. +- VIDEO/WIDGETS/BUGFIX: Previously, each widget font was 'flushed' (font_driver_flush()) at least once a frame. This is quite a slow operation. Now we only flush fonts if they have actually been used. +- VULKAN/BUGFIX: Fix display of statistics text +- UNIX/BUGFIX: Fix overflow when computing total memory on i386 +- WIIU/BUGFIX: Fix font driver horizontal text alignment +- WIIU/BUGFIX: Fix non-vertex coordinates in draws using tex shader +- WIIU/BUGFIX: Update and fix meta.xml file for the WiiU release. This change makes it so the information from the meta.xml file parsed for the WiiU's Homebrew Launcher is displayed properly. + +# 1.8.5 - 3DS: Keep the bottom screen hidden on sleep/wakeup. When the 3DS wakes back up after being closed, the bottom screen needs to be reinitialized. Adding the condition here will cause the screen to be turned on or off based on the state of ctr_bottom_screen_enabled, as you'd expect - ANDROID/CHROMEBOOK/CRASH: Fix Chromebook crashes (on x86 x64) when touching the screen - BUGFIX: Prevent double input when using 'return' key (hardware) to close on-screen keyboard - BUGFIX: Fix mouse capture hotkey not working - BUGFIX: Avoid overflow when calculating multiplying performance counter +- BUGFIX: Retroarch overlay displaying "Game remap file loaded." on the overlay instead of "Core remap file loaded." when only a core remap file is present - CHEEVOS/BUGFIX: Achievement triggers could cause Retroarch to Crash - CHEEVOS: Don't block Sameboy core because it only exposes some memory - CHEEVOS: Support for extended Sega CD memory @@ -21,14 +220,19 @@ - FFMPEG CORE: Fix crash on seeking when using HW decoding in some cases - LIBRETRO: Add disk control interface API extension - LINUX: Avoid possible crash when running retroarch at startup +- LINUX/GLX: Fix threaded video crashes/instability because of GLX OML sync callbacks - LOCALIZATION: Update French translation - LOCALIZATION: Update Korean translation - LOCALIZATION: Update Polish translation - LOCALIZATION: Update Spanish translation - LOCALIZATION: Update Portuguese Brazilian translation +- MENU: Add Menu Scroll Acceleration option - MENU: Automatically select currently checked item when opening drop-down lists - MENU: Fix smooth (vertical) line ticker scroll speed - MENU: Don't flush on override/remap messages +- MENU/DATETIME: Adds some new timedate styles that follow the DD/MM/YYYY format, found in several European countries +- MENU/DATETIME: Modifies the existing translation files in order to accommodate the new options that are now available +- MENU/DATETIME: Reorders the timedate view options based on a decreasing order of the quantity of information displayed, so that they are more convenient to switch around and easily categorized - MENU/BUGFIX: Fix bug - if you were in XMB and you would set menu driver to RGUI, you could no longer go to the left or right tab - MENU/MATERIALUI: Add option to remove navigation bar - MENU/OZONE: Add DPI-based scaling @@ -47,6 +251,8 @@ - ODROID GO ADVANCE: Rotation support - NETPLAY/ROOMS/BUGFIX: Prevent out-of-bounds array indexing when displaying/selecting netplay rooms in menus - SCANNER: Add 'Arcade DAT Filter' Option +- SCANNER: Add scanning Korea and Asia PS1 discs +- SCANNER: Add support for scanning PSP Korean - VIDEO: Set hardware 'Bilinear filtering' off by default - VIDEO/WIDGETS: Widgets are now menu-independent - VIDEO/WIDGETS: Allow notifications to use full screen width when not displaying menu @@ -54,6 +260,7 @@ - VIDEO/WIDGETS: Fix volume widget scaling - VIDEO/WIDGETS: Add independent widget scale override settings for fullscreen/windowed modes - VIDEO/WIDGETS/BUGFIX: Prevent improper display of (old style) OSD text when widgets are enabled +- VIDEO/WIDGETS/THREADED/BUGFIX: Fix issue - corruption of menu widgets when running some cores (e.g. VICE) with threaded video enabled - WIFI/CONNMANCTL: Display more characters from SSID # 1.8.4 diff --git a/Makefile.common b/Makefile.common index aff67b3485..5e102ce1dc 100644 --- a/Makefile.common +++ b/Makefile.common @@ -19,6 +19,12 @@ ifeq ($(HAVE_CXX11), 1) CXXFLAGS += $(CXX11_CFLAGS) endif +ifeq ($(HAVE_SAPI), 1) + LIBS += sapi.dll +endif + + + ifeq ($(HAVE_GL_CONTEXT),) HAVE_GL_CONTEXT = 0 HAVE_GL_MODERN = 0 @@ -176,6 +182,7 @@ OBJ += frontend/frontend_driver.o \ tasks/task_image.o \ tasks/task_playlist_manager.o \ tasks/task_manual_content_scan.o \ + tasks/task_core_backup.o \ $(LIBRETRO_COMM_DIR)/encodings/encoding_utf.o \ $(LIBRETRO_COMM_DIR)/encodings/encoding_crc32.o \ $(LIBRETRO_COMM_DIR)/encodings/encoding_base64.o \ @@ -219,7 +226,6 @@ OBJ += \ file_path_str.o \ $(LIBRETRO_COMM_DIR)/hash/rhash.o \ input/common/input_hid_common.o \ - input/input_mapper.o \ led/led_driver.o \ gfx/video_coord_array.o \ gfx/video_crt_switch.o \ @@ -241,6 +247,7 @@ OBJ += \ $(LIBRETRO_COMM_DIR)/compat/compat_posix_string.o \ managers/cheat_manager.o \ core_info.o \ + core_backup.o \ $(LIBRETRO_COMM_DIR)/file/config_file.o \ $(LIBRETRO_COMM_DIR)/file/config_file_userdata.o \ runtime_file.o \ @@ -260,9 +267,9 @@ OBJ += \ $(LIBRETRO_COMM_DIR)/utils/md5.o \ playlist.o \ $(LIBRETRO_COMM_DIR)/features/features_cpu.o \ - performance_counters.o \ verbosity.o \ $(LIBRETRO_COMM_DIR)/playlists/label_sanitization.o \ + $(LIBRETRO_COMM_DIR)/time/rtime.o \ manual_content_scan.o \ disk_control_interface.o @@ -317,7 +324,11 @@ ifeq ($(HAVE_LANGEXTRA), 1) intl/msg_hash_cht.o \ intl/msg_hash_ar.o \ intl/msg_hash_el.o \ - intl/msg_hash_tr.o + intl/msg_hash_tr.o \ + intl/msg_hash_sk.o \ + intl/msg_hash_fa.o \ + intl/msg_hash_he.o \ + intl/msg_hash_ast.o endif ifneq ($(HAVE_GETOPT_LONG), 1) @@ -426,6 +437,8 @@ ifeq ($(HAVE_QT), 1) ifneq ($(findstring Linux,$(OS)),) DEF_FLAGS += -fPIC + else ifneq ($(findstring BSD,$(OS)),) + DEF_FLAGS += -fPIC endif endif @@ -805,18 +818,11 @@ ifeq ($(HAVE_LAKKA_SWITCH), 1) DEFINES += -DHAVE_LAKKA_SWITCH endif -# Does not depend on HAVE_MENU -ifeq ($(HAVE_SHADERS_COMMON), 1) - OBJ += menu/menu_shader.o -endif - ifeq ($(HAVE_MENU_COMMON), 1) - OBJ += menu/menu_driver.o \ - menu/menu_setting.o \ + OBJ += menu/menu_setting.o \ menu/widgets/menu_filebrowser.o \ menu/widgets/menu_dialog.o \ menu/widgets/menu_input_bind_dialog.o \ - menu/menu_cbs.o \ menu/cbs/menu_cbs_ok.o \ menu/cbs/menu_cbs_cancel.o \ menu/cbs/menu_cbs_select.o \ @@ -837,10 +843,15 @@ ifeq ($(HAVE_MENU_COMMON), 1) menu/menu_displaylist.o endif - OBJ += input/input_osk.o - ifeq ($(HAVE_GFX_WIDGETS), 1) - OBJ += gfx/gfx_widgets.o + OBJ += gfx/gfx_widgets.o \ + gfx/widgets/gfx_widget_screenshot.o \ + gfx/widgets/gfx_widget_volume.o \ + gfx/widgets/gfx_widget_generic_message.o \ + gfx/widgets/gfx_widget_libretro_message.o + ifeq ($(HAVE_CHEEVOS), 1) + OBJ += gfx/widgets/gfx_widget_achievement_popup.o + endif endif ifeq ($(HAVE_OVERLAY), 1) @@ -1114,7 +1125,12 @@ OBJ += gfx/drivers_context/gfx_null_ctx.o ifeq ($(HAVE_KMS), 1) HAVE_AND_WILL_USE_DRM = 1 + +ifeq ($(HAVE_ODROIDGO2), 1) + OBJ += gfx/drivers_context/drm_go2_ctx.o +else OBJ += gfx/drivers_context/drm_ctx.o +endif DEF_FLAGS += $(GBM_CFLAGS) $(DRM_CFLAGS) LIBS += $(GBM_LIBS) $(DRM_LIBS) endif @@ -1670,7 +1686,8 @@ endif ifeq ($(HAVE_ZLIB_COMMON), 1) OBJ += $(LIBRETRO_COMM_DIR)/file/archive_file_zlib.o \ - $(LIBRETRO_COMM_DIR)/streams/trans_stream_zlib.o + $(LIBRETRO_COMM_DIR)/streams/trans_stream_zlib.o \ + $(LIBRETRO_COMM_DIR)/streams/rzip_stream.o DEFINES += -DHAVE_ZLIB HAVE_COMPRESSION = 1 @@ -1729,7 +1746,8 @@ endif OBJ += $(LIBRETRO_COMM_DIR)/formats/bmp/rbmp_encode.o \ $(LIBRETRO_COMM_DIR)/formats/json/jsonsax.o \ $(LIBRETRO_COMM_DIR)/formats/json/jsonsax_full.o \ - $(LIBRETRO_COMM_DIR)/formats/image_transfer.o + $(LIBRETRO_COMM_DIR)/formats/image_transfer.o \ + $(LIBRETRO_COMM_DIR)/formats/m3u/m3u_file.o # Gong embedded core ifeq ($(HAVE_GONG),1) @@ -1752,7 +1770,16 @@ endif # Accessibility ifeq ($(HAVE_ACCESSIBILITY), 1) DEFINES += -DHAVE_ACCESSIBILITY + +ifeq ($(HAVE_SAPI), 1) +ifneq ($(findstring Win32,$(OS)),) + LIBS += -lsapi endif +endif + +endif + + # Things that depend on network availability @@ -1798,38 +1825,41 @@ ifeq ($(HAVE_NETWORKING), 1) # Netplay DEFINES += -DHAVE_NETWORK_CMD OBJ += network/netplay/netplay_delta.o \ - network/netplay/netplay_handshake.o \ - network/netplay/netplay_init.o \ - network/netplay/netplay_io.o \ - network/netplay/netplay_keyboard.o \ - network/netplay/netplay_sync.o \ - network/netplay/netplay_discovery.o \ - network/netplay/netplay_buf.o \ - network/netplay/netplay_room_parse.o + network/netplay/netplay_handshake.o \ + network/netplay/netplay_init.o \ + network/netplay/netplay_io.o \ + network/netplay/netplay_keyboard.o \ + network/netplay/netplay_sync.o \ + network/netplay/netplay_discovery.o \ + network/netplay/netplay_buf.o \ + network/netplay/netplay_room_parse.o # RetroAchievements ifeq ($(HAVE_CHEEVOS), 1) DEFINES += -DHAVE_CHEEVOS INCLUDE_DIRS += -Ideps/rcheevos/include - OBJ += cheevos-new/cheevos.o \ - cheevos-new/badges.o \ - cheevos-new/fixup.o \ - cheevos-new/parser.o \ - cheevos-new/hash.o \ + OBJ += cheevos/cheevos.o \ + cheevos/badges.o \ + cheevos/fixup.o \ + cheevos/parser.o \ + cheevos/hash.o \ $(LIBRETRO_COMM_DIR)/formats/cdfs/cdfs.o \ - deps/rcheevos/src/rcheevos/trigger.o \ - deps/rcheevos/src/rcheevos/condset.o \ - deps/rcheevos/src/rcheevos/condition.o \ - deps/rcheevos/src/rcheevos/operand.o \ - deps/rcheevos/src/rcheevos/term.o \ - deps/rcheevos/src/rcheevos/expression.o \ - deps/rcheevos/src/rcheevos/value.o \ - deps/rcheevos/src/rcheevos/lboard.o \ deps/rcheevos/src/rcheevos/alloc.o \ + deps/rcheevos/src/rcheevos/compat.o \ + deps/rcheevos/src/rcheevos/condition.o \ + deps/rcheevos/src/rcheevos/condset.o \ + deps/rcheevos/src/rcheevos/consoleinfo.o \ deps/rcheevos/src/rcheevos/format.o \ + deps/rcheevos/src/rcheevos/lboard.o \ deps/rcheevos/src/rcheevos/memref.o \ + deps/rcheevos/src/rcheevos/operand.o \ deps/rcheevos/src/rcheevos/richpresence.o \ + deps/rcheevos/src/rcheevos/runtime.o \ + deps/rcheevos/src/rcheevos/runtime_progress.o \ + deps/rcheevos/src/rcheevos/trigger.o \ + deps/rcheevos/src/rcheevos/value.o \ + deps/rcheevos/src/rhash/hash.o \ deps/rcheevos/src/rurl/url.o ifeq ($(HAVE_LUA), 1) @@ -1878,7 +1908,8 @@ ifeq ($(HAVE_NETWORKING), 1) ifeq ($(HAVE_DISCORD), 1) NEED_CXX_LINKER = 1 DEFINES += -DHAVE_DISCORD - INCLUDE_DIRS += -Ideps/discord-rpc/include/ -Ideps/discord-rpc/thirdparty/rapidjson-1.1.0/include/ + INCLUDE_DIRS += -Ideps/discord-rpc/include \ + -Ideps/discord-rpc/thirdparty/rapidjson-1.1.0/include/ ifneq ($(HAVE_THREADS), 1) DEFINES += -DDISCORD_DISABLE_IO_THREAD @@ -1886,8 +1917,7 @@ ifeq ($(HAVE_NETWORKING), 1) OBJ += deps/discord-rpc/src/discord_rpc.o \ deps/discord-rpc/src/rpc_connection.o \ - deps/discord-rpc/src/serialization.o \ - discord/discord.o + deps/discord-rpc/src/serialization.o ifneq ($(findstring Win32,$(OS)),) OBJ += deps/discord-rpc/src/discord_register_win.o \ @@ -1936,8 +1966,7 @@ endif ifneq ($(findstring FPGA,$(OS)),) OBJ += gfx/drivers/fpga_gfx.o \ - gfx/drivers_context/fpga_ctx.o \ - gfx/drivers_font/fpga_font.o + gfx/drivers_context/fpga_ctx.o endif ifneq ($(findstring Win32,$(OS)),) @@ -2064,7 +2093,7 @@ ifeq ($(HAVE_MATH_NEON), 1) endif ifeq ($(HAVE_VITAGL), 1) - DEFINES += -DHAVE_VITAGL -DTRANSPOSE_MATRICES + DEFINES += -DHAVE_VITAGL -DSTB_DXT_IMPLEMENTATION -DSKIP_ERROR_HANDLING INCLUDE_DIRS += -I$(DEPS_DIR)/vitaGL/source SOURCES := $(DEPS_DIR)/vitaGL/source $(DEPS_DIR)/vitaGL/source/utils OBJ += $(patsubst %.c,%.o,$(foreach dir,$(SOURCES), $(wildcard $(dir)/*.c))) @@ -2113,6 +2142,7 @@ ifeq ($(HAVE_ODROIDGO2), 1) LIBS += -lrga -lpng -lz INCLUDE_DIRS += -I$(DEPS_DIR)/libgo2/include OBJ += $(DEPS_DIR)/libgo2/src/display.o \ - $(DEPS_DIR)/libgo2/src/queue.o + $(DEPS_DIR)/libgo2/src/queue.o \ + gfx/drivers/oga_gfx.o endif ################################## diff --git a/Makefile.ctr b/Makefile.ctr index 83b3624a72..3fe03430a6 100644 --- a/Makefile.ctr +++ b/Makefile.ctr @@ -51,8 +51,9 @@ DEFINES := ifeq ($(GRIFFIN_BUILD), 1) OBJ += griffin/griffin.o DEFINES += -DHAVE_GRIFFIN=1 -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_RGUI -DHAVE_XMB -DHAVE_MATERIALUI -DHAVE_LIBRETRODB -DHAVE_CC_RESAMPLER - DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA - #DEFINES += -DHAVE_NETWORKING -DHAVE_CHEEVOS -DRC_DISABLE_LUA -DHAVE_SOCKET_LEGACY -DHAVE_THREADS + DEFINES += -DHAVE_ZLIB -DHAVE_7ZIP -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA + DEFINES += -DHAVE_NETWORKING -DHAVE_CHEEVOS -DRC_DISABLE_LUA + #DEFINES += -DHAVE_SOCKET_LEGACY -DHAVE_THREADS #-DHAVE_SSL -DHAVE_BUILTINMBEDTLS -DMBEDTLS_SSL_DEBUG_ALL #ssl is currently incompatible with griffin due to use of the "static" flag on repeating functions that will conflict when included in one file else @@ -135,6 +136,7 @@ CFLAGS += -I. \ -Ideps \ -Ideps/7zip \ -Ideps/stb \ + -Ideps/rcheevos/include \ -Ilibretro-common/include \ -Ilibretro-common/include/compat/zlib diff --git a/Makefile.ctr.salamander b/Makefile.ctr.salamander index 9c05fd6b54..ffd3082f3f 100644 --- a/Makefile.ctr.salamander +++ b/Makefile.ctr.salamander @@ -38,6 +38,7 @@ OBJ := ctr/ctr_system.o \ libretro-common/streams/file_stream.o \ libretro-common/vfs/vfs_implementation.o \ libretro-common/hash/rhash.o \ + libretro-common/time/rtime.o \ file_path_str.o \ verbosity.o diff --git a/Makefile.griffin b/Makefile.griffin index 1f31a62650..634ccc1472 100644 --- a/Makefile.griffin +++ b/Makefile.griffin @@ -75,15 +75,22 @@ ifeq ($(WHOLE_ARCHIVE_LINK), 1) WHOLE_END := -Wl,--no-whole-archive endif +STATIC_BUILD = 1 ifneq (,$(findstring msvc,$(platform))) - LIBS := $(WHOLE_START) $(WHOLE_END) -else + STATIC_BUILD = 0 +endif ifneq (,$(findstring unix,$(platform))) + STATIC_BUILD = 0 +endif +ifeq (qnx, $(platform)) + STATIC_BUILD = 0 +endif + +ifeq ($(STATIC_BUILD), 0) LIBS := $(WHOLE_START) $(WHOLE_END) else LIBS := $(WHOLE_START) -lretro_$(platform) $(WHOLE_END) endif -endif libogc_platform := @@ -148,7 +155,7 @@ else ifeq ($(libogc_platform), 1) endif LIBDIRS += -L. - MACHDEP += -DGEKKO -mcpu=750 -meabi -mhard-float -DMSB_FIRST + MACHDEP += -DGEKKO -mcpu=750 -meabi -mhard-float ifeq ($(platform), ngc) LDFLAGS += $(MACHDEP) -Wl,-Map,$(notdir $(EXT_INTER_TARGET)).map @@ -791,6 +798,44 @@ else ifneq (,$(findstring windows_msvc2015,$(platform))) export INCLUDE := $(INCLUDE);libretro-common\include;libretro-common\include\compat\msvc;gfx\include;deps;deps\stb export LIB := $(LIB) endif +else ifeq (qnx,$(platform)) + HAVE_AUDIOMIXER := 1 + HAVE_RPNG := 1 + HAVE_RJPEG := 1 + HAVE_RBMP := 1 + HAVE_RTGA := 1 + HAVE_ZLIB := 1 + HAVE_7ZIP := 1 + HAVE_NETWORKING := 1 + HAVE_NETWORK_CMD := 1 + HAVE_NETPLAYDISCOVERY := 1 + HAVE_OVERLAY := 1 + HAVE_VIDEO_LAYOUT := 0 + HAVE_MATERIALUI := 1 + HAVE_XMB := 1 + HAVE_STB_FONT := 1 + HAVE_THREADS := 1 + HAVE_LIBRETRODB := 1 + HAVE_COMMAND := 1 + HAVE_STDIN_CMD := 1 + HAVE_CMD := 1 + HAVE_DYLIB := 1 + HAVE_DYNAMIC := 1 + HAVE_GRIFFIN_CPP := 0 + WANT_GLSLANG := 0 + HAVE_CONFIGFILE := 1 + CC=qcc -Vgcc_ntoarmv7le + CXX=QCC -Vgcc_ntoarmv7le + + ifeq ($(DEBUG), 1) + LDFLAGS += -g + endif + + PLATCFLAGS += -DHAVE_SHADERPIPELINE -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_OZONE -DHAVE_CC_RESAMPLER -DHAVE_CHEEVOS -DRC_DISABLE_LUA -DHAVE_FBO -DHAVE_GL_SYNC -DHAVE_GLSLANG -DHAVE_BUILTINGLSLANG -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_RUNAHEAD -DHAVE_GFX_WIDGETS -DHAVE_CONFIGFILE -DHAVE_SPIRV_CROSS -DHAVE_STB_FONT -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DHAVE_XMB -DRARCH_INTERNAL -DWANT_GLSLANG -DHAVE_XCB -DHAVE_EGL -DHAVE_BB10 -DHAVE_GLSL -DHAVE_AL -DRARCH_MOBILE + EXT_TARGET := $(TARGET_NAME) + EXT_INTER_TARGET := $(TARGET_NAME) + INCLUDE += -Ilibretro-common/include -Igfx/include -Ideps -Ideps/stb -Ideps/rcheevos/include -Ideps/SPIRV-Cross -Ideps/glslang -I. + LIBS += -lEGL -lbps -lscreen -lsocket -lm -lGLESv2 -lOpenAL else ifneq (,$(findstring unix,$(platform))) HAVE_AUDIOMIXER := 1 HAVE_RPNG := 1 @@ -823,6 +868,46 @@ else ifneq (,$(findstring unix,$(platform))) EXT_INTER_TARGET := $(TARGET_NAME) INCLUDE += -Ilibretro-common/include -Igfx/include -Ideps -Ideps/stb -Ideps/rcheevos/include -Ideps/SPIRV-Cross -Ideps/glslang -I. LIBS += -ldl -lm -lpthread -lGL -ludev -lpulse -lX11 -lX11-xcb -lXxf86vm +else ifeq (dos,$(platform)) + HAVE_AUDIOMIXER := 1 + HAVE_RPNG := 1 + HAVE_RJPEG := 1 + HAVE_RBMP := 1 + HAVE_RTGA := 1 + HAVE_ZLIB := 1 + HAVE_7ZIP := 1 + HAVE_NETWORKING := 0 + HAVE_NETWORK_CMD := 0 + HAVE_NETPLAYDISCOVERY := 0 + HAVE_OVERLAY := 1 + HAVE_VIDEO_LAYOUT := 0 + HAVE_MATERIALUI := 1 + HAVE_XMB := 0 + HAVE_STB_FONT := 1 + HAVE_THREADS := 0 + HAVE_LIBRETRODB := 1 + HAVE_COMMAND := 1 + HAVE_STDIN_CMD := 1 + HAVE_CMD := 1 + HAVE_DYLIB := 0 + HAVE_DYNAMIC := 0 + HAVE_GRIFFIN_CPP := 0 + WANT_GLSLANG := 0 + HAVE_CONFIGFILE := 1 + CC=i586-pc-msdosdjgpp-gcc + CXX=i586-pc-msdosdjgpp-g++ + + ifeq ($(DEBUG), 1) + LDFLAGS += -g + endif + + PLATCFLAGS += -DHAVE_SHADERPIPELINE -DHAVE_CC_RESAMPLER -DRC_DISABLE_LUA -DHAVE_FBO -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_GFX_WIDGETS -DHAVE_CONFIGFILE -DHAVE_SPIRV_CROSS -DHAVE_STB_FONT -DRARCH_INTERNAL -DHAVE_XCB + TARGET_NAME := retrodos + EXT_TARGET := $(TARGET_NAME).exe + EXT_INTER_TARGET := $(TARGET_NAME).exe + INCLUDE += -Ilibretro-common/include -Igfx/include -Ideps -Ideps/stb -Ideps/SPIRV-Cross -Ideps/glslang -I. + LIBS += -lm + LIBDIRS += -L. endif ifneq (,$(findstring msvc,$(platform))) @@ -1096,7 +1181,12 @@ $(APP_BOOTER_DIR)/app_booter.bin: $(MAKE) -C $(APP_BOOTER_DIR) pkg: all -ifeq ($(platform), wii) +ifeq ($(platform), qnx) + mkdir -p pkg/qnx/pkg + cp -r $(EXT_TARGET) pkg/qnx/pkg/RetroArch + cp -r media/canvas.png pkg/qnx/pkg/canvas.png + cp -r media/retroarch-96x96.png pkg/qnx/pkg/retroarch-96x96.png +else ifeq ($(platform), wii) cp -r $(EXT_TARGET) pkg/wii/CORE.dol else ifeq ($(platform), ngc) cp -r $(EXT_TARGET) pkg/ngc/CORE.dol @@ -1104,6 +1194,18 @@ else ifeq ($(platform), psp1) psp-fixup-imports$(EXT) $(EXT_TARGET) endif +ifeq ($(platform), qnx) +retroarch-dev.bar: pkg +ifeq ($(QNX_DEBUGTOKEN),) + blackberry-nativepackager -package $@ -devMode pkg/qnx/bar-descriptor.xml -C pkg/qnx/pkg pkg/qnx/pkg/* +else + blackberry-nativepackager -package $@ -devMode -debugToken $(QNX_DEBUGTOKEN) pkg/qnx/bar-descriptor.xml -C pkg/qnx/pkg pkg/qnx/pkg/* +endif + +retroarch-release.bar: pkg + blackberry-nativepackager -package $@ pkg/qnx/bar-descriptor.xml -C pkg/qnx/pkg pkg/qnx/pkg/* +endif + shaders-checkout: @if test -d $(SHADER_CG_DIR); then \ echo "[SHADER CHECKOUT::] Git pulling common-shaders..."; \ diff --git a/Makefile.libnx b/Makefile.libnx index c3eb990dd1..14da9d7456 100644 --- a/Makefile.libnx +++ b/Makefile.libnx @@ -133,7 +133,7 @@ LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs $(ARCH) -Wl,--allow-multiple-de # add things from Makefile.common CFLAGS += $(DEF_FLAGS) -LIBS := -lswresample -lavformat -lavcodec -lavutil -lswscale -lstdc++ -lbz2 -lpng -lz -lnx -lm +LIBS := -lswresample -lavformat -lavcodec -lavutil -lswscale -lstdc++ -lbz2 -lpng -lz -lnx -lvpx -lopus -llzma -lm ifeq ($(HAVE_OPENGL), 1) LIBS := -lEGL -lglapi -ldrm_nouveau $(LIBS) diff --git a/Makefile.ps2 b/Makefile.ps2 index 05cadc6ab9..9ffe65da9f 100644 --- a/Makefile.ps2 +++ b/Makefile.ps2 @@ -1,19 +1,14 @@ BUILD_FOR_PCSX2 = 0 DEBUG = 0 -HAVE_KERNEL_PRX = 0 HAVE_LOGGER = 0 HAVE_FILE_LOGGER = 0 HAVE_THREADS = 0 -BIG_STACK = 0 MUTE_WARNINGS = 1 PS2_IP = 192.168.1.150 TARGET = retroarchps2.elf TARGET_RELEASE = retroarchps2-release.elf -# Lib CDVD -CDVD_DIR = ps2/libcdvd - # Compile the IRXs first IRX_DIR = ps2/irx IRX_FILES = $(wildcard ps2/irx/*.c) @@ -22,7 +17,7 @@ ifeq ($(DEBUG), 1) OPTIMIZE_LV := -O0 -g RARCH_DEFINES += -DDEBUG else - OPTIMIZE_LV := -O2 + OPTIMIZE_LV := -O3 LDFLAGS := -s endif @@ -30,20 +25,18 @@ ifeq ($(MUTE_WARNINGS), 1) DISABLE_WARNINGS := -Wno-sign-compare -Wno-unused -Wno-parentheses endif -INCDIR = -I$(PS2DEV)/gsKit/include -I$(PS2SDK)/ports/include -I$(CDVD_DIR)/ee -INCDIR += -Ips2 -Ips2/include -Ilibretro-common/include -Ideps -Ideps/stb -Ideps/7zip +INCDIR = -I$(PS2DEV)/gsKit/include -I$(PS2SDK)/ports/include +INCDIR += -Ips2/include -Ilibretro-common/include -Ideps -Ideps/stb -Ideps/7zip INCDIR += -Ideps/pthreads -Ideps/pthreads/platform/ps2 -Ideps/pthreads/platform/helper -GPVAL = -G0 CFLAGS = $(OPTIMIZE_LV) $(DISABLE_WARNINGS) -ffast-math -fsingle-precision-constant ASFLAGS = $(CFLAGS) -RARCH_DEFINES += -DPS2 -DUSE_IOP_CTYPE_MACRO -D_MIPS_ARCH_R5900 -DHAVE_ZLIB -DHAVE_NO_BUILTINZLIB -DHAVE_RPNG -DHAVE_RJPEG -RARCH_DEFINES += -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -DHAVE_CC_RESAMPLER +RARCH_DEFINES += -DPS2 -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_RGUI +RARCH_DEFINES += -DHAVE_ZLIB -DHAVE_NO_BUILTINZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -DHAVE_CC_RESAMPLER -LIBDIR = -LDFLAGS += -L$(PS2SDK)/ports/lib -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ee/lib -L$(CDVD_DIR)/lib -L. -LIBS += -lretro_ps2 -lgskit -ldmakit -lgskit_toolkit -laudsrv -lmf -lpadx -lmtap -lmc -lhdd -lsdl -lfileXio -lz -LIBS += -lcdvdfs -lpatches -lpoweroff +LDFLAGS += -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ports/lib -L. +# Lib cdvd is needed to get proper time +LIBS += -lretro_ps2 -lpatches -lpoweroff -lgskit -ldmakit -laudsrv -lpadx -lmtap -lz -lcdvd ifeq ($(BUILD_FOR_PCSX2), 1) RARCH_DEFINES += -DBUILD_FOR_PCSX2 @@ -57,27 +50,17 @@ ifeq ($(HAVE_FILE_LOGGER), 1) CFLAGS += -DHAVE_FILE_LOGGER endif -ifeq ($(HAVE_KERNEL_PRX), 1) -CFLAGS += -DHAVE_KERNEL_PRX -endif - -ifeq ($(BIG_STACK), 1) -CFLAGS += -DBIG_STACK -endif - CFLAGS += $(RARCH_DEFINES) # All the IRX objects EE_OBJS += $(IRX_DIR)/freemtap_irx.o $(IRX_DIR)/freepad_irx.o $(IRX_DIR)/freesio2_irx.o $(IRX_DIR)/iomanX_irx.o EE_OBJS += $(IRX_DIR)/fileXio_irx.o $(IRX_DIR)/mcman_irx.o $(IRX_DIR)/mcserv_irx.o $(IRX_DIR)/usbd_irx.o EE_OBJS += $(IRX_DIR)/usbhdfsd_irx.o $(IRX_DIR)/freesd_irx.o $(IRX_DIR)/audsrv_irx.o $(IRX_DIR)/poweroff_irx.o -EE_OBJS += $(IRX_DIR)/cdvd_irx.o +EE_OBJS += $(IRX_DIR)/cdfs_irx.o # Missing objecst on the PS2SDK -EE_OBJS += ps2/compat_files/compat_ctype.o ps2/compat_files/time.o ps2/compat_files/ps2_devices.o -EE_OBJS += ps2/compat_files/fileXio_cdvd.o ps2/compat_files/ps2_descriptor.o +EE_OBJS += ps2/compat_files/ps2_devices.o -#EE_OBJS = griffin/griffin.o bootstrap/ps2/kernel_functions.o EE_OBJS += griffin/griffin.o EE_CFLAGS = $(CFLAGS) @@ -106,7 +89,10 @@ prepare: run: ps2client -h $(PS2_IP) execee host:$(EE_BIN) -debug: clean prepare all run +sim: + PCSX2 --elf=$(PWD)/$(EE_BIN) --nogui + +debug: clean all run package: ps2-packer $(EE_BIN) $(TARGET_RELEASE) @@ -115,9 +101,4 @@ release: clean all package #Include preferences include $(PS2SDK)/samples/Makefile.pref -include $(PS2SDK)/samples/Makefile.eeglobal - -#Linking with C++ -$(EE_BIN): $(EE_OBJS) $(PS2SDK)/ee/startup/crt0.o - $(EE_CXX) $(EE_NO_CRT) -T$(PS2SDK)/ee/startup/linkfile $(EE_CXXFLAGS) \ - -o $(EE_BIN) $(PS2SDK)/ee/startup/crt0.o $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(EE_OBJS) $(CRTEND_OBJ) $(CRTN_OBJ) $(EE_LDFLAGS) $(EE_LIBS) +include $(PS2SDK)/samples/Makefile.eeglobal_cpp diff --git a/Makefile.ps3 b/Makefile.ps3 index ae0dd1d281..4ca9937ff9 100644 --- a/Makefile.ps3 +++ b/Makefile.ps3 @@ -70,7 +70,7 @@ endif PPU_SRCS = griffin/griffin.c DEFINES += -DHAVE_VIDEO_LAYOUT -DEFINES += -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_GFX_WIDGETS -DHAVE_RGUI -DHAVE_XMB -DHAVE_OZONE -DHAVE_LIBRETRODB -DHAVE_MATERIALUI -DHAVE_SHADERPIPELINE -DRARCH_INTERNAL -DMSB_FIRST -DHAVE_OVERLAY -DHAVE_CC_RESAMPLER -DHAVE_STB_VORBIS -DHAVE_STB_FONT -DHAVE_RUNAHEAD -DHAVE_DR_MP3 -DHAVE_DR_FLAC +DEFINES += -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_GFX_WIDGETS -DHAVE_RGUI -DHAVE_XMB -DHAVE_OZONE -DHAVE_LIBRETRODB -DHAVE_MATERIALUI -DHAVE_SHADERPIPELINE -DRARCH_INTERNAL -DHAVE_OVERLAY -DHAVE_CC_RESAMPLER -DHAVE_STB_VORBIS -DHAVE_STB_FONT -DHAVE_RUNAHEAD -DHAVE_DR_MP3 -DHAVE_DR_FLAC DEFINES += -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES ifeq ($(DEX_BUILD), 1) diff --git a/Makefile.ps3.salamander b/Makefile.ps3.salamander index 5ef63d2372..09cd045b42 100644 --- a/Makefile.ps3.salamander +++ b/Makefile.ps3.salamander @@ -59,6 +59,7 @@ PPU_SRCS = frontend/frontend_salamander.c \ libretro-common/streams/file_stream.c \ libretro-common/vfs/vfs_implementation.c \ libretro-common/file/config_file.c \ + libretro-common/time/rtime.c \ file_path_str.c \ verbosity.c diff --git a/Makefile.psl1ght b/Makefile.psl1ght index 907d1cbe7c..9ac19921bc 100644 --- a/Makefile.psl1ght +++ b/Makefile.psl1ght @@ -1,29 +1,39 @@ +#------------------------------------------------------------------------------- +# Clear the implicit built in rules +#------------------------------------------------------------------------------- +.SUFFIXES: +#------------------------------------------------------------------------------- +ifeq ($(strip $(PSL1GHT)),) +$(error "Please set PSL1GHT in your environment. export PSL1GHT=") +endif + +include $(PSL1GHT)/ppu_rules + include version.all DEBUG = 0 HAVE_LOGGER = 0 -HAVE_FILE_LOGGER = 0 +HAVE_FILE_LOGGER = 1 PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7" PC_DEVELOPMENT_UDP_PORT = 3490 -CC = $(PS3DEV)/ppu/bin/ppu-gcc -CXX = $(PS3DEV)/ppu/bin/ppu-g++ -LD = $(PS3DEV)/ppu/bin/ppu-ld - -CONTENT_ID_FULL = UP0001-SSNE10000_00-0000000000000001 +CONTENTID = UP0001-SSNE10001_00-0000000000000001 +APPID = SSNE10001 +TITLE = Retroarch PSL1GHT +PACKAGE_BASENAME := retroarch_psl1ght ELF_TARGET := retroarch_psl1ght.elf -EBOOT_PATH = pkg/ps3/USRDIR/EBOOT.BIN -CORE_PATH = pkg/ps3/USRDIR/cores/CORE.SELF +SELF_TARGET := $(ELF_TARGET:.elf=.self) +CORE_PATH = pkg/psl1ght/pkg/USRDIR/cores/CORE.SELF -INCLUDE := -I. -I$(PS3DEV)/ppu/include -Ips3/gcmgl/include/export -Ips3/include -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib -LIBDIRS := -L$(PS3DEV)/ppu/lib -L$(PS3DEV)/portlibs/ppu/lib -L. +INCLUDE += -I. -Ips3/gcmgl/include/export -Ips3/include -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib -Ilibretro-common/include $(LIBPSL1GHT_INC) -Iinclude +LIBDIRS += -L. -MACHDEP := -D__CELLOS_LV2__ -D__PSL1GHT__ +MACHDEP := -D__CELLOS_LV2__ -D__PSL1GHT__ -mcpu=cell CFLAGS += -Wall $(MACHDEP) $(INCLUDE) LDFLAGS := $(MACHDEP) -LIBS := -lrgl_ps3 -lretro_psl1ght -laudio -lrsx -lgcm_sys -lnet -lio -lsysutil -lsysmodule -lm -ljpgdec -lpngdec -llv2 -lnet -lnetctl +LIBS := -lretro_psl1ght -laudio -lrsx -lgcm_sys -lnet -lio -lsysutil -lsysmodule -lm -ljpgdec -lpngdec -llv2 -lnet -lnetctl # system platform system_platform = unix @@ -38,46 +48,10 @@ endif PKG_SCRIPT = tools/ps3/ps3py/pkg.py ifeq ($(shell uname), Linux) -PKG_FINALIZE = package_finalize -MAKE_SELF_WC = make_self_wc -MAKE_SELF = make_self_npdrm -PYTHON2 = python2 GIT = git else -PKG_FINALIZE = package_finalize.exe -MAKE_SELF_WC = make_self_wc.exe -MAKE_SELF = make_self_npdrm.exe -PYTHON2 = python2.exe GIT = git.exe endif -# system platform -system_platform = unix -ifeq ($(shell uname -a),) -EXE_EXT = .exe - system_platform = win -else ifneq ($(findstring Darwin,$(shell uname -a)),) - system_platform = osx -else ifneq ($(findstring MINGW,$(shell uname -a)),) - system_platform = win -endif - -PKG_SCRIPT = tools/ps3/ps3py/pkg.py -ifeq ($(shell uname), Linux) -PKG_FINALIZE = package_finalize -MAKE_SELF_WC = make_self_wc -MAKE_SELF = make_self_npdrm -PYTHON2 = python2 -GIT = git -else -PKG_FINALIZE = package_finalize.exe -MAKE_SELF_WC = make_self_wc.exe -MAKE_SELF = make_self_npdrm.exe -PYTHON2 = python2.exe -GIT = git.exe -endif - -MAKE_FSELF_NPDRM = $(CELL_SDK)/host-win32/bin/make_fself_npdrm.exe -MAKE_PACKAGE_NPDRM = $(CELL_SDK)/host-win32/bin/make_package_npdrm.exe OBJ = griffin/griffin.o @@ -92,7 +66,7 @@ endif SHARED_FLAGS := SHARED_FLAGS += -DHAVE_VIDEO_LAYOUT -SHARED_FLAGS += -DHAVE_MENU -DHAVE_CONFIGFILE -DRARCH_CONSOLE -DHAVE_OPENGL -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_OPENGLES -DHAVE_OPENGLES1 -DHAVE_PSGL -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_GCMGL -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_MOUSE -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_GRIFFIN=1 -DHAVE_NETWORKING=1 -DHAVE_SOCKET_LEGACY=1 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -Wno-char-subscripts -DHAVE_CC_RESAMPLER +SHARED_FLAGS += -DHAVE_MENU -DHAVE_CONFIGFILE -DRARCH_CONSOLE -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_GCMGL -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_MOUSE -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_GRIFFIN=1 -DHAVE_NETWORKING=1 -DHAVE_SOCKET_LEGACY=1 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -Wno-char-subscripts -DHAVE_CC_RESAMPLER -DRARCH_INTERNAL -DHAVE_MULTIMAN -DHAVE_RGUI CFLAGS += -std=gnu99 $(SHARED_FLAGS) CXXFLAGS += $(SHARED_FLAGS) @@ -103,28 +77,18 @@ else CXXFLAGS += -03 -g endif -all: $(ELF_TARGET) +all: $(SELF_TARGET) $(ELF_TARGET): $(OBJ) $(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS) -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< +create-core: $(SELF_TARGET) + cp $(SELF_TARGET) $(CORE_PATH) -%.o: %.cpp - $(CXX) $(CFLAGS) -c -o $@ $< - -create-npdrm-core: - $(MAKE_FSELF_NPDRM) $(ELF_TARGET) $(CORE_PATH) - -create-core: - $(MAKE_SELF_WC) $(ELF_TARGET) $(CORE_PATH) - -pkg: $(ELF_TARGET) create-npdrm-core - $(MAKE_PACKAGE_NPDRM) pkg/ps3/package.conf ps3/pkg - -pkg-signed: $(ELF_TARGET) create-core - $(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(PACKAGE_VERSION).pkg +pkg: create-core + $(PKG) --contentid $(CONTENTID) pkg/psl1ght/pkg/ $(PACKAGE_BASENAME).pkg +# cp $(PACKAGE_BASENAME).pkg $(PACKAGE_BASENAME).gnpdrm.pkg +# $(PACKAGE_FINALIZE) $(PACKAGE_BASENAME).gnpdrm.pkg clean: rm -f $(ELF_TARGET) diff --git a/Makefile.psl1ght.salamander b/Makefile.psl1ght.salamander new file mode 100644 index 0000000000..ef504cbdd5 --- /dev/null +++ b/Makefile.psl1ght.salamander @@ -0,0 +1,120 @@ +#------------------------------------------------------------------------------- +# Clear the implicit built in rules +#------------------------------------------------------------------------------- +.SUFFIXES: +#------------------------------------------------------------------------------- +ifeq ($(strip $(PSL1GHT)),) +$(error "Please set PSL1GHT in your environment. export PSL1GHT=") +endif + +include $(PSL1GHT)/ppu_rules + +include version.all + +DEBUG = 0 +HAVE_LOGGER = 0 +HAVE_FILE_LOGGER = 1 + +PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7" +PC_DEVELOPMENT_UDP_PORT = 3490 + +CONTENTID = UP0001-SSNE10001_00-0000000000000001 +APPID = SSNE10001 +TITLE = Retroarch PSL1GHT +PACKAGE_BASENAME := retroarch_psl1ght + +ELF_TARGET := retroarch_psl1ght_salamander.elf +ELF_TARGET_NONSTRIPPED := retroarch_psl1ght_salamander_nonstripped.elf +EBOOT_PATH = pkg/psl1ght/pkg/USRDIR/EBOOT.BIN + +INCLUDE += -I. -Ips3/gcmgl/include/export -Ips3/include -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib -Ilibretro-common/include $(LIBPSL1GHT_INC) -Iinclude +LIBDIRS += -L. + +MACHDEP := -D__CELLOS_LV2__ -D__PSL1GHT__ -mcpu=cell -mhard-float -fmodulo-sched -ffunction-sections -fdata-sections +CFLAGS += -Wall $(MACHDEP) $(INCLUDE) +LDFLAGS := $(MACHDEP) +LIBS := -lgcm_sys -lrsx -lsysutil -lio -lnet -lsysmodule -lrt -llv2 -lm + +# system platform +system_platform = unix +ifeq ($(shell uname -a),) +EXE_EXT = .exe + system_platform = win +else ifneq ($(findstring Darwin,$(shell uname -a)),) + system_platform = osx +else ifneq ($(findstring MINGW,$(shell uname -a)),) + system_platform = win +endif + +PKG_SCRIPT = tools/ps3/ps3py/pkg.py +ifeq ($(shell uname), Linux) +GIT = git +else +GIT = git.exe +endif + +OBJ = frontend/frontend_salamander.o \ + frontend/frontend_driver.o \ + frontend/drivers/platform_ps3.o \ + libretro-common/file/file_path.o \ + libretro-common/file/file_path_io.o \ + libretro-common/lists/dir_list.o \ + libretro-common/lists/string_list.o \ + libretro-common/file/retro_dirent.o \ + libretro-common/hash/rhash.o \ + libretro-common/string/stdstring.o \ + libretro-common/encodings/encoding_utf.o \ + libretro-common/compat/compat_strl.o \ + libretro-common/compat/compat_strcasestr.o \ + libretro-common/compat/fopen_utf8.o \ + libretro-common/streams/file_stream.o \ + libretro-common/vfs/vfs_implementation.o \ + libretro-common/file/config_file.o \ + libretro-common/time/rtime.c \ + file_path_str.o \ + verbosity.o + +ifeq ($(HAVE_LOGGER), 1) +CFLAGS += -DHAVE_LOGGER +endif + +ifeq ($(HAVE_FILE_LOGGER), 1) +CFLAGS += -DHAVE_FILE_LOGGER +endif + +SHARED_FLAGS := + +SHARED_FLAGS += -DHAVE_VIDEO_LAYOUT +SHARED_FLAGS += -DHAVE_MENU -DHAVE_CONFIGFILE -DRARCH_CONSOLE -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_GCMGL -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_MOUSE -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_GRIFFIN=1 -DHAVE_NETWORKING=1 -DHAVE_SOCKET_LEGACY=1 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -Wno-char-subscripts -DHAVE_CC_RESAMPLER -DHAVE_MULTIMAN -DHAVE_RGUI -DIS_SALAMANDER +CFLAGS += -std=gnu99 $(SHARED_FLAGS) +CXXFLAGS += $(SHARED_FLAGS) + +ifeq ($(DEBUG), 1) + CFLAGS += -O0 -g +else + CFLAGS += -O3 -g + CXXFLAGS += -03 -g +endif + +all: create-salamander + +$(ELF_TARGET_NONSTRIPPED): $(OBJ) + $(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS) + +$(ELF_TARGET): $(ELF_TARGET_NONSTRIPPED) + $(STRIP) $< -o $@ + $(SPRX) $@ + +create-salamander: $(ELF_TARGET) + $(SELF_NPDRM) $(ELF_TARGET) $(EBOOT_PATH) $(CONTENTID) + +pkg: create-salamander + $(PKG) --contentid $(CONTENTID) pkg/psl1ght/pkg/ $(PACKAGE_BASENAME).pkg +# cp $(PACKAGE_BASENAME).pkg $(PACKAGE_BASENAME).gnpdrm.pkg +# $(PACKAGE_FINALIZE) $(PACKAGE_BASENAME).gnpdrm.pkg + +clean: + rm -f $(ELF_TARGET) + rm -f $(OBJ) + +.PHONY: clean diff --git a/Makefile.psp1 b/Makefile.psp1 index 610b12ad22..d59acb3521 100644 --- a/Makefile.psp1 +++ b/Makefile.psp1 @@ -25,7 +25,7 @@ INCDIR = deps deps/stb deps/7zip deps/pthreads deps/pthreads/platform/psp deps/p CFLAGS = $(OPTIMIZE_LV) -G0 -std=gnu99 -ffast-math -fsingle-precision-constant ASFLAGS = $(CFLAGS) -RARCH_DEFINES = -DPSP -D_MIPS_ARCH_ALLEGREX -DHAVE_LANGEXTRA -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -DHAVE_CC_RESAMPLER +RARCH_DEFINES = -DPSP -D_MIPS_ARCH_ALLEGREX -DHAVE_LANGEXTRA -DHAVE_ZLIB -DHAVE_AUDIOMIXER -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -DHAVE_CC_RESAMPLER LIBDIR = LDFLAGS = diff --git a/Makefile.psp1.salamander b/Makefile.psp1.salamander index ce72543fae..ef3f77c3ea 100644 --- a/Makefile.psp1.salamander +++ b/Makefile.psp1.salamander @@ -49,6 +49,7 @@ OBJS = frontend/frontend_salamander.o \ libretro-common/streams/file_stream.o \ libretro-common/vfs/vfs_implementation.o \ libretro-common/hash/rhash.o \ + libretro-common/time/rtime.o \ file_path_str.o \ verbosity.o \ bootstrap/psp1/kernel_functions.o diff --git a/Makefile.vita b/Makefile.vita index 8756c6d69d..fbb85cd20c 100644 --- a/Makefile.vita +++ b/Makefile.vita @@ -1,5 +1,6 @@ TARGET := retroarch_vita DEBUG ?= 0 +HAVE_FILE_LOGGER = 1 GRIFFIN_BUILD = 0 WHOLE_ARCHIVE_LINK = 0 @@ -59,6 +60,7 @@ else RARCH_CONSOLE := 1 HAVE_STATIC_VIDEO_FILTERS = 1 HAVE_STATIC_AUDIO_FILTERS = 1 + HAVE_AUDIOMIXER := 1 ifeq ($(DEBUG), 1) HAVE_NETLOGGER = 1 @@ -86,7 +88,7 @@ AR := $(PREFIX)ar OBJCOPY := $(PREFIX)objcopy STRIP := $(PREFIX)strip NM := $(PREFIX)nm -LD := $(CXX) +LD := $(CC) LIBDIRS := -L. @@ -121,7 +123,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions VITA_LIBS := -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub -lSceAppUtil_stub \ -lSceSysmodule_stub -lSceCtrl_stub -lSceHid_stub -lSceTouch_stub -lSceAudio_stub \ -lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub -lSceMotion_stub \ - -lSceFiber_stub -lSceMotion_stub -lSceAppMgr_stub -lpthread -lpng -lz + -lSceFiber_stub -lSceMotion_stub -lSceAppMgr_stub -lstdc++ -lpthread -lpng -lz LIBS := $(WHOLE_START) -lretro_vita $(WHOLE_END) $(VITA_LIBS) -lm -lc @@ -180,6 +182,10 @@ vpksend: $(TARGET).vpk send: $(TARGET).self curl -T $< ftp://$(PSVITAIP):1337/ux0:/app/$(VITA_TITLE_ID)/eboot.bin +launch: $(TARGET).self + curl -T $< ftp://$(PSVITAIP):1337/ux0:/app/$(VITA_TITLE_ID)/eboot.bin + echo "launch $(VITA_TITLE_ID)" | nc ${PSVITAIP} 1338 + .PHONY: clean all send vpksend .PRECIOUS: %.depend diff --git a/Makefile.vita.salamander b/Makefile.vita.salamander index 7081793bf8..726618d6e1 100644 --- a/Makefile.vita.salamander +++ b/Makefile.vita.salamander @@ -49,6 +49,7 @@ OBJS = frontend/frontend_salamander.o \ libretro-common/streams/file_stream.o \ libretro-common/vfs/vfs_implementation.o \ libretro-common/hash/rhash.o \ + libretro-common/time/rtime.o \ file_path_str.o \ verbosity.o diff --git a/Makefile.wii.salamander b/Makefile.wii.salamander index 81117e7151..933982613d 100644 --- a/Makefile.wii.salamander +++ b/Makefile.wii.salamander @@ -69,6 +69,7 @@ OBJ = frontend/frontend_salamander.o \ libretro-common/compat/compat_strcasestr.o \ libretro-common/compat/fopen_utf8.o \ libretro-common/file/config_file.o \ + libretro-common/time/rtime.o \ file_path_str.o \ verbosity.o \ $(APP_BOOTER_DIR)/app_booter.binobj diff --git a/Makefile.wiiu b/Makefile.wiiu index 2f01f2ffba..9e39411c0a 100644 --- a/Makefile.wiiu +++ b/Makefile.wiiu @@ -67,6 +67,7 @@ ifeq ($(SALAMANDER_BUILD),1) OBJ += libretro-common/streams/file_stream.o OBJ += libretro-common/vfs/vfs_implementation.o OBJ += libretro-common/hash/rhash.o + OBJ += libretro-common/time/rtime.o OBJ += file_path_str.o OBJ += verbosity.o @@ -97,7 +98,7 @@ endif OBJ += gfx/drivers/gx2_shaders/snowflake.o ifeq ($(GRIFFIN_BUILD), 1) - OBJ += griffin/griffin.o + OBJ += griffin/griffin.o griffin/griffin_cpp.o INCDIRS += -Ilibretro-common/include/compat/zlib # for stb, libfat, iosuhax @@ -107,7 +108,7 @@ endif INCDIRS += -Ideps/SPIRV-Cross DEFINES += -DHAVE_AUDIOMIXER - DEFINES += -DHAVE_GRIFFIN=1 -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_RGUI -DHAVE_LIBRETRODB + DEFINES += -DHAVE_GRIFFIN=1 -DHAVE_MENU -DHAVE_GFX_WIDGETS -DHAVE_CONFIGFILE -DHAVE_RGUI -DHAVE_LIBRETRODB DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DHAVE_CC_RESAMPLER DEFINES += -DHAVE_SPIRV_CROSS -DHAVE_SLANG DEFINES += -DHAVE_STB_FONT -DHAVE_STB_VORBIS -DHAVE_LANGEXTRA -DHAVE_LIBRETRODB -DHAVE_NETWORKING -DHAVE_NETPLAYDISCOVERY @@ -122,6 +123,7 @@ endif else HAVE_AUDIOMIXER = 1 HAVE_MENU_COMMON = 1 + HAVE_GFX_WIDGETS = 1 HAVE_RTGA = 1 HAVE_RPNG = 1 HAVE_RJPEG = 1 @@ -163,7 +165,7 @@ OBJ := $(addprefix $(BUILD_DIR)/,$(OBJ)) #----------------------------- # Compile flags -DEFINES += -DWIIU -DMSB_FIRST -D__WUT__ -DHW_WUP -D__wiiu__ +DEFINES += -DWIIU -D__WUT__ -DHW_WUP -D__wiiu__ DEFINES += -DHAVE_MAIN DEFINES += -DRARCH_CONSOLE @@ -184,7 +186,7 @@ CFLAGS := -mcpu=750 -meabi -mhard-float CFLAGS += -ffast-math -Werror=implicit-function-declaration CFLAGS += -ffunction-sections -fdata-sections #CFLAGS += -fomit-frame-pointer -mword-relocations -#CFLAGS += -Wall +CFLAGS += -Wall ifeq ($(DEBUG), 1) CFLAGS += -O0 -g diff --git a/README.md b/README.md index e97dc9c8d0..18384450d3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ [![Build Status](https://travis-ci.org/libretro/RetroArch.svg?branch=master)](https://travis-ci.org/libretro/RetroArch) [![Coverity Scan Build Status](https://scan.coverity.com/projects/8936/badge.svg)](https://scan.coverity.com/projects/retroarch) +[![Crowdin](https://badges.crowdin.net/retroarch/localized.svg)](https://crowdin.com/project/retroarch) # RetroArch @@ -18,7 +19,7 @@ These programs are instantiated as dynamic libraries. We refer to these as "libr ## libretro -[libretro](http://libretro.com) is an API that exposes generic audio/video/input callbacks. +[libretro](https://www.libretro.com) is an API that exposes generic audio/video/input callbacks. A frontend for libretro (such as RetroArch) handles video output, audio output, input and application lifecycle. A libretro core written in portable C or C++ can run seamlessly on many platforms with very little to no porting effort. @@ -33,7 +34,7 @@ Latest binaries are currently hosted on the [buildbot](http://buildbot.libretro. ## Support -To reach developers, either make an issue here on GitHub, make a thread on the [forum](http://www.libretro.com/forums/), chat on [discord](https://discord.gg/C4amCeV), or visit our IRC channel: #retroarch @ irc.freenode.org. You could create a post in [Reddit](https://www.reddit.com/r/RetroArch/) with *Technical Support* flair. +To reach developers, either make an issue here on GitHub, make a thread on the [forum](https://www.libretro.com/forums/), chat on [discord](https://discord.gg/C4amCeV), or visit our IRC channel: #retroarch @ irc.freenode.org. You could create a post in [Reddit](https://www.reddit.com/r/RetroArch/) with *Technical Support* flair. ## Documentation diff --git a/accessibility.h b/accessibility.h index f43107a206..f2fc1651d1 100644 --- a/accessibility.h +++ b/accessibility.h @@ -30,13 +30,4 @@ #include "config.h" #endif - -RETRO_BEGIN_DECLS - -bool is_accessibility_enabled(void); - -bool accessibility_speak_priority(const char* speak_text, int priority); - -RETRO_END_DECLS - #endif diff --git a/audio/drivers/jack.c b/audio/drivers/jack.c index fd68cc8600..053d62b654 100644 --- a/audio/drivers/jack.c +++ b/audio/drivers/jack.c @@ -25,6 +25,7 @@ #include #include +#include "../../configuration.h" #include "../../retroarch.h" #include "../../verbosity.h" @@ -96,13 +97,13 @@ static void shutdown_cb(void *data) #endif } -static int parse_ports(const char *audio_device, - char **dest_ports, const char **jports) +static int parse_ports(char **dest_ports, const char **jports) { int i; char *save = NULL; int parsed = 0; - char *audio_device_cpy = strdup(audio_device); + settings_t *settings = config_get_ptr(); + char *audio_device_cpy = strdup(settings->arrays.audio_device); const char *con = strtok_r(audio_device_cpy, ",", &save); if (con) @@ -203,7 +204,7 @@ static void *ja_init(const char *device, } } - parsed = parse_ports(device, dest_ports, jports); + parsed = parse_ports(dest_ports, jports); if (jack_activate(jd->client) < 0) { diff --git a/audio/drivers/roar.c b/audio/drivers/roar.c index 0980db0bee..da5725763b 100644 --- a/audio/drivers/roar.c +++ b/audio/drivers/roar.c @@ -105,8 +105,11 @@ static bool ra_alive(void *data) static void ra_set_nonblock_state(void *data, bool state) { roar_t *roar = (roar_t*)data; + if (roar_vs_blocking(roar->vss, (state) ? ROAR_VS_FALSE : ROAR_VS_TRUE, NULL) < 0) - fprintf(stderr, "RetroArch [ERROR]: Can't set nonblocking. Will not be able to fast-forward.\n"); + { + RARCH_ERR("Can't set nonblocking. Will not be able to fast-forward.\n"); + } roar->nonblocking = state; } diff --git a/audio/drivers/switch_audio.c b/audio/drivers/switch_audio.c index 4b9a20259c..4716844696 100644 --- a/audio/drivers/switch_audio.c +++ b/audio/drivers/switch_audio.c @@ -106,7 +106,7 @@ static ssize_t switch_audio_write(void *data, const void *buf, size_t size) num = 0; #ifdef HAVE_LIBNX - if (audoutWaitPlayFinish(&swa->current_buffer, &num, U64_MAX) != 0) { } + if (audoutWaitPlayFinish(&swa->current_buffer, &num, UINT64_MAX) != 0) { } #else svcWaitSynchronization(&handle_idx, &swa->event, 1, 33333333); svcResetSignal(swa->event); diff --git a/audio/drivers/switch_audio_compat.h b/audio/drivers/switch_audio_compat.h index 8f9b228376..86b7124b84 100644 --- a/audio/drivers/switch_audio_compat.h +++ b/audio/drivers/switch_audio_compat.h @@ -46,6 +46,10 @@ typedef AudioOutBuffer compat_audio_out_buffer; #define switch_audio_ipc_output_stop(a) audoutStopAudioOut() #define switch_audio_ipc_output_start(a) audoutStartAudioOut() +#ifndef UINT64_MAX +#define UINT64_MAX U64_MAX +#endif + #else /* libtransistor definitions */ diff --git a/audio/drivers/switch_thread_audio.c b/audio/drivers/switch_thread_audio.c index ef1d10864b..5ccc455921 100644 --- a/audio/drivers/switch_thread_audio.c +++ b/audio/drivers/switch_thread_audio.c @@ -86,7 +86,7 @@ static void mainLoop(void* data) if (!released_out_buffer) { #ifdef HAVE_LIBNX - rc = audoutWaitPlayFinish(&released_out_buffer, &released_out_count, U64_MAX); + rc = audoutWaitPlayFinish(&released_out_buffer, &released_out_count, UINT64_MAX); #else uint32_t handle_idx = 0; svcWaitSynchronization(&handle_idx, &swa->event, 1, 33333333); diff --git a/audio/drivers/tinyalsa.c b/audio/drivers/tinyalsa.c index 4344d7a7c8..81ffdcaac8 100644 --- a/audio/drivers/tinyalsa.c +++ b/audio/drivers/tinyalsa.c @@ -1525,7 +1525,7 @@ static struct pcm_params *pcm_params_get(unsigned int card, unsigned int device, fd = open(fn, O_RDWR|O_NONBLOCK); if (fd < 0) { - fprintf(stderr, "cannot open device '%s'\n", fn); + RARCH_ERR("[TINYALSA] Cannot open device '%s'\n", fn); goto err_open; } @@ -1538,7 +1538,7 @@ static struct pcm_params *pcm_params_get(unsigned int card, unsigned int device, param_init(params); if (ioctl(fd, SNDRV_PCM_IOCTL_HW_REFINE, params)) { - fprintf(stderr, "SNDRV_PCM_IOCTL_HW_REFINE error (%d)\n", errno); + RARCH_ERR("[TINYALSA] SNDRV_PCM_IOCTL_HW_REFINE error (%d)\n", errno); goto err_hw_refine; } @@ -2019,7 +2019,7 @@ static int pcm_mmap_transfer(struct pcm *pcm, const void *buffer, unsigned int b avail = pcm_avail_update(pcm); if (avail < 0) { - fprintf(stderr, "cannot determine available mmap frames"); + RARCH_ERR("[TINYALSA] Cannot determine available mmap frames"); return err; } @@ -2029,7 +2029,7 @@ static int pcm_mmap_transfer(struct pcm *pcm, const void *buffer, unsigned int b { if (pcm_start(pcm) < 0) { - fprintf(stderr, "start error: hw 0x%x app 0x%x avail 0x%x\n", + RARCH_ERR("[TINYALSA] Start error: hw 0x%x app 0x%x avail 0x%x\n", (unsigned int)pcm->mmap_status->hw_ptr, (unsigned int)pcm->mmap_control->appl_ptr, avail); @@ -2052,7 +2052,7 @@ static int pcm_mmap_transfer(struct pcm *pcm, const void *buffer, unsigned int b { pcm->prepared = 0; pcm->running = 0; - fprintf(stderr, "wait error: hw 0x%x app 0x%x avail 0x%x\n", + RARCH_ERR("[TINYALSA] Wait error: hw 0x%x app 0x%x avail 0x%x\n", (unsigned int)pcm->mmap_status->hw_ptr, (unsigned int)pcm->mmap_control->appl_ptr, avail); @@ -2073,7 +2073,7 @@ static int pcm_mmap_transfer(struct pcm *pcm, const void *buffer, unsigned int b frames = pcm_mmap_transfer_areas(pcm, (void *)buffer, offset, frames); if (frames < 0) { - fprintf(stderr, "write error: hw 0x%x app 0x%x avail 0x%x\n", + RARCH_ERR("[TINYALSA] Write error: hw 0x%x app 0x%x avail 0x%x\n", (unsigned int)pcm->mmap_status->hw_ptr, (unsigned int)pcm->mmap_control->appl_ptr, avail); diff --git a/camera/drivers/video4linux2.c b/camera/drivers/video4linux2.c index 28e8376cdf..cc5d57110c 100644 --- a/camera/drivers/video4linux2.c +++ b/camera/drivers/video4linux2.c @@ -402,7 +402,7 @@ static bool v4l_poll(void *data, if (preprocess_image(data)) { - if (frame_raw_cb != NULL) + if (frame_raw_cb) frame_raw_cb(v4l->buffer_output, v4l->width, v4l->height, v4l->width * 4); return true; diff --git a/cheevos-new/fixup.c b/cheevos-new/fixup.c deleted file mode 100644 index 08d7ca823d..0000000000 --- a/cheevos-new/fixup.c +++ /dev/null @@ -1,301 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2015-2018 - Andre Leiradella - * - * 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 "fixup.h" -#include "cheevos.h" -#include "util.h" - -#include "../retroarch.h" -#include "../core.h" - -#include "../deps/rcheevos/include/rcheevos.h" - -static int rcheevos_cmpaddr(const void* e1, const void* e2) -{ - const rcheevos_fixup_t* f1 = (const rcheevos_fixup_t*)e1; - const rcheevos_fixup_t* f2 = (const rcheevos_fixup_t*)e2; - - if (f1->address < f2->address) - { - return -1; - } - else if (f1->address > f2->address) - { - return 1; - } - else - { - return 0; - } -} - -static size_t rcheevos_var_reduce(size_t addr, size_t mask) -{ - while (mask) - { - size_t tmp = (mask - 1) & ~mask; - addr = (addr & tmp) | ((addr >> 1) & ~tmp); - mask = (mask & (mask - 1)) >> 1; - } - - return addr; -} - -static size_t rcheevos_var_highest_bit(size_t n) -{ - n |= n >> 1; - n |= n >> 2; - n |= n >> 4; - n |= n >> 8; - n |= n >> 16; - - return n ^ (n >> 1); -} - -void rcheevos_fixup_init(rcheevos_fixups_t* fixups) -{ - fixups->elements = NULL; - fixups->capacity = fixups->count = 0; - fixups->dirty = false; -} - -void rcheevos_fixup_destroy(rcheevos_fixups_t* fixups) -{ - CHEEVOS_FREE(fixups->elements); - rcheevos_fixup_init(fixups); -} - -const uint8_t* rcheevos_fixup_find(rcheevos_fixups_t* fixups, unsigned address, int console) -{ - rcheevos_fixup_t key; - rcheevos_fixup_t* found; - const uint8_t* location; - - if (fixups->dirty) - { - qsort(fixups->elements, fixups->count, sizeof(rcheevos_fixup_t), rcheevos_cmpaddr); - fixups->dirty = false; - } - - key.address = address; - found = (rcheevos_fixup_t*)bsearch(&key, fixups->elements, fixups->count, sizeof(rcheevos_fixup_t), rcheevos_cmpaddr); - - if (found != NULL) - { - return found->location; - } - - if (fixups->count == fixups->capacity) - { - unsigned new_capacity = fixups->capacity == 0 ? 16 : fixups->capacity * 2; - rcheevos_fixup_t* new_elements = (rcheevos_fixup_t*) - realloc(fixups->elements, new_capacity * sizeof(rcheevos_fixup_t)); - - if (new_elements == NULL) - { - return NULL; - } - - fixups->elements = new_elements; - fixups->capacity = new_capacity; - } - - fixups->elements[fixups->count].address = address; - fixups->elements[fixups->count++].location = location = - rcheevos_patch_address(address, console); - fixups->dirty = true; - - return location; -} - -const uint8_t* rcheevos_patch_address(unsigned address, int console) -{ - rarch_system_info_t* system = runloop_get_system_info(); - const void* pointer = NULL; - unsigned original_address = address; - - if (console == RC_CONSOLE_NINTENDO) - { - if (address >= 0x0800 && address < 0x2000) - { - /* Address in the mirrorred RAM, adjust to real RAM. */ - CHEEVOS_LOG(RCHEEVOS_TAG "NES memory address in mirrorred RAM %X, adjusted to %X\n", address, address & 0x07ff); - address &= 0x07ff; - } - } - else if (console == RC_CONSOLE_GAMEBOY_COLOR) - { - if (address >= 0xe000 && address <= 0xfdff) - { - /* Address in the echo RAM, adjust to real RAM. */ - CHEEVOS_LOG(RCHEEVOS_TAG "GBC memory address in echo RAM %X, adjusted to %X\n", address, address - 0x2000); - address -= 0x2000; - } - } - - if (system->mmaps.num_descriptors != 0) - { - /* We have memory descriptors, use it. */ - const rarch_memory_descriptor_t* desc = NULL; - const rarch_memory_descriptor_t* end = NULL; - - /* Patch the address to correctly map it to the mmaps. */ - if (console == RC_CONSOLE_GAMEBOY_ADVANCE) - { - if (address < 0x8000) - { - /* Internal RAM. */ - CHEEVOS_LOG(RCHEEVOS_TAG "GBA memory address %X adjusted to %X\n", address, address + 0x3000000); - address += 0x3000000; - } - else - { - /* Work RAM. */ - CHEEVOS_LOG(RCHEEVOS_TAG "GBA memory address %X adjusted to %X\n", address, address + 0x2000000 - 0x8000); - address += 0x2000000 - 0x8000; - } - } - else if (console == RC_CONSOLE_PC_ENGINE) - { - if (address < 0x002000) - { - /* RAM. */ - CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x1f0000); - address += 0x1f0000; - } - else if (address < 0x012000) - { - /* CD-ROM RAM. */ - CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x100000 - 0x002000); - address += 0x100000 - 0x002000; - } - else if (address < 0x042000) - { - /* Super System Card RAM. */ - CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x0d0000 - 0x012000); - address += 0x0d0000 - 0x012000; - } - else - { - /* CD-ROM battery backed RAM. */ - CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x1ee000 - 0x042000); - address += 0x1ee000 - 0x042000; - } - } - else if (console == RC_CONSOLE_SUPER_NINTENDO) - { - if (address < 0x020000) - { - /* Work RAM. */ - CHEEVOS_LOG(RCHEEVOS_TAG "SNES memory address %X adjusted to %X\n", address, address + 0x7e0000); - address += 0x7e0000; - } - else - { - /* Save RAM. */ - CHEEVOS_LOG(RCHEEVOS_TAG "SNES memory address %X adjusted to %X\n", address, address + 0x006000 - 0x020000); - address += 0x006000 - 0x020000; - } - } - else if (console == RC_CONSOLE_SEGA_CD) - { - if (address < 0x010000) - { - /* Work RAM. */ - address += 0xFF0000; - CHEEVOS_LOG(RCHEEVOS_TAG "Sega CD memory address %X adjusted to %X\n", original_address, address); - } - else - { - /* CD-ROM peripheral RAM - exposed at virtual address to avoid banking */ - address += 0x80020000 - 0x010000; - CHEEVOS_LOG(RCHEEVOS_TAG "Sega CD memory address %X adjusted to %X\n", original_address, address); - } - } - - desc = system->mmaps.descriptors; - end = desc + system->mmaps.num_descriptors; - - for (; desc < end; desc++) - { - if (((desc->core.start ^ address) & desc->core.select) == 0) - { - pointer = desc->core.ptr; - address -= desc->core.start; - - if (desc->disconnect_mask) - address = (unsigned)rcheevos_var_reduce(address & desc->disconnect_mask, desc->core.disconnect); - - if (address >= desc->core.len) - address -= rcheevos_var_highest_bit(address); - - address += desc->core.offset; - - CHEEVOS_LOG(RCHEEVOS_TAG "address %X set to descriptor %d at offset %X\n", original_address, (int)((desc - system->mmaps.descriptors) + 1), address); - break; - } - } - } - else - { - unsigned i; - - for (i = 0; i < 4; i++) - { - retro_ctx_memory_info_t meminfo; - - switch (i) - { - case 0: - meminfo.id = RETRO_MEMORY_SYSTEM_RAM; - break; - case 1: - meminfo.id = RETRO_MEMORY_SAVE_RAM; - break; - case 2: - meminfo.id = RETRO_MEMORY_VIDEO_RAM; - break; - case 3: - meminfo.id = RETRO_MEMORY_RTC; - break; - } - - core_get_memory(&meminfo); - - if (address < meminfo.size) - { - pointer = meminfo.data; - break; - } - - /** - * HACK Subtract the correct amount of bytes to reach the save RAM as - * it's size is not always set correctly in the core. - */ - if (i == 0 && console == RC_CONSOLE_NINTENDO) - address -= 0x6000; - else - address -= meminfo.size; - } - } - - if (pointer == NULL) - { - CHEEVOS_LOG(RCHEEVOS_TAG "address %X not supported\n", original_address); - return NULL; - } - - return (const uint8_t*)pointer + address; -} diff --git a/cheevos-new/badges.c b/cheevos/badges.c similarity index 83% rename from cheevos-new/badges.c rename to cheevos/badges.c index 627363198d..a04c55df9a 100644 --- a/cheevos-new/badges.c +++ b/cheevos/badges.c @@ -24,6 +24,7 @@ #ifdef HAVE_MENU #define CHEEVOS_MENU_BADGE_LIMIT 256 +/* TODO/FIXME - public global variables */ static uintptr_t cheevos_badge_menu_texture_list[CHEEVOS_MENU_BADGE_LIMIT] = { 0 }; void cheevos_reset_menu_badges(void) @@ -54,7 +55,7 @@ void cheevos_set_menu_badge(int index, const char *badge, bool locked) uintptr_t cheevos_get_menu_badge_texture(int index) { if (index < CHEEVOS_MENU_BADGE_LIMIT) - return cheevos_badge_menu_texture_list[index]; + return cheevos_badge_menu_texture_list[index]; return 0; } @@ -65,19 +66,23 @@ uintptr_t cheevos_get_badge_texture(const char *badge, bool locked) { char badge_file[24]; char fullpath[PATH_MAX_LENGTH]; - uintptr_t tex; + uintptr_t tex = 0; if (!badge) return 0; - snprintf(badge_file, sizeof(badge_file), "%s%s.png", badge, locked ? "_lock" : ""); + strlcpy(badge_file, badge, sizeof(badge_file)); + if (locked) + strlcat(badge_file, "_lock", sizeof(badge_file)); + strlcat(badge_file, ".png", sizeof(badge_file)); fill_pathname_application_special(fullpath, PATH_MAX_LENGTH * sizeof(char), APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES); - gfx_display_reset_textures_list(badge_file, fullpath, - &tex, TEXTURE_FILTER_MIPMAP_LINEAR, NULL, NULL); + if (!gfx_display_reset_textures_list(badge_file, fullpath, + &tex, TEXTURE_FILTER_MIPMAP_LINEAR, NULL, NULL)) + tex = 0; return tex; } diff --git a/cheevos-new/badges.h b/cheevos/badges.h similarity index 100% rename from cheevos-new/badges.h rename to cheevos/badges.h diff --git a/cheevos-new/cheevos.c b/cheevos/cheevos.c similarity index 58% rename from cheevos-new/cheevos.c rename to cheevos/cheevos.c index 3520c94427..06d8936a0f 100644 --- a/cheevos-new/cheevos.c +++ b/cheevos/cheevos.c @@ -22,8 +22,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -47,7 +47,7 @@ #endif #ifdef HAVE_DISCORD -#include "../discord/discord.h" +#include "../network/discord.h" #endif #include "badges.h" @@ -74,6 +74,7 @@ #include "../deps/rcheevos/include/rcheevos.h" #include "../deps/rcheevos/include/rurl.h" +#include "../deps/rcheevos/include/rhash.h" /* Define this macro to prevent cheevos from being deactivated. */ #undef CHEEVOS_DONT_DEACTIVATE @@ -81,9 +82,6 @@ /* Define this macro to dump all cheevos' addresses. */ #undef CHEEVOS_DUMP_ADDRS -/* Define this macro to remove HTTP timeouts. */ -#undef CHEEVOS_NO_TIMEOUT - /* Define this macro to load a JSON file from disk instead of downloading * from retroachievements.org. */ #undef CHEEVOS_JSON_OVERRIDE @@ -92,7 +90,7 @@ * that name. */ #undef CHEEVOS_SAVE_JSON - /* Define this macro to log URLs. */ +/* Define this macro to log URLs. */ #undef CHEEVOS_LOG_URLS /* Define this macro to have the password and token logged. THIS WILL DISCLOSE @@ -102,10 +100,20 @@ /* Define this macro to log downloaded badge images. */ #undef CHEEVOS_LOG_BADGES +/* Define this macro to capture how long it takes to generate a hash */ +#undef CHEEVOS_TIME_HASH + /* Number of usecs to wait between posting rich presence to the site. */ /* Keep consistent with SERVER_PING_FREQUENCY from RAIntegration. */ #define CHEEVOS_PING_FREQUENCY 2 * 60 * 1000000 +enum rcheevos_async_io_type +{ + CHEEVOS_ASYNC_RICHPRESENCE, + CHEEVOS_ASYNC_AWARD_ACHIEVEMENT, + CHEEVOS_ASYNC_SUBMIT_LBOARD +}; + typedef struct { rc_trigger_t* trigger; @@ -130,13 +138,6 @@ typedef struct retro_time_t last_update; } rcheevos_richpresence_t; -enum rcheevos_async_io_type -{ - CHEEVOS_ASYNC_RICHPRESENCE, - CHEEVOS_ASYNC_AWARD_ACHIEVEMENT, - CHEEVOS_ASYNC_SUBMIT_LBOARD -}; - typedef struct rcheevos_async_io_request { int id; @@ -171,23 +172,6 @@ typedef struct char hash[33]; } rcheevos_locals_t; -typedef struct -{ - int label; - const char* name; - const uint32_t* ext_hashes; -} rcheevos_finder_t; - -typedef struct -{ - uint8_t id[4]; /* NES^Z */ - uint8_t rom_size; - uint8_t vrom_size; - uint8_t rom_type; - uint8_t rom_type2; - uint8_t reserve[8]; -} rcheevos_nes_header_t; - static rcheevos_locals_t rcheevos_locals = { NULL, /* task */ @@ -206,12 +190,11 @@ static rcheevos_locals_t rcheevos_locals = "N/A",/* hash */ }; -bool rcheevos_loaded = false; -bool rcheevos_hardcore_active = false; -bool rcheevos_hardcore_paused = false; -bool rcheevos_state_loaded_flag = false; -int rcheevos_cheats_are_enabled = 0; -int rcheevos_cheats_were_enabled = 0; +/* TODO/FIXME - public global variables */ +bool rcheevos_loaded = false; +bool rcheevos_hardcore_active = false; +bool rcheevos_hardcore_paused = false; +bool rcheevos_state_loaded_flag = false; char rcheevos_user_agent_prefix[128] = ""; #ifdef HAVE_THREADS @@ -229,12 +212,10 @@ Supporting functions. *****************************************************************************/ #ifndef CHEEVOS_VERBOSE - void rcheevos_log(const char *fmt, ...) { (void)fmt; } - #endif static void rcheevos_get_user_agent(char* buffer) @@ -282,9 +263,7 @@ static void rcheevos_get_user_agent(char* buffer) ++scan; } else - { *ptr++ = *scan++; - } } } @@ -301,9 +280,7 @@ static void rcheevos_get_user_agent(char* buffer) ++scan; } else - { *ptr++ = *scan++; - } } } } @@ -311,88 +288,188 @@ static void rcheevos_get_user_agent(char* buffer) *ptr = '\0'; } -static void rcheevos_log_url(const char* format, const char* url) +#ifdef CHEEVOS_LOG_URLS +static void rcheevos_filter_url_param(char* url, char* param) +{ + char *next; + size_t param_len = strlen(param); + char *start = strchr(url, '?'); + if (!start) + start = url; + else + ++start; + + do + { + next = strchr(start, '&'); + + if (start[param_len] == '=' && memcmp(start, param, param_len) == 0) + { + if (next) + strcpy(start, next + 1); + else if (start > url) + start[-1] = '\0'; + else + *start = '\0'; + + return; + } + + if (!next) + return; + + start = next + 1; + } while (1); +} +#endif + +static void rcheevos_log_url(const char* api, const char* url) { #ifdef CHEEVOS_LOG_URLS -#ifdef CHEEVOS_LOG_PASSWORD - CHEEVOS_LOG(format, url); -#else + #ifdef CHEEVOS_LOG_PASSWORD + CHEEVOS_LOG(RCHEEVOS_TAG "%s: %s\n", api, url); + #else char copy[256]; - char* aux = NULL; - char* next = NULL; - - if (!string_is_empty(url)) - strlcpy(copy, url, sizeof(copy)); - - aux = strstr(copy, "?p="); - - if (!aux) - aux = strstr(copy, "&p="); - - if (aux) - { - aux += 3; - next = strchr(aux, '&'); - - if (next) - { - do - { - *aux++ = *next++; - } while (next[-1] != 0); - } - else - *aux = 0; - } - - aux = strstr(copy, "?t="); - - if (!aux) - aux = strstr(copy, "&t="); - - if (aux) - { - aux += 3; - next = strchr(aux, '&'); - - if (next) - { - do - { - *aux++ = *next++; - } while (next[-1] != 0); - } - else - *aux = 0; - } - - CHEEVOS_LOG(format, copy); -#endif + strlcpy(copy, url, sizeof(copy)); + rcheevos_filter_url_param(copy, "p"); + rcheevos_filter_url_param(copy, "t"); + CHEEVOS_LOG(RCHEEVOS_TAG "%s: %s\n", api, copy); + #endif #else - (void)format; + (void)api; (void)url; #endif } -static retro_time_t rcheevos_async_send_rich_presence(rcheevos_async_io_request* request); +static void rcheevos_log_post_url( + const char* api, + const char* url, + const char* post) +{ +#ifdef CHEEVOS_LOG_URLS + #ifdef CHEEVOS_LOG_PASSWORD + if (post && post[0]) + CHEEVOS_LOG(RCHEEVOS_TAG "%s: %s&%s\n", api, url, post); + else + CHEEVOS_LOG(RCHEEVOS_TAG "%s: %s\n", api, url); + #else + if (post && post[0]) + { + char post_copy[2048]; + strlcpy(post_copy, post, sizeof(post_copy)); + rcheevos_filter_url_param(post_copy, "p"); + rcheevos_filter_url_param(post_copy, "t"); + + if (post_copy[0]) + CHEEVOS_LOG(RCHEEVOS_TAG "%s: %s&%s\n", api, url, post_copy); + else + CHEEVOS_LOG(RCHEEVOS_TAG "%s: %s\n", api, url); + } + else + { + CHEEVOS_LOG(RCHEEVOS_TAG "%s: %s\n", api, url); + } + #endif +#else + (void)api; + (void)url; + (void)post; +#endif +} + +static unsigned rcheevos_peek(unsigned address, unsigned num_bytes, void* ud) +{ + const uint8_t* data = rcheevos_fixup_find(&rcheevos_locals.fixups, + address, rcheevos_locals.patchdata.console_id); + unsigned value = 0; + + if (data) + { + switch (num_bytes) + { + case 4: + value |= data[2] << 16 | data[3] << 24; + case 2: + value |= data[1] << 8; + case 1: + value |= data[0]; + } + } + else + rcheevos_locals.invalid_peek_address = true; + + return value; +} + + static void rcheevos_async_award_achievement(rcheevos_async_io_request* request); static void rcheevos_async_submit_lboard(rcheevos_async_io_request* request); +static retro_time_t rcheevos_async_send_rich_presence( + rcheevos_async_io_request* request) +{ + settings_t *settings = config_get_ptr(); + const char *cheevos_username = settings->arrays.cheevos_username; + bool cheevos_richpresence_enable = settings->bools.cheevos_richpresence_enable; + + if (cheevos_richpresence_enable && rcheevos_locals.richpresence.richpresence) + { + rc_evaluate_richpresence(rcheevos_locals.richpresence.richpresence, + rcheevos_locals.richpresence.evaluation, + sizeof(rcheevos_locals.richpresence.evaluation), rcheevos_peek, NULL, NULL); + } + + { + char url[256], post_data[1024]; + int ret = rc_url_ping(url, sizeof(url), post_data, sizeof(post_data), + cheevos_username, rcheevos_locals.token, rcheevos_locals.patchdata.game_id, + rcheevos_locals.richpresence.evaluation); + + if (ret < 0) + { + CHEEVOS_ERR(RCHEEVOS_TAG "buffer too small to create URL\n"); + } + else + { + rcheevos_log_post_url("rc_url_ping", url, post_data); + + rcheevos_get_user_agent(request->user_agent); + task_push_http_post_transfer_with_user_agent(url, post_data, true, "POST", request->user_agent, NULL, NULL); + } + } + +#ifdef HAVE_DISCORD + if (rcheevos_locals.richpresence.evaluation[0]) + { + if (settings->bools.discord_enable + && discord_is_ready()) + discord_update(DISCORD_PRESENCE_RETROACHIEVEMENTS, false); + } +#endif + + /* Update rich presence every two minutes */ + if (settings->bools.cheevos_richpresence_enable) + return cpu_features_get_time_usec() + CHEEVOS_PING_FREQUENCY; + + /* Send ping every four minutes */ + return cpu_features_get_time_usec() + CHEEVOS_PING_FREQUENCY * 2; +} + static void rcheevos_async_task_handler(retro_task_t* task) { - rcheevos_async_io_request* request = (rcheevos_async_io_request*)task->user_data; + rcheevos_async_io_request* request = (rcheevos_async_io_request*) + task->user_data; switch (request->type) { case CHEEVOS_ASYNC_RICHPRESENCE: + /* update the task to fire again in two minutes */ if (request->id == (int)rcheevos_locals.patchdata.game_id) - { - /* update the task to fire again in two minutes */ task->when = rcheevos_async_send_rich_presence(request); - } else { - /* game changed; stop the recurring task - a new one will be scheduled for the next game */ + /* game changed; stop the recurring task - a new one will + * be scheduled for the next game */ task_set_finished(task, 1); free(request); } @@ -410,23 +487,55 @@ static void rcheevos_async_task_handler(retro_task_t* task) } } -static void rcheevos_async_schedule(rcheevos_async_io_request* request, retro_time_t delay) +static void rcheevos_async_schedule( + rcheevos_async_io_request* request, retro_time_t delay) { retro_task_t* task = task_init(); - task->when = cpu_features_get_time_usec() + delay; - task->handler = rcheevos_async_task_handler; - task->user_data = request; - task->progress = -1; + task->when = cpu_features_get_time_usec() + delay; + task->handler = rcheevos_async_task_handler; + task->user_data = request; + task->progress = -1; task_queue_push(task); } -static void rcheevos_async_task_callback(retro_task_t* task, void* task_data, void* user_data, const char* error) +static void rcheevos_async_task_callback( + retro_task_t* task, void* task_data, void* user_data, const char* error) { rcheevos_async_io_request* request = (rcheevos_async_io_request*)user_data; if (!error) { - CHEEVOS_LOG(RCHEEVOS_TAG "%s %u\n", request->success_message, request->id); + char buffer[224]; + const http_transfer_data_t* data = (http_transfer_data_t*)task->task_data; + if (rcheevos_get_json_error(data->data, buffer, sizeof(buffer)) == RC_OK) + { + char errbuf[256]; + snprintf(errbuf, sizeof(errbuf), "%s %u: %s", request->failure_message, request->id, buffer); + CHEEVOS_LOG(RCHEEVOS_TAG "%s\n", errbuf); + + switch (request->type) + { + case CHEEVOS_ASYNC_RICHPRESENCE: + /* don't bother informing user when rich presence update fails */ + break; + + case CHEEVOS_ASYNC_AWARD_ACHIEVEMENT: + /* ignore already unlocked */ + if (string_starts_with(buffer, "User already has ")) + break; + /* fallthrough to default */ + + default: + runloop_msg_queue_push(errbuf, 0, 5 * 60, false, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR); + break; + } + } + else + { + CHEEVOS_LOG(RCHEEVOS_TAG "%s %u\n", request->success_message, request->id); + } + free(request); } else @@ -442,39 +551,6 @@ static void rcheevos_async_task_callback(retro_task_t* task, void* task_data, vo } } -static const char* rcheevos_rc_error(int ret) -{ - switch (ret) - { - case RC_OK: return "Ok"; - case RC_INVALID_LUA_OPERAND: return "Invalid Lua operand"; - case RC_INVALID_MEMORY_OPERAND: return "Invalid memory operand"; - case RC_INVALID_CONST_OPERAND: return "Invalid constant operand"; - case RC_INVALID_FP_OPERAND: return "Invalid floating-point operand"; - case RC_INVALID_CONDITION_TYPE: return "Invalid condition type"; - case RC_INVALID_OPERATOR: return "Invalid operator"; - case RC_INVALID_REQUIRED_HITS: return "Invalid required hits"; - case RC_DUPLICATED_START: return "Duplicated start condition"; - case RC_DUPLICATED_CANCEL: return "Duplicated cancel condition"; - case RC_DUPLICATED_SUBMIT: return "Duplicated submit condition"; - case RC_DUPLICATED_VALUE: return "Duplicated value expression"; - case RC_DUPLICATED_PROGRESS: return "Duplicated progress expression"; - case RC_MISSING_START: return "Missing start condition"; - case RC_MISSING_CANCEL: return "Missing cancel condition"; - case RC_MISSING_SUBMIT: return "Missing submit condition"; - case RC_MISSING_VALUE: return "Missing value expression"; - case RC_INVALID_LBOARD_FIELD: return "Invalid field in leaderboard"; - case RC_MISSING_DISPLAY_STRING: return "Missing display string"; - case RC_OUT_OF_MEMORY: return "Out of memory"; - case RC_INVALID_VALUE_FLAG: return "Invalid flag in value expression"; - case RC_MISSING_VALUE_MEASURED: return "Missing measured flag in value expression"; - case RC_MULTIPLE_MEASURED: return "Multiple measured targets"; - case RC_INVALID_MEASURED_TARGET: return "Invalid measured target"; - - default: return "Unknown error"; - } -} - static int rcheevos_parse(const char* json) { char buffer[256]; @@ -510,30 +586,38 @@ static int rcheevos_parse(const char* json) && rcheevos_locals.patchdata.unofficial_count == 0 && rcheevos_locals.patchdata.lboard_count == 0) { - rcheevos_locals.core = NULL; - rcheevos_locals.unofficial = NULL; - rcheevos_locals.lboards = NULL; + rcheevos_locals.core = NULL; + rcheevos_locals.unofficial = NULL; + rcheevos_locals.lboards = NULL; rcheevos_locals.richpresence.richpresence = NULL; rcheevos_free_patchdata(&rcheevos_locals.patchdata); return 0; } - /* Achievement memory accesses are 0-based, regardless of where the memory is accessed by the - * emulated code. As such, address 0 should always be accessible and serves as an indicator that - * other addresses will also be accessible. Individual achievements will be "Unsupported" if - * they contain addresses that cannot be resolved. This check gives the user immediate feedback - * if the core they're trying to use will disable all achievements as "Unsupported". + /* Achievement memory accesses are 0-based, regardless of + * where the memory is accessed by the + * emulated code. As such, address 0 should always be + * accessible and serves as an indicator that + * other addresses will also be accessible. + * Individual achievements will be "Unsupported" if + * they contain addresses that cannot be resolved. + * This check gives the user immediate feedback + * if the core they're trying to use will disable all + * achievements as "Unsupported". */ if (!rcheevos_patch_address(0, rcheevos_locals.patchdata.console_id)) { - int delay_judgment = 0; - + int delay_judgment = 0; rarch_system_info_t* system = runloop_get_system_info(); + if (system->mmaps.num_descriptors == 0) { - /* Special case: the mupen64plus-nx core doesn't initialize the RAM immediately. To avoid a race - * condition - if the core says there's SYSTEM_RAM, but the pointer is NULL, proceed. If the memory - * isn't exposed when the achievements start processing, they'll be marked "Unsupported" individually. + /* Special case: the mupen64plus-nx core doesn't + * initialize the RAM immediately. To avoid a race + * condition - if the core says there's SYSTEM_RAM, + * but the pointer is NULL, proceed. If the memory + * isn't exposed when the achievements start processing, + * they'll be marked "Unsupported" individually. */ retro_ctx_memory_info_t meminfo; meminfo.id = RETRO_MEMORY_SYSTEM_RAM; @@ -543,10 +627,14 @@ static int rcheevos_parse(const char* json) } else { - /* Special case: the sameboy core exposes the RAM at $8000, but not the ROM at $0000. NES and - * Gameboy achievements do attempt to map the entire bus, and it's unlikely that an achievement - * will reference the ROM data, so if the RAM is still present, allow the core to load. If any - * achievements do reference the ROM data, they'll be marked "Unsupported" individually. + /* Special case: the sameboy core exposes the RAM + * at $8000, but not the ROM at $0000. NES and + * Gameboy achievements do attempt to map the + * entire bus, and it's unlikely that an achievement + * will reference the ROM data, so if the RAM is + * still present, allow the core to load. If any + * achievements do reference the ROM data, they'll + * be marked "Unsupported" individually. */ delay_judgment |= (rcheevos_patch_address(0x8000, rcheevos_locals.patchdata.console_id) != NULL); } @@ -599,20 +687,21 @@ static int rcheevos_parse(const char* json) for (j = 0; j < count; j++, cheevo++, rac++) { cheevo->info = rac; - res = rc_trigger_size(cheevo->info->memaddr); + res = rc_trigger_size(cheevo->info->memaddr); if (res < 0) { - snprintf(buffer, sizeof(buffer), "Error in achievement %d \"%s\": %s", - cheevo->info->id, cheevo->info->title, rcheevos_rc_error(res)); + snprintf(buffer, sizeof(buffer), + "Error in achievement %d \"%s\": %s", + cheevo->info->id, cheevo->info->title, rc_error_str(res)); if (settings->bools.cheevos_verbose_enable) runloop_msg_queue_push(buffer, 0, 4 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); CHEEVOS_ERR(RCHEEVOS_TAG "%s: mem %s\n", buffer, cheevo->info->memaddr); cheevo->trigger = NULL; - cheevo->active = 0; - cheevo->last = 1; + cheevo->active = 0; + cheevo->last = 1; continue; } @@ -626,7 +715,7 @@ static int rcheevos_parse(const char* json) rc_parse_trigger(cheevo->trigger, cheevo->info->memaddr, NULL, 0); cheevo->active = RCHEEVOS_ACTIVE_SOFTCORE | RCHEEVOS_ACTIVE_HARDCORE; - cheevo->last = 1; + cheevo->last = 1; } } @@ -636,12 +725,13 @@ static int rcheevos_parse(const char* json) for (j = 0; j < count; j++, lboard++) { lboard->info = rcheevos_locals.patchdata.lboards + j; - res = rc_lboard_size(lboard->info->mem); + res = rc_lboard_size(lboard->info->mem); if (res < 0) { - snprintf(buffer, sizeof(buffer), "Error in leaderboard %d \"%s\": %s", - lboard->info->id, lboard->info->title, rcheevos_rc_error(res)); + snprintf(buffer, sizeof(buffer), + "Error in leaderboard %d \"%s\": %s", + lboard->info->id, lboard->info->title, rc_error_str(res)); if (settings->bools.cheevos_verbose_enable) runloop_msg_queue_push(buffer, 0, 4 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); @@ -661,9 +751,9 @@ static int rcheevos_parse(const char* json) rc_parse_lboard(lboard->lboard, lboard->info->mem, NULL, 0); - lboard->active = false; + lboard->active = false; lboard->last_value = 0; - lboard->format = rc_parse_format(lboard->info->format); + lboard->format = rc_parse_format(lboard->info->format); } if (rcheevos_locals.patchdata.richpresence_script && *rcheevos_locals.patchdata.richpresence_script) @@ -671,7 +761,9 @@ static int rcheevos_parse(const char* json) int buffer_size = rc_richpresence_size(rcheevos_locals.patchdata.richpresence_script); if (buffer_size <= 0) { - snprintf(buffer, sizeof(buffer), "Error in rich presence: %s", rcheevos_rc_error(buffer_size)); + snprintf(buffer, sizeof(buffer), + "Error in rich presence: %s", + rc_error_str(buffer_size)); if (settings->bools.cheevos_verbose_enable) runloop_msg_queue_push(buffer, 0, 4 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); @@ -689,16 +781,16 @@ static int rcheevos_parse(const char* json) } if (!rcheevos_locals.richpresence.richpresence && rcheevos_locals.patchdata.title) - { - snprintf(rcheevos_locals.richpresence.evaluation, sizeof(rcheevos_locals.richpresence.evaluation), + snprintf(rcheevos_locals.richpresence.evaluation, + sizeof(rcheevos_locals.richpresence.evaluation), "Playing %s", rcheevos_locals.patchdata.title); - } /* schedule the first rich presence call in 30 seconds */ { - rcheevos_async_io_request* request = (rcheevos_async_io_request*)calloc(1, sizeof(rcheevos_async_io_request)); - request->id = rcheevos_locals.patchdata.game_id; - request->type = CHEEVOS_ASYNC_RICHPRESENCE; + rcheevos_async_io_request* request = (rcheevos_async_io_request*) + calloc(1, sizeof(rcheevos_async_io_request)); + request->id = rcheevos_locals.patchdata.game_id; + request->type = CHEEVOS_ASYNC_RICHPRESENCE; rcheevos_async_schedule(request, CHEEVOS_PING_FREQUENCY / 4); } @@ -713,15 +805,11 @@ error: return -1; } -/***************************************************************************** -Test all the achievements (call once per frame). -*****************************************************************************/ - static void rcheevos_async_award_achievement(rcheevos_async_io_request* request) { char buffer[256]; settings_t *settings = config_get_ptr(); - int ret = rc_url_award_cheevo(buffer, sizeof(buffer), settings->arrays.cheevos_username, rcheevos_locals.token, request->id, request->hardcore); + int ret = rc_url_award_cheevo(buffer, sizeof(buffer), settings->arrays.cheevos_username, rcheevos_locals.token, request->id, request->hardcore, rcheevos_locals.hash); if (ret != 0) { @@ -730,7 +818,7 @@ static void rcheevos_async_award_achievement(rcheevos_async_io_request* request) return; } - rcheevos_log_url(RCHEEVOS_TAG "rc_url_award_cheevo: %s\n", buffer); + rcheevos_log_url("rc_url_award_cheevo", buffer); task_push_http_transfer_with_user_agent(buffer, true, NULL, request->user_agent, rcheevos_async_task_callback, request); } @@ -766,10 +854,11 @@ static void rcheevos_award(rcheevos_cheevo_t* cheevo, int mode) /* Start the award task. */ { - rcheevos_async_io_request* request = (rcheevos_async_io_request*)calloc(1, sizeof(rcheevos_async_io_request)); - request->type = CHEEVOS_ASYNC_AWARD_ACHIEVEMENT; - request->id = cheevo->info->id; - request->hardcore = ((mode & RCHEEVOS_ACTIVE_HARDCORE) != 0) ? 1 : 0; + rcheevos_async_io_request *request = (rcheevos_async_io_request*)calloc(1, sizeof(rcheevos_async_io_request)); + request->type = CHEEVOS_ASYNC_AWARD_ACHIEVEMENT; + request->id = cheevo->info->id; + request->hardcore = ((mode & RCHEEVOS_ACTIVE_HARDCORE) != 0) + ? 1 : 0; request->success_message = "Awarded achievement"; request->failure_message = "Error awarding achievement"; rcheevos_get_user_agent(request->user_agent); @@ -796,33 +885,10 @@ static void rcheevos_award(rcheevos_cheevo_t* cheevo, int mode) } } -static unsigned rcheevos_peek(unsigned address, unsigned num_bytes, void* ud) -{ - const uint8_t* data = rcheevos_fixup_find(&rcheevos_locals.fixups, - address, rcheevos_locals.patchdata.console_id); - unsigned value = 0; - - if (data) - { - switch (num_bytes) - { - case 4: value |= data[2] << 16 | data[3] << 24; - case 2: value |= data[1] << 8; - case 1: value |= data[0]; - } - } - else - { - rcheevos_locals.invalid_peek_address = true; - } - - return value; -} - static int rcheevos_has_indirect_memref(const rc_memref_value_t* memrefs) { const rc_memref_value_t* memref = memrefs; - while (memref != NULL) + while (memref) { if (memref->memref.is_indirect) return 1; @@ -907,7 +973,7 @@ static void rcheevos_async_submit_lboard(rcheevos_async_io_request* request) char buffer[256]; settings_t *settings = config_get_ptr(); int ret = rc_url_submit_lboard(buffer, sizeof(buffer), settings->arrays.cheevos_username, - rcheevos_locals.token, request->id, request->value, rcheevos_locals.hash); + rcheevos_locals.token, request->id, request->value); if (ret != 0) { @@ -916,7 +982,7 @@ static void rcheevos_async_submit_lboard(rcheevos_async_io_request* request) return; } - rcheevos_log_url(RCHEEVOS_TAG "rc_url_submit_lboard: %s\n", buffer); + rcheevos_log_url("rc_url_submit_lboard", buffer); task_push_http_transfer_with_user_agent(buffer, true, NULL, request->user_agent, rcheevos_async_task_callback, request); } @@ -971,39 +1037,33 @@ static void rcheevos_test_leaderboards(void) switch (rc_evaluate_lboard(lboard->lboard, &lboard->last_value, rcheevos_peek, NULL, NULL)) { default: - case RC_LBOARD_INACTIVE: break; - case RC_LBOARD_ACTIVE: - /* this is where we would update the onscreen tracker */ - break; - - case RC_LBOARD_TRIGGERED: + case RC_LBOARD_STATE_TRIGGERED: rcheevos_lboard_submit(lboard); break; - case RC_LBOARD_CANCELED: - { + case RC_LBOARD_STATE_CANCELED: CHEEVOS_LOG(RCHEEVOS_TAG "Cancel leaderboard %s\n", lboard->info->title); lboard->active = 0; runloop_msg_queue_push("Leaderboard attempt cancelled!", 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); break; - } - case RC_LBOARD_STARTED: - { - char buffer[256]; + case RC_LBOARD_STATE_STARTED: + if (!lboard->active) + { + char buffer[256]; - CHEEVOS_LOG(RCHEEVOS_TAG "Leaderboard started: %s\n", lboard->info->title); - lboard->active = 1; + CHEEVOS_LOG(RCHEEVOS_TAG "Leaderboard started: %s\n", lboard->info->title); + lboard->active = 1; - snprintf(buffer, sizeof(buffer), - "Leaderboard Active: %s", lboard->info->title); - runloop_msg_queue_push(buffer, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - runloop_msg_queue_push(lboard->info->description, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + snprintf(buffer, sizeof(buffer), + "Leaderboard Active: %s", lboard->info->title); + runloop_msg_queue_push(buffer, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + runloop_msg_queue_push(lboard->info->description, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + } break; - } } if (rcheevos_locals.invalid_peek_address) @@ -1031,53 +1091,6 @@ const char* rcheevos_get_richpresence(void) return rcheevos_locals.richpresence.evaluation; } -static retro_time_t rcheevos_async_send_rich_presence(rcheevos_async_io_request* request) -{ - settings_t *settings = config_get_ptr(); - const char *cheevos_username = settings->arrays.cheevos_username; - bool cheevos_richpresence_enable = settings->bools.cheevos_richpresence_enable; - - if (cheevos_richpresence_enable && rcheevos_locals.richpresence.richpresence) - { - rc_evaluate_richpresence(rcheevos_locals.richpresence.richpresence, - rcheevos_locals.richpresence.evaluation, - sizeof(rcheevos_locals.richpresence.evaluation), rcheevos_peek, NULL, NULL); - } - - { - char url[256], post_data[1024]; - - snprintf(url, sizeof(url), - "http://retroachievements.org/dorequest.php?r=ping&u=%s&t=%s", - cheevos_username, rcheevos_locals.token); - - if (rcheevos_locals.richpresence.evaluation[0]) - { - char* tmp = NULL; - net_http_urlencode(&tmp, rcheevos_locals.richpresence.evaluation); - snprintf(post_data, sizeof(post_data), "g=%u&m=%s", rcheevos_locals.patchdata.game_id, tmp); - CHEEVOS_FREE(tmp); - -#ifdef HAVE_DISCORD - if (settings->bools.discord_enable) - discord_update(DISCORD_PRESENCE_RETROACHIEVEMENTS, false); -#endif - } - else - snprintf(post_data, sizeof(post_data), "g=%u", rcheevos_locals.patchdata.game_id); - - rcheevos_get_user_agent(request->user_agent); - task_push_http_post_transfer_with_user_agent(url, post_data, true, "POST", request->user_agent, NULL, NULL); - } - - /* Update rich presence every two minutes */ - if (settings->bools.cheevos_richpresence_enable) - return cpu_features_get_time_usec() + CHEEVOS_PING_FREQUENCY; - - /* Send ping every four minutes */ - return cpu_features_get_time_usec() + CHEEVOS_PING_FREQUENCY * 2; -} - void rcheevos_reset_game(void) { unsigned i; @@ -1109,15 +1122,7 @@ void rcheevos_reset_game(void) rc_reset_lboard(lboard->lboard); if (lboard->active) - { lboard->active = 0; - - /* This ensures the leaderboard won't restart - * until the start trigger is false for at - * least one frame */ - if (lboard->lboard) - lboard->lboard->submitted = 1; - } } rcheevos_locals.richpresence.last_update = cpu_features_get_time_usec(); @@ -1133,12 +1138,12 @@ void rcheevos_get_achievement_state(unsigned index, char *buffer, size_t buffer_ if (index < rcheevos_locals.patchdata.core_count) { enum_idx = MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY; - cheevo = &rcheevos_locals.core[index]; + cheevo = rcheevos_locals.core ? &rcheevos_locals.core[index] : NULL; } else { enum_idx = MENU_ENUM_LABEL_VALUE_CHEEVOS_UNOFFICIAL_ENTRY; - cheevo = &rcheevos_locals.unofficial[index - rcheevos_locals.patchdata.core_count]; + cheevo = rcheevos_locals.unofficial ? &rcheevos_locals.unofficial[index - rcheevos_locals.patchdata.core_count] : NULL; } if (!cheevo || !cheevo->trigger) @@ -1148,16 +1153,13 @@ void rcheevos_get_achievement_state(unsigned index, char *buffer, size_t buffer_ else { settings_t* settings = config_get_ptr(); - bool hardcore = settings->bools.cheevos_hardcore_mode_enable; + bool hardcore = settings->bools.cheevos_hardcore_mode_enable && !rcheevos_hardcore_paused; if (hardcore && !(cheevo->active & RCHEEVOS_ACTIVE_HARDCORE)) enum_idx = MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY_HARDCORE; else if (!hardcore && !(cheevo->active & RCHEEVOS_ACTIVE_SOFTCORE)) enum_idx = MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY; - else - { - /* use either "Locked" for core or "Unofficial" for unofficial as set above */ + else /* Use either "Locked" for core or "Unofficial" for unofficial as set above */ check_measured = true; - } } strlcpy(buffer, msg_hash_to_str(enum_idx), buffer_size); @@ -1169,7 +1171,7 @@ void rcheevos_get_achievement_state(unsigned index, char *buffer, size_t buffer_ { char measured_buffer[12]; const unsigned int value = MIN(cheevo->trigger->measured_value, target); - const int percent = (int)(((unsigned long)value) * 100 / target); + const int percent = (int)(((unsigned long)value) * 100 / target); snprintf(measured_buffer, sizeof(measured_buffer), " - %d%%", percent); strlcat(buffer, measured_buffer, buffer_size); @@ -1177,7 +1179,8 @@ void rcheevos_get_achievement_state(unsigned index, char *buffer, size_t buffer_ } } -static void rcheevos_append_menu_achievement(menu_displaylist_info_t* info, size_t idx, rcheevos_cheevo_t* cheevo) +static void rcheevos_append_menu_achievement( + menu_displaylist_info_t* info, size_t idx, rcheevos_cheevo_t* cheevo) { bool badge_grayscale; @@ -1190,16 +1193,11 @@ static void rcheevos_append_menu_achievement(menu_displaylist_info_t* info, size /* unsupported */ badge_grayscale = true; } - else if (!(cheevo->active & RCHEEVOS_ACTIVE_HARDCORE) || !(cheevo->active & RCHEEVOS_ACTIVE_SOFTCORE)) - { - /* unlocked */ - badge_grayscale = false; - } + else if (!(cheevo->active & RCHEEVOS_ACTIVE_HARDCORE) || + !(cheevo->active & RCHEEVOS_ACTIVE_SOFTCORE)) + badge_grayscale = false; /* unlocked */ else - { - /* locked */ - badge_grayscale = true; - } + badge_grayscale = true; /* locked */ cheevos_set_menu_badge(idx, cheevo->info->badge, badge_grayscale); } @@ -1237,17 +1235,13 @@ void rcheevos_populate_menu(void* data) cheevo = rcheevos_locals.core; for (count = rcheevos_locals.patchdata.core_count; count > 0; count--) - { rcheevos_append_menu_achievement(info, i++, cheevo++); - } if (cheevos_test_unofficial) { cheevo = rcheevos_locals.unofficial; for (count = rcheevos_locals.patchdata.unofficial_count; count > 0; count--) - { rcheevos_append_menu_achievement(info, i++, cheevo++); - } } if (i == 0) @@ -1293,19 +1287,16 @@ bool rcheevos_get_description(rcheevos_ctx_desc_t* desc) return true; } -bool rcheevos_apply_cheats(bool* data_bool) +void rcheevos_pause_hardcore(void) { - rcheevos_cheats_are_enabled = *data_bool; - rcheevos_cheats_were_enabled |= rcheevos_cheats_are_enabled; - - return true; + rcheevos_hardcore_paused = true; } bool rcheevos_unload(void) { - bool running = false; + bool running = false; unsigned i = 0, count = 0; - settings_t* settings = config_get_ptr(); + settings_t* settings = config_get_ptr(); CHEEVOS_LOCK(rcheevos_locals.task_lock); running = rcheevos_locals.task != NULL; @@ -1322,8 +1313,7 @@ bool rcheevos_unload(void) CHEEVOS_LOCK(rcheevos_locals.task_lock); running = rcheevos_locals.task != NULL; CHEEVOS_UNLOCK(rcheevos_locals.task_lock); - } - while (running); + }while (running); #endif } @@ -1356,15 +1346,15 @@ bool rcheevos_unload(void) rcheevos_locals.lboards = NULL; rcheevos_locals.richpresence.richpresence = NULL; - rcheevos_loaded = false; - rcheevos_hardcore_active = false; - rcheevos_hardcore_paused = false; - rcheevos_state_loaded_flag = false; + rcheevos_loaded = false; + rcheevos_hardcore_active = false; + rcheevos_hardcore_paused = false; + rcheevos_state_loaded_flag = false; } /* if the config-level token has been cleared, we need to re-login on loading the next game */ if (!settings->arrays.cheevos_token[0]) - rcheevos_locals.token[0] = '\0'; + rcheevos_locals.token[0] = '\0'; return true; } @@ -1379,7 +1369,7 @@ bool rcheevos_toggle_hardcore_mode(void) if (cheevos_hardcore_mode_enable && !rcheevos_hardcore_paused) { - const char *msg = msg_hash_to_str( + const char *msg = msg_hash_to_str( MSG_CHEEVOS_HARDCORE_MODE_ENABLE); /* reset the state loaded flag in case it was set */ @@ -1393,7 +1383,8 @@ bool rcheevos_toggle_hardcore_mode(void) command_event(CMD_EVENT_REWIND_DEINIT, NULL); CHEEVOS_LOG("%s\n", msg); - runloop_msg_queue_push(msg, 0, 3 * 60, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + runloop_msg_queue_push(msg, 0, 3 * 60, true, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); } else { @@ -1404,6 +1395,9 @@ bool rcheevos_toggle_hardcore_mode(void) return true; } +/***************************************************************************** +Test all the achievements (call once per frame). +*****************************************************************************/ void rcheevos_test(void) { settings_t *settings = config_get_ptr(); @@ -1422,12 +1416,6 @@ void rcheevos_test(void) } } -bool rcheevos_set_cheats(void) -{ - rcheevos_cheats_were_enabled = rcheevos_cheats_are_enabled; - return true; -} - void rcheevos_set_support_cheevos(bool state) { rcheevos_locals.core_supports = state; @@ -1435,7 +1423,7 @@ void rcheevos_set_support_cheevos(bool state) bool rcheevos_get_support_cheevos(void) { - return rcheevos_locals.core_supports; + return rcheevos_locals.core_supports; } int rcheevos_get_console(void) @@ -1450,8 +1438,8 @@ const char* rcheevos_get_hash(void) static void rcheevos_unlock_cb(unsigned id, void* userdata) { - int i = 0; - unsigned j = 0, count = 0; + int i; + unsigned j = 0, count = 0; rcheevos_cheevo_t* cheevo = NULL; for (i = 0; i < 2; i++) @@ -1475,7 +1463,8 @@ static void rcheevos_unlock_cb(unsigned id, void* userdata) cheevo->active &= ~*(unsigned*)userdata; #endif CHEEVOS_LOG(RCHEEVOS_TAG "cheevo %u deactivated (%s): %s\n", id, - (*(unsigned*)userdata) == RCHEEVOS_ACTIVE_HARDCORE ? "hardcore" : "softcore", + (*(unsigned*)userdata) == RCHEEVOS_ACTIVE_HARDCORE + ? "hardcore" : "softcore", cheevo->info->title); return; } @@ -1507,34 +1496,22 @@ typedef struct char url[256]; char badge_basepath[PATH_MAX_LENGTH]; char badge_fullpath[PATH_MAX_LENGTH]; - unsigned char last_hash[16]; - unsigned char hash[16]; - unsigned ext_hash; + char hash[33]; unsigned gameid; unsigned i; unsigned j; unsigned k; - size_t bytes; - size_t count; - size_t offset; size_t len; - size_t size; - MD5_CTX md5; - rcheevos_nes_header_t header; retro_time_t t0; - struct retro_system_info sysinfo; void *data; char *json; const char *path; - const char *ext; - intfstream_t *stream; rcheevos_cheevo_t *cheevo; + const rcheevos_cheevo_t *cheevo_end; settings_t *settings; struct http_connection_t *conn; struct http_t *http; - const rcheevos_cheevo_t *cheevo_end; - cdfs_track_t *track; - cdfs_file_t cdfp; + struct rc_hash_iterator iterator; /* co-routine required fields */ CORO_FIELDS @@ -1543,313 +1520,22 @@ typedef struct enum { /* Negative values because CORO_SUB generates positive values */ - RCHEEVOS_GENERIC_MD5 = -1, - RCHEEVOS_SNES_MD5 = -2, - RCHEEVOS_LYNX_MD5 = -3, - RCHEEVOS_NES_MD5 = -4, - RCHEEVOS_PSX_MD5 = -5, - RCHEEVOS_ARCADE_MD5 = -6, - RCHEEVOS_EVAL_MD5 = -7, - RCHEEVOS_SEGACD_MD5 = -8, - RCHEEVOS_GET_GAMEID = -9, - RCHEEVOS_GET_CHEEVOS = -10, - RCHEEVOS_GET_BADGES = -11, - RCHEEVOS_LOGIN = -12, - RCHEEVOS_HTTP_GET = -13, - RCHEEVOS_DEACTIVATE = -14, - RCHEEVOS_PLAYING = -15, - RCHEEVOS_DELAY = -16, - RCHEEVOS_PCE_CD_MD5 = -17, - RCHEEVOS_NDS_MD5 = -18, - RCHEEVOS_BUFFER_FILE = -19 + RCHEEVOS_GET_GAMEID = -1, + RCHEEVOS_GET_CHEEVOS = -2, + RCHEEVOS_GET_BADGES = -3, + RCHEEVOS_LOGIN = -4, + RCHEEVOS_HTTP_GET = -5, + RCHEEVOS_DEACTIVATE = -6, + RCHEEVOS_PLAYING = -7, + RCHEEVOS_DELAY = -8 }; -static int rcheevos_prepare_hash_psx(rcheevos_coro_t* coro) -{ - char buffer[2048]; - char exe_name_buffer[64]; - size_t exe_name_size; - const char* exe_name = NULL; - char* scan = NULL; - int success = 0; - size_t to_read = 0; - - /* find the data track - it should be the first one */ - coro->track = cdfs_open_data_track(coro->path); - - if (!coro->track) - { - CHEEVOS_LOG(RCHEEVOS_TAG "could not open CD\n"); - return false; - } - - /* open the SYSTEM.CNF file and find the BOOT= record */ - if (cdfs_open_file(&coro->cdfp, coro->track, "SYSTEM.CNF")) - { - cdfs_read_file(&coro->cdfp, buffer, sizeof(buffer)); - - for (scan = buffer; scan < &buffer[sizeof(buffer)] && *scan; ++scan) - { - if (strncmp(scan, "BOOT", 4) == 0) - { - exe_name = scan + 4; - while (isspace(*exe_name)) - ++exe_name; - - if (*exe_name == '=') - { - ++exe_name; - while (isspace(*exe_name)) - ++exe_name; - - if (strncmp(exe_name, "cdrom:", 6) == 0) - exe_name += 6; - if (*exe_name == '\\') - ++exe_name; - break; - } - } - - while (*scan && *scan != '\n') - ++scan; - } - - cdfs_close_file(&coro->cdfp); - - if (exe_name) - { - scan = (char*)exe_name; - while (!isspace(*scan) && *scan != ';') - ++scan; - *scan = '\0'; - } - } - else - { - /* no SYSTEM.CNF, check for a PSX.EXE */ - exe_name = "PSX.EXE"; - } - - if (!exe_name || !cdfs_open_file(&coro->cdfp, coro->track, exe_name)) - { - CHEEVOS_LOG(RCHEEVOS_TAG "could not locate primary executable\n"); - } - else - { - /* store the exe name, we're about to overwrite buffer */ - strlcpy(exe_name_buffer, exe_name, sizeof(exe_name_buffer)); - exe_name_buffer[sizeof(exe_name_buffer) - 1] = '\0'; - exe_name_size = strlen(exe_name_buffer); - - /* read the first sector of the executable */ - cdfs_read_file(&coro->cdfp, buffer, sizeof(buffer)); - - /* the PSX-E header specifies the executable size as a 4-byte value 28 bytes into the header, which doesn't - * include the header itself. We want to include the header in the hash, so append another 2048 to that value. - * ASSERT: this results in the same value as coro->cdfp->size */ - coro->count = 2048 + (((uint8_t)buffer[28 + 3] << 24) | ((uint8_t)buffer[28 + 2] << 16) | - ((uint8_t)buffer[28 + 1] << 8) | (uint8_t)buffer[28]); - - if (coro->count <= CHEEVOS_MB(16)) /* sanity check */ - { - /* there's a few games that use a singular engine and only differ via their data files. - * luckily, they have unique serial numbers, and use the serial number as the boot file in the - * standard way. include the boot executable name in the hash */ - coro->count += exe_name_size; - - free(coro->data); - coro->data = (uint8_t*)malloc(coro->count); - memcpy(coro->data, exe_name_buffer, exe_name_size); - coro->len = exe_name_size; - - memcpy((uint8_t*)coro->data + coro->len, buffer, sizeof(buffer)); - coro->len += sizeof(buffer); - - while (coro->len < coro->count) - { - to_read = coro->count - coro->len; - if (to_read > 2048) - to_read = 2048; - - cdfs_read_file(&coro->cdfp, (uint8_t*)coro->data + coro->len, to_read); - - coro->len += to_read; - }; - - success = 1; - } - - cdfs_close_file(&coro->cdfp); - } - - cdfs_close_track(coro->track); - coro->track = NULL; - - return success; -} - -static int rcheevos_prepare_hash_nintendo_ds(rcheevos_coro_t* coro) -{ - unsigned char header[512]; - int success = 0; - intfstream_t *stream = intfstream_open_file( - coro->path, RETRO_VFS_FILE_ACCESS_READ, - RETRO_VFS_FILE_ACCESS_HINT_NONE); - - if (stream) - { - if (intfstream_read(stream, header, sizeof(header)) == 512) - { - unsigned int hash_size, arm9_size, arm9_addr, arm7_size, arm7_addr, icon_addr; - int offset = 0; - - if (header[0] == 0x2E && header[1] == 0x00 && header[2] == 0x00 && header[3] == 0xEA && - header[0xB0] == 0x44 && header[0xB1] == 0x46 && header[0xB2] == 0x96 && header[0xB3] == 0x00) - { - /* SuperCard header detected, ignore it */ - offset = 512; - intfstream_seek(stream, offset, RETRO_VFS_SEEK_POSITION_START); - intfstream_read(stream, header, sizeof(header)); - } - - arm9_addr = header[0x20] | (header[0x21] << 8) | (header[0x22] << 16) | (header[0x23] << 24); - arm9_size = header[0x2C] | (header[0x2D] << 8) | (header[0x2E] << 16) | (header[0x2F] << 24); - arm7_addr = header[0x30] | (header[0x31] << 8) | (header[0x32] << 16) | (header[0x33] << 24); - arm7_size = header[0x3C] | (header[0x3D] << 8) | (header[0x3E] << 16) | (header[0x3F] << 24); - icon_addr = header[0x68] | (header[0x69] << 8) | (header[0x6A] << 16) | (header[0x6B] << 24); - - hash_size = 0x160 + arm9_size + arm7_size + 0xA00; - if (hash_size > 16 * 1024 * 1024) - { - CHEEVOS_LOG(RCHEEVOS_TAG "arm9 code size (%u) + arm7 code size (%u) exceeds 16MB", arm9_size, arm7_size); - } - else - { - if (coro->data) - free(coro->data); - - coro->data = malloc(hash_size); - if (!coro->data) - { - CHEEVOS_LOG(RCHEEVOS_TAG "failed to allocate %u bytes", hash_size); - intfstream_close(stream); - CORO_STOP(); - } - else - { - uint8_t* hash_ptr = (uint8_t*)coro->data; - - memcpy(hash_ptr, header, 0x160); - hash_ptr += 0x160; - - intfstream_seek(stream, arm9_addr + offset, RETRO_VFS_SEEK_POSITION_START); - intfstream_read(stream, hash_ptr, arm9_size); - hash_ptr += arm9_size; - - intfstream_seek(stream, arm7_addr + offset, RETRO_VFS_SEEK_POSITION_START); - intfstream_read(stream, hash_ptr, arm7_size); - hash_ptr += arm7_size; - - intfstream_seek(stream, icon_addr + offset, RETRO_VFS_SEEK_POSITION_START); - intfstream_read(stream, hash_ptr, 0xA00); - - coro->len = hash_size; - success = 1; - } - } - } - - intfstream_close(stream); - } - - return success; -} - static int rcheevos_iterate(rcheevos_coro_t* coro) { char buffer[2048]; - const int snes_header_len = 0x200; - const int lynx_header_len = 0x40; - ssize_t num_read = 0; - size_t to_read = 4096; - uint8_t* ptr = NULL; - const char* end = NULL; - - static const uint32_t snes_exts[] = - { - 0x0b88aa88U, /* smc */ - 0x0b8872bbU, /* fig */ - 0x0b88a9a1U, /* sfc */ - 0x0b887623U, /* gd3 */ - 0x0b887627U, /* gd7 */ - 0x0b886bf3U, /* dx2 */ - 0x0b886312U, /* bsx */ - 0x0b88abd2U, /* swc */ - 0 - }; - - static const uint32_t nes_exts[] = - { - 0x0b88944bU, /* nes */ - 0 - }; - - static const uint32_t lynx_exts[] = - { - 0x0b888cf7U, /* lnx */ - 0 - }; - - static const uint32_t psx_exts[] = - { - 0x0b886782U, /* cue */ - 0x0b88899aU, /* m3u */ - /*0x0b88af0bU,* toc */ - /*0x0b88652fU,* ccd */ - /*0x0b889c67U,* pbp */ - 0x0b8865d4U, /* chd */ - 0 - }; - - static const uint32_t segacd_exts[] = - { - 0x0b886782U, /* cue */ - 0x0b8880d0U, /* iso */ - 0x0b8865d4U, /* chd */ - 0 - }; - - static const uint32_t pce_cd_exts[] = - { - 0x0b886782U, /* cue */ - 0x0b8865d4U, /* chd */ - 0 - }; - - static const uint32_t arcade_exts[] = - { - 0x0b88c7d8U, /* zip */ - 0 - }; - - static const uint32_t nds_exts[] = - { - 0x00b88942aU, /* nds */ - 0 - }; - - static rcheevos_finder_t finders[] = - { - {RCHEEVOS_SNES_MD5, "SNES (discards header)", snes_exts}, - {RCHEEVOS_LYNX_MD5, "Atari Lynx (discards header)", lynx_exts}, - {RCHEEVOS_NES_MD5, "NES (discards header)", nes_exts}, - {RCHEEVOS_NDS_MD5, "Nintendo DS (main executables)", nds_exts}, - {RCHEEVOS_PSX_MD5, "Playstation (main executable)", psx_exts}, - {RCHEEVOS_PCE_CD_MD5, "PC Engine CD (boot sector)", pce_cd_exts}, - {RCHEEVOS_SEGACD_MD5, "Sega CD/Saturn (first sector)", segacd_exts}, - {RCHEEVOS_ARCADE_MD5, "Arcade (filename)", arcade_exts}, - {RCHEEVOS_GENERIC_MD5, "Generic (plain content)", NULL} - }; +#ifdef CHEEVOS_TIME_HASH + retro_time_t start; +#endif CORO_ENTER(); @@ -1861,99 +1547,34 @@ static int rcheevos_iterate(rcheevos_coro_t* coro) if (!coro->settings->bools.cheevos_enable) CORO_STOP(); - /* Use the selected file's extension to determine which method to use */ - for (coro->i = 0; coro->i < ARRAY_SIZE(finders); coro->i++) + /* iterate over the possible hashes for the file being loaded */ + rc_hash_initialize_iterator(&coro->iterator, coro->path, NULL, 0); +#ifdef CHEEVOS_TIME_HASH + start = cpu_features_get_time_usec(); +#endif + while (rc_hash_iterate(coro->hash, &coro->iterator)) { - if (finders[coro->i].ext_hashes) - { - for (coro->j = 0; finders[coro->i].ext_hashes[coro->j]; coro->j++) - { - if (finders[coro->i].ext_hashes[coro->j] == coro->ext_hash) - { - CHEEVOS_LOG(RCHEEVOS_TAG "testing %s\n", finders[coro->i].name); - CORO_GOSUB(finders[coro->i].label); - - if (coro->gameid != 0) - goto found; - - break; - } - } - } - } - - /* Use the extensions supported by the core as a hint to what method we should use. */ - core_get_system_info(&coro->sysinfo); - CHEEVOS_LOG(RCHEEVOS_TAG "no method for file extension, trying core supported extensions: %s\n", coro->sysinfo.valid_extensions); - for (coro->i = 0; coro->i < ARRAY_SIZE(finders); coro->i++) - { - if (finders[coro->i].ext_hashes) - { - for (coro->j = 0; finders[coro->i].ext_hashes[coro->j]; coro->j++) - { - if (finders[coro->i].ext_hashes[coro->j] == coro->ext_hash) - break; - } - - /* did we already check this one? */ - if (finders[coro->i].ext_hashes[coro->j] == coro->ext_hash) - continue; - - coro->ext = coro->sysinfo.valid_extensions; - - while (coro->ext) - { - unsigned hash; - end = strchr(coro->ext, '|'); - - if (end) - { - hash = rcheevos_djb2(coro->ext, end - coro->ext); - coro->ext = end + 1; - } - else - { - hash = rcheevos_djb2(coro->ext, strlen(coro->ext)); - coro->ext = NULL; - } - - for (coro->j = 0; finders[coro->i].ext_hashes[coro->j]; coro->j++) - { - if (finders[coro->i].ext_hashes[coro->j] == hash) - { - CHEEVOS_LOG(RCHEEVOS_TAG "testing %s\n", finders[coro->i].name); - CORO_GOSUB(finders[coro->i].label); - - if (coro->gameid != 0) - goto found; - - coro->ext = NULL; /* force next finder */ - break; - } - } - } - } - } - - /* Try hashing methods not specifically tied to a file extension */ - for (coro->i = 0; coro->i < ARRAY_SIZE(finders); coro->i++) - { - if (finders[coro->i].ext_hashes) - continue; - - CHEEVOS_LOG(RCHEEVOS_TAG "testing %s\n", finders[coro->i].name); - CORO_GOSUB(finders[coro->i].label); - +#ifdef CHEEVOS_TIME_HASH + CHEEVOS_LOG(RCHEEVOS_TAG "hash generated in %ums\n", (cpu_features_get_time_usec() - start) / 1000); +#endif + CORO_GOSUB(RCHEEVOS_GET_GAMEID); if (coro->gameid != 0) - goto found; + break; + +#ifdef CHEEVOS_TIME_HASH + start = cpu_features_get_time_usec(); +#endif } + rc_hash_destroy_iterator(&coro->iterator); - CHEEVOS_LOG(RCHEEVOS_TAG "this game doesn't feature achievements\n"); - strcpy(rcheevos_locals.hash, "N/A"); - rcheevos_hardcore_paused = true; - CORO_STOP(); - -found: + /* if no match was found, bail */ + if (coro->gameid == 0) + { + CHEEVOS_LOG(RCHEEVOS_TAG "this game doesn't feature achievements\n"); + strcpy(rcheevos_locals.hash, "N/A"); + rcheevos_hardcore_paused = true; + CORO_STOP(); + } #ifdef CHEEVOS_JSON_OVERRIDE { @@ -2015,7 +1636,8 @@ found: * Inputs: CHEEVOS_VAR_GAMEID * Outputs: */ - CORO_GOSUB(RCHEEVOS_DEACTIVATE); + if (!coro->settings->bools.cheevos_start_active) + CORO_GOSUB(RCHEEVOS_DEACTIVATE); /* * Inputs: CHEEVOS_VAR_GAMEID @@ -2026,11 +1648,11 @@ found: if (coro->settings->bools.cheevos_verbose_enable && rcheevos_locals.patchdata.core_count > 0) { char msg[256]; - int mode = RCHEEVOS_ACTIVE_SOFTCORE; + int mode = RCHEEVOS_ACTIVE_SOFTCORE; const rcheevos_cheevo_t* cheevo = rcheevos_locals.core; const rcheevos_cheevo_t* end = cheevo + rcheevos_locals.patchdata.core_count; - int number_of_unlocked = rcheevos_locals.patchdata.core_count; - int number_of_unsupported = 0; + int number_of_unlocked = rcheevos_locals.patchdata.core_count; + int number_of_unsupported = 0; if (coro->settings->bools.cheevos_hardcore_mode_enable && !rcheevos_hardcore_paused) mode = RCHEEVOS_ACTIVE_HARDCORE; @@ -2045,15 +1667,32 @@ found: if (!number_of_unsupported) { - snprintf(msg, sizeof(msg), - "You have %d of %d achievements unlocked.", - number_of_unlocked, rcheevos_locals.patchdata.core_count); + if (coro->settings->bools.cheevos_start_active) + snprintf(msg, sizeof(msg), + "All %d achievements activated for this session.", + rcheevos_locals.patchdata.core_count); + else + { + snprintf(msg, sizeof(msg), + "You have %d of %d achievements unlocked.", + number_of_unlocked, rcheevos_locals.patchdata.core_count); + } } else { - snprintf(msg, sizeof(msg), - "You have %d of %d achievements unlocked (%d unsupported).", - number_of_unlocked - number_of_unsupported, rcheevos_locals.patchdata.core_count, number_of_unsupported); + if (coro->settings->bools.cheevos_start_active) + snprintf(msg, sizeof(msg), + "All %d achievements activated for this session (%d unsupported).", + rcheevos_locals.patchdata.core_count, + number_of_unsupported); + else + { + snprintf(msg, sizeof(msg), + "You have %d of %d achievements unlocked (%d unsupported).", + number_of_unlocked - number_of_unsupported, + rcheevos_locals.patchdata.core_count, + number_of_unsupported); + } } msg[sizeof(msg) - 1] = 0; @@ -2064,388 +1703,6 @@ found: CORO_STOP(); - /************************************************************************** - * Info Loads a file into memory - * Input coro->path - * Output coro->data, coro->len - *************************************************************************/ - CORO_SUB(RCHEEVOS_BUFFER_FILE) - if (!coro->data) - { - coro->stream = intfstream_open_file( - coro->path, - RETRO_VFS_FILE_ACCESS_READ, - RETRO_VFS_FILE_ACCESS_HINT_NONE); - - if (!coro->stream) - CORO_STOP(); - - CORO_YIELD(); - coro->len = 0; - coro->count = intfstream_get_size(coro->stream); - - /* size limit */ - if (coro->count > CHEEVOS_MB(64)) - coro->count = CHEEVOS_MB(64); - - coro->data = malloc(coro->count); - - if (!coro->data) - { - intfstream_close(coro->stream); - CHEEVOS_FREE(coro->stream); - CORO_STOP(); - } - - for (;;) - { - ptr = (uint8_t*)coro->data + coro->len; - to_read = 8192; - - if (to_read > coro->count) - to_read = coro->count; - - num_read = intfstream_read(coro->stream, (void*)ptr, to_read); - if (num_read <= 0) - break; - - coro->len += num_read; - coro->count -= num_read; - - if (coro->count == 0) - break; - - CORO_YIELD(); - } - - intfstream_close(coro->stream); - CHEEVOS_FREE(coro->stream); - } - CORO_RET(); - - - /************************************************************************** - * Info Tries to identify a SNES game - * Input coro->path or coro->data+coro->len - * Output coro->gameid - *************************************************************************/ - CORO_SUB(RCHEEVOS_SNES_MD5) - CORO_GOSUB(RCHEEVOS_BUFFER_FILE); - - /* Checks for the existence of a headered SNES file. - Unheadered files fall back to RCHEEVOS_GENERIC_MD5. */ - if (coro->len < 0x2000 || coro->len % 0x2000 != snes_header_len) - { - CHEEVOS_LOG(RCHEEVOS_TAG "could not locate SNES header\n", coro->gameid); - coro->gameid = 0; - CORO_RET(); - } - - coro->offset = snes_header_len; - coro->count = 0; - - CORO_GOSUB(RCHEEVOS_EVAL_MD5); - CORO_GOTO(RCHEEVOS_GET_GAMEID); - - - /************************************************************************** - * Info Tries to identify an Atari Lynx game - * Input coro->path or coro->data+coro->len - * Output coro->gameid - *************************************************************************/ - CORO_SUB(RCHEEVOS_LYNX_MD5) - CORO_GOSUB(RCHEEVOS_BUFFER_FILE); - - /* Checks for the existence of a headered Lynx file. - Unheadered files fall back to RCHEEVOS_GENERIC_MD5. */ - if (coro->len <= (unsigned)lynx_header_len || - memcmp("LYNX", (void *)coro->data, 5) != 0) - { - CHEEVOS_LOG(RCHEEVOS_TAG "could not locate LYNX header\n", coro->gameid); - coro->gameid = 0; - CORO_RET(); - } - - coro->offset = lynx_header_len; - coro->count = coro->len - lynx_header_len; - - CORO_GOSUB(RCHEEVOS_EVAL_MD5); - CORO_GOTO(RCHEEVOS_GET_GAMEID); - - - /************************************************************************** - * Info Tries to identify a NES game - * Input coro->path or coro->data+coro->len - * Output coro->gameid - *************************************************************************/ - CORO_SUB(RCHEEVOS_NES_MD5) - CORO_GOSUB(RCHEEVOS_BUFFER_FILE); - - /* Checks for the existence of a headered NES file. - Unheadered files fall back to RCHEEVOS_GENERIC_MD5. */ - if (coro->len < sizeof(coro->header)) - { - coro->gameid = 0; - CORO_RET(); - } - - memcpy((void*)&coro->header, coro->data, - sizeof(coro->header)); - - if ( coro->header.id[0] != 'N' - || coro->header.id[1] != 'E' - || coro->header.id[2] != 'S' - || coro->header.id[3] != 0x1a) - { - coro->gameid = 0; - CHEEVOS_LOG(RCHEEVOS_TAG "could not locate NES header\n", coro->gameid); - CORO_RET(); - } - - coro->offset = sizeof(coro->header); - coro->count = coro->len - coro->offset; - - CORO_GOSUB(RCHEEVOS_EVAL_MD5); - CORO_GOTO(RCHEEVOS_GET_GAMEID); - - - /************************************************************************** - * Info Tries to identify a Sega CD game - * Input coro->path, coro->len - * Output coro->gameid - *************************************************************************/ - CORO_SUB(RCHEEVOS_SEGACD_MD5) - { - /* ignore bin files less than 16MB - they're probably a ROM, not a CD */ - if (coro->ext_hash == 0x0b8861beU) - { - to_read = coro->len; - if (to_read == 0) - { - coro->stream = intfstream_open_file(coro->path, - RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); - if (coro->stream) - { - to_read = intfstream_get_size(coro->stream); - intfstream_close(coro->stream); - CHEEVOS_FREE(coro->stream); - } - } - - if (to_read < CHEEVOS_MB(16)) - { - CHEEVOS_LOG(RCHEEVOS_TAG "ignoring small BIN file - assuming not CD\n", coro->gameid); - coro->gameid = 0; - CORO_RET(); - } - } - - /* find the data track - it should be the first one */ - coro->track = cdfs_open_data_track(coro->path); - if (coro->track) - { - /* open the raw CD */ - if (cdfs_open_file(&coro->cdfp, coro->track, NULL)) - { - coro->count = 512; - free(coro->data); - coro->data = (uint8_t*)malloc(coro->count); - cdfs_read_file(&coro->cdfp, coro->data, coro->count); - coro->len = coro->count; - - cdfs_close_file(&coro->cdfp); - - cdfs_close_track(coro->track); - coro->track = NULL; - - CORO_GOSUB(RCHEEVOS_EVAL_MD5); - CORO_GOTO(RCHEEVOS_GET_GAMEID); - } - - cdfs_close_track(coro->track); - coro->track = NULL; - } - - CHEEVOS_LOG(RCHEEVOS_TAG "could not open CD\n", coro->gameid); - coro->gameid = 0; - CORO_RET(); - } - - - /************************************************************************** - * Info Tries to identify a PC Engine CD game - * Input coro->path - * Output coro->gameid - *************************************************************************/ - CORO_SUB(RCHEEVOS_PCE_CD_MD5) - { - /* find the data track - it should be the second one */ - coro->track = cdfs_open_data_track(coro->path); - if (coro->track) - { - /* open the raw CD */ - if (cdfs_open_file(&coro->cdfp, coro->track, NULL)) - { - /* the PC-Engine uses the second sector to specify boot information and program name. - * the string "PC Engine CD-ROM SYSTEM" should exist at 32 bytes into the sector - * http://shu.sheldows.com/shu/download/pcedocs/pce_cdrom.html - */ - cdfs_seek_sector(&coro->cdfp, 1); - cdfs_read_file(&coro->cdfp, buffer, 128); - - if (strncmp("PC Engine CD-ROM SYSTEM", (const char*)& buffer[32], 23) != 0) - { - CHEEVOS_LOG(RCHEEVOS_TAG "not a PC Engine CD\n", coro->gameid); - - cdfs_close_track(coro->track); - coro->track = NULL; - - coro->gameid = 0; - CORO_RET(); - } - - { - /* the first three bytes specify the sector of the program data, and the fourth byte - * is the number of sectors. - */ - const unsigned int first_sector = buffer[0] * 65536 + buffer[1] * 256 + buffer[2]; - cdfs_seek_sector(&coro->cdfp, first_sector); - - to_read = buffer[3] * 2048; - } - - coro->count = to_read + 22; - free(coro->data); - coro->data = (uint8_t*)malloc(coro->count); - memcpy(coro->data, &buffer[106], 22); - - cdfs_read_file(&coro->cdfp, ((uint8_t*)coro->data) + 22, to_read); - coro->len = coro->count; - - cdfs_close_file(&coro->cdfp); - - cdfs_close_track(coro->track); - coro->track = NULL; - - CORO_GOSUB(RCHEEVOS_EVAL_MD5); - CORO_GOTO(RCHEEVOS_GET_GAMEID); - } - - cdfs_close_track(coro->track); - coro->track = NULL; - } - - CHEEVOS_LOG(RCHEEVOS_TAG "could not open CD\n", coro->gameid); - coro->gameid = 0; - CORO_RET(); - } - - - /************************************************************************** - * Info Tries to identify a Playstation game - * Input coro->path - * Output coro->gameid - *************************************************************************/ - CORO_SUB(RCHEEVOS_PSX_MD5) - { - if (rcheevos_prepare_hash_psx(coro)) - { - CORO_GOSUB(RCHEEVOS_EVAL_MD5); - CORO_GOTO(RCHEEVOS_GET_GAMEID); - } - - coro->gameid = 0; - CORO_RET(); - } - - - /************************************************************************** - * Info Tries to identify a Nintendo DS game - * Input coro->path - * Output coro->gameid - *************************************************************************/ - CORO_SUB(RCHEEVOS_NDS_MD5) - { - if (rcheevos_prepare_hash_nintendo_ds(coro)) - { - CORO_GOSUB(RCHEEVOS_EVAL_MD5); - CORO_GOTO(RCHEEVOS_GET_GAMEID); - } - - coro->gameid = 0; - CORO_RET(); - } - - - /************************************************************************** - * Info Tries to identify a game by examining the entire file (no special processing) - * Input coro->path or coro->data+coro->len - * Output coro->gameid - *************************************************************************/ - CORO_SUB(RCHEEVOS_GENERIC_MD5) - CORO_GOSUB(RCHEEVOS_BUFFER_FILE); - - coro->offset = 0; - coro->count = 0; - - CORO_GOSUB(RCHEEVOS_EVAL_MD5); - - if (coro->count == 0) - { - coro->gameid = 0; - CORO_RET(); - } - - CORO_GOTO(RCHEEVOS_GET_GAMEID); - - - /************************************************************************** - * Info Tries to identify an arcade game based on its filename (with no extension). - * An arcade game "rom" is a zip file containing many ROMs. - * Input coro->path - * Output coro->gameid - *************************************************************************/ - CORO_SUB(RCHEEVOS_ARCADE_MD5) - if (!string_is_empty(coro->path)) - { - char base_noext[PATH_MAX_LENGTH]; - fill_pathname_base_noext(base_noext, coro->path, sizeof(base_noext)); - - MD5_Init(&coro->md5); - MD5_Update(&coro->md5, (void*)base_noext, strlen(base_noext)); - MD5_Final(coro->hash, &coro->md5); - - CORO_GOTO(RCHEEVOS_GET_GAMEID); - } - CORO_RET(); - - - /************************************************************************** - * Info Evaluates the CHEEVOS_VAR_MD5 hash - * Inputs coro->data, coro->count, coro->offset, coro->len - * Outputs coro->hash - *************************************************************************/ - CORO_SUB(RCHEEVOS_EVAL_MD5) - - if (coro->count == 0) - coro->count = coro->len; - - if (coro->len - coro->offset < coro->count) - coro->count = coro->len - coro->offset; - - /* size limit */ - if (coro->count > CHEEVOS_MB(64)) - coro->count = CHEEVOS_MB(64); - - MD5_Init(&coro->md5); - MD5_Update(&coro->md5, - (void*)((uint8_t*)coro->data + coro->offset), - coro->count); - MD5_Final(coro->hash, &coro->md5); - - CORO_RET(); - - /************************************************************************** * Info Gets the achievements from Retro Achievements * Inputs coro->hash @@ -2456,29 +1713,17 @@ found: { int size; - if (memcmp(coro->last_hash, coro->hash, sizeof(coro->hash)) == 0) - { - CHEEVOS_LOG(RCHEEVOS_TAG "hash did not change, returning %u\n", coro->gameid); - CORO_RET(); - } - memcpy(coro->last_hash, coro->hash, sizeof(coro->hash)); - - size = rc_url_get_gameid(coro->url, sizeof(coro->url), coro->hash); + CHEEVOS_LOG(RCHEEVOS_TAG "checking %s\n", coro->hash); + memcpy(rcheevos_locals.hash, coro->hash, sizeof(coro->hash)); + size = rc_url_get_gameid(coro->url, sizeof(coro->url), rcheevos_locals.hash); if (size < 0) { CHEEVOS_ERR(RCHEEVOS_TAG "buffer too small to create URL\n"); CORO_RET(); } - sprintf(rcheevos_locals.hash, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - coro->hash[0], coro->hash[1], coro->hash[2], coro->hash[3], - coro->hash[4], coro->hash[5], coro->hash[6], coro->hash[7], - coro->hash[8], coro->hash[9], coro->hash[10], coro->hash[11], - coro->hash[12], coro->hash[13], coro->hash[14], coro->hash[15]); - - CHEEVOS_LOG(RCHEEVOS_TAG "checking %s\n", rcheevos_locals.hash); - rcheevos_log_url(RCHEEVOS_TAG "rc_url_get_gameid: %s\n", coro->url); + rcheevos_log_url("rc_url_get_gameid", coro->url); CORO_GOSUB(RCHEEVOS_HTTP_GET); if (!coro->json) @@ -2511,7 +1756,7 @@ found: CORO_STOP(); } - rcheevos_log_url(RCHEEVOS_TAG "rc_url_get_patch: %s\n", coro->url); + rcheevos_log_url("rc_url_get_patch", coro->url); CORO_GOSUB(RCHEEVOS_HTTP_GET); if (!coro->json) @@ -2532,7 +1777,7 @@ found: *************************************************************************/ CORO_SUB(RCHEEVOS_GET_BADGES) - /* we always want badges if menu widgets are enabled */ + /* we always want badges if display widgets are enabled */ #if !defined(HAVE_GFX_WIDGETS) { settings_t *settings = config_get_ptr(); @@ -2564,6 +1809,9 @@ found: for (; coro->cheevo < coro->cheevo_end; coro->cheevo++) { + if (!coro->cheevo->info->badge[0]) + continue; + for (coro->j = 0 ; coro->j < 2; coro->j++) { coro->badge_fullpath[0] = '\0'; @@ -2651,21 +1899,36 @@ found: } if (string_is_empty(coro->settings->arrays.cheevos_token)) + { ret = rc_url_login_with_password(coro->url, sizeof(coro->url), coro->settings->arrays.cheevos_username, coro->settings->arrays.cheevos_password); + + if (ret == RC_OK) + { + CHEEVOS_LOG(RCHEEVOS_TAG "attempting to login %s (with password)\n", coro->settings->arrays.cheevos_username); + rcheevos_log_url("rc_url_login_with_password", coro->url); + } + } else + { ret = rc_url_login_with_token(coro->url, sizeof(coro->url), coro->settings->arrays.cheevos_username, coro->settings->arrays.cheevos_token); + if (ret == RC_OK) + { + CHEEVOS_LOG(RCHEEVOS_TAG "attempting to login %s (with token)\n", coro->settings->arrays.cheevos_username); + rcheevos_log_url("rc_url_login_with_token", coro->url); + } + } + if (ret < 0) { CHEEVOS_ERR(RCHEEVOS_TAG "buffer too small to create URL\n"); CORO_STOP(); } - rcheevos_log_url(RCHEEVOS_TAG "rc_url_login_with_password: %s\n", coro->url); CORO_GOSUB(RCHEEVOS_HTTP_GET); if (!coro->json) @@ -2686,6 +1949,7 @@ found: tok); runloop_msg_queue_push(msg, 0, 5 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); *coro->settings->arrays.cheevos_token = 0; + CHEEVOS_ERR(RCHEEVOS_TAG "login error: %s\n", tok); CHEEVOS_FREE(coro->json); CORO_STOP(); @@ -2703,6 +1967,7 @@ found: runloop_msg_queue_push(msg, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); } + CHEEVOS_LOG(RCHEEVOS_TAG "logged in successfully\n"); strlcpy(rcheevos_locals.token, tok, sizeof(rcheevos_locals.token)); @@ -2838,7 +2103,7 @@ found: CORO_STOP(); } - rcheevos_log_url(RCHEEVOS_TAG "rc_url_get_unlock_list: %s\n", coro->url); + rcheevos_log_url("rc_url_get_unlock_list", coro->url); CORO_GOSUB(RCHEEVOS_HTTP_GET); if (coro->json) @@ -2862,15 +2127,19 @@ found: *************************************************************************/ CORO_SUB(RCHEEVOS_PLAYING) - snprintf( - coro->url, sizeof(coro->url), - "http://retroachievements.org/dorequest.php?r=postactivity&u=%s&t=%s&a=3&m=%u", + { + int ret = rc_url_post_playing(coro->url, sizeof(coro->url), coro->settings->arrays.cheevos_username, - rcheevos_locals.token, coro->gameid - ); + rcheevos_locals.token, coro->gameid); - coro->url[sizeof(coro->url) - 1] = 0; - rcheevos_log_url(RCHEEVOS_TAG "url to post the 'playing' activity: %s\n", coro->url); + if (ret < 0) + { + CHEEVOS_ERR(RCHEEVOS_TAG "buffer too small to create URL\n"); + CORO_STOP(); + } + } + + rcheevos_log_url("rc_url_post_playing", coro->url); CORO_GOSUB(RCHEEVOS_HTTP_GET); @@ -2917,17 +2186,96 @@ static void rcheevos_task_handler(retro_task_t *task) } } +/* hooks for rhash library */ + +static void* rc_hash_handle_file_open(const char* path) +{ + return intfstream_open_file(path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); +} + +static void rc_hash_handle_file_seek(void* file_handle, size_t offset, int origin) +{ + intfstream_seek((intfstream_t*)file_handle, offset, origin); +} + +static size_t rc_hash_handle_file_tell(void* file_handle) +{ + return intfstream_tell((intfstream_t*)file_handle); +} + +static size_t rc_hash_handle_file_read(void* file_handle, void* buffer, size_t requested_bytes) +{ + return intfstream_read((intfstream_t*)file_handle, buffer, requested_bytes); +} + +static void rc_hash_handle_file_close(void* file_handle) +{ + intfstream_close((intfstream_t*)file_handle); + CHEEVOS_FREE(file_handle); +} + +static void* rc_hash_handle_cd_open_track(const char* path, uint32_t track) +{ + cdfs_track_t* cdfs_track; + + if (track == 0) + cdfs_track = cdfs_open_data_track(path); + else + cdfs_track = cdfs_open_track(path, track); + + if (cdfs_track) + { + cdfs_file_t* file = (cdfs_file_t*)malloc(sizeof(cdfs_file_t)); + if (cdfs_open_file(file, cdfs_track, NULL)) + return file; + + CHEEVOS_FREE(file); + } + + cdfs_close_track(cdfs_track); /* ASSERT: this free()s cdfs_track */ + return NULL; +} + +static size_t rc_hash_handle_cd_read_sector(void* track_handle, uint32_t sector, void* buffer, size_t requested_bytes) +{ + cdfs_file_t* file = (cdfs_file_t*)track_handle; + + cdfs_seek_sector(file, sector); + return cdfs_read_file(file, buffer, requested_bytes); +} + +static void rc_hash_handle_cd_close_track(void* track_handle) +{ + cdfs_file_t* file = (cdfs_file_t*)track_handle; + if (file) + { + cdfs_close_track(file->track); + cdfs_close_file(file); /* ASSERT: this does not free() file */ + CHEEVOS_FREE(file); + } +} + +static void rc_hash_handle_log_message(const char* message) +{ + CHEEVOS_LOG(RCHEEVOS_TAG "%s\n", message); +} + +/* end hooks */ + bool rcheevos_load(const void *data) { - char buffer[32]; retro_task_t *task = NULL; const struct retro_game_info *info = NULL; rcheevos_coro_t *coro = NULL; + settings_t *settings = config_get_ptr(); + bool cheevos_enable = settings && settings->bools.cheevos_enable; + struct rc_hash_filereader filereader; + struct rc_hash_cdreader cdreader; rcheevos_loaded = false; rcheevos_hardcore_paused = false; - if (!rcheevos_locals.core_supports || !data) + if (!cheevos_enable || !rcheevos_locals.core_supports || !data) { rcheevos_hardcore_paused = true; return false; @@ -2938,8 +2286,29 @@ bool rcheevos_load(const void *data) if (!coro) return false; - task = task_init(); + /* provide hooks for reading files */ + filereader.open = rc_hash_handle_file_open; + filereader.seek = rc_hash_handle_file_seek; + filereader.tell = rc_hash_handle_file_tell; + filereader.read = rc_hash_handle_file_read; + filereader.close = rc_hash_handle_file_close; + rc_hash_init_custom_filereader(&filereader); + cdreader.open_track = rc_hash_handle_cd_open_track; + cdreader.read_sector = rc_hash_handle_cd_read_sector; + cdreader.close_track = rc_hash_handle_cd_close_track; + rc_hash_init_custom_cdreader(&cdreader); + + rc_hash_init_error_message_callback(rc_hash_handle_log_message); + +#ifndef DEBUG /* in DEBUG mode, always initialize the verbose message handler */ + if (settings->bools.cheevos_verbose_enable) +#endif + { + rc_hash_init_verbose_message_callback(rc_hash_handle_log_message); + } + + task = task_init(); if (!task) { CHEEVOS_FREE(coro); @@ -2949,7 +2318,7 @@ bool rcheevos_load(const void *data) CORO_SETUP(); info = (const struct retro_game_info*)data; - strlcpy(buffer, path_get_extension(info->path), sizeof(buffer)); + coro->path = strdup(info->path); if (info->data) { @@ -2969,51 +2338,12 @@ bool rcheevos_load(const void *data) } memcpy(coro->data, info->data, coro->len); - coro->path = NULL; } else { coro->data = NULL; - coro->path = strdup(info->path); - - /* if we're looking at an m3u file, get the first disc from the playlist */ - if (string_is_equal_noncase(path_get_extension(coro->path), "m3u")) - { - intfstream_t* m3u_stream = intfstream_open_file(coro->path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); - if (m3u_stream) - { - char m3u_contents[1024]; - char disc_path[PATH_MAX_LENGTH]; - char* tmp; - int64_t num_read = intfstream_read( - m3u_stream, m3u_contents, sizeof(m3u_contents) - 1); - - intfstream_close(m3u_stream); - m3u_contents[num_read] = '\0'; - - tmp = m3u_contents; - while (*tmp && *tmp != '\n') - ++tmp; - if (tmp > buffer && tmp[-1] == '\r') - --tmp; - *tmp = '\0'; - - fill_pathname_basedir(disc_path, coro->path, sizeof(disc_path)); - strlcat(disc_path, m3u_contents, sizeof(disc_path)); - - free((void*)coro->path); - coro->path = strdup(disc_path); - - strlcpy(buffer, path_get_extension(disc_path), sizeof(buffer)); - } - } } - buffer[sizeof(buffer) - 1] = '\0'; - string_to_lower(buffer); - coro->ext_hash = rcheevos_djb2(buffer, strlen(buffer)); - CHEEVOS_LOG(RCHEEVOS_TAG "ext_hash %08x ('%s')\n", coro->ext_hash, buffer); - task->handler = rcheevos_task_handler; task->state = (void*)coro; task->mute = true; @@ -3032,6 +2362,5 @@ bool rcheevos_load(const void *data) CHEEVOS_UNLOCK(rcheevos_locals.task_lock); task_queue_push(task); - return true; } diff --git a/cheevos-new/cheevos.h b/cheevos/cheevos.h similarity index 92% rename from cheevos-new/cheevos.h rename to cheevos/cheevos.h index 952a760436..b1096be9a5 100644 --- a/cheevos-new/cheevos.h +++ b/cheevos/cheevos.h @@ -49,7 +49,7 @@ void rcheevos_get_achievement_state(unsigned index, char* buffer, size_t buffer_ bool rcheevos_get_description(rcheevos_ctx_desc_t *desc); -bool rcheevos_apply_cheats(bool *data_bool); +void rcheevos_pause_hardcore(); bool rcheevos_unload(void); @@ -57,8 +57,6 @@ bool rcheevos_toggle_hardcore_mode(void); void rcheevos_test(void); -bool rcheevos_set_cheats(void); - void rcheevos_set_support_cheevos(bool state); bool rcheevos_get_support_cheevos(void); @@ -73,8 +71,6 @@ extern bool rcheevos_loaded; extern bool rcheevos_hardcore_active; extern bool rcheevos_hardcore_paused; extern bool rcheevos_state_loaded_flag; -extern int rcheevos_cheats_are_enabled; -extern int rcheevos_cheats_were_enabled; RETRO_END_DECLS diff --git a/cheevos-new/coro.h b/cheevos/coro.h similarity index 100% rename from cheevos-new/coro.h rename to cheevos/coro.h diff --git a/cheevos/fixup.c b/cheevos/fixup.c new file mode 100644 index 0000000000..67bc4cf2a7 --- /dev/null +++ b/cheevos/fixup.c @@ -0,0 +1,314 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2015-2018 - Andre Leiradella + * + * 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 "fixup.h" +#include "cheevos.h" +#include "util.h" + +#include "../retroarch.h" +#include "../core.h" + +#include "../deps/rcheevos/include/rcheevos.h" +#include "../deps/rcheevos/include/rconsoles.h" + +static int rcheevos_cmpaddr(const void* e1, const void* e2) +{ + const rcheevos_fixup_t* f1 = (const rcheevos_fixup_t*)e1; + const rcheevos_fixup_t* f2 = (const rcheevos_fixup_t*)e2; + + if (f1->address < f2->address) + return -1; + else if (f1->address > f2->address) + return 1; + return 0; +} + +static size_t rcheevos_var_reduce(size_t addr, size_t mask) +{ + while (mask) + { + size_t tmp = (mask - 1) & ~mask; + addr = (addr & tmp) | ((addr >> 1) & ~tmp); + mask = (mask & (mask - 1)) >> 1; + } + + return addr; +} + +static size_t rcheevos_var_highest_bit(size_t n) +{ + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + + return n ^ (n >> 1); +} + +void rcheevos_fixup_init(rcheevos_fixups_t* fixups) +{ + fixups->elements = NULL; + fixups->capacity = fixups->count = 0; + fixups->dirty = false; +} + +void rcheevos_fixup_destroy(rcheevos_fixups_t* fixups) +{ + CHEEVOS_FREE(fixups->elements); + rcheevos_fixup_init(fixups); +} + +const uint8_t* rcheevos_fixup_find( + rcheevos_fixups_t* fixups, unsigned address, int console) +{ + rcheevos_fixup_t key; + rcheevos_fixup_t* found; + const uint8_t* location; + + if (fixups->dirty) + { + qsort(fixups->elements, fixups->count, + sizeof(rcheevos_fixup_t), rcheevos_cmpaddr); + fixups->dirty = false; + } + + key.address = address; + found = (rcheevos_fixup_t*)bsearch(&key, + fixups->elements, fixups->count, + sizeof(rcheevos_fixup_t), rcheevos_cmpaddr); + + if (found) + return found->location; + + if (fixups->count == fixups->capacity) + { + unsigned new_capacity = fixups->capacity == 0 ? 16 : fixups->capacity * 2; + rcheevos_fixup_t* new_elements = (rcheevos_fixup_t*) + realloc(fixups->elements, new_capacity * sizeof(rcheevos_fixup_t)); + + if (!new_elements) + return NULL; + + fixups->elements = new_elements; + fixups->capacity = new_capacity; + } + + fixups->elements[fixups->count].address = address; + fixups->elements[fixups->count++].location = location = + rcheevos_patch_address(address, console); + fixups->dirty = true; + + return location; +} + +const uint8_t* rcheevos_patch_address(unsigned address, int console) +{ + rarch_system_info_t* system = runloop_get_system_info(); + const void* pointer = NULL; + unsigned original_address = address; + + switch (console) + { + case RC_CONSOLE_NINTENDO: + if (address >= 0x0800 && address < 0x2000) + { + /* Address in the mirrorred RAM, + * adjust to real RAM. */ + CHEEVOS_LOG(RCHEEVOS_TAG "NES memory address in mirrorred RAM %X, adjusted to %X\n", address, address & 0x07ff); + address &= 0x07ff; + } + break; + case RC_CONSOLE_GAMEBOY_COLOR: + if (address >= 0xe000 && address <= 0xfdff) + { + /* Address in the echo RAM, adjust to real RAM. */ + CHEEVOS_LOG(RCHEEVOS_TAG "GBC memory address in echo RAM %X, adjusted to %X\n", address, address - 0x2000); + address -= 0x2000; + } + break; + default: + break; + } + + if (system->mmaps.num_descriptors != 0) + { + /* We have memory descriptors, use it. */ + const rarch_memory_descriptor_t* desc = NULL; + const rarch_memory_descriptor_t* end = NULL; + + /* Patch the address to correctly map it to the mmaps. */ + switch (console) + { + case RC_CONSOLE_GAMEBOY_ADVANCE: + if (address < 0x8000) + { + /* Internal RAM. */ + CHEEVOS_LOG(RCHEEVOS_TAG "GBA memory address %X adjusted to %X\n", address, address + 0x3000000); + address += 0x3000000; + } + else + { + /* Work RAM. */ + CHEEVOS_LOG(RCHEEVOS_TAG "GBA memory address %X adjusted to %X\n", address, address + 0x2000000 - 0x8000); + address += 0x2000000 - 0x8000; + } + break; + case RC_CONSOLE_PC_ENGINE: + if (address < 0x002000) + { + /* RAM. */ + CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x1f0000); + address += 0x1f0000; + } + else if (address < 0x012000) + { + /* CD-ROM RAM. */ + CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x100000 - 0x002000); + address += 0x100000 - 0x002000; + } + else if (address < 0x042000) + { + /* Super System Card RAM. */ + CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x0d0000 - 0x012000); + address += 0x0d0000 - 0x012000; + } + else + { + /* CD-ROM battery backed RAM. */ + CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x1ee000 - 0x042000); + address += 0x1ee000 - 0x042000; + } + break; + case RC_CONSOLE_SUPER_NINTENDO: + if (address < 0x020000) + { + /* Work RAM. */ + CHEEVOS_LOG(RCHEEVOS_TAG "SNES memory address %X adjusted to %X\n", address, address + 0x7e0000); + address += 0x7e0000; + } + else + { + /* Save RAM. */ + CHEEVOS_LOG(RCHEEVOS_TAG "SNES memory address %X adjusted to %X\n", address, address + 0x006000 - 0x020000); + address += 0x006000 - 0x020000; + } + break; + case RC_CONSOLE_SEGA_CD: + if (address < 0x010000) + { + /* Work RAM. */ + address += 0xFF0000; + CHEEVOS_LOG(RCHEEVOS_TAG "Sega CD memory address %X adjusted to %X\n", original_address, address); + } + else + { + /* CD-ROM peripheral RAM - exposed at virtual address to avoid banking */ + address += 0x80020000 - 0x010000; + CHEEVOS_LOG(RCHEEVOS_TAG "Sega CD memory address %X adjusted to %X\n", original_address, address); + } + break; + default: + break; + } + + desc = system->mmaps.descriptors; + end = desc + system->mmaps.num_descriptors; + + for (; desc < end; desc++) + { + if (((desc->core.start ^ address) & desc->core.select) == 0) + { + pointer = desc->core.ptr; + address -= desc->core.start; + + if (desc->disconnect_mask) + address = (unsigned)rcheevos_var_reduce( + address & desc->disconnect_mask, desc->core.disconnect); + + if (address >= desc->core.len) + address -= rcheevos_var_highest_bit(address); + + address += desc->core.offset; + + CHEEVOS_LOG(RCHEEVOS_TAG "address %X set to descriptor %d at offset %X\n", original_address, + (int)((desc - system->mmaps.descriptors) + 1), address); + break; + } + } + } + else if (console == RC_CONSOLE_GAMEBOY_ADVANCE) + { + /* The RetroAchievements implementation of memory access + * for GBA puts the save RAM first, + * so the default looping behavior below is backwards. + * + * If the core doesn't expose a + * memory map, say it isn't supported. + */ + pointer = NULL; + } + else + { + unsigned i; + + for (i = 0; i < 4; i++) + { + retro_ctx_memory_info_t meminfo; + + switch (i) + { + case 0: + meminfo.id = RETRO_MEMORY_SYSTEM_RAM; + break; + case 1: + meminfo.id = RETRO_MEMORY_SAVE_RAM; + break; + case 2: + meminfo.id = RETRO_MEMORY_VIDEO_RAM; + break; + case 3: + meminfo.id = RETRO_MEMORY_RTC; + break; + } + + core_get_memory(&meminfo); + + if (address < meminfo.size) + { + pointer = meminfo.data; + break; + } + + /** + * HACK Subtract the correct amount of bytes to + * reach the save RAM as its size is not always + * set correctly in the core. + */ + if (i == 0 && console == RC_CONSOLE_NINTENDO) + address -= 0x6000; + else + address -= meminfo.size; + } + } + + if (!pointer) + { + CHEEVOS_LOG(RCHEEVOS_TAG "address %X not supported\n", original_address); + return NULL; + } + + return (const uint8_t*)pointer + address; +} diff --git a/cheevos-new/fixup.h b/cheevos/fixup.h similarity index 100% rename from cheevos-new/fixup.h rename to cheevos/fixup.h diff --git a/cheevos-new/hash.c b/cheevos/hash.c similarity index 100% rename from cheevos-new/hash.c rename to cheevos/hash.c diff --git a/cheevos-new/hash.h b/cheevos/hash.h similarity index 100% rename from cheevos-new/hash.h rename to cheevos/hash.h diff --git a/cheevos-new/parser.c b/cheevos/parser.c similarity index 99% rename from cheevos-new/parser.c rename to cheevos/parser.c index cb6c4aedf8..a2688d4b78 100644 --- a/cheevos-new/parser.c +++ b/cheevos/parser.c @@ -349,12 +349,10 @@ static char* rcheevos_unescape_string(const char* string, size_t length) *buffer_it++ = escaped_char; string += 2; break; - }; + } } else - { *buffer_it++ = *string++; - } } *buffer_it = '\0'; diff --git a/cheevos-new/parser.h b/cheevos/parser.h similarity index 100% rename from cheevos-new/parser.h rename to cheevos/parser.h diff --git a/cheevos-new/util.h b/cheevos/util.h similarity index 94% rename from cheevos-new/util.h rename to cheevos/util.h index 1794ef3ebb..f94be8d506 100644 --- a/cheevos-new/util.h +++ b/cheevos/util.h @@ -32,7 +32,7 @@ End of setup *****************************************************************************/ #define RCHEEVOS_TAG "[RCHEEVOS]: " -#define CHEEVOS_FREE(p) do { void* q = (void*)p; if (q != NULL) free(q); } while (0) +#define CHEEVOS_FREE(p) do { void* q = (void*)p; if (q) free(q); } while (0) #ifdef CHEEVOS_VERBOSE diff --git a/config.def.h b/config.def.h index fd86393c2b..21314eb899 100644 --- a/config.def.h +++ b/config.def.h @@ -340,6 +340,9 @@ #define DEFAULT_VIDEO_SMOOTH false #endif +/* Graphics context specific scaling */ +#define DEFAULT_VIDEO_CTX_SCALING false + /* On resize and fullscreen, rendering area will stay 4:3 */ #define DEFAULT_FORCE_ASPECT true @@ -406,8 +409,11 @@ #endif #ifdef HAVE_OZONE +/* Ozone colour theme: 1 == Basic Black */ +#define DEFAULT_OZONE_COLOR_THEME 1 #define DEFAULT_OZONE_COLLAPSE_SIDEBAR false #define DEFAULT_OZONE_TRUNCATE_PLAYLIST_NAME true +#define DEFAULT_OZONE_SORT_AFTER_TRUNCATE_PLAYLIST_NAME true #define DEFAULT_OZONE_SCROLL_CONTENT_METADATA false #endif @@ -510,8 +516,10 @@ static const bool menu_show_core_updater = true; static const bool menu_show_legacy_thumbnail_updater = false; static const bool menu_show_sublabels = true; -#define DEFAULT_MENU_TICKER_TYPE (TICKER_TYPE_BOUNCE) -static const float menu_ticker_speed = 1.0f; +static const bool menu_scroll_fast = false; + +#define DEFAULT_MENU_TICKER_TYPE (TICKER_TYPE_LOOP) +static const float menu_ticker_speed = 2.0f; #define DEFAULT_MENU_TICKER_SMOOTH true @@ -532,11 +540,15 @@ static const bool content_show_music = true; #if defined(HAVE_FFMPEG) || defined(HAVE_MPV) static const bool content_show_video = true; #endif -#ifdef HAVE_NETWORKING +#if defined(HAVE_NETWORKING) +#if defined(_3DS) +static const bool content_show_netplay = false; +#else static const bool content_show_netplay = true; #endif +#endif static const bool content_show_history = true; -static const bool content_show_add = true; +static const bool content_show_add = true; static const bool content_show_playlists = true; #ifdef HAVE_XMB @@ -544,7 +556,11 @@ static const unsigned xmb_alpha_factor = 75; static const unsigned menu_font_color_red = 255; static const unsigned menu_font_color_green = 255; static const unsigned menu_font_color_blue = 255; +#ifdef HAVE_ODROIDGO2 +static const unsigned xmb_menu_layout = 2; +#else static const unsigned xmb_menu_layout = 0; +#endif static const unsigned xmb_icon_theme = XMB_ICON_THEME_MONOCHROME; static const unsigned xmb_theme = XMB_THEME_ELECTRIC_BLUE; @@ -599,7 +615,7 @@ static const bool rgui_extended_ascii = false; static const bool default_game_specific_options = true; static const bool default_auto_overrides_enable = true; static const bool default_auto_remaps_enable = true; -static const bool default_global_core_options = true; +static const bool default_global_core_options = false; static const bool default_auto_shaders_enable = true; static const bool default_sort_savefiles_enable = false; @@ -792,6 +808,10 @@ static const bool audio_enable_menu_bgm = false; #define DEFAULT_WASAPI_SH_BUFFER_LENGTH -16 #endif +/* Automatically mute audio when fast forward + * is enabled */ +#define DEFAULT_AUDIO_FASTFORWARD_MUTE false + /* MISC */ /* Enables displaying the current frames per second. */ @@ -900,6 +920,23 @@ static const bool savestate_auto_load = false; static const bool savestate_thumbnail_enable = false; +/* When creating save (srm) files, compress + * written data */ +#if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#define DEFAULT_SAVE_FILE_COMPRESSION true +#else +#define DEFAULT_SAVE_FILE_COMPRESSION false +#endif + +/* When creating save state files, compress + * written data */ +#if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +/* TODO/FIXME Apparently this is an issue on UWP for now, so disable it for now */ +#define DEFAULT_SAVESTATE_FILE_COMPRESSION false +#else +#define DEFAULT_SAVESTATE_FILE_COMPRESSION true +#endif + /* Slowmotion ratio. */ #define DEFAULT_SLOWMOTION_RATIO 3.0 @@ -925,10 +962,27 @@ static const bool stdin_cmd_enable = false; static const uint16_t network_remote_base_port = 55400; -#if defined(ANDROID) || defined(IOS) -static const bool network_on_demand_thumbnails = true; +#define DEFAULT_NETWORK_BUILDBOT_AUTO_EXTRACT_ARCHIVE true +#define DEFAULT_NETWORK_BUILDBOT_SHOW_EXPERIMENTAL_CORES false + +/* Automatically create a backup whenever a core is + * updated via the online updater + * > Enable by default on all modern platforms with + * online updater support */ +#if defined(HAVE_ONLINE_UPDATER) && (defined(__i386__) || defined(__i486__) || defined(__i686__) || defined(__x86_64__) || defined(_M_X64) || defined(_WIN32) || defined(OSX) || defined(ANDROID) || defined(IOS)) +#define DEFAULT_CORE_UPDATER_AUTO_BACKUP true #else -static const bool network_on_demand_thumbnails = false; +#define DEFAULT_CORE_UPDATER_AUTO_BACKUP false +#endif +/* Number of automatic core backups to retain + * (oldest backup will be deleted when creating + * a new one) */ +#define DEFAULT_CORE_UPDATER_AUTO_BACKUP_HISTORY_SIZE 1 + +#if defined(ANDROID) || defined(IOS) +#define DEFAULT_NETWORK_ON_DEMAND_THUMBNAILS true +#else +#define DEFAULT_NETWORK_ON_DEMAND_THUMBNAILS false #endif /* Number of entries that will be kept in content history playlist file. */ @@ -939,22 +993,29 @@ static const unsigned default_content_history_size = 200; static const int default_content_favorites_size = 200; /* Sort all playlists (apart from histories) alphabetically */ -static const bool playlist_sort_alphabetical = true; +#define DEFAULT_PLAYLIST_SORT_ALPHABETICAL true /* File format to use when writing playlists to disk */ -static const bool playlist_use_old_format = false; +#define DEFAULT_PLAYLIST_USE_OLD_FORMAT false + +/* When creating/updating playlists, compress written data */ +#if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#define DEFAULT_PLAYLIST_COMPRESSION true +#else +#define DEFAULT_PLAYLIST_COMPRESSION false +#endif #ifdef HAVE_MENU /* Specify when to display 'core name' inline on playlist entries */ -static const unsigned playlist_show_inline_core_name = PLAYLIST_INLINE_CORE_DISPLAY_HIST_FAV; +#define DEFAULT_PLAYLIST_SHOW_INLINE_CORE_NAME PLAYLIST_INLINE_CORE_DISPLAY_HIST_FAV /* Specifies which runtime record to use on playlist sublabels */ -static const unsigned playlist_sublabel_runtime_type = PLAYLIST_RUNTIME_PER_CORE; +#define DEFAULT_PLAYLIST_SUBLABEL_RUNTIME_TYPE PLAYLIST_RUNTIME_PER_CORE /* Specifies time/date display format for runtime 'last played' data */ #define DEFAULT_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE PLAYLIST_LAST_PLAYED_STYLE_YMD_HMS -static const unsigned playlist_entry_remove_enable = PLAYLIST_ENTRY_REMOVE_ENABLE_ALL; +#define DEFAULT_PLAYLIST_ENTRY_REMOVE_ENABLE PLAYLIST_ENTRY_REMOVE_ENABLE_ALL #endif #define DEFAULT_SCAN_WITHOUT_CORE_MATCH false @@ -972,16 +1033,16 @@ static const unsigned playlist_entry_remove_enable = PLAYLIST_ENTRY_REMOVE_ENABL /* Show Menu start-up screen on boot. */ #define DEFAULT_MENU_SHOW_START_SCREEN true -/* Default scale factor for non-frambuffer-based menu - * drivers and menu widgets */ +/* Default scale factor for non-frambuffer-based display + * drivers and display widgets */ #define DEFAULT_MENU_SCALE_FACTOR 1.0f -/* Specifies whether menu widgets should be scaled +/* Specifies whether display widgets should be scaled * automatically using the default menu scale factor */ #define DEFAULT_MENU_WIDGET_SCALE_AUTO true -/* Default scale factor for menu widgets when widget +/* Default scale factor for display widgets when widget * auto scaling is disabled (fullscreen mode) */ #define DEFAULT_MENU_WIDGET_SCALE_FACTOR 1.0f -/* Default scale factor for menu widgets when widget +/* Default scale factor for display widgets when widget * auto scaling is disabled (windowed mode) */ #define DEFAULT_MENU_WIDGET_SCALE_FACTOR_WINDOWED 1.0f @@ -1033,6 +1094,8 @@ static const unsigned input_bind_timeout = 5; static const unsigned input_bind_hold = 2; +#define DEFAULT_INPUT_HOTKEY_BLOCK_DELAY 5 + static const unsigned gfx_thumbnails_default = 3; static const unsigned menu_left_thumbnails_default = 0; @@ -1040,7 +1103,8 @@ static const unsigned menu_left_thumbnails_default = 0; static const unsigned gfx_thumbnail_upscale_threshold = 0; #ifdef HAVE_MENU -static const unsigned menu_timedate_style = MENU_TIMEDATE_STYLE_DM_HM; +#define DEFAULT_MENU_TIMEDATE_STYLE MENU_TIMEDATE_STYLE_DDMM_HM +#define DEFAULT_MENU_TIMEDATE_DATE_SEPARATOR MENU_TIMEDATE_DATE_SEPARATOR_HYPHEN #endif static const bool xmb_vertical_thumbnails = false; diff --git a/configuration.c b/configuration.c index 157295aabb..f28e885e62 100644 --- a/configuration.c +++ b/configuration.c @@ -314,276 +314,276 @@ enum midi_driver_enum }; #if defined(HAVE_METAL) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_METAL; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_METAL; #elif defined(HAVE_VITA2D) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VITA2D; -#elif (defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(__CELLOS_LV2__)) && !defined(__WINRT__) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL; -#elif defined(HAVE_OPENGL_CORE) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL_CORE; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VITA2D; +#elif (defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(__CELLOS_LV2__)) && !defined(__WINRT__) && !defined(__HAIKU__) +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL; +#elif defined(HAVE_OPENGL_CORE) && !defined(__HAIKU__) +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL_CORE; #elif defined(HAVE_OPENGL1) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL1; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL1; #elif defined(GEKKO) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_WII; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_WII; #elif defined(WIIU) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_WIIU; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_WIIU; #elif defined(XENON) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_XENON360; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_XENON360; #elif defined(HAVE_D3D11) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D11; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D11; #elif defined(HAVE_D3D12) -/* FIXME/WARNING: DX12 performance on Xbox is horrible for +/* FIXME/WARNING: DX12 performance on Xbox is horrible for * some reason. For now, we will default to D3D11 when possible. */ -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D12; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D12; #elif defined(HAVE_D3D10) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D10; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D10; #elif defined(HAVE_D3D9) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D9; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D9; #elif defined(HAVE_D3D8) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D8; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D8; #elif defined(HAVE_VG) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VG; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VG; #elif defined(PSP) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_PSP1; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_PSP1; #elif defined(PS2) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_PS2; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_PS2; #elif defined(_3DS) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_CTR; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_CTR; #elif defined(SWITCH) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SWITCH; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SWITCH; #elif defined(HAVE_XVIDEO) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_XVIDEO; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_XVIDEO; #elif defined(HAVE_SDL) && !defined(HAVE_SDL_DINGUX) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL; #elif defined(HAVE_SDL2) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL2; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL2; #elif defined(HAVE_SDL_DINGUX) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL_DINGUX; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL_DINGUX; #elif defined(_WIN32) && !defined(_XBOX) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GDI; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GDI; #elif defined(DJGPP) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VGA; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VGA; #elif defined(HAVE_FPGA) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_FPGA; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_FPGA; #elif defined(HAVE_DYLIB) && !defined(ANDROID) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_EXT; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_EXT; #else -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_NULL; +static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_NULL; #endif #if defined(__CELLOS_LV2__) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PS3; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PS3; #elif defined(XENON) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_XENON360; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_XENON360; #elif defined(GEKKO) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_WII; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_WII; #elif defined(WIIU) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_WIIU; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_WIIU; #elif defined(PSP) || defined(VITA) || defined(ORBIS) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PSP; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PSP; #elif defined(PS2) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PS2; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PS2; #elif defined(_3DS) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_CTR; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_CTR; #elif defined(SWITCH) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SWITCH; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SWITCH; #elif defined(HAVE_PULSE) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PULSE; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PULSE; #elif defined(HAVE_ALSA) && defined(HAVE_VIDEOCORE) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_ALSATHREAD; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_ALSATHREAD; #elif defined(HAVE_ALSA) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_ALSA; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_ALSA; #elif defined(HAVE_TINYALSA) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_TINYALSA; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_TINYALSA; #elif defined(HAVE_AUDIOIO) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_AUDIOIO; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_AUDIOIO; #elif defined(HAVE_OSS) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_OSS; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_OSS; #elif defined(HAVE_JACK) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_JACK; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_JACK; #elif defined(HAVE_COREAUDIO) && !defined(HAVE_COCOA_METAL) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_COREAUDIO; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_COREAUDIO; #elif defined(HAVE_COREAUDIO3) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_COREAUDIO3; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_COREAUDIO3; #elif defined(HAVE_XAUDIO) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_XAUDIO; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_XAUDIO; #elif defined(HAVE_DSOUND) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_DSOUND; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_DSOUND; #elif defined(HAVE_WASAPI) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_WASAPI; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_WASAPI; #elif defined(HAVE_AL) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_AL; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_AL; #elif defined(HAVE_SL) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SL; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SL; #elif defined(EMSCRIPTEN) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_RWEBAUDIO; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_RWEBAUDIO; #elif defined(HAVE_SDL) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SDL; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SDL; #elif defined(HAVE_SDL2) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SDL2; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SDL2; #elif defined(HAVE_RSOUND) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_RSOUND; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_RSOUND; #elif defined(HAVE_ROAR) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_ROAR; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_ROAR; #elif defined(HAVE_DYLIB) && !defined(ANDROID) -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_EXT; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_EXT; #else -static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_NULL; +static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_NULL; #endif #if defined(PSP) || defined(EMSCRIPTEN) -static enum audio_resampler_driver_enum AUDIO_DEFAULT_RESAMPLER_DRIVER = AUDIO_RESAMPLER_CC; +static const enum audio_resampler_driver_enum AUDIO_DEFAULT_RESAMPLER_DRIVER = AUDIO_RESAMPLER_CC; #else -static enum audio_resampler_driver_enum AUDIO_DEFAULT_RESAMPLER_DRIVER = AUDIO_RESAMPLER_SINC; +static const enum audio_resampler_driver_enum AUDIO_DEFAULT_RESAMPLER_DRIVER = AUDIO_RESAMPLER_SINC; #endif #if defined(HAVE_FFMPEG) -static enum record_driver_enum RECORD_DEFAULT_DRIVER = RECORD_FFMPEG; +static const enum record_driver_enum RECORD_DEFAULT_DRIVER = RECORD_FFMPEG; #else -static enum record_driver_enum RECORD_DEFAULT_DRIVER = RECORD_NULL; +static const enum record_driver_enum RECORD_DEFAULT_DRIVER = RECORD_NULL; #endif #ifdef HAVE_WINMM -static enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_WINMM; +static const enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_WINMM; #elif defined(HAVE_ALSA) && !defined(HAVE_HAKCHI) && !defined(HAVE_SEGAM) -static enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_ALSA; +static const enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_ALSA; #else -static enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_NULL; +static const enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_NULL; #endif #if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_UWP; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_UWP; #elif defined(XENON) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_XENON360; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_XENON360; #elif defined(_XBOX360) || defined(_XBOX) || defined(HAVE_XINPUT2) || defined(HAVE_XINPUT_XBOX1) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_XINPUT; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_XINPUT; #elif defined(ANDROID) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_ANDROID; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_ANDROID; #elif defined(EMSCRIPTEN) && defined(HAVE_SDL2) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SDL2; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SDL2; #elif defined(EMSCRIPTEN) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_RWEBINPUT; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_RWEBINPUT; #elif defined(_WIN32) && defined(HAVE_DINPUT) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_DINPUT; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_DINPUT; #elif defined(_WIN32) && !defined(HAVE_DINPUT) && _WIN32_WINNT >= 0x0501 -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WINRAW; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WINRAW; #elif defined(ORBIS) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PS4; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PS4; #elif defined(__CELLOS_LV2__) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PS3; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PS3; #elif defined(PSP) || defined(VITA) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PSP; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PSP; #elif defined(PS2) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PS2; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PS2; #elif defined(_3DS) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_CTR; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_CTR; #elif defined(SWITCH) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SWITCH; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SWITCH; #elif defined(GEKKO) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WII; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WII; #elif defined(WIIU) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WIIU; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WIIU; #elif defined(HAVE_X11) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_X; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_X; #elif defined(HAVE_UDEV) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_UDEV; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_UDEV; #elif defined(__linux__) && !defined(ANDROID) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_LINUXRAW; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_LINUXRAW; #elif defined(HAVE_WAYLAND) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WAYLAND; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WAYLAND; #elif defined(HAVE_COCOA) || defined(HAVE_COCOATOUCH) || defined(HAVE_COCOA_METAL) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_COCOA; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_COCOA; #elif defined(__QNX__) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_QNX; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_QNX; #elif defined(HAVE_SDL) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SDL; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SDL; #elif defined(HAVE_SDL2) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SDL2; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SDL2; #elif defined(DJGPP) -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_DOS; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_DOS; #else -static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_NULL; +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_NULL; #endif #if defined(__CELLOS_LV2__) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PS3; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PS3; #elif defined(HAVE_XINPUT) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_XINPUT; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_XINPUT; #elif defined(GEKKO) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_GX; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_GX; #elif defined(WIIU) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_WIIU; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_WIIU; #elif defined(_XBOX) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_XDK; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_XDK; #elif defined(ORBIS) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PS4; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PS4; #elif defined(PSP) || defined(VITA) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PSP; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PSP; #elif defined(PS2) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PS2; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PS2; #elif defined(_3DS) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_CTR; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_CTR; #elif defined(SWITCH) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_SWITCH; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_SWITCH; #elif defined(HAVE_DINPUT) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_DINPUT; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_DINPUT; #elif defined(HAVE_UDEV) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_UDEV; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_UDEV; #elif defined(__linux) && !defined(ANDROID) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_LINUXRAW; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_LINUXRAW; #elif defined(ANDROID) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_ANDROID; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_ANDROID; #elif defined(HAVE_SDL) || defined(HAVE_SDL2) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_SDL; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_SDL; #elif defined(DJGPP) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_DOS; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_DOS; #elif defined(IOS) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_MFI; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_MFI; #elif defined(HAVE_HID) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_HID; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_HID; #elif defined(__QNX__) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_QNX; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_QNX; #elif defined(EMSCRIPTEN) -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_RWEBPAD; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_RWEBPAD; #else -static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_NULL; +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_NULL; #endif #if defined(HAVE_V4L2) -static enum camera_driver_enum CAMERA_DEFAULT_DRIVER = CAMERA_V4L2; +static const enum camera_driver_enum CAMERA_DEFAULT_DRIVER = CAMERA_V4L2; #elif defined(EMSCRIPTEN) -static enum camera_driver_enum CAMERA_DEFAULT_DRIVER = CAMERA_RWEBCAM; +static const enum camera_driver_enum CAMERA_DEFAULT_DRIVER = CAMERA_RWEBCAM; #elif defined(ANDROID) -static enum camera_driver_enum CAMERA_DEFAULT_DRIVER = CAMERA_ANDROID; +static const enum camera_driver_enum CAMERA_DEFAULT_DRIVER = CAMERA_ANDROID; #else -static enum camera_driver_enum CAMERA_DEFAULT_DRIVER = CAMERA_NULL; +static const enum camera_driver_enum CAMERA_DEFAULT_DRIVER = CAMERA_NULL; #endif #if defined(HAVE_LAKKA) -static enum wifi_driver_enum WIFI_DEFAULT_DRIVER = WIFI_CONNMANCTL; +static const enum wifi_driver_enum WIFI_DEFAULT_DRIVER = WIFI_CONNMANCTL; #else -static enum wifi_driver_enum WIFI_DEFAULT_DRIVER = WIFI_NULL; +static const enum wifi_driver_enum WIFI_DEFAULT_DRIVER = WIFI_NULL; #endif #if defined(ANDROID) -static enum location_driver_enum LOCATION_DEFAULT_DRIVER = LOCATION_ANDROID; +static const enum location_driver_enum LOCATION_DEFAULT_DRIVER = LOCATION_ANDROID; #else -static enum location_driver_enum LOCATION_DEFAULT_DRIVER = LOCATION_NULL; +static const enum location_driver_enum LOCATION_DEFAULT_DRIVER = LOCATION_NULL; #endif #if defined(_3DS) && defined(HAVE_RGUI) -static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_RGUI; +static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_RGUI; #else #if defined(HAVE_MATERIALUI) && defined(RARCH_MOBILE) -static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_MATERIALUI; +static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_MATERIALUI; #elif defined(HAVE_OZONE) -static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_OZONE; +static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_OZONE; #elif defined(HAVE_XMB) && !defined(_XBOX) -static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_XMB; +static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_XMB; #elif defined(HAVE_RGUI) -static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_RGUI; +static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_RGUI; #else -static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_NULL; +static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_NULL; #endif #endif @@ -1180,7 +1180,8 @@ static struct config_array_setting *populate_settings_array(settings_t *settings return tmp; } -static struct config_path_setting *populate_settings_path(settings_t *settings, int *size) +static struct config_path_setting *populate_settings_path( + settings_t *settings, int *size) { unsigned count = 0; struct config_path_setting *tmp = (struct config_path_setting*)calloc(1, (*size + 1) * sizeof(struct config_path_setting)); @@ -1326,7 +1327,8 @@ static struct config_path_setting *populate_settings_path(settings_t *settings, return tmp; } -static struct config_bool_setting *populate_settings_bool(settings_t *settings, int *size) +static struct config_bool_setting *populate_settings_bool( + settings_t *settings, int *size) { struct config_bool_setting *tmp = (struct config_bool_setting*)calloc(1, (*size + 1) * sizeof(struct config_bool_setting)); unsigned count = 0; @@ -1343,7 +1345,6 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("desktop_menu_enable", &settings->bools.desktop_menu_enable, true, DEFAULT_DESKTOP_MENU_ENABLE, false); SETTING_BOOL("video_gpu_record", &settings->bools.video_gpu_record, true, DEFAULT_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, DEFAULT_ALL_USERS_CONTROL_MENU, false); SETTING_BOOL("menu_swap_ok_cancel_buttons", &settings->bools.input_menu_swap_ok_cancel_buttons, true, DEFAULT_MENU_SWAP_OK_CANCEL_BUTTONS, false); #ifdef HAVE_NETWORKING SETTING_BOOL("netplay_public_announce", &settings->bools.netplay_public_announce, true, DEFAULT_NETPLAY_PUBLIC_ANNOUNCE, false); @@ -1369,7 +1370,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("netplay_request_device_p14", &settings->bools.netplay_request_devices[13], true, false, false); SETTING_BOOL("netplay_request_device_p15", &settings->bools.netplay_request_devices[14], true, false, false); SETTING_BOOL("netplay_request_device_p16", &settings->bools.netplay_request_devices[15], true, false, false); - SETTING_BOOL("network_on_demand_thumbnails", &settings->bools.network_on_demand_thumbnails, true, network_on_demand_thumbnails, false); + SETTING_BOOL("network_on_demand_thumbnails", &settings->bools.network_on_demand_thumbnails, true, DEFAULT_NETWORK_ON_DEMAND_THUMBNAILS, false); #endif SETTING_BOOL("input_descriptor_label_show", &settings->bools.input_descriptor_label_show, true, input_descriptor_label_show, false); SETTING_BOOL("input_descriptor_hide_unbound", &settings->bools.input_descriptor_hide_unbound, true, input_descriptor_hide_unbound, false); @@ -1402,6 +1403,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("video_crop_overscan", &settings->bools.video_crop_overscan, true, DEFAULT_CROP_OVERSCAN, false); SETTING_BOOL("video_scale_integer", &settings->bools.video_scale_integer, true, DEFAULT_SCALE_INTEGER, false); SETTING_BOOL("video_smooth", &settings->bools.video_smooth, true, DEFAULT_VIDEO_SMOOTH, false); + SETTING_BOOL("video_ctx_scaling", &settings->bools.video_ctx_scaling, true, DEFAULT_VIDEO_CTX_SCALING, false); SETTING_BOOL("video_force_aspect", &settings->bools.video_force_aspect, true, DEFAULT_FORCE_ASPECT, false); SETTING_BOOL("video_threaded", video_driver_get_threaded(), true, DEFAULT_VIDEO_THREADED, false); SETTING_BOOL("video_shared_context", &settings->bools.video_shared_context, true, DEFAULT_VIDEO_SHARED_CONTEXT, false); @@ -1431,9 +1433,12 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, #ifdef HAVE_AUDIOMIXER SETTING_BOOL("audio_mixer_mute_enable", audio_get_bool_ptr(AUDIO_ACTION_MIXER_MUTE_ENABLE), true, false, false); #endif + SETTING_BOOL("audio_fastforward_mute", &settings->bools.audio_fastforward_mute, true, DEFAULT_AUDIO_FASTFORWARD_MUTE, false); SETTING_BOOL("location_allow", &settings->bools.location_allow, true, false, false); SETTING_BOOL("video_font_enable", &settings->bools.video_font_enable, true, DEFAULT_FONT_ENABLE, false); - SETTING_BOOL("core_updater_auto_extract_archive", &settings->bools.network_buildbot_auto_extract_archive, true, true, false); + SETTING_BOOL("core_updater_auto_extract_archive", &settings->bools.network_buildbot_auto_extract_archive, true, DEFAULT_NETWORK_BUILDBOT_AUTO_EXTRACT_ARCHIVE, false); + SETTING_BOOL("core_updater_show_experimental_cores", &settings->bools.network_buildbot_show_experimental_cores, true, DEFAULT_NETWORK_BUILDBOT_SHOW_EXPERIMENTAL_CORES, false); + SETTING_BOOL("core_updater_auto_backup", &settings->bools.core_updater_auto_backup, true, DEFAULT_CORE_UPDATER_AUTO_BACKUP, false); SETTING_BOOL("camera_allow", &settings->bools.camera_allow, true, false, false); SETTING_BOOL("discord_allow", &settings->bools.discord_enable, true, false, false); #if defined(VITA) @@ -1452,7 +1457,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, #ifdef HAVE_MENU SETTING_BOOL("menu_unified_controls", &settings->bools.menu_unified_controls, true, false, false); SETTING_BOOL("menu_throttle_framerate", &settings->bools.menu_throttle_framerate, true, true, false); - SETTING_BOOL("menu_linear_filter", &settings->bools.menu_linear_filter, true, true, false); + SETTING_BOOL("menu_linear_filter", &settings->bools.menu_linear_filter, true, DEFAULT_VIDEO_SMOOTH, false); SETTING_BOOL("menu_horizontal_animation", &settings->bools.menu_horizontal_animation, true, DEFAULT_MENU_HORIZONTAL_ANIMATION, false); SETTING_BOOL("menu_pause_libretro", &settings->bools.menu_pause_libretro, true, true, false); SETTING_BOOL("menu_savestate_resume", &settings->bools.menu_savestate_resume, true, menu_savestate_resume, false); @@ -1465,6 +1470,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("menu_show_sublabels", &settings->bools.menu_show_sublabels, true, menu_show_sublabels, false); SETTING_BOOL("menu_dynamic_wallpaper_enable", &settings->bools.menu_dynamic_wallpaper_enable, true, false, false); SETTING_BOOL("menu_ticker_smooth", &settings->bools.menu_ticker_smooth, true, DEFAULT_MENU_TICKER_SMOOTH, false); + SETTING_BOOL("menu_scroll_fast", &settings->bools.menu_scroll_fast, true, false, false); SETTING_BOOL("settings_show_drivers", &settings->bools.settings_show_drivers, true, DEFAULT_SETTINGS_SHOW_DRIVERS, false); SETTING_BOOL("settings_show_video", &settings->bools.settings_show_video, true, DEFAULT_SETTINGS_SHOW_VIDEO, false); SETTING_BOOL("settings_show_audio", &settings->bools.settings_show_audio, true, DEFAULT_SETTINGS_SHOW_AUDIO, false); @@ -1585,6 +1591,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("cheevos_verbose_enable", &settings->bools.cheevos_verbose_enable, true, false, false); SETTING_BOOL("cheevos_auto_screenshot", &settings->bools.cheevos_auto_screenshot, true, false, false); SETTING_BOOL("cheevos_badges_enable", &settings->bools.cheevos_badges_enable, true, false, false); + SETTING_BOOL("cheevos_start_active", &settings->bools.cheevos_start_active, true, false, false); #endif #ifdef HAVE_OVERLAY SETTING_BOOL("input_overlay_enable", &settings->bools.input_overlay_enable, true, config_overlay_enable_default(), false); @@ -1612,6 +1619,8 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("savestate_auto_save", &settings->bools.savestate_auto_save, true, savestate_auto_save, false); SETTING_BOOL("savestate_auto_load", &settings->bools.savestate_auto_load, true, savestate_auto_load, false); SETTING_BOOL("savestate_thumbnail_enable", &settings->bools.savestate_thumbnail_enable, true, savestate_thumbnail_enable, false); + SETTING_BOOL("save_file_compression", &settings->bools.save_file_compression, true, DEFAULT_SAVE_FILE_COMPRESSION, false); + SETTING_BOOL("savestate_file_compression", &settings->bools.savestate_file_compression, true, DEFAULT_SAVESTATE_FILE_COMPRESSION, false); SETTING_BOOL("history_list_enable", &settings->bools.history_list_enable, true, DEFAULT_HISTORY_LIST_ENABLE, false); SETTING_BOOL("playlist_entry_rename", &settings->bools.playlist_entry_rename, true, DEFAULT_PLAYLIST_ENTRY_RENAME, false); SETTING_BOOL("game_specific_options", &settings->bools.game_specific_options, true, default_game_specific_options, false); @@ -1646,11 +1655,12 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("video_3ds_lcd_bottom", &settings->bools.video_3ds_lcd_bottom, true, video_3ds_lcd_bottom, false); #endif - SETTING_BOOL("playlist_use_old_format", &settings->bools.playlist_use_old_format, true, playlist_use_old_format, false); + SETTING_BOOL("playlist_use_old_format", &settings->bools.playlist_use_old_format, true, DEFAULT_PLAYLIST_USE_OLD_FORMAT, false); + SETTING_BOOL("playlist_compression", &settings->bools.playlist_compression, true, DEFAULT_PLAYLIST_COMPRESSION, false); SETTING_BOOL("content_runtime_log", &settings->bools.content_runtime_log, true, DEFAULT_CONTENT_RUNTIME_LOG, false); SETTING_BOOL("content_runtime_log_aggregate", &settings->bools.content_runtime_log_aggregate, true, DEFAULT_CONTENT_RUNTIME_LOG_AGGREGATE, false); SETTING_BOOL("playlist_show_sublabels", &settings->bools.playlist_show_sublabels, true, DEFAULT_PLAYLIST_SHOW_SUBLABELS, false); - SETTING_BOOL("playlist_sort_alphabetical", &settings->bools.playlist_sort_alphabetical, true, playlist_sort_alphabetical, false); + SETTING_BOOL("playlist_sort_alphabetical", &settings->bools.playlist_sort_alphabetical, true, DEFAULT_PLAYLIST_SORT_ALPHABETICAL, false); SETTING_BOOL("playlist_fuzzy_archive_match", &settings->bools.playlist_fuzzy_archive_match, true, DEFAULT_PLAYLIST_FUZZY_ARCHIVE_MATCH, false); SETTING_BOOL("quit_press_twice", &settings->bools.quit_press_twice, true, DEFAULT_QUIT_PRESS_TWICE, false); @@ -1660,6 +1670,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, #ifdef HAVE_OZONE SETTING_BOOL("ozone_collapse_sidebar", &settings->bools.ozone_collapse_sidebar, true, DEFAULT_OZONE_COLLAPSE_SIDEBAR, false); SETTING_BOOL("ozone_truncate_playlist_name", &settings->bools.ozone_truncate_playlist_name, true, DEFAULT_OZONE_TRUNCATE_PLAYLIST_NAME, false); + SETTING_BOOL("ozone_sort_after_truncate_playlist_name", &settings->bools.ozone_sort_after_truncate_playlist_name, true, DEFAULT_OZONE_SORT_AFTER_TRUNCATE_PLAYLIST_NAME, false); SETTING_BOOL("ozone_scroll_content_metadata",&settings->bools.ozone_scroll_content_metadata, true, DEFAULT_OZONE_SCROLL_CONTENT_METADATA, false); #endif SETTING_BOOL("log_to_file", &settings->bools.log_to_file, true, DEFAULT_LOG_TO_FILE, false); @@ -1673,7 +1684,8 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, return tmp; } -static struct config_float_setting *populate_settings_float(settings_t *settings, int *size) +static struct config_float_setting *populate_settings_float( + settings_t *settings, int *size) { unsigned count = 0; struct config_float_setting *tmp = (struct config_float_setting*)calloc(1, (*size + 1) * sizeof(struct config_float_setting)); @@ -1694,11 +1706,15 @@ static struct config_float_setting *populate_settings_float(settings_t *settings #ifdef HAVE_OVERLAY SETTING_FLOAT("input_overlay_opacity", &settings->floats.input_overlay_opacity, true, DEFAULT_INPUT_OVERLAY_OPACITY, false); SETTING_FLOAT("input_overlay_scale", &settings->floats.input_overlay_scale, true, 1.0f, false); + SETTING_FLOAT("input_overlay_center_x", &settings->floats.input_overlay_center_x, true, 0.5f, false); + SETTING_FLOAT("input_overlay_center_y", &settings->floats.input_overlay_center_y, true, 0.5f, false); #endif #ifdef HAVE_MENU SETTING_FLOAT("menu_scale_factor", &settings->floats.menu_scale_factor, true, DEFAULT_MENU_SCALE_FACTOR, false); SETTING_FLOAT("menu_widget_scale_factor", &settings->floats.menu_widget_scale_factor, true, DEFAULT_MENU_WIDGET_SCALE_FACTOR, false); +#if !(defined(RARCH_CONSOLE) || defined(RARCH_MOBILE)) SETTING_FLOAT("menu_widget_scale_factor_windowed", &settings->floats.menu_widget_scale_factor_windowed, true, DEFAULT_MENU_WIDGET_SCALE_FACTOR_WINDOWED, false); +#endif SETTING_FLOAT("menu_wallpaper_opacity", &settings->floats.menu_wallpaper_opacity, true, menu_wallpaper_opacity, false); SETTING_FLOAT("menu_framebuffer_opacity", &settings->floats.menu_framebuffer_opacity, true, menu_framebuffer_opacity, false); SETTING_FLOAT("menu_footer_opacity", &settings->floats.menu_footer_opacity, true, menu_footer_opacity, false); @@ -1721,7 +1737,8 @@ static struct config_float_setting *populate_settings_float(settings_t *settings return tmp; } -static struct config_uint_setting *populate_settings_uint(settings_t *settings, int *size) +static struct config_uint_setting *populate_settings_uint( + settings_t *settings, int *size) { unsigned count = 0; struct config_uint_setting *tmp = (struct config_uint_setting*)calloc(1, (*size + 1) * sizeof(struct config_uint_setting)); @@ -1743,6 +1760,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("input_max_users", input_driver_get_uint(INPUT_ACTION_MAX_USERS), true, input_max_users, false); SETTING_UINT("fps_update_interval", &settings->uints.fps_update_interval, true, DEFAULT_FPS_UPDATE_INTERVAL, false); SETTING_UINT("input_menu_toggle_gamepad_combo", &settings->uints.input_menu_toggle_gamepad_combo, true, menu_toggle_gamepad_combo, false); + SETTING_UINT("input_hotkey_block_delay", &settings->uints.input_hotkey_block_delay, true, DEFAULT_INPUT_HOTKEY_BLOCK_DELAY, false); #ifdef GEKKO SETTING_UINT("input_mouse_scale", &settings->uints.input_mouse_scale, true, DEFAULT_MOUSE_SCALE, false); #endif @@ -1782,7 +1800,8 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("menu_thumbnails", &settings->uints.gfx_thumbnails, true, gfx_thumbnails_default, false); SETTING_UINT("menu_left_thumbnails", &settings->uints.menu_left_thumbnails, true, menu_left_thumbnails_default, false); SETTING_UINT("menu_thumbnail_upscale_threshold", &settings->uints.gfx_thumbnail_upscale_threshold, true, gfx_thumbnail_upscale_threshold, false); - SETTING_UINT("menu_timedate_style", &settings->uints.menu_timedate_style, true, menu_timedate_style, false); + SETTING_UINT("menu_timedate_style", &settings->uints.menu_timedate_style, true, DEFAULT_MENU_TIMEDATE_STYLE, false); + SETTING_UINT("menu_timedate_date_separator", &settings->uints.menu_timedate_date_separator, true, DEFAULT_MENU_TIMEDATE_DATE_SEPARATOR, false); SETTING_UINT("menu_ticker_type", &settings->uints.menu_ticker_type, true, DEFAULT_MENU_TICKER_TYPE, false); #ifdef HAVE_RGUI SETTING_UINT("rgui_menu_color_theme", &settings->uints.menu_rgui_color_theme, true, DEFAULT_RGUI_COLOR_THEME, false); @@ -1823,7 +1842,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("materialui_landscape_layout_optimization", &settings->uints.menu_materialui_landscape_layout_optimization, true, DEFAULT_MATERIALUI_LANDSCAPE_LAYOUT_OPTIMIZATION, false); SETTING_UINT("menu_shader_pipeline", &settings->uints.menu_xmb_shader_pipeline, true, DEFAULT_MENU_SHADER_PIPELINE, false); #ifdef HAVE_OZONE - SETTING_UINT("ozone_menu_color_theme", &settings->uints.menu_ozone_color_theme, true, 1, false); + SETTING_UINT("ozone_menu_color_theme", &settings->uints.menu_ozone_color_theme, true, DEFAULT_OZONE_COLOR_THEME, false); #endif #endif SETTING_UINT("audio_out_rate", &settings->uints.audio_out_rate, true, DEFAULT_OUTPUT_RATE, false); @@ -1890,18 +1909,21 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, #endif #ifdef HAVE_MENU - SETTING_UINT("playlist_entry_remove_enable", &settings->uints.playlist_entry_remove_enable, true, playlist_entry_remove_enable, false); - SETTING_UINT("playlist_show_inline_core_name", &settings->uints.playlist_show_inline_core_name, true, playlist_show_inline_core_name, false); - SETTING_UINT("playlist_sublabel_runtime_type", &settings->uints.playlist_sublabel_runtime_type, true, playlist_sublabel_runtime_type, false); + SETTING_UINT("playlist_entry_remove_enable", &settings->uints.playlist_entry_remove_enable, true, DEFAULT_PLAYLIST_ENTRY_REMOVE_ENABLE, false); + SETTING_UINT("playlist_show_inline_core_name", &settings->uints.playlist_show_inline_core_name, true, DEFAULT_PLAYLIST_SHOW_INLINE_CORE_NAME, false); + SETTING_UINT("playlist_sublabel_runtime_type", &settings->uints.playlist_sublabel_runtime_type, true, DEFAULT_PLAYLIST_SUBLABEL_RUNTIME_TYPE, false); SETTING_UINT("playlist_sublabel_last_played_style", &settings->uints.playlist_sublabel_last_played_style, true, DEFAULT_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE, false); #endif + SETTING_UINT("core_updater_auto_backup_history_size", &settings->uints.core_updater_auto_backup_history_size, true, DEFAULT_CORE_UPDATER_AUTO_BACKUP_HISTORY_SIZE, false); + *size = count; return tmp; } -static struct config_size_setting *populate_settings_size(settings_t *settings, int *size) +static struct config_size_setting *populate_settings_size( + settings_t *settings, int *size) { unsigned count = 0; struct config_size_setting *tmp = (struct config_size_setting*)calloc((*size + 1), sizeof(struct config_size_setting)); @@ -1916,7 +1938,8 @@ static struct config_size_setting *populate_settings_size(settings_t *settings, return tmp; } -static struct config_int_setting *populate_settings_int(settings_t *settings, int *size) +static struct config_int_setting *populate_settings_int( + settings_t *settings, int *size) { unsigned count = 0; struct config_int_setting *tmp = (struct config_int_setting*)calloc((*size + 1), sizeof(struct config_int_setting)); @@ -2492,20 +2515,30 @@ static bool check_menu_driver_compatibility(settings_t *settings) return true; /* TODO/FIXME - maintenance hazard */ - if (string_is_equal(video_driver, "d3d9") || - string_is_equal(video_driver, "d3d10") || - string_is_equal(video_driver, "d3d11") || - string_is_equal(video_driver, "d3d12") || + if (string_starts_with(video_driver, "d3d")) + if ( + string_is_equal(video_driver, "d3d9") || + string_is_equal(video_driver, "d3d10") || + string_is_equal(video_driver, "d3d11") || + string_is_equal(video_driver, "d3d12") + ) + return true; + if (string_starts_with(video_driver, "gl")) + if ( + string_is_equal(video_driver, "gl") || + string_is_equal(video_driver, "gl1") || + string_is_equal(video_driver, "glcore") + ) + return true; + if ( string_is_equal(video_driver, "caca") || string_is_equal(video_driver, "gdi") || - string_is_equal(video_driver, "gl") || - string_is_equal(video_driver, "gl1") || string_is_equal(video_driver, "gx2") || string_is_equal(video_driver, "vulkan") || - string_is_equal(video_driver, "glcore") || string_is_equal(video_driver, "metal") || string_is_equal(video_driver, "ctr") || - string_is_equal(video_driver, "vita2d")) + string_is_equal(video_driver, "vita2d") + ) return true; return false; @@ -2666,7 +2699,7 @@ static config_file_t *open_default_config_file(void) skeleton_conf[0] = '\0'; - /* Build a retroarch.cfg path from the + /* Build a retroarch.cfg path from the * global config directory (/etc). */ fill_pathname_join(skeleton_conf, GLOBAL_CONFIG_DIR, file_path_str(FILE_PATH_MAIN_CONFIG), path_size); @@ -2681,7 +2714,7 @@ static config_file_t *open_default_config_file(void) if (conf) { - /* Since this is a clean config file, we can + /* Since this is a clean config file, we can * safely use config_save_on_exit. */ config_set_bool(conf, "config_save_on_exit", true); saved = config_file_write(conf, conf_path, true); @@ -3342,7 +3375,7 @@ bool config_load_override(void *data) /* Create a new config file from core_path */ if (config_file_exists(core_path)) { - RARCH_LOG("[Overrides] core-specific overrides found at %s.\n", + RARCH_LOG("[Overrides]: Core-specific overrides found at %s.\n", core_path); path_set(RARCH_PATH_CONFIG_APPEND, core_path); @@ -3350,7 +3383,7 @@ bool config_load_override(void *data) should_append = true; } else - RARCH_LOG("[Overrides] no core-specific overrides found at %s.\n", + RARCH_LOG("[Overrides]: No core-specific overrides found at %s.\n", core_path); /* per-content-dir overrides */ @@ -3361,12 +3394,12 @@ bool config_load_override(void *data) temp_path[0] = '\0'; - RARCH_LOG("[Overrides] content-dir-specific overrides found at %s.\n", + RARCH_LOG("[Overrides]: Content dir-specific overrides found at %s.\n", game_path); if (should_append) { - RARCH_LOG("[Overrides] content-dir-specific overrides stacking on top of previous overrides.\n"); + RARCH_LOG("[Overrides]: Content dir-specific overrides stacking on top of previous overrides.\n"); strlcpy(temp_path, path_get(RARCH_PATH_CONFIG_APPEND), path_size); strlcat(temp_path, "|", path_size); strlcat(temp_path, content_path, path_size); @@ -3381,7 +3414,7 @@ bool config_load_override(void *data) should_append = true; } else - RARCH_LOG("[Overrides] no content-dir-specific overrides found at %s.\n", + RARCH_LOG("[Overrides]: No content-dir-specific overrides found at %s.\n", content_path); /* per-game overrides */ @@ -3392,12 +3425,12 @@ bool config_load_override(void *data) temp_path[0] = '\0'; - RARCH_LOG("[Overrides] game-specific overrides found at %s.\n", + RARCH_LOG("[Overrides]: Game-specific overrides found at %s.\n", game_path); if (should_append) { - RARCH_LOG("[Overrides] game-specific overrides stacking on top of previous overrides\n"); + RARCH_LOG("[Overrides]: game-specific overrides stacking on top of previous overrides\n"); strlcpy(temp_path, path_get(RARCH_PATH_CONFIG_APPEND), path_size); strlcat(temp_path, "|", path_size); strlcat(temp_path, game_path, path_size); @@ -3412,7 +3445,7 @@ bool config_load_override(void *data) should_append = true; } else - RARCH_LOG("[Overrides] no game-specific overrides found at %s.\n", + RARCH_LOG("[Overrides]: No game-specific overrides found at %s.\n", game_path); if (!should_append) @@ -3481,7 +3514,7 @@ bool config_unload_override(void) path_get(RARCH_PATH_CONFIG), config_get_ptr())) return false; - RARCH_LOG("[Overrides] configuration overrides unloaded, original configuration restored.\n"); + RARCH_LOG("[Overrides]: Configuration overrides unloaded, original configuration restored.\n"); /* Reset save paths */ retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL); @@ -3516,6 +3549,7 @@ bool config_load_remap(const char *directory_input_remapping, const char *core_name = system ? system->info.library_name : NULL; const char *rarch_path_basename = path_get(RARCH_PATH_BASENAME); const char *game_name = path_basename(rarch_path_basename); + enum msg_hash_enums msg_remap_loaded = MSG_GAME_REMAP_FILE_LOADED; char content_dir_name[PATH_MAX_LENGTH]; if (string_is_empty(core_name) || string_is_empty(game_name)) @@ -3577,6 +3611,8 @@ bool config_load_remap(const char *directory_input_remapping, if (input_remapping_load_file(new_conf, game_path)) { rarch_ctl(RARCH_CTL_SET_REMAPS_GAME_ACTIVE, NULL); + /* msg_remap_loaded is set to MSG_GAME_REMAP_FILE_LOADED + * by default - no need to change it here */ goto success; } } @@ -3588,6 +3624,7 @@ bool config_load_remap(const char *directory_input_remapping, if (input_remapping_load_file(new_conf, content_path)) { rarch_ctl(RARCH_CTL_SET_REMAPS_CONTENT_DIR_ACTIVE, NULL); + msg_remap_loaded = MSG_DIRECTORY_REMAP_FILE_LOADED; goto success; } } @@ -3599,6 +3636,7 @@ bool config_load_remap(const char *directory_input_remapping, if (input_remapping_load_file(new_conf, core_path)) { rarch_ctl(RARCH_CTL_SET_REMAPS_CORE_ACTIVE, NULL); + msg_remap_loaded = MSG_CORE_REMAP_FILE_LOADED; goto success; } } @@ -3612,8 +3650,8 @@ bool config_load_remap(const char *directory_input_remapping, return false; success: - runloop_msg_queue_push(msg_hash_to_str( - MSG_GAME_REMAP_FILE_LOADED), 1, 100, false, + runloop_msg_queue_push( + msg_hash_to_str(msg_remap_loaded), 1, 100, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); free(content_path); free(remap_directory); @@ -4110,7 +4148,7 @@ bool config_save_overrides(enum override_type type, void *data) tmp_i = sizeof(settings->paths) / sizeof(settings->paths.placeholder); path_overrides = populate_settings_path (overrides, &tmp_i); - RARCH_LOG("[Overrides] looking for changed settings... \n"); + RARCH_LOG("[Overrides]: Looking for changed settings... \n"); if (conf) { @@ -4184,15 +4222,15 @@ bool config_save_overrides(enum override_type type, void *data) switch (type) { case OVERRIDE_CORE: - RARCH_LOG ("[Overrides] path %s\n", core_path); + RARCH_LOG ("[Overrides]: path %s\n", core_path); ret = config_file_write(conf, core_path, true); break; case OVERRIDE_GAME: - RARCH_LOG ("[Overrides] path %s\n", game_path); + RARCH_LOG ("[Overrides]: path %s\n", game_path); ret = config_file_write(conf, game_path, true); break; case OVERRIDE_CONTENT_DIR: - RARCH_LOG ("[Overrides] path %s\n", content_path); + RARCH_LOG ("[Overrides]: path %s\n", content_path); ret = config_file_write(conf, content_path, true); break; case OVERRIDE_NONE: @@ -4236,6 +4274,7 @@ bool config_save_overrides(enum override_type type, void *data) free(override_directory); free(core_path); free(game_path); + free(content_path); return ret; } diff --git a/configuration.h b/configuration.h index 506c00067e..c906a79b65 100644 --- a/configuration.h +++ b/configuration.h @@ -91,6 +91,7 @@ typedef struct settings bool video_black_frame_insertion; bool video_vfilter; bool video_smooth; + bool video_ctx_scaling; bool video_force_aspect; bool video_crop_overscan; bool video_aspect_ratio_auto; @@ -130,6 +131,7 @@ typedef struct settings bool audio_rate_control; bool audio_wasapi_exclusive_mode; bool audio_wasapi_float_format; + bool audio_fastforward_mute; /* Input */ bool input_remap_binds_enable; @@ -142,7 +144,6 @@ typedef struct settings bool input_overlay_auto_rotate; bool input_descriptor_label_show; bool input_descriptor_hide_unbound; - bool input_all_users_control_menu; bool input_menu_swap_ok_cancel_buttons; bool input_backtouch_enable; bool input_backtouch_toggle; @@ -176,6 +177,7 @@ typedef struct settings bool menu_throttle_framerate; bool menu_linear_filter; bool menu_horizontal_animation; + bool menu_scroll_fast; bool menu_show_online_updater; bool menu_show_core_updater; bool menu_show_load_core; @@ -282,7 +284,9 @@ typedef struct settings /* Network */ bool network_buildbot_auto_extract_archive; + bool network_buildbot_show_experimental_cores; bool network_on_demand_thumbnails; + bool core_updater_auto_backup; /* UI */ bool ui_menubar_enable; @@ -301,6 +305,7 @@ typedef struct settings bool cheevos_badges_enable; bool cheevos_verbose_enable; bool cheevos_auto_screenshot; + bool cheevos_start_active; /* Camera */ bool camera_allow; @@ -342,6 +347,8 @@ typedef struct settings bool savestate_auto_save; bool savestate_auto_load; bool savestate_thumbnail_enable; + bool save_file_compression; + bool savestate_file_compression; bool network_cmd_enable; bool stdin_cmd_enable; bool keymapper_enable; @@ -375,6 +382,7 @@ typedef struct settings bool sustained_performance_mode; bool playlist_use_old_format; + bool playlist_compression; bool content_runtime_log; bool content_runtime_log_aggregate; @@ -387,6 +395,7 @@ typedef struct settings bool enable_device_vibration; bool ozone_collapse_sidebar; bool ozone_truncate_playlist_name; + bool ozone_sort_after_truncate_playlist_name; bool ozone_scroll_content_metadata; bool log_to_file; @@ -429,6 +438,8 @@ typedef struct settings float input_overlay_opacity; float input_overlay_scale; + float input_overlay_center_x; + float input_overlay_center_y; float slowmotion_ratio; float fastforward_ratio; @@ -483,6 +494,7 @@ typedef struct settings #ifdef GEKKO unsigned input_mouse_scale; #endif + unsigned input_hotkey_block_delay; unsigned input_menu_toggle_gamepad_combo; unsigned input_keyboard_gamepad_mapping_type; unsigned input_poll_type_behavior; @@ -538,6 +550,7 @@ typedef struct settings unsigned accessibility_narrator_speech_speed; unsigned menu_timedate_style; + unsigned menu_timedate_date_separator; unsigned gfx_thumbnails; unsigned menu_left_thumbnails; unsigned gfx_thumbnail_upscale_threshold; @@ -609,6 +622,8 @@ typedef struct settings unsigned ai_service_mode; unsigned ai_service_target_lang; unsigned ai_service_source_lang; + + unsigned core_updater_auto_backup_history_size; } uints; struct diff --git a/content.h b/content.h index fb44c05e21..e2b8ee6ed9 100644 --- a/content.h +++ b/content.h @@ -43,7 +43,7 @@ typedef struct content_ctx_info bool content_load_ram_file(unsigned slot); /* Save a RAM state from memory to disk. */ -bool content_save_ram_file(unsigned slot); +bool content_save_ram_file(unsigned slot, bool compress); /* Load a state from disk to memory. */ bool content_load_state(const char* path, bool load_to_backup_buffer, bool autoload); @@ -51,6 +51,9 @@ bool content_load_state(const char* path, bool load_to_backup_buffer, bool autol /* Save a state from memory to disk. */ bool content_save_state(const char *path, bool save_to_disk, bool autosave); +/* Returns true if a save state task is in progress */ +bool content_save_state_in_progress(void); + /* Copy a save state. */ bool content_rename_state(const char *origin, const char *dest); @@ -82,9 +85,6 @@ bool content_reset_savestate_backups(void); bool content_undo_load_buf_is_empty(void); bool content_undo_save_buf_is_empty(void); -/* Checks if launched from the commandline */ -bool content_launched_from_cli(void); - /* Clears the pending subsystem rom buffer */ bool content_is_subsystem_pending_load(void); diff --git a/core_backup.c b/core_backup.c new file mode 100644 index 0000000000..71097ffb66 --- /dev/null +++ b/core_backup.c @@ -0,0 +1,764 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2014-2017 - Jean-André Santoni + * Copyright (C) 2016-2019 - Brad Parker + * Copyright (C) 2019-2020 - James Leaver + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include