mirror of
https://github.com/pret/pokepinballrs.git
synced 2026-09-28 13:49:48 -04:00
37f87ccee2
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>