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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
; SL0P MENU - a top-level menu opened with SELECT in the overworld (hooked in
; home/overworld.asm). Table-driven so it's easy to grow: each entry has a name
; in SlopMenuText and a handler in SlopMenuHandlers. A handler returns:
; carry SET -> a map warp was started; exit the menu and let it proceed
; carry CLEAR -> return to the SL0P menu (redraw)
; Handlers may be submenus (WarpSubmenu) or direct actions (SlopHealParty).
;
; To add an entry: add a "NAME" line to SlopMenuText, a `dw Handler` to
; SlopMenuHandlers, and bump SLOP_MENU_COUNT.
DEF SLOP_MENU_COUNT EQU 2
SECTION "Slop Menu", ROMX
SlopMenu::
; ---- open the menu display (shared by the top menu and every submenu) ----
ldh a, [hUILayoutFlags]
set BIT_SINGLE_SPACED_LINES, a ; single-spaced list text
set BIT_DOUBLE_SPACED_MENU, a ; single-spaced cursor
ldh [hUILayoutFlags], a
ld a, $ff
ld [wUpdateSpritesEnabled], a ; hide the overworld sprites
call ClearSprites
.redraw
call ClearScreen
hlcoord 5, 1
ld de, SlopMenuTitle
call PlaceString
hlcoord 4, 3
lb bc, SLOP_MENU_COUNT + 2, 11
call TextBoxBorder
hlcoord 6, 4
ld de, SlopMenuText
call PlaceString
call SlopMenuShow
xor a
ld [wCurrentMenuItem], a
ld [wLastMenuItem], a
ld [wMenuWatchMovingOutOfBounds], a
ld [wMenuJoypadPollCount], a
ld a, 5
ld [wTopMenuItemX], a
ld a, 4
ld [wTopMenuItemY], a
ld a, PAD_A | PAD_B
ld [wMenuWatchedKeys], a
ld a, SLOP_MENU_COUNT - 1
ld [wMaxMenuItem], a
call HandleMenuInput
bit B_PAD_B, a
jr nz, .close
; dispatch: call SlopMenuHandlers[wCurrentMenuItem]
ld a, [wCurrentMenuItem]
add a
ld e, a
ld d, 0
ld hl, SlopMenuHandlers
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
ld de, .afterHandler
push de
jp hl ; call [hl]; returns to .afterHandler
.afterHandler
jr c, .exitProceed ; handler started a warp -> let it run
jr .redraw ; otherwise back to the SL0P menu
.exitProceed
call SlopMenuRestoreFlags
ret
.close
call SlopMenuRestoreFlags
ld a, $01
ld [wUpdateSpritesEnabled], a
call LoadScreenTilesFromBuffer2
jp CloseTextDisplay
SlopMenuRestoreFlags:
ldh a, [hUILayoutFlags]
res BIT_SINGLE_SPACED_LINES, a
res BIT_DOUBLE_SPACED_MENU, a
ldh [hUILayoutFlags], a
ret
; push wTileMap into VRAM and switch on the menu window display (mirrors the
; tail of DisplayTextIDInit) so a box drawn into wTileMap is actually shown.
SlopMenuShow:
ld b, HIGH(vBGMap1)
call CopyScreenTileBufferToVRAM
xor a
ldh [hWY], a
call LoadFontTilePatterns
ld a, $01
ldh [hAutoBGTransferEnabled], a
ret
SlopMenuTitle:
db "SL0P MENU@"
SlopMenuText:
db "WARP"
next "HEAL@"
SlopMenuHandlers:
dw WarpSubmenu
dw SlopHealParty
; ---------------------------------------------------------------------------
; WARP submenu: a town list. On A, start a fly-warp to the chosen map (no
; BIT_USED_FLY, so no bird) and return carry set. On B, return carry clear.
; The display was already set up by SlopMenu.
; ---------------------------------------------------------------------------
DEF WARP_COUNT EQU 13
WarpSubmenu:
call ClearScreen
hlcoord 4, 0
ld de, WarpTitleText1
call PlaceString
hlcoord 5, 1
ld de, WarpTitleText2
call PlaceString
hlcoord 3, 2
lb bc, 13, 11
call TextBoxBorder
hlcoord 5, 3
ld de, WarpMenuText
call PlaceString
call SlopMenuShow
xor a
ld [wCurrentMenuItem], a
ld [wLastMenuItem], a
ld [wMenuWatchMovingOutOfBounds], a
ld [wMenuJoypadPollCount], a
ld a, 4
ld [wTopMenuItemX], a
ld a, 3
ld [wTopMenuItemY], a
ld a, PAD_A | PAD_B
ld [wMenuWatchedKeys], a
ld a, WARP_COUNT - 1
ld [wMaxMenuItem], a
call HandleMenuInput
bit B_PAD_B, a
jr nz, .cancel
ld a, [wCurrentMenuItem]
ld e, a
ld d, 0
ld hl, WarpMapTable
add hl, de
ld a, [hl]
ld [wDestinationMap], a
ld hl, wStatusFlags6
set BIT_FLY_WARP, [hl]
scf ; carry set = warp started
ret
.cancel
and a ; carry clear = back to SL0P menu
ret
WarpTitleText1:
db "SECRET SL0P@"
WarpTitleText2:
db "WARP MENU@"
WarpMenuText:
db "PALLET"
next "VIRIDIAN"
next "PEWTER"
next "CERULEAN"
next "LAVENDER"
next "VERMILION"
next "CELADON"
next "FUCHSIA"
next "CINNABAR"
next "INDIGO"
next "SAFFRON"
next "ROUTE 4"
next "ROUTE 10@"
WarpMapTable:
db PALLET_TOWN, VIRIDIAN_CITY, PEWTER_CITY, CERULEAN_CITY, LAVENDER_TOWN
db VERMILION_CITY, CELADON_CITY, FUCHSIA_CITY, CINNABAR_ISLAND, INDIGO_PLATEAU
db SAFFRON_CITY, ROUTE_4, ROUTE_10
; ---------------------------------------------------------------------------
; HEAL action: restore every party member to full HP and clear status.
; Returns carry clear (back to the SL0P menu).
; ---------------------------------------------------------------------------
; party_struct offsets: curHP +$01 (BE), status +$04, maxHP +$22 (BE), size $2C
SlopHealParty:
ld a, [wPartyCount]
and a
jr z, .done
ld c, a
ld hl, wPartyMon1
.loop
push hl ; save mon base
ld de, $04
add hl, de
xor a
ld [hl], a ; status = 0
pop hl
push hl
ld de, $22
add hl, de ; -> maxHP
ld a, [hli]
ld b, a ; maxHP hi
ld e, [hl] ; maxHP lo
ld d, b
pop hl ; mon base
push hl
inc hl ; -> curHP hi
ld a, d
ld [hli], a
ld a, e
ld [hl], a ; curHP = maxHP
pop hl ; mon base
ld de, $2C
add hl, de ; next mon
dec c
jr nz, .loop
.done
and a ; carry clear = back to SL0P menu
ret
|