summaryrefslogtreecommitdiff
path: root/src/engine/menus/start.asm
blob: c2ec77dbecd36d078015815d09521d3f316708a6 (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
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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
; plays the Opening sequence, and handles player selection
; in the Title Screen and Start Menu
HandleTitleScreen:
; if last selected item in Start Menu is 0 (Card Pop!)
; then skip straight to the Start Menu
; this makes it so that returning from Card Pop!
; doesn't play the Opening sequence
	ld a, [wLastSelectedStartMenuItem]
	or a
	jr z, .start_menu

.play_opening
	ld a, MUSIC_STOP
	call PlaySong
	call Func_3ca0
	call PlayIntroSequence
	call LoadTitleScreenSprites

	xor a
	ld [wd635], a
	ld a, $3c
	ld [wTitleScreenIgnoreInputCounter], a
.loop
	call DoFrameIfLCDEnabled
	call UpdateRNGSources
	call AnimateRandomTitleScreenOrb
	ld hl, wd635
	inc [hl]
	call AssertSongFinished
	or a
	jr nz, .song_playing
	; reset back to the opening sequence
	farcall FadeScreenToWhite
	jr .play_opening

.song_playing
	; should we ignore user input?
	ld hl, wTitleScreenIgnoreInputCounter
	ld a, [hl]
	or a
	jr z, .check_keys
	; ignore input, decrement the counter
	dec [hl]
	jr .loop

.check_keys
	ldh a, [hKeysPressed]
	and A_BUTTON | START
	jr z, .loop
	ld a, SFX_02
	call PlaySFX
	farcall FadeScreenToWhite

.start_menu
	call CheckIfHasSaveData
	call HandleStartMenu

; new game
	ld a, [wStartMenuChoice]
	cp START_MENU_NEW_GAME
	jr nz, .continue_from_diary
	call DeleteSaveDataForNewGame
	jr c, HandleTitleScreen
	jr .card_pop
.continue_from_diary
	ld a, [wStartMenuChoice]
	cp START_MENU_CONTINUE_FROM_DIARY
	jr nz, .card_pop
	call AskToContinueFromDiaryWithDuelData
	jr c, HandleTitleScreen
.card_pop
	ld a, [wStartMenuChoice]
	cp START_MENU_CARD_POP
	jr nz, .continue_duel
	call ShowCardPopCGBDisclaimer
	jr c, HandleTitleScreen
.continue_duel
	call ResetDoFrameFunction
	call Func_3ca0
	ret

; updates wHasSaveData and wHasDuelSaveData
; depending on whether the save data is valid or not
CheckIfHasSaveData:
	farcall ValidateBackupGeneralSaveData
	ld a, TRUE
	jr c, .no_error
	ld a, FALSE
.no_error
	ld [wHasSaveData], a
	cp $00 ; or a
	jr z, .write_has_duel_data
	bank1call ValidateSavedNonLinkDuelData
	ld a, TRUE
	jr nc, .write_has_duel_data
	ld a, FALSE
.write_has_duel_data
	ld [wHasDuelSaveData], a
	farcall ValidateBackupGeneralSaveData
	ret

; handles printing the Start Menu
; and getting player input and choice
HandleStartMenu:
	ld a, MUSIC_PC_MAIN_MENU
	call PlaySong
	call DisableLCD
	farcall InitMenuScreen
	lb de, $30, $8f
	call SetupText
	call Func_3ca0
	xor a
	ld [wLineSeparation], a
	call .DrawPlayerPortrait
	call .SetStartMenuParams

	ld a, $ff
	ld [wTitleScreenIgnoreInputCounter], a
	ld a, [wLastSelectedStartMenuItem]
	cp $4
	jr c, .init_menu
	ld a, [wHasSaveData]
	or a
	jr z, .init_menu
	ld a, 1 ; start at second menu option
.init_menu
	ld hl, wStartMenuParams
	farcall InitAndPrintMenu
	farcall FlashWhiteScreen

.wait_input
	call DoFrameIfLCDEnabled
	call UpdateRNGSources
	call HandleMenuInput
	push af
	call PrintStartMenuDescriptionText
	pop af
	jr nc, .wait_input
	ldh a, [hCurMenuItem]
	cp e
	jr nz, .wait_input

	ld [wLastSelectedStartMenuItem], a
	ld a, [wHasSaveData]
	or a
	jr nz, .no_adjustment
	; New Game is 3rd option
	; but when there's no save data,
	; it's the 1st in menu list, so adjust it
	inc e
	inc e
.no_adjustment
	ld a, e
	ld [wStartMenuChoice], a
	ret

.SetStartMenuParams
	ld hl, .StartMenuParams
	ld de, wStartMenuParams
	ld bc, .StartMenuParamsEnd - .StartMenuParams
	call CopyDataHLtoDE

	ld e, 0
	ld a, [wHasSaveData]
	or a
	jr z, .get_text_id ; New Game
	inc e
	ld a, 2
	call .AddItems
	ld a, [wHasDuelSaveData]
	or a
	jr z, .get_text_id ; Continue From Diary
	inc e
	ld a, 1
	call .AddItems
	; Continue Duel

.get_text_id
	sla e
	ld d, $00
	ld hl, .StartMenuTextIDs
	add hl, de
	; set text ID as Start Menu param
	ld a, [hli]
	ld [wStartMenuParams + 6], a
	ld a, [hl]
	ld [wStartMenuParams + 7], a
	ret

; adds c items to start menu list
; this means adding 2 units per item to the text box height
; and adding to the number of items
.AddItems
	push bc
	ld c, a
	; number of items in menu
	ld a, [wStartMenuParams + 12]
	add c
	ld [wStartMenuParams + 12], a
	; height of text box
	sla c
	ld a, [wStartMenuParams + 3]
	add c
	ld [wStartMenuParams + 3], a
	pop bc
	ret

.StartMenuParams
	db  0, 0 ; start menu coords
	db 14, 4 ; start menu text box dimensions

	db  2, 2 ; text alignment for InitTextPrinting
	tx NewGameText
	db $ff

	db 1, 2 ; cursor x, cursor y
	db 2 ; y displacement between items
	db 1 ; number of items
	db SYM_CURSOR_R ; cursor tile number
	db SYM_SPACE ; tile behind cursor
	dw NULL ; function pointer if non-0
.StartMenuParamsEnd

.StartMenuTextIDs
	tx NewGameText
	tx CardPopContinueDiaryNewGameText
	tx CardPopContinueDiaryNewGameContinueDuelText

.DrawPlayerPortrait
	lb bc, 14, 1
	farcall $4, DrawPlayerPortrait
	ret

; prints the description for the current selected item
; in the Start Menu in the text box
PrintStartMenuDescriptionText:
	push hl
	push bc
	push de
	; don't print if it's already showing
	ld a, [wCurMenuItem]
	ld e, a
	ld a, [wCurHighlightedStartMenuItem]
	cp e
	jr z, .skip
	ld a, [wHasSaveData]
	or a
	jr nz, .has_data
	; New Game option is 3rd element
	; in function table, so add 2
	inc e
	inc e
.has_data

	ld a, e
	push af
	lb de, 0, 10
	lb bc, 20, 8
	call DrawRegularTextBox
	pop af
	ld hl, .StartMenuDescriptionFunctionTable
	call JumpToFunctionInTable
.skip
	ld a, [wCurMenuItem]
	ld [wCurHighlightedStartMenuItem], a
	pop de
	pop bc
	pop hl
	ret

.StartMenuDescriptionFunctionTable
	dw .CardPop
	dw .ContinueFromDiary
	dw .NewGame
	dw .ContinueDuel

.CardPop
	lb de, 1, 12
	call InitTextPrinting
	ldtx hl, WhenYouCardPopWithFriendText
	call PrintTextNoDelay
	ret

.ContinueDuel
	lb de, 1, 12
	call InitTextPrinting
	ldtx hl, TheGameWillContinueFromThePointInTheDuelText
	call PrintTextNoDelay
	ret

.NewGame
	lb de, 1, 12
	call InitTextPrinting
	ldtx hl, StartANewGameText
	call PrintTextNoDelay
	ret

.ContinueFromDiary
	; get OW map name
	ld a, [wCurOverworldMap]
	add a
	ld c, a
	ld b, $00
	ld hl, OverworldMapNames
	add hl, bc
	ld a, [hli]
	ld [wTxRam2 + 0], a
	ld a, [hl]
	ld [wTxRam2 + 1], a

	; get medal count
	ld a, [wMedalCount]
	ld [wTxRam3 + 0], a
	xor a
	ld [wTxRam3 + 1], a

	; print text
	lb de, 1, 10
	call InitTextPrinting
	ldtx hl, ContinueFromDiarySummaryText
	call PrintTextNoDelay

	ld a, [wTotalNumCardsCollected]
	ld d, a
	ld a, [wTotalNumCardsToCollect]
	ld e, a
	lb bc, 9, 14
	farcall PrintAlbumProgress_SkipGetProgress
	lb bc, 10, 16
	farcall PrintPlayTime_SkipUpdateTime
	ret

; asks the player whether it's okay to delete
; the save data in order to create a new one
; if player answers "yes", delete it
DeleteSaveDataForNewGame:
; exit if there no save data
	ld a, [wHasSaveData]
	or a
	ret z

	call DisableLCD
	farcall InitMenuScreen
	call Func_3ca0
	farcall FlashWhiteScreen
	call DoFrameIfLCDEnabled
	ldtx hl, SavedDataAlreadyExistsText
	call PrintScrollableText_NoTextBoxLabel
	ldtx hl, OKToDeleteTheDataText
	call YesOrNoMenuWithText
	ret c ; quit if chose "no"
	farcall InvalidateSaveData
	ldtx hl, AllDataWasDeletedText
	call PrintScrollableText_NoTextBoxLabel
	or a
	ret

; asks the player if the game should resume
; from diary even though there is Duel save data
; returns carry if "no" was selected
AskToContinueFromDiaryWithDuelData:
; return if there's no duel save data
	ld a, [wHasDuelSaveData]
	or a
	ret z

	call DisableLCD
	farcall InitMenuScreen
	call Func_3ca0
	farcall FlashWhiteScreen
	call DoFrameIfLCDEnabled
	ldtx hl, DataExistsWhenPowerWasTurnedOFFDuringDuelText
	call PrintScrollableText_NoTextBoxLabel
	ldtx hl, ContinueFromDiaryText
	call YesOrNoMenuWithText
	ret c
	or a
	ret

; shows disclaimer for Card Pop!
; in case player is not playing in CGB
; return carry if disclaimer was shown
ShowCardPopCGBDisclaimer:
; return if playing in CGB
	ld a, [wConsole]
	cp CONSOLE_CGB
	ret z

	lb de, 0, 10
	lb bc, 20, 8
	call DrawRegularTextBox
	lb de, 1,12
	call InitTextPrinting
	ldtx hl, YouCanAccessCardPopOnlyWithGameBoyColorsText
	call PrintTextNoDelay
	lb bc, SYM_CURSOR_D, SYM_BOX_BOTTOM
	lb de, 18, 17
	call SetCursorParametersForTextBox
	call WaitForButtonAorB
	scf
	ret

DrawPlayerPortraitAndPrintNewGameText:
	call DisableLCD
	farcall Func_10a9b
	farcall InitMenuScreen
	call Func_3ca0
	ld hl, HandleAllSpriteAnimations
	call SetDoFrameFunction
	lb bc, 7, 3
	farcall $4, DrawPlayerPortrait
	farcall FadeScreenFromWhite
	call DoFrameIfLCDEnabled
	ldtx hl, IsCrazyAboutPokemonAndPokemonCardCollectingText
	call PrintScrollableText_NoTextBoxLabel
	call ResetDoFrameFunction
	call Func_3ca0
	ret