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
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
$09as an example, but bank$0aand 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
TextOffsetsserved as the actual text to be printed in case aNULLis passed as a parameter toGetTextOffsetFromTextID. 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 isHandText, which is used for theNULLcase.
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.