Map the French, German, Italian and Spanish releases' addresses (#84)
PRET builds none of these releases, so scripts/map-revision.mjs derives where each keeps the profile's labels from the 1.1 build: a bank-by-bank alignment, then the exact references RGBDS recorded while linking 1.1, read at the matching place in the release, each result checked against its bytes. All but 1-3 labels per release are found; the rest, in code the release changed, are -1 so reading them refuses. check:reference verifies the generated file when the ROMs are present. CrystalAssets now points the profile at the cartridge's addresses, and the releases' characters (from their own fonts) and two European text codes decode. The introduction and Mom's scene play in each language and every map sweeps as in English, but the releases stay refused until the logic they localize (units, word order, layouts) is ported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3c480a28f0
commit
627f87d8b5
17 files changed
+1202
-190
No files matched your search
+10
-2
@@ -4,7 +4,7 @@
|
||||
|
||||
Translate Crystal's Game Boy assembly systems into a native TypeScript game. The browser runs the translated engine; the user's original ROM supplies data and assets. The emulator is a separate development reference for checking behavior, never a dependency of the native release.
|
||||
|
||||
PRET's [disassembly](https://github.com/pret/pokecrystal) is pinned at `7a7881d0d62e0ddbd82dcf10e7116807487ac651`. Its `crystal11` build with RGBDS 1.0.3 was verified byte-for-byte against the supplied English US/Europe 1.1 ROM (SHA-1 `f2f52230b536214ef7c9924f483392993e226cfb`). Its `crystal` and `crystal_au` builds reproduce the retail English 1.0 (`f4cd194bdee0d04ca4eac29e09b8e4e9d818c133`) and Australian (`a0fc810f1d4e124434f7be2c989ab5b5892ddf36`) cartridges, which the same profile reads (board #84). Other languages require their own verified profiles.
|
||||
PRET's [disassembly](https://github.com/pret/pokecrystal) is pinned at `7a7881d0d62e0ddbd82dcf10e7116807487ac651`. Its `crystal11` build with RGBDS 1.0.3 was verified byte-for-byte against the supplied English US/Europe 1.1 ROM (SHA-1 `f2f52230b536214ef7c9924f483392993e226cfb`). Its `crystal` and `crystal_au` builds reproduce the retail English 1.0 (`f4cd194bdee0d04ca4eac29e09b8e4e9d818c133`) and Australian (`a0fc810f1d4e124434f7be2c989ab5b5892ddf36`) cartridges, which the same profile reads (board #84). The French, German, Italian and Spanish releases (SHA-1 `c055992b…`, `accb5842…`, `6cee05e5…`, `889a06fc…`) get their addresses from `scripts/map-revision.mjs`; the Japanese release is not covered.
|
||||
|
||||
The emulator-backed prototype is now at `/reference.html`. The default application is the native port. The previous plan to progressively modify an emulated ROM has been superseded.
|
||||
|
||||
@@ -556,7 +556,15 @@ The numbered sections below keep their full scope. Each one opens with a checkli
|
||||
- Saves: each cartridge keeps its own list (slots are keyed by the ROM's SHA-1), and a native backup from one of the others imports, with a "Cartridge" line in the preview; the three share every map, event and object, so nothing is converted. Cartridge `.sav` files have the same layout in all three.
|
||||
- Reference: `tests/reference-revisions.spec.ts` runs the cartridge's `BattleTowerText` on 1.1, 1.0 and the Australian rebuild for every trainer, six random values and the three texts. Tests: `tests/revisions.test.ts` (each cartridge is accepted under its name and recognised from its header, a changed byte is refused, the Battle Tower's trainer range), `tests/save-slots.test.ts` (a backup carried over between cartridges). The whole unit suite and the playthrough from the introduction to Red pass with `CRYSTAL_ROM_PATH` set to each rebuild (only the private CI downloader's 1.1 check is specific).
|
||||
- Not affected: 1.0's other differences, the Pokédex's `wPokedexStatus` sharing a byte with `wPrevDexEntryBackup` (it misplaces the cursor after a search result's entry; the search mode is not ported) and the mobile Stadium 2 tilemap.
|
||||
- Not supported: the French, German, Italian, Spanish and Japanese releases. PRET builds none of them, and no copy was available to verify a profile against; each needs its own addresses, character set and name lengths (the Japanese release most of all).
|
||||
- The French, German, Italian and Spanish releases: increment B below. The Japanese release is not covered (no copy, and it differs the most).
|
||||
|
||||
## In progress: the French, German, Italian and Spanish releases (board #84, increment B)
|
||||
|
||||
- Addresses: `scripts/map-revision.mjs` writes `game/rom/revision-addresses.ts`, where each release keeps the profile's labels. PRET builds none of these releases, so they are derived from its 1.1 build: each bank of the 1.1 ROM is aligned with the release's (unique byte runs, refined inside unequal gaps; equal-length gaps keep their offset), and everything else through the exact references RGBDS recorded while linking 1.1 (every patch in `main11.o` and the other objects, placed with `pokecrystal11.map`), read at the matching place in the release: inside an alignment run, a walk from a resolved label over equal bytes (patched bytes excepted), or the instruction around the pointer near a changed routine. Pointers vote with their bank (the bank byte beside them, the `BANK()` load, or the section's); references resolved while assembling are found by their pointer bytes in a pointer context; labels sharing an address share it; a short text that looks alike in two languages is repaired by the release's own pointers. Each result is checked against the release's bytes (equal data, its patched pointers naming the resolved targets, the same instructions, or a text boundary). Of the 1,358 ROM labels the profile pins, French, German, Italian and Spanish each leave 1-3 unfound, all in code the release changed (the Diploma's certification string; in French and German two Bill's PC strings); they are written as -1, so reading them refuses instead of using 1.1's address. Work and save RAM keep 1.1's layout except the Seer's buffers in French, Italian and Spanish. `check:reference` regenerates the file and compares it when the four ROMs are present.
|
||||
- Runtime: `CrystalAssets` reads the cartridge's revision from its header (game codes BYTF, BYTD, BYTI, BYTS) and `useRevision` points the profile tables at its addresses (and back to 1.1's for another cartridge). Two tables that copied addresses at import now read them when used.
|
||||
- Characters (`game/rom/charset.ts`): the releases' fonts, identified glyph by glyph: French and German share à è é ù ß ç ë ï â ô û ê î, the apostrophe ligatures c' d' j' l' m' n' p' s' 's t' u' y' and +; Italian and Spanish share à è é ù À Á È É Ì Í Ñ Ò Ó Ù Ú á ì í ñ ò ó ú º & ¿ ¡ and English's 'd 'l 'm 'r 's 't 'v moved to $d8. All four add two `PlaceNextChar` codes: $1d places "-" and breaks the line, $1e prints nothing (a word break). Names accept those letters and English's umlauts, which the tile encoder now knows.
|
||||
- Checked: the introduction, Mom's scene and the first steps outside play in each language (`tests/languages.test.ts`), and the local sweep of every open map (each object, sign and warp) runs in all four with the same results as in English.
|
||||
- Not yet accepted: the cartridge selector recognizes the four releases and refuses them, because parts of their own logic, which the port reimplements, differ from English's. Comparing every routine's code with 1.1's (pointers masked) lists them; besides strings and menus read from the ROM, they include the units of Magikarp's length (`CalcMagikarpLength`, `PrintMagikarpLength`, the Lake of Rage checks in `LoadEnemyMon`) and of the Pokédex (`DisplayDexEntry`), the enemy's name order in French, Italian and Spanish (`PlaceEnemysName`), the clock and calendar (`SetDayOfWeek`, `PrintHour`, `GetTimeOfDayString`, Spanish's "¿" before the hour), the start menu, pack, PC, Bill's PC, Mom's bank and mailbox layouts and texts, the naming screen, the Hall of Fame and trainer card layouts, German's Pokémon Talk and Buena texts, the Diploma, and some French-only scripts (`GiveDratini`, `CheckCaughtCelebi`). These are the next increments; each language is accepted once its playthrough passes.
|
||||
|
||||
## Native battles: current state
|
||||
|
||||
|
||||
Reference in new issue
Block a user