Advertisement
luckytyphlosion

BN sprite archive format (just for readability)

Sep 5th, 2019 (edited)
501
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.95 KB | None | 0 0
  1. Taken from: https://forums.therockmanexezone.com/bn-sprite-archive-format-revised-t5403.html
  2.  
  3. All BN sprite archives look roughly like this:
  4. - Metadata header
  5. - Animation 0
  6. ----- Frame 0
  7. --------- Tileset
  8. --------- Palettes
  9. ------------- Palette 0
  10. ------------- ...
  11. ------------- Palette n (n<16)
  12. --------- Mini-animations
  13. ------------- Mini-animation 0
  14. ----------------- Mini-frame 0
  15. ----------------- ...
  16. ----------------- Mini-frame n (n<256)
  17. ------------- Mini-animation 1
  18. ------------- ...
  19. ------------- Mini-animation n (n<256)
  20. --------- Objects
  21. ------------- Object list 0
  22. ----------------- Object 0
  23. ----------------- ...
  24. ----------------- Object n (n<256)
  25. ------------- Object list 1
  26. ------------- ...
  27. ------------- Object list n (n<256)
  28. --------- Animation data
  29. ----- Frame 1
  30. ----- ...
  31. ----- Frame n (n<256)
  32. - Animation 1
  33. - ...
  34. - Animation n (n<256)
  35.  
  36. Furthermore, the binary file structure looks like this:
  37. - Metadata header
  38. - Animation pointers
  39. - Frame data
  40. - Tileset blocks
  41. - Palette blocks
  42. - Frame-specific blocks
  43. ----- Mini-animations
  44. ----- Object lists
  45.  
  46. Each sprite archive starts with a 4-byte metadata header. This block is not known to be used by any MMBN game and is skipped when loading animations.
  47.  
  48. Metadata header (4 bytes):
  49. +0x00: (byte) amount of tiles in the biggest tileset in the sprite archive
  50. +0x01: (byte) constant 0x00 ?
  51. +0x02: (byte) constant 0x01 ?
  52. +0x03: (byte) number of animations in the sprite archive
  53.  
  54. "Amount of tiles" basically equals ceil(size of bitmap data / 0x20).
  55.  
  56. ---
  57.  
  58. Directly after that is the animation pointer table. Each animation pointer is 32-bit, and all pointers are relative to the start of the table.
  59.  
  60. An animation consists of at least one frame. Each frame entry is 20 bytes long and has the structure below. All pointers are relative to the start of the animation pointer table.
  61.  
  62. Frame entry (20 bytes):
  63. +0x00: (int) pointer to tileset
  64. +0x04: (int) pointer to palettes
  65. +0x08: (int) pointer to mini-animations
  66. +0x0C: (int) pointer to object lists
  67. +0x10: (byte) delay
  68. +0x11: (byte) constant 0x00 ?
  69. +0x12: (byte) flags
  70. +0x13: (byte) constant 0x00 ?
  71.  
  72. Frame flags:
  73. 0x80: end animation
  74. 0x40: loop animation
  75.  
  76. The last frame in the animation must have bit 0x80 set in its flags; this marks the end of an animation. Additionally, if bit 0x40 is set in the flags of the last frame, the animation will restart from the first frame; otherwise it simply stays on the last frame. Note: if an animation loops, the last frame has flags 0x80 | 0x40 = 0xC0.
  77.  
  78. ---
  79.  
  80. Each tileset starts with its size, which is then followed by the raw 4bpp indexed bitmap data.
  81.  
  82. Tileset (4 + n bytes):
  83. +0x00: (int) size of bitmap data
  84. +0x04: (byte[n]) bitmap data (4bpp indexed)
  85.  
  86. The bitmap data can technically, but should not exceed 8160 bytes, as 255 is the maximum for the amount of tiles in the metadata block. Different frames can and often will share the same tileset block.
  87.  
  88. ---
  89.  
  90. A palette block starts with its size (always 0x20) and is followed by at least 1 and at most 16 palettes. Unfortunately there is no way to tell how many palettes there are. The best approach is probably to make a list of all pointers that exist in the sprite archive, and then loading palettes until the next pointer is reached. Each palette consists of 16 colors with RGB555 color depth.
  91.  
  92. Palettes (4 + n * 32 bytes):
  93. +0x00: (int) constant 0x20
  94. +0x04: (short[n][16]) palettes of 16 RGB555 colors
  95.  
  96. Similar to tilesets, palette blocks are usually shared by almost all frames in the archive, since each frame can only use one palette.
  97.  
  98. ---
  99.  
  100. The mini-animations are a bit special. Essentially, each frame of animation itself can be animated (yo dawg) by swapping out object lists. Each frame must have at least one mini-animation, which for the vast majority of sprites is just a static object list. Mini-animations are rarely used; in fact, only mugshots are known to make use of them. The default mini-animation is the first one.
  101.  
  102. A mini-animations data block begins with a pointer table of 32-bit pointers to mini-animations, relative to the start of the table. Each mini-animation consists of at least one mini-frame entry of 3 bytes.
  103.  
  104. Mini-frame entry (3 bytes):
  105. +0x00: (byte) index of object list to use
  106. +0x01: (byte) delay
  107. +0x02: (byte) flags
  108.  
  109. The flags work the same way as for full frame entries; 0x80 ends an animation, 0x40 loops it. Last mini-frame has value 0xC0 if it loops. Additionally, the last mini-frame is followed by three bytes 0xFF 0xFF 0xFF.
  110.  
  111. ---
  112.  
  113. The object lists work in conjunction with mini-animations. A mini-animation swaps out object lists in OAM memory to achieve motion. Every frame of animation must have at least one object list, which is usually used for the default (static) mini-animation.
  114.  
  115. Like the mini-animations, an object list block begins with a pointer table of 32-bit pointers to object lists, relative to the start of the table. Each object list consists of any number of object entries of 5 bytes. It can technically be empty, but this is not recommended.
  116.  
  117. Object entry (5 bytes):
  118. +0x00: (byte) starting tile number
  119. +0x01: (sbyte) X-coordinate of upper left corner
  120. +0x02: (sbyte) Y-coordinate of upper left corner
  121. +0x03: (byte) flags 1
  122. +0x04: (byte) flags 2
  123.  
  124. There are two packed bytes in an object entry that contain a number of values.
  125.  
  126. Flags 1:
  127. bits 0-1: object size
  128. bits 2-5: unused
  129. bit 6: horizontal-flip object
  130. bit 7: vertical-flip object
  131.  
  132. Flags 2:
  133. bits 0-1: object shape
  134. bits 2-3: unused
  135. bits 4-7: palette index
  136.  
  137. If the bits for horizontal-flip or vertical-flip are enabled, the object is shown horizontally and/or vertically flipped on the GBA screen.
  138.  
  139. Object shape and object size together determine the dimensions of the object. 8x8 tiles are loaded from left to right, from top to bottom, starting from the tile set as the starting tile in the object entry.
  140.  
  141. size 0, shape 0: 8x8
  142. size 0, shape 1: 16x8
  143. size 0, shape 2: 8x16
  144. size 1, shape 0: 16x16
  145. size 1, shape 1: 32x8
  146. size 1, shape 2: 8x32
  147. size 2, shape 0: 32x32
  148. size 2, shape 1: 32x16
  149. size 2, shape 2: 16x32
  150. size 3, shape 0: 64x64
  151. size 3, shape 1: 64x32
  152. size 3, shape 2: 32x64
  153.  
  154. A palette index refers to the palette block that this frame uses, not the palettes currently loaded in VRAM. All objects in an object list MUST use the same palette, and therefore the same goes for each frame of animation!
  155.  
  156. Each object entry is converted to a GBA OBJ sprite and copied to OAM memory. An object list is terminated by the five bytes 0xFF 0xFF 0xFF 0xFF 0xFF.
  157.  
  158. ---
  159.  
  160. Junk data may occur in a sprite archive. The data blocks for mini-animations and object lists are always padded to a multiple of 4. For all sprite archives in the official games, they are actually always padded to the next (!) multiple of 4 (even when it is not necessary to add padding), and the extra bytes are junk data seemingly taken from the rest of the file. The pattern to the junk data has not been uncovered, but since it goes unused completely it doesn't really matter.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement