• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Development: Game Boy Player for FireRed

Jambo51

Glory To Arstotzka
  • 736
    Posts
    15
    Years
    • Seen Jan 28, 2018
    This is a very popular feature in HGSS, with good reason.
    My question is this:

    Would it be worthwhile to attempt to make something similar for FireRed?
    Many people (myself included) have a very strong affinity for the original 8 bit music, and creating such a hack would open up hundreds of alternative uses for the routines used to play music.

    As a proof of concept, I present these 2 youtube videos showing that the FR rom is capable of playing "pure" 8 bit music. (What I mean by this, is that each track heard in these tracks is actual Synth, and not a sample of synth played through the direct tracks.)

    The videos:

    For those wondering how this works, the New Sappy helps immensely.
    Firstly, open the VoiceGroup editor within the new sappy, and navigate to voice 80 and 81 (0x50 and 0x51), and change it to match the following configurations.

    BIG THANKS TO MR. PKMN, who showed me this function of the new sappy, and pointed me in the right direction to make it emulate the square instruments!

    This works with any voicegroup, I just happened to choose that particular one.

    [PokeCommunity.com] Game Boy Player for FireRed

    [PokeCommunity.com] Game Boy Player for FireRed


    Then comes the most complicated part for the simple music. Now we go to 82 (the "wave synth") and edit the wave to match the square wave of the actual Square instrument. This is surprisingly easy to do!

    [PokeCommunity.com] Game Boy Player for FireRed


    This is your basic setup. Remember to repoint the wave to free space, otherwise it'll overwrite the ARM code at the start of the rom, rendering it useless. Then select "Edit Wave..." Modify it so that it looks EXACTLY like this:

    [PokeCommunity.com] Game Boy Player for FireRed


    This makes the wave sound IDENTICAL to the Square instrument. Thus we overcome the lack of 3 synth channels.
    This only affects the "wave synth" of the voicegroup you actually edit, so it's perfectly feasible to create a separate voicegroup specifically for the synth music!

    The next thing we must do, is write some sort of check into the music table selecting routines, to change which table to read based on a variable/flag.

    This is my code for this part of the rom. I had to be slightly imaginative to make this code work, and it will require a host of edits. First of all, the code:

    Code:
    .text
    .align 2
    .thumb
    .thumb_func
    .global gameboyplayerbackgroundroutine
    main:
     add r3, r2, #0x4
     ldr r2, ramtable
     push {r0,r2-r7}
     ldr r0, flag
     bl decrypt
     add r1, r0, #0x0
     pop {r0,r2-r7}
     cmp r1, #0x0
     bne gbp
     ldr r1, normaltable
     b exit
    gbp: ldr r1, gbptable
    exit: lsr r0, r0, #0xD
     add r0, r0, r1
     mov pc, r3
    decrypt: ldr r1, decry
     bx r1
    .align
    ramtable: .word 0x084A329C
    normaltable: .word 0x084A32CC
    gbptable: .word 0x08FFFFFF
    flag:  .word 0x000008F0
    decry:  .word 0x0806E6D1

    Now, there are 5 locations where this code needs to be linked in. Thankfully, it's actually relatively simple to do so!
    Navigate to 0x1DD0F8, 0x1DD124, 0x1DD170, 0x1DD1C4 and 0x1DD1F8 and change the code at ALL of the locations to:
    Code:
     7A 46 XX 49 08 47
    It's XX because the number should always be left unchanged, as it's loading from a pre-determined spot. Finally, replace all previously existing pointers to 0x4A32CC with a pointer to the THUMB routine, remembering to add 1 for thumb of course, and leaving the new pointer in the custom routine.

    Obviously, you should make a new music/SFX table specifically for the GBP music. And make sure the music is in the same slots as the "normal" music. Ie, have the Wild Battle Music in slot 0x12A on both tables etc.

    If you don't have a piece of GBP music for a tune in your game, you can always go the HGSS route and just put a pointer to the "normal" version instead!

    If you correctly pulled this off, the game will show no ill effects of the insertion, and will continue to load music as it should. Feel free to change the flag used should you wish to.

    At this stage, the music can actually be switched, but only by setting/clearing the flag in a script. For this to mimic HGSS's version, we would need to come up with a way to change the music on the fly. In other words, we would need an item which would return the player to the OW from the bag, then run a script which would change the flag/variable, followed by a fadedefault or a writebytetooffset 0x1 0x03000FC2, which would make the normal/gbp music play.

    This routine has a distinct advantage. It gets applied RIGHT from the boot screen of the game. So if the player has the flag set for the GBP, it will play the GBP music right from the boot screen onwards!
     
    Last edited:
    surprised nobody posted in this, but anyway, as it is possible for the game to play 8 bit music, how would you be able to switch between the new music and the old one?
     
    I didn't rip them from Red, no. I'm not aware of any programme which would let me do so either. This will be slightly more complicated than I had thought it would as most songs in RBY and GSC had custom synth for their bass (or main track in the case of New Bark Town).

    It turns out the GBP in HGSS was actually very lazily designed!

    I've managed to write a script which would get executed on leaving the bag from an item which asks if you want to change the music mode. Pn saying yes, it immediately changes the music table, and plays the same song which was previously playing from the second table.

    Obviously, this could be abused for plenty of other things, but the best use I can see is a GBP style use.
     
    I think this idea would be a nice nostalgia effect to all players. Plus for a hack with new music they could include an 8bit remix for a pseudo-nostalgia effect. Aside from the gameboy player implementation I cannot think of any other practical uses for such scripting though, but I definately think this should happen.
     
    I think to increase customisability (Just made that up...), you could set the table offsets to the very end of the ASM, and make it so the variable value looks of an offset in the table, so if the variable is 0x1, it'll look up the second offset. It's easy, and expands the concept. That way specific items could also only trigger specific music tables too.
     
    I thought maybe I could put in a little thing here...Could this also maybe be used for adding instruments to a track, similar how in BW, interacting with different people can cause the background music to have a different track.

    Also, sorry to get kind of off topic, but can someone PM me the link to "New Sappy"? Seems like everyone has it but me...
     
    I thought maybe I could put in a little thing here...Could this also maybe be used for adding instruments to a track, similar how in BW, interacting with different people can cause the background music to have a different track.

    Also, sorry to get kind of off topic, but can someone PM me the link to "New Sappy"? Seems like everyone has it but me...

    I highly doubt it would work this way, but we could probably come up with some clever way of doing it. There's a list of playing tracks somewhere in the RAM. We could directly hack that to add new tracks on the fly.

    I think to increase customisability (Just made that up...), you could set the table offsets to the very end of the ASM, and make it so the variable value looks of an offset in the table, so if the variable is 0x1, it'll look up the second offset. It's easy, and expands the concept. That way specific items could also only trigger specific music tables too.

    It could easily support that, but having multiple music tables would be wasteful IMO, as they take up a large amount of space. Still, if you so wished, there would be no issues with using it. Mines simply uses a flag for simplicity's sake.
     
    Sorry in advance for resurrecting this thread.

    I have two questions about alternate playable tracks, particularly in conjunction with this GB Player patch that I'm using in my hack. They're very different, so it might take more brainpower to get them answered properly.

    DISCLAIMER: I really don't know what I'm talking about when it comes to assembly code. All I can do is assemble it and insert it, along with change a few pointers within it.

    1. Is there a way that this ASM code (for the alternate playlist) can be combined with the ASM code seen in this thread (situational alternate tracks)? Both sets of code change data at offset 0x1DD0F6(8) for different purposes, making them impossible to use in conjunction in their current state. Would it be as simple as repointing a few areas of data to make one routine refer to the other, or would the procedure be more complex?
    2. I've found that I can't simply use Sappy to make alternate songs for a few tunes. For example, if I try to insert the 8-bit version of the Level-Up/Move Learned/Item Found/TM Obtained/pretty-much-everything-in-the-universe jingle (for FR/LG), things will seem to work alright...at first. However, once a Pokémon learns a move at level up, the jingle doesn't replay; there's only silence. It's even worse for the slot machine jingles, where they just won't play regardless of what I do. Any insight on this?
    I appreciate any feedback received from these questions!
     
    Last edited:
    Sorry in advance for resurrecting this thread.

    I have two questions about alternate playable tracks, particularly in conjunction with this GB Player patch that I'm using in my hack. They're very different, so it might take more brainpower to get them answered properly.

    DISCLAIMER: I really don't know what I'm talking about when it comes to assembly code. All I can do is assemble it and insert it, along with change a few pointers within it.

    1. Is there a way that this ASM code (for the alternate playlist) can be combined with the ASM code seen in this thread (situational alternate tracks)? Both sets of code change data at offset 0x1DD0F6(8) for different purposes, making them impossible to use in conjunction in their current state. Would it be as simple as repointing a few areas of data to make one routine refer to the other, or would the procedure be more complex?

    Technically, if you called the variable music switcher first, then called mine, it would work, but there's more to it than that since mines relies on specific code changes at positions in the ROM which would conflict with the variable switcher.

    • I've found that I can't simply use Sappy to make alternate songs for a few tunes. For example, if I try to insert the 8-bit version of the Level-Up/Move Learned/Item Found/TM Obtained/pretty-much-everything-in-the-universe jingle (for FR/LG), things will seem to work alright...at first. However, once a Pokémon learns a move at level up, the jingle doesn't replay; there's only silence. It's even worse for the slot machine jingles, where they just won't play regardless of what I do. Any insight on this?

    I inserted jingles and they worked fine. So that's odd.
     
    Technically, if you called the variable music switcher first, then called mine, it would work, but there's more to it than that since mines relies on specific code changes at positions in the ROM which would conflict with the variable switcher.

    I'm not going to further delve into what you mean by, "but there's more to it than that..." since I wouldn't know what to say about it. Would it seem more viable to make a new batch of code that combines both functions into one or do what it sounds like you're thinking of doing (have one refer to the other)?

    I'm just wondering because it seems unfortunate for people to have to choose between one or the other as far as features in hacks go, but it's kind of understandable in this case.

    I inserted jingles and they worked fine. So that's odd.
    Actually, the two instances I mentioned are the ONLY ones which that happens for. All other jingles (and songs, for that matter) work fine. In your observations, can a new tune just be put in its place through Sappy alone, or does it have to be of a certain length?

    I seriously doubt my second guess of that question because re-assembling the exact same tune for one of those two instances still causes the same problem.
     
    I'm not going to further delve into what you mean by, "but there's more to it than that..." since I wouldn't know what to say about it. Would it seem more viable to make a new batch of code that combines both functions into one or do what it sounds like you're thinking of doing (have one refer to the other)?

    I'm just wondering because it seems unfortunate for people to have to choose between one or the other as far as features in hacks go, but it's kind of understandable in this case.

    I'm certainly capable of combining the two, but personally I think it's a very hatchety way of picking what music you want to play. For example, I've already released hacks for Encounter music and battle music. I understand that sometimes, that doesn't quite suffice (like for one off battle tune changes or something), but I dislike anything which relies too heavily on variables. (If only because variables are unreliable in FR due to their nature of sharing memory space with other functions).

    Actually, the two instances I mentioned are the ONLY ones which that happens for. All other jingles (and songs, for that matter) work fine. In your observations, can a new tune just be put in its place through Sappy alone, or does it have to be of a certain length?

    I seriously doubt my second guess of that question because re-assembling the exact same tune for one of those two instances still causes the same problem.

    In my experience, the jingles play fine, but they get cut short (or the pause after them lasts too long) if their length doesn't match that of the original, but it wouldn't stop it from playing altogether, no. Perhaps the "Song Group" values are relates, since all the fanfares and jingles use 2, 2 for theirs, while all other songs (which I have seen) use 0, 0.

    The song group appears on the assembly page, in case you were confused about that.
     
    I'm certainly capable of combining the two, but personally I think it's a very hatchety way of picking what music you want to play. For example, I've already released hacks for Encounter music and battle music. I understand that sometimes, that doesn't quite suffice (like for one off battle tune changes or something), but I dislike anything which relies too heavily on variables. (If only because variables are unreliable in FR due to their nature of sharing memory space with other functions).

    I completely get that. In fact, it makes sense to me considering that this "GB Player" routine is, essentially, just a more widespread version of the single tune switching routine seen in Shiny Gold. It does seem more useful than single tune switching, though, considering that the games today probably use completely different playlists for day/night tracks (or the poor man's GB Player/Sounds item in HG/SS).

    (If I just angered any DS music hackers out there because of my incorrect notions, I'm sorry. I do intend to check out hacking for games on the system sometime soon.)

    EDIT: I just took a look at your code, and it does seem quite helpful for its stated effect. Of course, it won't help for those one-off situations that you mentioned, especially for scripted Wild Pokémon battles. In that case, it would only negatively affect legendary scripted battles, as standard scripted battles work fine with the "dowildbattle" command. Could a similar routine change which Pokémon get attributed to the legendary music instead of the R/S/E trainer battle music?

    If this question is getting too off-topic, feel free to PM me.

    In my experience, the jingles play fine, but they get cut short (or the pause after them lasts too long) if their length doesn't match that of the original, but it wouldn't stop it from playing altogether, no. Perhaps the "Song Group" values are relates, since all the fanfares and jingles use 2, 2 for theirs, while all other songs (which I have seen) use 0, 0.

    The song group appears on the assembly page, in case you were confused about that.
    Yeah, even considering everything you just said, I'm still having the same issue. I started a new game and raised a Charmander to Level 7. The fanfare didn't replay for the "CHARMANDER learned EMBER!" message. I'm using Sappy mod 17.1 for this. The new music appears in blank data and relates to the same song numbers as the base game counterparts. And the 8-bit tunes take up MUCH less space than the ones used in the standard game; duration doesn't seem to affect a thing, just size.
     
    Last edited:
    This needs to be done in a G/S/C remake...
    You may have noticed from my discussion with Jambo51 above that, from what I can tell, there is currently no "clean" way of having both a GB Player (actually, a complete alternate playlist) and variable (single-) track switching in the same hack. Although it's technically possible to do so, it would be quite messy and, frankly, not worth the headache and acrobatics involved.

    G/S/C (and HG/SS, and fan remakes) make use of alternate battle music (wild Pokémon, trainer, and gym leader) depending on if the player is in Johto or Kanto. From what I understand, the current hacks out there do this by having the game store tracks in variables and switching them out whenever the player switches regions through one of a very limited amount of means. Such code would directly conflict with the GB Player code, making it impossible to have both without making things awfully convoluted.

    It's a shame, really. But I guess that's what HG/SS are for. If anything, someone needs to get to improving the quality of the 8-bit music in those games!
     
    I didn't rip them from Red, no. I'm not aware of any programme which would let me do so either...

    I thought that there were special emulators that could rip them as a .gbs file?
     
    You may have noticed from my discussion with Jambo51 above that, from what I can tell, there is currently no "clean" way of having both a GB Player (actually, a complete alternate playlist) and variable (single-) track switching in the same hack. Although it's technically possible to do so, it would be quite messy and, frankly, not worth the headache and acrobatics involved.

    G/S/C (and HG/SS, and fan remakes) make use of alternate battle music (wild Pokémon, trainer, and gym leader) depending on if the player is in Johto or Kanto. From what I understand, the current hacks out there do this by having the game store tracks in variables and switching them out whenever the player switches regions through one of a very limited amount of means. Such code would directly conflict with the GB Player code, making it impossible to have both without making things awfully convoluted.

    It's a shame, really. But I guess that's what HG/SS are for. If anything, someone needs to get to improving the quality of the 8-bit music in those games!
    Well, the incompatibility of the two comes from the fact that the code Mastermind_X wrote up isn't exactly the best way of handling the music swaps. For example, with a more complex and robust music changer, then having both would be rather easy. If someone would go through all the trouble of making GSC 8-bitish songs in good quality for CrystalDust, then I would certainly put in this feature (and CrystalDust includes the more robust music-swapping code I talked about).
     
    I thought that there were special emulators that could rip them as a .gbs file?
    I wasn't aware of this. However, from what I know, .gbs files aren't in any sort of format that could be made compatible with neither. s files used in Sappy nor MIDI files. Do those .gbs files come in a format that can be read through a text/code editor? Just curious.

    Well, the incompatibility of the two comes from the fact that the code Mastermind_X wrote up isn't exactly the best way of handling the music swaps. For example, with a more complex and robust music changer, then having both would be rather easy. If someone would go through all the trouble of making GSC 8-bitish songs in good quality for CrystalDust, then I would certainly put in this feature (and CrystalDust includes the more robust music-swapping code I talked about).
    Ah, that's why I said it'd be complicated and a bit messy, not impossible. I know it's possible, considering Jambo51 said as such before. Of course, I'm happy to see that you've managed to do so in a relatively sensible manner for CrystalDust!

    As for those 8-bit songs, I might actually be able to make some tracks to suit your purposes! As of right now, I'm remastering my 8-bit songs for FireRed. How, exactly? Well, I've resorted to actually looking at the disassemlbed code (and, in some cases, the RAW code) from the original Red ROM itself. I've found a correlation between the way the GameBoy handles music and how the GBA replicates those functions. Now, all my 8-bit tracks, noise instruments aside, are beginning to sound like exact replicas of the tracks played from the original game itself! They're of much higher quality than what I've most recently made available.

    ...I did have more to say after this, but I found it more appropriate to send it via PM. So, I have!
     
    I wasn't aware of this. However, from what I know, .gbs files aren't in any sort of format that could be made compatible with neither. s files used in Sappy nor MIDI files. Do those .gbs files come in a format that can be read through a text/code editor? Just curious.
    Okay... I've done some searching, and here's what I could come up with for the .gbs files: [link] My whole thought was that maybe this would be a good way to skip any "by ear" problems with songs, but I can't find much good documentation on how they are structured.
    Also on a semirelated note, these links may help with manual music extraction: [link1] [link2]Those should almost definatly be of some use, assuming music extraction is still desired.

    [EDIT1] okay how dumb am I? I looks like the .gbs files are pretty much .gb roms with everything but the music taken out.
     
    Last edited:
    Okay... I've done some searching, and here's what I could come up with for the .gbs files: [link] My whole thought was that maybe this would be a good way to skip any "by ear" problems with songs, but I can't find much good documentation on how they are structured.
    Also on a semirelated note, these links may help with manual music extraction: [link1] [link2]Those should almost definatly be of some use, assuming music extraction is still desired.
    I remember looking at those articles before. I initially discounted them because it didn't look like there was enough in common between how GameBoy and GBA music was structured. However, with a bit of experimentation, I've found that all of those fine details actually can be properly had with .s format music. This requires a ton of voice changes throughout each song, but I now know how to majorly "translate" between the two formats. I'm still confused with how smooth, swift volume rises work (I currently just have the actual volume change, which is actually the "wrong" thing to do for GB Synth tracks) and how to utilize "E8," though.

    Too bad I don't know programming, then I could just make something that would do the laborious job for me!
     
    Last edited:
    Back
    Top