Compare commits

..

422 Commits

Author SHA1 Message Date
AniLeo c5511200d5 rpcs3_version: Bump to 0.0.39 2025-12-31 23:53:44 +01:00
Florin9doi 51fd4b2f76 USB: Added support for G27 compatibility modes
- Driving Force EX
- Driving Force Pro
- Driving Force GT
- G25
2025-12-31 21:25:37 +00:00
Niram7777 2f94891c23 Build Freebsd update LLVM dev (22)
Fix the CI by using the correct compiler version
https://wiki.freebsd.org/HardcodedCCVersions
2025-12-31 20:17:40 +00:00
Antonino Di Guardo f535c82a3f Improve Utilities and Log menus (#17944) 2025-12-31 16:44:11 +01:00
digant73 d929596b0f improve menus 2025-12-30 14:48:09 +01:00
Megamouse 4feb876b7f cellPhotoImport: Try to create unique filenames 2025-12-30 10:26:13 +01:00
Megamouse 953e31cbe8 Adjust media list dialog for larger folder depth
Use shared_ptr to fix crashes when navigating deeper folders
2025-12-30 10:26:13 +01:00
Megamouse 953f9f7e01 cellPhotoExport: Use roughly same path as cellScreenShot 2025-12-30 10:26:13 +01:00
Megamouse d85b9d0cd1 cellScreenshot: escape photo_title in path 2025-12-30 10:26:13 +01:00
Megamouse 9810d24ebb cellScreenshot: update filenames 2025-12-30 10:26:13 +01:00
RipleyTom 65273dde76 Remove call to glxewInit 2025-12-29 15:29:34 +02:00
Ninetime 2579ddf996 RPCN menu changes (#17936)
- Adds a shortcut for RPCN to the toolbar

- Adds a link for the Network tab to the Configuration menu
2025-12-29 07:12:21 +02:00
Megamouse 01fe12483f Qt: remove unused NotifyBatchedGameActionFinished signal 2025-12-27 22:00:12 +01:00
Megamouse bba1cf4b6e Qt: ask user for install options before starting the installation 2025-12-27 22:00:12 +01:00
Megamouse 92f56215d0 Qt: Allow user to precompile caches on demand when installing packages or adding disc games 2025-12-27 22:00:12 +01:00
kd-11 f5be489d9f rsx: Improve framebuffer layout change detection 2025-12-27 22:54:27 +03:00
kd-11 316aa44d3e vk: Fix crash when shuffling between cyclic and non-cyclic Z-buffer in one logical pass 2025-12-27 22:54:27 +03:00
kd-11 e586986845 rsx/gl: Clear cyclic Z barrier flag
- OpenGL doesn't care about this but we clear it anyway to indicate it is no longer pending.
2025-12-27 22:54:27 +03:00
kd-11 ba673d1407 rsx/vk: Add post-cyclic-z barriers allowing us to keep early Z optimizations 2025-12-27 22:54:27 +03:00
kd-11 fd3ecea21e rsx: Improve early-Z disablement mechanism 2025-12-27 22:54:27 +03:00
kd-11 5a809c5f72 rsx/fp: Stop using m_ctrl and use the correct object from m_prog 2025-12-27 22:54:27 +03:00
kd-11 441e7e0485 rsx: Disable early-Z optimizations if a loopback on the depth texture is active
- The optimizations worked a bit too well and allowed early-Z to kick in.
- Early Z inverts the logic making reads happen after writes and breaking loopback sampling.
2025-12-27 22:54:27 +03:00
kd-11 5baf8aeb22 vk/fp: Only emit alpha-testing variables when required 2025-12-27 22:54:27 +03:00
kd-11 bd1a25698c rsx: Fix alpha testing
- We no longer reload fragment state when toggling alpha-test. Instead, a different shader variant is picked.
2025-12-27 22:54:27 +03:00
kd-11 307dac479c rsx: Fix texcoord clamp regression 2025-12-27 22:54:27 +03:00
kd-11 0e9c877b83 rsx: Drop pointless ROP control bit check 2025-12-27 22:54:27 +03:00
kd-11 6e0b5a874d rxs: Improve alpha-to-coverage emulation 2025-12-27 22:54:27 +03:00
kd-11 da21b10144 rsx: Propagate state changes to trigger permutation lookup
- Alpha test
- MSAA (for CSAA enable flag)
- Polygon stipple
2025-12-27 22:54:27 +03:00
kd-11 69cdded5ba rsx: Fix sRGB control flag propagation to shader control
- Also clean up the texturing code and fix some memcpy overflow bugs.
2025-12-27 22:54:27 +03:00
kd-11 8030b01064 rsx: Propagate shader kill flag and refactor texture flags processing a bit 2025-12-27 22:54:27 +03:00
kd-11 1a733353de rsx: Fix MSAA sampling operations 2025-12-27 22:54:27 +03:00
kd-11 20dcfa5c8a rsx: Move heavy codegen capabilities to permutation flags from runtime checks 2025-12-27 22:54:27 +03:00
kd-11 3cb3f6972e vk: Hoist texture param loads 2025-12-27 22:54:27 +03:00
kd-11 215880cd1a rsx/vk/gl: Make texture parameter reads backend-dependent
- Allows optimizations and improvements per-backend
2025-12-27 22:54:27 +03:00
kd-11 308adca206 rsx/fp: Stop referencing wpos when the value is just getting discarded. 2025-12-27 22:54:27 +03:00
kd-11 5e4c2433c1 vk/gl: Mark unused FP outputs as unused 2025-12-27 22:54:27 +03:00
Florin9doi 0536ad3b23 USB: Fix an incorrect log 2025-12-27 20:40:28 +01:00
Florin9doi bdcde24e28 USB: Remove a duplicate PSP entry 2025-12-27 20:40:28 +01:00
Florin9doi 80d7db520b USB: Remove unused method 2025-12-27 20:40:28 +01:00
Florin9doi eafe0f76cf USB: Update Kamen Rider Summonride virtual portal
- Increase ack time for interrupt packets
- Add missing HID Descriptor Node
2025-12-27 20:40:28 +01:00
Florin9doi ce0a6da88e Docs: Update clone instructions 2025-12-27 20:40:28 +01:00
Megamouse fdbf25076e Fix lld warning LNK4286 2025-12-27 20:04:43 +01:00
oltolm 0ce686b1f1 fix lld warning LNK4217 2025-12-27 18:40:01 +01:00
Antonino Di Guardo 908c616783 Improve Manage menu (#17919) 2025-12-27 17:54:03 +01:00
Megamouse 739c178aac Qt/cheats: don't accept imported cheats unless valid 2025-12-27 17:18:44 +01:00
schm1dtmac 77aa5d4bbf [macOS] Don’t compile in GL-related code or link GLEW
This seems sensible enough since macOS’s archaic, deprecated OpenGL
implementation isn’t supported by RPCS3 anyways. Also fixes some CI
fails caused by GLEW as a consequence.
2025-12-24 21:21:57 +02:00
RipleyTom 847a147002 Improve usb timing accuracy 2025-12-24 04:44:47 +02:00
RipleyTom df6a3d01df Clean UsbTransfer state 2025-12-24 04:44:47 +02:00
Megamouse f81a5a5cb1 sceNpClans: cleanup 2025-12-23 13:26:34 +01:00
Megamouse 2fb697322f overlays: log font lookup info on exception (#17903)
- Logs the font lookup dirs and the target fonts when no font was found
in the native overlay
2025-12-21 14:00:36 +01:00
zeph 73bcabf7d5 Clans: fix graphical bug displaying JID instead of username (#17906)
This PR fixes a visual bug with the Clans system, incorrectly converting
the `jid` to a user's NPID, instead of using their username.

Variable names should now be a bit clearer and avoid similar issues in
the future.

---------

Signed-off-by: zeph <zephyrzefa15@gmail.com>
2025-12-21 13:11:33 +01:00
schm1dtmac 3819b9d57e [macOS] Force max pthread priority, fix throttling 2025-12-21 07:18:43 +02:00
zeph f946054a37 Clans: Emulator and server implementation (#17835)
This PR implements the Sony Clans subsystem for the RPCS3 emulator.

Used in:
- PlayStation Home [NPIA00005]
- ?

Addresses and closes
[#16464](https://github.com/RPCS3/rpcs3/issues/16464).

---

The source code for the server is available
[here](https://github.com/ZephyrCodesStuff/clans-rs) and is licensed
AGPLv3.
- It's written in Rust, with my best efforts in readability and
documentation.
- Every feature not-pertaining to RPCS3 has been feature-gated at
compile-time.
- Fully Dockerized deployment
- Ticket signature verification

NOTE: The server is fully compatible with the PS3 console as well, as it
follows the PS3 Clans Library specification.

---

The emulator code tries its best to follow on the steps of the RPCN
client code wherever possible; both in the Client as well as the
Settings and Config components.

Features:

- Clans client implementation in `clans_client.[h,cpp]`
- Syscalls implementation in `sceNpClans.[h,cpp]`
- A couple of missing structs and/or enum members have been added in
`sceNp.h`
- Qt GUI for selecting the desired Clans server to use (default: [HTTPS]
`clans.rpcs3.net`)
  - Implemented in `clans_settings_dialog.[h,cpp]`
  - Prevents modifying during emulator usage
- `clans.yml` config file for persistence
  - Implemented in `clans_config.[h,cpp]`

---------

Signed-off-by: zeph <35661622+ZephyrCodesStuff@users.noreply.github.com>
Signed-off-by: zeph <zephyrzefa15@gmail.com>
2025-12-20 16:43:17 +01:00
schm1dtmac 6546cf9e3a [macOS] General cleanup/fixups 2025-12-20 07:35:36 +01:00
Niram7777 cbecb91b94 Build 3rdparty/soundtouch include as system 2025-12-19 13:40:04 +00:00
Niram7777 8c9d266284 Build LLVM wrap getFirstNonPHI by version 2025-12-19 13:40:04 +00:00
Niram7777 a65eb3eb30 Build LLVM wrap getDeclaration by version 2025-12-19 13:40:04 +00:00
Marin Baron c9725b79fc Build 3rdparty include as system 2025-12-19 13:40:04 +00:00
Marin Baron 78690282eb Build LLVM some API dont support iterator so use pointer 2025-12-19 13:40:04 +00:00
Marin Baron 46db5c35eb Build LLVM deprecated getFirstNonPHI 2025-12-19 13:40:04 +00:00
Marin Baron 752155d5dd Build LLVM-22 fix removed getDeclaration 2025-12-19 13:40:04 +00:00
RipleyTom 371af2d94f Refuse to abort sceNp2 requests that change state 2025-12-19 12:06:02 +01:00
RipleyTom b99bd12d5e Add Extra sceNp2 logging 2025-12-19 12:06:02 +01:00
schm1dtmac 5507078bd8 [macOS] Use native os_sync calls for futexes 2025-12-17 21:21:59 +02:00
Elad ddfa773675 sys_fs: Optimize split files handling 2025-12-17 12:39:37 +02:00
Ani 36af9f54d3 Revert "SPU/config: Make SPU LLVM Mega block size default"
This reverts commit 4a042ae84f.
2025-12-17 07:03:15 +00:00
schm1dtmac 1147f47a8a Switch macOS atomics to futexes, bump min ver to 14.4
Co-authored-by: elad335 <18193363+elad335@users.noreply.github.com>
2025-12-17 00:38:38 +00:00
kd-11 03a91aa052 rsx/cfg: Increase valid register file size to 768 bytes per pixel pipe 2025-12-17 00:05:22 +00:00
Elad e0cdafddb5 SPU Analyzer: Fix missing jump table entries in Mega mode 2025-12-16 23:20:37 +00:00
schm1dtmac 4c7d19fc69 [macOS] Update to MVK 1.4.1 with private API support (fixes panics, improves feature support) 2025-12-16 22:50:40 +00:00
Ani 061fb5d112 Revert "Fix hypervisor context memory placement"
This reverts commit b1089ab1a3.
2025-12-16 21:54:21 +00:00
kd-11 b1089ab1a3 Fix hypervisor context memory placement 2025-12-16 16:31:56 +02:00
Elad 812d84e7f4 Util/sync.h: Fix iterator invalidation in futex emulation 2025-12-16 13:08:58 +02:00
Elad 103d580d9a Fixup futex emulation
std::unordered_multimap::find may return any matching element.. unlike equal_range. (code relied on matching the first)
There was also UB there of reference to an element after it has deleted.
2025-12-16 10:41:21 +02:00
Elad de8552048f PPU: Prevent repeated notifications 2025-12-16 10:41:21 +02:00
Elad 65cd4deb77 Prevent atomic cache line collisions 2025-12-16 10:41:21 +02:00
Elad 16e41f4492 Fix compilation with older Qt versions 2025-12-16 10:41:21 +02:00
RipleyTom 711ec69e48 Fix RPCN replies ordering 2025-12-16 10:07:03 +02:00
Megamouse cf87f24587 cellGem: improve bayer demosaicing 2025-12-15 14:20:34 +01:00
Megamouse 12a3818fcf Fix logging of gem configs 2025-12-15 14:20:34 +01:00
kd-11 d9da5f26c0 vk: Ignore memory pressure handling when allocating data heaps into ReBAR memory. 2025-12-15 11:53:47 +00:00
kd-11 1a3e150a62 vk: Extend memory allocation system to explicitly allow requesting no VRAM recovery on allocation fail. 2025-12-15 11:53:47 +00:00
Megamouse c3db85c68e cellGem: Fix YUV conversions, implement gain, averaging and basic outlier detection 2025-12-13 12:43:22 +01:00
kd-11 2b0456520e rsx/cfg: Fix edge case where an empty block is defined 2025-12-13 13:50:39 +03:00
Megamouse 0c455d12c9 Fix int -> float conversion warning 2025-12-13 03:55:44 +01:00
Megamouse 236f783466 overlays fix c++23 elifndef
This is a c++23 feature...
2025-12-13 03:55:44 +01:00
Megamouse f739ce7323 cellGem: Implement CELL_CAMERA_RAW8 to CELL_GEM_BAYER_RESTORED_RASTERIZED 2025-12-12 10:31:26 +01:00
Megamouse 3c0558c822 cellGem: Implement CELL_CAMERA_RAW8 to CELL_GEM_BAYER_RESTORED_RGGB 2025-12-12 10:31:26 +01:00
Megamouse c38146636a Update fusion to 1.2.11 2025-12-12 10:31:26 +01:00
Megamouse 26b0f822d8 ps_move_handler: enable orientation by default 2025-12-12 10:31:26 +01:00
Megamouse ee9dc44059 ps_move_handler: fix decoding of ZCM1 sensor values 2025-12-12 10:31:26 +01:00
Megamouse 24745416c5 cellGem: fix compilation 2025-12-12 10:31:26 +01:00
Megamouse fa4e2d1b42 ps_move_handler: fix trigger values depending on ps move version 2025-12-12 10:31:26 +01:00
Megamouse c2284c962b move ps_move_data to own file 2025-12-12 10:31:26 +01:00
Megamouse 757e9a0493 cellGem: implement world coordinate orientation in cellGemGetState 2025-12-12 10:31:26 +01:00
Megamouse f7cda4b2b4 cellGem: fix default orientation 2025-12-12 10:31:26 +01:00
Megamouse c6ef09500a cellGem: fix division by zero 2025-12-12 10:31:26 +01:00
Megamouse 26ae6f0902 cellGem: fix default accelerometer value 2025-12-12 10:31:26 +01:00
Megamouse 1b01a9274c cellGem: clarify member descriptions 2025-12-12 10:31:26 +01:00
kd-11 0f1eadcab0 rsx/gtest: Drop unused function 2025-12-10 13:07:07 +03:00
kd-11 1ea3c121fa rsx/cfg: Fix delay-slot detection when copying from the same register index but different precision. 2025-12-10 13:07:07 +03:00
kd-11 2c6d3dde67 C++ Pro
- Different from C++ amateur.
- Addresses code review suggestions to step up the C++
2025-12-10 13:07:07 +03:00
kd-11 a412e34fa6 rsx/cfg/fp: Fix back-traversal for IF-ELSE pairs 2025-12-10 13:07:07 +03:00
kd-11 4dc52fde82 rsx/common: Implement list insert for simple_array 2025-12-10 13:07:07 +03:00
kd-11 5688573b3d rsx/fp: Fix pre-branch epilogue emit 2025-12-10 13:07:07 +03:00
kd-11 98a12de256 rsx/gtest: Enable unit tests for nix builds 2025-12-10 13:07:07 +03:00
kd-11 43d8518faa rsx/fp: Warning cleanup 2025-12-10 13:07:07 +03:00
kd-11 1e6fe1f4ab rsx/cfg/fp: Add delay-slot detection to remove unnecessary barriers
- Reduces emitted barriers by like 99%
2025-12-10 13:07:07 +03:00
kd-11 93f89b8a74 rsx/cfg: Fix instruction injection when more than one barrier is needed for a single instruction 2025-12-10 13:07:07 +03:00
kd-11 8cd241ca10 rsx/fp: Implement OR16_LO and OR16_HI instructions 2025-12-10 13:07:07 +03:00
kd-11 8d2f7ae85f rsx/cfg: Implement partial barriers for 32-bit register channels 2025-12-10 13:07:07 +03:00
kd-11 81d657a960 rsx/cfg: Fix grouping barrier16 instructions when lane is shared. 2025-12-10 13:07:07 +03:00
kd-11 4183d09a52 rsx/fp/cfg: Fix input mask for DIV and DIVSQ instructions 2025-12-10 13:07:07 +03:00
kd-11 316e01995b rsx/fp: Re-implement ROP output resolve 2025-12-10 13:07:07 +03:00
kd-11 f2913e4692 rsx/fp: Reimplement GLSL code generation from CFG 2025-12-10 13:07:07 +03:00
kd-11 d23ea4760b rsx/cfg: Handle nested IF/LOOP blocks falling out to unsuitable nodes (ELSE).
- In that case, find the node's END node and link to that instead. ELSE nodes are not reachable from children of the preceding IF.
- ELSE nodes are special this way, all other types of nodes are reachable by adjacency.
2025-12-10 13:07:07 +03:00
kd-11 26fd0510ab rsx/fp: Enable CFG passes and emit block epilogues 2025-12-10 13:07:07 +03:00
kd-11 e8e2d4b93d rsx/fp: Fix issues with FP decompiler using new CFG system 2025-12-10 13:07:07 +03:00
kd-11 a7f5514913 rsx/cfg: Fix dependency injection tests for FP 2025-12-10 13:07:07 +03:00
kd-11 3bed46b844 rsx/fp/cfg: Fix IF/ELSE and LOOP node linkage 2025-12-10 13:07:07 +03:00
kd-11 e1ec2f58bb rsx/fp/asm: Fix ELSE encoding 2025-12-10 13:07:07 +03:00
kd-11 91e19652de rsx/cfg/gtest: Rewrite CFG tests using the assembler
- Also extend IF-ELSE test to catch a broken succession chain
2025-12-10 13:07:07 +03:00
kd-11 b244c0fa0f rsx/cfg/gtest: Update unit tests 2025-12-10 13:07:07 +03:00
kd-11 f4ba548748 rsx/fp/asm: Implement asm support for branches
- Allows creating more complex command sequences from text
2025-12-10 13:07:07 +03:00
kd-11 856eaac1b6 rsx/cfg: Implement dependency injection pass with branches 2025-12-10 13:07:07 +03:00
kd-11 8ff3dda5e8 rsx/cfg: Skip literal constants when annotating instructions 2025-12-10 13:07:07 +03:00
kd-11 fa40cef0b1 rsx/fp/cfg: Insert bi-directional edges correctly during traversal 2025-12-10 13:07:07 +03:00
kd-11 65b4bcb027 rsx/fp/asm: Add support for more instructions 2025-12-10 13:07:07 +03:00
kd-11 5a8ad219ba rsx/asm: Implement dependency barrier injection pass 2025-12-10 13:07:07 +03:00
kd-11 ed397c5d67 rsx/asm: Add support for more opcodes and add tests for mixed block IO 2025-12-10 13:07:07 +03:00
kd-11 13d66f324b rsx/shaders: Fix nix builds 2025-12-10 13:07:07 +03:00
kd-11 aaaa6feb5a rsx: Add UTs for register annotation pass and fix uncovered bugs 2025-12-10 13:07:07 +03:00
kd-11 88a54e2d98 rsx/fp: Add a basic assembler to aid in test authoring 2025-12-10 13:07:07 +03:00
kd-11 9d30716aa8 rsx: Implement register annotation pass 2025-12-10 13:07:07 +03:00
kd-11 e20bae3cd7 rsx/asm: Stub out register annotation and dependency passes 2025-12-10 13:07:07 +03:00
Megamouse aff645272f overlays/macOs: add some fallback fonts for cyrillic 2025-12-09 12:52:51 +01:00
Megamouse 27f39d2ac0 fmt: add more string_view versions of string functions 2025-12-08 19:49:42 +01:00
oltolm c840c98e9e bit_set.h: forward declare fmt_unveil
This change is necessary to fix the following clangd error in `StrFmt.h`

Redefinition of 'fmt_unveil'clang(redefinition)
bit_set.h(388, 8): Previous definition is here
2025-12-08 12:43:15 +02:00
RipleyTom adcacc1119 Remove RPCN test server 2025-12-08 09:16:52 +01:00
RipleyTom 65458effa6 RPCN v1.5.0 2025-12-08 09:16:52 +01:00
Antonino Di Guardo 0f1d516d9a Check available and required size when installing a package (#17829)
Show and check available and required size when installing a package.
Installation is not allowed, by disabling `Yes` and/or `Install` button,
if not enough disk space is detected.
On multi installation dialog box, installation size for each package is
reported in the list.

fixes #14440

</br>
</br>

### Single PKG installation - Not enough space available

![pr_single_no_space](https://github.com/user-attachments/assets/3fc83d3e-8219-4dca-a4ae-a351f3c4c662)

</br>
</br>

### Single PKG installation - Required space available

![pr_single_space](https://github.com/user-attachments/assets/84b6b4a0-ee4a-430e-b84f-60a754e0a4fa)

</br>
</br>

### Multi PKG installation - Not enough space available

![pr_no_space](https://github.com/user-attachments/assets/56af51a1-cd78-4ad5-818d-7707c0c45de4)

</br>
</br>

### Multi PKG installation - Required space available

![pr_space](https://github.com/user-attachments/assets/43cc66dd-7e98-46de-8dd3-859f8ebb2b05)

---------

Co-authored-by: Megamouse <studienricky89@googlemail.com>
2025-12-07 14:38:13 +01:00
oltolm 3f6529fecb UI: remove unnecessary QOverloads 2025-12-06 20:58:28 +01:00
schm1dtmac b76ca8807f (macOS) Support loading VK ICDs (in preparation for KosmicKrisp) 2025-12-06 19:21:54 +03:00
schm1dtmac 54206c62b3 Add OpenCV to macOS builds 2025-12-05 22:48:40 +01:00
Elad 67f7119717 Make RSX FIFO Atomic fetching default (#17810) 2025-12-04 18:17:39 +02:00
Megamouse 133b19f205 Update Qt for macOs to 6.10.1 2025-12-03 22:54:59 +01:00
Megamouse fce393024a Update Qt for macOs to 6.9.3 2025-12-03 22:54:59 +01:00
Megamouse 7d3cf831d5 Qt/macOS: Fix GUI freezes on Qt 6.8+ 2025-12-03 22:54:59 +01:00
Megamouse dc27047ed4 Qt: fix game list refresh order when changing the language 2025-12-03 21:17:46 +01:00
Megamouse b9a9c1af07 Qt: revert setting UserRole. this doesn't seem to have been the culprit for multiselection 2025-12-03 21:17:46 +01:00
Megamouse e3f5f2d14e cellPad: fix pad mode setters 2025-12-03 18:23:12 +02:00
Megamouse ff9401303b hidapi: switch to official libusb remote 2025-12-03 15:50:25 +01:00
kd-11 2a6f1cf35c rsx/common - work around macos posix_memalign quirks 2025-12-03 13:57:59 +03:00
Megamouse b86b4d15c6 Update SDL to 3.2.28 2025-12-03 09:33:51 +01:00
Megamouse 23ffa4ccdb Update FAudio to 25.12 2025-12-03 09:33:51 +01:00
Megamouse cbba687ffa Qt: Relax game_list deselection checks 2025-12-03 02:16:30 +01:00
Megamouse 613d428ced Qt: fix update note visiblity on linux/macOs 2025-12-03 01:12:00 +01:00
Ani 6489fca16b YoRHa: Fix the height of QSpinBox 2025-12-02 21:14:11 +00:00
Megamouse 3c747b377f Qt: fix translation of update dialog if the language was changed between downloading the json and clicking on update 2025-12-02 09:18:16 +01:00
Megamouse a859e14e19 Qt: update main window elements on language change 2025-12-02 09:18:16 +01:00
Megamouse 6dd37cb2d5 Qt: fix game list table multiselection
Apparently table items need one common role set for internal indexing.
2025-12-01 21:43:19 +01:00
Megamouse 7e8ed5ecc1 rsx: clear unused parameters on capture boot 2025-12-01 17:51:30 +01:00
Megamouse d396a778b7 rsx: fix capture path if title id is empty 2025-12-01 17:51:30 +01:00
Megamouse 25badf9534 Qt: Update header texts and actions when language changes 2025-12-01 14:49:04 +01:00
Megamouse 314b69c7d8 Qt: save spinbox values with fmt::format
This prevents saving localized strings with different decimal characters
2025-12-01 10:14:29 +01:00
Megamouse bc55f7787e Add notes for VS 2026 to BUILDING.md 2025-12-01 08:51:49 +01:00
Elad 4bda2f9b0f Test: Disable PUTLLC0 2025-11-30 18:31:50 +02:00
Elad d822d85ea1 SPU: Tame PUTLLC16 2025-11-30 18:31:50 +02:00
Elad 7001940483 SPU Analyzer: Be more strict with loads 2025-11-30 18:31:50 +02:00
Elad 3c5c74c496 SPU Cache debug 2025-11-30 18:31:50 +02:00
Megamouse c80aba2342 Update libpng to 1.6.51 2025-11-30 10:03:35 +00:00
Megamouse 84d5e42896 Update Qt to 6.10.1 2025-11-30 10:03:35 +00:00
Megamouse 53edd410c7 ppu: move alignment below llvm check 2025-11-30 09:23:36 +00:00
Megamouse 7f9cc357e8 Qt: Add sound effect manager 2025-11-30 09:23:36 +00:00
Megamouse e2cbbcf646 overlays: use enum for sound effects 2025-11-30 09:23:36 +00:00
Elad e938b93f48 SPU Analyzer: Ignore large switch state 2025-11-29 20:17:21 +02:00
Elad 4a042ae84f SPU/config: Make SPU LLVM Mega block size default 2025-11-29 18:24:01 +02:00
Elad c48ae344a8 SPU LLVM (Mega): Fix quarter of missing jumptable discoveries 2025-11-29 17:10:30 +02:00
Elad e09be04df6 Emu/UX: Automatic Cache Precompilation for PKG instal 2025-11-29 10:47:51 +02:00
Elad d625c1d004 SPU LLVM: Reduce notifications for PUTLLC16 2025-11-29 07:30:39 +02:00
Elad cae77784db UTs: Fix AlignedAllocator.Realloc test
_aligned_realloc may return the same pointer if the internal implementation finds it suitable. Fixes Windows' builds.
2025-11-29 07:30:39 +02:00
Elad 14bd6b0cc5 SPU: Enable PUTLLC16 by default
Experimental, may be reduced to specific patterns instead of being enabled globally.
2025-11-29 07:30:39 +02:00
Elad e11f8df064 PPU LLVM: Fixup PPU Profiler for PRX 2025-11-29 07:30:39 +02:00
Elad e2da6d36ba SPU LLVM: Permit relative-PC in PUTLLC16 with alignment check 2025-11-29 07:30:39 +02:00
Elad 27c2f2ae4d SPU Analyzer: Contnue with failed patterns until they proven failure 2025-11-29 07:30:39 +02:00
Elad 727f3dd7a1 SPU Analyzer: Try to detect no-return in BISL/BRSL 2025-11-29 07:30:39 +02:00
kd-11 7b560e5ffa rsx: Clean up aligned realloc implementation 2025-11-29 00:34:23 +03:00
rcaridade145 50c9a91942 rsx: Free previous pointer after reallocating memory
After realloc in simple_array free the memory referenced by the old pointer.
2025-11-28 21:54:45 +03:00
Elad d9f913016c Fix possible ambiguity of utils::bless (#17757)
Make utils::bless at util/bless.hpp argument type be complete, avoiding
possible ambiguity with RSX-utility version. A fix for Apple Clang
compiler.
2025-11-27 02:50:45 +02:00
kd-11 a442cb91a1 rsx/cfg: Check for end flag before handling any instruction including NOP 2025-11-27 02:53:34 +03:00
Elad 41aaa912e7 Fixup ::narrow (#17756)
Also fix negative signed to unsigned narrowing when source type is greater than destination.
2025-11-26 15:34:38 +02:00
Antonino Di Guardo 6ebdb0c0c1 Add an entry on Log panel's contextual menu to show the main disk usa… (#17715)
Added the entry `Show Disk Usage` on `Log` panel's contextual menu to
show the main disk usage of the emulator.
It reports VFS disk usage (with the exception of useless usb
directories) and cache disk usage.
I avoided to automatically display the disk usage, e.g. when refreshing
the game list, just because the disk usage calculation can require some
time (so it will slow down the emulator). So I opted to provide the
functionality on demand.
This PR is propaedeutic to pr6008. A separated PR to complete pr6008 will
follow. It will allow multiple selection of games on game list and a
contextual menu to manage the removal of the selected games.
2025-11-26 13:05:10 +02:00
Elad 914b52cf4a util/types.hpp: Fix signed/unsigned comparison error 2025-11-26 10:33:12 +02:00
kd-11 b451dfe877 vk: Fall back to host-visible pool if we cannot place resources in Re-BAR pool 2025-11-26 02:52:40 +03:00
kd-11 7986ee58de vk: Allow buffer creation to fail gracefully if placement is not possible 2025-11-26 02:52:40 +03:00
kd-11 5a9083e4fc rsx: Fix saw-tooth artifacts when using GPU deswizzle for small texel widths 2025-11-24 23:01:54 +03:00
kd-11 6a398f9947 rsx/cfg: Fix arm64 build 2025-11-24 16:48:03 +03:00
kd-11 8495a138c6 rsx/gtest: Fix unit tests build on GCC 2025-11-24 16:48:03 +03:00
kd-11 2c1d962bdc rsx/cfg: Replace 'avx512' intrinsics with SSE2-compatible ones
- These are just PAND and POR instruction wrappers for SSE2, no idea why they're classified as 'avx512'
2025-11-24 16:48:03 +03:00
kd-11 0fbd0e8cc7 rsx/gtest: Add tests for CFG BB succ edges and fix UT failures 2025-11-24 16:48:03 +03:00
kd-11 5c187f5cda rsx/fp: Use CFG to decompile fragment programs 2025-11-24 16:48:03 +03:00
kd-11 cb7650240c rsx/fp: Use CFG for fragment program 2025-11-24 16:48:03 +03:00
kd-11 9d92e190eb rsx/cfg: Add support for multi-slot instructions with literals
- Also fix pred edge direction bug
2025-11-24 16:48:03 +03:00
kd-11 42d9065c11 rsx: Add flow information to flow edges 2025-11-24 16:48:03 +03:00
kd-11 f300832edb rsx: Implement FP to CFG analyzer 2025-11-24 16:48:03 +03:00
kd-11 683baf46b2 rsx: Add find_if operation for simple_array<T> 2025-11-24 16:48:03 +03:00
Elad 89a13b75f7 SPU Analyzer: Fix jumptable append 2025-11-23 21:00:11 +02:00
Elad 7472d95b0c SPU Analyzer: Fix jumptable analysis for SPU Block Mega 2025-11-23 21:00:11 +02:00
Elad ecba1d2cb7 sys_fs: Remove PPU sleep hacks 2025-11-23 09:56:18 +02:00
oltolm fcff16b6f7 Fix Clang build and other small fixes (#17736)
1. I fixed the Clang build.
1. I removed what I think is an unnecessary `ptrtoint` in
`rpcs3/Emu/Cell/PPUTranslator.cpp`. I am not 100% sure that it's
correct, but I tested a small LLVM IR snippet and it didn't make a
difference. The ASM code was the same.
1. I also changed the definition of `prefetch_write` from `return
__builtin_prefetch(ptr, 1, 0);` to `return __builtin_prefetch(ptr, 1,
3);` because that's how `_m_prefetchw` is defined in GCC.
2025-11-23 07:11:36 +02:00
kd-11 a3f7c0d67f Fix typo 2025-11-22 12:35:22 +02:00
kd-11 98ca15699b Fix windows clang builds 2025-11-22 12:35:22 +02:00
kd-11 dec6fba68d gl: Use 16-byte alignment on staging buffers 2025-11-22 12:35:22 +02:00
kd-11 e1eb7421fb rsx: Enforce natural data alignment for IO buffers span cast 2025-11-22 12:35:22 +02:00
kd-11 ea7183b6bd test: Add unit tests for simple array alignment 2025-11-22 12:35:22 +02:00
kd-11 d6a36f4b60 vk: Fix build using new simple_array guard-rails 2025-11-22 12:35:22 +02:00
kd-11 6e11978638 rsx: Properly implement data alignment in simple_array<T> 2025-11-22 12:35:22 +02:00
kd-11 7f6842705c rsx: Rework GPU deswizzle kernel to prevent hangs 2025-11-22 01:49:31 +00:00
FeTetra 9deb6cd4fa Fix ppu_register_function_at with unaligned parameters (#17718)
This fixes some crashes in interpreter mode when calling functions like
`sys_dbg_write_process_memory` to write data which may not be an
instruction.

---------

Co-authored-by: Elad <18193363+elad335@users.noreply.github.com>
2025-11-21 16:07:47 +02:00
kd-11 e6d723c675 rsx: Fix 16-bit format hardware deswizzle 2025-11-21 11:52:35 +03:00
kd-11 400b4e71cf gl: Lower the GPU decoding requirements since each level is decoded separately 2025-11-21 11:52:35 +03:00
kd-11 3c3197d72d gl: Fix crashes when creating new context 2025-11-21 11:52:35 +03:00
kd-11 cffc13696d gl: Implement hardware deswizzle for small texel formats 2025-11-21 11:52:35 +03:00
kd-11 ff72f944ba rsx/vk: Add support for 8 and 16-bit texel GPU-accelerated deswizzle 2025-11-21 11:52:35 +03:00
kd-11 b067688c8e rsx: Drop meaningless log message
- This used to be a big deal a decade ago, now its just wasting CPU cycles and filling up log files
2025-11-21 11:52:35 +03:00
qurious-pixel 8ccc30725a Update install-freebsd.sh 2025-11-20 09:11:49 +02:00
qurious-pixel c38b8c6d12 restore [[noreturn]] 2025-11-20 09:11:49 +02:00
Elad 107d9dc533 PPU Profiler 2025-11-19 21:37:50 +02:00
Elad c669a0beb7 kernel_explorer: Order PPUs by priority 2025-11-17 21:32:58 +02:00
Elad f992ccdcad cellGam/celCamera: Add more wait flags 2025-11-17 21:32:58 +02:00
Elad e6dc0d98f5 SPU: Optimize check for args sharing page with Effective-Address 2025-11-17 21:32:58 +02:00
Elad 1250e428a7 SPU: Exclude reservation_check address receptacle from writer_lock 2025-11-17 21:32:58 +02:00
Elad ddecade935 vm/sys_memory: Remove VM locking in sys_memory_get_page_attribute 2025-11-17 21:32:58 +02:00
Megamouse de914247be overlays: remove unnecessary cast 2025-11-17 19:42:31 +01:00
Megamouse 6a51cd9f7f overlays: Use SCE-PS3-DH-R-CGB.TTF for chinese characters 2025-11-17 19:42:31 +01:00
Megamouse 2042b54d2d cmake: fix build with USE_FAUDIO if system SDL is not found 2025-11-17 19:42:31 +01:00
Megamouse 5267c87ca7 Overlays: check return value of stbtt_InitFont 2025-11-17 19:42:31 +01:00
Megamouse 6731feb751 overlays: add some more chinese fallback fonts 2025-11-17 19:42:31 +01:00
Megamouse 10f8a49e36 overlays: Check if a font actually contains the character 2025-11-17 19:42:31 +01:00
Megamouse a6371ef5d3 overlays: use get_font instead of duplicate font fallback 2025-11-17 19:42:31 +01:00
Megamouse 2d3e6c6d02 overlays: use std::string_view for font functions 2025-11-17 19:42:31 +01:00
Elad 9b1d39c14e SPU Analyzer: Fix spu_thread::is_exec_code for BRSL 2025-11-17 10:32:08 +02:00
Elad 5893851029 Core: Remove Intel-TSX ISA Extension based code 2025-11-17 10:32:08 +02:00
Megamouse 42177add17 Qt: fix image flip warning on newer Qt 2025-11-17 03:46:06 +02:00
Megamouse 84fdd2e056 rsx_debugger: fix gcc index access warning 2025-11-17 03:46:06 +02:00
Megamouse bc01863654 Fix some warnings 2025-11-17 03:46:06 +02:00
Megamouse cbb4dd8f22 Qt: forward declare gui_settings 2025-11-17 03:46:06 +02:00
oltolm 0439b62257 SPU Analyzer: use std::lexicographical_compare_three_way
It should compile now because we upgraded Linux CI.
2025-11-16 22:57:16 +02:00
oltolm a93197cdcb asm.hpp: replace custom functions with C++20 functions 2025-11-16 20:05:00 +02:00
oltolm b8031f4510 StrFmt.h: fix build with Clang 2025-11-16 20:05:00 +02:00
Elad db8437b01c Fix mask calculation in SPUThread.cpp 2025-11-16 12:12:20 +02:00
Elad 63f7bcf652 SPU: Use CMPXCHG16B for atomic store if possible 2025-11-16 12:12:20 +02:00
Elad 109abea454 sys_ppu_thread: Fix warning 2025-11-16 12:12:20 +02:00
Megamouse c7ae97f8ea Qt: add button to remove gamepad config 2025-11-16 01:19:43 +01:00
oltolm d61f4101ad utils: replace hex_to_u64 with std::from_chars 2025-11-15 21:33:29 +02:00
qurious-pixel ec70c9691f [Mac Arm64] Use runner ccache
Remove HomeBrew ccache in favor of Mac runner
2025-11-15 21:08:47 +03:00
Megamouse 18111ac8bc rsx: add simple pair and tuple types 2025-11-15 17:40:49 +02:00
Megamouse 5a761c7184 rsx: only allow trivially copyable types in simple_array 2025-11-15 17:40:49 +02:00
Megamouse 510ed00b11 rsx: fix some warnings 2025-11-15 17:40:49 +02:00
Megamouse fa06fed86f overlays: take screenshot after exiting the home menu 2025-11-15 14:55:09 +01:00
Megamouse 871dd729b2 cheats: fix cheat type on apply 2025-11-15 13:22:52 +01:00
Elad 7e209a7275 sys_spu: Improve arguments accuracy 2025-11-15 12:31:22 +02:00
Elad 0bb84b374e sys_ppu_thread: Fix u64 stack size argument 2025-11-15 12:31:22 +02:00
Elad 92e24a5779 PPU/x64: Fix gv_cvtu32_tofs 2025-11-14 21:15:27 +02:00
Elad e48ba283d8 Overlays/SaveStates: Add multi-slot support to controller menu 2025-11-12 15:57:53 +02:00
kd-11 0bf9ee9fa5 rsx: Fix an oops causing DEVICE_LOST
- We only apply scaling when RTTs are part of the input set.
- This fact was previously hidden by an optional arg
2025-11-11 01:04:31 +03:00
Elad c60e5cc48a ZSTD: Fixup threads terminations 2025-11-10 21:16:31 +02:00
Elad 642005cf1d Add wait flag in cellGemConvertVideoFinish 2025-11-10 21:16:31 +02:00
Elad b0956a8f74 More logging to sys_memory_allocate_from_container 2025-11-10 21:16:31 +02:00
Elad 2fb8cbda38 SaveStates/ZSTD: Improve termination and file handling 2025-11-10 13:04:43 +02:00
Elad c16278a5ab vm.cpp: Skip memory clearing on emulation stop 2025-11-10 13:04:43 +02:00
Elad bfe54a29ae Savestates/TAR: Extract files asynchronously 2025-11-10 13:04:43 +02:00
kd-11 265d6643e5 rsx: Fix shader interpreter 2025-11-09 17:29:22 +03:00
kd-11 d87f055bb2 vk: Fix hang when doing typeless copy in the resource assembler 2025-11-09 14:24:44 +03:00
kd-11 1af5afdaab vk: Reduce number of barriers for each copy transfer sequence
- Sometimes the same source image is copied more than once
2025-11-09 14:24:44 +03:00
kd-11 864bb9f0db rsx: Speed up slice gathering for large datasets
- We can cut down by an order of magnitude the amount of checks we do to construct objects
2025-11-09 14:24:44 +03:00
kd-11 1007aaee4c rsx: Refactor texture cache lookup core to be easier to read 2025-11-09 14:24:44 +03:00
Elad 8126a199f5 SPU: Fix race in PUTLLC with unchanged data 2025-11-08 16:20:18 +02:00
Joshua de Reeper b435deac9d sys_usbd: Small tidyups 2025-11-08 12:55:44 +02:00
shinra-electric 8a9b15dee3 Bump MoltenVK to v1.4.0 2025-11-07 22:26:41 +01:00
kd-11 c5a54a3d4f gl: Ensure overlays render in fill mode 2025-11-07 23:47:47 +03:00
kd-11 bcdf2ef36f gl: Implement polygon render modes 2025-11-07 23:47:47 +03:00
robotics13 3df0c8caef Synced Skylander variant IDs with values from Dolphin for #13315 2025-11-06 20:28:23 +01:00
FlexBy420 50eb46d294 download from releases instead 2025-11-05 23:30:17 +01:00
FlexBy420 ff922f6324 Update deploy-windows-clang.sh 2025-11-05 23:30:17 +01:00
FlexBy420 1e1da422ea Update deploy-windows-clang.sh 2025-11-05 23:30:17 +01:00
FlexBy420 3e5a035046 eh update macos-arm path again 2025-11-05 23:30:17 +01:00
FlexBy420 6e5338d091 update macos path again 2025-11-05 23:30:17 +01:00
FlexBy420 d73a7e0ff3 change translations location to a correct one (probably) 2025-11-05 23:30:17 +01:00
FlexBy420 a6c0433a2e forgot mkdir 2025-11-05 23:30:17 +01:00
FlexBy420 ca5a43a3ab macos support maybe? 2025-11-05 23:30:17 +01:00
FlexBy420 4710b38505 linux support 2025-11-05 23:30:17 +01:00
FlexBy420 9cde97c22b remove echo 2025-11-05 23:30:17 +01:00
FlexBy420 323f504138 comment 2025-11-05 23:30:17 +01:00
FlexBy420 d7df929ada Update deploy-windows.sh 2025-11-05 23:30:17 +01:00
Megamouse 2667d5de0f input: change default squircle value to 4000
The last squircle changes fixed a bug that caused the squircle to be too
large. This caused the previous default value of 8000 to be too circular
2025-11-05 22:39:34 +01:00
Megamouse 49548b913d rsx: fix some warnings 2025-11-05 21:56:26 +01:00
Megamouse 17c148d90e Update curl to 8.17.0 2025-11-05 21:56:26 +01:00
Megamouse 17621d2a5e Update FAudio to 25.11 2025-11-05 21:56:26 +01:00
kd-11 8984c2b316 rsx: Implement pixel_center_origin decorator for WPOS 2025-11-05 18:26:12 +03:00
kd-11 5d906e1da4 rsx: Whitespace fix 2025-11-05 18:26:12 +03:00
kd-11 dba48d6387 rsx: Invalidate surface cache slots that are trampled by buffer writes. 2025-11-05 18:26:12 +03:00
Joshua de Reeper 0403231a0d sys_usbd: fix id/type combo for Kamen Rider Display (#17662)
Fixes the display issues seen here:
https://github.com/RPCS3/rpcs3/issues/17653
2025-11-04 19:57:53 +01:00
Elad 8712414123 System.cpp: Check if the original EBOOT.BIN is valid for disc game updates 2025-11-03 12:04:11 +02:00
oltolm 2485a98d4f cmake: simplify code 2025-11-02 21:41:11 +00:00
Elad cc8929ef4a PSF.cpp: Fixup 2025-11-02 17:23:46 +02:00
Elad ede8382c6a Remove std::strcpy 2025-11-02 14:22:11 +02:00
Megamouse dc22584f72 input: always apply stick multiplier when no analog limiter button is set 2025-11-01 08:44:04 +01:00
Megamouse 7cb4a68043 Qt: fix type conversion warning 2025-10-31 19:55:03 +01:00
Megamouse ded91329bc Update SDL to 3.2.26 2025-10-31 19:55:03 +01:00
Joshua de Reeper 81f5be30aa sys_usbd: Emulate Kamen Rider Summonride Ride Gate (#17605)
This PR aims to implement another USB peripheral device, used in Kamen
Rider Summonride. Code is very similar to Skylanders (for the
loading/creating/removing of figures) and Disney Infinity for the actual
USB commands and responses (minus any of the built in random number
generation). I haven't been able to generate a full list of the Ride
Chips (see
[here](https://kamenrider.fandom.com/wiki/Kamen_Rider_Summonride#Characters)
for a list of Characters and Chips) besides the ones I have myself from
the Starter Set, so I am hoping that interested parties are able to play
around and discover what other chips there may be, or if there are any
issues when generating their own Characters and Chips.

Implements https://github.com/RPCS3/rpcs3/issues/17122
2025-10-31 18:17:51 +01:00
Elad ba2518f862 cellGame: Fix cellHddGameCheck dataVersion parameter 2025-10-30 21:34:54 +02:00
shinra-electric 3a6c71e523 Explicitly copy libunwind for x86 2025-10-29 14:53:53 +01:00
shinra-electric 8013129c5b Copy libc++abi to Frameworks instead of lib 2025-10-29 14:53:53 +01:00
shinra-electric 5ea92df4ca Cleaner export of LDFLAGS 2025-10-29 14:53:53 +01:00
shinra-electric afffd3061a Make hack for removing rpath failable 2025-10-29 14:53:53 +01:00
shinra-electric 8ea2109b37 Workaround for issues with Python and brew libc++ linkage on x86 2025-10-29 14:53:53 +01:00
shinra-electric fa8f35ea38 Bump llvm version from 19 to 21 2025-10-29 14:53:53 +01:00
Megamouse 50576d044b Qt: fix TSX warning style 2025-10-29 14:26:49 +01:00
Megamouse 3f797b2de3 VK: cache recording image 2025-10-28 22:04:01 +01:00
Megamouse 9124d08fdb GL: flip overlays vertically during recordings 2025-10-28 22:04:01 +01:00
Megamouse e4ae5bdce1 GL: only create new texture when necessary 2025-10-28 22:04:01 +01:00
Megamouse 5f37f2c8df VK: add memory barriers to copy_image 2025-10-28 22:04:01 +01:00
Megamouse 9dc66b46fc overlays: add record with overlays setting to settings dialog 2025-10-28 22:04:01 +01:00
Megamouse 0ca4f85dc7 overlays: add record with overlays setting to home menu 2025-10-28 22:04:01 +01:00
Megamouse 9c512849ef Vk: allow to record overlays 2025-10-28 22:04:01 +01:00
Megamouse 9550d5b67d GL: allow to record overlays 2025-10-28 22:04:01 +01:00
Megamouse dd40f49e5f Add new option for recording overlays 2025-10-28 22:04:01 +01:00
Megamouse 90fb81d1d9 Use move semantics for present_frame 2025-10-28 22:04:01 +01:00
Megamouse 3c401e7b3d Update fusion to 1.2.9 2025-10-26 09:20:32 +02:00
Megamouse dc53a3ba42 Update linux docker image to v.1.7 2025-10-26 09:20:32 +02:00
Live session user 3c1ebe9f4a [openal-soft] Fix malloc/free in fmtlib 2025-10-25 14:52:43 +03:00
kd-11 73c984a637 vk: Filter out re-bar usage from memory pressure watchdog 2025-10-24 12:51:03 +01:00
Elad ae30cb5557 SaveStates/SPU-LLVM: Fix SPU Access Violations on load 2025-10-23 19:00:42 +03:00
kd-11 311e7a9992 vk: Make best-effort attempt to utilize the low-latency pool 2025-10-22 20:20:07 +03:00
Elad 2f86f95c3f vm: Deallocate memory early, check no PS3 memory leaks 2025-10-22 10:55:48 +03:00
RipleyTom f61aaf83f6 More communication id validation changes 2025-10-21 21:27:55 +03:00
RipleyTom 66920b4d8f Improve sceNpSignalingGetLocalNetInfo 2025-10-21 17:17:05 +03:00
engdyn 038ee090b7 Fix build with Qt 6.10 2025-10-21 13:58:25 +01:00
RipleyTom 6a028b1883 Relax SceNpCommunicationId validation 2025-10-21 11:32:15 +03:00
Elad 64e5a8c099 SaveState Manager: Add option to boot last savestate 2025-10-21 04:27:54 +03:00
Elad abad7f2790 SaveState Manager: Format specially close dates 2025-10-21 04:27:54 +03:00
Elad c683b47ac3 SaveState Manager: Fix game specific filtering 2025-10-21 04:27:54 +03:00
kd-11 0c4e7fc178 vk: Do not access async scheduler if not explicitly initialized 2025-10-18 14:05:06 +03:00
kd-11 c4fba680d1 vk: Fix broken bound object comparison 2025-10-17 23:22:22 +03:00
kd-11 0d1a05ecd1 vk: Make buffer objects uniquely identifiable 2025-10-17 23:22:22 +03:00
kd-11 eb453462c1 vk: Use unique resource ids on buffer views 2025-10-17 23:22:22 +03:00
kd-11 5a91ed01eb vk: Rework the unique resource id system and apply it to buffer views 2025-10-17 23:22:22 +03:00
Megamouse 2fcd542b0b overlays: allow to update messages by id instead of text 2025-10-16 18:02:01 +02:00
Megamouse 146619de91 Qt: Allow to clear keyboard shortcuts in dialog 2025-10-15 23:27:10 +02:00
Marin Baron 41a122a266 [Build] Explicit Triple with LLVM 21.1.0 2025-10-15 20:09:21 +02:00
Elad 1c0fa2ad58 SaveStates: Improve try_lock_spu_threads_in_a_state_compatible_with_savestates 2025-10-15 17:16:32 +03:00
Megamouse a053abfba4 ffmpeg: update cellAtracXDec to ffmpeg 7 2025-10-14 21:12:39 +02:00
Elad e5848f4731 Qt: Fix savestate failuire message 2025-10-14 08:16:02 +03:00
Elad 32a18795fb Debug: Apply SPU Profiling data if debug enabled 2025-10-14 08:16:02 +03:00
Elad 6b556ca5b0 SaveStates: Fix Gem Thread Reboot 2025-10-14 08:16:02 +03:00
kd-11 a5b5ac1ed5 rsx: Fix user clip plane encode/decode 2025-10-14 01:51:57 +03:00
kd-11 1cae72c872 vk: Uniquely identify images using a monotonic incrementing counter 2025-10-13 12:12:22 +03:00
kd-11 878bb12a72 vk: Add support for blackwell PCI IDs 2025-10-13 12:12:22 +03:00
kd-11 e0249b05d2 vk: Improve documentation and remove notifications from instancing buffer 2025-10-13 12:12:22 +03:00
kd-11 1fa5286c87 vk: Raise heap changed interrupt when growing persistently bound SSBOs
- Using stale VAs leads to crashes for obvious reasons (UAF)
2025-10-13 12:12:22 +03:00
kd-11 f3f0c7d8da vk: Restore thread safety locks to descriptor routines 2025-10-13 12:12:22 +03:00
kd-11 afb814788f vk: Fix shader interpreter compilation and crashes 2025-10-13 12:12:22 +03:00
kd-11 efa4c6c34e gl: Reimplement user clip planes using the new ABI 2025-10-13 12:12:22 +03:00
kd-11 f3e34e1d44 vk: Fix user clip planes 2025-10-13 12:12:22 +03:00
kd-11 ce304f33de vk: Don't use rebar for transform constants data
- These heaps see massive writes, upto 8KB per draw in worst case scenarios. Write combining yields better throughput.
2025-10-13 12:12:22 +03:00
kd-11 c42fe42787 vk: Add re-bar toggle to GUI 2025-10-13 12:12:22 +03:00
kd-11 20a7297ac4 vk: Use BAR memory pool for low-latency resource uploads 2025-10-13 12:12:22 +03:00
kd-11 21809731e2 vk: Decorations for readonly SSBOs 2025-10-13 12:12:22 +03:00
kd-11 d770c7d7fa vk/exp: Remove unnecessary locks and optimize VS
- Hoists the most common pointer-chase to local var
2025-10-13 12:12:22 +03:00
kd-11 89e1c3ecfa rsx/vk: Update shader interpreter to use new varying draw params model 2025-10-13 12:12:22 +03:00
kd-11 f76ae4619b vk: Pass draw parameters to FS via varying register
- Should be better than pointer chasing with OpAccessChain + OpLoad
2025-10-13 12:12:22 +03:00
kd-11 2945ff1016 gl: Fix compilation error when using clip planes 2025-10-13 12:12:22 +03:00
kd-11 51e1ff4976 vk: Fix shader compiler issues caused by broken preprocessor macro expansion 2025-10-13 12:12:22 +03:00
kd-11 87677cfc85 vk: Guard against concurrent access of storage pool under high pressure and MTRSX. 2025-10-13 12:12:22 +03:00
kd-11 3ee626ce3c vk: Rewrite descriptor write template management 2025-10-13 12:12:22 +03:00
kd-11 c4426b0f07 rsx: Fix shader interpreter compilation 2025-10-13 12:12:22 +03:00
kd-11 1a5ec26392 vk: Fix shader compilation for certain glslang versions 2025-10-13 12:12:22 +03:00
kd-11 2275e689ce rsx: Restore optimizations in fragment shader recompiler 2025-10-13 12:12:22 +03:00
kd-11 10741a97ea vk: Improved state cache tracking 2025-10-13 12:12:22 +03:00
kd-11 1cc0446bc1 vk: Fix raster-env buffer type 2025-10-13 12:12:22 +03:00
kd-11 cec7ace28b vk: Fix shader compilation with fog parameters 2025-10-13 12:12:22 +03:00
kd-11 6e4f380e36 vk: Move polygon stipple parameters to fixed array buffer 2025-10-13 12:12:22 +03:00
kd-11 d68e4acb50 vk: Fix stale pointer reference when back-to-back partial updates are interrupted by a shader swap 2025-10-13 12:12:22 +03:00
kd-11 052ebe5acf vk: Fix windows build 2025-10-13 12:12:22 +03:00
kd-11 128267a236 vk: Fix wpos computation 2025-10-13 12:12:22 +03:00
kd-11 b1365a051d vk: Implement state tracking for command buffers
- Only tracks the heavy items for now. Binding the same pipeline or descriptor set causes some drivers to perform expensive operations (RADV, AMDVLK)
2025-10-13 12:12:22 +03:00
kd-11 3452aaf5d5 vk: Combine all draw-time constants to a single struct and update only the offset id
- Reduces push constants consumed per draw to 4 bytes total
2025-10-13 12:12:22 +03:00
kd-11 335f3dbe2f vk: Implement descriptor write buffering 2025-10-13 12:12:22 +03:00
kd-11 97620c4e17 rsx: Prepend namespace for simple_array uses
- Simplifies migration later on with find+replace in case we promote this useful class to utils namespace
2025-10-13 12:12:22 +03:00
kd-11 75f759079a rsx: Use simple array for texcoord stack
- Saves an expensive allocation when these ephemeral objects are constructed
2025-10-13 12:12:22 +03:00
kd-11 315ffed12f rsx: Simplify descriptor set contract a bit
- Making the functions sometimes destructive is confusing
2025-10-13 12:12:22 +03:00
kd-11 c347435151 vk: Move texture parameter stream to SSBO layout 2025-10-13 12:12:22 +03:00
kd-11 183acd4196 vk: Move FS context vars to block format 2025-10-13 12:12:22 +03:00
kd-11 1e40081d1f rsx/common: Add reverse_ptr impl to VS tree 2025-10-13 12:12:22 +03:00
kd-11 cd3e4fc8f1 rsx: Fix bugs in fragment program constants stream maagement
- Fix misplaced semicolon in GL fragment program compiler
- Add a simple lookup to avoid silly reverse-indexing issues in FP::AddConst
2025-10-13 12:12:22 +03:00
kd-11 e860cc9fad vk: Fix vertex context indexing 2025-10-13 12:12:22 +03:00
kd-11 aa119e1413 vk: Fix fragment constants indexing 2025-10-13 12:12:22 +03:00
kd-11 33e4b11509 vk: Fix use of push constants
- The double-overhead is so not worth it. Better to remove it down the line.
2025-10-13 12:12:22 +03:00
kd-11 5911330f8b rsx: Fix bug in reverse_iterator for simple_array 2025-10-13 12:12:22 +03:00
kd-11 e0e0d1ee0b rsx/vk: Convert fragment constants from static struct to array of vec4
- Also allows vulkan to use full-range binding model
2025-10-13 12:12:22 +03:00
kd-11 3188cb4a5a rsx: Enhance unordered_map declaration to be more versatile 2025-10-13 12:12:22 +03:00
kd-11 a3e6bdd8e4 rsx: Replace use of small vectors with simple_array 2025-10-13 12:12:22 +03:00
kd-11 ecc0fe4678 vk: Move draw-time constants to vertex layout stream and make it SSBO 2025-10-13 12:12:22 +03:00
kd-11 a819b9fc2a vk: Get basic vertex shaders working without traditional UBOs 2025-10-13 12:12:22 +03:00
kd-11 a4eccb259a vk: Fix allocation of vertex env data 2025-10-13 12:12:22 +03:00
kd-11 6e1436f1cd vk: Start converting UBO bindings to SSBO indexed arrays 2025-10-13 12:12:22 +03:00
Megamouse 9e49b9100f Qt: fix some warnings 2025-10-10 13:02:04 +02:00
Megamouse 950c7768bc cellL10n: fix ucs2 type 2025-10-10 13:02:04 +02:00
Megamouse 13bb9a2041 vm.cpp: remove unused variable 2025-10-10 13:02:04 +02:00
Megamouse 44e875618f cellPad: Fix some warnings 2025-10-10 13:02:04 +02:00
Megamouse 25fbdfb43a Qt/Input: Adjust pad settings dialog based on pad capabilities 2025-10-10 13:02:04 +02:00
Megamouse 43c4947cb9 Update Qt to 6.10.0 2025-10-10 10:54:39 +02:00
Elad b18a0830f3 Multi-Slot Savestates 2025-10-07 13:33:58 +03:00
RipleyTom 48bf30aa2d Fix sceNpManagerGetAccountRegion's returned language 2025-10-05 09:01:03 +03:00
RipleyTom f05fabdb79 Change sceNpManagerGetMyLanguages languages priority 2025-10-04 19:23:38 +03:00
Elad 274fec7bd0 Pull Request #17543: review fixes 2025-10-04 15:48:30 +03:00
derole 86b7ccef93 sys_ss/RPCN: Add PSID randomisation 2025-10-04 15:48:30 +03:00
Megamouse 054000fb37 Update SDL to 3.2.24 2025-10-04 13:54:07 +02:00
Megamouse 76cdcc9f32 Update FAudio to 25.10 2025-10-04 13:54:07 +02:00
Elad e8aa1caa4e Config: Implement 128-bit setting entry type 2025-10-03 19:46:01 +03:00
Elad 4141f76105 Win32/vm_native.cpp: Improve sparse memory file mapping robustness 2025-10-03 15:06:19 +03:00
477 changed files with 17049 additions and 6738 deletions
+20 -21
View File
@@ -6,12 +6,14 @@ export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
export HOMEBREW_NO_ENV_HINTS=1
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install -f --overwrite --quiet ccache pipenv googletest ffmpeg@5 "llvm@$LLVM_COMPILER_VER" glew sdl3 vulkan-headers
brew install -f --overwrite --quiet googletest opencv@4 ffmpeg@5 "llvm@$LLVM_COMPILER_VER" sdl3 vulkan-headers vulkan-loader
brew unlink --quiet ffmpeg qtbase qtsvg qtdeclarative
brew link -f --quiet "llvm@$LLVM_COMPILER_VER" ffmpeg@5
# moltenvk based on commit for 1.3.0 release
# moltenvk based on commit for 1.4.0 release
export HOMEBREW_DEVELOPER=1 # Prevents blocking of local formulae
wget https://raw.githubusercontent.com/Homebrew/homebrew-core/7255441cbcafabaa8950f67c7ec55ff499dbb2d3/Formula/m/molten-vk.rb
wget https://raw.githubusercontent.com/Homebrew/homebrew-core/ea2bec5f1f4384e188d7fc0702ab21a20a2ced08/Formula/m/molten-vk.rb
/opt/homebrew/bin/brew install -f --overwrite --formula --quiet ./molten-vk.rb
export HOMEBREW_DEVELOPER=0
@@ -27,23 +29,24 @@ export CMAKE_EXTRA_OPTS='-DLLVM_TARGETS_TO_BUILD=arm64'
export WORKDIR;
WORKDIR="$(pwd)"
# Setup ccache
if [ ! -d "$CCACHE_DIR" ]; then
mkdir -p "$CCACHE_DIR"
fi
# Get Qt
if [ ! -d "/tmp/Qt/$QT_VER" ]; then
mkdir -p "/tmp/Qt"
git clone https://github.com/engnr/qt-downloader.git
cd qt-downloader
git checkout f52efee0f18668c6d6de2dec0234b8c4bc54c597
# nested Qt 6.9.3 URL workaround
# sed -i '' "s/'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/'qt{0}_{0}{1}{2}'.format(major, minor, patch), 'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/g" qt-downloader
# sed -i '' "s/'{}\/{}\/qt{}_{}\/'/'{0}\/{1}\/qt{2}_{3}\/qt{2}_{3}\/'/g" qt-downloader
# archived Qt 6.7.3 URL workaround
sed -i '' "s/official_releases/archive/g" qt-downloader
sed -i '' "s/'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/'qt{0}_{0}{1}{2}'.format(major, minor, patch), 'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/g" qt-downloader
sed -i '' "s/'{}\/{}\/qt{}_{}\/'/'{0}\/{1}\/qt{2}_{3}\/qt{2}_{3}\/'/g" qt-downloader
cd "/tmp/Qt"
"$BREW_PATH/bin/pipenv" run pip3 uninstall py7zr requests semantic_version lxml
"$BREW_PATH/bin/pipenv" run pip3 install py7zr requests semantic_version lxml --no-cache
pip3 install py7zr requests semantic_version lxml --no-cache --break-system-packages
mkdir -p "$QT_VER/macos" ; ln -s "macos" "$QT_VER/clang_64"
# sed -i '' 's/args\.version \/ derive_toolchain_dir(args) \/ //g' "$WORKDIR/qt-downloader/qt-downloader" # Qt 6.9.3 workaround
"$BREW_PATH/bin/pipenv" run "$WORKDIR/qt-downloader/qt-downloader" macos desktop "$QT_VER" clang_64 --opensource --addons qtmultimedia qtimageformats # -o "$QT_VER/clang_64"
sed -i '' 's/args\.version \/ derive_toolchain_dir(args) \/ //g' "$WORKDIR/qt-downloader/qt-downloader"
python3 "$WORKDIR/qt-downloader/qt-downloader" macos desktop "$QT_VER" clang_64 --opensource --addons qtmultimedia qtimageformats -o "$QT_VER/clang_64"
fi
cd "$WORKDIR"
@@ -54,15 +57,14 @@ export SDL3_DIR="$BREW_PATH/opt/sdl3/lib/cmake/SDL3"
export PATH="$BREW_PATH/opt/llvm@$LLVM_COMPILER_VER/bin:$WORKDIR/qt-downloader/$QT_VER/clang_64/bin:$BREW_BIN:$BREW_SBIN:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin:$PATH"
export LDFLAGS="-L$BREW_PATH/lib $BREW_PATH/opt/ffmpeg@5/lib/libavcodec.dylib $BREW_PATH/opt/ffmpeg@5/lib/libavformat.dylib $BREW_PATH/opt/ffmpeg@5/lib/libavutil.dylib $BREW_PATH/opt/ffmpeg@5/lib/libswscale.dylib $BREW_PATH/opt/ffmpeg@5/lib/libswresample.dylib $BREW_PATH/opt/llvm@$LLVM_COMPILER_VER/lib/c++/libc++.1.dylib $BREW_PATH/lib/libSDL3.dylib $BREW_PATH/lib/libGLEW.dylib $BREW_PATH/opt/llvm@$LLVM_COMPILER_VER/lib/unwind/libunwind.1.dylib -Wl,-rpath,$BREW_PATH/lib"
export CPPFLAGS="-I$BREW_PATH/include -I$BREW_PATH/include -no-pie -D__MAC_OS_X_VERSION_MIN_REQUIRED=140000"
export CFLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=140000"
export CPPFLAGS="-I$BREW_PATH/include -D__MAC_OS_X_VERSION_MIN_REQUIRED=144000"
export CFLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=144000"
export LIBRARY_PATH="$BREW_PATH/lib"
export LD_LIBRARY_PATH="$BREW_PATH/lib"
export VULKAN_SDK
VULKAN_SDK="$BREW_PATH/opt/molten-vk"
ln -s "$VULKAN_SDK/lib/libMoltenVK.dylib" "$VULKAN_SDK/lib/libvulkan.dylib" || true
export VK_ICD_FILENAMES="$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json"
ln -s "$BREW_PATH/opt/vulkan-loader/lib/libvulkan.dylib" "$VULKAN_SDK/lib/libvulkan.dylib" || true
export LLVM_DIR
LLVM_DIR="$BREW_PATH/opt/llvm@$LLVM_COMPILER_VER"
@@ -70,12 +72,9 @@ LLVM_DIR="$BREW_PATH/opt/llvm@$LLVM_COMPILER_VER"
# shellcheck disable=SC2046
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/ffmpeg/ && !/llvm/ && !/opencv/ && !/SDL/ && !/feralinteractive/ { print $3 }' .gitmodules)
# 3rdparty fixes
sed -i '' "s/extern const double NSAppKitVersionNumber;/const double NSAppKitVersionNumber = 1343;/g" 3rdparty/hidapi/hidapi/mac/hid.c
mkdir build && cd build || exit 1
export MACOSX_DEPLOYMENT_TARGET=14.0
export MACOSX_DEPLOYMENT_TARGET=14.4
"$BREW_PATH/bin/cmake" .. \
-DBUILD_RPCS3_TESTS="${RUN_UNIT_TESTS}" \
@@ -107,7 +106,7 @@ export MACOSX_DEPLOYMENT_TARGET=14.0
-DCMAKE_OSX_ARCHITECTURES=arm64 \
-DCMAKE_IGNORE_PATH="$BREW_PATH/lib" \
-DCMAKE_IGNORE_PREFIX_PATH=/opt/homebrew/opt \
-DCMAKE_CXX_FLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=140000" \
-DCMAKE_CXX_FLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=144000" \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_OSX_SYSROOT="$(xcrun --sdk macosx --show-sdk-path)" \
-G Ninja
+18 -22
View File
@@ -6,15 +6,17 @@ export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
export HOMEBREW_NO_ENV_HINTS=1
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install -f --overwrite --quiet ccache pipenv "llvm@$LLVM_COMPILER_VER"
brew install -f --overwrite --quiet ccache "llvm@$LLVM_COMPILER_VER"
brew link -f --overwrite --quiet "llvm@$LLVM_COMPILER_VER"
# shellcheck disable=SC3009
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
arch -x86_64 /usr/local/bin/brew install -f --overwrite --quiet ffmpeg@5 "llvm@$LLVM_COMPILER_VER" glew sdl3 vulkan-headers
arch -x86_64 /usr/local/bin/brew install -f --overwrite --quiet python@3.14 opencv@4 ffmpeg@5 "llvm@$LLVM_COMPILER_VER" sdl3 vulkan-headers vulkan-loader
arch -x86_64 /usr/local/bin/brew unlink --quiet ffmpeg qtbase qtsvg qtdeclarative
arch -x86_64 /usr/local/bin/brew link -f --overwrite --quiet "llvm@$LLVM_COMPILER_VER" ffmpeg@5
# moltenvk based on commit for 1.3.0 release
# moltenvk based on commit for 1.4.0 release
export HOMEBREW_DEVELOPER=1 # Prevents blocking of local formulae
wget https://raw.githubusercontent.com/Homebrew/homebrew-core/7255441cbcafabaa8950f67c7ec55ff499dbb2d3/Formula/m/molten-vk.rb
wget https://raw.githubusercontent.com/Homebrew/homebrew-core/ea2bec5f1f4384e188d7fc0702ab21a20a2ced08/Formula/m/molten-vk.rb
arch -x86_64 /usr/local/bin/brew install -f --overwrite --formula --quiet ./molten-vk.rb
export HOMEBREW_DEVELOPER=0
export CXX=clang++
@@ -35,16 +37,13 @@ if [ ! -d "/tmp/Qt/$QT_VER" ]; then
git clone https://github.com/engnr/qt-downloader.git
cd qt-downloader
git checkout f52efee0f18668c6d6de2dec0234b8c4bc54c597
# nested Qt 6.9.3 URL workaround
# sed -i '' "s/'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/'qt{0}_{0}{1}{2}'.format(major, minor, patch), 'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/g" qt-downloader
# sed -i '' "s/'{}\/{}\/qt{}_{}\/'/'{0}\/{1}\/qt{2}_{3}\/qt{2}_{3}\/'/g" qt-downloader
# archived Qt 6.7.3 URL workaround
sed -i '' "s/official_releases/archive/g" qt-downloader
sed -i '' "s/'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/'qt{0}_{0}{1}{2}'.format(major, minor, patch), 'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/g" qt-downloader
sed -i '' "s/'{}\/{}\/qt{}_{}\/'/'{0}\/{1}\/qt{2}_{3}\/qt{2}_{3}\/'/g" qt-downloader
cd "/tmp/Qt"
"/opt/homebrew/bin/pipenv" --python "/opt/homebrew/bin/python3" run pip3 install py7zr requests semantic_version lxml
pip3 install py7zr requests semantic_version lxml --no-cache --break-system-packages
mkdir -p "$QT_VER/macos" ; ln -s "macos" "$QT_VER/clang_64"
# sed -i '' 's/args\.version \/ derive_toolchain_dir(args) \/ //g' "$WORKDIR/qt-downloader/qt-downloader" # Qt 6.9.3 workaround
"/opt/homebrew/bin/pipenv" --python "/opt/homebrew/bin/python3" run "$WORKDIR/qt-downloader/qt-downloader" macos desktop "$QT_VER" clang_64 --opensource --addons qtmultimedia qtimageformats # -o "$QT_VER/clang_64"
sed -i '' 's/args\.version \/ derive_toolchain_dir(args) \/ //g' "$WORKDIR/qt-downloader/qt-downloader"
python3 "$WORKDIR/qt-downloader/qt-downloader" macos desktop "$QT_VER" clang_64 --opensource --addons qtmultimedia qtimageformats -o "$QT_VER/clang_64"
fi
cd "$WORKDIR"
@@ -54,16 +53,16 @@ export Qt6_DIR="$WORKDIR/qt-downloader/$QT_VER/clang_64/lib/cmake/Qt$QT_VER_MAIN
export SDL3_DIR="$BREW_X64_PATH/opt/sdl3/lib/cmake/SDL3"
export PATH="/opt/homebrew/opt/llvm@$LLVM_COMPILER_VER/bin:$WORKDIR/qt-downloader/$QT_VER/clang_64/bin:$BREW_BIN:$BREW_SBIN:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin:$PATH"
export LDFLAGS="-L$BREW_X64_PATH/lib -Wl,-rpath,$BREW_X64_PATH/lib"
export CPPFLAGS="-I$BREW_X64_PATH/include -msse -msse2 -mcx16 -no-pie -D__MAC_OS_X_VERSION_MIN_REQUIRED=140000"
export CFLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=140000"
# shellcheck disable=SC2155
export LDFLAGS="-L$BREW_X64_PATH/lib -Wl,-rpath,$BREW_X64_PATH/lib,-L$(brew --prefix llvm)/lib/c++"
export CPPFLAGS="-I$BREW_X64_PATH/include -msse -msse2 -mcx16 -D__MAC_OS_X_VERSION_MIN_REQUIRED=144000"
export CFLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=144000"
export LIBRARY_PATH="$BREW_X64_PATH/opt/llvm@$LLVM_COMPILER_VER/lib:$BREW_X64_PATH/lib"
export LD_LIBRARY_PATH="$BREW_X64_PATH/opt/llvm@$LLVM_COMPILER_VER/lib:$BREW_X64_PATH/lib"
export VULKAN_SDK
VULKAN_SDK="$BREW_X64_PATH/opt/molten-vk"
ln -s "$VULKAN_SDK/lib/libMoltenVK.dylib" "$VULKAN_SDK/lib/libvulkan.dylib"
export VK_ICD_FILENAMES="$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json"
ln -s "$BREW_X64_PATH/opt/vulkan-loader/lib/libvulkan.dylib" "$VULKAN_SDK/lib/libvulkan.dylib"
export LLVM_DIR
LLVM_DIR="$BREW_X64_PATH/opt/llvm@$LLVM_COMPILER_VER"
@@ -71,12 +70,9 @@ LLVM_DIR="$BREW_X64_PATH/opt/llvm@$LLVM_COMPILER_VER"
# shellcheck disable=SC2046
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/ffmpeg/ && !/llvm/ && !/opencv/ && !/SDL/ && !/feralinteractive/ { print $3 }' .gitmodules)
# 3rdparty fixes
sed -i '' "s/extern const double NSAppKitVersionNumber;/const double NSAppKitVersionNumber = 1343;/g" 3rdparty/hidapi/hidapi/mac/hid.c
mkdir build && cd build || exit 1
export MACOSX_DEPLOYMENT_TARGET=14.0
export MACOSX_DEPLOYMENT_TARGET=14.4
"/opt/homebrew/bin/cmake" .. \
-DBUILD_RPCS3_TESTS=OFF \
@@ -110,7 +106,7 @@ export MACOSX_DEPLOYMENT_TARGET=14.0
-DCMAKE_TOOLCHAIN_FILE=buildfiles/cmake/TCDarwinX86_64.cmake \
-DCMAKE_IGNORE_PATH="$BREW_X64_PATH/lib" \
-DCMAKE_IGNORE_PREFIX_PATH=/usr/local/opt \
-DCMAKE_CXX_FLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=140000" \
-DCMAKE_CXX_FLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=144000" \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_OSX_SYSROOT="$(xcrun --sdk macosx --show-sdk-path)" \
-G Ninja
+20 -1
View File
@@ -14,7 +14,7 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
curl -fsSLo linuxdeploy-plugin-checkrt.sh https://github.com/darealshinji/linuxdeploy-plugin-checkrt/releases/download/continuous/linuxdeploy-plugin-checkrt.sh
chmod +x ./linuxdeploy-plugin-checkrt.sh
export EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so"
export EXTRA_PLATFORM_PLUGINS="libqwayland.so"
export EXTRA_QT_PLUGINS="svg;wayland-decoration-client;wayland-graphics-integration-client;wayland-shell-integration;waylandcompositor"
APPIMAGE_EXTRACT_AND_RUN=1 linuxdeploy --appdir AppDir --plugin qt --plugin checkrt
@@ -32,6 +32,25 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
# Remove git directory containing local commit history file
rm -rf ./AppDir/usr/share/rpcs3/git
# Download translations
mkdir -p "./AppDir/usr/translations"
ZIP_URL=$(curl -fsSL "https://api.github.com/repos/RPCS3/rpcs3_translations/releases/latest" \
| grep "browser_download_url" \
| grep "RPCS3-languages.zip" \
| cut -d '"' -f 4)
if [ -z "$ZIP_URL" ]; then
echo "Failed to find RPCS3-languages.zip in the latest release. Continuing without translations."
else
echo "Downloading translations from: $ZIP_URL"
curl -L -o translations.zip "$ZIP_URL" || {
echo "Failed to download translations.zip. Continuing without translations."
exit 0
}
unzip -o translations.zip -d "./AppDir/usr/translations" >/dev/null 2>&1 || \
echo "Failed to extract translations.zip. Continuing without translations."
rm -f translations.zip
fi
curl -fsSLo /uruntime "https://github.com/VHSgunzo/uruntime/releases/download/v0.3.4/uruntime-appimage-dwarfs-$CPU_ARCH"
chmod +x /uruntime
/uruntime --appimage-mkdwarfs -f --set-owner 0 --set-group 0 --no-history --no-create-timestamp \
+28 -4
View File
@@ -15,8 +15,15 @@ echo "AVVER=$AVVER" >> ../.ci/ci-vars.env
cd bin
mkdir "rpcs3.app/Contents/lib/" || true
mkdir -p "rpcs3.app/Contents/Resources/vulkan/icd.d" || true
wget https://github.com/KhronosGroup/MoltenVK/releases/download/v1.4.1/MoltenVK-macos-privateapi.tar
tar -xvf MoltenVK-macos-privateapi.tar
cp "MoltenVK/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib" "rpcs3.app/Contents/Frameworks/libMoltenVK.dylib"
cp "MoltenVK/MoltenVK/dynamic/dylib/macOS/MoltenVK_icd.json" "rpcs3.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json"
sed -i '' "s/.\//..\/..\/..\/Frameworks\//g" "rpcs3.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json"
cp "$(realpath /opt/homebrew/opt/llvm@$LLVM_COMPILER_VER/lib/c++/libc++abi.1.0.dylib)" "rpcs3.app/Contents/Frameworks/libc++abi.1.dylib"
cp "$(realpath /opt/homebrew/opt/gcc/lib/gcc/current/libgcc_s.1.1.dylib)" "rpcs3.app/Contents/Frameworks/libgcc_s.1.1.dylib"
cp "$(realpath /opt/homebrew/lib/libsharpyuv.0.dylib)" "rpcs3.app/Contents/lib/libsharpyuv.0.dylib"
cp "$(realpath /opt/homebrew/lib/libintl.8.dylib)" "rpcs3.app/Contents/lib/libintl.8.dylib"
@@ -31,11 +38,28 @@ rm -rf "rpcs3.app/Contents/Frameworks/QtPdf.framework" \
../../.ci/optimize-mac.sh rpcs3.app
# Download translations
mkdir -p "rpcs3.app/Contents/translations"
ZIP_URL=$(curl -fsSL "https://api.github.com/repos/RPCS3/rpcs3_translations/releases/latest" \
| grep "browser_download_url" \
| grep "RPCS3-languages.zip" \
| cut -d '"' -f 4)
if [ -z "$ZIP_URL" ]; then
echo "Failed to find RPCS3-languages.zip in the latest release. Continuing without translations."
else
echo "Downloading translations from: $ZIP_URL"
curl -L -o translations.zip "$ZIP_URL" || {
echo "Failed to download translations.zip. Continuing without translations."
exit 0
}
unzip -o translations.zip -d "rpcs3.app/Contents/translations" >/dev/null 2>&1 || \
echo "Failed to extract translations.zip. Continuing without translations."
rm -f translations.zip
fi
# Hack
install_name_tool \
-delete_rpath /opt/homebrew/lib \
-delete_rpath /opt/homebrew/opt/llvm@$LLVM_COMPILER_VER/lib RPCS3.app/Contents/MacOS/rpcs3
#-delete_rpath /opt/homebrew1/Cellar/sdl3/3.2.8/lib
install_name_tool -delete_rpath /opt/homebrew/lib RPCS3.app/Contents/MacOS/rpcs3 || echo "Hack for deleting rpath /opt/homebrew/lib not needed"
install_name_tool -delete_rpath /opt/homebrew/opt/llvm@$LLVM_COMPILER_VER/lib RPCS3.app/Contents/MacOS/rpcs3 || echo "Hack for deleting rpath /opt/homebrew/opt/llvm@$LLVM_COMPILER_VER/lib not needed"
# Need to do this rename hack due to case insensitive filesystem
mv rpcs3.app RPCS3_.app
+29 -2
View File
@@ -14,9 +14,17 @@ AVVER="${COMM_TAG}-${COMM_COUNT}"
echo "AVVER=$AVVER" >> ../.ci/ci-vars.env
cd bin
mkdir "rpcs3.app/Contents/lib/"
mkdir "rpcs3.app/Contents/lib/" || true
mkdir -p "rpcs3.app/Contents/Resources/vulkan/icd.d" || true
wget https://github.com/KhronosGroup/MoltenVK/releases/download/v1.4.1/MoltenVK-macos-privateapi.tar
tar -xvf MoltenVK-macos-privateapi.tar
cp "MoltenVK/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib" "rpcs3.app/Contents/Frameworks/libMoltenVK.dylib"
cp "MoltenVK/MoltenVK/dynamic/dylib/macOS/MoltenVK_icd.json" "rpcs3.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json"
sed -i '' "s/.\//..\/..\/..\/Frameworks\//g" "rpcs3.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json"
cp "/usr/local/opt/llvm@$LLVM_COMPILER_VER/lib/c++/libc++abi.1.0.dylib" "rpcs3.app/Contents/lib/libc++abi.1.dylib"
cp "$(realpath /usr/local/opt/llvm@$LLVM_COMPILER_VER/lib/c++/libc++abi.1.0.dylib)" "rpcs3.app/Contents/Frameworks/libc++abi.1.dylib"
cp "$(realpath /usr/local/opt/llvm@$LLVM_COMPILER_VER/lib/unwind/libunwind.1.dylib)" "rpcs3.app/Contents/Frameworks/libunwind.1.dylib"
cp "$(realpath /usr/local/opt/gcc/lib/gcc/current/libgcc_s.1.1.dylib)" "rpcs3.app/Contents/Frameworks/libgcc_s.1.1.dylib"
cp "$(realpath /usr/local/lib/libsharpyuv.0.dylib)" "rpcs3.app/Contents/lib/libsharpyuv.0.dylib"
cp "$(realpath /usr/local/lib/libintl.8.dylib)" "rpcs3.app/Contents/lib/libintl.8.dylib"
@@ -31,6 +39,25 @@ rm -rf "rpcs3.app/Contents/Frameworks/QtPdf.framework" \
../../.ci/optimize-mac.sh rpcs3.app
# Download translations
mkdir -p "rpcs3.app/Contents/translations"
ZIP_URL=$(curl -fsSL "https://api.github.com/repos/RPCS3/rpcs3_translations/releases/latest" \
| grep "browser_download_url" \
| grep "RPCS3-languages.zip" \
| cut -d '"' -f 4)
if [ -z "$ZIP_URL" ]; then
echo "Failed to find RPCS3-languages.zip in the latest release. Continuing without translations."
else
echo "Downloading translations from: $ZIP_URL"
curl -L -o translations.zip "$ZIP_URL" || {
echo "Failed to download translations.zip. Continuing without translations."
exit 0
}
unzip -o translations.zip -d "rpcs3.app/Contents/translations" >/dev/null 2>&1 || \
echo "Failed to extract translations.zip. Continuing without translations."
rm -f translations.zip
fi
# Need to do this rename hack due to case insensitive filesystem
mv rpcs3.app RPCS3_.app
mv RPCS3_.app RPCS3.app
+19
View File
@@ -24,6 +24,25 @@ mkdir ./bin/config/input_configs
curl -fsSL 'https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt' 1> ./bin/config/input_configs/gamecontrollerdb.txt
curl -fsSL 'https://rpcs3.net/compatibility?api=v1&export' | iconv -t UTF-8 1> ./bin/GuiConfigs/compat_database.dat
# Download translations
mkdir -p ./bin/share/qt6/translations
ZIP_URL=$(curl -fsSL "https://api.github.com/repos/RPCS3/rpcs3_translations/releases/latest" \
| grep "browser_download_url" \
| grep "RPCS3-languages.zip" \
| cut -d '"' -f 4)
if [ -z "$ZIP_URL" ]; then
echo "Failed to find RPCS3-languages.zip in the latest release. Continuing without translations."
else
echo "Downloading translations from: $ZIP_URL"
curl -L -o translations.zip "$ZIP_URL" || {
echo "Failed to download translations.zip. Continuing without translations."
exit 0
}
unzip -o translations.zip -d "./bin/share/qt6/translations" >/dev/null 2>&1 || \
echo "Failed to extract translations.zip. Continuing without translations."
rm -f translations.zip
fi
# Package artifacts
7z a -m0=LZMA2 -mx9 "$BUILD" ./bin/*
+19
View File
@@ -15,6 +15,25 @@ mkdir ./bin/config/input_configs
curl -fsSL 'https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt' 1> ./bin/config/input_configs/gamecontrollerdb.txt
curl -fsSL 'https://rpcs3.net/compatibility?api=v1&export' | iconv -t UTF-8 1> ./bin/GuiConfigs/compat_database.dat
# Download translations
mkdir -p ./bin/qt6/translations
ZIP_URL=$(curl -fsSL "https://api.github.com/repos/RPCS3/rpcs3_translations/releases/latest" \
| grep "browser_download_url" \
| grep "RPCS3-languages.zip" \
| cut -d '"' -f 4)
if [ -z "$ZIP_URL" ]; then
echo "Failed to find RPCS3-languages.zip in the latest release. Continuing without translations."
else
echo "Downloading translations from: $ZIP_URL"
curl -L -o translations.zip "$ZIP_URL" || {
echo "Failed to download translations.zip. Continuing without translations."
exit 0
}
unzip -o translations.zip -d "./bin/qt6/translations" >/dev/null 2>&1 || \
echo "Failed to extract translations.zip. Continuing without translations."
rm -f translations.zip
fi
# Download SSL certificate (not needed with CURLSSLOPT_NATIVE_CA)
#curl -fsSL 'https://curl.haxx.se/ca/cacert.pem' 1> ./bin/cacert.pem
+1 -1
View File
@@ -12,7 +12,7 @@ pkg info # debug
pkg install "llvm$LLVM_COMPILER_VER"
# Mandatory dependencies (qtX-base is pulled via qtX-multimedia)
pkg install git ccache cmake ninja "qt$QT_VER_MAIN-multimedia" "qt$QT_VER_MAIN-svg" glew openal-soft ffmpeg
pkg install git ccache cmake ninja "qt$QT_VER_MAIN-multimedia" "qt$QT_VER_MAIN-svg" glew openal-soft ffmpeg pcre2
# Optional dependencies (libevdev is pulled by qtX-base)
pkg install pkgconf alsa-lib pulseaudio sdl3 evdev-proto vulkan-headers vulkan-loader opencv
+1 -1
View File
@@ -8,7 +8,7 @@ QT_URL_VER=$(echo "$QT_VER" | sed "s/\.//g")
QT_VER_MSVC_UP=$(echo "${QT_VER_MSVC}" | tr '[:lower:]' '[:upper:]')
QT_PREFIX="online/qtsdkrepository/windows_x86/desktop/qt${QT_VER_MAIN}_${QT_URL_VER}/qt${QT_VER_MAIN}_${QT_URL_VER}/qt.qt${QT_VER_MAIN}.${QT_URL_VER}."
QT_PREFIX_2="win64_${QT_VER_MSVC}_64/${QT_VER}-0-${QT_DATE}"
QT_SUFFIX="-Windows-Windows_11_23H2-${QT_VER_MSVC_UP}-Windows-Windows_11_23H2-X86_64.7z"
QT_SUFFIX="-Windows-Windows_11_24H2-${QT_VER_MSVC_UP}-Windows-Windows_11_24H2-X86_64.7z"
QT_BASE_URL="${QT_HOST}${QT_PREFIX}${QT_PREFIX_2}qtbase${QT_SUFFIX}"
QT_DECL_URL="${QT_HOST}${QT_PREFIX}${QT_PREFIX_2}qtdeclarative${QT_SUFFIX}"
QT_TOOL_URL="${QT_HOST}${QT_PREFIX}${QT_PREFIX_2}qttools${QT_SUFFIX}"
+14 -10
View File
@@ -30,23 +30,23 @@ jobs:
matrix:
include:
- os: ubuntu-24.04
docker_img: "rpcs3/rpcs3-ci-jammy:1.6"
docker_img: "rpcs3/rpcs3-ci-jammy:1.7"
build_sh: "/rpcs3/.ci/build-linux.sh"
compiler: clang
UPLOAD_COMMIT_HASH: d812f1254a1157c80fd402f94446310560f54e5f
UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-linux"
- os: ubuntu-24.04
docker_img: "rpcs3/rpcs3-ci-jammy:1.6"
docker_img: "rpcs3/rpcs3-ci-jammy:1.7"
build_sh: "/rpcs3/.ci/build-linux.sh"
compiler: gcc
- os: ubuntu-24.04-arm
docker_img: "rpcs3/rpcs3-ci-jammy-aarch64:1.6"
docker_img: "rpcs3/rpcs3-ci-jammy-aarch64:1.7"
build_sh: "/rpcs3/.ci/build-linux-aarch64.sh"
compiler: clang
UPLOAD_COMMIT_HASH: a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1
UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-linux-arm64"
- os: ubuntu-24.04-arm
docker_img: "rpcs3/rpcs3-ci-jammy-aarch64:1.6"
docker_img: "rpcs3/rpcs3-ci-jammy-aarch64:1.7"
build_sh: "/rpcs3/.ci/build-linux-aarch64.sh"
compiler: gcc
name: RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }}
@@ -134,9 +134,9 @@ jobs:
runs-on: macos-14
env:
CCACHE_DIR: /tmp/ccache_dir
QT_VER: '6.7.3'
QT_VER: '6.10.1'
QT_VER_MAIN: '6'
LLVM_COMPILER_VER: '19'
LLVM_COMPILER_VER: '21'
RELEASE_MESSAGE: ../GitHubReleaseMessage.txt
UPLOAD_COMMIT_HASH: ${{ matrix.UPLOAD_COMMIT_HASH }}
UPLOAD_REPO_FULL_NAME: ${{ matrix.UPLOAD_REPO_FULL_NAME }}
@@ -212,9 +212,9 @@ jobs:
env:
COMPILER: msvc
QT_VER_MAIN: '6'
QT_VER: '6.9.3'
QT_VER: '6.10.1'
QT_VER_MSVC: 'msvc2022'
QT_DATE: '202509261208'
QT_DATE: '202511161843'
LLVM_VER: '19.1.7'
VULKAN_VER: '1.3.268.0'
VULKAN_SDK_SHA: '8459ef49bd06b697115ddd3d97c9aec729e849cd775f5be70897718a9b3b9db5'
@@ -413,7 +413,11 @@ jobs:
env:
CCACHE_DIR: ${{ github.workspace }}/ccache
QT_VER_MAIN: '6'
LLVM_COMPILER_VER: '19'
LLVM_COMPILER_VER: '-devel'
CC: 'clang-devel'
CXX: 'clang++-devel'
LLVM_CONFIG: 'llvm-config-devel'
steps:
- name: Checkout repository
uses: actions/checkout@main
@@ -432,7 +436,7 @@ jobs:
id: root
uses: vmactions/freebsd-vm@v1
with:
envs: 'QT_VER_MAIN LLVM_COMPILER_VER CCACHE_DIR'
envs: 'QT_VER_MAIN LLVM_COMPILER_VER CCACHE_DIR CC CXX LLVM_CONFIG'
usesh: true
run: .ci/install-freebsd.sh && .ci/build-freebsd.sh
+1 -1
View File
@@ -21,7 +21,7 @@
ignore = dirty
[submodule "3rdparty/hidapi"]
path = 3rdparty/hidapi/hidapi
url = ../../RPCS3/hidapi.git
url = ../../libusb/hidapi.git
branch = master
ignore = dirty
[submodule "3rdparty/pugixml"]
+2 -2
View File
@@ -59,11 +59,11 @@ if(WIN32 OR APPLE)
7zip/C/XzEnc.c
7zip/C/XzIn.c
7zip/C/ZstdDec.c)
target_include_directories(3rdparty_7zip INTERFACE
target_include_directories(3rdparty_7zip SYSTEM INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/7zip/C>
$<INSTALL_INTERFACE:/7zip/C>)
target_include_directories(3rdparty_7zip INTERFACE 7zip)
target_include_directories(3rdparty_7zip SYSTEM INTERFACE 7zip)
set_property(TARGET 3rdparty_7zip PROPERTY FOLDER "3rdparty/")
+9 -11
View File
@@ -35,7 +35,7 @@ if (USE_SYSTEM_FLATBUFFERS)
message(FATAL_ERROR "flatc failed to regenerate flatbuffers headers.")
endif()
else()
target_include_directories(3rdparty_flatbuffers INTERFACE flatbuffers/include)
target_include_directories(3rdparty_flatbuffers SYSTEM INTERFACE flatbuffers/include)
endif()
# libPNG
@@ -56,7 +56,7 @@ if (USE_SYSTEM_VULKAN_MEMORY_ALLOCATOR)
add_library(3rdparty::vulkanmemoryallocator ALIAS GPUOpen::VulkanMemoryAllocator)
else()
add_library(3rdparty_vulkanmemoryallocator INTERFACE)
target_include_directories(3rdparty_vulkanmemoryallocator INTERFACE GPUOpen/VulkanMemoryAllocator/include)
target_include_directories(3rdparty_vulkanmemoryallocator SYSTEM INTERFACE GPUOpen/VulkanMemoryAllocator/include)
add_library(3rdparty::vulkanmemoryallocator ALIAS 3rdparty_vulkanmemoryallocator)
endif()
@@ -107,11 +107,11 @@ add_subdirectory(yaml-cpp)
# OpenGL
if (NOT ANDROID)
if (NOT ANDROID AND NOT APPLE)
find_package(OpenGL REQUIRED OPTIONAL_COMPONENTS EGL)
add_library(3rdparty_opengl INTERFACE)
target_include_directories(3rdparty_opengl INTERFACE GL)
target_include_directories(3rdparty_opengl SYSTEM INTERFACE GL)
if (WIN32)
if(NOT MSVC)
@@ -119,8 +119,6 @@ if (NOT ANDROID)
else()
target_link_libraries(3rdparty_opengl INTERFACE dxgi.lib d2d1.lib dwrite.lib)
endif()
elseif(APPLE)
target_link_libraries(3rdparty_opengl INTERFACE OpenGL::GL OpenGL::GLU)
else()
target_link_libraries(3rdparty_opengl INTERFACE OpenGL::GL OpenGL::GLU OpenGL::GLX)
endif()
@@ -204,7 +202,7 @@ if(USE_VULKAN)
find_package(Wayland)
if (WAYLAND_FOUND)
target_include_directories(3rdparty_vulkan
INTERFACE ${WAYLAND_INCLUDE_DIR})
SYSTEM INTERFACE ${WAYLAND_INCLUDE_DIR})
endif()
endif()
@@ -278,7 +276,7 @@ if(USE_FAUDIO)
target_compile_definitions(FAudio-static INTERFACE -DHAVE_FAUDIO)
set(FAUDIO_TARGET FAudio-static)
else()
message(FATAL_ERROR
message(WARNING
"-- RPCS3: 3rdparty FAudio requires SDL 3.2.0 or newer. Since a valid SDL3"
">=3.2.0 version cannot be found, building with FAudio will be skipped.")
set(USE_FAUDIO OFF CACHE BOOL "Disabled FAudio with SDL < 3.2.0" FORCE)
@@ -298,7 +296,7 @@ if(NOT ANDROID)
message(STATUS "RPCS3: using shared ffmpeg")
find_package(FFMPEG REQUIRED)
target_include_directories(3rdparty_ffmpeg INTERFACE ${FFMPEG_INCLUDE_DIR})
target_include_directories(3rdparty_ffmpeg SYSTEM INTERFACE ${FFMPEG_INCLUDE_DIR})
target_link_libraries(3rdparty_ffmpeg INTERFACE ${FFMPEG_LIBRARIES})
else()
message(STATUS "RPCS3: using builtin ffmpeg")
@@ -328,14 +326,14 @@ if(NOT ANDROID)
${FFMPEG_LIB_SWSCALE}
${FFMPEG_LIB_SWRESAMPLE}
)
target_include_directories(3rdparty_ffmpeg INTERFACE "ffmpeg/include")
target_include_directories(3rdparty_ffmpeg SYSTEM INTERFACE "ffmpeg/include")
endif()
endif()
# GLEW
add_library(3rdparty_glew INTERFACE)
if(NOT MSVC AND NOT ANDROID)
if(NOT MSVC AND NOT ANDROID AND NOT APPLE)
find_package(GLEW REQUIRED)
target_link_libraries(3rdparty_glew INTERFACE GLEW::GLEW)
endif()
+1 -1
View File
@@ -3,7 +3,7 @@ include(ExternalProject)
ExternalProject_Add(moltenvk
GIT_REPOSITORY https://github.com/KhronosGroup/MoltenVK.git
GIT_TAG 49b97f2
GIT_TAG 4588705
BUILD_IN_SOURCE 1
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK
CONFIGURE_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/fetchDependencies" --macos
+3 -3
View File
@@ -49,11 +49,11 @@
<PropertyGroup Label="UserMacros">
<CmakeReleaseCLI>call vsdevcmd.bat -arch=amd64
cd "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)"
cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="./Release" -DCMAKE_SYSTEM_VERSION=10.0 -DLIBTYPE=STATIC -DFORCE_STATIC_VCRT=true -DALSOFT_UTILS=false -DALSOFT_EXAMPLES=false -DALSOFT_INSTALL=false -DALSOFT_INSTALL_CONFIG=false -DALSOFT_INSTALL_HRTF_DATA=false -DALSOFT_INSTALL_AMBDEC_PRESETS=false -DALSOFT_INSTALL_EXAMPLES=false -DALSOFT_INSTALL_UTILS=false "$(SolutionDir)3rdparty\OpenAL\openal-soft"
cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="./Release" -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_SYSTEM_VERSION=10.0 -DLIBTYPE=STATIC -DFORCE_STATIC_VCRT=true -DALSOFT_UTILS=false -DALSOFT_EXAMPLES=false -DALSOFT_INSTALL=false -DALSOFT_INSTALL_CONFIG=false -DALSOFT_INSTALL_HRTF_DATA=false -DALSOFT_INSTALL_AMBDEC_PRESETS=false -DALSOFT_INSTALL_EXAMPLES=false -DALSOFT_INSTALL_UTILS=false "$(SolutionDir)3rdparty\OpenAL\openal-soft"
</CmakeReleaseCLI>
<CmakeDebugCLI>call vsdevcmd.bat -arch=amd64
cd "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)"
cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_INSTALL_PREFIX="./Debug" -DCMAKE_SYSTEM_VERSION=10.0 -DLIBTYPE=STATIC -DALSOFT_UTILS=false -DALSOFT_EXAMPLES=false -DALSOFT_INSTALL=false -DALSOFT_INSTALL_CONFIG=false -DALSOFT_INSTALL_HRTF_DATA=false -DALSOFT_INSTALL_AMBDEC_PRESETS=false -DALSOFT_INSTALL_EXAMPLES=false -DALSOFT_INSTALL_UTILS=false "$(SolutionDir)3rdparty\OpenAL\openal-soft"
cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_INSTALL_PREFIX="./Debug" -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebug -DCMAKE_SYSTEM_VERSION=10.0 -DLIBTYPE=STATIC -DALSOFT_UTILS=false -DALSOFT_EXAMPLES=false -DALSOFT_INSTALL=false -DALSOFT_INSTALL_CONFIG=false -DALSOFT_INSTALL_HRTF_DATA=false -DALSOFT_INSTALL_AMBDEC_PRESETS=false -DALSOFT_INSTALL_EXAMPLES=false -DALSOFT_INSTALL_UTILS=false "$(SolutionDir)3rdparty\OpenAL\openal-soft"
</CmakeDebugCLI>
<CmakeCopyCLI>
echo Copying..
@@ -106,4 +106,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
+2 -2
View File
@@ -11,11 +11,11 @@ add_library(soundtouch STATIC EXCLUDE_FROM_ALL
soundtouch/source/SoundTouch/TDStretch.cpp
)
target_include_directories(soundtouch PRIVATE
target_include_directories(soundtouch SYSTEM PRIVATE
soundtouch/source/SoundTouch
soundtouch/include)
target_include_directories(soundtouch INTERFACE
target_include_directories(soundtouch SYSTEM INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/soundtouch/include>
$<INSTALL_INTERFACE:/soundtouch/include>)
+1 -1
View File
@@ -9,7 +9,7 @@ set(ASMJIT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/asmjit" CACHE PATH "Location of 'asm
include("${ASMJIT_DIR}/CMakeLists.txt")
add_library(asmjit ${ASMJIT_SRC})
target_include_directories(asmjit PUBLIC ${ASMJIT_DIR}/src)
target_include_directories(asmjit SYSTEM PUBLIC ${ASMJIT_DIR}/src)
target_link_libraries(asmjit PRIVATE ${ASMJIT_DEPS})
# ASMJIT should have a option for disabling installing and this wouldnt
+10 -7
View File
@@ -80,10 +80,12 @@
<ClCompile Include="curl\lib\cshutdn.c" />
<ClCompile Include="curl\lib\curlx\base64.c" />
<ClCompile Include="curl\lib\curlx\dynbuf.c" />
<ClCompile Include="curl\lib\curlx\fopen.c" />
<ClCompile Include="curl\lib\curlx\inet_ntop.c" />
<ClCompile Include="curl\lib\curlx\inet_pton.c" />
<ClCompile Include="curl\lib\curlx\multibyte.c" />
<ClCompile Include="curl\lib\curlx\nonblock.c" />
<ClCompile Include="curl\lib\curlx\strerr.c" />
<ClCompile Include="curl\lib\curlx\strparse.c" />
<ClCompile Include="curl\lib\curlx\timediff.c" />
<ClCompile Include="curl\lib\curlx\timeval.c" />
@@ -92,9 +94,9 @@
<ClCompile Include="curl\lib\curlx\warnless.c" />
<ClCompile Include="curl\lib\curlx\winapi.c" />
<ClCompile Include="curl\lib\curl_addrinfo.c" />
<ClCompile Include="curl\lib\curl_des.c" />
<ClCompile Include="curl\lib\curl_endian.c" />
<ClCompile Include="curl\lib\curl_fnmatch.c" />
<ClCompile Include="curl\lib\curl_fopen.c" />
<ClCompile Include="curl\lib\curl_gethostname.c" />
<ClCompile Include="curl\lib\curl_get_line.c" />
<ClCompile Include="curl\lib\curl_gssapi.c" />
@@ -120,7 +122,6 @@
<ClCompile Include="curl\lib\fake_addrinfo.c" />
<ClCompile Include="curl\lib\file.c" />
<ClCompile Include="curl\lib\fileinfo.c" />
<ClCompile Include="curl\lib\fopen.c" />
<ClCompile Include="curl\lib\formdata.c" />
<ClCompile Include="curl\lib\ftp.c" />
<ClCompile Include="curl\lib\ftplistparser.c" />
@@ -147,7 +148,6 @@
<ClCompile Include="curl\lib\idn.c" />
<ClCompile Include="curl\lib\if2ip.c" />
<ClCompile Include="curl\lib\imap.c" />
<ClCompile Include="curl\lib\krb5.c" />
<ClCompile Include="curl\lib\ldap.c" />
<ClCompile Include="curl\lib\llist.c" />
<ClCompile Include="curl\lib\macos.c" />
@@ -159,6 +159,7 @@
<ClCompile Include="curl\lib\mqtt.c" />
<ClCompile Include="curl\lib\multi.c" />
<ClCompile Include="curl\lib\multi_ev.c" />
<ClCompile Include="curl\lib\multi_ntfy.c" />
<ClCompile Include="curl\lib\netrc.c" />
<ClCompile Include="curl\lib\noproxy.c" />
<ClCompile Include="curl\lib\openldap.c" />
@@ -203,6 +204,7 @@
<ClCompile Include="curl\lib\version.c" />
<ClCompile Include="curl\lib\vquic\curl_ngtcp2.c" />
<ClCompile Include="curl\lib\vquic\curl_quiche.c" />
<ClCompile Include="curl\lib\vtls\apple.c" />
<ClCompile Include="curl\lib\vtls\cipher_suite.c" />
<ClCompile Include="curl\lib\vtls\hostcheck.c" />
<ClCompile Include="curl\lib\vtls\rustls.c" />
@@ -225,7 +227,6 @@
<ClCompile Include="curl\lib\vssh\curl_path.c" />
<ClCompile Include="curl\lib\vssh\libssh.c" />
<ClCompile Include="curl\lib\vssh\libssh2.c" />
<ClCompile Include="curl\lib\vssh\wolfssh.c" />
<ClCompile Include="curl\lib\vtls\gtls.c" />
<ClCompile Include="curl\lib\vtls\keylog.c" />
<ClCompile Include="curl\lib\vtls\mbedtls.c" />
@@ -274,10 +275,12 @@
<ClInclude Include="curl\lib\curlx\binmode.h" />
<ClInclude Include="curl\lib\curlx\curlx.h" />
<ClInclude Include="curl\lib\curlx\dynbuf.h" />
<ClInclude Include="curl\lib\curlx\fopen.h" />
<ClInclude Include="curl\lib\curlx\inet_ntop.h" />
<ClInclude Include="curl\lib\curlx\inet_pton.h" />
<ClInclude Include="curl\lib\curlx\multibyte.h" />
<ClInclude Include="curl\lib\curlx\nonblock.h" />
<ClInclude Include="curl\lib\curlx\strerr.h" />
<ClInclude Include="curl\lib\curlx\strparse.h" />
<ClInclude Include="curl\lib\curlx\timediff.h" />
<ClInclude Include="curl\lib\curlx\timeval.h" />
@@ -287,14 +290,13 @@
<ClInclude Include="curl\lib\curlx\winapi.h" />
<ClInclude Include="curl\lib\curl_addrinfo.h" />
<ClInclude Include="curl\lib\curl_ctype.h" />
<ClInclude Include="curl\lib\curl_des.h" />
<ClInclude Include="curl\lib\curl_endian.h" />
<ClInclude Include="curl\lib\curl_fnmatch.h" />
<ClInclude Include="curl\lib\curl_fopen.h" />
<ClInclude Include="curl\lib\curl_gethostname.h" />
<ClInclude Include="curl\lib\curl_get_line.h" />
<ClInclude Include="curl\lib\curl_gssapi.h" />
<ClInclude Include="curl\lib\curl_hmac.h" />
<ClInclude Include="curl\lib\curl_krb5.h" />
<ClInclude Include="curl\lib\curl_ldap.h" />
<ClInclude Include="curl\lib\curl_md4.h" />
<ClInclude Include="curl\lib\curl_md5.h" />
@@ -325,7 +327,6 @@
<ClInclude Include="curl\lib\fake_addrinfo.h" />
<ClInclude Include="curl\lib\file.h" />
<ClInclude Include="curl\lib\fileinfo.h" />
<ClInclude Include="curl\lib\fopen.h" />
<ClInclude Include="curl\lib\formdata.h" />
<ClInclude Include="curl\lib\ftp.h" />
<ClInclude Include="curl\lib\ftplistparser.h" />
@@ -357,6 +358,7 @@
<ClInclude Include="curl\lib\multihandle.h" />
<ClInclude Include="curl\lib\multiif.h" />
<ClInclude Include="curl\lib\multi_ev.h" />
<ClInclude Include="curl\lib\multi_ntfy.h" />
<ClInclude Include="curl\lib\netrc.h" />
<ClInclude Include="curl\lib\noproxy.h" />
<ClInclude Include="curl\lib\parsedate.h" />
@@ -403,6 +405,7 @@
<ClInclude Include="curl\lib\vquic\curl_ngtcp2.h" />
<ClInclude Include="curl\lib\vquic\curl_quiche.h" />
<ClInclude Include="curl\lib\vquic\vquic_int.h" />
<ClInclude Include="curl\lib\vtls\apple.h" />
<ClInclude Include="curl\lib\vtls\cipher_suite.h" />
<ClInclude Include="curl\lib\vtls\hostcheck.h" />
<ClInclude Include="curl\lib\vtls\rustls.h" />
+30 -21
View File
@@ -42,9 +42,6 @@
<ClCompile Include="curl\lib\curl_addrinfo.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\curl_des.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\curl_endian.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -159,9 +156,6 @@
<ClCompile Include="curl\lib\imap.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\krb5.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\ldap.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -333,9 +327,6 @@
<ClCompile Include="curl\lib\vssh\libssh2.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\vssh\wolfssh.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\vtls\gtls.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -396,9 +387,6 @@
<ClCompile Include="curl\lib\headers.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\fopen.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\noproxy.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -546,6 +534,21 @@
<ClCompile Include="curl\lib\cf-ip-happy.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\curl_fopen.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\multi_ntfy.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\vtls\apple.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\curlx\fopen.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="curl\lib\curlx\strerr.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="curl\include\curl\curl.h">
@@ -623,9 +626,6 @@
<ClInclude Include="curl\lib\curl_ctype.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\curl_des.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\curl_endian.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -926,9 +926,6 @@
<ClInclude Include="curl\lib\vtls\keylog.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\curl_krb5.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\easyoptions.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -953,9 +950,6 @@
<ClInclude Include="curl\lib\easy_lock.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\fopen.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\functypes.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -1112,6 +1106,21 @@
<ClInclude Include="curl\lib\curl_mem_undef.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\curl_fopen.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\multi_ntfy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\vtls\apple.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\curlx\fopen.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curl\lib\curlx\strerr.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="curl\lib\libcurl.rc">
+1 -1
View File
@@ -9,7 +9,7 @@ if (USE_DISCORD_RPC AND (WIN32 OR CMAKE_SYSTEM MATCHES "Linux" OR APPLE))
set(WARNINGS_AS_ERRORS FALSE CACHE BOOL "When enabled, compiles with `-Werror` (on *nix platforms).")
add_subdirectory(discord-rpc EXCLUDE_FROM_ALL)
target_include_directories(3rdparty_discordRPC INTERFACE discord-rpc/include)
target_include_directories(3rdparty_discordRPC SYSTEM INTERFACE discord-rpc/include)
target_compile_definitions(3rdparty_discordRPC INTERFACE -DWITH_DISCORD_RPC)
target_link_libraries(3rdparty_discordRPC INTERFACE discord-rpc)
endif()
+1 -1
View File
@@ -3,7 +3,7 @@
add_library(3rdparty_feralinteractive INTERFACE)
if (CMAKE_SYSTEM MATCHES "Linux")
target_include_directories(3rdparty_feralinteractive INTERFACE feralinteractive/lib)
target_include_directories(3rdparty_feralinteractive SYSTEM INTERFACE feralinteractive/lib)
target_compile_definitions(3rdparty_feralinteractive INTERFACE -DGAMEMODE_AVAILABLE)
target_link_libraries(3rdparty_feralinteractive INTERFACE feralinteractive)
endif()
+1 -1
View File
@@ -7,7 +7,7 @@ if(USE_SYSTEM_GLSLANG)
target_link_libraries(3rdparty_glslang INTERFACE glslang::SPIRV)
get_target_property(SPIRV_INCLUDE_DIRS glslang::SPIRV INTERFACE_INCLUDE_DIRECTORIES)
list(TRANSFORM SPIRV_INCLUDE_DIRS APPEND "/glslang")
target_include_directories(3rdparty_glslang INTERFACE ${SPIRV_INCLUDE_DIRS})
target_include_directories(3rdparty_glslang SYSTEM INTERFACE ${SPIRV_INCLUDE_DIRS})
else()
set(ENABLE_PCH OFF CACHE BOOL "Enables Precompiled header" FORCE)
set(BUILD_EXTERNAL OFF CACHE BOOL "Build external dependencies in /External" FORCE)
+1 -1
View File
@@ -4,7 +4,7 @@ if(USE_SYSTEM_HIDAPI)
pkg_check_modules(hidapi-hidraw REQUIRED IMPORTED_TARGET hidapi-hidraw)
add_library(3rdparty_hidapi INTERFACE)
target_link_libraries(3rdparty_hidapi INTERFACE PkgConfig::hidapi-hidraw)
target_include_directories(3rdparty_hidapi INTERFACE PkgConfig::hidapi-hidraw)
target_include_directories(3rdparty_hidapi SYSTEM INTERFACE PkgConfig::hidapi-hidraw)
else()
set(BUILD_SHARED_LIBS FALSE CACHE BOOL "Don't build shared libs")
set(HIDAPI_INSTALL_TARGETS FALSE CACHE BOOL "Don't install anything")
+2 -2
View File
@@ -6,14 +6,14 @@ if (NOT USE_SYSTEM_LIBPNG)
set(PNG_TESTS OFF CACHE BOOL "Build libpng tests")
set(SKIP_INSTALL_ALL ON)
add_subdirectory(libpng EXCLUDE_FROM_ALL)
target_include_directories(png_static INTERFACE "${libpng_BINARY_DIR}" "${libpng_SOURCE_DIR}")
target_include_directories(png_static SYSTEM INTERFACE "${libpng_BINARY_DIR}" "${libpng_SOURCE_DIR}")
set(LIBPNG_TARGET png_static PARENT_SCOPE)
else()
find_package(PNG REQUIRED)
add_library(3rdparty_system_libpng INTERFACE)
target_include_directories(3rdparty_system_libpng INTERFACE ${PNG_INCLUDE_DIR})
target_include_directories(3rdparty_system_libpng SYSTEM INTERFACE ${PNG_INCLUDE_DIR})
target_link_libraries(3rdparty_system_libpng INTERFACE ${PNG_LIBRARY})
target_compile_definitions(3rdparty_system_libpng INTERFACE ${PNG_DEFINITIONS})
-1
View File
@@ -384,7 +384,6 @@
<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_render_unsupported.c" />
<ClCompile Include="SDL\src\render\SDL_yuv_sw.c" />
-6
View File
@@ -172,9 +172,6 @@
<Filter Include="render\direct3d12">
<UniqueIdentifier>{f48c2b17-1bee-4fec-a7c8-24cf619abe08}</UniqueIdentifier>
</Filter>
<Filter Include="video\intrin">
<UniqueIdentifier>{653672cc-90ae-4eba-a256-6479f2c31804}</UniqueIdentifier>
</Filter>
<Filter Include="main">
<UniqueIdentifier>{00001967ea2801028a046a722a070000}</UniqueIdentifier>
</Filter>
@@ -1460,9 +1457,6 @@
<ClCompile Include="SDL\src\sensor\windows\SDL_windowssensor.c">
<Filter>sensor\windows</Filter>
</ClCompile>
<ClCompile Include="SDL\src\render\SDL_d3dmath.c">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="SDL\src\render\SDL_render.c">
<Filter>render</Filter>
</ClCompile>
+1 -1
View File
@@ -107,7 +107,7 @@ if(WITH_LLVM)
add_library(3rdparty_llvm INTERFACE)
target_link_libraries(3rdparty_llvm INTERFACE ${LLVM_LIBS})
target_include_directories(3rdparty_llvm INTERFACE ${LLVM_INCLUDE_DIRS})
target_include_directories(3rdparty_llvm SYSTEM INTERFACE ${LLVM_INCLUDE_DIRS})
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
target_compile_definitions(3rdparty_llvm INTERFACE ${LLVM_DEFINITIONS_LIST} LLVM_AVAILABLE)
+3 -3
View File
@@ -3,9 +3,9 @@ if(USE_SYSTEM_MINIUPNPC)
pkg_check_modules(MiniUPnPc REQUIRED IMPORTED_TARGET miniupnpc>=2.3.3)
add_library(3rdparty_miniupnpc INTERFACE)
target_link_libraries(3rdparty_miniupnpc INTERFACE PkgConfig::MiniUPnPc)
target_include_directories(3rdparty_miniupnpc INTERFACE PkgConfig::MiniUPnPc)
target_include_directories(3rdparty_miniupnpc SYSTEM INTERFACE PkgConfig::MiniUPnPc)
list(TRANSFORM MiniUPnPc_INCLUDE_DIRS APPEND "/miniupnpc")
target_include_directories(3rdparty_miniupnpc INTERFACE ${MiniUPnPc_INCLUDE_DIRS})
target_include_directories(3rdparty_miniupnpc SYSTEM INTERFACE ${MiniUPnPc_INCLUDE_DIRS})
else()
option (UPNPC_BUILD_STATIC "Build static library" TRUE)
option (UPNPC_BUILD_SHARED "Build shared library" FALSE)
@@ -17,5 +17,5 @@ else()
add_subdirectory(miniupnp/miniupnpc EXCLUDE_FROM_ALL)
add_library(3rdparty_miniupnpc INTERFACE)
target_link_libraries(3rdparty_miniupnpc INTERFACE libminiupnpc-static)
target_include_directories(3rdparty_miniupnpc INTERFACE libminiupnpc-static)
target_include_directories(3rdparty_miniupnpc SYSTEM INTERFACE libminiupnpc-static)
endif()
+3 -2
View File
@@ -6,14 +6,15 @@ find_package(Qt6 ${QT_MIN_VER} CONFIG COMPONENTS Widgets Concurrent Multimedia M
if(WIN32)
target_link_libraries(3rdparty_qt6 INTERFACE Qt6::Widgets Qt6::Concurrent Qt6::Multimedia Qt6::MultimediaWidgets Qt6::Svg Qt6::SvgWidgets)
else()
find_package(Qt6 ${QT_MIN_VER} COMPONENTS DBus Gui)
set(QT_NO_PRIVATE_MODULE_WARNING ON)
find_package(Qt6 ${QT_MIN_VER} COMPONENTS DBus Gui GuiPrivate)
if(Qt6DBus_FOUND)
target_link_libraries(3rdparty_qt6 INTERFACE Qt6::Widgets Qt6::DBus Qt6::Concurrent Qt6::Multimedia Qt6::MultimediaWidgets Qt6::Svg Qt6::SvgWidgets)
target_compile_definitions(3rdparty_qt6 INTERFACE -DHAVE_QTDBUS)
else()
target_link_libraries(3rdparty_qt6 INTERFACE Qt6::Widgets Qt6::Concurrent Qt6::Multimedia Qt6::MultimediaWidgets Qt6::Svg Qt6::SvgWidgets)
endif()
target_include_directories(3rdparty_qt6 INTERFACE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
target_link_libraries(3rdparty_qt6 INTERFACE Qt6::GuiPrivate)
endif()
if(Qt6Widgets_FOUND)
+1 -1
View File
@@ -3,7 +3,7 @@ if(USE_SYSTEM_RTMIDI)
pkg_check_modules(RtMidi REQUIRED IMPORTED_TARGET rtmidi>=6.0.0)
add_library(rtmidi INTERFACE)
target_link_libraries(rtmidi INTERFACE PkgConfig::RtMidi)
target_include_directories(rtmidi INTERFACE PkgConfig::RtMidi)
target_include_directories(rtmidi SYSTEM INTERFACE PkgConfig::RtMidi)
else()
option(RTMIDI_API_JACK "Compile with JACK support." OFF)
option(RTMIDI_BUILD_TESTING "Build test programs" OFF)
+1 -1
View File
@@ -1,2 +1,2 @@
add_library(3rdparty_stblib INTERFACE)
target_include_directories(3rdparty_stblib INTERFACE stb)
target_include_directories(3rdparty_stblib SYSTEM INTERFACE stb)
+1 -1
View File
@@ -13,6 +13,6 @@ else()
add_library(3rdparty_zlib INTERFACE)
target_link_libraries(3rdparty_zlib INTERFACE zlibstatic)
target_include_directories(3rdparty_zlib INTERFACE zlib ${CMAKE_CURRENT_BINARY_DIR}/zlib)
target_include_directories(3rdparty_zlib SYSTEM INTERFACE zlib ${CMAKE_CURRENT_BINARY_DIR}/zlib)
target_compile_definitions(3rdparty_zlib INTERFACE -DZLIB_CONST=1)
endif()
+2 -2
View File
@@ -3,14 +3,14 @@ if(USE_SYSTEM_ZSTD)
pkg_check_modules(zstd REQUIRED IMPORTED_TARGET libzstd)
add_library(3rdparty_zstd INTERFACE)
target_link_libraries(3rdparty_zstd INTERFACE PkgConfig::zstd)
target_include_directories(3rdparty_zstd INTERFACE PkgConfig::RtMidi)
target_include_directories(3rdparty_zstd SYSTEM INTERFACE PkgConfig::RtMidi)
else()
option(ZSTD_BUILD_PROGRAMS "BUILD PROGRAMS" OFF)
option(ZSTD_BUILD_SHARED "BUILD SHARED LIBRARIES" OFF)
option(ZSTD_BUILD_STATIC "BUILD STATIC LIBRARIES" ON)
option(ZSTD_BUILD_TESTS "BUILD TESTS" OFF)
add_subdirectory(zstd/build/cmake EXLUDE_FROM_ALL)
add_subdirectory(zstd/build/cmake EXCLUDE_FROM_ALL)
add_library(3rdparty_zstd INTERFACE)
target_link_libraries(3rdparty_zstd INTERFACE libzstd_static)
endif()
+10 -8
View File
@@ -8,37 +8,38 @@ Other instructions may be found [here](https://wiki.rpcs3.net/index.php?title=Bu
### Windows 10 or later
The following tools are required to build RPCS3 on Windows 10 or later:
- [Visual Studio 2022](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community)
- [Visual Studio 2022/2026](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community)
- **Optional** - [CMake 3.28.0+](https://www.cmake.org/download/) (add to PATH)
**NOTES:**
- **Visual Studio 2022** integrates **CMake 3.29+** and it also supports both the `sln` solution (`.sln`, `.vcxproj`) and `CMake` solution (`CMakeLists.txt`, `CMakePresets.json`).
- **Visual Studio 2026** needs at least **CMake 4.2.0+**.
- **Visual Studio 2022/2026** integrates **CMake 3.29+** and it also supports both the `sln` solution (`.sln`, `.vcxproj`) and `CMake` solution (`CMakeLists.txt`, `CMakePresets.json`).
See sections [Building with Visual Studio sln solution](#building-with-visual-studio-sln-solution) and [Building with Visual Studio CMake solution](#building-with-visual-studio-cmake-solution)
on how to build the project with **Visual Studio**.
- Install and use this standalone **CMake** tool just in case of your preference. See section [Building with standalone CMake tool](#building-with-standalone-cmake-tool) on how to build the project
with standalone **CMake** tool.
- [Python 3.6+](https://www.python.org/downloads/) (add to PATH)
- [Qt 6.9.3](https://www.qt.io/download-qt-installer) In case you can't download from the official installer, you can use [Another Qt installer](https://github.com/miurahr/aqtinstall) (In that case you will need to manually add the "qtmultimedia" module when installing Qt)
- [Qt 6.10.1](https://www.qt.io/download-qt-installer) In case you can't download from the official installer, you can use [Another Qt installer](https://github.com/miurahr/aqtinstall) (In that case you will need to manually add the "qtmultimedia" module when installing Qt)
- [Vulkan SDK 1.3.268.0](https://vulkan.lunarg.com/sdk/home) (see "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html)) for now future SDKs don't work. You need precisely 1.3.268.0.
The `sln` solution available only on **Visual Studio** is the preferred building solution. It easily allows to build the **RPCS3** application in `Release` and `Debug` mode.
In order to build **RPCS3** with the `sln` solution (with **Visual Studio**), **Qt** libs need to be detected. To detect the libs:
- add and set the `QTDIR` environment variable, e.g. `<QtInstallFolder>\6.9.3\msvc2022_64\`
- add and set the `QTDIR` environment variable, e.g. `<QtInstallFolder>\6.10.1\msvc2022_64\`
- or use the [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2022)
**NOTE:** If you have issues with the **Visual Studio Qt Plugin**, you may want to uninstall it and install the [Legacy Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.LEGACYQtVisualStudioTools2022) instead.
In order to build **RPCS3** with the `CMake` solution (with both **Visual Studio** and standalone **CMake** tool):
- add and set the `Qt6_ROOT` environment variable to the **Qt** libs path, e.g. `<QtInstallFolder>\6.9.3\msvc2022_64\`
- add and set the `Qt6_ROOT` environment variable to the **Qt** libs path, e.g. `<QtInstallFolder>\6.10.1\msvc2022_64\`
### Linux
These are the essentials tools to build RPCS3 on Linux. Some of them can be installed through your favorite package manager:
- Clang 17+ or GCC 13+
- [CMake 3.28.0+](https://www.cmake.org/download/)
- [Qt 6.9.3](https://www.qt.io/download-qt-installer)
- [Qt 6.10.1](https://www.qt.io/download-qt-installer)
- [Vulkan SDK 1.3.268.0](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html)) for now future SDKs don't work. You need precisely 1.3.268.0.
- [SDL3](https://github.com/libsdl-org/SDL/releases) (for the FAudio backend)
@@ -107,9 +108,10 @@ Clone and initialize the repository
```bash
git clone --recurse-submodules https://github.com/RPCS3/rpcs3.git
cd rpcs3
git submodule sync
# This is automatically done by `git clone --recurse-submodules`,
# but in case you forgot it, you can manually fetch submodules this way:
git submodule update --init
git submodule update --init --recursive
```
### Windows
@@ -121,7 +123,7 @@ Start **Visual Studio**, click on `Open a project or solution` and select the `r
##### Configuring the Qt Plugin (if used)
1) go to `Extensions->Qt VS Tools->Qt Versions`
2) add the path to your Qt installation with compiler e.g. `<QtInstallFolder>\6.9.3\msvc2022_64`, version will fill in automatically
2) add the path to your Qt installation with compiler e.g. `<QtInstallFolder>\6.10.1\msvc2022_64`, version will fill in automatically
3) go to `Extensions->Qt VS Tools->Options->Legacy Project Format`. (Only available in the **Legacy Qt Plugin**)
4) set `Build: Run pre-build setup` to `true`. (Only available in the **Legacy Qt Plugin**)
+1 -1
View File
@@ -133,7 +133,7 @@ if(MSVC)
endif()
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
message( FATAL_ERROR "RPCS3 can only be compiled on 64-bit platforms." )
message(FATAL_ERROR "RPCS3 can only be compiled on 64-bit platforms.")
endif()
if(APPLE AND CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
+62
View File
@@ -166,6 +166,55 @@ bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max)
return true;
}
bool try_to_uint128(u128* out, std::string_view value)
{
if (value.empty())
{
if (out) cfg_log.error("cfg::try_to_uint128(): called with an empty string");
return false;
}
u64 result_low = 0, result_high = 0;
const char* start_high64 = value.data();
const char* end = value.data() + value.size();
if (start_high64[0] == '0' && value.size() >= 2 && (start_high64[1] == 'x' || start_high64[1] == 'X'))
{
// Hex support
start_high64 += 2;
}
const char* start_low64 = end - std::min<usz>(end - start_high64, 16);
// Hexadecimal-only
constexpr int base = 16;
auto ret = std::from_chars(start_low64, end, result_low, base);
if (ret.ec != std::errc() || ret.ptr != end)
{
if (out) cfg_log.error("cfg::try_to_uint128('%s'): invalid integer", value);
return false;
}
if (start_high64 == start_low64)
{
if (out) *out = result_low;
return true;
}
ret = std::from_chars(start_high64, start_low64, result_high, base);
if (ret.ec != std::errc() || ret.ptr != start_low64)
{
if (out) cfg_log.error("cfg::try_to_uint128('%s'): invalid integer", value);
return false;
}
if (out) *out = result_low + (u128{result_high} << 64);
return true;
}
std::vector<std::string> cfg::make_float_range(f64 min, f64 max)
{
return {std::to_string(min), std::to_string(max)};
@@ -278,6 +327,19 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
return true;
}
std::string cfg::uint128::to_string(u128 value) noexcept
{
std::string result = "0x";
result.resize(result.size() + 32);
for (u32 i = 0; i < 32; i++)
{
result[result.size() - 1 - i] = "0123456789ABCDEF"[static_cast<u64>(value >> (i * 4)) % 16];
}
return result;
}
std::vector<std::string> cfg::try_to_enum_list(decltype(&fmt_class_string<int>::format) func)
{
std::vector<std::string> result;
+81
View File
@@ -38,6 +38,7 @@ namespace cfg
_enum, // cfg::_enum type
_int, // cfg::_int type
uint, // cfg::uint type
uint128, // cfg::uint128 type
string, // cfg::string type
set, // cfg::set_entry type
map, // cfg::map_entry type
@@ -578,6 +579,86 @@ namespace cfg
// Alias for 64 bit int
using uint64 = uint<0, u64{umax}>;
// Unsigned 128-bit integer entry.
class uint128 final : public _base
{
using int_type = u128;
atomic_t<int_type> m_value{};
int_type original_def = 0;
public:
int_type def;
uint128(node* owner, const std::string& name, int_type def = 0, bool dynamic = false)
: _base(type::uint128, owner, name, dynamic)
, m_value(def)
, original_def(def)
, def(def)
{
}
operator int_type() const
{
return m_value;
}
operator ullong() const
{
return static_cast<ullong>(m_value.load());
}
int_type get() const
{
return m_value;
}
void from_default() override
{
m_value = def;
}
void restore_defaults() override
{
def = original_def;
}
static std::string to_string(u128 value) noexcept;
std::string to_string() const override
{
return to_string(m_value.load());
}
std::string def_to_string() const override
{
return to_string(def);
}
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
{
u128 result;
if (try_to_uint128(&result, value))
{
m_value = result;
return true;
}
return false;
}
void set(u128 value)
{
m_value = value;
}
std::vector<std::string> to_list() const override
{
// Should not be used
return make_uint_range(0, 1);
}
};
// Simple string entry with mutex
class string : public _base
{
+8
View File
@@ -658,7 +658,11 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, co
std::string result;
auto null_mod = std::make_unique<llvm::Module> ("null_", *m_context);
#if LLVM_VERSION_MAJOR >= 21 && (LLVM_VERSION_MINOR >= 1 || LLVM_VERSION_MAJOR >= 22)
null_mod->setTargetTriple(llvm::Triple(jit_compiler::triple1()));
#else
null_mod->setTargetTriple(jit_compiler::triple1());
#endif
std::unique_ptr<llvm::RTDyldMemoryManager> mem;
@@ -672,7 +676,11 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, co
else
{
mem = std::make_unique<MemoryManager2>(std::move(symbols_cement));
#if LLVM_VERSION_MAJOR >= 21 && (LLVM_VERSION_MINOR >= 1 || LLVM_VERSION_MAJOR >= 22)
null_mod->setTargetTriple(llvm::Triple(jit_compiler::triple2()));
#else
null_mod->setTargetTriple(jit_compiler::triple2());
#endif
}
}
else
+81 -1
View File
@@ -83,7 +83,8 @@ std::string fmt::win_error_to_string(unsigned long error, void* module_handle)
if (FormatMessageW((module_handle ? FORMAT_MESSAGE_FROM_HMODULE : FORMAT_MESSAGE_FROM_SYSTEM) | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
module_handle, error, 0, reinterpret_cast<LPWSTR>(&message_buffer), 0, nullptr))
{
message = fmt::format("%s (0x%x)", fmt::trim(wchar_to_utf8(message_buffer), " \t\n\r\f\v"), error);
const std::string utf8 = wchar_to_utf8(message_buffer);
message = fmt::format("%s (0x%x)", fmt::trim_sv(utf8, " \t\n\r\f\v"), error);
}
else
{
@@ -823,6 +824,50 @@ std::vector<std::string> fmt::split(std::string_view source, std::initializer_li
return result;
}
std::vector<std::string_view> fmt::split_sv(std::string_view source, std::initializer_list<std::string_view> separators, bool is_skip_empty)
{
std::vector<std::string_view> result;
for (usz index = 0; index < source.size();)
{
usz pos = -1;
usz sep_size = 0;
for (auto& separator : separators)
{
if (usz pos0 = source.find(separator, index); pos0 < pos)
{
pos = pos0;
sep_size = separator.size();
}
}
if (!sep_size)
{
result.emplace_back(&source[index], source.size() - index);
return result;
}
std::string_view piece = {&source[index], pos - index};
index = pos + sep_size;
if (piece.empty() && is_skip_empty)
{
continue;
}
result.emplace_back(std::move(piece));
}
if (result.empty() && !is_skip_empty)
{
result.emplace_back();
}
return result;
}
std::string fmt::trim(const std::string& source, std::string_view values)
{
const usz begin = source.find_first_not_of(values);
@@ -838,6 +883,21 @@ std::string fmt::trim(const std::string& source, std::string_view values)
return source.substr(begin, end + 1 - begin);
}
std::string_view fmt::trim_sv(std::string_view source, std::string_view values)
{
const usz begin = source.find_first_not_of(values);
if (begin == source.npos)
return {};
const usz end = source.find_last_not_of(values);
if (end == source.npos)
return source.substr(begin);
return source.substr(begin, end + 1 - begin);
}
std::string fmt::trim_front(const std::string& source, std::string_view values)
{
const usz begin = source.find_first_not_of(values);
@@ -848,12 +908,32 @@ std::string fmt::trim_front(const std::string& source, std::string_view values)
return source.substr(begin);
}
std::string_view fmt::trim_front_sv(std::string_view source, std::string_view values)
{
const usz begin = source.find_first_not_of(values);
if (begin == source.npos)
return {};
return source.substr(begin);
}
void fmt::trim_back(std::string& source, std::string_view values)
{
const usz index = source.find_last_not_of(values);
source.resize(index + 1);
}
std::string_view fmt::trim_back_sv(std::string_view source, std::string_view values)
{
const usz index = source.find_last_not_of(values);
if (index == std::string_view::npos)
return {};
source.remove_suffix(source.size() - (index + 1));
return source;
}
std::string fmt::to_upper(std::string_view string)
{
std::string result;
+1 -1
View File
@@ -394,7 +394,7 @@ namespace fmt
}
#if !defined(_MSC_VER) || defined(__clang__)
[[noreturn]] ~throw_exception();
[[noreturn]] ~throw_exception() = default;
#endif
};
+44 -8
View File
@@ -28,6 +28,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 unsigned int128_t
bool try_to_uint128(u128* out, std::string_view value);
// Convert string to float
bool try_to_float(f64* out, std::string_view value, f64 min, f64 max);
@@ -136,57 +139,90 @@ namespace fmt
// Splits the string into a vector of strings using the separators. The vector may contain empty strings unless is_skip_empty is true.
std::vector<std::string> split(std::string_view source, std::initializer_list<std::string_view> separators, bool is_skip_empty = true);
// Splits the string_view into a vector of string_views using the separators. The vector may contain empty string_views unless is_skip_empty is true.
std::vector<std::string_view> split_sv(std::string_view source, std::initializer_list<std::string_view> separators, bool is_skip_empty = true);
// Removes all preceding and trailing characters specified by 'values' from 'source'.
std::string trim(const std::string& source, std::string_view values = " \t");
// Removes all preceding and trailing characters specified by 'values' from 'source' and returns the result.
std::string_view trim_sv(std::string_view source, std::string_view values = " \t");
// Removes all preceding characters specified by 'values' from 'source'.
std::string trim_front(const std::string& source, std::string_view values = " \t");
// Removes all preceding characters specified by 'values' from 'source' and returns the result.
std::string_view trim_front_sv(std::string_view source, std::string_view values = " \t");
// Removes all trailing characters specified by 'values' from 'source'.
void trim_back(std::string& source, std::string_view values = " \t");
// Removes all trailing characters specified by 'values' from 'source' and returns the result.
std::string_view trim_back_sv(std::string_view source, std::string_view values = " \t");
template <typename T>
std::string merge(const T& source, const std::string& separator)
std::string merge(const T& source, std::string_view separator)
{
if (source.empty())
{
return {};
}
usz total = (source.size() - 1) * separator.size();
for (const auto& s : source)
{
total += s.size();
}
std::string result;
result.reserve(total);
auto it = source.begin();
auto end = source.end();
for (--end; it != end; ++it)
{
result += std::string{*it} + separator;
result.append(*it);
if (!separator.empty())
result.append(separator);
}
return result + std::string{source.back()};
return result.append(source.back());
}
template <typename T>
std::string merge(std::initializer_list<T> sources, const std::string& separator)
std::string merge(std::initializer_list<T> sources, std::string_view separator)
{
if (!sources.size())
{
return {};
}
usz total = (sources.size() - 1) * separator.size();
for (const auto& s : sources)
{
if (s.empty()) continue;
total += s.size() + (s.size() - 1) * separator.size();
}
std::string result;
result.reserve(total);
bool first = true;
for (const auto& v : sources)
{
if (first)
{
result = fmt::merge(v, separator);
first = false;
first = false;
}
else
else if (!separator.empty())
{
result += separator + fmt::merge(v, separator);
result.append(separator);
}
result.append(fmt::merge(v, separator));
}
return result;
+16 -4
View File
@@ -106,6 +106,11 @@ thread_local u64 g_tls_wait_fail = 0;
thread_local bool g_tls_access_violation_recovered = false;
extern thread_local std::string(*g_tls_log_prefix)();
namespace stx
{
atomic_t<u32> g_launch_retainer{0};
}
// Report error and call std::abort(), defined in main.cpp
[[noreturn]] void report_fatal_error(std::string_view text, bool is_html = false, bool include_help_text = true);
@@ -2160,10 +2165,17 @@ void thread_base::start()
ensure(m_thread);
ensure(::ResumeThread(reinterpret_cast<HANDLE>(+m_thread)) != static_cast<DWORD>(-1));
#elif defined(__APPLE__)
pthread_attr_t stack_size_attr;
pthread_attr_init(&stack_size_attr);
pthread_attr_setstacksize(&stack_size_attr, 0x800000);
ensure(pthread_create(reinterpret_cast<pthread_t*>(&m_thread.raw()), &stack_size_attr, entry_point, this) == 0);
pthread_attr_t attrs;
struct sched_param sp;
memset(&sp, 0, sizeof(struct sched_param));
sp.sched_priority=99;
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, 0x800000);
pthread_attr_set_qos_class_np(&attrs, QOS_CLASS_USER_INTERACTIVE, 0);
pthread_attr_setschedpolicy(&attrs, SCHED_RR);
pthread_attr_setschedparam(&attrs, &sp);
ensure(pthread_create(reinterpret_cast<pthread_t*>(&m_thread.raw()), &attrs, entry_point, this) == 0);
#else
ensure(pthread_create(reinterpret_cast<pthread_t*>(&m_thread.raw()), nullptr, entry_point, this) == 0);
#endif
+7
View File
@@ -465,6 +465,8 @@ public:
namespace stx
{
struct launch_retainer;
extern atomic_t<u32> g_launch_retainer;
}
// Derived from the callable object Context, possibly a lambda
@@ -481,6 +483,11 @@ class named_thread final : public Context, result_storage<Context>, thread_base
u64 entry_point2()
{
while (u32 value = stx::g_launch_retainer)
{
stx::g_launch_retainer.wait(value);
}
thread::initialize([]()
{
if constexpr (!result::empty)
+3 -1
View File
@@ -23,7 +23,6 @@ Intersection (&) and symmetric difference (^) is also available.
#include "util/types.hpp"
#include "util/atomic.hpp"
#include "Utilities/StrFmt.h"
template <typename T>
concept BitSetEnum = std::is_enum_v<T> && requires(T x)
@@ -384,6 +383,9 @@ public:
}
};
template <typename T>
struct fmt_unveil;
template <typename T>
struct fmt_unveil<bs_t<T>>
{
+3 -3
View File
@@ -27,14 +27,14 @@ void fmt_class_string<cheat_type>::format(std::string& out, u64 arg)
});
}
bool cheat_info::from_str(const std::string& cheat_line)
bool cheat_info::from_str(std::string_view cheat_line)
{
auto cheat_vec = fmt::split(cheat_line, {"@@@"}, false);
const auto cheat_vec = fmt::split(cheat_line, {"@@@"}, false);
s64 val64 = 0;
if (cheat_vec.size() != 5 || !try_to_int64(&val64, cheat_vec[2], 0, cheat_type_max - 1))
{
log_cheat.fatal("Failed to parse cheat line");
log_cheat.error("Failed to parse cheat line: '%s'", cheat_line);
return false;
}
+1 -1
View File
@@ -28,6 +28,6 @@ struct cheat_info
u32 offset{};
std::string red_script{};
bool from_str(const std::string& cheat_line);
bool from_str(std::string_view cheat_line);
std::string to_str() const;
};
+27
View File
@@ -0,0 +1,27 @@
#pragma once
// Generic deferred routine wrapper
// Use-case is similar to "defer" statement in other languages, just invokes a callback when the object goes out of scope
#include <functional>
namespace utils
{
template <typename F>
requires std::is_invocable_v<F>
class deferred_op
{
public:
deferred_op(F&& callback)
: m_callback(callback)
{}
~deferred_op()
{
m_callback();
}
private:
F m_callback;
};
}
+87 -8
View File
@@ -17,6 +17,8 @@
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#elif __APPLE__
#include <os/os_sync_wait_on_address.h>
#endif
#ifdef _WIN32
@@ -76,21 +78,71 @@ inline int futex(volatile void* uaddr, int futex_op, uint val, const timespec* t
{
#ifdef __linux__
return syscall(SYS_futex, uaddr, futex_op, static_cast<int>(val), timeout, nullptr, static_cast<int>(mask));
#elif __APPLE__
switch (futex_op)
{
case FUTEX_WAIT_PRIVATE:
case FUTEX_WAIT_BITSET_PRIVATE:
{
if (timeout)
{
const uint64_t nsec = timeout->tv_nsec + timeout->tv_sec * 1000000000ull;
return os_sync_wait_on_address_with_timeout(const_cast<void*>(uaddr), static_cast<uint64_t>(val), sizeof(uint), OS_SYNC_WAIT_ON_ADDRESS_NONE, OS_CLOCK_MACH_ABSOLUTE_TIME, nsec);
}
else
{
return os_sync_wait_on_address(const_cast<void*>(uaddr), static_cast<uint64_t>(val), sizeof(uint), OS_SYNC_WAIT_ON_ADDRESS_NONE);
}
}
case FUTEX_WAKE_PRIVATE:
case FUTEX_WAKE_BITSET_PRIVATE:
{
for (;;)
{
int ret = 0;
if (val == INT32_MAX)
{
ret = os_sync_wake_by_address_all(const_cast<void*>(uaddr), sizeof(uint), OS_SYNC_WAKE_BY_ADDRESS_NONE);
}
else if (val-- >= 0)
{
ret = os_sync_wake_by_address_any(const_cast<void*>(uaddr), sizeof(uint), OS_SYNC_WAKE_BY_ADDRESS_NONE);
}
if (val <= 0 || val == INT32_MAX || (ret < 0 && errno == ENOENT))
{
return ret;
}
}
}
}
errno = EINVAL;
return -1;
#else
static struct futex_manager
{
struct waiter
{
uint val;
uint mask;
std::condition_variable cv;
uint val;
uint mask;
std::condition_variable cv;
};
std::mutex mutex;
std::unordered_multimap<volatile void*, waiter*> map;
struct bucket_t
{
std::mutex mutex;
std::unordered_multimap<volatile void*, waiter*> map;
};
// Not a power of 2 on purpose (for alignment optimiations)
bucket_t bucks[63];
int operator()(volatile void* uaddr, int futex_op, uint val, const timespec* timeout, uint mask)
{
auto& bucket = bucks[(reinterpret_cast<u64>(uaddr) / 8) % std::size(bucks)];
auto& mutex = bucket.mutex;
auto& map = bucket.map;
std::unique_lock lock(mutex);
switch (futex_op)
@@ -111,7 +163,9 @@ inline int futex(volatile void* uaddr, int futex_op, uint val, const timespec* t
waiter rec;
rec.val = val;
rec.mask = mask;
const auto& ref = *map.emplace(uaddr, &rec);
// Announce the waiter
map.emplace(uaddr, &rec);
int res = 0;
@@ -127,6 +181,16 @@ inline int futex(volatile void* uaddr, int futex_op, uint val, const timespec* t
{
res = -1;
errno = ETIMEDOUT;
// Cleanup
for (auto range = map.equal_range(uaddr); range.first != range.second; range.first++)
{
if (range.first->second == &rec)
{
map.erase(range.first);
break;
}
}
}
}
else
@@ -134,7 +198,6 @@ inline int futex(volatile void* uaddr, int futex_op, uint val, const timespec* t
// TODO: absolute timeout
}
map.erase(std::find(map.find(uaddr), map.end(), ref));
return res;
}
@@ -153,13 +216,29 @@ inline int futex(volatile void* uaddr, int futex_op, uint val, const timespec* t
if (entry.mask & mask)
{
entry.cv.notify_one();
entry.mask = 0;
entry.cv.notify_one();
res++;
val--;
}
}
if (res)
{
// Cleanup
for (auto range = map.equal_range(uaddr); range.first != range.second;)
{
if (range.first->second->mask == 0)
{
map.erase(range.first);
range = map.equal_range(uaddr);
continue;
}
range.first++;
}
}
return res;
}
}
+1 -1
View File
@@ -201,7 +201,7 @@ QPushButton::disabled {
/* QSpinBox (Settings -> Emulator -> width/height) */
/* QDoubleSpinBox (Pads -> Mouse Acceleration -> x/y) */
QSpinBox, QDoubleSpinBox {
height: 0.1em;
height: 1.50em;
background-color: #b3ac98;
}
QSpinBox::disabled, QDoubleSpinBox::disabled {
-1
View File
@@ -5,7 +5,6 @@ if(MSVC)
add_compile_definitions(
_CRT_SECURE_NO_DEPRECATE=1 _CRT_NON_CONFORMING_SWPRINTFS=1 _SCL_SECURE_NO_WARNINGS=1
NOMINMAX _ENABLE_EXTENDED_ALIGNED_STORAGE=1 _HAS_EXCEPTIONS=0)
add_link_options(/DYNAMICBASE)
#TODO: Some of these could be cleaned up
add_compile_options(/wd4805) # Comparing boolean and int
+1 -1
View File
@@ -66,7 +66,7 @@ else ()
find_package_handle_standard_args(FFMPEG
DEFAULT_MSG
FFMPEG_LIBAVCODEC FFMPEG_LIBAVFORMAT FFMPEG_LIBSWSCALE FFMPEG_LIBSWRESAMPLE
FFMPEG_LIBAVCODEC FFMPEG_LIBAVFORMAT FFMPEG_LIBAVUTIL FFMPEG_LIBSWSCALE FFMPEG_LIBSWRESAMPLE
)
if (FFMPEG_FOUND)
+2 -1
View File
@@ -25,6 +25,7 @@
#include <string>
#include <vector>
#include <charconv>
#include <string_view>
std::string to_hex(std::uint64_t value, bool prfx = true)
{
@@ -85,7 +86,7 @@ int main(int argc, char* argv[])
// Decode address and try to find the object
std::uint64_t addr = -1;
std::from_chars(arg.data() + strlen("--start-address=0x"), arg.data() + arg.size(), addr, 16);
std::from_chars(arg.data() + ("--start-address=0x"sv).size(), arg.data() + arg.size(), addr, 16);
for (int j = 0; j < 0x100'0000; j++)
{
+16 -22
View File
@@ -10,16 +10,6 @@ include(CheckFunctionExists)
set(CMAKE_CXX_STANDARD 20)
set(ADDITIONAL_LIBS "")
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
#on some Linux distros shm_unlink and similar functions are in librt only
list(APPEND ADDITIONAL_LIBS "rt")
elseif(NOT WIN32 AND NOT CMAKE_CXX_FLAGS MATCHES "LIBICONV_PLUG")
#it seems like glibc includes the iconv functions we use but other libc
#implementations like the one on OSX don't seem implement them
list(APPEND ADDITIONAL_LIBS "iconv")
endif()
if(UNIX AND NOT APPLE AND NOT ANDROID)
add_compile_definitions(DATADIR="${CMAKE_INSTALL_FULL_DATADIR}/rpcs3")
# Optionally enable X11 for window management
@@ -78,8 +68,16 @@ if (NOT ANDROID)
3rdparty::libcurl
3rdparty::zlib
3rdparty::opencv
3rdparty::fusion
${ADDITIONAL_LIBS})
3rdparty::fusion)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
#on some Linux distros shm_unlink and similar functions are in librt only
target_link_libraries(rpcs3_lib PRIVATE rt)
elseif(NOT WIN32 AND NOT CMAKE_CXX_FLAGS MATCHES "LIBICONV_PLUG")
#it seems like glibc includes the iconv functions we use but other libc
#implementations like the one on OSX don't seem implement them
target_link_libraries(rpcs3_lib PRIVATE iconv)
endif()
# Unix display manager
if(X11_FOUND)
@@ -106,19 +104,16 @@ if (NOT ANDROID)
endif()
# Build rpcs3 executable
add_executable(rpcs3 WIN32 MACOSX_BUNDLE)
if(WIN32)
add_executable(rpcs3 WIN32)
target_sources(rpcs3 PRIVATE rpcs3.rc)
target_compile_definitions(rpcs3 PRIVATE UNICODE _UNICODE)
elseif(APPLE)
add_executable(rpcs3 MACOSX_BUNDLE)
target_sources(rpcs3 PRIVATE rpcs3.icns update_helper.sh)
set_source_files_properties(update_helper.sh PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
set_target_properties(rpcs3
PROPERTIES
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/rpcs3.plist.in")
else()
add_executable(rpcs3)
endif()
target_sources(rpcs3
@@ -137,17 +132,12 @@ if (NOT ANDROID)
# Copy icons to executable directory
if(APPLE)
if (CMAKE_BUILD_TYPE MATCHES "Debug" OR CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo")
set(QT_DEPLOY_FLAGS "-no-strip")
else()
set(QT_DEPLOY_FLAGS "")
endif()
qt_finalize_target(rpcs3)
add_custom_command(TARGET rpcs3 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/rpcs3.icns $<TARGET_FILE_DIR:rpcs3>/../Resources/rpcs3.icns
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/Icons $<TARGET_FILE_DIR:rpcs3>/../Resources/Icons
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/GuiConfigs $<TARGET_FILE_DIR:rpcs3>/../Resources/GuiConfigs
COMMAND "${MACDEPLOYQT_EXECUTABLE}" "${PROJECT_BINARY_DIR}/bin/rpcs3.app" "${QT_DEPLOY_FLAGS}")
COMMAND "${MACDEPLOYQT_EXECUTABLE}" "${PROJECT_BINARY_DIR}/bin/rpcs3.app" "$<$<CONFIG:Debug,RelWithDebInfo>:-no-strip>")
elseif(UNIX)
add_custom_command(TARGET rpcs3 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/Icons $<TARGET_FILE_DIR:rpcs3>/Icons
@@ -198,8 +188,12 @@ if(BUILD_RPCS3_TESTS)
PRIVATE
tests/test.cpp
tests/test_fmt.cpp
tests/test_pair.cpp
tests/test_tuple.cpp
tests/test_simple_array.cpp
tests/test_address_range.cpp
tests/test_rsx_cfg.cpp
tests/test_rsx_fp_asm.cpp
)
target_link_libraries(rpcs3_test
+4 -4
View File
@@ -11,10 +11,10 @@ SELF_KEY::SELF_KEY(u64 ver_start, u64 ver_end, u16 rev, u32 type, const std::str
version_end = ver_end;
revision = rev;
self_type = type;
hex_to_bytes(erk, e.c_str(), 0);
hex_to_bytes(riv, r.c_str(), 0);
hex_to_bytes(pub, pb.c_str(), 0);
hex_to_bytes(priv, pr.c_str(), 0);
hex_to_bytes(erk, e, 0);
hex_to_bytes(riv, r, 0);
hex_to_bytes(pub, pb, 0);
hex_to_bytes(priv, pr, 0);
curve_type = ct;
}
+6 -6
View File
@@ -598,15 +598,15 @@ bool package_reader::read_param_sfo()
const bool is_psp = (entry.type & PKG_FILE_ENTRY_PSP) != 0u;
std::string name(entry.name_size + BUF_PADDING, '\0');
std::string name_buf(entry.name_size + BUF_PADDING, '\0');
if (usz read_size = decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data(), name.data()); read_size < entry.name_size)
if (usz read_size = decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data(), name_buf.data()); read_size < entry.name_size)
{
pkg_log.error("PKG name could not be read (size=0x%x, offset=0x%x)", entry.name_size, entry.name_offset);
continue;
}
fmt::trim_back(name, "\0"sv);
std::string_view name = fmt::trim_back_sv(name_buf, "\0"sv);
// 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")
@@ -854,18 +854,18 @@ bool package_reader::fill_data(std::map<std::string, install_entry*>& all_instal
break;
}
std::string name(entry.name_size + BUF_PADDING, '\0');
std::string name_buf(entry.name_size + BUF_PADDING, '\0');
const bool is_psp = (entry.type & PKG_FILE_ENTRY_PSP) != 0u;
if (const usz read_size = decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data(), name.data()); read_size < entry.name_size)
if (const usz read_size = decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data(), name_buf.data()); read_size < entry.name_size)
{
num_failures++;
pkg_log.error("PKG name could not be read (size=0x%x, offset=0x%x)", entry.name_size, entry.name_offset);
break;
}
fmt::trim_back(name, "\0"sv);
std::string_view name = fmt::trim_back_sv(name_buf, "\0"sv);
std::string path = m_install_path + vfs::escape(name);
+1
View File
@@ -347,6 +347,7 @@ public:
};
bool is_valid() const { return m_is_valid; }
const PKGHeader& get_header() const { return m_header; }
package_install_result check_target_app_version() const;
static package_install_result extract_data(std::deque<package_reader>& readers, std::deque<std::string>& bootable_paths);
const psf::registry& get_psf() const { return m_psf; }
+14 -37
View File
@@ -7,9 +7,12 @@
#include "sha1.h"
#include "sha256.h"
#include "key_vault.h"
#include <charconv>
#include <cstdlib>
#include <cstring>
#include <stdio.h>
#include <time.h>
#include <cstdio>
#include <ctime>
#include "Utilities/StrFmt.h"
#include "Utilities/StrUtil.h"
#include "Utilities/File.h"
@@ -21,50 +24,24 @@
// Auxiliary functions (endian swap, xor).
// Hex string conversion auxiliary functions.
u64 hex_to_u64(const char* hex_str)
void hex_to_bytes(unsigned char* data, std::string_view hex_str, unsigned int str_length)
{
auto length = std::strlen(hex_str);
u64 tmp = 0;
u64 result = 0;
char c;
while (length--)
{
c = *hex_str++;
if((c >= '0') && (c <= '9'))
tmp = c - '0';
else if((c >= 'a') && (c <= 'f'))
tmp = c - 'a' + 10;
else if((c >= 'A') && (c <= 'F'))
tmp = c - 'A' + 10;
else
tmp = 0;
result |= (tmp << (length * 4));
}
return result;
}
void hex_to_bytes(unsigned char* data, const char* hex_str, unsigned int str_length)
{
const auto strn_length = (str_length > 0) ? str_length : std::strlen(hex_str);
auto data_length = strn_length / 2;
char tmp_buf[3] = {0, 0, 0};
const auto strn_length = (str_length > 0) ? str_length : hex_str.size();
// Don't convert if the string length is odd.
if ((strn_length % 2) == 0)
{
while (data_length--)
for (size_t i = 0; i < strn_length; i += 2)
{
tmp_buf[0] = *hex_str++;
tmp_buf[1] = *hex_str++;
*data++ = static_cast<u8>(hex_to_u64(tmp_buf) & 0xFF);
const auto [ptr, err] = std::from_chars(hex_str.data() + i, hex_str.data() + i + 2, *data++, 16);
if (err != std::errc())
{
fmt::throw_exception("Failed to read hex string: %s", std::make_error_code(err).message());
}
}
}
}
// Crypto functions (AES128-CBC, AES128-ECB, SHA1-HMAC and AES-CMAC).
void aescbc128_decrypt(unsigned char *key, unsigned char *iv, unsigned char *in, unsigned char *out, usz len)
{
@@ -181,7 +158,7 @@ std::array<u8, PASSPHRASE_KEY_LEN> sc_combine_laid_paid(s64 laid, s64 paid)
{
const std::string paid_laid = fmt::format("%016llx%016llx", laid, paid);
std::array<u8, PASSPHRASE_KEY_LEN> out{};
hex_to_bytes(out.data(), paid_laid.c_str(), PASSPHRASE_KEY_LEN * 2);
hex_to_bytes(out.data(), paid_laid, PASSPHRASE_KEY_LEN * 2);
return out;
}
+3 -3
View File
@@ -6,7 +6,8 @@
#include "util/types.hpp"
#include <stdlib.h>
#include <cstdlib>
#include <string_view>
enum { CRYPTO_MAX_PATH = 4096 };
@@ -15,8 +16,7 @@ char* extract_file_name(const char* file_path, char real_file_name[CRYPTO_MAX_PA
std::string sha256_get_hash(const char* data, usz size, bool lower_case);
// Hex string conversion auxiliary functions.
u64 hex_to_u64(const char* hex_str);
void hex_to_bytes(unsigned char *data, const char *hex_str, unsigned int str_length);
void hex_to_bytes(unsigned char* data, std::string_view hex_str, unsigned int str_length);
// Crypto functions (AES128-CBC, AES128-ECB, SHA1-HMAC and AES-CMAC).
void aescbc128_decrypt(unsigned char *key, unsigned char *iv, unsigned char *in, unsigned char *out, usz len);
+1 -1
View File
@@ -52,6 +52,6 @@ namespace audio
g_cfg.audio.volume.set(std::clamp<s32>(new_volume, g_cfg.audio.volume.min, g_cfg.audio.volume.max));
Emu.GetCallbacks().update_emu_settings();
rsx::overlays::queue_message(get_localized_string(localized_string_id::AUDIO_CHANGED, fmt::format("%d%%", g_cfg.audio.volume.get()).c_str()), 3'000'000);
rsx::overlays::queue_message(localized_string(localized_string_id::AUDIO_CHANGED, "%d%%", g_cfg.audio.volume.get()), 3'000'000, {}, rsx::overlays::message_pin_location::top_left, {}, true, true);
}
} // namespace audio
+18 -2
View File
@@ -402,6 +402,7 @@ target_sources(rpcs3_emu PRIVATE
Io/GunCon3.cpp
Io/Infinity.cpp
Io/interception.cpp
Io/KamenRider.cpp
Io/KeyboardHandler.cpp
Io/midi_config_types.cpp
Io/mouse_config.cpp
@@ -410,6 +411,7 @@ target_sources(rpcs3_emu PRIVATE
Io/pad_config_types.cpp
Io/pad_types.cpp
Io/PadHandler.cpp
Io/ps_move_data.cpp
Io/rb3drums_config.cpp
Io/RB3MidiDrums.cpp
Io/RB3MidiGuitar.cpp
@@ -440,6 +442,8 @@ target_sources(rpcs3_emu PRIVATE
NP/np_requests.cpp
NP/signaling_handler.cpp
NP/np_structs_extra.cpp
NP/clans_client.cpp
NP/clans_config.cpp
NP/rpcn_client.cpp
NP/rpcn_config.cpp
NP/rpcn_countries.cpp
@@ -515,11 +519,15 @@ target_sources(rpcs3_emu PRIVATE
RSX/Overlays/overlay_video.cpp
RSX/Overlays/Shaders/shader_loading_dialog.cpp
RSX/Overlays/Shaders/shader_loading_dialog_native.cpp
RSX/Program/Assembler/FPASM.cpp
RSX/Program/Assembler/FPOpcodes.cpp
RSX/Program/Assembler/FPToCFG.cpp
RSX/Program/Assembler/Passes/FP/RegisterAnnotationPass.cpp
RSX/Program/Assembler/Passes/FP/RegisterDependencyPass.cpp
RSX/Program/CgBinaryProgram.cpp
RSX/Program/CgBinaryFragmentProgram.cpp
RSX/Program/CgBinaryVertexProgram.cpp
RSX/Program/FragmentProgramDecompiler.cpp
RSX/Program/FragmentProgramRegister.cpp
RSX/Program/GLSLCommon.cpp
RSX/Program/ProgramStateCache.cpp
RSX/Program/program_util.cpp
@@ -537,7 +545,7 @@ target_sources(rpcs3_emu PRIVATE
RSX/rsx_vertex_data.cpp
)
if(NOT ANDROID)
if(NOT ANDROID AND NOT APPLE)
target_sources(rpcs3_emu PRIVATE
RSX/GL/GLCommonDecompiler.cpp
RSX/GL/GLCompute.cpp
@@ -577,6 +585,7 @@ if(TARGET 3rdparty_vulkan)
RSX/VK/vkutils/buffer_object.cpp
RSX/VK/vkutils/chip_class.cpp
RSX/VK/vkutils/commands.cpp
RSX/VK/vkutils/ex.cpp
RSX/VK/vkutils/data_heap.cpp
RSX/VK/vkutils/descriptors.cpp
RSX/VK/vkutils/image.cpp
@@ -589,6 +598,7 @@ if(TARGET 3rdparty_vulkan)
RSX/VK/vkutils/device.cpp
RSX/VK/vkutils/sampler.cpp
RSX/VK/vkutils/shared.cpp
RSX/VK/vkutils/unique_resource.cpp
RSX/VK/VKAsyncScheduler.cpp
RSX/VK/VKCommandStream.cpp
RSX/VK/VKCommonDecompiler.cpp
@@ -619,6 +629,11 @@ if(TARGET 3rdparty_vulkan)
RSX/VK/VKTextureCache.cpp
RSX/VK/VulkanAPI.cpp
)
if(APPLE)
target_sources(rpcs3_emu PRIVATE
RSX/VK/vkutils/metal_layer.mm
)
endif()
endif()
find_package(Threads REQUIRED)
@@ -651,6 +666,7 @@ target_link_libraries(rpcs3_emu
3rdparty::yaml-cpp
3rdparty::zlib
3rdparty::zstd
3rdparty::libcurl
)
if(APPLE)
+79 -72
View File
@@ -190,7 +190,7 @@ struct cpu_prof
reservation_samples = 0;
}
static std::string format(const std::multimap<u64, u64, std::greater<u64>>& chart, u64 samples, u64 idle, bool extended_print = false)
static std::string format(const std::multimap<u64, u64, std::greater<u64>>& chart, u64 samples, u64 idle, u32 type_id, bool extended_print = false)
{
// Print results
std::string results;
@@ -204,11 +204,18 @@ struct cpu_prof
const f64 _frac = count / busy / samples;
// Print only 7 hash characters out of 11 (which covers roughly 48 bits)
fmt::append(results, "\n\t[%s", fmt::base57(be_t<u64>{name}));
results.resize(results.size() - 4);
if (type_id == 2)
{
fmt::append(results, "\n\t[%s", fmt::base57(be_t<u64>{name}));
results.resize(results.size() - 4);
// Print chunk address from lowest 16 bits
fmt::append(results, "...chunk-0x%05x]: %.4f%% (%u)", (name & 0xffff) * 4, _frac * 100., count);
// Print chunk address from lowest 16 bits
fmt::append(results, "...chunk-0x%05x]: %.4f%% (%u)", (name & 0xffff) * 4, _frac * 100., count);
}
else
{
fmt::append(results, "\n\t[0x%07x]: %.4f%% (%u)", name, _frac * 100., count);
}
if (results.size() >= (extended_print ? 10000 : 5000))
{
@@ -257,27 +264,37 @@ struct cpu_prof
}
// Print results
const std::string results = format(chart, samples, idle);
const std::string results = format(chart, samples, idle, ptr->id_type());
profiler.notice("Thread \"%s\" [0x%08x]: %u samples (%.4f%% idle), %u new, %u reservation (%.4f%%):\n%s", ptr->get_name(), ptr->id, samples, get_percent(idle, samples), new_samples, reservation_samples, get_percent(reservation_samples, samples - idle), results);
new_samples = 0;
}
static void print_all(std::unordered_map<shared_ptr<cpu_thread>, sample_info>& threads, sample_info& all_info)
static void print_all(std::unordered_map<shared_ptr<cpu_thread>, sample_info>& threads, sample_info& all_info, u32 type_id)
{
u64 new_samples = 0;
// Print all results and cleanup
for (auto& [ptr, info] : threads)
{
if (ptr->id_type() != type_id)
{
continue;
}
new_samples += info.new_samples;
info.print(ptr);
}
std::multimap<u64, u64, std::greater<u64>> chart;
for (auto& [_, info] : threads)
for (auto& [ptr, info] : threads)
{
if (ptr->id_type() != type_id)
{
continue;
}
// This function collects thread information regardless of 'new_samples' member state
for (auto& [name, count] : info.freq)
{
@@ -301,7 +318,7 @@ struct cpu_prof
if (new_samples < min_print_all_samples && thread_ctrl::state() != thread_state::aborting)
{
profiler.notice("All Threads: %u samples (%.4f%% idle), %u new, %u reservation (%.4f%%): Not enough new samples have been collected since the last print.", samples, get_percent(idle, samples), new_samples, reservation, get_percent(reservation, samples - idle));
profiler.notice("All %s Threads: %u samples (%.4f%% idle), %u new, %u reservation (%.4f%%): Not enough new samples have been collected since the last print.", type_id == 1 ? "PPU" : "SPU", samples, get_percent(idle, samples), new_samples, reservation, get_percent(reservation, samples - idle));
return;
}
@@ -310,12 +327,13 @@ struct cpu_prof
chart.emplace(count, name);
}
const std::string results = format(chart, samples, idle, true);
profiler.notice("All Threads: %u samples (%.4f%% idle), %u new, %u reservation (%.4f%%):%s", samples, get_percent(idle, samples), new_samples, reservation, get_percent(reservation, samples - idle), results);
const std::string results = format(chart, samples, idle, type_id, true);
profiler.notice("All %s Threads: %u samples (%.4f%% idle), %u new, %u reservation (%.4f%%):%s", type_id == 1 ? "PPU" : "SPU", samples, get_percent(idle, samples), new_samples, reservation, get_percent(reservation, samples - idle), results);
}
};
sample_info all_threads_info{};
sample_info all_spu_threads_info{};
sample_info all_ppu_threads_info{};
void operator()()
{
@@ -376,8 +394,11 @@ struct cpu_prof
{
if (auto state = +ptr->state; cpu_flag::exit - state)
{
const auto spu = ptr->try_get<spu_thread>();
const auto ppu = ptr->try_get<ppu_thread>();
// Get short function hash
const u64 name = atomic_storage<u64>::load(ptr->block_hash);
const u64 name = ppu ? atomic_storage<u32>::load(ppu->cia) : atomic_storage<u64>::load(ptr->block_hash);
// Append occurrence
info.samples++;
@@ -387,17 +408,17 @@ struct cpu_prof
info.freq[name]++;
info.new_samples++;
if (auto spu = ptr->try_get<spu_thread>())
if (spu)
{
if (spu->raddr)
{
info.reservation_samples++;
}
}
// Append verification time to fixed common name 0000000...chunk-0x3fffc
if (name >> 16 && (name & 0xffff) == 0)
info.freq[0xffff]++;
// Append verification time to fixed common name 0000000...chunk-0x3fffc
if (name >> 16 && (name & 0xffff) == 0)
info.freq[0xffff]++;
}
}
else
{
@@ -420,8 +441,10 @@ struct cpu_prof
{
profiler.success("Flushing profiling results...");
all_threads_info = {};
sample_info::print_all(threads, all_threads_info);
all_ppu_threads_info = {};
all_spu_threads_info = {};
sample_info::print_all(threads, all_ppu_threads_info, 1);
sample_info::print_all(threads, all_spu_threads_info, 2);
}
if (Emu.IsPaused())
@@ -442,7 +465,8 @@ struct cpu_prof
}
// Print all remaining results
sample_info::print_all(threads, all_threads_info);
sample_info::print_all(threads, all_ppu_threads_info, 1);
sample_info::print_all(threads, all_spu_threads_info, 2);
}
static constexpr auto thread_name = "CPU Profiler"sv;
@@ -459,7 +483,7 @@ extern f64 get_cpu_program_usage_percent(u64 hash)
{
u64 total = 0;
for (auto [name, count] : prof->all_threads_info.freq)
for (auto [name, count] : prof->all_spu_threads_info.freq)
{
if ((name & -65536) == hash)
{
@@ -472,7 +496,7 @@ extern f64 get_cpu_program_usage_percent(u64 hash)
return 0;
}
return std::max<f64>(0.0001, static_cast<f64>(total) * 100 / (prof->all_threads_info.samples - prof->all_threads_info.idle));
return std::max<f64>(0.0001, static_cast<f64>(total) * 100 / (prof->all_spu_threads_info.samples - prof->all_spu_threads_info.idle));
}
}
@@ -482,7 +506,7 @@ extern f64 get_cpu_program_usage_percent(u64 hash)
thread_local DECLARE(cpu_thread::g_tls_this_thread) = nullptr;
// Total number of CPU threads
static atomic_t<u64, 64> s_cpu_counter{0};
static atomic_t<u64, 128> s_cpu_counter{0};
// List of posted tasks for suspend_all
//static atomic_t<cpu_thread::suspend_work*> s_cpu_work[128]{};
@@ -639,27 +663,22 @@ void cpu_thread::operator()()
thread_ctrl::set_thread_affinity_mask(thread_ctrl::get_affinity_mask(get_class()));
}
while (!g_fxo->is_init<cpu_profiler>())
{
if (Emu.IsStopped())
{
return;
}
// Can we have a little race, right? First thread is started concurrently with g_fxo->init()
thread_ctrl::wait_for(1000);
}
ensure(g_fxo->is_init<cpu_profiler>());
switch (get_class())
{
case thread_class::ppu:
{
//g_fxo->get<cpu_profiler>().registered.push(id);
if (g_cfg.core.ppu_prof)
{
g_fxo->get<cpu_profiler>().registered.push(id);
}
break;
}
case thread_class::spu:
{
if (g_cfg.core.spu_prof)
if (g_cfg.core.spu_prof || g_cfg.core.spu_debug)
{
g_fxo->get<cpu_profiler>().registered.push(id);
}
@@ -1546,7 +1565,7 @@ void cpu_thread::flush_profilers() noexcept
return;
}
if (g_cfg.core.spu_prof)
if (g_cfg.core.spu_prof || g_cfg.core.spu_debug || g_cfg.core.ppu_prof)
{
g_fxo->get<cpu_profiler>().registered.push(0);
}
@@ -1585,22 +1604,30 @@ extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool reve
idm::select<named_thread<spu_thread>>([&](u32 id, spu_thread& spu)
{
spu_list.emplace_back(ensure(idm::get_unlocked<named_thread<spu_thread>>(id)));
if (give_up)
{
return;
}
if (spu.current_func && spu.unsavable)
if (spu.current_func && spu.unsavable && !force_collect)
{
const u64 start = spu.start_time;
// Automatically give up if it is asleep 15 seconds or more
if (start && current > start && current - start >= 15'000'000)
// Automatically give up if it is asleep 5 seconds or more
if (start && current > start && current - start >= 5'000'000)
{
give_up = true;
return;
}
}
spu_list.emplace_back(ensure(idm::get_unlocked<named_thread<spu_thread>>(id)));
});
if (!force_collect && give_up)
if (give_up)
{
spu_list.clear();
old_counter = umax;
return decltype(&spu_list){};
}
@@ -1625,6 +1652,7 @@ extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool reve
}
else if (get_system_time() - start >= 150'000)
{
std::this_thread::sleep_for(1ms);
passed_count++;
start = 0;
continue;
@@ -1636,37 +1664,29 @@ extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool reve
if (!spu_list)
{
// Give up for now
std::this_thread::sleep_for(10ms);
std::this_thread::sleep_for(50ms);
passed_count++;
start = 0;
continue;
}
// Avoid using suspend_all when more than 2 threads known to be unsavable
u32 unsavable_threads = 0;
u32 savable_threads = 0;
for (auto& spu : *spu_list)
{
if (spu->unsavable)
if (!spu->unsavable)
{
unsavable_threads++;
if (unsavable_threads >= 3)
{
break;
}
savable_threads++;
}
}
if (unsavable_threads >= 3)
if (!savable_threads)
{
std::this_thread::yield();
continue;
}
// Flag for optimization
bool paused_anyone = false;
if (cpu_thread::suspend_all(nullptr, {}, [&]()
{
if (!get_spus(false, true))
@@ -1695,19 +1715,13 @@ extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool reve
break;
}
}
else
{
paused_anyone = true;
ensure(!spu->state.test_and_set(cpu_flag::dbg_global_pause));
}
}
if (failed && paused_anyone)
for (auto& spu : *spu_list)
{
// For faster signalling, first remove state flags then batch notifications
for (auto& spu : *spu_list)
if (!failed && !is_emu_paused)
{
spu->state -= cpu_flag::dbg_global_pause;
ensure(!spu->state.test_and_set(cpu_flag::dbg_global_pause));
}
}
@@ -1719,13 +1733,6 @@ extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool reve
return false;
}
if (!paused_anyone)
{
// Need not do anything
std::this_thread::yield();
continue;
}
for (auto& spu : *spu_list)
{
if (spu->state & cpu_flag::wait)
@@ -1755,7 +1762,7 @@ extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool reve
{
spu->state.notify_one();
}
};
}
return false;
}
+4
View File
@@ -71,7 +71,11 @@ cpu_translator::cpu_translator(llvm::Module* _module, bool is_be)
result = m_ir->CreateInsertElement(v, m_ir->CreateExtractElement(data0, m_ir->CreateExtractElement(mask, i)), i);
v->addIncoming(result, loop);
m_ir->CreateCondBr(m_ir->CreateICmpULT(i, m_ir->getInt32(16)), loop, next);
#if LLVM_VERSION_MAJOR >= 21 || (LLVM_VERSION_MAJOR == 20 && LLVM_VERSION_MINOR >= 1)
m_ir->SetInsertPoint(next->getFirstNonPHIIt());
#else
m_ir->SetInsertPoint(next->getFirstNonPHI());
#endif
result = m_ir->CreateSelect(m_ir->CreateICmpSLT(index, zeros), zeros, result);
return result;
+21 -1
View File
@@ -1149,7 +1149,11 @@ struct llvm_fshl
static llvm::Function* get_fshl(llvm::IRBuilder<>* ir)
{
const auto _module = ir->GetInsertBlock()->getParent()->getParent();
#if LLVM_VERSION_MAJOR >= 21 || (LLVM_VERSION_MAJOR == 20 && LLVM_VERSION_MINOR >= 1)
return llvm::Intrinsic::getOrInsertDeclaration(_module, llvm::Intrinsic::fshl, {llvm_value_t<T>::get_type(ir->getContext())});
#else
return llvm::Intrinsic::getDeclaration(_module, llvm::Intrinsic::fshl, {llvm_value_t<T>::get_type(ir->getContext())});
#endif
}
static llvm::Value* fold(llvm::IRBuilder<>* ir, llvm::Value* v1, llvm::Value* v2, llvm::Value* v3)
@@ -1221,7 +1225,11 @@ struct llvm_fshr
static llvm::Function* get_fshr(llvm::IRBuilder<>* ir)
{
const auto _module = ir->GetInsertBlock()->getParent()->getParent();
#if LLVM_VERSION_MAJOR >= 21 || (LLVM_VERSION_MAJOR == 20 && LLVM_VERSION_MINOR >= 1)
return llvm::Intrinsic::getOrInsertDeclaration(_module, llvm::Intrinsic::fshr, {llvm_value_t<T>::get_type(ir->getContext())});
#else
return llvm::Intrinsic::getDeclaration(_module, llvm::Intrinsic::fshr, {llvm_value_t<T>::get_type(ir->getContext())});
#endif
}
static llvm::Value* fold(llvm::IRBuilder<>* ir, llvm::Value* v1, llvm::Value* v2, llvm::Value* v3)
@@ -2220,7 +2228,11 @@ struct llvm_add_sat
static llvm::Function* get_add_sat(llvm::IRBuilder<>* ir)
{
const auto _module = ir->GetInsertBlock()->getParent()->getParent();
#if LLVM_VERSION_MAJOR >= 21 || (LLVM_VERSION_MAJOR == 20 && LLVM_VERSION_MINOR >= 1)
return llvm::Intrinsic::getOrInsertDeclaration(_module, intr, {llvm_value_t<T>::get_type(ir->getContext())});
#else
return llvm::Intrinsic::getDeclaration(_module, intr, {llvm_value_t<T>::get_type(ir->getContext())});
#endif
}
llvm::Value* eval(llvm::IRBuilder<>* ir) const
@@ -2303,7 +2315,11 @@ struct llvm_sub_sat
static llvm::Function* get_sub_sat(llvm::IRBuilder<>* ir)
{
const auto _module = ir->GetInsertBlock()->getParent()->getParent();
#if LLVM_VERSION_MAJOR >= 21 || (LLVM_VERSION_MAJOR == 20 && LLVM_VERSION_MINOR >= 1)
return llvm::Intrinsic::getOrInsertDeclaration(_module, intr, {llvm_value_t<T>::get_type(ir->getContext())});
#else
return llvm::Intrinsic::getDeclaration(_module, intr, {llvm_value_t<T>::get_type(ir->getContext())});
#endif
}
llvm::Value* eval(llvm::IRBuilder<>* ir) const
@@ -3592,7 +3608,11 @@ public:
llvm::Function* get_intrinsic(llvm::Intrinsic::ID id)
{
const auto _module = m_ir->GetInsertBlock()->getParent()->getParent();
#if LLVM_VERSION_MAJOR >= 21 || (LLVM_VERSION_MAJOR == 20 && LLVM_VERSION_MINOR >= 1)
return llvm::Intrinsic::getOrInsertDeclaration(_module, id, {get_type<Types>()...});
#else
return llvm::Intrinsic::getDeclaration(_module, id, {get_type<Types>()...});
#endif
}
template <typename T1, typename T2>
@@ -4007,7 +4027,7 @@ llvm::CallInst* llvm_asm(
const std::string& constraints,
llvm::LLVMContext& context)
{
llvm::ArrayRef<llvm::Type*> types_ref = std::nullopt;
llvm::ArrayRef<llvm::Type*> types_ref {};
std::vector<llvm::Type*> types;
types.reserve(args.size());
+35 -29
View File
@@ -111,7 +111,41 @@ void AtracXdecDecoder::alloc_avcodec()
fmt::throw_exception("avcodec_find_decoder() failed");
}
ensure(!(codec->capabilities & AV_CODEC_CAP_SUBFRAMES));
packet = av_packet_alloc();
if (!packet)
{
fmt::throw_exception("av_packet_alloc() failed");
}
frame = av_frame_alloc();
if (!frame)
{
fmt::throw_exception("av_frame_alloc() failed");
}
}
void AtracXdecDecoder::free_avcodec()
{
if (packet)
{
av_packet_free(&packet);
}
if (frame)
{
av_frame_free(&frame);
}
if (ctx)
{
avcodec_free_context(&ctx);
}
}
void AtracXdecDecoder::init_avcodec()
{
if (ctx)
{
avcodec_free_context(&ctx);
}
ctx = avcodec_alloc_context3(codec);
if (!ctx)
@@ -133,34 +167,6 @@ void AtracXdecDecoder::alloc_avcodec()
frame->buf[0] = av_buffer_create(frame->data[0], ATXDEC_SAMPLES_PER_FRAME * sizeof(f32) * frame->ch_layout.nb_channels, [](void*, uint8_t*){}, nullptr, 0);
return 0;
};
packet = av_packet_alloc();
if (!packet)
{
fmt::throw_exception("av_packet_alloc() failed");
}
frame = av_frame_alloc();
if (!frame)
{
fmt::throw_exception("av_frame_alloc() failed");
}
}
void AtracXdecDecoder::free_avcodec()
{
av_packet_free(&packet);
av_frame_free(&frame);
avcodec_free_context(&ctx);
}
void AtracXdecDecoder::init_avcodec()
{
if (int err = avcodec_close(ctx); err)
{
fmt::throw_exception("avcodec_close() failed (err=0x%x='%s')", err, utils::av_error_to_string(err));
}
ctx->block_align = nbytes;
ctx->ch_layout.nb_channels = nch_in;
ctx->sample_rate = sampling_freq;
+4 -4
View File
@@ -192,10 +192,10 @@ struct AtracXdecDecoder
// HLE exclusive
b8 config_is_set = false; // For savestates
const AVCodec* codec;
AVCodecContext* ctx;
AVPacket* packet;
AVFrame* frame;
const AVCodec* codec = nullptr;
AVCodecContext* ctx = nullptr;
AVPacket* packet = nullptr;
AVFrame* frame = nullptr;
u8 spurs_stuff[84]; // 120 bytes on LLE, pointers to CellSpurs, CellSpursTaskset, etc.
+11 -3
View File
@@ -1139,8 +1139,10 @@ error_code cellCameraGetBufferInfo(s32 dev_num, vm::ptr<CellCameraInfo> info)
return CELL_OK;
}
error_code cellCameraGetBufferInfoEx(s32 dev_num, vm::ptr<CellCameraInfoEx> info)
error_code cellCameraGetBufferInfoEx(ppu_thread& ppu, s32 dev_num, vm::ptr<CellCameraInfoEx> info)
{
ppu.state += cpu_flag::wait;
cellCamera.notice("cellCameraGetBufferInfoEx(dev_num=%d, info=0x%x)", dev_num, info);
// calls cellCameraGetBufferInfo
@@ -1151,10 +1153,16 @@ error_code cellCameraGetBufferInfoEx(s32 dev_num, vm::ptr<CellCameraInfoEx> info
}
auto& g_camera = g_fxo->get<camera_thread>();
std::lock_guard lock(g_camera.mutex);
*info = g_camera.info;
CellCameraInfoEx info_out;
{
std::lock_guard lock(g_camera.mutex);
info_out = g_camera.info;
}
*info = info_out;
return CELL_OK;
}
+22 -11
View File
@@ -464,6 +464,8 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
{
get->isNewData = CELL_HDDGAME_ISNEWDATA_NODIR;
get->getParam = {};
cellGame.warning("cellHddGameCheck(): New data.");
}
else
{
@@ -476,13 +478,22 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
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());
// Old games do not have APP_VER key
strcpy_trunc(get->getParam.dataVersion, psf::get_string(psf, "APP_VER", psf::get_string(sfo, "VERSION", "")));
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++)
{
strcpy_trunc(get->getParam.titleLang[i], psf::get_string(psf, fmt::format("TITLE_%02d", i)));
}
cellGame.warning("cellHddGameCheck(): Data exists:\nATTRIBUTE: 0x%x, RESOLUTION: 0x%x, RESOLUTION: 0x%x, SOUND_FORMAT: 0x%x, dataVersion: %s"
, get->getParam.attribute, get->getParam.resolution, get->getParam.soundFormat, get->getParam.soundFormat, std::span<const u8>(reinterpret_cast<const u8*>(get->getParam.dataVersion), 6));
}
// TODO ?
@@ -550,7 +561,7 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
case CELL_HDDGAME_CBRESULT_ERR_NOSPACE:
cellGame.error("cellHddGameCheck(): callback returned CELL_HDDGAME_CBRESULT_ERR_NOSPACE. Space Needed: %d KB", result->errNeedSizeKB);
error_msg = get_localized_string(localized_string_id::CELL_HDD_GAME_CHECK_NOSPACE, fmt::format("%d", result->errNeedSizeKB).c_str());
error_msg = get_localized_string(localized_string_id::CELL_HDD_GAME_CHECK_NOSPACE, "%d", result->errNeedSizeKB);
break;
case CELL_HDDGAME_CBRESULT_ERR_BROKEN:
@@ -565,12 +576,12 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
case CELL_HDDGAME_CBRESULT_ERR_INVALID:
cellGame.error("cellHddGameCheck(): callback returned CELL_HDDGAME_CBRESULT_ERR_INVALID. Error message: %s", result->invalidMsg);
error_msg = get_localized_string(localized_string_id::CELL_HDD_GAME_CHECK_INVALID, fmt::format("%s", result->invalidMsg).c_str());
error_msg = get_localized_string(localized_string_id::CELL_HDD_GAME_CHECK_INVALID, "%s", result->invalidMsg);
break;
default:
cellGame.error("cellHddGameCheck(): callback returned unknown error (code=0x%x). Error message: %s", result->invalidMsg);
error_msg = get_localized_string(localized_string_id::CELL_HDD_GAME_CHECK_INVALID, fmt::format("%s", result->invalidMsg).c_str());
error_msg = get_localized_string(localized_string_id::CELL_HDD_GAME_CHECK_INVALID, "%s", result->invalidMsg);
break;
}
@@ -1169,7 +1180,7 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
}
case CELL_GAMEDATA_CBRESULT_ERR_NOSPACE:
cellGame.error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NOSPACE. Space Needed: %d KB", cbResult->errNeedSizeKB);
error_msg = get_localized_string(localized_string_id::CELL_GAMEDATA_CHECK_NOSPACE, fmt::format("%d", cbResult->errNeedSizeKB).c_str());
error_msg = get_localized_string(localized_string_id::CELL_GAMEDATA_CHECK_NOSPACE, "%d", cbResult->errNeedSizeKB);
break;
case CELL_GAMEDATA_CBRESULT_ERR_BROKEN:
@@ -1184,12 +1195,12 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
case CELL_GAMEDATA_CBRESULT_ERR_INVALID:
cellGame.error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_INVALID. Error message: %s", cbResult->invalidMsg);
error_msg = get_localized_string(localized_string_id::CELL_GAMEDATA_CHECK_INVALID, fmt::format("%s", cbResult->invalidMsg).c_str());
error_msg = get_localized_string(localized_string_id::CELL_GAMEDATA_CHECK_INVALID, "%s", cbResult->invalidMsg);
break;
default:
cellGame.error("cellGameDataCheckCreate2(): callback returned unknown error (code=0x%x). Error message: %s", cbResult->invalidMsg);
error_msg = get_localized_string(localized_string_id::CELL_GAMEDATA_CHECK_INVALID, fmt::format("%s", cbResult->invalidMsg).c_str());
error_msg = get_localized_string(localized_string_id::CELL_GAMEDATA_CHECK_INVALID, "%s", cbResult->invalidMsg);
break;
}
@@ -1686,7 +1697,7 @@ error_code cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::cptr<char
break;
case CELL_GAME_ERRDIALOG_NOSPACE:
// Not enough available space. The application will continue.
error_msg = get_localized_string(localized_string_id::CELL_GAME_ERROR_NOSPACE, fmt::format("%d", errNeedSizeKB).c_str());
error_msg = get_localized_string(localized_string_id::CELL_GAME_ERROR_NOSPACE, "%d", errNeedSizeKB);
break;
case CELL_GAME_ERRDIALOG_BROKEN_EXIT_GAMEDATA:
// Game data is corrupted. The application will be terminated.
@@ -1698,7 +1709,7 @@ error_code cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::cptr<char
break;
case CELL_GAME_ERRDIALOG_NOSPACE_EXIT:
// Not enough available space. The application will be terminated.
error_msg = get_localized_string(localized_string_id::CELL_GAME_ERROR_NOSPACE_EXIT, fmt::format("%d", errNeedSizeKB).c_str());
error_msg = get_localized_string(localized_string_id::CELL_GAME_ERROR_NOSPACE_EXIT, "%d", errNeedSizeKB);
break;
default:
return CELL_GAME_ERROR_PARAM;
@@ -1712,7 +1723,7 @@ error_code cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::cptr<char
}
error_msg += '\n';
error_msg += get_localized_string(localized_string_id::CELL_GAME_ERROR_DIR_NAME, fmt::format("%s", dirName).c_str());
error_msg += get_localized_string(localized_string_id::CELL_GAME_ERROR_DIR_NAME, "%s", dirName);
}
return open_exit_dialog(error_msg, type > CELL_GAME_ERRDIALOG_NOSPACE, msg_dialog_source::_cellGame);
+9 -9
View File
@@ -224,8 +224,8 @@ enum
struct CellGameDataSystemFileParam
{
char title[CELL_GAMEDATA_SYSP_TITLE_SIZE];
char titleLang[CELL_GAMEDATA_SYSP_LANGUAGE_NUM][CELL_GAMEDATA_SYSP_TITLE_SIZE];
char titleId[CELL_GAMEDATA_SYSP_TITLEID_SIZE];
char titleLang[CELL_GAMEDATA_SYSP_LANGUAGE_NUM][CELL_GAMEDATA_SYSP_TITLE_SIZE]; // 0x80
char titleId[CELL_GAMEDATA_SYSP_TITLEID_SIZE]; // 0xA80
char reserved0[2];
char dataVersion[CELL_GAMEDATA_SYSP_VERSION_SIZE];
char reserved1[2];
@@ -248,13 +248,13 @@ struct CellGameDataStatGet
{
be_t<s32> hddFreeSizeKB;
be_t<u32> isNewData;
char contentInfoPath[CELL_GAMEDATA_PATH_MAX];
char gameDataPath[CELL_GAMEDATA_PATH_MAX];
char reserved0[2];
be_t<s64> st_atime_;
be_t<s64> st_mtime_;
be_t<s64> st_ctime_;
CellGameDataSystemFileParam getParam;
char contentInfoPath[CELL_GAMEDATA_PATH_MAX]; // 0x8
char gameDataPath[CELL_GAMEDATA_PATH_MAX]; // 0x427
char reserved0[2]; // 0x846
be_t<s64> st_atime_; // 0x848
be_t<s64> st_mtime_; // 0x850
be_t<s64> st_ctime_; // 0x858
CellGameDataSystemFileParam getParam; // 0x860
be_t<s32> sizeKB;
be_t<s32> sysSizeKB;
char reserved1[68];
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -246,15 +246,15 @@ struct CellGemInfo
// z increases towards user (away from the camera)
struct CellGemState
{
be_t<f32> pos[4]; // center of sphere (mm)
be_t<f32> vel[4]; // velocity of sphere (mm/s)
be_t<f32> accel[4]; // acceleration of sphere (mm/s²)
be_t<f32> pos[4]; // center of sphere in world coordinates (mm)
be_t<f32> vel[4]; // velocity of sphere in world coordinates (mm/s)
be_t<f32> accel[4]; // acceleration of sphere in world coordinates (mm/s²)
be_t<f32> quat[4]; // quaternion orientation (x,y,z,w) of controller relative to default (facing the camera with buttons up)
be_t<f32> angvel[4]; // angular velocity of controller (radians/s)
be_t<f32> angaccel[4]; // angular acceleration of controller (radians/s²)
be_t<f32> handle_pos[4]; // center of controller handle (mm)
be_t<f32> handle_vel[4]; // velocity of controller handle (mm/s)
be_t<f32> handle_accel[4]; // acceleration of controller handle (mm/s²)
be_t<f32> angvel[4]; // angular velocity of controller in world coordinates (radians/s)
be_t<f32> angaccel[4]; // angular acceleration of controller in world coordinates (radians/s²)
be_t<f32> handle_pos[4]; // center of controller handle in world coordinates (mm)
be_t<f32> handle_vel[4]; // velocity of controller handle in world coordinates (mm/s)
be_t<f32> handle_accel[4]; // acceleration of controller handle in world coordinates (mm/s²)
CellGemPadData pad;
CellGemExtPortData ext;
be_t<u64> timestamp; // system_time_t (microseconds)
+1 -1
View File
@@ -2498,7 +2498,7 @@ s32 UCS2stoSBCSs(vm::cptr<u16> src, vm::ptr<u32> src_len, vm::ptr<u8> dst, vm::p
for (u32 src_pos = 0; src_pos < *src_len; src_pos++)
{
const s16 ucs2 = src[src_pos];
const u16 ucs2 = src[src_pos];
if (ucs2 >= 0xfffe)
{
+1 -1
View File
@@ -506,7 +506,7 @@ error_code cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr<CellMsgDialogCallba
default: string_id = localized_string_id::CELL_MSG_DIALOG_ERROR_DEFAULT; break; // An error has occurred.
}
const std::string error = get_localized_string(string_id, fmt::format("%08x", errorCode).c_str());
const std::string error = get_localized_string(string_id, "%08x", errorCode);
return cellMsgDialogOpen2(CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK, vm::make_str(error), callback, userData, extParam);
}
+1 -1
View File
@@ -215,7 +215,7 @@ error_code cell_music_select_contents()
const std::string vfs_dir_path = vfs::get("/dev_hdd0/music");
const std::string title = get_localized_string(localized_string_id::RSX_OVERLAYS_MEDIA_DIALOG_TITLE);
error_code error = rsx::overlays::show_media_list_dialog(rsx::overlays::media_list_dialog::media_type::audio, vfs_dir_path, title,
error_code error = rsx::overlays::show_media_list_dialog(rsx::overlays::media_list_dialog::media_type::audio, music_selection_context::max_depth, vfs_dir_path, title,
[&music](s32 status, utils::media_info info)
{
sysutil_register_cb([&music, info = std::move(info), status](ppu_thread& ppu) -> s32
+1 -1
View File
@@ -134,7 +134,7 @@ error_code cell_music_decode_select_contents()
const std::string vfs_dir_path = vfs::get("/dev_hdd0/music");
const std::string title = get_localized_string(localized_string_id::RSX_OVERLAYS_MEDIA_DIALOG_TITLE);
error_code error = rsx::overlays::show_media_list_dialog(rsx::overlays::media_list_dialog::media_type::audio, vfs_dir_path, title,
error_code error = rsx::overlays::show_media_list_dialog(rsx::overlays::media_list_dialog::media_type::audio, music_selection_context::max_depth, vfs_dir_path, title,
[&dec](s32 status, utils::media_info info)
{
sysutil_register_cb([&dec, info = std::move(info), status](ppu_thread& ppu) -> s32
+14 -6
View File
@@ -575,12 +575,12 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
if (setting & CELL_PAD_SETTING_PRESS_ON)
{
constexpr u32 copy_size = (CELL_PAD_LEN_CHANGE_PRESS_ON - CELL_PAD_BTN_OFFSET_DIGITAL1) * sizeof(u16);
constexpr u32 copy_size = (static_cast<u32>(CELL_PAD_LEN_CHANGE_PRESS_ON) - static_cast<u32>(CELL_PAD_BTN_OFFSET_DIGITAL1)) * sizeof(u16);
std::memcpy(&data->button[CELL_PAD_BTN_OFFSET_DIGITAL1], &output.button[CELL_PAD_BTN_OFFSET_DIGITAL1], copy_size);
}
else
{
constexpr u32 copy_size = (CELL_PAD_LEN_CHANGE_DEFAULT - CELL_PAD_BTN_OFFSET_DIGITAL1) * sizeof(u16);
constexpr u32 copy_size = (static_cast<u32>(CELL_PAD_LEN_CHANGE_DEFAULT) - static_cast<u32>(CELL_PAD_BTN_OFFSET_DIGITAL1)) * sizeof(u16);
std::memcpy(&data->button[CELL_PAD_BTN_OFFSET_DIGITAL1], &output.button[CELL_PAD_BTN_OFFSET_DIGITAL1], copy_size);
// Clear area if setting is not used
@@ -590,7 +590,7 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
if (data->len == CELL_PAD_LEN_CHANGE_SENSOR_ON)
{
constexpr u32 copy_size = (CELL_PAD_LEN_CHANGE_SENSOR_ON - CELL_PAD_BTN_OFFSET_SENSOR_X) * sizeof(u16);
constexpr u32 copy_size = (static_cast<u32>(CELL_PAD_LEN_CHANGE_SENSOR_ON) - static_cast<u32>(CELL_PAD_BTN_OFFSET_SENSOR_X)) * sizeof(u16);
std::memcpy(&data->button[CELL_PAD_BTN_OFFSET_SENSOR_X], &output.button[CELL_PAD_BTN_OFFSET_SENSOR_X], copy_size);
}
}
@@ -1051,7 +1051,15 @@ error_code cellPadSetPortSetting(u32 port_no, u32 port_setting)
if (port_no >= CELL_PAD_MAX_PORT_NUM)
return CELL_OK;
config.port_setting[port_no] = port_setting;
if (port_setting & CELL_PAD_SETTING_PRESS_ON)
config.port_setting[port_no] |= CELL_PAD_SETTING_PRESS_ON;
else
config.port_setting[port_no] &= ~CELL_PAD_SETTING_PRESS_ON;
if (port_setting & CELL_PAD_SETTING_SENSOR_ON)
config.port_setting[port_no] |= CELL_PAD_SETTING_SENSOR_ON;
else
config.port_setting[port_no] &= ~CELL_PAD_SETTING_SENSOR_ON;
// can also return CELL_PAD_ERROR_UNSUPPORTED_GAMEPAD <- Update: seems to be just internal and ignored
@@ -1123,7 +1131,7 @@ error_code cellPadSetPressMode(u32 port_no, u32 mode)
if (!config.max_connect)
return CELL_PAD_ERROR_UNINITIALIZED;
if (port_no >= CELL_PAD_MAX_PORT_NUM)
if (port_no >= CELL_MAX_PADS || mode > 1)
return CELL_PAD_ERROR_INVALID_PARAMETER;
// CELL_PAD_ERROR_NO_DEVICE is not returned in this case.
@@ -1157,7 +1165,7 @@ error_code cellPadSetSensorMode(u32 port_no, u32 mode)
if (!config.max_connect)
return CELL_PAD_ERROR_UNINITIALIZED;
if (port_no >= CELL_MAX_PADS)
if (port_no >= CELL_MAX_PADS || mode > 1)
return CELL_PAD_ERROR_INVALID_PARAMETER;
// CELL_PAD_ERROR_NO_DEVICE is not returned in this case.
+7 -20
View File
@@ -1,5 +1,6 @@
#include "stdafx.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/VFS.h"
#include "cellSysutil.h"
@@ -107,30 +108,16 @@ bool check_photo_path(const std::string& file_path)
return true;
}
std::string get_available_photo_path(const std::string& filename)
std::string get_available_photo_path(std::string_view filename)
{
const std::string photo_dir = "/dev_hdd0/photo/";
std::string dst_path = vfs::get(photo_dir + filename);
// Do not overwrite existing files. Add a suffix instead.
for (u32 i = 0; fs::exists(dst_path); i++)
std::string_view extension = ".png";
if (const auto extension_start = filename.find_last_of('.');
extension_start != umax)
{
const std::string suffix = fmt::format("_%d", i);
std::string new_filename = filename;
if (const usz pos = new_filename.find_last_of('.'); pos != std::string::npos)
{
new_filename.insert(pos, suffix);
}
else
{
new_filename.append(suffix);
}
dst_path = vfs::get(photo_dir + new_filename);
extension = filename.substr(extension_start);
}
return dst_path;
return Emu.GetCallbacks().get_photo_path(fmt::format("%s%s", Emu.GetTitle(), extension));
}
+22 -3
View File
@@ -142,7 +142,7 @@ error_code select_photo(std::string dst_dir)
const std::string vfs_dir_path = vfs::get("/dev_hdd0/photo");
const std::string title = get_localized_string(localized_string_id::RSX_OVERLAYS_MEDIA_DIALOG_TITLE_PHOTO_IMPORT);
error_code error = rsx::overlays::show_media_list_dialog(rsx::overlays::media_list_dialog::media_type::photo, vfs_dir_path, title,
error_code error = rsx::overlays::show_media_list_dialog(rsx::overlays::media_list_dialog::media_type::photo, umax, vfs_dir_path, title,
[&pi_manager, dst_dir](s32 status, utils::media_info info)
{
sysutil_register_cb([&pi_manager, dst_dir, info, status](ppu_thread& ppu) -> s32
@@ -176,10 +176,29 @@ error_code select_photo(std::string dst_dir)
const std::string filename = info.path.substr(info.path.find_last_of(fs::delim) + 1);
const std::string title = info.get_metadata("title", filename);
const std::string dst_path = dst_dir + "/" + filename;
std::string dst_path = dst_dir + "/";
std::string sub_type = info.sub_type;
strcpy_trunc(g_filedata->dstFileName, filename);
// Try to find a unique filename (TODO: how does the PS3 copy the files exactly?)
std::string extension;
std::string dst_filename = filename;
if (const auto extension_start = filename.find_last_of('.');
extension_start != umax)
{
extension = filename.substr(extension_start);
dst_filename = filename.substr(0, extension_start);
}
std::string suffix = extension;
u32 counter = 0;
while (!Emu.IsStopped() && fs::is_file(dst_path + dst_filename + suffix))
{
suffix = fmt::format(" %d%s", ++counter, extension);
}
dst_filename += std::move(suffix);
dst_path += dst_filename;
strcpy_trunc(g_filedata->dstFileName, dst_filename);
strcpy_trunc(g_filedata->photo_title, title);
strcpy_trunc(g_filedata->game_title, Emu.GetTitle());
strcpy_trunc(g_filedata->game_comment, ""); // TODO
+1 -1
View File
@@ -396,7 +396,7 @@ static error_code display_callback_result_error_message(ppu_thread& ppu, const C
switch (result.result)
{
case CELL_SAVEDATA_CBRESULT_ERR_NOSPACE:
msg = get_localized_string(localized_string_id::CELL_SAVEDATA_CB_NO_SPACE, fmt::format("%d", result.errNeedSizeKB).c_str());
msg = get_localized_string(localized_string_id::CELL_SAVEDATA_CB_NO_SPACE, "%d", result.errNeedSizeKB);
break;
case CELL_SAVEDATA_CBRESULT_ERR_FAILURE:
msg = get_localized_string(localized_string_id::CELL_SAVEDATA_CB_FAILURE);
+2 -22
View File
@@ -33,18 +33,12 @@ std::string screenshot_info::get_overlay_path() const
std::string screenshot_info::get_photo_title() const
{
std::string photo = photo_title;
if (photo.empty())
photo = Emu.GetTitle();
return photo;
return photo_title.empty() ? Emu.GetTitle() : photo_title;
}
std::string screenshot_info::get_game_title() const
{
std::string game = game_title;
if (game.empty())
game = Emu.GetTitle();
return game;
return game_title.empty() ? Emu.GetTitle() : game_title;
}
std::string screenshot_info::get_game_comment() const
@@ -52,20 +46,6 @@ std::string screenshot_info::get_game_comment() const
return game_comment;
}
std::string screenshot_info::get_screenshot_path(const std::string& date_path) const
{
u32 counter = 0;
std::string path = vfs::get("/dev_hdd0/photo/" + date_path + "/" + get_photo_title());
std::string suffix = ".png";
while (!Emu.IsStopped() && fs::is_file(path + suffix))
{
suffix = fmt::format("_%d.png", ++counter);
}
return path + suffix;
}
error_code cellScreenShotSetParameter(vm::cptr<CellScreenShotSetParam> param)
{
-1
View File
@@ -44,7 +44,6 @@ struct screenshot_info
std::string get_photo_title() const;
std::string get_game_title() const;
std::string get_game_comment() const;
std::string get_screenshot_path(const std::string& date_path) const;
};
struct screenshot_manager : public screenshot_info
+1 -1
View File
@@ -1230,7 +1230,7 @@ s32 _spurs::initialize(ppu_thread& ppu, vm::ptr<CellSpurs> spurs, u32 revision,
if (flags & SAF_UNKNOWN_FLAG_9) spuTgAttr->type |= 0x0800;
if (flags & SAF_SYSTEM_WORKLOAD_ENABLED) spuTgAttr->type |= SYS_SPU_THREAD_GROUP_TYPE_COOPERATE_WITH_SYSTEM;
if (s32 rc = sys_spu_thread_group_create(ppu, spurs.ptr(&CellSpurs::spuTG), nSpus, spuPriority, spuTgAttr))
if (s32 rc = sys_spu_thread_group_create(ppu, spurs.ptr(&CellSpurs::spuTG), nSpus, spuPriority, vm::unsafe_ptr_cast<reduced_sys_spu_thread_group_attribute>(spuTgAttr)))
{
ppu_execute<&sys_spu_image_close>(ppu, spurs.ptr(&CellSpurs::spuImg));
return rollback(), rc;
+13 -7
View File
@@ -3198,7 +3198,7 @@ error_code sceNpLookupTerm()
error_code sceNpLookupCreateTitleCtx(vm::cptr<SceNpCommunicationId> communicationId, vm::cptr<SceNpId> selfNpId)
{
sceNp.warning("sceNpLookupCreateTitleCtx(communicationId=*0x%x(%s), selfNpId=0x%x)", communicationId, communicationId ? communicationId->data : "", selfNpId);
sceNp.warning("sceNpLookupCreateTitleCtx(communicationId=*0x%x(%s), selfNpId=0x%x)", communicationId, communicationId ? std::string_view(communicationId->data, 9) : "", selfNpId);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
@@ -3930,8 +3930,8 @@ error_code sceNpManagerGetMyLanguages(vm::ptr<SceNpMyLanguages> myLanguages)
return SCE_NP_ERROR_INVALID_STATE;
}
myLanguages->language1 = SCE_NP_LANG_ENGLISH_US;
myLanguages->language2 = g_cfg.sys.language != CELL_SYSUTIL_LANG_ENGLISH_US ? g_cfg.sys.language : -1;
myLanguages->language1 = g_cfg.sys.language;
myLanguages->language2 = g_cfg.sys.language != CELL_SYSUTIL_LANG_ENGLISH_US ? CELL_SYSUTIL_LANG_ENGLISH_US : -1;
myLanguages->language3 = -1;
return CELL_OK;
@@ -3968,7 +3968,7 @@ error_code sceNpManagerGetAccountRegion(vm::ptr<SceNpCountryCode> countryCode, v
ensure(ccode.size() == sizeof(SceNpCountryCode::data));
std::memcpy(countryCode->data, ccode.data(), sizeof(SceNpCountryCode::data));
*language = CELL_SYSUTIL_LANG_ENGLISH_US;
*language = g_cfg.sys.language;
return CELL_OK;
}
@@ -6962,7 +6962,7 @@ error_code sceNpSignalingGetConnectionFromPeerAddress(u32 ctx_id, np_in_addr_t p
return CELL_OK;
}
error_code sceNpSignalingGetLocalNetInfo(u32 ctx_id, vm::ptr<SceNpSignalingNetInfo> info)
error_code sceNpSignalingGetLocalNetInfo(u32 ctx_id, vm::ptr<SceNpSignalingNetInfoDeprecated> info)
{
sceNp.warning("sceNpSignalingGetLocalNetInfo(ctx_id=%d, info=*0x%x)", ctx_id, info);
@@ -6973,7 +6973,8 @@ error_code sceNpSignalingGetLocalNetInfo(u32 ctx_id, vm::ptr<SceNpSignalingNetIn
return SCE_NP_SIGNALING_ERROR_NOT_INITIALIZED;
}
if (!info || info->size != sizeof(SceNpSignalingNetInfo))
// Library has backward support for a version of SceNpSignalingNetInfo without npport
if (!info || (info->size != sizeof(SceNpSignalingNetInfo) && info->size != sizeof(SceNpSignalingNetInfoDeprecated)))
{
return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT;
}
@@ -6985,7 +6986,12 @@ error_code sceNpSignalingGetLocalNetInfo(u32 ctx_id, vm::ptr<SceNpSignalingNetIn
info->nat_status = SCE_NP_SIGNALING_NETINFO_NAT_STATUS_TYPE2;
info->upnp_status = nph.get_upnp_status();
info->npport_status = SCE_NP_SIGNALING_NETINFO_NPPORT_STATUS_OPEN;
info->npport = SCE_NP_PORT;
if (info->size == sizeof(SceNpSignalingNetInfo))
{
auto new_info = vm::unsafe_ptr_cast<SceNpSignalingNetInfo>(info);
new_info->npport = SCE_NP_PORT;
}
return CELL_OK;
}
+12 -1
View File
@@ -32,6 +32,7 @@ using SceNpBasicMessageRecvAction = u32;
using SceNpClanId = u32;
using SceNpClansMessageId = u32;
using SceNpClansMemberRole = u32;
using SceNpClansMemberStatus = s32;
using SceNpCustomMenuIndexMask = u32;
@@ -1264,7 +1265,7 @@ struct SceNpCommunicationId
// OnlineId structure
struct SceNpOnlineId
{
char data[16 + 1]; // char term;
char data[SCE_NET_NP_ONLINEID_MAX_LENGTH + 1]; // char term;
char dummy[3];
};
@@ -1584,6 +1585,16 @@ struct SceNpSignalingNetInfo
be_t<u16> npport;
};
struct SceNpSignalingNetInfoDeprecated
{
be_t<u32> size;
be_t<u32> local_addr; // in_addr
be_t<u32> mapped_addr; // in_addr
be_t<s32> nat_status;
be_t<s32> upnp_status;
be_t<s32> npport_status;
};
struct SceNpCustomMenuAction
{
be_t<u32> options;
+6 -6
View File
@@ -1,4 +1,5 @@
#include "stdafx.h"
#include "Emu/Cell/ErrorCodes.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/IdManager.h"
@@ -540,7 +541,9 @@ error_code sceNpMatching2GetClanLobbyId(SceNpMatching2ContextId ctxId, SceNpClan
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
return CELL_OK;
// Returning this rather than `CELL_OK` allows for games to
// not need Matching2 Clans support to connect, when Clans are enabled.
return SCE_NP_MATCHING2_SERVER_ERROR_SERVICE_UNAVAILABLE;
}
error_code sceNpMatching2GetLobbyMemberDataInternal(
@@ -819,10 +822,7 @@ error_code sceNpMatching2AbortRequest(SceNpMatching2ContextId ctxId, SceNpMatchi
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND;
}
if (!nph.abort_request(reqId))
return SCE_NP_MATCHING2_ERROR_REQUEST_NOT_FOUND;
return CELL_OK;
return nph.abort_request(reqId);
}
error_code sceNpMatching2GetServerInfo(
@@ -1300,7 +1300,7 @@ error_code sceNpMatching2GrantRoomOwner(
error_code sceNpMatching2CreateContext(
vm::cptr<SceNpId> npId, vm::cptr<SceNpCommunicationId> commId, vm::cptr<SceNpCommunicationPassphrase> passPhrase, vm::ptr<SceNpMatching2ContextId> ctxId, s32 option)
{
sceNp2.warning("sceNpMatching2CreateContext(npId=*0x%x, commId=*0x%x(%s), passPhrase=*0x%x, ctxId=*0x%x, option=%d)", npId, commId, commId ? commId->data : "", passPhrase, ctxId, option);
sceNp2.warning("sceNpMatching2CreateContext(npId=*0x%x, commId=*0x%x(%s), passPhrase=*0x%x, ctxId=*0x%x, option=%d)", npId, commId, commId ? std::string_view(commId->data, 9) : "", passPhrase, ctxId, option);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
+480 -81
View File
@@ -1,10 +1,14 @@
#include "stdafx.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/IdManager.h"
#include "Emu/NP/np_handler.h"
#include "Emu/NP/clans_client.h"
#include "sceNp.h"
#include <memory>
#include "sceNpClans.h"
LOG_CHANNEL(sceNpClans);
template<>
@@ -14,6 +18,7 @@ void fmt_class_string<SceNpClansError>::format(std::string& out, u64 arg)
{
switch (error)
{
STR_CASE(SCE_NP_CLANS_SUCCESS);
STR_CASE(SCE_NP_CLANS_ERROR_ALREADY_INITIALIZED);
STR_CASE(SCE_NP_CLANS_ERROR_NOT_INITIALIZED);
STR_CASE(SCE_NP_CLANS_ERROR_NOT_SUPPORTED);
@@ -94,6 +99,9 @@ error_code sceNpClansInit(vm::cptr<SceNpCommunicationId> commId, vm::cptr<SceNpC
return SCE_NP_CLANS_ERROR_NOT_SUPPORTED;
}
// Allocate space for a client somewhere
std::shared_ptr<clan::clans_client> client = std::make_shared<clan::clans_client>();
clans_manager.client = client;
clans_manager.is_initialized = true;
return CELL_OK;
@@ -110,6 +118,7 @@ error_code sceNpClansTerm()
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
}
clans_manager.client.reset();
clans_manager.is_initialized = false;
return CELL_OK;
@@ -117,7 +126,7 @@ error_code sceNpClansTerm()
error_code sceNpClansCreateRequest(vm::ptr<SceNpClansRequestHandle> handle, u64 flags)
{
sceNpClans.todo("sceNpClansCreateRequest(handle=*0x%x, flags=0x%llx)", handle, flags);
sceNpClans.warning("sceNpClansCreateRequest(handle=*0x%x, flags=0x%x)", handle, flags);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -134,36 +143,58 @@ error_code sceNpClansCreateRequest(vm::ptr<SceNpClansRequestHandle> handle, u64
return SCE_NP_CLANS_ERROR_NOT_SUPPORTED;
}
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
s32 reqId = 0;
const SceNpClansError res = clans_manager.client->create_request(reqId);
if (res != SCE_NP_CLANS_SUCCESS)
{
return res;
}
*handle = reqId;
return CELL_OK;
}
error_code sceNpClansDestroyRequest(vm::ptr<SceNpClansRequestHandle> handle)
error_code sceNpClansDestroyRequest(SceNpClansRequestHandle handle)
{
sceNpClans.todo("sceNpClansDestroyRequest(handle=*0x%x)", handle);
sceNpClans.warning("sceNpClansDestroyRequest(handle=*0x%x)", handle);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
}
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpClansError res = clans_manager.client->destroy_request(handle);
if (res != SCE_NP_CLANS_SUCCESS)
{
return res;
}
return CELL_OK;
}
error_code sceNpClansAbortRequest(vm::ptr<SceNpClansRequestHandle> handle)
error_code sceNpClansAbortRequest(SceNpClansRequestHandle handle)
{
sceNpClans.todo("sceNpClansAbortRequest(handle=*0x%x)", handle);
sceNpClans.warning("sceNpClansAbortRequest(handle=*0x%x)", handle);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
}
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
clans_manager.client->destroy_request(handle);
return CELL_OK;
}
error_code sceNpClansCreateClan(vm::ptr<SceNpClansRequestHandle> handle, vm::cptr<char> name, vm::cptr<char> tag, vm::ptr<SceNpClanId> clanId)
error_code sceNpClansCreateClan(SceNpClansRequestHandle handle, vm::cptr<char> name, vm::cptr<char> tag, vm::ptr<SceNpClanId> clanId)
{
sceNpClans.todo("sceNpClansCreateClan(handle=*0x%x, name=%s, tag=%s, clanId=*0x%x)", handle, name, tag, clanId);
sceNpClans.warning("sceNpClansCreateClan(handle=*0x%x, name=%s, tag=%s, clanId=*0x%x)", handle, name, tag, clanId);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -180,31 +211,60 @@ error_code sceNpClansCreateClan(vm::ptr<SceNpClansRequestHandle> handle, vm::cpt
return SCE_NP_CLANS_ERROR_EXCEEDS_MAX;
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
std::string name_str;
vm::read_string(name.addr(), SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH, name_str);
std::string tag_str;
vm::read_string(tag.addr(), SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH, tag_str);
const SceNpClansError res = clans_manager.client->create_clan(nph, handle, name_str, tag_str, clanId);
if (res != SCE_NP_CLANS_SUCCESS)
{
return res;
}
return CELL_OK;
}
error_code sceNpClansDisbandClan(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId)
error_code sceNpClansDisbandClan(SceNpClansRequestHandle handle, SceNpClanId clanId)
{
sceNpClans.todo("sceNpClansDisbandClan(handle=*0x%x, clanId=*0x%x)", handle, clanId);
sceNpClans.warning("sceNpClansDisbandClan(handle=*0x%x, clanId=*0x%x)", handle, clanId);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
}
if (!clanId)
{
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpClansError res = clans_manager.client->disband_dlan(nph, handle, clanId);
if (res != SCE_NP_CLANS_SUCCESS)
{
return res;
}
return CELL_OK;
}
error_code sceNpClansGetClanList(vm::ptr<SceNpClansRequestHandle> handle, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansEntry> clanList, vm::ptr<SceNpClansPagingResult> pageResult)
error_code sceNpClansGetClanList(SceNpClansRequestHandle handle, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansEntry> clanList, vm::ptr<SceNpClansPagingResult> pageResult)
{
sceNpClans.todo("sceNpClansGetClanList(handle=*0x%x, paging=*0x%x, clanList=*0x%x, pageResult=*0x%x)", handle, paging, clanList, pageResult);
sceNpClans.warning("sceNpClansGetClanList(handle=*0x%x, paging=*0x%x, clanList=*0x%x, pageResult=*0x%x)", handle, paging, clanList, pageResult);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
}
if (!pageResult || (paging && !clanList)) // TODO: confirm
if (!pageResult || (paging && !clanList))
{
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
}
@@ -217,10 +277,35 @@ error_code sceNpClansGetClanList(vm::ptr<SceNpClansRequestHandle> handle, vm::cp
}
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
SceNpClansPagingRequest host_paging = {};
if (paging)
{
host_paging = *paging;
}
std::vector<SceNpClansEntry> host_clanList(SCE_NP_CLANS_PAGING_REQUEST_PAGE_MAX);
SceNpClansPagingResult host_pageResult = {};
const SceNpClansError ret = clans_manager.client->get_clan_list(nph, handle, host_paging, host_clanList, host_pageResult);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
if (clanList && host_pageResult.count > 0)
{
std::memcpy(clanList.get_ptr(), host_clanList.data(), sizeof(SceNpClansEntry) * host_pageResult.count);
}
*pageResult = host_pageResult;
return CELL_OK;
}
error_code sceNpClansGetClanListByNpId(vm::ptr<SceNpClansRequestHandle> handle, vm::cptr<SceNpClansPagingRequest> paging, vm::cptr<SceNpId> npid, vm::ptr<SceNpClansEntry> clanList, vm::ptr<SceNpClansPagingResult> pageResult)
// TODO: seems to not be needed, even by the PS3..?
error_code sceNpClansGetClanListByNpId(SceNpClansRequestHandle handle, vm::cptr<SceNpClansPagingRequest> paging, vm::cptr<SceNpId> npid, vm::ptr<SceNpClansEntry> clanList, vm::ptr<SceNpClansPagingResult> pageResult)
{
sceNpClans.todo("sceNpClansGetClanListByNpId(handle=*0x%x, paging=*0x%x, npid=*0x%x, clanList=*0x%x, pageResult=*0x%x)", handle, paging, npid, clanList, pageResult);
@@ -245,7 +330,8 @@ error_code sceNpClansGetClanListByNpId(vm::ptr<SceNpClansRequestHandle> handle,
return CELL_OK;
}
error_code sceNpClansSearchByProfile(vm::ptr<SceNpClansRequestHandle> handle, vm::cptr<SceNpClansPagingRequest> paging, vm::cptr<SceNpClansSearchableProfile> search, vm::ptr<SceNpClansClanBasicInfo> results, vm::ptr<SceNpClansPagingResult> pageResult)
// TODO: seems to not be needed, even by the PS3..?
error_code sceNpClansSearchByProfile(SceNpClansRequestHandle handle, vm::cptr<SceNpClansPagingRequest> paging, vm::cptr<SceNpClansSearchableProfile> search, vm::ptr<SceNpClansClanBasicInfo> results, vm::ptr<SceNpClansPagingResult> pageResult)
{
sceNpClans.todo("sceNpClansSearchByProfile(handle=*0x%x, paging=*0x%x, search=*0x%x, results=*0x%x, pageResult=*0x%x)", handle, paging, search, results, pageResult);
@@ -270,9 +356,9 @@ error_code sceNpClansSearchByProfile(vm::ptr<SceNpClansRequestHandle> handle, vm
return CELL_OK;
}
error_code sceNpClansSearchByName(vm::ptr<SceNpClansRequestHandle> handle, vm::cptr<SceNpClansPagingRequest> paging, vm::cptr<SceNpClansSearchableName> search, vm::ptr<SceNpClansClanBasicInfo> results, vm::ptr<SceNpClansPagingResult> pageResult)
error_code sceNpClansSearchByName(SceNpClansRequestHandle handle, vm::cptr<SceNpClansPagingRequest> paging, vm::cptr<SceNpClansSearchableName> search, vm::ptr<SceNpClansClanBasicInfo> results, vm::ptr<SceNpClansPagingResult> pageResult)
{
sceNpClans.todo("sceNpClansSearchByName(handle=*0x%x, paging=*0x%x, search=*0x%x, results=*0x%x, pageResult=*0x%x)", handle, paging, search, results, pageResult);
sceNpClans.warning("sceNpClansSearchByName(handle=*0x%x, paging=*0x%x, search=*0x%x, results=*0x%x, pageResult=*0x%x)", handle, paging, search, results, pageResult);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -292,12 +378,37 @@ error_code sceNpClansSearchByName(vm::ptr<SceNpClansRequestHandle> handle, vm::c
}
}
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
SceNpClansPagingRequest host_paging = {};
if (paging)
{
host_paging = *paging;
}
const SceNpClansSearchableName host_search = *search;
std::vector<SceNpClansClanBasicInfo> host_results(SCE_NP_CLANS_PAGING_REQUEST_PAGE_MAX);
SceNpClansPagingResult host_pageResult = {};
const SceNpClansError ret = clans_manager.client->clan_search(handle, host_paging, host_search, host_results, host_pageResult);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
if (results && host_pageResult.count > 0)
{
std::memcpy(results.get_ptr(), host_results.data(), sizeof(SceNpClansClanBasicInfo) * host_pageResult.count);
}
*pageResult = host_pageResult;
return CELL_OK;
}
error_code sceNpClansGetClanInfo(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::ptr<SceNpClansClanInfo> info)
error_code sceNpClansGetClanInfo(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::ptr<SceNpClansClanInfo> info)
{
sceNpClans.todo("sceNpClansGetClanInfo(handle=*0x%x, clanId=%d, info=*0x%x)", handle, clanId, info);
sceNpClans.warning("sceNpClansGetClanInfo(handle=*0x%x, clanId=*0x%x, info=*0x%x)", handle, clanId, info);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -310,12 +421,24 @@ error_code sceNpClansGetClanInfo(vm::ptr<SceNpClansRequestHandle> handle, SceNpC
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
}
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
SceNpClansClanInfo host_info = {};
const SceNpClansError ret = clans_manager.client->get_clan_info(handle, clanId, host_info);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
*info = host_info;
return CELL_OK;
}
error_code sceNpClansUpdateClanInfo(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansUpdatableClanInfo> info)
error_code sceNpClansUpdateClanInfo(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansUpdatableClanInfo> info)
{
sceNpClans.todo("sceNpClansUpdateClanInfo(handle=*0x%x, clanId=%d, info=*0x%x)", handle, clanId, info);
sceNpClans.warning("sceNpClansUpdateClanInfo(handle=*0x%x, clanId=*0x%x, info=*0x%x)", handle, clanId, info);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -328,17 +451,23 @@ error_code sceNpClansUpdateClanInfo(vm::ptr<SceNpClansRequestHandle> handle, Sce
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
}
//if (info->something > X)
//{
// return SCE_NP_CLANS_ERROR_EXCEEDS_MAX;
//}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpClansUpdatableClanInfo host_info = *info;
const SceNpClansError ret = clans_manager.client->update_clan_info(nph, handle, clanId, host_info);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansGetMemberList(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, SceNpClansMemberStatus status, vm::ptr<SceNpClansMemberEntry> memList, vm::ptr<SceNpClansPagingResult> pageResult)
error_code sceNpClansGetMemberList(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, SceNpClansMemberStatus status, vm::ptr<SceNpClansMemberEntry> memList, vm::ptr<SceNpClansPagingResult> pageResult)
{
sceNpClans.todo("sceNpClansGetMemberList(handle=*0x%x, clanId=%d, paging=*0x%x, status=%d, memList=*0x%x, pageResult=*0x%x)", handle, clanId, paging, status, memList, pageResult);
sceNpClans.warning("sceNpClansGetMemberList(handle=*0x%x, clanId=*0x%x, paging=*0x%x, status=0x%x, memList=*0x%x, pageResult=*0x%x)", handle, clanId, paging, status, memList, pageResult);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -358,12 +487,36 @@ error_code sceNpClansGetMemberList(vm::ptr<SceNpClansRequestHandle> handle, SceN
}
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
SceNpClansPagingRequest host_paging = {};
if (paging)
{
host_paging = *paging;
}
std::vector<SceNpClansMemberEntry> host_memList_addr(SCE_NP_CLANS_PAGING_REQUEST_PAGE_MAX);
SceNpClansPagingResult host_pageResult = {};
const SceNpClansError ret = clans_manager.client->get_member_list(nph, handle, clanId, host_paging, status, host_memList_addr, host_pageResult);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
if (memList && host_pageResult.count > 0)
{
std::memcpy(memList.get_ptr(), host_memList_addr.data(), sizeof(SceNpClansMemberEntry) * host_pageResult.count);
}
*pageResult = host_pageResult;
return CELL_OK;
}
error_code sceNpClansGetMemberInfo(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::ptr<SceNpClansMemberEntry> memInfo)
error_code sceNpClansGetMemberInfo(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::ptr<SceNpClansMemberEntry> memInfo)
{
sceNpClans.todo("sceNpClansGetMemberInfo(handle=*0x%x, clanId=%d, npid=*0x%x, memInfo=*0x%x)", handle, clanId, npid, memInfo);
sceNpClans.warning("sceNpClansGetMemberInfo(handle=*0x%x, clanId=*0x%x, npid=*0x%x, memInfo=*0x%x)", handle, clanId, npid, memInfo);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -375,12 +528,27 @@ error_code sceNpClansGetMemberInfo(vm::ptr<SceNpClansRequestHandle> handle, SceN
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpId host_npid = *npid;
SceNpClansMemberEntry host_memInfo = {};
const SceNpClansError ret = clans_manager.client->get_member_info(nph, handle, clanId, host_npid, host_memInfo);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
*memInfo = host_memInfo;
return CELL_OK;
}
error_code sceNpClansUpdateMemberInfo(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansUpdatableMemberInfo> info)
error_code sceNpClansUpdateMemberInfo(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansUpdatableMemberInfo> info)
{
sceNpClans.todo("sceNpClansUpdateMemberInfo(handle=*0x%x, clanId=%d, memInfo=*0x%x)", handle, clanId, info);
sceNpClans.warning("sceNpClansUpdateMemberInfo(handle=*0x%x, clanId=*0x%x, info=*0x%x)", handle, clanId, info);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -389,21 +557,26 @@ error_code sceNpClansUpdateMemberInfo(vm::ptr<SceNpClansRequestHandle> handle, S
if (!info)
{
// TODO: add more checks for info
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
}
//if (info->something > X)
//{
// return SCE_NP_CLANS_ERROR_EXCEEDS_MAX;
//}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpClansUpdatableMemberInfo host_info = *info;
const SceNpClansError ret = clans_manager.client->update_member_info(nph, handle, clanId, host_info);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansChangeMemberRole(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, u32 role)
error_code sceNpClansChangeMemberRole(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, u32 role)
{
sceNpClans.todo("sceNpClansChangeMemberRole(handle=*0x%x, clanId=%d, npid=*0x%x, role=%d)", handle, clanId, npid, role);
sceNpClans.warning("sceNpClansChangeMemberRole(handle=*0x%x, clanId=*0x%x, npid=*0x%x, role=0x%x)", handle, clanId, npid, role);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -415,10 +588,22 @@ error_code sceNpClansChangeMemberRole(vm::ptr<SceNpClansRequestHandle> handle, S
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpId host_npid = *npid;
const SceNpClansError ret = clans_manager.client->change_member_role(nph, handle, clanId, host_npid, static_cast<SceNpClansMemberRole>(role));
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansGetAutoAcceptStatus(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::ptr<b8> enable)
// TODO: no struct currently implements `autoAccept` as a field
error_code sceNpClansGetAutoAcceptStatus(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::ptr<b8> enable)
{
sceNpClans.todo("sceNpClansGetAutoAcceptStatus(handle=*0x%x, clanId=%d, enable=*0x%x)", handle, clanId, enable);
@@ -435,7 +620,8 @@ error_code sceNpClansGetAutoAcceptStatus(vm::ptr<SceNpClansRequestHandle> handle
return CELL_OK;
}
error_code sceNpClansUpdateAutoAcceptStatus(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, b8 enable)
// TODO: no struct currently implements `autoAccept` as a field
error_code sceNpClansUpdateAutoAcceptStatus(SceNpClansRequestHandle handle, SceNpClanId clanId, b8 enable)
{
sceNpClans.todo("sceNpClansUpdateAutoAcceptStatus(handle=*0x%x, clanId=%d, enable=%d)", handle, clanId, enable);
@@ -447,33 +633,51 @@ error_code sceNpClansUpdateAutoAcceptStatus(vm::ptr<SceNpClansRequestHandle> han
return CELL_OK;
}
error_code sceNpClansJoinClan(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId)
error_code sceNpClansJoinClan(SceNpClansRequestHandle handle, SceNpClanId clanId)
{
sceNpClans.todo("sceNpClansJoinClan(handle=*0x%x, clanId=%d)", handle, clanId);
sceNpClans.warning("sceNpClansJoinClan(handle=*0x%x, clanId=*0x%x)", handle, clanId);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpClansError ret = clans_manager.client->join_clan(nph, handle, clanId);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansLeaveClan(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId)
error_code sceNpClansLeaveClan(SceNpClansRequestHandle handle, SceNpClanId clanId)
{
sceNpClans.todo("sceNpClansLeaveClan(handle=*0x%x, clanId=%d)", handle, clanId);
sceNpClans.warning("sceNpClansLeaveClan(handle=*0x%x, clanId=*0x%x)", handle, clanId);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpClansError ret = clans_manager.client->leave_clan(nph, handle, clanId);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansKickMember(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::cptr<SceNpClansMessage> message)
error_code sceNpClansKickMember(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::cptr<SceNpClansMessage> message)
{
sceNpClans.todo("sceNpClansKickMember(handle=*0x%x, clanId=%d, npid=*0x%x, message=*0x%x)", handle, clanId, npid, message);
sceNpClans.warning("sceNpClansKickMember(handle=*0x%x, clanId=*0x%x, npid=*0x%x, message=*0x%x)", handle, clanId, npid, message);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -493,12 +697,29 @@ error_code sceNpClansKickMember(vm::ptr<SceNpClansRequestHandle> handle, SceNpCl
}
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpId host_npid = *npid;
SceNpClansMessage host_message = {};
if (message)
{
host_message = *message;
}
const SceNpClansError ret = clans_manager.client->kick_member(nph, handle, clanId, host_npid, host_message);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansSendInvitation(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::cptr<SceNpClansMessage> message)
error_code sceNpClansSendInvitation(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::cptr<SceNpClansMessage> message)
{
sceNpClans.todo("sceNpClansSendInvitation(handle=*0x%x, clanId=%d, npid=*0x%x, message=*0x%x)", handle, clanId, npid, message);
sceNpClans.warning("sceNpClansSendInvitation(handle=*0x%x, clanId=*0x%x, npid=*0x%x, message=*0x%x)", handle, clanId, npid, message);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -518,12 +739,29 @@ error_code sceNpClansSendInvitation(vm::ptr<SceNpClansRequestHandle> handle, Sce
}
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpId host_npid = *npid;
SceNpClansMessage host_message = {};
if (message)
{
host_message = *message;
}
const SceNpClansError ret = clans_manager.client->send_invitation(nph, handle, clanId, host_npid, host_message);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansCancelInvitation(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid)
error_code sceNpClansCancelInvitation(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> npid)
{
sceNpClans.todo("sceNpClansCancelInvitation(handle=*0x%x, clanId=%d, npid=*0x%x)", handle, clanId, npid);
sceNpClans.warning("sceNpClansCancelInvitation(handle=*0x%x, clanId=*0x%x, npid=*0x%x)", handle, clanId, npid);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -535,12 +773,23 @@ error_code sceNpClansCancelInvitation(vm::ptr<SceNpClansRequestHandle> handle, S
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpId host_npid = *npid;
const SceNpClansError ret = clans_manager.client->cancel_invitation(nph, handle, clanId, host_npid);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansSendInvitationResponse(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansMessage> message, b8 accept)
error_code sceNpClansSendInvitationResponse(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansMessage> message, b8 accept)
{
sceNpClans.todo("sceNpClansSendInvitationResponse(handle=*0x%x, clanId=%d, message=*0x%x, accept=%d)", handle, clanId, message, accept);
sceNpClans.warning("sceNpClansSendInvitationResponse(handle=*0x%x, clanId=*0x%x, message=*0x%x, accept=%d)", handle, clanId, message, accept);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -555,12 +804,27 @@ error_code sceNpClansSendInvitationResponse(vm::ptr<SceNpClansRequestHandle> han
}
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
SceNpClansMessage host_message = {};
if (message)
{
host_message = *message;
}
const SceNpClansError ret = clans_manager.client->send_invitation_response(nph, handle, clanId, host_message, accept);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansSendMembershipRequest(vm::ptr<SceNpClansRequestHandle> handle, u32 clanId, vm::cptr<SceNpClansMessage> message)
error_code sceNpClansSendMembershipRequest(SceNpClansRequestHandle handle, u32 clanId, vm::cptr<SceNpClansMessage> message)
{
sceNpClans.todo("sceNpClansSendMembershipRequest(handle=*0x%x, clanId=%d, message=*0x%x)", handle, clanId, message);
sceNpClans.warning("sceNpClansSendMembershipRequest(handle=*0x%x, clanId=*0x%x, message=*0x%x)", handle, clanId, message);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -575,24 +839,48 @@ error_code sceNpClansSendMembershipRequest(vm::ptr<SceNpClansRequestHandle> hand
}
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
SceNpClansMessage host_message = {};
if (message)
{
host_message = *message;
}
const SceNpClansError ret = clans_manager.client->request_membership(nph, handle, clanId, host_message);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansCancelMembershipRequest(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId)
error_code sceNpClansCancelMembershipRequest(SceNpClansRequestHandle handle, SceNpClanId clanId)
{
sceNpClans.todo("sceNpClansCancelMembershipRequest(handle=*0x%x, clanId=%d)", handle, clanId);
sceNpClans.warning("sceNpClansCancelMembershipRequest(handle=*0x%x, clanId=*0x%x)", handle, clanId);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpClansError ret = clans_manager.client->cancel_request_membership(nph, handle, clanId);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansSendMembershipResponse(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::cptr<SceNpClansMessage> message, b8 allow)
error_code sceNpClansSendMembershipResponse(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::cptr<SceNpClansMessage> message, b8 allow)
{
sceNpClans.todo("sceNpClansSendMembershipResponse(handle=*0x%x, clanId=%d, npid=*0x%x, message=*0x%x, allow=%d)", handle, clanId, npid, message, allow);
sceNpClans.warning("sceNpClansSendMembershipResponse(handle=*0x%x, clanId=*0x%x, npid=*0x%x, message=*0x%x, allow=%d)", handle, clanId, npid, message, allow);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -612,12 +900,29 @@ error_code sceNpClansSendMembershipResponse(vm::ptr<SceNpClansRequestHandle> han
}
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpId host_npid = *npid;
SceNpClansMessage host_message = {};
if (message)
{
host_message = *message;
}
const SceNpClansError ret = clans_manager.client->send_membership_response(nph, handle, clanId, host_npid, host_message, allow);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansGetBlacklist(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansBlacklistEntry> bl, vm::ptr<SceNpClansPagingResult> pageResult)
error_code sceNpClansGetBlacklist(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansBlacklistEntry> bl, vm::ptr<SceNpClansPagingResult> pageResult)
{
sceNpClans.todo("sceNpClansGetBlacklist(handle=*0x%x, clanId=%d, paging=*0x%x, bl=*0x%x, pageResult=*0x%x)", handle, clanId, paging, bl, pageResult);
sceNpClans.warning("sceNpClansGetBlacklist(handle=*0x%x, clanId=*0x%x, paging=*0x%x, bl=*0x%x, pageResult=*0x%x)", handle, clanId, paging, bl, pageResult);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -637,53 +942,99 @@ error_code sceNpClansGetBlacklist(vm::ptr<SceNpClansRequestHandle> handle, SceNp
}
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
SceNpClansPagingRequest host_paging = {};
if (paging)
{
host_paging = *paging;
}
std::vector<SceNpClansBlacklistEntry> host_blacklist(SCE_NP_CLANS_PAGING_REQUEST_PAGE_MAX);
SceNpClansPagingResult host_pageResult = {};
const SceNpClansError ret = clans_manager.client->get_blacklist(nph, handle, clanId, host_paging, host_blacklist, host_pageResult);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
if (bl && host_pageResult.count > 0)
{
std::memcpy(bl.get_ptr(), host_blacklist.data(), sizeof(SceNpClansBlacklistEntry) * host_pageResult.count);
}
*pageResult = host_pageResult;
return CELL_OK;
}
error_code sceNpClansAddBlacklistEntry(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid)
error_code sceNpClansAddBlacklistEntry(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> member)
{
sceNpClans.todo("sceNpClansAddBlacklistEntry(handle=*0x%x, clanId=%d, npid=*0x%x)", handle, clanId, npid);
sceNpClans.warning("sceNpClansAddBlacklistEntry(handle=*0x%x, clanId=*0x%x, member=*0x%x)", handle, clanId, member);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
}
if (!npid)
if (!member)
{
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpId host_member = *member;
const SceNpClansError ret = clans_manager.client->add_blacklist_entry(nph, handle, clanId, host_member);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansRemoveBlacklistEntry(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid)
error_code sceNpClansRemoveBlacklistEntry(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> member)
{
sceNpClans.todo("sceNpClansRemoveBlacklistEntry(handle=*0x%x, clanId=%d, npid=*0x%x)", handle, clanId, npid);
sceNpClans.warning("sceNpClansRemoveBlacklistEntry(handle=*0x%x, clanId=*0x%x, member=*0x%x)", handle, clanId, member);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
}
if (!npid)
if (!member)
{
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
const SceNpId host_member = *member;
const SceNpClansError ret = clans_manager.client->remove_blacklist_entry(nph, handle, clanId, host_member);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansRetrieveAnnouncements(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansMessageEntry> mlist, vm::ptr<SceNpClansPagingResult> pageResult)
error_code sceNpClansRetrieveAnnouncements(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansMessageEntry> mlist, vm::ptr<SceNpClansPagingResult> pageResult)
{
sceNpClans.todo("sceNpClansRetrieveAnnouncements(handle=*0x%x, clanId=%d, paging=*0x%x, mlist=*0x%x, pageResult=*0x%x)", handle, clanId, paging, mlist, pageResult);
sceNpClans.warning("sceNpClansRetrieveAnnouncements(handle=*0x%x, clanId=*0x%x, paging=*0x%x, mlist=*0x%x, pageResult=*0x%x)", handle, clanId, paging, mlist, pageResult);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
}
if (!pageResult || (paging && !mlist)) // TODO: confirm
if (!pageResult || (paging && !mlist) || clanId == UINT32_MAX) // TODO: confirm
{
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
}
@@ -696,12 +1047,36 @@ error_code sceNpClansRetrieveAnnouncements(vm::ptr<SceNpClansRequestHandle> hand
}
}
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
SceNpClansPagingRequest host_paging = {};
if (paging)
{
host_paging = *paging;
}
std::vector<SceNpClansMessageEntry> host_announcements(SCE_NP_CLANS_PAGING_REQUEST_PAGE_MAX);
SceNpClansPagingResult host_pageResult = {};
const SceNpClansError ret = clans_manager.client->retrieve_announcements(nph, handle, clanId, host_paging, host_announcements, host_pageResult);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
if (mlist && host_pageResult.count > 0)
{
std::memcpy(mlist.get_ptr(), host_announcements.data(), sizeof(SceNpClansMessageEntry) * host_pageResult.count);
}
*pageResult = host_pageResult;
return CELL_OK;
}
error_code sceNpClansPostAnnouncement(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansMessage> message, vm::cptr<SceNpClansMessageData> data, u32 duration, vm::ptr<SceNpClansMessageId> mId)
error_code sceNpClansPostAnnouncement(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansMessage> message, vm::cptr<SceNpClansMessageData> data, u32 duration, vm::ptr<SceNpClansMessageId> mId)
{
sceNpClans.todo("sceNpClansPostAnnouncement(handle=*0x%x, clanId=%d, message=*0x%x, data=*0x%x, duration=%d, mId=*0x%x)", handle, clanId, message, data, duration, mId);
sceNpClans.warning("sceNpClansPostAnnouncement(handle=*0x%x, clanId=*0x%x, message=*0x%x, data=*0x%x, duration=*0x%x, mId=*0x%x)", handle, clanId, message, data, duration, mId);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
@@ -713,32 +1088,56 @@ error_code sceNpClansPostAnnouncement(vm::ptr<SceNpClansRequestHandle> handle, S
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
}
if (!data) // TODO verify
{
return SCE_NP_CLANS_ERROR_NOT_SUPPORTED;
}
if (strlen(message->body) > SCE_NP_CLANS_ANNOUNCEMENT_MESSAGE_BODY_MAX_LENGTH || strlen(message->subject) > SCE_NP_CLANS_MESSAGE_SUBJECT_MAX_LENGTH) // TODO: correct max?
{
return SCE_NP_CLANS_ERROR_EXCEEDS_MAX;
}
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
const SceNpClansMessage host_announcement = *message;
SceNpClansMessageData host_data = {};
if (data)
{
host_data = *data;
}
SceNpClansMessageId host_announcementId = 0;
const SceNpClansError ret = clans_manager.client->post_announcement(nph, handle, clanId, host_announcement, host_data, duration, host_announcementId);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
*mId = host_announcementId;
return CELL_OK;
}
error_code sceNpClansRemoveAnnouncement(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, SceNpClansMessageId mId)
error_code sceNpClansRemoveAnnouncement(SceNpClansRequestHandle handle, SceNpClanId clanId, SceNpClansMessageId mId)
{
sceNpClans.todo("sceNpClansPostAnnouncement(handle=*0x%x, clanId=%d, mId=%d)", handle, clanId, mId);
sceNpClans.warning("sceNpClansRemoveAnnouncement(handle=*0x%x, clanId=*0x%x, mId=*0x%x)", handle, clanId, mId);
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
{
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
}
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
const SceNpClansError ret = clans_manager.client->delete_announcement(nph, handle, clanId, mId);
if (ret != SCE_NP_CLANS_SUCCESS)
{
return ret;
}
return CELL_OK;
}
error_code sceNpClansPostChallenge(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, SceNpClanId targetClan, vm::cptr<SceNpClansMessage> message, vm::cptr<SceNpClansMessageData> data, u32 duration, vm::ptr<SceNpClansMessageId> mId)
error_code sceNpClansPostChallenge(SceNpClansRequestHandle handle, SceNpClanId clanId, SceNpClanId targetClan, vm::cptr<SceNpClansMessage> message, vm::cptr<SceNpClansMessageData> data, u32 duration, vm::ptr<SceNpClansMessageId> mId)
{
sceNpClans.todo("sceNpClansPostChallenge(handle=*0x%x, clanId=%d, targetClan=%d, message=*0x%x, data=*0x%x, duration=%d, mId=*0x%x)", handle, clanId, targetClan, message, data, duration, mId);
@@ -765,7 +1164,7 @@ error_code sceNpClansPostChallenge(vm::ptr<SceNpClansRequestHandle> handle, SceN
return CELL_OK;
}
error_code sceNpClansRetrievePostedChallenges(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, SceNpClanId targetClan, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansMessageEntry> mList, vm::ptr<SceNpClansPagingResult> pageResult)
error_code sceNpClansRetrievePostedChallenges(SceNpClansRequestHandle handle, SceNpClanId clanId, SceNpClanId targetClan, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansMessageEntry> mList, vm::ptr<SceNpClansPagingResult> pageResult)
{
sceNpClans.todo("sceNpClansRetrievePostedChallenges(handle=*0x%x, clanId=%d, targetClan=%d, paging=*0x%x, mList=*0x%x, pageResult=*0x%x)", handle, clanId, targetClan, paging, mList, pageResult);
@@ -790,7 +1189,7 @@ error_code sceNpClansRetrievePostedChallenges(vm::ptr<SceNpClansRequestHandle> h
return CELL_OK;
}
error_code sceNpClansRemovePostedChallenge(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, SceNpClanId targetClan, SceNpClansMessageId mId)
error_code sceNpClansRemovePostedChallenge(SceNpClansRequestHandle handle, SceNpClanId clanId, SceNpClanId targetClan, SceNpClansMessageId mId)
{
sceNpClans.todo("sceNpClansRemovePostedChallenge(handle=*0x%x, clanId=%d, targetClan=%d, mId=%d)", handle, clanId, targetClan, mId);
@@ -802,7 +1201,7 @@ error_code sceNpClansRemovePostedChallenge(vm::ptr<SceNpClansRequestHandle> hand
return CELL_OK;
}
error_code sceNpClansRetrieveChallenges(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansMessageEntry> mList, vm::ptr<SceNpClansPagingResult> pageResult)
error_code sceNpClansRetrieveChallenges(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansMessageEntry> mList, vm::ptr<SceNpClansPagingResult> pageResult)
{
sceNpClans.todo("sceNpClansRetrieveChallenges(handle=*0x%x, clanId=%d, paging=*0x%x, mList=*0x%x, pageResult=*0x%x)", handle, clanId, paging, mList, pageResult);
+11 -16
View File
@@ -5,6 +5,8 @@
// Return codes
enum SceNpClansError : u32
{
SCE_NP_CLANS_SUCCESS = CELL_OK,
SCE_NP_CLANS_ERROR_ALREADY_INITIALIZED = 0x80022701,
SCE_NP_CLANS_ERROR_NOT_INITIALIZED = 0x80022702,
SCE_NP_CLANS_ERROR_NOT_SUPPORTED = 0x80022703,
@@ -138,7 +140,7 @@ enum
};
// Request handle for clan API
using SceNpClansRequestHandle = vm::ptr<struct SceNpClansRequest>;
using SceNpClansRequestHandle = u32;
// Paging request structure
struct SceNpClansPagingRequest
@@ -159,8 +161,8 @@ struct SceNpClansClanBasicInfo
{
be_t<u32> clanId;
be_t<u32> numMembers;
s8 name[SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH + 1];
s8 tag[SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH + 1];
char name[SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH + 1];
char tag[SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH + 1];
u8 reserved[2];
};
@@ -197,7 +199,7 @@ struct SceNpClansSearchableProfile
be_t<s32> intAttr2SearchOp;
be_t<s32> intAttr3SearchOp;
be_t<s32> binAttr1SearchOp;
s8 tag[SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH + 1];
char tag[SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH + 1];
u8 reserved[3];
};
@@ -205,7 +207,7 @@ struct SceNpClansSearchableProfile
struct SceNpClansSearchableName
{
be_t<s32> nameSearchOp;
s8 name[SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH + 1];
char name[SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH + 1];
u8 reserved[3];
};
@@ -213,7 +215,7 @@ struct SceNpClansSearchableName
struct SceNpClansUpdatableClanInfo
{
be_t<u32> fields;
s8 description[SCE_NP_CLANS_CLAN_DESCRIPTION_MAX_LENGTH + 1];
char description[SCE_NP_CLANS_CLAN_DESCRIPTION_MAX_LENGTH + 1];
SceNpClansSearchableAttr attr;
u8 binData1;
be_t<u32> binData1Size;
@@ -233,8 +235,8 @@ struct SceNpClansUpdatableMemberInfo
be_t<u32> fields;
u8 binData1;
be_t<u32> binData1Size;
u8 binAttr1[SCE_NP_CLANS_CLAN_BINARY_ATTRIBUTE1_MAX_SIZE + 1];
s8 description[SCE_NP_CLANS_MEMBER_DESCRIPTION_MAX_LENGTH + 1];
u8 binAttr1[SCE_NP_CLANS_MEMBER_BINARY_ATTRIBUTE1_MAX_SIZE];
char description[SCE_NP_CLANS_MEMBER_DESCRIPTION_MAX_LENGTH + 1];
b8 allowMsg;
u8 reserved[3];
};
@@ -271,7 +273,7 @@ struct SceNpClansMessageEntry
SceNpClansMessage message;
SceNpClansMessageData data;
SceNpId npid;
u8 reserved[4];
SceNpClanId postedBy;
};
// Blacklist entry structure
@@ -280,10 +282,3 @@ struct SceNpClansBlacklistEntry
SceNpId entry;
SceNpId registeredBy;
};
// fxm objects
struct sce_np_clans_manager
{
atomic_t<bool> is_initialized = false;
};
-1
View File
@@ -3,7 +3,6 @@
#include "util/types.hpp"
#include "Emu/Memory/vm_ptr.h"
#include "Emu/Cell/ErrorCodes.h"
#include <mutex>
#include <vector>
#include <mutex>
+1 -1
View File
@@ -221,7 +221,7 @@ std::pair<PPUDisAsm::const_op, u64> PPUDisAsm::try_get_const_op_gpr_value(u32 re
GET_CONST_REG(reg_rs, op.rs);
return { form, utils::rol64(reg_rs, op.sh64) & (~0ull << (op.mbe64 ^ 63)) };
return {form, std::rotl<u64>(reg_rs, op.sh64) & (~0ull << (op.mbe64 ^ 63))};
}
case ppu_itype::OR:
{
+9 -9
View File
@@ -3483,7 +3483,7 @@ auto RLWIMI()
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 mask = ppu_rotate_mask(32 + op.mb32, 32 + op.me32);
ppu.gpr[op.ra] = (ppu.gpr[op.ra] & ~mask) | (dup32(utils::rol32(static_cast<u32>(ppu.gpr[op.rs]), op.sh32)) & mask);
ppu.gpr[op.ra] = (ppu.gpr[op.ra] & ~mask) | (dup32(std::rotl<u32>(static_cast<u32>(ppu.gpr[op.rs]), op.sh32)) & mask);
if constexpr (((Flags == has_rc) || ...))
ppu_cr_set<s64>(ppu, 0, ppu.gpr[op.ra], 0);
};
@@ -3497,7 +3497,7 @@ auto RLWINM()
return ppu_exec_select<Flags...>::template select<>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
ppu.gpr[op.ra] = dup32(utils::rol32(static_cast<u32>(ppu.gpr[op.rs]), op.sh32)) & ppu_rotate_mask(32 + op.mb32, 32 + op.me32);
ppu.gpr[op.ra] = dup32(std::rotl<u32>(static_cast<u32>(ppu.gpr[op.rs]), op.sh32)) & ppu_rotate_mask(32 + op.mb32, 32 + op.me32);
if constexpr (((Flags == has_rc) || ...))
ppu_cr_set<s64>(ppu, 0, ppu.gpr[op.ra], 0);
};
@@ -3511,7 +3511,7 @@ auto RLWNM()
return ppu_exec_select<Flags...>::template select<>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
ppu.gpr[op.ra] = dup32(utils::rol32(static_cast<u32>(ppu.gpr[op.rs]), ppu.gpr[op.rb] & 0x1f)) & ppu_rotate_mask(32 + op.mb32, 32 + op.me32);
ppu.gpr[op.ra] = dup32(std::rotl<u32>(static_cast<u32>(ppu.gpr[op.rs]), ppu.gpr[op.rb] & 0x1f)) & ppu_rotate_mask(32 + op.mb32, 32 + op.me32);
if constexpr (((Flags == has_rc) || ...))
ppu_cr_set<s64>(ppu, 0, ppu.gpr[op.ra], 0);
};
@@ -3599,7 +3599,7 @@ auto RLDICL()
return ppu_exec_select<Flags...>::template select<>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
ppu.gpr[op.ra] = utils::rol64(ppu.gpr[op.rs], op.sh64) & (~0ull >> op.mbe64);
ppu.gpr[op.ra] = std::rotl<u64>(ppu.gpr[op.rs], op.sh64) & (~0ull >> op.mbe64);
if constexpr (((Flags == has_rc) || ...))
ppu_cr_set<s64>(ppu, 0, ppu.gpr[op.ra], 0);
};
@@ -3613,7 +3613,7 @@ auto RLDICR()
return ppu_exec_select<Flags...>::template select<>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
ppu.gpr[op.ra] = utils::rol64(ppu.gpr[op.rs], op.sh64) & (~0ull << (op.mbe64 ^ 63));
ppu.gpr[op.ra] = std::rotl<u64>(ppu.gpr[op.rs], op.sh64) & (~0ull << (op.mbe64 ^ 63));
if constexpr (((Flags == has_rc) || ...))
ppu_cr_set<s64>(ppu, 0, ppu.gpr[op.ra], 0);
};
@@ -3627,7 +3627,7 @@ auto RLDIC()
return ppu_exec_select<Flags...>::template select<>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
ppu.gpr[op.ra] = utils::rol64(ppu.gpr[op.rs], op.sh64) & ppu_rotate_mask(op.mbe64, op.sh64 ^ 63);
ppu.gpr[op.ra] = std::rotl<u64>(ppu.gpr[op.rs], op.sh64) & ppu_rotate_mask(op.mbe64, op.sh64 ^ 63);
if constexpr (((Flags == has_rc) || ...))
ppu_cr_set<s64>(ppu, 0, ppu.gpr[op.ra], 0);
};
@@ -3642,7 +3642,7 @@ auto RLDIMI()
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 mask = ppu_rotate_mask(op.mbe64, op.sh64 ^ 63);
ppu.gpr[op.ra] = (ppu.gpr[op.ra] & ~mask) | (utils::rol64(ppu.gpr[op.rs], op.sh64) & mask);
ppu.gpr[op.ra] = (ppu.gpr[op.ra] & ~mask) | (std::rotl<u64>(ppu.gpr[op.rs], op.sh64) & mask);
if constexpr (((Flags == has_rc) || ...))
ppu_cr_set<s64>(ppu, 0, ppu.gpr[op.ra], 0);
};
@@ -3656,7 +3656,7 @@ auto RLDCL()
return ppu_exec_select<Flags...>::template select<>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
ppu.gpr[op.ra] = utils::rol64(ppu.gpr[op.rs], ppu.gpr[op.rb] & 0x3f) & (~0ull >> op.mbe64);
ppu.gpr[op.ra] = std::rotl<u64>(ppu.gpr[op.rs], ppu.gpr[op.rb] & 0x3f) & (~0ull >> op.mbe64);
if constexpr (((Flags == has_rc) || ...))
ppu_cr_set<s64>(ppu, 0, ppu.gpr[op.ra], 0);
};
@@ -3670,7 +3670,7 @@ auto RLDCR()
return ppu_exec_select<Flags...>::template select<>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
ppu.gpr[op.ra] = utils::rol64(ppu.gpr[op.rs], ppu.gpr[op.rb] & 0x3f) & (~0ull << (op.mbe64 ^ 63));
ppu.gpr[op.ra] = std::rotl<u64>(ppu.gpr[op.rs], ppu.gpr[op.rb] & 0x3f) & (~0ull << (op.mbe64 ^ 63));
if constexpr (((Flags == has_rc) || ...))
ppu_cr_set<s64>(ppu, 0, ppu.gpr[op.ra], 0);
};
+19 -298
View File
@@ -832,6 +832,9 @@ extern void ppu_register_function_at(u32 addr, u32 size, ppu_intrp_func_t ptr =
return;
}
size = utils::align<u32>(size + addr % 4, 4);
addr &= -4;
// Initialize interpreter cache
while (size)
{
@@ -2308,7 +2311,7 @@ void ppu_thread::cpu_sleep()
raddr = 0;
// Setup wait flag and memory flags to relock itself
state += g_use_rtm ? cpu_flag::wait : cpu_flag::wait + cpu_flag::memory;
state += cpu_flag::wait + cpu_flag::memory;
if (auto ptr = vm::g_tls_locked)
{
@@ -2454,10 +2457,8 @@ ppu_thread::ppu_thread(const ppu_thread_params& param, std::string_view name, u3
// Trigger the scheduler
state += cpu_flag::suspend;
if (!g_use_rtm)
{
state += cpu_flag::memory;
}
// Acquire memory passive lock
state += cpu_flag::memory;
call_history.data.resize(g_cfg.core.ppu_call_history ? call_history_max_size : 1);
syscall_history.data.resize(g_cfg.core.ppu_call_history ? syscall_history_max_size : 1);
@@ -2703,11 +2704,7 @@ ppu_thread::ppu_thread(utils::serial& ar)
// Trigger the scheduler
state += cpu_flag::suspend;
if (!g_use_rtm)
{
state += cpu_flag::memory;
}
state += cpu_flag::memory;
ppu_tname = make_single<std::string>(ar.pop<std::string>());
@@ -3191,221 +3188,6 @@ extern u64 ppu_ldarx(ppu_thread& ppu, u32 addr)
return ppu_load_acquire_reservation<u64>(ppu, addr);
}
const auto ppu_stcx_accurate_tx = build_function_asm<u64(*)(u32 raddr, u64 rtime, const void* _old, u64 _new)>("ppu_stcx_accurate_tx", [](native_asm& c, auto& args)
{
using namespace asmjit;
#if defined(ARCH_X64)
Label fall = c.newLabel();
Label fail = c.newLabel();
Label _ret = c.newLabel();
Label load = c.newLabel();
//if (utils::has_avx() && !s_tsx_avx)
//{
// c.vzeroupper();
//}
// Create stack frame if necessary (Windows ABI has only 6 volatile vector registers)
c.push(x86::rbp);
c.push(x86::r13);
c.push(x86::r14);
c.sub(x86::rsp, 48);
#ifdef _WIN32
if (!s_tsx_avx)
{
c.movups(x86::oword_ptr(x86::rsp, 0), x86::xmm6);
c.movups(x86::oword_ptr(x86::rsp, 16), x86::xmm7);
}
#endif
// Prepare registers
build_swap_rdx_with(c, args, x86::r10);
c.movabs(x86::rbp, reinterpret_cast<u64>(&vm::g_sudo_addr));
c.mov(x86::rbp, x86::qword_ptr(x86::rbp));
c.lea(x86::rbp, x86::qword_ptr(x86::rbp, args[0]));
c.and_(x86::rbp, -128);
c.prefetchw(x86::byte_ptr(x86::rbp, 0));
c.prefetchw(x86::byte_ptr(x86::rbp, 64));
c.movzx(args[0].r32(), args[0].r16());
c.shr(args[0].r32(), 1);
c.movabs(x86::r11, reinterpret_cast<u64>(+vm::g_reservations));
c.lea(x86::r11, x86::qword_ptr(x86::r11, args[0]));
c.and_(x86::r11, -128 / 2);
c.and_(args[0].r32(), 63);
// Prepare data
if (s_tsx_avx)
{
c.vmovups(x86::ymm0, x86::ymmword_ptr(args[2], 0));
c.vmovups(x86::ymm1, x86::ymmword_ptr(args[2], 32));
c.vmovups(x86::ymm2, x86::ymmword_ptr(args[2], 64));
c.vmovups(x86::ymm3, x86::ymmword_ptr(args[2], 96));
}
else
{
c.movaps(x86::xmm0, x86::oword_ptr(args[2], 0));
c.movaps(x86::xmm1, x86::oword_ptr(args[2], 16));
c.movaps(x86::xmm2, x86::oword_ptr(args[2], 32));
c.movaps(x86::xmm3, x86::oword_ptr(args[2], 48));
c.movaps(x86::xmm4, x86::oword_ptr(args[2], 64));
c.movaps(x86::xmm5, x86::oword_ptr(args[2], 80));
c.movaps(x86::xmm6, x86::oword_ptr(args[2], 96));
c.movaps(x86::xmm7, x86::oword_ptr(args[2], 112));
}
// Alloc r14 to stamp0
const auto stamp0 = x86::r14;
build_get_tsc(c, stamp0);
Label fail2 = c.newLabel();
Label tx1 = build_transaction_enter(c, fall, [&]()
{
build_get_tsc(c);
c.sub(x86::rax, stamp0);
c.movabs(x86::r13, reinterpret_cast<u64>(&g_rtm_tx_limit2));
c.cmp(x86::rax, x86::qword_ptr(x86::r13));
c.jae(fall);
});
// Check pause flag
c.bt(x86::dword_ptr(args[2], ::offset32(&ppu_thread::state) - ::offset32(&ppu_thread::rdata)), static_cast<u32>(cpu_flag::pause));
c.jc(fall);
c.xbegin(tx1);
if (s_tsx_avx)
{
c.vxorps(x86::ymm0, x86::ymm0, x86::ymmword_ptr(x86::rbp, 0));
c.vxorps(x86::ymm1, x86::ymm1, x86::ymmword_ptr(x86::rbp, 32));
c.vxorps(x86::ymm2, x86::ymm2, x86::ymmword_ptr(x86::rbp, 64));
c.vxorps(x86::ymm3, x86::ymm3, x86::ymmword_ptr(x86::rbp, 96));
c.vorps(x86::ymm0, x86::ymm0, x86::ymm1);
c.vorps(x86::ymm1, x86::ymm2, x86::ymm3);
c.vorps(x86::ymm0, x86::ymm1, x86::ymm0);
c.vptest(x86::ymm0, x86::ymm0);
}
else
{
c.xorps(x86::xmm0, x86::oword_ptr(x86::rbp, 0));
c.xorps(x86::xmm1, x86::oword_ptr(x86::rbp, 16));
c.xorps(x86::xmm2, x86::oword_ptr(x86::rbp, 32));
c.xorps(x86::xmm3, x86::oword_ptr(x86::rbp, 48));
c.xorps(x86::xmm4, x86::oword_ptr(x86::rbp, 64));
c.xorps(x86::xmm5, x86::oword_ptr(x86::rbp, 80));
c.xorps(x86::xmm6, x86::oword_ptr(x86::rbp, 96));
c.xorps(x86::xmm7, x86::oword_ptr(x86::rbp, 112));
c.orps(x86::xmm0, x86::xmm1);
c.orps(x86::xmm2, x86::xmm3);
c.orps(x86::xmm4, x86::xmm5);
c.orps(x86::xmm6, x86::xmm7);
c.orps(x86::xmm0, x86::xmm2);
c.orps(x86::xmm4, x86::xmm6);
c.orps(x86::xmm0, x86::xmm4);
c.ptest(x86::xmm0, x86::xmm0);
}
c.jnz(fail);
// Store 8 bytes
c.mov(x86::qword_ptr(x86::rbp, args[0], 1, 0), args[3]);
c.xend();
c.lock().add(x86::qword_ptr(x86::r11), 64);
build_get_tsc(c);
c.sub(x86::rax, stamp0);
c.jmp(_ret);
// XABORT is expensive so try to finish with xend instead
c.bind(fail);
// Load old data to store back in rdata
if (s_tsx_avx)
{
c.vmovaps(x86::ymm0, x86::ymmword_ptr(x86::rbp, 0));
c.vmovaps(x86::ymm1, x86::ymmword_ptr(x86::rbp, 32));
c.vmovaps(x86::ymm2, x86::ymmword_ptr(x86::rbp, 64));
c.vmovaps(x86::ymm3, x86::ymmword_ptr(x86::rbp, 96));
}
else
{
c.movaps(x86::xmm0, x86::oword_ptr(x86::rbp, 0));
c.movaps(x86::xmm1, x86::oword_ptr(x86::rbp, 16));
c.movaps(x86::xmm2, x86::oword_ptr(x86::rbp, 32));
c.movaps(x86::xmm3, x86::oword_ptr(x86::rbp, 48));
c.movaps(x86::xmm4, x86::oword_ptr(x86::rbp, 64));
c.movaps(x86::xmm5, x86::oword_ptr(x86::rbp, 80));
c.movaps(x86::xmm6, x86::oword_ptr(x86::rbp, 96));
c.movaps(x86::xmm7, x86::oword_ptr(x86::rbp, 112));
}
c.xend();
c.jmp(fail2);
c.bind(fall);
c.mov(x86::rax, -1);
c.jmp(_ret);
c.bind(fail2);
c.lock().sub(x86::qword_ptr(x86::r11), 64);
c.bind(load);
// Store previous data back to rdata
if (s_tsx_avx)
{
c.vmovaps(x86::ymmword_ptr(args[2], 0), x86::ymm0);
c.vmovaps(x86::ymmword_ptr(args[2], 32), x86::ymm1);
c.vmovaps(x86::ymmword_ptr(args[2], 64), x86::ymm2);
c.vmovaps(x86::ymmword_ptr(args[2], 96), x86::ymm3);
}
else
{
c.movaps(x86::oword_ptr(args[2], 0), x86::xmm0);
c.movaps(x86::oword_ptr(args[2], 16), x86::xmm1);
c.movaps(x86::oword_ptr(args[2], 32), x86::xmm2);
c.movaps(x86::oword_ptr(args[2], 48), x86::xmm3);
c.movaps(x86::oword_ptr(args[2], 64), x86::xmm4);
c.movaps(x86::oword_ptr(args[2], 80), x86::xmm5);
c.movaps(x86::oword_ptr(args[2], 96), x86::xmm6);
c.movaps(x86::oword_ptr(args[2], 112), x86::xmm7);
}
c.mov(x86::rax, -1);
c.mov(x86::qword_ptr(args[2], ::offset32(&ppu_thread::last_ftime) - ::offset32(&ppu_thread::rdata)), x86::rax);
c.xor_(x86::eax, x86::eax);
//c.jmp(_ret);
c.bind(_ret);
#ifdef _WIN32
if (!s_tsx_avx)
{
c.vmovups(x86::xmm6, x86::oword_ptr(x86::rsp, 0));
c.vmovups(x86::xmm7, x86::oword_ptr(x86::rsp, 16));
}
#endif
if (s_tsx_avx)
{
c.vzeroupper();
}
c.add(x86::rsp, 48);
c.pop(x86::r14);
c.pop(x86::r13);
c.pop(x86::rbp);
maybe_flush_lbr(c);
c.ret();
#else
UNUSED(args);
// Unimplemented should fail.
c.brk(Imm(0x42));
c.ret(a64::x30);
#endif
});
template <typename T>
static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, u64 reg_value)
{
@@ -3486,77 +3268,6 @@ static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, u64 reg_value)
return false;
}
if (g_use_rtm) [[likely]]
{
switch (u64 count = ppu_stcx_accurate_tx(addr & -8, rtime, ppu.rdata, std::bit_cast<u64>(new_data)))
{
case umax:
{
auto& all_data = *vm::get_super_ptr<spu_rdata_t>(addr & -128);
auto& sdata = *vm::get_super_ptr<atomic_be_t<u64>>(addr & -8);
const bool ok = cpu_thread::suspend_all<+3>(&ppu, {all_data, all_data + 64, &res}, [&]
{
if ((res & -128) == rtime && cmp_rdata(ppu.rdata, all_data))
{
sdata.release(new_data);
res += 64;
return true;
}
mov_rdata_nt(ppu.rdata, all_data);
res -= 64;
return false;
});
if (ok)
{
break;
}
ppu.last_ftime = -1;
[[fallthrough]];
}
case 0:
{
if (ppu.last_faddr == addr)
{
ppu.last_fail++;
}
if (ppu.last_ftime != umax)
{
ppu.last_faddr = 0;
return false;
}
utils::prefetch_read(ppu.rdata);
utils::prefetch_read(ppu.rdata + 64);
ppu.last_faddr = addr;
ppu.last_ftime = res.load() & -128;
ppu.last_ftsc = utils::get_tsc();
return false;
}
default:
{
if (count > 20000 && g_cfg.core.perf_report) [[unlikely]]
{
perf_log.warning("STCX: took too long: %.3fus (%u c)", count / (utils::get_tsc_freq() / 1000'000.), count);
}
break;
}
}
if (ppu.last_faddr == addr)
{
ppu.last_succ++;
}
ppu.last_faddr = 0;
return true;
}
// Align address: we do not need the lower 7 bits anymore
addr &= -128;
@@ -4007,7 +3718,7 @@ extern void ppu_finalize(const ppu_module<lv2_obj>& info, bool force_mem_release
#endif
}
extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_module<lv2_obj>*>* loaded_modules)
extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_module<lv2_obj>*>* loaded_modules, bool is_fast_compilation)
{
if (g_cfg.core.ppu_decoder != ppu_decoder_type::llvm)
{
@@ -4455,6 +4166,12 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
break;
}
if (is_fast_compilation)
{
// Skip overlays in fast mode
break;
}
if (!wait_for_memory())
{
// Emulation stopped
@@ -4749,7 +4466,7 @@ extern void ppu_initialize()
progress_dialog.reset();
ppu_precompile(dir_queue, &module_list);
ppu_precompile(dir_queue, &module_list, false);
if (Emu.IsStopped())
{
@@ -5803,7 +5520,11 @@ static void ppu_initialize2(jit_compiler& jit, const ppu_module<lv2_obj>& module
std::unique_ptr<Module> _module = std::make_unique<Module>(obj_name, jit.get_context());
// Initialize target
#if LLVM_VERSION_MAJOR >= 21 && (LLVM_VERSION_MINOR >= 1 || LLVM_VERSION_MAJOR >= 22)
_module->setTargetTriple(Triple(jit_compiler::triple1()));
#else
_module->setTargetTriple(jit_compiler::triple1());
#endif
_module->setDataLayout(jit.get_engine().getTargetMachine()->createDataLayout());
// Initialize translator
+24 -3
View File
@@ -416,7 +416,6 @@ Function* PPUTranslator::GetSymbolResolver(const ppu_module<lv2_obj>& info)
assert(ptr_inst->getResultElementType() == m_ir->getPtrTy());
const auto faddr = m_ir->CreateLoad(ptr_inst->getResultElementType(), ptr_inst);
const auto faddr_int = m_ir->CreatePtrToInt(faddr, get_type<uptr>());
const auto pos_32 = m_reloc ? m_ir->CreateAdd(func_pc, m_seg0) : func_pc;
const auto pos = m_ir->CreateShl(pos_32, 1);
const auto ptr = m_ir->CreatePtrAdd(m_exec, pos);
@@ -427,7 +426,7 @@ Function* PPUTranslator::GetSymbolResolver(const ppu_module<lv2_obj>& info)
const auto seg_val = m_ir->CreateTrunc(m_ir->CreateLShr(m_seg0, 13), get_type<u16>());
// Store to jumptable
m_ir->CreateStore(faddr_int, ptr);
m_ir->CreateStore(faddr, ptr);
m_ir->CreateStore(seg_val, seg_ptr);
// Increment index and branch back to loop
@@ -593,6 +592,11 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect)
{
callee = m_module->getOrInsertFunction(fmt::format("__0x%x", target_last - base), type);
cast<Function>(callee.getCallee())->setCallingConv(CallingConv::GHC);
if (g_cfg.core.ppu_prof)
{
m_ir->CreateStore(GetAddr(target_last - m_addr), m_ir->CreateStructGEP(m_thread_type, m_thread, static_cast<uint>(&m_cia - m_locals)));
}
}
}
else
@@ -1115,7 +1119,24 @@ void PPUTranslator::VCFSX(ppu_opcode_t op)
void PPUTranslator::VCFUX(ppu_opcode_t op)
{
const auto b = get_vr<u32[4]>(op.vb);
set_vr(op.vd, fpcast<f32[4]>(b) * fsplat<f32[4]>(std::pow(2, -static_cast<int>(op.vuimm))));
#ifdef ARCH_ARM64
return set_vr(op.vd, fpcast<f32[4]>(b) * fsplat<f32[4]>(std::pow(2, -static_cast<int>(op.vuimm))));
#else
if (m_use_avx512)
{
return set_vr(op.vd, fpcast<f32[4]>(b) * fsplat<f32[4]>(std::pow(2, -static_cast<int>(op.vuimm))));
}
constexpr int bit_shift = 9;
const auto shifted = (b >> bit_shift);
const auto cleared = shifted << bit_shift;
const auto low_bits = b - cleared;
const auto high_part = fpcast<f32[4]>(noncast<s32[4]>(shifted)) * fsplat<f32[4]>(static_cast<f32>(1u << bit_shift));
const auto low_part = fpcast<f32[4]>(noncast<s32[4]>(low_bits));
const auto temp = high_part + low_part;
set_vr(op.vd, temp * fsplat<f32[4]>(std::pow(2, -static_cast<int>(op.vuimm))));
#endif
}
void PPUTranslator::VCMPBFP(ppu_opcode_t op)
+4 -4
View File
@@ -186,7 +186,7 @@ spu_function_t spu_recompiler::compile(spu_program&& _func)
c->cmp(SPU_OFF_32(state), 0);
c->jnz(label_stop);
if (g_cfg.core.spu_prof && g_cfg.core.spu_verification)
if ((g_cfg.core.spu_prof || g_cfg.core.spu_debug) && g_cfg.core.spu_verification)
{
c->mov(x86::rax, m_hash_start & -0xffff);
c->mov(SPU_OFF_64(block_hash), x86::rax);
@@ -755,7 +755,7 @@ spu_function_t spu_recompiler::compile(spu_program&& _func)
c->add(SPU_OFF_64(block_counter), ::size32(words) / (words_align / 4));
// Set block hash for profiling (if enabled)
if (g_cfg.core.spu_prof)
if (g_cfg.core.spu_prof || g_cfg.core.spu_debug)
{
c->mov(x86::rax, m_hash_start | 0xffff);
c->mov(SPU_OFF_64(block_hash), x86::rax);
@@ -1199,7 +1199,7 @@ void spu_recompiler::branch_set_link(u32 target)
c->movdqa(x86::dqword_ptr(*cpu, *qw1, 0, ::offset32(&spu_thread::stack_mirror)), x86::xmm0);
// Set block hash for profiling (if enabled)
if (g_cfg.core.spu_prof)
if (g_cfg.core.spu_prof || g_cfg.core.spu_debug)
{
c->mov(x86::rax, m_hash_start | 0xffff);
c->mov(SPU_OFF_64(block_hash), x86::rax);
@@ -3212,7 +3212,7 @@ void spu_recompiler::ROTQBYI(spu_opcode_t op)
}
else if (s == 4 || s == 8 || s == 12)
{
c->pshufd(va, va, utils::rol8(0xE4, s / 2));
c->pshufd(va, va, std::rotl<u8>(0xE4, s / 2));
}
else if (utils::has_ssse3())
{

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