Compare commits

...
1 Commits
Author SHA1 Message Date
kawaandClaude Opus 5.5 e5b3b4a91c Lay out the Hall of Fame, the Diploma and the credits per cartridge (#84)
Checks / web (push) Failing after 18s
Private ROM checks / private-rom (push) Failing after 25m52s
The European releases keep these routines' instructions and change
their operands: where the count and the ID go, which tiles the ID line
draws, where the player's name follows on the Diploma. game/rom/code.ts
reads those operands from the cartridge (and refuses a routine whose
instructions differ). The credits read the copyright's string from
ParseCredits (six more strings precede it in the releases) and use spill
tables fitted to each release's credits on the cartridge, with Spanish's
one group that spills otherwise while B is held.

The reference specs for these screens now pass against all four
releases, as every other reference spec that applies.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 03:01:10 +02:00
6 changed files with 174 additions and 23 deletions

No files matched your search

+61
View File
@@ -0,0 +1,61 @@
import type { RomReader } from "./reader";
import { WRAM } from "./profile";
/** One step of an instruction pattern: an opcode byte that must match, or
* an operand to read ("b" a byte, "w" a little-endian word). */
type Step = number | "b" | "w";
/** An ID line: ld hl, coord; three tiles (ld a / ld [hli], a twice, then
* ld [hl]); ld hl, the number's coord. */
export const ID_LINE: readonly Step[] = [0x21, "w", 0x3e, "b", 0x22, 0x3e, "b", 0x22, 0x36, "b", 0x21, "w"];
/** The operands of the instructions at `address`, which must follow
* `pattern`. The European releases keep many routines' instructions and
* change only their operands (where a string or a number goes, which tiles a
* line draws), so the port reads those operands from the cartridge. Another
* instruction there is logic the port has not ported for that cartridge. */
export function operands(r: RomReader, address: number, pattern: readonly Step[]): number[] {
const found = match(r, address, pattern);
if (!found) throw new Error(`The routine at 0x${address.toString(16)} differs on this cartridge; it is not ported yet.`);
return found.values;
}
/** The pattern's operands at `address` and where its instructions end, or
* undefined when the instructions there are others. */
export function match(r: RomReader, address: number, pattern: readonly Step[]): { values: number[]; end: number } | undefined {
const values: number[] = [];
let p = address;
for (const step of pattern) {
if (step === "b") values.push(r.byte(p++));
else if (step === "w") {
values.push(r.word(p));
p += 2;
} else if (r.byte(p++) !== step) return undefined;
}
return { values, end: p };
}
/** The operands of the first place in `from` .. `from + limit` where the
* pattern's instructions are, for a line a routine draws without a label of
* its own. */
export function findOperands(r: RomReader, from: number, limit: number, pattern: readonly Step[]): number[] {
return findMatch(r, from, limit, pattern).values;
}
export function findMatch(r: RomReader, from: number, limit: number, pattern: readonly Step[]) {
for (let p = from; p < from + limit; p++) {
const found = match(r, p, pattern);
if (found) return found;
}
throw new Error(`The routine at 0x${from.toString(16)} differs on this cartridge; it is not ported yet.`);
}
/** A pointer operand of code in `routine`'s bank, as a ROM offset. */
export const nearPointer = (r: RomReader, routine: number, pointer: number) =>
pointer < 0x4000 ? pointer : r.bank(routine) * 0x4000 + pointer - 0x4000;
/** hlcoord's tile position from a wTilemap address. */
export function tileCoord(address: number): [number, number] {
const offset = address - WRAM.wTilemap;
if (offset < 0 || offset >= 20 * 18) throw new Error("A screen position lies outside the tilemap.");
return [offset % 20, Math.floor(offset / 20)];
}
+5
View File
@@ -1232,6 +1232,8 @@ export const EGGS = {
/** Johto's scripts, routines and tables from Route 32 on, keyed by their
* PRET labels for `npm run check:reference`. */
export const JOHTO = {
"DisplayHOFMon.print_id_no": 0x867f8,
"_HallOfFamePC.print_num_hof": 0x866c6,
InitializeMagikarpHouse: 0x5cd3,
"InitializeMagikarpHouse.Ralph": 0x5ce3,
"_HallOfFamePC.TimeFamer": 0x8670c,
@@ -1509,6 +1511,8 @@ export const KANTO = {
KrisBackpic: 0x88ed6,
"AnimateHallOfFame.String_NewHallOfFamer": 0x8652c,
"HOF_AnimatePlayerPic.PlayTime": 0x868ed,
ParseCredits: 0x1099aa,
HOF_AnimatePlayerPic: 0x86810,
"InitDisplayForHallOfFame.SavingRecordText": 0x4e8bd,
ProfOaksPCBoot: 0x265ee,
SnorlaxAwake: 0xc43d,
@@ -1527,6 +1531,7 @@ export const KANTO = {
DiplomaGFX: 0x1dd805,
DiplomaPage1Tilemap: 0x1ddc4b,
PalPacket_Diploma: 0x9cb6,
PlaceDiplomaOnScreen: 0x1dd709,
"PlaceDiplomaOnScreen.Player": 0x1dd760,
"PlaceDiplomaOnScreen.Certification": 0x1dd768,
KrisSpriteGFX: 0xc7a40,
+5 -5
View File
@@ -2,10 +2,10 @@
// each release: where it keeps each profile entry (table.key) whose label
// moved from 1.1; 0 where it did not, -1 where the label was not found
// there, which the port must not read in that release. Do not edit.
export const REVISION_KEYS = ["BATTLE.AlreadyAsleepText","BATTLE.AlreadyConfusedText","BATTLE.AlreadyParalyzedText","BATTLE.AlreadyPoisonedText","BATTLE.AskForgetMoveText","BATTLE.AskGiveNicknameText","BATTLE.AsleepTreeMonsDay","BATTLE.AsleepTreeMonsMorn","BATTLE.AsleepTreeMonsNite","BATTLE.AttackMissed2Text","BATTLE.AttackMissedText","BATTLE.BadgeTypeBoosts","BATTLE.BadlyPoisonedText","BATTLE.BallAlmostHadItText","BATTLE.BallAppearedCaughtText","BATTLE.BallBlockedText","BATTLE.BallBoxFullText","BATTLE.BallBrokeFreeText","BATTLE.BallDontBeAThiefText","BATTLE.BallSentToPCText","BATTLE.BallSoCloseText","BATTLE.BattleCommand_Charge.BattleDugText","BATTLE.BattleCommand_Charge.BattleFlewText","BATTLE.BattleCommand_Charge.BattleGlowingText","BATTLE.BattleCommand_Charge.BattleLoweredHeadText","BATTLE.BattleCommand_Charge.BattleMadeWhirlwindText","BATTLE.BattleCommand_Charge.BattleTookSunlightText","BATTLE.BattleCommand_Charge.UsedText","BATTLE.BattleMonNicknameText","BATTLE.BattleText_AnEGGCantBattle","BATTLE.BattleText_CantEscape","BATTLE.BattleText_CantEscape2","BATTLE.BattleText_EnemyIsAboutToUseWillPlayerChangeMon","BATTLE.BattleText_EnemyMonFainted","BATTLE.BattleText_EnemySentOut","BATTLE.BattleText_EnemyWasDefeated","BATTLE.BattleText_GotAwaySafely","BATTLE.BattleText_ItemHealedConfusion","BATTLE.BattleText_ItemsCantBeUsedHere","BATTLE.BattleText_MonCantBeRecalled","BATTLE.BattleText_MonFainted","BATTLE.BattleText_MonHasNoMovesLeft","BATTLE.BattleText_MonIsAlreadyOut","BATTLE.BattleText_MonsLightScreenFell","BATTLE.BattleText_MonsReflectFaded","BATTLE.BattleText_RainContinuesToFall","BATTLE.BattleText_SafeguardFaded","BATTLE.BattleText_StringBuffer1GrewToLevel","BATTLE.BattleText_TargetRecoveredWithItem","BATTLE.BattleText_TargetWasHitByFutureSight","BATTLE.BattleText_TargetsEncoreEnded","BATTLE.BattleText_TheMoveIsDisabled","BATTLE.BattleText_TheRainStopped","BATTLE.BattleText_TheSandstormRages","BATTLE.BattleText_TheSandstormSubsided","BATTLE.BattleText_TheSunlightFaded","BATTLE.BattleText_TheSunlightIsStrong","BATTLE.BattleText_TheresNoEscapeFromTrainerBattle","BATTLE.BattleText_TheresNoPPLeftForThisMove","BATTLE.BattleText_TheresNoWillToBattle","BATTLE.BattleText_UseNextMon","BATTLE.BattleText_UserFledUsingAStringBuffer1","BATTLE.BattleText_UserHurtBySpikes","BATTLE.BattleText_UserRecoveredPPUsing","BATTLE.BattleText_UserWasReleasedFromStringBuffer1","BATTLE.BattleText_UsersHurtByStringBuffer1","BATTLE.BattleText_UsersStringBuffer1Activated","BATTLE.BattleText_WildFled","BATTLE.BeatUpAttackText","BATTLE.BecameConfusedText","BATTLE.BeganToNapText","BATTLE.BellChimedText","BATTLE.BellyDrumText","BATTLE.BitterBerryEffect","BATTLE.BlewSpikesText","BATTLE.BlownAwayText","BATTLE.BoostedExpPointsText","BATTLE.BracedItselfText","BATTLE.BugContest_SetCaughtContestMon.ContestCaughtMonText","BATTLE.ButItFailedText","BATTLE.CantEscapeNowText","BATTLE.CatchTutorial.Dude","BATTLE.ChooseAMonString","BATTLE.ClampedByText","BATTLE.CoinsScatteredText","BATTLE.ComeBackText","BATTLE.ConfusedNoMoreText","BATTLE.ConsumableEffects","BATTLE.ContestAskSwitchText","BATTLE.CopiedStatsText","BATTLE.CoveredByVeilText","BATTLE.CrashedText","BATTLE.CriticalHitText","BATTLE.DefrostedOpponentText","BATTLE.DestinyBondEffectText","BATTLE.DidNotLearnMoveText","BATTLE.DidntAffect1Text","BATTLE.DidntAffect2Text","BATTLE.DireHitEffect","BATTLE.DisabledMoveText","BATTLE.DisabledNoMoreText","BATTLE.DisplayAlreadyCaughtText.ContestAlreadyCaughtText","BATTLE.DoItMonText","BATTLE.DoesntAffectText","BATTLE.DownpourText","BATTLE.DraggedOutText","BATTLE.DreamEatenText","BATTLE.EliminatedStatsText","BATTLE.EnduredText","BATTLE.EnemyHitTimesText","BATTLE.EnemyText","BATTLE.EnergyRootEffect","BATTLE.EnergypowderEffect","BATTLE.EvadedText","BATTLE.ExpPointsText","BATTLE.FastAsleepText","BATTLE.FellAsleepText","BATTLE.FellInLoveText","BATTLE.FireSpinTrapText","BATTLE.FledFromBattleText","BATTLE.FledInFearText","BATTLE.FlinchedText","BATTLE.ForesawAttackText","BATTLE.FrozenSolidText","BATTLE.FullRestoreEffect","BATTLE.FullyParalyzedText","BATTLE.GettingPumpedText","BATTLE.GoForItMonText","BATTLE.GoMonText","BATTLE.GoodComeBackText","BATTLE.GotAnEncoreText","BATTLE.GotMoneyForWinningText","BATTLE.GuardSpecEffect","BATTLE.HPIsFullText","BATTLE.HappinessChanges","BATTLE.HasANightmareText","BATTLE.HasNoPPLeftText","BATTLE.HasSubstituteText","BATTLE.HealPowderEffect","BATTLE.HealingHPAmounts","BATTLE.HeavyBallMultiplier.WeightsTable","BATTLE.HeavyBall_GetDexEntryBank.PokedexEntryBanks","BATTLE.HeldStatusHealingEffects","BATTLE.HookedPokemonAttackedText","BATTLE.HungOnText","BATTLE.HurtByBurnText","BATTLE.HurtByCurseText","BATTLE.HurtByPoisonText","BATTLE.HurtItselfText","BATTLE.IdentifiedText","BATTLE.IgnoredOrders2Text","BATTLE.IgnoredOrdersText","BATTLE.IgnoredSleepingText","BATTLE.InLoveWithText","BATTLE.InfatuationText","BATTLE.IsConfusedText","BATTLE.IsHMMove.HMMoves","BATTLE.ItFailedText","BATTLE.ItemAttributes","BATTLE.ItemCantUseOnEggText","BATTLE.IteLine truncated
export const REVISION_KEYS = ["BATTLE.AlreadyAsleepText","BATTLE.AlreadyConfusedText","BATTLE.AlreadyParalyzedText","BATTLE.AlreadyPoisonedText","BATTLE.AskForgetMoveText","BATTLE.AskGiveNicknameText","BATTLE.AsleepTreeMonsDay","BATTLE.AsleepTreeMonsMorn","BATTLE.AsleepTreeMonsNite","BATTLE.AttackMissed2Text","BATTLE.AttackMissedText","BATTLE.BadgeTypeBoosts","BATTLE.BadlyPoisonedText","BATTLE.BallAlmostHadItText","BATTLE.BallAppearedCaughtText","BATTLE.BallBlockedText","BATTLE.BallBoxFullText","BATTLE.BallBrokeFreeText","BATTLE.BallDontBeAThiefText","BATTLE.BallSentToPCText","BATTLE.BallSoCloseText","BATTLE.BattleCommand_Charge.BattleDugText","BATTLE.BattleCommand_Charge.BattleFlewText","BATTLE.BattleCommand_Charge.BattleGlowingText","BATTLE.BattleCommand_Charge.BattleLoweredHeadText","BATTLE.BattleCommand_Charge.BattleMadeWhirlwindText","BATTLE.BattleCommand_Charge.BattleTookSunlightText","BATTLE.BattleCommand_Charge.UsedText","BATTLE.BattleMonNicknameText","BATTLE.BattleText_AnEGGCantBattle","BATTLE.BattleText_CantEscape","BATTLE.BattleText_CantEscape2","BATTLE.BattleText_EnemyIsAboutToUseWillPlayerChangeMon","BATTLE.BattleText_EnemyMonFainted","BATTLE.BattleText_EnemySentOut","BATTLE.BattleText_EnemyWasDefeated","BATTLE.BattleText_GotAwaySafely","BATTLE.BattleText_ItemHealedConfusion","BATTLE.BattleText_ItemsCantBeUsedHere","BATTLE.BattleText_MonCantBeRecalled","BATTLE.BattleText_MonFainted","BATTLE.BattleText_MonHasNoMovesLeft","BATTLE.BattleText_MonIsAlreadyOut","BATTLE.BattleText_MonsLightScreenFell","BATTLE.BattleText_MonsReflectFaded","BATTLE.BattleText_RainContinuesToFall","BATTLE.BattleText_SafeguardFaded","BATTLE.BattleText_StringBuffer1GrewToLevel","BATTLE.BattleText_TargetRecoveredWithItem","BATTLE.BattleText_TargetWasHitByFutureSight","BATTLE.BattleText_TargetsEncoreEnded","BATTLE.BattleText_TheMoveIsDisabled","BATTLE.BattleText_TheRainStopped","BATTLE.BattleText_TheSandstormRages","BATTLE.BattleText_TheSandstormSubsided","BATTLE.BattleText_TheSunlightFaded","BATTLE.BattleText_TheSunlightIsStrong","BATTLE.BattleText_TheresNoEscapeFromTrainerBattle","BATTLE.BattleText_TheresNoPPLeftForThisMove","BATTLE.BattleText_TheresNoWillToBattle","BATTLE.BattleText_UseNextMon","BATTLE.BattleText_UserFledUsingAStringBuffer1","BATTLE.BattleText_UserHurtBySpikes","BATTLE.BattleText_UserRecoveredPPUsing","BATTLE.BattleText_UserWasReleasedFromStringBuffer1","BATTLE.BattleText_UsersHurtByStringBuffer1","BATTLE.BattleText_UsersStringBuffer1Activated","BATTLE.BattleText_WildFled","BATTLE.BeatUpAttackText","BATTLE.BecameConfusedText","BATTLE.BeganToNapText","BATTLE.BellChimedText","BATTLE.BellyDrumText","BATTLE.BitterBerryEffect","BATTLE.BlewSpikesText","BATTLE.BlownAwayText","BATTLE.BoostedExpPointsText","BATTLE.BracedItselfText","BATTLE.BugContest_SetCaughtContestMon.ContestCaughtMonText","BATTLE.ButItFailedText","BATTLE.CantEscapeNowText","BATTLE.CatchTutorial.Dude","BATTLE.ChooseAMonString","BATTLE.ClampedByText","BATTLE.CoinsScatteredText","BATTLE.ComeBackText","BATTLE.ConfusedNoMoreText","BATTLE.ConsumableEffects","BATTLE.ContestAskSwitchText","BATTLE.CopiedStatsText","BATTLE.CoveredByVeilText","BATTLE.CrashedText","BATTLE.CriticalHitText","BATTLE.DefrostedOpponentText","BATTLE.DestinyBondEffectText","BATTLE.DidNotLearnMoveText","BATTLE.DidntAffect1Text","BATTLE.DidntAffect2Text","BATTLE.DireHitEffect","BATTLE.DisabledMoveText","BATTLE.DisabledNoMoreText","BATTLE.DisplayAlreadyCaughtText.ContestAlreadyCaughtText","BATTLE.DoItMonText","BATTLE.DoesntAffectText","BATTLE.DownpourText","BATTLE.DraggedOutText","BATTLE.DreamEatenText","BATTLE.EliminatedStatsText","BATTLE.EnduredText","BATTLE.EnemyHitTimesText","BATTLE.EnemyText","BATTLE.EnergyRootEffect","BATTLE.EnergypowderEffect","BATTLE.EvadedText","BATTLE.ExpPointsText","BATTLE.FastAsleepText","BATTLE.FellAsleepText","BATTLE.FellInLoveText","BATTLE.FireSpinTrapText","BATTLE.FledFromBattleText","BATTLE.FledInFearText","BATTLE.FlinchedText","BATTLE.ForesawAttackText","BATTLE.FrozenSolidText","BATTLE.FullRestoreEffect","BATTLE.FullyParalyzedText","BATTLE.GettingPumpedText","BATTLE.GoForItMonText","BATTLE.GoMonText","BATTLE.GoodComeBackText","BATTLE.GotAnEncoreText","BATTLE.GotMoneyForWinningText","BATTLE.GuardSpecEffect","BATTLE.HPIsFullText","BATTLE.HappinessChanges","BATTLE.HasANightmareText","BATTLE.HasNoPPLeftText","BATTLE.HasSubstituteText","BATTLE.HealPowderEffect","BATTLE.HealingHPAmounts","BATTLE.HeavyBallMultiplier.WeightsTable","BATTLE.HeavyBall_GetDexEntryBank.PokedexEntryBanks","BATTLE.HeldStatusHealingEffects","BATTLE.HookedPokemonAttackedText","BATTLE.HungOnText","BATTLE.HurtByBurnText","BATTLE.HurtByCurseText","BATTLE.HurtByPoisonText","BATTLE.HurtItselfText","BATTLE.IdentifiedText","BATTLE.IgnoredOrders2Text","BATTLE.IgnoredOrdersText","BATTLE.IgnoredSleepingText","BATTLE.InLoveWithText","BATTLE.InfatuationText","BATTLE.IsConfusedText","BATTLE.IsHMMove.HMMoves","BATTLE.ItFailedText","BATTLE.ItemAttributes","BATTLE.ItemCantUseOnEggText","BATTLE.IteLine truncated
export const REVISION_ADDRESSES = {
fr: [528985,527975,530010,529047,26265,60826,256876,256882,256864,528585,528564,1031749,529018,60772,60767,63433,63453,60762,63438,60816,60777,224300,224295,224290,224285,224275,224280,224224,258802,527258,527410,527290,527163,526842,527214,526889,527359,527947,527492,527546,527068,527633,527521,526595,526633,526670,526565,527681,526477,526532,527660,527606,526760,526728,526811,526784,526700,527309,527573,527231,527082,527382,527429,526501,528020,527995,527473,526265,530720,527928,528323,528953,530605,61711,530538,529248,258351,530380,59122,529804,530108,321009,0,528119,529612,258910,527907,160233,835777,530653,530422,528606,528666,529136,528888,26260,529842,529862,62557,528278,527834,835791,258779,528646,530559,529910,529100,529662,528201,529285,4711,61749,61745,529565,258356,527763,528973,530405,528084,529217,529229,527801,530696,527788,61645,529982,529359,258786,258772,258901,528803,526868,62544,529882,29243,526373,528460,529421,61266,62292,60521,60449,253510,526176,528179,526340,526395,526318,527871,530286,530765,528381,528399,528229,528251,527856,13533,529823,26587,63413,59153,63408,63458,63428,26245,0,529725,528306,529403,1031277,227769,530477,226393,529531,530058,529306,26250,26292,160255,1072770,1072683,1072705,527819,60821,528427,528723,529780,258896,68338,528682,63198,529944,526441,529264,62516,279404,526201,530739,227596,329073,330662,529330,530032,530215,530234,530177,528775,529377,527449,529753,528539,530494,528501,61739,62820,63183,61518,61549,530444,530346,526410,527003,526971,526918,528819,530516,528867,530246,528925,530302,530134,222443,61462,61297,530080,26255,528142,529505,529470,529071,530586,528700,26270,26287,60782,258334,258891,529436,528858,528753,529698,529634,528361,528625,528159,328948,528045,1072652,1072659,1072577,1072674,60811,526246,529126,530162,529584,529151,528999,529549,1031653,1031640,528489,328961,528070,526223,526148,258813,63839,527772,529190,528344,529164,528098,62503,62570,62633,258793,95168,95260,1838551,1838589,1838560,1838562,75027,559274,592741,592735,592730,298334,0,560058,24813,24824,71596,592022,591995,1838283,1842383,1842495,1842550,1842664,1851420,1819420,1819423,1819452,1819455,1819500,1819412,1819390,1819444,1819313,1819475,924544,0,0,89755,89185,89730,89725,89750,89740,89745,89735,0,1942651,0,304732,29711,79408,79427,0,79803,0,920855,921647,920796,920823,920839,922259,920724,919938,29126,0,317577,317917,317912,0,1073943,317940,923196,12768,150408,80458,79669,79651,79692,79674,79715,79697,80489,29749,91984,91900,92508,92601,92616,92621,92522,92606,92611,95310,95341,95443,95433,95448,95438,95453,90668,0,0,568937,0,1950436,0,324090,923158,29095,1383442,0,79379,29471,29827,29809,29818,89690,89720,89700,89695,89715,89710,89705,568796,924208,922612,23778,23794,924976,95375,95380,0,1031319,1031341,569048,304773,0,181589,181732,181762,181752,181737,181757,181747,181742,181727,0,0,0,29739,568816,925216,0,89790,89770,89765,89760,89785,89780,89775,93684,93765,93750,93760,93745,0,919636,0,323792,92368,317922,923818,923286,923323,602939,602957,602975,0,29590,88830,88847,324325,324256,324286,324281,324261,324276,324251,324266,324271,80352,0,603233,603829,604437,602993,602457,602184,602170,29584,29578,150608,0,150621,150615,76035,1157816,1157710,1157748,1157854,0,0,171631,324116,1069249,256932,0,923360,923980,924044,569021,6834,58284,0,29744,1855399,1855487,1855377,1855419,1855430,1855355,1855448,1855479,550666,1823134,1823107,1854563,1854676,1854651,1854588,1854636,1854610,1854583,550187,29711,178723,1093143,0,1955881,1957679,551146,321750,560855,299449,1955726,1955718,0,157167,0,0,0,760125,760205,760221,761237,761037,761301,761397,760941,760189,760181,761125,760469,760661,760277,760421,758535,760373,761005,760517,760229,760877,760325,760973,760141,760117,761365,761101,760149,761437,760845,760133,760173,1959834,760909,760197,761173,760157,68358,68328,68323,63217,60845,62772,62778,182482,182477,68353,63210,62783,62789,271486,182487,62452,60852,271491,271501,271804,0,76960,62798,63244,77012,61003,76997,62813,76388,63915,761487,62475,78690,66299,66262,0,0,0,66128,77334,77324,77319,77329,77344,77339,77297,0,150752,77605,63240,62794,63261,63188,63193,0,0,0,0,0,0,77007,76982,76992,76987,76977,77002,63178,61113,68348,62479,62498,63224,329751,63203,75508,61072,61008,271496,78224,62471,62802,182492,68333,60898,68343,90672,91868,91409,91404,91414,91424,91419,91429,91765,91785,91795,91760,91820,91745,91750,91755,91800,91790,91780,91805,91770,91810,91775,91815,91843,91851,91825,91691,91835,75056,75036,70628,79495,74497,934815,934811,934875,934868,0,0,935041,935049,935025,935017,935033,934939,934946,934723,934725,934727,159472,51586,53624,53641,79151,52907,51707,300206,79395,53660,51581,50956,621960,51167,51096,51249,158293,159726,159712,159631,159542,158611,52716,79268,79193,52213,52228,52218,51023,599199,754948,53307,51826,51866,597109,50901,53067,52854,12291,300285,172713,75170,75203,75190,598038,176422,176765,598399,178176,755092,754885,300507,300636,159457,9936,0,15536,0,30Line truncated
de: [529315,528124,530410,529380,26272,60873,256874,256880,256862,528854,528828,1031749,529355,60819,60814,63475,63495,60809,63480,60863,60824,224296,224291,224286,224281,224271,224276,224220,258800,527293,527442,527321,527187,526817,527238,526864,527385,528085,527528,527593,527080,527708,527572,526610,526638,526664,526578,527765,526493,526550,527744,527680,526733,526715,526790,526762,526687,527340,527632,527269,527100,527405,527461,526519,528162,528146,527507,526259,531166,528068,528552,529280,531046,61753,530972,529589,258349,530813,59169,530224,530516,321001,328922,528313,530002,258908,528040,160233,835780,531101,530853,528880,528953,529458,529218,26267,530251,530282,62599,528511,527948,835794,258777,528930,530994,530349,529426,530077,528418,529635,4713,61791,61787,529956,258354,527841,529303,530835,528254,529557,529568,527898,531147,527877,61687,530390,529716,258784,258770,258899,529107,526845,62586,530311,29250,526401,528741,529784,61308,62334,60568,60496,253509,526168,528391,526338,526423,526317,527995,530725,531218,528621,528644,528452,528475,527978,13530,530241,26594,63455,59200,63450,63500,63470,26252,526366,530159,528537,529754,1031277,227765,530908,226389,529917,530457,529661,26257,26299,160255,1072761,1072674,1072696,527918,60868,528685,529023,530205,258894,68330,528967,63240,530370,526462,529609,62558,279404,0,531181,227592,329070,330663,529693,530431,530644,530668,530594,529083,529736,527482,530181,528812,530928,528784,61781,62862,63225,61560,61591,530875,530788,526441,526998,526958,526905,529128,530941,529176,530705,529253,530745,530539,222439,61504,61339,530489,26262,528353,529884,529848,529406,531021,528991,26277,26294,60829,258332,258889,529814,529161,529061,530121,530039,528600,528911,528371,328935,528189,1072643,1072650,1072568,1072665,60858,526240,529447,530574,529976,529476,529335,529936,1031653,1031640,528768,328946,528232,526221,526149,258811,63881,527858,529528,528579,529498,528276,62545,62612,62675,258791,95161,95253,1839014,1839055,1839023,1839025,75000,559270,592770,592760,592754,298334,557804,560054,24820,24831,71573,592033,592004,1838737,1843476,1843599,1843659,1843788,1851415,1819501,1819504,1819531,1819534,1819589,1819494,1819476,1819524,1819381,1819559,924163,150691,0,89750,89180,89725,89720,89745,89735,89740,89730,0,1943064,569910,304739,29721,79351,79370,0,79746,0,920856,921258,920797,920824,920840,921870,920725,919939,29133,0,317577,317917,317912,0,1073934,317940,922807,12765,150408,80401,79612,79594,79635,79617,79658,79640,80432,29759,91980,91896,92504,92597,92612,92617,92518,92602,92607,95303,95334,95436,95426,95441,95431,95446,90663,0,0,568933,569898,1950431,0,324092,922769,29102,569710,569794,79322,29478,29837,29819,29828,89685,89715,89695,89690,89710,89705,89700,568792,923827,922223,23787,23803,924595,95368,95373,0,1031319,1031341,569043,304780,0,181578,181721,181751,181741,181726,181746,181736,181731,181716,0,0,0,29749,568812,924835,569925,89785,89765,89760,89755,89780,89775,89770,93677,93758,93743,93753,93738,0,919637,0,323794,92364,317922,923429,922897,922934,602947,602965,602983,0,29600,88825,88842,324334,324265,324295,324290,324270,324285,324260,324275,324280,80295,0,603241,603837,604445,603001,602465,602192,602178,29594,29585,150612,150604,150625,150619,76014,1158014,1157891,1157954,1158128,569930,569935,171643,324122,1069240,256930,0,922971,923591,923655,569017,6843,58328,569940,29754,1857983,1858066,1857959,1858001,1858017,1857936,1858031,1858060,550657,1824151,1824128,1855878,1856008,1855977,1855904,1855963,1855928,1855896,550187,29721,178735,1093149,0,1955832,1957630,551137,321742,560851,299450,1955686,1955677,0,157172,0,0,0,760137,760217,760233,761249,761049,761313,761409,760953,760201,760193,761137,760481,760673,760289,760433,758547,760385,761017,760529,760241,760889,760337,760985,760153,760129,761377,761113,760161,761449,760857,760145,760185,1959803,760921,760209,761185,760169,68350,68320,68315,63259,60892,62814,62820,182471,182466,68345,63252,62825,62831,271459,182476,62494,60899,271464,271474,271777,66693,76939,62840,63286,76985,61050,76970,62855,76367,63957,761499,62517,78661,66291,66254,66203,66225,66168,66126,77304,77294,77289,77299,77314,77309,77270,150706,150754,77575,63282,62836,63303,63230,63235,65858,328904,328349,328352,0,328228,76980,76955,76965,76960,76950,76975,63220,61155,68340,62521,62540,63266,329748,63245,75481,61114,61055,271469,78194,62513,62844,182481,68325,60945,68335,90667,91865,91404,91399,91409,91419,91414,91424,91760,91780,91790,91755,91815,91740,91745,91750,91795,91785,91775,91800,91765,91805,91770,91810,91840,91850,91820,91686,91832,75029,75009,70620,79438,74470,934786,934782,934847,934839,935147,935151,935026,935038,935002,934990,935014,934912,934919,934694,934696,934698,159472,0,0,0,79122,0,0,300207,79338,0,0,0,621960,0,0,0,158298,159726,159712,159631,159542,158616,0,0,79164,0,0,0,0,599207,754948,0,0,0,597116,0,0,0,12288,300286,172725,75143,75176,75163,598046,176434,176777,598407,178188,755092,754885,300508,300637,159457,Line truncated
it: [529031,528005,530046,529086,26264,60871,256874,256880,256862,528623,528610,1031749,529065,60817,60812,63482,63502,60807,63487,60861,60822,224301,224296,224291,224286,224276,224281,224225,258800,527250,527386,527276,527149,526841,527196,526882,527342,527972,527475,527533,527053,527625,527512,526601,526640,526676,526576,527686,526494,526546,527654,527598,526758,526729,526811,526774,526697,527292,527565,527221,527069,527362,527402,526520,528045,528023,527452,526263,530732,527952,528369,528995,530629,61760,530548,529304,258349,530399,59167,529874,530145,320987,328935,528165,529672,258908,527930,160214,835781,530675,530436,528636,528704,529167,528930,26259,529899,529927,62606,528324,527843,835795,258777,528682,530569,529973,529129,529730,528254,529346,4709,61798,61794,529628,258354,527764,529010,530419,528115,529262,529283,527809,530712,527793,61694,530028,529414,258784,258770,258899,528821,526864,62593,529955,29242,526394,528514,529471,61315,62341,60566,60494,0,526175,528232,526332,526411,526304,527895,530314,530780,528429,528451,528266,528288,527881,13534,529888,26586,63462,59198,63457,63507,63477,26244,526361,529798,528347,529449,1031277,227770,530487,226394,529586,530092,529369,26249,26291,160236,1072764,1072677,1072699,527822,60866,528482,528756,529851,258894,68338,528719,63247,529993,526462,529323,62565,279404,526197,530751,227597,329090,330690,529391,530068,530252,530268,530213,528801,529429,527426,529829,528594,530506,528559,61788,62869,63232,61567,61598,530456,530369,526437,526994,526976,526930,528843,530525,528897,530293,528969,530331,530166,222444,61511,61346,530120,26254,528192,529563,529526,529107,530596,528738,26269,26286,60827,258332,258889,529491,528878,528779,529772,529698,528410,528667,528213,328951,528068,1072646,1072653,1072571,1072668,60856,526245,529152,530196,529649,529184,529048,529608,1031653,1031640,528542,328970,528096,526220,0,258811,63888,527774,529232,528390,529200,528134,62552,62619,62682,258791,95173,95265,1838500,1838534,1838507,1838509,75102,559278,592757,592752,592747,298334,557812,560062,24812,24823,71594,592034,592003,1838224,1842422,1842533,1842593,1842696,1851423,1819225,1819228,1819252,1819255,1819310,1819217,1819205,1819244,1819128,1819278,924146,0,0,89760,89190,89735,89730,89755,89745,89750,89740,0,1941607,569911,304739,29712,79478,79497,49995,79873,50049,920855,921257,920796,920823,920839,921869,920724,919938,29125,0,317573,317913,317908,50229,1073937,317936,922806,12769,150407,80528,79739,79721,79762,79744,79785,79767,80559,29750,91983,91899,92507,92600,92615,92620,92521,92605,92610,95315,95346,95448,95438,95453,95443,95458,90670,150307,150348,568941,569899,1950432,50297,323898,922768,29094,569711,569795,79449,29470,29828,29810,29819,89695,89725,89705,89700,89720,89715,89710,568800,923810,922222,23780,23796,924578,95380,95385,0,1031319,1031341,569048,304780,150401,181597,181740,181770,181760,181745,181765,181755,181750,181735,49850,0,0,29740,568820,924818,569926,89795,89775,89770,89765,89790,89785,89780,93689,93770,93755,93765,93750,150246,919636,50291,323600,92367,317918,923428,922896,922933,602935,602953,602971,50211,29591,88835,88852,324130,324061,324091,324086,324066,324081,324056,324071,324076,80422,50036,603229,603825,604433,602989,602453,602180,602166,29584,29577,150609,150602,150623,150615,76121,1157844,1157730,1157786,1157949,569931,569936,171613,323923,1069243,256930,50017,922970,923590,923654,569025,6837,58334,569941,29745,1855673,1855769,1855657,1855692,1855710,1855637,1855732,1855764,550666,1823011,1822993,1854702,1854824,1854797,1854730,1854786,1854759,1854724,550187,29712,178705,1093151,50336,1955866,1957664,551144,321727,560859,299452,1955710,1955701,50349,157157,50238,50280,50362,760128,760208,760224,761240,761040,761304,761400,760944,760192,760184,761128,760472,760664,760280,760424,758538,760376,761008,760520,760232,760880,760328,760976,760144,760120,761368,761104,760152,761440,760848,760136,760176,1959808,760912,760200,761176,760160,68358,68328,68323,63266,60890,62821,62827,182490,182485,68353,63259,62832,62838,271474,182495,62501,60897,271479,271489,271792,66700,77046,62847,63293,77094,61048,77079,62862,76474,63964,761490,62524,78773,66297,66260,66208,66231,66171,66128,77414,77404,77399,77409,77424,77419,77379,0,150747,77685,63289,62843,63310,63237,63242,0,328917,0,328362,328223,0,77089,77064,77074,77069,77059,77084,63227,61162,68348,62528,62547,63273,329768,63252,75583,61121,61053,271484,78304,62520,62851,182500,68333,60943,68343,90674,91869,91411,91406,91416,91426,91421,91431,91767,91787,91797,91762,91822,91747,91752,91757,91802,91792,91782,91807,91772,91812,91777,91817,91843,91852,91827,91693,91836,75131,75111,70628,79565,74572,934806,934803,934865,934858,935149,935152,935034,935043,935016,935007,935025,934929,934936,934715,934717,934719,159453,51636,53674,53691,79234,52957,51757,300209,79465,53710,51631,51006,621958,51217,51146,51299,158281,159707,159693,159612,159523,158599,52766,79351,79276,52263,52278,52268,51073,599195,754948,53357,5Line truncated
es: [529173,528047,530289,529245,26270,60823,256874,256880,256862,528742,528721,1031749,529214,60769,60764,63433,63453,60759,63438,60813,60774,224300,224295,224290,224285,224275,224280,224224,258800,527227,527378,527258,527134,526820,527189,526866,527326,528016,527470,527526,527022,527628,527503,526611,526650,526688,526576,527694,526493,526548,527668,527594,526754,526723,526790,526771,526706,527276,527557,527207,527043,527353,527396,526519,528090,528068,527447,526260,531030,527998,528434,529131,530932,61711,530855,529471,258349,530678,59119,530110,530399,320992,328934,528200,529901,258908,527977,160236,0,530970,530722,528763,528825,529329,529065,26265,530133,530150,62557,528385,527882,0,258777,528808,530872,530198,529289,529968,528298,529513,4710,61749,61745,529848,258354,527790,529158,530701,528158,529426,529448,527845,531008,527825,61645,530257,529604,258784,258770,258899,528953,526848,62544,530167,29248,0,528606,529670,61266,62292,60518,60446,0,526169,528274,0,526395,526312,527933,530582,531081,528510,528531,528320,528345,527915,13530,530124,26592,63413,59150,63408,63458,63428,26250,526341,530032,528416,529647,1031277,227769,530789,226393,529805,530343,529535,26255,26297,160258,1072761,1072674,1072696,527861,60818,528570,528883,530085,258894,68358,528845,63198,530218,526449,529491,62516,279404,526198,531049,227596,0,330685,529570,530313,530510,530531,530477,528921,529627,527417,530063,528698,530808,528656,61739,62820,63183,61518,61549,530749,530643,526421,526964,526940,526903,528989,530832,529039,530556,529098,530602,530421,222443,61462,61297,530372,26260,528225,529779,529734,529266,530907,528864,26275,26292,60779,258332,258889,529691,529027,528904,530004,529933,528484,528791,528254,328949,528117,1072643,1072650,1072568,1072665,60808,526242,529315,530455,529871,529351,529194,529829,1031653,1031640,528635,328966,528140,526222,526149,258811,63839,527808,529398,528460,529370,528176,62503,62570,62633,258791,95154,95246,1838736,1838776,1838745,1838747,75137,559287,592778,592774,592769,298334,557813,560071,24818,24829,71616,592043,592006,1838451,1842873,1842981,1843045,1843153,1851424,1819501,1819443,1819501,1819474,1819536,1819432,1819417,1819462,1819339,1819501,924543,150689,1510290,89752,89182,89727,89722,89747,89737,89742,89732,1509001,1942287,569921,304728,29717,79504,79523,49993,79899,50047,920856,921648,920797,920824,920840,922260,920725,919939,29131,1510357,317573,317913,317908,50227,1073934,317936,923197,12765,150407,80554,79765,79747,79788,79770,79811,79793,80585,29755,91975,91891,92499,92592,92607,92612,92513,92597,92602,95296,95327,95429,95419,95434,95424,95439,90670,150308,150349,568950,569909,1950435,50295,324089,923159,29100,569721,569805,79475,29476,29833,29815,29824,89687,89717,89697,89692,89712,89707,89702,568809,924207,922613,23778,23794,924975,95361,95366,1510214,1031319,1031341,569057,304769,150402,181585,181728,181758,181748,181733,181753,181743,181738,181723,49848,2078033,2078061,29745,568829,925215,569936,89787,89767,89762,89757,89782,89777,89772,93670,93751,93736,93746,93731,150247,919637,50289,323790,92359,317918,923819,923287,923324,602957,602975,602993,50209,29596,88827,88844,324321,324252,324282,324277,324257,324272,324247,324262,324267,80448,50034,603251,603823,604431,603011,602475,602202,602188,29589,29583,150609,0,150623,150615,76150,1158057,1157941,1157989,1158177,569941,569946,171629,324112,1069240,256930,50015,923361,923981,924045,569034,6833,58284,569951,29750,1857778,1857861,1857762,1857796,1857813,1857738,1857832,1857855,550664,1823861,1823842,1855709,1855852,1855817,1855739,1855798,1855768,1855727,550187,29717,178721,1093151,50334,1955868,1957666,551147,321732,560868,299448,1955718,1955709,50347,0,50236,50278,50360,760135,760215,760231,761247,761047,761311,761407,760951,760199,760191,761135,760479,760671,760287,760431,758545,760383,761015,760527,760239,760887,760335,760983,760151,760127,761375,761111,760159,761447,760855,760143,760183,1959824,760919,760207,761183,760167,68378,68348,68343,63217,60842,62772,62778,182478,182473,68373,63210,62783,62789,271494,182483,62452,60849,271499,271509,271812,66717,77075,62798,63244,77123,61000,77108,62813,76503,63915,761497,62475,78811,66313,66274,66217,66242,66178,66132,77443,77433,77428,77438,77453,77448,77408,150704,150752,77714,63240,62794,63261,63188,63193,65861,328916,0,328361,328224,0,77118,77093,77103,77098,77088,77113,63178,61113,68368,62479,62498,63224,0,63203,75618,61072,61005,271504,78333,62471,62802,182488,68353,60895,68363,90674,91863,91411,91406,91416,91426,91421,91431,91767,91787,91797,91762,91822,91747,91752,91757,91802,91792,91782,91807,91772,91812,91777,91817,91842,91848,91827,91693,91836,75166,75146,70648,79591,74607,934808,934805,934869,934860,935167,935170,935048,935059,935026,935015,935037,934935,934943,934717,934719,0,159475,51585,53623,53640,79272,52906,51706,300205,79491,53659,51580,50955,621952,51166,51095,51248,158293,159729,159715,159634,159545,158611,52715,79391,79314,52212,52227,52217,51022,599217,7549Line truncated
fr: [528985,527975,530010,529047,26265,60826,256876,256882,256864,528585,528564,1031749,529018,60772,60767,63433,63453,60762,63438,60816,60777,224300,224295,224290,224285,224275,224280,224224,258802,527258,527410,527290,527163,526842,527214,526889,527359,527947,527492,527546,527068,527633,527521,526595,526633,526670,526565,527681,526477,526532,527660,527606,526760,526728,526811,526784,526700,527309,527573,527231,527082,527382,527429,526501,528020,527995,527473,526265,530720,527928,528323,528953,530605,61711,530538,529248,258351,530380,59122,529804,530108,321009,0,528119,529612,258910,527907,160233,835777,530653,530422,528606,528666,529136,528888,26260,529842,529862,62557,528278,527834,835791,258779,528646,530559,529910,529100,529662,528201,529285,4711,61749,61745,529565,258356,527763,528973,530405,528084,529217,529229,527801,530696,527788,61645,529982,529359,258786,258772,258901,528803,526868,62544,529882,29243,526373,528460,529421,61266,62292,60521,60449,253510,526176,528179,526340,526395,526318,527871,530286,530765,528381,528399,528229,528251,527856,13533,529823,26587,63413,59153,63408,63458,63428,26245,0,529725,528306,529403,1031277,227769,530477,226393,529531,530058,529306,26250,26292,160255,1072770,1072683,1072705,527819,60821,528427,528723,529780,258896,68338,528682,63198,529944,526441,529264,62516,279404,526201,530739,227596,329073,330662,529330,530032,530215,530234,530177,528775,529377,527449,529753,528539,530494,528501,61739,62820,63183,61518,61549,530444,530346,526410,527003,526971,526918,528819,530516,528867,530246,528925,530302,530134,222443,61462,61297,530080,26255,528142,529505,529470,529071,530586,528700,26270,26287,60782,258334,258891,529436,528858,528753,529698,529634,528361,528625,528159,328948,528045,1072652,1072659,1072577,1072674,60811,526246,529126,530162,529584,529151,528999,529549,1031653,1031640,528489,328961,528070,526223,526148,258813,63839,527772,529190,528344,529164,528098,62503,62570,62633,258793,95168,95260,1838551,1838589,1838560,1838562,75027,559274,592741,592735,592730,298334,0,560058,24813,24824,71596,592022,591995,1838283,1842383,1842495,1842550,1842664,1851420,1819420,1819423,1819452,1819455,1819500,1819412,1819390,1819444,1819313,1819475,924544,0,0,89755,89185,89730,89725,89750,89740,89745,89735,0,1942651,0,304732,29711,79408,79427,0,79803,0,920855,921647,920796,920823,920839,922259,920724,919938,29126,0,317577,317917,317912,0,1073943,317940,923196,12768,150408,80458,79669,79651,79692,79674,79715,79697,80489,29749,91984,91900,92508,92601,92616,92621,92522,92606,92611,95310,95341,95443,95433,95448,95438,95453,90668,0,550901,0,568937,0,1950436,0,324090,923158,29095,1383442,0,79379,29471,29827,29809,29818,89690,89720,89700,89695,89715,89710,89705,568796,924208,922612,23778,23794,924976,95375,95380,0,1031319,1031341,569048,304773,0,181589,181732,181762,181752,181737,181757,181747,181742,181727,0,0,0,29739,568816,925216,0,89790,89770,89765,89760,89785,89780,89775,93684,93765,93750,93760,93745,0,919636,0,323792,92368,317922,923818,923286,923323,602939,602957,602975,0,29590,88830,88847,324325,324256,324286,324281,324261,324276,324251,324266,324271,80352,0,603233,603829,604437,602993,602457,602184,602170,29584,29578,150608,0,150621,150615,76035,1157816,1157710,1157748,1157854,0,0,171631,324116,1069249,256932,0,923360,923980,924044,569021,6834,58284,0,29744,1855399,1855487,1855377,1855419,1855430,1855355,1855448,1855479,550666,550594,1823134,1823107,1854563,1854676,1854651,1854588,1854636,1854610,1854583,550187,29711,178723,1093143,0,1955881,1957679,550925,551146,321750,560855,299449,1955640,1955726,1955718,0,157167,0,0,0,760125,760205,760221,761237,761037,761301,761397,760941,760189,760181,761125,760469,760661,760277,760421,758535,760373,761005,760517,760229,760877,760325,760973,760141,760117,761365,761101,760149,761437,760845,760133,760173,1959834,760909,760197,761173,760157,68358,68328,68323,63217,60845,62772,62778,182482,182477,68353,63210,62783,62789,271486,182487,62452,60852,271491,271501,271804,0,76960,62798,63244,77012,61003,76997,62813,76388,63915,761487,62475,78690,66299,66262,0,0,0,66128,77334,77324,77319,77329,77344,77339,77297,0,150752,77605,63240,62794,63261,63188,63193,0,0,0,0,0,0,77007,76982,76992,76987,76977,77002,63178,61113,68348,62479,62498,63224,329751,63203,75508,61072,61008,271496,78224,62471,62802,182492,68333,60898,68343,90672,91868,91409,91404,91414,91424,91419,91429,91765,91785,91795,91760,91820,91745,91750,91755,91800,91790,91780,91805,91770,91810,91775,91815,91843,91851,91825,91691,91835,75056,75036,70628,79495,74497,934815,934811,934875,934868,0,0,935041,935049,935025,935017,935033,934939,934946,934723,934725,934727,159472,51586,53624,53641,79151,52907,51707,300206,79395,53660,51581,50956,621960,51167,51096,51249,158293,159726,159712,159631,159542,158611,52716,79268,79193,52213,52228,52218,51023,599199,754948,53307,51826,51866,597109,50901,53067,52854,12291,300285,172713,75170,75203,75190,598038,176422,176765,598399,178176,755092,754885,300507,30Line truncated
de: [529315,528124,530410,529380,26272,60873,256874,256880,256862,528854,528828,1031749,529355,60819,60814,63475,63495,60809,63480,60863,60824,224296,224291,224286,224281,224271,224276,224220,258800,527293,527442,527321,527187,526817,527238,526864,527385,528085,527528,527593,527080,527708,527572,526610,526638,526664,526578,527765,526493,526550,527744,527680,526733,526715,526790,526762,526687,527340,527632,527269,527100,527405,527461,526519,528162,528146,527507,526259,531166,528068,528552,529280,531046,61753,530972,529589,258349,530813,59169,530224,530516,321001,328922,528313,530002,258908,528040,160233,835780,531101,530853,528880,528953,529458,529218,26267,530251,530282,62599,528511,527948,835794,258777,528930,530994,530349,529426,530077,528418,529635,4713,61791,61787,529956,258354,527841,529303,530835,528254,529557,529568,527898,531147,527877,61687,530390,529716,258784,258770,258899,529107,526845,62586,530311,29250,526401,528741,529784,61308,62334,60568,60496,253509,526168,528391,526338,526423,526317,527995,530725,531218,528621,528644,528452,528475,527978,13530,530241,26594,63455,59200,63450,63500,63470,26252,526366,530159,528537,529754,1031277,227765,530908,226389,529917,530457,529661,26257,26299,160255,1072761,1072674,1072696,527918,60868,528685,529023,530205,258894,68330,528967,63240,530370,526462,529609,62558,279404,0,531181,227592,329070,330663,529693,530431,530644,530668,530594,529083,529736,527482,530181,528812,530928,528784,61781,62862,63225,61560,61591,530875,530788,526441,526998,526958,526905,529128,530941,529176,530705,529253,530745,530539,222439,61504,61339,530489,26262,528353,529884,529848,529406,531021,528991,26277,26294,60829,258332,258889,529814,529161,529061,530121,530039,528600,528911,528371,328935,528189,1072643,1072650,1072568,1072665,60858,526240,529447,530574,529976,529476,529335,529936,1031653,1031640,528768,328946,528232,526221,526149,258811,63881,527858,529528,528579,529498,528276,62545,62612,62675,258791,95161,95253,1839014,1839055,1839023,1839025,75000,559270,592770,592760,592754,298334,557804,560054,24820,24831,71573,592033,592004,1838737,1843476,1843599,1843659,1843788,1851415,1819501,1819504,1819531,1819534,1819589,1819494,1819476,1819524,1819381,1819559,924163,150691,0,89750,89180,89725,89720,89745,89735,89740,89730,0,1943064,569910,304739,29721,79351,79370,0,79746,0,920856,921258,920797,920824,920840,921870,920725,919939,29133,0,317577,317917,317912,0,1073934,317940,922807,12765,150408,80401,79612,79594,79635,79617,79658,79640,80432,29759,91980,91896,92504,92597,92612,92617,92518,92602,92607,95303,95334,95436,95426,95441,95431,95446,90663,0,550892,0,568933,569898,1950431,0,324092,922769,29102,569710,569794,79322,29478,29837,29819,29828,89685,89715,89695,89690,89710,89705,89700,568792,923827,922223,23787,23803,924595,95368,95373,0,1031319,1031341,569043,304780,0,181578,181721,181751,181741,181726,181746,181736,181731,181716,0,0,0,29749,568812,924835,569925,89785,89765,89760,89755,89780,89775,89770,93677,93758,93743,93753,93738,0,919637,0,323794,92364,317922,923429,922897,922934,602947,602965,602983,0,29600,88825,88842,324334,324265,324295,324290,324270,324285,324260,324275,324280,80295,0,603241,603837,604445,603001,602465,602192,602178,29594,29585,150612,150604,150625,150619,76014,1158014,1157891,1157954,1158128,569930,569935,171643,324122,1069240,256930,0,922971,923591,923655,569017,6843,58328,569940,29754,1857983,1858066,1857959,1858001,1858017,1857936,1858031,1858060,550657,550592,1824151,1824128,1855878,1856008,1855977,1855904,1855963,1855928,1855896,550187,29721,178735,1093149,0,1955832,1957630,550916,551137,321742,560851,299450,1955599,1955686,1955677,0,157172,0,0,0,760137,760217,760233,761249,761049,761313,761409,760953,760201,760193,761137,760481,760673,760289,760433,758547,760385,761017,760529,760241,760889,760337,760985,760153,760129,761377,761113,760161,761449,760857,760145,760185,1959803,760921,760209,761185,760169,68350,68320,68315,63259,60892,62814,62820,182471,182466,68345,63252,62825,62831,271459,182476,62494,60899,271464,271474,271777,66693,76939,62840,63286,76985,61050,76970,62855,76367,63957,761499,62517,78661,66291,66254,66203,66225,66168,66126,77304,77294,77289,77299,77314,77309,77270,150706,150754,77575,63282,62836,63303,63230,63235,65858,328904,328349,328352,0,328228,76980,76955,76965,76960,76950,76975,63220,61155,68340,62521,62540,63266,329748,63245,75481,61114,61055,271469,78194,62513,62844,182481,68325,60945,68335,90667,91865,91404,91399,91409,91419,91414,91424,91760,91780,91790,91755,91815,91740,91745,91750,91795,91785,91775,91800,91765,91805,91770,91810,91840,91850,91820,91686,91832,75029,75009,70620,79438,74470,934786,934782,934847,934839,935147,935151,935026,935038,935002,934990,935014,934912,934919,934694,934696,934698,159472,0,0,0,79122,0,0,300207,79338,0,0,0,621960,0,0,0,158298,159726,159712,159631,159542,158616,0,0,79164,0,0,0,0,599207,754948,0,0,0,597116,0,0,0,12288,300286,172725,75143,75176,75163,598046,176434,176777,598407,178188,755092Line truncated
it: [529031,528005,530046,529086,26264,60871,256874,256880,256862,528623,528610,1031749,529065,60817,60812,63482,63502,60807,63487,60861,60822,224301,224296,224291,224286,224276,224281,224225,258800,527250,527386,527276,527149,526841,527196,526882,527342,527972,527475,527533,527053,527625,527512,526601,526640,526676,526576,527686,526494,526546,527654,527598,526758,526729,526811,526774,526697,527292,527565,527221,527069,527362,527402,526520,528045,528023,527452,526263,530732,527952,528369,528995,530629,61760,530548,529304,258349,530399,59167,529874,530145,320987,328935,528165,529672,258908,527930,160214,835781,530675,530436,528636,528704,529167,528930,26259,529899,529927,62606,528324,527843,835795,258777,528682,530569,529973,529129,529730,528254,529346,4709,61798,61794,529628,258354,527764,529010,530419,528115,529262,529283,527809,530712,527793,61694,530028,529414,258784,258770,258899,528821,526864,62593,529955,29242,526394,528514,529471,61315,62341,60566,60494,0,526175,528232,526332,526411,526304,527895,530314,530780,528429,528451,528266,528288,527881,13534,529888,26586,63462,59198,63457,63507,63477,26244,526361,529798,528347,529449,1031277,227770,530487,226394,529586,530092,529369,26249,26291,160236,1072764,1072677,1072699,527822,60866,528482,528756,529851,258894,68338,528719,63247,529993,526462,529323,62565,279404,526197,530751,227597,329090,330690,529391,530068,530252,530268,530213,528801,529429,527426,529829,528594,530506,528559,61788,62869,63232,61567,61598,530456,530369,526437,526994,526976,526930,528843,530525,528897,530293,528969,530331,530166,222444,61511,61346,530120,26254,528192,529563,529526,529107,530596,528738,26269,26286,60827,258332,258889,529491,528878,528779,529772,529698,528410,528667,528213,328951,528068,1072646,1072653,1072571,1072668,60856,526245,529152,530196,529649,529184,529048,529608,1031653,1031640,528542,328970,528096,526220,0,258811,63888,527774,529232,528390,529200,528134,62552,62619,62682,258791,95173,95265,1838500,1838534,1838507,1838509,75102,559278,592757,592752,592747,298334,557812,560062,24812,24823,71594,592034,592003,1838224,1842422,1842533,1842593,1842696,1851423,1819225,1819228,1819252,1819255,1819310,1819217,1819205,1819244,1819128,1819278,924146,0,0,89760,89190,89735,89730,89755,89745,89750,89740,0,1941607,569911,304739,29712,79478,79497,49995,79873,50049,920855,921257,920796,920823,920839,921869,920724,919938,29125,0,317573,317913,317908,50229,1073937,317936,922806,12769,150407,80528,79739,79721,79762,79744,79785,79767,80559,29750,91983,91899,92507,92600,92615,92620,92521,92605,92610,95315,95346,95448,95438,95453,95443,95458,90670,150307,550899,150348,568941,569899,1950432,50297,323898,922768,29094,569711,569795,79449,29470,29828,29810,29819,89695,89725,89705,89700,89720,89715,89710,568800,923810,922222,23780,23796,924578,95380,95385,0,1031319,1031341,569048,304780,150401,181597,181740,181770,181760,181745,181765,181755,181750,181735,49850,0,0,29740,568820,924818,569926,89795,89775,89770,89765,89790,89785,89780,93689,93770,93755,93765,93750,150246,919636,50291,323600,92367,317918,923428,922896,922933,602935,602953,602971,50211,29591,88835,88852,324130,324061,324091,324086,324066,324081,324056,324071,324076,80422,50036,603229,603825,604433,602989,602453,602180,602166,29584,29577,150609,150602,150623,150615,76121,1157844,1157730,1157786,1157949,569931,569936,171613,323923,1069243,256930,50017,922970,923590,923654,569025,6837,58334,569941,29745,1855673,1855769,1855657,1855692,1855710,1855637,1855732,1855764,550666,550595,1823011,1822993,1854702,1854824,1854797,1854730,1854786,1854759,1854724,550187,29712,178705,1093151,50336,1955866,1957664,550923,551144,321727,560859,299452,1955623,1955710,1955701,50349,157157,50238,50280,50362,760128,760208,760224,761240,761040,761304,761400,760944,760192,760184,761128,760472,760664,760280,760424,758538,760376,761008,760520,760232,760880,760328,760976,760144,760120,761368,761104,760152,761440,760848,760136,760176,1959808,760912,760200,761176,760160,68358,68328,68323,63266,60890,62821,62827,182490,182485,68353,63259,62832,62838,271474,182495,62501,60897,271479,271489,271792,66700,77046,62847,63293,77094,61048,77079,62862,76474,63964,761490,62524,78773,66297,66260,66208,66231,66171,66128,77414,77404,77399,77409,77424,77419,77379,0,150747,77685,63289,62843,63310,63237,63242,0,328917,0,328362,328223,0,77089,77064,77074,77069,77059,77084,63227,61162,68348,62528,62547,63273,329768,63252,75583,61121,61053,271484,78304,62520,62851,182500,68333,60943,68343,90674,91869,91411,91406,91416,91426,91421,91431,91767,91787,91797,91762,91822,91747,91752,91757,91802,91792,91782,91807,91772,91812,91777,91817,91843,91852,91827,91693,91836,75131,75111,70628,79565,74572,934806,934803,934865,934858,935149,935152,935034,935043,935016,935007,935025,934929,934936,934715,934717,934719,159453,51636,53674,53691,79234,52957,51757,300209,79465,53710,51631,51006,621958,51217,51146,51299,158281,159707,159693,159612,159523,158599,52766,79351,79276,52263,52278,5226Line truncated
es: [529173,528047,530289,529245,26270,60823,256874,256880,256862,528742,528721,1031749,529214,60769,60764,63433,63453,60759,63438,60813,60774,224300,224295,224290,224285,224275,224280,224224,258800,527227,527378,527258,527134,526820,527189,526866,527326,528016,527470,527526,527022,527628,527503,526611,526650,526688,526576,527694,526493,526548,527668,527594,526754,526723,526790,526771,526706,527276,527557,527207,527043,527353,527396,526519,528090,528068,527447,526260,531030,527998,528434,529131,530932,61711,530855,529471,258349,530678,59119,530110,530399,320992,328934,528200,529901,258908,527977,160236,0,530970,530722,528763,528825,529329,529065,26265,530133,530150,62557,528385,527882,0,258777,528808,530872,530198,529289,529968,528298,529513,4710,61749,61745,529848,258354,527790,529158,530701,528158,529426,529448,527845,531008,527825,61645,530257,529604,258784,258770,258899,528953,526848,62544,530167,29248,0,528606,529670,61266,62292,60518,60446,0,526169,528274,0,526395,526312,527933,530582,531081,528510,528531,528320,528345,527915,13530,530124,26592,63413,59150,63408,63458,63428,26250,526341,530032,528416,529647,1031277,227769,530789,226393,529805,530343,529535,26255,26297,160258,1072761,1072674,1072696,527861,60818,528570,528883,530085,258894,68358,528845,63198,530218,526449,529491,62516,279404,526198,531049,227596,0,330685,529570,530313,530510,530531,530477,528921,529627,527417,530063,528698,530808,528656,61739,62820,63183,61518,61549,530749,530643,526421,526964,526940,526903,528989,530832,529039,530556,529098,530602,530421,222443,61462,61297,530372,26260,528225,529779,529734,529266,530907,528864,26275,26292,60779,258332,258889,529691,529027,528904,530004,529933,528484,528791,528254,328949,528117,1072643,1072650,1072568,1072665,60808,526242,529315,530455,529871,529351,529194,529829,1031653,1031640,528635,328966,528140,526222,526149,258811,63839,527808,529398,528460,529370,528176,62503,62570,62633,258791,95154,95246,1838736,1838776,1838745,1838747,75137,559287,592778,592774,592769,298334,557813,560071,24818,24829,71616,592043,592006,1838451,1842873,1842981,1843045,1843153,1851424,1819501,1819443,1819501,1819474,1819536,1819432,1819417,1819462,1819339,1819501,924543,150689,1510290,89752,89182,89727,89722,89747,89737,89742,89732,1509001,1942287,569921,304728,29717,79504,79523,49993,79899,50047,920856,921648,920797,920824,920840,922260,920725,919939,29131,1510357,317573,317913,317908,50227,1073934,317936,923197,12765,150407,80554,79765,79747,79788,79770,79811,79793,80585,29755,91975,91891,92499,92592,92607,92612,92513,92597,92602,95296,95327,95429,95419,95434,95424,95439,90670,150308,550902,150349,568950,569909,1950435,50295,324089,923159,29100,569721,569805,79475,29476,29833,29815,29824,89687,89717,89697,89692,89712,89707,89702,568809,924207,922613,23778,23794,924975,95361,95366,1510214,1031319,1031341,569057,304769,150402,181585,181728,181758,181748,181733,181753,181743,181738,181723,49848,2078033,2078061,29745,568829,925215,569936,89787,89767,89762,89757,89782,89777,89772,93670,93751,93736,93746,93731,150247,919637,50289,323790,92359,317918,923819,923287,923324,602957,602975,602993,50209,29596,88827,88844,324321,324252,324282,324277,324257,324272,324247,324262,324267,80448,50034,603251,603823,604431,603011,602475,602202,602188,29589,29583,150609,0,150623,150615,76150,1158057,1157941,1157989,1158177,569941,569946,171629,324112,1069240,256930,50015,923361,923981,924045,569034,6833,58284,569951,29750,1857778,1857861,1857762,1857796,1857813,1857738,1857832,1857855,550664,550596,1823861,1823842,1855709,1855852,1855817,1855739,1855798,1855768,1855727,550187,29717,178721,1093151,50334,1955868,1957666,550926,551147,321732,560868,299448,1955631,1955718,1955709,50347,0,50236,50278,50360,760135,760215,760231,761247,761047,761311,761407,760951,760199,760191,761135,760479,760671,760287,760431,758545,760383,761015,760527,760239,760887,760335,760983,760151,760127,761375,761111,760159,761447,760855,760143,760183,1959824,760919,760207,761183,760167,68378,68348,68343,63217,60842,62772,62778,182478,182473,68373,63210,62783,62789,271494,182483,62452,60849,271499,271509,271812,66717,77075,62798,63244,77123,61000,77108,62813,76503,63915,761497,62475,78811,66313,66274,66217,66242,66178,66132,77443,77433,77428,77438,77453,77448,77408,150704,150752,77714,63240,62794,63261,63188,63193,65861,328916,0,328361,328224,0,77118,77093,77103,77098,77088,77113,63178,61113,68368,62479,62498,63224,0,63203,75618,61072,61005,271504,78333,62471,62802,182488,68353,60895,68363,90674,91863,91411,91406,91416,91426,91421,91431,91767,91787,91797,91762,91822,91747,91752,91757,91802,91792,91782,91807,91772,91812,91777,91817,91842,91848,91827,91693,91836,75166,75146,70648,79591,74607,934808,934805,934869,934860,935167,935170,935048,935059,935026,935015,935037,934935,934943,934717,934719,0,159475,51585,53623,53640,79272,52906,51706,300205,79491,53659,51580,50955,621952,51166,51095,51248,158293,159729,159715,159634,159545,158611,52715,79391,79314,52212,Line truncated
} as const;
+13 -4
View File
@@ -1,4 +1,5 @@
import type { HallOfFameMon, HallOfFameTeam } from "../party/hall-of-fame";
import { ID_LINE, operands, tileCoord } from "../rom/code";
import { PokemonData } from "../rom/pokemon";
import { JOHTO } from "../rom/profile";
import { fontTiles, FRAME_TILE, SPACE_TILE, textTiles } from "../rom/font";
@@ -82,8 +83,11 @@ export function displayHOFMon(
put(1, 16, [0x6e]);
text(2, 16, String(mon.level));
} else text(1, 16, String(mon.level));
put(7, 16, [0x73, 0x74, 0xf3]); // <ID>, № and /.
text(10, 16, String(mon.otId).padStart(5, "0"));
// .print_id_no: three tiles (<ID>, № and / in English; each release
// its own) and the ID, where the cartridge's instructions put them.
const [idAt, first, second, third, numberAt] = operands(data.reader, JOHTO["DisplayHOFMon.print_id_no"], ID_LINE);
put(...tileCoord(idAt), [first, second, third]);
text(...tileCoord(numberAt), String(mon.otId).padStart(5, "0"));
return screen;
}
@@ -104,8 +108,13 @@ export function hallOfFameScreen(
// "HOF Master!" needs a count of HOF_MASTER_COUNT + 1, which the capped
// count never reaches: the original's bug (docs/bugs_and_glitches.md)
// leaves every team "-Time Famer".
placeText(screen, 1, 2, title);
placeText(screen, 2, 2, String(team.win).padStart(3, " "));
// .print_num_hof: the title, then the count over it (at 2, 2 in English;
// after the words in the European releases).
const [, titleAt, , countAt] = operands(data.reader, JOHTO["_HallOfFamePC.print_num_hof"], [
0x11, "w", 0x21, "w", 0xcd, "w", 0x21, "w",
]);
placeText(screen, ...tileCoord(titleAt), title);
placeText(screen, ...tileCoord(countAt), String(team.win).padStart(3, " "));
return screen;
}
+23 -5
View File
@@ -1,8 +1,9 @@
import { SOUND } from "../audio/constants";
import { findMatch, match, nearPointer, tileCoord } from "../rom/code";
import { fontTiles, textTiles } from "../rom/font";
import { decompress } from "../rom/lz";
import { EGG } from "../rom/pokemon";
import { KANTO, RAM, TRAINER_CARD } from "../rom/profile";
import { KANTO, RAM, TRAINER_CARD, WRAM } from "../rom/profile";
import type { RomReader } from "../rom/reader";
import { printerDisconnected } from "./printer";
import { blankScreen, romPalette, SCREEN_BUTTONS, SCREEN_WIDTH, type TileScreen } from "./screen";
@@ -55,12 +56,13 @@ export function diplomaScreen(r: RomReader, name: string, frame: number): TileSc
const palette = romPalette(r, TRAINER_CARD.PredefPals + r.byte(KANTO.PalPacket_Diploma + 1) * 8);
const screen = blankScreen(tiles, `diploma-${frame}`, [palette], `Diploma: ${name}`);
screen.map = Array.from(r.slice(KANTO.DiplomaPage1Tilemap, SCREEN_WIDTH * 18));
/** PlaceString; returns where it stopped (bc). */
const place = (p: number, x: number, y: number) => {
let column = x,
line = y;
for (let length = 0; length < 128; length++) {
const code = r.byte(p++);
if (code === 0x50) return;
if (code === 0x50) return line * SCREEN_WIDTH + column;
if (code === 0x4e) {
line += 2;
column = x;
@@ -71,9 +73,25 @@ export function diplomaScreen(r: RomReader, name: string, frame: number): TileSc
}
throw new Error("Unterminated diploma string.");
};
place(KANTO["PlaceDiplomaOnScreen.Player"], 2, 5);
textTiles(name).forEach((tile, i) => (screen.map[5 * SCREEN_WIDTH + 9 + i] = tile));
place(KANTO["PlaceDiplomaOnScreen.Certification"], 2, 8);
// The strings where the cartridge's instructions put them: "PLAYER"
// first; then English the empty string, the name at a fixed place and
// the certification, the European releases the name a tile after
// "PLAYER" and the certification.
const routine = KANTO.PlaceDiplomaOnScreen;
const at = (address: number) => tileCoord(address);
const first = findMatch(r, routine, 0x40, [0x11, "w", 0x21, "w", 0xcd, "w"]);
const afterPlayer = place(nearPointer(r, routine, first.values[0]), ...at(first.values[1]));
const english = match(r, first.end, [0x11, "w", 0x21, "w", 0xcd, "w", 0x11, "w", 0x21, "w", 0xcd, "w", 0x11, "w", 0x21, "w"]);
const european = english ? undefined : match(r, first.end, [0x11, "w", 0x60, 0x69, 0x23, 0xcd, "w", 0x11, "w", 0x21, "w"]);
let nameAt: number, certification: number, certificationAt: number;
if (english) [, , , , nameAt, , certification, certificationAt] = english.values;
else if (european) {
nameAt = WRAM.wTilemap + afterPlayer + 1;
[, , certification, certificationAt] = european.values;
} else throw new Error("This cartridge's diploma is not ported yet.");
const [nameX, nameY] = at(nameAt);
textTiles(name).forEach((tile, i) => (screen.map[nameY * SCREEN_WIDTH + nameX + i] = tile));
place(nearPointer(r, routine, certification), ...at(certificationAt));
return screen;
}
+67 -9
View File
@@ -1,4 +1,6 @@
import type { GameSound } from "../audio/sound";
import { currentRevision, type Revision } from "../rom/revision";
import { findOperands, ID_LINE, tileCoord } from "../rom/code";
import { SOUND } from "../audio/constants";
import { addHallOfFameEntry, type HallOfFameMon } from "../party/hall-of-fame";
import { textTiles } from "../rom/font";
@@ -294,8 +296,12 @@ export function hallOfFamePlayerCard(
placeTextbox(screen, 0, 2, 8, 9);
placeTextbox(screen, 0, 12, 4);
placeText(screen, 2, 4, name);
screen.map.splice(6 * SCREEN_WIDTH + 1, 3, 0x73, 0x74, 0xf3);
placeText(screen, 4, 6, String(id).padStart(5, "0"));
// <ID>, № and / (each release its own tiles) and the ID, where the
// cartridge's instructions put them.
const [idAt, first, second, third, numberAt] = findOperands(r, KANTO.HOF_AnimatePlayerPic, 0x100, ID_LINE);
const [idX, idY] = tileCoord(idAt);
screen.map.splice(idY * SCREEN_WIDTH + idX, 3, first, second, third);
placeText(screen, ...tileCoord(numberAt), String(id).padStart(5, "0"));
placeText(screen, 1, 8, readString(r, KANTO["HOF_AnimatePlayerPic.PlayTime"], defaultTextContext(name)));
placeText(screen, 3, 9, String(time.hours).padStart(3, " "));
screen.map[9 * SCREEN_WIDTH + 6] = HALLOFFAME_COLON;
@@ -383,9 +389,10 @@ const CREDITS_END = 0xff,
CREDITS_MUSIC = 0xfb,
CREDITS_WAIT2 = 0xfa,
CREDITS_THEEND = 0xf9;
/** constants/credits_constants.asm: the one string ParseCredits prints
* from column 2 rather than 0. */
const COPYRIGHT = 0x62;
/** constants/credits_constants.asm's COPYRIGHT: the one string
* ParseCredits prints from column 2 rather than 0, read from its own
* `cp COPYRIGHT` (the European releases have six more strings before it). */
const copyright = (r: RomReader) => findOperands(r, KANTO.ParseCredits, 0x80, [0xf1, 0xfe, "b", 0x28])[0];
/** How many VBlanks pass while ParseCredits runs each group of commands
* (one per wait), measured on the cartridge (tests/reference-credits.spec
* .ts): printing a name takes about 60 of a frame's 154 lines, and how
@@ -393,10 +400,50 @@ const COPYRIGHT = 0x62;
* so the spills are recorded rather than counted from cycles. They hold
* for credits that B does not shorten. CREDITS_MUSIC's own DelayFrame is
* not counted here. */
const PARSE_SPILLS = [
const PARSE_SPILLS: Partial<Record<Revision, readonly number[]>> = {
"1.1": [
1, 0, 0, 1, 1, 2, 2, 1, 3, 2, 1, 0, 3, 1, 2, 2, 2, 2, 1, 1, 1, 0, 2, 1, 2, 1, 2, 1, 0, 1, 1, 1,
1, 1, 1, 1, 2, 2, 2, 1, 2, 1, 1, 1, 0, 0,
];
],
// Fitted to each release's credits on the cartridge (as 1.1's were
// measured), the first parse before any sample kept at 1.1's.
fr: [
1, 0, 0, 1, 1, 2, 2, 1, 3, 2, 1, 0, 3, 1, 2, 2, 2, 2, 1, 1, 1, 0, 2, 1, 2, 1, 2, 1, 0, 1, 1, 2,
1, 1, 1, 2, 2, 2, 2, 1, 2, 1, 1, 1, 0, 0,
],
de: [
1, 0, 0, 1, 1, 2, 2, 1, 3, 2, 1, 0, 3, 1, 2, 2, 2, 2, 1, 1, 1, 0, 2, 1, 2, 1, 2, 1, 0, 1, 1, 2,
1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 0, 0,
],
it: [
1, 0, 0, 1, 1, 2, 2, 1, 3, 2, 1, 0, 3, 1, 2, 2, 2, 2, 1, 1, 1, 0, 2, 1, 2, 1, 2, 1, 0, 2, 1, 2,
1, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 0, 0,
],
es: [
1, 0, 0, 1, 1, 2, 2, 1, 3, 2, 1, 0, 3, 1, 2, 2, 2, 2, 1, 1, 1, 0, 2, 1, 2, 1, 2, 1, 0, 1, 1, 2,
1, 2, 1, 2, 2, 2, 2, 1, 2, 1, 1, 1, 0, 0,
],
};
/** Groups that spill otherwise while B is held (the music then sits
* elsewhere at each parse, so _UpdateSound's share of VBlank differs),
* fitted the same way. */
const PARSE_SPILLS_HELD: Partial<Record<Revision, Readonly<Record<number, number>>>> = {
es: { 39: 2 },
};
const english = (revision: Revision) => (revision === "1.0" || revision === "au" ? "1.1" : revision);
/** The spills of the cartridge in use: the European releases' credits
* have their own staff, so their own groups. The English cartridges share
* 1.1's script. */
export const parseSpills = () => {
const spills = PARSE_SPILLS[english(currentRevision())];
if (!spills) throw new Error("This cartridge's credits are not measured yet.");
return spills;
};
/** parseSpills, with the groups that spill otherwise while B is held. */
export const heldSpills = () => {
const held = PARSE_SPILLS_HELD[english(currentRevision())] ?? {};
return parseSpills().map((spill, group) => held[group] ?? spill);
};
/** Credits' jumptable (Credits_Jumptable.Jumptable), one entry a frame. */
const enum Step {
Parse = 0,
@@ -438,6 +485,9 @@ export class CreditsMachine {
readonly tilemap: number[];
readonly shown: number[];
readonly vram: Uint8Array;
private readonly copyright: number;
/** The buttons held this frame (step). */
private held = "";
private palettes: Palette[];
private readonly frames: Uint8Array;
private readonly blank: Uint8Array;
@@ -448,7 +498,12 @@ export class CreditsMachine {
private readonly r: RomReader,
base: Uint8Array,
readonly skippable: boolean,
/** Measured spills, by default the cartridge's (parseSpills), and
* those while B is held (heldSpills). */
private readonly spills: readonly number[] = parseSpills(),
private readonly spillsHeld: readonly number[] = spills === parseSpills() ? heldSpills() : spills,
) {
this.copyright = copyright(r);
this.vram = base.slice();
// Credits_LoadBorderGFX's .init: wCreditsBlankFrame2bpp, 16 tiles of
// color 2.
@@ -495,6 +550,7 @@ export class CreditsMachine {
scene: this.scene,
borderFrame: this.borderFrame,
lyOverride: this.lyOverride,
group: this.group,
};
}
/** wBGPals2's first three palettes as stored words. */
@@ -547,6 +603,7 @@ export class CreditsMachine {
* each VBlank that passes inside the entry: CREDITS_MUSIC's DelayFrame
* ("music", after MUSIC_NONE) and a parse running into later frames. */
*step(held: string): Generator<"music" | "frame", boolean, void> {
this.held = held;
// Credits_HandleBButton: B makes the timer run faster once the first
// 13 script bytes have passed.
if (held === "b" && this.skippable && this.pos >= 0x0d && this.timer) this.timer--;
@@ -627,7 +684,8 @@ export class CreditsMachine {
}
this.bgMode = 0;
this.tilemap.fill(SPACE, 5 * SCREEN_WIDTH, 17 * SCREEN_WIDTH);
const spills = PARSE_SPILLS[this.group++] ?? 0;
const table = this.held === "b" && this.skippable ? this.spillsHeld : this.spills;
const spills = table[this.group++] ?? 0;
for (let count = 0; count < 256; count++) {
const command = this.r.byte(KANTO.CreditsScript + this.pos);
// The VBlanks a long parse runs into pass before its last command,
@@ -674,7 +732,7 @@ export class CreditsMachine {
KANTO.CreditsStringsPointers + command * 2,
this.r.bank(KANTO.CreditsStringsPointers),
);
const x = command === COPYRIGHT ? 2 : 0;
const x = command === this.copyright ? 2 : 0;
this.placeString(pointer, x, 6 + this.get() * 2);
}
}