[4.5.9] TEXT_FREE Made Easy! (for Text Heavy Games)

crazygrouptrio

Active member
TEXT_FREE has been a wonky portion of NESmaker, and others have struggled or come up with some pretty out there workarounds. But, I have cracked the code (as it were) to simplify it and make it actually usable without using tons of space, controlling it with a single variable. It's fairly simple, but requires some setting up, so let's get started!

1. Create this variable in User Variables. We will use it to control what text we are going to display.
Code:
manualText

2. Go to your DrawBox macro, and comment out these lines (48 to 55):
Code:
    CMP #TEXT_FREE
    BNE notTextFree
        ;    LDA textQueued
        ;    AND #%00000001
        ;    BNE skipSettingNewPointer3
        ;        LDA #<arg5
        ;        STA textPointer
        ;        LDA #>arg5
        ;        STA textPointer+1
        ;    skipSettingNewPointer3:
            JMP activateTextNow
This is the portion that decides what TEXT_FREE to draw in Macro, but we don't want that. We want to decide elsewhere. So we remove it from the Macro.

3. Select a bank to store all of your text and all the code to write the text. We're using Bank #$1A as an example since it's empty from the start. It will be up to you how you summon the code, but it will require you switch to your text bank to use it.

4. Now stick this bit of code in your bank (in a subroutine or the bank itself):
Code:
doManualText:
;;;; This bit by Dale Coop to prevent multiple text inputs ;;;;;;;;;;;
;; checking if the text box is already displayed
LDA gameStatusByte
AND #%00000001
BEQ +continue:
    ;;; we also check if text box is about to be drawn / or currently drawing
    LDA textQueued
    AND #%00000011
    BEQ +skip
        JMP +continue
    +skip:
        RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+continue:
LDA #$1A ; YOUR BANK HERE
STA textBank
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LDA manualText
CMP #$00
BNE +
        LDA #<YourLabelHere1
        STA textPointer
        LDA #>YourLabelHere1
        STA textPointer+1
        JMP +doDrawManualText
+
CMP #$01
BNE +
        LDA #<YourLabelHere2
        STA textPointer
        LDA #>YourLabelHere2
        STA textPointer+1
        JMP +doDrawManualText
+
;;; add more here
RTS
+doDrawManualText
DrawBox #5, #11, #10, #3, #TEXT_FREE, #$00 ;;; use your own values for the text box location and size, these are just examples
RTS
This sets up the text box, tells it what bank we're using for text, then checks manualText for what text tables to load up, then jumps to a single instance of the macro that all free text will use. Replace the tables with your own labels, and add more at the end following the same format.

5. Finally, we need to actually put in the text we're writing. Below the last bit of code, under the RTS, put in your text in this format:
Code:
YourLabelHere1:
    .db _Y,_O,_U,_R, _SPACE, _L,_A,_B,_E,_L, _SPACE, _H,_E,_R,_E, _SPACE, _O,_N,_E, _PERIOD, _END

YourLabelHere2:
   .db _Y,_O,_U,_R, _SPACE, _L,_A,_B,_E,_L, _SPACE, _H,_E,_R,_E, _SPACE, _T,_W,_O, _PERIOD, _END

And that's it! To use, all you need to do is set up a method that loads a variable into manualText, then JMP to doManualText in your text bank, and it will display that text! Pretty simple right?

For an example, you can write an input code like this:
Code:
LDA #$01
STA manualText
SwitchBank #$1A
JSR doManualText
ReturnBank
RTS
And it will display the 2nd free text!

Hope this helps you all who want to have text heavy games! Happy texting!
 

Mihoshi20

Member
You can do something a little similar to this to get more End of Text Actions. You won't be able to easily call them from the Text editor in the tool but you can manipulate the engine outside of it to invoke new key words to use and their effects. Look inside the doDrawText.asm and you'll find the section detailing the End of Text Action routines and from there you can add new ones. Just remember to also add the keyword to constants with a hex value. I'll likely be making use of this manual text routine as it'll making using custom end of text actions easier to activate.

I used custom keywords in a yet unreleased game to show character portraits while a character was talking. Invoking the keyword at the beginning of the text to display the portrait sprites. This works similar to how the USER_0 etc keywords work.
 
Last edited:

Bucket Mouse

Active member
Yeah, this does look simpler than my version. Do you not need to write tables like this anymore?

Code:
freetextTable_lo:
    .db <sun, <sun, <blackhole, <waffle, <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, <tree, <hansyeti ; 32-39
    .db <yetibro, <yeti, <svenson, <valley1, <valley2, <valley3, <valley4, <screen ; 40-47
    .db <mayor, <walkins, <chickend1, <chickend2

freetextTable_hi:
    .db >sun, >sun, >blackhole, >waffle, >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, >tree, >hansyeti
    .db >yetibro, >yeti, >svenson, >valley1, >valley2, >valley3, >valley4, >screen
    .db >mayor, >walkins, >chickend1, >chickend2

I use one of the UserScreenBytes to indicate what the alternate text is. That's still a good idea.
 

JamesNES

Well-known member
Yeah, this does look simpler than my version. Do you not need to write tables like this anymore?

Code:
freetextTable_lo:
    .db <sun, <sun, <blackhole, <waffle, <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, <tree, <hansyeti ; 32-39
    .db <yetibro, <yeti, <svenson, <valley1, <valley2, <valley3, <valley4, <screen ; 40-47
    .db <mayor, <walkins, <chickend1, <chickend2

freetextTable_hi:
    .db >sun, >sun, >blackhole, >waffle, >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, >tree, >hansyeti
    .db >yetibro, >yeti, >svenson, >valley1, >valley2, >valley3, >valley4, >screen
    .db >mayor, >walkins, >chickend1, >chickend2

I use one of the UserScreenBytes to indicate what the alternate text is. That's still a good idea.

If you do a table like that you can LDX manualText into temp16 and skip all the CMPs
 

Luxnolucas

New member
Hello again, I have another issue. I used this method to display text when I press A. The text appears, but when I press A again, sprites from the tile layout appear instead of the text. Does anyone have any clues on where the issue might be coming from? Thank you.
 
Top Bottom