Files
Crystal/tests/reference-fixture.ts
kawaandClaude Opus 5.5 d3e3faff72
Checks / web (push) Failing after 19s
Private ROM checks / private-rom (push) Failing after 27m7s
Measure, weigh and name the European releases' own way (#84)
The French, German, Italian and Spanish releases store Magikarp's
length in millimetres (and print a tenth of them), start the Magikarp
house's record at their own length and holder, keep Pokédex heights in
decimetres and weights in hectograms (printed in metres and kilograms),
read the Heavy Ball's weight byte without converting it, and place the
enemy's nickname before EnemyText (French, Italian) or the trainer's
name before the class (French, Italian, Spanish).

map-revision --symbols writes each release's symbol file, so the
reference specs run against a release; specs that pin English data skip
there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 19:04:51 +02:00

58 lines
2.0 KiB
TypeScript

import type { Page } from "@playwright/test";
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
export const romPath = resolve(
process.env.CRYSTAL_ROM_PATH ??
"Pokemon - Crystal Version (UE) (V1.1) [C][!].gbc",
);
/** PRET's 1.1 symbols, or CRYSTAL_SYMBOLS_PATH for another cartridge (a
* release's symbols mapped from 1.1's, as scripts/map-revision.mjs finds
* its labels). */
export const symbolsPath = process.env.CRYSTAL_SYMBOLS_PATH ?? ".reference/pokecrystal/pokecrystal11.sym";
/** PRET's rebuilds of the other English cartridges (`make crystal
* crystal_au`), which keep 1.1's addresses for every label the port reads. */
export const revisionRoms = {
"1.0": resolve(".reference/pokecrystal/pokecrystal.gbc"),
au: resolve(".reference/pokecrystal/pokecrystal_au.gbc"),
} as const;
/** Banked addresses from the private PRET rebuild's symbol file. */
export function loadSymbols() {
const symbols = new Map(
readFileSync(symbolsPath, "utf8")
.split("\n")
.flatMap((line) => {
const match = /^([0-9a-f]{2}):([0-9a-f]{4}) (\S+)$/.exec(line);
return match
? [
[
match[3],
{
bank: parseInt(match[1], 16),
address: parseInt(match[2], 16),
},
] as const,
]
: [];
}),
);
return {
at: (name: string) => symbols.get(name)!.address,
routine: (name: string) => symbols.get(name)!,
};
}
/** Open the reference page and hand it the ROM (by default the user's 1.1)
* through an isolated file input, without an HTTP ROM endpoint. */
export async function openReference(page: Page, rom = romPath) {
await page.goto("/reference.html");
await page.evaluate(() => {
const input = document.createElement("input");
input.type = "file";
input.id = "reference-fixture";
document.body.append(input);
});
await page.locator("#reference-fixture").setInputFiles(rom);
}