docs: correct six statements that contradict the code

These are not stale-by-omission; each asserts something the code does not do,
and each was verified against the implementation before editing.

docs/BUILDING.md
  - PSX_ENABLE_VULKAN was documented "off by default" in two places. It
    defaults ON (runtime/runtime.cmake:778). Corrected both, and noted that
    the build option being ON does not make Vulkan the runtime renderer.
  - Removed the PSX_BUILD_COSIM row: no option() for it exists anywhere in
    the tree. Replaced with PSX_NETPLAY, which is real (runtime.cmake:194).
  - Step 2 (regenerate BIOS) was labelled "(Optional)". It is required before
    the first runtime build: step 3 configures psx-runtime from
    generated/OpenBIOS_full.c and fails at configure time without it
    ("Cannot find source file" / "No SOURCES given to target"). Regenerating
    the *retail* backend remains genuinely optional; that distinction is now
    explicit.
  - "This repository has no required git submodules" contradicted .gitmodules
    (recomp-ui, lib/recomp-net) and README's --recurse-submodules clone.
    Replaced with a table of which submodule each build option needs.

docs/ARCHITECTURE.md
  - Same Vulkan default correction.
  - Removed the claim that BIOS and game configs merge with "game wins on
    scalar keys". No such merge exists: load_bios_config is called only from
    the recompiler front-ends (main_bios.cpp, and main_psx.cpp solely to build
    the BiosAddressModel) and never from runtime/src/main.cpp.

docs/config_schema.md
  - Same merge claim, stated in more detail. Replaced with the actual runtime
    precedence: env > CLI > settings.toml > game.toml > compiled default.

docs/STRING_TRANSLATION.md
  - Header said "SPEC (design only - no implementation yet)" above a shipped
    feature: runtime/src/text_xlate.cpp (~970 lines), initialised from
    main.cpp, configured via [localization]. Marked IMPLEMENTED and added the
    public entry points.

docs/FEATURES.md
  - Layer A (dynamic DLL overlay loading) was headed "SHELVED". It is the live
    production dispatch path: overlay_loader.c is ~4,400 lines with 15
    LoadLibrary sites, last modified 2026-07-26, and COMPILING_OVERLAYS.md
    documents shipping the resulting .dll shards in releases. Added a status
    banner and kept the original account as history, since the CRC-keying
    dead ends it records are still worth reading.

docs/BIOS_SELECTION.md
  - Claimed the identity gate checks "size, CRC32, SHA-256". It checks size
    and CRC32 only (bios_backend_for_file, main.cpp:1088-1089); image_sha256
    is recorded metadata and never enters the accept/reject decision.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matthew Stanley
2026-07-27 10:19:36 -07:00
parent 45408d60f1
commit 9ad18ded0d
6 changed files with 104 additions and 21 deletions
+12 -4
View File
@@ -123,7 +123,10 @@ Three GPU backends behind one interface:
- **OpenGL** — GPU-authoritative VRAM/FBO renderer, the default; moves
rasterization and supersampling onto the GPU. Falls back to software if GL
init fails. (See [`docs/internal/GL_RENDERER_HANDOFF.md`](internal/GL_RENDERER_HANDOFF.md).)
- **Vulkan** — experimental, off by default (`PSX_ENABLE_VULKAN=OFF`).
- **Vulkan** — experimental. The build option `PSX_ENABLE_VULKAN` defaults **ON**
(compiled when the SDK tools are present), but it is not the runtime default
renderer: selecting it also requires the game to offer Vulkan and the user to
request it, otherwise the runtime falls back to OpenGL.
Widescreen (a genuine wider GTE FOV, not a stretch) is opt-in and gen-time; see
[`WIDESCREEN.md`](../WIDESCREEN.md) and
@@ -146,9 +149,14 @@ backend against the interpreter. See
## Configuration
Every process has a **BIOS config**; a game adds a **game config** (`game.toml`),
and the two are merged (game wins on scalar keys; program blocks and generated
dispatch tables are additive). Full schema:
A game is configured by its **game config** (`game.toml`). A **BIOS config**
(`bios/*.toml`) describes a BIOS image's identity and address model.
The two are **not merged.** The BIOS config is consumed only by the recompiler
at build time (`psxrecomp-bios`, and `psxrecomp-game` for the address model);
the shipping runtime never loads it — `runtime/src/main.cpp` contains no call to
`load_bios_config`. `[runtime]` keys therefore take effect only from `game.toml`,
`settings.toml`, the CLI, and the environment. Full schema:
[`docs/config_schema.md`](config_schema.md).
## Where to go next
+9 -4
View File
@@ -44,10 +44,15 @@ OpenBIOS. The compiled-in code is generated *from that exact image*, so a
different dump — SCPH-101, SCPH-5552, a bad rip — cannot be substituted: the
recompiled code would execute against data it does not match, and crash.
Every build therefore checks the identity (size, CRC32, SHA-256) of a chosen
BIOS before using it, and says which image it expects if the check fails. This
is not DRM and not a preference; it is the difference between running and
wild-jumping.
Every build therefore checks the identity of a chosen BIOS before using it, and
says which image it expects if the check fails. This is not DRM and not a
preference; it is the difference between running and wild-jumping.
The acceptance gate compares **file size and CRC32** against each linked
backend's recorded identity (`bios_backend_for_file` in `runtime/src/main.cpp`).
A SHA-256 is also recorded per image (`image_sha256` in
`runtime/include/psx_bios_image.h`) and is surfaced for provenance and bug
reports, but it is **not** part of the accept/reject decision.
If a chosen BIOS does not match:
+29 -7
View File
@@ -36,19 +36,33 @@ project ships no game data.
| **TinyCC (TCC) 0.9.27** | Not in this repo — downloaded at release-packaging time and bundled beside the game exe in `overlay_toolchain/`. | Toolchain-free overlay compilation for players (run as a subprocess) |
| **Python 3** | System (development) or an embedded copy bundled in releases | Runs `tools/compile_overlays.py` in the overlay pipeline |
| **OpenGL** | System (`opengl32` on Windows; `find_package(OpenGL)` elsewhere) | The GL renderer |
| **Vulkan** | Headers only, optional, **off by default** (`PSX_ENABLE_VULKAN=OFF`); loaded dynamically via SDL. Shader compilation needs `glslc` from the Vulkan SDK. | The experimental Vulkan renderer |
| **Vulkan** | Headers only, **on by default** (`PSX_ENABLE_VULKAN=ON`) — built when the SDK tools are available, otherwise skipped; loaded dynamically via SDL. Shader compilation needs `glslc` from the Vulkan SDK. Pass `-DPSX_ENABLE_VULKAN=OFF` to exclude it. | The experimental Vulkan renderer |
Developers building overlays locally just need `gcc` on `PATH` (the `gcc` tier);
the bundled `tcc` matters only for end-user release packages.
### Get the source
This repository has no required git submodules:
This repository has two submodules, **neither of which is required** for the
recompiler and runtime builds described below:
| Submodule | Needed when |
|---|---|
| `recomp-ui` | `-DPSX_RECOMP_UI=ON` (the launcher UI). Configure **fails** with a `FATAL_ERROR` if this is ON and the submodule is absent. |
| `lib/recomp-net` | `-DPSX_NETPLAY=ON` (netplay). |
A plain clone is enough to build the recompiler and the runtime:
```sh
git clone https://github.com/mstan/psxrecomp.git
```
Add `--recurse-submodules` if you intend to build the launcher or netplay:
```sh
git clone --recurse-submodules https://github.com/mstan/psxrecomp.git
```
## Per-platform prerequisites
**Windows (MSYS2/MinGW — recommended for release parity):**
@@ -77,11 +91,19 @@ Two CMake trees: the recompiler (a tool) and the runtime (the engine).
cmake -S recompiler -B recompiler/build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build recompiler/build
# 2. (Optional) regenerate either statically recompiled BIOS backend.
# 2. REQUIRED before the first runtime build: generate a BIOS backend.
# Step 3 configures psx-runtime from generated/OpenBIOS_full.c. If generated/
# is empty, CMake does NOT fall back -- it fails at configure time with
# "Cannot find source file: .../generated/OpenBIOS_full.c" followed by
# "No SOURCES given to target: psx-runtime". Re-run this step whenever the
# recompiler emitter changes; a stale generated/ raises a fingerprint-mismatch
# warning from runtime.cmake.
#
# OpenBIOS can always be regenerated from the tracked image. Regenerating
# the retail backend requires your own bios/SCPH1001.BIN dump.
# the retail backend requires your own bios/SCPH1001.BIN dump and is genuinely
# optional -- OpenBIOS alone is enough to build and boot.
bash tools/regen_bios.sh --config bios/OpenBIOS.toml
bash tools/regen_bios.sh --config bios/SCPH1001.toml
bash tools/regen_bios.sh --config bios/SCPH1001.toml # optional, needs your own dump
# 3. Runtime → produces psx-runtime (BIOS-only for this repo)
cmake -S runtime -B runtime/build -G Ninja -DCMAKE_BUILD_TYPE=Release \
@@ -117,8 +139,8 @@ On Windows with MSVC or plain MinGW makefiles, swap `-G Ninja` for your generato
| `PSX_DEBUG_TOOLS` | ON for Debug/RelWithDebInfo, OFF for Release | TCP debug server + heartbeat + per-block recording |
| `PSX_STATIC_RUNTIME` | ON for MinGW Release | Self-contained exe (statically links SDL2 + libgcc/libstdc++) |
| `PSX_RECOMP_UI` | ON | Wire a downstream game's pinned recomp-ui launcher; set OFF for headless/generated builds |
| `PSX_ENABLE_VULKAN` | OFF | Build the experimental Vulkan renderer |
| `PSX_BUILD_COSIM` | OFF | Build the first-divergence co-sim oracle target |
| `PSX_ENABLE_VULKAN` | **ON** | Build the experimental Vulkan renderer when the SDK tools are present (skipped if not). Pass `OFF` to exclude it outright. |
| `PSX_NETPLAY` | OFF | Netplay support; requires the `lib/recomp-net` submodule |
## Build and run a game
+20 -1
View File
@@ -46,7 +46,22 @@ includes `generated/overlays.c` when it exists.
---
## Layer A — Dynamic DLL loading (runtime, SHELVED)
## Layer A — Dynamic DLL loading (runtime) — SHIPPED
> **Status corrected 2026-07-27.** This section described Layer A as "SHELVED".
> It is not: dynamic DLL overlay loading is the **live production dispatch
> path**. `runtime/src/overlay_loader.c` is ~4,400 lines with 15 `LoadLibrary`
> call sites and was last modified 2026-07-26;
> [`COMPILING_OVERLAYS.md`](COMPILING_OVERLAYS.md) documents building the
> `cache/…/<phys>_<crc>.dll` shards that ship inside release packages. The
> shelving described below was a real moment in the project's history, and the
> account of the CRC-keying dead ends is worth keeping — but it was superseded.
> Content-hash dispatch replaced the unstable CRC key, and the Load Game crash
> was subsequently root-caused rather than worked around.
>
> Read everything below this banner as **history**, not current state. For the
> current pipeline see [`COMPILING_OVERLAYS.md`](COMPILING_OVERLAYS.md) and
> [`AOT_OVERLAY_PLAN.md`](AOT_OVERLAY_PLAN.md).
### What it was supposed to do
@@ -100,6 +115,10 @@ but the Load Game crash was not diagnosed before shelving.
The infrastructure is complete. The blocker is code correctness, not plumbing.
*(Historical. All three items were subsequently resolved — the CRC key was
replaced by content-hash dispatch and the cache layout now carries an emitter
tag, `<game-id>/<gcc|tcc>/<os>-<arch>/cg<N>_<hash>/<phys>_<crc>.dll`.)*
---
## Tomba overlay map (known)
+23 -2
View File
@@ -1,7 +1,28 @@
# On-the-Fly String Translation / Localization for psxrecomp
**Status:** SPEC (design only — no implementation yet). Reusable framework
feature; **Tsumu Light (SLPS-02253)** is the first consumer.
**Status:** IMPLEMENTED and wired into the runtime. Reusable framework feature;
**Tsumu Light (SLPS-02253)** is the first consumer.
> This document was left marked "SPEC (design only — no implementation yet)"
> long after the feature shipped. It now reads as the design rationale behind
> working code, not a proposal. Where the prose below says "will" or "should",
> read it as describing what was built.
The implementation lives in `runtime/src/text_xlate.cpp` (~970 lines) behind
`runtime/include/text_xlate.h`:
| Entry point | Role |
|---|---|
| `text_xlate_init(project_root, language)` | Loads `translations/*.toml` under the project root; called from `runtime/src/main.cpp` at startup |
| `text_xlate_set_language(language)` | Re-applies the resolved language (launcher/settings selection) |
| `text_xlate_on_dispatch(cpu, target)` | Per-dispatch capture/substitution hook |
| `text_xlate_vram_upload(x, y, w, h)` | VRAM-upload interception path |
| `text_xlate_debug_json(subcmd, out, cap)` | TCP debug-server introspection |
Configuration is `[localization].language` (falling back to `[runtime]`), with
`[localization].languages` driving the launcher's language dropdown; see
`recompiler/src/config_loader.h`. Setting the language to `jp`, `off`, or empty
disables substitution while leaving capture running.
**Goal.** Let a Japanese-only PSX title be played in English (or any target
language) by **capturing the game's source strings from memory and substituting
+11 -3
View File
@@ -26,10 +26,18 @@ psx-runtime # boots BIOS discless
psx-runtime games/tomba/game.toml # boots BIOS, then loads game
```
When both are loaded, keys merge:
How the two configs relate:
- **Scalar keys (`debug_port`, `window_title`, `memcard_dir`, ...)**: game
wins if set, inherit from bios.toml otherwise. Shallow override.
- **Scalar keys (`debug_port`, `window_title`, `memcard_dir`, ...)**: these come
from `game.toml` only. There is **no BIOS→game inheritance.** An earlier
version of this document described a shallow override where the game won and
otherwise inherited from `bios.toml`; that merge was never implemented.
`load_bios_config` (`recompiler/src/config_loader.cpp`) is called only from the
recompiler front-ends — `main_bios.cpp`, and `main_psx.cpp` purely to build the
`BiosAddressModel` — and never from `runtime/src/main.cpp`. Setting a
`[runtime]` scalar in a BIOS toml has no effect on a game run.
Runtime precedence is: environment > CLI > `settings.toml` > `game.toml` >
compiled-in default.
- **`[program]` (BIOS) and `[game]` blocks**: NOT merged — they describe
different programs. Both are visible to the loader.
- **Generated dispatch tables and C output**: ADDITIVE. BIOS contributes