dm2-dungeon: expand text escape codes 29/30 via per-version tables #274

Merged
jqueuniet merged 0 commits from refs/pull/274/head into main 2026-07-19 08:37:22 +02:00
jqueuniet commented 2026-07-19 07:07:18 +02:00 (Migrated from codeberg.org)

Closes #270.

Escape codes 29/30 in the dungeon.dat text section are two-code escapes: the next 5-bit code indexes an expansion table carried by the engine binary. TextDatabase::text_at(offset, expansion) now expands them through per-version tables selected by the new dm2_dungeon::TextExpansion enum:

  • Escape 29 (identical in every recovered binary): indices 0–23 → rune-glyph font indices emitted as ax, 24–31 → digits 07.
  • Escape 30: Standard (DOS EN/DE/FR/Demo, Mac JP, Sega CD US; presumed for the packed-executable ports) = ? ! THE YOU ' …; MacUs (Mac US/FR/Demo) truncates THE /YOU to a single space. Single-byte entries are font indices decoded intent-faithfully (0x79 renders blank due to the DM/CSB font bug but is documented as !).

Tables were recovered from the shipped executables (offsets documented in docs/formats/dungeon-dat.md § "Text data") and cross-checked against DMWEB's DM/CSB tables; glyph identity verified by rendering the 5×6 font from the DOS-EN retail and beta archives.

Expansion is decode-side only — parse/to_bytes are untouched and all 16 fixture round-trips stay byte-for-byte. Pinned tests cover DOS-EN retail (escape-29 digit strings, the SNAKE STAFF recipe) and the DOS 0.9 beta (the one port that renders this section in-game: "BE WARNED! …" via (30, 1), "NO WATER?" via (30, 0)). Callers in dm2-saves (inscriptions) and dm2-cli (extract JSON) pass Standard.

Gates: cargo fmt --all -- --check, cargo clippy --workspace --all-targets, and cargo test --workspace all exit 0 locally (fixture tests exercised for real; CI skips them per policy).

Closes #270. Escape codes 29/30 in the dungeon.dat text section are two-code escapes: the next 5-bit code indexes an expansion table carried by the engine binary. `TextDatabase::text_at(offset, expansion)` now expands them through per-version tables selected by the new `dm2_dungeon::TextExpansion` enum: - **Escape 29** (identical in every recovered binary): indices 0–23 → rune-glyph font indices emitted as `a`–`x`, 24–31 → digits `0`–`7`. - **Escape 30**: `Standard` (DOS EN/DE/FR/Demo, Mac JP, Sega CD US; presumed for the packed-executable ports) = `? ! THE YOU ' …`; `MacUs` (Mac US/FR/Demo) truncates `THE `/`YOU ` to a single space. Single-byte entries are font indices decoded intent-faithfully (`0x79` renders blank due to the DM/CSB font bug but is documented as `!`). Tables were recovered from the shipped executables (offsets documented in `docs/formats/dungeon-dat.md` § "Text data") and cross-checked against DMWEB's DM/CSB tables; glyph identity verified by rendering the 5×6 font from the DOS-EN retail and beta archives. Expansion is decode-side only — `parse`/`to_bytes` are untouched and all 16 fixture round-trips stay byte-for-byte. Pinned tests cover DOS-EN retail (escape-29 digit strings, the SNAKE STAFF recipe) and the DOS 0.9 beta (the one port that renders this section in-game: "BE WARNED! …" via `(30, 1)`, "NO WATER?" via `(30, 0)`). Callers in `dm2-saves` (inscriptions) and `dm2-cli` (extract JSON) pass `Standard`. Gates: `cargo fmt --all -- --check`, `cargo clippy --workspace --all-targets`, and `cargo test --workspace` all exit 0 locally (fixture tests exercised for real; CI skips them per policy).
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jqueuniet/dm2-tools!274
No description provided.