Compare commits

...
1066 Commits
Author SHA1 Message Date
Autechre 2e115baf36 Merge pull request #10875 from hhromic/add-state-slot-icon
(Ozone) Add missing icon for 'State Slot' option in Quick Menu
2020-06-20 01:50:30 +02:00
Hugo Hromic d9fabec88e (Ozone) Add missing icon for 'State Slot' option in Quick Menu 2020-06-19 22:55:47 +01:00
twinaphex 4c6b13919c Bump up version 2020-06-19 16:02:08 +02:00
Autechre d762519b8e Merge pull request #10874 from jdgleaver/core-message-fix
Fix display of core-generated messages when load content fails
2020-06-19 15:49:22 +02:00
jdgleaver 42537a67e1 Fix display of core-generated messages when load content fails 2020-06-19 12:22:37 +01:00
Autechre 8098c5978f Merge pull request #10870 from Jamiras/gfx_widgets_achievements
gfx_widgets: move achievement popup widget into its own file
2020-06-18 23:03:03 +02:00
Autechre a88bc56ede Merge pull request #10871 from jdgleaver/core-update-block
Add option to selectively 'lock' (prevent modification of) installed cores
2020-06-18 23:02:44 +02:00
jdgleaver 80f36e16d0 Add option to selectively 'lock' (prevent modification of) installed cores 2020-06-18 17:36:33 +01:00
Autechre 4ed7ad8465 Merge pull request #10867 from jdgleaver/core-auto-backup-default
Enable automatic core backups by default on 'modern' desktop and mobile platforms
2020-06-17 23:21:49 +02:00
Jamiras 47dbaeabb8 gfx_widgets: move achievement popup widget into its own file 2020-06-17 10:48:01 -06:00
hizzlekizzle 2cbed1ac5d Merge pull request #10868 from jdgleaver/shader-preset-save-label-fix
Add missing labels for 'VIDEO_SHADER_PRESET_SAVE' enums
2020-06-17 09:38:36 -05:00
jdgleaver b49d6e9d3a Add missing labels for 'VIDEO_SHADER_PRESET_SAVE' enums 2020-06-17 13:59:52 +01:00
jdgleaver 52aabc02ba Enable automatic core backups by default on 'modern' desktop and mobile platforms 2020-06-17 12:57:12 +01:00
Autechre e91e9336a9 Update CHANGES.md 2020-06-17 13:33:42 +02:00
Autechre 3c8f539d3b Merge pull request #10865 from jdgleaver/disk-control-insert-new
(Disk Control Interface) Enable 'Load New Disc' while disk tray is open
2020-06-17 13:33:10 +02:00
jdgleaver 0c18da5d49 (Disk Control Interface) Enable 'Load New Disc' while disk tray is open 2020-06-17 11:43:54 +01:00
twinaphex a00ab53ef6 Put fprintfs and printfs behind ifndef NDEBUG 2020-06-17 11:22:31 +02:00
Autechre dba4ca04ee Update CHANGES.md 2020-06-16 22:21:15 +02:00
Autechre 43a65ec65a Merge pull request #10862 from jdgleaver/core-auto-backup
Add option to automatically backup cores when updating
2020-06-16 22:20:37 +02:00
Autechre 5f8419b8d2 Merge pull request #10861 from Jamiras/gfx_threaded_msg
(widgets) prevent freeing message while it's being rendered
2020-06-16 22:18:48 +02:00
Jamiras 42e2d740d3 add lock around current_msgs 2020-06-16 07:27:15 -06:00
jdgleaver 2782b87267 Add option to automatically backup cores when updating 2020-06-16 11:12:22 +01:00
Autechre 4b364fa1e1 Merge pull request #10859 from Jamiras/cheevos_multi_pop
(cheevos) load badge texture outside of lock
2020-06-15 23:51:59 +02:00
Jamiras 649f83c82e load badge texture outside of lock 2020-06-15 10:48:02 -06:00
Autechre 85d60bac8f Update CHANGES.md 2020-06-15 18:30:11 +02:00
Autechre ffdbb968f9 Merge pull request #10858 from Jamiras/cheevos_hardcore_pause_unlock
(cheevos) correctly report unlocked non-hardcore achievements when hardcore is paused
2020-06-15 18:29:46 +02:00
Jamiras 20380a8042 correctly report unlocked non-hardcore achievements when hardcore is paused 2020-06-15 07:06:12 -06:00
twinaphex 685948368e (libretro-db) Should fix buffer overflow - should fix Database
Information and Scan folder/File with GCC 10
2020-06-14 18:03:00 +02:00
Autechre 1099b58793 Merge pull request #10852 from jdgleaver/glui-list-insert
(GLUI) Optimise list insertion when adding playlist and dropdown list items
2020-06-14 17:48:57 +02:00
Autechre 122a68385f Merge pull request #10853 from valadaa48/oga_gfx_24bit_menu
oga_gfx 24bit menu support
2020-06-14 17:48:31 +02:00
jdgleaver 85bbba84c2 (GLUI) Optimise list insertion when adding playlist and dropdown list items 2020-06-14 14:45:53 +01:00
valadaa48 69e2bd986d oga_gfx 24bit menu support
- hack borrowed from drm_gfx
2020-06-14 03:54:36 +00:00
Autechre 439aee616e Update CHANGES.md 2020-06-13 17:51:05 +02:00
twinaphex 4f78264541 Cleanups 2020-06-13 17:46:39 +02:00
twinaphex cc43f3a355 (SDL2 Input) Add RARCH_DEVICE_MOUSE_SCREEN 2020-06-13 17:32:18 +02:00
twinaphex 367cf5985d (winraw_input) Fix mouse input processing 2020-06-13 17:27:12 +02:00
twinaphex bba60163f7 (Dinput) Fix RARCH_DEVICE_MOUSE_SCREEN 2020-06-13 17:22:34 +02:00
Autechre 8593b10bee Merge pull request #10847 from Jamiras/cheevos_bsv
(cheevos) disable hardcore mode when playing bsv file
2020-06-13 17:04:52 +02:00
Jamiras 950823e90b disable hardcore mode when playing bsv file 2020-06-13 08:05:23 -06:00
twinaphex 01bd76405f Buildfixes 2020-06-13 08:37:26 +02:00
twinaphex b74b8b6a6c Move launched_from_cli to global state 2020-06-13 08:19:49 +02:00
twinaphex b46a316df9 (core info) Pass pointer around to some functions 2020-06-13 07:29:26 +02:00
twinaphex 34af28461f Move core info global state to retroarch.c 2020-06-13 07:21:00 +02:00
Twinaphex 6e979931a1 Remove unused variable 2020-06-13 06:49:59 +02:00
twinaphex c7cd327b5b Rearrange input state input drivers for ANALOG - do joypad
processing first, then keyboard second
2020-06-13 05:25:10 +02:00
twinaphex dd79629015 (QNX) Get rid of qnx_is_pressed 2020-06-13 02:13:32 +02:00
twinaphex 5b81b6887b (X11) Buildfix #3 2020-06-13 02:07:43 +02:00
twinaphex 9d65f7e633 (X11) Buildfix #2 2020-06-13 02:06:24 +02:00
twinaphex 60ca3d0ad7 (X11) Buildfix 2020-06-13 02:05:16 +02:00
twinaphex 9ede38df93 (X11) Cleanups 2020-06-13 02:03:48 +02:00
twinaphex 52ff31f877 Get rid of udev_is_pressed 2020-06-13 01:54:22 +02:00
twinaphex 6cc9a3f9b4 (UWP) Buildfix + uwp_input cleanups 2020-06-13 01:01:30 +02:00
twinaphex 6690790dae Fix --disable-menu 2020-06-12 22:24:39 +02:00
twinaphex d03a0a7b51 (WiiU) Buildfix 2020-06-12 19:33:13 +02:00
Autechre 8173db0c4a Merge pull request #10846 from jdgleaver/task-pl-manager-heap-use-after-free
(Playlist management tasks) Fix potential heap-use-after-free errors
2020-06-12 18:54:22 +02:00
twinaphex 00df029557 Get rid of some extraneous 'valid' checks in in input_keys_pressed 2020-06-12 18:45:35 +02:00
twinaphex d998f86f1f Cleanups 2020-06-12 18:41:09 +02:00
jdgleaver 6f51ef5966 (Playlist management tasks) Fix potential heap-use-after-free errors 2020-06-12 17:40:24 +01:00
twinaphex 4a91b11806 Further input driver standardization 2020-06-12 18:28:07 +02:00
Autechre 6e621a98d9 Merge pull request #10845 from jdgleaver/x11-udev-input-fixes
(X11/udev) Input fixes
2020-06-12 17:22:44 +02:00
Autechre 4e49114c5c Merge pull request #10844 from jdgleaver/manual-scan-recursive
(Manual Content Scanner) Add option to disable recursive scanning
2020-06-12 17:13:00 +02:00
jdgleaver 2c956fbe85 (X11/udev) When fetching RETRO_DEVICE_ID_JOYPAD_MASK, only query keyboard if corresponding gamepad button is not pressed 2020-06-12 16:06:32 +01:00
jdgleaver 321ede2256 (X11/udev) Input fixes 2020-06-12 14:12:22 +01:00
jdgleaver 1cdd3c32c0 (Manual Content Scanner) Add option to disable recursive scanning 2020-06-12 10:00:38 +01:00
twinaphex 45f90ad89a (menu_dialog) Cleanups
Make menu_hash_help no longer dependent on the menu code
2020-06-12 08:06:30 +02:00
twinaphex 6092de544c (Wiiu) Buildfix 2020-06-12 07:13:55 +02:00
twinaphex 0e907f01ca (winraw_input) Cleanups - use button_is_pressed 2020-06-12 06:37:36 +02:00
twinaphex c1d63ca7c1 Revert "Grab pointer to video_driver_window_get_ptr once during init"
This reverts commit 784904071a.
2020-06-12 06:36:27 +02:00
twinaphex 451a06076d Revert "(dinput_joypad) Grab window pointer once"
This reverts commit d85eb927c1.
2020-06-12 06:36:19 +02:00
twinaphex 5a064ef4ca (dinput) Cleanups - use button_is_pressed 2020-06-12 06:26:03 +02:00
twinaphex d85eb927c1 (dinput_joypad) Grab window pointer once 2020-06-12 06:12:25 +02:00
twinaphex 784904071a Grab pointer to video_driver_window_get_ptr once during init
function, then use that throughout this driver's functions
2020-06-12 06:07:20 +02:00
twinaphex d903d684a0 (glslang) Group together more strings 2020-06-12 05:24:34 +02:00
twinaphex c2044beedd Fix shader regression with MinProgramTexelOffset 2020-06-12 05:18:38 +02:00
twinaphex eb78b608d3 Cut down on code duplication 2020-06-12 00:50:08 +02:00
twinaphex 0b95a8838a (OSX) Cleanups 2020-06-12 00:30:24 +02:00
twinaphex ecfdc867f8 Cleanups 2020-06-12 00:16:31 +02:00
twinaphex e40d381f6b (WiiU) Cleanups 2020-06-11 22:05:30 +02:00
twinaphex 255794d903 (Udev) buildfix 2020-06-11 21:40:37 +02:00
twinaphex d1d8386343 (udev) Cleanups 2020-06-11 21:38:58 +02:00
twinaphex a7ab21ac15 (Emscripten) Buildfix 2020-06-11 21:21:20 +02:00
twinaphex 88a93dc648 (OSX) Buildfix 2020-06-11 21:00:28 +02:00
twinaphex 8cc220a4d2 (CTR) Buildfix 2020-06-11 20:59:35 +02:00
twinaphex 11520f9704 (X11) Buildfix 2020-06-11 20:23:44 +02:00
twinaphex dee0c5dbca CTR buildfix + cleanups 2020-06-11 19:33:27 +02:00
twinaphex f12ac35438 Cleanups 2020-06-11 19:03:50 +02:00
twinaphex 42984968f2 (X11) Further optimizations to x_is_pressed 2020-06-11 19:00:08 +02:00
twinaphex f96e148f74 Change to 1 instead 2020-06-11 18:43:53 +02:00
twinaphex e2e5366925 Cleanups 2020-06-11 18:43:30 +02:00
Twinaphex dc967f41ec (Cocoa) Create cocoa_is_pressed 2020-06-11 18:40:14 +02:00
Autechre 204f705b35 Update CHANGES.md 2020-06-11 18:05:14 +02:00
Autechre dc10dc4702 Merge pull request #10837 from parport0/master
Add options for moving the on-screen overlay
2020-06-11 18:03:02 +02:00
twinaphex d8cf551608 Silence 'suggest braces around initialization of subobject' warning 2020-06-11 17:38:11 +02:00
twinaphex 9c1d40c364 (Android) Buildfix 2020-06-11 17:37:23 +02:00
twinaphex 3eaf7d5e66 Further cleanups and corrections 2020-06-11 17:18:28 +02:00
twinaphex 6ddbf911e3 (SDL input) Build fix - and further cleanups in other
drivers
2020-06-11 17:12:08 +02:00
Autechre 1979b42834 Merge pull request #10836 from jdgleaver/hotkey-sublabels
Add sublabels to all hotkey bind entries
2020-06-11 16:59:10 +02:00
twinaphex cd01e0a048 Standardize input lightgun code 2020-06-11 16:58:49 +02:00
jdgleaver a7ebae35de Rephrase 'Reset Game' hotkey sublabel 2020-06-11 15:52:33 +01:00
twinaphex f9c771b4a8 Standardize lightgun_aiming_state function 2020-06-11 16:50:36 +02:00
twinaphex cf3cdbbcc9 Cleanups 2020-06-11 16:49:27 +02:00
twinaphex 39279292ef (dinput) Cut down on code duplication 2020-06-11 16:42:33 +02:00
jdgleaver fa069c28f3 Add sublabels to all hotkey bind entries 2020-06-11 15:38:25 +01:00
twinaphex 4fb59f5319 (winraw_input) More fixes 2020-06-11 16:37:50 +02:00
twinaphex 1b5796b321 Fix --disable-menu 2020-06-11 16:30:45 +02:00
Autechre 2c94d9a573 Merge pull request #10838 from Jamiras/cheevos_hash_more_exts
(cheevos) support for less common file extensions
2020-06-11 16:19:44 +02:00
Autechre cabab419c5 Merge pull request #10839 from jdgleaver/core-manager
Add 'core management' menu
2020-06-11 16:19:23 +02:00
Jamiras ffb1f0b67b support for less common file extensions 2020-06-11 07:33:17 -06:00
jdgleaver 42ad070a1d Add 'core management' menu 2020-06-11 14:12:20 +01:00
parport0 a4590acde9 Add options for moving the on-screen overlay 2020-06-11 15:39:23 +03:00
twinaphex 479a3ab9a3 (Dinput) Optimizations - create dinput_is_pressed 2020-06-11 08:54:17 +02:00
twinaphex a14d54b3fd (winraw_input) Further optimizations 2020-06-11 08:34:30 +02:00
twinaphex 5d58acd2c0 (Android) Input driver optimizations - fill in device_model one time
inside the init function - mistake previously was putting it erroneously
inside an inner loop
2020-06-11 08:08:21 +02:00
twinaphex 108bbf0bf6 Turn this into static function 2020-06-11 07:12:54 +02:00
twinaphex d893e880ec Revert "(Android) android_input.c - optimize - hose code that always remains"
This reverts commit df4428bd7a.
2020-06-11 07:10:15 +02:00
twinaphex df4428bd7a (Android) android_input.c - optimize - hose code that always remains
the same outside of loops
2020-06-11 06:46:40 +02:00
twinaphex 02132985af Cleanups 2020-06-11 06:34:59 +02:00
twinaphex 9aafd3c723 (winraw) Cleanups - get rid of setting pointer grabbing everywhere -
clean up mouse state grabbing everywhere - would be costly in loops
2020-06-11 06:29:36 +02:00
twinaphex 7ee5ffcd1c Further optimize SlangProcess 2020-06-11 05:51:03 +02:00
twinaphex 703cc7198d (input drivers) cleanup log spam 2020-06-11 05:37:40 +02:00
twinaphex d924c656b7 (winraw_input) cleanups 2020-06-11 05:15:36 +02:00
twinaphex a0e6a9e1d5 (xinput joypad) Function can be made static 2020-06-11 04:53:20 +02:00
twinaphex cfc511cc6b (Dinput joypad) Some cleanups 2020-06-11 04:46:15 +02:00
twinaphex b363ed7d79 (drivers_joypad) get rid of excessive logging 2020-06-11 04:06:33 +02:00
twinaphex a68b942d1d Refactor AI Service code 2020-06-11 03:27:01 +02:00
twinaphex 30bfca0d71 (task database) Optimize extension_to_file_type 2020-06-11 02:53:31 +02:00
twinaphex a2184bcd07 (task database) optimize detect_psp_game 2020-06-11 02:39:07 +02:00
twinaphex d714520c64 (Autodetect) Cleanups 2020-06-11 02:29:32 +02:00
twinaphex 5aa26e7eee Optimize check_menu_driver_compatibility 2020-06-10 23:40:29 +02:00
twinaphex 963c01cf48 (RGUI) Move global state to struct 2020-06-10 23:33:20 +02:00
twinaphex 7c3a1a8bf0 Cleanups 2020-06-10 23:25:03 +02:00
twinaphex cec33cbc49 Disable savestate compression for UWP for now - apparently doesn't work 2020-06-10 22:44:45 +02:00
twinaphex 2b5496a417 Move input_osk.c to retroarch.c 2020-06-10 18:21:53 +02:00
twinaphex 8daa90da23 move osk_ptr global state to rarch_state 2020-06-10 18:07:20 +02:00
twinaphex e0090010f4 Cleanup menu_input_bind_dialog.c 2020-06-10 17:54:19 +02:00
twinaphex bc24092374 (VIDEOCRT SWITCH) move global state to rarch_state 2020-06-10 17:42:08 +02:00
twinaphex e04bce7dd0 Move gfx_thumbnail global state to rarch_state 2020-06-10 17:22:02 +02:00
twinaphex 66451f3ef0 Cleanups 2020-06-10 16:51:21 +02:00
twinaphex 4f3059c608 Cleanups 2020-06-10 16:33:44 +02:00
twinaphex 8eee7b3bb9 (Task database) Cleanups 2020-06-10 16:24:52 +02:00
twinaphex b2f5262a3b crt_first_run and crt_video_restore were both useless 2020-06-10 15:50:29 +02:00
twinaphex 78e0ab6c0e Update 2020-06-10 15:17:15 +02:00
Autechre 02ca1a1f01 Merge pull request #10829 from valadaa48/oga_gfx_ffwd
Add ffwd to non-threaded oga_gfx driver
2020-06-10 15:05:04 +02:00
Autechre 8576169eeb Merge pull request #10831 from jdgleaver/widget-fix
(Widgets) Fix serious heap-use-after-free errors
2020-06-10 15:04:38 +02:00
jdgleaver 9bbc9dd30e (Widgets) Fix serious heap-use-after-free errors 2020-06-10 12:32:50 +01:00
twinaphex c63a65ffa5 (WiiU) Cleanups 2020-06-10 06:30:23 +02:00
twinaphex 1e2b649a21 Cleanups 2020-06-10 05:54:00 +02:00
twinaphex fa6ca2e39c Revert "Create input_joypad_analog_button"
This reverts commit 9e7ca7cbbe.
2020-06-10 05:50:51 +02:00
twinaphex 11cba2e805 Revert "Cleanups and documentation"
This reverts commit ec2a1e79a0.
2020-06-10 05:50:42 +02:00
twinaphex 317648ecd4 Revert "Cleanup"
This reverts commit 2a6317c52f.
2020-06-10 05:50:26 +02:00
twinaphex 2a6317c52f Cleanup 2020-06-10 05:33:35 +02:00
twinaphex ec2a1e79a0 Cleanups and documentation 2020-06-10 05:18:59 +02:00
hizzlekizzle db63e0a60a add hold-select to hardcoded menu gamepad combos (#10827)
* add hold-select to hardcoded menu gamepad combos
2020-06-09 21:54:28 -05:00
twinaphex 9e7ca7cbbe Create input_joypad_analog_button 2020-06-10 04:17:08 +02:00
twinaphex a7a03984f1 (input drivers) Cleanups 2020-06-10 04:00:40 +02:00
valadaa48 3abcb2b922 Add ffwd to non-threaded oga_gfx driver 2020-06-09 20:24:28 -04:00
twinaphex 05e3a1d7e5 Get rid of unnecessary get_time_usec call in menu_input_post_iterate -
just pass current_time value around
2020-06-10 00:53:54 +02:00
twinaphex ea1ca4edcc Get rid of analog D-pad mapping macros 2020-06-10 00:41:13 +02:00
twinaphex 8eb70071f4 Cleanups 2020-06-09 22:21:02 +02:00
twinaphex 4bc39ee1cf Cleanups 2020-06-09 22:13:28 +02:00
twinaphex 8a715fab1c Cleanups 2020-06-09 20:48:54 +02:00
twinaphex 20f2654884 Remove input_menu_keys_pressed - use input_keys_pressed instead
for menu as well
2020-06-09 20:44:20 +02:00
twinaphex c4534509f7 Cleanups - make two functions nearly identical 2020-06-09 20:36:58 +02:00
twinaphex 01547ef768 Make function input_keys_pressed more like input_menu_keys_pressed 2020-06-09 20:32:48 +02:00
twinaphex 42478983a3 Cleanups/dehardcode port 2020-06-09 20:16:47 +02:00
twinaphex c09a3b75ab Further cleanups - aim is to make both of these functions one and the
same
2020-06-09 20:00:24 +02:00
twinaphex 7b879c2a2b input_keys_pressed - pass port parameter to functions 2020-06-09 19:38:15 +02:00
twinaphex 23fb0f3d4d Cleanups 2020-06-09 19:21:25 +02:00
twinaphex b19e83aa6d input_menu_keys_pressed/keys_pressed optimizations - this time
without breaking hotkey enable
2020-06-09 19:15:11 +02:00
twinaphex bb4aa82cb3 Revert "input_keys_pressed/menu_input_keys_pressed - optimizations"
This reverts commit be5985b8e6.
2020-06-09 17:18:31 +02:00
twinaphex be5985b8e6 input_keys_pressed/menu_input_keys_pressed - optimizations 2020-06-09 16:42:17 +02:00
Autechre 55b6107eb0 Update CHANGES.md 2020-06-09 16:12:25 +02:00
Autechre 2ac89ec04c Merge pull request #10826 from jdgleaver/quick-menu-suppress-no-entries
Suppress the display of 'empty' quick menu listings when closing content
2020-06-09 16:11:53 +02:00
twinaphex 11a4db3120 Revert "Reduce button state from 256bit to 128bit - all the bind IDs"
This reverts commit 47456cf94b.
2020-06-09 16:11:26 +02:00
jdgleaver eb425b997b Suppress the display of 'empty' quick menu listings when closing content 2020-06-09 14:09:22 +01:00
Autechre 9098ac9ea2 Update CHANGES.md 2020-06-09 14:46:32 +02:00
twinaphex 1597a6893d Get rid of 'All Users Control Menu' setting - was not properly
implemented - input system is in for a big overhaul in the near
future so this could be addressed in a better way then
2020-06-09 13:55:03 +02:00
Autechre 8e84c51c5c Merge pull request #10824 from jdgleaver/hotkey-delay-menu
Wire up menu entry for 'hotkey delay' option + 'hotkey enable' clarifications
2020-06-09 13:49:23 +02:00
Autechre 756afa48f7 Merge pull request #10825 from jdgleaver/3ds-build-fix
Fix 3DS build
2020-06-09 13:48:36 +02:00
jdgleaver 32a6d97e48 Set SD_FLAG_ADVANCED on 'Hotkey Enable Delay' setting 2020-06-09 11:22:36 +01:00
jdgleaver 1fde6f8aed Fix 3DS build 2020-06-09 10:57:00 +01:00
jdgleaver 47150cab07 Wire up menu entry for 'hotkey delay' option + 'hotkey enable' clarifications 2020-06-09 10:20:44 +01:00
Autechre 26e1b9d66e Update CHANGES.md 2020-06-09 06:40:52 +02:00
Autechre 60bdd1d323 Merge pull request #10821 from Themaister/wsi-rework-semaphores
Vulkan: Refactor WSI handling
2020-06-09 05:56:34 +02:00
twinaphex 84781b7f3a Buildfix for targets that don't define HAVE_NVDA 2020-06-09 03:22:10 +02:00
Themaister f089e1ccf5 Vulkan: Do not emulate mailbox on Android. 2020-06-09 00:24:29 +02:00
Themaister cd4f22c275 Vulkan: Add path which uses WSI acquire semaphores.
Fence wait path has some issues on certain platforms. For now, gate this
on whether the GPU is integrated or not.
2020-06-09 00:24:29 +02:00
Themaister 15df55d011 Vulkan: Refactor swapchain index and frame index.
Do not tie these concepts together, it will not work for upcoming
refactor of swapchain logic.
2020-06-09 00:24:29 +02:00
Themaister 6f68571805 Vulkan: Use VK_LAYER_KHRONOS_validation in VULKAN_DEBUG=1.
LUNARG_standard_validation was deprecated and removed ages ago.
2020-06-09 00:24:28 +02:00
twinaphex 5a690b7ac8 (display widgets) Cleanups 2020-06-09 00:13:34 +02:00
Autechre c9211aff57 Merge pull request #10820 from fjtrujy/newlibWithCDVD
Adding CDFS Support
2020-06-08 23:22:56 +02:00
twinaphex 52050739a1 Cleanups 2020-06-08 23:13:29 +02:00
twinaphex b183abbb0f More string_is_equal optimizations; localize more strings 2020-06-08 22:46:56 +02:00
twinaphex 2ae0583ac5 Optimize action_iterate_type 2020-06-08 22:07:04 +02:00
Rinnegatamante 0644190121 [VITA] Added custom bubbles support. 2020-06-08 21:56:10 +02:00
twinaphex 7841f07e08 Add ifdef 2020-06-08 21:45:31 +02:00
twinaphex 9364deb539 Cut down on string_is_equals for history lists 2020-06-08 21:34:39 +02:00
twinaphex c31bfb4dc8 (task_pl_thumbnail_download) Simplifications 2020-06-08 21:20:07 +02:00
twinaphex 03247eceba More localizations - some string is equal optimizations 2020-06-08 20:52:37 +02:00
twinaphex a88bf59b27 Update log messages 2020-06-08 20:31:08 +02:00
twinaphex 47456cf94b Reduce button state from 256bit to 128bit - all the bind IDs
combined right now are still under 80, so 256 bits is too
overboard for now
2020-06-08 20:13:00 +02:00
twinaphex f64da5cb1e Update more log messages 2020-06-08 19:11:43 +02:00
twinaphex aed8b7943d Cleanup log messages 2020-06-08 18:58:18 +02:00
twinaphex b97462c8a4 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
2020-06-08 18:40:45 +02:00
twinaphex 6fce0435a1 Update more logs 2020-06-08 18:04:29 +02:00
twinaphex be886bf2aa Update log message 2020-06-08 18:01:15 +02:00
twinaphex c2bc40bbc3 Update SRAM log messages 2020-06-08 17:57:40 +02:00
twinaphex 781835d53c More logging messages updates 2020-06-08 17:49:55 +02:00
twinaphex 12b22b7904 (Windows) Fix core path entries in image/video/music history playlists 2020-06-08 17:33:21 +02:00
twinaphex fc491e9ea4 Add more environ logs 2020-06-08 17:32:36 +02:00
twinaphex 9ff44cc682 Namespace some logs 2020-06-08 17:13:23 +02:00
twinaphex 38f9a1b1f0 (OSK) move some global state to rarch_state 2020-06-08 16:31:10 +02:00
twinaphex 5fc12c7761 Dehardcode strings and other cleanups 2020-06-08 16:02:06 +02:00
twinaphex b1425bcd91 Localize NA string 2020-06-08 15:50:43 +02:00
twinaphex 66602f4ff8 Refactor left/right callbacks for tabs - just look for '_tab'
at the end of a string
2020-06-08 15:44:36 +02:00
twinaphex 091b1c88c2 Optimize database_cursor_iterate 2020-06-08 15:27:08 +02:00
twinaphex fa5d8b6f86 Fix builds that don't have HAVE_GX_WIDGETS defined 2020-06-08 14:22:42 +02:00
Autechre be9eefeb22 Merge pull request #10816 from jdgleaver/screenshot-fix
Fix crash when taking screenshots with widgets enabled
2020-06-08 13:56:01 +02:00
Autechre 774f63d9db Merge pull request #10815 from jdgleaver/builtin-core-fix
Fix launching of playlist content assigned to 'built-in' cores
2020-06-08 13:46:32 +02:00
twinaphex ac8985a38f Buildfix for OSX PPC 2020-06-08 13:45:32 +02:00
jdgleaver 0c7f0df41a Fix crash when taking screenshots with widgets enabled 2020-06-08 12:41:22 +01:00
Twinaphex 80dd4548e1 Remove unused variables 2020-06-08 13:39:18 +02:00
jdgleaver ba6e53c2e4 Fix launching of playlist content assigned to 'built-in' cores 2020-06-08 12:00:40 +01:00
twinaphex e7082d3e5b Now that NVDA should dynamically lookup the DLL, linking against
nvdaControllerClient64.dll should no longer be necessary
2020-06-08 08:03:05 +02:00
Autechre 9071acf2ce Merge pull request #10812 from libretro/dynamic_nvda_load
Added nvda dynamic loading.
2020-06-08 08:02:27 +02:00
twinaphex ce95dcaf79 (task_pl_thumbnail_download) Some string_is__equal optimizations 2020-06-08 07:31:58 +02:00
twinaphex 5db62e73da (Ozone/XMB) Optimize some string_is_equal comparisons 2020-06-08 07:19:19 +02:00
twinaphex 58b22b0a6e Optimize some long iterations of string_is_equal 2020-06-08 07:00:22 +02:00
twinaphex cfbaa0c89d (X11) Cut down on video_driver_has_focus calls 2020-06-08 06:16:01 +02:00
twinaphex 2a21a3f893 Cleanups 2020-06-08 06:00:53 +02:00
twinaphex 8ba8772edb Cleanups 2020-06-08 05:57:47 +02:00
twinaphex a87d15e361 Cleanups 2020-06-08 05:52:25 +02:00
twinaphex 2660182d52 Get rid of gfx_widgets_ready call inside
gfx_widgets_frame
2020-06-08 05:45:15 +02:00
twinaphex 5c2a2ca485 Move widgets state over to retroarch global state 2020-06-08 05:09:42 +02:00
Barry Rowe 35f1a4af8c Added nvda dynamic loading. 2020-06-07 19:46:22 -07:00
twinaphex 57c3b1b041 Move widgets_persisting to retroarch.c 2020-06-08 04:36:40 +02:00
twinaphex 73b5bf438b Move widgets_active to retroarch.c 2020-06-08 04:32:54 +02:00
twinaphex d9565b6619 Cut down on unnecessary widgets_active early returns 2020-06-08 04:17:33 +02:00
twinaphex d6229ed70d gfx_widgets_deinit - turn return value into bool 2020-06-08 04:12:15 +02:00
twinaphex 9707f1f622 Get rid of gfx_ctx_animation_tag 2020-06-08 04:09:12 +02:00
twinaphex eb20c10713 Start getting rid of gfx_ctx_animation_tag - it's just a uintptr_t
typedef
2020-06-08 03:56:35 +02:00
twinaphex 573eddb5a4 (Metal) Always run this regardless 2020-06-08 03:28:32 +02:00
twinaphex c1aeafbe3d Fix --disable-menu 2020-06-08 03:24:47 +02:00
twinaphex 7f54f410f4 Remove pointer grabbing from get_msg_queue function 2020-06-08 03:11:59 +02:00
twinaphex 69bdf581f4 Change this back 2020-06-08 03:10:31 +02:00
Autechre f6d361ad08 Merge pull request #10811 from Jamiras/rcheevos_hash
(cheevos) use rcheevos for identifying games
2020-06-08 03:08:50 +02:00
twinaphex 876419294d (gfx widgets) Pass more state around 2020-06-08 02:54:01 +02:00
twinaphex 54372f2524 Pass state around to widget interface 2020-06-08 02:31:36 +02:00
twinaphex 77f5433f22 Create global wrapper function for state 2020-06-08 01:59:25 +02:00
twinaphex 9aa736b522 Move forward declarations up 2020-06-08 01:56:45 +02:00
twinaphex a2ea198fdd (gfx widgets) Pass pointer around more 2020-06-08 01:55:04 +02:00
twinaphex 3f163eaa8d Bring all graphics widget global state together under one struct 2020-06-08 01:41:21 +02:00
Jamiras 7d488aa200 use rcheevos for identifying games 2020-06-07 17:13:50 -06:00
twinaphex dc217b313c Buildfix 2020-06-07 23:45:48 +02:00
twinaphex ddf45fdad2 (gfx widgets) Cleanups 2020-06-07 23:43:59 +02:00
twinaphex 4524ff7cd7 (Gfx widgets) Cleanups 2020-06-07 23:39:11 +02:00
twinaphex 797d3f871c (Gfx widgets) get rid of this early return - already done outside 2020-06-07 23:26:37 +02:00
twinaphex 6b5e9a3224 (gfx widgets) Cleanups 2020-06-07 23:17:37 +02:00
Twinaphex 03c1283fcb Remove unused variable 2020-06-07 23:04:20 +02:00
twinaphex ce02161255 Cleanups 2020-06-07 23:01:52 +02:00
twinaphex 5e2649a6f5 Move gfx_display global state to rarch state 2020-06-07 22:58:06 +02:00
twinaphex 155a490f4e Update more US strings 2020-06-07 22:25:29 +02:00
twinaphex cb90fdb802 (Cheevos) Cleanups 2020-06-07 21:48:36 +02:00
twinaphex 55a8404d01 (Cheevos) Cleanups 2020-06-07 21:34:43 +02:00
twinaphex 2baa3be2da Cleanups 2020-06-07 21:18:07 +02:00
twinaphex d15942f6c8 Cleanups 2020-06-07 20:55:27 +02:00
Autechre 3b93c7c36d Merge pull request #10810 from shantigilbert/master
Fix undeclared (VIDEO_RGA_SCALING) label
2020-06-07 20:29:54 +02:00
twinaphex 81b2cc0d14 Get rid of menu_entry_is_password 2020-06-07 20:27:17 +02:00
shantigilbert 137c468ca4 Fix undeclared label
This commit, https://github.com/libretro/RetroArch/commit/2c635e9e1b73a697d22c703dad05f08c20595c11 is missing this declaration.
2020-06-07 13:18:26 -05:00
twinaphex 05a344d831 Cleanups 2020-06-07 20:06:56 +02:00
twinaphex 058adf247c Further optimizations to menu_entry_get - get rid of some unnecessary
small wrapper functions
2020-06-07 20:02:12 +02:00
Francisco Javier Trujillo Mata d896d59e8e Use -O3 for compilatino 2020-06-07 19:43:18 +02:00
Francisco Javier Trujillo Mata df4e715738 Clean Makefile dependencies 2020-06-07 19:43:18 +02:00
Francisco Javier Trujillo Mata 06606407f4 Add CDVDFS support back 2020-06-07 19:43:18 +02:00
twinaphex 45896eb26e (Ozone) Cleanups - move some static variables to only function
that needed them - and some other cleanups in loops
2020-06-07 18:17:53 +02:00
twinaphex ad29b70d9e (RGUI) Cleanups 2020-06-07 18:09:31 +02:00
twinaphex 26133d8336 (MaterialUI) Don't iteratively call menu_entries_get_size 2020-06-07 17:58:55 +02:00
twinaphex 4feed0031e (XMB) Optimize xmb_selection_pointer_changed 2020-06-07 17:53:23 +02:00
twinaphex 2460603ea5 Further optimization to ozone_draw_entries 2020-06-07 17:46:23 +02:00
twinaphex 41ffca2b6f (CTR) Style nits 2020-06-07 17:28:53 +02:00
twinaphex 98b847cad9 Fix some memory leaks and fallthrough errors picked up on by
Clang static code analyzer
2020-06-07 16:15:35 +02:00
Twinaphex df8df6c18b Fix EXC_BAD_ACCESS crash on RetroArch exit on OSX 2020-06-07 05:53:46 +02:00
twinaphex f2ae16e125 Pass global pointer state around 2020-06-07 05:40:44 +02:00
twinaphex 4a9f136aa9 Make menu_shader.c no longer dependent on menu driver state 2020-06-07 05:06:20 +02:00
twinaphex 0d12472e74 Cleanups 2020-06-07 04:32:36 +02:00
twinaphex 8175f3c98e Cleanup menu_list_flush_stack and menu_list_pop_stack 2020-06-07 04:19:10 +02:00
twinaphex fdf9f82593 (XMB) Delay menu_entry_get processing until necessary 2020-06-07 03:53:53 +02:00
twinaphex 08f1fb5b38 (Ozone) Cleanups 2020-06-07 03:45:57 +02:00
twinaphex 0010bffb63 action_select_default optimization 2020-06-07 03:33:24 +02:00
twinaphex b2124a1f89 Further menu_entry_get optimizations 2020-06-07 03:27:30 +02:00
twinaphex c97fbbb155 (XMB) Make similar optimizations for XMB 2020-06-07 03:13:02 +02:00
Autechre eddcde84b6 Merge pull request #10802 from heuripedes/coz
Ozone improvement
2020-06-07 03:01:47 +02:00
twinaphex be76958070 Unneeded gdi_has_menu_frame 2020-06-07 02:56:56 +02:00
twinaphex b42897d0b6 (GDI) Weird code - clean this up 2020-06-07 02:55:51 +02:00
twinaphex 7b5ea63329 remove now obsolete file 2020-06-07 02:42:42 +02:00
twinaphex 4990bebd8a Turn macro names into all-caps 2020-06-07 02:41:48 +02:00
Autechre 50e522c9ce Merge pull request #10801 from snackycakes/hotkey_block_delay
Added a hotkey delay option to fix issue #9080
2020-06-07 01:25:28 +02:00
twinaphex 37d926fc0d Updates 2020-06-07 01:22:34 +02:00
twinaphex de09440d1c Change macros to all caps 2020-06-07 01:19:17 +02:00
Higor Eurípedes ec197c441e ozone: Move some menu_entry_get*() calls to a better place
menu_entry_get*() was getting called even for entries that wouldn't be displayed.
2020-06-06 20:08:28 -03:00
Higor Eurípedes 1f45018ee8 shader_glsl.c: Move buffer null pointer check in gl_glsl_set_coords()
`buffer` is initialized to a statically allocated variable and can only be NULL
when the allocation of a bigger buffer fails. When only the core frame is being
displayed, the buffer never points to the heap thanks to the small buffer
optimization.
2020-06-06 20:08:28 -03:00
twinaphex 9dca8de90f (configuration.c) Turn enums into const 2020-06-07 00:33:48 +02:00
twinaphex 9059b4962e Cleanups 2020-06-07 00:05:41 +02:00
Robert Hammond af64bbb627 Changed default value for config option input_hotkey_block_delay to 5. 2020-06-06 18:04:24 -04:00
twinaphex 361b252de2 Fix C89_BUILD and --disable-menu 2020-06-06 23:32:09 +02:00
twinaphex aae94efcfb Cleanup 2020-06-06 22:46:05 +02:00
twinaphex 7413d05705 Cleanups 2020-06-06 22:42:43 +02:00
twinaphex 4bbc226335 Move netplay_frontend.c to retroarch.c - move global state to
retroarch global state
2020-06-06 21:57:22 +02:00
Robert Hammond bd17e13ef7 Added a hotkey delay option to allow hotkey input to work properly when it is assigned to another action. Original pull request from 9080 by paradadf was taken and modified to be configuration based. 2020-06-06 15:39:51 -04:00
twinaphex 1f2403392e Cleanup 2020-06-06 20:59:43 +02:00
twinaphex 543e4bca16 Merge Discord code into retroarch.c 2020-06-06 20:50:25 +02:00
twinaphex 9219eb5aaf Merge input_mapper.c into retroarch.c 2020-06-06 20:27:38 +02:00
twinaphex cd42d02020 Cleanups 2020-06-06 19:36:46 +02:00
twinaphex d98a0e2dce Refactor away menu_display_libretro_running 2020-06-06 19:29:54 +02:00
twinaphex 255cd3a937 MENU_ENTRIES_CTL_LIST_GET no longer used by menu drivers 2020-06-06 19:09:03 +02:00
twinaphex 4f568fa68f Turn macro names into uppercase 2020-06-06 19:02:42 +02:00
twinaphex 82c009d405 Pass state around to menu_shader_manager_free 2020-06-06 18:44:53 +02:00
twinaphex 35fce65656 Move menu_driver_shader into menu_handle state 2020-06-06 18:41:21 +02:00
twinaphex 01da7b95e2 Revert "Move menu_displaylist global state to menu_handle_t"
This reverts commit c79966bd62.
2020-06-06 18:30:08 +02:00
twinaphex c79966bd62 Move menu_displaylist global state to menu_handle_t 2020-06-06 18:20:06 +02:00
twinaphex 2fb53ba687 Cleanups 2020-06-06 18:02:07 +02:00
Twinaphex 473f94ed58 Remove unused variable 2020-06-06 17:54:06 +02:00
twinaphex 7dbe75e89b CXX_BUILD buildfix 2020-06-06 17:41:51 +02:00
twinaphex 9448896586 Change more labels 2020-06-06 17:26:51 +02:00
twinaphex 68d67d8e4e Backport suggested US translation improvements 2020-06-06 17:24:41 +02:00
twinaphex 351fe36a6d Cleanups 2020-06-06 15:37:28 +02:00
Autechre 2aeb95cbd4 Merge pull request #10799 from jdgleaver/core-info-search
Core info search optimisations + improved core selection logic + clean-ups
2020-06-06 15:35:42 +02:00
twinaphex cb78470471 Cleanups 2020-06-06 15:15:51 +02:00
twinaphex 78b030d8b8 Cut down on code duplication 2020-06-06 15:06:45 +02:00
jdgleaver 445921ac5d Core info search optimisations + improved core selection logic + clean-ups 2020-06-06 13:59:28 +01:00
twinaphex c1b3ef6661 Cleanups 2020-06-06 14:54:13 +02:00
twinaphex 742c49cee7 Revert "Cleanups"
This reverts commit 802d501c39.
2020-06-06 14:48:42 +02:00
twinaphex 7063f3df13 Cleanups 2020-06-06 14:17:58 +02:00
twinaphex 802d501c39 Cleanups 2020-06-06 14:01:09 +02:00
twinaphex b8374826ac Merge menu_cbs into retroarch.c 2020-06-06 03:58:03 +02:00
twinaphex 412d158d2e Start adding mechanism to not list 'null' drivers in Driver screen 2020-06-06 02:48:49 +02:00
twinaphex 73a5ad91a1 Get rid of find_handle functions 2020-06-06 01:51:53 +02:00
twinaphex 1d63f67877 Move more to retroarch global state 2020-06-06 01:28:52 +02:00
twinaphex f0e80e365a Cleanups 2020-06-05 23:59:06 +02:00
twinaphex d3887545ee Cleanups 2020-06-05 23:55:41 +02:00
twinaphex ab53d57079 Cleanups 2020-06-05 23:25:16 +02:00
twinaphex bb73fc6a89 Silence warnings 2020-06-05 22:39:44 +02:00
twinaphex 6de048371f Cleanups 2020-06-05 22:31:30 +02:00
twinaphex 7501b010f4 Cleanups 2020-06-05 22:00:10 +02:00
twinaphex c3943836dd (Menu) Cleanups 2020-06-05 20:58:09 +02:00
twinaphex e587f1a60e (Menu) Cleanups 2020-06-05 20:32:13 +02:00
twinaphex e732edbd9a Cleanups 2020-06-05 20:21:02 +02:00
twinaphex f8fc3fbbf8 Move static global stuff into rarch global state 2020-06-05 20:11:13 +02:00
twinaphex 5b3253c7aa Move menu_driver_state into p_rarch state 2020-06-05 19:42:34 +02:00
twinaphex 09f85d130d Merge menu_driver.c into retroarch.c - yes, it's even bigger I know,
this is so that we can consolidate global state and then start splitting
things up across several files
2020-06-05 19:29:14 +02:00
twinaphex bcf34b8f3b Start passing around retroarch pointer 2020-06-05 19:22:33 +02:00
twinaphex b8f5f22a87 Cleanups 2020-06-05 18:17:31 +02:00
twinaphex 110339c1cc (libretro-db) Add TODO/FIXME notes 2020-06-05 18:13:25 +02:00
twinaphex b8c41812bf Move use_gl variable outside of the while loop 2020-06-05 16:53:28 +02:00
twinaphex 52e1c38cf1 Fix C89 variable declaration issue 2020-06-05 16:27:56 +02:00
Autechre c8b64bef1d Update CHANGES.md 2020-06-05 12:52:07 +02:00
Autechre 2cec960ada Merge pull request #10774 from Jamiras/cheevos_report_err
report API errors when unlocking achievements or submitting leaderboards
2020-06-05 12:50:12 +02:00
twinaphex b42c1a2eda Silence some Emscripten warnings 2020-06-04 23:44:54 +02:00
twinaphex c74d145167 Hose this out of HAVE_NETWORKING ifdef 2020-06-04 23:41:13 +02:00
twinaphex fce29caff7 Add time/rtime.c to Salamander builds 2020-06-04 23:37:35 +02:00
Autechre 58b7fa58e3 Merge pull request #10791 from guoyunhe/persian-fallback-font
Use fallback font for Persian
2020-06-04 22:41:54 +02:00
Guo Yunhe 40eb37ba46 Use fallback font for Persian 2020-06-04 23:36:04 +03:00
Autechre b88377d277 Merge pull request #10787 from guoyunhe/new-languages
Add Persian, Hebrew and Asturian language options
2020-06-04 16:31:12 +02:00
Autechre 30a4610b12 Merge pull request #10788 from jdgleaver/core-backup
Add option to backup/restore installed cores
2020-06-04 16:30:55 +02:00
twinaphex 88f7515d1d Cleanups, comments, style nits 2020-06-04 14:41:28 +02:00
jdgleaver f78c0a8cc9 Fix licensing of core_backup.h/.c 2020-06-04 13:22:46 +01:00
twinaphex 9fda2bdebd Add TODO/FIXME comments 2020-06-04 14:09:45 +02:00
Guo Yunhe 0701b99039 Add Persian, Hebrew and Asturian language options 2020-06-04 14:54:28 +03:00
jdgleaver 0a33e562f4 Add option to backup/restore installed cores 2020-06-04 12:20:58 +01:00
twinaphex a3cce404b6 Turn this into a static global variable 2020-06-04 12:23:59 +02:00
Autechre 7965549204 Merge pull request #10358 from guoyunhe/master
Fetch translation from Crowdin
2020-06-04 11:53:33 +02:00
Autechre 0bf6c9b239 Merge pull request #10778 from guoyunhe/fix-line-breaks
Fix line breaks for Crowdin
2020-06-04 11:53:13 +02:00
Guo Yunhe 171dd52984 Synchronize translations 2020-06-04 12:40:25 +03:00
Francisco José García García 27a0e6a1a4 [VITA] Change error name to vgl_error 2020-06-03 20:48:16 +02:00
Francisco José García García 13b5450ff9 [GL1] Initial changes for hw context without FBO 2020-06-03 20:48:16 +02:00
Autechre 9e908b1255 Merge pull request #10781 from tunip3/master
improve performance by enabling game mode
2020-06-03 18:08:39 +02:00
tunip3 fed9490471 improve performance by enabling game mode
by using
<rescap:Capability Name="expandedResources" />
it should hopefully enable game mode and improve performance, especially on xbox one
https://docs.microsoft.com/en-us/windows/win32/api/_gamemode/
2020-06-03 16:57:36 +01:00
Guo Yunhe 898bed26f0 Fix line breaks for Crowdin 2020-06-03 16:49:43 +03:00
Autechre cfcb107caf Merge pull request #10771 from guoyunhe/key-format
Change keys to upper case
2020-06-03 14:05:41 +02:00
Autechre 26a5fdcba4 Merge pull request #10772 from guoyunhe/fix-ctx-scale-msg
Avoid duplicate keys
2020-06-03 14:05:16 +02:00
Jamiras 6e5b786329 report API errors when unlocking achievements or submitting leaderboards 2020-06-02 22:03:35 -06:00
Francisco José García García ec5dcce74c [VITA] Fix name clash 2020-06-02 18:31:03 +02:00
Francisco José García García 4439e2fcb5 Squashed 'deps/vitaGL/' changes from fb87308d15..c816fec50f
c816fec50f Added stride arg to vglBindPackedAttribLocation.
07f4380e60 Added glUniform1i implementation.

git-subtree-dir: deps/vitaGL
git-subtree-split: c816fec50f823f1a7ee082042d5159dbdf16e46c
2020-06-02 18:31:03 +02:00
Guo Yunhe 2c635e9e1b Avoid duplicate keys 2020-06-02 11:15:12 +03:00
Guo Yunhe e9916df9d0 Change keys to upper case 2020-06-02 10:28:00 +03:00
Autechre ff65c836c2 Update CHANGES.md 2020-06-01 19:27:23 +02:00
twinaphex 6083450d4e 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) 2020-06-01 17:39:52 +02:00
Francisco José García García ba0d5705fc [VITA] Fix vitagl clash with function names 2020-06-01 14:16:53 +02:00
twinaphex 5644bd43b1 Pass p_rarch pointer around 2020-06-01 12:15:18 +02:00
twinaphex 4163a84d62 Pass p_rarch pointer around 2020-06-01 12:00:30 +02:00
Rinnegatamante 14a6c42e0d [VITA] Using a global to prevent erroneous vitaGL re-initializations. 2020-06-01 11:12:16 +02:00
twinaphex 072a93d00c Cleanups 2020-06-01 03:10:29 +02:00
twinaphex b8faf43040 Buildfix 2020-06-01 03:04:45 +02:00
twinaphex 433547caa0 Cleanups 2020-06-01 03:02:07 +02:00
twinaphex a9495b8846 Buildfix 2020-06-01 03:01:53 +02:00
twinaphex 293e45f551 Cleanups 2020-05-31 23:38:18 +02:00
twinaphex 0427f08511 Cleanup 2020-05-31 23:06:03 +02:00
twinaphex 76ee0ab97e Cleanups 2020-05-31 22:24:06 +02:00
twinaphex 24d4547605 Cleanups 2020-05-31 22:16:12 +02:00
twinaphex fb7589e253 Move g_extern and retro_ctx and current_core into RetroArch
global state
2020-05-31 21:59:35 +02:00
twinaphex 99a971b105 OSX Buildfixes 2020-05-31 19:55:01 +02:00
twinaphex c2be385fe4 Move more globals to state struct 2020-05-31 19:37:26 +02:00
twinaphex 1392afea46 Move more to global state 2020-05-31 19:31:32 +02:00
Francisco José García García 5fe273195b [VITA] Disable sqrtfv 2020-05-31 18:04:10 +02:00
Francisco José García García a10abdd929 Merge pull request #10750 from libretro/vitagl
VitaGL and Math-neon update
2020-05-31 17:26:43 +02:00
Francisco José García García ae9bdba06f Merge commit 'af97efdc17a1215a63a9ee639cf9361876ded50d' as 'deps/math-neon' 2020-05-31 17:24:53 +02:00
Francisco José García García af97efdc17 Squashed 'deps/math-neon/' content from commit bf34c68a8e
git-subtree-dir: deps/math-neon
git-subtree-split: bf34c68a8e141f7e6f37040da9311b07f1bbe529
2020-05-31 17:24:53 +02:00
Francisco José García García b2f61389ff [VITA] Remove math-neon 2020-05-31 17:24:11 +02:00
Francisco José García García e16ae7a641 Merge commit '56797b8841ab5a9a9d7a9ab82383567300361252' 2020-05-31 17:18:53 +02:00
Francisco José García García 56797b8841 Squashed 'deps/vitaGL/' changes from 9a6e4b3397..fb87308d15
fb87308d15 Added vglBindPackedAttribLocation.
7e933f6051 Added NO_DEBUG compile option.
28e8516718 Faster textures storing when format is the same as internal format.

git-subtree-dir: deps/vitaGL
git-subtree-split: fb87308d15a387d2549fb45d860b3d87ede8a0ca
2020-05-31 17:18:53 +02:00
Francisco José García García ec336442bd Merge pull request #10749 from libretro/vitagl
VitaGL fixes
2020-05-31 17:14:23 +02:00
Francisco José García García f976078ef2 [VITA] GL fixes 2020-05-31 17:10:26 +02:00
twinaphex dd8ba82513 Move more variables to global state 2020-05-31 16:41:03 +02:00
twinaphex c8c54b61ef Move static global variables to struct 2020-05-31 11:07:38 +02:00
twinaphex 2016218fc7 Cleanups 2020-05-31 10:27:29 +02:00
twinaphex 994dfa714b (retroarch.c) Reorganize global variables 2020-05-31 09:37:29 +02:00
twinaphex b695ef4591 Move more variables to RetroArch global state 2020-05-31 07:12:33 +02:00
twinaphex 78d1efac12 Move more static variables to RetroArch global state 2020-05-31 05:57:26 +02:00
twinaphex fd84dc5e24 Only log messages for input descriptors/set_controller_info and other
libretro callbacks if core logging level is set to DEBUG
2020-05-31 05:41:07 +02:00
twinaphex 3ad6c9c84b Merge branch 'master' of https://github.com/libretro/RetroArch 2020-05-31 05:37:32 +02:00
twinaphex 0135a33a7c Move more variables to RetroArch global struct 2020-05-30 17:16:45 +02:00
Autechre 0fedfa220f Merge pull request #10734 from jdgleaver/cheevos-m3u
(Cheevos) Use 'm3u_file.h' library when parsing M3U files
2020-05-30 14:51:08 +02:00
twinaphex 8ae3fe1e80 Cleanups 2020-05-30 14:45:12 +02:00
twinaphex 3b9f131930 Move more RetroArch global state to struct 2020-05-30 14:26:10 +02:00
jdgleaver eb429f9211 (Cheevos) When parsing M3U files, only capture the first entry 2020-05-30 12:16:52 +01:00
Autechre c1fc796bf7 Update CHANGES.md 2020-05-30 04:51:52 +02:00
Autechre 4d406c95d3 Merge pull request #10735 from niacat/sdl-gl-glsl
sdl_gl_ctx: advertise GLSL support
2020-05-30 01:57:53 +02:00
nia ef0038de2a sdl_gl_ctx: advertise GLSL support 2020-05-29 18:03:25 +01:00
jdgleaver 21ad64ab77 (Cheevos) Use 'm3u_file.h' library when parsing M3U files 2020-05-29 17:44:31 +01:00
twinaphex 13be887d2d Solve this a different way, update .travis.yml, DISABLE_THREADS
target will also now disable glslang
2020-05-29 15:14:46 +02:00
twinaphex 358ffbd3b9 This is wrong 2020-05-29 13:52:29 +02:00
twinaphex 2d659c3484 (Glslang) Don't build it when --disable-networking is set 2020-05-29 13:45:40 +02:00
twinaphex 00167caf54 Use localized strings 2020-05-29 12:54:09 +02:00
twinaphex 941c3b9678 Cleanups 2020-05-29 12:46:18 +02:00
twinaphex f2ee7c8f0b Localize message 2020-05-29 11:57:03 +02:00
twinaphex 479a8a6e64 (PS2) Fix warning incompatible pointer type 2020-05-29 11:22:53 +02:00
twinaphex 7b5d338bed (Travis) Add --disable-threads check 2020-05-29 11:20:46 +02:00
twinaphex 9f9710beb6 Fix --disable-threads 2020-05-29 11:16:38 +02:00
twinaphex 11f63f379b Localized strings 2020-05-29 10:59:14 +02:00
twinaphex 40a4b395d7 Localize string 2020-05-29 10:50:08 +02:00
twinaphex 8ddacead9f Cleanups 2020-05-29 10:37:01 +02:00
twinaphex 93ae674624 Cleanups 2020-05-29 10:33:07 +02:00
twinaphex 6cc47f8ee0 task_pl_thumbnail_download - replace many subsequent strlcat calls
with one snprintf
2020-05-29 10:30:56 +02:00
twinaphex ec35ce7fdc Add TODO/FIXME notes 2020-05-29 10:23:48 +02:00
twinaphex 06f5f40cb3 Cleanups 2020-05-29 10:09:30 +02:00
twinaphex 56619d7276 Add more TODO/FIXME notes 2020-05-29 06:31:15 +02:00
twinaphex 3ae7e9f8df Update TODO/FIXMEs 2020-05-29 06:20:16 +02:00
twinaphex a5ca6c24de Add more TODO/FIXMEs for globals 2020-05-29 06:17:39 +02:00
twinaphex a50fd86f3e Add global state warnings 2020-05-29 06:11:07 +02:00
Autechre 8cf3a48106 Update CHANGES.md 2020-05-29 05:56:52 +02:00
twinaphex da3548e680 Update MENU_ENUM_SUBLABEL_DOWNLOAD_CORE 2020-05-29 05:55:18 +02:00
twinaphex 810f837596 Update 2020-05-29 05:52:17 +02:00
twinaphex 22f2cf1e56 Get rid of dir_get and other useless wrapper functions 2020-05-29 05:36:48 +02:00
twinaphex 3af84d73e9 Move menu_content_environment_get to retroarch.c 2020-05-29 05:28:29 +02:00
twinaphex 8b796d3b47 Add TODO/FIXME notes for globals 2020-05-29 05:27:13 +02:00
twinaphex ea0d3b5fd8 Remove obsolete function rarch_timer_begin_us 2020-05-29 05:21:37 +02:00
twinaphex 6b781d5a9b Move global performance counter state into retroarch.c 2020-05-29 05:12:09 +02:00
twinaphex 009d979b6c Move more variables to retroarch global state 2020-05-29 04:59:29 +02:00
Autechre eafb2b060d Merge pull request #10727 from WeedyWeedSmoker/International-language-names-update
International: Fix incorrect language names
2020-05-29 03:36:55 +02:00
twinaphex aa753eb492 Localize more strings 2020-05-29 02:52:56 +02:00
Twinaphex b697ff8acd Remove unused variables 2020-05-28 23:26:17 +02:00
Autechre 7759c83b13 Update CHANGES.md 2020-05-28 23:22:33 +02:00
Autechre 4b4c1f130c Merge pull request #10723 from jdgleaver/unix-paths
(Linux) Set default saves/save states/system paths
2020-05-28 23:21:23 +02:00
Autechre b9ada7bb28 Merge pull request #10726 from jdgleaver/core-updater-2
More core updater improvements
2020-05-28 23:21:09 +02:00
Autechre e2f351ed20 Update .travis.yml 2020-05-28 23:20:48 +02:00
Autechre eab924f428 Update .travis.yml 2020-05-28 23:20:15 +02:00
twinaphex 2293abd424 Fix DISABLE_NETWORKING 2020-05-28 23:19:34 +02:00
twinaphex aa2e9b9a00 Buildfixes 2020-05-28 23:15:28 +02:00
Weedy Weed Smoker 9997d2d7ab International: Fix incorrect language names
This commit aims to fix Arabic and Chinese characters not appearing correctly, as well as making clear a restart is required for some languages to display properly…
2020-05-29 02:47:41 +07:00
jdgleaver 044bd03a13 More core updater improvements 2020-05-28 17:48:18 +01:00
jdgleaver e44242db93 (Linux) Set default saves/save states/system paths 2020-05-28 12:09:46 +01:00
Autechre dd65d901ee Merge pull request #10719 from RobLoach/stdstring
libretro-db: Fix stdstring undefined in c_converter
2020-05-28 08:33:36 +02:00
Rob Loach 16aac7bfac libretro-db: Fix stdstring undefined in c_converter 2020-05-27 18:34:47 -04:00
Autechre c2b8b3f1e1 Update CHANGES.md 2020-05-27 20:14:38 +02:00
Autechre 9552f87157 Update CHANGES.md 2020-05-27 20:11:31 +02:00
Autechre 2b10350edc Merge pull request #10716 from jdgleaver/core-updater-improvements
Core updater improvements
2020-05-27 18:31:18 +02:00
jdgleaver 9f4a9e9cd6 Core updater improvements 2020-05-27 17:02:43 +01:00
twinaphex 02bc3ee1e8 Buildfixes/cleanups 2020-05-26 21:34:05 +02:00
Autechre a62cac03e6 Merge pull request #10679 from jdgleaver/retro-message-ext
Add API extension to provide cores with finer grained control over environment callback messages
2020-05-26 17:39:49 +02:00
Twinaphex 63f5723b27 Silence warnings 2020-05-26 17:38:52 +02:00
Autechre 434f046244 Merge pull request #10714 from jdgleaver/glui-divider-fix
(GLUI) Fix rendering of last on-screen entry divider in thumbnail views
2020-05-26 17:05:07 +02:00
jdgleaver 63c7deb583 (GLUI) Fix rendering of last on-screen entry divider in thumbnail views 2020-05-26 13:03:09 +01:00
jdgleaver a1210d63cc Extended core message interface - add API support for 'progress' messages 2020-05-26 11:42:46 +01:00
jdgleaver 23916f88c7 Extended core message interface - add concept of message 'type' 2020-05-26 10:03:25 +01:00
jdgleaver fc8b76708a Add API extension to provide cores with finer grained control over environment callback messages 2020-05-26 10:03:25 +01:00
Twinaphex e179a8e568 Cleanups 2020-05-26 08:53:29 +02:00
twinaphex fec69828a9 Cleanup 2020-05-26 08:49:59 +02:00
twinaphex a1ed747a7f Cleanups 2020-05-26 08:42:10 +02:00
twinaphex 2386ec8f0c Move more variables to rarch global struct 2020-05-26 08:34:43 +02:00
twinaphex 7cfbe73288 Move more variables to rarch global state struct 2020-05-26 08:15:35 +02:00
twinaphex c637686a76 Move more variables to retroarch global state 2020-05-26 03:18:34 +02:00
twinaphex fda235518a Cleanup command_event_disable_overrides 2020-05-26 02:11:59 +02:00
twinaphex 1c45a070d1 Avoid namespace collision 2020-05-26 02:03:34 +02:00
twinaphex 922d5a00e1 Cleanups and add FIXME/TODO note 2020-05-26 02:02:20 +02:00
twinaphex 24ca499570 Cleanups 2020-05-26 01:14:26 +02:00
twinaphex b70451d550 Start creating retroarch main state global struct 2020-05-26 00:01:59 +02:00
twinaphex 602d3d285c Revert "(glcore) switch to glcore video driver when requested"
This reverts commit 7a3ddcd77d.
2020-05-25 21:31:23 +02:00
Autechre bcefb124f3 Merge pull request #10709 from libretro/revert-10703-revert-10702-revert-10685-patch-6
Revert "Revert "Revert "(video) fix "Allow Cores to Switch the Video Driver OFF" behavior"""
2020-05-25 21:27:13 +02:00
Autechre 3db672a60d Revert "Revert "Revert "(video) fix "Allow Cores to Switch the Video Driver OFF" behavior""" 2020-05-25 21:26:11 +02:00
Autechre d6fca804b4 Update CHANGES.md 2020-05-25 19:20:17 +02:00
Autechre 1fd777106d Merge pull request #10707 from jdgleaver/date-separator
Enable configuration of date seperator in clock and runtime 'last played' displays
2020-05-25 18:22:01 +02:00
Autechre d3519a2b82 Merge pull request #10706 from jdgleaver/ozone-sort-after-truncate
(Ozone) Add option to sort playlists after name truncation
2020-05-25 17:07:36 +02:00
jdgleaver 18912ac23d Enable configuration of date seperator in clock and runtime 'last played' displays 2020-05-25 15:46:53 +01:00
jdgleaver 230198fe4a (Ozone) Add option to sort playlists after name truncation 2020-05-25 11:32:17 +01:00
Autechre 089c64f427 Merge pull request #10703 from libretro/revert-10702-revert-10685-patch-6
Revert "Revert "(video) fix "Allow Cores to Switch the Video Driver OFF" behavior""
2020-05-24 23:42:25 +02:00
Autechre 950bf29c27 Revert "Revert "(video) fix "Allow Cores to Switch the Video Driver OFF" behavior"" 2020-05-24 23:42:12 +02:00
Autechre 2e26a05875 Merge pull request #10702 from libretro/revert-10685-patch-6
Revert "(video) fix "Allow Cores to Switch the Video Driver OFF" behavior"
2020-05-24 23:25:04 +02:00
Autechre d1f4279b8f Revert "(video) fix "Allow Cores to Switch the Video Driver OFF" behavior" 2020-05-24 23:24:35 +02:00
twinaphex 31ff7e384f Cleanups 2020-05-24 21:55:41 +02:00
twinaphex fa37234a49 Cut down on strlens 2020-05-24 21:23:52 +02:00
twinaphex a1752db25a Put this behind DEBUG ifdef 2020-05-24 20:49:58 +02:00
twinaphex 737718ba5d (network) Turn functions that are not accessed outside static 2020-05-24 20:38:50 +02:00
twinaphex 8bf11e9b18 (libretro-common) Try to prevent implicit usage of stdio fprintf 2020-05-24 20:18:36 +02:00
twinaphex bc226305d7 (x11_common.c) Cleanup 2020-05-24 19:38:41 +02:00
twinaphex e030986837 Replace fprintfs with RARCH_LOG/RARCH_ERR 2020-05-24 19:29:55 +02:00
twinaphex bcbad532e6 Rewrite fprintf into RARCH_ERR 2020-05-24 19:22:17 +02:00
twinaphex 88b8e5a16a Replace with string_ends_with 2020-05-24 19:16:13 +02:00
twinaphex d9bbe604e9 silence unused variable warnings 2020-05-24 19:13:22 +02:00
twinaphex 67f0df94f9 (CDROM) Reduce log spam 2020-05-24 19:11:55 +02:00
twinaphex 53beaee6e6 Cleanup 2020-05-24 18:28:27 +02:00
twinaphex 5b562c4c24 Style nits/cleanups 2020-05-24 18:21:30 +02:00
twinaphex 1a2fdffd5b Move variables to top 2020-05-24 18:02:47 +02:00
Autechre 8ada7049c2 Update CHANGES.md 2020-05-24 17:50:24 +02:00
twinaphex 93e8edf2f9 Fix C89_BUILD error and several style nits 2020-05-24 17:41:27 +02:00
Autechre 8ce192de82 Merge pull request #10699 from guoyunhe/ar-cjk-fonts
Fix Arabic, Chinese and Korean font rendering
2020-05-24 17:36:49 +02:00
twinaphex 376b62e8fa Cut down on more unnecessary strlens 2020-05-24 17:25:52 +02:00
twinaphex 64c30610f5 Fix menu_shader_manager_save_preset_internal 2020-05-24 16:44:48 +02:00
Guo Yunhe b6561ee9ca Fix Arabic, Chinese and Korean font rendering 2020-05-24 17:39:22 +03:00
twinaphex cf1bc2634d Prevent doing unnecessary double strlen 2020-05-24 16:38:53 +02:00
twinaphex 2f836f786f (Dutch) Fix small typo for now - when Crowdin gets resynced this
should already be in there
2020-05-24 08:23:47 +02:00
Autechre 1431a0b275 Update CHANGES.md 2020-05-24 08:19:29 +02:00
Autechre 1c8b6bebce Update CHANGES.md 2020-05-24 08:18:04 +02:00
twinaphex cebc01cb1e C89_BUILD buildfix 2020-05-24 06:54:42 +02:00
Autechre 2ac18a621a Merge pull request #10697 from phcoder/x11
Improvements for XShm
2020-05-24 06:51:13 +02:00
twinaphex 51b868b6a4 (Vita) Buildfix 2020-05-24 06:47:04 +02:00
Vladimir Serbinenko c9c2d8a0b6 xshm_gfx: Add missing casts 2020-05-24 06:34:59 +02:00
Vladimir Serbinenko 54a07eaa60 Move decarations to the start of function 2020-05-24 06:33:20 +02:00
Vladimir Serbinenko 3f5eb55405 Replace C++ commants with C89 ones 2020-05-24 06:32:36 +02:00
Vladimir Serbinenko 77829a8e5b Rename xshm to x11 as it can now work without shm
xshm was disabled, so no problem with config update
2020-05-24 05:11:53 +02:00
Vladimir Serbinenko 1d4462b198 config.libs.sh: Improve messages for x components detection 2020-05-24 05:05:42 +02:00
Vladimir Serbinenko 62bb1d4da4 xshm: Allow to operate without shm extension
In most cases it doesn't make a nice gameplay but is still useful for debugging
on remote system and xnest
2020-05-24 05:01:51 +02:00
Autechre cdaf08b908 Update AndroidManifest.xml 2020-05-24 04:37:09 +02:00
Autechre af3006c3d7 Update RetroArch_iOS9-Info.plist 2020-05-24 04:36:49 +02:00
Autechre 5c3a7a7e7f Update Info_Metal.plist 2020-05-24 04:35:06 +02:00
Autechre 3613b666e5 Update Info.plist 2020-05-24 04:34:53 +02:00
Autechre 3689a719fd Update version.dtd 2020-05-24 04:32:17 +02:00
Autechre 5397f1c046 Update version.all 2020-05-24 04:32:00 +02:00
Autechre 4991245cdf Update CHANGES.md 2020-05-24 04:31:31 +02:00
twinaphex 5e772350b4 Turn rgui_osk_ptr_at_pos into static function 2020-05-24 04:06:49 +02:00
twinaphex eb92274f9b (RGUI) Cleanup function 2020-05-24 04:02:30 +02:00
twinaphex b5fe162c32 C89_BUILD fix 2020-05-24 03:52:23 +02:00
Vladimir Serbinenko c4b4961ed1 xshm: fix compatibility with x input 2020-05-24 03:52:13 +02:00
Autechre 32a4607eb6 Merge pull request #10695 from heuripedes/small-buffer-opt
Small buffer optimizations
2020-05-24 03:48:21 +02:00
Vladimir Serbinenko cfe68a4c2d Fix crash in x11_display_server_get_screen_orientation 2020-05-24 03:38:24 +02:00
Vladimir Serbinenko cde22645e5 Reeenable xshm 2020-05-24 03:35:40 +02:00
Higor Eurípedes 4ea0f232ef Use small buffer optimization in gfx_animation_ticker_smooth()
Like the previous commit, this one lowers the number of temporary allocations
while the menu is up.
2020-05-23 22:34:12 -03:00
Higor Eurípedes 0c9499a88e Implements small buffer optimization in font_driver_reshape_msg()
Use a stack-allocated 64 bytes long buffer to avoid so many temp heap
allocations when the menu is up. This size is more than enough store 75% of the
return values from msg_hash_to_str and 50% of the returned values from
msg_hash_get_help of any currently supported language (includes fallback to
English).

String size per type:
                     count       mean         std  ...   50%    75%    max
type                                               ...
msg_hash_get_help  83885.0  95.295476  106.331779  ...  54.0  103.0  842.0
msg_hash_to_str    83903.0  27.737959   33.389184  ...  19.0   31.0  440.0

string size per type and language:
                             count        mean         std  ...   50%    75%    max
type              language                                  ...
msg_hash_get_help 0         4415.0   89.922310   96.873902  ...  55.0  101.0  590.0
                  1         4415.0   97.555606  118.031412  ...  55.0  101.0  842.0
                  2         4415.0  118.459570  127.811760  ...  75.0  131.0  774.0
                  3         4415.0  111.978256  112.702991  ...  68.0  125.0  651.0
                  4         4415.0  106.040544  111.360658  ...  62.0  124.0  776.0
                  5         4415.0  100.129105  114.437432  ...  62.0  103.0  688.0
                  6         4415.0   32.987769   31.047851  ...  28.0   28.0  595.0
                  7         4415.0  109.366025  124.717259  ...  71.0  121.0  720.0
                  8         4415.0   98.023783  105.149942  ...  62.0  105.0  610.0
                  9         4415.0   93.834428  104.433820  ...  55.0  101.0  637.0
                  10        4415.0   93.657984   96.884429  ...  55.0  101.0  594.0
                  11        4415.0   93.452775  104.040553  ...  48.0  100.0  583.0
                  12        4415.0   89.729558  104.062959  ...  50.0  100.0  550.0
                  13        4415.0   91.462514   95.968107  ...  55.0  101.0  590.0
                  14        4415.0   92.062741   97.959207  ...  55.0  101.0  611.0
                  15        4415.0   92.597055   97.190835  ...  56.0  101.0  600.0
                  16        4415.0   92.088109   98.110738  ...  55.0  101.0  608.0
                  17        4415.0  102.483126  106.379639  ...  65.0  110.0  652.0
                  18        4415.0  104.782786  114.025678  ...  65.0  112.0  646.0
msg_hash_to_str   0         4415.0   24.591619   29.148312  ...  18.0   28.0  346.0
                  1         4416.0   31.247736   36.302532  ...  21.0   36.0  352.0
                  2         4416.0   31.853714   39.332395  ...  21.0   36.0  418.0
                  3         4416.0   28.270833   33.300996  ...  21.0   32.0  429.0
                  4         4416.0   27.139040   31.905206  ...  19.0   31.0  346.0
                  5         4416.0   27.380435   32.314188  ...  19.0   31.0  346.0
                  6         4416.0   25.028080   29.188490  ...  19.0   28.0  346.0
                  7         4416.0   29.660553   35.283592  ...  21.0   33.0  393.0
                  8         4416.0   27.685915   32.707466  ...  20.0   31.0  346.0
                  9         4416.0   34.786685   43.587766  ...  21.0   39.0  414.0
                  10        4416.0   28.769928   34.428596  ...  20.0   32.0  440.0
                  11        4416.0   24.407609   28.690934  ...  18.0   27.0  346.0
                  12        4416.0   23.970788   27.075638  ...  18.0   28.0  346.0
                  13        4416.0   24.587636   29.146213  ...  18.0   28.0  346.0
                  14        4416.0   27.642889   33.300451  ...  20.0   31.0  346.0
                  15        4416.0   25.036005   29.159115  ...  18.0   28.0  346.0
                  16        4416.0   24.732111   29.134002  ...  18.0   28.0  346.0
                  17        4416.0   32.068161   38.807095  ...  21.0   36.0  407.0
                  18        4416.0   28.160779   34.013300  ...  20.0   31.0  432.0
2020-05-23 22:33:45 -03:00
twinaphex 3a057d594b MSVC2003 buildfix 2020-05-24 00:05:14 +02:00
twinaphex a8a5372c6b (UWP) File I/O is slow, so enable playlist compression and
savefile compression by default
2020-05-23 23:48:01 +02:00
twinaphex cff87ab1e0 (OSX) Buildfix for Discord 2020-05-23 16:43:32 +02:00
Autechre 9b73f2a38c Update CHANGES.md 2020-05-23 05:51:57 +02:00
Autechre 4cdd5dce38 Update CHANGES.md 2020-05-23 05:51:09 +02:00
Autechre 020ee2d289 Update CHANGES.md 2020-05-23 05:50:05 +02:00
Autechre de8267d2e2 Update CHANGES.md 2020-05-23 05:49:09 +02:00
Autechre 942d82593b Merge pull request #10691 from phcoder/rbxv
Fix xvideo support on xwayland and input in general
2020-05-23 05:47:57 +02:00
Vladimir Serbinenko a86e8e0f36 Support YV12
Only I420 and YZ12 are available on xwayland. Support it
2020-05-23 05:39:18 +02:00
twinaphex c8940c130d Cleanup 2020-05-23 05:16:24 +02:00
twinaphex 4a388668a3 Update 2020-05-23 04:52:28 +02:00
twinaphex 5e3fd8e95e move GetProcessId to C files 2020-05-23 04:49:14 +02:00
Vladimir Serbinenko 9c4fde00ce xvideo: Fix order of context init
Current order causes an error in x11_input init and hence keyboard
doesn't work
2020-05-23 04:36:53 +02:00
twinaphex 6591b53547 Cleanup 2020-05-23 04:23:03 +02:00
twinaphex 7d6c0417eb Silence warning 2020-05-23 04:17:12 +02:00
twinaphex 268bf61da6 Silence warnings 2020-05-23 03:36:51 +02:00
twinaphex 506271e769 Expand size of frontend variable to avoid warning 2020-05-23 03:25:22 +02:00
twinaphex 5e88958e26 Silence warnings 2020-05-23 03:23:35 +02:00
twinaphex 6408da2ae4 Silence warnings 2020-05-23 03:19:25 +02:00
twinaphex b3a4c02d05 Reduce variable size 2020-05-23 03:12:16 +02:00
twinaphex 2518ad47d9 Reduce size of image_label 2020-05-23 03:11:35 +02:00
twinaphex 65534f0286 (netplay frontend) This variable doesn't need to be so big 2020-05-23 03:09:46 +02:00
twinaphex 8c7e785661 Convert more strstrs 2020-05-23 02:46:58 +02:00
twinaphex 1db42a5611 Cleanup filebrowser_parse 2020-05-23 02:40:31 +02:00
twinaphex 44a254264b Replace more strstrs 2020-05-23 02:29:13 +02:00
twinaphex d2d16ea171 Update CHANGES.md 2020-05-23 02:00:28 +02:00
Autechre 89f5eefb92 Merge pull request #10554 from WeedyWeedSmoker/International-translations-update
International: Add all the language updates from Crowdin…
2020-05-23 01:52:28 +02:00
twinaphex 9fe01ff0c8 Replace strstr with string_ends_with 2020-05-23 00:41:14 +02:00
Weedy Weed Smoker 8894caddc2 Polish: Unify timedate ENUMs and cleanup part 2 2020-05-23 04:29:48 +07:00
Weedy Weed Smoker 852eb8ab8e Polish: Unify timedate ENUMs and cleanup 2020-05-23 04:23:47 +07:00
twinaphex d717f3537a Update sdl2_gfx.c 2020-05-22 22:58:41 +02:00
Weedy Weed Smoker 4478167634 Greek: Correct typo in Unify timedate ENUMs 2020-05-23 03:57:02 +07:00
Weedy Weed Smoker dd612a6637 French: Correct typo in Unify timedate ENUMs 2020-05-23 03:46:50 +07:00
twinaphex 923dc52f87 Simplify menu_filebrowser.c and menu_shader.c code 2020-05-22 22:29:25 +02:00
Weedy Weed Smoker 80c1b54b52 Merge branch 'master' into International-translations-update 2020-05-23 03:14:09 +07:00
twinaphex 421bcb07d3 (task_audio_mixer.c) Optimize further 2020-05-22 22:00:25 +02:00
twinaphex eaba575c9e Replace strstrs where possible 2020-05-22 21:11:35 +02:00
twinaphex 31674f9246 Use string_ends_with and string_starts_with 2020-05-22 20:57:48 +02:00
twinaphex 9f4b3b0fc6 Start using string_ends_with 2020-05-22 20:07:21 +02:00
twinaphex 7cbb79277d Cleanup core_load_game function 2020-05-22 19:43:10 +02:00
Autechre 6044f8b335 Merge pull request #10686 from jdgleaver/image-type-detection-fix
Image file type detection fixes/optimisations
2020-05-22 18:18:22 +02:00
jdgleaver d24498bdf1 Image file type detection fixes/optimisations 2020-05-22 16:57:37 +01:00
Autechre 00d7c40c7a Merge pull request #10683 from barbudreadmon/patch-5
(vita) try at fixing upside-down vertical games
2020-05-22 16:47:17 +02:00
Autechre a97c884159 Merge pull request #10685 from barbudreadmon/patch-6
(video) fix "Allow Cores to Switch the Video Driver OFF" behavior
2020-05-22 16:46:53 +02:00
Autechre 5ad36f7040 Update CHANGES.md 2020-05-22 16:29:03 +02:00
barbudreadmon 2f57d3cbea (video) fix "Allow Cores to Switch the Video Driver OFF" behavior
fix #10677 : video driver must never be switched when this setting is set to OFF, it is the job of the core to request the right context
2020-05-22 15:38:47 +02:00
Autechre 6652bb4795 Merge pull request #10684 from jdgleaver/thumb-download-fix
(On Demand Thumbnails) Fix heap-use-after-free error
2020-05-22 14:05:47 +02:00
jdgleaver 955e25fc39 (On Demand Thumbnails) Fix heap-use-after-free error 2020-05-22 11:07:34 +01:00
barbudreadmon 2052f1595c (vita) try at fixing upside-down vertical games
it is a blind commit, i don't have access to the hardware, see #6859 for more explanations
2020-05-22 12:02:19 +02:00
Twinaphex f2bb7e29a4 Revert "(Discord RPC) Update"
This reverts commit a6030f89fe.
2020-05-22 05:37:01 +02:00
twinaphex a6030f89fe (Discord RPC) Update 2020-05-22 04:56:53 +02:00
Autechre 3cd320fa83 Merge pull request #10680 from im4potato/timedate
Unify timedate ENUMs and cleanup
2020-05-22 03:24:14 +02:00
twinaphex ec9efcb4b0 C89_BUILD buildfix 2020-05-22 02:32:36 +02:00
twinaphex 6dcaa04a93 (Ozone) Move static variables outside of the header file 2020-05-22 01:54:57 +02:00
twinaphex 70957aa52a (Ozone) Move these static variables outside of the header 2020-05-22 01:45:52 +02:00
im4potato 1c4cb37e61 Unify timedate ENUMs and cleanup 2020-05-21 16:26:06 -07:00
twinaphex 875791b40c (cheat manager) Cleanups - go through function pointer 2020-05-22 01:09:28 +02:00
twinaphex 6dc758a080 Move cheevos-new to cheevos/ 2020-05-21 23:23:01 +02:00
Twinaphex ede03659ca Update 2020-05-21 22:31:51 +02:00
Twinaphex 4b4a8693ac Remove unused variable 2020-05-21 22:27:20 +02:00
twinaphex 0edd97d5db file_path.c) Cleanup 2020-05-21 20:04:36 +02:00
twinaphex a9cf718e75 Get rid of auto variable in glslang.cpp 2020-05-21 20:04:36 +02:00
Autechre 52e8c102fc Merge pull request #10671 from johanbcn/improved-shader-preset-dirs
Improved shader preset dirs
2020-05-21 17:17:03 +02:00
Autechre 29e9a54000 Merge pull request #10678 from jdgleaver/path-is-absolute
Optimise 'path_is_absolute()'
2020-05-21 15:37:29 +02:00
jdgleaver f522cfcce8 Optimise 'path_is_absolute()' 2020-05-21 13:28:42 +01:00
Joan Coll Cerdán 04016ed4a6 Improve shader initialization code.
Patch by @jdgleaver.
2020-05-21 13:29:09 +02:00
twinaphex e1e6f2db51 Fix CXX_BUILD 2020-05-21 05:10:33 +02:00
Autechre 6fa4350ade Update CHANGES.md 2020-05-21 04:53:51 +02:00
twinaphex 70f57974c7 Buildfix 2020-05-21 04:23:01 +02:00
twinaphex 4f2566ad50 (JACK) Query audio device from settings struct again 2020-05-21 04:21:00 +02:00
twinaphex a4f143a71a Buildfix 2020-05-21 00:46:49 +02:00
twinaphex 2037de5b33 Silence more warnings 2020-05-20 23:40:26 +02:00
twinaphex 6173d11b62 Silence unused function warning 2020-05-20 23:35:32 +02:00
twinaphex 060ad38905 (WiiU) Buildfix 2020-05-20 23:34:23 +02:00
twinaphex 41fd598195 Update CHANGES.md 2020-05-20 23:02:54 +02:00
twinaphex 0fced84f93 (Netplay) Lower announce rate 2020-05-20 23:01:04 +02:00
Autechre 50cb20592c Merge pull request #10655 from fjtrujy/ps2-newlib
Adapt PS2 port to newlib support
2020-05-20 20:14:22 +02:00
Francisco Javier Trujillo Mata 1eeb3dcf30 Adapt PS2 port to new SDK with newlib support (CDVDFS support is missing) 2020-05-20 20:13:19 +02:00
twinaphex a3d3e18369 Update 2020-05-20 19:54:37 +02:00
Autechre 69ec94fe47 Merge pull request #10673 from jdgleaver/window-title-fix
NUL terminate 'fps_text' string
2020-05-20 18:55:26 +02:00
jdgleaver 41cee583e3 NUL terminate 'fps_text' string 2020-05-20 17:51:20 +01:00
Autechre 4713bf5cef Merge pull request #10672 from jdgleaver/file-path-optimisations
Various file path handling optimisations
2020-05-20 18:21:59 +02:00
jdgleaver c346e1f816 Various file path handling optimisations 2020-05-20 17:05:22 +01:00
twinaphex 3d677ee90c (Discord RPC) Simplify - use string_is_equal - de-auto type certain
variables where possible
2020-05-20 17:59:42 +02:00
Joan Coll Cerdán e43111d9cb Support fallback dirs to cycle user shader presets
When a user shader preset was saved, if the Video Shader directory
wasn't writable, it would fall back to the Menu Config directory, and
failing that, it would fall back to the directory where retroarch.cfg
is stored.

This change allows the shader cycling feature to use those directories
if no shader presets are found on the Video Shader directory.
2020-05-20 17:47:23 +02:00
Joan Coll Cerdán 2768655267 Cleaner structure for auto shader presets.
Additional changes:

* Restore the previous storage path for user-presets until a better
  solution is agreed upon.

* Stop using the Video Shaders directory as fallback directory to
  store autopresets. Will be used only when autoloading as last resort to
  ensure compatibility with old setups.
2020-05-20 17:47:23 +02:00
twinaphex 057ae3c134 Update CHANGES.md 2020-05-20 17:35:52 +02:00
twinaphex e64b4c1d24 For gamepad-like console/Android TV devices - default to Ozone 2020-05-20 17:34:39 +02:00
twinaphex aeb3f692d5 Get rid of superfluous get_ai_service_auto/set_ai_service_auto get/set
wrapper functions
2020-05-20 16:35:53 +02:00
twinaphex af01b97a11 Add TODO/FIXME 2020-05-20 16:32:20 +02:00
twinaphex d9ab59cb4a Comment out function that isn't used 2020-05-20 16:29:57 +02:00
twinaphex 4a20709645 (Win32) Cleanup accessibility_speak_windows 2020-05-20 16:26:39 +02:00
twinaphex 647bdc5cbd (Discord RPC) Cleanups 2020-05-20 16:10:46 +02:00
twinaphex 115e779cf0 (Discord) Comment out code that isn't being used 2020-05-20 16:03:46 +02:00
twinaphex 3387170d62 (Discord) Cleanups - get rid of discord_register.h header 2020-05-20 15:43:01 +02:00
twinaphex 03ea12d334 Move discord files to network/ 2020-05-20 15:27:27 +02:00
twinaphex a8fdfd77ce Make gamma correction 'int' type across the board 2020-05-20 15:04:16 +02:00
twinaphex cb5de27631 Cleanup 2020-05-20 14:48:22 +02:00
twinaphex d9ccd3a737 Turn core_poll_type_override into enum variable 2020-05-20 14:23:25 +02:00
Autechre 5874bb8b27 Update CHANGES.md 2020-05-20 14:02:41 +02:00
Autechre 2f42fc5932 Merge pull request #10670 from jdgleaver/remap-default-fix
(Input Remapping) Fix 'reset to default' action for analog sticks and undefined core inputs
2020-05-20 13:58:31 +02:00
jdgleaver 0bbd5b7a45 (Input Remapping) Fix 'reset to default' action for analog sticks and undefined core inputs 2020-05-20 11:48:09 +01:00
twinaphex d1c130d60a Global variable cleanups 2020-05-20 06:29:58 +02:00
twinaphex 692f37b91a Rearrange global variables 2020-05-20 06:04:51 +02:00
twinaphex 13279eb0d4 Move defines to top 2020-05-20 04:54:14 +02:00
twinaphex 9e5f00ba27 Turn retroarch_fail static 2020-05-20 04:43:35 +02:00
twinaphex 1e21bf5074 Move defines to top 2020-05-20 04:39:27 +02:00
twinaphex 51c1064609 retroarch_validate_per_core_options - cut down on code duplication 2020-05-20 04:18:57 +02:00
twinaphex a188826a10 Cleanups 2020-05-20 04:02:43 +02:00
twinaphex 24dd7409bc Move more global variables and forward declarations up top 2020-05-20 03:58:36 +02:00
twinaphex cc2d70f044 (retroarch.c) Turn some AI functions static 2020-05-20 03:47:14 +02:00
twinaphex 7b5b14b0a7 More reorganization of globals, enums, defines 2020-05-20 03:38:16 +02:00
twinaphex 969475254f (retroarch.c) Reorganize globals, forward declarations, and defines 2020-05-20 03:30:04 +02:00
twinaphex 2cc776d2d9 Cleanups 2020-05-20 02:42:39 +02:00
twinaphex 5852251d56 Fix --disable-menu 2020-05-20 02:25:33 +02:00
twinaphex 182ad31c63 (retroarch.c) Relocate structs and enums 2020-05-20 02:19:20 +02:00
twinaphex 2a36fa0855 Remove double ';' 2020-05-19 21:29:35 +02:00
twinaphex ad1aa59ce1 Cleanup != NULL comparisons 2020-05-19 21:15:06 +02:00
twinaphex 6d37d014a0 Simplify ozone_get_entries_padding 2020-05-19 20:51:40 +02:00
Autechre bc522c3fa5 Merge pull request #10664 from jdgleaver/menu-remove-hash
Remove last remaining menu hash
2020-05-19 18:43:09 +02:00
jdgleaver 73b9b5b270 Remove last remaining menu hash 2020-05-19 17:29:12 +01:00
Autechre 4b90fcdeac Update CHANGES.md 2020-05-19 18:06:04 +02:00
Autechre 7eaa771d57 Merge pull request #10663 from jdgleaver/overlay-leak-fix
Fix memory leak when loading overlays
2020-05-19 18:05:23 +02:00
twinaphex 521f4bfefc Remove more unneeded video_frame_info variables 2020-05-19 17:52:54 +02:00
jdgleaver 6800fadafe Fix memory leak when loading overlays 2020-05-19 16:37:20 +01:00
twinaphex 26c6c34817 video_frame_info - remove more unused settings 2020-05-19 16:51:05 +02:00
twinaphex 3f98cbc52d Get rid of some unneeded variables in video_frame_info 2020-05-19 16:42:56 +02:00
twinaphex 9ace693ec0 Refactor menu_driver_frame 2020-05-19 16:20:43 +02:00
twinaphex 0aff65e77b Sync libretro-common 2020-05-19 15:22:00 +02:00
Autechre 8c63ea2515 Update CHANGES.md 2020-05-19 15:14:24 +02:00
Autechre f9f0c5aea6 Merge pull request #10662 from jdgleaver/thumbnail-free-fix
(gfx_thumbnail) Fix heap-use-after-free error
2020-05-19 15:13:21 +02:00
jdgleaver 5eee8daa4f (gfx_thumbnail) Fix heap-use-after-free error 2020-05-19 14:03:02 +01:00
twinaphex d4dd1f71a5 (menu_displaylist.c) Move state into struct 2020-05-19 14:59:06 +02:00
twinaphex 25888db0af (menu_driver.c) Move state into struct 2020-05-19 13:40:27 +02:00
Autechre 2b19a50775 Update CHANGES.md 2020-05-19 12:50:26 +02:00
Autechre 8c0b15052a Merge pull request #10658 from jdgleaver/input-remap-start-scan-fix
(Input Mapping/Remapping) Restore broken 'reset to default' functionality
2020-05-19 12:47:34 +02:00
jdgleaver 5e904c4dc3 (Input Mapping/Remapping) Restore broken 'reset to default' functionality 2020-05-19 11:35:57 +01:00
twinaphex 54fd445c75 (verbosity) move static global variables to struct 2020-05-19 02:13:51 +02:00
Autechre 27a7ab20e2 Update CHANGES.md 2020-05-18 20:58:06 +02:00
Autechre 646efb91e1 Merge pull request #10654 from Jamiras/chd_find_special_fail
return false when special track cannot be found
2020-05-18 20:57:42 +02:00
Jamiras c805fd3213 return false when special track cannot be found 2020-05-18 09:10:06 -06:00
Weedy Weed Smoker 2d83b58703 French: disable hardcore when cheats are enabled 2020-05-18 18:12:52 +07:00
Autechre 582f967fb0 Update AndroidManifest.xml 2020-05-18 02:15:03 +02:00
Autechre 12af4ed7e3 Update CHANGES.md 2020-05-17 22:23:22 +02:00
Autechre f5623edec1 Merge pull request #10640 from Jamiras/cheevos_cheats
(cheevos) disable hardcore when cheats are enabled
2020-05-17 22:22:31 +02:00
Autechre 0be52f8a49 Update CHANGES.md 2020-05-17 22:22:00 +02:00
Autechre 83410572cc Merge pull request #10646 from QuarkTheAwesome/master
WiiU: Gamepad hotplugging support, theoretical multi-gamepad support, warning fixes
2020-05-17 22:21:21 +02:00
Ash Logan 70fba3e92e (WiiU/kpad) Actually return true when kpad_init succeeds, warning fix 2020-05-17 16:43:38 +10:00
Ash Logan 41541128c5 (WiiU/hid) Warning fixes 2020-05-17 16:42:31 +10:00
Ash Logan cdaf907467 (WiiU/hid) hid.h only used in drivers_hid/wiiu, don't include everywhere 2020-05-17 16:39:41 +10:00
Ash Logan f22af81e7d (WiiU/wpad) Allow hotplugging Gamepad, support >1 channel 2020-05-17 16:32:51 +10:00
Jamiras 9107e5767c make message less verbose 2020-05-16 09:28:13 -06:00
Jamiras 6946f878ef disable hardcore when cheats are enabled 2020-05-16 08:01:24 -06:00
Autechre f1158b988c Update RetroArch_iOS9-Info.plist 2020-05-16 15:22:20 +02:00
Autechre fb073544d2 Update Info_Metal.plist 2020-05-16 15:21:05 +02:00
Autechre a8d8523747 Update Info.plist 2020-05-16 15:20:52 +02:00
Autechre ef9a3c2007 Update AndroidManifest.xml 2020-05-16 15:20:15 +02:00
Autechre b0a549716f Update version.dtd 2020-05-16 15:19:53 +02:00
Autechre 435af0f982 Update version.all 2020-05-16 15:19:31 +02:00
Autechre 8c2c094830 Update CHANGES.md 2020-05-16 15:19:02 +02:00
Autechre feb39a114d Update CHANGES.md 2020-05-16 15:18:51 +02:00
Autechre b7f56fc551 Merge pull request #10627 from johanbcn/shader-presets-fallback-dirs
Fallback directories for shader presets
2020-05-16 13:55:58 +02:00
Weedy Weed Smoker 9631719061 Update msg_hash_pt_br.h according to PR #10551 2020-05-16 09:38:45 +07:00
Weedy Weed Smoker 056a5d1466 French: add cheevos_start_active option 2020-05-16 08:42:10 +07:00
Weedy Weed Smoker 493dd1749c French: Add option to stretch menu to fill screen 2020-05-16 08:38:15 +07:00
Weedy Weed Smoker f5a880b6c5 French: Add desktop-style playlist view mode 2020-05-16 08:36:06 +07:00
Weedy Weed Smoker ec624f7baa French: Add back RGUI_BORDER_FILLER_THICKNESS 2020-05-16 08:34:23 +07:00
Autechre d3a55ef732 Merge pull request #10637 from meleu/patch-11
cheevos: option to start a session with all achievements active
2020-05-15 22:31:09 +02:00
Autechre b910e6230f Merge pull request #10636 from jdgleaver/ozone-playlist-sorting
(Ozone) Fix sidebar playlist sort order when 'Truncate Playlist Names' is enabled
2020-05-15 22:30:11 +02:00
meleu 69949187f6 add cheevos_start_active option 2020-05-15 14:49:47 -03:00
jdgleaver b53f635441 (Ozone) Fix sidebar playlist sort order when 'Truncate Playlist Names' is enabled 2020-05-15 17:26:36 +01:00
Autechre c31d4e6b69 Merge pull request #10633 from jdgleaver/cheevos-disable
Don't perform unnecessary cheevos initialisation when cheevos are disabled
2020-05-15 15:22:16 +02:00
jdgleaver 706875160e Don't perform unnecessary cheevos initialisation when cheevos are disabled 2020-05-15 13:33:05 +01:00
Autechre a8eaf82e06 Merge pull request #10612 from Jamiras/rcheevos_90
(cheevos) upgrade to rcheevos 9.0
2020-05-15 09:53:03 +02:00
Autechre 82666abbdd Update CHANGES.md 2020-05-14 19:42:38 +02:00
Autechre e7c909fe66 Merge pull request #10631 from jdgleaver/global-core-options-default
Disable 'Use Global Core Options File' by default
2020-05-14 19:41:14 +02:00
jdgleaver d9673b8c8f Disable 'Use Global Core Options File' by default 2020-05-14 17:27:13 +01:00
Autechre 383fdae18f Merge pull request #10629 from jdgleaver/rgui-wallpaper
(RGUI) Enable custom wallpaper when menu size is reduced at low resolutions
2020-05-14 15:54:19 +02:00
jdgleaver 9d5a54ced4 (RGUI) Enable custom wallpaper when menu size is reduced at low resolutions 2020-05-14 14:18:53 +01:00
Autechre 50b4492fef Merge pull request #10628 from jdgleaver/tab-switch-rate
(XMB/GLUI) Limit tab switch rate when input repeat is active
2020-05-14 13:55:58 +02:00
jdgleaver eff8c31ffd (XMB/GLUI) Limit tab switch rate when input repeat is active 2020-05-14 11:24:32 +01:00
twinaphex 89c7d1a835 Update libretro-common 2020-05-14 09:27:58 +02:00
Autechre 7d517a431d Merge pull request #10626 from phcoder/mips
cpu_features_get_time_usec: Use sceKernelGetSystemTimeWide on PSP and…
2020-05-14 09:23:59 +02:00
Joan Coll Cerdán 718e9eaf37 Comply with the C89 standard 2020-05-14 00:32:52 +02:00
Joan Coll Cerdán fe42f6bb73 Changed the order of shader preset directories.
The Menu Config directory now takes precedence over the Video Shader
directory for the storage of shader preset overrides. With this, all
user overrides are grouped by default under the same path.
2020-05-13 19:54:08 +02:00
Joan Coll Cerdán f1f248dd11 Add fallback directories to shader presets.
Improves the management of shader presets by using the Menu Config directory
and the directory of the configuration file as alternate fallback directories
whenever the Video Shader directory is not writable.
2020-05-13 19:54:08 +02:00
Vladimir Serbinenko cab004f08a cpu_features_get_time_usec: Use sceKernelGetSystemTimeWide on PSP and Vita 2020-05-13 11:20:40 +02:00
Autechre 1545285953 Merge pull request #10625 from phcoder/dosalam
Support for dos salamander
2020-05-13 09:29:37 +02:00
Vladimir Serbinenko 31d9fedf47 cpu_features_get_time_usec: Use monotonic_clock on djgpp 2020-05-12 22:55:15 +02:00
Autechre 6c4c93e17b Update CHANGES.md 2020-05-12 18:09:38 +02:00
Autechre ba452c204b Merge pull request #10624 from dankcushions/menuticker
Adjusted menu defaults
2020-05-12 17:57:34 +02:00
Vladimir Serbinenko 70c57beea9 Support for dos salamander 2020-05-12 17:39:04 +02:00
dankcushions edb308ceb2 Adjusted menu defaults 2020-05-12 16:27:16 +01:00
twinaphex 2ab7da36f2 (Win32) Style nits 2020-05-12 17:16:36 +02:00
twinaphex cfd0731422 (PS3) Style nit cleanups 2020-05-12 17:11:51 +02:00
twinaphex 494c0f8fe4 (PSL1GHT) Cleanups 2020-05-12 17:06:58 +02:00
twinaphex 1d1c7e5a0d (PSL1GHT/GCM) Style nits 2020-05-12 15:10:15 +02:00
twinaphex bde18ba86a Style nits 2020-05-12 14:36:27 +02:00
twinaphex 9088137051 Remove unused function 2020-05-12 14:20:12 +02:00
twinaphex cc50eaa88f Cleanup 2020-05-12 14:02:10 +02:00
twinaphex 86b78e2fea Cleanups 2020-05-12 09:11:18 +02:00
twinaphex 57bbf7c944 (gfx widgets) Rearrange variables 2020-05-12 08:56:57 +02:00
twinaphex 84369cf6ba (Win32) Cleanups 2020-05-12 08:49:41 +02:00
twinaphex 3981b1cc82 (Qt) Cleanups 2020-05-12 08:02:55 +02:00
Autechre e8d2ea7a56 Update CHANGES.md 2020-05-12 06:27:57 +02:00
Autechre 1fabb661a6 Update CHANGES.md 2020-05-12 06:27:18 +02:00
Autechre 709d6a2214 Merge pull request #10617 from Jamiras/cheevos_image_loading
(cheevos) make sure texture pointer is null when load fails
2020-05-12 06:26:35 +02:00
Autechre ca9c022a7f Merge pull request #10618 from phcoder/dos
Dos/DJGPP fixes
2020-05-12 06:26:17 +02:00
Autechre 34b8b457c7 Merge pull request #10619 from phcoder/frodoid
3ds: Add ID for frodo
2020-05-12 06:25:26 +02:00
Vladimir Serbinenko 6d184abf84 Fix dist-cores.sh for dos 2020-05-12 03:20:53 +02:00
Vladimir Serbinenko 05500c6c39 dos: Add 32-bit gfx support 2020-05-12 03:09:38 +02:00
Vladimir Serbinenko 306fed32f6 Fix djgpp clock 2020-05-12 03:09:38 +02:00
Vladimir Serbinenko 67c3c93aec dos fixes 2020-05-12 03:09:38 +02:00
Vladimir Serbinenko 7b351da006 Fix crash with null audio driver 2020-05-12 03:09:38 +02:00
Vladimir Serbinenko cc73de48d6 Fix dos compilation 2020-05-12 03:09:38 +02:00
Vladimir Serbinenko cc52f140d0 3ds: Add ID for frodo 2020-05-12 02:10:36 +02:00
Jamiras 4093616e09 make sure texture pointer is null when load fails 2020-05-11 16:24:29 -06:00
Autechre 96cfa57d1b Update CHANGES.md 2020-05-11 23:33:23 +02:00
Autechre ef4261e1f8 Update CHANGES.md 2020-05-11 23:33:05 +02:00
Autechre 4fe372662a Merge pull request #10614 from jdgleaver/glui-desktop-thumb-persistence
(GLUI) Desktop View: When scrolling playlists, show last selected thumbnails while waiting for next entry to load
2020-05-11 23:32:39 +02:00
jdgleaver 43b890a269 (GLUI) Desktop View: When scrolling playlists, show last selected thumbnails while waiting for next entry to load 2020-05-11 16:32:49 +01:00
twinaphex 6a4a522244 Cut down on some code duplication and turn
retroarch_validate_game_options static
2020-05-11 17:19:55 +02:00
twinaphex dd721def41 (Qt) Cleanups 2020-05-11 17:07:37 +02:00
twinaphex 81a623c2b6 Style nits 2020-05-11 16:49:31 +02:00
Jamiras 1534e81bed upgrade to rcheevos 9.0 2020-05-11 08:43:11 -06:00
Autechre 718d9801da Update CHANGES.md 2020-05-11 16:26:26 +02:00
Autechre 42c5bb970e Merge pull request #10613 from jdgleaver/rgui-fill-screen
(RGUI) Add option to always stretch menu to fill the screen
2020-05-11 16:26:01 +02:00
jdgleaver 26c01dd34c (RGUI) Add option to always stretch menu to fill the screen 2020-05-11 11:38:24 +01:00
Autechre 98daa0d28c Update CHANGES.md 2020-05-11 10:19:05 +02:00
Autechre 01667b5fc3 Update CHANGES.md 2020-05-11 04:53:16 +02:00
twinaphex 4a9e1e6c7e Revert "Backport"
This reverts commit 685db05032.
2020-05-11 03:49:27 +02:00
Autechre f5b33c8912 Update CHANGES.md 2020-05-11 03:33:41 +02:00
Autechre 35269cce93 Update CHANGES.md 2020-05-11 03:32:10 +02:00
twinaphex 685db05032 Backport
https://github.com/neil4/RetroArch-Lite/commit/66876fe8581de7b2ee79a06a5c4912d0e8e52b41
- handles insertion/removal of audio devices for Xaudio2 - hopefully a
callback based approach can be done later
2020-05-11 03:29:01 +02:00
twinaphex 39dbfd1db4 Remove unused menu_content.h 2020-05-11 02:32:45 +02:00
Autechre 57cd3fdf06 Merge pull request #10611 from AlexKornitzer/master
cocoa: disable clipping cursor to window
2020-05-11 02:31:32 +02:00
Alex Kornitzer 1d2dd249f3 cocoa: disable clipping cursor to window 2020-05-11 00:58:06 +01:00
Alex Kornitzer cdfb8348b0 cocoa: use absolute positioning over relative
Now that we clip the window to locate the cursor correctly on re-entry
we need to do our cursor calculations using absolute coordinates
2020-05-11 00:58:06 +01:00
Autechre 211a8a149b Update CHANGES.md 2020-05-11 00:31:17 +02:00
Autechre c2b7ebbcdf Merge pull request #10610 from AlexKornitzer/master
cocoa: fix cursor tracking
2020-05-11 00:30:47 +02:00
Alex Kornitzer c4ee0463aa cocoa: don't update mouse events when outside nswindow 2020-05-10 22:44:44 +01:00
Alex Kornitzer edfafd9fad cocoa: fix mouse movement
The input driver was using absolute coordinate arithmetic while making
use of delta changes for each coordinate, as a result the absolute
change netted to zero. This fixes that and tries to mitigate cursor
event sync issues (sync issues will require more work).
2020-05-10 22:44:44 +01:00
Autechre 9c749f03eb Update CHANGES.md 2020-05-10 15:41:10 +02:00
Autechre 58b9b6c875 Merge pull request #10606 from TobiX/wiiu-gfx-widgets
Enable GFX widgets on WiiU
2020-05-10 15:40:13 +02:00
Tobias Gruetzmacher 29929acdba (WiiU) Enable GFX widgets 2020-05-10 15:13:23 +02:00
Tobias Gruetzmacher 3c192419dd (WiiU) Fix griffin build 2020-05-10 14:30:30 +02:00
Autechre 7b8983a0e0 Merge pull request #10594 from MrHuu/master
(3DS) Enable basic networking / cheevos
2020-05-10 14:07:21 +02:00
twinaphex e74161bc6c Change name of nvdaController.h 2020-05-10 08:51:25 +02:00
twinaphex 10e6ea21a3 Put this behind HAVE_ACCESSIBILITY ifdef 2020-05-10 07:17:15 +02:00
twinaphex ba8a07a2b6 (Menu driver) Turn some functions into static functions 2020-05-10 07:14:29 +02:00
Autechre a8e3917613 Update CHANGES.md 2020-05-10 07:04:44 +02:00
twinaphex 1e9b94ded4 Get rid of hash 2020-05-10 05:05:43 +02:00
Twinaphex 2f3ef75bf6 Remove some unused variables and some style nits 2020-05-10 01:10:45 +02:00
twinaphex 3ad4b057f9 Go back to 1.8.4 netcode 2020-05-10 01:02:47 +02:00
Autechre 1fc64df5f6 Merge pull request #10603 from Brottweiler/patch-1
Use GenericName correctly in desktop entry
2020-05-10 00:56:36 +02:00
Christoffer Tibell 1e6ccb2310 Use GenericName correctly in desktop entry 2020-05-09 23:14:30 +02:00
Autechre 29a28f0d02 Merge pull request #10600 from jdgleaver/glui-desktop-view
(GLUI) Add desktop-style playlist view mode
2020-05-09 22:36:08 +02:00
Autechre aa5ddee807 Merge pull request #10601 from barbudreadmon/patch-4
(glcore) switch to glcore video driver when requested
2020-05-09 22:33:46 +02:00
barbudreadmon 7a3ddcd77d (glcore) switch to glcore video driver when requested
fix #10486
2020-05-09 17:15:45 +02:00
jdgleaver 63644ac761 (GLUI) Add desktop-style playlist view mode 2020-05-09 14:53:52 +01:00
Francisco José García García df3af35ee4 (VITA) Fix for new VITASDK 2020-05-09 09:51:50 +02:00
Francisco José García García 84de78e7c9 (Vita) Fix for latest VITASDK 2020-05-09 09:46:12 +02:00
MrHuu e519ccd0be (3DS) Enable basic networking / cheevos 2020-05-08 20:50:15 +02:00
Autechre 470756e22c Merge pull request #10588 from im4potato/translation
US Translation: Add back RGUI_BORDER_FILLER_THICKNESS
2020-05-08 06:47:03 +02:00
im4potato 09e54d1e75 US Translation: Fix spelling of "checkerboard" to match other settings 2020-05-07 21:05:30 -07:00
im4potato 38c8369e58 US Translation: Add back RGUI_BORDER_FILLER_THICKNESS 2020-05-07 20:58:50 -07:00
Autechre 9fb170bcd4 Merge pull request #10586 from francescotintori/francesco/vs2019
Added VS2019 solution project (copied from VS2017)
2020-05-08 00:21:16 +02:00
francescotintori e1d0514ec5 Added VS2019 solution project (copied from VS2017) 2020-05-07 23:03:54 +02:00
twinaphex ad7612eef3 (wiiu) Style nit cleanups 2020-05-07 20:23:14 +02:00
twinaphex 33cf0e160c Style nits 2020-05-07 20:13:02 +02:00
Autechre b78c48c2c3 Merge pull request #10581 from Roet-Ivar/wiiu_storage_usb_access
Added access to WiiU-formated storage to be browsed by RetroArch
2020-05-07 20:05:09 +02:00
Autechre 778b42de58 Merge pull request #10584 from meleu/patch-9
retroarch.cfg: add cheevos related configs
2020-05-07 20:04:40 +02:00
meleu 2f392f2260 retroarch.cfg: add cheevos related configs 2020-05-07 14:28:15 -03:00
Roet-Ivar ad34f4845b Added access to WiiU-formated storage to be browsed by RetroArch 2020-05-07 12:49:04 +02:00
Autechre 36802f7133 Update CHANGES.md 2020-05-06 02:13:22 +02:00
Autechre ca782bd015 Update CHANGES.md 2020-05-06 02:13:01 +02:00
Autechre 7b3aaa6bbb Merge pull request #10570 from MrHuu/patch-7
(3DS) re-Enable 7z support
2020-05-05 18:02:34 +02:00
MrHuu 16d12e804c (3DS) re-Enable 7z support
Adds missing HAVE_7ZIP definition for griffin builds.

I have no issues with this. Browsing and loading .7z files works as it should.
Unless there's a specific reason this was removed, it can be enabled.
2020-05-05 12:25:13 +02:00
Autechre 25be09acd3 Merge pull request #10564 from jdgleaver/3ds-filter-fix
(3DS) Disable video filter if upscaled resolution exceeds hardware limits
2020-05-04 19:28:42 +02:00
Autechre 621e220177 Merge pull request #10569 from jdgleaver/3ds-font-fix
(3DS) Fix font driver
2020-05-04 19:28:10 +02:00
jdgleaver a305a48a11 (3DS) Fix font driver 2020-05-04 16:57:44 +01:00
hizzlekizzle 877a7f8d6c Merge pull request #10563 from phcoder/radir
psl1ght: Fix cores info path
2020-05-04 09:54:36 -05:00
jdgleaver 702bc18128 (3DS) Disable video filter if upscaled resolution exceeds hardware limits 2020-05-04 11:52:53 +01:00
Francisco José García García 78c27dc77a Squashed 'deps/vitaGL/' content from commit 9a6e4b3397
git-subtree-dir: deps/vitaGL
git-subtree-split: 9a6e4b3397c207e136b2d618fa4b58e2b37c383e
2020-05-04 12:43:18 +02:00
Francisco José García García 0de4efae44 Merge commit '78c27dc77af4a03886058cc76f3553a0b3e28cc1' as 'deps/vitaGL' 2020-05-04 12:43:18 +02:00
Francisco José García García ded0e13623 Remove old vitaGL 2020-05-04 12:43:11 +02:00
Vladimir Serbinenko afe68f9cd8 psl1ght: Fix cores info path 2020-05-04 11:43:47 +02:00
Weedy Weed Smoker d51cd37fa8 French: Add option to mute audio when fast-forward 2020-05-02 20:01:53 +07:00
Weedy Weed Smoker 695203212c French: (Ozone) Refactor footer display 2020-05-02 19:57:27 +07:00
Weedy Weed Smoker 7d849ac8fb International: Add all the languages from Crowdin… 2020-05-02 13:29:17 +07:00
Autechre 3ecde62930 Merge pull request #10550 from guoyunhe/unify-show-hide
unify "show/hide" -> "show or hide"
2020-05-01 21:17:01 +02:00
Guo Yunhe ab7c2f23cf unify "show/hide" -> "show or hide" 2020-05-01 21:17:52 +03:00
Autechre 0554e3cb3d Merge pull request #10549 from Alcaro/patch-4
Fix copypasted typo
2020-05-01 18:42:06 +02:00
Alcaro c9dcc18fa4 Fix copypasted typo 2020-05-01 17:46:18 +02:00
Autechre 43c521de44 Merge pull request #10548 from jdgleaver/qt-volume-settings
(Qt) Add 'audio mixer volume' and 'mute when fast-forwarding' settings options
2020-05-01 17:30:05 +02:00
jdgleaver 4ef5eb1eb2 (Qt) Add 'audio mixer volume' and 'mute when fast-forwarding' settings options 2020-05-01 13:58:20 +01:00
Autechre 1a07476138 Merge pull request #10547 from jdgleaver/fast-forward-mute
Add option to mute audio when fast-forwarding
2020-05-01 14:11:31 +02:00
jdgleaver 3f2ba2e791 Add option to mute audio when fast-forwarding 2020-05-01 12:19:31 +01:00
hizzlekizzle 9dc963e15a Merge pull request #10544 from jdgleaver/glcore-shader-fix
(glcore/slang) Set filter and wrap mode correctly when intialising shader textures
2020-04-30 15:45:45 -05:00
Autechre fb28c79e13 Merge pull request #10545 from aschain/maylashN64-fix
Fix for mayflash N64 adapter
2020-04-30 20:09:45 +02:00
A Schain 1e751d00ea 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.
2020-04-30 13:27:44 -04:00
jdgleaver 548c5dc925 (glcore/slang) Set filter and wrap mode correctly when intialising shader textures 2020-04-30 17:04:02 +01:00
Autechre 9c100ded3a Merge pull request #10535 from jdgleaver/ozone-metadata-toggle
(Ozone) Enable second thumbnail/content metadata toggle using RetroPad 'select'
2020-04-30 15:52:51 +02:00
Autechre 5160f35bd8 Merge pull request #10531 from altiereslima/master
Update msg_hash_pt_br.h
2020-04-30 15:00:53 +02:00
Autechre 34d3641d0a Merge pull request #10534 from ShadowOne333/patch-2
Update and fix meta.xml file for the WiiU release
2020-04-30 15:00:38 +02:00
Autechre 4198a0d3a8 Merge pull request #10536 from karlforshaw/master
Advise against using -s and -S variables on the command line.
2020-04-30 14:59:46 +02:00
Autechre 8f0ef54455 Merge pull request #10539 from trioan/buildfix
MSVC Buildfix
2020-04-30 14:19:23 +02:00
Autechre e92331cf1f Merge pull request #10542 from jdgleaver/screenshot-fix
(task_screenshot) Fix heap-use-after-free error when widgets are disabled
2020-04-30 14:17:21 +02:00
jdgleaver 3a3c4f60bf (task_screenshot) Fix heap-use-after-free error when widgets are disabled 2020-04-30 11:25:53 +01:00
jdgleaver 19a8a815f0 (Ozone) Hide thumbnail button hints when viewing file browser lists 2020-04-30 09:57:44 +01:00
trioan 35bf716766 (MSVC 2012) Buildfix 2020-04-29 19:45:48 -05:00
trioan 3883616d93 (MSVC 2013) Buildfix 2020-04-29 19:45:32 -05:00
trioan de0b34aa0a (MSVC 2015) Buildfix 2020-04-29 22:59:20 +00:00
trioan e14fc1b087 (MSVC 2017) Buildfix 2020-04-29 22:55:22 +00:00
hizzlekizzle 53d07b30cc Merge pull request #10515 from im-4-potato/master
US Translation: Style changes and more cleanup
2020-04-29 17:49:28 -05:00
jdgleaver 0b294faa71 (Ozone) Refactor footer display 2020-04-29 17:54:49 +01:00
twinaphex d995fa045a (GDI) Get rid of unused functions 2020-04-29 18:40:48 +02:00
Karl Forshaw 5ed60cde04 Advise against using -s and -S variables on the command line.
Signed-off-by: Karl Forshaw <[email protected]>
2020-04-29 13:39:12 +01:00
twinaphex bb27496e2e Prevent NULL pointer dereference 2020-04-29 14:38:11 +02:00
twinaphex 9b8c596057 (GL Core) Buildfix for video context drivers that dont
implement this callback
2020-04-29 13:50:21 +02:00
jdgleaver 30555f8132 (Ozone) Enable second thumbnail/content metadata toggle using RetroPad 'select' 2020-04-29 12:29:42 +01:00
Shadow a319db9119 Typo fix
Typo fix
2020-04-28 21:36:13 -07:00
Shadow b5eabf633a 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.
2020-04-28 21:20:30 -07:00
altiereslima a27912b816 Update msg_hash_pt_br.h 2020-04-28 18:13:47 -03:00
twinaphex 156d3629e6 libretro-common Update 2020-04-28 16:26:26 +02:00
twinaphex 4f9a3f6813 Update 2020-04-28 16:25:00 +02:00
Autechre 3b6b067fe5 Merge pull request #10530 from jdgleaver/compress-states-default
Enable save state compression by default
2020-04-28 12:53:26 +02:00
jdgleaver 1ac544b612 Enable save state compression by default 2020-04-28 11:37:16 +01:00
Autechre e3a78e0ecf Merge pull request #10529 from jdgleaver/ozone-touch-fix
(Ozone) Fix undefined behaviour when using touch screen to change input remaps
2020-04-28 12:02:28 +02:00
jdgleaver 58e6ca9ad4 (Ozone) Fix undefined behaviour when using touch screen to change input remaps 2020-04-28 10:46:19 +01:00
im-4-potato 0c40b2b3ef Merge remote-tracking branch 'upstream/master' 2020-04-27 14:55:08 -07:00
Autechre 6642868b86 Merge pull request #10518 from guoyunhe/patch-5
Unify mixer settings strings
2020-04-27 23:06:13 +02:00
twinaphex 14c63e0cd5 Bump version number 2020-04-27 23:05:30 +02:00
im-4-potato fcb4933671 US Translation: A few fixes for Title Case 2020-04-27 13:43:55 -07:00
im-4-potato 571d9708e1 US Translation: Sync with other changes 2020-04-27 13:18:30 -07:00
Autechre bd319de5cf Merge pull request #10517 from guoyunhe/patch-4
Force Aspect -> Force Aspect Ratio
2020-04-27 20:30:13 +02:00
Autechre 78a67bd775 Merge pull request #10516 from guoyunhe/patch-3
Framerate -> Refresh Rate
2020-04-27 20:29:57 +02:00
Autechre 3744f2454c Merge pull request #10519 from julianaito/master
Remove OpenBSD/macppc specific quirk
2020-04-27 20:29:40 +02:00
Autechre 39aae2872d Merge pull request #10525 from libretro/set_gamepad_bitwise_fix
Added small fix to set_gamepad_input_override bit logic.
2020-04-27 20:28:54 +02:00
Autechre e9a35c1cab Merge pull request #10524 from jdgleaver/config-write-on-change
Only write config files to disk when parameters change
2020-04-27 19:35:55 +02:00
Barry Rowe d87fa1799e Added small fix to set_gamepad_input_override bit logic. 2020-04-27 10:16:11 -07:00
jdgleaver 9eb8472805 Only write config files to disk when parameters change 2020-04-27 17:06:35 +01:00
im-4-potato 6921ca44a7 US Translation: More Fixes 2020-04-26 17:07:06 -07:00
im-4-potato 7b4a4d1da4 US Translation: More Fixes 2020-04-26 17:00:59 -07:00
im-4-potato 60cfbce48b US Translation: More fixes 2020-04-26 14:51:20 -07:00
im-4-potato 3e3a84a602 US Translation: More fixes 2020-04-26 12:36:47 -07:00
Charlène Wendling 0e4857c8f6 Remove OpenBSD/macppc specific quirk
OpenBSD/macppc moved to clang and __mftb() is not available anymore,
leading to undefined references errors. It's fixed with #10383 already.
2020-04-26 14:13:59 +02:00
im-4-potato 68021903c9 US Translation: More minor fixes 2020-04-26 03:15:24 -07:00
im-4-potato f803ee2c0b US Translation: A few more "save state" fixes 2020-04-26 03:00:16 -07:00
Guo Yunhe c40f2ae5bb Unify mixer settings strings 2020-04-26 12:14:57 +03:00
Guo Yunhe 8d71714446 Update msg_hash_us.h 2020-04-26 11:36:18 +03:00
Guo Yunhe cc6a5a6077 Update msg_hash_us.h 2020-04-26 09:37:34 +03:00
Guo Yunhe 004588d627 Update msg_hash_us.h 2020-04-26 09:30:49 +03:00
Guo Yunhe 49d0045434 Force Aspect -> Force Aspect Ratio 2020-04-26 09:24:11 +03:00
Guo Yunhe f5c7b1bf73 Framerate -> Refresh Rate
Based on the key and context, here should be `refresh rate` instead of `frame rate`.
2020-04-26 08:55:48 +03:00
im-4-potato 6972492fb4 US Translation: Changes tabs back to spaces 2020-04-25 20:52:10 -07:00
im-4-potato 311a7d40d2 US Translation: Style changes and more cleanup 2020-04-25 20:40:29 -07:00
twinaphex c88ffa56ff (Vulkan) Fix crash 2020-04-25 17:44:13 +02:00
Autechre 05b1785f24 Merge pull request #10511 from WeedyWeedSmoker/International-translations-fix-formatting
International: Fix formatting for all languages & Remove untranslated strings
2020-04-25 16:15:56 +02:00
Weedy Weed Smoker 9b99393c20 International: Fix 2020-04-25 20:43:42 +07:00
Weedy Weed Smoker 38c70d5705 International: Remove untranslated strings + fixes 2020-04-25 19:26:25 +07:00
Weedy Weed Smoker 8def289271 International: Formatting fix for all languages 2020-04-25 19:24:22 +07:00
Autechre 88abadce43 Merge pull request #10505 from WeedyWeedSmoker/Japanese-translation-update
Japanese: Fix multi-line strings
2020-04-24 20:44:11 +02:00
Weedy Weed Smoker 7f7680da6e Japanese: Remove extraneous spaces 2020-04-25 00:45:23 +07:00
Weedy Weed Smoker 7b71f22e85 Japanese: Fix multi-line strings 2020-04-25 00:16:36 +07:00
Autechre c4d6c9541c Merge pull request #10504 from altiereslima/master
Update msg_hash_pt_br.h
2020-04-24 07:50:09 +02:00
altiereslima 5a468c8b3e Update msg_hash_pt_br.h 2020-04-23 21:37:01 -03:00
altiereslima 12e68bf477 Update msg_hash_pt_br.h 2020-04-23 21:19:52 -03:00
Autechre 1040e57c94 Merge pull request #10498 from WeedyWeedSmoker/French-translation-update
French: Add optional playlist compression
2020-04-24 01:10:59 +02:00
Autechre b18219687c Merge pull request #10500 from jdgleaver/vulkan-stats-fix
(Vulkan) Fix display of statistics text
2020-04-24 01:10:52 +02:00
Autechre e6fcf73a1e Merge pull request #10501 from maksun/patch-1
[Retroarch] Tiny glitch when displaying version
2020-04-24 01:10:43 +02:00
maksun b92ac7d439 [Retroarch] Tiny issue when displaying version
Just two lines to fix #10445
2020-04-23 19:48:51 +02:00
jdgleaver 0e3026d41f (Vulkan) Fix display of statistics text 2020-04-23 17:48:15 +01:00
Weedy Weed Smoker 3346124d21 French: Add optional playlist compression 2020-04-23 19:41:20 +07:00
Autechre 89c405b196 Merge pull request #10487 from jdgleaver/playlist-compression
Add optional playlist compression
2020-04-23 13:30:58 +02:00
jdgleaver 69305fda96 (playlist.c) Remove unused variable 2020-04-23 12:04:08 +01:00
jdgleaver 8cf629b3c2 (playlist.c) Minor clean-ups 2020-04-23 11:55:17 +01:00
jdgleaver 25c6499c5d (playlist.c) Omit whitespace when writing compressed JSON format playlists 2020-04-23 10:49:16 +01:00
twinaphex bdf9969c7e Update libretro-common 2020-04-23 07:20:06 +02:00
Autechre 62c2842c86 Merge pull request #10478 from WeedyWeedSmoker/French-translation-update
French: Add optional save (SRAM) file compression, Clean up and organize FR translation & Formatting
2020-04-23 04:23:23 +02:00
Autechre e8fe4e26ff Merge pull request #10497 from yoshisuga/ios_tvos_audio_session_fix
[iOS] [tvOS] Fix audio getting cut off on interruption
2020-04-23 04:18:13 +02:00
Autechre 1085e553d5 Merge pull request #10496 from altiereslima/master
Update Portuguese Brazilian Translation
2020-04-23 02:43:08 +02:00
altiereslima e38808b17c Update Portuguese Brazilian Translation 2020-04-22 20:32:09 -03:00
Autechre 21f15d5cbd Merge pull request #10490 from phcoder/msb
Remove manual MSB_FIRST definitions and switch to retro_endianness.h
2020-04-22 21:16:45 +02:00
Autechre 0c42b643a9 Merge pull request #10491 from QuarkTheAwesome/master
[WiiU] Warning fixes+devkitPPC updates
2020-04-22 21:16:33 +02:00
Autechre 28bf33cd78 Merge pull request #10493 from QuarkTheAwesome/gfx-display-wiiu-patch
WiiU: gfx_display: fix non-vertex coordinates in draws using tex shader
2020-04-22 21:16:17 +02:00
Autechre 7f0f36fb7a Merge pull request #10495 from MrHuu/patch-6
(3DS) Add ID for TGB-Dual
2020-04-22 21:15:26 +02:00
MrHuu 941b369016 (3DS) Add ID for TGB-Dual
Add unique id for TGB-Dual .cia build
2020-04-22 21:07:42 +02:00
Yoshi Sugawara a85ed986de Set audio session category to ambient so sound does not get cut off on interruption (phone call/playing back audio) 2020-04-22 08:54:57 -10:00
Weedy Weed Smoker 21d0320e42 French: Add optional save (SRAM) file compression 2020-04-22 21:19:24 +07:00
hizzlekizzle 843503e92a Merge pull request #10492 from phcoder/3ids
IDs for uzem and neocd
2020-04-22 09:12:02 -05:00
Ash Logan 08dfd58994 WiiU: Enable -Wall
This is the standard, according to CONTRIBUTING.md
2020-04-22 23:37:18 +10:00
Ash Logan ed24d05752 WiiU: gfx_display: fix non-vertex coordinates in draws using tex shader
This second case is hit when there's a quad with different-coloured 
corners, since the tex shader is needed to support that. In the quad 
case, there are no vertexes, and the ->x,y,width,height fields are used 
instead.

Fixes #8519.
2020-04-22 23:35:46 +10:00
Vladimir Serbinenko 28d30064b6 IDs for uzem and neocd 2020-04-22 13:44:23 +02:00
Ash Logan 7bac0220dc libfat: Remove st_spare for new devkitPPC versions
slurped from 
https://github.com/devkitPro/libfat/commit/d6bb60a4baa360946c32588a829f908607d85780
2020-04-22 10:56:49 +10:00
Autechre cb510f04d8 Merge pull request #10488 from MrHuu/patch-5
(3DS) Allow control bindings for multiple players
2020-04-22 01:08:34 +02:00
MrHuu 92dc0dc6d0 (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.
2020-04-21 20:52:49 +02:00
jdgleaver fa9290cf1e Add optional playlist compression 2020-04-21 16:44:26 +01:00
Vladimir Serbinenko 1fcdddf579 Remove manual MSB_FIRST definitions and switch to retro_endianness.h 2020-04-21 04:16:55 +02:00
Autechre ce4c750326 Merge pull request #10484 from Tatsuya79/patch-3
qt: add saveram compression option
2020-04-21 02:03:21 +02:00
Tatsuya79 ce99109001 qt: add saveram compression option 2020-04-21 01:50:05 +02:00
twinaphex 8a15f0094a Bugfix 2020-04-21 00:49:02 +02:00
twinaphex 3a2a365ec9 (libretro-common) Fix retro_endianness.h 2020-04-21 00:46:48 +02:00
Autechre 3529f2da4c Merge pull request #10481 from jdgleaver/save-compression
Add optional save (SRAM) file compression
2020-04-21 00:25:58 +02:00
twinaphex 64bbe5b646 (MSVC 2010) Buildfix 2020-04-21 00:20:31 +02:00
hizzlekizzle 2427d90f48 Merge pull request #10482 from jdgleaver/font-fix
(WiiU/3DS) Fix font driver horizontal text alignment
2020-04-20 14:50:21 -05:00
jdgleaver 6c49ae5152 (WiiU/3DS) Fix font driver horizontal text alignment 2020-04-20 16:20:21 +01:00
jdgleaver 0d1fd657ab Add optional save (SRAM) file compression 2020-04-20 12:48:40 +01:00
Weedy Weed Smoker b4cadb1a16 Caught another formatting error… 2020-04-20 06:49:17 +07:00
Weedy Weed Smoker a2192b14db Caught a formatting error… 2020-04-20 06:18:39 +07:00
Weedy Weed Smoker ae467486ba French: Translate all FIXME tagged elements too 2020-04-20 05:25:07 +07:00
Weedy Weed Smoker 88d162452a French: Clean up and organize FR translation 2020-04-20 04:53:17 +07:00
twinaphex 3fa60d08de Update libretro-common 2020-04-19 20:44:22 +02:00
twinaphex 1eb612135b Revert "Revert "Take this out - cores that need usleep and such - address it in""
This reverts commit 7e3a400cb7.
2020-04-19 19:18:53 +02:00
twinaphex 7e3a400cb7 Revert "Take this out - cores that need usleep and such - address it in"
This reverts commit 48b6b4ca8e.
2020-04-19 18:54:05 +02:00
twinaphex 48b6b4ca8e Take this out - cores that need usleep and such - address it in
the core itself, or rewrite the reference so it uses libretro-common
sleeping functions instead
2020-04-19 18:15:47 +02:00
Autechre c2319b3a21 Merge pull request #10470 from jdgleaver/ai-service-menu-hide
AI Service Menu - Hide redundant entries when service is disabled
2020-04-18 18:01:06 +02:00
twinaphex 9a50205867 Add this around ifdefs 2020-04-18 17:59:27 +02:00
jdgleaver b1503bc7c8 AI Service Menu - Hide redundant entries when service is disabled 2020-04-18 14:06:35 +01:00
im4potatoandim-4-potato d5d4c1a319 msg_hash_us.h: Clean up and organize US translation (#10460)
* msg_hash_us.h: Clean up and organize US translation

* msg_hash_us.h: More cleanup

* msg_hash_us.h: Update to latest version after syncing with upstream

* msg_hash_us.h: Removed indents from preprocessor lines

Co-authored-by: im-4-potato <[email protected]>
2020-04-17 21:07:51 -05:00
Barry Rowe 8988e2d34b Added additional return to accessibility_speak_windows 2020-04-17 14:07:28 -07:00
Autechre 9588eb451b Merge pull request #10467 from jdgleaver/ai-fixes2
More build fixes
2020-04-17 18:40:29 +02:00
Autechre acfa3fc4d4 Merge pull request #10465 from jdgleaver/rzip-stream-additions
Expand functionality of 'rzip_stream' interface
2020-04-17 18:40:14 +02:00
jdgleaver 6ef5fa1aa5 More build fixes 2020-04-17 17:08:12 +01:00
Autechre af140741bc Merge pull request #10466 from jdgleaver/ai-fixes
Build fixes
2020-04-17 17:50:29 +02:00
jdgleaver ddc860d4b0 Build fixes 2020-04-17 16:42:37 +01:00
jdgleaver c1f4a7536a Expand functionality of 'rzip_stream' interface 2020-04-17 16:18:16 +01:00
twinaphex b91c342ff4 Buildfix MSVC 2010 2020-04-17 16:40:39 +02:00
twinaphex 352519c91e Another builfdix 2020-04-17 16:32:10 +02:00
twinaphex f3b82dc998 Buildfix 2020-04-17 16:29:23 +02:00
twinaphex 9f3a2db44e Merge branch 'master' of https://github.com/libretro/RetroArch 2020-04-17 16:24:39 +02:00
Autechre 018a0baed6 Merge pull request #10401 from libretro/accessibility_menu_fixes
Accessibility menu fixes
2020-04-17 03:19:17 +02:00
Autechre ddaeb2b24b Merge pull request #10458 from WeedyWeedSmoker/French-translation-update
French: Add optional save state compression, corrections, formatting
2020-04-17 01:51:44 +02:00
Autechre 51183787af Merge pull request #10459 from AlexKornitzer/feature/cocoa-fix
ui_cocoa: fix mouse input for cocoa
2020-04-17 01:49:38 +02:00
Autechre 2e3b6c5a17 Merge pull request #10463 from phcoder/kbl1ght
Implement psl1ght keyboard
2020-04-17 01:49:18 +02:00
Autechre f5a8e16109 Merge pull request #10462 from phcoder/f1x
platform_unix: Fix overflow when computing total memory on i386
2020-04-17 01:48:59 +02:00
Autechre 950cd41dfa Merge pull request #10448 from CrewMdk/patch-2
Updated spanish language translation
2020-04-17 01:48:32 +02:00
Autechre 0b86348711 Merge pull request #10461 from Tatsuya79/patch-2
qt: add savestate compression option
2020-04-17 01:48:15 +02:00
Autechre c8555924e0 Merge pull request #10464 from phcoder/vitasleep
Add usleep and sleep on Vita.
2020-04-17 01:47:56 +02:00
Vladimir Serbinenko a029cb9fc5 Add usleep and sleep on Vita.
libstdc++ links against them under some circumstances. This is needed for
neocd
2020-04-17 00:58:01 +02:00
Vladimir Serbinenko 5b668ae421 Implement psl1ght keyboard 2020-04-17 00:56:23 +02:00
Vladimir Serbinenko 99e9a1ea0d platform_unix: Fix overflow when computing total memory on i386 2020-04-17 00:54:06 +02:00
Tatsuya79 56159976af qt: add savestate compression option 2020-04-17 00:10:02 +02:00
Alex Kornitzer ac4b49f1c2 ui_cocoa: fix mouse input for cocoa
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.
2020-04-16 22:01:40 +01:00
Weedy Weed Smoker 875bb8bda3 International: Formatting corrections 2020-04-17 03:52:25 +07:00
Weedy Weed Smoker c76e46d930 French: Corrections for clarity 2020-04-17 03:50:58 +07:00
Weedy Weed Smoker baf67a7dff French: Add optional save state compression 2020-04-17 03:49:34 +07:00
Barry Rowe adb5c4c7dd Moved SAPI code into a define. 2020-04-16 11:57:39 -07:00
Autechre 5303ecee22 Merge pull request #10454 from jdgleaver/save-state-compression
Add optional save state compression
2020-04-15 20:41:30 +02:00
jdgleaver 233456df47 Add optional save state compression 2020-04-15 15:48:41 +01:00
CrewMdk 725ee77383 Updated spanish language translation
The latest additions from English to Spanish have been added.
2020-04-13 20:18:53 -05:00
Barry Rowe 289be872f3 Added in auto-translate support, fixes for ozone and glui accessibility, and support for nvda and SAPI narration. 2020-04-13 17:46:08 -07:00
Autechre 910da74519 Merge pull request #10442 from WeedyWeedSmoker/French-translation-update
French: Add optional per-playlist alphabetical sorting
2020-04-13 02:56:00 +02:00
Weedy Weed Smoker 2e0f85ac93 French: Add per-playlist alphabetical sorting 2020-04-13 01:35:49 +07:00
Autechre ef2e51b4f6 Merge pull request #10434 from jdgleaver/per-playlist-sort
(Playlist Management) Add optional per-playlist alphabetical sorting
2020-04-12 14:02:56 +02:00
Autechre af3980ff66 Merge pull request #10420 from m4tsa/libnx_update
Fix the single breaking change from libnx 3.1.0
2020-04-11 18:10:08 +02:00
Mats A e3cbd2e62f add define to keep compat with previous libnx release 2020-04-11 18:07:59 +02:00
Autechre d98731d5d9 Merge pull request #10415 from LordeIlluminati/LordeIlluminati-patch-1
Update msg_hash_pt_br.h
2020-04-11 14:41:10 +02:00
Autechre ca4328b53c Merge pull request #10437 from valadaa48/oga_perf_fix
oga_gfx: move non-inlined function out of loop
2020-04-11 14:40:35 +02:00
Autechre 26bed1e264 Merge pull request #10429 from phcoder/f1x
Fix psl1ght compilation
2020-04-11 14:26:30 +02:00
jdgleaver 4dec80e9e3 Style nits 2020-04-11 13:00:24 +01:00
valadaa48 587a425f77 oga_gfx: move non-inlined function out of loop 2020-04-11 02:30:39 +00:00
hizzlekizzle 8096ced303 Merge pull request #10433 from felinben/translation
Update retroarch.desktop for German
2020-04-10 19:47:09 -05:00
Linux User 86e8aeaaa5 Update retroarch.desktop for German 2020-04-10 17:41:19 +01:00
jdgleaver 223cae66c1 (Playlist Management) Add optional per-playlist alphabetical sorting 2020-04-10 17:07:49 +01:00
hizzlekizzle d6058bba82 Merge pull request #10430 from Alcaro/patch-3
intl/README.md: Fix typo
2020-04-09 16:24:29 -05:00
Alcaro 3249c10215 intl/README.md: Fix typo 2020-04-09 21:07:17 +02:00
Vladimir Serbinenko c957e07399 Fix psl1ght compilation
pkg.py is not necessatily in path
mftb works better than posix on psl1ght
2020-04-09 15:53:38 +02:00
Autechre df1fefd775 Merge pull request #10421 from jdgleaver/playlist-fixes
Improve handling of 'broken' playlists
2020-04-09 14:17:01 +02:00
Autechre d521945479 Merge pull request #10425 from jdgleaver/ozone-font-alignemnt
(Ozone) Enable proper vertical text alignment + thumbnail display improvements
2020-04-09 14:16:46 +02:00
Autechre 74fb8cb7b2 Merge pull request #10426 from jdgleaver/ozone-pointer-fix
(Ozone) Pointer input fixes
2020-04-09 13:38:08 +02:00
jdgleaver 887999904b (Ozone) Pointer input fixes 2020-04-08 17:09:38 +01:00
jdgleaver 545e5fd6ab (Ozone) Enable proper vertical text alignment + thumbnail display improvements 2020-04-08 15:15:39 +01:00
Jeff Sousa ac5e151d1e Update msg_hash_pt_br.h 2020-04-08 09:16:46 -03:00
Jeff Sousa c8d269e5de Update msg_hash_pt_br.h 2020-04-08 09:15:15 -03:00
Jeff Sousa e7173e974b Update msg_hash_pt_br.h 2020-04-08 09:10:34 -03:00
Jeff Sousa 7b0d527ffe Update msg_hash_pt_br.h 2020-04-08 08:46:57 -03:00
Mats A 6f5f600f47 rename U64_MAX to UINT64_MAX due to libnx changes 2020-04-07 13:23:06 +02:00
jdgleaver ad8a1174f7 Improve handling of 'broken' playlists 2020-04-07 12:00:16 +01:00
Jeff Sousa 24b5e5234f Update msg_hash_pt_br.h 2020-04-07 01:37:00 -03:00
LordeIlluminati 1d438d8d06 Update msg_hash_pt_br.h 2020-04-07 00:43:16 -03:00
LordeIlluminati 891372c4b1 Update msg_hash_pt_br.h 2020-04-07 00:24:29 -03:00
LordeIlluminati 3de030ba74 Update msg_hash_pt_br.h 2020-04-06 22:37:34 -03:00
LordeIlluminati a6dd70a320 Update msg_hash_pt_br.h 2020-04-06 22:31:15 -03:00
LordeIlluminati ffe79897e5 Update msg_hash_pt_br.h 2020-04-06 19:13:03 -03:00
Autechre b01aabf7d1 Merge pull request #10411 from jdgleaver/widget-text-alignment
Widget text improvements
2020-04-06 15:37:58 +02:00
Autechre 304e13ac16 Merge pull request #10412 from jdgleaver/task-fix
Fix task deadlocks
2020-04-06 15:25:25 +02:00
jdgleaver c1d41e190c (task_queue) Add warning about the usage of 'task_queue_remove()' 2020-04-06 14:16:24 +01:00
jdgleaver 13df7795fc Fix task deadlocks 2020-04-06 13:51:22 +01:00
jdgleaver f559798750 Widget text improvements 2020-04-06 11:39:30 +01:00
twinaphex e88568625c Merge branch 'master' of https://github.com/libretro/RetroArch 2020-04-06 01:04:23 +02:00
Autechre 0716fa02d6 Update CHANGES.md 2020-04-05 13:12:18 +02:00
Autechre 325a8a4cbd Merge pull request #10394 from CrewMdk/patch-1
Updated spanish language translation
2020-04-05 13:06:39 +02:00
Autechre b0820ca1db Merge pull request #10386 from jdgleaver/rgui-downscale
(RGUI) Enable automatic menu size reduction when running at low resolutions (down to 256x192)
2020-04-05 13:06:30 +02:00
Autechre 8d44c0c752 Merge pull request #10397 from Jamiras/cheevos_gba_no_mmap
[cheevos] report non-memorymap gba cores as unsupported
2020-04-05 13:06:15 +02:00
Autechre 5b5a086fd3 Merge pull request #10398 from Jamiras/cheevos_null_check
[cheevos] prevent null reference rendering achievement list while closing application
2020-04-05 13:05:59 +02:00
Autechre f7e6d9e7b8 Merge pull request #10399 from Jamiras/thread_queue_unfinished
fix race condition where task could momentarily not be in the queue when reordering
2020-04-05 13:05:49 +02:00
Autechre 1f43533ff9 Merge pull request #10400 from yoshisuga/yoshisuga/tvos_no_overlay
tvOS: Disable overlays for tvOS, fix app icon
2020-04-05 13:05:30 +02:00
Yoshi Sugawara 4f5616cb91 tvOS: Disable overlays for tvOS, fix app icon 2020-04-04 08:22:24 -10:00
Jamiras 23ba478f82 fix race condition where task could momentarily not be in the queue when reordering 2020-04-04 09:37:55 -06:00
Jamiras ff3b033815 prevent null reference rendering achievement list while closing emulator 2020-04-04 09:28:11 -06:00
Jamiras a08840de6d report non-memorymap gba cores as unsupported 2020-04-04 09:13:10 -06:00
CrewMdk ed34643f01 Updated spanish language translation 2020-04-03 20:36:06 -06:00
jdgleaver a9c496e01f (RGUI) Enable automatic menu size reduction when running at low resolutions (down to 256x192) 2020-04-02 16:54:39 +01:00
twinaphex a9154373fc Merge branch 'master' of https://github.com/libretro/RetroArch 2020-04-02 02:13:12 +02:00
twinaphex 92c472c227 Merge branch 'master' of https://github.com/libretro/RetroArch 2020-03-29 06:01:31 +02:00
twinaphex 4589fde775 Simplify video_context_driver_translate_aspect 2020-03-28 05:44:58 +01:00
twinaphex 8b8d9e0841 Style nits 2020-03-28 05:40:16 +01:00
twinaphex 19c68fad43 Take out cb_update_window_title and cb_get_metrics 2020-03-28 05:36:31 +01:00
600 changed files with 205324 additions and 139261 deletions

No files matched your search

+1 -1
View File
@@ -174,7 +174,7 @@ retroarch_switch.nso
# PS2
ps2/irx/*.c
ps2/libcdvd/lib/
*.irx
# Wayland
gfx/common/wayland/idle-inhibit-unstable-v1.c
+12
View File
@@ -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
@@ -136,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"
@@ -144,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"
+2 -2
View File
@@ -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",
+183 -1
View File
@@ -1,18 +1,200 @@
# 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
- CHD: Fixes a crash caused by ignoring the return value from one of the CHD library functions.
- 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
+57 -39
View File
@@ -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)
@@ -807,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 \
@@ -839,14 +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 \
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)
@@ -1681,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
@@ -1764,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
@@ -1810,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)
@@ -1890,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
@@ -1898,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 \
@@ -2075,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)))
+4 -2
View File
@@ -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
+1
View File
@@ -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
+41 -1
View File
@@ -155,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
@@ -868,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)))
+15 -34
View File
@@ -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
+1 -1
View File
@@ -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)
+1
View File
@@ -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
+1
View File
@@ -70,6 +70,7 @@ OBJ = frontend/frontend_salamander.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
+1
View File
@@ -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
+7 -2
View File
@@ -1,5 +1,6 @@
TARGET := retroarch_vita
DEBUG ?= 0
HAVE_FILE_LOGGER = 1
GRIFFIN_BUILD = 0
WHOLE_ARCHIVE_LINK = 0
@@ -87,7 +88,7 @@ AR := $(PREFIX)ar
OBJCOPY := $(PREFIX)objcopy
STRIP := $(PREFIX)strip
NM := $(PREFIX)nm
LD := $(CXX)
LD := $(CC)
LIBDIRS := -L.
@@ -122,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
@@ -181,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
+1
View File
@@ -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
+1
View File
@@ -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
+6 -4
View File
@@ -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
+1
View File
@@ -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
-9
View File
@@ -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
+5 -4
View File
@@ -25,6 +25,7 @@
#include <boolean.h>
#include <rthreads/rthreads.h>
#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)
{
+4 -1
View File
@@ -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;
}
+1 -1
View File
@@ -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);
+4
View File
@@ -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 */
+1 -1
View File
@@ -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);
+6 -6
View File
@@ -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);
+1 -1
View File
@@ -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;
-301
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}
+10 -5
View File
@@ -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;
}
File renamed without changes.
File diff suppressed because it is too large. Load diff
+1 -5
View File
@@ -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
File renamed without changes.
+314
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1 -3
View File
@@ -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';
File renamed without changes.
+1 -1
View File
@@ -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
+67 -14
View File
@@ -413,6 +413,7 @@
#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
@@ -517,8 +518,8 @@ static const bool menu_show_sublabels = true;
static const bool menu_scroll_fast = false;
#define DEFAULT_MENU_TICKER_TYPE (TICKER_TYPE_BOUNCE)
static const float menu_ticker_speed = 1.0f;
#define DEFAULT_MENU_TICKER_TYPE (TICKER_TYPE_LOOP)
static const float menu_ticker_speed = 2.0f;
#define DEFAULT_MENU_TICKER_SMOOTH true
@@ -539,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
@@ -610,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;
@@ -803,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. */
@@ -911,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
@@ -936,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. */
@@ -950,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
@@ -1044,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;
@@ -1051,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_DDMM_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;
+194 -164
View File
@@ -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;
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 enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL;
static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL;
#elif defined(HAVE_OPENGL_CORE) && !defined(__HAIKU__)
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL_CORE;
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);
@@ -1432,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)
@@ -1453,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);
@@ -1587,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);
@@ -1614,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);
@@ -1648,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);
@@ -1662,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);
@@ -1675,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));
@@ -1696,6 +1706,8 @@ 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);
@@ -1725,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));
@@ -1747,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
@@ -1786,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);
@@ -1894,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));
@@ -1920,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));
@@ -2496,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;
@@ -2670,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);
@@ -2685,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);
@@ -3346,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);
@@ -3354,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 */
@@ -3365,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);
@@ -3385,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 */
@@ -3396,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);
@@ -3416,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)
@@ -3485,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);
@@ -4119,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)
{
@@ -4193,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:
@@ -4245,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;
}
+14 -1
View File
@@ -131,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;
@@ -143,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;
@@ -284,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;
@@ -303,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;
@@ -344,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;
@@ -377,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;
@@ -389,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;
@@ -431,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;
@@ -485,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;
@@ -540,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;
@@ -611,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
+4 -4
View File
@@ -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);
+764
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#include <string/stdstring.h>
#include <lists/string_list.h>
#include <file/file_path.h>
#include <streams/interface_stream.h>
#include <streams/file_stream.h>
#include <lists/dir_list.h>
#include <time/rtime.h>
#include <retro_miscellaneous.h>
#include "frontend/frontend_driver.h"
#include "file_path_special.h"
#include "verbosity.h"
#include "core_backup.h"
/* Holds all entries in a core backup list */
struct core_backup_list
{
size_t size;
size_t capacity;
core_backup_list_entry_t *entries;
};
/*********************/
/* Utility Functions */
/*********************/
/* Generates backup directory path for specified core.
* Returns false if 'core_path' and/or 'dir_core_assets'
* are invalid, or a filesystem error occurs */
static bool core_backup_get_backup_dir(
const char *dir_libretro, const char *dir_core_assets,
const char *core_filename,
char *backup_dir, size_t len)
{
char *last_underscore = NULL;
char core_file_id[PATH_MAX_LENGTH];
char tmp[PATH_MAX_LENGTH];
core_file_id[0] = '\0';
tmp[0] = '\0';
/* Extract core file 'ID' (name without extension + suffix)
* from core path */
if (string_is_empty(dir_libretro) ||
string_is_empty(core_filename) ||
(len < 1))
return false;
strlcpy(core_file_id, core_filename, sizeof(core_file_id));
/* > Remove file extension */
path_remove_extension(core_file_id);
if (string_is_empty(core_file_id))
return false;
/* > Remove platform-specific file name suffix,
* if required */
last_underscore = strrchr(core_file_id, '_');
if (!string_is_empty(last_underscore))
if (!string_is_equal(last_underscore, "_libretro"))
*last_underscore = '\0';
if (string_is_empty(core_file_id))
return false;
/* Get core backup directory
* > If no assets directory is defined, use
* core directory as a base */
fill_pathname_join(tmp, string_is_empty(dir_core_assets) ?
dir_libretro : dir_core_assets,
"core_backups", sizeof(tmp));
fill_pathname_join(backup_dir, tmp,
core_file_id, len);
if (string_is_empty(backup_dir))
return false;
/* > Create directory, if required */
if (!path_is_directory(backup_dir))
{
if (!path_mkdir(backup_dir))
{
RARCH_ERR("[core backup] Failed to create backup directory: %s.\n", backup_dir);
return false;
}
}
return true;
}
/* Generates a timestamped core backup file path from
* the specified core path. Returns true if successful */
bool core_backup_get_backup_path(
const char *core_path, uint32_t crc, enum core_backup_mode backup_mode,
const char *dir_core_assets, char *backup_path, size_t len)
{
int n;
time_t current_time;
struct tm time_info;
const char *core_filename = NULL;
char core_dir[PATH_MAX_LENGTH];
char backup_dir[PATH_MAX_LENGTH];
char backup_filename[PATH_MAX_LENGTH];
core_dir[0] = '\0';
backup_dir[0] = '\0';
backup_filename[0] = '\0';
/* Get core filename and parent directory */
if (string_is_empty(core_path))
return false;
core_filename = path_basename(core_path);
if (string_is_empty(core_filename))
return false;
fill_pathname_parent_dir(core_dir, core_path, sizeof(core_dir));
if (string_is_empty(core_dir))
return false;
/* Get backup directory */
if (!core_backup_get_backup_dir(core_dir, dir_core_assets, core_filename,
backup_dir, sizeof(backup_dir)))
return false;
/* Get current time */
time(&current_time);
rtime_localtime(&current_time, &time_info);
/* Generate backup filename */
n = snprintf(backup_filename, sizeof(backup_filename),
"%s.%04u%02u%02uT%02u%02u%02u.%08x.%u%s",
core_filename,
(unsigned)time_info.tm_year + 1900,
(unsigned)time_info.tm_mon + 1,
(unsigned)time_info.tm_mday,
(unsigned)time_info.tm_hour,
(unsigned)time_info.tm_min,
(unsigned)time_info.tm_sec,
crc,
(unsigned)backup_mode,
file_path_str(FILE_PATH_CORE_BACKUP_EXTENSION));
if ((n < 0) || (n >= 128))
n = 0; /* Silence GCC warnings... */
/* Build final path */
fill_pathname_join(backup_path, backup_dir,
backup_filename, len);
return true;
}
/* Returns detected type of specified core backup file */
enum core_backup_type core_backup_get_backup_type(const char *backup_path)
{
const char *backup_ext = NULL;
struct string_list *metadata_list = NULL;
char core_ext[255];
core_ext[0] = '\0';
if (string_is_empty(backup_path) || !path_is_valid(backup_path))
goto error;
/* Get backup file extension */
backup_ext = path_get_extension(backup_path);
if (string_is_empty(backup_ext))
goto error;
/* Get platform-specific dynamic library extension */
if (!frontend_driver_get_core_extension(core_ext, sizeof(core_ext)))
goto error;
/* Check if this is an archived backup */
if (string_is_equal_noncase(backup_ext,
file_path_str(FILE_PATH_CORE_BACKUP_EXTENSION_NO_DOT)))
{
const char *backup_filename = NULL;
const char *src_ext = NULL;
/* Split the backup filename into its various
* metadata components */
backup_filename = path_basename(backup_path);
if (string_is_empty(backup_filename))
goto error;
metadata_list = string_split(backup_filename, ".");
if (!metadata_list || (metadata_list->size != 6))
goto error;
/* Get extension of source core file */
src_ext = metadata_list->elems[1].data;
if (string_is_empty(src_ext))
goto error;
/* Check whether extension is valid */
if (!string_is_equal_noncase(src_ext, core_ext))
goto error;
string_list_free(metadata_list);
metadata_list = NULL;
return CORE_BACKUP_TYPE_ARCHIVE;
}
/* Check if this is a plain dynamic library file */
if (string_is_equal_noncase(backup_ext, core_ext))
return CORE_BACKUP_TYPE_LIB;
error:
if (metadata_list)
{
string_list_free(metadata_list);
metadata_list = NULL;
}
return CORE_BACKUP_TYPE_INVALID;
}
/* Fetches crc value of specified core backup file.
* Returns true if successful */
bool core_backup_get_backup_crc(char *backup_path, uint32_t *crc)
{
struct string_list *metadata_list = NULL;
enum core_backup_type backup_type;
if (string_is_empty(backup_path) || !crc)
goto error;
/* Get backup type */
backup_type = core_backup_get_backup_type(backup_path);
switch (backup_type)
{
case CORE_BACKUP_TYPE_ARCHIVE:
{
const char *backup_filename = NULL;
const char *crc_str = NULL;
/* Split the backup filename into its various
* metadata components */
backup_filename = path_basename(backup_path);
if (string_is_empty(backup_filename))
goto error;
metadata_list = string_split(backup_filename, ".");
if (!metadata_list || (metadata_list->size != 6))
goto error;
/* Get crc string */
crc_str = metadata_list->elems[3].data;
if (string_is_empty(crc_str))
goto error;
/* Convert to an integer */
*crc = (uint32_t)string_hex_to_unsigned(crc_str);
if (*crc == 0)
goto error;
string_list_free(metadata_list);
metadata_list = NULL;
return true;
}
break;
case CORE_BACKUP_TYPE_LIB:
{
intfstream_t *backup_file = NULL;
/* This is a plain dynamic library file,
* have to read file data to determine crc */
/* Open backup file */
backup_file = intfstream_open_file(
backup_path, RETRO_VFS_FILE_ACCESS_READ,
RETRO_VFS_FILE_ACCESS_HINT_NONE);
if (backup_file)
{
bool success;
/* Get crc value */
success = intfstream_get_crc(backup_file, crc);
/* Close backup file */
intfstream_close(backup_file);
free(backup_file);
backup_file = NULL;
return success;
}
}
break;
default:
/* Backup is invalid */
break;
}
error:
if (metadata_list)
{
string_list_free(metadata_list);
metadata_list = NULL;
}
return false;
}
/* Fetches core path associated with specified core
* backup file. Returns detected type of backup
* file - CORE_BACKUP_TYPE_INVALID indicates that
* backup file cannot be restored/installed, or
* arguments are otherwise invalid */
enum core_backup_type core_backup_get_core_path(
const char *backup_path, const char *dir_libretro,
char *core_path, size_t len)
{
const char *backup_filename = NULL;
char *core_filename = NULL;
enum core_backup_type backup_type = CORE_BACKUP_TYPE_INVALID;
if (string_is_empty(backup_path) || string_is_empty(dir_libretro))
return backup_type;
backup_filename = path_basename(backup_path);
if (string_is_empty(backup_filename))
return backup_type;
/* Check backup type */
switch (core_backup_get_backup_type(backup_path))
{
case CORE_BACKUP_TYPE_ARCHIVE:
{
char *period = NULL;
/* This is an archived backup with timestamp/crc
* metadata in the filename */
core_filename = strdup(backup_filename);
/* Find the location of the second period */
period = strchr(core_filename, '.');
if (!period || (*(++period) == '\0'))
break;
period = strchr(period, '.');
if (!period)
break;
/* Trim everything after (and including) the
* second period */
*period = '\0';
if (string_is_empty(core_filename))
break;
/* All good - build core path */
fill_pathname_join(core_path, dir_libretro,
core_filename, len);
backup_type = CORE_BACKUP_TYPE_ARCHIVE;
}
break;
case CORE_BACKUP_TYPE_LIB:
/* This is a plain dynamic library file */
fill_pathname_join(core_path, dir_libretro,
backup_filename, len);
backup_type = CORE_BACKUP_TYPE_LIB;
break;
default:
/* Backup is invalid */
break;
}
if (core_filename)
{
free(core_filename);
core_filename = NULL;
}
return backup_type;
}
/*************************/
/* Backup List Functions */
/*************************/
/**************************************/
/* Initialisation / De-Initialisation */
/**************************************/
/* Parses backup file name and adds to backup list, if valid */
static bool core_backup_add_entry(core_backup_list_t *backup_list,
const char *core_filename, const char *backup_path)
{
char *backup_filename = NULL;
core_backup_list_entry_t *entry = NULL;
unsigned backup_mode = 0;
if (!backup_list ||
string_is_empty(core_filename) ||
string_is_empty(backup_path) ||
(backup_list->size >= backup_list->capacity))
goto error;
backup_filename = strdup(path_basename(backup_path));
if (string_is_empty(backup_filename))
goto error;
/* Ensure base backup filename matches core */
if (!string_starts_with(backup_filename, core_filename))
goto error;
/* Remove backup file extension */
path_remove_extension(backup_filename);
/* Parse backup filename metadata
* - <core_filename>.<timestamp>.<crc>.<backup_mode>
* - timestamp: YYYYMMDDTHHMMSS */
entry = &backup_list->entries[backup_list->size];
if (sscanf(backup_filename + strlen(core_filename),
".%04u%02u%02uT%02u%02u%02u.%08x.%u",
&entry->date.year, &entry->date.month, &entry->date.day,
&entry->date.hour, &entry->date.minute, &entry->date.second,
&entry->crc, &backup_mode) != 8)
goto error;
entry->backup_mode = (enum core_backup_mode)backup_mode;
/* Cache backup path */
entry->backup_path = strdup(backup_path);
backup_list->size++;
free(backup_filename);
return true;
error:
if (backup_filename)
free(backup_filename);
return false;
}
/* Creates a new core backup list containing entries
* for all existing backup files.
* Returns a handle to a new core_backup_list_t object
* on success, otherwise returns NULL. */
core_backup_list_t *core_backup_list_init(
const char *core_path, const char *dir_core_assets)
{
size_t i;
const char *core_filename = NULL;
struct string_list *dir_list = NULL;
core_backup_list_t *backup_list = NULL;
core_backup_list_entry_t *entries = NULL;
char core_dir[PATH_MAX_LENGTH];
char backup_dir[PATH_MAX_LENGTH];
core_dir[0] = '\0';
backup_dir[0] = '\0';
/* Get core filename and parent directory */
if (string_is_empty(core_path))
goto error;
core_filename = path_basename(core_path);
if (string_is_empty(core_filename))
goto error;
fill_pathname_parent_dir(core_dir, core_path, sizeof(core_dir));
if (string_is_empty(core_dir))
goto error;
/* Get backup directory */
if (!core_backup_get_backup_dir(core_dir, dir_core_assets, core_filename,
backup_dir, sizeof(backup_dir)))
goto error;
/* Get backup file list */
dir_list = dir_list_new(
backup_dir,
file_path_str(FILE_PATH_CORE_BACKUP_EXTENSION),
false, /* include_dirs */
false, /* include_hidden */
false, /* include_compressed */
false /* recursive */
);
/* Sanity check */
if (!dir_list)
goto error;
if (dir_list->size < 1)
goto error;
/* Ensure list is sorted in alphabetical order
* > This corresponds to 'timestamp' order */
dir_list_sort(dir_list, true);
/* Create core backup list */
backup_list = (core_backup_list_t*)calloc(1, sizeof(*backup_list));
if (!backup_list)
goto error;
/* Create entries array
* (Note: Set this to the full size of the directory
* list - this may be larger than we need, but saves
* many inefficiencies later) */
entries = (core_backup_list_entry_t*)calloc(dir_list->size, sizeof(*entries));
if (!entries)
goto error;
backup_list->entries = entries;
backup_list->capacity = dir_list->size;
backup_list->size = 0;
/* Loop over backup files and parse file names */
for (i = 0; i < dir_list->size; i++)
{
const char *backup_path = dir_list->elems[i].data;
core_backup_add_entry(backup_list, core_filename, backup_path);
}
if (backup_list->size == 0)
goto error;
string_list_free(dir_list);
return backup_list;
error:
if (dir_list)
string_list_free(dir_list);
if (backup_list)
core_backup_list_free(backup_list);
return NULL;
}
/* Frees specified core backup list */
void core_backup_list_free(core_backup_list_t *backup_list)
{
size_t i;
if (!backup_list)
return;
if (backup_list->entries)
{
for (i = 0; i < backup_list->size; i++)
{
core_backup_list_entry_t *entry = &backup_list->entries[i];
if (!entry)
continue;
if (entry->backup_path)
{
free(entry->backup_path);
entry->backup_path = NULL;
}
}
free(backup_list->entries);
backup_list->entries = NULL;
}
free(backup_list);
}
/***********/
/* Getters */
/***********/
/* Returns number of entries in core backup list */
size_t core_backup_list_size(core_backup_list_t *backup_list)
{
if (!backup_list)
return 0;
return backup_list->size;
}
/* Returns number of entries of specified 'backup mode'
* (manual or automatic) in core backup list */
size_t core_backup_list_get_num_backups(
core_backup_list_t *backup_list,
enum core_backup_mode backup_mode)
{
size_t i;
size_t num_backups = 0;
if (!backup_list || !backup_list->entries)
return 0;
for (i = 0; i < backup_list->size; i++)
{
core_backup_list_entry_t *current_entry = &backup_list->entries[i];
if (current_entry &&
(current_entry->backup_mode == backup_mode))
num_backups++;
}
return num_backups;
}
/* Fetches core backup list entry corresponding
* to the specified entry index.
* Returns false if index is invalid. */
bool core_backup_list_get_index(
core_backup_list_t *backup_list,
size_t idx,
const core_backup_list_entry_t **entry)
{
if (!backup_list || !backup_list->entries || !entry)
return false;
if (idx >= backup_list->size)
return false;
*entry = &backup_list->entries[idx];
if (*entry)
return true;
return false;
}
/* Fetches core backup list entry corresponding
* to the specified core crc checksum value.
* Note that 'manual' and 'auto' backups are
* considered independent - we only compare
* crc values for the specified backup_mode.
* Returns false if entry is not found. */
bool core_backup_list_get_crc(
core_backup_list_t *backup_list,
uint32_t crc, enum core_backup_mode backup_mode,
const core_backup_list_entry_t **entry)
{
size_t i;
if (!backup_list || !backup_list->entries || !entry)
return false;
for (i = 0; i < backup_list->size; i++)
{
core_backup_list_entry_t *current_entry = &backup_list->entries[i];
if (current_entry &&
(current_entry->crc == crc) &&
(current_entry->backup_mode == backup_mode))
{
*entry = current_entry;
return true;
}
}
return false;
}
/* Fetches a string representation of a backup
* list entry timestamp.
* Returns false in the event of an error */
bool core_backup_list_get_entry_timestamp_str(
const core_backup_list_entry_t *entry,
enum core_backup_date_separator_type date_separator,
char *timestamp, size_t len)
{
int n;
const char *format_str = "";
if (!entry || (len < 20))
return false;
/* Get time format string */
switch (date_separator)
{
case CORE_BACKUP_DATE_SEPARATOR_SLASH:
format_str = "%04u/%02u/%02u %02u:%02u:%02u";
break;
case CORE_BACKUP_DATE_SEPARATOR_PERIOD:
format_str = "%04u.%02u.%02u %02u:%02u:%02u";
break;
default:
format_str = "%04u-%02u-%02u %02u:%02u:%02u";
break;
}
n = snprintf(timestamp, len,
format_str,
entry->date.year,
entry->date.month,
entry->date.day,
entry->date.hour,
entry->date.minute,
entry->date.second);
if ((n < 0) || (n >= 32))
n = 0; /* Silence GCC warnings... */
return true;
}
/* Fetches a string representation of a backup
* list entry crc value.
* Returns false in the event of an error */
bool core_backup_list_get_entry_crc_str(
const core_backup_list_entry_t *entry,
char *crc, size_t len)
{
int n;
if (!entry || (len < 9))
return false;
n = snprintf(crc, len, "%08x", entry->crc);
if ((n < 0) || (n >= 32))
n = 0; /* Silence GCC warnings... */
return true;
}
+177
View File
@@ -0,0 +1,177 @@
/* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __CORE_BACKUP_H
#define __CORE_BACKUP_H
#include <retro_common_api.h>
#include <libretro.h>
#include <boolean.h>
RETRO_BEGIN_DECLS
/* Defines the various types of supported core backup
* file. Allows us to handle manual core installs
* (via downloaded/compiled dynamic libraries dropped
* in the 'downloads' folder) using the same task
* interface as 'managed'/archived backups */
enum core_backup_type
{
CORE_BACKUP_TYPE_INVALID = 0,
CORE_BACKUP_TYPE_ARCHIVE,
CORE_BACKUP_TYPE_LIB
};
/* Used to distinguish manual and automatic
* core backups */
enum core_backup_mode
{
CORE_BACKUP_MODE_MANUAL = 0,
CORE_BACKUP_MODE_AUTO
};
/* Note: These must be kept synchronised with
* 'enum menu_timedate_date_separator_type' in
* 'menu_defines.h' */
enum core_backup_date_separator_type
{
CORE_BACKUP_DATE_SEPARATOR_HYPHEN = 0,
CORE_BACKUP_DATE_SEPARATOR_SLASH,
CORE_BACKUP_DATE_SEPARATOR_PERIOD,
CORE_BACKUP_DATE_SEPARATOR_LAST
};
/* Holds all timestamp info for a core backup file */
typedef struct
{
unsigned year;
unsigned month;
unsigned day;
unsigned hour;
unsigned minute;
unsigned second;
} core_backup_list_date_t;
/* Holds all info related to a core backup file */
typedef struct
{
char *backup_path;
core_backup_list_date_t date;
uint32_t crc;
enum core_backup_mode backup_mode;
} core_backup_list_entry_t;
/* Prevent direct access to core_backup_list_t
* members */
typedef struct core_backup_list core_backup_list_t;
/*********************/
/* Utility Functions */
/*********************/
/* Generates a timestamped core backup file path from
* the specified core path. Returns true if successful */
bool core_backup_get_backup_path(
const char *core_path, uint32_t crc, enum core_backup_mode backup_mode,
const char *dir_core_assets, char *backup_path, size_t len);
/* Returns detected type of specified core backup file */
enum core_backup_type core_backup_get_backup_type(const char *backup_path);
/* Fetches crc value of specified core backup file.
* Returns true if successful */
bool core_backup_get_backup_crc(char *backup_path, uint32_t *crc);
/* Fetches core path associated with specified core
* backup file. Returns detected type of backup
* file - CORE_BACKUP_TYPE_INVALID indicates that
* backup file cannot be restored/installed, or
* arguments are otherwise invalid */
enum core_backup_type core_backup_get_core_path(
const char *backup_path, const char *dir_libretro,
char *core_path, size_t len);
/*************************/
/* Backup List Functions */
/*************************/
/**************************************/
/* Initialisation / De-Initialisation */
/**************************************/
/* Creates a new core backup list containing entries
* for all existing backup files.
* Returns a handle to a new core_backup_list_t object
* on success, otherwise returns NULL. */
core_backup_list_t *core_backup_list_init(
const char *core_path, const char *dir_core_assets);
/* Frees specified core backup list */
void core_backup_list_free(core_backup_list_t *backup_list);
/***********/
/* Getters */
/***********/
/* Returns number of entries in core backup list */
size_t core_backup_list_size(core_backup_list_t *backup_list);
/* Returns number of entries of specified 'backup mode'
* (manual or automatic) in core backup list */
size_t core_backup_list_get_num_backups(
core_backup_list_t *backup_list,
enum core_backup_mode backup_mode);
/* Fetches core backup list entry corresponding
* to the specified entry index.
* Returns false if index is invalid. */
bool core_backup_list_get_index(
core_backup_list_t *backup_list,
size_t idx,
const core_backup_list_entry_t **entry);
/* Fetches core backup list entry corresponding
* to the specified core crc checksum value.
* Note that 'manual' and 'auto' backups are
* considered independent - we only compare
* crc values for the specified backup_mode.
* Returns false if entry is not found. */
bool core_backup_list_get_crc(
core_backup_list_t *backup_list,
uint32_t crc, enum core_backup_mode backup_mode,
const core_backup_list_entry_t **entry);
/* Fetches a string representation of a backup
* list entry timestamp.
* Returns false in the event of an error */
bool core_backup_list_get_entry_timestamp_str(
const core_backup_list_entry_t *entry,
enum core_backup_date_separator_type date_separator,
char *timestamp, size_t len);
/* Fetches a string representation of a backup
* list entry crc value.
* Returns false in the event of an error */
bool core_backup_list_get_entry_crc_str(
const core_backup_list_entry_t *entry,
char *crc, size_t len);
RETRO_END_DECLS
#endif
+444 -101
View File
@@ -19,6 +19,7 @@
#include <string/stdstring.h>
#include <file/config_file.h>
#include <file/file_path.h>
#include <streams/file_stream.h>
#include <lists/dir_list.h>
#include <file/archive_file.h>
@@ -45,25 +46,6 @@ enum compare_op
COMPARE_OP_GREATER_EQUAL
};
struct core_info_state
{
#ifdef HAVE_COMPRESSION
const struct string_list *tmp_list;
#endif
const char *tmp_path;
core_info_t *current;
core_info_list_t *curr_list;
};
typedef struct core_info_state core_info_state_t;
static core_info_state_t core_info_st;
static core_info_state_t *coreinfo_get_ptr(void)
{
return &core_info_st;
}
static void core_info_list_resolve_all_extensions(
core_info_list_t *core_info_list)
{
@@ -140,15 +122,17 @@ static void core_info_list_resolve_all_firmware(
snprintf(desc_key, sizeof(desc_key), "firmware%u_desc", c);
snprintf(opt_key, sizeof(opt_key), "firmware%u_opt", c);
if (config_get_string(config, path_key, &tmp) && !string_is_empty(tmp))
if (config_get_string(config, path_key, &tmp))
{
info->firmware[c].path = strdup(tmp);
if (!string_is_empty(tmp))
info->firmware[c].path = strdup(tmp);
free(tmp);
tmp = NULL;
}
if (config_get_string(config, desc_key, &tmp) && !string_is_empty(tmp))
if (config_get_string(config, desc_key, &tmp))
{
info->firmware[c].desc = strdup(tmp);
if (!string_is_empty(tmp))
info->firmware[c].desc = strdup(tmp);
free(tmp);
tmp = NULL;
}
@@ -187,6 +171,7 @@ static void core_info_list_free(core_info_list_t *core_info_list)
free(info->databases);
free(info->notes);
free(info->required_hw_api);
free(info->description);
string_list_free(info->supported_extensions_list);
string_list_free(info->authors_list);
string_list_free(info->note_list);
@@ -203,6 +188,8 @@ static void core_info_list_free(core_info_list_t *core_info_list)
free(info->firmware[j].desc);
}
free(info->firmware);
free(info->core_file_id.str);
}
free(core_info_list->all_ext);
@@ -230,7 +217,7 @@ static config_file_t *core_info_list_iterate(
current_path,
info_path_base_size);
#if defined(RARCH_MOBILE) || (defined(RARCH_CONSOLE) && !defined(PSP) && !defined(_3DS) && !defined(VITA) && !defined(PS2) && !defined(HW_WUP))
#if defined(RARCH_MOBILE) || (defined(RARCH_CONSOLE) && !defined(PSP) && !defined(_3DS) && !defined(VITA) && !defined(HW_WUP))
{
char *substr = strrchr(info_path_base, '_');
if (substr)
@@ -254,6 +241,36 @@ static config_file_t *core_info_list_iterate(
return conf;
}
/* Returned path must be free()'d */
static char *core_info_get_core_lock_file_path(const char *core_path)
{
char *lock_file_path = NULL;
const char *lock_file_ext = file_path_str(FILE_PATH_LOCK_EXTENSION);
size_t len;
if (string_is_empty(core_path))
return NULL;
/* Note: We follow the common 'core_info' trend of
* allocating all strings dynamically... */
/* Get path length */
len = (strlen(core_path) + strlen(lock_file_ext) + 1) * sizeof(char);
/* Allocate string */
lock_file_path = (char*)malloc(len);
if (!lock_file_path)
return NULL;
lock_file_path[0] = '\0';
/* Lock file is just core path + 'lock' extension */
strlcpy(lock_file_path, core_path, len);
strlcat(lock_file_path, lock_file_ext, len);
return lock_file_path;
}
static core_info_list_t *core_info_list_new(const char *path,
const char *libretro_info_dir,
const char *exts,
@@ -315,48 +332,48 @@ static core_info_list_t *core_info_list_new(const char *path,
{
char *tmp = NULL;
if (config_get_string(conf, "display_name", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "display_name", &tmp))
{
core_info[i].display_name = strdup(tmp);
if (!string_is_empty(tmp))
core_info[i].display_name = strdup(tmp);
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "display_version", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "display_version", &tmp))
{
core_info[i].display_version = strdup(tmp);
if (!string_is_empty(tmp))
core_info[i].display_version = strdup(tmp);
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "corename", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "corename", &tmp))
{
core_info[i].core_name = strdup(tmp);
if (!string_is_empty(tmp))
core_info[i].core_name = strdup(tmp);
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "systemname", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "systemname", &tmp))
{
core_info[i].systemname = strdup(tmp);
if (!string_is_empty(tmp))
core_info[i].systemname = strdup(tmp);
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "systemid", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "systemid", &tmp))
{
core_info[i].system_id = strdup(tmp);
if (!string_is_empty(tmp))
core_info[i].system_id = strdup(tmp);
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "manufacturer", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "manufacturer", &tmp))
{
core_info[i].system_manufacturer = strdup(tmp);
if (!string_is_empty(tmp))
core_info[i].system_manufacturer = strdup(tmp);
free(tmp);
tmp = NULL;
}
@@ -367,92 +384,116 @@ static core_info_list_t *core_info_list_new(const char *path,
core_info[i].firmware_count = count;
}
if (config_get_string(conf, "supported_extensions", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "supported_extensions", &tmp))
{
core_info[i].supported_extensions = strdup(tmp);
core_info[i].supported_extensions_list =
string_split(core_info[i].supported_extensions, "|");
if (!string_is_empty(tmp))
{
core_info[i].supported_extensions = strdup(tmp);
core_info[i].supported_extensions_list =
string_split(core_info[i].supported_extensions, "|");
}
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "authors", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "authors", &tmp))
{
core_info[i].authors = strdup(tmp);
core_info[i].authors_list =
string_split(core_info[i].authors, "|");
if (!string_is_empty(tmp))
{
core_info[i].authors = strdup(tmp);
core_info[i].authors_list =
string_split(core_info[i].authors, "|");
}
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "permissions", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "permissions", &tmp))
{
core_info[i].permissions = strdup(tmp);
core_info[i].permissions_list =
string_split(core_info[i].permissions, "|");
if (!string_is_empty(tmp))
{
core_info[i].permissions = strdup(tmp);
core_info[i].permissions_list =
string_split(core_info[i].permissions, "|");
}
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "license", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "license", &tmp))
{
core_info[i].licenses = strdup(tmp);
core_info[i].licenses_list =
string_split(core_info[i].licenses, "|");
if (!string_is_empty(tmp))
{
core_info[i].licenses = strdup(tmp);
core_info[i].licenses_list =
string_split(core_info[i].licenses, "|");
}
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "categories", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "categories", &tmp))
{
core_info[i].categories = strdup(tmp);
core_info[i].categories_list =
string_split(core_info[i].categories, "|");
if (!string_is_empty(tmp))
{
core_info[i].categories = strdup(tmp);
core_info[i].categories_list =
string_split(core_info[i].categories, "|");
}
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "database", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "database", &tmp))
{
core_info[i].databases = strdup(tmp);
core_info[i].databases_list =
string_split(core_info[i].databases, "|");
if (!string_is_empty(tmp))
{
core_info[i].databases = strdup(tmp);
core_info[i].databases_list =
string_split(core_info[i].databases, "|");
}
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "notes", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "notes", &tmp))
{
core_info[i].notes = strdup(tmp);
core_info[i].note_list = string_split(core_info[i].notes, "|");
if (!string_is_empty(tmp))
{
core_info[i].notes = strdup(tmp);
core_info[i].note_list = string_split(core_info[i].notes, "|");
}
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "required_hw_api", &tmp)
&& !string_is_empty(tmp))
if (config_get_string(conf, "required_hw_api", &tmp))
{
core_info[i].required_hw_api = strdup(tmp);
core_info[i].required_hw_api_list = string_split(core_info[i].required_hw_api, "|");
if (!string_is_empty(tmp))
{
core_info[i].required_hw_api = strdup(tmp);
core_info[i].required_hw_api_list = string_split(core_info[i].required_hw_api, "|");
}
free(tmp);
tmp = NULL;
}
if (config_get_string(conf, "description", &tmp))
{
if (!string_is_empty(tmp))
core_info[i].description = strdup(tmp);
free(tmp);
tmp = NULL;
}
if (tmp)
free(tmp);
tmp = NULL;
@@ -466,17 +507,56 @@ static core_info_list_t *core_info_list_new(const char *path,
if (config_get_bool(conf, "database_match_archive_member",
&tmp_bool))
core_info[i].database_match_archive_member = tmp_bool;
if (config_get_bool(conf, "is_experimental",
&tmp_bool))
core_info[i].is_experimental = tmp_bool;
}
core_info[i].config_data = conf;
}
if (!string_is_empty(base_path))
{
const char *core_filename = path_basename(base_path);
/* Cache core path */
core_info[i].path = strdup(base_path);
if (!core_info[i].display_name)
core_info[i].display_name =
strdup(path_basename(core_info[i].path));
/* Cache core file 'id'
* > Filename without extension or platform-specific suffix */
if (!string_is_empty(core_filename))
{
char *core_file_id = strdup(core_filename);
path_remove_extension(core_file_id);
if (!string_is_empty(core_file_id))
{
#if defined(RARCH_MOBILE) || (defined(RARCH_CONSOLE) && !defined(PSP) && !defined(_3DS) && !defined(VITA) && !defined(HW_WUP))
char *last_underscore = strrchr(core_file_id, '_');
if (last_underscore)
*last_underscore = '\0';
#endif
core_info[i].core_file_id.str = core_file_id;
core_info[i].core_file_id.len = strlen(core_file_id);
core_file_id = NULL;
}
if (core_file_id)
{
free(core_file_id);
core_file_id = NULL;
}
/* Get fallback display name, if required */
if (!core_info[i].display_name)
core_info[i].display_name = strdup(core_filename);
}
}
/* Get core lock status */
core_info[i].is_locked = core_info_get_core_lock(core_info[i].path, false);
}
if (core_info_list)
@@ -497,7 +577,13 @@ bool core_info_list_get_info(core_info_list_t *core_info_list,
core_info_t *out_info, const char *path)
{
size_t i;
if (!core_info_list || !out_info)
const char *core_filename = NULL;
if (!core_info_list || !out_info || string_is_empty(path))
return false;
core_filename = path_basename(path);
if (string_is_empty(core_filename))
return false;
memset(out_info, 0, sizeof(*out_info));
@@ -506,8 +592,10 @@ bool core_info_list_get_info(core_info_list_t *core_info_list,
{
const core_info_t *info = &core_info_list->list[i];
if (string_is_equal(path_basename(info->path),
path_basename(path)))
if (!info || (info->core_file_id.len == 0))
continue;
if (!strncmp(info->core_file_id.str, core_filename, info->core_file_id.len))
{
*out_info = *info;
return true;
@@ -573,15 +661,23 @@ static core_info_t *core_info_find_internal(
const char *core)
{
size_t i;
const char *core_path_basename = path_basename(core);
const char *core_filename = NULL;
if (!list || string_is_empty(core))
return NULL;
core_filename = path_basename(core);
if (string_is_empty(core_filename))
return NULL;
for (i = 0; i < list->count; i++)
{
core_info_t *info = core_info_get(list, i);
if (!info || !info->path)
if (!info || (info->core_file_id.len == 0))
continue;
if (string_is_equal(path_basename(info->path), core_path_basename))
if (!strncmp(info->core_file_id.str, core_filename, info->core_file_id.len))
return info;
}
@@ -630,9 +726,8 @@ static bool core_info_list_update_missing_firmware_internal(
return true;
}
void core_info_free_current_core(void)
void core_info_free_current_core(core_info_state_t *p_coreinfo)
{
core_info_state_t *p_coreinfo = coreinfo_get_ptr();
if (p_coreinfo->current)
free(p_coreinfo->current);
p_coreinfo->current = NULL;
@@ -698,10 +793,11 @@ bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info,
set_missing_bios);
}
bool core_info_load(core_info_ctx_find_t *info)
bool core_info_load(
core_info_ctx_find_t *info,
core_info_state_t *p_coreinfo)
{
core_info_t *core_info = NULL;
core_info_state_t *p_coreinfo = coreinfo_get_ptr();
if (!info)
return false;
@@ -721,14 +817,18 @@ bool core_info_load(core_info_ctx_find_t *info)
return true;
}
bool core_info_find(core_info_ctx_find_t *info, const char *core_path)
bool core_info_find(core_info_ctx_find_t *info)
{
core_info_state_t *p_coreinfo = coreinfo_get_ptr();
if (!info || !p_coreinfo->curr_list)
return false;
info->inf = core_info_find_internal(p_coreinfo->curr_list, core_path);
info->inf = core_info_find_internal(p_coreinfo->curr_list, info->path);
if (!info->inf)
return false;
return true;
}
@@ -946,22 +1046,30 @@ bool core_info_list_get_display_name(core_info_list_t *core_info_list,
const char *path, char *s, size_t len)
{
size_t i;
const char *core_filename = NULL;
if (!core_info_list)
if (!core_info_list || string_is_empty(path))
return false;
core_filename = path_basename(path);
if (string_is_empty(core_filename))
return false;
for (i = 0; i < core_info_list->count; i++)
{
const core_info_t *info = &core_info_list->list[i];
if (!string_is_equal(path_basename(info->path), path_basename(path)))
if (!info || (info->core_file_id.len == 0))
continue;
if (!info->display_name)
continue;
if (!strncmp(info->core_file_id.str, core_filename, info->core_file_id.len))
{
if (string_is_empty(info->display_name))
break;
strlcpy(s, info->display_name, len);
return true;
strlcpy(s, info->display_name, len);
return true;
}
}
return false;
@@ -985,6 +1093,100 @@ bool core_info_get_display_name(const char *path, char *s, size_t len)
return true;
}
/* Returns core_info parameters required for
* core updater tasks, read from specified file.
* Returned core_updater_info_t object must be
* freed using core_info_free_core_updater_info().
* Returns NULL if 'path' is invalid. */
core_updater_info_t *core_info_get_core_updater_info(const char *path)
{
char *tmp_str = NULL;
bool tmp_bool = false;
core_updater_info_t *info = NULL;
config_file_t *conf = NULL;
if (string_is_empty(path))
return NULL;
/* Read config file */
conf = config_file_new_from_path_to_string(path);
if (!conf)
return NULL;
/* Create info struct */
info = (core_updater_info_t*)calloc(1, sizeof(*info));
if (!info)
return NULL;
/* Fetch required parameters */
/* > is_experimental */
info->is_experimental = false;
if (config_get_bool(conf, "is_experimental", &tmp_bool))
info->is_experimental = tmp_bool;
/* > display_name */
info->display_name = NULL;
if (config_get_string(conf, "display_name", &tmp_str))
{
if (!string_is_empty(tmp_str))
info->display_name = tmp_str;
else
free(tmp_str);
tmp_str = NULL;
}
/* > description */
info->description = NULL;
if (config_get_string(conf, "description", &tmp_str))
{
if (!string_is_empty(tmp_str))
info->description = tmp_str;
else
free(tmp_str);
tmp_str = NULL;
}
/* > licenses */
info->licenses = NULL;
if (config_get_string(conf, "license", &tmp_str))
{
if (!string_is_empty(tmp_str))
info->licenses = tmp_str;
else
free(tmp_str);
tmp_str = NULL;
}
/* Clean up */
config_file_free(conf);
return info;
}
void core_info_free_core_updater_info(core_updater_info_t *info)
{
if (!info)
return;
if (info->display_name)
free(info->display_name);
if (info->description)
free(info->description);
if (info->licenses)
free(info->licenses);
free(info);
info = NULL;
}
static int core_info_qsort_func_path(const core_info_t *a,
const core_info_t *b)
{
@@ -1337,3 +1539,144 @@ bool core_info_hw_api_supported(core_info_t *info)
return true;
#endif
}
/* Sets 'locked' status of specified core
* > Returns true if successful
* > Like all functions that access the cached
* core info list this is *not* thread safe */
bool core_info_set_core_lock(const char *core_path, bool lock)
{
char *lock_file_path = NULL;
RFILE *lock_file = NULL;
bool lock_file_exists = false;
core_info_ctx_find_t core_info;
if (string_is_empty(core_path))
goto error;
/* Search for specified core */
core_info.inf = NULL;
core_info.path = core_path;
if (!core_info_find(&core_info))
goto error;
/* Get associated lock file path */
lock_file_path = core_info_get_core_lock_file_path(core_info.inf->path);
if (string_is_empty(lock_file_path))
goto error;
/* Check whether lock file exists */
lock_file_exists = path_is_valid(lock_file_path);
/* Create or delete lock file, as required */
if (lock && !lock_file_exists)
{
lock_file = filestream_open(
lock_file_path,
RETRO_VFS_FILE_ACCESS_WRITE,
RETRO_VFS_FILE_ACCESS_HINT_NONE);
if (!lock_file)
goto error;
/* We have to write something - just output
* a single character */
if (filestream_putc(lock_file, 0) != 0)
goto error;
filestream_close(lock_file);
lock_file = NULL;
}
else if (!lock && lock_file_exists)
if (filestream_delete(lock_file_path) != 0)
goto error;
/* Clean up */
free(lock_file_path);
lock_file_path = NULL;
/* File operations were successful - update
* core info entry */
core_info.inf->is_locked = lock;
return true;
error:
if (lock_file_path)
{
free(lock_file_path);
lock_file_path = NULL;
}
if (lock_file)
{
filestream_close(lock_file);
lock_file = NULL;
}
return false;
}
/* Fetches 'locked' status of specified core
* > If 'validate_path' is 'true', will search
* cached core info list for a corresponding
* 'sanitised' core file path. This is *not*
* thread safe
* > If 'validate_path' is 'false', performs a
* direct filesystem check. This *is* thread
* safe, but validity of specified core path
* must be checked externally */
bool core_info_get_core_lock(const char *core_path, bool validate_path)
{
const char *core_file_path = NULL;
char *lock_file_path = NULL;
bool is_locked = false;
core_info_ctx_find_t core_info;
if (string_is_empty(core_path))
goto end;
/* Check whether core path is to be validated */
if (validate_path)
{
core_info.inf = NULL;
core_info.path = core_path;
if (core_info_find(&core_info))
core_file_path = core_info.inf->path;
}
else
core_file_path = core_path;
/* A core cannot be locked if it does not exist... */
if (string_is_empty(core_file_path) ||
!path_is_valid(core_file_path))
goto end;
/* Get lock file path */
lock_file_path = core_info_get_core_lock_file_path(core_file_path);
if (string_is_empty(lock_file_path))
goto end;
/* Check whether lock file exists */
is_locked = path_is_valid(lock_file_path);
/* If core path has been validated (and a
* core info object is available), ensure
* that core info 'is_locked' field is
* up to date */
if (validate_path && core_info.inf)
core_info.inf->is_locked = is_locked;
end:
if (lock_file_path)
{
free(lock_file_path);
lock_file_path = NULL;
}
return is_locked;
}
+74 -3
View File
@@ -35,10 +35,29 @@ typedef struct
bool optional;
} core_info_firmware_t;
/* Simple container/convenience struct for
* holding the 'id' of a core file
* > 'id' is the filename without extension or
* platform-specific suffix
* > 'id' is used for core info searches - enables
* matching regardless of core file base path,
* and is platform-independent (e.g. an Android
* core file will be correctly identified on Linux)
* > 'len' is used to cache the length of 'str', for
* improved performance when performing string
* comparisons */
typedef struct
{
char *str;
size_t len;
} core_file_id_t;
typedef struct
{
bool supports_no_game;
bool database_match_archive_member;
bool is_experimental;
bool is_locked;
size_t firmware_count;
char *path;
void *config_data;
@@ -56,6 +75,7 @@ typedef struct
char *databases;
char *notes;
char *required_hw_api;
char *description;
struct string_list *categories_list;
struct string_list *databases_list;
struct string_list *note_list;
@@ -65,9 +85,20 @@ typedef struct
struct string_list *licenses_list;
struct string_list *required_hw_api_list;
core_info_firmware_t *firmware;
core_file_id_t core_file_id;
void *userdata;
} core_info_t;
/* A subset of core_info parameters required for
* core updater tasks */
typedef struct
{
bool is_experimental;
char *display_name;
char *description;
char *licenses;
} core_updater_info_t;
typedef struct
{
core_info_t *list;
@@ -98,6 +129,18 @@ enum core_info_list_qsort_type
CORE_INFO_LIST_SORT_SYSTEM_NAME
};
struct core_info_state
{
#ifdef HAVE_COMPRESSION
const struct string_list *tmp_list;
#endif
const char *tmp_path;
core_info_t *current;
core_info_list_t *curr_list;
};
typedef struct core_info_state core_info_state_t;
size_t core_info_list_num_info_files(core_info_list_t *list);
/* Non-reentrant, does not allocate. Returns pointer to internal state. */
@@ -109,6 +152,14 @@ bool core_info_list_get_display_name(core_info_list_t *list,
bool core_info_get_display_name(const char *path, char *s, size_t len);
/* Returns core_info parameters required for
* core updater tasks, read from specified file.
* Returned core_updater_info_t object must be
* freed using core_info_free_core_updater_info().
* Returns NULL if 'path' is invalid. */
core_updater_info_t *core_info_get_core_updater_info(const char *path);
void core_info_free_core_updater_info(core_updater_info_t *info);
void core_info_get_name(const char *path, char *s, size_t len,
const char *path_info, const char *dir_cores,
const char *exts, bool show_hidden_files,
@@ -116,7 +167,7 @@ void core_info_get_name(const char *path, char *s, size_t len,
core_info_t *core_info_get(core_info_list_t *list, size_t i);
void core_info_free_current_core(void);
void core_info_free_current_core(core_info_state_t *p_coreinfo);
bool core_info_init_current_core(void);
@@ -132,9 +183,11 @@ bool core_info_get_list(core_info_list_t **core);
bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info,
bool *set_missing_bios);
bool core_info_find(core_info_ctx_find_t *info, const char *name);
bool core_info_find(core_info_ctx_find_t *info);
bool core_info_load(core_info_ctx_find_t *info);
bool core_info_load(
core_info_ctx_find_t *info,
core_info_state_t *p_coreinfo);
bool core_info_database_supports_content_path(const char *database_path, const char *path);
@@ -149,6 +202,24 @@ bool core_info_list_get_info(core_info_list_t *core_info_list,
bool core_info_hw_api_supported(core_info_t *info);
/* Sets 'locked' status of specified core
* > Returns true if successful
* > Like all functions that access the cached
* core info list this is *not* thread safe */
bool core_info_set_core_lock(const char *core_path, bool lock);
/* Fetches 'locked' status of specified core
* > If 'validate_path' is 'true', will search
* cached core info list for a corresponding
* 'sanitised' core file path. This is *not*
* thread safe
* > If 'validate_path' is 'false', performs a
* direct filesystem check. This *is* thread
* safe, but validity of specified core path
* must be checked externally */
bool core_info_get_core_lock(const char *core_path, bool validate_path);
core_info_state_t *coreinfo_get_ptr(void);
RETRO_END_DECLS
#endif /* CORE_INFO_H_ */
+105 -21
View File
@@ -82,6 +82,18 @@ static void core_updater_list_free_entry(core_updater_list_entry_t *entry)
free(entry->display_name);
entry->display_name = NULL;
}
if (entry->description)
{
free(entry->description);
entry->description = NULL;
}
if (entry->licenses_list)
{
string_list_free(entry->licenses_list);
entry->licenses_list = NULL;
}
}
/* Creates a new, empty core updater list.
@@ -410,13 +422,11 @@ static bool core_updater_list_set_paths(
char remote_core_path[PATH_MAX_LENGTH];
char local_core_path[PATH_MAX_LENGTH];
char local_info_path[PATH_MAX_LENGTH];
char display_name[255];
bool is_archive;
remote_core_path[0] = '\0';
local_core_path[0] = '\0';
local_info_path[0] = '\0';
display_name[0] = '\0';
if (!entry || string_is_empty(filename_str))
return false;
@@ -499,10 +509,8 @@ static bool core_updater_list_set_paths(
last_underscore = (char*)strrchr(local_info_path, '_');
if (!string_is_empty(last_underscore))
{
if (string_is_not_equal_fast(last_underscore, "_libretro", 9))
if (!string_is_equal(last_underscore, "_libretro"))
*last_underscore = '\0';
}
/* > Add proper file extension */
strlcat(
@@ -518,29 +526,94 @@ static bool core_updater_list_set_paths(
entry->local_info_path = strdup(local_info_path);
/* display_name
* > Note: It's a bit rubbish that we have to
* read the actual core info files here...
* Would be better to cache this globally
* (at present, we only cache info for
* *installed* cores...) */
if (path_is_valid(local_info_path))
if (!core_info_get_display_name(
local_info_path, display_name, sizeof(display_name)))
display_name[0] = '\0';
return true;
}
/* > If info file does not exist, just use
* core filename */
if (string_is_empty(display_name))
strlcpy(display_name, filename_str, sizeof(display_name));
/* Reads info file associated with core and
* adds relevant information to updater list
* entry */
static bool core_updater_list_set_core_info(
core_updater_list_entry_t *entry,
const char *local_info_path,
const char *filename_str)
{
core_updater_info_t *core_info = NULL;
if (!entry ||
string_is_empty(local_info_path) ||
string_is_empty(filename_str))
return false;
/* Clear any existing core info */
if (entry->display_name)
{
free(entry->display_name);
entry->display_name = NULL;
}
entry->display_name = strdup(display_name);
if (entry->description)
{
free(entry->description);
entry->description = NULL;
}
if (entry->licenses_list)
{
/* Note: We can safely leave this as NULL if
* the core info file is invalid */
string_list_free(entry->licenses_list);
entry->licenses_list = NULL;
}
entry->is_experimental = false;
/* Read core info file
* > Note: It's a bit rubbish that we have to
* read the actual core info files here...
* Would be better to cache this globally
* (at present, we only cache info for
* *installed* cores...) */
core_info = core_info_get_core_updater_info(local_info_path);
if (core_info)
{
/* display_name + is_experimental */
if (!string_is_empty(core_info->display_name))
{
entry->display_name = strdup(core_info->display_name);
entry->is_experimental = core_info->is_experimental;
}
else
{
/* If display name is blank, use core filename and
* assume core is experimental (i.e. all 'fit for consumption'
* cores must have a valid/complete core info file) */
entry->display_name = strdup(filename_str);
entry->is_experimental = true;
}
/* description */
if (!string_is_empty(core_info->description))
entry->description = strdup(core_info->description);
else
entry->description = strdup("");
/* licenses_list */
if (!string_is_empty(core_info->licenses))
entry->licenses_list = string_split(core_info->licenses, "|");
/* Clean up */
core_info_free_core_updater_info(core_info);
}
else
{
/* If info file is missing, use core filename and
* assume core is experimental (i.e. all 'fit for consumption'
* cores must have a valid/complete core info file) */
entry->display_name = strdup(filename_str);
entry->is_experimental = true;
entry->description = strdup("");
}
return true;
}
@@ -576,10 +649,15 @@ static bool core_updater_list_push_entry(
list_entry->remote_core_path = entry->remote_core_path;
list_entry->local_core_path = entry->local_core_path;
list_entry->local_info_path = entry->local_info_path;
/* Assign core info */
list_entry->display_name = entry->display_name;
list_entry->description = entry->description;
list_entry->licenses_list = entry->licenses_list;
list_entry->is_experimental = entry->is_experimental;
/* Copy crc */
list_entry->crc = entry->crc;
list_entry->crc = entry->crc;
/* Copy date */
memcpy(&list_entry->date, &entry->date, sizeof(core_updater_list_date_t));
@@ -644,6 +722,12 @@ static void core_updater_list_add_entry(
filename_str))
goto error;
if (!core_updater_list_set_core_info(
&entry,
entry.local_info_path,
filename_str))
goto error;
/* Add entry to list */
if (!core_updater_list_push_entry(core_list, &entry))
goto error;
+5
View File
@@ -26,6 +26,8 @@
#include <retro_common_api.h>
#include <libretro.h>
#include <lists/string_list.h>
#include <boolean.h>
RETRO_BEGIN_DECLS
@@ -52,6 +54,9 @@ typedef struct
char *local_core_path;
char *local_info_path;
char *display_name;
char *description;
struct string_list *licenses_list;
bool is_experimental;
uint32_t crc;
core_updater_list_date_t date;
} core_updater_list_entry_t;
+1 -1
View File
@@ -144,7 +144,7 @@ void libretro_dummy_retro_get_system_av_info(
refresh_rate = 60.0;
info->timing.fps = refresh_rate;
info->timing.sample_rate = 30000.0;
info->timing.sample_rate = 48000.0;
info->geometry.base_width = frame_buf_width;
info->geometry.base_height = frame_buf_height;
-6
View File
@@ -126,12 +126,6 @@ else ifneq (,$(findstring win,$(platform)))
endif
endif
ifeq ($(HAVE_BIGENDIAN),1)
CPUOPTS += -DHAVE_BIGENDIAN=1 -DMSB_FIRST
else
CPUOPTS += -DHAVE_BIGENDIAN=0
endif
ifeq ($(HAVE_SSA), 1)
LIBS += $(shell pkg-config libass --libs)
DEFINES += -DHAVE_SSA
+60 -41
View File
@@ -692,38 +692,42 @@ void CORE_PREFIX(retro_run)(void)
frames[0] = tmp;
}
while (!decode_thread_dead && min_pts > frames[1].pts)
{
int64_t pts = 0;
if (!decode_thread_dead)
video_buffer_wait_for_finished_slot(video_buffer);
if (!decode_thread_dead)
{
uint32_t *data = video_frame_temp_buffer;
video_decoder_context_t *ctx = NULL;
video_buffer_get_finished_slot(video_buffer, &ctx);
pts = ctx->pts;
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
if (use_gl)
if (use_gl)
{
float mix_factor;
while (!decode_thread_dead && min_pts > frames[1].pts)
{
int64_t pts = 0;
if (!decode_thread_dead)
video_buffer_wait_for_finished_slot(video_buffer);
if (!decode_thread_dead)
{
unsigned y;
const uint8_t *src;
int stride, width;
uint32_t *data = video_frame_temp_buffer;
video_decoder_context_t *ctx = NULL;
video_buffer_get_finished_slot(video_buffer, &ctx);
pts = ctx->pts;
#ifndef HAVE_OPENGLES
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, frames[1].pbo);
#ifdef __MACH__
data = (uint32_t*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
data = (uint32_t*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
#else
data = (uint32_t*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER,
data = (uint32_t*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER,
0, media.width * media.height * sizeof(uint32_t), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
#endif
#endif
const uint8_t *src = ctx->target->data[0];
int stride = ctx->target->linesize[0];
int width = media.width * sizeof(uint32_t);
for (unsigned y = 0; y < media.height; y++, src += stride, data += width/4)
src = ctx->target->data[0];
stride = ctx->target->linesize[0];
width = media.width * sizeof(uint32_t);
for (y = 0; y < media.height; y++, src += stride, data += width/4)
memcpy(data, src, width);
#ifndef HAVE_OPENGLES
@@ -741,28 +745,13 @@ void CORE_PREFIX(retro_run)(void)
#ifndef HAVE_OPENGLES
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
#endif
video_buffer_open_slot(video_buffer, ctx);
}
else
#endif
{
const uint8_t *src = ctx->target->data[0];
int stride = ctx->target->linesize[0];
size_t width = media.width * sizeof(uint32_t);
for (unsigned y = 0; y < media.height; y++, src += stride, data += width/4)
memcpy(data, src, width);
dupe = false;
}
video_buffer_open_slot(video_buffer, ctx);
frames[1].pts = av_q2d(fctx->streams[video_stream_index]->time_base) * pts;
}
frames[1].pts = av_q2d(fctx->streams[video_stream_index]->time_base) * pts;
}
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
if (use_gl)
{
float mix_factor = (min_pts - frames[0].pts) / (frames[1].pts - frames[0].pts);
mix_factor = (min_pts - frames[0].pts) / (frames[1].pts - frames[0].pts);
if (!temporal_interpolation)
mix_factor = 1.0f;
@@ -804,6 +793,36 @@ void CORE_PREFIX(retro_run)(void)
else
#endif
{
while (!decode_thread_dead && min_pts > frames[1].pts)
{
int64_t pts = 0;
if (!decode_thread_dead)
video_buffer_wait_for_finished_slot(video_buffer);
if (!decode_thread_dead)
{
unsigned y;
const uint8_t *src;
int stride, width;
uint32_t *data = video_frame_temp_buffer;
video_decoder_context_t *ctx = NULL;
video_buffer_get_finished_slot(video_buffer, &ctx);
pts = ctx->pts;
src = ctx->target->data[0];
stride = ctx->target->linesize[0];
width = media.width * sizeof(uint32_t);
for (y = 0; y < media.height; y++, src += stride, data += width/4)
memcpy(data, src, width);
dupe = false;
video_buffer_open_slot(video_buffer, ctx);
}
frames[1].pts = av_q2d(fctx->streams[video_stream_index]->time_base) * pts;
}
CORE_PREFIX(video_cb)(dupe ? NULL : video_frame_temp_buffer,
media.width, media.height, media.width * sizeof(uint32_t));
}
+18 -9
View File
@@ -37,25 +37,32 @@ void ctr_linear_free_pages(u32 pages);
void ctr_free_pages(u32 pages)
{
u32 linear_free_pages;
u32 stack_free, stack_usage, stack_free_pages;
if(!pages)
return;
u32 linear_free_pages = ctr_get_linear_free() >> 12;
linear_free_pages = ctr_get_linear_free() >> 12;
if((ctr_get_linear_unused() >> 12) > pages + 0x100)
if ((ctr_get_linear_unused() >> 12) > pages + 0x100)
return ctr_linear_free_pages(pages);
#if 0
if(linear_free_pages > pages + 0x400)
if (linear_free_pages > pages + 0x400)
return ctr_linear_free_pages(pages);
#endif
u32 stack_free = ctr_get_stack_free();
u32 stack_usage = __stacksize__ > stack_free? __stacksize__ - stack_free: 0;
stack_free = ctr_get_stack_free();
stack_usage = __stacksize__ > stack_free
? __stacksize__ - stack_free
: 0;
stack_free = stack_free > __stack_size_extra ? __stack_size_extra : stack_free;
stack_free = stack_free > __stack_size_extra
? __stack_size_extra
: stack_free;
u32 stack_free_pages = stack_free >> 12;
stack_free_pages = stack_free >> 12;
if(linear_free_pages + (stack_free_pages - (stack_usage >> 12)) > pages)
{
@@ -83,7 +90,8 @@ void ctr_free_pages(u32 pages)
__stacksize__ -= stack_free_pages << 12;
#if 0
printf("s:0x%08X-->0x%08X(-0x%08X) \n", stack_free,
stack_free - (stack_free_pages << 12), stack_free_pages << 12);
stack_free - (stack_free_pages << 12),
stack_free_pages << 12);
DEBUG_HOLD();
#endif
}
@@ -111,11 +119,12 @@ void* _sbrk_r(struct _reent *ptr, ptrdiff_t incr)
{
static u32 sbrk_top = 0;
u32 tmp;
int diff;
if (!sbrk_top)
sbrk_top = __heapBase;
int diff = ((sbrk_top + incr + 0xFFF) & ~0xFFF)
diff = ((sbrk_top + incr + 0xFFF) & ~0xFFF)
- (__heapBase + __heap_size);
if (diff > 0)
+154 -111
View File
@@ -15,13 +15,53 @@
#define SVC_ACL_MASK(svc_id) (0x1 << ((svc_id) & 0x1F))
#define THREAD_PAGE_ACL_OFFSET 0xF38
u32 __ctr_svchax = 0;
u32 __ctr_svchax = 0;
u32 __ctr_svchax_srv = 0;
extern void* __service_ptr;
typedef u32(*backdoor_fn)(u32 arg0, u32 arg1);
typedef struct
{
Handle started_event;
Handle lock;
volatile u32 target_kaddr;
volatile u32 target_val;
} mch2_thread_args_t;
typedef struct
{
u32* stack_top;
Handle handle;
bool keep;
mch2_thread_args_t args;
} mch2_thread_t;
typedef struct
{
u32 old_cpu_time_limit;
bool isNew3DS;
u32 kernel_fcram_mapping_offset;
Handle arbiter;
volatile u32 alloc_address;
volatile u32 alloc_size;
u8* flush_buffer;
Handle dummy_threads_lock;
Handle target_threads_lock;
Handle main_thread_lock;
u32* thread_page_va;
u32 thread_page_kva;
u32 threads_limit;
Handle alloc_thread;
Handle poll_thread;
mch2_thread_t threads[MCH2_THREAD_COUNT_MAX];
} mch2_vars_t;
__attribute((naked))
static u32 svc_7b(backdoor_fn entry_fn, ...) /* can pass up to two arguments to entry_fn(...) */
{
@@ -46,7 +86,7 @@ static u32 svc_7b(backdoor_fn entry_fn, ...) /* can pass up to two arguments to
static void k_enable_all_svcs(u32 isNew3DS)
{
u32* thread_ACL = *(*(u32***)CURRENT_KTHREAD + 0x22) - 0x6;
u32* thread_ACL = *(*(u32***)CURRENT_KTHREAD + 0x22) - 0x6;
u32* process_ACL = *(u32**)CURRENT_KPROCESS + (isNew3DS ? 0x24 : 0x22);
memset(thread_ACL, 0xFF, 0x10);
@@ -88,45 +128,6 @@ static u32 get_thread_page(void)
return 0;
}
typedef struct
{
Handle started_event;
Handle lock;
volatile u32 target_kaddr;
volatile u32 target_val;
} mch2_thread_args_t;
typedef struct
{
u32* stack_top;
Handle handle;
bool keep;
mch2_thread_args_t args;
} mch2_thread_t;
typedef struct
{
u32 old_cpu_time_limit;
bool isNew3DS;
u32 kernel_fcram_mapping_offset;
Handle arbiter;
volatile u32 alloc_address;
volatile u32 alloc_size;
u8* flush_buffer;
Handle dummy_threads_lock;
Handle target_threads_lock;
Handle main_thread_lock;
u32* thread_page_va;
u32 thread_page_kva;
u32 threads_limit;
Handle alloc_thread;
Handle poll_thread;
mch2_thread_t threads[MCH2_THREAD_COUNT_MAX];
} mch2_vars_t;
static void alloc_thread_entry(mch2_vars_t* mch2)
{
u32 tmp;
@@ -162,7 +163,7 @@ static u32 get_first_free_basemem_page(bool isNew3DS)
{
s64 v1;
int memused_base_linear; /* guessed */
int memused_base = osGetMemRegionUsed(MEMREGION_BASE);
int memused_base = osGetMemRegionUsed(MEMREGION_BASE);
svcGetSystemInfo(&v1, 2, 0);
memused_base_linear = 0x6C000 + v1 +
@@ -197,13 +198,25 @@ static void do_memchunkhax2(void)
{
static u8 flush_buffer[0x8000];
static u8 thread_stacks[MCH2_THREAD_STACKS_SIZE];
extern u32 __heapBase;
extern u32 __heap_size;
int i;
u32 tmp;
mch2_vars_t mch2 = {0};
u32 linear_buffer;
u32 linear_address;
u32 dst_memchunk;
u32 mem_free;
u32 fragmented_size;
u32* mapped_page;
volatile u32 *thread_ACL;
u32 alloc_address_kaddr;
u32 fragmented_address = 0;
u32 linear_size = 0xF000;
u32 skip_pages = 2;
mch2_vars_t mch2 = {0};
mch2.flush_buffer = flush_buffer;
mch2.threads_limit = get_threads_limit();
mch2.flush_buffer = flush_buffer;
mch2.threads_limit = get_threads_limit();
mch2.kernel_fcram_mapping_offset = (osGetKernelVersion() > SYSTEM_VERSION(2, 40, 0)) ? 0xC0000000 : 0xD0000000;
for (i = 0; i < MCH2_THREAD_COUNT_MAX; i++)
@@ -215,8 +228,10 @@ static void do_memchunkhax2(void)
for (i = 0; i < mch2.threads_limit; i++)
{
svcCreateThread(&mch2.threads[i].handle, (ThreadFunc)check_tls_thread_entry, (u32)&mch2.threads[i].keep,
mch2.threads[i].stack_top, 0x18, 0);
svcCreateThread(&mch2.threads[i].handle,
(ThreadFunc)check_tls_thread_entry,
(u32)&mch2.threads[i].keep,
mch2.threads[i].stack_top, 0x18, 0);
svcWaitSynchronization(mch2.threads[i].handle, U64_MAX);
}
@@ -229,61 +244,70 @@ static void do_memchunkhax2(void)
for (i = 0; i < mch2.threads_limit; i++)
if (!mch2.threads[i].keep)
svcCreateThread(&mch2.threads[i].handle, (ThreadFunc)dummy_thread_entry, mch2.dummy_threads_lock,
mch2.threads[i].stack_top, 0x3F - i, 0);
svcCreateThread(&mch2.threads[i].handle,
(ThreadFunc)dummy_thread_entry,
mch2.dummy_threads_lock,
mch2.threads[i].stack_top, 0x3F - i, 0);
svcSignalEvent(mch2.dummy_threads_lock);
for (i = mch2.threads_limit - 1; i >= 0; i--)
{
if (!mch2.threads[i].keep)
{
svcWaitSynchronization(mch2.threads[i].handle, U64_MAX);
svcCloseHandle(mch2.threads[i].handle);
mch2.threads[i].handle = 0;
}
}
svcCloseHandle(mch2.dummy_threads_lock);
u32 fragmented_address = 0;
mch2.arbiter = __sync_get_arbiter();
mch2.arbiter = __sync_get_arbiter();
svcControlMemory(&linear_buffer, 0, 0, 0x1000,
MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
u32 linear_buffer;
svcControlMemory(&linear_buffer, 0, 0, 0x1000, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
mch2.alloc_size = ((((linear_size - (skip_pages << 12))
+ 0x1000) >> 13) << 12);
u32 linear_size = 0xF000;
u32 skip_pages = 2;
mch2.alloc_size = ((((linear_size - (skip_pages << 12)) + 0x1000) >> 13) << 12);
u32 mem_free = osGetMemRegionFree(MEMREGION_APPLICATION);
mem_free = osGetMemRegionFree(MEMREGION_APPLICATION);
fragmented_size = mem_free - linear_size;
u32 fragmented_size = mem_free - linear_size;
extern u32 __heapBase;
extern u32 __heap_size;
fragmented_address = __heapBase + __heap_size;
u32 linear_address;
mch2.alloc_address = fragmented_address + fragmented_size;
fragmented_address = __heapBase + __heap_size;
mch2.alloc_address = fragmented_address + fragmented_size;
svcControlMemory(&linear_address, 0x0, 0x0, linear_size, MEMOP_ALLOC_LINEAR,
MEMPERM_READ | MEMPERM_WRITE);
svcControlMemory(&linear_address,
0x0, 0x0, linear_size, MEMOP_ALLOC_LINEAR,
MEMPERM_READ | MEMPERM_WRITE);
if (fragmented_size)
svcControlMemory(&tmp, (u32)fragmented_address, 0x0, fragmented_size, MEMOP_ALLOC,
MEMPERM_READ | MEMPERM_WRITE);
svcControlMemory(&tmp,
(u32)fragmented_address, 0x0, fragmented_size, MEMOP_ALLOC,
MEMPERM_READ | MEMPERM_WRITE);
if (skip_pages)
svcControlMemory(&tmp, (u32)linear_address, 0x0, (skip_pages << 12), MEMOP_FREE, MEMPERM_DONTCARE);
svcControlMemory(&tmp,
(u32)linear_address, 0x0, (skip_pages << 12), MEMOP_FREE,
MEMPERM_DONTCARE);
for (i = skip_pages; i < (linear_size >> 12) ; i += 2)
svcControlMemory(&tmp, (u32)linear_address + (i << 12), 0x0, 0x1000, MEMOP_FREE, MEMPERM_DONTCARE);
svcControlMemory(&tmp,
(u32)linear_address + (i << 12), 0x0, 0x1000,
MEMOP_FREE, MEMPERM_DONTCARE);
u32 alloc_address_kaddr = osConvertVirtToPhys((void*)linear_address) + mch2.kernel_fcram_mapping_offset;
alloc_address_kaddr = osConvertVirtToPhys(
(void*)linear_address) + mch2.kernel_fcram_mapping_offset;
mch2.thread_page_kva = get_first_free_basemem_page(mch2.isNew3DS) - 0x10000; /* skip down 16 pages */
mch2.thread_page_kva = get_first_free_basemem_page(mch2.isNew3DS)
- 0x10000; /* skip down 16 pages */
((u32*)linear_buffer)[0] = 1;
((u32*)linear_buffer)[1] = mch2.thread_page_kva;
((u32*)linear_buffer)[2] = alloc_address_kaddr + (((mch2.alloc_size >> 12) - 3) << 13) + (skip_pages << 12);
u32 dst_memchunk = linear_address + (((mch2.alloc_size >> 12) - 2) << 13) + (skip_pages << 12);
dst_memchunk = linear_address
+ (((mch2.alloc_size >> 12) - 2) << 13)
+ (skip_pages << 12);
memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000);
@@ -291,18 +315,21 @@ static void do_memchunkhax2(void)
GSPGPU_FlushDataCache((void*)linear_buffer, 16);
memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000);
/* can't clear gspEvents[GSPGPU_EVENT_PPF]), directly so execute a dummy copy
* and use gspWaitForEvent to clear it. */
/* can't clear gspEvents[GSPGPU_EVENT_PPF]),
* directly so execute a dummy copy
* and use gspWaitForEvent to clear it. */
/* LightEvent_Clear(&gspEvents[GSPGPU_EVENT_PPF]); */
/* LightEvent_Clear(&gspEvents[GSPGPU_EVENT_PPF]); */
GX_TextureCopy((void*)linear_buffer, 0, (void*)dst_memchunk, 0, 16, 8);
gspWaitForEvent(GSPGPU_EVENT_PPF, false);
svcCreateThread(&mch2.alloc_thread, (ThreadFunc)alloc_thread_entry, (u32)&mch2,
mch2.threads[MCH2_THREAD_COUNT_MAX - 1].stack_top, 0x3F, 1);
svcCreateThread(&mch2.alloc_thread,
(ThreadFunc)alloc_thread_entry, (u32)&mch2,
mch2.threads[MCH2_THREAD_COUNT_MAX - 1].stack_top, 0x3F, 1);
while ((u32) svcArbitrateAddress(mch2.arbiter, mch2.alloc_address, ARBITRATION_WAIT_IF_LESS_THAN_TIMEOUT, 0,
0) == 0xD9001814);
while ((u32) svcArbitrateAddress(mch2.arbiter, mch2.alloc_address,
ARBITRATION_WAIT_IF_LESS_THAN_TIMEOUT, 0,
0) == 0xD9001814);
GX_TextureCopy((void*)linear_buffer, 0, (void*)dst_memchunk, 0, 16, 8);
memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000);
@@ -311,9 +338,9 @@ static void do_memchunkhax2(void)
svcWaitSynchronization(mch2.alloc_thread, U64_MAX);
svcCloseHandle(mch2.alloc_thread);
u32* mapped_page = (u32*)(mch2.alloc_address + mch2.alloc_size - 0x1000);
volatile u32* thread_ACL = &mapped_page[THREAD_PAGE_ACL_OFFSET >> 2];
mapped_page = (u32*)
(mch2.alloc_address + mch2.alloc_size - 0x1000);
thread_ACL = &mapped_page[THREAD_PAGE_ACL_OFFSET >> 2];
svcCreateEvent(&mch2.main_thread_lock, 0);
svcCreateEvent(&mch2.target_threads_lock, 1);
@@ -325,16 +352,18 @@ static void do_memchunkhax2(void)
continue;
mch2.threads[i].args.started_event = mch2.main_thread_lock;
mch2.threads[i].args.lock = mch2.target_threads_lock;
mch2.threads[i].args.target_kaddr = 0;
mch2.threads[i].args.lock = mch2.target_threads_lock;
mch2.threads[i].args.target_kaddr = 0;
thread_ACL[0] = 0;
thread_ACL[0] = 0;
GSPGPU_FlushDataCache((void*)thread_ACL, 16);
GSPGPU_InvalidateDataCache((void*)thread_ACL, 16);
svcClearEvent(mch2.main_thread_lock);
svcCreateThread(&mch2.threads[i].handle, (ThreadFunc)target_thread_entry, (u32)&mch2.threads[i].args,
mch2.threads[i].stack_top, 0x18, 0);
svcCreateThread(&mch2.threads[i].handle,
(ThreadFunc)target_thread_entry,
(u32)&mch2.threads[i].args,
mch2.threads[i].stack_top, 0x18, 0);
svcWaitSynchronization(mch2.main_thread_lock, U64_MAX);
if (thread_ACL[0])
@@ -342,8 +371,10 @@ static void do_memchunkhax2(void)
thread_ACL[SVC_ACL_OFFSET(0x7B) >> 2] = SVC_ACL_MASK(0x7B);
GSPGPU_FlushDataCache((void*)thread_ACL, 16);
GSPGPU_InvalidateDataCache((void*)thread_ACL, 16);
mch2.threads[i].args.target_kaddr = get_thread_page() + THREAD_PAGE_ACL_OFFSET + SVC_ACL_OFFSET(0x7B);
mch2.threads[i].args.target_val = SVC_ACL_MASK(0x7B);
mch2.threads[i].args.target_kaddr = get_thread_page()
+ THREAD_PAGE_ACL_OFFSET
+ SVC_ACL_OFFSET(0x7B);
mch2.threads[i].args.target_val = SVC_ACL_MASK(0x7B);
break;
}
@@ -365,14 +396,18 @@ static void do_memchunkhax2(void)
svcCloseHandle(mch2.target_threads_lock);
svcCloseHandle(mch2.main_thread_lock);
svcControlMemory(&tmp, mch2.alloc_address, 0, mch2.alloc_size, MEMOP_FREE, MEMPERM_DONTCARE);
svcControlMemory(&tmp, mch2.alloc_address, 0, mch2.alloc_size,
MEMOP_FREE, MEMPERM_DONTCARE);
write_kaddr(alloc_address_kaddr + linear_size - 0x3000 + 0x4, alloc_address_kaddr + linear_size - 0x1000);
svcControlMemory(&tmp, (u32)fragmented_address, 0x0, fragmented_size, MEMOP_FREE, MEMPERM_DONTCARE);
svcControlMemory(&tmp, (u32)fragmented_address, 0x0, fragmented_size,
MEMOP_FREE, MEMPERM_DONTCARE);
for (i = 1 + skip_pages; i < (linear_size >> 12) ; i += 2)
svcControlMemory(&tmp, (u32)linear_address + (i << 12), 0x0, 0x1000, MEMOP_FREE, MEMPERM_DONTCARE);
svcControlMemory(&tmp, (u32)linear_address + (i << 12), 0x0, 0x1000,
MEMOP_FREE, MEMPERM_DONTCARE);
svcControlMemory(&tmp, linear_buffer, 0, 0x1000, MEMOP_FREE, MEMPERM_DONTCARE);
svcControlMemory(&tmp, linear_buffer, 0, 0x1000, MEMOP_FREE,
MEMPERM_DONTCARE);
APT_SetAppCpuTimeLimit(mch2.old_cpu_time_limit);
}
@@ -418,7 +453,8 @@ static void memchunkhax1_write_pair(u32 val1, u32 val2)
u32* next_ptr1;
u32* prev_ptr6;
svcControlMemory(&linear_buffer, 0, 0, 0x10000, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
svcControlMemory(&linear_buffer, 0, 0, 0x10000,
MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
flush_buffer = (u8*)(linear_buffer + 0x8000);
@@ -426,23 +462,24 @@ static void memchunkhax1_write_pair(u32 val1, u32 val2)
svcControlMemory(&tmp, linear_buffer + 0x3000, 0, 0x2000, MEMOP_FREE, 0);
svcControlMemory(&tmp, linear_buffer + 0x6000, 0, 0x1000, MEMOP_FREE, 0);
next_ptr1 = (u32*)(linear_buffer + 0x0004);
next_ptr1 = (u32*)(linear_buffer + 0x0004);
gspwn(linear_buffer + 0x0000, linear_buffer + 0x1000, 16, flush_buffer);
next_ptr3 = (u32*)(linear_buffer + 0x2004);
prev_ptr3 = (u32*)(linear_buffer + 0x2008);
next_ptr3 = (u32*)(linear_buffer + 0x2004);
prev_ptr3 = (u32*)(linear_buffer + 0x2008);
gspwn(linear_buffer + 0x2000, linear_buffer + 0x3000, 16, flush_buffer);
prev_ptr6 = (u32*)(linear_buffer + 0x5008);
prev_ptr6 = (u32*)(linear_buffer + 0x5008);
gspwn(linear_buffer + 0x5000, linear_buffer + 0x6000, 16, flush_buffer);
*next_ptr1 = *next_ptr3;
*prev_ptr6 = *prev_ptr3;
*next_ptr1 = *next_ptr3;
*prev_ptr6 = *prev_ptr3;
*prev_ptr3 = val1 - 4;
*next_ptr3 = val2;
*prev_ptr3 = val1 - 4;
*next_ptr3 = val2;
gspwn(linear_buffer + 0x3000, linear_buffer + 0x2000, 16, flush_buffer);
svcControlMemory(&tmp, 0, 0, 0x2000, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
svcControlMemory(&tmp, 0, 0, 0x2000,
MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
gspwn(linear_buffer + 0x1000, linear_buffer + 0x0000, 16, flush_buffer);
gspwn(linear_buffer + 0x6000, linear_buffer + 0x5000, 16, flush_buffer);
@@ -450,7 +487,6 @@ static void memchunkhax1_write_pair(u32 val1, u32 val2)
svcControlMemory(&tmp, linear_buffer + 0x0000, 0, 0x1000, MEMOP_FREE, 0);
svcControlMemory(&tmp, linear_buffer + 0x2000, 0, 0x4000, MEMOP_FREE, 0);
svcControlMemory(&tmp, linear_buffer + 0x7000, 0, 0x9000, MEMOP_FREE, 0);
}
static void do_memchunkhax1(void)
@@ -458,7 +494,9 @@ static void do_memchunkhax1(void)
u32 saved_vram_value = *(u32*)0x1F000008;
/* 0x1F000000 contains the enable bit for svc 0x7B */
memchunkhax1_write_pair(get_thread_page() + THREAD_PAGE_ACL_OFFSET + SVC_ACL_OFFSET(0x7B), 0x1F000000);
memchunkhax1_write_pair(get_thread_page()
+ THREAD_PAGE_ACL_OFFSET
+ SVC_ACL_OFFSET(0x7B), 0x1F000000);
write_kaddr(0x1F000008, saved_vram_value);
}
@@ -480,9 +518,11 @@ Result get_luma_version(u32 *major, u32 *minor)
Result svchax_init(bool patch_srv)
{
bool isNew3DS;
u32 kver;
APT_CheckNew3DS(&isNew3DS);
u32 kver = osGetKernelVersion();
kver = osGetKernelVersion();
if (!__ctr_svchax)
{
@@ -491,9 +531,11 @@ Result svchax_init(bool patch_srv)
u32 luma_major, luma_minor;
if (kver > SYSTEM_VERSION(2, 50, 11) &&
(R_FAILED(get_luma_version(&luma_major, &luma_minor) || luma_major < 8)))
(R_FAILED(get_luma_version(&luma_major, &luma_minor)
|| luma_major < 8)))
return -1;
else if (kver > SYSTEM_VERSION(2, 46, 0) && kver <= SYSTEM_VERSION(2, 50, 11))
else if (kver > SYSTEM_VERSION(2, 46, 0)
&& kver <= SYSTEM_VERSION(2, 50, 11))
do_memchunkhax2();
else if (kver <= SYSTEM_VERSION(2, 46, 0))
do_memchunkhax1();
@@ -506,8 +548,9 @@ Result svchax_init(bool patch_srv)
if (patch_srv && !__ctr_svchax_srv)
{
u32 PID_kaddr = read_kaddr(CURRENT_KPROCESS) + (isNew3DS ? 0xBC : (kver > SYSTEM_VERSION(2, 40, 0)) ? 0xB4 : 0xAC);
u32 old_PID = read_kaddr(PID_kaddr);
u32 PID_kaddr = read_kaddr(CURRENT_KPROCESS)
+ (isNew3DS ? 0xBC : (kver > SYSTEM_VERSION(2, 40, 0)) ? 0xB4 : 0xAC);
u32 old_PID = read_kaddr(PID_kaddr);
write_kaddr(PID_kaddr, 0);
srvExit();
srvInit();
+40 -37
View File
@@ -10,6 +10,7 @@
#define CTR_APPMEMALLOC_PTR ((u32*)0x1FF80040)
/* Global variables */
u32 __stacksize__ = 0x00400000;
u32 __linear_heap_size = 0x01000000;
@@ -22,22 +23,24 @@ u32 __stack_size_extra;
extern u32 __linear_heap_size_hbl;
extern u32 __heap_size_hbl;
extern void* __service_ptr;
extern void (*__system_retAddr)(void);
/* Forward declarations */
void envDestroyHandles(void);
void __appExit();
void __appExit(void);
void __libc_fini_array(void);
void __appInit();
void __appInit(void);
void __libc_init_array(void);
void __system_initSyscalls(void);
void __system_initArgv();
void __system_initArgv(void);
void __ctru_exit(int rc);
int __libctru_gtod(struct _reent* ptr, struct timeval* tp, struct timezone* tz);
int __libctru_gtod(struct _reent* ptr,
struct timeval* tp, struct timezone* tz);
void (*__system_retAddr)(void);
extern void* __service_ptr;
Result __sync_init(void) __attribute__((weak));
@@ -140,37 +143,41 @@ extern const char* __system_arglist;
char __argv_hmac[0x20] = {0x1d, 0x78, 0xff, 0xb9, 0xc5, 0xbc, 0x78, 0xb7, 0xac, 0x29, 0x1d, 0x3e, 0x16, 0xd0, 0xcf, 0x53,
0xef, 0x12, 0x58, 0x83, 0xb6, 0x9e, 0x2f, 0x79, 0x47, 0xf9, 0x35, 0x61, 0xeb, 0x50, 0xd7, 0x67};
Result APT_ReceiveDeliverArg_(void* param, size_t param_size, void* hmac, size_t hmac_size, u64* source_pid, bool* received)
Result APT_ReceiveDeliverArg_(void* param, size_t param_size,
void* hmac, size_t hmac_size, u64* source_pid, bool* received)
{
u32 cmdbuf[16];
cmdbuf[0]=IPC_MakeHeader(0x35,2,0);
cmdbuf[1]=param_size;
cmdbuf[2]=hmac_size;
u32 saved_threadstorage[4];
u32* staticbufs = getThreadStaticBuffers();
saved_threadstorage[0]=staticbufs[0];
saved_threadstorage[1]=staticbufs[1];
saved_threadstorage[2]=staticbufs[2];
saved_threadstorage[3]=staticbufs[3];
staticbufs[0]=IPC_Desc_StaticBuffer(param_size, 0);
staticbufs[1]=(u32)param;
staticbufs[2]=IPC_Desc_StaticBuffer(hmac_size, 2);
staticbufs[3]=(u32)hmac;
u32 *staticbufs;
Result ret;
Result ret = aptSendCommand(cmdbuf);
staticbufs[0]=saved_threadstorage[0];
staticbufs[1]=saved_threadstorage[1];
staticbufs[2]=saved_threadstorage[2];
staticbufs[3]=saved_threadstorage[3];
cmdbuf[0] = IPC_MakeHeader(0x35,2,0);
cmdbuf[1] = param_size;
cmdbuf[2] = hmac_size;
staticbufs = getThreadStaticBuffers();
saved_threadstorage[0] = staticbufs[0];
saved_threadstorage[1] = staticbufs[1];
saved_threadstorage[2] = staticbufs[2];
saved_threadstorage[3] = staticbufs[3];
staticbufs[0] = IPC_Desc_StaticBuffer(param_size, 0);
staticbufs[1] = (u32)param;
staticbufs[2] = IPC_Desc_StaticBuffer(hmac_size, 2);
staticbufs[3] = (u32)hmac;
ret = aptSendCommand(cmdbuf);
staticbufs[0] = saved_threadstorage[0];
staticbufs[1] = saved_threadstorage[1];
staticbufs[2] = saved_threadstorage[2];
staticbufs[3] = saved_threadstorage[3];
if(R_FAILED(ret))
return ret;
if(source_pid)
*source_pid = ((u64*)cmdbuf)[1];
*source_pid = ((u64*)cmdbuf)[1];
if(received)
*received = ((bool*)cmdbuf)[16];
*received = ((bool*)cmdbuf)[16];
return cmdbuf[1];
}
@@ -202,13 +209,15 @@ void __system_initArgv(void)
if (__system_argc)
{
__system_argv = (char**) malloc((__system_argc + 1) * sizeof(char**));
__system_argv[0] = arg_struct->args;
__system_argv = (char**)malloc(
(__system_argc + 1) * sizeof(char**));
__system_argv[0] = arg_struct->args;
for (i = 1; i < __system_argc; i++)
__system_argv[i] = __system_argv[i - 1] + strlen(__system_argv[i - 1]) + 1;
i = __system_argc - 1;
i = __system_argc - 1;
__system_argc = 1;
while (i)
{
if(__system_argv[i] && isalnum(__system_argv[i][0])
@@ -223,8 +232,8 @@ void __system_initArgv(void)
}
else
{
__system_argc = 1;
__system_argv = (char**) malloc(sizeof(char**) * 2);
__system_argc = 1;
__system_argv = (char**) malloc(sizeof(char**) * 2);
__system_argv[0] = "sdmc:/retroarch/retroarch";
}
__system_argv[__system_argc] = NULL;
@@ -269,8 +278,6 @@ void dump_result_value(Result val)
printf("level : %u\n", res.level);
}
bool select_pressed = false;
void wait_for_input(void)
{
printf("\n\nPress Start.\n\n");
@@ -290,10 +297,6 @@ void wait_for_input(void)
if (kDown & KEY_SELECT)
exit(0);
#if 0
select_pressed = true;
#endif
svcSleepThread(1000000);
}
}
+9 -8
View File
@@ -15,12 +15,12 @@ static void (*launch_3dsx)(const char* path,
static int exec_3dsx_actual(const char* path,
const char** args, bool appendPath)
{
bool inited;
bool fileExists;
struct stat sBuff;
argData_s newProgramArgs;
unsigned int argChars = 0;
unsigned int argNum = 0;
bool fileExists;
bool inited;
unsigned int argNum = 0;
if (!path || path[0] == '\0')
{
@@ -51,7 +51,8 @@ static int exec_3dsx_actual(const char* path,
newProgramArgs.dst += strlen(path) + 1;
newProgramArgs.buf[0]++;
}
while(args[argNum] != NULL)
while(args[argNum])
{
strcpy(newProgramArgs.dst, args[argNum]);
newProgramArgs.dst += strlen(args[argNum]) + 1;
@@ -59,18 +60,18 @@ static int exec_3dsx_actual(const char* path,
argNum++;
}
inited = loader_Rosalina.init();
launch_3dsx = loader_Rosalina.launchFile;
inited = loader_Rosalina.init();
launch_3dsx = loader_Rosalina.launchFile;
if (!inited)
{
inited = loader_Ninjhax2.init();
inited = loader_Ninjhax2.init();
launch_3dsx = loader_Ninjhax2.launchFile;
}
if (!inited)
{
inited = loader_Ninjhax1.init();
inited = loader_Ninjhax1.init();
launch_3dsx = loader_Ninjhax1.launchFile;
}
+32 -22
View File
@@ -6,9 +6,10 @@
#define FILE_CHUNK_SIZE 4096
typedef struct{
u32 argc;
char args[0x300 - 0x4];
typedef struct
{
u32 argc;
char args[0x300 - 0x4];
}ciaParam;
char argvHmac[0x20] = {0x1d, 0x78, 0xff, 0xb9, 0xc5, 0xbc, 0x78, 0xb7, 0xac, 0x29, 0x1d, 0x3e, 0x16, 0xd0, 0xcf, 0x53, 0xef, 0x12, 0x58, 0x83, 0xb6, 0x9e, 0x2f, 0x79, 0x47, 0xf9, 0x35, 0x61, 0xeb, 0x50, 0xd7, 0x67};
@@ -28,11 +29,10 @@ static int isCiaInstalled(u64 titleId, u16 version)
u32 titlesToRetrieve;
u32 titlesRetrieved;
u64* titleIds;
bool titleExists = false;
u32 titlesToCheck;
AM_TitleEntry titleInfo;
Result failed;
failed = AM_GetTitleCount(MEDIATYPE_SD, &titlesToRetrieve);
bool titleExists = false;
Result failed = AM_GetTitleCount(MEDIATYPE_SD, &titlesToRetrieve);
if (R_FAILED(failed))
return -1;
@@ -44,7 +44,7 @@ static int isCiaInstalled(u64 titleId, u16 version)
if (R_FAILED(failed))
return -1;
for(u32 titlesToCheck = 0; titlesToCheck < titlesRetrieved; titlesToCheck++)
for(titlesToCheck = 0; titlesToCheck < titlesRetrieved; titlesToCheck++)
{
if (titleIds[titlesToCheck] == titleId)
{
@@ -57,7 +57,8 @@ static int isCiaInstalled(u64 titleId, u16 version)
if (titleExists)
{
failed = AM_GetTitleInfo(MEDIATYPE_SD, 1 /*titleCount*/, &titleId, &titleInfo);
failed = AM_GetTitleInfo(MEDIATYPE_SD,
1 /*titleCount*/, &titleId, &titleInfo);
if (R_FAILED(failed))
return -1;
@@ -70,15 +71,13 @@ static int isCiaInstalled(u64 titleId, u16 version)
static int installCia(Handle ciaFile)
{
Result failed;
Handle outputHandle;
u64 fileSize;
u64 fileOffset = 0;
u32 bytesRead;
u32 bytesWritten;
u8 transferBuffer[FILE_CHUNK_SIZE];
failed = AM_StartCiaInstall(MEDIATYPE_SD, &outputHandle);
u64 fileOffset = 0;
Result failed = AM_StartCiaInstall(MEDIATYPE_SD, &outputHandle);
if (R_FAILED(failed))
return -1;
@@ -89,14 +88,19 @@ static int installCia(Handle ciaFile)
while(fileOffset < fileSize)
{
u64 bytesRemaining = fileSize - fileOffset;
failed = FSFILE_Read(ciaFile, &bytesRead, fileOffset, transferBuffer, bytesRemaining < FILE_CHUNK_SIZE ? bytesRemaining : FILE_CHUNK_SIZE);
failed = FSFILE_Read(ciaFile, &bytesRead,
fileOffset, transferBuffer,
bytesRemaining < FILE_CHUNK_SIZE
? bytesRemaining
: FILE_CHUNK_SIZE);
if (R_FAILED(failed))
{
AM_CancelCIAInstall(outputHandle);
return -1;
}
failed = FSFILE_Write(outputHandle, &bytesWritten, fileOffset, transferBuffer, bytesRead, 0);
failed = FSFILE_Write(outputHandle, &bytesWritten,
fileOffset, transferBuffer, bytesRead, 0);
if (R_FAILED(failed))
{
AM_CancelCIAInstall(outputHandle);
@@ -146,6 +150,7 @@ int exec_cia(const char* path, const char** args)
}
inited = R_SUCCEEDED(amInit()) && R_SUCCEEDED(fsInit());
if (inited)
{
AM_TitleEntry ciaInfo;
@@ -155,12 +160,15 @@ int exec_cia(const char* path, const char** args)
ciaParam param;
int argsLength;
/* open CIA file */
Result res = FSUSER_OpenArchive(&ciaArchive, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""));
Result res = FSUSER_OpenArchive(&ciaArchive,
ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""));
if (R_FAILED(res))
errorAndQuit("Cant open SD FS archive.");
res = FSUSER_OpenFile(&ciaFile, ciaArchive, fsMakePath(PATH_ASCII, path + 5/*skip "sdmc:"*/), FS_OPEN_READ, 0);
res = FSUSER_OpenFile(&ciaFile,
ciaArchive, fsMakePath(PATH_ASCII, path + 5/*skip "sdmc:"*/),
FS_OPEN_READ, 0);
if (R_FAILED(res))
errorAndQuit("Cant open CIA file.");
@@ -185,10 +193,11 @@ int exec_cia(const char* path, const char** args)
FSFILE_Close(ciaFile);
FSUSER_CloseArchive(ciaArchive);
param.argc = 0;
argsLength = 0;
char* argLocation = param.args;
while(args[param.argc] != NULL)
param.argc = 0;
argsLength = 0;
char *argLocation = param.args;
while(args[param.argc])
{
strcpy(argLocation, args[param.argc]);
argLocation += strlen(args[param.argc]) + 1;
@@ -200,7 +209,8 @@ int exec_cia(const char* path, const char** args)
if (R_FAILED(res))
errorAndQuit("CIA cant run, cant prepare.");
res = APT_DoApplicationJump(&param, sizeof(param.argc) + argsLength, argvHmac);
res = APT_DoApplicationJump(&param, sizeof(param.argc)
+ argsLength, argvHmac);
if (R_FAILED(res))
errorAndQuit("CIA cant run, cant jump.");
+7 -3
View File
@@ -3,20 +3,24 @@
Handle launchOpenFile(const char* path)
{
Handle file;
Result res;
ssize_t units;
static uint16_t __utf16path[PATH_MAX+1];
if (strncmp(path, "sdmc:/", 6) == 0)
path += 5;
else if (*path != '/')
return 0;
/* Convert the executable path to UTF-16 */
static uint16_t __utf16path[PATH_MAX+1];
ssize_t units = utf8_to_utf16(__utf16path, (const uint8_t*)path, PATH_MAX);
units = utf8_to_utf16(__utf16path, (const uint8_t*)path, PATH_MAX);
if (units < 0 || units >= PATH_MAX) return 0;
__utf16path[units] = 0;
/* Open the file directly */
FS_Path apath = { PATH_EMPTY, 1, (u8*)"" };
FS_Path fpath = { PATH_UTF16, (units+1)*2, (u8*)__utf16path };
Result res = FSUSER_OpenFileDirectly(&file, ARCHIVE_SDMC, apath, fpath, FS_OPEN_READ, 0);
res = FSUSER_OpenFileDirectly(&file, ARCHIVE_SDMC,
apath, fpath, FS_OPEN_READ, 0);
return R_SUCCEEDED(res) ? file : 0;
}
+16 -11
View File
@@ -9,28 +9,32 @@ static bool init(void)
static Result HBLDR_SetTarget(const char* path)
{
Result rc;
u32 pathLen = strlen(path) + 1;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(2, 0, 2); /* 0x20002 */
cmdbuf[1] = IPC_Desc_StaticBuffer(pathLen, 0);
cmdbuf[2] = (u32)path;
cmdbuf[0] = IPC_MakeHeader(2, 0, 2); /* 0x20002 */
cmdbuf[1] = IPC_Desc_StaticBuffer(pathLen, 0);
cmdbuf[2] = (u32)path;
Result rc = svcSendSyncRequest(hbldrHandle);
if (R_SUCCEEDED(rc)) rc = cmdbuf[1];
rc = svcSendSyncRequest(hbldrHandle);
if (R_SUCCEEDED(rc))
rc = cmdbuf[1];
return rc;
}
static Result HBLDR_SetArgv(const void* buffer, u32 size)
{
Result rc;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(3, 0, 2); /* 0x30002 */
cmdbuf[1] = IPC_Desc_StaticBuffer(size, 1);
cmdbuf[2] = (u32)buffer;
cmdbuf[0] = IPC_MakeHeader(3, 0, 2); /* 0x30002 */
cmdbuf[1] = IPC_Desc_StaticBuffer(size, 1);
cmdbuf[2] = (u32)buffer;
Result rc = svcSendSyncRequest(hbldrHandle);
if (R_SUCCEEDED(rc)) rc = cmdbuf[1];
rc = svcSendSyncRequest(hbldrHandle);
if (R_SUCCEEDED(rc))
rc = cmdbuf[1];
return rc;
}
@@ -39,7 +43,8 @@ static void deinit(void)
svcCloseHandle(hbldrHandle);
}
static void launchFile(const char* path, argData_s* args, executableMetadata_s* em)
static void launchFile(const char* path,
argData_s* args, executableMetadata_s* em)
{
if (strncmp(path, "sdmc:/",6) == 0)
path += 5;
+98 -75
View File
@@ -25,14 +25,17 @@ void GPU_Reset(u32* gxbuf, u32* gpuBuf, u32 gpuBufSize)
GPUCMD_SetBuffer(gpuBuf, gpuBufSize, 0);
}
void GPU_SetFloatUniform(GPU_SHADER_TYPE type, u32 startreg, u32* data, u32 numreg)
void GPU_SetFloatUniform(GPU_SHADER_TYPE type,
u32 startreg, u32* data, u32 numreg)
{
int regOffset;
if(!data)
return;
int regOffset = (type == GPU_GEOMETRY_SHADER) ? (-0x30) : (0x0);
regOffset = (type == GPU_GEOMETRY_SHADER) ? (-0x30) : (0x0);
GPUCMD_AddWrite(GPUREG_VSH_FLOATUNIFORM_CONFIG+regOffset, 0x80000000|startreg);
GPUCMD_AddWrite(GPUREG_VSH_FLOATUNIFORM_CONFIG+regOffset,
0x80000000 | startreg);
GPUCMD_AddWrites(GPUREG_VSH_FLOATUNIFORM_DATA+regOffset, data, numreg*4);
}
@@ -40,43 +43,46 @@ void GPU_SetFloatUniform(GPU_SHADER_TYPE type, u32 startreg, u32* data, u32 numr
void GPU_SetViewport(u32* depthBuffer, u32* colorBuffer,
u32 x, u32 y, u32 w, u32 h)
{
u32 f116e;
u32 param[0x4];
float fw=(float)w;
float fh=(float)h;
float fw = (float)w;
float fh = (float)h;
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_FLUSH, 0x00000001);
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_INVALIDATE, 0x00000001);
u32 f116e=0x01000000|(((h-1)&0xFFF)<<12)|(w&0xFFF);
f116e = 0x01000000 | (((h-1) & 0xFFF) << 12) | (w & 0xFFF);
param[0x0]=((u32)depthBuffer)>>3;
param[0x1]=((u32)colorBuffer)>>3;
param[0x2]=f116e;
param[0x0] = ((u32)depthBuffer) >> 3;
param[0x1] = ((u32)colorBuffer) >> 3;
param[0x2] = f116e;
GPUCMD_AddIncrementalWrites(GPUREG_DEPTHBUFFER_LOC, param, 0x00000003);
GPUCMD_AddWrite(GPUREG_RENDERBUF_DIM, f116e);
GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_FORMAT, 0x00000003); /* depth buffer format */
GPUCMD_AddWrite(GPUREG_COLORBUFFER_FORMAT, 0x00000002); /* color buffer format */
/* depth buffer format */
GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_FORMAT, 0x00000003);
/* color buffer format */
GPUCMD_AddWrite(GPUREG_COLORBUFFER_FORMAT, 0x00000002);
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_BLOCK32, 0x00000000); /* ? */
param[0x0]=f32tof24(fw/2);
param[0x1]=f32tof31(2.0f / fw) << 1;
param[0x2]=f32tof24(fh/2);
param[0x3]=f32tof31(2.0f / fh) << 1;
param[0x0] = f32tof24(fw/2);
param[0x1] = f32tof31(2.0f / fw) << 1;
param[0x2] = f32tof24(fh/2);
param[0x3] = f32tof31(2.0f / fh) << 1;
GPUCMD_AddIncrementalWrites(GPUREG_VIEWPORT_WIDTH, param, 0x00000004);
GPUCMD_AddWrite(GPUREG_VIEWPORT_XY, (y<<16)|(x&0xFFFF));
GPUCMD_AddWrite(GPUREG_VIEWPORT_XY, (y << 16)|(x & 0xFFFF));
param[0x0]=0x00000000;
param[0x1]=0x00000000;
param[0x2]=((h-1)<<16)|((w-1)&0xFFFF);
param[0x0] = 0x00000000;
param[0x1] = 0x00000000;
param[0x2] = ((h-1) << 16)|((w-1) & 0xFFFF);
GPUCMD_AddIncrementalWrites(GPUREG_SCISSORTEST_MODE, param, 0x00000003);
/* enable depth buffer */
param[0x0]=0x0000000F;
param[0x1]=0x0000000F;
param[0x2]=0x00000002;
param[0x3]=0x00000002;
param[0x0] = 0x0000000F;
param[0x1] = 0x0000000F;
param[0x2] = 0x00000002;
param[0x3] = 0x00000002;
GPUCMD_AddIncrementalWrites(GPUREG_COLORBUFFER_READ, param, 0x00000004);
}
@@ -85,8 +91,8 @@ void GPU_SetScissorTest(GPU_SCISSORMODE mode, u32 left, u32 bottom, u32 right, u
u32 param[3];
param[0x0] = mode;
param[0x1] = (bottom<<16)|(left&0xFFFF);
param[0x2] = ((top-1)<<16)|((right-1)&0xFFFF);
param[0x1] = (bottom << 16) | (left & 0xFFFF);
param[0x2] = ((top-1) << 16) | ((right-1) & 0xFFFF);
GPUCMD_AddIncrementalWrites(GPUREG_SCISSORTEST_MODE, param, 0x00000003);
}
@@ -99,12 +105,14 @@ void GPU_DepthMap(float zScale, float zOffset)
void GPU_SetAlphaTest(bool enable, GPU_TESTFUNC function, u8 ref)
{
GPUCMD_AddWrite(GPUREG_FRAGOP_ALPHA_TEST, (enable&1)|((function&7)<<4)|(ref<<8));
GPUCMD_AddWrite(GPUREG_FRAGOP_ALPHA_TEST,
(enable&1)|((function&7) << 4)|(ref << 8));
}
void GPU_SetStencilTest(bool enable, GPU_TESTFUNC function, u8 ref, u8 input_mask, u8 write_mask)
{
GPUCMD_AddWrite(GPUREG_STENCIL_TEST, (enable&1)|((function&7)<<4)|(write_mask<<8)|(ref<<16)|(input_mask<<24));
GPUCMD_AddWrite(GPUREG_STENCIL_TEST,
(enable&1)|((function&7) << 4)|(write_mask << 8)|(ref << 16)|(input_mask << 24));
}
void GPU_SetStencilOp(GPU_STENCILOP sfail, GPU_STENCILOP dfail, GPU_STENCILOP pass)
@@ -114,14 +122,14 @@ void GPU_SetStencilOp(GPU_STENCILOP sfail, GPU_STENCILOP dfail, GPU_STENCILOP pa
void GPU_SetDepthTestAndWriteMask(bool enable, GPU_TESTFUNC function, GPU_WRITEMASK writemask)
{
GPUCMD_AddWrite(GPUREG_DEPTH_COLOR_MASK, (enable&1)|((function&7)<<4)|(writemask<<8));
GPUCMD_AddWrite(GPUREG_DEPTH_COLOR_MASK, (enable&1)|((function&7) << 4)|(writemask << 8));
}
void GPU_SetAlphaBlending(GPU_BLENDEQUATION colorEquation, GPU_BLENDEQUATION alphaEquation,
GPU_BLENDFACTOR colorSrc, GPU_BLENDFACTOR colorDst,
GPU_BLENDFACTOR alphaSrc, GPU_BLENDFACTOR alphaDst)
{
GPUCMD_AddWrite(GPUREG_BLEND_FUNC, colorEquation | (alphaEquation<<8) | (colorSrc<<16) | (colorDst<<20) | (alphaSrc<<24) | (alphaDst<<28));
GPUCMD_AddWrite(GPUREG_BLEND_FUNC, colorEquation | (alphaEquation << 8) | (colorSrc << 16) | (colorDst << 20) | (alphaSrc << 24) | (alphaDst << 28));
GPUCMD_AddMaskedWrite(GPUREG_COLOR_OPERATION, 0x2, 0x00000100);
}
@@ -138,7 +146,7 @@ void GPU_SetBlendingColor(u8 r, u8 g, u8 b, u8 a)
void GPU_SetTextureEnable(GPU_TEXUNIT units)
{
GPUCMD_AddMaskedWrite(GPUREG_SH_OUTATTR_CLOCK, 0x2, units<<8); /* enables texcoord outputs */
GPUCMD_AddMaskedWrite(GPUREG_SH_OUTATTR_CLOCK, 0x2, units << 8); /* enables texcoord outputs */
GPUCMD_AddWrite(GPUREG_TEXUNIT_CONFIG, 0x00011000|units); /* enables texture units */
}
@@ -148,22 +156,22 @@ void GPU_SetTexture(GPU_TEXUNIT unit, u32* data, u16 width, u16 height, u32 para
{
case GPU_TEXUNIT0:
GPUCMD_AddWrite(GPUREG_TEXUNIT0_TYPE, colorType);
GPUCMD_AddWrite(GPUREG_TEXUNIT0_ADDR1, ((u32)data)>>3);
GPUCMD_AddWrite(GPUREG_TEXUNIT0_DIM, (width<<16)|height);
GPUCMD_AddWrite(GPUREG_TEXUNIT0_ADDR1, ((u32)data) >> 3);
GPUCMD_AddWrite(GPUREG_TEXUNIT0_DIM, (width << 16)|height);
GPUCMD_AddWrite(GPUREG_TEXUNIT0_PARAM, param);
break;
case GPU_TEXUNIT1:
GPUCMD_AddWrite(GPUREG_TEXUNIT1_TYPE, colorType);
GPUCMD_AddWrite(GPUREG_TEXUNIT1_ADDR, ((u32)data)>>3);
GPUCMD_AddWrite(GPUREG_TEXUNIT1_DIM, (width<<16)|height);
GPUCMD_AddWrite(GPUREG_TEXUNIT1_ADDR, ((u32)data) >> 3);
GPUCMD_AddWrite(GPUREG_TEXUNIT1_DIM, (width << 16)|height);
GPUCMD_AddWrite(GPUREG_TEXUNIT1_PARAM, param);
break;
case GPU_TEXUNIT2:
GPUCMD_AddWrite(GPUREG_TEXUNIT2_TYPE, colorType);
GPUCMD_AddWrite(GPUREG_TEXUNIT2_ADDR, ((u32)data)>>3);
GPUCMD_AddWrite(GPUREG_TEXUNIT2_DIM, (width<<16)|height);
GPUCMD_AddWrite(GPUREG_TEXUNIT2_ADDR, ((u32)data) >> 3);
GPUCMD_AddWrite(GPUREG_TEXUNIT2_DIM, (width << 16)|height);
GPUCMD_AddWrite(GPUREG_TEXUNIT2_PARAM, param);
break;
}
@@ -172,49 +180,60 @@ void GPU_SetTexture(GPU_TEXUNIT unit, u32* data, u16 width, u16 height, u32 para
void GPU_SetTextureBorderColor(GPU_TEXUNIT unit,u32 borderColor)
{
switch (unit)
{
case GPU_TEXUNIT0:
GPUCMD_AddWrite(GPUREG_TEXUNIT0_BORDER_COLOR, borderColor);
break;
{
case GPU_TEXUNIT0:
GPUCMD_AddWrite(GPUREG_TEXUNIT0_BORDER_COLOR, borderColor);
break;
case GPU_TEXUNIT1:
GPUCMD_AddWrite(GPUREG_TEXUNIT1_BORDER_COLOR, borderColor);
break;
case GPU_TEXUNIT1:
GPUCMD_AddWrite(GPUREG_TEXUNIT1_BORDER_COLOR, borderColor);
break;
case GPU_TEXUNIT2:
GPUCMD_AddWrite(GPUREG_TEXUNIT2_BORDER_COLOR, borderColor);
break;
}
case GPU_TEXUNIT2:
GPUCMD_AddWrite(GPUREG_TEXUNIT2_BORDER_COLOR, borderColor);
break;
}
}
const u8 GPU_FORMATSIZE[4]={1,1,2,4};
void GPU_SetAttributeBuffers(u8 totalAttributes, u32* baseAddress, u64 attributeFormats, u16 attributeMask, u64 attributePermutation, u8 numBuffers, u32 bufferOffsets[], u64 bufferPermutations[], u8 bufferNumAttributes[])
void GPU_SetAttributeBuffers(
u8 totalAttributes,
u32* baseAddress,
u64 attributeFormats,
u16 attributeMask,
u64 attributePermutation,
u8 numBuffers,
u32 bufferOffsets[],
u64 bufferPermutations[],
u8 bufferNumAttributes[])
{
int i, j;
u32 param[0x28];
u8 sizeTable[0xC];
memset(param, 0x00, 0x28*4);
param[0x0]=((u32)baseAddress)>>3;
param[0x1]=attributeFormats&0xFFFFFFFF;
param[0x2]=((totalAttributes-1)<<28)|((attributeMask&0xFFF)<<16)|((attributeFormats>>32)&0xFFFF);
param[0x0] = ((u32)baseAddress) >> 3;
param[0x1] = attributeFormats & 0xFFFFFFFF;
param[0x2] = ((totalAttributes-1) << 28) | ((attributeMask & 0xFFF) << 16) | ((attributeFormats >> 32) & 0xFFFF);
int i, j;
u8 sizeTable[0xC];
for(i=0;i<totalAttributes;i++)
for(i = 0; i < totalAttributes; i++)
{
u8 v=attributeFormats&0xF;
sizeTable[i]=GPU_FORMATSIZE[v&3]*((v>>2)+1);
attributeFormats>>=4;
u8 v = attributeFormats & 0xF;
sizeTable[i] = GPU_FORMATSIZE[v & 3]*((v>>2)+1);
attributeFormats >>= 4;
}
for(i=0;i<numBuffers;i++)
{
u16 stride=0;
param[3*(i+1)+0]=bufferOffsets[i];
param[3*(i+1)+1]=bufferPermutations[i]&0xFFFFFFFF;
for(j=0;j<bufferNumAttributes[i];j++)stride+=sizeTable[(bufferPermutations[i]>>(4*j))&0xF];
param[3*(i+1)+2]=(bufferNumAttributes[i]<<28)|((stride&0xFFF)<<16)|((bufferPermutations[i]>>32)&0xFFFF);
u16 stride = 0;
param[3*(i+1)+0] = bufferOffsets[i];
param[3*(i+1)+1] = bufferPermutations[i] & 0xFFFFFFFF;
for(j = 0; j < bufferNumAttributes[i]; j++)
stride += sizeTable[(bufferPermutations[i]>>(4*j)) & 0xF];
param[3*(i+1)+2] = (bufferNumAttributes[i] << 28) | ((stride & 0xFFF)<< 16) | ((bufferPermutations[i] >> 32) & 0xFFFF);
}
GPUCMD_AddIncrementalWrites(GPUREG_ATTRIBBUFFERS_LOC, param, 0x00000027);
@@ -222,17 +241,17 @@ void GPU_SetAttributeBuffers(u8 totalAttributes, u32* baseAddress, u64 attribute
GPUCMD_AddMaskedWrite(GPUREG_VSH_INPUTBUFFER_CONFIG, 0xB, 0xA0000000|(totalAttributes-1));
GPUCMD_AddWrite(GPUREG_VSH_NUM_ATTR, (totalAttributes-1));
GPUCMD_AddIncrementalWrites(GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW, ((u32[]){attributePermutation&0xFFFFFFFF, (attributePermutation>>32)&0xFFFF}), 2);
GPUCMD_AddIncrementalWrites(GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW, ((u32[]){attributePermutation & 0xFFFFFFFF, (attributePermutation >> 32) & 0xFFFF}), 2);
}
void GPU_SetAttributeBuffersAddress(u32* baseAddress)
{
GPUCMD_AddWrite(GPUREG_ATTRIBBUFFERS_LOC, ((u32)baseAddress)>>3);
GPUCMD_AddWrite(GPUREG_ATTRIBBUFFERS_LOC, ((u32)baseAddress) >> 3);
}
void GPU_SetFaceCulling(GPU_CULLMODE mode)
{
GPUCMD_AddWrite(GPUREG_FACECULLING_CONFIG, mode&0x3);
GPUCMD_AddWrite(GPUREG_FACECULLING_CONFIG, mode & 0x3);
}
void GPU_SetCombinerBufferWrite(u8 rgb_config, u8 alpha_config)
@@ -244,15 +263,16 @@ const u8 GPU_TEVID[]={0xC0,0xC8,0xD0,0xD8,0xF0,0xF8};
void GPU_SetTexEnv(u8 id, u16 rgbSources, u16 alphaSources, u16 rgbOperands, u16 alphaOperands, GPU_COMBINEFUNC rgbCombine, GPU_COMBINEFUNC alphaCombine, u32 constantColor)
{
if(id>6)return;
u32 param[0x5];
if(id > 6)
return;
memset(param, 0x00, 5*4);
param[0x0]=(alphaSources<<16)|(rgbSources);
param[0x1]=(alphaOperands<<12)|(rgbOperands);
param[0x2]=(alphaCombine<<16)|(rgbCombine);
param[0x3]=constantColor;
param[0x4]=0x00000000; /* ? */
param[0x0] = (alphaSources << 16) | (rgbSources);
param[0x1] = (alphaOperands << 12) | (rgbOperands);
param[0x2] = (alphaCombine << 16) | (rgbCombine);
param[0x3] = constantColor;
param[0x4] = 0x00000000; /* ? */
GPUCMD_AddIncrementalWrites(GPUREG_0000|GPU_TEVID[id], param, 0x00000005);
}
@@ -262,7 +282,8 @@ void GPU_DrawArray(GPU_Primitive_t primitive, u32 first, u32 count)
/* set primitive type */
GPUCMD_AddMaskedWrite(GPUREG_PRIMITIVE_CONFIG, 0x2, primitive);
GPUCMD_AddMaskedWrite(GPUREG_RESTART_PRIMITIVE, 0x2, 0x00000001);
/* index buffer address register should be cleared (except bit 31) before drawing */
/* index buffer address register should be cleared
* (except bit 31) before drawing */
GPUCMD_AddWrite(GPUREG_INDEXBUFFER_CONFIG, 0x80000000);
/* pass number of vertices */
GPUCMD_AddWrite(GPUREG_NUMVERTICES, count);
@@ -298,10 +319,11 @@ void GPU_DrawElements(GPU_Primitive_t primitive, u32* indexArray, u32 n)
GPUCMD_AddMaskedWrite(GPUREG_START_DRAW_FUNC0, 0x1, 0x00000001);
GPUCMD_AddWrite(GPUREG_VTX_FUNC, 0x00000001);
/* CHECKME: does this one also require GPUREG_FRAMEBUFFER_FLUSH at the end? */
/* CHECKME: does this one also require
* GPUREG_FRAMEBUFFER_FLUSH at the end? */
}
void GPU_FinishDrawing()
void GPU_FinishDrawing(void)
{
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_FLUSH, 0x00000001);
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_INVALIDATE, 0x00000001);
@@ -317,7 +339,8 @@ void GPU_Finalize(void)
GPUCMD_Split(NULL, NULL);
#else
GPUCMD_AddWrite(GPUREG_FINALIZE, 0x12345678);
/* not the cleanest way of guaranteeing 0x10-byte size but whatever good enough for now */
/* not the cleanest way of guaranteeing 0x10-byte size
* but whatever good enough for now */
GPUCMD_AddWrite(GPUREG_FINALIZE,0x12345678);
#endif
}
+32 -29
View File
@@ -217,30 +217,39 @@ static int database_cursor_iterate(libretrodb_cursor_t *cur,
if (!string_is_empty(val_string))
db_info->franchise = strdup(val_string);
}
else if (string_is_equal(str, "bbfc_rating"))
else if (string_ends_with(str, "_rating"))
{
if (!string_is_empty(val_string))
db_info->bbfc_rating = strdup(val_string);
}
else if (string_is_equal(str, "esrb_rating"))
{
if (!string_is_empty(val_string))
db_info->esrb_rating = strdup(val_string);
}
else if (string_is_equal(str, "elspa_rating"))
{
if (!string_is_empty(val_string))
db_info->elspa_rating = strdup(val_string);
}
else if (string_is_equal(str, "cero_rating"))
{
if (!string_is_empty(val_string))
db_info->cero_rating = strdup(val_string);
}
else if (string_is_equal(str, "pegi_rating"))
{
if (!string_is_empty(val_string))
db_info->pegi_rating = strdup(val_string);
if (string_is_equal(str, "bbfc_rating"))
{
if (!string_is_empty(val_string))
db_info->bbfc_rating = strdup(val_string);
}
else if (string_is_equal(str, "esrb_rating"))
{
if (!string_is_empty(val_string))
db_info->esrb_rating = strdup(val_string);
}
else if (string_is_equal(str, "elspa_rating"))
{
if (!string_is_empty(val_string))
db_info->elspa_rating = strdup(val_string);
}
else if (string_is_equal(str, "cero_rating"))
{
if (!string_is_empty(val_string))
db_info->cero_rating = strdup(val_string);
}
else if (string_is_equal(str, "pegi_rating"))
{
if (!string_is_empty(val_string))
db_info->pegi_rating = strdup(val_string);
}
else if (string_is_equal(str, "edge_rating"))
db_info->edge_magazine_rating = (unsigned)val->val.uint_;
else if (string_is_equal(str, "famitsu_rating"))
db_info->famitsu_magazine_rating = (unsigned)val->val.uint_;
else if (string_is_equal(str, "tgdb_rating"))
db_info->tgdb_rating = (unsigned)val->val.uint_;
}
else if (string_is_equal(str, "enhancement_hw"))
{
@@ -252,14 +261,8 @@ static int database_cursor_iterate(libretrodb_cursor_t *cur,
if (!string_is_empty(val_string))
db_info->edge_magazine_review = strdup(val_string);
}
else if (string_is_equal(str, "edge_rating"))
db_info->edge_magazine_rating = (unsigned)val->val.uint_;
else if (string_is_equal(str, "edge_issue"))
db_info->edge_magazine_issue = (unsigned)val->val.uint_;
else if (string_is_equal(str, "famitsu_rating"))
db_info->famitsu_magazine_rating = (unsigned)val->val.uint_;
else if (string_is_equal(str, "tgdb_rating"))
db_info->tgdb_rating = (unsigned)val->val.uint_;
else if (string_is_equal(str, "users"))
db_info->max_users = (unsigned)val->val.uint_;
else if (string_is_equal(str, "releasemonth"))
+1
View File
@@ -4,6 +4,7 @@
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
#include <retro_endianness.h>
#include "7zTypes.h"
#ifdef __cplusplus
+6 -5
View File
@@ -1,14 +1,15 @@
#pragma once
#define DISCORD_EXPORT
#include <retro_common_api.h>
#ifdef __cplusplus
#if defined(__cplusplus) && !defined(CXX_BUILD)
extern "C" {
#endif
DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command);
DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, const char* steamId);
int get_process_id(void);
void Discord_Register(const char* applicationId, const char* command);
void Discord_RegisterSteamGame(const char* applicationId, const char* steamId);
#ifdef __cplusplus
#if defined(__cplusplus) && !defined(CXX_BUILD)
}
#endif
+11 -17
View File
@@ -1,12 +1,6 @@
#pragma once
#include <stdint.h>
/* clang-format off */
# define DISCORD_EXPORT
/* clang-format on */
#ifdef __cplusplus
extern "C" {
#endif
@@ -52,28 +46,28 @@ typedef struct DiscordEventHandlers
#define DISCORD_REPLY_YES 1
#define DISCORD_REPLY_IGNORE 2
DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
DiscordEventHandlers* handlers,
int autoRegister,
const char* optionalSteamId);
DISCORD_EXPORT void Discord_Shutdown(void);
void Discord_Initialize(const char* applicationId,
DiscordEventHandlers* handlers,
int autoRegister,
const char* optionalSteamId);
void Discord_Shutdown(void);
/* checks for incoming messages, dispatches callbacks */
DISCORD_EXPORT void Discord_RunCallbacks(void);
void Discord_RunCallbacks(void);
/* If you disable the lib starting its own I/O thread,
* you'll need to call this from your own */
#ifdef DISCORD_DISABLE_IO_THREAD
DISCORD_EXPORT void Discord_UpdateConnection(void);
void Discord_UpdateConnection(void);
#endif
DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence);
DISCORD_EXPORT void Discord_ClearPresence(void);
void Discord_UpdatePresence(const DiscordRichPresence* presence);
void Discord_ClearPresence(void);
DISCORD_EXPORT void Discord_Respond(const char* userid,
void Discord_Respond(const char* userid,
/* DISCORD_REPLY_ */ int reply);
DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers);
void Discord_UpdateHandlers(DiscordEventHandlers* handlers);
#ifdef __cplusplus
} /* extern "C" */
+28 -27
View File
@@ -5,36 +5,37 @@
#include <stdint.h>
#include <time.h>
struct Backoff {
int64_t minAmount;
int64_t maxAmount;
int64_t current;
int fails;
std::mt19937_64 randGenerator;
std::uniform_real_distribution<> randDistribution;
struct Backoff
{
int64_t minAmount;
int64_t maxAmount;
int64_t current;
int fails;
std::mt19937_64 randGenerator;
std::uniform_real_distribution<> randDistribution;
double rand01() { return randDistribution(randGenerator); }
double rand01() { return randDistribution(randGenerator); }
Backoff(int64_t min, int64_t max)
Backoff(int64_t min, int64_t max)
: minAmount(min)
, maxAmount(max)
, current(min)
, fails(0)
, randGenerator((uint64_t)time(0))
{
}
, maxAmount(max)
, current(min)
, fails(0)
, randGenerator((uint64_t)time(0))
{
}
void reset()
{
fails = 0;
current = minAmount;
}
void reset()
{
fails = 0;
current = minAmount;
}
int64_t nextDelay()
{
++fails;
int64_t delay = (int64_t)((double)current * 2.0 * rand01());
current = std::min(current + delay, maxAmount);
return current;
}
int64_t nextDelay()
{
++fails;
int64_t delay = (int64_t)((double)current * 2.0 * rand01());
current = std::min(current + delay, maxAmount);
return current;
}
};
+9 -11
View File
@@ -5,15 +5,13 @@
#include <stdint.h>
#include <stdlib.h>
/* not really connectiony, but need per-platform */
int GetProcessId();
struct BaseConnection {
static BaseConnection* Create();
static void Destroy(BaseConnection*&);
bool isOpen{false};
bool Open();
bool Close();
bool Write(const void* data, size_t length);
bool Read(void* data, size_t length);
struct BaseConnection
{
static BaseConnection* Create();
static void Destroy(BaseConnection*&);
bool isOpen{false};
bool Open();
bool Close();
bool Write(const void* data, size_t length);
bool Read(void* data, size_t length);
};
-5
View File
@@ -9,11 +9,6 @@
#include <sys/un.h>
#include <unistd.h>
int GetProcessId()
{
return ::getpid();
}
struct BaseConnectionUnix : public BaseConnection {
int sock{-1};
};
-5
View File
@@ -6,11 +6,6 @@
#define NOIME
#include <windows.h>
int GetProcessId()
{
return (int)::GetCurrentProcessId();
}
struct BaseConnectionWin : public BaseConnection
{
HANDLE pipe{INVALID_HANDLE_VALUE};
+12 -6
View File
@@ -1,21 +1,29 @@
#include "discord_rpc.h"
#include "discord_register.h"
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include <boolean.h>
#include <file/file_path.h>
#include <compat/strl.h>
#include <discord_rpc.h>
int get_process_id(void)
{
return getpid();
}
/* we want to register games so we can run them from
* Discord client as discord-<appid>:// */
void Discord_Register(const char* applicationId, const char* command)
void Discord_Register(const char *applicationId, const char *command)
{
FILE* fp;
int fileLen;
@@ -82,9 +90,7 @@ void Discord_Register(const char* applicationId, const char* command)
fprintf(stderr, "Failed to register mime handler\n");
}
void Discord_RegisterSteamGame(
const char* applicationId,
const char* steamId)
void Discord_RegisterSteamGame(const char *applicationId, const char *steamId)
{
char command[256];
snprintf(command, sizeof(command), "xdg-open steam://rungameid/%s", steamId);
+40 -39
View File
@@ -3,7 +3,10 @@
#import <AppKit/AppKit.h>
#include "../include/discord_register.h"
int get_process_id(void)
{
return getpid();
}
static void RegisterCommand(const char* applicationId, const char* command)
{
@@ -31,54 +34,52 @@ static void RegisterCommand(const char* applicationId, const char* command)
static void RegisterURL(const char* applicationId)
{
char url[256];
snprintf(url, sizeof(url), "discord-%s", applicationId);
CFStringRef cfURL = CFStringCreateWithCString(NULL, url, kCFStringEncodingUTF8);
NSString* myBundleId = [[NSBundle mainBundle] bundleIdentifier];
char url[256];
snprintf(url, sizeof(url), "discord-%s", applicationId);
CFStringRef cfURL = CFStringCreateWithCString(NULL, url, kCFStringEncodingUTF8);
NSString* myBundleId = [[NSBundle mainBundle] bundleIdentifier];
if (!myBundleId)
{
fprintf(stderr, "No bundle id found\n");
return;
}
if (!myBundleId)
{
fprintf(stderr, "No bundle id found\n");
return;
}
NSURL* myURL = [[NSBundle mainBundle] bundleURL];
if (!myURL)
{
fprintf(stderr, "No bundle url found\n");
return;
}
NSURL* myURL = [[NSBundle mainBundle] bundleURL];
if (!myURL)
{
fprintf(stderr, "No bundle url found\n");
return;
}
OSStatus status = LSSetDefaultHandlerForURLScheme(cfURL, (__bridge CFStringRef)myBundleId);
if (status != noErr)
{
fprintf(stderr, "Error in LSSetDefaultHandlerForURLScheme: %d\n", (int)status);
return;
}
OSStatus status = LSSetDefaultHandlerForURLScheme(cfURL, (__bridge CFStringRef)myBundleId);
if (status != noErr)
{
fprintf(stderr, "Error in LSSetDefaultHandlerForURLScheme: %d\n", (int)status);
return;
}
status = LSRegisterURL((__bridge CFURLRef)myURL, true);
if (status != noErr)
{
fprintf(stderr, "Error in LSRegisterURL: %d\n", (int)status);
}
status = LSRegisterURL((__bridge CFURLRef)myURL, true);
if (status != noErr)
fprintf(stderr, "Error in LSRegisterURL: %d\n", (int)status);
}
void Discord_Register(const char* applicationId, const char* command)
{
if (command)
RegisterCommand(applicationId, command);
else
{
/* RAII Lite */
@autoreleasepool {
RegisterURL(applicationId);
}
}
if (command)
RegisterCommand(applicationId, command);
else
{
/* RAII Lite */
@autoreleasepool {
RegisterURL(applicationId);
}
}
}
void Discord_RegisterSteamGame(const char* applicationId, const char* steamId)
{
char command[256];
snprintf(command, sizeof(command), "steam://rungameid/%s", steamId);
Discord_Register(applicationId, command);
char command[256];
snprintf(command, sizeof(command), "steam://rungameid/%s", steamId);
Discord_Register(applicationId, command);
}
+80 -75
View File
@@ -1,5 +1,4 @@
#include "discord_rpc.h"
#include "discord_register.h"
#define WIN32_LEAN_AND_MEAN
#define NOMCX
@@ -10,6 +9,11 @@
#include <wchar.h>
#include <stdio.h>
int get_process_id(void)
{
return (int)GetCurrentProcessId();
}
/**
* Updated fixes for MinGW and WinXP
* This block is written the way it does not involve changing the rest of the code
@@ -53,99 +57,99 @@ static LSTATUS regset(HKEY hkey,
const void* data,
DWORD len)
{
HKEY htkey = hkey, hsubkey = NULL;
LSTATUS ret;
if (subkey && subkey[0])
{
if ((ret = RegCreateKeyExW(hkey, subkey, 0, 0, 0, KEY_ALL_ACCESS, 0, &hsubkey, 0)) !=
LSTATUS ret;
HKEY htkey = hkey, hsubkey = NULL;
if (subkey && subkey[0])
{
if ((ret = RegCreateKeyExW(hkey, subkey, 0, 0, 0, KEY_ALL_ACCESS, 0, &hsubkey, 0)) !=
ERROR_SUCCESS)
return ret;
htkey = hsubkey;
}
ret = RegSetValueExW(htkey, name, 0, type, (const BYTE*)data, len);
if (hsubkey && hsubkey != hkey)
RegCloseKey(hsubkey);
return ret;
return ret;
htkey = hsubkey;
}
ret = RegSetValueExW(htkey, name, 0, type, (const BYTE*)data, len);
if (hsubkey && hsubkey != hkey)
RegCloseKey(hsubkey);
return ret;
}
static void Discord_RegisterW(
const wchar_t* applicationId, const wchar_t* command)
{
/* https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
* we want to register games so we can run them as discord-<appid>://
* Update the HKEY_CURRENT_USER, because it doesn't seem to require special permissions. */
/* https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
* we want to register games so we can run them as discord-<appid>://
* Update the HKEY_CURRENT_USER, because it doesn't seem to require special permissions. */
DWORD len;
LSTATUS result;
wchar_t urlProtocol = 0;
wchar_t keyName[256];
wchar_t protocolName[64];
wchar_t protocolDescription[128];
wchar_t exeFilePath[MAX_PATH];
DWORD exeLen = GetModuleFileNameW(NULL, exeFilePath, MAX_PATH);
wchar_t openCommand[1024];
DWORD len;
LSTATUS result;
wchar_t urlProtocol = 0;
wchar_t keyName[256];
wchar_t protocolName[64];
wchar_t protocolDescription[128];
wchar_t exeFilePath[MAX_PATH];
DWORD exeLen = GetModuleFileNameW(NULL, exeFilePath, MAX_PATH);
wchar_t openCommand[1024];
if (command && command[0])
StringCbPrintfW(openCommand, sizeof(openCommand), L"%S", command);
else
StringCbPrintfW(openCommand, sizeof(openCommand), L"%S", exeFilePath);
if (command && command[0])
StringCbPrintfW(openCommand, sizeof(openCommand), L"%S", command);
else
StringCbPrintfW(openCommand, sizeof(openCommand), L"%S", exeFilePath);
StringCbPrintfW(protocolName, sizeof(protocolName),
L"discord-%S", applicationId);
StringCbPrintfW(
protocolDescription, sizeof(protocolDescription),
L"URL:Run game %S protocol", applicationId);
StringCbPrintfW(keyName, sizeof(keyName), L"Software\\Classes\\%S", protocolName);
HKEY key;
LSTATUS status =
StringCbPrintfW(protocolName, sizeof(protocolName),
L"discord-%S", applicationId);
StringCbPrintfW(
protocolDescription, sizeof(protocolDescription),
L"URL:Run game %S protocol", applicationId);
StringCbPrintfW(keyName, sizeof(keyName), L"Software\\Classes\\%S", protocolName);
HKEY key;
LSTATUS status =
RegCreateKeyExW(HKEY_CURRENT_USER, keyName, 0, NULL, 0, KEY_WRITE, NULL, &key, NULL);
if (status != ERROR_SUCCESS)
{
fprintf(stderr, "Error creating key\n");
return;
}
len = (DWORD)lstrlenW(protocolDescription) + 1;
result =
if (status != ERROR_SUCCESS)
{
fprintf(stderr, "Error creating key\n");
return;
}
len = (DWORD)lstrlenW(protocolDescription) + 1;
result =
RegSetKeyValueW(key, NULL, NULL, REG_SZ, protocolDescription, len * sizeof(wchar_t));
if (FAILED(result)) {
fprintf(stderr, "Error writing description\n");
}
if (FAILED(result))
fprintf(stderr, "Error writing description\n");
len = (DWORD)lstrlenW(protocolDescription) + 1;
result = RegSetKeyValueW(key, NULL, L"URL Protocol", REG_SZ, &urlProtocol, sizeof(wchar_t));
if (FAILED(result))
fprintf(stderr, "Error writing description\n");
len = (DWORD)lstrlenW(protocolDescription) + 1;
result = RegSetKeyValueW(key, NULL, L"URL Protocol", REG_SZ, &urlProtocol, sizeof(wchar_t));
if (FAILED(result))
fprintf(stderr, "Error writing description\n");
result = RegSetKeyValueW(
key, L"DefaultIcon", NULL, REG_SZ, exeFilePath, (exeLen + 1) * sizeof(wchar_t));
if (FAILED(result))
fprintf(stderr, "Error writing icon\n");
result = RegSetKeyValueW(
key, L"DefaultIcon", NULL, REG_SZ, exeFilePath, (exeLen + 1) * sizeof(wchar_t));
if (FAILED(result))
fprintf(stderr, "Error writing icon\n");
len = (DWORD)lstrlenW(openCommand) + 1;
result = RegSetKeyValueW(
key, L"shell\\open\\command", NULL, REG_SZ, openCommand, len * sizeof(wchar_t));
if (FAILED(result))
fprintf(stderr, "Error writing command\n");
RegCloseKey(key);
len = (DWORD)lstrlenW(openCommand) + 1;
result = RegSetKeyValueW(
key, L"shell\\open\\command", NULL, REG_SZ, openCommand, len * sizeof(wchar_t));
if (FAILED(result))
fprintf(stderr, "Error writing command\n");
RegCloseKey(key);
}
void Discord_Register(const char* applicationId, const char* command)
{
wchar_t openCommand[1024];
const wchar_t* wcommand = NULL;
wchar_t appId[32];
wchar_t appId[32];
wchar_t openCommand[1024];
const wchar_t* wcommand = NULL;
MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32);
if (command && command[0])
{
const int commandBufferLen =
sizeof(openCommand) / sizeof(*openCommand);
MultiByteToWideChar(CP_UTF8, 0, command, -1,
openCommand, commandBufferLen);
wcommand = openCommand;
}
MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32);
Discord_RegisterW(appId, wcommand);
if (command && command[0])
{
const int commandBufferLen =
sizeof(openCommand) / sizeof(*openCommand);
MultiByteToWideChar(CP_UTF8, 0, command, -1,
openCommand, commandBufferLen);
wcommand = openCommand;
}
Discord_RegisterW(appId, wcommand);
}
void Discord_RegisterSteamGame(
@@ -172,7 +176,8 @@ void Discord_RegisterSteamGame(
status = RegQueryValueExW(key,
L"SteamExe", NULL, NULL, (BYTE*)steamPath, &pathBytes);
RegCloseKey(key);
if (status != ERROR_SUCCESS || pathBytes < 1) {
if (status != ERROR_SUCCESS || pathBytes < 1)
{
fprintf(stderr, "Error reading SteamExe key\n");
return;
}
+86 -83
View File
@@ -1,7 +1,7 @@
#include "discord_rpc.h"
#include "discord_register.h"
#include "backoff.h"
#include "discord_register.h"
#include "msg_queue.h"
#include "rpc_connection.h"
#include "serialization.h"
@@ -15,14 +15,10 @@
#include <thread>
#endif
constexpr size_t MaxMessageSize{16 * 1024};
constexpr size_t MessageQueueSize{8};
constexpr size_t JoinQueueSize{8};
struct QueuedMessage
{
size_t length;
char buffer[MaxMessageSize];
char buffer[16384];
void Copy(const QueuedMessage& other)
{
@@ -50,25 +46,32 @@ struct User
* from future changes in these sizes */
};
static int Pid{0};
static int Nonce{1};
static int LastErrorCode{0};
static int LastDisconnectErrorCode{0};
static char JoinGameSecret[256];
static char SpectateGameSecret[256];
static char LastErrorMessage[256];
static char LastDisconnectErrorMessage[256];
static RpcConnection* Connection{nullptr};
static DiscordEventHandlers QueuedHandlers{};
static DiscordEventHandlers Handlers{};
static std::atomic_bool WasJustConnected{false};
static std::atomic_bool WasJustDisconnected{false};
static std::atomic_bool GotErrorMessage{false};
static std::atomic_bool WasJoinGame{false};
static std::atomic_bool WasSpectateGame{false};
static char JoinGameSecret[256];
static char SpectateGameSecret[256];
static int LastErrorCode{0};
static char LastErrorMessage[256];
static int LastDisconnectErrorCode{0};
static char LastDisconnectErrorMessage[256];
static std::mutex PresenceMutex;
static std::mutex HandlerMutex;
static QueuedMessage QueuedPresence{};
static MsgQueue<QueuedMessage, MessageQueueSize> SendQueue;
static MsgQueue<User, JoinQueueSize> JoinAskQueue;
static MsgQueue<QueuedMessage, 8> SendQueue;
static MsgQueue<User, 8> JoinAskQueue;
static User connectedUser;
/* We want to auto connect, and retry on failure,
@@ -76,64 +79,64 @@ static User connectedUser;
* backoff from 0.5 seconds to 1 minute */
static Backoff ReconnectTimeMs(500, 60 * 1000);
static auto NextConnect = std::chrono::system_clock::now();
static int Pid{0};
static int Nonce{1};
#ifndef DISCORD_DISABLE_IO_THREAD
static void Discord_UpdateConnection(void);
class IoThreadHolder {
private:
std::atomic_bool keepRunning{true};
std::mutex waitForIOMutex;
std::condition_variable waitForIOActivity;
std::thread ioThread;
class IoThreadHolder
{
private:
std::atomic_bool keepRunning{true};
std::mutex waitForIOMutex;
std::condition_variable waitForIOActivity;
std::thread ioThread;
public:
void Start()
{
keepRunning.store(true);
ioThread = std::thread([&]() {
const std::chrono::duration<int64_t, std::milli> maxWait{500LL};
Discord_UpdateConnection();
while (keepRunning.load()) {
std::unique_lock<std::mutex> lock(waitForIOMutex);
waitForIOActivity.wait_for(lock, maxWait);
Discord_UpdateConnection();
}
});
}
public:
void Start()
{
keepRunning.store(true);
ioThread = std::thread([&]() {
const std::chrono::duration<int64_t, std::milli> maxWait{500LL};
Discord_UpdateConnection();
while (keepRunning.load()) {
std::unique_lock<std::mutex> lock(waitForIOMutex);
waitForIOActivity.wait_for(lock, maxWait);
Discord_UpdateConnection();
}
});
}
void Notify() { waitForIOActivity.notify_all(); }
void Notify() { waitForIOActivity.notify_all(); }
void Stop()
{
keepRunning.exchange(false);
Notify();
if (ioThread.joinable())
void Stop()
{
keepRunning.exchange(false);
Notify();
if (ioThread.joinable())
ioThread.join();
}
}
~IoThreadHolder() { Stop(); }
~IoThreadHolder() { Stop(); }
};
#else
class IoThreadHolder {
public:
void Start() {}
void Stop() {}
void Notify() {}
class IoThreadHolder
{
public:
void Start() {}
void Stop() {}
void Notify() {}
};
#endif /* DISCORD_DISABLE_IO_THREAD */
static IoThreadHolder* IoThread{nullptr};
static void UpdateReconnectTime()
static void UpdateReconnectTime(void)
{
NextConnect = std::chrono::system_clock::now() +
std::chrono::duration<int64_t, std::milli>{ReconnectTimeMs.nextDelay()};
}
#ifdef DISCORD_DISABLE_IO_THREAD
extern "C" DISCORD_EXPORT void Discord_UpdateConnection(void)
extern "C" void Discord_UpdateConnection(void)
#else
static void Discord_UpdateConnection(void)
#endif
@@ -160,18 +163,18 @@ static void Discord_UpdateConnection(void)
if (!Connection->Read(message))
break;
const char* evtName = GetStrMember(&message, "evt");
const char* nonce = GetStrMember(&message, "nonce");
const char *evtName = GetStrMember(&message, "evt");
const char *nonce = GetStrMember(&message, "nonce");
if (nonce)
{
/* in responses only --
* should use to match up response when needed. */
if (evtName && strcmp(evtName, "ERROR") == 0)
if (evtName && !strcmp(evtName, "ERROR"))
{
auto data = GetObjMember(&message, "data");
LastErrorCode = GetIntMember(data, "code");
JsonValue *data = GetObjMember(&message, "data");
LastErrorCode = GetIntMember(data, "code");
StringCopy(LastErrorMessage, GetStrMember(data, "message", ""));
GotErrorMessage.store(true);
}
@@ -182,39 +185,40 @@ static void Discord_UpdateConnection(void)
if (!evtName)
continue;
auto data = GetObjMember(&message, "data");
JsonValue *data = GetObjMember(&message, "data");
if (strcmp(evtName, "ACTIVITY_JOIN") == 0)
if (!strcmp(evtName, "ACTIVITY_JOIN"))
{
auto secret = GetStrMember(data, "secret");
const char *secret = GetStrMember(data, "secret");
if (secret)
{
StringCopy(JoinGameSecret, secret);
WasJoinGame.store(true);
}
}
else if (strcmp(evtName, "ACTIVITY_SPECTATE") == 0)
else if (!strcmp(evtName, "ACTIVITY_SPECTATE"))
{
auto secret = GetStrMember(data, "secret");
const char *secret = GetStrMember(data, "secret");
if (secret)
{
StringCopy(SpectateGameSecret, secret);
WasSpectateGame.store(true);
}
}
else if (strcmp(evtName, "ACTIVITY_JOIN_REQUEST") == 0)
else if (!strcmp(evtName, "ACTIVITY_JOIN_REQUEST"))
{
auto user = GetObjMember(data, "user");
auto userId = GetStrMember(user, "id");
auto username = GetStrMember(user, "username");
auto avatar = GetStrMember(user, "avatar");
auto joinReq = JoinAskQueue.GetNextAddMessage();
JsonValue *user = GetObjMember(data, "user");
const char *userId = GetStrMember(user, "id");
const char *username = GetStrMember(user, "username");
const char *avatar = GetStrMember(user, "avatar");
auto joinReq = JoinAskQueue.GetNextAddMessage();
if (userId && username && joinReq)
{
StringCopy(joinReq->userId, userId);
StringCopy(joinReq->username, username);
auto discriminator = GetStrMember(user, "discriminator");
const char *discriminator = GetStrMember(user,
"discriminator");
if (discriminator)
StringCopy(joinReq->discriminator, discriminator);
if (avatar)
@@ -283,7 +287,7 @@ static bool DeregisterForEvent(const char* evtName)
return false;
}
extern "C" DISCORD_EXPORT void Discord_Initialize(
extern "C" void Discord_Initialize(
const char* applicationId,
DiscordEventHandlers* handlers,
int autoRegister,
@@ -301,7 +305,7 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(
Discord_Register(applicationId, nullptr);
}
Pid = GetProcessId();
Pid = get_process_id();
{
std::lock_guard<std::mutex> guard(HandlerMutex);
@@ -321,16 +325,16 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(
Connection->onConnect = [](JsonDocument& readyMessage)
{
Discord_UpdateHandlers(&QueuedHandlers);
auto data = GetObjMember(&readyMessage, "data");
auto user = GetObjMember(data, "user");
auto userId = GetStrMember(user, "id");
auto username = GetStrMember(user, "username");
auto avatar = GetStrMember(user, "avatar");
JsonValue *data = GetObjMember(&readyMessage, "data");
JsonValue *user = GetObjMember(data, "user");
const char *userId = GetStrMember(user, "id");
const char *username = GetStrMember(user, "username");
const char *avatar = GetStrMember(user, "avatar");
if (userId && username)
{
StringCopy(connectedUser.userId, userId);
StringCopy(connectedUser.username, username);
auto discriminator = GetStrMember(user, "discriminator");
const char *discriminator = GetStrMember(user, "discriminator");
if (discriminator)
StringCopy(connectedUser.discriminator, discriminator);
if (avatar)
@@ -356,7 +360,7 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(
IoThread->Start();
}
extern "C" DISCORD_EXPORT void Discord_Shutdown(void)
extern "C" void Discord_Shutdown(void)
{
if (!Connection)
return;
@@ -373,8 +377,7 @@ extern "C" DISCORD_EXPORT void Discord_Shutdown(void)
RpcConnection::Destroy(Connection);
}
extern "C" DISCORD_EXPORT void
Discord_UpdatePresence(const DiscordRichPresence* presence)
extern "C" void Discord_UpdatePresence(const DiscordRichPresence* presence)
{
{
std::lock_guard<std::mutex> guard(PresenceMutex);
@@ -385,12 +388,12 @@ Discord_UpdatePresence(const DiscordRichPresence* presence)
IoThread->Notify();
}
extern "C" DISCORD_EXPORT void Discord_ClearPresence(void)
extern "C" void Discord_ClearPresence(void)
{
Discord_UpdatePresence(nullptr);
}
extern "C" DISCORD_EXPORT void Discord_Respond(const char* userId, /* DISCORD_REPLY_ */ int reply)
extern "C" void Discord_Respond(const char* userId, /* DISCORD_REPLY_ */ int reply)
{
/* if we are not connected, let's not batch up stale messages for later */
if (!Connection || !Connection->IsOpen())
@@ -406,7 +409,7 @@ extern "C" DISCORD_EXPORT void Discord_Respond(const char* userId, /* DISCORD_RE
}
}
extern "C" DISCORD_EXPORT void Discord_RunCallbacks(void)
extern "C" void Discord_RunCallbacks(void)
{
/* Note on some weirdness: internally we might connect, get other signals, disconnect any number
* of times inbetween calls here. Externally, we want the sequence to seem sane, so any other
@@ -498,7 +501,7 @@ extern "C" DISCORD_EXPORT void Discord_RunCallbacks(void)
DeregisterForEvent(event)
#endif
extern "C" DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* newHandlers)
extern "C" void Discord_UpdateHandlers(DiscordEventHandlers* newHandlers)
{
if (newHandlers)
{
+5 -4
View File
@@ -3,7 +3,8 @@
#include <atomic>
static const int RpcVersion = 1;
#define RPC_VERSION 1
static RpcConnection Instance;
/*static*/ RpcConnection* RpcConnection::Create(const char* applicationId)
@@ -36,8 +37,8 @@ void RpcConnection::Open()
JsonDocument message;
if (Read(message))
{
auto cmd = GetStrMember(&message, "cmd");
auto evt = GetStrMember(&message, "evt");
const char *cmd = GetStrMember(&message, "cmd");
const char *evt = GetStrMember(&message, "evt");
if (cmd && evt
&& !strcmp(cmd, "DISPATCH")
&& !strcmp(evt, "READY"))
@@ -52,7 +53,7 @@ void RpcConnection::Open()
{
sendFrame.opcode = Opcode::Handshake;
sendFrame.length = (uint32_t)JsonWriteHandshakeObj(
sendFrame.message, sizeof(sendFrame.message), RpcVersion, appId);
sendFrame.message, sizeof(sendFrame.message), RPC_VERSION, appId);
if (connection->Write(&sendFrame,
sizeof(MessageFrameHeader) + sendFrame.length))
+2 -2
View File
@@ -5,7 +5,7 @@
/* I took this from the buffer size libuv uses for named pipes;
* I suspect ours would usually be much smaller. */
constexpr size_t MaxRpcFrameSize = 64 * 1024;
#define MAX_RPC_FRAMESIZE 65536
struct RpcConnection
{
@@ -33,7 +33,7 @@ struct RpcConnection
struct MessageFrame : public MessageFrameHeader
{
char message[MaxRpcFrameSize - sizeof(MessageFrameHeader)];
char message[MAX_RPC_FRAMESIZE - sizeof(MessageFrameHeader)];
};
enum class State : uint32_t
-5
View File
@@ -1162,19 +1162,14 @@ void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct st
0,
u8array_to_u16 (entry->entryData, DIR_ENTRY_aDate)
);
st->st_spare1 = 0;
st->st_mtime = _FAT_filetime_to_time_t (
u8array_to_u16 (entry->entryData, DIR_ENTRY_mTime),
u8array_to_u16 (entry->entryData, DIR_ENTRY_mDate)
);
st->st_spare2 = 0;
st->st_ctime = _FAT_filetime_to_time_t (
u8array_to_u16 (entry->entryData, DIR_ENTRY_cTime),
u8array_to_u16 (entry->entryData, DIR_ENTRY_cDate)
);
st->st_spare3 = 0;
st->st_blksize = partition->bytesPerSector; /* Prefered file I/O block size */
st->st_blocks = (st->st_size + partition->bytesPerSector - 1) / partition->bytesPerSector; /* File size in blocks */
st->st_spare4[0] = 0;
st->st_spare4[1] = 0;
}
+112 -113
View File
@@ -36,134 +36,133 @@ Email: [email protected]
PSVITA performances test results:
RUNFAST: Enabled
RUNFAST: Disabled
------------------------------------------------------------------------------------------------------
MATRIX FUNCTION TESTS
------------------------------------------------------------------------------------------------------
matmul2_c =
|-7.16, 9.42|
|17.86, -10.70|
|-14.56, 5.96|
|-15.35, 10.50|
matmul2_neon =
|-7.16, 9.42|
|17.86, -10.70|
matmul2: c=183985 neon=87480 rate=2.10
matvec2_c = |-7.16, 17.86|
matvec2_neon = |-7.16, 17.86|
matvec2: c=98178 neon=66040 rate=1.49
|-14.56, 5.96|
|-15.35, 10.50|
matmul2: c=174924 neon=64490 rate=2.71
matvec2_c = |-14.56, -15.35|
matvec2_neon = |-14.56, -15.35|
matvec2: c=88957 neon=58337 rate=1.52
matmul3_c =
|11.14, -0.78, -3.98|
|16.56, 17.96, 23.58|
|8.73, -0.18, 1.57|
|-21.39, -4.68, -1.74|
|-8.66, -8.97, 1.83|
|15.88, 0.30, -2.23|
matmul3_neon =
|11.14, -0.78, -3.98|
|16.56, 17.96, 23.58|
|8.73, -0.18, 1.57|
matmul3: c=551838 neon=340292 rate=1.62
matvec3_c = |11.14, 16.56, 8.73|
matvec3_neon = |11.14, 16.56, 8.73|
matvec3: c=98178 neon=66040 rate=1.49
|-21.39, -4.68, -1.74|
|-8.66, -8.97, 1.83|
|15.88, 0.30, -2.23|
matmul3: c=552486 neon=297268 rate=1.86
matvec3_c = |-21.39, -8.66, 15.88|
matvec3_neon = |-21.39, -8.66, 15.88|
matvec3: c=184104 neon=128780 rate=1.43
matmul4_c =
|17.91, -23.96, 1.86, 16.53|
|4.10, -18.16, 4.17, 29.06|
|6.92, -1.60, 3.12, 27.81|
|-15.13, -7.46, -17.91, 22.49|
|-13.65, -1.80, -12.92, 6.56|
|-10.21, 9.47, 2.73, 14.79|
|0.97, 11.69, -0.64, -12.87|
|20.06, 6.77, 35.61, -0.02|
matmul4_neon =
|17.91, -23.96, 1.86, 16.53|
|4.10, -18.16, 4.17, 29.06|
|6.92, -1.60, 3.12, 27.81|
|-15.13, -7.46, -17.91, 22.49|
matmul4: c=1316131 neon=315444 rate=4.17
matvec4_c = |17.91, 4.10, 6.92, -15.126419|
matvec4_neon = |17.91, 4.10, 6.92, -15.126419|
matvec4: c=98178 neon=66040 rate=1.49
|-13.65, -1.80, -12.92, 6.56|
|-10.21, 9.47, 2.73, 14.79|
|0.97, 11.69, -0.64, -12.87|
|20.06, 6.77, 35.61, -0.02|
matmul4: c=1315568 neon=254227 rate=5.17
matvec4_c = |-13.65, -10.21, 0.97, 20.058556|
matvec4_neon = |-13.65, -10.21, 0.97, 20.058556|
matvec4: c=331712 neon=147196 rate=2.25
dot2_c = 5.804099
dot2_neon = 5.804099
dot2: c=291526 neon=307025 rate=0.95
normalize2_c = [0.97, 0.24]
normalize2_neon = [0.97, 0.24]
normalize2: c=1058588 neon=965696 rate=1.10
dot2_c = -10.903330
dot2_neon = -10.903330
dot2: c=230295 neon=168799 rate=1.36
normalize2_c = [-0.74, 0.67]
normalize2_neon = [-0.74, 0.67]
normalize2: c=950716 neon=965780 rate=0.98
dot3_c = -0.817487
dot3_neon = -0.817487
dot3: c=322094 neon=444834 rate=0.72
normalize3_c = [0.50, 0.12, -0.86]
normalize3_neon = [0.50, 0.12, -0.86]
normalize3: c=1257201 neon=1134375 rate=1.11
cross3_c = [-13.16, -17.29, -10.19]
cross3_neon = [-13.16, -17.29, -10.19]
cross3: c=705298 neon=766477 rate=0.92
dot3_c = -4.226746
dot3_neon = -4.226746
dot3: c=306957 neon=337316 rate=0.91
normalize3_c = [-0.69, 0.62, -0.38]
normalize3_neon = [-0.69, 0.62, -0.38]
normalize3: c=1180950 neon=1134557 rate=1.04
cross3_c = [-9.67, -19.39, -14.24]
cross3_neon = [-9.67, -19.39, -14.24]
cross3: c=659558 neon=766896 rate=0.86
dot4_c = -7.880241
dot4_neon = -7.880241
dot4: c=414431 neon=506460 rate=0.82
normalize4_c = [0.45, 0.11, -0.77, -0.44]
normalize4_neon = [0.45, 0.11, -0.77, -0.44]
normalize4: c=1410727 neon=1102802 rate=1.28
dot4_c = 2.782796
dot4_neon = 2.782796
dot4: c=414233 neon=276068 rate=1.50
normalize4_c = [-0.59, 0.53, -0.32, -0.52]
normalize4_neon = [-0.59, 0.53, -0.32, -0.52]
normalize4: c=1364294 neon=1103327 rate=1.24
------------------------------------------------------------------------------------------------------
CMATH FUNCTION TESTS
------------------------------------------------------------------------------------------------------
Function Range Number ABS Max Error REL Max Error RMS Error Time Rate
------------------------------------------------------------------------------------------------------
sinf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 647042739 x1.00
sinf_c [-3.14, 3.14] 500000 7.75e-07 1.00e+02% 4.09e-07 646276691 x1.00
sinf_neon [-3.14, 3.14] 500000 1.00e+00 1.00e+02% 7.07e-01 645546381 x1.00
cosf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 644742077 x1.00
cosf_c [-3.14, 3.14] 500000 7.75e-07 6.74e-01% 4.15e-07 643957358 x1.00
cosf_neon [-3.14, 3.14] 500000 1.00e+00 1.00e+02% 7.06e-01 643211256 x1.00
tanf [-0.79, 0.79] 500000 0.00e+00 0.00e+00% 0.00e+00 642444112 x1.00
tanf_c [-0.79, 0.79] 500000 2.98e-06 7.94e-04% 1.31e-06 641628507 x1.00
tanf_neon [-0.79, 0.79] 500000 1.00e+00 1.00e+02% nan 640740514 x1.00
asinf [-1.00, 1.00] 500000 0.00e+00 0.00e+00% 0.00e+00 639560380 x1.00
asinf_c [-1.00, 1.00] 500000 5.54e-05 1.06e-02% nan 638453383 x1.00
asinf_neon [-1.00, 1.00] 500000 1.57e+00 1.00e+02% 6.84e-01 637349653 x1.00
acosf [-1.00, 1.00] 500000 0.00e+00 0.00e+00% 0.00e+00 636078992 x1.00
acosf_c [-1.00, 1.00] 500000 5.56e-05 6.46e-03% nan 634934201 x1.00
acosf_neon [-1.00, 1.00] 500000 1.57e+00 1.02e+05% 6.84e-01 633793585 x1.00
atanf [-1.00, 1.00] 500000 0.00e+00 0.00e+00% 0.00e+00 632835241 x1.00
atanf_c [-1.00, 1.00] 500000 1.67e-04 2.12e-02% 7.40e-05 632142823 x1.00
atanf_neon [-1.00, 1.00] 500000 7.85e-01 0.00e+00% nan 631387330 x1.00
sinhf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 630142014 x1.00
sinhf_c [-3.14, 3.14] 500000 1.91e-06 1.52e-01% 1.85e-07 628992714 x1.00
sinhf_neon [-3.14, 3.14] 500000 1.15e+01 1.00e+02% 4.55e+00 627998454 x1.00
coshf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 626869866 x1.00
coshf_c [-3.14, 3.14] 500000 9.54e-07 2.38e-05% 1.64e-07 625829657 x1.00
coshf_neon [-3.14, 3.14] 500000 1.06e+01 9.14e+01% 3.92e+00 624873969 x1.00
tanhf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 623689093 x1.00
tanhf_c [-3.14, 3.14] 500000 1.20e-05 2.48e-01% 5.48e-06 622547097 x1.00
tanhf_neon [-3.14, 3.14] 500000 9.96e-01 1.00e+02% 8.26e-01 621506812 x1.00
expf [0.00, 10.00] 500000 0.00e+00 0.00e+00% 0.00e+00 620497304 x1.00
expf_c [0.00, 10.00] 500000 9.77e-03 6.15e-05% 1.64e-03 619569554 x1.00
expf_neon [0.00, 10.00] 500000 2.20e+04 1.00e+02% 4.92e+03 618761400 x1.00
logf [1.00, 1000.00] 500000 0.00e+00 0.00e+00% 0.00e+00 617882765 x1.00
logf_c [1.00, 1000.00] 500000 6.20e-06 1.62e-02% 9.83e-07 617087810 x1.00
logf_neon [1.00, 1000.00] 500000 9.49e+01 inf% 9.39e+01 616388420 x1.00
log10f [1.00, 1000.00] 500000 0.00e+00 0.00e+00% 0.00e+00 615405364 x1.00
log10f_c [1.00, 1000.00] 500000 2.86e-06 6.68e-03% 4.79e-07 614442585 x1.00
log10f_neon [1.00, 1000.00] 500000 4.12e+01 inf% 4.07e+01 613671782 x1.00
floorf [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 611113689 x1.00
floorf_c [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 608159325 x1.00
floorf_neon [1.00, 1000.00] 5000000 2.00e+00 2.00e+02% 1.42e-02 604769008 x1.01
ceilf [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 601342443 x1.00
ceilf_c [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 598387998 x1.00
ceilf_neon [1.00, 1000.00] 5000000 2.00e+00 1.00e+02% 1.02e+00 594959710 x1.01
fabsf [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 592068236 x1.00
fabsf_c [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 589808748 x1.00
fabsf_neon [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 587712180 x1.01
sqrtf [1.00, 1000.00] 500000 0.00e+00 0.00e+00% 0.00e+00 586496654 x1.00
sqrtf_c [1.00, 1000.00] 500000 2.33e-04 1.06e-03% 8.69e-05 585470866 x1.00
sqrtf_neon [1.00, 1000.00] 500000 0.00e+00 0.00e+00% nan 584594551 x1.00
invsqrtf [1.00, 1000.00] 500000 0.00e+00 0.00e+00% 0.00e+00 583492213 x1.00
invsqrtf_c [1.00, 1000.00] 500000 4.35e-06 4.78e-04% 2.00e-07 582448164 x1.00
invsqrtf_neon [1.00, 1000.00] 500000 0.00e+00 0.00e+00% nan 581642365 x1.00
atan2f [0.10, 10.00] 10000 0.00e+00 0.00e+00% 0.00e+00 83594269 x1.00
atan2f_c [0.10, 10.00] 10000 1.73e-04 2.23e-02% 0.00e+00 85383651 x0.98
atan2f_neon [0.10, 10.00] 10000 0.00e+00 0.00e+00% 0.00e+00 87387055 x0.96
powf [1.00, 10.00] 10000 0.00e+00 0.00e+00% 0.00e+00 93430489 x1.00
powf_c [1.00, 10.00] 10000 1.08e+05 4.37e-03% 0.00e+00 96726976 x0.97
powf_neon [1.00, 10.00] 10000 9.97e+09 1.00e+02% 0.00e+00 100185753 x0.93
fmodf [1.00, 10.00] 10000 0.00e+00 0.00e+00% 0.00e+00 101653673 x1.00
fmodf_c [1.00, 10.00] 10000 9.90e+00 8.06e-02% 0.00e+00 103177551 x0.99
fmodf_neon [1.00, 10.00] 10000 9.99e+00 1.00e+02% 0.00e+00 104771240 x0.97
sinf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 1394459996 x1.00
sinf_c [-3.14, 3.14] 500000 7.75e-07 1.00e+02% 4.09e-07 1395128226 x1.00
sinf_neon [-3.14, 3.14] 500000 8.34e-07 1.00e+02% 4.09e-07 1395853554 x1.00
cosf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 1396644271 x1.00
cosf_c [-3.14, 3.14] 500000 7.75e-07 6.74e-01% 4.15e-07 1397360321 x1.00
cosf_neon [-3.14, 3.14] 500000 8.34e-07 6.74e-01% 4.16e-07 1398126872 x1.00
tanf [-0.79, 0.79] 500000 0.00e+00 0.00e+00% 0.00e+00 1398889596 x1.00
tanf_c [-0.79, 0.79] 500000 2.98e-06 7.94e-04% 1.31e-06 1399704712 x1.00
tanf_neon [-0.79, 0.79] 500000 1.91e-06 3.62e-04% 6.66e-07 1400612899 x1.00
asinf [-1.00, 1.00] 500000 0.00e+00 0.00e+00% 0.00e+00 1401838993 x1.00
asinf_c [-1.00, 1.00] 500000 5.54e-05 1.06e-02% nan 1402745512 x1.00
asinf_neon [-1.00, 1.00] 500000 4.66e-05 8.90e-03% nan 1403967661 x1.00
acosf [-1.00, 1.00] 500000 0.00e+00 0.00e+00% 0.00e+00 1405317842 x1.00
acosf_c [-1.00, 1.00] 500000 5.56e-05 6.46e-03% nan 1406294753 x1.00
acosf_neon [-1.00, 1.00] 500000 4.67e-05 6.35e-03% nan 1407598039 x1.00
atanf [-1.00, 1.00] 500000 0.00e+00 0.00e+00% 0.00e+00 1408314869 x1.00
atanf_c [-1.00, 1.00] 500000 1.67e-04 2.12e-02% 7.40e-05 1408872421 x1.00
atanf_neon [-1.00, 1.00] 500000 1.67e-04 2.12e-02% 7.40e-05 1409736652 x1.00
sinhf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 1411101066 x1.00
sinhf_c [-3.14, 3.14] 500000 1.91e-06 1.52e-01% 1.85e-07 1412173492 x1.00
sinhf_neon [-3.14, 3.14] 500000 1.91e-06 1.52e-01% 1.90e-07 1413205410 x1.00
coshf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 1414417802 x1.00
coshf_c [-3.14, 3.14] 500000 9.54e-07 2.38e-05% 1.64e-07 1415426083 x1.00
coshf_neon [-3.14, 3.14] 500000 1.91e-06 2.22e-05% 1.68e-07 1416412636 x1.00
tanhf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 1417684273 x1.00
tanhf_c [-3.14, 3.14] 500000 1.20e-05 2.48e-01% 5.48e-06 1418659628 x1.00
tanhf_neon [-3.14, 3.14] 500000 2.38e-07 2.47e-01% 5.40e-08 1419650721 x1.00
expf [0.00, 10.00] 500000 0.00e+00 0.00e+00% 0.00e+00 1420706074 x1.00
expf_c [0.00, 10.00] 500000 9.77e-03 6.15e-05% 1.64e-03 1421444150 x1.00
expf_neon [0.00, 10.00] 500000 9.77e-03 6.58e-05% 1.64e-03 1422203499 x1.00
logf [1.00, 1000.00] 500000 0.00e+00 0.00e+00% 0.00e+00 1423106698 x1.00
logf_c [1.00, 1000.00] 500000 6.20e-06 1.62e-02% 9.83e-07 1423735174 x1.00
logf_neon [1.00, 1000.00] 500000 7.63e-06 1.03e-02% 1.07e-06 1424434406 x1.00
log10f [1.00, 1000.00] 500000 0.00e+00 0.00e+00% 0.00e+00 1425516892 x1.00
log10f_c [1.00, 1000.00] 500000 2.86e-06 6.68e-03% 4.79e-07 1426200368 x1.00
log10f_neon [1.00, 1000.00] 500000 3.34e-06 6.68e-03% 4.84e-07 1426966844 x1.00
floorf [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 1429081993 x1.00
floorf_c [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 1430839273 x1.00
floorf_neon [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 1433474766 x1.00
ceilf [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 1435602956 x1.00
ceilf_c [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 1437403711 x1.00
ceilf_neon [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 1440044970 x1.00
fabsf [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 1441265630 x1.00
fabsf_c [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 1442491716 x1.00
fabsf_neon [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 1443680744 x1.00
sqrtf [1.00, 1000.00] 500000 0.00e+00 0.00e+00% 0.00e+00 1444844144 x1.00
sqrtf_c [1.00, 1000.00] 500000 2.33e-04 1.06e-03% 8.69e-05 1445710342 x1.00
sqrtf_neon [1.00, 1000.00] 500000 7.63e-06 2.91e-05% 1.60e-06 1446544637 x1.00
invsqrtf [1.00, 1000.00] 500000 0.00e+00 0.00e+00% 0.00e+00 1446995307 x1.00
invsqrtf_c [1.00, 1000.00] 500000 4.35e-06 4.78e-04% 2.00e-07 1447471977 x1.00
invsqrtf_neon [1.00, 1000.00] 500000 1.19e-07 2.12e-05% 4.81e-09 1447987675 x1.00
atan2f [0.10, 10.00] 10000 0.00e+00 0.00e+00% 0.00e+00 1449713108 x1.00
atan2f_c [0.10, 10.00] 10000 1.73e-04 2.23e-02% 0.00e+00 1451276575 x1.00
atan2f_neon [0.10, 10.00] 10000 1.67e-04 2.12e-02% 0.00e+00 1453093260 x1.00
powf [1.00, 10.00] 10000 0.00e+00 0.00e+00% 0.00e+00 1458606663 x1.00
powf_c [1.00, 10.00] 10000 1.08e+05 4.37e-03% 0.00e+00 1461584933 x1.00
powf_neon [1.00, 10.00] 10000 1.36e+05 5.88e-03% 0.00e+00 1464702743 x1.00
fmodf [1.00, 10.00] 10000 0.00e+00 0.00e+00% 0.00e+00 1466022029 x1.00
fmodf_c [1.00, 10.00] 10000 9.90e+00 8.06e-02% 0.00e+00 1467403015 x1.00
fmodf_neon [1.00, 10.00] 10000 9.97e+00 8.06e-02% 0.00e+00 1468767755 x1.00
+689
View File
@@ -0,0 +1,689 @@
/*
Math-NEON: Neon Optimised Math Library based on cmath
Contact: lachlan.ts@gmail.com
Copyright (C) 2009 Lachlan Tychsen - Smith aka Adventus
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <math_neon.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#ifdef WIN32
#include <time.h>
#else
#include <sys/time.h>
#include <sys/resource.h>
#endif
#define randf() (rand() / (RAND_MAX + 1.0f))
void LOG(const char *format, ...) {
__gnuc_va_list arg;
va_start(arg, format);
char msg[512];
vsprintf(msg, format, arg);
va_end(arg);
FILE *log = fopen("ux0:/data/mathneon.log", "a+");
if (log != NULL) {
fwrite(msg, 1, strlen(msg), log);
fclose(log);
}
}
struct test1_s {
const char* name;
float (*func)(float); //the function
float (*bench)(float); //the function to benchmark against.
float rng0, rng1;
int num;
float emaxabs;
float xmaxabs;
float emaxrel;
float xmaxrel;
float erms;
int time; //time to execute num functions;
};
struct test2_s {
const char* name;
float (*func)(float, float); //the function
float (*bench)(float, float); //the function to benchmark against.
float rng0, rng1;
int num;
float emaxabs;
float xmaxabs;
float emaxrel;
float xmaxrel;
float erms;
int time; //time to execute num functions;
};
float invsqrtf(float x){
return (1.0f / sqrtf(x));
}
typedef struct test1_s test1_t;
typedef struct test2_s test2_t;
test1_t test1[51] =
{
{"sinf ", sinf, sinf, -M_PI, M_PI, 500000},
{"sinf_c ", sinf_c, sinf, -M_PI, M_PI, 500000},
{"sinf_neon ", sinf_neon, sinf, -M_PI, M_PI, 500000},
{"cosf ", cosf, cosf, -M_PI, M_PI, 500000},
{"cosf_c ", cosf_c, cosf, -M_PI, M_PI, 500000},
{"cosf_neon ", cosf_neon, cosf, -M_PI, M_PI, 500000},
{"tanf ", tanf, tanf, -M_PI_4, M_PI_4, 500000, 0, 0, 0},
{"tanf_c ", tanf_c, tanf, -M_PI_4, M_PI_4, 500000, 0, 0, 0},
{"tanf_neon ", tanf_neon, tanf, -M_PI_4, M_PI_4, 500000, 0, 0, 0},
{"asinf ", asinf, asinf, -1, 1, 500000, 0, 0, 0},
{"asinf_c ", asinf_c, asinf, -1, 1, 500000, 0, 0, 0},
{"asinf_neon ", asinf_neon, asinf, -1, 1, 500000, 0, 0, 0},
{"acosf ", acosf, acosf, -1, 1, 500000, 0, 0, 0},
{"acosf_c ", acosf_c, acosf, -1, 1, 500000, 0, 0, 0},
{"acosf_neon ", acosf_neon, acosf, -1, 1, 500000, 0, 0, 0},
{"atanf ", atanf, atanf, -1, 1, 500000, 0, 0, 0},
{"atanf_c ", atanf_c, atanf, -1, 1, 500000, 0, 0, 0},
{"atanf_neon ", atanf_neon, atanf, -1, 1, 500000, 0, 0, 0},
{"sinhf ", sinhf, sinhf, -M_PI, M_PI, 500000, 0, 0, 0},
{"sinhf_c ", sinhf_c, sinhf, -M_PI, M_PI, 500000, 0, 0, 0},
{"sinhf_neon ", sinhf_neon, sinhf, -M_PI, M_PI, 500000, 0, 0, 0},
{"coshf ", coshf, coshf, -M_PI, M_PI, 500000, 0, 0, 0},
{"coshf_c ", coshf_c, coshf, -M_PI, M_PI, 500000, 0, 0, 0},
{"coshf_neon ", coshf_neon, coshf, -M_PI, M_PI, 500000, 0, 0, 0},
{"tanhf ", tanhf, tanhf, -M_PI, M_PI, 500000, 0, 0, 0},
{"tanhf_c ", tanhf_c, tanhf, -M_PI, M_PI, 500000, 0, 0, 0},
{"tanhf_neon ", tanhf_neon, tanhf, -M_PI, M_PI, 500000, 0, 0, 0},
{"expf ", expf, expf, 0, 10, 500000, 0, 0, 0},
{"expf_c ", expf_c, expf, 0, 10, 500000, 0, 0, 0},
{"expf_neon ", expf_neon, expf, 0, 10, 500000, 0, 0, 0},
{"logf ", logf, logf, 1, 1000, 500000, 0, 0, 0},
{"logf_c ", logf_c, logf, 1, 1000, 500000, 0, 0, 0},
{"logf_neon ", logf_neon, logf, 1, 1000, 500000, 0, 0, 0},
{"log10f ", log10f, log10f, 1, 1000, 500000, 0, 0, 0},
{"log10f_c ", log10f_c, log10f, 1, 1000, 500000, 0, 0, 0},
{"log10f_neon ", log10f_neon,log10f, 1, 1000, 500000, 0, 0, 0},
{"floorf ", floorf, floorf, 1, 1000, 5000000, 0, 0, 0},
{"floorf_c ", floorf_c, floorf, 1, 1000, 5000000, 0, 0, 0},
{"floorf_neon", floorf_neon,floorf, 1, 1000, 5000000, 0, 0, 0},
{"ceilf ", ceilf, ceilf, 1, 1000, 5000000, 0, 0, 0},
{"ceilf_c ", ceilf_c, ceilf, 1, 1000, 5000000, 0, 0, 0},
{"ceilf_neon", ceilf_neon, ceilf, 1, 1000, 5000000, 0, 0, 0},
{"fabsf ", fabsf, fabsf, 1, 1000, 5000000, 0, 0, 0},
{"fabsf_c ", fabsf_c, fabsf, 1, 1000, 5000000, 0, 0, 0},
{"fabsf_neon", fabsf_neon, fabsf, 1, 1000, 5000000, 0, 0, 0},
{"sqrtf ", sqrtf, sqrtf, 1, 1000, 500000, 0, 0, 0},
{"sqrtf_c ", sqrtf_c, sqrtf, 1, 1000, 500000, 0, 0, 0},
{"sqrtf_neon ", sqrtf_neon, sqrtf, 1, 1000, 500000, 0, 0, 0},
{"invsqrtf ", invsqrtf, invsqrtf, 1, 1000, 500000, 0, 0, 0},
{"invsqrtf_c ", invsqrtf_c, invsqrtf, 1, 1000, 500000, 0, 0, 0},
{"invsqrtf_neon ", invsqrtf_neon, invsqrtf, 1, 1000, 500000, 0, 0, 0},
};
test2_t test2[9] =
{
{"atan2f ", atan2f, atan2f, 0.1, 10, 10000, 0, 0, 0},
{"atan2f_c ", atan2f_c, atan2f, 0.1, 10, 10000, 0, 0, 0},
{"atan2f_neon ", atan2f_neon,atan2f, 0.1, 10, 10000, 0, 0, 0},
{"powf ", powf, powf, 1, 10, 10000, 0, 0, 0},
{"powf_c ", powf_c, powf, 1, 10, 10000, 0, 0, 0},
{"powf_neon ", powf_neon, powf, 1, 10, 10000, 0, 0, 0},
{"fmodf ", fmodf, fmodf, 1, 10, 10000, 0, 0, 0},
{"fmodf_c ", fmodf_c, fmodf, 1, 10, 10000, 0, 0, 0},
{"fmodf_neon ", fmodf_neon, fmodf, 1, 10, 10000, 0, 0, 0},
};
void
test_mathfunc1(test1_t *tst)
{
float x;
float dx = (tst->rng1 - tst->rng0) / ((float)tst->num);
#ifndef WIN32
struct rusage ru;
#endif
tst->emaxabs = tst->xmaxabs = 0;
tst->emaxrel = tst->xmaxrel = 0;
tst->erms = 0;
for(x = tst->rng0; x < tst->rng1 ; x += dx){
float r = (tst->func)((float)x);
float rr = (tst->bench)((float)x);
float dr = fabs(r - rr);
float drr = dr * (100.0f / rr);
tst->erms += dr*dr;
if (dr > tst->emaxabs){
tst->emaxabs = dr;
tst->xmaxabs = x;
}
if (drr > tst->emaxrel){
tst->emaxrel = drr;
tst->xmaxrel = x;
}
}
tst->erms = sqrt(tst->erms / ((float) tst->num));
#ifdef WIN32
tst->time = (1000 * clock()) / (CLOCKS_PER_SEC / 1000);
#else
tst->time = sceKernelGetSystemTimeWide();
#endif
for(x = tst->rng0; x < tst->rng1 ; x += dx){
(tst->func)((float)x);
}
#ifdef WIN32
tst->time = (1000 * clock()) / (CLOCKS_PER_SEC / 1000) - tst->time;
#else
tst->time = sceKernelGetSystemTimeWide();
#endif
}
void
test_mathfunc2(test2_t *tst)
{
float x, y;
float rng = tst->rng1 - tst->rng0;
float d = (rng * rng) / ((float) tst->num);
#ifndef WIN32
struct rusage ru;
#endif
tst->emaxabs = tst->xmaxabs = 0;
tst->emaxrel = tst->xmaxrel = 0;
for(y = (tst->rng0); y < (tst->rng1) ; y += d){
for(x = (tst->rng0); x < (tst->rng1); x += d){
float r = (tst->func)((float)x, y);
float rr = (tst->bench)((float)x, y);
float dr = fabs(r - rr);
float drr = dr * (100.0f / rr);
if (dr > tst->emaxabs){
tst->emaxabs = dr;
tst->xmaxabs = x;
}
if (drr > tst->emaxrel && fabsf(rr) > 0.0001){
tst->emaxrel = drr;
tst->xmaxrel = x;
}
}
}
#ifdef WIN32
tst->time = (1000 * clock()) / (CLOCKS_PER_SEC / 1000) ;
#else
tst->time = sceKernelGetSystemTimeWide();
#endif
for(y = tst->rng0; y < tst->rng1 ; y += d){
for(x = tst->rng0; x < tst->rng1 ; x += d){
(tst->func)((float)x, (float)y);
}
}
#ifdef WIN32
tst->time = (1000 * clock()) / (CLOCKS_PER_SEC / 1000) - tst->time;
#else
tst->time = sceKernelGetSystemTimeWide();
#endif
}
void test_vectorfunc()
{
float v0[4], v1[4], d[4];
for(int i=0;i<4;i++)
{
v0[i] = 10*randf() - 5;
v1[i] = 10*randf() - 5;
d[i] = 10*randf() - 5;
}
int testnum = 5000000;
struct rusage ru;
int v2t[3], v3t[3], v4t[3];
float r;
LOG("\n");
//dot 2
v2t[0] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
r = dot2_c(v0, v1);
};
v2t[1] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
r = dot2_neon(v0, v1);
};
v2t[2] = sceKernelGetSystemTimeWide();
r = dot2_c(v0, v1);
LOG("dot2_c = %f\n", r);
r = dot2_neon(v0, v1);
LOG("dot2_neon = %f\n", r);
LOG("dot2: c=%i \t neon=%i \t rate=%.2f \n", v2t[1] - v2t[0], v2t[2] - v2t[1],
(float)(v2t[1] - v2t[0]) / (float)(v2t[2] - v2t[1]));
//normalize 2
v2t[0] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
normalize2_c(v0, d);
};
v2t[1] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
normalize2_neon(v0, d);
};
v2t[2] = sceKernelGetSystemTimeWide();
normalize2_c(v0, d);
LOG("normalize2_c = [%.2f, %.2f]\n", d[0], d[1]);
normalize2_neon(v0, d);
LOG("normalize2_neon = [%.2f, %.2f]\n", d[0], d[1]);
LOG("normalize2: c=%i \t neon=%i \t rate=%.2f \n", v2t[1] - v2t[0], v2t[2] - v2t[1],
(float)(v2t[1] - v2t[0]) / (float)(v2t[2] - v2t[1]));
LOG("\n");
//dot 3
v3t[0] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
r = dot3_c(v0, v1);
};
v3t[1] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
r = dot3_neon(v0, v1);
};
v3t[2] = sceKernelGetSystemTimeWide();
r = dot3_c(v0, v1);
LOG("dot3_c = %f\n", r);
r = dot3_neon(v0, v1);
LOG("dot3_neon = %f\n", r);
LOG("dot3: c=%i \t neon=%i \t rate=%.2f \n", v3t[1] - v3t[0], v3t[2] - v3t[1],
(float)(v3t[1] - v3t[0]) / (float)(v3t[2] - v3t[1]));
//normalize 3
v3t[0] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
normalize3_c(v0, d);
};
v3t[1] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
normalize3_neon(v0, d);
};
v3t[2] = sceKernelGetSystemTimeWide();
normalize3_c(v0, d);
LOG("normalize3_c = [%.2f, %.2f, %.2f]\n", d[0], d[1], d[2]);
normalize3_neon(v0, d);
LOG("normalize3_neon = [%.2f, %.2f, %.2f]\n", d[0], d[1], d[2]);
LOG("normalize3: c=%i \t neon=%i \t rate=%.2f \n", v3t[1] - v3t[0], v3t[2] - v3t[1],
(float)(v3t[1] - v3t[0]) / (float)(v3t[2] - v3t[1]));
//cross 3
v3t[0] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
cross3_c(v0, v1, d);
};
v3t[1] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
cross3_neon(v0, v1, d);
};
v3t[2] = sceKernelGetSystemTimeWide();
cross3_c(v0, v1, d);
LOG("cross3_c = [%.2f, %.2f, %.2f]\n", d[0], d[1], d[2]);
cross3_neon(v0, v1, d);
LOG("cross3_neon = [%.2f, %.2f, %.2f]\n", d[0], d[1], d[2]);
LOG("cross3: c=%i \t neon=%i \t rate=%.2f \n", v3t[1] - v3t[0], v3t[2] - v3t[1],
(float)(v3t[1] - v3t[0]) / (float)(v3t[2] - v3t[1]));
LOG("\n");
//dot 4
v4t[0] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
r = dot4_c(v0, v1);
};
v4t[1] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
r = dot4_neon(v0, v1);
};
v4t[2] = sceKernelGetSystemTimeWide();
r = dot4_c(v0, v1);
LOG("dot4_c = %f\n", r);
r = dot4_neon(v0, v1);
LOG("dot4_neon = %f\n", r);
LOG("dot4: c=%i \t neon=%i \t rate=%.2f \n", v4t[1] - v4t[0], v4t[2] - v4t[1],
(float)(v4t[1] - v4t[0]) / (float)(v4t[2] - v4t[1]));
//normalize 4
v4t[0] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
normalize4_c(v0, d);
};
v4t[1] = sceKernelGetSystemTimeWide();
for(int i=0;i < testnum; i++)
{
normalize4_neon(v0, d);
};
v4t[2] = sceKernelGetSystemTimeWide();
normalize4_c(v0, d);
LOG("normalize4_c = [%.2f, %.2f, %.2f, %.2f]\n", d[0], d[1], d[2], d[3]);
normalize4_neon(v0, d);
LOG("normalize4_neon = [%.2f, %.2f, %.2f, %.2f]\n", d[0], d[1], d[2], d[3]);
LOG("normalize4: c=%i \t neon=%i \t rate=%.2f \n", v4t[1] - v4t[0], v4t[2] - v4t[1],
(float)(v4t[1] - v4t[0]) / (float)(v4t[2] - v4t[1]));
LOG("\n");
}
void test_matrixfunc()
{
float m0[16], m1[16], m2[16];
int m2t[3], m3t[3], m4t[3];
int i;
int testnum = 1000000;
struct rusage ru;
for(int i=0;i<16;i++)
{
m0[i] = 10.0f * randf() - 5.0f;
m1[i] = 10.0f * randf() - 5.0f;
m2[i] = 10.0f * randf() - 5.0f;
}
//matmul2
m2t[0] = sceKernelGetSystemTimeWide();
for(i = 0; i < testnum; i++){
matmul2_c(m0, m1, m2);
}
m2t[1] = sceKernelGetSystemTimeWide();
for(i = 0; i < testnum; i++){
matmul2_neon(m0, m1, m2);
}
m2t[2] = sceKernelGetSystemTimeWide();
matmul2_c(m0, m1, m2);
LOG("matmul2_c = \n");
LOG("\t\t\t|%.2f, %.2f|\n", m2[0], m2[2]);
LOG("\t\t\t|%.2f, %.2f|\n", m2[1], m2[3]);
matmul2_neon(m0, m1, m2);
LOG("matmul2_neon = \n");
LOG("\t\t\t|%.2f, %.2f|\n", m2[0], m2[2]);
LOG("\t\t\t|%.2f, %.2f|\n", m2[1], m2[3]);
LOG("matmul2: c=%i \t neon=%i \t rate=%.2f \n", m2t[1] - m2t[0], m2t[2] - m2t[1],
(float)(m2t[1] - m2t[0]) / (float)(m2t[2] - m2t[1]));
//matvec2
m2t[0] = sceKernelGetSystemTimeWide();
for(i = 0; i < testnum; i++){
matvec2_c(m0, m1, m2);
}
m2t[1] = sceKernelGetSystemTimeWide();
for(i = 0; i < testnum; i++){
matvec2_neon(m0, m1, m2);
}
m2t[2] = sceKernelGetSystemTimeWide();
memset(m2, 0, 4*sizeof(float));
matvec2_c(m0, m1, m2);
LOG("matvec2_c = |%.2f, %.2f|\n", m2[0], m2[1]);
memset(m2, 0, 4*sizeof(float));
matvec2_neon(m0, m1, m2);
LOG("matvec2_neon = |%.2f, %.2f|\n", m2[0], m2[1]);
LOG("matvec2: c=%i \t neon=%i \t rate=%.2f \n", m2t[1] - m2t[0], m2t[2] - m2t[1],
(float)(m2t[1] - m2t[0]) / (float)(m2t[2] - m2t[1]));
//MAT3
m3t[0] = sceKernelGetSystemTimeWide();
for(i = 0; i < testnum; i++){
matmul3_c(m0, m1, m2);
}
m3t[1] = sceKernelGetSystemTimeWide();
for(i = 0; i < testnum; i++){
matmul3_neon(m0, m1, m2);
}
m3t[2] = sceKernelGetSystemTimeWide();
memset(m2, 0, 9*sizeof(float));
matmul3_c(m0, m1, m2);
LOG("matmul3_c =\n");
LOG("\t\t\t|%.2f, %.2f, %.2f|\n", m2[0], m2[3], m2[6]);
LOG("\t\t\t|%.2f, %.2f, %.2f|\n", m2[1], m2[4], m2[7]);
LOG("\t\t\t|%.2f, %.2f, %.2f|\n", m2[2], m2[5], m2[8]);
memset(m2, 0, 9*sizeof(float));
matmul3_neon(m0, m1, m2);
LOG("matmul3_neon =\n");
LOG("\t\t\t|%.2f, %.2f, %.2f|\n", m2[0], m2[3], m2[6]);
LOG("\t\t\t|%.2f, %.2f, %.2f|\n", m2[1], m2[4], m2[7]);
LOG("\t\t\t|%.2f, %.2f, %.2f|\n", m2[2], m2[5], m2[8]);
LOG("matmul3: c=%i \t neon=%i \t rate=%.2f \n", m3t[1] - m3t[0], m3t[2] - m3t[1],
(float)(m3t[1] - m3t[0]) / (float)(m3t[2] - m3t[1]));
//matvec3
m3t[0] = sceKernelGetSystemTimeWide();
for(i = 0; i < testnum; i++){
matvec3_c(m0, m1, m2);
}
m3t[1] = sceKernelGetSystemTimeWide();
for(i = 0; i < testnum; i++){
matvec3_neon(m0, m1, m2);
}
m3t[2] = sceKernelGetSystemTimeWide();
memset(m2, 0, 4*sizeof(float));
matvec3_c(m0, m1, m2);
LOG("matvec3_c = |%.2f, %.2f, %.2f|\n", m2[0], m2[1], m2[2]);
memset(m2, 0, 4*sizeof(float));
matvec3_neon(m0, m1, m2);
LOG("matvec3_neon = |%.2f, %.2f, %.2f|\n", m2[0], m2[1], m2[2]);
LOG("matvec3: c=%i \t neon=%i \t rate=%.2f \n", m3t[1] - m3t[0], m3t[2] - m3t[1],
(float)(m3t[1] - m3t[0]) / (float)(m3t[2] - m3t[1]));
//MAT4
m4t[0] = sceKernelGetSystemTimeWide();
for(i = 0; i < testnum; i++){
matmul4_c(m0, m1, m2);
}
m4t[1] = sceKernelGetSystemTimeWide();
for(i = 0; i < testnum; i++){
matmul4_neon(m0, m1, m2);
}
m4t[2] = sceKernelGetSystemTimeWide();
memset(m2, 0, 16*sizeof(float));
matmul4_c(m0, m1, m2);
LOG("matmul4_c =\n");
LOG("\t\t\t|%.2f, %.2f, %.2f, %.2f|\n", m2[0], m2[4], m2[8], m2[12]);
LOG("\t\t\t|%.2f, %.2f, %.2f, %.2f|\n", m2[1], m2[5], m2[9], m2[13]);
LOG("\t\t\t|%.2f, %.2f, %.2f, %.2f|\n", m2[2], m2[6], m2[10], m2[14]);
LOG("\t\t\t|%.2f, %.2f, %.2f, %.2f|\n", m2[3], m2[7], m2[11], m2[15]);
memset(m2, 0, 16*sizeof(float));
matmul4_neon(m0, m1, m2);
LOG("matmul4_neon =\n");
LOG("\t\t\t|%.2f, %.2f, %.2f, %.2f|\n", m2[0], m2[4], m2[8], m2[12]);
LOG("\t\t\t|%.2f, %.2f, %.2f, %.2f|\n", m2[1], m2[5], m2[9], m2[13]);
LOG("\t\t\t|%.2f, %.2f, %.2f, %.2f|\n", m2[2], m2[6], m2[10], m2[14]);
LOG("\t\t\t|%.2f, %.2f, %.2f, %.2f|\n", m2[3], m2[7], m2[11], m2[15]);
LOG("matmul4: c=%i \t neon=%i \t rate=%.2f \n", m4t[1] - m4t[0], m4t[2] - m4t[1],
(float)(m4t[1] - m4t[0]) / (float)(m4t[2] - m4t[1]));
//matvec4
m4t[0] = sceKernelGetSystemTimeWide();
for(i = 0; i < testnum; i++){
matvec4_c(m0, m1, m2);
}
m4t[1] = sceKernelGetSystemTimeWide();
for(i = 0; i < testnum; i++){
matvec4_neon(m0, m1, m2);
}
m4t[2] = sceKernelGetSystemTimeWide();
memset(m2, 0, 4*sizeof(float));
matvec4_c(m0, m1, m2);
LOG("matvec4_c = |%.2f, %.2f, %.2f, %f|\n", m2[0], m2[1], m2[2], m2[3]);
memset(m2, 0, 4*sizeof(float));
matvec4_neon(m0, m1, m2);
LOG("matvec4_neon = |%.2f, %.2f, %.2f, %f|\n", m2[0], m2[1], m2[2], m2[3]);
LOG("matvec4: c=%i \t neon=%i \t rate=%.2f \n", m4t[1] - m4t[0], m4t[2] - m4t[1],
(float)(m4t[1] - m4t[0]) / (float)(m4t[2] - m4t[1]));
}
int main(int argc, char** argv)
{
int i, ii;
#if 1
LOG("RUNFAST: Disabled \n");
#else
LOG("RUNFAST: Enabled \n");
enable_runfast();
#endif
srand(time(NULL));
#if 1
//test single argument functions:
LOG("------------------------------------------------------------------------------------------------------\n");
LOG("MATRIX FUNCTION TESTS \n");
LOG("------------------------------------------------------------------------------------------------------\n");
test_matrixfunc();
test_vectorfunc();
LOG("------------------------------------------------------------------------------------------------------\n");
LOG("CMATH FUNCTION TESTS \n");
LOG("------------------------------------------------------------------------------------------------------\n");
LOG("Function\tRange\t\tNumber\tABS Max Error\tREL Max Error\tRMS Error\tTime\tRate\n");
LOG("------------------------------------------------------------------------------------------------------\n");
for(i = 0; i < 51; i++){
test_mathfunc1(&test1[i]);
ii = i - (i % 3);
LOG("%s\t", test1[i].name);
LOG("[%.2f, %.2f]\t", test1[i].rng0, test1[i].rng1);
LOG("%i\t", test1[i].num);
LOG("%.2e\t", test1[i].emaxabs);
LOG("%.2e%%\t", test1[i].emaxrel);
LOG("%.2e\t", test1[i].erms);
LOG("%i\t", test1[i].time);
LOG("x%.2f\t", (float)test1[ii].time / test1[i].time);
LOG("\n");
}
for(i = 0; i < 9; i++){
test_mathfunc2(&test2[i]);
ii = i - (i % 3);
LOG("%s\t", test2[i].name);
LOG("[%.2f, %.2f]\t", test2[i].rng0, test2[i].rng1);
LOG("%i\t", test2[i].num);
LOG("%.2e\t", test2[i].emaxabs);
LOG("%.2e%%\t", test2[i].emaxrel);
LOG("%.2e\t", test2[i].erms);
LOG("%i\t", test2[i].time);
LOG("x%.2f\t", (float)test2[ii].time / test2[i].time);
LOG("\n");
}
#else
float x = 0;
for(x = -M_PI_2; x < M_PI_2; x+= 0.01)
{
LOG("x=%.2f\t in=%.2f\t c=%.2f\t neon=%.2f \n", x, sinhf(x), sinhf_c(x), sinhf_neon(x));
}
#endif
return 0;
}
+5 -1
View File
@@ -33,7 +33,7 @@ THE SOFTWARE.
//Default Floating Point value ABI: 0=softfp, 1=hardfp. Only effects *_neon routines.
//You can access the hardfp versions directly via the *_hard suffix.
//You can access the softfp versions directly via the *_soft suffix.
#define __MATH_FPABI 0
#define __MATH_FPABI 1
#endif
@@ -84,6 +84,10 @@ THE SOFTWARE.
#define modf_neon modf_neon_hfp
#define sqrtf_neon sqrtf_neon_hfp
#define invsqrtf_neon invsqrtf_neon_hfp
#define dot2_neon dot2_neon_hfp
#define dot3_neon dot3_neon_hfp
#define dot4_neon dot4_neon_hfp
#else
#define sinf_neon sinf_neon_sfp
#define cosf_neon cosf_neon_sfp
+49
View File
@@ -1,3 +1,52 @@
# v9.0.0
* new size: RC_MEMSIZE_BITCOUNT
* new flag: RC_CONDITION_OR_NEXT
* new flag: RC_CONDITION_TRIGGER
* new flag: RC_CONDITION_MEASURED_IF
* new operators: RC_OPERATOR_MULT / RC_OPERATOR_DIV
* is_bcd removed from memref - now part of RC_MEMSIZE
* add rc_runtime_t and associated functions
* add rc_hash_ functions
* add rc_error_str function
* add game_hash parameter to rc_url_award_cheevo
* remove hash parameter from rc_url_submit_lboard
* add rc_url_ping function
* add rc_console_ functions
# v8.1.0
* new flag: RC_CONDITION_MEASURED
* new flag: RC_CONDITION_ADD_ADDRESS
* add rc_evaluate_trigger - extended version of rc_test_trigger with more granular return codes
* make rc_evaluate_value return a signed int (was unsigned int)
* new formats: RC_FORMAT_MINUTES and RC_FORMAT_SECONDS_AS_MINUTES
* removed " Points" text from RC_FORMAT_SCORE format
* removed RC_FORMAT_OTHER format. "OTHER" format now parses to RC_FORMAT_SCORE
* bugfix: AddHits will now honor AndNext on previous condition
# v8.0.1
* bugfix: prevent null reference exception if rich presence contains condition without display string
* bugfix: 24-bit read from memory should only read 24-bits
# v8.0.0
* support for prior operand type
* support for AndNext condition flag
* support for rich presence
* bugfix: update delta/prior memory values while group is paused
* bugfix: allow floating point number without leading 0
* bugfix: support empty alt groups
# v7.1.1
* Address signed/unsigned mismatch warnings
# v7.1.0
* Added the RC_DISABLE_LUA macro to compile rcheevos without Lua support
# v7.0.2
* Make sure the code is C89-compliant
+191 -96
View File
@@ -59,10 +59,16 @@ enum {
RC_INVALID_VALUE_FLAG = -20,
RC_MISSING_VALUE_MEASURED = -21,
RC_MULTIPLE_MEASURED = -22,
RC_INVALID_MEASURED_TARGET = -23
RC_INVALID_MEASURED_TARGET = -23,
RC_INVALID_COMPARISON = -24
};
```
To convert the return code into something human-readable, pass it to:
```c
const char* rc_error_str(int ret);
```
### Console identifiers
This enumeration uniquely identifies each of the supported platforms in RetroAchievements.
@@ -92,14 +98,38 @@ enum {
RC_CONSOLE_PLAYSTATION_2 = 21,
RC_CONSOLE_XBOX = 22,
RC_CONSOLE_SKYNET = 23,
RC_CONSOLE_XBOX_ONE = 24,
RC_CONSOLE_POKEMON_MINI = 24,
RC_CONSOLE_ATARI_2600 = 25,
RC_CONSOLE_MS_DOS = 26,
RC_CONSOLE_ARCADE = 27,
RC_CONSOLE_VIRTUAL_BOY = 28,
RC_CONSOLE_MSX = 29,
RC_CONSOLE_COMMODORE_64 = 30,
RC_CONSOLE_ZX81 = 31
RC_CONSOLE_ZX81 = 31,
RC_CONSOLE_ORIC = 32,
RC_CONSOLE_SG1000 = 33,
RC_CONSOLE_VIC20 = 34,
RC_CONSOLE_AMIGA = 35,
RC_CONSOLE_AMIGA_ST = 36,
RC_CONSOLE_AMSTRAD_PC = 37,
RC_CONSOLE_APPLE_II = 38,
RC_CONSOLE_SATURN = 39,
RC_CONSOLE_DREAMCAST = 40,
RC_CONSOLE_PSP = 41,
RC_CONSOLE_CDI = 42,
RC_CONSOLE_3DO = 43,
RC_CONSOLE_COLECOVISION = 44,
RC_CONSOLE_INTELLIVISION = 45,
RC_CONSOLE_VECTREX = 46,
RC_CONSOLE_PC8800 = 47,
RC_CONSOLE_PC9800 = 48,
RC_CONSOLE_PCFX = 49,
RC_CONSOLE_ATARI_5200 = 50,
RC_CONSOLE_ATARI_7800 = 51,
RC_CONSOLE_X68K = 52,
RC_CONSOLE_WONDERSWAN = 53,
RC_CONSOLE_CASSETTEVISION = 54,
RC_CONSOLE_SUPER_CASSETTEVISION = 55
};
```
@@ -115,27 +145,23 @@ An operand is the leaf node of RetroAchievements expressions, and can hold one o
typedef struct {
union {
/* A value read from memory. */
struct {
/* The memory address or constant value of this variable. */
unsigned value;
/* The previous memory contents if RC_OPERAND_DELTA. */
unsigned previous;
rc_memref_value_t* memref;
/* The size of the variable. */
char size;
/* True if the value is in BCD. */
char is_bcd;
/* The type of the variable. */
};
/* An integer value. */
unsigned num;
/* A floating point value. */
double fp_value;
double dbl;
/* A reference to the Lua function that provides the value. */
int function_ref;
int luafunc;
};
/* specifies which member of the value union is being used */
char type;
/* the actual RC_MEMSIZE of the operand - memref.size may differ */
char size;
}
rc_operand_t;
```
@@ -144,20 +170,21 @@ The `size` field, when applicable, holds one of these values:
```c
enum {
RC_OPERAND_BIT_0,
RC_OPERAND_BIT_1,
RC_OPERAND_BIT_2,
RC_OPERAND_BIT_3,
RC_OPERAND_BIT_4,
RC_OPERAND_BIT_5,
RC_OPERAND_BIT_6,
RC_OPERAND_BIT_7,
RC_OPERAND_LOW,
RC_OPERAND_HIGH,
RC_OPERAND_8_BITS,
RC_OPERAND_16_BITS,
RC_OPERAND_24_BITS,
RC_OPERAND_32_BITS,
RC_MEMSIZE_8_BITS,
RC_MEMSIZE_16_BITS,
RC_MEMSIZE_24_BITS,
RC_MEMSIZE_32_BITS,
RC_MEMSIZE_LOW,
RC_MEMSIZE_HIGH,
RC_MEMSIZE_BIT_0,
RC_MEMSIZE_BIT_1,
RC_MEMSIZE_BIT_2,
RC_MEMSIZE_BIT_3,
RC_MEMSIZE_BIT_4,
RC_MEMSIZE_BIT_5,
RC_MEMSIZE_BIT_6,
RC_MEMSIZE_BIT_7,
RC_MEMSIZE_BITCOUNT
};
```
@@ -165,15 +192,18 @@ The `type` field is always valid, and holds one of these values:
```c
enum {
RC_OPERAND_ADDRESS, /* Compare to the value of a live address in RAM. */
RC_OPERAND_DELTA, /* The value last known at this address. */
RC_OPERAND_CONST, /* A 32-bit unsigned integer. */
RC_OPERAND_FP, /* A floating point value. */
RC_OPERAND_LUA /* A Lua function that provides the value. */
RC_OPERAND_ADDRESS, /* The value of a live address in RAM. */
RC_OPERAND_DELTA, /* The value last known at this address. */
RC_OPERAND_CONST, /* A 32-bit unsigned integer. */
RC_OPERAND_FP, /* A floating point value. */
RC_OPERAND_LUA, /* A Lua function that provides the value. */
RC_OPERAND_PRIOR, /* The last differing value at this address. */
RC_OPERAND_BCD, /* The BCD-decoded value of a live address in RAM */
RC_OPERAND_INVERTED /* The twos-complement value of a live address in RAM */
};
```
`RC_OPERAND_ADDRESS`, `RC_OPERAND_DELTA` and `RC_OPERAND_CONST` mean that the anonymous structure in the union is active. `RC_OPERAND_FP` means that `fp_value` is active. `RC_OPERAND_LUA` means `function_ref` is active.
`RC_OPERAND_ADDRESS`, `RC_OPERAND_DELTA`, `RC_OPERAND_PRIOR`, `RC_OPERAND_BCD`, and `RC_OPERAND_INVERTED` mean that `memref` is active. `RC_OPERAND_CONST` means that `num` is active. `RC_OPERAND_FP` means that `dbl` is active. `RC_OPERAND_LUA` means `luafunc` is active.
### `rc_condition_t`
@@ -184,9 +214,6 @@ A condition compares its two operands according to the defined operator. It also
typedef struct rc_condition_t rc_condition_t;
struct rc_condition_t {
/* The next condition in the chain. */
rc_condition_t* next;
/* The condition's operands. */
rc_operand_t operand1;
rc_operand_t operand2;
@@ -196,6 +223,9 @@ struct rc_condition_t {
/* Number of hits so far. */
unsigned current_hits;
/* The next condition in the chain. */
rc_condition_t* next;
/* The type of the condition. */
char type;
/* The comparison operator to use. */
@@ -219,7 +249,9 @@ enum {
RC_CONDITION_ADD_HITS,
RC_CONDITION_AND_NEXT,
RC_CONDITION_MEASURED,
RC_CONDITION_ADD_ADDRESS
RC_CONDITION_ADD_ADDRESS,
RC_CONDITION_TRIGGER,
RC_CONDITION_MEASURED_IF
};
```
@@ -227,13 +259,16 @@ enum {
```c
enum {
RC_CONDITION_EQ,
RC_CONDITION_LT,
RC_CONDITION_LE,
RC_CONDITION_GT,
RC_CONDITION_GE,
RC_CONDITION_NE,
RC_CONDITION_NONE
RC_OPERATOR_EQ,
RC_OPERATOR_LT,
RC_OPERATOR_LE,
RC_OPERATOR_GT,
RC_OPERATOR_GE,
RC_OPERATOR_NE,
RC_OPERATOR_NONE,
RC_OPERATOR_MULT,
RC_OPERATOR_DIV,
RC_OPERATOR_AND
};
```
@@ -267,6 +302,9 @@ typedef struct {
/* The list of sub condition sets in this test. */
rc_condset_t* alternative;
/* The memory references required by the trigger. */
rc_memref_value_t* memrefs;
}
rc_trigger_t;
```
@@ -313,7 +351,8 @@ enum {
RC_TRIGGER_STATE_ACTIVE, /* achievement is active and may trigger */
RC_TRIGGER_STATE_PAUSED, /* achievement is currently paused and will not trigger */
RC_TRIGGER_STATE_RESET, /* achievement hit counts were reset */
RC_TRIGGER_STATE_TRIGGERED /* achievement has triggered */
RC_TRIGGER_STATE_TRIGGERED, /* achievement has triggered */
RC_TRIGGER_STATE_PRIMED /* all non-Trigger conditions are true */
};
```
@@ -323,52 +362,12 @@ Finally, `rc_reset_trigger` can be used to reset the internal state of a trigger
void rc_reset_trigger(rc_trigger_t* self);
```
### `rc_term_t`
A term is the leaf node of expressions used to compute values from operands. A term is evaluated by multiplying its two operands. `invert` is used to invert the bits of the second operand of the term, when the unary operator `~` is used.
```c
typedef struct rc_term_t rc_term_t;
struct rc_term_t {
/* The next term in this chain. */
rc_term_t* next;
/* The first operand. */
rc_operand_t operand1;
/* The second operand. */
rc_operand_t operand2;
/* A value that is applied to the second variable to invert its bits. */
unsigned invert;
};
```
### `rc_expression_t`
An expression is a collection of terms. All terms in the collection are added together to give the value of the expression.
```c
typedef struct rc_expression_t rc_expression_t;
struct rc_expression_t {
/* The next expression in this chain. */
rc_expression_t* next;
/* The list of terms in this expression. */
rc_term_t* terms;
};
```
### `rc_value_t`
A value is a collection of expressions. It's used to give the value for a leaderboard, and it evaluates to value of the expression with the greatest value in the collection.
A value is a collection of conditions that result in a single RC_CONDITION_MEASURED expression. It's used to calculate the value for a leaderboard and for lookups in rich presence.
```c
typedef struct {
/* The list of expression to evaluate. */
rc_expression_t* expressions;
/* The list of conditions to evaluate. */
rc_condset_t* conditions;
@@ -413,9 +412,9 @@ typedef struct {
rc_trigger_t cancel;
rc_value_t value;
rc_value_t* progress;
rc_memref_value_t* memrefs;
char started;
char submitted;
char state;
}
rc_lboard_t;
```
@@ -437,11 +436,12 @@ The function returns an action that must be performed by the caller, and `value`
```c
enum {
RC_LBOARD_INACTIVE,
RC_LBOARD_ACTIVE,
RC_LBOARD_STARTED,
RC_LBOARD_CANCELED,
RC_LBOARD_TRIGGERED
RC_LBOARD_STATE_INACTIVE, /* leaderboard is not being processed */
RC_LBOARD_STATE_WAITING, /* leaderboard cannot activate until the start condition has been false for at least one frame */
RC_LBOARD_STATE_ACTIVE, /* leaderboard is active and may start */
RC_LBOARD_STATE_STARTED, /* leaderboard attempt in progress */
RC_LBOARD_STATE_CANCELED, /* leaderboard attempt canceled */
RC_LBOARD_STATE_TRIGGERED /* leaderboard attempt complete, value should be submitted */
};
```
@@ -458,6 +458,101 @@ The caller must keep track of these values and do the necessary actions:
void rc_reset_lboard(rc_lboard_t* lboard);
```
### `rc_runtime_t`
The runtime encapsulates a set of achievements and leaderboards and manages processing them for each frame. When important things occur, events are raised for the caller via a callback.
```c
typedef struct rc_runtime_t {
rc_runtime_trigger_t* triggers;
unsigned trigger_count;
unsigned trigger_capacity;
rc_runtime_lboard_t* lboards;
unsigned lboard_count;
unsigned lboard_capacity;
rc_runtime_richpresence_t* richpresence;
char* richpresence_display_buffer;
char richpresence_update_timer;
rc_memref_value_t* memrefs;
rc_memref_value_t** next_memref;
}
rc_runtime_t;
```
The runtime must first be initialized.
```c
void rc_runtime_init(rc_runtime_t* runtime);
```
Then individual achievements, leaderboards, and even rich presence can be loaded into the runtime. These functions return RC_OK, or one of the negative value error codes listed above.
```c
int rc_runtime_activate_achievement(rc_runtime_t* runtime, unsigned id, const char* memaddr, lua_State* L, int funcs_idx);
int rc_runtime_activate_lboard(rc_runtime_t* runtime, unsigned id, const char* memaddr, lua_State* L, int funcs_idx);
int rc_runtime_activate_richpresence(rc_runtime_t* runtime, const char* script, lua_State* L, int funcs_idx);
```
The runtime should be called once per frame to evaluate the state of the active achievements/leaderboards:
```c
void rc_runtime_do_frame(rc_runtime_t* runtime, rc_runtime_event_handler_t event_handler, rc_peek_t peek, void* ud, lua_State* L);
```
The `event_handler` is a callback function that is called for each event that occurs when processing the frame.
```c
typedef struct rc_runtime_event_t {
unsigned id;
int value;
char type;
}
rc_runtime_event_t;
typedef void (*rc_runtime_event_handler_t)(const rc_runtime_event_t* runtime_event);
```
The `event.type` field will be one of the following:
* RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED (id=achievement id)
An achievement starts in the RC_TRIGGER_STATE_WAITING state and cannot trigger until it has been false for at least one frame. This event indicates the achievement is no longer waiting and may trigger on a future frame.
* RC_RUNTIME_EVENT_ACHIEVEMENT_PAUSED (id=achievement id)
One or more conditions in the achievement have disabled the achievement.
* RC_RUNTIME_EVENT_ACHIEVEMENT_RESET (id=achievement id)
One or more conditions in the achievement have reset any progress captured in the achievement.
* RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED (id=achievement id)
All conditions for the achievement have been met and the user should be informed.
NOTE: If `rc_runtime_reset` is called without deactivating the achievement, it may trigger again.
* RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED (id=achievement id)
All non-trigger conditions for the achievement have been met. This typically indicates the achievement is a challenge achievement and the challenge is active.
* RC_RUNTIME_EVENT_LBOARD_STARTED (id=leaderboard id, value=leaderboard value)
The leaderboard's start condition has been met and the user should be informed that a leaderboard attempt has started.
* RC_RUNTIME_EVENT_LBOARD_CANCELED (id=leaderboard id, value=leaderboard value)
The leaderboard's cancel condition has been met and the user should be informed that a leaderboard attempt has failed.
* RC_RUNTIME_EVENT_LBOARD_UPDATED (id=leaderboard id, value=leaderboard value)
The leaderboard value has changed.
* RC_RUNTIME_EVENT_LBOARD_TRIGGERED (id=leaderboard id, value=leaderboard value)
The leaderboard's submit condition has been met and the user should be informed that a leaderboard attempt was successful. The value should be submitted.
When an achievement triggers, it should be deactivated so it won't trigger again:
```c
void rc_runtime_deactivate_achievement(rc_runtime_t* runtime, unsigned id);
```
Additionally, the unlock should be submitted to the server.
When a leaderboard triggers, it should not be deactivated in case the player wants to try again for a better score. The value should be submitted to the server.
`rc_runtime_do_frame` also periodically updates the rich presense string (every 60 frames). To get the current value, call
```c
const char* rc_runtime_get_richpresence(const rc_runtime_t* runtime);
```
When the game is reset, the runtime should also be reset:
```c
void rc_runtime_reset(rc_runtime_t* runtime);
```
This ensures any active achievements/leaderboards are set back to their initial states and prevents unexpected triggers when the memory changes in atypical way.
### Value Formatting
**rcheevos** includes helper functions to parse formatting strings from RetroAchievements, and format values according to them.
+169 -97
View File
@@ -35,46 +35,12 @@ enum {
RC_INVALID_VALUE_FLAG = -20,
RC_MISSING_VALUE_MEASURED = -21,
RC_MULTIPLE_MEASURED = -22,
RC_INVALID_MEASURED_TARGET = -23
RC_INVALID_MEASURED_TARGET = -23,
RC_INVALID_COMPARISON = -24,
RC_INVALID_STATE = -25
};
/*****************************************************************************\
| Console identifiers |
\*****************************************************************************/
enum {
RC_CONSOLE_MEGA_DRIVE = 1,
RC_CONSOLE_NINTENDO_64 = 2,
RC_CONSOLE_SUPER_NINTENDO = 3,
RC_CONSOLE_GAMEBOY = 4,
RC_CONSOLE_GAMEBOY_ADVANCE = 5,
RC_CONSOLE_GAMEBOY_COLOR = 6,
RC_CONSOLE_NINTENDO = 7,
RC_CONSOLE_PC_ENGINE = 8,
RC_CONSOLE_SEGA_CD = 9,
RC_CONSOLE_SEGA_32X = 10,
RC_CONSOLE_MASTER_SYSTEM = 11,
RC_CONSOLE_PLAYSTATION = 12,
RC_CONSOLE_ATARI_LYNX = 13,
RC_CONSOLE_NEOGEO_POCKET = 14,
RC_CONSOLE_GAME_GEAR = 15,
RC_CONSOLE_GAMECUBE = 16,
RC_CONSOLE_ATARI_JAGUAR = 17,
RC_CONSOLE_NINTENDO_DS = 18,
RC_CONSOLE_WII = 19,
RC_CONSOLE_WII_U = 20,
RC_CONSOLE_PLAYSTATION_2 = 21,
RC_CONSOLE_XBOX = 22,
RC_CONSOLE_SKYNET = 23,
RC_CONSOLE_XBOX_ONE = 24,
RC_CONSOLE_ATARI_2600 = 25,
RC_CONSOLE_MS_DOS = 26,
RC_CONSOLE_ARCADE = 27,
RC_CONSOLE_VIRTUAL_BOY = 28,
RC_CONSOLE_MSX = 29,
RC_CONSOLE_COMMODORE_64 = 30,
RC_CONSOLE_ZX81 = 31
};
const char* rc_error_str(int ret);
/*****************************************************************************\
| Callbacks |
@@ -93,6 +59,12 @@ typedef unsigned (*rc_peek_t)(unsigned address, unsigned num_bytes, void* ud);
/* Sizes. */
enum {
RC_MEMSIZE_8_BITS,
RC_MEMSIZE_16_BITS,
RC_MEMSIZE_24_BITS,
RC_MEMSIZE_32_BITS,
RC_MEMSIZE_LOW,
RC_MEMSIZE_HIGH,
RC_MEMSIZE_BIT_0,
RC_MEMSIZE_BIT_1,
RC_MEMSIZE_BIT_2,
@@ -101,12 +73,7 @@ enum {
RC_MEMSIZE_BIT_5,
RC_MEMSIZE_BIT_6,
RC_MEMSIZE_BIT_7,
RC_MEMSIZE_LOW,
RC_MEMSIZE_HIGH,
RC_MEMSIZE_8_BITS,
RC_MEMSIZE_16_BITS,
RC_MEMSIZE_24_BITS,
RC_MEMSIZE_32_BITS
RC_MEMSIZE_BITCOUNT
};
typedef struct {
@@ -114,8 +81,6 @@ typedef struct {
unsigned address;
/* The size of the variable. */
char size;
/* True if the value is in BCD. */
char is_bcd;
/* True if the reference will be used in indirection */
char is_indirect;
} rc_memref_t;
@@ -143,12 +108,14 @@ struct rc_memref_value_t {
/* types */
enum {
RC_OPERAND_ADDRESS, /* Compare to the value of a live address in RAM. */
RC_OPERAND_DELTA, /* The value last known at this address. */
RC_OPERAND_CONST, /* A 32-bit unsigned integer. */
RC_OPERAND_FP, /* A floating point value. */
RC_OPERAND_LUA, /* A Lua function that provides the value. */
RC_OPERAND_PRIOR /* The last differing value at this address. */
RC_OPERAND_ADDRESS, /* The value of a live address in RAM. */
RC_OPERAND_DELTA, /* The value last known at this address. */
RC_OPERAND_CONST, /* A 32-bit unsigned integer. */
RC_OPERAND_FP, /* A floating point value. */
RC_OPERAND_LUA, /* A Lua function that provides the value. */
RC_OPERAND_PRIOR, /* The last differing value at this address. */
RC_OPERAND_BCD, /* The BCD-decoded value of a live address in RAM */
RC_OPERAND_INVERTED /* The twos-complement value of a live address in RAM */
};
typedef struct {
@@ -166,7 +133,11 @@ typedef struct {
int luafunc;
} value;
/* specifies which member of the value union is being used */
char type;
/* the actual RC_MEMSIZE of the operand - memref.size may differ */
char size;
}
rc_operand_t;
@@ -184,18 +155,24 @@ enum {
RC_CONDITION_ADD_HITS,
RC_CONDITION_AND_NEXT,
RC_CONDITION_MEASURED,
RC_CONDITION_ADD_ADDRESS
RC_CONDITION_ADD_ADDRESS,
RC_CONDITION_OR_NEXT,
RC_CONDITION_TRIGGER,
RC_CONDITION_MEASURED_IF
};
/* operators */
enum {
RC_CONDITION_EQ,
RC_CONDITION_LT,
RC_CONDITION_LE,
RC_CONDITION_GT,
RC_CONDITION_GE,
RC_CONDITION_NE,
RC_CONDITION_NONE
RC_OPERATOR_EQ,
RC_OPERATOR_LT,
RC_OPERATOR_LE,
RC_OPERATOR_GT,
RC_OPERATOR_GE,
RC_OPERATOR_NE,
RC_OPERATOR_NONE,
RC_OPERATOR_MULT,
RC_OPERATOR_DIV,
RC_OPERATOR_AND
};
typedef struct rc_condition_t rc_condition_t;
@@ -256,7 +233,8 @@ enum {
RC_TRIGGER_STATE_ACTIVE, /* achievement is active and may trigger */
RC_TRIGGER_STATE_PAUSED, /* achievement is currently paused and will not trigger */
RC_TRIGGER_STATE_RESET, /* achievement hit counts were reset */
RC_TRIGGER_STATE_TRIGGERED /* achievement has triggered */
RC_TRIGGER_STATE_TRIGGERED, /* achievement has triggered */
RC_TRIGGER_STATE_PRIMED /* all non-Trigger conditions are true */
};
typedef struct {
@@ -290,38 +268,10 @@ int rc_test_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, lua_State*
void rc_reset_trigger(rc_trigger_t* self);
/*****************************************************************************\
| Expressions and values |
| Values |
\*****************************************************************************/
typedef struct rc_term_t rc_term_t;
struct rc_term_t {
/* The next term in this chain. */
rc_term_t* next;
/* The first operand. */
rc_operand_t operand1;
/* The second operand. */
rc_operand_t operand2;
/* A value that is applied to the second variable to invert its bits. */
unsigned invert;
};
typedef struct rc_expression_t rc_expression_t;
struct rc_expression_t {
/* The next expression in this chain. */
rc_expression_t* next;
/* The list of terms in this expression. */
rc_term_t* terms;
};
typedef struct {
/* The list of expression to evaluate. */
rc_expression_t* expressions;
/* The list of conditions to evaluate. */
rc_condset_t* conditions;
@@ -340,11 +290,12 @@ int rc_evaluate_value(rc_value_t* value, rc_peek_t peek, void* ud, lua_State* L)
/* Return values for rc_evaluate_lboard. */
enum {
RC_LBOARD_INACTIVE,
RC_LBOARD_ACTIVE,
RC_LBOARD_STARTED,
RC_LBOARD_CANCELED,
RC_LBOARD_TRIGGERED
RC_LBOARD_STATE_INACTIVE, /* leaderboard is not being processed */
RC_LBOARD_STATE_WAITING, /* leaderboard cannot activate until the start condition has been false for at least one frame */
RC_LBOARD_STATE_ACTIVE, /* leaderboard is active and may start */
RC_LBOARD_STATE_STARTED, /* leaderboard attempt in progress */
RC_LBOARD_STATE_CANCELED, /* leaderboard attempt canceled */
RC_LBOARD_STATE_TRIGGERED /* leaderboard attempt complete, value should be submitted */
};
typedef struct {
@@ -355,8 +306,7 @@ typedef struct {
rc_value_t* progress;
rc_memref_value_t* memrefs;
char started;
char submitted;
char state;
}
rc_lboard_t;
@@ -433,6 +383,128 @@ int rc_richpresence_size(const char* script);
rc_richpresence_t* rc_parse_richpresence(void* buffer, const char* script, lua_State* L, int funcs_ndx);
int rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, unsigned buffersize, rc_peek_t peek, void* peek_ud, lua_State* L);
/*****************************************************************************\
| Runtime |
\*****************************************************************************/
typedef struct rc_runtime_trigger_t {
unsigned id;
rc_trigger_t* trigger;
void* buffer;
unsigned char md5[16];
char owns_memrefs;
}
rc_runtime_trigger_t;
typedef struct rc_runtime_lboard_t {
unsigned id;
int value;
rc_lboard_t* lboard;
void* buffer;
unsigned char md5[16];
char owns_memrefs;
}
rc_runtime_lboard_t;
typedef struct rc_runtime_richpresence_t {
rc_richpresence_t* richpresence;
void* buffer;
struct rc_runtime_richpresence_t* previous;
char owns_memrefs;
}
rc_runtime_richpresence_t;
typedef struct rc_runtime_t {
rc_runtime_trigger_t* triggers;
unsigned trigger_count;
unsigned trigger_capacity;
rc_runtime_lboard_t* lboards;
unsigned lboard_count;
unsigned lboard_capacity;
rc_runtime_richpresence_t* richpresence;
char* richpresence_display_buffer;
char richpresence_update_timer;
rc_memref_value_t* memrefs;
rc_memref_value_t** next_memref;
}
rc_runtime_t;
void rc_runtime_init(rc_runtime_t* runtime);
void rc_runtime_destroy(rc_runtime_t* runtime);
int rc_runtime_activate_achievement(rc_runtime_t* runtime, unsigned id, const char* memaddr, lua_State* L, int funcs_idx);
void rc_runtime_deactivate_achievement(rc_runtime_t* runtime, unsigned id);
rc_trigger_t* rc_runtime_get_achievement(const rc_runtime_t* runtime, unsigned id);
int rc_runtime_activate_lboard(rc_runtime_t* runtime, unsigned id, const char* memaddr, lua_State* L, int funcs_idx);
void rc_runtime_deactivate_lboard(rc_runtime_t* runtime, unsigned id);
rc_lboard_t* rc_runtime_get_lboard(const rc_runtime_t* runtime, unsigned id);
int rc_runtime_activate_richpresence(rc_runtime_t* runtime, const char* script, lua_State* L, int funcs_idx);
const char* rc_runtime_get_richpresence(const rc_runtime_t* runtime);
enum {
RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, /* from WAITING, PAUSED, or PRIMED to ACTIVE */
RC_RUNTIME_EVENT_ACHIEVEMENT_PAUSED,
RC_RUNTIME_EVENT_ACHIEVEMENT_RESET,
RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED,
RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED,
RC_RUNTIME_EVENT_LBOARD_STARTED,
RC_RUNTIME_EVENT_LBOARD_CANCELED,
RC_RUNTIME_EVENT_LBOARD_UPDATED,
RC_RUNTIME_EVENT_LBOARD_TRIGGERED
};
typedef struct rc_runtime_event_t {
unsigned id;
int value;
char type;
}
rc_runtime_event_t;
typedef void (*rc_runtime_event_handler_t)(const rc_runtime_event_t* runtime_event);
void rc_runtime_do_frame(rc_runtime_t* runtime, rc_runtime_event_handler_t event_handler, rc_peek_t peek, void* ud, lua_State* L);
void rc_runtime_reset(rc_runtime_t* runtime);
int rc_runtime_progress_size(const rc_runtime_t* runtime, lua_State* L);
int rc_runtime_serialize_progress(void* buffer, const rc_runtime_t* runtime, lua_State* L);
int rc_runtime_deserialize_progress(rc_runtime_t* runtime, const unsigned char* serialized, lua_State* L);
/*****************************************************************************\
| Memory mapping |
\*****************************************************************************/
enum {
RC_MEMORY_TYPE_SYSTEM_RAM, /* normal system memory */
RC_MEMORY_TYPE_SAVE_RAM, /* memory that persists between sessions */
RC_MEMORY_TYPE_VIDEO_RAM, /* memory reserved for graphical processing */
RC_MEMORY_TYPE_READONLY, /* memory that maps to read only data */
RC_MEMORY_TYPE_HARDWARE_CONTROLLER, /* memory for interacting with system components */
RC_MEMORY_TYPE_VIRTUAL_RAM, /* secondary address space that maps to real memory in system RAM */
RC_MEMORY_TYPE_UNUSED /* these addresses don't really exist */
};
typedef struct rc_memory_region_t {
unsigned start_address; /* first address of block as queried by RetroAchievements */
unsigned end_address; /* last address of block as queried by RetroAchievements */
unsigned real_address; /* real address for first address of block */
char type; /* RC_MEMORY_TYPE_ for block */
const char* description; /* short description of block */
}
rc_memory_region_t;
typedef struct rc_memory_regions_t {
const rc_memory_region_t* region;
unsigned num_regions;
}
rc_memory_regions_t;
const rc_memory_regions_t* rc_console_memory_regions(int console_id);
#ifdef __cplusplus
}
#endif
+79
View File
@@ -0,0 +1,79 @@
#ifndef RCONSOLES_H
#define RCONSOLES_H
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************\
| Console identifiers |
\*****************************************************************************/
enum {
RC_CONSOLE_MEGA_DRIVE = 1,
RC_CONSOLE_NINTENDO_64 = 2,
RC_CONSOLE_SUPER_NINTENDO = 3,
RC_CONSOLE_GAMEBOY = 4,
RC_CONSOLE_GAMEBOY_ADVANCE = 5,
RC_CONSOLE_GAMEBOY_COLOR = 6,
RC_CONSOLE_NINTENDO = 7,
RC_CONSOLE_PC_ENGINE = 8,
RC_CONSOLE_SEGA_CD = 9,
RC_CONSOLE_SEGA_32X = 10,
RC_CONSOLE_MASTER_SYSTEM = 11,
RC_CONSOLE_PLAYSTATION = 12,
RC_CONSOLE_ATARI_LYNX = 13,
RC_CONSOLE_NEOGEO_POCKET = 14,
RC_CONSOLE_GAME_GEAR = 15,
RC_CONSOLE_GAMECUBE = 16,
RC_CONSOLE_ATARI_JAGUAR = 17,
RC_CONSOLE_NINTENDO_DS = 18,
RC_CONSOLE_WII = 19,
RC_CONSOLE_WII_U = 20,
RC_CONSOLE_PLAYSTATION_2 = 21,
RC_CONSOLE_XBOX = 22,
/* 23 used to be EVENTS */
RC_CONSOLE_POKEMON_MINI = 24,
RC_CONSOLE_ATARI_2600 = 25,
RC_CONSOLE_MS_DOS = 26,
RC_CONSOLE_ARCADE = 27,
RC_CONSOLE_VIRTUAL_BOY = 28,
RC_CONSOLE_MSX = 29,
RC_CONSOLE_COMMODORE_64 = 30,
RC_CONSOLE_ZX81 = 31,
RC_CONSOLE_ORIC = 32,
RC_CONSOLE_SG1000 = 33,
RC_CONSOLE_VIC20 = 34,
RC_CONSOLE_AMIGA = 35,
RC_CONSOLE_AMIGA_ST = 36,
RC_CONSOLE_AMSTRAD_PC = 37,
RC_CONSOLE_APPLE_II = 38,
RC_CONSOLE_SATURN = 39,
RC_CONSOLE_DREAMCAST = 40,
RC_CONSOLE_PSP = 41,
RC_CONSOLE_CDI = 42,
RC_CONSOLE_3DO = 43,
RC_CONSOLE_COLECOVISION = 44,
RC_CONSOLE_INTELLIVISION = 45,
RC_CONSOLE_VECTREX = 46,
RC_CONSOLE_PC8800 = 47,
RC_CONSOLE_PC9800 = 48,
RC_CONSOLE_PCFX = 49,
RC_CONSOLE_ATARI_5200 = 50,
RC_CONSOLE_ATARI_7800 = 51,
RC_CONSOLE_X68K = 52,
RC_CONSOLE_WONDERSWAN = 53,
RC_CONSOLE_CASSETTEVISION = 54,
RC_CONSOLE_SUPER_CASSETTEVISION = 55,
RC_CONSOLE_HUBS = 100,
RC_CONSOLE_EVENTS = 101
};
const char* rc_console_name(int console_id);
#ifdef __cplusplus
}
#endif
#endif /* RCONSOLES_H */
+124
View File
@@ -0,0 +1,124 @@
#ifndef RHASH_H
#define RHASH_H
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include "rconsoles.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ===================================================== */
/* generates a hash from a block of memory.
* returns non-zero on success, or zero on failure.
*/
int rc_hash_generate_from_buffer(char hash[33], int console_id, uint8_t* buffer, size_t buffer_size);
/* generates a hash from a file.
* returns non-zero on success, or zero on failure.
*/
int rc_hash_generate_from_file(char hash[33], int console_id, const char* path);
/* ===================================================== */
/* data for rc_hash_iterate
*/
struct rc_hash_iterator
{
uint8_t* buffer;
size_t buffer_size;
uint8_t consoles[12];
int index;
const char* path;
};
/* initializes a rc_hash_iterator
* - path must be provided
* - if buffer and buffer_size are provided, path may be a filename (i.e. for something extracted from a zip file)
*/
void rc_hash_initialize_iterator(struct rc_hash_iterator* iterator, const char* path, uint8_t* buffer, size_t buffer_size);
/* releases resources associated to a rc_hash_iterator
*/
void rc_hash_destroy_iterator(struct rc_hash_iterator* iterator);
/* generates the next hash for the data in the rc_hash_iterator.
* returns non-zero if a hash was generated, or zero if no more hashes can be generated for the data.
*/
int rc_hash_iterate(char hash[33], struct rc_hash_iterator* iterator);
/* ===================================================== */
/* specifies a function to call when an error occurs to display the error message */
typedef void (*rc_hash_message_callback)(const char*);
void rc_hash_init_error_message_callback(rc_hash_message_callback callback);
/* specifies a function to call for verbose logging */
void rc_hash_init_verbose_message_callback(rc_hash_message_callback callback);
/* ===================================================== */
/* opens a file */
typedef void* (*rc_hash_filereader_open_file_handler)(const char* path_utf8);
/* moves the file pointer - standard fseek parameters */
typedef void (*rc_hash_filereader_seek_handler)(void* file_handle, size_t offset, int origin);
/* locates the file pointer */
typedef size_t (*rc_hash_filereader_tell_handler)(void* file_handle);
/* reads the specified number of bytes from the file starting at the read pointer.
* returns the number of bytes actually read.
*/
typedef size_t (*rc_hash_filereader_read_handler)(void* file_handle, void* buffer, size_t requested_bytes);
/* closes the file */
typedef void (*rc_hash_filereader_close_file_handler)(void* file_handle);
struct rc_hash_filereader
{
rc_hash_filereader_open_file_handler open;
rc_hash_filereader_seek_handler seek;
rc_hash_filereader_tell_handler tell;
rc_hash_filereader_read_handler read;
rc_hash_filereader_close_file_handler close;
};
void rc_hash_init_custom_filereader(struct rc_hash_filereader* reader);
/* ===================================================== */
/* opens a track from the specified file. track 0 indicates the first data track should be opened.
* returns a handle to be passed to the other functions, or NULL if the track could not be opened.
*/
typedef void* (*rc_hash_cdreader_open_track_handler)(const char* path, uint32_t track);
/* attempts to read the specified number of bytes from the file starting at the read pointer.
* returns the number of bytes actually read.
*/
typedef size_t (*rc_hash_cdreader_read_sector_handler)(void* track_handle, uint32_t sector, void* buffer, size_t requested_bytes);
/* closes the track handle */
typedef void (*rc_hash_cdreader_close_track_handler)(void* track_handle);
struct rc_hash_cdreader
{
rc_hash_cdreader_open_track_handler open_track;
rc_hash_cdreader_read_sector_handler read_sector;
rc_hash_cdreader_close_track_handler close_track;
};
void rc_hash_init_default_cdreader();
void rc_hash_init_custom_cdreader(struct rc_hash_cdreader* reader);
/* ===================================================== */
#ifdef __cplusplus
}
#endif
#endif /* RHASH_H */
+6 -3
View File
@@ -7,11 +7,11 @@
extern "C" {
#endif
int rc_url_award_cheevo(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned cheevo_id, int hardcore);
int rc_url_award_cheevo(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned cheevo_id, int hardcore, const char* game_hash);
int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned lboard_id, int value, const char* game_hash);
int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned lboard_id, int value);
int rc_url_get_gameid(char* buffer, size_t size, unsigned char hash[16]);
int rc_url_get_gameid(char* buffer, size_t size, const char* hash);
int rc_url_get_patch(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned gameid);
@@ -25,6 +25,9 @@ int rc_url_get_unlock_list(char* buffer, size_t size, const char* user_name, con
int rc_url_post_playing(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned gameid);
int rc_url_ping(char* url_buffer, size_t url_buffer_size, char* post_buffer, size_t post_buffer_size,
const char* user_name, const char* login_token, unsigned gameid, const char* rich_presence);
#ifdef __cplusplus
}
#endif
+34
View File
@@ -52,3 +52,37 @@ void rc_destroy_parse_state(rc_parse_state_t* parse)
if (parse->scratch.memref != parse->scratch.memref_buffer)
free(parse->scratch.memref);
}
const char* rc_error_str(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";
case RC_INVALID_COMPARISON: return "Invalid comparison";
case RC_INVALID_STATE: return "Invalid state";
default: return "Unknown error";
}
}
+44
View File
@@ -0,0 +1,44 @@
#include "compat.h"
#include <ctype.h>
#include <stdarg.h>
int rc_strncasecmp(const char* left, const char* right, size_t length)
{
while (length)
{
if (*left != *right)
{
const int diff = tolower(*left) - tolower(*right);
if (diff != 0)
return diff;
}
++left;
++right;
--length;
}
return 0;
}
char* rc_strdup(const char* str)
{
const size_t length = strlen(str);
char* buffer = (char*)malloc(length + 1);
memcpy(buffer, str, length + 1);
return buffer;
}
int rc_snprintf(char* buffer, size_t size, const char* format, ...)
{
int result;
va_list args;
va_start(args, format);
/* assume buffer is large enough and ignore size */
result = vsprintf(buffer, format, args);
va_end(args);
return result;
}
+55
View File
@@ -0,0 +1,55 @@
#ifndef RC_COMPAT_H
#define RC_COMPAT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(MINGW) || defined(__MINGW32__) || defined(__MINGW64__)
/* MinGW redefinitions */
#elif defined(_MSC_VER)
/* Visual Studio redefinitions */
#ifndef strcasecmp
#define strcasecmp _stricmp
#endif
#ifndef strncasecmp
#define strncasecmp _strnicmp
#endif
#ifndef strdup
#define strdup _strdup
#endif
#elif __STDC_VERSION__ < 199901L
/* C89 redefinitions */
#ifndef snprintf
extern int rc_snprintf(char* buffer, size_t size, const char* format, ...);
#define snprintf rc_snprintf
#endif
#ifndef strncasecmp
extern int rc_strncasecmp(const char* left, const char* right, size_t length);
#define strncasecmp rc_strncasecmp
#endif
#ifndef strdup
extern char* rc_strdup(const char* str);
#define strdup rc_strdup
#endif
#endif /* __STDC_VERSION__ < 199901L */
#ifdef __cplusplus
}
#endif
#endif /* RC_COMPAT_H */
+105 -17
View File
@@ -6,6 +6,7 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
rc_condition_t* self;
const char* aux;
int ret2;
int can_modify = 0;
aux = *memaddr;
self = RC_ALLOC(rc_condition_t, parse);
@@ -15,12 +16,15 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
switch (*aux) {
case 'p': case 'P': self->type = RC_CONDITION_PAUSE_IF; break;
case 'r': case 'R': self->type = RC_CONDITION_RESET_IF; break;
case 'a': case 'A': self->type = RC_CONDITION_ADD_SOURCE; break;
case 'b': case 'B': self->type = RC_CONDITION_SUB_SOURCE; break;
case 'a': case 'A': self->type = RC_CONDITION_ADD_SOURCE; can_modify = 1; break;
case 'b': case 'B': self->type = RC_CONDITION_SUB_SOURCE; can_modify = 1; break;
case 'c': case 'C': self->type = RC_CONDITION_ADD_HITS; break;
case 'n': case 'N': self->type = RC_CONDITION_AND_NEXT; break;
case 'o': case 'O': self->type = RC_CONDITION_OR_NEXT; break;
case 'm': case 'M': self->type = RC_CONDITION_MEASURED; break;
case 'i': case 'I': self->type = RC_CONDITION_ADD_ADDRESS; break;
case 'q': case 'Q': self->type = RC_CONDITION_MEASURED_IF; break;
case 'i': case 'I': self->type = RC_CONDITION_ADD_ADDRESS; can_modify = 1; break;
case 't': case 'T': self->type = RC_CONDITION_TRIGGER; break;
default: parse->offset = RC_INVALID_CONDITION_TYPE; return 0;
}
@@ -37,9 +41,14 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
return 0;
}
if (self->operand1.type == RC_OPERAND_FP) {
parse->offset = can_modify ? RC_INVALID_FP_OPERAND : RC_INVALID_COMPARISON;
return 0;
}
switch (*aux++) {
case '=':
self->oper = RC_CONDITION_EQ;
self->oper = RC_OPERATOR_EQ;
aux += *aux == '=';
break;
@@ -51,33 +60,45 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
return 0;
}
self->oper = RC_CONDITION_NE;
self->oper = RC_OPERATOR_NE;
break;
case '<':
self->oper = RC_CONDITION_LT;
self->oper = RC_OPERATOR_LT;
if (*aux == '=') {
self->oper = RC_CONDITION_LE;
self->oper = RC_OPERATOR_LE;
aux++;
}
break;
case '>':
self->oper = RC_CONDITION_GT;
self->oper = RC_OPERATOR_GT;
if (*aux == '=') {
self->oper = RC_CONDITION_GE;
self->oper = RC_OPERATOR_GE;
aux++;
}
break;
case '*':
self->oper = RC_OPERATOR_MULT;
break;
case '/':
self->oper = RC_OPERATOR_DIV;
break;
case '&':
self->oper = RC_OPERATOR_AND;
break;
case '_':
case ')':
case '\0':
self->oper = RC_CONDITION_NONE;
self->oper = RC_OPERATOR_NONE;
self->operand2.type = RC_OPERAND_CONST;
self->operand2.value.num = 1;
self->required_hits = 0;
@@ -85,6 +106,36 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
return self;
}
switch (self->oper) {
case RC_OPERATOR_MULT:
case RC_OPERATOR_DIV:
case RC_OPERATOR_AND:
/* modifying operators are only valid on modifying statements */
if (!can_modify) {
parse->offset = RC_INVALID_OPERATOR;
return 0;
}
break;
default:
/* comparison operators are not valid on modifying statements */
if (can_modify) {
switch (self->type) {
case RC_CONDITION_ADD_SOURCE:
case RC_CONDITION_SUB_SOURCE:
case RC_CONDITION_ADD_ADDRESS:
/* prevent parse errors on legacy achievements where a condition was present before changing the type */
self->oper = RC_OPERATOR_NONE;
break;
default:
parse->offset = RC_INVALID_OPERATOR;
return 0;
}
}
break;
}
ret2 = rc_parse_operand(&self->operand2, &aux, 1, is_indirect, parse);
if (ret2 < 0) {
@@ -92,6 +143,17 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
return 0;
}
if (self->oper == RC_OPERATOR_NONE) {
/* if operator is none, explicitly clear out the right side */
self->operand2.type = RC_INVALID_CONST_OPERAND;
self->operand2.value.num = 0;
}
if (!can_modify && self->operand2.type == RC_OPERAND_FP) {
parse->offset = RC_INVALID_COMPARISON;
return 0;
}
if (*aux == '(') {
char* end;
self->required_hits = (unsigned)strtoul(++aux, &end, 10);
@@ -127,13 +189,39 @@ int rc_test_condition(rc_condition_t* self, rc_eval_state_t* eval_state) {
unsigned value2 = rc_evaluate_operand(&self->operand2, eval_state);
switch (self->oper) {
case RC_CONDITION_EQ: return value1 == value2;
case RC_CONDITION_NE: return value1 != value2;
case RC_CONDITION_LT: return value1 < value2;
case RC_CONDITION_LE: return value1 <= value2;
case RC_CONDITION_GT: return value1 > value2;
case RC_CONDITION_GE: return value1 >= value2;
case RC_CONDITION_NONE: return 1;
case RC_OPERATOR_EQ: return value1 == value2;
case RC_OPERATOR_NE: return value1 != value2;
case RC_OPERATOR_LT: return value1 < value2;
case RC_OPERATOR_LE: return value1 <= value2;
case RC_OPERATOR_GT: return value1 > value2;
case RC_OPERATOR_GE: return value1 >= value2;
case RC_OPERATOR_NONE: return 1;
default: return 1;
}
}
int rc_evaluate_condition_value(rc_condition_t* self, rc_eval_state_t* eval_state) {
unsigned value = rc_evaluate_operand(&self->operand1, eval_state);
switch (self->oper) {
case RC_OPERATOR_MULT:
if (self->operand2.type == RC_OPERAND_FP)
value = (int)((double)value * self->operand2.value.dbl);
else
value *= rc_evaluate_operand(&self->operand2, eval_state);
break;
case RC_OPERATOR_DIV:
if (self->operand2.type == RC_OPERAND_FP)
value = (int)((double)value / self->operand2.value.dbl);
else
value /= rc_evaluate_operand(&self->operand2, eval_state);
break;
case RC_OPERATOR_AND:
value &= rc_evaluate_operand(&self->operand2, eval_state);
break;
}
return value;
}
+111 -72
View File
@@ -9,15 +9,16 @@ static void rc_update_condition_pause(rc_condition_t* condition, int* in_pause)
case RC_CONDITION_PAUSE_IF:
*in_pause = condition->pause = 1;
break;
case RC_CONDITION_ADD_SOURCE:
case RC_CONDITION_SUB_SOURCE:
case RC_CONDITION_ADD_HITS:
case RC_CONDITION_AND_NEXT:
case RC_CONDITION_OR_NEXT:
case RC_CONDITION_ADD_ADDRESS:
condition->pause = *in_pause;
break;
default:
*in_pause = condition->pause = 0;
break;
@@ -48,14 +49,15 @@ rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse) {
return 0;
}
if ((*next)->oper == RC_CONDITION_NONE) {
if ((*next)->oper == RC_OPERATOR_NONE) {
switch ((*next)->type) {
case RC_CONDITION_ADD_ADDRESS:
case RC_CONDITION_ADD_HITS:
case RC_CONDITION_ADD_SOURCE:
case RC_CONDITION_SUB_SOURCE:
case RC_CONDITION_AND_NEXT:
break;
case RC_CONDITION_OR_NEXT:
break;
default:
parse->offset = RC_INVALID_OPERATOR;
@@ -110,10 +112,14 @@ rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse) {
static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, rc_eval_state_t* eval_state) {
rc_condition_t* condition;
int set_valid, cond_valid, prev_cond;
int set_valid, cond_valid, and_next, or_next;
unsigned measured_value = 0;
int can_measure = 1, measured_from_hits = 0;
eval_state->primed = 1;
set_valid = 1;
prev_cond = 1;
and_next = 1;
or_next = 0;
eval_state->add_value = eval_state->add_hits = eval_state->add_address = 0;
for (condition = self->conditions; condition != 0; condition = condition->next) {
@@ -121,93 +127,107 @@ static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, rc
continue;
}
/* STEP 1: process modifier conditions */
switch (condition->type) {
case RC_CONDITION_ADD_SOURCE:
eval_state->add_value += rc_evaluate_operand(&condition->operand1, eval_state);
eval_state->add_value += rc_evaluate_condition_value(condition, eval_state);
eval_state->add_address = 0;
continue;
case RC_CONDITION_SUB_SOURCE:
eval_state->add_value -= rc_evaluate_operand(&condition->operand1, eval_state);
eval_state->add_address = 0;
continue;
case RC_CONDITION_ADD_HITS:
/* always evaluate the condition to ensure everything is updated correctly */
cond_valid = rc_test_condition(condition, eval_state);
/* merge AndNext value and reset it for the next condition */
cond_valid &= prev_cond;
prev_cond = 1;
/* if the condition is true, tally it */
if (cond_valid) {
if (condition->required_hits == 0 || condition->current_hits < condition->required_hits) {
condition->current_hits++;
}
condition->is_true = (condition->required_hits == 0 || condition->current_hits >= condition->required_hits);
}
else {
condition->is_true = 0;
}
eval_state->add_value = 0;
eval_state->add_address = 0;
eval_state->add_hits += condition->current_hits;
continue;
case RC_CONDITION_AND_NEXT:
prev_cond &= rc_test_condition(condition, eval_state);
eval_state->add_value = 0;
eval_state->add_value -= rc_evaluate_condition_value(condition, eval_state);
eval_state->add_address = 0;
continue;
case RC_CONDITION_ADD_ADDRESS:
eval_state->add_address = rc_evaluate_operand(&condition->operand1, eval_state);
eval_state->add_address = rc_evaluate_condition_value(condition, eval_state);
continue;
case RC_CONDITION_MEASURED:
if (condition->required_hits == 0) {
/* Measured condition without a hit target measures the value of the left operand */
measured_value = rc_evaluate_condition_value(condition, eval_state) + eval_state->add_value;
}
break;
default:
break;
}
/* always evaluate the condition to ensure everything is updated correctly */
cond_valid = rc_test_condition(condition, eval_state);
/* STEP 2: evaluate the current condition */
condition->is_true = rc_test_condition(condition, eval_state);
eval_state->add_value = 0;
eval_state->add_address = 0;
/* merge AndNext value and reset it for the next condition */
cond_valid &= prev_cond;
prev_cond = 1;
/* apply logic flags and reset them for the next condition */
cond_valid = condition->is_true;
cond_valid &= and_next;
cond_valid |= or_next;
and_next = 1;
or_next = 0;
/* if the condition has a target hit count that has already been met, it's automatically true, even if not currently true. */
if (condition->required_hits != 0 && (condition->current_hits + eval_state->add_hits) >= condition->required_hits) {
cond_valid = 1;
}
else if (cond_valid) {
condition->current_hits++;
/* true conditions should update hit count */
if (cond_valid) {
eval_state->has_hits = 1;
if (condition->required_hits == 0) {
/* not a hit-based requirement: ignore any additional logic! */
/* no target hit count, just keep tallying */
++condition->current_hits;
}
else if ((condition->current_hits + eval_state->add_hits) < condition->required_hits) {
/* HitCount target has not yet been met, condition is not yet valid */
cond_valid = 0;
else if (condition->current_hits < condition->required_hits) {
/* target hit count hasn't been met, tally and revalidate - only true if hit count becomes met */
++condition->current_hits;
cond_valid = (condition->current_hits == condition->required_hits);
}
else {
/* target hit count has been met, do nothing */
}
}
condition->is_true = cond_valid;
eval_state->has_hits |= (condition->current_hits || eval_state->add_hits);
else if (condition->current_hits > 0) {
/* target has been true in the past, if the hit target is met, consider it true now */
eval_state->has_hits = 1;
cond_valid = (condition->current_hits == condition->required_hits);
}
/* capture measured state */
if (condition->type == RC_CONDITION_MEASURED) {
unsigned int measured_value;
if (condition->required_hits > 0)
/* STEP 3: handle logic flags */
switch (condition->type) {
case RC_CONDITION_ADD_HITS:
eval_state->add_hits += condition->current_hits;
continue;
case RC_CONDITION_AND_NEXT:
and_next = cond_valid;
continue;
case RC_CONDITION_OR_NEXT:
or_next = cond_valid;
continue;
default:
break;
}
if (eval_state->add_hits) {
if (condition->required_hits != 0) {
/* if the condition has a target hit count, we have to recalculate cond_valid including the AddHits counter */
measured_from_hits = 1;
measured_value = condition->current_hits + eval_state->add_hits;
else
measured_value = rc_evaluate_operand(&condition->operand1, eval_state) + eval_state->add_value;
cond_valid = (measured_value >= condition->required_hits);
}
else {
/* no target hit count. we can't tell if the add_hits value is from this frame or not, so ignore it.
complex condition will only be true if the current condition is true */
}
if (measured_value > eval_state->measured_value)
eval_state->measured_value = measured_value;
eval_state->add_hits = 0;
}
else if (condition->required_hits != 0) {
/* if there's a hit target, capture the current hits for recording Measured value later */
measured_from_hits = 1;
measured_value = condition->current_hits;
}
/* reset AddHits and AddSource/SubSource values */
eval_state->add_value = eval_state->add_hits = eval_state->add_address = 0;
/* STEP 4: handle special flags */
switch (condition->type) {
case RC_CONDITION_PAUSE_IF:
/* as soon as we find a PauseIf that evaluates to true, stop processing the rest of the group */
@@ -227,20 +247,38 @@ static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, rc
/* PauseIf has a HitCount that hasn't been met, ignore it for now. */
}
break;
continue;
case RC_CONDITION_RESET_IF:
if (cond_valid) {
eval_state->was_reset = 1; /* let caller know to reset all hit counts */
set_valid = 0; /* cannot be valid if we've hit a reset condition */
}
continue;
case RC_CONDITION_MEASURED_IF:
if (!cond_valid)
can_measure = 0;
break;
case RC_CONDITION_TRIGGER:
/* update truthiness of set, but do not update truthiness of primed state */
set_valid &= cond_valid;
continue;
default:
set_valid &= cond_valid;
break;
}
/* STEP 5: update overall truthiness of set and primed state */
eval_state->primed &= cond_valid;
set_valid &= cond_valid;
}
/* if not suppressed, update the measured value */
if (measured_value > eval_state->measured_value && can_measure) {
eval_state->measured_value = measured_value;
eval_state->measured_from_hits = measured_from_hits;
}
return set_valid;
@@ -255,6 +293,7 @@ int rc_test_condset(rc_condset_t* self, rc_eval_state_t* eval_state) {
if (self->has_pause) {
if ((self->is_paused = rc_test_condset_internal(self, 1, eval_state))) {
/* one or more Pause conditions exists, if any of them are true, stop processing this group */
eval_state->primed = 0;
return 0;
}
}
+590
View File
@@ -0,0 +1,590 @@
#include "rcheevos.h"
#include "rconsoles.h"
#include <ctype.h>
const char* rc_console_name(int console_id)
{
switch (console_id)
{
case RC_CONSOLE_3DO:
return "3DO";
case RC_CONSOLE_AMIGA:
return "Amiga";
case RC_CONSOLE_AMIGA_ST:
return "Amiga ST";
case RC_CONSOLE_AMSTRAD_PC:
return "Amstrad CPC";
case RC_CONSOLE_APPLE_II:
return "Apple II";
case RC_CONSOLE_ARCADE:
return "Arcade";
case RC_CONSOLE_ATARI_2600:
return "Atari 2600";
case RC_CONSOLE_ATARI_5200:
return "Atari 5200";
case RC_CONSOLE_ATARI_7800:
return "Atari 7800";
case RC_CONSOLE_ATARI_JAGUAR:
return "Atari Jaguar";
case RC_CONSOLE_ATARI_LYNX:
return "Atari Lynx";
case RC_CONSOLE_CASSETTEVISION:
return "CassetteVision";
case RC_CONSOLE_CDI:
return "CD-I";
case RC_CONSOLE_COLECOVISION:
return "ColecoVision";
case RC_CONSOLE_COMMODORE_64:
return "Commodore 64";
case RC_CONSOLE_DREAMCAST:
return "Dreamcast";
case RC_CONSOLE_EVENTS:
return "Events";
case RC_CONSOLE_GAMEBOY:
return "GameBoy";
case RC_CONSOLE_GAMEBOY_ADVANCE:
return "GameBoy Advance";
case RC_CONSOLE_GAMEBOY_COLOR:
return "GameBoy Color";
case RC_CONSOLE_GAMECUBE:
return "GameCube";
case RC_CONSOLE_GAME_GEAR:
return "Game Gear";
case RC_CONSOLE_HUBS:
return "Hubs";
case RC_CONSOLE_INTELLIVISION:
return "Intellivision";
case RC_CONSOLE_MASTER_SYSTEM:
return "Master System";
case RC_CONSOLE_MEGA_DRIVE:
return "Sega Genesis";
case RC_CONSOLE_MS_DOS:
return "MS-DOS";
case RC_CONSOLE_MSX:
return "MSX";
case RC_CONSOLE_NINTENDO:
return "Nintendo Entertainment System";
case RC_CONSOLE_NINTENDO_64:
return "Nintendo 64";
case RC_CONSOLE_NINTENDO_DS:
return "Nintendo DS";
case RC_CONSOLE_NEOGEO_POCKET:
return "Neo Geo Pocket";
case RC_CONSOLE_ORIC:
return "Oric";
case RC_CONSOLE_PC8800:
return "PC-8000/8800";
case RC_CONSOLE_PC9800:
return "PC-9800";
case RC_CONSOLE_PCFX:
return "PCFX";
case RC_CONSOLE_PC_ENGINE:
return "PCEngine";
case RC_CONSOLE_PLAYSTATION:
return "PlayStation";
case RC_CONSOLE_PLAYSTATION_2:
return "PlayStation 2";
case RC_CONSOLE_PSP:
return "PlayStation Portable";
case RC_CONSOLE_POKEMON_MINI:
return "Pokemon Mini";
case RC_CONSOLE_SEGA_32X:
return "Sega 32X";
case RC_CONSOLE_SEGA_CD:
return "Sega CD";
case RC_CONSOLE_SATURN:
return "Sega Saturn";
case RC_CONSOLE_SG1000:
return "SG-1000";
case RC_CONSOLE_SUPER_NINTENDO:
return "Super Nintendo Entertainment System";
case RC_CONSOLE_SUPER_CASSETTEVISION:
return "Super CassetteVision";
case RC_CONSOLE_WONDERSWAN:
return "WonderSwan";
case RC_CONSOLE_VECTREX:
return "Vectrex";
case RC_CONSOLE_VIC20:
return "VIC-20";
case RC_CONSOLE_VIRTUAL_BOY:
return "Virtual Boy";
case RC_CONSOLE_WII:
return "Wii";
case RC_CONSOLE_WII_U:
return "Wii-U";
case RC_CONSOLE_X68K:
return "X68K";
case RC_CONSOLE_XBOX:
return "XBOX";
case RC_CONSOLE_ZX81:
return "ZX-81";
default:
return "Unknown";
}
}
/* ===== 3DO ===== */
/* http://www.arcaderestoration.com/memorymap/48/3DO+Bios.aspx */
/* NOTE: the Opera core attempts to expose the NVRAM as RETRO_SAVE_RAM, but the 3DO documentation
* says that applications should only access NVRAM through API calls as it's shared across mulitple
* games. This suggests that even if the core does expose it, it may change depending on which other
* games the user has played - so ignore it.
*/
static const rc_memory_region_t _rc_memory_regions_3do[] = {
{ 0x000000U, 0x1FFFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Main RAM" },
};
static const rc_memory_regions_t rc_memory_regions_3do = { _rc_memory_regions_3do, 1 };
/* ===== Apple II ===== */
static const rc_memory_region_t _rc_memory_regions_appleii[] = {
{ 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Main RAM" },
{ 0x010000U, 0x01FFFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Auxillary RAM" }
};
static const rc_memory_regions_t rc_memory_regions_appleii = { _rc_memory_regions_appleii, 2 };
/* ===== Atari 2600 ===== */
static const rc_memory_region_t _rc_memory_regions_atari2600[] = {
{ 0x000000U, 0x00007FU, 0x000080U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_atari2600 = { _rc_memory_regions_atari2600, 1 };
/* ===== Atari 7800 ===== */
/* http://www.atarihq.com/danb/files/78map.txt */
/* http://pdf.textfiles.com/technical/7800_devkit.pdf */
static const rc_memory_region_t _rc_memory_regions_atari7800[] = {
{ 0x000000U, 0x0017FFU, 0x000000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Hardware Interface" },
{ 0x001800U, 0x0027FFU, 0x001800U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x002800U, 0x002FFFU, 0x002800U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored RAM" },
{ 0x003000U, 0x0037FFU, 0x003000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored RAM" },
{ 0x003800U, 0x003FFFU, 0x003800U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored RAM" },
{ 0x004000U, 0x007FFFU, 0x004000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" },
{ 0x008000U, 0x00FFFFU, 0x008000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM" }
};
static const rc_memory_regions_t rc_memory_regions_atari7800 = { _rc_memory_regions_atari7800, 7 };
/* ===== Atari Jaguar ===== */
/* https://www.mulle-kybernetik.com/jagdox/memorymap.html */
static const rc_memory_region_t _rc_memory_regions_atari_jaguar[] = {
{ 0x000000U, 0x1FFFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_atari_jaguar = { _rc_memory_regions_atari_jaguar, 1 };
/* ===== Atari Lynx ===== */
/* http://www.retroisle.com/atari/lynx/Technical/Programming/lynxprgdumm.php */
static const rc_memory_region_t _rc_memory_regions_atari_lynx[] = {
{ 0x000000U, 0x0000FFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Zero Page" },
{ 0x000100U, 0x0001FFU, 0x000100U, RC_MEMORY_TYPE_SYSTEM_RAM, "Stack" },
{ 0x000200U, 0x00FBFFU, 0x000200U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x00FC00U, 0x00FCFFU, 0x00FC00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "SUZY hardware access" },
{ 0x00FD00U, 0x00FDFFU, 0x00FD00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "MIKEY hardware access" },
{ 0x00FE00U, 0x00FFF7U, 0x00FE00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Boot ROM" },
{ 0x00FFF8U, 0x00FFFFU, 0x00FFF8U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Hardware vectors" }
};
static const rc_memory_regions_t rc_memory_regions_atari_lynx = { _rc_memory_regions_atari_lynx, 7 };
/* ===== ColecoVision ===== */
static const rc_memory_region_t _rc_memory_regions_colecovision[] = {
{ 0x000000U, 0x0003FFU, 0x006000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_colecovision = { _rc_memory_regions_colecovision, 1 };
/* ===== GameBoy / GameBoy Color ===== */
static const rc_memory_region_t _rc_memory_regions_gameboy[] = {
{ 0x000000U, 0x0000FFU, 0x000000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt vector" },
{ 0x000100U, 0x00014FU, 0x000100U, RC_MEMORY_TYPE_READONLY, "Cartridge header" },
{ 0x000150U, 0x003FFFU, 0x000150U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM (fixed)" }, /* bank 0 */
{ 0x004000U, 0x007FFFU, 0x004000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM (paged)" }, /* bank 1-XX (switchable) */
{ 0x008000U, 0x0097FFU, 0x008000U, RC_MEMORY_TYPE_VIDEO_RAM, "Tile RAM" },
{ 0x009800U, 0x009BFFU, 0x009800U, RC_MEMORY_TYPE_VIDEO_RAM, "BG1 map data" },
{ 0x009C00U, 0x009FFFU, 0x009C00U, RC_MEMORY_TYPE_VIDEO_RAM, "BG2 map data" },
{ 0x00A000U, 0x00BFFFU, 0x00A000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM"},
{ 0x00C000U, 0x00CFFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (fixed)" },
{ 0x00D000U, 0x00DFFFU, 0x00D000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (bank 1)" },
{ 0x00E000U, 0x00FDFFU, 0x00C000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Echo RAM" },
{ 0x00FE00U, 0x00FE9FU, 0x00FE00U, RC_MEMORY_TYPE_VIDEO_RAM, "Sprite RAM"},
{ 0x00FEA0U, 0x00FEFFU, 0x00FEA0U, RC_MEMORY_TYPE_READONLY, "Unusable"},
{ 0x00FF00U, 0x00FF7FU, 0x00FF00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Hardware I/O"},
{ 0x00FF80U, 0x00FFFEU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "Quick RAM"},
{ 0x00FFFFU, 0x00FFFFU, 0x00FFFFU, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt enable"},
/* GameBoy Color provides six extra banks of memory that can be paged out through the $DXXX
* memory space, but the timing of that does not correspond with blanks, which is when achievements
* are processed. As such, it is desirable to always have access to these extra banks. We do this
* by expecting the extra banks to be addressable at addresses not supported by the native system. */
{ 0x010000U, 0x015FFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (banks 2-7, GBC only)" }
};
static const rc_memory_regions_t rc_memory_regions_gameboy = { _rc_memory_regions_gameboy, 16 };
static const rc_memory_regions_t rc_memory_regions_gameboy_color = { _rc_memory_regions_gameboy, 17 };
/* ===== GameBoy Advance ===== */
static const rc_memory_region_t _rc_memory_regions_gameboy_advance[] = {
{ 0x000000U, 0x007FFFU, 0x03000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" },
{ 0x008000U, 0x047FFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_gameboy_advance = { _rc_memory_regions_gameboy_advance, 2 };
/* ===== Game Gear ===== */
/* http://www.smspower.org/Development/MemoryMap */
static const rc_memory_region_t _rc_memory_regions_game_gear[] = {
{ 0x000000U, 0x001FFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_game_gear = { _rc_memory_regions_game_gear, 1 };
/* ===== Intellivision ===== */
/* http://wiki.intellivision.us/index.php%3Ftitle%3DMemory_Map */
static const rc_memory_region_t _rc_memory_regions_intellivision[] = {
{ 0x000000U, 0x00007FU, 0x000000U, RC_MEMORY_TYPE_VIDEO_RAM, "STIC Registers" },
{ 0x000080U, 0x0000FFU, 0x000080U, RC_MEMORY_TYPE_UNUSED, "" },
{ 0x000100U, 0x00035FU, 0x000100U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x000360U, 0x0003FFU, 0x000360U, RC_MEMORY_TYPE_UNUSED, "" },
{ 0x000400U, 0x000FFFU, 0x000400U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" },
{ 0x001000U, 0x001FFFU, 0x001000U, RC_MEMORY_TYPE_UNUSED, "" },
{ 0x002000U, 0x002FFFU, 0x002000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" },
{ 0x003000U, 0x003FFFU, 0x003000U, RC_MEMORY_TYPE_VIDEO_RAM, "Video RAM" },
{ 0x004000U, 0x00FFFFU, 0x004000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Cartridge RAM" },
};
static const rc_memory_regions_t rc_memory_regions_intellivision = { _rc_memory_regions_intellivision, 9 };
/* ===== Master System ===== */
/* http://www.smspower.org/Development/MemoryMap */
static const rc_memory_region_t _rc_memory_regions_master_system[] = {
{ 0x000000U, 0x001FFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_master_system = { _rc_memory_regions_master_system, 1 };
/* ===== MegaDrive (Genesis) ===== */
/* http://www.smspower.org/Development/MemoryMap */
static const rc_memory_region_t _rc_memory_regions_megadrive[] = {
{ 0x000000U, 0x00FFFFU, 0xFF0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x010000U, 0x01FFFFU, 0x000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
};
static const rc_memory_regions_t rc_memory_regions_megadrive = { _rc_memory_regions_megadrive, 2 };
/* ===== MSX ===== */
/* https://www.msx.org/wiki/The_Memory */
/* MSX only has 64KB of addressable RAM, of which 32KB is reserved for the system/BIOS.
* However, the system has up to 512KB of RAM, which is paged into the addressable RAM
* We expect the raw RAM to be exposed, rather than force the devs to worry about the
* paging system. The entire RAM is expected to appear starting at $10000, which is not
* addressable by the system itself.
*/
static const rc_memory_region_t _rc_memory_regions_msx[] = {
{ 0x000000U, 0x07FFFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
};
static const rc_memory_regions_t rc_memory_regions_msx = { _rc_memory_regions_msx, 1 };
/* ===== Neo Geo Pocket ===== */
/* http://neopocott.emuunlim.com/docs/tech-11.txt */
static const rc_memory_region_t _rc_memory_regions_neo_geo_pocket[] = {
/* MednafenNGP exposes 16KB, but the doc suggests there's 24-32KB */
{ 0x000000U, 0x003FFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_neo_geo_pocket = { _rc_memory_regions_neo_geo_pocket, 1 };
/* ===== Nintendo Entertainment System ===== */
/* https://wiki.nesdev.com/w/index.php/CPU_memory_map */
static const rc_memory_region_t _rc_memory_regions_nes[] = {
{ 0x0000U, 0x07FFU, 0x0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x0800U, 0x0FFFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */
{ 0x1000U, 0x17FFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */
{ 0x1800U, 0x1FFFU, 0x0000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirror RAM" }, /* duplicates memory from $0000-$07FF */
{ 0x2000U, 0x2007U, 0x2000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "PPU Register" },
{ 0x2008U, 0x3FFFU, 0x2008U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored PPU Register" }, /* repeats every 8 bytes */
{ 0x4000U, 0x4017U, 0x4000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "APU and I/O register" },
{ 0x4018U, 0x401FU, 0x4018U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "APU and I/O test register" },
{ 0x4020U, 0x5FFFU, 0x4020U, RC_MEMORY_TYPE_READONLY, "Cartridge data"}, /* varies by mapper */
{ 0x6000U, 0x7FFFU, 0x6000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM"},
{ 0x8000U, 0xFFFFU, 0x8000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM"},
};
static const rc_memory_regions_t rc_memory_regions_nes = { _rc_memory_regions_nes, 11 };
/* ===== Nintendo 64 ===== */
/* https://raw.githubusercontent.com/mikeryan/n64dev/master/docs/n64ops/n64ops%23h.txt */
static const rc_memory_region_t _rc_memory_regions_n64[] = {
{ 0x000000U, 0x1FFFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RDRAM 1 */
{ 0x200000U, 0x3FFFFFU, 0x00020000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RDRAM 2 */
{ 0x400000U, 0x7FFFFFU, 0x80000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } /* expansion pak - cannot find any details for real address */
};
static const rc_memory_regions_t rc_memory_regions_n64 = { _rc_memory_regions_n64, 3 };
/* ===== Nintendo DS ===== */
/* https://www.akkit.org/info/gbatek.htm#dsmemorymaps */
static const rc_memory_region_t _rc_memory_regions_nintendo_ds[] = {
{ 0x000000U, 0x3FFFFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_nintendo_ds = { _rc_memory_regions_nintendo_ds, 1 };
/* ===== Oric ===== */
static const rc_memory_region_t _rc_memory_regions_oric[] = {
/* actual size depends on machine type - up to 64KB */
{ 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_oric = { _rc_memory_regions_oric, 1 };
/* ===== PC-8800 ===== */
static const rc_memory_region_t _rc_memory_regions_pc8800[] = {
{ 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Main RAM" },
{ 0x010000U, 0x010FFFU, 0x010000U, RC_MEMORY_TYPE_VIDEO_RAM, "Text VRAM" } /* technically VRAM, but often used as system RAM */
};
static const rc_memory_regions_t rc_memory_regions_pc8800 = { _rc_memory_regions_pc8800, 2 };
/* ===== PC Engine ===== */
static const rc_memory_region_t _rc_memory_regions_pcengine[] = {
{ 0x000000U, 0x001FFFU, 0x1F0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x002000U, 0x011FFFU, 0x100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "CD RAM" },
{ 0x012000U, 0x041FFFU, 0x0D0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Super System Card RAM" },
{ 0x042000U, 0x0427FFU, 0x1EE000U, RC_MEMORY_TYPE_SAVE_RAM, "CD Battery-backed RAM" }
};
static const rc_memory_regions_t rc_memory_regions_pcengine = { _rc_memory_regions_pcengine, 4 };
/* ===== PlayStation ===== */
/* http://www.raphnet.net/electronique/psx_adaptor/Playstation.txt */
static const rc_memory_region_t _rc_memory_regions_playstation[] = {
{ 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Kernel RAM" },
{ 0x010000U, 0x1FFFFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_playstation = { _rc_memory_regions_playstation, 2 };
/* ===== Pokemon Mini ===== */
/* https://www.pokemon-mini.net/documentation/memory-map/ */
static const rc_memory_region_t _rc_memory_regions_pokemini[] = {
{ 0x000000U, 0x000FFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "BIOS RAM" },
{ 0x001000U, 0x001FFFU, 0x001000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_pokemini = { _rc_memory_regions_pokemini, 2 };
/* ===== Sega CD ===== */
static const rc_memory_region_t _rc_memory_regions_segacd[] = {
{ 0x000000U, 0x00FFFFU, 0x00FF0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "68000 RAM" },
{ 0x010000U, 0x08FFFFU, 0x80020000U, RC_MEMORY_TYPE_SAVE_RAM, "CD PRG RAM" } /* normally banked into $020000-$03FFFF */
};
static const rc_memory_regions_t rc_memory_regions_segacd = { _rc_memory_regions_segacd, 2 };
/* ===== Sega Saturn ===== */
/* https://segaretro.org/Sega_Saturn_hardware_notes_(2004-04-27) */
static const rc_memory_region_t _rc_memory_regions_saturn[] = {
{ 0x000000U, 0x0FFFFFU, 0x00200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Work RAM Low" },
{ 0x100000U, 0x1FFFFFU, 0x06000000U, RC_MEMORY_TYPE_SAVE_RAM, "Work RAM High" }
};
static const rc_memory_regions_t rc_memory_regions_saturn = { _rc_memory_regions_saturn, 2 };
/* ===== SG-1000 ===== */
/* http://www.smspower.org/Development/MemoryMap */
static const rc_memory_region_t _rc_memory_regions_sg1000[] = {
{ 0x000000U, 0x0003FFU, 0xC000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
/* TODO: should cartridge memory be exposed ($0000-$BFFF)? it's usually just ROM data, but may contain on-cartridge RAM
* This not is also concerning: http://www.smspower.org/Development/MemoryMap
* Cartridges may disable the system RAM and thus take over the full 64KB address space. */
};
static const rc_memory_regions_t rc_memory_regions_sg1000 = { _rc_memory_regions_sg1000, 1 };
/* ===== Super Cassette Vision ===== */
static const rc_memory_region_t _rc_memory_regions_scv[] = {
{ 0x000000U, 0x000FFFU, 0x000000U, RC_MEMORY_TYPE_READONLY, "System ROM" },
{ 0x001000U, 0x001FFFU, 0x001000U, RC_MEMORY_TYPE_UNUSED, "" },
{ 0x002000U, 0x003FFFU, 0x002000U, RC_MEMORY_TYPE_VIDEO_RAM, "Video RAM" },
{ 0x004000U, 0x007FFFU, 0x004000U, RC_MEMORY_TYPE_UNUSED, "" },
{ 0x008000U, 0x00DFFFU, 0x008000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM" },
{ 0x00E000U, 0x00FF7FU, 0x00E000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" },
{ 0x00FF80U, 0x00FFFFU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_scv = { _rc_memory_regions_scv, 7 };
/* ===== Super Nintendo ===== */
/* https://segaretro.org/Sega_Saturn_hardware_notes_(2004-04-27) */
static const rc_memory_region_t _rc_memory_regions_snes[] = {
{ 0x000000U, 0x01FFFFU, 0x7E0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x020000U, 0x03FFFFU, 0xFE0000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
};
static const rc_memory_regions_t rc_memory_regions_snes = { _rc_memory_regions_snes, 2 };
/* ===== WonderSwan ===== */
/* http://daifukkat.su/docs/wsman/#ovr_memmap */
static const rc_memory_region_t _rc_memory_regions_wonderswan[] = {
/* RAM ends at 0x3FFF for WonderSwan, WonderSwan color uses all 64KB */
{ 0x000000U, 0x00FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x010000U, 0x01FFFFU, 0x000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
};
static const rc_memory_regions_t rc_memory_regions_wonderswan = { _rc_memory_regions_wonderswan, 2 };
/* ===== Vectrex ===== */
/* https://roadsidethoughts.com/vectrex/vectrex-memory-map.htm */
static const rc_memory_region_t _rc_memory_regions_vectrex[] = {
{ 0x000000U, 0x0003FFU, 0x00C800U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_vectrex = { _rc_memory_regions_vectrex, 1 };
/* ===== Virtual Boy ===== */
static const rc_memory_region_t _rc_memory_regions_virtualboy[] = {
{ 0x000000U, 0x00FFFFU, 0x05000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x010000U, 0x01FFFFU, 0x06000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
};
static const rc_memory_regions_t rc_memory_regions_virtualboy = { _rc_memory_regions_virtualboy, 2 };
/* ===== default ===== */
static const rc_memory_regions_t rc_memory_regions_none = { 0, 0 };
const rc_memory_regions_t* rc_console_memory_regions(int console_id)
{
switch (console_id)
{
case RC_CONSOLE_3DO:
return &rc_memory_regions_3do;
case RC_CONSOLE_APPLE_II:
return &rc_memory_regions_appleii;
case RC_CONSOLE_ATARI_2600:
return &rc_memory_regions_atari2600;
case RC_CONSOLE_ATARI_7800:
return &rc_memory_regions_atari7800;
case RC_CONSOLE_ATARI_JAGUAR:
return &rc_memory_regions_atari_jaguar;
case RC_CONSOLE_ATARI_LYNX:
return &rc_memory_regions_atari_lynx;
case RC_CONSOLE_COLECOVISION:
return &rc_memory_regions_colecovision;
case RC_CONSOLE_GAMEBOY:
return &rc_memory_regions_gameboy;
case RC_CONSOLE_GAMEBOY_COLOR:
return &rc_memory_regions_gameboy_color;
case RC_CONSOLE_GAMEBOY_ADVANCE:
return &rc_memory_regions_gameboy_advance;
case RC_CONSOLE_GAME_GEAR:
return &rc_memory_regions_game_gear;
case RC_CONSOLE_INTELLIVISION:
return &rc_memory_regions_intellivision;
case RC_CONSOLE_MASTER_SYSTEM:
return &rc_memory_regions_master_system;
case RC_CONSOLE_MEGA_DRIVE:
case RC_CONSOLE_SEGA_32X:
/* NOTE: 32x adds an extra 512KB of memory (256KB RAM + 256KB VRAM) to the
* Genesis, but we currently don't support it. */
return &rc_memory_regions_megadrive;
case RC_CONSOLE_MSX:
return &rc_memory_regions_msx;
case RC_CONSOLE_NEOGEO_POCKET:
return &rc_memory_regions_neo_geo_pocket;
case RC_CONSOLE_NINTENDO:
return &rc_memory_regions_nes;
case RC_CONSOLE_NINTENDO_64:
return &rc_memory_regions_n64;
case RC_CONSOLE_NINTENDO_DS:
return &rc_memory_regions_nintendo_ds;
case RC_CONSOLE_ORIC:
return &rc_memory_regions_oric;
case RC_CONSOLE_PC8800:
return &rc_memory_regions_pc8800;
case RC_CONSOLE_PC_ENGINE:
return &rc_memory_regions_pcengine;
case RC_CONSOLE_PLAYSTATION:
return &rc_memory_regions_playstation;
case RC_CONSOLE_POKEMON_MINI:
return &rc_memory_regions_pokemini;
case RC_CONSOLE_SATURN:
return &rc_memory_regions_saturn;
case RC_CONSOLE_SEGA_CD:
return &rc_memory_regions_segacd;
case RC_CONSOLE_SG1000:
return &rc_memory_regions_sg1000;
case RC_CONSOLE_SUPER_CASSETTEVISION:
return &rc_memory_regions_scv;
case RC_CONSOLE_SUPER_NINTENDO:
return &rc_memory_regions_snes;
case RC_CONSOLE_WONDERSWAN:
return &rc_memory_regions_wonderswan;
case RC_CONSOLE_VECTREX:
return &rc_memory_regions_vectrex;
case RC_CONSOLE_VIRTUAL_BOY:
return &rc_memory_regions_virtualboy;
default:
return &rc_memory_regions_none;
}
}
-41
View File
@@ -1,41 +0,0 @@
#include "internal.h"
rc_expression_t* rc_parse_expression(const char** memaddr, rc_parse_state_t* parse) {
rc_expression_t* self;
rc_term_t** next;
self = RC_ALLOC(rc_expression_t, parse);
next = &self->terms;
for (;;) {
*next = rc_parse_term(memaddr, 0, parse);
if (parse->offset < 0) {
return 0;
}
next = &(*next)->next;
if (**memaddr != '_') {
break;
}
(*memaddr)++;
}
*next = 0;
return self;
}
int rc_evaluate_expression(rc_expression_t* self, rc_eval_state_t* eval_state) {
rc_term_t* term;
int value;
value = 0;
for (term = self->terms; term != 0; term = term->next) {
value += rc_evaluate_term(term, eval_state);
}
return value;
}
+5 -3
View File
@@ -1,5 +1,7 @@
#include "internal.h"
#include "compat.h"
#include <string.h>
#include <stdio.h>
@@ -11,7 +13,7 @@ int rc_parse_format(const char* format_str) {
}
break;
case 'T':
if (!strcmp(format_str, "IME")) {
return RC_FORMAT_FRAMES;
@@ -21,7 +23,7 @@ int rc_parse_format(const char* format_str) {
}
break;
case 'S':
if (!strcmp(format_str, "ECS")) {
return RC_FORMAT_SECONDS;
@@ -34,7 +36,7 @@ int rc_parse_format(const char* format_str) {
}
break;
case 'M':
if (!strcmp(format_str, "ILLISECS")) {
return RC_FORMAT_CENTISECS;
+4 -11
View File
@@ -6,7 +6,6 @@
#define RC_ALLOW_ALIGN(T) struct __align_ ## T { char ch; T t; };
RC_ALLOW_ALIGN(rc_condition_t)
RC_ALLOW_ALIGN(rc_condset_t)
RC_ALLOW_ALIGN(rc_expression_t)
RC_ALLOW_ALIGN(rc_lboard_t)
RC_ALLOW_ALIGN(rc_memref_value_t)
RC_ALLOW_ALIGN(rc_operand_t)
@@ -15,7 +14,6 @@ RC_ALLOW_ALIGN(rc_richpresence_display_t)
RC_ALLOW_ALIGN(rc_richpresence_display_part_t)
RC_ALLOW_ALIGN(rc_richpresence_lookup_t)
RC_ALLOW_ALIGN(rc_richpresence_lookup_item_t)
RC_ALLOW_ALIGN(rc_term_t)
RC_ALLOW_ALIGN(rc_trigger_t)
RC_ALLOW_ALIGN(rc_value_t)
RC_ALLOW_ALIGN(char)
@@ -36,8 +34,6 @@ typedef struct {
rc_condition_t condition;
rc_condset_t condset;
rc_trigger_t trigger;
rc_term_t term;
rc_expression_t expression;
rc_lboard_t lboard;
rc_memref_value_t memref_value;
rc_richpresence_t richpresence;
@@ -61,6 +57,8 @@ typedef struct {
unsigned measured_value; /* Measured */
char was_reset; /* ResetIf triggered */
char has_hits; /* one of more hit counts is non-zero */
char primed; /* true if all non-Trigger conditions are true */
char measured_from_hits; /* true if the measured_value came from a condition's hit count */
}
rc_eval_state_t;
@@ -86,7 +84,7 @@ void rc_destroy_parse_state(rc_parse_state_t* parse);
void* rc_alloc(void* pointer, int* offset, int size, int alignment, rc_scratch_t* scratch);
char* rc_alloc_str(rc_parse_state_t* parse, const char* text, int length);
rc_memref_value_t* rc_alloc_memref_value(rc_parse_state_t* parse, unsigned address, char size, char is_bcd, char is_indirect);
rc_memref_value_t* rc_alloc_memref_value(rc_parse_state_t* parse, unsigned address, char size, char is_indirect);
void rc_update_memref_values(rc_memref_value_t* memref, rc_peek_t peek, void* ud);
void rc_update_memref_value(rc_memref_value_t* memref, rc_peek_t peek, void* ud);
rc_memref_value_t* rc_get_indirect_memref(rc_memref_value_t* memref, rc_eval_state_t* eval_state);
@@ -99,16 +97,11 @@ void rc_reset_condset(rc_condset_t* self);
rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse, int is_indirect);
int rc_test_condition(rc_condition_t* self, rc_eval_state_t* eval_state);
int rc_evaluate_condition_value(rc_condition_t* self, rc_eval_state_t* eval_state);
int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, int is_indirect, rc_parse_state_t* parse);
unsigned rc_evaluate_operand(rc_operand_t* self, rc_eval_state_t* eval_state);
rc_term_t* rc_parse_term(const char** memaddr, int is_indirect, rc_parse_state_t* parse);
int rc_evaluate_term(rc_term_t* self, rc_eval_state_t* eval_state);
rc_expression_t* rc_parse_expression(const char** memaddr, rc_parse_state_t* parse);
int rc_evaluate_expression(rc_expression_t* self, rc_eval_state_t* eval_state);
void rc_parse_value_internal(rc_value_t* self, const char** memaddr, rc_parse_state_t* parse);
void rc_parse_lboard_internal(rc_lboard_t* self, const char* memaddr, rc_parse_state_t* parse);
+61 -54
View File
@@ -133,7 +133,7 @@ void rc_parse_lboard_internal(rc_lboard_t* self, const char* memaddr, rc_parse_s
return;
}
self->started = self->submitted = 0;
self->state = RC_LBOARD_STATE_WAITING;
}
int rc_lboard_size(const char* memaddr) {
@@ -164,82 +164,89 @@ rc_lboard_t* rc_parse_lboard(void* buffer, const char* memaddr, lua_State* L, in
int rc_evaluate_lboard(rc_lboard_t* self, int* value, rc_peek_t peek, void* peek_ud, lua_State* L) {
int start_ok, cancel_ok, submit_ok;
int action = -1;
rc_update_memref_values(self->memrefs, peek, peek_ud);
/* ASSERT: these are always tested once every frame, to ensure delta variables work properly */
if (self->state == RC_LBOARD_STATE_INACTIVE)
return RC_LBOARD_STATE_INACTIVE;
/* these are always tested once every frame, to ensure hit counts work properly */
start_ok = rc_test_trigger(&self->start, peek, peek_ud, L);
cancel_ok = rc_test_trigger(&self->cancel, peek, peek_ud, L);
submit_ok = rc_test_trigger(&self->submit, peek, peek_ud, L);
if (self->submitted) {
/* if we've already submitted or canceled the leaderboard, don't reactivate it until it becomes inactive. */
if (!start_ok) {
self->submitted = 0;
}
}
else if (!self->started) {
/* leaderboard is not active, if the start condition is true, activate it */
if (start_ok && !cancel_ok) {
if (submit_ok) {
/* start and submit both true in the same frame, just submit without announcing the leaderboard is available */
action = RC_LBOARD_TRIGGERED;
/* prevent multiple submissions/notifications */
self->submitted = 1;
switch (self->state)
{
case RC_LBOARD_STATE_WAITING:
case RC_LBOARD_STATE_TRIGGERED:
case RC_LBOARD_STATE_CANCELED:
/* don't activate/reactivate until the start condition becomes false */
if (start_ok) {
*value = 0;
return RC_LBOARD_STATE_INACTIVE; /* just return inactive for all of these */
}
else if (self->start.requirement != 0 || self->start.alternative != 0) {
self->started = 1;
action = RC_LBOARD_STARTED;
}
}
}
else {
/* leaderboard is active */
if (cancel_ok) {
/* cancel condition is true, deactivate the leaderboard */
self->started = 0;
action = RC_LBOARD_CANCELED;
/* prevent multiple cancel notifications */
self->submitted = 1;
}
else if (submit_ok) {
/* submit condition is true, submit the current value */
self->started = 0;
action = RC_LBOARD_TRIGGERED;
self->submitted = 1;
}
}
if (action == -1) {
action = self->started ? RC_LBOARD_ACTIVE : RC_LBOARD_INACTIVE;
/* start condition is false, allow the leaderboard to start on future frames */
self->state = RC_LBOARD_STATE_ACTIVE;
break;
case RC_LBOARD_STATE_ACTIVE:
/* leaderboard attempt is not in progress. if the start condition is true and the cancel condition is not, start the attempt */
if (start_ok && !cancel_ok) {
if (submit_ok) {
/* start and submit are both true in the same frame, just submit without announcing the leaderboard is available */
self->state = RC_LBOARD_STATE_TRIGGERED;
}
else if (self->start.requirement == 0 && self->start.alternative == 0) {
/* start condition is empty - this leaderboard is submit-only with no measured progress */
}
else {
/* start the leaderboard attempt */
self->state = RC_LBOARD_STATE_STARTED;
/* reset any hit counts in the value */
if (self->value.conditions)
rc_reset_condset(self->value.conditions);
}
}
break;
case RC_LBOARD_STATE_STARTED:
/* leaderboard attempt in progress */
if (cancel_ok) {
/* cancel condition is true, abort the attempt */
self->state = RC_LBOARD_STATE_CANCELED;
}
else if (submit_ok) {
/* submit condition is true, submit the current value */
self->state = RC_LBOARD_STATE_TRIGGERED;
}
break;
}
/* Calculate the value */
switch (action) {
case RC_LBOARD_STARTED:
if (self->value.conditions)
rc_reset_condset(self->value.conditions);
/* fall through */
case RC_LBOARD_ACTIVE:
*value = rc_evaluate_value(self->progress != 0 ? self->progress : &self->value, peek, peek_ud, L);
break;
switch (self->state) {
case RC_LBOARD_STATE_STARTED:
if (self->progress) {
*value = rc_evaluate_value(self->progress, peek, peek_ud, L);
break;
}
/* fallthrough to RC_LBOARD_STATE_TRIGGERED */
case RC_LBOARD_TRIGGERED:
case RC_LBOARD_STATE_TRIGGERED:
*value = rc_evaluate_value(&self->value, peek, peek_ud, L);
break;
case RC_LBOARD_INACTIVE:
case RC_LBOARD_CANCELED:
default:
*value = 0;
break;
}
return action;
return self->state;
}
void rc_reset_lboard(rc_lboard_t* self) {
self->started = self->submitted = 0;
self->state = RC_LBOARD_STATE_WAITING;
rc_reset_trigger(&self->start);
rc_reset_trigger(&self->submit);
+12 -49
View File
@@ -5,7 +5,7 @@
#define MEMREF_PLACEHOLDER_ADDRESS 0xFFFFFFFF
static rc_memref_value_t* rc_alloc_memref_value_sizing_mode(rc_parse_state_t* parse, unsigned address, char size, char is_bcd, char is_indirect) {
static rc_memref_value_t* rc_alloc_memref_value_sizing_mode(rc_parse_state_t* parse, unsigned address, char size, char is_indirect) {
rc_memref_t* memref;
int i;
@@ -20,7 +20,7 @@ static rc_memref_value_t* rc_alloc_memref_value_sizing_mode(rc_parse_state_t* pa
/* have to track unique address/size/bcd combinations - use scratch.memref for sizing mode */
for (i = 0; i < parse->scratch.memref_count; ++i) {
memref = &parse->scratch.memref[i];
if (memref->address == address && memref->size == size && memref->is_bcd == is_bcd) {
if (memref->address == address && memref->size == size) {
return &parse->scratch.obj.memref_value;
}
}
@@ -57,7 +57,6 @@ static rc_memref_value_t* rc_alloc_memref_value_sizing_mode(rc_parse_state_t* pa
memref = &parse->scratch.memref[parse->scratch.memref_count++];
memref->address = address;
memref->size = size;
memref->is_bcd = is_bcd;
memref->is_indirect = is_indirect;
}
@@ -65,7 +64,7 @@ static rc_memref_value_t* rc_alloc_memref_value_sizing_mode(rc_parse_state_t* pa
return RC_ALLOC(rc_memref_value_t, parse);
}
static rc_memref_value_t* rc_alloc_memref_value_constuct_mode(rc_parse_state_t* parse, unsigned address, char size, char is_bcd, char is_indirect) {
static rc_memref_value_t* rc_alloc_memref_value_constuct_mode(rc_parse_state_t* parse, unsigned address, char size, char is_indirect) {
rc_memref_value_t** next_memref_value;
rc_memref_value_t* memref_value;
rc_memref_value_t* indirect_memref_value;
@@ -75,8 +74,8 @@ static rc_memref_value_t* rc_alloc_memref_value_constuct_mode(rc_parse_state_t*
next_memref_value = parse->first_memref;
while (*next_memref_value) {
memref_value = *next_memref_value;
if (!memref_value->memref.is_indirect && memref_value->memref.address == address &&
memref_value->memref.size == size && memref_value->memref.is_bcd == is_bcd) {
if (!memref_value->memref.is_indirect && memref_value->memref.address == address &&
memref_value->memref.size == size) {
return memref_value;
}
@@ -96,7 +95,6 @@ static rc_memref_value_t* rc_alloc_memref_value_constuct_mode(rc_parse_state_t*
memref_value = RC_ALLOC(rc_memref_value_t, parse);
memref_value->memref.address = address;
memref_value->memref.size = size;
memref_value->memref.is_bcd = is_bcd;
memref_value->memref.is_indirect = is_indirect;
memref_value->value = 0;
memref_value->previous = 0;
@@ -110,7 +108,6 @@ static rc_memref_value_t* rc_alloc_memref_value_constuct_mode(rc_parse_state_t*
indirect_memref_value = RC_ALLOC(rc_memref_value_t, parse);
indirect_memref_value->memref.address = MEMREF_PLACEHOLDER_ADDRESS;
indirect_memref_value->memref.size = size;
indirect_memref_value->memref.is_bcd = is_bcd;
indirect_memref_value->memref.is_indirect = 1;
indirect_memref_value->value = 0;
indirect_memref_value->previous = 0;
@@ -123,16 +120,19 @@ static rc_memref_value_t* rc_alloc_memref_value_constuct_mode(rc_parse_state_t*
return memref_value;
}
rc_memref_value_t* rc_alloc_memref_value(rc_parse_state_t* parse, unsigned address, char size, char is_bcd, char is_indirect) {
rc_memref_value_t* rc_alloc_memref_value(rc_parse_state_t* parse, unsigned address, char size, char is_indirect) {
if (!parse->first_memref)
return rc_alloc_memref_value_sizing_mode(parse, address, size, is_bcd, is_indirect);
return rc_alloc_memref_value_sizing_mode(parse, address, size, is_indirect);
return rc_alloc_memref_value_constuct_mode(parse, address, size, is_bcd, is_indirect);
return rc_alloc_memref_value_constuct_mode(parse, address, size, is_indirect);
}
static unsigned rc_memref_get_value(rc_memref_t* self, rc_peek_t peek, void* ud) {
unsigned value;
if (!peek)
return 0;
switch (self->size)
{
case RC_MEMSIZE_BIT_0:
@@ -177,56 +177,19 @@ static unsigned rc_memref_get_value(rc_memref_t* self, rc_peek_t peek, void* ud)
case RC_MEMSIZE_8_BITS:
value = peek(self->address, 1, ud);
if (self->is_bcd) {
value = ((value >> 4) & 0x0f) * 10 + (value & 0x0f);
}
break;
case RC_MEMSIZE_16_BITS:
value = peek(self->address, 2, ud);
if (self->is_bcd) {
value = ((value >> 12) & 0x0f) * 1000
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value >> 0) & 0x0f) * 1;
}
break;
case RC_MEMSIZE_24_BITS:
/* peek 4 bytes - don't expect the caller to understand 24-bit numbers */
value = peek(self->address, 4, ud);
if (self->is_bcd) {
value = ((value >> 20) & 0x0f) * 100000
+ ((value >> 16) & 0x0f) * 10000
+ ((value >> 12) & 0x0f) * 1000
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value >> 0) & 0x0f) * 1;
} else {
value &= 0x00FFFFFF;
}
value = peek(self->address, 4, ud) & 0x00FFFFFF;
break;
case RC_MEMSIZE_32_BITS:
value = peek(self->address, 4, ud);
if (self->is_bcd) {
value = ((value >> 28) & 0x0f) * 10000000
+ ((value >> 24) & 0x0f) * 1000000
+ ((value >> 20) & 0x0f) * 100000
+ ((value >> 16) & 0x0f) * 10000
+ ((value >> 12) & 0x0f) * 1000
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value >> 0) & 0x0f) * 1;
}
break;
default:
+243 -147
View File
@@ -70,7 +70,6 @@ static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr, rc_
const char* aux = *memaddr;
char* end;
unsigned long address;
char is_bcd = 0;
char size;
switch (*aux++) {
@@ -78,15 +77,18 @@ static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr, rc_
self->type = RC_OPERAND_DELTA;
break;
case 'b': case 'B':
self->type = RC_OPERAND_ADDRESS;
is_bcd = 1;
break;
case 'p': case 'P':
self->type = RC_OPERAND_PRIOR;
break;
case 'b': case 'B':
self->type = RC_OPERAND_BCD;
break;
case '~':
self->type = RC_OPERAND_INVERTED;
break;
default:
self->type = RC_OPERAND_ADDRESS;
aux--;
@@ -104,25 +106,33 @@ static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr, rc_
aux++;
switch (*aux++) {
case 'm': case 'M': size = RC_MEMSIZE_BIT_0; break;
case 'n': case 'N': size = RC_MEMSIZE_BIT_1; break;
case 'o': case 'O': size = RC_MEMSIZE_BIT_2; break;
case 'p': case 'P': size = RC_MEMSIZE_BIT_3; break;
case 'q': case 'Q': size = RC_MEMSIZE_BIT_4; break;
case 'r': case 'R': size = RC_MEMSIZE_BIT_5; break;
case 's': case 'S': size = RC_MEMSIZE_BIT_6; break;
case 't': case 'T': size = RC_MEMSIZE_BIT_7; break;
case 'l': case 'L': size = RC_MEMSIZE_LOW; break;
case 'u': case 'U': size = RC_MEMSIZE_HIGH; break;
case 'h': case 'H': size = RC_MEMSIZE_8_BITS; break;
case 'w': case 'W': size = RC_MEMSIZE_24_BITS; break;
case 'x': case 'X': size = RC_MEMSIZE_32_BITS; break;
case 'm': case 'M': self->size = RC_MEMSIZE_BIT_0; size = RC_MEMSIZE_8_BITS; break;
case 'n': case 'N': self->size = RC_MEMSIZE_BIT_1; size = RC_MEMSIZE_8_BITS; break;
case 'o': case 'O': self->size = RC_MEMSIZE_BIT_2; size = RC_MEMSIZE_8_BITS; break;
case 'p': case 'P': self->size = RC_MEMSIZE_BIT_3; size = RC_MEMSIZE_8_BITS; break;
case 'q': case 'Q': self->size = RC_MEMSIZE_BIT_4; size = RC_MEMSIZE_8_BITS; break;
case 'r': case 'R': self->size = RC_MEMSIZE_BIT_5; size = RC_MEMSIZE_8_BITS; break;
case 's': case 'S': self->size = RC_MEMSIZE_BIT_6; size = RC_MEMSIZE_8_BITS; break;
case 't': case 'T': self->size = RC_MEMSIZE_BIT_7; size = RC_MEMSIZE_8_BITS; break;
case 'l': case 'L': self->size = RC_MEMSIZE_LOW; size = RC_MEMSIZE_8_BITS; break;
case 'u': case 'U': self->size = RC_MEMSIZE_HIGH; size = RC_MEMSIZE_8_BITS; break;
case 'k': case 'K': self->size = RC_MEMSIZE_BITCOUNT; size = RC_MEMSIZE_8_BITS; break;
case 'h': case 'H': self->size = size = RC_MEMSIZE_8_BITS; break;
case 'w': case 'W': self->size = size = RC_MEMSIZE_24_BITS; break;
case 'x': case 'X': self->size = size = RC_MEMSIZE_32_BITS; break;
default: /* fall through */
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
aux--;
/* fallthrough */
case ' ':
size = RC_MEMSIZE_16_BITS;
self->size = size = RC_MEMSIZE_16_BITS;
break;
default:
return RC_INVALID_MEMORY_OPERAND;
}
address = strtoul(aux, &end, 16);
@@ -135,7 +145,7 @@ static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr, rc_
address = 0xffffffffU;
}
self->value.memref = rc_alloc_memref_value(parse, address, size, is_bcd, is_indirect);
self->value.memref = rc_alloc_memref_value(parse, address, size, is_indirect);
if (parse->offset < 0)
return parse->offset;
@@ -143,14 +153,17 @@ static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr, rc_
return RC_OK;
}
static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, int is_indirect, rc_parse_state_t* parse) {
int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, int is_indirect, rc_parse_state_t* parse) {
const char* aux = *memaddr;
char* end;
int ret;
unsigned long value;
int negative;
self->size = RC_MEMSIZE_32_BITS;
switch (*aux) {
case 'h': case 'H':
case 'h': case 'H': /* hex constant */
if (aux[2] == 'x' || aux[2] == 'X') {
/* H0x1234 is a typo - either H1234 or 0xH1234 was probably meant */
return RC_INVALID_CONST_OPERAND;
@@ -171,115 +184,9 @@ static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, in
aux = end;
break;
case '0':
if (aux[1] == 'x' || aux[1] == 'X') {
/* fall through */
default:
ret = rc_parse_operand_memory(self, &aux, parse, is_indirect);
if (ret < 0) {
return ret;
}
break;
}
/* fall through */
case '+': case '-':
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
value = strtoul(aux, &end, 10);
if (end == aux) {
return RC_INVALID_CONST_OPERAND;
}
if (value > 0xffffffffU) {
value = 0xffffffffU;
}
self->type = RC_OPERAND_CONST;
self->value.num = (unsigned)value;
aux = end;
break;
case '@':
ret = rc_parse_operand_lua(self, &aux, parse);
if (ret < 0) {
return ret;
}
break;
}
*memaddr = aux;
return RC_OK;
}
static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, int is_indirect, rc_parse_state_t* parse) {
const char* aux = *memaddr;
char* end;
int ret;
unsigned long value;
long svalue;
switch (*aux) {
case 'h': case 'H':
value = strtoul(++aux, &end, 16);
if (end == aux) {
return RC_INVALID_CONST_OPERAND;
}
if (value > 0xffffffffU) {
value = 0xffffffffU;
}
self->type = RC_OPERAND_CONST;
self->value.num = (unsigned)value;
aux = end;
break;
case 'v': case 'V':
svalue = strtol(++aux, &end, 10);
if (end == aux) {
return RC_INVALID_CONST_OPERAND;
}
if (svalue > 0xffffffffU) {
svalue = 0xffffffffU;
}
self->type = RC_OPERAND_CONST;
self->value.num = (unsigned)svalue;
aux = end;
break;
case '0':
if (aux[1] == 'x' || aux[1] == 'X') {
/* fall through */
default:
ret = rc_parse_operand_memory(self, &aux, parse, is_indirect);
if (ret < 0) {
return ret;
}
break;
}
/* fall through */
case '.':
case '+': case '-':
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
self->value.dbl = strtod(aux, &end);
case 'f': case 'F': /* floating point constant */
self->value.dbl = strtod(++aux, &end);
if (end == aux) {
return RC_INVALID_FP_OPERAND;
@@ -292,9 +199,77 @@ static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, int i
else {
self->type = RC_OPERAND_FP;
}
aux = end;
break;
case 'v': case 'V': /* signed integer constant */
negative = 0;
++aux;
if (*aux == '-')
{
negative = 1;
++aux;
}
else if (*aux == '+')
{
++aux;
}
value = strtoul(aux, &end, 10);
if (end == aux) {
return RC_INVALID_CONST_OPERAND;
}
if (value > 0x7fffffffU) {
value = 0x7fffffffU;
}
self->type = RC_OPERAND_CONST;
if (negative)
self->value.num = (unsigned)(-((long)value));
else
self->value.num = (unsigned)value;
aux = end;
break;
case '0':
if (aux[1] == 'x' || aux[1] == 'X') {
/* fall through */
default:
ret = rc_parse_operand_memory(self, &aux, parse, is_indirect);
if (ret < 0) {
return ret;
}
break;
}
/* fall through for case '0' where not '0x' */
case '+': case '-':
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
value = strtoul(aux, &end, 10);
if (end == aux) {
return RC_INVALID_CONST_OPERAND;
}
if (value > 0xffffffffU) {
value = 0xffffffffU;
}
self->type = RC_OPERAND_CONST;
self->value.num = (unsigned)value;
aux = end;
break;
case '@':
ret = rc_parse_operand_lua(self, &aux, parse);
@@ -309,15 +284,6 @@ static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, int i
return RC_OK;
}
int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, int is_indirect, rc_parse_state_t* parse) {
if (is_trigger) {
return rc_parse_operand_trigger(self, memaddr, is_indirect, parse);
}
else {
return rc_parse_operand_term(self, memaddr, is_indirect, parse);
}
}
#ifndef RC_DISABLE_LUA
typedef struct {
@@ -339,6 +305,8 @@ static int rc_luapeek(lua_State* L) {
#endif /* RC_DISABLE_LUA */
static const unsigned char rc_bits_set[16] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
unsigned rc_evaluate_operand(rc_operand_t* self, rc_eval_state_t* eval_state) {
#ifndef RC_DISABLE_LUA
rc_luapeek_t luapeek;
@@ -346,15 +314,15 @@ unsigned rc_evaluate_operand(rc_operand_t* self, rc_eval_state_t* eval_state) {
unsigned value = 0;
/* step 1: read memory */
switch (self->type) {
case RC_OPERAND_CONST:
value = self->value.num;
break;
return self->value.num;
case RC_OPERAND_FP:
/* This is handled by rc_evaluate_expression. */
/* This is handled by rc_evaluate_condition_value. */
return 0;
case RC_OPERAND_LUA:
#ifndef RC_DISABLE_LUA
@@ -366,7 +334,7 @@ unsigned rc_evaluate_operand(rc_operand_t* self, rc_eval_state_t* eval_state) {
luapeek.ud = eval_state->peek_userdata;
lua_pushlightuserdata(eval_state->L, &luapeek);
if (lua_pcall(eval_state->L, 2, 1, 0) == LUA_OK) {
if (lua_isboolean(eval_state->L, -1)) {
value = lua_toboolean(eval_state->L, -1);
@@ -384,6 +352,8 @@ unsigned rc_evaluate_operand(rc_operand_t* self, rc_eval_state_t* eval_state) {
break;
case RC_OPERAND_ADDRESS:
case RC_OPERAND_BCD:
case RC_OPERAND_INVERTED:
value = rc_get_indirect_memref(self->value.memref, eval_state)->value;
break;
@@ -396,5 +366,131 @@ unsigned rc_evaluate_operand(rc_operand_t* self, rc_eval_state_t* eval_state) {
break;
}
/* step 2: mask off appropriate bits */
switch (self->size)
{
case RC_MEMSIZE_BIT_0:
value = (value >> 0) & 1;
break;
case RC_MEMSIZE_BIT_1:
value = (value >> 1) & 1;
break;
case RC_MEMSIZE_BIT_2:
value = (value >> 2) & 1;
break;
case RC_MEMSIZE_BIT_3:
value = (value >> 3) & 1;
break;
case RC_MEMSIZE_BIT_4:
value = (value >> 4) & 1;
break;
case RC_MEMSIZE_BIT_5:
value = (value >> 5) & 1;
break;
case RC_MEMSIZE_BIT_6:
value = (value >> 6) & 1;
break;
case RC_MEMSIZE_BIT_7:
value = (value >> 7) & 1;
break;
case RC_MEMSIZE_LOW:
value = value & 0x0f;
break;
case RC_MEMSIZE_HIGH:
value = (value >> 4) & 0x0f;
break;
case RC_MEMSIZE_BITCOUNT:
value = rc_bits_set[(value & 0x0F)]
+ rc_bits_set[((value >> 4) & 0x0F)];
break;
}
/* step 3: apply logic */
switch (self->type)
{
case RC_OPERAND_BCD:
switch (self->size)
{
case RC_MEMSIZE_8_BITS:
value = ((value >> 4) & 0x0f) * 10
+ ((value ) & 0x0f);
break;
case RC_MEMSIZE_16_BITS:
value = ((value >> 12) & 0x0f) * 1000
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value ) & 0x0f);
break;
case RC_MEMSIZE_24_BITS:
value = ((value >> 20) & 0x0f) * 100000
+ ((value >> 16) & 0x0f) * 10000
+ ((value >> 12) & 0x0f) * 1000
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value ) & 0x0f);
break;
case RC_MEMSIZE_32_BITS:
value = ((value >> 28) & 0x0f) * 10000000
+ ((value >> 24) & 0x0f) * 1000000
+ ((value >> 20) & 0x0f) * 100000
+ ((value >> 16) & 0x0f) * 10000
+ ((value >> 12) & 0x0f) * 1000
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value ) & 0x0f);
break;
default:
break;
}
break;
case RC_OPERAND_INVERTED:
switch (self->size)
{
case RC_MEMSIZE_LOW:
case RC_MEMSIZE_HIGH:
value ^= 0x0f;
break;
case RC_MEMSIZE_8_BITS:
value ^= 0xff;
break;
case RC_MEMSIZE_16_BITS:
value ^= 0xffff;
break;
case RC_MEMSIZE_24_BITS:
value ^= 0xffffff;
break;
case RC_MEMSIZE_32_BITS:
value ^= 0xffffffff;
break;
default:
value ^= 0x01;
break;
}
break;
default:
break;
}
return value;
}
+43 -15
View File
@@ -1,9 +1,8 @@
#include "internal.h"
#include "compat.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* special formats only used by rc_richpresence_display_part_t.display_type. must not overlap other RC_FORMAT values */
enum {
@@ -116,6 +115,7 @@ static rc_richpresence_display_t* rc_parse_richpresence_display_internal(const c
/* just calculating size, can't confirm lookup exists */
part = RC_ALLOC(rc_richpresence_display_part_t, parse);
in = line;
line = ++ptr;
while (ptr < endline && *ptr != ')')
++ptr;
@@ -124,6 +124,10 @@ static rc_richpresence_display_t* rc_parse_richpresence_display_internal(const c
if (parse->offset < 0)
return 0;
++ptr;
} else {
/* no closing parenthesis - allocate space for the invalid string */
--in; /* already skipped over @ */
rc_alloc_str(parse, line, (int)(ptr - in));
}
} else {
@@ -139,6 +143,7 @@ static rc_richpresence_display_t* rc_parse_richpresence_display_internal(const c
part->first_lookup_item = lookup->first_item;
part->display_type = lookup->format;
in = line;
line = ++ptr;
while (ptr < endline && *ptr != ')')
++ptr;
@@ -149,6 +154,12 @@ static rc_richpresence_display_t* rc_parse_richpresence_display_internal(const c
return 0;
++ptr;
}
else {
/* non-terminated macro, dump the macro and the remaining portion of the line */
--in; /* already skipped over @ */
part->display_type = RC_FORMAT_STRING;
part->text = rc_alloc_str(parse, in, (int)(ptr - in));
}
break;
}
@@ -170,7 +181,7 @@ static rc_richpresence_display_t* rc_parse_richpresence_display_internal(const c
/* assert: the allocated string is going to be smaller than the memory used for the parameter of the macro */
part->display_type = RC_FORMAT_UNKNOWN_MACRO;
part->text = rc_alloc_str(parse, line, ptr - line);
part->text = rc_alloc_str(parse, line, (int)(ptr - line));
}
}
}
@@ -194,7 +205,7 @@ static const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup
const char* defaultlabel = 0;
char* endptr = 0;
unsigned key;
int chars;
unsigned chars;
next = &lookup->first_item;
@@ -372,7 +383,7 @@ int rc_richpresence_size(const char* script) {
rc_richpresence_t* self;
rc_parse_state_t parse;
rc_init_parse_state(&parse, 0, 0, 0);
self = RC_ALLOC(rc_richpresence_t, &parse);
rc_parse_richpresence_internal(self, script, &parse);
@@ -389,7 +400,7 @@ rc_richpresence_t* rc_parse_richpresence(void* buffer, const char* script, lua_S
rc_init_parse_state_memrefs(&parse, &self->memrefs);
rc_parse_richpresence_internal(self, script, &parse);
rc_destroy_parse_state(&parse);
return parse.offset >= 0 ? self : 0;
}
@@ -398,8 +409,10 @@ int rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, unsi
rc_richpresence_display_t* display;
rc_richpresence_display_part_t* part;
rc_richpresence_lookup_item_t* item;
char tmp[256];
char* ptr;
int chars;
const char* text;
size_t chars;
unsigned value;
rc_update_memref_values(richpresence->memrefs, peek, peek_ud);
@@ -412,37 +425,52 @@ int rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, unsi
while (part) {
switch (part->display_type) {
case RC_FORMAT_STRING:
chars = snprintf(ptr, buffersize, "%s", part->text);
text = part->text;
chars = strlen(text);
break;
case RC_FORMAT_LOOKUP:
value = rc_evaluate_value(&part->value, peek, peek_ud, L);
item = part->first_lookup_item;
if (!item) {
text = "";
chars = 0;
} else {
while (item->next_item && item->value != value)
item = item->next_item;
chars = snprintf(ptr, buffersize, "%s", item->label);
text = item->label;
chars = strlen(text);
}
break;
case RC_FORMAT_UNKNOWN_MACRO:
chars = snprintf(ptr, buffersize, "[Unknown macro]%s", part->text);
chars = snprintf(tmp, sizeof(tmp), "[Unknown macro]%s", part->text);
text = tmp;
break;
default:
value = rc_evaluate_value(&part->value, peek, peek_ud, L);
chars = rc_format_value(ptr, buffersize, value, part->display_type);
chars = rc_format_value(tmp, sizeof(tmp), value, part->display_type);
text = tmp;
break;
}
if (chars > 0) {
ptr += chars;
buffersize -= chars;
if (chars > 0 && buffersize > 0) {
if ((unsigned)chars >= buffersize) {
/* prevent write past end of buffer */
memcpy(ptr, text, buffersize - 1);
ptr[buffersize - 1] = '\0';
buffersize = 0;
}
else {
memcpy(ptr, text, chars);
ptr[chars] = '\0';
buffersize -= (unsigned)chars;
}
}
ptr += chars;
part = part->next;
}
+589
View File
@@ -0,0 +1,589 @@
#include "internal.h"
#include "../rhash/md5.h"
#include <stdlib.h>
#include <string.h>
#define RC_RICHPRESENCE_DISPLAY_BUFFER_SIZE 256
void rc_runtime_init(rc_runtime_t* self) {
memset(self, 0, sizeof(rc_runtime_t));
self->next_memref = &self->memrefs;
}
void rc_runtime_destroy(rc_runtime_t* self) {
unsigned i;
if (self->triggers) {
for (i = 0; i < self->trigger_count; ++i)
free(self->triggers[i].buffer);
free(self->triggers);
self->triggers = NULL;
self->trigger_count = self->trigger_capacity = 0;
}
if (self->lboards) {
free(self->lboards);
self->lboards = NULL;
self->lboard_count = self->lboard_capacity = 0;
}
while (self->richpresence) {
rc_runtime_richpresence_t* previous = self->richpresence->previous;
free(self->richpresence->buffer);
free(self->richpresence);
self->richpresence = previous;
}
if (self->richpresence_display_buffer) {
free(self->richpresence_display_buffer);
self->richpresence_display_buffer = NULL;
}
self->next_memref = 0;
self->memrefs = 0;
}
static void rc_runtime_checksum(const char* memaddr, unsigned char* md5) {
md5_state_t state;
md5_init(&state);
md5_append(&state, (unsigned char*)memaddr, (int)strlen(memaddr));
md5_finish(&state, md5);
}
static void rc_runtime_deactivate_trigger_by_index(rc_runtime_t* self, unsigned index) {
if (self->triggers[index].owns_memrefs) {
/* if the trigger has one or more memrefs in its buffer, we can't free the buffer.
* just null out the trigger so the runtime processor will skip it
*/
rc_reset_trigger(self->triggers[index].trigger);
self->triggers[index].trigger = NULL;
}
else {
/* trigger doesn't own any memrefs, go ahead and free it, then replace it with the last trigger */
free(self->triggers[index].buffer);
if (--self->trigger_count > index)
memcpy(&self->triggers[index], &self->triggers[self->trigger_count], sizeof(rc_runtime_trigger_t));
}
}
void rc_runtime_deactivate_achievement(rc_runtime_t* self, unsigned id) {
unsigned i;
for (i = 0; i < self->trigger_count; ++i) {
if (self->triggers[i].id == id && self->triggers[i].trigger != NULL)
rc_runtime_deactivate_trigger_by_index(self, i);
}
}
int rc_runtime_activate_achievement(rc_runtime_t* self, unsigned id, const char* memaddr, lua_State* L, int funcs_idx) {
void* trigger_buffer;
rc_trigger_t* trigger;
rc_parse_state_t parse;
unsigned char md5[16];
int size;
char owns_memref;
unsigned i;
if (memaddr == NULL)
return RC_INVALID_MEMORY_OPERAND;
rc_runtime_checksum(memaddr, md5);
/* check to see if the id is already registered with an active trigger */
for (i = 0; i < self->trigger_count; ++i) {
if (self->triggers[i].id == id && self->triggers[i].trigger != NULL) {
if (memcmp(self->triggers[i].md5, md5, 16) == 0) {
/* if the checksum hasn't changed, we can reuse the existing item */
rc_reset_trigger(self->triggers[i].trigger);
return RC_OK;
}
/* checksum has changed, deactivate the the item */
rc_runtime_deactivate_trigger_by_index(self, i);
/* deactivate may reorder the list so we should continue from the current index. however, we
* assume that only one trigger is active per id, so having found that, just stop scanning.
*/
break;
}
}
/* check to see if a disabled trigger for the specific id matches the trigger being registered */
for (i = 0; i < self->trigger_count; ++i) {
if (self->triggers[i].id == id && memcmp(self->triggers[i].md5, md5, 16) == 0) {
/* retrieve the trigger pointer from the buffer */
size = 0;
trigger = (rc_trigger_t*)rc_alloc(self->triggers[i].buffer, &size, sizeof(rc_trigger_t), RC_ALIGNOF(rc_trigger_t), 0);
self->triggers[i].trigger = trigger;
rc_reset_trigger(trigger);
return RC_OK;
}
}
/* item has not been previously registered, determine how much space we need for it, and allocate it */
size = rc_trigger_size(memaddr);
if (size < 0)
return size;
trigger_buffer = malloc(size);
if (!trigger_buffer)
return RC_OUT_OF_MEMORY;
/* populate the item, using the communal memrefs pool */
rc_init_parse_state(&parse, trigger_buffer, L, funcs_idx);
parse.first_memref = &self->memrefs;
trigger = RC_ALLOC(rc_trigger_t, &parse);
rc_parse_trigger_internal(trigger, &memaddr, &parse);
rc_destroy_parse_state(&parse);
if (parse.offset < 0) {
free(trigger_buffer);
*self->next_memref = NULL; /* disassociate any memrefs allocated by the failed parse */
return parse.offset;
}
/* if at least one memref was allocated within the trigger, we can't free the buffer when the trigger is deactivated */
owns_memref = (*self->next_memref != NULL);
if (owns_memref) {
/* advance through the new memrefs so we're ready for the next allocation */
do {
self->next_memref = &(*self->next_memref)->next;
} while (*self->next_memref != NULL);
}
/* grow the trigger buffer if necessary */
if (self->trigger_count == self->trigger_capacity) {
self->trigger_capacity += 32;
if (!self->triggers)
self->triggers = (rc_runtime_trigger_t*)malloc(self->trigger_capacity * sizeof(rc_runtime_trigger_t));
else
self->triggers = (rc_runtime_trigger_t*)realloc(self->triggers, self->trigger_capacity * sizeof(rc_runtime_trigger_t));
}
/* assign the new trigger */
self->triggers[self->trigger_count].id = id;
self->triggers[self->trigger_count].trigger = trigger;
self->triggers[self->trigger_count].buffer = trigger_buffer;
memcpy(self->triggers[self->trigger_count].md5, md5, 16);
self->triggers[self->trigger_count].owns_memrefs = owns_memref;
++self->trigger_count;
/* reset it, and return it */
trigger->memrefs = NULL;
rc_reset_trigger(trigger);
return RC_OK;
}
rc_trigger_t* rc_runtime_get_achievement(const rc_runtime_t* self, unsigned id)
{
unsigned i;
for (i = 0; i < self->trigger_count; ++i) {
if (self->triggers[i].id == id && self->triggers[i].trigger != NULL)
return self->triggers[i].trigger;
}
return NULL;
}
static void rc_runtime_deactivate_lboard_by_index(rc_runtime_t* self, unsigned index) {
if (self->lboards[index].owns_memrefs) {
/* if the lboard has one or more memrefs in its buffer, we can't free the buffer.
* just null out the lboard so the runtime processor will skip it
*/
rc_reset_lboard(self->lboards[index].lboard);
self->lboards[index].lboard = NULL;
}
else {
/* lboard doesn't own any memrefs, go ahead and free it, then replace it with the last lboard */
free(self->lboards[index].buffer);
if (--self->lboard_count > index)
memcpy(&self->lboards[index], &self->lboards[self->lboard_count], sizeof(rc_runtime_lboard_t));
}
}
void rc_runtime_deactivate_lboard(rc_runtime_t* self, unsigned id) {
unsigned i;
for (i = 0; i < self->lboard_count; ++i) {
if (self->lboards[i].id == id && self->lboards[i].lboard != NULL)
rc_runtime_deactivate_lboard_by_index(self, i);
}
}
int rc_runtime_activate_lboard(rc_runtime_t* self, unsigned id, const char* memaddr, lua_State* L, int funcs_idx) {
void* lboard_buffer;
unsigned char md5[16];
rc_lboard_t* lboard;
rc_parse_state_t parse;
int size;
char owns_memref;
unsigned i;
if (memaddr == 0)
return RC_INVALID_MEMORY_OPERAND;
rc_runtime_checksum(memaddr, md5);
/* check to see if the id is already registered with an active lboard */
for (i = 0; i < self->lboard_count; ++i) {
if (self->lboards[i].id == id && self->lboards[i].lboard != NULL) {
if (memcmp(self->lboards[i].md5, md5, 16) == 0) {
/* if the checksum hasn't changed, we can reuse the existing item */
rc_reset_lboard(self->lboards[i].lboard);
return RC_OK;
}
/* checksum has changed, deactivate the the item */
rc_runtime_deactivate_lboard_by_index(self, i);
/* deactivate may reorder the list so we should continue from the current index. however, we
* assume that only one trigger is active per id, so having found that, just stop scanning.
*/
break;
}
}
/* check to see if a disabled lboard for the specific id matches the lboard being registered */
for (i = 0; i < self->lboard_count; ++i) {
if (self->lboards[i].id == id && memcmp(self->lboards[i].md5, md5, 16) == 0) {
/* retrieve the lboard pointer from the buffer */
size = 0;
lboard = (rc_lboard_t*)rc_alloc(self->lboards[i].buffer, &size, sizeof(rc_lboard_t), RC_ALIGNOF(rc_lboard_t), 0);
self->lboards[i].lboard = lboard;
rc_reset_lboard(lboard);
return RC_OK;
}
}
/* item has not been previously registered, determine how much space we need for it, and allocate it */
size = rc_lboard_size(memaddr);
if (size < 0)
return size;
lboard_buffer = malloc(size);
if (!lboard_buffer)
return RC_OUT_OF_MEMORY;
/* populate the item, using the communal memrefs pool */
rc_init_parse_state(&parse, lboard_buffer, L, funcs_idx);
lboard = RC_ALLOC(rc_lboard_t, &parse);
parse.first_memref = &self->memrefs;
rc_parse_lboard_internal(lboard, memaddr, &parse);
rc_destroy_parse_state(&parse);
if (parse.offset < 0) {
free(lboard_buffer);
*self->next_memref = NULL; /* disassociate any memrefs allocated by the failed parse */
return parse.offset;
}
/* if at least one memref was allocated within the trigger, we can't free the buffer when the trigger is deactivated */
owns_memref = (*self->next_memref != NULL);
if (owns_memref) {
/* advance through the new memrefs so we're ready for the next allocation */
do {
self->next_memref = &(*self->next_memref)->next;
} while (*self->next_memref != NULL);
}
/* grow the lboard buffer if necessary */
if (self->lboard_count == self->lboard_capacity) {
self->lboard_capacity += 16;
if (!self->lboards)
self->lboards = (rc_runtime_lboard_t*)malloc(self->lboard_capacity * sizeof(rc_runtime_lboard_t));
else
self->lboards = (rc_runtime_lboard_t*)realloc(self->lboards, self->lboard_capacity * sizeof(rc_runtime_lboard_t));
}
/* assign the new lboard */
self->lboards[self->lboard_count].id = id;
self->lboards[self->lboard_count].value = 0;
self->lboards[self->lboard_count].lboard = lboard;
self->lboards[self->lboard_count].buffer = lboard_buffer;
memcpy(self->lboards[self->lboard_count].md5, md5, 16);
self->lboards[self->lboard_count].owns_memrefs = owns_memref;
++self->lboard_count;
/* reset it, and return it */
lboard->memrefs = NULL;
rc_reset_lboard(lboard);
return RC_OK;
}
rc_lboard_t* rc_runtime_get_lboard(const rc_runtime_t* self, unsigned id)
{
unsigned i;
for (i = 0; i < self->lboard_count; ++i) {
if (self->lboards[i].id == id && self->lboards[i].lboard != NULL)
return self->lboards[i].lboard;
}
return NULL;
}
int rc_runtime_activate_richpresence(rc_runtime_t* self, const char* script, lua_State* L, int funcs_idx) {
rc_richpresence_t* richpresence;
rc_runtime_richpresence_t* previous;
rc_richpresence_display_t* display;
rc_parse_state_t parse;
int size;
if (script == NULL)
return RC_MISSING_DISPLAY_STRING;
size = rc_richpresence_size(script);
if (size < 0)
return size;
if (!self->richpresence_display_buffer) {
self->richpresence_display_buffer = (char*)malloc(RC_RICHPRESENCE_DISPLAY_BUFFER_SIZE * sizeof(char));
if (!self->richpresence_display_buffer)
return RC_OUT_OF_MEMORY;
}
self->richpresence_display_buffer[0] = '\0';
previous = self->richpresence;
if (previous) {
if (!previous->owns_memrefs) {
free(previous->buffer);
previous = previous->previous;
}
}
self->richpresence = (rc_runtime_richpresence_t*)malloc(sizeof(rc_runtime_richpresence_t));
if (!self->richpresence)
return RC_OUT_OF_MEMORY;
self->richpresence->previous = previous;
self->richpresence->owns_memrefs = 0;
self->richpresence->buffer = malloc(size);
if (!self->richpresence->buffer)
return RC_OUT_OF_MEMORY;
rc_init_parse_state(&parse, self->richpresence->buffer, L, funcs_idx);
self->richpresence->richpresence = richpresence = RC_ALLOC(rc_richpresence_t, &parse);
parse.first_memref = &self->memrefs;
rc_parse_richpresence_internal(richpresence, script, &parse);
rc_destroy_parse_state(&parse);
if (parse.offset < 0) {
free(self->richpresence->buffer);
free(self->richpresence);
self->richpresence = previous;
*self->next_memref = NULL; /* disassociate any memrefs allocated by the failed parse */
return parse.offset;
}
/* if at least one memref was allocated within the rich presence, we can't free the buffer when the rich presence is deactivated */
self->richpresence->owns_memrefs = (*self->next_memref != NULL);
if (self->richpresence->owns_memrefs) {
/* advance through the new memrefs so we're ready for the next allocation */
do {
self->next_memref = &(*self->next_memref)->next;
} while (*self->next_memref != NULL);
}
richpresence->memrefs = NULL;
self->richpresence_update_timer = 0;
if (!richpresence->first_display || !richpresence->first_display->display) {
/* non-existant rich presence, treat like static empty string */
*self->richpresence_display_buffer = '\0';
self->richpresence->richpresence = NULL;
}
else if (richpresence->first_display->next || /* has conditional display strings */
richpresence->first_display->display->next || /* has macros */
richpresence->first_display->display->value.conditions) { /* is only a macro */
/* dynamic rich presence - reset all of the conditions */
display = richpresence->first_display;
while (display != NULL) {
rc_reset_trigger(&display->trigger);
display = display->next;
}
rc_evaluate_richpresence(self->richpresence->richpresence, self->richpresence_display_buffer, RC_RICHPRESENCE_DISPLAY_BUFFER_SIZE - 1, NULL, NULL, L);
}
else {
/* static rich presence - copy the static string */
const char* src = richpresence->first_display->display->text;
char* dst = self->richpresence_display_buffer;
const char* end = dst + RC_RICHPRESENCE_DISPLAY_BUFFER_SIZE - 1;
while (*src && dst < end)
*dst++ = *src++;
*dst = '\0';
/* by setting self->richpresence to null, it won't be evaluated in do_frame() */
self->richpresence = NULL;
}
return RC_OK;
}
const char* rc_runtime_get_richpresence(const rc_runtime_t* self)
{
if (self->richpresence_display_buffer)
return self->richpresence_display_buffer;
return "";
}
void rc_runtime_do_frame(rc_runtime_t* self, rc_runtime_event_handler_t event_handler, rc_peek_t peek, void* ud, lua_State* L) {
rc_runtime_event_t runtime_event;
unsigned i;
runtime_event.value = 0;
rc_update_memref_values(self->memrefs, peek, ud);
for (i = 0; i < self->trigger_count; ++i) {
rc_trigger_t* trigger = self->triggers[i].trigger;
int trigger_state;
if (!trigger)
continue;
trigger_state = trigger->state;
switch (rc_evaluate_trigger(trigger, peek, ud, L))
{
case RC_TRIGGER_STATE_RESET:
runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_RESET;
runtime_event.id = self->triggers[i].id;
event_handler(&runtime_event);
break;
case RC_TRIGGER_STATE_TRIGGERED:
runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED;
runtime_event.id = self->triggers[i].id;
event_handler(&runtime_event);
break;
case RC_TRIGGER_STATE_PAUSED:
if (trigger_state != RC_TRIGGER_STATE_PAUSED) {
runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_PAUSED;
runtime_event.id = self->triggers[i].id;
event_handler(&runtime_event);
}
break;
case RC_TRIGGER_STATE_PRIMED:
if (trigger_state != RC_TRIGGER_STATE_PRIMED) {
runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED;
runtime_event.id = self->triggers[i].id;
event_handler(&runtime_event);
}
break;
case RC_TRIGGER_STATE_ACTIVE:
if (trigger_state != RC_TRIGGER_STATE_ACTIVE) {
runtime_event.type = RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED;
runtime_event.id = self->triggers[i].id;
event_handler(&runtime_event);
}
break;
}
}
for (i = 0; i < self->lboard_count; ++i) {
rc_lboard_t* lboard = self->lboards[i].lboard;
int lboard_state;
if (!lboard)
continue;
lboard_state = lboard->state;
switch (rc_evaluate_lboard(lboard, &runtime_event.value, peek, ud, L))
{
case RC_LBOARD_STATE_STARTED: /* leaderboard is running */
if (lboard_state != RC_LBOARD_STATE_STARTED) {
self->lboards[i].value = runtime_event.value;
runtime_event.type = RC_RUNTIME_EVENT_LBOARD_STARTED;
runtime_event.id = self->lboards[i].id;
event_handler(&runtime_event);
}
else if (runtime_event.value != self->lboards[i].value) {
self->lboards[i].value = runtime_event.value;
runtime_event.type = RC_RUNTIME_EVENT_LBOARD_UPDATED;
runtime_event.id = self->lboards[i].id;
event_handler(&runtime_event);
}
break;
case RC_LBOARD_STATE_CANCELED:
if (lboard_state != RC_LBOARD_STATE_CANCELED) {
runtime_event.type = RC_RUNTIME_EVENT_LBOARD_CANCELED;
runtime_event.id = self->lboards[i].id;
event_handler(&runtime_event);
}
break;
case RC_LBOARD_STATE_TRIGGERED:
if (lboard_state != RC_RUNTIME_EVENT_LBOARD_TRIGGERED) {
runtime_event.type = RC_RUNTIME_EVENT_LBOARD_TRIGGERED;
runtime_event.id = self->lboards[i].id;
event_handler(&runtime_event);
}
break;
}
}
if (self->richpresence && self->richpresence->richpresence) {
if (self->richpresence_update_timer == 0) {
/* generate into a temporary buffer so we don't get a partially updated string if it's read while its being updated */
char buffer[RC_RICHPRESENCE_DISPLAY_BUFFER_SIZE];
int len = rc_evaluate_richpresence(self->richpresence->richpresence, buffer, RC_RICHPRESENCE_DISPLAY_BUFFER_SIZE - 1, peek, ud, L);
/* copy into the real buffer - write the 0 terminator first to ensure reads don't overflow the buffer */
if (len > 0) {
buffer[RC_RICHPRESENCE_DISPLAY_BUFFER_SIZE - 1] = '\0';
memcpy(self->richpresence_display_buffer, buffer, RC_RICHPRESENCE_DISPLAY_BUFFER_SIZE);
}
/* schedule the next update for 60 frames later - most systems use a 60 fps framerate (some use more 50 or 75)
* since we're only sending to the server every two minutes, that's only every 7200 frames while active, which
* is evenly divisible by 50, 60, and 75.
*/
self->richpresence_update_timer = 59;
}
else {
self->richpresence_update_timer--;
}
}
}
void rc_runtime_reset(rc_runtime_t* self) {
unsigned i;
for (i = 0; i < self->trigger_count; ++i) {
if (self->triggers[i].trigger)
rc_reset_trigger(self->triggers[i].trigger);
}
for (i = 0; i < self->lboard_count; ++i) {
if (self->lboards[i].lboard)
rc_reset_lboard(self->lboards[i].lboard);
}
if (self->richpresence) {
rc_richpresence_display_t* display = self->richpresence->richpresence->first_display;
while (display != 0) {
rc_reset_trigger(&display->trigger);
display = display->next;
}
}
}
+445
View File
@@ -0,0 +1,445 @@
#include "internal.h"
#include "../rhash/md5.h"
#include <string.h>
#define RC_RUNTIME_MARKER 0x0A504152 /* RAP\n */
#define RC_RUNTIME_CHUNK_MEMREFS 0x4645524D /* MREF */
#define RC_RUNTIME_CHUNK_ACHIEVEMENT 0x56484341 /* ACHV */
#define RC_RUNTIME_CHUNK_DONE 0x454E4F44 /* DONE */
typedef struct rc_runtime_progress_t {
rc_runtime_t* runtime;
int offset;
unsigned char* buffer;
int chunk_size_offset;
lua_State* L;
} rc_runtime_progress_t;
#define RC_TRIGGER_STATE_UNUPDATED 0x7F
#define RC_MEMREF_FLAG_PREV_IS_PRIOR 0x00010000
static void rc_runtime_progress_write_uint(rc_runtime_progress_t* progress, unsigned value)
{
if (progress->buffer) {
progress->buffer[progress->offset + 0] = value & 0xFF; value >>= 8;
progress->buffer[progress->offset + 1] = value & 0xFF; value >>= 8;
progress->buffer[progress->offset + 2] = value & 0xFF; value >>= 8;
progress->buffer[progress->offset + 3] = value & 0xFF;
}
progress->offset += 4;
}
static unsigned rc_runtime_progress_read_uint(rc_runtime_progress_t* progress)
{
unsigned value = progress->buffer[progress->offset + 0] |
(progress->buffer[progress->offset + 1] << 8) |
(progress->buffer[progress->offset + 2] << 16) |
(progress->buffer[progress->offset + 3] << 24);
progress->offset += 4;
return value;
}
static void rc_runtime_progress_write_md5(rc_runtime_progress_t* progress, unsigned char* md5)
{
if (progress->buffer)
memcpy(&progress->buffer[progress->offset], md5, 16);
progress->offset += 16;
}
static int rc_runtime_progress_match_md5(rc_runtime_progress_t* progress, unsigned char* md5)
{
int result = 0;
if (progress->buffer)
result = (memcmp(&progress->buffer[progress->offset], md5, 16) == 0);
progress->offset += 16;
return result;
}
static void rc_runtime_progress_start_chunk(rc_runtime_progress_t* progress, unsigned chunk_id)
{
rc_runtime_progress_write_uint(progress, chunk_id);
progress->chunk_size_offset = progress->offset;
progress->offset += 4;
}
static void rc_runtime_progress_end_chunk(rc_runtime_progress_t* progress)
{
unsigned length;
int offset;
progress->offset = (progress->offset + 3) & ~0x03; /* align to 4 byte boundary */
if (progress->buffer) {
/* ignore chunk size field when calculating chunk size */
length = (unsigned)(progress->offset - progress->chunk_size_offset - 4);
/* temporarily update the write pointer to write the chunk size field */
offset = progress->offset;
progress->offset = progress->chunk_size_offset;
rc_runtime_progress_write_uint(progress, length);
progress->offset = offset;
}
}
static void rc_runtime_progress_init(rc_runtime_progress_t* progress, rc_runtime_t* runtime, lua_State* L)
{
memset(progress, 0, sizeof(rc_runtime_progress_t));
progress->runtime = runtime;
progress->L = L;
}
static int rc_runtime_progress_write_memrefs(rc_runtime_progress_t* progress)
{
rc_memref_value_t* memref = progress->runtime->memrefs;
unsigned int flags = 0;
rc_runtime_progress_start_chunk(progress, RC_RUNTIME_CHUNK_MEMREFS);
while (memref) {
flags = memref->memref.size;
if (memref->previous == memref->prior)
flags |= RC_MEMREF_FLAG_PREV_IS_PRIOR;
rc_runtime_progress_write_uint(progress, memref->memref.address);
rc_runtime_progress_write_uint(progress, flags);
rc_runtime_progress_write_uint(progress, memref->value);
rc_runtime_progress_write_uint(progress, memref->prior);
memref = memref->next;
}
rc_runtime_progress_end_chunk(progress);
return RC_OK;
}
static int rc_runtime_progress_read_memrefs(rc_runtime_progress_t* progress)
{
unsigned entries;
unsigned address, flags, value, prior;
char size;
rc_memref_value_t* memref;
/* re-read the chunk size to determine how many memrefs are present */
progress->offset -= 4;
entries = rc_runtime_progress_read_uint(progress) / 16;
while (entries != 0) {
address = rc_runtime_progress_read_uint(progress);
flags = rc_runtime_progress_read_uint(progress);
value = rc_runtime_progress_read_uint(progress);
prior = rc_runtime_progress_read_uint(progress);
size = flags & 0xFF;
memref = progress->runtime->memrefs;
while (memref) {
if (memref->memref.address == address && memref->memref.size == size) {
memref->value = value;
memref->previous = (flags & RC_MEMREF_FLAG_PREV_IS_PRIOR) ? prior : value;
memref->prior = prior;
}
memref = memref->next;
}
--entries;
}
return RC_OK;
}
static int rc_runtime_progress_write_condset(rc_runtime_progress_t* progress, rc_condset_t* condset)
{
rc_condition_t* cond;
rc_runtime_progress_write_uint(progress, condset->is_paused);
cond = condset->conditions;
while (cond) {
rc_runtime_progress_write_uint(progress, cond->current_hits);
rc_runtime_progress_write_uint(progress, cond->is_true);
cond = cond->next;
}
return RC_OK;
}
static int rc_runtime_progress_read_condset(rc_runtime_progress_t* progress, rc_condset_t* condset)
{
rc_condition_t* cond;
condset->is_paused = rc_runtime_progress_read_uint(progress);
cond = condset->conditions;
while (cond) {
cond->current_hits = rc_runtime_progress_read_uint(progress);
cond->is_true = rc_runtime_progress_read_uint(progress) & 0xFF;
cond = cond->next;
}
return RC_OK;
}
static int rc_runtime_progress_write_trigger(rc_runtime_progress_t* progress, rc_trigger_t* trigger)
{
rc_condset_t* condset;
int result;
rc_runtime_progress_write_uint(progress, trigger->state);
rc_runtime_progress_write_uint(progress, trigger->measured_value);
if (trigger->requirement) {
result = rc_runtime_progress_write_condset(progress, trigger->requirement);
if (result != RC_OK)
return result;
}
condset = trigger->alternative;
while (condset)
{
result = rc_runtime_progress_write_condset(progress, condset);
if (result != RC_OK)
return result;
condset = condset->next;
}
return RC_OK;
}
static int rc_runtime_progress_read_trigger(rc_runtime_progress_t* progress, rc_trigger_t* trigger)
{
rc_condset_t* condset;
int result;
trigger->state = rc_runtime_progress_read_uint(progress);
trigger->measured_value = rc_runtime_progress_read_uint(progress);
if (trigger->requirement) {
result = rc_runtime_progress_read_condset(progress, trigger->requirement);
if (result != RC_OK)
return result;
}
condset = trigger->alternative;
while (condset)
{
result = rc_runtime_progress_read_condset(progress, condset);
if (result != RC_OK)
return result;
condset = condset->next;
}
return RC_OK;
}
static int rc_runtime_progress_write_achievements(rc_runtime_progress_t* progress)
{
unsigned i;
int result;
for (i = 0; i < progress->runtime->trigger_count; ++i)
{
rc_runtime_trigger_t* runtime_trigger = &progress->runtime->triggers[i];
if (!runtime_trigger->trigger)
continue;
switch (runtime_trigger->trigger->state)
{
case RC_TRIGGER_STATE_INACTIVE:
case RC_TRIGGER_STATE_TRIGGERED:
/* don't store state for inactive or triggered achievements */
break;
default:
break;
}
rc_runtime_progress_start_chunk(progress, RC_RUNTIME_CHUNK_ACHIEVEMENT);
rc_runtime_progress_write_uint(progress, runtime_trigger->id);
rc_runtime_progress_write_md5(progress, runtime_trigger->md5);
result = rc_runtime_progress_write_trigger(progress, runtime_trigger->trigger);
if (result != RC_OK)
return result;
rc_runtime_progress_end_chunk(progress);
}
return RC_OK;
}
static int rc_runtime_progress_read_achievement(rc_runtime_progress_t* progress)
{
unsigned id = rc_runtime_progress_read_uint(progress);
unsigned i;
for (i = 0; i < progress->runtime->trigger_count; ++i) {
rc_runtime_trigger_t* runtime_trigger = &progress->runtime->triggers[i];
if (runtime_trigger->id == id && runtime_trigger->trigger != NULL) {
/* ignore triggered and waiting achievements */
if (runtime_trigger->trigger->state == RC_TRIGGER_STATE_UNUPDATED) {
/* only update state if definition hasn't changed (md5 matches) */
if (rc_runtime_progress_match_md5(progress, runtime_trigger->md5))
return rc_runtime_progress_read_trigger(progress, runtime_trigger->trigger);
break;
}
}
}
return RC_OK;
}
static int rc_runtime_progress_serialize_internal(rc_runtime_progress_t* progress)
{
md5_state_t state;
unsigned char md5[16];
int result;
rc_runtime_progress_write_uint(progress, RC_RUNTIME_MARKER);
if ((result = rc_runtime_progress_write_memrefs(progress)) != RC_OK)
return result;
if ((result = rc_runtime_progress_write_achievements(progress)) != RC_OK)
return result;
rc_runtime_progress_write_uint(progress, RC_RUNTIME_CHUNK_DONE);
rc_runtime_progress_write_uint(progress, 16);
if (progress->buffer) {
md5_init(&state);
md5_append(&state, progress->buffer, progress->offset);
md5_finish(&state, md5);
}
rc_runtime_progress_write_md5(progress, md5);
return RC_OK;
}
int rc_runtime_progress_size(const rc_runtime_t* runtime, lua_State* L)
{
rc_runtime_progress_t progress;
int result;
rc_runtime_progress_init(&progress, (rc_runtime_t*)runtime, L);
result = rc_runtime_progress_serialize_internal(&progress);
if (result != RC_OK)
return result;
return progress.offset;
}
int rc_runtime_serialize_progress(void* buffer, const rc_runtime_t* runtime, lua_State* L)
{
rc_runtime_progress_t progress;
rc_runtime_progress_init(&progress, (rc_runtime_t*)runtime, L);
progress.buffer = (unsigned char*)buffer;
return rc_runtime_progress_serialize_internal(&progress);
}
int rc_runtime_deserialize_progress(rc_runtime_t* runtime, const unsigned char* serialized, lua_State* L)
{
rc_runtime_progress_t progress;
md5_state_t state;
unsigned char md5[16];
unsigned chunk_id;
unsigned chunk_size;
unsigned next_chunk_offset;
unsigned i;
int result = RC_OK;
rc_runtime_progress_init(&progress, runtime, L);
progress.buffer = (unsigned char*)serialized;
if (rc_runtime_progress_read_uint(&progress) != RC_RUNTIME_MARKER) {
rc_runtime_reset(runtime);
return RC_INVALID_STATE;
}
for (i = 0; i < runtime->trigger_count; ++i) {
rc_runtime_trigger_t* runtime_trigger = &runtime->triggers[i];
if (runtime_trigger->trigger) {
switch (runtime_trigger->trigger->state)
{
case RC_TRIGGER_STATE_INACTIVE:
case RC_TRIGGER_STATE_TRIGGERED:
/* don't update state for inactive or triggered achievements */
break;
default:
/* mark active achievements as unupdated. anything that's still unupdated
* after deserializing the progress will be reset to waiting */
runtime_trigger->trigger->state = RC_TRIGGER_STATE_UNUPDATED;
break;
}
}
}
do {
chunk_id = rc_runtime_progress_read_uint(&progress);
chunk_size = rc_runtime_progress_read_uint(&progress);
next_chunk_offset = progress.offset + chunk_size;
switch (chunk_id)
{
case RC_RUNTIME_CHUNK_MEMREFS:
result = rc_runtime_progress_read_memrefs(&progress);
break;
case RC_RUNTIME_CHUNK_ACHIEVEMENT:
result = rc_runtime_progress_read_achievement(&progress);
break;
case RC_RUNTIME_CHUNK_DONE:
md5_init(&state);
md5_append(&state, progress.buffer, progress.offset);
md5_finish(&state, md5);
if (!rc_runtime_progress_match_md5(&progress, md5))
result = RC_INVALID_STATE;
break;
default:
if (chunk_size & 0xFFFF0000)
result = RC_INVALID_STATE; /* assume unknown chunk > 64KB is invalid */
break;
}
progress.offset = next_chunk_offset;
} while (result == RC_OK && chunk_id != RC_RUNTIME_CHUNK_DONE);
if (result != RC_OK) {
rc_runtime_reset(runtime);
}
else {
for (i = 0; i < runtime->trigger_count; ++i) {
rc_trigger_t* trigger = runtime->triggers[i].trigger;
if (trigger && trigger->state == RC_TRIGGER_STATE_UNUPDATED)
rc_reset_trigger(trigger);
}
}
return result;
}
-103
View File
@@ -1,103 +0,0 @@
#include "internal.h"
rc_term_t* rc_parse_term(const char** memaddr, int is_indirect, rc_parse_state_t* parse) {
rc_term_t* self;
const char* aux;
char size;
int ret2;
aux = *memaddr;
self = RC_ALLOC(rc_term_t, parse);
self->invert = 0;
ret2 = rc_parse_operand(&self->operand1, &aux, 0, is_indirect, parse);
if (ret2 < 0) {
parse->offset = ret2;
return 0;
}
if (*aux == '*') {
aux++;
if (*aux == '~') {
aux++;
self->invert = 1;
}
ret2 = rc_parse_operand(&self->operand2, &aux, 0, is_indirect, parse);
if (ret2 < 0) {
parse->offset = ret2;
return 0;
}
if (self->invert) {
switch (self->operand2.type) {
case RC_OPERAND_ADDRESS:
case RC_OPERAND_DELTA:
case RC_OPERAND_PRIOR:
size = self->operand2.value.memref->memref.size;
break;
default:
size = RC_MEMSIZE_32_BITS;
break;
}
switch (size) {
case RC_MEMSIZE_BIT_0:
case RC_MEMSIZE_BIT_1:
case RC_MEMSIZE_BIT_2:
case RC_MEMSIZE_BIT_3:
case RC_MEMSIZE_BIT_4:
case RC_MEMSIZE_BIT_5:
case RC_MEMSIZE_BIT_6:
case RC_MEMSIZE_BIT_7:
/* invert is already 1 */
break;
case RC_MEMSIZE_LOW:
case RC_MEMSIZE_HIGH:
self->invert = 0xf;
break;
case RC_MEMSIZE_8_BITS:
self->invert = 0xffU;
break;
case RC_MEMSIZE_16_BITS:
self->invert = 0xffffU;
break;
case RC_MEMSIZE_24_BITS:
self->invert = 0xffffffU;
break;
case RC_MEMSIZE_32_BITS:
self->invert = 0xffffffffU;
break;
}
}
}
else {
self->operand2.type = RC_OPERAND_CONST;
self->operand2.value.num = 1;
}
*memaddr = aux;
return self;
}
int rc_evaluate_term(rc_term_t* self, rc_eval_state_t* eval_state) {
/* Operands are usually memory references and are always retrieved as unsigned. The floating
* point operand is signed, and will automatically make the result signed. Otherwise, multiply
* by the secondary operand (which is usually 1) and cast to signed.
*/
unsigned value = rc_evaluate_operand(&self->operand1, eval_state);
if (self->operand2.type != RC_OPERAND_FP) {
return (int)(value * (rc_evaluate_operand(&self->operand2, eval_state) ^ self->invert));
}
return (int)((double)value * self->operand2.value.dbl);
}
Loaded 100 of 600 files, more files were not shown because too many files have changed in this diff. Show more