summaryrefslogtreecommitdiff
path: root/Add-a-new-text-scrolling-speed.md
blob: b69d657df8d64a2080d04ce4646b98f01743c609 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
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 `<SCROLL>` 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, <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.


## 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 `<SCROLL>` command

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](../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.