Bucket Mouse
Active member
In the tutorial videos, Joe shows how to use a command in the ASM called TEXT_FREE that reads a text entry from any bank. He writes a HELLO WORLD message in Bank 1A and then writes more code to display it.
This feature is new to 4.5.9, and like most new features, is not fully hooked up yet. As it is, all text entries written in the NESMaker GUI are stored in npcText01.dat, which is compiled into Bank 19. Look in GameEngineData/ScreenData for npcText01 and open it with Notepad+, as we'll be needing it later.
It's possible to rig up NESMaker to store text in two banks, like what was done with the multiple banks music tutorial. But that's a lot of work, and why do it when a workaround already exists? We're going to use TEXT_FREE to cheat the system and store extra text messages anywhere we want.
STEP ONE: USERSCREENBYTES
The first step is to make sure userScreenBytes is active (see THIS tutorial for how to do that). You really need to get the userScreenBytes working as most new tutorials will use them for something.
STEP TWO: DRAWBOX2
The macro that calls the text is called DrawBox. We're going to make a second macro called DrawBox2, which we'll use for TEXT_FREE. Copy-paste this into a Notepad+ file and save it in System/Macros as DrawBox2.asm.
This new macro is much like the original, except it loads text from a different set of tables, which we'll create in a bit.
STEP THREE: ALTER DRAWNPCTEXT
Find the drawNPCtext.asm input script in the Inputs folder. Open it with Notepad+, NOT NESMaker's built-in input script editor. Then save it under a new name, like drawNPCtext-1 or something.
We're going to tell the text button to use the alternate macro if userScreenByte00 is any number other than zero.
Scroll down to near the bottom where the line LDA textHandler is. We're gonna alter that portion so it looks like this:
In NESMaker, replace the old drawNPCtext input script with the new one. First, the new code checks if userScreenByte00 is any number other than zero. If it is, it uses the DrawBox2 macro, but first it adds the Object ID of the NPC you're talking to (1, 2, 3 or 4). After the macro runs, the Object ID number is subtracted to reset things.
STEP FOUR: REDIRECT THE BANK
The part where the bankswitch happens is in another script. Find doDrawText.asm in the Subroutines folder, and search for the line alreadyDrawingText. Then alter that portion like so:
STEP FIVE: BUILD YOUR TEXT LIBRARY
In the tutorial, Joe stored a line of text that said "HELLO WORLD" in Bank 1A. It should actually still be there, and if it's not you can add it:
Time to build the table. Below MyDumbText, put this stuff:
Pay close attention to the way this is written. Always use the < sign in the Lo table and the > sign in the Hi table.
So why'd we enter it three times? It's due to the way the script works. It will ignore userScreenByte00 if it is set to zero. But there has to be a "zero" entry by default, so we have to put something there. The second repeat is due to the addition of the Object ID number, which means it will never read Entry 1 either -- only 2 and onward. After this point you can add more text names without the need to repeat them. Write them in NESMaker's text entry GUI, compile the game, scoop the raw data out of npcText01.dat (which you opened earlier) and paste it into Bank 1A.
Copy the text from npcText01
Paste it into Bank 1A. RENAME the label.
Make it one short word that easily identifies what line of text it is.
Now we don't need the original text entry anymore, so go back to NESMaker's text GUI and delete what you wrote there. Space successfully saved.
Make as many text entries this way as desired. Store them neatly in easily countable rows of 8, like this:
STEP SIX: HOW TO USE IT
Open your overworld and find the screen you want. Once you're seeing that screen, open up Screen Info and observe the User Defined Bytes at the bottom. Now we can use them, specifically the first one:
Make the number of UserScreenByte00 ONE NUMBER LESS THAN the text entry in your custom table that you want NPC #1 to say.
IMPORTANT: any other NPC on the screen will say the next three text entries in the order you have listed them, so list them appropriately.
And that's how to store extra NPC text in a separate bank. With a little modification, this method can be used for Autotext tiles or any other use of text dialogue boxes in NESMaker. The crucial element is the redirect of DrawBox to DrawBox 2. Anywhere you see DrawBox, you can probably use this:
This feature is new to 4.5.9, and like most new features, is not fully hooked up yet. As it is, all text entries written in the NESMaker GUI are stored in npcText01.dat, which is compiled into Bank 19. Look in GameEngineData/ScreenData for npcText01 and open it with Notepad+, as we'll be needing it later.
It's possible to rig up NESMaker to store text in two banks, like what was done with the multiple banks music tutorial. But that's a lot of work, and why do it when a workaround already exists? We're going to use TEXT_FREE to cheat the system and store extra text messages anywhere we want.
STEP ONE: USERSCREENBYTES
The first step is to make sure userScreenBytes is active (see THIS tutorial for how to do that). You really need to get the userScreenBytes working as most new tutorials will use them for something.
STEP TWO: DRAWBOX2
The macro that calls the text is called DrawBox. We're going to make a second macro called DrawBox2, which we'll use for TEXT_FREE. Copy-paste this into a Notepad+ file and save it in System/Macros as DrawBox2.asm.
Code:
MACRO DrawBox2 arg0, arg1, arg2, arg3, arg4
TXA
PHA
TYA
PHA
; arg0 = X value, in metatiles
; arg1 = y value, in metatiles
; arg2 = width, in metatiles
; arg3 = height, in metatiles
; arg4 = must always be #TEXT_FREE
LDA arg0
STA Box_x_origin;arg0_hold
STA temp_boxX
LDA arg1
STA Box_y_origin;arg1_hold
STA Box_y_hold
STA temp_boxY
LDA arg2
STA Box_width; arg2_hold
STA temp_boxWidth
LDA arg3
STA Box_height
STA Box_height_hold
STA temp_boxHeight
;arg3_hold
LDA arg4
;STA ;arg4_hold
STA endDrawBoxAction ;; also serves a text mode.
; CMP #TEXT_FREE
; BNE notTextFree
LDA textQueued
AND #%00000001
BNE skipSettingNewPointer3
LDX userScreenByte0
; CLC
; ADC #$01
LDA freetextTable_lo,x
STA textPointer
LDA freetextTable_hi,x
STA textPointer+1
skipSettingNewPointer3:
JMP activateTextNow
; notTextFree:
;;; check if it is NPC text, if there are any other types.
; LDA arg5
; STA textToWrite
activateTextNow:
LDA Box_x_origin
STA temp_boxX
LDA Box_y_origin
STA Box_y_hold
STA temp_boxY
LDA Box_width
STA temp_boxWidth
LDA Box_height
STA Box_height_hold
STA temp_boxHeight
LDA queueFlags
ORA #%10000000
STA queueFlags
JSR doDrawBox
PLA
TAY
PLA
TAX
ENDM
This new macro is much like the original, except it loads text from a different set of tables, which we'll create in a bit.
STEP THREE: ALTER DRAWNPCTEXT
Find the drawNPCtext.asm input script in the Inputs folder. Open it with Notepad+, NOT NESMaker's built-in input script editor. Then save it under a new name, like drawNPCtext-1 or something.
We're going to tell the text button to use the alternate macro if userScreenByte00 is any number other than zero.
Scroll down to near the bottom where the line LDA textHandler is. We're gonna alter that portion so it looks like this:
Code:
LDA textHandler
BNE +skipNpcText
LDA userScreenByte0
BNE +alternate
DrawBox #BOX_1_ORIGIN_X, #BOX_1_ORIGIN_Y, #BOX_1_WIDTH , #BOX_1_HEIGHT, #TEXT_NPC, npc_text
;;; x
;;; y
;;; width
;;; height
;;; text mode
;#TEXT_NPC pulls from the index in the following argument.
;#TEXT_FREE allows you to just write a label definition in the following argument
; and as long as you're in the right bank, will draw it.
;;; string or index.
+skipNpcText
RTS
+alternate: ; userScreenByte00 loads from Bank 1A
LDA userScreenByte0
ADC Object_id,x
STA userScreenByte0 ; temporarily adds sprite ID to screenbyte number
DrawBox2 #BOX_1_ORIGIN_X, #BOX_1_ORIGIN_Y, #BOX_1_WIDTH, #BOX_1_HEIGHT, #TEXT_FREE
LDA userScreenByte0
SBC Object_id,x ; restores sprite ID to normal for next sprite
STA userScreenByte0
RTS
In NESMaker, replace the old drawNPCtext input script with the new one. First, the new code checks if userScreenByte00 is any number other than zero. If it is, it uses the DrawBox2 macro, but first it adds the Object ID of the NPC you're talking to (1, 2, 3 or 4). After the macro runs, the Object ID number is subtracted to reset things.
STEP FOUR: REDIRECT THE BANK
The part where the bankswitch happens is in another script. Find doDrawText.asm in the Subroutines folder, and search for the line alreadyDrawingText. Then alter that portion like so:
Code:
alreadyDrawingText:
LDA #$00
STA scrollOffsetCounter
;;;;
;;;; EDITED PORTION TO CHANGE BANK WHEN USING TEXTFREE
LDA userScreenByte0
BEQ +
SwitchBank #$1A
JMP ++
+
SwitchBank textBank ;; original line = keep
++
;;;;;; END OF EDITED PORTION
;;;;;;
LDY #$00
STEP FIVE: BUILD YOUR TEXT LIBRARY
In the tutorial, Joe stored a line of text that said "HELLO WORLD" in Bank 1A. It should actually still be there, and if it's not you can add it:
Code:
MyDumbText:
.db _H,_E,_L,_L,_O, _SPACE, _BREAK
.db _W, _O, _R, _L, _D, _END
Time to build the table. Below MyDumbText, put this stuff:
Code:
freetextTable_lo:
.db <MyDumbText, <MyDumbText, <MyDumbText
freetextTable_hi:
.db >MyDumbText, >MyDumbText, >MyDumbText
Pay close attention to the way this is written. Always use the < sign in the Lo table and the > sign in the Hi table.
So why'd we enter it three times? It's due to the way the script works. It will ignore userScreenByte00 if it is set to zero. But there has to be a "zero" entry by default, so we have to put something there. The second repeat is due to the addition of the Object ID number, which means it will never read Entry 1 either -- only 2 and onward. After this point you can add more text names without the need to repeat them. Write them in NESMaker's text entry GUI, compile the game, scoop the raw data out of npcText01.dat (which you opened earlier) and paste it into Bank 1A.
Copy the text from npcText01
Paste it into Bank 1A. RENAME the label.
Make it one short word that easily identifies what line of text it is.
Now we don't need the original text entry anymore, so go back to NESMaker's text GUI and delete what you wrote there. Space successfully saved.
Make as many text entries this way as desired. Store them neatly in easily countable rows of 8, like this:
Code:
freetextTable_lo:
.db <MyDumbText, <MyDumbText, <MyDumbText, <quitit, <kilroy, <tiny, <owl2, <owl3 ; 0-7
.db <owl4, <owl5, <owl7, <owl6, <owlslumlord, <owl8, <cheeto, <chicken ; 8-15
.db <cotton, <barman, <fish, <store, <civilization, <meatsign, <meatball1, <meatball2 ; 16-23
.db <artrat, <sewer, <balloon, <artsign, <cavesign, <switch1, <switch2, <switch3 ; 24-31
.db <batty, <cliffs, <headsign, <head1, <head2, <mansnow
freetextTable_hi:
.db >MyDumbText, >MyDumbText, >MyDumbText, >quitit, >kilroy, >tiny, >owl2, >owl3
.db >owl4, >owl5, >owl7, >owl6, >owlslumlord, >owl8, >cheeto, >chicken
.db >cotton, >barman, >fish, >store, >civilization, >meatsign, >meatball1, >meatball2
.db >artrat, >sewer, >balloon, >artsign, >cavesign, >switch1, >switch2, >switch3
.db >batty, >cliffs, >headsign, >head1, >head2, >mansnow
STEP SIX: HOW TO USE IT
Open your overworld and find the screen you want. Once you're seeing that screen, open up Screen Info and observe the User Defined Bytes at the bottom. Now we can use them, specifically the first one:
Make the number of UserScreenByte00 ONE NUMBER LESS THAN the text entry in your custom table that you want NPC #1 to say.
IMPORTANT: any other NPC on the screen will say the next three text entries in the order you have listed them, so list them appropriately.
And that's how to store extra NPC text in a separate bank. With a little modification, this method can be used for Autotext tiles or any other use of text dialogue boxes in NESMaker. The crucial element is the redirect of DrawBox to DrawBox 2. Anywhere you see DrawBox, you can probably use this:
Code:
LDA userScreenByte0
BNE +alternate
DrawBox #BOX_1_ORIGIN_X, #BOX_1_ORIGIN_Y, #BOX_1_WIDTH, #BOX_1_HEIGHT, #TEXT_NPC, screenText
RTS
+alternate:
DrawBox2 #BOX_1_ORIGIN_X, #BOX_1_ORIGIN_Y, #BOX_1_WIDTH, #BOX_1_HEIGHT, #TEXT_FREE
RTS
Last edited: