Compare commits

..

425 Commits

Author SHA1 Message Date
Ani 0178b20983 rpcs3_version: Bump to 0.0.27 2023-03-01 21:56:02 +00:00
JoãoPaulo f9142a1c56 Update FW 4.90 Latest Version
Updates the latest FW version according to: https://www.playstation.com/en-us/support/hardware/ps3/system-software/
List of changes:
This system software update improves system performance.
2023-03-01 20:25:24 +01:00
oltolm b19209c45c [3rdparty] update cubeb 2023-03-01 18:03:55 +01:00
Megamouse 73b5b9d7b7 cellRtc: fix out of bounds write
Turns out you should listen to warnings once in a while...
sprint actually wrote more than 3 characters into the microDigits buffer !!!
2023-03-01 10:15:21 +01:00
kd-11 0a9d646bd7 rsx: Workaround for clang build 2023-03-01 01:10:06 +03:00
kd-11 24edfe2190 rsx: Use simple_array for basic array of integers
- Some methods are getting spammed every draw call
2023-03-01 01:10:06 +03:00
kd-11 0bb8127372 rsx: Use emplace when constructing in-place.
- Unexpectedly high gains for msvc builds. GCC doesn't care, clang shits itself.
2023-03-01 01:10:06 +03:00
kd-11 1b8a69154f rsx: Use non-owning container to ellide a derpy allocation with msvc 2023-03-01 01:10:06 +03:00
illusion0001 f2155b49e2 Debugger: show CIA in register view (#13462) 2023-02-28 00:30:23 +01:00
Eladash 62c9b99e72 Update SPUThread.cpp 2023-02-27 14:17:05 +01:00
Elad Ashkenazi 2a344e1d87 cellMsgDialog: fix use-after-free 2023-02-27 14:17:05 +01:00
Megamouse ae14aa991d overlays: hotfix for return_code lifetime 2023-02-27 12:04:10 +01:00
Megamouse 2885c8a4ab cellSaveData: get rid of g_last_user_response 2023-02-27 10:24:06 +01:00
Megamouse 3d411431c6 input: disable ldd home menu for now 2023-02-26 22:17:55 +01:00
oltolm 1800faf0dd cellVdec.cpp: use lock_unlock instead of lock_guard 2023-02-26 22:20:07 +03:00
oltolm 19ded3809f fix out-of-bounds in VKGSRenderTypes.hpp 2023-02-26 22:20:07 +03:00
oltolm 40cd255051 fix: back() called an empty string in PPUThread.cpp 2023-02-26 22:20:07 +03:00
oltolm ad4677a67c fix use after move in cellVdec.cpp 2023-02-26 22:20:07 +03:00
RipleyTom d9e0d016c6 Fix for Windows ENOTCONN on connecting socket
Fixes Windows returns ENOTCONN when using recvfrom/sendto on connecting socket instead of the expected EAGAIN.
2023-02-26 10:35:20 +01:00
kd-11 c570fd03d1 rsx/overlays: Handle corner case where thread signal happens just before pop_all is called. 2023-02-26 02:30:16 +03:00
kd-11 1e0565f17b rsx/overlays: Fix emu close 2023-02-26 02:30:16 +03:00
Megamouse 3ff464641a Fix Visual Studio 17.5.0 compilation
For some reason there's an internal compiler error related to atomic wait.
I could work around this issue when I commented "mask = default_mask<X>;".
So after playing around a bit I had the suspicion that the VS parser can't handle some of the templatization.
Giving the decltype its own alias seems to fix this issue (and makes the code a bit more readable anyway in my opinion).
2023-02-25 19:20:55 +03:00
Megamouse 7cb3d305d4 main: set locale to C before doing anything else 2023-02-25 11:23:07 +01:00
Megamouse e46dba43ad config: try to fix float locale issues 2023-02-25 11:23:07 +01:00
Megamouse afad96a52a Qt: try to fix QString::toDouble locale nonsense 2023-02-25 11:23:07 +01:00
RipleyTom 1a00341e6b Forces local IP to bind address if set 2023-02-25 10:38:19 +01:00
kd-11 3388c8ed09 overlays/manager: Explicit ctor for the input context 2023-02-24 00:46:53 +03:00
kd-11 6d4967ffef [overlays] Implement input suspend+resume
- Tested with OSK + home menu. Requires hacks to enable this setup so it's mostly an academic achievement.
2023-02-24 00:46:53 +03:00
kd-11 b27366e1e6 rsx/overlays: Enable input hijacking 2023-02-24 00:46:53 +03:00
kd-11 95a29b5d1d rsx/overlays: Fix clang/msvc build 2023-02-24 00:46:53 +03:00
kd-11 d320867569 rsx/overlays: Add a name to the input thread context 2023-02-24 00:46:53 +03:00
kd-11 aabd388070 rsx/overlays: Remove some unused thread declarations 2023-02-24 00:46:53 +03:00
kd-11 7db6594358 rsx/overlays: Use lf_queue for a lock-free stack implementation 2023-02-24 00:46:53 +03:00
kd-11 388ca1c645 rsx/overlays: Fix build 2023-02-24 00:46:53 +03:00
kd-11 7c04b00e2b rsx/vk: Remove stale include 2023-02-24 00:46:53 +03:00
kd-11 dac0644f07 rsx/overlays: Fill in the user response when message dialog input loop exits and we're in blocking mode
- Avoids a race condition caused by the "blocking" call only updating results on cleanup/close
2023-02-24 00:46:53 +03:00
kd-11 7d103fe0f0 rsx/overlays: Fix crash 2023-02-24 00:46:53 +03:00
kd-11 901d9f3f6e rsx/overlays: Simplify attach-thread-input API
- Restructure the inputs to encourage shorter input signature.
2023-02-24 00:46:53 +03:00
kd-11 ddc9e74aa8 rsx/overlays: Putting it all together
- Migrate dialogs with input-only threads to use the unified input
  system
2023-02-24 00:46:53 +03:00
kd-11 12690de9de rsx/overlays: Refactor and implement callbacks for input token 2023-02-24 00:46:53 +03:00
Megamouse 6b30cdac09 Use u64 for system_time_t, as s64 doesn't make much sense in a microsecond context. 2023-02-22 23:57:20 +01:00
Megamouse ccb7528a59 fix some warnings 2023-02-22 23:57:20 +01:00
Ivan Chikish 01ed8a07af fixed_typemap.hpp: static allocation for m_init
This allows to safely call is_init<T>() at any time.
2023-02-23 00:54:35 +03:00
Megamouse a9f399d6cc patch_manager: fix focus loss during config value editing 2023-02-22 01:17:36 +01:00
Megamouse a527a485f8 patch_manager: add more decimal places to spinbox 2023-02-22 01:17:36 +01:00
Megamouse f0c8f6d47b patch_manager: check config values before applying them 2023-02-22 01:17:36 +01:00
Megamouse a29dc3893f patch_manager: change wording 2023-02-22 01:17:36 +01:00
Megamouse c6f392bf6c patch_manager: allow multiple dynamic values 2023-02-22 01:17:36 +01:00
Megamouse f2ded2fdb7 patch_manager: Add dropdown labels 2023-02-22 01:17:36 +01:00
Megamouse 080737fd1f patch_manager: add more dynamic to dynamic patches 2023-02-22 01:17:36 +01:00
Megamouse 1040757556 patch_manager: add ability to add dynamic patches 2023-02-22 01:17:36 +01:00
Megamouse 38d612e5ba fix some warnings 2023-02-22 00:15:11 +01:00
Megamouse c20aa2ad5f VS: fix miniupnp dependency 2023-02-22 00:15:11 +01:00
Megamouse a7c3753c5a cellMsgDialog: Improve some logging and localization 2023-02-21 23:35:13 +01:00
Megamouse ebf72eb126 overlays: add internal lock for progress bar texts 2023-02-21 23:35:13 +01:00
Megamouse be49a80bc7 overlays: use array for progress bars 2023-02-21 23:35:13 +01:00
brian218 23da770364 sys_game: LV2 board storage minor fixups 2023-02-21 22:57:37 +01:00
RipleyTom 6186ac0245 rpcn: signaling handler improvements & upnp
Simplify signaling by making Matching2 a layer over normal signaling.
Implements UPNP port forwarding
Implement sceNpMatching2AbortRequest
Fix reported bw in sceNpUtil
Hack for Fat Princess binding udp on 3658
Reenable CB for sceNpBasicAddPlayersHistoryAsync
Misc fixes
2023-02-21 15:41:41 +01:00
Megamouse 364c33060b Fix boot by RPCS3_GAMEID constants 2023-02-20 22:53:22 +01:00
Elad Ashkenazi 3922f76ab5 PINE: Fix crash on exit (#13409) 2023-02-20 09:59:40 +01:00
Megamouse bb2c9196f5 cellVdec: align RGBA/ARGB strides 2023-02-18 22:43:22 +01:00
Megamouse 1c8d3e0dca cellVdec: fix au_count race condition 2023-02-18 15:31:21 +01:00
Megamouse 6b556a5206 PINE: fix error format function 2023-02-17 19:33:58 +01:00
oltolm bbd308a908 fix order of static initialization: add comment 2023-02-17 11:58:40 +03:00
oltolm b5b8f7c35a fix order of static initialization 2023-02-17 11:58:40 +03:00
Megamouse de592267fe Create TEST12345/USRDIR for test elfs 2023-02-16 20:51:57 +01:00
Margen67 5bb89328d0 Remove whitespace 2023-02-15 08:58:02 +01:00
Megamouse 75fbb3d551 Qt: save last gs_frame screen and re-use it in no-gui mode 2023-02-14 08:03:26 +01:00
Megamouse eb0fb2fef7 Qt/CLI: Add option to select a screen for the game window 2023-02-14 08:03:26 +01:00
Megamouse b1b92e95ab Qt: move fullscreen cli arg from global to gs_frame 2023-02-14 08:03:26 +01:00
Megamouse 3a68b7ac0d Fix C00 boot from external HG games 2023-02-13 07:31:58 +01:00
Eladash 3976018980 Debugger: Print error codes stored in GPR 2023-02-12 23:10:20 +01:00
Megamouse 1dac708323 cellPad: move CellPadData to pad_types for convenience 2023-02-12 17:04:31 +01:00
Megamouse d4187242b9 cellPad/vsh: fix PS button recognition 2023-02-12 17:04:31 +01:00
Megamouse 61c0d81667 cellPad/vsh: fix sixaxis interaction
This allows you to influence the particles in the XMB
2023-02-12 17:04:31 +01:00
Megamouse c3e4b6da46 cellPad: allow opening the home menu with ldd pads
Speculative
2023-02-12 17:04:31 +01:00
Megamouse 38c7cf474d cellPad: add sanity check for indices in cellPadLdd functions 2023-02-12 17:04:31 +01:00
Megamouse ec4cbe5380 cellPad: simplify some code 2023-02-12 17:04:31 +01:00
Vestral 465ca97531 Fix displaying of audio device when it's disconnected 2023-02-10 04:19:20 +01:00
Megamouse 2f7a2d5134 Update hidapi from 0.13.0 to 0.13.1 2023-02-09 23:34:07 +01:00
Megamouse c1b5af21f0 Update SDL from 2.26.2 to 2.26.3 2023-02-09 23:34:07 +01:00
Megamouse cfb788941c overlays: review fixes 2023-02-09 20:36:35 +01:00
Megamouse 69435dd951 overlays: Fix linux compilation 2023-02-09 20:36:35 +01:00
Megamouse 3b09a39576 overlays: fix home menu date format 2023-02-09 20:36:35 +01:00
Megamouse 53f81ce9c7 overlays: fix home menu entry center alignment 2023-02-09 20:36:35 +01:00
Megamouse e064380a7d overlays: add message box to home menu 2023-02-09 20:36:35 +01:00
Megamouse 9375e255e1 overlays: add pages to home menu 2023-02-09 20:36:35 +01:00
Megamouse a56fc57a83 evdev: allow more buttons on sony guitar 2023-02-09 18:09:07 +01:00
Megamouse 4f75dc06b9 evdev: optimize get_next_button_press pad id check 2023-02-09 18:09:07 +01:00
Megamouse d3b7a5146c rsx_debugger: replace malloc with buffer cache
This also fixes a memory leak.
2023-02-09 00:02:43 +01:00
Megamouse bc487f43f7 cli: Add option to boot a game with a specific pad profile 2023-02-08 21:54:51 +01:00
Megamouse 088ac71930 cli: allow to start games in fullscreen
Technically this can be done through configs, but since it is easy to do, let's just add the cli option.
2023-02-08 21:54:51 +01:00
Eladash 27cad422b9 cellGame: Truncate excess of characters in TITLE_ID
In cellGameDataCheckCreate
2023-02-07 18:21:18 +03:00
Megamouse 5a63271f0e Fix openGl overlay colors 2023-02-07 13:40:47 +01:00
kd-11 9a35684507 rsx: Don't accept garbage shader input 2023-02-07 13:51:26 +03:00
RipleyTom 0d2714a1d9 FAudio cmake fix 2023-02-07 08:54:41 +01:00
Megamouse 553e4b28bf Disable 3rdparty FAudio if the SDL version is not available 2023-02-06 21:41:20 +01:00
Megamouse b579e45ed7 Update SDL download link 2023-02-06 21:41:20 +01:00
Megamouse 1662bcfae4 Qt: add copy context menu entry to log viewer 2023-02-06 20:43:53 +01:00
Elad Ashkenazi 8652b7d358 cellVdec: Fix AU decode count on callback (#13342) 2023-02-05 13:02:51 +01:00
Megamouse 1cf8aacc11 CLI: add option to boot rsx capture 2023-02-05 11:47:08 +01:00
Megamouse 13ef4c1236 Clarify unknown type log message 2023-02-05 09:36:56 +01:00
Megamouse 68dd25a4a5 Replace std::filesystem::u8path with TODO 2023-02-05 09:36:56 +01:00
Megamouse bcb1c6c080 Fix package installation exit condition after error occured 2023-02-05 09:36:56 +01:00
Megamouse 2372116acc Improve logging during package installations 2023-02-05 09:36:56 +01:00
kd-11 508dd2b509 rsx: Formatting change 2023-02-05 01:30:20 +03:00
kd-11 61b69eeed2 rsx/overlays: Force disable rounded rectangles on macOS 2023-02-05 01:30:20 +03:00
kd-11 dc8652806e rsx/overlays: Support disabling vertex-snap on a per-draw-call basis 2023-02-05 01:30:20 +03:00
kd-11 af6db7d895 rsx/overlays: Remove workaround no longer required 2023-02-05 01:30:20 +03:00
kd-11 64ec99be33 rsx: Unify UI rendering shaders 2023-02-05 01:30:20 +03:00
brian218 53e906d0f3 sys_game: Implemented sys_game_board_storage_write() & Made it modifiable 2023-02-04 22:19:59 +01:00
Elad Ashkenazi 780a6a7b40 sys_prx: Fix PRX module filename reading (#13339) 2023-02-04 21:24:24 +01:00
RipleyTom 737fbf661a Add more disconnected limitations in sys_net 2023-02-04 20:33:21 +01:00
kd-11 c0243a92d0 rsx/overlays: Re-export spinner
Fixes some incorrect black pixels
2023-02-04 17:36:09 +01:00
Megamouse 3a8fcd1b0b Update wolfssl from 5.5.0 to 5.5.4 2023-02-04 16:57:22 +01:00
Megamouse 04d9693b51 Update FAudio from 22.08 to 23.02 2023-02-04 16:57:22 +01:00
Nicolas Adenis-Lamarre 0023716053 - fix analog_t required for some games
- changing mapping to better fit to games (for example, select is rarely used)

Signed-off-by: Nicolas Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com>
2023-02-04 16:10:40 +01:00
kd-11 37b46df738 rsx/overlays/message-queue: Do not fade albedo, only alpha 2023-02-04 16:08:20 +03:00
illusion0001 ba06198012 GUI: Remove ANSI color code from TTY 2023-02-04 10:51:19 +01:00
Elad Ashkenazi acf9caa4ae Game list: Use the latest game icon instead of 1.00's (#13340) 2023-02-04 07:41:30 +01:00
Megamouse d69e345bc0 SDL: Fix button presses
SDL currently always returns 1 if a button is pressed
2023-02-03 18:24:54 +01:00
Megamouse c5b25fa132 Remove obsolete shader compilation hint settings 2023-02-03 09:27:04 +01:00
kd-11 262ecda2bf rsx/overlays: Cache the loading animated icon
Smooths out some frametime spikes when showing the notification message
2023-02-03 09:13:27 +03:00
kd-11 f243539362 rsx/overlays: Make animation caching possible 2023-02-03 09:13:27 +03:00
kd-11 ec33891f6f rsx/overlays: Work around some commitee grandstanding shenanigans
ffs: https://bugs.launchpad.net/ubuntu/+source/gcc-8/+bug/1831385
2023-02-03 09:13:27 +03:00
kd-11 f007188fa0 rsx/overlays: Minor fixups 2023-02-03 09:13:27 +03:00
kd-11 170fd813f0 rsx/overlays: Ellide redundant clock read 2023-02-03 09:13:27 +03:00
kd-11 4c59359cf7 rsx/overlays: Add time unit to some measured variables 2023-02-03 09:13:27 +03:00
kd-11 ddf25b7869 rsx/overlays: Shorten notification fadeout 2023-02-03 09:13:27 +03:00
kd-11 4914f3b2c3 rsx/overlays: Fix msvc project files 2023-02-03 09:13:27 +03:00
kd-11 08faed7d86 rsx/overlays: Naming sense 2023-02-03 09:13:27 +03:00
kd-11 989e0f28d6 rsx/overlays: Remove redundant resize 2023-02-03 09:13:27 +03:00
kd-11 54f41095e9 rsx/overlay: Some cleanup in animated icon class 2023-02-03 09:13:27 +03:00
kd-11 faaa72d398 rsx: Reverse declaration order for animated icon 2023-02-03 09:13:27 +03:00
kd-11 97b36eb53c cmake: Add shader compile notification to build system 2023-02-03 09:13:27 +03:00
kd-11 2503525016 rsx/overlays: Move shader compiling notification to a separate cpp file 2023-02-03 09:13:27 +03:00
kd-11 e96fedfefe rsx/overlays: Darken background a bit 2023-02-03 09:13:27 +03:00
kd-11 f279d8d6d1 rsx: Lower shader notification duration to 5 seconds 2023-02-03 09:13:27 +03:00
kd-11 4bfba20877 rsx: Remove unnecessary debug pragma 2023-02-03 09:13:27 +03:00
kd-11 504bd93007 rsx: Implement overlay message queue stacking 2023-02-03 09:13:27 +03:00
kd-11 2f2fe72808 ui: Add 24x24 loading animation 2023-02-03 09:13:27 +03:00
kd-11 5babf47e70 build: Fix linux build 2023-02-03 09:13:27 +03:00
kd-11 78a588cacb rsx: Use animated icon and message queue for shader compiler notifications 2023-02-03 09:13:27 +03:00
kd-11 205f8a6479 rsx: Fix message queue order and positioning 2023-02-03 09:13:27 +03:00
kd-11 34c1e1a9ad rsx: Add support for rounded rectangles 2023-02-03 09:13:27 +03:00
kd-11 0885884839 rsx: Implement notification queue 2023-02-03 09:13:27 +03:00
Elad Ashkenazi c471120a80 System.cpp: Do not create VFS directories outside of RPCS3 dir (#13311) 2023-01-29 11:29:26 +01:00
Megamouse 3202cc7021 overlays/osk: fix y offset direction facepalm 2023-01-28 23:13:51 +01:00
Megamouse fc34b3f144 cellOskDialog: improve kb event hook callback 2023-01-28 21:51:36 +01:00
Megamouse fb974a4551 overlays/osk: clear on enter 2023-01-28 21:51:36 +01:00
Megamouse 3d99fea575 overlays/osk: Do not render preview background in separate windows mode 2023-01-28 21:51:36 +01:00
Megamouse feb04c64a8 overlays/osk: show dialog on key input 2023-01-28 21:51:36 +01:00
Megamouse d3dbf9e83f overlays/osk: Clear text properly in continuous mode 2023-01-28 21:51:36 +01:00
Megamouse 9b6d7a5275 cellOskDialog: don't wait for osk event_hook_callback 2023-01-28 21:51:36 +01:00
Megamouse 754fd03750 overlays/osk: hide title in separate window mode 2023-01-28 21:51:36 +01:00
Megamouse adfa5d63bb overlays/osk: fix dialog positioning 2023-01-28 21:51:36 +01:00
Megamouse 81ff956a48 cellOskDialog: use getter instead of weak_ptr 2023-01-28 21:51:36 +01:00
Megamouse daefe27fec overlays: allow keyboard input if pads are intercepted 2023-01-28 21:51:36 +01:00
Megamouse 6106ff8b31 overlays/osk: fix cellOskDialogExtInputDeviceLock 2023-01-28 21:51:36 +01:00
Megamouse 1e6c180690 overlays: don't flip if the overlay is invisible 2023-01-28 21:51:36 +01:00
Megamouse d1a950d59f overlays/osk: keep dialog open in continuous mode 2023-01-28 21:51:36 +01:00
Megamouse 641fadc1fb overlays/osk: handle input device change 2023-01-28 21:51:36 +01:00
Megamouse 5299061282 overlays/osk: visualize separate windows 2023-01-28 21:51:36 +01:00
kd-11 d0c029c83e rsx: Ignore bad face mode configuration 2023-01-28 21:11:32 +03:00
Eladash 5aced2e44b Print LV2 Syscall Usage only if increased since last print 2023-01-28 17:21:45 +01:00
Ani 18ab42dc83 readme: Remove Azure, rename Cirrus CI badges 2023-01-28 14:43:54 +01:00
Jan Beich a748508bc9 evdev_gun: enable udev code on BSDs
libudev is supported on DragonFly and FreeBSD, similar to libevdev.
NetBSD and OpenBSD can simply disable both via -DUSE_LIBEVDEV=OFF.

This reverts commit 337ee77a99.
2023-01-28 12:35:42 +00:00
shinra-electric 8b453e6a3b Update MoltenVK to 1.2.2 (VK 1.3.239) 2023-01-28 11:52:11 +00:00
Jan Beich 3196ada481 vk: Drop deprecated (239) and removed (240) header
In file included from rpcs3/Emu/System.cpp:55:
rpcs3/Emu/RSX/VK/VulkanAPI.h:17:10: fatal error: 'vulkan/vk_sdk_platform.h' file not found
 #include <vulkan/vk_sdk_platform.h>
          ^~~~~~~~~~~~~~~~~~~~~~~~~~
2023-01-28 01:26:12 +01:00
RipleyTom 7c4734c24d Fix SDL CMake warnings 2023-01-27 17:02:13 +01:00
Malcolm Jestadt 813f7b50c1 SPU LLVM: Minor SUMB AVX-512 path optimization
- Tweak shuffle to allow LLVM to emit a cheap blend instruction instead of the expensive VPERMI2W instruction
2023-01-27 13:06:48 +03:00
Megamouse 6532d2b650 input: fix dynamic pad handler mode reset 2023-01-27 00:13:20 +01:00
Megamouse e0baad417a perfoverlay: fix minimal graph min/max calculation 2023-01-27 00:13:20 +01:00
Megamouse f6759de1e9 Qt: fix vfs dialog usb tab cast 2023-01-26 21:33:39 +01:00
brian218 7648171fe2 sys_usbd: Improved usb_handler_thread timing 2023-01-26 15:52:45 +01:00
brian218 71c3264ea7 USIO: Always resize the response vector to the given size 2023-01-26 15:52:45 +01:00
brian218 49455965c0 sys_game: Implemented sys_game_get_rtc_status() & Updated sys_game_board_storage_read() 2023-01-26 15:52:45 +01:00
kd-11 5f0467b084 rsx: Remove framebuffer_status_valid flag and move to state 2023-01-26 11:42:39 +03:00
kd-11 6adcabda29 rsx: Fix graphics state foot-gun 2023-01-26 11:42:39 +03:00
Anton Kourganov 52b67b46fc Allow unbinding pad buttons by right clicking (#13283) 2023-01-23 22:00:08 +01:00
MSuih a700e3b39e Whitelist EA Active 2 accessories 2023-01-23 17:02:51 +01:00
Egor Romanovskiy 4fbbdf8732 sys_usbd: fix usb handler deinitialization 2023-01-23 12:32:09 +01:00
Elad Ashkenazi 9a91fef337 Deprecate HDD0/disc, make RPCS3/games movable (#13265) 2023-01-23 08:00:46 +01:00
nastys 53cc067c17 macOS CI: move to AArch64 VM (x64 builds) (#13155) 2023-01-21 21:21:41 +01:00
Megamouse d3183708e8 overlays: do not open home menu in VSH 2023-01-21 09:11:53 +01:00
Megamouse 44771150b7 overlays: add simple home menu 2023-01-21 09:11:53 +01:00
Megamouse ac2b2d82d2 overlays/osk: move pointer variables to fxo 2023-01-20 23:41:56 +01:00
Megamouse 11c42eb8d4 overlays/osk: add analog movement if CELL_OSKDIALOG_NO_INPUT_ANALOG is unset 2023-01-20 23:41:56 +01:00
Megamouse dc0230c476 overlays/osk: Fix layout and positioning 2023-01-20 23:41:56 +01:00
Megamouse 0a8c343e6e cellOskDialog: cellOskDialogSetSeparateWindowOption 2023-01-20 23:41:56 +01:00
Megamouse afdbef1a81 cellOskDialog: improve dictionary functions 2023-01-20 23:41:56 +01:00
Megamouse f659338e5e overlays/osk: implement first osk pointer 2023-01-20 23:41:56 +01:00
Megamouse 4a82d81efe overlays/osk: implement scaling 2023-01-20 23:41:56 +01:00
Megamouse 6b4208be9b overlays/osk: align osk position 2023-01-20 23:41:56 +01:00
Megamouse 3d78c7f43a cellOskDialog: fix error check and improve initialKeyLayout logic 2023-01-20 23:41:56 +01:00
Megamouse 34df4509af overlays/osk: implement "support languages"
Some languages/panels in the osk need to be activated by the developer.
They are not available otherwise.
So let's check if they were pre-configured and only add the panels if they are supported.
2023-01-20 23:41:56 +01:00
brian218 6c3b2b938a Fix emucore.vcxproj.filters 2023-01-20 13:05:33 +03:00
Egor Romanovskiy 59588b12c8 Fix BUILDING.md Vulkan SDK Version 2023-01-19 23:35:00 +01:00
Jan Beich 3eaa29e7c2 Thread: silence -Wsign-compare on FreeBSD aarch64
Utilities/Thread.cpp:1805:48: error: comparison of integers of different signs: 'uptr' (aka 'unsigned long') and '__register_t' (aka 'long') [-Werror,-Wsign-compare]
        const bool is_executing = uptr(info->si_addr) == RIP(context);
                                  ~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~~~
2023-01-19 18:49:06 +03:00
brian218 c3c2bb7ad8 USIO: Do not crash simply due to invalid commands 2023-01-18 08:09:35 +01:00
brian218 0e64c74a78 sys_usbd: Added buffer null check for sys_usbd_transfer_data() 2023-01-18 08:09:35 +01:00
brian218 d2dc57585c sys_fs: Improved sys_fs_fcntl(0xc0000015&0xc000001c) 2023-01-18 08:09:35 +01:00
brian218 e0fe7989e9 USB: Added VFS USB mass storage devices to the USB device list 2023-01-18 08:09:35 +01:00
Megamouse 709305df0e overlays: fix indentation 2023-01-18 00:24:00 +01:00
Megamouse 24445123fc Recording: Fix possible encoder segfault 2023-01-18 00:24:00 +01:00
Megamouse 450a64b58b cellUserInfo: fix potentially locked user dialogs 2023-01-18 00:24:00 +01:00
Megamouse b3a9c8d83f input: move config getters to base class 2023-01-17 02:01:03 +01:00
Megamouse 35c92723c7 input: fix ds4 led/rumble in pad settings 2023-01-17 01:07:57 +01:00
kd-11 719e7a9d56 rsx: Fix inadvertent signal override for MSAA 2023-01-17 02:24:21 +03:00
kd-11 eed9e56bf4 rsx: Allow vertex fetch from uninitialized register 2023-01-17 02:24:21 +03:00
Megamouse 1d214ed26a Qt: add system cmd dialog 2023-01-16 17:26:05 +01:00
Megamouse 2d9d92b7d7 Qt: Remove CELL_SYSUTIL_SYSTEM_MENU_CLOSE menu option
This never made any sense
2023-01-16 17:26:05 +01:00
xperia64 240cb2d627 Add output scaling filtering options, migrate FSR checkbox to these options 2023-01-16 13:52:51 +01:00
kd-11 bd69466e94 rsx: Fix some pipe state signal propagation routines 2023-01-16 15:20:53 +03:00
Elad Ashkenazi e6a7597444 PRX/savestates/VSH: Associate PRX with library, fix VSH browser (#13221)
* PRX/savestate:s Associate PRX with library

* VFS/Savestates: Fix host_root resolving

* Savestates: Fix segfault in ppu_initialize

* SPU: Avoid some log spam

* VSH/sys_vm: Fix limit on root processes
2023-01-15 23:12:54 +03:00
Megamouse 1852b370d7 Qt: Allow users to create shortcuts for existing bootable entries even after canceling the installation 2023-01-11 19:26:13 +01:00
Megamouse 12fa7c41f6 Qt: more package install fixes
- Clean directories if fill_path fails
- Fix check_target_app_version when installing multiple packages (compromise: no more optimized singular file installs for now)
2023-01-11 19:26:13 +01:00
Megamouse fc85ed8730 Qt: fix some package install cancellation issues
- Abort installation if any thread has errors
- Only clean the directories of packages that actually had errors
- Additionally clean the directories of packages that were cancelled before they could finish
- Clear boot path in case of error or cancelation
- Propagate result to caller
- Skip success message if the installation was canceled
2023-01-11 19:26:13 +01:00
Megamouse 65f10ff840 package_reader: fix some warnings 2023-01-11 19:26:13 +01:00
kd-11 6809d84a00 vk: Bump max number of suppported inline draw calls to 32k
- Surprisingly some games actually exhaust the entire 16k pool causing slowdown
2023-01-11 16:48:53 +03:00
kd-11 2752cd1390 rsx/vk: Fix some problems with dynamic state updates 2023-01-11 16:48:53 +03:00
kd-11 10b56415e8 vk: Avoid loading the whole dynamic state properties if only the shader changed
- Handles a common case where a game engine switches materials but uses the same configuration
  e.g rendering two types of wall or ground may need different shaders but similar state properties
2023-01-11 16:48:53 +03:00
kd-11 bd87c80943 rsx: Simplify the debug overlay print text routines.
- Greatly simplifies adding text
2023-01-11 16:48:53 +03:00
kd-11 f71e7ef1cc vk: Switch programs if the primitive type changed
- This will change when EXT_dynamic_state is integrated
2023-01-11 16:48:53 +03:00
kd-11 756ad17c2c Fix GCC11 compilation 2023-01-11 16:48:53 +03:00
kd-11 29c1b20b41 Fix compilation 2023-01-11 16:48:53 +03:00
kd-11 aa5097e0d4 glsl: Update fog enums in shaders 2023-01-11 16:48:53 +03:00
kd-11 2ccfee2e45 rsx: Propagate decode failures up the chain.
- Dumping invalid data should not crash
2023-01-11 16:48:53 +03:00
kd-11 bf1311b902 Fix GCC compilation 2023-01-11 16:48:53 +03:00
kd-11 71efb3bc84 rsx: Use gcm cast to handle input enum validation 2023-01-11 16:48:53 +03:00
kd-11 439bdde849 rsx: Fix printing of expected values 2023-01-11 16:48:53 +03:00
kd-11 c7fed20f3c vk: Short-circuit program load if state did not change
- TODO: Incorporate VK_EXT_extended_dynamic_state
2023-01-11 16:48:53 +03:00
kd-11 3dd6e5664c rsx: Do not call a dynamic function to simply test-and-set. Do it inline. 2023-01-11 16:48:53 +03:00
kd-11 d4ee308ffd vk: Fix rare crash when handling mixed depth format types 2023-01-11 16:48:53 +03:00
kd-11 a272f3e3b9 rsx: Improve performance by using an integral type to indicate error 2023-01-11 16:48:53 +03:00
kd-11 f6027719d2 rsx: Fix vertex decode 2023-01-11 16:48:53 +03:00
kd-11 38402e78c0 rsx: Fixup vertex enums in shaders 2023-01-11 16:48:53 +03:00
kd-11 eae1ac6558 refactor: Fix build 2023-01-11 16:48:53 +03:00
kd-11 0b019401bd Refactor gcm enums 2023-01-11 16:48:53 +03:00
kd-11 73cda2324a rsx/lv2: Refactor DMA control stuff after VSH work 2023-01-11 16:48:53 +03:00
kd-11 3dba894369 rsx: Minor refactoring RSXThread
- Part 1 of many
2023-01-11 16:48:53 +03:00
brian218 659ee81e80 USIO: Backup file fixup 2023-01-11 09:10:09 +01:00
Megamouse 99c307a68e Qt: move progress indication to own handler 2023-01-11 05:43:34 +01:00
Megamouse d28eea342a Qt: use play_sound callback instead of QSound 2023-01-10 20:57:32 +01:00
Megamouse 29078bc428 cellMouse: decrease some log levels 2023-01-10 20:57:32 +01:00
Megamouse 6bcb5ae66b Fix some includes and warnings 2023-01-10 20:57:32 +01:00
brian218 cf1e68fb0e USIO: Emulation Performance Optimization 2023-01-10 21:35:12 +03:00
Megamouse 43288a6760 Qt: add shortcut manager 2023-01-10 19:28:26 +01:00
UltraHDR 9ee7d04560 Set LSApplicationCategoryType to games
https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype
This makes it show up in the macOS Launchpad Games folder
2023-01-10 20:53:43 +03:00
Megamouse 16bf215d8a pine: fix some warnings 2023-01-10 19:51:25 +03:00
Megamouse 99ed77da8c pine: simplify writing strings 2023-01-10 19:51:25 +03:00
Megamouse b9f733c401 pine: replace goto with lambda 2023-01-10 19:51:25 +03:00
Megamouse 18966d424c Input: ignore F11 in keyboard pad handler (starts/stops recordings) 2023-01-09 21:06:51 +01:00
Megamouse c725b886e1 Qt: Disable ESC to exit fullscreen if kb shortcuts are disabled 2023-01-09 21:06:51 +01:00
Megamouse 9b7eaf5117 Improve error logging 2023-01-09 21:06:51 +01:00
Elad Ashkenazi 36a55660bf Unbreak BSD 2023-01-09 20:20:13 +01:00
Elad Ashkenazi 0946e5945f VSH Improvements (#13172)
* sys_prx: Implement PRX LIB register syscall

* VSH: partial log spam fix

* sys_process reboot fix

* Implement sys_memory_container_destroy_parent_with_childs

* sys_net: Implement SO_RCVTIMEO/SO_SENDTIMEO

* VSH: Implement sys_rsx_context_free

* PPU LLVM: distinguish PPU cache exec also by address

Fixes referencing multiple PRX.

* UI: Do not report size of apps inside /dev_flash
2023-01-09 20:03:01 +03:00
Ani 8ec1a5627d AppImage: Do not bundle libgmodule-2.0 and libglib-2.0 2023-01-09 08:19:53 +01:00
Ani df718bcb0f rpcs3_version: Bump to 0.0.26 2023-01-07 22:47:41 +00:00
Eladash 8eefbcae45 VSH/UI: Add VSH to game grid
* Custom VSH config.
* VSH shortcut creation.
2023-01-07 22:52:50 +01:00
Megamouse 8cf28730cb Update submodules 2023-01-07 21:50:02 +01:00
Megamouse f894e2b9a2 Qt: Fix open_dir for paths with multiple slashes 2023-01-07 16:07:41 +01:00
Megamouse e3cd31f057 update_manager: Simplify wchar conversion 2023-01-07 16:07:41 +01:00
Foxxcoon 05086cda3b Fix #11126 2023-01-07 16:40:39 +03:00
Elad Ashkenazi 7c2d6f8a23 PKG: Pack multiple PKGs into fast+efficient install (#13147) 2023-01-03 15:31:39 +03:00
kd-11 7423abb136 rsx: Remove incorrect hack 2023-01-02 23:03:39 +03:00
Megamouse 310fa7127d VS: Add SDL dependency to rpcs3 project 2022-12-30 22:02:41 +01:00
Elad Ashkenazi 3250c16cdc Restrict package installation to 1 thread
It is possible that a package contains the same file multiple times.
This leads to possible corruption or installation failure when they are extracted on different threads.
(easy to reproduce with DeS)
2022-12-30 21:10:23 +01:00
Eladash 02f35383bd PKG: Implement Multi-threaded installation 2022-12-30 17:48:14 +03:00
Eladash 1d5fef4930 PKG: Create directories first 2022-12-30 17:48:14 +03:00
Eladash dddea008e9 unedat.cpp: Remove outdated lock 2022-12-30 17:48:14 +03:00
Elad Ashkenazi dd8ec8f09e PKG install hotfix 2022-12-30 17:48:14 +03:00
Megamouse 98dbbd84ac Qt: fix size watcher cancellation on soft refresh
Also setting the cancel flag manually since the canceled signal seems to be very unreliable (I managed to trigger it rarely)
2022-12-30 13:43:55 +01:00
Elad Ashkenazi 382a27cb2f Allow to cancel dir size calculation (#13134) 2022-12-30 09:34:35 +01:00
Nekotekina eeda958f33 fs: fix read/read_at/write (Unix)
It's known that too huge read can require multiple syscalls.
2022-12-29 16:19:54 +03:00
Nekotekina 2f9cac8d18 fs: implement file::read_at
Reads from the given offset; does not seek; thread-safe.
2022-12-29 16:19:54 +03:00
kd-11 9d432187aa vk: Fix bug that made fall-out barriers never get triggered 2022-12-28 17:37:50 +03:00
kd-11 b13165f95a vk/rtts: Account for corner case where the same texture can be bound to more than 1 slot 2022-12-28 17:37:50 +03:00
kd-11 110c20d25f vk: Restructure framebuffer loop barrier management 2022-12-28 17:37:50 +03:00
kd-11 4def7f143c rsx: Fix logicOp behavior when blending is also active 2022-12-27 02:56:43 +03:00
kd-11 908d524631 vk: Add some missing PCI IDs 2022-12-27 02:00:28 +03:00
Megamouse 6c74274502 Qt: fix size_on_disk filetype 2022-12-25 17:16:49 +03:00
Eladash ee8cd82e9d Demote PRX export already loaded error 2022-12-25 16:10:32 +03:00
Eladash 820e692e57 PRX: Implement multi-referenced library management 2022-12-25 16:10:32 +03:00
Megamouse 5b95cfda40 Qt: Improve Check Config utility
Warn if the user selects a weird file.
Allow more file types and show them all by default.
2022-12-22 23:51:32 +01:00
Megamouse b2c4fed39c Qt: stop all async refresh threads on close 2022-12-22 21:47:47 +01:00
Megamouse 96c6dc01eb Qt: Implement config check in Utilities and log viewer 2022-12-22 09:09:51 +01:00
Megamouse f545532556 cellSaveData: add some more info to log error 2022-12-22 09:09:51 +01:00
Megamouse 8ac9968096 Qt: optimize log viewer file loading 2022-12-19 23:18:58 +01:00
Megamouse a9ee9a69a4 Qt: show some more info about the current log viewer state 2022-12-19 23:18:58 +01:00
Megamouse 46a50265a3 Qt: save some log viewer filter settings 2022-12-19 23:18:58 +01:00
kd-11 41e9e0b965 rsx: Restructure color format enum to clearly separate float from int formats 2022-12-19 23:13:25 +03:00
kd-11 388d090b91 rsx: Propagate surface format changes to shader ROP control 2022-12-19 23:13:25 +03:00
Ani 1a60fb3c96 cirrus: Update rpcs3-ci-bionic to 1.6 (#13064) 2022-12-18 16:07:11 +00:00
Elad Ashkenazi baa2768a69 StrUtil.h: Prevent an overflow in strcpy_trunc 2022-12-17 19:55:16 +01:00
kd-11 04fb86556a rsx: Fix surface metadata life-cycle
- Beware of clone operations. Blindly inheriting the parent's metadata is wrong.
- It is possible, especially when reusing a pre-existing slice, that the parent and child info has diverged
2022-12-17 20:16:58 +03:00
kd-11 90cf47cdce rsx: Handle some corner cases in surface locking 2022-12-17 20:16:58 +03:00
kd-11 bf96cbe980 rsx: Fix const RTV/DSV cast from texture cache 2022-12-17 20:16:58 +03:00
kd-11 66dc1cc15d rsx: Conditionally skip flush if no new data was introduced 2022-12-17 20:16:58 +03:00
kd-11 a05e3f02b8 rsx: Avoid expensive protection scan by sharing some data between surface and texture cache 2022-12-17 20:16:58 +03:00
Megamouse 8ec01450f8 Qt: check dir size async 2022-12-17 16:19:22 +01:00
Megamouse b2962e0522 Qt: show item count in category filter 2022-12-17 16:19:22 +01:00
Eladash 8980fc5524 rsx: Fix exceptions 2022-12-17 14:27:20 +01:00
Eladash f54da22f6f UI: Report Game Size On Disk, Make Game Removal An Informed Decision 2022-12-17 12:27:17 +01:00
kd-11 cebc0ec4a1 vk: Add missing memory barrier 2022-12-17 13:10:32 +03:00
brian218 812224f7f7 Stop LV2 Watchdog when CELL_SYSUTIL_REQUEST_EXITGAME is issued 2022-12-15 13:12:40 +03:00
brian218 d78e2dad29 sys_game: Made the LV2 Watchdog restarts the game forcefully 2022-12-15 13:12:40 +03:00
kd-11 7e35679ec2 vk: Revise some TRANSFER->TRANSFER barriers that introduced RAW hazards when copying images 2022-12-14 03:24:37 +03:00
kd-11 b39f457363 vk: Zero-initialize scratch VRAM allocations 2022-12-14 03:24:37 +03:00
Megamouse 18b7955384 SDL handler 2022-12-13 11:56:48 +01:00
Ani 0e625e6928 PSF: Add AS as valid category
Used for some PS3 Applications
2022-12-13 09:34:21 +01:00
brian218 65ae85061f Misc and minor improvements of syscalls used by VSH (#13067) 2022-12-13 07:33:17 +01:00
Megamouse e2c1547d95 Qt: facepalm fix in open_dir 2022-12-12 20:19:07 +01:00
kd-11 2d5a427bd4 gl: Throw exception if we cannot initialize critical requirements 2022-12-12 14:23:06 +03:00
Megamouse 45bd0d1f25 rsx_debugger: fix overflow and some warning 2022-12-11 21:39:18 +01:00
Megamouse f38084f0cf Qt: don't show message if only the rpcs3 games dir shortcut was created 2022-12-11 21:39:18 +01:00
Ani 0d929a210f NP: Disable some logging (#13061) 2022-12-11 16:49:14 +00:00
Megamouse 057f5beac6 Qt: remove cache dir when deleting games 2022-12-11 15:29:01 +01:00
kd-11 26021e11f7 gl: Require GLSL 450 when using barycentric extension 2022-12-11 15:21:58 +03:00
kd-11 941ecc76a1 ci: Update glslang to sdk-1.3.224.1 2022-12-11 15:21:58 +03:00
kd-11 12806af6aa Bump windows vulkan SDK version 2022-12-11 15:21:58 +03:00
kd-11 55886b0a50 gl: Fix shader extension requirements 2022-12-11 15:21:58 +03:00
kd-11 577b5ef2bd Support compiling with older SDK headers 2022-12-11 15:21:58 +03:00
kd-11 780c38a5e5 gl: Silence compiler warning spam 2022-12-11 15:21:58 +03:00
kd-11 6756bf7d4b rsx: Only request attribute interpolation if the GPU requires it and the driver supports it 2022-12-11 15:21:58 +03:00
kd-11 9c0b2338cf rsx: Fix shader compilation 2022-12-11 15:21:58 +03:00
kd-11 a0ef1a672c rsx: Implement interpolation using barycentrics 2022-12-11 15:21:58 +03:00
kd-11 1fd265d316 rsx: Properly flag the program control if needed 2022-12-11 15:21:58 +03:00
kd-11 e3b23822fd rsx: Pass on shader flags to the cache 2022-12-11 15:21:58 +03:00
brian218 ab3c8268f0 sys_sm: Implemented sys_sm_shutdown() (#13048) 2022-12-11 09:10:06 +01:00
Megamouse 6f306121a6 Qt: fix opening folders by using util functions 2022-12-10 22:54:26 +01:00
Megamouse 8399516475 cli: fix title_path 2022-12-10 18:18:16 +01:00
Megamouse a60ea61291 linux: fix shortcut cli args 2022-12-10 18:18:16 +01:00
Megamouse 64cff74861 Qt: simplify shortcut creation 2022-12-10 18:18:16 +01:00
Elad Ashkenazi e2c1e656b9 RSSX Debugger: Do not show invalid color buffers 2022-12-10 16:51:49 +01:00
brian218 cdc1d0c02b sys_fs: sys_fs_get_mount_info(): Made g_mp_sys_dev_root always reported as mounted 2022-12-10 15:28:04 +01:00
Eladash 151a0955cf rsx: Implement draw call stepping 2022-12-10 15:09:42 +01:00
Eladash 40406bd3fe RSX debugger: Implement Texture Dumper
Also fix many bugs in textures display.
2022-12-10 15:09:42 +01:00
Megamouse 1cc3e6e510 cellRec: hotfix for pre-recording 2022-12-10 04:10:40 +01:00
Megamouse 064ab58f3c cellRec: move data instead of memcpy 2022-12-10 03:24:40 +01:00
Megamouse 85c0a2e602 cellRec: add more logging 2022-12-10 03:24:40 +01:00
shinra-electric 809e880bd1 [3rdParty] Update MoltenVK to 1.3.236 & set MSL Fastmath to On Demand (#13035)
* Update MoltenVK to 1.2.236

* Change mvk_config.fastMathEnabled from a bool to Int

fastMathEnabled now has three options:
NEVER = 0
ALWAYS = 1 
ON_DEMAND = 2

On demand seems better, since it will use fast math except for shaders that are incompatible.
2022-12-09 20:49:56 +01:00
Eladash 7df093c94b Make it work with LLVM
Allow multiple entries for a single code.
2022-12-09 21:16:05 +03:00
Eladash f572e29a13 PPU: Add new patch function for SONIC 06 2022-12-09 21:16:05 +03:00
brian218 681a6ef73c Qt: Improved the shown path in overlay message "Recording stopped" 2022-12-09 16:40:38 +01:00
shinra-electric bf37087a10 Fix build errors by changing AVCodec* to a const
...rather than a variable. 

Allows RPCS3 to build on macOS again (Xcode 14.1)
2022-12-09 14:21:37 +03:00
Eladash a18b46d8ad Path hotfix 2022-12-09 12:20:57 +03:00
Eladash 74bb90b414 System.cpp: protect boot arguments 2022-12-09 12:20:57 +03:00
Eladash 8334767c16 GUI: bring relative game shortcut to the GUI 2022-12-09 12:20:57 +03:00
Eladash 0d126afb1f PKG: Ask to user if he wants to install game shortcut on PKG installation 2022-12-09 12:20:57 +03:00
Eladash b7d80ab335 Add support to boot using PS3 game path or TITLEID in CLI and shortcuts
Allowing to move of game directories without having to update the shortcut path. (as long as it is registered within RPCS3 UI).
2022-12-09 12:20:57 +03:00
Megamouse b0e376ae76 rsx/qt: add recording to game window 2022-12-08 21:08:37 +01:00
Megamouse a3bcb6c15a cellRec: implement proper recording
Everything should work mostly. I didn't find a game to test the external input though.
2022-12-08 21:08:37 +01:00
Megamouse 88269636d3 utils: implement video encoder and image sink 2022-12-08 21:08:37 +01:00
Megamouse 4f5076346d Qt: minor camera config warning fixes 2022-12-08 21:08:37 +01:00
Megamouse 89de913e95 Qt: reset screenshot toggle in gs_frame desctructor 2022-12-08 21:08:37 +01:00
Megamouse 0e73c4598e cellVideoExport: fix file paths 2022-12-08 21:08:37 +01:00
Megamouse 6b8aef9fdd cellAdec: fix some uninitialized member warnings 2022-12-08 21:08:37 +01:00
Jan Beich 1811dd67bf CI: switch FreeBSD to Clang/libc++ 15 2022-12-08 19:36:12 +01:00
brian218 6d4379059c sys_fs: Integrated get_mount_count() into sys_fs_get_mount_info_size() 2022-12-08 18:31:46 +01:00
brian218 a0f3704b41 sys_fs: Integrated the function of get_vfs() into get_mp() 2022-12-08 18:31:46 +01:00
brian218 9274b3f14d USIO: Fixed "Card Reader Not Connected" Error 2022-12-07 20:20:52 +01:00
brian218 0a3e540a10 sys_fs: get_vfs() minor fixup 2022-12-07 20:20:52 +01:00
Megamouse 4657afd899 Qt: remove entire cache dir of a serial on remove all caches 2022-12-07 18:55:56 +01:00
Megamouse 2082f06443 Qt: remove empty cache dirs if possible 2022-12-07 18:55:56 +01:00
Megamouse b49f8623f6 Windows: Check WSAStartup result 2022-12-07 18:11:01 +01:00
Megamouse 69e4138223 Try to fix dll checks 2022-12-07 00:00:45 +01:00
Elad Ashkenazi 5fec8666e3 Dont append main thread's ID on fatal error dialog (#13021) 2022-12-06 22:18:26 +01:00
Megamouse 8af4a94864 Qt: add context menu to trophy game table 2022-12-06 21:30:08 +01:00
Megamouse ab873129f8 Qt: add copy name and description to trophy context menu 2022-12-06 21:30:08 +01:00
kd-11 6155207407 ux: Instruct the user to delete the dlls from the installation folder. 2022-12-06 20:46:35 +01:00
kd-11 98a58daf57 Fix build 2022-12-06 20:46:35 +01:00
kd-11 0aaa40cd53 ux: Update vcredist links and optionally disable help text from error dialog 2022-12-06 20:46:35 +01:00
Megamouse a6b44ea1bb Qt: support fatal error as htmk 2022-12-06 20:46:35 +01:00
kd-11 ca0ca2e5a8 ux/core: Add module verification step for some critical libraries
- Prevents running the emu with downloaded dll files
2022-12-06 20:46:35 +01:00
RipleyTom 14a388b3fe Increase max number of skylanders to 8 2022-12-06 18:14:58 +01:00
Eladash 82a8d96fba sys_fs hotfix
Co-Authored-By: brian218 <17809637+brian218@users.noreply.github.com>
2022-12-03 17:53:39 +01:00
Elad Ashkenazi ad3ea966cb Add RPCS3/games/ for automatic games detection, support PSN games outside HDD0 (#12982)
* SFO: Do not load PARAM.SFO with illegal TITLE_ID
* Add support for PSN games outside HDD0
* Add RPCS3/games/ for automatic game detection
2022-12-02 13:18:07 +03:00
brian218 8d9dd1d19c Implemented sys_fs_newfs() 2022-12-02 08:18:46 +01:00
Megamouse 337ee77a99 evdev_gun: "fix" BSD 2022-11-30 19:38:42 +01:00
Megamouse c09991ebdb evdev_gun: convert udev code to evdev 2022-11-30 19:38:42 +01:00
Megamouse 5188293242 evdev gun support cleanup 2022-11-30 19:38:42 +01:00
Nicolas Adenis-Lamarre 2805fe0a06 evdev gun support
supports guns via evdev. multiple guns.
extra buttons are configurable (guns can be configured for that).

Signed-off-by: Nicolas Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com>
2022-11-30 19:38:42 +01:00
Team XLink Developers b4757b514d Add ability to have sockets bind to a local IP address (#12998) 2022-11-30 18:35:42 +03:00
Elad Ashkenazi 630edde10f logs.cpp: fix regression (#12995)
Fixes #12994
2022-11-29 22:56:18 +03:00
Eladash e9e139c364 logs improvements
* Do not use unsafe pointer arithmetics exceeding existing memory. (exceeding m_fptr)
* Properly use the enire 32MB of the buffer, previously only 16MB were used for cuncurrent access.
* Fix a bug occurring after attempting to push 1TB (40 bits).
* Flush the log before hitting a debugging breakpoint.
2022-11-28 18:52:11 +03:00
Julien Reichardt 60c01ef9a9 Use uppercase RPCS3 name in the metainfo file 2022-11-28 06:20:48 +03:00
Megamouse 5dbadccd7f Log PSF path on error 2022-11-27 22:07:15 +01:00
Megamouse 49a968219f Silence some usually irrelevant errors 2022-11-27 22:07:15 +01:00
Eladash 8b934abcf2 Improve error_code, make HDD1 errors be warnings 2022-11-26 16:33:47 +03:00
Nekotekina fa74d3e88c vm: implement lock-free try_access with range locking 2022-11-26 09:30:11 +03:00
Nekotekina 1123e25136 Implement ref_ptr (see read_from_ptr)
Type `aref`: reference wrapper
2022-11-26 09:30:11 +03:00
Nekotekina 7c15001042 Implement read_from_ptr<>() util
Doing std::bit_cast on a "span".
Should be usable in constexpr.
2022-11-26 09:30:11 +03:00
Nekotekina bf388e5428 cfmt/StrFmt: support s128 formatting (untested) 2022-11-26 09:30:11 +03:00
Paweł Kotiuk 661be41c5a Update AppStream Metadata
Add some fields according to specification from https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html
2022-11-24 20:45:04 +01:00
kd-11 8be4ac6869 gl: Fix rotation operations in blit engine 2022-11-22 12:15:18 +03:00
kd-11 81f9259063 gl: Add support for capture debug markers 2022-11-22 12:15:18 +03:00
kd-11 a97424d46c rsx: Fix low precision shader option 2022-11-22 12:15:18 +03:00
brian218 b639f3c8ec Fixed up lv2_fs_mount_point stuff & Fixed loop.tmp potential leak 2022-11-19 10:42:49 +01:00
brian218 13ca1a7f09 Further implemented sys_fs_get_mount_info() and sys_fs_get_mount_info_size() 2022-11-19 10:42:49 +01:00
brian218 16098c38c8 sys_ss_appliance_info_manager(): Fixed VSH error 80029567 and 80029564 2022-11-19 10:42:49 +01:00
kd-11 c4b259e0f8 rsx: Always enable ROP output quantization on NV 2022-11-18 23:06:47 +03:00
kd-11 e04855a0da rsx: Improve ROP output handling
- Perform 8-bit quantization/rounding before emulated operations like ALPHA_TEST
2022-11-18 23:06:47 +03:00
Megamouse 8199f97e7a Qt: add option to automatically resize the game window 2022-11-17 19:58:18 +01:00
Megamouse 2eef3ab645 Update glslang and SPIRV from sdk-1.3.224.1 to sdk-1.3.231.0 2022-11-17 16:04:18 +01:00
Megamouse d56ec56458 Update wolfssl from v5.4.0 to v5.5.0 2022-11-17 16:04:18 +01:00
Megamouse 0293415db1 Update curl from 7.84 to 7.86 2022-11-17 16:04:18 +01:00
Megamouse 6e935d9d84 Update pugixml from v1.12.1 to v1.13 2022-11-17 16:04:18 +01:00
Elad Ashkenazi 99ae561caa cellPad: Noise-cancelling log changes (#12958) 2022-11-16 20:00:22 +01:00
MSuih 3f8421fc17 Add enable exclusive fullscreen mode setting 2022-11-14 17:50:13 +01:00
Megamouse 324b1039cf set cellVideoOutSetGamma to trace
It is spammed a lot in some games and we already know it works.
2022-11-12 11:23:58 +03:00
Megamouse 961d905433 Loader: disable unsupported PPU decoder settings 2022-11-12 11:23:58 +03:00
Megamouse 3c79f3943f Minor simplifcation in ppu_finalize 2022-11-12 11:23:58 +03:00
Megamouse 1e7b2c052a Loader: skip savestate check in add_only mode 2022-11-12 11:23:58 +03:00
Megamouse ff082b98cb VS: fix compilation on VS 17.4 2022-11-12 11:23:58 +03:00
kd-11 3236931416 Whitespace fix only 2022-11-11 12:09:23 +03:00
kd-11 ed0c798252 Wait for renderer to initialize before skipping it for system progress initialization. 2022-11-11 12:09:23 +03:00
kd-11 5943b802d7 grammar 2022-11-11 12:09:23 +03:00
Eladash b875a86e1d PRX: export functions on start() 2022-11-09 02:28:12 +03:00
Eladash 0a35a62235 sys_prx: Make PPU imports/exports thread-safe 2022-11-09 02:28:12 +03:00
kd-11 e98b07de03 vk: Set line width when rasterizing points (workaround)
- Fixes point rendering when using AMD drivers.
2022-11-07 23:12:31 +03:00
kd-11 de5217745c gl: Fix point size export 2022-11-07 23:12:31 +03:00
RipleyTom ec53adc2b7 Fix get_member_and_attrs 2022-11-07 12:31:18 +01:00
Eladash b57ab74ee7 cfg: Partial support for case-insensitivity for true-false settings 2022-11-05 10:36:46 +01:00
Eladash 69368d972d Savestates: Move "Start Paused" setting to UI 2022-11-05 10:36:46 +01:00
473 changed files with 23751 additions and 8600 deletions
+5 -3
View File
@@ -7,11 +7,12 @@ git submodule -q update --init --depth 1 $(awk '/path/ && !/llvm/ { print $3 }'
# Prefer newer Clang than in base system (see also .ci/install-freebsd.sh)
# libc++ isn't in llvm* packages, so download manually
fetch https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-13.0.1-rc1.tar.gz
tar xf llvm*.tar.gz
export CC=clang13 CXX=clang++13
fetch https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.6/llvm-project-15.0.6.src.tar.xz
tar xf llvm*.tar.xz
export CC=clang15 CXX=clang++15
cmake -B libcxx_build -G Ninja -S llvm*/libcxx \
-DLLVM_CCACHE_BUILD=ON \
-DLIBCXX_INCLUDE_BENCHMARKS=OFF \
-DCMAKE_INSTALL_PREFIX:PATH=libcxx_prefix
cmake --build libcxx_build
cmake --install libcxx_build
@@ -20,6 +21,7 @@ export LDFLAGS="$LDFLAGS -nostdlib++ -L$PWD/libcxx_prefix/lib -l:libc++.a -lcxxr
CONFIGURE_ARGS="
-DWITH_LLVM=OFF
-DUSE_SDL=OFF
-DUSE_PRECOMPILED_HEADERS=OFF
-DUSE_NATIVE_INSTRUCTIONS=OFF
-DUSE_SYSTEM_FFMPEG=ON
+1
View File
@@ -51,6 +51,7 @@ cmake .. \
-DCMAKE_AR="$AR" \
-DCMAKE_RANLIB="$RANLIB" \
-DUSE_SYSTEM_CURL=ON \
-DUSE_SDL=OFF \
-DOpenGL_GL_PREFERENCE=LEGACY \
-G Ninja
+42 -12
View File
@@ -1,15 +1,43 @@
#!/bin/sh -ex
brew update
brew install llvm@13 sdl2 nasm qt@5 ninja cmake glew git p7zip create-dmg ccache
brew install -f --overwrite llvm@14 nasm ninja git p7zip create-dmg ccache
export MACOSX_DEPLOYMENT_TARGET=11.6
#/usr/sbin/softwareupdate --install-rosetta --agree-to-license
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
arch -x86_64 /usr/local/homebrew/bin/brew install -f --overwrite llvm@14 sdl2 glew cmake
#export MACOSX_DEPLOYMENT_TARGET=12.0
export CXX=clang++
export CC=clang
export Qt5_DIR="/usr/local/opt/qt@5/lib/cmake/Qt5"
export PATH="/usr/local/opt/llvm@13/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin"
export LDFLAGS="-L/usr/local/opt/llvm@13/lib -Wl,-rpath,/usr/local/opt/llvm@13/lib"
export CPPFLAGS="-I/usr/local/opt/llvm@13/include -msse -msse2 -mcx16 -no-pie"
export BREW_PATH;
BREW_PATH="$(brew --prefix)"
export BREW_X64_PATH;
BREW_X64_PATH="$("/usr/local/homebrew/bin/brew" --prefix)"
export BREW_BIN="/usr/local/bin"
export BREW_SBIN="/usr/local/sbin"
export CMAKE_EXTRA_OPTS='-DLLVM_TARGETS_TO_BUILD=X86'
export WORKDIR;
WORKDIR="$(pwd)"
#get Qt
git clone https://github.com/engnr/qt-downloader.git
cd qt-downloader
git checkout f52efee0f18668c6d6de2dec0234b8c4bc54c597
pip3 install pipenv
pipenv run pip3 install py7zr requests semantic_version lxml
pipenv run ./qt-downloader macos desktop 5.15.2 clang_64 --opensource
cd ..
export Qt5_DIR="$WORKDIR/qt-downloader/5.15.2/clang_64/lib/cmake/Qt5"
export SDL2_DIR="$BREW_X64_PATH/opt/sdl2/lib/cmake/SDL2"
export PATH="$BREW_PATH/opt/llvm@14/bin:$WORKDIR/qt-downloader/5.15.2/clang_64/bin:$BREW_BIN:$BREW_SBIN:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin:$PATH"
export LDFLAGS="-L$BREW_X64_PATH/lib -Wl,-rpath,$BREW_X64_PATH/lib"
export CPPFLAGS="-I$BREW_X64_PATH/include -msse -msse2 -mcx16 -no-pie"
export LIBRARY_PATH="$BREW_X64_PATH/lib"
export LD_LIBRARY_PATH="$BREW_X64_PATH/lib"
git submodule update --init --recursive --depth 1
@@ -18,16 +46,18 @@ sed -i '' "s/extern const double NSAppKitVersionNumber;/const double NSAppKitVer
mkdir build && cd build || exit 1
cmake .. \
-DUSE_DISCORD_RPC=OFF -DUSE_VULKAN=ON -DUSE_ALSA=OFF -DUSE_PULSE=OFF -DUSE_AUDIOUNIT=ON \
-DLLVM_CCACHE_BUILD=OFF -DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF \
"$BREW_X64_PATH/bin/cmake" .. \
-DUSE_SDL=ON -DUSE_DISCORD_RPC=OFF -DUSE_VULKAN=ON -DUSE_ALSA=OFF -DUSE_PULSE=OFF -DUSE_AUDIOUNIT=ON \
-DLLVM_CCACHE_BUILD=OFF -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF \
-DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF \
-DLLVM_INCLUDE_UTILS=OFF -DLLVM_USE_PERF=OFF -DLLVM_ENABLE_Z3_SOLVER=OFF \
-DUSE_NATIVE_INSTRUCTIONS=OFF \
-DUSE_SYSTEM_MVK=OFF \
$CMAKE_EXTRA_OPTS \
-DLLVM_TARGET_ARCH=X86_64 -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_IGNORE_PATH="$BREW_PATH/lib" \
-G Ninja
ninja; build_status=$?;
"$BREW_PATH/bin/ninja"; build_status=$?;
cd ..
@@ -36,4 +66,4 @@ cd ..
if [ "$build_status" -eq 0 ] && [ "$SHOULD_DEPLOY" = "true" ]; then
.ci/deploy-mac.sh
fi
fi
+8 -4
View File
@@ -18,10 +18,14 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
# Embed newer libstdc++ for distros that don't come with it (ubuntu 16.04)
mkdir -p appdir/usr/optional/ ; mkdir -p appdir/usr/optional/libstdc++/
cp /usr/lib/x86_64-linux-gnu/libstdc++.so.6 ./appdir/usr/optional/libstdc++/
# Remove libwayland-client because it has platform-dependent exports and breaks other OSes
rm -f ./appdir/usr/lib/libwayland-client.so*
# Remove libgmodule and libglib due to g_source_set_static_name symbol conflict with host libraries
rm -f ./appdir/usr/lib/libgmodule-2.0.so*
rm -f ./appdir/usr/lib/libglib-2.0.so*
# Install latest appimage runner
rm ./appdir/AppRun
curl -sL https://github.com/RPCS3/AppImageKit-checkrt/releases/download/continuous2/AppRun-patched-x86_64 -o ./appdir/AppRun
@@ -39,7 +43,7 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
# Package it up and send it off
./squashfs-root/usr/bin/appimagetool "$APPDIR"
ls
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ../rpcs3/rpcs3_version.cpp)
@@ -57,7 +61,7 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
FILESIZE=$(stat -c %s ./rpcs3*.AppImage)
SHA256SUM=$(sha256sum ./rpcs3*.AppImage | awk '{ print $1 }')
echo "${SHA256SUM};${FILESIZE}B" > "$RELEASE_MESSAGE"
fi
if [ "$DEPLOY_PPA" = "true" ]; then
+5 -3
View File
@@ -14,7 +14,9 @@ echo "AVVER=$AVVER" >> ../.ci/ci-vars.env
cd bin
mkdir "rpcs3.app/Contents/lib/"
cp "/usr/local/opt/llvm@13/lib/c++/libc++abi.1.0.dylib" "rpcs3.app/Contents/lib/libc++abi.1.dylib"
cp "/usr/local/Homebrew/opt/llvm@14/lib/c++/libc++abi.1.0.dylib" "rpcs3.app/Contents/lib/libc++abi.1.dylib"
rm -rf "rpcs3.app/Contents/Frameworks/QtPdf.framework" \
"rpcs3.app/Contents/Frameworks/QtQml.framework" \
"rpcs3.app/Contents/Frameworks/QtQmlModels.framework" \
@@ -33,7 +35,7 @@ echo "IconIndex=0" >> Quickstart.url
DMG_FILEPATH="$BUILD_ARTIFACTSTAGINGDIRECTORY/rpcs3-v${COMM_TAG}-${COMM_COUNT}-${COMM_HASH}_macos.dmg"
create-dmg --volname RPCS3 \
/opt/homebrew/bin/create-dmg --volname RPCS3 \
--window-size 800 400 \
--icon-size 100 \
--icon rpcs3.app 200 190 \
@@ -45,7 +47,7 @@ create-dmg --volname RPCS3 \
"$DMG_FILEPATH" \
RPCS3.app
7z a -mx9 rpcs3-v"${COMM_TAG}"-"${COMM_COUNT}"-"${COMM_HASH}"_macos.7z RPCS3.app
/opt/homebrew/bin/7z a -mx9 rpcs3-v"${COMM_TAG}"-"${COMM_COUNT}"-"${COMM_HASH}"_macos.7z RPCS3.app
FILESIZE=$(stat -f %z "$DMG_FILEPATH")
SHA256SUM=$(shasum -a 256 "$DMG_FILEPATH" | awk '{ print $1 }')
+1 -1
View File
@@ -9,7 +9,7 @@ export ASSUME_ALWAYS_YES=true
pkg info # debug
# Prefer newer Clang than in base system (see also .ci/build-freebsd.sh)
pkg install llvm13
pkg install llvm15
# Mandatory dependencies (qt5-dbus and qt5-gui are pulled via qt5-widgets)
pkg install git ccache cmake ninja qt5-qmake qt5-buildtools qt5-widgets qt5-concurrent qt5-multimedia qt5-svg glew openal-soft ffmpeg
+1 -1
View File
@@ -21,7 +21,7 @@ QT_MM_URL="${QT_HOST}${QT_PREFIX}qtmultimedia${QT_SUFFIX}"
QT_SVG_URL="${QT_HOST}${QT_PREFIX}qtsvg${QT_SUFFIX}"
LLVMLIBS_URL='https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win/llvmlibs_mt.7z'
GLSLANG_URL='https://github.com/RPCS3/glslang/releases/download/custom-build-win/glslanglibs_mt.7z'
VULKAN_SDK_URL="https://www.dropbox.com/s/o918fc11pfk8x9c/VulkanSDK-${VULKAN_VER}-Installer.exe"
VULKAN_SDK_URL="https://www.dropbox.com/s/cs77c3iv5mbo0bt/VulkanSDK-${VULKAN_VER}-Installer.exe"
DEP_URLS=" \
$QT_BASE_URL \
+9 -7
View File
@@ -23,8 +23,8 @@ windows_task:
QT_VER_MSVC: 'msvc2019'
QT_DATE: '202011130602'
QTDIR: C:\Qt\${QT_VER}\${QT_VER_MSVC}_64
VULKAN_VER: '1.3.204.0'
VULKAN_SDK_SHA: '41f4996335cc5a545d7b2f6e5ff29cf3867789aae4be053a7069aa93408861fa'
VULKAN_VER: '1.3.224.1'
VULKAN_SDK_SHA: '2029e652e39ee6a6036cff3765da31e1e6c595fd2413d3cd111dfab7855621ea'
VULKAN_SDK: C:\VulkanSDK\${VULKAN_VER}
CACHE_DIR: "./cache"
UPLOAD_COMMIT_HASH: 7d09e3be30805911226241afbb14f8cdc2eb054e
@@ -61,7 +61,7 @@ windows_task:
linux_task:
container:
image: rpcs3/rpcs3-ci-bionic:1.5
image: rpcs3/rpcs3-ci-bionic:1.6
cpu: 4
memory: 16G
env:
@@ -120,15 +120,17 @@ freebsd_task:
script: "./.ci/build-freebsd.sh"
macos_task:
timeout_in: 120m
timeout_in: 12000m
ccache_cache:
folder: /tmp/ccache_dir
matrix:
- name: Cirrus macOS
osx_instance:
image: monterey-xcode-13.3
macos_instance:
image: ghcr.io/cirruslabs/macos-monterey-xcode:14
mac_script:
- mkdir artifacts
- chmod +x ".ci/build-mac.sh"
- chmod +x ".ci/deploy-mac.sh"
- ".ci/build-mac.sh"
env:
BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}/artifacts
@@ -141,7 +143,7 @@ macos_task:
RELEASE_MESSAGE: "../GitHubReleaseMessage.txt"
artifacts:
name: Artifact
path: "artifacts/rpcs3-*_macos.*"
path: "artifacts/*"
push_script: |
if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ]; then
source './.ci/export-cirrus-vars.sh'
@@ -29,8 +29,8 @@ body:
Please provide the _exact_ build (or commit) information that introduced the regression you're reporting.
* Please see [How to find the build that caused a regression](https://wiki.rpcs3.net/index.php?title=Help:Using_different_versions_of_RPCS3#How_to_find_the_build_that_caused_a_regression.3F) in our wiki.
* You can find [History of RPCS3 builds](https://rpcs3.net/compatibility?b) here.
Make sure you're running with settings as close to default as possible
Make sure you're running with settings as close to default as possible
* **Do NOT enable any emulator game patches when reporting issues**
* Only change settings that are required for the game to work
- type: input
@@ -48,7 +48,7 @@ body:
Obtaining the log file:
* Run the game until you find the regression.
* Completely close RPCS3 and locate the log file.
RPCS3's Log file will be ```RPCS3.log.gz``` (sometimes shows as RPCS3.log with zip icon) or ```RPCS3.log``` (sometimes shows as RPCS3 wtih notepad icon).
* On Windows it will be in the RPCS3 directory near the executable
* On Linux it will be in ```~/.cache/rpcs3/```
@@ -70,21 +70,21 @@ body:
* To create an RSX capture, use _Create_ _RSX_ _Capture_ under _Utilities_.
* Captures will be stored in RPCS3 folder → captures.
* To create a RenderDoc capture, please refer to [RenderDoc's documentation](https://renderdoc.org/docs/how/how_capture_frame.html).
- type: textarea
- type: textarea
id: captures
attributes:
label: Attach capture files for visual issues
description: Compress your capture with 7z, Rar etc. and attach it here, or upload it to the cloud (Dropbox, Mega etc) and add a link to it.
validations:
required: false
- type: textarea
- type: textarea
id: system-info
attributes:
label: System configuration
description: Provide information about your system, such as operating system, CPU and GPU model, GPU driver version and other information that describes your system configuration.
validations:
required: false
- type: textarea
- type: textarea
id: other-details
attributes:
label: Other details
+6 -6
View File
@@ -28,13 +28,13 @@ body:
attributes:
value: |
# Log files
Provide a log file that includes the bug you're reporting.
Obtaining the log file:
* Run the game until you find the regression.
* Completely close RPCS3 and locate the log file.
RPCS3's Log file will be ```RPCS3.log.gz``` (sometimes shows as RPCS3.log with zip icon) or ```RPCS3.log``` (sometimes shows as RPCS3 wtih notepad icon).
* On Windows it will be in the RPCS3 directory near the executable
* On Linux it will be in ```~/.cache/rpcs3/```
@@ -55,21 +55,21 @@ body:
* To create an RSX capture, use _Create_ _RSX_ _Capture_ under _Utilities_.
* Captures will be stored in RPCS3 folder → captures.
* To create a RenderDoc capture, please refer to [RenderDoc's documentation](https://renderdoc.org/docs/how/how_capture_frame.html).
- type: textarea
- type: textarea
id: captures
attributes:
label: Attach capture files for visual issues
description: Compress your capture with 7z, Rar etc. and attach it here, or upload it to the cloud (Dropbox, Mega etc) and add a link to it.
validations:
required: false
- type: textarea
- type: textarea
id: system-info
attributes:
label: System configuration
description: Provide information about your system, such as operating system, CPU and GPU model, GPU driver version and other information that describes your system configuration.
validations:
required: false
- type: textarea
- type: textarea
id: other-details
attributes:
label: Other details
+1 -1
View File
@@ -29,7 +29,7 @@ body:
* Why your feature is important to RPCS3.
* If the feature is implemented in other projects, attach screenshots.
* If this feature is something that a game is trying to use, upload a log file for it.
RPCS3's Log file will be ```RPCS3.log.gz``` (sometimes shows as RPCS3.log with zip icon) or ```RPCS3.log``` (sometimes shows as RPCS3 wtih notepad icon).
* On Windows it will be in the RPCS3 directory near the executable
* On Linux it will be in ```~/.cache/rpcs3/```
+3
View File
@@ -122,6 +122,9 @@ yaml-cpp.pc
/3rdparty/libusb_cmake/config.h
/3rdparty/libusb_cmake/libusb-1.0.pc
# miniupnp
/3rdparty/miniupnp/x64/*
# ssl certificate
cacert.pem
+7
View File
@@ -76,3 +76,10 @@
path = 3rdparty/SoundTouch/soundtouch
url = ../../RPCS3/soundtouch.git
ignore = dirty
[submodule "3rdparty/libsdl-org/SDL"]
path = 3rdparty/libsdl-org/SDL
url = https://github.com/libsdl-org/SDL.git
ignore = dirty
[submodule "3rdparty/miniupnp/miniupnp"]
path = 3rdparty/miniupnp/miniupnp
url = https://github.com/miniupnp/miniupnp.git
+46 -12
View File
@@ -142,7 +142,7 @@ add_subdirectory(SoundTouch EXCLUDE_FROM_ALL)
# libevdev
set(LIBEVDEV_TARGET 3rdparty_dummy_lib)
if(USE_LIBEVDEV)
pkg_check_modules(LIBEVDEV libevdev)
pkg_check_modules(LIBEVDEV libevdev libudev)
if(LIBEVDEV_FOUND)
add_library(3rdparty_libevdev INTERFACE)
target_compile_definitions(3rdparty_libevdev INTERFACE -DHAVE_LIBEVDEV)
@@ -165,10 +165,10 @@ if(USE_VULKAN)
message("-- RPCS3: MoltenVK submodule")
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK"
)
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK"
)
add_library(moltenvk_lib SHARED IMPORTED)
@@ -222,21 +222,28 @@ set(FAUDIO_TARGET 3rdparty_dummy_lib)
if(USE_FAUDIO)
# FAudio depends on SDL2
find_package(SDL2)
if (NOT SDL2_FOUND OR SDL2_VERSION VERSION_LESS 2.0.12)
message(WARNING
"-- RPCS3: FAudio requires SDL 2.0.9 or newer. Please note, this warning"
"can also be displayed with SDL2 versions between 2.0.9-2.0.12, as the"
"CMake config files are not correctly installed. Since a valid SDL2"
">=2.0.9 version cannot be found, building with FAudio will be skipped.")
set(USE_FAUDIO False)
else()
if (USE_SYSTEM_FAUDIO)
if (USE_SYSTEM_FAUDIO)
if (NOT SDL2_FOUND OR SDL2_VERSION VERSION_LESS 2.0.12)
message(WARNING
"-- RPCS3: System FAudio requires SDL 2.0.9 or newer. Please note, this warning"
"can also be displayed with SDL2 versions between 2.0.9-2.0.12, as the"
"CMake config files are not correctly installed. Since a valid SDL2"
">=2.0.9 version cannot be found, building with FAudio will be skipped.")
set(USE_FAUDIO OFF CACHE BOOL "Disabled using system FAudio with SDL < 2.0.12" FORCE)
else()
message(STATUS "RPCS3: Using system FAudio")
find_package(FAudio REQUIRED CONFIGS FAudioConfig.cmake FAudio-config.cmake)
add_library(3rdparty_FAudio INTERFACE)
target_link_libraries(3rdparty_FAudio INTERFACE FAudio)
target_compile_definitions(3rdparty_FAudio INTERFACE -DHAVE_FAUDIO)
set(FAUDIO_TARGET 3rdparty_FAudio)
endif()
else()
if (NOT SDL2_FOUND OR SDL2_VERSION VERSION_LESS 2.24.0)
message(WARNING
"-- RPCS3: 3rdparty FAudio requires SDL 2.24.0 or newer. Since a valid SDL2"
">=2.24.0 version cannot be found, building with FAudio will be skipped.")
set(USE_FAUDIO OFF CACHE BOOL "Disabled FAudio with SDL < 2.24.0" FORCE)
else()
message(STATUS "RPCS3: Using builtin FAudio")
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared library")
@@ -329,6 +336,31 @@ add_subdirectory(wolfssl EXCLUDE_FROM_ALL)
# CURL
add_subdirectory(curl EXCLUDE_FROM_ALL)
# SDL2
set(SDL2_TARGET 3rdparty_dummy_lib)
if(USE_SDL)
if(USE_SYSTEM_SDL)
find_package(SDL2)
if(SDL2_FOUND AND NOT SDL2_VERSION VERSION_LESS 2.24.0)
message(STATUS "Using system SDL2")
add_library(3rdparty_sdl2 INTERFACE)
target_compile_definitions(3rdparty_sdl2 INTERFACE -DHAVE_SDL2=1)
set(SDL2_TARGET 3rdparty_sdl2)
else()
message(FATAL_ERROR "SDL2 is not available on this system")
endif()
else()
message(STATUS "Using static SDL2 from 3rdparty")
add_library(3rdparty_sdl2 INTERFACE)
target_compile_definitions(3rdparty_sdl2 INTERFACE -DHAVE_SDL2=1)
add_subdirectory(libsdl-org EXCLUDE_FROM_ALL)
set(SDL2_TARGET 3rdparty_sdl2)
endif()
endif()
# MINIUPNP
add_subdirectory(miniupnp EXCLUDE_FROM_ALL)
# add nice ALIAS targets for ease of use
if(USE_SYSTEM_LIBUSB)
add_library(3rdparty::libusb ALIAS usb-1.0-shared)
@@ -355,3 +387,5 @@ add_library(3rdparty::glew ALIAS 3rdparty_glew)
add_library(3rdparty::wolfssl ALIAS wolfssl)
add_library(3rdparty::libcurl ALIAS libcurl)
add_library(3rdparty::soundtouch ALIAS soundtouch)
add_library(3rdparty::sdl2 ALIAS ${SDL2_TARGET})
add_library(3rdparty::miniupnpc ALIAS libminiupnpc-static)
+1 -1
View File
@@ -4,7 +4,7 @@ include(ExternalProject)
ExternalProject_Add(moltenvk
GIT_REPOSITORY https://github.com/KhronosGroup/MoltenVK.git
GIT_TAG 260bad4
GIT_TAG fb581e4
BUILD_IN_SOURCE 1
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK
CONFIGURE_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/fetchDependencies" --macos
+9 -3
View File
@@ -66,12 +66,12 @@
<ClCompile Include="curl\lib\base64.c" />
<ClCompile Include="curl\lib\bufref.c" />
<ClCompile Include="curl\lib\c-hyper.c" />
<ClCompile Include="curl\lib\cfilters.c" />
<ClCompile Include="curl\lib\conncache.c" />
<ClCompile Include="curl\lib\connect.c" />
<ClCompile Include="curl\lib\content_encoding.c" />
<ClCompile Include="curl\lib\cookie.c" />
<ClCompile Include="curl\lib\curl_addrinfo.c" />
<ClCompile Include="curl\lib\curl_ctype.c" />
<ClCompile Include="curl\lib\curl_des.c" />
<ClCompile Include="curl\lib\curl_endian.c" />
<ClCompile Include="curl\lib\curl_fnmatch.c" />
@@ -90,7 +90,6 @@
<ClCompile Include="curl\lib\curl_threads.c" />
<ClCompile Include="curl\lib\dict.c" />
<ClCompile Include="curl\lib\doh.c" />
<ClCompile Include="curl\lib\dotdot.c" />
<ClCompile Include="curl\lib\dynbuf.c" />
<ClCompile Include="curl\lib\easy.c" />
<ClCompile Include="curl\lib\easygetopt.c" />
@@ -123,7 +122,7 @@
<ClCompile Include="curl\lib\http_negotiate.c" />
<ClCompile Include="curl\lib\http_ntlm.c" />
<ClCompile Include="curl\lib\http_proxy.c" />
<ClCompile Include="curl\lib\idn_win32.c" />
<ClCompile Include="curl\lib\idn.c" />
<ClCompile Include="curl\lib\if2ip.c" />
<ClCompile Include="curl\lib\imap.c" />
<ClCompile Include="curl\lib\inet_ntop.c" />
@@ -140,6 +139,7 @@
<ClCompile Include="curl\lib\multi.c" />
<ClCompile Include="curl\lib\netrc.c" />
<ClCompile Include="curl\lib\nonblock.c" />
<ClCompile Include="curl\lib\noproxy.c" />
<ClCompile Include="curl\lib\openldap.c" />
<ClCompile Include="curl\lib\parsedate.c" />
<ClCompile Include="curl\lib\pingpong.c" />
@@ -215,6 +215,7 @@
<ClCompile Include="curl\lib\vtls\sectransp.c" />
<ClCompile Include="curl\lib\vtls\vtls.c" />
<ClCompile Include="curl\lib\vtls\wolfssl.c" />
<ClCompile Include="curl\lib\ws.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="curl\include\curl\curl.h" />
@@ -232,6 +233,7 @@
<ClInclude Include="curl\lib\asyn.h" />
<ClInclude Include="curl\lib\bufref.h" />
<ClInclude Include="curl\lib\c-hyper.h" />
<ClInclude Include="curl\lib\cfilters.h" />
<ClInclude Include="curl\lib\config-amigaos.h" />
<ClInclude Include="curl\lib\config-dos.h" />
<ClInclude Include="curl\lib\config-mac.h" />
@@ -288,6 +290,7 @@
<ClInclude Include="curl\lib\formdata.h" />
<ClInclude Include="curl\lib\ftp.h" />
<ClInclude Include="curl\lib\ftplistparser.h" />
<ClInclude Include="curl\lib\functypes.h" />
<ClInclude Include="curl\lib\getinfo.h" />
<ClInclude Include="curl\lib\gopher.h" />
<ClInclude Include="curl\lib\h2h3.h" />
@@ -303,6 +306,7 @@
<ClInclude Include="curl\lib\http_negotiate.h" />
<ClInclude Include="curl\lib\http_ntlm.h" />
<ClInclude Include="curl\lib\http_proxy.h" />
<ClInclude Include="curl\lib\idn.h" />
<ClInclude Include="curl\lib\if2ip.h" />
<ClInclude Include="curl\lib\imap.h" />
<ClInclude Include="curl\lib\inet_ntop.h" />
@@ -315,6 +319,7 @@
<ClInclude Include="curl\lib\multiif.h" />
<ClInclude Include="curl\lib\netrc.h" />
<ClInclude Include="curl\lib\nonblock.h" />
<ClInclude Include="curl\lib\noproxy.h" />
<ClInclude Include="curl\lib\parsedate.h" />
<ClInclude Include="curl\lib\pingpong.h" />
<ClInclude Include="curl\lib\pop3.h" />
@@ -380,6 +385,7 @@
<ClInclude Include="curl\lib\vtls\sectransp.h" />
<ClInclude Include="curl\lib\vtls\vtls.h" />
<ClInclude Include="curl\lib\vtls\wolfssl.h" />
<ClInclude Include="curl\lib\ws.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="curl\lib\libcurl.rc" />
+27 -9
View File
@@ -48,9 +48,6 @@
<ClCompile Include="curl\lib\curl_addrinfo.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\curl_ctype.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\curl_des.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -105,9 +102,6 @@
<ClCompile Include="curl\lib\doh.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\dotdot.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\easy.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -180,9 +174,6 @@
<ClCompile Include="curl\lib\http_proxy.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\idn_win32.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\if2ip.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -483,6 +474,18 @@
<ClCompile Include="curl\lib\fopen.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\noproxy.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\ws.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\cfilters.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\idn.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="curl\include\curl\curl.h">
@@ -974,6 +977,21 @@
<ClInclude Include="curl\lib\fopen.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\functypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\noproxy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\ws.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\cfilters.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\idn.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="curl\lib\libcurl.rc">
+11
View File
@@ -0,0 +1,11 @@
option(SDL2_DISABLE_SDL2MAIN "" ON)
option(SDL2_DISABLE_INSTALL "" ON)
option(SDL2_DISABLE_UNINSTALL "" ON)
option(SDL_SHARED OFF)
set(SDL_SHARED_ENABLED_BY_DEFAULT OFF)
option(SDL_STATIC ON)
set(SDL_STATIC_ENABLED_BY_DEFAULT ON)
option(SDL_TEST OFF)
set(SDL_TEST_ENABLED_BY_DEFAULT OFF)
set(OPT_DEF_LIBC ON)
add_subdirectory(SDL EXCLUDE_FROM_ALL)
Vendored Submodule
+1
Submodule 3rdparty/libsdl-org/SDL added at adf31f6ec0
+461
View File
@@ -0,0 +1,461 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SDL\include\begin_code.h" />
<ClInclude Include="SDL\include\close_code.h" />
<ClInclude Include="SDL\include\SDL.h" />
<ClInclude Include="SDL\include\SDL_assert.h" />
<ClInclude Include="SDL\include\SDL_atomic.h" />
<ClInclude Include="SDL\include\SDL_audio.h" />
<ClInclude Include="SDL\include\SDL_bits.h" />
<ClInclude Include="SDL\include\SDL_blendmode.h" />
<ClInclude Include="SDL\include\SDL_clipboard.h" />
<ClInclude Include="SDL\include\SDL_config.h" />
<ClInclude Include="SDL\include\SDL_config_windows.h" />
<ClInclude Include="SDL\include\SDL_copying.h" />
<ClInclude Include="SDL\include\SDL_cpuinfo.h" />
<ClInclude Include="SDL\include\SDL_egl.h" />
<ClInclude Include="SDL\include\SDL_endian.h" />
<ClInclude Include="SDL\include\SDL_error.h" />
<ClInclude Include="SDL\include\SDL_events.h" />
<ClInclude Include="SDL\include\SDL_filesystem.h" />
<ClInclude Include="SDL\include\SDL_gamecontroller.h" />
<ClInclude Include="SDL\include\SDL_gesture.h" />
<ClInclude Include="SDL\include\SDL_guid.h" />
<ClInclude Include="SDL\include\SDL_haptic.h" />
<ClInclude Include="SDL\include\SDL_hints.h" />
<ClInclude Include="SDL\include\SDL_hidapi.h" />
<ClInclude Include="SDL\include\SDL_joystick.h" />
<ClInclude Include="SDL\include\SDL_keyboard.h" />
<ClInclude Include="SDL\include\SDL_keycode.h" />
<ClInclude Include="SDL\include\SDL_loadso.h" />
<ClInclude Include="SDL\include\SDL_locale.h" />
<ClInclude Include="SDL\include\SDL_log.h" />
<ClInclude Include="SDL\include\SDL_main.h" />
<ClInclude Include="SDL\include\SDL_messagebox.h" />
<ClInclude Include="SDL\include\SDL_metal.h" />
<ClInclude Include="SDL\include\SDL_misc.h" />
<ClInclude Include="SDL\include\SDL_mouse.h" />
<ClInclude Include="SDL\include\SDL_mutex.h" />
<ClInclude Include="SDL\include\SDL_name.h" />
<ClInclude Include="SDL\include\SDL_opengl.h" />
<ClInclude Include="SDL\include\SDL_opengl_glext.h" />
<ClInclude Include="SDL\include\SDL_opengles.h" />
<ClInclude Include="SDL\include\SDL_opengles2.h" />
<ClInclude Include="SDL\include\SDL_opengles2_gl2.h" />
<ClInclude Include="SDL\include\SDL_opengles2_gl2ext.h" />
<ClInclude Include="SDL\include\SDL_opengles2_gl2platform.h" />
<ClInclude Include="SDL\include\SDL_opengles2_khrplatform.h" />
<ClInclude Include="SDL\include\SDL_pixels.h" />
<ClInclude Include="SDL\include\SDL_platform.h" />
<ClInclude Include="SDL\include\SDL_power.h" />
<ClInclude Include="SDL\include\SDL_quit.h" />
<ClInclude Include="SDL\include\SDL_rect.h" />
<ClInclude Include="SDL\include\SDL_render.h" />
<ClInclude Include="SDL\include\SDL_revision.h" />
<ClInclude Include="SDL\include\SDL_rwops.h" />
<ClInclude Include="SDL\include\SDL_scancode.h" />
<ClInclude Include="SDL\include\SDL_sensor.h" />
<ClInclude Include="SDL\include\SDL_shape.h" />
<ClInclude Include="SDL\include\SDL_stdinc.h" />
<ClInclude Include="SDL\include\SDL_surface.h" />
<ClInclude Include="SDL\include\SDL_system.h" />
<ClInclude Include="SDL\include\SDL_syswm.h" />
<ClInclude Include="SDL\include\SDL_test.h" />
<ClInclude Include="SDL\include\SDL_test_assert.h" />
<ClInclude Include="SDL\include\SDL_test_common.h" />
<ClInclude Include="SDL\include\SDL_test_compare.h" />
<ClInclude Include="SDL\include\SDL_test_crc32.h" />
<ClInclude Include="SDL\include\SDL_test_font.h" />
<ClInclude Include="SDL\include\SDL_test_fuzzer.h" />
<ClInclude Include="SDL\include\SDL_test_harness.h" />
<ClInclude Include="SDL\include\SDL_test_images.h" />
<ClInclude Include="SDL\include\SDL_test_log.h" />
<ClInclude Include="SDL\include\SDL_test_md5.h" />
<ClInclude Include="SDL\include\SDL_test_memory.h" />
<ClInclude Include="SDL\include\SDL_test_random.h" />
<ClInclude Include="SDL\include\SDL_thread.h" />
<ClInclude Include="SDL\include\SDL_timer.h" />
<ClInclude Include="SDL\include\SDL_touch.h" />
<ClInclude Include="SDL\include\SDL_types.h" />
<ClInclude Include="SDL\include\SDL_version.h" />
<ClInclude Include="SDL\include\SDL_video.h" />
<ClInclude Include="SDL\include\SDL_vulkan.h" />
<ClInclude Include="SDL\src\audio\directsound\SDL_directsound.h" />
<ClInclude Include="SDL\src\audio\disk\SDL_diskaudio.h" />
<ClInclude Include="SDL\src\audio\dummy\SDL_dummyaudio.h" />
<ClInclude Include="SDL\src\audio\SDL_audio_c.h" />
<ClInclude Include="SDL\src\audio\SDL_audiodev_c.h" />
<ClInclude Include="SDL\src\audio\SDL_sysaudio.h" />
<ClInclude Include="SDL\src\audio\SDL_wave.h" />
<ClInclude Include="SDL\src\audio\wasapi\SDL_wasapi.h" />
<ClInclude Include="SDL\src\audio\winmm\SDL_winmm.h" />
<ClInclude Include="SDL\src\core\windows\SDL_directx.h" />
<ClInclude Include="SDL\src\core\windows\SDL_hid.h" />
<ClInclude Include="SDL\src\core\windows\SDL_immdevice.h" />
<ClInclude Include="SDL\src\core\windows\SDL_windows.h" />
<ClInclude Include="SDL\src\core\windows\SDL_xinput.h" />
<ClInclude Include="SDL\src\dynapi\SDL_dynapi.h" />
<ClInclude Include="SDL\src\dynapi\SDL_dynapi_overrides.h" />
<ClInclude Include="SDL\src\dynapi\SDL_dynapi_procs.h" />
<ClInclude Include="SDL\src\events\blank_cursor.h" />
<ClInclude Include="SDL\src\events\default_cursor.h" />
<ClInclude Include="SDL\src\events\scancodes_windows.h" />
<ClInclude Include="SDL\src\events\SDL_clipboardevents_c.h" />
<ClInclude Include="SDL\src\events\SDL_displayevents_c.h" />
<ClInclude Include="SDL\src\events\SDL_dropevents_c.h" />
<ClInclude Include="SDL\src\events\SDL_events_c.h" />
<ClInclude Include="SDL\src\events\SDL_gesture_c.h" />
<ClInclude Include="SDL\src\events\SDL_keyboard_c.h" />
<ClInclude Include="SDL\src\events\SDL_mouse_c.h" />
<ClInclude Include="SDL\src\events\SDL_touch_c.h" />
<ClInclude Include="SDL\src\events\SDL_windowevents_c.h" />
<ClInclude Include="SDL\src\haptic\SDL_haptic_c.h" />
<ClInclude Include="SDL\src\haptic\SDL_syshaptic.h" />
<ClInclude Include="SDL\src\haptic\windows\SDL_dinputhaptic_c.h" />
<ClInclude Include="SDL\src\haptic\windows\SDL_windowshaptic_c.h" />
<ClInclude Include="SDL\src\haptic\windows\SDL_xinputhaptic_c.h" />
<ClInclude Include="SDL\src\hidapi\hidapi\hidapi.h" />
<ClInclude Include="SDL\src\hidapi\SDL_hidapi_c.h" />
<ClInclude Include="SDL\src\joystick\controller_type.h" />
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapijoystick_c.h" />
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_nintendo.h" />
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_rumble.h" />
<ClInclude Include="SDL\src\joystick\SDL_gamecontrollerdb.h" />
<ClInclude Include="SDL\src\joystick\SDL_joystick_c.h" />
<ClInclude Include="SDL\src\joystick\SDL_sysjoystick.h" />
<ClInclude Include="SDL\src\joystick\usb_ids.h" />
<ClInclude Include="SDL\src\joystick\virtual\SDL_virtualjoystick_c.h" />
<ClInclude Include="SDL\src\joystick\windows\SDL_dinputjoystick_c.h" />
<ClInclude Include="SDL\src\joystick\windows\SDL_rawinputjoystick_c.h" />
<ClInclude Include="SDL\src\joystick\windows\SDL_windowsjoystick_c.h" />
<ClInclude Include="SDL\src\joystick\windows\SDL_xinputjoystick_c.h" />
<ClInclude Include="SDL\src\libm\math_libm.h" />
<ClInclude Include="SDL\src\libm\math_private.h" />
<ClInclude Include="SDL\src\locale\SDL_syslocale.h" />
<ClInclude Include="SDL\src\misc\SDL_sysurl.h" />
<ClInclude Include="SDL\src\power\SDL_syspower.h" />
<ClInclude Include="SDL\src\render\direct3d11\SDL_shaders_d3d11.h" />
<ClInclude Include="SDL\src\render\direct3d12\SDL_shaders_d3d12.h" />
<ClInclude Include="SDL\src\render\direct3d\SDL_shaders_d3d.h" />
<ClInclude Include="SDL\src\render\opengles2\SDL_gles2funcs.h" />
<ClInclude Include="SDL\src\render\opengles2\SDL_shaders_gles2.h" />
<ClInclude Include="SDL\src\render\opengl\SDL_glfuncs.h" />
<ClInclude Include="SDL\src\render\opengl\SDL_shaders_gl.h" />
<ClInclude Include="SDL\src\render\SDL_d3dmath.h" />
<ClInclude Include="SDL\src\render\SDL_sysrender.h" />
<ClInclude Include="SDL\src\render\SDL_yuv_sw_c.h" />
<ClInclude Include="SDL\src\render\software\SDL_blendfillrect.h" />
<ClInclude Include="SDL\src\render\software\SDL_blendline.h" />
<ClInclude Include="SDL\src\render\software\SDL_blendpoint.h" />
<ClInclude Include="SDL\src\render\software\SDL_draw.h" />
<ClInclude Include="SDL\src\render\software\SDL_drawline.h" />
<ClInclude Include="SDL\src\render\software\SDL_drawpoint.h" />
<ClInclude Include="SDL\src\render\software\SDL_render_sw_c.h" />
<ClInclude Include="SDL\src\render\software\SDL_rotate.h" />
<ClInclude Include="SDL\src\render\software\SDL_triangle.h" />
<ClInclude Include="SDL\src\SDL_assert_c.h" />
<ClInclude Include="SDL\src\SDL_dataqueue.h" />
<ClInclude Include="SDL\src\SDL_error_c.h" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_ps3.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_steam.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_wii.c" />
<ClCompile Include="SDL\src\SDL_guid.c" />
<ClInclude Include="SDL\src\SDL_hints_c.h" />
<ClInclude Include="SDL\src\SDL_internal.h" />
<ClInclude Include="SDL\src\SDL_list.h" />
<ClInclude Include="SDL\src\SDL_log_c.h" />
<ClInclude Include="SDL\src\sensor\dummy\SDL_dummysensor.h" />
<ClInclude Include="SDL\src\sensor\SDL_sensor_c.h" />
<ClInclude Include="SDL\src\sensor\SDL_syssensor.h" />
<ClInclude Include="SDL\src\sensor\windows\SDL_windowssensor.h" />
<ClInclude Include="SDL\src\thread\SDL_systhread.h" />
<ClInclude Include="SDL\src\thread\SDL_thread_c.h" />
<ClInclude Include="SDL\src\thread\generic\SDL_syscond_c.h" />
<ClInclude Include="SDL\src\thread\windows\SDL_sysmutex_c.h" />
<ClInclude Include="SDL\src\thread\windows\SDL_systhread_c.h" />
<ClInclude Include="SDL\src\timer\SDL_timer_c.h" />
<ClInclude Include="SDL\src\video\dummy\SDL_nullevents_c.h" />
<ClInclude Include="SDL\src\video\dummy\SDL_nullframebuffer_c.h" />
<ClInclude Include="SDL\src\video\dummy\SDL_nullvideo.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_icd.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_layer.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_platform.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_sdk_platform.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan.hpp" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_android.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_beta.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_core.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_directfb.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_fuchsia.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_ggp.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_ios.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_macos.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_metal.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_vi.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_wayland.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_win32.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xcb.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xlib.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xlib_xrandr.h" />
<ClInclude Include="SDL\src\video\SDL_blit.h" />
<ClInclude Include="SDL\src\video\SDL_blit_auto.h" />
<ClInclude Include="SDL\src\video\SDL_blit_copy.h" />
<ClInclude Include="SDL\src\video\SDL_blit_slow.h" />
<ClInclude Include="SDL\src\video\SDL_egl_c.h" />
<ClInclude Include="SDL\src\video\SDL_pixels_c.h" />
<ClInclude Include="SDL\src\video\SDL_rect_c.h" />
<ClInclude Include="SDL\src\video\SDL_RLEaccel_c.h" />
<ClInclude Include="SDL\src\video\SDL_shape_internals.h" />
<ClInclude Include="SDL\src\video\SDL_sysvideo.h" />
<ClInclude Include="SDL\src\video\SDL_vulkan_internal.h" />
<ClInclude Include="SDL\src\video\SDL_yuv_c.h" />
<ClInclude Include="SDL\src\video\windows\SDL_msctf.h" />
<ClInclude Include="SDL\src\video\windows\SDL_vkeys.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsclipboard.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsevents.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsframebuffer.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowskeyboard.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsmessagebox.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsmodes.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsmouse.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsopengl.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsopengles.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsshape.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsvideo.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsvulkan.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowswindow.h" />
<ClInclude Include="SDL\src\video\windows\wmmsg.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_sse_func.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_std_func.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="SDL\src\atomic\SDL_atomic.c" />
<ClCompile Include="SDL\src\atomic\SDL_spinlock.c" />
<ClCompile Include="SDL\src\audio\directsound\SDL_directsound.c" />
<ClCompile Include="SDL\src\audio\disk\SDL_diskaudio.c" />
<ClCompile Include="SDL\src\audio\dummy\SDL_dummyaudio.c" />
<ClCompile Include="SDL\src\audio\SDL_audio.c" />
<ClCompile Include="SDL\src\audio\SDL_audiocvt.c" />
<ClCompile Include="SDL\src\audio\SDL_audiodev.c" />
<ClCompile Include="SDL\src\audio\SDL_audiotypecvt.c" />
<ClCompile Include="SDL\src\audio\SDL_mixer.c" />
<ClCompile Include="SDL\src\audio\SDL_wave.c" />
<ClCompile Include="SDL\src\audio\winmm\SDL_winmm.c" />
<ClCompile Include="SDL\src\audio\wasapi\SDL_wasapi.c" />
<ClCompile Include="SDL\src\audio\wasapi\SDL_wasapi_win32.c" />
<ClCompile Include="SDL\src\core\windows\SDL_hid.c" />
<ClCompile Include="SDL\src\core\windows\SDL_immdevice.c" />
<ClCompile Include="SDL\src\core\windows\SDL_windows.c" />
<ClCompile Include="SDL\src\core\windows\SDL_xinput.c" />
<ClCompile Include="SDL\src\cpuinfo\SDL_cpuinfo.c" />
<ClCompile Include="SDL\src\dynapi\SDL_dynapi.c" />
<ClCompile Include="SDL\src\events\SDL_clipboardevents.c" />
<ClCompile Include="SDL\src\events\SDL_displayevents.c" />
<ClCompile Include="SDL\src\events\SDL_dropevents.c" />
<ClCompile Include="SDL\src\events\SDL_events.c" />
<ClCompile Include="SDL\src\events\SDL_gesture.c" />
<ClCompile Include="SDL\src\events\SDL_keyboard.c" />
<ClCompile Include="SDL\src\events\SDL_mouse.c" />
<ClCompile Include="SDL\src\events\SDL_quit.c" />
<ClCompile Include="SDL\src\events\SDL_touch.c" />
<ClCompile Include="SDL\src\events\SDL_windowevents.c" />
<ClCompile Include="SDL\src\file\SDL_rwops.c" />
<ClCompile Include="SDL\src\filesystem\windows\SDL_sysfilesystem.c" />
<ClCompile Include="SDL\src\haptic\dummy\SDL_syshaptic.c" />
<ClCompile Include="SDL\src\haptic\SDL_haptic.c" />
<ClCompile Include="SDL\src\haptic\windows\SDL_dinputhaptic.c" />
<ClCompile Include="SDL\src\haptic\windows\SDL_windowshaptic.c" />
<ClCompile Include="SDL\src\haptic\windows\SDL_xinputhaptic.c" />
<ClCompile Include="SDL\src\hidapi\SDL_hidapi.c" />
<ClCompile Include="SDL\src\joystick\controller_type.c" />
<ClCompile Include="SDL\src\joystick\dummy\SDL_sysjoystick.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapijoystick.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_combined.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_gamecube.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_luna.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_ps4.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_ps5.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_rumble.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_shield.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_stadia.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_switch.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_xbox360.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_xbox360w.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
<ClCompile Include="SDL\src\joystick\SDL_gamecontroller.c" />
<ClCompile Include="SDL\src\joystick\SDL_joystick.c" />
<ClCompile Include="SDL\src\joystick\virtual\SDL_virtualjoystick.c" />
<ClCompile Include="SDL\src\joystick\windows\SDL_dinputjoystick.c" />
<ClCompile Include="SDL\src\joystick\windows\SDL_rawinputjoystick.c" />
<ClCompile Include="SDL\src\joystick\windows\SDL_windowsjoystick.c" />
<ClCompile Include="SDL\src\joystick\windows\SDL_windows_gaming_input.c" />
<ClCompile Include="SDL\src\joystick\windows\SDL_xinputjoystick.c" />
<ClCompile Include="SDL\src\libm\e_atan2.c" />
<ClCompile Include="SDL\src\libm\e_exp.c" />
<ClCompile Include="SDL\src\libm\e_fmod.c" />
<ClCompile Include="SDL\src\libm\e_log.c" />
<ClCompile Include="SDL\src\libm\e_log10.c" />
<ClCompile Include="SDL\src\libm\e_pow.c" />
<ClCompile Include="SDL\src\libm\e_rem_pio2.c" />
<ClCompile Include="SDL\src\libm\e_sqrt.c" />
<ClCompile Include="SDL\src\libm\k_cos.c" />
<ClCompile Include="SDL\src\libm\k_rem_pio2.c" />
<ClCompile Include="SDL\src\libm\k_sin.c" />
<ClCompile Include="SDL\src\libm\k_tan.c" />
<ClCompile Include="SDL\src\libm\s_atan.c" />
<ClCompile Include="SDL\src\libm\s_copysign.c" />
<ClCompile Include="SDL\src\libm\s_cos.c" />
<ClCompile Include="SDL\src\libm\s_fabs.c" />
<ClCompile Include="SDL\src\libm\s_floor.c" />
<ClCompile Include="SDL\src\libm\s_scalbn.c" />
<ClCompile Include="SDL\src\libm\s_sin.c" />
<ClCompile Include="SDL\src\libm\s_tan.c" />
<ClCompile Include="SDL\src\loadso\windows\SDL_sysloadso.c" />
<ClCompile Include="SDL\src\locale\SDL_locale.c" />
<ClCompile Include="SDL\src\locale\windows\SDL_syslocale.c" />
<ClCompile Include="SDL\src\misc\SDL_url.c" />
<ClCompile Include="SDL\src\misc\windows\SDL_sysurl.c" />
<ClCompile Include="SDL\src\power\SDL_power.c" />
<ClCompile Include="SDL\src\power\windows\SDL_syspower.c" />
<ClCompile Include="SDL\src\render\direct3d11\SDL_shaders_d3d11.c" />
<ClCompile Include="SDL\src\render\direct3d12\SDL_render_d3d12.c" />
<ClCompile Include="SDL\src\render\direct3d12\SDL_shaders_d3d12.c" />
<ClCompile Include="SDL\src\render\direct3d\SDL_render_d3d.c" />
<ClCompile Include="SDL\src\render\direct3d11\SDL_render_d3d11.c" />
<ClCompile Include="SDL\src\render\direct3d\SDL_shaders_d3d.c" />
<ClCompile Include="SDL\src\render\opengl\SDL_render_gl.c" />
<ClCompile Include="SDL\src\render\opengl\SDL_shaders_gl.c" />
<ClCompile Include="SDL\src\render\opengles2\SDL_render_gles2.c" />
<ClCompile Include="SDL\src\render\opengles2\SDL_shaders_gles2.c" />
<ClCompile Include="SDL\src\render\SDL_d3dmath.c" />
<ClCompile Include="SDL\src\render\SDL_render.c" />
<ClCompile Include="SDL\src\render\SDL_yuv_sw.c" />
<ClCompile Include="SDL\src\render\software\SDL_blendfillrect.c" />
<ClCompile Include="SDL\src\render\software\SDL_blendline.c" />
<ClCompile Include="SDL\src\render\software\SDL_blendpoint.c" />
<ClCompile Include="SDL\src\render\software\SDL_drawline.c" />
<ClCompile Include="SDL\src\render\software\SDL_drawpoint.c" />
<ClCompile Include="SDL\src\render\software\SDL_render_sw.c" />
<ClCompile Include="SDL\src\render\software\SDL_rotate.c" />
<ClCompile Include="SDL\src\render\software\SDL_triangle.c" />
<ClCompile Include="SDL\src\SDL.c" />
<ClCompile Include="SDL\src\SDL_assert.c" />
<ClCompile Include="SDL\src\SDL_dataqueue.c" />
<ClCompile Include="SDL\src\SDL_list.c" />
<ClCompile Include="SDL\src\SDL_error.c" />
<ClCompile Include="SDL\src\SDL_hints.c" />
<ClCompile Include="SDL\src\SDL_log.c" />
<ClCompile Include="SDL\src\SDL_utils.c" />
<ClCompile Include="SDL\src\sensor\dummy\SDL_dummysensor.c" />
<ClCompile Include="SDL\src\sensor\SDL_sensor.c" />
<ClCompile Include="SDL\src\sensor\windows\SDL_windowssensor.c" />
<ClCompile Include="SDL\src\stdlib\SDL_crc16.c" />
<ClCompile Include="SDL\src\stdlib\SDL_crc32.c" />
<ClCompile Include="SDL\src\stdlib\SDL_getenv.c" />
<ClCompile Include="SDL\src\stdlib\SDL_iconv.c" />
<ClCompile Include="SDL\src\stdlib\SDL_malloc.c" />
<ClCompile Include="SDL\src\stdlib\SDL_mslibc.c" />
<ClCompile Include="SDL\src\stdlib\SDL_qsort.c" />
<ClCompile Include="SDL\src\stdlib\SDL_stdlib.c" />
<ClCompile Include="SDL\src\stdlib\SDL_string.c" />
<ClCompile Include="SDL\src\stdlib\SDL_strtokr.c" />
<ClCompile Include="SDL\src\thread\generic\SDL_syscond.c" />
<ClCompile Include="SDL\src\thread\SDL_thread.c" />
<ClCompile Include="SDL\src\thread\windows\SDL_syscond_cv.c" />
<ClCompile Include="SDL\src\thread\windows\SDL_sysmutex.c" />
<ClCompile Include="SDL\src\thread\windows\SDL_syssem.c" />
<ClCompile Include="SDL\src\thread\windows\SDL_systhread.c" />
<ClCompile Include="SDL\src\thread\windows\SDL_systls.c" />
<ClCompile Include="SDL\src\timer\SDL_timer.c" />
<ClCompile Include="SDL\src\timer\windows\SDL_systimer.c" />
<ClCompile Include="SDL\src\video\dummy\SDL_nullevents.c" />
<ClCompile Include="SDL\src\video\dummy\SDL_nullframebuffer.c" />
<ClCompile Include="SDL\src\video\dummy\SDL_nullvideo.c" />
<ClCompile Include="SDL\src\video\SDL_blit.c" />
<ClCompile Include="SDL\src\video\SDL_blit_0.c" />
<ClCompile Include="SDL\src\video\SDL_blit_1.c" />
<ClCompile Include="SDL\src\video\SDL_blit_A.c" />
<ClCompile Include="SDL\src\video\SDL_blit_auto.c" />
<ClCompile Include="SDL\src\video\SDL_blit_copy.c" />
<ClCompile Include="SDL\src\video\SDL_blit_N.c" />
<ClCompile Include="SDL\src\video\SDL_blit_slow.c" />
<ClCompile Include="SDL\src\video\SDL_bmp.c" />
<ClCompile Include="SDL\src\video\SDL_clipboard.c" />
<ClCompile Include="SDL\src\video\SDL_egl.c" />
<ClCompile Include="SDL\src\video\SDL_fillrect.c" />
<ClCompile Include="SDL\src\video\SDL_pixels.c" />
<ClCompile Include="SDL\src\video\SDL_rect.c" />
<ClCompile Include="SDL\src\video\SDL_RLEaccel.c" />
<ClCompile Include="SDL\src\video\SDL_shape.c" />
<ClCompile Include="SDL\src\video\SDL_stretch.c" />
<ClCompile Include="SDL\src\video\SDL_surface.c" />
<ClCompile Include="SDL\src\video\SDL_video.c" />
<ClCompile Include="SDL\src\video\SDL_vulkan_utils.c" />
<ClCompile Include="SDL\src\video\SDL_yuv.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsclipboard.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsevents.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsframebuffer.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowskeyboard.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsmessagebox.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsmodes.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsmouse.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsopengl.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsopengles.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsshape.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsvideo.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsvulkan.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowswindow.c" />
<ClCompile Include="SDL\src\video\yuv2rgb\yuv_rgb.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}</ProjectGuid>
</PropertyGroup>
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default_macros.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)\buildfiles\msvc\rpcs3_default.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(SolutionDir)\buildfiles\msvc\rpcs3_debug.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(SolutionDir)\buildfiles\msvc\rpcs3_release.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>SDL\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ProgramDatabase</DebugInformationFormat>
</ClCompile>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+413
View File
@@ -0,0 +1,413 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="SDL\src\SDL_guid.c" />
<ClCompile Include="SDL\src\atomic\SDL_atomic.c" />
<ClCompile Include="SDL\src\atomic\SDL_spinlock.c" />
<ClCompile Include="SDL\src\audio\directsound\SDL_directsound.c" />
<ClCompile Include="SDL\src\audio\disk\SDL_diskaudio.c" />
<ClCompile Include="SDL\src\audio\dummy\SDL_dummyaudio.c" />
<ClCompile Include="SDL\src\audio\SDL_audio.c" />
<ClCompile Include="SDL\src\audio\SDL_audiocvt.c" />
<ClCompile Include="SDL\src\audio\SDL_audiodev.c" />
<ClCompile Include="SDL\src\audio\SDL_audiotypecvt.c" />
<ClCompile Include="SDL\src\audio\SDL_mixer.c" />
<ClCompile Include="SDL\src\audio\SDL_wave.c" />
<ClCompile Include="SDL\src\audio\winmm\SDL_winmm.c" />
<ClCompile Include="SDL\src\audio\wasapi\SDL_wasapi.c" />
<ClCompile Include="SDL\src\audio\wasapi\SDL_wasapi_win32.c" />
<ClCompile Include="SDL\src\core\windows\SDL_hid.c" />
<ClCompile Include="SDL\src\core\windows\SDL_immdevice.c" />
<ClCompile Include="SDL\src\core\windows\SDL_windows.c" />
<ClCompile Include="SDL\src\core\windows\SDL_xinput.c" />
<ClCompile Include="SDL\src\cpuinfo\SDL_cpuinfo.c" />
<ClCompile Include="SDL\src\dynapi\SDL_dynapi.c" />
<ClCompile Include="SDL\src\events\SDL_clipboardevents.c" />
<ClCompile Include="SDL\src\events\SDL_displayevents.c" />
<ClCompile Include="SDL\src\events\SDL_dropevents.c" />
<ClCompile Include="SDL\src\events\SDL_events.c" />
<ClCompile Include="SDL\src\events\SDL_gesture.c" />
<ClCompile Include="SDL\src\events\SDL_keyboard.c" />
<ClCompile Include="SDL\src\events\SDL_mouse.c" />
<ClCompile Include="SDL\src\events\SDL_quit.c" />
<ClCompile Include="SDL\src\events\SDL_touch.c" />
<ClCompile Include="SDL\src\events\SDL_windowevents.c" />
<ClCompile Include="SDL\src\file\SDL_rwops.c" />
<ClCompile Include="SDL\src\filesystem\windows\SDL_sysfilesystem.c" />
<ClCompile Include="SDL\src\haptic\dummy\SDL_syshaptic.c" />
<ClCompile Include="SDL\src\haptic\SDL_haptic.c" />
<ClCompile Include="SDL\src\haptic\windows\SDL_dinputhaptic.c" />
<ClCompile Include="SDL\src\haptic\windows\SDL_windowshaptic.c" />
<ClCompile Include="SDL\src\haptic\windows\SDL_xinputhaptic.c" />
<ClCompile Include="SDL\src\hidapi\SDL_hidapi.c" />
<ClCompile Include="SDL\src\joystick\controller_type.c" />
<ClCompile Include="SDL\src\joystick\dummy\SDL_sysjoystick.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapijoystick.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_combined.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_gamecube.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_luna.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_ps4.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_ps5.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_rumble.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_shield.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_stadia.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_switch.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_xbox360.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_xbox360w.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
<ClCompile Include="SDL\src\joystick\SDL_gamecontroller.c" />
<ClCompile Include="SDL\src\joystick\SDL_joystick.c" />
<ClCompile Include="SDL\src\joystick\virtual\SDL_virtualjoystick.c" />
<ClCompile Include="SDL\src\joystick\windows\SDL_dinputjoystick.c" />
<ClCompile Include="SDL\src\joystick\windows\SDL_rawinputjoystick.c" />
<ClCompile Include="SDL\src\joystick\windows\SDL_windowsjoystick.c" />
<ClCompile Include="SDL\src\joystick\windows\SDL_windows_gaming_input.c" />
<ClCompile Include="SDL\src\joystick\windows\SDL_xinputjoystick.c" />
<ClCompile Include="SDL\src\libm\e_atan2.c" />
<ClCompile Include="SDL\src\libm\e_exp.c" />
<ClCompile Include="SDL\src\libm\e_fmod.c" />
<ClCompile Include="SDL\src\libm\e_log.c" />
<ClCompile Include="SDL\src\libm\e_log10.c" />
<ClCompile Include="SDL\src\libm\e_pow.c" />
<ClCompile Include="SDL\src\libm\e_rem_pio2.c" />
<ClCompile Include="SDL\src\libm\e_sqrt.c" />
<ClCompile Include="SDL\src\libm\k_cos.c" />
<ClCompile Include="SDL\src\libm\k_rem_pio2.c" />
<ClCompile Include="SDL\src\libm\k_sin.c" />
<ClCompile Include="SDL\src\libm\k_tan.c" />
<ClCompile Include="SDL\src\libm\s_atan.c" />
<ClCompile Include="SDL\src\libm\s_copysign.c" />
<ClCompile Include="SDL\src\libm\s_cos.c" />
<ClCompile Include="SDL\src\libm\s_fabs.c" />
<ClCompile Include="SDL\src\libm\s_floor.c" />
<ClCompile Include="SDL\src\libm\s_scalbn.c" />
<ClCompile Include="SDL\src\libm\s_sin.c" />
<ClCompile Include="SDL\src\libm\s_tan.c" />
<ClCompile Include="SDL\src\loadso\windows\SDL_sysloadso.c" />
<ClCompile Include="SDL\src\locale\SDL_locale.c" />
<ClCompile Include="SDL\src\locale\windows\SDL_syslocale.c" />
<ClCompile Include="SDL\src\misc\SDL_url.c" />
<ClCompile Include="SDL\src\misc\windows\SDL_sysurl.c" />
<ClCompile Include="SDL\src\power\SDL_power.c" />
<ClCompile Include="SDL\src\power\windows\SDL_syspower.c" />
<ClCompile Include="SDL\src\render\direct3d11\SDL_shaders_d3d11.c" />
<ClCompile Include="SDL\src\render\direct3d12\SDL_render_d3d12.c" />
<ClCompile Include="SDL\src\render\direct3d12\SDL_shaders_d3d12.c" />
<ClCompile Include="SDL\src\render\direct3d\SDL_render_d3d.c" />
<ClCompile Include="SDL\src\render\direct3d11\SDL_render_d3d11.c" />
<ClCompile Include="SDL\src\render\direct3d\SDL_shaders_d3d.c" />
<ClCompile Include="SDL\src\render\opengl\SDL_render_gl.c" />
<ClCompile Include="SDL\src\render\opengl\SDL_shaders_gl.c" />
<ClCompile Include="SDL\src\render\opengles2\SDL_render_gles2.c" />
<ClCompile Include="SDL\src\render\opengles2\SDL_shaders_gles2.c" />
<ClCompile Include="SDL\src\render\SDL_d3dmath.c" />
<ClCompile Include="SDL\src\render\SDL_render.c" />
<ClCompile Include="SDL\src\render\SDL_yuv_sw.c" />
<ClCompile Include="SDL\src\render\software\SDL_blendfillrect.c" />
<ClCompile Include="SDL\src\render\software\SDL_blendline.c" />
<ClCompile Include="SDL\src\render\software\SDL_blendpoint.c" />
<ClCompile Include="SDL\src\render\software\SDL_drawline.c" />
<ClCompile Include="SDL\src\render\software\SDL_drawpoint.c" />
<ClCompile Include="SDL\src\render\software\SDL_render_sw.c" />
<ClCompile Include="SDL\src\render\software\SDL_rotate.c" />
<ClCompile Include="SDL\src\render\software\SDL_triangle.c" />
<ClCompile Include="SDL\src\SDL.c" />
<ClCompile Include="SDL\src\SDL_assert.c" />
<ClCompile Include="SDL\src\SDL_dataqueue.c" />
<ClCompile Include="SDL\src\SDL_list.c" />
<ClCompile Include="SDL\src\SDL_error.c" />
<ClCompile Include="SDL\src\SDL_hints.c" />
<ClCompile Include="SDL\src\SDL_log.c" />
<ClCompile Include="SDL\src\SDL_utils.c" />
<ClCompile Include="SDL\src\sensor\dummy\SDL_dummysensor.c" />
<ClCompile Include="SDL\src\sensor\SDL_sensor.c" />
<ClCompile Include="SDL\src\sensor\windows\SDL_windowssensor.c" />
<ClCompile Include="SDL\src\stdlib\SDL_crc16.c" />
<ClCompile Include="SDL\src\stdlib\SDL_crc32.c" />
<ClCompile Include="SDL\src\stdlib\SDL_getenv.c" />
<ClCompile Include="SDL\src\stdlib\SDL_iconv.c" />
<ClCompile Include="SDL\src\stdlib\SDL_malloc.c" />
<ClCompile Include="SDL\src\stdlib\SDL_mslibc.c" />
<ClCompile Include="SDL\src\stdlib\SDL_qsort.c" />
<ClCompile Include="SDL\src\stdlib\SDL_stdlib.c" />
<ClCompile Include="SDL\src\stdlib\SDL_string.c" />
<ClCompile Include="SDL\src\stdlib\SDL_strtokr.c" />
<ClCompile Include="SDL\src\thread\generic\SDL_syscond.c" />
<ClCompile Include="SDL\src\thread\SDL_thread.c" />
<ClCompile Include="SDL\src\thread\windows\SDL_syscond_cv.c" />
<ClCompile Include="SDL\src\thread\windows\SDL_sysmutex.c" />
<ClCompile Include="SDL\src\thread\windows\SDL_syssem.c" />
<ClCompile Include="SDL\src\thread\windows\SDL_systhread.c" />
<ClCompile Include="SDL\src\thread\windows\SDL_systls.c" />
<ClCompile Include="SDL\src\timer\SDL_timer.c" />
<ClCompile Include="SDL\src\timer\windows\SDL_systimer.c" />
<ClCompile Include="SDL\src\video\dummy\SDL_nullevents.c" />
<ClCompile Include="SDL\src\video\dummy\SDL_nullframebuffer.c" />
<ClCompile Include="SDL\src\video\dummy\SDL_nullvideo.c" />
<ClCompile Include="SDL\src\video\SDL_blit.c" />
<ClCompile Include="SDL\src\video\SDL_blit_0.c" />
<ClCompile Include="SDL\src\video\SDL_blit_1.c" />
<ClCompile Include="SDL\src\video\SDL_blit_A.c" />
<ClCompile Include="SDL\src\video\SDL_blit_auto.c" />
<ClCompile Include="SDL\src\video\SDL_blit_copy.c" />
<ClCompile Include="SDL\src\video\SDL_blit_N.c" />
<ClCompile Include="SDL\src\video\SDL_blit_slow.c" />
<ClCompile Include="SDL\src\video\SDL_bmp.c" />
<ClCompile Include="SDL\src\video\SDL_clipboard.c" />
<ClCompile Include="SDL\src\video\SDL_egl.c" />
<ClCompile Include="SDL\src\video\SDL_fillrect.c" />
<ClCompile Include="SDL\src\video\SDL_pixels.c" />
<ClCompile Include="SDL\src\video\SDL_rect.c" />
<ClCompile Include="SDL\src\video\SDL_RLEaccel.c" />
<ClCompile Include="SDL\src\video\SDL_shape.c" />
<ClCompile Include="SDL\src\video\SDL_stretch.c" />
<ClCompile Include="SDL\src\video\SDL_surface.c" />
<ClCompile Include="SDL\src\video\SDL_video.c" />
<ClCompile Include="SDL\src\video\SDL_vulkan_utils.c" />
<ClCompile Include="SDL\src\video\SDL_yuv.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsclipboard.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsevents.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsframebuffer.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowskeyboard.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsmessagebox.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsmodes.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsmouse.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsopengl.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsopengles.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsshape.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsvideo.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsvulkan.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowswindow.c" />
<ClCompile Include="SDL\src\video\yuv2rgb\yuv_rgb.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_ps3.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_steam.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_wii.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="SDL\include\begin_code.h" />
<ClInclude Include="SDL\include\close_code.h" />
<ClInclude Include="SDL\include\SDL.h" />
<ClInclude Include="SDL\include\SDL_assert.h" />
<ClInclude Include="SDL\include\SDL_atomic.h" />
<ClInclude Include="SDL\include\SDL_audio.h" />
<ClInclude Include="SDL\include\SDL_bits.h" />
<ClInclude Include="SDL\include\SDL_blendmode.h" />
<ClInclude Include="SDL\include\SDL_clipboard.h" />
<ClInclude Include="SDL\include\SDL_config.h" />
<ClInclude Include="SDL\include\SDL_config_windows.h" />
<ClInclude Include="SDL\include\SDL_copying.h" />
<ClInclude Include="SDL\include\SDL_cpuinfo.h" />
<ClInclude Include="SDL\include\SDL_egl.h" />
<ClInclude Include="SDL\include\SDL_endian.h" />
<ClInclude Include="SDL\include\SDL_error.h" />
<ClInclude Include="SDL\include\SDL_events.h" />
<ClInclude Include="SDL\include\SDL_filesystem.h" />
<ClInclude Include="SDL\include\SDL_gamecontroller.h" />
<ClInclude Include="SDL\include\SDL_gesture.h" />
<ClInclude Include="SDL\include\SDL_guid.h" />
<ClInclude Include="SDL\include\SDL_haptic.h" />
<ClInclude Include="SDL\include\SDL_hints.h" />
<ClInclude Include="SDL\include\SDL_hidapi.h" />
<ClInclude Include="SDL\include\SDL_joystick.h" />
<ClInclude Include="SDL\include\SDL_keyboard.h" />
<ClInclude Include="SDL\include\SDL_keycode.h" />
<ClInclude Include="SDL\include\SDL_loadso.h" />
<ClInclude Include="SDL\include\SDL_locale.h" />
<ClInclude Include="SDL\include\SDL_log.h" />
<ClInclude Include="SDL\include\SDL_main.h" />
<ClInclude Include="SDL\include\SDL_messagebox.h" />
<ClInclude Include="SDL\include\SDL_metal.h" />
<ClInclude Include="SDL\include\SDL_misc.h" />
<ClInclude Include="SDL\include\SDL_mouse.h" />
<ClInclude Include="SDL\include\SDL_mutex.h" />
<ClInclude Include="SDL\include\SDL_name.h" />
<ClInclude Include="SDL\include\SDL_opengl.h" />
<ClInclude Include="SDL\include\SDL_opengl_glext.h" />
<ClInclude Include="SDL\include\SDL_opengles.h" />
<ClInclude Include="SDL\include\SDL_opengles2.h" />
<ClInclude Include="SDL\include\SDL_opengles2_gl2.h" />
<ClInclude Include="SDL\include\SDL_opengles2_gl2ext.h" />
<ClInclude Include="SDL\include\SDL_opengles2_gl2platform.h" />
<ClInclude Include="SDL\include\SDL_opengles2_khrplatform.h" />
<ClInclude Include="SDL\include\SDL_pixels.h" />
<ClInclude Include="SDL\include\SDL_platform.h" />
<ClInclude Include="SDL\include\SDL_power.h" />
<ClInclude Include="SDL\include\SDL_quit.h" />
<ClInclude Include="SDL\include\SDL_rect.h" />
<ClInclude Include="SDL\include\SDL_render.h" />
<ClInclude Include="SDL\include\SDL_revision.h" />
<ClInclude Include="SDL\include\SDL_rwops.h" />
<ClInclude Include="SDL\include\SDL_scancode.h" />
<ClInclude Include="SDL\include\SDL_sensor.h" />
<ClInclude Include="SDL\include\SDL_shape.h" />
<ClInclude Include="SDL\include\SDL_stdinc.h" />
<ClInclude Include="SDL\include\SDL_surface.h" />
<ClInclude Include="SDL\include\SDL_system.h" />
<ClInclude Include="SDL\include\SDL_syswm.h" />
<ClInclude Include="SDL\include\SDL_test.h" />
<ClInclude Include="SDL\include\SDL_test_assert.h" />
<ClInclude Include="SDL\include\SDL_test_common.h" />
<ClInclude Include="SDL\include\SDL_test_compare.h" />
<ClInclude Include="SDL\include\SDL_test_crc32.h" />
<ClInclude Include="SDL\include\SDL_test_font.h" />
<ClInclude Include="SDL\include\SDL_test_fuzzer.h" />
<ClInclude Include="SDL\include\SDL_test_harness.h" />
<ClInclude Include="SDL\include\SDL_test_images.h" />
<ClInclude Include="SDL\include\SDL_test_log.h" />
<ClInclude Include="SDL\include\SDL_test_md5.h" />
<ClInclude Include="SDL\include\SDL_test_memory.h" />
<ClInclude Include="SDL\include\SDL_test_random.h" />
<ClInclude Include="SDL\include\SDL_thread.h" />
<ClInclude Include="SDL\include\SDL_timer.h" />
<ClInclude Include="SDL\include\SDL_touch.h" />
<ClInclude Include="SDL\include\SDL_types.h" />
<ClInclude Include="SDL\include\SDL_version.h" />
<ClInclude Include="SDL\include\SDL_video.h" />
<ClInclude Include="SDL\include\SDL_vulkan.h" />
<ClInclude Include="SDL\src\audio\directsound\SDL_directsound.h" />
<ClInclude Include="SDL\src\audio\disk\SDL_diskaudio.h" />
<ClInclude Include="SDL\src\audio\dummy\SDL_dummyaudio.h" />
<ClInclude Include="SDL\src\audio\SDL_audio_c.h" />
<ClInclude Include="SDL\src\audio\SDL_audiodev_c.h" />
<ClInclude Include="SDL\src\audio\SDL_sysaudio.h" />
<ClInclude Include="SDL\src\audio\SDL_wave.h" />
<ClInclude Include="SDL\src\audio\wasapi\SDL_wasapi.h" />
<ClInclude Include="SDL\src\audio\winmm\SDL_winmm.h" />
<ClInclude Include="SDL\src\core\windows\SDL_directx.h" />
<ClInclude Include="SDL\src\core\windows\SDL_hid.h" />
<ClInclude Include="SDL\src\core\windows\SDL_immdevice.h" />
<ClInclude Include="SDL\src\core\windows\SDL_windows.h" />
<ClInclude Include="SDL\src\core\windows\SDL_xinput.h" />
<ClInclude Include="SDL\src\dynapi\SDL_dynapi.h" />
<ClInclude Include="SDL\src\dynapi\SDL_dynapi_overrides.h" />
<ClInclude Include="SDL\src\dynapi\SDL_dynapi_procs.h" />
<ClInclude Include="SDL\src\events\blank_cursor.h" />
<ClInclude Include="SDL\src\events\default_cursor.h" />
<ClInclude Include="SDL\src\events\scancodes_windows.h" />
<ClInclude Include="SDL\src\events\SDL_clipboardevents_c.h" />
<ClInclude Include="SDL\src\events\SDL_displayevents_c.h" />
<ClInclude Include="SDL\src\events\SDL_dropevents_c.h" />
<ClInclude Include="SDL\src\events\SDL_events_c.h" />
<ClInclude Include="SDL\src\events\SDL_gesture_c.h" />
<ClInclude Include="SDL\src\events\SDL_keyboard_c.h" />
<ClInclude Include="SDL\src\events\SDL_mouse_c.h" />
<ClInclude Include="SDL\src\events\SDL_touch_c.h" />
<ClInclude Include="SDL\src\events\SDL_windowevents_c.h" />
<ClInclude Include="SDL\src\haptic\SDL_haptic_c.h" />
<ClInclude Include="SDL\src\haptic\SDL_syshaptic.h" />
<ClInclude Include="SDL\src\haptic\windows\SDL_dinputhaptic_c.h" />
<ClInclude Include="SDL\src\haptic\windows\SDL_windowshaptic_c.h" />
<ClInclude Include="SDL\src\haptic\windows\SDL_xinputhaptic_c.h" />
<ClInclude Include="SDL\src\hidapi\hidapi\hidapi.h" />
<ClInclude Include="SDL\src\hidapi\SDL_hidapi_c.h" />
<ClInclude Include="SDL\src\joystick\controller_type.h" />
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapijoystick_c.h" />
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_rumble.h" />
<ClInclude Include="SDL\src\joystick\SDL_gamecontrollerdb.h" />
<ClInclude Include="SDL\src\joystick\SDL_joystick_c.h" />
<ClInclude Include="SDL\src\joystick\SDL_sysjoystick.h" />
<ClInclude Include="SDL\src\joystick\usb_ids.h" />
<ClInclude Include="SDL\src\joystick\virtual\SDL_virtualjoystick_c.h" />
<ClInclude Include="SDL\src\joystick\windows\SDL_dinputjoystick_c.h" />
<ClInclude Include="SDL\src\joystick\windows\SDL_rawinputjoystick_c.h" />
<ClInclude Include="SDL\src\joystick\windows\SDL_windowsjoystick_c.h" />
<ClInclude Include="SDL\src\joystick\windows\SDL_xinputjoystick_c.h" />
<ClInclude Include="SDL\src\libm\math_libm.h" />
<ClInclude Include="SDL\src\libm\math_private.h" />
<ClInclude Include="SDL\src\locale\SDL_syslocale.h" />
<ClInclude Include="SDL\src\misc\SDL_sysurl.h" />
<ClInclude Include="SDL\src\power\SDL_syspower.h" />
<ClInclude Include="SDL\src\render\direct3d11\SDL_shaders_d3d11.h" />
<ClInclude Include="SDL\src\render\direct3d12\SDL_shaders_d3d12.h" />
<ClInclude Include="SDL\src\render\direct3d\SDL_shaders_d3d.h" />
<ClInclude Include="SDL\src\render\opengles2\SDL_gles2funcs.h" />
<ClInclude Include="SDL\src\render\opengles2\SDL_shaders_gles2.h" />
<ClInclude Include="SDL\src\render\opengl\SDL_glfuncs.h" />
<ClInclude Include="SDL\src\render\opengl\SDL_shaders_gl.h" />
<ClInclude Include="SDL\src\render\SDL_d3dmath.h" />
<ClInclude Include="SDL\src\render\SDL_sysrender.h" />
<ClInclude Include="SDL\src\render\SDL_yuv_sw_c.h" />
<ClInclude Include="SDL\src\render\software\SDL_blendfillrect.h" />
<ClInclude Include="SDL\src\render\software\SDL_blendline.h" />
<ClInclude Include="SDL\src\render\software\SDL_blendpoint.h" />
<ClInclude Include="SDL\src\render\software\SDL_draw.h" />
<ClInclude Include="SDL\src\render\software\SDL_drawline.h" />
<ClInclude Include="SDL\src\render\software\SDL_drawpoint.h" />
<ClInclude Include="SDL\src\render\software\SDL_render_sw_c.h" />
<ClInclude Include="SDL\src\render\software\SDL_rotate.h" />
<ClInclude Include="SDL\src\render\software\SDL_triangle.h" />
<ClInclude Include="SDL\src\SDL_assert_c.h" />
<ClInclude Include="SDL\src\SDL_dataqueue.h" />
<ClInclude Include="SDL\src\SDL_error_c.h" />
<ClInclude Include="SDL\src\SDL_hints_c.h" />
<ClInclude Include="SDL\src\SDL_internal.h" />
<ClInclude Include="SDL\src\SDL_list.h" />
<ClInclude Include="SDL\src\SDL_log_c.h" />
<ClInclude Include="SDL\src\sensor\dummy\SDL_dummysensor.h" />
<ClInclude Include="SDL\src\sensor\SDL_sensor_c.h" />
<ClInclude Include="SDL\src\sensor\SDL_syssensor.h" />
<ClInclude Include="SDL\src\sensor\windows\SDL_windowssensor.h" />
<ClInclude Include="SDL\src\thread\SDL_systhread.h" />
<ClInclude Include="SDL\src\thread\SDL_thread_c.h" />
<ClInclude Include="SDL\src\thread\generic\SDL_syscond_c.h" />
<ClInclude Include="SDL\src\thread\windows\SDL_sysmutex_c.h" />
<ClInclude Include="SDL\src\thread\windows\SDL_systhread_c.h" />
<ClInclude Include="SDL\src\timer\SDL_timer_c.h" />
<ClInclude Include="SDL\src\video\dummy\SDL_nullevents_c.h" />
<ClInclude Include="SDL\src\video\dummy\SDL_nullframebuffer_c.h" />
<ClInclude Include="SDL\src\video\dummy\SDL_nullvideo.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_icd.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_layer.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_platform.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_sdk_platform.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan.hpp" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_android.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_beta.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_core.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_directfb.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_fuchsia.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_ggp.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_ios.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_macos.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_metal.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_vi.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_wayland.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_win32.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xcb.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xlib.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xlib_xrandr.h" />
<ClInclude Include="SDL\src\video\SDL_blit.h" />
<ClInclude Include="SDL\src\video\SDL_blit_auto.h" />
<ClInclude Include="SDL\src\video\SDL_blit_copy.h" />
<ClInclude Include="SDL\src\video\SDL_blit_slow.h" />
<ClInclude Include="SDL\src\video\SDL_egl_c.h" />
<ClInclude Include="SDL\src\video\SDL_pixels_c.h" />
<ClInclude Include="SDL\src\video\SDL_rect_c.h" />
<ClInclude Include="SDL\src\video\SDL_RLEaccel_c.h" />
<ClInclude Include="SDL\src\video\SDL_shape_internals.h" />
<ClInclude Include="SDL\src\video\SDL_sysvideo.h" />
<ClInclude Include="SDL\src\video\SDL_vulkan_internal.h" />
<ClInclude Include="SDL\src\video\SDL_yuv_c.h" />
<ClInclude Include="SDL\src\video\windows\SDL_msctf.h" />
<ClInclude Include="SDL\src\video\windows\SDL_vkeys.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsclipboard.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsevents.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsframebuffer.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowskeyboard.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsmessagebox.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsmodes.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsmouse.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsopengl.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsopengles.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsshape.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsvideo.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsvulkan.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowswindow.h" />
<ClInclude Include="SDL\src\video\windows\wmmsg.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_sse_func.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_std_func.h" />
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_nintendo.h" />
</ItemGroup>
</Project>
+8
View File
@@ -0,0 +1,8 @@
option (UPNPC_BUILD_STATIC "Build static library" TRUE)
option (UPNPC_BUILD_SHARED "Build shared library" FALSE)
option (UPNPC_BUILD_TESTS "Build test executables" FALSE)
option (UPNPC_BUILD_SAMPLE "Build sample executables" FALSE)
option (NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE)
option (UPNPC_NO_INSTALL "Disable installation" TRUE)
add_subdirectory(miniupnp/miniupnpc EXCLUDE_FROM_ALL)
Vendored Submodule
+1
+138
View File
@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{5228f863-e0dd-4de7-aa7b-5c52b14cd4d0}</ProjectGuid>
<RootNamespace>miniupnpcstatic</RootNamespace>
</PropertyGroup>
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default_macros.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINSOCK_DEPRECATED_NO_WARNINGS; _CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>generated;miniupnp\miniupnpc;miniupnp\miniupnpc\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
<PreBuildEvent>
<Command>cd $(ProjectDir)miniupnp\miniupnpc\msvc
cscript genminiupnpcstrings.vbs</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINSOCK_DEPRECATED_NO_WARNINGS; _CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>generated;miniupnp\miniupnpc;miniupnp\miniupnpc\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>
</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PreBuildEvent>
<Command>cd $(ProjectDir)miniupnp\miniupnpc\msvc
cscript genminiupnpcstrings.vbs</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="miniupnp\miniupnpc\src\addr_is_reserved.c" />
<ClCompile Include="miniupnp\miniupnpc\src\connecthostport.c" />
<ClCompile Include="miniupnp\miniupnpc\src\igd_desc_parse.c" />
<ClCompile Include="miniupnp\miniupnpc\src\minisoap.c" />
<ClCompile Include="miniupnp\miniupnpc\src\minissdpc.c" />
<ClCompile Include="miniupnp\miniupnpc\src\miniupnpc.c" />
<ClCompile Include="miniupnp\miniupnpc\src\miniwget.c" />
<ClCompile Include="miniupnp\miniupnpc\src\minixml.c" />
<ClCompile Include="miniupnp\miniupnpc\src\portlistingparse.c" />
<ClCompile Include="miniupnp\miniupnpc\src\receivedata.c" />
<ClCompile Include="miniupnp\miniupnpc\src\upnpcommands.c" />
<ClCompile Include="miniupnp\miniupnpc\src\upnpdev.c" />
<ClCompile Include="miniupnp\miniupnpc\src\upnperrors.c" />
<ClCompile Include="miniupnp\miniupnpc\src\upnpreplyparse.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="miniupnp\miniupnpc\src\addr_is_reserved.h" />
<ClInclude Include="miniupnp\miniupnpc\src\connecthostport.h" />
<ClInclude Include="miniupnp\miniupnpc\include\igd_desc_parse.h" />
<ClInclude Include="miniupnp\miniupnpc\src\minisoap.h" />
<ClInclude Include="miniupnp\miniupnpc\src\minissdpc.h" />
<ClInclude Include="miniupnp\miniupnpc\include\miniupnpc.h" />
<ClInclude Include="miniupnp\miniupnpc\miniupnpcstrings.h" />
<ClInclude Include="miniupnp\miniupnpc\include\miniupnpctypes.h" />
<ClInclude Include="miniupnp\miniupnpc\include\miniupnpc_declspec.h" />
<ClInclude Include="miniupnp\miniupnpc\include\miniwget.h" />
<ClInclude Include="miniupnp\miniupnpc\src\miniwget_private.h" />
<ClInclude Include="miniupnp\miniupnpc\src\minixml.h" />
<ClInclude Include="miniupnp\miniupnpc\include\portlistingparse.h" />
<ClInclude Include="miniupnp\miniupnpc\src\receivedata.h" />
<ClInclude Include="miniupnp\miniupnpc\include\upnpcommands.h" />
<ClInclude Include="miniupnp\miniupnpc\include\upnpdev.h" />
<ClInclude Include="miniupnp\miniupnpc\include\upnperrors.h" />
<ClInclude Include="miniupnp\miniupnpc\include\upnpreplyparse.h" />
<ClInclude Include="miniupnp\miniupnpc\src\win32_snprintf.h" />
<ClInclude Include="miniupnp\miniupnpc\rc_version.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+94 -100
View File
@@ -24,6 +24,7 @@
#define close_portable(a) (close(a))
#include <sys/socket.h>
#include <sys/un.h>
#include <poll.h>
#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
#include <unistd.h>
#endif
@@ -79,13 +80,13 @@ namespace pine
* A preallocated buffer used to store all IPC replies.
* to the size of 50.000 MsgWrite64 IPC calls.
*/
char* m_ret_buffer;
std::vector<char> m_ret_buffer;
/**
* IPC messages buffer.
* A preallocated buffer used to store all IPC messages.
*/
char* m_ipc_buffer;
std::vector<char> m_ipc_buffer;
/**
* IPC Command messages opcodes.
@@ -118,8 +119,8 @@ namespace pine
*/
struct IPCBuffer
{
int size; /**< Size of the buffer. */
char* buffer; /**< Buffer. */
usz size{}; /**< Size of the buffer. */
char* buffer{}; /**< Buffer. */
};
/**
@@ -144,13 +145,30 @@ namespace pine
*/
IPCBuffer ParseCommand(char* buf, char* ret_buffer, u32 buf_size)
{
u32 ret_cnt = 5;
u32 buf_cnt = 0;
usz ret_cnt = 5;
usz buf_cnt = 0;
const auto error = [&]()
{
return IPCBuffer{ 5, MakeFailIPC(ret_buffer) };
};
const auto write_string = [&](const std::string& str)
{
if (!SafetyChecks(buf_cnt, 0, ret_cnt, str.size() + 1 + sizeof(u32), buf_size))
return false;
ToArray(ret_buffer, ::narrow<u32>(str.size() + 1), ret_cnt);
ret_cnt += sizeof(u32);
memcpy(&ret_buffer[ret_cnt], str.data(), str.size());
ret_cnt += str.size();
ret_buffer[ret_cnt++] = '\0';
return true;
};
while (buf_cnt < buf_size)
{
if (!SafetyChecks(buf_cnt, 1, ret_cnt, 0, buf_size))
return IPCBuffer{ 5, MakeFailIPC(ret_buffer) };
return error();
buf_cnt++;
// example IPC messages: MsgRead/Write
// refer to the client doc for more info on the format
@@ -169,10 +187,10 @@ namespace pine
case MsgRead8:
{
if (!SafetyChecks(buf_cnt, 4, ret_cnt, 1, buf_size))
goto error;
return error();
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
if (!Impl::template check_addr(a))
goto error;
return error();
const u8 res = Impl::read8(a);
ToArray(ret_buffer, res, ret_cnt);
ret_cnt += 1;
@@ -182,10 +200,10 @@ namespace pine
case MsgRead16:
{
if (!SafetyChecks(buf_cnt, 4, ret_cnt, 2, buf_size))
goto error;
return error();
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
if (!Impl::template check_addr<2>(a))
goto error;
return error();
const u16 res = Impl::read16(a);
ToArray(ret_buffer, res, ret_cnt);
ret_cnt += 2;
@@ -195,10 +213,10 @@ namespace pine
case MsgRead32:
{
if (!SafetyChecks(buf_cnt, 4, ret_cnt, 4, buf_size))
goto error;
return error();
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
if (!Impl::template check_addr<4>(a))
goto error;
return error();
const u32 res = Impl::read32(a);
ToArray(ret_buffer, res, ret_cnt);
ret_cnt += 4;
@@ -208,10 +226,10 @@ namespace pine
case MsgRead64:
{
if (!SafetyChecks(buf_cnt, 4, ret_cnt, 8, buf_size))
goto error;
return error();
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
if (!Impl::template check_addr<8>(a))
goto error;
return error();
u64 res = Impl::read64(a);
ToArray(ret_buffer, res, ret_cnt);
ret_cnt += 8;
@@ -221,10 +239,10 @@ namespace pine
case MsgWrite8:
{
if (!SafetyChecks(buf_cnt, 1 + 4, ret_cnt, 0, buf_size))
goto error;
return error();
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
if (!Impl::template check_addr(a, vm::page_writable))
goto error;
return error();
Impl::write8(a, FromArray<u8>(&buf[buf_cnt], 4));
buf_cnt += 5;
break;
@@ -232,10 +250,10 @@ namespace pine
case MsgWrite16:
{
if (!SafetyChecks(buf_cnt, 2 + 4, ret_cnt, 0, buf_size))
goto error;
return error();
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
if (!Impl::template check_addr<2>(a, vm::page_writable))
goto error;
return error();
Impl::write16(a, FromArray<u16>(&buf[buf_cnt], 4));
buf_cnt += 6;
break;
@@ -243,10 +261,10 @@ namespace pine
case MsgWrite32:
{
if (!SafetyChecks(buf_cnt, 4 + 4, ret_cnt, 0, buf_size))
goto error;
return error();
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
if (!Impl::template check_addr<4>(a, vm::page_writable))
goto error;
return error();
Impl::write32(a, FromArray<u32>(&buf[buf_cnt], 4));
buf_cnt += 8;
break;
@@ -254,31 +272,24 @@ namespace pine
case MsgWrite64:
{
if (!SafetyChecks(buf_cnt, 8 + 4, ret_cnt, 0, buf_size))
goto error;
return error();
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
if (!Impl::template check_addr<8>(a, vm::page_writable))
goto error;
return error();
Impl::write64(a, FromArray<u64>(&buf[buf_cnt], 4));
buf_cnt += 12;
break;
}
case MsgVersion:
{
char version[256] = {};
snprintf(version, sizeof(version), "RPCS3 %s", Impl::get_version_and_branch().c_str());
const u32 size = strlen(version) + 1;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
goto error;
ToArray(ret_buffer, size, ret_cnt);
ret_cnt += 4;
memcpy(&ret_buffer[ret_cnt], version, size);
ret_cnt += size;
if (!write_string("RPCS3 " + Impl::get_version_and_branch()))
return error();
break;
}
case MsgStatus:
{
if (!SafetyChecks(buf_cnt, 0, ret_cnt, 4, buf_size))
goto error;
return error();
EmuStatus status = Impl::get_status();
ToArray(ret_buffer, status, ret_cnt);
ret_cnt += 4;
@@ -287,72 +298,35 @@ namespace pine
}
case MsgTitle:
{
const auto title_string = Impl::get_title();
const auto size = title_string.size() + 1;
char* title = new char[size];
snprintf(title, size, "%s", title_string.c_str());
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
goto error;
ToArray(ret_buffer, size, ret_cnt);
ret_cnt += 4;
memcpy(&ret_buffer[ret_cnt], title, size);
ret_cnt += size;
delete[] title;
if (!write_string(Impl::get_title()))
return error();
break;
}
case MsgID:
{
const auto title_id_string = Impl::get_title_ID();
const auto size = title_id_string.size() + 1;
char* title_id = new char[size];
snprintf(title_id, size, "%s", title_id_string.c_str());
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
goto error;
ToArray(ret_buffer, size, ret_cnt);
ret_cnt += 4;
memcpy(&ret_buffer[ret_cnt], title_id, size);
ret_cnt += size;
delete[] title_id;
if (!write_string(Impl::get_title_ID()))
return error();
break;
}
case MsgUUID:
{
const auto hash_string = Impl::get_executable_hash();
const auto size = hash_string.size() + 1;
char* hash = new char[size];
snprintf(hash, size, "%s", hash_string.c_str());
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
goto error;
ToArray(ret_buffer, size, ret_cnt);
ret_cnt += 4;
memcpy(&ret_buffer[ret_cnt], hash, size);
ret_cnt += size;
delete[] hash;
if (!write_string(Impl::get_executable_hash()))
return error();
break;
}
case MsgGameVersion:
{
const auto game_version_string = Impl::get_app_version();
const auto size = game_version_string.size() + 1;
char* game_version = new char[size];
snprintf(game_version, size, "%s", game_version_string.c_str());
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size, buf_size))
goto error;
ToArray(ret_buffer, size, ret_cnt);
ret_cnt += 4;
memcpy(&ret_buffer[ret_cnt], game_version, size);
ret_cnt += size;
delete[] game_version;
if (!write_string(Impl::get_app_version()))
return error();
break;
}
default:
{
error:
return IPCBuffer{ 5, MakeFailIPC(ret_buffer) };
return error();
}
}
}
return IPCBuffer{ static_cast<int>(ret_cnt), MakeOkIPC(ret_buffer, ret_cnt) };
return IPCBuffer{ ret_cnt, MakeOkIPC(ret_buffer, ret_cnt) };
}
/**
@@ -361,26 +335,48 @@ namespace pine
* size: size of the IPC buffer.
* return value: buffer containing the status code allocated of size
*/
static inline char* MakeOkIPC(char* ret_buffer, uint32_t size = 5)
static inline char* MakeOkIPC(char* ret_buffer, usz size = 5)
{
ToArray<uint32_t>(ret_buffer, size, 0);
ToArray(ret_buffer, ::narrow<u32>(size), 0);
ret_buffer[4] = IPC_OK;
return ret_buffer;
}
static inline char* MakeFailIPC(char* ret_buffer, uint32_t size = 5)
static inline char* MakeFailIPC(char* ret_buffer, usz size = 5)
{
ToArray<uint32_t>(ret_buffer, size, 0);
ToArray(ret_buffer, ::narrow<u32>(size), 0);
ret_buffer[4] = IPC_FAIL;
return ret_buffer;
}
/**
* Initializes an open socket for IPC communication.
* return value: -1 if a fatal failure happened, 0 otherwise.
* return value: false if a fatal failure happened, true otherwise.
*/
int StartSocket()
bool StartSocket()
{
::pollfd poll_fd{};
for (int pending_connection = 0; pending_connection != 1;)
{
if (thread_ctrl::state() == thread_state::aborting)
{
return false;
}
std::memset(&poll_fd, 0, sizeof(poll_fd));
poll_fd.events = POLLIN;
poll_fd.revents = 0;
poll_fd.fd = m_sock;
#ifdef _WIN32
// Try to wait for an incoming connection
pending_connection = ::WSAPoll(&poll_fd, 1, 10);
#else
pending_connection = ::poll(&poll_fd, 1, 10);
#endif
}
m_msgsock = accept(m_sock, 0, 0);
if (m_msgsock == -1)
@@ -398,10 +394,10 @@ namespace pine
{
#endif
Impl::error("IPC: An unrecoverable error happened! Shutting down...");
return -1;
return false;
}
}
return 0;
return true;
}
// Thread used to relay IPC commands.
@@ -409,10 +405,10 @@ namespace pine
{
// we allocate once buffers to not have to do mallocs for each IPC
// request, as malloc is expansive when we optimize for µs.
m_ret_buffer = new char[MAX_IPC_RETURN_SIZE];
m_ipc_buffer = new char[MAX_IPC_SIZE];
m_ret_buffer.resize(MAX_IPC_RETURN_SIZE);
m_ipc_buffer.resize(MAX_IPC_SIZE);
if (StartSocket() < 0)
if (!StartSocket())
return;
while (thread_ctrl::state() != thread_state::aborting)
@@ -432,7 +428,7 @@ namespace pine
if (tmp_length <= 0)
{
receive_length = 0;
if (StartSocket() < 0)
if (!StartSocket())
return;
break;
}
@@ -442,7 +438,7 @@ namespace pine
// if we got at least the final size then update
if (end_length == 4 && receive_length >= 4)
{
end_length = FromArray<u32>(m_ipc_buffer, 0);
end_length = FromArray<u32>(m_ipc_buffer.data(), 0);
// we'd like to avoid a client trying to do OOB
if (end_length > MAX_IPC_SIZE || end_length < 4)
{
@@ -459,12 +455,12 @@ namespace pine
// disconnects
if (receive_length != 0)
{
pine_server::IPCBuffer res = ParseCommand(&m_ipc_buffer[4], m_ret_buffer, static_cast<u32>(end_length) - 4);
pine_server::IPCBuffer res = ParseCommand(&m_ipc_buffer[4], m_ret_buffer.data(), static_cast<u32>(end_length) - 4);
// if we cannot send back our answer restart the socket
if (write_portable(m_msgsock, res.buffer, res.size) < 0)
{
if (StartSocket() < 0)
if (!StartSocket())
return;
}
}
@@ -480,9 +476,9 @@ namespace pine
* NB: implicitely inlined
*/
template <typename T>
static char* ToArray(char* res_array, T res, int i)
static char* ToArray(char* res_array, T res, usz i)
{
memcpy((res_array + i), reinterpret_cast<char*>(&res), sizeof(T));
memcpy(res_array + i, reinterpret_cast<char*>(&res), sizeof(T));
return res_array;
}
@@ -503,7 +499,7 @@ namespace pine
* Ensures an IPC message isn't too big.
* return value: false if checks failed, true otherwise.
*/
static inline bool SafetyChecks(u32 command_len, int command_size, u32 reply_len, int reply_size = 0, u32 buf_size = MAX_IPC_SIZE - 1)
static inline bool SafetyChecks(usz command_len, usz command_size, usz reply_len, usz reply_size = 0, usz buf_size = MAX_IPC_SIZE - 1)
{
bool res = ((command_len + command_size) > buf_size ||
(reply_len + reply_size) >= MAX_IPC_RETURN_SIZE);
@@ -609,8 +605,6 @@ namespace pine
~pine_server()
{
Cleanup();
delete[] m_ret_buffer;
delete[] m_ipc_buffer;
}
}; // class pine_server
+3 -3
View File
@@ -11,7 +11,7 @@ Other instructions may be found [here](https://wiki.rpcs3.net/index.php?title=Bu
* [Python 3.6+](https://www.python.org/downloads/) (add to PATH)
* [Qt 5.15.2](https://www.qt.io/download-qt-installer)
* [Visual Studio 2019](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community)
* [Vulkan SDK 1.2.198+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html))
* [Vulkan SDK 1.3.224+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html))
**Either add the** `QTDIR` **environment variable, e.g.** `<QtInstallFolder>\5.15.2\msvc2019_64\` **, or use the [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2019)**
@@ -22,8 +22,8 @@ These are the essentials tools to build RPCS3 on Linux. Some of them can be inst
* Clang 12+ or GCC 11+
* [CMake 3.16.9+](https://www.cmake.org/download/)
* [Qt 5.15.2](https://www.qt.io/download-qt-installer)
* [Vulkan SDK 1.2.198+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html))
* [SDL2](https://www.libsdl.org/download-2.0.php) (for the FAudio backend)
* [Vulkan SDK 1.3.224+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html))
* [SDL2](https://github.com/libsdl-org/SDL/releases) (for the FAudio backend)
**If you have an NVIDIA GPU, you may need to install the libglvnd package.**
+2
View File
@@ -21,6 +21,8 @@ option(USE_DISCORD_RPC "Discord rich presence integration" OFF)
option(USE_SYSTEM_ZLIB "Prefer system ZLIB instead of the builtin one" ON)
option(USE_VULKAN "Vulkan render backend" ON)
option(USE_PRECOMPILED_HEADERS "Use precompiled headers" OFF)
option(USE_SDL "Enables SDL input handler" OFF)
option(USE_SYSTEM_SDL "Prefer system SDL instead of the builtin one" OFF)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/buildfiles/cmake")
+2 -3
View File
@@ -1,9 +1,8 @@
RPCS3
=====
[![Azure Build Status](https://dev.azure.com/nekotekina/nekotekina/_apis/build/status/RPCS3.rpcs3?branchName=master)](https://dev.azure.com/nekotekina/nekotekina/_build?definitionId=4&branchName=master)
[![Cirrus CI - Base Branch Build Status](https://img.shields.io/cirrus/github/RPCS3/rpcs3?label=Cirrus%20CI%20(FreeBSD)&logo=cirrus-ci)](https://cirrus-ci.com/github/RPCS3/rpcs3)
[![RPCS3 discord server](https://img.shields.io/discord/272035812277878785?color=5865F2&label=RPCS3%20Discord&logo=discord&logoColor=white)](https://discord.me/rpcs3)
[![Cirrus CI - Base Branch Build Status](https://img.shields.io/cirrus/github/RPCS3/rpcs3?label=Cirrus%20CI&logo=cirrus-ci)](https://cirrus-ci.com/github/RPCS3/rpcs3)
[![RPCS3 Discord Server](https://img.shields.io/discord/272035812277878785?color=5865F2&label=RPCS3%20Discord&logo=discord&logoColor=white)](https://discord.me/rpcs3)
The world's first free and open-source PlayStation 3 emulator/debugger, written in C++ for Windows, Linux, macOS and FreeBSD.
+37 -5
View File
@@ -1,7 +1,6 @@
#include "stdafx.h"
#include "Config.h"
#include "util/types.hpp"
#include "util/yaml.hpp"
#include <charconv>
@@ -97,7 +96,7 @@ bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max)
if (result < min || result > max)
{
if (out) cfg_log.error("cfg::try_to_int64('%s'): out of bounds (%d..%d)", value, min, max);
if (out) cfg_log.error("cfg::try_to_int64('%s'): out of bounds (val=%d, min=%d, max=%d)", value, result, min, max);
return false;
}
@@ -140,7 +139,7 @@ bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max)
if (result < min || result > max)
{
if (out) cfg_log.error("cfg::try_to_uint64('%s'): out of bounds (%u..%u)", value, min, max);
if (out) cfg_log.error("cfg::try_to_uint64('%s'): out of bounds (val=%u, min=%u, max=%u)", value, result, min, max);
return false;
}
@@ -176,7 +175,7 @@ bool try_to_float(f64* out, std::string_view value, f64 min, f64 max)
if (result < min || result > max)
{
if (out) cfg_log.error("cfg::try_to_float('%s'): out of bounds (%f..%f)", value, min, max);
if (out) cfg_log.error("cfg::try_to_float('%s'): out of bounds (val=%f, min=%f, max=%f)", value, result, min, max);
return false;
}
@@ -184,6 +183,27 @@ bool try_to_float(f64* out, std::string_view value, f64 min, f64 max)
return true;
}
bool try_to_string(std::string* out, const f64& value)
{
#ifdef __APPLE__
if (out) *out = std::to_string(value);
return true;
#else
std::array<char, 32> str{};
if (auto [ptr, ec] = std::to_chars(str.data(), str.data() + str.size(), value, std::chars_format::fixed); ec == std::errc())
{
if (out) *out = std::string(str.data(), ptr);
return true;
}
else
{
if (out) cfg_log.error("cfg::try_to_string(): could not convert value '%f' to string. error='%s'", value, std::make_error_code(ec).message());
return false;
}
#endif
}
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, std::string_view value)
{
u64 max = umax;
@@ -231,7 +251,7 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
if (result > max)
{
if (out) cfg_log.error("cfg::try_to_enum_value('%s'): out of bounds(0..%u)", value, max);
if (out) cfg_log.error("cfg::try_to_enum_value('%s'): out of bounds(val=%u, min=0, max=%u)", value, result, max);
return false;
}
@@ -559,6 +579,18 @@ void cfg::log_entry::from_default()
set_map({});
}
std::pair<u16, u16> cfg::device_info::get_usb_ids() const
{
auto string_to_hex = [](const std::string& str) -> u16
{
u16 value = 0x0000;
if (!str.empty() && std::from_chars(str.data(), str.data() + str.size(), value, 16).ec != std::errc{})
cfg_log.error("Failed to parse hex from string \"%s\"", str);
return value;
};
return {string_to_hex(vid), string_to_hex(pid)};
}
void cfg::device_entry::set_map(map_of_type<device_info>&& map)
{
m_map = std::move(map);
+72 -10
View File
@@ -80,7 +80,13 @@ namespace cfg
// Convert to string (optional)
virtual std::string to_string() const
{
return{};
return {};
}
// Convert default to string (optional)
virtual std::string def_to_string() const
{
return {};
}
// Try to convert from string (optional)
@@ -89,7 +95,7 @@ namespace cfg
// Get string list (optional)
virtual std::vector<std::string> to_list() const
{
return{};
return {};
}
// Set multiple values. Implementation-specific, optional.
@@ -163,11 +169,24 @@ namespace cfg
return m_value ? "true" : "false";
}
std::string def_to_string() const override
{
return def ? "true" : "false";
}
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
{
if (value == "false")
if (value.size() != 4 && value.size() != 5)
{
return false;
}
char copy[5];
std::transform(value.begin(), value.end(), std::begin(copy), ::tolower);
if (value.size() == 5 && std::string_view{copy, 5} == "false")
m_value = false;
else if (value == "true")
else if (value.size() == 4 && std::string_view{copy, 4} == "true")
m_value = true;
else
return false;
@@ -224,6 +243,13 @@ namespace cfg
return result; // TODO: ???
}
std::string def_to_string() const override
{
std::string result;
fmt_class_string<T>::format(result, fmt_unveil<T>::get(def));
return result; // TODO: ???
}
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
{
u64 result;
@@ -259,8 +285,8 @@ namespace cfg
int_type def;
// Expose range
static const s64 max = Max;
static const s64 min = Min;
static constexpr s64 max = Max;
static constexpr s64 min = Min;
_int(node* owner, const std::string& name, int_type def = std::min<int_type>(Max, std::max<int_type>(Min, 0)), bool dynamic = false)
: _base(type::_int, owner, name, dynamic)
@@ -289,6 +315,11 @@ namespace cfg
return std::to_string(m_value);
}
std::string def_to_string() const override
{
return std::to_string(def);
}
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
{
s64 result;
@@ -303,6 +334,7 @@ namespace cfg
void set(const s64& value)
{
ensure(value >= Min && value <= Max);
m_value = static_cast<int_type>(value);
}
@@ -352,7 +384,24 @@ namespace cfg
std::string to_string() const override
{
return std::to_string(m_value);
std::string result;
if (try_to_string(&result, m_value))
{
return result;
}
return "0.0";
}
std::string def_to_string() const override
{
std::string result;
if (try_to_string(&result, def))
{
return result;
}
return "0.0";
}
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
@@ -369,6 +418,7 @@ namespace cfg
void set(const f64& value)
{
ensure(value >= Min && value <= Max);
m_value = static_cast<float_type>(value);
}
@@ -399,8 +449,8 @@ namespace cfg
int_type def;
// Expose range
static const u64 max = Max;
static const u64 min = Min;
static constexpr u64 max = Max;
static constexpr u64 min = Min;
uint(node* owner, const std::string& name, int_type def = std::max<int_type>(Min, 0), bool dynamic = false)
: _base(type::uint, owner, name, dynamic)
@@ -429,6 +479,11 @@ namespace cfg
return std::to_string(m_value);
}
std::string def_to_string() const override
{
return std::to_string(def);
}
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
{
u64 result;
@@ -443,6 +498,7 @@ namespace cfg
void set(const u64& value)
{
ensure(value >= Min && value <= Max);
m_value = static_cast<int_type>(value);
}
@@ -500,6 +556,11 @@ namespace cfg
return *m_value.load().get();
}
std::string def_to_string() const override
{
return def;
}
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
{
m_value = std::string(value);
@@ -533,7 +594,7 @@ namespace cfg
std::vector<std::string> to_list() const override
{
return{ m_set.begin(), m_set.end() };
return { m_set.begin(), m_set.end() };
}
bool from_list(std::vector<std::string>&& list) override
@@ -598,6 +659,7 @@ namespace cfg
std::string serial;
std::string vid;
std::string pid;
std::pair<u16, u16> get_usb_ids() const;
};
class device_entry final : public _base
+151 -16
View File
@@ -437,6 +437,9 @@ std::string fs::get_parent_dir(std::string_view path, u32 levels)
bool fs::stat(const std::string& path, stat_t& info)
{
// Ensure consistent information on failure
info = {};
if (auto device = get_virtual_device(path))
{
return device->stat(path, info);
@@ -1103,10 +1106,12 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
class windows_file final : public file_base
{
const HANDLE m_handle;
atomic_t<u64> m_pos;
public:
windows_file(HANDLE handle)
: m_handle(handle)
, m_pos(0)
{
}
@@ -1162,7 +1167,39 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
const DWORD size = static_cast<DWORD>(std::min<u64>(count, DWORD{umax} & -4096));
DWORD nread = 0;
ensure(ReadFile(m_handle, data, size, &nread, nullptr)); // "file::read"
OVERLAPPED ovl{};
const u64 pos = m_pos;
ovl.Offset = DWORD(pos);
ovl.OffsetHigh = DWORD(pos >> 32);
ensure(ReadFile(m_handle, data, size, &nread, &ovl) || GetLastError() == ERROR_HANDLE_EOF); // "file::read"
nread_sum += nread;
m_pos += nread;
if (nread < size)
{
break;
}
count -= size;
data += size;
}
return nread_sum;
}
u64 read_at(u64 offset, void* buffer, u64 count) override
{
u64 nread_sum = 0;
for (char* data = static_cast<char*>(buffer); count;)
{
const DWORD size = static_cast<DWORD>(std::min<u64>(count, DWORD{umax} & -4096));
DWORD nread = 0;
OVERLAPPED ovl{};
ovl.Offset = DWORD(offset);
ovl.OffsetHigh = DWORD(offset >> 32);
ensure(ReadFile(m_handle, data, size, &nread, &ovl) || GetLastError() == ERROR_HANDLE_EOF); // "file::read"
nread_sum += nread;
if (nread < size)
@@ -1172,6 +1209,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
count -= size;
data += size;
offset += size;
}
return nread_sum;
@@ -1186,8 +1224,13 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
const DWORD size = static_cast<DWORD>(std::min<u64>(count, DWORD{umax} & -4096));
DWORD nwritten = 0;
ensure(WriteFile(m_handle, data, size, &nwritten, nullptr)); // "file::write"
OVERLAPPED ovl{};
const u64 pos = m_pos;
ovl.Offset = DWORD(pos);
ovl.OffsetHigh = DWORD(pos >> 32);
ensure(WriteFile(m_handle, data, size, &nwritten, &ovl)); // "file::write"
nwritten_sum += nwritten;
m_pos += nwritten;
if (nwritten < size)
{
@@ -1208,20 +1251,19 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
fmt::throw_exception("Invalid whence (0x%x)", whence);
}
LARGE_INTEGER pos;
pos.QuadPart = offset;
const s64 new_pos =
whence == fs::seek_set ? offset :
whence == fs::seek_cur ? offset + m_pos :
whence == fs::seek_end ? offset + size() : -1;
const DWORD mode =
whence == seek_set ? FILE_BEGIN :
whence == seek_cur ? FILE_CURRENT : FILE_END;
if (!SetFilePointerEx(m_handle, pos, &pos, mode))
if (new_pos < 0)
{
g_tls_error = to_error(GetLastError());
fs::g_tls_error = fs::error::inval;
return -1;
}
return pos.QuadPart;
m_pos = new_pos;
return m_pos;
}
u64 size() override
@@ -1340,16 +1382,55 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
u64 read(void* buffer, u64 count) override
{
const auto result = ::read(m_fd, buffer, count);
ensure(result != -1); // "file::read"
u64 result = 0;
// Loop because (huge?) read can be processed partially
while (auto r = ::read(m_fd, buffer, count))
{
ensure(r > 0); // "file::read"
count -= r;
result += r;
buffer = static_cast<u8*>(buffer) + r;
if (!count)
break;
}
return result;
}
u64 read_at(u64 offset, void* buffer, u64 count) override
{
u64 result = 0;
// For safety; see read()
while (auto r = ::pread(m_fd, buffer, count, offset))
{
ensure(r > 0); // "file::read_at"
count -= r;
offset += r;
result += r;
buffer = static_cast<u8*>(buffer) + r;
if (!count)
break;
}
return result;
}
u64 write(const void* buffer, u64 count) override
{
const auto result = ::write(m_fd, buffer, count);
ensure(result != -1); // "file::write"
u64 result = 0;
// For safety; see read()
while (auto r = ::write(m_fd, buffer, count))
{
ensure(r > 0); // "file::write"
count -= r;
result += r;
buffer = static_cast<const u8*>(buffer) + r;
if (!count)
break;
}
return result;
}
@@ -1463,6 +1544,21 @@ fs::file::file(const void* ptr, usz size)
return 0;
}
u64 read_at(u64 offset, void* buffer, u64 count) override
{
if (offset < m_size)
{
// Get readable size
if (const u64 result = std::min<u64>(count, m_size - offset))
{
std::memcpy(buffer, m_ptr + offset, result);
return result;
}
}
return 0;
}
u64 write(const void*, u64) override
{
return 0;
@@ -1828,7 +1924,7 @@ bool fs::remove_all(const std::string& path, bool remove_root, bool is_no_dir_ok
return true;
}
u64 fs::get_dir_size(const std::string& path, u64 rounding_alignment)
u64 fs::get_dir_size(const std::string& path, u64 rounding_alignment, atomic_t<bool>* cancel_flag)
{
u64 result = 0;
@@ -1841,6 +1937,11 @@ u64 fs::get_dir_size(const std::string& path, u64 rounding_alignment)
for (const auto& entry : root_dir)
{
if (cancel_flag && *cancel_flag)
{
return umax;
}
if (entry.name == "." || entry.name == "..")
{
continue;
@@ -1948,6 +2049,40 @@ fs::file fs::make_gather(std::vector<fs::file> files)
return 0;
}
u64 read_at(u64 start, void* buffer, u64 size) override
{
if (start < end)
{
u64 pos = start;
// Get readable size
if (const u64 max = std::min<u64>(size, end - pos))
{
u8* buf_out = static_cast<u8*>(buffer);
u64 buf_max = max;
for (auto it = ends.upper_bound(pos); it != ends.end(); ++it)
{
const u64 count = std::min<u64>(it->first - pos, buf_max);
const u64 read = files[it->second].read_at(files[it->second].size() + pos - it->first, buf_out, count);
buf_out += count;
buf_max -= count;
pos += read;
if (read < count || buf_max == 0)
{
break;
}
}
return pos - start;
}
}
return 0;
}
u64 write(const void*, u64) override
{
return 0;
+31 -1
View File
@@ -93,6 +93,7 @@ namespace fs
virtual void sync();
virtual bool trunc(u64 length) = 0;
virtual u64 read(void* buffer, u64 size) = 0;
virtual u64 read_at(u64 offset, void* buffer, u64 size) = 0;
virtual u64 write(const void* buffer, u64 size) = 0;
virtual u64 seek(s64 offset, seek_mode whence) = 0;
virtual u64 size() = 0;
@@ -301,6 +302,17 @@ namespace fs
return m_file->read(buffer, count);
}
// Read the data from the file at specified offset in thread-safe manner
u64 read_at(u64 offset, void* buffer, u64 count,
u32 line = __builtin_LINE(),
u32 col = __builtin_COLUMN(),
const char* file = __builtin_FILE(),
const char* func = __builtin_FUNCTION()) const
{
if (!m_file) xnull({line, col, file, func});
return m_file->read_at(offset, buffer, count);
}
// Write the data to the file and return the amount of data actually written
u64 write(const void* buffer, u64 count,
u32 line = __builtin_LINE(),
@@ -657,7 +669,7 @@ namespace fs
bool remove_all(const std::string& path, bool remove_root = true, bool is_no_dir_ok = false);
// Get size of all files recursively
u64 get_dir_size(const std::string& path, u64 rounding_alignment = 1);
u64 get_dir_size(const std::string& path, u64 rounding_alignment = 1, atomic_t<bool>* cancel_flag = nullptr);
enum class error : uint
{
@@ -724,6 +736,24 @@ namespace fs
return 0;
}
u64 read_at(u64 offset, void* buffer, u64 size) override
{
const u64 end = obj.size();
if (offset < end)
{
// Get readable size
if (const u64 max = std::min<u64>(size, end - offset))
{
std::copy(obj.cbegin() + offset, obj.cbegin() + offset + max, static_cast<value_type*>(buffer));
update_time();
return max;
}
}
return 0;
}
u64 write(const void* buffer, u64 size) override
{
const u64 old_size = obj.size();
+9 -2
View File
@@ -37,6 +37,12 @@ std::string utf16_to_utf8(std::u16string_view src)
return converter.to_bytes(src.data());
}
std::u16string utf8_to_utf16(std::string_view src)
{
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter{};
return converter.from_bytes(src.data());
}
std::wstring utf8_to_wchar(std::string_view src)
{
#ifdef _WIN32
@@ -449,7 +455,7 @@ struct fmt::cfmt_src
{
// Hack: use known function pointers to determine type
#define TYPE(type) \
if (sup[extra].fmt_string == &fmt_class_string<type>::format) return sizeof(type);
if (sup[extra].fmt_string == &fmt_class_string<type>::format) return sizeof(type);
TYPE(int);
TYPE(llong);
@@ -457,10 +463,11 @@ struct fmt::cfmt_src
TYPE(short);
if (std::is_signed<char>::value) TYPE(char);
TYPE(long);
TYPE(u128);
TYPE(s128);
#undef TYPE
if (sup[extra].fmt_string == &fmt_class_string<u128>::format)
return -1;
return 0;
}
+23
View File
@@ -237,6 +237,29 @@ struct fmt_class_string<wchar_t*, void> : fmt_class_string<const wchar_t*>
{
};
namespace fmt
{
template <typename T>
concept StringConvertible = requires (T & t)
{
{ t.to_string() } -> std::convertible_to<std::string>;
};
}
template <fmt::StringConvertible T>
struct fmt_class_string<T, void>
{
static FORCE_INLINE SAFE_BUFFERS(const T&) get_object(u64 arg)
{
return *reinterpret_cast<const T*>(static_cast<uptr>(arg));
}
static void format(std::string& out, u64 arg)
{
out += get_object(arg).to_string();
}
};
namespace fmt
{
// Both uchar and std::byte are allowed
+5 -1
View File
@@ -11,12 +11,13 @@
std::wstring utf8_to_wchar(std::string_view src);
std::string wchar_to_utf8(std::wstring_view src);
std::string utf16_to_utf8(std::u16string_view src);
std::u16string utf8_to_utf16(std::string_view src);
// Copy null-terminated string from a std::string or a char array to a char array with truncation
template <typename D, typename T>
inline void strcpy_trunc(D& dst, const T& src)
{
const usz count = std::size(src) >= std::size(dst) ? std::size(dst) - 1 : std::size(src);
const usz count = std::size(src) >= std::size(dst) ? std::max<usz>(std::size(dst), 1) - 1 : std::size(src);
std::memcpy(std::data(dst), std::data(src), count);
std::memset(std::data(dst) + count, 0, std::size(dst) - count);
}
@@ -30,6 +31,9 @@ bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max);
// Convert string to float
bool try_to_float(f64* out, std::string_view value, f64 min, f64 max);
// Convert float to string locale independent
bool try_to_string(std::string* out, const f64& value);
// Get the file extension of a file path ("png", "jpg", etc.)
std::string get_file_extension(const std::string& file_path);
+14 -14
View File
@@ -96,27 +96,21 @@ thread_local bool g_tls_access_violation_recovered = false;
extern thread_local std::string(*g_tls_log_prefix)();
// Report error and call std::abort(), defined in main.cpp
[[noreturn]] void report_fatal_error(std::string_view);
[[noreturn]] void report_fatal_error(std::string_view text, bool is_html = false, bool include_help_text = true);
std::string dump_useful_thread_info()
{
thread_local volatile bool guard = false;
std::string result;
// In case the dumping function was the cause for the exception/access violation
// Avoid recursion
if (std::exchange(guard, true))
{
return result;
}
if (auto cpu = get_current_cpu_thread())
{
cpu->dump_all(result);
// Wrap it to disable some internal exceptions when printing (not thrown on main thread)
Emu.BlockingCallFromMainThread([&]()
{
cpu->dump_all(result);
});
}
guard = false;
return result;
}
@@ -1802,7 +1796,7 @@ static void signal_handler(int /*sig*/, siginfo_t* info, void* uct) noexcept
const bool is_executing = err & 0x10;
const bool is_writing = err & 0x2;
#elif defined(ARCH_ARM64)
const bool is_executing = uptr(info->si_addr) == RIP(context);
const bool is_executing = uptr(info->si_addr) == uptr(RIP(context));
const u32 insn = is_executing ? 0 : *reinterpret_cast<u32*>(RIP(context));
const bool is_writing = (insn & 0xbfff0000) == 0x0c000000
|| (insn & 0xbfe00000) == 0x0c800000
@@ -1927,7 +1921,10 @@ const bool s_terminate_handler_set = []() -> bool
std::set_terminate([]()
{
if (IsDebuggerPresent())
{
logs::listener::sync_all();
utils::trap();
}
report_fatal_error("RPCS3 has abnormally terminated.");
});
@@ -2065,7 +2062,7 @@ void thread_base::set_name(std::string name)
u64 thread_base::finalize(thread_state result_state) noexcept
{
// Report pending errors
error_code::error_report(0, 0, 0, 0);
error_code::error_report(0, nullptr, nullptr, nullptr, nullptr);
#ifdef _WIN32
static thread_local ULONG64 tls_cycles{};
@@ -2650,7 +2647,10 @@ void thread_base::exec()
sig_log.fatal("Thread terminated due to fatal error: %s", reason);
if (IsDebuggerPresent())
{
logs::listener::sync_all();
utils::trap();
}
if (const auto _this = g_tls_this_thread)
{
+496 -128
View File
File diff suppressed because it is too large Load Diff
+51 -1
View File
@@ -18,6 +18,13 @@ namespace patch_key
static const std::string patch = "Patch";
static const std::string patch_version = "Patch Version";
static const std::string version = "Version";
static const std::string enabled = "Enabled";
static const std::string config_values = "Configurable Values";
static const std::string value = "Value";
static const std::string type = "Type";
static const std::string min = "Min";
static const std::string max = "Max";
static const std::string allowed_values = "Allowed Values";
}
inline static const std::string patch_engine_version = "1.2";
@@ -47,6 +54,14 @@ enum class patch_type
utf8, // Text of string (not null-terminated automatically)
};
enum class patch_configurable_type
{
double_range,
double_enum,
long_range,
long_enum
};
class patch_engine
{
public:
@@ -63,7 +78,40 @@ public:
mutable u32 alloc_addr = 0; // Used to save optional allocation address (if occured)
};
using patch_app_versions = std::unordered_map<std::string /*app_version*/, bool /*enabled*/>;
struct patch_allowed_value
{
std::string label;
f64 value{};
bool operator==(const patch_allowed_value& other) const
{
return value == other.value && label == other.label;
}
};
struct patch_config_value
{
f64 value{};
f64 min{};
f64 max{};
patch_configurable_type type{};
std::vector<patch_allowed_value> allowed_values;
bool operator==(const patch_config_value& other) const
{
return value == other.value && min == other.min && max == other.max && type == other.type && allowed_values == other.allowed_values;
}
void set_and_check_value(f64 new_value, const std::string& name);
};
struct patch_config_values
{
bool enabled{};
std::map<std::string, patch_config_value> config_values;
};
using patch_app_versions = std::unordered_map<std::string /*app_version*/, patch_config_values>;
using patch_serials = std::unordered_map<std::string /*serial*/, patch_app_versions>;
using patch_titles = std::unordered_map<std::string /*serial*/, patch_serials>;
@@ -78,10 +126,12 @@ public:
std::string author{};
std::string notes{};
std::string source_path{};
std::map<std::string, patch_config_value> default_config_values;
// Redundant information for accessibility (see patch_container)
std::string hash{};
std::string version{};
std::map<std::string, patch_config_value> actual_config_values;
};
struct patch_container
+33 -20
View File
@@ -367,9 +367,11 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
break;
}
if (!ctx.type)
const usz src_type = src.type(ctx.args);
if (!ctx.type || src_type > 8)
{
ctx.type = static_cast<u8>(src.type(ctx.args));
ctx.type = static_cast<u8>(src_type);
if (!ctx.type)
{
@@ -379,7 +381,13 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
// Sign-extended argument expected
const u64 val = src.template get<u64>(ctx.args);
const bool negative = ctx.type && static_cast<s64>(val) < 0;
bool negative = ctx.type && ctx.type <= 8 && static_cast<s64>(val) < 0;
if (ctx.type == 16)
{
u128 val2 = *reinterpret_cast<const u128*>(val);
negative = !!(val2 & (u128{1} << 127));
}
const usz start = out.size();
@@ -398,15 +406,14 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
out.push_back(' ');
}
if (ctx.type == 16)
if (ctx.type >= 16)
{
// TODO: support negative values (s128)
u128 val2 = *reinterpret_cast<u128*>(val);
write_decimal(val2, ctx.prec);
u128 val2 = *reinterpret_cast<const u128*>(val);
write_decimal(negative ? u128{} - val2 : val2, ctx.prec);
}
else
{
write_decimal(negative ? 0 - val : val, ctx.prec);
write_decimal(negative ? u64{} - val : val, ctx.prec);
}
}
@@ -438,9 +445,11 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
break;
}
if (!ctx.type)
const usz src_type = src.type(ctx.args);
if (!ctx.type || src_type > 8)
{
ctx.type = static_cast<u8>(src.type(ctx.args));
ctx.type = static_cast<u8>(src_type);
if (!ctx.type)
{
@@ -471,9 +480,9 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
if ((ctx.alter && val) || !ctx.dot || ctx.prec)
{
if (ctx.type == 16)
if (ctx.type >= 16)
{
u128 val2 = *reinterpret_cast<u128*>(val);
u128 val2 = *reinterpret_cast<const u128*>(val);
write_octal(val2, ctx.prec);
}
else
@@ -504,9 +513,11 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
break;
}
if (!ctx.type)
const usz src_type = src.type(ctx.args);
if (!ctx.type || src_type > 8)
{
ctx.type = static_cast<u8>(src.type(ctx.args));
ctx.type = static_cast<u8>(src_type);
if (!ctx.type)
{
@@ -537,9 +548,9 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
if ((ctx.alter && val) || !ctx.dot || ctx.prec)
{
if (ctx.type == 16)
if (ctx.type >= 16)
{
u128 val2 = *reinterpret_cast<u128*>(val);
u128 val2 = *reinterpret_cast<const u128*>(val);
write_hex(val2, ch == 'X', ctx.prec);
}
else
@@ -576,9 +587,11 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
break;
}
if (!ctx.type)
const usz src_type = src.type(ctx.args);
if (!ctx.type || src_type > 8)
{
ctx.type = static_cast<u8>(src.type(ctx.args));
ctx.type = static_cast<u8>(src_type);
if (!ctx.type)
{
@@ -599,9 +612,9 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
if (!ctx.dot || ctx.prec)
{
if (ctx.type == 16)
if (ctx.type >= 16)
{
u128 val2 = *reinterpret_cast<u128*>(val);
u128 val2 = *reinterpret_cast<const u128*>(val);
write_decimal(val2, ctx.prec);
}
else
+3 -3
View File
@@ -777,9 +777,9 @@ struct color4_base
};
constexpr color4_base()
: x{}
, y{}
, z{}
: x{ T{0} }
, y{ T{0} }
, z{ T{0} }
, w{ T(1) }
{
}
+8
View File
@@ -359,6 +359,14 @@ public:
return result;
}
// Withdraw the list in reverse order (LIFO/FILO)
lf_queue_slice<T> pop_all_reversed()
{
lf_queue_slice<T> result;
result.m_head = m_head.exchange(nullptr);
return result;
}
// Apply func(data) to each element, return the total length
template <typename F>
usz apply(F func)
+28 -2
View File
@@ -4,17 +4,43 @@
namespace utils
{
namespace stack_trace
{
// Printing utilities
template <typename T>
concept Logger = requires (T& t, const std::string& msg)
{
{ t.print(msg) };
};
struct print_to_log
{
logs::channel& log;
public:
print_to_log(logs::channel& chan)
: log(chan)
{}
void print(const std::string& s)
{
log.error("%s", s);
}
};
}
std::vector<void*> get_backtrace(int max_depth = 255);
std::vector<std::string> get_backtrace_symbols(const std::vector<void*>& stack);
FORCE_INLINE void print_trace(logs::channel& logger, int max_depth = 255)
FORCE_INLINE void print_trace(stack_trace::Logger auto& logger, int max_depth = 255)
{
const auto trace = get_backtrace(max_depth);
const auto lines = get_backtrace_symbols(trace);
for (const auto& line : lines)
{
logger.error("%s", line);
logger.print(line);
}
}
}
+2 -2
View File
@@ -70,8 +70,8 @@ jobs:
QT_VER_MSVC: 'msvc2019'
QT_DATE: '202011130602'
QTDIR: C:\Qt\$(QT_VER)\$(QT_VER_MSVC)_64
VULKAN_VER: '1.3.204.0'
VULKAN_SDK_SHA: '41f4996335cc5a545d7b2f6e5ff29cf3867789aae4be053a7069aa93408861fa'
VULKAN_VER: '1.3.224.1'
VULKAN_SDK_SHA: '2029e652e39ee6a6036cff3765da31e1e6c595fd2413d3cd111dfab7855621ea'
VULKAN_SDK: C:\VulkanSDK\$(VULKAN_VER)
CACHE_DIR: ./cache
UPLOAD_COMMIT_HASH: 7d09e3be30805911226241afbb14f8cdc2eb054e
@@ -1,5 +1,5 @@
/*
TheMitoSan Dark-Theme for RPCS3
/*
TheMitoSan Dark-Theme for RPCS3
Based on Kuroi (Dark) by Ani
by themitosan @ twitter.com/themitosan
Ani @ https://github.com/AniLeo
@@ -135,7 +135,7 @@ QPushButton::disabled {
}
QPushButton::pressed {
background-color: #333;
background-color: #333;
}
/* Log and Debugger borders */
@@ -193,7 +193,7 @@ QListWidget::item:hover {
}
/* Pad Settings: Controller Image */
QLabel#l_controller {
QLabel#l_controller {
color: #FFF;
}
@@ -230,8 +230,8 @@ QLabel#color_button {
}
/* Search bar on main toolbar */
QLineEdit#mw_searchbar {
margin-left: 0.7em;
QLineEdit#mw_searchbar {
margin-left: 0.7em;
color: #ecf0f1;
}
+10 -10
View File
@@ -1,4 +1,4 @@
/*
/*
Envy theme for RPCS3 by drysalter (https://github.com/drysalter)
03/04/2019
*/
@@ -19,7 +19,7 @@ Candy Red: #ff007a
Yellow: #f2d571
Fuchsia: #ff00ff
Orange: #ff6000
Cyan: #3498d8
Cyan: #3498d8
*/
@@ -209,7 +209,7 @@ QRadioButton::indicator:unchecked {
}
QRadioButton::indicator:disabled {
background-color: #4d5058;
background-color: #4d5058;
}
/* Combo Boxes */
@@ -272,7 +272,7 @@ QSlider::handle:horizontal {
border: 1px solid #5c5c5c;
border-radius: 0.1em;
width: 18px;
margin: -2px 2;
margin: -2px 2;
}
QSlider::handle:horizontal:hover {
@@ -335,7 +335,7 @@ QPushButton:disabled {
}
QPushButton::pressed {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d3038, stop: 1 #2d3038);
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d3038, stop: 1 #2d3038);
}
/* Spinboxes */
@@ -479,7 +479,7 @@ QListWidget::indicator:disabled {
}
/* Pad Settings: Controller Image */
QLabel#l_controller {
QLabel#l_controller {
color: #8cf944;
}
@@ -505,7 +505,7 @@ QLabel#color_button {
}
/* Search bar on main toolbar */
QLineEdit#mw_searchbar {
QLineEdit#mw_searchbar {
color: #ecf0f1;
background-color: #2d3038;
border: 1px solid #f8f8f8;
@@ -513,14 +513,14 @@ QLineEdit#mw_searchbar {
padding-left: 5px;
}
QLineEdit#mw_searchbar:hover {
QLineEdit#mw_searchbar:hover {
color: #ecf0f1;
background-color: #2d3038;
border: 1px solid #8cf944;
margin: 15px;
}
QLineEdit#mw_searchbar:focus {
QLineEdit#mw_searchbar:focus {
border: 1px solid #8cf944;
}
@@ -566,7 +566,7 @@ QTableView {
QTableView::item:hover {
color: #8cf944;
}
}
/* Game Icon Background */
QLabel#gamelist_icon_background_color {
@@ -1,5 +1,5 @@
/*
ModernBlue Theme for RPCS3
/*
ModernBlue Theme for RPCS3
by themitosan @ twitter.com/themitosan
(2017.12.12)
*/
@@ -124,7 +124,7 @@ QGroupBox::title {
/* Buttons */
QPushButton {
background-color: #46598b;
color: #fff;
color: #fff;
}
QPushButton::disabled {
@@ -133,7 +133,7 @@ QPushButton::disabled {
}
QPushButton::pressed {
background-color: #172038;
background-color: #172038;
}
/* Log and Debugger borders */
@@ -190,7 +190,7 @@ QListWidget::item:hover {
}
/* Pad Settings: Controller Image */
QLabel#l_controller {
QLabel#l_controller {
color: #fff;
}
@@ -227,8 +227,8 @@ QLabel#color_button {
}
/* Search bar on main toolbar */
QLineEdit#mw_searchbar {
margin-left: 0.7em;
QLineEdit#mw_searchbar {
margin-left: 0.7em;
color: #ecf0f1;
}
+8 -8
View File
@@ -105,7 +105,7 @@ QToolButton:hover {
}
/* Search bar in Main Toolbar */
QLineEdit#mw_searchbar {
QLineEdit#mw_searchbar {
color: #455971;
background-color: #FFFFFF;
border: 1px solid #999999;
@@ -113,15 +113,15 @@ QLineEdit#mw_searchbar {
padding-left: 5px;
}
QLineEdit#mw_searchbar:hover {
margin-left: 0.7em;
QLineEdit#mw_searchbar:hover {
margin-left: 0.7em;
color: #0074e7;
background-color: #FFFFFF;
border: 1px solid #0071ec;
margin: 15px;
}
QLineEdit#mw_searchbar:focus {
QLineEdit#mw_searchbar:focus {
border: 1px solid #0074e7;
}
@@ -148,7 +148,7 @@ QSlider::handle:horizontal {
border: 1px solid #5c5c5c;
border-radius: 0.1em;
width: 18px;
margin: -2px 2;
margin: -2px 2;
}
QSlider::handle:horizontal:hover {
@@ -242,7 +242,7 @@ QRadioButton::indicator:unchecked {
}
QRadioButton::indicator:disabled {
background-color: #455971;
background-color: #455971;
}
/* Checkboxes */
@@ -533,7 +533,7 @@ QProgressBar::chunk {
}
/* Pad Settings: Controller Image */
QLabel#l_controller {
QLabel#l_controller {
color: #0074e7;
}
@@ -554,7 +554,7 @@ QHeaderView::section {
background-color: #111525;
color: #FFFFFF;
padding-top: 3px;
padding-left: 3px;
padding-left: 3px;
height: 20px;
border: none;
}
+8 -8
View File
@@ -105,7 +105,7 @@ QToolButton:hover {
}
/* Search bar in Main Toolbar */
QLineEdit#mw_searchbar {
QLineEdit#mw_searchbar {
color: #455971;
background-color: #FFFFFF;
border: 1px solid #999999;
@@ -113,15 +113,15 @@ QLineEdit#mw_searchbar {
padding-left: 5px;
}
QLineEdit#mw_searchbar:hover {
margin-left: 0.7em;
QLineEdit#mw_searchbar:hover {
margin-left: 0.7em;
color: #455971;
background-color: #FFFFFF;
border: 1px solid #0071ec;
margin: 15px;
}
QLineEdit#mw_searchbar:focus {
QLineEdit#mw_searchbar:focus {
border: 1px solid #0071ec;
}
@@ -148,7 +148,7 @@ QSlider::handle:horizontal {
border: 1px solid #5c5c5c;
border-radius: 0.1em;
width: 18px;
margin: -2px 2;
margin: -2px 2;
}
QSlider::handle:horizontal:disabled {
@@ -254,7 +254,7 @@ QRadioButton::indicator:unchecked {
}
QRadioButton::indicator:disabled {
background-color: #455971;
background-color: #455971;
}
/* Checkboxes */
@@ -552,7 +552,7 @@ QProgressBar::chunk {
}
/* Pad Settings: Controller Image */
QLabel#l_controller {
QLabel#l_controller {
color: #4343c1;
}
@@ -573,7 +573,7 @@ QHeaderView::section {
background-color: #FFFFFF;
color: #455971;
padding-top: 3px;
padding-left: 3px;
padding-left: 3px;
height: 20px;
border: none;
}
+2 -2
View File
@@ -456,10 +456,10 @@ QSlider#sizeSlider::groove:horizontal {
height: 1.5em;
}
/*
/*
On Patch Creator, it's the patch validation label
since we can't avoid repainting color, let's bold it instead
*/
QLabel#validLabel {
font-weight: 600;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

+2 -2
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Common default props for defining properties with macros. Import right after Microsoft.Cpp.Default.props -->
<ImportGroup Label="PropertySheets" />
@@ -8,4 +8,4 @@
</PropertyGroup>
<ItemDefinitionGroup />
<ItemGroup />
</Project>
</Project>
+39 -23
View File
@@ -1,11 +1,12 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29306.81
# Visual Studio Version 17
VisualStudioVersion = 17.3.32929.385
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "3rdparty\asmjit\asmjit.vcxproj", "{AC40FF01-426E-4838-A317-66354CEFAE88}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "emucore", "rpcs3\emucore.vcxproj", "{C4A10229-4712-4BD2-B63E-50D93C67A038}"
ProjectSection(ProjectDependencies) = postProject
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0} = {5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}
{939FE206-1182-ABC3-1234-FEAB88E98404} = {939FE206-1182-ABC3-1234-FEAB88E98404}
EndProjectSection
EndProject
@@ -40,22 +41,23 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml-cpp", "3rdparty\yaml-c
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcs3", "rpcs3\rpcs3.vcxproj", "{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}"
ProjectSection(ProjectDependencies) = postProject
{AC40FF01-426E-4838-A317-66354CEFAE88} = {AC40FF01-426E-4838-A317-66354CEFAE88}
{A107C21C-418A-4697-BB10-20C3AA60E2E4} = {A107C21C-418A-4697-BB10-20C3AA60E2E4}
{C4A10229-4712-4BD2-B63E-50D93C67A038} = {C4A10229-4712-4BD2-B63E-50D93C67A038}
{78CB2F39-B809-4A06-8329-8C0A19119D3D} = {78CB2F39-B809-4A06-8329-8C0A19119D3D}
{3384223A-6D97-4799-9862-359F85312892} = {3384223A-6D97-4799-9862-359F85312892}
{60F89955-91C6-3A36-8000-13C592FEC2DF} = {60F89955-91C6-3A36-8000-13C592FEC2DF}
{3EE5F075-B546-42C4-B6A8-E3CCEF38B78D} = {3EE5F075-B546-42C4-B6A8-E3CCEF38B78D}
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}
{9610627D-20FE-4B07-8CE3-9FF68A5F1EC2} = {9610627D-20FE-4B07-8CE3-9FF68A5F1EC2}
{FDA7B080-03B0-48C8-B24F-88118981422A} = {FDA7B080-03B0-48C8-B24F-88118981422A}
{508c291a-3d18-49f5-b25d-f7c8db92cb21} = {508c291a-3d18-49f5-b25d-f7c8db92cb21}
{DA6F56B4-06A4-441D-AD70-AC5A7D51FADB} = {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}
{FDC361C5-7734-493B-8CFB-037308B35122} = {FDC361C5-7734-493B-8CFB-037308B35122}
{8F85B6CC-250F-4ACA-A617-E820A74E3E3C} = {8F85B6CC-250F-4ACA-A617-E820A74E3E3C}
{5B146DEA-9ACE-4D32-A7FD-3F42464DD69C} = {5B146DEA-9ACE-4D32-A7FD-3F42464DD69C}
{349EE8F9-7D25-4909-AAF5-FF3FADE72187} = {349EE8F9-7D25-4909-AAF5-FF3FADE72187}
{3EE5F075-B546-42C4-B6A8-E3CCEF38B78D} = {3EE5F075-B546-42C4-B6A8-E3CCEF38B78D}
{508C291A-3D18-49F5-B25D-F7C8DB92CB21} = {508C291A-3D18-49F5-B25D-F7C8DB92CB21}
{5B146DEA-9ACE-4D32-A7FD-3F42464DD69C} = {5B146DEA-9ACE-4D32-A7FD-3F42464DD69C}
{60F89955-91C6-3A36-8000-13C592FEC2DF} = {60F89955-91C6-3A36-8000-13C592FEC2DF}
{78CB2F39-B809-4A06-8329-8C0A19119D3D} = {78CB2F39-B809-4A06-8329-8C0A19119D3D}
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA} = {8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}
{8F85B6CC-250F-4ACA-A617-E820A74E3E3C} = {8F85B6CC-250F-4ACA-A617-E820A74E3E3C}
{9610627D-20FE-4B07-8CE3-9FF68A5F1EC2} = {9610627D-20FE-4B07-8CE3-9FF68A5F1EC2}
{A107C21C-418A-4697-BB10-20C3AA60E2E4} = {A107C21C-418A-4697-BB10-20C3AA60E2E4}
{AC40FF01-426E-4838-A317-66354CEFAE88} = {AC40FF01-426E-4838-A317-66354CEFAE88}
{C4A10229-4712-4BD2-B63E-50D93C67A038} = {C4A10229-4712-4BD2-B63E-50D93C67A038}
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}
{DA6F56B4-06A4-441D-AD70-AC5A7D51FADB} = {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}
{FDA7B080-03B0-48C8-B24F-88118981422A} = {FDA7B080-03B0-48C8-B24F-88118981422A}
{FDC361C5-7734-493B-8CFB-037308B35122} = {FDC361C5-7734-493B-8CFB-037308B35122}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hidapi", "3rdparty\hidapi\hidapi.vcxproj", "{A107C21C-418A-4697-BB10-20C3AA60E2E4}"
@@ -73,7 +75,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "3rdparty\curl\li
{73973223-5EE8-41CA-8E88-1D60E89A237B} = {73973223-5EE8-41CA-8E88-1D60E89A237B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SPIRV", "3rdparty\SPIRV\spirv.vcxproj", "{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spirv", "3rdparty\SPIRV\spirv.vcxproj", "{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rdParty", "3rdParty", "{6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}"
EndProject
@@ -83,13 +85,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cubeb", "rpcs3\Cubeb.vcxpro
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcubeb", "3rdparty\cubeb\libcubeb.vcxproj", "{FDA7B080-03B0-48C8-B24F-88118981422A}"
EndProject
Project("{508c291a-3d18-49f5-b25d-f7c8db92cb21}") = "soundtouch", "3rdparty\SoundTouch\soundtouch.vcxproj", "{508c291a-3d18-49f5-b25d-f7c8db92cb21}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soundtouch", "3rdparty\SoundTouch\soundtouch.vcxproj", "{508C291A-3D18-49F5-B25D-F7C8DB92CB21}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL", "3rdparty\libsdl-org\SDL.vcxproj", "{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pine", "pine", "{A55DA1B5-CC17-4525-BE7F-1659CE17BB56}"
ProjectSection(SolutionItems) = preProject
3rdparty\pine\pine_server.h = 3rdparty\pine\pine_server.h
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc_static", "3rdparty\miniupnp\miniupnpc_static.vcxproj", "{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -176,10 +182,18 @@ Global
{FDA7B080-03B0-48C8-B24F-88118981422A}.Debug|x64.Build.0 = Debug|x64
{FDA7B080-03B0-48C8-B24F-88118981422A}.Release|x64.ActiveCfg = Release|x64
{FDA7B080-03B0-48C8-B24F-88118981422A}.Release|x64.Build.0 = Release|x64
{508c291a-3d18-49f5-b25d-f7c8db92cb21}.Debug|x64.ActiveCfg = Debug|x64
{508c291a-3d18-49f5-b25d-f7c8db92cb21}.Debug|x64.Build.0 = Debug|x64
{508c291a-3d18-49f5-b25d-f7c8db92cb21}.Release|x64.ActiveCfg = Release|x64
{508c291a-3d18-49f5-b25d-f7c8db92cb21}.Release|x64.Build.0 = Release|x64
{508C291A-3D18-49F5-B25D-F7C8DB92CB21}.Debug|x64.ActiveCfg = Debug|x64
{508C291A-3D18-49F5-B25D-F7C8DB92CB21}.Debug|x64.Build.0 = Debug|x64
{508C291A-3D18-49F5-B25D-F7C8DB92CB21}.Release|x64.ActiveCfg = Release|x64
{508C291A-3D18-49F5-B25D-F7C8DB92CB21}.Release|x64.Build.0 = Release|x64
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}.Debug|x64.ActiveCfg = Debug|x64
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}.Debug|x64.Build.0 = Debug|x64
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}.Release|x64.ActiveCfg = Release|x64
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}.Release|x64.Build.0 = Release|x64
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Debug|x64.ActiveCfg = Debug|x64
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Debug|x64.Build.0 = Debug|x64
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Release|x64.ActiveCfg = Release|x64
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -206,8 +220,10 @@ Global
{A37E4273-85DB-4217-B775-CE971B87D9DF} = {B0AC29FD-7B01-4B5E-9C8D-0A081E4C5668}
{9610627D-20FE-4B07-8CE3-9FF68A5F1EC2} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
{FDA7B080-03B0-48C8-B24F-88118981422A} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
{508c291a-3d18-49f5-b25d-f7c8db92cb21} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
{508C291A-3D18-49F5-B25D-F7C8DB92CB21} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
{A55DA1B5-CC17-4525-BE7F-1659CE17BB56} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {06CC7920-E085-4B81-9582-8DE8AAD42510}
+4 -2
View File
@@ -66,10 +66,12 @@ set(RPCS3_SRC
Input/ds4_pad_handler.cpp
Input/dualsense_pad_handler.cpp
Input/evdev_joystick_handler.cpp
Input/evdev_gun_handler.cpp
Input/hid_pad_handler.cpp
Input/keyboard_pad_handler.cpp
Input/mm_joystick_handler.cpp
Input/pad_thread.cpp
Input/sdl_pad_handler.cpp
Input/xinput_pad_handler.cpp
)
@@ -185,13 +187,13 @@ elseif(WIN32)
# If Qt5 is installed from vcpkg
list(APPEND _QT5_TOOLS_PATHS "${Qt5_DIR}/../../../tools/qt5$<$<CONFIG:Debug>:/debug>/bin/")
add_custom_command(TARGET rpcs3 POST_BUILD
COMMAND set PATH=${_QT5_TOOLS_PATHS}$<SEMICOLON>%PATH%
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_SOURCE_DIR}/bin" "$<TARGET_FILE_DIR:rpcs3>"
# If Qt5 is installed from vcpkg, add binary path to PATH
# otherwise windeployqt tool won't be able to locate necessary dlls
COMMAND set PATH=${Qt5_DIR}/../../../$<$<CONFIG:Debug>:debug/>bin/$<SEMICOLON>%PATH%
COMMAND set PATH=${Qt5_DIR}/../../../$<$<CONFIG:Debug>:debug/>bin/$<SEMICOLON>%PATH%
COMMAND "${_WINDEPLOYQT}" --no-angle --no-compiler-runtime --no-opengl-sw --no-patchqt --no-translations --no-quick --plugindir "$<TARGET_FILE_DIR:rpcs3>/qt/plugins" $<$<CONFIG:Debug>:--debug> $<$<CONFIG:Release>:--release> "$<TARGET_FILE:rpcs3>")
endif()
+1 -1
View File
@@ -124,7 +124,7 @@ int aes_crypt_cbc( aes_context *ctx,
* both encryption and decryption. So a context initialized with
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
*
* both
* both
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
+1 -1
View File
@@ -245,7 +245,7 @@ constexpr s64 PAID_30 = 0x1070000023000001L; // spu_token_processor.self; CoreOS
constexpr s64 PAID_31 = 0x1070000024000001L; // sv_iso_spu_module.self; CoreOS; same for CEX DEX DECR
constexpr s64 PAID_32 = 0x1070000025000001L; // aim_spu_module.self; CoreOS; same for CEX DEX DECR
constexpr s64 PAID_33 = 0x1070000026000001L; // ss_sc_init.self; [2.43 JIG PUP]
constexpr s64 PAID_34 = 0x1070000027000001L; // dispatcher.fself; lv1;
constexpr s64 PAID_34 = 0x1070000027000001L; // dispatcher.fself; lv1;
constexpr s64 PAID_35 = 0x1070000028000001L; // factory_data_mngr_server.fself; JIG lv1 proc
constexpr s64 PAID_36 = 0x1070000029000001L; // fdm_spu_module.self; [2.43 JIG PUP]
constexpr s64 PAID_37 = 0x107000002A000001L;
-5
View File
@@ -13,9 +13,6 @@
LOG_CHANNEL(edat_log, "EDAT");
// Static variables are being modified concurrently in ec.cpp, for now use a mutex
static shared_mutex ec_mtx;
void generate_key(int crypto_mode, int version, unsigned char *key_final, unsigned char *iv_final, unsigned char *key, unsigned char *iv)
{
int mode = crypto_mode & 0xF0000000;
@@ -482,8 +479,6 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
unsigned char signature_s[0x15] = { 0 };
unsigned char zero_buf[0x15] = { 0 };
std::lock_guard lock(ec_mtx);
// Setup ECDSA curve and public key.
ecdsa_set_curve(VSH_CURVE_P, VSH_CURVE_A, VSH_CURVE_B, VSH_CURVE_N, VSH_CURVE_GX, VSH_CURVE_GY);
ecdsa_set_pub(VSH_PUB);
+5
View File
@@ -115,6 +115,11 @@ public:
return bytesRead;
}
u64 read_at(u64 offset, void* buffer, u64 size) override
{
return ReadData(offset, static_cast<u8*>(buffer), size);
}
u64 write(const void*, u64) override
{
return 0;
+332 -91
View File
@@ -4,12 +4,17 @@
#include "key_vault.h"
#include "util/logs.hpp"
#include "Utilities/StrUtil.h"
#include "Utilities/Thread.h"
#include "Utilities/mutex.h"
#include "Emu/System.h"
#include "Emu/system_utils.hpp"
#include "Emu/VFS.h"
#include "unpkg.h"
#include "util/sysinfo.hpp"
#include "Loader/PSF.h"
#include <filesystem>
LOG_CHANNEL(pkg_log, "PKG");
package_reader::package_reader(const std::string& path)
@@ -61,6 +66,7 @@ bool package_reader::read_header()
return false;
}
pkg_log.notice("Path: '%s'", m_path);
pkg_log.notice("Header: pkg_magic = 0x%x = \"%s\"", +m_header.pkg_magic, std::string(reinterpret_cast<const char*>(&m_header.pkg_magic), 4));
pkg_log.notice("Header: pkg_type = 0x%x = %d", m_header.pkg_type, m_header.pkg_type);
pkg_log.notice("Header: pkg_platform = 0x%x = %d", m_header.pkg_platform, m_header.pkg_platform);
@@ -189,8 +195,7 @@ bool package_reader::read_metadata()
// Read title ID and use it as an installation directory
m_install_dir.resize(9);
archive_seek(55);
archive_read(&m_install_dir.front(), m_install_dir.size());
archive_read_block(55, &m_install_dir.front(), m_install_dir.size());
// Read package metadata
@@ -509,9 +514,9 @@ bool package_reader::read_param_sfo()
std::vector<PKGEntry> entries(m_header.file_count);
std::memcpy(entries.data(), m_buf.get(), entries.size() * sizeof(PKGEntry));
std::memcpy(entries.data(), m_bufs.back().get(), entries.size() * sizeof(PKGEntry));
for (const auto& entry : entries)
for (const PKGEntry& entry : entries)
{
if (entry.name_size > 256)
{
@@ -523,7 +528,7 @@ bool package_reader::read_param_sfo()
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data());
const std::string_view name{reinterpret_cast<char*>(m_buf.get()), entry.name_size};
const std::string_view name{reinterpret_cast<char*>(m_bufs.back().get()), entry.name_size};
// We're looking for the PARAM.SFO file, if there is any
if (usz ndelim = name.find_first_not_of('/'); ndelim == umax || name.substr(ndelim) != "PARAM.SFO")
@@ -538,13 +543,13 @@ bool package_reader::read_param_sfo()
{
const u64 block_size = std::min<u64>(BUF_SIZE, entry.file_size - pos);
if (decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data()) != block_size)
if (decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data()).size() != block_size)
{
pkg_log.error("Failed to decrypt PARAM.SFO file");
return false;
}
if (tmp.write(m_buf.get(), block_size) != block_size)
if (tmp.write(m_bufs.back().get(), block_size) != block_size)
{
pkg_log.error("Failed to write to temporary PARAM.SFO file");
return false;
@@ -553,7 +558,7 @@ bool package_reader::read_param_sfo()
tmp.seek(0);
m_psf = psf::load_object(tmp);
m_psf = psf::load_object(tmp, name);
if (m_psf.empty())
{
@@ -563,11 +568,9 @@ bool package_reader::read_param_sfo()
return true;
}
else
{
pkg_log.error("Failed to create temporary PARAM.SFO file");
return false;
}
pkg_log.error("Failed to create temporary PARAM.SFO file");
return false;
}
return false;
@@ -610,13 +613,14 @@ package_error package_reader::check_target_app_version() const
return package_error::no_error;
}
const fs::file installed_sfo_file(rpcs3::utils::get_hdd0_dir() + "game/" + std::string(title_id) + "/PARAM.SFO");
const std::string sfo_path = rpcs3::utils::get_hdd0_dir() + "game/" + std::string(title_id) + "/PARAM.SFO";
const fs::file installed_sfo_file(sfo_path);
if (!installed_sfo_file)
{
if (!target_app_ver.empty())
{
// We are unable to compare anything with the target app version
pkg_log.error("A target app version is required (%s), but no PARAM.SFO was found for %s", target_app_ver, title_id);
pkg_log.error("A target app version is required (%s), but no PARAM.SFO was found for %s. (path='%s', error=%s)", target_app_ver, title_id, sfo_path, fs::g_tls_error);
return package_error::app_version;
}
@@ -624,7 +628,7 @@ package_error package_reader::check_target_app_version() const
return package_error::no_error;
}
const auto installed_psf = psf::load_object(installed_sfo_file);
const auto installed_psf = psf::load_object(installed_sfo_file, sfo_path);
const auto installed_title_id = psf::get_string(installed_psf, "TITLE_ID", "");
const auto installed_app_ver = psf::get_string(installed_psf, "APP_VER", "");
@@ -686,16 +690,16 @@ package_error package_reader::check_target_app_version() const
return package_error::app_version;
}
fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name, int mode, u8 *custom_klic, bool verbose = false);
bool package_reader::extract_data(atomic_t<double>& sync)
bool package_reader::set_install_path()
{
if (!m_is_valid)
{
return false;
}
// Get full path and create the directory
m_install_path.clear();
// Get full path
std::string dir = rpcs3::utils::get_hdd0_dir();
// Based on https://www.psdevwiki.com/ps3/PKG_files#ContentType
@@ -730,14 +734,30 @@ bool package_reader::extract_data(atomic_t<double>& sync)
dir += m_install_dir + '/';
// If false, an existing directory is being overwritten: cannot cancel the operation
const bool was_null = !fs::is_dir(dir);
m_was_null = !fs::is_dir(dir);
if (!fs::create_path(dir))
m_install_path = dir;
return true;
}
bool package_reader::fill_data(std::map<std::string, install_entry*>& all_install_entries)
{
if (!m_is_valid)
{
pkg_log.error("Could not create the installation directory %s", dir);
return false;
}
if (!fs::create_path(m_install_path))
{
pkg_log.error("Could not create the installation directory %s (error=%s)", m_install_path, fs::g_tls_error);
return false;
}
m_install_entries.clear();
m_bootable_file_path.clear();
m_entry_indexer = 0;
m_written_bytes = 0;
if (!decrypt_data())
{
return false;
@@ -747,26 +767,146 @@ bool package_reader::extract_data(atomic_t<double>& sync)
std::vector<PKGEntry> entries(m_header.file_count);
std::memcpy(entries.data(), m_buf.get(), entries.size() * sizeof(PKGEntry));
std::memcpy(entries.data(), m_bufs.back().get(), entries.size() * sizeof(PKGEntry));
// Create directories first
for (const auto& entry : entries)
{
if (entry.name_size > 256)
if (entry.name_size > PKG_MAX_FILENAME_SIZE)
{
num_failures++;
pkg_log.error("PKG name size is too big (0x%x)", entry.name_size);
break;
}
const bool is_psp = (entry.type & PKG_FILE_ENTRY_PSP) != 0u;
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data());
const std::string name{reinterpret_cast<char*>(m_bufs.back().get()), entry.name_size};
std::string path = m_install_path + vfs::escape(name);
if (entry.pad || (entry.type & ~PKG_FILE_ENTRY_KNOWN_BITS))
{
pkg_log.todo("Entry with unknown type or padding: type=0x%08x, pad=0x%x, name='%s'", entry.type, entry.pad, name);
}
else
{
pkg_log.notice("Entry: type=0x%08x, name='%s'", entry.type, name);
}
const u8 entry_type = entry.type & 0xff;
switch (entry_type)
{
case PKG_FILE_ENTRY_FOLDER:
case 0x12:
{
if (fs::is_dir(path))
{
pkg_log.warning("Reused existing directory %s", path);
}
else if (fs::create_path(path))
{
pkg_log.notice("Created directory %s", path);
}
else
{
num_failures++;
pkg_log.error("Failed to create directory %s", path);
break;
}
break;
}
default:
{
// TODO: check for valid utf8 characters
const std::string true_path = std::filesystem::weakly_canonical(path).string();
if (true_path.empty())
{
num_failures++;
pkg_log.error("Failed to get weakly_canonical path for '%s'", path);
break;
}
auto map_ptr = &*all_install_entries.try_emplace(true_path).first;
m_install_entries.push_back({
.weak_reference = map_ptr,
.name = name,
.file_offset = entry.file_offset,
.file_size = entry.file_size,
.type = entry.type,
.pad = entry.pad
});
if (map_ptr->second && !(entry.type & PKG_FILE_ENTRY_OVERWRITE))
{
// Cannot override
continue;
}
// Link
map_ptr->second = &m_install_entries.back();
continue;
}
}
}
if (num_failures != 0)
{
pkg_log.error("Package installation failed: %s", m_install_path);
return false;
}
return true;
}
fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name, int mode, u8 *custom_klic, bool verbose = false);
void package_reader::extract_worker(thread_key thread_data_key)
{
while (m_num_failures == 0 && !m_aborted)
{
// Make sure m_entry_indexer does not exceed m_install_entries
const usz index = m_entry_indexer.fetch_op([this](usz& v)
{
if (v < m_install_entries.size())
{
v++;
return true;
}
return false;
}).first;
if (index >= m_install_entries.size())
{
break;
}
const install_entry& entry = ::at32(m_install_entries, index);
if (!entry.is_dominating())
{
// Overwritten by another entry
m_written_bytes += entry.file_size;
continue;
}
const bool is_psp = (entry.type & PKG_FILE_ENTRY_PSP) != 0u;
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data());
const std::string& path = entry.weak_reference->first;
const std::string& name = entry.name;
const std::string name{reinterpret_cast<char*>(m_buf.get()), entry.name_size};
const std::string path = dir + vfs::escape(name);
const bool log_error = entry.pad || (entry.type & ~PKG_FILE_ENTRY_KNOWN_BITS);
(log_error ? pkg_log.error : pkg_log.notice)("Entry 0x%08x: %s (pad=0x%x)", entry.type, name, entry.pad);
if (entry.pad || (entry.type & ~PKG_FILE_ENTRY_KNOWN_BITS))
{
pkg_log.todo("Entry with unknown type or padding: type=0x%08x, pad=0x%x, name='%s'", entry.type, entry.pad, name);
}
else
{
pkg_log.notice("Entry: type=0x%08x, name='%s'", entry.type, name);
}
switch (const u8 entry_type = entry.type & 0xff)
{
@@ -798,43 +938,33 @@ bool package_reader::extract_data(atomic_t<double>& sync)
if (entry_type == PKG_FILE_ENTRY_NPDRMEDAT)
{
pkg_log.todo("NPDRM EDAT!");
pkg_log.warning("NPDRM EDAT!");
}
if (fs::file out = is_buffered ? fs::make_stream<std::vector<u8>>() : fs::file{ path, fs::rewrite })
if (fs::file out = is_buffered ? fs::make_stream<std::vector<u8>>() : fs::file{ path, did_overwrite ? fs::rewrite : fs::write_new })
{
bool extract_success = true;
for (u64 pos = 0; pos < entry.file_size; pos += BUF_SIZE)
{
const u64 block_size = std::min<u64>(BUF_SIZE, entry.file_size - pos);
if (decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data()) != block_size)
const std::span<const char> data_span = decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data(), thread_data_key);
if (data_span.size() != block_size)
{
extract_success = false;
pkg_log.error("Failed to extract file %s", path);
pkg_log.error("Failed to extract file %s (data_span.size=%d, block_size=%d)", path, data_span.size(), block_size);
break;
}
if (out.write(m_buf.get(), block_size) != block_size)
if (out.write(data_span.data(), block_size) != block_size)
{
extract_success = false;
pkg_log.error("Failed to write file %s", path);
pkg_log.error("Failed to write file %s (error=%s)", path, fs::g_tls_error);
break;
}
if (sync.fetch_add((block_size + 0.0) / m_header.data_size) < 0.)
{
if (was_null)
{
pkg_log.error("Package installation cancelled: %s", dir);
out.close();
fs::remove_all(dir, true);
return false;
}
// Cannot cancel the installation
sync += 1.;
}
m_written_bytes += block_size;
}
if (is_buffered)
@@ -842,8 +972,8 @@ bool package_reader::extract_data(atomic_t<double>& sync)
out = DecryptEDAT(out, name, 1, reinterpret_cast<u8*>(&m_header.klicensee), true);
if (!out || !fs::write_file(path, fs::rewrite, static_cast<fs::container_stream<std::vector<u8>>*>(out.release().get())->obj))
{
num_failures++;
pkg_log.error("Failed to create file %s", path);
m_num_failures++;
pkg_log.error("Failed to create file %s (error=%s)", path, fs::g_tls_error);
break;
}
}
@@ -857,93 +987,192 @@ bool package_reader::extract_data(atomic_t<double>& sync)
else
{
pkg_log.notice("Created file %s", path);
if (name == "USRDIR/EBOOT.BIN" && entry.file_size > 4)
{
// Expose the creation of a bootable file
m_bootable_file_path = path;
}
}
}
else
{
num_failures++;
m_num_failures++;
}
}
else
{
num_failures++;
pkg_log.error("Failed to create file %s", path);
m_num_failures++;
pkg_log.error("Failed to create file %s (is_buffered=%d, did_overwrite=%d, error=%s)", path, is_buffered, did_overwrite, fs::g_tls_error);
}
break;
}
case PKG_FILE_ENTRY_FOLDER:
case 0x12:
default:
{
if (fs::create_dir(path))
m_num_failures++;
pkg_log.error("Unknown PKG entry type (0x%x) %s", entry.type, name);
break;
}
}
}
}
package_error package_reader::extract_data(std::deque<package_reader>& readers, std::deque<std::string>& bootable_paths)
{
package_error error = package_error::no_error;
usz num_failures = 0;
// Set paths first in order to know if the install dir was empty before starting any installations.
// This will also allow us to remove all the new packages in one path at once if any of them fail.
for (package_reader& reader : readers)
{
reader.m_result = result::not_started;
if (!reader.set_install_path())
{
error = package_error::other;
reader.m_result = result::error;
break;
}
}
for (package_reader& reader : readers)
{
// Use a seperate map for each reader. We need to check if the target app version exists for each package in sequence.
std::map<std::string, install_entry*> all_install_entries;
if (error == package_error::no_error)
{
// Check if this package is allowed to be installed on top of the existing data
error = reader.check_target_app_version();
}
if (error == package_error::no_error)
{
reader.m_result = result::started;
// Parse the files to be installed and create all paths.
if (!reader.fill_data(all_install_entries))
{
pkg_log.notice("Created directory %s", path);
error = package_error::other;
}
else if (fs::is_dir(path))
}
reader.m_bufs.resize(std::min<usz>(utils::get_thread_count(), reader.m_install_entries.size()));
reader.m_num_failures = error == package_error::no_error ? 0 : 1;
atomic_t<usz> thread_indexer = 0;
named_thread_group workers("PKG Installer "sv, std::max<u32>(::narrow<u32>(reader.m_bufs.size()), 1) - 1, [&]()
{
reader.extract_worker(thread_key{thread_indexer++});
});
reader.extract_worker(thread_key{thread_indexer++});
workers.join();
num_failures += reader.m_num_failures;
reader.m_bufs.clear();
reader.m_bufs.shrink_to_fit();
// We don't count this package as aborted if all entries were processed.
if (reader.m_num_failures || (reader.m_aborted && reader.m_entry_indexer < reader.m_install_entries.size()))
{
// Clear boot path. We don't want to propagate potentially broken paths to the caller.
reader.m_bootable_file_path.clear();
bool cleaned = reader.m_was_null;
if (reader.m_was_null && fs::is_dir(reader.m_install_path))
{
pkg_log.warning("Reused existing directory %s", path);
pkg_log.notice("Removing partial installation ('%s')", reader.m_install_path);
if (!fs::remove_all(reader.m_install_path, true))
{
pkg_log.notice("Failed to remove partial installation ('%s') (error=%s)", reader.m_install_path, fs::g_tls_error);
cleaned = false;
}
}
if (reader.m_num_failures)
{
pkg_log.error("Package failed to install ('%s')", reader.m_install_path);
reader.m_result = cleaned ? result::error_cleaned : result::error;
}
else
{
num_failures++;
pkg_log.error("Failed to create directory %s", path);
pkg_log.warning("Package installation aborted ('%s')", reader.m_install_path);
reader.m_result = cleaned ? result::aborted_cleaned : result::aborted;
}
break;
}
default:
reader.m_result = result::success;
if (reader.get_progress(1) != 1)
{
num_failures++;
pkg_log.error("Unknown PKG entry type (0x%x) %s", entry.type, name);
}
pkg_log.warning("Missing %d bytes from PKG total files size.", reader.m_header.data_size - reader.m_written_bytes);
reader.m_written_bytes = reader.m_header.data_size; // Mark as completed anyway
}
// May be empty
bootable_paths.emplace_back(std::move(reader.m_bootable_file_path));
}
if (num_failures == 0)
if (num_failures > 0)
{
pkg_log.success("Package successfully installed to %s", dir);
}
else
{
fs::remove_all(dir, true);
pkg_log.error("Package installation failed: %s", dir);
error = package_error::other;
}
return num_failures == 0;
return error;
}
void package_reader::archive_seek(const s64 new_offset, const fs::seek_mode damode)
{
if (m_file) m_file.seek(new_offset, damode);
};
}
u64 package_reader::archive_read(void* data_ptr, const u64 num_bytes)
{
return m_file ? m_file.read(data_ptr, num_bytes) : 0;
};
}
u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
std::span<const char> package_reader::archive_read_block(u64 offset, void* data_ptr, u64 num_bytes)
{
const usz read_n = m_file.read_at(offset, data_ptr, num_bytes);
return {static_cast<const char*>(data_ptr), read_n};
}
std::span<const char> package_reader::decrypt(u64 offset, u64 size, const uchar* key, thread_key thread_data_key)
{
if (!m_is_valid)
{
return 0;
return {};
}
if (!m_buf)
if (m_bufs.empty())
{
// Assume in single-threaded mode still
m_bufs.resize(1);
}
auto& local_buf = ::at32(m_bufs, thread_data_key.unique_num);
if (!local_buf)
{
// Allocate buffer with BUF_SIZE size or more if required
m_buf.reset(new u128[std::max<u64>(BUF_SIZE, sizeof(PKGEntry) * m_header.file_count) / sizeof(u128)]);
local_buf.reset(new u128[std::max<u64>(BUF_SIZE, sizeof(PKGEntry) * m_header.file_count) / sizeof(u128)]);
}
archive_seek(m_header.data_offset + offset);
// Read the data and set available size
const u64 read = archive_read(m_buf.get(), size);
const auto data_span = archive_read_block(m_header.data_offset + offset, local_buf.get(), size);
ensure(data_span.data() == static_cast<void*>(local_buf.get()));
// Get block count
const u64 blocks = (read + 15) / 16;
const u64 blocks = (data_span.size() + 15) / 16;
if (m_header.pkg_type == PKG_RELEASE_TYPE_DEBUG)
{
@@ -969,7 +1198,7 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
sha1(reinterpret_cast<const u8*>(input), sizeof(input), hash.data);
m_buf[i] ^= hash._v128;
local_buf[i] ^= hash._v128;
}
}
else if (m_header.pkg_type == PKG_RELEASE_TYPE_RELEASE)
@@ -989,7 +1218,7 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
aes_crypt_ecb(&ctx, AES_ENCRYPT, reinterpret_cast<const u8*>(&input), reinterpret_cast<u8*>(&key));
m_buf[i] ^= key;
local_buf[i] ^= key;
}
}
else
@@ -998,5 +1227,17 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
}
// Return the amount of data written in buf
return read;
};
return data_span;
}
int package_reader::get_progress(int maximum) const
{
const usz wr = m_written_bytes;
return wr >= m_header.data_size ? maximum : ::narrow<int>(wr * maximum / m_header.data_size);
}
void package_reader::abort_extract()
{
m_aborted = true;
}
+64 -7
View File
@@ -6,12 +6,15 @@
#include "Utilities/File.h"
#include <sstream>
#include <iomanip>
#include <span>
#include <deque>
// Constants
enum
enum : u32
{
PKG_HEADER_SIZE = 0xC0, // sizeof(pkg_header) + sizeof(pkg_unk_checksum)
PKG_HEADER_SIZE2 = 0x280,
PKG_MAX_FILENAME_SIZE = 256,
};
enum : u16
@@ -303,35 +306,89 @@ enum class package_error
class package_reader
{
struct thread_key
{
const usz unique_num = umax;
};
struct install_entry
{
typename std::map<std::string, install_entry*>::value_type* weak_reference{};
std::string name;
u64 file_offset{};
u64 file_size{};
u32 type{};
u32 pad{};
// Check if the entry is the same one registered in entries to install
bool is_dominating() const
{
return weak_reference->second == this;
}
};
public:
package_reader(const std::string& path);
~package_reader();
enum result
{
not_started,
started,
success,
aborted,
aborted_cleaned,
error,
error_cleaned
};
bool is_valid() const { return m_is_valid; }
package_error check_target_app_version() const;
bool extract_data(atomic_t<double>& sync);
static package_error extract_data(std::deque<package_reader>& readers, std::deque<std::string>& bootable_paths);
psf::registry get_psf() const { return m_psf; }
result get_result() const { return m_result; };
int get_progress(int maximum = 100) const;
void abort_extract();
private:
bool read_header();
bool read_metadata();
bool read_param_sfo();
bool decrypt_data();
void archive_seek(const s64 new_offset, const fs::seek_mode damode = fs::seek_set);
u64 archive_read(void* data_ptr, const u64 num_bytes);
u64 decrypt(u64 offset, u64 size, const uchar* key);
void archive_seek(s64 new_offset, const fs::seek_mode damode = fs::seek_set);
u64 archive_read(void* data_ptr, u64 num_bytes);
bool set_install_path();
bool fill_data(std::map<std::string, install_entry*>& all_install_entries);
std::span<const char> archive_read_block(u64 offset, void* data_ptr, u64 num_bytes);
std::span<const char> decrypt(u64 offset, u64 size, const uchar* key, thread_key thread_data_key = {0});
void extract_worker(thread_key thread_data_key);
const usz BUF_SIZE = 8192 * 1024; // 8 MB
std::deque<install_entry> m_install_entries;
std::string m_install_path;
atomic_t<bool> m_aborted = false;
atomic_t<usz> m_num_failures = 0;
atomic_t<usz> m_entry_indexer = 0;
atomic_t<usz> m_written_bytes = 0;
bool m_was_null = false;
static constexpr usz BUF_SIZE = 8192 * 1024; // 8 MB
bool m_is_valid = false;
result m_result = result::not_started;
std::string m_path{};
std::string m_install_dir{};
fs::file m_file{};
std::unique_ptr<u128[]> m_buf{};
std::vector<std::unique_ptr<u128[]>> m_bufs{};
std::array<uchar, 16> m_dec_key{};
PKGHeader m_header{};
PKGMetaData m_metadata{};
psf::registry m_psf{};
// Expose bootable file installed (if installed such)
std::string m_bootable_file_path;
};
+20 -2
View File
@@ -41,6 +41,7 @@ target_include_directories(rpcs3_emu
target_sources(rpcs3_emu PRIVATE
../util/atomic.cpp
../util/media_utils.cpp
../util/video_provider.cpp
../util/logs.cpp
../util/yaml.cpp
../util/vm_native.cpp
@@ -158,6 +159,10 @@ target_link_libraries(rpcs3_emu
PUBLIC
3rdparty::soundtouch)
target_link_libraries(rpcs3_emu
PUBLIC
3rdparty::miniupnpc)
# Cell
target_sources(rpcs3_emu PRIVATE
Cell/MFC.cpp
@@ -321,6 +326,7 @@ target_sources(rpcs3_emu PRIVATE
Cell/Modules/cellVoice.cpp
Cell/Modules/cellVpost.cpp
Cell/Modules/cellWebBrowser.cpp
Cell/Modules/HLE_PATCHES.cpp
Cell/Modules/libad_async.cpp
Cell/Modules/libad_core.cpp
Cell/Modules/libmedi.cpp
@@ -380,12 +386,14 @@ target_link_libraries(rpcs3_emu
# Io
target_sources(rpcs3_emu PRIVATE
Io/camera_config.cpp
Io/recording_config.cpp
Io/interception.cpp
Io/KeyboardHandler.cpp
Io/pad_config.cpp
Io/pad_config_types.cpp
Io/PadHandler.cpp
Io/usb_device.cpp
Io/usb_vfs.cpp
Io/Skylander.cpp
Io/GHLtar.cpp
Io/Buzz.cpp
@@ -407,6 +415,8 @@ target_sources(rpcs3_emu PRIVATE
NP/np_structs_extra.cpp
NP/rpcn_client.cpp
NP/rpcn_config.cpp
NP/upnp_config.cpp
NP/upnp_handler.cpp
)
# Memory
@@ -433,12 +443,20 @@ target_sources(rpcs3_emu PRIVATE
RSX/Common/TextureUtils.cpp
RSX/Common/texture_cache.cpp
RSX/Null/NullGSRender.cpp
RSX/Overlays/HomeMenu/overlay_home_menu.cpp
RSX/Overlays/HomeMenu/overlay_home_menu_components.cpp
RSX/Overlays/HomeMenu/overlay_home_menu_main_menu.cpp
RSX/Overlays/HomeMenu/overlay_home_menu_message_box.cpp
RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp
RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp
RSX/Overlays/overlay_animated_icon.cpp
RSX/Overlays/overlay_animation.cpp
RSX/Overlays/overlay_controls.cpp
RSX/Overlays/overlay_cursor.cpp
RSX/Overlays/overlay_edit_text.cpp
RSX/Overlays/overlay_fonts.cpp
RSX/Overlays/overlay_list_view.cpp
RSX/Overlays/overlay_manager.cpp
RSX/Overlays/overlay_media_list_dialog.cpp
RSX/Overlays/overlay_message.cpp
RSX/Overlays/overlay_message_dialog.cpp
@@ -447,10 +465,10 @@ target_sources(rpcs3_emu PRIVATE
RSX/Overlays/overlay_perf_metrics.cpp
RSX/Overlays/overlay_progress_bar.cpp
RSX/Overlays/overlay_save_dialog.cpp
RSX/Overlays/overlay_shader_compile_notification.cpp
RSX/Overlays/overlay_user_list_dialog.cpp
RSX/Overlays/overlay_utils.cpp
RSX/Overlays/overlays.cpp
RSX/Overlays/overlay_shader_compile_notification.cpp
RSX/Overlays/overlay_trophy_notification.cpp
RSX/Overlays/Shaders/shader_loading_dialog.cpp
RSX/Overlays/Shaders/shader_loading_dialog_native.cpp
@@ -538,7 +556,7 @@ endif()
target_link_libraries(rpcs3_emu
PUBLIC
3rdparty::ffmpeg
3rdparty::ffmpeg 3rdparty::sdl2
3rdparty::opengl 3rdparty::stblib
3rdparty::vulkan 3rdparty::glew
3rdparty::libusb 3rdparty::wolfssl
+35 -16
View File
@@ -3,35 +3,54 @@
#include "util/types.hpp"
#include "Utilities/StrFmt.h"
namespace logs
{
struct message;
}
// Error code type (return type), implements error reporting.
class error_code
{
s32 value;
public:
error_code() = default;
// Implementation must be provided independently
static s32 error_report(s32 result, const char* fmt, const fmt_type_info* sup, const u64* args);
// Common constructor
template<typename ET>
error_code(const ET& value)
: value(error_report(static_cast<s32>(value), " : %s", fmt::type_info_v<ET>, fmt_args_t<ET>{fmt_unveil<ET>::get(value)}))
template <typename ET> requires requires (ET v) { static_cast<s32>(v); }
error_code(const logs::message* ch, const ET& value) noexcept
: value(error_report(static_cast<s32>(value), ch, " : %s", fmt::type_info_v<ET>, fmt_args_t<ET>{fmt_unveil<ET>::get(value)}))
{
}
// Error constructor (2 args)
template<typename ET, typename T>
error_code(const ET& value, const T& arg)
: value(error_report(static_cast<s32>(value), " : %s, %s", fmt::type_info_v<ET, T>, fmt_args_t<ET, T>{fmt_unveil<ET>::get(value), fmt_unveil<T>::get(arg)}))
template <typename ET, typename T> requires requires (ET v) { static_cast<s32>(v); }
error_code(const logs::message* ch, const ET& value, const T& arg) noexcept
: value(error_report(static_cast<s32>(value), ch, " : %s, %s", fmt::type_info_v<ET, T>, fmt_args_t<ET, T>{fmt_unveil<ET>::get(value), fmt_unveil<T>::get(arg)}))
{
}
// Formatting constructor (error, format string, variadic list)
template <typename ET, typename... Args> requires (sizeof...(Args) > 0)
error_code(const ET& value, const const_str& fmt, const Args&... args)
: value(error_report(static_cast<s32>(value), fmt, fmt::type_info_v<Args...>, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...}))
template <typename ET, typename... Args> requires requires (ET v) { static_cast<s32>(v); }
error_code(const logs::message* ch, const ET& value, const const_str& fmt, const Args&... args) noexcept
: value(error_report(static_cast<s32>(value), ch, fmt, fmt::type_info_v<Args...>, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...}))
{
}
public:
// Implementation must be provided independently
static s32 error_report(s32 result, const logs::message* channel, const char* fmt, const fmt_type_info* sup, const u64* args);
error_code() = default;
// Constructor without channel
template <typename... Args> requires (sizeof...(Args) > 0 && !(std::is_same_v<std::decay_t<std::remove_pointer_t<Args>>, logs::message> || ...))
error_code(const Args&... args) noexcept
: error_code(std::add_pointer_t<const logs::message>{}, args...)
{
}
// Constructor with channel
template <typename... Args>
error_code(const logs::message& ch, const Args&... args) noexcept
: error_code(std::addressof(ch), args...)
{
}
@@ -51,7 +70,7 @@ enum CellNotAnError : s32
// Constructor specialization that doesn't trigger reporting
template <>
constexpr FORCE_INLINE error_code::error_code(const CellNotAnError& value)
constexpr FORCE_INLINE error_code::error_code(const CellNotAnError& value) noexcept
: value(value)
{
}
+58
View File
@@ -0,0 +1,58 @@
#include "stdafx.h"
#include "Emu/IdManager.h"
#include "Emu/Cell/PPUModule.h"
#include "Utilities/Thread.h"
#include "Emu/Cell/lv2/sys_spu.h"
#include "Emu/Cell/lv2/sys_sync.h"
#include <thread>
// SONIC THE HEDGEDOG: a fix for a race condition between SPUs and PPUs causing missing graphics (SNR is overriden when non-empty)
void WaitForSPUsToEmptySNRs(ppu_thread& ppu, u32 spu_id, u32 snr_mask)
{
ppu.state += cpu_flag::wait;
auto [spu, group] = lv2_spu_group::get_thread(spu_id);
if ((!spu && spu_id != umax) || snr_mask % 4 == 0)
{
return;
}
// Wait until specified SNRs are reported empty at least once
for (bool has_busy = true; has_busy && !ppu.is_stopped(); std::this_thread::yield())
{
has_busy = false;
auto for_one = [&](u32, spu_thread& spu)
{
if ((snr_mask & 1) && spu.ch_snr1.get_count())
{
has_busy = true;
return;
}
if ((snr_mask & 2) && spu.ch_snr2.get_count())
{
has_busy = true;
}
};
if (spu)
{
// Wait for a single SPU
for_one(spu->id, *spu);
}
else
{
// Wait for all SPUs
idm::select<named_thread<spu_thread>>(for_one);
}
}
}
DECLARE(ppu_module_manager::hle_patches)("RPCS3_HLE_LIBRARY", []()
{
REG_FUNC(RPCS3_HLE_LIBRARY, WaitForSPUsToEmptySNRs);
});
+1 -1
View File
@@ -163,7 +163,7 @@ bool statichle_handler::check_against_patterns(vm::cptr<u8>& data, u32 size, u32
}
const auto sfunc = &::at32(smodule->functions, pat.fnid);
const u32 target = g_fxo->get<ppu_function_manager>().func_addr(sfunc->index) + 4;
const u32 target = g_fxo->get<ppu_function_manager>().func_addr(sfunc->index, true);
// write stub
vm::write32(addr, ppu_instructions::LIS(0, (target&0xFFFF0000)>>16));
+11 -15
View File
@@ -282,15 +282,10 @@ public:
struct AudioReader
{
u32 addr;
u32 size;
bool init;
bool has_ats;
AudioReader()
: init(false)
{
}
u32 addr{};
u32 size{};
bool init{};
bool has_ats{};
} reader;
@@ -304,13 +299,14 @@ public:
u32 memBias = 0;
AdecTask task;
u64 last_pts, first_pts;
u64 last_pts{};
u64 first_pts{};
u32 ch_out;
u32 ch_cfg;
u32 frame_size;
u32 sample_rate;
bool use_ats_headers;
u32 ch_out{};
u32 ch_cfg{};
u32 frame_size{};
u32 sample_rate{};
bool use_ats_headers{};
AudioDecoder(s32 type, u32 addr, u32 size, vm::ptr<CellAdecCbMsg> func, u32 arg)
: ppu_thread({}, "", 0)
+1 -1
View File
@@ -427,5 +427,5 @@ using cell_audio = named_thread<cell_audio_thread>;
namespace audio
{
cell_audio_config::raw_config get_raw_config();
void configure_audio(bool force_reset = false);
extern void configure_audio(bool force_reset = false);
}
+1 -1
View File
@@ -39,7 +39,7 @@ audio_out_configuration::audio_out_configuration()
std::vector<CellAudioOutSoundMode>& primary_modes = primary_output.sound_modes;
std::vector<CellAudioOutSoundMode>& secondary_modes = secondary_output.sound_modes;
const psf::registry sfo = psf::load_object(fs::file(Emu.GetSfoDir(true) + "/PARAM.SFO"));
const psf::registry sfo = psf::load_object(Emu.GetSfoDir(true) + "/PARAM.SFO");
const s32 sound_format = psf::get_integer(sfo, "SOUND_FORMAT", psf::sound_format_flag::lpcm_2); // Default to Linear PCM 2 Ch.
const bool supports_lpcm_2 = (sound_format & psf::sound_format_flag::lpcm_2); // Linear PCM 2 Ch.
+1 -1
View File
@@ -298,7 +298,7 @@ error_code cellAudioOutGetAvailableDeviceInfo(u32 count, vm::ptr<CellAudioOutDev
error_code cellVideoOutSetGamma(u32 videoOut, f32 gamma)
{
cellAvconfExt.warning("cellVideoOutSetGamma(videoOut=%d, gamma=%f)", videoOut, gamma);
cellAvconfExt.trace("cellVideoOutSetGamma(videoOut=%d, gamma=%f)", videoOut, gamma);
if (gamma < 0.8f || gamma > 1.2f)
{
+8 -8
View File
@@ -147,7 +147,7 @@ void camera_context::save(utils::serial& ar)
GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellCamera);
ar(notify_data_map, start_timestamp, read_mode, is_streaming, is_attached, is_open, info, attr, frame_num);
ar(notify_data_map, start_timestamp_us, read_mode, is_streaming, is_attached, is_open, info, attr, frame_num);
}
static bool check_dev_num(s32 dev_num)
@@ -1268,7 +1268,7 @@ error_code cellCameraStart(s32 dev_num)
// TODO: Yet another CELL_CAMERA_ERROR_TIMEOUT
g_camera.start_timestamp = get_guest_system_time();
g_camera.start_timestamp_us = get_guest_system_time();
g_camera.is_streaming = true;
return CELL_OK;
@@ -1372,7 +1372,7 @@ error_code cellCameraReadEx(s32 dev_num, vm::ptr<CellCameraReadEx> read)
return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND;
}
g_camera.bytes_read = bytes_read;
g_camera.bytes_read = ::narrow<u32>(bytes_read);
cellCamera.trace("cellCameraRead: frame_number=%d, width=%d, height=%d. bytes_read=%d (passed to game: frame=%d, bytesread=%d)",
frame_number, width, height, bytes_read, read ? read->frame.get() : 0, read ? read->bytesread.get() : 0);
@@ -1385,18 +1385,18 @@ error_code cellCameraReadEx(s32 dev_num, vm::ptr<CellCameraReadEx> read)
if (has_new_frame)
{
g_camera.frame_timestamp = (get_guest_system_time() - g_camera.start_timestamp);
g_camera.frame_timestamp_us = get_guest_system_time() - g_camera.start_timestamp_us;
}
if (read) // NULL returns CELL_OK
{
read->timestamp = g_camera.frame_timestamp;
read->timestamp = g_camera.frame_timestamp_us;
read->frame = g_camera.frame_num;
read->bytesread = g_camera.bytes_read;
auto& shared_data = g_fxo->get<gem_camera_shared>();
shared_data.frame_timestamp.store(read->timestamp);
shared_data.frame_timestamp_us.store(read->timestamp);
}
return CELL_OK;
@@ -1672,7 +1672,7 @@ void camera_context::operator()()
const u64 camera_id = 0;
data2 = image_data_size << 32 | buffer_number << 16 | camera_id;
data3 = get_guest_system_time() - start_timestamp; // timestamp
data3 = get_guest_system_time() - start_timestamp_us; // timestamp
}
else // CELL_CAMERA_READ_FUNCCALL, also default
{
@@ -1801,7 +1801,7 @@ void camera_context::reset_state()
pbuf_locked[0] = false;
pbuf_locked[1] = false;
has_new_frame = false;
frame_timestamp = 0;
frame_timestamp_us = 0;
bytes_read = 0;
if (info.buffer)
+4 -4
View File
@@ -384,7 +384,7 @@ struct CellCameraReadEx
be_t<s32> version;
be_t<u32> frame;
be_t<u32> bytesread;
be_t<s64> timestamp;
be_t<u64> timestamp; // system_time_t (microseconds)
vm::bptr<u8> pbuf;
};
@@ -422,7 +422,7 @@ public:
shared_mutex mutex;
shared_mutex mutex_notify_data_map;
u64 start_timestamp = 0;
u64 start_timestamp_us = 0;
atomic_t<u8> read_mode{CELL_CAMERA_READ_FUNCCALL};
atomic_t<bool> is_streaming{false};
@@ -444,7 +444,7 @@ public:
attr_t attr[500]{};
atomic_t<bool> has_new_frame = false;
atomic_t<u32> frame_num = 0;
atomic_t<u32> frame_timestamp = 0;
atomic_t<u64> frame_timestamp_us = 0;
atomic_t<u32> bytes_read = 0;
atomic_t<u8> init = 0;
@@ -471,7 +471,7 @@ using camera_thread = named_thread<camera_context>;
/// Shared data between cellGem and cellCamera
struct gem_camera_shared
{
atomic_t<s64> frame_timestamp{}; // latest read timestamp from cellCamera (cellCameraRead(Ex))
atomic_t<u64> frame_timestamp_us{}; // latest read timestamp from cellCamera (cellCameraRead(Ex))
atomic_t<s32> width{640};
atomic_t<s32> height{480};
atomic_t<s32> size{0};
+18 -10
View File
@@ -415,7 +415,7 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
else
{
// TODO: Is cellHddGameCheck really responsible for writing the information in get->getParam ? (If not, delete this else)
const psf::registry psf = psf::load_object(fs::file(local_dir +"/PARAM.SFO"));
const psf::registry psf = psf::load_object(local_dir + "/PARAM.SFO");
// Some following fields may be zero in old FW 1.00 version PARAM.SFO
if (psf.contains("PARENTAL_LEVEL")) get->getParam.parentalLevel = ::at32(psf, "PARENTAL_LEVEL").as_integer();
@@ -466,7 +466,7 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
// psf::assign(sfo, "CATEGORY", psf::string(3, "HG"));
// }
// psf::assign(sfo, "TITLE_ID", psf::string(CELL_GAME_SYSP_TITLEID_SIZE, setParam->titleId));
// psf::assign(sfo, "TITLE_ID", psf::string(TITLEID_SFO_ENTRY_SIZE, setParam->titleId));
// psf::assign(sfo, "TITLE", psf::string(CELL_GAME_SYSP_TITLE_SIZE, setParam->title));
// psf::assign(sfo, "VERSION", psf::string(CELL_GAME_SYSP_VERSION_SIZE, setParam->dataVersion));
// psf::assign(sfo, "PARENTAL_LEVEL", +setParam->parentalLevel);
@@ -670,7 +670,7 @@ error_code cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr
*attributes = 0; // TODO
// TODO: dirName might be a read only string when BootCheck is called on a disc game. (e.g. Ben 10 Ultimate Alien: Cosmic Destruction)
sfo = psf::load_object(fs::file(vfs::get("/dev_bdvd/PS3_GAME/PARAM.SFO")));
sfo = psf::load_object(vfs::get("/dev_bdvd/PS3_GAME/PARAM.SFO"));
}
else if (cat == "GD")
{
@@ -679,7 +679,7 @@ error_code cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr
*type = CELL_GAME_GAMETYPE_DISC;
*attributes = CELL_GAME_ATTRIBUTE_PATCH; // TODO
sfo = psf::load_object(fs::file(vfs::get(Emu.GetDir() + "PARAM.SFO")));
sfo = psf::load_object(vfs::get(Emu.GetDir() + "PARAM.SFO"));
}
else
{
@@ -688,7 +688,7 @@ error_code cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr
*type = CELL_GAME_GAMETYPE_HDD;
*attributes = 0; // TODO
sfo = psf::load_object(fs::file(vfs::get(Emu.GetDir() + "PARAM.SFO")));
sfo = psf::load_object(vfs::get(Emu.GetDir() + "PARAM.SFO"));
dir = Emu.GetTitleID();
}
@@ -723,7 +723,7 @@ error_code cellGamePatchCheck(vm::ptr<CellGameContentSize> size, vm::ptr<void> r
return CELL_GAME_ERROR_NOTPATCH;
}
psf::registry sfo = psf::load_object(fs::file(vfs::get(Emu.GetDir() + "PARAM.SFO")));
psf::registry sfo = psf::load_object(vfs::get(Emu.GetDir() + "PARAM.SFO"));
auto& perm = g_fxo->get<content_permission>();
@@ -990,7 +990,7 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
psf::assign(sfo, "CATEGORY", psf::string(3, "GD"));
}
psf::assign(sfo, "TITLE_ID", psf::string(CELL_GAME_SYSP_TITLEID_SIZE, setParam->titleId));
psf::assign(sfo, "TITLE_ID", psf::string(TITLEID_SFO_ENTRY_SIZE, setParam->titleId, true));
psf::assign(sfo, "TITLE", psf::string(CELL_GAME_SYSP_TITLE_SIZE, setParam->title));
psf::assign(sfo, "VERSION", psf::string(CELL_GAME_SYSP_VERSION_SIZE, setParam->dataVersion));
psf::assign(sfo, "PARENTAL_LEVEL", +setParam->parentalLevel);
@@ -1005,6 +1005,14 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
psf::assign(sfo, fmt::format("TITLE_%02d", i), psf::string(CELL_GAME_SYSP_TITLE_SIZE, setParam->titleLang[i]));
}
if (!psf::check_registry(sfo))
{
// This results in CELL_OK, broken SFO and CELL_GAMEDATA_ERROR_BROKEN on the next load
// Avoid creation for now
cellGame.error("Broken SFO paramters: %s", sfo);
return CELL_OK;
}
fs::pending_file temp(vfs::get(dir + "/PARAM.SFO"));
temp.file.write(psf::save_object(sfo));
ensure(temp.commit());
@@ -1125,7 +1133,7 @@ error_code cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<c
perm.sfo =
{
{ "CATEGORY", psf::string(3, "GD") },
{ "TITLE_ID", psf::string(CELL_GAME_SYSP_TITLEID_SIZE, init->titleId) },
{ "TITLE_ID", psf::string(TITLEID_SFO_ENTRY_SIZE, init->titleId) },
{ "TITLE", psf::string(CELL_GAME_SYSP_TITLE_SIZE, init->title) },
{ "VERSION", psf::string(CELL_GAME_SYSP_VERSION_SIZE, init->version) },
};
@@ -1698,7 +1706,7 @@ error_code cellDiscGameGetBootDiscInfo(vm::ptr<CellDiscGameSystemFileParam> getP
}
// Always sets 0 at first dword
*utils::bless<nse_t<u32, 1>>(getParam->titleId + 0) = 0;
write_to_ptr<u32>(getParam->titleId, 0);
// This is also called by non-disc games, see NPUB90029
static const std::string dir = "/dev_bdvd/PS3_GAME"s;
@@ -1708,7 +1716,7 @@ error_code cellDiscGameGetBootDiscInfo(vm::ptr<CellDiscGameSystemFileParam> getP
return CELL_DISCGAME_ERROR_NOT_DISCBOOT;
}
const psf::registry psf = psf::load_object(fs::file(vfs::get(dir + "/PARAM.SFO")));
const psf::registry psf = psf::load_object(vfs::get(dir + "/PARAM.SFO"));
if (psf.contains("PARENTAL_LEVEL")) getParam->parentalLevel = ::at32(psf, "PARENTAL_LEVEL").as_integer();
if (psf.contains("TITLE_ID")) strcpy_trunc(getParam->titleId, ::at32(psf, "TITLE_ID").as_string());
+5
View File
@@ -216,6 +216,11 @@ enum // old consts
CELL_DISCGAME_SYSP_TITLEID_SIZE=10,
};
enum
{
TITLEID_SFO_ENTRY_SIZE = 16, // This is the true length on PS3 (TODO: Fix in more places)
};
struct CellGameDataSystemFileParam
{
char title[CELL_GAMEDATA_SYSP_TITLE_SIZE];
+4 -4
View File
@@ -529,7 +529,7 @@ void cellGcmSetFlipHandler(vm::ptr<void(u32)> handler)
{
cellGcmSys.warning("cellGcmSetFlipHandler(handler=*0x%x)", handler);
if (const auto rsx = rsx::get_current_renderer(); rsx->is_inited)
if (const auto rsx = rsx::get_current_renderer(); rsx->is_initialized)
{
rsx->flip_handler = handler;
}
@@ -681,7 +681,7 @@ void cellGcmSetUserHandler(vm::ptr<void(u32)> handler)
{
cellGcmSys.warning("cellGcmSetUserHandler(handler=*0x%x)", handler);
if (const auto rsx = rsx::get_current_renderer(); rsx->is_inited)
if (const auto rsx = rsx::get_current_renderer(); rsx->is_initialized)
{
rsx->user_handler = handler;
}
@@ -707,7 +707,7 @@ void cellGcmSetVBlankHandler(vm::ptr<void(u32)> handler)
{
cellGcmSys.warning("cellGcmSetVBlankHandler(handler=*0x%x)", handler);
if (const auto rsx = rsx::get_current_renderer(); rsx->is_inited)
if (const auto rsx = rsx::get_current_renderer(); rsx->is_initialized)
{
rsx->vblank_handler = handler;
}
@@ -923,7 +923,7 @@ void cellGcmSetQueueHandler(vm::ptr<void(u32)> handler)
{
cellGcmSys.warning("cellGcmSetQueueHandler(handler=*0x%x)", handler);
if (const auto rsx = rsx::get_current_renderer(); rsx->is_inited)
if (const auto rsx = rsx::get_current_renderer(); rsx->is_initialized)
{
rsx->queue_handler = handler;
}
+201 -73
View File
@@ -12,7 +12,12 @@
#include "Emu/RSX/Overlays/overlay_cursor.h"
#include "Input/pad_thread.h"
#ifdef HAVE_LIBEVDEV
#include "Input/evdev_gun_handler.h"
#endif
#include <cmath> // for fmod
#include <type_traits>
LOG_CHANNEL(cellGem);
@@ -88,6 +93,46 @@ void fmt_class_string<CellGemVideoConvertFormatEnum>::format(std::string& out, u
// * HLE helper structs *
// **********************
#ifdef HAVE_LIBEVDEV
struct gun_handler
{
public:
gun_handler() = default;
static constexpr auto thread_name = "Evdev Gun Thread"sv;
evdev_gun_handler handler{};
atomic_t<u32> num_devices{0};
void operator()()
{
if (g_cfg.io.move != move_handler::gun)
{
return;
}
while (thread_ctrl::state() != thread_state::aborting && !Emu.IsStopped())
{
const bool is_active = !Emu.IsPaused() && handler.is_init();
if (is_active)
{
for (u32 i = 0; i < num_devices; i++)
{
std::scoped_lock lock(handler.mutex);
handler.poll(i);
}
}
thread_ctrl::wait_for(is_active ? 1000 : 10000);
}
}
};
using gun_thread = named_thread<gun_handler>;
#endif
struct gem_config_data
{
public:
@@ -170,7 +215,7 @@ public:
shared_mutex mtx;
u64 start_timestamp = 0;
u64 start_timestamp_us = 0;
// helper functions
bool is_controller_ready(u32 gem_num) const
@@ -214,6 +259,16 @@ public:
connected_controllers = 1;
break;
}
#ifdef HAVE_LIBEVDEV
case move_handler::gun:
{
gun_thread& gun = g_fxo->get<gun_thread>();
std::scoped_lock lock(gun.handler.mutex);
connected_controllers = gun.handler.init() ? gun.handler.get_num_guns() : 0;
gun.num_devices = connected_controllers;
break;
}
#endif
case move_handler::null:
default:
break;
@@ -244,10 +299,20 @@ public:
return;
}
GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellGem);
[[maybe_unused]] const s32 version = GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellGem);
ar(attribute, vc_attribute, status_flags, enable_pitch_correction, inertial_counter, controllers
, connected_controllers, update_started, camera_frame, memory_ptr, start_timestamp);
, connected_controllers, update_started, camera_frame, memory_ptr);
if (version == 1 && !ar.is_writing())
{
u32 ts = ar;
start_timestamp_us = ts;
}
else
{
ar(start_timestamp_us);
}
}
gem_config_data(utils::serial& ar)
@@ -646,9 +711,10 @@ static inline void ds3_get_stick_values(const std::shared_ptr<Pad>& pad, s32& x_
}
}
static void ds3_pos_to_gem_image_state(const u32 port_no, const gem_config::gem_controller& controller, vm::ptr<CellGemImageState>& gem_image_state)
template <typename T>
static void ds3_pos_to_gem_state(const u32 port_no, const gem_config::gem_controller& controller, T& gem_state)
{
if (!is_input_allowed())
if (!gem_state || !is_input_allowed())
{
return;
}
@@ -666,30 +732,14 @@ static void ds3_pos_to_gem_image_state(const u32 port_no, const gem_config::gem_
s32 ds3_pos_x, ds3_pos_y;
ds3_get_stick_values(pad, ds3_pos_x, ds3_pos_y);
pos_to_gem_image_state(port_no, controller, gem_image_state, ds3_pos_x, ds3_pos_y, ds3_max_x, ds3_max_y);
}
static void ds3_pos_to_gem_state(const u32 port_no, const gem_config::gem_controller& controller, vm::ptr<CellGemState>& gem_state)
{
if (!is_input_allowed())
if constexpr (std::is_same<T, vm::ptr<CellGemState>>::value)
{
return;
pos_to_gem_state(port_no, controller, gem_state, ds3_pos_x, ds3_pos_y, ds3_max_x, ds3_max_y);
}
std::lock_guard lock(pad::g_pad_mutex);
const auto handler = pad::get_current_handler();
const auto& pad = ::at32(handler->GetPads(), port_no);
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
else if constexpr (std::is_same<T, vm::ptr<CellGemImageState>>::value)
{
return;
pos_to_gem_image_state(port_no, controller, gem_state, ds3_pos_x, ds3_pos_y, ds3_max_x, ds3_max_y);
}
s32 ds3_pos_x, ds3_pos_y;
ds3_get_stick_values(pad, ds3_pos_x, ds3_pos_y);
pos_to_gem_state(port_no, controller, gem_state, ds3_pos_x, ds3_pos_y, ds3_max_x, ds3_max_y);
}
/**
@@ -803,31 +853,8 @@ static bool mouse_input_to_pad(const u32 mouse_no, be_t<u16>& digital_buttons, b
return true;
}
static void mouse_pos_to_gem_image_state(const u32 mouse_no, const gem_config::gem_controller& controller, vm::ptr<CellGemImageState>& gem_image_state)
{
if (!gem_image_state || !is_input_allowed())
{
return;
}
auto& handler = g_fxo->get<MouseHandlerBase>();
std::scoped_lock lock(handler.mutex);
// Make sure that the mouse handler is initialized
handler.Init(std::min<u32>(g_fxo->get<gem_config>().attribute.max_connect, CELL_GEM_MAX_NUM));
if (mouse_no >= handler.GetMice().size())
{
return;
}
const auto& mouse = ::at32(handler.GetMice(), mouse_no);
pos_to_gem_image_state(mouse_no, controller, gem_image_state, mouse.x_pos, mouse.y_pos, mouse.x_max, mouse.y_max);
}
static void mouse_pos_to_gem_state(const u32 mouse_no, const gem_config::gem_controller& controller, vm::ptr<CellGemState>& gem_state)
template <typename T>
static void mouse_pos_to_gem_state(const u32 mouse_no, const gem_config::gem_controller& controller, T& gem_state)
{
if (!gem_state || !is_input_allowed())
{
@@ -848,9 +875,85 @@ static void mouse_pos_to_gem_state(const u32 mouse_no, const gem_config::gem_con
const auto& mouse = ::at32(handler.GetMice(), mouse_no);
pos_to_gem_state(mouse_no, controller, gem_state, mouse.x_pos, mouse.y_pos, mouse.x_max, mouse.y_max);
if constexpr (std::is_same<T, vm::ptr<CellGemState>>::value)
{
pos_to_gem_state(mouse_no, controller, gem_state, mouse.x_pos, mouse.y_pos, mouse.x_max, mouse.y_max);
}
else if constexpr (std::is_same<T, vm::ptr<CellGemImageState>>::value)
{
pos_to_gem_image_state(mouse_no, controller, gem_state, mouse.x_pos, mouse.y_pos, mouse.x_max, mouse.y_max);
}
}
#ifdef HAVE_LIBEVDEV
static bool gun_input_to_pad(const u32 gem_no, be_t<u16>& digital_buttons, be_t<u16>& analog_t)
{
digital_buttons = 0;
analog_t = 0;
if (!is_input_allowed())
return false;
gun_thread& gun = g_fxo->get<gun_thread>();
std::scoped_lock lock(gun.handler.mutex);
if (gun.handler.get_button(gem_no, gun_button::btn_left) == 1)
digital_buttons |= CELL_GEM_CTRL_T;
if (gun.handler.get_button(gem_no, gun_button::btn_right) == 1)
digital_buttons |= CELL_GEM_CTRL_MOVE;
if (gun.handler.get_button(gem_no, gun_button::btn_middle) == 1)
digital_buttons |= CELL_GEM_CTRL_START;
if (gun.handler.get_button(gem_no, gun_button::btn_1) == 1)
digital_buttons |= CELL_GEM_CTRL_CROSS;
if (gun.handler.get_button(gem_no, gun_button::btn_2) == 1)
digital_buttons |= CELL_GEM_CTRL_CIRCLE;
if (gun.handler.get_button(gem_no, gun_button::btn_3) == 1)
digital_buttons |= CELL_GEM_CTRL_SELECT;
if (gun.handler.get_button(gem_no, gun_button::btn_5) == 1)
digital_buttons |= CELL_GEM_CTRL_TRIANGLE;
if (gun.handler.get_button(gem_no, gun_button::btn_6) == 1)
digital_buttons |= CELL_GEM_CTRL_SQUARE;
analog_t = gun.handler.get_button(gem_no, gun_button::btn_left) ? 0xFFFF : 0;
return true;
}
template <typename T>
static void gun_pos_to_gem_state(const u32 gem_no, const gem_config::gem_controller& controller, T& gem_state)
{
if (!gem_state || !is_input_allowed())
return;
int x_pos, y_pos, x_max, y_max;
{
gun_thread& gun = g_fxo->get<gun_thread>();
std::scoped_lock lock(gun.handler.mutex);
x_pos = gun.handler.get_axis_x(gem_no);
y_pos = gun.handler.get_axis_y(gem_no);
x_max = gun.handler.get_axis_x_max(gem_no);
y_max = gun.handler.get_axis_y_max(gem_no);
}
if constexpr (std::is_same<T, vm::ptr<CellGemState>>::value)
{
pos_to_gem_state(gem_no, controller, gem_state, x_pos, y_pos, x_max, y_max);
}
else if constexpr (std::is_same<T, vm::ptr<CellGemImageState>>::value)
{
pos_to_gem_image_state(gem_no, controller, gem_state, x_pos, y_pos, x_max, y_max);
}
}
#endif
// *********************
// * cellGem functions *
// *********************
@@ -1232,23 +1335,31 @@ error_code cellGemGetImageState(u32 gem_num, vm::ptr<CellGemImageState> gem_imag
*gem_image_state = {};
if (g_cfg.io.move == move_handler::fake || g_cfg.io.move == move_handler::mouse)
if (g_cfg.io.move != move_handler::null)
{
auto& shared_data = g_fxo->get<gem_camera_shared>();
gem_image_state->frame_timestamp = shared_data.frame_timestamp.load();
gem_image_state->frame_timestamp = shared_data.frame_timestamp_us.load();
gem_image_state->timestamp = gem_image_state->frame_timestamp + 10;
gem_image_state->r = gem.controllers[gem_num].radius; // Radius in camera pixels
gem_image_state->distance = gem.controllers[gem_num].distance; // 1.5 meters away from camera
gem_image_state->visible = gem.is_controller_ready(gem_num);
gem_image_state->r_valid = true;
if (g_cfg.io.move == move_handler::fake)
switch (g_cfg.io.move)
{
ds3_pos_to_gem_image_state(gem_num, gem.controllers[gem_num], gem_image_state);
}
else if (g_cfg.io.move == move_handler::mouse)
{
mouse_pos_to_gem_image_state(gem_num, gem.controllers[gem_num], gem_image_state);
case move_handler::fake:
ds3_pos_to_gem_state(gem_num, gem.controllers[gem_num], gem_image_state);
break;
case move_handler::mouse:
mouse_pos_to_gem_state(gem_num, gem.controllers[gem_num], gem_image_state);
break;
#ifdef HAVE_LIBEVDEV
case move_handler::gun:
gun_pos_to_gem_state(gem_num, gem.controllers[gem_num], gem_image_state);
break;
#endif
case move_handler::null:
fmt::throw_exception("Unreachable");
}
}
@@ -1280,21 +1391,29 @@ error_code cellGemGetInertialState(u32 gem_num, u32 state_flag, u64 timestamp, v
*inertial_state = {};
if (g_cfg.io.move == move_handler::fake || g_cfg.io.move == move_handler::mouse)
if (g_cfg.io.move != move_handler::null)
{
ds3_input_to_ext(gem_num, gem.controllers[gem_num], inertial_state->ext);
inertial_state->timestamp = (get_guest_system_time() - gem.start_timestamp);
inertial_state->timestamp = (get_guest_system_time() - gem.start_timestamp_us);
inertial_state->counter = gem.inertial_counter++;
inertial_state->accelerometer[0] = 10; // Current gravity in m/s²
if (g_cfg.io.move == move_handler::fake)
switch (g_cfg.io.move)
{
case move_handler::fake:
ds3_input_to_pad(gem_num, inertial_state->pad.digitalbuttons, inertial_state->pad.analog_T);
}
else if (g_cfg.io.move == move_handler::mouse)
{
break;
case move_handler::mouse:
mouse_input_to_pad(gem_num, inertial_state->pad.digitalbuttons, inertial_state->pad.analog_T);
break;
#ifdef HAVE_LIBEVDEV
case move_handler::gun:
gun_input_to_pad(gem_num, inertial_state->pad.digitalbuttons, inertial_state->pad.analog_T);
break;
#endif
case move_handler::null:
fmt::throw_exception("Unreachable");
}
}
@@ -1442,7 +1561,7 @@ error_code cellGemGetState(u32 gem_num, u32 flag, u64 time_parameter, vm::ptr<Ce
*gem_state = {};
if (g_cfg.io.move == move_handler::fake || g_cfg.io.move == move_handler::mouse)
if (g_cfg.io.move != move_handler::null)
{
ds3_input_to_ext(gem_num, gem.controllers[gem_num], gem_state->ext);
@@ -1452,19 +1571,28 @@ error_code cellGemGetState(u32 gem_num, u32 flag, u64 time_parameter, vm::ptr<Ce
tracking_flags |= CELL_GEM_TRACKING_FLAG_POSITION_TRACKED;
gem_state->tracking_flags = tracking_flags;
gem_state->timestamp = (get_guest_system_time() - gem.start_timestamp);
gem_state->timestamp = (get_guest_system_time() - gem.start_timestamp_us);
gem_state->camera_pitch_angle = 0.f;
gem_state->quat[3] = 1.f;
if (g_cfg.io.move == move_handler::fake)
switch (g_cfg.io.move)
{
case move_handler::fake:
ds3_input_to_pad(gem_num, gem_state->pad.digitalbuttons, gem_state->pad.analog_T);
ds3_pos_to_gem_state(gem_num, gem.controllers[gem_num], gem_state);
}
else if (g_cfg.io.move == move_handler::mouse)
{
break;
case move_handler::mouse:
mouse_input_to_pad(gem_num, gem_state->pad.digitalbuttons, gem_state->pad.analog_T);
mouse_pos_to_gem_state(gem_num, gem.controllers[gem_num], gem_state);
break;
#ifdef HAVE_LIBEVDEV
case move_handler::gun:
gun_input_to_pad(gem_num, gem_state->pad.digitalbuttons, gem_state->pad.analog_T);
gun_pos_to_gem_state(gem_num, gem.controllers[gem_num], gem_state);
break;
#endif
case move_handler::null:
fmt::throw_exception("Unreachable");
}
}
@@ -1645,7 +1773,7 @@ error_code cellGemInit(ppu_thread& ppu, vm::cptr<CellGemAttribute> attribute)
}
// TODO: is this correct?
gem.start_timestamp = get_guest_system_time();
gem.start_timestamp_us = get_guest_system_time();
return CELL_OK;
}
@@ -1821,7 +1949,7 @@ error_code cellGemReset(u32 gem_num)
gem.reset_controller(gem_num);
// TODO: is this correct?
gem.start_timestamp = get_guest_system_time();
gem.start_timestamp_us = get_guest_system_time();
return CELL_OK;
}
+4 -4
View File
@@ -200,8 +200,8 @@ struct CellGemExtPortData
struct CellGemImageState
{
be_t<u64> frame_timestamp; // time the frame was captured by libCamera (usecs)
be_t<u64> timestamp; // time processing of the frame was finished (usecs)
be_t<u64> frame_timestamp; // time the frame was captured by libCamera. system_time_t (usecs)
be_t<u64> timestamp; // time processing of the frame was finished. system_time_t (usecs)
be_t<f32> u; // horizontal screen position in pixels
be_t<f32> v; // vertical screen position in pixels
be_t<f32> r; // size of sphere on screen in pixels
@@ -226,7 +226,7 @@ struct CellGemInertialState
be_t<f32> gyro_bias[4]; // gyro bias (radians/s)
CellGemPadData pad;
CellGemExtPortData ext;
be_t<u64> timestamp;
be_t<u64> timestamp; // system_time_t (microseconds)
be_t<s32> counter;
be_t<f32> temperature;
};
@@ -256,7 +256,7 @@ struct CellGemState
be_t<f32> handle_accel[4]; // acceleration of controller handle (mm/s²)
CellGemPadData pad;
CellGemExtPortData ext;
be_t<u64> timestamp;
be_t<u64> timestamp; // system_time_t (microseconds)
be_t<f32> temperature;
be_t<f32> camera_pitch_angle;
be_t<u32> tracking_flags;
+2 -2
View File
@@ -296,8 +296,8 @@ error_code cellGifDecReadHeader(vm::ptr<GifDecoder> mainHandle, vm::ptr<GifStrea
default: break; // TODO
}
if (*utils::bless<be_t<u32>>(buffer + 0) != 0x47494638u ||
(*utils::bless<le_t<u16>>(buffer + 4) != 0x6139u && *utils::bless<le_t<u16>>(buffer + 4) != 0x6137u)) // Error: The first 6 bytes are not a valid GIF signature
if (read_from_ptr<be_t<u32>>(buffer + 0) != 0x47494638u ||
(read_from_ptr<le_t<u16>>(buffer + 4) != 0x6139u && read_from_ptr<le_t<u16>>(buffer + 4) != 0x6137u)) // Error: The first 6 bytes are not a valid GIF signature
{
return CELL_GIFDEC_ERROR_STREAM_FORMAT; // Surprisingly there is no error code related with headerss
}
+3 -3
View File
@@ -248,7 +248,7 @@ error_code cellHttpUtilBuildRequestLine(vm::cptr<CellHttpRequestLine> req, vm::p
if (required)
{
*required = result.size();
*required = ::narrow<u32>(result.size());
}
return CELL_OK;
@@ -277,7 +277,7 @@ error_code cellHttpUtilBuildHeader(vm::cptr<CellHttpHeader> header, vm::ptr<char
if (required)
{
*required = result.size();
*required = ::narrow<u32>(result.size());
}
return CELL_OK;
@@ -336,7 +336,7 @@ error_code cellHttpUtilBuildUri(vm::cptr<CellHttpUri> uri, vm::ptr<char> buf, u3
fmt::append(result, "%s", uri->path);
}
const u32 size_needed = result.size() + 1; // Including '\0'
const u32 size_needed = ::narrow<u32>(result.size() + 1); // Including '\0'
if (buf)
{
+2 -2
View File
@@ -150,8 +150,8 @@ error_code cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellJpgDe
default: break; // TODO
}
if (*utils::bless<le_t<u32>>(buffer.get() + 0) != 0xE0FFD8FF || // Error: Not a valid SOI header
*utils::bless<u32>(buffer.get() + 6) != "JFIF"_u32) // Error: Not a valid JFIF string
if (read_from_ptr<le_t<u32>>(buffer.get() + 0) != 0xE0FFD8FF || // Error: Not a valid SOI header
read_from_ptr<u32>(buffer.get() + 6) != "JFIF"_u32) // Error: Not a valid JFIF string
{
return CELL_JPGDEC_ERROR_HEADER;
}
+3 -3
View File
@@ -119,7 +119,7 @@ error_code cellKbClearBuf(u32 port_no)
const KbInfo& current_info = handler.GetInfo();
if (port_no >= handler.GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
return CELL_KB_ERROR_NO_DEVICE;
return not_an_error(CELL_KB_ERROR_NO_DEVICE);
KbData& current_data = handler.GetData(port_no);
current_data.len = 0;
@@ -331,7 +331,7 @@ error_code cellKbRead(u32 port_no, vm::ptr<CellKbData> data)
const KbInfo& current_info = handler.GetInfo();
if (port_no >= handler.GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
return CELL_KB_ERROR_NO_DEVICE;
return not_an_error(CELL_KB_ERROR_NO_DEVICE);
KbData& current_data = handler.GetData(port_no);
@@ -474,7 +474,7 @@ error_code cellKbGetConfiguration(u32 port_no, vm::ptr<CellKbConfig> config)
const KbInfo& current_info = handler.GetInfo();
if (port_no >= handler.GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
return CELL_KB_ERROR_NO_DEVICE;
return not_an_error(CELL_KB_ERROR_NO_DEVICE);
// tests show that config is checked only after the device's status
if (!config)
+8 -8
View File
@@ -63,7 +63,7 @@ void MouseHandlerBase::save(utils::serial& ar)
error_code cellMouseInit(u32 max_connect)
{
sys_io.warning("cellMouseInit(max_connect=%d)", max_connect);
sys_io.notice("cellMouseInit(max_connect=%d)", max_connect);
auto& handler = g_fxo->get<MouseHandlerBase>();
@@ -104,7 +104,7 @@ error_code cellMouseClearBuf(u32 port_no)
if (port_no >= handler.GetMice().size() || current_info.status[port_no] != CELL_MOUSE_STATUS_CONNECTED)
{
return CELL_MOUSE_ERROR_NO_DEVICE;
return not_an_error(CELL_MOUSE_ERROR_NO_DEVICE);
}
handler.GetDataList(port_no).clear();
@@ -229,7 +229,7 @@ error_code cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
if (port_no >= handler.GetMice().size() || current_info.status[port_no] != CELL_MOUSE_STATUS_CONNECTED)
{
return CELL_MOUSE_ERROR_NO_DEVICE;
return not_an_error(CELL_MOUSE_ERROR_NO_DEVICE);
}
std::memset(data.get_ptr(), 0, data.size());
@@ -259,7 +259,7 @@ error_code cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
error_code cellMouseGetDataList(u32 port_no, vm::ptr<CellMouseDataList> data)
{
sys_io.warning("cellMouseGetDataList(port_no=%d, data=0x%x)", port_no, data);
sys_io.notice("cellMouseGetDataList(port_no=%d, data=0x%x)", port_no, data);
auto& handler = g_fxo->get<MouseHandlerBase>();
@@ -279,7 +279,7 @@ error_code cellMouseGetDataList(u32 port_no, vm::ptr<CellMouseDataList> data)
if (port_no >= handler.GetMice().size() || current_info.status[port_no] != CELL_MOUSE_STATUS_CONNECTED)
{
return CELL_MOUSE_ERROR_NO_DEVICE;
return not_an_error(CELL_MOUSE_ERROR_NO_DEVICE);
}
std::memset(data.get_ptr(), 0, data.size());
@@ -368,7 +368,7 @@ error_code cellMouseGetTabletDataList(u32 port_no, vm::ptr<CellMouseTabletDataLi
if (port_no >= handler.GetMice().size() || current_info.status[port_no] != CELL_MOUSE_STATUS_CONNECTED)
{
return CELL_MOUSE_ERROR_NO_DEVICE;
return not_an_error(CELL_MOUSE_ERROR_NO_DEVICE);
}
std::memset(data.get_ptr(), 0, data.size());
@@ -406,7 +406,7 @@ error_code cellMouseGetTabletDataList(u32 port_no, vm::ptr<CellMouseTabletDataLi
error_code cellMouseGetRawData(u32 port_no, vm::ptr<CellMouseRawData> data)
{
sys_io.warning("cellMouseGetRawData(port_no=%d, data=*0x%x)", port_no, data);
sys_io.notice("cellMouseGetRawData(port_no=%d, data=*0x%x)", port_no, data);
auto& handler = g_fxo->get<MouseHandlerBase>();
@@ -424,7 +424,7 @@ error_code cellMouseGetRawData(u32 port_no, vm::ptr<CellMouseRawData> data)
if (port_no >= handler.GetMice().size() || current_info.status[port_no] != CELL_MOUSE_STATUS_CONNECTED)
{
return CELL_MOUSE_ERROR_NO_DEVICE;
return not_an_error(CELL_MOUSE_ERROR_NO_DEVICE);
}
std::memset(data.get_ptr(), 0, data.size());
+37 -12
View File
@@ -5,6 +5,8 @@
#include "Emu/Cell/lv2/sys_sync.h"
#include "Emu/Cell/timers.hpp"
#include "Emu/Io/interception.h"
#include "Emu/RSX/Overlays/overlay_manager.h"
#include "Emu/RSX/Overlays/overlay_message_dialog.h"
#include "cellSysutil.h"
@@ -135,19 +137,21 @@ struct msg_dlg_thread_info
using msg_dlg_thread = named_thread<msg_dlg_thread_info>;
// variable used to immediately get the response from auxiliary message dialogs (callbacks would be async)
atomic_t<s32> g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE;
// forward declaration for open_msg_dialog
error_code cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialogCallback> callback, vm::ptr<void> userData, vm::ptr<void> extParam);
// wrapper to call for other hle dialogs
error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialogCallback> callback, vm::ptr<void> userData, vm::ptr<void> extParam)
error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialogCallback> callback, vm::ptr<void> userData, vm::ptr<void> extParam, s32* return_code)
{
cellSysutil.notice("open_msg_dialog(is_blocking=%d, type=0x%x, msgString=%s, callback=*0x%x, userData=*0x%x, extParam=*0x%x)", is_blocking, type, msgString, callback, userData, extParam);
cellSysutil.notice("open_msg_dialog(is_blocking=%d, type=0x%x, msgString=%s, callback=*0x%x, userData=*0x%x, extParam=*0x%x, return_code=*0x%x)", is_blocking, type, msgString, callback, userData, extParam, return_code);
const MsgDialogType _type{ type };
if (return_code)
{
*return_code = CELL_MSGDIALOG_BUTTON_NONE;
}
if (auto manager = g_fxo->try_get<rsx::overlays::display_manager>())
{
if (manager->get<rsx::overlays::message_dialog>())
@@ -160,10 +164,15 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString,
return CellSysutilError{ret + 0u};
}
g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE;
const auto notify = std::make_shared<atomic_t<bool>>(false);
const auto res = manager->create<rsx::overlays::message_dialog>()->show(is_blocking, msgString.get_ptr(), _type, [callback, userData](s32 status)
const auto res = manager->create<rsx::overlays::message_dialog>()->show(is_blocking, msgString.get_ptr(), _type, [callback, userData, &return_code, is_blocking, notify](s32 status)
{
if (is_blocking && return_code)
{
*return_code = status;
}
sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
if (callback)
@@ -174,8 +183,20 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString,
return CELL_OK;
});
}
if (is_blocking && notify)
{
*notify = true;
notify->notify_one();
}
});
// Wait for on_close
while (is_blocking && !Emu.IsStopped() && !*notify)
{
notify->wait(false, atomic_wait_timeout{1'000'000});
}
return res;
}
@@ -193,8 +214,13 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString,
dlg->type = _type;
dlg->on_close = [callback, userData, wptr = std::weak_ptr<MsgDialogBase>(dlg)](s32 status)
dlg->on_close = [callback, userData, &return_code, wptr = std::weak_ptr<MsgDialogBase>(dlg)](s32 status)
{
if (return_code)
{
*return_code = status;
}
const auto dlg = wptr.lock();
if (dlg && dlg->state.compare_and_swap_test(MsgDialogState::Open, MsgDialogState::Close))
@@ -222,13 +248,12 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString,
auto& ppu = *get_current_cpu_thread();
lv2_obj::sleep(ppu);
// PS3 memory must not be accessed by Main thread
// PS3 memory must not be accessed by Main thread
std::string msg_string = msgString.get_ptr();
// Run asynchronously in GUI thread
Emu.CallFromMainThread([&, msg_string = std::move(msg_string)]()
{
g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE;
dlg->Create(msg_string);
lv2_obj::awake(&ppu);
});
@@ -369,11 +394,11 @@ error_code cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMs
if (_type.se_normal)
{
cellSysutil.warning("%s", msgString);
cellSysutil.warning("Opening message dialog with message: %s", msgString);
}
else
{
cellSysutil.error("%s", msgString);
cellSysutil.error("Opening error message dialog with message: %s", msgString);
}
return open_msg_dialog(false, type, msgString, callback, userData, extParam);
+1 -3
View File
@@ -89,10 +89,8 @@ enum class MsgDialogState
Close,
};
extern atomic_t<s32> g_last_user_response;
void close_msg_dialog();
error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialogCallback> callback = vm::null, vm::ptr<void> userData = vm::null, vm::ptr<void> extParam = vm::null);
error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialogCallback> callback = vm::null, vm::ptr<void> userData = vm::null, vm::ptr<void> extParam = vm::null, s32* return_code = nullptr);
error_code open_exit_dialog(const std::string& message, bool is_exit_requested);
class MsgDialogBase
@@ -140,7 +140,7 @@ void music_selection_context::create_playlist(const std::string& new_hash)
if (!file.file || (file.file.write(out.c_str(), out.size()), !file.commit()))
{
cellMusicSelectionContext.error("Failed to create music playlist file %s (%s)", yaml_path, fs::g_tls_error);
cellMusicSelectionContext.error("Failed to create music playlist file %s (error=%s)", yaml_path, fs::g_tls_error);
}
}
@@ -302,7 +302,7 @@ u32 music_selection_context::step_track(bool next)
// Play the previous track. Start with the last track if we reached the start of the playlist.
if (current_track == 0)
{
current_track = playlist.size() - 1;
current_track = ::narrow<u32>(playlist.size() - 1);
}
else
{
+21 -5
View File
@@ -90,6 +90,23 @@ void fmt_class_string<CellNetCtlState>::format(std::string& out, u64 arg)
});
}
struct CellGameUpdateResult
{
be_t<s32> status; // CellGameUpdateResultStatus
be_t<s32> error_code;
char app_ver[CELL_GAME_SYSP_APP_VER_SIZE];
char padding[2];
};
struct CellGameUpdateParam
{
be_t<u32> size;
be_t<u32> cid;
};
using CellGameUpdateCallback = void(s32 status, s32 error_code, vm::ptr<void> userdata);
using CellGameUpdateCallbackEx = void(vm::ptr<CellGameUpdateResult> result, vm::ptr<void> userdata);
error_code cellNetCtlInit()
{
cellNetCtl.warning("cellNetCtlInit()");
@@ -204,16 +221,15 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
switch (code)
{
case CELL_NET_CTL_INFO_DEVICE: info->device = CELL_NET_CTL_DEVICE_WIRED; break;
// case CELL_NET_CTL_INFO_ETHER_ADDR: std::memset(info->ether_addr.data, 0xFF, sizeof(info->ether_addr.data)); break;
case CELL_NET_CTL_INFO_MTU: info->mtu = 1500; break;
case CELL_NET_CTL_INFO_LINK: info->link = CELL_NET_CTL_LINK_CONNECTED; break;
case CELL_NET_CTL_INFO_LINK_TYPE: info->link_type = CELL_NET_CTL_LINK_TYPE_10BASE_FULL; break;
case CELL_NET_CTL_INFO_LINK_TYPE: info->link_type = CELL_NET_CTL_LINK_TYPE_100BASE_FULL; break;
case CELL_NET_CTL_INFO_IP_CONFIG: info->ip_config = CELL_NET_CTL_IP_STATIC; break;
case CELL_NET_CTL_INFO_DEFAULT_ROUTE: strcpy_trunc(info->default_route, "192.168.1.1"); break;
case CELL_NET_CTL_INFO_PRIMARY_DNS: strcpy_trunc(info->primary_dns, np::ip_to_string(nph.get_dns_ip())); break;
case CELL_NET_CTL_INFO_SECONDARY_DNS: strcpy_trunc(info->secondary_dns, np::ip_to_string(nph.get_dns_ip())); break;
case CELL_NET_CTL_INFO_IP_ADDRESS: strcpy_trunc(info->ip_address, np::ip_to_string(nph.get_public_ip_addr())); break;
case CELL_NET_CTL_INFO_NETMASK: strcpy_trunc(info->netmask, "255.255.255.255"); break;
case CELL_NET_CTL_INFO_IP_ADDRESS: strcpy_trunc(info->ip_address, np::ip_to_string(nph.get_local_ip_addr())); break; // verified on HW
case CELL_NET_CTL_INFO_NETMASK: strcpy_trunc(info->netmask, "255.255.255.0"); break;
case CELL_NET_CTL_INFO_HTTP_PROXY_CONFIG: info->http_proxy_config = 0; break;
case CELL_NET_CTL_INFO_DHCP_HOSTNAME: strcpy_trunc(info->dhcp_hostname, nph.get_hostname()); break;
default: cellNetCtl.error("Unsupported request: %s", InfoCodeToName(code)); break;
@@ -331,7 +347,7 @@ error_code cellNetCtlGetNatInfo(vm::ptr<CellNetCtlNatInfo> natInfo)
natInfo->nat_type = CELL_NET_CTL_NATINFO_NAT_TYPE_2;
natInfo->stun_status = CELL_NET_CTL_NATINFO_STUN_OK;
natInfo->upnp_status = CELL_NET_CTL_NATINFO_UPNP_NO;
natInfo->upnp_status = nph.get_upnp_status();
return CELL_OK;
}
-19
View File
@@ -1,7 +1,5 @@
#pragma once
#include "cellGame.h"
#include "Emu/Memory/vm_ptr.h"
// Error Codes
@@ -335,20 +333,3 @@ enum
CELL_GAMEUPDATE_RESULT_STATUS_ABORTED = 6,
CELL_GAMEUPDATE_RESULT_STATUS_SYSTEM_UPDATE_NEEDED = 7
};
struct CellGameUpdateResult
{
be_t<s32> status; // CellGameUpdateResultStatus
be_t<s32> error_code;
char app_ver[CELL_GAME_SYSP_APP_VER_SIZE];
char padding[2];
};
struct CellGameUpdateParam
{
be_t<u32> size;
be_t<u32> cid;
};
using CellGameUpdateCallback = void(s32 status, s32 error_code, vm::ptr<void> userdata);
using CellGameUpdateCallbackEx = void(vm::ptr<CellGameUpdateResult> result, vm::ptr<void> userdata);
+370 -211
View File
@@ -4,14 +4,15 @@
#include "Emu/Cell/PPUModule.h"
#include "Emu/Io/interception.h"
#include "Emu/Io/Keyboard.h"
#include "Emu/RSX/Overlays/overlay_osk.h"
#include "Emu/IdManager.h"
#include "Emu/RSX/Overlays/overlay_manager.h"
#include "Emu/RSX/Overlays/overlay_osk.h"
#include "cellSysutil.h"
#include "cellOskDialog.h"
#include "cellMsgDialog.h"
#include "util/init_mutex.hpp"
#include "cellImeJp.h"
#include <thread>
@@ -51,77 +52,73 @@ void fmt_class_string<CellOskDialogContinuousMode>::format(std::string& out, u64
});
}
OskDialogBase::~OskDialogBase()
void osk_info::reset()
{
std::lock_guard lock(text_mtx);
dlg.reset();
valid_text = {};
use_separate_windows = false;
lock_ext_input_device = false;
device_mask = 0;
input_field_window_width = 0;
input_field_background_transparency = 1.0f;
input_field_layout_info = {};
input_panel_layout_info = {};
key_layout_options = CELL_OSKDIALOG_10KEY_PANEL;
initial_key_layout = CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_SYSTEM;
initial_input_device = CELL_OSKDIALOG_INPUT_DEVICE_PAD;
clipboard_enabled = false;
half_byte_kana_enabled = false;
supported_languages = 0;
dimmer_enabled = true;
base_color = OskDialogBase::color{ 0.2f, 0.2f, 0.2f, 1.0f };
pointer_enabled = false;
pointer_x = 0.0f;
pointer_y = 0.0f;
initial_scale = 1.0f;
layout = {};
osk_continuous_mode = CELL_OSKDIALOG_CONTINUOUS_MODE_NONE;
last_dialog_state = CELL_SYSUTIL_OSKDIALOG_UNLOADED;
osk_confirm_callback.store({});
osk_force_finish_callback.store({});
osk_hardware_keyboard_event_hook_callback.store({});
hook_event_mode.store(0);
}
struct osk_info
// Align horizontally
u32 osk_info::get_aligned_x(u32 layout_mode)
{
std::shared_ptr<OskDialogBase> dlg;
std::array<char16_t, CELL_OSKDIALOG_STRING_SIZE> valid_text{};
shared_mutex text_mtx;
atomic_t<bool> use_separate_windows = false;
atomic_t<bool> lock_ext_input = false;
atomic_t<u32> device_mask = 0; // 0 means all devices can influence the OSK
atomic_t<u32> key_layout = CELL_OSKDIALOG_10KEY_PANEL;
atomic_t<CellOskDialogInitialKeyLayout> initial_key_layout = CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_SYSTEM;
atomic_t<CellOskDialogInputDevice> initial_input_device = CELL_OSKDIALOG_INPUT_DEVICE_PAD;
atomic_t<bool> clipboard_enabled = false; // For copy and paste
atomic_t<bool> half_byte_kana_enabled = false;
atomic_t<u32> supported_languages = 0; // Used to enable non-default languages in the OSK
atomic_t<bool> dimmer_enabled = true;
atomic_t<OskDialogBase::color> base_color = OskDialogBase::color{ 0.2f, 0.2f, 0.2f, 1.0f };
atomic_t<bool> pointer_enabled = false;
CellOskDialogPoint pointer_pos{0.0f, 0.0f};
atomic_t<f32> initial_scale = 1.0f;
atomic_t<u32> layout_mode = CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT | CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP;
atomic_t<CellOskDialogContinuousMode> osk_continuous_mode = CELL_OSKDIALOG_CONTINUOUS_MODE_NONE;
atomic_t<u32> last_dialog_state = CELL_SYSUTIL_OSKDIALOG_UNLOADED; // Used for continuous seperate window dialog
atomic_t<vm::ptr<cellOskDialogConfirmWordFilterCallback>> osk_confirm_callback{};
atomic_t<vm::ptr<cellOskDialogForceFinishCallback>> osk_force_finish_callback{};
atomic_t<vm::ptr<cellOskDialogHardwareKeyboardEventHookCallback>> osk_hardware_keyboard_event_hook_callback{};
atomic_t<u16> hook_event_mode{0};
stx::init_mutex init;
void reset()
// Let's prefer a centered alignment.
if (layout_mode & CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_CENTER)
{
std::lock_guard lock(text_mtx);
dlg.reset();
valid_text = {};
use_separate_windows = false;
lock_ext_input = false;
device_mask = 0;
key_layout = CELL_OSKDIALOG_10KEY_PANEL;
initial_key_layout = CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_SYSTEM;
initial_input_device = CELL_OSKDIALOG_INPUT_DEVICE_PAD;
clipboard_enabled = false;
half_byte_kana_enabled = false;
supported_languages = 0;
dimmer_enabled = true;
base_color = OskDialogBase::color{ 0.2f, 0.2f, 0.2f, 1.0f };
pointer_enabled = false;
pointer_pos = {0.0f, 0.0f};
initial_scale = 1.0f;
layout_mode = CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT | CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP;
osk_continuous_mode = CELL_OSKDIALOG_CONTINUOUS_MODE_NONE;
last_dialog_state = CELL_SYSUTIL_OSKDIALOG_UNLOADED;
osk_confirm_callback.store({});
osk_force_finish_callback.store({});
osk_hardware_keyboard_event_hook_callback.store({});
hook_event_mode.store(0);
return CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_CENTER;
}
};
if (layout_mode & CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT)
{
return CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT;
}
return CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_RIGHT;
}
// Align vertically
u32 osk_info::get_aligned_y(u32 layout_mode)
{
// Let's prefer a centered alignment.
if (layout_mode & CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_CENTER)
{
return CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_CENTER;
}
if (layout_mode & CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP)
{
return CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP;
}
return CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_BOTTOM;
}
// TODO: don't use this function
std::shared_ptr<OskDialogBase> _get_osk_dialog(bool create)
@@ -160,6 +157,67 @@ std::shared_ptr<OskDialogBase> _get_osk_dialog(bool create)
return osk.dlg;
}
extern bool close_osk_from_ps_button()
{
const auto osk = _get_osk_dialog(false);
if (!osk)
{
// The OSK is not open
return true;
}
osk_info& info = g_fxo->get<osk_info>();
// We can only close the osk in separate window mode when it is hidden (continuous_mode is set to CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE)
if (!info.use_separate_windows || osk->continuous_mode != CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE)
{
cellOskDialog.warning("close_osk_from_ps_button: can't close OSK (use_separate_windows=%d, continuous_mode=%s)", info.use_separate_windows.load(), osk->continuous_mode.load());
return false;
}
std::lock_guard lock(info.text_mtx);
if (auto cb = info.osk_force_finish_callback.load())
{
bool done = false;
bool close_osk = false;
sysutil_register_cb([&](ppu_thread& cb_ppu) -> s32
{
cellOskDialog.notice("osk_force_finish_callback()");
close_osk = cb(cb_ppu);
cellOskDialog.notice("osk_force_finish_callback returned %d", close_osk);
done = true;
return 0;
});
// wait for check callback
while (!done && !Emu.IsStopped())
{
std::this_thread::yield();
}
if (!close_osk)
{
// We are not allowed to close the OSK
cellOskDialog.warning("close_osk_from_ps_button: can't close OSK (osk_force_finish_callback returned false)");
return false;
}
}
// Forcefully terminate the OSK
cellOskDialog.warning("close_osk_from_ps_button: Terminating the OSK ...");
osk->Close(FAKE_CELL_OSKDIALOG_CLOSE_TERMINATE);
osk->state = OskDialogState::Closed;
cellOskDialog.notice("close_osk_from_ps_button: sending CELL_SYSUTIL_OSKDIALOG_FINISHED");
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0);
return true;
}
error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dialogParam, vm::ptr<CellOskDialogInputFieldInfo> inputFieldInfo)
{
cellOskDialog.warning("cellOskDialogLoadAsync(container=0x%x, dialogParam=*0x%x, inputFieldInfo=*0x%x)", container, dialogParam, inputFieldInfo);
@@ -169,6 +227,9 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
return CELL_OSKDIALOG_ERROR_PARAM;
}
cellOskDialog.notice("cellOskDialogLoadAsync: dialogParam={ allowOskPanelFlg=0x%x, prohibitFlgs=0x%x, firstViewPanel=%d, controlPoint=(%.2f,%.2f) }",
dialogParam->allowOskPanelFlg, dialogParam->prohibitFlgs, dialogParam->firstViewPanel, dialogParam->controlPoint.x, dialogParam->controlPoint.y);
auto osk = _get_osk_dialog(true);
// Can't open another dialog if this one is already open.
@@ -183,10 +244,12 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
const u32 prohibitFlgs = dialogParam->prohibitFlgs;
const u32 allowOskPanelFlg = dialogParam->allowOskPanelFlg;
const u32 firstViewPanel = dialogParam->firstViewPanel;
info.layout.x_offset = dialogParam->controlPoint.x;
info.layout.y_offset = dialogParam->controlPoint.y;
// Get init text and prepare return value
osk->osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK;
std::memset(osk->osk_text, 0, sizeof(osk->osk_text));
osk->osk_text = {};
// Also clear the info text just to be sure (it should be zeroed at this point anyway)
{
@@ -214,11 +277,16 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
}
}
osk->on_osk_close = [wptr = std::weak_ptr<OskDialogBase>(osk)](s32 status)
osk->on_osk_close = [](s32 status)
{
cellOskDialog.notice("on_osk_close(status=%d)", status);
const auto osk = wptr.lock();
const auto osk = _get_osk_dialog(false);
if (!osk)
{
return;
}
osk->state = OskDialogState::Closed;
auto& info = g_fxo->get<osk_info>();
@@ -229,7 +297,7 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
{
case CELL_OSKDIALOG_CLOSE_CONFIRM:
{
if (auto ccb = info.osk_confirm_callback.exchange({}))
if (auto ccb = info.osk_confirm_callback.load())
{
std::vector<u16> string_to_send(CELL_OSKDIALOG_STRING_SIZE);
atomic_t<bool> done = false;
@@ -266,7 +334,7 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
if (info.use_separate_windows.load() && osk->osk_text[0] == 0)
{
cellOskDialog.warning("cellOskDialogLoadAsync: input result is CELL_OSKDIALOG_INPUT_FIELD_RESULT_NO_INPUT_TEXT");
cellOskDialog.warning("on_osk_close: input result is CELL_OSKDIALOG_INPUT_FIELD_RESULT_NO_INPUT_TEXT");
osk->osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_NO_INPUT_TEXT;
}
else
@@ -300,12 +368,16 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
case CELL_OSKDIALOG_CLOSE_CONFIRM:
{
info.last_dialog_state = CELL_SYSUTIL_OSKDIALOG_INPUT_ENTERED;
cellOskDialog.notice("on_osk_close: sending CELL_SYSUTIL_OSKDIALOG_INPUT_ENTERED");
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_INPUT_ENTERED, 0);
break;
}
case CELL_OSKDIALOG_CLOSE_CANCEL:
{
info.last_dialog_state = CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED;
cellOskDialog.notice("on_osk_close: sending CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED");
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED, 0);
break;
}
@@ -320,32 +392,34 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
break;
}
}
if (info.osk_continuous_mode.load() == CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE)
{
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_DISPLAY_CHANGED, CELL_OSKDIALOG_DISPLAY_STATUS_HIDE);
}
}
else if (status != FAKE_CELL_OSKDIALOG_CLOSE_ABORT) // Handled in cellOskDialogAbort
{
info.last_dialog_state = CELL_SYSUTIL_OSKDIALOG_FINISHED;
cellOskDialog.notice("on_osk_close: sending CELL_SYSUTIL_OSKDIALOG_FINISHED");
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0);
}
input::SetIntercepted(false);
// The interception status of the continuous separate window is handled differently
if (!keep_seperate_window_open)
{
input::SetIntercepted(false);
}
};
// Set key callback
osk->on_osk_key_input_entered = [wptr = std::weak_ptr<OskDialogBase>(osk)](CellOskDialogKeyMessage key_message)
osk->on_osk_key_input_entered = [](CellOskDialogKeyMessage key_message)
{
const auto osk = wptr.lock();
auto& info = g_fxo->get<osk_info>();
std::lock_guard lock(info.text_mtx);
auto event_hook_callback = info.osk_hardware_keyboard_event_hook_callback.load();
cellOskDialog.notice("on_osk_key_input_entered: led=%d, mkey=%d, keycode=%d, hook_event_mode=%d, event_hook_callback=*0x%x", key_message.led, key_message.mkey, key_message.keycode, info.hook_event_mode.load(), event_hook_callback);
if (!event_hook_callback)
const auto osk = _get_osk_dialog(false);
if (!osk || !event_hook_callback)
{
// Nothing to do here
return;
@@ -409,39 +483,43 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
break;
}
}
if (!is_kook_key)
{
cellOskDialog.notice("on_osk_key_input_entered: not a hook key: led=%d, mkey=%d, keycode=%d, hook_event_mode=%d", key_message.led, key_message.mkey, key_message.keycode, info.hook_event_mode.load());
return;
}
// The max size is 100 characters plus '\0'. Apparently this used to be 30 plus '\0' in older firmware.
constexpr u32 max_size = 101;
std::vector<u16> string_to_send(max_size, 0);
atomic_t<bool> done = false;
for (u32 i = 0; i < max_size - 1; i++)
{
string_to_send[i] = osk->osk_text[i];
if (osk->osk_text[i] == 0) break;
}
// TODO: Send unconfirmed string if there is one.
// As far as I understand, this is for example supposed to be the IME preview.
// So when you type in japanese, you get some word propositions which you can select and confirm.
// The "confirmed" string is basically everything you already wrote, while the "unconfirmed"
// string is the auto-completion part that you haven't accepted as proper word yet.
// The game expects you to send this "preview", or an empty string if there is none.
std::array<u16, max_size> string_to_send{};
sysutil_register_cb([&](ppu_thread& cb_ppu) -> s32
sysutil_register_cb([key_message, string_to_send, event_hook_callback](ppu_thread& cb_ppu) -> s32
{
// Prepare callback variables
vm::var<CellOskDialogKeyMessage> keyMessage(key_message);
vm::var<u32> action(CELL_OSKDIALOG_CHANGE_NO_EVENT);
vm::var<u16[], vm::page_allocator<>> pActionInfo(max_size, string_to_send.data());
vm::var<u16[], vm::page_allocator<>> pActionInfo(string_to_send.size(), string_to_send.data());
std::u16string utf16_string;
utf16_string.insert(0, reinterpret_cast<char16_t*>(string_to_send.data()), string_to_send.size());
std::string action_info = utf16_to_ascii8(utf16_string);
// Create helpers for logging
std::u16string utf16_string(reinterpret_cast<const char16_t*>(string_to_send.data()), string_to_send.size());
std::string utf8_string = utf16_to_ascii8(utf16_string);
cellOskDialog.notice("osk_hardware_keyboard_event_hook_callback(led=%d, mkey=%d, keycode=%d, action=%d, pActionInfo='%s')", keyMessage->led, keyMessage->mkey, keyMessage->keycode, *action, action_info);
cellOskDialog.notice("osk_hardware_keyboard_event_hook_callback(led=%d, mkey=%d, keycode=%d, action=%d, pActionInfo='%s')", keyMessage->led, keyMessage->mkey, keyMessage->keycode, *action, utf8_string);
const bool return_value = event_hook_callback(cb_ppu, keyMessage, action, pActionInfo.begin());
// Call the hook function. The game reads and writes pActionInfo. We need to react based on the returned action.
const bool return_value = event_hook_callback(cb_ppu, keyMessage, action, pActionInfo);
ensure(action);
ensure(pActionInfo);
// Parse returned text for logging
utf16_string.clear();
for (u32 i = 0; i < max_size; i++)
{
@@ -449,12 +527,23 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
if (!code) break;
utf16_string.push_back(code);
}
action_info = utf16_to_ascii8(utf16_string);
utf8_string = utf16_to_ascii8(utf16_string);
cellOskDialog.notice("osk_hardware_keyboard_event_hook_callback: return_value=%d, action=%d, pActionInfo='%s'", return_value, *action, action_info);
cellOskDialog.notice("osk_hardware_keyboard_event_hook_callback: return_value=%d, action=%d, pActionInfo='%s'", return_value, *action, utf8_string);
// Check if the hook function was successful
if (return_value)
{
const auto osk = _get_osk_dialog(false);
if (!osk)
{
cellOskDialog.error("osk_hardware_keyboard_event_hook_callback: osk is null");
return 0;
}
auto& info = g_fxo->get<osk_info>();
std::lock_guard lock(info.text_mtx);
switch (*action)
{
case CELL_OSKDIALOG_CHANGE_NO_EVENT:
@@ -465,31 +554,25 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
}
case CELL_OSKDIALOG_CHANGE_WORDS_INPUT:
{
// Set unconfirmed string and reset unconfirmed string
for (u32 i = 0; i < max_size; i++)
{
osk->osk_text[i] = pActionInfo.begin()[i];
}
// TODO: Replace unconfirmed string.
cellOskDialog.todo("osk_hardware_keyboard_event_hook_callback: replace unconfirmed string with '%s'", utf8_string);
break;
}
case CELL_OSKDIALOG_CHANGE_WORDS_INSERT:
{
// TODO: Remove unconfirmed string
cellOskDialog.todo("osk_hardware_keyboard_event_hook_callback: remove unconfirmed string");
// Set confirmed string and reset unconfirmed string
for (u32 i = 0; i < max_size; i++)
{
info.valid_text[i] = pActionInfo.begin()[i];
osk->osk_text[i] = 0;
}
cellOskDialog.notice("osk_hardware_keyboard_event_hook_callback: inserting string '%s'", utf8_string);
osk->Insert(utf16_string);
break;
}
case CELL_OSKDIALOG_CHANGE_WORDS_REPLACE_ALL:
{
// Set confirmed string and reset all strings
for (u32 i = 0; i < max_size; i++)
{
info.valid_text[i] = pActionInfo.begin()[i];
osk->osk_text[i] = 0;
}
// Replace confirmed string and remove unconfirmed string.
cellOskDialog.notice("osk_hardware_keyboard_event_hook_callback: replacing all strings with '%s'", utf8_string);
osk->SetText(utf16_string);
break;
}
default:
@@ -500,19 +583,14 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
}
}
done = true;
return 0;
});
// wait for callback
while (!done && !Emu.IsStopped())
{
std::this_thread::yield();
}
};
// Set device mask and event lock
osk->ignore_input_events = info.lock_ext_input.load();
osk->ignore_device_events = info.lock_ext_input_device.load();
osk->input_device = info.initial_input_device.load();
osk->continuous_mode = info.osk_continuous_mode.load();
if (info.use_separate_windows)
{
@@ -520,28 +598,47 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
osk->mouse_input_enabled = (info.device_mask != CELL_OSKDIALOG_DEVICE_MASK_PAD);
}
if (info.osk_continuous_mode == CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE)
{
info.last_dialog_state = CELL_SYSUTIL_OSKDIALOG_LOADED;
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_LOADED, 0);
return CELL_OK;
}
input::SetIntercepted(osk->pad_input_enabled, osk->keyboard_input_enabled, osk->mouse_input_enabled);
cellOskDialog.notice("cellOskDialogLoadAsync: creating OSK dialog ...");
Emu.BlockingCallFromMainThread([=, &info]()
{
osk->Create(get_localized_string(localized_string_id::CELL_OSK_DIALOG_TITLE), message, osk->osk_text, maxLength, prohibitFlgs, allowOskPanelFlg, firstViewPanel, info.base_color.load(), info.dimmer_enabled.load(), false);
osk->Create({
.title = get_localized_string(localized_string_id::CELL_OSK_DIALOG_TITLE),
.message = message,
.init_text = osk->osk_text.data(),
.charlimit = maxLength,
.prohibit_flags = prohibitFlgs,
.panel_flag = allowOskPanelFlg,
.support_language = info.supported_languages,
.first_view_panel = firstViewPanel,
.layout = info.layout,
.input_layout = info.input_field_layout_info,
.panel_layout = info.input_panel_layout_info,
.input_field_window_width = info.input_field_window_width,
.input_field_background_transparency = info.input_field_background_transparency,
.initial_scale = info.initial_scale,
.base_color = info.base_color,
.dimmer_enabled = info.dimmer_enabled,
.use_separate_windows = info.use_separate_windows,
.intercept_input = false // We handle the interception manually based on the device mask
});
});
if (info.osk_continuous_mode == CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE)
g_fxo->get<osk_info>().last_dialog_state = CELL_SYSUTIL_OSKDIALOG_LOADED;
if (info.use_separate_windows)
{
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_DISPLAY_CHANGED, CELL_OSKDIALOG_DISPLAY_STATUS_SHOW);
const bool visible = osk->continuous_mode != CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE;
cellOskDialog.notice("cellOskDialogLoadAsync: sending CELL_SYSUTIL_OSKDIALOG_DISPLAY_CHANGED with %s", visible ? "CELL_OSKDIALOG_DISPLAY_STATUS_SHOW" : "CELL_OSKDIALOG_DISPLAY_STATUS_HIDE");
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_DISPLAY_CHANGED, visible ? CELL_OSKDIALOG_DISPLAY_STATUS_SHOW : CELL_OSKDIALOG_DISPLAY_STATUS_HIDE);
}
g_fxo->get<osk_info>().last_dialog_state = CELL_SYSUTIL_OSKDIALOG_LOADED;
cellOskDialog.notice("cellOskDialogLoadAsync: sending CELL_SYSUTIL_OSKDIALOG_LOADED");
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_LOADED, 0);
cellOskDialog.notice("cellOskDialogLoadAsync: created OSK dialog");
return CELL_OK;
}
@@ -626,7 +723,15 @@ error_code getText(vm::ptr<CellOskDialogCallbackReturnParam> OutputInfo, bool is
info.reset();
}
if (keep_seperate_window_open)
{
cellOskDialog.notice("cellOskDialogUnloadAsync: terminating continuous overlay");
osk->Close(FAKE_CELL_OSKDIALOG_CLOSE_TERMINATE);
}
osk->state = OskDialogState::Unloaded;
cellOskDialog.notice("cellOskDialogUnloadAsync: sending CELL_SYSUTIL_OSKDIALOG_UNLOADED");
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_UNLOADED, 0);
}
else if (keep_seperate_window_open)
@@ -638,8 +743,14 @@ error_code getText(vm::ptr<CellOskDialogCallbackReturnParam> OutputInfo, bool is
case CELL_SYSUTIL_OSKDIALOG_UNLOADED:
case CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED:
case CELL_SYSUTIL_OSKDIALOG_INPUT_ENTERED:
{
auto& info = g_fxo->get<osk_info>();
std::lock_guard lock(info.text_mtx);
info.valid_text = {};
osk->Clear(true);
break;
}
default:
break;
}
@@ -708,6 +819,8 @@ error_code cellOskDialogAbort()
}
g_fxo->get<osk_info>().last_dialog_state = CELL_SYSUTIL_OSKDIALOG_FINISHED;
cellOskDialog.notice("cellOskDialogAbort: sending CELL_SYSUTIL_OSKDIALOG_FINISHED");
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0);
return CELL_OK;
@@ -742,9 +855,13 @@ error_code cellOskDialogSetDeviceMask(u32 deviceMask)
error_code cellOskDialogSetSeparateWindowOption(vm::ptr<CellOskDialogSeparateWindowOption> windowOption)
{
cellOskDialog.todo("cellOskDialogSetSeparateWindowOption(windowOption=*0x%x)", windowOption);
cellOskDialog.warning("cellOskDialogSetSeparateWindowOption(windowOption=*0x%x)", windowOption);
if (!windowOption)
if (!windowOption ||
!windowOption->inputFieldLayoutInfo ||
!!windowOption->reserved ||
windowOption->continuousMode > CELL_OSKDIALOG_CONTINUOUS_MODE_SHOW ||
windowOption->deviceMask > CELL_OSKDIALOG_DEVICE_MASK_PAD)
{
return CELL_OSKDIALOG_ERROR_PARAM;
}
@@ -753,20 +870,43 @@ error_code cellOskDialogSetSeparateWindowOption(vm::ptr<CellOskDialogSeparateWin
osk.use_separate_windows = true;
osk.osk_continuous_mode = static_cast<CellOskDialogContinuousMode>(+windowOption->continuousMode);
osk.device_mask = windowOption->deviceMask;
// TODO: handle rest of windowOption
// inputFieldWindowWidth;
// inputFieldBackgroundTrans;
// inputFieldLayoutInfo;
// inputPanelLayoutInfo;
osk.input_field_window_width = windowOption->inputFieldWindowWidth;
osk.input_field_background_transparency = std::clamp<f32>(windowOption->inputFieldBackgroundTrans, 0.0f, 1.0f);
cellOskDialog.warning("cellOskDialogSetSeparateWindowOption: use_separate_windows=true, continuous_mode=%s, device_mask=0x%x)", osk.osk_continuous_mode.load(), osk.device_mask.load());
// Choose proper alignments, since the devs didn't make them exclusive for some reason.
const auto aligned_layout = [](const CellOskDialogLayoutInfo& info) -> osk_window_layout
{
osk_window_layout res{};
res.layout_mode = info.layoutMode;
res.x_align = osk_info::get_aligned_x(res.layout_mode);
res.y_align = osk_info::get_aligned_y(res.layout_mode);
res.x_offset = info.position.x;
res.y_offset = info.position.y;
return res;
};
osk.input_field_layout_info = aligned_layout(*windowOption->inputFieldLayoutInfo);
// Panel layout is optional
if (windowOption->inputPanelLayoutInfo)
{
osk.input_panel_layout_info = aligned_layout(*windowOption->inputPanelLayoutInfo);
}
else
{
// Align to input field
osk.input_panel_layout_info = osk.input_field_layout_info;
}
cellOskDialog.warning("cellOskDialogSetSeparateWindowOption: use_separate_windows=true, continuous_mode=%s, device_mask=0x%x, input_field_window_width=%d, input_field_background_transparency=%.2f, input_field_layout_info=%s, input_panel_layout_info=%s)",
osk.osk_continuous_mode.load(), osk.device_mask.load(), osk.input_field_window_width.load(), osk.input_field_background_transparency.load(), osk.input_field_layout_info, osk.input_panel_layout_info);
return CELL_OK;
}
error_code cellOskDialogSetInitialInputDevice(u32 inputDevice)
{
cellOskDialog.todo("cellOskDialogSetInitialInputDevice(inputDevice=%d)", inputDevice);
cellOskDialog.warning("cellOskDialogSetInitialInputDevice(inputDevice=%d)", inputDevice);
if (inputDevice > CELL_OSKDIALOG_INPUT_DEVICE_KEYBOARD)
{
@@ -775,24 +915,24 @@ error_code cellOskDialogSetInitialInputDevice(u32 inputDevice)
g_fxo->get<osk_info>().initial_input_device = static_cast<CellOskDialogInputDevice>(inputDevice);
// TODO: use value
// TODO: Signal CELL_SYSUTIL_OSKDIALOG_INPUT_DEVICE_CHANGED if the input device changed (probably only when the dialog is already open)
return CELL_OK;
}
error_code cellOskDialogSetInitialKeyLayout(u32 initialKeyLayout)
{
cellOskDialog.todo("cellOskDialogSetInitialKeyLayout(initialKeyLayout=%d)", initialKeyLayout);
cellOskDialog.warning("cellOskDialogSetInitialKeyLayout(initialKeyLayout=%d)", initialKeyLayout);
if (initialKeyLayout > (CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_10KEY | CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_FULLKEY))
if (initialKeyLayout > CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_FULLKEY)
{
return CELL_OSKDIALOG_ERROR_PARAM;
}
g_fxo->get<osk_info>().initial_key_layout = static_cast<CellOskDialogInitialKeyLayout>(initialKeyLayout);
auto& osk = g_fxo->get<osk_info>();
// TODO: use value
if (osk.key_layout_options & initialKeyLayout)
{
osk.initial_key_layout = static_cast<CellOskDialogInitialKeyLayout>(initialKeyLayout);
}
return CELL_OK;
}
@@ -808,53 +948,37 @@ error_code cellOskDialogDisableDimmer()
error_code cellOskDialogSetKeyLayoutOption(u32 option)
{
cellOskDialog.todo("cellOskDialogSetKeyLayoutOption(option=0x%x)", option);
cellOskDialog.warning("cellOskDialogSetKeyLayoutOption(option=0x%x)", option);
if (option == 0 || option > 3) // CELL_OSKDIALOG_10KEY_PANEL OR CELL_OSKDIALOG_FULLKEY_PANEL
{
return CELL_OSKDIALOG_ERROR_PARAM;
}
g_fxo->get<osk_info>().key_layout = option;
// TODO: use value
g_fxo->get<osk_info>().key_layout_options = option;
return CELL_OK;
}
error_code cellOskDialogAddSupportLanguage(u32 supportLanguage)
{
cellOskDialog.todo("cellOskDialogAddSupportLanguage(supportLanguage=0x%x)", supportLanguage);
// TODO: error checks
cellOskDialog.warning("cellOskDialogAddSupportLanguage(supportLanguage=0x%x)", supportLanguage);
g_fxo->get<osk_info>().supported_languages = supportLanguage;
// TODO: disable extra languages unless they were enabled here
// Extra languages are:
// CELL_OSKDIALOG_PANELMODE_POLISH
// CELL_OSKDIALOG_PANELMODE_KOREAN
// CELL_OSKDIALOG_PANELMODE_TURKEY
// CELL_OSKDIALOG_PANELMODE_TRADITIONAL_CHINESE
// CELL_OSKDIALOG_PANELMODE_SIMPLIFIED_CHINESE
// CELL_OSKDIALOG_PANELMODE_PORTUGUESE_BRAZIL
// CELL_OSKDIALOG_PANELMODE_DANISH
// CELL_OSKDIALOG_PANELMODE_SWEDISH
// CELL_OSKDIALOG_PANELMODE_NORWEGIAN
// CELL_OSKDIALOG_PANELMODE_FINNISH
return CELL_OK;
}
error_code cellOskDialogSetLayoutMode(s32 layoutMode)
{
cellOskDialog.todo("cellOskDialogSetLayoutMode(layoutMode=%d)", layoutMode);
cellOskDialog.warning("cellOskDialogSetLayoutMode(layoutMode=0x%x)", layoutMode);
// TODO: error checks
auto& osk = g_fxo->get<osk_info>();
osk.layout.layout_mode = layoutMode;
g_fxo->get<osk_info>().layout_mode = layoutMode;
// TODO: use layout mode
// Choose proper alignments, since the devs didn't make them exclusive for some reason.
osk.layout.x_align = osk_info::get_aligned_x(layoutMode);
osk.layout.y_align = osk_info::get_aligned_y(layoutMode);
return CELL_OK;
}
@@ -907,6 +1031,26 @@ error_code cellOskDialogExtRegisterKeyboardEventHookCallbackEx(u16 hookEventMode
error_code cellOskDialogExtAddJapaneseOptionDictionary(vm::cpptr<char> filePath)
{
cellOskDialog.todo("cellOskDialogExtAddJapaneseOptionDictionary(filePath=**0x%0x)", filePath);
std::vector<std::string> paths;
if (filePath)
{
for (u32 i = 0; i < 4; i++)
{
if (!filePath[i])
{
break;
}
std::array<char, CELL_IMEJP_DIC_PATH_MAXLENGTH + 1> path{};
std::memcpy(path.data(), filePath[i].get_ptr(), CELL_IMEJP_DIC_PATH_MAXLENGTH);
paths.push_back(path.data());
}
}
cellOskDialog.todo("cellOskDialogExtAddJapaneseOptionDictionary: got %d dictionaries:\n%s", paths.size(), fmt::merge(paths, "\n"));
return CELL_OK;
}
@@ -914,8 +1058,6 @@ error_code cellOskDialogExtEnableClipboard()
{
cellOskDialog.todo("cellOskDialogExtEnableClipboard()");
// TODO: error checks
g_fxo->get<osk_info>().clipboard_enabled = true;
// TODO: implement copy paste
@@ -940,15 +1082,43 @@ error_code cellOskDialogExtSendFinishMessage(u32 /*CellOskDialogFinishReason*/ f
return CELL_OK;
}
error_code cellOskDialogExtAddOptionDictionary(vm::cptr<CellOskDialogImeDictionaryInfo> dictionaryInfo)
error_code cellOskDialogExtAddOptionDictionary(vm::cpptr<CellOskDialogImeDictionaryInfo> dictionaryInfo)
{
cellOskDialog.todo("cellOskDialogExtAddOptionDictionary(dictionaryInfo=*0x%x)", dictionaryInfo);
if (!dictionaryInfo)
{
return CELL_OSKDIALOG_ERROR_PARAM;
}
std::vector<std::pair<u32, std::string>> paths; // language and path
for (u32 i = 0; i < 10; i++)
{
if (!dictionaryInfo[i] || !dictionaryInfo[i]->dictionaryPath)
{
break;
}
std::array<char, CELL_IMEJP_DIC_PATH_MAXLENGTH + 1> path{};
std::memcpy(path.data(), dictionaryInfo[i]->dictionaryPath.get_ptr(), CELL_IMEJP_DIC_PATH_MAXLENGTH);
paths.push_back({ dictionaryInfo[i]->targetLanguage, path.data() });
}
std::vector<std::string> msgs;
for (const auto& entry : paths)
{
msgs.push_back(fmt::format("languages=0x%x, path='%s'", entry.first, entry.second));
}
cellOskDialog.todo("cellOskDialogExtAddOptionDictionary: got %d dictionaries:\n%s", msgs.size(), fmt::merge(msgs, "\n"));
return CELL_OK;
}
error_code cellOskDialogExtSetInitialScale(f32 initialScale)
{
cellOskDialog.todo("cellOskDialogExtSetInitialScale(initialScale=%f)", initialScale);
cellOskDialog.warning("cellOskDialogExtSetInitialScale(initialScale=%f)", initialScale);
if (initialScale < CELL_OSKDIALOG_SCALE_MIN || initialScale > CELL_OSKDIALOG_SCALE_MAX)
{
@@ -957,8 +1127,6 @@ error_code cellOskDialogExtSetInitialScale(f32 initialScale)
g_fxo->get<osk_info>().initial_scale = initialScale;
// TODO: implement overlay scaling
return CELL_OK;
}
@@ -966,13 +1134,11 @@ error_code cellOskDialogExtInputDeviceLock()
{
cellOskDialog.warning("cellOskDialogExtInputDeviceLock()");
// TODO: error checks
g_fxo->get<osk_info>().lock_ext_input = true;
g_fxo->get<osk_info>().lock_ext_input_device = true;
if (const auto osk = _get_osk_dialog(false))
{
osk->ignore_input_events = true;
osk->ignore_device_events = true;
}
return CELL_OK;
@@ -982,13 +1148,11 @@ error_code cellOskDialogExtInputDeviceUnlock()
{
cellOskDialog.warning("cellOskDialogExtInputDeviceUnlock()");
// TODO: error checks
g_fxo->get<osk_info>().lock_ext_input = false;
g_fxo->get<osk_info>().lock_ext_input_device = false;
if (const auto osk = _get_osk_dialog(false))
{
osk->ignore_input_events = false;
osk->ignore_device_events = false;
}
return CELL_OK;
@@ -1052,30 +1216,27 @@ error_code cellOskDialogExtUpdateInputText()
error_code cellOskDialogExtSetPointerEnable(b8 enable)
{
cellOskDialog.todo("cellOskDialogExtSetPointerEnable(enable=%d)", enable);
cellOskDialog.warning("cellOskDialogExtSetPointerEnable(enable=%d)", enable);
// TODO: error checks
// TODO: While the pointer is already displayed in the osk overlay, it is not really useful right now.
// On real hardware, this may be used for actual PS Move or mouse input.
g_fxo->get<osk_info>().pointer_enabled = enable;
// TODO: Show/hide pointer at the specified position in the OSK overlay.
return CELL_OK;
}
error_code cellOskDialogExtUpdatePointerDisplayPos(vm::cptr<CellOskDialogPoint> pos)
{
cellOskDialog.todo("cellOskDialogExtUpdatePointerDisplayPos(pos=0x%x, posX=%f, posY=%f)", pos->x, pos->y);
// TODO: error checks
cellOskDialog.warning("cellOskDialogExtUpdatePointerDisplayPos(pos=0x%x, posX=%f, posY=%f)", pos, pos->x, pos->y);
if (pos)
{
g_fxo->get<osk_info>().pointer_pos = *pos;
osk_info& osk = g_fxo->get<osk_info>();
osk.pointer_x = pos->x;
osk.pointer_y = pos->y;
}
// TODO: Update pointer position in the OSK overlay.
return CELL_OK;
}
@@ -1083,8 +1244,6 @@ error_code cellOskDialogExtEnableHalfByteKana()
{
cellOskDialog.todo("cellOskDialogExtEnableHalfByteKana()");
// TODO: error checks
g_fxo->get<osk_info>().half_byte_kana_enabled = true;
// TODO: use new value in osk
@@ -1096,8 +1255,6 @@ error_code cellOskDialogExtDisableHalfByteKana()
{
cellOskDialog.todo("cellOskDialogExtDisableHalfByteKana()");
// TODO: error checks
g_fxo->get<osk_info>().half_byte_kana_enabled = false;
// TODO: use new value in osk
@@ -1107,21 +1264,23 @@ error_code cellOskDialogExtDisableHalfByteKana()
error_code cellOskDialogExtRegisterForceFinishCallback(vm::ptr<cellOskDialogForceFinishCallback> pCallback)
{
cellOskDialog.todo("cellOskDialogExtRegisterForceFinishCallback(pCallback=*0x%x)", pCallback);
cellOskDialog.warning("cellOskDialogExtRegisterForceFinishCallback(pCallback=*0x%x)", pCallback);
if (!pCallback)
{
return CELL_OSKDIALOG_ERROR_PARAM;
}
g_fxo->get<osk_info>().osk_force_finish_callback = pCallback;
osk_info& info = g_fxo->get<osk_info>();
std::lock_guard lock(info.text_mtx);
info.osk_force_finish_callback = pCallback;
// TODO: use force finish callback when the PS-Button is pressed and a System dialog shall be spawned while the OSK is loaded
// 1. Check if current mode is CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE or (CELL_OSKDIALOG_CONTINUOUS_MODE_SHOW && hidden)
// 2. If one of the above is true, call osk_force_finish_callback
// 3. Check the return value of osk_force_finish_callback. If false, ignore the PS-Button press, else go to the next step
// 4. Close dialog etc., send CELL_SYSUTIL_OSKDIALOG_FINISHED
// 5. After we return from the System dialog, send CELL_SYSUTIL_SYSTEM_MENU_CLOSE to notify the game that it can load the OSK and resume.
// We use the force finish callback when the PS-Button is pressed and a System dialog shall be spawned while the OSK is loaded
// 1. Check if we are in any continuous mode and the dialog is hidden
// 2. If the above is true, call osk_force_finish_callback, deny the PS-Button press otherwise
// 3. Check the return value of osk_force_finish_callback.
// if false, ignore the PS-Button press,
// else close the dialog etc., send CELL_SYSUTIL_OSKDIALOG_FINISHED
return CELL_OK;
}
+104 -7
View File
@@ -2,6 +2,8 @@
#include "util/types.hpp"
#include "util/atomic.hpp"
#include "util/init_mutex.hpp"
#include "Utilities/mutex.h"
#include "Emu/Memory/vm_ptr.h"
#include <string>
#include <functional>
@@ -86,6 +88,7 @@ enum CellOskDialogFinishReason
enum CellOskDialogFinishReasonFake // Helper. Must be negative values.
{
FAKE_CELL_OSKDIALOG_CLOSE_ABORT = -1,
FAKE_CELL_OSKDIALOG_CLOSE_TERMINATE = -2,
};
enum CellOskDialogType
@@ -242,6 +245,20 @@ using cellOskDialogConfirmWordFilterCallback = int(vm::ptr<u16> pConfirmString,
using cellOskDialogHardwareKeyboardEventHookCallback = class b8(vm::ptr<CellOskDialogKeyMessage> keyMessage, vm::ptr<u32> action, vm::ptr<void> pActionInfo);
using cellOskDialogForceFinishCallback = class b8();
struct osk_window_layout
{
u32 layout_mode = CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT | CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP;
u32 x_align = CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT;
u32 y_align = CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP;
f32 x_offset = 0.0f;
f32 y_offset = 0.0f;
std::string to_string() const
{
return fmt::format("{ layout_mode=0x%x, x_align=0x%x, y_align=0x%x, x_offset=%.2f, y_offset=%.2f }", layout_mode, x_align, y_align, x_offset, y_offset);
}
};
enum class OskDialogState
{
Unloaded,
@@ -261,23 +278,103 @@ public:
f32 a = 1.0f;
};
virtual void Create(const std::string& title, const std::u16string& message, char16_t* init_text, u32 charlimit, u32 prohibit_flags, u32 panel_flag, u32 first_view_panel, color base_color, bool dimmer_enabled, bool intercept_input) = 0;
struct osk_params
{
std::string title;
std::u16string message;
char16_t* init_text = nullptr;
u32 charlimit = 0;
u32 prohibit_flags = 0;
u32 panel_flag = 0;
u32 support_language = 0;
u32 first_view_panel = 0;
osk_window_layout layout{};
osk_window_layout input_layout{}; // Only used with separate windows
osk_window_layout panel_layout{}; // Only used with separate windows
u32 input_field_window_width = 0; // Only used with separate windows
f32 input_field_background_transparency = 1.0f; // Only used with separate windows
f32 initial_scale = 1.0f;
color base_color{};
bool dimmer_enabled = false;
bool use_separate_windows = false;
bool intercept_input = false;
};
virtual void Create(const osk_params& params) = 0;
virtual void Clear(bool clear_all_data) = 0;
virtual void Insert(const std::u16string& text) = 0;
virtual void SetText(const std::u16string& text) = 0;
// Closes the dialog.
// Set status to CELL_OSKDIALOG_CLOSE_CONFIRM or CELL_OSKDIALOG_CLOSE_CANCEL for user input.
// Set status to -1 if closed by the game or system.
// Set status to -2 if terminated by the system.
virtual void Close(s32 status) = 0;
virtual ~OskDialogBase();
virtual ~OskDialogBase() {};
std::function<void(s32 status)> on_osk_close;
std::function<void(CellOskDialogKeyMessage key_message)> on_osk_key_input_entered;
atomic_t<OskDialogState> state{ OskDialogState::Unloaded };
atomic_t<bool> pad_input_enabled{ true }; // Determines if the OSK consumes the device's events.
atomic_t<bool> mouse_input_enabled{ true }; // Determines if the OSK consumes the device's events.
atomic_t<bool> keyboard_input_enabled{ true }; // Determines if the OSK consumes the device's events.
atomic_t<bool> ignore_input_events{ false }; // Determines if the OSK ignores all consumed events.
atomic_t<CellOskDialogContinuousMode> continuous_mode{ CELL_OSKDIALOG_CONTINUOUS_MODE_NONE };
atomic_t<CellOskDialogInputDevice> input_device{ CELL_OSKDIALOG_INPUT_DEVICE_PAD }; // The current input device.
atomic_t<bool> pad_input_enabled{ true }; // Determines if the OSK consumes the device's input.
atomic_t<bool> mouse_input_enabled{ true }; // Determines if the OSK consumes the device's input.
atomic_t<bool> keyboard_input_enabled{ true }; // Determines if the OSK consumes the device's input.
atomic_t<bool> ignore_device_events{ false }; // Determines if the OSK ignores device events.
atomic_t<CellOskDialogInputFieldResult> osk_input_result{ CellOskDialogInputFieldResult::CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK };
char16_t osk_text[CELL_OSKDIALOG_STRING_SIZE]{};
std::array<char16_t, CELL_OSKDIALOG_STRING_SIZE> osk_text{};
};
struct osk_info
{
std::shared_ptr<OskDialogBase> dlg;
std::array<char16_t, CELL_OSKDIALOG_STRING_SIZE> valid_text{}; // The string that's going to be served to the game.
shared_mutex text_mtx;
atomic_t<bool> use_separate_windows = false;
atomic_t<bool> lock_ext_input_device = false;
atomic_t<u32> device_mask = 0; // OSK ignores input from the specified devices. 0 means all devices can influence the OSK
atomic_t<u32> input_field_window_width = 0;
atomic_t<f32> input_field_background_transparency = 1.0f;
osk_window_layout input_field_layout_info{};
osk_window_layout input_panel_layout_info{};
atomic_t<u32> key_layout_options = CELL_OSKDIALOG_10KEY_PANEL;
atomic_t<CellOskDialogInitialKeyLayout> initial_key_layout = CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_SYSTEM; // TODO: use
atomic_t<CellOskDialogInputDevice> initial_input_device = CELL_OSKDIALOG_INPUT_DEVICE_PAD; // OSK at first only receives input from the initial device
atomic_t<bool> clipboard_enabled = false; // For copy and paste
atomic_t<bool> half_byte_kana_enabled = false;
atomic_t<u32> supported_languages = 0; // Used to enable non-default languages in the OSK
atomic_t<bool> dimmer_enabled = true;
atomic_t<OskDialogBase::color> base_color = OskDialogBase::color{ 0.2f, 0.2f, 0.2f, 1.0f };
atomic_t<bool> pointer_enabled = false;
atomic_t<f32> pointer_x = 0.0f;
atomic_t<f32> pointer_y = 0.0f;
atomic_t<f32> initial_scale = 1.0f;
osk_window_layout layout = {};
atomic_t<CellOskDialogContinuousMode> osk_continuous_mode = CELL_OSKDIALOG_CONTINUOUS_MODE_NONE;
atomic_t<u32> last_dialog_state = CELL_SYSUTIL_OSKDIALOG_UNLOADED; // Used for continuous seperate window dialog
atomic_t<vm::ptr<cellOskDialogConfirmWordFilterCallback>> osk_confirm_callback{};
atomic_t<vm::ptr<cellOskDialogForceFinishCallback>> osk_force_finish_callback{};
atomic_t<vm::ptr<cellOskDialogHardwareKeyboardEventHookCallback>> osk_hardware_keyboard_event_hook_callback{};
atomic_t<u16> hook_event_mode{0};
stx::init_mutex init;
void reset();
// Align horizontally
static u32 get_aligned_x(u32 layout_mode);
// Align vertically
static u32 get_aligned_y(u32 layout_mode);
};
+56 -110
View File
@@ -141,10 +141,10 @@ error_code cellPadClearBuf(u32 port_no)
if (port_no >= config.max_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto pad = pads[port_no];
const auto& pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;
return not_an_error(CELL_PAD_ERROR_NO_DEVICE);
clear_pad_buffer(pad);
@@ -174,10 +174,10 @@ error_code cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
if (port_no >= config.max_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto pad = pads[port_no];
const auto& pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;
return not_an_error(CELL_PAD_ERROR_NO_DEVICE);
pad_get_data(port_no, data.get_ptr());
return CELL_OK;
@@ -207,7 +207,7 @@ void pad_get_data(u32 port_no, CellPadData* data)
}
else if (pad->ldd)
{
std::memcpy(data, pad->ldd_data, sizeof(CellPadData));
pad->ldd_data = *data;
if (setting & CELL_PAD_SETTING_SENSOR_ON)
data->len = CELL_PAD_LEN_CHANGE_SENSOR_ON;
else
@@ -219,6 +219,15 @@ void pad_get_data(u32 port_no, CellPadData* data)
const u16 d1Initial = pad->m_digital_1;
const u16 d2Initial = pad->m_digital_2;
const auto set_value = [&btnChanged](u16& value, u16 new_value)
{
if (value != new_value)
{
btnChanged = true;
value = new_value;
}
};
for (Button& button : pad->m_buttons)
{
// here we check btns, and set pad accordingly,
@@ -233,22 +242,10 @@ void pad_get_data(u32 port_no, CellPadData* data)
switch (button.m_outKeyCode)
{
case CELL_PAD_CTRL_LEFT:
if (pad->m_press_left != button.m_value) btnChanged = true;
pad->m_press_left = button.m_value;
break;
case CELL_PAD_CTRL_DOWN:
if (pad->m_press_down != button.m_value) btnChanged = true;
pad->m_press_down = button.m_value;
break;
case CELL_PAD_CTRL_RIGHT:
if (pad->m_press_right != button.m_value) btnChanged = true;
pad->m_press_right = button.m_value;
break;
case CELL_PAD_CTRL_UP:
if (pad->m_press_up != button.m_value) btnChanged = true;
pad->m_press_up = button.m_value;
break;
case CELL_PAD_CTRL_LEFT: set_value(pad->m_press_left, button.m_value); break;
case CELL_PAD_CTRL_DOWN: set_value(pad->m_press_down, button.m_value); break;
case CELL_PAD_CTRL_RIGHT: set_value(pad->m_press_right, button.m_value); break;
case CELL_PAD_CTRL_UP: set_value(pad->m_press_up, button.m_value); break;
// These arent pressure btns
case CELL_PAD_CTRL_R3:
case CELL_PAD_CTRL_L3:
@@ -266,38 +263,14 @@ void pad_get_data(u32 port_no, CellPadData* data)
switch (button.m_outKeyCode)
{
case CELL_PAD_CTRL_SQUARE:
if (pad->m_press_square != button.m_value) btnChanged = true;
pad->m_press_square = button.m_value;
break;
case CELL_PAD_CTRL_CROSS:
if (pad->m_press_cross != button.m_value) btnChanged = true;
pad->m_press_cross = button.m_value;
break;
case CELL_PAD_CTRL_CIRCLE:
if (pad->m_press_circle != button.m_value) btnChanged = true;
pad->m_press_circle = button.m_value;
break;
case CELL_PAD_CTRL_TRIANGLE:
if (pad->m_press_triangle != button.m_value) btnChanged = true;
pad->m_press_triangle = button.m_value;
break;
case CELL_PAD_CTRL_R1:
if (pad->m_press_R1 != button.m_value) btnChanged = true;
pad->m_press_R1 = button.m_value;
break;
case CELL_PAD_CTRL_L1:
if (pad->m_press_L1 != button.m_value) btnChanged = true;
pad->m_press_L1 = button.m_value;
break;
case CELL_PAD_CTRL_R2:
if (pad->m_press_R2 != button.m_value) btnChanged = true;
pad->m_press_R2 = button.m_value;
break;
case CELL_PAD_CTRL_L2:
if (pad->m_press_L2 != button.m_value) btnChanged = true;
pad->m_press_L2 = button.m_value;
break;
case CELL_PAD_CTRL_SQUARE: set_value(pad->m_press_square, button.m_value); break;
case CELL_PAD_CTRL_CROSS: set_value(pad->m_press_cross, button.m_value); break;
case CELL_PAD_CTRL_CIRCLE: set_value(pad->m_press_circle, button.m_value); break;
case CELL_PAD_CTRL_TRIANGLE: set_value(pad->m_press_triangle, button.m_value); break;
case CELL_PAD_CTRL_R1: set_value(pad->m_press_R1, button.m_value); break;
case CELL_PAD_CTRL_L1: set_value(pad->m_press_L1, button.m_value); break;
case CELL_PAD_CTRL_R2: set_value(pad->m_press_R2, button.m_value); break;
case CELL_PAD_CTRL_L2: set_value(pad->m_press_L2, button.m_value); break;
default: break;
}
}
@@ -307,22 +280,10 @@ void pad_get_data(u32 port_no, CellPadData* data)
{
switch (stick.m_offset)
{
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
if (pad->m_analog_left_x != stick.m_value) btnChanged = true;
pad->m_analog_left_x = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
if (pad->m_analog_left_y != stick.m_value) btnChanged = true;
pad->m_analog_left_y = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
if (pad->m_analog_right_x != stick.m_value) btnChanged = true;
pad->m_analog_right_x = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
if (pad->m_analog_right_y != stick.m_value) btnChanged = true;
pad->m_analog_right_y = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: set_value(pad->m_analog_left_x, stick.m_value); break;
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: set_value(pad->m_analog_left_y, stick.m_value); break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: set_value(pad->m_analog_right_x, stick.m_value); break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: set_value(pad->m_analog_right_y, stick.m_value); break;
default: break;
}
}
@@ -333,22 +294,10 @@ void pad_get_data(u32 port_no, CellPadData* data)
{
switch (sensor.m_offset)
{
case CELL_PAD_BTN_OFFSET_SENSOR_X:
if (pad->m_sensor_x != sensor.m_value) btnChanged = true;
pad->m_sensor_x = sensor.m_value;
break;
case CELL_PAD_BTN_OFFSET_SENSOR_Y:
if (pad->m_sensor_y != sensor.m_value) btnChanged = true;
pad->m_sensor_y = sensor.m_value;
break;
case CELL_PAD_BTN_OFFSET_SENSOR_Z:
if (pad->m_sensor_z != sensor.m_value) btnChanged = true;
pad->m_sensor_z = sensor.m_value;
break;
case CELL_PAD_BTN_OFFSET_SENSOR_G:
if (pad->m_sensor_g != sensor.m_value) btnChanged = true;
pad->m_sensor_g = sensor.m_value;
break;
case CELL_PAD_BTN_OFFSET_SENSOR_X: set_value(pad->m_sensor_x, sensor.m_value); break;
case CELL_PAD_BTN_OFFSET_SENSOR_Y: set_value(pad->m_sensor_y, sensor.m_value); break;
case CELL_PAD_BTN_OFFSET_SENSOR_Z: set_value(pad->m_sensor_z, sensor.m_value); break;
case CELL_PAD_BTN_OFFSET_SENSOR_G: set_value(pad->m_sensor_g, sensor.m_value); break;
default: break;
}
}
@@ -504,7 +453,7 @@ error_code cellPadPeriphGetData(u32 port_no, vm::ptr<CellPadPeriphData> data)
const auto& pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;
return not_an_error(CELL_PAD_ERROR_NO_DEVICE);
pad_get_data(port_no, &data->cellpad_data);
@@ -536,10 +485,10 @@ error_code cellPadGetRawData(u32 port_no, vm::ptr<CellPadData> data)
if (port_no >= config.max_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto pad = pads[port_no];
const auto& pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;
return not_an_error(CELL_PAD_ERROR_NO_DEVICE);
// ?
@@ -551,7 +500,7 @@ error_code cellPadGetDataExtra(u32 port_no, vm::ptr<u32> device_type, vm::ptr<Ce
sys_io.trace("cellPadGetDataExtra(port_no=%d, device_type=*0x%x, data=*0x%x)", port_no, device_type, data);
// TODO: This is used just to get data from a BD/CEC remote,
// but if the port isnt a remote, device type is set to 0 and just regular cellPadGetData is returned
// but if the port isnt a remote, device type is set to CELL_PAD_DEV_TYPE_STANDARD and just regular cellPadGetData is returned
if (auto err = cellPadGetData(port_no, data))
{
@@ -560,7 +509,7 @@ error_code cellPadGetDataExtra(u32 port_no, vm::ptr<u32> device_type, vm::ptr<Ce
if (device_type) // no error is returned on NULL
{
*device_type = 0;
*device_type = CELL_PAD_DEV_TYPE_STANDARD;
}
// Set BD data
@@ -602,10 +551,10 @@ error_code cellPadSetActDirect(u32 port_no, vm::ptr<CellPadActParam> param)
if (port_no >= config.max_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto pad = pads[port_no];
const auto& pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;
return not_an_error(CELL_PAD_ERROR_NO_DEVICE);
// TODO: find out if this is checked here or later or at all
if (!(pad->m_device_capability & CELL_PAD_CAPABILITY_ACTUATOR))
@@ -750,10 +699,10 @@ error_code cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellPadCapabilityInfo>
if (port_no >= config.max_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto pad = pads[port_no];
const auto& pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;
return not_an_error(CELL_PAD_ERROR_NO_DEVICE);
// Should return the same as device capability mask, psl1ght has it backwards in pad->h
memset(info->info, 0, CELL_PAD_MAX_CAPABILITY_INFO * sizeof(u32));
@@ -782,7 +731,7 @@ error_code cellPadSetPortSetting(u32 port_no, u32 port_setting)
config.port_setting[port_no] = port_setting;
// can also return CELL_PAD_ERROR_UNSUPPORTED_GAMEPAD
// can also return CELL_PAD_ERROR_UNSUPPORTED_GAMEPAD <- Update: seems to be just internal and ignored
return CELL_OK;
}
@@ -808,10 +757,10 @@ error_code cellPadInfoPressMode(u32 port_no)
if (port_no >= config.max_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto pad = pads[port_no];
const auto& pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;
return not_an_error(CELL_PAD_ERROR_NO_DEVICE);
return not_an_error((pad->m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) ? 1 : 0);
}
@@ -837,10 +786,10 @@ error_code cellPadInfoSensorMode(u32 port_no)
if (port_no >= config.max_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const auto pad = pads[port_no];
const auto& pad = pads[port_no];
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return CELL_PAD_ERROR_NO_DEVICE;
return not_an_error(CELL_PAD_ERROR_NO_DEVICE);
return not_an_error((pad->m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) ? 1 : 0);
}
@@ -867,7 +816,7 @@ error_code cellPadSetPressMode(u32 port_no, u32 mode)
if (port_no >= CELL_PAD_MAX_PORT_NUM)
return CELL_OK;
const auto pad = pads[port_no];
const auto& pad = pads[port_no];
// TODO: find out if this is checked here or later or at all
if (!(pad->m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE))
@@ -952,15 +901,15 @@ error_code cellPadLddDataInsert(s32 handle, vm::ptr<CellPadData> data)
return CELL_PAD_ERROR_UNINITIALIZED;
const auto handler = pad::get_current_handler();
auto& pads = handler->GetPads();
if (handle < 0 || !data) // data == NULL stalls on decr
if (handle < 0 || static_cast<u32>(handle) >= pads.size() || !data) // data == NULL stalls on decr
return CELL_PAD_ERROR_INVALID_PARAMETER;
auto& pads = handler->GetPads();
if (!pads[handle]->ldd)
return CELL_PAD_ERROR_NO_DEVICE;
memcpy(pads[handle]->ldd_data, data.get_ptr(), sizeof(CellPadData));
pads[handle]->ldd_data = *data;
return CELL_OK;
}
@@ -977,11 +926,11 @@ error_code cellPadLddGetPortNo(s32 handle)
return CELL_PAD_ERROR_UNINITIALIZED;
const auto handler = pad::get_current_handler();
auto& pads = handler->GetPads();
if (handle < 0)
if (handle < 0 || static_cast<u32>(handle) >= pads.size())
return CELL_PAD_ERROR_INVALID_PARAMETER;
auto& pads = handler->GetPads();
if (!pads[handle]->ldd)
return CELL_PAD_ERROR_FATAL; // might be incorrect
@@ -1001,13 +950,10 @@ error_code cellPadLddUnregisterController(s32 handle)
return CELL_PAD_ERROR_UNINITIALIZED;
const auto handler = pad::get_current_handler();
if (handle < 0)
return CELL_PAD_ERROR_INVALID_PARAMETER;
const auto& pads = handler->GetPads();
// TODO: check if handle >= pads.size()
if (handle < 0 || static_cast<u32>(handle) >= pads.size())
return CELL_PAD_ERROR_INVALID_PARAMETER;
if (!pads[handle]->ldd)
return CELL_PAD_ERROR_NO_DEVICE;
-6
View File
@@ -126,12 +126,6 @@ enum
CELL_PADFILTER_IIR_CUTOFF_2ND_LPF_BT_010 = 2, // 10% Nyquist frequency
};
struct CellPadData
{
be_t<s32> len;
be_t<u16> button[CELL_PAD_MAX_CODES];
};
struct CellPadInfo
{
be_t<u32> max_connect;
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -148,7 +148,7 @@ enum
CELL_REC_SETINFO_MOVIE_START_TIME_MSEC = 100,
CELL_REC_SETINFO_MOVIE_END_TIME_MSEC = 101,
CELL_REC_SETINFO_MOVIE_META = 200,
CELL_REC_SETINFO_SCEME_META = 201,
CELL_REC_SETINFO_SCENE_META = 201,
CELL_REC_MOVIE_META_GAME_TITLE_LEN = 128,
CELL_REC_MOVIE_META_MOVIE_TITLE_LEN = 128,
+29 -29
View File
@@ -259,8 +259,8 @@ error_code cellRtcFormatRfc2822(vm::ptr<char> pszDateTime, vm::cptr<CellRtcTick>
pszDateTime[0xb] = ' ';
// year
char yearDigits[5];
sprintf(yearDigits, "%04hi", u16{date_time->year});
std::array<char, 5> yearDigits{};
snprintf(yearDigits.data(), yearDigits.size(), "%04hi", u16{date_time->year});
pszDateTime[0xc] = yearDigits[0];
pszDateTime[0xd] = yearDigits[1];
pszDateTime[0xe] = yearDigits[2];
@@ -268,22 +268,22 @@ error_code cellRtcFormatRfc2822(vm::ptr<char> pszDateTime, vm::cptr<CellRtcTick>
pszDateTime[0x10] = ' ';
// Hours
char hourDigits[3];
sprintf(hourDigits, "%02hi", u16{date_time->hour});
std::array<char, 3> hourDigits{};
snprintf(hourDigits.data(), hourDigits.size(), "%02hi", u16{date_time->hour});
pszDateTime[0x11] = hourDigits[0];
pszDateTime[0x12] = hourDigits[1];
pszDateTime[0x13] = ':';
// Minutes
char minDigits[3];
sprintf(minDigits, "%02hi", u16{date_time->minute});
std::array<char, 3> minDigits{};
snprintf(minDigits.data(), minDigits.size(), "%02hi", u16{date_time->minute});
pszDateTime[0x14] = minDigits[0];
pszDateTime[0x15] = minDigits[1];
pszDateTime[0x16] = ':';
// Seconds
char secDigits[3];
sprintf(secDigits, "%02hi", u16{date_time->second});
std::array<char, 3> secDigits{};
snprintf(secDigits.data(), secDigits.size(), "%02hi", u16{date_time->second});
pszDateTime[0x17] = secDigits[0];
pszDateTime[0x18] = secDigits[1];
pszDateTime[0x19] = ' ';
@@ -379,8 +379,8 @@ error_code cellRtcFormatRfc3339(vm::ptr<char> pszDateTime, vm::cptr<CellRtcTick>
s32 tzone = iTimeZone;
// Year - XXXX-04-13T10:56:31.35+66:40
char yearDigits[5];
sprintf(yearDigits, "%04hi", u16{date_time->year});
std::array<char, 5> yearDigits{};
snprintf(yearDigits.data(), yearDigits.size(), "%04hi", u16{date_time->year});
pszDateTime[0x0] = yearDigits[0];
pszDateTime[0x1] = yearDigits[1];
pszDateTime[0x2] = yearDigits[2];
@@ -388,43 +388,43 @@ error_code cellRtcFormatRfc3339(vm::ptr<char> pszDateTime, vm::cptr<CellRtcTick>
pszDateTime[0x4] = '-';
// Month - 2020-XX-13T10:56:31.35+66:40
char monthDigits[3];
sprintf(monthDigits, "%02hi", u16{date_time->month});
std::array<char, 3> monthDigits{};
snprintf(monthDigits.data(), monthDigits.size(), "%02hi", u16{date_time->month});
pszDateTime[0x5] = monthDigits[0];
pszDateTime[0x6] = monthDigits[1];
pszDateTime[0x7] = '-';
// Day - 2020-04-XXT10:56:31.35+66:40
char dayDigits[3];
sprintf(dayDigits, "%02hi", u16{date_time->day});
std::array<char, 3> dayDigits{};
snprintf(dayDigits.data(), dayDigits.size(), "%02hi", u16{date_time->day});
pszDateTime[0x8] = dayDigits[0];
pszDateTime[0x9] = dayDigits[1];
pszDateTime[0xa] = 'T';
// Hours - 2020-04-13TXX:56:31.35+66:40
char hourDigits[3];
sprintf(hourDigits, "%02hi", u16{date_time->hour});
std::array<char, 3> hourDigits{};
snprintf(hourDigits.data(), hourDigits.size(), "%02hi", u16{date_time->hour});
pszDateTime[0xb] = hourDigits[0];
pszDateTime[0xc] = hourDigits[1];
pszDateTime[0xd] = ':';
// Minutes - 2020-04-13T10:XX:31.35+66:40
char minDigits[3];
sprintf(minDigits, "%02hi", u16{date_time->minute});
std::array<char, 3> minDigits{};
snprintf(minDigits.data(), minDigits.size(), "%02hi", u16{date_time->minute});
pszDateTime[0xe] = minDigits[0];
pszDateTime[0xf] = minDigits[1];
pszDateTime[0x10] = ':';
// Seconds - 2020-04-13T10:56:XX.35+66:40
char secDigits[3];
sprintf(secDigits, "%02hi", u16{date_time->second});
std::array<char, 3> secDigits{};
snprintf(secDigits.data(), secDigits.size(), "%02hi", u16{date_time->second});
pszDateTime[0x11] = secDigits[0];
pszDateTime[0x12] = secDigits[1];
pszDateTime[0x13] = '.';
// Microseconds - 2020-04-13T10:56:31.XX+66:40
char microDigits[3];
sprintf(microDigits, "%02u", u32{date_time->microsecond});
std::array<char, 3> microDigits{};
snprintf(microDigits.data(), microDigits.size(), "%02u", u32{date_time->microsecond});
pszDateTime[0x14] = microDigits[0];
pszDateTime[0x15] = microDigits[1];
@@ -846,7 +846,7 @@ error_code cellRtcSetTick(vm::ptr<CellRtcDateTime> pTime, vm::cptr<CellRtcTick>
pTime->second = seconds;
pTime->minute = minutes;
pTime->hour = hours;
pTime->day = days_tmp + 1;
pTime->day = ::narrow<u16>(days_tmp + 1);
pTime->month = months;
pTime->year = years;
@@ -1006,10 +1006,10 @@ error_code cellRtcTickAddMonths(vm::ptr<CellRtcTick> pTick0, vm::cptr<CellRtcTic
// Not pretty, but works
s64 total_months = (date_time->year * 12ULL) + date_time->month + iAdd + -1;
s32 total_months_s32 = total_months;
s32 total_months_s32 = ::narrow<s32>(total_months);
u32 unk_1 = total_months_s32 >> 0x1f;
u64 unk_2 = ((total_months_s32 / 6 + unk_1) >> 1) - unk_1;
u32 unk_3 = unk_2;
u32 unk_3 = ::narrow<u32>(unk_2);
unk_1 = unk_3 & 0xffff;
u64 unk_4 = (total_months - ((u64{unk_3} << 4) - (unk_3 << 2))) + 1;
if (((unk_2 & 0xffff) == 0) || ((unk_3 = unk_4 & 0xffff, (unk_4 & 0xffff) == 0 || (0xc < unk_3))))
@@ -1036,8 +1036,8 @@ error_code cellRtcTickAddMonths(vm::ptr<CellRtcTick> pTick0, vm::cptr<CellRtcTic
date_time->day = month_days;
}
date_time->month = unk_4;
date_time->year = unk_2;
date_time->month = ::narrow<u16>(unk_4);
date_time->year = ::narrow<u16>(unk_2);
cellRtcGetTick(date_time, pTick0);
return CELL_OK;
@@ -1086,7 +1086,7 @@ error_code cellRtcTickAddYears(vm::ptr<CellRtcTick> pTick0, vm::cptr<CellRtcTick
date_time->day = month_days;
}
date_time->year = total_years;
date_time->year = ::narrow<u16>(total_years);
cellRtcGetTick(date_time, pTick0);
return CELL_OK;
@@ -1351,7 +1351,7 @@ error_code cellRtcSetCurrentTick(vm::cptr<CellRtcTick> pTick)
// TODO syscall not implemented
/*
u32 tmp2 = sys_time_get_system_time(tmp / cellRtcGetTickResolution(), (tmp % cellRtcGetTickResolution()) * 1000);
u64 tmp2 = sys_time_get_system_time(tmp / cellRtcGetTickResolution(), (tmp % cellRtcGetTickResolution()) * 1000);
return (tmp2 & (tmp2 | tmp2 - 1) >> 0x1f);
*/

Some files were not shown because too many files have changed in this diff Show More