[4.5.X] Bank Switching for Songs and SFX

Knietfeld

Member
I'm here to show you how you can have two banks of music and Sound effects. The Underworld Map uses Bank1A and the Overworld Map uses Bank1B.
It seems like a pretty complex task, but I did a lot of the work for you. I'm pretty confident anyone relatively familiar with NESMaker and Famitracker will be successful following this tutorial.

For this tutorial, all you have to do is download a file, move it to the right place, change five files in Nesmaker's Script Settings, rename a file, change a few labels in that file, comment out one line in that file, and maybe change all the names of all the instruments in a famitracker project. Super easy! And maybe a little tedious.

A Few Things Before We Get Started

Using Overworld/Underworld to determine which music bank to use made sense to me, but if you would rather have a ScreenFlag determine the music bank, the files I provide will probably give you a good framework to build off of. If you're decent with coding you can probably figure it out. You may only need to change the variable that is checked from WarpMap to ScreenFlags00 for example or you may have to dive in and figure out what variables are available for initialization to work. If you figure it out it'd be great if you shared your findings in the comments here. I didn't look into it but I'd be happy to help if anyone asks.

Before doing this, I suggest having your sound effects and your music that will be in the "underworld" map finalized that way you don't have to go through the steps of importing both music files again. After all this is done, changing the music for the Overworld is just like changing the music now, but the Underworld is a bit more tedious, so it'd be nice to only have to do it once. It's not terrible, but doing importing two music files several times in a day is annoying. This is just a suggestion though, I'm sure I'm not the only one here who would prefer to make sure my project can contain the music before I go to the trouble of writing more.

The Easy Part

First, if you haven't already, make a copy of your NESMaker folder and use that from now on for this game. The method I've set up for putting all the scripts in the right place replaces the WarpToScreen macro which will cause problems in other NESMaker projects using the same NESMaker folder. I needed to modify the macro because every time you warp screens it needs to check which music bank to use and I didn't want to modify every script that calls this macro, changing the macro is
easier for both of us.

Follow this link and click the download icon to download my GameEngineData folder.

Open your new copied Nesmaker folder and drop the new GameEngineData folder into NESmaker_4_5_x. It will place all my new scripts in the correct folders for you.
move gameengine.png
Doing this doesn't affect any of your current scripts since all the new ones have different names, except for the WarpToScreen macro.

If you change your mind and want to change back all the scripts, there is a copy of the original WarpToScreen macro in the System folder now, (you would just drop it into the Macros folder to replace the modified one) though it's pretty easy to comment out what I added to WarpToScreen anyway.

Now, you need to change out all the pertinent scripts in Script Settings. All the new scripts are in the same folder as the scripts they will be replacing.

From top going down, the ones to change are:

In System, change NMI to NMI_SecondMusicBank_1A
UpdateScriptSettings1.png
In Banks, change Bank1A and Bank1B to Bank1A_SecondMusicBank_1A and Bank1B_SecondMusicBank_1A.
In Game, change "Initialize" and "Main Game Loop" to the new ones ending in _SecondMusicBank_1A.
UpdateScriptSettings2.png
If you've already edited any of the scripts that my files would replace and you don't want to lose your code, don't worry. I've left comments in my modified scripts and you can find any of my modifications by searching "kn-". just compare your scripts to mine and add in what I changed. I only added a few lines of code in most of these scripts and it shouldn't be hard to add in my stuff. I tried to mark the top and bottom of my main additions. If you've already done something with Bank1A, and hope to just add this code and a little bit of music to some other code you've already added to that bank, just make sure all of my Bank1A stuff comes first. There's one part in NESMaker's code that relies on the first part of Bank 1A and Bank1B being nearly perfect copies of each other to work.

The Part You Have to Work for

As you should expect, you'll need two separate Famitracker projects that already import correctly into NESMaker. One will end up in Bank1A and be useable in Underworld screens, the other will end up in Bank1B and be useable in Overworld screens.

You can use completely different styles of Famitracker projects. They don't need to have the same number of songs or sound effects. They don't need to have the same instruments or even the same number of instruments. If you're game has separate game modes or something and you truly do want everything completely different, I suggest you make sure the file with more songs is the file in Bank1B. I'll explain why later.

But most likely you will want to have the same sound effects and instruments in both the overworld music and the underworld music. You may even want to have some songs available in both maps. However, if you use the same names in both you'll get a bunch of "label already defined" errors when you finally compile the game. To overcome that, you've got to rename a whole bunch of stuff, and it's best to do that before importing anything.

While testing I used the music and sound effects from the 4.5.x tutorials and I just added _1A to everything for my underworld music. I just copied _1A it and pasted it onto every name in the project. Just check out the names in the picture.
Add_1AToEVERYTHING.png
You'll need to do that for everything that is shared across the two maps.

It will be easier for you if you have the same number of songs and sound effects in both maps, and unless you plan on sound effects sounding different in the underworld, you'll want to keep the sound effects in the same order in both files.


Once you've finished editing names and you have your "AwesomeMusicForBank1A.ftm" ready, in Famitracker, click file and "Export Text" then in NESMaker right click Sound, and select "Import Famitracker .txt." If there are no problems with your .txt you can now click "Export and Test asm" and Oh no! You have an error!

OHNObutnotReally.png

But don't worry this is all part of the plan. The compiler can't find Bank 1A's music file, "AllSongs_WithSFX_1A.asm", because you haven't made it yet. While the compiler didn't make your game, it did make it's usual AllSongs_WithSFX file. You just have to go to your newly copied NESMaker folder \NESMaker_4_5_x\GameEngineData\Sound and rename AllSongs_WithSFX to AllSongs_WithSFX_1A. Now it exists.

Open AllSongs_WithSFX_1A and scroll down a bit. You will need to update three list labels to make them become, song_list_1A, sfx_list_1A, and instrument_list_1A. They shouldn't be hard to find. The names have to be exactly that because those are the names you Bank1A sound Engine is looking for.

But before you export and test your game again, import the music you want for Bank1B into NESMaker.
When you test your game again, this music will be written into AllSongs_WithSFX and the Bank1A music will be in AllSongs_WithSFX_1A.

continued in the first comment, I've said too much
 

Attachments

  • ChangeInstrumentLabel.png
    ChangeInstrumentLabel.png
    78.2 KB · Views: 14
  • OHNOAGAIN.png
    OHNOAGAIN.png
    78.4 KB · Views: 13
  • ChangeInstrumentLabel.png
    ChangeInstrumentLabel.png
    78.2 KB · Views: 12
  • ChangeInstrumentListLabel.png
    ChangeInstrumentListLabel.png
    32.6 KB · Views: 13
  • ExtraSoundEffects.png
    ExtraSoundEffects.png
    3.5 KB · Views: 12

Knietfeld

Member
But wait, more errors.
OHNOAGAIN.png
In my example above I forgot to change the list labels that I already told you about, but there are a few other errors you're likely have too.

The best thing to do is keep that box open and use that guide to tell you where your errors are.

I said what my first three errors were in that box, but what is the fourth?

It is in AllSongs_WithSFX.asm line 131. So I open that file and scroll down to that line. It looks like there's a problem with one of my instrument names. Now, if I edit AllSongs_WithSFX.asm it won't change anything because that file is rewritten every time I test a game in NESMaker. My changes have to occur in my _1A variant of that file. So I double click my offending label, drum2_2, press ctrl+F to open the Find box, open my _1A variant and search for that label. Sure enough, I forgot to add _1A to the name in my Famitracker project.
ChangeInstrumentLabel.png

By observing how the other instruments are named I can see that this one ought to be "drum2_1A_2" So I change it, but if I click Find Next in the Find box I see that "drum2_2" is also in my instrument list, so I also need to fix it there.

ChangeInstrumentListLabel.png

Because I only had one error like this, fixing it in AllSongs_WithSFX_1A.asm makes sense. But if you have a handful of errors like that you might as well just delete AllSongs_WithSFX_1A.asm, then go back to Famitracker, update those names, then reimport both music files again. Don't forget to update your Famitracker file anyway, because if you don't you'll have to fix that error every time you decide to update the music in both banks.

There's another set of errors, though. These ones show to be in EXTRA_SFX.asm.

When you "Import Famitracker .txt" in NESMaker it always adds an include at the bottom of AllSongs_WithSFX.asm for EXTRA_SFX.asm. I just went to the very last line of AllSongs_WithSFX_1A.asm and used a ; to comment out the offending line of code. I may be wrong, but I don't think these sound effects are used for anything in NESMaker automatically so it seems ok to comment out. The sfx names are in lists in both of your AllSongs_WithSFX files, so if you change SCR_EXTRA_SOUND_EFFECTS to a blank file in ScriptSettings you get a bunch of errors again. So commenting it out in AllSongs_WithSFX_1A is the easier option.

ExtraSoundEffects.png

If you've used the tool "ft_txt_to_asm" and imported the .asm into NESMaker by clicking "Load Converted Famitracker .asm" the newly created AllSongs_WithSFX file doesn't have .include... at the bottom. So maybe you didn't have that error at all. I didn't play around with that method of importing very much while I was testing this out so I'm not sure I understand the differences at the moment to be of much help but I'd look into it if someone had a question for me.

Hopefully it won't take long to eliminate all the errors. Of course leave a comment if you run into any errors you can't solve and I'll try to help.

Now you can test your game again and it ought to be working!

One More Thing

Test out a screen in the Underworld map and it should play music from Bank1A. However, when you are setting up the music for that screen you will find one more thing you'll want to change in the Famitracker project for the Overworld Music.

NESMaker was made with just one song bank in mind. When setting the song for a screen, it always shows the Bank1B song titles in the drop down menu. This is inconvenient when setting songs in the underworld map. Likewise, if you have less songs in the Overworld Map than in the Underworld map, you won't even get the option of selecting the higher numbered songs. This is why I said you should have the same number of songs in both banks or the number of songs in Bank1B should be greater. If there are only four songs in Bank1B and therefore in the dropdown menu, you will never be able to select songs five, six, or seven to play in the Underworld screens. And since the names are always the Bank1B song names you'll have a hard time choosing the right song in the Underworld.

The solution is simple, you probably already figured it out, but I had to mention it just in case. Just rename the tracks in your Bank1B Famitracker project to include both map's song titles. And if you don't have enough songs in the Overworld map, make some stand-ins. They don't have to be real songs, they just have to meet the requirements of the sound engine and make the right number of songs in the song_list. Then, of course, you make sure to make the titles reflect both map's songs. Reimporting the Bank1B music is just the same as you've always imported music to NESMaker, so deciding to change up the file is really easy.

If you have a discrepancy in the number of sound effects similar to this it doesn't matter as much since usually specific code calls up sound effects, but a similar approach would probably work. In most cases I think people will want the same sound effects in both banks anyway, though.

That's it!

Well, I hope this worked for you and made perfect sense.

This tutorial was mostly made as a response to Jonny's Tutorial Request in the forums so if it's helpful to you he deserves some thanks too. I wasn't planning on using two music banks on the game I'm currently working on (even though I am using two different playstyles so having different banks of music and sound effects makes complete sense... maybe I'll think about it) but he specified what he was trying to do and it sounded like a fun puzzle to figure out. Making this tutorial took longer than solving the puzzle, so I hope it helps a few people.

I hope this can make your game just that little bit more awesome!

If you have questions I'm happy to help when I have time.

Oh, and I guess I'll share a video of my test game working. It's not so impressive because you can't see the banks switching or anything. Bonus points if you recognize the Overworld music!

View: https://youtu.be/xePAmosrDWg
 

TakuikaNinja

Active member
You could've checked the forum's resources section for arranged/optimised versions of the beta version's music made by a certain someone... *wink wink*
 

Jonny

Well-known member
Thank you... trying this out now...

It was going really well, I had only 2 errors from the re-labelling but after that export and text gave me hundreds of 'Can't Determine Address' errors. Not sure where I'm going wrong.

Looks like the errors are all the instruments but I re-labelled them all :(

musicbank.gif

What does Can't determine address mean usually? Maybe this is a separate issue
 
Last edited:

Knietfeld

Member
@Jonny, offhand I don't know what your error is. What's the very first error in your list of errors? Let's see a snapshot of that. Sometimes it's just one thing was wrong and a bunch of stuff after that registers as an error even if it's ok.

I might have just figured it out actually. Are the first two errors Unknown label? If I switch out the Extra SFX script for a blank script in NESMaker's Script Settings I get the same errors. I wonder if for some reason your 1B music doesn't have the include for SCR_EXTRA_SOUND_EFFECTS. I thought it was only not included when using the ft_txt_to_asm tool but maybe I was wrong. If you commented it out in AllSongs_WithSFX_1A.asm then uncomment it and test your game again.
 
Last edited:

Jonny

Well-known member
I think you're right. I'll take look at that. I had taken out SCR_EXTRA_SOUND_EFFECTS while I was attempting to do it myself before I started your tutorial. Thank you.
 

Jonny

Well-known member
Fingers crossed I think I've finally got mine working! I did mostly as written above in the tutorial with a couple of differences. For some reason, in my project I could only get it working this way. Other changes probably and the fact I'd already started messing about with music banks didn't help. I didn't do the music compiling with nesmaker. I used @TakuikaNinja tool instead to sort the files beforehand and I've got a copy of the sound engine in both banks and also kept all the instruments and sfx exactly the same. I also made the amount of tracks the same. All of this is unnecessary if you follow the above tutorial but for some reason this was the only way I could get it to work in my game particularly.

I then set up a check for a screenflag which changes which bank is used and put it in NMI, MainGameLoop and initialization. So far so good! I just need to make a modified warpToScreen as included with @Knietfeld tutorial and add the screenflag check instead of the subroutine stuff. Hopefully that will work. Really happy I'm finally getting somewhere with it! Thanks again.
 

Knietfeld

Member
Awesome @Jonny! Maybe you're already planning on it, but would you mind posting examples of your code changes for using a screenflag instead of warpmap once you get it working? So we can help out anyone who would have trouble doing that?
 

Jonny

Well-known member
Sure... so where 'SwitchBank #$1B' usually is for NMI, Initialization and MainGameLoop I changed it to...
Code:
    LDA ScreenFlags00
    AND #%00000001
    BNE +
    LDA #$1A
    STA temp
    JMP ++   
+
    LDA #$1B
    STA temp
++
    SwitchBank temp
I haven't changed warpToScreen macro yet, I'm not sure if I need to. It seems to work without that change but not fully tested yet.

It really helped to change all the labels in famitracker first, made things a lot easier!
 

SciNEStist

Well-known member
is it possible to do the same thing with game states?

for example:
Code:
LDA gameState
        CMP #$00
        BNE +
        SwitchBank #$1A
            jsr doHandleUpdateMusic_1A
            jmp ++
        +
        SwitchBank #$1B
             JSR doHandleUpdateMusic
        ++   
        ReturnBank
 

SciNEStist

Well-known member
One thing I suggest for anyone wanting to do this: when creating your 2 different music banks, create blank "dummy" versions of the songs for the opposite music bank that contains no actual data/music. That way, the UI will still work and you can select your music with the dropdowns.
 
Quick Question: when your game has DPCM support with most tracks... how does one include the DPCM instruments file? for both Bank1A & Bank1B?

EDIT: well Bank1B still works... but not 1A... the game at least runs!

EDIT 2: so uh... anyone want to figure out how to get DPCM working with this?
Because even if I don't put any DPCM tracks into the 1A bank... it still doesn't work at all
 
Last edited:
Top Bottom