Skip to content
ElectroDeoxys edited this page Aug 19, 2024 · 4 revisions

In this tutorial we'll go through how to add new text. As an example, we'll add "Hello world!".

Contents

  1. Add text pointer and text data
  2. Move text offsets to their own bank
  3. Add empty text entry

1. Add text pointer and text data

Firstly we need to add an entry to the end of the text offsets list. Edit src/text/text_offsets.asm:

 TextOffsets::
 	...
 	textpointer GamblerDescription                                 ; 0x0bab
 	textpointer RecycleName                                        ; 0x0bac
 	textpointer RecycleDescription                                 ; 0x0bad
+	textpointer HelloWorldText

Next we add the actual text in one of the text files. "Text 13" has space in it, so we'll use it. Edit src/text/text13.asm:

 RecycleDescription:
 	text "Flip a coin. If heads, put a card"
 	line "in your discard pile on top of your"
 	line "deck."
 	done

+ HelloWorldText:
+ 	text "Hello world!"
+ 	done
+

If you follow these instructions, you'll find that you get a bank overflow with the following message:

error: src/text.asm(6) -> src/text/text1.asm(1152):
    Section 'Text 1' grew too big (max size = 0x4000 bytes, reached 0x4003).

This means that we added too much data to a single bank and need to move things around.

2. Move text offsets to their own bank

As a short term solution we can remove unused text and get some bytes worth of space. But we can do some small changes to get a much better and longer term solution. We can see that the text offsets are in the same section as the start of the text data:

SECTION "Text 1", ROMX
INCLUDE "text/text_offsets.asm"
INCLUDE "text/text1.asm"

This means that if we add a new entry to TextOffsets then we are also robbing space from "Text 1", even if our text data is in some other bank. We can separate the offsets from the data and give it its own bank section. For this, edit src/text.asm:

 INCLUDE "macros.asm"
 INCLUDE "constants.asm"
 
+SECTION "Text Offsets", ROMX
+ INCLUDE "text/text_offsets.asm"
+
 SECTION "Text 1", ROMX
-INCLUDE "text/text_offsets.asm"
 INCLUDE "text/text1.asm"

We've put the offset pointers to their own section. Next we will signal to the linker that we want this section to go to its own bank. Edit src/layout.link:

 ROMX $07
 	"Booster Packs"
 ROMX $08
 	"AI Logic 2"
+ROMX $09
+	"Text Offsets"
 ROMX $0b
 	"Effect Functions"
 ROMX $0c

Here we used bank $09 as an example, but bank $0a and others are also empty and could be used as well.

Now bank $09 has all the text pointers, and because it's an empty bank, we will have all the space we will realistically need. Next we just need to tweak some things to accomodate this bank change. Edit src/home/print_text.asm:

 GetTextOffsetFromTextID::
	...
 	rla
 	rl h
 	rla
-	add BANK(TextOffsets)
+	add BANK("Text 1")
 	call BankswitchROM
 	res 7, d
 	set 6, d ; $4000 ≤ de ≤ $7fff

Finally, modify the textpointer macro in src/macros/data.asm:

 MACRO textpointer
-	dw ((\1 + ($4000 * (BANK(\1) - 1))) - (TextOffsets + ($4000 * (BANK(TextOffsets) - 1)))) & $ffff
-	db ((\1 + ($4000 * (BANK(\1) - 1))) - (TextOffsets + ($4000 * (BANK(TextOffsets) - 1)))) >> 16
+	dw ((\1 + ($4000 * (BANK(\1) - 1))) - (STARTOF("Text 1") + ($4000 * (BANK("Text 1") - 1)))) & $ffff
+	db ((\1 + ($4000 * (BANK(\1) - 1))) - (STARTOF("Text 1") + ($4000 * (BANK("Text 1") - 1)))) >> 16
 	const \1_
 	EXPORT \1_

3. Add empty text entry

Due to technical reasons, now we have to explicitly handle the case where we need to show an empty text (text ID NULL). For that we simply add new text to src/text/text1.asm:

+NullText:
+       done
+
 HandText:
        text "Hand"
        done

The reason the null text ID no longer works is that the first entry in TextOffsets served as the actual text to be printed in case a NULL is passed as a parameter to GetTextOffsetFromTextID. Since this entry is just $00, then the string is terminated immediately. This no longer works because the first text in the text ROM bank is HandText, which is used for the NULL case.

Here NullText is just an empty string with a terminating byte. Now edit src/text/text_offsets.asm:

-       const_def 1
+       const_def

 TextOffsets::
-       dwb $0000, $00                                                 ; 0x0000
+       textpointer NullText                                           ; 0x0000
        textpointer HandText                                           ; 0x0001
        textpointer CheckText                                          ; 0x0002
        textpointer AttackText                                         ; 0x0003

With all that done, now you can add text IDs and not worry about potential bank overflows.