Add a new text scrolling speed - pret/pokecrystal GitHub Wiki
This tutorial details how to add an additional text speed option to the options screen. As an example we'll implement an option for instant text.
- Define wram constant
- Add instant text to options
- Fix text speed while holding A or B
- Fix
<SCROLL>
command
Edit constants/wram_constants.asm:
; wOptions1::
DEF TEXT_DELAY_MASK EQU %111
const_def 4
const NO_TEXT_SCROLL ; 4
const STEREO ; 5
const BATTLE_SHIFT ; 6
const BATTLE_SCENE ; 7
+DEF TEXT_DELAY_NONE EQU %000 ; 0
DEF TEXT_DELAY_FAST EQU %001 ; 1
DEF TEXT_DELAY_MED EQU %011 ; 3
DEF TEXT_DELAY_SLOW EQU %101 ; 5
As you can see we defined TEXT_DELAY_NONE
as 0, which will print all characters with 0 frame delay.
Edit engine/menus/options_menu.asm:
.Pointers:
dw Options_TextSpeed
...
const_def
const OPT_TEXT_SPEED_FAST ; 0
const OPT_TEXT_SPEED_MED ; 1
const OPT_TEXT_SPEED_SLOW ; 2
+ const OPT_TEXT_SPEED_NONE ; 3
Options_TextSpeed:
call GetTextSpeed
ldh a, [hJoyPressed]
bit D_LEFT_F, a
jr nz, .LeftPressed
bit D_RIGHT_F, a
jr z, .NonePressed
ld a, c ; right pressed
- cp OPT_TEXT_SPEED_SLOW
+ cp OPT_TEXT_SPEED_NONE
jr c, .Increase
...
.LeftPressed:
ld a, c
and a
jr nz, .Decrease
- ld c, OPT_TEXT_SPEED_SLOW + 1
+ ld c, OPT_TEXT_SPEED_NONE + 1
This will make it cycleable in the options menu but it won't actually work quite yet. We still need to define its string and load the correct previous & next value into registers, otherwise it won't display the selected value correctly.
.Strings:
; entries correspond to OPT_TEXT_SPEED_* constants
dw .Fast
dw .Mid
dw .Slow
+ dw .None
.Fast: db "FAST@"
.Mid: db "MID @"
.Slow: db "SLOW@"
+.None: db "NONE@"
GetTextSpeed:
; converts TEXT_DELAY_* value in a to OPT_TEXT_SPEED_* value in c,
; with previous/next TEXT_DELAY_* values in d/e
ld a, [wOptions]
and TEXT_DELAY_MASK
cp TEXT_DELAY_SLOW
jr z, .slow
cp TEXT_DELAY_FAST
jr z, .fast
+ cp TEXT_DELAY_NONE
+ jr z, .none
; none of the above
ld c, OPT_TEXT_SPEED_MED
lb de, TEXT_DELAY_FAST, TEXT_DELAY_SLOW
ret
.slow
ld c, OPT_TEXT_SPEED_SLOW
- lb de, TEXT_DELAY_MED, TEXT_DELAY_FAST
+ lb de, TEXT_DELAY_MED, TEXT_DELAY_NONE
ret
.fast
ld c, OPT_TEXT_SPEED_FAST
- lb de, TEXT_DELAY_SLOW, TEXT_DELAY_MED
+ lb de, TEXT_DELAY_NONE, TEXT_DELAY_MED
+ ret
+
+.none
+ ld c, OPT_TEXT_SPEED_NONE
+ lb de, TEXT_DELAY_SLOW, TEXT_DELAY_FAST
ret
Note how lb de, <previous>, <next>
correspond to the order defined with the OPT_TEXT_SPEED_<speed>
constants. If your custom text speed is not 0 like mine you're done.
There are a few extra quirks to fix. When you hold the A or B buttons while text is scrolling it does so at TEXT_DELAY_FAST
. Since our custom text speed is faster than that we need to make sure this doesn't happen.
Edit home/print_text.asm:
PrintLetterDelay::
...
; text speed
ld a, [wOptions]
and %111
+ jr z, .end
jr .updatedelay
Lastly, the <SCROLL>
command, which is used when a stat is sharply raised or lowered (among a couple other cases), will cause the line to skip instantly, giving you no time to read it. We'll force a delay into it.
_ContText
fallsthrough into _ContTextNoPause
but it doesn't need the delay, so we'll replace the fallthrough with a jump
Edit home/text.asm:
_ContText::
...
call z, UnloadBlinkingCursor
- ; fallthrough
+ jr _ContTextNoPause.not_instant
_ContTextNoPause::
+ ld a, [wOptions]
+ and TEXT_DELAY_MASK
+ cp TEXT_DELAY_FAST
+ jr nz, .not_instant
+ ld c, 15
+ call DelayFrames
+.not_instant
push de
And there you go.