diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 3293157c..62f13e49 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -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 diff --git a/docs/BIOS_SELECTION.md b/docs/BIOS_SELECTION.md index 372e366c..9847630d 100644 --- a/docs/BIOS_SELECTION.md +++ b/docs/BIOS_SELECTION.md @@ -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: diff --git a/docs/BUILDING.md b/docs/BUILDING.md index d19ad07a..ede5c1ee 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -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 diff --git a/docs/FEATURES.md b/docs/FEATURES.md index 94bc5afd..a64de402 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -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/…/_.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, `//-/cg_/_.dll`.)* + --- ## Tomba overlay map (known) diff --git a/docs/STRING_TRANSLATION.md b/docs/STRING_TRANSLATION.md index e0d665cb..aee205e2 100644 --- a/docs/STRING_TRANSLATION.md +++ b/docs/STRING_TRANSLATION.md @@ -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 diff --git a/docs/config_schema.md b/docs/config_schema.md index 261e27ba..bac8ef78 100644 --- a/docs/config_schema.md +++ b/docs/config_schema.md @@ -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