Compare commits

...
422 Commits
Author SHA1 Message Date
AniLeo 595e42c4f3 rpcs3_version: Bump to 0.0.40 2026-03-03 13:16:24 +01:00
Megamouse 9288565676 Qt: properly handle cancel of pkg install dialog 2026-03-02 07:54:26 +01:00
Ani 00a1c7278a config/ux: Disable double-click to fullscreen by default
The state of mouse/keyboard on rpcs3 has matured enough to the point where using mouse on rpcs3 to play games is normal. Other games do not fullscreen on double-click, our default should match the expected application behaviour.
2026-03-01 11:58:38 +01:00
RipleyTom 5ca19eabd5 NP code review
sceNpTrophy fixes

- sceNpTrophyGetTrophyUnlockState: signed 1 was potentially shifted by 31(UB)
- sceNpTrophyUnlockTrophy: used a reader_lock and was missing check for read only context

cellGame fixes

- cellHddGameCheck: missing log parameters
- cellGameDataCheckCreate2: missing log parameter
- cellGameThemeInstall: condition inverted checking for extension + added tolower just in case
- cellGameThemeInstallFromBuffer: OOB access, buf is always filled from the start and then used as a parameter to the CB

sceNp fixes

- sceNpManagerGetTicket: Made accurate from RE
- sceNpDrmGetTimelimit: Fix msec calculation

sceNp2 fixes

-sceNpMatching2ContextStartAsync: avoid capturing ctx
-sceNpMatching2ContextStop: Minor error value swap

rpcn_client fixes

-add_friend: missing log parameter
-handle_friend_notification: misc validation issue

np_handler fixes
-ticket: Missing move in move constructor
-ticket::parse: Misc validation fix
-get_player_history_entry: potential UB fix

np_requests fixes

-Wrong CB event_type set for get_room_member_data_external_list!
-reply_tus_get_data was not copying status data!
-Order of error check in reply_get_room_member_data_external_list was wrong
-Improved logging

np_requests_gui:

-Added missing guards for gui_notifications

upnp_handler fixes

-Highest density of bugs per line of code in the west, let's pretend I never wrote this

signaling_handler fixes

-Swapped to multimap to avoid collisions on timestamps

Misc fixes
2026-03-01 09:20:32 +02:00
Megamouse 198c2e9eb8 Qt: attempt to download up to 3 times on return_code -255 2026-02-28 20:35:55 +01:00
Megamouse df5b624e45 clans: use std::move for ticket 2026-02-28 14:40:25 +01:00
Megamouse 37a125ddbd clans: const correctness 2026-02-28 14:40:25 +01:00
Megamouse 3624dac22b clans: remove unused struct 2026-02-28 14:40:25 +01:00
Megamouse b8f4aaa6fb Update SDL to 3.4.2 2026-02-28 11:35:36 +01:00
Megamouse 8cee5a33d0 Fix some warnings 2026-02-28 11:35:36 +01:00
Megamouse a9d4e1399a Update zlib to 1.3.2 2026-02-28 11:35:36 +01:00
Elad 0f3275ec82 sys_fs: Fixup op_read 2026-02-28 10:58:25 +02:00
Elad 45c6e938a5 SPU LLVM: Expand SPU Profiling to blocks 2026-02-28 10:58:25 +02:00
Elad 1ec3de9e8f SPU Analyzer: Fix analysis of instructions without regmod 2026-02-28 10:58:25 +02:00
Elad 35ccd63dbc Win32/File.cpp: Fix fs::file constraints to avoid crashes 2026-02-28 10:58:25 +02:00
Elad 188151fa99 SPU/misc: Remove outdated Instruction statistics 2026-02-28 10:58:25 +02:00
Elad 16b05c930f Misc: Force define LLVM for IntelliSense 2026-02-28 10:58:25 +02:00
Elad f39d82f990 SPU: Fix spu_itype::zregmod 2026-02-28 10:58:25 +02:00
Elad bbd91dad92 SPU DisAsm: Disable unlikely float representations 2026-02-28 10:58:25 +02:00
Elad cc1b4c8fd1 Fix strcpy_trunc type validation 2026-02-28 10:58:25 +02:00
RipleyTom 3b6afc1d9a Final sys_ fixes 2026-02-28 09:00:49 +02:00
RipleyTom b30a20c2dc More sys_ fixes 2026-02-27 06:02:28 +02:00
Ani 60db25980f ci: Update docker to 1.9 2026-02-26 12:37:45 +01:00
Ani 8396cc2300 openal: Update to 1.25.1 2026-02-26 12:37:45 +01:00
kd-11 41e036473a rsx: Fix broken shaders when depth format conversion is enabled with no format conversion code active 2026-02-25 22:44:33 +03:00
kd-11 daa53c8642 vk: Fix cubemap detection logic 2026-02-25 22:44:33 +03:00
kd-11 99c9c16187 rsx: Disallow sRGB hardware format promotion unless no remap is required 2026-02-25 22:44:33 +03:00
kd-11 94cd6a6f9e gl/vk: Clean up vertex texture handling
- Clean up code after refactors
2026-02-25 22:44:33 +03:00
kd-11 4fa3aaf2b5 rsx: Fix flickering when initializing texture units 2026-02-25 22:44:33 +03:00
kd-11 34f0e865ac rsx: Get rid of some guessing when handling special hardware formats 2026-02-25 22:44:33 +03:00
kd-11 cb7c3488ab rsx: Do not emit format conversion code in shaders if the feature is unused
- The sampling logic has become increasingly complex yet it is needed very rarely
2026-02-25 22:44:33 +03:00
kd-11 759ef0f5b0 rsx: Add border color correction for hardware SNORM formats 2026-02-25 22:44:33 +03:00
kd-11 585305f434 rsx: Improve hardware texel remapping support
- Fixes issues observed when the remap is requested on a hardcoded channel
- In that scenario, fall back to software
2026-02-25 22:44:33 +03:00
kd-11 cee868560a rsx: Add configuration toggle to debug tab 2026-02-25 22:44:33 +03:00
kd-11 0fb8091a31 rsx: Disable HW remapper if BX2 is active or the user requests not to use it 2026-02-25 22:44:33 +03:00
kd-11 bf5056145e rsx: Track BX2 reads per-TIU to allow enabling/disabling hw remapping 2026-02-25 22:44:33 +03:00
kd-11 34380b1ee7 vk: Make use of mutable formats for dynamic views 2026-02-25 22:44:33 +03:00
kd-11 f27315c821 vk: Support explicit mutable format list
- Actually important for performance reasons
2026-02-25 22:44:33 +03:00
kd-11 794abe2025 vk: Clean up image_view interfaces 2026-02-25 22:44:33 +03:00
kd-11 e29cd4cc93 gl: Implement SNORM and SRGB format overrides 2026-02-25 22:44:33 +03:00
kd-11 0f1735d0df gl: Add support for subviews 2026-02-25 22:44:33 +03:00
kd-11 07abde4e8d vk: Allow cached view to have mutable format 2026-02-25 22:44:33 +03:00
kd-11 3f174b2a97 vk: Implement SNORM and SRGB format overrides 2026-02-25 22:44:33 +03:00
kd-11 4c20bdcc9f vk: Add support for derived image views 2026-02-25 22:44:33 +03:00
kd-11 f2a17e4898 rsx: Add format override functionality to format_ex 2026-02-25 22:44:33 +03:00
kd-11 b9bdbfa55b vk: De-sphaggetify texture handling 2026-02-25 22:44:33 +03:00
kd-11 9e7268ed6d gl: Despaghettify texture handling 2026-02-25 22:44:33 +03:00
Megamouse 7c8b915ba1 tiny style fixes 2026-02-25 11:53:04 +01:00
Megamouse 9ede04c4b9 Invalidate some global variables in gs_frame dtor 2026-02-25 11:53:04 +01:00
Megamouse 8a0eae0ccd overlays: allow to go to begin/end of list without auto repeat 2026-02-25 11:53:04 +01:00
Megamouse f6429a1ae8 overlays: add fullscreen toggle to home menu 2026-02-25 11:53:04 +01:00
Megamouse bc93fdf9f4 input: Add some logging to mouse_gyro_handler 2026-02-25 11:53:04 +01:00
RipleyTom 064c006339 Various sys_ fixes 2026-02-25 04:41:01 +02:00
silviolet 260c986186 Implemented sorted emit_data for YAML nodes
- emit_data now Recursively sorts each node in a YAML node and outputs them as per the function description, originally a TODO
- The default config is still unsorted so when you click save or apply the sorted file will appear
2026-02-22 16:05:14 +02:00
oltolm 3b49420205 cellVdec: replace std::aligned_union_t with a union 2026-02-22 14:56:48 +02:00
kd-11 f5cf818bcc rsx: Disable interpolation for SNORM emulated textures 2026-02-22 14:56:56 +03:00
kd-11 2d7b72a769 rsx: Implement format_ex decoding for FS inputs 2026-02-22 14:56:56 +03:00
kd-11 2b7bb9ef0a rsx: Add format_ex utility 2026-02-22 14:56:56 +03:00
kd-11 e22c83f4ce rsx: Improve comments/documentation around border color SEXT convert 2026-02-22 14:56:56 +03:00
oltolm 3585881a6c cellSaveData: fix "Your comparator is not a valid strict-weak ordering" 2026-02-22 12:33:24 +02:00
Ani 6bfb33279f test_fmt: include <algorithm> 2026-02-20 19:46:39 +02:00
Ani 89efca9f63 system_utils: include <vector> 2026-02-20 19:46:39 +02:00
Ani bfea622999 sys_time: include <exception> on NOT WIN32 2026-02-20 19:46:39 +02:00
AniandRipleyTom e075170cc4 JITASM: include <mutex> on APPLE
Co-Authored-By: RipleyTom <[email protected]>
2026-02-20 19:46:39 +02:00
AniandRipleyTom c7d7f2d03b Thread: Move include <thread> to .h
Co-Authored-By: RipleyTom <[email protected]>
2026-02-20 19:46:39 +02:00
AniandRipleyTom fec2be87f6 types.hpp: #include <new>
Co-Authored-By: RipleyTom <[email protected]>
2026-02-20 19:46:39 +02:00
Ani 6de8861b4e rpcs3: Target c++23 (msvc) 2026-02-20 19:46:39 +02:00
Ani 48667d68b2 rpcs3: Target c++23 2026-02-20 19:46:39 +02:00
RipleyTom a6b5c7e79f Generalize np::npid_to_string() use 2026-02-20 17:50:49 +02:00
RipleyTom a29758de6e signaling_handler: bugfix and cleanup 2026-02-20 17:50:49 +02:00
Megamouse ff992a67c8 win/fs: check file handle with GetFileInformationByHandle when creating fs::file
On empty mounted drives CreateFileW may return a valid handle even if the drive is not usable.
We have to check the file handle early. Otherwise other functions may fail later as a result.
2026-02-20 11:25:39 +02:00
RipleyTom aaf84a8445 sys_net/P2P: Various fixes
Fix RTT adjustment
Fix possible dead pointer interaction in lv2_socket_native::recvfrom()
Fix iterator invalidation in nt_p2p_port::recv_data()
2026-02-20 05:15:49 +02:00
RipleyTom b7b0e06a54 sys_net/lv2_socket_native: Various fixes
Fix is_socket_connected(always returned false)
Implement SYS_NET_IP_TTLCHK and SYS_NET_IP_MAXTTL
Fix lv2_socket_native::sendmsg, it was only sending the first iovec
Fix sys_net_bnet_sendto addrlen check
Fix assert in lv2_socket_native::recvfrom()
2026-02-20 05:15:49 +02:00
RipleyTom 53dcf2ba00 rpcn_client: Misc fixes
Fix missing freeaddrinfo
Fix wrong return value in a rpcn_client::connect() path
Fix missing 0 presence validation in vec_stream::get_string()
2026-02-20 05:15:49 +02:00
kd-11 2064bd87e3 rsx: Fix GCC build 2026-02-19 00:33:09 +03:00
kd-11 dc63f2fc1f rsx: Correct border-color register value for shader texel remapping
- PS3 border color does not correctly support signed channels and instead treats them as simple compression
- We instead perform the reverse conversion before sending it to our shader pipeline
2026-02-19 00:33:09 +03:00
kd-11 0faa8945bc rsx/vk: Fix bug with custom border color sampler storage
- If an app used multiple border colors, only the first one was being applied.
2026-02-19 00:33:09 +03:00
kd-11 b30a44c136 rsx: Make BX2 flag respect constant overrides 2026-02-15 21:04:56 +03:00
kd-11 8a1b323749 rsx/fp: Rework FP prepass analyzer to capture more information about bx2 expansion 2026-02-15 21:04:56 +03:00
kd-11 27fe5c6604 rsx: Fix input-side vs output-side remapping flags
- Sign bit and biased renorm apply on input, Gamma on output
2026-02-15 21:04:56 +03:00
Ani ed3d2a096c audio: Default buffering to 34ms 2026-02-15 15:19:32 +01:00
kd-11 49029c9b98 rsx: Handle 16-bit format remapping 2026-02-15 15:31:53 +03:00
kd-11 2f5a66581f rsx/fp: Fix biased renormalization without BX2 flag
- With biased renorm, a value of 0 gives a value slightly less than -1
- Biased renormalization does not have a "clamped" mode unlike sext
2026-02-15 15:31:53 +03:00
kd-11 3f321c61f3 rsx: Fix remapping behavior for depth textures (sampled as depth) 2026-02-15 15:31:53 +03:00
kd-11 765e72dcb7 rsx: Use 'format features' to drive BX2 texture sample remapping on the GPU
- Fixes problems with BX2 kicking in when it shouldn't
2026-02-15 15:31:53 +03:00
kd-11 d3cd3e9650 rsx: Remove value remapping shuffle 2026-02-15 15:31:53 +03:00
kd-11 e29832fa00 fixup [first commit] 2026-02-15 15:31:53 +03:00
kd-11 6b272ed563 rsx: Re-work value remapping capabilities to match real hardware
- Drop heurestics and use what real hardware is doing instead
2026-02-15 15:31:53 +03:00
kd-11 3df370a7e6 rsx: Value remapping can only happen to a texel lane once per sample
- Avoids double operation if for example BX2 and SNORM/SEXT are active concurrently
2026-02-15 15:31:53 +03:00
Ani dd490fc725 Update libpng to 1.6.55 2026-02-15 12:51:57 +01:00
Ani 1e63088b3e Update cubeb to 2026-01-22 2026-02-15 12:51:57 +01:00
Ani 8dfd7e126e Update glext to 2026.01.26 2026-02-15 12:51:57 +01:00
Ani 66c7dd1381 Update FAudio to 26.02 2026-02-15 12:51:57 +01:00
Ani 9290422fea Update 7zip to 26.00 2026-02-15 12:51:57 +01:00
Paul Plant 365b2939f6 Updated Fedora build dependencies list 2026-02-15 12:15:38 +01:00
Megamouse 97bbc2d419 Update yaml-cpp to 0.9.0 2026-02-15 11:19:02 +01:00
Marin Baron 06798ef729 [Build] Remove quotes protoc 2026-02-15 09:50:18 +01:00
Zion Nimchuk c6f5abe59f Update docker and ccache 2026-02-15 07:48:24 +01:00
RipleyTom 9f92824721 Fix glsl_invalid_program not fitting within 3 bits 2026-02-14 16:56:38 +02:00
RipleyTom 7f2dec46ca Ignore gcc strict aliasing warnings on __sync_lock_test_and_set 2026-02-14 16:56:38 +02:00
RipleyTom 236dc96689 Microphone fixes 2026-02-14 16:56:38 +02:00
Ani 7cfe96a1d1 macOS: Check for hw.optional.neon as fallback 2026-02-11 10:39:30 +01:00
Malcolm b2469039af ARM64: Detect some arm features and let LLVM know if they are or aren't present via attributes
- On x86, LLVM has robust detection for the CPU name. If a CPU like skylake has AVX disabled, it will fall back to something without AVX (nehalem)
- On ARM, detection is not as robust. For instance, on my snapdragon 8 gen 2, it assumes that we have SVE support, as the cortex-x3 supports SVE.
- If an ARM cpu is paired with other cpus from another generation which doesn't support the same instructions as the cortex-x3, or if the cortex-x3 just has SVE disabled for no apparant reason (in the case of the snapdragon 8 gen 2)
- We need to actually detect that ourselves.
- Beyond SVE also detect support for some instructions that might be useful SPU LLVM when optimized with intrinsics.
2026-02-11 08:19:59 +02:00
Megamouse 8f066541a3 Qt: adjust ansi colors based on background color 2026-02-09 23:22:45 +01:00
Megamouse 4c234dc744 Qt: Fix duplicate ansi highlighter creation
It is created in the slot when the action is toggled in LoadSettings
2026-02-09 23:22:45 +01:00
Megamouse 6a07c3f46d input: fix input guard button offsets for closing native overlays
L2, R1 and all hat buttons were incorrectly enforcing the
pad interception after closing a native dialog.
2026-02-09 21:51:46 +01:00
RipleyTom 3bb21db71b Guard async transactions against spurious wakeups 2026-02-09 07:59:29 +02:00
kd-11 aeaa62a28c rsx/sync: Do not allow short-circuiting behavior when releasing GCM labels via host queue 2026-02-08 17:46:15 +03:00
RipleyTom 93dbdead24 Improve add friend logging/dialogs 2026-02-06 08:33:23 +01:00
Malcolm 93fd33a19a ARM: Use ISB instead of yield in place of x86 pause
ISB isn't an exact match for pause, but it does slow down execution at least a litle.
Unfortunately, yield does nothing on machines without SMT (99% of aarch64 machines)
2026-02-06 07:54:44 +02:00
silviolet ebf9374ccd Fixed typos in rpcs3/System.cpp
- changed string containing a typo buyes -> bytes
- capitalized ps2/ps3 to PS2/PS3
2026-02-04 11:54:50 +02:00
Megamouse 43b2ce6577 MouseHandler: minor cleanup 2026-02-03 10:26:37 +01:00
Megamouse 7a6b34cac3 Update Qt to 6.10.2 2026-02-03 10:26:37 +01:00
Megamouse 98aaafe4a4 Update libpng to 1.6.54 2026-02-03 10:26:37 +01:00
Megamouse 294050986f Qt: allow to exclude strings in log viewer 2026-02-03 08:58:03 +01:00
Megamouse 3eb8fdaef4 Qt: simplify log level filtering in log viewer 2026-02-03 08:58:03 +01:00
Megamouse 622fe1ce47 Qt: don't filter log if the input dialog was canceled 2026-02-03 08:58:03 +01:00
trautamaki f1e679d981 Switch from FFmpeg av_opt_set_* to swr_alloc_set_opts2 (#18138)
ffmpeg 7 doesn't allow to set in_channel_count and out_channel_count anymore
2026-02-03 08:00:48 +01:00
Megamouse 8ba48932d3 Qt: try to fix update downloader 2026-02-03 07:13:03 +01:00
kd-11 55aae4dd40 vk: Fix NVIDIA crash when resizing the game window quickly 2026-02-02 21:21:50 +03:00
kd-11 ad90f8b44b rsx: Conservative MM flush during CPU handling of nv3089_image_in 2026-02-02 16:16:24 +03:00
Windsurf7 588cf69dad Add mouse-based gyro emulation (#18113)
This change adds a hardcoded mouse-based motion sensor emulation
feature, inspired by how Cemu handles mouse-driven gyro input.

While the game window is focused, holding the right mouse button enables
gyro emulation:
- Mouse X movement feeds Motion X
- Mouse Y movement feeds Motion Z
- Mouse Wheel feeds Motion Y

The axis mapping and behavior were tested with the "Spark Runner"
minigame in _Sly Cooper: Thieves in Time_ and _Bentley's Hackpack_.
In accordance with this minigame, a top-down view motion control scheme
relies on the X/Z axes.

While the right mouse button is being held, mouse deltas are captured
via the Qt native event filter and accumulated in the frontend, then
consumed by the pad thread.
On right mouse button release, motion values are reset to the neutral
center to avoid residual drift.

This input path is intentionally independent of pad configuration and
works even when a keyboard-only profile is selected.

This implementation thus resolves issue #13883 by allowing motion-only
gameplay without requiring a physical motion-capable controller.
2026-02-02 09:21:02 +01:00
RipleyTom 1c08439907 Force disable RPCN IPv6 support for now 2026-01-31 08:46:11 +02:00
RipleyTom 96cf5c4e63 Fix generic_async_transaction_context thread handling 2026-01-31 08:46:11 +02:00
RipleyTom db3d9cd217 Implement sceNpMatching2GetRoomMemberDataExternalList 2026-01-30 13:56:29 +01:00
RipleyTom 3e0cfc651d Fix sceNpBasicLimited_0xEB42E2E6 2026-01-30 10:45:55 +02:00
RipleyTom 4df51025e5 Improve Message ComId handling 2026-01-30 10:45:55 +02:00
RipleyTom 97feb4eed4 Add Message logging 2026-01-30 10:45:55 +02:00
Tuna Celik 086ab3cb37 Fix for an emulation shutdown hang 2026-01-29 23:25:56 +02:00
Ani b7311bd6db hle: Register missing functions 2026-01-29 09:13:22 +02:00
RipleyTom b0b0ed7634 Implement sceNpMatching2GetCbQueueInfo 2026-01-28 22:33:35 +01:00
RipleyTom cafc2aa9d0 Implement sceNpMatching2GetMemoryInfo 2026-01-28 22:33:35 +01:00
RipleyTom 8f8032b5a8 Implement sceNpMatching2GetSignalingOptParamLocal 2026-01-28 22:33:35 +01:00
RipleyTom 0e2584fc9f sceNpBasicLimitedSendMessage 2026-01-27 17:21:46 +02:00
kd-11 818b11fd2f Revert adrenalin crash workaround 2026-01-26 15:34:46 +01:00
kd-11 0ee3e24b25 vk: Drain the pending frame queue before resizing the swapchain 2026-01-26 02:59:31 +01:00
kd-11 fb420d5989 vk: Fix flood of VVL synchronization violations appearing when capturing media 2026-01-26 02:59:31 +01:00
kd-11 9b09fba811 vk: Prevent WAW hazard when the window size exceeds the output draw box 2026-01-26 02:59:31 +01:00
kd-11 33d79ee2cd vk: Fix CPU frame misalignment bug
- This one has been around for a really long time.
- The frame-based structure was due to translating the original vulkan tutorial to working code.
- While it is not feasible to throw the arch away, we don't need a rigid 2-frame set for acquire-submit semaphores.
2026-01-26 02:59:31 +01:00
kd-11 a907cc838b vk: Always specify LATE_FRAGMENT_TESTS and EARLY_FRAGMENT_TESTS together when declaring barriers
- The combination of access patterns can go either way, do not assume early testing to always take place.
2026-01-26 02:59:31 +01:00
kd-11 29cb4f59bd vk: Invalidate renderpass key in post-cyclic-z barrier
- Post-Z renderpass split is crucial due to loss of writes. The failure to invalidate the renderpass key was an oversight.
2026-01-26 02:59:31 +01:00
kd-11 9dfaca4cd8 vk: Fix WAW hazard when preparing copy commands for texture uploads using scratch 2026-01-26 02:59:31 +01:00
kd-11 318385787a vk: Force strict query scopes quirk if SRM is enabled 2026-01-26 02:59:31 +01:00
kd-11 11464f0793 vk: Tighten image barriers to account for IMAGE_OP_LOAD operation when starting a renderpass 2026-01-26 02:59:31 +01:00
kd-11 11087a973c vk: Set debug names for image views
- Crucial for debugging hangs and crashes as well as VVL output
2026-01-26 02:59:31 +01:00
kd-11 2e4a187145 vk: Persist debug name in the image wrapper to aid in debugging 2026-01-26 02:59:31 +01:00
Megamouse d854ff03fe Qt: allow to disable logging to the log frame while it is hidden 2026-01-25 11:42:16 +01:00
Florin9doi f883718b23 USB: Complete Summonride figures
- Support the last 3 riders discovered by @RipleyTom
- Simplify the creator dialog
2026-01-25 03:02:23 +01:00
kd-11 b9f5d85d16 rsx: Lower harmless errors to warnings 2026-01-25 01:31:58 +03:00
kd-11 131eee2eed rsx: Fix convolution filter decoding 2026-01-25 01:31:58 +03:00
kd-11 590a0bbcad vk: Include GCM format in debug name for temp texture-cache resources 2026-01-25 01:31:58 +03:00
kd-11 ae8e28282c rsx/zcull: Fix silly copypasta
- Find+Replace bug
2026-01-25 01:31:58 +03:00
Megamouse 1e0909c579 CI: download dependency if the filename is the same but the checksum changed 2026-01-24 21:23:26 +01:00
schm1dtmac fbd5bbcfa3 Address review comments 2026-01-24 20:18:25 +01:00
schm1dtmac 7a12e80666 [macOS] Specify plist version 2026-01-24 20:18:25 +01:00
schm1dtmac a646a66ead [macOS] Fix release naming 2026-01-24 20:18:25 +01:00
Daniel López Guimaraes b41c2754ce cellVdec: Remove resolved TODOs 2026-01-24 19:31:39 +01:00
Daniel López Guimaraes 4b07ac4f27 cellVdec: Document all supported codecs
These are all the codecs that the PS3 can handle. There are some numbers
skipped on the codecs enum, but this is intentional: there isn't a codec
assigned to those.
2026-01-24 19:31:39 +01:00
Daniel López Guimaraes f70b5e0c1c cellVdec: Add support for all MPEG4 profile levels
The names are based from the maximum resolution that the PS3 supports
and the levels that are listed on the MPEG-4 Part 2 Wikipedia.

The PS3 uses a separate decoder for MPEG4 instead of DivX, so the
handling on cellVdecGetPicItem should probably be separate too. However,
research needs to be done on that side and things seem to be working
with what we currently have.
2026-01-24 19:31:39 +01:00
SkiskiandRomain Janvier ef9ff09e17 change velocity for RB3 pro guitar when it stays the same twice in a row (#18064)
There is a bug when you play twice in a row with the same velocity on a
string. The second note is not taken into account as the game does not
notice any change in the velocity.

It is because the velocity is never reset (or at least not very often).
The idea is to check if the velocity of the string is the same as the
previous one. And if it is, we just flip the last bit. Since the
accepted values goes from 6 to 127, from what I've seen, it should be
ok.

I don't have an official RB3 pro guitar, but I have a YouRock Guitar
that is compatible and works perfectly with a real MPA. When I use midi
in rpcs3, I miss notes because of that bug. I've add a log message to
test the patch and in a streak of nearly 150 notes, I should have missed
nearly 20 notes. I had absolutely no missed note with thanks to the
patch.

fixes https://github.com/RPCS3/rpcs3/issues/18062

---------

Co-authored-by: Romain Janvier <[email protected]>
2026-01-24 18:35:00 +01:00
Rosalie Wanders a5f570996f Qt: change UI labels based on device product type 2026-01-24 15:18:07 +01:00
RipleyTom aec981935c Migration bugfixes 2026-01-24 14:23:52 +01:00
RipleyTom 27ebd182e7 Flatbuffers to Protobuf (#18082)
Migrate from Flatbuffers to Protobuf to make some lawyers happy.

Fixes https://github.com/RPCS3/rpcs3/issues/17894
2026-01-24 09:37:47 +01:00
Florin9doi 3e49c32c9c USB: Summonride updates 2026-01-20 21:07:53 +02:00
qurious-pixel d91c11deb0 Define source encoding for iconv 2026-01-20 18:41:19 +01:00
qurious-pixel 2ef8dce8cf Explicitly install iconv 2026-01-20 18:41:19 +01:00
Malcolm 0f85e9123e utils: Scale busy_wait according to arm timer frequency
> - This is a fatal issue that was impacting arm builds, since busy_waits were written assuming an approx 3Ghz x86 machine
> and most arm machines have a hardware timer that runs south of 100mhz, meaning the top items in the profiler were calls to busy_wait();
> all over the code. Fixing this is a very significant speedup, on my snapdragon 8 gen 2 device. 27->37FPS in Metal Gear Rising, but almost
> all games benefit when run on ARM.
2026-01-17 10:07:01 +02:00
Malcolm 760c35eec8 PPU LLVM: Use arm fmax/fmin for vmaxfp/vminfp
- Arm fmax/fmin match altivec behaviour regarding nan behaviour
2026-01-17 09:20:13 +02:00
Malcolm eaebd3426e LLVM: enable FMA for ARM cpus unconditionally
- All armv8 machines should have FMA.
- Should be a speedup for snapdragon elite and apple machines.
2026-01-15 08:29:33 +02:00
Daniel López Guimaraes d7b723cd7c cellVdec: Add MPEG4 profile 3
This profile is used in SingStar recordings while in a song on some
versions.
2026-01-14 03:49:53 +01:00
qurious-pixel 1591b7f5a6 Prepend _win64_ 2026-01-14 03:22:17 +01:00
qurious-pixel 7090f16ff3 Prepend win64 on all Windows artifacts 2026-01-14 03:22:17 +01:00
Megamouse a0f2f006b1 Qt: just remove the entire .app dir on macOs 2026-01-13 23:51:57 +01:00
Megamouse 72851d7d44 VS: Fix ISO filters 2026-01-13 23:51:57 +01:00
Megamouse caaee9b7cc Qt: remove all shortcut files if requested 2026-01-13 23:51:57 +01:00
qurious-pixel d656420cc4 Export AVVER for Release Title name 2026-01-13 21:26:14 +01:00
Elad df72f4abed rsx: Fixup get_address() after #18038 2026-01-13 16:14:49 +02:00
Elad 960e2a9ed8 rsx: Make get_address(MAIN) more strict 2026-01-13 15:28:07 +02:00
Elad 57f162c3c4 rsx/nv3089: Fix wrong suggestion 2026-01-13 15:28:07 +02:00
Elad 2d42a4e25b rsx/gcm: Do not rely on GCM IOMAP table in HLE gcmIoOffsetToAddress 2026-01-13 15:28:07 +02:00
Elad 8f8d468774 rsx/gcm: Fix cellGcmGetTimeStampLocation 2026-01-13 10:53:42 +02:00
RipleyTom 4a12f70f2c Add Delete command to RPCN 2026-01-12 21:33:04 +01:00
Zion Nimchuk ee1886fad9 Fix windows aarch64 deploy 2026-01-12 18:48:49 +01:00
Valters 5fd6d413d7 Add async suffix to TODO sceNpLookupUserProfileAsync 2026-01-12 18:15:37 +01:00
Megamouse ec7f666c6b Loader: Fix graceful Emu Restart
This wasn't working because GracefulShutdown was guarding the boot
2026-01-12 15:45:27 +01:00
Megamouse d5bf11703d Qt: Restart game even if there's no savestate when using the restart shortcut 2026-01-12 15:45:27 +01:00
Megamouse cf94be2aac ISO: reset m_path to original path during Restart 2026-01-12 15:45:27 +01:00
Elad 100a402cd8 rsx/nv3089: Fix image_in source line length estimation 2026-01-12 15:33:41 +02:00
kd-11 86b559ab52 rsx/zcull: Stop any running when the clear command is processed 2026-01-12 14:24:05 +03:00
kd-11 c199a96dac rsx/zcull: Rename write_enabled to surface_active to make the meaning clear 2026-01-12 14:24:05 +03:00
kd-11 f45742df52 gcm: Implement cellGcmGetTimeStampLocation as HLE to improve timestamp reports detection
- Timestamp reports don't need host GPU access and are much faster to emulate
2026-01-12 14:24:05 +03:00
kd-11 578d30d3ae rsx: Fix context_dma enum naming 2026-01-12 14:24:05 +03:00
kd-11 a6321caaa2 rsx: Remove surface management hack breaking savestate capture 2026-01-12 14:24:05 +03:00
Zion Nimchuk 4842339f9e Setup to deploy aarch64 binaries 2026-01-12 10:58:16 +01:00
Florin9doi aa220d24e8 Fixed more SingStar previews 2026-01-11 22:14:36 +01:00
Florin9doi d9edf98d55 USB: Usbd support for microphones 2026-01-11 22:14:36 +01:00
Megamouse cf6aaaa74f VS: update googletest package
This fixes building the test project in VS 2026
2026-01-11 19:23:11 +01:00
Megamouse 25b412a90f cellVdec: impove error logging 2026-01-11 18:49:25 +01:00
Florin9doi d584575984 Fixed more SingStar previews, this time for v05.00 2026-01-11 17:36:38 +01:00
Live session user 7e9e0f56fb Windows ARM build 2026-01-11 16:53:16 +01:00
Elad 8188c45b9d Cut sceNpDrmIsAvailable sleep time 2026-01-11 17:03:41 +02:00
Elad 1f731afbd9 sys_fs: Add PPU sleep 2026-01-11 17:03:41 +02:00
Florin9doi 9781690918 Fixed SingStar previews 2026-01-11 14:26:04 +02:00
Megamouse cd6dfc82a2 cellVdec: also use ctx->framerate to calculate the timestamps
ffmpeg 7 doesn't seem to guess the time_base parameter anymore
2026-01-10 19:17:32 +01:00
Megamouse ae6bdf84f1 Update ffmpeg to 7.1.2 2026-01-10 19:17:32 +01:00
Megamouse ad65878c0c gl: fix some cppcheck issues 2026-01-10 19:17:32 +01:00
zephandMegamouse 50fcee6fe0 UI: ANSI colors, code fix suggestion
Co-authored-by: Megamouse <[email protected]>
2026-01-10 17:22:54 +01:00
zeph 4431f6b3d9 UI: ANSI TTY colors, fix git submodule versions and correct include 2026-01-10 17:22:54 +01:00
zeph 84ddcea45a UI: ANSI colors, more explicit erase check 2026-01-10 17:22:54 +01:00
zeph 6eeca69c56 UI: ANSI colors, further fix-ups 2026-01-10 17:22:54 +01:00
zeph 484d97caf1 UI: colored ANSI logs fix-ups 2026-01-10 17:22:54 +01:00
zeph b2768bbd61 UI: colored ANSI logs 2026-01-10 17:22:54 +01:00
Megamouse 9faf9a6145 ISO: optimize byteswap and utf16 string conversion 2026-01-10 15:22:41 +01:00
Megamouse 36bce33684 ISO: use string_view in retrieve 2026-01-10 15:22:41 +01:00
Megamouse f712de0c91 ISO: Remove psf hack 2026-01-10 15:22:41 +01:00
Megamouse a8624682a7 ISO: add some logging 2026-01-10 12:14:09 +01:00
Megamouse 4dc994833d Qt: fix shortcut creation for ISO 2026-01-10 12:14:09 +01:00
Megamouse 98e64d7821 Qt: fix appicon for ISO 2026-01-10 12:14:09 +01:00
Megamouse 6bd4f52173 Qt: Allow to boot iso files from menu 2026-01-10 12:14:09 +01:00
Megamouse 41a5c69db4 Qt: Allow to add iso files from menu 2026-01-10 12:14:09 +01:00
Megamouse f2afdee40c Qt: fix missing mice menu 2026-01-10 12:14:09 +01:00
Megamouse 19129eddd7 Qt: ISO clean up
Should fix some potential Qt bugs as well
2026-01-10 06:36:58 +01:00
Megamouse be77083a2b Qt: some cleanup 2026-01-10 06:36:58 +01:00
Functionable 49bcc93072 ISO: Move load_icon 2026-01-09 14:40:51 +02:00
Functionable a53f2fc7b9 ISO: Fix save states in games with multiple executables
- Some games will load into a different executable from EBOOT.BIN, and
attempting to restore those games from savestate causes the game to
crash immediately.
- This commit repurposes the disc_info field in a savestate generated
from an ISO game to store the running game executable at the time of the
save state.
2026-01-09 14:40:51 +02:00
Functionable f4dffd985b ISO: Fix argv[0] being set to a garbage value
- Due to GetCallbacks().resolve_path behaviour being reverted in a prior
commit, resolved_path will not have the path to the game executable.
This causes issues when setting argv[0] to the game executable path and
apparently breaks some games which may rely on this value.
2026-01-09 14:40:51 +02:00
Functionable 59a1f81e86 ISO: Game loading fixes
- After undoing the changes to do with resolve_path, loading game
updates was broken. This required the condition to be changed to check
for launching_from_disc_archive.
- When attempting to load an update for an ISO game,
inherited_ps3_game_path needs to be set otherwise launching the updated
game will fail.
- An additional check was added to ensure that the inherited vitual game
directory isn't saved as the game path in games.yml.
- Fixed attempting to load an updated ISO game by launching its updated
executable, which can happen when loading a savestate for a game with
updates, the emulator would crash before.
- Unload ISO file when Load() fails, otherwise ISO loading might be
stuck in a broken state.
2026-01-09 14:40:51 +02:00
Functionable a2d76aedaa ISO: Fix recent actions created when launching ISO games 2026-01-09 14:40:51 +02:00
Functionable 59f9a7c080 ISO: Use clearer code to set game.icon_in_archive
- Suggested change from PR review
2026-01-09 14:40:51 +02:00
Functionable 714359b544 ISO: Move icon loading to a common function in qt_utils.h 2026-01-09 14:40:51 +02:00
Functionable bc1d0b9e65 ISO: Move game size assignment to size_calc_func in game_list_table.cpp 2026-01-09 14:40:51 +02:00
Functionable 407cbf9690 ISO: Add ISO games through Emulator::AddGamesFromDir
- When dragging and dropping ISO files, they will be treated the same as
game directories currently are and added to the game list rather than
immediately being opened.
2026-01-09 14:40:51 +02:00
Functionable 4cd75971f0 ISO: Move code to load psf::registry into iso_archive
- Multiple places end up needing to retrieve a psf::registry from an is
o archive.
- Added a safety check along with this
2026-01-09 14:40:51 +02:00
Functionable 38daf8d325 ISO: Add empty path check to iso_archive::retrieve 2026-01-09 14:40:51 +02:00
Functionable 095f433f8e ISO: Fix loading games in continuous mode
Some games will load into another game and continuous mode will be set.
Currently, if this happens the ISO will get unloaded in the shutdown
function. This commit adds an additional check before calling the unload
function to fix this.
2026-01-09 14:40:51 +02:00
Functionable fa11af1cba ISO: Remove resolve_path hack
- Modify Emulator::GetFakeCat to return "DG" for mounted ISO games like
expected.
- Undo changes to main_application resolve_path callback
2026-01-09 14:40:51 +02:00
Functionable 48f39acac7 ISO: Unload the iso_device on shutdown 2026-01-09 14:40:51 +02:00
Functionable 257043529a ISO: Loader improvements
- Don't use floating point when advancing sectors
- Remove redudndant seek in iso_archive constructor
- Drop error code checks in iso_file::read_at
- Don't use lexically_normal for handling path in iso_archive::retrieve.
More complete directory search implementation.
2026-01-09 14:40:51 +02:00
Functionable 2533aa02d0 ISO: Don't access m_game_info from icon_load_func 2026-01-09 14:40:51 +02:00
Functionable 27510f5fa8 ISO: Move game image loading to game_list_base::IconLoadFunction 2026-01-09 14:40:51 +02:00
Functionable acdb0ee729 ISO: Small clean up
Cleaning up old comments and fixing small mistakes in ISO.cpp
2026-01-09 14:40:51 +02:00
Functionable 673cc040fa ISO: Add UI support
Adds ISO file type to load dialog and allows launching ISO games via
drag and drop.
2026-01-09 14:40:51 +02:00
Functionable eff25ed0aa ISO: Fix game movie icons 2026-01-09 14:40:51 +02:00
Functionable ab45b1bf61 ISO: Fix icons in savestate_manager_dialog 2026-01-09 14:40:51 +02:00
Functionable 1d2f6404c6 ISO: Fix for save states 2026-01-09 14:40:51 +02:00
Functionable d6d7ae35f8 ISO: Add games to games list 2026-01-09 14:40:51 +02:00
Functionable 990e002782 ISO: Modify game boot for ISOs
This commit modifies code in System.cpp to allow games to boot from ISO
images. Game data is loaded by leveraging fs::set_virtual_device, and
setting the m_path to the ISO device location.

This commit also modifies the resolve_path callback to return the path
it was given if it wasn't found in the OS. This is necessary as
Emulator::GetFakeCat will return "HG" on disc games, making games
unplayable through ISO.
2026-01-09 14:40:51 +02:00
Functionable 6c083d6184 ISO: Add ISO reader code and ISO device
Adds infrastructure to read files/data from ISOs.

Also adds classes extending fs::device_base and fs::file_base in order
to allow reading files through fs namespace functions. This approach
should allow ISO data to be read by the emulator with the least changes
to existing code.
2026-01-09 14:40:51 +02:00
Megamouse ef5a4bf7e4 Qt/input: fix pressure intensity button availability 2026-01-08 14:33:37 +01:00
kd-11 c22d2b51bb gl: Do not overwrite texture-cache image dimensions when updating format
- The code was an outdated relic from the early days. The calculated pitch was wrong as it did not take subregions (incomplete rows) into account.
2026-01-08 14:31:44 +03:00
Megamouse 72a19a87b6 Qt: Add mulit selection to game grid 2026-01-08 07:45:04 +01:00
Megamouse 1bfd1154f5 Update FAudio to 26.01 2026-01-07 19:12:04 +01:00
Megamouse 0bd6aee8c8 Update SDL to 3.4.0 2026-01-07 19:12:04 +01:00
qurious-pixel e3a938fb76 Embed qt.conf in RPCS3 binary 2026-01-07 09:58:06 +01:00
qurious-pixel db89f55ca1 Add Qt translations to Windows Clang 2026-01-07 09:58:06 +01:00
Antonino Di Guardo 27033ee0cb move disk usage dialog box to game list's context menu (#17977) 2026-01-07 08:22:40 +01:00
Megamouse 90df8baa5f Qt: Fix game list multi-selection after Refresh 2026-01-06 17:09:39 +01:00
Megamouse 1eb0b2260d Refactor game_list_frame 2026-01-06 16:22:07 +01:00
digant73 9fb7c8f52c Add multi-selection context menu
fix compile errors on Mac and provide reviewed changes

fix wrong resolved conflict

removed duplicate

cleanup after latest merged PRs

minor cleanup

rename and move get_existing_dir() to File.cpp

apply reviewed changes
2026-01-06 09:47:15 +01:00
Florin9doi 9b256d71a9 USB: Fixed G27 crash during reinitialization 2026-01-05 21:00:37 +01:00
Megamouse 8f26c01ae5 Qt: try to fix drag and drop issues 2026-01-05 20:14:55 +01:00
Megamouse 113679ead8 Update SDL to 3.2.30 2026-01-05 18:13:25 +01:00
Megamouse c2b93317ad Revert "Update SDL to 3.4.0"
This reverts commit cfbc416521.
2026-01-05 18:13:25 +01:00
schm1dtmac a0e0a6c6a6 [macOS Updater] Cleanup remnants of the old app bundle post-update 2026-01-04 19:11:37 +01:00
kd-11 cc37a40f40 rsx/fp: Harden the FP decompiler a bit when bogus inputs are passed in. 2026-01-04 15:05:52 +03:00
schm1dtmac aab40bd269 Try and cut down unnecessary Qt translations 2026-01-04 09:46:49 +01:00
schm1dtmac 44bd0568e7 Unify Mac CI action 2026-01-04 09:46:49 +01:00
schm1dtmac c83769e79e Unify & cleanup Mac deploy script 2026-01-04 09:46:49 +01:00
schm1dtmac e65755d68d Unify & optimise Mac build script 2026-01-04 09:46:49 +01:00
Megamouse 643d1102cc Add SDL camera handler 2026-01-03 14:40:02 +01:00
Megamouse ea6bb77d57 Qt: Fix image dimensions passed to camera_video_sink::present 2026-01-03 02:27:54 +01:00
Megamouse 050d2d3b2f macOs: Deploy Qt translations 2026-01-03 00:28:41 +01:00
Megamouse 8d55db334e Qt: deploy and apply Qt translations 2026-01-01 19:17:13 +01:00
kd-11 ee06dccdea vk: Disable VK_EXT_attachment_feedback_loop_layout support for adrenalin driver 2026-01-01 13:36:31 +02:00
qurious-pixel 8d7484df89 [BSD] Use FreeBSD 14.3 vm
Fixes runner stopping when running out of disk space.
2026-01-01 10:50:19 +02:00
Megamouse ae72de3881 Refactor camera code to support different camera handlers
I split this off the sdl camera PR due to rebase conflicts.
It can also be seen as a partial integration test.
2026-01-01 08:54:57 +01:00
Megamouse cfbc416521 Update SDL to 3.4.0 2026-01-01 06:51:46 +01:00
Megamouse 05ae739a22 Update OpenAl to 1.25.0 2026-01-01 06:51:46 +01:00
Megamouse f50b9cd5c4 Update libpng to 1.6.53 2026-01-01 06:51:46 +01:00
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 <[email protected]>
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 <[email protected]>
Signed-off-by: zeph <[email protected]>
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
schm1dtmacandelad335 1147f47a8a Switch macOS atomics to futexes, bump min ver to 14.4
Co-authored-by: elad335 <[email protected]>
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 GuardoandMegamouse 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 <[email protected]>
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
481 changed files with 99527 additions and 16609 deletions
-125
View File
@@ -1,125 +0,0 @@
#!/bin/sh -ex
# shellcheck disable=SC2086
export HOMEBREW_NO_AUTO_UPDATE=1
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
export HOMEBREW_NO_ENV_HINTS=1
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install -f --overwrite --quiet pipenv googletest opencv@4 ffmpeg@5 "llvm@$LLVM_COMPILER_VER" glew sdl3 vulkan-headers
brew unlink --quiet ffmpeg qtbase qtsvg qtdeclarative
brew link -f --quiet "llvm@$LLVM_COMPILER_VER" ffmpeg@5
# 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/ea2bec5f1f4384e188d7fc0702ab21a20a2ced08/Formula/m/molten-vk.rb
/opt/homebrew/bin/brew install -f --overwrite --formula --quiet ./molten-vk.rb
export HOMEBREW_DEVELOPER=0
export CXX=clang++
export CC=clang
export BREW_PATH;
BREW_PATH="$(brew --prefix)"
export BREW_BIN="/opt/homebrew/bin"
export BREW_SBIN="/opt/homebrew/sbin"
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
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
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"
"$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"
fi
cd "$WORKDIR"
ditto "/tmp/Qt/$QT_VER" "qt-downloader/$QT_VER"
export Qt6_DIR="$WORKDIR/qt-downloader/$QT_VER/clang_64/lib/cmake/Qt$QT_VER_MAIN"
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 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"
export LLVM_DIR
LLVM_DIR="$BREW_PATH/opt/llvm@$LLVM_COMPILER_VER"
# exclude ffmpeg, LLVM, opencv, and sdl from submodule update
# 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
"$BREW_PATH/bin/cmake" .. \
-DBUILD_RPCS3_TESTS="${RUN_UNIT_TESTS}" \
-DRUN_RPCS3_TESTS="${RUN_UNIT_TESTS}" \
-DUSE_SDL=ON \
-DUSE_DISCORD_RPC=ON \
-DUSE_VULKAN=ON \
-DUSE_ALSA=OFF \
-DUSE_PULSE=OFF \
-DUSE_AUDIOUNIT=ON \
-DUSE_SYSTEM_FFMPEG=ON \
-DLLVM_CCACHE_BUILD=OFF \
-DLLVM_BUILD_RUNTIME=OFF \
-DLLVM_BUILD_TOOLS=OFF \
-DLLVM_INCLUDE_DOCS=OFF \
-DLLVM_INCLUDE_EXAMPLES=OFF \
-DLLVM_INCLUDE_TESTS=OFF \
-DLLVM_INCLUDE_TOOLS=OFF \
-DLLVM_INCLUDE_UTILS=OFF \
-DLLVM_USE_PERF=OFF \
-DLLVM_ENABLE_Z3_SOLVER=OFF \
-DUSE_NATIVE_INSTRUCTIONS=OFF \
-DUSE_SYSTEM_MVK=ON \
-DUSE_SYSTEM_FAUDIO=OFF \
-DUSE_SYSTEM_SDL=ON \
-DUSE_SYSTEM_OPENCV=ON \
"$CMAKE_EXTRA_OPTS" \
-DLLVM_TARGET_ARCH=arm64 \
-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_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_OSX_SYSROOT="$(xcrun --sdk macosx --show-sdk-path)" \
-G Ninja
"$BREW_PATH/bin/ninja"; build_status=$?;
cd ..
# If it compiled succesfully let's deploy.
if [ "$build_status" -eq 0 ]; then
.ci/deploy-mac-arm64.sh
fi
+74 -66
View File
@@ -1,38 +1,51 @@
#!/bin/sh -ex
# Gather explicit version number and number of commits
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' rpcs3/rpcs3_version.cpp)
COMM_COUNT=$(git rev-list --count HEAD)
COMM_HASH=$(git rev-parse --short=8 HEAD)
# AVVER is used for GitHub releases, it is the version number. LVER is used for release naming.
AVVER="${COMM_TAG}-${COMM_COUNT}"
export LVER="${COMM_TAG}-${COMM_COUNT}-${COMM_HASH}"
echo "AVVER=$AVVER" >> .ci/ci-vars.env
# shellcheck disable=SC2086
export HOMEBREW_NO_AUTO_UPDATE=1
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
rm /usr/local/bin/{idle3.14,pip3.14,pydoc3.14,python3.14,python3.14-config} && \
rm /usr/local/bin/{idle3,pip3,pydoc3,python3,python3-config}
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 opencv@4 ffmpeg@5 "llvm@$LLVM_COMPILER_VER" glew sdl3 vulkan-headers
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
if [ "$AARCH64" -eq 1 ]; then
brew install -f --overwrite --quiet googletest opencv@4 sdl3 vulkan-headers vulkan-loader molten-vk
brew unlink --quiet ffmpeg fmt qtbase qtsvg qtdeclarative protobuf
else
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 [email protected] opencv@4 "llvm@$LLVM_COMPILER_VER" sdl3 vulkan-headers vulkan-loader molten-vk
arch -x86_64 /usr/local/bin/brew unlink --quiet ffmpeg qtbase qtsvg qtdeclarative
fi
# 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/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++
export CC=clang
export BREW_X64_PATH;
BREW_X64_PATH="$("/usr/local/bin/brew" --prefix)"
export BREW_BIN="/usr/local/bin"
export BREW_SBIN="/usr/local/sbin"
export CMAKE_EXTRA_OPTS='-DLLVM_TARGETS_TO_BUILD=X86'
export BREW_PATH;
if [ "$AARCH64" -eq 1 ]; then
BREW_PATH="$(brew --prefix)"
export BREW_BIN="/opt/homebrew/bin"
export BREW_SBIN="/opt/homebrew/sbin"
else
BREW_PATH="$("/usr/local/bin/brew" --prefix)"
export BREW_BIN="/usr/local/bin"
export BREW_SBIN="/usr/local/sbin"
fi
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"
@@ -42,82 +55,77 @@ if [ ! -d "/tmp/Qt/$QT_VER" ]; then
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"
"/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"
python3 "$WORKDIR/qt-downloader/qt-downloader" macos desktop "$QT_VER" clang_64 --opensource --addons qtmultimedia qtimageformats -o "$QT_VER/clang_64"
fi
cd "$WORKDIR"
ditto "/tmp/Qt/$QT_VER" "qt-downloader/$QT_VER"
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 SDL3_DIR="$BREW_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"
# 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 -no-pie -D__MAC_OS_X_VERSION_MIN_REQUIRED=140000"
export CFLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=140000"
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 PATH="/opt/homebrew/opt/llvm@$LLVM_COMPILER_VER/bin:$PATH"
export LDFLAGS="-L$BREW_PATH/opt/llvm@$LLVM_COMPILER_VER/lib/c++ -L$BREW_PATH/opt/llvm@$LLVM_COMPILER_VER/lib/unwind -lunwind"
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"
VULKAN_SDK="$BREW_PATH/opt/molten-vk"
ln -s "$BREW_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"
# exclude ffmpeg, LLVM, opencv, and sdl from submodule update
LLVM_DIR="$BREW_PATH/opt/llvm@$LLVM_COMPILER_VER"
# Pull all the submodules except some
# 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
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/llvm/ && !/opencv/ && !/SDL/ && !/feralinteractive/ { print $3 }' .gitmodules)
mkdir build && cd build || exit 1
export MACOSX_DEPLOYMENT_TARGET=14.0
"/opt/homebrew/bin/cmake" .. \
-DBUILD_RPCS3_TESTS=OFF \
-DRUN_RPCS3_TESTS=OFF \
if [ "$AARCH64" -eq 1 ]; then
cmake .. \
-DBUILD_RPCS3_TESTS="${RUN_UNIT_TESTS}" \
-DRUN_RPCS3_TESTS="${RUN_UNIT_TESTS}" \
-DCMAKE_OSX_DEPLOYMENT_TARGET=14.4 \
-DCMAKE_OSX_SYSROOT="$(xcrun --sdk macosx --show-sdk-path)" \
-DMACOSX_BUNDLE_SHORT_VERSION_STRING="${COMM_TAG}" \
-DMACOSX_BUNDLE_BUNDLE_VERSION="${COMM_COUNT}" \
-DSTATIC_LINK_LLVM=ON \
-DUSE_SDL=ON \
-DUSE_DISCORD_RPC=ON \
-DUSE_VULKAN=ON \
-DUSE_ALSA=OFF \
-DUSE_PULSE=OFF \
-DUSE_AUDIOUNIT=ON \
-DUSE_SYSTEM_FFMPEG=ON \
-DLLVM_CCACHE_BUILD=OFF \
-DLLVM_BUILD_RUNTIME=OFF \
-DLLVM_BUILD_TOOLS=OFF \
-DLLVM_INCLUDE_DOCS=OFF \
-DLLVM_INCLUDE_EXAMPLES=OFF \
-DLLVM_INCLUDE_TESTS=OFF \
-DLLVM_INCLUDE_TOOLS=OFF \
-DLLVM_INCLUDE_UTILS=OFF \
-DLLVM_USE_PERF=OFF \
-DLLVM_ENABLE_Z3_SOLVER=OFF \
-DUSE_SYSTEM_FFMPEG=OFF \
-DUSE_NATIVE_INSTRUCTIONS=OFF \
-DUSE_PRECOMPILED_HEADERS=OFF \
-DUSE_SYSTEM_MVK=ON \
-DUSE_SYSTEM_FAUDIO=OFF \
-DUSE_SYSTEM_SDL=ON \
-DUSE_SYSTEM_OPENCV=ON \
"$CMAKE_EXTRA_OPTS" \
-DLLVM_TARGET_ARCH=X86_64 \
-G Ninja
else
cmake .. \
-DBUILD_RPCS3_TESTS=OFF \
-DRUN_RPCS3_TESTS=OFF \
-DCMAKE_OSX_ARCHITECTURES=x86_64 \
-DCMAKE_SYSTEM_PROCESSOR=x86_64 \
-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_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_OSX_DEPLOYMENT_TARGET=14.4 \
-DCMAKE_OSX_SYSROOT="$(xcrun --sdk macosx --show-sdk-path)" \
-DMACOSX_BUNDLE_SHORT_VERSION_STRING="${COMM_TAG}" \
-DMACOSX_BUNDLE_BUNDLE_VERSION="${COMM_COUNT}"\
-DSTATIC_LINK_LLVM=ON \
-DUSE_SDL=ON \
-DUSE_DISCORD_RPC=ON \
-DUSE_AUDIOUNIT=ON \
-DUSE_SYSTEM_FFMPEG=OFF \
-DUSE_NATIVE_INSTRUCTIONS=OFF \
-DUSE_PRECOMPILED_HEADERS=OFF \
-DUSE_SYSTEM_MVK=ON \
-DUSE_SYSTEM_SDL=ON \
-DUSE_SYSTEM_OPENCV=ON \
-G Ninja
fi
"/opt/homebrew/bin/ninja"; build_status=$?;
ninja; build_status=$?;
cd ..
+7 -4
View File
@@ -2,6 +2,9 @@
git config --global --add safe.directory '*'
CPU_ARCH="${1:-x86_64}"
MSYS2="${2:-clang64}"
# Pull all the submodules except some
# Note: Tried to use git submodule status, but it takes over 20 seconds
# shellcheck disable=SC2046
@@ -23,7 +26,7 @@ else
fi
cmake .. \
-DCMAKE_PREFIX_PATH=/clang64 \
-DCMAKE_PREFIX_PATH=/"${MSYS2}" \
-DCMAKE_INSTALL_PREFIX=/usr \
-DUSE_NATIVE_INSTRUCTIONS=OFF \
-DUSE_PRECOMPILED_HEADERS=OFF \
@@ -44,8 +47,8 @@ cmake .. \
-DUSE_DISCORD_RPC=ON \
-DOpenGL_GL_PREFERENCE=LEGACY \
-DWITH_LLVM=ON \
-DLLVM_DIR=/clang64/lib/cmake/llvm \
-DVulkan_LIBRARY=/clang64/lib/libvulkan-1.dll.a \
-DLLVM_DIR=/"${MSYS2}"/lib/cmake/llvm \
-DVulkan_LIBRARY=/"${MSYS2}"/lib/libvulkan-1.dll.a \
-DSTATIC_LINK_LLVM=ON \
-DBUILD_RPCS3_TESTS=OFF \
-DRUN_RPCS3_TESTS=OFF \
@@ -57,5 +60,5 @@ cd ..
# If it compiled succesfully let's deploy.
if [ "$build_status" -eq 0 ]; then
.ci/deploy-windows-clang.sh "x86_64"
.ci/deploy-windows-clang.sh "${CPU_ARCH}" "${MSYS2}"
fi
-76
View File
@@ -1,76 +0,0 @@
#!/bin/sh -ex
# shellcheck disable=SC2086
cd build || exit 1
# Gather explicit version number and number of commits
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ../rpcs3/rpcs3_version.cpp)
COMM_COUNT=$(git rev-list --count HEAD)
COMM_HASH=$(git rev-parse --short=8 HEAD)
AVVER="${COMM_TAG}-${COMM_COUNT}"
# AVVER is used for GitHub releases, it is the version number.
echo "AVVER=$AVVER" >> ../.ci/ci-vars.env
cd bin
mkdir "rpcs3.app/Contents/lib/" || true
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"
rm -rf "rpcs3.app/Contents/Frameworks/QtPdf.framework" \
"rpcs3.app/Contents/Frameworks/QtQml.framework" \
"rpcs3.app/Contents/Frameworks/QtQmlModels.framework" \
"rpcs3.app/Contents/Frameworks/QtQuick.framework" \
"rpcs3.app/Contents/Frameworks/QtVirtualKeyboard.framework" \
"rpcs3.app/Contents/Plugins/platforminputcontexts" \
"rpcs3.app/Contents/Plugins/virtualkeyboard" \
"rpcs3.app/Contents/Resources/git"
../../.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 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
mv RPCS3_.app RPCS3.app
# NOTE: "--deep" is deprecated
codesign --deep -fs - RPCS3.app
echo "[InternetShortcut]" > Quickstart.url
echo "URL=https://rpcs3.net/quickstart" >> Quickstart.url
echo "IconIndex=0" >> Quickstart.url
ARCHIVE_FILEPATH="$BUILD_ARTIFACTSTAGINGDIRECTORY/rpcs3-v${COMM_TAG}-${COMM_COUNT}-${COMM_HASH}_macos_arm64.7z"
"/opt/homebrew/bin/7z" a -mx9 "$ARCHIVE_FILEPATH" RPCS3.app Quickstart.url
FILESIZE=$(stat -f %z "$ARCHIVE_FILEPATH")
SHA256SUM=$(shasum -a 256 "$ARCHIVE_FILEPATH" | awk '{ print $1 }')
cd ..
echo "${SHA256SUM};${FILESIZE}B" > "$RELEASE_MESSAGE"
cd bin
+23 -20
View File
@@ -3,24 +3,16 @@
# shellcheck disable=SC2086
cd build || exit 1
# Gather explicit version number and number of commits
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ../rpcs3/rpcs3_version.cpp)
COMM_COUNT=$(git rev-list --count HEAD)
COMM_HASH=$(git rev-parse --short=8 HEAD)
AVVER="${COMM_TAG}-${COMM_COUNT}"
# AVVER is used for GitHub releases, it is the version number.
echo "AVVER=$AVVER" >> ../.ci/ci-vars.env
cd bin
mkdir "rpcs3.app/Contents/lib/"
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 /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"
cp "$(realpath $BREW_PATH/opt/llvm@$LLVM_COMPILER_VER/lib/c++/libc++abi.1.0.dylib)" "rpcs3.app/Contents/Frameworks/libc++abi.1.dylib"
cp "$(realpath $BREW_PATH/opt/gcc/lib/gcc/current/libgcc_s.1.1.dylib)" "rpcs3.app/Contents/Frameworks/libgcc_s.1.1.dylib"
rm -rf "rpcs3.app/Contents/Frameworks/QtPdf.framework" \
"rpcs3.app/Contents/Frameworks/QtQml.framework" \
@@ -52,13 +44,20 @@ else
rm -f translations.zip
fi
# Copy Qt translations manually
QT_TRANS="$WORKDIR/qt-downloader/$QT_VER/clang_64/translations"
cp $QT_TRANS/qt_*.qm rpcs3.app/Contents/translations
cp $QT_TRANS/qtbase_*.qm rpcs3.app/Contents/translations
cp $QT_TRANS/qtmultimedia_*.qm rpcs3.app/Contents/translations
rm -f rpcs3.app/Contents/translations/qt_help_*.qm
# Need to do this rename hack due to case insensitive filesystem
mv rpcs3.app RPCS3_.app
mv RPCS3_.app RPCS3.app
# Hack
install_name_tool -delete_rpath /usr/local/lib RPCS3.app/Contents/MacOS/rpcs3
#-delete_rpath /usr/local/Cellar/sdl3/3.2.8/lib
install_name_tool -delete_rpath /opt/homebrew/lib RPCS3.app/Contents/MacOS/rpcs3 || true
install_name_tool -delete_rpath /usr/local/lib RPCS3.app/Contents/MacOS/rpcs3 || true
# NOTE: "--deep" is deprecated
codesign --deep -fs - RPCS3.app
@@ -67,8 +66,12 @@ echo "[InternetShortcut]" > Quickstart.url
echo "URL=https://rpcs3.net/quickstart" >> Quickstart.url
echo "IconIndex=0" >> Quickstart.url
ARCHIVE_FILEPATH="$BUILD_ARTIFACTSTAGINGDIRECTORY/rpcs3-v${COMM_TAG}-${COMM_COUNT}-${COMM_HASH}_macos.7z"
"/opt/homebrew/bin/7z" a -mx9 "$ARCHIVE_FILEPATH" RPCS3.app Quickstart.url
if [ "$AARCH64" -eq 1 ]; then
ARCHIVE_FILEPATH="$BUILD_ARTIFACTSTAGINGDIRECTORY/rpcs3-v${LVER}_macos_aarch64.7z"
else
ARCHIVE_FILEPATH="$BUILD_ARTIFACTSTAGINGDIRECTORY/rpcs3-v${LVER}_macos.7z"
fi
7z a -mx9 "$ARCHIVE_FILEPATH" RPCS3.app Quickstart.url
FILESIZE=$(stat -f %z "$ARCHIVE_FILEPATH")
SHA256SUM=$(shasum -a 256 "$ARCHIVE_FILEPATH" | awk '{ print $1 }')
+5 -4
View File
@@ -7,12 +7,13 @@
cd build || exit 1
CPU_ARCH="${1:-x86_64}"
MSYS2="${2:-clang64}"
echo "Deploying rpcs3 windows clang $CPU_ARCH"
# BUILD_blablabla is CI specific, so we wrap it for portability
ARTIFACT_DIR=$(cygpath -u "$BUILD_ARTIFACTSTAGINGDIRECTORY")
MSYS2_CLANG_BIN=$(cygpath -w /clang64/bin)
MSYS2_CLANG_BIN=$(cygpath -w /"${MSYS2}"/bin)
MSYS2_USR_BIN=$(cygpath -w /usr/bin)
echo "Installing dependencies of: ./bin/rpcs3.exe (MSYS2 dir is '$MSYS2_CLANG_BIN', usr dir is '$MSYS2_USR_BIN')"
@@ -22,7 +23,7 @@ cmake -DMSYS2_CLANG_BIN="$MSYS2_CLANG_BIN" -DMSYS2_USR_BIN="$MSYS2_USR_BIN" -Dex
mkdir ./bin/config
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
curl -fsSL 'https://rpcs3.net/compatibility?api=v1&export' | iconv -f ISO-8859-1 -t UTF-8 1> ./bin/GuiConfigs/compat_database.dat
# Download translations
mkdir -p ./bin/share/qt6/translations
@@ -38,7 +39,7 @@ else
echo "Failed to download translations.zip. Continuing without translations."
exit 0
}
unzip -o translations.zip -d "./bin/share/qt6/translations" >/dev/null 2>&1 || \
7z x translations.zip -o"./bin/share/qt6/translations" >/dev/null 2>&1 || \
echo "Failed to extract translations.zip. Continuing without translations."
rm -f translations.zip
fi
@@ -49,7 +50,7 @@ fi
# Generate sha256 hashes
# Write to file for GitHub releases
sha256sum "$BUILD" | awk '{ print $1 }' | tee "$BUILD.sha256"
echo "$(cat "$BUILD.sha256");$(stat -c %s "$BUILD")B" > GitHubReleaseMessage.txt
echo "$(cat "$BUILD.sha256");$(stat -c %s "$BUILD")B" > "$RELEASE_MESSAGE"
# Move files to publishing directory
mkdir -p "$ARTIFACT_DIR"
+16 -4
View File
@@ -1,7 +1,7 @@
#!/bin/sh -ex
# Resource/dependency URLs
CCACHE_URL="https://github.com/ccache/ccache/releases/download/v4.11.2/ccache-4.11.2-windows-x86_64.zip"
CCACHE_URL="https://github.com/ccache/ccache/releases/download/v4.12.3/ccache-4.12.3-windows-x86_64.zip"
DEP_URLS=" \
$CCACHE_URL"
@@ -28,11 +28,23 @@ download_and_verify()
correctChecksum="$2"
algo="$3"
fileName="$4"
path="$DEPS_CACHE_DIR/$fileName"
for _ in 1 2 3; do
[ -e "$DEPS_CACHE_DIR/$fileName" ] || curl -fLo "$DEPS_CACHE_DIR/$fileName" "$url"
fileChecksum=$("${algo}sum" "$DEPS_CACHE_DIR/$fileName" | awk '{ print $1 }')
[ "$fileChecksum" = "$correctChecksum" ] && return 0
# Check if the file exists and the checksum is correct
if [ -e "$path" ]; then
fileChecksum=$("${algo}sum" "$path" | awk '{ print $1 }')
[ "$fileChecksum" = "$correctChecksum" ] && return 0
fi
# Otherwise download the file
curl -fLo "$path" "$url"
# Check again if the file exists and the checksum is correct
if [ -e "$path" ]; then
fileChecksum=$("${algo}sum" "$path" | awk '{ print $1 }')
[ "$fileChecksum" = "$correctChecksum" ] && return 0
fi
done
return 1;
+9 -2
View File
@@ -13,14 +13,21 @@ COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ./rpcs3/rpcs3_
COMM_COUNT=$(git rev-list --count HEAD)
COMM_HASH=$(git rev-parse --short=8 HEAD)
# Differentiate Windows builds
if [ "$COMPILER" = 'clang' ];then
BUILD_SUFFIX="win64_${CPU_ARCH}_${COMPILER}"
else
BUILD_SUFFIX="${CPU_ARCH}_${COMPILER}"
fi
# Format the above into filenames
if [ -n "$PR_NUMBER" ]; then
AVVER="${COMM_TAG}-${COMM_HASH}"
BUILD_RAW="rpcs3-v${AVVER}_${CPU_ARCH}_${COMPILER}"
BUILD_RAW="rpcs3-v${AVVER}_${BUILD_SUFFIX}"
BUILD="${BUILD_RAW}.7z"
else
AVVER="${COMM_TAG}-${COMM_COUNT}"
BUILD_RAW="rpcs3-v${AVVER}-${COMM_HASH}_${CPU_ARCH}_${COMPILER}"
BUILD_RAW="rpcs3-v${AVVER}-${COMM_HASH}_${BUILD_SUFFIX}"
BUILD="${BUILD_RAW}.7z"
fi
+18 -4
View File
@@ -14,9 +14,10 @@ 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}"
QT_MM_URL="${QT_HOST}${QT_PREFIX}addons.qtmultimedia.${QT_PREFIX_2}qtmultimedia${QT_SUFFIX}"
QT_SVG_URL="${QT_HOST}${QT_PREFIX}${QT_PREFIX_2}qtsvg${QT_SUFFIX}"
QT_TRANSLATIONS_URL="${QT_HOST}${QT_PREFIX}${QT_PREFIX_2}qttranslations${QT_SUFFIX}"
LLVMLIBS_URL="https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win-${LLVM_VER}/llvmlibs_mt.7z"
VULKAN_SDK_URL="https://www.dropbox.com/scl/fi/sjjh0fc4ld281pjbl2xzu/VulkanSDK-${VULKAN_VER}-Installer.exe?rlkey=f6wzc0lvms5vwkt2z3qabfv9d&dl=1"
CCACHE_URL="https://github.com/ccache/ccache/releases/download/v4.11.2/ccache-4.11.2-windows-x86_64.zip"
CCACHE_URL="https://github.com/ccache/ccache/releases/download/v4.12.3/ccache-4.12.3-windows-x86_64.zip"
DEP_URLS=" \
$QT_BASE_URL \
@@ -24,6 +25,7 @@ DEP_URLS=" \
$QT_TOOL_URL \
$QT_MM_URL \
$QT_SVG_URL \
$QT_TRANSLATIONS_URL \
$LLVMLIBS_URL \
$VULKAN_SDK_URL\
$CCACHE_URL"
@@ -51,11 +53,23 @@ download_and_verify()
correctChecksum="$2"
algo="$3"
fileName="$4"
path="$DEPS_CACHE_DIR/$fileName"
for _ in 1 2 3; do
[ -e "$DEPS_CACHE_DIR/$fileName" ] || curl -fLo "$DEPS_CACHE_DIR/$fileName" "$url"
fileChecksum=$("${algo}sum" "$DEPS_CACHE_DIR/$fileName" | awk '{ print $1 }')
[ "$fileChecksum" = "$correctChecksum" ] && return 0
# Check if the file exists and the checksum is correct
if [ -e "$path" ]; then
fileChecksum=$("${algo}sum" "$path" | awk '{ print $1 }')
[ "$fileChecksum" = "$correctChecksum" ] && return 0
fi
# Otherwise download the file
curl -fLo "$path" "$url"
# Check again if the file exists and the checksum is correct
if [ -e "$path" ]; then
fileChecksum=$("${algo}sum" "$path" | awk '{ print $1 }')
[ "$fileChecksum" = "$correctChecksum" ] && return 0
fi
done
return 1;
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
runs-on: windows-2025
env:
COMPILER: msvc
CCACHE_SHA: '1f39f3ad5aae3fe915e99ad1302633bc8f6718e58fa7c0de2b0ba7e080f0f08c'
CCACHE_SHA: '859141059ac950e1e8cd042c66f842f26b9e3a62a1669a69fe6ba180cb58bbdf'
CCACHE_BIN_DIR: 'C:\ccache_bin'
CCACHE_DIR: 'C:\ccache'
CCACHE_INODECACHE: 'true'
+74 -37
View File
@@ -30,23 +30,23 @@ jobs:
matrix:
include:
- os: ubuntu-24.04
docker_img: "rpcs3/rpcs3-ci-jammy:1.7"
docker_img: "rpcs3/rpcs3-ci-jammy:1.9"
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.7"
docker_img: "rpcs3/rpcs3-ci-jammy:1.9"
build_sh: "/rpcs3/.ci/build-linux.sh"
compiler: gcc
- os: ubuntu-24.04-arm
docker_img: "rpcs3/rpcs3-ci-jammy-aarch64:1.7"
docker_img: "rpcs3/rpcs3-ci-jammy-aarch64:1.9"
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.7"
docker_img: "rpcs3/rpcs3-ci-jammy-aarch64:1.9"
build_sh: "/rpcs3/.ci/build-linux-aarch64.sh"
compiler: gcc
name: RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }}
@@ -123,23 +123,24 @@ jobs:
matrix:
include:
- name: Intel
build_sh: .ci/build-mac.sh
AARCH64: 0
UPLOAD_COMMIT_HASH: 51ae32f468089a8169aaf1567de355ff4a3e0842
UPLOAD_REPO_FULL_NAME: rpcs3/rpcs3-binaries-mac
- name: Apple Silicon
build_sh: .ci/build-mac-arm64.sh
AARCH64: 1
UPLOAD_COMMIT_HASH: 8e21bdbc40711a3fccd18fbf17b742348b0f4281
UPLOAD_REPO_FULL_NAME: rpcs3/rpcs3-binaries-mac-arm64
name: RPCS3 Mac ${{ matrix.name }}
runs-on: macos-14
env:
CCACHE_DIR: /tmp/ccache_dir
QT_VER: '6.10.1'
QT_VER: '6.10.2'
QT_VER_MAIN: '6'
LLVM_COMPILER_VER: '21'
RELEASE_MESSAGE: ../GitHubReleaseMessage.txt
UPLOAD_COMMIT_HASH: ${{ matrix.UPLOAD_COMMIT_HASH }}
UPLOAD_REPO_FULL_NAME: ${{ matrix.UPLOAD_REPO_FULL_NAME }}
AARCH64: ${{ matrix.AARCH64 }}
RUN_UNIT_TESTS: github.event_name == 'pull_request' && 'ON' || 'OFF'
steps:
- name: Checkout repository
@@ -164,7 +165,7 @@ jobs:
restore-keys: ${{ runner.os }}-qt-${{ matrix.name }}-${{ env.QT_VER }}
- name: Build
run: ${{ matrix.build_sh }}
run: .ci/build-mac.sh
- name: Upload artifacts
uses: actions/upload-artifact@main
@@ -212,13 +213,13 @@ jobs:
env:
COMPILER: msvc
QT_VER_MAIN: '6'
QT_VER: '6.10.1'
QT_VER: '6.10.2'
QT_VER_MSVC: 'msvc2022'
QT_DATE: '202511161843'
QT_DATE: '202601261212'
LLVM_VER: '19.1.7'
VULKAN_VER: '1.3.268.0'
VULKAN_SDK_SHA: '8459ef49bd06b697115ddd3d97c9aec729e849cd775f5be70897718a9b3b9db5'
CCACHE_SHA: '1f39f3ad5aae3fe915e99ad1302633bc8f6718e58fa7c0de2b0ba7e080f0f08c'
CCACHE_SHA: '859141059ac950e1e8cd042c66f842f26b9e3a62a1669a69fe6ba180cb58bbdf'
CCACHE_BIN_DIR: 'C:\ccache_bin'
CCACHE_DIR: 'C:\ccache'
CCACHE_INODECACHE: 'true'
@@ -328,16 +329,25 @@ jobs:
Windows_Build_Clang:
# Only run push event on master branch of main repo, but run all PRs
if: github.event_name != 'push' || (github.repository == 'RPCS3/rpcs3' && github.ref_name == 'master')
name: RPCS3 Windows Clang
runs-on: windows-2025
strategy:
fail-fast: false
matrix:
include:
- msys2: clang64
compiler: clang
arch: win64
arch: x86_64
os: windows-2025
name: X64
- msys2: clangarm64
compiler: clang
arch: aarch64
os: windows-11-arm
name: ARM64
env:
CCACHE_DIR: 'C:\ccache'
RELEASE_MESSAGE: ../GitHubReleaseMessage.txt
name: RPCS3 Windows Clang ${{ matrix.arch }}
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@main
@@ -351,23 +361,26 @@ jobs:
update: true
cache: true
install: |
mingw-w64-clang-x86_64-clang
mingw-w64-clang-x86_64-ccache
mingw-w64-clang-x86_64-cmake
mingw-w64-clang-x86_64-lld
mingw-w64-clang-x86_64-ninja
mingw-w64-clang-x86_64-llvm
mingw-w64-clang-x86_64-ffmpeg
mingw-w64-clang-x86_64-opencv
mingw-w64-clang-x86_64-glew
mingw-w64-clang-x86_64-vulkan
mingw-w64-clang-x86_64-vulkan-headers
mingw-w64-clang-x86_64-vulkan-loader
mingw-w64-clang-x86_64-gtest
mingw-w64-clang-x86_64-qt6-base
mingw-w64-clang-x86_64-qt6-declarative
mingw-w64-clang-x86_64-qt6-multimedia
mingw-w64-clang-x86_64-qt6-svg
mingw-w64-clang-${{ matrix.arch }}-clang
mingw-w64-clang-${{ matrix.arch }}-ccache
mingw-w64-clang-${{ matrix.arch }}-cmake
mingw-w64-clang-${{ matrix.arch }}-lld
mingw-w64-clang-${{ matrix.arch }}-ninja
mingw-w64-clang-${{ matrix.arch }}-llvm
mingw-w64-clang-${{ matrix.arch }}-ffmpeg
mingw-w64-clang-${{ matrix.arch }}-opencv
mingw-w64-clang-${{ matrix.arch }}-iconv
mingw-w64-clang-${{ matrix.arch }}-glew
mingw-w64-clang-${{ matrix.arch }}-vulkan
mingw-w64-clang-${{ matrix.arch }}-vulkan-headers
mingw-w64-clang-${{ matrix.arch }}-vulkan-loader
mingw-w64-clang-${{ matrix.arch }}-gtest
mingw-w64-clang-${{ matrix.arch }}-qt6-base
mingw-w64-clang-${{ matrix.arch }}-qt6-declarative
mingw-w64-clang-${{ matrix.arch }}-qt6-multimedia
mingw-w64-clang-${{ matrix.arch }}-qt6-svg
mingw-w64-clang-${{ matrix.arch }}-qt6-tools
mingw-w64-clang-${{ matrix.arch }}-qt6-translations
base-devel
curl
git
@@ -378,8 +391,8 @@ jobs:
id: restore-build-ccache
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ runner.arch }}-${{ github.run_id }}
restore-keys: ${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ runner.arch }}-
key: ${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ matrix.arch }}-${{ github.run_id }}
restore-keys: ${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ matrix.arch }}-
- name: Build RPCS3
shell: msys2 {0}
@@ -387,7 +400,25 @@ jobs:
export CCACHE_DIR=$(cygpath -u "$CCACHE_DIR")
echo "CCACHE_DIR=$CCACHE_DIR"
.ci/setup-windows-ci-vars.sh ${{ matrix.arch }} ${{ matrix.compiler }}
.ci/build-windows-clang.sh
.ci/build-windows-clang.sh ${{ matrix.arch }} ${{ matrix.msys2 }}
- name: Deploy master build to GitHub Releases (only aarch64)
if: |
matrix.arch == 'aarch64' &&
github.event_name != 'pull_request' &&
github.repository == 'RPCS3/rpcs3' &&
github.ref == 'refs/heads/master'
env:
RPCS3_TOKEN: ${{ secrets.RPCS3_TOKEN }}
# We specify it here since this upload is specific to arm64
UPLOAD_COMMIT_HASH: ee05050fd1d8488148a771b526702656a10dacf0
UPLOAD_REPO_FULL_NAME: "RPCS3/rpcs3-binaries-win-arm64"
run: |
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ./rpcs3/rpcs3_version.cpp)
COMM_COUNT=$(git rev-list --count HEAD)
COMM_HASH=$(git rev-parse --short=8 HEAD)
export AVVER="${COMM_TAG}-${COMM_COUNT}"
.ci/github-upload.sh
- name: Save build Ccache
if: github.ref == 'refs/heads/master'
@@ -399,7 +430,7 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@main
with:
name: RPCS3 for Windows (${{ runner.arch }}, ${{ matrix.compiler }})
name: RPCS3 for Windows (${{ matrix.name }}, clang)
path: ${{ env.BUILD_ARTIFACTSTAGINGDIRECTORY }}
compression-level: 0
if-no-files-found: error
@@ -413,7 +444,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,8 +467,10 @@ 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
copyback: false
release: "14.3"
run: .ci/install-freebsd.sh && .ci/build-freebsd.sh
- name: Save Build Ccache
+4 -4
View File
@@ -52,10 +52,6 @@
path = 3rdparty/wolfssl/wolfssl
url = ../../wolfSSL/wolfssl.git
ignore = dirty
[submodule "3rdparty/flatbuffers"]
path = 3rdparty/flatbuffers
url = ../../google/flatbuffers.git
ignore = dirty
[submodule "3rdparty/cubeb/cubeb"]
path = 3rdparty/cubeb/cubeb
url = ../../mozilla/cubeb.git
@@ -112,3 +108,7 @@
path = 3rdparty/feralinteractive/feralinteractive
url = ../../FeralInteractive/gamemode.git
ignore = dirty
[submodule "3rdparty/protobuf/protobuf"]
path = 3rdparty/protobuf/protobuf
url = ../../protocolbuffers/protobuf.git
ignore = dirty
+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/")
+10 -22
View File
@@ -25,18 +25,8 @@ add_subdirectory(zstd EXCLUDE_FROM_ALL)
# 7zip sdk
add_subdirectory(7zip EXCLUDE_FROM_ALL)
add_library(3rdparty_flatbuffers INTERFACE)
if (USE_SYSTEM_FLATBUFFERS)
pkg_check_modules(FLATBUFFERS REQUIRED IMPORTED_TARGET flatbuffers>=2.0.0)
target_link_libraries(3rdparty_flatbuffers INTERFACE PkgConfig::FLATBUFFERS)
set(FBS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../rpcs3/Emu/NP/generated/")
execute_process(COMMAND flatc --cpp -o "${FBS_DIR}" "${FBS_DIR}/np2_structs.fbs" RESULT_VARIABLE FBS_CMD_ERROR)
if(FBS_CMD_ERROR AND NOT FBS_CMD_ERROR EQUAL 0)
message(FATAL_ERROR "flatc failed to regenerate flatbuffers headers.")
endif()
else()
target_include_directories(3rdparty_flatbuffers INTERFACE flatbuffers/include)
endif()
# Protobuf
add_subdirectory(protobuf EXCLUDE_FROM_ALL)
# libPNG
add_subdirectory(libpng EXCLUDE_FROM_ALL)
@@ -56,7 +46,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 +97,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 +109,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 +192,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()
@@ -298,7 +286,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 +316,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()
@@ -374,7 +362,7 @@ endif()
add_library(3rdparty::zlib ALIAS 3rdparty_zlib)
add_library(3rdparty::zstd ALIAS 3rdparty_zstd)
add_library(3rdparty::7zip ALIAS 3rdparty_7zip)
add_library(3rdparty::flatbuffers ALIAS 3rdparty_flatbuffers)
add_library(3rdparty::protobuf ALIAS 3rdparty_protobuf)
add_library(3rdparty::pugixml ALIAS pugixml)
add_library(3rdparty::glslang ALIAS 3rdparty_glslang)
add_library(3rdparty::yaml-cpp ALIAS yaml-cpp)
+123 -2
View File
@@ -6,7 +6,7 @@ extern "C" {
#endif
/*
** Copyright 2013-2020 The Khronos Group Inc.
** Copyright 2013-2026 The Khronos Group Inc.
** SPDX-License-Identifier: MIT
**
** This header is generated from the Khronos OpenGL / OpenGL ES XML
@@ -32,7 +32,7 @@ extern "C" {
#define GLAPI extern
#endif
#define GL_GLEXT_VERSION 20250203
#define GL_GLEXT_VERSION 20260126
#include <KHR/khrplatform.h>
@@ -7358,6 +7358,47 @@ GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const voi
#endif
#endif /* GL_EXT_fog_coord */
#ifndef GL_EXT_fragment_shading_rate
#define GL_EXT_fragment_shading_rate 1
#define GL_SHADING_RATE_1X1_PIXELS_EXT 0x96A6
#define GL_SHADING_RATE_1X2_PIXELS_EXT 0x96A7
#define GL_SHADING_RATE_2X1_PIXELS_EXT 0x96A8
#define GL_SHADING_RATE_2X2_PIXELS_EXT 0x96A9
#define GL_SHADING_RATE_1X4_PIXELS_EXT 0x96AA
#define GL_SHADING_RATE_4X1_PIXELS_EXT 0x96AB
#define GL_SHADING_RATE_4X2_PIXELS_EXT 0x96AC
#define GL_SHADING_RATE_2X4_PIXELS_EXT 0x96AD
#define GL_SHADING_RATE_4X4_PIXELS_EXT 0x96AE
#define GL_SHADING_RATE_EXT 0x96D0
#define GL_SHADING_RATE_ATTACHMENT_EXT 0x96D1
#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT 0x96D2
#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT 0x96D3
#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_EXT 0x96D4
#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_EXT 0x96D5
#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_EXT 0x96D6
#define GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT 0x96D7
#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT 0x96D8
#define GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT 0x96D9
#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT 0x96DA
#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_ASPECT_RATIO_EXT 0x96DB
#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT 0x96DC
#define GL_FRAGMENT_SHADING_RATE_WITH_SHADER_DEPTH_STENCIL_WRITES_SUPPORTED_EXT 0x96DD
#define GL_FRAGMENT_SHADING_RATE_WITH_SAMPLE_MASK_SUPPORTED_EXT 0x96DE
#define GL_FRAGMENT_SHADING_RATE_ATTACHMENT_WITH_DEFAULT_FRAMEBUFFER_SUPPORTED_EXT 0x96DF
#define GL_FRAGMENT_SHADING_RATE_NON_TRIVIAL_COMBINERS_SUPPORTED_EXT 0x8F6F
#define GL_FRAGMENT_SHADING_RATE_PRIMITIVE_RATE_WITH_MULTI_VIEWPORT_SUPPORTED_EXT 0x9780
typedef void (APIENTRYP PFNGLGETFRAGMENTSHADINGRATESEXTPROC) (GLsizei samples, GLsizei maxCount, GLsizei *count, GLenum *shadingRates);
typedef void (APIENTRYP PFNGLSHADINGRATEEXTPROC) (GLenum rate);
typedef void (APIENTRYP PFNGLSHADINGRATECOMBINEROPSEXTPROC) (GLenum combinerOp0, GLenum combinerOp1);
typedef void (APIENTRYP PFNGLFRAMEBUFFERSHADINGRATEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint baseLayer, GLsizei numLayers, GLsizei texelWidth, GLsizei texelHeight);
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glGetFragmentShadingRatesEXT (GLsizei samples, GLsizei maxCount, GLsizei *count, GLenum *shadingRates);
GLAPI void APIENTRY glShadingRateEXT (GLenum rate);
GLAPI void APIENTRY glShadingRateCombinerOpsEXT (GLenum combinerOp0, GLenum combinerOp1);
GLAPI void APIENTRY glFramebufferShadingRateEXT (GLenum target, GLenum attachment, GLuint texture, GLint baseLayer, GLsizei numLayers, GLsizei texelWidth, GLsizei texelHeight);
#endif
#endif /* GL_EXT_fragment_shading_rate */
#ifndef GL_EXT_framebuffer_blit
#define GL_EXT_framebuffer_blit 1
#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
@@ -7816,6 +7857,86 @@ GLAPI void APIENTRY glImportMemoryWin32NameEXT (GLuint memory, GLuint64 size, GL
#endif
#endif /* GL_EXT_memory_object_win32 */
#ifndef GL_EXT_mesh_shader
#define GL_EXT_mesh_shader 1
#define GL_MESH_SHADER_EXT 0x9559
#define GL_TASK_SHADER_EXT 0x955A
#define GL_MAX_MESH_UNIFORM_BLOCKS_EXT 0x8E60
#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_EXT 0x8E61
#define GL_MAX_MESH_IMAGE_UNIFORMS_EXT 0x8E62
#define GL_MAX_MESH_UNIFORM_COMPONENTS_EXT 0x8E63
#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_EXT 0x8E64
#define GL_MAX_MESH_ATOMIC_COUNTERS_EXT 0x8E65
#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_EXT 0x8E66
#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_EXT 0x8E67
#define GL_MAX_TASK_UNIFORM_BLOCKS_EXT 0x8E68
#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_EXT 0x8E69
#define GL_MAX_TASK_IMAGE_UNIFORMS_EXT 0x8E6A
#define GL_MAX_TASK_UNIFORM_COMPONENTS_EXT 0x8E6B
#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_EXT 0x8E6C
#define GL_MAX_TASK_ATOMIC_COUNTERS_EXT 0x8E6D
#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_EXT 0x8E6E
#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_EXT 0x8E6F
#define GL_MAX_TASK_WORK_GROUP_TOTAL_COUNT_EXT 0x9740
#define GL_MAX_MESH_WORK_GROUP_TOTAL_COUNT_EXT 0x9741
#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_EXT 0x9757
#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_EXT 0x9759
#define GL_MAX_TASK_PAYLOAD_SIZE_EXT 0x9742
#define GL_MAX_TASK_SHARED_MEMORY_SIZE_EXT 0x9743
#define GL_MAX_MESH_SHARED_MEMORY_SIZE_EXT 0x9744
#define GL_MAX_TASK_PAYLOAD_AND_SHARED_MEMORY_SIZE_EXT 0x9745
#define GL_MAX_MESH_PAYLOAD_AND_SHARED_MEMORY_SIZE_EXT 0x9746
#define GL_MAX_MESH_OUTPUT_MEMORY_SIZE_EXT 0x9747
#define GL_MAX_MESH_PAYLOAD_AND_OUTPUT_MEMORY_SIZE_EXT 0x9748
#define GL_MAX_MESH_OUTPUT_VERTICES_EXT 0x9538
#define GL_MAX_MESH_OUTPUT_PRIMITIVES_EXT 0x9756
#define GL_MAX_MESH_OUTPUT_COMPONENTS_EXT 0x9749
#define GL_MAX_MESH_OUTPUT_LAYERS_EXT 0x974A
#define GL_MAX_MESH_MULTIVIEW_VIEW_COUNT_EXT 0x9557
#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_EXT 0x92DF
#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_EXT 0x9543
#define GL_MAX_PREFERRED_TASK_WORK_GROUP_INVOCATIONS_EXT 0x974B
#define GL_MAX_PREFERRED_MESH_WORK_GROUP_INVOCATIONS_EXT 0x974C
#define GL_MESH_PREFERS_LOCAL_INVOCATION_VERTEX_OUTPUT_EXT 0x974D
#define GL_MESH_PREFERS_LOCAL_INVOCATION_PRIMITIVE_OUTPUT_EXT 0x974E
#define GL_MESH_PREFERS_COMPACT_VERTEX_OUTPUT_EXT 0x974F
#define GL_MESH_PREFERS_COMPACT_PRIMITIVE_OUTPUT_EXT 0x9750
#define GL_MAX_TASK_WORK_GROUP_COUNT_EXT 0x9751
#define GL_MAX_MESH_WORK_GROUP_COUNT_EXT 0x9752
#define GL_MAX_MESH_WORK_GROUP_SIZE_EXT 0x9758
#define GL_MAX_TASK_WORK_GROUP_SIZE_EXT 0x975A
#define GL_MESH_WORK_GROUP_SIZE_EXT 0x953E
#define GL_TASK_WORK_GROUP_SIZE_EXT 0x953F
#define GL_MESH_VERTICES_OUT_EXT 0x9579
#define GL_MESH_PRIMITIVES_OUT_EXT 0x957A
#define GL_MESH_OUTPUT_TYPE_EXT 0x957B
#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_EXT 0x959C
#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_EXT 0x959D
#define GL_REFERENCED_BY_MESH_SHADER_EXT 0x95A0
#define GL_REFERENCED_BY_TASK_SHADER_EXT 0x95A1
#define GL_TASK_SHADER_INVOCATIONS_EXT 0x9753
#define GL_MESH_SHADER_INVOCATIONS_EXT 0x9754
#define GL_MESH_PRIMITIVES_GENERATED_EXT 0x9755
#define GL_MESH_SHADER_BIT_EXT 0x00000040
#define GL_TASK_SHADER_BIT_EXT 0x00000080
#define GL_MESH_SUBROUTINE_EXT 0x957C
#define GL_TASK_SUBROUTINE_EXT 0x957D
#define GL_MESH_SUBROUTINE_UNIFORM_EXT 0x957E
#define GL_TASK_SUBROUTINE_UNIFORM_EXT 0x957F
#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_EXT 0x959E
#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_EXT 0x959F
typedef void (APIENTRYP PFNGLDRAWMESHTASKSEXTPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
typedef void (APIENTRYP PFNGLDRAWMESHTASKSINDIRECTEXTPROC) (GLintptr indirect);
typedef void (APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTEXTPROC) (GLintptr indirect, GLsizei drawcount, GLsizei stride);
typedef void (APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTEXTPROC) (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glDrawMeshTasksEXT (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
GLAPI void APIENTRY glDrawMeshTasksIndirectEXT (GLintptr indirect);
GLAPI void APIENTRY glMultiDrawMeshTasksIndirectEXT (GLintptr indirect, GLsizei drawcount, GLsizei stride);
GLAPI void APIENTRY glMultiDrawMeshTasksIndirectCountEXT (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
#endif
#endif /* GL_EXT_mesh_shader */
#ifndef GL_EXT_misc_attribute
#define GL_EXT_misc_attribute 1
#endif /* GL_EXT_misc_attribute */
+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
+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()
Submodule 3rdparty/flatbuffers deleted from 595bf0007a
+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})
+29 -7
View File
@@ -23,6 +23,7 @@
<ClInclude Include="SDL\include\SDL3\SDL_clipboard.h" />
<ClInclude Include="SDL\include\SDL3\SDL_copying.h" />
<ClInclude Include="SDL\include\SDL3\SDL_cpuinfo.h" />
<ClInclude Include="SDL\include\SDL3\SDL_dlopennote.h" />
<ClInclude Include="SDL\include\SDL3\SDL_egl.h" />
<ClInclude Include="SDL\include\SDL3\SDL_endian.h" />
<ClInclude Include="SDL\include\SDL3\SDL_error.h" />
@@ -102,6 +103,7 @@
<ClInclude Include="SDL\src\audio\wasapi\SDL_wasapi.h" />
<ClInclude Include="SDL\src\camera\SDL_camera_c.h" />
<ClInclude Include="SDL\src\camera\SDL_syscamera.h" />
<ClInclude Include="SDL\src\core\SDL_core_unsupported.h" />
<ClInclude Include="SDL\src\core\windows\SDL_directx.h" />
<ClInclude Include="SDL\src\core\windows\SDL_gameinput.h" />
<ClInclude Include="SDL\src\core\windows\SDL_hid.h" />
@@ -130,6 +132,8 @@
<ClInclude Include="SDL\src\filesystem\SDL_sysfilesystem.h" />
<ClInclude Include="SDL\src\gpu\SDL_sysgpu.h" />
<ClInclude Include="SDL\src\gpu\vulkan\SDL_gpu_vulkan_vkfuncs.h" />
<ClInclude Include="SDL\src\haptic\hidapi\SDL_hidapihaptic.h" />
<ClInclude Include="SDL\src\haptic\hidapi\SDL_hidapihaptic_c.h" />
<ClInclude Include="SDL\src\io\SDL_asyncio_c.h" />
<ClInclude Include="SDL\src\io\SDL_sysasyncio.h" />
<ClInclude Include="SDL\src\haptic\SDL_haptic_c.h" />
@@ -140,7 +144,11 @@
<ClInclude Include="SDL\src\hidapi\SDL_hidapi_c.h" />
<ClInclude Include="SDL\src\joystick\controller_type.h" />
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapijoystick_c.h" />
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_flydigi.h" />
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_nintendo.h" />
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_rumble.h" />
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_sinput.h" />
<ClInclude Include="SDL\src\joystick\hidapi\SDL_report_descriptor.h" />
<ClInclude Include="SDL\src\joystick\SDL_gamepad_c.h" />
<ClInclude Include="SDL\src\joystick\SDL_gamepad_db.h" />
<ClInclude Include="SDL\src\joystick\SDL_joystick_c.h" />
@@ -156,6 +164,7 @@
<ClInclude Include="SDL\src\libm\math_private.h" />
<ClInclude Include="SDL\src\locale\SDL_syslocale.h" />
<ClInclude Include="SDL\src\main\SDL_main_callbacks.h" />
<ClInclude Include="SDL\src\misc\SDL_libusb.h" />
<ClInclude Include="SDL\src\misc\SDL_sysurl.h" />
<ClInclude Include="SDL\src\power\SDL_syspower.h" />
<ClInclude Include="SDL\src\render\direct3d11\SDL_shaders_d3d11.h" />
@@ -175,7 +184,6 @@
<ClInclude Include="SDL\src\render\software\SDL_drawline.h" />
<ClInclude Include="SDL\src\render\software\SDL_drawpoint.h" />
<ClInclude Include="SDL\src\render\software\SDL_render_sw_c.h" />
<ClInclude Include="SDL\src\render\software\SDL_rotate.h" />
<ClInclude Include="SDL\src\render\software\SDL_triangle.h" />
<ClInclude Include="SDL\src\render\vulkan\SDL_shaders_vulkan.h" />
<ClInclude Include="SDL\src\SDL_assert_c.h" />
@@ -184,20 +192,35 @@
<ClCompile Include="SDL\src\camera\dummy\SDL_camera_dummy.c" />
<ClCompile Include="SDL\src\camera\mediafoundation\SDL_camera_mediafoundation.c" />
<ClCompile Include="SDL\src\camera\SDL_camera.c" />
<ClCompile Include="SDL\src\core\windows\pch_cpp.cpp" />
<ClCompile Include="SDL\src\core\windows\SDL_gameinput.cpp" />
<ClCompile Include="SDL\src\dialog\SDL_dialog.c" />
<ClCompile Include="SDL\src\dialog\SDL_dialog_utils.c" />
<ClCompile Include="SDL\src\filesystem\SDL_filesystem.c" />
<ClCompile Include="SDL\src\filesystem\windows\SDL_sysfsops.c" />
<ClCompile Include="SDL\src\haptic\hidapi\SDL_hidapihaptic.c" />
<ClCompile Include="SDL\src\haptic\hidapi\SDL_hidapihaptic_lg4ff.c" />
<ClCompile Include="SDL\src\io\windows\SDL_asyncio_windows_ioring.c" />
<ClCompile Include="SDL\src\gpu\SDL_gpu.c" />
<ClCompile Include="SDL\src\gpu\d3d12\SDL_gpu_d3d12.c" />
<ClCompile Include="SDL\src\gpu\vulkan\SDL_gpu_vulkan.c" />
<ClCompile Include="SDL\src\io\generic\SDL_asyncio_generic.c" />
<ClCompile Include="SDL\src\io\SDL_asyncio.c" />
<ClCompile Include="SDL\src\joystick\gdk\SDL_gameinputjoystick.cpp" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_8bitdo.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_flydigi.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_gip.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_lg4ff.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_sinput.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_steam_triton.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_switch2.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_zuiki.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_report_descriptor.c" />
<ClCompile Include="SDL\src\main\generic\SDL_sysmain_callbacks.c" />
<ClCompile Include="SDL\src\main\SDL_main_callbacks.c" />
<ClCompile Include="SDL\src\main\SDL_runapp.c" />
<ClCompile Include="SDL\src\main\windows\SDL_sysmain_runapp.c" />
<ClCompile Include="SDL\src\misc\SDL_libusb.c" />
<ClCompile Include="SDL\src\render\vulkan\SDL_render_vulkan.c" />
<ClCompile Include="SDL\src\render\vulkan\SDL_shaders_vulkan.c" />
<ClCompile Include="SDL\src\SDL_guid.c" />
@@ -241,6 +264,7 @@
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xcb.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xlib.h" />
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xlib_xrandr.h" />
<ClInclude Include="SDL\src\video\miniz.h" />
<ClInclude Include="SDL\src\video\offscreen\SDL_offscreenevents_c.h" />
<ClInclude Include="SDL\src\video\offscreen\SDL_offscreenframebuffer_c.h" />
<ClInclude Include="SDL\src\video\offscreen\SDL_offscreenopengles.h" />
@@ -256,13 +280,14 @@
<ClInclude Include="SDL\src\video\SDL_pixels_c.h" />
<ClInclude Include="SDL\src\video\SDL_rect_c.h" />
<ClInclude Include="SDL\src\video\SDL_RLEaccel_c.h" />
<ClInclude Include="SDL\src\video\SDL_rotate.h" />
<ClInclude Include="SDL\src\video\SDL_stb_c.h" />
<ClInclude Include="SDL\src\video\SDL_surface_c.h" />
<ClInclude Include="SDL\src\video\SDL_sysvideo.h" />
<ClInclude Include="SDL\src\video\SDL_video_unsupported.h" />
<ClInclude Include="SDL\src\video\SDL_vulkan_internal.h" />
<ClInclude Include="SDL\src\video\SDL_yuv_c.h" />
<ClInclude Include="SDL\src\video\windows\SDL_msctf.h" />
<ClInclude Include="SDL\src\video\windows\SDL_surface_utils.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsclipboard.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsevents.h" />
<ClInclude Include="SDL\src\video\windows\SDL_windowsframebuffer.h" />
@@ -303,7 +328,6 @@
<ClCompile Include="SDL\src\audio\SDL_wave.c" />
<ClCompile Include="SDL\src\audio\wasapi\SDL_wasapi.c" />
<ClCompile Include="SDL\src\core\SDL_core_unsupported.c" />
<ClCompile Include="SDL\src\core\windows\SDL_gameinput.c" />
<ClCompile Include="SDL\src\core\windows\SDL_hid.c" />
<ClCompile Include="SDL\src\core\windows\SDL_immdevice.c" />
<ClCompile Include="SDL\src\core\windows\SDL_windows.c" />
@@ -333,7 +357,6 @@
<ClCompile Include="SDL\src\hidapi\SDL_hidapi.c" />
<ClCompile Include="SDL\src\joystick\controller_type.c" />
<ClCompile Include="SDL\src\joystick\dummy\SDL_sysjoystick.c" />
<ClCompile Include="SDL\src\joystick\gdk\SDL_gameinputjoystick.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapijoystick.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_combined.c" />
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_gamecube.c" />
@@ -393,7 +416,6 @@
<ClCompile Include="SDL\src\render\software\SDL_drawline.c" />
<ClCompile Include="SDL\src\render\software\SDL_drawpoint.c" />
<ClCompile Include="SDL\src\render\software\SDL_render_sw.c" />
<ClCompile Include="SDL\src\render\software\SDL_rotate.c" />
<ClCompile Include="SDL\src\render\software\SDL_triangle.c" />
<ClCompile Include="SDL\src\SDL.c" />
<ClCompile Include="SDL\src\SDL_assert.c" />
@@ -464,6 +486,7 @@
<ClCompile Include="SDL\src\video\SDL_pixels.c" />
<ClCompile Include="SDL\src\video\SDL_rect.c" />
<ClCompile Include="SDL\src\video\SDL_RLEaccel.c" />
<ClCompile Include="SDL\src\video\SDL_rotate.c" />
<ClCompile Include="SDL\src\video\SDL_stb.c" />
<ClCompile Include="SDL\src\video\SDL_stretch.c" />
<ClCompile Include="SDL\src\video\SDL_surface.c" />
@@ -471,12 +494,11 @@
<ClCompile Include="SDL\src\video\SDL_video_unsupported.c" />
<ClCompile Include="SDL\src\video\SDL_vulkan_utils.c" />
<ClCompile Include="SDL\src\video\SDL_yuv.c" />
<ClCompile Include="SDL\src\video\windows\SDL_surface_utils.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsclipboard.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsevents.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsframebuffer.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsgameinput.cpp" />
<ClCompile Include="SDL\src\video\windows\SDL_windowskeyboard.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsgameinput.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsmessagebox.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsmodes.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsmouse.c" />
+117 -30
View File
@@ -214,6 +214,9 @@
<Filter Include="io\windows">
<UniqueIdentifier>{000028b2ea36d7190d13777a4dc70000}</UniqueIdentifier>
</Filter>
<Filter Include="haptic\hidapi">
<UniqueIdentifier>{695ffc61-5497-4227-b415-15e9bdd5b6bf}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SDL\include\SDL3\SDL_begin_code.h">
@@ -699,9 +702,6 @@
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_std_func.h">
<Filter>video\yuv2rgb</Filter>
</ClInclude>
<ClInclude Include="SDL\src\video\windows\SDL_surface_utils.h">
<Filter>video\windows</Filter>
</ClInclude>
<ClInclude Include="SDL\src\video\windows\SDL_windowsclipboard.h">
<Filter>video\windows</Filter>
</ClInclude>
@@ -831,9 +831,6 @@
<ClInclude Include="SDL\src\render\software\SDL_render_sw_c.h">
<Filter>render\software</Filter>
</ClInclude>
<ClInclude Include="SDL\src\render\software\SDL_rotate.h">
<Filter>render\software</Filter>
</ClInclude>
<ClInclude Include="SDL\src\render\software\SDL_triangle.h">
<Filter>render\software</Filter>
</ClInclude>
@@ -911,12 +908,6 @@
<ClInclude Include="SDL\src\hidapi\SDL_hidapi_c.h" />
<ClInclude Include="SDL\src\thread\generic\SDL_sysrwlock_c.h" />
<ClInclude Include="SDL\src\thread\generic\SDL_sysrwlock_c.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_common.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_internal.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_lsx.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_lsx_func.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_sse.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_std.h" />
<ClInclude Include="SDL\src\render\vulkan\SDL_shaders_vulkan.h">
<Filter>render\vulkan</Filter>
</ClInclude>
@@ -950,6 +941,60 @@
<ClInclude Include="SDL\include\SDL3\SDL_storage.h" />
<ClInclude Include="SDL\include\SDL3\SDL_time.h" />
<ClInclude Include="SDL\src\events\SDL_categories_c.h" />
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_std.h">
<Filter>video\yuv2rgb</Filter>
</ClInclude>
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_common.h">
<Filter>video\yuv2rgb</Filter>
</ClInclude>
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_internal.h">
<Filter>video\yuv2rgb</Filter>
</ClInclude>
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_lsx.h">
<Filter>video\yuv2rgb</Filter>
</ClInclude>
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_lsx_func.h">
<Filter>video\yuv2rgb</Filter>
</ClInclude>
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_sse.h">
<Filter>video\yuv2rgb</Filter>
</ClInclude>
<ClInclude Include="SDL\src\video\miniz.h">
<Filter>video</Filter>
</ClInclude>
<ClInclude Include="SDL\src\video\SDL_rotate.h">
<Filter>video</Filter>
</ClInclude>
<ClInclude Include="SDL\src\video\SDL_video_unsupported.h">
<Filter>video</Filter>
</ClInclude>
<ClInclude Include="SDL\src\misc\SDL_libusb.h">
<Filter>misc</Filter>
</ClInclude>
<ClInclude Include="SDL\src\haptic\hidapi\SDL_hidapihaptic.h">
<Filter>haptic\hidapi</Filter>
</ClInclude>
<ClInclude Include="SDL\src\haptic\hidapi\SDL_hidapihaptic_c.h">
<Filter>haptic\hidapi</Filter>
</ClInclude>
<ClInclude Include="SDL\src\core\SDL_core_unsupported.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_flydigi.h">
<Filter>joystick\hidapi</Filter>
</ClInclude>
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_nintendo.h">
<Filter>joystick\hidapi</Filter>
</ClInclude>
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_sinput.h">
<Filter>joystick\hidapi</Filter>
</ClInclude>
<ClInclude Include="SDL\src\joystick\hidapi\SDL_report_descriptor.h">
<Filter>joystick\hidapi</Filter>
</ClInclude>
<ClInclude Include="SDL\include\SDL3\SDL_dlopennote.h">
<Filter>API Headers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="SDL\src\audio\wasapi\SDL_wasapi.c" />
@@ -1037,9 +1082,6 @@
<ClCompile Include="SDL\src\core\SDL_core_unsupported.c">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="SDL\src\core\windows\SDL_gameinput.c">
<Filter>core\windows</Filter>
</ClCompile>
<ClCompile Include="SDL\src\core\windows\SDL_hid.c">
<Filter>core\windows</Filter>
</ClCompile>
@@ -1166,9 +1208,6 @@
<ClCompile Include="SDL\src\joystick\dummy\SDL_sysjoystick.c">
<Filter>joystick\dummy</Filter>
</ClCompile>
<ClCompile Include="SDL\src\joystick\gdk\SDL_gameinputjoystick.c">
<Filter>joystick\gdk</Filter>
</ClCompile>
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_combined.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
@@ -1328,9 +1367,6 @@
<ClCompile Include="SDL\src\video\dummy\SDL_nullvideo.c">
<Filter>video\dummy</Filter>
</ClCompile>
<ClCompile Include="SDL\src\video\windows\SDL_surface_utils.c">
<Filter>video\windows</Filter>
</ClCompile>
<ClCompile Include="SDL\src\video\windows\SDL_windowsclipboard.c">
<Filter>video\windows</Filter>
</ClCompile>
@@ -1343,9 +1379,6 @@
<ClCompile Include="SDL\src\video\windows\SDL_windowskeyboard.c">
<Filter>video\windows</Filter>
</ClCompile>
<ClCompile Include="SDL\src\video\windows\SDL_windowsgameinput.c">
<Filter>video\windows</Filter>
</ClCompile>
<ClCompile Include="SDL\src\video\windows\SDL_windowsmessagebox.c">
<Filter>video\windows</Filter>
</ClCompile>
@@ -1508,9 +1541,6 @@
<ClCompile Include="SDL\src\render\software\SDL_render_sw.c">
<Filter>render\software</Filter>
</ClCompile>
<ClCompile Include="SDL\src\render\software\SDL_rotate.c">
<Filter>render\software</Filter>
</ClCompile>
<ClCompile Include="SDL\src\render\software\SDL_triangle.c">
<Filter>render\software</Filter>
</ClCompile>
@@ -1535,9 +1565,6 @@
</ClCompile>
<ClCompile Include="SDL\src\thread\generic\SDL_sysrwlock.c" />
<ClCompile Include="SDL\src\thread\generic\SDL_sysrwlock.c" />
<ClCompile Include="SDL\src\video\yuv2rgb\yuv_rgb_lsx.c" />
<ClCompile Include="SDL\src\video\yuv2rgb\yuv_rgb_sse.c" />
<ClCompile Include="SDL\src\video\yuv2rgb\yuv_rgb_std.c" />
<ClCompile Include="SDL\src\render\vulkan\SDL_render_vulkan.c">
<Filter>render\vulkan</Filter>
</ClCompile>
@@ -1579,6 +1606,66 @@
<ClCompile Include="SDL\src\storage\generic\SDL_genericstorage.c" />
<ClCompile Include="SDL\src\storage\steam\SDL_steamstorage.c" />
<ClCompile Include="SDL\src\storage\SDL_storage.c" />
<ClCompile Include="SDL\src\video\windows\SDL_windowsgameinput.cpp">
<Filter>video\windows</Filter>
</ClCompile>
<ClCompile Include="SDL\src\video\yuv2rgb\yuv_rgb_lsx.c">
<Filter>video\yuv2rgb</Filter>
</ClCompile>
<ClCompile Include="SDL\src\video\yuv2rgb\yuv_rgb_sse.c">
<Filter>video\yuv2rgb</Filter>
</ClCompile>
<ClCompile Include="SDL\src\video\yuv2rgb\yuv_rgb_std.c">
<Filter>video\yuv2rgb</Filter>
</ClCompile>
<ClCompile Include="SDL\src\video\SDL_rotate.c">
<Filter>video</Filter>
</ClCompile>
<ClCompile Include="SDL\src\misc\SDL_libusb.c">
<Filter>misc</Filter>
</ClCompile>
<ClCompile Include="SDL\src\haptic\hidapi\SDL_hidapihaptic.c">
<Filter>haptic\hidapi</Filter>
</ClCompile>
<ClCompile Include="SDL\src\haptic\hidapi\SDL_hidapihaptic_lg4ff.c">
<Filter>haptic\hidapi</Filter>
</ClCompile>
<ClCompile Include="SDL\src\core\windows\pch_cpp.cpp">
<Filter>core\windows</Filter>
</ClCompile>
<ClCompile Include="SDL\src\core\windows\SDL_gameinput.cpp">
<Filter>core\windows</Filter>
</ClCompile>
<ClCompile Include="SDL\src\joystick\gdk\SDL_gameinputjoystick.cpp">
<Filter>joystick\gdk</Filter>
</ClCompile>
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_8bitdo.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_flydigi.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_gip.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_lg4ff.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_sinput.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_steam_triton.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_switch2.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_zuiki.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
<ClCompile Include="SDL\src\joystick\hidapi\SDL_report_descriptor.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="SDL\src\core\windows\version.rc" />
+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()
+27
View File
@@ -0,0 +1,27 @@
add_library(3rdparty_protobuf INTERFACE)
if (USE_SYSTEM_PROTOBUF)
pkg_check_modules(PROTOBUF REQUIRED IMPORTED_TARGET protobuf>=33.0.0)
target_link_libraries(3rdparty_protobuf INTERFACE PkgConfig::PROTOBUF)
set(PROTOBUF_DIR "${CMAKE_SOURCE_DIR}/rpcs3/Emu/NP/generated")
execute_process(COMMAND protoc --cpp_out=${PROTOBUF_DIR} --proto_path=${PROTOBUF_DIR} np2_structs.proto RESULT_VARIABLE PROTOBUF_CMD_ERROR)
if(PROTOBUF_CMD_ERROR AND NOT PROTOBUF_CMD_ERROR EQUAL 0)
message(FATAL_ERROR "protoc failed to regenerate protobuf files.")
endif()
else()
option(protobuf_INSTALL "Install protobuf binaries and files" OFF)
option(protobuf_BUILD_TESTS "Build tests" OFF)
option(protobuf_BUILD_CONFORMANCE "Build conformance tests" OFF)
option(protobuf_BUILD_EXAMPLES "Build examples" OFF)
option(protobuf_BUILD_PROTOBUF_BINARIES "Build protobuf libraries and protoc compiler" ON)
option(protobuf_BUILD_PROTOC_BINARIES "Build libprotoc and protoc compiler" OFF)
option(protobuf_BUILD_LIBPROTOC "Build libprotoc" OFF)
option(protobuf_BUILD_LIBUPB "Build libupb" OFF)
option(protobuf_ALLOW_CCACHE "Adjust build flags to allow for ccache support." ON)
option(protobuf_DISABLE_RTTI "Remove runtime type information in the binaries" OFF)
option(protobuf_FORCE_FETCH_DEPENDENCIES "Force all dependencies to be downloaded from GitHub. Local installations will be ignored." OFF)
option(protobuf_LOCAL_DEPENDENCIES_ONLY "Prevent downloading any dependencies from GitHub. If this option is set, the dependency must be available locally as an installed package." OFF)
add_subdirectory(protobuf EXCLUDE_FROM_ALL)
target_include_directories(3rdparty_protobuf SYSTEM INTERFACE protobuf/src)
target_link_libraries(3rdparty_protobuf INTERFACE libprotobuf)
endif()
Vendored Submodule
+1
+111
View File
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7B3B4C5D-6E7F-8A9B-0C1D-2E3F4A5B6C7D}</ProjectGuid>
<Keyword>MakeFileProj</Keyword>
</PropertyGroup>
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default_macros.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros">
<CmakeReleaseCLI>call vsdevcmd.bat -arch=amd64
if not exist "$(SolutionDir)build\tmp\protobuf_build-$(Configuration)-$(Platform)" mkdir "$(SolutionDir)build\tmp\protobuf_build-$(Configuration)-$(Platform)"
cd "$(SolutionDir)build\tmp\protobuf_build-$(Configuration)-$(Platform)"
cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="$(SolutionDir)build\lib\$(Configuration)-$(Platform)\protobuf_build" -DCMAKE_SYSTEM_VERSION=10.0 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -Dprotobuf_INSTALL=ON -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF -Dprotobuf_BUILD_EXAMPLES=OFF -Dprotobuf_BUILD_PROTOBUF_BINARIES=ON -Dprotobuf_BUILD_PROTOC_BINARIES=OFF -Dprotobuf_BUILD_LIBPROTOC=OFF -Dprotobuf_BUILD_LIBUPB=OFF -Dprotobuf_ALLOW_CCACHE=ON -Dprotobuf_FORCE_FETCH_DEPENDENCIES=ON -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=ON "$(SolutionDir)3rdparty\protobuf\protobuf"
</CmakeReleaseCLI>
<CmakeDebugCLI>call vsdevcmd.bat -arch=amd64
if not exist "$(SolutionDir)build\tmp\protobuf_build-$(Configuration)-$(Platform)" mkdir "$(SolutionDir)build\tmp\protobuf_build-$(Configuration)-$(Platform)"
cd "$(SolutionDir)build\tmp\protobuf_build-$(Configuration)-$(Platform)"
cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_INSTALL_PREFIX="$(SolutionDir)build\lib\$(Configuration)-$(Platform)\protobuf_build" -DCMAKE_SYSTEM_VERSION=10.0 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebugDLL -Dprotobuf_INSTALL=ON -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF -Dprotobuf_BUILD_EXAMPLES=OFF -Dprotobuf_BUILD_PROTOBUF_BINARIES=ON -Dprotobuf_BUILD_PROTOC_BINARIES=OFF -Dprotobuf_BUILD_LIBPROTOC=OFF -Dprotobuf_BUILD_LIBUPB=OFF -Dprotobuf_ALLOW_CCACHE=ON -Dprotobuf_FORCE_FETCH_DEPENDENCIES=ON -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF "$(SolutionDir)3rdparty\protobuf\protobuf"
</CmakeDebugCLI>
<CmakeCleanCLI>
echo Cleaning..
rmdir /s /q "$(SolutionDir)build\lib\$(Configuration)-$(Platform)\protobuf_build"
cd "$(SolutionDir)build\tmp\protobuf_build-$(Configuration)-$(Platform)"
for /F "delims= eol=|" %%f in ('
dir /b ^| findstr /V "[^.]*\build[^.]*\.vcxproj"') do (
echo Deleting .\%%f
if exist %%f\nul (
rmdir .\%%f /s /q
) else (
del .\%%f /q
)
)
</CmakeCleanCLI>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakePreprocessorDefinitions>
</NMakePreprocessorDefinitions>
<OutDir>$(SolutionDir)build\lib\$(Configuration)-$(Platform)\</OutDir>
<IntDir>$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\</IntDir>
<NMakeBuildCommandLine>
$(CmakeDebugCLI)
ninja
ninja install
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
$(CmakeCleanCLI)
$(CmakeDebugCLI)
ninja
ninja install
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
$(CmakeCleanCLI)
</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakePreprocessorDefinitions>
</NMakePreprocessorDefinitions>
<OutDir>$(SolutionDir)build\lib\$(Configuration)-$(Platform)\</OutDir>
<IntDir>$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\</IntDir>
<NMakeBuildCommandLine>
$(CmakeReleaseCLI)
ninja
ninja install
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
$(CmakeCleanCLI)
$(CmakeReleaseCLI)
ninja
ninja install
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
$(CmakeCleanCLI)
</NMakeCleanCommandLine>
</PropertyGroup>
<ItemDefinitionGroup>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+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
View File
@@ -76,6 +76,7 @@
<ClCompile Include="yaml-cpp\src\exceptions.cpp" />
<ClCompile Include="yaml-cpp\src\exp.cpp">
</ClCompile>
<ClCompile Include="yaml-cpp\src\fptostring.cpp" />
<ClCompile Include="yaml-cpp\src\memory.cpp">
</ClCompile>
<ClCompile Include="yaml-cpp\src\node.cpp">
+3
View File
@@ -94,5 +94,8 @@
<ClCompile Include="yaml-cpp\src\depthguard.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="yaml-cpp\src\fptostring.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+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()
+1 -1
View File
@@ -3,7 +3,7 @@ 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)
+9 -8
View File
@@ -20,26 +20,26 @@ The following tools are required to build RPCS3 on Windows 10 or later:
with standalone **CMake** tool.
- [Python 3.6+](https://www.python.org/downloads/) (add to PATH)
- [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)
- [Qt 6.10.2](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.10.1\msvc2022_64\`
- add and set the `QTDIR` environment variable, e.g. `<QtInstallFolder>\6.10.2\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.10.1\msvc2022_64\`
- add and set the `Qt6_ROOT` environment variable to the **Qt** libs path, e.g. `<QtInstallFolder>\6.10.2\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.10.1](https://www.qt.io/download-qt-installer)
- [Qt 6.10.2](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)
@@ -51,7 +51,7 @@ These are the essentials tools to build RPCS3 on Linux. Some of them can be inst
#### Debian & Ubuntu
sudo apt-get install build-essential ninja-build libasound2-dev libpulse-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git libevdev-dev libsdl3-3.2 libsdl3-dev libjack-dev libsndio-dev
sudo apt-get install build-essential ninja-build libasound2-dev libpulse-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git libevdev-dev libsdl3-dev libjack-dev libsndio-dev libcurl4-openssl-dev qt6-base-dev qt6-base-private-dev qt6-multimedia-dev qt6-svg-dev libxkbcommon-dev
Ubuntu is usually horrendously out of date, and some packages need to be downloaded by hand. This part is for Qt, GCC, Vulkan, and CMake
@@ -95,7 +95,7 @@ sudo apt-get install cmake
#### Fedora
sudo dnf install alsa-lib-devel cmake ninja-build glew glew-devel libatomic libevdev-devel libudev-devel openal-devel qt6-qtbase-devel qt6-qtbase-private-devel vulkan-devel pipewire-jack-audio-connection-kit-devel qt6-qtmultimedia-devel qt6-qtsvg-devel llvm-devel
sudo dnf install alsa-lib-devel cmake ninja-build glew glew-devel libatomic libevdev-devel libudev-devel openal-soft-devel qt6-qtbase-devel qt6-qtbase-private-devel vulkan-devel pipewire-jack-audio-connection-kit-devel qt6-qtmultimedia-devel qt6-qtsvg-devel llvm-devel libcurl-devel
#### OpenSUSE
@@ -108,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
@@ -122,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.10.1\msvc2022_64`, version will fill in automatically
2) add the path to your Qt installation with compiler e.g. `<QtInstallFolder>\6.10.2\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**)
+5 -5
View File
@@ -13,12 +13,12 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11)
message(FATAL_ERROR "RPCS3 requires at least gcc-11.")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13)
message(FATAL_ERROR "RPCS3 requires at least gcc-13.")
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0)
message(FATAL_ERROR "RPCS3 requires at least clang-12.0.")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0)
message(FATAL_ERROR "RPCS3 requires at least clang-19.0.")
endif()
endif()
@@ -42,7 +42,7 @@ option(USE_SYSTEM_CUBEB "Prefer system cubeb instead of the builtin one" OFF)
option(USE_SYSTEM_CURL "Prefer system Curl instead of the prebuild one" ON)
option(USE_SYSTEM_FAUDIO "Prefer system FAudio instead of the builtin one" OFF)
option(USE_SYSTEM_FFMPEG "Prefer system ffmpeg instead of the prebuild one" OFF)
option(USE_SYSTEM_FLATBUFFERS "Prefer system flatbuffers instead of the builtin one" OFF)
option(USE_SYSTEM_PROTOBUF "Prefer system protobuf instead of the builtin one" OFF)
option(USE_SYSTEM_GLSLANG "Prefer system glslang instead of the builtin one" OFF)
option(USE_SYSTEM_HIDAPI "Prefer system hidapi instead of the builtin one" OFF)
option(USE_SYSTEM_LIBPNG "Prefer system libpng instead of the builtin one" OFF)
+65 -9
View File
@@ -117,6 +117,7 @@ static fs::error to_error(DWORD e)
case ERROR_NEGATIVE_SEEK: return fs::error::inval;
case ERROR_DIRECTORY: return fs::error::inval;
case ERROR_INVALID_NAME: return fs::error::inval;
case ERROR_INVALID_FUNCTION: return fs::error::inval;
case ERROR_SHARING_VIOLATION: return fs::error::acces;
case ERROR_DIR_NOT_EMPTY: return fs::error::notempty;
case ERROR_NOT_READY: return fs::error::noent;
@@ -398,12 +399,11 @@ namespace fs
class windows_file final : public file_base
{
HANDLE m_handle;
atomic_t<u64> m_pos;
atomic_t<u64> m_pos {0};
public:
windows_file(HANDLE handle)
: m_handle(handle)
, m_pos(0)
{
}
@@ -417,10 +417,10 @@ namespace fs
stat_t get_stat() override
{
FILE_BASIC_INFO basic_info;
FILE_BASIC_INFO basic_info {};
ensure(GetFileInformationByHandleEx(m_handle, FileBasicInfo, &basic_info, sizeof(FILE_BASIC_INFO))); // "file::stat"
stat_t info;
stat_t info {};
info.is_directory = (basic_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
info.is_writable = (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0;
info.size = this->size();
@@ -441,7 +441,7 @@ namespace fs
bool trunc(u64 length) override
{
FILE_END_OF_FILE_INFO _eof;
FILE_END_OF_FILE_INFO _eof {};
_eof.EndOfFile.QuadPart = length;
if (!SetFileInformationByHandle(m_handle, FileEndOfFileInfo, &_eof, sizeof(_eof)))
@@ -563,6 +563,7 @@ namespace fs
u64 size() override
{
// NOTE: this can fail if we access a mounted empty drive (e.g. after unmounting an iso).
LARGE_INTEGER size;
ensure(GetFileSizeEx(m_handle, &size)); // "file::size"
@@ -579,12 +580,12 @@ namespace fs
file_id id{"windows_file"};
id.data.resize(sizeof(FILE_ID_INFO));
FILE_ID_INFO info;
FILE_ID_INFO info {};
if (!GetFileInformationByHandleEx(m_handle, FileIdInfo, &info, sizeof(info)))
{
// Try GetFileInformationByHandle as a fallback
BY_HANDLE_FILE_INFORMATION info2;
BY_HANDLE_FILE_INFORMATION info2{};
ensure(GetFileInformationByHandle(m_handle, &info2));
info = {};
@@ -625,7 +626,7 @@ namespace fs
struct ::stat file_info;
ensure(::fstat(m_fd, &file_info) == 0); // "file::stat"
stat_t info;
stat_t info {};
info.is_directory = S_ISDIR(file_info.st_mode);
info.is_writable = file_info.st_mode & 0200; // HACK: approximation
info.size = file_info.st_size;
@@ -901,6 +902,22 @@ std::string_view fs::get_parent_dir_view(std::string_view path, u32 parent_level
return result;
}
std::string fs::get_path_if_dir(const std::string& path)
{
if (path.empty() || !fs::is_dir(path))
{
return {};
}
// If delimiters are already present at the end of the string then nothing else to do
if (usz sz = path.find_last_of(delim); sz != umax && (sz + 1) == path.size())
{
return path;
}
return path + '/';
}
bool fs::get_stat(const std::string& path, stat_t& info)
{
// Ensure consistent information on failure
@@ -1640,6 +1657,45 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
return;
}
// Check if the handle is actually valid.
// This can fail on empty mounted drives (e.g. with ERROR_NOT_READY or ERROR_INVALID_FUNCTION).
BY_HANDLE_FILE_INFORMATION info{};
if (!GetFileInformationByHandle(handle, &info))
{
const DWORD last_error = GetLastError();
CloseHandle(handle);
if (last_error == ERROR_INVALID_FUNCTION)
{
g_tls_error = fs::error::isdir;
return;
}
g_tls_error = to_error(last_error);
return;
}
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
CloseHandle(handle);
g_tls_error = fs::error::isdir;
return;
}
if (info.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
{
CloseHandle(handle);
g_tls_error = fs::error::acces;
return;
}
if ((mode & fs::write) && (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
{
CloseHandle(handle);
g_tls_error = fs::error::readonly;
return;
}
m_file = std::make_unique<windows_file>(handle);
#else
int flags = O_CLOEXEC; // Ensures all files are closed on execl for auto updater
@@ -2579,7 +2635,7 @@ bool fs::pending_file::commit(bool overwrite)
while (file_handle != INVALID_HANDLE_VALUE)
{
// Get file ID (used to check for hardlinks)
BY_HANDLE_FILE_INFORMATION file_info;
BY_HANDLE_FILE_INFORMATION file_info{};
if (!GetFileInformationByHandle(file_handle, &file_info) || file_info.nNumberOfLinks == 1)
{
+13 -8
View File
@@ -66,13 +66,13 @@ namespace fs
// File attributes (TODO)
struct stat_t
{
bool is_directory;
bool is_symlink;
bool is_writable;
u64 size;
s64 atime;
s64 mtime;
s64 ctime;
bool is_directory = false;
bool is_symlink = false;
bool is_writable = false;
u64 size = 0;
s64 atime = 0;
s64 mtime = 0;
s64 ctime = 0;
using enable_bitcopy = std::true_type;
@@ -155,7 +155,7 @@ namespace fs
// Virtual device
struct device_base
{
const std::string fs_prefix;
std::string fs_prefix;
device_base();
virtual ~device_base();
@@ -195,6 +195,9 @@ namespace fs
return std::string{get_parent_dir_view(path, parent_level)};
}
// Return "path" plus an ending delimiter (if missing) if "path" is an existing directory. Otherwise, an empty string
std::string get_path_if_dir(const std::string& path);
// Get file information
bool get_stat(const std::string& path, stat_t& info);
@@ -254,6 +257,8 @@ namespace fs
// Open file with specified mode
explicit file(const std::string& path, bs_t<open_mode> mode = ::fs::read);
file(std::unique_ptr<file_base>&& ptr) : m_file(std::move(ptr)) {}
static file from_native_handle(native_handle handle);
// Open memory for read
+4
View File
@@ -14,6 +14,10 @@
#define CAN_OVERCOMMIT
#endif
#if defined(__APPLE__)
#include <mutex>
#endif
LOG_CHANNEL(jit_log, "JIT");
void jit_announce(uptr func, usz size, std::string_view name)
+25
View File
@@ -688,6 +688,30 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, co
mem = std::make_unique<MemoryManager1>(std::move(symbols_cement));
}
std::vector<std::string> attributes;
#if defined(ARCH_ARM64)
if (utils::has_sha3())
attributes.push_back("+sha3");
else
attributes.push_back("-sha3");
if (utils::has_dotprod())
attributes.push_back("+dotprod");
else
attributes.push_back("-dotprod");
if (utils::has_sve())
attributes.push_back("+sve");
else
attributes.push_back("-sve");
if (utils::has_sve2())
attributes.push_back("+sve2");
else
attributes.push_back("-sve2");
#endif
{
m_engine.reset(llvm::EngineBuilder(std::move(null_mod))
.setErrorStr(&result)
@@ -699,6 +723,7 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, co
//.setCodeModel(llvm::CodeModel::Large)
#endif
.setRelocationModel(llvm::Reloc::Model::PIC_)
.setMAttrs(attributes)
.setMCPU(m_cpu)
.create());
}
+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;
+45 -12
View File
@@ -13,13 +13,13 @@ std::string wchar_to_utf8(std::wstring_view src);
std::string utf16_to_utf8(std::u16string_view src);
std::u16string utf8_to_utf16(std::string_view src);
// Copy null-terminated string from a std::string or a char array to a char array with truncation
template <typename D, typename T>
// Copy null-terminated string from a std::basic_string or a char array to a char array with truncation
template <typename D, typename T> requires requires (D& d, T& t) { std::declval<decltype(&t[0])&>() = &d[0]; }
inline void strcpy_trunc(D&& dst, const T& src)
{
const usz count = std::size(src) >= std::size(dst) ? std::max<usz>(std::size(dst), 1) - 1 : std::size(src);
std::memcpy(std::data(dst), std::data(src), count);
std::memset(std::data(dst) + count, 0, std::size(dst) - count);
std::copy_n(std::data(src), count, std::data(dst));
std::fill_n(std::data(dst) + count, std::size(dst) - count, std::remove_cvref_t<decltype(dst[0])>{});
}
// Convert string to signed integer
@@ -139,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(*end);
}
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;
+11 -5
View File
@@ -8,7 +8,6 @@
#include "Emu/RSX/RSXThread.h"
#include "Thread.h"
#include "Utilities/JIT.h"
#include <thread>
#include <cfenv>
#ifdef ARCH_ARM64
@@ -2165,10 +2164,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
+1
View File
@@ -4,6 +4,7 @@
#include "util/atomic.hpp"
#include "util/shared_ptr.hpp"
#include <thread>
#include <string>
// Hardware core layout
+1 -1
View File
@@ -329,7 +329,7 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st
is_valid = false;
continue;
}
else if (serial.size() != 9 || !std::all_of(serial.begin(), serial.end(), [](char c) { return std::isalnum(c); }))
else if (serial.size() != 9 || !std::all_of(serial.begin(), serial.end(), [](char c) { return std::isalnum(static_cast<unsigned char>(c)); }))
{
append_log_message(log_messages, fmt::format("Error: Serial '%s' invalid (patch: %s, key: %s, location: %s, file: %s)", serial, description, main_key, get_yaml_node_location(serial_node), path), &patch_log.error);
is_valid = false;
+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;
};
+8
View File
@@ -821,6 +821,14 @@ struct color4_base
a *= rhs;
}
void operator += (const color4_base<T>& rhs)
{
r += rhs.r;
g += rhs.g;
b += rhs.b;
a += rhs.a;
}
constexpr color4_base<T> operator * (const color4_base<T>& rhs) const
{
return { r * rhs.r, g * rhs.g, b * rhs.b, a * rhs.a };
+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
@@ -13,7 +13,7 @@
<ItemDefinitionGroup>
<ClCompile>
<LanguageStandard Condition = "'$(VisualStudioVersion.Substring(0,2))'&lt;'17'">stdcpplatest</LanguageStandard>
<LanguageStandard Condition = "'$(VisualStudioVersion.Substring(0,2))'&gt;='17'">stdcpp20</LanguageStandard>
<LanguageStandard Condition = "'$(VisualStudioVersion.Substring(0,2))'&gt;='17'">stdcpp23</LanguageStandard>
<PreprocessorDefinitions>_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING=1;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<AdditionalOptions>-d2FH4- %(AdditionalOptions)</AdditionalOptions>
+92 -1
View File
@@ -7,7 +7,7 @@
<OutDir>$(SolutionDir)build\lib\$(Configuration)-$(Platform)\</OutDir>
<LibraryPath>$(SolutionDir)build\lib\$(Configuration)-$(Platform)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath)</LibraryPath>
<IntDir>$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\</IntDir>
<GTestPath>$(SolutionDir)packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-static.1.8.1.7\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-static.targets</GTestPath>
<GTestPath>$(SolutionDir)packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-static.1.8.1.8\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-static.targets</GTestPath>
<GTestInstalled Condition="Exists('$(GTestPath)')">true</GTestInstalled>
</PropertyGroup>
<ItemDefinitionGroup>
@@ -131,6 +131,97 @@
LLVMX86Info.lib;
LLVMX86TargetMCA.lib;
LLVMXRay.lib;
absl_log_severity.lib;
absl_raw_logging_internal.lib;
absl_spinlock_wait.lib;
absl_malloc_internal.lib;
absl_base.lib;
absl_throw_delegate.lib;
absl_scoped_set_env.lib;
absl_strerror.lib;
absl_poison.lib;
absl_tracing_internal.lib;
absl_hashtablez_sampler.lib;
absl_raw_hash_set.lib;
absl_crc_cpu_detect.lib;
absl_crc_internal.lib;
absl_crc32c.lib;
absl_crc_cord_state.lib;
absl_stacktrace.lib;
absl_symbolize.lib;
absl_examine_stack.lib;
absl_failure_signal_handler.lib;
absl_debugging_internal.lib;
absl_demangle_internal.lib;
absl_decode_rust_punycode.lib;
absl_demangle_rust.lib;
absl_utf8_for_code_point.lib;
absl_leak_check.lib;
absl_flags_program_name.lib;
absl_flags_config.lib;
absl_flags_marshalling.lib;
absl_flags_commandlineflag_internal.lib;
absl_flags_commandlineflag.lib;
absl_flags_private_handle_accessor.lib;
absl_flags_reflection.lib;
absl_flags_internal.lib;
absl_flags_usage_internal.lib;
absl_flags_usage.lib;
absl_flags_parse.lib;
absl_hash.lib;
absl_city.lib;
absl_low_level_hash.lib;
absl_log_internal_check_op.lib;
absl_log_internal_conditions.lib;
absl_log_internal_format.lib;
absl_log_internal_globals.lib;
absl_log_internal_proto.lib;
absl_log_internal_message.lib;
absl_log_internal_log_sink_set.lib;
absl_log_internal_nullguard.lib;
absl_die_if_null.lib;
absl_log_flags.lib;
absl_log_globals.lib;
absl_log_initialize.lib;
absl_log_sink.lib;
absl_log_internal_structured_proto.lib;
absl_vlog_config_internal.lib;
absl_log_internal_fnmatch.lib;
absl_int128.lib;
absl_exponential_biased.lib;
absl_periodic_sampler.lib;
absl_random_distributions.lib;
absl_random_seed_gen_exception.lib;
absl_random_seed_sequences.lib;
absl_random_internal_seed_material.lib;
absl_random_internal_entropy_pool.lib;
absl_random_internal_platform.lib;
absl_random_internal_randen.lib;
absl_random_internal_randen_slow.lib;
absl_random_internal_randen_hwaes.lib;
absl_random_internal_randen_hwaes_impl.lib;
absl_random_internal_distribution_test_util.lib;
absl_status.lib;
absl_statusor.lib;
absl_string_view.lib;
absl_strings.lib;
absl_strings_internal.lib;
absl_str_format_internal.lib;
absl_cord_internal.lib;
absl_cordz_functions.lib;
absl_cordz_handle.lib;
absl_cordz_info.lib;
absl_cordz_sample_token.lib;
absl_cord.lib;
absl_graphcycles_internal.lib;
absl_kernel_timeout_internal.lib;
absl_synchronization.lib;
absl_time.lib;
absl_civil_time.lib;
absl_time_zone.lib;
libutf8_validity.lib;
libutf8_range.lib;
libprotobuf-lite.lib;
</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)3rdparty\ffmpeg\lib\windows\x86_64</AdditionalLibraryDirectories>
<StackReserveSize>8388608</StackReserveSize>
+8
View File
@@ -9,11 +9,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "emucore", "rpcs3\emucore.vc
{2C902C67-985C-4BE0-94A3-E0FE2EB929A3} = {2C902C67-985C-4BE0-94A3-E0FE2EB929A3}
{3C67A2FF-4710-402A-BE3E-31B0CB0576DF} = {3C67A2FF-4710-402A-BE3E-31B0CB0576DF}
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0} = {5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}
{7B3B4C5D-6E7F-8A9B-0C1D-2E3F4A5B6C7D} = {7B3B4C5D-6E7F-8A9B-0C1D-2E3F4A5B6C7D}
{8846A9AA-5539-4C91-8301-F54260E1A07A} = {8846A9AA-5539-4C91-8301-F54260E1A07A}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm_build", "3rdparty\llvm\llvm_build.vcxproj", "{8BC303AB-25BE-4276-8E57-73F171B2D672}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "protobuf_build", "3rdparty\protobuf\protobuf_build.vcxproj", "{7B3B4C5D-6E7F-8A9B-0C1D-2E3F4A5B6C7D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GLGSRender", "rpcs3\GLGSRender.vcxproj", "{3384223A-6D97-4799-9862-359F85312892}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "rpcs3.emu", "rpcs3.emu", "{10FBF193-D532-4CCF-B875-4C7091A7F6C2}"
@@ -130,6 +133,10 @@ Global
{C4A10229-4712-4BD2-B63E-50D93C67A038}.Release|x64.Build.0 = Release|x64
{8BC303AB-25BE-4276-8E57-73F171B2D672}.Debug|x64.ActiveCfg = Debug|x64
{8BC303AB-25BE-4276-8E57-73F171B2D672}.Release|x64.ActiveCfg = Release|x64
{7B3B4C5D-6E7F-8A9B-0C1D-2E3F4A5B6C7D}.Debug|x64.ActiveCfg = Debug|x64
{7B3B4C5D-6E7F-8A9B-0C1D-2E3F4A5B6C7D}.Debug|x64.Build.0 = Debug|x64
{7B3B4C5D-6E7F-8A9B-0C1D-2E3F4A5B6C7D}.Release|x64.ActiveCfg = Release|x64
{7B3B4C5D-6E7F-8A9B-0C1D-2E3F4A5B6C7D}.Release|x64.Build.0 = Release|x64
{3384223A-6D97-4799-9862-359F85312892}.Debug|x64.ActiveCfg = Debug|x64
{3384223A-6D97-4799-9862-359F85312892}.Debug|x64.Build.0 = Debug|x64
{3384223A-6D97-4799-9862-359F85312892}.Release|x64.ActiveCfg = Release|x64
@@ -240,6 +247,7 @@ Global
{AC40FF01-426E-4838-A317-66354CEFAE88} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
{C4A10229-4712-4BD2-B63E-50D93C67A038} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
{8BC303AB-25BE-4276-8E57-73F171B2D672} = {B0AC29FD-7B01-4B5E-9C8D-0A081E4C5668}
{7B3B4C5D-6E7F-8A9B-0C1D-2E3F4A5B6C7D} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
{3384223A-6D97-4799-9862-359F85312892} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
{78CB2F39-B809-4A06-8329-8C0A19119D3D} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
{EB33566E-DA7F-4D28-9077-88C0B7C77E35} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
+4 -2
View File
@@ -8,7 +8,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/git-version.cmake)
include(ConfigureCompiler)
include(CheckFunctionExists)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 23)
if(UNIX AND NOT APPLE AND NOT ANDROID)
add_compile_definitions(DATADIR="${CMAKE_INSTALL_FULL_DATADIR}/rpcs3")
@@ -148,8 +148,9 @@ if (NOT ANDROID)
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/GuiConfigs $<TARGET_FILE_DIR:rpcs3>/GuiConfigs
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/test $<TARGET_FILE_DIR:rpcs3>/test
COMMAND "${WINDEPLOYQT_EXECUTABLE}" --no-compiler-runtime --no-opengl-sw --no-patchqt
--no-translations --no-system-d3d-compiler --no-system-dxc-compiler --no-quick-import
--no-system-d3d-compiler --no-system-dxc-compiler --no-quick-import
--plugindir "$<IF:$<CXX_COMPILER_ID:MSVC>,$<TARGET_FILE_DIR:rpcs3>/plugins,$<TARGET_FILE_DIR:rpcs3>/share/qt6/plugins>"
--translationdir "$<IF:$<CXX_COMPILER_ID:MSVC>,$<TARGET_FILE_DIR:rpcs3>/translations,$<TARGET_FILE_DIR:rpcs3>/share/qt6/translations>"
--verbose 0 "$<TARGET_FILE:rpcs3>")
endif()
@@ -193,6 +194,7 @@ if(BUILD_RPCS3_TESTS)
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
+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; }
+1
View File
@@ -12,6 +12,7 @@
#include <cstring>
#include <cstdio>
#include <ctime>
#include "Utilities/StrFmt.h"
#include "Utilities/StrUtil.h"
#include "Utilities/File.h"
+19 -4
View File
@@ -125,6 +125,7 @@ target_sources(rpcs3_emu PRIVATE
../Loader/PSF.cpp
../Loader/PUP.cpp
../Loader/TAR.cpp
../Loader/ISO.cpp
../Loader/TROPUSR.cpp
../Loader/TRP.cpp
)
@@ -411,6 +412,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
@@ -421,6 +423,7 @@ target_sources(rpcs3_emu PRIVATE
Io/TopShotFearmaster.cpp
Io/Turntable.cpp
Io/usb_device.cpp
Io/usb_microphone.cpp
Io/usb_vfs.cpp
Io/usio.cpp
Io/LogitechG27.cpp
@@ -429,7 +432,7 @@ target_sources(rpcs3_emu PRIVATE
# Np
target_sources(rpcs3_emu PRIVATE
NP/fb_helpers.cpp
NP/pb_helpers.cpp
NP/np_cache.cpp
NP/np_gui_cache.cpp
NP/np_contexts.cpp
@@ -441,12 +444,15 @@ 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
NP/upnp_config.cpp
NP/upnp_handler.cpp
NP/ip_address.cpp
NP/generated/np2_structs.pb.cc
)
# Memory
@@ -516,12 +522,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
@@ -539,7 +548,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
@@ -623,6 +632,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)
@@ -644,7 +658,7 @@ target_link_libraries(rpcs3_emu
3rdparty::soundtouch
3rdparty::miniupnpc
3rdparty::libevdev
3rdparty::flatbuffers
3rdparty::protobuf
3rdparty::pugixml
3rdparty::vulkanmemoryallocator
Threads::Threads
@@ -655,6 +669,7 @@ target_link_libraries(rpcs3_emu
3rdparty::yaml-cpp
3rdparty::zlib
3rdparty::zstd
3rdparty::libcurl
)
if(APPLE)
+2 -6
View File
@@ -206,11 +206,7 @@ struct cpu_prof
// Print only 7 hash characters out of 11 (which covers roughly 48 bits)
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);
fmt::append(results, "\n\t[%s]: %.4f%% (%u)", spu_block_hash{name}, _frac * 100., count);
}
else
{
@@ -506,7 +502,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]{};
+4 -8
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;
@@ -197,14 +201,6 @@ void cpu_translator::initialize(llvm::LLVMContext& context, llvm::ExecutionEngin
m_use_vnni = true;
m_use_gfni = true;
}
// Aarch64 CPUs
if (cpu == "cyclone" || cpu.contains("cortex"))
{
m_use_fma = true;
// AVX does not use intrinsics so far
m_use_avx = true;
}
}
llvm::Value* cpu_translator::bitcast(llvm::Value* val, llvm::Type* type) const
+30 -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
@@ -3065,13 +3081,22 @@ protected:
// Allow PSHUFB intrinsic
bool m_use_ssse3 = true;
#ifdef ARCH_ARM64
// all arm CPUS have FMA
bool m_use_fma = true;
// Should be nonsense to set this for ARM,
// but this flag is only used in SPU verification
// For now, setting this flag will speed up SPU verification
// but I will remove this later with explicit parralelism - Whatcookie
bool m_use_avx = true;
#else
// Allow FMA
bool m_use_fma = false;
// Allow AVX
bool m_use_avx = false;
#endif
// Allow skylake-x tier AVX-512
bool m_use_avx512 = false;
@@ -3592,7 +3617,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>
+7
View File
@@ -2228,6 +2228,12 @@ error_code cellFontStatic()
return CELL_OK;
}
error_code cellFontsetUSleep()
{
cellFont.todo("cellFontsetUSleep()");
return CELL_OK;
}
DECLARE(ppu_module_manager::cellFont)("cellFont", []()
{
@@ -2315,4 +2321,5 @@ DECLARE(ppu_module_manager::cellFont)("cellFont", []()
REG_FUNC(cellFont, cellFontGraphicsGetLineRGBA);
REG_FUNC(cellFont, cellFontControl);
REG_FUNC(cellFont, cellFontStatic);
REG_FUNC(cellFont, cellFontsetUSleep);
});
+14
View File
@@ -1034,6 +1034,18 @@ s32 cellFsUnregisterL10nCallbacks()
return CELL_OK;
}
s32 cellFsGetDirent()
{
cellFs.todo("cellFsGetDirent()");
return CELL_OK;
}
s32 cellFsGetDirentCount()
{
cellFs.todo("cellFsGetDirentCount()");
return CELL_OK;
}
DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
{
REG_FUNC(sys_fs, cellFsAccess);
@@ -1065,6 +1077,8 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
REG_FUNC(sys_fs, cellFsGetBlockSize);
REG_FUNC(sys_fs, cellFsGetBlockSize2);
REG_FUNC(sys_fs, cellFsGetDirectoryEntries);
REG_FUNC(sys_fs, cellFsGetDirent);
REG_FUNC(sys_fs, cellFsGetDirentCount);
REG_FUNC(sys_fs, cellFsGetFreeSize);
REG_FUNC(sys_fs, cellFsGetPath);
REG_FUNC(sys_fs, cellFsLink);
+6 -6
View File
@@ -492,8 +492,8 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
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));
cellGame.warning("cellHddGameCheck(): Data exists:\nATTRIBUTE: 0x%x, RESOLUTION: 0x%x, SOUND_FORMAT: 0x%x, dataVersion: %s"
, get->getParam.attribute, get->getParam.resolution, get->getParam.soundFormat, std::span<const u8>(reinterpret_cast<const u8*>(get->getParam.dataVersion), 6));
}
// TODO ?
@@ -580,7 +580,7 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
break;
default:
cellGame.error("cellHddGameCheck(): callback returned unknown error (code=0x%x). Error message: %s", result->invalidMsg);
cellGame.error("cellHddGameCheck(): callback returned unknown error (code=0x%x). Error message: %s", result->result, result->invalidMsg);
error_msg = get_localized_string(localized_string_id::CELL_HDD_GAME_CHECK_INVALID, "%s", result->invalidMsg);
break;
}
@@ -1199,7 +1199,7 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
break;
default:
cellGame.error("cellGameDataCheckCreate2(): callback returned unknown error (code=0x%x). Error message: %s", cbResult->invalidMsg);
cellGame.error("cellGameDataCheckCreate2(): callback returned unknown error (code=0x%x). Error message: %s", cbResult->result, cbResult->invalidMsg);
error_msg = get_localized_string(localized_string_id::CELL_GAMEDATA_CHECK_INVALID, "%s", cbResult->invalidMsg);
break;
}
@@ -1747,7 +1747,7 @@ error_code cellGameThemeInstall(vm::cptr<char> usrdirPath, vm::cptr<char> fileNa
{
u32 magic{};
if (src_path.ends_with(".p3t") || !theme.read(magic) || magic != "P3TF"_u32)
if (!fmt::to_lower(src_path).ends_with(".p3t") || !theme.read(magic) || magic != "P3TF"_u32)
{
return CELL_GAME_ERROR_INVALID_THEME_FILE;
}
@@ -1819,7 +1819,7 @@ error_code cellGameThemeInstallFromBuffer(ppu_thread& ppu, u32 fileSize, u32 buf
const u32 read_size = std::min(bufSize, fileSize - file_offset);
cellGame.notice("cellGameThemeInstallFromBuffer: writing %d bytes at pos %d", read_size, file_offset);
if (theme.write(reinterpret_cast<u8*>(buf.get_ptr()) + file_offset, read_size) != read_size)
if (theme.write(reinterpret_cast<u8*>(buf.get_ptr()), read_size) != read_size)
{
cellGame.error("cellGameThemeInstallFromBuffer: failed to write to destination file '%s' (error=%s)", dst_path, fs::g_tls_error);
+29 -17
View File
@@ -98,16 +98,26 @@ u32 gcmGetLocalMemorySize(u32 sdk_version)
error_code gcmMapEaIoAddress(ppu_thread& ppu, u32 ea, u32 io, u32 size, bool is_strict);
u32 gcmIoOffsetToAddress(u32 ioOffset)
u32 gcmIoOffsetToAddress(u32 io_offs)
{
const u32 upper12Bits = g_fxo->get<gcm_config>().offsetTable.eaAddress[ioOffset >> 20];
u32 upper_12bits = 0;
if (upper12Bits > 0xBFF)
if (io_offs < 0x20000000)
{
return 0;
upper_12bits = rsx::get_current_renderer()->iomap_table.ea[io_offs >> 20];
if (upper_12bits >= rsx::constants::local_mem_base)
{
upper_12bits = 0;
}
}
return (upper12Bits << 20) | (ioOffset & 0xFFFFF);
if (!upper_12bits)
{
cellGcmSys.error("Failed to convert io offset: 0x%x", io_offs);
}
return upper_12bits | (io_offs & 0xFFFFF);
}
void InitOffsetTable()
@@ -132,15 +142,15 @@ u32 cellGcmGetLabelAddress(u8 index)
return rsx::get_current_renderer()->label_addr + 0x10 * index;
}
vm::ptr<CellGcmReportData> cellGcmGetReportDataAddressLocation(u32 index, u32 location)
vm::ptr<CellGcmReportData> cellGcmGetReportDataAddressLocation(ppu_thread& ppu, u32 index, u32 location)
{
cellGcmSys.warning("cellGcmGetReportDataAddressLocation(index=%d, location=%d)", index, location);
cellGcmSys.trace("cellGcmGetReportDataAddressLocation(index=%d, location=%d)", index, location);
if (location == CELL_GCM_LOCATION_MAIN)
{
if (index >= 1024 * 1024)
{
cellGcmSys.error("cellGcmGetReportDataAddressLocation: Wrong main index (%d)", index);
cellGcmSys.error("%s: Wrong main index (%d)", ppu.current_function, index);
}
return vm::cast(gcmIoOffsetToAddress(0x0e000000 + index * 0x10));
@@ -150,7 +160,7 @@ vm::ptr<CellGcmReportData> cellGcmGetReportDataAddressLocation(u32 index, u32 lo
if (index >= 2048)
{
cellGcmSys.error("cellGcmGetReportDataAddressLocation: Wrong local index (%d)", index);
cellGcmSys.error("%s: Wrong local index (%d)", ppu.current_function, index);
}
return vm::cast(rsx::get_current_renderer()->label_addr + ::offset32(&RsxReports::report) + index * 0x10);
@@ -225,20 +235,22 @@ u32 cellGcmGetReportDataAddress(u32 index)
return rsx::get_current_renderer()->label_addr + ::offset32(&RsxReports::report) + index * 0x10;
}
u32 cellGcmGetReportDataLocation(u32 index, u32 location)
u32 cellGcmGetReportDataLocation(ppu_thread& ppu, u32 index, u32 location)
{
cellGcmSys.warning("cellGcmGetReportDataLocation(index=%d, location=%d)", index, location);
vm::ptr<CellGcmReportData> report = cellGcmGetReportDataAddressLocation(index, location);
vm::ptr<CellGcmReportData> report = cellGcmGetReportDataAddressLocation(ppu, index, location);
return report->value;
}
u64 cellGcmGetTimeStampLocation(u32 index, u32 location)
u64 cellGcmGetTimeStampLocation(ppu_thread& ppu, u32 index, u32 location)
{
cellGcmSys.warning("cellGcmGetTimeStampLocation(index=%d, location=%d)", index, location);
cellGcmSys.trace("cellGcmGetTimeStampLocation(index=%d, location=%d)", index, location);
// NOTE: No error checkings
return cellGcmGetReportDataAddressLocation(index, location)->timer;
vm::ptr<CellGcmReportData> report = cellGcmGetReportDataAddressLocation(ppu, index, location);
// Timestamp reports don't need host GPU access and are much faster to emulate
return vm::get_super_ptr<CellGcmReportData>(report.addr())->timer;
}
//----------------------------------------------------------------------------
@@ -1508,8 +1520,8 @@ DECLARE(ppu_module_manager::cellGcmSys)("cellGcmSys", []()
REG_FUNC(cellGcmSys, cellGcmGetReportDataAddress);
REG_FUNC(cellGcmSys, cellGcmGetReportDataAddressLocation);
REG_FUNC(cellGcmSys, cellGcmGetReportDataLocation);
REG_FUNC(cellGcmSys, cellGcmGetTimeStamp).flag(MFF_FORCED_HLE); // HLE-ing this allows for optimizations around reports
REG_FUNC(cellGcmSys, cellGcmGetTimeStampLocation);
REG_FUNC(cellGcmSys, cellGcmGetTimeStamp).flag(MFF_FORCED_HLE); // HLE-ing this allows for optimizations around reports
REG_FUNC(cellGcmSys, cellGcmGetTimeStampLocation).flag(MFF_FORCED_HLE); // Ditto
// Command Buffer Control
REG_FUNC(cellGcmSys, cellGcmGetControlRegister);
+462 -262
View File
@@ -276,6 +276,8 @@ public:
u64 start_timestamp_us = 0;
std::array<ps_move_data, CELL_GEM_MAX_NUM> fake_move_data {}; // No need to be in savestate
atomic_t<u32> m_wake_up = 0;
atomic_t<u32> m_done = 0;
@@ -624,9 +626,9 @@ public:
cellGem.notice("Could not load mouse gem config. Using defaults.");
}
cellGem.notice("Real gem config=\n", g_cfg_gem_real.to_string());
cellGem.notice("Fake gem config=\n", g_cfg_gem_fake.to_string());
cellGem.notice("Mouse gem config=\n", g_cfg_gem_mouse.to_string());
cellGem.notice("Real gem config=%s", g_cfg_gem_real.to_string());
cellGem.notice("Fake gem config=%s", g_cfg_gem_fake.to_string());
cellGem.notice("Mouse gem config=%s", g_cfg_gem_mouse.to_string());
}
};
@@ -696,22 +698,165 @@ namespace gem
{
}
static inline u8 Y(u8 r, u8 g, u8 b) { return static_cast<u8>(0.299f * r + 0.587f * g + 0.114f * b); }
static inline u8 U(u8 r, u8 g, u8 b) { return static_cast<u8>(-0.14713f * r - 0.28886f * g + 0.436f * b); }
static inline u8 V(u8 r, u8 g, u8 b) { return static_cast<u8>(0.615f * r - 0.51499f * g - 0.10001f * b); }
YUV(const u8 rgb[3])
{
const u8 r = rgb[0];
const u8 g = rgb[1];
const u8 b = rgb[2];
y = Y(r, g, b);
u = U(r, g, b);
v = V(r, g, b);
}
static inline u8 Y(u8 r, u8 g, u8 b) { return static_cast<u8>(std::clamp(0.299f * r + 0.587f * g + 0.114f * b, 0.0f, 255.0f)); }
static inline u8 U(u8 r, u8 g, u8 b) { return static_cast<u8>(std::clamp(-0.169f * r - 0.331f * g + 0.499f * b + 128, 0.0f, 255.0f)); }
static inline u8 V(u8 r, u8 g, u8 b) { return static_cast<u8>(std::clamp(0.499f * r - 0.460f * g - 0.040f * b + 128, 0.0f, 255.0f)); }
};
bool convert_image_format(CellCameraFormat input_format, CellGemVideoConvertFormatEnum output_format,
const std::vector<u8>& video_data_in, u32 width, u32 height,
u8* video_data_out, u32 video_data_out_size, std::string_view caller)
template <bool use_gain>
static inline void debayer_raw8_impl(const u8* src, u8* dst, u8 alpha, f32 gain_r, f32 gain_g, f32 gain_b)
{
if (output_format != CELL_GEM_NO_VIDEO_OUTPUT && !video_data_out)
constexpr u32 in_pitch = 640;
constexpr u32 out_pitch = 640 * 4;
// Hamilton–Adams demosaicing
for (s32 y = 0; y < 480; y++)
{
const bool is_even_y = (y % 2) == 0;
const u8* srcc = src + y * in_pitch;
const u8* srcu = src + std::max(0, y - 1) * in_pitch;
const u8* srcd = src + std::min(480 - 1, y + 1) * in_pitch;
u8* dst0 = dst + y * out_pitch;
// Split loops (roughly twice the performance by removing one condition)
if (is_even_y)
{
for (s32 x = 0; x < 640; x++, dst0 += 4)
{
const bool is_even_x = (x % 2) == 0;
const int xl = std::max(0, x - 1);
const int xr = std::min(640 - 1, x + 1);
u8 r, b, g;
if (is_even_x)
{
// Blue pixel
const u8 up = srcu[x];
const u8 down = srcd[x];
const u8 left = srcc[xl];
const u8 right = srcc[xr];
const int dh = std::abs(int(left) - int(right));
const int dv = std::abs(int(up) - int(down));
r = (srcu[xl] + srcu[xr] + srcd[xl] + srcd[xr]) / 4;
if (dh < dv)
g = (left + right) / 2;
else if (dv < dh)
g = (up + down) / 2;
else
g = (up + down + left + right) / 4;
b = srcc[x];
}
else
{
// Green (on blue row)
r = (srcu[x] + srcd[x]) / 2;
g = srcc[x];
b = (srcc[xl] + srcc[xr]) / 2;
}
if constexpr (use_gain)
{
dst0[0] = static_cast<u8>(std::clamp(r * gain_r, 0.0f, 255.0f));
dst0[1] = static_cast<u8>(std::clamp(b * gain_b, 0.0f, 255.0f));
dst0[2] = static_cast<u8>(std::clamp(g * gain_g, 0.0f, 255.0f));
}
else
{
dst0[0] = r;
dst0[1] = g;
dst0[2] = b;
}
dst0[3] = alpha;
}
}
else
{
for (s32 x = 0; x < 640; x++, dst0 += 4)
{
const bool is_even_x = (x % 2) == 0;
const int xl = std::max(0, x - 1);
const int xr = std::min(640 - 1, x + 1);
u8 r, b, g;
if (is_even_x)
{
// Green (on red row)
r = (srcc[xl] + srcc[xr]) / 2;
g = srcc[x];
b = (srcu[x] + srcd[x]) / 2;
}
else
{
// Red pixel
const u8 up = srcu[x];
const u8 down = srcd[x];
const u8 left = srcc[xl];
const u8 right = srcc[xr];
const int dh = std::abs(int(left) - int(right));
const int dv = std::abs(int(up) - int(down));
r = srcc[x];
if (dh < dv)
g = (left + right) / 2;
else if (dv < dh)
g = (up + down) / 2;
else
g = (up + down + left + right) / 4;
b = (srcu[xl] + srcu[xr] + srcd[xl] + srcd[xr]) / 4;
}
if constexpr (use_gain)
{
dst0[0] = static_cast<u8>(std::clamp(r * gain_r, 0.0f, 255.0f));
dst0[1] = static_cast<u8>(std::clamp(b * gain_b, 0.0f, 255.0f));
dst0[2] = static_cast<u8>(std::clamp(g * gain_g, 0.0f, 255.0f));
}
else
{
dst0[0] = r;
dst0[1] = g;
dst0[2] = b;
}
dst0[3] = alpha;
}
}
}
}
static void debayer_raw8(const u8* src, u8* dst, u8 alpha, f32 gain_r, f32 gain_g, f32 gain_b)
{
if (gain_r != 1.0f || gain_g != 1.0f || gain_b != 1.0f)
debayer_raw8_impl<true>(src, dst, alpha, gain_r, gain_g, gain_b);
else
debayer_raw8_impl<false>(src, dst, alpha, gain_r, gain_g, gain_b);
}
bool convert_image_format(CellCameraFormat input_format, const CellGemVideoConvertAttribute& vc,
const std::vector<u8>& video_data_in, u32 width, u32 height,
u8* video_data_out, u32 video_data_out_size, u8* buffer_memory,
std::string_view caller)
{
if (vc.output_format != CELL_GEM_NO_VIDEO_OUTPUT && !video_data_out)
{
return false;
}
const u32 required_in_size = get_buffer_size_by_format(static_cast<s32>(input_format), width, height);
const s32 required_out_size = cellGemGetVideoConvertSize(output_format);
const s32 required_out_size = cellGemGetVideoConvertSize(vc.output_format);
if (video_data_in.size() != required_in_size)
{
@@ -721,7 +866,7 @@ namespace gem
if (required_out_size < 0 || video_data_out_size != static_cast<u32>(required_out_size))
{
cellGem.error("convert: out_size unknown: required=%d, actual=%d, format %d (called from %s)", required_out_size, video_data_out_size, output_format, caller);
cellGem.error("convert: out_size unknown: required=%d, actual=%d, format %d (called from %s)", required_out_size, video_data_out_size, vc.output_format, caller);
return false;
}
@@ -730,7 +875,121 @@ namespace gem
return false;
}
switch (output_format)
thread_local std::vector<u8> corrected_buffer;
thread_local std::vector<u8> combined_buffer;
thread_local std::vector<u8> conversion_buffer;
const u8* src_data = video_data_in.data();
const u8 alpha = vc.alpha;
const f32 gain_r = vc.gain * vc.blue_gain;
const f32 gain_g = vc.gain * vc.green_gain;
const f32 gain_b = vc.gain * vc.red_gain;
// Only RAW8 should be relevant for cellGem unless I'm mistaken
if (input_format == CELL_CAMERA_RAW8)
{
// TODO: CELL_GEM_AUTO_WHITE_BALANCE
// TODO: CELL_GEM_GAMMA_BOOST
// Correct outliers
if (vc.conversion_flags & CELL_GEM_FILTER_OUTLIER_PIXELS)
{
corrected_buffer.resize(width * height);
for (u32 y = 0; y < height; y++)
{
const u8* src = src_data + y * 640;
u8* dst = &corrected_buffer[y * 640];
for (u32 x = 0; x < width; x++, src++)
{
// Let's just say these 2 are outliers
if (const u8 val = *src; val > 0 && val < 255)
{
*dst++ = val;
continue;
}
// Just take the 4 neighbours for now
s32 sum = 0;
if (y >= 2) sum += *(src - (2 * 640));
if (x >= 2) sum += *(src - 2);
if (x < 638) sum += *(src + 2);
if (y < 478) sum += *(src + (2 * 640));
*dst++ = sum / 4; // Ignore count. It will only be less than 4 on the edges
}
}
src_data = corrected_buffer.data();
}
// Combine with previous frame
if (buffer_memory && (vc.conversion_flags & CELL_GEM_COMBINE_PREVIOUS_INPUT_FRAME))
{
combined_buffer.resize(width * height);
for (u32 i = 0; i < combined_buffer.size(); i++)
{
const u8 val = src_data[i];
u8& old = buffer_memory[i];
combined_buffer[i] = (old + val) / 2;
old = val;
}
src_data = combined_buffer.data();
}
switch (vc.output_format)
{
case CELL_GEM_YUV_640x480:
case CELL_GEM_YUV422_640x480:
case CELL_GEM_YUV411_640x480:
{
// Let's debayer the image first for YUV formats
conversion_buffer.resize(cellGemGetVideoConvertSize(CELL_GEM_RGBA_640x480));
debayer_raw8(src_data, conversion_buffer.data(), alpha, gain_r, gain_g, gain_b);
src_data = conversion_buffer.data();
input_format = CELL_CAMERA_RGBA;
width = 640;
height = 480;
break;
}
case CELL_GEM_BAYER_RESTORED:
case CELL_GEM_BAYER_RESTORED_RGGB:
case CELL_GEM_BAYER_RESTORED_RASTERIZED:
{
// Let's apply gain
if (gain_r != 1.0f || gain_g != 1.0f || gain_b != 1.0f)
{
conversion_buffer.resize(cellGemGetVideoConvertSize(CELL_GEM_RGBA_640x480));
const f32 bggr_gains[2][2] = {{gain_b, gain_g}, {gain_g, gain_r}};
const u8* src = src_data;
u8* dst = conversion_buffer.data();
for (u32 y = 0; y < 480; y++)
{
const f32* gains = bggr_gains[y % 2];
for (u32 x = 0; x < 640; x++)
{
*dst++ = static_cast<u8>(std::clamp(*src++ * gains[x % 2], 0.0f, 255.0f));
}
}
src_data = conversion_buffer.data();
}
break;
}
default:
break;
}
}
switch (vc.output_format)
{
case CELL_GEM_RGBA_640x480: // RGBA output; 640*480*4-byte output buffer required
{
@@ -738,51 +997,18 @@ namespace gem
{
case CELL_CAMERA_RAW8:
{
const u32 in_pitch = width;
const u32 out_pitch = width * 4;
for (u32 y = 0; y < height - 1; y += 2)
{
const u8* src0 = &video_data_in[y * in_pitch];
const u8* src1 = src0 + in_pitch;
u8* dst0 = video_data_out + y * out_pitch;
u8* dst1 = dst0 + out_pitch;
for (u32 x = 0; x < width - 1; x += 2, src0 += 2, src1 += 2, dst0 += 8, dst1 += 8)
{
const u8 b = src0[0];
const u8 g0 = src0[1];
const u8 g1 = src1[0];
const u8 r = src1[1];
const u8 top[4] = { r, g0, b, 255 };
const u8 bottom[4] = { r, g1, b, 255 };
// Top-Left
std::memcpy(dst0, top, 4);
// Top-Right Pixel
std::memcpy(dst0 + 4, top, 4);
// Bottom-Left Pixel
std::memcpy(dst1, bottom, 4);
// Bottom-Right Pixel
std::memcpy(dst1 + 4, bottom, 4);
}
}
debayer_raw8(src_data, video_data_out, alpha, gain_r, gain_g, gain_b);
break;
}
case CELL_CAMERA_RGBA:
{
std::memcpy(video_data_out, video_data_in.data(), std::min<usz>(required_in_size, required_out_size));
std::memcpy(video_data_out, src_data, std::min<usz>(required_in_size, required_out_size));
break;
}
default:
{
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, output_format, caller);
std::memcpy(video_data_out, video_data_in.data(), std::min<usz>(required_in_size, required_out_size));
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, vc.output_format, caller);
std::memcpy(video_data_out, src_data, std::min<usz>(required_in_size, required_out_size));
return false;
}
}
@@ -792,17 +1018,18 @@ namespace gem
{
if (input_format == CELL_CAMERA_RAW8)
{
std::memcpy(video_data_out, video_data_in.data(), std::min<usz>(required_in_size, required_out_size));
std::memcpy(video_data_out, src_data, std::min<usz>(required_in_size, required_out_size));
}
else
{
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, output_format, caller);
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, vc.output_format, caller);
return false;
}
break;
}
case CELL_GEM_YUV_640x480: // YUV output; 640*480+640*480+640*480-byte output buffer required (contiguous)
{
// YUV 4:4:4 planar. 1 value each per pixel
const u32 yuv_pitch = width;
u8* dst_y = video_data_out;
@@ -813,61 +1040,21 @@ namespace gem
{
case CELL_CAMERA_RAW8:
{
const u32 in_pitch = width;
for (u32 y = 0; y < height - 1; y += 2)
{
const u8* src0 = &video_data_in[y * in_pitch];
const u8* src1 = src0 + in_pitch;
u8* dst_y0 = dst_y + y * yuv_pitch;
u8* dst_y1 = dst_y0 + yuv_pitch;
u8* dst_u0 = dst_u + y * yuv_pitch;
u8* dst_u1 = dst_u0 + yuv_pitch;
u8* dst_v0 = dst_v + y * yuv_pitch;
u8* dst_v1 = dst_v0 + yuv_pitch;
for (u32 x = 0; x < width - 1; x += 2, src0 += 2, src1 += 2, dst_y0 += 2, dst_y1 += 2, dst_u0 += 2, dst_u1 += 2, dst_v0 += 2, dst_v1 += 2)
{
const u8 b = src0[0];
const u8 g0 = src0[1];
const u8 g1 = src1[0];
const u8 r = src1[1];
// Convert RGBA to YUV
const YUV yuv_top = YUV(r, g0, b);
const YUV yuv_bottom = YUV(r, g1, b);
dst_y0[0] = dst_y0[1] = yuv_top.y;
dst_y1[0] = dst_y1[1] = yuv_bottom.y;
dst_u0[0] = dst_u0[1] = yuv_top.u;
dst_u1[0] = dst_u1[1] = yuv_bottom.u;
dst_v0[0] = dst_v0[1] = yuv_top.v;
dst_v1[0] = dst_v1[1] = yuv_bottom.v;
}
}
fmt::throw_exception("Unreachable: should already be debayered");
break;
}
case CELL_CAMERA_RGBA:
{
const u32 in_pitch = width / 4;
const u32 in_pitch = width * 4;
for (u32 y = 0; y < height; y++)
{
const u8* src = &video_data_in[y * in_pitch];
const u8* src = src_data + y * in_pitch;
for (u32 x = 0; x < width; x++, src += 4)
{
const u8 r = src[0];
const u8 g = src[1];
const u8 b = src[2];
// Convert RGBA to YUV
const YUV yuv = YUV(r, g, b);
const YUV yuv = YUV(src);
*dst_y++ = yuv.y;
*dst_u++ = yuv.u;
@@ -878,8 +1065,8 @@ namespace gem
}
default:
{
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, output_format, caller);
std::memcpy(video_data_out, video_data_in.data(), std::min<usz>(required_in_size, required_out_size));
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, vc.output_format, caller);
std::memcpy(video_data_out, src_data, std::min<usz>(required_in_size, required_out_size));
return false;
}
}
@@ -887,6 +1074,7 @@ namespace gem
}
case CELL_GEM_YUV422_640x480: // YUV output; 640*480+320*480+320*480-byte output buffer required (contiguous)
{
// YUV 4:2:2 planar. 1 Y value per pixel, 1 U/V value per 2 horizontal pixels
const u32 y_pitch = width;
const u32 uv_pitch = width / 2;
@@ -898,43 +1086,7 @@ namespace gem
{
case CELL_CAMERA_RAW8:
{
const u32 in_pitch = width;
for (u32 y = 0; y < height - 1; y += 2)
{
const u8* src0 = &video_data_in[y * in_pitch];
const u8* src1 = src0 + in_pitch;
u8* dst_y0 = dst_y + y * y_pitch;
u8* dst_y1 = dst_y0 + y_pitch;
u8* dst_u0 = dst_u + y * uv_pitch;
u8* dst_u1 = dst_u0 + uv_pitch;
u8* dst_v0 = dst_v + y * uv_pitch;
u8* dst_v1 = dst_v0 + uv_pitch;
for (u32 x = 0; x < width - 1; x += 2, src0 += 2, src1 += 2, dst_y0 += 2, dst_y1 += 2)
{
const u8 b = src0[0];
const u8 g0 = src0[1];
const u8 g1 = src1[0];
const u8 r = src1[1];
// Convert RGBA to YUV
const YUV yuv_top = YUV(r, g0, b);
const YUV yuv_bottom = YUV(r, g1, b);
dst_y0[0] = dst_y0[1] = yuv_top.y;
dst_y1[0] = dst_y1[1] = yuv_bottom.y;
*dst_u0++ = yuv_top.u;
*dst_u1++ = yuv_bottom.u;
*dst_v0++ = yuv_top.v;
*dst_v1++ = yuv_bottom.v;
}
}
fmt::throw_exception("Unreachable: should already be debayered");
break;
}
case CELL_CAMERA_RGBA:
@@ -943,33 +1095,28 @@ namespace gem
for (u32 y = 0; y < height; y++)
{
const u8* src = &video_data_in[y * in_pitch];
const u8* src = src_data + y * in_pitch;
for (u32 x = 0; x < width - 1; x += 2, src += 8, dst_y += 2)
{
const u8 r_0 = src[0];
const u8 g_0 = src[1];
const u8 b_0 = src[2];
const u8 r_1 = src[4];
const u8 g_1 = src[5];
const u8 b_1 = src[6];
// Convert RGBA to YUV
const YUV yuv_0 = YUV(r_0, g_0, b_0);
const u8 y_1 = YUV::Y(r_1, g_1, b_1);
const YUV yuv_0 = YUV(src);
const YUV yuv_1 = YUV(src + 4);
dst_y[0] = yuv_0.y;
dst_y[1] = y_1;
*dst_u++ = yuv_0.u;
*dst_v++ = yuv_0.v;
dst_y[1] = yuv_1.y;
// Average U/V from 2 horizontal pixels
*dst_u++ = (yuv_0.u + yuv_1.u) / 2;
*dst_v++ = (yuv_0.v + yuv_1.v) / 2;
}
}
break;
}
default:
{
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, output_format, caller);
std::memcpy(video_data_out, video_data_in.data(), std::min<usz>(required_in_size, required_out_size));
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, vc.output_format, caller);
std::memcpy(video_data_out, src_data, std::min<usz>(required_in_size, required_out_size));
return false;
}
}
@@ -977,109 +1124,54 @@ namespace gem
}
case CELL_GEM_YUV411_640x480: // YUV411 output; 640*480+320*240+320*240-byte output buffer required (contiguous)
{
const u32 y_pitch = width;
const u32 uv_pitch = width / 4;
// YUV 4:1:1 planar. 1 Y value per pixel, 1 U/V value per 2x2 pixel block
u8* dst_y = video_data_out;
u8* dst_u = dst_y + y_pitch * height;
u8* dst_v = dst_u + uv_pitch * height;
u8* dst_u = dst_y + 640 * 480;
u8* dst_v = dst_u + 320 * 240;
switch (input_format)
{
case CELL_CAMERA_RAW8:
{
const u32 in_pitch = width;
for (u32 y = 0; y < height - 1; y += 2)
{
const u8* src0 = &video_data_in[y * in_pitch];
const u8* src1 = src0 + in_pitch;
u8* dst_y0 = dst_y + y * y_pitch;
u8* dst_y1 = dst_y0 + y_pitch;
u8* dst_u0 = dst_u + y * uv_pitch;
u8* dst_u1 = dst_u0 + uv_pitch;
u8* dst_v0 = dst_v + y * uv_pitch;
u8* dst_v1 = dst_v0 + uv_pitch;
for (u32 x = 0; x < width - 3; x += 4, src0 += 4, src1 += 4, dst_y0 += 4, dst_y1 += 4)
{
const u8 b_left = src0[0];
const u8 g0_left = src0[1];
const u8 b_right = src0[2];
const u8 g0_right = src0[3];
const u8 g1_left = src1[0];
const u8 r_left = src1[1];
const u8 g1_right = src1[2];
const u8 r_right = src1[3];
// Convert RGBA to YUV
const YUV yuv_top_left = YUV(r_left, g0_left, b_left); // Re-used for top-right
const u8 y_top_right = YUV::Y(r_right, g0_right, b_right);
const YUV yuv_bottom_left = YUV(r_left, g1_left, b_left); // Re-used for bottom-right
const u8 y_bottom_right = YUV::Y(r_right, g1_right, b_right);
dst_y0[0] = dst_y0[1] = yuv_top_left.y;
dst_y0[2] = dst_y0[3] = y_top_right;
dst_y1[0] = dst_y1[1] = yuv_bottom_left.y;
dst_y1[2] = dst_y1[3] = y_bottom_right;
*dst_u0++ = yuv_top_left.u;
*dst_u1++ = yuv_bottom_left.u;
*dst_v0++ = yuv_top_left.v;
*dst_v1++ = yuv_bottom_left.v;
}
}
fmt::throw_exception("Unreachable: should already be debayered");
break;
}
case CELL_CAMERA_RGBA:
{
const u32 in_pitch = width * 4;
for (u32 y = 0; y < height; y++)
// 2 rows at a time to get a 2x2 pixel block
for (u32 y = 0; y < height - 1; y += 2)
{
const u8* src = &video_data_in[y * in_pitch];
const u8* src = src_data + y * in_pitch;
const u8* src2 = src + in_pitch;
u8* dst_y1 = dst_y + y * 640;
u8* dst_y2 = dst_y1 + 640;
for (u32 x = 0; x < width - 3; x += 4, src += 16, dst_y += 4)
for (u32 x = 0; x < width - 1; x += 2, src += 8, src2 += 8, dst_y1 += 2, dst_y2 += 2)
{
const u8 r_0 = src[0];
const u8 g_0 = src[1];
const u8 b_0 = src[2];
const u8 r_1 = src[4];
const u8 g_1 = src[5];
const u8 b_1 = src[6];
const u8 r_2 = src[8];
const u8 g_2 = src[9];
const u8 b_2 = src[10];
const u8 r_3 = src[12];
const u8 g_3 = src[13];
const u8 b_3 = src[14];
// Convert RGBA to YUV
const YUV yuv_0 = YUV(r_0, g_0, b_0);
const u8 y_1 = YUV::Y(r_1, g_1, b_1);
const u8 y_2 = YUV::Y(r_2, g_2, b_2);
const u8 y_3 = YUV::Y(r_3, g_3, b_3);
const YUV yuv_0 = YUV(src);
const YUV yuv_1 = YUV(src + 4);
const YUV yuv_2 = YUV(src2);
const YUV yuv_3 = YUV(src2 + 4);
dst_y[0] = yuv_0.y;
dst_y[1] = y_1;
dst_y[2] = y_2;
dst_y[3] = y_3;
*dst_u++ = yuv_0.u;
*dst_v++ = yuv_0.v;
dst_y1[0] = yuv_0.y;
dst_y1[1] = yuv_1.y;
dst_y2[0] = yuv_2.y;
dst_y2[1] = yuv_3.y;
// Average U/V from 2x2 pixel block
*dst_u++ = (yuv_0.u + yuv_1.u + yuv_2.u + yuv_3.u) / 4;
*dst_v++ = (yuv_0.v + yuv_1.v + yuv_2.v + yuv_3.v) / 4;
}
}
break;
}
default:
{
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, output_format, caller);
std::memcpy(video_data_out, video_data_in.data(), std::min<usz>(required_in_size, required_out_size));
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, vc.output_format, caller);
std::memcpy(video_data_out, src_data, std::min<usz>(required_in_size, required_out_size));
return false;
}
}
@@ -1096,7 +1188,7 @@ namespace gem
for (u32 y = 0; y < height - 1; y += 2)
{
const u8* src0 = &video_data_in[y * in_pitch];
const u8* src0 = src_data + y * in_pitch;
const u8* src1 = src0 + in_pitch;
u8* dst0 = video_data_out + (y / 2) * out_pitch;
@@ -1109,8 +1201,8 @@ namespace gem
const u8 g1 = src1[0];
const u8 r = src1[1];
const u8 top[4] = { r, g0, b, 255 };
const u8 bottom[4] = { r, g1, b, 255 };
const u8 top[4] = { r, g0, b, alpha };
const u8 bottom[4] = { r, g1, b, alpha };
// Top-Left
std::memcpy(dst0, top, 4);
@@ -1128,7 +1220,7 @@ namespace gem
for (u32 y = 0; y < height / 2; y++)
{
const u8* src = &video_data_in[y * 2 * in_pitch];
const u8* src = src_data + y * 2 * in_pitch;
u8* dst = video_data_out + y * out_pitch;
for (u32 x = 0; x < width / 2; x++, src += 4 * 2, dst += 4)
@@ -1140,19 +1232,97 @@ namespace gem
}
default:
{
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, output_format, caller);
std::memcpy(video_data_out, video_data_in.data(), std::min<usz>(required_in_size, required_out_size));
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, vc.output_format, caller);
std::memcpy(video_data_out, src_data, std::min<usz>(required_in_size, required_out_size));
return false;
}
}
break;
}
case CELL_GEM_BAYER_RESTORED_RGGB: // Restored Bayer output, 2x2 pixels rearranged into 320x240 RG1G2B
{
if (input_format == CELL_CAMERA_RAW8)
{
const u32 dst_w = std::min(320u, width / 2);
const u32 dst_h = std::min(240u, height / 2);
const u32 in_pitch = width;
constexpr u32 out_pitch = 320 * 4;
for (u32 y = 0; y < dst_h; y++)
{
const u8* src0 = src_data + y * 2 * in_pitch;
const u8* src1 = src0 + in_pitch;
u8* dst = video_data_out + y * out_pitch;
for (u32 x = 0; x < dst_w; x++, src0 += 2, src1 += 2, dst += 4)
{
const u8 b = src0[0];
const u8 g0 = src0[1];
const u8 g1 = src1[0];
const u8 r = src1[1];
dst[0] = r;
dst[1] = g0;
dst[2] = g1;
dst[3] = b;
}
}
}
else
{
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, vc.output_format, caller);
std::memcpy(video_data_out, src_data, std::min<usz>(required_in_size, required_out_size));
return false;
}
break;
}
case CELL_GEM_BAYER_RESTORED_RASTERIZED: // Restored Bayer output, R,G1,G2,B rearranged into 4 contiguous 320x240 1-channel rasters
{
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, output_format, caller);
std::memcpy(video_data_out, video_data_in.data(), std::min<usz>(required_in_size, required_out_size));
return false;
if (input_format == CELL_CAMERA_RAW8)
{
const u32 dst_w = std::min(320u, width / 2);
const u32 dst_h = std::min(240u, height / 2);
const u32 in_pitch = width;
constexpr u32 out_plane = 320 * 240;
constexpr u32 out_pitch = 320;
u8* dst_plane_r = video_data_out;
u8* dst_plane_g1 = video_data_out + out_plane;
u8* dst_plane_g2 = video_data_out + out_plane * 2;
u8* dst_plane_b = video_data_out + out_plane * 3;
for (u32 y = 0; y < dst_h; y++)
{
const u8* src0 = src_data + y * 2 * in_pitch;
const u8* src1 = src0 + in_pitch;
u8* dst_r = dst_plane_r + y * out_pitch;
u8* dst_g1 = dst_plane_g1 + y * out_pitch;
u8* dst_g2 = dst_plane_g2 + y * out_pitch;
u8* dst_b = dst_plane_b + y * out_pitch;
for (u32 x = 0; x < dst_w; x++, src0 += 2, src1 += 2)
{
const u8 b = src0[0];
const u8 g0 = src0[1];
const u8 g1 = src1[0];
const u8 r = src1[1];
dst_r[x] = r;
dst_g1[x] = g0;
dst_g2[x] = g1;
dst_b[x] = b;
}
}
}
else
{
cellGem.error("Unimplemented: Converting %s to %s (called from %s)", input_format, vc.output_format, caller);
std::memcpy(video_data_out, src_data, std::min<usz>(required_in_size, required_out_size));
return false;
}
break;
}
case CELL_GEM_NO_VIDEO_OUTPUT: // Disable video output
{
@@ -1161,7 +1331,7 @@ namespace gem
}
default:
{
cellGem.error("Trying to convert %s to %s (called from %s)", input_format, output_format, caller);
cellGem.error("Trying to convert %s to %s (called from %s)", input_format, vc.output_format, caller);
return false;
}
}
@@ -1331,8 +1501,15 @@ void gem_config_data::operator()()
vc = vc_attribute;
}
if (g_cfg.io.camera != camera_handler::qt)
switch (g_cfg.io.camera)
{
#ifdef HAVE_SDL3
case camera_handler::sdl:
#endif
case camera_handler::qt:
break;
case camera_handler::fake:
case camera_handler::null:
video_conversion_in_progress = false;
done();
continue;
@@ -1340,13 +1517,15 @@ void gem_config_data::operator()()
const auto& shared_data = g_fxo->get<gem_camera_shared>();
if (gem::convert_image_format(shared_data.format, vc.output_format, video_data_in, shared_data.width, shared_data.height, vc_attribute.video_data_out ? vc_attribute.video_data_out.get_ptr() : nullptr, video_data_out_size, "cellGem"))
if (gem::convert_image_format(shared_data.format, vc, video_data_in, shared_data.width, shared_data.height,
vc.video_data_out ? vc.video_data_out.get_ptr() : nullptr, video_data_out_size,
vc.buffer_memory ? vc.buffer_memory.get_ptr() : nullptr, "cellGem"))
{
cellGem.trace("Converted video frame of format %s to %s", shared_data.format.load(), vc.output_format.get());
if (g_cfg.io.paint_move_spheres)
{
paint_spheres(vc.output_format, shared_data.width, shared_data.height, vc_attribute.video_data_out ? vc_attribute.video_data_out.get_ptr() : nullptr, video_data_out_size);
paint_spheres(vc.output_format, shared_data.width, shared_data.height, vc.video_data_out ? vc.video_data_out.get_ptr() : nullptr, video_data_out_size);
}
}
@@ -1617,7 +1796,7 @@ static inline void pos_to_gem_image_state(u32 gem_num, gem_config::gem_controlle
const f32 scaling_width = x_max / static_cast<f32>(shared_data.width);
const f32 scaling_height = y_max / static_cast<f32>(shared_data.height);
const f32 mmPerPixel = CELL_GEM_SPHERE_RADIUS_MM / controller.radius;
const f32 mmPerPixel = controller.radius <= 0.0f ? 0.0f : (CELL_GEM_SPHERE_RADIUS_MM / controller.radius);
// Image coordinates in pixels
const f32 image_x = static_cast<f32>(x_pos) / scaling_width;
@@ -1657,7 +1836,7 @@ static inline void pos_to_gem_image_state(u32 gem_num, gem_config::gem_controlle
}
}
static inline void pos_to_gem_state(u32 gem_num, gem_config::gem_controller& controller, vm::ptr<CellGemState>& gem_state, s32 x_pos, s32 y_pos, s32 x_max, s32 y_max, const ps_move_data& move_data)
static inline void pos_to_gem_state(u32 gem_num, gem_config::gem_controller& controller, vm::ptr<CellGemState>& gem_state, s32 x_pos, s32 y_pos, s32 x_max, s32 y_max, ps_move_data& move_data)
{
const auto& shared_data = g_fxo->get<gem_camera_shared>();
@@ -1670,7 +1849,7 @@ static inline void pos_to_gem_state(u32 gem_num, gem_config::gem_controller& con
const f32 scaling_width = x_max / static_cast<f32>(shared_data.width);
const f32 scaling_height = y_max / static_cast<f32>(shared_data.height);
const f32 mmPerPixel = CELL_GEM_SPHERE_RADIUS_MM / controller.radius;
const f32 mmPerPixel = controller.radius <= 0.0f ? 0.0f : (CELL_GEM_SPHERE_RADIUS_MM / controller.radius);
// Image coordinates in pixels
const f32 image_x = static_cast<f32>(x_pos) / scaling_width;
@@ -1703,10 +1882,10 @@ static inline void pos_to_gem_state(u32 gem_num, gem_config::gem_controller& con
// Calculate orientation
if (g_cfg.io.move == move_handler::real || (g_cfg.io.move == move_handler::fake && move_data.orientation_enabled))
{
gem_state->quat[0] = move_data.quaternion[0]; // x
gem_state->quat[1] = move_data.quaternion[1]; // y
gem_state->quat[2] = move_data.quaternion[2]; // z
gem_state->quat[3] = move_data.quaternion[3]; // w
gem_state->quat[0] = move_data.quaternion.x();
gem_state->quat[1] = move_data.quaternion.y();
gem_state->quat[2] = move_data.quaternion.z();
gem_state->quat[3] = move_data.quaternion.w();
}
else
{
@@ -1733,6 +1912,17 @@ static inline void pos_to_gem_state(u32 gem_num, gem_config::gem_controller& con
gem_state->quat[3] = q_w;
}
if constexpr (!ps_move_data::use_imu_for_velocity)
{
move_data.update_velocity(shared_data.frame_timestamp_us, gem_state->pos);
for (u32 i = 0; i < 3; i++)
{
gem_state->vel[i] = move_data.vel_world[i];
gem_state->accel[i] = move_data.accel_world[i];
}
}
// Update visibility for fake handlers
if (g_cfg.io.move != move_handler::real)
{
@@ -1906,9 +2096,17 @@ static void ps_move_pos_to_gem_state(u32 gem_num, gem_config::gem_controller& co
if constexpr (std::is_same_v<T, vm::ptr<CellGemState>>)
{
gem_state->temperature = pad->move_data.temperature;
gem_state->accel[0] = pad->move_data.accelerometer_x * 1000; // linear velocity in mm/s²
gem_state->accel[1] = pad->move_data.accelerometer_y * 1000; // linear velocity in mm/s²
gem_state->accel[2] = pad->move_data.accelerometer_z * 1000; // linear velocity in mm/s²
for (u32 i = 0; i < 3; i++)
{
if constexpr (ps_move_data::use_imu_for_velocity)
{
gem_state->vel[i] = pad->move_data.vel_world[i];
gem_state->accel[i] = pad->move_data.accel_world[i];
}
gem_state->angvel[i] = pad->move_data.angvel_world[i];
gem_state->angaccel[i] = pad->move_data.angaccel_world[i];
}
pos_to_gem_state(gem_num, controller, gem_state, info.x_pos, info.y_pos, info.x_max, info.y_max, pad->move_data);
}
@@ -2147,7 +2345,8 @@ static void mouse_pos_to_gem_state(u32 mouse_no, gem_config::gem_controller& con
if constexpr (std::is_same_v<T, vm::ptr<CellGemState>>)
{
pos_to_gem_state(mouse_no, controller, gem_state, mouse.x_pos, mouse.y_pos, mouse.x_max, mouse.y_max, {});
ps_move_data& move_data = ::at32(g_fxo->get<gem_config>().fake_move_data, mouse_no);
pos_to_gem_state(mouse_no, controller, gem_state, mouse.x_pos, mouse.y_pos, mouse.x_max, mouse.y_max, move_data);
}
else if constexpr (std::is_same_v<T, vm::ptr<CellGemImageState>>)
{
@@ -2215,7 +2414,8 @@ static void gun_pos_to_gem_state(u32 gem_no, gem_config::gem_controller& control
if constexpr (std::is_same_v<T, vm::ptr<CellGemState>>)
{
pos_to_gem_state(gem_no, controller, gem_state, x_pos, y_pos, x_max, y_max, {});
ps_move_data& move_data = ::at32(g_fxo->get<gem_config>().fake_move_data, gem_no);
pos_to_gem_state(gem_no, controller, gem_state, x_pos, y_pos, x_max, y_max, move_data);
}
else if constexpr (std::is_same_v<T, vm::ptr<CellGemImageState>>)
{
@@ -2769,7 +2969,7 @@ error_code cellGemGetInertialState(u32 gem_num, u32 state_flag, u64 timestamp, v
inertial_state->timestamp = (get_guest_system_time() - gem.start_timestamp_us);
inertial_state->counter = gem.inertial_counter++;
inertial_state->accelerometer[0] = 10; // Current gravity in m/s²
inertial_state->accelerometer[2] = 1.0f; // Current gravity in G units (9.81 == 1 unit)
switch (g_cfg.io.move)
{
@@ -2786,12 +2986,12 @@ error_code cellGemGetInertialState(u32 gem_num, u32 state_flag, u64 timestamp, v
if (pad && pad->is_connected() && !pad->is_copilot())
{
inertial_state->temperature = pad->move_data.temperature;
inertial_state->accelerometer[0] = pad->move_data.accelerometer_x;
inertial_state->accelerometer[1] = pad->move_data.accelerometer_y;
inertial_state->accelerometer[2] = pad->move_data.accelerometer_z;
inertial_state->gyro[0] = pad->move_data.gyro_x;
inertial_state->gyro[1] = pad->move_data.gyro_y;
inertial_state->gyro[2] = pad->move_data.gyro_z;
for (u32 i = 0; i < 3; i++)
{
inertial_state->accelerometer[i] = pad->move_data.accelerometer[i];
inertial_state->gyro[i] = pad->move_data.gyro[i];
}
}
}
+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
@@ -634,7 +634,7 @@ u32 microphone_device::capture_audio()
if (ALCenum err = alcGetError(micdevice.device); err != ALC_NO_ERROR)
{
cellMic.error("Error getting number of captured samples of device '%s' (error=%s)", micdevice.name, fmt::alc_error{micdevice.device, err});
return CELL_MICIN_ERROR_FATAL;
return 0;
}
num_samples = std::min<u32>(num_samples, samples_in);
+1 -1
View File
@@ -238,7 +238,7 @@ public:
if (over_size > Size)
{
m_tail += (over_size - Size);
if (m_tail > Size)
if (m_tail >= Size)
m_tail -= Size;
m_used = Size;
+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
+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
+24 -9
View File
@@ -876,39 +876,42 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
// Sort the entries
{
const u32 order = setList->sortOrder;
const u32 type = setList->sortType;
std::sort(save_entries.begin(), save_entries.end(), [order, type](const SaveDataEntry& entry1, const SaveDataEntry& entry2) -> bool
auto comp = [type](const SaveDataEntry& entry1, const SaveDataEntry& entry2) -> bool
{
const bool mtime_lower = entry1.mtime < entry2.mtime;
const bool mtime_equal = entry1.mtime == entry2.mtime;
const bool subtitle_lower = entry1.subtitle < entry2.subtitle;
const bool subtitle_equal = entry1.subtitle == entry2.subtitle;
const bool revert_order = order == CELL_SAVEDATA_SORTORDER_DESCENT;
if (type == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME)
{
if (mtime_equal)
{
return subtitle_lower != revert_order;
return subtitle_lower;
}
return mtime_lower != revert_order;
return mtime_lower;
}
else if (type == CELL_SAVEDATA_SORTTYPE_SUBTITLE)
{
if (subtitle_equal)
{
return mtime_lower != revert_order;
return mtime_lower;
}
return subtitle_lower != revert_order;
return subtitle_lower;
}
ensure(false);
return true;
});
};
if (setList->sortOrder == CELL_SAVEDATA_SORTORDER_ASCENT)
std::sort(save_entries.begin(), save_entries.end(), comp);
else
std::sort(save_entries.rbegin(), save_entries.rend(), comp);
}
// Fill the listGet->dirList array
@@ -2514,6 +2517,18 @@ error_code cellSaveDataUserFixedDelete(ppu_thread& ppu, u32 userId, PSetList set
return savedata_op(ppu, SAVEDATA_OP_FIXED_DELETE, 0, vm::null, 1, setList, setBuf, vm::null, funcFixed, vm::null, vm::null, container, 6, userdata, userId, funcDone);
}
error_code cellSaveDataGetEnableOverlay()
{
cellSaveData.todo("cellSaveDataGetEnableOverlay()");
// auto& manager = g_fxo->get<savedata_manager>();
// manager.enable_overlay;
// TODO
return CELL_OK;
}
void cellSaveDataEnableOverlay(s32 enable)
{
cellSaveData.notice("cellSaveDataEnableOverlay(enable=%d)", enable);
@@ -2521,7 +2536,6 @@ void cellSaveDataEnableOverlay(s32 enable)
manager.enable_overlay = enable != 0;
}
// Functions (Extensions)
error_code cellSaveDataListDelete(ppu_thread& ppu, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncDone funcDone, u32 container, vm::ptr<void> userdata)
{
@@ -2678,6 +2692,7 @@ void cellSysutil_SaveData_init()
REG_VAR(cellSysutil, g_savedata_context).flag(MFF_HIDDEN);
// libsysutil functions:
REG_FUNC(cellSysutil, cellSaveDataGetEnableOverlay);
REG_FUNC(cellSysutil, cellSaveDataEnableOverlay);
REG_FUNC(cellSysutil, cellSaveDataDelete2);
+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
+8
View File
@@ -1438,6 +1438,13 @@ s32 cellSpursInitializeWithAttribute2(ppu_thread& ppu, vm::ptr<CellSpurs> spurs,
attr->swlIsPreem);
}
// Initialise SPURS
s32 cellSpursInitializeForSpuSharing()
{
cellSpurs.todo("cellSpursInitializeForSpuSharing()");
return CELL_OK;
}
/// Initialise SPURS attribute
s32 _cellSpursAttributeInitialize(vm::ptr<CellSpursAttribute> attr, u32 revision, u32 sdkVersion, u32 nSpus, s32 spuPriority, s32 ppuPriority, b8 exitIfNoWork)
{
@@ -5390,6 +5397,7 @@ DECLARE(ppu_module_manager::cellSpurs)("cellSpurs", [](ppu_static_module* _this)
REG_FUNC(cellSpurs, cellSpursInitialize);
REG_FUNC(cellSpurs, cellSpursInitializeWithAttribute);
REG_FUNC(cellSpurs, cellSpursInitializeWithAttribute2);
REG_FUNC(cellSpurs, cellSpursInitializeForSpuSharing);
REG_FUNC(cellSpurs, cellSpursFinalize);
REG_FUNC(cellSpurs, _cellSpursAttributeInitialize);
REG_FUNC(cellSpurs, cellSpursAttributeSetMemoryContainerForSpuThread);
+28
View File
@@ -406,6 +406,30 @@ error_code cellSysmoduleIsLoadedEx()
return CELL_OK;
}
error_code cellSysmoduleLoadModuleFile()
{
UNIMPLEMENTED_FUNC(cellSysmodule);
return CELL_OK;
}
error_code cellSysmoduleUnloadModuleFile()
{
UNIMPLEMENTED_FUNC(cellSysmodule);
return CELL_OK;
}
error_code cellSysmoduleSetDebugmode()
{
UNIMPLEMENTED_FUNC(cellSysmodule);
return CELL_OK;
}
error_code cellSysmoduleSetInternalmode()
{
UNIMPLEMENTED_FUNC(cellSysmodule);
return CELL_OK;
}
DECLARE(ppu_module_manager::cellSysmodule)("cellSysmodule", []()
{
REG_FUNC(cellSysmodule, cellSysmoduleInitialize);
@@ -421,4 +445,8 @@ DECLARE(ppu_module_manager::cellSysmodule)("cellSysmodule", []()
REG_FUNC(cellSysmodule, cellSysmoduleUnloadModuleEx);
REG_FUNC(cellSysmodule, cellSysmoduleLoadModuleEx);
REG_FUNC(cellSysmodule, cellSysmoduleIsLoadedEx);
REG_FUNC(cellSysmodule, cellSysmoduleLoadModuleFile);
REG_FUNC(cellSysmodule, cellSysmoduleUnloadModuleFile);
REG_FUNC(cellSysmodule, cellSysmoduleSetDebugmode);
REG_FUNC(cellSysmodule, cellSysmoduleSetInternalmode);
});
+181 -90
View File
@@ -211,6 +211,7 @@ struct vdec_context final
lf_queue<vdec_cmd> in_cmd;
AVRational log_time_base{}; // Used to reduce log spam
AVRational log_framerate{}; // Used to reduce log spam
vdec_context(s32 type, u32 /*profile*/, u32 addr, u32 size, vm::ptr<CellVdecCbMsg> func, u32 arg)
: type(type)
@@ -231,6 +232,7 @@ struct vdec_context final
codec = avcodec_find_decoder(AV_CODEC_ID_H264);
break;
}
case CELL_VDEC_CODEC_TYPE_MPEG4:
case CELL_VDEC_CODEC_TYPE_DIVX:
{
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG4);
@@ -292,6 +294,19 @@ struct vdec_context final
sws_freeContext(sws);
}
static u32 freq_to_framerate_code(f64 freq)
{
if (std::abs(freq - 23.976) < 0.002) return CELL_VDEC_FRC_24000DIV1001;
if (std::abs(freq - 24.000) < 0.001) return CELL_VDEC_FRC_24;
if (std::abs(freq - 25.000) < 0.001) return CELL_VDEC_FRC_25;
if (std::abs(freq - 29.970) < 0.002) return CELL_VDEC_FRC_30000DIV1001;
if (std::abs(freq - 30.000) < 0.001) return CELL_VDEC_FRC_30;
if (std::abs(freq - 50.000) < 0.001) return CELL_VDEC_FRC_50;
if (std::abs(freq - 59.940) < 0.002) return CELL_VDEC_FRC_60000DIV1001;
if (std::abs(freq - 60.000) < 0.001) return CELL_VDEC_FRC_60;
return 0;
}
void exec(ppu_thread& ppu, u32 vid)
{
perf_meter<"VDEC"_u32> perf0;
@@ -341,6 +356,7 @@ struct vdec_context final
out_queue.clear(); // Flush image queue
log_time_base = {};
log_framerate = {};
frc_set = 0; // TODO: ???
next_pts = 0;
@@ -471,10 +487,10 @@ struct vdec_context final
frame.userdata = au_usrd;
frame.attr = attr;
u64 amend = 0;
if (frc_set)
{
u64 amend = 0;
switch (frc_set)
{
case CELL_VDEC_FRC_24000DIV1001: amend = 1001 * 90000 / 24000; break;
@@ -491,62 +507,45 @@ struct vdec_context final
}
}
next_pts += amend;
next_dts += amend;
frame.frc = frc_set;
}
else if (ctx->time_base.num == 0)
else if (ctx->time_base.den && ctx->time_base.num)
{
if (log_time_base.den != ctx->time_base.den || log_time_base.num != ctx->time_base.num)
const auto freq = 1. * ctx->time_base.den / ctx->time_base.num / ticks_per_frame;
frame.frc = freq_to_framerate_code(freq);
if (frame.frc)
{
cellVdec.error("time_base.num is 0 (handle=0x%x, seq_id=%d, cmd_id=%d, %d/%d, tpf=%d framerate=%d/%d)", handle, cmd->seq_id, cmd->id, ctx->time_base.num, ctx->time_base.den, ticks_per_frame, ctx->framerate.num, ctx->framerate.den);
amend = u64{90000} * ctx->time_base.num * ticks_per_frame / ctx->time_base.den;
}
}
else if (ctx->framerate.den && ctx->framerate.num)
{
const auto freq = ctx->framerate.num / static_cast<f64>(ctx->framerate.den);
frame.frc = freq_to_framerate_code(freq);
if (frame.frc)
{
amend = u64{90000} * ctx->framerate.den / ctx->framerate.num;
}
}
if (amend == 0 || frame.frc == 0)
{
if (log_time_base.den != ctx->time_base.den || log_time_base.num != ctx->time_base.num || log_framerate.den != ctx->framerate.den || log_framerate.num != ctx->framerate.num)
{
cellVdec.error("Invalid frequency (handle=0x%x, seq_id=%d, cmd_id=%d, timebase=%d/%d, tpf=%d framerate=%d/%d)", handle, cmd->seq_id, cmd->id, ctx->time_base.num, ctx->time_base.den, ticks_per_frame, ctx->framerate.num, ctx->framerate.den);
log_time_base = ctx->time_base;
log_framerate = ctx->framerate;
}
// Hack
const u64 amend = u64{90000} / 30;
amend = u64{90000} / 30;
frame.frc = CELL_VDEC_FRC_30;
next_pts += amend;
next_dts += amend;
}
else
{
u64 amend = u64{90000} * ctx->time_base.num * ticks_per_frame / ctx->time_base.den;
const auto freq = 1. * ctx->time_base.den / ctx->time_base.num / ticks_per_frame;
if (std::abs(freq - 23.976) < 0.002)
frame.frc = CELL_VDEC_FRC_24000DIV1001;
else if (std::abs(freq - 24.000) < 0.001)
frame.frc = CELL_VDEC_FRC_24;
else if (std::abs(freq - 25.000) < 0.001)
frame.frc = CELL_VDEC_FRC_25;
else if (std::abs(freq - 29.970) < 0.002)
frame.frc = CELL_VDEC_FRC_30000DIV1001;
else if (std::abs(freq - 30.000) < 0.001)
frame.frc = CELL_VDEC_FRC_30;
else if (std::abs(freq - 50.000) < 0.001)
frame.frc = CELL_VDEC_FRC_50;
else if (std::abs(freq - 59.940) < 0.002)
frame.frc = CELL_VDEC_FRC_60000DIV1001;
else if (std::abs(freq - 60.000) < 0.001)
frame.frc = CELL_VDEC_FRC_60;
else
{
if (log_time_base.den != ctx->time_base.den || log_time_base.num != ctx->time_base.num)
{
// 1/1000 usually means that the time stamps are written in 1ms units and that the frame rate may vary.
cellVdec.error("Unsupported time_base (handle=0x%x, seq_id=%d, cmd_id=%d, %d/%d, tpf=%d framerate=%d/%d)", handle, cmd->seq_id, cmd->id, ctx->time_base.num, ctx->time_base.den, ticks_per_frame, ctx->framerate.num, ctx->framerate.den);
log_time_base = ctx->time_base;
}
// Hack
amend = u64{90000} / 30;
frame.frc = CELL_VDEC_FRC_30;
}
next_pts += amend;
next_dts += amend;
}
next_pts += amend;
next_dts += amend;
cellVdec.trace("Got picture (handle=0x%x, seq_id=%d, cmd_id=%d, pts=0x%llx[0x%llx], dts=0x%llx[0x%llx])", handle, cmd->seq_id, cmd->id, frame.pts, frame->pts, frame.dts, frame->pkt_dts);
@@ -680,7 +679,15 @@ static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0
{
cellVdec.warning("cellVdecQueryAttr: AVC (profile=%d)", profile);
//const vm::ptr<CellVdecAvcSpecificInfo> sinfo = vm::cast(spec_addr);
const vm::ptr<CellVdecAvcSpecificInfo> sinfo = vm::cast(spec_addr);
if (sinfo)
{
if (sinfo->thisSize != sizeof(CellVdecAvcSpecificInfo))
{
return { CELL_VDEC_ERROR_ARG, "Invalid AVC specific info size %d", sinfo->thisSize };
}
}
// TODO: sinfo
@@ -699,7 +706,7 @@ static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0
case CELL_VDEC_AVC_LEVEL_4P0: memSize = new_sdk ? 0x33A5FFD : 0x36A527D; break;
case CELL_VDEC_AVC_LEVEL_4P1: memSize = new_sdk ? 0x33A5FFD : 0x36A527D; break;
case CELL_VDEC_AVC_LEVEL_4P2: memSize = new_sdk ? 0x33A5FFD : 0x36A527D; break;
default: return CELL_VDEC_ERROR_ARG;
default: return { CELL_VDEC_ERROR_ARG, "Invalid AVC profile level %d", profile };
}
decoderVerLower = 0x11300;
@@ -715,12 +722,10 @@ static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0
{
if (sinfo->thisSize != sizeof(CellVdecMpeg2SpecificInfo))
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "Invalid MPEG2 specific info size %d", sinfo->thisSize };
}
}
// TODO: sinfo
const u32 maxDecH = sinfo ? +sinfo->maxDecodedFrameHeight : 0;
const u32 maxDecW = sinfo ? +sinfo->maxDecodedFrameWidth : 0;
@@ -730,7 +735,7 @@ static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0
{
if (maxDecW > 352 || maxDecH > 288)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "Invalid max decoded frame size %dx%d for profile %d", maxDecH, maxDecW, profile };
}
memSize = new_sdk ? 0x11290B : 0x2A610B;
@@ -740,7 +745,7 @@ static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0
{
if (maxDecW > 720 || maxDecH > 576)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "Invalid max decoded frame size %dx%d for profile %d", maxDecH, maxDecW, profile };
}
memSize = new_sdk ? 0x2DFB8B : 0x47110B;
@@ -750,7 +755,7 @@ static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0
{
if (maxDecW > 1440 || maxDecH > 1152)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "Invalid max decoded frame size %dx%d for profile %d", maxDecH, maxDecW, profile };
}
memSize = new_sdk ? 0xA0270B : 0xB8F90B;
@@ -760,18 +765,94 @@ static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0
{
if (maxDecW > 1920 || maxDecH > 1152)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "Invalid max decoded frame size %dx%d for profile %d", maxDecH, maxDecW, profile };
}
memSize = new_sdk ? 0xD2F40B : 0xEB990B;
break;
}
default: return CELL_VDEC_ERROR_ARG;
default: return { CELL_VDEC_ERROR_ARG, "Invalid MPEG2 profile %d", profile };
}
decoderVerLower = 0x1030000;
break;
}
case CELL_VDEC_CODEC_TYPE_MPEG4:
{
cellVdec.warning("cellVdecQueryAttr: MPEG4 (profile=%d)", profile);
const vm::ptr<CellVdecMpeg4SpecificInfo> sinfo = vm::cast(spec_addr);
if (sinfo)
{
if (sinfo->thisSize != sizeof(CellVdecMpeg4SpecificInfo))
{
return { CELL_VDEC_ERROR_ARG, "Invalid MPEG4 specific info size %d", sinfo->thisSize };
}
}
const u32 maxDecH = sinfo ? +sinfo->maxDecodedFrameHeight : 0;
const u32 maxDecW = sinfo ? +sinfo->maxDecodedFrameWidth : 0;
switch (profile)
{
case CELL_VDEC_MPEG4_SP_L1:
{
if (maxDecW > 176 || maxDecH > 144)
{
return { CELL_VDEC_ERROR_ARG, "Invalid max decoded frame size %dx%d for profile %d", maxDecH, maxDecW, profile };
}
memSize = new_sdk ? 0x8B78B : 0xBB70B;
break;
}
case CELL_VDEC_MPEG4_SP_L2:
case CELL_VDEC_MPEG4_SP_L3:
{
if (maxDecW > 352 || maxDecH > 288)
{
return { CELL_VDEC_ERROR_ARG, "Invalid max decoded frame size %dx%d for profile %d", maxDecH, maxDecW, profile };
}
memSize = new_sdk ? 0xEFE0B : 0x11FD8B;
break;
}
case CELL_VDEC_MPEG4_SP_D1_NTSC:
{
if (maxDecW > 720 || maxDecH > 480)
{
return { CELL_VDEC_ERROR_ARG, "Invalid max decoded frame size %dx%d for profile %d", maxDecH, maxDecW, profile };
}
memSize = new_sdk ? 0x22DB0B : 0x25DA8B;
break;
}
case CELL_VDEC_MPEG4_SP_VGA:
{
if (maxDecW > 640 || maxDecH > 480)
{
return { CELL_VDEC_ERROR_ARG, "Invalid max decoded frame size %dx%d for profile %d", maxDecH, maxDecW, profile };
}
memSize = new_sdk ? 0x1FC00B : 0x22BF8B;
break;
}
case CELL_VDEC_MPEG4_SP_D1_PAL:
{
if (maxDecW > 720 || maxDecH > 576)
{
return { CELL_VDEC_ERROR_ARG, "Invalid max decoded frame size %dx%d for profile %d", maxDecH, maxDecW, profile };
}
memSize = new_sdk ? 0x28570B : 0x2B568B;
break;
}
default: return { CELL_VDEC_ERROR_ARG, "Invalid MPEG4 profile %d", profile };
}
decoderVerLower = 0x1080000;
break;
}
case CELL_VDEC_CODEC_TYPE_DIVX:
{
cellVdec.warning("cellVdecQueryAttr: DivX (profile=%d)", profile);
@@ -780,9 +861,9 @@ static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0
if (sinfo)
{
if (sinfo->thisSize != sizeof(CellVdecDivxSpecificInfo2))
if (sinfo->thisSize != sizeof(CellVdecDivxSpecificInfo) && sinfo->thisSize != sizeof(CellVdecDivxSpecificInfo2))
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "Invalid DIVX specific info size %d", sinfo->thisSize };
}
}
@@ -790,7 +871,7 @@ static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0
//const u32 maxDecH = sinfo ? +sinfo->maxDecodedFrameHeight : 0;
//const u32 maxDecW = sinfo ? +sinfo->maxDecodedFrameWidth : 0;
u32 nrOfBuf = sinfo ? +sinfo->numberOfDecodedFrameBuffer : 0;
u32 nrOfBuf = sinfo && sinfo->thisSize == sizeof(CellVdecDivxSpecificInfo2) ? +sinfo->numberOfDecodedFrameBuffer : 0;
if (nrOfBuf == 0)
{
@@ -800,12 +881,12 @@ static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0
{
if (profile != CELL_VDEC_DIVX_QMOBILE && profile != CELL_VDEC_DIVX_MOBILE)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "Invalid number of decoded frame buffers %d for DIVX profile %d", nrOfBuf, profile };
}
}
else if (nrOfBuf != 4 && nrOfBuf != 3)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "Invalid number of decoded frame buffers %d for DIVX", nrOfBuf };
}
// TODO: change memSize based on buffercount.
@@ -817,13 +898,13 @@ static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0
case CELL_VDEC_DIVX_HOME_THEATER: memSize = new_sdk ? 0x386A60 : 0x498060; break;
case CELL_VDEC_DIVX_HD_720 : memSize = new_sdk ? 0x692070 : 0x805690; break;
case CELL_VDEC_DIVX_HD_1080 : memSize = new_sdk ? 0xD78100 : 0xFC9870; break;
default: return CELL_VDEC_ERROR_ARG;
default: return { CELL_VDEC_ERROR_ARG, "Invalid DIVX profile %d", profile };
}
decoderVerLower = 0x30806;
break;
}
default: return CELL_VDEC_ERROR_ARG;
default: return { CELL_VDEC_ERROR_ARG, "Invalid codec type %d", type };
}
attr->decoderVerLower = decoderVerLower;
@@ -839,7 +920,7 @@ error_code cellVdecQueryAttr(vm::cptr<CellVdecType> type, vm::ptr<CellVdecAttr>
if (!type || !attr)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "type=%d, attr=%d", !!type, !!attr };
}
return vdecQueryAttr(type->codecType, type->profileLevel, 0, attr.get_ptr());
@@ -851,7 +932,7 @@ error_code cellVdecQueryAttrEx(vm::cptr<CellVdecTypeEx> type, vm::ptr<CellVdecAt
if (!type || !attr)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "type=%d, attr=%d", !!type, !!attr };
}
return vdecQueryAttr(type->codecType, type->profileLevel, type->codecSpecificInfo_addr, attr.get_ptr());
@@ -862,13 +943,14 @@ static error_code vdecOpen(ppu_thread& ppu, T type, U res, vm::cptr<CellVdecCb>
{
if (!type || !res || !cb || !handle || !cb->cbFunc)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "type=%d, res=%d, cb=%d, handle=%d, cbFunc=%d", !!type, !!res, !!cb, !!handle, cb && cb->cbFunc };
}
if (!res->memAddr || res->ppuThreadPriority + 0u >= 3072 || res->spuThreadPriority + 0u >= 256 || res->ppuThreadStackSize < 4096
|| type->codecType + 0u >= 0xe)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "memAddr=%d, ppuThreadPriority=%d, spuThreadPriority=%d, ppuThreadStackSize=%d, codecType=%d",
res->memAddr, res->ppuThreadPriority, res->spuThreadPriority, res->ppuThreadStackSize, type->codecType };
}
u32 spec_addr = 0;
@@ -878,11 +960,16 @@ static error_code vdecOpen(ppu_thread& ppu, T type, U res, vm::cptr<CellVdecCb>
spec_addr = type->codecSpecificInfo_addr;
}
if (CellVdecAttr attr{};
vdecQueryAttr(type->codecType, type->profileLevel, spec_addr, &attr) != CELL_OK ||
attr.memSize > res->memSize)
CellVdecAttr attr{};
const error_code err = vdecQueryAttr(type->codecType, type->profileLevel, spec_addr, &attr);
if (err != CELL_OK)
{
return CELL_VDEC_ERROR_ARG;
return err;
}
if (attr.memSize > res->memSize)
{
return { CELL_VDEC_ERROR_ARG, "attr.memSize=%d, res->memSize=%d", attr.memSize, res->memSize };
}
// Create decoder context
@@ -953,7 +1040,7 @@ error_code cellVdecClose(ppu_thread& ppu, u32 handle)
if (!vdec)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "vdec is nullptr" };
}
{
@@ -991,7 +1078,7 @@ error_code cellVdecClose(ppu_thread& ppu, u32 handle)
if (!idm::remove_verify<vdec_context>(handle, std::move(vdec)))
{
// Other thread removed it beforehead
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "remove_verify failed" };
}
return CELL_OK;
@@ -1007,7 +1094,7 @@ error_code cellVdecStartSeq(ppu_thread& ppu, u32 handle)
if (!vdec)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "vdec is nullptr" };
}
sequence_state old_state{};
@@ -1059,7 +1146,7 @@ error_code cellVdecEndSeq(ppu_thread& ppu, u32 handle)
if (!vdec)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "vdec is nullptr" };
}
{
@@ -1109,8 +1196,7 @@ error_code cellVdecDecodeAu(ppu_thread& ppu, u32 handle, CellVdecDecodeMode mode
return { CELL_VDEC_ERROR_ARG, "mode=%d", +mode };
}
// TODO: what does the 3 stand for ?
if ((mode == (CELL_VDEC_DEC_MODE_B_SKIP | CELL_VDEC_DEC_MODE_PB_SKIP) && vdec->type != 3) ||
if ((mode == (CELL_VDEC_DEC_MODE_B_SKIP | CELL_VDEC_DEC_MODE_PB_SKIP) && vdec->type != CELL_VDEC_CODEC_TYPE_VC1) ||
(mode == CELL_VDEC_DEC_MODE_PB_SKIP && vdec->type != CELL_VDEC_CODEC_TYPE_AVC))
{
return { CELL_VDEC_ERROR_ARG, "mode=%d, type=%d", +mode, vdec->type };
@@ -1157,8 +1243,7 @@ error_code cellVdecDecodeAuEx2(ppu_thread& ppu, u32 handle, CellVdecDecodeMode m
return { CELL_VDEC_ERROR_ARG, "mode=%d", +mode };
}
// TODO: what does the 3 stand for ?
if ((mode == (CELL_VDEC_DEC_MODE_B_SKIP | CELL_VDEC_DEC_MODE_PB_SKIP) && vdec->type != 3) ||
if ((mode == (CELL_VDEC_DEC_MODE_B_SKIP | CELL_VDEC_DEC_MODE_PB_SKIP) && vdec->type != CELL_VDEC_CODEC_TYPE_VC1) ||
(mode == CELL_VDEC_DEC_MODE_PB_SKIP && vdec->type != CELL_VDEC_CODEC_TYPE_AVC))
{
return { CELL_VDEC_ERROR_ARG, "mode=%d, type=%d", +mode, vdec->type };
@@ -1196,7 +1281,7 @@ error_code cellVdecGetPictureExt(ppu_thread& ppu, u32 handle, vm::cptr<CellVdecP
if (!vdec || !format)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "vdec=%d, format=%d", !!vdec, !!format };
}
{
@@ -1210,12 +1295,12 @@ error_code cellVdecGetPictureExt(ppu_thread& ppu, u32 handle, vm::cptr<CellVdecP
if (format->formatType > 4 || (format->formatType <= CELL_VDEC_PICFMT_RGBA32_ILV && format->colorMatrixType > CELL_VDEC_COLOR_MATRIX_TYPE_BT709))
{
return CELL_VDEC_ERROR_ARG;
return {CELL_VDEC_ERROR_ARG, "formatType=%d, colorMatrixType=%d", +format->formatType, +format->colorMatrixType};
}
if (arg4 && arg4 != 8 && arg4 != 0xc)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "arg4=0x%x", arg4 };
}
if (arg4 || format->unk0 || format->unk1)
@@ -1335,7 +1420,7 @@ error_code cellVdecGetPicture(ppu_thread& ppu, u32 handle, vm::cptr<CellVdecPicF
if (!format)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "format is nullptr" };
}
vm::var<CellVdecPicFormat2> format2;
@@ -1358,7 +1443,7 @@ error_code cellVdecGetPicItem(ppu_thread& ppu, u32 handle, vm::pptr<CellVdecPicI
if (!vdec || !picItem)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "vdec=%d, picItem=%d", !!vdec, !!picItem };
}
u64 sequence_id{};
@@ -1377,7 +1462,12 @@ error_code cellVdecGetPicItem(ppu_thread& ppu, u32 handle, vm::pptr<CellVdecPicI
struct all_info_t
{
CellVdecPicItem picItem;
std::aligned_union_t<0, CellVdecAvcInfo, CellVdecDivxInfo, CellVdecMpeg2Info> picInfo;
union
{
CellVdecAvcInfo avcInfo;
CellVdecDivxInfo divxInfo;
CellVdecMpeg2Info mpeg2Info;
} picInfo;
};
AVFrame* frame{};
@@ -1510,7 +1600,8 @@ error_code cellVdecGetPicItem(ppu_thread& ppu, u32 handle, vm::pptr<CellVdecPicI
avc->reserved[0] = 0;
avc->reserved[1] = 0;
}
else if (vdec->type == CELL_VDEC_CODEC_TYPE_DIVX)
// TODO: handle MPEG4 properly
else if (vdec->type == CELL_VDEC_CODEC_TYPE_MPEG4 || vdec->type == CELL_VDEC_CODEC_TYPE_DIVX)
{
const vm::ptr<CellVdecDivxInfo> dvx = picinfo_addr;
@@ -1601,7 +1692,7 @@ error_code cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frameRateCode)
// 0x80 seems like a common prefix
if (!vdec || (frameRateCode & 0xf8) != 0x80)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "vdec=%d, frameRateCode=0x%x", !!vdec, +frameRateCode };
}
std::lock_guard lock{vdec->mutex};
@@ -1625,7 +1716,7 @@ error_code cellVdecOpenExt(ppu_thread& ppu, vm::cptr<CellVdecType> type, vm::cpt
if (!res)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "res is nullptr" };
}
vm::var<CellVdecResource> tmp = vm::make_var<CellVdecResource>({});
@@ -1678,7 +1769,7 @@ error_code cellVdecSetPts(u32 handle, vm::ptr<void> unk)
if (!vdec || !unk)
{
return CELL_VDEC_ERROR_ARG;
return { CELL_VDEC_ERROR_ARG, "vdec=%d, unk=%d", !!vdec, !!unk };
}
std::lock_guard lock{vdec->mutex};
+26 -3
View File
@@ -14,9 +14,15 @@ enum CellVdecError : u32
enum CellVdecCodecType : s32
{
CELL_VDEC_CODEC_TYPE_MPEG2 = 0,
CELL_VDEC_CODEC_TYPE_AVC = 1,
CELL_VDEC_CODEC_TYPE_DIVX = 5,
CELL_VDEC_CODEC_TYPE_MPEG2 = 0,
CELL_VDEC_CODEC_TYPE_AVC = 1,
CELL_VDEC_CODEC_TYPE_MPEG4 = 2,
CELL_VDEC_CODEC_TYPE_VC1 = 3,
CELL_VDEC_CODEC_TYPE_DIVX = 5,
CELL_VDEC_CODEC_TYPE_JVT = 7,
CELL_VDEC_CODEC_TYPE_DIVX3_11 = 9,
CELL_VDEC_CODEC_TYPE_MVC = 11,
CELL_VDEC_CODEC_TYPE_MVC2 = 13, // seems the same as CELL_VDEC_CODEC_TYPE_MVC?
CELL_VDEC_CODEC_TYPE_MAX
};
@@ -672,3 +678,20 @@ struct CellVdecMpeg2Info
u8 ccData[2][128];
be_t<u64> reserved[2];
};
enum MPEG4_level
{
CELL_VDEC_MPEG4_SP_L1,
CELL_VDEC_MPEG4_SP_L2,
CELL_VDEC_MPEG4_SP_L3,
CELL_VDEC_MPEG4_SP_D1_NTSC,
CELL_VDEC_MPEG4_SP_VGA,
CELL_VDEC_MPEG4_SP_D1_PAL,
};
struct CellVdecMpeg4SpecificInfo
{
be_t<u32> thisSize;
be_t<u16> maxDecodedFrameWidth;
be_t<u16> maxDecodedFrameHeight;
};
+75 -18
View File
@@ -745,7 +745,7 @@ error_code sceNpDrmIsAvailable(ppu_thread& ppu, vm::cptr<u8> k_licensee_addr, vm
lv2_obj::sleep(ppu);
const auto ret = npDrmIsAvailable(k_licensee_addr, drm_path);
lv2_sleep(25'000, &ppu);
lv2_sleep(5'000, &ppu);
return ret;
}
@@ -871,7 +871,7 @@ error_code sceNpDrmGetTimelimit(vm::cptr<char> path, vm::ptr<u64> time_remain)
}
// Convert time to milliseconds
s64 msec = *sec * 1000ll + *nsec / 1000ll;
s64 msec = *sec * 1000ll + *nsec / 1'000'000ll;
// Return the remaining time in microseconds
if (npd.activate_time != 0 && msec < npd.activate_time)
@@ -1118,10 +1118,35 @@ error_code sceNpBasicSetPresenceDetails2(vm::cptr<SceNpBasicPresenceDetails2> pr
return CELL_OK;
}
error_code sceNpBasicSendMessage(vm::cptr<SceNpId> to, vm::cptr<void> data, u32 size)
{
sceNp.warning("sceNpBasicSendMessage(to=*0x%x, data=*0x%x, size=%d)", to, data, size);
u64 sys_time_get_system_time();
error_code acquire_time_slot(u64* time_array, usz array_size, u64 slot_duration)
{
static shared_mutex mutex;
std::lock_guard lock(mutex);
const u64 current_time = sys_time_get_system_time();
for (usz index = 0; index < array_size; index++)
{
if (time_array[index] == 0)
{
time_array[index] = current_time;
return CELL_OK;
}
if (current_time > (time_array[index] + slot_duration))
{
time_array[index] = current_time;
return CELL_OK;
}
}
return SCE_NP_BASIC_ERROR_BUSY;
}
error_code _sceNpBasicSendMessage(vm::cptr<SceNpId> to, vm::cptr<void> data, u32 size, bool rate_limited)
{
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
if (!nph.is_NP_init)
@@ -1144,6 +1169,23 @@ error_code sceNpBasicSendMessage(vm::cptr<SceNpId> to, vm::cptr<void> data, u32
return SCE_NP_BASIC_ERROR_EXCEEDS_MAX;
}
if (rate_limited)
{
struct sceNpBasicSendMessage_time_slots
{
sceNpBasicSendMessage_time_slots() = default;
sceNpBasicSendMessage_time_slots(sceNpBasicSendMessage_time_slots&&) = delete;
std::array<u64, 20> data{};
};
auto& time_slots = g_fxo->get<sceNpBasicSendMessage_time_slots>();
if (auto error = acquire_time_slot(time_slots.data.data(), time_slots.data.size(), 60000000); error != CELL_OK)
{
return error;
}
}
if (nph.get_psn_status() != SCE_NP_MANAGER_STATUS_ONLINE)
{
return not_an_error(SCE_NP_BASIC_ERROR_NOT_CONNECTED);
@@ -1157,13 +1199,26 @@ error_code sceNpBasicSendMessage(vm::cptr<SceNpId> to, vm::cptr<void> data, u32
.msgFeatures = {},
.data = std::vector<u8>(static_cast<const u8*>(data.get_ptr()), static_cast<const u8*>(data.get_ptr()) + size)};
std::set<std::string> npids;
npids.insert(std::string(to->handle.data));
npids.insert(np::npid_to_string(*to));
nph.send_message(msg_data, npids);
return CELL_OK;
}
error_code sceNpBasicSendMessage(vm::cptr<SceNpId> to, vm::cptr<void> data, u32 size)
{
sceNp.warning("sceNpBasicSendMessage(to=*0x%x, data=*0x%x, size=%d)", to, data, size);
return _sceNpBasicSendMessage(to, data, size, false);
}
// This function is sceNpBasicSendMessage + a rate limiter that will return SCE_NP_BASIC_ERROR_BUSY if it too many messages have been sent
error_code sceNpBasicLimited_0xEB42E2E6(vm::cptr<SceNpId> to, vm::cptr<void> data, u32 size)
{
sceNp.warning("sceNpBasicLimited_0xEB42E2E6(to=*0x%x, data=*0x%x, size=%d)", to, data, size);
return _sceNpBasicSendMessage(to, data, size, true);
}
error_code sceNpBasicSendMessageGui(ppu_thread& ppu, vm::cptr<SceNpBasicMessageDetails> msg, sys_memory_container_t containerId)
{
sceNp.warning("sceNpBasicSendMessageGui(msg=*0x%x, containerId=%d)", msg, containerId);
@@ -1173,7 +1228,7 @@ error_code sceNpBasicSendMessageGui(ppu_thread& ppu, vm::cptr<SceNpBasicMessageD
sceNp.notice("sceNpBasicSendMessageGui: msgId: %d, mainType: %d, subType: %d, msgFeatures: %d, count: %d, npids: *0x%x", msg->msgId, msg->mainType, msg->subType, msg->msgFeatures, msg->count, msg->npids);
for (u32 i = 0; i < msg->count && msg->npids; i++)
{
sceNp.trace("sceNpBasicSendMessageGui: NpId[%d] = %s", i, static_cast<char*>(&msg->npids[i].handle.data[0]));
sceNp.trace("sceNpBasicSendMessageGui: NpId[%d] = %s", i, np::npid_to_string(msg->npids[i]));
}
sceNp.notice("sceNpBasicSendMessageGui: subject: %s", msg->subject);
sceNp.notice("sceNpBasicSendMessageGui: body: %s", msg->body);
@@ -1343,7 +1398,7 @@ error_code sceNpBasicSendMessageGui(ppu_thread& ppu, vm::cptr<SceNpBasicMessageD
{
for (u32 i = 0; i < msg->count; i++)
{
npids.insert(std::string(msg->npids[i].handle.data));
npids.insert(np::npid_to_string(msg->npids[i]));
}
}
@@ -3433,7 +3488,7 @@ error_code sceNpLookupUserProfile(s32 transId, vm::cptr<SceNpId> npId, vm::ptr<S
error_code sceNpLookupUserProfileAsync(s32 transId, vm::cptr<SceNpId> npId, vm::ptr<SceNpUserInfo> userInfo, vm::ptr<SceNpAboutMe> aboutMe, vm::ptr<SceNpMyLanguages> languages,
vm::ptr<SceNpCountryCode> countryCode, vm::ptr<SceNpAvatarImage> avatarImage, s32 prio, vm::ptr<void> option)
{
sceNp.todo("sceNpLookupUserProfile(transId=%d, npId=*0x%x, userInfo=*0x%x, aboutMe=*0x%x, languages=*0x%x, countryCode=*0x%x, avatarImage=*0x%x, prio=%d, option=*0x%x)", transId, npId, userInfo,
sceNp.todo("sceNpLookupUserProfileAsync(transId=%d, npId=*0x%x, userInfo=*0x%x, aboutMe=*0x%x, languages=*0x%x, countryCode=*0x%x, avatarImage=*0x%x, prio=%d, option=*0x%x)", transId, npId, userInfo,
aboutMe, languages, countryCode, avatarImage, prio, option);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
@@ -4187,19 +4242,16 @@ error_code sceNpManagerGetTicket(vm::ptr<void> buffer, vm::ptr<u32> bufferSize)
}
const auto& ticket = nph.get_ticket();
*bufferSize = static_cast<u32>(ticket.size());
if (!buffer)
{
*bufferSize = static_cast<u32>(ticket.size());
return CELL_OK;
}
if (*bufferSize < ticket.size())
{
return SCE_NP_ERROR_INVALID_ARGUMENT;
}
memcpy(buffer.get_ptr(), ticket.data(), ticket.size());
const u32 size_read = std::min(::size32(ticket), static_cast<u32>(*bufferSize));
std::memcpy(buffer.get_ptr(), ticket.data(), size_read);
*bufferSize = size_read;
return CELL_OK;
}
@@ -5621,7 +5673,7 @@ error_code scenp_score_record_score(s32 transId, SceNpScoreBoardId boardId, SceN
else
{
data = &gameInfo->nativeData[0];
data_size = 64;
data_size = sizeof(gameInfo->nativeData);
}
nph.record_score(trans_ctx, boardId, score, scoreComment, data, data_size, tmpRank, async);
@@ -7089,7 +7141,7 @@ error_code sceNpUtilCanonicalizeNpIdForPsp(vm::ptr<SceNpId> npId)
error_code sceNpUtilCmpNpId(vm::ptr<SceNpId> id1, vm::ptr<SceNpId> id2)
{
sceNp.trace("sceNpUtilCmpNpId(id1=*0x%x(%s), id2=*0x%x(%s))", id1, id1 ? id1->handle.data : "", id2, id2 ? id2->handle.data : "");
sceNp.trace("sceNpUtilCmpNpId(id1=*0x%x(%s), id2=*0x%x(%s))", id1, id1 ? np::npid_to_string(*id1) : std::string(), id2, id2 ? np::npid_to_string(*id2) : std::string());
if (!id1 || !id2)
{
@@ -7289,6 +7341,11 @@ s32 _Z32_sce_np_sysutil_cxml_prepare_docPN16sysutil_cxmlutil11FixedMemoryERN4cxm
return CELL_OK;
}
DECLARE(ppu_module_manager::sceNpBasicLimited)
("sceNpBasicLimited", []() {
ppu_module_manager::register_static_function<&sceNpBasicLimited_0xEB42E2E6>("sceNpBasicLimited", ppu_select_name("sceNpBasicLimited", "sceNpBasicLimited_0xEB42E2E6"), BIND_FUNC_WITH_BLR(sceNpBasicLimited_0xEB42E2E6, "sceNpBasicLimited"), 0xEB42E2E6);
});
DECLARE(ppu_module_manager::sceNp)
("sceNp", []() {
REG_FUNC(sceNp, sceNpInit);
+16 -15
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];
};
@@ -1396,9 +1397,9 @@ struct SceNpBasicMessageDetails
// Presence details of an user
struct SceNpBasicPresenceDetails
{
s8 title[SCE_NP_BASIC_PRESENCE_TITLE_SIZE_MAX];
s8 status[SCE_NP_BASIC_PRESENCE_STATUS_SIZE_MAX];
s8 comment[SCE_NP_BASIC_PRESENCE_COMMENT_SIZE_MAX];
char title[SCE_NP_BASIC_PRESENCE_TITLE_SIZE_MAX];
char status[SCE_NP_BASIC_PRESENCE_STATUS_SIZE_MAX];
char comment[SCE_NP_BASIC_PRESENCE_COMMENT_SIZE_MAX];
u8 data[SCE_NP_BASIC_MAX_PRESENCE_SIZE];
be_t<u32> size;
be_t<s32> state;
@@ -1409,9 +1410,9 @@ struct SceNpBasicPresenceDetails2
{
be_t<u32> struct_size;
be_t<s32> state;
s8 title[SCE_NP_BASIC_PRESENCE_TITLE_SIZE_MAX];
s8 status[SCE_NP_BASIC_PRESENCE_EXTENDED_STATUS_SIZE_MAX];
s8 comment[SCE_NP_BASIC_PRESENCE_COMMENT_SIZE_MAX];
char title[SCE_NP_BASIC_PRESENCE_TITLE_SIZE_MAX];
char status[SCE_NP_BASIC_PRESENCE_EXTENDED_STATUS_SIZE_MAX];
char comment[SCE_NP_BASIC_PRESENCE_COMMENT_SIZE_MAX];
u8 data[SCE_NP_BASIC_MAX_PRESENCE_SIZE];
be_t<u32> size;
};
@@ -1419,9 +1420,9 @@ struct SceNpBasicPresenceDetails2
// Country/region code
struct SceNpCountryCode
{
s8 data[2];
s8 term;
s8 padding[1];
char data[2];
char term;
char padding[1];
};
// Date information
@@ -1450,8 +1451,8 @@ struct SceNpScoreGameInfo
// Ranking comment structure
struct SceNpScoreComment
{
s8 data[SCE_NP_SCORE_COMMENT_MAXLEN];
s8 term[1];
char data[SCE_NP_SCORE_COMMENT_MAXLEN];
char term[1];
};
// Ranking information structure
@@ -1523,15 +1524,15 @@ struct SceNpScoreNpIdPcId
// Basic clan information to be used in raking
struct SceNpScoreClanBasicInfo
{
s8 clanName[SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH + 1];
s8 clanTag[SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH + 1];
char clanName[SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH + 1];
char clanTag[SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH + 1];
u8 reserved[10];
};
// Clan member information handled in ranking
struct SceNpScoreClansMemberDescription
{
s8 description[SCE_NP_CLANS_CLAN_DESCRIPTION_MAX_LENGTH + 1];
char description[SCE_NP_CLANS_CLAN_DESCRIPTION_MAX_LENGTH + 1];
};
// Clan ranking information
+62 -12
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(
@@ -613,9 +616,9 @@ error_code sceNpMatching2CreateServerContext(
return CELL_OK;
}
error_code sceNpMatching2GetMemoryInfo(vm::ptr<SceNpMatching2MemoryInfo> memInfo) // TODO
error_code sceNpMatching2GetMemoryInfo(vm::ptr<SceNpMatching2MemoryInfo> memInfo)
{
sceNp2.todo("sceNpMatching2GetMemoryInfo(memInfo=*0x%x)", memInfo);
sceNp2.warning("sceNpMatching2GetMemoryInfo(memInfo=*0x%x)", memInfo);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
@@ -624,6 +627,14 @@ error_code sceNpMatching2GetMemoryInfo(vm::ptr<SceNpMatching2MemoryInfo> memInfo
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!memInfo)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
SceNpMatching2MemoryInfo mem_info = nph.get_memory_info();
*memInfo = mem_info;
return CELL_OK;
}
@@ -787,7 +798,7 @@ error_code sceNpMatching2JoinLobby(
error_code sceNpMatching2GetRoomMemberDataExternalList(SceNpMatching2ContextId ctxId, vm::cptr<SceNpMatching2GetRoomMemberDataExternalListRequest> reqParam,
vm::cptr<SceNpMatching2RequestOptParam> optParam, vm::ptr<SceNpMatching2RequestId> assignedReqId)
{
sceNp2.todo("sceNpMatching2GetRoomMemberDataExternalList(ctxId=%d, reqParam=*0x%x, optParam=*0x%x, assignedReqId=*0x%x)", ctxId, reqParam, optParam, assignedReqId);
sceNp2.warning("sceNpMatching2GetRoomMemberDataExternalList(ctxId=%d, reqParam=*0x%x, optParam=*0x%x, assignedReqId=*0x%x)", ctxId, reqParam, optParam, assignedReqId);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
if (auto res = generic_match2_error_check(nph, ctxId, reqParam); res != CELL_OK)
@@ -795,6 +806,13 @@ error_code sceNpMatching2GetRoomMemberDataExternalList(SceNpMatching2ContextId c
return res;
}
const u32 request_id = nph.get_room_member_data_external_list(ctxId, optParam, reqParam.get_ptr());
if (assignedReqId)
{
*assignedReqId = request_id;
}
return CELL_OK;
}
@@ -819,10 +837,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(
@@ -1056,7 +1071,7 @@ error_code sceNpMatching2GetRoomMemberDataInternalLocal(SceNpMatching2ContextId
error_code sceNpMatching2GetCbQueueInfo(SceNpMatching2ContextId ctxId, vm::ptr<SceNpMatching2CbQueueInfo> queueInfo)
{
sceNp2.todo("sceNpMatching2GetCbQueueInfo(ctxId=%d, queueInfo=*0x%x)", ctxId, queueInfo);
sceNp2.warning("sceNpMatching2GetCbQueueInfo(ctxId=%d, queueInfo=*0x%x)", ctxId, queueInfo);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
@@ -1065,6 +1080,17 @@ error_code sceNpMatching2GetCbQueueInfo(SceNpMatching2ContextId ctxId, vm::ptr<S
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!queueInfo)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*queueInfo = {};
// TODO: check the values returned on real hardware
queueInfo->requestCbQueueLen = 255;
queueInfo->sessionEventCbQueueLen = 255;
queueInfo->sessionMsgCbQueueLen = 255;
return CELL_OK;
}
@@ -1109,7 +1135,7 @@ error_code sceNpMatching2ContextStartAsync(SceNpMatching2ContextId ctxId, u32 ti
{
sysutil_register_cb([=, context_callback = ctx->context_callback, context_callback_param = ctx->context_callback_param](ppu_thread& cb_ppu) -> s32
{
context_callback(cb_ppu, ctxId, SCE_NP_MATCHING2_CONTEXT_EVENT_Start, SCE_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION, 0, ctx->context_callback_param);
context_callback(cb_ppu, ctxId, SCE_NP_MATCHING2_CONTEXT_EVENT_Start, SCE_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION, 0, context_callback_param);
return 0;
});
}
@@ -1326,7 +1352,7 @@ error_code sceNpMatching2CreateContext(
error_code sceNpMatching2GetSignalingOptParamLocal(SceNpMatching2ContextId ctxId, SceNpMatching2RoomId roomId, vm::ptr<SceNpMatching2SignalingOptParam> signalingOptParam)
{
sceNp2.todo("sceNpMatching2GetSignalingOptParamLocal(ctxId=%d, roomId=%d, signalingOptParam=*0x%x)", ctxId, roomId, signalingOptParam);
sceNp2.warning("sceNpMatching2GetSignalingOptParamLocal(ctxId=%d, roomId=%d, signalingOptParam=*0x%x)", ctxId, roomId, signalingOptParam);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
@@ -1335,6 +1361,30 @@ error_code sceNpMatching2GetSignalingOptParamLocal(SceNpMatching2ContextId ctxId
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!ctxId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
}
if (!roomId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ROOM_ID;
}
if (!check_match2_context(ctxId))
{
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND;
}
const auto [error, signaling_opt_param] = nph.local_get_signaling_opt_param(roomId);
if (error)
{
return error;
}
*signalingOptParam = *signaling_opt_param;
return CELL_OK;
}
@@ -1710,7 +1760,7 @@ error_code sceNpMatching2ContextStop(SceNpMatching2ContextId ctxId)
const auto ctx = get_match2_context(ctxId);
if (!ctx)
return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND;
if (!ctx->started.compare_and_swap_test(1, 0))
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_STARTED;
+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;
};
+10 -4
View File
@@ -1026,14 +1026,14 @@ error_code sceNpTrophyUnlockTrophy(ppu_thread& ppu, u32 context, u32 handle, s32
auto& trophy_manager = g_fxo->get<sce_np_trophy_manager>();
reader_lock lock(trophy_manager.mtx);
std::scoped_lock lock(trophy_manager.mtx);
if (!trophy_manager.is_initialized)
{
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
}
const auto [ctxt, error] = trophy_manager.get_context_ex(context, handle);
const auto [ctxt, error] = trophy_manager.get_context_ex(context, handle, true);
if (error)
{
@@ -1184,9 +1184,9 @@ error_code sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, vm::ptr<SceN
for (u32 id = 0; id < count_; id++)
{
if (tropusr->GetTrophyUnlockState(id))
flags->flag_bits[id / 32] |= 1 << (id % 32);
flags->flag_bits[id / 32] |= 1u << (id % 32);
else
flags->flag_bits[id / 32] &= ~(1 << (id % 32));
flags->flag_bits[id / 32] &= ~(1u << (id % 32));
}
return CELL_OK;
@@ -1529,6 +1529,11 @@ error_code sceNpTrophyGetTrophyIcon(u32 context, u32 handle, s32 trophyId, vm::p
return CELL_OK;
}
error_code sceNpTrophyNetworkSync()
{
UNIMPLEMENTED_FUNC(sceNpTrophy);
return CELL_OK;
}
DECLARE(ppu_module_manager::sceNpTrophy)("sceNpTrophy", []()
{
@@ -1553,4 +1558,5 @@ DECLARE(ppu_module_manager::sceNpTrophy)("sceNpTrophy", []()
REG_FUNC(sceNpTrophy, sceNpTrophyGetTrophyDetails);
REG_FUNC(sceNpTrophy, sceNpTrophyGetTrophyInfo);
REG_FUNC(sceNpTrophy, sceNpTrophyGetGameIcon);
REG_FUNC(sceNpTrophy, sceNpTrophyNetworkSync);
});
+1 -1
View File
@@ -65,7 +65,7 @@ struct sce_np_util_manager
error_code sceNpUtilBandwidthTestInitStart([[maybe_unused]] ppu_thread& ppu, u32 prio, u32 stack)
{
sceNpUtil.todo("sceNpUtilBandwidthTestInitStart(prio=%d, stack=%d)", prio, stack);
sceNpUtil.warning("sceNpUtilBandwidthTestInitStart(prio=%d, stack=%d)", prio, stack);
auto& util_manager = g_fxo->get<sce_np_util_manager>();
std::lock_guard lock(util_manager.mtx);
+1 -1
View File
@@ -330,7 +330,7 @@ void comment_constant(std::string& last_opcode, u64 value, bool print_float = fa
// Comment constant formation
fmt::append(last_opcode, " #0x%xh", value);
if (print_float && ((value >> 31) <= 1u || (value >> 31) == 0x1'ffff'ffffu))
if (print_float && ((value >> 31) <= 1u || (value >> 31) == 0x1'ffff'ffffu) && (value > 0x3fffff && (value << 32 >> 32) < 0xffc00000))
{
const f32 float_val = std::bit_cast<f32>(static_cast<u32>(value));

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