--- name: dkc1-tools description: Working guide to the DKC1Recomp debugging/verification tool suite — builds, hosts, routes, detectors, regression gates, and the code atlas. Use when debugging widescreen/gameplay issues, running evidence captures, or navigating the disassembly knowledge sources. --- # DKC1Recomp tool suite This repo is a **static recompilation** of Donkey Kong Country (SNES, USA v1.0) with **host-side widescreen presentation**. Everything here follows one contract: game logic stays byte-for-byte stock; widescreen is presentation only (margins, camera bias, wider object *visibility* — never changed *simulation*). The supported ROM is headerless USA v1.0, sha256 `fa8cacf5bbfc39ee6bbaa557adf89133d60d42f6cf9e1db30d5a36a469f74d15` (never commit ROMs, save states, captures, or generated game code). ## ⚠ Do not confuse the two widescreen efforts There were TWO widescreen projects. Only this repo is current: | | **This repo (current)** | **Legacy emulator hack (reference only)** | |---|---|---| | Approach | Host-side presentation over stock logic | ROM patched with asar (game code modified) | | Location | `C:\Users\ellio\Documents\GitHub\DKC1Recomp` | in-repo consolidated copy: `reference/legacy-widescreen/` (canonical for reading); originals at `D:\Downloads\DKLR\DKC-Widescreen-358x224\`, `D:\Downloads\DKLR\DKC_Widescreen_358x224*.sfc` (+398 variants, MSU1 builds), `reference/disassembly/DKC1/Custom\Patches\Widescreen_358x224.asm`, `RomMap\ROM_Map_HACK_*` | | Use for | All new work | Prior-art reference: its worklog documents bug classes (OAM X-high wrap, exit-boundary coverage, section controllers) that inspired our detectors. **Never copy its code or compare its patched-ROM behavior as "stock".** | If a file mentions `358x224`, asar patching, or lives under `reference/legacy-widescreen/` or under `D:\Downloads\DKLR\` outside the disassembly's clean sources, it is the legacy effort. (Careful: the RECOMP host renders 342x224 / 398x224 — a `398x224` mention alone does not mean legacy; `358x224` always does.) ## Repo map - `runner/` — host + adapters (`dkc1_game.c` presentation glue, `win32_host.c` visible debugger, `headless_main.c`, detectors) - `snesrecomp/` — engine submodule (**fork: elliotttate/snesrecomp**; `runner/src/snes/ws_shadow.c` is the widescreen margin cache) - `recomp/*.cfg` — recompiler configs incl. **dispatch contracts** (runtime-proven indirect-call target sets). Fixes for recompilation-correctness bugs go HERE, then regenerate. - `generated/` — machine-emitted game C. **Never hand-edit or commit.** - `tools/` — the analysis/verification suite (see `TOOLS.md` here) - `recipes/*.dks` — deterministic input routes; `contracts/*.json` — regression contracts; `docs/KNOWN_ISSUES.json` + `docs/DASHBOARD.md` - Build: `build_host_tools.bat` (isolated tool-session build → `build/dkc1_headless_tools.exe`, `dkc1_desktop_tools.exe`, `dkc1_layer_capture.exe`), `build_host.bat` (primary), `build_host_noadapt.bat` (no-widescreen-adapter oracle). All embed build identity (git commit shown in window title / state sidecars). ## Where fixes go (never into decompiled/generated code) 1. **Presentation/widescreen bug** → `ws_shadow.c`, `dkc1_game.c`/ `dkc1_video.c` adapters, or the hosts. 2. **Recomp-correctness bug** (wrong dispatch, miscompile) → `recomp/*.cfg`, regenerate. 3. To understand intent, use the knowledge sources via **`python tools/atlas.py `** — one query joins IDA's curated names/descriptions, disassembly+pseudocode listing, the live recompiled variant, dispatch contracts, WRAM labels, and known-issue mentions. Debug output (verdicts, click reports, trace PCs) pastes straight in. ## Evidence discipline (non-negotiable) - Detectors/taps are **default-off** (env-gated); arming one must never change emulation (A/B hash-identical). - Watch **transitions, not dumps**; match actors by **source record ($15FD)**, never by mutable pool slot. - Routes are **predicate-driven** (`wait`/`pulse` on WRAM), resolved to fixed input schedules before differential comparison. - A fix is verified only by **3× byte-identical replays** including end-of-run framebuffer/audio hashes (`tools/run_regression.py` enforces this plus ratcheted integrity budgets). - Event flags like `$1595` are consumed same-frame — end-of-frame WRAM dumps cannot see them; watch durable effects (state, timers) instead. - WRAM semantics: see `tools/atlas.py wram:`; key addresses are in `TOOLS.md`. ## Typical workflows **Widescreen bug of ANY kind:** start at **`docs/WIDESCREEN_PLAYBOOK.md`** — the symptom-first decision guide: five entry points, the eight-rung localization ladder (pixel → provenance → layers → policy → stock-vs-wide → reverse_watch → atlas/irview/slice → oracle), the verdict/detector → owner table for every invariant-monitor verdict, fix-ownership routing incl. DKC1_REPLACE, the full verification ladder, and worked examples from docs/KNOWN_ISSUES.json. **"Something looks wrong on screen" (visible host):** click the pixel — the panel reports world coord, tile, provenance, last writer, OAM entries, nearest actor. F9 exports a repro bundle (rolling inputs + states + memory + auto layer-isolation captures). With `DKC1_AUTO_EXPORT=1` + `DKC1_FLIGHT_RECORDER=1`, any integrity detector exports automatically and appends a post-failure tail. **Reproduce + diagnose headlessly:** run a recipe with taps armed, e.g. `DKC1_WIDESCREEN=1 DKC1_SCRIPT=recipes/route_jungle.dks DKC1_WS_TRACE=t.jsonl build\dkc1_headless_tools.exe 9000`, then the matching analyzer (`analyze_ws_trace.py`, `lifecycle_by_source.py`, `analyze_retrodiction.py`…). **Gate a fix:** `python tools/run_regression.py contracts/jungle-entry.json --exe build/dkc1_headless_tools.exe --rom --json-out build/regression/results.json`, then `python tools/make_dashboard.py`. Sweep everything: `python tools/level_sweep.py --rom `. **Pin a new bug:** add it to `docs/KNOWN_ISSUES.json` with a repro; ratchet its detector count in the contract `budgets`; tighten to 0 when fixed. Full catalog of all 47 tools, every env var, route DSL, and debug keys: **`TOOLS.md` in this folder.** For battery/in-game saves, use `verify_ingame_saves.py` and `docs/INGAME_SAVES.md`. Desktop hosts now persist SRAM: isolate their user directory (SDL: `DKC1_USER_DIR`; legacy Win32: working directory). Headless tests retain explicit SRAM input and never implicitly update a battery file. For the native iPhone/iPad frontend, read `docs/IOS.md`. `build_ios.sh` builds the app; `tools/verify_ios_simulator.py` compares three runs of the existing headless runner inside the simulator app against three desktop runs. `DKC1_IOS_DIAGNOSTICS` is a default-off build option. Mobile landscape chooses a bounded native source width (418 on the connected phone) with fixed SNES pixel proportions. Read `docs/IOS.md` for the limited validated scene scope. The same default-off diagnostic build supports `--verify-graphics`, reusing the native Metal output/cache oracle, plus paused upscale-preview captures. See `TOOLS.md` for source-frame inputs, output hashes and UI probe limits.