Compare commits

...

421 Commits

Author SHA1 Message Date
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
Ani a00f9e4211 rpcs3_version: Bump to 0.0.25 2022-11-01 21:50:08 +00:00
brian218 3cb9cd7724 sys_fs: Minor fixup (#12913)
Stubbed sys_fs_newfs
2022-11-01 19:49:50 +03:00
Eladash 9632d0ab8a Emu: fixup message when the application has crashed 2022-11-01 19:08:55 +03:00
brian218 68b68e676b sys_fs.cpp: Satisfy Clang 2022-10-31 18:53:09 +03:00
brian218 c7ced46707 Add support for mounting and unmounting CELL_FS_SIMPLEFS 2022-10-31 18:53:09 +03:00
brian218 ecc194cb62 Use DECR's Product Code when Debug Console Mode is enabled 2022-10-31 18:53:09 +03:00
Nekotekina a1b4ffcf52 VFS.cpp: fixup for mounting files 2022-10-31 14:20:02 +03:00
Nekotekina ae809ad320 Unexpected bugfixes
Mostly unaligned memory access.
Also includes workarounds for ubsan execution.
2022-10-31 14:20:02 +03:00
kd-11 7d1c18a569 Fix LOD bias widget title. 2022-10-31 13:39:37 +03:00
kd-11 71f034c4ea Move 'LOD bias addend' to debug tab 2022-10-31 13:39:37 +03:00
kd-11 b156b40f8f rsx: Fix clear color for formats with less than 32-bit width 2022-10-31 13:39:37 +03:00
Darkhost1999 8d5a9dc722 Add Texture lod bias to UI (#12905) 2022-10-30 21:06:53 +01:00
RipleyTom 06dc6909c4 implement sceNpManagerGetMyLanguages 2022-10-30 18:00:54 +01:00
capriots c639b7d5f4 cellAudioAdd6chData(): fix channel order 2022-10-30 04:50:02 +01:00
Megamouse a38e144320 overlays: use the system keyboard layout for osk 2022-10-29 22:56:08 +02:00
Megamouse 059c45f202 overlays: implement osk keyboard cursor actions 2022-10-29 22:56:08 +02:00
Megamouse eccceea7fb overlays: implement osk delete action 2022-10-29 22:56:08 +02:00
Megamouse ad340c3007 overlays/osk: Implement fallback for unknown keys
Note that those keys won't be passed to the cellOsk event hook callback
2022-10-29 22:56:08 +02:00
Elad Ashkenazi c214f45e14 Savestates/rsx/IO: Resume emulation on long START press, enable "Start Paused" by defaut (#12881)
* Savestates: Enable "Start Paused" by default
* Emu/rsx/IO: Resume emulation on long START press
* rsx: fix missing graphics with savestates' "Start Paused" setting
* rsx/overlays: Add simple reference counting for messages to hide them manually
* Move some code in Emulator::Pause() so thread pausing is the first thing done by this function
2022-10-29 19:53:00 +02:00
Elad Ashkenazi c8620070b9 Savestates/System.cpp: Realized fix for suspend mode (#12883) 2022-10-28 09:51:46 +02:00
brian218 61a371b106 Implemented sys_fs_mount() and sys_fs_unmount() 2022-10-28 08:51:41 +02:00
shinra-electric 5210df6882 [3rdParty] Update MoltenVK to 1.2.231 2022-10-25 07:22:44 +02:00
shinra-electric edb7991979 Remove MVK Semaphore Support Style options
This line is no longer needed as MVK will select the appropriate support style automatically. 

See https://github.com/KhronosGroup/MoltenVK/pull/1738
2022-10-25 07:22:44 +02:00
Elad Ashkenazi 90d6069a16 Update System.cpp 2022-10-24 18:54:53 +03:00
RipleyTom 880a4e3ca6 SceNpScore: improvements 2022-10-24 00:49:44 +02:00
Eladash 18e30c7e44 rsx: Implement custom fractional frame limit 2022-10-24 00:10:37 +02:00
Eladash 0113224cb6 cfg: Implement float config entry
Add missing string empty checks
2022-10-24 00:10:37 +02:00
Eladash d1bd936765 rsx: Unlimit texture LOD bias addend
It's a relative setting and actual bias ranges from -16 to +16, so the maximum difference an addend would make is 32.
2022-10-24 00:10:37 +02:00
kd-11 2c41eecdb1 rsx: Force position invariance on GPUs where it matters 2022-10-24 00:49:44 +03:00
Elad Ashkenazi 1a9e38a1dd System.cpp: Minor regression fix (#12874)
Do not move savestate if the actual boot is unsuccessful.
2022-10-23 18:07:44 +03:00
Eladash 9f3f619774 Minor cleanup 2022-10-23 13:06:57 +02:00
Eladash 795e234c6f game list: Silence some warning 2022-10-23 13:06:57 +02:00
Eladash 23fdcbfeb8 Add one missing line, fix savestate restart 2022-10-23 13:06:57 +02:00
Eladash ee3e36672c Savestates: Rename savestate when booting the game regularly (suspend mode) 2022-10-23 10:49:58 +02:00
Eladash 119b4e4529 Savestates/Menu: Add "Create Savestate" Button 2022-10-23 10:49:58 +02:00
Eladash cc6112cbc4 Savestates: Auto-relaunch savestate when suspen mode is off 2022-10-23 10:49:58 +02:00
Eladash f16c9cd3c6 Savestates: Disable HDD1 saving optimization
HDD1 is very volatile, it was a bad idea not to save it.
2022-10-23 10:49:58 +02:00
Eladash 9e4c24baa3 qt: Add "suspend Emulation Mode Savestates" to advanced tab 2022-10-23 10:49:58 +02:00
Elad Ashkenazi 801609fb78 Make RPCS3 not delete savestate on boot by default 2022-10-23 10:49:58 +02:00
Megamouse 4c8630d29f sceNpTrophyRegisterContext: log tls error 2022-10-22 22:30:23 +02:00
Megamouse 4e426af114 Qt: replace nul character with 0 in the log viewer
Fixes cropped content
2022-10-22 22:30:23 +02:00
Megamouse 5b66fe47db sceNpTrophyCreateContext: do not log nul characters 2022-10-22 22:30:23 +02:00
RipleyTom 7ae9b15b5c sys_net: return appropriate packet size for P2P 2022-10-22 20:14:32 +03:00
RipleyTom 67323994fc Implement sceNpScoreSanitizeComment 2022-10-22 18:43:13 +02:00
kd-11 fcc7a7452a vk: Fix scratch buf size calculation when uploading DSVs 2022-10-22 15:11:40 +03:00
kd-11 1bb0caed6f gl: Add missing memory barrier after texture decode 2022-10-22 15:11:40 +03:00
Elad Ashkenazi 23a445619b Savestates: +1 Bug 2022-10-22 13:37:33 +02:00
RipleyTom 837d9ca688 Disable AlignConsecutiveAssignments 2022-10-22 11:32:04 +02:00
RipleyTom 9b121a6414 sys_net: improvements
sys_net: implement reusable addr for p2p sockets
sys_net: implement getpeername for P2PS
sys_net: sockets inherit NBIO from their parent
2022-10-22 11:32:04 +02:00
Megamouse 5f1aafb961 Dualsense: Enable improved rumble emulation (or so)
Also disable audio haptics to save power
2022-10-22 10:26:26 +02:00
Megamouse 615ff08d1a Dualsense: Release LEDs on when the handler is destroyed 2022-10-22 10:26:26 +02:00
Megamouse 3320d1e1c7 Dualsense: Read firmware version as seen in firmware installer 2022-10-22 10:26:26 +02:00
Megamouse 3deb177ab7 Dualsense: name some report members based on SDL2 2022-10-22 10:26:26 +02:00
Megamouse 41dad58489 Loader/Input: Process Qt events instead of yielding during init 2022-10-21 23:42:01 +02:00
Megamouse cb8a240f1a Qt/Input: Properly clear pad selection in pad settings
Fixes a rare issue that causes a newly selected pad handler with no pads to try to connect a previously selected pad from another handler.
2022-10-21 23:42:01 +02:00
Megamouse 871ef2cdfe Input: return pad connection in get_next_button_press
This fix some minor race condition in the UI that had no real consequences just by chance.
2022-10-21 23:42:01 +02:00
Megamouse 6c0bc43776 Input: change brightness data type in hid to u32 2022-10-21 23:42:01 +02:00
Megamouse a16d18d83c Input: rename misleading ThreadProc to process 2022-10-21 23:42:01 +02:00
Megamouse e499c3c6e3 Input: move m_is_init to base class 2022-10-21 23:42:01 +02:00
Megamouse ddd261c943 Input: refactor vibration
There's no need to deal with vibration levels outside of the handlers.
All we need to know is the 0-255 DS3 range which is given by the u8 type.
2022-10-21 23:42:01 +02:00
Vestral a1f9ff0aaa Cubeb: rewrite locking 2022-10-21 22:15:49 +02:00
Megamouse d636ea9338 Update dependencies
zlib  1.2.12 -> 1.2.13
libpng 1.6.37 -> 1.6.38
glslang sdk-1.3.216.0 -> sdk-1.3.224.1
SPIRV-Headers sdk-1.3.211.0 -> sdk-1.3.224.1
SPIRV-Tools sdk-1.3.211.0 -> sdk-1.3.224.1
2022-10-21 20:44:46 +02:00
Megamouse 1747e68d1d Fix warning 2022-10-21 20:44:46 +02:00
Elad Ashkenazi c4c710d39d GUI TTY: fix a regression (#12855) 2022-10-21 19:05:21 +02:00
brian218 9a5dbda063 Changed the log level of LV2 Watchdog's being triggered 2022-10-21 17:38:59 +02:00
kd-11 bd9c876e36 gl: Handle clip plane switching using API calls and the state tracker 2022-10-21 13:45:45 +03:00
Eladash 903d847058 cellAudio: Implement setting to disable sampling skip 2022-10-21 09:32:49 +02:00
brian218 789e42e26f sys_sm_shutdown() log minor fixup 2022-10-21 02:09:08 +02:00
brian218 85e11ca341 USIO Input Enhancement 2022-10-20 21:00:38 +02:00
Eladash 0da81d22d3 SPU Profiler: fix CPU usage when emulation is paused
Avoid collecting samples when the thread paused.
2022-10-20 11:22:33 +03:00
Eladash 52b993095d SPU Profiler: nearly always print on Emu.Pause() 2022-10-20 11:22:33 +03:00
Megamouse 363e0a40e5 Input: Allow to toggle player LED (Dualsense and DS3) 2022-10-19 22:55:50 +02:00
Eladash 7ea0a6d642 sys_game_watchdog minor fixups 2022-10-18 13:08:48 +02:00
Megamouse 035d410a89 evdev: change default axis for gyro 2022-10-18 00:19:01 +02:00
Megamouse b0b42071f2 Input: Fix Dualsense gyro axis and adjust DS4 resolution 2022-10-18 00:19:01 +02:00
brian218 5c24009eb5 Implemented sys_game_watchdog syscalls 2022-10-17 20:32:01 +03:00
Eladash 00340f33c3 GUI/TTY: fix UI deadlock when TTY is being spammed 2022-10-17 19:12:51 +03:00
RipleyTom 01c285fc4a RPCN v0.7
Bump protocol version
Improve signaling RTT calculation for client
Implement score game data functions
Various sceNpScore fixes
Verify flatbuffer buffers
Use std::variant for transaction specific data
2022-10-17 09:57:10 +02:00
Eladash 87797e117e sys_spu: Some more fixes of wait flag misuse 2022-10-16 20:55:36 +03:00
Eladash a5cc9a5517 Update cellFsGetDirectoryEntries to use wait flag correctly 2022-10-16 20:55:36 +03:00
Eladash 806acf8cd0 sys_fs: Fixed placement of check_state() and add some bugfixes 2022-10-16 20:55:36 +03:00
kd-11 04f6302ecc Fix decode shader compilation 2022-10-16 19:58:30 +03:00
kd-11 1df977fae2 gl: Avoid including unnecessary headers 2022-10-16 19:58:30 +03:00
kd-11 9105c2cf4a gl: Refactor capabilities and add GLSL version detection support. 2022-10-16 19:58:30 +03:00
kd-11 6d43fcf8fb gl: Fall back to renderpass decoder on ATI drivers 2022-10-16 19:58:30 +03:00
Megamouse fafae1cbb5 cellRtc: Fix some param checks 2022-10-15 19:56:53 +02:00
brian218 419e673d5b Fix USIO Backup behavior 2022-10-15 14:38:43 +02:00
brian218 48f47de95c Added USB passthrough for H050 USJ PCB 2022-10-15 14:38:43 +02:00
brian218 44a1df4353 usb_device: Updated control_transfer in order to prevent some games from being frozen 2022-10-15 14:38:43 +02:00
Megamouse 13b3c78c7f Input: fix MMJOY axis identification 2022-10-15 13:17:16 +02:00
Megamouse e362c2c078 Input: fix some type warnings 2022-10-15 13:17:16 +02:00
Megamouse 814adbb8c4 Input: simplify InitPadConfig 2022-10-15 13:17:16 +02:00
Megamouse cf86b6c107 Input: keep old port status when reconnecting ldd pads
The port status might not change currently, but it should be more correct this way.
2022-10-12 22:30:09 +02:00
Megamouse 12a83e5a1c Input: simplify unnecessarily complex ldd reload 2022-10-12 22:30:09 +02:00
Megamouse 0f769eec81 Input: log more pad information 2022-10-12 21:01:02 +02:00
kd-11 0737c788fc rsx: Fix parsing of broken command streams with hanging begin/end commands without a pair.
- While these are game bugs, the parser shouldn't break on encountering them.
2022-10-12 11:19:52 +03:00
kd-11 3fe9aea5b5 rsx/overlays: Allow some basic communication from the UI components to the backend renderers 2022-10-11 23:13:12 +02:00
Megamouse ab6ba848b8 overlays: simplify overlay_media_list_dialog 2022-10-11 23:13:12 +02:00
Elad Ashkenazi 0a38800e44 Savestates: fix endless renaming of used savestates (#12780) 2022-10-11 17:02:25 +03:00
kd-11 6be5618d22 config: Add missing option 2022-10-11 14:00:34 +03:00
kd-11 95d9462a71 settings: Remove misleading comment 2022-10-11 14:00:34 +03:00
kd-11 e05cd9f47b qt: Add translation for shader precision 2022-10-11 14:00:34 +03:00
kd-11 aa09302ca0 Clean up some unnecessary changes
- Hopefully nothing breaks 🤞
2022-10-11 14:00:34 +03:00
kd-11 6d6b9fd269 Qt: Apply tooltip hover to parent groupbox.
Co-authored-by: Megamouse <studienricky89@googlemail.com>
2022-10-11 14:00:34 +03:00
kd-11 6d265452cf rsxqt: Fix shader precision tooltip 2022-10-11 14:00:34 +03:00
kd-11 65d20f2d08 gl: Add mesa support for polygon offset 2022-10-11 14:00:34 +03:00
kd-11 a229e30b08 rsx: Implement RSX-compliant polygon offset 2022-10-11 14:00:34 +03:00
kd-11 d246a37b11 rsx: Move fp16 toggle to a global shader precision option 2022-10-11 14:00:34 +03:00
brian218 e839595053 Implemented sys_game_get_system_sw_version() 2022-10-11 08:32:49 +02:00
brian218 a711eb31f4 Corrected the implementation of sys_game_board_storage_read() 2022-10-11 08:32:49 +02:00
brian218 b117a6d4cd Improved the compatibility of USIO for old versions of games 2022-10-11 07:51:21 +02:00
Megamouse 36b1004e26 cubeb: ignore callbacks for unknown streams or contexts 2022-10-11 00:09:28 +02:00
Megamouse c75c47fdd2 cubeb: add some more logging and error checks 2022-10-11 00:09:28 +02:00
Megamouse 0f626c8d30 Qt: delay first log frame update
This fixes the log not scrolling automatically when we first open RPCS3 with a low log level.
2022-10-10 23:21:49 +02:00
Megamouse 021783dcc1 Qt: throw if a translation is expected in GetLocalizedSetting 2022-10-10 22:46:42 +02:00
Megamouse 1f339862db Qt: add missing translation comment 2022-10-10 22:46:42 +02:00
Megamouse 4446d9ce4b cellSubDisplay: add error checks 2022-10-10 21:26:27 +02:00
Elad Ashkenazi 92b08a4faf rsx: Fixup a bug after mfc list optimization (#12782) 2022-10-10 04:04:41 +03:00
brian218 d311b4bd53 Update sys_game_board_storage_read() 2022-10-09 21:05:10 +03:00
Eladash a6dfc3be2f SPU: Enable the MFC list optimization for Atomic RSX FIFO 2022-10-09 19:27:46 +03:00
Eladash 750e7b73e3 Optimize vm::range_lock a bit
Bad conditions led to optimization misses and long-generated code.
2022-10-09 19:27:46 +03:00
Eladash 6a36967e6f SPU: Inline and batch MFC list transfers 2022-10-09 19:27:46 +03:00
kd-11 d6d7ade6e3 vk: Reload state on dynamic state changed 2022-10-09 03:00:39 +03:00
shinra-electric 151d98df51 Update based on feedback by GovanifY 2022-10-09 02:16:08 +03:00
shinra-electric fa744e53d3 Replace sprintf with snprintf to silence compiler warning
This fixes the following compiler deprecation warning

`warning: 'sprintf' is deprecated: This function is provided for compatibility reasons only.  Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead.`
2022-10-09 02:16:08 +03:00
Elad Ashkenazi e0df2c584f rsx: Attempt to fix frame limiter 2022-10-09 01:33:40 +03:00
kd-11 3c88477270 Fixup for scissor/viewport invalidation rules 2022-10-07 15:27:54 +03:00
kd-11 df46e5137c gl: Fix texture reconstruction logic
- Use correct target types
- Fix key generation to apply differently for each target type
2022-10-07 11:53:34 +03:00
kd-11 ffe8133865 vk: Avoid unnecessary dynamic state updates 2022-10-07 11:53:34 +03:00
kd-11 7140e82189 rsx: Fix program invalidation rules 2022-10-07 11:53:34 +03:00
Elad Ashkenazi cb743da215 sys_spu: fixup raw spu destroy regression
Caused a missed cpu_thread::state notification which is required now.
2022-10-06 12:23:51 +03:00
Elad Ashkenazi 4d24ba1f35 PPU Precompilation: Abort compilation as soon as possible on Emu.Stop() 2022-10-06 12:23:51 +03:00
kd-11 87411da95f gl: Explicitly declare gl_Position as invariant when using MESA 2022-10-06 06:41:24 +03:00
Eladash d25d1ecb3a LV2: Avoid using multi-variable atomic waiting on cpu_thread::state wait 2022-10-04 16:28:34 +03:00
Eladash 2a00a88e2a SPU LLVM: don't force-enter process_mfc_cmd() because it's slower 2022-10-04 16:28:34 +03:00
Eladash b01220d2c5 debugger: Don't refresh no-thread window at a high rate 2022-10-04 16:28:34 +03:00
Eladash 58dd2bff41 Savestates: Fix unintentional pause when saving with HLE VDEC contexts 2022-10-04 14:14:38 +03:00
Eladash f34773ed73 Savestates: Make Ctrl+R work when not ingame
Restore old behavior of Ctrl+R making it restart emulation when stoppped.
2022-10-04 14:14:38 +03:00
Eladash 9b5cc7cda7 System.cpp: Fix RSX thread abort 2022-10-04 14:14:38 +03:00
Elad Ashkenazi 77db8f04b9 Savestates: fix saving in HLE functions 2022-10-04 14:14:38 +03:00
Eladash 9319bc579c cellAudio: Always send periodic sampling events 2022-10-04 13:41:57 +03:00
kd-11 73784b9e12 Fix GCC build 2022-10-03 12:57:16 +03:00
kd-11 533f960854 rsx: Handle some more corner cases 2022-10-03 12:57:16 +03:00
kd-11 765208a181 rsx: Avoid clobbering CELL memory when splitting fbos 2022-10-03 12:57:16 +03:00
kd-11 4417701ea7 rsx: Track orphaned surfaces' parent addresses 2022-10-03 12:57:16 +03:00
kd-11 f66eaf8f44 rsx: Add some handy util functions to simple_array 2022-10-03 12:57:16 +03:00
kd-11 0dd9c386ee Fix running the emulator with AUDIT enabled 2022-10-03 12:57:16 +03:00
Eladash af8c871411 Add origin PRX names for log messages 2022-10-02 20:03:27 +03:00
brian218 50e1e6596e USIO Backup Minor Optimization 2022-10-01 17:32:22 +03:00
Malcolm Jestadt d8897c585d PPU/SPU LLVM: Allow Zen4 cpus to use VPERMI2B/VPERMT2B instead of the vperm2b256to128 path
- Zen4 based cpus can process VPERM2B in a single uop, unlike intel where it is 3 uops.
2022-10-01 15:38:29 +03:00
Megamouse 7d32dc312f Qt: pad settings: clear input data on thread pause
Fixes incorrectly disabled buttons when changing from a handler with a disconnected pad to any other handler
2022-10-01 13:49:58 +02:00
RipleyTom eff1e4bd7e CELL_NET_CTL_INFO_IP_ADDRESS returns external address 2022-10-01 11:56:41 +02:00
nastys ac50b46608 Mac CI fixes 2022-10-01 11:01:21 +02:00
kd-11 a0e2a3db1d Fix underflow in ZCULL sync 2022-09-30 23:44:37 +03:00
Elad Ashkenazi 0cc981ec18 SPU: fix atomicity of inaccurate GETLLAR 2022-09-30 15:26:08 +03:00
RipleyTom 8170b91f76 sceNpScore: return error on 0 scores returned 2022-09-28 21:58:11 +02:00
RipleyTom d1a7bb0136 Fix faulty GetScoreFriendsRequest 2022-09-28 21:58:11 +02:00
RipleyTom 56caa10e56 Fix blocking raw socket recvfrom 2022-09-28 21:58:11 +02:00
brian218 926496b59d USIO: Save Game Settings - Full Implementation 2022-09-28 16:54:55 +03:00
kd-11 102d30db2d vk: Update support for framebuffer loops to comply with current spec 2022-09-28 12:55:31 +03:00
kd-11 5281a85b67 rsx: Fix compiler warnings 2022-09-28 12:55:31 +03:00
kd-11 de28c812e8 rsx: Re-evaluate color MRT setup when the surface target type changes 2022-09-28 12:55:31 +03:00
RipleyTom eea73deab3 RPCN v0.6 2022-09-27 23:39:54 +03:00
kd-11 67c02e3522 vk: Bump compute descriptor pool size to 8k
- TODO: This should be dynamic.
2022-09-27 14:58:47 +03:00
kd-11 19dd2a693b gl: Fix transform job assert 2022-09-27 14:58:47 +03:00
Ani 3df133652a gui: Rename full width AVX-512 (#12709)
Some people think that this is a toggle to enable and disable AVX-512 support, let's make it more clear
2022-09-26 23:40:04 +01:00
xddxd 80d2034083 Update LLVM commit (Zen Detection) 2022-09-26 20:40:26 +01:00
shinra-electric db9389d24c [macOS] Ask CMake to look in the right place for include & link directories (#12516)
* Ask CMake to look in the right place for include_directories and link_directories on macOS (arm64 and x86_64)

Homebrew installs to a different location on Arm Macs compared to Intel Macs. 

This change prevents this error when compiling on Arm:   
`ld: warning: directory not found for option '-L/opt/local/lib'`

Use STREQUAL instead of MATCHES, since MATCHES is supposed to be used with regular expressions. 

Also update the homebrew directories for Intel, since they were wrong.

Remove the conditional check for x86 Apple, as usr/local is part of the default search path.
Tested on Intel and the warning does not appear.
2022-09-26 18:07:05 +01:00
brian218 c996be321c sys_game_board_storage_read(): Add more known code & Improve byte casting 2022-09-26 17:17:49 +01:00
Nekotekina 6ff6a4989a Implement at32() util
Works like .at() but uses source location for "exception".
2022-09-26 18:04:15 +03:00
cohaereo 2655255d4d sys_net: Implement sys_net_bnet_sendmsg for native sockets 2022-09-25 18:24:47 +03:00
Eladash 8485afa3a5 PPU debugger: report ppu_thread::ack_suspend state 2022-09-25 14:31:39 +03:00
Eladash 2759091ede Debugger: Rewind SPU captures
Very basic implementation, can be improved.
2022-09-25 14:31:39 +03:00
Eladash ae02b71a85 Savestates/Debugger: fix mfc debug option with savestates 2022-09-25 14:31:39 +03:00
Eladash 4445569bb0 Savestates: Don't actually delete savestates 2022-09-25 14:31:39 +03:00
Nekotekina a604394b20 BufferUtils: fix regression on AVX path
primitive_restart_impl::upload_untouched was broken.
Bug in vec_broadcast_gpr on AVX path.
2022-09-24 17:23:12 +03:00
kd-11 dd8a337b14 rsx: Fix some more warnings 2022-09-22 23:46:48 +03:00
kd-11 0572d44996 gl: Fix enum collision 2022-09-22 23:46:48 +03:00
kd-11 38aa116c59 Fix build 2022-09-22 23:46:48 +03:00
kd-11 61666bae69 rsx: Fix hardware deswizzle not getting used when hardware deswizzle flag is not set 2022-09-22 23:46:48 +03:00
kd-11 362a26a404 gl: Fix D24X8 accelerated encode/decode
- PS3 D24X8 is swapped as a full word, unlike PC.
- Add missing paths to handle custom swap behavior.
2022-09-22 23:46:48 +03:00
kd-11 81fa3da101 gl: Minor optimization around test..set patterns in the state tracker 2022-09-22 23:46:48 +03:00
RipleyTom bd1fb86492 Fix pkg batch install dlg on linux 2022-09-22 19:41:09 +02:00
Elad Ashkenazi 238298f695 sys_ppu_thread: Fix surmixer hack (#12689)
* sys_ppu_thread: Fix surmixer hack

* Hotfix after #12678
2022-09-21 21:10:59 +03:00
Eladash 194f7375da SPU/LV2: Fix tiny race conditions 2022-09-21 20:35:34 +03:00
brian218 3581c5b078 USIO: Save Game Settings 2022-09-21 14:43:24 +03:00
Marc Riera c5572acd38 Allow USB passthrough for Densha de GO! controller 2022-09-21 12:04:16 +03:00
nastys acc2fea7e3 Update MoltenVK to 250e1f9 and single queue (#12620) 2022-09-20 11:12:27 +03:00
kd-11 3dc7b64fa1 rsx: Fix initialization of null cubemap resources 2022-09-19 19:13:46 +03:00
kd-11 79f2c21dfb gl: Restrict compute image bindings to [0-8]
NVIDIA only supports 8 compute image slots even on modern GPUs.
2022-09-19 01:37:10 +03:00
kd-11 df36c44bc2 gl: Avoid UBO/SSBO binding index collisions
- Some drivers don't like this. Actually only RADV.
- Almost all GPUs going back 15 years have a large number of UBO slots but limited SSBO slots.
  Move UBO slots up as we have tons more headroom there.
2022-09-19 01:37:10 +03:00
Nekotekina c4db65cc08 Fix one more warning 2022-09-18 18:35:17 +03:00
Nekotekina c86ddb3b7d cellImeJp: fix regression 2022-09-18 18:35:17 +03:00
Florin9doi a1aebdc5d6 Request macOS 10.14.+ permissions (#12600) 2022-09-17 18:26:22 +01:00
Nekotekina b49a1f27eb Warning fixes 2022-09-17 16:35:02 +03:00
brian218 e7fd84e031 USIO: Keep LastGameStatus Memory 2022-09-17 10:59:28 +03:00
Eladash 9d9e18f614 CPU preemption control: don't yield if we can't stop 2022-09-16 18:57:55 +03:00
Eladash c8199de188 CPU preemption control: Improve stutter elimination 2022-09-16 18:57:55 +03:00
Eladash fc331da883 CPU preemption control: remove yield before thread stop 2022-09-16 18:57:55 +03:00
Eladash b6d3fa8c66 CPU preemption control: avoidance in reservation operations 2022-09-16 18:57:55 +03:00
Eladash 3cebea1801 CPU preemption control: extend range to 400 2022-09-16 18:57:55 +03:00
Eladash 2e9ee81dcd CPU preemption control: Improve analysis 2022-09-16 18:57:55 +03:00
Eladash cf4da5c4d1 CPU preemption control: bugfixes 2022-09-16 18:57:55 +03:00
Eladash 9d1ec0b319 CPU preemption control: try to minimize sleep time gaps between setups 2022-09-16 18:57:55 +03:00
Eladash 9c5108c1ca CPU preemption control: Add one more debug variable 2022-09-16 18:57:55 +03:00
Eladash 2807be7080 SPU: Regression fix after #12648 2022-09-13 20:11:30 +03:00
Eladash ec7b18dab5 Implement independent CPU preemptions 2022-09-13 19:28:20 +03:00
brian218 b9e20dc5c9 sys_game_board_storage_read(): Fix regression after #12637 2022-09-13 12:57:43 +03:00
Eladash cfdc852f03 SPU: Power consumption reduction when using SPU inaccurate reservations 2022-09-13 11:21:01 +03:00
Eladash 92514e33bb Avoid reservation notifications in liblv2.sprx 2022-09-13 11:21:01 +03:00
kd-11 572a2a06d1 rsx: Properly reset occlusion counters even when the register is not in use. 2022-09-12 17:15:06 +03:00
Eladash f076fcd539 cellMusic: Implement some error checking 2022-09-12 15:04:23 +03:00
Eladash 4ac59875af ppu: add some debug information 2022-09-12 15:04:23 +03:00
Eladash 780ca38f2f SPU: Extend Inaccurate SPU reservations 2022-09-12 14:16:39 +03:00
Ethan Rushbrook 97ea5e9dba readme: improvements
Fixed platform availability
Fixed discord link (discord.me is not valid)
2022-09-12 13:34:58 +03:00
Yui 9e83bc6544 Add the ability to set the PSID from the configuration (#12637) 2022-09-12 13:23:13 +03:00
Eladash 37aefe5811 sys_ppu_thread: Fix max thread name size 2022-09-12 12:57:39 +03:00
kd-11 d686b48f65 rsx: Simplify FIFO concurrent access. 2022-09-09 23:17:27 +03:00
kd-11 f319362e35 vk: Fix queue concurrency behavior for images 2022-09-09 23:17:27 +03:00
kd-11 0d9b1654ec asm: Avoid ALU instructions on busy wait cycles 2022-09-09 23:17:27 +03:00
kd-11 940e726754 rsx: Minor FIFO cleanup 2022-09-09 23:17:27 +03:00
kd-11 f43824762a rsx: Get rid of an allocation in analyse_vertex_data that adds about 5% overhead.
This method is called many thousands of times per frame and that single allocation introduces a small perf hit.
Just get rid of it, it doesn't improve anything to have it there.
2022-09-09 23:17:27 +03:00
kd-11 cd53bb7eff rsx: Avoid on-the-fly ZCULL allocations with unordered_map 2022-09-09 23:17:27 +03:00
Eladash 60fc90bb8e System.cpp: Fix Create Firmware Cache 2022-09-08 19:38:11 +03:00
Nekotekina a9437d69ab simd_builder: fixups
Fix resetting vmask in reduce() step.
Fix AVX-512 loads in vec_load_unaligned().
Fix bzhi reg size in build_look().
2022-09-08 18:12:15 +03:00
Nekotekina 5d91caebe9 Linux: delete /tmp/perf.map on exit 2022-09-08 16:56:06 +03:00
Eladash eb4131e1c7 cellGame: Minor revert
I think there are many more bugs here..
2022-09-07 20:42:23 +03:00
Eladash 07f0ba213e SPU: Allow special channel storage in channel busy waiting period
Move code to SPUThread.cpp.
2022-09-07 20:42:23 +03:00
Eladash 48382564d1 SPU: Implement "quintuple" Inbound MBOX storage 2022-09-07 20:42:23 +03:00
Eladash 274386a078 rsx: Add some debugging information 2022-09-07 18:39:32 +03:00
Eladash 557d015662 System.cpp: Fix Create PPU Cache regression 2022-09-07 18:39:32 +03:00
Nekotekina 5985f0eefa BufferUtils: cleanup regarding ARM64 2022-09-07 17:59:07 +03:00
Nekotekina 82258915da BufferUtils: rewrite remaining intrinsic code with simd_builder 2022-09-07 17:59:07 +03:00
Nekotekina 11a1f090d3 BufferUtils: simd_builder refactoring
Some simplifications implemented.
2022-09-07 17:59:07 +03:00
sguo35 a0d48c588a spu/arm64: clean up assembly code generation
Clean up asmjit usage so we don't unnecessarily allocate memory
anymore for SPURecompiler functions.
2022-09-07 17:33:01 +03:00
Eladash 5e2424da58 IdManager.cpp: Fix cellFs IDs 2022-09-07 17:05:51 +03:00
Eladash 72a6696f5c cellGame Fix PS3 disc insert 2022-09-07 17:05:51 +03:00
brian218 9087116ee5 Fix USIO fault when it received unsupported FW commands 2022-09-07 16:42:37 +03:00
Eladash 89e0dcba5e cellVdec: Adjust for reservations 2022-09-07 16:05:56 +03:00
Eladash 7698064f5a SPU: Untangle VM lock to avoid deadlocks 2022-09-07 16:05:56 +03:00
Megamouse ab31e96385 Qt: batch stack suffix updates
No need to patch the suffix every single time. We can just do it when we exit the stack loop.
2022-09-05 21:20:14 +02:00
Megamouse a9dcad629b Qt: fix weird missing space in stack log 2022-09-05 21:20:14 +02:00
Megamouse e49679484a Qt: simplify log logic. We can in fact only flush once.
Also invert a negation
2022-09-05 21:20:14 +02:00
Elad Ashkenazi 290226539f Fix ARM build (#12606) 2022-09-04 21:11:04 +03:00
brian218 75efc79930 Implemented sys_game_board_storage_read() 2022-09-04 13:28:05 +03:00
Nick Renieris 905496e926 PPU: Fix STVLX
Fixes Sly 2 and Sly 3 crash on boot (RSX desync).
2022-09-04 12:27:29 +03:00
srive 64579eef7e Update tooltips.h 2022-09-02 08:59:08 +02:00
Elad Ashkenazi e0a648240f Unlog sceNpUtilCmpNpId 2022-09-02 08:29:09 +02:00
Eladash 7bad8f3348 Savestates/SPU: Minor fixup after fb01ed55 2022-09-01 20:09:28 +03:00
Eladash 11a197a387 Savestates/RSX: fix unintentional vblank thread spin after abort 2022-09-01 20:09:28 +03:00
Eladash ee1384341e rsx: Implement atomic vertex upload (with Strict Rendering Mode) 2022-09-01 20:09:28 +03:00
Eladash fb01ed55e5 SPU: Fix potential deadlock in event queue syscalls 2022-09-01 19:03:38 +03:00
Elad Ashkenazi 5a0a5d9ff1 vm.cpp: Fix emulation stopping on SPU access violation (#12586) 2022-09-01 18:23:18 +03:00
Nekotekina 58e3232710 BufferUtils: Fix regression in upload_untouched 2022-09-01 17:39:04 +03:00
460 changed files with 22194 additions and 6449 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
+1 -1
View File
@@ -19,7 +19,7 @@ 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 \
-DUSE_SDL=ON -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 \
-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 \
+1 -1
View File
@@ -14,7 +14,7 @@ echo "AVVER=$AVVER" >> ../.ci/ci-vars.env
cd bin
mkdir "rpcs3.app/Contents/lib/"
cp "/usr/local/opt/llvm@13/lib/libc++abi.1.0.dylib" "rpcs3.app/Contents/lib/libc++abi.1.dylib"
cp "/usr/local/opt/llvm@13/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" \
+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 \
+3 -3
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:
+1 -1
View File
@@ -21,7 +21,7 @@ Cpp11BracedListStyle: true
IndentCaseLabels: false
SortIncludes: false
ReflowComments: true
AlignConsecutiveAssignments: true
AlignConsecutiveAssignments: false
AlignTrailingComments: true
AlignAfterOpenBracket: DontAlign
ConstructorInitializerAllOnOneLineOrOnePerLine: false
+4
View File
@@ -76,3 +76,7 @@
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
+25 -2
View File
@@ -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)
@@ -329,6 +329,28 @@ 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()
# add nice ALIAS targets for ease of use
if(USE_SYSTEM_LIBUSB)
add_library(3rdparty::libusb ALIAS usb-1.0-shared)
@@ -355,3 +377,4 @@ 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})
+1 -1
View File
@@ -4,7 +4,7 @@ include(ExternalProject)
ExternalProject_Add(moltenvk
GIT_REPOSITORY https://github.com/KhronosGroup/MoltenVK.git
GIT_TAG 1112005
GIT_TAG a307b24
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)
set(SDL_SHARED OFF)
set(SDL_SHARED_ENABLED_BY_DEFAULT OFF)
set(SDL_STATIC ON)
set(SDL_STATIC_ENABLED_BY_DEFAULT ON)
set(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 f070c83a60
+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>
+5 -10
View File
@@ -265,9 +265,8 @@ namespace pine
case MsgVersion:
{
char version[256] = {};
sprintf(version, "RPCS3 %s", Impl::get_version_and_branch().c_str());
snprintf(version, sizeof(version), "RPCS3 %s", Impl::get_version_and_branch().c_str());
const u32 size = strlen(version) + 1;
version[size] = 0x00;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
goto error;
ToArray(ret_buffer, size, ret_cnt);
@@ -291,8 +290,7 @@ namespace pine
const auto title_string = Impl::get_title();
const auto size = title_string.size() + 1;
char* title = new char[size];
sprintf(title, "%s", title_string.c_str());
title[size] = 0x00;
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);
@@ -307,8 +305,7 @@ namespace pine
const auto title_id_string = Impl::get_title_ID();
const auto size = title_id_string.size() + 1;
char* title_id = new char[size];
sprintf(title_id, "%s", title_id_string.c_str());
title_id[size] = 0x00;
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);
@@ -323,8 +320,7 @@ namespace pine
const auto hash_string = Impl::get_executable_hash();
const auto size = hash_string.size() + 1;
char* hash = new char[size];
sprintf(hash, "%s", hash_string.c_str());
hash[size] = 0x00;
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);
@@ -339,8 +335,7 @@ namespace pine
const auto game_version_string = Impl::get_app_version();
const auto size = game_version_string.size() + 1;
char* game_version = new char[size];
sprintf(game_version, "%s", game_version_string.c_str());
game_version[size] = 0x00;
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);
+2 -1
View File
@@ -5,9 +5,10 @@ if(USE_SYSTEM_WOLFSSL)
target_link_libraries(wolfssl INTERFACE PkgConfig::WolfSSL)
else()
# TODO(cjj19970505@live.cn)
# OPENSSL_EXTRA, WOLFSSL_DES_ECB and HAVE_SNI are unconfigurable from CMake cache.
# OPENSSL_EXTRA, and HAVE_SNI are unconfigurable from CMake cache.
# but they do have it in a TODO list (wolfssl/CMakeList, 1021)
add_compile_definitions(OPENSSL_EXTRA WOLFSSL_DES_ECB HAVE_SNI HAVE_WRITE_DUP)
add_compile_definitions(FP_MAX_BITS=8192)
set(WOLFSSL_TLS13 "no" CACHE INTERNAL "")
set(WOLFSSL_SHA224 "yes" CACHE INTERNAL "")
+2 -2
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.2.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,7 +22,7 @@ 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))
* [Vulkan SDK 1.2.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://www.libsdl.org/download-2.0.php) (for the FAudio backend)
**If you have an NVIDIA GPU, you may need to install the libglvnd package.**
+5 -3
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")
@@ -104,9 +106,9 @@ if(WIN32)
add_definitions(-D_WIN32_WINNT=0x0602)
endif()
if(APPLE)
include_directories(/opt/local/include)
link_directories(/opt/local/lib)
if(APPLE AND CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
include_directories(/opt/homebrew/include)
link_directories(/opt/homebrew/lib)
endif()
# Warnings are silenced for 3rdparty code
+2 -2
View File
@@ -5,10 +5,10 @@ RPCS3
[![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)
The world's first free and open-source PlayStation 3 emulator/debugger, written in C++ for Windows and Linux.
The world's first free and open-source PlayStation 3 emulator/debugger, written in C++ for Windows, Linux, macOS and FreeBSD.
You can find some basic information on our [**website**](https://rpcs3.net/). Game info is being populated on the [**Wiki**](https://wiki.rpcs3.net/).
For discussion about this emulator, PS3 emulation, and game compatibility reports, please visit our [**forums**](https://forums.rpcs3.net) and our [**Discord server**](https://discord.me/RPCS3).
For discussion about this emulator, PS3 emulation, and game compatibility reports, please visit our [**forums**](https://forums.rpcs3.net) and our [**Discord server**](https://discord.gg/RPCS3).
[**Support Lead Developers Nekotekina and kd-11 on Patreon**](https://www.patreon.com/Nekotekina)
+56 -8
View File
@@ -60,9 +60,15 @@ std::vector<std::string> cfg::make_int_range(s64 min, s64 max)
bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max)
{
if (value.empty())
{
if (out) cfg_log.error("cfg::try_to_uint64(): called with an empty string");
return false;
}
s64 result;
const char* start = &value.front();
const char* end = &value.back() + 1;
const char* start = value.data();
const char* end = start + value.size();
int base = 10;
int sign = +1;
@@ -72,7 +78,7 @@ bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max)
start += 1;
}
if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X'))
if (start[0] == '0' && value.size() >= 2 && (start[1] == 'x' || start[1] == 'X'))
{
// Limited hex support
base = 16;
@@ -106,12 +112,18 @@ std::vector<std::string> cfg::make_uint_range(u64 min, u64 max)
bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max)
{
if (value.empty())
{
if (out) cfg_log.error("cfg::try_to_uint64(): called with an empty string");
return false;
}
u64 result;
const char* start = &value.front();
const char* end = &value.back() + 1;
const char* start = value.data();
const char* end = start + value.size();
int base = 10;
if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X'))
if (start[0] == '0' && value.size() >= 2 && (start[1] == 'x' || start[1] == 'X'))
{
// Limited hex support
base = 16;
@@ -136,6 +148,42 @@ bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max)
return true;
}
std::vector<std::string> cfg::make_float_range(f64 min, f64 max)
{
return {std::to_string(min), std::to_string(max)};
}
bool try_to_float(f64* out, std::string_view value, f64 min, f64 max)
{
if (value.empty())
{
if (out) cfg_log.error("cfg::try_to_float(): called with an empty string");
return false;
}
// std::from_chars float is yet to be implemented on Xcode it seems
// And strtod doesn't support ranged view so we need to ensure it meets a null terminator
const std::string str = std::string{value};
char* end_check{};
const double result = std::strtod(str.data(), &end_check);
if (end_check != str.data() + str.size())
{
if (out) cfg_log.error("cfg::try_to_float('%s'): invalid float", value);
return false;
}
if (result < min || result > max)
{
if (out) cfg_log.error("cfg::try_to_float('%s'): out of bounds (%f..%f)", value, min, max);
return false;
}
if (out) *out = result;
return true;
}
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, std::string_view value)
{
u64 max = umax;
@@ -162,8 +210,8 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
}
u64 result;
const char* start = &value.front();
const char* end = &value.back() + 1;
const char* start = value.data();
const char* end = start + value.size();
int base = 10;
if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X'))
+120 -5
View File
@@ -20,6 +20,9 @@ namespace cfg
// Format min and max unsigned values
std::vector<std::string> make_uint_range(u64 min, u64 max);
// Format min and max float values
std::vector<std::string> make_float_range(f64 min, f64 max);
// Internal hack
bool try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, std::string_view);
@@ -77,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)
@@ -86,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.
@@ -160,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;
@@ -221,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;
@@ -286,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;
@@ -309,6 +343,77 @@ namespace cfg
}
};
// Float entry with custom Min/Max range.
template <s32 Min, s32 Max>
class _float final : public _base
{
static_assert(Min < Max, "Invalid cfg::_float range");
using float_type = f64;
atomic_t<float_type> m_value;
public:
float_type def;
// Expose range
static constexpr float_type max = Max;
static constexpr float_type min = Min;
_float(node* owner, const std::string& name, float_type def = std::min<float_type>(Max, std::max<float_type>(Min, 0)), bool dynamic = false)
: _base(type::_int, owner, name, dynamic)
, m_value(def)
, def(def)
{
}
operator float_type() const
{
return m_value;
}
float_type get() const
{
return m_value;
}
void from_default() override
{
m_value = def;
}
std::string to_string() const override
{
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
{
f64 result;
if (try_to_float(&result, value, Min, Max))
{
m_value = static_cast<float_type>(result);
return true;
}
return false;
}
void set(const f64& value)
{
m_value = static_cast<float_type>(value);
}
std::vector<std::string> to_list() const override
{
return make_float_range(Min, Max);
}
};
// Alias for 32 bit int
using int32 = _int<s32{smin}, s32{smax}>;
@@ -360,6 +465,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;
@@ -431,6 +541,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);
@@ -464,7 +579,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
+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;
+34 -3
View File
@@ -74,7 +74,7 @@ namespace fs
using enable_bitcopy = std::true_type;
constexpr bool operator==(const stat_t&) const = default;
constexpr bool operator==(const stat_t&) const = default;
};
// Helper, layout is equal to iovec struct
@@ -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();
@@ -793,7 +823,8 @@ namespace fs
if (write)
{
m_stat.mtime = std::max(m_stat.atime, ++m_stat.mtime);
m_stat.mtime++;
m_stat.mtime = std::max(m_stat.atime, m_stat.mtime);
m_stat.ctime = m_stat.mtime;
}
}
+143 -83
View File
@@ -20,6 +20,34 @@ LOG_CHANNEL(jit_log, "JIT");
void jit_announce(uptr func, usz size, std::string_view name)
{
#ifdef __linux__
static const struct tmp_perf_map
{
std::string name{fmt::format("/tmp/perf-%d.map", getpid())};
fs::file data{name, fs::rewrite + fs::append};
tmp_perf_map() = default;
tmp_perf_map(const tmp_perf_map&) = delete;
tmp_perf_map& operator=(const tmp_perf_map&) = delete;
~tmp_perf_map()
{
fs::remove_file(name);
}
} s_map;
if (size && name.size())
{
s_map.data.write(fmt::format("%x %x %s\n", func, size, name));
}
if (!func && !size && !name.size())
{
fs::remove_file(s_map.name);
return;
}
#endif
if (!size)
{
jit_log.error("Empty function announced: %s (%p)", name, func);
@@ -83,12 +111,6 @@ void jit_announce(uptr func, usz size, std::string_view name)
dump.write(reinterpret_cast<uchar*>(func), size);
}
}
#ifdef __linux__
static const fs::file s_map(fmt::format("/tmp/perf-%d.map", getpid()), fs::rewrite + fs::append);
s_map.write(fmt::format("%x %x %s\n", func, size, name));
#endif
}
static u8* get_jit_memory()
@@ -357,7 +379,7 @@ asmjit::inline_runtime::~inline_runtime()
asmjit::simd_builder::simd_builder(CodeHolder* ch) noexcept
: native_asm(ch)
{
_init(true);
_init(0);
consts[~v128()] = this->newLabel();
}
@@ -365,9 +387,9 @@ asmjit::simd_builder::~simd_builder()
{
}
void asmjit::simd_builder::_init(bool full)
void asmjit::simd_builder::_init(uint new_vsize)
{
if (full && utils::has_avx512_icl())
if ((!new_vsize && utils::has_avx512_icl()) || new_vsize == 64)
{
v0 = x86::zmm0;
v1 = x86::zmm1;
@@ -377,7 +399,7 @@ void asmjit::simd_builder::_init(bool full)
v5 = x86::zmm5;
vsize = 64;
}
else if (full && utils::has_avx2())
else if ((!new_vsize && utils::has_avx2()) || new_vsize == 32)
{
v0 = x86::ymm0;
v1 = x86::ymm1;
@@ -395,12 +417,13 @@ void asmjit::simd_builder::_init(bool full)
v3 = x86::xmm3;
v4 = x86::xmm4;
v5 = x86::xmm5;
vsize = 16;
vsize = new_vsize ? new_vsize : 16;
}
if (full && utils::has_avx512())
if (utils::has_avx512())
{
vmask = -1;
if (!new_vsize)
vmask = -1;
}
else
{
@@ -480,6 +503,10 @@ void asmjit::simd_builder::vec_clobbering_test(u32 esize, const Operand& v, cons
{
this->emit(x86::Inst::kIdVptest, v, rhs);
}
else if (esize == 16 && utils::has_avx())
{
this->emit(x86::Inst::kIdVptest, v, rhs);
}
else if (esize == 16 && utils::has_sse41())
{
this->emit(x86::Inst::kIdPtest, v, rhs);
@@ -504,6 +531,54 @@ void asmjit::simd_builder::vec_clobbering_test(u32 esize, const Operand& v, cons
}
}
void asmjit::simd_builder::vec_broadcast_gpr(u32 esize, const Operand& v, const x86::Gp& r)
{
if (esize == 2)
{
if (utils::has_avx512())
this->emit(x86::Inst::kIdVpbroadcastw, v, r.r32());
else if (utils::has_avx())
{
this->emit(x86::Inst::kIdVmovd, v, r.r32());
if (utils::has_avx2())
this->emit(x86::Inst::kIdVpbroadcastw, v, v);
else
{
this->emit(x86::Inst::kIdVpunpcklwd, v, v, v);
this->emit(x86::Inst::kIdVpshufd, v, v, Imm(0));
}
}
else
{
this->emit(x86::Inst::kIdMovd, v, r.r32());
this->emit(x86::Inst::kIdPunpcklwd, v, v);
this->emit(x86::Inst::kIdPshufd, v, v, Imm(0));
}
}
else if (esize == 4)
{
if (utils::has_avx512())
this->emit(x86::Inst::kIdVpbroadcastd, v, r.r32());
else if (utils::has_avx())
{
this->emit(x86::Inst::kIdVmovd, v, r.r32());
if (utils::has_avx2())
this->emit(x86::Inst::kIdVpbroadcastd, v, v);
else
this->emit(x86::Inst::kIdVpshufd, v, v, Imm(0));
}
else
{
this->emit(x86::Inst::kIdMovd, v, r.r32());
this->emit(x86::Inst::kIdPshufd, v, v, Imm(0));
}
}
else
{
fmt::throw_exception("Unimplemented");
}
}
asmjit::x86::Mem asmjit::simd_builder::ptr_scale_for_vec(u32 esize, const x86::Gp& base, const x86::Gp& index)
{
switch (ensure(esize))
@@ -530,7 +605,7 @@ void asmjit::simd_builder::vec_load_unaligned(u32 esize, const Operand& v, const
this->emit(x86::Inst::kIdVpinsrw, x86::Xmm(v.id()), x86::Xmm(v.id()), src, Imm(0));
else if (vsize == 2)
this->emit(x86::Inst::kIdPinsrw, v, src, Imm(0));
else if (vmask && vmask < 8)
else if ((vmask && vmask < 8) || vsize >= 64)
this->emit(x86::Inst::kIdVmovdqu16, v, src);
else
return vec_load_unaligned(vsize, v, src);
@@ -542,7 +617,7 @@ void asmjit::simd_builder::vec_load_unaligned(u32 esize, const Operand& v, const
this->emit(x86::Inst::kIdVmovd, x86::Xmm(v.id()), src);
else if (vsize == 4)
this->emit(x86::Inst::kIdMovd, v, src);
else if (vmask && vmask < 8)
else if ((vmask && vmask < 8) || vsize >= 64)
this->emit(x86::Inst::kIdVmovdqu32, v, src);
else
return vec_load_unaligned(vsize, v, src);
@@ -554,7 +629,7 @@ void asmjit::simd_builder::vec_load_unaligned(u32 esize, const Operand& v, const
this->emit(x86::Inst::kIdVmovq, x86::Xmm(v.id()), src);
else if (vsize == 8)
this->emit(x86::Inst::kIdMovq, v, src);
else if (vmask && vmask < 8)
else if ((vmask && vmask < 8) || vsize >= 64)
this->emit(x86::Inst::kIdVmovdqu64, v, src);
else
return vec_load_unaligned(vsize, v, src);
@@ -562,7 +637,9 @@ void asmjit::simd_builder::vec_load_unaligned(u32 esize, const Operand& v, const
else if (esize >= 16)
{
ensure(vsize >= 16);
if (utils::has_avx())
if ((vmask && vmask < 8) || vsize >= 64)
this->emit(x86::Inst::kIdVmovdqu64, v, src); // Not really needed
else if (utils::has_avx())
this->emit(x86::Inst::kIdVmovdqu, v, src);
else
this->emit(x86::Inst::kIdMovups, v, src);
@@ -636,7 +713,7 @@ void asmjit::simd_builder::_vec_binary_op(x86::Inst::Id sse_op, x86::Inst::Id ve
{
if (utils::has_avx())
{
if (vex_op == x86::Inst::kIdNone || this->_extraReg.isReg())
if (evex_op != x86::Inst::kIdNone && (vex_op == x86::Inst::kIdNone || this->_extraReg.isReg() || vsize >= 64))
{
this->evex().emit(evex_op, dst, lhs, rhs);
}
@@ -694,40 +771,31 @@ void asmjit::simd_builder::vec_umax(u32 esize, const Operand& dst, const Operand
fmt::throw_exception("Unimplemented");
}
void asmjit::simd_builder::vec_umin_horizontal_i128(u32 esize, const x86::Gp& dst, const Operand& src, const Operand& tmp)
void asmjit::simd_builder::vec_cmp_eq(u32 esize, const Operand& dst, const Operand& lhs, const Operand& rhs)
{
using enum x86::Inst::Id;
if (!utils::has_sse41())
{
fmt::throw_exception("Unimplemented");
}
ensure(src != tmp);
if (esize == 2)
{
this->emit(utils::has_avx() ? kIdVphminposuw : kIdPhminposuw, x86::Xmm(tmp.id()), x86::Xmm(src.id()));
this->emit(utils::has_avx() ? kIdVpextrw : kIdPextrw, dst, x86::Xmm(tmp.id()), Imm(0));
}
else if (esize == 4)
{
if (utils::has_avx())
if (vsize == 64)
{
this->vpsrldq(x86::Xmm(tmp.id()), x86::Xmm(src.id()), 8);
this->vpminud(x86::Xmm(tmp.id()), x86::Xmm(tmp.id()), x86::Xmm(src.id()));
this->vpsrldq(x86::Xmm(src.id()), x86::Xmm(tmp.id()), 4);
this->vpminud(x86::Xmm(src.id()), x86::Xmm(src.id()), x86::Xmm(tmp.id()));
this->vmovd(dst.r32(), x86::Xmm(src.id()));
this->evex().emit(kIdVpcmpeqw, x86::k0, lhs, rhs);
this->evex().emit(kIdVpmovm2w, dst, x86::k0);
}
else
{
this->movdqa(x86::Xmm(tmp.id()), x86::Xmm(src.id()));
this->psrldq(x86::Xmm(tmp.id()), 8);
this->pminud(x86::Xmm(tmp.id()), x86::Xmm(src.id()));
this->movdqa(x86::Xmm(src.id()), x86::Xmm(tmp.id()));
this->psrldq(x86::Xmm(src.id()), 4);
this->pminud(x86::Xmm(src.id()), x86::Xmm(tmp.id()));
this->movd(dst.r32(), x86::Xmm(src.id()));
_vec_binary_op(kIdPcmpeqw, kIdVpcmpeqw, kIdNone, dst, lhs, rhs);
}
}
else if (esize == 4)
{
if (vsize == 64)
{
this->evex().emit(kIdVpcmpeqd, x86::k0, lhs, rhs);
this->evex().emit(kIdVpmovm2d, dst, x86::k0);
}
else
{
_vec_binary_op(kIdPcmpeqw, kIdVpcmpeqw, kIdNone, dst, lhs, rhs);
}
}
else
@@ -736,50 +804,42 @@ void asmjit::simd_builder::vec_umin_horizontal_i128(u32 esize, const x86::Gp& ds
}
}
void asmjit::simd_builder::vec_umax_horizontal_i128(u32 esize, const x86::Gp& dst, const Operand& src, const Operand& tmp)
void asmjit::simd_builder::vec_extract_high(u32, const Operand& dst, const Operand& src)
{
using enum x86::Inst::Id;
if (!utils::has_sse41())
{
fmt::throw_exception("Unimplemented");
}
ensure(src != tmp);
if (esize == 2)
{
vec_set_all_ones(x86::Xmm(tmp.id()));
vec_xor(esize, x86::Xmm(tmp.id()), x86::Xmm(tmp.id()), x86::Xmm(src.id()));
this->emit(utils::has_avx() ? kIdVphminposuw : kIdPhminposuw, x86::Xmm(tmp.id()), x86::Xmm(tmp.id()));
this->emit(utils::has_avx() ? kIdVpextrw : kIdPextrw, dst, x86::Xmm(tmp.id()), Imm(0));
this->not_(dst.r16());
}
else if (esize == 4)
{
if (utils::has_avx())
{
this->vpsrldq(x86::Xmm(tmp.id()), x86::Xmm(src.id()), 8);
this->vpmaxud(x86::Xmm(tmp.id()), x86::Xmm(tmp.id()), x86::Xmm(src.id()));
this->vpsrldq(x86::Xmm(src.id()), x86::Xmm(tmp.id()), 4);
this->vpmaxud(x86::Xmm(src.id()), x86::Xmm(src.id()), x86::Xmm(tmp.id()));
this->vmovd(dst.r32(), x86::Xmm(src.id()));
}
else
{
this->movdqa(x86::Xmm(tmp.id()), x86::Xmm(src.id()));
this->psrldq(x86::Xmm(tmp.id()), 8);
this->pmaxud(x86::Xmm(tmp.id()), x86::Xmm(src.id()));
this->movdqa(x86::Xmm(src.id()), x86::Xmm(tmp.id()));
this->psrldq(x86::Xmm(src.id()), 4);
this->pmaxud(x86::Xmm(src.id()), x86::Xmm(tmp.id()));
this->movd(dst.r32(), x86::Xmm(src.id()));
}
}
if (vsize == 32)
this->vextracti32x8(x86::Ymm(dst.id()), x86::Zmm(src.id()), 1);
else if (vsize == 16)
this->vextracti128(x86::Xmm(dst.id()), x86::Ymm(src.id()), 1);
else
{
fmt::throw_exception("Unimplemented");
if (utils::has_avx())
this->vpsrldq(x86::Xmm(dst.id()), x86::Xmm(src.id()), vsize);
else
{
this->movdqa(x86::Xmm(dst.id()), x86::Xmm(src.id()));
this->psrldq(x86::Xmm(dst.id()), vsize);
}
}
}
void asmjit::simd_builder::vec_extract_gpr(u32 esize, const x86::Gp& dst, const Operand& src)
{
if (esize == 8 && utils::has_avx())
this->vmovq(dst.r64(), x86::Xmm(src.id()));
else if (esize == 8)
this->movq(dst.r64(), x86::Xmm(src.id()));
else if (esize == 4 && utils::has_avx())
this->vmovd(dst.r32(), x86::Xmm(src.id()));
else if (esize == 4)
this->movd(dst.r32(), x86::Xmm(src.id()));
else if (esize == 2 && utils::has_avx())
this->vpextrw(dst.r32(), x86::Xmm(src.id()), 0);
else if (esize == 2)
this->pextrw(dst.r32(), x86::Xmm(src.id()), 0);
else
fmt::throw_exception("Unimplemented");
}
#endif /* X86 */
#ifdef LLVM_AVAILABLE
+74 -28
View File
@@ -226,12 +226,13 @@ namespace asmjit
void operator()() noexcept;
void _init(bool full);
void _init(uint new_vsize = 0);
void vec_cleanup_ret();
void vec_set_all_zeros(const Operand& v);
void vec_set_all_ones(const Operand& v);
void vec_set_const(const Operand& v, const v128& value);
void vec_clobbering_test(u32 esize, const Operand& v, const Operand& rhs);
void vec_broadcast_gpr(u32 esize, const Operand& v, const x86::Gp& r);
// return x86::ptr(base, ctr, X, 0) where X is set for esize accordingly
x86::Mem ptr_scale_for_vec(u32 esize, const x86::Gp& base, const x86::Gp& index);
@@ -260,11 +261,18 @@ namespace asmjit
_vec_binary_op(kIdPor, kIdVpor, kIdVpord, dst, lhs, rhs);
}
void vec_andn(u32, const Operand& dst, const Operand& lhs, const Operand& rhs)
{
using enum x86::Inst::Id;
_vec_binary_op(kIdPandn, kIdVpandn, kIdVpandnd, dst, lhs, rhs);
}
void vec_umin(u32 esize, const Operand& dst, const Operand& lhs, const Operand& rhs);
void vec_umax(u32 esize, const Operand& dst, const Operand& lhs, const Operand& rhs);
void vec_cmp_eq(u32 esize, const Operand& dst, const Operand& lhs, const Operand& rhs);
void vec_umin_horizontal_i128(u32 esize, const x86::Gp& dst, const Operand& src, const Operand& tmp);
void vec_umax_horizontal_i128(u32 esize, const x86::Gp& dst, const Operand& src, const Operand& tmp);
void vec_extract_high(u32 esize, const Operand& dst, const Operand& src);
void vec_extract_gpr(u32 esize, const x86::Gp& dst, const Operand& src);
simd_builder& keep_if_not_masked()
{
@@ -287,7 +295,7 @@ namespace asmjit
return *this;
}
void build_loop(u32 esize, auto reg_ctr, auto reg_cnt, auto&& build, auto&& reduce)
void build_loop(u32 esize, const x86::Gp& reg_ctr, const x86::Gp& reg_cnt, auto&& build, auto&& reduce)
{
ensure((esize & (esize - 1)) == 0);
ensure(esize <= vsize);
@@ -299,47 +307,85 @@ namespace asmjit
const u32 step = vsize / esize;
this->xor_(reg_ctr.r32(), reg_ctr.r32()); // Reset counter reg
this->sub(reg_cnt, step);
this->cmp(reg_cnt, step);
this->jb(next); // If count < step, skip main loop body
this->align(AlignMode::kCode, 16);
this->bind(body);
this->sub(reg_cnt, step);
build();
this->add(reg_ctr, step);
this->sub(reg_cnt, step);
this->ja(body);
this->cmp(reg_cnt, step);
this->jae(body);
this->bind(next);
if (!vmask)
reduce();
this->add(reg_cnt, step);
this->jz(exit);
if (vmask)
{
// Build single last iteration (masked)
this->bzhi(reg_cnt, x86::Mem(consts[~u128()], 0), reg_cnt);
this->kmovq(x86::k7, reg_cnt);
this->test(reg_cnt, reg_cnt);
this->jz(exit);
if (esize == 1 && vsize == 64)
{
this->bzhi(reg_cnt.r64(), x86::Mem(consts[~u128()], 0), reg_cnt.r64());
this->kmovq(x86::k7, reg_cnt.r64());
}
else
{
this->bzhi(reg_cnt.r32(), x86::Mem(consts[~u128()], 0), reg_cnt.r32());
this->kmovd(x86::k7, reg_cnt.r32());
}
vmask = 7;
build();
vmask = -1;
reduce();
// Rollout reduction step
this->bind(exit);
while (true)
{
vsize /= 2;
if (vsize < esize)
break;
this->_init(vsize);
reduce();
}
}
else
{
// Build tail loop (reduced vector width)
Label body = this->newLabel();
this->align(AlignMode::kCode, 16);
this->bind(body);
const uint vsz = vsize / step;
this->_init(false);
vsize = vsz;
build();
this->_init(true);
this->inc(reg_ctr);
this->sub(reg_cnt, 1);
this->ja(body);
// Build unrolled loop tail (reduced vector width)
while (true)
{
vsize /= 2;
if (vsize < esize)
break;
// Shall not clobber flags
this->_init(vsize);
reduce();
if (vsize == esize)
{
// Last "iteration"
this->test(reg_cnt, reg_cnt);
this->jz(exit);
build();
}
else
{
const u32 step = vsize / esize;
Label next = this->newLabel();
this->cmp(reg_cnt, step);
this->jb(next);
build();
this->add(reg_ctr, step);
this->sub(reg_cnt, step);
this->bind(next);
}
}
this->bind(exit);
}
this->bind(exit);
this->_init(0);
}
};
+3 -2
View File
@@ -449,7 +449,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 +457,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;
}
+4 -1
View File
@@ -16,7 +16,7 @@ std::string utf16_to_utf8(std::u16string_view src);
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);
}
@@ -27,6 +27,9 @@ bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max);
// Convert string to unsigned integer
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);
// Get the file extension of a file path ("png", "jpg", etc.)
std::string get_file_extension(const std::string& file_path);
+15 -13
View File
@@ -16,7 +16,9 @@
#include <process.h>
#include <sysinfoapi.h>
#else
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifdef __APPLE__
#define _XOPEN_SOURCE
#define __USE_GNU
@@ -94,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;
}
@@ -1925,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.");
});
@@ -2063,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{};
@@ -2648,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)
{
+34 -16
View File
@@ -703,8 +703,6 @@ static usz apply_modification(std::basic_string<u32>& applied, const patch_engin
}
case patch_type::code_alloc:
{
relocate_instructions_at = 0;
const u32 out_branch = vm::try_get_addr(dst + (offset & -4)).first;
// Allow only if points to a PPU executable instruction
@@ -715,10 +713,17 @@ static usz apply_modification(std::basic_string<u32>& applied, const patch_engin
const u32 alloc_size = utils::align(static_cast<u32>(p.value.long_value + 1) * 4, 0x10000);
// Check if should maybe reuse previous code cave allocation (0 size)
if (alloc_size - 4 != 0)
{
// Nope
relocate_instructions_at = 0;
}
// Always executable
u64 flags = vm::alloc_executable | vm::alloc_unwritable;
switch (p.offset % patch_engine::mem_protection::mask)
switch (p.offset & patch_engine::mem_protection::mask)
{
case patch_engine::mem_protection::rw:
case patch_engine::mem_protection::wx:
@@ -738,7 +743,7 @@ static usz apply_modification(std::basic_string<u32>& applied, const patch_engin
// Range allowed for absolute branches to operate at
// It takes into account that we need to put a branch for return at the end of memory space
const u32 addr = p.alloc_addr = alloc_map->alloc(alloc_size, nullptr, 0x10000, flags);
const u32 addr = p.alloc_addr = (relocate_instructions_at ? relocate_instructions_at : alloc_map->alloc(alloc_size, nullptr, 0x10000, flags));
if (!addr)
{
@@ -751,18 +756,31 @@ static usz apply_modification(std::basic_string<u32>& applied, const patch_engin
// NOP filled
std::fill_n(vm::get_super_ptr<u32>(addr), p.value.long_value, 0x60000000);
// Register code
ppu_register_range(addr, alloc_size);
// Check if already registered by previous code allocation
if (relocate_instructions_at != addr)
{
// Register code
ppu_register_range(addr, alloc_size);
}
// Write branch to code
ppu_form_branch_to_code(out_branch, addr);
resval = out_branch & -4;
// Write address of the allocated memory to the code entry
*vm::get_super_ptr<u32>(resval) = addr;
// Write branch to return to code
ppu_form_branch_to_code(addr + static_cast<u32>(p.value.long_value) * 4, resval + 4);
if (!ppu_form_branch_to_code(addr + static_cast<u32>(p.value.long_value) * 4, resval + 4))
{
patch_log.error("Failed to write return jump at 0x%x", addr + static_cast<u32>(p.value.long_value) * 4);
ensure(alloc_map->dealloc(addr));
continue;
}
// Write branch to code
if (!ppu_form_branch_to_code(out_branch, addr))
{
patch_log.error("Failed to jump to code cave at 0x%x", out_branch);
ensure(alloc_map->dealloc(addr));
continue;
}
relocate_instructions_at = addr;
break;
}
@@ -939,7 +957,7 @@ std::basic_string<u32> patch_engine::apply(const std::string& name, u8* dst, u32
}
std::basic_string<u32> applied_total;
const auto& container = m_map.at(name);
const auto& container = ::at32(m_map, name);
const auto& serial = Emu.GetTitleID();
const auto& app_version = Emu.GetAppVersion();
@@ -975,7 +993,7 @@ std::basic_string<u32> patch_engine::apply(const std::string& name, u8* dst, u32
continue;
}
const auto& app_versions = serials.at(found_serial);
const auto& app_versions = ::at32(serials, found_serial);
std::string found_app_version;
if (app_versions.find(app_version) != app_versions.end())
@@ -988,7 +1006,7 @@ std::basic_string<u32> patch_engine::apply(const std::string& name, u8* dst, u32
is_all_versions = true;
}
if (!found_app_version.empty() && app_versions.at(found_app_version))
if (!found_app_version.empty() && ::at32(app_versions, found_app_version))
{
// This patch is enabled
if (is_all_serials)
@@ -1073,7 +1091,7 @@ void patch_engine::unload(const std::string& name)
return;
}
const auto& container = m_map.at(name);
const auto& container = ::at32(m_map, name);
for (const auto& [description, patch] : container.patch_info_map)
{
+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
+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);
}
}
}
+4 -2
View File
@@ -30,7 +30,8 @@ namespace utils
if (lo())
{
version += "." + std::to_string(lo());
version += '.';
version += std::to_string(lo());
}
if (type() != version_type::release)
@@ -40,7 +41,8 @@ namespace utils
version += "-" + postfix();
}
version += " " + utils::to_string(type());
version += ' ';
version += utils::to_string(type());
if (type_index() > 1)
{
+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 -1
Submodule llvm updated: 5521155be5...9b52b6c39a
+30 -22
View File
@@ -1,6 +1,6 @@
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
@@ -40,22 +40,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}"
@@ -83,7 +84,9 @@ 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
@@ -176,10 +179,14 @@ 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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -206,7 +213,8 @@ 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}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
+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
)
-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;
+203 -74
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)
@@ -189,8 +194,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,7 +513,7 @@ 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)
{
@@ -523,7 +527,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 +542,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 +557,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())
{
@@ -610,7 +614,8 @@ 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())
@@ -624,7 +629,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,15 +691,19 @@ 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::fill_data(std::map<std::string, install_entry*>& all_install_entries)
{
if (!m_is_valid)
{
return false;
}
m_install_entries.clear();
m_install_path.clear();
m_bootable_file_path.clear();
m_entry_indexer = 0;
m_written_bytes = 0;
// Get full path and create the directory
std::string dir = rpcs3::utils::get_hdd0_dir();
@@ -730,7 +739,7 @@ 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))
{
@@ -738,6 +747,8 @@ bool package_reader::extract_data(atomic_t<double>& sync)
return false;
}
m_install_path = dir;
if (!decrypt_data())
{
return false;
@@ -747,23 +758,107 @@ 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 = 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);
switch (const u8 entry_type = entry.type & 0xff)
{
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:
{
const std::string true_path = std::filesystem::weakly_canonical(std::filesystem::u8path(path)).string();
auto map_ptr = &*all_install_entries.try_emplace(true_path).first;
m_install_entries.push_back({ map_ptr, name, entry.file_offset, entry.file_size, entry.type, 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", dir);
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);
usz package_reader::extract_worker(thread_key thread_data_key, std::map<std::string, install_entry*>& all_install_entries)
{
usz num_failures = 0;
while (true)
{
const usz maybe_index = m_entry_indexer++;
if (maybe_index >= m_install_entries.size())
{
break;
}
const install_entry& entry = ::at32(m_install_entries, maybe_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 name{reinterpret_cast<char*>(m_buf.get()), entry.name_size};
const std::string path = dir + vfs::escape(name);
const std::string& path = entry.weak_reference->first;
const std::string& name = entry.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);
@@ -798,43 +893,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);
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);
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)
@@ -857,6 +942,12 @@ 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
@@ -872,43 +963,67 @@ bool package_reader::extract_data(atomic_t<double>& sync)
break;
}
case PKG_FILE_ENTRY_FOLDER:
case 0x12:
{
if (fs::create_dir(path))
{
pkg_log.notice("Created directory %s", path);
}
else if (fs::is_dir(path))
{
pkg_log.warning("Reused existing directory %s", path);
}
else
{
num_failures++;
pkg_log.error("Failed to create directory %s", path);
}
break;
}
default:
{
num_failures++;
pkg_log.error("Unknown PKG entry type (0x%x) %s", entry.type, name);
break;
}
}
}
if (num_failures == 0)
return num_failures;
}
bool package_reader::extract_data(std::deque<package_reader>& readers, std::deque<std::string>& bootable_paths)
{
std::map<std::string, install_entry*> all_install_entries;
for (auto& reader : readers)
{
pkg_log.success("Package successfully installed to %s", dir);
if (!reader.fill_data(all_install_entries))
{
return false;
}
}
else
usz num_failures = 0;
for (auto& reader : readers)
{
fs::remove_all(dir, true);
pkg_log.error("Package installation failed: %s", dir);
reader.m_bufs.resize(std::min<usz>(utils::get_thread_count(), reader.m_install_entries.size()));
atomic_t<usz> thread_indexer = 0;
named_thread_group workers("PKG Installer "sv, std::max<usz>(reader.m_bufs.size(), 1) - 1, [&]()
{
num_failures += reader.extract_worker(thread_key{thread_indexer++}, all_install_entries);
});
num_failures += reader.extract_worker(thread_key{thread_indexer++}, all_install_entries);
workers.join();
reader.m_bufs.clear();
reader.m_bufs.shrink_to_fit();
if (num_failures)
{
if (reader.m_was_null)
{
fs::remove_all(reader.m_install_path, true);
}
pkg_log.success("Package failed to install ('%s')", reader.m_install_path);
break;
}
else if (reader.get_progress(1) != 1)
{
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));
}
return num_failures == 0;
@@ -922,28 +1037,42 @@ void package_reader::archive_seek(const s64 new_offset, const fs::seek_mode damo
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 +1098,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 +1118,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 +1127,5 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
}
// Return the amount of data written in buf
return read;
return data_span;
};
+65 -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,90 @@ 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();
bool is_valid() const { return m_is_valid; }
package_error check_target_app_version() const;
bool extract_data(atomic_t<double>& sync);
static bool extract_data(std::deque<package_reader>& readers, std::deque<std::string>& bootable_paths);
psf::registry get_psf() const { return m_psf; }
int get_progress(int maximum = 100) const
{
const usz wr = m_written_bytes;
return wr >= m_header.data_size ? maximum : ::narrow<int>(wr * maximum / m_header.data_size);
}
void abort_extract()
{
m_entry_indexer.fetch_op([this](usz& v)
{
if (v < m_install_entries.size())
{
v = m_install_entries.size();
return true;
}
return false;
});
}
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 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});
usz extract_worker(thread_key thread_data_key, std::map<std::string, install_entry*>& all_install_entries);
const usz BUF_SIZE = 8192 * 1024; // 8 MB
std::deque<install_entry> m_install_entries;
std::string m_install_path;
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;
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;
};
+2 -2
View File
@@ -111,7 +111,7 @@ std::pair<AudioChannelCnt, AudioChannelCnt> AudioBackend::get_channel_count_and_
audio_out_configuration& audio_out_cfg = g_fxo->get<audio_out_configuration>();
std::lock_guard lock(audio_out_cfg.mtx);
ensure(device_index < audio_out_cfg.out.size());
const audio_out_configuration::audio_out& out = audio_out_cfg.out.at(device_index);
const audio_out_configuration::audio_out& out = ::at32(audio_out_cfg.out, device_index);
return out.get_channel_count_and_downmixer();
}
@@ -120,7 +120,7 @@ AudioChannelCnt AudioBackend::get_max_channel_count(u32 device_index)
audio_out_configuration& audio_out_cfg = g_fxo->get<audio_out_configuration>();
std::lock_guard lock(audio_out_cfg.mtx);
ensure(device_index < audio_out_cfg.out.size());
const audio_out_configuration::audio_out& out = audio_out_cfg.out.at(device_index);
const audio_out_configuration::audio_out& out = ::at32(audio_out_cfg.out, device_index);
AudioChannelCnt count = AudioChannelCnt::STEREO;
+2 -2
View File
@@ -40,7 +40,7 @@ enum class AudioChannelCnt : u32
enum class AudioStateEvent : u32
{
UNSPECIFIED_ERROR,
DEFAULT_DEVICE_CHANGED,
DEFAULT_DEVICE_MAYBE_CHANGED,
};
class AudioBackend
@@ -226,7 +226,7 @@ protected:
AudioFreq m_sampling_rate = AudioFreq::FREQ_48K;
AudioChannelCnt m_channels = AudioChannelCnt::STEREO;
shared_mutex m_cb_mutex{};
std::timed_mutex m_cb_mutex{};
std::function<u32(u32, void *)> m_write_callback{};
shared_mutex m_state_cb_mutex{};
+188 -81
View File
@@ -22,14 +22,14 @@ CubebBackend::CubebBackend()
}
#endif
if (int err = cubeb_init(&m_ctx, "RPCS3", nullptr))
cubeb *ctx{};
if (int err = cubeb_init(&ctx, "RPCS3", nullptr))
{
Cubeb.error("cubeb_init() failed: %i", err);
m_ctx = nullptr;
return;
}
if (int err = cubeb_register_device_collection_changed(m_ctx, CUBEB_DEVICE_TYPE_OUTPUT, device_collection_changed_cb, this))
if (int err = cubeb_register_device_collection_changed(ctx, CUBEB_DEVICE_TYPE_OUTPUT, device_collection_changed_cb, this))
{
Cubeb.error("cubeb_register_device_collection_changed() failed: %i", err);
}
@@ -38,7 +38,10 @@ CubebBackend::CubebBackend()
m_dev_collection_cb_enabled = true;
}
Cubeb.notice("Using backend %s", cubeb_get_backend_id(m_ctx));
Cubeb.notice("Using backend %s", cubeb_get_backend_id(ctx));
std::lock_guard cb_lock{m_state_cb_mutex};
m_ctx = ctx;
}
CubebBackend::~CubebBackend()
@@ -78,8 +81,19 @@ bool CubebBackend::Operational()
bool CubebBackend::DefaultDeviceChanged()
{
std::lock_guard lock{m_dev_sw_mutex};
return !m_reset_req.observe() && m_default_dev_changed;
if (m_default_device.empty() || m_reset_req.observe())
{
return false;
}
device_handle device = GetDevice();
if (!device.handle)
{
Cubeb.error("Selected device not found. Trying alternative approach...");
device = GetDefaultDeviceAlt(m_sampling_rate, m_sample_size, m_channels);
}
return !device.handle || device.id != m_default_device;
}
bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize sample_size, AudioChannelCnt ch_cnt)
@@ -90,20 +104,23 @@ bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize
return false;
}
std::lock_guard lock(m_cb_mutex);
std::lock_guard dev_sw_lock{m_dev_sw_mutex};
CloseUnlocked();
Close();
std::lock_guard lock{m_cb_mutex};
const bool use_default_device = dev_id.empty() || dev_id == audio_device_enumerator::DEFAULT_DEV_ID;
auto [dev_handle, dev_ident, dev_ch_cnt] = GetDevice(use_default_device ? "" : dev_id);
if (!dev_handle)
if (use_default_device) Cubeb.notice("Trying to open default device");
else Cubeb.notice("Trying to open device with dev_id='%s'", dev_id);
device_handle device = GetDevice(use_default_device ? "" : dev_id);
if (!device.handle)
{
if (use_default_device)
{
std::tie(dev_handle, dev_ident, dev_ch_cnt) = GetDefaultDeviceAlt(freq, sample_size, ch_cnt);
device = GetDefaultDeviceAlt(freq, sample_size, ch_cnt);
if (!dev_handle)
if (!device.handle)
{
Cubeb.error("Cannot detect default device. Channel count detection unavailable.");
}
@@ -115,15 +132,21 @@ bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize
}
}
if (dev_ch_cnt == 0)
if (device.ch_cnt == 0)
{
Cubeb.error("Device reported invalid channel count, using stereo instead");
dev_ch_cnt = 2;
device.ch_cnt = 2;
}
if (use_default_device)
{
std::lock_guard lock{m_state_cb_mutex};
m_default_device = device.id;
}
m_sampling_rate = freq;
m_sample_size = sample_size;
m_channels = static_cast<AudioChannelCnt>(std::min(static_cast<u32>(convert_channel_count(dev_ch_cnt)), static_cast<u32>(ch_cnt)));
m_channels = static_cast<AudioChannelCnt>(std::min(static_cast<u32>(convert_channel_count(device.ch_cnt)), static_cast<u32>(ch_cnt)));
full_sample_size = get_channels() * get_sample_size();
cubeb_stream_params stream_param{};
@@ -141,7 +164,7 @@ bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize
fmt::throw_exception("Invalid audio channel count");
}
}();
stream_param.prefs = m_dev_collection_cb_enabled && dev_handle ? CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING : CUBEB_STREAM_PREF_NONE;
stream_param.prefs = m_dev_collection_cb_enabled && device.handle ? CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING : CUBEB_STREAM_PREF_NONE;
u32 min_latency{};
if (int err = cubeb_get_min_latency(m_ctx, &stream_param, &min_latency))
@@ -152,7 +175,7 @@ bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize
const u32 stream_latency = std::max(static_cast<u32>(AUDIO_MIN_LATENCY * get_sampling_rate()), min_latency);
if (int err = cubeb_stream_init(m_ctx, &m_stream, "Main stream", nullptr, nullptr, dev_handle, &stream_param, stream_latency, data_cb, state_cb, this))
if (int err = cubeb_stream_init(m_ctx, &m_stream, "Main stream", nullptr, nullptr, device.handle, &stream_param, stream_latency, data_cb, state_cb, this))
{
Cubeb.error("cubeb_stream_init() failed: %i", err);
m_stream = nullptr;
@@ -162,7 +185,7 @@ bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize
if (int err = cubeb_stream_start(m_stream))
{
Cubeb.error("cubeb_stream_start() failed: %i", err);
CloseUnlocked();
Close();
return false;
}
@@ -171,15 +194,10 @@ bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize
Cubeb.error("cubeb_stream_set_volume() failed: %i", err);
}
if (use_default_device)
{
m_current_device = dev_ident;
}
return true;
}
void CubebBackend::CloseUnlocked()
void CubebBackend::Close()
{
if (m_stream != nullptr)
{
@@ -189,21 +207,17 @@ void CubebBackend::CloseUnlocked()
}
cubeb_stream_destroy(m_stream);
m_stream = nullptr;
}
m_playing = false;
m_last_sample.fill(0);
{
std::lock_guard lock{m_cb_mutex};
m_stream = nullptr;
m_playing = false;
m_last_sample.fill(0);
}
m_default_dev_changed = false;
m_current_device.clear();
}
void CubebBackend::Close()
{
std::lock_guard lock(m_cb_mutex);
std::lock_guard dev_sw_lock{m_dev_sw_mutex};
CloseUnlocked();
std::lock_guard lock{m_state_cb_mutex};
m_default_device.clear();
}
void CubebBackend::Play()
@@ -253,10 +267,13 @@ f64 CubebBackend::GetCallbackFrameLen()
return std::max<f64>(AUDIO_MIN_LATENCY, static_cast<f64>(stream_latency) / get_sampling_rate());
}
std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDevice(std::string_view dev_id)
CubebBackend::device_handle CubebBackend::GetDevice(std::string_view dev_id)
{
const bool default_dev = dev_id.empty();
if (default_dev) Cubeb.notice("Searching for default device");
else Cubeb.notice("Searching for device with dev_id='%s'", dev_id);
cubeb_device_collection dev_collection{};
if (int err = cubeb_enumerate_devices(m_ctx, CUBEB_DEVICE_TYPE_OUTPUT, &dev_collection))
{
@@ -274,14 +291,24 @@ std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDevice(std::string_vi
return {};
}
std::tuple<cubeb_devid, std::string, u32> result{};
Cubeb.notice("Found %d possible output devices", dev_collection.count);
device_handle result{};
for (u64 dev_idx = 0; dev_idx < dev_collection.count; dev_idx++)
{
const cubeb_device_info& dev_info = dev_collection.device[dev_idx];
const std::string dev_ident{dev_info.device_id};
if (dev_ident.empty())
device_handle device{};
device.handle = dev_info.devid;
device.ch_cnt = dev_info.max_channels;
if (dev_info.device_id)
{
device.id = dev_info.device_id;
}
if (device.id.empty())
{
Cubeb.error("device_id is missing from device");
continue;
@@ -291,17 +318,26 @@ std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDevice(std::string_vi
{
if (dev_info.preferred & CUBEB_DEVICE_PREF_MULTIMEDIA)
{
result = {dev_info.devid, dev_ident, dev_info.max_channels};
result = std::move(device);
break;
}
}
else if (dev_ident == dev_id)
else if (device.id == dev_id)
{
result = {dev_info.devid, dev_ident, dev_info.max_channels};
result = std::move(device);
break;
}
}
if (result.handle)
{
Cubeb.notice("Found device '%s' with %d channels", result.id, result.ch_cnt);
}
else
{
Cubeb.notice("No device found for dev_id='%s'", dev_id);
}
if (int err = cubeb_device_collection_destroy(m_ctx, &dev_collection))
{
Cubeb.error("cubeb_device_collection_destroy() failed: %i", err);
@@ -310,8 +346,10 @@ std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDevice(std::string_vi
return result;
};
std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDefaultDeviceAlt(AudioFreq freq, AudioSampleSize sample_size, AudioChannelCnt ch_cnt)
CubebBackend::device_handle CubebBackend::GetDefaultDeviceAlt(AudioFreq freq, AudioSampleSize sample_size, AudioChannelCnt ch_cnt)
{
Cubeb.notice("Starting alternative search for default device with freq=%d, sample_size=%d and ch_cnt=%d", static_cast<u32>(freq), static_cast<u32>(sample_size), static_cast<u32>(ch_cnt));
cubeb_stream_params param =
{
.format = sample_size == AudioSampleSize::S16 ? CUBEB_SAMPLE_S16NE : CUBEB_SAMPLE_FLOAT32NE,
@@ -340,14 +378,19 @@ std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDefaultDeviceAlt(Audi
cubeb_device* crnt_dev{};
if (int err = cubeb_stream_get_current_device(tmp_stream, &crnt_dev))
if (int err = cubeb_stream_get_current_device(tmp_stream, &crnt_dev); err != CUBEB_OK || !crnt_dev)
{
Cubeb.error("cubeb_stream_get_current_device() failed: %i", err);
Cubeb.error("cubeb_stream_get_current_device() failed: err=%i, crnt_dev=%d", err, !!crnt_dev);
cubeb_stream_destroy(tmp_stream);
return {};
}
const std::string out_dev_name{crnt_dev->output_name};
std::string out_dev_name;
if (crnt_dev->output_name)
{
out_dev_name = crnt_dev->output_name;
}
if (int err = cubeb_stream_device_destroy(tmp_stream, crnt_dev))
{
@@ -358,19 +401,46 @@ std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDefaultDeviceAlt(Audi
if (out_dev_name.empty())
{
Cubeb.notice("No default device available");
return {};
}
return GetDevice(out_dev_name);
}
long CubebBackend::data_cb(cubeb_stream* /* stream */, void* user_ptr, void const* /* input_buffer */, void* output_buffer, long nframes)
long CubebBackend::data_cb(cubeb_stream* stream, void* user_ptr, void const* /* input_buffer */, void* output_buffer, long nframes)
{
if (nframes <= 0)
{
Cubeb.error("data_cb called with nframes=%d", nframes);
return 0;
}
if (!output_buffer)
{
Cubeb.error("data_cb called with invalid output_buffer");
return CUBEB_ERROR;
}
if (!stream)
{
Cubeb.error("data_cb called with invalid stream");
return CUBEB_ERROR;
}
CubebBackend* const cubeb = static_cast<CubebBackend*>(user_ptr);
ensure(cubeb);
std::unique_lock lock(cubeb->m_cb_mutex, std::defer_lock);
if (nframes && !cubeb->m_reset_req.observe() && lock.try_lock() && cubeb->m_write_callback && cubeb->m_playing)
if (!cubeb->m_reset_req.observe() && lock.try_lock_for(std::chrono::microseconds{50}) && cubeb->m_write_callback && cubeb->m_playing)
{
if (stream != cubeb->m_stream)
{
// Cubeb.error("data_cb called with unknown stream");
return CUBEB_ERROR;
}
const u32 sample_size = cubeb->full_sample_size.observe();
const u32 bytes_req = nframes * sample_size;
u32 written = std::min(cubeb->m_write_callback(bytes_req, output_buffer), bytes_req);
@@ -390,65 +460,102 @@ long CubebBackend::data_cb(cubeb_stream* /* stream */, void* user_ptr, void cons
{
// Stream parameters are modified only after stream_destroy. stream_destroy will return
// only after this callback returns, so it's safe to access full_sample_size here.
memset(output_buffer, 0, nframes * cubeb->full_sample_size.observe());
memset(output_buffer, 0, nframes * cubeb->full_sample_size);
}
return nframes;
}
void CubebBackend::state_cb(cubeb_stream* /* stream */, void* user_ptr, cubeb_state state)
void CubebBackend::state_cb(cubeb_stream* stream, void* user_ptr, cubeb_state state)
{
CubebBackend* const cubeb = static_cast<CubebBackend*>(user_ptr);
if (!stream)
{
Cubeb.error("state_cb called with invalid stream");
return;
}
if (state == CUBEB_STATE_ERROR)
CubebBackend* const cubeb = static_cast<CubebBackend*>(user_ptr);
ensure(cubeb);
std::lock_guard lock(cubeb->m_state_cb_mutex);
if (stream != cubeb->m_stream)
{
Cubeb.error("state_cb called with unknown stream");
return;
}
switch (state)
{
case CUBEB_STATE_ERROR:
{
Cubeb.error("Stream entered error state");
std::lock_guard lock(cubeb->m_state_cb_mutex);
if (!cubeb->m_reset_req.test_and_set() && cubeb->m_state_callback)
{
cubeb->m_state_callback(AudioStateEvent::UNSPECIFIED_ERROR);
}
break;
}
case CUBEB_STATE_STARTED:
{
Cubeb.notice("Stream started");
break;
}
case CUBEB_STATE_STOPPED:
{
Cubeb.notice("Stream stopped");
break;
}
case CUBEB_STATE_DRAINED:
{
Cubeb.notice("Stream drained");
break;
}
default:
{
Cubeb.notice("Stream entered unknown state %d", static_cast<u32>(state));
break;
}
}
}
void CubebBackend::device_collection_changed_cb(cubeb* /* context */, void* user_ptr)
void CubebBackend::device_collection_changed_cb(cubeb* context, void* user_ptr)
{
CubebBackend* const cubeb = static_cast<CubebBackend*>(user_ptr);
Cubeb.notice("Device collection changed");
std::lock_guard lock{cubeb->m_dev_sw_mutex};
// Non default device is used (or default device cannot be detected)
if (cubeb->m_current_device.empty())
if (!context)
{
Cubeb.error("device_collection_changed_cb called with invalid stream");
return;
}
CubebBackend* const cubeb = static_cast<CubebBackend*>(user_ptr);
ensure(cubeb);
if (cubeb->m_reset_req.observe())
{
return;
}
auto [handle, dev_id, ch_cnt] = cubeb->GetDevice();
if (!handle)
{
std::tie(handle, dev_id, ch_cnt) = cubeb->GetDefaultDeviceAlt(cubeb->m_sampling_rate, cubeb->m_sample_size, cubeb->m_channels);
}
std::lock_guard cb_lock{cubeb->m_state_cb_mutex};
if (!handle)
if (context != cubeb->m_ctx)
{
// No devices available
if (!cubeb->m_reset_req.test_and_set() && cubeb->m_state_callback)
{
cubeb->m_state_callback(AudioStateEvent::UNSPECIFIED_ERROR);
}
Cubeb.error("device_collection_changed_cb called with unkown context");
return;
}
else if (!cubeb->m_reset_req.observe() && dev_id != cubeb->m_current_device)
{
cubeb->m_default_dev_changed = true;
if (cubeb->m_state_callback)
{
cubeb->m_state_callback(AudioStateEvent::DEFAULT_DEVICE_CHANGED);
}
// Non default device is used (or default device cannot be detected)
if (cubeb->m_default_device.empty())
{
Cubeb.notice("Skipping default device notification");
return;
}
if (cubeb->m_state_callback)
{
cubeb->m_state_callback(AudioStateEvent::DEFAULT_DEVICE_MAYBE_CHANGED);
}
}
+10 -6
View File
@@ -44,9 +44,8 @@ private:
atomic_t<bool> m_reset_req = false;
shared_mutex m_dev_sw_mutex{};
std::string m_current_device{};
bool m_default_dev_changed = false;
// Protected by callback mutex
std::string m_default_device{};
bool m_dev_collection_cb_enabled = false;
@@ -55,8 +54,13 @@ private:
static void state_cb(cubeb_stream* stream, void* user_ptr, cubeb_state state);
static void device_collection_changed_cb(cubeb* context, void* user_ptr);
void CloseUnlocked();
struct device_handle
{
cubeb_devid handle{};
std::string id;
u32 ch_cnt{};
};
std::tuple<cubeb_devid, std::string /* dev_ident */, u32 /* ch_cnt */> GetDevice(std::string_view dev_id = "");
std::tuple<cubeb_devid, std::string /* dev_ident */, u32 /* ch_cnt */> GetDefaultDeviceAlt(AudioFreq freq, AudioSampleSize sample_size, AudioChannelCnt ch_cnt);
device_handle GetDevice(std::string_view dev_id = "");
device_handle GetDefaultDeviceAlt(AudioFreq freq, AudioSampleSize sample_size, AudioChannelCnt ch_cnt);
};
+1 -1
View File
@@ -234,7 +234,7 @@ void FAudioBackend::OnVoiceProcessingPassStart_func(FAudioVoiceCallback *cb_obj,
FAudioBackend *faudio = static_cast<FAudioBackend *>(cb_obj);
std::unique_lock lock(faudio->m_cb_mutex, std::defer_lock);
if (BytesRequired && !faudio->m_reset_req.observe() && lock.try_lock() && faudio->m_write_callback && faudio->m_playing)
if (BytesRequired && !faudio->m_reset_req.observe() && lock.try_lock_for(std::chrono::microseconds{50}) && faudio->m_write_callback && faudio->m_playing)
{
ensure(BytesRequired <= faudio->m_data_buf.size(), "FAudio internal buffer is too small. Report to developers!");
+14 -12
View File
@@ -80,12 +80,6 @@ XAudio2Backend::XAudio2Backend()
return;
}
if (HRESULT hr = enumerator->RegisterEndpointNotificationCallback(this); FAILED(hr))
{
XAudio.error("RegisterEndpointNotificationCallback() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
return;
}
// All succeeded, "commit"
m_xaudio2_instance = std::move(instance);
m_device_enumerator = std::move(enumerator);
@@ -125,7 +119,7 @@ bool XAudio2Backend::Operational()
bool XAudio2Backend::DefaultDeviceChanged()
{
std::lock_guard lock{m_dev_sw_mutex};
std::lock_guard lock{m_state_cb_mutex};
return !m_reset_req.observe() && m_default_dev_changed;
}
@@ -162,9 +156,12 @@ void XAudio2Backend::CloseUnlocked()
m_master_voice = nullptr;
}
m_device_enumerator->UnregisterEndpointNotificationCallback(this);
m_playing = false;
m_last_sample.fill(0);
std::lock_guard lock(m_state_cb_mutex);
m_default_dev_changed = false;
m_current_device.clear();
}
@@ -172,7 +169,6 @@ void XAudio2Backend::CloseUnlocked()
void XAudio2Backend::Close()
{
std::lock_guard lock(m_cb_mutex);
std::lock_guard dev_sw_lock{m_dev_sw_mutex};
CloseUnlocked();
}
@@ -207,7 +203,6 @@ bool XAudio2Backend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSi
}
std::lock_guard lock(m_cb_mutex);
std::lock_guard dev_sw_lock{m_dev_sw_mutex};
CloseUnlocked();
const bool use_default_device = dev_id.empty() || dev_id == audio_device_enumerator::DEFAULT_DEV_ID;
@@ -282,6 +277,13 @@ bool XAudio2Backend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSi
return false;
}
if (HRESULT hr = m_device_enumerator->RegisterEndpointNotificationCallback(this); FAILED(hr))
{
XAudio.error("RegisterEndpointNotificationCallback() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
CloseUnlocked();
return false;
}
if (HRESULT hr = m_source_voice->SetVolume(1.0f); FAILED(hr))
{
XAudio.error("SetVolume() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
@@ -331,7 +333,7 @@ f64 XAudio2Backend::GetCallbackFrameLen()
void XAudio2Backend::OnVoiceProcessingPassStart(UINT32 BytesRequired)
{
std::unique_lock lock(m_cb_mutex, std::defer_lock);
if (BytesRequired && !m_reset_req.observe() && lock.try_lock() && m_write_callback && m_playing)
if (BytesRequired && !m_reset_req.observe() && lock.try_lock_for(std::chrono::microseconds{50}) && m_write_callback && m_playing)
{
ensure(BytesRequired <= m_data_buf.size(), "XAudio internal buffer is too small. Report to developers!");
@@ -386,7 +388,7 @@ HRESULT XAudio2Backend::OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWS
return S_OK;
}
std::lock_guard lock{m_dev_sw_mutex};
std::lock_guard lock(m_state_cb_mutex);
// Non default device is used
if (m_current_device.empty())
@@ -404,7 +406,7 @@ HRESULT XAudio2Backend::OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWS
if (m_state_callback)
{
m_state_callback(AudioStateEvent::DEFAULT_DEVICE_CHANGED);
m_state_callback(AudioStateEvent::DEFAULT_DEVICE_MAYBE_CHANGED);
}
}
}
+1 -1
View File
@@ -45,7 +45,7 @@ private:
Microsoft::WRL::ComPtr<IMMDeviceEnumerator> m_device_enumerator{};
shared_mutex m_dev_sw_mutex{};
// Protected by state callback mutex
std::string m_current_device{};
bool m_default_dev_changed = false;
+8 -6
View File
@@ -37,11 +37,11 @@ target_include_directories(rpcs3_emu
PUBLIC
${RPCS3_SRC_DIR})
# Utilities
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
@@ -117,7 +117,6 @@ target_sources(rpcs3_emu PRIVATE
../Loader/TRP.cpp
)
# Audio
target_sources(rpcs3_emu PRIVATE
Audio/audio_resampler.cpp
@@ -188,6 +187,7 @@ target_sources(rpcs3_emu PRIVATE
Cell/lv2/sys_event.cpp
Cell/lv2/sys_event_flag.cpp
Cell/lv2/sys_fs.cpp
Cell/lv2/sys_game.cpp
Cell/lv2/sys_gamepad.cpp
Cell/lv2/sys_gpio.cpp
Cell/lv2/sys_hid.cpp
@@ -322,6 +322,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
@@ -339,7 +340,7 @@ target_sources(rpcs3_emu PRIVATE
Cell/Modules/sceNpUtil.cpp
Cell/Modules/StaticHLE.cpp
Cell/Modules/sys_crashdump.cpp
Cell/Modules/sys_game.cpp
Cell/Modules/sys_game_.cpp
Cell/Modules/sys_heap.cpp
Cell/Modules/sys_io_.cpp
Cell/Modules/sys_libc_.cpp
@@ -381,6 +382,7 @@ 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
@@ -415,7 +417,6 @@ target_sources(rpcs3_emu PRIVATE
Memory/vm.cpp
)
# RSX
target_sources(rpcs3_emu PRIVATE
RSX/gcm_enums.cpp
@@ -467,6 +468,7 @@ target_sources(rpcs3_emu PRIVATE
RSX/Capture/rsx_replay.cpp
RSX/GL/glutils/blitter.cpp
RSX/GL/glutils/buffer_object.cpp
RSX/GL/glutils/capabilities.cpp
RSX/GL/glutils/common.cpp
RSX/GL/glutils/fbo.cpp
RSX/GL/glutils/image.cpp
@@ -539,7 +541,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
@@ -550,7 +552,7 @@ target_link_libraries(rpcs3_emu
if(APPLE)
check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
if (${HAVE_CLOCK_GETTIME})
target_compile_definitions(rpcs3_emu PUBLIC -DHAVE_CLOCK_GETTIME)
target_compile_definitions(rpcs3_emu PUBLIC -DHAVE_CLOCK_GETTIME)
endif()
endif()
+142 -35
View File
@@ -5,6 +5,7 @@
#include "Emu/System.h"
#include "Emu/system_config.h"
#include "Emu/Memory/vm_locking.h"
#include "Emu/Memory/vm_reservation.h"
#include "Emu/IdManager.h"
#include "Emu/GDB.h"
#include "Emu/Cell/PPUThread.h"
@@ -54,6 +55,9 @@ void fmt_class_string<cpu_flag>::format(std::string& out, u64 arg)
case cpu_flag::memory: return "mem";
case cpu_flag::pending: return "pend";
case cpu_flag::pending_recheck: return "pend-re";
case cpu_flag::notify: return "ntf";
case cpu_flag::yield: return "y";
case cpu_flag::preempt: return "PREEMPT";
case cpu_flag::dbg_global_pause: return "G-PAUSE";
case cpu_flag::dbg_pause: return "PAUSE";
case cpu_flag::dbg_step: return "STEP";
@@ -84,15 +88,18 @@ struct cpu_prof
// Total number of samples
u64 samples = 0, idle = 0;
// Avoid printing replicas
bool printed = false;
// Avoid printing replicas or when not much changed
u64 new_samples = 0;
static constexpr u64 min_print_samples = 500;
static constexpr u64 min_print_all_samples = min_print_samples * 20;
void reset()
{
freq.clear();
samples = 0;
idle = 0;
printed = false;
new_samples = 0;
}
static std::string format(const std::multimap<u64, u64, std::greater<u64>>& chart, u64 samples, u64 idle, bool extended_print = false)
@@ -128,8 +135,13 @@ struct cpu_prof
// Print info
void print(const std::shared_ptr<cpu_thread>& ptr)
{
if (printed || samples == idle)
if (new_samples < min_print_samples || samples == idle)
{
if (cpu_flag::exit - ptr->state)
{
profiler.notice("Thread \"%s\" [0x%08x]: %u samples, %u new (%.4f%% idle): Not enough new samples have been collected since the last print.", ptr->get_name(), ptr->id, samples, new_samples, 100. * idle / samples);
}
return;
}
@@ -143,13 +155,22 @@ struct cpu_prof
// Print results
const std::string results = format(chart, samples, idle);
profiler.notice("Thread \"%s\" [0x%08x]: %u samples (%.4f%% idle):%s", ptr->get_name(), ptr->id, samples, 100. * idle / samples, results);
profiler.notice("Thread \"%s\" [0x%08x]: %u samples, %u new (%.4f%% idle):%s", ptr->get_name(), ptr->id, samples, new_samples, 100. * idle / samples, results);
printed = true;
new_samples = 0;
}
static void print_all(const std::unordered_map<std::shared_ptr<cpu_thread>, sample_info>& threads)
static void print_all(std::unordered_map<std::shared_ptr<cpu_thread>, sample_info>& threads)
{
u64 new_samples = 0;
// Print all results and cleanup
for (auto& [ptr, info] : threads)
{
new_samples += info.new_samples;
info.print(ptr);
}
std::multimap<u64, u64, std::greater<u64>> chart;
std::unordered_map<u64, u64, value_hash<u64>> freq;
@@ -158,7 +179,7 @@ struct cpu_prof
for (auto& [_, info] : threads)
{
// This function collects thread information regardless of 'printed' member state
// This function collects thread information regardless of 'new_samples' member state
for (auto& [name, count] : info.freq)
{
freq[name] += count;
@@ -168,18 +189,24 @@ struct cpu_prof
idle += info.idle;
}
for (auto& [name, count] : freq)
{
chart.emplace(count, name);
}
if (samples == idle)
{
return;
}
if (new_samples < min_print_all_samples && thread_ctrl::state() != thread_state::aborting)
{
profiler.notice("All Threads: %u samples, %u new (%.4f%% idle): Not enough new samples have been collected since the last print.", samples, new_samples, 100. * idle / samples);
return;
}
for (auto& [name, count] : freq)
{
chart.emplace(count, name);
}
const std::string results = format(chart, samples, idle, true);
profiler.notice("All Threads: %u samples (%.4f%% idle):%s", samples, 100. * idle / samples, results);
profiler.notice("All Threads: %u samples, %u new (%.4f%% idle):%s", samples, new_samples, 100. * idle / samples, results);
}
};
@@ -240,7 +267,7 @@ struct cpu_prof
// Sample active threads
for (auto& [ptr, info] : threads)
{
if (cpu_flag::exit - ptr->state)
if (auto state = +ptr->state; cpu_flag::exit - state)
{
// Get short function hash
const u64 name = atomic_storage<u64>::load(ptr->block_hash);
@@ -248,9 +275,10 @@ struct cpu_prof
// Append occurrence
info.samples++;
if (auto state = +ptr->state; !::is_paused(state) && !::is_stopped(state) && cpu_flag::wait - state)
if (cpu_flag::wait - state)
{
info.freq[name]++;
info.new_samples++;
// Append verification time to fixed common name 0000000...chunk-0x3fffc
if (name >> 16 && (name & 0xffff) == 0)
@@ -258,6 +286,12 @@ struct cpu_prof
}
else
{
if (state & (cpu_flag::dbg_pause + cpu_flag::dbg_global_pause))
{
// Idle state caused by emulation pause is not accounted for
continue;
}
info.idle++;
}
}
@@ -271,11 +305,13 @@ struct cpu_prof
{
profiler.success("Flushing profiling results...");
// Print all results and cleanup
for (auto& [ptr, info] : threads)
{
info.print(ptr);
}
sample_info::print_all(threads);
}
if (Emu.IsPaused())
{
thread_ctrl::wait_for(5000);
continue;
}
// Wait, roughly for 20µs
@@ -283,11 +319,6 @@ struct cpu_prof
}
// Print all remaining results
for (auto& [ptr, info] : threads)
{
info.print(ptr);
}
sample_info::print_all(threads);
}
@@ -574,6 +605,7 @@ void cpu_thread::operator()()
if (!(state0 & cpu_flag::stop))
{
cpu_task();
state += cpu_flag::wait;
if (state & cpu_flag::ret && state.test_and_reset(cpu_flag::ret))
{
@@ -583,7 +615,7 @@ void cpu_thread::operator()()
continue;
}
thread_ctrl::wait_on(state, state0);
state.wait(state0);
if (state & cpu_flag::ret && state.test_and_reset(cpu_flag::ret))
{
@@ -635,20 +667,22 @@ cpu_thread::cpu_thread(u32 id)
void cpu_thread::cpu_wait(bs_t<cpu_flag> old)
{
thread_ctrl::wait_on(state, old);
state.wait(old);
}
static atomic_t<u32> s_dummy_atomic = 0;
bool cpu_thread::check_state() noexcept
{
bool cpu_sleep_called = false;
bool cpu_can_stop = true;
bool escape, retval;
bool escape{}, retval{};
while (true)
{
// Process all flags in a single atomic op
bs_t<cpu_flag> state1;
const auto state0 = state.fetch_op([&](bs_t<cpu_flag>& flags)
auto state0 = state.fetch_op([&](bs_t<cpu_flag>& flags)
{
bool store = false;
@@ -688,7 +722,6 @@ bool cpu_thread::check_state() noexcept
{
// Sticky flag, indicates check_state() is not allowed to return true
flags -= cpu_flag::temp;
flags -= cpu_flag::wait;
cpu_can_stop = false;
store = true;
}
@@ -730,7 +763,7 @@ bool cpu_thread::check_state() noexcept
if (!is_stopped(flags) && flags.none_of(cpu_flag::ret))
{
// Check pause flags which hold thread inside check_state (ignore suspend/debug flags on cpu_flag::temp)
if (flags & (cpu_flag::pause + cpu_flag::memory) || (cpu_can_stop && flags & (cpu_flag::dbg_global_pause + cpu_flag::dbg_pause + cpu_flag::suspend)))
if (flags & (cpu_flag::pause + cpu_flag::memory) || (cpu_can_stop && flags & (cpu_flag::dbg_global_pause + cpu_flag::dbg_pause + cpu_flag::suspend + cpu_flag::yield + cpu_flag::preempt)))
{
if (!(flags & cpu_flag::wait))
{
@@ -738,6 +771,12 @@ bool cpu_thread::check_state() noexcept
store = true;
}
if (flags & (cpu_flag::yield + cpu_flag::preempt) && cpu_can_stop)
{
flags -= (cpu_flag::yield + cpu_flag::preempt);
store = true;
}
escape = false;
state1 = flags;
return store;
@@ -753,9 +792,9 @@ bool cpu_thread::check_state() noexcept
}
else
{
if (cpu_can_stop && !(flags & cpu_flag::wait))
if (flags & cpu_flag::wait)
{
flags += cpu_flag::wait;
flags -= cpu_flag::wait;
store = true;
}
@@ -767,6 +806,34 @@ bool cpu_thread::check_state() noexcept
return store;
}).first;
if (state0 & cpu_flag::preempt && cpu_can_stop)
{
if (cpu_flag::wait - state0)
{
if (!escape || !retval)
{
// Yield itself
state0 += cpu_flag::yield;
escape = false;
}
}
if (const u128 bits = s_cpu_bits)
{
reader_lock lock(s_cpu_lock);
cpu_counter::for_all_cpu(bits & s_cpu_bits, [](cpu_thread* cpu)
{
if (cpu->state.none_of(cpu_flag::wait + cpu_flag::yield))
{
cpu->state += cpu_flag::yield;
}
return true;
});
}
}
if (escape)
{
if (s_tls_thread_slot == umax && !retval)
@@ -855,6 +922,32 @@ bool cpu_thread::check_state() noexcept
break;
}
}
continue;
}
if (state0 & cpu_flag::yield && cpu_flag::wait - state0 && cpu_can_stop)
{
if (auto spu = try_get<spu_thread>())
{
if (spu->raddr && spu->rtime == vm::reservation_acquire(spu->raddr) && spu->getllar_spin_count < 10)
{
// Reservation operation is a critical section (but this may result in false positives)
continue;
}
}
else if (auto ppu = try_get<ppu_thread>())
{
if (ppu->raddr && ppu->rtime == vm::reservation_acquire(ppu->raddr))
{
// Same
continue;
}
}
// Short sleep when yield flag is present alone (makes no sense when other methods which can stop thread execution have been done)
// Pass a mask of a single bit which is often unused to avoid notifications
s_dummy_atomic.wait(0, 1u << 30, atomic_wait_timeout{80'000});
}
}
}
@@ -892,6 +985,14 @@ cpu_thread& cpu_thread::operator=(thread_state)
if (old & cpu_flag::wait && old.none_of(cpu_flag::again + cpu_flag::exit))
{
state.notify_one(cpu_flag::exit);
if (auto thread = try_get<spu_thread>())
{
if (u32 resv = atomic_storage<u32>::load(thread->raddr))
{
vm::reservation_notifier(resv).notify_one();
}
}
}
return *this;
@@ -1232,13 +1333,19 @@ u32 CPUDisAsm::DisAsmBranchTarget(s32 /*imm*/)
return 0;
}
extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates()
extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool revert_lock)
{
const u64 start = get_system_time();
// Attempt to lock for half a second, if somehow takes longer abort it
do
{
if (revert_lock)
{
// Revert the operation of this function
break;
}
if (cpu_thread::suspend_all(nullptr, {}, []()
{
return idm::select<named_thread<spu_thread>>([](u32, spu_thread& spu)
+2
View File
@@ -25,6 +25,8 @@ enum class cpu_flag : u32
pending, // Thread has postponed work
pending_recheck, // Thread needs to recheck if there is pending work before ::pending removal
notify, // Flag meant solely to allow atomic notification on state without changing other flags
yield, // Thread is being requested to yield its execution time if it's running
preempt, // Thread is being requested to preempt the execution of all CPU threads
dbg_global_pause, // Emulation paused
dbg_pause, // Thread paused
+6
View File
@@ -30,6 +30,7 @@
#endif
#include "util/types.hpp"
#include "util/sysinfo.hpp"
#include "Utilities/StrFmt.h"
#include "Utilities/BitField.h"
#include "Utilities/JIT.h"
@@ -3442,6 +3443,11 @@ public:
template <typename T1, typename T2, typename T3>
value_t<u8[16]> vperm2b(T1 a, T2 b, T3 c)
{
if (!utils::has_fast_vperm2b())
{
return vperm2b256to128(a, b, c);
}
value_t<u8[16]> result;
const auto data0 = a.eval(m_ir);
+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);
});
+2 -2
View File
@@ -162,8 +162,8 @@ bool statichle_handler::check_against_patterns(vm::cptr<u8>& data, u32 size, u32
return false;
}
const auto sfunc = &smodule->functions.at(pat.fnid);
const u32 target = g_fxo->get<ppu_function_manager>().func_addr(sfunc->index) + 4;
const auto sfunc = &::at32(smodule->functions, pat.fnid);
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));
+14 -49
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)
@@ -454,30 +450,8 @@ public:
if (adecIsAtracX(type)) last_pts -= 0x10000; // hack
}
struct AVPacketHolder : AVPacket
{
AVPacketHolder(u32 data_size)
{
av_init_packet(this);
if (data_size)
{
this->data = static_cast<u8*>(av_calloc(1, data_size + AV_INPUT_BUFFER_PADDING_SIZE));
this->size = data_size + AV_INPUT_BUFFER_PADDING_SIZE;
}
else
{
this->data = nullptr;
this->size = 0;
}
}
~AVPacketHolder()
{
av_free(data);
}
} au(0);
AVPacket* packet = av_packet_alloc();
std::unique_ptr<AVPacket, decltype([](AVPacket* p){av_packet_unref(p);})> packet_(packet);
if (just_started && just_finished)
{
@@ -544,8 +518,6 @@ public:
just_started = false;
}
bool last_frame = false;
while (true)
{
if (Emu.IsStopped() || is_closed)
@@ -554,14 +526,7 @@ public:
break;
}
last_frame = av_read_frame(fmt, &au) < 0;
if (last_frame)
{
//break;
av_free(au.data);
au.data = NULL;
au.size = 0;
}
av_read_frame(fmt, packet);
struct AdecFrameHolder : AdecFrame
{
+51 -37
View File
@@ -158,6 +158,7 @@ audio_ringbuffer::audio_ringbuffer(cell_audio_config& _cfg)
cb_ringbuf.set_buf_size(static_cast<u32>(static_cast<u32>(cfg.backend_ch_cnt) * cfg.audio_sampling_rate * cfg.audio_sample_size * buffer_dur_mult));
backend->SetWriteCallback(std::bind(&audio_ringbuffer::backend_write_callback, this, std::placeholders::_1, std::placeholders::_2));
backend->SetStateCallback(std::bind(&audio_ringbuffer::backend_state_callback, this, std::placeholders::_1));
}
audio_ringbuffer::~audio_ringbuffer()
@@ -191,6 +192,14 @@ u32 audio_ringbuffer::backend_write_callback(u32 size, void *buf)
return static_cast<u32>(cb_ringbuf.pop(buf, size, true));
}
void audio_ringbuffer::backend_state_callback(AudioStateEvent event)
{
if (event == AudioStateEvent::DEFAULT_DEVICE_MAYBE_CHANGED)
{
backend_device_changed = true;
}
}
u64 audio_ringbuffer::get_timestamp()
{
return get_system_time();
@@ -683,7 +692,6 @@ void cell_audio_thread::reset_counters()
m_start_time = ringbuffer->get_timestamp();
m_last_period_end = m_start_time;
m_dynamic_period = 0;
m_backend_failed = false;
m_audio_should_restart = true;
}
@@ -720,9 +728,13 @@ void cell_audio_thread::operator()()
u32 untouched_expected = 0;
u32 loop_count = 0;
// Main cellAudio loop
while (thread_ctrl::state() != thread_state::aborting)
{
loop_count++;
const auto update_req = m_update_configuration.observe();
if (update_req != audio_backend_update::NONE)
{
@@ -735,37 +747,8 @@ void cell_audio_thread::operator()()
update_config(update_req == audio_backend_update::ALL);
}
if (!ringbuffer->get_operational_status())
{
if (m_backend_failed)
{
thread_ctrl::wait_for(500 * 1000);
}
else
{
cellAudio.warning("Backend stopped unexpectedly (likely device change). Attempting to recover...");
}
update_config(true);
m_backend_failed = true;
continue;
}
if (ringbuffer->device_changed())
{
cellAudio.warning("Default device changed, attempting to switch...");
update_config(false);
continue;
}
if (m_backend_failed)
{
cellAudio.warning("Backend recovered");
m_backend_failed = false;
}
const bool emu_paused = Emu.IsPaused();
const u64 timestamp = ringbuffer->update(emu_paused);
const u64 timestamp = ringbuffer->update(emu_paused || m_backend_failed);
if (emu_paused)
{
@@ -803,6 +786,36 @@ void cell_audio_thread::operator()()
continue;
}
bool operational = ringbuffer->get_operational_status();
if (!operational && loop_count % 128 == 0)
{
update_config(true);
operational = ringbuffer->get_operational_status();
}
if (ringbuffer->device_changed())
{
cellAudio.warning("Default device changed, attempting to switch...");
update_config(false);
if (operational != ringbuffer->get_operational_status())
{
continue;
}
}
if (!m_backend_failed && !operational)
{
cellAudio.error("Backend stopped unexpectedly (likely device change). Attempting to recover...");
m_backend_failed = true;
}
else if (m_backend_failed && operational)
{
cellAudio.success("Backend recovered");
m_backend_failed = false;
}
if (!cfg.buffering_enabled)
{
const u64 period_end = (m_counter * cfg.audio_block_period) + m_start_time;
@@ -906,7 +919,7 @@ void cell_audio_thread::operator()()
// As such, if the game doesn't touch buffers for too long we advance time hoping the game recovers
if (
(untouched == active_ports && time_since_last_period > cfg.fully_untouched_timeout) ||
(time_since_last_period > cfg.partially_untouched_timeout)
(time_since_last_period > cfg.partially_untouched_timeout) || g_cfg.audio.disable_sampling_skip
)
{
// There's no audio in the buffers, simply advance time and hope the game recovers
@@ -1859,12 +1872,13 @@ error_code cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
{
for (u32 i = 0; i < CELL_AUDIO_BLOCK_SAMPLES; i++)
{
// Channel order in src is Front Left, Center, Front Right, Surround Left, Surround Right, LFE
dst[i * 8 + 0] += src[i * 6 + 0] * volume; // mix L ch
dst[i * 8 + 1] += src[i * 6 + 1] * volume; // mix R ch
dst[i * 8 + 2] += src[i * 6 + 2] * volume; // mix center
dst[i * 8 + 3] += src[i * 6 + 3] * volume; // mix LFE
dst[i * 8 + 4] += src[i * 6 + 4] * volume; // mix rear L
dst[i * 8 + 5] += src[i * 6 + 5] * volume; // mix rear R
dst[i * 8 + 1] += src[i * 6 + 2] * volume; // mix R ch
dst[i * 8 + 2] += src[i * 6 + 1] * volume; // mix center
dst[i * 8 + 3] += src[i * 6 + 5] * volume; // mix LFE
dst[i * 8 + 4] += src[i * 6 + 3] * volume; // mix rear L
dst[i * 8 + 5] += src[i * 6 + 4] * volume; // mix rear R
//dst[i * 8 + 6] += 0.0f; // side L
//dst[i * 8 + 7] += 0.0f; // side R
}
+4 -2
View File
@@ -292,6 +292,7 @@ private:
audio_resampler resampler{};
atomic_t<bool> backend_active = false;
atomic_t<bool> backend_device_changed = false;
bool playing = false;
u64 update_timestamp = 0;
@@ -310,6 +311,7 @@ private:
void commit_data(f32* buf, u32 sample_cnt);
u32 backend_write_callback(u32 size, void *buf);
void backend_state_callback(AudioStateEvent event);
public:
audio_ringbuffer(cell_audio_config &cfg);
@@ -345,9 +347,9 @@ public:
return backend->Operational();
}
bool device_changed() const
bool device_changed()
{
return backend->DefaultDeviceChanged();
return backend_device_changed.test_and_reset() && backend->DefaultDeviceChanged();
}
std::string_view get_backend_name() const
+18 -18
View File
@@ -33,13 +33,13 @@ void fmt_class_string<CellAudioOutError>::format(std::string& out, u64 arg)
audio_out_configuration::audio_out_configuration()
{
audio_out& primary_output = out.at(CELL_AUDIO_OUT_PRIMARY);
audio_out& secondary_output = out.at(CELL_AUDIO_OUT_SECONDARY);
audio_out& primary_output = ::at32(out, CELL_AUDIO_OUT_PRIMARY);
audio_out& secondary_output = ::at32(out, CELL_AUDIO_OUT_SECONDARY);
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.
@@ -58,8 +58,8 @@ audio_out_configuration::audio_out_configuration()
const auto add_sound_mode = [&](u32 index, u8 type, u8 channel, u8 fs, u32 layout, bool supported)
{
audio_out& output = out.at(index);
bool& selected = initial_mode_selected.at(index);
audio_out& output = ::at32(out, index);
bool& selected = ::at32(initial_mode_selected, index);
CellAudioOutSoundMode mode{};
mode.type = type;
@@ -103,7 +103,7 @@ audio_out_configuration::audio_out_configuration()
{
// Linear PCM 5.1 Ch. 48 kHz
add_sound_mode(CELL_AUDIO_OUT_PRIMARY, CELL_AUDIO_OUT_CODING_TYPE_LPCM, CELL_AUDIO_OUT_CHNUM_6, CELL_AUDIO_OUT_FS_48KHZ, CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr, supports_lpcm_5_1);
// Dolby Digital 5.1 Ch.
add_sound_mode(CELL_AUDIO_OUT_PRIMARY, CELL_AUDIO_OUT_CODING_TYPE_AC3, CELL_AUDIO_OUT_CHNUM_6, CELL_AUDIO_OUT_FS_48KHZ, CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr, supports_ac3);
@@ -161,8 +161,8 @@ audio_out_configuration::audio_out_configuration()
// The secondary output only supports Linear PCM 2 Ch.
add_sound_mode(CELL_AUDIO_OUT_SECONDARY, CELL_AUDIO_OUT_CODING_TYPE_LPCM, CELL_AUDIO_OUT_CHNUM_2, CELL_AUDIO_OUT_FS_48KHZ, CELL_AUDIO_OUT_SPEAKER_LAYOUT_2CH, true);
ensure(!primary_modes.empty() && initial_mode_selected.at(CELL_AUDIO_OUT_PRIMARY));
ensure(!secondary_modes.empty() && initial_mode_selected.at(CELL_AUDIO_OUT_SECONDARY));
ensure(!primary_modes.empty() && ::at32(initial_mode_selected, CELL_AUDIO_OUT_PRIMARY));
ensure(!secondary_modes.empty() && ::at32(initial_mode_selected, CELL_AUDIO_OUT_SECONDARY));
for (const CellAudioOutSoundMode& mode : primary_modes)
{
@@ -238,7 +238,7 @@ error_code cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32
// Check if the requested audio parameters are available and find the max supported channel count
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
std::lock_guard lock(cfg.mtx);
const audio_out_configuration::audio_out& out = cfg.out.at(audioOut);
const audio_out_configuration::audio_out& out = ::at32(cfg.out, audioOut);
for (const CellAudioOutSoundMode& mode : out.sound_modes)
{
@@ -265,7 +265,7 @@ error_code cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32
// Check if the requested audio parameters are available
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
std::lock_guard lock(cfg.mtx);
const audio_out_configuration::audio_out& out = cfg.out.at(audioOut);
const audio_out_configuration::audio_out& out = ::at32(cfg.out, audioOut);
for (const CellAudioOutSoundMode& mode : out.sound_modes)
{
@@ -319,7 +319,7 @@ error_code cellAudioOutGetState(u32 audioOut, u32 deviceIndex, vm::ptr<CellAudio
{
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
std::lock_guard lock(cfg.mtx);
const audio_out_configuration::audio_out& out = cfg.out.at(audioOut);
const audio_out_configuration::audio_out& out = ::at32(cfg.out, audioOut);
_state.state = out.state;
_state.encoder = out.encoder;
@@ -360,7 +360,7 @@ error_code cellAudioOutConfigure(u32 audioOut, vm::ptr<CellAudioOutConfiguration
{
std::lock_guard lock(cfg.mtx);
audio_out_configuration::audio_out& out = cfg.out.at(audioOut);
audio_out_configuration::audio_out& out = ::at32(cfg.out, audioOut);
// Apparently the set config does not necessarily have to exist in the list of sound modes.
@@ -406,7 +406,7 @@ error_code cellAudioOutConfigure(u32 audioOut, vm::ptr<CellAudioOutConfiguration
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
{
std::lock_guard lock(cfg.mtx);
cfg.out.at(audioOut).state = CELL_AUDIO_OUT_OUTPUT_STATE_DISABLED;
::at32(cfg.out, audioOut).state = CELL_AUDIO_OUT_OUTPUT_STATE_DISABLED;
}
audio::configure_audio(true);
@@ -414,7 +414,7 @@ error_code cellAudioOutConfigure(u32 audioOut, vm::ptr<CellAudioOutConfiguration
{
std::lock_guard lock(cfg.mtx);
cfg.out.at(audioOut).state = CELL_AUDIO_OUT_OUTPUT_STATE_ENABLED;
::at32(cfg.out, audioOut).state = CELL_AUDIO_OUT_OUTPUT_STATE_ENABLED;
}
};
@@ -455,7 +455,7 @@ error_code cellAudioOutGetConfiguration(u32 audioOut, vm::ptr<CellAudioOutConfig
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
std::lock_guard lock(cfg.mtx);
const audio_out_configuration::audio_out& out = cfg.out.at(audioOut);
const audio_out_configuration::audio_out& out = ::at32(cfg.out, audioOut);
// Return the active config.
CellAudioOutConfiguration _config{};
@@ -516,7 +516,7 @@ error_code cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptr<Cell
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
std::lock_guard lock(cfg.mtx);
ensure(audioOut < cfg.out.size());
const audio_out_configuration::audio_out& out = cfg.out.at(audioOut);
const audio_out_configuration::audio_out& out = ::at32(cfg.out, audioOut);
ensure(out.sound_modes.size() <= 16);
CellAudioOutDeviceInfo _info{};
@@ -528,7 +528,7 @@ error_code cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptr<Cell
for (usz i = 0; i < out.sound_modes.size(); i++)
{
_info.availableModes[i] = out.sound_modes.at(i);
_info.availableModes[i] = ::at32(out.sound_modes, i);
}
*info = _info;
@@ -557,7 +557,7 @@ error_code cellAudioOutSetCopyControl(u32 audioOut, u32 control)
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
std::lock_guard lock(cfg.mtx);
cfg.out.at(audioOut).copy_control = control;
::at32(cfg.out, audioOut).copy_control = control;
return CELL_OK;
}
+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)
{
+1 -1
View File
@@ -175,7 +175,7 @@ static error_code check_camera_info(const VariantOfCellCameraInfo& info)
return CELL_CAMERA_ERROR_BAD_FRAMERATE;
}
auto check_fps = [fps = info.framerate](const std::vector<s32>& range)
auto check_fps = [fps = info.framerate](std::initializer_list<s32> range)
{
return std::find(range.begin(), range.end(), fps) != range.end();
};
-2
View File
@@ -477,5 +477,3 @@ struct gem_camera_shared
atomic_t<s32> size{0};
atomic_t<CellCameraFormat> format{CELL_CAMERA_RAW8};
};
static inline s32 get_video_buffer_size(s32 width, s32 height);
@@ -52,7 +52,7 @@ struct cross_controller
close_msg_dialog();
sysutil_register_cb([=](ppu_thread& ppu) -> s32
sysutil_register_cb([this, status](ppu_thread& ppu) -> s32
{
callback(ppu, CELL_CROSS_CONTROLLER_STATUS_FINALIZED, status, vm::null, userdata);
return CELL_OK;
@@ -74,9 +74,9 @@ struct cross_controller
// TODO: Show icons from comboplay_plugin.rco in dialog. Maybe use a new dialog or add an optional icon to this one.
error_code res = open_msg_dialog(false, CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_OFF, vm::make_str(msg), msg_dialog_callback, userdata);
sysutil_register_cb([=](ppu_thread& ppu) -> s32
sysutil_register_cb([this, res](ppu_thread& ppu) -> s32
{
callback(ppu, CELL_CROSS_CONTROLLER_STATUS_INITIALIZED, res == CELL_OK ? CELL_OK : CELL_CROSS_CONTROLLER_ERROR_INTERNAL, vm::null, userdata);
callback(ppu, CELL_CROSS_CONTROLLER_STATUS_INITIALIZED, res == CELL_OK ? +CELL_OK : +CELL_CROSS_CONTROLLER_ERROR_INTERNAL, vm::null, userdata);
return CELL_OK;
});
+19 -23
View File
@@ -230,17 +230,12 @@ disc_change_manager::~disc_change_manager()
error_code disc_change_manager::register_callbacks(vm::ptr<CellGameDiscEjectCallback> func_eject, vm::ptr<CellGameDiscInsertCallback> func_insert)
{
if (!func_eject || !func_insert)
{
return CELL_GAME_ERROR_PARAM;
}
std::lock_guard lock(mtx);
eject_callback = func_eject;
insert_callback = func_insert;
Emu.GetCallbacks().enable_disc_eject(true);
Emu.GetCallbacks().enable_disc_eject(!!func_eject);
Emu.GetCallbacks().enable_disc_insert(false);
return CELL_OK;
@@ -420,16 +415,16 @@ 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 = psf.at("PARENTAL_LEVEL").as_integer();
if (psf.contains("ATTRIBUTE")) get->getParam.attribute = psf.at("ATTRIBUTE").as_integer();
if (psf.contains("RESOLUTION")) get->getParam.resolution = psf.at("RESOLUTION").as_integer();
if (psf.contains("SOUND_FORMAT")) get->getParam.soundFormat = psf.at("SOUND_FORMAT").as_integer();
if (psf.contains("TITLE")) strcpy_trunc(get->getParam.title, psf.at("TITLE").as_string());
if (psf.contains("APP_VER")) strcpy_trunc(get->getParam.dataVersion, psf.at("APP_VER").as_string());
if (psf.contains("TITLE_ID")) strcpy_trunc(get->getParam.titleId, psf.at("TITLE_ID").as_string());
if (psf.contains("PARENTAL_LEVEL")) get->getParam.parentalLevel = ::at32(psf, "PARENTAL_LEVEL").as_integer();
if (psf.contains("ATTRIBUTE")) get->getParam.attribute = ::at32(psf, "ATTRIBUTE").as_integer();
if (psf.contains("RESOLUTION")) get->getParam.resolution = ::at32(psf, "RESOLUTION").as_integer();
if (psf.contains("SOUND_FORMAT")) get->getParam.soundFormat = ::at32(psf, "SOUND_FORMAT").as_integer();
if (psf.contains("TITLE")) strcpy_trunc(get->getParam.title, ::at32(psf, "TITLE").as_string());
if (psf.contains("APP_VER")) strcpy_trunc(get->getParam.dataVersion, ::at32(psf, "APP_VER").as_string());
if (psf.contains("TITLE_ID")) strcpy_trunc(get->getParam.titleId, ::at32(psf, "TITLE_ID").as_string());
for (u32 i = 0; i < CELL_HDDGAME_SYSP_LANGUAGE_NUM; i++)
{
@@ -675,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")
{
@@ -684,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
{
@@ -693,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();
}
@@ -728,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>();
@@ -1536,7 +1531,8 @@ error_code cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::cptr<char
return CELL_GAME_ERROR_PARAM;
}
error_msg += "\n" + get_localized_string(localized_string_id::CELL_GAME_ERROR_DIR_NAME, fmt::format("%s", dirName).c_str());
error_msg += '\n';
error_msg += get_localized_string(localized_string_id::CELL_GAME_ERROR_DIR_NAME, fmt::format("%s", dirName).c_str());
}
return open_exit_dialog(error_msg, type > CELL_GAME_ERRDIALOG_NOSPACE);
@@ -1702,7 +1698,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;
@@ -1712,10 +1708,10 @@ 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 = psf.at("PARENTAL_LEVEL").as_integer();
if (psf.contains("TITLE_ID")) strcpy_trunc(getParam->titleId, psf.at("TITLE_ID").as_string());
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());
return CELL_OK;
}
+5 -7
View File
@@ -322,7 +322,7 @@ error_code cellGcmBindZcull(u8 index, u32 offset, u32 width, u32 height, u32 cul
{
return err;
}
vm::_ptr<CellGcmZcullInfo>(gcm_cfg.zculls_addr)[index] = gcm_zcull;
return CELL_OK;
}
@@ -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;
}
@@ -1314,8 +1314,6 @@ void _cellGcmSetFlipCommandWithWaitLabel(ppu_thread& ppu, vm::ptr<CellGcmContext
{
cellGcmSys.warning("cellGcmSetFlipCommandWithWaitLabel(ctx=*0x%x, id=0x%x, label_index=0x%x, label_value=0x%x)", ctx, id, label_index, label_value);
auto& gcm_cfg = g_fxo->get<gcm_config>();
rsx::make_command(ctx->current, NV406E_SEMAPHORE_OFFSET, { label_index * 0x10, label_value });
if (auto error = gcmSetPrepareFlip<true>(ppu, ctx, id); error < 0)
+188 -72
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:
@@ -214,12 +259,22 @@ 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;
}
gem_controller& controller = controllers.at(gem_num);
gem_controller& controller = ::at32(controllers, gem_num);
controller = {};
controller.sphere_rgb = gem_color::get_default_color(gem_num);
@@ -446,7 +501,7 @@ static bool check_gem_num(const u32 gem_num)
return gem_num < CELL_GEM_MAX_NUM;
}
static inline void draw_overlay_cursor(u32 gem_num, const gem_config::gem_controller& controller, s32 x_pos, s32 y_pos, s32 x_max, s32 y_max)
static inline void draw_overlay_cursor(u32 gem_num, const gem_config::gem_controller&, s32 x_pos, s32 y_pos, s32 x_max, s32 y_max)
{
const u16 x = static_cast<u16>(x_pos / (x_max / static_cast<f32>(rsx::overlays::overlay::virtual_width)));
const u16 y = static_cast<u16>(y_pos / (y_max / static_cast<f32>(rsx::overlays::overlay::virtual_height)));
@@ -563,7 +618,7 @@ static void ds3_input_to_pad(const u32 port_no, be_t<u16>& digital_buttons, be_t
std::lock_guard lock(pad::g_pad_mutex);
const auto handler = pad::get_current_handler();
const auto& pad = handler->GetPads().at(port_no);
const auto& pad = ::at32(handler->GetPads(), port_no);
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
{
@@ -646,9 +701,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;
}
@@ -656,7 +712,7 @@ static void ds3_pos_to_gem_image_state(const u32 port_no, const gem_config::gem_
std::lock_guard lock(pad::g_pad_mutex);
const auto handler = pad::get_current_handler();
const auto& pad = handler->GetPads().at(port_no);
const auto& pad = ::at32(handler->GetPads(), port_no);
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
{
@@ -666,30 +722,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 = handler->GetPads().at(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);
}
/**
@@ -712,7 +752,7 @@ static void ds3_input_to_ext(const u32 port_no, const gem_config::gem_controller
std::lock_guard lock(pad::g_pad_mutex);
const auto handler = pad::get_current_handler();
const auto& pad = handler->GetPads().at(port_no);
const auto& pad = ::at32(handler->GetPads(), port_no);
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
{
@@ -769,7 +809,7 @@ static bool mouse_input_to_pad(const u32 mouse_no, be_t<u16>& digital_buttons, b
return false;
}
const auto& mouse_data = handler.GetMice().at(mouse_no);
const auto& mouse_data = ::at32(handler.GetMice(), mouse_no);
const auto is_pressed = [&mouse_data](MouseButtonCodes button) -> bool { return !!(mouse_data.buttons & button); };
digital_buttons = 0;
@@ -803,31 +843,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 = handler.GetMice().at(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())
{
@@ -846,11 +863,85 @@ static void mouse_pos_to_gem_state(const u32 mouse_no, const gem_config::gem_con
return;
}
const auto& mouse = handler.GetMice().at(mouse_no);
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_SELECT;
if (gun.handler.get_button(gem_no, gun_button::btn_1) == 1)
digital_buttons |= CELL_GEM_CTRL_START;
if (gun.handler.get_button(gem_no, gun_button::btn_2) == 1)
digital_buttons |= CELL_GEM_CTRL_CROSS;
if (gun.handler.get_button(gem_no, gun_button::btn_3) == 1)
digital_buttons |= CELL_GEM_CTRL_CIRCLE;
if (gun.handler.get_button(gem_no, gun_button::btn_4) == 1)
digital_buttons |= CELL_GEM_CTRL_SQUARE;
if (gun.handler.get_button(gem_no, gun_button::btn_5) == 1)
digital_buttons |= CELL_GEM_CTRL_TRIANGLE;
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,7 +1323,7 @@ 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();
@@ -1242,13 +1333,21 @@ error_code cellGemGetImageState(u32 gem_num, vm::ptr<CellGemImageState> gem_imag
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,7 +1379,7 @@ 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);
@@ -1288,13 +1387,21 @@ error_code cellGemGetInertialState(u32 gem_num, u32 state_flag, u64 timestamp, v
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 +1549,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);
@@ -1456,15 +1563,24 @@ error_code cellGemGetState(u32 gem_num, u32 flag, u64 time_parameter, vm::ptr<Ce
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");
}
}
+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
@@ -1120,7 +1120,7 @@ error_code cellHttpAuthCacheExport(vm::ptr<u32> buf, u32 len, vm::ptr<u32> outsi
// TODO
}
u32 size = 0;
[[maybe_unused]] u32 size = 0;
// TODO
@@ -2786,7 +2786,7 @@ error_code cellHttpClientAddHeader(CellHttpClientId clientId, vm::cptr<CellHttpH
error_code cellHttpClientDeleteHeader(CellHttpClientId clientId, vm::cptr<char> name)
{
cellHttp.todo("cellHttpClientDeleteHeader(clientId=0x%x, name=%s)", clientId, name);
auto& man = g_fxo->get<http_manager>();
std::lock_guard lock(man.mtx);
@@ -2806,7 +2806,7 @@ error_code cellHttpClientDeleteHeader(CellHttpClientId clientId, vm::cptr<char>
error_code cellHttpClientSetSslCallback(CellHttpClientId clientId, vm::ptr<CellHttpsSslCallback> cbfunc, vm::ptr<void> userArg)
{
cellHttp.todo("cellHttpClientSetSslCallback(clientId=0x%x, cbfunc=*0x%x, userArg=*0x%x)", clientId, cbfunc, userArg);
auto& man = g_fxo->get<http_manager>();
std::lock_guard lock(man.mtx);
+2 -2
View File
@@ -230,7 +230,7 @@ error_code cellHttpUtilBuildRequestLine(vm::cptr<CellHttpRequestLine> req, vm::p
std::string path = fmt::format("%s", req->path);
if (path.empty())
{
path = "/";
path += '/';
}
// TODO: are the numbers properly formatted ?
@@ -805,7 +805,7 @@ error_code cellHttpUtilBase64Encoder(vm::ptr<char> out, vm::cptr<void> input, u3
error_code cellHttpUtilBase64Decoder(vm::ptr<char> output, vm::cptr<void> in, u32 len)
{
cellHttpUtil.todo("cellHttpUtilBase64Decoder(output=*0x%x, in=*0x%x, len=%d)", output, in, len);
cellHttpUtil.todo("cellHttpUtilBase64Decoder(output=*0x%x, in=*0x%x, len=%d)", output, in, len);
if (!in)
{
+7
View File
@@ -45,7 +45,14 @@ bool ime_jp_manager::addChar(u16 c)
std::u16string tmp;
tmp += c;
#if defined(__GNUG__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wrestrict"
#endif
input_string.insert(cursor++, tmp);
#if defined(__GNUG__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
cursor_end = cursor;
input_state = CELL_IMEJP_BEFORE_CONVERT;
return true;
+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;
}
+4 -4
View File
@@ -49,7 +49,7 @@ KeyboardHandlerBase::KeyboardHandlerBase(utils::serial* ar)
Emu.DeferDeserialization([this]()
{
Init(m_info.max_connect);
init.init();
auto lk = init.init();
});
}
}
@@ -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)
-2
View File
@@ -56,5 +56,3 @@ struct CellKbConfig
be_t<u32> read_mode;
be_t<u32> code_type;
};
u16 cellKbCnvRawCode(u32 arrange, u32 mkey, u32 led, u16 rawcode);
+17 -17
View File
@@ -151,23 +151,23 @@ void mic_context::load_config_and_init()
for (s32 index = 0; index < static_cast<s32>(device_list.size()); index++)
{
mic_list.emplace(std::piecewise_construct, std::forward_as_tuple(index), std::forward_as_tuple(microphone_handler::standard));
mic_list.at(index).add_device(device_list[index]);
::at32(mic_list, index).add_device(device_list[index]);
}
break;
}
case microphone_handler::singstar:
{
mic_list.emplace(std::piecewise_construct, std::forward_as_tuple(0), std::forward_as_tuple(microphone_handler::singstar));
mic_list.at(0).add_device(device_list[0]);
::at32(mic_list, 0).add_device(device_list[0]);
if (device_list.size() >= 2)
mic_list.at(0).add_device(device_list[1]);
::at32(mic_list, 0).add_device(device_list[1]);
break;
}
case microphone_handler::real_singstar:
case microphone_handler::rocksmith:
{
mic_list.emplace(std::piecewise_construct, std::forward_as_tuple(0), std::forward_as_tuple(g_cfg.audio.microphone_type));
mic_list.at(0).add_device(device_list[0]);
::at32(mic_list, 0).add_device(device_list[0]);
break;
}
case microphone_handler::null:
@@ -563,7 +563,7 @@ error_code cellMicOpen(s32 dev_num, s32 sampleRate)
if (!mic_thr.mic_list.count(dev_num))
return CELL_MICIN_ERROR_DEVICE_NOT_FOUND;
auto& device = mic_thr.mic_list.at(dev_num);
auto& device = ::at32(mic_thr.mic_list, dev_num);
if (device.is_opened())
return CELL_MICIN_ERROR_ALREADY_OPEN;
@@ -583,7 +583,7 @@ error_code cellMicOpenRaw(s32 dev_num, s32 sampleRate, s32 maxChannels)
if (!mic_thr.mic_list.count(dev_num))
return CELL_MICIN_ERROR_DEVICE_NOT_FOUND;
auto& device = mic_thr.mic_list.at(dev_num);
auto& device = ::at32(mic_thr.mic_list, dev_num);
if (device.is_opened())
return CELL_MICIN_ERROR_ALREADY_OPEN;
@@ -604,7 +604,7 @@ error_code cellMicOpenEx(s32 dev_num, s32 rawSampleRate, s32 rawChannel, s32 DSP
if (!mic_thr.mic_list.count(dev_num))
return CELL_MICIN_ERROR_DEVICE_NOT_FOUND;
auto& device = mic_thr.mic_list.at(dev_num);
auto& device = ::at32(mic_thr.mic_list, dev_num);
if (device.is_opened())
return CELL_MICIN_ERROR_ALREADY_OPEN;
@@ -626,7 +626,7 @@ u8 cellMicIsOpen(s32 dev_num)
if (!mic_thr.mic_list.count(dev_num))
return false;
return mic_thr.mic_list.at(dev_num).is_opened();
return ::at32(mic_thr.mic_list, dev_num).is_opened();
}
s32 cellMicIsAttached(s32 dev_num)
@@ -647,7 +647,7 @@ error_code cellMicClose(s32 dev_num)
if (!mic_thr.mic_list.count(dev_num))
return CELL_MICIN_ERROR_DEVICE_NOT_FOUND;
auto& device = mic_thr.mic_list.at(dev_num);
auto& device = ::at32(mic_thr.mic_list, dev_num);
if (!device.is_opened())
return CELL_MICIN_ERROR_NOT_OPEN;
@@ -669,7 +669,7 @@ error_code cellMicStart(s32 dev_num)
if (!mic_thr.mic_list.count(dev_num))
return CELL_MICIN_ERROR_DEVICE_NOT_FOUND;
auto& device = mic_thr.mic_list.at(dev_num);
auto& device = ::at32(mic_thr.mic_list, dev_num);
if (!device.is_opened())
return CELL_MICIN_ERROR_NOT_OPEN;
@@ -691,7 +691,7 @@ error_code cellMicStartEx(s32 dev_num, u32 iflags)
if (!mic_thr.mic_list.count(dev_num))
return CELL_MICIN_ERROR_DEVICE_NOT_FOUND;
auto& device = mic_thr.mic_list.at(dev_num);
auto& device = ::at32(mic_thr.mic_list, dev_num);
if (!device.is_opened())
return CELL_MICIN_ERROR_NOT_OPEN;
@@ -713,7 +713,7 @@ error_code cellMicStop(s32 dev_num)
if (!mic_thr.mic_list.count(dev_num))
return CELL_MICIN_ERROR_DEVICE_NOT_FOUND;
auto& device = mic_thr.mic_list.at(dev_num);
auto& device = ::at32(mic_thr.mic_list, dev_num);
if (!device.is_opened())
return CELL_MICIN_ERROR_NOT_OPEN;
@@ -743,7 +743,7 @@ error_code cellMicGetDeviceAttr(s32 dev_num, CellMicDeviceAttr deviceAttributes,
if (!mic_thr.mic_list.count(dev_num))
return CELL_MICIN_ERROR_DEVICE_NOT_FOUND;
auto& device = mic_thr.mic_list.at(dev_num);
auto& device = ::at32(mic_thr.mic_list, dev_num);
switch (deviceAttributes)
{
@@ -771,7 +771,7 @@ error_code cellMicSetDeviceAttr(s32 dev_num, CellMicDeviceAttr deviceAttributes,
if (!mic_thr.mic_list.count(dev_num))
return CELL_MICIN_ERROR_DEVICE_NOT_FOUND;
auto& device = mic_thr.mic_list.at(dev_num);
auto& device = ::at32(mic_thr.mic_list, dev_num);
switch (deviceAttributes)
{
@@ -854,7 +854,7 @@ error_code cellMicGetFormatRaw(s32 dev_num, vm::ptr<CellMicInputFormatI> format)
if (!mic_thr.mic_list.count(dev_num))
return CELL_MICIN_ERROR_DEVICE_NOT_FOUND;
auto& device = mic_thr.mic_list.at(dev_num);
auto& device = ::at32(mic_thr.mic_list, dev_num);
format->subframeSize = device.get_bit_resolution() / 8; // Probably?
format->bitResolution = device.get_bit_resolution();
@@ -956,7 +956,7 @@ error_code cellMicReadRaw(s32 dev_num, vm::ptr<void> data, s32 max_bytes)
if (!mic_thr.mic_list.count(dev_num))
return CELL_MICIN_ERROR_DEVICE_NOT_FOUND;
auto& mic = mic_thr.mic_list.at(dev_num);
auto& mic = ::at32(mic_thr.mic_list, dev_num);
if (!mic.is_opened() || !(mic.get_signal_types() & CELLMIC_SIGTYPE_RAW))
return CELL_MICIN_ERROR_NOT_OPEN;
@@ -978,7 +978,7 @@ error_code cellMicRead(s32 dev_num, vm::ptr<void> data, u32 max_bytes)
if (!mic_thr.mic_list.count(dev_num))
return CELL_MICIN_ERROR_DEVICE_NOT_FOUND;
auto& mic = mic_thr.mic_list.at(dev_num);
auto& mic = ::at32(mic_thr.mic_list, dev_num);
if (!mic.is_opened() || !(mic.get_signal_types() & CELLMIC_SIGTYPE_DSP))
return CELL_MICIN_ERROR_NOT_OPEN;
+6 -6
View File
@@ -49,7 +49,7 @@ MouseHandlerBase::MouseHandlerBase(utils::serial* ar)
Emu.DeferDeserialization([this]()
{
Init(m_info.max_connect);
init.init();
auto lk = init.init();
});
}
}
@@ -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());
@@ -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());
@@ -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());
+1 -1
View File
@@ -245,7 +245,7 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString,
break;
}
thread_ctrl::wait_on(ppu.state, state);
ppu.state.wait(state);
}
if (is_blocking)
+43 -9
View File
@@ -161,8 +161,8 @@ struct music_state
if (next_track < playlist.size())
{
path = vfs::get(playlist.at(next_track));
cellMusic.notice("set_playback_command: current vfs path: '%s' (unresolved='%s')", path, playlist.at(next_track));
path = vfs::get(::at32(playlist, next_track));
cellMusic.notice("set_playback_command: current vfs path: '%s' (unresolved='%s')", path, ::at32(playlist, next_track));
}
else
{
@@ -244,10 +244,15 @@ error_code cellMusicGetSelectionContext(vm::ptr<CellMusicSelectionContext> conte
if (!context)
return CELL_MUSIC_ERROR_PARAM;
auto& music = g_fxo->get<music_state>();
std::lock_guard lock(music.mtx);
if (!music.current_selection_context)
{
return CELL_MUSIC2_ERROR_NO_ACTIVE_CONTENT;
}
*context = music.current_selection_context.get();
cellMusic.success("cellMusicGetSelectionContext: selection context = %s", music.current_selection_context.to_string());
@@ -317,6 +322,12 @@ error_code cellMusicGetContentsId(vm::ptr<CellSearchContentId> contents_id)
// HACKY
auto& music = g_fxo->get<music_state>();
std::lock_guard lock(music.mtx);
if (!music.current_selection_context)
{
return CELL_MUSIC2_ERROR_NO_ACTIVE_CONTENT;
}
return music.current_selection_context.find_content_id(contents_id);
}
@@ -363,6 +374,7 @@ error_code cellMusicInitialize2SystemWorkload(s32 mode, vm::ptr<CellMusic2Callba
auto& music = g_fxo->get<music_state>();
music.func = func;
music.userData = userData;
music.current_selection_context = {};
sysutil_register_cb([=, &music](ppu_thread& ppu) -> s32
{
@@ -429,6 +441,7 @@ error_code cellMusicInitializeSystemWorkload(s32 mode, u32 container, vm::ptr<Ce
auto& music = g_fxo->get<music_state>();
music.func = func;
music.userData = userData;
music.current_selection_context = {};
sysutil_register_cb([=, &music](ppu_thread& ppu) -> s32
{
@@ -451,6 +464,7 @@ error_code cellMusicInitialize(s32 mode, u32 container, s32 spuPriority, vm::ptr
auto& music = g_fxo->get<music_state>();
music.func = func;
music.userData = userData;
music.current_selection_context = {};
sysutil_register_cb([=, &music](ppu_thread& ppu) -> s32
{
@@ -489,6 +503,11 @@ error_code cellMusicGetSelectionContext2(vm::ptr<CellMusicSelectionContext> cont
auto& music = g_fxo->get<music_state>();
std::lock_guard lock(music.mtx);
if (!music.current_selection_context)
{
return CELL_MUSIC2_ERROR_NO_ACTIVE_CONTENT;
}
*context = music.current_selection_context.get();
cellMusic.success("cellMusicGetSelectionContext2: selection context = %s", music.current_selection_context.to_string());
@@ -533,14 +552,21 @@ error_code cellMusicSetPlaybackCommand2(s32 command, vm::ptr<void> param)
if (!music.func)
return CELL_MUSIC2_ERROR_GENERIC;
sysutil_register_cb([=, &music](ppu_thread& ppu) -> s32
error_code result = CELL_OK;
if (!music.current_selection_context)
{
const error_code result = music.set_playback_command(command);
result = CELL_MUSIC_ERROR_GENERIC;
}
sysutil_register_cb([=, &music, prev_res = result](ppu_thread& ppu) -> s32
{
const error_code result = prev_res ? prev_res : music.set_playback_command(command);
music.func(ppu, CELL_MUSIC2_EVENT_SET_PLAYBACK_COMMAND_RESULT, vm::addr_t(+result), music.userData);
return CELL_OK;
});
return CELL_OK;
return result;
}
error_code cellMusicSetPlaybackCommand(s32 command, vm::ptr<void> param)
@@ -555,14 +581,21 @@ error_code cellMusicSetPlaybackCommand(s32 command, vm::ptr<void> param)
if (!music.func)
return CELL_MUSIC_ERROR_GENERIC;
sysutil_register_cb([=, &music](ppu_thread& ppu) -> s32
error_code result = CELL_OK;
if (!music.current_selection_context)
{
const error_code result = music.set_playback_command(command);
result = CELL_MUSIC2_ERROR_GENERIC;
}
sysutil_register_cb([=, &music, prev_res = result](ppu_thread& ppu) -> s32
{
const error_code result = prev_res ? prev_res : music.set_playback_command(command);
music.func(ppu, CELL_MUSIC_EVENT_SET_PLAYBACK_COMMAND_RESULT, vm::addr_t(+result), music.userData);
return CELL_OK;
});
return CELL_OK;
return result;
}
error_code cellMusicSelectContents2()
@@ -591,6 +624,7 @@ error_code cellMusicInitialize2(s32 mode, s32 spuPriority, vm::ptr<CellMusic2Cal
auto& music = g_fxo->get<music_state>();
music.func = func;
music.userData = userData;
music.current_selection_context = {};
sysutil_register_cb([=, &music](ppu_thread& ppu) -> s32
{
+6
View File
@@ -141,6 +141,7 @@ struct CellMusicSelectionContext
struct music_selection_context
{
bool valid = false;
char magic[4] = "SUS";
std::string hash;
CellSearchContentType content_type = CELL_SEARCH_CONTENTTYPE_MUSIC;
@@ -167,6 +168,11 @@ struct music_selection_context
bool load_playlist();
u32 step_track(bool next);
operator bool() const
{
return atomic_storage<bool>::load(valid);
}
// Helper
error_code find_content_id(vm::ptr<CellSearchContentId> contents_id);
};
+2 -2
View File
@@ -235,7 +235,7 @@ error_code cell_music_decode_read(vm::ptr<void> buf, vm::ptr<u32> startTime, u64
{
start_time_ms = dec.decoder.timestamps_ms.front().second;
while (dec.decoder.timestamps_ms.size() > 1 && dec.read_pos >= dec.decoder.timestamps_ms.at(1).first)
while (dec.decoder.timestamps_ms.size() > 1 && dec.read_pos >= ::at32(dec.decoder.timestamps_ms, 1).first)
{
dec.decoder.timestamps_ms.pop_front();
}
@@ -274,7 +274,7 @@ error_code cell_music_decode_read(vm::ptr<void> buf, vm::ptr<u32> startTime, u64
error_code cellMusicDecodeInitialize(s32 mode, u32 container, s32 spuPriority, vm::ptr<CellMusicDecodeCallback> func, vm::ptr<void> userData)
{
cellMusicDecode.warning("cellMusicDecodeInitialize(mode=0x%x, container=0x%x, spuPriority=0x%x, func=*0x%x, userData=*0x%x)", mode, container, spuPriority, func, userData);
if (mode != CELL_MUSIC_DECODE2_MODE_NORMAL || (spuPriority - 0x10U > 0xef) || !func)
{
return CELL_MUSIC_DECODE_ERROR_PARAM;
@@ -47,7 +47,7 @@ std::string music_selection_context::to_string() const
for (usz i = 0; i < playlist.size(); i++)
{
fmt::append(str, "\n - Track %d: %s", i, playlist.at(i));
fmt::append(str, "\n - Track %d: %s", i, ::at32(playlist, i));
}
return str;
@@ -242,6 +242,7 @@ bool music_selection_context::load_playlist()
playlist.push_back(track_node[i].Scalar());
}
valid = true;
return true;
}
+2 -2
View File
@@ -212,7 +212,7 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
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_local_ip_addr())); 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_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;
@@ -237,7 +237,7 @@ struct netstart_hack
error_code cellNetCtlNetStartDialogLoadAsync(vm::cptr<CellNetCtlNetStartDialogParam> param)
{
cellNetCtl.error("cellNetCtlNetStartDialogLoadAsync(param=*0x%x)", param);
cellNetCtl.warning("cellNetCtlNetStartDialogLoadAsync(param=*0x%x)", param);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
+8 -8
View File
@@ -144,7 +144,7 @@ error_code cellPadClearBuf(u32 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);
@@ -177,7 +177,7 @@ error_code cellPadGetData(u32 port_no, vm::ptr<CellPadData> 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.get_ptr());
return CELL_OK;
@@ -504,7 +504,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);
@@ -539,7 +539,7 @@ error_code cellPadGetRawData(u32 port_no, vm::ptr<CellPadData> 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);
// ?
@@ -605,7 +605,7 @@ error_code cellPadSetActDirect(u32 port_no, vm::ptr<CellPadActParam> param)
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))
@@ -753,7 +753,7 @@ error_code cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellPadCapabilityInfo>
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));
@@ -811,7 +811,7 @@ error_code cellPadInfoPressMode(u32 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);
}
@@ -840,7 +840,7 @@ error_code cellPadInfoSensorMode(u32 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);
}
+1 -1
View File
@@ -42,7 +42,7 @@ bool check_config(vm::cptr<CellPngEncConfig> config)
if (!config ||
config->maxWidth == 0u || config->maxWidth > 1000000u ||
config->maxHeight == 0u || config->maxHeight > 1000000u ||
config->maxBitDepth != 8u && config->maxBitDepth != 16u ||
(config->maxBitDepth != 8u && config->maxBitDepth != 16u) ||
static_cast<s32>(config->addMemSize) < 0 ||
config->exParamNum != 0u)
{
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,
+19 -15
View File
@@ -7,9 +7,6 @@
#include "Emu/Cell/lv2/sys_memory.h"
#include "Emu/Cell/lv2/sys_ss.h"
//#include <iomanip>
//#include <sstream>
LOG_CHANNEL(cellRtc);
// clang-format off
@@ -43,16 +40,16 @@ void fmt_class_string<CellRtcError>::format(std::string& out, u64 arg)
// Grabbed from JPCSP
// This is the # of microseconds between January 1, 0001 and January 1, 1970.
const u64 RTC_MAGIC_OFFSET = 62135596800000000ULL;
constexpr u64 RTC_MAGIC_OFFSET = 62135596800000000ULL;
// This is the # of microseconds between January 1, 0001 and January 1, 1601 (for Win32 FILETIME.)
const u64 RTC_FILETIME_OFFSET = 50491123200000000ULL;
constexpr u64 RTC_FILETIME_OFFSET = 50491123200000000ULL;
const u64 EPOCH_AS_FILETIME = 116444736000000000ULL;
constexpr u64 EPOCH_AS_FILETIME = 116444736000000000ULL;
// Also stores leap year
const u8 DAYS_IN_MONTH[24] = {0x1F, 0x1C, 0x1F, 0x1E, 0x1F, 0x1E, 0x1F, 0x1F, 0x1E, 0x1F, 0x1E, 0x1F, 0x1F, 0x1D, 0x1F, 0x1E, 0x1F, 0x1E, 0x1F, 0x1F, 0x1E, 0x1F, 0x1E, 0x1F};
const char WEEKDAY_NAMES[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; // 4 as terminator
const char MONTH_NAMES[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; // 4 as terminator
constexpr u8 DAYS_IN_MONTH[24] = {0x1F, 0x1C, 0x1F, 0x1E, 0x1F, 0x1E, 0x1F, 0x1F, 0x1E, 0x1F, 0x1E, 0x1F, 0x1F, 0x1D, 0x1F, 0x1E, 0x1F, 0x1E, 0x1F, 0x1F, 0x1E, 0x1F, 0x1E, 0x1F};
constexpr char WEEKDAY_NAMES[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; // 4 as terminator
constexpr char MONTH_NAMES[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; // 4 as terminator
s64 convertToUNIXTime(u16 seconds, u16 minutes, u16 hours, u16 days, s32 years)
{
@@ -122,7 +119,7 @@ error_code cellRtcGetCurrentTick(vm::ptr<CellRtcTick> pTick)
error_code cellRtcGetCurrentClock(vm::ptr<CellRtcDateTime> pClock, s32 iTimeZone)
{
cellRtc.todo("cellRtcGetCurrentClock(pClock=*0x%x, time_zone=%d)", pClock, iTimeZone);
cellRtc.todo("cellRtcGetCurrentClock(pClock=*0x%x, iTimeZone=%d)", pClock, iTimeZone);
if (!vm::check_addr(pClock.addr()))
{
@@ -1131,6 +1128,13 @@ error_code cellRtcGetCurrentSecureTick(vm::ptr<CellRtcTick> tick)
{
cellRtc.todo("cellRtcGetCurrentSecureTick(*0x%x)", tick);
if (!vm::check_addr(tick.addr()))
{
return CELL_RTC_ERROR_INVALID_POINTER;
}
// TODO
return CELL_OK;
}
@@ -1445,7 +1449,7 @@ error_code cellRtcIsLeapYear(s32 year)
{
cellRtc.todo("cellRtcIsLeapYear(year=%d)", year);
if (year < 0)
if (year < 1)
{
return CELL_RTC_ERROR_INVALID_ARG;
}
@@ -1457,7 +1461,7 @@ error_code cellRtcGetDaysInMonth(s32 year, s32 month)
{
cellRtc.todo("cellRtcGetDaysInMonth(year=%d, month=%d)", year, month);
if ((year < 0) || (month <= 0) || (month > 12))
if ((year <= 0) || (month <= 0) || (month > 12))
{
return CELL_RTC_ERROR_INVALID_ARG;
}
@@ -1474,10 +1478,10 @@ error_code cellRtcGetDayOfWeek(s32 year, s32 month, s32 day)
{
cellRtc.trace("cellRtcGetDayOfWeek(year=%d, month=%d, day=%d)", year, month, day);
if (month - 1 < 2)
if (month == 1 || month == 2)
{
year -= 1;
month += 0xc;
year--;
month += 12;
}
return not_an_error(((month * 0xd + 8) / 5 + ((year + (year >> 2) + (year < 0 && (year & 3U) != 0)) - year / 100) + year / 400 + day) % 7);
+7 -7
View File
@@ -29,13 +29,13 @@ struct CellRtcTick
struct CellRtcDateTime
{
be_t<u16> year;
be_t<u16> month;
be_t<u16> day;
be_t<u16> hour;
be_t<u16> minute;
be_t<u16> second;
be_t<u32> microsecond;
be_t<u16> year; // 1 to 9999
be_t<u16> month; // 1 to 12
be_t<u16> day; // 1 to 31
be_t<u16> hour; // 0 to 23
be_t<u16> minute; // 0 to 59
be_t<u16> second; // 0 to 59
be_t<u32> microsecond; // 0 to 999999
};
error_code cellRtcTickAddYears(vm::ptr<CellRtcTick> pTick0, vm::cptr<CellRtcTick> pTick1, s32 iAdd);
+6 -6
View File
@@ -148,7 +148,7 @@ int check_filename(std::string_view file_path, bool disallow_system_files, bool
return 70;
}
char name[CELL_SAVEDATA_FILENAME_SIZE - 3];
char name[CELL_SAVEDATA_FILENAME_SIZE + 3];
if (dotpos)
{
@@ -228,7 +228,7 @@ static std::vector<SaveDataEntry> get_save_entries(const std::string& base_dir,
}
// PSF parameters
const psf::registry psf = psf::load_object(fs::file(base_dir + entry.name + "/PARAM.SFO"));
const psf::registry psf = psf::load_object(base_dir + entry.name + "/PARAM.SFO");
if (psf.empty())
{
@@ -755,7 +755,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
listGet->dirListNum++; // number of directories in list
// PSF parameters
const psf::registry psf = psf::load_object(fs::file(base_dir + entry.name + "/PARAM.SFO"));
const psf::registry psf = psf::load_object(base_dir + entry.name + "/PARAM.SFO");
if (psf.empty())
{
@@ -1372,7 +1372,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
const std::string old_path = base_dir + ".backup_" + save_entry.escaped + "/";
const std::string new_path = base_dir + ".working_" + save_entry.escaped + "/";
psf::registry psf = psf::load_object(fs::file(dir_path + "PARAM.SFO"));
psf::registry psf = psf::load_object(dir_path + "PARAM.SFO");
bool has_modified = false;
bool recreated = false;
@@ -1830,7 +1830,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
if (file == all_files.cend() || file->second.size() <= fileSet->fileOffset)
{
cellSaveData.error("Failed to open file %s%s", dir_path, file_path);
cellSaveData.error("Failed to open file %s%s (size=%d, fileOffset=%d)", dir_path, file_path, file->second.size(), fileSet->fileOffset);
savedata_result = CELL_SAVEDATA_ERROR_FAILURE;
break;
}
@@ -2070,7 +2070,7 @@ static NEVER_INLINE error_code savedata_get_list_item(vm::cptr<char> dirName, vm
return CELL_SAVEDATA_ERROR_NODATA;
}
const psf::registry psf = psf::load_object(fs::file(sfo));
const psf::registry psf = psf::load_object(sfo);
if (sysFileParam)
{

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