So I could play Deadstorm Pirates 2 players with DolphinBar + 2 Wiimotes
99% of this is AI assisted development.
I reviewed the code and the functionality.
- There is this logic where you might find it weird.
It maps first available player with GunCon3 to slot 0.
So if you have P4:G and P6:G, you'll have P4:0, P6:1
This is intentional because I couldn't figure out why P2 is reserved and
I needed to map to P1 and P2.
- Has a GUI so you can see your Wiimotes and remap them.
- Enabling PS Move cursor overlay will also show GunCon3 IRs on the
screen.
### NOTE
On Linux you'll need udev rules (same as Dolphin) for this to work.
Put [THIS
FILE](https://github.com/dolphin-emu/dolphin/blob/master/Data/51-usb-device.rules)
in `/etc/udev/rules.d/`
vrefp, vrsqrtefp, vexptefp and vlogefp return the Cell's estimates instead
of exact results, matched bit for bit against a real PS3 with VSCR[NJ] set
and clear.
This allows RPCS3 to communicate with Dualshock 3,4 and DualSense
controller out of the box on Linux distributions and FreeBSD, without
the need for manual actions.
The single raw string literal exceeded the MSVC string literal size limit
(error C2026: string too big, trailing characters truncated).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- Real hardware behavior for constants table access is complicated.
1. If you try to encode access of c[N] where N > 467 you read back 0 in the shader
2. If you try to bypass the limitation using ARL then the index wraps around 512.
3. Using the ARL bypass between 468 and 512 returns garbage.
Crafted title IDs could escape serial-derived directories and redirect
recursive cache cleanup outside RPCS3's cache root. Reject structural
path components, escape identifiers used as host names, and make
cleanup matching literal and exact.
Analysis and fixes made by Opus 5.5.
## Bug
`cellSearchGetMusicSelectionContext` only put the selected (or a random)
track into the context, even when the search contained many tracks.
Games that pick custom music through cellSearch got a one-track
playlist, so with repeat ALL the same song played on loop forever.
## Fix
- For a search of single tracks the playlist now contains every track of
the search, and `first_track` / `current_track` point to the selected
one (random when shuffled, otherwise the first).
- `music_selection_context::find_content_id` starts from the selected
track instead of the first entry of the playlist.
- `audio_decoder` keeps the selected track first when shuffling and only
shuffles the rest.
Tested with NHL 14.
Fixes#14738
Part of #18779, #11596
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
RPCN forwards MessageDetails from other users. The protobuf uint16
wrappers can carry 32-bit values, and narrowing them on the recipient
aborts RPCS3.
Validate both values before casting so malformed messages are
discarded.
RPCN room peers control message payloads and destination lists. Values
above the Matching2 limits overflow the recipient's fixed event buffer
and terminate the NP handler.
Reject malformed room message notifications before allocating event
data.
Signaling peers control the timestamps used for RTT calculation. A
future timestamp wraps the unsigned delta, and the fatal checked cast
terminates the signaling thread.
Reject future and oversized RTT values before updating peer state.
The resampler buffers part of its input whenever the file's sample rate differs from the 48 kHz output,
because the output buffer was only sized for the frame's own samples. These samples piled up and were
never flushed, so a 44.1 kHz track came out 8.125% short (5-20 s cut from the end of every song).
The decoder itself was never drained either.
- Size the output for the pending resampler samples too and only append what swr_convert actually wrote.
- Flush the decoder and the resampler once the last packet has been read.
- Reserve the whole track up front, reuse the resampler output buffer and byteswap in place before
appending, instead of growing the track buffer and allocating a buffer for every frame.
Fixes#18930 (custom music cut in Gran Turismo 5).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Qt's QTabWidget only intercepts Ctrl+Tab/Ctrl+Shift+Tab while the tab
widget itself has keyboard focus. The dialog's own currentChanged
handler moves focus to the Close button after every tab switch, and
clicking into a tab's content moves focus to a child widget, so the
shortcut stopped working after the first switch.
Add explicit window-scoped shortcuts that cycle the tab index
directly, so Ctrl+Tab/Ctrl+Shift+Tab keep working regardless of which
widget currently has focus.
Fixes#19425
Co-Authored-By: Claude Sonnet 5 <[email protected]>
This is the only known function that passes arguments in vector
registers.
Although we had an implementation for it, it was never used before.
Hopefully it works.
Attempting to fix "invalid" argument passed to cellGemSetYaw due to
wrong register decoding.
Fixes crashes in Armored Core Verdict and Armored Core V.
RPCS3 HDD reads were finishing much faster than on PS3, so emulating
their timing gives the audio worker time to free old sound banks before
the new ones exhaust the heap.
### Remove
- gui: Remove Debug "Approximate PPU Vector NaN Handling"
- gui: Remove I/O "Load SDL GameController Mappings"
- gui: Remove Advanced "VBlank NTSC Fixup", enable by default
- gui: Remove Debug "Accurate DFMA"
### Move
- gui: Move Advanced "Enable SPU Events Busy Loop" to Debug
- gui: Move Advanced "Set DAZ and FTZ" to Debug
- gui: Move Audio Device to the left column in Audio
### Group
- gui: Add "Savestates" section in Advanced
### Order
- gui: Alphabetically order the Advanced Tab
- gui: Alphabetically order the I/O tab
### Visibility
- gui: Hide formats list when Audio Format is not Manual
- gui: Hide 3D settings if GPU "Enable 3D Support" is disabled
- gui: Hide RCAS if GPU "Output Scaling" is not FSR1
Fixes#18381
### Bug:
`gs_frame::show()` went through `QWindow::show()`. On desktop platforms
`QPlatformIntegration::defaultWindowState()` is `Qt::WindowNoState`, so
that always routes through `showNormal()`, which pushes
`Qt::WindowNoState` to the native window before the startup visibility
is applied. On a window that is already fullscreen this is a real "leave
fullscreen" request immediately followed by an "enter fullscreen" one,
and a window manager is free to resolve that pair as windowed.
`QXcbWindow::setWindowState()` returns early when the requested state
matches the current one, so the first call of a session is a no-op, but
a later one on a fullscreen window is not, and
`QWaylandWindow::setWindowState()` forwards unconditionally.
Only the OpenGL frame runs into this. `gl_gs_frame` shows itself from
its constructor so that wayland-egl has a mapped surface before the
context is created (c7b2a21f), so by the time `gs_frame::flip()` shows
the frame again on the first flip, the window is already fullscreen.
Vulkan and Null only ever show the frame on that first flip, which is
why they are fine. It also explains why this never reproduced on
Windows: `ShowWindow()` applies both states synchronously and the second
one wins.
### TO BE TESTED ON LINUX
Not runtime tested yet: it needs a run on X11 and on Wayland with an
OpenGL game and "Start games in fullscreen mode" enabled.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Display an error message when booting a game from an encrypted ISO file
/ BD Drive in case:
- no decryption key file found
- wrong decryption key file provided (e.g. with key of another game)
Further, code improved to skip a key file for an ISO file recognized as
decrypted (avoid to decrypt (to corrupt) the ISO file with a wrongly
provided key).
ZPASS_COUNT is an observable side-effect of Z-buffer access, despite Z-TEST and Z-WRITE being disabled. Technically, this is a pure Z-READ operation.
Co-authored-by: kd-11 <[email protected]>
save_patches always emitted the address element as fmt::format("0x%.8x"),
but for move_file and hide_file that element is a VFS path: load() keeps the
text in original_offset and skips u32 validation for those two types.
Round-tripping such a patch through save_patches replaced the source path
with 0x00000000.
The entry stays syntactically valid and keeps loading, so the patch is still
listed and can still be toggled in the Patch Manager while silently matching
no file. Re-downloading does not repair it either, since append_patches
discards an incoming patch whose Patch Version is not strictly greater.
Gate the emit on patch_type_uses_hex_offset, the predicate that already
existed for this and was used only on the load side. The numeric branch
keeps using offset rather than original_offset on purpose: an address
modifier is folded into offset at load time and the flat form emitted here
has nowhere to put it.
Co-Authored-By: Claude Opus 5 <[email protected]>
save_patches opened the target with fs::rewrite (write + create + trunc),
then discarded the result of file.write() and returned true unconditionally.
A write that fails part way leaves a truncated file, load() rejects the
whole file on a parse error, and import_patches refuses to write when
load() fails, so every later import returns -1 with no in-app recovery.
75e66ab5e made the patch config and the pad config atomic but missed this
function; save_config, 70 lines up in the same file, already writes through
fs::pending_file and checks the result. Do the same here.
Co-Authored-By: Claude Opus 5 <[email protected]>
Adreno waves are 64 lanes, and a workgroup narrower than the wave does not pack
together with its neighbours -- it occupies a whole wave and masks the surplus
lanes off. At 32 that idled half of every wave on every dispatch, and these
kernels run on every texture upload of a kilobyte or more, plus every deswizzle
and detile.
Nothing argues the other way here. The kernels carry no shared memory and no
barriers, so group size is a scheduling hint with no LDS or synchronisation
cost to trade against.
- PKG entry paths are converted to std::filesystem::path through explicit UTF-8 (utf8_to_wchar / wchar_to_utf8) instead of the narrow constructor, which read the bytes in the host ANSI code page and terminated the process on any it could not map (Shift-JIS file names such as s10c3_R126_<90 AC 91 CC>.mdat in Darkside Chronicles).
- The canonical path is converted back with UTF-8 as well, so a dev_hdd0 path with non-ASCII characters yields a valid key and passes the containment check (upstream rejected every entry as "escapes installation directory").
- The installation directory is canonicalized without its closing / separators, like every entry: on a file system that cannot resolve it, the lexical form no longer keeps an empty last element that no entry can match (network drives).
- Absolute / . / .. checks run on the raw name bytes via a shared leaves_directory() helper; the .. case is now an installation failure instead of an emergency exit.
- The installation directory name read from the package is validated with the same helper and escaped.
- weakly_canonical is computed once per directory and reused for files not yet on disk (existing paths and folders are still resolved whole): identical keys and verdicts, ~25x faster enumeration (6000 files: 1.7 s → 63 ms).
- Supersedes *19463 (trailing separator after the lexical fallback)
- Supersedes *19492
- Minor: map key moved instead of copied.
The `InstCombine` is a very important pass for optimizing common expressions and simplifying logic. It could help produce sustainably better code at little cost.
This change really is the last straw I've had with Homebrew, I simply cannot trust that they won't do something similar to Apple Silicon in the future. Inevitably much of the Intel CI's downloaded deps will get built from source due to this which would cause build times to skyrocket, were we to keep using Homebrew.
Infamous 2 displays infamous 1 trophy data in overlay if trophies are
present on local user account. If infamous 1 trophies are not present,
the overlay does not display any trophy data.
This code addition sets the trophy name list once (if empty) and
prevents future trophy contexts from changing it. The overlay now
displays the proper trophy data for infamous 2.
The emulated G27 was always attached while enabled, so games kept
reading a phantom wheel (centered steering after the previous commit,
formerly hard-left) and ignored pad steering input. Attach the emulated
device only while the mapped steering device is connected: games now
see the wheel plug in and out exactly like on real hardware, and pad
play works without disabling the option and restarting the game.
Also guard the personality reconnect against the device having been
detached between the game's mode-change request and the housekeeping
tick.
Co-Authored-By: Claude Fable 5 <[email protected]>
The emulated G27 fell back to MIN for every axis whose mapped SDL device
was not connected. For the steering axis MIN encodes full-left, so enabling
the emulated wheel without the physical device attached (or while playing
with a regular gamepad) made games receive permanent hard-left steering.
Fall back to the axis' neutral position instead: center for steering,
released for pedals (unchanged behavior for pedals).
Co-Authored-By: Claude Fable 5 <[email protected]>
- u16 path needs AVX-512-ICL because vpcompressw isn't included in skylake-x level AVX-512
- u32 path is untested as I couldn't find any games that hit it
PKG file_count was used for vector allocation before validating
that the encrypted package data contained the entry table. Limit the
count and require the entry table to fit in the declared data region
before allocating.
PKG entry names could contain traversal components and escape the
installation directory. Reject absolute and special components, then
require the resolved target to remain below the installation root
before creating or writing files.
This patch adds a optimization to fold 8-bit addition/subtraction idioms back into a native 8-bit add. Also adds fast paths to the `SHUFB` and `ABSDB` instructions for when a operand came from a compare.
- Regardless of the O/Z tag on the format, DST_ALPHA is always 1
- I don't know why it's that way, it shouldn't be but we're probably just looking at a hardware bug
- No need to rerun the blend config and depth state evaluation every time the shader changes.
- There's probably more that can be done, but I'll check later.
This is the default behavior of the home_menu_page, which was only
intended for use during gameplay originally.
We also expect the game grid to have a parent.
Follow up of #18648 and #18345 adding BD Drive support to the remaining supported OSes.
As it happens on Windows, both physical BD Drive and virtual drive (e.g. mounted `.iso` file) are supported.
Code for mac OS and FreeBSD provided by AI.
- key files need to be provided under `<rpcs3>/data/redump` folder (currently it needs to be manually created). This folder is also already the fallback folder for any encrypted ISO file
Fixes#18345
Previously in the Big Picture Mode when selecting a game to look at its
details, the ICON1.PAM video would start to play but there would be no
audio playing if the .PAM file had it. This PR fixes that.
Note: the change in qt_video_source.cpp is needed because it seemed like
it didn't use it's own parameter. Without that, the audio would not fade
out even after you left the game details.
Follow up of #19292 to improve Game Collections in context menu:
- Add and remove the game to/from multiple collections (e.g. "3rd person" and "Fantasy")
- Create a collection and add the game to it
- Remove the game from current collection if it is not the "All games"
Adds additional paths for the special index constants calculation where we know certain constants can't occur due to LLVM's known bits analysis. Also, adds a path for when we know that only the constants will be used.
This was based on patterns found in LBP2 and RE3.
Make optional VSH CPU compilation on `File ➔ All Titles ➔ Create LLVM
Caches` dialog. By default it is now excluded due to VSH caches are
fully covered by the dedicated submenu `File ➔ Firmware`.
Use sizeof(u128) instead of 16.
Clear padding after archive_read_block.
Use aligned_div instead of manually aligning blocks.
Fix local_buf size when using raw ptr of the original buffer.
Due to a bug where `SHUFB`'s GFNI constant generation path expects to be combine using a select instead of a OR, it was causing issues with on non-AVX512 CPUs so support was reverted (see #19217). That can still happen on AVX512 CPUs when the shuffle is single source. This patch fixes it and re-lower the target requirements back to just GFNI by avoiding the OR well on the GFNI path. I also renamed a variable and added a comment to better clarify its behavior.
- Instead of filling over 10 arguments and having the ctor silently drop half of them, we create proper wrappers to construct objects for a singular purpose.
Add on Game List title a brief recap of total number of entries in the
list and total number of Disc, HDD and all the other remaining types of
content.
- Verified with hardware tests. RSX does not support proper loops.
- The LOOP/REP instruction simply codes a "REPEAT n" instruction for a block of code.
- There is no accumulator register. The compiler emits a preamble inside the loop block to simulate the running counter.
- Oddly enough, the original start and step values are stored in the instruction but are unused. Maybe useful for debugging real hardware?
The constant generation AVX512-ICL path only requires the feature GFNI, which exists on non-AVX512 CPUs. This was a hold-over from when the shuffle step was merged together. (The proceeding unsigned minimum is from SSE2)
Add parameter checks to sys_net_infoctl
Fix P2P getpeername() fatal
Fix possible deadlock in tcp_timeout_monitor
Remove vport assert from poll
Add upgrade path for new P2PS state in savestates
Fix P2PS close_stream() not waking threads
Fix possible deadlock in P2PS connect()
Ensure RST is sent on unhandled packets
Add thread lock for p2p sockets(used for poll/select to avoid event gap)
Fix poll/select returning EINTR if no sockets were polled
Implement sys_net_infoctl cmd 6(sys_net_get_sockinfo)
Cleanup sys_net_infoctl cmd 9 code
Add SYS_NET_STATE_* values to header
Rewrite P2P and P2PS poll/select implementations
Add extra P2PS state for disconnected and report it as readable with 0 bytes(EOF)
Fix P2PS sockets connecting without being bound first missing hashmap insert
Add missing error check in sceNpSignalingActivateConnection
- Require 3 log files
- Remove quick summary
- Remove other details
- Add dropdown to confirm user has uploaded the required log files
- Specify visual capture as RSX .rrc or RenderDoc .rdc
The AUDIT in .inside() triggers whenever m_cached_buffer_range was not
assigned yet.
Added another AUDIT to ensure that m_cached_buffer_range is valid after
assignment.
cellCameraOpenEx already dealloacted pbuf, but this was not updated by the internal structure and caused cellCameraEnd to call vm::dealloc on the same addresses again. This can lead to cellCameraEnd to deallocate memory that is not related to cellCamera at all!
* Register wait flat for sys_overlay_load_module and sys_overlay_load_module_by_fd
* Register wait flag for cellOskDialogLoadAsync
* Register wait flag for cellCameraOpenEx
Shortens the dependency chain in the `FI` instruction by calculating the exponent adjustment and clamping separately from the mantissa. They can be safely combine as `+-FLT_MAX` overwrites the mantissa as all its bits are set.
Also fixes an AVX512 SNaN clamping issue and poor code gen on pre AVX2 targets.
Adds filtering options to manage the game list
The existing option `hide` does not feel sufficient because there are
different reasons a user may want to hide a game
Adds option Broken
Let's the user define games as broken.
Adds an option for completed
Let's the user define games as completed.
This uses copy pasta of existing code.
AI was not used. I used github search, control + F, git blame, and
intellisense.
I understood build errors, made necessary edits as needed, compiled and
tested the code.
The options show_hidden, show_broken, show_completed do not show up in
the current_settings.ini file until you toggle the option under view.
This happens on Master as well with the option show_hidden. The settings
show up in the ini file in the order that they are created this is not a
bug it is working by design.
Move `m_list_dirty = true` inside the successful insert path in `add_game_invite`, so the friends invite overlay only refreshes when a new invite is actually added instead of on duplicate/no-op updates.
Track RPCN invite messages in a dedicated in-memory list, append new invites from the callback, and remove invites immediately after accept/dismiss so stale entries are not reprocessed on reload. Also make `np_handler::select_invitation` return `bool` consistently and clear selected invitation data if the system notification fails.
Split the friends dialog invite flow into friend requests and game invitations, add a dedicated game invite page, and wire accept/reject actions with the proper prompts. Accepting now routes through a new `np_handler::select_invitation` helper that validates invite messages, notifies the game, and marks invites as used. Also added locking around selected-message state in `np_handler` to make selection access thread-safe, plus new localized strings for the added UI text.
This adds a tool that writes a snapshot of the full PS3 guest address
space to disk for offline analysis.
This tool produces a flat image that any hex editor or script can index
directly by guest address. It dumps allocated PS3 guest memory only, not
RPCS3 host-process memory, host registers, or GPU-side state.
What it does:
1. Pauses emulation and waits up to five seconds for every PPU, SPU, and
RSX thread to settle. If they do not settle, nothing is written.
2. Copies every allocated guest page into an intermediate buffer on a
named worker thread, then writes it to a sparse `guest_memory.bin` whose
file offset equals the PS3 effective address. Reads go through
`vm::g_sudo_addr` so guest protected pages are captured too.
3. Saves each live SPU thread's 256 KB local store to its own file, with
its ID, LV2 ID, PC, and type recorded.
4. Writes `manifest.json`, listing every allocated region with its
addresses and permissions, the storage mode, and the SPU local-store
table.
5. Resumes emulation.
The menu entry is under Utilities next to Memory Viewer and is enabled
while a game is loaded. Free space is checked before writing. If sparse
file setup fails, the incomplete attempt is removed and the user can
choose another destination or cancel. Failed or cancelled dumps remove
their output folder instead of leaving a partial image.
Tested on Windows using an NTFS destination with a build from this
branch: dumped a running game with 479,535,104 allocated guest bytes
across 76 regions and five SPU local stores. The image was sparse, its
offsets matched guest addresses, and emulation resumed cleanly. The
sparse file failure path was also exercised with a temporary local test:
choosing another location reopened the destination picker, while
cancelling aborted the attempt without leaving partial output. Runtime
behavior on Linux and macOS is untested.
The first draft of this implementation was AI assisted. I reviewed and
adjusted the code and tested the Windows/NTFS path myself. I am happy to
rework anything or answer any questions.
Supports: when value is the immediate result of either a bitwise OR operation or a bitwise AND when either operands is a constant.
Prevents some false positives when the value has PHI nodes in its ancestors.
Fix accidentally clearing a binding during remap if the same button is assigned to rightclick in the pad navigation.
Only allow clearing a binding on release if the same button was also pressed while no remapping occured.
The `FMA` instruction conditionally zeros one multiplicand if the other
is zero/denormal to emulate the xfloat's extended range. This patch
replaces that with a `select(is_non_zero, fma(a, b, c), c)` which has a
shorter dependency chain in most situations and probably allows LLVM to
better optimize it with surrounding instructions.
I added a AVX512 path that uses `vfixupimmps` to prevent a pessimization
where LLVM transforms it into a strictly serial predicate chain. I
confirmed that it works with denormals and both zeros.
https://godbolt.org/z/hsP5G43Ye
LLVM 21 moved the KnownFPClass definition from `ValueTracking.h` to its own file. I verified that specific version moved it, with 20 being the last without it.
Replaced the denormal/zero check in `fma32x4` with LLVM's `KnownFPClass` analysis.
That method now includes a overload which expects the caller to provide the known struct. This is used for memorization with the FMA instructions, where the range clamping and instruction specific special value handling are combined. `FMS` and `FNMS` has a larger search depth as it can potentially shorten the chain by a lot.
Replace constant checks in `FM`, `FCEQ`, and `FCMEQ` with `KnownFPClass`. The equality compares now also optimize for when the operands is infinity, which is safe as it behaves identically to the default path.
Avoid clamping if the value is known not to be Inf/NaN (overflow). Includes a optional precalculated argument, which only calculates the known if it has not been done already.
Optimize the float multiply and compare methods by taking advantage of the `denormals-are-zero` flag, removing duplicated logic, and generally doing things more efficiently.
Refactors SELB by changing "division accuracy correction" pattern match to reduce nesting, include more comments, and use more descriptive variable names. Also replaced duplicated granularity-check loops with single loop which determines byte granularity as a integer.
## Summary
- fall back from database-applied `SPU Decoder: Recompiler (ASMJIT)` to
`Recompiler (LLVM)` on ARM64 builds during boot
- log the fallback in `fixup_settings()` instead of letting SPU
initialization fail later
## Problem
`Need for Speed: Most Wanted [BLES01659]` receives `SPU Decoder:
Recompiler (ASMJIT)` from the config database. On ARM64 builds that
decoder is unsupported, which caused RPCS3 to abort during SPU
initialization with `Unsupported spu decoder` while the UI remained on
the loading screen.
## Validation
- built RPCS3 locally on macOS Apple Silicon
- booted `BLES01659` through the database config path with the custom
per-game override temporarily removed
- verified the log now shows the ARM64 fallback warning and `SPU
Decoder: Recompiler (LLVM)` instead of the previous fatal error
- observed the title proceed past the old boot blocker into active RSX
program compilation
---------
Co-authored-by: Elad <[email protected]>
Prevent invoking more than utils::get_max_threads() active thrreads at a time.
Windows sees more than utils::get_max_threads() active threads as potentially malicious behavior and lowers the program's overall CPU time.
- LLVM can't handle the select pattern we use to avoid poison values for large shifts
- So let's just use the intrinsic to avoid poison values altogether for now
- https://github.com/llvm/llvm-project/issues/200698
Fully implements cellSysmodule and sets it to HLE by default.
There is an undocumented function that decrypts the OpenPSID. There
doesn't seem to be any information about this on the PS3 dev wiki or
anywhere else, so I thought I mention this separately.
Refactored `SHUFB` by moving the byteswap optimization prior to the target specific path. Also separated the shuffle and special index constants calculation into separate steps in order to reduce code duplication.
Added a number of TODOs as this refactor revealed some of optimizations opportunities. None of which has been added as this refactor intends to minimize new behavior.
The "Fill more block info" re-decode indexed result.data[(ia - lsa) / 41] instead of / 4 (its companion decode uses / 4), so it read the wrong word and corrupted the per-block reg_const / reg_val32 constant propagation.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Giga cleanup clears m_block_info for removed blocks but left their in-range edges in m_targets, so the register-state walk dereferenced a stale target and aborted ("Range check failed") - e.g. a brsl whose return is a stop-trap, hit in Skylanders Giants. Prune those edges at the m_targets cleanup; export out_target_list after the prune so callers see the cleaned map; keep the initiate_patterns and cond_next-walk guards as defense in depth.
Adds made-up-data regression tests (the exported-map test fails without the prune) and the rpcs3_test.vcxproj entry.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The `FREST` instruction uses a scalar lookup-table loop to calculate the
mantissa. Given that it's only 32 elements, we can load it into two
512-bit vectors and treat them as the sources to the `vperm2d` shuffle
instruction. This allows it to be calculated in parallel, improving its
performance.
The `FRSQEST` instruction uses a lookup-table to calculate both the
exponent and mantissa. The exponent follows a simple linear pattern and
thus can be calculated using integer arithmetic: `(exponent==0)? 0xFF :
190 - (exponent + 1) / 2`. This patch replaces the LUT with this method,
vectorizing its calculating and saving on 1kB.
The mantissa still relies on a LUT, which bottlenecks this instruction's
emulation despite the improvement.
- Added a LLVM SPU recompiler implementation as LLVM can't take advantage of the rounding mode.
- Further optimized the method by replacing MSB check with saturation subtraction. Negative values are saturated to zero due to the float's sign bit.
Removed the SSE4.1 instruction to make it compatible with the baseline instruction set. Increased dependency chain by one instruction and caused constant generation to be slightly more expensive.
Closes#18856
Moved the three download database actions from the game list context
menu to Manage -> Databases submenu, since they are not related to a
specific game entry.
The "Dirty hack for sound" in AudioSetNotifyEventQueue() is gated on a
named constant c_mxr000 that is supposed to equal the IPC key of the
_mxr000 event queue created by the game's _cellsurMixerMain thread
(0x8000cafe02460300, e.g. Virtua Fighter 5 FS / SEGA AM2 CRI titles).
When the inline literal was refactored into the named constant in
730badd37 ("cellAudio: Move and partially fix _mxr000 hack", 2023) a
trailing hex digit was dropped: 0x8000cafe0246030 instead of
0x8000cafe02460300 (the value used by the original 2018 hack in
cc0d7c598). As a result `key == c_mxr000` never matches and
lv2_event_queue::find(c_mxr000) looks up the wrong key, so the
surmixer-queue serialization path is effectively dead for every
_mxr000 CRI game.
Restore the correct 16-digit key so the gate and lookup match the
queue the game actually creates.
Note: this corrects a real latent bug but does not by itself resolve
the cellSurMixer null-deref in VF5FS (#17066), which is a separate,
flaky CRI channel-strip init divergence.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The PPU/SPU recompilers emit i8mm intrinsics (ummla/smmla, used by the
SPU GBB/GBH gather paths) gated on utils::has_i8mm(). The JIT's MAttrs
list mirrored dotprod/sha3/sve from HWCAP but never added i8mm, and the
resolved -mcpu on Apple silicon is the cortex-a78 fallback (no i8mm), so
the backend aborted with "Cannot select: intrinsic %llvm.aarch64.neon.ummla"
on every game. Mirror i8mm into MAttrs like the other features.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
(cherry picked from commit 52d121fee79cc569c9ac273852edd0e493ae51fc)
This adds a dropdown in the emulated G27 settings dialog ("Force
feedback direction encoding") with three options: Steering Axis
(default), Cartesian, Polar. Default is Steering Axis so existing users
see no change.
RPCS3 right now hardcodes SDL_HAPTIC_STEERING_AXIS for the spring and
constant-force effects it sends to the host wheel. That's SDL's
recommended encoding for wheels and works on the hardware the code was
written against. Some Windows DirectInput drivers (like my MOZA R3) do
not react to these affects at all. This now allows changing it to an
encoding that works.
- Compiles down to just 2 instructions on Neon, instead of falling back to scalar instructions
- Remove this workaround when LLVM fixes this issue upstream: https://github.com/llvm/llvm-project/issues/200325
This is a continuation of my work on #18113.
Addresses issue #18197.
Adds a new checkbox in the I/O settings tab that enables mouse-based
gyro emulation at game startup, making the feature more discoverable to
users.
Two small fixes that stop the emulator from writing past buffer
boundaries.
RawSPU: when loading a program onto an SPU processor, it now checks that
the program actually fits in 256 KB before copying it. Before this, a
corrupted file could write past the buffer into random host memory.
PPUInterpreter: a one-character typo fix. A modulo operation used % 127
instead of % 128 when computing cross-boundary data sizes. This caused
reservation checks to compare the wrong number of bytes on every load
that crossed a cache line. This fix was pointed out by @AniLeo in the
spam PR #18795 (Discovered by Opus 4.7)
The PS3 hardware enforces these limits:
- Each SPU has exactly 256 KB of memory (from Cell Broadband Engine
Handbook v1.1)
- The PPE cache line is 128 bytes — all reservation logic uses this
granularity
Neither fix should affect the usual games. They only applying to
corrupted or malformed files. Will highly appreciate feedback and
suggestions for this PR
Tested on CI: CI passes on my fork 9 of 10 platforms (Mac Intel failed
downloading a dependency).
Title and Desc written by Codex
- Some SPU programs inexplicably fail to compile when TBL2/TBX2 are used.
- As an insane workaround, first try to compile with TBL2/TBX2, if LLVM crashes while compiling, try to compile the same program without TBL2/TBX2.
- Saves 2 instructions in MPY, 1 instruction in MPYU, 2 instructions in MPYS, 2 instructions in MPYA, 1 instruction in MPYI, and 2 instructions in MPYUI
- Fragment state just reloads some constant buffers.
- Fragment program state recalculates the program.
- This is overkill for a variant reload, but that can be optimized later.
I observed under macOS (although the bug seems platform agnostic to me)
that when restarting a game, then subsequently quitting it, I'd get
stuck in a 'restart loop' where the game would restart upon completely
shutting down, and this would repeat every time I tried to close the
game until I gave up & force quit RPCS3. Seems like for whatever reason,
the use of std::move didn't actually guarantee that after_kill_callback
got nuked if at all, so all I've done is take a hammer to the fucker and
manually set it to nullptr after being called.
Co-authored-by: Elad <[email protected]>
The shuffle in step_track() used std::default_random_engine with a
default (fixed) seed, causing the playlist to be 'shuffled' into the
same deterministic order every time. Use std::random_device to seed the
engine so each shuffle produces a genuinely random order.
Fixes#18672
Users frequently close the game list accidentally and then can't
figure out how to restore it. Remove the DockWidgetClosable feature
so the close button is not shown. The game list visibility can still
be toggled via View > View Game List menu action.
Fixes#18518
## Summary
Fixes the GUI language dropdown to show territory variants when
translation files include country codes.
**Before:** "Portuguese" for both `pt_BR` and `pt_PT`
**After:** "Portuguese (Brazil)" and "Portuguese (Portugal)"
Also fixes the same ambiguity for Chinese and any other language with
country variants.
## Implementation
Uses `QLocale::territoryToString()` alongside the existing
`QLocale::languageToString()` to construct display labels. When no
territory exists (e.g., `en`, `ja`), the label is unchanged.
## Edge cases
- No-territory locales (`en`, `ja`): unchanged —
`QLocale::territoryToString(AnyTerritory)` returns empty, guard
preserves plain language name
- Territory names are locale-translated (not hardcoded English) — they
follow the current UI language, same as `languageToString()`
- `zh_CN` → "Chinese (China)" / `zh_TW` → "Chinese (Taiwan)"
(territory-based, unlike the PS3 system language dropdown which uses
Simplified/Traditional script names — this is appropriate for the GUI
translator selector context)
## Test Plan
- [ ] Language menu shows "Portuguese (Brazil)" when `rpcs3_pt_BR.qm` is
present
- [ ] Language menu shows "Chinese (China)" when `rpcs3_zh_CN.qm` is
present
- [ ] Plain languages (`en`, `ja`) continue to show without parens
---
<details>
<summary>Review note: territory strings in UI locale</summary>
Territory names render in the current UI language (not forced English).
This matches `QLocale::languageToString()` behavior and is consistent
with how the rest of the menu renders. If hardcoded English labels are
preferred, that can be added after review.
</details>
Fixes#18215
Address review feedback on #18701 (cc @elad335): combine the SPU
worker fix from #18701, the SPRX Loader fix from #18703, and three
additional similar W^X leaks discovered while auditing the codebase
for the same pattern. Use Allman-style braces to match RPCS3 coding
style.
Background:
On AArch64 Apple Silicon, MAP_JIT pages enforce W^X per-thread.
pthread_jit_write_protect_np(false) enables write mode and
pthread_jit_write_protect_np(true) restores execute mode. When code
takes an early return or throws between these calls, the thread is
left in write mode, which can cause segfaults on subsequent code
fetches or inconsistent state at thread teardown.
Fixes applied (all gated on __APPLE__):
1. Emu/Cell/SPUCommonRecompiler.cpp - SPU cache worker thread
Add RAII guard so execute mode is restored on worker exit.
2. Emu/System.cpp - SPRX Loader thread
Enter write mode (was missing entirely) so ppu_initialize() and
ppu_precompile() can write to MAP_JIT pages, and pair with an
RAII guard. Reproducer: Red Dead Redemption (BLUS30418) crashes
~12s into boot at 0x300010000 without this fix.
3. Emu/Cell/SPULLVMRecompiler.cpp - SPU LLVM compile path
The compile function enters write mode, then has an early
"return nullptr" path on rebuild_ubertrampoline failure that
skipped the explicit restore. Add RAII guard so execute mode
is restored on every exit path. The existing explicit restore
before the cache-flush asm directives is preserved.
4. Emu/Cell/PPUThread.cpp - PPU LLVM worker thread (operator())
Worker entered write mode but never restored it on operator()
return. Add RAII guard.
5. Emu/Cell/PPUThread.cpp - ppu_initialize() main path
This scope alternates write/execute mode and contains an early
"return compiled_new" at the empty-jits check plus a final
return that both leak write mode. Add RAII guard so execute
mode is always restored on exit. Intermediate explicit
transitions for the symbol-resolver invocation are preserved.
No behavioral change on x86_64 or non-Apple ARM64 (all changes are
inside #ifdef __APPLE__ / #if defined(__APPLE__)).
Supersedes #18703.
## Summary
The "Left" and "Right" strings in `pad_settings_dialog` were shared
between DPad/Stick direction labels (which have ample space) and offset
value labels — Squircle Values, Stick Multipliers, and Stick
Interpolation (where space is tight). Translators couldn't abbreviate
the offset version without also affecting the direction binding labels.
## Change
Added disambiguation via `comment="Offset direction"` in the `.ui`
file's `<string>` elements for the six offset labels:
- `label_squircle_left`
- `label_squircle_right`
- `label_stick_multi_left`
- `label_stick_multi_right`
- `left_stick_lerp_label`
- `right_stick_lerp_label`
Qt now generates separate translation entries, allowing translators to
use shorter abbreviations in the tight offset areas while keeping full
forms for direction bindings.
**English UI is unchanged** — no visual difference for English users.
Fixes#18691
### FIXES + MINOR IMPROVEMENTS:
- Fixed issue18685: Not a real issue. PR18648 added some logging that made
evident a missing check on the validity of the paths in `games.yml`
before trying to manage the path as a possible ISO file. That missing
check was already present but simply invisible due to missing log
- Fixed `bytes_to_hex()` function used to store file hash hex string: In
some cases the integrity check wrongly reported the check as failed
- Optimized `fs::get_optical_raw_device()` function: Moved under
`_WIN32` block a check valid only on `Windows` and simplified the logic
to detect a CDROM / BD as raw device
- Used `iso_file` objects instead of `fs:file` in `ISO.cpp`: It allows
to use proper `bool()` operator on some checks
- The main thread may bind the program before the compiler context has published the binding instructions
- Once bound, late bindings are not updated so the program remains with uninitialized bindings and rendering breaks
Fixes regression from #18546 and #18679.
## Problem
The is_from_yml ISO branch constructed iso_archive unconditionally,
bypassing the cache check inside add_game, making the cache write-only
for yml-sourced ISOs.
## Fix
Added a lightweight index cache entry (iso_path + "//index") storing the
subdir list + mtime. On hit, skips archive construction entirely. On
miss, walks as before and writes the index
Append to `CMAKE_PREFIX_PATH` and `CMAKE_SYSTEM_PREFIX` instead of using `include_directories()` and `link_directories()`.
This avoids include/link path
pollution and reduces clashes with vendored dependencies. This means that conflicting homebrew packages no longer have to be unlinked to build rpcs3, as system paths are searched last.
0.85 elfs break here due to them not having a version header offset.
Very unlikely these elfs will ever load but its useful to be able to decrypt them at least.
Co-authored-by: Elad <[email protected]>
Follow up of #18345 to add support (currently only on `Windows`; see
notes below) for playing a PS3 disc game directly from a Blu-Ray Disc
Drive.
### HOW IT WORKS:
- The BD drive can be added as any other game so from `VFS games` or
from `Add Games` menu. In case it is selected from `VFS games`, any
attempt to write files is discarded, e.g. file `Disc Games Can Be Put
Here For Automatic Detection.txt`
- It scans the default redump keys folder `<rpcs3>/data/redump` (it
currently needs to be manually created due it is not yet provided by
rpcs3 installation) to find a matching decryption key
### NOTES:
- Support is currently provided on `Windows` where I can fully test it.
I cannot test under other OS. However, the additions needed for the
other OS are limited only on `fs::file.h/cpp`. In particular inside the
following new functions:
- `bool is_optical_raw_device(const std::string& path);`
- `bool get_optical_raw_device(const std::string& path, std::string*
raw_device = nullptr);`
- Icons etc. are always refreshed (ISO cache cannot be used due `mtime`
on raw device is not available and any cache check would always fail)
- Code in `ISO.h/cpp` needed some rework to properly manage a read on a
raw device (alignment on offset, size and memory is mandatory). The BD
drive needs to be detected as a file, not as a folder
### MINOR FIXES:
- Fixed wrong specifier used in logging on `ISO.h/cpp`
The passthrough path was fake-completing zero-length bulk/interrupt IN
URBs to mirror the emulated path, so games that drain-poll between
transfers wouldn't stall the libusb worker thread. This baked an
emulator-side assumption about device behaviour into the host stack.
Real PS3 USIO devices issue a ZLP on the read endpoint after any
transfer that would otherwise leave the host's drain URB outstanding
(notably after a CMD_WRITE). Devices that follow the same protocol
(e.g. ITAIKO firmware) are expected to do the same; faking it here
masks firmware bugs and diverges from real hardware behaviour.
Drop the workaround and let libusb submit the URB normally. The IN
URB now completes when the device sends its ZLP, matching real PS3.
Refs: https://github.com/RPCS3/rpcs3/pull/18636#discussion_r3143290987
The PS3 USB stack routes both bulk and interrupt requests through
usb_device_passthrough::interrupt_transfer. The old code unconditionally
called libusb_fill_interrupt_transfer regardless of the endpoint type,
which on Linux's usbfs backend is rejected with EINVAL whenever the URB
type doesn't match the endpoint's bmAttributes. Reads against bulk IN
endpoints therefore never completed and the worker thread stalled.
Look up the endpoint descriptor and dispatch to libusb_fill_bulk_transfer
when bmAttributes indicates bulk. A new usb_device::find_endpoint helper
walks the descriptor tree once per submission.
Confirmed broken on Linux and working on Windows pre-fix; macOS
untested. WinUSB silently accepts the type mismatch, which is why this
went unnoticed. Reproduces with any passthrough device that has a bulk
IN endpoint, e.g. a Bandai Namco USIO (0b9a:0910) under Taiko no Tatsujin
S111 [SCEEXE000]: the game's boot-time the I/O board check runs and then hangs.
Two related defensive fixes uncovered while debugging the above:
- Zero-length bulk/interrupt IN URBs hang in libusb until the device
sends a ZLP. The emulated path fake-completes them immediately; mirror
that here so drain-polls between transfers don't stall the worker.
- An unexpected libusb_submit_transfer error used to leave
UsbTransfer::busy = true forever. Mark it as a fake completion with
EHCI_CC_HALTED so the USB manager processes the failure cleanly
instead of deadlocking the request.
The color/depth alias collapse heuristic at get_framebuffer_layout()
picks depth whenever depth_test_enabled or stencil_test_enabled is set.
But test means read, not write - so deferred renderers that run a
Z-prepass and then a G-buffer pass with depth-test ON, depth-write OFF,
color-write ON get classified as a depth pass even though they're
writing color. The color writes get silently dropped.
In Starhawk this killed every lit surface - characters, skybox, anything
that goes through the deferred lighting path rendered black or
invisible. Terrain, particles, and emissive geometry kept working
because they don't go through that same pipeline.
Fix is to check writes instead of tests:
if (zeta_write_enabled && !color_write_enabled)
keep_as_depth(); // Z-prepass, shadow gen
else
keep_as_color(); // G-buffer / lit pass
For the both-writes case I went with color since losing color is much
more obvious visually than losing depth (the engine's Z-prepass usually
still has the depth around).
Tested with Starhawk [BCUS98181] in menu and gameplay - before: missing
characters and sky. After: matches PS3 reference. Logged every aliasing
event during a couple minutes of gameplay and they were all the G-buffer
pattern (depth-test ON, depth-write OFF, color-write ON), all handled
right. The depth-keep branch wasn't actually exercised in Starhawk, but
it's there for games that do use a Z-prepass to an aliased buffer.
Fixes#11877.
The constructor inserted rows into m_list_captured_frame for the command queue but never did the same for m_list_captured_draw_calls. GetMemory()'s setItem() loop for draw calls then no-op'd on missing rows, so the Captured Draw Calls tab always appeared empty after a frame capture.
The previous approach used munmap followed by mmap without MAP_FIXED
(since Apple rejects MAP_FIXED | MAP_JIT). Between the two calls,
another thread could claim the unmapped address range, causing mmap
to return a different address and triggering a fatal verification error.
Under concurrent load (e.g. PPU LLVM compilation with many worker threads),
this race manifests reliably as "Verification failed (object: 0x0)" crashes
across all PPUW threads in memory_decommit.
Fix: Use MAP_FIXED without MAP_JIT instead. This atomically replaces the
mapping without any window for other threads to interfere. The MAP_JIT
attribute is lost on the replaced pages, but the application's code signing
entitlements (allow-unsigned-executable-memory, disable-executable-page-protection)
permit executable mappings without it.
Applied the same fix to memory_reset which had the identical pattern.
Replaces the plain text "Show Details" changelog in the update dialog
with a QTextBrowser that converts PR references like (#1234) into
clickable GitHub links.
**Why? :** Easy to check PRs you are interested in beyond the title.
Switch from API to direct download.
Fixes 403 error code.
jammy-aarch64 needs `unzip` from universe in the Dockerfile.
eg:
```
add-apt-repository universe
apt update -qq
apt-get install -y unzip
```
Fixes https://github.com/RPCS3/rpcs3/issues/18560
Every launch constructs a fresh iso_archive for each ISO game, which
calls iso_form_hierarchy() and walks the full directory tree. On top of
that, qt_utils opens a second iso_archive just for icon loading, so
every ISO game ends up doing two full directory tree walks on every
launch.
This adds a metadata cache keyed by ISO path + mtime stored under
fs::get_config_dir()/iso_cache/. Each entry stores the raw SFO binary,
resolved icon/movie/audio paths and raw icon bytes.
- On cache hit, iso_archive construction is skipped entirely for both
game list scanning and icon loading
- On cache miss archive is scanned as before and the result is persisted
to disk
- Cache is automatically invalidated when the ISO file's mtime changes
Tested with a decrypted PS3 disc ISO (God of War III):
- First launch writes cache files correctly to iso_cache/
- Second launch reads from cache with correct title and icon
- touch game.iso correctly invalidates the cache and triggers a rescan
fix compile errors and suppress minor warnings
strip minor bug fixes and cleanup
minor cleanup
minor cleanup
Fixed crash at boot parsing an ISO with a empty directory entry at file head
applied suggested changes
added missing break in switch
Update rpcs3/Loader/ISO.cpp
Co-authored-by: Megamouse <[email protected]>
use hex_to_bytes() instead of self made functions
minor cleanup
rewrite nested if()
add explicit support to .key
minor cleanup
optimize partial sector read
minor optimization
fix conflict
On Apple ARM64, memory_reserve unconditionally applies MAP_JIT to all
reservations. However, regions marked as is_memory_mapping are later
replaced by file-backed MAP_FIXED mappings via shm::map/map_critical.
Overlaying a file-backed MAP_FIXED mapping onto a MAP_JIT region causes
the resulting pages to be inaccessible, leading to a segfault when the
SPRX Loader attempts to write module data into PS3 memory (g_sudo_addr).
Fix: Only apply MAP_JIT for non-mapping regions. Memory mapping regions
don't need JIT capability since they use shared memory for the PS3
address space, not executable JIT code.
Tested on Apple M3 Max, macOS 26.3.1. The SPRX Loader now successfully
loads all modules and emulation proceeds past the loading stage.
Please do not ask for help or report compatibility regressions here, use [RPCS3 Discord server](https://discord.gg/rpcs3) or [forums](https://forums.rpcs3.net/) instead.
- type:textarea
id:quick-summary
attributes:
label:Quick summary
description:Please briefly describe what has stopped working correctly.
validations:
required:true
Please do not ask for help here, use the [RPCS3 Discord server](https://discord.gg/rpcs3) or the [RPCS3 Forum](https://forums.rpcs3.net/) instead.
- type:textarea
id:details
attributes:
@@ -26,21 +19,29 @@ body:
attributes:
value:|
# Identify the regressed build
Please provide the _exact_ build (or commit) information that introduced the regression you're reporting.
Please provide the _exact_ build information that **introduced** the regression you're reporting (i.e. the first version where it happens).
* Please see [How to find the build that caused a regression](https://wiki.rpcs3.net/index.php?title=Help:Using_different_versions_of_RPCS3#How_to_find_the_build_that_caused_a_regression.3F) in our wiki.
* You can find [History of RPCS3 builds](https://rpcs3.net/compatibility?b) here.
* You can find the [History of RPCS3 builds](https://rpcs3.net/builds) here.
Make sure you're running with settings as close to default as possible
* **Do NOT enable any emulator game patches when reporting issues**
* Only change settings that are required for the game to work
* **Only change settings that are required for the game to work**
- type:input
id:regressed-build
id:last-good-build
attributes:
label:Build with regression
description:Provide _exact_ build (or commit) information that introduced the regression you're reporting.
label:Last working build
description:Provide the _exact_ last working build. This needs to be the build right before the first broken build.
placeholder:v0.0.23-13948-31df99f7
validations:
required:true
- type:input
id:first-bad-build
attributes:
label:First broken build
description:Provide the _exact_ first broken build. This needs to be the build right after the last working build.
placeholder:v0.0.23-13949-d1a46b49
validations:
required:true
- type:markdown
attributes:
value:|
@@ -56,12 +57,25 @@ body:
- type:textarea
id:logs
attributes:
label:Attach two log files
label:Attach 3 log files
description:|
Attach one file for the build with regression and another for a build that works.
* A RPCS3 log file for the last working build
* A RPCS3 log file for the first broken build
* A RPCS3 log file for the latest master build (not required if latest master build is the first broken build)
Drag & drop the files into this input field, or upload them to another service (f.ex. Dropbox, Mega) and provide a link.
validations:
required:true
- type:dropdown
id:require-log-files
attributes:
label:I have attached all 3 required log files
options:
- "Yes"
- "No"
default:1
validations:
required:true
- type:markdown
attributes:
value:|
@@ -73,8 +87,8 @@ body:
- type:textarea
id:captures
attributes:
label:Attach capture files for visual issues
description:Compress your capture with 7z, Rar etc. and attach it here, or upload it to the cloud (Dropbox, Mega etc) and add a link to it.
label:Attach the RSX (.rrc) or RenderDoc (.rdc) capture files for visual issues
description:Compress your capture with .7z, .gz, etc. and attach it here, or upload it to another service (f.ex. Dropbox, Mega) and provide a link.
validations:
required:false
- type:textarea
@@ -84,10 +98,3 @@ body:
description:Provide information about your system, such as operating system, CPU and GPU model, GPU driver version and other information that describes your system configuration.
validations:
required:false
- type:textarea
id:other-details
attributes:
label:Other details
description:Include anything else you deem to be important.
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)"
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)"
@@ -20,27 +20,27 @@ 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.11.0](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.
- [Qt 6.12.0](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.4.341.1](https://vulkan.lunarg.com/sdk/home) (see "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html)). Note that future SDKs may not work.
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.11.0\msvc2022_64\`
- add and set the `QTDIR` environment variable, e.g. `<QtInstallFolder>\6.12.0\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.11.0\msvc2022_64\`
- add and set the `Qt6_ROOT` environment variable to the **Qt** libs path, e.g. `<QtInstallFolder>\6.12.0\msvc2022_64\`
### Linux
These are the essentials tools to build RPCS3 on Linux. Some of them can be installed through your favorite package manager:
- [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.
- [Vulkan SDK 1.4.341.1](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html)). Note that future SDKs may not work.
- [SDL3](https://github.com/libsdl-org/SDL/releases) (for the FAudio backend)
**If you have an NVIDIA GPU, you may need to install the libglvnd package.**
@@ -72,14 +72,7 @@ You can either use `update-alternatives` to setup `gcc-13`/`g++-13` as your defa
##### Vulkan SDK
For Ubuntu systems, it is strongly recommended to use the PPA from [LunarG](https://packages.lunarg.com/) which will provide a compatible Vulkan SDK to compile RPCS3. If your Vulkan SDK is older, it can lead to compilation errors.
For Ubuntu systems, it is strongly recommended to use the official [Linux Tarball Vulkan SDK](https://vulkan.lunarg.com/doc/view/1.4.341.0/linux/getting_started.html) which will provide a compatible Vulkan SDK to compile RPCS3. If your Vulkan SDK is older, it can lead to compilation errors.
##### CMake
@@ -123,7 +116,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.11.0\msvc2022_64`, version will fill in automatically
2) add the path to your Qt installation with compiler e.g. `<QtInstallFolder>\6.12.0\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**)
@@ -132,7 +125,7 @@ Start **Visual Studio**, click on `Open a project or solution` and select the `r
**NOTE:** The recommended build configuration is `Release`. (On older revisions: `Release - LLVM`)
To speed up the compilation time, you may want to download and extract to `<rpcs3_root>\build\lib_ext\<$(Configuration)>-x64` (e.g. `c:\rpcs3\build\lib_ext\Release-x64`; the path needs to be created) the following precompiled lib:
-`<$(Configuration)>` can assume values `Release` or `Debug`.
@@ -179,6 +172,22 @@ In case you preferred to install and use the standalone **CMake** tool:
```
3) once the build is completed, the **RPCS3** application will be available under the `<rpcs3_root>\build-msvc\bin` folder
#### Building with the PowerShell script
As an alternative to building through Visual Studio, run the PowerShell helper from the repository root:
```powershell
.\scripts\win_build.ps1
```
The script locates a supported Visual Studio installation, finds Qt from `Qt6_ROOT` or a standard `C:\Qt` installation, configures a Release Ninja Multi-Config build, and then builds it. Pass `-Cores <count>` to set the parallel build count; by default it uses all logical processors:
```powershell
.\scripts\win_build.ps1 -Cores 8
```
The resulting application is placed in `<rpcs3_root>\build\bin`.
option(USE_NATIVE_INSTRUCTIONS"USE_NATIVE_INSTRUCTIONS makes rpcs3 compile with -march=native, which is useful for local builds, but not good for packages."ON)
option(USE_ARM_LSE2"Compile with LSE2 instructions"OFF)
option(WITH_LLVM"Enable usage of LLVM library"ON)
option(BUILD_LLVM"Build LLVM from git submodule"OFF)
option(STATIC_LINK_LLVM"Link against LLVM statically. This will get set to ON if you build LLVM from the submodule."OFF)
@@ -63,6 +64,7 @@ option(USE_LTO "Use LTO for building" ON)
option(BUILD_RPCS3_TESTS"Build RPCS3 unit tests."OFF)
option(RUN_RPCS3_TESTS"Run RPCS3 unit tests. Requires BUILD_RPCS3_TESTS"OFF)
option(USE_GAMEMODE"Choose whether to enable GameMode features or not."ON)
option(BUNDLE_UDEV_RULES"Include udev rules on Linux/FreeBSD"OFF)
@@ -9,7 +9,7 @@ The world's first free and open-source PlayStation 3 emulator/debugger, written
You can find some basic information on our [**website**](https://rpcs3.net/). Game info is being populated on the [**Wiki**](https://wiki.rpcs3.net/).
For discussion about this emulator, PS3 emulation, and game compatibility reports, please visit our [**forums**](https://forums.rpcs3.net) and our [**Discord server**](https://discord.gg/RPCS3).
[**Support Lead Developers Nekotekina and kd-11 on Patreon**](https://www.patreon.com/Nekotekina)
[**Support the Lead Developers on Patreon**](https://rpcs3.net/patreon)
## Contributing
@@ -23,6 +23,16 @@ If you want to contribute as a developer, please take a look at the following pa
You should also contact any of the developers in the forums or in the Discord server to learn more about the current state of the emulator.
### AI Use
Use of AI tools for research and reverse engineering purposes is permitted. However, contributors are expected to fully own and understand all code they submit. Any communication with the team — including code, code comments, and GitHub comments — must come from the human contributor, not an AI agent acting autonomously.
We have unfortunately seen a rise in untested and unverified AI-generated slop being submitted to this project. This wastes maintainer time and, in worse cases, such changes get merged and break functionality for all users. Repeated violations will result in a ban from the repository. Please be respectful of everyone's time.
**Pull requests opened by AI agents or automated tools must include a disclosure in the PR description** stating the scope of AI involvement — which parts were AI-generated and what human testing or review was performed prior to submission. PRs that omit this disclosure may be closed without review.
If you are unsure about your work, open a discussion issue to talk it through with the team, or reach out to a maintainer on [Discord](https://discord.gg/RPCS3).
## Building
See [BUILDING.md](BUILDING.md) for more information about how to setup an environment to build RPCS3.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.