The current URL is datacrystal.tcrf.net.
Donkey Kong Land/Notes
The following article is a Notes Page for Donkey Kong Land.
Maps
All three Donkey Kong Land games use the same LZ derivative to compress their maps. The main differences with the next two games are that the map's width and height are stored before the compressed data starts and any tiles that contain sprites are initialized to the 8-bit value 0x80. Additionally, the uncompressed map data is stored at a different location in RAM.
In DKL, the uncompressed map data starts at 0xCC00 in RAM.
Map IDs
Valid map IDs range from 0x00-49.
0x00: Freezing Fun 0x01: Jungle Jaunt 0x02: Congo Carnage 0x03: Tricky Temple 0x04: Reef Rampage 0x05: Riggin' Rumble 0x06: Nautilus Chase 0x07: Snake Charmer's Challenge 0x08: Swirlwind Storm 0x09: Simian Swing 0x0A: Rope Ravine 0x0B: Deck Trek 0x0C: Button Barrel Blast bonus #2 0x0D: Tyre Trail 0x0E: File select menu 0x0F: Kong Krazy 0x10: Kremlantis 0x11: Balloon Barrage (mislabeled "Construction Site Fight" in the manual) 0x12: Pot Hole Panic 0x13: Mountain Mayhem 0x14: Skyscraper Caper 0x15: Construction Site Fight (mislabeled "Balloon Barrage" in the manual) 0x16: Track Attack 0x17: Sky High Caper 0x18: Arctic Barrel Arsenal 0x19: Fast Barrel Blast 0x1A: Collapsing Clouds 0x1B: Oil Drum Slum 0x1C: Landslide Leap 0x1D: Chomp's Coliseum 0x1E: Button Barrel Blast 0x1F: Spiky Tyre Trail 0x20: Mad Mole Holes 0x21: Freezing Fun bonus 0x22: Fast Barrel Blast bonus #2 0x23: Deck Trek bonus #2 0x24: Riggin' Rumble bonus #2 0x25: Tyre Trail bonus #2 0x26: Simian Swing bonus #1 0x27: Tyre Trail bonus #3 0x28: Jungle Jaunt bonus #1 0x29: Congo Carnage bonus #1 0x2A: Mountain Mayhem bonus #1 0x2B: Wild Sting Fling 0x2C: Tricky Temple bonus #1 0x2D: Swirlwind Storm bonus #1 0x2E: Arctic Barrel Arsenal bonus #2 0x2F: Deck Trek bonus #1 0x30: Balloon Barrage bonus #2 0x31: Snake Charmer's Challenge bonus #1 0x32: Balloon Barrage bonus #1 0x33: Jungle Jaunt bonus #2 0x34: Rope Ravine bonus #2 0x35: Oil Drum Slum bonus #1 0x36: Sky High Caper bonus #1 0x37: Seabed Showdown 0x38: Kong Token bonuses (shared by multiple levels): * Simian Swing bonus #2 * Rope Ravine bonus #1 * Tyre Trail bonus #1 * Congo Carnage bonus #2 * Arctic Barrel Arsenal bonus #1 * Spiky Tyre Trail bonus #2 * Collapsing Clouds bonus #2 * Fast Barrel Blast bonus #1 0x39: K. Rool's Kingdom 0x3A: Pot Hole Panic bonus #1 0x3B: Track Attack bonus #2 0x3C: Landslide Leap bonus #2 0x3D: Riggin' Rumble bonus #1 0x3E: Construction Site Fight bonus #2 0x3F: Spiky Tyre Trail bonus #1 0x40: Track Attack bonus #1 0x41: Pot Hole Panic bonus #2 0x42: Kong Krazy bonus 0x43: Skyscraper Caper bonus 0x44: Mountain Mayhem bonus #2 0x45: Construction Site Fight bonus #1 0x46: Collapsing Clouds bonus #1 0x47: Oil Drum Slum bonus #2 0x48: Button Barrel Blast bonus #1 0x49: Landslide Leap bonus #1
Map Data
0x3247A: A list of MapInfo structures— one for each map. It's indexed using a map ID.
0x32886: A list of 16-bit map initialization function pointers to the same bank. A function pointed to by this list gets called when a map gets loaded. It's indexed using a map ID.
0x31EB2: A list of 8-bit map theme IDs— one for each map. It's indexed using a map ID.
- A map's theme determines various map properties, including which tile animations are played on it.
Map Metatiles
0x34001: A list of 24-bit pointers (bank last) to metatile maps that are compressed using an LZ derivative. It's indexed using a map ID. If the address part of a pointer in this list is 0, then that map has no metatile map.
- The height of each metatile map is not explicitly stated but one can reasonably guess it by comparing the size of the uncompressed data with the metatile map's width. Also keep in mind that some maps have a metatile map whose last row of metatiles is incomplete.
0x31DD4: A list of the 8-bit widths, in metatiles, of each map's metatile map. It's indexed using a map ID.
0x31D8A: A list of 8-bit values that, for each map, determine both the MSB of a pointer to its MetatileIndexTable and which ROM bank it is in. It's indexed using a map ID.
- Bits 0-5: Bits 0-5 of the MSB of a pointer to the MetatileIndexTable*
- Bit 6: Determines which ROM bank contains the MetatileIndexTable
- Possible values:
- 0: The MetatileIndexTable is in ROM bank 1
- 1: The MetatileIndexTable is in ROM bank 7
- Possible values:
- Bit 7: Bit 7 of the MSB of a pointer to the MetatileIndexTable*
- * Bit 6 of the MSB of the pointer to the MetatileIndexTable is always 1.
0x31EFC: A list of 8-bit values that, for each map, determine the LSB of a pointer to its MetatileIndexTable. It's indexed using a map ID.
See also: Metatiles
Map Layouts
0x32196: A list of 16-bit pointers to Layout structures— one for each map. It's indexed using a map ID.
0x32024: A list of 8-bit ROM bank indices where Layout structures may be found— one for each map. It's indexed using a map ID.
The type of Layout used by a map is determined by its MapInfo structure.
See also: Layouts
Map Bananas
0x3291A: A list of 16-bit pointers to BananaLayout structures in ROM bank 4— one for each map. A pointer to 0 indicates that no BananaLayout has been assigned to that map.
Map 0x39 is set to never load banana layout data, presumably so that the RAM used by the banana system can be used for other purposes.
See also: Bananas
Map Start Points
0x3250E: A list of 16-bit x coordinates for the player character's start point— one for each map. It's indexed using a map ID.
0x325A2: A list of 16-bit y coordinates for the player character's start point— one for each map. It's indexed using a map ID.
0x31F46: A list of 8-bit character state IDs for the player character to start with— one for each map. It's indexed using a map ID.
The direction that the player character starts with is determined by the map's MapInfo structure.
Map Audio
0x31FDA: A list of 8-bit music track IDs that determine which music track to play on each map. It's indexed using a map ID.
Map Data Sets
Usually, when a map gets loaded, these data sets get loaded in the following order:
See also: Data Sets
Map Hidden Ropes
The following maps contain hidden ropes: 0x01, 0x05, 0x09, 0x0D, 0x0F, 0x13, 0x19, and 0x1C.
0x31E1E: A list of 8-bit metatile IDs that represent the metatile ID used by closed rope holes. It's indexed using a map ID.
- Metatiles with this ID will reveal a hidden rope when stomped on. Maps without rope holes use a metatile ID that does not appear on the map.
0x31E68: A list of 8-bit Metatiles IDs that represent the metatile ID used by opened rope holes. It's indexed using a map ID.
- When a rope hole gets opened, its metatile gets replaced by one from this list.
0x32636: A list of 16-bit function pointers to ROM bank 2. It's indexed using a map ID.
- When a hidden rope gets revealed, a function from this list gets called. The function being called can be used to determine which hidden rope is assigned to each map.
- Function pointers present in this list and their meanings:
See also: Hidden Ropes
Map Hidden Caves
The following maps contain hidden caves: 0x01, 0x02, and 0x1F.
These MapPatchHotspotSets are used to reveal hidden caves:
- 0xDA7F: MapPatchHotspotSet for map 0x01
- 0xDAAE: MapPatchHotspotSet for map 0x02
- 0xDAEB: MapPatchHotspotSet for map 0x1F
See also: Hidden Caves
MapInfo Structure
- 0x00:
- 0x01:
- Bits 0-1: ?
- Bit 2: Whether the map is a bonus map.
- Bit 3: The direction that the player character starts with.
- Bits 4-5: ?
- Bit 6:
- Determines which base address to use for non-player metasprite tile pattern pointers (see MetaspriteInfo).
- Possible values:
- 0: base = 0x4000
- 1: base = 0xC000
- A base of 0xC000 appears only on boss maps because boss graphics are loaded to RAM (presumably to allow them to be decompressed). Using it on maps with non-boss objects will result in those objects having messed up graphics.
- Bit 7: ?
Map Theme IDs
0x00: Snow 0x01: Jungle 0x02: Temple 0x03: Coral 0x04: Ship 0x05: Kong token bonus minigame 0x06: File select menu 0x07: Underwater ruins 0x08: Blimp 0x09: Cave 0x0A: Clouds 0x0B: Skyscraper 0x0C: Construction site 0x0D: Mountain
Metatiles
A metatile is a collection of two or more tiles that forms a larger graphic.
Donkey Kong Land uses 4 x 4 tile metatiles which means that each one is a 32 x 32 pixel square.
See also: Map Metatiles
Metatile Maps
A metatile map is a 2D array of 8-bit metatile IDs that defines how the background of a map looks and behaves.
Metatile maps have their origin at (32,32), meaning it's drawn down and to the right that many pixels.
Metatile Tables
Metatile tables are used to describe the various properties of individual metatiles.
MetatileIndexTable Structure
Describes which tile indices are used by a set of metatiles.
- 0x0000-00FF: A list of 8-bit tile indices for each metatile's tile (0,0), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0100-01FF: A list of 8-bit tile indices for each metatile's tile (1,0), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0200-02FF: A list of 8-bit tile indices for each metatile's tile (2,0), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0300-03FF: A list of 8-bit tile indices for each metatile's tile (3,0), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0400-04FF: A list of 8-bit tile indices for each metatile's tile (0,1), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0500-05FF: A list of 8-bit tile indices for each metatile's tile (1,1), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0600-06FF: A list of 8-bit tile indices for each metatile's tile (2,1), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0700-07FF: A list of 8-bit tile indices for each metatile's tile (3,1), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0800-08FF: A list of 8-bit tile indices for each metatile's tile (0,2), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0900-09FF: A list of 8-bit tile indices for each metatile's tile (1,2), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0A00-0AFF: A list of 8-bit tile indices for each metatile's tile (2,2), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0B00-0BFF: A list of 8-bit tile indices for each metatile's tile (3,2), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0C00-0CFF: A list of 8-bit tile indices for each metatile's tile (0,3), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0D00-0DFF: A list of 8-bit tile indices for each metatile's tile (1,3), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0E00-0EFF: A list of 8-bit tile indices for each metatile's tile (2,3), padded to 0x100 bytes. It's indexed using a metatile ID.
- 0x0F00+: A list of 8-bit tile indices for each metatile's tile (3,3). It's indexed using a metatile ID.
Each list in this structure, ignoring padding, may not cross a 0x100 byte page boundary.
Layouts
Layouts determine where most things, including objects, are placed on a map. Bananas are a notable exception since they're placed using a different kind of layout.
The layout data is notably different from the format used by Donkey Kong Land 2 and Donkey Kong Land III. For one, it's much more complicated. Additionally, bananas are placed using a different kind of layout.
See also: Map Layouts
Layout Types
- 0: Layout1D
- This layout type has the unique ability to use FunctionPlacements and CameraCuePlacements.
- 1: Layout2D
- This layout type partitions Placements in a regular grid. It is suitable for situations where there are many Placements in the same vertical space. Compared to 1D layouts it's more versatile but lacks some features and uses more memory.
Layout Structure
- A Layout must have, at minimum, a list of Placements that determine where things are placed on the map. The list may contain up to 0x80 items. Each list item has an ID that is the same as its index in the list.
- There are two different types of Layout structures: Layout1D and Layout2D.
See also: Layout1D, Layout2D, Placement
Layout1D Structure
1D layouts store Placements in a list that is sorted based on ascending x coordinate.
- 0x00+: A list of Placement structures that is sorted based on ascending x coordinate. Its end point isn't clearly defined, but one can reasonably assume one after encountering a list item whose x coordinate is too far right to ever enter the view.
A quirk of 1D layouts is that the last item in the Placement list must have an x coordinate that is far enough right that it will never enter the view. Due to that, only 0x7F out of the maximum 0x80 Placements are available for regular use.
Layout2DHeader Structure
- 0x00-01: A pointer to the first valid item in the partition array in the same ROM bank.
- 0x02-03: A pointer to the byte after the last valid item in the partition array in the same ROM bank. It's also a pointer to the Layout's Placement list in the same ROM bank.
See also: Layout2D
Layout2D Structure
2D layouts partition Placements into a regular grid of 0x80 x 0x80 pixel cells. The structure itself consists of a 2D array, row pointers to that array, and a Placement list that is sorted based on partition.
- Immediately preceding this structure is a Layout2DHeader structure.
- 0x00+: A list of 16-bit pointers to rows of a continuous 2D array in the same ROM bank. The array, called the partition array, is indexed using a location, in partitions.
- Unless a partition is empty, its associated array item points to an item in the Layout's Placement list that is the first Placement in said partition.
- A partition is empty if its associated array item points to 0.
- A partition is also empty if its associated array item is located outside of the range defined in the Layout2DHeader that precedes this structure.
- Since the array is continuous, its width can be calculated like so:
SIZE_OF_PTR_16 = 2 sizeOfRow = (rowPointers[1] - rowPointers[0]) / SIZE_OF_PTR_16
- The array's height is undefined, but one can reasonably guess it by utilizing the pointers in the Layout2DHeader.
The origin for this layout type is located at (-0x80,-0x80), in pixels.
A quirk of 2D layouts is that the last item in the Placement list must not be located in any partition. Due to that, only 0x7F out of the maximum 0x80 Placements are available for regular use.
See also: Layout, Layout2DHeader, Placement
Placement Structure
A structure that describes something that is placed on a map.
See also: ObjectPlacement1D, ObjectPlacement2D, FunctionPlacement, CameraCuePlacement, DataBlockPlacement
ObjectPlacement1D Structure
A Placement that describes where an object is placed. They can only be used by 1D layouts.
- 0x00:
- 0x01: LSB of x coordinate
- 0x02:
- Bits 0-4: MSB of x coordinate
- Bits 5-7: MSB of y coordinate
- 0x03: LSB of y coordinate
See also: Placement
ObjectPlacement2D Structure
A Placement that describes where an object is placed. They can only be used by 2D layouts.
- 0x00:
- 0x01:
- Bits 0-6: The object's x coordinate (partition-relative).
- Bit 7: If set, then this indicates that this Placement is in a different partition than the one that precedes it.
- 0x02:
- Bits 0-6: The object's y coordinate (partition-relative).
- Bit 7: Unused?
- 0x03: This Placement's ID represented as a bit index (big endian) and a byte index.
- Bits 0-2: A bit index (big endian).
- Bits 3-7: A byte index.
- It's formatted this way because it makes it easier to extract bits from bit lists.
- It can be converted to a regular Placement ID like so:
SIZE_OF_BYTE_IN_BITS = 8 placementId = byteIndex * SIZE_OF_BYTE_IN_BITS + ((SIZE_OF_BYTE_IN_BITS - 1) - bitIndex)
See also: Placement
FunctionPlacement Structure
A Placement that describes where to call a function. The function may get called multiple times. They can only be used by 1D layouts.
The function must have this signature:
@in hl - A pointer to the byte following the FunctionPlacement structure that is being executed and to any DataBlockPlacement structures that may follow it.
- 0x00:
- Bits 0-4: MSB of x coordinate
- Bit 5: Must be 0
- Bit 6: Must be 0
- Bit 7: Must be 1
- 0x01: LSB of x coordinate
- 0x02-03:
- Bits 0x0-E: A pointer to the function to call. The bank being pointed to is the one containing this structure.
- Bit 0xF: Unused?
See also: Placement
CameraCuePlacement Structure
A non-functional Placement type that may have at one point been used to affect the camera's behavior. They don't appear on any maps. They can only be used by 1D layouts.
When it enters the view, either the upper or lower camera bound gets set. However, since those get overwritten again quickly afterward, it has no visible effect. It may have at some point been a functional way to influence the camera— a role that OBJ_CAMERA_CUE now fulfills.
- 0x00:
- Bits 0-4: MSB of x coordinate
- Bit 5: Must be 1
- Bit 6: Must be 0
- Bit 7: Must be 1
- 0x01: LSB of x coordinate
- 0x02:
- Bits 0-4: The MSB of the value to set a variable to.
- Bits 5-7: Determines which variable to set.
- Possible values:
- 0: Set the upper camera bound. However, since it gets overwritten again quickly afterward, this has no visible effect.
- 1-7: Set the lower camera bound. However, since it gets overwritten again quickly afterward, this has no visible effect.
- Possible values:
- 0x03: The LSB of the value to set a variable to.
See also: Placement
DataBlockPlacement Structure
Contains additional data for the (non-data-block) Placement structure that precedes it. One or more of these may optionally follow any Placement structure.
While these don't actually have a presence on the map, they're important for passing data to functions for object initialization and FunctionPlacement structures.
- 0x00:
- Bits 0-4: Field 0
- Bit 5: Unused?
- Bit 6: Must be 1
- Bit 7: Must be 1
- 0x01: Field 1
- 0x02: Field 2
- 0x03: Field 3
See also: Placement, ObjectPlacement1D, ObjectPlacement2D
Objects
Objects are placed on maps by using layouts.
Object Type Configuration Data
0x10001: A list of 16-bit pointers to ObjectTypeConfig structures in the same ROM bank. It's indexed using an object type ID.
- Each type of object is given an initial state based on its corresponding item in this list. Therefore, changing items in this list will affect all objects of a given type.
ObjectTypeConfig Structure
Contains values that define part of the initial state for a type of object.
- 0x00: ?
- 0x01: ?
- 0x02-03: A 16-bit pointer to the object type's default MetaspriteSet in ROM bank 6.
- 0x04-05:
- Bits 0x0-E: A 16-bit function pointer to ROM bank 4 for the object type's default update function.
- Bit 0xF: ?
- 0x06: ?
- 0x07: ?
- 0x08: ?
- 0x09: ?
Object Configuration Data
Object configuration data makes it possible to have variations of the same object type beyond just location and direction. Not all object types have configuration data but, when present, it can be provided in any of the following ways:
- Location
- The configuration data is stored in the object's location.
- Unless otherwise noted, location bits used in this way are subsequently set to zero. For example: if bits 0-1 of an x coordinate are used to store configuration data, then those bits would get set to 0— effectively flooring the x coordinate to a multiple of 4.
- Direction
- Data blocks
- The configuration data is stored in one or more DataBlockPlacement structures that follow the object's associated ObjectPlacement1D or ObjectPlacement2D structure.
Object State
0xC000-C7FF: A list of 8 ObjectState structures in RAM that describe which objects are currently in existence.
ObjectState Structure
Describes an object's state.
- 0x00-AF: Padding. This area is often used for unrelated data.
- 0xB0: The type of object this is, 0x00 if the ObjectState isn't in use.
- 0xB1: ?
- 0xB2: (For objects that use the regular metasprite drawing system) The metasprite set index of the object's metasprite.
- 0xB3:
- Bit 5: The direction that the object faces
- 0xB4-B6: x coordinate, in 1/0x100 pixels.
- 0xB7-B9: y coordinate, in 1/0x100 pixels.
- 0xBA-CE: Often used for data that is specific to a type of object.
- 0xCF: Invulnerability timer
- 0xD0-D2: A 24-bit pointer (bank last) to tile patterns for the object's metasprite.
- 0xD3-D4: A 16-bit pointer to the first tile pattern allocated for this object in VRAM.
- 0xD5: The number of tile patterns for this object's graphics that need to be uploaded to VRAM.
- 0xD6:
- Bit 2: Whether the object's graphics need to be updated.
- 0xD7-D8: A 16-bit pointer to the MetaspriteLayout used by the object's metasprite in ROM bank 0x06. If the MSB of this pointer is 0, then it means that none has been assigned.
- 0xD9: The index of the first tile pattern allocated for this object's graphics.
- 0xDA-DB: The next value of ObjectState+0xD7.
- 0xDC: The next value of ObjectState+0xD9.
- 0xDD: ?
- 0xDE: ?
- 0xDF: ? The previous value of ObjectState+0xDE.
- 0xE0: ?
- 0xE1: ? The previous value of ObjectState+0xE0.
- ...
- 0xE8: ?
- ...
- 0xEA: ?
- 0xEB: ?
- 0xEC-ED: A pointer to the MetaspriteSet in ROM bank 6 that contains the MetaspriteInfo for the object's metasprite.
- 0xEE-EF:
- Bits 0x0-E: A 16-bit pointer to the object's update function in ROM bank 4.
- Bit 0xF: ?
- 0xF0: ?
- 0xF1: ?
- ...
- 0xF3: ?
- 0xF4: ?
- 0xF5: ?
- 0xF6: ?
- 0xF7: ?
- 0xF8: ?
- 0xF9: ?
- 0xFA-FB: ?
- 0xFC-FD: ?
- ...?
Object Directions
- 0: Right
- 1: Left
Object Types
Valid object type IDs range from 0x00-3E.
0x00 (OBJ_NULL)
A special object type that represents "no object". While it can be spawned, doing so restarts the game.
0x01 (OBJ_EXPLOSION)
An explosion, like what appears when you destroy a buddy barrel or an animal crate.
0x02 (OBJ_ANIMAL_CRATE)
An animal crate containing an animal friend.
Configuration
- x bits 0-1: The type of animal crate this is
ObjectState Variables
- 0xB2: The type of animal crate this is.
Graphics
The animal crate's type is used as a metasprite set index.
Animal Crate Types
- 0: Rambi
- 1: Expresso
- 2-3: Empty (the crate self-destructs)
0x03 (OBJ_BURIED_TIRE)
A half-buried tire
See also: OBJ_TIRE
0x04 (OBJ_SWIRLWIND)
Swirlwind
0x05 (OBJ_ZINGER)
Zinger
Configuration
- x bits 0-1: Movement pattern type
- The type of movement pattern to use.
- Direction: Affects its graphic, but does not affect its movement pattern.
ObjectState Variables
- 0xBA-BB: Affects the movement pattern
- 0xBD-BE: Affects the movement pattern
- 0xC2: The type of movement pattern being used.
Zinger Movement Pattern Types
- 0: Vertical (short)
- 1: Circular / diagonal
- 2: Vertical (long)
0x06 (OBJ_KRITTER)
Kritter
Configuration
- Data Block 0:
- 0x00:
- Bits 0-4: MSB of movement range maximum
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: LSB of movement range minimum
- 0x02: MSB of movement range minimum
- 0x03: LSB of movement range maximum
ObjectState Variables
- 0xBB: ?
- 0xC0-C1: Movement range minimum
- 0xC2-C3: Movement range maximum
See also: OBJ_JUMPING_KRITTER
0x07 (OBJ_ARMY)
Army
ObjectState Variables
- 0xC2: ?
0x08 (OBJ_SLIPPA)
Slippa
Configuration
- Data Block 0:
- 0x00:
- Bits 0-4: MSB of movement range maximum
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: LSB of movement range minimum
- 0x02: MSB of movement range minimum
- 0x03: LSB of movement range maximum
ObjectState Variables
- 0xC0-C1: Movement range minimum
- 0xC2-C3: Movement range maximum
See also: OBJ_CLIMBING_SLIPPA, OBJ_SLIPPA_JAR
0x09 (OBJ_VINE)
A vine that may be swung on
Configuration
- x bits 0-1: The vine's ID
- A vine's ID is used to determine whether the vine will automatically start swinging when it spawns. If a vine with the preceding ID is in view when this vine spawns, then this vine will start out swinging and with its animation frame automatically synchronized.
- Vine IDs wrap around from 0 to 3, therefore the ID that precedes 0 is 3. The same ID may be used by multiple vines.
- Direction: Only affects the vine's graphics. There is no way to make a left-swinging vine.
ObjectState Variables
- 0xB1: ?
- 0xC2: The vine's ID
- 0xC3: Whether the vine is NOT swinging
Graphics
- Unless a vine starts out swinging, it starts with metasprite set index 0x12.
- Unlike most objects, sprite palette 1 is used for its graphic.
0x0A (OBJ_KONG_LETTER)
A K-O-N-G letter.
Configuration
- x bits 0-1: The type of K-O-N-G letter this is.
ObjectState Variables
- 0xC0: The type of K-O-N-G letter this is.
Graphics
- Its graphic isn't flipped according to it's direction.
- The tile pattern indices used for the object's graphic are offset based on which type of K-O-N-G letter this is, like so:
tilePatternIndexOffset = type * 4
K-O-N-G Letter Types
- 0: K
- 1: O
- 2: N
- 3: G
See also: OBJ_KONG_LETTER_PLATFORM, OBJ_KONG_LETTER_PLATFORM_MACHINE
0x0B (OBJ_BUDDY_BARREL)
Buddy barrel
See also: OBJ_TOUCH_ACTIVATED_BUDDY_BARREL
0x0C (OBJ_NECKY)
Necky
See also: OBJ_COCONUT_PROJECTILE
0x0D (OBJ_KONG_TOKEN_COUNTER)
Kong token counter (used for bonus stage minigames)
See also: OBJ_KONG_TOKEN
0x0E (OBJ_TIRE)
Tire
See also: OBJ_BURIED_TIRE
0x0F (OBJ_BANANA_BUNCH)
Banana bunch
0x10 (OBJ_OIL_DRUM)
Oil drum
Configuration
- y bits 0-1: The type of oil drum behavior to use.
ObjectState Variables
- 0xC0: The type of oil drum behavior being used.
Oil Drum Behavior Types
- 0: On fire permanently
- 1: Alternates between on fire and extinguished
- 2: Extinguished permanently
0x11 (OBJ_EXTRA_LIFE_BALLOON)
Extra life balloon
0x12 (OBJ_MINCER)
Mincer
Configuration
- Data Block 0: ?
0x13 (OBJ_TNT_BARREL)
TNT barrel
See also: OBJ_WOODEN_BARREL, OBJ_METALLIC_BARREL
0x14 (OBJ_METALLIC_BARREL)
Metallic barrel
See also: OBJ_WOODEN_BARREL, OBJ_TNT_BARREL
0x15 (OBJ_EXPRESSO)
Expresso
See also: OBJ_ANIMAL_CRATE
0x16 (OBJ_RAMBI)
Rambi
See also: OBJ_ANIMAL_CRATE
0x17 (OBJ_MINI_NECKY)
Mini-necky
See also: OBJ_COCONUT_PROJECTILE
0x18 (OBJ_NEMO)
Nemo
Configuration
- Data Block 0: ?
0x19 (OBJ_BUTTON)
Button
0x1A (OBJ_JUMPING_KRITTER)
Kritter (jumping)
Configuration
- Data Block 0: ?
See also: OBJ_KRITTER
0x1B (OBJ_GNAWTY)
Gnawty
Configuration
- Data Block 0:
- 0x00:
- Bits 0-4: MSB of movement range maximum
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: LSB of movement range minimum
- 0x02: MSB of movement range minimum
- 0x03: LSB of movement range maximum
ObjectState Variables
- 0xC0-C1: Movement range minimum
- 0xC2-C3: Movement range maximum
0x1C (OBJ_COCONUT_PROJECTILE)
The coconut thrown by neckies and mini-neckies
See also: OBJ_NECKY, OBJ_MINI_NECKY
0x1D (OBJ_EXPLOSIVES_BARREL)
A barrel of explosives
0x1E (OBJ_ROPE)
A climbable rope
Configuration
- x bits 0-1: The type of rope this is.
- Direction: Has no effect. The rope's initial movement direction is always to the right.
- Data Block 0:
- This data block is only used if the rope's type is 0.
- This data block must be present if the rope's type is 0.
- 0x00:
- Bits 0-4: MSB of movement range maximum
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: LSB of movement range minimum
- 0x02: MSB of movement range minimum
- 0x03: LSB of movement range maximum
ObjectState Variables
- 0xC0-C1: Movement range minimum
- 0xC2-C3: Movement range maximum
- 0xC4: The type of rope this is.
- 0xC5: Current length
- 0xC6: Target length
- 0xC9: (Hidden ropes only) The ID of the bonus map that the rope leads to. It must be a bonus map.
Graphics
- Ropes are drawn in segments.
- Each segment is drawn using a single 8 x 16 sprite.
- A segment's sprite must not overlap with any other segment's sprite.
- Graphics are available for 3 segment lengths: 0x10, 0x08, and 0x04 with tile pattern index offsets of 0x00, 0x02, and 0x04 respectively.
- Many of the segment length graphics are shorter than a sprite. In those cases, the graphic is aligned to the topmost edge of the sprite.
- Because the segments do not have per-pixel precision, one end of the rope is unable to smoothly adjust as the rope's length changes. The bottom end of the rope is always the one to do this.
- Its graphics do not flip according to its direction.
- Ropes are drawn with an offset of (-10,2).
Rope Types
- 0: Fixed-length
- Length: 0x78
- Motion: Stationary until climbed. Afterward it ping-pongs horizontally within its movement range with an initial direction of right.
- 1: Hidden
- Length: 0x00 increasing to 0x78
- Motion: Moves upward until it disappears
- Notes: This kind of rope warps you to another map if you climb it. Since there's no way to specify a destination map in the configuration, this rope can only be used properly when spawned programmatically which only happens when a hidden rope gets revealed.
0x1F (OBJ_KLAPTRAP)
Klaptrap
Configuration
- Data Block 0:
- 0x00:
- Bits 0-4: MSB of movement range maximum
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: LSB of movement range minimum
- 0x02: MSB of movement range minimum
- 0x03: LSB of movement range maximum
ObjectState Variables
- 0xC0-C1: Movement range minimum
- 0xC2-C3: Movement range maximum
0x20 (OBJ_KONG_LETTER_PLATFORM_MACHINE)
Transforms K-O-N-G letters into platforms
See also: OBJ_KONG_LETTER, OBJ_KONG_LETTER_PLATFORM
0x21 (OBJ_CHOMPS_JR)
Chomps Jr.
Configuration
- Data Block 0:
- 0x00:
- Bits 0-4: The type of movement to use.
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: Movement range minimum x
- If this value is non-zero, then it gets negated and made object-relative.
- 0x02: Movement range maximum x
- If this value is non-zero, then it gets made object-relative. Otherwise, 0x4000 is used instead.
- 0x03: (Wave movement type only) The height of the movement track.
ObjectState Variables
- 0xC0: Whether the custom movement range minimum y is enabled
- 0xC1-C2: Movement range minimum x
- 0xC3-C4: Movement range maximum x
- 0xC6-C7: ?
- 0xC8: ? (Wave movement type only) The height of the movement track.
Fish Movement Types
- 0: Wander
- The object will wander around in its movement area.
- Movement range minimum y: -0x80 (object-relative)
- Movement range maximum y: 0 (object-relative)
- 1: Wave
- The object will move as if it's on a track shaped like a series of sine waves.
- The track's width is the same as the movement range's width. The track's height is set manually.
- Movement range minimum y: The height of the movement track (negated and made object-relative)
- Movement range maximum y: 0 (object-relative)
0x22 (OBJ_CLAMBO)
Clambo
0x23 (OBJ_KONG_LETTER_PLATFORM)
A platform that looks like a K-O-N-G letter
Configuration
- x bits 0-1: The type of K-O-N-G letter this is.
- y bits 0-1: Group ID
- The ID of the group of K-O-N-G letter platforms that this belongs to.
- When K-O-N-G letters are fed into a K-O-N-G letter platform machine, only K-O-N-G letters in the same group get revealed.
ObjectState Variables
- 0xC0: The type of K-O-N-G letter this is.
- 0xC1: Group ID
Graphics
It gets drawn in the same way as OBJ_KONG_LETTER.
See also: OBJ_KONG_LETTER, OBJ_KONG_LETTER_PLATFORM_MACHINE
0x24 (OBJ_FANGFISH)
Fangfish
Configuration
- Data Block 0:
- 0x00:
- Bits 0-4: The type of movement to use.
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: Movement range minimum x
- If this value is non-zero, then it gets negated and made object-relative.
- 0x02: Movement range maximum x
- If this value is non-zero, then it gets made object-relative. Otherwise, 0x4000 is used instead.
- 0x03: (Wave movement type only) The height of the movement track.
ObjectState Variables
- 0xC0: Whether the custom movement range minimum y is enabled
- 0xC1-C2: Movement range minimum x
- 0xC3-C4: Movement range maximum x
- 0xC6-C7: ?
- 0xC8: ? (Wave movement type only) The height of the movement track.
0x25 (OBJ_KRUSHA)
Krusha
Configuration
- Data Block 0:
- 0x00:
- Bits 0-4: MSB of movement range maximum
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: LSB of movement range minimum
- 0x02: MSB of movement range minimum
- 0x03: LSB of movement range maximum
ObjectState Variables
- 0xBB: ?
- 0xC0-C1: Movement range minimum
- 0xC2-C3: Movement range maximum
0x26 (OBJ_GLOOP)
Gloop
Configuration
- Data Block 0:
- 0x00:
- Bits 0-4: MSB of movement range maximum
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: LSB of movement range minimum
- 0x02: MSB of movement range minimum
- 0x03: LSB of movement range maximum
ObjectState Variables
- 0xC0-C1: Movement range minimum
- 0xC2-C3: Movement range maximum
0x27 (OBJ_WOODEN_BARREL)
Wooden barrel
See also: OBJ_TNT_BARREL, OBJ_METALLIC_BARREL
0x28 (OBJ_WILD_STING)
Wild sting
ObjectState Variables
- 0xC2: ?
- 0xC3: ?
Graphics
Data set 0x2B must be loaded for objects of this type to appear correctly. Additionally, the map must be set to load metasprite graphics from RAM (see MapInfo). As a result, objects of this type will only appear correctly on map 0x2B (Wild Sting Fling).
0x29 (OBJ_HARD_HAT)
Hard Hat
Graphics
Data set 0x20 must be loaded for objects of this type to appear correctly. Additionally, the map must be set to load metasprite graphics from RAM (see MapInfo). As a result, objects of this type will only appear correctly on map 0x20 (Mad Mole Holes).
See also: OBJ_HARD_HAT_PROJECTILE
0x2A (OBJ_CHECKPOINT)
Checkpoint
ObjectState Variables
- 0xC0: ?
0x2B (OBJ_GOAL)
Goal
0x2C (OBJ_HOGWASH)
Hogwash
Configuration
- Data Block 0:
- 0x00:
- Bits 0-4: MSB of movement range maximum
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: LSB of movement range minimum
- 0x02: MSB of movement range minimum
- 0x03: LSB of movement range maximum
ObjectState Variables
- 0xC0-C1: Movement range minimum
- 0xC2-C3: Movement range maximum
0x2D (OBJ_SLIPPA_JAR)
A jar that spawns slippas
Configuration
- x bit 0: Determines which directions to spawn slippas in
- Possible values:
- 0: Spawns slippas to the left
- 1: Spawns slippas to the left and right
- Possible values:
- x bit 1: The slippa jar's initial state
- y bit 0: Slippa spawn delay
- Determines the delay between when a slippa dies and when the slippa jar spawns more of them.
- Possible values:
- 0: Short delay
- 1: Long delay
- Direction: (while stationary only) Affects the jar's graphic only. The slippas that it spawns are not affected.
- Data Block 0:
- 0x00:
- Bits 0-4: MSB of slippa movement range maximum
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: LSB of slippa movement range minimum
- 0x02: MSB of slippa movement range minimum
- 0x03: LSB of slippa movement range maximum
ObjectState Variables
- 0xBA-BC: The horizontal movement speed to use while rolling, in 1/0x100 pixels.
- 0xC0-C1: Slippa movement range minimum
- 0xC2-C3: Slippa movement range maximum
- 0xC4:
- Bit 5: Related to the direction that slippas are spawned in
- 0xC5:
- Bit 5: Related to the direction that slippas are spawned in
- 0xC7: Slippa spawn delay
Graphics
- While stationary it uses metasprite set indices 0x00-0B.
- While rolling it uses metasprite set indices 0x0C-14.
Slippa Jar States
- 0: Stationary
- The slippa jar remains stationary and spawns slippas.
- 1: Rolling
- The slippa jar rolls around, presumably powered by any slippas that are inside it. If it runs into a wall, then it rights itself and becomes Stationary.
See also: OBJ_SLIPPA
0x2E (OBJ_TOUCH_ACTIVATED_BUDDY_BARREL)
A touch-activated buddy barrel
See also: OBJ_BUDDY_BARREL
0x2F (OBJ_KONG_TOKEN)
Kong token
0x30 (OBJ_CLOUD_PLATFORM)
Cloud platform
Configuration
- Direction: Whether to focus the camera on the platform. The object's direction gets set to 0.
ObjectState Variables
- 0xBC: ?
- 0xC1:
- Bit 5: Whether to focus the camera on the platform.
0x31 (OBJ_BARREL_CANNON)
Barrel cannon
Configuration
- Direction: Only affects the object's graphic
- Data Block 0:
- 0x00:
- Bits 0-4: Movement speed, in increments of 0x20.
- It determines the speed at which to move along the movement track.
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01:
- Bit 0: No discernible effect. Every barrel cannon in the game has this bit set to 0.
- Bit 1: Whether to move while full.
- Bit 2: Whether to move while empty.
- Bits 3-7: The length of the movement track along the movement track's forward axis, in increments of 8.
- 0x02:
- Bit 0: (Delayed barrel cannons only) Whether to allow shooting while rotating.
- Bits 1-2: The movement track's forward axis.
- When a barrel begins moving along its track, it always starts along the backward axis. For example: if the forward axis is north, then it will initially move south, stop, then move north.
- Bits 3-7: The length of the movement track along the movement track's backward axis, in increments of 8.
- 0x03:
- Data Block 1:
- 0x00:
- Bits 0-4: Physics delay
- The number of frames to disable character physics for after shooting, in increments of 8.
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01:
- Bits 0-2: Unused
- Bits 3-7: Input delay
- The number of frames to disable character input for after shooting, in increments of 8.
- 0x02: The amount of force to shoot with.
- 0x40 is a little force and 0x90 is a lot. Shooting upward requires much more force than shooting in other directions.
- 0x03:
- Bit 0: Unused
- Bit 1: Rotation mode
- Bit 2: Whether to enable "rotate while empty" when entered.
- This is the only way to enable "rotate while empty".
- Bit 3: Whether to enable "move while empty" when entered.
- This could be used to, for example, allow the barrel cannon to move out of reach after it has been fired.
- Bits 4-7: The rotation speed, in increments of 0x10.
- A rotation speed of 0x100 will turn the barrel cannon by one secondary-intercardinal direction (i.e. 22.5 degrees) per frame.
ObjectState Variables
- 0xB1: Fine rotation
- 0xB2: The barrel cannon's direction and type. This value is also used as its metasprite set index.
- 0xBA-BB: Movement speed.
- 0xBC: ?
- 0xC0:
- Bit 0: ?
- Bit 1: Whether to move while full.
- Bit 2: Whether to move while empty.
- Bit 3: (Delayed barrel cannons only) Whether to allow shooting while rotating.
- Bit 4-5: The movement track's forward axis.
- Bit 6: Whether to enable "rotate while empty" when entered.
- Bit 7: Whether to enable "move while empty" when entered.
- 0xC1-C2: The minimum x or y coordinate of the movement track's extents. A y coordinate is used unless the movement track's forward axis is 1.
- 0xC3-C4: The maximum x or y coordinate of the movement track's extents. A y coordinate is used unless the movement track's forward axis is 1.
- 0xC5: Initial rotation
- 0xC6: Target rotation
- 0xC7: The value that gets added to the rotation when a full rotation step has been made. Its value depends on the barrel cannon's relative rotation direction. This should be either -1 (rotate Left) or 1 (rotate Right)).
- 0xC8: Physics delay, in frames.
- 0xC9: Input delay, in frames.
- 0xCA: Shooting force.
- 0xCB: Rotation speed.
- 0xCC:
- Bit 0: The barrel cannon's rotation mode.
- Bits 1-5: ?
- Bit 6: Whether to rotate while empty.
- Bit 7: Whether to shoot now.
- 0xCE: ?
Graphics
The metasprite set index used can be calculated like so:
metaspriteSetIndex = type * 0x10 + rotation
Barrel Cannon Types
- 0: Delayed
- The barrel cannon shoots only after user input. It has no emblem.
- Note that, unless its option to shoot while rotating is enabled, this type of barrel cannon must reach its target rotation before it can be fired. This can be a problem if its rotation speed is set to zero or if its rotation mode is set to Forever. In either situation, the character would become stuck inside the barrel cannon if they were to use it.
- 1: Auto-fire
- The barrel cannon shoots after it finishes rotating, without user input. It has an explosion emblem.
Barrel Cannon Rotation Modes
- 0: Once
- When entered, the barrel cannon will rotate to its target rotation and then stop. After being fired it will rotate back to its initial rotation.
- 1: Forever
- The barrel cannon repeatedly rotates to its target rotation and then back. If the initial and target rotations are the same, then this results in the barrel cannon spinning in one direction forever.
Barrel Cannon Directions
Barrel cannon directions start at north and turn clockwise in increments of secondary-intercardinal directions (i.e. 22.5 degrees).
- 0x0: N
- 0x1: NNE
- 0x2: NE
- 0x3: ENE
- 0x4: E
- 0x5: ESE
- 0x6: SE
- 0x7: SSE
- 0x8: S
- 0x9: SSW
- 0xA: SW
- 0xB: WSW
- 0xC: W
- 0xD: WNW
- 0xE: NW
- 0xF: NNW
Barrel Cannon Relative Directions
- 0: Left
- 1: Right
Barrel Cannon Movement Track Forward Axes
- 0: N
- 1: W
- 2: NW
- 3: NE
0x32 (OBJ_MOVING_PLATFORM)
Moving platform
Configuration
- x bits 0-1: The type of moving platform that this is.
- y bits 0-1: ?
- Direction: ? The object's direction gets overwritten with 0.
- Data Block 0:
- ?
- This data block is only used if the platform's type is in the range 0-1.
- This data block must be present if the platform's type is in the range 0-1.
Graphics
The first metasprite set index used is based on the moving platform's type and can be calculated like so:
firstMetaspriteSetIndex = type * 4
Moving Platform Types
Valid moving platform types range from 0-2.
- 0: Conveyor
- Animation length: 4
- 1: Directional
- Animation length: 1 (4 subimages— one for each direction)
- 2: Rock
- Animation length: 1
0x33 (OBJ_HARD_HAT_PROJECTILE)
The hard hat thrown by Hard Hat.
Graphics
Data set 0x20 must be loaded for objects of this type to appear correctly. Additionally, the map must be set to load metasprite graphics from RAM (see MapInfo). As a result, objects of this type will only appear correctly on map 0x20 (Mad Mole Holes).
See also: OBJ_HARD_HAT
0x34 (OBJ_SNAPPER)
Snapper
Configuration
- Data Block 0:
- 0x00:
- Bits 0-4: MSB of movement range maximum
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: LSB of movement range minimum
- 0x02: MSB of movement range minimum
- 0x03: LSB of movement range maximum
ObjectState Variables
- 0xC0-C1: Movement range minimum
- 0xC2-C3: Movement range maximum
0x35 (OBJ_CLIMBING_SLIPPA)
A slippa that climbs downward. Once it reaches the end of its climbing range it falls to its demise.
Configuration
- Data Block 0:
- 0x00:
- Bits 0-4: MSB of climbing range maximum
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: LSB of climbing range minimum
- 0x02: MSB of climbing range minimum
- 0x03: LSB of climbing range maximum
ObjectState Variables
- 0xC0-C1: Climbing range minimum
- 0xC2-C3: Climbing range maximum
See also: OBJ_SLIPPA
0x36 (OBJ_BOULDER)
Boulder
See also: OBJ_BOULDER_SPAWNER
0x37 (OBJ_BOULDER_SPAWNER)
An invisible object that spawns boulders
Configuration
- x bits 0-1: Bits 0-1 of the boulder spawn rate.
- The rate at which to spawn boulders.
- Example values:
- 0x00: Never spawn boulders.
- 0x03: Spawn a boulder approximately every half a second.
- 0x15: Spawn an impenetrable cascade of boulders.
- y bits 0-1: Bits 1-2 of the boulder spawn rate.
- y bit 2: Boulder spawn type.
- Possible values:
- 0: In-place
- Spawn boulders at the boulder spawner's location.
- 1: From above
- Spawn boulders at the top of the screen.
- Possible values:
ObjectState Variables
- 0xC0: Boulder spawn rate.
- 0xC1: Boulder spawn timer. A boulder gets spawned when it overflows.
- 0xC2: ?
See also: OBJ_BOULDER
0x38 (OBJ_CAMERA_CUE)
Camera cue. It's an invisible object that affects the camera's behavior while it's in view.
0x39 (OBJ_WARP_POINT)
A warp point— an invisible object that moves you to another location when you touch it.
Configuration
Data block 0:
- If the map containing the warp point is a bonus map, then this data block gets ignored and the game returns to the previous map.
- 0x00:
- Bits 0-4: Unused
- Bits 5-7: Reserved (see DataBlockPlacement).
- 0x01: Destination
- The ID of the bonus map to warp to. The destination must be a bonus map.
- 0x02: Return spawn point
- The ID of the spawn point to return to. It's used to index in the list of SpawnInfo structures at 0x4BED3 that describe where to spawn the player character after they exit the bonus map.
- 0x03: Unused
- If the map containing the warp point is a bonus map, then this data block gets ignored and the game returns to the previous map.
ObjectState Variables
- 0xC9: (Non-bonus maps only) Destination map ID
0x3A (OBJ_CROWN_PROJECTILE)
The crown thrown by King K. Rool.
Graphics
Data set 0x39 must be loaded for objects of this type to appear correctly. Additionally, the map must be set to load metasprite graphics from RAM (see MapInfo). As a result, objects of this type will only appear correctly on map 0x39 (K. Rool's Kingdom).
See also: OBJ_KING_K_ROOL
0x3B (OBJ_KING_K_ROOL)
King K. Rool
Graphics
Data set 0x39 must be loaded for objects of this type to appear correctly. Additionally, the map must be set to load metasprite graphics from RAM (see MapInfo). As a result, objects of this type will only appear correctly on map 0x39 (K. Rool's Kingdom).
See also: OBJ_CROWN_PROJECTILE
0x3C (OBJ_BALLOON_PLATFORM)
Balloon platform
0x3D (OBJ_COLOSSAL_CLAMBO)
Colossal Clambo
Configuration
- x bits 0-1: Which part of Colossal Clambo this represents.
ObjectState Variables
- 0xC0: Which part of Colossal Clambo this represents.
Graphics
Data set 0x37 must be loaded for objects of this type to appear correctly. Additionally, the map must be set to load metasprite graphics from RAM (see MapInfo). As a result, objects of this type will only appear correctly on map 0x37 (Seabed Showdown).
Colossal Clambo Part Types
- 0: Colossal Clambo
- 1: Clam
- 2: Pearl projectile
0x3E (OBJ_UNKNOWN_3E)
It doesn't show up when spawned. The code treats it a lot like K-O-N-G letters and K-O-N-G letter platforms.
Metasprites
A metasprite is a collection of one or more sprites drawn together to form a complete graphic.
MetaspriteSet Structure
- 0x00+: A list of MetaspriteInfo structures. It's indexed using a metasprite set index. It has no clearly defined end point.
MetaspriteInfo Structure
Describes how to draw a metasprite.
- 0x00-03:
- Bits 0x00-0D: A 16-bit pointer to the metasprite's MetaspriteLayout is this value + 0x4000. If this value is 0, then the metasprite has no layout and must be drawn programmatically.
- To determine which bank is being pointed to, consider the type of metasprite this is:
- Is it a player character metasprite? Use ROM bank 5
- Is it some other kind of metasprite? Use ROM bank 6
- Alternatively, one can assume that it points to the same ROM bank as the MetaspriteInfo structure since that seems to always be the case.
- To determine which bank is being pointed to, consider the type of metasprite this is:
- Bits 0x0E-12: The ROM bank containing the metasprite's tile patterns.
- Bits 0x13-16: The number of tile patterns used by this metasprite is this value * 2.
- Bits 0x17-1F:
- The address of the metasprite's tile patterns can be derived from this value like so:
base = ? (see below) address = base + value*0x20
- If the metasprite in question is a player character metasprite, then base has a value of 0x4000. Otherwise, the value of base can be determined by looking at the map's MapInfo.
MetaspriteLayout Structure
Describes the metasprite-relative locations of the sprites that compose a metasprite.
- 0x00: The number of items in the following list is this value / 4.
- 0x01+: A list of SignedPoints that describe metasprite-relative offsets for each sprite that composes the metasprite.
This structure must never cross a 0x100 byte page boundary.
SignedPoint Structure
- 0x0: y coordinate (signed)
- 0x1: x coordinate (signed)
Drawing Metasprites
- Each sprite forming a metasprite is drawn relative to the metasprite based on an offset from in the metasprite's MetaspriteLayout structure. An additional offset of (-8,-16) is added as well.
- Note that, unlike in Donkey Kong Land 2 and Donkey Kong Land III, the sprite offsets in the MetaspriteLayout structure aren't cumulative.
- Only 8 x 16 sprites are used when drawing metasprites.
- Tile pattern indices increase by 2 for every consecutively drawn sprite.
- Sprite palette 0 is used for most metasprites. Some objects, such as OBJ_VINE, use sprite palette 1 instead.
- When flipping the metasprite horizontally, negate the x offset from the MetaspriteLayout structure before adding it. Additionally, the metasprite should be drawn 8 pixels to the left.
Bananas
Unlike in Donkey Kong Land 2 and Donkey Kong Land III, banana layout data is stored separately from other layout data. Up to 0x80 bananas may be placed per map.
See also: Map Bananas
BananaLayout Structure
- A list containing BananaGroupPlacement and DummyBananaPlacement structures. It's terminated by the 16-bit value 0.
BananaGroupPlacement Structure
This structure defines zero or more group-relative banana placements.
- 0x00-01:
- Bit 0x0: Must be 0.
- Bits 0x1-C: The group's x coordinate is this value * 2.
- Bits 0xD-F: The most significant byte of the group's y coordinate*.
- 0x02: The least significant byte of the group's y coordinate*.
- 0x03+: A list of BananaGroupMember structures. It's terminated with the 8-bit value 0.
* The group's y coordinate should get multiplied by 4.
BananaGroupMember Structure
- 0x00: Must not be 0.
- Bits 0-3*: The banana's group-relative y coordinate is this value * 8.
- Bits 4-7*: The banana's group-relative x coordinate is this value * 8.
- * Subtract 1 from the byte's value before extracting these bits.
DummyBananaPlacement Structure
This structure describes the placement of a special kind of banana whose x coordinate is always set to 0xFF00. They are probably used to partition regular bananas.
- 0x00-01:
- Bit 0x0: Must be 1.
- Bits 0x1-F: The banana's y coordinate.
Drawing Bananas
- The 8 tile patterns for the banana animation can be found in data set 0x58. They get loaded to 0x8780-87FF in VRAM (tile pattern indices 0x78-7F).
- Each banana is drawn using a single 8 x 16 sprite.
- The tile pattern used and whether x flipping is enabled depends on the animation frame.
- Sprite palette 0 is always used.
- Bananas are drawn offset from their actual locations by (-12,-24) pixels.
Characters
Character States
0x16792: A list of 16-bit pointers to MetaspriteSet structures in ROM bank 5 that determine the default MetaspriteSet for each of Donkey Kong's character states. It's indexed using a character state ID.
- Some of the items in this list seem to point to invalid data— possibly because some character states are incompatible with Donkey Kong.
0x161CC: A list of 16-bit pointers to MetaspriteSet structures in ROM bank 5 that determine the default MetaspriteSet for each of Diddy Kong's character states. It's indexed using a character state ID.
- Some of the items in this list seem to point to invalid data— possibly because some character states are incompatible with Diddy Kong.
Character State IDs
... 0x15: File select menu cursor 0x16: Riding Expresso 0x17: Riding Rambi ... 0x1E: Finishing a level 0x1F: Spawning at a checkpoint ... 0x21: Switching characters 0x22: Swimming ... 0x25: Dying 0x26: Crouching 0x27: Rolling 0x28: Standing / walking / running 0x29: Jumping ...?
Data Sets
Data sets are used to load related data all at once.
0x31C4E: A list of DataSet structures. It's indexed using a data set ID.
0x31D58: A list of UncompressedDataTransfer structures. It's indexed using an uncompressed data transfer ID + 1.
0x1C001: A list of CompressedDataTransfer structures. It's indexed using a compressed data transfer ID.
See also: Map Data Sets
DataSet Structure
Describes a list of data transfers to execute.
- 0x00+: A list of DataTransferReference structures. It is terminated by the 8-bit value 0xFF.
DataTransferReference Structure
Describes a data transfer to execute.
- Bits 0-6: A compressed or uncompressed data transfer ID (see below).
- Bit 7: Whether the data transfer ID above is a compressed or uncompressed data transfer ID.
- Possible values:
- 0: Compressed
- 1: Uncompressed
- Possible values:
UncompressedDataTransfer Structure
Describes where uncompressed data is located and where to copy it to.
- 0x00: The size of the source data, in bytes, is this value * 0x10. If this value is 0, then its uncompressed size is 0x1000 bytes instead.
- 0x01-02: Source address (big endian). The source ROM bank is always 0xC.
- 0x03-04: Destination address (big endian).
CompressedDataTransfer Structure
Describes where compressed data is located and where to decompress it to.
- 0x00: Compression format / uncompressed size
- Possible values:
- 0x00: Indicates that the source data is compressed using the RLE derivative. Its uncompressed size is not specified.
- 0x01+: Indicates that the source is compressed using the Huffman coding derivative. Its uncompressed size, in bytes, is this value * 0x10.
- Possible values:
- 0x01-02: Source address
- The address of the compressed data to decompress.
- 0x03-04:
- Bits 0-3: Source ROM bank
- The ROM bank containing the compressed source data. If this is 0, then 0x12 gets used instead.
- Bits 4-F: Destination address
- The address to decompress the source data to is this value * 0x10.
Data Set IDs
- 0x00-49: The primary data set for the map with the same ID. It usually loads graphics and a metatile collision map.
- ...
- 0x58: Loads tile patterns for bananas and hearts.
- ...?
Tile Animations
The tile animation that plays depends on the current map's map theme ID.
0x1C181: A list of TileTransfer structures that are used for tile animations. It's indexed using a tile transfer ID.
TileTransfer Structure
Describes where tile patterns are located and where to copy them to.
- 0x00-01:
- Bits 0-3: Source ROM bank
- The ROM bank containing the tile patterns to copy can be derived from this value like so:
romBank = 0x10 + max(1, value)
- Bits 4-F: Source address
- A pointer to the tile patterns to copy is this value * 0x10.
- 0x02-03: Destination address
- A pointer to where to copy the tile patterns to.
- 0x04: Tile pattern count
- The number of tile patterns to copy.
Map Theme Tile Animations
Maps with these map theme IDs play tile animations:
- 0x02: Animates torch flames by loading tile transfer IDs 0x00-03 in sequence.
- 0x08: Animates a background of scrolling blocks. The logic involved in doing so is more complicated than for other tile animations.
- 0x0A: Animates arrow paths by loading tile transfer IDs 0x08-0B in sequence.
- 0x0B: Animates conveyor ropes by loading tile transfer IDs 0x0C-0F in sequence.
Tile Transfer IDs
- 0x00-03: Torch flame animation
- ...
- 0x08-0B: Arrow path animation
- 0x0C-0F: Conveyor rope animation
- ...?
Hidden Ropes
There are 8 hidden ropes in the game. They can be revealed by stomping on weak terrain found at various locales. Doing so will reveal a hole that the hidden rope then rises from. Climbing the hidden rope will warp the player character to a bonus map.
Hidden ropes are spawned programmatically and behave a little differently from regularly-spawned ropes:
- They don't have configuration data.
- The rope's type is set to Hidden, but their target length gets overwritten with 0x60.
0xBB0F: A list of HiddenRopeInfo structures. It's indexed using a hidden rope ID.
See also: Map Hidden Ropes
HiddenRopeInfo Structure
- 0x00-01: x
- The hidden rope's x coordinate.
- 0x02-03: y
- The hidden rope's y coordinate
- 0x04: Destination
- The ID of the bonus map that the hidden rope leads to. It must be a bonus map.
- 0x05-09: Return point
- A SpawnInfo structure describing where to return to after exiting the bonus map.
Hidden Rope IDs
- 0x00: The hidden rope used by map 0x09.
- 0x01: The hidden rope used by map 0x05.
- 0x02: The hidden rope used by map 0x0D.
- 0x03: The hidden rope used by map 0x13.
- 0x04: The hidden rope used by map 0x1C.
- 0x05: The hidden rope used by map 0x0F.
- 0x06: The hidden rope used by map 0x19.
- 0x07: The hidden rope used by map 0x01.
Hidden Caves
There are 3 hidden caves in the game disguised as regular stone walls. They become revealed when their entrances are touched by either Rambi or a rolling metallic barrel.
The way this works is that each map with a hidden cave is assigned a MapPatchHotspotSet. A MapPatchHotspot from the set gets triggered if either Rambi or a rolling metallic barrel enter its hotspot area.
Linking caves to other areas isn't done in any special way. Instead, it is done by using warp point objects.
See also: Map Hidden Caves
MapPatchHotspotSet Structure
A set of MapPatchHotspot structures.
- 0x00-01: A 16-bit pointer to the same ROM bank. Pointed to is the next item in the set or the 16-bit value 0 if there is no next item.
- Following that is a MapPatchHotspot structure that is part of the set. There is always at least one item in the set.
See also: MapPatchHotspot
MapPatchHotspot Structure
Describes a map patch and the area in which it can be triggered.
- 0x00: ID
- An ID that's used to check whether the patch has been applied.
- 0x01-02: x
- The x coordinate of the hotspot area.
- 0x03: Width
- The width of the hotspot area (extends rightward).
- 0x04-05: y
- The y coordinate of the hotspot area.
- 0x06: Height
- The height of the hotspot area (extends downward).
- Following that is a 1-byte list length* followed by a list of ByteTransfer structures to execute when the hotspot is triggered. They are used primarily to update the metatile map.
- Following that is 1-byte list length* followed by a list of MetatileDrawInfo structures to draw when the hotspot is triggered. They are used to make changes to the metatile map visible immediately. Keep in mind that, since the metatiles are drawn at absolute locations, the camera must be at a very specific location for it to work properly.
* A list length of 0 gets interpreted as 0x100.
See also: MapPatchHotspotSet, ByteTransfer, MetatileDrawInfo
ByteTransfer Structure
Describes an 8-bit value and where it should be written to. To execute a ByteTransfer, write its value to its destination.
- 0x00-01: Destination
- The address to write to the value to.
- 0x02: Value
- The value to write to the destination.
MetatileDrawInfo Structure
Describes where to draw a metatile on a VRAM tile map.
- 0x00: The ID of the metatile to draw.
- 0x01-02: A pointer to a tile of a VRAM tile map where the top-left corner of the metatile will be drawn.
Compression
Donkey Kong Land uses several different compression schemes— most of which are also used by its sequels Donkey Kong Land 2 and Donkey Kong Land III.
LZ Derivative
The metatile maps are compressed using the same LZ derivative found in Donkey Kong Land 2 and Donkey Kong Land III.
Format
- Four bits (a half of a byte, or one nibble) are read at a time. If the game finds the following hexadecimal sequences: BE, BF, C, D, E, or F, it is treated as separate compression cases. If it finds any other type of 8-bit hexadecimal sequence, it is treated as an uncompressed byte.
- Case BE:
- Format: BE xx y
- xx: Initial tile, increased by 0x01 each time
- y: Length-3. Resulting length can range from 0x3 to 0x12.
- Examples:
- BE 00 3 -- Initial tile is 00, and length is 3+3=6. The resulting decompressed data: 00 01 02 03 04 05.
- BE 48 F -- Initial tile is 48, and length is 3+F=12. The resulting decompressed data: 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59.
- Format: BE xx y
- Case BF:
- Format: BF xx yy z
- xx yy: Two tiles (useful for repeated 64x32-pixel structures)
- z: Length-2. Resulting length can range from 0x2 to 0x11.
- Examples:
- BF 30 31 5 -- Tiles are 30 31, and length is 5+2=7. The resulting decompressed data: 30 31 30 31 30 31 30 31 30 31 30 31 30 31.
- BF 24 29 9 -- Tiles are 24 29, and length is 9+2=B. The resulting decompressed data: 24 29 24 29 24 29 24 29 24 29 24 29 24 29 24 29 24 29 24 29 24 29.
- Format: BF xx yy z
- Case C:
- Format:
- C xx y F zz (if xx is odd)
- Copies a previously written area in RAM -- it reads int(xx/2) + y*0x80 bytes backwards.
- zz: Length-4. Resulting length can range from 0x4 to 0x103.
- C xx y z (if xx is odd and z < F)
- Copies a previously written area in RAM -- it reads int(xx/2) + y*0x80 bytes backwards.
- z: Length-4. Resulting length can range from 0x4 to 0x12.
- C xx F yy (if xx is even)
- Copies a previously written area in RAM -- it reads int(xx/2) bytes backwards.
- yy: Length-4. Resulting length can range from 0x4 to 0x103.
- C xx y (if xx is even and y < F)
- Copies a previously written area in RAM -- it reads int(xx/2) bytes backwards.
- y: Length-4. Resulting length can range from 0x4 to 0x12.
- Examples:
- C 41 2 3 -- Suppose the current RAM address to be written to is 0xCF00. We must subtract this by int(41/2) + 2*80 = 120 to get 0xCDE0. Length is 3+4=7, so data from 0xCDE0 to 0xCDE6 must be read, and copied into 0xCF00 to 0xCF06. Suppose the data starting at 0xCDE0 contains: 10 11 12 13 28 29 40. Therefore, the data at 0xCF00 to 0xCF06 will also contain this same data: 10 11 12 13 28 29 40.
- C 41 2 F 13 -- Suppose the current RAM address to be written to is 0xCF00. We must subtract this by int(41/2) + 2*80 = 120 to get 0xCDE0. Length is 13+4=17, so data from 0xCDE0 to 0xCDF6 must be read, and copied into 0xCF00 to 0xCF16. Suppose the data starting at 0xCDE0 contains: 10 11 12 13 28 29 40 50 50 50 50 50 50 50 50 50 40 40 40 40 40 40 40 40. Therefore, the data at 0xCF00 to 0xCF06 will also contain this same data: 10 11 12 13 28 29 40 50 50 50 50 50 50 50 50 50 40 40 40 40 40 40 40 40.
- C 40 3 -- Suppose the current RAM address to be written to is 0xCF00. We must subtract this by int(40/2) = 20 to get 0xCEE0. Length is 3+4=7, so data from 0xCEE0 to 0xCEE6 must be read, and copied into 0xCF00 to 0xCF06. Suppose the data starting at 0xCEE0 contains: 10 11 12 13 28 29 40. Therefore, the data at 0xCF00 to 0xCF06 will also contain this same data: 10 11 12 13 28 29 40.
- C 40 F 13 -- Suppose the current RAM address to be written to is 0xCF00. We must subtract this by int(40/2) = 20 to get 0xCEE0. Length is 13+4=17, so data from 0xCEE0 to 0xCEF6 must be read, and copied into 0xCF00 to 0xCF16. Suppose the data starting at 0xCEE0 contains: 10 11 12 13 28 29 40 50 50 50 50 50 50 50 50 50 40 40 40 40 40 40 40 40. Therefore, the data at 0xCF00 to 0xCF06 will also contain this same data: 10 11 12 13 28 29 40 50 50 50 50 50 50 50 50 50 40 40 40 40 40 40 40 40.
- C xx y F zz (if xx is odd)
- Format:
- Case D:
- Format: D x yy z...
- x: Constant high nibble
- yy: Length-0x14. Resulting length can range from 0x14 to 0x113.
- z: Depending on the length, the game then reads 4-bit sequences, and this ends up being the low nibble.
- Example:
- D 5 0C -- 5 is the upper nibble. Length is 0x0C+0x14=0x20. 0x20 4-bit sequences will be read. Suppose the data here contains: 01 23 45 67 89 AB CD EF 00 44 88 CC 76 54 32 10. These are all low nibbles, so the resulting decompressed data will be: 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 50 50 54 54 58 58 5C 5C 57 56 55 54 53 52 51 50.
- Format: D x yy z...
- Case E:
- Format:
- E E
- End map decompression sequence!
- E x y z... (if x != E)
- x: Constant high nibble
- y: Length-0x4. Resulting length can range from 0x4 to 0x13. This is the difference between cases D and E.
- z: Depending on the length, the game then reads 4-bit sequences, and this ends up being the low nibble.
- Example:
- E 5 C -- 5 is the upper nibble. Length is 0xC+0x4=0x10. 0x10 4-bit sequences will be read. Suppose the data here contains: 01 23 45 67 00 88 32 10. These are all low nibbles, so the resulting decompressed data will be: 50 51 52 53 54 55 56 57 50 50 58 58 53 52 51 50.
- E E
- Format:
- Case F:
- Format:
- F xx y z (if y >= 8)
- xx: Tile
- Length: (y mod 8) * 0x10 + z + 0xB. Resulting length can range from 0xB to 0x8A.
- F xx y (if y < 8)
- xx: Tile
- Length: y+3. Resulting length can range from 0x3 to 0xA.
- Examples:
- F 48 5 -- Tile is 48, and length is 5+3=8. The resulting decompressed data: 48 48 48 48 48 48 48 48.
- F 48 D 2 -- Tile is 48, and length is (D mod 8)*0x10+2+B = 0x5D. The resulting decompressed data: 48 being repeated 0x5D times.
- F xx y z (if y >= 8)
- Format:
Decompressor
A decompressor, implemented in Python 2.7.9:
""" Decompresses data compressed using the LZ derivative. @param input - A stream of compressed data. @return The uncompressed data. """ def decompress(stream): bitReader = BitReader(stream) output = bytearray() while True: nibble = bitReader.readNibble() if nibble == 0xC: # C xx F yy where xx is even - Write yy+4 bytes from ((int)xx)/2+1 bytes earlier # C xx y F zz where xx is odd - Write zz+4 bytes from ((int)(xx+y*0x100))/2+1 bytes earlier # C xx y where xx is even - Write y+4 bytes from ((int)xx)/2+1 bytes earlier # C xx y z where xx is odd - Write z+4 bytes from ((int)(xx+y*0x100))/2+1 bytes earlier distance = bitReader.readByte() if distance % 2 == 1: # Distance is odd. distance += bitReader.readNibble() * 0x100 distance = distance//2 + 1 length = bitReader.readNibble() if length == 0xF: length = bitReader.readByte() length += 4 def reiterate(length, distance): source = len(output) - distance for i in range(length): output.append(output[source + i]) reiterate(length, distance) elif nibble == 0xD: # D x yy z[...] - Write xz[i] yy+0x14 times constantHighNibble = bitReader.readNibble() << 4 length = bitReader.readByte() + 0x14 for i in range(length): output.append(constantHighNibble | bitReader.readNibble()) elif nibble == 0xE: nibble = bitReader.readNibble() if nibble == 0xE: # EE - End of stream break # E x y z[...] - Write xz[i] y+4 times constantHighNibble = nibble << 4 length = bitReader.readNibble() + 4 for i in range(length): output.append(constantHighNibble | bitReader.readNibble()) elif nibble == 0xF: value = bitReader.readByte() length = bitReader.readNibble() if length >= 0x8: # F xx y z where y >= 8 - Write xx n times where n = (y % 8) * 0x10 + z + 0xB length = (length % 8) * 0x10 + bitReader.readNibble() + 0xB else: # F xx y where y < 8 - Write xx y+3 times length += 3 for i in range(length): output.append(value) else: byte = (nibble << 4) | bitReader.readNibble() if byte == 0xBE: # BE xx y - Write xx+i y+3 times value = bitReader.readByte() length = bitReader.readNibble() + 3 for i in range(length): output.append((value+i) & 0xFF) elif byte == 0xBF: # BF xxxx y - Write xxxx y+2 times byte0 = bitReader.readByte() byte1 = bitReader.readByte() length = bitReader.readNibble() + 2 for i in range(length): output.append(byte0) output.append(byte1) else: # xx - Write xx output.append(byte) return output class BitReader: def __init__(self, stream): self.stream = stream self.currentByte = 0 self.bitPosition = 7 def readBit(self): if self.bitPosition == 7: self.currentByte, = unpack("<B", self.stream) result = getBit(self.bitPosition, self.currentByte) self.bitPosition -= 1 if self.bitPosition == -1: self.bitPosition = 7 return result def readBits(self, bitCount): result = 0 for i in range(bitCount): result <<= 1 result |= self.readBit() return result def readByte(self): return self.readBits(8) def readNibble(self): return self.readBits(4) def getBit(b, n): if b < 0: raise Exception("b must be positive.") return (n >> b) & 1 def unpack(fmt, file): import struct return struct.unpack(fmt, buffer(file.read(struct.calcsize(fmt))))
Huffman Coding Derivative
Most background graphics are compressed using the same Huffman coding derivative found in Donkey Kong Land 2, Donkey Kong Land III, Battletoads (Game Boy), Battletoads in Ragnarok's World, and Battletoads/Double Dragon (Game Boy).
The game's decompressor for this format has a special behavior depending on where data is being decompressed to. After each decompressed byte is written, the game checks whether the destination address is in the range 0x9800-98FF and, if so, subtracts 0x1000 from it— effectively making the destination address wrap around when it is in the range 0x8800-97FF. This behavior allows compressed tile graphics that were originally in unsigned order to be decompressed to VRAM in signed order.
Format
Data compressed in this way takes the form of a bitstream of variable-bit-length code words. Each code word describes a path through a binary tree which starts at branch 0xFE and ends at a leaf node. Each leaf node has an associated literal which gets written to the output. Once enough bytes have been written, the decompression stops.
- A bitstream value of 0 indicates that a left turn should be made.
- A bitstream value of 1 indicates that a right turn should be made.
- The bitstream is read starting from the most significant bit of every byte.
The binary tree is split into three tables:
- 0x3D00-3DFF: Table LT
- Contains 8-bit values for the left-side nodes in the binary tree. It's indexed using a branch ID.
- 0x3E00-3EFF: Table RT
- Contains 8-bit values for the right-side nodes in the binary tree. It's indexed using a branch ID.
- 0x3F00-3FFF: Table TT
- Contains 8-bit values describing the type of each node in tables LT and RT. It's indexed using a branch ID.
- Each byte follows this format:
- Bits 0-2: Unused
- Bit 3: The type of the node in table LT with the same branch ID.
- Bits 4-6: Unused
- Bit 7: The type of the node in table RT with the same branch ID.
- Node types:
- 0: A leaf node whose value is a literal
- 1: A branch node whose value is the branch ID of its children
- Node types:
The same binary tree is shared by all data compressed in this way.
Decompressor
A decompressor, implemented in Python 2.7.9:
""" Decompresses data compressed using the Huffman derivative. @param tables - A tuple containing the 3 decompression tables (left, right, and type). @param uncompressedSize - The size of the uncompressed data. @param input - A stream of compressed data. @return The uncompressed data. """ def decompress(tables, uncompressedSize, input): bitReader = BitReader(input) output = bytearray() leftTable, rightTable, typeTable = tables # The ID of the binary tree's root branch. ROOT_BRANCH_ID = 0xFE currentBranchId = ROOT_BRANCH_ID while len(output) < uncompressedSize: if bitReader.readBit() == 0: # Take a left branch. nodeValue = leftTable[currentBranchId] nodeType = getBit(3, typeTable[currentBranchId]) else: # Take a right branch. nodeValue = rightTable[currentBranchId] nodeType = getBit(7, typeTable[currentBranchId]) if nodeType == NodeType.LEAF: # Write the leaf's value to the output and start over from the root branch. output.append(nodeValue) currentBranchId = ROOT_BRANCH_ID elif nodeType == NodeType.BRANCH: # Follow the branch. currentBranchId = nodeValue else: raise Exception("Unknown node type.") return output class NodeType: LEAF = 0 BRANCH = 1 class BitReader: def __init__(self, stream): self.stream = stream self.currentByte = 0 self.bitPosition = 7 def readBit(self): if self.bitPosition == 7: self.currentByte, = unpack("<B", self.stream) result = getBit(self.bitPosition, self.currentByte) self.bitPosition -= 1 if self.bitPosition == -1: self.bitPosition = 7 return result def getBit(b, n): if b < 0: raise Exception("b must be positive.") return (n >> b) & 1 def unpack(fmt, file): import struct return struct.unpack(fmt, buffer(file.read(struct.calcsize(fmt))))
RLE Derivative
Metatile collision maps and some sprite graphics are compressed using an RLE derivative.
Format
Data compressed in this way takes the form of a 2-byte header followed by a byte stream of literal values and sentinel value + run length pairs. When a sentinel value is encountered, a number of zero bytes are written to the output based on the run length. This makes it suitable for compressing data with many continuous zeroes.
Note that a run length of 0x00 is interpreted as 0x100.
Header
- 0x00: The sentinel value
- 0x01: The number of compressed blocks that follow. Each uncompressed block is 0x10 bytes.
- 0x02+: A stream of compressed data
Decompressor
A decompressor, implemented in Python 2.7.9:
""" Decompresses data compressed using the RLE derivative. @param input - A stream containing the compressed data. @return The uncompressed data. """ def decompress(input): output = bytearray() # Read the header. sentinelValue, blockCount = unpack("<BB", input) # The size of an uncompressed block, in bytes. BLOCK_SIZE = 0x10 # The size of the uncompressed data, in bytes. uncompressedSize = blockCount * BLOCK_SIZE while len(output) < uncompressedSize: value, = unpack("<B", input) if value == sentinelValue: runLength, = unpack("<B", input) if runLength == 0: runLength = 0x100 for i in range(runLength): output.append(0) else: output.append(value) return output def unpack(fmt, file): import struct return struct.unpack(fmt, buffer(file.read(struct.calcsize(fmt))))
Miscellaneous
Information that doesn't fit anywhere else goes here.
SpawnInfo Structure
Describes where and how to spawn a character.
- 0x00-01: x
- 0x02-03: y
- 0x04:
- Bits 0-6: Character state ID
- Bit 7: Direction
Internal Data for Donkey Kong Land
| |
---|---|