Hacking an N64 game to replace the audio?

Discussion in 'Modding and Hacking - Consoles and Electronics' started by FireAza, Sep 30, 2012.

  1. FireAza

    FireAza Shake! Shake!

    Joined:
    May 31, 2012
    Messages:
    2,003
    Likes Received:
    25
    So I've been playing Mischief Makers on the N64, and I was thinking it would be really cool to hear the game with the original Japanese voices. Now, I could go out and buy a Japanese copy of the game, but I was thinking it would be really cool to hack the original ROM and swap out the English audio for the Japanese audio, while still leaving the English text in the game and burning the result to a replacement EPROM. Would such a thing be possible? And for bonus points, would it be possible to put both versions of the game in the cart and have it switchable? Would the saves still work in this case?
     
  2. mikeryan

    mikeryan Active Member

    Joined:
    Aug 2, 2010
    Messages:
    45
    Likes Received:
    0
    N64 ROM chips used a multiplexed address and data bus, which is different from the interface used by classic systems and traditional EEPROMs. To read data you latch in an address and then clock out data using the same set of pins. It's very similar to the ROMs used in GBA.

    I've seen a small handful of EEPROM chips like this, but they're uncommon. I doubt you'll be able to find one that meets all your requirements:

    • 5 volts
    • 16 bit address and data bus
    • large enough for an N64 ROM
    On the off-chance that you do find one it'll most likely be surface mount, so plan on spinning a custom PCB, or at least a custom TSSOP to DIP adapter.
     
  3. FireAza

    FireAza Shake! Shake!

    Joined:
    May 31, 2012
    Messages:
    2,003
    Likes Received:
    25
  4. C-Kronos

    C-Kronos Intrepid Member

    Joined:
    Mar 2, 2009
    Messages:
    633
    Likes Received:
    3
    If you can manage to hack the ROM and replace the audio files, you can use a 64drive or an ED64 to play it on the actual hardware. I know some N64 games have been decompressed, but I'm not sure if this is one of them. Maybe some of the people over at goldeneyevault can point you in the right direction to accomplish what you want to do.
     
  5. Zoinkity

    Zoinkity Site Supporter 2015

    Joined:
    Feb 18, 2012
    Messages:
    499
    Likes Received:
    108
    Sound bank swapping.

    Screw it. I just made a patch.
    http://www.mediafire.com/?yw7j7n35nnm17tb
    It's an xdelta. Just apply it to an unbyteswapped NTME ROM. Probably works, but didn't bother uploading to console to really test it out.

    +_+

    Original message:

    Sub's sound extraction tools are great but the filelists are incomplete. The 'voices' are typical B1 soundbanks and can be manipulated with N64soundlisttool. I know it's silly, but the US version is listed, but never went back for the other regions. Here's the entries for the N64soundlisttool; just copy them into the config file:
    [Mischief Makers (E)]
    4AB4D0,4BCC60,0
    4AB4D0,4BCC60,1
    4AB4D0,4BCC60,2
    [Yuke Yuke!! Trouble Makers (J)]
    4B7210,4C8650,0
    4B7210,4C8650,1
    4B7210,4C8650,2

    Incidentally, typical design is N64 music and sound effects are stored in different formats, therefore different locations.

    The simplest thing is to do a direct file swap. One slight issue in this particular case is that the japanese soundbanks are different in size. The sound tools won't be much help as they can't extend the allocated space for sound in order to insert a larger bank (this would be on a per-game basis). The two possible routes will be to extend the sound bank, drop the japanese in, and hope you don't break in-game allocation routines; the alternate route would be to simply drop the english script into the japanese game.
    Most are already rigged with variable width fonts since, at this point, most were compiled with multi-region support already in mind. That said, since data streaming is pretty common as well, so long as the game doesn't use a whole lot of direct addressing (filetables, as opposed to directly loading everything via hardcoded addresses in ASM) it's usually negligable to entend the thing a little and offset other data.

    This would take a bit of work to extend & drop but I'd advise that method. From CBC7C-CD7FC is a table of ROM offsets falling after the different sound banks up to the end of ROM. The S1 and B1 banks offsets are set in ASM, which is rather typical. So, if you were to drop in the japanese bank, increment everything that isn't NULL in that bank by the difference in filesize, then change all the S1 and B1 address instances at:
    0x28C0+
    0x2B24+
    0x2940+
    0x298C+
    0x29A0+

    +_+

    A combined game is possible, but the difficulty of implementing it depends on the title. As a point of interest, many games will include multiple regions of text files that are selected at runtime. The selection is usually hardcoded, but you occationally get the enterprising title that loads it based on the region setting in the gameID. It made sense from a development point of view when you can send flags and arguments when booting the title, since that meant you only need to build one game and send '-j' to test the other language set. It is occationally done with images as well; a good example would be the unreleased Dragon Storm--good from the perspective that an effectively shovelware half-developed title had this already implemented for no particularly good reason.

    Game structure is key. Games that use filename lookups are the easiest, since you just extend their filetables and add more lookups, then append a language identifier on all your lookup strings. Strict filesystems can also use an offsetting method, or a simple index<<1 + (region==japanese) kind of system. Having to hack in switches or conditionals though can be tedious, and when you're talking games with several thousand files it could prove impossible.

    ROMs can be resized all the way up to 512Mb, but although the hardware limit is probably higher no emulator or flashcart I know of will permit higher than that. So, there is a file limit.


    Saves are less finicky on hardware than emulators. Unless there's something specificly region-breaking, such as testing the encoded region or incompatible data, it works perfectly fine.
     
    Last edited: Oct 1, 2012
  6. SubDrag

    SubDrag Rapidly Rising Member

    Joined:
    Mar 13, 2011
    Messages:
    92
    Likes Received:
    15
    I must admit that I did all the US games and thought that the other regions would be the same, or similar enough people could easily find it. In retrospect I should've done them all in that go. At this point, I guess I just slowly add them or if someone gives me more.

    If there really is a way to put in a new chip in an old game, I'd love to see that explored one day.
     
  7. Zoinkity

    Zoinkity Site Supporter 2015

    Joined:
    Feb 18, 2012
    Messages:
    499
    Likes Received:
    108
    Since you were asking, here's a decompression script in pythonese:
    (Incidentally, CODE tags would be a nice addition over the intense INDENTing)

    def dec(data):
    tbl1 = [ 1, 1, 1, 1, 1, 2, 2, 2]
    tbl2 = [-2,-1, 0, 1, 2,-1, 0, 1]
    out = bytearray()
    # Initialize stream:
    d = Trouble._grab(data)
    val = 4
    while True:

    ctrl = next(d)
    if ctrl < 0x80:
    i = ctrl>>4 & 7​
    l = ctrl&0xF​
    p = len(out) - (tbl1 * val) - tbl2

    # copy l bytes from out[p] to end of out​
    for i in range(l+1):​
    v = out[p+i]​
    out.append(v)​
    elif ctrl == 0x80:
    val = next(d)<<8​
    val |= next(d)​
    elif ctrl < 0xA0:
    l = ctrl&0x1F​
    p = len(out) - next(d)​
    # copy l+1 bytes from out[p] to end of out​
    for i in range(l+1):​

    v = out[p+i]​
    out.append(v)​
    elif ctrl < 0xC0:
    l = ctrl&0x1F​
    # write l+1 bytes from source to target​
    for i in range(l+1):​
    out.append(next(d))​
    elif ctrl < 0xD0:
    l = ctrl&0xF​
    # write next byte of source to target l+2 times​
    v = next(d)​
    for i in range(l+2):​
    out.append(v)​
    elif ctrl < 0xE0:
    l = ctrl&0xF​
    # write 0 to target l+1 times​
    for i in range(l+1):​
    out.append(0)​
    elif ctrl < 0xF0:
    l = (ctrl&0xF) + 1​
    # Duplicate last byte at target l+1 * 16 times.​
    v = out[len(out)-1]​
    for i in range(l<<4):​
    out.append(v)​
    elif ctrl < 0xFF:
    l = ctrl&0xF​
    # Replicate last byte at target l+1 times.​
    p = len(out)-1​
    for i in range(l+1):​
    v = out[p+i]​
    out.append(v)​
    elif ctrl==0xFF:
    break​
    return out
     
    Last edited: Oct 1, 2012
  8. FireAza

    FireAza Shake! Shake!

    Joined:
    May 31, 2012
    Messages:
    2,003
    Likes Received:
    25
    Wow! Nice work! A shame I don't have a flashcart to play it on, but still, impressive!
     
  9. Zoinkity

    Zoinkity Site Supporter 2015

    Joined:
    Feb 18, 2012
    Messages:
    499
    Likes Received:
    108
    A lot of stuff is loaded by direct access so I can't vouch that this is bug free. Also, never bothered testing if the whole bank is loaded or not.
    (not my best work sadly)
    If it does have a problem I'll fix it for you. I agree, the original voices had a lot more flair to them.

    If it was just the matter of the sound file being switched from english to japanese, that would be easy to script and could even be retained on reset. Honestly, hacking a place for the setting switch would be more involved than just the switch.
    The simple method is to just plop the whole other bank at the end of ROM and add a test+increment for loading from it. A register within the NMIbuffer can track the current sound setting and retain it if you press reset. A super-lame way of switching would be to have it XOR the value each reset, but an in-game setting would be the better solution.
     
  10. HEX1GON

    HEX1GON FREEZE! Scumbag

    Joined:
    May 4, 2011
    Messages:
    9,916
    Likes Received:
    837
    Would any of this change if the game's audio was MP3? Apparently Top Gear Overdrive had MP3 format music, if it's possible to extract that, it would be interesting.
     
  11. Zoinkity

    Zoinkity Site Supporter 2015

    Joined:
    Feb 18, 2012
    Messages:
    499
    Likes Received:
    108
    If you're just replacing audio files, that's as easy as replacing audio files ;*) Sub's sound tool and editor are both capable of swapping the mp3s in PD, and any other title is about as negligable.


    Replacing the audio format is possible. The trouble there is you'll have to do a bit more work:

    • Hack out the original audio routine and replace it with a (most likely modified) mp3 routine you strip from something else.
    • Convert all audio to mp3 format.
    • Redo the lookup system to be able to pull each track on demand.
    • Come up with a workaround to loop your audio the same way the tracker(ish) system works.
    • Oh, and since this game doesn't already use zlib you'll have to hook that too.


    This game uses a simple MML unless I'm mistaken. There's a few titles that use mp3, and there's a couple different interpretters out there.

    The funny part is that mp3 is a bit limitted for general background music but works well for recorded voice and sounds. The reason has to do with how music is used in games, where there's a lead in before the looping segment. High-quality midi is more versatile when you concider it from that angle.

    Can't remember if we ever did Top Gear Overdrive or not. I think Factor 5's mp3s were headerless, but Rare's weren't.
     
sonicdude10
Draft saved Draft deleted
Insert every image as a...
  1.  0%

Share This Page