summaryrefslogtreecommitdiff
path: root/src/engine/menus/start.asm
diff options
context:
space:
mode:
authorElectroDeoxys <ElectroDeoxys@gmail.com>2021-09-27 12:25:56 +0100
committerElectroDeoxys <ElectroDeoxys@gmail.com>2021-09-27 12:25:56 +0100
commita53828331cf4c86f7d14e3b178eaa18817b514a3 (patch)
tree4ce731fcf42324466ba9899a3fe8343bfbeb9dda /src/engine/menus/start.asm
parent7825b5ef0f09a877142ea1eb221e895bb60a0253 (diff)
Split part of bank 7
Diffstat (limited to 'src/engine/menus/start.asm')
-rw-r--r--src/engine/menus/start.asm418
1 files changed, 418 insertions, 0 deletions
diff --git a/src/engine/menus/start.asm b/src/engine/menus/start.asm
new file mode 100644
index 0000000..4d46d4a
--- /dev/null
+++ b/src/engine/menus/start.asm
@@ -0,0 +1,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 Func_10ab4
+ 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 Func_10ab4
+
+.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 Func_10000
+ 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 InitAndPrintPauseMenu
+ 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
+ ld bc, $90e
+ farcall Func_1024f
+ ld bc, $a10
+ farcall Func_101df
+ 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 Func_10000
+ 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 Func_10000
+ 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 Func_10000
+ call Func_3ca0
+ ld hl, HandleAllSpriteAnimations
+ call SetDoFrameFunction
+ lb bc, 7, 3
+ farcall $4, DrawPlayerPortrait
+ farcall Func_10af9
+ call DoFrameIfLCDEnabled
+ ldtx hl, IsCrazyAboutPokemonAndPokemonCardCollectingText
+ call PrintScrollableText_NoTextBoxLabel
+ call ResetDoFrameFunction
+ call Func_3ca0
+ ret