News:

Don't forget to visit the main site! There's lots of helpful docs, patches, and more!

Main Menu

Metroid II stuff

Started by Raccoon Sam, March 03, 2017, 11:29:03 AM

Previous topic - Next topic

Raccoon Sam

EDIT: what a mess
oh well, hopefully there's something of interest here though

So long story short, I was going through some of my old files and found a ROM map of Metroid II I had started too long ago. Nostalgic and intrigued, I looked into it and tried to fill in some holes I had missed.
I didn't get too far until I realised that RT-55J had beaten me to it, and that his notes were written down far far more neatly. However, after a quick cross-reference, there are a few parts he had figured out that I hadn't, but I also made some insights he missed. My stuff is a mess and a lot of stuff might be/probably is/definitely is not correct, but a few things might be of interest. RT, if you're reading this, let's nail this down once and for all - after all, the game's only 16 banks big!

The ROM map stuff
[spoiler]
Sprite format: **** SEE NOTE 0 ****
   - Four bytes, YY XX TT AA, for one 8x8 tile
   - Four-byte definitions go on until a $FF terminator is found
   YY = Y coordinate
   XX = X coordinate
   TT = tile to use
   AA = standard attributes (flip vertically, horizontally, priority etc.)


04000 - 04089 : Sprite pointers, 69 of them.
0408A - 0493D : Sprite data, set 0 (Save texts, Samus Power Suit sprites, etc.) **** SEE NOTE 1 ****
0493E - 04C1C : possibly related data to above.

04C1D - 04C58 : 30 pointers to below (many duplicates to only 10 unique ones)
04C59 - 04DDE : Entries the pointers above point to. Something to do with sprites, but unknown and range possibly incorrect
04DDF - 0519F : Unknown. Range possibly incorrect
051A0 - 055DC : Probably beam and missile related trajectory code
055DD - 05672 : Coordinate table for beam/missile generation
05673 - 058F0 : No idea

058F1 - 05910 : Pointer table, 16 pointers.
05911 - 05A10 : 16 16-byte arrays. Item names?

05A11 - 05AB0 : Some routine(?)
05AB1 - 05CAE : Massive pointer array. 255 in total. Points to sprites below.
05CAB - 070B9 : Sprite data, set 1 (Various sprites, common elements, enemies, effects, Metroids) **** SEE NOTE 2 ****

070BA - 071DA : Some routine. Metroid confrontation cutscene related.
071DB - 071FA : Pointer table, 16 pointers.
071FB - 0723A : 16 16-byte arrays. Unknown.

0723B - 0729B : Some routine(?)
0729C - 072BB : a 32-byte array. Unknown.

072BC - 07328 : Some routine(?)
07329 - 07358 : 24 pointers
07359 - 073B9 : 24 4-byte arrays. Unknown.

073BA - 07449 : Some routine(?)
0744A - 07495 : Sprite pointers, 38 of them.
07496 - 079EE : Sprite data, set 2 (Ending sprites) **** SEE NOTE 3 ****

079EF - 07B86 : Some routine(?)
07B87 - 07FFF : empty

08000 - 0FFFF : TODO

10000 - 13FFF : GBS/music data **** SEE MIIGBS.TXT ****
14000 - 142E4 : Some routine(?)
142E5 - 146E4 : Massive pointer array. 512 in total, 480 if you weed out the duplicates.
146E5 - 15877 : The byte groups that the pointers above point to. Something to do with doors.
15878 - 15989 : Unknown
1598A - 15B33 : Unknown

15B34 - 15F33 : Title screen tilemap data
15F34 - 16F33 : Title screen graphics

16F34 - 17F1F : Ending graphics
17F20 - 1991F : Common graphics
19920 - 1A91F : Enemy graphics
1A920 - 1B51F : Various graphics
1B520 - 1B91F : Metroid, egg, Samus' ship graphics
1B920 - 1BE02 : Credits text. Format:
   - 1 byte = 1 character
   - $F1 = line break
   - $F0 = terminator

1BE03 - 1BFFF : Unknown
1C000 - 1FFFF : Various graphics
20000 - 2007F : Unknown
20080 - 2087F : Physmap attributes for tilesets. Format:
   - Eight bits, S??d Dabw, for one 8x8 tile
   - Four bytes per block (top left tile, top right tile, bottom left tile, bottom right tile)
   w = water
   b = one-way from below
   a = one-way from above
   D = damage that bounces you away
   d = accumulating damage when touching
   ? = ?
   ? = ?
   S = Saving tile

20880 - 2187F :
   Tile definitions for 16x16 blocks in each tileset. $200 bytes per tileset, 4 bytes per block.

21880 - 219BB : Unknown
219BC - 229BB : Metroid graphics
229BC - 239BB : Tileset graphics
239BC - 23EBB : Metroid graphics
23EBC - 23FFF : Unknown, but also pointers to physmaps and tileset definitions.

Zone 0:
24000 - 241FF : Word array, something to do with room transitions.
24200 - 242FF : $100 byte array for room order (?)
24300 - 244FF : Unknown, something to do with zone warps
24500 - 27FFF : Level data. $100 bytes per 16x16 room.

Zone 1:
28000 - 281FF : Word array, something to do with room transitions.
28200 - 282FF : $100 byte array for room order (?)
28300 - 284FF : Unknown, something to do with zone warps
28500 - 2BFFF : Level data. $100 bytes per 16x16 room.

Zone 2:
2C000 - 2C1FF : Word array, something to do with room transitions.
2C200 - 2C2FF : $100 byte array for room order (?)
2C300 - 2C4FF : Unknown, something to do with zone warps
2C500 - 2FFFF : Level data. $100 bytes per 16x16 room.

Zone 3:
30000 - 301FF : Word array, something to do with room transitions.
30200 - 302FF : $100 byte array for room order (?)
30300 - 304FF : Unknown, something to do with zone warps
30500 - 33FFF : Level data. $100 bytes per 16x16 room.

Zone 4:
34000 - 341FF : Word array, something to do with room transitions.
34200 - 342FF : $100 byte array for room order (?)
34300 - 344FF : Unknown, something to do with zone warps
34500 - 37FFF : Level data. $100 bytes per 16x16 room.

Zone 5:
38000 - 381FF : Word array, something to do with room transitions.
38200 - 382FF : $100 byte array for room order (?)
38300 - 384FF : Unknown, something to do with zone warps
38500 - 3BFFF : Level data. $100 bytes per 16x16 room.

Zone 6:
3C000 - 3C1FF : Word array, something to do with room transitions.
3C200 - 3C2FF : $100 byte array for room order (?)
3C300 - 3C4FF : Unknown, something to do with zone warps
3C500 - 3FFFF : Level data. $100 bytes per 16x16 room.

----------------------------------------------------------------
[/spoiler]

Notes:
[spoiler]**** NOTE 0: ****
So, to visualise the sprites and get a sense of understanding, I wrote a quick'n'dirty converter that takes in bytes and spits out .anim markup, which are something that DarkFunction Editor can read and write.

The output feels right, although I'm not 100% certain about the attribute byte and the coordinate origin. Also, there's no way of knowing which sprites use which graphics and what gives the current room the "what graphics to load here" attribute. The data is obviously somewhere in the areas I couldn't verify, but one thing is certain: there's no single pointer anywhere that tells which address to read a single graphics page from. The graphics pages loaded to VRAM are built from smaller strips from several places in the ROM. That's why some graphics look weird on these output GIFs (and also, in case it wasn't obvious, that's why the "secret world enemies" look like they do). Below are the GIFs, one frame = one sprite.

**** NOTE 1: ****


**** NOTE 2: ****


**** NOTE 3: ****


----------------------------------------------------------------
[/spoiler]

GBS stuff:
[spoiler]
First things first - a GBS file is a Game Boy ROM image with all the stuff stripped out except the music data. Essentially, it's emulated music. Debugging a GBS file is much easier than debugging its respective ROM, but because of the nature of GBS files, the pointers in this document aren't actually pointers to offsets in the GBS file, but in the ROM. Sure, the pointer '90 5F' is in the GBS file too, but going to its address (0x11F90) in the GBS will show you unrelated data. Going to the address 0x11F90 in the ROM is correct, but like I said, it's much more fun debugging a GBS file, so some pointer math is required. The pointer '90 5F' is a pointer to data found in the ROM at 0x11F90, which is found in the GBS at 0x201D. So (POINTER - $3F73 = GBS_ADDRESS) or (GBS_ADDRESS + $FF73 = ADDRESS_IN_ROM).
I'm not sure if I explained this in the best way possible but oh well... If you're having trouble understanding, search for a byte array (you copied from somewhere in the GBS) in the ROM and observe its address.

In the GBS:
0x0099 - 0x012C : pitch table
0x012B - 0x019E : tempo table(?)
0x019F - 0x1FBC : unknown but probably really important. I'm sure I saw a few pointer arrays there. Not needed for things explained below, though.

About the note data:
Note data is RLEish, and curiously very similar to the note data in Super Mario Land and possibly Super Mario Land 2.
Maybe a common music engine was used, a la N-SPC? Needs investigation. See my old video
here for SML similarities.

In short, it's just command after command what to do. There are several commands, all of which I've named. In their first instance I explain the command's function and in the subsequent instances I simply refer to their name. The first song is completely annotated so you get a firm understanding on what the bytes mean, but the later ones are just formatted bytes mostly.

Notice:
1) Most terminology is completely pulled from the deep reaches of my anus, so don't stop to wonder if "Grand Pointers" actually means anything important. I just needed a convention to name my offsets and pointers - GP00 is the name of the first Grand Pointer (its value is 90 5F), and $GP00 is like a notation for a bookmark; it simply shows what bytes are stored in the ROM's address 0x11F90 (0x201D in the GBS).
2) All the bytes unabridged from 0x1FBD onwards have been pasted here with only my formatting and shitty comments added.
3) If you read all this and still have no idea what's going on, watch this
this video

In the GBS:
0x1FBD - 0x201C : the Grand Pointer array:

90 5F                           // GP00
8A 60                           // GP01
D4 61                           // GP02
ED 64                           // GP03
5F 68                           // GP04
EE 68                           // GP05
88 69                           // GP06
E2 6A                           // GP07
C3 6B                           // GP08
8E 6C                           // GP09
51 6D                           // GP10
8B 6D                           // GP11
D5 6E                           // GP12
50 6F                           // GP13
A4 6F                           // GP14
69 47                           // ???? - note: not a pointer at all?
3C 70                           // GP15
27 74                           // GP16
8A 74                           // GP17
D4 61                           // GP02 - note: duplicate!
3A 7C                           // GP18
45 7C                           // GP19
50 7C                           // GP20
5B 7C                           // GP21
E2 6A                           // GP07 - note: duplicate!
C3 6B                           // GP08 - note: duplicate!
8E 6C                           // GP09 - note: duplicate!
51 6D                           // GP10 - note: duplicate!
8B 6D                           // GP11 - note: duplicate!
66 7C                           // GP22
71 7C                           // GP23
09 7D                           // GP24
FF FF                           // ???? probably not pointers at all
FF FF                           // ????
FF FF                           // ????
FF FF                           // ????
FF DB                           // ????
FF FF                           // ????
FF DE                           // ????
DE FF                           // ????
FF DE                           // ????
FF FF                      &nb

P.JBoy

...

Raccoon Sam

#2
 :whoa: Wow, that's exactly what I was hoping to see! Insanely good job, much much more than I expected to see documented anywhere.
What do you think would be the best method for audio editor development?
I used http://benjaminsoule.fr/tools/vmml/ for testing and wrote some scripts to convert the byte streams to valid MML I could just paste onto the page, but that really only worked for some smaller segments, not whole multichannel songs with track effects and all.
A GBS -> XM/MOD/IT -> music data converter maybe?

P.JBoy

I honestly don't know, looks like there's a load of assembly in the mix too when it comes to playing the songs
...

FelixWright

Opening this forum topic startled me. Where is the music coming from?

RT-55J

Holy carp guys. This is really impressive.

I'm rather busy with my last semester as an undergrad so far, so I'd don't think I'd be able to contribute much right now to a disassembly/documentation effort.

I've been meaning for some time to make some rudimentary scripts to read and work with various pieces of data, but my feelings of inadequacy of a programmer, combined with the scope of the project, have been quite crippling in this respect. In reality, if I taught myself how to read binary files in whatever language, I could probably crank out something decent in a couple weeks of spare time (good luck to myself trying to convince myself of that).

Raccoon Sam

Quote from: P.JBoy on March 04, 2017, 07:50:53 AM
a load of assembly in the mix too when it comes to playing the songs
What do you mean? Sure, the F1, F2 and F3 commands are weird but what assembly is there really to tackle down if you only want to edit the songs? Unless I'm missing something, it's a pretty simple format to read (and edit, given the right tools)

P.JBoy

In retrospect, I must have been thinking about the sound effects, which are using assembly to control their output
...

jorge_dmtz

Hello, I'm new here, and I want to help improve this awesome game, the thing is I know just the basic stuff about moding but I got a lot of free time, maybe I could be of some help, I would like to help you disassebly this game just like they did with Metroid 1