If you are still using the old URL (datacrystal.romhacking.net), please update your bookmarks! The old URL may stop working soon.
The current URL is datacrystal.tcrf.net.
The current URL is datacrystal.tcrf.net.
Motocross Maniacs/Notes: Difference between revisions
Jump to navigation
Jump to search
(replaced: [[Image: → [[File: (87)) |
|||
(25 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
{{ | {{notes|game=Motocross Maniacs}} | ||
|game=Motocross Maniacs | |||
}} | |||
The goal of these notes is to provide enough elements for someone to hopefully write a basic level editor. | The goal of these notes is to provide enough elements for someone to hopefully write a basic level editor. | ||
Line 19: | Line 6: | ||
== Course data == | == Course data == | ||
=== General idea === | === 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. | 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. | Below is the beginning of course 1: floor, small triangular ramp, floor, etc. | ||
[[ | [[File:Motocross_Maniacs_ScreenData.png|600px]] | ||
Each course has two laps, both identical, so only lap 1 requires definition. | Each course has two laps, both identical, so only lap 1 requires definition. | ||
A | 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. | 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. | ||
[[ | [[File:Motocross_Maniacs_TriangularRamp.png|200px]] | ||
=== Course data === | === Course data === | ||
==== Course data structure ==== | ==== Course data structure ==== | ||
In the ROM data, a | 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. | Below is a sample of course 1, with 3-byte words highlighted. | ||
[[ | [[File:Motocross_Maniacs_Level1Data.png|600px]] | ||
* First object = floor (ID= | * First object = floor (ID='''x00'''), located at ('''x0F''','''x00'''). | ||
* Second object = small triangular ramp (ID= | * Second object = small triangular ramp (ID='''x01'''), located at ('''x0E''','''x0A'''). | ||
The length of the lap of a course is bounded by | The length of the lap of a course is bounded by '''xFF'''. | ||
==== Course data location in ROM ==== | ==== 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 === | ||
==== Course object data structure ==== | ==== Course object data structure ==== | ||
In the ROM data, a | 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. | |||
[[File:Motocross_Maniacs_ObjectDefinition.png|600px]] | |||
* 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 ==== | ==== 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 ==== | ==== Course objects ==== | ||
The table of pointers to course object definitions contains | 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 | 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. | ||
{| class="wikitable" style="margin:auto" style="text-align:center" | {| class="wikitable" style="margin:auto" style="text-align:center" | ||
|- | |- | ||
! ID !! name!! dimensions !! screen cap | ! ID !! name!! dimensions !! screen cap | ||
|- | |- | ||
| | | '''x00''' || long floor || '''(x01,x0A)''' || [[File:Motocross_Maniacs_CourseObject00-floor.png|300px]] | ||
|- | |- | ||
| | | '''x01''' || small triangular ramp with floor|| '''(x02,x02)''' || [[File:Motocross_Maniacs_CourseObject01-smallTriangularRamp.png |60px]] | ||
|- | |- | ||
| | | '''x02''' || ramp up with floor|| '''(x03,x03)''' || [[File:Motocross_Maniacs_CourseObject02-longRampLeft.png |90px]] | ||
|- | |- | ||
| | | '''x03''' || sandbox left || '''(x01,x03)''' || [[File:Motocross_Maniacs_CourseObject03-sandboxLeft.png |90px]] | ||
|- | |- | ||
| | | '''x04''' || sandbox right || '''(x01,x03)''' || [[File:Motocross_Maniacs_CourseObject04-sandboxRight.png |90px]] | ||
|- | |- | ||
| | | '''x05 to x08 ''' || circular ramp up with floor|| '''(x03,x04)''' || [[File:Motocross_Maniacs_CourseObject05-circularRampLeft.png |120px]] | ||
|- | |- | ||
| | | '''x09''' || short floor || '''(x01,x03)''' || [[File:Motocross_Maniacs_CourseObject09-shortFloor.png |90px]] | ||
|- | |- | ||
| | | '''x0A''' || sandbox middle || '''(x01,x04)''' || [[File:Motocross_Maniacs_CourseObject0A-sandboxMiddle.png|120px]] | ||
|- | |- | ||
| | | '''x0B''' || circular ramp bottom|| '''(x03,x06)''' || [[File:Motocross_Maniacs_CourseObject0B-circularRampBottom.png |180px]] | ||
|- | |- | ||
| | | '''x0C''' || ramp up 1 || '''(x03,x03)''' || [[File:Motocross_Maniacs_CourseObjects0C-rampUpLeft.png |90px]] | ||
|- | |- | ||
| | | '''x0D''' || floor with flanking ramps|| '''(x01,x04)''' || [[File:Motocross_Maniacs_courseObjects0D-floorWithRamps.png |120px]] | ||
|- | |- | ||
| | | '''x0E''' || ramp down 1 || '''(x03,x03)''' || [[File:Motocross_Maniacs_courseObject0E-rampDownRight.png |90px]] | ||
|- | |- | ||
| | | '''x0F''' || ramp down with floor|| '''(x03,x03)''' || [[File:Motocross_Maniacs_courseObject0F-rampDownRight.png |90px]] | ||
|- | |- | ||
| | | '''x10''' || speed bump with floor|| '''(x01,x01)''' || [[File:Motocross_Maniacs_Object10-speedBump.png |30px]] | ||
|- | |- | ||
| | | '''x11''' || looping ramp top left|| '''(x04,x04)''' || [[File:Motocross_Maniacs_Object11-circularRampInvertedTopLeft.png |120px]] | ||
|- | |- | ||
| | | '''x12''' || looping ramp bottom left|| '''(x04,x04)''' || [[File:Motocross_Maniacs_Object12-circularRampBottomLeft.png |120px]] | ||
|- | |- | ||
| | | '''x13''' || looping ramp top right|| '''(x04,x04)''' || [[File:Motocross_Maniacs_Object13-circularRampTopRight.png |120px]] | ||
|- | |- | ||
| | | '''x14''' || looping ramp bottom right|| '''(x04,x04)''' || [[File:Motocross_Maniacs_Object14-circularRampBottomRight.png |120px]] | ||
|- | |- | ||
| | | '''x15''' || floor with flanking ramp up|| '''(x01,x03)''' || [[File:Motocross_Maniacs_Object15-floorWithFlankingLeftRamp.png |90px]] | ||
|- | |- | ||
| | | '''x16 and x17''' || horizontal ramp|| '''(x01,x03)''' || [[File:Motocross_Maniacs_Object16-horizontalRamp.png |90px]] | ||
|- | |- | ||
| | | '''x18''' || ramp angle up 1|| '''(x02,x02)''' || [[File:Motocross_Maniacs_Object18-rampAngleUpRight.png |60px]] | ||
|- | |- | ||
| | | '''x19''' || blank square 1 (4 metatiles '''x08''') || '''(x02,x02)''' || [[File:Motocross_Maniacs_Object19-blankSquare.png |60px]] | ||
|- | |- | ||
| | | '''x1A''' || blank square 2 (2 metatiles '''x08''' and 2 '''x6B''') || '''(x02,x02)''' || [[File:Motocross_Maniacs_Object19-blankSquare.png |60px]] | ||
|- | |- | ||
| | | '''x1B''' || long ramp up || '''(x04,x04)''' || [[File:Motocross_Maniacs_Object1B-longRampUpLeft.png |120px]] | ||
|- | |- | ||
| | | '''x1C''' || medium floor || '''(x01,x04)''' || [[File:Motocross_Maniacs_Object1C-mediumFloor.png |120px]] | ||
|- | |- | ||
| | | '''x1D''' || small ramp up with floor || '''(x02,x02)''' || [[File:Motocross_Maniacs_Object1D-smallRampUpLeftWithFloor.png |60px]] | ||
|- | |- | ||
| | | '''x1E''' || ramp up with platform 1 || '''(x02,x04)''' || [[File:Motocross_Maniacs_Object1E-rampUpLeftWithPlatform.png |120px]] | ||
|- | |- | ||
| | | '''x1F''' || small triangular ramp || '''(x01,x02)''' || [[File:Motocross_Maniacs_Object1F-smallTriangularRamp.png |60px]] | ||
|- | |- | ||
| | | '''x20''' || ramp down 2|| '''(x03,x03)''' || [[File:Motocross_Maniacs_Object20-longRampDown.png |90px]] | ||
|- | |- | ||
| | | '''x21''' || floor with flanking ramp up 2|| '''(x01,x03)''' || [[File:Motocross_Maniacs_Object21-floorWithFlankingRampUp.png |90px]] | ||
|- | |- | ||
| | | '''x22''' || floor with flanking ramp up 2|| '''(x01,x03)''' || [[File:Motocross_Maniacs_Object22-floorWithFlankingRampDown.png |90px]] | ||
|- | |- | ||
| | | '''x23''' || tiny bump || '''(x01,x01)''' || [[File:Motocross_Maniacs_Object23-tinyBump.png |30px]] | ||
|- | |- | ||
| | | '''x24''' || ramp angle up 2 || '''(x02,x01)''' || [[File:Motocross_Maniacs_Object24-rampAngle.png |30px]] | ||
|- | |- | ||
| | | '''x25''' || ramp down || '''(x02,x02)''' || [[File:Motocross_Maniacs_Object25-rampDown.png |60px]] | ||
|- | |- | ||
| | | '''x26''' || ramp up|| '''(x02,x02)''' || [[File:Motocross_Maniacs_Object26-rampUp.png |60px]] | ||
|- | |- | ||
| | | '''x27''' || ramp angle down 2|| '''(x02,x01)''' || [[File:Motocross_Maniacs_Object27-rampAngle.png |30px]] | ||
|- | |- | ||
| | | '''x28''' || ramp angle down 3|| '''(x01,x02)''' || [[File:Motocross_Maniacs_Object28-rampAngleDown.png |60px]] | ||
|- | |- | ||
| | | '''x29''' || small looping ramp top left|| '''(x03,x03)''' || [[File:Motocross_Maniacs_Object29-SmallCircularRampInvertedTopLeft.png |90px]] | ||
|- | |- | ||
| | | '''x2A''' || small looping ramp bottom left|| '''(x03,x03)''' || [[File:Motocross_Maniacs_Object2A-SmallCircularRampBottomLeft.png |90px]] | ||
|- | |- | ||
| | | '''x2B''' || small looping ramp top right|| '''(x03,x03)''' || [[File:Motocross_Maniacs_Object2B-SmallCircularRampTopRightt.png |90px]] | ||
|- | |- | ||
| | | '''x2C''' || small looping ramp bottom right|| '''(x03,x03)''' || [[File:Motocross_Maniacs_Object2C-SmallCircularRampBottomRight.png |90px]] | ||
|- | |- | ||
| | | '''x2D''' || small ramp down with floor|| '''(x02,x02)''' || [[File:Motocross_Maniacs_Object2D-rampDownWithFloor.png |60px]] | ||
|- | |- | ||
| | | '''x2E''' || sand and floor above|| '''(x01,x03)''' || [[File:Motocross_Maniacs_Object2E-sandAndFloor.png |90px]] | ||
|- | |- | ||
| | | '''x2F''' || long ramp down|| '''(x04,x04)''' || [[File:Motocross_Maniacs_Object2F-longRampDown.png |120px]] | ||
|- | |- | ||
| | | '''x30''' || floor with flanking ramp up (similar to '''x21''')|| '''(x01,x03)''' || [[File:Motocross_Maniacs_object30-floorWithFlankingRampUp.png |90px]] | ||
|- | |- | ||
| | | '''x31 and x32''' || vertical circular ramp right || '''(x04,x02)''' || [[File:Motocross_Maniacs_Object31-verticalCircularRamp2.png |60px]] | ||
|- | |- | ||
| | | '''x33''' || floor platform with tiny ramp above sandbox || '''(x02,x03)''' || [[File:Motocross_Maniacs_object33-floorWithTinyRampOverSandbox.png |90px]] | ||
|- | |- | ||
| | | '''x34''' || long sandbox with floor above || '''(x01,x06)''' || [[File:Motocross_Maniacs_Object34longSandboxWithFloorAbove.png |180px]] | ||
|- | |- | ||
| | | '''x35''' || floor platform with tiny ramp 1 || '''(x02,x04)''' || [[File:Motocross_Maniacs_Object35-thickFloorWithSmallBump.png |120px]] | ||
|- | |- | ||
| | | '''x36''' || floor platform with tiny ramp 2 || '''(x02,x04)''' || [[File:Motocross_Maniacs_Object36-mediumThickFloorWithSmallBump.png |120px]] | ||
|- | |- | ||
| | | '''x37 and x38''' || short ramp down || '''(x02,x04)''' || [[File:Motocross_Maniacs_Object37-shortRampDown.png |60px]] | ||
|- | |- | ||
| | | '''x39''' || vertical circular ramp left || '''(x04,x02)''' || [[File:Motocross_Maniacs_Object39-verticalCircularRampLeft.png |60px]] | ||
|- | |- | ||
| | | '''x3A''' || long sandbox || '''(x01,x0A)''' || [[File:Motocross_Maniacs_object3A-longSandbox.png |300px]] | ||
|- | |- | ||
| | | '''x3B''' || ramp angle up 3 (similar to '''x18''')|| '''(x02,x02)''' || [[File:Motocross_Maniacs_Object3B-rampAngleUp.png |60px]] | ||
|- | |- | ||
| | | '''x3C''' || ramp angle up to platform || '''(x01,x02)''' || [[File:Motocross_Maniacs_Object3C-rampAngleUpToTop.png |60px]] | ||
|- | |- | ||
| | | '''x3D''' || ramp angle down from platform || '''(x01,x02)''' || [[File:Motocross_Maniacs_Object3D-rampAngleDownToPlatform.png |60px]] | ||
|- | |- | ||
| | | '''x3E''' || short ramp up || '''(x02,x02)''' || [[File:Motocross_Maniacs_Object3E-shortRampUp.png |60px]] | ||
|- | |- | ||
| | | '''x3F''' || circular ramp up to platform with floor || '''(x02,x03)''' || [[File:Motocross_Maniacs_Object3F-circularRampUpWithFloorAndPlatform.png |90px]] | ||
|- | |- | ||
| | | '''x40 and x41''' || ramp angle going up || '''(x02,x02)''' || [[File:Motocross_Maniacs_Object40-rampAngleGoingUp.png |60px]] | ||
|- | |- | ||
| | | '''x42''' || circular ramp down with floor || '''(x02,x05)''' || [[File:Motocross_Maniacs_Object42-circularRampDownWithFloor.png |150px]] | ||
|- | |- | ||
| | | '''x43''' || vertical ramp || '''(x02,x01)''' || [[File:Motocross_Maniacs_Object43-verticalRamp.png |30px]] | ||
|- | |- | ||
| | | '''x44 and x45''' || floor with small rock obstacle || '''(x01,x01)''' || [[File:Motocross_Maniacs_Object44-floorWithSmallRockObstacle.png |30px]] | ||
|- | |- | ||
| | | '''x46 to x48''' || short horizontal ramp || '''(x01,x02)''' || [[File:Motocross_Maniacs_Object46-shortHorizontalRamp.png |60px]] | ||
|- | |- | ||
| | | '''x49 and x4A''' || ramp up || '''(x02,x04)''' || [[File:Motocross_Maniacs_Object49-rampUp.png |120px]] | ||
|- | |- | ||
| | | '''x4B''' || ramp up with platform 2 || '''(x02,x05)''' || [[File:Motocross_Maniacs_object4B-rampUpWithPlatform2.png |150px]] | ||
|- | |- | ||
| | | '''x4C''' || finish line ramp top || '''(x01,x02)''' || [[File:Motocross_Maniacs_Object4C-FinishLineRampTop.png |60px]] | ||
|- | |- | ||
| | | '''x4D''' || ramp up || '''(x03,x03)''' || [[File:Motocross_Maniacs_object4D-rampUp.png |90px]] | ||
|- | |- | ||
| | | '''x4E and x4F''' || single looping road sign || '''(x04,x02)''' || [[File:Motocross_Maniacs_object4E-singleLoopingRoadSign.png |60px]] | ||
|- | |- | ||
| | | '''x50''' || "Go!" road sign with floor || '''(x04,x02)''' || [[File:Motocross_Maniacs_Object50-GoRoadSign.png |60px]] | ||
|- | |- | ||
| | | '''x51''' || "Go!" road sign with sandbox || '''(x04,x02)''' || [[File:Motocross_Maniacs_object51-goRoadSignWithSandbox.png |60px]] | ||
|- | |- | ||
| | | '''x52''' || road sign with up arrow || '''(x04,x02)''' || [[File:Motocross_Maniacs_Object52-roadSignUpArrow.png |60px]] | ||
|- | |- | ||
| | | '''x53''' || road sign with down arrow || '''(x04,x02)''' || [[File:Motocross_Maniacs_object53-roadSignDownArrow.png |60px]] | ||
|- | |- | ||
| | | '''x54''' || horizontal double looping road sign || '''(x03,x03)''' || [[File:Motocross_Maniacs_Object54-doubleLoopRoadSignWithFloor.png |90px]] | ||
|- | |- | ||
| | | '''x55''' || vertical double looping road sign || '''(x04,x02)''' || [[File:Motocross_Maniacs_Object55-verticalDoubleLoopRoadSignWithFloor.png |60px]] | ||
|- | |- | ||
| | | '''x56 to x59''' || short floor 2 (similar to '''x09''')|| '''(x01,x03)''' || [[File:Motocross_Maniacs_Object59-floor.png |90px]] | ||
|- | |||
| '''x5A to x5C''' || floor grass|| '''(x01,x03)''' || [[File:Motocross_Maniacs_Object5A-floorGrass.png |90px]] | |||
|- | |||
| '''x5D to x62''' || small vertical ramp|| '''(x01,x01)''' || [[File:Motocross_Maniacs_Object5D-SmallVerticalRamp.png |30px]] | |||
|- | |||
| '''x63''' || short circular ramp up|| '''(x02,x02)''' || [[File:Motocross_Maniacs_Object63-shortCircularRampUp.png |60px]] | |||
|} | |} | ||
Line 232: | Line 228: | ||
Metatiles are 16x16px, and are made of 2x2 arrays of 8x8px tiles. | 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. | They are defined with 4 consecutive bytes, the first two are the top half of the array, the last two are the lower half. | ||
[[ | [[File:Motocross_Maniacs_TriangularRamp.png|200px]] | ||
The top-left metatile (in red) is defined by | 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 | 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 ==== | ==== 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 === | === 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 | These '''items''' are placed on the course just like the other '''course objects'''. | ||
[[ | [[File:Motocross_Maniacs_Items.png|600px]] | ||
==== Item data structure ==== | ==== Item data structure ==== | ||
In the ROM data, items are defined by 3-byte words | 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: | 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 ==== | ==== Item data location in ROM ==== | ||
Note that data for course 8 appears before data for course 7. | 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 | Note that each chunk of item data ends with '''xFF'''. | ||
=== Course music data === | === Course music data === | ||
A table of 8 bytes at | 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): | 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: | 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 === | === 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. | 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. | ||
Line 288: | Line 292: | ||
* 3 bytes are used to set the computer's new position in the game | * 3 bytes are used to set the computer's new position in the game | ||
==== Computer opponent AI data location in ROM ==== | ==== 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 == | ||
Line 305: | Line 309: | ||
* 2 bytes for the display address | * 2 bytes for the display address | ||
* a sequence of text tiles for the word | * a sequence of text tiles for the word | ||
* a terminal | * a terminal '''xFE''' when the word is finished | ||
* a terminal | * a terminal '''xFF''' when the text is finished | ||
=== Text data location in ROM === | === Text data location in ROM === | ||
==== Title screen ==== | ==== Title screen ==== | ||
[[ | [[File:Motocross_Maniacs_TitleScreen.png|300px]] | ||
* | * '''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 ==== | ==== Game over screen ==== | ||
Fun fact: the game over text data is nested in the title screen text data. | Fun fact: the game over text data is nested in the title screen text data. | ||
* | * '''x0F08-x0F13''' "GAME OVER" at '''x98E6''' | ||
==== Pre-race screen ==== | ==== Pre-race screen ==== | ||
[[ | [[File:Motocross_Maniacs_PreRaceScreen.png|300px]] | ||
* | * '''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 ==== | ==== Time up screen ==== | ||
This message doesn't contain a display address, only the text itself. | 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 == | == Gameplay data == | ||
=== Initial values === | |||
* '''x09E4''' - initial Nitro (x04) | |||
=== Qualifying times data === | === Qualifying times data === | ||
Strange: they are lower than the course records. | Strange: they are lower than the course records. | ||
Qualifying times for each course require 3 bytes: | 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 | 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 === | === Gravity data === | ||
* | * '''x2143-x214A''' - a table of 8 bytes that is continuously read during the game, it specifies gravity pull. | ||
Changing all bytes to | Changing all bytes to '''x38''' creates a very slow descent for instance. | ||
=== Going up ramps data === | === Going up ramps data === | ||
* | * '''x214B''' (todo) | ||
=== Post-ramp boost behavior data === | === Post-ramp boost behavior data === | ||
* | * '''x5CBF''' - in chunks of 4 bytes (todo) | ||
=== Bike mid-air behavior data === | === Bike mid-air behavior data === | ||
* | * '''x5D8F''' - in chunks of 4 bytes (todo) | ||
=== Nitro boost data === | === Nitro boost data === | ||
* | * '''x5E37''' (todo) | ||
== | == Tile-related data == | ||
=== Tile | === Tile data === | ||
Each of the 8 courses in the game uses the same tileset. | 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. | |||
Each 8x8px tile is defined by | 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'''. | ||
If | |||
For example, if the bytes of a given tile are | 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: | ||
[[ | [[File:Motocross_Maniacs_TileExample.png|150px]] | ||
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 === | === Sprite data === | ||
* | * '''x3481-x34F1''' - a table of pointers for player sprite building (todo) | ||
== Music and sound FX data == | == Music and sound FX data == | ||
This section is work in progress, still very incomplete. | 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. | 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: | 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 | ||
{{Internal Data|game=Motocross Maniacs}} |
Latest revision as of 09:05, 26 January 2024
The following article is a Notes Page for Motocross Maniacs.
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. 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.
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. * 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. * 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.
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. 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.
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
* 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
* 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 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:
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
Internal Data for Motocross Maniacs
| |
---|---|