258 Commits

Author SHA1 Message Date
Retnuhytnuob 274ab00a8b Convert the 0x06... range to practical forms; mode lamp naming (#265)
Adds some define macro for specifying an address in the Board/Object VRAM space, indexed by the Block, Row, Col
Documents the usage of the block 2 + 6 lines of block 3, with a 'modulused crosssection of the board', and a tilemap that draws those in the correct color, for the section where the camera is. (this also explains the 'wrapping, with wrong colors' if viewing the BG layer 3.)
Adds a define macro for addressing with the 'board wrapped' memory content, so that the tile reads as its board relative position, rather than its vram memory position.
Applies macro in place of memory address, when working with the VRAM data.

Resolves #224
2026-09-17 00:21:56 -05:00
Retnuhytnuob 14547ba828 Cleanup AI comments, add usage disclaimer. (#264)
* cleanup data dump comments
* AI usage disclaimer
2026-09-12 22:59:53 -05:00
Retnuhytnuob d55c2eb214 Consts for Bonus Loop, remaining board element states (#263)
Helper macros:
* BoardIn/NotInActivityMobe
* Start Of Even Bonus loop & RayquazaCatchChanceTrip

States:
* Bonus stage loop
* Sapphire Shop Gate (plusle/minun) & index consts + shock wall anim state
* Spoink Launcher
* Makuhita
* Seedot
* Zigzagoon
* Pelipper
* Nuzleaf
2026-09-11 21:19:07 -05:00
Retnuhytnuob 465d69bdac BoardProc naming, EOB summary consts, Collision type consts / params (#261)
Adds switch consts for Collision:

BoardCollisionType, CollisionBounceBehaviorType, CollisionResolutionState
Also names some input/output params for collision functions.
Renames BoardProcess#[a/b] functions, to reflect what that phase does.
Adds enum vals for the CurrentBoardProcPairs array indexing

Adds switch consts for End of Ball Bonus phases, debug modes, Tilt Direction handling, Return location from bonus boards, demo variants

Now uses consts for the number of dex lines/characters per line.
2026-09-11 21:10:14 -05:00
Retnuhytnuob c9335f5e6e Hatch state cleanup (enums, var naming), CatchTileBurst Phases (#262)
State Enums for:
* CatchTileBurstPhase
* EggAnimationPhase
* CyndaquilPositions
* HatchMachineStates
2026-09-11 21:08:29 -05:00
Retnuhytnuob 95fdbfaeea Flipper consts, FX sequence consts, document the per frame proc indexes (#259)
* active fx type
* flipper and proc step documentation
2026-09-05 21:26:29 -05:00
Retnuhytnuob f263794b19 Palette_Mappings in Rom file 2026-09-04 22:06:27 -05:00
Retnuhytnuob 4f1c19c7ce Pal IX consts for main boards 2026-09-04 01:35:42 -05:00
Retnuhytnuob 5b1b8d9c08 Add consts for pal_IX 2026-09-03 21:37:58 -05:00
Retnuhytnuob 644e8c5c96 remaining oaml based dups 2026-09-01 23:23:40 -05:00
Retnuhytnuob cbbe689810 packed oam copy checkpoint1 2026-09-01 02:35:47 -05:00
Retnuhytnuob dc6735de3f voice group partial naming; remaining cry files 2026-08-31 23:38:39 -05:00
Retnuhytnuob 5bdef82621 name unused cries 2026-08-31 22:36:10 -05:00
Retnuhytnuob f6be9962aa remaining cries 2026-08-31 02:23:42 -05:00
Retnuhytnuob ba9460c229 cries through Numel 2026-08-31 01:35:43 -05:00
Retnuhytnuob 95d3530fa6 poke cry through 265 2026-08-31 00:56:14 -05:00
Retnuhytnuob de868cd7d7 . 2026-08-30 14:52:29 -05:00
Retnuhytnuob 58fad629a4 pal and addressing work 2026-08-29 23:53:37 -05:00
Retnuhytnuob 8b655cb324 freeze pal usage comment 2026-08-17 01:17:23 -05:00
Retnuhytnuob 013b9ac0c9 pokebal pall name updates 2026-08-17 00:58:46 -05:00
Retnuhytnuob d44a615136 Naming for Sprite Groups / sprite sets for bonus field select and ereader 2026-08-15 02:48:31 -05:00
Retnuhytnuob f3f8ba893d last of the Pals 2026-08-14 03:15:20 -05:00
Retnuhytnuob ef29d1b7a0 additional pal, and char block addressing 2026-08-13 02:44:26 -05:00
Retnuhytnuob c66aa92b16 Updated based on findings; split/color graphics. 2026-08-12 00:22:57 -05:00
Retnuhytnuob 96132c1a3e Merge branch 'master' into hud-tilemap-sources 2026-08-11 21:47:22 -05:00
simisonne ce68dfdbec Identify and dump board HUD tile graphics and pokedex info window tilemap
gBoardHudTilemapA and gBoardHudTilemapB are not tilemaps despite their
names: both blobs are 4bpp tile graphics for the board HUD, loaded to
charblock 1 tiles 320-351 and 352-415 on every board transition and
referenced from the BG0 tilemap buffer with palette bank 12. Extracted
as board_hud_tiles_a/b.png following the stage/main conventions.

gPokedexInfoWindowTiles is a genuine 32x32 u16 tilemap. Its content
rows 0-5 are a 26x6 window referencing tile indices 224-409, which are
sheet rows 7-12, cols 0-25 of the 32 wide gPokedexBgText_Gfx tileset.
Extracted as info_window_tilemap.bin following the pokedex tilemap
conventions (bg1/bg2/bg3_tilemap.bin).

All assets verified byte exact against baserom via gbagfx round trip;
make compare passes.
2026-08-11 13:55:28 +00:00
Retnuhytnuob 0f88c8fa38 Examined longer byte arrays for Oam potential
While these don't *have* to be oam entries, their placement in the file makes them likely. 
For the longer sets, I manually checked them to see whether the result of interpreting them as oam "made sense". (data that doesn't tends to give a number of affine/mode params, and paletteNum entries that aren't commonly applied.) - These were also checked for a certain level of regularity.

I suspect these may have been there at one point, and were overwritten with one or more shorter OAM collections at some point in their process of building the games.

These have been taged as gUnusedSpriteSets to distinguish them from the other entries.
2026-08-10 22:19:24 -05:00
Cyphgirl 86fed4e683 Name the unused timer warning palette, fix a stale address
gUnknown_086B0864 is not the slow palette - gTimerWarningPalette_Slow
already exists two labels down. All three differ only in colour 3, red
for _Fast and yellow for _Slow, and white here, so it is the white
member of the same set. Nothing points at it; the code alternates _Fast
and _Slow against gDefaultTimerPalette, which lives in rom_1.s.

gUnknown_086AACE6 carried an address comment of 0x086AACEC. The name is
the correct one: at 0x6AACE6 the count reads 1 and the entry matches
what is emitted, where at 0x6AACEC it would read 4252, and with the
right address the record ends exactly where the next label starts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 06:00:01 -04:00
Cyphgirl ee220ad614 Decode the last of rom_2.s
Ten of the eighteen gaps are sprite sets in the file's own format - a
.2byte count followed by that many six-byte entries - so they become
packed_sprite_oam runs like the sets around them. gUnknown_086AB804 is a
96x128 image in four quadrants, which is what a real one looks like.

Only decode a set whose address something in the ROM points to. Checking
that the shape and size bits form a legal sprite size is no filter at
all, since almost any small value passes: an earlier pass on this took
animation timing for OAM and emitted six sets whose entries were all
shape 0, size 0 and tile under 6, plus one that read the previous
structure at the wrong alignment and put sprites at x=454. make compare
passes on all of that, because it only proves the bytes round-trip.

The timing tables go in as .2byte literals. The 0x20 beside
gTimerWarningPalette_Fast is sixteen colours and goes in as a palette,
and gUnusedRomTail keeps its comment and becomes one opaque .bin, being
documented dead data including a stray copy of the save signature.

src/crt0.s now holds the only .incbin "baserom.gba" left in the repo, and
that one is the ROM header.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 20:35:01 -04:00
Cyphgirl ef5609226b Extract the unused mon hatch palettes
Each group is a 16-palette block, but LoadMonFieldSpriteGraphics and the
pokedex both index it as eggIndex % 6, so only the first six are ever
read - and those six are already named. The remaining ten per group (and
thirteen in group 5) are grey filler: 63 palettes with only 8 distinct
values between them, and no pointer to any of them anywhere in the ROM.

They have no art to generate them, so they go in as .gbapal.bin the way
gb_player does, one file per group.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 20:22:38 -04:00
Cyphgirl 7bc8cdd3cf Extract the remaining board strip filler
The last 42 blobs are the flat part of each board strip past its
feature's DMA length. Each becomes an image beside the art it trails,
at the art's own width where the tile count allows it.

ruby_board.inc and sapphire_board.inc now hold no baserom.gba at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 20:18:20 -04:00
Cyphgirl 5d931bb272 Extract the shop signs and fill the solid tails
A scan for pointers to every remaining blob found that six of them are
whole labels, not tails: gShopItemTilePointers reaches them, and they
draw the POKeMON MART and POKeMON CENTER signs in two variants of three
pieces. Bank 6, and the tilemap puts them at x=24.

The other 57 have no pointer anywhere in the ROM. They are the flat part
of the board strip past each feature's DMA length - grey on ruby, white
on sapphire - and 15 of them consist of nothing but solid tiles, so they
need no image at all and become .space and .fill runs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 20:14:55 -04:00
Cyphgirl 0fc6193243 Extract the trap indicators and sapphire's P square
Both boards' trap indicators are three states of a 2x2 block - the hole
with its shutters open, part way, and shut. Sapphire's P square is the
same shape over five blink frames.

Palettes follow the same brightness band as the earlier board work: the
band 1 copy, ruby bank 5 and sapphire bank 2 for the traps, bank 5 for
the P square. The band 0 copies of both would have given a different
answer, so this is a convention rather than a proof; the P square's
band 1 hit is a mixed-bank block and was ignored for that reason.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 19:50:09 -04:00
Cyphgirl cdd8518db7 Extract both boards' progress digits
DrawRuby/SapphireProgressDigits draws the progress level from these, so
the labels are digits, not the bonus arrows and bonus multiplier the old
names claimed. Ruby's are one tile per digit in a tens and a ones slot;
sapphire's are 8x16, so each digit is a top and bottom half in each slot.
Every label is exactly its 0x20 DMA length.

Ruby's block sits at x=19 in the board tilemap on bank 3. Sapphire's is
in BG0 at x=17, once per brightness band, and band 1 gives bank 11.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 19:46:50 -04:00
Cyphgirl 4867f38e83 Extract both boards' catch lights
Three lane slots, six states each, split into two 2-tile halves that the
tilemap stacks into a 2x2 block - the CATCH and EVO letters and the ball
icon, lit and unlit. States 0 and 1 are one label shared by all three
slots, which is why 3 x 6 x 2 pointers come to 28 labels.

The blocks sit at x=12, 14 and 16 in each board's BG0 tilemap, drawn once
per brightness band; taking the same band as the wailmer water gives ruby
bank 0 and sapphire bank 8, both of which put the lights on the playfield
tan the boards actually use.

Every label is exactly its DMA length apart from two on ruby, whose tails
become .space and one remaining incbin.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 19:43:12 -04:00
Cyphgirl b4e8a6d36e Extract the wailmer water and hatch machine tiles
AnimateRotatingBackground cycles three frames over four rows of 2, 4, 3
and 3 tiles - the water turning under the wailmer. Every tail past the
DMA length is zero, so the whole family becomes .space.

The board's BG0 tilemap draws that block at x=21 three times over, once
per brightness zone, on banks 15/14, 3 and 1; bank 3 is the one whose
fronds are gold the way the board shows them.

gHatchMachineDrawSegment is ten targets, each with an idle and a hit
state split into two halves of 2 tiles, all of them copied whole - so
these 38 need no tails at all. Bank 6, the machine's red and green.

Both families had address-suffixed labels; they now say which segment,
frame and state they are.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 19:20:14 -04:00
Cyphgirl 256cc6d1f3 Extract the board slingshot and saver lights
AnimateRuby/SapphireSlingshotHit copies five rows of 1, 2, 3, 3 and 2
tiles, which is the wedge itself; every byte past a row's DMA length is
zero, so the slingshots come out whole and their tails become .space.
Ruby's wedge is BG palette bank 2, sapphire's bank 1.

The saver rows are 6, 6, 5, 2 tiles on ruby and 7, 7, 6, 2 on sapphire -
Latios over red SAVER and Latias over blue SAVER, both on bank 0. Their
tails are not blank, since other board art shares the same ROM strip, so
those stay as incbins the way the arrows above them already do.

Sapphire's labels for both were address-suffixed placeholders; they now
use ruby's naming, with gSapphireSlingshotTilePtrs and
gSapphireSaverDisplayTilePtrs updated to match.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 19:14:25 -04:00
Cyphgirl 2da237945f Extract the catch sprite frame palettes
Each gMonCatchSpriteGroupN_Pal holds 16 palettes, but only the first five
were named. LoadCatchSpriteGraphics reads slot i*5 + mon for frame i, so
the palettes are striped frame-major while the graphics are mon-major:
every catch sprite is three 6x6 frames with a palette each - the mon's
own colours, the red capture flash, and the darkened silhouette.

A PNG carries one palette, so each sheet becomes three images and the
two .inc files reference the images and palettes in sequence. Slot 15 is
a colour-0-only palette shared by every group; it has no art, so it goes
in as catch_mon_pal_empty.gbapal.bin.

graphics/debug_ascii_font_extra.png was mislabelled palette data: its 384
bytes are group 16's frame 1 and 2 palettes for chikorita, cyndaquil,
totodile and aerodactyl plus the empty padding slots. Removed.

Every frame round-trips byte-exact in both directions, PNG to 4bpp
against the ROM tiles and PNG to gbapal against the ROM palette.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 18:56:51 -04:00
Retnuhytnuob 6ba75e3e2f Merge pull request #239 from simisonne/sapphire-lights-dump
Dump sapphire ball power up and hole lights
2026-08-09 14:45:51 -05:00
simisonne 7258683fc6 Dump sapphire ball power up and hole lights
Extract the sapphire board's ball power up and 'hole' light tile graphics from baserom into tracked PNG sources, following the folder conventions established by the ruby board. Resolves #231.
2026-08-09 13:08:22 +00:00
Cyphgirl cff0082a52 Extract the rom_1.s tilemap blob and correct two sheet names
Move the 854-byte blob after gSapphireBoardZigzagoonFx_Gfx out of inline
.2byte data into graphics/stage/unknown_085279CC.bin, labelled
gUnknown_085279CC. Both ends are pinned by real references, so its extent
is exact: the 0xC00 gfx copies above it and the pointer to gOptionsBGMList
below. Nothing reaches it -- no pointer in the ROM lands inside it at any
alignment, and .text ends 4.9MB earlier, so PC-relative forms cannot span
the gap either.

Rename bumper_plusle_fx_tail to compressed_numbers and give it its own
label at 0x084ECF6C. It is a narrow digit font holding 0-9 plus a trailing
glyph, not overrun tiles from the Plusle hit bumper sheet it was filed
under -- it sits past the whole mon_portraits block, nowhere near that
sheet's stride.

Rename the capture_screen "unreferenced gap" segment to
capture_screen_absorb_fx_frame_0. The sheet loads at OBJ tile 704, and
shifting gMonCatchBallAbsorbPokemonFxSpriteSet's ball-adjacent entries back
by 21 tiles maps t123/t127/t129 onto t102/t106/t108 -- the two ball
sub-slots are 21 tiles apart, one per absorb frame.

ROM stays byte-identical to baserom.gba throughout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 21:20:20 -04:00
Retnuhytnuob 158ba46210 naming patch 2026-08-08 15:36:15 -05:00
Cyphgirl c15304397d Extract the last of the rom_1.s baserom blobs
The remaining seventeen, in one pass. Nothing in rom_1.s reads baserom.gba any
more; the two lines that still name it are commented out and predate this work.

Seven are ordinary slot sheets and went in the usual way, each with a SLOTS entry
that derives its bank from full coverage: the flying Rayquaza (one 67-tile sprite
of 14 pieces, three sub-tile phases so the shape approximates two of them), the
Kyogre surfacing splash, both Chikorita projectile sheets, the hatch machine
spark, the Linoone side bumper, and the decimal digits. The digits get the same
treatment as the alphabet, one 8x16 glyph per metatile laid ten across, so the
sheet reads as 0123456789.

Four are not graphics. gPokedexInfoWindowTiles is 1024 BG map entries and becomes
a .bin. gPokeballCaptureOamFrames is 40 framesets of six OAM entries and is
listed as raw attributes, three halfwords a line, since nothing has confirmed the
field split. The tail under gSapphireBoardZigzagoonFx_Gfx is 427 halfwords that
no pointer reaches and whose length is not a multiple of the tile size, so it is
listed flat too. gDefaultCustomButtonConfigTileIds is ten bytes and becomes
.byte.

Three are palette tails past the end of an indexed set, and they exposed
something: *.gbapal is gitignored here, because every palette in the tree is a
build product of a .png that carries it. A palette with no art has nothing to be
generated from, so a bare .gbapal would have been untracked and deleted by the
next make clean. They take the .gbapal.bin suffix instead, which is what
gb_player.gbapal.bin already does for the same reason.

Verified past the usual gates: make clean, rebuild every tool, rebuild the ROM
from the checked-in sources alone -- pokepinballrs.gba: OK. That is what would
have caught the palette mistake, and is worth doing whenever an extraction adds a
file type the build generates.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 10:17:50 -04:00
Cyphgirl d510ebd0df Extract the catch tile burst start sheet from baserom
gCatchTile_BurstStart_Gfx is 8 frames of the lightning strike drawn by
gCatchTile_RevealOamFramesets, and it is the last of the burst family. Six frames
have their pieces on one sub-tile phase and consume the slice in order, so they
take shapes; frame 4 has a piece 4px off and takes an approximate one.

I had this filed as blocked, on the grounds that frame 6 contains an overlap no
layout can express. That was half right and it cost the other seven frames. The
overlap is real -- a 16x16 at t204 and a 16x32 at t207 both claim t207, so that
frame's tiles are not one run and it stays a strip -- but it says nothing about
the rest of the sheet, and treating the whole thing as blocked was the error.

The frames were worth generating rather than hand-computing: 6 shapes, up to
78 cells each. The helper takes a frameset's piece list and either returns a
shape or explains why not. It rejects on three grounds, and the third only turned
up here: mixed sub-tile phases, two pieces landing on one grid cell, and pieces
that do not consume the tile slice in order. That last check is what correctly
sends frame 6 to a strip -- a grid-overlap test alone accepts it, because the two
pieces do not collide on screen, only in the tile numbers they read.

t219 is unused and t240..255 are unreferenced. Palette from
gCatchTile_BurstStart_Pal into OBJ bank 14, so no vote.

Rebuilt sheet matches the ROM blob before and after recolouring, check passes,
make compare passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 10:05:08 -04:00
Cyphgirl 91f1f7dfe1 Extract the catch tile burst stage 2 sheet from baserom
gCatchTile_BurstStage2_Gfx is 16 sprites of 16x16, a uniform 2x2 grid with
nothing irregular anywhere in it, so one -oam entry covers the whole sheet.

The framesets are what make it look harder than it is.
gCatchTile_BurstRevealOamFramesets0 draws six 16x16 pieces at a time into a 3x2
block of cells, reusing the same few sprites in different arrangements, so the
sheet is a bank of quarters the animation picks from rather than a run of whole
frames. Reading the tile numbers as frame boundaries is what made this look like
an irregular composite earlier; reading them as cell contents makes the grid
obvious. Only t0..35 are ever named, and t36..63 are unreferenced but still
inside the copy.

Palette from gCatchTile_BurstStage2_Pal into OBJ bank 14 in the copy right after,
so no vote and no overrides.

Rebuilt sheet matches the ROM blob before and after recolouring, check passes,
make compare passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 10:00:53 -04:00
Cyphgirl 7de2b83237 Extract both board HUD tilemaps from baserom
gBoardHudTilemapA and gBoardHudTilemapB are BG map entries, not tiles: 512 and
1024 of them, 16 and 32 rows of 32. all_board_setup.c copies A to 0x06006800 and
B to 0x06006C00 on every board, so the two sit end to end and make one 48-row
strip, A on top.

They go in as .bin beside the other tilemaps rather than through gbagfx, the same
treatment as the intro scene maps. The names already said tilemap, and the entry
histogram agrees: 64 and 30 distinct halfwords, with the palette nibble spread
across banks rather than the near-uniform fill that marks a background.

Decoding the tile indices shows A dense across all 32 columns and B occupying
only columns 8 to 27, which is consistent with one strip whose lower two thirds
are inset.

Both labels already carried their trailing .space 0x20, so only the incbins
changed. make compare passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 09:58:17 -04:00
Cyphgirl e19e280e0d Extract the catch target collision map from baserom
gCatchTargetCollisionBitmap is not graphics. CheckCatchTargetCollision indexes it
[y * 48 + x] against the ball's offset from the Jirachi centre, bounds-checked to
48 on both axes, which accounts for the label exactly: 2304 bytes, one per
position. Bit 7 is the solid flag and the low seven bits are the surface angle
the collision answers with, scaled by 512.

So it goes to data/board_data/collision as a .bin with its dimensions in the
name, next to the flipper map and the per-board entity maps, rather than through
gbagfx. tools/collision_viewer already reads that family.

Decoding it confirms the reading: the solid cells form a disc filling 41% of the
square, and the angles of the solid cells run the full range around it, which is
what a round target should look like.

make compare passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 09:55:33 -04:00
Cyphgirl 81bab75500 Extract both pond bumpers from baserom
gRubyFlashingTiles_Secondary is the Chinchou pond bumper. It and gLotadBumperTiles
are the two branches of one loop in ruby_process3_entities_2.c, which picks a
bumper by field variant and streams 0x100 into tile 372 + 8i for the three of
them. gRubyBumpersSpriteSet draws each as a single 16x32, twice side by side, so
both sheets are 2 tiles wide and 11 frames tall.

Taken as a pair for the same reason as the ball spawn glows: one DMA site, one
sprite set, one geometry, so the second sheet costs nothing once the first is
understood. Both palettes are settled rather than voted -- each branch loads its
own into OBJ bank 9 in the copy right after the tiles, and both gbapals were
already extracted under matching names.

The renders confirm the naming: Chinchou comes out blue with yellow antennae,
Lotad green with its pad. That is the sixth label in this series describing
something other than its contents, and as usual the sprite set and the palette
label both had it right.

Both rebuilt sheets match the ROM blob before and after recolouring, check
passes, make compare passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 09:52:40 -04:00
Cyphgirl dd98b58c23 Extract the ball upgrade fx frames from baserom
gBallShadowTileGraphics is not a shadow. The group all_board_process7.c streams
these into is FIELD_SG_BALL_UPGRADE_FX, gBallUpgradeFxSpriteSet draws them as a
single 32x32 over tile 247, and the palette is bank 1, the ball's own. 6 frames
of 0x200, 4 tiles wide, no OAM packing. gBallShadowTileIndices and
ballShadowTimer in ruby_board_indicators.c carry the same wrong name.

The colours are what caught it. Bank 1 rendered the frames as pink sparkles and
expanding rings, which is wrong for anything called a shadow, so it looked like
another palette mistake. It was the label that was wrong: reading up to where
spriteGroup is assigned named the group outright, and the art is the sparkle that
plays when the ball upgrades. Fifth mislabelled symbol in this series, and the
first found by disbelieving a render rather than by resolving the slot.

Rebuilt sheet matches the ROM blob before and after recolouring, check passes,
make compare passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 09:48:36 -04:00
Cyphgirl 6d2cffda06 Extract the flipper frames from baserom
gFlipperTileGraphics is 6 angles of 0x200, copied into tile 0 for the left
flipper and tile 16 for the right. Each is a single 32x32 from
gBonusBoardLeft/RightFlipperSpriteSet in palette bank 0, so the sheet is 4 tiles
wide with no OAM packing and no shape.

These are the same two slots the shared bonus-board block fills at t0..31 on every
board's intro sheet, which is why bank 0 is already the answer ruby and kyogre
record for their own copies of the flipper.

Rebuilt sheet matches the ROM blob before and after recolouring, check passes,
make compare passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 09:45:00 -04:00