Sprite set file: Difference between revisions
Appearance
No edit summary |
|||
| (One intermediate revision by the same user not shown) | |||
| Line 1: | Line 1: | ||
Sprite sets are stored in directory id_low = 0x5f29, id_high = 0xc8e5 in the [[master file table]]. Each sprite set contains multiple distinct sprites, and each sprite may be made of multiple [https://problemkaputt.de/gbatek-lcd-obj-overview.htm GBA OBJs]. | Sprite sets are stored in directory id_low = 0x5f29, id_high = 0xc8e5 in the [[master file table]]. Each sprite set contains multiple distinct sprites, and each sprite may be made of multiple [https://problemkaputt.de/gbatek-lcd-obj-overview.htm GBA OBJs]. Not ''all'' sprites are stored in these sprite sets (example: Boks, bats, etc. are stored elsewhere). | ||
= File format = | = File format = | ||
| Line 7: | Line 7: | ||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
struct spriteset_header { | struct spriteset_header { | ||
u16 | u16 palStart; // palette start index in the sprite palettes file | ||
u16 spriteCount; // number of sprites in this sprite set | u16 spriteCount; // number of sprites in this sprite set | ||
u16 unknown_0x04; | u16 unknown_0x04; | ||
| Line 36: | Line 36: | ||
struct spriteset_obj { | struct spriteset_obj { | ||
u8 flip; // bitmask; 4 = horizontal, 8 = vertical | u8 flip; // bitmask; 4 = horizontal, 8 = vertical. TODO: other bits? | ||
// 00=8x8, 01=16x8, 02=8x16 | // 00=8x8, 01=16x8, 02=8x16 | ||
| Line 48: | Line 48: | ||
// Bottom 12 bits: Start index for this OBJ in the raw tile data array | // Bottom 12 bits: Start index for this OBJ in the raw tile data array | ||
// Top 4 bits: Palette index | // Top 4 bits: Palette index, add to spriteset_header.palStart | ||
u16 tileAndPalette; | u16 tileAndPalette; | ||
}; | }; | ||
struct spriteset_tile { | struct spriteset_tile { | ||
u8[32] | u8 data[32]; // Raw GBA tile data (8x8 px, 4bpp) | ||
} | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
= Palettes = | |||
Each OBJ is linked to the palette it should use using the information in spriteset_obj.tileAndPalette and spriteset_header.palStart. However, the game engine can override this (used e.g. to animate menu cursors etc.). | |||
Each game's master file table contains a single file that defines ''all'' palettes for each spriteset_sprite. This file is stored in the MFT directory with id_low = 0x4679 and id_high = 0x9a65. This directory will only contain a single file with the ID 0xc5e9 in every game. | |||
The structure of this file is simple: A 4 byte header, containing the number of palettes in this file, followed by an array of that many palettes. Each palette is 0x20 bytes in size (16 entries per palette, 2 bytes per entry, see [https://problemkaputt.de/gbatek-lcd-color-palettes.htm GBATEK]). The game engine will automatically copy palettes from this file into palette RAM as neccessary. | |||
To get the palette index for a spriteset_obj, add <code>(spriteset_obj.tileAndPalette >> 12) + spriteset_header.palStart</code>. | |||
= Usage example = | = Usage example = | ||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
void load_sprite(spriteset_header* spriteset, int spriteId) | void load_sprite(spriteset_header* spriteset, void* spritePalettes, int spriteId) | ||
{ | { | ||
// spriteset should point to the start of a spriteset file | |||
// spritePalettes should point to the start of the sprite palettes file (there is only one per game) | |||
spriteset_sprite* sprites = (u8*)spriteset + spriteset->offsetToSprites; | spriteset_sprite* sprites = (u8*)spriteset + spriteset->offsetToSprites; | ||
spriteset_tile* tiles = (u8*)spriteset + spriteset->offsetToTiles; | spriteset_tile* tiles = (u8*)spriteset + spriteset->offsetToTiles; | ||
spriteset_sprite* sprite = &sprites[spriteId]; | spriteset_sprite* sprite = &sprites[spriteId]; | ||
// do something with sprite | // do something with sprite | ||
spriteset_obj* objs = (u8*)spriteset + spriteset->offsetToOBJs + sprite->objOffset; | |||
for (int objIndex=0; objIndex < sprite->objCount; objIndex++) { | for (int objIndex=0; objIndex < sprite->objCount; objIndex++) { | ||
spriteset_obj* obj = objs | spriteset_obj* obj = &objs[objIndex]; | ||
// do something with obj | // do something with obj | ||
int | int firstTileIndex = obj->tileAndPalette & 0xfff; | ||
spriteset_tile* firstTile = &tiles[ | spriteset_tile* firstTile = &tiles[firstTileIndex]; | ||
// do something with the tiles | |||
// number of tiles is implied by sprite->shape | // number of tiles is implied by sprite->shape | ||
// | // for OBJs with a height of more than 1 tile, successive rows of tiles are stored 16 tiles apart. | ||
// example: assuming startTileIndex = 4 and shape = 8x16: tile indices are 4 and 20. | |||
// color lookup example: | |||
int pixelColor = firstTile->data[0] & 0xf; // extract color of 1st pixel in the tile | |||
int paletteIndex = spriteset->palStart + (obj->tileAndPalette >> 12); | |||
// First 4 bytes are an ignoreable header, and each palette is 0x20 bytes in size (16 colors * 2 bytes per color) | |||
u16* palettePtr = (u8*)spritePalettes + 4 + 0x20*paletteIndex; | |||
u16 paletteEntry = palettePtr[pixelColor]; | |||
} | } | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
= Sprite set list = | |||
== Boktai 1 == | |||
{| class="wikitable exportable" | |||
! File ID || Description | |||
|- | |||
| 1bc7 || Flamethrowers | |||
|- | |||
| 2117 || Muspell | |||
|- | |||
| 2137 || Carmilla | |||
|- | |||
| 31ce || Hel 2 | |||
|- | |||
| 41a8 || Multiplayer menus | |||
|- | |||
| 4e23 || Garmr | |||
|- | |||
| 575d || Count (with coat) | |||
|- | |||
| 576d || Count (without coat) | |||
|- | |||
| 66a8 || Solar sensor help screens | |||
|- | |||
| 746a || Armors (shield only) | |||
|- | |||
| 766a || Armors (sword and shield) | |||
|- | |||
| 769a || Armors (hammer and shield) | |||
|- | |||
| 786a || Armors (sword only) | |||
|- | |||
| 789a || Armors (hammer only) | |||
|- | |||
| 7a6a || Armors (no weapon) | |||
|- | |||
| 8ab4 || Select menu – items & weapon | |||
|- | |||
| a1f7 || Solar tree | |||
|- | |||
| a3ae || Splash screens, settings, new game, etc. | |||
|- | |||
| a493 || Bank/Loans | |||
|- | |||
| a6aa || Select menu – map | |||
|- | |||
| a9c5 || Markers (Immortal, Undead, Arrows, Trap) & Yes/No | |||
|- | |||
| aac7 || Main menu | |||
|- | |||
| b11e || Hel 1 | |||
|- | |||
| e894 || Gun parts 1 | |||
|- | |||
| edbe || Unknown – maybe link battle? | |||
|- | |||
| fa48 || Gun parts 2 (Dark gun, star lens, astro/infinite battery) | |||
|- | |||
| ff88 || Dungeon titles (shown when entering a dungeon) | |||
|} | |||
== Boktai 2 == | |||
{| class="wikitable exportable" | |||
! File ID || Description | |||
|- | |||
| 0c23 || Big ray of sun (end of Jormy?) | |||
|- | |||
| 0f54 || Main menu | |||
|- | |||
| 1774 || Big picture of Django with the Sol de Vice | |||
|- | |||
| 18c2 || Multiplayer (contains unused JOYSPOT image) | |||
|- | |||
| 1b12 || Solar sensor help screens | |||
|- | |||
| 1bc7 || Flamethrowers | |||
|- | |||
| 24a0 || “boktai2” and Dream Avenue xF screens | |||
|- | |||
| 3f12 || World map screen | |||
|- | |||
| 5d04 || Inventory icons (and MegaMan and ShadeMan icons) | |||
|- | |||
| 5d36 || ShadeMan | |||
|- | |||
| 6893 || Bank/Loans (contains unused JP art) | |||
|- | |||
| 7ee2 || Splash screens and region select | |||
|- | |||
| 82f1 || Markers (Undead, Immortal, Trap, arrows), mission completed/failed, purification completed | |||
|- | |||
| 9524 || Jormy | |||
|- | |||
| 9abf || Library | |||
|- | |||
| ae52 || Skeletons and Liches | |||
|- | |||
| af82 || MegaMan | |||
|- | |||
| b991 || Candle on a box (where is this used?) | |||
|- | |||
| c153 || Mall (e.g. solar forging, shops, …) | |||
|- | |||
| cef0 || Bank/Loans (and “Restart”?) | |||
|- | |||
| d27a || Dialog box portraits | |||
|- | |||
| d3ca || Duneyrr | |||
|- | |||
| d3da || Ringo/Dainn | |||
|- | |||
| d3ea || Cheyenne | |||
|- | |||
| d3fa || Durathror | |||
|- | |||
| d40a || Dvalinn | |||
|- | |||
| de23 || Django/Sabata | |||
|- | |||
| dfce || Smith and Marcello | |||
|- | |||
| dfde || Lita | |||
|- | |||
| dfee || Zazie | |||
|- | |||
| dffe || Violet and her doll | |||
|- | |||
| e00e || Nero | |||
|- | |||
| e01e || Kid | |||
|- | |||
| e02e || Librarian | |||
|- | |||
| e03e || ??? and the coffin seller | |||
|- | |||
| e04e || Clocktower guy and old guy | |||
|- | |||
| e2de || Carmilla | |||
|- | |||
| e349 || Dainn | |||
|- | |||
| ef43 || In-game menu | |||
|- | |||
| f099 || Chandelier | |||
|} | |||
== Boktai 3 == | |||
{| class="wikitable exportable" | |||
! File ID || Description | |||
|- | |||
| 0658 || MegaMan | |||
|- | |||
| 1289 || Multiplayer | |||
|- | |||
| 158a || Ringo/Dainn | |||
|- | |||
| 1778 || Cheyenne | |||
|- | |||
| 1bc7 || Flamethrowers | |||
|- | |||
| 2bec || Gun parts | |||
|- | |||
| 32ba || Bank/Loans | |||
|- | |||
| 35e3 || Trinity | |||
|- | |||
| 3d99 || Bike | |||
|- | |||
| 3db6 || Critter that steals your solar nut in the tutorial | |||
|- | |||
| 530d || Select menu, San Miguel, maybe unused stuff? | |||
|- | |||
| 546b || Cannons | |||
|- | |||
| 5d04 || Inventory icons (and Count/MegaMan/Django icons) | |||
|- | |||
| 731d || Main menu | |||
|- | |||
| 7516 || Chair | |||
|- | |||
| 761e || Armors | |||
|- | |||
| 7c8b || Multiplayer (wireless) | |||
|- | |||
| 82f1 || Markers (Undead, Immortal, Trap, arrows), mission completed/failed, purification completed | |||
|- | |||
| 999b || Torch | |||
|- | |||
| a2db || World map | |||
|- | |||
| ae52 || Skeletons | |||
|- | |||
| af82 || MegaMan | |||
|- | |||
| b3de || Vanargand | |||
|- | |||
| b991 || Candle on a box (where is this used?) | |||
|- | |||
| de23 || Django/Sabata | |||
|- | |||
| df11 || Solar sensor help screens | |||
|- | |||
| dfce || Smith/Marcello | |||
|- | |||
| dfde || Lita | |||
|- | |||
| dfee || Zazie | |||
|- | |||
| dffe || Violet and her doll | |||
|- | |||
| e00e || Nero | |||
|- | |||
| e01e || Kid | |||
|- | |||
| e02e || Librarian | |||
|- | |||
| e03e || ??? and the bike shop guy | |||
|- | |||
| e04e || Clocktower guy and old guy | |||
|- | |||
| e2ab || Splash screens and region select | |||
|- | |||
| e2de || Carmilla | |||
|- | |||
| e2ee || Townspeople | |||
|- | |||
| e2fe || Gari | |||
|- | |||
| e349 || Dainn | |||
|- | |||
| e89f || Dungeon titles (shown when entering a dungeon) | |||
|- | |||
| f099 || Chandelier | |||
|- | |||
| f761 || Count | |||
|- | |||
| f771 || Bird and lots of “No”? | |||
|- | |||
| f7d2 || Trance | |||
|- | |||
| fb81 || Ratatosk | |||
|} | |||
[[Category:Documentation]] [[Category:File formats]] | [[Category:Documentation]] [[Category:File formats]] | ||
[[Category:Boktai 1]] [[Category:Boktai 2]] [[Category:Boktai 3]] | [[Category:Boktai 1]] [[Category:Boktai 2]] [[Category:Boktai 3]] | ||