Blaster Master/Data Structures

From Data Crystal
< Blaster Master
Revision as of 01:27, 28 March 2013 by Snarfblam (talk | contribs) (removing category)
Jump to navigation Jump to search

Each level and each ROM bank containing level data has a simple and consistent data format. Knowing only the number of levels in a ROM bank, it is possible to identify the location and type of all data within a bank by following the pointers.

This document is a formal definition of the ROM's data formats with the intent of documenting the data structure unambiguously, if not a bit difficult to understand.

Simple Data Formats

  • Pointer: A two byte pointer that always references data in the same bank. Level data is always paged in at 0x8000, so the pointer value will always be between 0x8000 and 0xBFFF. Pointers are little endian (0xABCD would be stored in the ROM as CD AB). To convert pointer addresses to ROM offsets, simply subtract 0x8000 and add the base offset of the ROM bank.
  • Palette: Each level uses the same sprite palettes. Each level has it's own background palette. Each level palette is 16 bytes, four palettes of four colors each. The "background color" for each four-color palette is disregarded and will always be black.


Bank Format

Each bank begins with a couple of pointers for each of the levels stored in that bank. Each level's data follows.


Bank Layout

Level Data Pointers[*]    Level Pointers
Level Data[*]             Level Data

[*] Indicates a variable number of instances of said data type. Each Bank begins with a number of Level Data Pointers. The Level Data Pointers data structure is four bytes, composed of two pointers, as defined below. The Level Data Pointers are followed by Level Data for each level.

Level Data is not a rigid data structure, but rather a number of data structures referenced by a set of pointers. See below.

Level Data Pointers

Pointer     Level Map Data
Pointer     Level Scroll Data

Level Map Data points to the Level Map Pointers for a given level. Level Scroll Data points to the level's scroll map.


Level Data

Each level is stored in a single contiguous area of ROM memory, though the format does not strictly require this. In a hack different types of data for each level could be placed arbitrarily (within a single bank) as long as the pointers correctly identify the location of the data.

Each level starts with a number of pointers to each type of data for a level's map. This table of pointers is identified at the beginning of a bank via Level Map Data, as defined in the Bank Format section.

Level Map Data

Pointer     Bg Palette
Pointer     Combo Attribute Table
Pointer     Combo Definiton Table
Pointer     Structure Definition Table
Pointer     Block Definition Table
Pointer     Map Data

The level map is constructed from a series of successive building blocks. Combos are 16 pixels wide and tall and are constructed from four patterns. Structures are 32 pixels wide and tall, constructed from four combos. Blocks are 64 pixels wide and tall, constructed from four structures. That is to say that blocks are made up of structures, which are, in turn, made up of combos, which are made up of patterns. The level map is composed of blocks.

The terms block, structure, and combo are somewhat arbitrary and chosen because they are commonly used for similar data structures in ROM documentation. Blocks, structures, and combos may also be referred to as blocks, sub-blocks, and ultra-sub-blocks (or blocks, SB, and USB) in other documentation.

Combo Definition

The combo definition table is a list of Combo Definitions, the number of which varies between levels. The number of Combo Definitions present for a given level can be calculated by subtracting the Combo Definition Table pointer from the Structure Definition Table pointer and dividing the result by four (this is based on the assumption that the Structure Definition Table immediately follows the Combo Definition Table, as in the original unaltered ROM).

Each combo is composed of four patterns, specified by the Combo Definition.

Byte    Top Left Pattern Index
Byte    Top Right Pattern Index
Byte    Bottom Left Pattern Index
Byte    Bottom Right Pattern Index

Combo Attributes

Each combo definition is complemented by combo attribute data. Combo attribute data is stored separately form the Combo Definition Table in a Combo Attribute Table. Combo attribute data is one byte per combo, where the bits have the following meaning (least significant bit first).

Bit 0-1   Palette Used (from 0 to 3).
Bit 2     Used in conjunction with bit 3. Indicates a door is an entrance to an overhead area.
Bit 3     Door (to another level or to/from overhead section).
Bit 4     Damage, used for lava, spikes, etc.
Bit 5     Ladder. Combine with Bit 7 to indicate the top of a ladder or bit 6 to indicate ladder is under water.
Bit 6     Water.
Bit 7     Solid.

Breakable combos are created by specifying both bits 7 and 6 (solid and water). The doorways that connect two scrolling regions are specified with both bits 7 and 8 (solid and door). These physics are for the tank levels. The meanings of physics bits are different in overhead levels.

Structure Definition

A structure is a composite of four combos. The structures are defined in a manner similar to a combo. A structure does not define any physics or other attributes of its own. Instead, simply it inherits the characteristics of its combos.

The number of Structure Definitions present for a given level can be calculated by subtracting the Structure Definition Table pointer from the Block Definition Table pointer and dividing the result by four (this is based on the assumption that the Block Definition Table immediately follows the Structure Definition Table, as in the original unaltered ROM).

Byte    Top Left Combo Index
Byte    Top Right Combo Index
Byte    Bottom Left Combo Index
Byte    Bottom Right Combo Index

Block Definition

A block is a composite of four structures. The blocks are also are defined in a manner similar to a combo. Like a structure, the characteristics of a block are simply those inherited from it's constituents.

The number of Block Definitions present for a given level can be calculated by subtracting the Block Definition Table pointer from the Level Map pointer and dividing the result by four (this is based on the assumption that the Level Map immediately follows the Block Definition Table, as in the original unaltered ROM).

Byte    Top Left Structure Index
Byte    Top Right Structure Index
Byte    Bottom Left Structure Index
Byte    Bottom Right Structure Index

Map Data

The level map is constructed from blocks. The map is defined as a grid of blocks 32 wide and tall.

Byte[0x20, 0x20]    Block Indecies

The data pertaining to scrolling is defined elsewhere. The map wraps around seamlessly during game-play.

Level Scroll Data

Level scroll data works by defining borders where the game will stop scrolling, creating rectangular scrolling regions. For the purposes of scrolling, the map is divided into a grid with "screen sized" (256x256 pixel) cells. Each grid cell can have a scroll boundary on any side (top, bottom, left, or right).

The player can travel from one scrolling region to another via a connecting doorway. Non-rectangular scrolling regions, unless very carefully constructed, will result in graphical glitches. Allowing a player to freely move through a scroll boundary without the use of a connecting doorway will also cause graphical glitches.

 Bit[8, 8]    Vertical scroll flags
 Bit[8, 8]    Horizontal scroll flags

The scroll map is 16 bytes. Scroll data is a bi-planar array of bits. Each byte specifies scroll data for one row of screens, most significant byte first (left-to-right on the map corresponds to high-to-low bits).

The first eight bytes specify 64 vertical scrolling flags, one for each cell of the hypothetical scrolling grid, and the second eight bytes specify horizontal scrolling flags. A scroll border is indicated by a set bit, which indicates scrolling would stop at the top or left of the screen the data corresponds to. For example, if bit 6 of the tenth byte is set, then the player can't scroll between the first and second screens in the second row of the map. In other words, this would indicate there is a scroll boundary on the left edge of map cell (1, 1).

Scroll Grid Offset

The level scrolling grid is offset by 32 pixels to the right and 32 pixels down from the top-left corner of the map. This means that the scroll boundaries all fall in the center of a block. Each block on the edge of a screen in the scrolling grid is shared with an adjacent screen.