[4.5.9] Move your Inputs out of the Static Bank

JamesNES

Well-known member
NES Maker puts all your button scripts into the static bank by default, which it really doesn't need to do 99% of the time. With a bit of messing around we can put them all into an empty bank and free up that precious space in 1F.

I'm going to use Bank 1A as that's blank from the start, but you can use any bank of course.

Part One - Moving the Input Read Script

First, in MainGameLoop.asm, we're going to find:

Code:
JSR doHandleInputReads

which is around line 42. Since we're moving our input reads to bank 1A, we just need to tell it to be in that bank first so we change it to:

Code:
        SwitchBank #$1A
            JSR doHandleInputReads
        ReturnBank

Next, in LoadAllSubroutines.asm, find these two lines:

Code:
.include ROOT\Game\Subroutines\doHandleInputReads.asm

;;;further down
.include "GameData\DataBank01_Includes.asm"

Cut and paste them straight in Bank1A.asm. In 1A by default there's some random leftover stuff you can just delete.

If you open up DataBank01_Includes.asm you'll see that it's all your input scripts. So now the code for reading inputs and the input scripts are in a new bank, we need to do few fiddly things so it doesn't keep

Now we load up Subroutines\doHandleInputReads.asm and remove a bunch of bank switches that we don't need any more (and didn't need in the first place). It looks like NES Maker was originally go to be set up to have input scripts in different banks but wasn't fully implemented.

At line 66 there's a bankswitch, we can just delete that:

Code:
    LDy tempBank
    JSR doBankswitchY

Next there are three instances of:

Code:
    LDA TargetScriptBank,y
    STA temp

  
    SwitchBank temp

Which have to be deleted.

And last there are several uses of ReturnBank through the file that need to be deleted.

Part Two - Fixing the Jump Script

(You can skip this if your game doesn't have jumping)

Now, if you compile and load your game it should initially appear to be all done. Left and right will work, but if you try and jump, it'll crash. This is because in the default jump script, there's a switch to Bank 1C to get info like the player's height:

Code:
    SwitchBank #$1C
    LDY Object_type,x
    LDA ObjectBboxTop,y
    CLC
    ADC ObjectHeight,y
    sta temp2
  
    LDA Object_x_hi,x
    CLC
    ADC ObjectBboxLeft,y
    STA temp
    JSR getPointColTable

  ;;there are more further down the script too

These are all constant, they only change when you make changes in the character editor in NES Maker itself. So you can just replace them with numbers.

1656807553697.png

Using values from your character editor the code above becomes:

Code:
    LDA #$0F;; top + height
    sta temp2
  
    LDA Object_x_hi,x
    CLC
    ADC #$02
    STA temp
    JSR getPointColTable

At the bottom of the script is somewhere you need to use jump speed values, these are translated from the editor differently. To find out what values you're using for that, you can open up GameEngineData\ScreenData\ObjectData\monsterObjectStartJumpSpeedLo.dat and monsterObjectStartJumpSpeedHi.dat. If your player object is your first object, their value will be the first in the tables:

1656807603743.png

Also delete the ReturnBank at the end of the file. So with everything changed, my jump script now looks like this:

Code:
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Only can jump if the place below feet is free.
 

    LDA #$0F
    sta temp2
  
    LDA Object_x_hi,x
    CLC
    ADC #$02
    STA temp
    JSR getPointColTable
  
    LDA Object_y_hi,x
    CLC
    ADC #$02
    CLC
    ADC temp2
    STA temp1
  
    CheckCollisionPoint temp, temp1, #$01, tempA ;; check below feet to see if it is solid.
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
    BNE +checkMore
       JMP +doJump
    +checkMore
  
    CheckCollisionPoint temp, temp1, #$07, tempA ;; check below feet to see if it is jumpthrough platform.
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
    BNE +checkMore
        JMP +doJump
    +checkMore
     CheckCollisionPoint temp, temp1, #$09, tempA ;; check below feet to see if it is prize block .
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
    BNE +checkMore
        JMP +doJump
    +checkMore
    CheckCollisionPoint temp, temp1, #$0A, tempA ;; check below feet to see if it is ladder.
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
     BNE +dontDoJump
          JMP  +doJump
        +dontDoJump
            ;; check second point.
        LDA #$0C
        CLC
        ADC temp
        STA temp
        JSR getPointColTable
        CheckCollisionPoint temp, temp1, #$01, tempA ;; check below feet to see if it is solid.
                                            ;;; if it is (equal), can jump.
                                            ;;; if not, skips jumping.        
        BEQ +doJump
      
        CheckCollisionPoint temp, temp1, #$07, tempA ;; check below feet to see if it is jumpthrough platform.
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
        BEQ +doJump
        CheckCollisionPoint temp, temp1, #$09, tempA ;; check below feet to see if it is jumpthrough platform.
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
        BEQ +doJump
        CheckCollisionPoint temp, temp1, #$0A, tempA ;; check below feet to see if it is ladder.
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
        BEQ +doJump
            JMP +skipJumping
+doJump:
    TXA
    STA temp ;; assumes the object we want to move is in x.
    PlaySound #sfx_thump

    LDA #$E0
    EOR #$FF
    STA Object_v_speed_lo,x
    LDA #$03
    EOR #$FF
    STA Object_v_speed_hi,x
      
    TXA
    STA temp ;; assumes the object we want to move is in x.
 ;  change the object's action so that he is in jump mode.

+skipJumping:
  
    RTS

And that does it. The jump script is the only I've seen getting data from other banks, but there might be something else out there. I did this a few months ago and haven't struck any issues yet, but your mileage may vary.

I've attached a zip with the changed asm files in it for reference. I did this on a new install of NES Maker so there shouldn't be anything else changed in there.

Extra Bit

Was messing around with some stuff today (I want more than eight states), and realised you can move
Code:
.include "GameData\ScriptTables.asm"

out of base.asm and put it into the same bank as where you moved your input scripts to. It saves a varying amount of space depending on how many scripts you have, but for me it was like 2% of the static bank. Nothing to sniff at.
 

Attachments

  • doHandleInputReads.zip
    3.7 KB · Views: 37
Last edited:
NES Maker puts all your button scripts into the static bank by default, which it really doesn't need to do 99% of the time. With a bit of messing around we can put them all into an empty bank and free up that precious space in 1F.

I'm going to use Bank 1A as that's blank from the start, but you can use any bank of course.

Part One - Moving the Input Read Script

First, in MainGameLoop.asm, we're going to find:

Code:
JSR doHandleInputReads

which is around line 42. Since we're moving our input reads to bank 1A, we just need to tell it to be in that bank first so we change it to:

Code:
        SwitchBank #$1A
            JSR doHandleInputReads
        ReturnBank

Next, in LoadAllSubroutines.asm, find these two lines:

Code:
.include ROOT\Game\Subroutines\doHandleInputReads.asm

;;;further down
.include "GameData\DataBank01_Includes.asm"

Cut and paste them straight in Bank1A.asm. In 1A by default there's some random leftover stuff you can just delete.

If you open up DataBank01_Includes.asm you'll see that it's all your input scripts. So now the code for reading inputs and the input scripts are in a new bank, we need to do few fiddly things so it doesn't keep

Now we load up Subroutines\doHandleInputReads.asm and remove a bunch of bank switches that we don't need any more (and didn't need in the first place). It looks like NES Maker was originally go to be set up to have input scripts in different banks but wasn't fully implemented.

At line 66 there's a bankswitch, we can just delete that:

Code:
    LDy tempBank
    JSR doBankswitchY

Next there are three instances of:

Code:
    LDA TargetScriptBank,y
    STA temp

  
    SwitchBank temp

Which have to be deleted.

And last there are several uses of ReturnBank through the file that need to be deleted.

Part Two - Fixing the Jump Script

(You can skip this if your game doesn't have jumping)

Now, if you compile and load your game it should initially appear to be all done. Left and right will work, but if you try and jump, it'll crash. This is because in the default jump script, there's a switch to Bank 1C to get info like the player's height:

Code:
    SwitchBank #$1C
    LDY Object_type,x
    LDA ObjectBboxTop,y
    CLC
    ADC ObjectHeight,y
    sta temp2
  
    LDA Object_x_hi,x
    CLC
    ADC ObjectBboxLeft,y
    STA temp
    JSR getPointColTable

  ;;there are more further down the script too

These are all constant, they only change when you make changes in the character editor in NES Maker itself. So you can just replace them with numbers.

View attachment 6329

Using values from your character editor the code above becomes:

Code:
    LDA #$0F;; top + height
    sta temp2
  
    LDA Object_x_hi,x
    CLC
    ADC #$02
    STA temp
    JSR getPointColTable

At the bottom of the script is somewhere you need to use jump speed values, these are translated from the editor differently. To find out what values you're using for that, you can open up GameEngineData\ScreenData\ObjectData\monsterObjectStartJumpSpeedLo.dat and monsterObjectStartJumpSpeedHi.dat. If your player object is your first object, their value will be the first in the tables:

View attachment 6330

Also delete the ReturnBank at the end of the file. So with everything changed, my jump script now looks like this:

Code:
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Only can jump if the place below feet is free.
 

    LDA #$0F
    sta temp2
  
    LDA Object_x_hi,x
    CLC
    ADC #$02
    STA temp
    JSR getPointColTable
  
    LDA Object_y_hi,x
    CLC
    ADC #$02
    CLC
    ADC temp2
    STA temp1
  
    CheckCollisionPoint temp, temp1, #$01, tempA ;; check below feet to see if it is solid.
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
    BNE +checkMore
       JMP +doJump
    +checkMore
  
    CheckCollisionPoint temp, temp1, #$07, tempA ;; check below feet to see if it is jumpthrough platform.
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
    BNE +checkMore
        JMP +doJump
    +checkMore
     CheckCollisionPoint temp, temp1, #$09, tempA ;; check below feet to see if it is prize block .
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
    BNE +checkMore
        JMP +doJump
    +checkMore
    CheckCollisionPoint temp, temp1, #$0A, tempA ;; check below feet to see if it is ladder.
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
     BNE +dontDoJump
          JMP  +doJump
        +dontDoJump
            ;; check second point.
        LDA #$0C
        CLC
        ADC temp
        STA temp
        JSR getPointColTable
        CheckCollisionPoint temp, temp1, #$01, tempA ;; check below feet to see if it is solid.
                                            ;;; if it is (equal), can jump.
                                            ;;; if not, skips jumping.        
        BEQ +doJump
      
        CheckCollisionPoint temp, temp1, #$07, tempA ;; check below feet to see if it is jumpthrough platform.
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
        BEQ +doJump
        CheckCollisionPoint temp, temp1, #$09, tempA ;; check below feet to see if it is jumpthrough platform.
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
        BEQ +doJump
        CheckCollisionPoint temp, temp1, #$0A, tempA ;; check below feet to see if it is ladder.
                                        ;;; if it is (equal), can jump.
                                        ;;; if not, skips jumping.
        BEQ +doJump
            JMP +skipJumping
+doJump:
    TXA
    STA temp ;; assumes the object we want to move is in x.
    PlaySound #sfx_thump

    LDA #$E0
    EOR #$FF
    STA Object_v_speed_lo,x
    LDA #$03
    EOR #$FF
    STA Object_v_speed_hi,x
      
    TXA
    STA temp ;; assumes the object we want to move is in x.
 ;  change the object's action so that he is in jump mode.

+skipJumping:
  
    RTS

And that does it. The jump script is the only I've seen getting data from other banks, but there might be something else out there. I did this a few months ago and haven't struck any issues yet, but your mileage may vary.

I've attached a zip with the changed asm files in it for reference. I did this on a new install of NES Maker so there shouldn't be anything else changed in there.
This "might" help me free up space man! Thanks!
 

Jonny

Well-known member
I'm glad I read this as there WAS indeedy something I did wrong. For doHandleInputReads.asm I thought I needed to change TargetScriptBank,y to the new bank not just remove it alltogether so will go ahead and comment that out.

So much space for activities in 1F now :)
 

drexegar

Member
Does moving the inputs have a significant slow down with bankswitching on every press? Or its pretty small?
 

JamesNES

Well-known member
Does moving the inputs have a significant slow down with bankswitching on every press? Or its pretty small?
Bankswitching has virtually no effect on speed! So you can go nuts with it. Just look at the macro, takes almost nothing
 
okay so long story short JameNES I followed your tutorial and it WORKS! but with one issue...
despite it saving loads of space I need in the main bank... sometimes the game will run the input scripts regardless of player input
here's a video describing what I mean:
View: https://youtu.be/3f1P0uFP-Yc


Help?
(also I know this isn't my game dev channel but it's there for the newer private videos I make)
 

TakuikaNinja

Active member
Does the music use DPCM by any chance? It can corrupt inputs (yes, really - this hardware fault was fixed on PAL systems). If this is the case, you should replace the controller polling script with a double read version instead: 2-player double read routine
 
Does the music use DPCM by any chance? It can corrupt inputs (yes, really - this hardware fault was fixed on PAL systems). If this is the case, you should replace the controller polling script with a double read version instead: 2-player double read routine
It uses DPCM yeah but I wanna move my inputs outta the static bank
EDIT: I TRIED IT AND IT FIXED IT... THANK YOU!
 
Last edited:

SciNEStist

Well-known member
My Jump script uses a little more info from other banks, So My method (thanks to the advice of JamesNES and others in discord) for fixing it went a little different.

Step 1: Remove the switchbank and returnbank lines from the jump script, as described above

step 2: Search and replaced ALL instances of the following (if you have them)

ObjectJumpSpeedHi
ObjectJumpSpeedLo
ObjectBboxTop
ObjectBboxLeft
ObjectHeight
ObjectWidth

Replace them with these, respectively

PlayerJumpSpeedHi
PlayerJumpSpeedLo
PlayerBboxTop
PlayerBboxLeft
PlayerHeight
PlayerWidth

Step 3: Go into the Bankdata\Bank1E.asm (In my case, I switched to bank 1E, you will want to edit whatever bank you are putting the inputs into)
And add these lines:

Rich (BB code):
PlayerJumpSpeedLo:
    .include "ScreenData\ObjectData\monsterObjectStartJumpSpeedLo.dat"
PlayerJumpSpeedHi:
    .include "ScreenData\ObjectData\monsterObjectStartJumpSpeedHi.dat"   
PlayerHeight:
    .include "ScreenData\ObjectData\ObjectHeight.dat"
PlayerWidth:
    .include "ScreenData\ObjectData\ObjectWidth.dat"
PlayerBboxTop:
    .include "ScreenData\ObjectData\ObjectBboxTop.dat"
PlayerBboxLeft:
    .include "ScreenData\ObjectData\ObjectBboxLeft.dat"

Now every time you create your game, the tables of the relevant data will be copied a 2nd time into your new bank and accessible in your input scripts. I know this somewhat diminishes the space savings, but it was the best option I could think of that didnt require going in to every code and re-editing all the values manually every time you make a change.
 

9Panzer

Well-known member
Good god @JamesNES I kinda skipped over this last year because I assumed that it wouldn't be alot of space that the inputs freed up .... god damn I was wrong. Thank you again! If it wasn't for you must of us wouldn't be able to pull of what we do!
 
Good god @JamesNES I kinda skipped over this last year because I assumed that it wouldn't be alot of space that the inputs freed up .... god damn I was wrong. Thank you again! If it wasn't for you must of us wouldn't be able to pull of what we do!
correct! can't even fathom how my in-progress strat game could survive without stuff like this!
 

reddoc

New member
Hello, I am reading this thread, And something I don't understand, is that in my project, when looking in script setting, I cannot find Bank 1F, the last one is Bank 1E.

What did I missed ?
 

dale_coop

Moderator
Staff member
Bank1F is the static bank... it means there is no bank script file for it.
All the code that is not stored in the other banks is in the static bank.
That bank is full of code, and by default in nesmaker, there is not much space available for all your own code. So, when you decide to add more code, you will have to clean up some space (by moving some code out from the static bank).
If you don't do that, the bank will be full and you will have an error when compilming the project.
 
Saved a lot of space!
But having some trouble with some of my inputs-scripts afterwards unfortunatly. (They did work before moving banks.)

Looking at "DataBank01_Includes.asm" the first scripts work fine,
but when i use whatever inputscript that gets set to "Script10:" or above, the game instantly freezes and crashes.

(If i move the non-working input-asseblycode to another earlyer .asm file, and replace that code,
for example "script08:" (my paus-script in that .asm file normally) it works the correct way there.)

It seems to me like the scripts higher than "Script0f:" in the "DataBank01_Includes.asm" does not switch banks correctly??
 
Thanks for the tip Dale.
I make safty-copys of the Nesmaker-folder regulary so it is easy to go back and retry.
I downloaded and replaced the "doHandleInputReads.asm" from the zip-file again, so that i am sure that it is the correct one i am using.

Unfortunattly it did not solve the problem.
Done this 3 times from backup. It seems it is the last two scripts in "DataBank01_Includes.asm" that causes problems.
The first times it was a warpToScreen-inputscript and my healing-inputScript

The last time i had optimized my inputscripts so i had less .asm files. (I fused my throw Barrol-script and throwWoodenBox-script into one and removed the warp-script) But then the Healing-inputscript and the previously working "hammerBrother-projectile"-inputscript started causing the "invalid OP code crashes" in the emulater instead.

Perhaps this is not working together with some of the other tutorials i have implimented in my project, or i have done something funky somewhere in the nesmaker scripts myself.
 
Last edited:
Top Bottom