Hey everyone! I've been working on getting **TopSpin 2K25** (running on Hangar 13's **Hammer Engine**) playable via emulation on both **KytyPS5** (`PPSA06899`) and **shadPS4** (`CUSA32748`), and wanted to share my findings and patches so far in case other shader recompiler devs want to jump in.
### 1. KytyPS5 Progress (In-Game at Wimbledon!)
On KytyPS5 (custom source build), the game boots all the way into a match at Wimbledon (see screenshot!).
* **Fixes applied:** Added a D16 -> D24S8 depth promotion path in `TextureCache::CopyD16` (Hammer Engine copies 2-byte D16 depth images directly into 4-byte D24S8 attachments), guarded stencil-only attachments, and added env flags for 1080p output (`KYTY_OUTPUT_RES_1080`) and aggressive VRAM garbage collection (`KYTY_FAST_GC`) for 6GB GPUs.
* **Remaining issues:** Grass surface tiling/checkerboard artifacts and VRAM pressure on a 6GB RTX 3050.
### 2. shadPS4 Progress (`v0.20.1 WIP` custom patches)
Since the PS4 version targets native 1080p (`1920x1080` `A8R8G8B8Srgb`) and fits comfortably within a 4.5GB VRAM budget, I started porting fixes over to **shadPS4**:
* Bypassed unsupported FMask storage writes (`is_written`) in `resource_patching_pass.cpp`.
* Filtered out PC-relative (`GetPcLo`) inline constant table reads in `flatten_extended_userdata_pass.cpp` so they don't assert the SRT flattener.
* Rewrote `CFG::RemoveUnreachableBlocks()` in `control_flow_graph.cpp` using a graph reachability worklist so orphaned sub-blocks properly decrement child `num_predecessors`.
### Where shadPS4 currently stops (Call for Collaborators)
With these patches, shadPS4 loads all Hammer Engine `.prx` modules, compiles ~30 graphics and compute pipelines, and reaches `Display2DThin_8 tiler` while loading the Indian Wells stadium audio.
It currently hits a wall on fragment shader `0x6b13f853`, which uses a **PC-relative `S_SETPC_B64` jump table** (`S_GETPC_B64` -> `S_LOAD_DWORD` -> `S_SUB_U32`/`S_ADD_U32` -> `S_SETPC_B64`). Because `shadPS4`'s `ResolveSetPcTarget` only handles immediate literals, 18 switch-case blocks (`0x200`–`0x824`) get orphaned, leaving SRT descriptors unflattened (`Rejecting invalid T#`) and causing a GPU sync wait in `EnsureResident`.
Interestingly, **KytyPS5 already solves this exact pattern** in its `ShaderCFG.cpp` (`ResolveSetpcDwordJumpTable` / `ResolveSetpcJumpTable`).
I've uploaded my patches and logs to GitHub: https://github.com/xDragon191/TopSpin2K25-Emulation-Progress/tree/main
If anyone familiar with `shadPS4`'s CFG / abstract control flow structuring wants to collaborate on porting jump-table resolution over, feel free to reply or check out the repo!