Commit Graph
216 Commits
Author SHA1 Message Date
LunaMoo bbbe195bdf fix gow vortex patch by making sure changed register value get's used in JIT 2026-10-12 16:40:43 +02:00
Henrik RydgårdandClaude Opus 5.5 ae68a7e73f Coded Arms: Contagion: Read back the stencil the crosshair checks
The crosshair turns red, and lock-on works, when stencil bit 3 is set at
the centre of the frame, which the game tests by reading the pixel from
VRAM with the CPU (#17936). Hook that and read back the stencil of that
row into the alpha bytes in RAM. The alpha the hardware backends keep
doesn't follow stencil everywhere, so reading color isn't enough.

Adds PerformReadbackStencilToMemory for this (8888 only for now).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 12:15:56 +02:00
Henrik RydgårdandClaude Opus 5.5 18816b111a Savestate: Put back hooked instructions some old states saved as hook ops
Some old states have replacement hook ops in memory. Since hooks moved out of
memory, those changed the functions' hashes on load, so they weren't hooked
again, and the CPU hit the op as an illegal instruction. Restore the
instructions this session hooked at the same addresses, as the old hooking did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:52:46 +02:00
Henrik RydgårdandClaude Opus 5.5 24ea7c4193 Everybody's Golf: Read back the screen under the loading spinner
The spinner copies the displayed framebuffer under it into the transparent
texels of its frames, which came out as stale VRAM around the disc. Hook it
after it gets the framebuffer and read back the rows it covers.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 15:10:34 +02:00
Henrik RydgårdandClaude Opus 5.5 94d943664e Everybody's Golf: Hook the player portrait copy too
The first game builds its portrait like Golf 2 and Tennis, but its copy
function keeps y and h in different registers and loads the framebuffer pointer
at a different offset. Move the readbacks into a helper and add a hook for this
layout.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 15:06:24 +02:00
Henrik RydgårdandClaude Opus 5.5 6f56798c44 Everybody's Tennis: Hook the player portrait copy too
Tennis builds its portraits like Everybody's Golf 2: it memcpys a 64x64 rect of
the framebuffer and sets each texel's alpha bit from depth read straight from
VRAM, so the circles in the corners came out empty. Its copy function is
scheduled differently and hashes differently, so add it as a second entry for
the same hook, which is renamed to fit both.

Fixes #17826.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 15:00:40 +02:00
Henrik RydgårdandClaude Opus 5.5 648766dad4 Everybody's Golf 2: Read back color and depth for the player portraits
The game builds each 64x64 portrait by memcpying a rect of the framebuffer one
partial row at a time, then setting each texel's alpha bit from the depth
buffer, which it reads directly from VRAM. Neither got read back: the row
copies don't line up with a framebuffer, and depth is never downloaded.

Hook the copy function to read back both, whole rows at a time. That needed two
fixes to requested depth copies: they were dropped when the depth buffer lies
above all color buffers, and only an exact full-buffer size matched.

The portrait texture now matches the software renderer, though it still
doesn't show up on screen with Vulkan.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 13:25:10 +02:00
Henrik RydgårdandClaude Opus 5.5 5fa4a475f9 Rename the replacement pseudo-op, drop the leftover emuhack defines
With block entries out of memory, the only fake opcode left is the one the CPU cores fetch in
place of a hooked instruction. Call it MIPS_CALL_REPLACEMENT_OP, and its handlers
Int_CallReplacement and Dis_CallReplacement, and remove the sub-op defines and the unused
MIPS_IS_REPLACEMENT.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 10:33:30 +02:00
Henrik RydgårdandClaude Opus 5.5 48973c83c6 Debugger: Show replacement hooks in the disassembly again
Memory no longer holds the hooks, so the disassembly fetches the op the CPU runs, which is the
CallRepl pseudo-op at a hooked address. That lookup can come from the Win32 debugger's UI thread,
so the CPU thread now changes the hook map under a lock (and reads it without, being the only
writer).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 10:33:30 +02:00
Henrik RydgårdandClaude Opus 5.5 6d122f416e Keep JIT block entries and replacement hooks out of PSP memory
The JITs used to find a block by overwriting its first instruction with an "emuhack" holding
the offset into the code space, and replacement functions installed their own emuhack the same
way. Anything that read code (savestates, the debugger, memory dumps, cheats, the function
hasher, games reading their own code) had to translate them back.

Blocks now live in a block shadow: one u32 per guest instruction, indexed by the PC masked with
BLOCK_SHADOW_MASK (1GB on 64-bit, folding the kernel and uncached mirrors; 256MB on 32-bit, iOS
and Switch, where address space is short), with the low bits cleared so a misaligned PC can't
read across two entries. Only the ranges under memory views are committed, so a bad PC still
faults in the dispatcher, and the shadow is reserved before the memory map so it can't land in
a gap of the 4GB window. Entries hold full 32-bit offsets, lifting the 16MB limit. The
dispatchers on every backend, and the IR interpreter's loop, look blocks up there.

A hooked instruction without a compiled block gets the JIT's hook value in its entry: the offset
of the dispatcher's compile path (1 for the interpreters, the IR arena keeping that offset
empty), so dispatching there compiles a block, and the frontends substitute the hook. Compiling
replaces the entry with the block's, and destroying the block puts the hook value back. The hook
value is rewritten when the JIT changes or regenerates its dispatcher.

Hooks live in a map keyed by the masked address, and are dropped when the game overwrites the
hooked instruction, or when an icache invalidation finds the function's hash (immediates masked,
as when matching it) changed. Those checks run when queued invalidations are processed, since
cheats and the debugger queue them before writing. Installing and removing hooks invalidates
deferred, as it happens in HLE calls that can run inside a block. The cache instruction goes
through MIPSState, so it drops changed hooks too.

With clean memory, the save/clear/restore around savestates, memory reads and dumps goes away,
as do the source-range invalidations in the memcpy replacements, sceDmac and the cheats.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 10:33:30 +02:00
Henrik RydgårdandClaude Opus 5 4aef060293 Carry "this is video" across block copies
videos_ only learns about the CSC output, so the texture we actually draw is
just an ordinary 512x512 8888 texture whose contents happen to be different
every frame: hash, miss, throw it in the secondary cache, rebuild, forever.

So track the copy. NotifyVideoCopy marks the destination as video when the
source is, and the copy funnels call it: sceDmacMemcpy, sceKernelMemcpy, and
the four replaced memcpy/memmove variants. It sits outside their "is either
side VRAM" gate, since a RAM-to-RAM copy of a frame is still a frame.

Being a video texture also gets it forced linear filtering and keeps it out of
texture upscaling, which is what you want for a video either way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 16:10:28 -06:00
Henrik Rydgård 9f90512ef6 Make instruction cache invalidation (for us, jit cache invalidation) clearer 2026-08-16 16:59:52 +02:00
Henrik Rydgård c5e4d0d90d Rename the get-memory-pointer functions to make it clear where CPU exceptions can happen. 2026-08-12 14:06:16 +02:00
Henrik Rydgård 0596ee97f6 More memory access cleanup 2026-08-11 20:14:01 +02:00
Henrik Rydgård 3bd41376da More memory cleanup 2026-08-11 20:12:10 +02:00
Henrik Rydgård 9396030f02 More Read_U32 cleanup 2026-08-11 09:08:52 +02:00
Henrik Rydgård 2d208ca7d9 Remove Read_U32 from sceKernelMutex 2026-08-10 11:02:25 +02:00
Henrik Rydgård a6516c8d66 __KernelModuleDoState: Only apply function replacement on state load. Improves performance of rewind states 2026-07-14 20:31:39 +02:00
Henrik Rydgård 9f5be16663 Jit: Remove the Jal-to-replacement optimization (really not all that benificial) 2026-02-17 09:40:27 +01:00
Henrik Rydgård 936c344a52 misc 2026-02-09 16:41:51 +01:00
Henrik Rydgård 5f7a937466 Rename ValidSize to ClampValidSizeAt 2025-12-30 20:31:07 +01:00
bibarub 6950dbc0de FB Readback hook for Kingdom Hearts 2025-07-18 01:50:31 +03:00
bibarub 2130b6ba45 Hook FB Readbacks in games by Takuyo 2025-07-17 17:09:40 +03:00
bibarub d8e2bb0569 Hook framebuffer readback function in Never7, Ever17, and Remember11 2025-07-16 16:04:57 +03:00
bibarub 138aab0789 Hook framebuffer readback function in Steins;Gate 2025-07-16 01:23:40 +03:00
Henrik Rydgård 1f09b782d7 Make Persona 2 battle transition more reliable. 2025-06-12 11:02:37 +02:00
Henrik Rydgård d04aa75b54 Hook framebuffer readback function in Persona 2
Same as #20067, but for Persona 2.

Fixes #13079
2025-03-03 11:32:00 +01:00
Henrik Rydgård bea49a652e Hook framebuffer readback function in Persona 1.
We really need a more general solution for this... Although we can't
generally trap acceses on all platforms :(
2025-03-03 10:45:48 +01:00
Henrik Rydgård 5326d87f9c Rename CrossSIMD to SIMDHeader, but also keep CrossSIMD.h (will have a future use) 2024-12-19 15:15:43 +01:00
Henrik Rydgård c91169e702 Restore removed <algorithm> includes.
Turns out these were needed after all. For some reason, on Windows and
Mac, <algorithm> gets auto-included by something else so I don't notice
when it's missing, and MSVC's include dependency tracker doesn't see it
either.
2024-12-19 09:53:07 +01:00
Henrik Rydgård 3e198c53b2 More include cleanup 2024-12-18 13:57:26 +01:00
Henrik Rydgård df6ed8cfc9 Do some cleanup of #includes in GPU 2024-12-18 13:57:26 +01:00
Henrik Rydgård 0df2a40487 Remove the "GPUInterface" base class. Not really useful, GPUCommon is pretty much the same thing. 2024-12-02 11:12:14 +01:00
Henrik Rydgård 7992ff4627 Make CBreakpoints an object 2024-11-25 00:22:53 +01:00
Herman Semenov 192650f551 [Core/HLE/GPU/D3D11/GLES] Using for based loop C++17 and replaced on structured binding map C++17 2024-09-18 11:10:10 +02:00
Henrik Rydgård e01ca5b057 Logging API change (refactor) (#19324)
* Rename LogType to Log

* Explicitly use the Log:: enum when logging. Allows for autocomplete when editing.

* Mac/ARM64 buildfix

* Do the same with the hle result log macros

* Rename the log names to mixed case while at it.

* iOS buildfix

* Qt buildfix attempt, ARM32 buildfix
2024-07-14 14:42:59 +02:00
LunaMoo 1f21ebdff3 Change GOWFramerateHack30 to FramerateHack30 and workaround problems in:
- Blitz: Overtime,
- Brian Lara 2007: Pressure Play.
2024-06-08 18:02:44 +02:00
Henrik Rydgård bdf7f5f40f IRInterpreter: Fix issue where we could accidentally optimize out CallReplacement ops. 2024-05-26 00:12:48 +02:00
Henrik Rydgård 2cd7b5cceb Hacky compat workaround for Resistance's ad-hoc mode
Slicing the slow memcpy calls messes up some timing so it crashes. Too
hard to fix for 1.17.1, so we do this :(
2024-02-04 00:43:48 +01:00
Unknown W. Brackets e1eecb475a HLE: Slice the very slow memset/memcpy variants.
When they take an especially long time, this allows thread switches
meanwhile.  Important for cases where they might consume more than a total
frame worth of cycles in a background thread.
2023-12-16 20:53:01 -08:00
Unknown W. Brackets 053831bf4d HLE: Add mechanics for sliced replacements. 2023-12-16 09:08:58 -08:00
Unknown W. Brackets 810d8c0890 Debugger: Use dedicated func to notify mem copy. 2023-09-24 19:07:36 -07:00
Henrik Rydgård 8fc01e37d9 Check for bad indices in GetReplacementFunc to avoid crashes 2023-09-23 10:09:55 +02:00
Unknown W. Brackets 2d13b40123 GPU: Rename match flags to avoid confusion. 2023-03-25 23:25:42 -07:00
Unknown W. Brackets 05c225655d GPU: Add xfer flag to ignore create vfb flags.
Save icons need CPU reads to work.
2023-03-25 23:19:21 -07:00
Henrik Rydgård dc74778dea Do the last ones too 2023-02-09 10:27:29 +01:00
Henrik Rydgård c52db636ce Optimize tag formatting 2023-02-09 10:22:46 +01:00
Unknown W. Brackets e9ce0d0b5e HLE: Add size checks to replace funcs. 2023-01-09 16:53:25 -08:00
Henrik Rydgård a4d3e0ead8 Add range checks in replaced memcpy/memset functions. (#16693)
* Add range checks in replaced memcpy/memset functions.

Keep seeing especially Replace_memcpy as a semi-rare crash in the
reports. Hopefully this will take care of it, though if games hit this,
they're probably on their way to failing somehow anyway.

* Alternate approach, correctly causing memory exceptions if not ignoring
2023-01-01 18:25:40 +00:00
Unknown W. Brackets 0496ca32ff Global: Cleanup some minor includes and typos. 2022-12-27 08:33:07 -08:00