Skip to content

Commit 8109a5f

Browse files
Kim2091claudeNight1099
authored
Replace FFP Template code with modified remix-comp-base (Ekozmaster#14)
* Initial remix-comp implementation * Clean up codebase * Fix missing dll * Integrate tracer into remix-comp * Refine prompts * Clean up build process * Update build.bat * Make build.bat even easier * Overhaul remix-comp workflow and fix FFP bugs - Overhaul patch workflow templates and prompt files - Fix tracer re-enabling FFP unconditionally after capture (now saves/restores) - Parse [FFP.Registers] INI section (was ignored due to static constexpr) - Add on-demand diagnostic capture from ImGui with per-category log controls - Wire diagnostics hooks into D3D9 proxy (Present, BeginScene, SetVS*, draw calls) - Add Diagnostics tab to ImGui overlay with capture controls and category toggles - Fix analyze.py format spec for non-float values Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix logging issues * Clean up logging system * Various bug & QoL fixes * Fix more bugs, skill files, prompts * Add pointers to dx9 skill so agents know about if it hasnt triggerd * move remix-comp-context.md rule to a refernce * Optimize context usage for prompts + skills * Potentially reduce context usage * Split out drawcall context * New DX9 RE scripts * Clarify common FFP conversion issues in skill files * Move ffp registers from config to hardcoded * Convert from asi to proxy * Rename remix-comp to remix-comp-proxy, enhance tracer Rename the project from remix-comp to remix-comp-proxy across all source files, build scripts, INI config, skill/prompt files, and documentation. The directory, INI filename, and all internal references are updated; upstream remix-comp-base references are preserved. Tracer enhancements: - External trigger file support: on_present() polls for dxtrace_capture.trigger so the Python CLI works with the proxy - Delayed capture with configurable countdown (0-30s) via ImGui - Category-based capture filtering (draw calls, state, shaders, textures, transforms, vertex setup, resources, scene, getters, misc) - Updated About tab to reflect current contributors and features * Replace berry icon with optional custom icon Remove xoxor4d's berry.png branding — this is a separate project now and we don't want users directing support requests to him for our work. His contributions are still credited in the About tab and README. The icon system still works: drop any icon.png into rtx_comp/textures/ and it shows in the About tab. Nothing loads by default. * Fix FFP toggle bug * Move ini file location (next to DLL), enhance logging warnings * distinguished the remix-comp-proxy template (copied per-game) from shared tooling, gave real paths to run in examples, remove lines counts (self discoverable) * bring other agents into sync * Fix correctness bugs, finish DX script migration, harden proxy Critical fixes: - D3DRS/D3DBLEND enum values in dx9_common.py aligned to SDK header - CreateDevice HRESULT check before wrapping device pointer - Missing CS_MODE_64 import in xrefs.py - dataflow _get_mem returns Unknown when index register present - asi_patcher validates addr >= base before computing RVA Important fixes: - Migrate 5 DX scripts off duplicated internals onto dx9_common - Null p_this in module destructors (renderer, imgui, diagnostics, skinning) - backward_slice_cfg: CFG-aware slice that follows predecessor edges - Remove unused g_installed_signature_patches externs from comp.hpp - Split find_matrix_registers main() into discrete phases - cfg.py _resolve_switch accepts scale==8 for x64 tables - init_log_file uses std::call_once for thread safety - Two new dataflow tests: cross-block slice and branch-merge paths Design notes: document delegation hub, threading model, FFP suppression, x64 pointer truncation hazards. * Add scripts to assist with skinning conversion * Bug fixes for skinning scripts --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Ben Gregg <ben10gregg@gmail.com>
1 parent bf5b013 commit 8109a5f

435 files changed

Lines changed: 238236 additions & 4796 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/CLAUDE.md

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
11
# Vibe Reverse Engineering -- Claude Code Instructions
22

3+
## Read-Only Templates
4+
5+
These directories are **shared tooling and templates**. Do not modify them for game-specific work — per-game changes go in `patches/<GameName>/`.
6+
7+
- `rtx_remix_tools/dx/remix-comp-proxy/` — proxy framework **template** (copied per-game)
8+
- `rtx_remix_tools/dx/scripts/` — DX9 analysis scripts (shared tooling)
9+
- `retools/` — static analysis toolkit (shared tooling)
10+
- `livetools/` — Frida-based dynamic analysis (shared tooling)
11+
- `graphics/` — DX9 tracer framework (shared tooling)
12+
13+
**Per-game work goes in `patches/<GameName>/`.** When starting a new game, copy `rtx_remix_tools/dx/remix-comp-proxy/` (excluding `build/`) to `patches/<GameName>/` and edit the copy. If the user says "edit remix-comp-proxy code" without specifying, ask whether they mean the template or a game copy.
14+
15+
Shared tooling can be modified to improve the tools themselves — just not for game-specific customization.
16+
17+
---
18+
319
## Delegation Rule
420

521
**Never run static analysis tools directly.** Delegate to a `static-analyzer` subagent. Only exceptions — run these inline:
622
- `sigdb.py identify` / `fingerprint` (single-function ID, <5s)
7-
- `context.py assemble` / `postprocess` (context gathering, <5s)
23+
- `context.py assemble` / `postprocess` (context gathering, <5s; use `--no-dataflow` on large functions)
824
- `dataflow.py --constants` / `--slice` (single-function analysis, <5s)
925
- `readmem.py` (single typed read from PE, <5s)
1026
- `asi_patcher.py build` (build step, not analysis)
@@ -72,9 +88,20 @@ Each file reads as if it was always designed this way. Comments guide the next d
7288

7389
---
7490

91+
## DX9 FFP Porting
92+
93+
When working on any of the following — invoke the **`dx9-ffp-port` skill** immediately before starting:
94+
- Editing `renderer.cpp`, `ffp_state.cpp`, `remix-comp-proxy.ini`, or draw routing logic
95+
- Porting a game for RTX Remix / fixed-function pipeline
96+
- Diagnosing VS constant registers, vertex declarations, matrix mapping, skinning
97+
- Building, deploying, or iterating on a remix-comp-proxy patch (`build.bat`, `diagnostics.log`, ImGui F4)
98+
99+
---
100+
75101
## References
76102

77-
- **Tool catalog, decision guide, and caveats**: @.claude/rules/tool-catalog.md
103+
- **Tool dispatch (which tool, run vs delegate)**: @.claude/rules/tool-dispatch.md
104+
- **Full tool syntax tables and caveats**: `.claude/references/tool-catalog.md` (read on demand, not auto-loaded)
78105
- **Subagent workflow and delegation rules**: @.claude/rules/subagent-workflow.md
79-
- **DX9 FFP proxy porting for RTX Remix**: `/dx9-ffp-port` skill
80-
- **Frida-based dynamic analysis**: `/dynamic-analysis` skill
106+
- **DX9 FFP proxy porting for RTX Remix**: `.claude/skills/dx9-ffp-port/SKILL.md` (invoke `dx9-ffp-port` skill, not auto-loaded)
107+
- **Frida-based dynamic analysis**: `/dynamic-analysis` skill
Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ These are fast (<5s) and allowed inline:
3131

3232
Everything else. Tell the subagent WHAT you need, not HOW to run it — it has the full tool catalog.
3333

34+
**D3D9-specific questions?** Check the DX analysis scripts section below first — they're faster and more targeted than general retools for D3D API usage, device calls, shader constants, and vertex formats.
35+
3436
- "What does this function do?" → decompile + callgraph + xrefs + dataflow --constants
3537
- "Who calls this function?" → xrefs or callgraph --up
3638
- "What does this function call?" → callgraph --down (add --indirect for vtable calls)
@@ -57,6 +59,31 @@ Everything else. Tell the subagent WHAT you need, not HOW to run it — it has t
5759
- "How many draw calls happen?" → `livetools dipcnt`
5860
- "Who writes to this memory address?" → `livetools memwatch`
5961

62+
### DX analysis scripts (main agent, fast first-pass)
63+
64+
These are targeted D3D9 scanners under `rtx_remix_tools/dx/scripts/`. They run in seconds and surface D3D-specific patterns that general-purpose retools would take longer to find. **Use these BEFORE retools** when the question is about D3D9 API usage, device calls, shaders, or vertex formats. Run as `python rtx_remix_tools/dx/scripts/<script> <args>`.
65+
66+
- "How does the game use D3D9?" → `find_d3d_calls.py <game.exe>` (imports + call sites)
67+
- "Which VS constant registers hold matrices?" → `find_vs_constants.py <game.exe>` (SetVertexShaderConstantF call sites with register/count)
68+
- "Which PS constant registers are used?" → `find_ps_constants.py <game.exe>` (SetPixelShaderConstantF/I/B with register/count)
69+
- "Where does the game call the D3D device?" → `find_device_calls.py <game.exe>` (vtable call patterns + device pointer refs)
70+
- "What render states does the game set?" → `find_render_states.py <game.exe>` (SetRenderState args: culling, blending, depth, fog)
71+
- "How does the texture pipeline work?" → `find_texture_ops.py <game.exe>` (SetTexture stages, TSS ops, sampler filter/address modes)
72+
- "Which transform types are used?" → `find_transforms.py <game.exe>` (SetTransform: World, View, Projection, Texture)
73+
- "What surface formats does the game create?" → `find_surface_formats.py <game.exe>` (CreateTexture/RT/DS format extraction)
74+
- "Does the game use state blocks?" → `find_stateblocks.py <game.exe>` (state block creation/recording/apply)
75+
- "Does the game use FVF or vertex declarations?" → `decode_fvf.py <game.exe>` (FVF bitfield decoding)
76+
- "What vertex formats does the game use?" → `decode_vtx_decls.py <game.exe> --scan` (vertex declarations, detects skinning)
77+
- "Are shaders embedded in the binary?" → `find_shader_bytecode.py <game.exe>` (shader bytecode extraction with version/size)
78+
- "What's the FFP vs shader draw call mix?" → `classify_draws.py <game.exe>` (draw call classification by state context)
79+
- "Which registers are View/Proj/World?" → `find_matrix_registers.py <game.exe>` (CTAB names + frequency heuristics + layout suggestion)
80+
- "D3DX constant table or vtable calls?" → `find_vtable_calls.py <game.exe>` (D3DX CTAB usage + D3D9 vtable calls)
81+
- "Does the game have skinned meshes? What config does the proxy need?" → `find_skinning.py <game.exe>` (skinned decls, bone palettes, blend states, suggested INI)
82+
- "Does the game use FFP vertex blending?" → `find_blend_states.py <game.exe>` (D3DRS_VERTEXBLEND + INDEXEDVERTEXBLENDENABLE + WORLDMATRIX)
83+
- "Map all D3D calls in a code region" → `scan_d3d_region.py <game.exe> 0xSTART 0xEND`
84+
85+
These are fast first-pass scanners — they surface candidate addresses. Follow up with `retools` (decompiler, xrefs) and `livetools` (trace, bp) for deep analysis of the addresses they find.
86+
6087
### dx9tracer (main agent for capture, delegate analysis)
6188

6289
- "Trigger a frame capture" → main agent: `python -m graphics.directx.dx9.tracer trigger`
@@ -162,15 +189,16 @@ python -m livetools status # check connection
162189

163190
A proxy DLL that intercepts all 119 `IDirect3DDevice9` methods, capturing every call with arguments, backtraces, pointer-followed data (matrices, constants, shader bytecodes), and in-process shader disassembly (via the game's own d3dx9 DLL). Outputs JSONL for offline analysis.
164191

165-
**Architecture**: Python codegen (`d3d9_methods.py`) → C proxy DLL (`src/`) → JSONL → Python analyzer (`analyze.py`). The proxy chains to the real d3d9 (or another wrapper) and adds near-zero overhead when not capturing.
192+
**Architecture**: Python codegen (`d3d9_methods.py`) → C proxy DLL (`src/`) or C++ remix-comp-proxy dispatch (`tracer_dispatch.inc`) → JSONL → Python analyzer (`analyze.py`). The standalone proxy chains to the real d3d9 (or another wrapper) and adds near-zero overhead when not capturing. The remix-comp-proxy integrated tracer records from within the dinput8.dll hook.
166193

167194
### Setup and Capture
168195

169196
```
170-
python -m graphics.directx.dx9.tracer codegen -o d3d9_trace_hooks.inc # regenerate C hooks
171-
cd graphics/directx/dx9/tracer/src && build.bat # build proxy DLL
197+
python -m graphics.directx.dx9.tracer codegen -o d3d9_trace_hooks.inc # C hooks (standalone proxy)
198+
python -m graphics.directx.dx9.tracer codegen -f cpp -o tracer_dispatch.inc # C++ dispatch (remix-comp module)
199+
cd graphics/directx/dx9/tracer/src && build.bat # build standalone proxy DLL
172200
# Deploy d3d9.dll + proxy.ini to game directory
173-
python -m graphics.directx.dx9.tracer trigger --game-dir <GAME_DIR> # trigger capture (3s countdown)
201+
python -m graphics.directx.dx9.tracer trigger --game-dir <GAME_DIR> # trigger capture (3s countdown)
174202
```
175203

176204
**proxy.ini** settings: `CaptureFrames=N` (frames to record), `CaptureInit=1` (capture boot-time calls like shader creation), `Chain.DLL=<wrapper.dll>` (chain to another d3d9 wrapper, or leave empty for system d3d9).
@@ -210,6 +238,31 @@ All analysis: `python -m graphics.directx.dx9.tracer analyze <JSONL> [OPTIONS]`
210238
| `--filter EXPR` | Filter records by field (e.g. `frame==0`, `slot==83`) |
211239
| `--export-csv FILE` | Export raw records to CSV |
212240

241+
## DX Analysis Scripts (`rtx_remix_tools/dx/scripts/`) -- fast D3D9 scanners
242+
243+
Targeted first-pass scanners for D3D9 games. Run from repo root. Output is candidate addresses and patterns — always follow up with retools/livetools for confirmation.
244+
245+
| Script | What it surfaces | Example |
246+
|--------|-----------------|---------|
247+
| `find_d3d_calls.py $B` | D3D9/D3DX imports and call sites | `python rtx_remix_tools/dx/scripts/find_d3d_calls.py game.exe` |
248+
| `find_vs_constants.py $B` | `SetVertexShaderConstantF` call sites with register/count args | `python rtx_remix_tools/dx/scripts/find_vs_constants.py game.exe` |
249+
| `find_ps_constants.py $B` | `SetPixelShaderConstantF/I/B` call sites with register/count args | `python rtx_remix_tools/dx/scripts/find_ps_constants.py game.exe` |
250+
| `find_device_calls.py $B` | Device vtable call patterns and device pointer refs | `python rtx_remix_tools/dx/scripts/find_device_calls.py game.exe` |
251+
| `find_render_states.py $B` | SetRenderState arguments decoded by category (culling, blending, depth, fog) | `python rtx_remix_tools/dx/scripts/find_render_states.py game.exe` |
252+
| `find_texture_ops.py $B` | Texture pipeline: SetTexture stages, TSS color/alpha ops, sampler states | `python rtx_remix_tools/dx/scripts/find_texture_ops.py game.exe` |
253+
| `find_transforms.py $B` | SetTransform/MultiplyTransform types (World, View, Projection, Texture) | `python rtx_remix_tools/dx/scripts/find_transforms.py game.exe` |
254+
| `find_surface_formats.py $B` | CreateTexture/RenderTarget/DepthStencil D3DFMT extraction | `python rtx_remix_tools/dx/scripts/find_surface_formats.py game.exe` |
255+
| `find_stateblocks.py $B` | State block creation, recording, and apply patterns | `python rtx_remix_tools/dx/scripts/find_stateblocks.py game.exe` |
256+
| `decode_fvf.py $B` | FVF bitfield decode from SetFVF calls (or `--decode 0xNNN` manual) | `python rtx_remix_tools/dx/scripts/decode_fvf.py game.exe` |
257+
| `find_vtable_calls.py $B` | D3DX constant table usage and D3D9 vtable calls | `python rtx_remix_tools/dx/scripts/find_vtable_calls.py game.exe` |
258+
| `decode_vtx_decls.py $B --scan` | Vertex declaration formats (BLENDWEIGHT/BLENDINDICES = skinning) | `python rtx_remix_tools/dx/scripts/decode_vtx_decls.py game.exe --scan` |
259+
| `find_shader_bytecode.py $B` | Embedded shader bytecode extraction (version, size, `--dump-dir`) | `python rtx_remix_tools/dx/scripts/find_shader_bytecode.py game.exe` |
260+
| `classify_draws.py $B` | Draw call classification by state context (FFP/shader/hybrid %) | `python rtx_remix_tools/dx/scripts/classify_draws.py game.exe` |
261+
| `find_matrix_registers.py $B` | Identify View/Proj/World registers (CTAB + frequency + layout suggestion) | `python rtx_remix_tools/dx/scripts/find_matrix_registers.py game.exe` |
262+
| `find_skinning.py $B` | Consolidated skinning analysis: skinned decls, bone palettes, blend states, suggested INI | `python rtx_remix_tools/dx/scripts/find_skinning.py game.exe` |
263+
| `find_blend_states.py $B` | D3DRS_VERTEXBLEND + INDEXEDVERTEXBLENDENABLE + WORLDMATRIX transforms | `python rtx_remix_tools/dx/scripts/find_blend_states.py game.exe` |
264+
| `scan_d3d_region.py $B 0xSTART 0xEND` | Map all D3D9 vtable calls in a code region | `python rtx_remix_tools/dx/scripts/scan_d3d_region.py game.exe 0x401000 0x500000` |
265+
213266
## Tool Caveats
214267

215268
### `rtti.py` -- MSVC RTTI only

0 commit comments

Comments
 (0)