In order to craft custom python scripts to copy sprites between roms, I need to know exactly where the sprite tiles’ data starts and stops. That’s the only point of these notes. 😹 Expect the scripts to appear here once they’re complete and tested!
All these measurements are from a rom without a header— those 200 leading bytes screw up so many efforts in this hobby, it’s best to avoid them at all times (imho).
48 tiles per sprite ➡️ | sprites start | 16 colors in palette | palette start (32 bytes) |
---|---|---|---|
Decil | $0D0000 |
ends on $0D07E0 | 80 01 00 00 FF 7F 3F 2A F9 01 8C 6D 4A 55 1F 00 BD 03 52 7E 7F 03 BC 02 B5 01 15 00 08 45 84 34 | $0E7D00 | | Kain | $0D0800 | 80 01 00 00 FF 7F 7F 36 D6 11 00 52 C0 6A 19 00 0F 00 88 7F 19 7E 70 6D BC 02 80 41 7F 03 C0 28 | $0E7D20 | | Kydia | $0D1000 | 80 01 00 00 FF 7F BF 32 18 2A 00 7C 4A 2F DF 6C C0 01 F6 67 FF 47 3F 03 B5 01 15 44 00 7E 43 1E | $0E7D40 | | Tellah | $0D1800 | 80 01 00 00 FF 7F FF 3A 39 22 1B 44 10 7E 5F 7D 00 7F F7 7E 7F 03 08 6D BC 02 B5 01 11 5C 0B 44 | $0E7D60 | | Edward | $0D2000 | 80 01 00 00 FF 7F BF 3A F9 21 C0 02 7F 03 1F 00 00 7E FF 3F E0 03 69 00 BC 02 B5 01 ED 00 19 00 | $0E7D80 | | Rosa | $0D2800 | 80 01 00 00 FF 7F BF 32 F7 21 04 12 6F 0D 3E 35 00 54 BA 24 77 2E 3B 03 34 56 CF 3E EF 3C F3 1D | $0E7DA0 | | Yang | $0D3000 | 80 01 00 00 FF 7F FF 25 77 01 BC 02 15 00 1F 00 0F 00 FF 13 D6 5A 7F 03 9F 01 8C 7D AD 35 00 5C | $0E7DC0 | | Palom | $0D3800 | 80 01 00 00 FF 7F 1F 2E 7A 1D 60 03 EF 00 1D 00 00 6C FF 3F 7F 03 BC 02 5F 01 F7 01 73 01 E0 01 | $0E7DE0 | | Porom | $0D4000 | 80 01 00 00 FF 7F 7F 3A D9 25 19 00 EE 00 DF 00 00 7D FF 03 E0 03 3F 03 79 02 B5 01 31 01 C0 02 | $0E7E00 | | Pecil | $0D4800 | 80 01 00 00 FF 7F 3F 32 7A 1D F7 3E 52 7E 1F 21 A0 02 7F 03 17 00 FF 4F 18 7F 6B 1D 00 74 8C 65 | $0E7E20 | | Cid | $0D5000 | 80 01 00 00 FF 7F 3D 02 77 01 00 5D 55 00 1D 01 10 7E 7F 03 BC 02 B7 01 33 01 AF 00 00 7E 00 40 | $0E7E40 | | Rydia | $0D5800 | 80 01 00 00 FF 7F BF 32 18 2A 20 02 29 27 DF 6C 00 7C 63 0E EF 3F FF 03 79 02 19 54 BF 7E A0 01 | $0E7E60 | | Edge | $0D6000 | 80 01 00 00 FF 7F 79 36 B5 1D 00 5D 8C 31 1F 00 08 21 7F 03 F5 01 94 7E B5 56 CE 5D 4A 7D 6F 01 | $0E7E80 | | FuSoYa | $0D6800 | 80 01 00 00 FF 7F FF 36 39 1E 0F 6D 8E 7E 1F 50 E0 02 D5 7D 86 5D 33 7B 0A 6E FB 7F 49 54 03 3C | $0E7EA0 | | Golbez | $0D7600 | 80 01 00 00 FF 7F 60 03 3F 2A F9 01 1B 00 15 00 7F 03 BC 02 B5 01 40 7F 40 7E 80 6D 00 5D 00 38 | $0E7EC0 |
Golbez only has 27 tiles— the other characters have 48 (4 rows of 16 tiles).
Yet in FF4 Ultima, Golbez has his own set of 48 tiles stored at $1D0000
Connections to draw from these data:
Each battle sprites has 48 tiles. Each tile is encoded in only 32 bytes (!) which is the exact same amount of data used to encode a 16-color palette. So the 16 colors seen in the Golbez palette above are sufficient memory space to encode one of those tiles…
Here is the first tile in Kain’s battle sprites. I’m only 1 year into this romhacking hobby and I’m really amazed that 1 tile of 16-color sprite graphics can get stored with only 32 bytes— it seems extremely efficient, however the SNES does it… Eventually I’ll totally grok it, but for now this is pretty mystifying.
I also may have measured this wrong. 😹
Decil | $0D8000 |
---|---|
Kain | $0D8300 |
Kydia | $0D8600 |
Tellah | $0D8900 |
Edward | $0D8C00 |
Rosa | $0D8F00 |
Yang | $0D9200 |
Palom | $0D9500 |
Porom | $0D9800 |
Pecil | $0D9B00 |
Cid | $0D9E00 |
Rydia | $0DA100 |
Edge | $0DA400 |
FuSoYa | $0DA700 |
Golbez | ??? |
They are 8 colors, so exactly 16 bytes per palette. The first color is the transparency, the second is the black outline color: they are both $00 00.
00 00 00 00 5D 22 96 01 7F 01 4C 7E 74 7F 8C 69
00 00 00 00 9F 2A 96 01 7F 01 F2 13 CC 71 C8 02
00 00 00 00 BF 2A 1A 02 98 51 F2 44 FF 73 BA 34
00 00 00 00 1F 3F 5B 26 BD 10 8F 6D 7B 33 94 12
Only these first four palettes are used by the player characters; more exist below these four.
Decil, Kain, Yang, Cid, Edge, FuSoYa = palette 00
Kydia, Palom, Porom, Rydia = palette 01
Tellah, Edward, Rosa = palette 02