Page 2 of 3

Re: Metroid ported to use the MMC3.

Posted: Thu Aug 14, 2014 9:30 pm
by Movax12
snarfblam wrote: ... it checks the flag set by the NMI and if set, then runs the NMI routine.
That is how I was doing it too. I always felt there had to be a better way.

Re: Metroid ported to use the MMC3.

Posted: Tue Aug 19, 2014 1:21 am
by pops
An update:

The Metroid disassembly is incredibly disorganized. It's pretty clear that multiple people were working on this project, and that the left hand didn't know what the right was doing. Over the past few days of tidying the source code up, I've seen many dead ends - code that looks like it would do something but (a) is never called, or (b) because of the input data it receives, it always exits immediately. Redundant loading of variables, as in the snippet below, is common:

Code: Select all

LC457:
        lda MirrorCntrl                 ;Load MirrorCntrl into A.
        jmp PrepPPUMirror

    ...

PrepPPUMirror:
        lda MirrorCntrl                 ;Load MirrorCntrl into A.
        jmp SetPPUMirror                ;Set mirroring through MMC3 chip.

The AI routines are labyrinth, inefficient, and have inconsistent ways of calling subroutines. Because the code is disorganized and bizarre, I'm uncertain that fully documenting the remaining code would be helpful to anyone. While Metroid was certainly an amazing accomplishment for its time, it wouldn't be a good template for future projects.

That said, I think I've done something pretty neat.

The original disassembly referenced a ton of hardcoded addresses. I've managed to replace all of these in the $C000-$FFFF range (the hardwired last bank that contains the main game engine) with labels - although not very descriptive ones as of yet. If I decide to continue working on this project, I'm going to start cleaning up the GameEngine.asm source code file - perhaps separating it out, placing all related code together. Thus this project would become less of a straight disassembly of Metroid - instead, a better organized and lightly optimized version of that game.

We'll see.

Re: Metroid ported to use the MMC3.

Posted: Tue Aug 19, 2014 2:39 am
by thefox
pops wrote:That said, I think I've done something pretty neat.
A quick note: UxROM is not MMC3, TxROM is.

Re: Metroid ported to use the MMC3.

Posted: Tue Aug 19, 2014 8:11 am
by pops
Ha. I started using that designation for a different project, months ago, and never double checked it. Thanks. :)

Re: Metroid ported to use the MMC3.

Posted: Tue Aug 19, 2014 10:48 am
by JRoatch
About the disorganized code. Exactly 10 years ago, I tried out SnowBro's metedit, and I remembered there was a patch that reduced the size of level data by about 1/4 or something due to metroid storing attribute bits for every object placed when the whole screen was set to a single attribute anyway.

Also the PHP as the first thing in NMI.

Re: Metroid ported to use the MMC3.

Posted: Thu Aug 21, 2014 3:40 pm
by pops
43110 wrote:I remembered there was a patch that reduced the size of level data by about 1/4 or something due to metroid storing attribute bits for every object placed when the whole screen was set to a single attribute anyway.
I'm certain this isn't the case - the very first room in Brinstar contains objects using all four BG palettes.

However, on the subject of making level data much smaller:

Each area in Metroid (Brinstar, Tourian, etc.) occupies a single 16kb bank. Almost 50% of these Area banks is occupied by the sound engine and AI routines common to every Area bank. These shared routines are further duplicated in other banks. I estimate that eliminating this shared data would save almost 36kb of rom space! I'm certain it would be possible to move these shared routines into a single shared bank of ~8kb (leaving ~8kb of space left over for new AI/graphics routines), while simultaneously doubling the space available for an Area's rooms/structures/graphics/music data. There's also ~3kb of free space in the Graphics bank.

I've started reorganizing the code in the fixed code bank: instead of a single 9600 line file, there's now separate files for graphics routines, sound effects, PPU writing, room display, and so on. There's still a ton of work left to go, of course. I've also eliminated ~240 bytes of data - and the game still runs fine, as far as I can tell (I haven't done a complete run through yet).

Re: Metroid ported to use the MMC3.

Posted: Thu Aug 21, 2014 4:03 pm
by rainwarrior
pops wrote:Each area in Metroid (Brinstar, Tourian, etc.) occupies a single 16kb bank. Almost 50% of these Area banks is occupied by the sound engine and AI routines common to every Area bank. These shared routines are further duplicated in other banks.
I read this and I was quite surprised they would waste so much space duplicating routines like this that could easily be reached by a banked-jump, but then I realized that this would have been unavoidable on the FDS, so it kinda makes sense as a port from that version.

Re: Metroid ported to use the MMC3.

Posted: Thu Aug 21, 2014 4:48 pm
by thefox
rainwarrior wrote:
pops wrote:Each area in Metroid (Brinstar, Tourian, etc.) occupies a single 16kb bank. Almost 50% of these Area banks is occupied by the sound engine and AI routines common to every Area bank. These shared routines are further duplicated in other banks.
I read this and I was quite surprised they would waste so much space duplicating routines like this that could easily be reached by a banked-jump, but then I realized that this would have been unavoidable on the FDS, so it kinda makes sense as a port from that version.
Same as if you first looked at Kid Icarus, you probably wouldn't guess that it needs 8 KB of WRAM.

Re: Metroid ported to use the MMC3.

Posted: Thu Aug 21, 2014 5:35 pm
by tepples
If your game is 80K, there's no hurt in duplication anyway.

Re: Metroid ported to use the MMC3.

Posted: Thu Aug 21, 2014 7:07 pm
by snarfblam
You know, I've already written a hack to expand Metroid that places each level's object and screen definitions into its own 16k bank.

Re: Metroid ported to use the MMC3.

Posted: Thu Aug 21, 2014 8:08 pm
by pops
snarfblam wrote:You know, I've already written a hack to expand Metroid that places each level's object and screen definitions into its own 16k bank.
I didn't know that.
What modifications did you make? Did you have to make any trade-offs?

Re: Metroid ported to use the MMC3.

Posted: Fri Aug 22, 2014 10:24 am
by JRoatch
pops wrote:
43110 wrote:I remembered there was a patch that reduced the size of level data by about 1/4 or something due to metroid storing attribute bits for every object placed when the whole screen was set to a single attribute anyway.
I'm certain this isn't the case - the very first room in Brinstar contains objects using all four BG palettes.
It was basically removing the third byte of each of the object data in room definitions, and letting the attribute byte of the whole room take charge. Not that much of a saver for sure.

Re: Metroid ported to use the MMC3.

Posted: Fri Aug 22, 2014 3:32 pm
by snarfblam
pops wrote:What modifications did you make? Did you have to make any trade-offs?
I expanded the ROM from 8 to 16 banks (256 KB), and converted it from CHR RAM to CHR ROM. Each level's object and screen definitions were moved to their own bank, giving you $4000 for them. Removing the CHR and object/screen definitions from level data banks also frees up more room than you'll ever need for palettes, item data, etc. Originally, the only time bank swapping occurred was when switching levels. Since the sound engine (called from NMI) is stored in the original level data bank, when I added bank-swapping code to access the moved object/screen data, I had to add a safeguard to the NMI routine to make sure the proper bank is loaded.

Aside from that, I did some data shuffling to keep the organization of banks more consistent.

The game doesn't do anything tricky with CHR RAM. There are 18 or so predefined (4 KB) CHR arrangements so that made it easy to convert to CHR ROM. Since there were extra CHR ROM banks, I added the ability to cycle banks for animated background tiles (as seen in 'Roids). Alternatively, you could use the extra banks to do CHR swaps and provide different tilesets for different areas of a level for more variety, which is what I'm doing with a hack I'm working on.

The expansion can be applied via my level editor.

Re: Metroid ported to use the MMC3.

Posted: Sun Aug 24, 2014 8:25 am
by pops
snarfblam wrote:... converted it from CHR RAM to CHR ROM.
This is brilliant. I know you can use the MMC3 to split up CHR ROM into 2x2kb and 4x1kb chunks. Do you use the 2kb chunks for BG or sprites?
Since the sound engine (called from NMI) is stored in the original level data bank, when I added bank-swapping code to access the moved object/screen data, I had to add a safeguard to the NMI routine to make sure the proper bank is loaded.
Did you consider putting the songs in their own 16kb banks? The sound engine takes up 3414 bytes at present and it might be possible to slim it slightly further. The average song data is about 300 bytes; the largest is the title song at about 1000 bytes. With that in mind, you could put all the music and sound data into its own bank and have tons of room left over for new music.

Do you have any updates on the hack you're working on?

Re: Metroid ported to use the MMC3.

Posted: Sun Aug 24, 2014 2:59 pm
by pops
Here's a thought: how do you think a music engine like Famitone 2 would compare, feature-wise, with the default Metroid music engine? I think that with a little awesome engineering, it would be possible to replace one with the other...