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. ## Contents 1. [Define wram constant](#1-define-wram-constant) 2. [Add instant text to options](#2-add-instant-text-to-options) 3. [Fix text speed while holding A or B](#3-fix-text-speed-while-holding-a-or-b) 4. [Fix `` command](#4-fix-scroll-command) ## 1. Define wram constant Edit [constants/wram_constants.asm](../blob/master/constants/wram_constants.asm): ```diff ; wOptions:: ; cfcc TEXT_DELAY_MASK EQU %111 const_def 4 const NO_TEXT_SCROLL ; 4 const STEREO ; 5 const BATTLE_SHIFT ; 6 const BATTLE_SCENE ; 7 +TEXT_DELAY_NONE EQU %000 ; 0 TEXT_DELAY_FAST EQU %001 ; 1 TEXT_DELAY_MED EQU %011 ; 3 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. ## 2. Add instant text to options Edit [engine/menus/options_menu.asm](../blob/master/engine/menu/options_menu.asm): ```diff .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. ```diff .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, , ` correspond to the order defined with the `OPT_TEXT_SPEED_` constants. If your custom text speed is not 0 like mine you're done. ## 3. Fix text speed while holding A or B 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](../blob/master/home/print_text.asm): ```diff PrintLetterDelay:: ... ; text speed ld a, [wOptions] and %111 + jr z, .end jr .updatedelay ``` ## 4. Fix `` command Lastly, the `` 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](../blob/master/home/text.asm): ```diff _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.