+  RHDN Forum Archive
|-+  Romhacking
| |-+  ROM Hacking Discussion
| | |-+  Dr. Mario (NES) Hacking Information?
Pages: [1]
Author Topic: Dr. Mario (NES) Hacking Information?  (Read 2 times)
Zero X. Diamond
Guest
« on: March 24, 2009, 05:34:06 pm »

Hey guys, I'm new here.  I think this is the right forum to post this thread from what I saw, but I'm not 100% positive; if not, please don't hate me for it!

Anyhow, I've been working on a neat little hack of Dr. Mario for the NES.  My aim with the project is to hack all the graphics, most of the text (some of it wouldn't need modification obviously--level, speed, etc.) and most importantly, the music.  I've already got two tunes composed to replace Fever and Chill in NSF format and everything, but from my understanding, I need to know how the music system works for the game in question before getting the music into the project is even feasible.  Now the problem with this is that there is no documentation about Dr. Mario's internal structure whatsoever.  I spent all weekend searching Google and this site, but I've had no luck, and all I've been able to really determine myself in terms of useful information is the location of the palette information for the game, and even then this was done using the NES Palette Editor found in the utilities section here.

I only have minor experience in ROM hacking, mostly in NES and mostly not much more than importing graphics and hex editing text.  As such, while I do know the methods for actually editing the hard coded information by hand, I really have no idea where to start or what have you.  If anybody could give me a hand here, especially with the sound system stuff, I'd be very, very grateful.  As lame and pandering as it sounds, I'll credit anyone who gives me a hand in a readme along with the release of the hack.

Thanks in advance!
Parasyte
Guest
« Reply #1 on: March 24, 2009, 06:34:23 pm »

The typical response goes something like this, "Now would be a good time to learn assembly."

That means, the most direct approach to finding 1) where the data is stored and 2) what its format is, is by locating and making sense of the assembly code which actually uses it. There are other ways to find these two important pieces of information, mainly trial and error, and educated guessing. But getting right into the code can often be faster and more accurate.

Long ago, I wrote several short (and sweet!) tutorials to get people started with assembly hacking. None are directly related to music (or audio, for that matter) but the processes (methods) described and general information is still largely relevant. For example, applying the 'breakpoint methodology' to the NES APU registers will quickly drop you right into the thick of the game's audio engine.
PolishedTurd
Guest
« Reply #2 on: March 24, 2009, 09:31:50 pm »

A good way to start is to follow the advice that was given to me about finding music pointers in this forum recently. Start the code/data logger, then load the game, start playing, and pause the emulator (not the game). So the title screen song will play, then the "settings" song, then fever or chill, whichever you chose. Fire up the hex editor and look for 3 2-byte pointers in blue near one another, then corrupt them to see if they change the music (note that sound effects are probably close to the music pointers in memory, so a few of those will be blue as well). The addresses of the song pointers must be read in order for the APU to know what tracks to cue up. Set a read breakpoint on one of them at a time, and see what happens in the code immediately after that point.

Also, look in the NES memory in a hex editor. Probably near the beginning (zero page), look for hex values that change exactly with the music. You will see values that change based on moment-to-moment musical events, and values that change as the music changes phrases (every several seconds). Each of these is another trail of breadcrumbs to follow.

I've only hacked one ROM so far (Ninja Gaiden), but here are some general guidelines I've come up with:

- Search for the things that change, when you can pinpoint what should happen and when. For example, you know the song changes when the number of viruses reaches zero. You can easily use the Cheat Finder to figure out where the viruses are being counted, and then set a conditional read breakpoint where that $address == #0. That will bring you to a place where the song is about to be changed.

- Find as many trails as possible to where you are trying to reach. You can start from a small endpoint and trace your way up to the larger piece, or start from a large pool of possibilities and work your way down. It is best to do both, and multiple instances of both if you can. Here, the music pointers will be the large piece. They will lead to the tracks (drums, bass, melody, harmony), from which you can infer the values and looping patterns. To start from a small piece and work your way up, find a place in one of the songs where only one "thing" is happening in the music. There is one song (I think it's Fever) after a buildup where the drums do a quick roll and none of the other tracks are playing. Save state near that point in the song, then watch the hex editor for the track that changes while the others do not. That can tell you what values correspond to a snare drum, from which you can crack the rest of the drum code. In the title screen song, the beginning has no drums, and then the drums come in after 8 measures, so watch the hex for that. 

- As much as possible, isolate what you are searching for. Try to eliminate everything else that is changing or being updated (in this case, graphics and the mechanics of the gameplay). Your best bet here is the screen where you select your difficulty and music, because when you do not touch the controller, no graphics are being updated. The music will constitute most of the dynamic action.

- Bite off the smallest meaningful piece that you can chew. Some of the songs in Dr. Mario are long. I'd say start with the shorter or simpler ones (victory song, death song, winning on level 15 or 20, etc.) so you can figure out the structure more easily. My impression is that NES music (and much of music in general) is built on the premise of looping parts a certain number of times and then changing to another loop.

Also look at other people's hacks of NES game music engines for ideas. It seems that someone has really figured out the engine for one of the Final Fantasy games, going so far as to write new opcodes for it to optimize memory use. Sorry I don't know his name offhand (I would certainly be interested in how he went about doing that, BTW).

Dr. Mario has some pretty evolved music for the NES, with dynamics and color. I would love for someone to figure out the engine so I can play with it also. I'd be willing to assist you in figuring it out later (I'll be very busy in the next few weeks), but I certainly encourage you to find out as much as you can and then publish it for others in the meantime.
SerenadeDS
Guest
« Reply #3 on: March 24, 2009, 09:34:31 pm »

Quote from: PolishedTurd on March 24, 2009, 09:31:50 pm
A good way to start is to follow the advice that was given to me about finding music pointers in this forum recently.

Yep, and Sliver-X did a nice job explaning and including pictures too. You can find that here, in case you need a visual representation. May not be the same as what you're trying to do, but it's related to the post before mine.
tummai
Guest
« Reply #4 on: March 27, 2009, 09:02:14 am »

For sound, the first thing I do is set a breakpoint on a write to one of the APU registers (usually $4000) and that will let me know which bank the sound engine is in.

The next thing I look for is the note table.  On the NES, notes are 11-bit values that are written to the 3rd and 4th registers of each channel. ($4002/03 for Square 1, $4006/07 for Square 2, $400A/0B for Triangle).  Blargg's APU reference will help you to know what register does what.  First I will try a hex search for common note values.  (Look at Celius's chart for reference).  I'll search for the low A.  Games generally store note values in two ways:

1) As pairs.  ie, low A will be F107, Bb will be 8007, etc
2) Hi byte in one table, Low byte in another, in which case I'll search for something like "07 07 07 06 06" to see if I can spot the Hi byte table.

Not all games use Celius's values, so if F107 doesn't turn up for the low A, I'll try FF07, FE07, FD07, FC07, etc until I find it.

If I can't find the note table by hex searching, I will start the Trace Logger in FCEUXSP, and set a breakpoint for writes to these registers ($4002/03 for example) and then follow the bread-crumb trail backwards to see where they got the value.

After I get these two pieces of information, I'll try to find the song pointers, which has been described in the last couple of posts.  Once I find the song pointers, I can look at the data.  From here, I try to determine what bytes do what.  Generally, there are four types of bytes:

1) note value (tells what note to play.  A, B, C#, D, etc).  These will usually jump out at you since they are the most frequent type
2) note length (tells whether you have a quarter note, 8th note, 16th note, etc)
3) opcodes (these bytes signal the sound engine to run subroutines that will do different things like set loops, alter the pitch, change song tempo, set the channel volume, etc.  basically anything that 1) and 2) can't do).
4) operands for opcodes.  After an opcode value, there will usually be one or more values that it takes as arguments/operands.

Each type will have a byte range.  For the NES Final Fantasy 7 game for example, values of $00-3F are note lengths.  $40-7F are notes and $C0-E5 are opcodes.  You can usually guess the ranges just by looking at the data and listening to the song, but if that doesn't work, you can trace through the sound engine code and find them.  There will usually be some branching code.  For example, the final fantasy 7 code:

1) reads a byte from the song data
2) compares it to $40.  If less than, jump to note length code
3) else compare to $C0.  If less than, jump to note value code
4) else jump to opcode code.

Note values usually just index into the note table(s), and since I already know about the note table, I can quickly make a chart of what byte value equals what note.

Note lengths are fairly easy to figure out.  Either they index into a note length table or they represent the note lengths themselves. (ie. 16th notes are half the value of 8th notes which are half the value of quarter notes, which are half the value of half notes, etc)

The opcodes take the most time to figure out and really require ASM knowledge.  I usually have to trace through several frames of the sound engine one instruction at a time, taking notes along the way.  You can try to speed up the process with ROM corruption though.  Once you know which byte values are opcodes, you can alter the operands and listen for differences in the song.  Changes in pitch or song speed can tip you off to whether the opcode alters the notes' pitch or the song tempo, for example.

Hope that helps!  Good luck! Smiley  If anything I said wasn't clear, feel free to ask and I can try to explain it better.
Pages: [1]  


Powered by SMF 1.1.4 | SMF © 2006-2007, Simple Machines LLC