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>
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>
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>
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>
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>
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>
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>
gRubyFlashingDecorationTiles is not decorations. ruby_trigger_targets.c streams
it into tile 313 for SG_RUBY_CHIKORITA, and gRubyChikoritaSpriteSet is what draws
it: a 32x32 over a 32x16 in palette bank 3. That tiles into a clean 4x6 block
with nothing left over, so the whole sheet is one segment, 8 frames stacked.
The render is eight frames of a Chikorita, which settles it.
That is the third mislabelled symbol in this series, after the Kyogre whirlpool
that is a freeze trap and the Groudon background that is effect art. The pattern
is the same each time: the label describes where the art was thought to go, the
DmaCopy16 destination and the sprite set that reads that slot describe what it
actually is.
Rebuilt sheet matches the ROM blob before and after recolouring, the slot derives
bank 3 on full coverage with no override needed, check passes, make compare
passes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gRubyMakuhitaGfx is 10 frames of 0x300 streamed over tile 428 by ruby_ramp.c.
gRubyMakuhitaSpriteSet draws a frame as a 32x32 at the origin, an 8x32 beside it
and a 32x8 under it offset 8px right, which is a 5x5 block with the bottom-left
tile unused -- so it takes an oam-shape with one spacer rather than -mwidth.
Worth noting the shape is not guessable from round-tripping: a plain 4-wide
render of this sheet also comes back byte-exact and still looks like a Makuhita,
because the 8x32 column is narrow enough to pass at a glance. Only the sprite
set settles it. Ruby's intro sheet reaches the same art as two segments,
makuhita_top and makuhita_feet, which is not an option here -- the frames would
have to interleave.
Rebuilt sheet matches the ROM blob, objpalette derives bank 8 from the slot,
check passes, make compare passes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Removes 291 baserom incbins (223,976 bytes). Everything below was checked by
re-encoding the emitted data and comparing against the ROM bytes before the
source was touched, and the build matches at every step.
Sprite sets and tables in rom_2.s
- Convert 212 packed sprite sets to packed_sprite_oam. Note the "l" suffix in
packed_sprite_oaml means an 8-byte entry, not 6, so the entry size is checked
against each set's leading count rather than inferred from its size.
- Convert 79 named tables using their extern declarations to fix each shape,
including the structs defined in .c files rather than headers (KecleonMoveNode,
IntroAnimVelocity). Eight tables whose element count does not divide by the
declared row width are listed flat, with a comment, rather than forced into a
shape the data contradicts.
- gEReaderTextGlyphTable is 14 pages of 3x24 u16. Each entry packs a glyph offset
in bits 4-15 with an advance width in bits 0-3 that the draw code masks off:
i=2, apostrophe/comma/full stop/l=4, word-final n=5, everything else 6. The 42
lines of text are transcribed as comments; the glyph map and the transcription
were checked against each other over all 1008 entries.
- gUnknown_086BBC44 was two things: six sprite sets, then 680 bytes that nothing
in the ROM points at, holding stale pointers past the rom end and a second copy
of the POKEPINAGB signature. That part stays an incbin as gUnusedRomTail.
Large blobs in rom_1.s
- gUnknown_81A6BE4 is an 8x8 ASCII font, 0x20-0x5F in order, with a yen sign in
the backslash slot. The other 30,720 bytes are zero. Now gDebugAsciiFont.
- The idle board configs are attract-mode demos: 4800 ReplayInputFrame each
paired with one PinballGame snapshot. Extracted to data/idle_board. The labels
run 0, 2, 3, 1 in ROM order.
- Kyogre body, Rayquaza body variants, the travel painter mons, the hole
indicator and the Sapphire bumpers are extracted as tile sheets. Frame counts
come from the declared strides; palettes come from the OBJ palette sets, not
the board BG palette, whose banks are black or grey for these sprites. Where a
sprite's pieces tile into a rectangle the sheet is laid out with -oamshape so
the frames are readable; where they do not, or where the tiles are scattered
over several board positions, it is one frame per row and the comment says so.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Reverts the screen-based approach. Every BG sheet goes back to a plain
tile-grid PNG, which the existing %.4bpp: %.png rule builds, since
tilemap editing is covered by other tooling.
- Drop the 68 assembled screen and unmapped-strip PNGs, the 21 detilemap
rules, tools/scripts/detilemap.py and the VRAM layout notes.
- Revert Makefile: .SECONDARY goes back to its original unscoped form.
- Write each sheet out coloured rather than restoring the greyscale
originals. A 4bpp PNG carries one 16-colour palette, so each sheet uses
the bank most of its cells reference; multi-bank sheets are therefore
approximate in appearance. Pixel indices are unaffected, so all 25
sheets still round-trip byte-exactly.
- scene4plussleminun keeps its three-segment form: the sheet is 513 tiles
because of the align-1 padding tile and does not fit one grid.
Ruby and Sapphire keep their BG tiles and tilemaps as extracted files
rather than reverting to baserom incbins, so the 73,728 bytes those
removed stay removed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Extends the intro_sprite work to every other OBJ sheet whose palette is
recoverable: 136 more segment PNGs across the boards, the evolution pickups
and the Pokedex, all byte-for-byte identical through the build.
A second kind of sheet
- The intro_sprite sheets are loaded whole, so their segments start at OBJ
tile 0. Everything else is streamed frame by frame over a slot inside that
sheet while the board runs -- the entities, the shop sign, the banners. Those
start at the slot's tile instead, and since every frame is drawn through the
same OAM entry they all share one bank. SLOTS records where each lands, taken
from the destination of the DmaCopy16 that streams it.
- Segment ranges and the vote are unchanged otherwise, so a slot that coincides
with an intro_sprite segment lands on the palette already reviewed for it.
A slot that is only part of a sprite (the charge indicator streams four tiles
into the middle of an eight-tile one) falls back to the entry covering it.
Tile 704 and OBJ bank 14
- These are the overlay pair. Every mode that wants a banner streams its sheet
over one and its palette over the other, so the sprite set the vote finds
there says nothing about the art. Those sheets take the palette loaded beside
their own copy instead: gRubyPainterPalette and gSapphirePainterPalette for
the travel painters, gBonusStagePal_Lit for the ball save, gBonusClearTextPal_Lit
for the end of ball, gTravelPortraitPalette for the roulette fx.
- The evolution pickups work the same way one level down: gEvoItemPalettes runs
parallel to gEvoItemAppear_GfxList, so each icon sheet takes its own entry.
Nine of them share one appear-and-sparkle animation and colour it differently;
a PNG holds one palette, so a shared segment keeps the first sheet's.
Also
- Spheal and the Pokedex join BOARDS. The Pokedex sheet is also what the
e-reader screen puts in OBJ VRAM, so both sprite-set tables have to be
consulted to reach all of its segments.
- Sheets built by the plain %.4bpp: %.png rule have no config entry to record
the answer in; derive adds one carrying only the palette, which
generate_graphics_rules.sh ignores.
- Palette paths are written relative to the config that holds them, not to the
board -- graphics/stage/gfx.json holds a sapphire sheet.
Left greyscale: 37 PNGs. Five go to BG VRAM (the text and glyph sheets, the
high score watermark), where the bank lives in the tilemap entries the code
writes rather than in any OAM data, so they need a different derivation. The
rest are sheets with no incbin -- the light and arrow strips, several gunk_*
blobs -- whose place in VRAM is not established yet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The 203 segment PNGs behind the seven boards' intro_sprite sheets were
checked in as 4-bit greyscale: a 4bpp sheet carries no palette of its own,
so nothing in the tree recorded which of the 16 OBJ banks a sprite is drawn
through, and every sheet was an unreadable grey blob. All seven are now
indexed colour, byte-for-byte identical through the build.
The inversion
- gbagfx converts a palette-less PNG with invertColors = !image.hasPalette
(main.c:71), so a greyscale sheet stores 15 - index, and gaining a PLTE
turns that off. The recolour inverts on the way in; passing the samples
through unchanged would have quietly rewritten every tile.
Deriving the bank (tools/scripts/objpalette.py)
- data/rom_2.s spells out every OAM entry with its tileNum and paletteNum,
and the g<Board>BoardSpriteSets tables say which a board uses. Segments lie
end to end in tile order, so each owns a tile range and the entries landing
wholly inside it name its bank. An entry crossing a boundary is reading a
different sheet -- OBJ VRAM at 0x06010000 is rewritten constantly -- and is
dropped. Second pass over the g<Board>*OamData arrays for the boss sheets,
which the code indexes frame by frame instead of via a sprite set.
- Tile counts come from the built per-segment .4bpp: -oam and -oamshape
segments are not width*height/64, and PNG dimensions drift ruby by 13 tiles.
- Banks holding under four distinct colours cannot win the vote. Those are
flash states and banks a board leaves at zero, and would render solid.
- The result is recorded in each gfx config as "palette"/"palbank", so it is
reviewable and `objpalette.py check` can verify the PNGs against it.
Scratch regions
Eight tile ranges are streamed over at run time from a table of interchangeable
art, and coloured by a palette that arrives with the replacement tiles rather
than sitting in the board's own set. Which entry the sheet ships is recoverable
by searching the ROM for the segment's tiles -- exact for all but the Geodude
portrait, matched by likeness. Listed with their writers in VRAM_LAYOUT.md.
OBJ bank 11 on the main fields is never its resting ROM value either:
UpdateSpoinkAnimation rewrites it every frame from gFieldPaletteVariants,
three brightness sets crossed with which half of the board is on screen.
Ruby's palset_0 is 0x120 bytes, not the 0x200 the DMA copies, so its OBJ banks
9-15 come from the next label, gBonusStageObjPal. Sapphire leaves banks 12-15
at zero and loads them when the sprites that use them appear.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Removes 74 baserom incbins (104,512 bytes) and makes every background
tile sheet in the game readable and correctly coloured, byte-for-byte
identical to the ROM throughout.
Palettes
- Extract 69 standalone palettes to JASC .pal, built via the existing
%.gbapal: %.pal rule. gbagfx's gbapal->pal direction pads anything that
is not 16 or 256 colours up to 256 (gfx.c:822), so the JASC is written
directly from the ROM bytes and gbagfx only does pal->gbapal.
- Convert the 9 legacy raw-binary .pal files to JASC, so a single .pal
format exists. dusclops_anim held 496 colours, over the JASC limit, so
it becomes 31 per-frame files.
BG sheets (tools/scripts/detilemap.py)
- BG tile sheets are deduplicated, so the raw sheet is unreadable as an
image at any width. The checked-in source becomes the assembled screen
(8bpp, pixel = bank*16 + index, which keeps every per-cell palette bank
distinct) and detilemap folds the screens back through their tilemaps.
- Covers all 9 intro scenes and all 8 boards: 21 sheets.
- Ruby and Sapphire stream their board through a 22-slot scroll ring, so
a tilemap row R draws chunk R of a virtual bgtop+bgbottom strip rather
than indexing the sheet. --row-chunk handles that; the model is written
up in data/board_data/VRAM_LAYOUT.md.
- 8 sheets have non-blank tiles no tilemap reaches (BG0 tilemaps are built
at runtime); --extra carries them rather than silently zeroing.
Build
- .SECONDARY was unscoped, which marked $(OBJS) secondary too. Make does
not rebuild a missing secondary file when its dependant looks current,
so deleting an object and running `make compare` relinked a stale ELF
and printed OK. Now scoped to generated art and audio. .PRECIOUS with
patterns would be terser but defeats .DELETE_ON_ERROR, which would let
a half-written .4bpp produce a wrong ROM silently.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
57 pieces out of baserom.gba, in colour. ROM still matches
(make compare).
Three groups per board, one per coin value, each with lit variants of
three pieces. The two boards differ in table shape: ruby has four
variant rows with the destinations fifth, sapphire has three plus a
destination row and a row of spacers. Ruby repeats the first variant in
groups 0 and 2, so 57 distinct pieces cover the 72 slots.
Piece 2 of groups 0 and 1 is never copied on either board -- their
destination overlaps the next group's piece 0 -- so there is no DMA size
to take. Those 13 are extracted at their full declared span instead.
Everything else uses the size from DrawRubyCoinRewardMeter and
DrawSapphireCoinRewardMeter.
Palettes are bank 9 of gRubyBoardPalette and bank 11 of
gSapphireBoardPalette, both tilemap-attested. The two boards do not
match here: ruby's coin arrows are green with white numerals, sapphire's
are light blue with white numerals, which is what the field scans show.
Sapphire bank 0 is also blue and scores within 3 RGB units of bank 11
against the scan, but it is navy where the board art is clearly light
blue, so the render decided it rather than the distance.
Left alone: graphics/stage/ruby/ruby_coin_arrows.png, an earlier
extraction of the whole 0xC00 block as one 256x24 sheet, still
referenced by a commented-out incbin above the first symbol. It matches
baserom exactly but cannot be wired up without collapsing the 30
individual symbols, which is presumably why it was left commented. It is
now redundant and could be removed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
60 pieces out of baserom.gba, in colour. ROM still matches
(make compare).
Same shape as the evo arrows: three letter groups spelling GET, each
with a set of variants for the lit progression, each variant three
pieces going to three VRAM destinations one tilemap row apart. Group
sizes differ per piece (0x40 or 0x60) and were taken from the
DmaCopy16 calls in DrawRubyCatchArrowProgress and
DrawSapphireCatchArrowProgress. Groups 0 and 2 repeat their first
variant, so 60 distinct pieces cover the 72 table slots.
30 symbols span more ROM than is copied; the remainder is .space where
blank (22) and a baserom incbin otherwise (8).
Palettes are bank 8 of gRubyBoardPalette and bank 11 of
gSapphireBoardPalette. Both are referenced by their board tilemap at
these tiles and both render the arrows red-orange with a white letter,
matching the Ruby and Sapphire Field scans. Index layouts differ per
board again: ruby draws the body at index 5, sapphire at index 7.
Note these are the "Catch 'em Arrows" in the Bulbapedia legends; the
symbol and function names disagree with each other already
(gRubyGetArrowTilePtrs drawn by DrawRubyCatchArrowProgress) and were
left alone.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
78 arrow rows out of baserom.gba, in colour. ROM still matches
(make compare).
Each arrow is four rows that go to four separate VRAM destinations one
tilemap row apart, with an off and an on state (mart has four states:
mart off/on and evo off/on, since the ramp is shared). Row widths are
not uniform -- they run 2 to 5 tiles -- so the copied size per row was
taken from the DmaCopy16 calls in ruby_board_indicators.c and
sapphire_board_indicators.c rather than assumed from the symbol spans.
22 symbols span more ROM than the game copies. Only the copied part is
extracted; the remainder stays as a baserom incbin, or .space where it
is blank (6 of them).
gSapphireBumperArrow_082E0860 and _082E08E0 are skipped: they are
already .space, and both the table comment and the fact that
AnimateSapphireBumperArrowPalette only copies rows 1-3 confirm row 0 is
unused.
Palette is bank 11 of gRubyBoardPalette / gSapphireBoardPalette. That
bank is the only one on either board that is both yellow at the arrow
body index and actually referenced by the board tilemap at these tiles.
The two boards do not share index layouts -- ruby draws the body at
index 10 with outline 15, sapphire at index 4 with outline 11 -- so each
was decoded separately. Checked against the Ruby and Sapphire Field
scans on Bulbapedia, where all four arrow types on both boards are
yellow with a dark outline.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The previous commit coloured these from gRubyBoardPaletteSet0 /
gSapphireBoardPaletteSet0, which are not what the game loads. The BG
palette actually copied to BG_PLTT is gRubyBoardPalette /
gSapphireBoardPalette (all_board_setup.c:81 and :97); the PaletteSet
symbols are something else. Bank numbers read out of the board tilemaps
index the loaded palette, so they were being applied to the wrong data
and produced gold arrows.
Checked against the Ruby Field scan on Bulbapedia, where the arrows are
green with pale letters. gRubyBoardPalette bank 0 reproduces that: body
(98,189,115) against a mean of (146,180,130) sampled from the scan, and
letter (213,230,255). The previously committed colours were 121 away in
RGB and plainly gold.
The bank was in the tilemap all along. The arrow tiles appear at three
places in gRubyBoardBG0Tilemap and I read the wrong one; the instance at
y54 is bank 0. Sapphire's y54 instance is likewise bank 0, so both are
now bank 0 of their board palette.
Ruby is verified against the reference image. Sapphire is inferred from
the same tilemap instance that proved correct for ruby, and has not been
checked against a Sapphire Field render.
Graphics only; all 60 .4bpp rebuild byte-identically and make compare
still passes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Re-renders the 60 evo arrow tiles in colour instead of greyscale.
Graphics only, no ROM data change; every .4bpp rebuilds byte-identically
and make compare still passes.
Palettes were traced rather than guessed. gRubyEvoArrowTilePtrs and
gSapphireEvoArrowTilePtrs give destination addresses (0x0600D080 etc.),
and both boards put BG1/BG3 on BGCNT_CHARBASE(2), so the arrows occupy
tile indices (dest - 0x8000) / 32. Looking those indices up in the board
BG tilemaps gives the palette bank they are drawn with:
ruby gRubyBoardPaletteSet0 bank 1
sapphire gSapphireBoardPaletteSet0 bank 4
Two things made this less direct than it sounds. The arrows' lit state
is not a palette change: DrawRubyEvoArrowProgress selects one of four
tile variants per piece and DMAs it over the same VRAM, so the palette
is fixed and the tilemap reading is the authoritative one. And the ruby
block spans a palette boundary, so the tilemap alone offers two banks
for it; bank 2 renders as flat grey while bank 1 renders the same gold
E/V/O design that sapphire's tilemap-verified bank 4 produces, which is
what settles it.
Note the boards have three BG palette sets and every bank differs
between them, so these are the set 0 colours. For sapphire the arrow
is near-identical across all three sets, varying only in brightness.
ruby_evo_raw.png is left greyscale: it has no .4bpp and is not part of
the build.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Finds palettes still on baserom.gba whose symbol name pairs with an
already-extracted graphic (<base>_Gfx / <base>_Pal), extracts them, and
re-renders the matching PNGs in colour instead of greyscale. ROM still
matches (make compare).
gEReaderBackground_Pals 0x81D20 0x200
gMainBoardEvoBanner_Pal 0x5221AC 0x200
gMainCatchModeBanner_Pal 0x5267CC 0x200
gMainBoardJirachiBanner_Pal 0x5269CC 0x200
gMainBoardTravel_Pal 0x526BCC 0x200
gRubyChinchouCatchBurstBanner_Pal 0x51956C 0x20
gRubyLotadCatchBurstBanner_Pal 0x51958C 0x20
gSapphireShroomishCatchBurstBanner_Pal 0x5195AC 0x1C0
The name pairing alone would not say which bank of a 0x200 palette
belongs to the graphic, so that was checked rather than assumed: in
seven of the eight only bank 0 is non-blank and the rest is zero
padding, which makes the choice unambiguous. gEReaderBackground_Pals
has banks 0 and 1 populated and bank 0 is the one embedded.
The PNGs are re-rendered through gbagfx rather than by rewriting the
PNG header. gbagfx uses the colour type as the signal for whether to
invert pixel values (see the comment in convert_png.c), so flipping a
greyscale PNG to indexed in place silently changes every index and the
built .4bpp with it. Going through the tool keeps both directions
consistent; each file was checked to rebuild its .4bpp byte-identically
before this was committed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* dump u8 * pointers
* through 08137DA4
* checkpoint 08138014
* travel paint
* sapphire travel paint
* painter palette rename
* ruby evo arrows
* prenaming sapphire evo arrows
* sapphire evo arrows
* raw ruby coin arrow dump
* rename capture ball variants
* indicatorLight naming
* carve pointer array at 0x086AFCB0
* dump/carve gFieldBoardConfigs 0x086AFD70
* dumped gKecleonSpriteYSortData:: @ 0x086AEA70
* dump spheal flight path data
* merged the 2 SphealFrameset Arrays
* naming of spheal/sealeo frameset data
* dump gOptionsSpriteSets and potential data block after the Pokepinagb string
* add comment with original name of raw fu the 2 raw functions
* add comment with original name of the 2 raw functions
* folderized board lights
* split Ruby Light file, name ruby light unknowns
* Sapphire board lights
* class standardization: board collision data set
* board data folderization
* 4 banner graphics, unk naming
* added m4a_tables.c
* move comment point for m4a_tables
* agb_sram rodata
* incorporate remainder of m4a_tables file.
* Move AgbLibSramVersion into src/agb_sram.c
* Dump se fragment
* Don't hardcode gDeltaEncodingTable address
* Don't hardcode AgbMain in crt0.s
* Cleanup gAreaPortraitIndexes name
* More name cleanup
---------
Co-authored-by: Marcus Huderle <huderlem@gmail.com>
* Add tooling support for graphics with 2^n chunking
* update to OAM handling, from 2n sizing
* Update assembly to use the hex, rather than music name, for ease of uese in decompme/m2C
* additional tools/examples
* graphics build, not currently compare matching.
* remove sprites.png
* working conversion in make file!
* stage/main folder done
* stage/misc folder done
* stage/ruby complete
* stage/sapphire updated
* base for remaining kinda-graphics; file name casing
* more name casing
* extract catch sprites
* remove special 6x4 handling from oam slicer; switched hed the 2 images to using non-oam 2x2 chunks. (net same, but allows the 6x4 to process normally when things like the whalmer are found)
* Palette info for the catch sprites, thanks to cyphgirl
* obliterate the old hatch-sprite code
* refactor segments to not have the base file name dependancy
* catch mon 1-9, horizontal layout
* rename the f param in the json for graphics
* casing cleanup?
* .
* possible fix for the out of date segment piece
* Replace graphic_cnvt_attrs.txt strategy with individually-generated makefile rules
* Don't specify tileCount
---------
Co-authored-by: Marcus Huderle <huderlem@gmail.com>