Motocross Maniacs/Notes

From Data Crystal
< Motocross Maniacs
Revision as of 15:01, 9 June 2023 by NES Boy (talk | contribs) (NES Boy moved page Motocross Maniacs to Motocross Maniacs:Notes: More appropriate location for the page.)
Jump to navigation Jump to search
Motocross Maniacs
Internal Name "MOTOCROSSMANIAC"
Region Code x01 (non-Japanese)
Type Grayscale Game
SGB Support x00 (not SGB)
Cartridge Type ROM
License Code x0000 (new license)
ROM Size x00 (32 KiB)
ROM Checksum x4EEF
SRAM Size xxx
Header Checksum x57

The goal of these notes is to provide enough elements for someone to hopefully write a basic level editor.

This Konami classic is a tiny ROM that only contains 2 banks. And no bank switching = less headaches for disassembly!

Course data

General idea

Courses 1 to 8 are simply sequences of course objects, such as ramps, bumps, etc.
These course objects are placed one after the other, from left to right.
Below is the beginning of course 1: floor, small triangular ramp, floor, etc.
 Motocross Maniacs ScreenData.png
Each course has two laps, both identical, so only lap 1 requires definition.
A course object is an array of metatiles, where each metatile is 16x16px (each metatile is a 2x2 array of regular 8x8px tiles).
Below is a small triangular ramp object: it's made of 4 metatiles (each in a different color), and each metatile is made of 4 tiles.
 Motocross Maniacs TriangularRamp.png

Course data

Course data structure

In the ROM data, a course is defined by a sequence of 3-byte words YY XX ZZ:
 * YY XX = coordinates (from top left) of the upper-lefthand corner of the object. Units are in metatiles (= 2 tiles).
 * ZZ = objectID
Below is a sample of course 1, with 3-byte words highlighted.
 Motocross Maniacs Level1Data.png
 * First object = floor (ID=x00), located at (x0F,x00).
 * Second object = small triangular ramp (ID=x01), located at (x0E,x0A).
The length of the lap of a course is bounded by xFF.

Course data location in ROM

* 0x4760-0x476F - table of 8 pointers to the 8 courses
* 0x4770-0x4908 - course 1 data
* 0x4909-0x4AE3 - course 2 data
* 0x4AE4-0x4C8E - course 3 data
* 0x4C8F-0x4E9C - course 4 data
* 0x4E9D-0x5062 - course 5 data
* 0x5063-0x52A0 - course 6 data
* 0x52A1-0x54C0 - course 7 data
* 0x54C1-0x56CB - course 8 data

Each chunk of course data ends with xFF.

Course object data

Course object data structure

In the ROM data, a course object is defined by an array of metatiles XX YY AA BB....
 * XX YY define the array's dimensions: XX rows and YY columns.
 * AA BB... are the metatileIDs that will fill the array, one line at a time.
Course 1 contains x87 (=103) course objects. Below are the first two: a floor object, followed by a small triangular ramp object.
  Motocross Maniacs ObjectDefinition.png
  * The floor object is a row of x0A metatiles with ID x09.
  * The small triangular ramp object is a 2x2 array of metatiles x0A, x0B, xC and x0D.
Note that the sequence of course objects does not need to be ordered. The game constantly reads through the entire sequence to determine which objects to place next.

Course object data location in ROM

* x56CC-x5793 - table of pointers to course object definitions
* x5794-x579F - object x00 (floor)
* x57A0-x57A5 - object x01 (small triangular ramp)
* ...
* x5A19-x5A1E - object x63 (short circular ramp up)

Course objects

The table of pointers to course object definitions contains x63 pointers, but several objects have multiple IDs.

Certain course objects with different IDs appear very similar, but they are often translated by 1 tile, the reason being that these objects are positioned on a metatile grid, and can only be moved around in multiples of 2 tiles.

ID name dimensions screen cap
x00 long floor (x01,x0A) Motocross Maniacs CourseObject00-floor.png
x01 small triangular ramp with floor (x02,x02) Motocross Maniacs CourseObject01-smallTriangularRamp.png
x02 ramp up with floor (x03,x03) Motocross Maniacs CourseObject02-longRampLeft.png
x03 sandbox left (x01,x03) Motocross Maniacs CourseObject03-sandboxLeft.png
x04 sandbox right (x01,x03) Motocross Maniacs CourseObject04-sandboxRight.png
x05 to x08 circular ramp up with floor (x03,x04) Motocross Maniacs CourseObject05-circularRampLeft.png
x09 short floor (x01,x03) Motocross Maniacs CourseObject09-shortFloor.png
x0A sandbox middle (x01,x04) Motocross Maniacs CourseObject0A-sandboxMiddle.png
x0B circular ramp bottom (x03,x06) Motocross Maniacs CourseObject0B-circularRampBottom.png
x0C ramp up 1 (x03,x03) Motocross Maniacs CourseObjects0C-rampUpLeft.png
x0D floor with flanking ramps (x01,x04) Motocross Maniacs courseObjects0D-floorWithRamps.png
x0E ramp down 1 (x03,x03) Motocross Maniacs courseObject0E-rampDownRight.png
x0F ramp down with floor (x03,x03) Motocross Maniacs courseObject0F-rampDownRight.png
x10 speed bump with floor (x01,x01) Motocross Maniacs Object10-speedBump.png
x11 looping ramp top left (x04,x04) Motocross Maniacs Object11-circularRampInvertedTopLeft.png
x12 looping ramp bottom left (x04,x04) Motocross Maniacs Object12-circularRampBottomLeft.png
x13 looping ramp top right (x04,x04) Motocross Maniacs Object13-circularRampTopRight.png
x14 looping ramp bottom right (x04,x04) Motocross Maniacs Object14-circularRampBottomRight.png
x15 floor with flanking ramp up (x01,x03) Motocross Maniacs Object15-floorWithFlankingLeftRamp.png
x16 and x17 horizontal ramp (x01,x03) Motocross Maniacs Object16-horizontalRamp.png
x18 ramp angle up 1 (x02,x02) Motocross Maniacs Object18-rampAngleUpRight.png
x19 blank square 1 (4 metatiles x08) (x02,x02) Motocross Maniacs Object19-blankSquare.png
x1A blank square 2 (2 metatiles x08 and 2 x6B) (x02,x02) Motocross Maniacs Object19-blankSquare.png
x1B long ramp up (x04,x04) Motocross Maniacs Object1B-longRampUpLeft.png
x1C medium floor (x01,x04) Motocross Maniacs Object1C-mediumFloor.png
x1D small ramp up with floor (x02,x02) Motocross Maniacs Object1D-smallRampUpLeftWithFloor.png
x1E ramp up with platform 1 (x02,x04) Motocross Maniacs Object1E-rampUpLeftWithPlatform.png
x1F small triangular ramp (x01,x02) Motocross Maniacs Object1F-smallTriangularRamp.png
x20 ramp down 2 (x03,x03) Motocross Maniacs Object20-longRampDown.png
x21 floor with flanking ramp up 2 (x01,x03) Motocross Maniacs Object21-floorWithFlankingRampUp.png
x22 floor with flanking ramp up 2 (x01,x03) Motocross Maniacs Object22-floorWithFlankingRampDown.png
x23 tiny bump (x01,x01) Motocross Maniacs Object23-tinyBump.png
x24 ramp angle up 2 (x02,x01) Motocross Maniacs Object24-rampAngle.png
x25 ramp down (x02,x02) Motocross Maniacs Object25-rampDown.png
x26 ramp up (x02,x02) Motocross Maniacs Object26-rampUp.png
x27 ramp angle down 2 (x02,x01) Motocross Maniacs Object27-rampAngle.png
x28 ramp angle down 3 (x01,x02) Motocross Maniacs Object28-rampAngleDown.png
x29 small looping ramp top left (x03,x03) Motocross Maniacs Object29-SmallCircularRampInvertedTopLeft.png
x2A small looping ramp bottom left (x03,x03) Motocross Maniacs Object2A-SmallCircularRampBottomLeft.png
x2B small looping ramp top right (x03,x03) Motocross Maniacs Object2B-SmallCircularRampTopRightt.png
x2C small looping ramp bottom right (x03,x03) Motocross Maniacs Object2C-SmallCircularRampBottomRight.png
x2D small ramp down with floor (x02,x02) Motocross Maniacs Object2D-rampDownWithFloor.png
x2E sand and floor above (x01,x03) Motocross Maniacs Object2E-sandAndFloor.png
x2F long ramp down (x04,x04) Motocross Maniacs Object2F-longRampDown.png
x30 floor with flanking ramp up (similar to x21) (x01,x03) Motocross Maniacs object30-floorWithFlankingRampUp.png
x31 and x32 vertical circular ramp right (x04,x02) Motocross Maniacs Object31-verticalCircularRamp2.png
x33 floor platform with tiny ramp above sandbox (x02,x03) Motocross Maniacs object33-floorWithTinyRampOverSandbox.png
x34 long sandbox with floor above (x01,x06) Motocross Maniacs Object34longSandboxWithFloorAbove.png
x35 floor platform with tiny ramp 1 (x02,x04) Motocross Maniacs Object35-thickFloorWithSmallBump.png
x36 floor platform with tiny ramp 2 (x02,x04) Motocross Maniacs Object36-mediumThickFloorWithSmallBump.png
x37 and x38 short ramp down (x02,x04) Motocross Maniacs Object37-shortRampDown.png
x39 vertical circular ramp left (x04,x02) Motocross Maniacs Object39-verticalCircularRampLeft.png
x3A long sandbox (x01,x0A) Motocross Maniacs object3A-longSandbox.png
x3B ramp angle up 3 (similar to x18) (x02,x02) Motocross Maniacs Object3B-rampAngleUp.png
x3C ramp angle up to platform (x01,x02) Motocross Maniacs Object3C-rampAngleUpToTop.png
x3D ramp angle down from platform (x01,x02) Motocross Maniacs Object3D-rampAngleDownToPlatform.png
x3E short ramp up (x02,x02) Motocross Maniacs Object3E-shortRampUp.png
x3F circular ramp up to platform with floor (x02,x03) Motocross Maniacs Object3F-circularRampUpWithFloorAndPlatform.png
x40 and x41 ramp angle going up (x02,x02) Motocross Maniacs Object40-rampAngleGoingUp.png
x42 circular ramp down with floor (x02,x05) Motocross Maniacs Object42-circularRampDownWithFloor.png
x43 vertical ramp (x02,x01) Motocross Maniacs Object43-verticalRamp.png
x44 and x45 floor with small rock obstacle (x01,x01) Motocross Maniacs Object44-floorWithSmallRockObstacle.png
x46 to x48 short horizontal ramp (x01,x02) Motocross Maniacs Object46-shortHorizontalRamp.png
x49 and x4A ramp up (x02,x04) Motocross Maniacs Object49-rampUp.png
x4B ramp up with platform 2 (x02,x05) Motocross Maniacs object4B-rampUpWithPlatform2.png
x4C finish line ramp top (x01,x02) Motocross Maniacs Object4C-FinishLineRampTop.png
x4D ramp up (x03,x03) Motocross Maniacs object4D-rampUp.png
x4E and x4F single looping road sign (x04,x02) Motocross Maniacs object4E-singleLoopingRoadSign.png
x50 "Go!" road sign with floor (x04,x02) Motocross Maniacs Object50-GoRoadSign.png
x51 "Go!" road sign with sandbox (x04,x02) Motocross Maniacs object51-goRoadSignWithSandbox.png
x52 road sign with up arrow (x04,x02) Motocross Maniacs Object52-roadSignUpArrow.png
x53 road sign with down arrow (x04,x02) Motocross Maniacs object53-roadSignDownArrow.png
x54 horizontal double looping road sign (x03,x03) Motocross Maniacs Object54-doubleLoopRoadSignWithFloor.png
x55 vertical double looping road sign (x04,x02) Motocross Maniacs Object55-verticalDoubleLoopRoadSignWithFloor.png
x56 to x59 short floor 2 (similar to x09) (x01,x03) Motocross Maniacs Object59-floor.png
x5A to x5C floor grass (x01,x03) Motocross Maniacs Object5A-floorGrass.png
x5D to x62 small vertical ramp (x01,x01) Motocross Maniacs Object5D-SmallVerticalRamp.png
x63 short circular ramp up (x02,x02) Motocross Maniacs Object63-shortCircularRampUp.png

Metatile data

Metatile data structure

Metatiles are 16x16px, and are made of 2x2 arrays of 8x8px tiles.
They are defined with 4 consecutive bytes, the first two are the top half of the array, the last two are the lower half.
Motocross Maniacs TriangularRamp.png
The top-left metatile (in red) is defined by x7F x7F x7F x1E, where x7F is blank and x1E is a chunk of ramp.
The bottom-left metatile (in yellow) is defined by x1E x1A x8E x8E, where x1A is an inner chunk of ramp, and x8E is floor.

Metatile data location in ROM

* x5A1F-5C8E
There is a total of x9C (=156) metatiles.
Of course not all tiles are used in the metatile definitions, but certain tiles one would expect to be used are not present, namely:
 * x38 - ramp tile
 * x5B - ramp tile
 * x8C - floor tile
 * xB9 to BE - blank tiles
 * xC3 and C4 - blank tiles

Item data

Items are the various power-ups you can collect throughout a course: N for Nitrous boost, T for tires, S for speed, etc.
These items are placed on the course just like the other course objects.
Motocross Maniacs Items.png

Item data structure

In the ROM data, items are defined by 3-byte words YY XX ZZ:
* YY XX = coordinates from top left of the course
* ZZ = itemID
Possible IDs are:
* x02 = S for speed
* x03 = T for tire
* x04 = N for nitro
* x05 = R for traction
* x06 = mini-bikers hitbox (invisible)
* x07 = jet hitbox (invisible)

Item data location in ROM

Note that data for course 8 appears before data for course 7.

* x5EAB-x5F0A - table of 8 pointers to item data for each of the 8 courses
   x5F0B x5F54 x5F91 x5FBF x5FF9 x603C x60AD x6079
* x5F0B-x5F53 - course 1 item data
* x5F54-x5F90 - course 2 item data
* x5F91-x5FBE - course 3 item data
* x5FBF-x5FF8 - course 4 item data
* x5FF9-x603B - course 5 item data
* x603C-x6078 - course 6 item data
* x6079-x60AC - course 8 item data
* x60AD-x60E9 - course 7 item data
Note that each chunk of item data ends with xFF.

Course music data

A table of 8 bytes at x677C specifies which background music to play for each of the 8 courses:
 x20 x1E x1F x1D x20 x1E x1F x1D
The musicIDs are (note the IDs are not in course order):
* x20 - course 1 music (same as course 5)
* x1E - course 2 music (same as course 6)
* x1F - course 3 music (same as course 7)
* x1D - course 4 music (same as course 8)
You can also use other (short) tunes from the game as well:
* x19 - course select menu music
* x1A - victory music, but no record
* x1B - victory music, with a record
* x1C - game over music

Computer opponent AI data

When the player passes the computer opponent and pushes it offscreen, the following data is accessed. The data is a sequence of checkpoints, which are tested against the player's current coordinates until the closest position is found. The computer's coordinates are then set to the new position.

Computer opponent AI structure

(todo) Data is organized in chunks of 5 bytes:
* 2 bytes specify various checkpoints throughout the course
* 3 bytes are used to set the computer's new position in the game

Computer opponent AI data location in ROM

* x60EA-x60F9 - table of 8 pointers for offscreen computer opponent data for each of the 8 courses.
    x60FA x61AE x6230 x62A8 x633E x63D4 x644C x64E2
* x60FA-x61AD - course 1 data
* x61AE-x622F - course 2 data
* x6230-x62A7 - course 3 data
* x62A8-x633D - course 4 data
* x633E-x63D3 - course 5 data
* x63D4-x644B - course 6 data
* x644C-x64E1 - course 7 data
* x64E2-x6xxx - course 8 data (todo)

Text data

Text data structure

Below are various text elements from the game, as well as their respective ROM locations.
Text data is a sequence of words, each word structured as follows:
* 2 bytes for the display address
* a sequence of text tiles for the word
* a terminal xFE when the word is finished
* a terminal xFF when the text is finished

Text data location in ROM

Title screen

Motocross Maniacs TitleScreen.png
 * x0EC1-x0EC5 "TM" (from the Motocross Maniacs logo) at x990F
 * x0EC6-x0EDC "TM AND © 1989 KONAMI" at x9940
 * x0EDD-x0EEF "INDUSTRY CO.,LTD." at x9960
 * x0EDD-x0EEF "INDUSTRY CO.,LTD." at x9960
 * x0EF0-x0F07 "LICENSED BY NINTENDO " (yes, an extra blank tile) at x9980
 * x0F14-x0F1A "SOLO" at x99E6
 * x0F1B-x0F28 "VS COMPUTER" at x99E6
 * x0F29-x0F36 "VS 2-PLAYER" at x9A06

Game over screen

Fun fact: the game over text data is nested in the title screen text data.
* x0F08-x0F13 "GAME OVER" at x98E6

Pre-race screen

Motocross Maniacs PreRaceScreen.png
 * 0x0F37-0x0F48 "QUALIFYING TIME" at x99A3
 * 0x0F49-0x0F4F ":  :" at x99E8
 * 0x0F50-0x0F5D row of 11 gray tiles at x9865
 * 0x0F5E-0x0F6B " COURSE    " at x9885
 * 0x0F6C-0x0F79 row of 11 gray tiles at x98A5
 * 0x0F7A-0x0F8A "COURSE RECORD" at x9924
 * 0x0F8B-0x0F8F  ":  :" at x9968

Time up screen

This message doesn't contain a display address, only the text itself.
* 0x2F66-0x2F6D "TIME UP"
* 0x2F6E-0x2F75 (row of 9 gray tiles)

Gameplay data

Initial values

* x09E4 - initial Nitro (x04)

Qualifying times data

Strange: they are lower than the course records.
Qualifying times for each course require 3 bytes: XX YY ZZ, which represents a time of ZZ:YY.XX.
For example, level 1A's time is 1:20.00 and is stored as 00 20 01.
* x2DD1-x2DE8 qualifying times for level A. 
* x2DE9-x2E03 qualifying times for level B.
* x2E04-x2E1B qualifying times for level C.

Gravity data

* x2143-x214A - a table of 8 bytes that is continuously read during the game, it specifies gravity pull.
Changing all bytes to x38 creates a very slow descent for instance.

Going up ramps data

* x214B (todo)

Post-ramp boost behavior data

* x5CBF - in chunks of 4 bytes (todo)

Bike mid-air behavior data

* x5D8F - in chunks of 4 bytes (todo)

Nitro boost data

* x5E37 (todo)

Tile-related data

Tile data

Each of the 8 courses in the game uses the same tileset.
Each 8x8px tile is defined by x0F (sixteen) consecutive bytes, so each row of a tile requires 2 bytes.
If XX YY are two such bytes, the colors of the pixels of that given line are XX + 2*YY, where white = x00 / light gray = x01 / dark gray = x02 / black = x03.
For example, if the bytes of a given tile are x53 xF4 (and the rest are x00), written bitwise that's 01010011 11110100. And with the XX + 2*YY operation we get: 23230211, which gives us the following tile:
Motocross Maniacs TileExample.png
It is located just before the course data. It ends at x475F.

Tile/player collision data

During gameplay, the bike touches a series of background tiles. Each collision has a specified behavior: raise the bike (ramp), support the bike (floor), knock the bike down (ramp tile hit from the side), do nothing (blank tile), etc.
Tile/player collision data is located at x5C8F-x5D8E, and spans xFF bytes, one for each background tile. Collision data is likely bit-encoded (todo). 
Here are some examples:
* x00 - do nothing (e.g. road signs)
* x80 - regular floor tiles
* x83 - tiny speed bump
* x84 - rock
* x94 - ramp going up at 45°
* x9C - ramp going down at 45°
* xC0 - sandbox tiles

Sprite data

* x3481-x34F1 - a table of pointers for player sprite building (todo)

Music and sound FX data

This section is work in progress, still very incomplete.
* x6F1F-x6F5F - a table of pointers to music and sound FX data (todo)
 The data itself seems to be in chunks of 4 bytes.
 Pointer offsets (to be doubled) from the above pointer table lead to the following sound FX data:
  * x00 to x06 - no nitros left (various sounds)
  * x07 - pause jingle
  * x08 - motor running
  * x09 - crossing the finish line (?)
  * x0A - nitro fired
  * x0B - no nitros left click
  * x0C - N or R item pick-up
  * x0D - T item pick-up (high pitched than the previous one)
  * x0E - when a backflip adds a small biker
  * x0F - "3,2,1" countdown at the beginning of a course
  * x10 - "Go!"
  * x11 - strange ambulance siren sound (?)
  * x12 - rolling is sand
  * x13 - short selection beep (?)
  * x14 - selection beep (?)
  * x15 - motorbike falls and rolls over
  * x16 - course selected sound ("nksh!")
  * x17 - crowd roars when you win
* x7050-x706D - a table of pointers to music data for the course 1/5 song